diff --git a/.bzrignore b/.bzrignore index d8be10eacdb..414a40ef1eb 100644 --- a/.bzrignore +++ b/.bzrignore @@ -1057,3 +1057,4 @@ vio/test-ssl vio/test-sslclient vio/test-sslserver vio/viotest-ssl +libmysql/libmysql.ver diff --git a/BUILD/Makefile.am b/BUILD/Makefile.am index 4e27ffd5e7f..b43be5c3bdc 100644 --- a/BUILD/Makefile.am +++ b/BUILD/Makefile.am @@ -20,14 +20,22 @@ EXTRA_DIST = FINISH.sh \ SETUP.sh \ check-cpu \ + cleanup \ compile-alpha \ compile-alpha-ccc \ compile-alpha-cxx \ compile-alpha-debug \ + compile-amd64-debug-max \ + compile-amd64-max \ + compile-darwin-mwcc \ + compile-dist \ + compile-hpux11-parisc2-aCC \ compile-ia64-debug-max \ + compile-irix-mips64-mipspro \ compile-pentium \ compile-pentium-debug \ compile-pentium-debug-max \ + compile-pentium-debug-max-no-embedded \ compile-pentium-debug-no-bdb \ compile-pentium-debug-openssl \ compile-pentium-gcov \ @@ -36,10 +44,16 @@ EXTRA_DIST = FINISH.sh \ compile-pentium-myodbc \ compile-pentium-mysqlfs-debug \ compile-pentium-pgcc \ + compile-pentium-valgrind-max \ + compile-pentium64-debug \ + compile-pentium64-debug-max \ + compile-pentium64-valgrind-max \ + compile-ppc \ + compile-ppc-debug \ + compile-ppc-debug-max \ + compile-ppc-max \ compile-solaris-sparc \ compile-solaris-sparc-debug \ - compile-irix-mips64-mipspro \ - compile-hpux11-parisc2-aCC \ compile-solaris-sparc-forte \ compile-solaris-sparc-purify diff --git a/BUILD/compile-pentium64-debug-max b/BUILD/compile-pentium64-debug-max new file mode 100755 index 00000000000..f0745c88c90 --- /dev/null +++ b/BUILD/compile-pentium64-debug-max @@ -0,0 +1,13 @@ +#! /bin/sh + +path=`dirname $0` +. "$path/SETUP.sh" $@ --with-debug=full + +extra_flags="$pentium64_cflags $debug_cflags $max_cflags" +c_warnings="$c_warnings $debug_extra_warnings" +cxx_warnings="$cxx_warnings $debug_extra_warnings" +extra_configs="$pentium_configs $debug_configs $max_configs" + +extra_configs="$extra_configs " + +. "$path/FINISH.sh" diff --git a/BitKeeper/triggers/post-commit b/BitKeeper/triggers/post-commit index a54086a0d0d..a09da93adaf 100755 --- a/BitKeeper/triggers/post-commit +++ b/BitKeeper/triggers/post-commit @@ -2,7 +2,7 @@ #shift FROM=$USER@mysql.com -INTERNALS=internals@lists.mysql.com +COMMITS=commits@lists.mysql.com DOCS=docs-commit@mysql.com LIMIT=10000 VERSION="4.1" @@ -61,14 +61,14 @@ EOF ) | head -n $LIMIT | /usr/sbin/sendmail -t #++ -# internals@ mail +# commits@ mail #-- - echo "Notifying internals list at $INTERNALS" + echo "Notifying commits list at $COMMITS" ( cat < From: $FROM -To: $INTERNALS +To: $COMMITS Subject: bk commit into $VERSION tree ($CHANGESET)$BS X-CSetKey: <$CSETKEY> $BH diff --git a/Docs/Makefile.am b/Docs/Makefile.am index b1f69381774..685eaeef7d1 100644 --- a/Docs/Makefile.am +++ b/Docs/Makefile.am @@ -18,11 +18,11 @@ noinst_SCRIPTS = Support/generate-text-files.pl EXTRA_DIST = $(noinst_SCRIPTS) mysql.info INSTALL-BINARY -all: txt_files - -txt_files: ../INSTALL-SOURCE ../INSTALL-WIN-SOURCE ../EXCEPTIONS-CLIENT \ +TXT_FILES= ../INSTALL-SOURCE ../INSTALL-WIN-SOURCE ../EXCEPTIONS-CLIENT \ INSTALL-BINARY ../support-files/MacOSX/ReadMe.txt +all-local: $(TXT_FILES) + # make sure that "make install" installs the info page, too # automake only seems to take care of this automatically, # if we're building the info page from texi directly. @@ -30,28 +30,32 @@ install-data-hook: mysql.info $(mkinstalldirs) $(DESTDIR)$(infodir) $(INSTALL_DATA) $(srcdir)/mysql.info $(DESTDIR)$(infodir) -CLEAN_FILES: $(txt_files) - touch $(txt_files) +uninstall-local: + @RM@ -f $(DESTDIR)$(infodir)/mysql.info + +# This target is not used in builds, just for convinience +CLEAN_FILES: $(TXT_FILES) + touch $(TXT_FILES) GT = $(srcdir)/Support/generate-text-files.pl ../INSTALL-SOURCE: mysql.info $(GT) - perl -w $(GT) mysql.info "installing-source" "windows-source-build" > $@ + perl -w $(GT) $< "installing-source" "windows-source-build" > $@ ../INSTALL-WIN-SOURCE: mysql.info $(GT) - perl -w $(GT) mysql.info "windows-source-build" "post-installation" > $@ + perl -w $(GT) $< "windows-source-build" "post-installation" > $@ # We put the description for the binary installation here so that # people who download source wont have to see it. It is moved up to # the toplevel by the script that makes the binary tar files. INSTALL-BINARY: mysql.info $(GT) - perl -w $(GT) mysql.info "installing-binary" "installing-source" > $@ + perl -w $(GT) $< "installing-binary" "installing-source" > $@ ../EXCEPTIONS-CLIENT: mysql.info $(GT) - perl -w $(GT) mysql.info "mysql-floss-license-exception" "function-index" > $@ + perl -w $(GT) $< "mysql-floss-license-exception" "function-index" > $@ ../support-files/MacOSX/ReadMe.txt: mysql.info $(GT) - perl -w $(GT) mysql.info "mac-os-x-installation" "netware-installation" > $@ + perl -w $(GT) $< "mac-os-x-installation" "netware-installation" > $@ # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/Makefile.am b/Makefile.am index 9025251ff2a..2aefbd05283 100644 --- a/Makefile.am +++ b/Makefile.am @@ -19,7 +19,8 @@ AUTOMAKE_OPTIONS = foreign # These are built from source in the Docs directory -EXTRA_DIST = INSTALL-SOURCE README COPYING EXCEPTIONS-CLIENT +EXTRA_DIST = INSTALL-SOURCE INSTALL-WIN-SOURCE \ + README COPYING EXCEPTIONS-CLIENT SUBDIRS = . include @docs_dirs@ @zlib_dir@ \ @readline_topdir@ sql-common \ @thread_dirs@ pstack \ @@ -34,16 +35,19 @@ DIST_SUBDIRS = . include @docs_dirs@ zlib \ BUILD netware os2 @libmysqld_dirs@ \ @bench_dirs@ support-files @fs_dirs@ @tools_dirs@ -# Relink after clean -linked_sources = linked_client_sources linked_server_sources \ - linked_libmysql_sources linked_libmysql_r_sources \ - linked_libmysqld_sources linked_libmysqldex_sources \ +# Run these targets before any others, also make part of clean target, +# to make sure we create new links after a clean. +BUILT_SOURCES = linked_client_sources linked_server_sources \ + @linked_client_targets@ \ + @linked_libmysqld_targets@ \ linked_include_sources @linked_netware_sources@ -CLEANFILES = $(linked_sources) - -# This is just so that the linking is done early. -all-local: $(linked_sources) +# The db.h file is a bit special, see note in "configure.in". +# In the case we didn't compile with bdb, a dummy file is put +# there, but will not be removed by the bdb make file becuase +# it will never be called. +CLEANFILES = $(BUILT_SOURCES) bdb/build_unix/db.h +DISTCLEANFILES = ac_available_languages_fragment linked_include_sources: cd include; $(MAKE) link_sources @@ -73,13 +77,8 @@ linked_netware_sources: cd @netware_dir@; $(MAKE) link_sources echo timestamp > linked_netware_sources -#avoid recursive make calls in sql directory linked_server_sources: - cd sql; rm -f mini_client_errors.c;\ - @LN_CP_F@ ../libmysql/errmsg.c mini_client_errors.c;\ - rm -f pack.c;@LN_CP_F@ ../sql-common/pack.c pack.c;\ - rm -f client.c;@LN_CP_F@ ../sql-common/client.c client.c;\ - rm -f my_time.c;@LN_CP_F@ ../sql-common/my_time.c my_time.c + cd sql; $(MAKE) link_sources echo timestamp > linked_server_sources # Create permission databases @@ -91,35 +90,28 @@ bin-dist: all # Remove BK's "SCCS" subdirectories from source distribution dist-hook: - rm -rf `find $(distdir) -type d -name SCCS` + rm -rf `find $(distdir) -type d -name SCCS -print` tags: support-files/build-tags .PHONY: init-db bin-dist -# Test installation. Ports are configurable from the environment. - -MYSQL_TEST_MANAGER_PORT = 9305 -MYSQL_TEST_MASTER_PORT = 9306 -MYSQL_TEST_SLAVE_PORT = 9308 -MYSQL_TEST_NDB_PORT = 9350 +# Target 'test' will run the regression test suite using the built server. +# +# If you are running in a shared environment, users can avoid clashing +# port numbers by setting individual small numbers 1-100 to the +# environment variable MTR_BUILD_THREAD. The script "mysql-test-run" +# will then calculate the various port numbers it needs from this, +# making sure each user use different ports. test: cd mysql-test ; \ - ./mysql-test-run \ - --manager-port=$(MYSQL_TEST_MANAGER_PORT) \ - --master_port=$(MYSQL_TEST_MASTER_PORT) \ - --slave_port=$(MYSQL_TEST_SLAVE_PORT) \ - --ndbcluster_port=$(MYSQL_TEST_NDB_PORT) && \ - ./mysql-test-run --ps-protocol \ - --manager-port=$(MYSQL_TEST_MANAGER_PORT) \ - --master_port=$(MYSQL_TEST_MASTER_PORT) \ - --slave_port=$(MYSQL_TEST_SLAVE_PORT) \ - --ndbcluster_port=$(MYSQL_TEST_NDB_PORT) + ./mysql-test-run && \ + ./mysql-test-run --ps-protocol test-force: cd mysql-test; \ - ./mysql-test-run --force ;\ + ./mysql-test-run --force && \ ./mysql-test-run --ps-protocol --force # We are testing a new Perl version of the test script @@ -130,5 +122,5 @@ test-pl: test-force-pl: cd mysql-test; \ - ./mysql-test-run.pl --force ; \ + ./mysql-test-run.pl --force && \ ./mysql-test-run.pl --ps-protocol --force diff --git a/NEW-RPMS/.cvsignore b/NEW-RPMS/.cvsignore deleted file mode 100644 index eee690e5a6c..00000000000 --- a/NEW-RPMS/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -MySQL-*.rpm diff --git a/acinclude.m4 b/acinclude.m4 index 9c7271f7cc9..0a5778285ea 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -310,8 +310,9 @@ case $SYSTEM_TYPE in fi ;; *) - if test -f "$mysql_zlib_dir/lib/libz.a" -a \ - -f "$mysql_zlib_dir/include/zlib.h"; then + if test \( -f "$mysql_zlib_dir/lib/libz.a" -o -f "$mysql_zlib_dir/lib/libz.so" -o \ + -f "$mysql_zlib_dir/lib/libz.sl" -o -f "$mysql_zlib_dir/lib/libz.dylib" \) \ + -a -f "$mysql_zlib_dir/include/zlib.h"; then ZLIB_INCLUDES="-I$mysql_zlib_dir/include" ZLIB_LIBS="-L$mysql_zlib_dir/lib -lz" MYSQL_CHECK_ZLIB_DIR diff --git a/client/Makefile.am b/client/Makefile.am index 1e8851fb3b9..c0569d5fa6f 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -41,8 +41,8 @@ DEFS = -DUNDEF_THREADS_HACK link_sources: for f in $(sql_src) ; do \ - rm -f $(srcdir)/$$f; \ - @LN_CP_F@ $(top_srcdir)/sql/$$f $(srcdir)/$$f; \ + rm -f $$f; \ + @LN_CP_F@ $(top_srcdir)/sql/$$f $$f; \ done; # Don't update the files from bitkeeper diff --git a/client/mysql.cc b/client/mysql.cc index d408e8a5423..d76195535a3 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -254,7 +254,7 @@ static COMMANDS commands[] = { { "quit", 'q', com_quit, 0, "Quit mysql." }, { "rehash", '#', com_rehash, 0, "Rebuild completion hash." }, { "source", '.', com_source, 1, - "Execute a SQL script file. Takes a file name as an argument."}, + "Execute an SQL script file. Takes a file name as an argument."}, { "status", 's', com_status, 0, "Get status information from the server."}, #ifdef USE_POPEN { "system", '!', com_shell, 1, "Execute a system shell command."}, @@ -509,7 +509,7 @@ static struct my_option my_long_options[] = {"help", 'I', "Synonym for -?", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #ifdef __NETWARE__ - {"auto-close", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", + {"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"auto-rehash", OPT_AUTO_REHASH, @@ -1813,9 +1813,13 @@ com_help(String *buffer __attribute__((unused)), if (help_arg) return com_server_help(buffer,line,help_arg+1); - put_info("\nFor the complete MySQL Manual online, visit:\n http://www.mysql.com/documentation\n", INFO_INFO); - put_info("For info on technical support from MySQL developers, visit:\n http://www.mysql.com/support\n", INFO_INFO); - put_info("For info on MySQL books, utilities, consultants, etc., visit:\n http://www.mysql.com/portal\n", INFO_INFO); + put_info("\nFor information about MySQL products and services, visit:\n" + " http://www.mysql.com/\n" + "For developer information, including the MySQL Reference Manual, " + "visit:\n" + " http://dev.mysql.com/\n" + "To buy MySQL Network Support, training, or other products, visit:\n" + " https://shop.mysql.com/\n", INFO_INFO); put_info("List of all MySQL commands:", INFO_INFO); if (!named_cmds) put_info("Note that all text commands must be first on line and end with ';'",INFO_INFO); diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index da790bce375..7bb3061f412 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -127,7 +127,7 @@ static TYPELIB command_typelib= static struct my_option my_long_options[] = { #ifdef __NETWARE__ - {"auto-close", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", + {"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"count", 'c', diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 802d5081ad6..627e0945d93 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -433,7 +433,7 @@ static struct my_option my_long_options[] = { #ifdef __NETWARE__ - {"auto-close", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", + {"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif #ifndef DBUG_OFF diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index 2a2ae1311c9..f0f7c247553 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -63,7 +63,7 @@ static struct my_option my_long_options[] = (gptr*) &opt_all_in_1, (gptr*) &opt_all_in_1, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, #ifdef __NETWARE__ - {"auto-close", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", + {"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"auto-repair", OPT_AUTO_REPAIR, diff --git a/client/mysqldump.c b/client/mysqldump.c index 3458f74d8a2..7ff9504607f 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -165,7 +165,7 @@ static struct my_option my_long_options[] = "Allow creation of column names that are keywords.", (gptr*) &opt_keywords, (gptr*) &opt_keywords, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, #ifdef __NETWARE__ - {"auto-close", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", + {"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"character-sets-dir", OPT_CHARSETS_DIR, diff --git a/client/mysqlimport.c b/client/mysqlimport.c index ca4acd82db6..a7872740c0c 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -59,7 +59,7 @@ static char *shared_memory_base_name=0; static struct my_option my_long_options[] = { #ifdef __NETWARE__ - {"auto-close", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", + {"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"character-sets-dir", OPT_CHARSETS_DIR, @@ -517,6 +517,13 @@ int main(int argc, char **argv) free_defaults(argv_to_free); return(1); /* purecov: deadcode */ } + + if (mysql_query(sock, "set @@character_set_database=binary;")) + { + db_error(sock); /* We shall countinue here, if --force was given */ + return(1); + } + if (lock_tables) lock_table(sock, argc, argv); for (; *argv != NULL; argv++) diff --git a/client/mysqlshow.c b/client/mysqlshow.c index 44fc9448782..3b714c20ba7 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -156,7 +156,7 @@ int main(int argc, char **argv) static struct my_option my_long_options[] = { #ifdef __NETWARE__ - {"auto-close", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", + {"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"character-sets-dir", 'c', "Directory where character sets are.", diff --git a/client/mysqltest.c b/client/mysqltest.c index 35408368a73..d10ad054798 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -3272,19 +3272,24 @@ static int run_query_stmt(MYSQL *mysql, struct st_query *q, int flags) /* Read result from each column */ for (col_idx= 0; col_idx < num_fields; col_idx++) { - /* FIXME is string terminated? */ - const char *val= (const char *)bind[col_idx].buffer; - ulonglong len= *bind[col_idx].length; + const char *val; + ulonglong len; if (col_idx < max_replace_column && replace_column[col_idx]) { val= replace_column[col_idx]; len= strlen(val); } - if (*bind[col_idx].is_null) + else if (*bind[col_idx].is_null) { val= "NULL"; len= 4; } + else + { + /* FIXME is string terminated? */ + val= (const char *) bind[col_idx].buffer; + len= *bind[col_idx].length; + } if (!display_result_vertically) { if (col_idx) /* No tab before first col */ diff --git a/cmd-line-utils/libedit/Makefile.am b/cmd-line-utils/libedit/Makefile.am index af1bf8b2c97..ae6755f1c5c 100644 --- a/cmd-line-utils/libedit/Makefile.am +++ b/cmd-line-utils/libedit/Makefile.am @@ -2,8 +2,8 @@ # Makefile for the GNU readline library. # Copyright (C) 1994,1996,1997 Free Software Foundation, Inc. -ASRC=vi.c emacs.c common.c -AHDR=vi.h emacs.h common.h +ASRC = $(srcdir)/vi.c $(srcdir)/emacs.c $(srcdir)/common.c +AHDR = vi.h emacs.h common.h INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \ -I$(srcdir)/../.. -I.. @@ -42,16 +42,16 @@ SUFFIXES = .sh $< > $@-t @MV@ $@-t $@ -vi.h: vi.c makelist - sh ./makelist -h ./vi.c > $@.tmp && \ +vi.h: $(srcdir)/vi.c makelist + sh ./makelist -h $(srcdir)/vi.c > $@.tmp && \ mv $@.tmp $@ -emacs.h: emacs.c makelist - sh ./makelist -h ./emacs.c > $@.tmp && \ +emacs.h: $(srcdir)/emacs.c makelist + sh ./makelist -h $(srcdir)/emacs.c > $@.tmp && \ mv $@.tmp $@ -common.h: common.c makelist - sh ./makelist -h ./common.c > $@.tmp && \ +common.h: $(srcdir)/common.c makelist + sh ./makelist -h $(srcdir)/common.c > $@.tmp && \ mv $@.tmp $@ help.c: ${ASRC} makelist diff --git a/configure.in b/configure.in index 40a3e8ea5d4..24d6900a5f9 100644 --- a/configure.in +++ b/configure.in @@ -5,18 +5,19 @@ 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, 4.1.16) +AM_INIT_AUTOMAKE(mysql, 4.1.18) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 DOT_FRM_VERSION=6 # See the libtool docs for information on how to do shared lib versions. -SHARED_LIB_VERSION=14:0:0 +SHARED_LIB_MAJOR_VERSION=14 +SHARED_LIB_VERSION=$SHARED_LIB_MAJOR_VERSION:0:0 # ndb version NDB_VERSION_MAJOR=4 NDB_VERSION_MINOR=1 -NDB_VERSION_BUILD=16 +NDB_VERSION_BUILD=18 NDB_VERSION_STATUS="" # Set all version vars based on $VERSION. How do we do this more elegant ? @@ -37,7 +38,7 @@ romanian russian serbian slovak spanish swedish ukrainian" # Generate make rules for all error messages AVAILABLE_LANGUAGES_ERRORS= -AVAILABLE_LANGUAGES_ERRORS_RULES=$srcdir/ac_available_languages_fragment +AVAILABLE_LANGUAGES_ERRORS_RULES=ac_available_languages_fragment rm -f $AVAILABLE_LANGUAGES_ERRORS_RULES for i in $AVAILABLE_LANGUAGES do @@ -68,6 +69,7 @@ AC_DEFINE_UNQUOTED([PROTOCOL_VERSION], [$PROTOCOL_VERSION], AC_SUBST(DOT_FRM_VERSION) AC_DEFINE_UNQUOTED([DOT_FRM_VERSION], [$DOT_FRM_VERSION], [Version of .frm files]) +AC_SUBST(SHARED_LIB_MAJOR_VERSION) AC_SUBST(SHARED_LIB_VERSION) AC_SUBST(AVAILABLE_LANGUAGES) AC_SUBST(AVAILABLE_LANGUAGES_ERRORS) @@ -431,6 +433,13 @@ then fi fi +# libmysqlclient versioning when linked with GNU ld. +if $LD --version 2>/dev/null|grep -q GNU; then + LD_VERSION_SCRIPT="-Wl,--version-script=\$(top_srcdir)/libmysql/libmysql.ver" + AC_CONFIG_FILES(libmysql/libmysql.ver) +fi +AC_SUBST(LD_VERSION_SCRIPT) + # Avoid bug in fcntl on some versions of linux AC_MSG_CHECKING("if we should use 'skip-locking' as default for $target_os") # Any wariation of Linux @@ -1672,6 +1681,19 @@ if expr "$SYSTEM_TYPE" : ".*netware.*" > /dev/null; then OPTIMIZE_CXXFLAGS="$OPTIMIZE_CXXFLAGS -DNDEBUG" fi +# If the user specified CFLAGS, we won't add any optimizations +if test -n "$SAVE_CFLAGS" +then + OPTIMIZE_CFLAGS="" + DEBUG_OPTIMIZE_CC="" +fi +# Ditto for CXXFLAGS +if test -n "$SAVE_CXXFLAGS" +then + OPTIMIZE_CXXFLAGS="" + DEBUG_OPTIMIZE_CXX="" +fi + AC_ARG_WITH(debug, [ --without-debug Build a production version without debugging code], [with_debug=$withval], @@ -2300,6 +2322,7 @@ then echo "Warning: extra-tools disabled because --enable-thread-safe-client wasn't used" else tools_dirs="tools" + AC_CONFIG_FILES(tools/Makefile) fi fi AC_SUBST(tools_dirs) @@ -2310,9 +2333,12 @@ MYSQL_CHECK_VIO MYSQL_CHECK_OPENSSL libmysqld_dirs= +linked_libmysqld_targets= if test "$with_embedded_server" = "yes" then libmysqld_dirs=libmysqld + linked_libmysqld_targets="linked_libmysqld_sources linked_libmysqldex_sources" + AC_CONFIG_FILES(libmysqld/Makefile libmysqld/examples/Makefile) # We can't build embedded library without building the server, because # we depend on libmysys, libmystrings, libmyisam, etc. with_server=yes @@ -2321,6 +2347,7 @@ fi # mysql_config --libmysqld-libs will print out something like # -L/path/to/lib/mysql -lmysqld -lmyisam -lmysys -lmystrings -ldbug ... AC_SUBST([libmysqld_dirs]) +AC_SUBST([linked_libmysqld_targets]) # Shall we build the docs? AC_ARG_WITH(docs, @@ -2347,10 +2374,14 @@ AC_ARG_WITH(man, if test "$with_man" = "yes" then man_dirs="man" + man1_files=`ls -1 $srcdir/man/*.1 | sed -e 's;^.*man/;;'` + man1_files=`echo $man1_files` else man_dirs="" + man1_files="" fi AC_SUBST(man_dirs) +AC_SUBST(man1_files) # Shall we build the bench code? AC_ARG_WITH(bench, @@ -2420,7 +2451,7 @@ then readline_basedir="libedit" readline_dir="$readline_topdir/$readline_basedir" readline_link="\$(top_builddir)/cmd-line-utils/libedit/libedit.a" - readline_h_ln_cmd="\$(LN) -s \$(top_builddir)/cmd-line-utils/libedit/readline readline" + readline_h_ln_cmd="\$(LN) -s \$(top_srcdir)/cmd-line-utils/libedit/readline readline" compile_libedit=yes AC_DEFINE_UNQUOTED(HAVE_HIST_ENTRY, 1) AC_DEFINE_UNQUOTED(USE_LIBEDIT_INTERFACE, 1) @@ -2430,7 +2461,7 @@ then readline_basedir="readline" readline_dir="$readline_topdir/$readline_basedir" readline_link="\$(top_builddir)/cmd-line-utils/readline/libreadline.a" - readline_h_ln_cmd="\$(LN) -s \$(top_builddir)/cmd-line-utils/readline readline" + readline_h_ln_cmd="\$(LN) -s \$(top_srcdir)/cmd-line-utils/readline readline" compile_readline=yes AC_DEFINE_UNQUOTED(USE_NEW_READLINE_INTERFACE, 1) else @@ -2911,6 +2942,7 @@ if test "$THREAD_SAFE_CLIENT" != "no" then sql_client_dirs="libmysql_r $sql_client_dirs" linked_client_targets="$linked_client_targets linked_libmysql_r_sources" + AC_CONFIG_FILES(libmysql_r/Makefile) AC_DEFINE([THREAD_SAFE_CLIENT], [1], [Should be client be thread safe]) fi @@ -3265,12 +3297,11 @@ AC_CONFIG_FILES(Makefile extra/Makefile mysys/Makefile dnl myisam/Makefile myisammrg/Makefile dnl os2/Makefile os2/include/Makefile os2/include/sys/Makefile dnl man/Makefile BUILD/Makefile vio/Makefile dnl - libmysql_r/Makefile libmysqld/Makefile libmysqld/examples/Makefile dnl libmysql/Makefile client/Makefile dnl pstack/Makefile pstack/aout/Makefile sql/Makefile sql/share/Makefile dnl sql-common/Makefile SSL/Makefile dnl dbug/Makefile scripts/Makefile dnl - include/Makefile sql-bench/Makefile tools/Makefile dnl + include/Makefile sql-bench/Makefile dnl tests/Makefile Docs/Makefile support-files/Makefile dnl support-files/MacOSX/Makefile mysql-test/Makefile dnl netware/Makefile dnl diff --git a/extra/comp_err.c b/extra/comp_err.c index 6c7fad6a270..f47c8a1beca 100644 --- a/extra/comp_err.c +++ b/extra/comp_err.c @@ -159,7 +159,9 @@ static void get_options(register int *argc,register char **argv[]) case 'I': case '?': printf(" %s (Compile errormessage) Ver 1.3\n",progname); - puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n"); + puts("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 [-?] [-I] [-V] fromfile[s] tofile\n",progname); puts("Options: -Info -Version\n"); help=1; diff --git a/heap/_check.c b/heap/_check.c index a745aee48bf..ad432856a69 100644 --- a/heap/_check.c +++ b/heap/_check.c @@ -167,7 +167,7 @@ static int check_one_rb_key(HP_INFO *info, uint keynr, ulong records, ulong found= 0; byte *key, *recpos; uint key_length; - uint not_used; + uint not_used[2]; if ((key= tree_search_edge(&keydef->rb_tree, info->parents, &info->last_pos, offsetof(TREE_ELEMENT, left)))) @@ -177,7 +177,7 @@ static int check_one_rb_key(HP_INFO *info, uint keynr, ulong records, memcpy(&recpos, key + (*keydef->get_key_length)(keydef,key), sizeof(byte*)); key_length= hp_rb_make_key(keydef, info->recbuf, recpos, 0); if (ha_key_cmp(keydef->seg, (uchar*) info->recbuf, (uchar*) key, - key_length, SEARCH_FIND | SEARCH_SAME, ¬_used)) + key_length, SEARCH_FIND | SEARCH_SAME, not_used)) { error= 1; DBUG_PRINT("error",("Record in wrong link: key: %d Record: %lx\n", diff --git a/heap/hp_create.c b/heap/hp_create.c index af32fefea1b..2b811dac89b 100644 --- a/heap/hp_create.c +++ b/heap/hp_create.c @@ -170,9 +170,9 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef, static int keys_compare(heap_rb_param *param, uchar *key1, uchar *key2) { - uint not_used; + uint not_used[2]; return ha_key_cmp(param->keyseg, key1, key2, param->key_length, - param->search_flag, ¬_used); + param->search_flag, not_used); } static void init_block(HP_BLOCK *block, uint reclength, ulong min_records, diff --git a/include/Makefile.am b/include/Makefile.am index 0c845900a4f..3fa7b04d69a 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -38,23 +38,15 @@ SUPERCLEANFILES = mysql_version.h my_config.h # Some include files that may be moved and patched by configure DISTCLEANFILES = sched.h $(SUPERCLEANFILES) -clean: +clean-local: $(RM) -fr readline -distclean: +distclean-local: $(RM) -fr readline -all-local: my_config.h - -# Since we include my_config.h it better exist from the beginning -link_sources: - $(CP) ../config.h my_config.h - -$(RM) -fr readline - @readline_h_ln_cmd@ - -# Keep automake happy - my_config.h: ../config.h $(CP) ../config.h my_config.h + +link_sources: -$(RM) -fr readline @readline_h_ln_cmd@ diff --git a/include/config-netware.h b/include/config-netware.h index 1b24655ee89..503c8bbef67 100644 --- a/include/config-netware.h +++ b/include/config-netware.h @@ -92,6 +92,9 @@ extern "C" { /* On NetWare, stack grows towards lower address*/ #define STACK_DIRECTION -1 +/* On NetWare, we need to set stack size for threads, otherwise default 16K is used */ +#define NW_THD_STACKSIZE 65536 + /* On NetWare, to fix the problem with the deletion of open files */ #define CANT_DELETE_OPEN_FILES 1 @@ -116,15 +119,12 @@ extern "C" { /* do not use the extended time in LibC sys\stat.h */ #define _POSIX_SOURCE -/* Kernel call on NetWare that will only yield if our time slice is up */ -void kYieldIfTimeSliceUp(void); - /* Some macros for portability */ #define set_timespec(ABSTIME,SEC) { (ABSTIME).tv_sec=time(NULL)+(SEC); (ABSTIME).tv_nsec=0; } /* extra protection against CPU Hogs on NetWare */ -#define NETWARE_YIELD kYieldIfTimeSliceUp() +#define NETWARE_YIELD pthread_yield() /* Screen mode for help texts */ #define NETWARE_SET_SCREEN_MODE(A) setscreenmode(A) diff --git a/include/config-win.h b/include/config-win.h index 9663947683e..e1972051e67 100644 --- a/include/config-win.h +++ b/include/config-win.h @@ -278,10 +278,10 @@ inline double ulonglong2double(ulonglong value) *((T)+4)=(uchar) (((A) >> 32)); } #define int8store(T,A) *((ulonglong *) (T))= (ulonglong) (A) -#define doubleget(V,M) { *((long *) &V) = *((long*) M); \ - *(((long *) &V)+1) = *(((long*) M)+1); } -#define doublestore(T,V) { *((long *) T) = *((long*) &V); \ - *(((long *) T)+1) = *(((long*) &V)+1); } +#define doubleget(V,M) do { *((long *) &V) = *((long*) M); \ + *(((long *) &V)+1) = *(((long*) M)+1); } while(0) +#define doublestore(T,V) do { *((long *) T) = *((long*) &V); \ + *(((long *) T)+1) = *(((long*) &V)+1); } while(0) #define float4get(V,M) { *((long *) &(V)) = *((long*) (M)); } #define floatget(V,M) memcpy((byte*) &V,(byte*) (M),sizeof(float)) #define floatstore(T,V) memcpy((byte*)(T), (byte*)(&V), sizeof(float)) diff --git a/include/hash.h b/include/hash.h index 9a6d91036e1..8f5ff21ae5e 100644 --- a/include/hash.h +++ b/include/hash.h @@ -33,7 +33,7 @@ typedef void (*hash_free_key)(void *); typedef struct st_hash { uint key_offset,key_length; /* Length of key if const length */ - uint records,blength,current_record; + uint records, blength; uint flags; DYNAMIC_ARRAY array; /* Place for hash_keys */ hash_get_key get_key; @@ -41,6 +41,9 @@ typedef struct st_hash { CHARSET_INFO *charset; } HASH; +/* A search iterator state */ +typedef uint HASH_SEARCH_STATE; + #define hash_init(A,B,C,D,E,F,G,H) _hash_init(A,B,C,D,E,F,G, H CALLER_INFO) my_bool _hash_init(HASH *hash, CHARSET_INFO *charset, uint default_array_elements, uint key_offset, @@ -49,12 +52,15 @@ my_bool _hash_init(HASH *hash, CHARSET_INFO *charset, void hash_free(HASH *tree); void my_hash_reset(HASH *hash); byte *hash_element(HASH *hash,uint idx); -gptr hash_search(HASH *info,const byte *key,uint length); -gptr hash_next(HASH *info,const byte *key,uint length); +gptr hash_search(const HASH *info, const byte *key, uint length); +gptr hash_first(const HASH *info, const byte *key, uint length, + HASH_SEARCH_STATE *state); +gptr hash_next(const HASH *info, const byte *key, uint length, + HASH_SEARCH_STATE *state); my_bool my_hash_insert(HASH *info,const byte *data); my_bool hash_delete(HASH *hash,byte *record); my_bool hash_update(HASH *hash,byte *record,byte *old_key,uint old_key_length); -void hash_replace(HASH *hash, uint idx, byte *new_row); +void hash_replace(HASH *hash, HASH_SEARCH_STATE *state, byte *new_row); my_bool hash_check(HASH *hash); /* Only in debug library */ #define hash_clear(H) bzero((char*) (H),sizeof(*(H))) diff --git a/include/my_base.h b/include/my_base.h index d702ec45140..271e7cd23ba 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -231,6 +231,7 @@ enum ha_base_keytype { #define HA_OPTION_CHECKSUM 32 #define HA_OPTION_DELAY_KEY_WRITE 64 #define HA_OPTION_NO_PACK_KEYS 128 /* Reserved for MySQL */ +#define HA_OPTION_CREATE_FROM_ENGINE 256 #define HA_OPTION_TEMP_COMPRESS_RECORD ((uint) 16384) /* set by isamchk */ #define HA_OPTION_READ_ONLY_DATA ((uint) 32768) /* Set by isamchk */ @@ -241,7 +242,6 @@ enum ha_base_keytype { #define HA_CREATE_TMP_TABLE 4 #define HA_CREATE_CHECKSUM 8 #define HA_CREATE_DELAY_KEY_WRITE 64 -#define HA_CREATE_FROM_ENGINE 128 /* Bits in flag to _status */ diff --git a/include/my_handler.h b/include/my_handler.h index 18a6234d3f6..8b3cc1a1ee0 100644 --- a/include/my_handler.h +++ b/include/my_handler.h @@ -63,4 +63,6 @@ extern int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, register uchar *b, uint key_length, uint nextflag, uint *diff_pos); +extern HA_KEYSEG *ha_find_null(HA_KEYSEG *keyseg, uchar *a); + #endif /* _my_handler_h */ diff --git a/include/myisam.h b/include/myisam.h index e276d4efdff..c2d3d99a414 100644 --- a/include/myisam.h +++ b/include/myisam.h @@ -322,7 +322,9 @@ typedef enum /* Treat NULLs as inequal when collecting statistics (default for 4.1/5.0) */ MI_STATS_METHOD_NULLS_NOT_EQUAL, /* Treat NULLs as equal when collecting statistics (like 4.0 did) */ - MI_STATS_METHOD_NULLS_EQUAL + MI_STATS_METHOD_NULLS_EQUAL, + /* Ignore NULLs - count only tuples without NULLs in the index components */ + MI_STATS_METHOD_IGNORE_NULLS } enum_mi_stats_method; typedef struct st_mi_check_param @@ -349,7 +351,14 @@ typedef struct st_mi_check_param int tmpfile_createflag; myf myf_rw; IO_CACHE read_cache; + + /* + The next two are used to collect statistics, see update_key_parts for + description. + */ ulonglong unique_count[MI_MAX_KEY_SEG+1]; + ulonglong notnull_count[MI_MAX_KEY_SEG+1]; + ha_checksum key_crc[MI_MAX_POSSIBLE_KEY]; ulong rec_per_key_part[MI_MAX_KEY_SEG*MI_MAX_POSSIBLE_KEY]; void *thd; @@ -409,7 +418,8 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info, my_bool repair); int update_state_info(MI_CHECK *param, MI_INFO *info,uint update); void update_key_parts(MI_KEYDEF *keyinfo, ulong *rec_per_key_part, - ulonglong *unique, ulonglong records); + ulonglong *unique, ulonglong *notnull, + ulonglong records); int filecopy(MI_CHECK *param, File to,File from,my_off_t start, my_off_t length, const char *type); int movepoint(MI_INFO *info,byte *record,my_off_t oldpos, diff --git a/include/sha1.h b/include/sha1.h index 1c345469d3c..e67acbf96b8 100644 --- a/include/sha1.h +++ b/include/sha1.h @@ -60,8 +60,8 @@ typedef struct SHA1_CONTEXT C_MODE_START -int sha1_reset( SHA1_CONTEXT* ); -int sha1_input( SHA1_CONTEXT*, const uint8 *, unsigned int ); -int sha1_result( SHA1_CONTEXT* , uint8 Message_Digest[SHA1_HASH_SIZE] ); +int mysql_sha1_reset(SHA1_CONTEXT*); +int mysql_sha1_input(SHA1_CONTEXT*, const uint8 *, unsigned int); +int mysql_sha1_result(SHA1_CONTEXT* , uint8 Message_Digest[SHA1_HASH_SIZE]); C_MODE_END diff --git a/innobase/btr/makefilewin b/innobase/btr/makefilewin deleted file mode 100644 index a5806b74a51..00000000000 --- a/innobase/btr/makefilewin +++ /dev/null @@ -1,16 +0,0 @@ -include ..\include\makefile.i - -btr.lib: btr0cur.obj btr0btr.obj btr0pcur.obj btr0sea.obj - lib -out:..\libs\btr.lib btr0cur.obj btr0btr.obj btr0pcur.obj btr0sea.obj - -btr0cur.obj: btr0cur.c - $(CCOM) $(CFL) -c btr0cur.c - -btr0btr.obj: btr0btr.c - $(CCOM) $(CFL) -c btr0btr.c - -btr0sea.obj: btr0sea.c - $(CCOM) $(CFL) -c btr0sea.c - -btr0pcur.obj: btr0pcur.c - $(CCOM) $(CFL) -c btr0pcur.c diff --git a/innobase/buf/makefilewin b/innobase/buf/makefilewin deleted file mode 100644 index ce62cb95958..00000000000 --- a/innobase/buf/makefilewin +++ /dev/null @@ -1,20 +0,0 @@ -include ..\include\makefile.i - -buf.lib: buf0buf.obj buf0lru.obj buf0flu.obj buf0rea.obj - lib -out:..\libs\buf.lib buf0buf.obj buf0lru.obj buf0flu.obj buf0rea.obj - -buf0buf.obj: buf0buf.c - $(CCOM) $(CFL) -c buf0buf.c - -buf0lru.obj: buf0lru.c - $(CCOM) $(CFL) -c buf0lru.c - -buf0flu.obj: buf0flu.c - $(CCOM) $(CFL) -c buf0flu.c - -buf0rea.obj: buf0rea.c - $(CCOM) $(CFL) -c buf0rea.c - - - - diff --git a/innobase/data/makefilewin b/innobase/data/makefilewin deleted file mode 100644 index 785b75fbb2b..00000000000 --- a/innobase/data/makefilewin +++ /dev/null @@ -1,11 +0,0 @@ -include ..\include\makefile.i - -data.lib: data0type.obj data0data.obj - lib -out:..\libs\data.lib data0type.obj data0data.obj - -data0type.obj: data0type.c - $(CCOM) $(CFL) -c data0type.c - -data0data.obj: data0data.c - $(CCOM) $(CFL) -c data0data.c - diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index b0327f77fd3..0cdd593b678 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -2077,8 +2077,11 @@ dict_foreign_find_index( dict_table_t* table, /* in: table */ const char** columns,/* in: array of column names */ ulint n_cols, /* in: number of columns */ - dict_index_t* types_idx)/* in: NULL or an index to whose types the - column types must match */ + dict_index_t* types_idx, /* in: NULL or an index to whose types the + column types must match */ + ibool check_charsets) /* in: whether to check charsets. + only has an effect if types_idx != + NULL. */ { dict_index_t* index; const char* col_name; @@ -2107,7 +2110,8 @@ dict_foreign_find_index( if (types_idx && !cmp_types_are_equal( dict_index_get_nth_type(index, i), - dict_index_get_nth_type(types_idx, i))) { + dict_index_get_nth_type(types_idx, i), + check_charsets)) { break; } @@ -2178,7 +2182,8 @@ dict_foreign_add_to_cache( /*======================*/ /* out: DB_SUCCESS or error code */ dict_foreign_t* foreign, /* in, own: foreign key constraint */ - ibool check_types) /* in: TRUE=check type compatibility */ + ibool check_charsets) /* in: TRUE=check charset + compatibility */ { dict_table_t* for_table; dict_table_t* ref_table; @@ -2214,16 +2219,10 @@ dict_foreign_add_to_cache( } if (for_in_cache->referenced_table == NULL && ref_table) { - dict_index_t* types_idx; - if (check_types) { - types_idx = for_in_cache->foreign_index; - } else { - types_idx = NULL; - } index = dict_foreign_find_index(ref_table, (const char**) for_in_cache->referenced_col_names, for_in_cache->n_fields, - types_idx); + for_in_cache->foreign_index, check_charsets); if (index == NULL) { dict_foreign_error_report(ef, for_in_cache, @@ -2247,16 +2246,10 @@ dict_foreign_add_to_cache( } if (for_in_cache->foreign_table == NULL && for_table) { - dict_index_t* types_idx; - if (check_types) { - types_idx = for_in_cache->referenced_index; - } else { - types_idx = NULL; - } index = dict_foreign_find_index(for_table, (const char**) for_in_cache->foreign_col_names, for_in_cache->n_fields, - types_idx); + for_in_cache->referenced_index, check_charsets); if (index == NULL) { dict_foreign_error_report(ef, for_in_cache, @@ -3033,7 +3026,7 @@ col_loop1: /* Try to find an index which contains the columns as the first fields and in the right order */ - index = dict_foreign_find_index(table, column_names, i, NULL); + index = dict_foreign_find_index(table, column_names, i, NULL, TRUE); if (!index) { mutex_enter(&dict_foreign_err_mutex); @@ -3298,8 +3291,7 @@ try_find_index: if (referenced_table) { index = dict_foreign_find_index(referenced_table, - column_names, i, - foreign->foreign_index); + column_names, i, foreign->foreign_index, TRUE); if (!index) { dict_foreign_free(foreign); mutex_enter(&dict_foreign_err_mutex); diff --git a/innobase/dict/dict0load.c b/innobase/dict/dict0load.c index 0d58823a2ea..5127e258f56 100644 --- a/innobase/dict/dict0load.c +++ b/innobase/dict/dict0load.c @@ -1094,7 +1094,7 @@ dict_load_foreign( /* out: DB_SUCCESS or error code */ const char* id, /* in: foreign constraint id as a null-terminated string */ - ibool check_types)/* in: TRUE=check type compatibility */ + ibool check_charsets)/* in: TRUE=check charset compatibility */ { dict_foreign_t* foreign; dict_table_t* sys_foreign; @@ -1205,7 +1205,7 @@ dict_load_foreign( a new foreign key constraint but loading one from the data dictionary. */ - return(dict_foreign_add_to_cache(foreign, check_types)); + return(dict_foreign_add_to_cache(foreign, check_charsets)); } /*************************************************************************** @@ -1220,7 +1220,8 @@ dict_load_foreigns( /*===============*/ /* out: DB_SUCCESS or error code */ const char* table_name, /* in: table name */ - ibool check_types) /* in: TRUE=check type compatibility */ + ibool check_charsets) /* in: TRUE=check charset + compatibility */ { btr_pcur_t pcur; mem_heap_t* heap; @@ -1319,7 +1320,7 @@ loop: /* Load the foreign constraint definition to the dictionary cache */ - err = dict_load_foreign(id, check_types); + err = dict_load_foreign(id, check_charsets); if (err != DB_SUCCESS) { btr_pcur_close(&pcur); diff --git a/innobase/dict/makefilewin b/innobase/dict/makefilewin deleted file mode 100644 index e828d06943c..00000000000 --- a/innobase/dict/makefilewin +++ /dev/null @@ -1,21 +0,0 @@ -include ..\include\makefile.i - -dict.lib: dict0dict.obj dict0boot.obj dict0load.obj dict0mem.obj dict0crea.obj - lib -out:..\libs\dict.lib dict0dict.obj dict0boot.obj dict0load.obj dict0mem.obj dict0crea.obj - -dict0dict.obj: dict0dict.c - $(CCOM) $(CFL) -c dict0dict.c - -dict0boot.obj: dict0boot.c - $(CCOM) $(CFL) -c dict0boot.c - -dict0mem.obj: dict0mem.c - $(CCOM) $(CFL) -c dict0mem.c - -dict0crea.obj: dict0crea.c - $(CCOM) $(CFL) -c dict0crea.c - -dict0load.obj: dict0load.c - $(CCOM) $(CFL) -c dict0load.c - - diff --git a/innobase/dyn/makefilewin b/innobase/dyn/makefilewin deleted file mode 100644 index 71a58a756c1..00000000000 --- a/innobase/dyn/makefilewin +++ /dev/null @@ -1,9 +0,0 @@ -include ..\include\makefile.i - -dyn.lib: dyn0dyn.obj makefile - lib -out:..\libs\dyn.lib dyn0dyn.obj - -dyn0dyn.obj: dyn0dyn.c - $(CCOM) $(CFL) -c dyn0dyn.c - - diff --git a/innobase/eval/makefilewin b/innobase/eval/makefilewin deleted file mode 100644 index f587f2a05a6..00000000000 --- a/innobase/eval/makefilewin +++ /dev/null @@ -1,10 +0,0 @@ -include ..\include\makefile.i - -eval.lib: eval0eval.obj eval0proc.obj - lib -out:..\libs\eval.lib eval0eval.obj eval0proc.obj - -eval0eval.obj: eval0eval.c - $(CCOM) $(CFL) -c eval0eval.c - -eval0proc.obj: eval0proc.c - $(CCOM) $(CFL) -c eval0proc.c diff --git a/innobase/fil/makefilewin b/innobase/fil/makefilewin deleted file mode 100644 index 1b2d6ab2dbb..00000000000 --- a/innobase/fil/makefilewin +++ /dev/null @@ -1,10 +0,0 @@ -include ..\include\makefile.i - -fil.lib: fil0fil.obj - lib -out:..\libs\fil.lib fil0fil.obj - -fil0fil.obj: fil0fil.c - $(CCOM) $(CFL) -c fil0fil.c - - - diff --git a/innobase/fsp/makefilewin b/innobase/fsp/makefilewin deleted file mode 100644 index 503cf27f490..00000000000 --- a/innobase/fsp/makefilewin +++ /dev/null @@ -1,9 +0,0 @@ -include ..\include\makefile.i - -fsp.lib: fsp0fsp.obj - lib -out:..\libs\fsp.lib fsp0fsp.obj - -fsp0fsp.obj: fsp0fsp.c - $(CCOM) $(CFL) -c fsp0fsp.c - - diff --git a/innobase/fut/makefilewin b/innobase/fut/makefilewin deleted file mode 100644 index 40f3161015c..00000000000 --- a/innobase/fut/makefilewin +++ /dev/null @@ -1,12 +0,0 @@ -include ..\include\makefile.i - -fut.lib: fut0lst.obj fut0fut.obj - lib -out:..\libs\fut.lib fut0lst.obj fut0fut.obj - -fut0lst.obj: fut0lst.c - $(CCOM) $(CFL) -c fut0lst.c - -fut0fut.obj: fut0fut.c - $(CCOM) $(CFL) -c fut0fut.c - - diff --git a/innobase/ha/makefilewin b/innobase/ha/makefilewin deleted file mode 100644 index c7cd130ceea..00000000000 --- a/innobase/ha/makefilewin +++ /dev/null @@ -1,10 +0,0 @@ -include ..\include\makefile.i - -ha.lib: ha0ha.obj hash0hash.obj - lib -out:..\libs\ha.lib ha0ha.obj hash0hash.obj - -ha0ha.obj: ha0ha.c - $(CCOM) $(CFL) -c ha0ha.c - -hash0hash.obj: hash0hash.c - $(CCOM) $(CFL) -c hash0hash.c diff --git a/innobase/ibuf/makefilewin b/innobase/ibuf/makefilewin deleted file mode 100644 index 86bf9794520..00000000000 --- a/innobase/ibuf/makefilewin +++ /dev/null @@ -1,7 +0,0 @@ -include ..\include\makefile.i - -ibuf.lib: ibuf0ibuf.obj - lib -out:..\libs\ibuf.lib ibuf0ibuf.obj - -ibuf0ibuf.obj: ibuf0ibuf.c - $(CCOM) $(CFL) -c ibuf0ibuf.c diff --git a/innobase/include/Makefile.am b/innobase/include/Makefile.am index 102d25566da..3483556abe1 100644 --- a/innobase/include/Makefile.am +++ b/innobase/include/Makefile.am @@ -28,7 +28,7 @@ noinst_HEADERS = btr0btr.h btr0btr.ic btr0cur.h btr0cur.ic \ ha0ha.h ha0ha.ic hash0hash.h hash0hash.ic \ ibuf0ibuf.h ibuf0ibuf.ic ibuf0types.h lock0lock.h \ lock0lock.ic lock0types.h log0log.h log0log.ic log0recv.h \ - log0recv.ic mach0data.h mach0data.ic makefilewin.i \ + log0recv.ic mach0data.h mach0data.ic \ mem0dbg.h mem0dbg.ic mem0mem.h mem0mem.ic mem0pool.h \ mem0pool.ic mtr0log.h mtr0log.ic mtr0mtr.h mtr0mtr.ic \ mtr0types.h os0file.h os0proc.h os0proc.ic \ diff --git a/innobase/include/dict0dict.h b/innobase/include/dict0dict.h index 3333385ec56..bf1382e8bb2 100644 --- a/innobase/include/dict0dict.h +++ b/innobase/include/dict0dict.h @@ -197,7 +197,8 @@ dict_foreign_add_to_cache( /*======================*/ /* out: DB_SUCCESS or error code */ dict_foreign_t* foreign, /* in, own: foreign key constraint */ - ibool check_types); /* in: TRUE=check type compatibility */ + ibool check_charsets);/* in: TRUE=check charset + compatibility */ /************************************************************************* Checks if a table is referenced by foreign keys. */ diff --git a/innobase/include/dict0load.h b/innobase/include/dict0load.h index f13620bc6e8..741123614ab 100644 --- a/innobase/include/dict0load.h +++ b/innobase/include/dict0load.h @@ -82,7 +82,8 @@ dict_load_foreigns( /*===============*/ /* out: DB_SUCCESS or error code */ const char* table_name, /* in: table name */ - ibool check_types); /* in: TRUE=check type compatibility */ + ibool check_charsets);/* in: TRUE=check charsets + compatibility */ /************************************************************************ Prints to the standard output information on all tables found in the data dictionary system table. */ diff --git a/innobase/include/makefilewin.i b/innobase/include/makefilewin.i deleted file mode 100644 index f756cf2ea3a..00000000000 --- a/innobase/include/makefilewin.i +++ /dev/null @@ -1,34 +0,0 @@ -# File included in all makefiles of the database -# (c) Innobase Oy 1995 - 2000 - -CCOM=cl - -# Flags for the debug version -#CFL= -MTd -Za -Zi -W4 -WX -F8192 -D "WIN32" -#CFLN = -MTd -Zi -W4 -F8192 -D "WIN32" -#CFLW = -MTd -Zi -W3 -WX -F8192 -D "WIN32" -#LFL = - -# Flags for the fast version -#CFL= -MT -Zi -Og -O2 -W3 -WX -D "WIN32" -#CFLN = -MT -Zi -Og -O2 -W3 -D "WIN32" -#CFLW = -MT -Zi -Og -O2 -W3 -WX -D "WIN32" -#LFL = - -# Flags for the fast debug version -CFL= -MTd -Zi -W3 -WX -F8192 -D "WIN32" -CFLN = -MTd -Zi -W3 -F8192 -D "WIN32" -CFLW = -MTd -Zi -W3 -WX -F8192 -D "WIN32" -LFL = /link/NODEFAULTLIB:LIBCMT - -# Flags for the profiler version -#CFL= -MT -Zi -Og -O2 -W3 -WX -D "WIN32" -#CFLN = -MT -Zi -Og -O2 -WX -D "WIN32" -#CFLW = -MT -Zi -Og -O2 -W3 -WX -D "WIN32" -#LFL= -link -PROFILE - -# Flags for the fast version without debug info (= the production version) -#CFL= -MT -Og -O2 -G6 -W3 -WX -D "WIN32" -#CFLN = -MT -Og -O2 -G6 -W3 -D "WIN32" -#CFLW = -MT -Og -O2 -G6 -W3 -WX -D "WIN32" -#LFL = diff --git a/innobase/include/os0file.h b/innobase/include/os0file.h index 280a949c1c5..0091e942d2c 100644 --- a/innobase/include/os0file.h +++ b/innobase/include/os0file.h @@ -86,9 +86,10 @@ log. */ #define OS_FILE_NOT_FOUND 71 #define OS_FILE_DISK_FULL 72 #define OS_FILE_ALREADY_EXISTS 73 -#define OS_FILE_AIO_RESOURCES_RESERVED 74 /* wait for OS aio resources +#define OS_FILE_PATH_ERROR 74 +#define OS_FILE_AIO_RESOURCES_RESERVED 75 /* wait for OS aio resources to become available again */ -#define OS_FILE_ERROR_NOT_SPECIFIED 75 +#define OS_FILE_ERROR_NOT_SPECIFIED 76 /* Types for aio operations */ #define OS_FILE_READ 10 @@ -182,7 +183,7 @@ Creates a temporary file. */ FILE* os_file_create_tmpfile(void); /*========================*/ - /* out: temporary file handle (never NULL) */ + /* out: temporary file handle, or NULL on error */ /*************************************************************************** The os_file_opendir() function opens a directory stream corresponding to the directory named by the dirname argument. The directory stream is positioned diff --git a/innobase/include/rem0cmp.h b/innobase/include/rem0cmp.h index 712e263350e..6288d47bd63 100644 --- a/innobase/include/rem0cmp.h +++ b/innobase/include/rem0cmp.h @@ -24,7 +24,8 @@ cmp_types_are_equal( /* out: TRUE if the types are considered equal in comparisons */ dtype_t* type1, /* in: type 1 */ - dtype_t* type2); /* in: type 2 */ + dtype_t* type2, /* in: type 2 */ + ibool check_charsets); /* in: whether to check charsets */ /***************************************************************** This function is used to compare two data fields for which we know the data type. */ diff --git a/innobase/include/srv0srv.h b/innobase/include/srv0srv.h index 4352083b21f..992271e32ee 100644 --- a/innobase/include/srv0srv.h +++ b/innobase/include/srv0srv.h @@ -34,6 +34,12 @@ extern ibool srv_lower_case_table_names; extern mutex_t srv_monitor_file_mutex; /* Temporary file for innodb monitor output */ extern FILE* srv_monitor_file; +/* Mutex for locking srv_dict_tmpfile. +This mutex has a very high rank; threads reserving it should not +be holding any InnoDB latches. */ +extern mutex_t srv_dict_tmpfile_mutex; +/* Temporary file for output from the data dictionary */ +extern FILE* srv_dict_tmpfile; /* Server parameters which are read from the initfile */ diff --git a/innobase/lock/makefilewin b/innobase/lock/makefilewin deleted file mode 100644 index 149b0a2fed6..00000000000 --- a/innobase/lock/makefilewin +++ /dev/null @@ -1,7 +0,0 @@ -include ..\include\makefile.i - -lock.lib: lock0lock.obj - lib -out:..\libs\lock.lib lock0lock.obj - -lock0lock.obj: lock0lock.c - $(CCOM) $(CFL) -c lock0lock.c diff --git a/innobase/log/makefilewin b/innobase/log/makefilewin deleted file mode 100644 index a690af3bb35..00000000000 --- a/innobase/log/makefilewin +++ /dev/null @@ -1,10 +0,0 @@ -include ..\include\makefile.i - -log.lib: log0log.obj log0recv.obj - lib -out:..\libs\log.lib log0log.obj log0recv.obj - -log0log.obj: log0log.c - $(CCOM) $(CFL) -c log0log.c - -log0recv.obj: log0recv.c - $(CCOM) $(CFL) -c log0recv.c diff --git a/innobase/mach/makefilewin b/innobase/mach/makefilewin deleted file mode 100644 index 5306b0fe14c..00000000000 --- a/innobase/mach/makefilewin +++ /dev/null @@ -1,9 +0,0 @@ -include ..\include\makefile.i - -mach.lib: mach0data.obj - lib -out:..\libs\mach.lib mach0data.obj - -mach0data.obj: mach0data.c - $(CCOM) $(CFLN) -c mach0data.c - - diff --git a/innobase/makefilewin b/innobase/makefilewin deleted file mode 100644 index 1bd8d96e5e7..00000000000 --- a/innobase/makefilewin +++ /dev/null @@ -1,164 +0,0 @@ -doall: del_libs pb_all os.lib ut.lib mach.lib sync.lib mem.lib dyn.lib ha.lib com.lib thr.lib srv.lib fil.lib buf.lib log.lib mtr.lib log.lib fut.lib fsp.lib dict.lib data.lib rem.lib page.lib btr.lib ibuf.lib usr.lib que.lib trx.lib lock.lib read.lib row.lib pars.lib eval.lib ib_odbc.lib - -del_libs: - cd libs - del *.lib - cd .. - -pb_all: - pb_all - -os.lib: - cd os - remake - cd .. - -ut.lib: - cd ut - remake - cd .. - -mach.lib: - cd mach - remake - cd .. - -sync.lib: - cd sync - remake - cd .. - -mem.lib: - cd mem - remake - cd .. - -dyn.lib: - cd dyn - remake - cd .. - -ha.lib: - cd ha - remake - cd .. - -com.lib: - cd com - remake - cd .. - -thr.lib: - cd thr - remake - cd .. - -srv.lib: - cd srv - remake - cd .. - -fil.lib: - cd fil - remake - cd .. - -buf.lib: - cd buf - remake - cd .. - -log.lib: - cd log - remake - cd .. - -mtr.lib: - cd mtr - remake - cd .. - -fut.lib: - cd fut - remake - cd .. - -fsp.lib: - cd fsp - remake - cd .. - -dict.lib: - cd dict - remake - cd .. - -data.lib: - cd data - remake - cd .. - -rem.lib: - cd rem - remake - cd .. - -page.lib: - cd page - remake - cd .. - -btr.lib: - cd btr - remake - cd .. - -ibuf.lib: - cd ibuf - remake - cd .. - -usr.lib: - cd usr - remake - cd .. - -que.lib: - cd que - remake - cd .. - -trx.lib: - cd trx - remake - cd .. - -lock.lib: - cd lock - remake - cd .. - -read.lib: - cd read - remake - cd .. - -row.lib: - cd row - remake - cd .. - -pars.lib: - cd pars - remake - cd .. - -eval.lib: - cd eval - remake - cd .. - -ib_odbc.lib: - cd odbc - remake - cd .. diff --git a/innobase/mem/makefilewin b/innobase/mem/makefilewin deleted file mode 100644 index 8a30f8a6e71..00000000000 --- a/innobase/mem/makefilewin +++ /dev/null @@ -1,10 +0,0 @@ -include ..\include\makefile.i - -mem.lib: mem0mem.obj mem0pool.obj makefile - lib -out:..\libs\mem.lib mem0mem.obj mem0pool.obj - -mem0mem.obj: mem0mem.c mem0dbg.c - $(CCOM) $(CFL) -c mem0mem.c - -mem0pool.obj: mem0pool.c - $(CCOM) $(CFL) -c mem0pool.c diff --git a/innobase/mtr/makefilewin b/innobase/mtr/makefilewin deleted file mode 100644 index 9da0863bd28..00000000000 --- a/innobase/mtr/makefilewin +++ /dev/null @@ -1,14 +0,0 @@ -include ..\include\makefile.i - -mtr.lib: mtr0mtr.obj mtr0log.obj - lib -out:..\libs\mtr.lib mtr0mtr.obj mtr0log.obj - -mtr0mtr.obj: mtr0mtr.c - $(CCOM) $(CFL) -c mtr0mtr.c - -mtr0log.obj: mtr0log.c - $(CCOM) $(CFL) -c mtr0log.c - - - - diff --git a/innobase/my_cnf b/innobase/my_cnf deleted file mode 100644 index 94365237841..00000000000 --- a/innobase/my_cnf +++ /dev/null @@ -1,63 +0,0 @@ -# Example mysql config file. -# Copy this file to c:\my.cnf to set global options -# -# One can use all long options that the program supports. -# Run the program with --help to get a list of available options - -# This will be passed to all mysql clients -[client] -#password=my_password -port=3306 -#socket=MySQL - -# Here is entries for some specific programs -# The following values assume you have at least 32M ram - -# The MySQL server -[mysqld] -port=3306 -#socket=MySQL -skip-locking -default-character-set=latin1 -set-variable = key_buffer=2M -set-variable = max_allowed_packet=1M -set-variable = thread_stack=128K -set-variable = flush_time=1800 - -innobase_data_home_dir = e:\ibdata\ -innobase_data_file_path = ibdata1:25M;ibdata2:37M;ibdata3:100M;ibdata4:300M -set-variable = innobase_mirrored_log_groups=1 -innobase_log_group_home_dir = e:\iblogs\ -set-variable = innobase_log_files_in_group=3 -set-variable = innobase_log_file_size=5M -set-variable = innobase_log_buffer_size=8M -innobase_flush_log_at_trx_commit=1 -innobase_log_arch_dir = e:\iblogs\ -innobase_log_archive=0 -set-variable = innobase_buffer_pool_size=16M -set-variable = innobase_additional_mem_pool_size=2M -set-variable = innobase_file_io_threads=4 -set-variable = innobase_lock_wait_timeout=50 - - -# Uncomment the following row if you move the MySQL distribution to another -# location -#basedir = d:/mysql/ - -[mysqldump] -quick -set-variable = max_allowed_packet=16M - -[mysql] -no-auto-rehash - -[isamchk] -set-variable= key=16M - -[client_fltk] -help_file= c:\mysql\sql_client\MySQL.help -client_file= c:\mysql\MySQL.options -history_length=20 -database = test -queries_root= c:\mysql\queries -last_database_file= c:\mysql\lastdb diff --git a/innobase/os/makefilewin b/innobase/os/makefilewin deleted file mode 100644 index 8bc8d08611b..00000000000 --- a/innobase/os/makefilewin +++ /dev/null @@ -1,17 +0,0 @@ -include ..\include\makefile.i - -os.lib: os0sync.obj os0thread.obj os0proc.obj os0file.obj - lib -out:..\libs\os.lib os0sync.obj os0thread.obj os0proc.obj os0file.obj - -os0sync.obj: os0sync.c - $(CCOM) $(CFLW) -c os0sync.c - -os0thread.obj: os0thread.c - $(CCOM) $(CFLW) -c os0thread.c - -os0proc.obj: os0proc.c - $(CCOM) $(CFLW) -c os0proc.c - -os0file.obj: os0file.c - $(CCOM) $(CFLW) -c os0file.c - diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index 49f88c0d62a..6ef6f7cd545 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -303,6 +303,8 @@ os_file_get_last_error( return(OS_FILE_NOT_FOUND); } else if (err == EEXIST) { return(OS_FILE_ALREADY_EXISTS); + } else if (err == EXDEV || err == ENOTDIR || err == EISDIR) { + return(OS_FILE_PATH_ERROR); } else { return(100 + err); } @@ -352,7 +354,8 @@ os_file_handle_error( return(TRUE); - } else if (err == OS_FILE_ALREADY_EXISTS) { + } else if (err == OS_FILE_ALREADY_EXISTS + || err == OS_FILE_PATH_ERROR) { return(FALSE); } else { @@ -456,7 +459,8 @@ os_file_handle_error_no_exit( return(TRUE); - } else if (err == OS_FILE_ALREADY_EXISTS) { + } else if (err == OS_FILE_ALREADY_EXISTS + || err == OS_FILE_PATH_ERROR) { return(FALSE); } else { diff --git a/innobase/os/os0thread.c b/innobase/os/os0thread.c index 0278e3b2b66..e1a1119cfd4 100644 --- a/innobase/os/os0thread.c +++ b/innobase/os/os0thread.c @@ -147,6 +147,15 @@ os_thread_create( "InnoDB: Error: pthread_attr_setstacksize returned %d\n", ret); exit(1); } +#endif +#ifdef __NETWARE__ + ret = pthread_attr_setstacksize(&attr, + (size_t) NW_THD_STACKSIZE); + if (ret) { + fprintf(stderr, + "InnoDB: Error: pthread_attr_setstacksize returned %d\n", ret); + exit(1); + } #endif os_mutex_enter(os_sync_mutex); os_thread_count++; diff --git a/innobase/page/makefilewin b/innobase/page/makefilewin deleted file mode 100644 index 4a132cf828c..00000000000 --- a/innobase/page/makefilewin +++ /dev/null @@ -1,12 +0,0 @@ -include ..\include\makefile.i - -page.lib: page0page.obj page0cur.obj - lib -out:..\libs\page.lib page0page.obj page0cur.obj - -page0page.obj: page0page.c - $(CCOM) $(CFL) -c page0page.c - -page0cur.obj: page0cur.c - $(CCOM) $(CFL) -c page0cur.c - - diff --git a/innobase/pars/makefilewin b/innobase/pars/makefilewin deleted file mode 100644 index f183d89cbe2..00000000000 --- a/innobase/pars/makefilewin +++ /dev/null @@ -1,26 +0,0 @@ -include ..\include\makefile.i - -pars.lib: pars0grm.obj lexyy.obj pars0pars.obj pars0opt.obj pars0sym.obj rename_and_copy - lib -out:..\libs\pars.lib pars0grm.obj lexyy.obj pars0pars.obj pars0opt.obj pars0sym.obj - -pars0grm.obj: pars0grm.y - bs pars0grm.y - $(CCOM) $(CFLW) -c pars0grm.c - -rename_and_copy: - ren pars0grm.h pars0grm.h - copy pars0grm.h ..\include - -lexyy.obj: pars0lex.l - fl pars0lex.l - $(CCOM) $(CFLN) -c lexyy.c - -pars0pars.obj: pars0pars.c - $(CCOM) $(CFL) -c pars0pars.c - -pars0opt.obj: pars0opt.c - $(CCOM) $(CFL) -c pars0opt.c - -pars0sym.obj: pars0sym.c - $(CCOM) $(CFL) -c pars0sym.c - diff --git a/innobase/que/makefilewin b/innobase/que/makefilewin deleted file mode 100644 index 9661c716551..00000000000 --- a/innobase/que/makefilewin +++ /dev/null @@ -1,7 +0,0 @@ -include ..\include\makefile.i - -que.lib: que0que.obj - lib -out:..\libs\que.lib que0que.obj - -que0que.obj: que0que.c - $(CCOM) $(CFL) -c que0que.c diff --git a/innobase/read/makefilewin b/innobase/read/makefilewin deleted file mode 100644 index 39593993a67..00000000000 --- a/innobase/read/makefilewin +++ /dev/null @@ -1,7 +0,0 @@ -include ..\include\makefile.i - -read.lib: read0read.obj - lib -out:..\libs\read.lib read0read.obj - -read0read.obj: read0read.c - $(CCOM) $(CFL) -c read0read.c diff --git a/innobase/rem/makefilewin b/innobase/rem/makefilewin deleted file mode 100644 index 51ca4a92012..00000000000 --- a/innobase/rem/makefilewin +++ /dev/null @@ -1,12 +0,0 @@ -include ..\include\makefile.i - -rem.lib: rem0rec.obj rem0cmp.obj - lib -out:..\libs\rem.lib rem0rec.obj rem0cmp.obj - -rem0rec.obj: rem0rec.c - $(CCOM) $(CFL) -c rem0rec.c - -rem0cmp.obj: rem0cmp.c - $(CCOM) $(CFL) -c rem0cmp.c - - diff --git a/innobase/rem/rem0cmp.c b/innobase/rem/rem0cmp.c index f2dc8a7021a..ce3ed6e6355 100644 --- a/innobase/rem/rem0cmp.c +++ b/innobase/rem/rem0cmp.c @@ -98,7 +98,8 @@ cmp_types_are_equal( /* out: TRUE if the types are considered equal in comparisons */ dtype_t* type1, /* in: type 1 */ - dtype_t* type2) /* in: type 2 */ + dtype_t* type2, /* in: type 2 */ + ibool check_charsets) /* in: whether to check charsets */ { if (dtype_is_non_binary_string_type(type1->mtype, type1->prtype) && dtype_is_non_binary_string_type(type2->mtype, type2->prtype)) { @@ -106,12 +107,12 @@ cmp_types_are_equal( /* Both are non-binary string types: they can be compared if and only if the charset-collation is the same */ - if (dtype_get_charset_coll(type1->prtype) - == dtype_get_charset_coll(type2->prtype)) { + if (check_charsets) { + return(dtype_get_charset_coll(type1->prtype) + == dtype_get_charset_coll(type2->prtype)); + } else { return(TRUE); } - - return(FALSE); } if (dtype_is_binary_string_type(type1->mtype, type1->prtype) diff --git a/innobase/row/makefilewin b/innobase/row/makefilewin deleted file mode 100644 index c17240c6119..00000000000 --- a/innobase/row/makefilewin +++ /dev/null @@ -1,34 +0,0 @@ -include ..\include\makefile.i - -row.lib: row0mysql.obj row0upd.obj row0sel.obj row0umod.obj row0uins.obj row0ins.obj row0upd.obj row0undo.obj row0purge.obj row0vers.obj row0row.obj - lib -out:..\libs\row.lib row0mysql.obj row0sel.obj row0umod.obj row0uins.obj row0ins.obj row0upd.obj row0undo.obj row0purge.obj row0vers.obj row0row.obj - -row0mysql.obj: row0mysql.c - $(CCOM) $(CFL) -c row0mysql.c - -row0ins.obj: row0ins.c - $(CCOM) $(CFL) -c row0ins.c - -row0sel.obj: row0sel.c - $(CCOM) $(CFL) -c row0sel.c - -row0upd.obj: row0upd.c - $(CCOM) $(CFL) -c row0upd.c - -row0undo.obj: row0undo.c - $(CCOM) $(CFL) -c row0undo.c - -row0purge.obj: row0purge.c - $(CCOM) $(CFL) -c row0purge.c - -row0row.obj: row0row.c - $(CCOM) $(CFL) -c row0row.c - -row0vers.obj: row0vers.c - $(CCOM) $(CFL) -c row0vers.c - -row0umod.obj: row0umod.c - $(CCOM) $(CFL) -c row0umod.c - -row0uins.obj: row0uins.c - $(CCOM) $(CFL) -c row0uins.c diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c index 5ca1ee51cbd..26ae0e6cc76 100644 --- a/innobase/row/row0ins.c +++ b/innobase/row/row0ins.c @@ -522,18 +522,48 @@ row_ins_cascade_calc_update_vec( && ufield->new_val.len < dtype_get_fixed_size(type)) { + ulint cset; + ufield->new_val.data = mem_heap_alloc(heap, dtype_get_fixed_size(type)); ufield->new_val.len = dtype_get_fixed_size(type); - ut_a(dtype_get_pad_char(type) - != ULINT_UNDEFINED); - memset(ufield->new_val.data, - (byte)dtype_get_pad_char(type), - dtype_get_fixed_size(type)); - ut_memcpy(ufield->new_val.data, + /* Handle UCS2 strings differently. + As no new collations will be + introduced in 4.1, we hardcode the + charset-collation codes here. + In 5.0, the logic is based on + mbminlen. */ + cset = dtype_get_charset_coll( + dtype_get_prtype(type)); + + if (cset == 35/*ucs2_general_ci*/ + || cset == 90/*ucs2_bin*/ + || (cset >= 128/*ucs2_unicode_ci*/ + && cset <= 144 + /*ucs2_persian_ci*/)) { + /* space=0x0020 */ + ulint i; + for (i = 0; + i < ufield->new_val.len; + i += 2) { + mach_write_to_2(((byte*) + ufield->new_val.data) + + i, 0x0020); + } + } else { + ut_a(dtype_get_pad_char(type) + != ULINT_UNDEFINED); + + memset(ufield->new_val.data, + (byte)dtype_get_pad_char( + type), + ufield->new_val.len); + } + + memcpy(ufield->new_val.data, parent_ufield->new_val.data, parent_ufield->new_val.len); } diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 7ce5c766e06..ba50e6a3511 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -1804,7 +1804,7 @@ row_table_add_foreign_constraints( if (err == DB_SUCCESS) { /* Check that also referencing constraints are ok */ - err = dict_load_foreigns(name, trx->check_foreigns); + err = dict_load_foreigns(name, TRUE); } if (err != DB_SUCCESS) { @@ -2963,7 +2963,8 @@ row_rename_table_for_mysql( mem_heap_t* heap = NULL; const char** constraints_to_drop = NULL; ulint n_constraints_to_drop = 0; - ibool recovering_temp_table = FALSE; + ibool recovering_temp_table = FALSE; + ibool old_is_tmp, new_is_tmp; ulint len; ulint i; ibool success; @@ -3003,6 +3004,9 @@ row_rename_table_for_mysql( trx->op_info = "renaming table"; trx_start_if_not_started(trx); + old_is_tmp = row_is_mysql_tmp_table_name(old_name); + new_is_tmp = row_is_mysql_tmp_table_name(new_name); + if (row_mysql_is_recovered_tmp_table(new_name)) { recovering_temp_table = TRUE; @@ -3047,7 +3051,7 @@ row_rename_table_for_mysql( len = (sizeof str1) + (sizeof str2) + (sizeof str3) + (sizeof str5) - 4 + ut_strlenq(new_name, '\'') + ut_strlenq(old_name, '\''); - if (row_is_mysql_tmp_table_name(new_name)) { + if (new_is_tmp) { db_name_len = dict_get_db_name_len(old_name) + 1; /* MySQL is doing an ALTER TABLE command and it renames the @@ -3200,7 +3204,7 @@ row_rename_table_for_mysql( the table is stored in a single-table tablespace */ success = dict_table_rename_in_cache(table, new_name, - !row_is_mysql_tmp_table_name(new_name)); + !new_is_tmp); if (!success) { trx->error_state = DB_SUCCESS; trx_general_rollback_for_mysql(trx, FALSE, NULL); @@ -3217,19 +3221,16 @@ row_rename_table_for_mysql( goto funct_exit; } - err = dict_load_foreigns(new_name, trx->check_foreigns); + /* We only want to switch off some of the type checking in + an ALTER, not in a RENAME. */ + + err = dict_load_foreigns(new_name, + old_is_tmp ? trx->check_foreigns : TRUE); - if (row_is_mysql_tmp_table_name(old_name)) { + if (err != DB_SUCCESS) { + ut_print_timestamp(stderr); - /* MySQL is doing an ALTER TABLE command and it - renames the created temporary table to the name - of the original table. In the ALTER TABLE we maybe - created some FOREIGN KEY constraints for the temporary - table. But we want to load also the foreign key - constraint definitions for the original table name. */ - - if (err != DB_SUCCESS) { - ut_print_timestamp(stderr); + if (old_is_tmp) { fputs(" InnoDB: Error: in ALTER TABLE ", stderr); ut_print_name(stderr, trx, new_name); @@ -3237,36 +3238,23 @@ row_rename_table_for_mysql( "InnoDB: has or is referenced in foreign key constraints\n" "InnoDB: which are not compatible with the new table definition.\n", stderr); - - ut_a(dict_table_rename_in_cache(table, - old_name, FALSE)); - trx->error_state = DB_SUCCESS; - trx_general_rollback_for_mysql(trx, FALSE, - NULL); - trx->error_state = DB_SUCCESS; - } - } else { - if (err != DB_SUCCESS) { - - ut_print_timestamp(stderr); - + } else { fputs( " InnoDB: Error: in RENAME TABLE table ", stderr); ut_print_name(stderr, trx, new_name); fputs("\n" - "InnoDB: is referenced in foreign key constraints\n" - "InnoDB: which are not compatible with the new table definition.\n", + "InnoDB: is referenced in foreign key constraints\n" + "InnoDB: which are not compatible with the new table definition.\n", stderr); - - ut_a(dict_table_rename_in_cache(table, - old_name, FALSE)); - - trx->error_state = DB_SUCCESS; - trx_general_rollback_for_mysql(trx, FALSE, - NULL); - trx->error_state = DB_SUCCESS; } + + ut_a(dict_table_rename_in_cache(table, + old_name, FALSE)); + trx->error_state = DB_SUCCESS; + trx_general_rollback_for_mysql(trx, FALSE, + NULL); + trx->error_state = DB_SUCCESS; } } funct_exit: diff --git a/innobase/srv/makefilewin b/innobase/srv/makefilewin deleted file mode 100644 index 129c65ec220..00000000000 --- a/innobase/srv/makefilewin +++ /dev/null @@ -1,15 +0,0 @@ -include ..\include\makefile.i - -srv.lib: srv0srv.obj srv0que.obj srv0start.obj - lib -out:..\libs\srv.lib srv0srv.obj srv0que.obj srv0start.obj - -srv0srv.obj: srv0srv.c - $(CCOM) $(CFL) -c srv0srv.c - -srv0que.obj: srv0que.c - $(CCOM) $(CFL) -c srv0que.c - -srv0start.obj: srv0start.c - $(CCOM) $(CFL) -c srv0start.c - - diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index e56389a8541..d7bd698fe0e 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -334,6 +334,12 @@ mutex_t srv_innodb_monitor_mutex; mutex_t srv_monitor_file_mutex; /* Temporary file for innodb monitor output */ FILE* srv_monitor_file; +/* Mutex for locking srv_dict_tmpfile. +This mutex has a very high rank; threads reserving it should not +be holding any InnoDB latches. */ +mutex_t srv_dict_tmpfile_mutex; +/* Temporary file for output from the data dictionary */ +FILE* srv_dict_tmpfile; ulint srv_main_thread_process_no = 0; ulint srv_main_thread_id = 0; diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index 87f4c31257a..4d208ea2d15 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -1178,6 +1178,13 @@ NetWare. */ } } + mutex_create(&srv_dict_tmpfile_mutex); + mutex_set_level(&srv_dict_tmpfile_mutex, SYNC_DICT_OPERATION); + srv_dict_tmpfile = os_file_create_tmpfile(); + if (!srv_dict_tmpfile) { + return(DB_ERROR); + } + /* Restrict the maximum number of file i/o threads */ if (srv_n_file_io_threads > SRV_MAX_N_IO_THREADS) { @@ -1804,8 +1811,13 @@ innobase_shutdown_for_mysql(void) mem_free(srv_monitor_file_name); } } - + if (srv_dict_tmpfile) { + fclose(srv_dict_tmpfile); + srv_dict_tmpfile = 0; + } + mutex_free(&srv_monitor_file_mutex); + mutex_free(&srv_dict_tmpfile_mutex); /* 3. Free all InnoDB's own mutexes and the os_fast_mutexes inside them */ diff --git a/innobase/sync/makefilewin b/innobase/sync/makefilewin deleted file mode 100644 index 73cff40405a..00000000000 --- a/innobase/sync/makefilewin +++ /dev/null @@ -1,14 +0,0 @@ -include ..\include\makefile.i - -sync.lib: sync0sync.obj sync0rw.obj sync0arr.obj - lib -out:..\libs\sync.lib sync0sync.obj sync0rw.obj sync0arr.obj - -sync0sync.obj: sync0sync.c - $(CCOM) $(CFLN) -c sync0sync.c - -sync0rw.obj: sync0rw.c - $(CCOM) $(CFL) -c sync0rw.c - -sync0arr.obj: sync0arr.c - $(CCOM) $(CFL) -c sync0arr.c - diff --git a/innobase/thr/makefilewin b/innobase/thr/makefilewin deleted file mode 100644 index 3f29ea1d3e3..00000000000 --- a/innobase/thr/makefilewin +++ /dev/null @@ -1,9 +0,0 @@ -include ..\include\makefile.i - -thr.lib: thr0loc.obj - lib -out:..\libs\thr.lib thr0loc.obj - -thr0loc.obj: thr0loc.c - $(CCOM) $(CFL) -c thr0loc.c - - diff --git a/innobase/trx/makefilewin b/innobase/trx/makefilewin deleted file mode 100644 index 35588779d66..00000000000 --- a/innobase/trx/makefilewin +++ /dev/null @@ -1,26 +0,0 @@ -include ..\include\makefile.i - -trx.lib: trx0sys.obj trx0trx.obj trx0rseg.obj trx0undo.obj trx0rec.obj trx0roll.obj trx0purge.obj - lib -out:..\libs\trx.lib trx0sys.obj trx0trx.obj trx0rseg.obj trx0undo.obj trx0rec.obj trx0roll.obj trx0purge.obj - -trx0trx.obj: trx0trx.c - $(CCOM) $(CFL) -c -I.. trx0trx.c - -trx0sys.obj: trx0sys.c - $(CCOM) $(CFL) -c -I.. trx0sys.c - -trx0rseg.obj: trx0rseg.c - $(CCOM) $(CFL) -c -I.. trx0rseg.c - -trx0undo.obj: trx0undo.c - $(CCOM) $(CFL) -c -I.. trx0undo.c - -trx0rec.obj: trx0rec.c - $(CCOM) $(CFL) -c -I.. trx0rec.c - -trx0roll.obj: trx0roll.c - $(CCOM) $(CFL) -c -I.. trx0roll.c - -trx0purge.obj: trx0purge.c - $(CCOM) $(CFL) -c -I.. trx0purge.c - diff --git a/innobase/usr/makefilewin b/innobase/usr/makefilewin deleted file mode 100644 index 66a77275e9b..00000000000 --- a/innobase/usr/makefilewin +++ /dev/null @@ -1,7 +0,0 @@ -include ..\include\makefile.i - -usr.lib: usr0sess.obj - lib -out:..\libs\usr.lib usr0sess.obj - -usr0sess.obj: usr0sess.c - $(CCOM) $(CFL) -c usr0sess.c diff --git a/innobase/ut/makefilewin b/innobase/ut/makefilewin deleted file mode 100644 index 2fda190773b..00000000000 --- a/innobase/ut/makefilewin +++ /dev/null @@ -1,21 +0,0 @@ -include ..\include\makefile.i - -ut.lib: ut0ut.obj ut0mem.obj ut0byte.obj ut0dbg.obj ut0rnd.obj - lib -out:..\libs\ut.lib ut0ut.obj ut0mem.obj ut0byte.obj ut0dbg.obj ut0rnd.obj - -ut0ut.obj: ut0ut.c - $(CCOM) $(CFL) -c ut0ut.c - -ut0mem.obj: ut0mem.c - $(CCOM) $(CFL) -c ut0mem.c - -ut0byte.obj: ut0byte.c - $(CCOM) $(CFL) -c ut0byte.c - -ut0dbg.obj: ut0dbg.c - $(CCOM) $(CFL) -c ut0dbg.c - -ut0rnd.obj: ut0rnd.c - $(CCOM) $(CFL) -c ut0rnd.c - - diff --git a/isam/isamchk.c b/isam/isamchk.c index 2912131d25b..cacfca8be0a 100644 --- a/isam/isamchk.c +++ b/isam/isamchk.c @@ -244,7 +244,7 @@ static struct my_option my_long_options[] = "Analyze distribution of keys. Will make some joins in MySQL faster.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #ifdef __NETWARE__ - {"auto-close", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", + {"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"character-sets-dir", OPT_CHARSETS_DIR_IC, diff --git a/libmysql/Makefile.am b/libmysql/Makefile.am index 4bd9eddafb0..8e76d0f125d 100644 --- a/libmysql/Makefile.am +++ b/libmysql/Makefile.am @@ -43,33 +43,33 @@ link_sources: vs=`echo $(vio_objects) | sed "s;\.lo;.c;g"`; \ scs=`echo $(sql_cmn_objects) | sed "s;\.lo;.c;g"`; \ for f in $$ss; do \ - rm -f $(srcdir)/$$f; \ - @LN_CP_F@ $(srcdir)/../strings/$$f $(srcdir)/$$f; \ + rm -f $$f; \ + @LN_CP_F@ $(top_srcdir)/strings/$$f $$f; \ done; \ for f in $$vs $(vioheaders); do \ - rm -f $(srcdir)/$$f; \ - @LN_CP_F@ $(srcdir)/../vio/$$f $(srcdir)/$$f; \ + rm -f $$f; \ + @LN_CP_F@ $(top_srcdir)/vio/$$f $$f; \ done; \ for f in $$scs; do \ - rm -f $(srcdir)/$$f; \ - @LN_CP_F@ $(srcdir)/../sql-common/$$f $(srcdir)/$$f; \ + rm -f $$f; \ + @LN_CP_F@ $(top_srcdir)/sql-common/$$f $$f; \ done; \ for f in $(mystringsextra); do \ - rm -f $(srcdir)/$$f; \ - @LN_CP_F@ $(srcdir)/../strings/$$f $(srcdir)/$$f; \ + rm -f $$f; \ + @LN_CP_F@ $(top_srcdir)/strings/$$f $$f; \ done; \ for f in $$ds; do \ - rm -f $(srcdir)/$$f; \ - @LN_CP_F@ $(srcdir)/../dbug/$$f $(srcdir)/$$f; \ + rm -f $$f; \ + @LN_CP_F@ $(top_srcdir)/dbug/$$f $$f; \ done; \ for f in $$ms $(mysysheaders); do \ - rm -f $(srcdir)/$$f; \ - @LN_CP_F@ $(srcdir)/../mysys/$$f $(srcdir)/$$f; \ + rm -f $$f; \ + @LN_CP_F@ $(top_srcdir)/mysys/$$f $$f; \ done; \ - rm -f $(srcdir)/net.c; \ - @LN_CP_F@ $(srcdir)/../sql/net_serv.cc $(srcdir)/net.c ; \ - rm -f $(srcdir)/password.c; \ - @LN_CP_F@ $(srcdir)/../sql/password.c $(srcdir)/password.c + rm -f net.c; \ + @LN_CP_F@ $(top_srcdir)/sql/net_serv.cc net.c ; \ + rm -f password.c; \ + @LN_CP_F@ $(top_srcdir)/sql/password.c password.c # This part requires GNUmake # diff --git a/libmysql/Makefile.shared b/libmysql/Makefile.shared index bb4d252f385..3f72049bf43 100644 --- a/libmysql/Makefile.shared +++ b/libmysql/Makefile.shared @@ -75,7 +75,7 @@ mysysobjects2 = my_lib.lo mysysobjects = $(mysysobjects1) $(mysysobjects2) target_libadd = $(mysysobjects) $(mystringsobjects) $(dbugobjects) \ $(sql_cmn_objects) $(vio_objects) $(sqlobjects) -target_ldflags = -version-info @SHARED_LIB_VERSION@ +target_ldflags = -version-info @SHARED_LIB_VERSION@ @LD_VERSION_SCRIPT@ vio_objects= vio.lo viosocket.lo viossl.lo viosslfactories.lo CLEANFILES = $(target_libadd) $(SHLIBOBJS) \ $(target) diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 7c6d140d2ef..921f042922a 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -2733,7 +2733,7 @@ my_bool STDCALL mysql_stmt_attr_get(MYSQL_STMT *stmt, { switch (attr_type) { case STMT_ATTR_UPDATE_MAX_LENGTH: - *(unsigned long *) value= stmt->update_max_length; + *(my_bool*) value= stmt->update_max_length; break; default: return TRUE; diff --git a/libmysql/libmysql.ver.in b/libmysql/libmysql.ver.in new file mode 100644 index 00000000000..20eb0fd41bb --- /dev/null +++ b/libmysql/libmysql.ver.in @@ -0,0 +1 @@ +libmysqlclient_@SHARED_LIB_MAJOR_VERSION@ { global: *; }; diff --git a/libmysql_r/Makefile.am b/libmysql_r/Makefile.am index a76ef675189..f7cf00321cb 100644 --- a/libmysql_r/Makefile.am +++ b/libmysql_r/Makefile.am @@ -41,6 +41,6 @@ libmysqlclient_r_la_LDFLAGS = $(target_ldflags) link_sources: set -x; \ for f in `cd $(libmysql_dir) && echo *.[ch]`; do \ - rm -f $(srcdir)/$$f; \ - @LN_CP_F@ $(libmysql_dir)/$$f $(srcdir)/$$f; \ + rm -f $$f; \ + @LN_CP_F@ $(libmysql_dir)/$$f $$f; \ done diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am index f4e9d4e6b39..d6f68047296 100644 --- a/libmysqld/Makefile.am +++ b/libmysqld/Makefile.am @@ -122,19 +122,19 @@ endif link_sources: set -x; \ for f in $(sqlsources); do \ - rm -f $(srcdir)/$$f; \ - @LN_CP_F@ $(srcdir)/../sql/$$f $(srcdir)/$$f; \ + rm -f $$f; \ + @LN_CP_F@ $(top_srcdir)/sql/$$f $$f; \ done; \ for f in $(libmysqlsources); do \ - rm -f $(srcdir)/$$f; \ - @LN_CP_F@ $(srcdir)/../libmysql/$$f $(srcdir)/$$f; \ + rm -f $$f; \ + @LN_CP_F@ $(top_srcdir)/libmysql/$$f $$f; \ done; \ for f in $(sqlexamplessources); do \ - rm -f $(srcdir)/$$f; \ - @LN_CP_F@ $(srcdir)/../sql/examples/$$f $(srcdir)/$$f; \ + rm -f $$f; \ + @LN_CP_F@ $(top_srcdir)/sql/examples/$$f $$f; \ done; \ - rm -f $(srcdir)/client_settings.h; \ - @LN_CP_F@ $(srcdir)/../libmysql/client_settings.h $(srcdir)/client_settings.h; + rm -f client_settings.h; \ + @LN_CP_F@ $(top_srcdir)/libmysql/client_settings.h client_settings.h clean-local: diff --git a/libmysqld/examples/Makefile.am b/libmysqld/examples/Makefile.am index d19023c100f..588a6153a3b 100644 --- a/libmysqld/examples/Makefile.am +++ b/libmysqld/examples/Makefile.am @@ -20,14 +20,15 @@ client_sources = $(mysqltest_embedded_SOURCES) $(mysql_SOURCES) tests_sources= $(mysql_client_test_embedded_SOURCES) link_sources: + set -x; \ for f in $(client_sources); do \ - rm -f $(srcdir)/$$f; \ - @LN_CP_F@ $(srcdir)/../../client/$$f $(srcdir)/$$f; \ - done; + rm -f $$f; \ + @LN_CP_F@ $(top_srcdir)/client/$$f $$f; \ + done; \ for f in $(tests_sources); do \ - rm -f $(srcdir)/$$f; \ - @LN_CP_F@ $(srcdir)/../../tests/$$f $(srcdir)/$$f; \ - done; + rm -f $$f; \ + @LN_CP_F@ $(top_srcdir)/tests/$$f $$f; \ + done DEFS = -DEMBEDDED_LIBRARY INCLUDES = @MT_INCLUDES@ \ @@ -48,7 +49,7 @@ mysql_LDADD = @readline_link@ @TERMCAP_LIB@ $(LDADD) mysql_client_test_embedded_LINK = $(CXXLINK) mysql_client_test_embedded_SOURCES = mysql_client_test.c -clean: +clean-local: rm -f $(client_sources) rm -f $(tests_sources) diff --git a/libmysqld/ha_blackhole.cc b/libmysqld/ha_blackhole.cc new file mode 100755 index 00000000000..e69de29bb2d diff --git a/man/Makefile.am b/man/Makefile.am index 539c43dfed6..9702c4b2ace 100644 --- a/man/Makefile.am +++ b/man/Makefile.am @@ -17,30 +17,8 @@ ## Process this file with automake to create Makefile.in -man_MANS = mysql.1 isamchk.1 isamlog.1 mysql_zap.1 mysqlaccess.1 \ - mysqladmin.1 mysqld.1 mysqld_multi.1 mysqldump.1 mysqlshow.1 \ - perror.1 replace.1 mysqld_safe.1 mysql_fix_privilege_tables.1 - -EXTRA_DIST = mysql.1.in isamchk.1.in isamlog.1.in mysql_zap.1.in \ - mysqlaccess.1.in mysqladmin.1.in mysqld.1.in mysqld_multi.1.in \ - mysqldump.1.in mysqlshow.1.in perror.1.in replace.1.in mysqlman.1.in \ - mysqld_safe.1.in mysql_fix_privilege_tables.1.in - -CLEANFILES = $(man_MANS) - -SUFFIXES = .in - -.in: - @RM@ -f $@ $@-t - @SED@ \ - -e 's!@''MYSQL_BASE_VERSION''@!@MYSQL_BASE_VERSION@!' \ - -e 's!@''sysconfdir''@!@sysconfdir@!' \ - -e 's!@''bindir''@!$(bindir)!g' \ - -e 's!@''libexecdir''@!$(libexecdir)!g' \ - -e 's!@''localstatedir''@!$(localstatedir)!g' \ - -e 's!@''MYSQL_NO_DASH_VERSION''@!@MYSQL_NO_DASH_VERSION@!' \ - $< > $@-t - @MV@ $@-t $@ +man1_MANS = @man1_files@ +EXTRA_DIST = $(man1_MANS) # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/man/isamchk.1.in b/man/isamchk.1.in deleted file mode 100644 index d908e8af3ee..00000000000 --- a/man/isamchk.1.in +++ /dev/null @@ -1,145 +0,0 @@ -.TH isamchk 1 "19 December 2000" "MySQL @MYSQL_BASE_VERSION@" "MySQL database" -.SH NAME -.BR isamchk - \- Description, check and repair of ISAM tables. -Used without options all tables on the command will be checked for errors -.SH USAGE -isamchk [OPTIONS] tables[.ISM] -.SH SYNOPSIS -.B isamchk -.RB [ \-a | \-\-analyze ] -.RB [ \-# | \-\-debug=... ] -.RB [ \-\-character\-sets\-dir=...] -.RB [ \-C | \-\-default\-character\-set=...] -.RB [ \-d | \-\-description ] -.RB [ \-e | \-\-extend\-check ] -.RB [ \-f | \-\-force ] -.RB [ \-? | \-\-help ] -.RB [ \-i | \-\-information ] -.RB [ \-k | \-\-keys\-used=# ] -.RB [ \-l | \-\-no\-symlinks] -.RB [ \-q | \-\-quick ] -.RB [ \-r | \-\-recover ] -.RB [ \-o | \-\-safe\-recover ] -.RB [ \-O | "\-\-set\-variable var=option"] -.RB [ \-s | \-\-silent ] -.RB [ \-S | \-\-sort\-index ] -.RB [ \-R | \-\-sort\-records=#] -.RB [ \-u | \-\-unpack ] -.RB [ \-v | \-\-verbose ] -.RB [ \-V | \-\-version ] -.RB [ \-w | \-\-wait ] -.SH DESCRIPTION -.TP -.BR \-a | \-\-analyze -Analyze distribution of keys. Will make some joins in -MySQL faster. -.TP -.BR \-# | \-\-debug=... -Output debug log. Often this is 'd:t:o ,filename` -.TP -.BR \-\-character\-sets\-dir=... -Directory where character sets are -.TP -.BR \-C | \-\-default\-character\-set=... -Set the default character set -.TP -.BR \-d | \-\-description -Prints some information about table. -.TP -.BR \-e | \-\-extend\-check -Check the table VERY thoroughly. One need use this -only in extreme cases as isamchk should normally find -all errors even without this switch -.TP -.BR \-f | \-\-force -Overwrite old temporary files. -If one uses \-f when checking tables (running isamchk -without \-r), isamchk will automatically restart with -\-r on any wrong table. -.TP -.BR \-? | \-\-help -Display help and exit. -.TP -.BR \-i | \-\-information -Print statistics information about the table -.TP -.BR \-k | \-\-keys\-used=# -Used with '\-r'. Tell ISAM to update only the first -# keys. This can be used to get faster inserts! -.TP -.BR \-l | \-\-no\-symlinks -Do not follow symbolic links when repairing. Normally -isamchk repairs the table a symlink points at. -.TP -.BR \-q | \-\-quick -Used with \-r to get a faster repair. (The data file -isn't touched.) One can give a second '\-q' to force -isamchk to modify the original datafile. -.TP -.BR \-r | \-\-recover -Can fix almost anything except unique keys that aren't -unique. -.TP -.BR \-o | \-\-safe\-recover -Uses old recovery method; slower than '\-r' but can -handle a couple of cases that '\-r' cannot handle. -.TP -.BR \-O | " \-\-set\-variable var=option " -Change the value of a variable. -.TP -.BR \-s | \-\-silent -Only print errors. One can use two \-s to make isamchk -very silent -.TP -.BR \-S | \-\-sort\-index -Sort index blocks. This speeds up 'read\-next' in -applications -.TP -.BR \-R | \-\-sort\-records=# -Sort records according to an index. This makes your -data much more localized and may speed up things -(It may be VERY slow to do a sort the first time!) -.TP -.BR \-u | \-\-unpack -Unpack file packed with pack_isam. -.TP -.BR \-v | \-\-verbose -Print more information. This can be used with -\-d and \-e. Use many \-v for more verbosity! -.TP -.BR \-V | \-\-version -Print version and exit. -.TP -.BR \-w | \-\-wait -Wait if table is locked. -.SH "SEE ALSO" -isamlog(1), -mysql(1), -mysqlaccess(1), -mysqladmin(1), -mysqld(1), -mysqld_multi(1), -mysqld_safe(1), -mysqldump(1), -mysql_fix_privilege_tables(1), -mysqlshow(1), -mysql_zap(1), -perror(1), -replace(1) -.P -For more information please refer to the MySQL reference -manual, which may already be installed locally and which -is also available online at http://dev.mysql.com/doc/mysql/en -.SH BUGS -Please refer to http://bugs.mysql.com/ to report bugs. -.SH AUTHOR -Ver 1.0, distribution @MYSQL_NO_DASH_VERSION@ -Michael (Monty) Widenius (monty@mysql.com), -MySQL AB (http://www.mysql.com/). -This software comes with no warranty. -Manual page by L. (Kill-9) Pedersen -(kill-9@kill\-9.dk), Mercurmedia Data Model Architect / -system developer (http://www.mercurmedia.com) - -.\" end of man page diff --git a/man/isamlog.1.in b/man/isamlog.1.in deleted file mode 100644 index 5f69e70297a..00000000000 --- a/man/isamlog.1.in +++ /dev/null @@ -1,107 +0,0 @@ -.TH isamlog 1 "19 December 2000" "MySQL @MYSQL_BASE_VERSION@" "MySQL database" -.SH NAME -isamlog - Write info about whats in a nisam log file. -.SH USAGE -isamlog [-?iruvIV] [-c #] [-f #] [-F filepath/] [-o #] [-R file recordpos] [-w write_file] [log-filename [table ...]] -.SH SYNOPSIS -.B isamlog -.RB [ -? | -I ] -.RB [ -V ] -.RB [ -c ] -.RB [ -f ] -.RB [ -F ] -.RB [ -i ] -.RB [ -o ] -.RB [ "-p #" ] -.RB [ -r ] -.RB [ -R ] -.RB [ -u ] -.RB [ -v ] -.RB [ -w ] -.SH DESCRIPTION -.TP -.BR isamlog -.TP -.BR -? | -I -info -.TP -.BR -V -version -.TP -.BR -c -do only # commands -.TP -.BR -f -max open files -.TP -.BR -F -file path -.TP -.BR -i -extra info -.TP -.BR -o -offset -.TP -.BR "-p #" -remove # components from path -.TP -.BR -r -recover -.TP -.BR -R -file recordposition -.TP -.BR -u -update -.TP -.BR -v -verbose -.TP -.BR -w -write file -.SH NOTE -If no file name is given isam.log is used -One can give a second and a third '-v' for more verbose. -Normaly one does a update (-u). -If a recover is done all writes and all possibly updates and deletes is done -and errors are only counted. -If one gives table names as arguments only these tables will be updated - - - -.SH "SEE ALSO" -isamchk(1), -mysql(1), -mysqlaccess(1), -mysqladmin(1), -mysqld(1), -mysqld_multi(1), -mysqld_safe(1), -mysqldump(1), -mysql_fix_privilege_tables(1), -mysqlshow(1), -mysql_zap(1), -perror(1), -replace(1) -.P -For more information please refer to the MySQL reference -manual, which may already be installed locally and which -is also available online at http://dev.mysql.com/doc/mysql/en -.SH BUGS -Please refer to http://bugs.mysql.com/ to report bugs. - -.SH AUTHOR - -Ver 1.0, distribution @MYSQL_NO_DASH_VERSION@ -Michael (Monty) Widenius (monty@mysql.com), -MySQL AB (http://www.mysql.com/). -This software comes with no warranty. -Manual page by L. (Kill-9) Pedersen -(kill-9@kill-9.dk), Mercurmedia Data Model Architect / -system developer (http://www.mercurmedia.com) - - -.\" end of man page - - diff --git a/man/mysql.1.in b/man/mysql.1.in deleted file mode 100644 index c4463aa658b..00000000000 --- a/man/mysql.1.in +++ /dev/null @@ -1,160 +0,0 @@ -.TH mysql 1 "19 December 2000" "MySQL @MYSQL_BASE_VERSION@" "MySQL database" -.SH NAME -mysql \- text-based client for mysqld, a SQL-based relational database daemon -.SH USAGE -mysql [OPTIONS] [Database] -.SH SYNOPSIS -.B mysql -.RB [ \-B | \-\-batch ] -.RB [ \-# | \-\-debug= -.IR logfile ] -.RB [ \-T | \-\-debug-info ] -.RB [ \-e | \-\-exec= -.IR command ] -.RB [ \-f | \-\-force ] -.RB [ \-? | \-\-help ] -.RB [ \-h | \-\-host= -.IR hostname ] -.RB [ \-n | \-\-unbuffered ] -.RB [ \-p[pwd] ] -.RI [ \-\-password=[pwd] ] -.RB [ \-P | \-\-port= -.IR pnum ] -.RB [ \-q | \-\-quick ] -.RB [ \-r | \-\-raw ] -.RB [ \-s | \-\-silent ] -.RB [ \-S | \-\-socket= -.IR snum ] -.RB [ \-u | \-\-user= -.IR uname ] -.RB [ \-v | \-\-verbose ] -.RB [ \-V | \-\-version ] -.RB [ \-w | \-\-wait ] -.SH DESCRIPTION -The -.IR mysql -program provides a curses-based interface to the SQL-based database -server daemon, -.IR mysqld (1). -Full fuller documentation, refer to the HTML documents installed with -the package. -.SH OPTIONS -.TP -.BR \-B | \-\-batch -Print results with a tab as separator, -each row on a new line. -.TP -\fB\-#\fP|\fB\-\-debug=\fP\fIlogfile\fP -Employ the specified debug log. -.TP -.BR \-T | \-\-debug-info -Print debug information upon exiting. -.TP -\fB\-e | \-\-exec=\fP\fPcommand\fP -Execute the specified command and quit -.BR ( \-\-batch -is implicit). -.TP -.BR \-f | \-\-force -Continue even if the face of a SQL error. -.TP -.BR \-? | \-\-help -Display a help message and exit. -.TP -\fB\-h\fP|\fP\-\-host=\fP\fIhostname\fP -Connect to the specified host. -.TP -.BR \-n | \-\-unbuffered -Flush the buffer after each query. -.TP -\fB\-p\fP|\fB\-\-password\fP[\fB=\fP\fIpwd\fP] -Employ the specified password when connecting to the database server. -If a password is not supplied, it will be requested interactively. -.TP -\fB\-P\fR|\fB\-\-port=\fP\fIpnum\fP -Employ the specified port number for connecting to the database server. -.TP -.BR \-q | \-\-quick -Do not cache the result; print it row by row. -This may slow down the server if the output is suspended. -.TP -.BR \-r | \-\-raw -Write fields without conversion. -(used with -.BR \-\-batch ). -.TP -.BR \-s | \-\-silent -Silent mode: reduce the amount of output. -.TP -\fB\-S\fP|\fB\-\-socket=\fP\fIsnum\fP -Employ the specified socket file for connecting to the database server. -.TP -\fB\-u\fP|\fB\-\-user=\fP\fIuname\fP -Employ the specified user name for logging in to the server. -.TP -.BR \-v | \-\-verbose -Verbose mode: write more -Specifying this option -.I twice -produces a tabular output format. -.TP -.BR \-V | \-\-version -Print the -.I mysql -version number and exit. -.TP -.BR \-w | \-\-wait -Wait and retry if the database server connection is down. -.SH FILES -.TP 2.2i -.I /etc/my.cnf -MySQL configuration file -.TP -.I @bindir@/mysql -Client executable -.TP -.I @libexecdir@/mysqld -Server executable -.TP -.I @bindir@/mysqld_safe -executable shell script for starting mysqld safely -.TP -.I @localstatedir@ -location of database files -.SH EXAMPLE -You can also read a backup dump file back into MySQL with: -.TP -.BR mysql -\fP\fIdatabase\fP -.BR < -backup-file.sql -.SH "SEE ALSO" -isamchk(1), -isamlog(1), -mysqlaccess(1), -mysqladmin(1), -mysqld(1), -mysqld_multi(1), -mysqld_safe(1), -mysqldump(1), -mysql_fix_privilege_tables(1), -mysqlshow(1), -mysql_zap(1), -perror(1), -replace(1) -.P -For more information please refer to the MySQL reference -manual, which may already be installed locally and which -is also available online at http://dev.mysql.com/doc/mysql/en -.SH BUGS -Please refer to http://bugs.mysql.com/ to report bugs. -.SH AUTHOR -Ver 6.3, distribution @MYSQL_NO_DASH_VERSION@ -Michael (Monty) Widenius (monty@mysql.com), -MySQL AB (http://www.mysql.com/) -This software comes with no warranty. -Manual page by R. P. C. Rodgers, -Lister Hill National Center for Biomedical Communication, -U.S. National Library of Medicine -(rodgers@nlm.nih.gov). -.\" end of man page diff --git a/man/mysql_fix_privilege_tables.1.in b/man/mysql_fix_privilege_tables.1.in deleted file mode 100644 index fe1016e8d98..00000000000 --- a/man/mysql_fix_privilege_tables.1.in +++ /dev/null @@ -1,40 +0,0 @@ -.TH mysql 1 "17 March 2003" "MySQL @MYSQL_BASE_VERSION@" "MySQL database" -.SH NAME -mysql_fix_privilege_tables \- Fixes MySQL privilege tables. -.SH SYNOPSIS -mysql_fix_privilege_tables [mysql_root_password] -.SH DESCRIPTION -This scripts updates the mysql.user, mysql.db, mysql.host and the -mysql.func tables to MySQL 3.22.14 and above. - -This is needed if you want to use the new GRANT functions, -CREATE AGGREGATE FUNCTION or want to use the more secure passwords in 3.23 - -If you get 'Access denied' errors, run the script again -and give the MySQL root user password as an argument. - -.SH "SEE ALSO" -isamchk(1), -isamlog(1), -mysql(1), -mysqlaccess(1), -mysqladmin(1), -mysqld(1), -mysqld_multi(1), -mysqld_safe(1), -mysqldump(1), -mysqlshow(1), -mysql_zap(1), -perror(1), -replace(1) -.P -For more information please refer to the MySQL reference -manual, which may already be installed locally and which -is also available online at http://dev.mysql.com/doc/mysql/en -.SH BUGS -Please refer to http://bugs.mysql.com/ to report bugs. -.SH AUTHOR -This manpage was written by Christian Hammers . - -MySQL is available at http://www.mysql.com/. -.\" end of man page diff --git a/man/mysql_zap.1.in b/man/mysql_zap.1.in deleted file mode 100644 index fb030427dc2..00000000000 --- a/man/mysql_zap.1.in +++ /dev/null @@ -1,52 +0,0 @@ -.TH zap 1 "19 December 2000" "MySQL @MYSQL_BASE_VERSION@" "MySQL database" -.SH NAME -zap - a perl script used to kill processes -.SH USAGE -/usr/bin/mysql_zap [-signal] [-?Ift] pattern -.SH SYNOPSIS -.B zap -.RB [ \-I | \-? ] -.RB [ \-f ] -.RB [ \-t ] -.SH DESCRIPTION -.TP -.BR zap -supports by executing -.TP -.BR \-I | \-? -info -.TP -.BR \-f -force -.TP -.BR \-t -test -.SH NOTE -If -.BR -f -isn't given, ask user for confirmation for each process to kill. If signal isn't given, try first with signal 15 and after that with signal 9. If -.BR -t -is given the processes is only shown on stdout. -.SH "SEE ALSO" -isamchk(1), -isamlog(1), -mysql(1), -mysqlaccess(1), -mysqladmin(1), -mysqld(1), -mysqld_multi(1), -mysqld_safe(1), -mysqldump(1), -mysql_fix_privilege_tables(1), -mysqlshow(1), -perror(1), -replace(1) -.P -For more information please refer to the MySQL reference -manual, which may already be installed locally and which -is also available online at http://dev.mysql.com/doc/mysql/en -.SH BUGS -Please refer to http://bugs.mysql.com/ to report bugs. -.SH AUTHOR -Ver 1.0, distribution @MYSQL_NO_DASH_VERSION@ Michael (Monty) Widenius (monty@mysql.com), MySQL AB (http://www.mysql.com/). This software comes with no warranty. Manual page by L. (Kill-9) Pedersen (kill-9@kill-9.dk), Mercurmedia Data Model Architect / system developer (http://www.mercurmedia.com) -.\" end of man page diff --git a/man/mysqlaccess.1.in b/man/mysqlaccess.1.in deleted file mode 100644 index e0b3d314a10..00000000000 --- a/man/mysqlaccess.1.in +++ /dev/null @@ -1,125 +0,0 @@ -.TH mysqlaccess 1 "19 December 2000" "MySQL @MYSQL_BASE_VERSION@" "MySQL database" -.SH NAME -.BR mysqlaccess \- Create new users to mysql. -.SH USAGE -mysqlaccess [host [user [db]]] OPTIONS -.SH SYNOPSIS -.B mysqlaccess -.RB [ \-? | \-\-help ] -.RB [ \-v | \-\-version ] -.RB [ \-p | \-\-password=# ] -.RB [ \-h | \-\-host=# ] -.RB [ \-d | \-\-db=# ] -.RB [ \-U | \-\-superuser=# ] -.RB [ \-P | \-\-spassword=# ] -.RB [ \-H | \-\-rhost=# ] -.RB [ \-\-old_server ] -.RB [ \-b | \-\-brief ] -.RB [ \-t | \-\-table ] -.RB [ \-\-relnotes] -.RB [ \-\-plan ] -.RB [ \-\-howto ] -.RB [ \-\-debug=N ] -.RB [ \-\-copy ] -.RB [ \-\-preview ] -.RB [ \-\-commit ] -.RB [ \-\-rollback ] -.SH DESCRIPTION -.TP -.BR \-? | \-\-help -display this helpscreen and exit -.TP -.BR \-v | \-\-version -print information on the program `mysqlaccess' -.TP -.BR \-u | \-\-user=# -username for logging in to the db -.TP -.BR \-p | \-\-password=# -validate password for user -.TP -.BR \-h | \-\-host=# -name or IP\-number of the host -.TP -.BR \-d | \-\-db=# -name of the database -.TP -.BR \-U | \-\-superuser=# -connect as superuser -.TP -.BR \-P | \-\-spassword=# -password for superuser -.TP -.BR \-H | \-\-rhost=# -remote MySQL\-server to connect to -.TP -.BR \-\-old_server -connect to old MySQL\-server (before v3.21) which -does not yet know how to handle full where clauses. -.TP -.BR \-b | \-\-brief -single\-line tabular report -.TP -.BR \-t | \-\-table -report in table\-format -.TP -.BR \-\-relnotes -print release\-notes -.TP -.BR \-\-plan -print suggestions/ideas for future releases -.TP -.BR \-\-howto -some examples of how to run `mysqlaccess' -.TP -.BR \-\-debug=N -enter debuglevel N (0..3) -.TP -.BR \-\-copy -reload temporary grant\-tables from original ones -.TP -.BR \-\-preview -show differences in privileges after making -changes in (temporary) grant\-tables -.TP -.BR \-\-commit -copy grant\-rules from temporary tables to grant\-tables -(!don't forget to do an mysqladmin reload) -.TP -.BR \-\-rollback -undo the last changes to the grant\-tables. -.SH NOTE -At least the user and the db must be given (even with wildcards) -If no host is given, `localhost' is assumed -Wildcards (*,?,%,_) are allowed for host, user and db, but be sure -to escape them from your shell!! (i.e., type \\* or '*') -.SH "SEE ALSO" -isamchk(1), -isamlog(1), -mysql(1), -mysqladmin(1), -mysqld(1), -mysqld_multi(1), -mysqld_safe(1), -mysqldump(1), -mysql_fix_privilege_tables(1), -mysqlshow(1), -mysql_zap(1), -perror(1), -replace(1) -.P -For more information please refer to the MySQL reference -manual, which may already be installed locally and which -is also available online at http://dev.mysql.com/doc/mysql/en -.SH BUGS -Please refer to http://bugs.mysql.com/ to report bugs. -.SH AUTHOR -Ver 1.0, distribution @MYSQL_NO_DASH_VERSION@ -Michael (Monty) Widenius (monty@mysql.com), -MySQL AB (http://www.mysql.com/). -This software comes with no warranty. -Manual page by L. (Kill-9) Pedersen -(kill-9@kill\-9.dk), Mercurmedia Data Model Architect / -system developer (http://www.mercurmedia.com) - -.\" end of man page diff --git a/man/mysqladmin.1.in b/man/mysqladmin.1.in deleted file mode 100644 index e62cb32dc78..00000000000 --- a/man/mysqladmin.1.in +++ /dev/null @@ -1,209 +0,0 @@ -.TH mysqladmin 1 "19 December 2000" "MySQL @MYSQL_BASE_VERSION@" "MySQL database" -.SH NAME - mysqladmin [OPTIONS] command command.... \- A utility for performing administrative operations -.SH OPTION SYNOPSIS -.B mysqladmin -.RB [ \-# | \-\-debug= -.IR logfile ] -.RB [ \-f | \-\-force ] -.RB [ \-? | \-\-help ] -.BR [ --character-sets-dir=\fP\fIdirectory\fP ] -.RB [ \-C | \-\-compress ] -.RB [ \-h | \-\-host=[#] ] -.RB [ \-p[pwd] ] -.RI [ \-\-password=[pwd] ] -.RB [ \-P | \-\-port= -.IR pnum ] -.RB [ \-i | \-\-sleep= -.IR sec ] -.RB [ \-E | \-\-vertical ] -.RB [ \-s | \-\-silent ] -.RB [ \-S | \-\-socket= -.IR # ] -.RB [ \-r | \-\-relative ] -.RB [ \-t | \-\-timeout= -.IR # ] -.RB [ \-u | \-\-user= -.IR uname ] -.RB [ \-v | \-\-verbose ] -.RB [ \-V | \-\-version ] -.RB [ \-w | \-\-wait[=retries] ] -.SH OPTION DESCRIPTION -You can get a list of the options your version of -.IR mysqladmin -supports by executing -.BR "mysqladmin \-\-help" -.SH OPTIONS -.TP -.BR \-# | \-\-debug=\fP\fIlogfile\fP -Output debug log. Often this is 'd:t:o,filename` -.TP -.BR \-f | \-\-force -Don't ask for confirmation on drop database; with -multiple commands, continue even if an error occurs -.TP -.BR \-? | \-\-help - Display help and exit -.TP -.BR --character-sets-dir=\fP\fIdirectory\fP -Set the character set directory -.TP -.BR \-C | \-\-compress -Use compression in server/client protocol -.TP -\fB\-h\fP|\fP\-\-host=\fP\fIhostname\fP -Connect to host -.TP -\fB\-p\fP|\fB\-\-password\fP[\fB=\fP\fIpwd\fP] -Password to use when connecting to server -If password is not given it's asked from the tty -.TP -\fB\-P\fR|\fB\-\-port=\fP\fIpnum\fP -Port number to use for connection -.TP -\fB\-i\fR|\fB\-\-sleep=\fP\fIsec\fP -Execute commands again and again with a sleep between -.TP -.BR \-r | \-\-relative -Show difference between current and previous values -when used with -.BR -i -. Currently works only with -extended-status -.TP -.BR \-E | \-\-vertical -Print output vertically. Is similar to -.BR --relative, -but prints output vertically. -.TP -.BR \-s | \-\-silent -Silently exit if one can't connect to server -.TP -\fB\-S\fR|\fB\-\-socket=\fP\fIfile\fP -Socket file to use for connection -.TP -\fB\-t\fR|\fB\-\-timeout=\fP\fIsec\fP -Timeout for connection to the mysqld server -.TP -\fB\-u\fP|\fB\-\-user=\fP\fIuname\fP -User for login if not current user -.TP -.BR \-v | \-\-verbose -Write more information -.TP -.BR \-V | \-\-version -Output version information and exit -.TP -.BR \-w | \-\-wait - Wait and retry if connection is down -.SH COMMAND SYNOPSIS -.B MySQLADMIN -.RB [ "create \fP\fIdatabasename\fP "] -.RB [ "drop \fP\fIdatabasename\fP" ] -.RB [ extended-status ] -.RB [ flush-hosts ] -.RB [ flush-logs ] -.RB [ flush-tables ] -.RB [ flush-privileges ] -.RB [ " kill id,id,... " ] -.RB [ "password \fP\fInew-password\fP "] -.RB [ ping ] -.RB [ processlist ] -.RB [ reload ] -.RB [ refresh ] -.RB [ shutdown ] -.RB [ slave-start ] -.RB [ slave-stop ] -.RB [ status ] -.RB [ variables ] -.RB [ version ] - -.SH COMMANDS -Where command is a one or more of: (Commands may be shortened) -.TP -.BR "create databasename" -Create a new database -.TP -.BR "drop databasename" -Delete a database and all its tables -.TP -.BR extended-status -Gives an extended status message from the server -.TP -.BR flush-hosts -Flush all cached hosts -.TP -.BR flush-logs -Flush all logs -.TP -.BR flush-status -Clear status variables -.TP -.BR flush-tables -Flush all tables -.TP -.BR flush-threads -Flush the thread cache -.TP -.BR flush-privileges -Reload grant tables (same as reload) -.TP -.BR "kill id,id,..." -Kill mysql threads -.TP -.BR "password \fP\fInew-password\fP" -Change old password to new-password -.TP -.BR ping -Check if mysqld is alive -.TP -.BR processlist -Show list of active threads in server -.TP -.BR reload -Reload grant tables -.TP -.BR refresh -Flush all tables and close and open logfiles -.TP -.BR shutdown -Take server down -.TP -.BR status -Gives a short status message from the server -.TP -.BR variables -Prints variables available -.TP -.BR version -Get version info from server -.SH "SEE ALSO" -isamchk(1), -isamlog(1), -mysql(1), -mysqlaccess(1), -mysqld(1), -mysqld_multi(1), -mysqld_safe(1), -mysqldump(1), -mysql_fix_privilege_tables(1), -mysqlshow(1), -mysql_zap(1), -perror(1), -replace(1) -.P -For more information please refer to the MySQL reference -manual, which may already be installed locally and which -is also available online at http://dev.mysql.com/doc/mysql/en -.SH BUGS -Please refer to http://bugs.mysql.com/ to report bugs. -.SH AUTHOR -Ver 1.0, distribution @MYSQL_NO_DASH_VERSION@ -Michael (Monty) Widenius (monty@mysql.com), -MySQL AB (http://www.mysql.com/). -This software comes with no warranty. -Manual page by L. (Kill-9) Pedersen -(kill-9@kill-9.dk), Mercurmedia Data Model Architect / -system developer (http://www.mercurmedia.com) -.\" end of man page - diff --git a/man/mysqld.1.in b/man/mysqld.1.in deleted file mode 100644 index 73f07337f25..00000000000 --- a/man/mysqld.1.in +++ /dev/null @@ -1,234 +0,0 @@ -.TH mysqld 1 "19 December 2000" "MySQL @MYSQL_BASE_VERSION@" "MySQL database" -.SH NAME -mysqld \- The MySQL server demon -.SH USAGE -mysqld [OPTIONS] -.SH SYNOPSIS -.B mysqld -.RB [ \-\-ansi ] -.RB [ \-b | \-\-basedir=\fP\fIpath\fP ] -.RB [ \-\-big-tables ] -.RB [ \-\-bind\-address=IP ] -.RB [ \-\-character\-sets\-dir=\fP\fIpath\fP ] -.RB [ \-\-chroot=\fP\fIpath\fP ] -.RB [ \-h | \-\-datadir=\fP\fIpath\fP ] -.RB [ \-\-default\-character\-set=\fP\fIcharset\fP ] -.RB [ \-\-default\-table\-type=\fP\fItype \fP] -.RB [ \-\-delay\-key\-write\-for\-all\-tables ] -.RB [ \-\-enable\-locking ] -.RB [ \-T | \-\-exit\-info] -.RB [ \-\-flush ] -.RB [ \-? | \-\-help ] -.RB [ \-\-init\-file=file ] -.RB [ \-L | \-\-language=... ] -.RB [ \-l | \-\-log[=file] ] -.RB [ \-\-log\-isam[=file] ] -.RB [ \-\-log\-slow\-queries\fP\fI[=file]\fP ] -.RB [ \-\-log\-update\fP\fI[=file]\fP ] -.RB [ \-\-log\-long\-format ] -.RB [ \-\-low\-priority\-updates ] -.RB [ \-\-memlock ] -.RB [ " \-\-myisam\-recover [=option[,option...]]] where option is one of DEFAULT, BACKUP, FORCE or QUICK." ] -.RB [ \-\-pid\-file=\fP\fIpath\fP ] -.RB [ \-P | \-\-port=... ] -.RB [ \-o | \-\-old\-protocol ] -.RB [ \-\-one\-thread ] -.RB [ \-O | \-\-set\-variable var=\fP\fIoption\fP ] -.RB [ \-Sg | \-\-skip\-grant\-tables ] -.RB [ \-\-safe\-mode ] -.RB [ \-\-secure ] -.RB [ \-\-skip\-concurrent\-insert ] -.RB [ \-\-skip\-delay\-key\-write ] -.RB [ \-\-skip\-locking ] -.RB [ \-\-skip\-name\-resolve ] -.RB [ \-\-skip\-networking ] -.RB [ \-\-skip\-new ] -.RB [ \-\-skip\-host\-cache ] -.RB [ \-\-skip\-show\-database ] -.RB [ \-\-skip\-thread\-priority ] -.RB [ \-\-socket=path ] -.RB [ \-t | \-\-tmpdir=\fP\fIpath \fP] -.RB [ \-u | \-\-user=\fP\fIuser_name\fP ] -.RB [ \-V | \-\-version ] -.SH DESCRIPTION -.TP -.BR --ansi -Use ANSI SQL syntax instead of MySQL syntax. See section 5.2 Running MySQL in ANSI Mode. -.TP -.BR -b | --basedir=\fP\fIpath \fP -Path to installation directory. All paths are usually resolved relative to this. -.TP -.BR --big-tables -Allow big result sets by saving all temporary sets on file. It solves most 'table full' errors, but also slows down the queries where in\-memory tables would suffice. Since Version 3.23.2, MySQL is able to solve it automaticaly by using memory for small temporary tables and switching to disk tables where necessary. -.TP -.BR \-\-bind\-address=\fP\fIIP \fP -IP address to bind to. -.TP -.BR \-\-character\-sets\-dir=\fP\fIpath \fP -Directory where character sets are. See section 10.1.1 The Character Set Used for Data and Sorting. -.TP -.BR \-\-chroot=\fP\fIpath \fP -Chroot mysqld daemon during startup. Recommended security measure. It will somewhat limit LOAD DATA INFILE and SELECT ... INTO OUTFILE though. -.TP -.BR \-h | \-\-datadir=\fP\fIpath \fP -Path to the database root. -.TP -.BR \-\-default\-character\-set=\fP\fIcharset \fP -Set the default character set. See section 10.1.1 The Character Set Used for Data and Sorting. -.TP -.BR \-\-default\-table\-type=\fP\fItype \fP -Set the default table type for tables. See section 8 MySQL Table Types. -.TP -.BR \-\-delay\-key\-write\-for\-all\-tables -Don't flush key buffers between writes for any MyISAM table. See Mysql Manual section 12.2.3 Tuning Server Parameters. -.TP -.BR \-\-enable\-locking -Enable system locking. -.TP -.BR \-T | \-\-exit\-info -Print some debug info at exit. -.TP -.BR \-\-flush -Flush all changes to disk after each SQL command. Normally MySQL only does a write of all changes to disk after each SQL command and lets the operating system handle the syncing to disk. See section 20.2 What to Do if MySQL Keeps Crashing. -.TP -.BR \-? | \-\-help -Display short help and exit. -.TP -.BR \-\-init\-file=\fP\fIfile \fP -Read SQL commands from this file at startup. -.TP -.BR \-L | \-\-language=... -Client error messages in given language. May be given as a full path. See Mysql Manual section 10.1 What Languages Are Supported by MySQL?. -.TP -.BR \-l | \-\-log\fP\fI[=file] \fP -Log connections and queries to file. -.TP -.BR \-\-log\-isam\fP\fI[=file] \fP -Log all ISAM/MyISAM changes to file (only used when debugging ISAM/MyISAM). -.TP -.BR \-\-log\-slow\-queries\fP\fI[=file] \fP -Log all queries that have taken more than long_query_time seconds to execute to file. See Mysql Manual section 21.5 The Slow Query Log. -.TP -.BR \-\-log\-update\fP\fI[=file] \fP -Log updates to file.# where # is a unique number if not given. See Mysql Manual section 21.3 The Update Log. -.TP -.BR \-\-log\-long\-format -Log some extra information to update log. If you are using -.BR \-\-log\-slow\-queries -then queries that are not using indexes are logged to the slow query log. -.TP -.BR \-\-low\-priority\-updates -Table\-modifying operations (INSERT/DELETE/UPDATE) will have lower priority than selects. It can also be done via {INSERT | REPLACE | UPDATE | DELETE} LOW_PRIORITY ... to lower the priority of only one query, or by SET OPTION SQL_LOW_PRIORITY_UPDATES=1 to change the priority in one thread. See Mysql Manual section 12.2.9 Table Locking Issues. -.TP -.BR \-\-memlock -Lock the mysqld process in memory. This works only if your system supports the mlockall() system call. This may help if you have a problem where the operating system is causing mysqld to swap on disk. -.TP -.BR " \-\-myisam\-recover [=option[,option...]]] where option is one of DEFAULT, BACKUP, FORCE or QUICK. " -If this option is used, mysqld will on open check if the table is marked as crashed or if if the table wasn't closed properly (The last option only works if you are running with \-\-skip\-locking). If this is the case mysqld will run check on the table. If the table was corrupted, mysqld will attempt to repair it. The following options affects how the repair works. -.BR DEFAULT -The same as not giving any option to \-\-myisam\-recover. -.BR BACKUP -If the data table was changed during recover, save a backup of the `table_name.MYD' data file as `table_name\-datetime.BAK'. -.BR FORCE -Run recover even if we will loose more than one row from the .MYD file. -.BR QUICK -Don't check the rows in the table if there isn't any delete blocks. -Before a table is automaticly repaired, mysqld will add a note about this in the error log. If you want to be able to recover from most things without user intervention, you should use the options BACKUP,FORCE. This will force a repair of a table even if some rows would be deleted, but it will keep the old data file as a backup so that you can later examine what happened. -.TP -.BR \-\-pid\-file=\fP\fIpath \fP -Path to pid file used by mysqld_safe. -.TP -.BR \-P | \-\-port=... -Port number to listen for TCP/IP connections. -.TP -.BR \-o | \-\-old\-protocol -Use the 3.20 protocol for compatibility with some very old clients. See Mysql Manual section 4.17.3 Upgrading from Version 3.20 to Version 3.21. -.TP -.BR \-\-one\-thread -Only use one thread (for debugging under Linux). See Mysql Manual section H.1 Debugging a MySQL server. -.TP -.BR \-O | " \-\-set\-variable var=\fP\fIoption\fP " -Give a variable a value. \-\-help lists variables. You can find a full description for all variables in the SHOW VARIABLES section in this manual. See Mysql Manual section 7.28.4 SHOW VARIABLES. The tuning server parameters section includes information of how to optimize these. See Mysql Manual section 12.2.3 Tuning Server Parameters. -.TP -.BR \-Sg | \-\-skip\-grant\-tables -This option causes the server not to use the privilege system at all. This gives everyone full access to all databases! (You can tell a running server to start using the grant tables again by executing mysqladmin flush\-privileges or mysqladmin reload.) -.TP -.BR \-\-safe\-mode -Skip some optimize stages. Implies -.BR \-\-skip\-delay\-key\-write. -.TP -.BR \-\-secure -IP numbers returned by the gethostbyname() system call are checked to make sure they resolve back to the original hostname. This makes it harder for someone on the outside to get access by pretending to be another host. This option also adds some sanity checks of hostnames. The option is turned off by default in MySQL Version 3.21 because sometimes it takes a long time to perform backward resolutions. MySQL Version 3.22 caches hostnames (unless \-\-skip\-host\-cache is used) and has this option enabled by default. -.TP -.BR \-\-skip\-concurrent\-insert -Turn off the ability to select and insert at the same time on MyISAM tables. (This is only to be used if you think you have found a bug in this feature). -.TP -.BR \-\-skip\-delay\-key\-write -Ignore the delay_key_write option for all tables. See Mysql Manual section 12.2.3 Tuning Server Parameters. -.TP -.BR \-\-skip\-locking -Don't use system locking. To use isamchk or myisamchk you must shut down the server. See Mysql Manual section 1.6 How Stable Is MySQL?. Note that in MySQL Version 3.23 you can use REPAIR and CHECK to repair/check MyISAM tables. -.TP -.BR \-\-skip\-name\-resolve -Hostnames are not resolved. All Host column values in the grant tables must be IP numbers or localhost. -.TP -.BR \-\-skip\-networking -Don't listen for TCP/IP connections at all. All interaction with mysqld must be made via Unix sockets. This option is highly recommended for systems where only local requests are allowed. However, this option is unsuitable for systems that use MIT\-pthreads, because the MIT\-pthreads package doesn't support Unix sockets. -.TP -.BR \-\-skip\-new -Don't use new, possible wrong routines. Implies -.BR \-\-skip\-delay\-key\-write -. This will also set default table type to ISAM. See Mysql Manual section 8.3 ISAM Tables. -.TP -.BR \-\-skip\-host\-cache -Never use host name cache for faster name\-ip resolution, but query DNS server on every connect instead. -.TP -.BR \-\-skip\-show\-database -Don't allow 'SHOW DATABASE' commands, unless the user has process privilege. -.TP -.BR \-\-skip\-thread\-priority -Disable using thread priorities for faster response time. -.TP -.BR \-\-socket=\fP\fIpath \fP -Socket file to use for local connections instead of default /tmp/mysql.sock. -.TP -.BR \-t | \-\-tmpdir=\fP\fIpath\fP -Path for temporary files. It may be useful if your default /tmp directory resides on a partition too small to hold temporary tables. -.TP -.BR \-u | \-\-user=\fP\fIuser_name \fP -Run mysqld daemon as user user_name. This option is mandatory when starting mysqld as root. -.TP -.BR \-V | \-\-version -Output version information and exit. - -.SH NOTE -.SH "SEE ALSO" -isamchk(1), -isamlog(1), -mysql(1), -mysqlaccess(1), -mysqladmin(1), -mysqld_multi(1), -mysqld_safe(1), -mysqldump(1), -mysql_fix_privilege_tables(1), -mysqlshow(1), -mysql_zap(1), -perror(1), -replace(1) -.P -For more information please refer to the MySQL reference -manual, which may already be installed locally and which -is also available online at http://dev.mysql.com/doc/mysql/en -.SH BUGS -Please refer to http://bugs.mysql.com/ to report bugs. -.SH AUTHOR -Ver 1.0, distribution @MYSQL_NO_DASH_VERSION@ -Michael (Monty) Widenius (monty@mysql.com), -MySQL AB (http://www.mysql.com/). -This software comes with no warranty. -Manual page by L. (Kill-9) Pedersen -(kill-9@kill\-9.dk), Mercurmedia Data Model Architect / -system developer (http://www.mercurmedia.com) - -.\" end of man page diff --git a/man/mysqld_multi.1.in b/man/mysqld_multi.1.in deleted file mode 100644 index 58e5c71d01d..00000000000 --- a/man/mysqld_multi.1.in +++ /dev/null @@ -1,94 +0,0 @@ -.TH mysqld_multi 1 "19 December 2000" "MySQL @MYSQL_BASE_VERSION@" "MySQL database" -.SH NAME -mysqld_multi - is meant for managing several mysqld processes running in different UNIX sockets and TCP/IP ports. -.SH USAGE -mysqld_multi [OPTIONS] {start|stop|report} [GNR,GNR,GNR...] -.SH SYNOPSIS -.B mysqld_multi -.RB [ --config-file=... ] -.RB [ --example ] -.RB [ --help ] -.RB [ --log=... ] -.RB [ --mysqladmin=... ] -.RB [ --mysqld=... ] -.RB [ --no-log ] -.RB [ --password=... ] -.RB [ --tcp-ip ] -.RB [ --user=... ] -.RB [ --version ] -.SH DESCRIPTION -.TP -.BR mysqld_multi -.TP -.BR --config-file=... -Alternative config file. NOTE: This will not affect this program\'s own options (group [mysqld_multi]), but only groups [mysqld#]. Without this option everything will be searched from the ordinary my.cnf file. -.TP -.BR --example -Give an example of a config file. -.TP -.BR --help -Print this help and exit. -.TP -.BR --log=... -Log file. Full path to and the name for the log file. NOTE: If the file exists, everything will be appended. -.TP -.BR --mysqladmin=... -mysqladmin binary to be used for a server shutdown. -.TP -.BR --mysqld=... -mysqld binary to be used. Note that you can give mysqld_safe to this option also. The options are passed to mysqld. Just make sure you have mysqld in your environment variable PATH or fix mysqld_safe. -.TP -.BR --no-log -Print to stdout instead of the log file. By default the log file is turned on. -.TP -.BR --password=... -Password for user for mysqladmin. -.TP -.BR --tcp-ip -Connect to the MySQL server(s) via the TCP/IP port instead of the UNIX socket. This affects stopping and reporting. If a socket file is missing, the server may still be running, but can be accessed only via the TCP/IP port. By default connecting is done via the UNIX socket. -.TP -.BR --user=... -MySQL user for mysqladmin. -.TP -.BR --version -Print the version number and exit. -.SH NOTE -Please see the mysql manual for more detailed information on this. - - - -.SH "SEE ALSO" -isamchk(1), -isamlog(1), -mysql(1), -mysqlaccess(1), -mysqladmin(1), -mysqld(1), -mysqld_safe(1), -mysqldump(1), -mysql_fix_privilege_tables(1), -mysqlshow(1), -mysql_zap(1), -perror(1), -replace(1) -.P -For more information please refer to the MySQL reference -manual, which may already be installed locally and which -is also available online at http://dev.mysql.com/doc/mysql/en -.SH BUGS -Please refer to http://bugs.mysql.com/ to report bugs. - -.SH AUTHOR - -Ver 1.0, distribution @MYSQL_NO_DASH_VERSION@ -Michael (Monty) Widenius (monty@mysql.com), -MySQL AB (http://www.mysql.com/). -This software comes with no warranty. -Manual page by L. (Kill-9) Pedersen -(kill-9@kill-9.dk), Mercurmedia Data Model Architect / -system developer (http://www.mercurmedia.com) - - -.\" end of man page - - diff --git a/man/mysqld_safe.1.in b/man/mysqld_safe.1.in deleted file mode 100644 index 5aabd232a11..00000000000 --- a/man/mysqld_safe.1.in +++ /dev/null @@ -1,91 +0,0 @@ -.TH safe_mysqld 1 "19 December 2000" "MySQL @MYSQL_BASE_VERSION@" "MySQL database" -.SH NAME -mysqld_safe \- start the mysqld daemon on Unix. -.SH SYNOPSIS -.B mysqld_safe -.RB [ \-\-basedir=\fP\fIpath\fP ] -.RB [ \-\-core\-file\-size=# ] -.RB [ \-\-defaults\-extra\-file=\fP\fIpath\fP ] -.RB [ \-\-defaults\-file=\fP\fIpath\fP ] -.RB [ \-\-open\-files=# ] -.RB [ \-\-datadir=\fP\fIpath\fP ] -.RB [ \-\-err\-log=\fP\fIpath \fP] -.RB [ \-\-ledir=path ] -.RB [ \-\-log=\fP\fIpath\fP ] -.RB [ \-\-no\-defaults ] -.RB [ \-\-open\-files=# ] -.RB [ \-\-pid\-file=\fP\fIpath\fP ] -.RB [ \-\-port=# ] -.RB [ \-\-socket=\fP\fIpath\fP ] -.RB [ \-\-timezone=# ] -.RB [ \-\-user=# ] -.SH DESCRIPTION -mysqld_safe adds some safety features such as restarting the server when an -error occurs and logging run-time information to a log file. -.BR -.TP -.BR \-\-basedir=\fP\fIpath \fP -.TP -.BR \-\-core\-file\-size=# -Size of the core file mysqld should be able to create. Passed to ulimit \-c. -.TP -.BR \-\-defaults\-extra\-file=\fP\fIpath \fP -.TP -.BR \-\-defaults\-file=\fP\fIpath \fP -.TP -.BR \-\-datadir=\fP\fIpath \fP -.TP -.BR \-\-err\-log=\fP\fIpath \fP -.TP -.BR \-\-ledir=\fP\fIpath \fP -Path to mysqld -.TP -.BR \-\-log=\fP\fIpath \fP -.TP -.BR \-\-no\-defaults -.TP -.BR \-\-open\-files=# -Number of files mysqld should be able to open. Passed to ulimit \-n. -.TP -.BR \-\-pid\-file=\fP\fIpath \fP -.TP -.BR \-\-port=# -.TP -.BR \-\-socket=\fP\fIpath \fP -.TP -.BR \-\-timezone=# -Set the timezone (the TZ) variable to the value of this parameter. -.TP -.BR \-\-user=# -.SH NOTE -Note that all options on the command line to mysqld_safe are passed to mysqld. If you wants to use any options in mysqld_safe that mysqld doesn't support, you must specify these in the option file. -.SH "SEE ALSO" -isamchk(1), -isamlog(1), -mysql(1), -mysqlaccess(1), -mysqladmin(1), -mysqld(1), -mysqld_multi(1), -mysqldump(1), -mysql_fix_privilege_tables(1), -mysqlshow(1), -mysql_zap(1), -perror(1), -replace(1) -.P -For more information please refer to the MySQL reference -manual, which may already be installed locally and which -is also available online at http://dev.mysql.com/doc/mysql/en -.SH BUGS -Please refer to http://bugs.mysql.com/ to report bugs. -.SH AUTHOR -Ver 1.0, distribution @MYSQL_NO_DASH_VERSION@ -Michael (Monty) Widenius (monty@mysql.com), -MySQL AB (http://www.mysql.com). -This software comes with no warranty. -Manual page by L. (Kill-9) Pedersen -(kill-9@kill\-9.dk), Mercurmedia Data Model Architect / -system developer (http://www.mercurmedia.com) - -.\" end of man page diff --git a/man/mysqldump.1.in b/man/mysqldump.1.in deleted file mode 100644 index 0f581429af7..00000000000 --- a/man/mysqldump.1.in +++ /dev/null @@ -1,279 +0,0 @@ -.TH mysqldump 1 "19 December 2000" "MySQL @MYSQL_BASE_VERSION@" "MySQL database" -.SH NAME -mysqldump \- text\-based client for dumping or backing up mysql databases, tables and or data. - -.SH USAGE -.BR "mysqldump [\fP\fIOPTIONS\fP] database [\fP\fItables\fP]" -.TP -OR -.BR "mysqldump [\fP\fIOPTIONS\fP] \-\-databases [\fP\fIOPTIONS\fP] DB1 [\fP\fIDB2 DB3...\fP]" -.TP -OR -.BR "mysqldump [\fP\fIOPTIONS\fP] \-\-all-databases [\fP\fIOPTIONS\fP]" - -.SH OPTION SYNOPSIS -.B mysqldump -.RB [ \-A | \-\-all-databases ] -.RB [ \-a | \-\-all ] -.RB [ \-# | \-\-debug=... ] -.RB [ \-\-character-sets-dir=...] -.RB [ \-? | \-\-help ] -.RB [ \-B | \-\-databases ] -.RB [ \-c | \-\-complete-insert ] -.RB [ \-C | \-\-compress ] -.RB [ \-\-default-character-set=...] -.RB [ \-e | \-\-extended-insert ] -.RB [ \-\-add-drop-table ] -.RB [ \-\-add-locks ] -.RB [ \-\-allow-keywords ] -.RB [ \-\-delayed-insert ] -.RB [ \-F | \-\-flush-logs ] -.RB [ \-f | \-\-force ] -.RB [ \-h | \-\-host=... ] -.RB [ \-l | \-\-lock-tables ] -.RB [ \-n | \-\-no-create-db ] -.RB [ \-t | \-\-no-create-info ] -.RB [ \-d | \-\-no-data ] -.RB [ \-O | \-\-set-variable var=\fP\fIoption\fP ] -.RB [ \-\-opt ] -.RB [ \-p | \-\-password\fP\fI[=...]\fP ] -.RB [ \-P | \-\-port=... ] -.RB [ \-q | \-\-quick ] -.RB [ \-Q | \-\-quote-names ] -.RB [ \-S | \-\-socket=... ] -.RB [ \-\-tables ] -.RB [ \-T | \-\-tab=... ] -.RB [ \-u | \-\-user=# ] -.RB [ \-v | \-\-verbose ] -.RB [ \-V | \-\-version ] -.RB [ \-w | \-\-where= ] -.RB [ \-\-delayed ] -.RB [ \-e | \-\-extended-insert ] -.RB [ \-\-fields\-terminated\-by=... ] -.RB [ \-\-fields\-enclosed\-by=... ] -.RB [ \-\-fields-optionally\-enclosed\-by=... ] -.RB [ \-\-fields\-escaped\-by=... ] -.RB [ \-\-lines\-terminated\-by=... ] -.RB [ \-v | \-\-verbose ] -.RB [ \-V | \-\-version ] -.RB [ "\-O net_buffer_length=#, where # < 16M" ] -.SH DESCRIPTION -Dumping definition and data mysql database or table -.IR mysqldump -supports by executing -.TP -.BR \-A | \-\-all\-databases -Dump all the databases. This will be same as -.BR \-\-databases -with all databases selected. -.TP -.BR \-a | \-\-all -Include all MySQL specific create options. -.TP -.BR \-# | \-\-debug=... -Output debug log. Often this is 'd:t:o,filename`. -.TP -.BR \-\-character\-sets\-dir=... -Directory where character sets are -.TP -.BR \-? | \-\-help -Display this help message and exit. -.TP -.BR \-B | \-\-databases -To dump several databases. Note the difference in -usage; In this case no tables are given. All name -arguments are regarded as databasenames. -'USE db_name;' will be included in the output -.TP -.BR \-c | \-\-complete\-insert -Use complete insert statements. -.TP -.BR \-C | \-\-compress -Use compression in server/client protocol. -.TP -.BR \-\-default\-character\-set=... -Set the default character set -.TP -.BR \-e | \-\-extended\-insert -Allows utilization of the new, much faster -INSERT syntax. -.TP -.BR \-\-add\-drop\-table -Add a 'drop table' before each create. -.TP -.BR \-\-add\-locks -Add locks around insert statements. -.TP -.BR \-\-allow\-keywords -Allow creation of column names that are keywords. -.TP -.BR \-\-delayed\-insert -Insert rows with INSERT DELAYED. -.TP -.BR \-F | \-\-flush\-logs -Flush logs file in server before starting dump. -.TP -.BR \-f | \-\-force -Continue even if we get an sql\-error. -.TP -.BR \-h | \-\-host=... -Connect to host. -.TP -.BR \-l | \-\-lock\-tables -Lock all tables for read. -.TP -.BR \-n | \-\-no\-create\-db -\&'CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name;' -will not be put in the output. The above line will -be added otherwise, if -.BR \-\-databases -or -.BR \-\-all\-databases -option was given. -.TP -.BR \-t | \-\-no\-create\-info -Don't write table creation info. -.TP -.BR \-d | \-\-no\-data -No row information. -.TP -.BR \-O | "\-\-set\-variable var=option" -give a variable a value. -.BR \-\-help -lists variables -.TP -.BR \-\-opt -Same as -.BR " \-\-add\-drop\-table \-\-add\-locks \-\-all \-\-extended\-insert \-\-quick \-\-lock\-tables " -.TP -.BR \-p | \-\-password[=...] -Password to use when connecting to server. -If password is not given it's solicited on the tty. -.TP -.BR \-P | \-\-port=... -Port number to use for connection. -.TP -.BR \-q | \-\-quick -Don't buffer query, dump directly to stdout. -.TP -.BR \-Q | \-\-quote\-names -Quote table and column names with ` -.TP -.BR \-S | \-\-socket=... -Socket file to use for connection. -.TP -.BR \-\-tables -\fP\fIOverrides \fPoption -.BR \-\-databases (\-B). -.TP -.BR \-T | \-\-tab=... -Creates tab separated textfile for each table to -given path. (creates .sql and .txt files). -NOTE: This only works if mysqldump is run on -the same machine as the mysqld daemon. -.TP -.BR \-u | \-\-user=# -User for login if not current user. -.TP -.BR \-v | \-\-verbose -Print info about the various stages. -.TP -.BR \-V | \-\-version -Output version information and exit. -.TP -.BR \-w | \-\-where= -dump only selected records; QUOTES mandatory! -.TP -.BR \-\-delayed -Insert rows with the INSERT DELAYED command. -.TP -.BR \-e | \-\-extended-insert -Use the new multiline INSERT syntax. (Gives more compact and faster inserts statements.) -.TP -.BR \-\-fields\-terminated\-by=... -.TP -.BR \-\-fields\-enclosed\-by=... -.TP -.TP -.BR \-\-fields-optionally\-enclosed\-by=... -.TP -.BR \-\-fields\-escaped\-by=... -.TP -.BR \-\-lines\-terminated\-by=... -These options are used with the -.BR -T -option and have the same meaning as the corresponding clauses for LOAD DATA INFILE. See Mysql manual section 7.23 LOAD DATA INFILE Syntax. -.TP -.BR \-v | \-\-verbose -Verbose mode. Print out more information on what the program does. -.TP -.BR \-V | \-\-version -Print version information and exit. -.TP -.BR "\-O net_buffer_length=#, where # < 16M " -When creating multi-row-insert statements (as with option -.BR --extended-insert -or -.BR --opt -), mysqldump will create rows up to net_buffer_length length. If you increase this variable, you should also ensure that the max_allowed_packet variable in the MySQL server is bigger than the net_buffer_length. -.SH EXAMPLES -.TP -The most normal use of mysqldump is probably for making a backup of whole -databases. See the section on Database Backups in the MySQL Reference Manual. -.TP -mysqldump \-\-opt \fP\fIdatabase\fP > backup-file.sql -.TP -You can read this back into MySQL with: -.TP -.BR mysql -\fP\fIdatabase\fP -.BR < -backup-file.sql -.TP -or -.TP -.BR mysql -\-e 'source /patch\-to\-backup/backup\-file.sql' database -.TP -However, it's also very useful to populate another MySQL server with information from a database: -.TP -mysqldump \-\-opt \fP\fIdatabase\fP | mysql \-\-host=\fP\fIremote\-host\fP \-C database -.TP -It is possible to dump several databases with one command: -.TP -mysqldump \-\-databases database1 [ database2 database3... ] > my_databases.sql -.TP -If all the databases are wanted, one can use: -.TP -mysqldump \fP\fI\-\-all\-databases\fP > all_databases.sql - -.SH "SEE ALSO" -isamchk(1), -isamlog(1), -mysql(1), -mysqlaccess(1), -mysqladmin(1), -mysqld(1), -mysqld_multi(1), -mysqld_safe(1), -mysql_fix_privilege_tables(1), -mysqlshow(1), -mysql_zap(1), -perror(1), -replace(1) -.P -For more information please refer to the MySQL reference -manual, which may already be installed locally and which -is also available online at http://dev.mysql.com/doc/mysql/en -.SH BUGS -Please refer to http://bugs.mysql.com/ to report bugs. -.SH AUTHOR -Ver 1.0, distribution @MYSQL_NO_DASH_VERSION@ -Michael (Monty) Widenius (monty@mysql.com), -MySQL AB (http://www.mysql.com/). -This software comes with no warranty. -Manual page by L. (Kill-9) Pedersen -(kill-9@kill-9.dk), Mercurmedia Data Model Architect / -system developer (http://www.mercurmedia.com) - -.\" end of man page diff --git a/man/mysqlman.1.in b/man/mysqlman.1 similarity index 89% rename from man/mysqlman.1.in rename to man/mysqlman.1 index b09b01ca759..2170942ebd9 100644 --- a/man/mysqlman.1.in +++ b/man/mysqlman.1 @@ -1,4 +1,4 @@ -.TH mysqlman 1 "20 July 2004" "MySQL @MYSQL_BASE_VERSION@" "MySQL database" +.TH mysqlman 1 "20 July 2004" "MySQL" "MySQL database" .SH NAME mysqlman \- default man page for mysql .SH "DESCRIPTION" diff --git a/man/mysqlshow.1.in b/man/mysqlshow.1.in deleted file mode 100644 index 2db79ae070e..00000000000 --- a/man/mysqlshow.1.in +++ /dev/null @@ -1,98 +0,0 @@ -.TH mysqlshow 1 "19 December 2000" "MySQL @MYSQL_BASE_VERSION@" "MySQL database" -.SH NAME -.BR mysqlshow - \- Shows the structure of a mysql database (databases,tables and columns) -.SH USAGE -shell> mysqlshow [\fP\fIOPTIONS\fP] [\fP\fIdatabase [table [column]]\fP] -.SH SYNOPSIS -.B mysqlshow -.RB [ \-# | \-\-debug=...] -.RB [ \-? | \-\-help ] -.RB [ \-c | \-\-character\-sets\-dir=...] -.RB [ \-C | \-\-compress ] -.RB [ \-h | \-\-host=... ] -.RB [ \-i | \-\-status ] -.RB [ \-k | \-\-keys ] -.RB [ \-p | \-\-password\fP\fI[=...]\fP ] -.RB [ \-P | \-\-port=... ] -.RB [ \-S | \-\-socket=... ] -.RB [ \-u | \-\-user=# ] -.RB [ \-V | \-\-version ] -.SH DESCRIPTION -.TP -.BR \-# | \-\-debug=... -output debug log. Often this is 'd:t:o,filename` -.TP -.BR \-? | \-\-help -display help and exit -.TP -.BR \-c | \-\-character\-sets\-dir=... -Directory where character sets are -.TP -.BR \-C | \-\-compress -Use compression in server/client protocol -.TP -.BR \-h | \-\-host=... -connect to host -.TP -.BR \-i | \-\-status -Shows a lot of extra information about each table -.TP -.BR \-k | \-\-keys -show keys for table -.TP -.BR \-p | \-\-password \fP\fI[=...] \fP -password to use when connecting to server -If password is not given it's asked from the tty. -.TP -.BR \-P | \-\-port=... -Port number to use for connection -.TP -.BR \-S | \-\-socket=... -Socket file to use for connection -.TP -.BR \-u | \-\-user=# -user for login if not current user -.TP -.BR \-V | \-\-version -output version information and exit - - -.SH NOTE -If last argument contains a shell or SQL wildcard (*,?,% or _) then only -what's matched by the wildcard is shown. -If no database is given then all matching databases are shown. -If no table is given then all matching tables in database are shown -If no column is given then all matching columns and columntypes in table -are shown - -.SH "SEE ALSO" -isamchk(1), -isamlog(1), -mysql(1), -mysqlaccess(1), -mysqladmin(1), -mysqld(1), -mysqld_multi(1), -mysqld_safe(1), -mysqldump(1), -mysql_fix_privilege_tables(1), -mysql_zap(1), -perror(1), -replace(1) -.P -For more information please refer to the MySQL reference -manual, which may already be installed locally and which -is also available online at http://dev.mysql.com/doc/mysql/en -.SH BUGS -Please refer to http://bugs.mysql.com/ to report bugs. -.SH AUTHOR -Ver 1.0, distribution @MYSQL_NO_DASH_VERSION@ -Michael (Monty) Widenius (monty@mysql.com), -MySQL AB (http://www.mysql.com/). -This software comes with no warranty. -Manual page by L. (Kill-9) Pedersen -(kill-9@kill\-9.dk), Mercurmedia Data Model Architect / -system developer (http://www.mercurmedia.com) - -.\" end of man page diff --git a/man/perror.1.in b/man/perror.1.in deleted file mode 100644 index 45b343a9c3f..00000000000 --- a/man/perror.1.in +++ /dev/null @@ -1,58 +0,0 @@ -.TH perror 1 "19 December 2000" "MySQL @MYSQL_BASE_VERSION@" "MySQL database" -.SH NAME -perror \- describes a system or MySQL error code. -.SH SYNOPSIS -perror [OPTIONS] [ERRORCODE [ERRORCODE...]] -.SH DESCRIPTION -Can be used to display a description for a system error code, or an MyISAM/ISAM table handler error code. -The error messages are mostly system dependent. -.SH OPTIONS -.TP -.BR \-? | \-\-help -Displays this help and exits. -.TP -.BR \-I | \-\-info -Synonym for the above. -.TP -.BR \-s | \-\-silent -Only print the error message -.TP -.BR \-v | \-\-verbose -Print error code and message (default). -.TP -.BR \-V | \-\-version -Displays version information and exits. -.SH EXAMPLE -shell> perror 64 79 -Error code 64: Machine is not on the network -Error code 79: Can not access a needed shared library -.SH "SEE ALSO" -isamchk(1), -isamlog(1), -mysql(1), -mysqlaccess(1), -mysqladmin(1), -mysqld(1), -mysqld_multi(1), -mysqld_safe(1), -mysqldump(1), -mysql_fix_privilege_tables(1), -mysqlshow(1), -mysql_zap(1), -replace(1) -.P -For more information please refer to the MySQL reference -manual, which may already be installed locally and which -is also available online at http://dev.mysql.com/doc/mysql/en -.SH BUGS -Please refer to http://bugs.mysql.com/ to report bugs. -.SH AUTHOR -Ver 1.0, distribution @MYSQL_NO_DASH_VERSION@ -Michael (Monty) Widenius (monty@mysql.com), -MySQL AB (http://www.mysql.com/). -This software comes with no warranty. -Manual page by L. (Kill-9) Pedersen -(kill-9@kill\-9.dk), Mercurmedia Data Model Architect / -system developer (http://www.mercurmedia.com) - -.\" end of man page diff --git a/man/replace.1.in b/man/replace.1.in deleted file mode 100644 index 618ed0f5bea..00000000000 --- a/man/replace.1.in +++ /dev/null @@ -1,73 +0,0 @@ -.TH replace 1 "19 December 2000" "MySQL @MYSQL_BASE_VERSION@" "MySQL database" -.SH NAME -.TP -replace - A utility program that is used by msql2mysql, but that has more general applicability as well. replace changes strings in place in files or on the standard input. Uses a finite state machine to match longer strings first. Can be used to swap strings. -.SH USAGE -replace [-?svIV] from to from to ... -- [files] -.TP -or -.TP -replace [-?svIV] from to from to ... < fromfile > tofile -.SH SYNOPSIS -.B replace -.RB [ -? | -I ] -.RB [ -s ] -.RB [ -v ] -.SH DESCRIPTION -.TP -.BR replace -.TP -.BR -? | -I -info -.TP -.BR -s -silent -.TP -.BR -v -verbose -.SH EXTRA INFO -.B Special characters in from string: -.TP -\\^ -Match start of line. -.TP -\\$ -Match end of line. -.TP -\\b -Match space-character, start of line or end of line. For a end \\b the next replace starts locking at the end space-character. A \\b alone in a string matches only a space-character. -.SH EXAMPLE -this command swaps a and b in the given files: -.TP -shell> replace a b b a -- file1 file2 ... -.SH "SEE ALSO" -isamchk(1), -isamlog(1), -mysql(1), -mysqlaccess(1), -mysqladmin(1), -mysqld(1), -mysqld_multi(1), -mysqld_safe(1), -mysqldump(1), -mysql_fix_privilege_tables(1), -mysqlshow(1), -mysql_zap(1), -perror(1), -.P -For more information please refer to the MySQL reference -manual, which may already be installed locally and which -is also available online at http://dev.mysql.com/doc/mysql/en -.SH BUGS -Please refer to http://bugs.mysql.com/ to report bugs. -.SH AUTHOR -Ver 1.0, distribution @MYSQL_NO_DASH_VERSION@ -Michael (Monty) Widenius (monty@mysql.com), -MySQL AB (http://www.mysql.com/). -This software comes with no warranty. -Manual page by L. (Kill-9) Pedersen -(kill-9@kill-9.dk), Mercurmedia Data Model Architect / -system developer (http://www.mercurmedia.com) -.\" end of man page - - diff --git a/myisam/ft_parser.c b/myisam/ft_parser.c index 0b1e68b0d70..fad8b5c4273 100644 --- a/myisam/ft_parser.c +++ b/myisam/ft_parser.c @@ -147,8 +147,10 @@ byte ft_get_word(CHARSET_INFO *cs, byte **start, byte *end, for (word->pos=doc; docprev='A'; /* be sure *prev is true_word_char */ word->len= (uint)(doc-word->pos) - mwc; @@ -188,8 +190,10 @@ byte ft_simple_get_word(CHARSET_INFO *cs, byte **start, byte *end, for (word->pos=doc; doclen= (uint)(doc-word->pos) - mwc; diff --git a/myisam/mi_check.c b/myisam/mi_check.c index 7397ee4e204..15d1cceebfe 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -391,7 +391,10 @@ int chk_key(MI_CHECK *param, register MI_INFO *info) found_keys++; param->record_checksum=init_checksum; + bzero((char*) ¶m->unique_count,sizeof(param->unique_count)); + bzero((char*) ¶m->notnull_count,sizeof(param->notnull_count)); + if ((!(param->testflag & T_SILENT))) printf ("- check data record references index: %d\n",key+1); if (keyinfo->flag & HA_FULLTEXT) @@ -496,7 +499,9 @@ int chk_key(MI_CHECK *param, register MI_INFO *info) if (param->testflag & T_STATISTICS) update_key_parts(keyinfo, rec_per_key_part, param->unique_count, - (ulonglong) info->state->records); + param->stats_method == MI_STATS_METHOD_IGNORE_NULLS? + param->notnull_count: NULL, + (ulonglong)info->state->records); } if (param->testflag & T_INFO) { @@ -552,6 +557,96 @@ err: return 1; } + +/* + "Ignore NULLs" statistics collection method: process first index tuple. + + SYNOPSIS + mi_collect_stats_nonulls_first() + keyseg IN Array of key part descriptions + notnull INOUT Array, notnull[i] = (number of {keypart1...keypart_i} + tuples that don't contain NULLs) + key IN Key values tuple + + DESCRIPTION + Process the first index tuple - find out which prefix tuples don't + contain NULLs, and update the array of notnull counters accordingly. +*/ + +static +void mi_collect_stats_nonulls_first(HA_KEYSEG *keyseg, ulonglong *notnull, + uchar *key) +{ + uint first_null, kp; + first_null= ha_find_null(keyseg, key) - keyseg; + /* + All prefix tuples that don't include keypart_{first_null} are not-null + tuples (and all others aren't), increment counters for them. + */ + for (kp= 0; kp < first_null; kp++) + notnull[kp]++; +} + + +/* + "Ignore NULLs" statistics collection method: process next index tuple. + + SYNOPSIS + mi_collect_stats_nonulls_next() + keyseg IN Array of key part descriptions + notnull INOUT Array, notnull[i] = (number of {keypart1...keypart_i} + tuples that don't contain NULLs) + prev_key IN Previous key values tuple + last_key IN Next key values tuple + + DESCRIPTION + Process the next index tuple: + 1. Find out which prefix tuples of last_key don't contain NULLs, and + update the array of notnull counters accordingly. + 2. Find the first keypart number where the prev_key and last_key tuples + are different(A), or last_key has NULL value(B), and return it, so the + caller can count number of unique tuples for each key prefix. We don't + need (B) to be counted, and that is compensated back in + update_key_parts(). + + RETURN + 1 + number of first keypart where values differ or last_key tuple has NULL +*/ + +static +int mi_collect_stats_nonulls_next(HA_KEYSEG *keyseg, ulonglong *notnull, + uchar *prev_key, uchar *last_key) +{ + uint diffs[2]; + uint first_null_seg, kp; + HA_KEYSEG *seg; + + /* + Find the first keypart where values are different or either of them is + NULL. We get results in diffs array: + diffs[0]= 1 + number of first different keypart + diffs[1]=offset: (last_key + diffs[1]) points to first value in + last_key that is NULL or different from corresponding + value in prev_key. + */ + ha_key_cmp(keyseg, prev_key, last_key, USE_WHOLE_KEY, + SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL, diffs); + seg= keyseg + diffs[0] - 1; + + /* Find first NULL in last_key */ + first_null_seg= ha_find_null(seg, last_key + diffs[1]) - keyseg; + for (kp= 0; kp < first_null_seg; kp++) + notnull[kp]++; + + /* + Return 1+ number of first key part where values differ. Don't care if + these were NULLs and not .... We compensate for that in + update_key_parts. + */ + return diffs[0]; +} + + /* Check if index is ok */ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo, @@ -563,7 +658,7 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo, uchar key[MI_MAX_POSSIBLE_KEY_BUFF],*temp_buff,*keypos,*old_keypos,*endpos; my_off_t next_page,record; char llbuff[22]; - uint diff_pos; + uint diff_pos[2]; DBUG_ENTER("chk_index"); DBUG_DUMP("buff",(byte*) buff,mi_getint(buff)); @@ -621,7 +716,7 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo, } if ((*keys)++ && (flag=ha_key_cmp(keyinfo->seg,info->lastkey,key,key_length, - comp_flag, &diff_pos)) >=0) + comp_flag, diff_pos)) >=0) { DBUG_DUMP("old",(byte*) info->lastkey, info->lastkey_length); DBUG_DUMP("new",(byte*) key, key_length); @@ -640,8 +735,20 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo, if (param->stats_method == MI_STATS_METHOD_NULLS_NOT_EQUAL) ha_key_cmp(keyinfo->seg,info->lastkey,key,USE_WHOLE_KEY, SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL, - &diff_pos); - param->unique_count[diff_pos-1]++; + diff_pos); + else if (param->stats_method == MI_STATS_METHOD_IGNORE_NULLS) + { + diff_pos[0]= mi_collect_stats_nonulls_next(keyinfo->seg, + param->notnull_count, + info->lastkey, key); + } + param->unique_count[diff_pos[0]-1]++; + } + else + { + if (param->stats_method == MI_STATS_METHOD_IGNORE_NULLS) + mi_collect_stats_nonulls_first(keyinfo->seg, param->notnull_count, + key); } } (*key_checksum)+= mi_byte_checksum((byte*) key, @@ -1731,9 +1838,10 @@ static int sort_one_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo, _mi_kpointer(info,keypos-nod_flag,param->new_file_pos); /* Save new pos */ if (sort_one_index(param,info,keyinfo,next_page,new_file)) { - DBUG_PRINT("error",("From page: %ld, keyoffset: %d used_length: %d", - (ulong) pagepos, (int) (keypos - buff), - (int) used_length)); + DBUG_PRINT("error", + ("From page: %ld, keyoffset: %lu used_length: %d", + (ulong) pagepos, (ulong) (keypos - buff), + (int) used_length)); DBUG_DUMP("buff",(byte*) buff,used_length); goto err; } @@ -2088,7 +2196,8 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, if (param->testflag & T_STATISTICS) update_key_parts(sort_param.keyinfo, rec_per_key_part, sort_param.unique, - (ulonglong) info->state->records); + param->stats_method == MI_STATS_METHOD_IGNORE_NULLS? + sort_param.notnull: NULL,(ulonglong) info->state->records); share->state.key_map|=(ulonglong) 1 << sort_param.key; if (sort_param.fix_datafile) @@ -3232,15 +3341,15 @@ int sort_write_record(MI_SORT_PARAM *sort_param) static int sort_key_cmp(MI_SORT_PARAM *sort_param, const void *a, const void *b) { - uint not_used; + uint not_used[2]; return (ha_key_cmp(sort_param->seg, *((uchar**) a), *((uchar**) b), - USE_WHOLE_KEY, SEARCH_SAME,¬_used)); + USE_WHOLE_KEY, SEARCH_SAME, not_used)); } /* sort_key_cmp */ static int sort_key_write(MI_SORT_PARAM *sort_param, const void *a) { - uint diff_pos; + uint diff_pos[2]; char llbuff[22],llbuff2[22]; SORT_INFO *sort_info=sort_param->sort_info; MI_CHECK *param= sort_info->param; @@ -3250,16 +3359,26 @@ static int sort_key_write(MI_SORT_PARAM *sort_param, const void *a) { cmp=ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey, (uchar*) a, USE_WHOLE_KEY,SEARCH_FIND | SEARCH_UPDATE, - &diff_pos); + diff_pos); if (param->stats_method == MI_STATS_METHOD_NULLS_NOT_EQUAL) ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey, (uchar*) a, USE_WHOLE_KEY, - SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL, &diff_pos); - sort_param->unique[diff_pos-1]++; + SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL, diff_pos); + else if (param->stats_method == MI_STATS_METHOD_IGNORE_NULLS) + { + diff_pos[0]= mi_collect_stats_nonulls_next(sort_param->seg, + sort_param->notnull, + sort_info->key_block->lastkey, + (uchar*)a); + } + sort_param->unique[diff_pos[0]-1]++; } else { cmp= -1; + if (param->stats_method == MI_STATS_METHOD_IGNORE_NULLS) + mi_collect_stats_nonulls_first(sort_param->seg, sort_param->notnull, + (uchar*)a); } if ((sort_param->keyinfo->flag & HA_NOSAME) && cmp == 0) { @@ -3978,24 +4097,34 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info, /* Update statistics for each part of an index - + SYNOPSIS update_key_parts() - keyinfo Index information (only key->keysegs used) + keyinfo IN Index information (only key->keysegs used) rec_per_key_part OUT Store statistics here - unique IN Array of #distinct values collected over index - run. + unique IN Array of (#distinct tuples) + notnull_tuples IN Array of (#tuples), or NULL records Number of records in the table - - NOTES + + DESCRIPTION + This function is called produce index statistics values from unique and + notnull_tuples arrays after these arrays were produced with sequential + index scan (the scan is done in two places: chk_index() and + sort_key_write()). + + This function handles all 3 index statistics collection methods. + Unique is an array: - unique[0]= (#different values of {keypart1}) - 1 - unique[1]= (#different values of {keypart2,keypart1} tuple) - unique[0] - 1 - ... - The 'unique' array is collected in one sequential scan through the entire - index. This is done in two places: in chk_index() and in sort_key_write(). - Statistics collection may consider NULLs as either equal or unequal (see - SEARCH_NULL_ARE_NOT_EQUAL, MI_STATS_METHOD_*). + unique[0]= (#different values of {keypart1}) - 1 + unique[1]= (#different values of {keypart1,keypart2} tuple)-unique[0]-1 + ... + + For MI_STATS_METHOD_IGNORE_NULLS method, notnull_tuples is an array too: + notnull_tuples[0]= (#of {keypart1} tuples such that keypart1 is not NULL) + notnull_tuples[1]= (#of {keypart1,keypart2} tuples such that all + keypart{i} are not NULL) + ... + For all other statistics collection methods notnull_tuples==NULL. Output is an array: rec_per_key_part[k] = @@ -4007,25 +4136,53 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info, index tuples} = #tuples-in-the-index / #distinct-tuples-in-the-index. + + The #tuples-in-the-index and #distinct-tuples-in-the-index have different + meaning depending on which statistics collection method is used: + + MI_STATS_METHOD_* how are nulls compared? which tuples are counted? + NULLS_EQUAL NULL == NULL all tuples in table + NULLS_NOT_EQUAL NULL != NULL all tuples in table + IGNORE_NULLS n/a tuples that don't have NULLs */ void update_key_parts(MI_KEYDEF *keyinfo, ulong *rec_per_key_part, - ulonglong *unique, ulonglong records) + ulonglong *unique, ulonglong *notnull, + ulonglong records) { - ulonglong count=0,tmp; + ulonglong count=0,tmp, unique_tuples; + ulonglong tuples= records; uint parts; for (parts=0 ; parts < keyinfo->keysegs ; parts++) { count+=unique[parts]; - if (count == 0) - tmp=records; + unique_tuples= count + 1; + if (notnull) + { + tuples= notnull[parts]; + /* + #(unique_tuples not counting tuples with NULLs) = + #(unique_tuples counting tuples with NULLs as different) - + #(tuples with NULLs) + */ + unique_tuples -= (records - notnull[parts]); + } + + if (unique_tuples == 0) + tmp= 1; + else if (count == 0) + tmp= tuples; /* 1 unique tuple */ else - tmp= (records + (count+1)/2) / (count+1); - /* for some weird keys (e.g. FULLTEXT) tmp can be <1 here. - let's ensure it is not */ + tmp= (tuples + unique_tuples/2) / unique_tuples; + + /* + for some weird keys (e.g. FULLTEXT) tmp can be <1 here. + let's ensure it is not + */ set_if_bigger(tmp,1); if (tmp >= (ulonglong) ~(ulong) 0) tmp=(ulonglong) ~(ulong) 0; + *rec_per_key_part=(ulong) tmp; rec_per_key_part++; } diff --git a/myisam/mi_delete.c b/myisam/mi_delete.c index b964cb35dd8..6c302aecea1 100644 --- a/myisam/mi_delete.c +++ b/myisam/mi_delete.c @@ -157,7 +157,7 @@ static int _mi_ck_real_delete(register MI_INFO *info, MI_KEYDEF *keyinfo, goto err; } if ((error=d_search(info,keyinfo, - (keyinfo->flag & HA_FULLTEXT ? SEARCH_FIND + (keyinfo->flag & HA_FULLTEXT ? SEARCH_FIND | SEARCH_UPDATE : SEARCH_SAME), key,key_length,old_root,root_buff)) >0) { @@ -390,7 +390,8 @@ static int del(register MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *key, MYISAM_SHARE *share=info->s; MI_KEY_PARAM s_temp; DBUG_ENTER("del"); - DBUG_PRINT("enter",("leaf_page: %ld keypos: %lx",leaf_page,keypos)); + DBUG_PRINT("enter",("leaf_page: %ld keypos: 0x%lx", leaf_page, + (ulong) keypos)); DBUG_DUMP("leaf_buff",(byte*) leaf_buff,mi_getint(leaf_buff)); endpos=leaf_buff+mi_getint(leaf_buff); @@ -495,7 +496,8 @@ static int underflow(register MI_INFO *info, register MI_KEYDEF *keyinfo, MI_KEY_PARAM s_temp; MYISAM_SHARE *share=info->s; DBUG_ENTER("underflow"); - DBUG_PRINT("enter",("leaf_page: %ld keypos: %lx",(long) leaf_page,keypos)); + DBUG_PRINT("enter",("leaf_page: %ld keypos: 0x%lx",(long) leaf_page, + (ulong) keypos)); DBUG_DUMP("anc_buff",(byte*) anc_buff,mi_getint(anc_buff)); DBUG_DUMP("leaf_buff",(byte*) leaf_buff,mi_getint(leaf_buff)); diff --git a/myisam/mi_key.c b/myisam/mi_key.c index 9df22889b22..f4b92f969db 100644 --- a/myisam/mi_key.c +++ b/myisam/mi_key.c @@ -217,7 +217,10 @@ uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old, { k_length-=length; if (keyseg->flag & (HA_VAR_LENGTH | HA_BLOB_PART)) + { + old+= 2; k_length-=2; /* Skip length */ + } continue; /* Found NULL */ } } diff --git a/myisam/mi_rnext_same.c b/myisam/mi_rnext_same.c index 4d770258a72..92692d0517f 100644 --- a/myisam/mi_rnext_same.c +++ b/myisam/mi_rnext_same.c @@ -28,7 +28,7 @@ int mi_rnext_same(MI_INFO *info, byte *buf) { int error; - uint inx,not_used; + uint inx,not_used[2]; MI_KEYDEF *keyinfo; DBUG_ENTER("mi_rnext_same"); @@ -69,7 +69,7 @@ int mi_rnext_same(MI_INFO *info, byte *buf) info->s->state.key_root[inx]))) break; if (ha_key_cmp(keyinfo->seg, info->lastkey, info->lastkey2, - info->last_rkey_length, SEARCH_FIND, ¬_used)) + info->last_rkey_length, SEARCH_FIND, not_used)) { error=1; my_errno=HA_ERR_END_OF_FILE; diff --git a/myisam/mi_search.c b/myisam/mi_search.c index 4ea2480889e..9321f5b87d5 100644 --- a/myisam/mi_search.c +++ b/myisam/mi_search.c @@ -128,13 +128,13 @@ int _mi_search(register MI_INFO *info, register MI_KEYDEF *keyinfo, if ((nextflag & (SEARCH_SMALLER | SEARCH_LAST)) && flag != 0) { - uint not_used; + uint not_used[2]; if (_mi_get_prev_key(info,keyinfo, buff, info->lastkey, keypos, &info->lastkey_length)) goto err; if (!(nextflag & SEARCH_SMALLER) && ha_key_cmp(keyinfo->seg, info->lastkey, key, key_len, SEARCH_FIND, - ¬_used)) + not_used)) { my_errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */ goto err; @@ -178,7 +178,7 @@ int _mi_bin_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, { reg4 int start,mid,end,save_end; int flag; - uint totlength,nod_flag,not_used; + uint totlength,nod_flag,not_used[2]; DBUG_ENTER("_mi_bin_search"); LINT_INIT(flag); @@ -192,7 +192,7 @@ int _mi_bin_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, { mid= (start+end)/2; if ((flag=ha_key_cmp(keyinfo->seg,page+(uint) mid*totlength,key,key_len, - comp_flag,¬_used)) + comp_flag, not_used)) >= 0) end=mid; else @@ -200,7 +200,7 @@ int _mi_bin_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, } if (mid != start) flag=ha_key_cmp(keyinfo->seg,page+(uint) start*totlength,key,key_len, - comp_flag,¬_used); + comp_flag, not_used); if (flag < 0) start++; /* point at next, bigger key */ *ret_pos=page+(uint) start*totlength; @@ -241,7 +241,7 @@ int _mi_seq_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, uchar *buff, my_bool *last_key) { int flag; - uint nod_flag,length,not_used; + uint nod_flag,length,not_used[2]; uchar t_buff[MI_MAX_KEY_BUFF],*end; DBUG_ENTER("_mi_seq_search"); @@ -262,7 +262,7 @@ int _mi_seq_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, DBUG_RETURN(MI_FOUND_WRONG_KEY); } if ((flag=ha_key_cmp(keyinfo->seg,t_buff,key,key_len,comp_flag, - ¬_used)) >= 0) + not_used)) >= 0) break; #ifdef EXTRA_DEBUG DBUG_PRINT("loop",("page: %lx key: '%s' flag: %d", (long) page, t_buff, @@ -503,9 +503,9 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, cmp_rest: if (key_len_left>0) { - uint not_used; + uint not_used[2]; if ((flag = ha_key_cmp(keyinfo->seg+1,vseg, - k,key_len_left,nextflag,¬_used)) >= 0) + k, key_len_left, nextflag, not_used)) >= 0) break; } else diff --git a/myisam/mi_write.c b/myisam/mi_write.c index cd9e73fba22..52455320515 100644 --- a/myisam/mi_write.c +++ b/myisam/mi_write.c @@ -885,10 +885,10 @@ int _mi_ck_write_tree(register MI_INFO *info, uint keynr, uchar *key, static int keys_compare(bulk_insert_param *param, uchar *key1, uchar *key2) { - uint not_used; + uint not_used[2]; return ha_key_cmp(param->info->s->keyinfo[param->keynr].seg, - key1, key2, USE_WHOLE_KEY, SEARCH_SAME, - ¬_used); + key1, key2, USE_WHOLE_KEY, SEARCH_SAME, + not_used); } diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c index 2dd05cf7e67..49e3ea0f142 100644 --- a/myisam/myisamchk.c +++ b/myisam/myisamchk.c @@ -165,7 +165,7 @@ static struct my_option my_long_options[] = "Analyze distribution of keys. Will make some joins in MySQL faster. You can check the calculated distribution.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #ifdef __NETWARE__ - {"auto-close", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", + {"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"block-search", 'b', @@ -339,7 +339,8 @@ static struct my_option my_long_options[] = REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"stats_method", OPT_STATS_METHOD, "Specifies how index statistics collection code should threat NULLs. " - "Possible values of name are \"nulls_unequal\" (default behavior for 4.1/5.0), and \"nulls_equal\" (emulate 4.0 behavior).", + "Possible values of name are \"nulls_unequal\" (default behavior for 4.1/5.0), " + "\"nulls_equal\" (emulate 4.0 behavior), and \"nulls_ignored\".", (gptr*) &myisam_stats_method_str, (gptr*) &myisam_stats_method_str, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} @@ -451,6 +452,10 @@ static void usage(void) -a, --analyze Analyze distribution of keys. Will make some joins in\n\ MySQL faster. You can check the calculated distribution\n\ by using '--description --verbose table_name'.\n\ + --stats_method=name Specifies how index statistics collection code should\n\ + threat NULLs. Possible values of name are \"nulls_unequal\"\n\ + (default for 4.1/5.0), \"nulls_equal\" (emulate 4.0), and \n\ + \"nulls_ignored\".\n\ -d, --description Prints some information about table.\n\ -A, --set-auto-increment[=value]\n\ Force auto_increment to start at this or higher value\n\ @@ -472,7 +477,7 @@ static void usage(void) #include const char *myisam_stats_method_names[] = {"nulls_unequal", "nulls_equal", - NullS}; + "nulls_ignored", NullS}; TYPELIB myisam_stats_method_typelib= { array_elements(myisam_stats_method_names) - 1, "", myisam_stats_method_names, NULL}; @@ -699,14 +704,25 @@ get_one_option(int optid, case OPT_STATS_METHOD: { int method; + enum_mi_stats_method method_conv; myisam_stats_method_str= argument; if ((method=find_type(argument, &myisam_stats_method_typelib, 2)) <= 0) { fprintf(stderr, "Invalid value of stats_method: %s.\n", argument); exit(1); } - check_param.stats_method= test(method-1)? MI_STATS_METHOD_NULLS_EQUAL : - MI_STATS_METHOD_NULLS_NOT_EQUAL; + switch (method-1) { + case 0: + method_conv= MI_STATS_METHOD_NULLS_EQUAL; + break; + case 1: + method_conv= MI_STATS_METHOD_NULLS_NOT_EQUAL; + break; + case 2: + method_conv= MI_STATS_METHOD_IGNORE_NULLS; + break; + } + check_param.stats_method= method_conv; break; } #ifdef DEBUG /* Only useful if debugging */ diff --git a/myisam/myisamdef.h b/myisam/myisamdef.h index 93a7bf96f59..a766d59d72a 100644 --- a/myisam/myisamdef.h +++ b/myisam/myisamdef.h @@ -297,7 +297,14 @@ typedef struct st_mi_sort_param pthread_t thr; IO_CACHE read_cache, tempfile, tempfile_for_exceptions; DYNAMIC_ARRAY buffpek; + + /* + The next two are used to collect statistics, see update_key_parts for + description. + */ ulonglong unique[MI_MAX_KEY_SEG+1]; + ulonglong notnull[MI_MAX_KEY_SEG+1]; + my_off_t pos,max_pos,filepos,start_recpos; uint key, key_length,real_key_length,sortbuff_size; uint maxbuffers, keys, find_length, sort_keys_length; diff --git a/myisam/myisampack.c b/myisam/myisampack.c index f017e4d23ab..39eaf8927a6 100644 --- a/myisam/myisampack.c +++ b/myisam/myisampack.c @@ -239,7 +239,7 @@ enum options_mp {OPT_CHARSETS_DIR_MP=256, OPT_AUTO_CLOSE}; static struct my_option my_long_options[] = { #ifdef __NETWARE__ - {"auto-close", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", + {"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"backup", 'b', "Make a backup of the table as table_name.OLD.", diff --git a/myisam/sort.c b/myisam/sort.c index e8cd9938e42..96b55d599c8 100644 --- a/myisam/sort.c +++ b/myisam/sort.c @@ -481,8 +481,12 @@ int thr_write_keys(MI_SORT_PARAM *sort_param) { share->state.key_map|=(ulonglong) 1 << sinfo->key; if (param->testflag & T_STATISTICS) - update_key_parts(sinfo->keyinfo, rec_per_key_part, - sinfo->unique, (ulonglong) info->state->records); + update_key_parts(sinfo->keyinfo, rec_per_key_part, sinfo->unique, + param->stats_method == MI_STATS_METHOD_IGNORE_NULLS? + sinfo->notnull: NULL, + (ulonglong) info->state->records); + + if (!sinfo->buffpek.elements) { if (param->testflag & T_VERBOSE) diff --git a/myisammrg/myrg_queue.c b/myisammrg/myrg_queue.c index dfb434d6397..7172b9f0e2a 100644 --- a/myisammrg/myrg_queue.c +++ b/myisammrg/myrg_queue.c @@ -20,9 +20,9 @@ static int queue_key_cmp(void *keyseg, byte *a, byte *b) { MI_INFO *aa=((MYRG_TABLE *)a)->table; MI_INFO *bb=((MYRG_TABLE *)b)->table; - uint not_used; + uint not_used[2]; int ret= ha_key_cmp((HA_KEYSEG *)keyseg, aa->lastkey, bb->lastkey, - USE_WHOLE_KEY, SEARCH_FIND, ¬_used); + USE_WHOLE_KEY, SEARCH_FIND, not_used); return ret < 0 ? -1 : ret > 0 ? 1 : 0; } /* queue_key_cmp */ diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am index d062ee79827..9a88aff8300 100644 --- a/mysql-test/Makefile.am +++ b/mysql-test/Makefile.am @@ -87,6 +87,9 @@ install-data-local: $(INSTALL_DATA) $(srcdir)/lib/init_db.sql $(DESTDIR)$(testdir)/lib $(INSTALL_DATA) $(srcdir)/lib/*.pl $(DESTDIR)$(testdir)/lib +uninstall-local: + @RM@ -f -r $(DESTDIR)$(testdir) + std_data/client-key.pem: @CP@ $(top_srcdir)/SSL/$(@F) $(srcdir)/std_data std_data/client-cert.pem: diff --git a/mysql-test/include/have_euckr.inc b/mysql-test/include/have_euckr.inc new file mode 100644 index 00000000000..af794aafc04 --- /dev/null +++ b/mysql-test/include/have_euckr.inc @@ -0,0 +1,4 @@ +-- require r/have_euckr.require +disable_query_log; +show collation like "euckr_korean_ci"; +enable_query_log; diff --git a/mysql-test/include/have_gb2312.inc b/mysql-test/include/have_gb2312.inc new file mode 100644 index 00000000000..4328bc67639 --- /dev/null +++ b/mysql-test/include/have_gb2312.inc @@ -0,0 +1,4 @@ +-- require r/have_gb2312.require +disable_query_log; +show collation like "gb2312_chinese_ci"; +enable_query_log; diff --git a/mysql-test/my_manage.c b/mysql-test/my_manage.c index 88e68dfc27e..919d3bd0529 100644 --- a/mysql-test/my_manage.c +++ b/mysql-test/my_manage.c @@ -230,7 +230,10 @@ int wait_for_server_start(char *bin_dir __attribute__((unused)), char *user, char *password, int port,char *tmp_dir) { arg_list_t al; - int err= 0, i; + int err= 0; +#ifndef __WIN__ + int i; +#endif char trash[FN_REFLEN]; /* mysqladmin file */ diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 4b055e0bb84..58308f0ccdd 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -172,6 +172,7 @@ our $exe_mysqlbinlog; our $exe_mysql_client_test; our $exe_mysqld; our $exe_mysqldump; # Called from test case +our $exe_mysqlimport; # Called from test case our $exe_mysqlshow; # Called from test case our $exe_mysql_fix_system_tables; our $exe_mysqltest; @@ -462,6 +463,13 @@ sub command_line_setup () { my $opt_slave_myport= 9308; $opt_ndbcluster_port= 9350; + if ( $ENV{'MTR_BUILD_THREAD'} ) + { + $opt_master_myport= $ENV{'MTR_BUILD_THREAD'} * 40 + 8120; + $opt_slave_myport= $opt_master_myport + 16; + $opt_ndbcluster_port= $opt_master_myport + 24; + } + # Read the command line # Note: Keep list, and the order, in sync with usage at end of this file @@ -833,7 +841,9 @@ sub executable_setup () { { $path_client_bindir= mtr_path_exists("$glob_basedir/client_release", "$glob_basedir/bin"); - $exe_mysqld= mtr_exe_exists ("$path_client_bindir/mysqld-nt"); + $exe_mysqld= mtr_exe_exists ("$path_client_bindir/mysqld-nt", + "$path_client_bindir/mysqld", + "$path_client_bindir/mysqld-debug",); $path_language= mtr_path_exists("$glob_basedir/share/english/"); $path_charsetsdir= mtr_path_exists("$glob_basedir/share/charsets"); } @@ -861,6 +871,7 @@ sub executable_setup () { "/usr/bin/false"); } $exe_mysqldump= mtr_exe_exists("$path_client_bindir/mysqldump"); + $exe_mysqlimport= mtr_exe_exists("$path_client_bindir/mysqlimport"); $exe_mysqlshow= mtr_exe_exists("$path_client_bindir/mysqlshow"); $exe_mysqlbinlog= mtr_exe_exists("$path_client_bindir/mysqlbinlog"); $exe_mysqladmin= mtr_exe_exists("$path_client_bindir/mysqladmin"); @@ -874,6 +885,7 @@ sub executable_setup () { { $path_client_bindir= mtr_path_exists("$glob_basedir/bin"); $exe_mysqldump= mtr_exe_exists("$path_client_bindir/mysqldump"); + $exe_mysqlimport= mtr_exe_exists("$path_client_bindir/mysqlimport"); $exe_mysqlshow= mtr_exe_exists("$path_client_bindir/mysqlshow"); $exe_mysqlbinlog= mtr_exe_exists("$path_client_bindir/mysqlbinlog"); $exe_mysqladmin= mtr_exe_exists("$path_client_bindir/mysqladmin"); @@ -886,8 +898,18 @@ sub executable_setup () { "$glob_basedir/share/english/"); $path_charsetsdir= mtr_path_exists("$glob_basedir/share/mysql/charsets", "$glob_basedir/share/charsets"); - $exe_mysqld= mtr_exe_exists ("$glob_basedir/libexec/mysqld", - "$glob_basedir/bin/mysqld"); + + if ( $glob_win32 ) + { + $exe_mysqld= mtr_exe_exists ("$glob_basedir/bin/mysqld-nt", + "$glob_basedir/bin/mysqld", + "$glob_basedir/bin/mysqld-debug",); + } + else + { + $exe_mysqld= mtr_exe_exists ("$glob_basedir/libexec/mysqld", + "$glob_basedir/bin/mysqld"); + } if ( $glob_use_embedded_server ) { @@ -971,6 +993,13 @@ sub environment_setup () { chomp($ENV{$key}); } } + + # We are nice and report a bit about our settings + print "Using MTR_BUILD_THREAD = ",$ENV{MTR_BUILD_THREAD} || 0,"\n"; + print "Using MASTER_MYPORT = $ENV{MASTER_MYPORT}\n"; + print "Using MASTER_MYPORT1 = $ENV{MASTER_MYPORT1}\n"; + print "Using SLAVE_MYPORT = $ENV{SLAVE_MYPORT}\n"; + print "Using NDBCLUSTER_PORT = $opt_ndbcluster_port\n"; } @@ -2076,6 +2105,14 @@ sub run_mysqltest ($) { $cmdline_mysqldump .= " --debug=d:t:A,$opt_vardir/log/mysqldump.trace"; } + my $cmdline_mysqlimport= "$exe_mysqlimport -uroot " . + "--port=$master->[0]->{'path_myport'} " . + "--socket=$master->[0]->{'path_mysock'} --password="; + if ( $opt_debug ) + { + $cmdline_mysqlimport .= + " --debug=d:t:A,$opt_vardir/log/mysqlimport.trace"; + } my $cmdline_mysqlshow= "$exe_mysqlshow -uroot " . "--port=$master->[0]->{'path_myport'} " . @@ -2126,6 +2163,7 @@ sub run_mysqltest ($) { $ENV{'MYSQL'}= $cmdline_mysql; $ENV{'MYSQL_DUMP'}= $cmdline_mysqldump; + $ENV{'MYSQL_IMPORT'}= $cmdline_mysqlimport; $ENV{'MYSQL_SHOW'}= $cmdline_mysqlshow; $ENV{'MYSQL_BINLOG'}= $cmdline_mysqlbinlog; $ENV{'MYSQL_FIX_SYSTEM_TABLES'}= $cmdline_mysql_fix_system_tables; diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index 3e7a54fdead..3f303911d11 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -209,6 +209,25 @@ NDBCLUSTER_PORT=9350 MYSQL_MANAGER_PW_FILE=$MYSQL_TEST_DIR/var/tmp/manager.pwd MYSQL_MANAGER_LOG=$MYSQL_TEST_DIR/var/log/manager.log MYSQL_MANAGER_USER=root + +# +# To make it easier for different devs to work on the same host, +# an environment variable can be used to control all ports. A small +# number is to be used, 0 - 16 or similar. +# +if [ -n "$MTR_BUILD_THREAD" ] ; then + MASTER_MYPORT=`expr $MTR_BUILD_THREAD '*' 5 + 10000` + MYSQL_MANAGER_PORT=`expr $MASTER_MYPORT + 2` + SLAVE_MYPORT=`expr $MASTER_MYPORT + 3` + NDBCLUSTER_PORT=`expr $MASTER_MYPORT + 4` + + echo "Using MTR_BUILD_THREAD = $MTR_BUILD_THREAD" + echo "Using MASTER_MYPORT = $MASTER_MYPORT" + echo "Using MYSQL_MANAGER_PORT = $MYSQL_MANAGER_PORT" + echo "Using SLAVE_MYPORT = $SLAVE_MYPORT" + echo "Using NDBCLUSTER_PORT = $NDBCLUSTER_PORT" +fi + NO_SLAVE=0 USER_TEST= FAILED_CASES= @@ -546,6 +565,11 @@ if [ x$SOURCE_DIST = x1 ] ; then else MYSQL_DUMP="$BASEDIR/client/mysqldump" fi + if [ -f "$BASEDIR/client/.libs/mysqlimport" ] ; then + MYSQL_IMPORT="$BASEDIR/client/.libs/mysqlimport" + else + MYSQL_IMPORT="$BASEDIR/client/mysqlimport" + fi if [ -f "$BASEDIR/client/.libs/mysqlbinlog" ] ; then MYSQL_BINLOG="$BASEDIR/client/.libs/mysqlbinlog" else @@ -614,6 +638,7 @@ else fi MYSQL_TEST="$CLIENT_BINDIR/mysqltest" MYSQL_DUMP="$CLIENT_BINDIR/mysqldump" + MYSQL_IMPORT="$CLIENT_BINDIR/mysqlimport" MYSQL_BINLOG="$CLIENT_BINDIR/mysqlbinlog" MYSQLADMIN="$CLIENT_BINDIR/mysqladmin" WAIT_PID="$CLIENT_BINDIR/mysql_waitpid" @@ -693,10 +718,11 @@ fi MYSQL_DUMP_DIR="$MYSQL_DUMP" export MYSQL_DUMP_DIR MYSQL_DUMP="$MYSQL_DUMP --no-defaults -uroot --socket=$MASTER_MYSOCK --password=$DBPASSWD $EXTRA_MYSQLDUMP_OPT" +MYSQL_IMPORT="$MYSQL_IMPORT -uroot --socket=$MASTER_MYSOCK --password=$DBPASSWD $EXTRA_MYSQLDUMP_OPT" MYSQL_BINLOG="$MYSQL_BINLOG --no-defaults --local-load=$MYSQL_TMP_DIR $EXTRA_MYSQLBINLOG_OPT" MYSQL_FIX_SYSTEM_TABLES="$MYSQL_FIX_SYSTEM_TABLES --no-defaults --host=localhost --port=$MASTER_MYPORT --socket=$MASTER_MYSOCK --user=root --password=$DBPASSWD --basedir=$BASEDIR --bindir=$CLIENT_BINDIR --verbose" MYSQL="$MYSQL --no-defaults --host=localhost --port=$MASTER_MYPORT --socket=$MASTER_MYSOCK --user=root --password=$DBPASSWD" -export MYSQL MYSQL_DUMP MYSQL_BINLOG MYSQL_FIX_SYSTEM_TABLES +export MYSQL MYSQL_DUMP MYSQL_IMPORT MYSQL_BINLOG MYSQL_FIX_SYSTEM_TABLES export CLIENT_BINDIR MYSQL_CLIENT_TEST CHARSETSDIR export NDB_TOOLS_DIR export NDB_MGM diff --git a/mysql-test/mysql_test_run_new.c b/mysql-test/mysql_test_run_new.c index 40e45a92851..8beebefd298 100644 --- a/mysql-test/mysql_test_run_new.c +++ b/mysql-test/mysql_test_run_new.c @@ -1716,7 +1716,6 @@ int main(int argc, char **argv) int* handle; char test[FN_LEN]; char mask[FN_REFLEN]; - char *p; int position; /* single test */ diff --git a/mysql-test/r/analyse.result b/mysql-test/r/analyse.result index 0ebd4a3e409..f8737d8082b 100644 --- a/mysql-test/r/analyse.result +++ b/mysql-test/r/analyse.result @@ -108,3 +108,29 @@ select * from t1 procedure analyse (1,1); Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype test.t1.d 100000 100000 6 6 0 0 100000 0 MEDIUMINT(6) UNSIGNED NOT NULL drop table t1; +create table t1 (product varchar(32), country_id int not null, year int, +profit int); +insert into t1 values ( 'Computer', 2,2000, 1200), +( 'TV', 1, 1999, 150), +( 'Calculator', 1, 1999,50), +( 'Computer', 1, 1999,1500), +( 'Computer', 1, 2000,1500), +( 'TV', 1, 2000, 150), +( 'TV', 2, 2000, 100), +( 'TV', 2, 2000, 100), +( 'Calculator', 1, 2000,75), +( 'Calculator', 2, 2000,75), +( 'TV', 1, 1999, 100), +( 'Computer', 1, 1999,1200), +( 'Computer', 2, 2000,1500), +( 'Calculator', 2, 2000,75), +( 'Phone', 3, 2003,10) +; +create table t2 (country_id int primary key, country char(20) not null); +insert into t2 values (1, 'USA'),(2,'India'), (3,'Finland'); +select product, sum(profit),avg(profit) from t1 group by product with rollup procedure analyse(); +Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype +test.t1.product Computer TV 2 8 0 0 4.2500 NULL ENUM('Computer','Phone','TV') NOT NULL +sum(profit) 10 6900 2 4 0 0 1946 2868 ENUM('10','275','600','6900') NOT NULL +avg(profit) 10.0000 1380.0000 7 9 0 0 394.6875 570.2003 ENUM('10.0000','68.7500','120.0000','1380.0000') NOT NULL +drop table t1,t2; diff --git a/mysql-test/r/analyze.result b/mysql-test/r/analyze.result index 0b44a502b13..796b382f5d6 100644 --- a/mysql-test/r/analyze.result +++ b/mysql-test/r/analyze.result @@ -30,3 +30,10 @@ check table t1; Table Op Msg_type Msg_text test.t1 check status OK drop table t1; +CREATE TABLE t1 (a int); +prepare stmt1 from "SELECT * FROM t1 PROCEDURE ANALYSE()"; +execute stmt1; +Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype +execute stmt1; +Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype +deallocate prepare stmt1; diff --git a/mysql-test/r/bdb.result b/mysql-test/r/bdb.result index 6da3dbb929d..9fb42a0f6fd 100644 --- a/mysql-test/r/bdb.result +++ b/mysql-test/r/bdb.result @@ -1284,3 +1284,22 @@ SELECT id FROM t1 WHERE (list_id = 1) AND (term = "letterd"); id 4 DROP TABLE t1; +create table t1 (a int, key(a)) engine=bdb; +create table t2 (b int, key(b)) engine=bdb; +insert into t1 values (1),(1),(2),(3),(4); +insert into t2 values (1),(5),(6),(7); +delete from t1 where (a in (select b from t2)); +select count(*) from t1; +count(*) +3 +insert into t1 set a=(select b from t2); +ERROR 21000: Subquery returns more than 1 row +select count(*) from t1; +count(*) +3 +update t1 set a = a + 1 where (a in (select b from t2)); +select count(*) from t1; +count(*) +3 +drop table t1, t2; +End of 4.1 tests diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index 6edd4cbc48f..6fe148adce5 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -1,4 +1,4 @@ -drop table if exists t1,t2,t3; +drop table if exists t1,t2,t3,t4,t5; drop database if exists mysqltest; create table t1 (b char(0)); insert into t1 values (""),(null); @@ -247,21 +247,6 @@ select * from t1; 0 1 2 0 0 1 drop table t1; -create table t1 select 1,2,3; -create table if not exists t1 select 1,2; -Warnings: -Note 1050 Table 't1' already exists -create table if not exists t1 select 1,2,3,4; -ERROR 21S01: Column count doesn't match value count at row 1 -create table if not exists t1 select 1; -Warnings: -Note 1050 Table 't1' already exists -select * from t1; -1 2 3 -1 2 3 -0 1 2 -0 0 1 -drop table t1; create table t1 (a int not null, b int, primary key (a)); insert into t1 values (1,1); create table if not exists t1 select 2; @@ -601,6 +586,11 @@ DESC t2; Field Type Null Key Default Extra f2 varchar(86) YES NULL DROP TABLE t1,t2; +CREATE TABLE t12913 (f1 ENUM ('a','b')) AS SELECT 'a' AS f1; +SELECT * FROM t12913; +f1 +a +DROP TABLE t12913; create database mysqltest; use mysqltest; drop database mysqltest; @@ -621,3 +611,91 @@ create table if not exists t1 (a int); Warnings: Note 1050 Table 't1' already exists drop table t1; +create table t1 ( +a varchar(112) charset utf8 collate utf8_bin not null, +primary key (a) +) select 'test' as a ; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(112) character set utf8 collate utf8_bin NOT NULL default '', + PRIMARY KEY (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +CREATE TABLE t2 ( +a int(11) default NULL +); +insert into t2 values(111); +create table t1 ( +a varchar(12) charset utf8 collate utf8_bin not null, +b int not null, primary key (a) +) select a, 1 as b from t2 ; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(12) character set utf8 collate utf8_bin NOT NULL default '', + `b` int(11) NOT NULL default '0', + PRIMARY KEY (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +create table t1 ( +a varchar(12) charset utf8 collate utf8_bin not null, +b int not null, primary key (a) +) select 'a' as a , 1 as b from t2 ; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(12) character set utf8 collate utf8_bin NOT NULL default '', + `b` int(11) NOT NULL default '0', + PRIMARY KEY (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +create table t1 ( +a varchar(12) charset utf8 collate utf8_bin, +b int not null, primary key (a) +) select 'a' as a , 1 as b from t2 ; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(12) character set utf8 collate utf8_bin NOT NULL default '', + `b` int(11) NOT NULL default '0', + PRIMARY KEY (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1, t2; +create table t1 ( +a1 int not null, +a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int +); +insert into t1 values (1,1,1, 1,1,1, 1,1,1); +create table t2 ( +a1 varchar(12) charset utf8 collate utf8_bin not null, +a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int, +primary key (a1) +) select a1,a2,a3,a4,a5,a6,a7,a8,a9 from t1 ; +drop table t2; +create table t2 ( +a1 varchar(12) charset utf8 collate utf8_bin, +a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int +) select a1,a2,a3,a4,a5,a6,a7,a8,a9 from t1; +drop table t1, t2; +create table t1 ( +a1 int, a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int +); +insert into t1 values (1,1,1, 1,1,1, 1,1,1); +create table t2 ( +a1 varchar(12) charset utf8 collate utf8_bin not null, +a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int, +primary key (a1) +) select a1,a2,a3,a4,a5,a6,a7,a8,a9 from t1 ; +drop table t2; +create table t2 ( a int default 3, b int default 3) +select a1,a2 from t1; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` int(11) default '3', + `b` int(11) default '3', + `a1` int(11) default NULL, + `a2` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1, t2; diff --git a/mysql-test/r/csv.result b/mysql-test/r/csv.result index ea0d34271b5..2e3d11ad461 100644 --- a/mysql-test/r/csv.result +++ b/mysql-test/r/csv.result @@ -4929,3 +4929,50 @@ Warnings: Note 1051 Unknown table 't2' Note 1051 Unknown table 't3' Note 1051 Unknown table 't4' +DROP TABLE IF EXISTS bug13894; +CREATE TABLE bug13894 ( val integer ) ENGINE = CSV; +INSERT INTO bug13894 VALUES (5); +INSERT INTO bug13894 VALUES (10); +INSERT INTO bug13894 VALUES (11); +INSERT INTO bug13894 VALUES (10); +SELECT * FROM bug13894; +val +5 +10 +11 +10 +UPDATE bug13894 SET val=6 WHERE val=10; +SELECT * FROM bug13894; +val +5 +11 +6 +6 +DROP TABLE bug13894; +DROP TABLE IF EXISTS bug14672; +CREATE TABLE bug14672 (c1 integer) engine = CSV; +INSERT INTO bug14672 VALUES (1), (2), (3); +SELECT * FROM bug14672; +c1 +1 +2 +3 +DELETE FROM bug14672 WHERE c1 = 2; +SELECT * FROM bug14672; +c1 +1 +3 +INSERT INTO bug14672 VALUES (4); +SELECT * FROM bug14672; +c1 +1 +3 +4 +INSERT INTO bug14672 VALUES (5); +SELECT * FROM bug14672; +c1 +1 +3 +4 +5 +DROP TABLE bug14672; diff --git a/mysql-test/r/ctype_cp1250_ch.result b/mysql-test/r/ctype_cp1250_ch.result index 7b2ca7d7e0e..533bfb8cb53 100644 --- a/mysql-test/r/ctype_cp1250_ch.result +++ b/mysql-test/r/ctype_cp1250_ch.result @@ -19,3 +19,26 @@ SELECT * FROM t1 WHERE popisek LIKE '2005-01-1'; popisek 2005-01-1 drop table t1; +set names cp1250; +CREATE TABLE t1 +( +id INT AUTO_INCREMENT PRIMARY KEY, +str VARCHAR(32) CHARACTER SET cp1250 COLLATE cp1250_czech_cs NOT NULL default '', +UNIQUE KEY (str) +); +INSERT INTO t1 VALUES (NULL, 'a'); +INSERT INTO t1 VALUES (NULL, 'aa'); +INSERT INTO t1 VALUES (NULL, 'aaa'); +INSERT INTO t1 VALUES (NULL, 'aaaa'); +INSERT INTO t1 VALUES (NULL, 'aaaaa'); +INSERT INTO t1 VALUES (NULL, 'aaaaaa'); +INSERT INTO t1 VALUES (NULL, 'aaaaaaa'); +select * from t1 where str like 'aa%'; +id str +2 aa +3 aaa +4 aaaa +5 aaaaa +6 aaaaaa +7 aaaaaaa +drop table t1; diff --git a/mysql-test/r/ctype_cp932.result b/mysql-test/r/ctype_cp932.result index 8763055647c..b384eaa144d 100644 --- a/mysql-test/r/ctype_cp932.result +++ b/mysql-test/r/ctype_cp932.result @@ -8576,22 +8576,6 @@ FC4B DROP TABLE t1; DROP TABLE t2; DROP TABLE t3; -RESET MASTER; -CREATE TABLE t1(f1 blob); -PREPARE stmt1 FROM 'INSERT INTO t1 VALUES(?)'; -SET @var1= x'8300'; -EXECUTE stmt1 USING @var1; -SHOW BINLOG EVENTS FROM 79; -Log_name Pos Event_type Server_id Orig_log_pos Info -master-bin.000001 # Query 1 # use `test`; SET ONE_SHOT CHARACTER_SET_CLIENT=95,COLLATION_CONNECTION=95,COLLATION_DATABASE=95,COLLATION_SERVER=8 -master-bin.000001 # Query 1 # use `test`; CREATE TABLE t1(f1 blob) -master-bin.000001 # Query 1 # use `test`; SET ONE_SHOT CHARACTER_SET_CLIENT=95,COLLATION_CONNECTION=95,COLLATION_DATABASE=95,COLLATION_SERVER=8 -master-bin.000001 # User var 1 # @`var1`=_binary 0x8300 COLLATE binary -master-bin.000001 # Query 1 # use `test`; INSERT INTO t1 VALUES(@'var1') -SELECT HEX(f1) FROM t1; -HEX(f1) -8300 -DROP table t1; SET collation_connection='cp932_japanese_ci'; create table t1 select repeat('a',4000) a; delete from t1; diff --git a/mysql-test/r/ctype_cp932_binlog.result b/mysql-test/r/ctype_cp932_binlog.result new file mode 100644 index 00000000000..89f0ae71f4f --- /dev/null +++ b/mysql-test/r/ctype_cp932_binlog.result @@ -0,0 +1,19 @@ +drop table if exists t1; +set names cp932; +set character_set_database = cp932; +RESET MASTER; +CREATE TABLE t1(f1 blob); +PREPARE stmt1 FROM 'INSERT INTO t1 VALUES(?)'; +SET @var1= x'8300'; +EXECUTE stmt1 USING @var1; +SHOW BINLOG EVENTS FROM 79; +Log_name Pos Event_type Server_id Orig_log_pos Info +master-bin.000001 # Query 1 # use `test`; SET ONE_SHOT CHARACTER_SET_CLIENT=95,COLLATION_CONNECTION=95,COLLATION_DATABASE=95,COLLATION_SERVER=8 +master-bin.000001 # Query 1 # use `test`; CREATE TABLE t1(f1 blob) +master-bin.000001 # Query 1 # use `test`; SET ONE_SHOT CHARACTER_SET_CLIENT=95,COLLATION_CONNECTION=95,COLLATION_DATABASE=95,COLLATION_SERVER=8 +master-bin.000001 # User var 1 # @`var1`=_binary 0x8300 COLLATE binary +master-bin.000001 # Query 1 # use `test`; INSERT INTO t1 VALUES(@'var1') +SELECT HEX(f1) FROM t1; +HEX(f1) +8300 +DROP table t1; diff --git a/mysql-test/r/ctype_euckr.result b/mysql-test/r/ctype_euckr.result new file mode 100644 index 00000000000..6017bc07763 --- /dev/null +++ b/mysql-test/r/ctype_euckr.result @@ -0,0 +1,167 @@ +drop table if exists t1; +SET @test_character_set= 'euckr'; +SET @test_collation= 'euckr_korean_ci'; +SET @safe_character_set_server= @@character_set_server; +SET @safe_collation_server= @@collation_server; +SET character_set_server= @test_character_set; +SET collation_server= @test_collation; +CREATE DATABASE d1; +USE d1; +CREATE TABLE t1 (c CHAR(10), KEY(c)); +SHOW FULL COLUMNS FROM t1; +Field Type Collation Null Key Default Extra Privileges Comment +c char(10) euckr_korean_ci YES MUL NULL +INSERT INTO t1 VALUES ('aaa'),('aaaa'),('aaaaa'); +SELECT c as want3results FROM t1 WHERE c LIKE 'aaa%'; +want3results +aaa +aaaa +aaaaa +DROP TABLE t1; +CREATE TABLE t1 (c1 varchar(15), KEY c1 (c1(2))); +SHOW FULL COLUMNS FROM t1; +Field Type Collation Null Key Default Extra Privileges Comment +c1 varchar(15) euckr_korean_ci YES MUL NULL +INSERT INTO t1 VALUES ('location'),('loberge'),('lotre'),('boabab'); +SELECT c1 as want3results from t1 where c1 like 'l%'; +want3results +location +loberge +lotre +SELECT c1 as want3results from t1 where c1 like 'lo%'; +want3results +location +loberge +lotre +SELECT c1 as want1result from t1 where c1 like 'loc%'; +want1result +location +SELECT c1 as want1result from t1 where c1 like 'loca%'; +want1result +location +SELECT c1 as want1result from t1 where c1 like 'locat%'; +want1result +location +SELECT c1 as want1result from t1 where c1 like 'locati%'; +want1result +location +SELECT c1 as want1result from t1 where c1 like 'locatio%'; +want1result +location +SELECT c1 as want1result from t1 where c1 like 'location%'; +want1result +location +DROP TABLE t1; +DROP DATABASE d1; +USE test; +SET character_set_server= @safe_character_set_server; +SET collation_server= @safe_collation_server; +SET NAMES euckr; +SET collation_connection='euckr_korean_ci'; +create table t1 select repeat('a',4000) a; +delete from t1; +insert into t1 values ('a'), ('a '), ('a\t'); +select collation(a),hex(a) from t1 order by a; +collation(a) hex(a) +euckr_korean_ci 6109 +euckr_korean_ci 61 +euckr_korean_ci 6120 +drop table t1; +create table t1 engine=innodb select repeat('a',50) as c1; +alter table t1 add index(c1(5)); +insert into t1 values ('abcdefg'),('abcde100'),('abcde110'),('abcde111'); +select collation(c1) from t1 limit 1; +collation(c1) +euckr_korean_ci +select c1 from t1 where c1 like 'abcdef%' order by c1; +c1 +abcdefg +select c1 from t1 where c1 like 'abcde1%' order by c1; +c1 +abcde100 +abcde110 +abcde111 +select c1 from t1 where c1 like 'abcde11%' order by c1; +c1 +abcde110 +abcde111 +select c1 from t1 where c1 like 'abcde111%' order by c1; +c1 +abcde111 +drop table t1; +select @@collation_connection; +@@collation_connection +euckr_korean_ci +create table t1 ROW_FORMAT=DYNAMIC select repeat('a',50) as c1 ; +insert into t1 values('abcdef'); +insert into t1 values('_bcdef'); +insert into t1 values('a_cdef'); +insert into t1 values('ab_def'); +insert into t1 values('abc_ef'); +insert into t1 values('abcd_f'); +insert into t1 values('abcde_'); +select c1 as c1u from t1 where c1 like 'ab\_def'; +c1u +ab_def +select c1 as c2h from t1 where c1 like 'ab#_def' escape '#'; +c2h +ab_def +drop table t1; +SET collation_connection='euckr_bin'; +create table t1 select repeat('a',4000) a; +delete from t1; +insert into t1 values ('a'), ('a '), ('a\t'); +select collation(a),hex(a) from t1 order by a; +collation(a) hex(a) +euckr_bin 6109 +euckr_bin 61 +euckr_bin 6120 +drop table t1; +create table t1 engine=innodb select repeat('a',50) as c1; +alter table t1 add index(c1(5)); +insert into t1 values ('abcdefg'),('abcde100'),('abcde110'),('abcde111'); +select collation(c1) from t1 limit 1; +collation(c1) +euckr_bin +select c1 from t1 where c1 like 'abcdef%' order by c1; +c1 +abcdefg +select c1 from t1 where c1 like 'abcde1%' order by c1; +c1 +abcde100 +abcde110 +abcde111 +select c1 from t1 where c1 like 'abcde11%' order by c1; +c1 +abcde110 +abcde111 +select c1 from t1 where c1 like 'abcde111%' order by c1; +c1 +abcde111 +drop table t1; +select @@collation_connection; +@@collation_connection +euckr_bin +create table t1 ROW_FORMAT=DYNAMIC select repeat('a',50) as c1 ; +insert into t1 values('abcdef'); +insert into t1 values('_bcdef'); +insert into t1 values('a_cdef'); +insert into t1 values('ab_def'); +insert into t1 values('abc_ef'); +insert into t1 values('abcd_f'); +insert into t1 values('abcde_'); +select c1 as c1u from t1 where c1 like 'ab\_def'; +c1u +ab_def +select c1 as c2h from t1 where c1 like 'ab#_def' escape '#'; +c2h +ab_def +drop table t1; +SET NAMES euckr; +CREATE TABLE t1 (a text) character set euckr; +INSERT INTO t1 VALUES (0xA2E6),(0xFEF7); +SELECT hex(a) FROM t1 ORDER BY a; +hex(a) +A2E6 +FEF7 +DROP TABLE t1; diff --git a/mysql-test/r/ctype_gb2312.result b/mysql-test/r/ctype_gb2312.result new file mode 100644 index 00000000000..314c336bab9 --- /dev/null +++ b/mysql-test/r/ctype_gb2312.result @@ -0,0 +1,167 @@ +drop table if exists t1; +SET @test_character_set= 'gb2312'; +SET @test_collation= 'gb2312_chinese_ci'; +SET @safe_character_set_server= @@character_set_server; +SET @safe_collation_server= @@collation_server; +SET character_set_server= @test_character_set; +SET collation_server= @test_collation; +CREATE DATABASE d1; +USE d1; +CREATE TABLE t1 (c CHAR(10), KEY(c)); +SHOW FULL COLUMNS FROM t1; +Field Type Collation Null Key Default Extra Privileges Comment +c char(10) gb2312_chinese_ci YES MUL NULL +INSERT INTO t1 VALUES ('aaa'),('aaaa'),('aaaaa'); +SELECT c as want3results FROM t1 WHERE c LIKE 'aaa%'; +want3results +aaa +aaaa +aaaaa +DROP TABLE t1; +CREATE TABLE t1 (c1 varchar(15), KEY c1 (c1(2))); +SHOW FULL COLUMNS FROM t1; +Field Type Collation Null Key Default Extra Privileges Comment +c1 varchar(15) gb2312_chinese_ci YES MUL NULL +INSERT INTO t1 VALUES ('location'),('loberge'),('lotre'),('boabab'); +SELECT c1 as want3results from t1 where c1 like 'l%'; +want3results +location +loberge +lotre +SELECT c1 as want3results from t1 where c1 like 'lo%'; +want3results +location +loberge +lotre +SELECT c1 as want1result from t1 where c1 like 'loc%'; +want1result +location +SELECT c1 as want1result from t1 where c1 like 'loca%'; +want1result +location +SELECT c1 as want1result from t1 where c1 like 'locat%'; +want1result +location +SELECT c1 as want1result from t1 where c1 like 'locati%'; +want1result +location +SELECT c1 as want1result from t1 where c1 like 'locatio%'; +want1result +location +SELECT c1 as want1result from t1 where c1 like 'location%'; +want1result +location +DROP TABLE t1; +DROP DATABASE d1; +USE test; +SET character_set_server= @safe_character_set_server; +SET collation_server= @safe_collation_server; +SET NAMES gb2312; +SET collation_connection='gb2312_chinese_ci'; +create table t1 select repeat('a',4000) a; +delete from t1; +insert into t1 values ('a'), ('a '), ('a\t'); +select collation(a),hex(a) from t1 order by a; +collation(a) hex(a) +gb2312_chinese_ci 6109 +gb2312_chinese_ci 61 +gb2312_chinese_ci 6120 +drop table t1; +create table t1 engine=innodb select repeat('a',50) as c1; +alter table t1 add index(c1(5)); +insert into t1 values ('abcdefg'),('abcde100'),('abcde110'),('abcde111'); +select collation(c1) from t1 limit 1; +collation(c1) +gb2312_chinese_ci +select c1 from t1 where c1 like 'abcdef%' order by c1; +c1 +abcdefg +select c1 from t1 where c1 like 'abcde1%' order by c1; +c1 +abcde100 +abcde110 +abcde111 +select c1 from t1 where c1 like 'abcde11%' order by c1; +c1 +abcde110 +abcde111 +select c1 from t1 where c1 like 'abcde111%' order by c1; +c1 +abcde111 +drop table t1; +select @@collation_connection; +@@collation_connection +gb2312_chinese_ci +create table t1 ROW_FORMAT=DYNAMIC select repeat('a',50) as c1 ; +insert into t1 values('abcdef'); +insert into t1 values('_bcdef'); +insert into t1 values('a_cdef'); +insert into t1 values('ab_def'); +insert into t1 values('abc_ef'); +insert into t1 values('abcd_f'); +insert into t1 values('abcde_'); +select c1 as c1u from t1 where c1 like 'ab\_def'; +c1u +ab_def +select c1 as c2h from t1 where c1 like 'ab#_def' escape '#'; +c2h +ab_def +drop table t1; +SET collation_connection='gb2312_bin'; +create table t1 select repeat('a',4000) a; +delete from t1; +insert into t1 values ('a'), ('a '), ('a\t'); +select collation(a),hex(a) from t1 order by a; +collation(a) hex(a) +gb2312_bin 6109 +gb2312_bin 61 +gb2312_bin 6120 +drop table t1; +create table t1 engine=innodb select repeat('a',50) as c1; +alter table t1 add index(c1(5)); +insert into t1 values ('abcdefg'),('abcde100'),('abcde110'),('abcde111'); +select collation(c1) from t1 limit 1; +collation(c1) +gb2312_bin +select c1 from t1 where c1 like 'abcdef%' order by c1; +c1 +abcdefg +select c1 from t1 where c1 like 'abcde1%' order by c1; +c1 +abcde100 +abcde110 +abcde111 +select c1 from t1 where c1 like 'abcde11%' order by c1; +c1 +abcde110 +abcde111 +select c1 from t1 where c1 like 'abcde111%' order by c1; +c1 +abcde111 +drop table t1; +select @@collation_connection; +@@collation_connection +gb2312_bin +create table t1 ROW_FORMAT=DYNAMIC select repeat('a',50) as c1 ; +insert into t1 values('abcdef'); +insert into t1 values('_bcdef'); +insert into t1 values('a_cdef'); +insert into t1 values('ab_def'); +insert into t1 values('abc_ef'); +insert into t1 values('abcd_f'); +insert into t1 values('abcde_'); +select c1 as c1u from t1 where c1 like 'ab\_def'; +c1u +ab_def +select c1 as c2h from t1 where c1 like 'ab#_def' escape '#'; +c2h +ab_def +drop table t1; +SET NAMES gb2312; +CREATE TABLE t1 (a text) character set gb2312; +INSERT INTO t1 VALUES (0xA2A1),(0xD7FE); +SELECT hex(a) FROM t1 ORDER BY a; +hex(a) +A2A1 +D7FE +DROP TABLE t1; diff --git a/mysql-test/r/ctype_recoding.result b/mysql-test/r/ctype_recoding.result index 1c75988fd21..0b5c6f8974c 100644 --- a/mysql-test/r/ctype_recoding.result +++ b/mysql-test/r/ctype_recoding.result @@ -181,11 +181,18 @@ select * from t1 where a=_koi8r' a ×ÁÓÑ select * from t1 where a=concat(_koi8r'×ÁÓÑ'); -ERROR HY000: Illegal mix of collations (cp1251_general_ci,IMPLICIT) and (koi8r_general_ci,COERCIBLE) for operation '=' +a +×ÁÓÑ select * from t1 where a=_latin1'×ÁÓÑ'; ERROR HY000: Illegal mix of collations (cp1251_general_ci,IMPLICIT) and (latin1_swedish_ci,COERCIBLE) for operation '=' drop table t1; set names latin1; +create table t1 (a char(10) character set utf8 collate utf8_bin); +insert into t1 values (' xxx'); +select * from t1 where a=lpad('xxx',10,' '); +a + xxx +drop table t1; set names koi8r; create table t1 (c1 char(10) character set cp1251); insert into t1 values ('ß'); diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result index 619ad750ff3..0e12ec88662 100644 --- a/mysql-test/r/ctype_ucs.result +++ b/mysql-test/r/ctype_ucs.result @@ -677,3 +677,29 @@ hex(a) 005B 803D drop table t1; +create table t1(f1 varchar(5) CHARACTER SET ucs2 COLLATE ucs2_bin NOT NULL) engine=InnoDB; +insert into t1 values('a'); +create index t1f1 on t1(f1); +select f1 from t1 where f1 like 'a%'; +f1 +a +drop table t1; +create table t1 (utext varchar(20) character set ucs2); +insert into t1 values ("lily"); +insert into t1 values ("river"); +prepare stmt from 'select utext from t1 where utext like ?'; +set @param1='%%'; +execute stmt using @param1; +utext +lily +river +execute stmt using @param1; +utext +lily +river +select utext from t1 where utext like '%%'; +utext +lily +river +drop table t1; +deallocate prepare stmt; diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index c7606b918df..cf9426e6b21 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -1061,3 +1061,20 @@ create table t1 (a varchar(255)) default charset=utf8; select * from t1 where find_in_set('-1', a); a drop table t1; +create table t1 (a int); +insert into t1 values (48),(49),(50); +set names utf8; +select distinct char(a) from t1; +char(a) +0 +1 +2 +drop table t1; +CREATE TABLE t1 (t TINYTEXT CHARACTER SET utf8); +INSERT INTO t1 VALUES(REPEAT('a', 100)); +CREATE TEMPORARY TABLE t2 SELECT COALESCE(t) AS bug FROM t1; +SELECT LENGTH(bug) FROM t2; +LENGTH(bug) +100 +DROP TABLE t2; +DROP TABLE t1; diff --git a/mysql-test/r/date_formats.result b/mysql-test/r/date_formats.result index 2db014c4a52..34a2dedd976 100644 --- a/mysql-test/r/date_formats.result +++ b/mysql-test/r/date_formats.result @@ -456,3 +456,11 @@ f1 f2 Warnings: Warning 1292 Truncated incorrect date value: '2003-04-05 g' Warning 1292 Truncated incorrect datetime value: '2003-04-05 10:11:12.101010234567' +create table t1 (f1 datetime); +insert into t1 (f1) values ("2005-01-01"); +insert into t1 (f1) values ("2005-02-01"); +select date_format(f1, "%m") as d1, date_format(f1, "%M") as d2 from t1 order by date_format(f1, "%M"); +d1 d2 +02 February +01 January +drop table t1; diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index 8fa2df2e756..ebd6880a10e 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -428,4 +428,11 @@ REPAIR TABLE t1; Table Op Msg_type Msg_text test.t1 repair status OK SET myisam_repair_threads=@@global.myisam_repair_threads; +INSERT INTO t1 VALUES('testword\'\''); +SELECT a FROM t1 WHERE MATCH a AGAINST('testword' IN BOOLEAN MODE); +a +testword'' +SELECT a FROM t1 WHERE MATCH a AGAINST('testword\'\'' IN BOOLEAN MODE); +a +testword'' DROP TABLE t1; diff --git a/mysql-test/r/fulltext2.result b/mysql-test/r/fulltext2.result index 0b1d8eb9a15..72c6b2d22ed 100644 --- a/mysql-test/r/fulltext2.result +++ b/mysql-test/r/fulltext2.result @@ -215,3 +215,24 @@ select count(*) from t1 where match a against ('aaazzz' in boolean mode); count(*) 262 drop table t1; +set names utf8; +create table t1(a text,fulltext(a)) collate=utf8_swedish_ci; +insert into t1 values('test test '),('test'),('test'),('test'), +('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'), +('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'), +('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'), +('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'), +('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'), +('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'), +('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'), +('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'), +('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'), +('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'), +('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'), +('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'), +('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'), +('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'), +('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'); +delete from t1 limit 1; +drop table t1; +set names latin1; diff --git a/mysql-test/r/func_math.result b/mysql-test/r/func_math.result index b36902d7872..11a3d14fb65 100644 --- a/mysql-test/r/func_math.result +++ b/mysql-test/r/func_math.result @@ -145,3 +145,9 @@ insert into t1 values (1); select rand(i) from t1; ERROR HY000: Incorrect arguments to RAND drop table t1; +create table t1 (a varchar(90), ts datetime not null, index (a)) engine=innodb default charset=utf8; +insert into t1 values ('http://www.foo.com/', now()); +select a from t1 where a='http://www.foo.com/' order by abs(timediff(ts, 0)); +a +http://www.foo.com/ +drop table t1; diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result index 2d464c891bf..181ecf7b65b 100644 --- a/mysql-test/r/func_misc.result +++ b/mysql-test/r/func_misc.result @@ -49,3 +49,11 @@ select a from t1 where mid(a+0,6,3) = ( mid(20040106123400,6,3) ); a 2004-01-06 12:34:00 drop table t1; +create table t1 as select uuid(), length(uuid()); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `uuid()` char(36) character set utf8 NOT NULL default '', + `length(uuid())` int(10) NOT NULL default '0' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; diff --git a/mysql-test/r/func_sapdb.result b/mysql-test/r/func_sapdb.result index 68c3baa7bde..ea40e1559fd 100644 --- a/mysql-test/r/func_sapdb.result +++ b/mysql-test/r/func_sapdb.result @@ -170,8 +170,8 @@ Field Type Null Key Default Extra f1 date 0000-00-00 f2 datetime YES NULL f3 time YES NULL -f4 time 00:00:00 -f5 time 00:00:00 +f4 time YES NULL +f5 time YES NULL f6 time 00:00:00 f7 datetime YES NULL f8 date YES NULL diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index c51b07f09d6..bf2f3e2bf03 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -655,3 +655,9 @@ t1 where object_id=85984; object_id geometrytype(geo) ISSIMPLE(GEO) ASTEXT(centroid(geo)) 85984 MULTIPOLYGON 0 POINT(-114.87787186923 36.33101763469) drop table t1; +select (asWKT(geomfromwkb((0x000000000140240000000000004024000000000000)))); +(asWKT(geomfromwkb((0x000000000140240000000000004024000000000000)))) +POINT(10 10) +select (asWKT(geomfromwkb((0x010100000000000000000024400000000000002440)))); +(asWKT(geomfromwkb((0x010100000000000000000024400000000000002440)))) +POINT(10 10) diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index a50293752ec..13593ec2a88 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -351,10 +351,10 @@ GRANT USAGE ON *.* TO 'grant_user'@'localhost' GRANT INSERT (a, d, c, b) ON `test`.`t1` TO 'grant_user'@'localhost' select Host,Db,User,Table_name,Column_name,Column_priv from mysql.columns_priv; Host Db User Table_name Column_name Column_priv -localhost test grant_user t1 c Insert localhost test grant_user t1 b Insert -localhost test grant_user t1 a Insert localhost test grant_user t1 d Insert +localhost test grant_user t1 a Insert +localhost test grant_user t1 c Insert revoke ALL PRIVILEGES on t1 from grant_user@localhost; show grants for grant_user@localhost; Grants for grant_user@localhost @@ -377,9 +377,9 @@ show grants for mysqltest_3@localhost; Grants for mysqltest_3@localhost GRANT USAGE ON *.* TO 'mysqltest_3'@'localhost' GRANT SELECT (b) ON `mysqltest_1`.`t2` TO 'mysqltest_3'@'localhost' -GRANT SELECT (c) ON `mysqltest_2`.`t1` TO 'mysqltest_3'@'localhost' GRANT UPDATE (a) ON `mysqltest_1`.`t1` TO 'mysqltest_3'@'localhost' GRANT UPDATE (d) ON `mysqltest_2`.`t2` TO 'mysqltest_3'@'localhost' +GRANT SELECT (c) ON `mysqltest_2`.`t1` TO 'mysqltest_3'@'localhost' update mysqltest_1.t1, mysqltest_1.t2 set q=10 where b=1; ERROR 42000: UPDATE command denied to user 'mysqltest_3'@'localhost' for column 'q' in table 't1' update mysqltest_1.t1, mysqltest_2.t2 set d=20 where d=1; @@ -443,3 +443,33 @@ flush privileges; set @user123="non-existent"; select * from mysql.db where user=@user123; Host Db User Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Grant_priv References_priv Index_priv Alter_priv Create_tmp_table_priv Lock_tables_priv +set names koi8r; +create database ÂÄ; +grant select on ÂÄ.* to root@localhost; +select hex(Db) from mysql.db where Db='ÂÄ'; +hex(Db) +D0B1D0B4 +show grants for root@localhost; +Grants for root@localhost +GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION +GRANT SELECT ON `ÂÄ`.* TO 'root'@'localhost' +flush privileges; +show grants for root@localhost; +Grants for root@localhost +GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION +GRANT SELECT ON `ÂÄ`.* TO 'root'@'localhost' +drop database ÂÄ; +revoke all privileges on ÂÄ.* from root@localhost; +show grants for root@localhost; +Grants for root@localhost +GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION +set names latin1; +insert into mysql.user (host, user) values ('', 'mysqltest_7'); +flush privileges; +set password for mysqltest_7@ = password('systpass'); +show grants for mysqltest_7@; +Grants for mysqltest_7@ +GRANT USAGE ON *.* TO 'mysqltest_7'@'' IDENTIFIED BY PASSWORD '*2FB071A056F9BB745219D9C876814231DAF46517' +drop user mysqltest_7@; +show grants for mysqltest_7@; +ERROR 42000: There is no such grant defined for user 'mysqltest_7' on host '' diff --git a/mysql-test/r/grant2.result b/mysql-test/r/grant2.result index 6b6bb697306..85963705718 100644 --- a/mysql-test/r/grant2.result +++ b/mysql-test/r/grant2.result @@ -131,3 +131,15 @@ lock table mysql.user write; revoke all on *.* from 'mysqltest_1'@'localhost'; unlock tables; drop user 'mysqltest_1'@'localhost'; +insert into mysql.user (user, host) values +('mysqltest_1', 'host1'), +('mysqltest_2', 'host2'), +('mysqltest_3', 'host3'), +('mysqltest_4', 'host4'), +('mysqltest_5', 'host5'), +('mysqltest_6', 'host6'), +('mysqltest_7', 'host7'); +flush privileges; +drop user mysqltest_3@host3; +drop user mysqltest_1@host1, mysqltest_2@host2, mysqltest_4@host4, +mysqltest_5@host5, mysqltest_6@host6, mysqltest_7@host7; diff --git a/mysql-test/r/handler.result b/mysql-test/r/handler.result index 072d4582cbc..9b0c6dbc263 100644 --- a/mysql-test/r/handler.result +++ b/mysql-test/r/handler.result @@ -445,3 +445,21 @@ drop table t2; drop table t3; drop table t4; drop table t5; +create table t1 (c1 int); +insert into t1 values (1); +handler t1 open; +handler t1 read first; +c1 +1 +send the below to another connection, do not wait for the result + optimize table t1; +proceed with the normal connection +handler t1 read next; +c1 +1 +handler t1 close; +read the result from the other connection +Table Op Msg_type Msg_text +test.t1 optimize status OK +proceed with the normal connection +drop table t1; diff --git a/mysql-test/r/have_euckr.require b/mysql-test/r/have_euckr.require new file mode 100644 index 00000000000..0771ceec570 --- /dev/null +++ b/mysql-test/r/have_euckr.require @@ -0,0 +1,2 @@ +Collation Charset Id Default Compiled Sortlen +euckr_korean_ci euckr 19 Yes Yes 1 diff --git a/mysql-test/r/have_gb2312.require b/mysql-test/r/have_gb2312.require new file mode 100644 index 00000000000..9bcb7c94a14 --- /dev/null +++ b/mysql-test/r/have_gb2312.require @@ -0,0 +1,2 @@ +Collation Charset Id Default Compiled Sortlen +gb2312_chinese_ci gb2312 24 Yes Yes 1 diff --git a/mysql-test/r/having.result b/mysql-test/r/having.result index 218276406b1..9730f9f81bf 100644 --- a/mysql-test/r/having.result +++ b/mysql-test/r/having.result @@ -128,3 +128,16 @@ id description c 1 test 0 2 test2 0 drop table t1,t2,t3; +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (3), (4), (1), (3), (1); +SELECT SUM(a) FROM t1 GROUP BY a HAVING SUM(a)>0; +SUM(a) +2 +6 +4 +SELECT SUM(a) FROM t1 GROUP BY a HAVING SUM(a); +SUM(a) +2 +6 +4 +DROP TABLE t1; diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index ca78d23e6dc..3ec78c518fc 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -1722,3 +1722,75 @@ checksum table test_checksum; Table Checksum test.test_checksum 2050879373 drop table test_checksum; +set foreign_key_checks=0; +create table t2 (a int primary key, b int, foreign key (b) references t1(a)) engine = innodb; +create table t1(a char(10) primary key, b varchar(20)) engine = innodb; +ERROR HY000: Can't create table './test/t1.frm' (errno: 150) +set foreign_key_checks=1; +drop table t2; +set foreign_key_checks=0; +create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1; +create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=utf8; +ERROR HY000: Can't create table './test/t2.frm' (errno: 150) +set foreign_key_checks=1; +drop table t1; +set foreign_key_checks=0; +create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb; +create table t1(a varchar(10) primary key) engine = innodb; +alter table t1 modify column a int; +Got one of the listed errors +set foreign_key_checks=1; +drop table t2,t1; +set foreign_key_checks=0; +create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1; +create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1; +alter table t1 convert to character set utf8; +set foreign_key_checks=1; +drop table t2,t1; +set foreign_key_checks=0; +create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1; +create table t3(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=utf8; +rename table t3 to t1; +ERROR HY000: Error on rename of './test/t3' to './test/t1' (errno: 150) +set foreign_key_checks=1; +drop table t2,t3; +create table t2 ( +a int, b char(10), filler char(10), primary key(a, b(2)) +) character set utf8 engine = innodb; +insert into t2 values (1,'abcdefg','one'); +insert into t2 values (2,'ijkilmn','two'); +insert into t2 values (3, 'qrstuvw','three'); +update t2 set a=5, filler='booo' where a=1; +drop table t2; +create table t2 ( +a int, b char(10), filler char(10), primary key(a, b(2)) +) character set ucs2 engine = innodb; +insert into t2 values (1,'abcdefg','one'); +insert into t2 values (2,'ijkilmn','two'); +insert into t2 values (3, 'qrstuvw','three'); +update t2 set a=5, filler='booo' where a=1; +drop table t2; +create table t1(a int not null, b char(110),primary key(a,b(100))) engine=innodb default charset=utf8; +insert into t1 values(1,'abcdefg'),(2,'defghijk'); +insert into t1 values(6,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1); +insert into t1 values(7,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2); +select a,hex(b) from t1 order by b; +a hex(b) +1 61626364656667 +2 6465666768696A6B +6 D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1 +7 D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2 +update t1 set b = 'three' where a = 6; +drop table t1; +create table t1(a int not null, b text(110),primary key(a,b(100))) engine=innodb default charset=utf8; +insert into t1 values(1,'abcdefg'),(2,'defghijk'); +insert into t1 values(6,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1); +insert into t1 values(7,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2); +select a,hex(b) from t1 order by b; +a hex(b) +1 61626364656667 +2 6465666768696A6B +6 D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1 +7 D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2 +update t1 set b = 'three' where a = 6; +drop table t1; diff --git a/mysql-test/r/insert_select.result b/mysql-test/r/insert_select.result index d4eb4e8b788..028b40ac3b6 100644 --- a/mysql-test/r/insert_select.result +++ b/mysql-test/r/insert_select.result @@ -678,3 +678,11 @@ f1 2001 2002 drop table t1; +create table t1(x int, y int); +create table t2(x int, z int); +insert into t1(x,y) select x,z from t2 on duplicate key update x=values(x); +insert into t1(x,y) select x,z from t2 on duplicate key update x=values(z); +ERROR 42S22: Unknown column 'z' in 'field list' +insert into t1(x,y) select x,z from t2 on duplicate key update x=values(t2.x); +ERROR 42S02: Unknown table 't2' in field list +drop table t1,t2; diff --git a/mysql-test/r/loaddata.result b/mysql-test/r/loaddata.result index 46db14a5871..e1076cd3072 100644 --- a/mysql-test/r/loaddata.result +++ b/mysql-test/r/loaddata.result @@ -76,3 +76,12 @@ select * from t1; id 0 SET @@SQL_MODE=@OLD_SQL_MODE; +drop table t1; +create table t1 (a varchar(20), b varchar(20)); +load data infile '../../std_data/loaddata5.dat' into table t1 fields terminated by ',' enclosed by '"' escaped by '"' (a,b); +select * from t1; +a b +field1 field2 +a"b cd"ef +a"b c"d"e +drop table t1; diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index 3035908688a..038ea43cabc 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -717,3 +717,52 @@ SELECT b FROM t2; b 3 DROP TABLE t1, t2; +create table t1(a int); +create table t2(a int); +insert into t1 values (1); +insert into t2 values (2); +create table t3 (a int) engine=merge union=(t1, t2) insert_method=first; +select * from t3; +a +1 +2 +insert t2 select * from t2; +select * from t2; +a +2 +2 +insert t3 select * from t1; +select * from t3; +a +1 +1 +2 +2 +insert t1 select * from t3; +select * from t1; +a +1 +1 +1 +1 +2 +2 +select * from t2; +a +2 +2 +select * from t3; +a +1 +1 +1 +1 +2 +2 +2 +2 +check table t1, t2; +Table Op Msg_type Msg_text +test.t1 check status OK +test.t2 check status OK +drop table t1, t2, t3; diff --git a/mysql-test/r/mix_innodb_myisam_binlog.result b/mysql-test/r/mix_innodb_myisam_binlog.result index 72288d1027b..e9613bac833 100644 --- a/mysql-test/r/mix_innodb_myisam_binlog.result +++ b/mysql-test/r/mix_innodb_myisam_binlog.result @@ -93,6 +93,7 @@ master-bin.000001 79 Query 1 79 use `test`; BEGIN master-bin.000001 119 Query 1 79 use `test`; insert into t1 values(8) master-bin.000001 178 Query 1 79 use `test`; insert into t2 select * from t1 master-bin.000001 244 Query 1 244 use `test`; ROLLBACK +master-bin.000001 287 Query 1 287 use `test`; DO RELEASE_LOCK("a") delete from t1; delete from t2; reset master; @@ -202,3 +203,53 @@ select (@after-@before) >= 2; (@after-@before) >= 2 1 drop table t1,t2; +commit; +begin; +create temporary table ti (a int) engine=innodb; +rollback; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +insert into ti values(1); +set autocommit=0; +create temporary table t1 (a int) engine=myisam; +commit; +insert t1 values (1); +rollback; +create table t0 (n int); +insert t0 select * from t1; +set autocommit=1; +insert into t0 select GET_LOCK("lock1",null); +set autocommit=0; +create table t2 (n int) engine=innodb; +insert into t2 values (3); +select get_lock("lock1",60); +get_lock("lock1",60) +1 +show binlog events from 79; +Log_name Pos Event_type Server_id Orig_log_pos Info +master-bin.000001 79 Query 1 79 use `test`; BEGIN +master-bin.000001 119 Query 1 79 use `test`; insert into t1 values(16) +master-bin.000001 179 Query 1 79 use `test`; insert into t1 values(18) +master-bin.000001 239 Query 1 239 use `test`; COMMIT +master-bin.000001 280 Query 1 280 use `test`; delete from t1 +master-bin.000001 329 Query 1 329 use `test`; delete from t2 +master-bin.000001 378 Query 1 378 use `test`; alter table t2 type=MyISAM +master-bin.000001 439 Query 1 439 use `test`; insert into t1 values (1) +master-bin.000001 499 Query 1 499 use `test`; insert into t2 values (20) +master-bin.000001 560 Query 1 560 use `test`; drop table t1,t2 +master-bin.000001 611 Query 1 611 use `test`; BEGIN +master-bin.000001 651 Query 1 611 use `test`; create temporary table ti (a int) engine=innodb +master-bin.000001 733 Query 1 733 use `test`; ROLLBACK +master-bin.000001 776 Query 1 776 use `test`; insert into ti values(1) +master-bin.000001 835 Query 1 835 use `test`; BEGIN +master-bin.000001 875 Query 1 835 use `test`; create temporary table t1 (a int) engine=myisam +master-bin.000001 957 Query 1 957 use `test`; COMMIT +master-bin.000001 998 Query 1 998 use `test`; create table t0 (n int) +master-bin.000001 1056 Query 1 1056 use `test`; insert t0 select * from t1 +master-bin.000001 1117 Query 1 1117 use `test`; DO RELEASE_LOCK("a") +master-bin.000001 1172 Query 1 1172 use `test`; insert into t0 select GET_LOCK("lock1",null) +master-bin.000001 1251 Query 1 1251 use `test`; create table t2 (n int) engine=innodb +master-bin.000001 1323 Query 1 1323 use `test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `test`.`t1`,`test`.`ti` +master-bin.000001 1424 Query 1 1424 use `test`; DO RELEASE_LOCK("lock1") +do release_lock("lock1"); +drop table t0,t2; diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index 0a6f3ddc28b..d2d0417f6e6 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -498,6 +498,16 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 system NULL NULL NULL NULL 1 Using temporary 1 SIMPLE t2 index NULL PRIMARY 4 NULL 2 Using index; Distinct drop table t1,t2; +create table t1 ( +c1 varchar(32), +key (c1) +) engine=myisam; +alter table t1 disable keys; +insert into t1 values ('a'), ('b'); +select c1 from t1 order by c1 limit 1; +c1 +a +drop table t1; CREATE TABLE t1 (`a` int(11) NOT NULL default '0', `b` int(11) NOT NULL default '0', UNIQUE KEY `a` USING RTREE (`a`,`b`)) ENGINE=MyISAM; Got one of the listed errors create table t1 (a int, b varchar(200), c text not null) checksum=1; @@ -670,3 +680,53 @@ show index from t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment t1 1 a 1 a A 10 NULL NULL YES BTREE drop table t1; +set myisam_stats_method=nulls_ignored; +show variables like 'myisam_stats_method'; +Variable_name Value +myisam_stats_method nulls_ignored +create table t1 ( +a char(3), b char(4), c char(5), d char(6), +key(a,b,c,d) +); +insert into t1 values ('bcd','def1', NULL, 'zz'); +insert into t1 values ('bcd','def2', NULL, 'zz'); +insert into t1 values ('bce','def1', 'yuu', NULL); +insert into t1 values ('bce','def2', NULL, 'quux'); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +show index from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 1 a 1 a A 2 NULL NULL YES BTREE +t1 1 a 2 b A 4 NULL NULL YES BTREE +t1 1 a 3 c A 4 NULL NULL YES BTREE +t1 1 a 4 d A 4 NULL NULL YES BTREE +delete from t1; +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +show index from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 1 a 1 a A 0 NULL NULL YES BTREE +t1 1 a 2 b A 0 NULL NULL YES BTREE +t1 1 a 3 c A 0 NULL NULL YES BTREE +t1 1 a 4 d A 0 NULL NULL YES BTREE +set myisam_stats_method=DEFAULT; +drop table t1; +create table t1( +cip INT NOT NULL, +time TIME NOT NULL, +score INT NOT NULL DEFAULT 0, +bob TINYBLOB +); +insert into t1 (cip, time) VALUES (1, '00:01'), (2, '00:02'), (3,'00:03'); +insert into t1 (cip, bob, time) VALUES (4, 'a', '00:04'), (5, 'b', '00:05'), +(6, 'c', '00:06'); +select * from t1 where bob is null and cip=1; +cip time score bob +1 00:01:00 0 NULL +create index bug on t1 (bob(22), cip, time); +select * from t1 where bob is null and cip=1; +cip time score bob +1 00:01:00 0 NULL +drop table t1; diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index cb2e8e5528a..fb72abe9b45 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -1493,3 +1493,13 @@ insert into t2 (a, b) values (NULL, NULL),(10, NULL),(NULL, "twenty"),(30, "thir drop table t1, t2; +create table t1 (a text character set utf8, b text character set latin1); +insert t1 values (0x4F736E616272C3BC636B, 0x4BF66C6E); +select * from t1; +a b +Osnabrück Köln +test.t1: Records: 1 Deleted: 0 Skipped: 0 Warnings: 0 +select * from t1; +a b +Osnabrück Köln +drop table t1; diff --git a/mysql-test/r/ndb_alter_table.result b/mysql-test/r/ndb_alter_table.result index 3714ea14e16..b5fceba7cee 100644 --- a/mysql-test/r/ndb_alter_table.result +++ b/mysql-test/r/ndb_alter_table.result @@ -179,8 +179,7 @@ a b c 2 two two alter table t1 drop index c; select * from t1 where b = 'two'; -a b c -2 two two +ERROR HY000: Can't lock file (errno: 241) select * from t1 where b = 'two'; a b c 2 two two diff --git a/mysql-test/r/ndb_basic.result b/mysql-test/r/ndb_basic.result index 3712fa2b5ca..42b5a39d3d8 100644 --- a/mysql-test/r/ndb_basic.result +++ b/mysql-test/r/ndb_basic.result @@ -667,3 +667,7 @@ counter datavalue 57 newval 58 newval drop table t1; +CREATE TABLE t1 ( b INT ) PACK_KEYS = 0 ENGINE = ndb; +select * from t1; +b +drop table t1; diff --git a/mysql-test/r/ndb_charset.result b/mysql-test/r/ndb_charset.result index 00bc36a7c0d..b8d881fca83 100644 --- a/mysql-test/r/ndb_charset.result +++ b/mysql-test/r/ndb_charset.result @@ -190,12 +190,22 @@ p a 6 AAA drop table t1; create table t1 ( -a varchar(10) primary key -) engine=ndb; -insert into t1 values ('jonas % '); -replace into t1 values ('jonas % '); -replace into t1 values ('jonas % '); +a char(10) primary key +) engine=ndbcluster default charset=latin1; +insert into t1 values ('aaabb'); select * from t1; a -jonas % +aaabb +replace into t1 set a = 'AAABB'; +select * from t1; +a +AAABB +replace into t1 set a = 'aAaBb'; +select * from t1; +a +aAaBb +replace into t1 set a = 'aaabb'; +select * from t1; +a +aaabb drop table t1; diff --git a/mysql-test/r/ndb_multi.result b/mysql-test/r/ndb_multi.result index 2080be241e8..bd3af223a65 100644 --- a/mysql-test/r/ndb_multi.result +++ b/mysql-test/r/ndb_multi.result @@ -30,6 +30,7 @@ create table t1 (a int) engine=ndbcluster; insert into t1 value (2); select * from t1; ERROR HY000: Got error 241 'Invalid schema object version' from ndbcluster +flush table t1; select * from t1; a 2 diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index f5bf3ffa96d..ba9336c20bb 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -639,25 +639,6 @@ execute stmt using @a, @b; ?=? 1 deallocate prepare stmt; -create table t1 (utext varchar(20) character set ucs2); -insert into t1 values ("lily"); -insert into t1 values ("river"); -prepare stmt from 'select utext from t1 where utext like ?'; -set @param1='%%'; -execute stmt using @param1; -utext -lily -river -execute stmt using @param1; -utext -lily -river -select utext from t1 where utext like '%%'; -utext -lily -river -drop table t1; -deallocate prepare stmt; create table t1 (a int); prepare stmt from "select ??"; 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 '?' at line 1 @@ -699,3 +680,56 @@ execute stmt; @@tx_isolation REPEATABLE-READ deallocate prepare stmt; +prepare stmt from "create temporary table t1 (letter enum('','a','b','c') +not null)"; +execute stmt; +drop table t1; +execute stmt; +drop table t1; +execute stmt; +drop table t1; +set names latin1; +prepare stmt from "create table t1 (a enum('test') default 'test') + character set utf8"; +execute stmt; +drop table t1; +execute stmt; +drop table t1; +execute stmt; +drop table t1; +set names default; +deallocate prepare stmt; +create table t1 ( +word_id mediumint(8) unsigned not null default '0', +formatted varchar(20) not null default '' +); +insert into t1 values +(80,'pendant'), (475,'pretendants'), (989,'tendances'), +(1019,'cependant'),(1022,'abondance'),(1205,'independants'), +(13,'lessiver'),(25,'lambiner'),(46,'situer'),(71,'terminer'), +(82,'decrocher'); +select count(*) from t1 where formatted like '%NDAN%'; +count(*) +6 +select count(*) from t1 where formatted like '%ER'; +count(*) +5 +prepare stmt from "select count(*) from t1 where formatted like ?"; +set @like="%NDAN%"; +execute stmt using @like; +count(*) +6 +set @like="%ER"; +execute stmt using @like; +count(*) +5 +set @like="%NDAN%"; +execute stmt using @like; +count(*) +6 +set @like="%ER"; +execute stmt using @like; +count(*) +5 +deallocate prepare stmt; +drop table t1; diff --git a/mysql-test/r/ps_grant.result b/mysql-test/r/ps_grant.result index f883bef8591..1d66bad7eb7 100644 --- a/mysql-test/r/ps_grant.result +++ b/mysql-test/r/ps_grant.result @@ -32,19 +32,19 @@ identified by 'looser' ; show grants for second_user@localhost ; Grants for second_user@localhost GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3' -GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost' GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost' +GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost' drop table mysqltest.t9 ; show grants for second_user@localhost ; Grants for second_user@localhost GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3' -GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost' GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost' +GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost' show grants for second_user@localhost ; Grants for second_user@localhost GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3' -GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost' GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost' +GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost' prepare s_t1 from 'select a as my_col from t1' ; execute s_t1 ; my_col diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result index ed87e2be2b4..24363ea27ab 100644 --- a/mysql-test/r/query_cache.result +++ b/mysql-test/r/query_cache.result @@ -982,4 +982,29 @@ show status like "Qcache_hits"; Variable_name Value Qcache_hits 1 drop table t1; +create table t1 (a int); +flush status; +(select a from t1) union (select a from t1); +a +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +show status like "Qcache_inserts"; +Variable_name Value +Qcache_inserts 1 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 0 +(select a from t1) union (select a from t1); +a +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +show status like "Qcache_inserts"; +Variable_name Value +Qcache_inserts 1 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 1 +drop table t1; set GLOBAL query_cache_size=0; diff --git a/mysql-test/r/rpl_until.result b/mysql-test/r/rpl_until.result index 5772f176919..6bbfe36c56b 100644 --- a/mysql-test/r/rpl_until.result +++ b/mysql-test/r/rpl_until.result @@ -31,7 +31,7 @@ n 4 show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master -# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 561 slave-relay-bin.000002 # master-bin.000001 Yes No 0 0 244 # Master master-bin.000001 244 No # +# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 561 slave-relay-bin.000002 # master-bin.000001 # No 0 0 244 # Master master-bin.000001 244 No # start slave until master_log_file='master-no-such-bin.000001', master_log_pos=291; select * from t1; n @@ -41,7 +41,7 @@ n 4 show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master -# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 561 slave-relay-bin.000002 # master-bin.000001 Yes No 0 0 244 # Master master-no-such-bin.000001 291 No # +# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 561 slave-relay-bin.000002 # master-bin.000001 # No 0 0 244 # Master master-no-such-bin.000001 291 No # start slave until relay_log_file='slave-relay-bin.000002', relay_log_pos=537; select * from t2; n @@ -49,7 +49,7 @@ n 2 show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master -# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 561 slave-relay-bin.000002 # master-bin.000001 Yes No 0 0 449 # Relay slave-relay-bin.000002 537 No # +# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 561 slave-relay-bin.000002 # master-bin.000001 # No 0 0 449 # Relay slave-relay-bin.000002 537 No # start slave; stop slave; start slave until master_log_file='master-bin.000001', master_log_pos=561; diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index be46d180f2d..b80ca2b195e 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -2698,3 +2698,19 @@ a b c d 1 2 2 1 1 2 3 1 DROP TABLE IF EXISTS t1, t2; +create table t1 (f1 int primary key, f2 int); +create table t2 (f3 int, f4 int, primary key(f3,f4)); +insert into t1 values (1,1); +insert into t2 values (1,1),(1,2); +select distinct count(f2) >0 from t1 left join t2 on f1=f3 group by f1; +count(f2) >0 +1 +drop table t1,t2; +create table t1 (f1 int,f2 int); +insert into t1 values(1,1); +create table t2 (f3 int, f4 int, primary key(f3,f4)); +insert into t2 values(1,1); +select * from t1 where f1 in (select f3 from t2 where (f3,f4)= (select f3,f4 from t2)); +f1 f2 +1 1 +drop table t1,t2; diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index 1e5e8f442a8..9861daff409 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -513,3 +513,10 @@ t1 CREATE TABLE `t1` ( KEY `c2` USING BTREE (`c2`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; +flush tables; +SHOW TABLE STATUS like 't1'; +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 +t1 NULL NULL NULL NULL # # # # NULL NULL NULL NULL NULL NULL NULL NULL Incorrect information in file: './test/t1.frm' +show create table t1; +ERROR HY000: Incorrect information in file: './test/t1.frm' +drop table t1; diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 318bfa2cda8..a9b2345d834 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -1253,3 +1253,29 @@ id 5 99 drop table t1; +create table t1 (f1 decimal(60,25), f2 decimal(60,25)); +insert into t1 values (0.0,0.0); +select f1 from t1 union all select f2 from t1; +f1 +0.0000000000000000000000000 +0.0000000000000000000000000 +select 'XXXXXXXXXXXXXXXXXXXX' as description, f1 from t1 +union all +select 'YYYYYYYYYYYYYYYYYYYY' as description, f2 from t1; +description f1 +XXXXXXXXXXXXXXXXXXXX 0.0000000000000000000000000 +YYYYYYYYYYYYYYYYYYYY 0.0000000000000000000000000 +drop table t1; +create table t1 (f1 decimal(60,24), f2 decimal(60,24)); +insert into t1 values (0.0,0.0); +select f1 from t1 union all select f2 from t1; +f1 +0.000000000000000000000000 +0.000000000000000000000000 +select 'XXXXXXXXXXXXXXXXXXXX' as description, f1 from t1 +union all +select 'YYYYYYYYYYYYYYYYYYYY' as description, f2 from t1; +description f1 +XXXXXXXXXXXXXXXXXXXX 0.000000000000000000000000 +YYYYYYYYYYYYYYYYYYYY 0.000000000000000000000000 +drop table t1; diff --git a/mysql-test/r/update.result b/mysql-test/r/update.result index d6c1118f90c..7854fd773a1 100644 --- a/mysql-test/r/update.result +++ b/mysql-test/r/update.result @@ -263,3 +263,98 @@ test delete from t1 where count(*)=1; ERROR HY000: Invalid use of group function drop table t1; +create table t1 ( a int, b int default 0, index (a) ); +insert into t1 (a) values (0),(0),(0),(0),(0),(0),(0),(0); +flush status; +select a from t1 order by a limit 1; +a +0 +show status like 'handler_read%'; +Variable_name Value +Handler_read_first 1 +Handler_read_key 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_rnd 0 +Handler_read_rnd_next 0 +flush status; +update t1 set a=9999 order by a limit 1; +update t1 set b=9999 order by a limit 1; +show status like 'handler_read%'; +Variable_name Value +Handler_read_first 1 +Handler_read_key 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_rnd 2 +Handler_read_rnd_next 9 +flush status; +delete from t1 order by a limit 1; +show status like 'handler_read%'; +Variable_name Value +Handler_read_first 1 +Handler_read_key 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_rnd 0 +Handler_read_rnd_next 0 +flush status; +delete from t1 order by a desc limit 1; +show status like 'handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_rnd 1 +Handler_read_rnd_next 9 +alter table t1 disable keys; +flush status; +delete from t1 order by a limit 1; +show status like 'handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_rnd 1 +Handler_read_rnd_next 9 +select * from t1; +a b +0 0 +0 0 +0 0 +0 0 +0 0 +update t1 set a=a+10,b=1 order by a limit 3; +update t1 set a=a+11,b=2 order by a limit 3; +update t1 set a=a+12,b=3 order by a limit 3; +select * from t1 order by a; +a b +11 2 +21 2 +22 3 +22 3 +23 3 +drop table t1; +create table t1 (f1 date not null); +insert into t1 values('2000-01-01'),('0000-00-00'); +update t1 set f1='2002-02-02' where f1 is null; +select * from t1; +f1 +2000-01-01 +2002-02-02 +drop table t1; +create table t1 (f1 int); +create table t2 (f2 int); +insert into t1 values(1),(2); +insert into t2 values(1),(1); +update t1,t2 set f1=3,f2=3 where f1=f2 and f1=1; +affected rows: 3 +info: Rows matched: 3 Changed: 3 Warnings: 0 +update t2 set f2=1; +update t1 set f1=1 where f1=3; +update t2,t1 set f1=3,f2=3 where f1=f2 and f1=1; +affected rows: 3 +info: Rows matched: 3 Changed: 3 Warnings: 0 +drop table t1,t2; diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index 67c78d82a24..0aa7ea7f83c 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -499,3 +499,8 @@ set names latin1; select @@have_innodb; @@have_innodb # +set @test = @@query_prealloc_size; +set @@query_prealloc_size = @test; +select @@query_prealloc_size = @test; +@@query_prealloc_size = @test +1 diff --git a/mysql-test/std_data/loaddata5.dat b/mysql-test/std_data/loaddata5.dat new file mode 100644 index 00000000000..5bdddfa977a --- /dev/null +++ b/mysql-test/std_data/loaddata5.dat @@ -0,0 +1,3 @@ +"field1","field2" +"a""b","cd""ef" +"a"b",c"d"e diff --git a/mysql-test/t/analyse.test b/mysql-test/t/analyse.test index e38e43381bc..dfca8f575a4 100644 --- a/mysql-test/t/analyse.test +++ b/mysql-test/t/analyse.test @@ -57,4 +57,29 @@ insert into t1 values (100000); select * from t1 procedure analyse (1,1); drop table t1; +# +# Bug #14138 ROLLUP and PROCEDURE ANALYSE() hang server +# +create table t1 (product varchar(32), country_id int not null, year int, + profit int); +insert into t1 values ( 'Computer', 2,2000, 1200), + ( 'TV', 1, 1999, 150), + ( 'Calculator', 1, 1999,50), + ( 'Computer', 1, 1999,1500), + ( 'Computer', 1, 2000,1500), + ( 'TV', 1, 2000, 150), + ( 'TV', 2, 2000, 100), + ( 'TV', 2, 2000, 100), + ( 'Calculator', 1, 2000,75), + ( 'Calculator', 2, 2000,75), + ( 'TV', 1, 1999, 100), + ( 'Computer', 1, 1999,1200), + ( 'Computer', 2, 2000,1500), + ( 'Calculator', 2, 2000,75), + ( 'Phone', 3, 2003,10) + ; +create table t2 (country_id int primary key, country char(20) not null); +insert into t2 values (1, 'USA'),(2,'India'), (3,'Finland'); +select product, sum(profit),avg(profit) from t1 group by product with rollup procedure analyse(); +drop table t1,t2; # End of 4.1 tests diff --git a/mysql-test/t/analyze.test b/mysql-test/t/analyze.test index 3c3b3933bc3..5d653b65579 100644 --- a/mysql-test/t/analyze.test +++ b/mysql-test/t/analyze.test @@ -39,4 +39,13 @@ check table t1; drop table t1; +# +# procedure in PS BUG#13673 +# +CREATE TABLE t1 (a int); +prepare stmt1 from "SELECT * FROM t1 PROCEDURE ANALYSE()"; +execute stmt1; +execute stmt1; +deallocate prepare stmt1; + # End of 4.1 tests diff --git a/mysql-test/t/bdb.test b/mysql-test/t/bdb.test index 6ceb0ea0789..de9709b97ad 100644 --- a/mysql-test/t/bdb.test +++ b/mysql-test/t/bdb.test @@ -930,4 +930,22 @@ SELECT id FROM t1 WHERE (list_id = 1) AND (term = "lettera"); SELECT id FROM t1 WHERE (list_id = 1) AND (term = "letterd"); DROP TABLE t1; -# End of 4.1 tests +# +# Bug #15536: Crash when DELETE with subquery using BDB tables +# +create table t1 (a int, key(a)) engine=bdb; +create table t2 (b int, key(b)) engine=bdb; +insert into t1 values (1),(1),(2),(3),(4); +insert into t2 values (1),(5),(6),(7); +delete from t1 where (a in (select b from t2)); +select count(*) from t1; +# INSERT also blows up +--error 1242 +insert into t1 set a=(select b from t2); +select count(*) from t1; +# UPDATE also blows up +update t1 set a = a + 1 where (a in (select b from t2)); +select count(*) from t1; +drop table t1, t2; + +--echo End of 4.1 tests diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index 73184853d1a..7799200eaa0 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -3,7 +3,7 @@ # --disable_warnings -drop table if exists t1,t2,t3; +drop table if exists t1,t2,t3,t4,t5; drop database if exists mysqltest; --enable_warnings @@ -200,13 +200,6 @@ drop table t1; # bug #1434 # -create table t1 select 1,2,3; -create table if not exists t1 select 1,2; ---error 1136 -create table if not exists t1 select 1,2,3,4; -create table if not exists t1 select 1; -select * from t1; -drop table t1; create table t1 select 1,2,3; create table if not exists t1 select 1,2; --error 1136 @@ -501,6 +494,13 @@ AS f2 FROM t1; DESC t2; DROP TABLE t1,t2; +# +# Bug#12913 Simple SQL can crash server or connection +# +CREATE TABLE t12913 (f1 ENUM ('a','b')) AS SELECT 'a' AS f1; +SELECT * FROM t12913; +DROP TABLE t12913; + # # Bug#11028: Crash on create table like # @@ -526,4 +526,81 @@ create table t1 (a int); create table if not exists t1 (a int); drop table t1; +# BUG#14139 +create table t1 ( + a varchar(112) charset utf8 collate utf8_bin not null, + primary key (a) +) select 'test' as a ; +show create table t1; +drop table t1; + +# +# BUG#14480: assert failure in CREATE ... SELECT because of wrong +# calculation of number of NULLs. +# +CREATE TABLE t2 ( + a int(11) default NULL +); +insert into t2 values(111); + +create table t1 ( + a varchar(12) charset utf8 collate utf8_bin not null, + b int not null, primary key (a) +) select a, 1 as b from t2 ; +show create table t1; +drop table t1; + +create table t1 ( + a varchar(12) charset utf8 collate utf8_bin not null, + b int not null, primary key (a) +) select 'a' as a , 1 as b from t2 ; +show create table t1; +drop table t1; + +create table t1 ( + a varchar(12) charset utf8 collate utf8_bin, + b int not null, primary key (a) +) select 'a' as a , 1 as b from t2 ; +show create table t1; +drop table t1, t2; + +create table t1 ( + a1 int not null, + a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int +); +insert into t1 values (1,1,1, 1,1,1, 1,1,1); + +create table t2 ( + a1 varchar(12) charset utf8 collate utf8_bin not null, + a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int, + primary key (a1) +) select a1,a2,a3,a4,a5,a6,a7,a8,a9 from t1 ; +drop table t2; + +create table t2 ( + a1 varchar(12) charset utf8 collate utf8_bin, + a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int +) select a1,a2,a3,a4,a5,a6,a7,a8,a9 from t1; + +drop table t1, t2; +create table t1 ( + a1 int, a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int +); +insert into t1 values (1,1,1, 1,1,1, 1,1,1); + +create table t2 ( + a1 varchar(12) charset utf8 collate utf8_bin not null, + a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int, + primary key (a1) +) select a1,a2,a3,a4,a5,a6,a7,a8,a9 from t1 ; + +# Test the default value +drop table t2; + +create table t2 ( a int default 3, b int default 3) + select a1,a2 from t1; +show create table t2; + +drop table t1, t2; + # End of 4.1 tests diff --git a/mysql-test/t/csv.test b/mysql-test/t/csv.test index 2ac46d75f9a..5b693335a43 100644 --- a/mysql-test/t/csv.test +++ b/mysql-test/t/csv.test @@ -1314,4 +1314,41 @@ select period from t1; drop table if exists t1,t2,t3,t4; +# +# Bug #13894 Server crashes on update of CSV table +# + +--disable_warnings +DROP TABLE IF EXISTS bug13894; +--enable_warnings + +CREATE TABLE bug13894 ( val integer ) ENGINE = CSV; +INSERT INTO bug13894 VALUES (5); +INSERT INTO bug13894 VALUES (10); +INSERT INTO bug13894 VALUES (11); +INSERT INTO bug13894 VALUES (10); +SELECT * FROM bug13894; +UPDATE bug13894 SET val=6 WHERE val=10; +SELECT * FROM bug13894; +DROP TABLE bug13894; + +# +# Bug #14672 Bug in deletion +# + +--disable_warnings +DROP TABLE IF EXISTS bug14672; +--enable_warnings + +CREATE TABLE bug14672 (c1 integer) engine = CSV; +INSERT INTO bug14672 VALUES (1), (2), (3); +SELECT * FROM bug14672; +DELETE FROM bug14672 WHERE c1 = 2; +SELECT * FROM bug14672; +INSERT INTO bug14672 VALUES (4); +SELECT * FROM bug14672; +INSERT INTO bug14672 VALUES (5); +SELECT * FROM bug14672; +DROP TABLE bug14672; + # End of 4.1 tests diff --git a/mysql-test/t/ctype_cp1250_ch.test b/mysql-test/t/ctype_cp1250_ch.test index ea4b35a44a3..2d1e5f0bf9d 100644 --- a/mysql-test/t/ctype_cp1250_ch.test +++ b/mysql-test/t/ctype_cp1250_ch.test @@ -23,4 +23,25 @@ SELECT * FROM t1 WHERE popisek = '2005-01-1'; SELECT * FROM t1 WHERE popisek LIKE '2005-01-1'; drop table t1; +# +# Bug#13347: empty result from query with like and cp1250 charset +# +set names cp1250; +CREATE TABLE t1 +( + id INT AUTO_INCREMENT PRIMARY KEY, + str VARCHAR(32) CHARACTER SET cp1250 COLLATE cp1250_czech_cs NOT NULL default '', + UNIQUE KEY (str) +); + +INSERT INTO t1 VALUES (NULL, 'a'); +INSERT INTO t1 VALUES (NULL, 'aa'); +INSERT INTO t1 VALUES (NULL, 'aaa'); +INSERT INTO t1 VALUES (NULL, 'aaaa'); +INSERT INTO t1 VALUES (NULL, 'aaaaa'); +INSERT INTO t1 VALUES (NULL, 'aaaaaa'); +INSERT INTO t1 VALUES (NULL, 'aaaaaaa'); +select * from t1 where str like 'aa%'; +drop table t1; + # End of 4.1 tests diff --git a/mysql-test/t/ctype_cp932.test b/mysql-test/t/ctype_cp932.test index d6c3c226140..3ea8be211df 100644 --- a/mysql-test/t/ctype_cp932.test +++ b/mysql-test/t/ctype_cp932.test @@ -401,29 +401,6 @@ DROP TABLE t2; DROP TABLE t3; #DROP TABLE t4; -# Test prepared statement with 0x8300 sequence in parameter while -# running with cp932 client character set. -RESET MASTER; -CREATE TABLE t1(f1 blob); -PREPARE stmt1 FROM 'INSERT INTO t1 VALUES(?)'; -SET @var1= x'8300'; -# TODO: Note that this doesn't actually test the code which was added for -# bug#11338 because this syntax for prepared statements causes the PS to -# be replicated differently than if we executed the PS from C or Java. -# Using this syntax, variable names are inserted into the binlog instead -# of values. The real goal of this test is to check the code that was -# added to Item_param::query_val_str() in order to do hex encoding of -# PS parameters when the client character set is cp932; -# Bug#11338 has an example java program which can be used to verify this -# code (and I have used it to test the fix) until there is some way to -# exercise this code from mysql-test-run. -EXECUTE stmt1 USING @var1; ---replace_column 2 # 5 # -SHOW BINLOG EVENTS FROM 79; -SELECT HEX(f1) FROM t1; -DROP table t1; -# end test for bug#11338 - SET collation_connection='cp932_japanese_ci'; -- source include/ctype_filesort.inc -- source include/ctype_innodb_like.inc diff --git a/mysql-test/t/ctype_cp932_binlog.test b/mysql-test/t/ctype_cp932_binlog.test new file mode 100644 index 00000000000..e8ec0d46caf --- /dev/null +++ b/mysql-test/t/ctype_cp932_binlog.test @@ -0,0 +1,35 @@ +-- source include/not_embedded.inc +-- source include/have_cp932.inc + +--character_set cp932 +--disable_warnings +drop table if exists t1; +--enable_warnings + +set names cp932; +set character_set_database = cp932; + +# Test prepared statement with 0x8300 sequence in parameter while +# running with cp932 client character set. +RESET MASTER; +CREATE TABLE t1(f1 blob); +PREPARE stmt1 FROM 'INSERT INTO t1 VALUES(?)'; +SET @var1= x'8300'; +# TODO: Note that this doesn't actually test the code which was added for +# bug#11338 because this syntax for prepared statements causes the PS to +# be replicated differently than if we executed the PS from C or Java. +# Using this syntax, variable names are inserted into the binlog instead +# of values. The real goal of this test is to check the code that was +# added to Item_param::query_val_str() in order to do hex encoding of +# PS parameters when the client character set is cp932; +# Bug#11338 has an example java program which can be used to verify this +# code (and I have used it to test the fix) until there is some way to +# exercise this code from mysql-test-run. +EXECUTE stmt1 USING @var1; +--replace_column 2 # 5 # +SHOW BINLOG EVENTS FROM 79; +SELECT HEX(f1) FROM t1; +DROP table t1; +# end test for bug#11338 + +# End of 4.1 tests diff --git a/mysql-test/t/ctype_euckr.test b/mysql-test/t/ctype_euckr.test new file mode 100644 index 00000000000..56939817b2f --- /dev/null +++ b/mysql-test/t/ctype_euckr.test @@ -0,0 +1,33 @@ +-- source include/have_euckr.inc + +# +# Tests with the euckr character set +# +--disable_warnings +drop table if exists t1; +--enable_warnings + +SET @test_character_set= 'euckr'; +SET @test_collation= 'euckr_korean_ci'; +-- source include/ctype_common.inc + +SET NAMES euckr; +SET collation_connection='euckr_korean_ci'; +-- source include/ctype_filesort.inc +-- source include/ctype_innodb_like.inc +-- source include/ctype_like_escape.inc +SET collation_connection='euckr_bin'; +-- source include/ctype_filesort.inc +-- source include/ctype_innodb_like.inc +-- source include/ctype_like_escape.inc + +# +# Bug#15377 Valid multibyte sequences are truncated on INSERT +# +SET NAMES euckr; +CREATE TABLE t1 (a text) character set euckr; +INSERT INTO t1 VALUES (0xA2E6),(0xFEF7); +SELECT hex(a) FROM t1 ORDER BY a; +DROP TABLE t1; + +# End of 4.1 tests diff --git a/mysql-test/t/ctype_gb2312.test b/mysql-test/t/ctype_gb2312.test new file mode 100644 index 00000000000..835818d441c --- /dev/null +++ b/mysql-test/t/ctype_gb2312.test @@ -0,0 +1,33 @@ +-- source include/have_gb2312.inc + +# +# Tests with the gb2312 character set +# +--disable_warnings +drop table if exists t1; +--enable_warnings + +SET @test_character_set= 'gb2312'; +SET @test_collation= 'gb2312_chinese_ci'; +-- source include/ctype_common.inc + +SET NAMES gb2312; +SET collation_connection='gb2312_chinese_ci'; +-- source include/ctype_filesort.inc +-- source include/ctype_innodb_like.inc +-- source include/ctype_like_escape.inc +SET collation_connection='gb2312_bin'; +-- source include/ctype_filesort.inc +-- source include/ctype_innodb_like.inc +-- source include/ctype_like_escape.inc + +# +# Bug#15377 Valid multibyte sequences are truncated on INSERT +# +SET NAMES gb2312; +CREATE TABLE t1 (a text) character set gb2312; +INSERT INTO t1 VALUES (0xA2A1),(0xD7FE); +SELECT hex(a) FROM t1 ORDER BY a; +DROP TABLE t1; + +# End of 4.1 tests diff --git a/mysql-test/t/ctype_recoding.test b/mysql-test/t/ctype_recoding.test index 9949ef88da4..5648cea7fd3 100644 --- a/mysql-test/t/ctype_recoding.test +++ b/mysql-test/t/ctype_recoding.test @@ -144,8 +144,7 @@ create table t1 (a char(10) character set cp1251); insert into t1 values (_koi8r'×ÁÓÑ'); # this is possible: select * from t1 where a=_koi8r'×ÁÓÑ'; -# this is not possible, because we have a function, not just a constant: ---error 1267 +# this is possible, because we have a function with constant arguments: select * from t1 where a=concat(_koi8r'×ÁÓÑ'); # this is not posible, cannot convert _latin1'×ÁÓÑ' into cp1251: --error 1267 @@ -153,6 +152,14 @@ select * from t1 where a=_latin1' drop table t1; set names latin1; +# +# Bug#10446 Illegal mix of collations +# +create table t1 (a char(10) character set utf8 collate utf8_bin); +insert into t1 values (' xxx'); +select * from t1 where a=lpad('xxx',10,' '); +drop table t1; + # # Check more automatic conversion # diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test index 2c9e71ddff5..ed55287ca05 100644 --- a/mysql-test/t/ctype_ucs.test +++ b/mysql-test/t/ctype_ucs.test @@ -419,4 +419,26 @@ insert into t1 values (0x005b); select hex(a) from t1; drop table t1; +# +# Bug #14583 Bug on query using a LIKE on indexed field with ucs2_bin collation +# +create table t1(f1 varchar(5) CHARACTER SET ucs2 COLLATE ucs2_bin NOT NULL) engine=InnoDB; +insert into t1 values('a'); +create index t1f1 on t1(f1); +select f1 from t1 where f1 like 'a%'; +drop table t1; + +# +# Bug#9442 Set parameter make query fail if column character set is UCS2 +# +create table t1 (utext varchar(20) character set ucs2); +insert into t1 values ("lily"); +insert into t1 values ("river"); +prepare stmt from 'select utext from t1 where utext like ?'; +set @param1='%%'; +execute stmt using @param1; +execute stmt using @param1; +select utext from t1 where utext like '%%'; +drop table t1; +deallocate prepare stmt; # End of 4.1 tests diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index dcb7469d46e..01bffe9492e 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -873,4 +873,23 @@ create table t1 (a varchar(255)) default charset=utf8; select * from t1 where find_in_set('-1', a); drop table t1; +# +# Bug#13233: select distinct char(column) fails with utf8 +# +create table t1 (a int); +insert into t1 values (48),(49),(50); +set names utf8; +select distinct char(a) from t1; +drop table t1; + +# +# Bug#15581: COALESCE function truncates mutli-byte TINYTEXT values +# +CREATE TABLE t1 (t TINYTEXT CHARACTER SET utf8); +INSERT INTO t1 VALUES(REPEAT('a', 100)); +CREATE TEMPORARY TABLE t2 SELECT COALESCE(t) AS bug FROM t1; +SELECT LENGTH(bug) FROM t2; +DROP TABLE t2; +DROP TABLE t1; + # End of 4.1 tests diff --git a/mysql-test/t/date_formats.test b/mysql-test/t/date_formats.test index 62e9d81021e..6d501865d2c 100644 --- a/mysql-test/t/date_formats.test +++ b/mysql-test/t/date_formats.test @@ -260,4 +260,12 @@ select str_to_date("2003-04-05 g", "%Y-%m-%d") as f1, str_to_date("2003-04-05 10:11:12.101010234567", "%Y-%m-%d %H:%i:%S.%f") as f2; --enable_ps_protocol +# +# Bug #14016 +# +create table t1 (f1 datetime); +insert into t1 (f1) values ("2005-01-01"); +insert into t1 (f1) values ("2005-02-01"); +select date_format(f1, "%m") as d1, date_format(f1, "%M") as d2 from t1 order by date_format(f1, "%M"); +drop table t1; # End of 4.1 tests diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test index fa63778c4c1..1399b9bfdff 100644 --- a/mysql-test/t/fulltext.test +++ b/mysql-test/t/fulltext.test @@ -348,6 +348,13 @@ INSERT INTO t1 VALUES('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'); SET myisam_repair_threads=2; REPAIR TABLE t1; SET myisam_repair_threads=@@global.myisam_repair_threads; + +# +# BUG#5686 - #1034 - Incorrect key file for table - only utf8 +# +INSERT INTO t1 VALUES('testword\'\''); +SELECT a FROM t1 WHERE MATCH a AGAINST('testword' IN BOOLEAN MODE); +SELECT a FROM t1 WHERE MATCH a AGAINST('testword\'\'' IN BOOLEAN MODE); DROP TABLE t1; # End of 4.1 tests diff --git a/mysql-test/t/fulltext2.test b/mysql-test/t/fulltext2.test index bcd39b9ea04..7a7b572d58f 100644 --- a/mysql-test/t/fulltext2.test +++ b/mysql-test/t/fulltext2.test @@ -179,7 +179,37 @@ update t1 set a='aaaxxx' where a = 'aaayyy'; select count(*) from t1 where match a against ('aaaxxx' in boolean mode); select count(*) from t1 where match a against ('aaayyy' in boolean mode); select count(*) from t1 where match a against ('aaazzz' in boolean mode); - drop table t1; +# +# BUG#11336 +# +# for uca collation isalnum and strnncollsp don't agree on whether +# 0xC2A0 is a space (strnncollsp is right, isalnum is wrong). +# +# they still don't, the bug was fixed by avoiding strnncollsp +# + +set names utf8; +create table t1(a text,fulltext(a)) collate=utf8_swedish_ci; +insert into t1 values('test test '),('test'),('test'),('test'), +('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'), +('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'), +('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'), +('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'), +('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'), +('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'), +('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'), +('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'), +('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'), +('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'), +('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'), +('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'), +('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'), +('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'), +('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'); +delete from t1 limit 1; +drop table t1; +set names latin1; + # End of 4.1 tests diff --git a/mysql-test/t/func_math.test b/mysql-test/t/func_math.test index c75454a96d4..a8f62e38e86 100644 --- a/mysql-test/t/func_math.test +++ b/mysql-test/t/func_math.test @@ -86,4 +86,14 @@ insert into t1 values (1); select rand(i) from t1; drop table t1; +# +# Bug #14009: use of abs() on null value causes problems with filesort +# +# InnoDB is required to reproduce the fault, but it is okay if we default to +# MyISAM when testing. +create table t1 (a varchar(90), ts datetime not null, index (a)) engine=innodb default charset=utf8; +insert into t1 values ('http://www.foo.com/', now()); +select a from t1 where a='http://www.foo.com/' order by abs(timediff(ts, 0)); +drop table t1; + # End of 4.1 tests diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test index 72af9024070..87d9d601c87 100644 --- a/mysql-test/t/func_misc.test +++ b/mysql-test/t/func_misc.test @@ -38,4 +38,9 @@ select a from t1 where mid(a+0,6,3) = ( mid(20040106123400,6,3) ); drop table t1; +# Test for BUG#9535 +create table t1 as select uuid(), length(uuid()); +show create table t1; +drop table t1; + # End of 4.1 tests diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test index b204bc11e2f..3eb17f3a484 100644 --- a/mysql-test/t/gis.test +++ b/mysql-test/t/gis.test @@ -360,4 +360,7 @@ t1 where object_id=85984; drop table t1; +select (asWKT(geomfromwkb((0x000000000140240000000000004024000000000000)))); +select (asWKT(geomfromwkb((0x010100000000000000000024400000000000002440)))); + # End of 4.1 tests diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index b0de62e679c..805fa881399 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -409,4 +409,28 @@ flush privileges; set @user123="non-existent"; select * from mysql.db where user=@user123; +set names koi8r; +create database ÂÄ; +grant select on ÂÄ.* to root@localhost; +select hex(Db) from mysql.db where Db='ÂÄ'; +show grants for root@localhost; +flush privileges; +show grants for root@localhost; +drop database ÂÄ; +revoke all privileges on ÂÄ.* from root@localhost; +show grants for root@localhost; +set names latin1; + +# +# Bug #15598 Server crashes in specific case during setting new password +# - Caused by a user with host '' +# +insert into mysql.user (host, user) values ('', 'mysqltest_7'); +flush privileges; +set password for mysqltest_7@ = password('systpass'); +show grants for mysqltest_7@; +drop user mysqltest_7@; +--error 1141 +show grants for mysqltest_7@; + # End of 4.1 tests diff --git a/mysql-test/t/grant2.test b/mysql-test/t/grant2.test index cb00c41a0ca..79ea7f70712 100644 --- a/mysql-test/t/grant2.test +++ b/mysql-test/t/grant2.test @@ -206,4 +206,37 @@ drop user 'mysqltest_1'@'localhost'; disconnect con2root; disconnect con3root; +# +# Bug #15775: "drop user" command does not refresh acl_check_hosts +# + +# Create some test users +insert into mysql.user (user, host) values + ('mysqltest_1', 'host1'), + ('mysqltest_2', 'host2'), + ('mysqltest_3', 'host3'), + ('mysqltest_4', 'host4'), + ('mysqltest_5', 'host5'), + ('mysqltest_6', 'host6'), + ('mysqltest_7', 'host7'); +flush privileges; + +# Drop one user +drop user mysqltest_3@host3; + +# This connect failed before fix since the acl_check_hosts list was corrupted by the "drop user" +connect (con8,127.0.0.1,root,,test,$MASTER_MYPORT,); +disconnect con8; +connection default; + +# Clean up - Drop all of the remaining users at once +drop user mysqltest_1@host1, mysqltest_2@host2, mysqltest_4@host4, + mysqltest_5@host5, mysqltest_6@host6, mysqltest_7@host7; + +# Check that it's still possible to connect +connect (con9,127.0.0.1,root,,test,$MASTER_MYPORT,); +disconnect con9; +connection default; + + # End of 4.1 tests diff --git a/mysql-test/t/handler.test b/mysql-test/t/handler.test index 1bb9b1d3504..a78800d3d5a 100644 --- a/mysql-test/t/handler.test +++ b/mysql-test/t/handler.test @@ -347,4 +347,32 @@ drop table t3; drop table t4; drop table t5; +# +# Bug#14397 - OPTIMIZE TABLE with an open HANDLER causes a crash +# +create table t1 (c1 int); +insert into t1 values (1); +# client 1 +handler t1 open; +handler t1 read first; +# client 2 +connect (con2,localhost,root,,); +connection con2; +--exec echo send the below to another connection, do not wait for the result +send optimize table t1; +--sleep 1 +# client 1 +--exec echo proceed with the normal connection +connection default; +handler t1 read next; +handler t1 close; +# client 2 +--exec echo read the result from the other connection +connection con2; +reap; +# client 1 +--exec echo proceed with the normal connection +connection default; +drop table t1; + # End of 4.1 tests diff --git a/mysql-test/t/having.test b/mysql-test/t/having.test index 920a3b752ab..3dd9ace6a1b 100644 --- a/mysql-test/t/having.test +++ b/mysql-test/t/having.test @@ -123,4 +123,16 @@ group by a.id, a.description having (a.description is not null) and (c=0); drop table t1,t2,t3; +# +# Bug #14274: HAVING clause containing only set function +# + +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (3), (4), (1), (3), (1); + +SELECT SUM(a) FROM t1 GROUP BY a HAVING SUM(a)>0; +SELECT SUM(a) FROM t1 GROUP BY a HAVING SUM(a); + +DROP TABLE t1; + # End of 4.1 tests diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index 3a693968769..e2c12eedcae 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -1280,4 +1280,89 @@ connection a; checksum table test_checksum; drop table test_checksum; +# tests for bugs #9802 and #13778 + +# test that FKs between invalid types are not accepted + +set foreign_key_checks=0; +create table t2 (a int primary key, b int, foreign key (b) references t1(a)) engine = innodb; +-- error 1005 +create table t1(a char(10) primary key, b varchar(20)) engine = innodb; +set foreign_key_checks=1; +drop table t2; + +# test that FKs between different charsets are not accepted in CREATE even +# when f_k_c is 0 + +set foreign_key_checks=0; +create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1; +-- error 1005 +create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=utf8; +set foreign_key_checks=1; +drop table t1; + +# test that invalid datatype conversions with ALTER are not allowed + +set foreign_key_checks=0; +create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb; +create table t1(a varchar(10) primary key) engine = innodb; +-- error 1025,1025 +alter table t1 modify column a int; +set foreign_key_checks=1; +drop table t2,t1; + +# test that charset conversions with ALTER are allowed when f_k_c is 0 + +set foreign_key_checks=0; +create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1; +create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1; +alter table t1 convert to character set utf8; +set foreign_key_checks=1; +drop table t2,t1; + +# test that RENAME does not allow invalid charsets when f_k_c is 0 + +set foreign_key_checks=0; +create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1; +create table t3(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=utf8; +-- error 1025 +rename table t3 to t1; +set foreign_key_checks=1; +drop table t2,t3; + +# tests for bug #14056 Column prefix index on UTF-8 primary key column causes 'Can't find record..' + +create table t2 ( + a int, b char(10), filler char(10), primary key(a, b(2)) +) character set utf8 engine = innodb; + +insert into t2 values (1,'abcdefg','one'); +insert into t2 values (2,'ijkilmn','two'); +insert into t2 values (3, 'qrstuvw','three'); +update t2 set a=5, filler='booo' where a=1; +drop table t2; +create table t2 ( + a int, b char(10), filler char(10), primary key(a, b(2)) +) character set ucs2 engine = innodb; + +insert into t2 values (1,'abcdefg','one'); +insert into t2 values (2,'ijkilmn','two'); +insert into t2 values (3, 'qrstuvw','three'); +update t2 set a=5, filler='booo' where a=1; +drop table t2; + +create table t1(a int not null, b char(110),primary key(a,b(100))) engine=innodb default charset=utf8; +insert into t1 values(1,'abcdefg'),(2,'defghijk'); +insert into t1 values(6,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1); +insert into t1 values(7,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2); +select a,hex(b) from t1 order by b; +update t1 set b = 'three' where a = 6; +drop table t1; +create table t1(a int not null, b text(110),primary key(a,b(100))) engine=innodb default charset=utf8; +insert into t1 values(1,'abcdefg'),(2,'defghijk'); +insert into t1 values(6,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1); +insert into t1 values(7,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2); +select a,hex(b) from t1 order by b; +update t1 set b = 'three' where a = 6; +drop table t1; # End of 4.1 tests diff --git a/mysql-test/t/insert_select.test b/mysql-test/t/insert_select.test index 6fcdef6ab03..48acdf1cbc5 100644 --- a/mysql-test/t/insert_select.test +++ b/mysql-test/t/insert_select.test @@ -214,4 +214,16 @@ insert into t1(f1) select if(max(f1) is null, '2000',max(f1)+1) from t1; select * from t1; drop table t1; +# +# Bug #13392 values() fails with 'ambiguous' or returns NULL +# with ON DUPLICATE and SELECT +create table t1(x int, y int); +create table t2(x int, z int); +insert into t1(x,y) select x,z from t2 on duplicate key update x=values(x); +--error 1054 +insert into t1(x,y) select x,z from t2 on duplicate key update x=values(z); +--error 1109 +insert into t1(x,y) select x,z from t2 on duplicate key update x=values(t2.x); +drop table t1,t2; + # End of 4.1 tests diff --git a/mysql-test/t/loaddata.test b/mysql-test/t/loaddata.test index 86fbdc62702..e989cb0b2ac 100644 --- a/mysql-test/t/loaddata.test +++ b/mysql-test/t/loaddata.test @@ -31,7 +31,6 @@ load data infile '../../std_data/loaddata4.dat' into table t1 fields terminated select * from t1; drop table t1; - # # Bug #12053 LOAD DATA INFILE ignores NO_AUTO_VALUE_ON_ZERO setting # @@ -57,5 +56,15 @@ enable_query_log; select * from t1; --exec rm $MYSQL_TEST_DIR/var/tmp/t1 SET @@SQL_MODE=@OLD_SQL_MODE; +drop table t1; + +# +# Bug #11203: LOAD DATA does not accept same characters for ESCAPED and +# ENCLOSED +# +create table t1 (a varchar(20), b varchar(20)); +load data infile '../../std_data/loaddata5.dat' into table t1 fields terminated by ',' enclosed by '"' escaped by '"' (a,b); +select * from t1; +drop table t1; # End of 4.1 tests diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test index d384c017611..a723443b395 100644 --- a/mysql-test/t/merge.test +++ b/mysql-test/t/merge.test @@ -350,4 +350,30 @@ INSERT INTO t2 (b) VALUES (1) ON DUPLICATE KEY UPDATE b=3; SELECT b FROM t2; DROP TABLE t1, t2; + +# +# BUG#5390 - problems with merge tables +# Problem #1: INSERT...SELECT +# +#drop table if exists t1, t2, t3; +create table t1(a int); +create table t2(a int); +insert into t1 values (1); +insert into t2 values (2); +create table t3 (a int) engine=merge union=(t1, t2) insert_method=first; +select * from t3; +# +insert t2 select * from t2; +select * from t2; +# +insert t3 select * from t1; +select * from t3; +# +insert t1 select * from t3; +select * from t1; +select * from t2; +select * from t3; +check table t1, t2; +drop table t1, t2, t3; + # End of 4.1 tests diff --git a/mysql-test/t/mix_innodb_myisam_binlog.test b/mysql-test/t/mix_innodb_myisam_binlog.test index 6eb9eae2d99..4581736ac8c 100644 --- a/mysql-test/t/mix_innodb_myisam_binlog.test +++ b/mysql-test/t/mix_innodb_myisam_binlog.test @@ -206,7 +206,35 @@ select (@after:=unix_timestamp())*0; # always give repeatable output # the bug, the reap would return immediately after the insert into t2. select (@after-@before) >= 2; -# cleanup drop table t1,t2; +commit; + +# test for BUG#7947 - DO RELEASE_LOCK() not written to binlog on rollback in the middle +# of a transaction + +connection con2; +begin; +create temporary table ti (a int) engine=innodb; +rollback; +insert into ti values(1); +set autocommit=0; +create temporary table t1 (a int) engine=myisam; +commit; +insert t1 values (1); +rollback; +create table t0 (n int); +insert t0 select * from t1; +set autocommit=1; +insert into t0 select GET_LOCK("lock1",null); +set autocommit=0; +create table t2 (n int) engine=innodb; +insert into t2 values (3); +disconnect con2; +connection con3; +select get_lock("lock1",60); +show binlog events from 79; +do release_lock("lock1"); +drop table t0,t2; + # End of 4.1 tests diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index dc40ecc2dd4..ce40cae3266 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -473,6 +473,18 @@ explain select sql_big_result distinct t1.a from t1,t2 order by t2.a; explain select distinct t1.a from t1,t2 order by t2.a; drop table t1,t2; +# +# Bug#14616 - Freshly imported table returns error 124 when using LIMIT +# +create table t1 ( + c1 varchar(32), + key (c1) +) engine=myisam; +alter table t1 disable keys; +insert into t1 values ('a'), ('b'); +select c1 from t1 order by c1 limit 1; +drop table t1; + # # Test RTREE index # @@ -637,4 +649,41 @@ show index from t1; drop table t1; +# WL#2609, CSC#XXXX: MyISAM +set myisam_stats_method=nulls_ignored; +show variables like 'myisam_stats_method'; + +create table t1 ( + a char(3), b char(4), c char(5), d char(6), + key(a,b,c,d) +); +insert into t1 values ('bcd','def1', NULL, 'zz'); +insert into t1 values ('bcd','def2', NULL, 'zz'); +insert into t1 values ('bce','def1', 'yuu', NULL); +insert into t1 values ('bce','def2', NULL, 'quux'); +analyze table t1; +show index from t1; +delete from t1; +analyze table t1; +show index from t1; + +set myisam_stats_method=DEFAULT; +drop table t1; + +# BUG#13814 - key value packed incorrectly for TINYBLOBs + +create table t1( + cip INT NOT NULL, + time TIME NOT NULL, + score INT NOT NULL DEFAULT 0, + bob TINYBLOB +); + +insert into t1 (cip, time) VALUES (1, '00:01'), (2, '00:02'), (3,'00:03'); +insert into t1 (cip, bob, time) VALUES (4, 'a', '00:04'), (5, 'b', '00:05'), + (6, 'c', '00:06'); +select * from t1 where bob is null and cip=1; +create index bug on t1 (bob(22), cip, time); +select * from t1 where bob is null and cip=1; +drop table t1; # End of 4.1 tests diff --git a/mysql-test/t/mysql_client_test.test b/mysql-test/t/mysql_client_test.test index ccf5e0bf66a..66b57dd5fb7 100644 --- a/mysql-test/t/mysql_client_test.test +++ b/mysql-test/t/mysql_client_test.test @@ -6,7 +6,7 @@ # var/log/mysql_client_test.trace --disable_result_log ---exec echo $MYSQL_CLIENT_TEST ---exec $MYSQL_CLIENT_TEST +--exec echo $MYSQL_CLIENT_TEST --getopt-ll-test=25600M +--exec $MYSQL_CLIENT_TEST --getopt-ll-test=25600M # End of 4.1 tests diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 4978da0bd67..ad1fb534836 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -635,4 +635,16 @@ insert into t2 (a, b) values (NULL, NULL),(10, NULL),(NULL, "twenty"),(30, "thir --exec $MYSQL_DUMP --skip-comments --xml --no-create-info test drop table t1, t2; +# +# BUG #12123 +# +create table t1 (a text character set utf8, b text character set latin1); +insert t1 values (0x4F736E616272C3BC636B, 0x4BF66C6E); +select * from t1; +--exec $MYSQL_DUMP --tab=$MYSQL_TEST_DIR/var/tmp/ test +--exec $MYSQL test < $MYSQL_TEST_DIR/var/tmp/t1.sql +--exec $MYSQL_IMPORT test $MYSQL_TEST_DIR/var/tmp/t1.txt +select * from t1; + +drop table t1; # End of 4.1 tests diff --git a/mysql-test/t/ndb_alter_table.test b/mysql-test/t/ndb_alter_table.test index 5c792f76316..22383a82bca 100644 --- a/mysql-test/t/ndb_alter_table.test +++ b/mysql-test/t/ndb_alter_table.test @@ -138,6 +138,7 @@ INSERT INTO t1 VALUES (1,2,0),(18,19,4),(20,21,0); select c from t1 order by c; drop table t1; +--disable_ps_protocol create table t1 ( a int primary key, b varchar(10), c varchar(10), index (b) ) engine=ndb; insert into t1 values (1,'one','one'), (2,'two','two'), (3,'three','three'); @@ -147,10 +148,13 @@ select * from t1 where b = 'two'; connection server1; alter table t1 drop index c; connection server2; +# This should fail since index information is not automatically refreshed +--error 1015 select * from t1 where b = 'two'; select * from t1 where b = 'two'; connection server1; drop table t1; +--enable_ps_protocol #--disable_warnings #DROP TABLE IF EXISTS t2; diff --git a/mysql-test/t/ndb_basic.test b/mysql-test/t/ndb_basic.test index 144e466d937..c8cf5823500 100644 --- a/mysql-test/t/ndb_basic.test +++ b/mysql-test/t/ndb_basic.test @@ -606,4 +606,12 @@ select * from t1 order by counter; drop table t1; +# +# BUG#14514 Creating table with packed key fails silently +# + +CREATE TABLE t1 ( b INT ) PACK_KEYS = 0 ENGINE = ndb; +select * from t1; +drop table t1; + # End of 4.1 tests diff --git a/mysql-test/t/ndb_charset.test b/mysql-test/t/ndb_charset.test index 89f1ed17cfb..a885427f593 100644 --- a/mysql-test/t/ndb_charset.test +++ b/mysql-test/t/ndb_charset.test @@ -159,14 +159,17 @@ select * from t1 where a = 'AaA' order by p; select * from t1 where a = 'AAA' order by p; drop table t1; -# bug +# bug#14007 create table t1 ( - a varchar(10) primary key -) engine=ndb; -insert into t1 values ('jonas % '); -replace into t1 values ('jonas % '); -replace into t1 values ('jonas % '); + a char(10) primary key +) engine=ndbcluster default charset=latin1; + +insert into t1 values ('aaabb'); +select * from t1; +replace into t1 set a = 'AAABB'; +select * from t1; +replace into t1 set a = 'aAaBb'; +select * from t1; +replace into t1 set a = 'aaabb'; select * from t1; drop table t1; - -# End of 4.1 tests diff --git a/mysql-test/t/ndb_multi.test b/mysql-test/t/ndb_multi.test index 760150c6f6a..1183f2b283f 100644 --- a/mysql-test/t/ndb_multi.test +++ b/mysql-test/t/ndb_multi.test @@ -40,6 +40,7 @@ connection server1; # Currently a retry is required remotely --error 1296 select * from t1; +flush table t1; select * from t1; # Connect to server2 and use the tables from there diff --git a/mysql-test/t/not_embedded_server-master.opt b/mysql-test/t/not_embedded_server-master.opt new file mode 100644 index 00000000000..35fcc5f30c6 --- /dev/null +++ b/mysql-test/t/not_embedded_server-master.opt @@ -0,0 +1 @@ +--loose-to-force-a-restart diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index c4cb0056763..b0755d06414 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -665,19 +665,6 @@ set @b='CHRISTINE'; execute stmt using @a, @b; deallocate prepare stmt; # -# Bug#9442 Set parameter make query fail if column character set is UCS2 -# -create table t1 (utext varchar(20) character set ucs2); -insert into t1 values ("lily"); -insert into t1 values ("river"); -prepare stmt from 'select utext from t1 where utext like ?'; -set @param1='%%'; -execute stmt using @param1; -execute stmt using @param1; -select utext from t1 where utext like '%%'; -drop table t1; -deallocate prepare stmt; -# # Bug#11299 "prepared statement makes wrong SQL syntax in binlog which stops # replication": check that errouneous queries with placeholders are not # allowed @@ -718,4 +705,63 @@ set @@tx_isolation=default; execute stmt; deallocate prepare stmt; +# +# Bug#14410 "Crash in Enum or Set type in CREATE TABLE and PS/SP" +# +# Part I. Make sure the typelib for ENUM is created in the statement memory +# root. +prepare stmt from "create temporary table t1 (letter enum('','a','b','c') +not null)"; +execute stmt; +drop table t1; +execute stmt; +drop table t1; +execute stmt; +drop table t1; +# Part II. Make sure that when the default value is converted to UTF-8, +# the new item is # created in the statement memory root. +set names latin1; +prepare stmt from "create table t1 (a enum('test') default 'test') + character set utf8"; +execute stmt; +drop table t1; +execute stmt; +drop table t1; +execute stmt; +drop table t1; +# Cleanup +set names default; +deallocate prepare stmt; + +# +# A test case for Bug#12734 "prepared statement may return incorrect result +# set for a select SQL request": test that canDoTurboBM is reset for each +# execute of a prepared statement. +# +create table t1 ( + word_id mediumint(8) unsigned not null default '0', + formatted varchar(20) not null default '' +); + +insert into t1 values + (80,'pendant'), (475,'pretendants'), (989,'tendances'), + (1019,'cependant'),(1022,'abondance'),(1205,'independants'), + (13,'lessiver'),(25,'lambiner'),(46,'situer'),(71,'terminer'), + (82,'decrocher'); + +select count(*) from t1 where formatted like '%NDAN%'; +select count(*) from t1 where formatted like '%ER'; +prepare stmt from "select count(*) from t1 where formatted like ?"; +set @like="%NDAN%"; +execute stmt using @like; +set @like="%ER"; +execute stmt using @like; +set @like="%NDAN%"; +execute stmt using @like; +set @like="%ER"; +execute stmt using @like; +deallocate prepare stmt; +drop table t1; + # End of 4.1 tests + diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test index d08dc5fb352..3140739309e 100644 --- a/mysql-test/t/query_cache.test +++ b/mysql-test/t/query_cache.test @@ -712,6 +712,21 @@ show status like "Qcache_inserts"; show status like "Qcache_hits"; drop table t1; +# +# BUG#14652: Queries with leading '(' characters. +# +create table t1 (a int); +flush status; +(select a from t1) union (select a from t1); +show status like "Qcache_queries_in_cache"; +show status like "Qcache_inserts"; +show status like "Qcache_hits"; +(select a from t1) union (select a from t1); +show status like "Qcache_queries_in_cache"; +show status like "Qcache_inserts"; +show status like "Qcache_hits"; +drop table t1; + set GLOBAL query_cache_size=0; # End of 4.1 tests diff --git a/mysql-test/t/rpl_until.test b/mysql-test/t/rpl_until.test index 6fd58252ed4..57ebc67db1d 100644 --- a/mysql-test/t/rpl_until.test +++ b/mysql-test/t/rpl_until.test @@ -29,7 +29,7 @@ sleep 2; # here table should be still not deleted select * from t1; --replace_result $MASTER_MYPORT MASTER_MYPORT ---replace_column 1 # 9 # 23 # 33 # +--replace_column 1 # 9 # 11 # 23 # 33 # show slave status; # this should fail right after start @@ -38,7 +38,7 @@ start slave until master_log_file='master-no-such-bin.000001', master_log_pos=29 select * from t1; sleep 2; --replace_result $MASTER_MYPORT MASTER_MYPORT ---replace_column 1 # 9 # 23 # 33 # +--replace_column 1 # 9 # 11 # 23 # 33 # show slave status; # try replicate all until second insert to t2; @@ -46,7 +46,7 @@ start slave until relay_log_file='slave-relay-bin.000002', relay_log_pos=537; sleep 4; select * from t2; --replace_result $MASTER_MYPORT MASTER_MYPORT ---replace_column 1 # 9 # 23 # 33 # +--replace_column 1 # 9 # 11 # 23 # 33 # show slave status; # clean up diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index 56fab52729e..996d5854854 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -2228,4 +2228,24 @@ SELECT t2.a, t2.b, IF(t1.b IS NULL,'',c) AS c, COUNT(*) AS d FROM t2,t1 WHERE t2.a = t1.a AND t2.b = t1.b GROUP BY a, b, c; DROP TABLE IF EXISTS t1, t2; +# +# Bug #13855 select distinct with group by caused server crash +# +create table t1 (f1 int primary key, f2 int); +create table t2 (f3 int, f4 int, primary key(f3,f4)); +insert into t1 values (1,1); +insert into t2 values (1,1),(1,2); +select distinct count(f2) >0 from t1 left join t2 on f1=f3 group by f1; +drop table t1,t2; + +# +# Bug #14482 Server crash when subselecting from the same table +# +create table t1 (f1 int,f2 int); +insert into t1 values(1,1); +create table t2 (f3 int, f4 int, primary key(f3,f4)); +insert into t2 values(1,1); +select * from t1 where f1 in (select f3 from t2 where (f3,f4)= (select f3,f4 from t2)); +drop table t1,t2; + # End of 4.1 tests diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test index e6a404e3b57..d70903adbc4 100644 --- a/mysql-test/t/show_check.test +++ b/mysql-test/t/show_check.test @@ -378,4 +378,17 @@ create table t1 ( SHOW CREATE TABLE t1; DROP TABLE t1; +# Test for BUG#93: 4.1 protocl crash on corupted frm and SHOW TABLE STATUS + +flush tables; + +# Create a junk frm file on disk +system echo "this is a junk file for test" >> var/master-data/test/t1.frm ; +--replace_column 6 # 7 # 8 # 9 # +SHOW TABLE STATUS like 't1'; +--error 1033 +show create table t1; +drop table t1; + + # End of 4.1 tests diff --git a/mysql-test/t/symlink.test b/mysql-test/t/symlink.test index 85ad04aa556..c0c1db3d553 100644 --- a/mysql-test/t/symlink.test +++ b/mysql-test/t/symlink.test @@ -3,6 +3,8 @@ disable_query_log; show variables like "have_symlink"; enable_query_log; +--source include/not_windows.inc + --disable_warnings drop table if exists t1,t2,t7,t8,t9; drop database if exists mysqltest; diff --git a/mysql-test/t/type_time.test b/mysql-test/t/type_time.test index 7ae3f65f7cc..cb7e4f85ad1 100644 --- a/mysql-test/t/type_time.test +++ b/mysql-test/t/type_time.test @@ -21,4 +21,22 @@ select t, time_to_sec(t),sec_to_time(time_to_sec(t)) from t1; select sec_to_time(time_to_sec(t)) from t1; drop table t1; +# +# BUG #12440: Incorrect processing of time values containing +# long fraction part and/or large exponent part. +# +# These must return normal result: +# ########################################################## +# To be uncommented after fix BUG #15805 +# ########################################################## +# SELECT CAST(235959.123456 AS TIME); +# SELECT CAST(0.235959123456e+6 AS TIME); +# SELECT CAST(235959123456e-6 AS TIME); +# These must cut fraction part and produce warning: +# SELECT CAST(235959.1234567 AS TIME); +# SELECT CAST(0.2359591234567e6 AS TIME); +# This must return NULL and produce warning: +# SELECT CAST(0.2359591234567e+30 AS TIME); +# ########################################################## + # End of 4.1 tests diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index 6a54909536a..1f6fc2c8d3b 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -756,4 +756,22 @@ select 99 union all select id from t1 order by 1; select id from t1 union all select 99 order by 1; drop table t1; +# +# Bug #14216: UNION + DECIMAL wrong values in result +# +create table t1 (f1 decimal(60,25), f2 decimal(60,25)); +insert into t1 values (0.0,0.0); +select f1 from t1 union all select f2 from t1; +select 'XXXXXXXXXXXXXXXXXXXX' as description, f1 from t1 +union all +select 'YYYYYYYYYYYYYYYYYYYY' as description, f2 from t1; +drop table t1; +create table t1 (f1 decimal(60,24), f2 decimal(60,24)); +insert into t1 values (0.0,0.0); +select f1 from t1 union all select f2 from t1; +select 'XXXXXXXXXXXXXXXXXXXX' as description, f1 from t1 +union all +select 'YYYYYYYYYYYYYYYYYYYY' as description, f2 from t1; +drop table t1; + # End of 4.1 tests diff --git a/mysql-test/t/update.test b/mysql-test/t/update.test index 84e9ced2017..95adb40962c 100644 --- a/mysql-test/t/update.test +++ b/mysql-test/t/update.test @@ -227,4 +227,64 @@ select DATABASE(); delete from t1 where count(*)=1; drop table t1; +# BUG#12915: Optimize "DELETE|UPDATE ... ORDER BY ... LIMIT n" to use an index +create table t1 ( a int, b int default 0, index (a) ); +insert into t1 (a) values (0),(0),(0),(0),(0),(0),(0),(0); + +flush status; +select a from t1 order by a limit 1; +show status like 'handler_read%'; + +flush status; +update t1 set a=9999 order by a limit 1; +update t1 set b=9999 order by a limit 1; +show status like 'handler_read%'; + +flush status; +delete from t1 order by a limit 1; +show status like 'handler_read%'; + +flush status; +delete from t1 order by a desc limit 1; +show status like 'handler_read%'; + +alter table t1 disable keys; + +flush status; +delete from t1 order by a limit 1; +show status like 'handler_read%'; + +select * from t1; +update t1 set a=a+10,b=1 order by a limit 3; +update t1 set a=a+11,b=2 order by a limit 3; +update t1 set a=a+12,b=3 order by a limit 3; +select * from t1 order by a; + +drop table t1; + +# +# Bug#14186 select datefield is null not updated +# +create table t1 (f1 date not null); +insert into t1 values('2000-01-01'),('0000-00-00'); +update t1 set f1='2002-02-02' where f1 is null; +select * from t1; +drop table t1; + +# +# Bug#15028 Multitable update returns different numbers of matched rows +# depending on table order +create table t1 (f1 int); +create table t2 (f2 int); +insert into t1 values(1),(2); +insert into t2 values(1),(1); +--enable_info +update t1,t2 set f1=3,f2=3 where f1=f2 and f1=1; +--disable_info +update t2 set f2=1; +update t1 set f1=1 where f1=3; +--enable_info +update t2,t1 set f1=3,f2=3 where f1=f2 and f1=1; +--disable_info +drop table t1,t2; # End of 4.1 tests diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index a8844070207..8322c0f84bd 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -388,7 +388,6 @@ set character_set_results=NULL; select ifnull(@@character_set_results,"really null"); set names latin1; -# End of 4.1 tests # # Bug #9613: @@have_innodb @@ -396,3 +395,12 @@ set names latin1; --replace_column 1 # select @@have_innodb; + +# +# Bug #13334: query_prealloc_size default less than minimum +# +set @test = @@query_prealloc_size; +set @@query_prealloc_size = @test; +select @@query_prealloc_size = @test; + +# End of 4.1 tests diff --git a/mysys/charset.c b/mysys/charset.c index 3a39fce9437..665f2efecd8 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -38,6 +38,22 @@ my_bool my_charset_same(CHARSET_INFO *cs1, CHARSET_INFO *cs2) } +static uint +get_collation_number_internal(const char *name) +{ + CHARSET_INFO **cs; + for (cs= all_charsets; + cs < all_charsets+array_elements(all_charsets)-1 ; + cs++) + { + if ( cs[0] && cs[0]->name && + !my_strcasecmp(&my_charset_latin1, cs[0]->name, name)) + return cs[0]->number; + } + return 0; +} + + static my_bool init_state_maps(CHARSET_INFO *cs) { uint i; @@ -189,7 +205,8 @@ static my_bool simple_cs_is_full(CHARSET_INFO *cs) static int add_collation(CHARSET_INFO *cs) { - if (cs->name && (cs->number || (cs->number=get_collation_number(cs->name)))) + if (cs->name && (cs->number || + (cs->number=get_collation_number_internal(cs->name)))) { if (!all_charsets[cs->number]) { @@ -419,18 +436,8 @@ void free_charsets(void) uint get_collation_number(const char *name) { - CHARSET_INFO **cs; init_available_charsets(MYF(0)); - - for (cs= all_charsets; - cs < all_charsets+array_elements(all_charsets)-1 ; - cs++) - { - if ( cs[0] && cs[0]->name && - !my_strcasecmp(&my_charset_latin1, cs[0]->name, name)) - return cs[0]->number; - } - return 0; /* this mimics find_type() */ + return get_collation_number_internal(name); } diff --git a/mysys/hash.c b/mysys/hash.c index ffebdf76144..75135a470c9 100644 --- a/mysys/hash.c +++ b/mysys/hash.c @@ -36,9 +36,10 @@ typedef struct st_hash_info { static uint hash_mask(uint hashnr,uint buffmax,uint maxlength); static void movelink(HASH_LINK *array,uint pos,uint next_link,uint newlink); -static int hashcmp(HASH *hash,HASH_LINK *pos,const byte *key,uint length); +static int hashcmp(const HASH *hash, HASH_LINK *pos, const byte *key, + uint length); -static uint calc_hash(HASH *hash,const byte *key,uint length) +static uint calc_hash(const HASH *hash, const byte *key, uint length) { ulong nr1=1, nr2=4; hash->charset->coll->hash_sort(hash->charset,(uchar*) key,length,&nr1,&nr2); @@ -63,7 +64,6 @@ _hash_init(HASH *hash,CHARSET_INFO *charset, hash->key_offset=key_offset; hash->key_length=key_length; hash->blength=1; - hash->current_record= NO_RECORD; /* For the future */ hash->get_key=get_key; hash->free=free_element; hash->flags=flags; @@ -135,7 +135,6 @@ void my_hash_reset(HASH *hash) reset_dynamic(&hash->array); /* Set row pointers so that the hash can be reused at once */ hash->blength= 1; - hash->current_record= NO_RECORD; DBUG_VOID_RETURN; } @@ -147,7 +146,8 @@ void my_hash_reset(HASH *hash) */ static inline char* -hash_key(HASH *hash,const byte *record,uint *length,my_bool first) +hash_key(const HASH *hash, const byte *record, uint *length, + my_bool first) { if (hash->get_key) return (*hash->get_key)(record,length,first); @@ -163,8 +163,8 @@ static uint hash_mask(uint hashnr,uint buffmax,uint maxlength) return (hashnr & ((buffmax >> 1) -1)); } -static uint hash_rec_mask(HASH *hash,HASH_LINK *pos,uint buffmax, - uint maxlength) +static uint hash_rec_mask(const HASH *hash, HASH_LINK *pos, + uint buffmax, uint maxlength) { uint length; byte *key= (byte*) hash_key(hash,pos->data,&length,0); @@ -186,14 +186,25 @@ unsigned int rec_hashnr(HASH *hash,const byte *record) } - /* Search after a record based on a key */ - /* Sets info->current_ptr to found record */ +gptr hash_search(const HASH *hash, const byte *key, uint length) +{ + HASH_SEARCH_STATE state; + return hash_first(hash, key, length, &state); +} -gptr hash_search(HASH *hash,const byte *key,uint length) +/* + Search after a record based on a key + + NOTE + Assigns the number of the found record to HASH_SEARCH_STATE state +*/ + +gptr hash_first(const HASH *hash, const byte *key, uint length, + HASH_SEARCH_STATE *current_record) { HASH_LINK *pos; uint flag,idx; - DBUG_ENTER("hash_search"); + DBUG_ENTER("hash_first"); flag=1; if (hash->records) @@ -206,7 +217,7 @@ gptr hash_search(HASH *hash,const byte *key,uint length) if (!hashcmp(hash,pos,key,length)) { DBUG_PRINT("exit",("found key at %d",idx)); - hash->current_record= idx; + *current_record= idx; DBUG_RETURN (pos->data); } if (flag) @@ -218,31 +229,32 @@ gptr hash_search(HASH *hash,const byte *key,uint length) } while ((idx=pos->next) != NO_RECORD); } - hash->current_record= NO_RECORD; + *current_record= NO_RECORD; DBUG_RETURN(0); } /* Get next record with identical key */ /* Can only be called if previous calls was hash_search */ -gptr hash_next(HASH *hash,const byte *key,uint length) +gptr hash_next(const HASH *hash, const byte *key, uint length, + HASH_SEARCH_STATE *current_record) { HASH_LINK *pos; uint idx; - if (hash->current_record != NO_RECORD) + if (*current_record != NO_RECORD) { HASH_LINK *data=dynamic_element(&hash->array,0,HASH_LINK*); - for (idx=data[hash->current_record].next; idx != NO_RECORD ; idx=pos->next) + for (idx=data[*current_record].next; idx != NO_RECORD ; idx=pos->next) { pos=data+idx; if (!hashcmp(hash,pos,key,length)) { - hash->current_record= idx; + *current_record= idx; return pos->data; } } - hash->current_record=NO_RECORD; + *current_record= NO_RECORD; } return 0; } @@ -282,7 +294,8 @@ static void movelink(HASH_LINK *array,uint find,uint next_link,uint newlink) > 0 key of record > key */ -static int hashcmp(HASH *hash,HASH_LINK *pos,const byte *key,uint length) +static int hashcmp(const HASH *hash, HASH_LINK *pos, const byte *key, + uint length) { uint rec_keylength; byte *rec_key= (byte*) hash_key(hash,pos->data,&rec_keylength,1); @@ -308,7 +321,6 @@ my_bool my_hash_insert(HASH *info,const byte *record) if (!(empty=(HASH_LINK*) alloc_dynamic(&info->array))) return(TRUE); /* No more memory */ - info->current_record= NO_RECORD; data=dynamic_element(&info->array,0,HASH_LINK*); halfbuff= info->blength >> 1; @@ -451,7 +463,6 @@ my_bool hash_delete(HASH *hash,byte *record) } if ( --(hash->records) < hash->blength >> 1) hash->blength>>=1; - hash->current_record= NO_RECORD; lastpos=data+hash->records; /* Remove link to record */ @@ -544,7 +555,6 @@ my_bool hash_update(HASH *hash,byte *record,byte *old_key,uint old_key_length) if ((idx=pos->next) == NO_RECORD) DBUG_RETURN(1); /* Not found in links */ } - hash->current_record= NO_RECORD; org_link= *pos; empty=idx; @@ -594,10 +604,10 @@ byte *hash_element(HASH *hash,uint idx) isn't changed */ -void hash_replace(HASH *hash, uint idx, byte *new_row) +void hash_replace(HASH *hash, HASH_SEARCH_STATE *current_record, byte *new_row) { - if (idx != NO_RECORD) /* Safety */ - dynamic_element(&hash->array,idx,HASH_LINK*)->data=new_row; + if (*current_record != NO_RECORD) /* Safety */ + dynamic_element(&hash->array, *current_record, HASH_LINK*)->data= new_row; } diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 53e46932167..dfc3fb3d39c 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -689,10 +689,10 @@ static longlong getopt_ll(char *arg, const struct my_option *optp, int *err) ulonglong block_size= (optp->block_size ? (ulonglong) optp->block_size : 1L); num= eval_num_suffix(arg, err, (char*) optp->name); - if (num > 0 && (ulonglong) num > (ulonglong) (ulong) optp->max_value && + if (num > 0 && (ulonglong) num > (ulonglong) optp->max_value && optp->max_value) /* if max value is not set -> no upper limit */ - num= (longlong) (ulong) optp->max_value; - num= ((num - (longlong) optp->sub_size) / block_size); + num= (ulonglong) optp->max_value; + num= ((num - optp->sub_size) / block_size); num= (longlong) (num * block_size); return max(num, optp->min_value); } diff --git a/mysys/my_handler.c b/mysys/my_handler.c index 5ee181ca78e..3eed0ee6c08 100644 --- a/mysys/my_handler.c +++ b/mysys/my_handler.c @@ -75,7 +75,7 @@ static int compare_bin(uchar *a, uint a_length, uchar *b, uint b_length, SYNOPSIS ha_key_cmp() - keyseg Key segments of key to compare + keyseg Array of key segments of key to compare a First key to compare, in format from _mi_pack_key() This is normally key specified by user b Second key to compare. This is always from a row @@ -84,10 +84,26 @@ static int compare_bin(uchar *a, uint a_length, uchar *b, uint b_length, next_flag How keys should be compared If bit SEARCH_FIND is not set the keys includes the row position and this should also be compared + diff_pos OUT Number of first keypart where values differ, counting + from one. + diff_pos[1] OUT (b + diff_pos[1]) points to first value in tuple b + that is different from corresponding value in tuple a. + + EXAMPLES + Example1: if the function is called for tuples + ('aaa','bbb') and ('eee','fff'), then + diff_pos[0] = 1 (as 'aaa' != 'eee') + diff_pos[1] = 0 (offset from beggining of tuple b to 'eee' keypart). + + Example2: if the index function is called for tuples + ('aaa','bbb') and ('aaa','fff'), + diff_pos[0] = 2 (as 'aaa' != 'eee') + diff_pos[1] = 3 (offset from beggining of tuple b to 'fff' keypart, + here we assume that first key part is CHAR(3) NOT NULL) NOTES Number-keys can't be splited - + RETURN VALUES <0 If a < b 0 If a == b @@ -107,6 +123,7 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, float f_1,f_2; double d_1,d_2; uint next_key_length; + uchar *orig_b= b; *diff_pos=0; for ( ; (int) key_length >0 ; key_length=next_key_length, keyseg++) @@ -114,6 +131,7 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, uchar *end; uint piks=! (keyseg->flag & HA_NO_SORT); (*diff_pos)++; + diff_pos[1]= (uint)(b - orig_b); /* Handle NULL part */ if (keyseg->null_bit) @@ -448,3 +466,84 @@ end: } return 0; } /* ha_key_cmp */ + + +/* + Find the first NULL value in index-suffix values tuple + + SYNOPSIS + ha_find_null() + keyseg Array of keyparts for key suffix + a Key suffix value tuple + + DESCRIPTION + Find the first NULL value in index-suffix values tuple. + TODO Consider optimizing this fuction or its use so we don't search for + NULL values in completely NOT NULL index suffixes. + + RETURN + First key part that has NULL as value in values tuple, or the last key part + (with keyseg->type==HA_TYPE_END) if values tuple doesn't contain NULLs. +*/ + +HA_KEYSEG *ha_find_null(HA_KEYSEG *keyseg, uchar *a) +{ + for (; (enum ha_base_keytype) keyseg->type != HA_KEYTYPE_END; keyseg++) + { + uchar *end; + if (keyseg->null_bit) + { + if (!*a++) + return keyseg; + } + end= a+ keyseg->length; + + switch ((enum ha_base_keytype) keyseg->type) { + case HA_KEYTYPE_TEXT: + case HA_KEYTYPE_BINARY: + if (keyseg->flag & HA_SPACE_PACK) + { + int a_length; + get_key_length(a_length, a); + a += a_length; + break; + } + else + a= end; + break; + case HA_KEYTYPE_VARTEXT: + case HA_KEYTYPE_VARBINARY: + { + int a_length; + get_key_length(a_length, a); + a+= a_length; + break; + } + case HA_KEYTYPE_NUM: + if (keyseg->flag & HA_SPACE_PACK) + { + int alength= *a++; + end= a+alength; + } + a= end; + break; + case HA_KEYTYPE_INT8: + case HA_KEYTYPE_SHORT_INT: + case HA_KEYTYPE_USHORT_INT: + case HA_KEYTYPE_LONG_INT: + case HA_KEYTYPE_ULONG_INT: + case HA_KEYTYPE_INT24: + case HA_KEYTYPE_UINT24: +#ifdef HAVE_LONG_LONG + case HA_KEYTYPE_LONGLONG: + case HA_KEYTYPE_ULONGLONG: +#endif + case HA_KEYTYPE_FLOAT: + case HA_KEYTYPE_DOUBLE: + a= end; + break; + } + } + return keyseg; +} + diff --git a/mysys/my_lib.c b/mysys/my_lib.c index c3b0b57e549..1908c70f407 100644 --- a/mysys/my_lib.c +++ b/mysys/my_lib.c @@ -426,6 +426,18 @@ MY_DIR *my_dir(const char *path, myf MyFlags) do { +#ifdef __BORLANDC__ + attrib= find.ff_attrib; +#else + attrib= find.attrib; + /* + Do not show hidden and system files which Windows sometimes create. + Note. Because Borland's findfirst() is called with the third + argument = 0 hidden/system files are excluded from the search. + */ + if (attrib & (_A_HIDDEN | _A_SYSTEM)) + continue; +#endif #ifdef __BORLANDC__ if (!(finfo.name= strdup_root(names_storage, find.ff_name))) goto error; @@ -442,11 +454,10 @@ MY_DIR *my_dir(const char *path, myf MyFlags) bzero(finfo.mystat, sizeof(MY_STAT)); #ifdef __BORLANDC__ finfo.mystat->st_size=find.ff_fsize; - mode=MY_S_IREAD; attrib=find.ff_attrib; #else finfo.mystat->st_size=find.size; - mode=MY_S_IREAD; attrib=find.attrib; #endif + mode=MY_S_IREAD; if (!(attrib & _A_RDONLY)) mode|=MY_S_IWRITE; if (attrib & _A_SUBDIR) diff --git a/mysys/sha1.c b/mysys/sha1.c index d93b4571baf..110d24f8bfc 100644 --- a/mysys/sha1.c +++ b/mysys/sha1.c @@ -69,7 +69,7 @@ static void SHA1ProcessMessageBlock(SHA1_CONTEXT*); Initialize SHA1Context SYNOPSIS - sha1_reset() + mysql_sha1_reset() context [in/out] The context to reset. DESCRIPTION @@ -92,7 +92,7 @@ const uint32 sha_const_key[5]= }; -int sha1_reset(SHA1_CONTEXT *context) +int mysql_sha1_reset(SHA1_CONTEXT *context) { #ifndef DBUG_OFF if (!context) @@ -119,7 +119,7 @@ int sha1_reset(SHA1_CONTEXT *context) Return the 160-bit message digest into the array provided by the caller SYNOPSIS - sha1_result() + mysql_sha1_result() context [in/out] The context to use to calculate the SHA-1 hash. Message_Digest: [out] Where the digest is returned. @@ -132,8 +132,8 @@ int sha1_reset(SHA1_CONTEXT *context) != SHA_SUCCESS sha Error Code. */ -int sha1_result(SHA1_CONTEXT *context, - uint8 Message_Digest[SHA1_HASH_SIZE]) +int mysql_sha1_result(SHA1_CONTEXT *context, + uint8 Message_Digest[SHA1_HASH_SIZE]) { int i; @@ -165,7 +165,7 @@ int sha1_result(SHA1_CONTEXT *context, Accepts an array of octets as the next portion of the message. SYNOPSIS - sha1_input() + mysql_sha1_input() context [in/out] The SHA context to update message_array An array of characters representing the next portion of the message. @@ -176,8 +176,8 @@ int sha1_result(SHA1_CONTEXT *context, != SHA_SUCCESS sha Error Code. */ -int sha1_input(SHA1_CONTEXT *context, const uint8 *message_array, - unsigned length) +int mysql_sha1_input(SHA1_CONTEXT *context, const uint8 *message_array, + unsigned length) { if (!length) return SHA_SUCCESS; diff --git a/mysys/testhash.c b/mysys/testhash.c index 72badffdbcd..d15016113cd 100644 --- a/mysys/testhash.c +++ b/mysys/testhash.c @@ -74,7 +74,7 @@ static int do_test() bzero((char*) key1,sizeof(key1[0])*1000); printf("- Creating hash\n"); - if (hash_init(&hash,recant/2,0,6,0,free_record,0)) + if (hash_init(&hash, default_charset_info, recant/2, 0, 6, 0, free_record, 0)) goto err; printf("- Writing records:\n"); @@ -172,15 +172,16 @@ static int do_test() break; if (key1[j] > 1) { + HASH_SEARCH_STATE state; printf("- Testing identical read\n"); sprintf(key,"%6d",j); pos=1; - if (!(recpos=hash_search(&hash,key,0))) + if (!(recpos= hash_first(&hash, key, 0, &state))) { printf("can't find key1: \"%s\"\n",key); goto err; } - while (hash_next(&hash,key,0) && pos < (ulong) (key1[j]+10)) + while (hash_next(&hash, key, 0, &state) && pos < (ulong) (key1[j]+10)) pos++; if (pos != (ulong) key1[j]) { @@ -189,7 +190,7 @@ static int do_test() } } printf("- Creating output heap-file 2\n"); - if (hash_init(&hash2,hash.records,0,0,hash2_key,free_record,0)) + if (hash_init(&hash2, default_charset_info, hash.records, 0, 0, hash2_key, free_record,0)) goto err; printf("- Copying and removing records\n"); diff --git a/ndb/docs/Makefile.am b/ndb/docs/Makefile.am index 1399ce3b6a5..9b7ec213e26 100644 --- a/ndb/docs/Makefile.am +++ b/ndb/docs/Makefile.am @@ -1,14 +1,12 @@ DOXYDIR = doxygen noinst_HEADERS = $(DOXYDIR)/predoxy.pl $(DOXYDIR)/postdoxy.pl $(DOXYDIR)/Doxyfile.ndbapi $(DOXYDIR)/Doxyfile.mgmapi $(DOXYDIR)/header.ndbapi.tex $(DOXYDIR)/header.mgmapi.tex -all: do-check ndbapidoc mgmapidoc - DOXYTMP = .doxytmp DOXYOUT = .doxyout NDB_RELEASE = @NDB_VERSION_MAJOR@.@NDB_VERSION_MINOR@.@NDB_VERSION_BUILD@-@NDB_VERSION_STATUS@ -clean: +clean-local: rm -rf ndbapi.pdf ndbapi.html mgmapi.pdf mgmapi.html rm -rf $(DOXYTMP) $(DOXYOUT) diff --git a/ndb/include/kernel/AttributeDescriptor.hpp b/ndb/include/kernel/AttributeDescriptor.hpp index 071d45e2607..9d7de21d904 100644 --- a/ndb/include/kernel/AttributeDescriptor.hpp +++ b/ndb/include/kernel/AttributeDescriptor.hpp @@ -36,6 +36,7 @@ private: static Uint32 getType(const Uint32 &); static Uint32 getSize(const Uint32 &); + static Uint32 getSizeInBytes(const Uint32 &); static Uint32 getSizeInWords(const Uint32 &); static Uint32 getArrayType(const Uint32 &); static Uint32 getArraySize(const Uint32 &); @@ -79,6 +80,7 @@ private: #define AD_SIZE_SHIFT (4) #define AD_SIZE_MASK (7) +#define AD_SIZE_IN_BYTES_SHIFT (3) #define AD_SIZE_IN_WORDS_OFFSET (31) #define AD_SIZE_IN_WORDS_SHIFT (5) @@ -185,6 +187,13 @@ AttributeDescriptor::getSize(const Uint32 & desc){ return (desc >> AD_SIZE_SHIFT) & AD_SIZE_MASK; } +inline +Uint32 +AttributeDescriptor::getSizeInBytes(const Uint32 & desc){ + return (getArraySize(desc) << getSize(desc)) + >> AD_SIZE_IN_BYTES_SHIFT; +} + inline Uint32 AttributeDescriptor::getSizeInWords(const Uint32 & desc){ diff --git a/ndb/include/kernel/signaldata/DumpStateOrd.hpp b/ndb/include/kernel/signaldata/DumpStateOrd.hpp index 7368a0ec40d..4dd22cf5092 100644 --- a/ndb/include/kernel/signaldata/DumpStateOrd.hpp +++ b/ndb/include/kernel/signaldata/DumpStateOrd.hpp @@ -78,6 +78,8 @@ public: LqhDumpAllScanRec = 2301, LqhDumpAllActiveScanRec = 2302, LqhDumpLcpState = 2303, + LqhErrorInsert5042 = 2315, + AccDumpOneScanRec = 2400, AccDumpAllScanRec = 2401, AccDumpAllActiveScanRec = 2402, @@ -98,6 +100,8 @@ public: StartTcTimer = 2509, StopTcTimer = 2510, StartPeriodicTcTimer = 2511, + TcStartDumpIndexOpCount = 2512, + TcDumpIndexOpCount = 2513, CmvmiDumpConnections = 2600, CmvmiDumpLongSignalMemory = 2601, CmvmiSetRestartOnErrorInsert = 2602, diff --git a/ndb/include/logger/LogHandler.hpp b/ndb/include/logger/LogHandler.hpp index 7df6ad864e5..8b9aa43d7a9 100644 --- a/ndb/include/logger/LogHandler.hpp +++ b/ndb/include/logger/LogHandler.hpp @@ -125,6 +125,18 @@ public: */ void setErrorCode(int code); + /** + * Returns the error string. + */ + char* getErrorStr(); + + /** + * Sets the error string. + * + * @param str the error string. + */ + void setErrorStr(char* str); + /** * Parse logstring parameters * @@ -195,6 +207,7 @@ private: const char* m_pDateTimeFormat; int m_errorCode; + char* m_errorStr; // for handling repeated messages unsigned m_count_repeated_messages; diff --git a/ndb/include/logger/Logger.hpp b/ndb/include/logger/Logger.hpp index ee762098fb6..3414468d42d 100644 --- a/ndb/include/logger/Logger.hpp +++ b/ndb/include/logger/Logger.hpp @@ -178,8 +178,11 @@ public: * Add a new handler * * @param logstring string describing the handler to add + * @param err OS errno in event of error + * @param len max length of errStr buffer + * @param errStr logger error string in event of error */ - bool addHandler(const BaseString &logstring); + bool addHandler(const BaseString &logstring, int *err, int len, char* errStr); /** * Remove a log handler. diff --git a/ndb/include/ndb_version.h.in b/ndb/include/ndb_version.h.in index 826f5124407..38b72306d03 100644 --- a/ndb/include/ndb_version.h.in +++ b/ndb/include/ndb_version.h.in @@ -57,5 +57,8 @@ char ndb_version_string_buf[NDB_VERSION_STRING_BUF_SZ]; */ /*#define NDB_VERSION_ID 0*/ +#define NDBD_INCL_NODECONF_VERSION_4 MAKE_VERSION(4,1,17) +#define NDBD_INCL_NODECONF_VERSION_5 MAKE_VERSION(5,0,18) + #endif diff --git a/ndb/src/common/logger/FileLogHandler.cpp b/ndb/src/common/logger/FileLogHandler.cpp index 8678b999b6f..3d29e63ac1f 100644 --- a/ndb/src/common/logger/FileLogHandler.cpp +++ b/ndb/src/common/logger/FileLogHandler.cpp @@ -187,6 +187,7 @@ FileLogHandler::setParam(const BaseString ¶m, const BaseString &value){ return setMaxSize(value); if(param == "maxfiles") return setMaxFiles(value); + setErrorStr("Invalid parameter"); return false; } @@ -196,16 +197,18 @@ FileLogHandler::setFilename(const BaseString &filename) { if(m_pLogFile) delete m_pLogFile; m_pLogFile = new File_class(filename.c_str(), "a+"); - open(); - return true; + return open(); } bool FileLogHandler::setMaxSize(const BaseString &size) { char *end; long val = strtol(size.c_str(), &end, 0); /* XXX */ - if(size.c_str() == end) + if(size.c_str() == end || val < 0) + { + setErrorStr("Invalid file size"); return false; + } if(end[0] == 'M') val *= 1024*1024; if(end[0] == 'k') @@ -220,8 +223,11 @@ bool FileLogHandler::setMaxFiles(const BaseString &files) { char *end; long val = strtol(files.c_str(), &end, 0); - if(files.c_str() == end) + if(files.c_str() == end || val < 1) + { + setErrorStr("Invalid maximum number of files"); return false; + } m_maxNoFiles = val; return true; @@ -230,6 +236,9 @@ FileLogHandler::setMaxFiles(const BaseString &files) { bool FileLogHandler::checkParams() { if(m_pLogFile == NULL) + { + setErrorStr("Log file cannot be null."); return false; + } return true; } diff --git a/ndb/src/common/logger/LogHandler.cpp b/ndb/src/common/logger/LogHandler.cpp index 521bd346fd3..c11f962d4fb 100644 --- a/ndb/src/common/logger/LogHandler.cpp +++ b/ndb/src/common/logger/LogHandler.cpp @@ -23,7 +23,8 @@ // LogHandler::LogHandler() : m_pDateTimeFormat("%d-%.2d-%.2d %.2d:%.2d:%.2d"), - m_errorCode(0) + m_errorCode(0), + m_errorStr(NULL) { m_max_repeat_frequency= 3; // repeat messages maximum every 3 seconds m_count_repeated_messages= 0; @@ -155,6 +156,19 @@ LogHandler::setErrorCode(int code) m_errorCode = code; } + +char* +LogHandler::getErrorStr() +{ + return m_errorStr; +} + +void +LogHandler::setErrorStr(char* str) +{ + m_errorStr= str; +} + bool LogHandler::parseParams(const BaseString &_params) { Vector v_args; @@ -165,9 +179,18 @@ LogHandler::parseParams(const BaseString &_params) { for(size_t i=0; i < v_args.size(); i++) { Vector v_param_value; if(v_args[i].split(v_param_value, "=", 2) != 2) + { ret = false; - else if (!setParam(v_param_value[0], v_param_value[1])) - ret = false; + setErrorStr("Can't find key=value pair."); + } + else + { + v_param_value[0].trim(" \t"); + if (!setParam(v_param_value[0], v_param_value[1])) + { + ret = false; + } + } } if(!checkParams()) diff --git a/ndb/src/common/logger/Logger.cpp b/ndb/src/common/logger/Logger.cpp index 4a48236053d..48e084a782b 100644 --- a/ndb/src/common/logger/Logger.cpp +++ b/ndb/src/common/logger/Logger.cpp @@ -167,7 +167,7 @@ Logger::addHandler(LogHandler* pHandler) } bool -Logger::addHandler(const BaseString &logstring) { +Logger::addHandler(const BaseString &logstring, int *err, int len, char* errStr) { size_t i; Vector logdest; Vectorloghandlers; @@ -200,9 +200,18 @@ Logger::addHandler(const BaseString &logstring) { handler = new ConsoleLogHandler(); if(handler == NULL) + { + snprintf(errStr,len,"Could not create log destination: %s", + logdest[i].c_str()); DBUG_RETURN(false); + } if(!handler->parseParams(params)) + { + *err= handler->getErrorCode(); + if(handler->getErrorStr()) + strncpy(errStr, handler->getErrorStr(), len); DBUG_RETURN(false); + } loghandlers.push_back(handler); } diff --git a/ndb/src/common/logger/SysLogHandler.cpp b/ndb/src/common/logger/SysLogHandler.cpp index 5b1b8d85ca7..c7fcb102dd4 100644 --- a/ndb/src/common/logger/SysLogHandler.cpp +++ b/ndb/src/common/logger/SysLogHandler.cpp @@ -154,5 +154,6 @@ SysLogHandler::setFacility(const BaseString &facility) { return true; } } + setErrorStr("Invalid syslog facility name"); return false; } diff --git a/ndb/src/kernel/blocks/ERROR_codes.txt b/ndb/src/kernel/blocks/ERROR_codes.txt index 791df915d66..62481837c14 100644 --- a/ndb/src/kernel/blocks/ERROR_codes.txt +++ b/ndb/src/kernel/blocks/ERROR_codes.txt @@ -3,7 +3,7 @@ Next NDBCNTR 1000 Next NDBFS 2000 Next DBACC 3002 Next DBTUP 4013 -Next DBLQH 5042 +Next DBLQH 5043 Next DBDICT 6006 Next DBDIH 7174 Next DBTC 8037 @@ -61,6 +61,8 @@ Insert system error in GCP participant when receiving GCP_SAVEREQ. 5007: Delay GCP_SAVEREQ by 10 secs +7165: Delay INCL_NODE_REQ in starting node yeilding error in GCP_PREPARE + ERROR CODES FOR TESTING NODE FAILURE, LOCAL CHECKPOINT HANDLING: ----------------------------------------------------------------- @@ -155,11 +157,15 @@ Insert node failure handling when receiving COMPLETEREQ. 5006: Insert node failure handling when receiving ABORTREQ. +5042: +As 5002, but with specified table (see DumpStateOrd) + These error code can be combined with error codes for testing time-out handling in DBTC to ensure that node failures are also well handled in time-out handling. They can also be used to test multiple node failure handling. + ERROR CODES FOR TESTING TIME-OUT HANDLING IN DBLQH ------------------------------------------------- 5011: @@ -196,6 +202,9 @@ Delay execution of ABORTREQ signal 2 seconds to generate time-out. 8048: Make TC not choose own node for simple/dirty read 5041: Crash is receiving simple read from other TC on different node +5100,5101: Drop ABORT req in primary replica + Crash on "next" ABORT + ERROR CODES FOR TESTING TIME-OUT HANDLING IN DBTC ------------------------------------------------- 8040: @@ -303,6 +312,8 @@ LQH: 5026 Crash when receiving COPY_ACTIVEREQ 5027 Crash when receiving STAT_RECREQ +5042 Crash starting node, when scan is finished on primary replica + Test Crashes in handling take over ---------------------------------- diff --git a/ndb/src/kernel/blocks/backup/Backup.cpp b/ndb/src/kernel/blocks/backup/Backup.cpp index 56af24c5cf0..f61f01d680b 100644 --- a/ndb/src/kernel/blocks/backup/Backup.cpp +++ b/ndb/src/kernel/blocks/backup/Backup.cpp @@ -786,13 +786,17 @@ Backup::checkNodeFail(Signal* signal, pos= &ref->nodeId - signal->getDataPtr(); break; } + case GSN_WAIT_GCP_REQ: + case GSN_DROP_TRIG_REQ: case GSN_CREATE_TRIG_REQ: case GSN_ALTER_TRIG_REQ: - case GSN_WAIT_GCP_REQ: + ptr.p->setErrorCode(AbortBackupOrd::BackupFailureDueToNodeFail); + return; case GSN_UTIL_SEQUENCE_REQ: case GSN_UTIL_LOCK_REQ: - case GSN_DROP_TRIG_REQ: return; + default: + ndbrequire(false); } for(Uint32 i = 0; (i = mask.find(i+1)) != NdbNodeBitmask::NotFound; ) @@ -1803,7 +1807,7 @@ Backup::execBACKUP_FRAGMENT_CONF(Signal* signal) const Uint32 nodeId = refToNode(signal->senderBlockRef()); const Uint32 noOfBytes = conf->noOfBytes; const Uint32 noOfRecords = conf->noOfRecords; - + BackupRecordPtr ptr; c_backupPool.getPtr(ptr, ptrI); @@ -1880,7 +1884,7 @@ Backup::execBACKUP_FRAGMENT_REF(Signal* signal) } } } - ndbrequire(false); + goto err; done: ptr.p->masterData.sendCounter--; @@ -1892,7 +1896,8 @@ done: masterAbort(signal, ptr); return; }//if - + +err: AbortBackupOrd *ord = (AbortBackupOrd*)signal->getDataPtrSend(); ord->backupId = ptr.p->backupId; ord->backupPtr = ptr.i; @@ -3769,7 +3774,7 @@ Backup::checkFile(Signal* signal, BackupFilePtr filePtr) req->userReference = reference(); req->varIndex = 0; req->offset = tmp - c_startOfPages; - req->size = sz; // Avrunda uppot + req->size = sz; // Round up sendSignal(NDBFS_REF, GSN_FSAPPENDREQ, signal, FsAppendReq::SignalLength, JBA); diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp index 5bd35812b47..6564963f61a 100644 --- a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp +++ b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp @@ -11694,7 +11694,6 @@ Dbdict::alterTrigger_toDropLocal(Signal* signal, OpAlterTriggerPtr opPtr) // broken trigger allowed if force if (! (triggerPtr.p->triggerLocal & TriggerRecord::TL_CREATED_LQH)) { jam(); - ndbrequire(opPtr.p->m_requestFlag & RequestFlag::RF_FORCE); alterTrigger_sendReply(signal, opPtr, false); return; } diff --git a/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp index ca066b588e7..6bb499eff18 100644 --- a/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp +++ b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp @@ -215,7 +215,7 @@ void Dbdih::sendINCL_NODEREQ(Signal* signal, Uint32 nodeId) signal->theData[2] = c_nodeStartMaster.failNr; signal->theData[3] = 0; signal->theData[4] = currentgcp; - sendSignal(nodeDihRef, GSN_INCL_NODEREQ, signal, 5, JBB); + sendSignal(nodeDihRef, GSN_INCL_NODEREQ, signal, 5, JBA); }//Dbdih::sendINCL_NODEREQ() void Dbdih::sendMASTER_GCPREQ(Signal* signal, Uint32 nodeId) @@ -1857,6 +1857,14 @@ void Dbdih::gcpBlockedLab(Signal* signal) // global checkpoint id and the correct state. We do not wait for any reply // since the starting node will not send any. /*-------------------------------------------------------------------------*/ + Uint32 startVersion = getNodeInfo(c_nodeStartMaster.startNode).m_version; + + if ((getMajor(startVersion) == 4 && startVersion >= NDBD_INCL_NODECONF_VERSION_4) || + (getMajor(startVersion) == 5 && startVersion >= NDBD_INCL_NODECONF_VERSION_5)) + { + c_INCL_NODEREQ_Counter.setWaitingFor(c_nodeStartMaster.startNode); + } + sendINCL_NODEREQ(signal, c_nodeStartMaster.startNode); }//Dbdih::gcpBlockedLab() @@ -2059,6 +2067,13 @@ void Dbdih::execINCL_NODEREQ(Signal* signal) jamEntry(); Uint32 retRef = signal->theData[0]; Uint32 nodeId = signal->theData[1]; + if (nodeId == getOwnNodeId() && ERROR_INSERTED(7165)) + { + CLEAR_ERROR_INSERT_VALUE; + sendSignalWithDelay(reference(), GSN_INCL_NODEREQ, signal, 5000, signal->getLength()); + return; + } + Uint32 tnodeStartFailNr = signal->theData[2]; currentgcp = signal->theData[4]; CRASH_INSERTION(7127); @@ -2086,6 +2101,15 @@ void Dbdih::execINCL_NODEREQ(Signal* signal) // id's and the lcp status. /*-----------------------------------------------------------------------*/ CRASH_INSERTION(7171); + Uint32 masterVersion = getNodeInfo(refToNode(cmasterdihref)).m_version; + + if ((NDB_VERSION_MAJOR == 4 && masterVersion >= NDBD_INCL_NODECONF_VERSION_4) || + (NDB_VERSION_MAJOR == 5 && masterVersion >= NDBD_INCL_NODECONF_VERSION_5)) + { + signal->theData[0] = getOwnNodeId(); + signal->theData[1] = getOwnNodeId(); + sendSignal(cmasterdihref, GSN_INCL_NODECONF, signal, 2, JBB); + } return; }//if if (getNodeStatus(nodeId) != NodeRecord::STARTING) { @@ -3737,8 +3761,16 @@ void Dbdih::execNODE_FAILREP(Signal* signal) /*------------------------------------------------------------------------*/ // Verify that a starting node has also crashed. Reset the node start record. /*-------------------------------------------------------------------------*/ - if (c_nodeStartMaster.startNode != RNIL) { - ndbrequire(getNodeStatus(c_nodeStartMaster.startNode)!= NodeRecord::ALIVE); + if (false && c_nodeStartMaster.startNode != RNIL && getNodeStatus(c_nodeStartMaster.startNode) == NodeRecord::ALIVE) + { + BlockReference cntrRef = calcNdbCntrBlockRef(c_nodeStartMaster.startNode); + SystemError * const sysErr = (SystemError*)&signal->theData[0]; + sysErr->errorCode = SystemError::StartInProgressError; + sysErr->errorRef = reference(); + sysErr->data1= 0; + sysErr->data2= __LINE__; + sendSignal(cntrRef, GSN_SYSTEM_ERROR, signal, SystemError::SignalLength, JBA); + nodeResetStart(); }//if /*--------------------------------------------------*/ @@ -5187,15 +5219,16 @@ void Dbdih::removeNodeFromTable(Signal* signal, /** * For each of replica record */ - Uint32 replicaNo = 0; + bool found = false; ReplicaRecordPtr replicaPtr; for(replicaPtr.i = fragPtr.p->storedReplicas; replicaPtr.i != RNIL; - replicaPtr.i = replicaPtr.p->nextReplica, replicaNo++) { + replicaPtr.i = replicaPtr.p->nextReplica) { jam(); ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord); if(replicaPtr.p->procNode == nodeId){ jam(); + found = true; noOfRemovedReplicas++; removeNodeFromStored(nodeId, fragPtr, replicaPtr); if(replicaPtr.p->lcpOngoingFlag){ @@ -5211,6 +5244,15 @@ void Dbdih::removeNodeFromTable(Signal* signal, } } } + if (!found) + { + jam(); + /** + * Run updateNodeInfo to remove any dead nodes from list of activeNodes + * see bug#15587 + */ + updateNodeInfo(fragPtr); + } noOfRemainingLcpReplicas += fragPtr.p->noLcpReplicas; } @@ -10976,7 +11018,11 @@ void Dbdih::initCommonData() cnoReplicas = 1; ndb_mgm_get_int_parameter(p, CFG_DB_NO_REPLICAS, &cnoReplicas); - cnoReplicas = cnoReplicas > 4 ? 4 : cnoReplicas; + if (cnoReplicas > 4) + { + progError(__LINE__, ERR_INVALID_CONFIG, + "Only up to four replicas are supported. Check NoOfReplicas."); + } cgcpDelay = 2000; ndb_mgm_get_int_parameter(p, CFG_DB_GCP_INTERVAL, &cgcpDelay); @@ -11568,14 +11614,14 @@ void Dbdih::execCHECKNODEGROUPSREQ(Signal* signal) break; case CheckNodeGroups::GetNodeGroupMembers: { ok = true; - Uint32 ownNodeGoup = + Uint32 ownNodeGroup = Sysfile::getNodeGroup(sd->nodeId, SYSFILE->nodeGroups); - sd->output = ownNodeGoup; + sd->output = ownNodeGroup; sd->mask.clear(); NodeGroupRecordPtr ngPtr; - ngPtr.i = ownNodeGoup; + ngPtr.i = ownNodeGroup; ptrAss(ngPtr, nodeGroupRecord); for (Uint32 j = 0; j < ngPtr.p->nodeCount; j++) { jam(); @@ -11583,7 +11629,7 @@ void Dbdih::execCHECKNODEGROUPSREQ(Signal* signal) } #if 0 for (int i = 0; i < MAX_NDB_NODES; i++) { - if (ownNodeGoup == + if (ownNodeGroup == Sysfile::getNodeGroup(i, SYSFILE->nodeGroups)) { sd->mask.set(i); } diff --git a/ndb/src/kernel/blocks/dblqh/Dblqh.hpp b/ndb/src/kernel/blocks/dblqh/Dblqh.hpp index 951d1e90251..13ae5aa1bbf 100644 --- a/ndb/src/kernel/blocks/dblqh/Dblqh.hpp +++ b/ndb/src/kernel/blocks/dblqh/Dblqh.hpp @@ -2881,6 +2881,7 @@ private: UintR ctransidHash[1024]; Uint32 c_diskless; + Uint32 c_error_insert_table_id; public: /** diff --git a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp index b6178227d31..06c783016ac 100644 --- a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp +++ b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp @@ -3532,6 +3532,7 @@ void Dblqh::execLQHKEYREQ(Signal* signal) jam(); regTcPtr->activeCreat = ZTRUE; CRASH_INSERTION(5002); + CRASH_INSERTION2(5042, tabptr.i == c_error_insert_table_id); } else { regTcPtr->activeCreat = ZFALSE; }//if @@ -5869,12 +5870,21 @@ void Dblqh::execABORT(Signal* signal) warningReport(signal, 8); return; }//if + + TcConnectionrec * const regTcPtr = tcConnectptr.p; + + if (ERROR_INSERTED(5100)) + { + SET_ERROR_INSERT_VALUE(5101); + return; + } + CRASH_INSERTION2(5101, regTcPtr->nextReplica != ZNIL); + /* ------------------------------------------------------------------------- */ /*A GUIDING DESIGN PRINCIPLE IN HANDLING THESE ERROR SITUATIONS HAVE BEEN */ /*KEEP IT SIMPLE. THUS WE RATHER INSERT A WAIT AND SET THE ABORT_STATE TO */ /*ACTIVE RATHER THAN WRITE NEW CODE TO HANDLE EVERY SPECIAL SITUATION. */ /* ------------------------------------------------------------------------- */ - TcConnectionrec * const regTcPtr = tcConnectptr.p; if (regTcPtr->nextReplica != ZNIL) { /* ------------------------------------------------------------------------- */ // We will immediately send the ABORT message also to the next LQH node in line. @@ -9210,6 +9220,15 @@ void Dblqh::nextScanConfCopyLab(Signal* signal) // completion. Signal completion through scanCompletedStatus-flag. /*---------------------------------------------------------------------------*/ scanptr.p->scanCompletedStatus = ZTRUE; + scanptr.p->scanState = ScanRecord::WAIT_LQHKEY_COPY; + if (ERROR_INSERTED(5042)) + { + CLEAR_ERROR_INSERT_VALUE; + tcConnectptr.p->copyCountWords = ~0; + signal->theData[0] = 9999; + sendSignal(numberToRef(CMVMI, scanptr.p->scanNodeId), + GSN_NDB_TAMPER, signal, 1, JBA); + } return; }//if @@ -18402,8 +18421,12 @@ Dblqh::execDUMP_STATE_ORD(Signal* signal) return; } - - + if (dumpState->args[0] == DumpStateOrd::LqhErrorInsert5042 && signal->getLength() == 2) + { + c_error_insert_table_id = dumpState->args[1]; + SET_ERROR_INSERT_VALUE(5042); + } + }//Dblqh::execDUMP_STATE_ORD() void Dblqh::execSET_VAR_REQ(Signal* signal) @@ -18444,60 +18467,54 @@ void Dblqh::execCREATE_TRIG_REQ(Signal* signal) { jamEntry(); - NodeId myNodeId = getOwnNodeId(); - BlockReference tupref = calcTupBlockRef(myNodeId); - sendSignal(tupref, GSN_CREATE_TRIG_REQ, signal, CreateTrigReq::SignalLength, JBB); + sendSignal(DBTUP_REF, GSN_CREATE_TRIG_REQ, signal, + CreateTrigReq::SignalLength, JBB); } void Dblqh::execCREATE_TRIG_CONF(Signal* signal) { jamEntry(); - NodeId myNodeId = getOwnNodeId(); - BlockReference dictref = calcDictBlockRef(myNodeId); - sendSignal(dictref, GSN_CREATE_TRIG_CONF, signal, CreateTrigConf::SignalLength, JBB); + sendSignal(DBDICT_REF, GSN_CREATE_TRIG_CONF, signal, + CreateTrigConf::SignalLength, JBB); } void Dblqh::execCREATE_TRIG_REF(Signal* signal) { jamEntry(); - NodeId myNodeId = getOwnNodeId(); - BlockReference dictref = calcDictBlockRef(myNodeId); - sendSignal(dictref, GSN_CREATE_TRIG_REF, signal, CreateTrigRef::SignalLength, JBB); + sendSignal(DBDICT_REF, GSN_CREATE_TRIG_REF, signal, + CreateTrigRef::SignalLength, JBB); } void Dblqh::execDROP_TRIG_REQ(Signal* signal) { jamEntry(); - NodeId myNodeId = getOwnNodeId(); - BlockReference tupref = calcTupBlockRef(myNodeId); - sendSignal(tupref, GSN_DROP_TRIG_REQ, signal, DropTrigReq::SignalLength, JBB); + sendSignal(DBTUP_REF, GSN_DROP_TRIG_REQ, signal, + DropTrigReq::SignalLength, JBB); } void Dblqh::execDROP_TRIG_CONF(Signal* signal) { jamEntry(); - NodeId myNodeId = getOwnNodeId(); - BlockReference dictref = calcDictBlockRef(myNodeId); - sendSignal(dictref, GSN_DROP_TRIG_CONF, signal, DropTrigConf::SignalLength, JBB); + sendSignal(DBDICT_REF, GSN_DROP_TRIG_CONF, signal, + DropTrigConf::SignalLength, JBB); } void Dblqh::execDROP_TRIG_REF(Signal* signal) { jamEntry(); - NodeId myNodeId = getOwnNodeId(); - BlockReference dictref = calcDictBlockRef(myNodeId); - sendSignal(dictref, GSN_DROP_TRIG_REF, signal, DropTrigRef::SignalLength, JBB); + sendSignal(DBDICT_REF, GSN_DROP_TRIG_REF, signal, + DropTrigRef::SignalLength, JBB); } Uint32 Dblqh::calcPageCheckSum(LogPageRecordPtr logP){ diff --git a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp index 04b40dafcb5..d9d1f01b213 100644 --- a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp +++ b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp @@ -4607,6 +4607,7 @@ void Dbtc::copyApi(Signal* signal) regTmpApiPtr->commitAckMarker = RNIL; regTmpApiPtr->firstTcConnect = RNIL; regTmpApiPtr->lastTcConnect = RNIL; + releaseAllSeizedIndexOperations(regTmpApiPtr); }//Dbtc::copyApi() void Dbtc::unlinkApiConnect(Signal* signal) @@ -6128,7 +6129,6 @@ void Dbtc::timeOutFoundLab(Signal* signal, Uint32 TapiConPtr) << " - place: " << c_apiConTimer_line[apiConnectptr.i]); switch (apiConnectptr.p->apiConnectstate) { case CS_STARTED: - ndbrequire(c_apiConTimer_line[apiConnectptr.i] != 3615); if(apiConnectptr.p->lqhkeyreqrec == apiConnectptr.p->lqhkeyconfrec){ jam(); /* @@ -6388,8 +6388,8 @@ void Dbtc::sendAbortedAfterTimeout(Signal* signal, int Tcheck) warningEvent(buf); ndbout_c(buf); ndbrequire(false); + releaseAbortResources(signal); } - releaseAbortResources(signal); return; }//if TloopCount++; @@ -10134,7 +10134,7 @@ void Dbtc::releaseAbortResources(Signal* signal) // apiConnectptr.p->apiConnectstate = CS_CONNECTED; apiConnectptr.p->apiConnectstate = CS_ABORTING; apiConnectptr.p->abortState = AS_IDLE; - + releaseAllSeizedIndexOperations(apiConnectptr.p); if(apiConnectptr.p->m_exec_flag || apiConnectptr.p->apiFailState == ZTRUE){ jam(); bool ok = false; @@ -10707,6 +10707,33 @@ Dbtc::execDUMP_STATE_ORD(Signal* signal) signal->theData[0] = TcContinueB::ZTRANS_EVENT_REP; sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 5000, 1); } + + if (dumpState->args[0] == DumpStateOrd::TcStartDumpIndexOpCount) + { + static int frequency = 1; + if (signal->getLength() > 1) + frequency = signal->theData[1]; + else + if (refToBlock(signal->getSendersBlockRef()) != DBTC) + frequency = 1; + + if (frequency) + { + dumpState->args[0] = DumpStateOrd::TcDumpIndexOpCount; + execDUMP_STATE_ORD(signal); + dumpState->args[0] = DumpStateOrd::TcStartDumpIndexOpCount; + + Uint32 delay = 1000 * (frequency > 25 ? 25 : frequency); + sendSignalWithDelay(cownref, GSN_DUMP_STATE_ORD, signal, delay, 1); + } + } + + if (dumpState->args[0] == DumpStateOrd::TcDumpIndexOpCount) + { + infoEvent("IndexOpCount: pool: %d free: %d", + c_theIndexOperationPool.getSize(), + c_theIndexOperationPool.getNoOfFree()); + } }//Dbtc::execDUMP_STATE_ORD() void Dbtc::execSET_VAR_REQ(Signal* signal) diff --git a/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp b/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp index 470b98fd04c..e16d3df6d8d 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp @@ -445,6 +445,7 @@ Dbtup::commitRecord(Signal* signal, befOpPtr.p->changeMask.bitOR(attributeMask); befOpPtr.p->gci = regOperPtr->gci; + befOpPtr.p->optype = opType; operPtr.p = befOpPtr.p; checkDetachedTriggers(signal, befOpPtr.p, @@ -483,6 +484,7 @@ Dbtup::commitRecord(Signal* signal, befOpPtr.p->pageIndex = befOpPtr.p->pageIndexC; befOpPtr.p->gci = regOperPtr->gci; + befOpPtr.p->optype = opType; operPtr.p = befOpPtr.p; checkDetachedTriggers(signal, befOpPtr.p, diff --git a/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp b/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp index cbb165c3eb1..7b642f90a17 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp @@ -700,6 +700,27 @@ Dbtup::checkUpdateOfPrimaryKey(Uint32* updateBuffer, Tablerec* const regTabPtr) Uint32 attrDescriptorIndex = regTabPtr->tabDescriptor + (attributeId << ZAD_LOG_SIZE); Uint32 attrDescriptor = tableDescriptor[attrDescriptorIndex].tabDescr; Uint32 attributeOffset = tableDescriptor[attrDescriptorIndex + 1].tabDescr; + + Uint32 xfrmBuffer[1 + MAX_KEY_SIZE_IN_WORDS * 1]; // strxfrm_multiply == 1 + Uint32 charsetFlag = AttributeOffset::getCharsetFlag(attributeOffset); + if (charsetFlag) { + Uint32 csPos = AttributeOffset::getCharsetPos(attributeOffset); + CHARSET_INFO* cs = regTabPtr->charsetArray[csPos]; + Uint32 sizeInBytes = AttributeDescriptor::getSizeInBytes(attrDescriptor); + Uint32 sizeInWords = AttributeDescriptor::getSizeInWords(attrDescriptor); + const uchar* srcPtr = (uchar*)&updateBuffer[1]; + uchar* dstPtr = (uchar*)&xfrmBuffer[1]; + Uint32 n = + (*cs->coll->strnxfrm)(cs, dstPtr, sizeInBytes, srcPtr, sizeInBytes); + // pad with blanks (unlikely) and zeroes to match NDB API behaviour + while (n < sizeInBytes) + dstPtr[n++] = 0x20; + while (n < 4 * sizeInWords) + dstPtr[n++] = 0; + xfrmBuffer[0] = ahIn.m_value; + updateBuffer = xfrmBuffer; + } + ReadFunction f = regTabPtr->readFunctionArray[attributeId]; AttributeHeader::init(&attributeHeader, attributeId, 0); @@ -707,7 +728,7 @@ Dbtup::checkUpdateOfPrimaryKey(Uint32* updateBuffer, Tablerec* const regTabPtr) tMaxRead = MAX_KEY_SIZE_IN_WORDS; bool tmp = tXfrmFlag; - tXfrmFlag = false; + tXfrmFlag = true; ndbrequire((this->*f)(&keyReadBuffer[0], ahOut, attrDescriptor, attributeOffset)); tXfrmFlag = tmp; ndbrequire(tOutBufIndex == ahOut->getDataSize()); diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp index 3ee0dc6e750..47d156c1f9e 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.cpp +++ b/ndb/src/mgmsrv/MgmtSrvr.cpp @@ -179,6 +179,8 @@ MgmtSrvr::startEventLog() } const char * tmp; + char errStr[100]; + int err= 0; BaseString logdest; char *clusterLog= NdbConfig_ClusterLogFileName(_ownNodeId); NdbAutoPtr tmp_aptr(clusterLog); @@ -192,9 +194,17 @@ MgmtSrvr::startEventLog() logdest.assfmt("FILE:filename=%s,maxsize=1000000,maxfiles=6", clusterLog); } - if(!g_eventLogger.addHandler(logdest)) { + errStr[0]='\0'; + if(!g_eventLogger.addHandler(logdest, &err, sizeof(errStr), errStr)) { ndbout << "Warning: could not add log destination \"" - << logdest.c_str() << "\"" << endl; + << logdest.c_str() << "\". Reason: "; + if(err) + ndbout << strerror(err); + if(err && errStr[0]!='\0') + ndbout << ", "; + if(errStr[0]!='\0') + ndbout << errStr; + ndbout << endl; } } diff --git a/ndb/src/ndbapi/NdbImpl.hpp b/ndb/src/ndbapi/NdbImpl.hpp index 33aaca8de96..aa918a6f9f8 100644 --- a/ndb/src/ndbapi/NdbImpl.hpp +++ b/ndb/src/ndbapi/NdbImpl.hpp @@ -78,11 +78,9 @@ public: /** * NOTE free lists must be _after_ theNdbObjectIdMap take * assure that destructors are run in correct order + * NOTE these has to be in this specific order to make destructor run in + * correct order */ - Ndb_free_list_t theConIdleList; - Ndb_free_list_t theOpIdleList; - Ndb_free_list_t theScanOpIdleList; - Ndb_free_list_t theIndexOpIdleList; Ndb_free_list_t theRecAttrIdleList; Ndb_free_list_t theSignalIdleList; Ndb_free_list_t theLabelList; @@ -91,6 +89,10 @@ public: Ndb_free_list_t theCallList; Ndb_free_list_t theNdbBlobIdleList; Ndb_free_list_t theScanList; + Ndb_free_list_t theScanOpIdleList; + Ndb_free_list_t theOpIdleList; + Ndb_free_list_t theIndexOpIdleList; + Ndb_free_list_t theConIdleList; }; #ifdef VM_TRACE diff --git a/ndb/src/ndbapi/NdbRecAttr.cpp b/ndb/src/ndbapi/NdbRecAttr.cpp index f993c652bf9..26039fb7867 100644 --- a/ndb/src/ndbapi/NdbRecAttr.cpp +++ b/ndb/src/ndbapi/NdbRecAttr.cpp @@ -35,6 +35,7 @@ Adjust: 971206 UABRONM First version NdbRecAttr::NdbRecAttr(Ndb*) { + theStorageX = 0; init(); } @@ -64,6 +65,9 @@ NdbRecAttr::setup(const NdbColumnImpl* anAttrInfo, char* aValue) theNULLind = 0; m_nullable = anAttrInfo->m_nullable; + if (theStorageX) + delete[] theStorageX; + // check alignment to signal data // a future version could check alignment per data type as well diff --git a/ndb/src/ndbapi/ndb_cluster_connection.cpp b/ndb/src/ndbapi/ndb_cluster_connection.cpp index 4fcf4d08396..a313a973a42 100644 --- a/ndb/src/ndbapi/ndb_cluster_connection.cpp +++ b/ndb/src/ndbapi/ndb_cluster_connection.cpp @@ -308,6 +308,19 @@ Ndb_cluster_connection_impl::~Ndb_cluster_connection_impl() // fragmentToNodeMap.release(); + if (ndb_global_event_buffer_mutex != NULL) + { + NdbMutex_Destroy(ndb_global_event_buffer_mutex); + ndb_global_event_buffer_mutex= NULL; + } +#ifdef VM_TRACE + if (ndb_print_state_mutex != NULL) + { + NdbMutex_Destroy(ndb_print_state_mutex); + ndb_print_state_mutex= NULL; + } +#endif + DBUG_VOID_RETURN; } diff --git a/ndb/test/ndbapi/testDataBuffers.cpp b/ndb/test/ndbapi/testDataBuffers.cpp index 03d52252334..27e241fa87a 100644 --- a/ndb/test/ndbapi/testDataBuffers.cpp +++ b/ndb/test/ndbapi/testDataBuffers.cpp @@ -254,12 +254,6 @@ testcase(int flag) ndbout << "tab=" << tab << " cols=" << attrcnt << " size max=" << smax << " tot=" << stot << endl; - ndb = new Ndb("TEST_DB"); - if (ndb->init() != 0) - return ndberror("init"); - if (ndb->waitUntilReady(30) < 0) - return ndberror("waitUntilReady"); - if ((tcon = NdbSchemaCon::startSchemaTrans(ndb)) == 0) return ndberror("startSchemaTransaction"); if ((top = tcon->getNdbSchemaOp()) == 0) @@ -541,7 +535,6 @@ testcase(int flag) return ndberror("key %d not found", k); ndbout << "scanned " << key << endl; - ndb = 0; ndbout << "done" << endl; return 0; } @@ -605,7 +598,23 @@ NDB_COMMAND(testDataBuffers, "testDataBuffers", "testDataBuffers", "testDataBuff return NDBT_ProgramExit(NDBT_WRONGARGS); } } + unsigned ok = true; + + ndb = new Ndb("TEST_DB"); + if (ndb->init() != 0) + { + ndberror("init"); + ok = false; + goto out; + } + if (ndb->waitUntilReady(30) < 0) + { + ndberror("waitUntilReady"); + ok = false; + goto out; + } + for (i = 1; 0 == loopcnt || i <= loopcnt; i++) { ndbout << "=== loop " << i << " ===" << endl; for (int flag = 0; flag < (1<getDictionary(); + dict->dropTable(tab); } } + out: + delete ndb; return NDBT_ProgramExit(ok ? NDBT_OK : NDBT_FAILED); } diff --git a/ndb/test/ndbapi/testNodeRestart.cpp b/ndb/test/ndbapi/testNodeRestart.cpp index 9c25d715d07..a741e6233d9 100644 --- a/ndb/test/ndbapi/testNodeRestart.cpp +++ b/ndb/test/ndbapi/testNodeRestart.cpp @@ -21,6 +21,7 @@ #include #include #include +#include int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ @@ -409,6 +410,132 @@ int runLateCommit(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_OK; } +int runBug15587(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + int loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + NdbRestarter restarter; + + Uint32 tableId = ctx->getTab()->getTableId(); + int dump[2] = { DumpStateOrd::LqhErrorInsert5042, 0 }; + dump[1] = tableId; + + int nodeId = restarter.getDbNodeId(1); + + ndbout << "Restart node " << nodeId << endl; + + if (restarter.restartOneDbNode(nodeId, + /** initial */ false, + /** nostart */ true, + /** abort */ true)) + return NDBT_FAILED; + + if (restarter.waitNodesNoStart(&nodeId, 1)) + return NDBT_FAILED; + + if (restarter.dumpStateOneNode(nodeId, dump, 2)) + return NDBT_FAILED; + + if (restarter.startNodes(&nodeId, 1)) + return NDBT_FAILED; + + if (restarter.waitNodesStarted(&nodeId, 1)) + return NDBT_FAILED; + + ctx->stopTest(); + return NDBT_OK; +} + +int runBug15632(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + int loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + NdbRestarter restarter; + + int nodeId = restarter.getDbNodeId(1); + + ndbout << "Restart node " << nodeId << endl; + + if (restarter.restartOneDbNode(nodeId, + /** initial */ false, + /** nostart */ true, + /** abort */ true)) + return NDBT_FAILED; + + if (restarter.waitNodesNoStart(&nodeId, 1)) + return NDBT_FAILED; + + if (restarter.insertErrorInNode(nodeId, 7165)) + return NDBT_FAILED; + + if (restarter.startNodes(&nodeId, 1)) + return NDBT_FAILED; + + if (restarter.waitNodesStarted(&nodeId, 1)) + return NDBT_FAILED; + + if (restarter.restartOneDbNode(nodeId, + /** initial */ false, + /** nostart */ true, + /** abort */ true)) + return NDBT_FAILED; + + if (restarter.waitNodesNoStart(&nodeId, 1)) + return NDBT_FAILED; + + if (restarter.insertErrorInNode(nodeId, 7171)) + return NDBT_FAILED; + + if (restarter.startNodes(&nodeId, 1)) + return NDBT_FAILED; + + if (restarter.waitNodesStarted(&nodeId, 1)) + return NDBT_FAILED; + + ctx->stopTest(); + return NDBT_OK; +} + +int runBug15685(NDBT_Context* ctx, NDBT_Step* step){ + + Ndb* pNdb = GETNDB(step); + HugoOperations hugoOps(*ctx->getTab()); + NdbRestarter restarter; + + HugoTransactions hugoTrans(*ctx->getTab()); + if (hugoTrans.loadTable(GETNDB(step), 10) != 0){ + return NDBT_FAILED; + } + + if(hugoOps.startTransaction(pNdb) != 0) + goto err; + + if(hugoOps.pkUpdateRecord(pNdb, 0, 1, rand()) != 0) + goto err; + + if(hugoOps.execute_NoCommit(pNdb) != 0) + goto err; + + if (restarter.insertErrorInAllNodes(5100)) + return NDBT_FAILED; + + hugoOps.execute_Rollback(pNdb); + + if (restarter.waitClusterStarted() != 0) + goto err; + + if (restarter.insertErrorInAllNodes(0)) + return NDBT_FAILED; + + ctx->stopTest(); + return NDBT_OK; + +err: + ctx->stopTest(); + return NDBT_FAILED; +} + + NDBT_TESTSUITE(testNodeRestart); TESTCASE("NoLoad", "Test that one node at a time can be stopped and then restarted "\ @@ -558,6 +685,8 @@ TESTCASE("RestartNFDuringNR", INITIALIZER(runCheckAllNodesStarted); INITIALIZER(runLoadTable); STEP(runRestarts); + STEP(runPkUpdateUntilStopped); + STEP(runScanUpdateUntilStopped); FINALIZER(runScanReadVerify); FINALIZER(runClearTable); } @@ -647,6 +776,8 @@ TESTCASE("RestartNodeDuringLCP", INITIALIZER(runCheckAllNodesStarted); INITIALIZER(runLoadTable); STEP(runRestarts); + STEP(runPkUpdateUntilStopped); + STEP(runScanUpdateUntilStopped); FINALIZER(runScanReadVerify); FINALIZER(runClearTable); } @@ -671,6 +802,24 @@ TESTCASE("LateCommit", STEP(runLateCommit); FINALIZER(runClearTable); } +TESTCASE("Bug15587", + "Test bug with NF during NR"){ + INITIALIZER(runLoadTable); + STEP(runScanUpdateUntilStopped); + STEP(runBug15587); + FINALIZER(runClearTable); +} +TESTCASE("Bug15632", + "Test bug with NF during NR"){ + INITIALIZER(runLoadTable); + STEP(runBug15632); + FINALIZER(runClearTable); +} +TESTCASE("Bug15685", + "Test bug with NF during abort"){ + STEP(runBug15685); + FINALIZER(runClearTable); +} NDBT_TESTSUITE_END(testNodeRestart); int main(int argc, const char** argv){ diff --git a/ndb/test/ndbapi/testOperations.cpp b/ndb/test/ndbapi/testOperations.cpp index 726f35b01fb..505b1620900 100644 --- a/ndb/test/ndbapi/testOperations.cpp +++ b/ndb/test/ndbapi/testOperations.cpp @@ -659,6 +659,9 @@ main(int argc, const char** argv){ for(Uint32 i = 0; i < 12; i++) { + if(i == 6 || i == 8 || i == 10) + continue; + BaseString name("bug_9749"); name.appfmt("_%d", i); NDBT_TestCaseImpl1 *pt = new NDBT_TestCaseImpl1(&ts, diff --git a/ndb/test/run-test/daily-basic-tests.txt b/ndb/test/run-test/daily-basic-tests.txt index fc04664564f..6378b4a06d3 100644 --- a/ndb/test/run-test/daily-basic-tests.txt +++ b/ndb/test/run-test/daily-basic-tests.txt @@ -434,6 +434,18 @@ max-time: 500 cmd: testScan args: -l 100 -n Scan-bug8262 T7 +max-time: 500 +cmd: testNodeRestart +args: -n Bug15587 T1 + +max-time: 500 +cmd: testNodeRestart +args: -n Bug15632 T1 + +max-time: 500 +cmd: testNodeRestart +args: -n Bug15685 T1 + # OLD FLEX max-time: 500 cmd: flexBench diff --git a/ndb/tools/ndb_error_reporter b/ndb/tools/ndb_error_reporter new file mode 100755 index 00000000000..2b5aadb6171 --- /dev/null +++ b/ndb/tools/ndb_error_reporter @@ -0,0 +1,88 @@ +#!/usr/bin/perl -w + +use strict; + +if(@ARGV < 1) +{ + print STDERR "Usage:\n"; + print STDERR "\tndb_error_reporter config.ini [username] [--fs]\n\n"; + print STDERR "\tusername is a user that you can use to ssh into\n"; + print STDERR "\t all of your nodes with.\n\n"; + print STDERR "\t--fs means include the filesystems in the report\n"; + print STDERR "\t WARNING: This may require a lot of disk space.\n"; + print STDERR "\t Only use this option when asked to.\n\n"; + exit(1); +} + +my $config_file= $ARGV[0]; +my $config_get_fs= 0; +my $config_username= ''; +if(defined($ARGV[1])) +{ + $config_get_fs= 1 if $ARGV[1] eq '--fs'; + $config_username= $ARGV[1].'@' if $ARGV[1] ne '--fs'; + $config_get_fs= (defined $ARGV[2] && $ARGV[2] eq '--fs')?1:$config_get_fs; +} + +if(!stat($config_file)) +{ + print STDERR "Cannot open configuration file.\n\n"; + exit(1); +} + +my @nodes= split ' ',`ndb_config --config-file=$ARGV[0] --nodes --query=id --type=ndbd`; + +push @nodes, split ' ',`ndb_config --config-file=$ARGV[0] --nodes --query=id --type=ndb_mgmd`; + +sub config { + my $nodeid= shift; + my $query= shift; + my $res= `ndb_config --config-file=$ARGV[0] --id=$nodeid --query=$query`; + chomp $res; + $res; +} + +my @t= localtime(); +my $reportdir= sprintf('ndb_error_report_%u%02u%02u%02u%02u%02u', + ($t[5]+1900),($t[4]+1),$t[3],$t[2],$t[1],$t[0]); + +if(stat($reportdir) || stat($reportdir.'tar.bz2')) +{ + print STDERR "It looks like another ndb_error_report process is running.\n"; + print STDERR "If that is not the case, remove the ndb_error_report directory"; + print STDERR " and run ndb_error_report again.\n\n"; + exit(1); +} + +mkdir($reportdir); + +foreach my $node (@nodes) +{ + print "\n\n Copying data from node $node". + (($config_get_fs)?" with filesystem":""). + "\n\n"; + my $recurse= ($config_get_fs)?'-r ':''; + system 'scp '.$recurse.$config_username.config($node,'host'). + ':'.config($node,'datadir')."/ndb_".$node."* ". + "$reportdir/\n"; +} + +print "\n\n Copying configuration file...\n\n\t$config_file\n\n"; +system "cp $config_file $reportdir/"; + +my $r = system 'bzip2 2>&1 > /dev/null < /dev/null'; +my $outfile; +if($r==0) +{ + $outfile= "$reportdir.tar.bz2"; + system "tar c $reportdir|bzip2 > $outfile"; +} +else +{ + $outfile= "$reportdir.tar.gz"; + system "tar c $reportdir|gzip > $outfile"; +} + +system "rm -rf $reportdir"; + +print "\n\nPlease attach $outfile to your error report\n\n"; diff --git a/ndb/tools/ndb_size.pl b/ndb/tools/ndb_size.pl index 64a20423636..c285a7590fd 100644 --- a/ndb/tools/ndb_size.pl +++ b/ndb/tools/ndb_size.pl @@ -26,24 +26,33 @@ use HTML::Template; # BUGS # ---- # - enum/set is 0 byte storage! Woah - efficient! +# - DECIMAL is 0 byte storage. A bit too efficient. # - some float stores come out weird (when there's a comma e.g. 'float(4,1)') # - no disk data values # - computes the storage requirements of views (and probably MERGE) # - ignores character sets. my $template = HTML::Template->new(filename => 'ndb_size.tmpl', - die_on_bad_params => 0); + die_on_bad_params => 0) + or die "Could not open ndb_size.tmpl."; my $dbh; +if(@ARGV < 3 || $ARGV[0] eq '--usage' || $ARGV[0] eq '--help') +{ + print STDERR "Usage:\n"; + print STDERR "\tndb_size.pl database hostname user password\n\n"; + print STDERR "If you need to specify a port number, use host:port\n\n"; + exit(1); +} + { my $database= $ARGV[0]; my $hostname= $ARGV[1]; - my $port= $ARGV[2]; - my $user= $ARGV[3]; - my $password= $ARGV[4]; - my $dsn = "DBI:mysql:database=$database;host=$hostname;port=$port"; - $dbh= DBI->connect($dsn, $user, $password); + my $user= $ARGV[2]; + my $password= $ARGV[3]; + my $dsn = "DBI:mysql:database=$database;host=$hostname"; + $dbh= DBI->connect($dsn, $user, $password) or exit(1); $template->param(db => $database); $template->param(dsn => $dsn); } @@ -55,6 +64,14 @@ my $tables = $dbh->selectall_arrayref("show tables"); my @table_size; +my @dbDataMemory; +my @dbIndexMemory; +my @NoOfAttributes; +my @NoOfIndexes; +my @NoOfTables; +$NoOfTables[$_]{val} = @{$tables} foreach 0..$#releases; + + sub align { my($to,@unaligned) = @_; my @aligned; @@ -68,9 +85,8 @@ foreach(@{$tables}) { my $table= @{$_}[0]; my @columns; - my $info= $dbh->selectall_hashref("describe ".$dbh->quote($table),"Field"); - my @count = $dbh->selectrow_array("select count(*) from " - .$dbh->quote($table)); + my $info= $dbh->selectall_hashref('describe `'.$table.'`',"Field"); + my @count = $dbh->selectrow_array('select count(*) from `'.$table.'`'); my %columnsize; # used for index calculations # We now work out the DataMemory usage @@ -130,16 +146,19 @@ foreach(@{$tables}) elsif($type =~ /varchar/ || $type =~ /varbinary/) { my $fixed= 1+$size; - my @dynamic=$dbh->selectrow_array("select avg(length(" - .$dbh->quote($name) - .")) from ".$dbh->quote($table)); + my @dynamic=$dbh->selectrow_array("select avg(length(`" + .$name + ."`)) from `".$table.'`'); $dynamic[0]=0 if !$dynamic[0]; @realsize= ($fixed,$fixed,ceil($dynamic[0])); } elsif($type =~ /binary/ || $type =~ /char/) {@realsize=($size,$size,$size)} elsif($type =~ /text/ || $type =~ /blob/) - {@realsize=(256,256,1)} # FIXME check if 5.1 is correct + { + @realsize=(256,256,1); + $NoOfTables[$_]{val} += 1 foreach 0..$#releases; # blob uses table + } # FIXME check if 5.1 is correct @realsize= align(4,@realsize); @@ -166,7 +185,7 @@ foreach(@{$tables}) # we can still connect to pre-5.0 mysqlds. my %indexes; { - my $sth= $dbh->prepare("show index from "$dbh->quote($table)); + my $sth= $dbh->prepare("show index from `".$table.'`'); $sth->execute; while(my $i = $sth->fetchrow_hashref) { @@ -257,7 +276,51 @@ foreach(@{$tables}) IndexMemory=>\@IndexMemory, }; + + $dbDataMemory[$_]{val} += $DataMemory[$_]{val} foreach 0..$#releases; + $dbIndexMemory[$_]{val} += $IndexMemory[$_]{val} foreach 0..$#releases; + $NoOfAttributes[$_]{val} += @columns foreach 0..$#releases; + $NoOfIndexes[$_]{val} += @indexes foreach 0..$#releases; +} + +my @NoOfTriggers; +# for unique hash indexes +$NoOfTriggers[$_]{val} += $NoOfIndexes[$_]{val}*3 foreach 0..$#releases; +# for ordered index +$NoOfTriggers[$_]{val} += $NoOfIndexes[$_]{val} foreach 0..$#releases; + +my @ParamMemory; +foreach (0..$#releases) { + $ParamMemory[0]{releases}[$_]{val}= POSIX::ceil(200*$NoOfAttributes[$_]{val}/1024); + $ParamMemory[0]{name}= 'Attributes'; + + $ParamMemory[1]{releases}[$_]{val}= 20*$NoOfTables[$_]{val}; + $ParamMemory[1]{name}= 'Tables'; + + $ParamMemory[2]{releases}[$_]{val}= 10*$NoOfIndexes[$_]{val}; + $ParamMemory[2]{name}= 'OrderedIndexes'; + + $ParamMemory[3]{releases}[$_]{val}= 15*$NoOfIndexes[$_]{val}; + $ParamMemory[3]{name}= 'UniqueHashIndexes'; } $template->param(tables => \@table_size); +$template->param(Parameters => [{name=>'DataMemory (kb)', + releases=>\@dbDataMemory}, + {name=>'IndexMemory (kb)', + releases=>\@dbIndexMemory}, + {name=>'MaxNoOfTables', + releases=>\@NoOfTables}, + {name=>'MaxNoOfAttributes', + releases=>\@NoOfAttributes}, + {name=>'MaxNoOfOrderedIndexes', + releases=>\@NoOfIndexes}, + {name=>'MaxNoOfUniqueHashIndexes', + releases=>\@NoOfIndexes}, + {name=>'MaxNoOfTriggers', + releases=>\@NoOfTriggers} + ] + ); +$template->param(ParamMemory => \@ParamMemory); + print $template->output; diff --git a/ndb/tools/ndb_size.tmpl b/ndb/tools/ndb_size.tmpl index d83d5d2c6af..dc02b5a5970 100644 --- a/ndb/tools/ndb_size.tmpl +++ b/ndb/tools/ndb_size.tmpl @@ -13,18 +13,58 @@ td,th { border: 1px solid black }

MySQL Cluster analysis for

This is an automated analysis of the database for migration into MySQL Cluster. No warranty is made to the accuracy of the information.

-

This information should be valid for MySQL 4.1

+

This information should be valid for MySQL 4.1 and 5.0. Since 5.1 is not a final release yet, the numbers should be used as a guide only.

+

Parameter Settings

+

NOTE the configuration parameters below do not take into account system tables and other requirements.

+ + + + + + + + + + + + + + + +
Parameter
+ +

Memory usage because of parameters

+ +

Usage is in kilobytes. Actual usage will vary as you should set the parameters larger than those listed in the table above.

+ + + + + + + + + + + + + + + +
Parameter
+ +

Table List


-

+

">

diff --git a/netware/BUILD/compile-linux-tools b/netware/BUILD/compile-linux-tools index 70f07be649e..c67830be7ed 100755 --- a/netware/BUILD/compile-linux-tools +++ b/netware/BUILD/compile-linux-tools @@ -18,7 +18,6 @@ path=`dirname $0` if test -e "Makefile"; then make -k clean; fi # remove files -rm -f NEW-RPMS/* rm -f */.deps/*.P rm -f */*.linux @@ -29,7 +28,8 @@ rm -f */*.linux ./configure --without-innodb --without-docs # build tools only -make clean all-local +make clean +make (cd dbug; make libdbug.a) (cd strings; make libmystrings.a) (cd mysys; make libmysys.a) @@ -54,7 +54,7 @@ make clean all-local # copying required linux tools cp extra/comp_err extra/comp_err.linux cp libmysql/conf_to_src libmysql/conf_to_src.linux -cp libmysql_r/conf_to_src libmysql_r/conf_to_src.linux +#cp libmysql_r/conf_to_src libmysql_r/conf_to_src.linux cp sql/gen_lex_hash sql/gen_lex_hash.linux cp strings/conf_to_src strings/conf_to_src.linux diff --git a/netware/BUILD/compile-netware-END b/netware/BUILD/compile-netware-END index 2bd59f97114..c5c08cea908 100755 --- a/netware/BUILD/compile-netware-END +++ b/netware/BUILD/compile-netware-END @@ -12,7 +12,6 @@ path=`dirname $0` if test -e "Makefile"; then make -k clean; fi # remove files -rm -f NEW-RPMS/* rm -f */.deps/*.P rm -rf Makefile.in.bk diff --git a/netware/BUILD/compile-netware-src b/netware/BUILD/compile-netware-src index df7f6fcdd1a..f4e8a53ffea 100644 --- a/netware/BUILD/compile-netware-src +++ b/netware/BUILD/compile-netware-src @@ -21,7 +21,6 @@ if test -e "Makefile"; then fi # remove other files -rm -f NEW-RPMS/* rm -f */.deps/*.P rm -rf Makefile.in.bk diff --git a/netware/Makefile.am b/netware/Makefile.am index aeb93d1575d..0588e6b1ade 100644 --- a/netware/Makefile.am +++ b/netware/Makefile.am @@ -42,10 +42,10 @@ netware_build_files = client/mysql.def client/mysqladmin.def \ link_sources: set -x; \ for f in $(netware_build_files); do \ - rm -f $(srcdir)/../$$f; \ + rm -f ../$$f; \ org=`echo $$f | sed -e 's/.*\/\(.*\)/\1/g'`; \ - @LN_CP_F@ $(srcdir)/$$org $(srcdir)/../$$f; \ - done; + @LN_CP_F@ $(srcdir)/$$org ../$$f; \ + done else EXTRA_DIST= comp_err.def init_db.sql install_test_db.ncf \ isamchk.def isamlog.def libmysql.def libmysql.imp \ diff --git a/netware/libmysql.def b/netware/libmysql.def index fea117dedd1..8a34754e092 100644 --- a/netware/libmysql.def +++ b/netware/libmysql.def @@ -7,5 +7,6 @@ COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Res DESCRIPTION "MySQL Client Library" VERSION 4, 0 AUTOUNLOAD +STACKSIZE 32768 XDCDATA ../netware/mysql.xdc #DEBUG diff --git a/netware/my_print_defaults.def b/netware/my_print_defaults.def index 826981256b5..f22fdec38af 100644 --- a/netware/my_print_defaults.def +++ b/netware/my_print_defaults.def @@ -5,6 +5,7 @@ MODULE libc.nlm COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved." DESCRIPTION "MySQL Print Defaults Tool" VERSION 4, 0 +STACKSIZE 32768 XDCDATA ../netware/mysql.xdc #DEBUG diff --git a/netware/myisamlog.def b/netware/myisamlog.def index 3580c870c10..553a818a2ae 100644 --- a/netware/myisamlog.def +++ b/netware/myisamlog.def @@ -6,6 +6,7 @@ SCREENNAME "MySQL MyISAM Table Log Tool" COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved." DESCRIPTION "MySQL MyISAM Table Log Tool" VERSION 4, 0 +STACKSIZE 32768 XDCDATA ../netware/mysql.xdc #DEBUG diff --git a/netware/myisampack.def b/netware/myisampack.def index a6946982236..d1f85fe03f8 100644 --- a/netware/myisampack.def +++ b/netware/myisampack.def @@ -6,6 +6,7 @@ SCREENNAME "MySQL MyISAM Table Pack Tool" COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved." DESCRIPTION "MySQL MyISAM Table Pack Tool" VERSION 4, 0 +STACKSIZE 32768 XDCDATA ../netware/mysql.xdc #DEBUG diff --git a/netware/mysql.def b/netware/mysql.def index b79c94b1bb1..16acc7babe1 100644 --- a/netware/mysql.def +++ b/netware/mysql.def @@ -6,6 +6,7 @@ SCREENNAME "MySQL Monitor[scrollable]" COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved." DESCRIPTION "MySQL Monitor" VERSION 4, 0 +STACKSIZE 32768 MULTIPLE XDCDATA ../netware/mysql.xdc #DEBUG diff --git a/netware/mysql_install_db.def b/netware/mysql_install_db.def index 1657b7c17af..372bbf15570 100644 --- a/netware/mysql_install_db.def +++ b/netware/mysql_install_db.def @@ -6,6 +6,7 @@ SCREENNAME "MySQL Install" COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved." DESCRIPTION "MySQL Initial Database Installer" VERSION 4, 0 +STACKSIZE 32768 XDCDATA ../netware/mysql.xdc #DEBUG diff --git a/netware/mysql_test_run.c b/netware/mysql_test_run.c index 849828210f2..c23264cdbbd 100644 --- a/netware/mysql_test_run.c +++ b/netware/mysql_test_run.c @@ -172,7 +172,7 @@ void report_stats() log_msg("\nFailed %u/%u test(s), %.02f%% successful.\n", total_fail, total_test, percent); log_msg("\nThe .out and .err files in %s may give you some\n", result_dir); - log_msg("hint of what when wrong.\n"); + log_msg("hint of what went wrong.\n"); log_msg("\nIf you want to report this error, please first read the documentation\n"); log_msg("at: http://www.mysql.com/doc/en/MySQL_test_suite.html\n"); } @@ -347,6 +347,8 @@ void start_master() add_arg(&al, "--character-sets-dir=%s", char_dir); add_arg(&al, "--tmpdir=%s", mysql_tmp_dir); add_arg(&al, "--language=%s", lang_dir); + add_arg(&al, "--log-slow-queries"); + add_arg(&al, "--log-queries-not-using-indexes"); #ifdef DEBUG //only for debug builds add_arg(&al, "--debug"); #endif @@ -520,6 +522,8 @@ void start_slave() add_arg(&al, "--master-retry-count=10"); add_arg(&al, "-O"); add_arg(&al, "slave_net_timeout=10"); + add_arg(&al, "--log-slow-queries"); + add_arg(&al, "--log-queries-not-using-indexes"); #ifdef DEBUG //only for debug builds add_arg(&al, "--debug"); #endif @@ -941,7 +945,7 @@ void run_test(char *test) // increment total ++total_test; } - else if (err == 2) + else if (err == 62) // To reflect the changes made in client/mysqltest.c { // skip rstr = TEST_SKIP; diff --git a/netware/mysqladmin.def b/netware/mysqladmin.def index cfab4f4c23d..6532cab84a0 100644 --- a/netware/mysqladmin.def +++ b/netware/mysqladmin.def @@ -6,6 +6,7 @@ SCREENNAME "MySQL Admin[scrollable]" COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved." DESCRIPTION "MySQL Admin Tool" VERSION 4, 0 +STACKSIZE 32768 XDCDATA ../netware/mysql.xdc #DEBUG diff --git a/netware/mysqlbinlog.def b/netware/mysqlbinlog.def index 3e75cf07a57..aced63429c5 100644 --- a/netware/mysqlbinlog.def +++ b/netware/mysqlbinlog.def @@ -6,6 +6,7 @@ SCREENNAME "MySQL Binary Log Dump Tool[scrollable]" COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved." DESCRIPTION "MySQL Binary Log Dump Tool" VERSION 4, 0 +STACKSIZE 32768 XDCDATA ../netware/mysql.xdc #DEBUG diff --git a/netware/mysqlcheck.def b/netware/mysqlcheck.def index cb70c1b394d..1b90b2a1dbe 100644 --- a/netware/mysqlcheck.def +++ b/netware/mysqlcheck.def @@ -6,6 +6,7 @@ SCREENNAME "MySQL Check Tool[scrollable]" COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved." DESCRIPTION "MySQL Check Tool" VERSION 4, 0 +STACKSIZE 32768 XDCDATA ../netware/mysql.xdc #DEBUG diff --git a/netware/mysqld_safe.c b/netware/mysqld_safe.c index a307b52bb7e..8e8f5111241 100644 --- a/netware/mysqld_safe.c +++ b/netware/mysqld_safe.c @@ -258,11 +258,11 @@ void finish_defaults() void read_defaults(arg_list_t *pal) { arg_list_t al; - char defaults_file[PATH_MAX]; + char defaults_file[PATH_MAX]; char mydefaults[PATH_MAX]; char line[PATH_MAX]; FILE *fp; - + // defaults output file snprintf(defaults_file, PATH_MAX, "%s/bin/defaults.out", basedir); remove(defaults_file); @@ -270,7 +270,7 @@ void read_defaults(arg_list_t *pal) // mysqladmin file snprintf(mydefaults, PATH_MAX, "%s/bin/my_print_defaults", basedir); - // args + // args init_args(&al); add_arg(&al, mydefaults); if (default_option[0]) @@ -279,11 +279,11 @@ void read_defaults(arg_list_t *pal) add_arg(&al, "server"); add_arg(&al, "mysqld_safe"); add_arg(&al, "safe_mysqld"); - + spawn(mydefaults, &al, TRUE, NULL, defaults_file, NULL); - + free_args(&al); - + // gather defaults if ((fp= fopen(defaults_file, "r")) != NULL) { diff --git a/netware/mysqld_safe.def b/netware/mysqld_safe.def index 2a9ef04b47d..ff3f1924906 100644 --- a/netware/mysqld_safe.def +++ b/netware/mysqld_safe.def @@ -6,6 +6,7 @@ SCREENNAME "MySQL Database Server" COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved." DESCRIPTION "MySQL Database Server Monitor" VERSION 4, 0 +STACKSIZE 32768 MULTIPLE XDCDATA ../netware/mysql.xdc #DEBUG diff --git a/netware/mysqldump.def b/netware/mysqldump.def index 811c53ce5f6..5d7999c789f 100644 --- a/netware/mysqldump.def +++ b/netware/mysqldump.def @@ -6,6 +6,7 @@ SCREENNAME "MySQL Dump Tool[scrollable]" COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved." DESCRIPTION "MySQL Dump Tool" VERSION 4, 0 +STACKSIZE 32768 XDCDATA ../netware/mysql.xdc #DEBUG diff --git a/netware/mysqlimport.def b/netware/mysqlimport.def index dc9af18aa09..f98d8021a73 100644 --- a/netware/mysqlimport.def +++ b/netware/mysqlimport.def @@ -6,6 +6,7 @@ SCREENNAME "MySQL Import[scrollable]" COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved." DESCRIPTION "MySQL Import Tool" VERSION 4, 0 +STACKSIZE 32768 XDCDATA ../netware/mysql.xdc #DEBUG diff --git a/netware/perror.def b/netware/perror.def index 18c95d8b236..d67bd6191b4 100644 --- a/netware/perror.def +++ b/netware/perror.def @@ -5,6 +5,7 @@ MODULE libc.nlm COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved." DESCRIPTION "MySQL Error Code Description Tool" VERSION 4, 0 +STACKSIZE 32768 XDCDATA ../netware/mysql.xdc #DEBUG diff --git a/pstack/Makefile.am b/pstack/Makefile.am index 77f84d212cd..20d5d8314ce 100644 --- a/pstack/Makefile.am +++ b/pstack/Makefile.am @@ -20,7 +20,7 @@ # SUBDIRS = aout -INCLUDES = -I$(top_srcdir)/include +INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include noinst_HEADERS = bucomm.h debug.h ieee.h budbg.h demangle.h \ linuxthreads.h pstack.h pstacktrace.h SRC= bucomm.c filemode.c linuxthreads.c rddbg.c \ diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 27b42314273..30ba75c551d 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -85,12 +85,13 @@ CLEANFILES = @server_scripts@ \ mysql_find_rows \ mysqlhotcopy \ mysqldumpslow \ + mysql_explain_log \ + mysql_tableinfo \ mysqld_multi \ make_win_src_distribution \ - make_win_binary_distribution \ mysql_create_system_tables -SUPERCLEANFILES = mysqlbug +DISTCLEANFILES = mysqlbug # We want the right version and configure comand line in mysqlbug mysqlbug: ${top_builddir}/config.status mysqlbug.sh diff --git a/scripts/make_binary_distribution.sh b/scripts/make_binary_distribution.sh index c00ba1c6f57..3c16937e158 100644 --- a/scripts/make_binary_distribution.sh +++ b/scripts/make_binary_distribution.sh @@ -177,6 +177,7 @@ if [ $BASE_SYSTEM = "netware" ] ; then libname=`basename $i .a` $MV $i $BASE/lib/$libname.lib done + rm -f $BASE/lib/*.la fi copyfileto $BASE/include config.h include/* @@ -266,6 +267,9 @@ if [ $BASE_SYSTEM = "netware" ] ; then $BASE/support-files/mysql*.spec \ $BASE/support-files/mysql-log-rotate \ $BASE/support-files/binary-configure \ + $BASE/support-files/build-tags \ + $BASE/support-files/MySQL-shared-compat.spec \ + $BASE/support-files/ndb-config-2-node.ini \ $BASE/INSTALL-BINARY \ $BASE/MySQLEULA.txt else diff --git a/scripts/make_win_src_distribution.sh b/scripts/make_win_src_distribution.sh index 2e93ebcb007..2e312e0c3cf 100644 --- a/scripts/make_win_src_distribution.sh +++ b/scripts/make_win_src_distribution.sh @@ -199,7 +199,7 @@ copy_dir_files() print_debug "Creating directory '$arg'" mkdir $BASE/$arg fi - for i in *.c *.cpp *.h *.ih *.i *.ic *.asm *.def *.hpp *.dsp *.dsw \ + for i in *.c *.cpp *.h *.ih *.i *.ic *.asm *.def *.hpp \ README INSTALL* LICENSE AUTHORS NEWS ChangeLog \ *.inc *.test *.result *.pem Moscow_leap des_key_file \ *.vcproj *.sln *.dat *.000001 *.require *.opt @@ -340,7 +340,7 @@ mv $BASE/sql/sql_yacc.cpp-new $BASE/sql/sql_yacc.cpp # # Search the tree for plain text files and adapt the line end marker # -find $BASE \( -name "*.dsp" -o -name "*.dsw" -o -name "*.cnf" -o -name "*.ini" \ +find $BASE \( -name "*.cnf" -o -name "*.ini" \ -o -name COPYING -o -name ChangeLog -o -name EXCEPTIONS-CLIENT \ -o -name "INSTALL*" -o -name LICENSE -o -name "README*" \ -o -name "*.vcproj" -o -name "*.sln" \) -type f -print \ diff --git a/scripts/mysql_fix_privilege_tables.sql b/scripts/mysql_fix_privilege_tables.sql index 0d7d32fd6a9..a72bd2799aa 100644 --- a/scripts/mysql_fix_privilege_tables.sql +++ b/scripts/mysql_fix_privilege_tables.sql @@ -29,7 +29,7 @@ ALTER TABLE user add Grant_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,a ALTER TABLE host add Grant_priv enum('N','Y') NOT NULL,add References_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add Index_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add Alter_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL; ALTER TABLE db add Grant_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add References_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add Index_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL,add Alter_priv enum('N','Y') COLLATE utf8_general_ci NOT NULL; ---- Fix privileges for old tables +-- Fix privileges for old tables UPDATE user SET Grant_priv=File_priv,References_priv=Create_priv,Index_priv=Create_priv,Alter_priv=Create_priv WHERE @hadGrantPriv = 0; UPDATE db SET References_priv=Create_priv,Index_priv=Create_priv,Alter_priv=Create_priv WHERE @hadGrantPriv = 0; UPDATE host SET References_priv=Create_priv,Index_priv=Create_priv,Alter_priv=Create_priv WHERE @hadGrantPriv = 0; diff --git a/scripts/mysqld_multi.sh b/scripts/mysqld_multi.sh index 7fff4cbb731..4a6f380494f 100644 --- a/scripts/mysqld_multi.sh +++ b/scripts/mysqld_multi.sh @@ -718,9 +718,6 @@ sub usage print <connector_fd; my_free(mysql->options.ssl_key, MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.ssl_cert, MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.ssl_ca, MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.ssl_capath, MYF(MY_ALLOW_ZERO_PTR)); - my_free(mysql->options.ssl_cipher, MYF(MY_ALLOW_ZERO_PTR)); + my_free(mysql->options.ssl_cipher, MYF(MY_ALLOW_ZERO_PTR)); + if (st) + SSL_CTX_free(st->ssl_context); my_free(mysql->connector_fd,MYF(MY_ALLOW_ZERO_PTR)); mysql->options.ssl_key = 0; mysql->options.ssl_cert = 0; diff --git a/sql-common/my_time.c b/sql-common/my_time.c index 40d7799e274..3c46a944ba9 100644 --- a/sql-common/my_time.c +++ b/sql-common/my_time.c @@ -514,18 +514,34 @@ fractional: /* Get fractional second part */ if ((end-str) >= 2 && *str == '.' && my_isdigit(&my_charset_latin1,str[1])) { - uint field_length=5; + int field_length= 5; str++; value=(uint) (uchar) (*str - '0'); - while (++str != end && - my_isdigit(&my_charset_latin1,str[0]) && - field_length--) - value=value*10 + (uint) (uchar) (*str - '0'); - if (field_length) + while (++str != end && my_isdigit(&my_charset_latin1, *str)) + { + if (field_length-- > 0) + value= value*10 + (uint) (uchar) (*str - '0'); + } + if (field_length > 0) value*= (long) log_10_int[field_length]; + else if (field_length < 0) + *was_cut= 1; date[4]=value; } else date[4]=0; + + /* Check for exponent part: E | E */ + /* (may occur as result of %g formatting of time value) */ + if ((end - str) > 1 && + (*str == 'e' || *str == 'E') && + (my_isdigit(&my_charset_latin1, str[1]) || + ((str[1] == '-' || str[1] == '+') && + (end - str) > 2 && + my_isdigit(&my_charset_latin1, str[2])))) + { + *was_cut= 1; + return 1; + } if (internal_format_positions[7] != 255) { diff --git a/sql/Makefile.am b/sql/Makefile.am index ea7cea9c7b9..218cf5dbca5 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -111,17 +111,17 @@ AM_YFLAGS = -d mysql_tzinfo_to_sql.cc: rm -f mysql_tzinfo_to_sql.cc - @LN_CP_F@ tztime.cc mysql_tzinfo_to_sql.cc + @LN_CP_F@ $(srcdir)/tztime.cc mysql_tzinfo_to_sql.cc link_sources: mysql_tzinfo_to_sql.cc rm -f mini_client_errors.c - @LN_CP_F@ ../libmysql/errmsg.c mini_client_errors.c + @LN_CP_F@ $(top_srcdir)/libmysql/errmsg.c mini_client_errors.c rm -f pack.c - @LN_CP_F@ ../sql-common/pack.c pack.c + @LN_CP_F@ $(top_srcdir)/sql-common/pack.c pack.c rm -f client.c - @LN_CP_F@ ../sql-common/client.c client.c + @LN_CP_F@ $(top_srcdir)/sql-common/client.c client.c rm -f my_time.c - @LN_CP_F@ ../sql-common/my_time.c my_time.c + @LN_CP_F@ $(top_srcdir)/sql-common/my_time.c my_time.c mysql_tzinfo_to_sql.o: $(mysql_tzinfo_to_sql_SOURCES) $(CXXCOMPILE) -c $(INCLUDES) -DTZINFO2SQL $< @@ -145,7 +145,7 @@ lex_hash.h: gen_lex_hash$(EXEEXT) udf_example.so: udf_example.cc $(CXXCOMPILE) -shared -o $@ $< -distclean: +distclean-local: rm -f lex_hash.h # Don't update the files from bitkeeper diff --git a/sql/examples/ha_tina.cc b/sql/examples/ha_tina.cc index 8a9aa91c680..91e42bfea31 100644 --- a/sql/examples/ha_tina.cc +++ b/sql/examples/ha_tina.cc @@ -58,12 +58,16 @@ static int tina_init= 0; ** TINA tables *****************************************************************************/ -/* - Used for sorting chains. +/* + Used for sorting chains with qsort(). */ int sort_set (tina_set *a, tina_set *b) { - return ( a->begin > b->begin ? 1 : ( a->begin < b->begin ? -1 : 0 ) ); + /* + We assume that intervals do not intersect. So, it is enought to compare + any two points. Here we take start of intervals for comparison. + */ + return ( a->begin > b->begin ? -1 : ( a->begin < b->begin ? 1 : 0 ) ); } static byte* tina_get_key(TINA_SHARE *share,uint *length, @@ -162,7 +166,8 @@ static TINA_SHARE *get_share(const char *table_name, TABLE *table) thr_lock_init(&share->lock); pthread_mutex_init(&share->mutex,MY_MUTEX_INIT_FAST); - if ((share->data_file= my_open(data_file_name, O_RDWR, MYF(0))) == -1) + if ((share->data_file= my_open(data_file_name, O_RDWR|O_APPEND, + MYF(0))) == -1) goto error2; /* We only use share->data_file for writing, so we scan to the end to append */ @@ -739,13 +744,8 @@ int ha_tina::rnd_end() qsort(chain, (size_t)(chain_ptr - chain), sizeof(tina_set), (qsort_cmp)sort_set); for (ptr= chain; ptr < chain_ptr; ptr++) { - /* We peek a head to see if this is the last chain */ - if (ptr+1 == chain_ptr) - memmove(share->mapped_file + ptr->begin, share->mapped_file + ptr->end, - length - (size_t)ptr->end); - else - memmove((caddr_t)share->mapped_file + ptr->begin, (caddr_t)share->mapped_file + ptr->end, - (size_t)((ptr++)->begin - ptr->end)); + memmove(share->mapped_file + ptr->begin, share->mapped_file + ptr->end, + length - (size_t)ptr->end); length= length - (size_t)(ptr->end - ptr->begin); } diff --git a/sql/field.cc b/sql/field.cc index 6d2f92e27ea..b1d9167aee2 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -5745,8 +5745,7 @@ void Field_blob::get_key_image(char *buff,uint length, return; } get_ptr(&blob); - gobj= Geometry::create_from_wkb(&buffer, - blob + SRID_SIZE, blob_length - SRID_SIZE); + gobj= Geometry::construct(&buffer, blob, blob_length); if (gobj->get_mbr(&mbr, &dummy)) bzero(buff, SIZEOF_STORED_DOUBLE*4); else @@ -6039,8 +6038,7 @@ void Field_geom::get_key_image(char *buff, uint length, CHARSET_INFO *cs, return; } get_ptr(&blob); - gobj= Geometry::create_from_wkb(&buffer, - blob + SRID_SIZE, blob_length - SRID_SIZE); + gobj= Geometry::construct(&buffer, blob, blob_length); if (gobj->get_mbr(&mbr, &dummy)) bzero(buff, SIZEOF_STORED_DOUBLE*4); else @@ -6100,7 +6098,7 @@ int Field_geom::store(const char *from, uint length, CHARSET_INFO *cs) uint32 wkb_type; if (length < SRID_SIZE + WKB_HEADER_SIZE + SIZEOF_STORED_DOUBLE*2) goto err; - wkb_type= uint4korr(from + WKB_HEADER_SIZE); + wkb_type= uint4korr(from + SRID_SIZE + 1); if (wkb_type < (uint32) Geometry::wkb_point || wkb_type > (uint32) Geometry::wkb_end) return -1; @@ -6511,8 +6509,20 @@ bool Field_num::eq_def(Field *field) ** Handling of field and create_field *****************************************************************************/ +/* + Convert create_field::length from number of characters to number of bytes + + SYNOPSIS + create_field::create_length_to_internal_length() + + DESCRIPTION + Convert create_field::length from number of characters to number of bytes, + save original value in chars_length. +*/ + void create_field::create_length_to_internal_length(void) { + chars_length= length; switch (sql_type) { case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_MEDIUM_BLOB: @@ -6939,11 +6949,11 @@ uint32 Field_blob::max_length() switch (packlength) { case 1: - return 255; + return 255 * field_charset->mbmaxlen; case 2: - return 65535; + return 65535 * field_charset->mbmaxlen; case 3: - return 16777215; + return 16777215 * field_charset->mbmaxlen; case 4: return (uint32) 4294967295U; default: diff --git a/sql/field.h b/sql/field.h index ba963418c7a..04f1bd68c7a 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1180,7 +1180,15 @@ public: LEX_STRING comment; // Comment for field Item *def; // Default value enum enum_field_types sql_type; + /* + At various stages in execution this can be length of field in bytes or + max number of characters. + */ uint32 length; + /* + The value of 'length' before a call to create_length_to_internal_length + */ + uint32 chars_length; uint decimals,flags,pack_length; Field::utype unireg_check; TYPELIB *interval; // Which interval to use diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 5c81dd2163c..d24587e23ea 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -2015,6 +2015,22 @@ get_innobase_type_from_mysql_type( return(0); } +/*********************************************************************** +Writes an unsigned integer value < 64k to 2 bytes, in the little-endian +storage format. */ +inline +void +innobase_write_to_2_little_endian( +/*==============================*/ + byte* buf, /* in: where to store */ + ulint val) /* in: value to write, must be < 64k */ +{ + ut_a(val < 256 * 256); + + buf[0] = (byte)(val & 0xFF); + buf[1] = (byte)(val / 256); +} + /*********************************************************************** Stores a key value for a row to a buffer. */ @@ -2034,8 +2050,6 @@ ha_innobase::store_key_val_for_row( char* buff_start = buff; enum_field_types mysql_type; Field* field; - ulint blob_len; - byte* blob_data; ibool is_null; DBUG_ENTER("store_key_val_for_row"); @@ -2084,13 +2098,25 @@ ha_innobase::store_key_val_for_row( || mysql_type == FIELD_TYPE_BLOB || mysql_type == FIELD_TYPE_LONG_BLOB) { + CHARSET_INFO* cs; + ulint key_len; + ulint len; + ulint true_len; + int error=0; + ulint blob_len; + byte* blob_data; + ut_a(key_part->key_part_flag & HA_PART_KEY_SEG); + key_len = key_part->length; + if (is_null) { - buff += key_part->length + 2; + buff += key_len + 2; continue; } + + cs = field->charset(); blob_data = row_mysql_read_blob_ref(&blob_len, (byte*) (record @@ -2099,29 +2125,108 @@ ha_innobase::store_key_val_for_row( ut_a(get_field_offset(table, field) == key_part->offset); - if (blob_len > key_part->length) { - blob_len = key_part->length; + + true_len = blob_len; + + /* For multi byte character sets we need to calculate + the true length of the key */ + + if (key_len > 0 && cs->mbmaxlen > 1) { + true_len = (ulint) cs->cset->well_formed_len(cs, + (const char *) blob_data, + (const char *) blob_data + + blob_len, + key_len / cs->mbmaxlen, + &error); + } + + /* All indexes on BLOB and TEXT are column prefix + indexes, and we may need to truncate the data to be + stored in the key value: */ + + if (true_len > key_len) { + true_len = key_len; } /* MySQL reserves 2 bytes for the length and the storage of the number is little-endian */ - ut_a(blob_len < 256); - *((byte*)buff) = (byte)blob_len; + innobase_write_to_2_little_endian( + (byte*)buff, true_len); buff += 2; - memcpy(buff, blob_data, blob_len); + memcpy(buff, blob_data, true_len); - buff += key_part->length; + /* Note that we always reserve the maximum possible + length of the BLOB prefix in the key value. */ + + buff += key_len; } else { + /* Here we handle all other data types except the + true VARCHAR, BLOB and TEXT. Note that the column + value we store may be also in a column prefix + index. */ + + CHARSET_INFO* cs; + ulint true_len; + ulint key_len; + const mysql_byte* src_start; + int error=0; + enum_field_types real_type; + + key_len = key_part->length; + if (is_null) { - buff += key_part->length; + buff += key_len; continue; } - memcpy(buff, record + key_part->offset, - key_part->length); - buff += key_part->length; + + src_start = record + key_part->offset; + real_type = field->real_type(); + true_len = key_len; + + /* Character set for the field is defined only + to fields whose type is string and real field + type is not enum or set. For these fields check + if character set is multi byte. */ + + if (real_type != FIELD_TYPE_ENUM + && real_type != FIELD_TYPE_SET + && ( mysql_type == MYSQL_TYPE_VAR_STRING + || mysql_type == MYSQL_TYPE_STRING)) { + + cs = field->charset(); + + /* For multi byte character sets we need to + calculate the true length of the key */ + + if (key_len > 0 && cs->mbmaxlen > 1) { + + true_len = (ulint) + cs->cset->well_formed_len(cs, + (const char *)src_start, + (const char *)src_start + + key_len, + key_len / cs->mbmaxlen, + &error); + } + } + + memcpy(buff, src_start, true_len); + buff += true_len; + + /* Pad the unused space with spaces. Note that no + padding is ever needed for UCS-2 because in MySQL, + all UCS2 characters are 2 bytes, as MySQL does not + support surrogate pairs, which are needed to represent + characters in the range U+10000 to U+10FFFF. */ + + if (true_len < key_len) { + ulint pad_len = key_len - true_len; + memset(buff, ' ', pad_len); + buff += pad_len; + } } } @@ -4729,6 +4834,7 @@ ha_innobase::update_table_comment( uint length = strlen(comment); char* str; row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt; + long flen; /* We do not know if MySQL can call this function before calling external_lock(). To be safe, update the thd of the current table @@ -4748,43 +4854,43 @@ ha_innobase::update_table_comment( trx_search_latch_release_if_reserved(prebuilt->trx); str = NULL; - if (FILE* file = os_file_create_tmpfile()) { - long flen; + /* output the data to a temporary file */ - /* output the data to a temporary file */ - fprintf(file, "InnoDB free: %lu kB", + mutex_enter_noninline(&srv_dict_tmpfile_mutex); + rewind(srv_dict_tmpfile); + + fprintf(srv_dict_tmpfile, "InnoDB free: %lu kB", (ulong) fsp_get_available_space_in_free_extents( prebuilt->table->space)); - dict_print_info_on_foreign_keys(FALSE, file, + dict_print_info_on_foreign_keys(FALSE, srv_dict_tmpfile, prebuilt->trx, prebuilt->table); - flen = ftell(file); - if (flen < 0) { - flen = 0; - } else if (length + flen + 3 > 64000) { - flen = 64000 - 3 - length; - } - - /* allocate buffer for the full string, and - read the contents of the temporary file */ - - str = my_malloc(length + flen + 3, MYF(0)); - - if (str) { - char* pos = str + length; - if(length) { - memcpy(str, comment, length); - *pos++ = ';'; - *pos++ = ' '; - } - rewind(file); - flen = fread(pos, 1, flen, file); - pos[flen] = 0; - } - - fclose(file); + flen = ftell(srv_dict_tmpfile); + if (flen < 0) { + flen = 0; + } else if (length + flen + 3 > 64000) { + flen = 64000 - 3 - length; } + /* allocate buffer for the full string, and + read the contents of the temporary file */ + + str = my_malloc(length + flen + 3, MYF(0)); + + if (str) { + char* pos = str + length; + if (length) { + memcpy(str, comment, length); + *pos++ = ';'; + *pos++ = ' '; + } + rewind(srv_dict_tmpfile); + flen = (uint) fread(pos, 1, flen, srv_dict_tmpfile); + pos[flen] = 0; + } + + mutex_exit_noninline(&srv_dict_tmpfile_mutex); + prebuilt->trx->op_info = (char*)""; return(str ? str : (char*) comment); @@ -4802,6 +4908,7 @@ ha_innobase::get_foreign_key_create_info(void) { row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt; char* str = 0; + long flen; ut_a(prebuilt != NULL); @@ -4811,47 +4918,42 @@ ha_innobase::get_foreign_key_create_info(void) update_thd(current_thd); - if (FILE* file = os_file_create_tmpfile()) { - long flen; + prebuilt->trx->op_info = (char*)"getting info on foreign keys"; - prebuilt->trx->op_info = (char*)"getting info on foreign keys"; + /* In case MySQL calls this in the middle of a SELECT query, + release possible adaptive hash latch to avoid + deadlocks of threads */ - /* In case MySQL calls this in the middle of a SELECT query, - release possible adaptive hash latch to avoid - deadlocks of threads */ + trx_search_latch_release_if_reserved(prebuilt->trx); - trx_search_latch_release_if_reserved(prebuilt->trx); + mutex_enter_noninline(&srv_dict_tmpfile_mutex); + rewind(srv_dict_tmpfile); - /* output the data to a temporary file */ - dict_print_info_on_foreign_keys(TRUE, file, + /* output the data to a temporary file */ + dict_print_info_on_foreign_keys(TRUE, srv_dict_tmpfile, prebuilt->trx, prebuilt->table); - prebuilt->trx->op_info = (char*)""; + prebuilt->trx->op_info = (char*)""; - flen = ftell(file); - if (flen < 0) { - flen = 0; - } else if(flen > 64000 - 1) { - flen = 64000 - 1; - } - - /* allocate buffer for the string, and - read the contents of the temporary file */ - - str = my_malloc(flen + 1, MYF(0)); - - if (str) { - rewind(file); - flen = fread(str, 1, flen, file); - str[flen] = 0; - } - - fclose(file); - } else { - /* unable to create temporary file */ - str = my_strdup( -"/* Error: cannot display foreign key constraints */", MYF(0)); + flen = ftell(srv_dict_tmpfile); + if (flen < 0) { + flen = 0; + } else if (flen > 64000 - 1) { + flen = 64000 - 1; } + /* allocate buffer for the string, and + read the contents of the temporary file */ + + str = my_malloc(flen + 1, MYF(0)); + + if (str) { + rewind(srv_dict_tmpfile); + flen = (uint) fread(str, 1, flen, srv_dict_tmpfile); + str[flen] = 0; + } + + mutex_exit_noninline(&srv_dict_tmpfile_mutex); + return(str); } diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 87529cc8713..9b84e48e970 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -40,7 +40,7 @@ TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names)-1,"", myisam_recover_names, NULL}; const char *myisam_stats_method_names[] = {"nulls_unequal", "nulls_equal", - NullS}; + "nulls_ignored", NullS}; TYPELIB myisam_stats_method_typelib= { array_elements(myisam_stats_method_names) - 1, "", myisam_stats_method_names, NULL}; diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 608dc3eaa54..594551b918a 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -50,6 +50,8 @@ static const char *ha_ndb_ext=".ndb"; #define NDB_FAILED_AUTO_INCREMENT ~(Uint64)0 #define NDB_AUTO_INCREMENT_RETRIES 10 +#define NDB_INVALID_SCHEMA_OBJECT 241 + #define ERR_PRINT(err) \ DBUG_PRINT("error", ("%d message: %s", err.code, err.message)) @@ -212,7 +214,21 @@ Thd_ndb::Thd_ndb() Thd_ndb::~Thd_ndb() { if (ndb) + { +#ifndef DBUG_OFF + Ndb::Free_list_usage tmp; tmp.m_name= 0; + while (ndb->get_free_list_usage(&tmp)) + { + uint leaked= (uint) tmp.m_created - tmp.m_free; + if (leaked) + fprintf(stderr, "NDB: Found %u %s%s that %s not been released\n", + leaked, tmp.m_name, + (leaked == 1)?"":"'s", + (leaked == 1)?"has":"have"); + } +#endif delete ndb; + } ndb= 0; } @@ -3269,14 +3285,20 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type) DBUG_PRINT("info", ("Table schema version: %d", tab->getObjectVersion())); } - if (m_table != (void *)tab || m_table_version < tab->getObjectVersion()) + if (m_table_version < tab->getObjectVersion()) { /* - The table has been altered, refresh the index list + The table has been altered, caller has to retry */ - build_index_list(ndb, table, ILBP_OPEN); + NdbError err= ndb->getNdbError(NDB_INVALID_SCHEMA_OBJECT); + DBUG_RETURN(ndb_to_mysql_error(&err)); + } + if (m_table != (void *)tab) + { m_table= (void *)tab; m_table_version = tab->getObjectVersion(); + if (!(my_errno= build_index_list(ndb, table, ILBP_OPEN))) + DBUG_RETURN(my_errno); } m_table_info= tab_info; } @@ -3711,7 +3733,7 @@ int ha_ndbcluster::create(const char *name, const void *data, *pack_data; const char **key_names= form->keynames.type_names; char name2[FN_HEADLEN]; - bool create_from_engine= (info->table_options & HA_CREATE_FROM_ENGINE); + bool create_from_engine= (info->table_options & HA_OPTION_CREATE_FROM_ENGINE); DBUG_ENTER("create"); DBUG_PRINT("enter", ("name: %s", name)); @@ -4657,7 +4679,21 @@ bool ndbcluster_end() { DBUG_ENTER("ndbcluster_end"); if(g_ndb) + { +#ifndef DBUG_OFF + Ndb::Free_list_usage tmp; tmp.m_name= 0; + while (g_ndb->get_free_list_usage(&tmp)) + { + uint leaked= (uint) tmp.m_created - tmp.m_free; + if (leaked) + fprintf(stderr, "NDB: Found %u %s%s that %s not been released\n", + leaked, tmp.m_name, + (leaked == 1)?"":"'s", + (leaked == 1)?"has":"have"); + } +#endif delete g_ndb; + } g_ndb= NULL; if (g_ndb_cluster_connection) delete g_ndb_cluster_connection; diff --git a/sql/handler.cc b/sql/handler.cc index e6bc1496a00..e166f9885fc 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1382,7 +1382,7 @@ int ha_create_table_from_engine(THD* thd, DBUG_RETURN(3); update_create_info_from_table(&create_info, &table); - create_info.table_options|= HA_CREATE_FROM_ENGINE; + create_info.table_options|= HA_OPTION_CREATE_FROM_ENGINE; if (lower_case_table_names == 2 && !(table.file->table_flags() & HA_FILE_BASED)) diff --git a/sql/item.cc b/sql/item.cc index d284af2b9f1..f996e962cca 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -211,16 +211,8 @@ bool Item::eq(const Item *item, bool binary_cmp) const Item *Item::safe_charset_converter(CHARSET_INFO *tocs) { - /* - Allow conversion from and to "binary". - Don't allow automatic conversion to non-Unicode charsets, - as it potentially loses data. - */ - if (collation.collation != &my_charset_bin && - tocs != &my_charset_bin && - !(tocs->state & MY_CS_UNICODE)) - return NULL; // safe conversion is not possible - return new Item_func_conv_charset(this, tocs); + Item_func_conv_charset *conv= new Item_func_conv_charset(this, tocs, 1); + return conv->safe ? conv : NULL; } @@ -1768,7 +1760,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) Item** res= find_item_in_list(this, thd->lex->current_select->item_list, &counter, REPORT_EXCEPT_NOT_FOUND, ¬_used); - if (res != not_found_item && (*res)->type() == Item::FIELD_ITEM) + if (res != (Item **)not_found_item && (*res)->type() == Item::FIELD_ITEM) { set_field((*((Item_field**)res))->field); return 0; @@ -2796,8 +2788,14 @@ bool Item_insert_value::fix_fields(THD *thd, Item **items) { DBUG_ASSERT(fixed == 0); + st_table_list *orig_next_table= table_list->next; + table_list->next= 0; if (!arg->fixed && arg->fix_fields(thd, table_list, &arg)) + { + table_list->next= orig_next_table; return 1; + } + table_list->next= orig_next_table; if (arg->type() == REF_ITEM) { @@ -2809,6 +2807,7 @@ bool Item_insert_value::fix_fields(THD *thd, arg= ref->ref[0]; } Item_field *field_arg= (Item_field *)arg; + if (field_arg->field->table->insert_values) { Field *def_field= (Field*) sql_alloc(field_arg->field->size_of()); @@ -2856,7 +2855,7 @@ Item_result item_cmp_type(Item_result a,Item_result b) void resolve_const_item(THD *thd, Item **ref, Item *comp_item) { Item *item= *ref; - Item *new_item; + Item *new_item= NULL; if (item->basic_const_item()) return; // Can't be better Item_result res_type=item_cmp_type(comp_item->result_type(), @@ -2885,8 +2884,17 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item) new_item= (null_value ? (Item*) new Item_null(name) : (Item*) new Item_int(name, result, length)); } - else if (res_type == ROW_RESULT) + else if (res_type == ROW_RESULT && item->type() == Item::ROW_ITEM && + comp_item->type() == Item::ROW_ITEM) { + /* + Substitute constants only in Item_rows. Don't affect other Items + with ROW_RESULT (eg Item_singlerow_subselect). + + For such Items more optimal is to detect if it is constant and replace + it with Item_row. This would optimize queries like this: + SELECT * FROM t1 WHERE (a,b) = (SELECT a,b FROM t2 LIMIT 1); + */ Item_row *item_row= (Item_row*) item; Item_row *comp_item_row= (Item_row*) comp_item; uint col; @@ -2903,7 +2911,7 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item) while (col-- > 0) resolve_const_item(thd, item_row->addr(col), comp_item_row->el(col)); } - else + else if (res_type == REAL_RESULT) { // It must REAL_RESULT double result=item->val(); uint length=item->max_length,decimals=item->decimals; @@ -3267,8 +3275,11 @@ bool Item_type_holder::join_types(THD *thd, Item *item) { int delta1= max_length_orig - decimals_orig; int delta2= item->max_length - item->decimals; - max_length= min(max(delta1, delta2) + decimals, - (fld_type == MYSQL_TYPE_FLOAT) ? FLT_DIG+6 : DBL_DIG+7); + if (fld_type == MYSQL_TYPE_DECIMAL) + max_length= max(delta1, delta2) + decimals; + else + max_length= min(max(delta1, delta2) + decimals, + (fld_type == MYSQL_TYPE_FLOAT) ? FLT_DIG+6 : DBL_DIG+7); } else max_length= (fld_type == MYSQL_TYPE_FLOAT) ? FLT_DIG+6 : DBL_DIG+7; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 2c76c7ec7b3..f9aa220c181 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2524,6 +2524,12 @@ bool Item_func_like::fix_fields(THD *thd, TABLE_LIST *tlist, Item ** ref) return 0; } +void Item_func_like::cleanup() +{ + canDoTurboBM= FALSE; + Item_bool_func2::cleanup(); +} + #ifdef USE_REGEX bool diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 045566a46d5..ade09113c63 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -911,6 +911,7 @@ public: cond_result eq_cmp_result() const { return COND_TRUE; } const char *func_name() const { return "like"; } bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref); + void cleanup(); }; #ifdef USE_REGEX diff --git a/sql/item_func.cc b/sql/item_func.cc index 019147e151f..c82d505c1bb 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1983,7 +1983,7 @@ void item_user_lock_release(User_level_lock *ull) tmp.copy(command, strlen(command), tmp.charset()); tmp.append(ull->key,ull->key_length); tmp.append("\")", 2); - Query_log_event qev(current_thd, tmp.ptr(), tmp.length(),1, FALSE); + Query_log_event qev(current_thd, tmp.ptr(), tmp.length(),0, FALSE); qev.error_code=0; // this query is always safe to run on slave mysql_bin_log.write(&qev); } @@ -3261,7 +3261,6 @@ Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name, LEX_STRING component) { sys_var *var; - char buff[MAX_SYS_VAR_LENGTH*2+4+8], *pos; LEX_STRING *base_name, *component_name; if (component.str == 0 && diff --git a/sql/item_func.h b/sql/item_func.h index 5d6cc445317..2c4976d1152 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -938,7 +938,6 @@ class user_var_entry; class Item_func_set_user_var :public Item_func { enum Item_result cached_result_type; - LEX_STRING name; user_var_entry *entry; char buffer[MAX_FIELD_WIDTH]; String value; @@ -952,6 +951,7 @@ class Item_func_set_user_var :public Item_func public: + LEX_STRING name; // keep it public Item_func_set_user_var(LEX_STRING a,Item *b) :Item_func(b), cached_result_type(INT_RESULT), name(a) {} @@ -972,10 +972,10 @@ public: class Item_func_get_user_var :public Item_func { - LEX_STRING name; user_var_entry *var_entry; public: + LEX_STRING name; // keep it public Item_func_get_user_var(LEX_STRING a): Item_func(), name(a) {} double val(); diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc index 8b856d809d6..6bd2e65632f 100644 --- a/sql/item_geofunc.cc +++ b/sql/item_geofunc.cc @@ -78,8 +78,7 @@ String *Item_func_geometry_from_wkb::val_str(String *str) str->q_append(srid); if ((null_value= (args[0]->null_value || - !Geometry::create_from_wkb(&buffer, wkb->ptr(), wkb->length()) || - str->append(*wkb)))) + !Geometry::create_from_wkb(&buffer, wkb->ptr(), wkb->length(), str)))) return 0; return str; } @@ -96,8 +95,7 @@ String *Item_func_as_wkt::val_str(String *str) if ((null_value= (args[0]->null_value || - !(geom= Geometry::create_from_wkb(&buffer, swkb->ptr() + SRID_SIZE, - swkb->length() - SRID_SIZE))))) + !(geom= Geometry::construct(&buffer, swkb->ptr(), swkb->length()))))) return 0; str->length(0); @@ -123,8 +121,7 @@ String *Item_func_as_wkb::val_str(String *str) if ((null_value= (args[0]->null_value || - !(Geometry::create_from_wkb(&buffer, swkb->ptr() + SRID_SIZE, - swkb->length() - SRID_SIZE))))) + !(Geometry::construct(&buffer, swkb->ptr(), swkb->length()))))) return 0; str->copy(swkb->ptr() + SRID_SIZE, swkb->length() - SRID_SIZE, @@ -142,8 +139,7 @@ String *Item_func_geometry_type::val_str(String *str) if ((null_value= (args[0]->null_value || - !(geom= Geometry::create_from_wkb(&buffer, swkb->ptr() + SRID_SIZE, - swkb->length() - SRID_SIZE))))) + !(geom= Geometry::construct(&buffer, swkb->ptr(), swkb->length()))))) return 0; /* String will not move */ str->copy(geom->get_class_info()->m_name.str, @@ -164,8 +160,7 @@ String *Item_func_envelope::val_str(String *str) if ((null_value= args[0]->null_value || - !(geom= Geometry::create_from_wkb(&buffer, swkb->ptr() + SRID_SIZE, - swkb->length() - SRID_SIZE)))) + !(geom= Geometry::construct(&buffer, swkb->ptr(), swkb->length())))) return 0; srid= uint4korr(swkb->ptr()); @@ -188,8 +183,7 @@ String *Item_func_centroid::val_str(String *str) uint32 srid; if ((null_value= args[0]->null_value || - !(geom= Geometry::create_from_wkb(&buffer, swkb->ptr() + SRID_SIZE, - swkb->length() - SRID_SIZE)))) + !(geom= Geometry::construct(&buffer, swkb->ptr(), swkb->length())))) return 0; str->set_charset(&my_charset_bin); @@ -218,8 +212,7 @@ String *Item_func_spatial_decomp::val_str(String *str) if ((null_value= (args[0]->null_value || - !(geom= Geometry::create_from_wkb(&buffer, swkb->ptr() + SRID_SIZE, - swkb->length() - SRID_SIZE))))) + !(geom= Geometry::construct(&buffer, swkb->ptr(), swkb->length()))))) return 0; srid= uint4korr(swkb->ptr()); @@ -267,8 +260,7 @@ String *Item_func_spatial_decomp_n::val_str(String *str) if ((null_value= (args[0]->null_value || args[1]->null_value || - !(geom= Geometry::create_from_wkb(&buffer, swkb->ptr() + SRID_SIZE, - swkb->length() - SRID_SIZE))))) + !(geom= Geometry::construct(&buffer, swkb->ptr(), swkb->length()))))) return 0; str->set_charset(&my_charset_bin); @@ -475,10 +467,8 @@ longlong Item_func_spatial_rel::val_int() if ((null_value= (args[0]->null_value || args[1]->null_value || - !(g1= Geometry::create_from_wkb(&buffer1, res1->ptr() + SRID_SIZE, - res1->length() - SRID_SIZE)) || - !(g2= Geometry::create_from_wkb(&buffer2, res2->ptr() + SRID_SIZE, - res2->length() - SRID_SIZE)) || + !(g1= Geometry::construct(&buffer1, res1->ptr(), res1->length())) || + !(g2= Geometry::construct(&buffer2, res2->ptr(), res2->length())) || g1->get_mbr(&mbr1, &dummy) || g2->get_mbr(&mbr2, &dummy)))) return 0; @@ -543,8 +533,7 @@ longlong Item_func_isclosed::val_int() null_value= (!swkb || args[0]->null_value || !(geom= - Geometry::create_from_wkb(&buffer, swkb->ptr() + SRID_SIZE, - swkb->length() - SRID_SIZE)) || + Geometry::construct(&buffer, swkb->ptr(), swkb->length())) || geom->is_closed(&isclosed)); return (longlong) isclosed; @@ -566,9 +555,7 @@ longlong Item_func_dimension::val_int() null_value= (!swkb || args[0]->null_value || - !(geom= Geometry::create_from_wkb(&buffer, - swkb->ptr() + SRID_SIZE, - swkb->length() - SRID_SIZE)) || + !(geom= Geometry::construct(&buffer, swkb->ptr(), swkb->length())) || geom->dimension(&dim, &dummy)); return (longlong) dim; } @@ -583,9 +570,8 @@ longlong Item_func_numinteriorring::val_int() Geometry *geom; null_value= (!swkb || - !(geom= Geometry::create_from_wkb(&buffer, - swkb->ptr() + SRID_SIZE, - swkb->length() - SRID_SIZE)) || + !(geom= Geometry::construct(&buffer, + swkb->ptr(), swkb->length())) || geom->num_interior_ring(&num)); return (longlong) num; } @@ -600,9 +586,8 @@ longlong Item_func_numgeometries::val_int() Geometry *geom; null_value= (!swkb || - !(geom= Geometry::create_from_wkb(&buffer, - swkb->ptr() + SRID_SIZE, - swkb->length() - SRID_SIZE)) || + !(geom= Geometry::construct(&buffer, + swkb->ptr(), swkb->length())) || geom->num_geometries(&num)); return (longlong) num; } @@ -618,9 +603,8 @@ longlong Item_func_numpoints::val_int() null_value= (!swkb || args[0]->null_value || - !(geom= Geometry::create_from_wkb(&buffer, - swkb->ptr() + SRID_SIZE, - swkb->length() - SRID_SIZE)) || + !(geom= Geometry::construct(&buffer, + swkb->ptr(), swkb->length())) || geom->num_points(&num)); return (longlong) num; } @@ -635,9 +619,8 @@ double Item_func_x::val() Geometry *geom; null_value= (!swkb || - !(geom= Geometry::create_from_wkb(&buffer, - swkb->ptr() + SRID_SIZE, - swkb->length() - SRID_SIZE)) || + !(geom= Geometry::construct(&buffer, + swkb->ptr(), swkb->length())) || geom->get_x(&res)); return res; } @@ -652,9 +635,8 @@ double Item_func_y::val() Geometry *geom; null_value= (!swkb || - !(geom= Geometry::create_from_wkb(&buffer, - swkb->ptr() + SRID_SIZE, - swkb->length() - SRID_SIZE)) || + !(geom= Geometry::construct(&buffer, + swkb->ptr(), swkb->length())) || geom->get_y(&res)); return res; } @@ -670,9 +652,8 @@ double Item_func_area::val() const char *dummy; null_value= (!swkb || - !(geom= Geometry::create_from_wkb(&buffer, - swkb->ptr() + SRID_SIZE, - swkb->length() - SRID_SIZE)) || + !(geom= Geometry::construct(&buffer, + swkb->ptr(), swkb->length())) || geom->area(&res, &dummy)); return res; } @@ -686,9 +667,8 @@ double Item_func_glength::val() Geometry *geom; null_value= (!swkb || - !(geom= Geometry::create_from_wkb(&buffer, - swkb->ptr() + SRID_SIZE, - swkb->length() - SRID_SIZE)) || + !(geom= Geometry::construct(&buffer, + swkb->ptr(), swkb->length())) || geom->length(&res)); return res; } @@ -700,9 +680,8 @@ longlong Item_func_srid::val_int() Geometry_buffer buffer; null_value= (!swkb || - !Geometry::create_from_wkb(&buffer, - swkb->ptr() + SRID_SIZE, - swkb->length() - SRID_SIZE)); + !Geometry::construct(&buffer, + swkb->ptr(), swkb->length())); if (null_value) return 0; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 6ca6ce62c54..04765e18191 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -131,11 +131,13 @@ String *Item_func_sha::val_str(String *str) SHA1_CONTEXT context; /* Context used to generate SHA1 hash */ /* Temporary buffer to store 160bit digest */ uint8 digest[SHA1_HASH_SIZE]; - sha1_reset(&context); /* We do not have to check for error here */ + mysql_sha1_reset(&context); /* We do not have to check for error here */ /* No need to check error as the only case would be too long message */ - sha1_input(&context,(const unsigned char *) sptr->ptr(), sptr->length()); + mysql_sha1_input(&context, + (const unsigned char *) sptr->ptr(), sptr->length()); /* Ensure that memory is free and we got result */ - if (!( str->alloc(SHA1_HASH_SIZE*2) || (sha1_result(&context,digest)))) + if (!( str->alloc(SHA1_HASH_SIZE*2) || + (mysql_sha1_result(&context,digest)))) { sprintf((char *) str->ptr(), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\ @@ -2252,6 +2254,8 @@ String *Item_func_conv::val_str(String *str) String *Item_func_conv_charset::val_str(String *str) { DBUG_ASSERT(fixed == 1); + if (use_cached_value) + return null_value ? 0 : &str_value; String *arg= args[0]->val_str(str); uint dummy_errors; if (!arg) diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index b01d75b8e02..89bab4a909c 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -444,12 +444,15 @@ public: class Item_func_char :public Item_str_func { public: - Item_func_char(List &list) :Item_str_func(list) {} + Item_func_char(List &list) :Item_str_func(list) + { collation.set(default_charset()); } + Item_func_char(List &list, CHARSET_INFO *cs) :Item_str_func(list) + { collation.set(cs); } String *val_str(String *); void fix_length_and_dec() { - collation.set(default_charset()); - maybe_null=0; max_length=arg_count; + maybe_null=0; + max_length=arg_count * collation.collation->mbmaxlen; } const char *func_name() const { return "char"; } }; @@ -611,10 +614,40 @@ public: class Item_func_conv_charset :public Item_str_func { - CHARSET_INFO *conv_charset; + bool use_cached_value; public: - Item_func_conv_charset(Item *a, CHARSET_INFO *cs) :Item_str_func(a) - { conv_charset=cs; } + bool safe; + CHARSET_INFO *conv_charset; // keep it public + Item_func_conv_charset(Item *a, CHARSET_INFO *cs) :Item_str_func(a) + { conv_charset= cs; use_cached_value= 0; safe= 0; } + Item_func_conv_charset(Item *a, CHARSET_INFO *cs, bool cache_if_const) + :Item_str_func(a) + { + DBUG_ASSERT(args[0]->fixed); + conv_charset= cs; + if (cache_if_const && args[0]->const_item()) + { + uint errors= 0; + String tmp, *str= args[0]->val_str(&tmp); + if (!str || str_value.copy(str->ptr(), str->length(), + str->charset(), conv_charset, &errors)) + null_value= 1; + use_cached_value= 1; + safe= (errors == 0); + } + else + { + use_cached_value= 0; + /* + Conversion from and to "binary" is safe. + Conversion to Unicode is safe. + Other kind of conversions are potentially lossy. + */ + safe= (args[0]->collation.collation == &my_charset_bin || + cs == &my_charset_bin || + (cs->state & MY_CS_UNICODE)); + } + } String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "convert"; } @@ -715,7 +748,12 @@ public: Item_func_uuid(): Item_str_func() {} void fix_length_and_dec() { collation.set(system_charset_info); - max_length= UUID_LENGTH; + /* + NOTE! uuid() should be changed to use 'ascii' + charset when hex(), format(), md5(), etc, and implicit + number-to-string conversion will use 'ascii' + */ + max_length= UUID_LENGTH * system_charset_info->mbmaxlen; } const char *func_name() const{ return "uuid"; } String *val_str(String *); diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 2c53ba82007..eb58b180ed7 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -1528,6 +1528,16 @@ void Item_func_date_format::fix_length_and_dec() if (args[1]->type() == STRING_ITEM) { // Optimize the normal case fixed_length=1; + + /* + Force case sensitive collation on format string. + This needed because format modifiers with different case, + for example %m and %M, have different meaning. Thus eq() + will distinguish them. + */ + args[1]->collation.set( + get_charset_by_csname(args[1]->collation.collation->csname, + MY_CS_BINSORT,MYF(0)), DERIVATION_COERCIBLE); /* The result is a binary string (no reason to use collation->mbmaxlen This is becasue make_date_time() only returns binary strings @@ -2371,6 +2381,7 @@ void Item_func_add_time::fix_length_and_dec() enum_field_types arg0_field_type; decimals=0; max_length=MAX_DATETIME_FULL_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; + maybe_null= 1; /* The field type for the result of an Item_func_add_time function is defined @@ -2732,7 +2743,8 @@ Field *Item_func_str_to_date::tmp_table_field(TABLE *t_arg) void Item_func_str_to_date::fix_length_and_dec() { char format_buff[64]; - String format_str(format_buff, sizeof(format_buff), &my_charset_bin), *format; + String format_str(format_buff, sizeof(format_buff), &my_charset_bin); + String *format; maybe_null= 1; decimals=0; cached_field_type= MYSQL_TYPE_STRING; diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 0df84d14bea..ce9d6b0a7aa 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -607,12 +607,12 @@ enum interval_type class Item_date_add_interval :public Item_date_func { - const interval_type int_type; String value; - const bool date_sub_interval; enum_field_types cached_field_type; public: + const interval_type int_type; // keep it public + const bool date_sub_interval; // keep it public Item_date_add_interval(Item *a,Item *b,interval_type type_arg,bool neg_arg) :Item_date_func(a,b),int_type(type_arg), date_sub_interval(neg_arg) {} String *val_str(String *); @@ -628,10 +628,10 @@ public: class Item_extract :public Item_int_func { - const interval_type int_type; String value; bool date_value; public: + const interval_type int_type; // keep it public Item_extract(interval_type type_arg, Item *a) :Item_int_func(a), int_type(type_arg) {} longlong val_int(); @@ -808,6 +808,7 @@ public: { decimals=0; max_length=MAX_TIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; + maybe_null= 1; } Field *tmp_table_field(TABLE *t_arg) { @@ -855,8 +856,8 @@ enum date_time_format class Item_func_get_format :public Item_str_func { - const timestamp_type type; public: + const timestamp_type type; // keep it public Item_func_get_format(timestamp_type type_arg, Item *a) :Item_str_func(a), type(type_arg) {} diff --git a/sql/lock.cc b/sql/lock.cc index 944c36d4d1e..f65ce69bb80 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -394,6 +394,88 @@ MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b) } +/* + Find duplicate lock in tables. + + SYNOPSIS + mysql_lock_have_duplicate() + thd The current thread. + table The table to check for duplicate lock. + tables The list of tables to search for the dup lock. + + NOTE + This is mainly meant for MERGE tables in INSERT ... SELECT + situations. The 'real', underlying tables can be found only after + the table is opened. The easier way is to check this after the + tables are locked. + + RETURN + 1 A table from 'tables' matches a lock on 'table'. + 0 No duplicate lock is present. + -1 Error. +*/ + +int mysql_lock_have_duplicate(THD *thd, TABLE *table, TABLE_LIST *tables) +{ + uint count; + MYSQL_LOCK *sql_lock1; + MYSQL_LOCK *sql_lock2; + TABLE **tables1= &table; + TABLE **tables2; + TABLE **table_ptr; + TABLE_LIST *tablist2; + TABLE *write_lock_used; + THR_LOCK_DATA **lock_data1; + THR_LOCK_DATA **end_data1; + THR_LOCK_DATA **lock_data2; + THR_LOCK_DATA **end_data2; + THR_LOCK *lock1; + DBUG_ENTER("mysql_lock_have_duplicate"); + + if (! (sql_lock1= get_lock_data(thd, tables1, 1, 1, &write_lock_used))) + goto err0; + + count=0; + for (tablist2 = tables; tablist2; tablist2= tablist2->next) + count++; + if (! (tables2= (TABLE**) sql_alloc(sizeof(TABLE*) * count))) + goto err1; + table_ptr= tables2; + for (tablist2 = tables; tablist2; tablist2= tablist2->next) + *(table_ptr++)= tablist2->table; + if (! (sql_lock2= get_lock_data(thd, tables2, count, 1, &write_lock_used))) + goto err1; + + count= 1; + for (lock_data1= sql_lock1->locks, + end_data1= lock_data1 + sql_lock1->lock_count; + lock_data1 < end_data1; + lock_data1++) + { + lock1= (*lock_data1)->lock; + for (lock_data2= sql_lock2->locks, + end_data2= lock_data2 + sql_lock2->lock_count; + lock_data2 < end_data2; + lock_data2++) + { + if ((*lock_data2)->lock == lock1) + goto end; + } + } + count= 0; + + end: + my_free((gptr) sql_lock2, MYF(0)); + my_free((gptr) sql_lock1, MYF(0)); + DBUG_RETURN(count); + + err1: + my_free((gptr) sql_lock1, MYF(0)); + err0: + DBUG_RETURN(-1); +} + + /* unlock a set of external */ static int unlock_external(THD *thd, TABLE **table,uint count) @@ -430,6 +512,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, MYSQL_LOCK *sql_lock; THR_LOCK_DATA **locks; TABLE **to; + DBUG_ENTER("get_lock_data"); *write_lock_used=0; for (i=tables=lock_count=0 ; i < count ; i++) @@ -445,7 +528,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, my_malloc(sizeof(*sql_lock)+ sizeof(THR_LOCK_DATA*)*tables+sizeof(table_ptr)*lock_count, MYF(0)))) - return 0; + DBUG_RETURN(0); locks=sql_lock->locks=(THR_LOCK_DATA**) (sql_lock+1); to=sql_lock->table=(TABLE**) (locks+tables); sql_lock->table_count=lock_count; @@ -465,7 +548,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, { my_error(ER_OPEN_AS_READONLY,MYF(0),table->table_name); my_free((gptr) sql_lock,MYF(0)); - return 0; + DBUG_RETURN(0); } } THR_LOCK_DATA **org_locks = locks; @@ -475,7 +558,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, for ( ; org_locks != locks ; org_locks++) (*org_locks)->debug_print_param= (void *) table; } - return sql_lock; + DBUG_RETURN(sql_lock); } @@ -558,6 +641,7 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list) char key[MAX_DBKEY_LENGTH]; char *db= table_list->db; uint key_length; + HASH_SEARCH_STATE state; DBUG_ENTER("lock_table_name"); DBUG_PRINT("enter",("db: %s name: %s", db, table_list->real_name)); @@ -568,9 +652,9 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list) /* Only insert the table if we haven't insert it already */ - for (table=(TABLE*) hash_search(&open_cache,(byte*) key,key_length) ; + for (table=(TABLE*) hash_first(&open_cache, (byte*)key, key_length, &state); table ; - table = (TABLE*) hash_next(&open_cache,(byte*) key,key_length)) + table = (TABLE*) hash_next(&open_cache, (byte*)key, key_length, &state)) if (table->in_use == thd) DBUG_RETURN(0); diff --git a/sql/log_event.cc b/sql/log_event.cc index be4654bccd3..3f545df5776 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2035,7 +2035,7 @@ Rotate_log_event::Rotate_log_event(THD* thd_arg, llstr(pos_arg, buff), flags)); #endif if (flags & DUP_NAME) - new_log_ident= my_strdup_with_length(new_log_ident_arg, + new_log_ident= my_strdup_with_length((byte*) new_log_ident_arg, ident_len, MYF(MY_WME)); DBUG_VOID_RETURN; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 32c5861028e..429a71b4437 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -701,7 +701,8 @@ int mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen= 0); int mysql_ha_close(THD *thd, TABLE_LIST *tables); int mysql_ha_read(THD *, TABLE_LIST *,enum enum_ha_read_modes,char *, List *,enum ha_rkey_function,Item *,ha_rows,ha_rows); -int mysql_ha_flush(THD *thd, TABLE_LIST *tables, uint mode_flags); +int mysql_ha_flush(THD *thd, TABLE_LIST *tables, uint mode_flags, + bool is_locked); /* mysql_ha_flush mode_flags bits */ #define MYSQL_HA_CLOSE_FINAL 0x00 #define MYSQL_HA_REOPEN_ON_USAGE 0x01 @@ -1021,6 +1022,7 @@ void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table); void mysql_lock_abort(THD *thd, TABLE *table); bool mysql_lock_abort_for_thread(THD *thd, TABLE *table); MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b); +int mysql_lock_have_duplicate(THD *thd, TABLE *table, TABLE_LIST *tables); bool lock_global_read_lock(THD *thd); void unlock_global_read_lock(THD *thd); bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh, bool is_not_commit); @@ -1105,6 +1107,8 @@ void change_byte(byte *,uint,char,char); void init_read_record(READ_RECORD *info, THD *thd, TABLE *reg_form, SQL_SELECT *select, int use_record_cache, bool print_errors); +void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table, + bool print_error, uint idx); void end_read_record(READ_RECORD *info); ha_rows filesort(THD *thd, TABLE *form,struct st_sort_field *sortorder, uint s_length, SQL_SELECT *select, @@ -1116,7 +1120,7 @@ int calc_weekday(long daynr,bool sunday_first_day_of_week); uint calc_week(TIME *l_time, uint week_behaviour, uint *year); void find_date(char *pos,uint *vek,uint flag); TYPELIB *convert_strings_to_array_type(my_string *typelibs, my_string *end); -TYPELIB *typelib(List &strings); +TYPELIB *typelib(MEM_ROOT *mem_root, List &strings); ulong get_form_pos(File file, uchar *head, TYPELIB *save_names); ulong make_new_entry(File file,uchar *fileinfo,TYPELIB *formnames, const char *newname); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index e1e87652255..cce48cc0d54 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3089,6 +3089,12 @@ int main(int argc, char **argv) } } #endif +#ifdef __NETWARE__ + /* Increasing stacksize of threads on NetWare */ + + pthread_attr_setstacksize(&connection_attrib, NW_THD_STACKSIZE); +#endif + thread_stack_min=thread_stack - STACK_MIN_SIZE; (void) thr_setconcurrency(concurrency); // 10 by default @@ -4370,7 +4376,7 @@ Disable with --skip-bdb (will save memory).", {"bootstrap", OPT_BOOTSTRAP, "Used by mysql installation scripts.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"character-set-client-handshake", OPT_CHARACTER_SET_CLIENT_HANDSHAKE, - "Don't use client side character set value sent during handshake.", + "Don't ignore client side character set value sent during handshake.", (gptr*) &opt_character_set_client_handshake, (gptr*) &opt_character_set_client_handshake, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, @@ -5281,7 +5287,8 @@ The minimum value for this variable is 4096.", GET_ULONG, REQUIRED_ARG, 8192*1024, 4, ~0L, 0, 1, 0}, {"myisam_stats_method", OPT_MYISAM_STATS_METHOD, "Specifies how MyISAM index statistics collection code should threat NULLs. " - "Possible values of name are \"nulls_unequal\" (default behavior for 4.1/5.0), and \"nulls_equal\" (emulate 4.0 behavior).", + "Possible values of name are \"nulls_unequal\" (default behavior for 4.1/5.0), " + "\"nulls_equal\" (emulate 4.0 behavior), and \"nulls_ignored\".", (gptr*) &myisam_stats_method_str, (gptr*) &myisam_stats_method_str, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"net_buffer_length", OPT_NET_BUFFER_LENGTH, @@ -5349,7 +5356,8 @@ The minimum value for this variable is 4096.", "Persistent buffer for query parsing and execution", (gptr*) &global_system_variables.query_prealloc_size, (gptr*) &max_system_variables.query_prealloc_size, 0, GET_ULONG, - REQUIRED_ARG, QUERY_ALLOC_PREALLOC_SIZE, 16384, ~0L, 0, 1024, 0}, + REQUIRED_ARG, QUERY_ALLOC_PREALLOC_SIZE, QUERY_ALLOC_PREALLOC_SIZE, + ~0L, 0, 1024, 0}, {"range_alloc_block_size", OPT_RANGE_ALLOC_BLOCK_SIZE, "Allocation block size for storing ranges during optimization", (gptr*) &global_system_variables.range_alloc_block_size, @@ -5948,7 +5956,7 @@ static void mysql_init_variables(void) #else have_openssl=SHOW_OPTION_NO; #endif -#if !defined(HAVE_REALPATH) || defined(HAVE_BROKEN_REALPATH) +#ifdef HAVE_BROKEN_REALPATH have_symlink=SHOW_OPTION_NO; #else have_symlink=SHOW_OPTION_YES; @@ -6474,16 +6482,26 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), } case OPT_MYISAM_STATS_METHOD: { - myisam_stats_method_str= argument; int method; + ulong method_conv; + myisam_stats_method_str= argument; if ((method=find_type(argument, &myisam_stats_method_typelib, 2)) <= 0) { fprintf(stderr, "Invalid value of myisam_stats_method: %s.\n", argument); exit(1); } - global_system_variables.myisam_stats_method= - test(method-1)? MI_STATS_METHOD_NULLS_EQUAL : - MI_STATS_METHOD_NULLS_NOT_EQUAL; + switch (method-1) { + case 0: + method_conv= MI_STATS_METHOD_NULLS_EQUAL; + break; + case 1: + method_conv= MI_STATS_METHOD_NULLS_NOT_EQUAL; + break; + case 2: + method_conv= MI_STATS_METHOD_IGNORE_NULLS; + break; + } + global_system_variables.myisam_stats_method= method_conv; break; } case OPT_SQL_MODE: @@ -6619,7 +6637,7 @@ static void get_options(int argc,char **argv) usage(); exit(0); } -#if !defined(HAVE_REALPATH) || defined(HAVE_BROKEN_REALPATH) +#if defined(HAVE_BROKEN_REALPATH) my_use_symdir=0; my_disable_symlinks=1; have_symlink=SHOW_OPTION_NO; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 5cb330100f8..71f937f90c6 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -582,6 +582,96 @@ SEL_ARG *SEL_ARG::clone_tree() return root; } + +/* + Find the best index to retrieve first N records in given order + + SYNOPSIS + get_index_for_order() + table Table to be accessed + order Required ordering + limit Number of records that will be retrieved + + DESCRIPTION + Find the best index that allows to retrieve first #limit records in the + given order cheaper then one would retrieve them using full table scan. + + IMPLEMENTATION + Run through all table indexes and find the shortest index that allows + records to be retrieved in given order. We look for the shortest index + as we will have fewer index pages to read with it. + + This function is used only by UPDATE/DELETE, so we take into account how + the UPDATE/DELETE code will work: + * index can only be scanned in forward direction + * HA_EXTRA_KEYREAD will not be used + Perhaps these assumptions could be relaxed + + RETURN + index number + MAX_KEY if no such index was found. +*/ + +uint get_index_for_order(TABLE *table, ORDER *order, ha_rows limit) +{ + uint idx; + uint match_key= MAX_KEY, match_key_len= MAX_KEY_LENGTH + 1; + ORDER *ord; + + for (ord= order; ord; ord= ord->next) + if (!ord->asc) + return MAX_KEY; + + for (idx= 0; idx < table->keys; idx++) + { + if (!(table->keys_in_use_for_query.is_set(idx))) + continue; + KEY_PART_INFO *keyinfo= table->key_info[idx].key_part; + uint partno= 0; + + /* + The below check is sufficient considering we now have either BTREE + indexes (records are returned in order for any index prefix) or HASH + indexes (records are not returned in order for any index prefix). + */ + if (!(table->file->index_flags(idx, 0, 1) & HA_READ_ORDER)) + continue; + for (ord= order; ord; ord= ord->next, partno++) + { + Item *item= order->item[0]; + if (!(item->type() == Item::FIELD_ITEM && + ((Item_field*)item)->field->eq(keyinfo[partno].field))) + break; + } + + if (!ord && table->key_info[idx].key_length < match_key_len) + { + /* + Ok, the ordering is compatible and this key is shorter then + previous match (we want shorter keys as we'll have to read fewer + index pages for the same number of records) + */ + match_key= idx; + match_key_len= table->key_info[idx].key_length; + } + } + + if (match_key != MAX_KEY) + { + /* + Found an index that allows records to be retrieved in the requested + order. Now we'll check if using the index is cheaper then doing a table + scan. + */ + double full_scan_time= table->file->scan_time(); + double index_scan_time= table->file->read_time(match_key, 1, limit); + if (index_scan_time > full_scan_time) + match_key= MAX_KEY; + } + return match_key; +} + + /* Test if a key can be used in different ranges diff --git a/sql/opt_range.h b/sql/opt_range.h index 87e0315a09e..15f0bf02b34 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -167,4 +167,6 @@ public: QUICK_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, struct st_table_ref *ref); +uint get_index_for_order(TABLE *table, ORDER *order, ha_rows limit); + #endif diff --git a/sql/password.c b/sql/password.c index 04b3a46bd48..94b9dc440be 100644 --- a/sql/password.c +++ b/sql/password.c @@ -392,15 +392,15 @@ make_scrambled_password(char *to, const char *password) SHA1_CONTEXT sha1_context; uint8 hash_stage2[SHA1_HASH_SIZE]; - sha1_reset(&sha1_context); + mysql_sha1_reset(&sha1_context); /* stage 1: hash password */ - sha1_input(&sha1_context, (uint8 *) password, strlen(password)); - sha1_result(&sha1_context, (uint8 *) to); + mysql_sha1_input(&sha1_context, (uint8 *) password, strlen(password)); + mysql_sha1_result(&sha1_context, (uint8 *) to); /* stage 2: hash stage1 output */ - sha1_reset(&sha1_context); - sha1_input(&sha1_context, (uint8 *) to, SHA1_HASH_SIZE); + mysql_sha1_reset(&sha1_context); + mysql_sha1_input(&sha1_context, (uint8 *) to, SHA1_HASH_SIZE); /* separate buffer is used to pass 'to' in octet2hex */ - sha1_result(&sha1_context, hash_stage2); + mysql_sha1_result(&sha1_context, hash_stage2); /* convert hash_stage2 to hex string */ *to++= PVERSION41_CHAR; octet2hex(to, hash_stage2, SHA1_HASH_SIZE); @@ -431,20 +431,20 @@ scramble(char *to, const char *message, const char *password) uint8 hash_stage1[SHA1_HASH_SIZE]; uint8 hash_stage2[SHA1_HASH_SIZE]; - sha1_reset(&sha1_context); + mysql_sha1_reset(&sha1_context); /* stage 1: hash password */ - sha1_input(&sha1_context, (uint8 *) password, strlen(password)); - sha1_result(&sha1_context, hash_stage1); + mysql_sha1_input(&sha1_context, (uint8 *) password, strlen(password)); + mysql_sha1_result(&sha1_context, hash_stage1); /* stage 2: hash stage 1; note that hash_stage2 is stored in the database */ - sha1_reset(&sha1_context); - sha1_input(&sha1_context, hash_stage1, SHA1_HASH_SIZE); - sha1_result(&sha1_context, hash_stage2); + mysql_sha1_reset(&sha1_context); + mysql_sha1_input(&sha1_context, hash_stage1, SHA1_HASH_SIZE); + mysql_sha1_result(&sha1_context, hash_stage2); /* create crypt string as sha1(message, hash_stage2) */; - sha1_reset(&sha1_context); - sha1_input(&sha1_context, (const uint8 *) message, SCRAMBLE_LENGTH); - sha1_input(&sha1_context, hash_stage2, SHA1_HASH_SIZE); + mysql_sha1_reset(&sha1_context); + mysql_sha1_input(&sha1_context, (const uint8 *) message, SCRAMBLE_LENGTH); + mysql_sha1_input(&sha1_context, hash_stage2, SHA1_HASH_SIZE); /* xor allows 'from' and 'to' overlap: lets take advantage of it */ - sha1_result(&sha1_context, (uint8 *) to); + mysql_sha1_result(&sha1_context, (uint8 *) to); my_crypt(to, (const uchar *) to, hash_stage1, SCRAMBLE_LENGTH); } @@ -477,17 +477,17 @@ check_scramble(const char *scramble, const char *message, uint8 buf[SHA1_HASH_SIZE]; uint8 hash_stage2_reassured[SHA1_HASH_SIZE]; - sha1_reset(&sha1_context); + mysql_sha1_reset(&sha1_context); /* create key to encrypt scramble */ - sha1_input(&sha1_context, (const uint8 *) message, SCRAMBLE_LENGTH); - sha1_input(&sha1_context, hash_stage2, SHA1_HASH_SIZE); - sha1_result(&sha1_context, buf); + mysql_sha1_input(&sha1_context, (const uint8 *) message, SCRAMBLE_LENGTH); + mysql_sha1_input(&sha1_context, hash_stage2, SHA1_HASH_SIZE); + mysql_sha1_result(&sha1_context, buf); /* encrypt scramble */ my_crypt((char *) buf, buf, (const uchar *) scramble, SCRAMBLE_LENGTH); /* now buf supposedly contains hash_stage1: so we can get hash_stage2 */ - sha1_reset(&sha1_context); - sha1_input(&sha1_context, buf, SHA1_HASH_SIZE); - sha1_result(&sha1_context, hash_stage2_reassured); + mysql_sha1_reset(&sha1_context); + mysql_sha1_input(&sha1_context, buf, SHA1_HASH_SIZE); + mysql_sha1_result(&sha1_context, hash_stage2_reassured); return memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE); } diff --git a/sql/protocol.cc b/sql/protocol.cc index 6a17ae2f95b..a2287740f1e 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -565,9 +565,23 @@ bool Protocol::send_fields(List *list, uint flag) else { /* With conversion */ + uint max_char_len; int2store(pos, thd_charset->number); - uint char_len= field.length / item->collation.collation->mbmaxlen; - int4store(pos+2, char_len * thd_charset->mbmaxlen); + /* + For TEXT/BLOB columns, field_length describes the maximum data + length in bytes. There is no limit to the number of characters + that a TEXT column can store, as long as the data fits into + the designated space. + For the rest of textual columns, field_length is evaluated as + char_count * mbmaxlen, where character count is taken from the + definition of the column. In other words, the maximum number + of characters here is limited by the column definition. + */ + max_char_len= (field.type >= (int) MYSQL_TYPE_TINY_BLOB && + field.type <= (int) MYSQL_TYPE_BLOB) ? + field.length / item->collation.collation->mbminlen : + field.length / item->collation.collation->mbmaxlen; + int4store(pos+2, max_char_len * thd_charset->mbmaxlen); } pos[6]= field.type; int2store(pos+7,field.flags); diff --git a/sql/records.cc b/sql/records.cc index e5a0d102b10..7e4a808f0c3 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -28,8 +28,52 @@ static int rr_from_pointers(READ_RECORD *info); static int rr_from_cache(READ_RECORD *info); static int init_rr_cache(READ_RECORD *info); static int rr_cmp(uchar *a,uchar *b); +static int rr_index_first(READ_RECORD *info); +static int rr_index(READ_RECORD *info); - /* init struct for read with info->read_record */ + +/* + Initialize READ_RECORD structure to perform full index scan + + SYNOPSIS + init_read_record_idx() + info READ_RECORD structure to initialize. + thd Thread handle + table Table to be accessed + print_error If true, call table->file->print_error() if an error + occurs (except for end-of-records error) + idx index to scan + + DESCRIPTION + Initialize READ_RECORD structure to perform full index scan (in forward + direction) using read_record.read_record() interface. + + This function has been added at late stage and is used only by + UPDATE/DELETE. Other statements perform index scans using + join_read_first/next functions. +*/ + +void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table, + bool print_error, uint idx) +{ + bzero((char*) info,sizeof(*info)); + info->table= table; + info->file= table->file; + info->record= table->record[0]; + info->print_error= print_error; + + table->status=0; /* And it's always found */ + if (!table->file->inited) + { + table->file->ha_index_init(idx); + table->file->extra(HA_EXTRA_RETRIEVE_PRIMARY_KEY); + } + /* read_record will be changed to rr_index in rr_index_first */ + info->read_record= rr_index_first; +} + + +/* init struct for read with info->read_record */ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table, SQL_SELECT *select, @@ -152,6 +196,21 @@ void end_read_record(READ_RECORD *info) } } +static int rr_handle_error(READ_RECORD *info, int error) +{ + if (error == HA_ERR_END_OF_FILE) + error= -1; + else + { + if (info->print_error) + info->table->file->print_error(error, MYF(0)); + if (error < 0) // Fix negative BDB errno + error= 1; + } + return error; +} + + /* Read a record from head-database */ static int rr_quick(READ_RECORD *info) @@ -166,15 +225,7 @@ static int rr_quick(READ_RECORD *info) } if (tmp != HA_ERR_RECORD_DELETED) { - if (tmp == HA_ERR_END_OF_FILE) - tmp= -1; - else - { - if (info->print_error) - info->file->print_error(tmp,MYF(0)); - if (tmp < 0) // Fix negative BDB errno - tmp=1; - } + tmp= rr_handle_error(info, tmp); break; } } @@ -182,6 +233,57 @@ static int rr_quick(READ_RECORD *info) } +/* + Reads first row in an index scan + + SYNOPSIS + rr_index_first() + info Scan info + + RETURN + 0 Ok + -1 End of records + 1 Error +*/ + + +static int rr_index_first(READ_RECORD *info) +{ + int tmp= info->file->index_first(info->record); + info->read_record= rr_index; + if (tmp) + tmp= rr_handle_error(info, tmp); + return tmp; +} + + +/* + Reads index sequentially after first row + + SYNOPSIS + rr_index() + info Scan info + + DESCRIPTION + Read the next index record (in forward direction) and translate return + value. + + RETURN + 0 Ok + -1 End of records + 1 Error +*/ + + +static int rr_index(READ_RECORD *info) +{ + int tmp= info->file->index_next(info->record); + if (tmp) + tmp= rr_handle_error(info, tmp); + return tmp; +} + + static int rr_sequential(READ_RECORD *info) { int tmp; @@ -192,17 +294,13 @@ static int rr_sequential(READ_RECORD *info) my_error(ER_SERVER_SHUTDOWN,MYF(0)); return 1; } + /* + rnd_next can return RECORD_DELETED for MyISAM when one thread is + reading and another deleting without locks. + */ if (tmp != HA_ERR_RECORD_DELETED) { - if (tmp == HA_ERR_END_OF_FILE) - tmp= -1; - else - { - if (info->print_error) - info->table->file->print_error(tmp,MYF(0)); - if (tmp < 0) // Fix negative BDB errno - tmp=1; - } + tmp= rr_handle_error(info, tmp); break; } } @@ -213,23 +311,18 @@ static int rr_sequential(READ_RECORD *info) static int rr_from_tempfile(READ_RECORD *info) { int tmp; -tryNext: - if (my_b_read(info->io_cache,info->ref_pos,info->ref_length)) - return -1; /* End of file */ - if ((tmp=info->file->rnd_pos(info->record,info->ref_pos))) + for (;;) { - if (tmp == HA_ERR_END_OF_FILE) - tmp= -1; - else if (tmp == HA_ERR_RECORD_DELETED || - (tmp == HA_ERR_KEY_NOT_FOUND && info->ignore_not_found_rows)) - goto tryNext; - else - { - if (info->print_error) - info->file->print_error(tmp,MYF(0)); - if (tmp < 0) // Fix negative BDB errno - tmp=1; - } + if (my_b_read(info->io_cache,info->ref_pos,info->ref_length)) + return -1; /* End of file */ + if (!(tmp=info->file->rnd_pos(info->record,info->ref_pos))) + break; + /* The following is extremely unlikely to happen */ + if (tmp == HA_ERR_RECORD_DELETED || + (tmp == HA_ERR_KEY_NOT_FOUND && info->ignore_not_found_rows)) + continue; + tmp= rr_handle_error(info, tmp); + break; } return tmp; } /* rr_from_tempfile */ @@ -267,26 +360,23 @@ static int rr_from_pointers(READ_RECORD *info) { int tmp; byte *cache_pos; -tryNext: - if (info->cache_pos == info->cache_end) - return -1; /* End of file */ - cache_pos=info->cache_pos; - info->cache_pos+=info->ref_length; - if ((tmp=info->file->rnd_pos(info->record,cache_pos))) + for (;;) { - if (tmp == HA_ERR_END_OF_FILE) - tmp= -1; - else if (tmp == HA_ERR_RECORD_DELETED || - (tmp == HA_ERR_KEY_NOT_FOUND && info->ignore_not_found_rows)) - goto tryNext; - else - { - if (info->print_error) - info->file->print_error(tmp,MYF(0)); - if (tmp < 0) // Fix negative BDB errno - tmp=1; - } + if (info->cache_pos == info->cache_end) + return -1; /* End of file */ + cache_pos= info->cache_pos; + info->cache_pos+= info->ref_length; + + if (!(tmp=info->file->rnd_pos(info->record,cache_pos))) + break; + + /* The following is extremely unlikely to happen */ + if (tmp == HA_ERR_RECORD_DELETED || + (tmp == HA_ERR_KEY_NOT_FOUND && info->ignore_not_found_rows)) + continue; + tmp= rr_handle_error(info, tmp); + break; } return tmp; } diff --git a/sql/share/Makefile.am b/sql/share/Makefile.am index f0207fdef03..3b13d73e8da 100644 --- a/sql/share/Makefile.am +++ b/sql/share/Makefile.am @@ -43,6 +43,13 @@ install-data-local: $(INSTALL_DATA) $(srcdir)/charsets/README $(DESTDIR)$(pkgdatadir)/charsets/README $(INSTALL_DATA) $(srcdir)/charsets/*.xml $(DESTDIR)$(pkgdatadir)/charsets +# FIXME maybe shouldn't remove, could be needed by other installation? +uninstall-local: + @RM@ -f -r $(DESTDIR)$(pkgdatadir) + +# Do nothing +link_sources: + fix_errors: for lang in @AVAILABLE_LANGUAGES@; \ do \ diff --git a/sql/share/charsets/latin5.xml b/sql/share/charsets/latin5.xml index 67e5873c503..5004f045889 100644 --- a/sql/share/charsets/latin5.xml +++ b/sql/share/charsets/latin5.xml @@ -112,11 +112,6 @@ - 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F @@ -130,10 +125,10 @@ 9C 9D 9E 9F A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB - CC CD CE CF D0 D1 D2 44 D3 D4 D5 D6 D7 D8 D9 DA - 49 DB DC DD DE DF 53 E0 E1 E2 E3 E4 5B 4C 58 E5 - CC CD CE CF D0 D1 D2 44 D3 D4 D5 D6 D7 D8 D9 DA - 49 DB DC DD DE DF 53 FA E1 E2 E3 E4 5B 4B 58 FF + 41 41 41 41 41 41 41 44 46 46 46 46 4C 4C 4C 4C + 49 51 52 52 52 52 53 E0 52 5A 5A 5A 5B 4C 58 57 + 41 41 41 41 41 41 41 44 46 46 46 46 4C 4C 4C 4C + 49 51 52 52 52 52 53 FA 52 5A 5A 5A 5B 4B 58 5F diff --git a/sql/spatial.cc b/sql/spatial.cc index 1afb7bb7dec..684f7e9ecf3 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -119,24 +119,21 @@ Geometry::Class_info *Geometry::find_class(const char *name, uint32 len) return 0; } -Geometry *Geometry::create_from_wkb(Geometry_buffer *buffer, - const char *data, uint32 data_len) + +Geometry *Geometry::construct(Geometry_buffer *buffer, + const char *data, uint32 data_len) { uint32 geom_type; Geometry *result; + char byte_order; - if (data_len < 1 + 4) + if (data_len < SRID_SIZE + WKB_HEADER_SIZE) // < 4 + (1 + 4) return NULL; - data++; - /* - FIXME: check byte ordering - Also check if we could replace this with one byte - */ - geom_type= uint4korr(data); - data+= 4; + byte_order= data[SRID_SIZE]; + geom_type= uint4korr(data + SRID_SIZE + 1); if (!(result= create_by_typeid(buffer, (int) geom_type))) return NULL; - result->m_data= data; + result->m_data= data+ SRID_SIZE + WKB_HEADER_SIZE; result->m_data_end= data + data_len; return result; } @@ -168,13 +165,71 @@ Geometry *Geometry::create_from_wkt(Geometry_buffer *buffer, return NULL; if (init_stream) { - result->init_from_wkb(wkt->ptr(), wkt->length()); + result->set_data_ptr(wkt->ptr(), wkt->length()); result->shift_wkb_header(); } return result; } +static double wkb_get_double(const char *ptr, Geometry::wkbByteOrder bo) +{ + double res; + if (bo != Geometry::wkb_xdr) + float8get(res, ptr); + else + { + char inv_array[8]; + inv_array[0]= ptr[7]; + inv_array[1]= ptr[6]; + inv_array[2]= ptr[5]; + inv_array[3]= ptr[4]; + inv_array[4]= ptr[3]; + inv_array[5]= ptr[2]; + inv_array[6]= ptr[1]; + inv_array[7]= ptr[0]; + float8get(res, inv_array); + } + return res; +} + + +static uint32 wkb_get_uint(const char *ptr, Geometry::wkbByteOrder bo) +{ + if (bo != Geometry::wkb_xdr) + return uint4korr(ptr); + /* else */ + { + char inv_array[4]; + inv_array[0]= ptr[3]; + inv_array[1]= ptr[2]; + inv_array[2]= ptr[1]; + inv_array[3]= ptr[0]; + return uint4korr(inv_array); + } +} + + +int Geometry::create_from_wkb(Geometry_buffer *buffer, + const char *wkb, uint32 len, String *res) +{ + uint32 geom_type; + Geometry *geom; + + if (len < WKB_HEADER_SIZE) + return 1; + geom_type= wkb_get_uint(wkb+1, (wkbByteOrder)wkb[0]); + if (!(geom= create_by_typeid(buffer, (int) geom_type)) || + res->reserve(WKB_HEADER_SIZE, 512)) + return 1; + + res->q_append((char) wkb_ndr); + res->q_append(geom_type); + return geom->init_from_wkb(wkb+WKB_HEADER_SIZE, len - WKB_HEADER_SIZE, + (wkbByteOrder) wkb[0], res); +} + + bool Geometry::envelope(String *result) const { MBR mbr; @@ -344,6 +399,20 @@ bool Gis_point::init_from_wkt(Gis_read_stream *trs, String *wkb) } +uint Gis_point::init_from_wkb(const char *wkb, uint len, + wkbByteOrder bo, String *res) +{ + double x, y; + if (len < POINT_DATA_SIZE || res->reserve(POINT_DATA_SIZE)) + return 0; + x= wkb_get_double(wkb, bo); + y= wkb_get_double(wkb + SIZEOF_STORED_DOUBLE, bo); + res->q_append(x); + res->q_append(y); + return POINT_DATA_SIZE; +} + + bool Gis_point::get_data_as_wkt(String *txt, const char **end) const { double x, y; @@ -413,6 +482,33 @@ bool Gis_line_string::init_from_wkt(Gis_read_stream *trs, String *wkb) } +uint Gis_line_string::init_from_wkb(const char *wkb, uint len, + wkbByteOrder bo, String *res) +{ + uint32 n_points, proper_length; + const char *wkb_end; + Gis_point p; + + if (len < 4) + return 0; + n_points= wkb_get_uint(wkb, bo); + proper_length= 4 + n_points * POINT_DATA_SIZE; + + if (len < proper_length || res->reserve(proper_length)) + return 0; + + res->q_append(n_points); + wkb_end= wkb + proper_length; + for (wkb+= 4; wkbcheck_next_symbol(')')) return 1; - ls.init_from_wkb(wkb->ptr()+ls_pos, wkb->length()-ls_pos); + ls.set_data_ptr(wkb->ptr() + ls_pos, wkb->length() - ls_pos); if (ls.is_closed(&closed) || !closed) { trs->set_error_msg("POLYGON's linear ring isn't closed"); @@ -607,6 +703,43 @@ bool Gis_polygon::init_from_wkt(Gis_read_stream *trs, String *wkb) } +uint Gis_polygon::init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, + String *res) +{ + uint32 n_linear_rings; + const char *wkb_orig= wkb; + + if (len < 4) + return 0; + + n_linear_rings= wkb_get_uint(wkb, bo); + if (res->reserve(4, 512)) + return 0; + wkb+= 4; + len-= 4; + res->q_append(n_linear_rings); + + while (n_linear_rings--) + { + Gis_line_string ls; + uint32 ls_pos= res->length(); + int ls_len; + int closed; + + if (!(ls_len= ls.init_from_wkb(wkb, len, bo, res))) + return 0; + + ls.set_data_ptr(res->ptr() + ls_pos, res->length() - ls_pos); + + if (ls.is_closed(&closed) || !closed) + return 0; + wkb+= ls_len; + } + + return (uint) (wkb - wkb_orig); +} + + bool Gis_polygon::get_data_as_wkt(String *txt, const char **end) const { uint32 n_linear_rings; @@ -895,6 +1028,36 @@ bool Gis_multi_point::init_from_wkt(Gis_read_stream *trs, String *wkb) } +uint Gis_multi_point::init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, + String *res) +{ + uint32 n_points; + uint proper_size; + Gis_point p; + const char *wkb_end; + + if (len < 4) + return 0; + n_points= wkb_get_uint(wkb, bo); + proper_size= 4 + n_points * (WKB_HEADER_SIZE + POINT_DATA_SIZE); + + if (len < proper_size || res->reserve(proper_size)) + return 0; + + res->q_append(n_points); + wkb_end= wkb + proper_size; + for (wkb+=4; wkb < wkb_end; wkb+= (WKB_HEADER_SIZE + POINT_DATA_SIZE)) + { + res->q_append((char)wkb_ndr); + res->q_append((uint32)wkb_point); + if (!p.init_from_wkb(wkb + WKB_HEADER_SIZE, + POINT_DATA_SIZE, (wkbByteOrder) wkb[0], res)) + return 0; + } + return proper_size; +} + + bool Gis_multi_point::get_data_as_wkt(String *txt, const char **end) const { uint32 n_points; @@ -1004,6 +1167,44 @@ bool Gis_multi_line_string::init_from_wkt(Gis_read_stream *trs, String *wkb) } +uint Gis_multi_line_string::init_from_wkb(const char *wkb, uint len, + wkbByteOrder bo, String *res) +{ + uint32 n_line_strings; + const char *wkb_orig= wkb; + + if (len < 4) + return 0; + n_line_strings= wkb_get_uint(wkb, bo); + + if (res->reserve(4, 512)) + return 0; + res->q_append(n_line_strings); + + wkb+= 4; + while (n_line_strings--) + { + Gis_line_string ls; + int ls_len; + + if ((len < WKB_HEADER_SIZE) || + res->reserve(WKB_HEADER_SIZE, 512)) + return 0; + + res->q_append((char) wkb_ndr); + res->q_append((uint32) wkb_linestring); + + if (!(ls_len= ls.init_from_wkb(wkb + WKB_HEADER_SIZE, len, + (wkbByteOrder) wkb[0], res))) + return 0; + ls_len+= WKB_HEADER_SIZE;; + wkb+= ls_len; + len-= ls_len; + } + return (uint) (wkb - wkb_orig); +} + + bool Gis_multi_line_string::get_data_as_wkt(String *txt, const char **end) const { @@ -1109,7 +1310,7 @@ int Gis_multi_line_string::length(double *len) const double ls_len; Gis_line_string ls; data+= WKB_HEADER_SIZE; - ls.init_from_wkb(data, (uint32) (m_data_end - data)); + ls.set_data_ptr(data, (uint32) (m_data_end - data)); if (ls.length(&ls_len)) return 1; *len+= ls_len; @@ -1138,7 +1339,7 @@ int Gis_multi_line_string::is_closed(int *closed) const Gis_line_string ls; if (no_data(data, 0)) return 1; - ls.init_from_wkb(data, (uint32) (m_data_end - data)); + ls.set_data_ptr(data, (uint32) (m_data_end - data)); if (ls.is_closed(closed)) return 1; if (!*closed) @@ -1220,6 +1421,43 @@ bool Gis_multi_polygon::init_from_wkt(Gis_read_stream *trs, String *wkb) } +uint Gis_multi_polygon::init_from_wkb(const char *wkb, uint len, + wkbByteOrder bo, String *res) +{ + uint32 n_poly; + const char *wkb_orig= wkb; + + if (len < 4) + return 0; + n_poly= wkb_get_uint(wkb, bo); + + if (res->reserve(4, 512)) + return 0; + res->q_append(n_poly); + + wkb+=4; + while (n_poly--) + { + Gis_polygon p; + int p_len; + + if (len < WKB_HEADER_SIZE || + res->reserve(WKB_HEADER_SIZE, 512)) + return 0; + res->q_append((char) wkb_ndr); + res->q_append((uint32) wkb_polygon); + + if (!(p_len= p.init_from_wkb(wkb + WKB_HEADER_SIZE, len, + (wkbByteOrder) wkb[0], res))) + return 0; + p_len+= WKB_HEADER_SIZE; + wkb+= p_len; + len-= p_len; + } + return (uint) (wkb - wkb_orig); +} + + bool Gis_multi_polygon::get_data_as_wkt(String *txt, const char **end) const { uint32 n_polygons; @@ -1356,7 +1594,7 @@ int Gis_multi_polygon::area(double *ar, const char **end_of_data) const Gis_polygon p; data+= WKB_HEADER_SIZE; - p.init_from_wkb(data, (uint32) (m_data_end - data)); + p.set_data_ptr(data, (uint32) (m_data_end - data)); if (p.area(&p_area, &data)) return 1; result+= p_area; @@ -1388,7 +1626,7 @@ int Gis_multi_polygon::centroid(String *result) const while (n_polygons--) { data+= WKB_HEADER_SIZE; - p.init_from_wkb(data, (uint32) (m_data_end - data)); + p.set_data_ptr(data, (uint32) (m_data_end - data)); if (p.area(&cur_area, &data) || p.centroid_xy(&cur_cx, &cur_cy)) return 1; @@ -1442,7 +1680,7 @@ uint32 Gis_geometry_collection::get_data_size() const if (!(geom= create_by_typeid(&buffer, wkb_type))) return GET_SIZE_ERROR; - geom->init_from_wkb(data, (uint) (m_data_end - data)); + geom->set_data_ptr(data, (uint) (m_data_end - data)); if ((object_size= geom->get_data_size()) == GET_SIZE_ERROR) return GET_SIZE_ERROR; data+= object_size; @@ -1482,6 +1720,48 @@ bool Gis_geometry_collection::init_from_wkt(Gis_read_stream *trs, String *wkb) } +uint Gis_geometry_collection::init_from_wkb(const char *wkb, uint len, + wkbByteOrder bo, String *res) +{ + uint32 n_geom; + const char *wkb_orig= wkb; + + if (len < 4) + return 0; + n_geom= wkb_get_uint(wkb, bo); + + if (res->reserve(4, 512)) + return 0; + res->q_append(n_geom); + + wkb+= 4; + while (n_geom--) + { + Geometry_buffer buffer; + Geometry *geom; + int g_len; + uint32 wkb_type; + + if (len < WKB_HEADER_SIZE || + res->reserve(WKB_HEADER_SIZE, 512)) + return 0; + + res->q_append((char) wkb_ndr); + wkb_type= wkb_get_uint(wkb+1, (wkbByteOrder) wkb[0]); + res->q_append(wkb_type); + + if (!(geom= create_by_typeid(&buffer, wkb_type)) || + !(g_len= geom->init_from_wkb(wkb + WKB_HEADER_SIZE, len, + (wkbByteOrder) wkb[0], res))) + return 0; + g_len+= WKB_HEADER_SIZE; + wkb+= g_len; + len-= g_len; + } + return (uint) (wkb - wkb_orig); +} + + bool Gis_geometry_collection::get_data_as_wkt(String *txt, const char **end) const { @@ -1506,7 +1786,7 @@ bool Gis_geometry_collection::get_data_as_wkt(String *txt, if (!(geom= create_by_typeid(&buffer, wkb_type))) return 1; - geom->init_from_wkb(data, (uint) (m_data_end - data)); + geom->set_data_ptr(data, (uint) (m_data_end - data)); if (geom->as_wkt(txt, &data)) return 1; if (txt->append(",", 1, 512)) @@ -1541,7 +1821,7 @@ bool Gis_geometry_collection::get_mbr(MBR *mbr, const char **end) const if (!(geom= create_by_typeid(&buffer, wkb_type))) return 1; - geom->init_from_wkb(data, (uint32) (m_data_end - data)); + geom->set_data_ptr(data, (uint32) (m_data_end - data)); if (geom->get_mbr(mbr, &data)) return 1; } @@ -1582,7 +1862,7 @@ int Gis_geometry_collection::geometry_n(uint32 num, String *result) const if (!(geom= create_by_typeid(&buffer, wkb_type))) return 1; - geom->init_from_wkb(data, (uint) (m_data_end - data)); + geom->set_data_ptr(data, (uint) (m_data_end - data)); if ((length= geom->get_data_size()) == GET_SIZE_ERROR) return 1; data+= length; @@ -1635,7 +1915,7 @@ bool Gis_geometry_collection::dimension(uint32 *res_dim, const char **end) const data+= WKB_HEADER_SIZE; if (!(geom= create_by_typeid(&buffer, wkb_type))) return 1; - geom->init_from_wkb(data, (uint32) (m_data_end - data)); + geom->set_data_ptr(data, (uint32) (m_data_end - data)); if (geom->dimension(&dim, &end_data)) return 1; set_if_bigger(*res_dim, dim); diff --git a/sql/spatial.h b/sql/spatial.h index b96434831a1..ec5e80e00fd 100644 --- a/sql/spatial.h +++ b/sql/spatial.h @@ -202,6 +202,10 @@ public: virtual const Class_info *get_class_info() const=0; virtual uint32 get_data_size() const=0; virtual bool init_from_wkt(Gis_read_stream *trs, String *wkb)=0; + + /* returns the length of the wkb that was read */ + virtual uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, + String *res)=0; virtual bool get_data_as_wkt(String *txt, const char **end) const=0; virtual bool get_mbr(MBR *mbr, const char **end) const=0; virtual bool dimension(uint32 *dim, const char **end) const=0; @@ -231,11 +235,13 @@ public: return my_reinterpret_cast(Geometry *)(buffer); } - static Geometry *create_from_wkb(Geometry_buffer *buffer, - const char *data, uint32 data_len); + static Geometry *construct(Geometry_buffer *buffer, + const char *data, uint32 data_len); static Geometry *create_from_wkt(Geometry_buffer *buffer, Gis_read_stream *trs, String *wkt, bool init_stream=1); + static int create_from_wkb(Geometry_buffer *buffer, + const char *wkb, uint32 len, String *res); int as_wkt(String *wkt, const char **end) { uint32 len= get_class_info()->m_name.length; @@ -249,7 +255,7 @@ public: return 0; } - inline void init_from_wkb(const char *data, uint32 data_len) + inline void set_data_ptr(const char *data, uint32 data_len) { m_data= data; m_data_end= data + data_len; @@ -293,6 +299,7 @@ class Gis_point: public Geometry public: uint32 get_data_size() const; bool init_from_wkt(Gis_read_stream *trs, String *wkb); + uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res); bool get_data_as_wkt(String *txt, const char **end) const; bool get_mbr(MBR *mbr, const char **end) const; @@ -339,6 +346,7 @@ class Gis_line_string: public Geometry public: uint32 get_data_size() const; bool init_from_wkt(Gis_read_stream *trs, String *wkb); + uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res); bool get_data_as_wkt(String *txt, const char **end) const; bool get_mbr(MBR *mbr, const char **end) const; int length(double *len) const; @@ -364,6 +372,7 @@ class Gis_polygon: public Geometry public: uint32 get_data_size() const; bool init_from_wkt(Gis_read_stream *trs, String *wkb); + uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res); bool get_data_as_wkt(String *txt, const char **end) const; bool get_mbr(MBR *mbr, const char **end) const; int area(double *ar, const char **end) const; @@ -389,6 +398,7 @@ class Gis_multi_point: public Geometry public: uint32 get_data_size() const; bool init_from_wkt(Gis_read_stream *trs, String *wkb); + uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res); bool get_data_as_wkt(String *txt, const char **end) const; bool get_mbr(MBR *mbr, const char **end) const; int num_geometries(uint32 *num) const; @@ -410,6 +420,7 @@ class Gis_multi_line_string: public Geometry public: uint32 get_data_size() const; bool init_from_wkt(Gis_read_stream *trs, String *wkb); + uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res); bool get_data_as_wkt(String *txt, const char **end) const; bool get_mbr(MBR *mbr, const char **end) const; int num_geometries(uint32 *num) const; @@ -433,6 +444,7 @@ class Gis_multi_polygon: public Geometry public: uint32 get_data_size() const; bool init_from_wkt(Gis_read_stream *trs, String *wkb); + uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res); bool get_data_as_wkt(String *txt, const char **end) const; bool get_mbr(MBR *mbr, const char **end) const; int num_geometries(uint32 *num) const; @@ -456,6 +468,7 @@ class Gis_geometry_collection: public Geometry public: uint32 get_data_size() const; bool init_from_wkt(Gis_read_stream *trs, String *wkb); + uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res); bool get_data_as_wkt(String *txt, const char **end) const; bool get_mbr(MBR *mbr, const char **end) const; int num_geometries(uint32 *num) const; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 1b5f69c7873..c1847d010c5 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -193,6 +193,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) my_bool return_val= 1; bool check_no_resolve= specialflag & SPECIAL_NO_RESOLVE; char tmp_name[NAME_LEN+1]; + int password_length; DBUG_ENTER("acl_load"); priv_version++; /* Privileges updated */ @@ -250,7 +251,9 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) init_read_record(&read_record_info,thd,table=tables[1].table,NULL,1,0); VOID(my_init_dynamic_array(&acl_users,sizeof(ACL_USER),50,100)); - if (table->field[2]->field_length < SCRAMBLED_PASSWORD_CHAR_LENGTH_323) + password_length= table->field[2]->field_length / + table->field[2]->charset()->mbmaxlen; + if (password_length < SCRAMBLED_PASSWORD_CHAR_LENGTH_323) { sql_print_error("Fatal error: mysql.user table is damaged or in " "unsupported 3.20 format."); @@ -258,10 +261,10 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) } DBUG_PRINT("info",("user table fields: %d, password length: %d", - table->fields, table->field[2]->field_length)); + table->fields, password_length)); pthread_mutex_lock(&LOCK_global_system_variables); - if (table->field[2]->field_length < SCRAMBLED_PASSWORD_CHAR_LENGTH) + if (password_length < SCRAMBLED_PASSWORD_CHAR_LENGTH) { if (opt_secure_auth) { @@ -900,7 +903,7 @@ static void acl_update_user(const char *user, const char *host, { if (!acl_user->host.hostname && !host[0] || acl_user->host.hostname && - !my_strcasecmp(&my_charset_latin1, host, acl_user->host.hostname)) + !my_strcasecmp(system_charset_info, host, acl_user->host.hostname)) { acl_user->access=privileges; if (mqh->bits & 1) @@ -979,7 +982,7 @@ static void acl_update_db(const char *user, const char *host, const char *db, { if (!acl_db->host.hostname && !host[0] || acl_db->host.hostname && - !my_strcasecmp(&my_charset_latin1, host, acl_db->host.hostname)) + !my_strcasecmp(system_charset_info, host, acl_db->host.hostname)) { if (!acl_db->db && !db[0] || acl_db->db && !strcmp(db,acl_db->db)) @@ -1125,7 +1128,7 @@ static void init_check_host(void) DBUG_ENTER("init_check_host"); VOID(my_init_dynamic_array(&acl_wild_hosts,sizeof(struct acl_host_and_ip), acl_users.elements,1)); - VOID(hash_init(&acl_check_hosts,&my_charset_latin1,acl_users.elements,0,0, + VOID(hash_init(&acl_check_hosts,system_charset_info,acl_users.elements,0,0, (hash_get_key) check_get_key,0,0)); if (!allow_all_hosts) { @@ -1141,14 +1144,14 @@ static void init_check_host(void) { // Check if host already exists acl_host_and_ip *acl=dynamic_element(&acl_wild_hosts,j, acl_host_and_ip *); - if (!my_strcasecmp(&my_charset_latin1, + if (!my_strcasecmp(system_charset_info, acl_user->host.hostname, acl->hostname)) break; // already stored } if (j == acl_wild_hosts.elements) // If new (void) push_dynamic(&acl_wild_hosts,(char*) &acl_user->host); } - else if (!hash_search(&acl_check_hosts,(byte*) &acl_user->host, + else if (!hash_search(&acl_check_hosts,(byte*) acl_user->host.hostname, (uint) strlen(acl_user->host.hostname))) { if (my_hash_insert(&acl_check_hosts,(byte*) acl_user)) @@ -1222,7 +1225,7 @@ bool check_change_password(THD *thd, const char *host, const char *user, } if (!thd->slave_thread && (strcmp(thd->user,user) || - my_strcasecmp(&my_charset_latin1, host, thd->priv_host))) + my_strcasecmp(system_charset_info, host, thd->priv_host))) { if (check_access(thd, UPDATE_ACL, "mysql",0,1,0)) return(1); @@ -1368,7 +1371,8 @@ find_acl_user(const char *host, const char *user, my_bool exact) acl_user->user && !strcmp(user,acl_user->user)) { if (exact ? !my_strcasecmp(&my_charset_latin1, host, - acl_user->host.hostname) : + acl_user->host.hostname ? + acl_user->host.hostname : "") : compare_hostname(&acl_user->host,host,host)) { DBUG_RETURN(acl_user); @@ -1431,7 +1435,7 @@ static bool compare_hostname(const acl_host_and_ip *host, const char *hostname, return (tmp & host->ip_mask) == host->ip; } return (!host->hostname || - (hostname && !wild_case_compare(&my_charset_latin1, + (hostname && !wild_case_compare(system_charset_info, hostname,host->hostname)) || (ip && !wild_compare(ip,host->hostname,0))); } @@ -1444,7 +1448,7 @@ bool hostname_requires_resolving(const char *hostname) int namelen= strlen(hostname); int lhlen= strlen(my_localhost); if ((namelen == lhlen) && - !my_strnncoll(&my_charset_latin1, (const uchar *)hostname, namelen, + !my_strnncoll(system_charset_info, (const uchar *)hostname, namelen, (const uchar *)my_localhost, strlen(my_localhost))) return FALSE; for (; (cur=*hostname); hostname++) @@ -1478,8 +1482,8 @@ static bool update_user_table(THD *thd, TABLE *table, DBUG_ENTER("update_user_table"); DBUG_PRINT("enter",("user: %s host: %s",user,host)); - table->field[0]->store(host,(uint) strlen(host), &my_charset_latin1); - table->field[1]->store(user,(uint) strlen(user), &my_charset_latin1); + table->field[0]->store(host,(uint) strlen(host), system_charset_info); + table->field[1]->store(user,(uint) strlen(user), system_charset_info); table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); if (table->file->index_read_idx(table->record[0],0, @@ -1491,7 +1495,7 @@ static bool update_user_table(THD *thd, TABLE *table, DBUG_RETURN(1); /* purecov: deadcode */ } store_record(table,record[1]); - table->field[2]->store(new_password, new_password_len, &my_charset_latin1); + table->field[2]->store(new_password, new_password_len, system_charset_info); if ((error=table->file->update_row(table->record[1],table->record[0]))) { table->file->print_error(error,MYF(0)); /* purecov: deadcode */ @@ -1556,8 +1560,8 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, password=combo.password.str; } - table->field[0]->store(combo.host.str,combo.host.length, &my_charset_latin1); - table->field[1]->store(combo.user.str,combo.user.length, &my_charset_latin1); + table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); + table->field[1]->store(combo.user.str,combo.user.length, system_charset_info); table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); if (table->file->index_read_idx(table->record[0], 0, (byte*) table->field[0]->ptr, @@ -1576,18 +1580,18 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, old_row_exists = 0; restore_record(table,default_values); // cp empty row from default_values table->field[0]->store(combo.host.str,combo.host.length, - &my_charset_latin1); + system_charset_info); table->field[1]->store(combo.user.str,combo.user.length, - &my_charset_latin1); + system_charset_info); table->field[2]->store(password, password_len, - &my_charset_latin1); + system_charset_info); } else { old_row_exists = 1; store_record(table,record[1]); // Save copy for update if (combo.password.str) // If password given - table->field[2]->store(password, password_len, &my_charset_latin1); + table->field[2]->store(password, password_len, system_charset_info); else if (!rights && !revoke_grant && thd->lex->ssl_type == SSL_TYPE_NOT_SPECIFIED && !thd->lex->mqh.bits) { @@ -1634,15 +1638,15 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, if (thd->lex->ssl_cipher) table->field[next_field+1]->store(thd->lex->ssl_cipher, strlen(thd->lex->ssl_cipher), - &my_charset_latin1); + system_charset_info); if (thd->lex->x509_issuer) table->field[next_field+2]->store(thd->lex->x509_issuer, strlen(thd->lex->x509_issuer), - &my_charset_latin1); + system_charset_info); if (thd->lex->x509_subject) table->field[next_field+3]->store(thd->lex->x509_subject, strlen(thd->lex->x509_subject), - &my_charset_latin1); + system_charset_info); break; case SSL_TYPE_NOT_SPECIFIED: break; @@ -1747,9 +1751,9 @@ static int replace_db_table(TABLE *table, const char *db, DBUG_RETURN(-1); } - table->field[0]->store(combo.host.str,combo.host.length, &my_charset_latin1); - table->field[1]->store(db,(uint) strlen(db), &my_charset_latin1); - table->field[2]->store(combo.user.str,combo.user.length, &my_charset_latin1); + table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); + table->field[1]->store(db,(uint) strlen(db), system_charset_info); + table->field[2]->store(combo.user.str,combo.user.length, system_charset_info); table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); if (table->file->index_read_idx(table->record[0],0, (byte*) table->field[0]->ptr, @@ -1763,9 +1767,9 @@ static int replace_db_table(TABLE *table, const char *db, } old_row_exists = 0; restore_record(table,default_values); // cp empty row from default_values - table->field[0]->store(combo.host.str,combo.host.length, &my_charset_latin1); - table->field[1]->store(db,(uint) strlen(db), &my_charset_latin1); - table->field[2]->store(combo.user.str,combo.user.length, &my_charset_latin1); + table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); + table->field[1]->store(db,(uint) strlen(db), system_charset_info); + table->field[2]->store(combo.user.str,combo.user.length, system_charset_info); } else { @@ -1877,7 +1881,7 @@ GRANT_TABLE::GRANT_TABLE(const char *h, const char *d,const char *u, key_length =(uint) strlen(d)+(uint) strlen(u)+(uint) strlen(t)+3; hash_key = (char*) alloc_root(&memex,key_length); strmov(strmov(strmov(hash_key,user)+1,db)+1,tname); - (void) hash_init(&hash_columns,&my_charset_latin1, + (void) hash_init(&hash_columns,system_charset_info, 0,0,0, (hash_get_key) get_key_column,0,0); } @@ -1913,17 +1917,17 @@ GRANT_TABLE::GRANT_TABLE(TABLE *form, TABLE *col_privs) privs = fix_rights_for_table(privs); cols = fix_rights_for_column(cols); - (void) hash_init(&hash_columns,&my_charset_latin1, + (void) hash_init(&hash_columns,system_charset_info, 0,0,0, (hash_get_key) get_key_column,0,0); if (cols) { int key_len; col_privs->field[0]->store(host.hostname, host.hostname ? (uint) strlen(host.hostname) : 0, - &my_charset_latin1); - col_privs->field[1]->store(db,(uint) strlen(db), &my_charset_latin1); - col_privs->field[2]->store(user,(uint) strlen(user), &my_charset_latin1); - col_privs->field[3]->store(tname,(uint) strlen(tname), &my_charset_latin1); + system_charset_info); + col_privs->field[1]->store(db,(uint) strlen(db), system_charset_info); + col_privs->field[2]->store(user,(uint) strlen(user), system_charset_info); + col_privs->field[3]->store(tname,(uint) strlen(tname), system_charset_info); key_len=(col_privs->field[0]->pack_length()+ col_privs->field[1]->pack_length()+ col_privs->field[2]->pack_length()+ @@ -1985,14 +1989,15 @@ static GRANT_TABLE *table_hash_search(const char *host,const char* ip, char helping [NAME_LEN*2+USERNAME_LENGTH+3]; uint len; GRANT_TABLE *grant_table,*found=0; + HASH_SEARCH_STATE state; len = (uint) (strmov(strmov(strmov(helping,user)+1,db)+1,tname)-helping)+ 1; - for (grant_table=(GRANT_TABLE*) hash_search(&column_priv_hash, - (byte*) helping, - len) ; + for (grant_table=(GRANT_TABLE*) hash_first(&column_priv_hash, + (byte*) helping, + len, &state) ; grant_table ; grant_table= (GRANT_TABLE*) hash_next(&column_priv_hash,(byte*) helping, - len)) + len, &state)) { if (exact) { @@ -2029,10 +2034,10 @@ static int replace_column_table(GRANT_TABLE *g_t, byte key[MAX_KEY_LENGTH]; DBUG_ENTER("replace_column_table"); - table->field[0]->store(combo.host.str,combo.host.length, &my_charset_latin1); - table->field[1]->store(db,(uint) strlen(db), &my_charset_latin1); - table->field[2]->store(combo.user.str,combo.user.length, &my_charset_latin1); - table->field[3]->store(table_name,(uint) strlen(table_name), &my_charset_latin1); + table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); + table->field[1]->store(db,(uint) strlen(db), system_charset_info); + table->field[2]->store(combo.user.str,combo.user.length, system_charset_info); + table->field[3]->store(table_name,(uint) strlen(table_name), system_charset_info); key_length=(table->field[0]->pack_length()+ table->field[1]->pack_length()+ table->field[2]->pack_length()+ table->field[3]->pack_length()); key_copy(key,table,0,key_length); @@ -2050,7 +2055,7 @@ static int replace_column_table(GRANT_TABLE *g_t, bool old_row_exists=0; key_restore(table,key,0,key_length); table->field[4]->store(xx->column.ptr(),xx->column.length(), - &my_charset_latin1); + system_charset_info); table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); if (table->file->index_read(table->record[0],(byte*) table->field[0]->ptr, @@ -2068,7 +2073,7 @@ static int replace_column_table(GRANT_TABLE *g_t, restore_record(table,default_values); // Get empty record key_restore(table,key,0,key_length); table->field[4]->store(xx->column.ptr(),xx->column.length(), - &my_charset_latin1); + system_charset_info); } else { @@ -2140,7 +2145,8 @@ static int replace_column_table(GRANT_TABLE *g_t, { GRANT_COLUMN *grant_column = NULL; char colum_name_buf[HOSTNAME_LENGTH+1]; - String column_name(colum_name_buf,sizeof(colum_name_buf),&my_charset_latin1); + String column_name(colum_name_buf,sizeof(colum_name_buf), + system_charset_info); privileges&= ~rights; table->field[6]->store((longlong) @@ -2210,10 +2216,10 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, } restore_record(table,default_values); // Get empty record - table->field[0]->store(combo.host.str,combo.host.length, &my_charset_latin1); - table->field[1]->store(db,(uint) strlen(db), &my_charset_latin1); - table->field[2]->store(combo.user.str,combo.user.length, &my_charset_latin1); - table->field[3]->store(table_name,(uint) strlen(table_name), &my_charset_latin1); + table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); + table->field[1]->store(db,(uint) strlen(db), system_charset_info); + table->field[2]->store(combo.user.str,combo.user.length, system_charset_info); + table->field[3]->store(table_name,(uint) strlen(table_name), system_charset_info); store_record(table,record[1]); // store at pos 1 table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); if (table->file->index_read_idx(table->record[0],0, @@ -2258,7 +2264,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, } } - table->field[4]->store(grantor,(uint) strlen(grantor), &my_charset_latin1); + table->field[4]->store(grantor,(uint) strlen(grantor), system_charset_info); table->field[6]->store((longlong) store_table_rights); table->field[7]->store((longlong) store_col_rights); rights=fix_rights_for_table(store_table_rights); @@ -2724,7 +2730,7 @@ static my_bool grant_load(TABLE_LIST *tables) DBUG_ENTER("grant_load"); grant_option = FALSE; - (void) hash_init(&column_priv_hash,&my_charset_latin1, + (void) hash_init(&column_priv_hash,system_charset_info, 0,0,0, (hash_get_key) get_grant_table, (hash_free_key) free_grant_table,0); init_sql_alloc(&memex, ACL_ALLOC_BLOCK_SIZE, 0); @@ -3203,7 +3209,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) if (!(host=acl_user->host.hostname)) host= ""; if (!strcmp(lex_user->user.str,user) && - !my_strcasecmp(&my_charset_latin1, lex_user->host.str, host)) + !my_strcasecmp(system_charset_info, lex_user->host.str, host)) break; } if (counter == acl_users.elements) @@ -3337,7 +3343,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) host= ""; if (!strcmp(lex_user->user.str,user) && - !my_strcasecmp(&my_charset_latin1, lex_user->host.str, host)) + !my_strcasecmp(system_charset_info, lex_user->host.str, host)) { want_access=acl_db->access; if (want_access) @@ -3397,7 +3403,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) user= ""; if (!strcmp(lex_user->user.str,user) && - !my_strcasecmp(&my_charset_latin1, lex_user->host.str, + !my_strcasecmp(system_charset_info, lex_user->host.str, grant_table->host.hostname)) { ulong table_access= grant_table->privs; @@ -3600,7 +3606,7 @@ ACL_USER *check_acl_user(LEX_USER *user_name, if (!(user=acl_user->user)) user= ""; if (!(host=acl_user->host.hostname)) - host= "%"; + host= ""; if (!strcmp(user_name->user.str,user) && !my_strcasecmp(system_charset_info, user_name->host.str, host)) break; @@ -3715,17 +3721,25 @@ int mysql_drop_user(THD *thd, List &list) record[0]))) { tables[0].table->file->print_error(error, MYF(0)); - DBUG_RETURN(-1); + result= -1; + goto end; } delete_dynamic_element(&acl_users, acl_userd); } } + if (result) + my_error(ER_DROP_USER, MYF(0)); + +end: + /* Reload acl_check_hosts as its memory is mapped to acl_user */ + delete_dynamic(&acl_wild_hosts); + hash_free(&acl_check_hosts); + init_check_host(); + VOID(pthread_mutex_unlock(&acl_cache->lock)); rw_unlock(&LOCK_grant); close_thread_tables(thd); - if (result) - my_error(ER_DROP_USER, MYF(0)); DBUG_RETURN(result); } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index b48f2537069..ea013bb4e1e 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -306,7 +306,8 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh, thd->proc_info="Flushing tables"; close_old_data_files(thd,thd->open_tables,1,1); - mysql_ha_flush(thd, tables, MYSQL_HA_REOPEN_ON_USAGE | MYSQL_HA_FLUSH_ALL); + mysql_ha_flush(thd, tables, MYSQL_HA_REOPEN_ON_USAGE | MYSQL_HA_FLUSH_ALL, + TRUE); bool found=1; /* Wait until all threads has closed all the tables we had locked */ DBUG_PRINT("info", @@ -798,6 +799,7 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name, reg1 TABLE *table; char key[MAX_DBKEY_LENGTH]; uint key_length; + HASH_SEARCH_STATE state; DBUG_ENTER("open_table"); /* find a unused table in the open table cache */ @@ -860,11 +862,13 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name, } /* close handler tables which are marked for flush */ - mysql_ha_flush(thd, (TABLE_LIST*) NULL, MYSQL_HA_REOPEN_ON_USAGE); + mysql_ha_flush(thd, (TABLE_LIST*) NULL, MYSQL_HA_REOPEN_ON_USAGE, TRUE); - for (table=(TABLE*) hash_search(&open_cache,(byte*) key,key_length) ; + for (table= (TABLE*) hash_first(&open_cache, (byte*) key, key_length, + &state); table && table->in_use ; - table = (TABLE*) hash_next(&open_cache,(byte*) key,key_length)) + table= (TABLE*) hash_next(&open_cache, (byte*) key, key_length, + &state)) { if (table->version != refresh_version) { @@ -1008,10 +1012,20 @@ TABLE *find_locked_table(THD *thd, const char *db,const char *table_name) /**************************************************************************** -** Reopen an table because the definition has changed. The date file for the -** table is already closed. -** Returns 0 if ok. -** If table can't be reopened, the entry is unchanged. + Reopen an table because the definition has changed. The date file for the + table is already closed. + + SYNOPSIS + reopen_table() + table Table to be opened + locked 1 if we have already a lock on LOCK_open + + NOTES + table->query_id will be 0 if table was reopened + + RETURN + 0 ok + 1 error ('table' is unchanged if table couldn't be reopened) ****************************************************************************/ bool reopen_table(TABLE *table,bool locked) @@ -1081,8 +1095,10 @@ bool reopen_table(TABLE *table,bool locked) (*field)->table_name=table->table_name; } for (key=0 ; key < table->keys ; key++) + { for (part=0 ; part < table->key_info[key].usable_key_parts ; part++) table->key_info[key].key_part[part].field->table= table; + } VOID(pthread_cond_broadcast(&COND_refresh)); error=0; @@ -1235,12 +1251,14 @@ bool table_is_used(TABLE *table, bool wait_for_name_lock) { do { + HASH_SEARCH_STATE state; char *key= table->table_cache_key; uint key_length=table->key_length; - for (TABLE *search=(TABLE*) hash_search(&open_cache, - (byte*) key,key_length) ; + for (TABLE *search= (TABLE*) hash_first(&open_cache, (byte*) key, + key_length, &state); search ; - search = (TABLE*) hash_next(&open_cache,(byte*) key,key_length)) + search= (TABLE*) hash_next(&open_cache, (byte*) key, + key_length, &state)) { if (search->locked_by_flush || search->locked_by_name && wait_for_name_lock || @@ -1265,7 +1283,7 @@ bool wait_for_tables(THD *thd) { thd->some_tables_deleted=0; close_old_data_files(thd,thd->open_tables,0,dropping_tables != 0); - mysql_ha_flush(thd, (TABLE_LIST*) NULL, MYSQL_HA_REOPEN_ON_USAGE); + mysql_ha_flush(thd, (TABLE_LIST*) NULL, MYSQL_HA_REOPEN_ON_USAGE, TRUE); if (!table_is_used(thd->open_tables,1)) break; (void) pthread_cond_wait(&COND_refresh,&LOCK_open); @@ -2957,11 +2975,14 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name, key_length=(uint) (strmov(strmov(key,db)+1,table_name)-key)+1; for (;;) { + HASH_SEARCH_STATE state; result= signalled= 0; - for (table=(TABLE*) hash_search(&open_cache,(byte*) key,key_length) ; + for (table= (TABLE*) hash_first(&open_cache, (byte*) key, key_length, + &state); table; - table = (TABLE*) hash_next(&open_cache,(byte*) key,key_length)) + table= (TABLE*) hash_next(&open_cache, (byte*) key, key_length, + &state)) { THD *in_use; table->version=0L; /* Free when thread is ready */ diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 4214c9a7c07..457478e90db 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -956,16 +956,26 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) goto err; } - /* - Test if the query is a SELECT - (pre-space is removed in dispatch_command) - */ - if (my_toupper(system_charset_info, sql[0]) != 'S' || - my_toupper(system_charset_info, sql[1]) != 'E' || - my_toupper(system_charset_info,sql[2]) !='L') { - DBUG_PRINT("qcache", ("The statement is not a SELECT; Not cached")); - goto err; + uint i= 0; + /* + Skip '(' characters in queries like following: + (select a from t1) union (select a from t1); + */ + while (sql[i]=='(') + i++; + + /* + Test if the query is a SELECT + (pre-space is removed in dispatch_command) + */ + if (my_toupper(system_charset_info, sql[i]) != 'S' || + my_toupper(system_charset_info, sql[i + 1]) != 'E' || + my_toupper(system_charset_info, sql[i + 2]) != 'L') + { + DBUG_PRINT("qcache", ("The statement is not a SELECT; Not cached")); + goto err; + } } STRUCT_LOCK(&structure_guard_mutex); @@ -2863,6 +2873,7 @@ my_bool Query_cache::move_by_type(byte **border, } case Query_cache_block::TABLE: { + HASH_SEARCH_STATE record_idx; DBUG_PRINT("qcache", ("block 0x%lx TABLE", (ulong) block)); if (*border == 0) break; @@ -2880,7 +2891,7 @@ my_bool Query_cache::move_by_type(byte **border, byte *key; uint key_length; key=query_cache_table_get_key((byte*) block, &key_length, 0); - hash_search(&tables, (byte*) key, key_length); + hash_first(&tables, (byte*) key, key_length, &record_idx); block->destroy(); new_block->init(len); @@ -2914,7 +2925,7 @@ my_bool Query_cache::move_by_type(byte **border, /* Fix pointer to table name */ new_block->table()->table(new_block->table()->db() + tablename_offset); /* Fix hash to point at moved block */ - hash_replace(&tables, tables.current_record, (byte*) new_block); + hash_replace(&tables, &record_idx, (byte*) new_block); DBUG_PRINT("qcache", ("moved %lu bytes to 0x%lx, new gap at 0x%lx", len, (ulong) new_block, (ulong) *border)); @@ -2922,6 +2933,7 @@ my_bool Query_cache::move_by_type(byte **border, } case Query_cache_block::QUERY: { + HASH_SEARCH_STATE record_idx; DBUG_PRINT("qcache", ("block 0x%lx QUERY", (ulong) block)); if (*border == 0) break; @@ -2939,7 +2951,7 @@ my_bool Query_cache::move_by_type(byte **border, byte *key; uint key_length; key=query_cache_query_get_key((byte*) block, &key_length, 0); - hash_search(&queries, (byte*) key, key_length); + hash_first(&queries, (byte*) key, key_length, &record_idx); // Move table of used tables memmove((char*) new_block->table(0), (char*) block->table(0), ALIGN_SIZE(n_tables*sizeof(Query_cache_block_table))); @@ -3007,7 +3019,7 @@ my_bool Query_cache::move_by_type(byte **border, net->query_cache_query= (gptr) new_block; } /* Fix hash to point at moved block */ - hash_replace(&queries, queries.current_record, (byte*) new_block); + hash_replace(&queries, &record_idx, (byte*) new_block); DBUG_PRINT("qcache", ("moved %lu bytes to 0x%lx, new gap at 0x%lx", len, (ulong) new_block, (ulong) *border)); break; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 947da6b10d6..ef938a13489 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -353,7 +353,7 @@ void THD::cleanup(void) close_thread_tables(this); } mysql_ha_flush(this, (TABLE_LIST*) 0, - MYSQL_HA_CLOSE_FINAL | MYSQL_HA_FLUSH_ALL); + MYSQL_HA_CLOSE_FINAL | MYSQL_HA_FLUSH_ALL, FALSE); hash_free(&handler_tables_hash); delete_dynamic(&user_var_events); hash_free(&user_vars); diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 1dd52a2ba74..203173f52f4 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -37,6 +37,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, bool using_limit=limit != HA_POS_ERROR; bool transactional_table, log_delayed, safe_update, const_cond; ha_rows deleted; + uint usable_index= MAX_KEY; DBUG_ENTER("mysql_delete"); if ((open_and_lock_tables(thd, table_list))) @@ -119,30 +120,47 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, tables.table = table; tables.alias = table_list->alias; - table->sort.io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE), - MYF(MY_FAE | MY_ZEROFILL)); if (thd->lex->select_lex.setup_ref_array(thd, order->elements) || setup_order(thd, thd->lex->select_lex.ref_pointer_array, &tables, - fields, all_fields, (ORDER*) order->first) || - !(sortorder=make_unireg_sortorder((ORDER*) order->first, &length)) || - (table->sort.found_records = filesort(thd, table, sortorder, length, - select, HA_POS_ERROR, - &examined_rows)) - == HA_POS_ERROR) + fields, all_fields, (ORDER*) order->first)) { delete select; free_underlaid_joins(thd, &thd->lex->select_lex); DBUG_RETURN(-1); // This will force out message } - /* - Filesort has already found and selected the rows we want to delete, - so we don't need the where clause - */ - delete select; - select= 0; + + if (!select && limit != HA_POS_ERROR) + usable_index= get_index_for_order(table, (ORDER*)(order->first), limit); + + if (usable_index == MAX_KEY) + { + table->sort.io_cache= (IO_CACHE *) my_malloc(sizeof(IO_CACHE), + MYF(MY_FAE | MY_ZEROFILL)); + + if ( !(sortorder=make_unireg_sortorder((ORDER*) order->first, &length)) || + (table->sort.found_records = filesort(thd, table, sortorder, length, + select, HA_POS_ERROR, + &examined_rows)) + == HA_POS_ERROR) + { + delete select; + free_underlaid_joins(thd, &thd->lex->select_lex); + DBUG_RETURN(-1); // This will force out message + } + /* + Filesort has already found and selected the rows we want to delete, + so we don't need the where clause + */ + delete select; + select= 0; + } } - init_read_record(&info,thd,table,select,1,1); + if (usable_index==MAX_KEY) + init_read_record(&info,thd,table,select,1,1); + else + init_read_record_idx(&info, thd, table, 1, usable_index); + deleted=0L; init_ftfuncs(thd, &thd->lex->select_lex, 1); thd->proc_info="updating"; @@ -223,6 +241,7 @@ cleanup: if (!log_delayed) thd->options|=OPTION_STATUS_NO_TRANS_UPDATE; } + free_underlaid_joins(thd, &thd->lex->select_lex); if (transactional_table) { if (ha_autocommit_or_rollback(thd,error >= 0)) @@ -234,7 +253,6 @@ cleanup: mysql_unlock_tables(thd, thd->lock); thd->lock=0; } - free_underlaid_joins(thd, &thd->lex->select_lex); if (error >= 0 || thd->net.report_error) send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN: 0); else diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 491b82c1c1d..1c5381a9fa0 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -354,6 +354,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, ha_rows select_limit,ha_rows offset_limit) { TABLE_LIST *hash_tables; + TABLE **table_ptr; TABLE *table; MYSQL_LOCK *lock; List list; @@ -429,9 +430,21 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, } tables->table=table; - if (cond && ((!cond->fixed && - cond->fix_fields(thd, tables, &cond)) || cond->check_cols(1))) - goto err0; + HANDLER_TABLES_HACK(thd); + lock= mysql_lock_tables(thd, &tables->table, 1, 0); + HANDLER_TABLES_HACK(thd); + + if (!lock) + goto err0; // mysql_lock_tables() printed error message already + + if (cond) + { + if (table->query_id != thd->query_id) + cond->cleanup(); // File was reopened + if ((!cond->fixed && + cond->fix_fields(thd, tables, &cond)) || cond->check_cols(1)) + goto err0; + } if (keyname) { @@ -449,13 +462,6 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, select_limit+=offset_limit; protocol->send_fields(&list,1); - HANDLER_TABLES_HACK(thd); - lock= mysql_lock_tables(thd, &tables->table, 1, 0); - HANDLER_TABLES_HACK(thd); - - if (!lock) - goto err0; // mysql_lock_tables() printed error message already - /* In ::external_lock InnoDB resets the fields which tell it that the handle is used in the HANDLER interface. Tell it again that @@ -616,6 +622,7 @@ err0: MYSQL_HA_REOPEN_ON_USAGE mark for reopen. MYSQL_HA_FLUSH_ALL flush all tables, not only those marked for flush. + is_locked If LOCK_open is locked. DESCRIPTION The list of HANDLER tables may be NULL, in which case all HANDLER @@ -623,7 +630,6 @@ err0: If 'tables' is NULL and MYSQL_HA_FLUSH_ALL is not set, all HANDLER tables marked for flush are closed. Broadcasts a COND_refresh condition, for every table closed. - The caller must lock LOCK_open. NOTE Since mysql_ha_flush() is called when the base table has to be closed, @@ -633,10 +639,12 @@ err0: 0 ok */ -int mysql_ha_flush(THD *thd, TABLE_LIST *tables, uint mode_flags) +int mysql_ha_flush(THD *thd, TABLE_LIST *tables, uint mode_flags, + bool is_locked) { TABLE_LIST *tmp_tables; TABLE **table_ptr; + bool did_lock= FALSE; DBUG_ENTER("mysql_ha_flush"); DBUG_PRINT("enter", ("tables: %p mode_flags: 0x%02x", tables, mode_flags)); @@ -662,6 +670,12 @@ int mysql_ha_flush(THD *thd, TABLE_LIST *tables, uint mode_flags) (*table_ptr)->table_cache_key, (*table_ptr)->real_name, (*table_ptr)->table_name)); + /* The first time it is required, lock for close_thread_table(). */ + if (! did_lock && ! is_locked) + { + VOID(pthread_mutex_lock(&LOCK_open)); + did_lock= TRUE; + } mysql_ha_flush_table(thd, table_ptr, mode_flags); continue; } @@ -680,6 +694,12 @@ int mysql_ha_flush(THD *thd, TABLE_LIST *tables, uint mode_flags) if ((mode_flags & MYSQL_HA_FLUSH_ALL) || ((*table_ptr)->version != refresh_version)) { + /* The first time it is required, lock for close_thread_table(). */ + if (! did_lock && ! is_locked) + { + VOID(pthread_mutex_lock(&LOCK_open)); + did_lock= TRUE; + } mysql_ha_flush_table(thd, table_ptr, mode_flags); continue; } @@ -687,6 +707,10 @@ int mysql_ha_flush(THD *thd, TABLE_LIST *tables, uint mode_flags) } } + /* Release the lock if it was taken by this function. */ + if (did_lock) + VOID(pthread_mutex_unlock(&LOCK_open)); + DBUG_RETURN(0); } @@ -718,8 +742,8 @@ static int mysql_ha_flush_table(THD *thd, TABLE **table_ptr, uint mode_flags) table->table_name, mode_flags)); if ((hash_tables= (TABLE_LIST*) hash_search(&thd->handler_tables_hash, - (byte*) (*table_ptr)->table_name, - strlen((*table_ptr)->table_name) + 1))) + (byte*) table->table_name, + strlen(table->table_name) + 1))) { if (! (mode_flags & MYSQL_HA_REOPEN_ON_USAGE)) { @@ -733,6 +757,7 @@ static int mysql_ha_flush_table(THD *thd, TABLE **table_ptr, uint mode_flags) } } + safe_mutex_assert_owner(&LOCK_open); (*table_ptr)->file->ha_index_or_rnd_end(); if (close_thread_table(thd, table_ptr)) { diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 8c6fed26f8e..283fe571d53 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -194,7 +194,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, runs without --log-update or --log-bin). */ int log_on= DELAYED_LOG_UPDATE | DELAYED_LOG_BIN ; - bool transactional_table, log_delayed; + bool transactional_table, log_delayed, joins_freed= FALSE; uint value_count; ulong counter = 1; ulonglong id; @@ -386,6 +386,9 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, thd->row_count++; } + free_underlaid_joins(thd, &thd->lex->select_lex); + joins_freed= TRUE; + /* Now all rows are inserted. Time to update logs and sends response to user @@ -480,7 +483,6 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, (ulong) (info.deleted+info.updated), (ulong) thd->cuted_fields); ::send_ok(thd,info.copied+info.deleted+info.updated,(ulonglong)id,buff); } - free_underlaid_joins(thd, &thd->lex->select_lex); table->insert_values=0; DBUG_RETURN(0); @@ -489,7 +491,8 @@ abort: if (lock_type == TL_WRITE_DELAYED) end_delayed_insert(thd); #endif - free_underlaid_joins(thd, &thd->lex->select_lex); + if (!joins_freed) + free_underlaid_joins(thd, &thd->lex->select_lex); table->insert_values=0; DBUG_RETURN(-1); } diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 4d09da70ef7..aa4ea3e6c8c 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -806,8 +806,20 @@ int READ_INFO::read_field() *to++= (byte) escape_char; goto found_eof; } - *to++ = (byte) unescape((char) chr); - continue; + /* + When escape_char == enclosed_char, we treat it like we do for + handling quotes in SQL parsing -- you can double-up the + escape_char to include it literally, but it doesn't do escapes + like \n. This allows: LOAD DATA ... ENCLOSED BY '"' ESCAPED BY '"' + with data like: "fie""ld1", "field2" + */ + if (escape_char != enclosed_char || chr == escape_char) + { + *to++ = (byte) unescape((char) chr); + continue; + } + PUSH(chr); + chr= escape_char; } #ifdef ALLOW_LINESEPARATOR_IN_STRINGS if (chr == line_term_char) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index a2ad8a414f8..90de630da60 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -689,6 +689,9 @@ static int check_connection(THD *thd) DBUG_PRINT("info", ("New connection received on %s", vio_description(net->vio))); +#ifdef SIGNAL_WITH_VIO_CLOSE + thd->set_active_vio(net->vio); +#endif if (!thd->host) // If TCP/IP connection { @@ -2894,16 +2897,17 @@ unsent_create_error: if (unit->select_limit_cnt < select_lex->select_limit) unit->select_limit_cnt= HA_POS_ERROR; // No limit - if (find_real_table_in_list(tables->next, tables->db, tables->real_name)) + if ((res= open_and_lock_tables(thd, tables))) + break; + + insert_table= tables->table; + /* MERGE sub-tables can only be detected after open. */ + if (mysql_lock_have_duplicate(thd, insert_table, tables->next)) { /* Using same table for INSERT and SELECT */ select_lex->options |= OPTION_BUFFER_RESULT; } - if ((res= open_and_lock_tables(thd, tables))) - break; - - insert_table= tables->table; /* Skip first table, which is the table we are inserting in */ select_lex->table_list.first= (byte*) first_local_table->next; tables= (TABLE_LIST *) select_lex->table_list.first; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index c485d6cd04e..1b09913dcc8 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -69,8 +69,6 @@ static int return_zero_rows(JOIN *join, select_result *res,TABLE_LIST *tables, SELECT_LEX_UNIT *unit); static COND *optimize_cond(THD *thd, COND *conds, Item::cond_result *cond_value); -static COND *remove_eq_conds(THD *thd, COND *cond, - Item::cond_result *cond_value); static bool const_expression_in_where(COND *conds,Item *item, Item **comp_item); static bool open_tmp_table(TABLE *table); static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param, @@ -289,7 +287,7 @@ JOIN::prepare(Item ***rref_pointer_array, if (having_fix_rc || thd->net.report_error) DBUG_RETURN(-1); /* purecov: inspected */ if (having->with_sum_func) - having->split_sum_func(thd, ref_pointer_array, all_fields); + having->split_sum_func2(thd, ref_pointer_array, all_fields, &having); } // Is it subselect @@ -689,6 +687,7 @@ JOIN::optimize() { order=0; // The output has only one row simple_order=1; + select_distinct= 0; // No need in distinct for 1 row } calc_group_buffer(this, group_list); @@ -1043,18 +1042,21 @@ JOIN::save_join_tab() void JOIN::exec() { + List *columns_list= &fields_list; int tmp_error; DBUG_ENTER("JOIN::exec"); error= 0; if (procedure) { - if (procedure->change_columns(fields_list) || - result->prepare(fields_list, unit)) + procedure_fields_list= fields_list; + if (procedure->change_columns(procedure_fields_list) || + result->prepare(procedure_fields_list, unit)) { thd->limit_found_rows= thd->examined_row_count= 0; DBUG_VOID_RETURN; } + columns_list= &procedure_fields_list; } else if (test(select_options & OPTION_BUFFER_RESULT) && result && result->prepare(fields_list, unit)) @@ -1071,7 +1073,7 @@ JOIN::exec() (zero_result_cause?zero_result_cause:"No tables used")); else { - result->send_fields(fields_list,1); + result->send_fields(*columns_list, 1); /* We have to test for 'conds' here as the WHERE may not be constant even if we don't have any tables for prepared statements or if @@ -1081,9 +1083,9 @@ JOIN::exec() (!conds || conds->val_int()) && (!having || having->val_int())) { - if (do_send_rows && (procedure ? (procedure->send_row(fields_list) || - procedure->end_of_records()) - : result->send_data(fields_list))) + if (do_send_rows && + (procedure ? (procedure->send_row(procedure_fields_list) || + procedure->end_of_records()) : result->send_data(fields_list))) error= 1; else { @@ -1107,7 +1109,7 @@ JOIN::exec() if (zero_result_cause) { - (void) return_zero_rows(this, result, tables_list, fields_list, + (void) return_zero_rows(this, result, tables_list, *columns_list, send_row_on_empty_set(), select_options, zero_result_cause, @@ -4611,7 +4613,7 @@ optimize_cond(THD *thd, COND *conds, Item::cond_result *cond_value) COND_FALSE always false ( 1 = 2 ) */ -static COND * +COND * remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value) { if (cond->type() == Item::COND_ITEM) @@ -5290,7 +5292,14 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, *(reg_field++) =new_field; } if (!--hidden_field_count) + { hidden_null_count=null_count; + /* + We need to update hidden_field_count as we may have stored group + functions with constant arguments + */ + param->hidden_field_count= (uint) (reg_field - table->field); + } } DBUG_ASSERT(field_count >= (uint) (reg_field - table->field)); field_count= (uint) (reg_field - table->field); @@ -5486,7 +5495,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, } } - if (distinct) + if (distinct && field_count != param->hidden_field_count) { /* Create an unique key or an unique constraint over all columns @@ -5844,13 +5853,13 @@ do_select(JOIN *join,List *fields,TABLE *table,Procedure *procedure) JOIN_TAB *join_tab; int (*end_select)(JOIN *, struct st_join_table *,bool); DBUG_ENTER("do_select"); - + List *columns_list= procedure ? &join->procedure_fields_list : fields; join->procedure=procedure; /* Tell the client how many fields there are in a row */ if (!table) - join->result->send_fields(*fields,1); + join->result->send_fields(*columns_list, 1); else { VOID(table->file->extra(HA_EXTRA_WRITE_CACHE)); @@ -5912,7 +5921,7 @@ do_select(JOIN *join,List *fields,TABLE *table,Procedure *procedure) error=(*end_select)(join,join_tab,1); } else if (join->send_row_on_empty_set()) - error= join->result->send_data(*join->fields); + error= join->result->send_data(*columns_list); } else { @@ -5940,21 +5949,19 @@ do_select(JOIN *join,List *fields,TABLE *table,Procedure *procedure) } if (table) { - int tmp; + int tmp, new_errno= 0; if ((tmp=table->file->extra(HA_EXTRA_NO_CACHE))) { DBUG_PRINT("error",("extra(HA_EXTRA_NO_CACHE) failed")); - my_errno= tmp; - error= -1; + new_errno= tmp; } if ((tmp=table->file->ha_index_or_rnd_end())) { DBUG_PRINT("error",("ha_index_or_rnd_end() failed")); - my_errno= tmp; - error= -1; + new_errno= tmp; } - if (error == -1) - table->file->print_error(my_errno,MYF(0)); + if (new_errno) + table->file->print_error(new_errno,MYF(0)); } #ifndef DBUG_OFF if (error) @@ -6611,7 +6618,7 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), DBUG_RETURN(0); // Didn't match having error=0; if (join->procedure) - error=join->procedure->send_row(*join->fields); + error=join->procedure->send_row(join->procedure_fields_list); else if (join->do_send_rows) error=join->result->send_data(*join->fields); if (error) @@ -7352,8 +7359,12 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, DBUG_ENTER("test_if_skip_sort_order"); LINT_INIT(ref_key_parts); - /* Check which keys can be used to resolve ORDER BY */ - usable_keys.set_all(); + /* + Check which keys can be used to resolve ORDER BY. + We must not try to use disabled keys. + */ + usable_keys= table->keys_in_use; + for (ORDER *tmp_order=order; tmp_order ; tmp_order=tmp_order->next) { if ((*tmp_order->item)->type() != Item::FIELD_ITEM) diff --git a/sql/sql_select.h b/sql/sql_select.h index c7440fe4c3a..636ee967645 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -204,6 +204,7 @@ class JOIN :public Sql_alloc //Part, shared with list above, emulate following list List tmp_fields_list1, tmp_fields_list2, tmp_fields_list3; List &fields_list; // hold field list passed to mysql_select + List procedure_fields_list; int error; ORDER *order, *group_list, *proc_param; //hold parameters of mysql_select @@ -456,3 +457,4 @@ bool cp_buffer_from_ref(THD *thd, TABLE_REF *ref); bool error_if_full_join(JOIN *join); int report_error(TABLE *table, int error); int safe_index_read(JOIN_TAB *tab); +COND *remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index d6ceca5f23c..268292022e4 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1890,7 +1890,7 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables, case SHOW_SLAVE_RUNNING: { pthread_mutex_lock(&LOCK_active_mi); - end= strmov(buff, (active_mi->slave_running && + end= strmov(buff, (active_mi && active_mi->slave_running && active_mi->rli.slave_running) ? "ON" : "OFF"); pthread_mutex_unlock(&LOCK_active_mi); break; @@ -1902,9 +1902,12 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables, SLAVE STATUS, and have the sum over all lines here. */ pthread_mutex_lock(&LOCK_active_mi); - pthread_mutex_lock(&active_mi->rli.data_lock); - end= int10_to_str(active_mi->rli.retried_trans, buff, 10); - pthread_mutex_unlock(&active_mi->rli.data_lock); + if (active_mi) + { + pthread_mutex_lock(&active_mi->rli.data_lock); + end= int10_to_str(active_mi->rli.retried_trans, buff, 10); + pthread_mutex_unlock(&active_mi->rli.data_lock); + } pthread_mutex_unlock(&LOCK_active_mi); break; } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 01126043764..71cbc0be1e3 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -220,7 +220,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, for (table=tables ; table ; table=table->next) { char *db=table->db; - mysql_ha_flush(thd, table, MYSQL_HA_CLOSE_FINAL); + mysql_ha_flush(thd, table, MYSQL_HA_CLOSE_FINAL, TRUE); if (!close_temporary_table(thd, db, table->real_name)) { tmp_table_deleted=1; @@ -524,7 +524,14 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, */ if (!interval) { - interval= sql_field->interval= typelib(sql_field->interval_list); + /* + Create the typelib in prepared statement memory if we're + executing one. + */ + MEM_ROOT *stmt_root= thd->current_arena->mem_root; + + interval= sql_field->interval= typelib(stmt_root, + sql_field->interval_list); List_iterator it(sql_field->interval_list); String conv, *tmp; for (uint i= 0; (tmp= it++); i++) @@ -534,7 +541,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, { uint cnv_errs; conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs); - char *buf= (char*) sql_alloc(conv.length()+1); + char *buf= (char*) alloc_root(stmt_root, conv.length()+1); memcpy(buf, conv.ptr(), conv.length()); buf[conv.length()]= '\0'; interval->type_names[i]= buf; @@ -556,8 +563,22 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, */ if (sql_field->def && cs != sql_field->def->collation.collation) { - if (!(sql_field->def= - sql_field->def->safe_charset_converter(cs))) + Item_arena backup_arena; + bool need_to_change_arena= + !thd->current_arena->is_conventional_execution(); + if (need_to_change_arena) + { + /* Asser that we don't do that at every PS execute */ + DBUG_ASSERT(thd->current_arena->is_first_stmt_execute()); + thd->set_n_backup_item_arena(thd->current_arena, &backup_arena); + } + + sql_field->def= sql_field->def->safe_charset_converter(cs); + + if (need_to_change_arena) + thd->restore_backup_item_arena(thd->current_arena, &backup_arena); + + if (! sql_field->def) { /* Could not convert */ my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); @@ -639,16 +660,25 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, else { /* Field redefined */ + sql_field->def= dup_field->def; sql_field->sql_type= dup_field->sql_type; sql_field->charset= (dup_field->charset ? dup_field->charset : create_info->default_table_charset); - sql_field->length= dup_field->length; - sql_field->pack_length= dup_field->pack_length; + sql_field->length= dup_field->chars_length; + sql_field->pack_length= dup_field->pack_length; sql_field->create_length_to_internal_length(); sql_field->decimals= dup_field->decimals; - sql_field->flags= dup_field->flags; sql_field->unireg_check= dup_field->unireg_check; + /* + We're making one field from two, the result field will have + dup_field->flags as flags. If we've incremented null_fields + because of sql_field->flags, decrement it back. + */ + if (!(sql_field->flags & NOT_NULL_FLAG)) + null_fields--; + sql_field->flags= dup_field->flags; + sql_field->interval= dup_field->interval; it2.remove(); // Remove first (create) definition select_field_pos--; break; @@ -1920,7 +1950,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, if (protocol->send_fields(&field_list, 1)) DBUG_RETURN(-1); - mysql_ha_flush(thd, tables, MYSQL_HA_CLOSE_FINAL); + mysql_ha_flush(thd, tables, MYSQL_HA_CLOSE_FINAL, FALSE); for (table = tables; table; table = table->next) { char table_name[NAME_LEN*2+2]; @@ -2772,8 +2802,9 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, if (!new_db || !my_strcasecmp(table_alias_charset, new_db, db)) new_db= db; used_fields=create_info->used_fields; + + mysql_ha_flush(thd, table_list, MYSQL_HA_CLOSE_FINAL, FALSE); - mysql_ha_flush(thd, table_list, MYSQL_HA_CLOSE_FINAL); /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */ if (alter_info->tablespace_op != NO_TABLESPACE_OP) DBUG_RETURN(mysql_discard_or_import_tablespace(thd,table_list, diff --git a/sql/sql_update.cc b/sql/sql_update.cc index ca40ed554dd..24c7a278e79 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -61,7 +61,8 @@ int mysql_update(THD *thd, bool safe_update= thd->options & OPTION_SAFE_UPDATES; bool used_key_is_modified, transactional_table, log_delayed; int error=0; - uint used_index; + uint used_index= MAX_KEY; + bool need_sort= TRUE; #ifndef NO_EMBEDDED_ACCESS_CHECKS uint want_privilege; #endif @@ -69,7 +70,7 @@ int mysql_update(THD *thd, ha_rows updated, found; key_map old_used_keys; TABLE *table; - SQL_SELECT *select; + SQL_SELECT *select= 0; READ_RECORD info; TABLE_LIST *update_table_list= ((TABLE_LIST*) thd->lex->select_lex.table_list.first); @@ -130,11 +131,19 @@ int mysql_update(THD *thd, DBUG_RETURN(-1); /* purecov: inspected */ } + if (conds) + { + Item::cond_result cond_value; + conds= remove_eq_conds(thd, conds, &cond_value); + if (cond_value == Item::COND_FALSE) + limit= 0; // Impossible WHERE + } // Don't count on usage of 'only index' when calculating which key to use table->used_keys.clear_all(); - select=make_select(table,0,0,conds,&error); - if (error || - (select && select->check_quick(thd, safe_update, limit)) || !limit) + if (limit) + select=make_select(table,0,0,conds,&error); + if (error || !limit || + (select && select->check_quick(thd, safe_update, limit))) { delete select; free_underlaid_joins(thd, &thd->lex->select_lex); @@ -145,6 +154,11 @@ int mysql_update(THD *thd, send_ok(thd); // No matching records DBUG_RETURN(0); } + if (!select && limit != HA_POS_ERROR) + { + if ((used_index= get_index_for_order(table, order, limit)) != MAX_KEY) + need_sort= FALSE; + } /* If running in safe sql mode, don't allow updates without keys */ if (table->quick_keys.is_clear_all()) { @@ -157,6 +171,7 @@ int mysql_update(THD *thd, } } init_ftfuncs(thd, &thd->lex->select_lex, 1); + /* Check if we are modifying a key that we are used to search with */ if (select && select->quick) { @@ -164,13 +179,15 @@ int mysql_update(THD *thd, used_key_is_modified= (!select->quick->unique_key_range() && check_if_key_used(table, used_index, fields)); } - else if ((used_index=table->file->key_used_on_scan) < MAX_KEY) - used_key_is_modified=check_if_key_used(table, used_index, fields); else { - used_key_is_modified=0; - used_index= MAX_KEY; + used_key_is_modified= 0; + if (used_index == MAX_KEY) // no index for sort order + used_index= table->file->key_used_on_scan; + if (used_index != MAX_KEY) + used_key_is_modified= check_if_key_used(table, used_index, fields); } + if (used_key_is_modified || order) { /* @@ -184,7 +201,8 @@ int mysql_update(THD *thd, table->file->extra(HA_EXTRA_KEYREAD); } - if (order) + /* note: can actually avoid sorting below.. */ + if (order && (need_sort || used_key_is_modified)) { /* Doing an ORDER BY; Let filesort find and sort the rows we are going @@ -194,6 +212,7 @@ int mysql_update(THD *thd, SORT_FIELD *sortorder; ha_rows examined_rows; + used_index= MAX_KEY; // For call to init_read_record() table->sort.io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE), MYF(MY_FAE | MY_ZEROFILL)); if (!(sortorder=make_unireg_sortorder(order, &length)) || @@ -225,7 +244,11 @@ int mysql_update(THD *thd, DISK_BUFFER_SIZE, MYF(MY_WME))) goto err; - init_read_record(&info,thd,table,select,0,1); + if (used_index == MAX_KEY) + init_read_record(&info,thd,table,select,0,1); + else + init_read_record_idx(&info, thd, table, 1, used_index); + thd->proc_info="Searching rows for update"; uint tmp_limit= limit; @@ -251,6 +274,7 @@ int mysql_update(THD *thd, error= 1; // Aborted limit= tmp_limit; end_read_record(&info); + /* Change select to use tempfile */ if (select) { @@ -353,6 +377,7 @@ int mysql_update(THD *thd, if (!log_delayed) thd->options|=OPTION_STATUS_NO_TRANS_UPDATE; } + free_underlaid_joins(thd, &thd->lex->select_lex); if (transactional_table) { if (ha_autocommit_or_rollback(thd, error >= 0)) @@ -365,7 +390,6 @@ int mysql_update(THD *thd, thd->lock=0; } - free_underlaid_joins(thd, &thd->lex->select_lex); if (error >= 0) send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0); /* purecov: inspected */ else @@ -830,8 +854,7 @@ int multi_update::prepare(List ¬_used_values, { TABLE *table=table_ref->table; if (!(tables_to_update & table->map) && - find_real_table_in_list(update_tables, table_ref->db, - table_ref->real_name)) + mysql_lock_have_duplicate(thd, table, update_tables)) table->no_cache= 1; // Disable row cache } DBUG_RETURN(thd->is_fatal_error != 0); @@ -1058,22 +1081,23 @@ bool multi_update::send_data(List ¬_used_values) int error; TABLE *tmp_table= tmp_tables[offset]; fill_record(tmp_table->field+1, *values_for_table[offset], 1); - found++; /* Store pointer to row */ memcpy((char*) tmp_table->field[0]->ptr, (char*) table->file->ref, table->file->ref_length); /* Write row, ignoring duplicated updates to a row */ - if ((error= tmp_table->file->write_row(tmp_table->record[0])) && - (error != HA_ERR_FOUND_DUPP_KEY && - error != HA_ERR_FOUND_DUPP_UNIQUE)) + if (error= tmp_table->file->write_row(tmp_table->record[0])) { - if (create_myisam_from_heap(thd, tmp_table, tmp_table_param + offset, - error, 1)) + if (error != HA_ERR_FOUND_DUPP_KEY && + error != HA_ERR_FOUND_DUPP_UNIQUE && + create_myisam_from_heap(thd, tmp_table, + tmp_table_param + offset, error, 1)) { do_update=0; DBUG_RETURN(1); // Not a table_is_full error } } + else + found++; } } DBUG_RETURN(0); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 82f9c5a288f..c99abc7d349 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2924,6 +2924,8 @@ simple_expr: { $$= new Item_func_atan($3,$5); } | CHAR_SYM '(' expr_list ')' { $$= new Item_func_char(*$3); } + | CHAR_SYM '(' expr_list USING charset_name ')' + { $$= new Item_func_char(*$3, $5); } | CHARSET '(' expr ')' { $$= new Item_func_charset($3); } | COALESCE '(' expr_list ')' diff --git a/sql/table.cc b/sql/table.cc index 04d1a95cd9b..de539205ffd 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1099,15 +1099,15 @@ fix_type_pointers(const char ***array, TYPELIB *point_to_type, uint types, } /* fix_type_pointers */ -TYPELIB *typelib(List &strings) +TYPELIB *typelib(MEM_ROOT *mem_root, List &strings) { - TYPELIB *result=(TYPELIB*) sql_alloc(sizeof(TYPELIB)); + TYPELIB *result= (TYPELIB*) alloc_root(mem_root, sizeof(TYPELIB)); if (!result) return 0; result->count=strings.elements; result->name=""; uint nbytes= (sizeof(char*) + sizeof(uint)) * (result->count + 1); - if (!(result->type_names= (const char**) sql_alloc(nbytes))) + if (!(result->type_names= (const char**) alloc_root(mem_root, nbytes))) return 0; result->type_lengths= (uint*) (result->type_names + result->count + 1); List_iterator it(strings); diff --git a/sql/tztime.cc b/sql/tztime.cc index b5ebc9f350a..b0a32748998 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -2359,6 +2359,7 @@ scan_tz_dir(char * name_end) int main(int argc, char **argv) { +#ifndef __NETWARE__ MY_INIT(argv[0]); if (argc != 2 && argc != 3) @@ -2417,6 +2418,10 @@ main(int argc, char **argv) free_root(&tz_storage, MYF(0)); } +#else + fprintf(stderr, "This tool has not been ported to NetWare\n"); +#endif /* __NETWARE__ */ + return 0; } diff --git a/strings/conf_to_src.c b/strings/conf_to_src.c index d5ffa15ee0c..93088bc7512 100644 --- a/strings/conf_to_src.c +++ b/strings/conf_to_src.c @@ -169,50 +169,68 @@ static int my_read_charset_file(const char *filename) return FALSE; } +static int +is_case_sensitive(CHARSET_INFO *cs) +{ + return (cs->sort_order && + cs->sort_order['A'] < cs->sort_order['a'] && + cs->sort_order['a'] < cs->sort_order['B']) ? 1 : 0; +} + void dispcset(FILE *f,CHARSET_INFO *cs) { fprintf(f,"{\n"); fprintf(f," %d,%d,%d,\n",cs->number,0,0); - fprintf(f," MY_CS_COMPILED%s%s,\n", + fprintf(f," MY_CS_COMPILED%s%s%s,\n", cs->state & MY_CS_BINSORT ? "|MY_CS_BINSORT" : "", - cs->state & MY_CS_PRIMARY ? "|MY_CS_PRIMARY" : ""); + cs->state & MY_CS_PRIMARY ? "|MY_CS_PRIMARY" : "", + is_case_sensitive(cs) ? "|MY_CS_CSSORT" : ""); if (cs->name) { - fprintf(f," \"%s\",\n",cs->csname); - fprintf(f," \"%s\",\n",cs->name); - fprintf(f," \"\",\n"); - fprintf(f," ctype_%s,\n",cs->name); - fprintf(f," to_lower_%s,\n",cs->name); - fprintf(f," to_upper_%s,\n",cs->name); + fprintf(f," \"%s\", /* cset name */\n",cs->csname); + fprintf(f," \"%s\", /* coll name */\n",cs->name); + fprintf(f," \"\", /* comment */\n"); + fprintf(f," NULL, /* tailoring */\n"); + fprintf(f," ctype_%s, /* ctype */\n",cs->name); + fprintf(f," to_lower_%s, /* lower */\n",cs->name); + fprintf(f," to_upper_%s, /* upper */\n",cs->name); if (cs->sort_order) - fprintf(f," sort_order_%s,\n",cs->name); + fprintf(f," sort_order_%s, /* sort_order */\n",cs->name); else - fprintf(f," NULL,\n"); - fprintf(f," to_uni_%s,\n",cs->name); - fprintf(f," from_uni_%s,\n",cs->name); + fprintf(f," NULL, /* sort_order */\n"); + fprintf(f," NULL, /* contractions */\n"); + fprintf(f," NULL, /* sort_order_big*/\n"); + fprintf(f," to_uni_%s, /* to_uni */\n",cs->name); } else { - fprintf(f," NULL,\n"); - fprintf(f," NULL,\n"); - fprintf(f," NULL,\n"); - fprintf(f," NULL,\n"); - fprintf(f," NULL,\n"); - fprintf(f," NULL,\n"); - fprintf(f," NULL,\n"); - fprintf(f," NULL,\n"); - fprintf(f," NULL,\n"); + fprintf(f," NULL, /* cset name */\n"); + fprintf(f," NULL, /* coll name */\n"); + fprintf(f," NULL, /* comment */\n"); + fprintf(f," NULL, /* tailoging */\n"); + fprintf(f," NULL, /* ctype */\n"); + fprintf(f," NULL, /* lower */\n"); + fprintf(f," NULL, /* upper */\n"); + fprintf(f," NULL, /* sort order */\n"); + fprintf(f," NULL, /* contractions */\n"); + fprintf(f," NULL, /* sort_order_big*/\n"); + fprintf(f," NULL, /* to_uni */\n"); } - - fprintf(f," \"\",\n"); - fprintf(f," \"\",\n"); - fprintf(f," 0,\n"); - fprintf(f," 0,\n"); - fprintf(f," 0,\n"); + + fprintf(f," NULL, /* from_uni */\n"); + fprintf(f," NULL, /* state map */\n"); + fprintf(f," NULL, /* ident map */\n"); + fprintf(f," 1, /* strxfrm_multiply*/\n"); + fprintf(f," 1, /* mbminlen */\n"); + fprintf(f," 1, /* mbmaxlen */\n"); + fprintf(f," 0, /* min_sort_char */\n"); + fprintf(f," 255, /* max_sort_char */\n"); + fprintf(f," 0, /* escape_with_backslash_is_dangerous */\n"); + fprintf(f," &my_charset_8bit_handler,\n"); if (cs->state & MY_CS_BINSORT) - fprintf(f," &my_collation_bin_handler,\n"); + fprintf(f," &my_collation_8bit_bin_handler,\n"); else fprintf(f," &my_collation_8bit_simple_ci_handler,\n"); fprintf(f,"}\n"); @@ -251,6 +269,11 @@ main(int argc, char **argv __attribute__((unused))) } } + + fprintf(f,"#include \n"); + fprintf(f,"#include \n\n"); + + for (cs=all_charsets; cs < all_charsets+256; cs++) { if (simple_cs_is_full(cs)) diff --git a/strings/ctype-euc_kr.c b/strings/ctype-euc_kr.c index f15e97de5be..2863b192f50 100644 --- a/strings/ctype-euc_kr.c +++ b/strings/ctype-euc_kr.c @@ -8635,6 +8635,41 @@ my_mb_wc_euc_kr(CHARSET_INFO *cs __attribute__((unused)), } +/* + Returns well formed length of a EUC-KR string. +*/ +static uint +my_well_formed_len_euckr(CHARSET_INFO *cs __attribute__((unused)), + const char *b, const char *e, + uint pos, int *error) +{ + const char *b0= b; + const char *emb= e - 1; /* Last possible end of an MB character */ + + *error= 0; + while (pos-- && b < e) + { + if ((uchar) b[0] < 128) + { + /* Single byte ascii character */ + b++; + } + else if (b < emb && iseuc_kr(*b) && iseuc_kr(b[1])) + { + /* Double byte character */ + b+= 2; + } + else + { + /* Wrong byte sequence */ + *error= 1; + break; + } + } + return (uint) (b - b0); +} + + static MY_COLLATION_HANDLER my_collation_ci_handler = { NULL, /* init */ @@ -8655,7 +8690,7 @@ static MY_CHARSET_HANDLER my_charset_handler= mbcharlen_euc_kr, my_numchars_mb, my_charpos_mb, - my_well_formed_len_mb, + my_well_formed_len_euckr, my_lengthsp_8bit, my_numcells_8bit, my_mb_wc_euc_kr, /* mb_wc */ diff --git a/strings/ctype-gb2312.c b/strings/ctype-gb2312.c index 0cbad2d1c55..52dd61a8462 100644 --- a/strings/ctype-gb2312.c +++ b/strings/ctype-gb2312.c @@ -5686,6 +5686,41 @@ my_mb_wc_gb2312(CHARSET_INFO *cs __attribute__((unused)), } +/* + Returns well formed length of a EUC-KR string. +*/ +static uint +my_well_formed_len_gb2312(CHARSET_INFO *cs __attribute__((unused)), + const char *b, const char *e, + uint pos, int *error) +{ + const char *b0= b; + const char *emb= e - 1; /* Last possible end of an MB character */ + + *error= 0; + while (pos-- && b < e) + { + if ((uchar) b[0] < 128) + { + /* Single byte ascii character */ + b++; + } + else if (b < emb && isgb2312head(*b) && isgb2312tail(b[1])) + { + /* Double byte character */ + b+= 2; + } + else + { + /* Wrong byte sequence */ + *error= 1; + break; + } + } + return (uint) (b - b0); +} + + static MY_COLLATION_HANDLER my_collation_ci_handler = { NULL, /* init */ @@ -5706,7 +5741,7 @@ static MY_CHARSET_HANDLER my_charset_handler= mbcharlen_gb2312, my_numchars_mb, my_charpos_mb, - my_well_formed_len_mb, + my_well_formed_len_gb2312, my_lengthsp_8bit, my_numcells_8bit, my_mb_wc_gb2312, /* mb_wc */ diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c index efddab621f2..095b2f3a4ac 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -867,7 +867,7 @@ int my_longlong10_to_str_8bit(CHARSET_INFO *cs __attribute__((unused)), while (long_val != 0) { long quo= long_val/10; - *--p = '0' + (long_val - quo*10); + *--p = (char) ('0' + (long_val - quo*10)); long_val= quo; } diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index 56c05635300..d8985a890d9 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -1043,7 +1043,7 @@ int my_ll10tostr_ucs2(CHARSET_INFO *cs __attribute__((unused)), while (long_val != 0) { long quo= long_val/10; - *--p = '0' + (long_val - quo*10); + *--p = (char) ('0' + (long_val - quo*10)); long_val= quo; } @@ -1352,11 +1352,48 @@ int my_strnncoll_ucs2_bin(CHARSET_INFO *cs, return t_is_prefix ? (int) (t - te) : (int) ((se-s) - (te-t)); } -static int my_strnncollsp_ucs2_bin(CHARSET_INFO *cs, +static int my_strnncollsp_ucs2_bin(CHARSET_INFO *cs __attribute__((unused)), const uchar *s, uint slen, const uchar *t, uint tlen) { - return my_strnncoll_ucs2_bin(cs,s,slen,t,tlen,0); + const uchar *se, *te; + uint minlen; + + /* extra safety to make sure the lengths are even numbers */ + slen= (slen >> 1) << 1; + tlen= (tlen >> 1) << 1; + + se= s + slen; + te= t + tlen; + + for (minlen= min(slen, tlen); minlen; minlen-= 2) + { + int s_wc= s[0] * 256 + s[1]; + int t_wc= t[0] * 256 + t[1]; + if ( s_wc != t_wc ) + return s_wc > t_wc ? 1 : -1; + + s+= 2; + t+= 2; + } + + if (slen != tlen) + { + int swap= 1; + if (slen < tlen) + { + s= t; + se= te; + swap= -1; + } + + for ( ; s < se ; s+= 2) + { + if (s[0] || s[1] != ' ') + return (s[0] == 0 && s[1] < ' ') ? -swap : swap; + } + } + return 0; } diff --git a/strings/ctype-win1250ch.c b/strings/ctype-win1250ch.c index 351af3de23e..e936ef1d423 100644 --- a/strings/ctype-win1250ch.c +++ b/strings/ctype-win1250ch.c @@ -512,42 +512,84 @@ static int my_strnxfrm_win1250ch(CHARSET_INFO * cs __attribute__((unused)), #ifdef REAL_MYSQL -static uchar NEAR like_range_prefix_min_win1250ch[] = +static uchar NEAR like_range_prefix_min_win1250ch[]= { -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -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, 54, 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, 165, 124, 125, 126, 0, -0, 0, 130, 0, 132, 133, 134, 135, 0, 137, 138, 139, 83, 84, 142, 90, -0, 145, 146, 147, 148, 149, 150, 151, 0, 153, 138, 155, 83, 84, 142, 90, -32, 161, 162, 76, 164, 165, 166, 167, 168, 65, 83, 171, 172, 173, 174, 90, -176, 177, 178, 76, 180, 181, 0, 183, 184, 65, 83, 187, 76, 189, 76, 90, -82, 65, 65, 65, 65, 76, 67, 67, 200, 69, 69, 69, 69, 73, 73, 68, -68, 78, 78, 79, 79, 79, 79, 215, 216, 85, 85, 85, 85, 89, 84, 223, -82, 65, 65, 65, 65, 76, 67, 67, 200, 69, 69, 69, 69, 73, 73, 68, -68, 78, 78, 79, 79, 79, 79, 247, 216, 85, 85, 85, 85, 89, 84, 255, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, + 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, + 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, + 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, + 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, + 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, + 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, + 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, + 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, + 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF }; -static uchar NEAR like_range_prefix_max_win1250ch[] = { -182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, -182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, -160, 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, 185, 98, 73, 240, 234, 102, 103, 104, 238, 106, 107, 179, 109, 242, 245, -112, 113, 224, 186, 254, 251, 118, 119, 120, 253, 159, 91, 92, 93, 94, 95, -96, 54, 98, 73, 240, 234, 102, 103, 104, 238, 106, 107, 179, 109, 242, 245, -112, 113, 224, 186, 254, 251, 118, 119, 120, 253, 159, 165, 124, 125, 126, 182, -182, 182, 130, 182, 132, 133, 134, 135, 182, 137, 154, 139, 186, 254, 158, 159, -182, 145, 146, 147, 148, 149, 150, 151, 182, 153, 154, 155, 186, 254, 158, 159, -32, 161, 162, 179, 164, 165, 166, 167, 168, 185, 186, 171, 172, 173, 174, 159, -176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 179, 189, 179, 159, -224, 185, 185, 185, 185, 179, 238, 238, 200, 234, 234, 234, 234, 238, 238, 240, -240, 242, 242, 245, 245, 245, 245, 215, 248, 251, 251, 251, 251, 253, 254, 223, -224, 185, 185, 185, 185, 179, 238, 238, 200, 234, 234, 234, 234, 238, 238, 240, -240, 242, 242, 245, 245, 245, 245, 247, 248, 251, 251, 251, 251, 253, 254, 255, + +/* + The letter "C" is a special case: + "CH" is sorted between "H" and "I". + prefix_max for "C" is "I": prefix_max[0x43] == 0x49 + prefix_max for "c" is "i": prefix_max[0x63] == 0x69 + For all other characters: prefix_max[i] == i +*/ + +static uchar NEAR like_range_prefix_max_win1250ch[]= +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, + 0x40, 0x41, 0x42, 0x49, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, + 0x60, 0x61, 0x62, 0x69, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, + 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, + 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, + 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, + 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, + 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, + 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, + 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, + 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, + 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF }; #define min_sort_char '\x20' diff --git a/support-files/MacOSX/make_mysql_pkg.pl b/support-files/MacOSX/make_mysql_pkg.pl deleted file mode 100644 index 22283d57098..00000000000 --- a/support-files/MacOSX/make_mysql_pkg.pl +++ /dev/null @@ -1,475 +0,0 @@ -#!/usr/bin/perl -w -# -# -# make_mysql_pkg.pl -# -# This script creates a Mac OS X installation package -# of MySQL for Apple's Installer application. -# -# To use it: -# -# 1.) Unpack the mysql source tarball and cd into the directory -# 2.) execute this script -# -# -# Written by Marc Liyanage (http://www.entropy.ch) -# -# History: -# -# When Who What -# ------------------------------------------------------------------ -# 2001-09-16 Marc Liyanage First version -# 2001-11-18 Marc Liyanage Improved configure directory options -# - -use strict; -use DirHandle; - -my $data = {}; - -$data->{PREFIX_DIR} = "/usr/local/mysql"; -$data->{CONFIG} = join(" ", - "--prefix=$data->{PREFIX_DIR}", - "--localstatedir=$data->{PREFIX_DIR}/data", - "--libdir=$data->{PREFIX_DIR}/lib", - "--includedir=$data->{PREFIX_DIR}/include", - "--with-named-z-libs=/usr/local/libz.a", - "--with-innodb", - "--with-server-suffix='-entropy.ch'", - "--with-comment='http://www.entropy.ch/software/macosx/mysql/'", - "--with-mysqld-user=mysql", - "--enable-assembler", - "CFLAGS=\"-DHAVE_BROKEN_REALPATH -lncurses\"", -); - - - - - -prepare($data); -configure_source($data); -make($data); -make_binary_distribution($data); -create_pax_root($data); -create_package($data); -cleanup($data); - -print "Package $data->{PACKAGE_TARBALL_FILENAME} created\n"; - - - - - - -# Subroutines follow here... - - - - -# Prepares data in the global $data hash, like version numbers, -# directory names etc. Also makes sure that no old stuff -# is in our way. -# -sub prepare { - - my ($data) = @_; - - # Keep the current wd for reference - # - $data->{OLDWD} = `pwd`; - chomp($data->{OLDWD}); - - # Look for configure script - # - unless (-f "configure") { - abort($data, "Unable to find 'configure', make sure you're in the MySQL source toplevel directory!"); - } - - # Try to find version number there - # - my $mysql_version_h = `cat configure`; - ($data->{VERSION}) = $mysql_version_h =~ /^VERSION=(.+?)$/m; - - unless ($data->{VERSION} =~ /\d+/) { - abort($data, "Unable to find MySQL version number!"); - } - - debug($data, "found MySQL version number $data->{VERSION}"); - - - # PAXROOT_DIR is where we will build our own little - # fake /usr/local directory. Make sure it doesn't exist, - # then try to create it. - # - $data->{PAXROOT_DIR} = "/tmp/mysql-$data->{VERSION}-paxroot"; - - if (-e $data->{PAXROOT_DIR}) { - abort($data, "$data->{PAXROOT_DIR} exists, please remove first"); - } - - if (system("mkdir $data->{PAXROOT_DIR}")) { - abort($data, "Unable to mkdir $data->{PAXROOT_DIR}, please make sure you have the right permissions!"); - } - - - # PACKAGE_DIR is where we will build the package directory - # hierarchy, according to the standard .pkg layout. - # - $data->{PACKAGE_NAME} = "mysql-$data->{VERSION}.pkg"; - $data->{PACKAGE_DIR} = "/tmp/$data->{PACKAGE_NAME}"; - - if (-e $data->{PACKAGE_DIR}) { - abort($data, "$data->{PACKAGE_DIR} exists, please remove first"); - } - - if (system("mkdir $data->{PACKAGE_DIR}")) { - abort($data, "Unable to mkdir $data->{PACKAGE_DIR}, please make sure you have the right permissions!"); - } - - -} - - - -# Configure the MySQL source with our options -# -sub configure_source { - - my ($data) = @_; - - if (system("./configure $data->{CONFIG}")) { - abort($data, "Unable to configure!"); - } - -} - - - - -# Build the software -# -sub make { - - my ($data) = @_; - - if (system("make")) { - abort($data, "Unable to make!"); - } - -} - - - -# We don't ever install the software, but instead we use an -# included script to create a binary distribution -# tarball. -# -sub make_binary_distribution { - - my ($data) = @_; - - if (system("./scripts/make_binary_distribution > make_binary_distribution.out")) { - abort($data, "Unable to make_binary_distribution!"); - } - - my @output = `cat make_binary_distribution.out`; - my $last_line = $output[-1]; - unlink("make_binary_distribution.out"); - - my ($tarball_filename, $tarball_directory) = $last_line =~ /^((.+)\.tar\.gz) created/i; - - unless ($tarball_filename and -f $tarball_filename) { - abort($data, "Unable determine the output filename of scripts/make_binary_distribution!"); - } - - $data->{BINARY_TARBALL_FILENAME} = $tarball_filename; - $data->{BINARY_TARBALL_DIRECTORY} = $tarball_directory; - -} - - - - -# Now we build a fake /usr/local directory hierarchy. -# This will be fed to the pax tool to create the archive. -# -sub create_pax_root { - - my ($data) = @_; - - # Go there and try to extract the binary distribution - # tarball which we created in the previous step. - # - chdir($data->{PAXROOT_DIR}); - my $tarfile = "$data->{OLDWD}/$data->{BINARY_TARBALL_FILENAME}"; - - if (system("tar -xzf $tarfile")) { - abort($data, "Unable to extract $tarfile inside $data->{PAXROOT_DIR}"); - } - - # Rename it to what we want it to be in the - # installed /usr/local directory later on, i.e. - # mysql-. Then create a symlink from - # mysql to mysql- - # - rename($data->{BINARY_TARBALL_DIRECTORY}, "mysql-$data->{VERSION}"); - symlink("mysql-$data->{VERSION}", "mysql"); - - - # We create a bunch of symlinks in /usr/local/bin and - # /usr/local/share/man so that the end-user will not - # have to adjust PATH and MANPATH to include the - # /usr/local/mysql/bin and man directories. - # - system("mkdir -p $_") foreach qw(bin share/man); - - - # First create the symlinks in the bin directory - # - # 2001-02-13: we no longer use symlinks for the binaries, we - # use small dummy scripts instead because the - # mysql scripts do a lot of guesswork with their - # own path and that will not work when called via the symlink - # -# symlink("../mysql/bin/$_", "$_") foreach (grep {$_ !~ /^\.+$/} DirHandle->new("../mysql/bin")->read()); - - chdir("bin"); - - foreach my $command (grep {$_ !~ /^\.+$/} DirHandle->new("../mysql/bin")->read()) { - - my $scriptcode = qq+#!/bin/sh\n# Part of the entropy.ch mysql package\ncd /usr/local/mysql/\nexec ./bin/$command "\$\@"\n+; - open(SCRIPTFILE, ">$command") or die "Unable to write open $command\n"; - print SCRIPTFILE $scriptcode; - close(SCRIPTFILE); - chmod(0755, $command); - - } - - - - - - - - # Now include the man pages. Two problems here: - # 1.) the make_binary_distribution script does not seem - # to include the man pages, so we have to copy them over - # now. [outdated, was fixed by MySQL!] - # 2.) The man pages could be in different sections, so - # we have to recursively copy *and* symlink them. - # - - # First find out what's there in the source distribution. - # Store the names of the manpages in anonymous - # arrays which in turn will be stored in a hash, using - # the section numbers as hash keys. - # - chdir("$data->{PAXROOT_DIR}/mysql"); - my %man_sections; - foreach my $manpage (grep {$_ =~ /^.+\.(\d+)$/} DirHandle->new("man")->read()) { - - my ($section) = $manpage =~ /\.(\d+)$/; - - $man_sections{$section} ||= []; - push @{$man_sections{$section}}, "$manpage"; - - } - - - # Now iterate through the sections and man pages, - # and copy/symlink the man pages - # - chdir("$data->{PAXROOT_DIR}/share/man/"); - - foreach my $section (keys(%man_sections)) { - - system("mkdir -p man$section"); - chdir("man$section"); - - foreach my $manpage (@{$man_sections{$section}}) { - - symlink("../../../mysql/man/$manpage", $manpage) - - } - - chdir(".."); - - } - - - - # Fix up the library and lib directories. They are packed up wrong in the - # binary distribution tarball. - # - # (no longer needed as of 3.23.47) - # (oops, still needed because 3.23.47 is broken...) - # -# if (-d "$data->{PAXROOT_DIR}/mysql/lib/mysql") { -# abort($data, "$data->{PAXROOT_DIR}/mysql/lib/mysql exists, layout has changed!"); -# } -# chdir("$data->{PAXROOT_DIR}/mysql/lib/"); -# system("mkdir -p mysql"); -# system("mv * mysql"); - -# if (-d "$data->{PAXROOT_DIR}/mysql/include/mysql") { -# abort($data, "$data->{PAXROOT_DIR}/mysql/include/mysql exists, layout has changed!"); -# } -# chdir("$data->{PAXROOT_DIR}/mysql/include/"); -# system("mkdir -p mysql"); -# system("mv * mysql"); - - - - - - - - - -} - - - -# Take the pax root directory, create a few auxiliary -# files and then pack everything up into a tarball -# -sub create_package { - - my ($data) = @_; - - # Create the resources directory in which all - # interesting files for this package will be stored - # - $data->{PKG_RESOURCES_DIR} = "$data->{PACKAGE_DIR}/Contents/Resources"; - - if (system("mkdir -p $data->{PKG_RESOURCES_DIR}")) { - abort("Unable to create package resources dir $data->{PKG_RESOURCES_DIR}"); - } - - - # Create the big archive with all the files using - # the pax tool - # - chdir($data->{PAXROOT_DIR}); - if(system("pax -w . | gzip -c > $data->{PKG_RESOURCES_DIR}/mysql-$data->{VERSION}.pax.gz")) { - abort("Unable to create package pax file"); - } - - - # Create the "Bill Of Materials" (bom) file. - # - if(system("mkbom . $data->{PKG_RESOURCES_DIR}/mysql-$data->{VERSION}.bom")) { - abort("Unable to create package bom file"); - } - - - # Create the ".sizes" file with some information about the package - # - my $size_uncompressed = `du -sk $data->{PAXROOT_DIR} | cut -f 1`; - chomp($size_uncompressed); - - my $size_compressed = `du -sk $data->{PACKAGE_DIR} | cut -f 1`; - chomp($size_compressed); - - my $numfiles = `find /tmp/mysql-$data->{VERSION}-paxroot | wc -l`; - $numfiles--; - - open(SIZESFILE, ">$data->{PKG_RESOURCES_DIR}/mysql-$data->{VERSION}.sizes") or abort("Unable to write open sizes file $data->{PKG_RESOURCES_DIR}/mysql-$data->{VERSION}.sizes"); - print SIZESFILE "NumFiles $numfiles\n"; - print SIZESFILE "InstalledSize $size_uncompressed\n"; - print SIZESFILE "CompressedSize $size_compressed\n"; - close(SIZESFILE); - - - # Create the ".info" file with more information abou the package. - # - open(INFOFILE, ">$data->{PKG_RESOURCES_DIR}/mysql-$data->{VERSION}.info") or abort("Unable to write open sizes file $data->{PKG_RESOURCES_DIR}/mysql-$data->{VERSION}.info"); - my $infodata = join("", ); - $infodata =~ s/<%(.+?)%>/$data->{$1}/eg; - abort("Unable to get info file data from __DATA__!") unless ($infodata =~ /\w+/); - print INFOFILE $infodata; - close(INFOFILE); - - - - # Finally, create the .tar.gz file for the package, - # this is our end result - # - chdir($data->{PACKAGE_DIR}); - chdir(".."); - - $data->{PACKAGE_TARBALL_FILENAME} = "$data->{PACKAGE_NAME}.tar.gz"; - - if(system("tar -czf $data->{OLDWD}/$data->{PACKAGE_TARBALL_FILENAME} $data->{PACKAGE_NAME}")) { - abort("Unable to create package tar file $data->{OLDWD}/$data->{PACKAGE_TARBALL_FILENAME}"); - } - - - -} - - -# Abort with an error message -# -sub abort { - - my ($data, $errormessage) = @_; - - my ($caller) = (caller(1))[3]; - $caller =~ s/^main:://; - - print "*** Error: $caller(): $errormessage\n"; - - exit 1; - -} - - -# Output informative messages -# -sub debug { - - my ($data, $message) = @_; - - my ($caller) = (caller(1))[3]; - $caller =~ s/^main:://; - - print "*** Info: $caller(): $message\n"; - -} - - - -# Remove temporary items -# -sub cleanup { - - my ($data) = @_; - - chdir($data->{OLDWD}); - - system("rm -rf $data->{PACKAGE_DIR}"); - system("rm -rf $data->{PAXROOT_DIR}"); - system("rm $data->{BINARY_TARBALL_FILENAME}"); - -} - - - - -__DATA__ -Title MySQL -Version <%VERSION%> -Description The MySQL database server in a convenient Mac OS X package. Some additional configuration is necessary, please see http://www.entropy.ch/software/macosx/mysql/ -DefaultLocation /usr/local -Diskname (null) -DeleteWarning -NeedsAuthorization YES -DisableStop NO -UseUserMask NO -Application NO -Relocatable NO -Required NO -InstallOnly NO -RequiresReboot NO -InstallFat NO diff --git a/support-files/Makefile.am b/support-files/Makefile.am index 972d1dc7038..26d51438a1b 100644 --- a/support-files/Makefile.am +++ b/support-files/Makefile.am @@ -107,7 +107,5 @@ SUFFIXES = .sh $< > $@-t @MV@ $@-t $@ -all: binary-configure - # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/support-files/my-huge.cnf.sh b/support-files/my-huge.cnf.sh index d25686f1c21..06683994a72 100644 --- a/support-files/my-huge.cnf.sh +++ b/support-files/my-huge.cnf.sh @@ -33,7 +33,7 @@ sort_buffer_size = 2M read_buffer_size = 2M read_rnd_buffer_size = 8M myisam_sort_buffer_size = 64M -thread_cache = 8 +thread_cache_size = 8 query_cache_size = 32M # Try number of CPU's*2 for thread_concurrency thread_concurrency = 8 diff --git a/support-files/my-innodb-heavy-4G.cnf.sh b/support-files/my-innodb-heavy-4G.cnf.sh index 062d106ce6a..4204e172016 100644 --- a/support-files/my-innodb-heavy-4G.cnf.sh +++ b/support-files/my-innodb-heavy-4G.cnf.sh @@ -128,7 +128,7 @@ join_buffer_size = 8M # the amount of thread creations needed if you have a lot of new # connections. (Normally this doesn't give a notable performance # improvement if you have a good thread implementation.) -thread_cache = 8 +thread_cache_size = 8 # This permits the application to give the threads system a hint for the # desired number of threads that should be run at the same time. This diff --git a/support-files/my-large.cnf.sh b/support-files/my-large.cnf.sh index 59aca4b32f2..85151eb1077 100644 --- a/support-files/my-large.cnf.sh +++ b/support-files/my-large.cnf.sh @@ -33,7 +33,7 @@ sort_buffer_size = 1M read_buffer_size = 1M read_rnd_buffer_size = 4M myisam_sort_buffer_size = 64M -thread_cache = 8 +thread_cache_size = 8 query_cache_size= 16M # Try number of CPU's*2 for thread_concurrency thread_concurrency = 8 diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 7247bfbaf3e..7afdae69439 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -350,8 +350,9 @@ BuildMySQL "--disable-shared \ %if %{STATIC_BUILD} --with-mysqld-ldflags='-all-static' \ --with-client-ldflags='-all-static' \ - --with-zlib-dir=bundled \ $USE_OTHER_LIBC_DIR \ +%else + --with-zlib-dir=bundled \ %endif --with-comment=\"MySQL Community Edition - Standard (GPL)\" \ --with-server-suffix='%{server_suffix}' \ @@ -486,22 +487,22 @@ echo "Restarting mysqld." %preun server if test $1 = 0 then - # Stop MySQL before uninstalling it + # Stop MySQL before uninstalling it if test -x %{_sysconfdir}/init.d/mysql then %{_sysconfdir}/init.d/mysql stop > /dev/null - fi - # Remove autostart of mysql - # for older SuSE Linux versions - if test -x /sbin/insserv - then - /sbin/insserv -r %{_sysconfdir}/init.d/mysql - # use chkconfig on Red Hat and newer SuSE releases - elif test -x /sbin/chkconfig - then - /sbin/chkconfig --del mysql - fi + # Remove autostart of mysql + # for older SuSE Linux versions + if test -x /sbin/insserv + then + /sbin/insserv -r %{_sysconfdir}/init.d/mysql + # use chkconfig on Red Hat and newer SuSE releases + elif test -x /sbin/chkconfig + then + /sbin/chkconfig --del mysql + fi + fi fi # We do not remove the mysql user since it may still own a lot of @@ -522,43 +523,50 @@ fi %doc %attr(644, root, man) %{_mandir}/man1/isamchk.1* %doc %attr(644, root, man) %{_mandir}/man1/isamlog.1* -%doc %attr(644, root, man) %{_mandir}/man1/mysql_zap.1* +%doc %attr(644, root, man) %{_mandir}/man1/myisamchk.1* +%doc %attr(644, root, man) %{_mandir}/man1/myisamlog.1* +%doc %attr(644, root, man) %{_mandir}/man1/myisampack.1* %doc %attr(644, root, man) %{_mandir}/man1/mysqld.1* -%doc %attr(644, root, man) %{_mandir}/man1/mysql_fix_privilege_tables.1* %doc %attr(644, root, man) %{_mandir}/man1/mysqld_multi.1* %doc %attr(644, root, man) %{_mandir}/man1/mysqld_safe.1* +%doc %attr(644, root, man) %{_mandir}/man1/mysql_fix_privilege_tables.1* +%doc %attr(644, root, man) %{_mandir}/man1/mysqlhotcopy.1* +%doc %attr(644, root, man) %{_mandir}/man1/mysql.server.1* +%doc %attr(644, root, man) %{_mandir}/man1/mysql_zap.1* +%doc %attr(644, root, man) %{_mandir}/man1/pack_isam.1* %doc %attr(644, root, man) %{_mandir}/man1/perror.1* %doc %attr(644, root, man) %{_mandir}/man1/replace.1* +%doc %attr(644, root, man) %{_mandir}/man1/safe_mysqld.1* %ghost %config(noreplace,missingok) %{_sysconfdir}/my.cnf %attr(755, root, root) %{_bindir}/isamchk %attr(755, root, root) %{_bindir}/isamlog -%attr(755, root, root) %{_bindir}/my_print_defaults %attr(755, root, root) %{_bindir}/myisamchk %attr(755, root, root) %{_bindir}/myisam_ftdump %attr(755, root, root) %{_bindir}/myisamlog %attr(755, root, root) %{_bindir}/myisampack +%attr(755, root, root) %{_bindir}/my_print_defaults +%attr(755, root, root) %{_bindir}/mysqlbug %attr(755, root, root) %{_bindir}/mysql_convert_table_format %attr(755, root, root) %{_bindir}/mysql_create_system_tables +%attr(755, root, root) %{_bindir}/mysqld_multi +%attr(755, root, root) %{_bindir}/mysqld_safe %attr(755, root, root) %{_bindir}/mysql_explain_log %attr(755, root, root) %{_bindir}/mysql_fix_extensions %attr(755, root, root) %{_bindir}/mysql_fix_privilege_tables +%attr(755, root, root) %{_bindir}/mysqlhotcopy %attr(755, root, root) %{_bindir}/mysql_install_db %attr(755, root, root) %{_bindir}/mysql_secure_installation %attr(755, root, root) %{_bindir}/mysql_setpermission +%attr(755, root, root) %{_bindir}/mysqltest %attr(755, root, root) %{_bindir}/mysql_tzinfo_to_sql %attr(755, root, root) %{_bindir}/mysql_zap -%attr(755, root, root) %{_bindir}/mysqlbug -%attr(755, root, root) %{_bindir}/mysqld_multi -%attr(755, root, root) %{_bindir}/mysqld_safe -%attr(755, root, root) %{_bindir}/mysqlhotcopy -%attr(755, root, root) %{_bindir}/mysqltest %attr(755, root, root) %{_bindir}/pack_isam %attr(755, root, root) %{_bindir}/perror %attr(755, root, root) %{_bindir}/replace -%attr(755, root, root) %{_bindir}/resolve_stack_dump %attr(755, root, root) %{_bindir}/resolveip +%attr(755, root, root) %{_bindir}/resolve_stack_dump %attr(755, root, root) %{_bindir}/safe_mysqld %attr(755, root, root) %{_sbindir}/mysqld @@ -586,10 +594,14 @@ fi %attr(755, root, root) %{_bindir}/mysqlimport %attr(755, root, root) %{_bindir}/mysqlshow +%doc %attr(644, root, man) %{_mandir}/man1/msql2mysql.1* %doc %attr(644, root, man) %{_mandir}/man1/mysql.1* %doc %attr(644, root, man) %{_mandir}/man1/mysqlaccess.1* %doc %attr(644, root, man) %{_mandir}/man1/mysqladmin.1* +%doc %attr(644, root, man) %{_mandir}/man1/mysqlbinlog.1* +%doc %attr(644, root, man) %{_mandir}/man1/mysqlcheck.1* %doc %attr(644, root, man) %{_mandir}/man1/mysqldump.1* +%doc %attr(644, root, man) %{_mandir}/man1/mysqlimport.1* %doc %attr(644, root, man) %{_mandir}/man1/mysqlshow.1* %post shared @@ -627,6 +639,7 @@ fi %files devel %defattr(-, root, root, 0755) %doc EXCEPTIONS-CLIENT +%doc %attr(644, root, man) %{_mandir}/man1/mysql_config.1* %attr(755, root, root) %{_bindir}/comp_err %attr(755, root, root) %{_bindir}/mysql_config %dir %attr(755, root, root) %{_includedir}/mysql @@ -676,6 +689,21 @@ fi # itself - note that they must be ordered by date (important when # merging BK trees) %changelog +* Mon Dec 05 2005 Joerg Bruehe + +- Avoid using the "bundled" zlib on "shared" builds: + As it is not installed (on the build system), this gives dependency + problems with "libtool" causing the build to fail. + +* Tue Nov 22 2005 Joerg Bruehe + +- Extend the file existence check for "init.d/mysql" on un-install + to also guard the call to "insserv"/"chkconfig". + +* Thu Oct 27 2005 Lenz Grimmer + +- added more man pages + * Thu Oct 13 2005 Lenz Grimmer - added a usermod call to assign a potential existing mysql user to the diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index eadbd37f8f6..91c2ab9205d 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -51,6 +51,8 @@ static unsigned int iter_count= 0; static const char *opt_basedir= "./"; +static longlong opt_getopt_ll_test= 0; + static int embedded_server_arg_count= 0; static char *embedded_server_args[MAX_SERVER_ARGS]; @@ -6899,98 +6901,6 @@ static void test_prepare_grant() } #endif /* EMBEDDED_LIBRARY */ -/* - Test a crash when invalid/corrupted .frm is used in the - SHOW TABLE STATUS - bug #93 (reported by serg@mysql.com). -*/ - -static void test_frm_bug() -{ - MYSQL_STMT *stmt; - MYSQL_BIND bind[2]; - MYSQL_RES *result; - MYSQL_ROW row; - FILE *test_file; - char data_dir[FN_REFLEN]; - char test_frm[FN_REFLEN]; - int rc; - - myheader("test_frm_bug"); - - mysql_autocommit(mysql, TRUE); - - rc= mysql_query(mysql, "drop table if exists test_frm_bug"); - myquery(rc); - - rc= mysql_query(mysql, "flush tables"); - myquery(rc); - - stmt= mysql_simple_prepare(mysql, "show variables like 'datadir'"); - check_stmt(stmt); - - rc= mysql_stmt_execute(stmt); - check_execute(stmt, rc); - - bind[0].buffer_type= MYSQL_TYPE_STRING; - bind[0].buffer= data_dir; - bind[0].buffer_length= FN_REFLEN; - bind[0].is_null= 0; - bind[0].length= 0; - bind[1]= bind[0]; - - rc= mysql_stmt_bind_result(stmt, bind); - check_execute(stmt, rc); - - rc= mysql_stmt_fetch(stmt); - check_execute(stmt, rc); - - if (!opt_silent) - fprintf(stdout, "\n data directory: %s", data_dir); - - rc= mysql_stmt_fetch(stmt); - DIE_UNLESS(rc == MYSQL_NO_DATA); - - strxmov(test_frm, data_dir, "/", current_db, "/", "test_frm_bug.frm", NullS); - - if (!opt_silent) - fprintf(stdout, "\n test_frm: %s", test_frm); - - if (!(test_file= my_fopen(test_frm, (int) (O_RDWR | O_CREAT), MYF(MY_WME)))) - { - fprintf(stdout, "\n ERROR: my_fopen failed for '%s'", test_frm); - fprintf(stdout, "\n test cancelled"); - exit(1); - } - if (!opt_silent) - fprintf(test_file, "this is a junk file for test"); - - rc= mysql_query(mysql, "SHOW TABLE STATUS like 'test_frm_bug'"); - myquery(rc); - - result= mysql_store_result(mysql); - mytest(result);/* It can't be NULL */ - - rc= my_process_result_set(result); - DIE_UNLESS(rc == 1); - - mysql_data_seek(result, 0); - - row= mysql_fetch_row(result); - mytest(row); - - if (!opt_silent) - fprintf(stdout, "\n Comment: %s", row[17]); - DIE_UNLESS(row[17] != 0); - - mysql_free_result(result); - mysql_stmt_close(stmt); - - my_fclose(test_file, MYF(0)); - mysql_query(mysql, "drop table if exists test_frm_bug"); -} - - /* Test DECIMAL conversion */ static void test_decimal_bug() @@ -11830,6 +11740,102 @@ static void test_bug11718() rc= mysql_query(mysql, "drop table t1, t2"); myquery(rc); } + + +/* + Bug #12925: Bad handling of maximum values in getopt +*/ +static void test_bug12925() +{ + myheader("test_bug12925"); + if (opt_getopt_ll_test) + DIE_UNLESS(opt_getopt_ll_test == LL(25600*1024*1024)); +} + + +/* Bug #16144: mysql_stmt_attr_get type error */ + +static void test_bug16144() +{ + const my_bool flag_orig= (my_bool) 0xde; + my_bool flag= flag_orig; + MYSQL_STMT *stmt; + myheader("test_bug16144"); + + /* Check that attr_get returns correct data on little and big endian CPUs */ + stmt= mysql_stmt_init(mysql); + mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (const void*) &flag); + mysql_stmt_attr_get(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &flag); + DIE_UNLESS(flag == flag_orig); + + mysql_stmt_close(stmt); +} + + +/* + Bug #15613: "libmysqlclient API function mysql_stmt_prepare returns wrong + field length" +*/ + +static void test_bug15613() +{ + MYSQL_STMT *stmt; + const char *stmt_text; + MYSQL_RES *metadata; + MYSQL_FIELD *field; + int rc; + myheader("test_bug15613"); + + /* I. Prepare the table */ + rc= mysql_query(mysql, "set names latin1"); + myquery(rc); + mysql_query(mysql, "drop table if exists t1"); + rc= mysql_query(mysql, + "create table t1 (t text character set utf8, " + "tt tinytext character set utf8, " + "mt mediumtext character set utf8, " + "lt longtext character set utf8, " + "vl varchar(255) character set latin1," + "vb varchar(255) character set binary," + "vu varchar(255) character set utf8)"); + myquery(rc); + + stmt= mysql_stmt_init(mysql); + + /* II. Check SELECT metadata */ + stmt_text= ("select t, tt, mt, lt, vl, vb, vu from t1"); + rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); + metadata= mysql_stmt_result_metadata(stmt); + field= mysql_fetch_fields(metadata); + if (!opt_silent) + { + printf("Field lengths (client character set is latin1):\n" + "text character set utf8:\t\t%lu\n" + "tinytext character set utf8:\t\t%lu\n" + "mediumtext character set utf8:\t\t%lu\n" + "longtext character set utf8:\t\t%lu\n" + "varchar(255) character set latin1:\t%lu\n" + "varchar(255) character set binary:\t%lu\n" + "varchar(255) character set utf8:\t%lu\n", + field[0].length, field[1].length, field[2].length, field[3].length, + field[4].length, field[5].length, field[6].length); + } + DIE_UNLESS(field[0].length == 65535); + DIE_UNLESS(field[1].length == 255); + DIE_UNLESS(field[2].length == 16777215); + DIE_UNLESS(field[3].length == 4294967295UL); + DIE_UNLESS(field[4].length == 255); + DIE_UNLESS(field[5].length == 255); + DIE_UNLESS(field[6].length == 255); + + /* III. Cleanup */ + rc= mysql_query(mysql, "drop table t1"); + myquery(rc); + rc= mysql_query(mysql, "set names default"); + myquery(rc); + mysql_stmt_close(stmt); +} + /* Read and parse arguments and MySQL options from my.cnf */ @@ -11872,6 +11878,9 @@ static struct my_option client_test_long_options[] = {"user", 'u', "User for login if not current user", (char **) &opt_user, (char **) &opt_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #endif + {"getopt-ll-test", 'g', "Option for testing bug in getopt library", + (char **) &opt_getopt_ll_test, (char **) &opt_getopt_ll_test, 0, + GET_LL, REQUIRED_ARG, 0, 0, LONGLONG_MAX, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -11976,7 +11985,6 @@ static struct my_tests_st my_tests[]= { #ifndef EMBEDDED_LIBRARY { "test_prepare_grant", test_prepare_grant }, #endif - { "test_frm_bug", test_frm_bug }, { "test_explain_bug", test_explain_bug }, { "test_decimal_bug", test_decimal_bug }, { "test_nstmts", test_nstmts }, @@ -12048,6 +12056,9 @@ static struct my_tests_st my_tests[]= { { "test_bug11183", test_bug11183 }, { "test_bug12001", test_bug12001 }, { "test_bug11718", test_bug11718 }, + { "test_bug12925", test_bug12925 }, + { "test_bug16144", test_bug16144 }, + { "test_bug15613", test_bug15613 }, { 0, 0 } }; diff --git a/vio/vio.c b/vio/vio.c index 427c52e29d3..6174acd7024 100644 --- a/vio/vio.c +++ b/vio/vio.c @@ -83,7 +83,7 @@ void vio_reset(Vio* vio, enum enum_vio_type type, #ifdef HAVE_OPENSSL if (type == VIO_TYPE_SSL) { - vio->viodelete =vio_ssl_delete; + vio->viodelete =vio_delete; vio->vioerrno =vio_ssl_errno; vio->read =vio_ssl_read; vio->write =vio_ssl_write; diff --git a/vio/vio_priv.h b/vio/vio_priv.h index c1c78cc6efa..eb495025ddd 100644 --- a/vio/vio_priv.h +++ b/vio/vio_priv.h @@ -28,7 +28,6 @@ void vio_ignore_timeout(Vio *vio, uint which, uint timeout); #ifdef HAVE_OPENSSL #include "my_net.h" /* needed because of struct in_addr */ -void vio_ssl_delete(Vio* vio); int vio_ssl_read(Vio *vio,gptr buf, int size); int vio_ssl_write(Vio *vio,const gptr buf,int size); void vio_ssl_timeout(Vio *vio, uint which, uint timeout); diff --git a/vio/viossl.c b/vio/viossl.c index a3a2e7190bd..62145fe5006 100644 --- a/vio/viossl.c +++ b/vio/viossl.c @@ -69,25 +69,6 @@ report_errors() DBUG_VOID_RETURN; } -/* - Delete a vio object - - SYNPOSIS - vio_ssl_delete() - vio Vio object. May be 0. -*/ - - -void vio_ssl_delete(Vio * vio) -{ - if (vio) - { - if (vio->type != VIO_CLOSED) - vio_close(vio); - my_free((gptr) vio,MYF(0)); - } -} - int vio_ssl_errno(Vio *vio __attribute__((unused))) { diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c index 498d10da0ee..46306cf48bb 100644 --- a/vio/viosslfactories.c +++ b/vio/viosslfactories.c @@ -191,9 +191,6 @@ void netware_ssl_cleanup() /* NetWare SSL initialization */ static void netware_ssl_init() { - /* initialize OpenSSL library */ - SSL_library_init(); - /* cleanup OpenSSL library */ NXVmRegisterExitHandler(netware_ssl_cleanup, NULL); } @@ -231,16 +228,17 @@ new_VioSSLConnectorFd(const char* key_file, ptr->ssl_method= 0; /* FIXME: constants! */ -#ifdef __NETWARE__ - netware_ssl_init(); -#endif - if (!ssl_algorithms_added) { DBUG_PRINT("info", ("todo: OpenSSL_add_all_algorithms()")); ssl_algorithms_added = TRUE; + SSL_library_init(); OpenSSL_add_all_algorithms(); } +#ifdef __NETWARE__ + netware_ssl_init(); +#endif + if (!ssl_error_strings_loaded) { DBUG_PRINT("info", ("todo:SSL_load_error_strings()")); @@ -325,17 +323,18 @@ new_VioSSLAcceptorFd(const char *key_file, /* FIXME: constants! */ ptr->session_id_context= ptr; -#ifdef __NETWARE__ - netware_ssl_init(); -#endif - if (!ssl_algorithms_added) { DBUG_PRINT("info", ("todo: OpenSSL_add_all_algorithms()")); ssl_algorithms_added = TRUE; + SSL_library_init(); OpenSSL_add_all_algorithms(); } +#ifdef __NETWARE__ + netware_ssl_init(); +#endif + if (!ssl_error_strings_loaded) { DBUG_PRINT("info", ("todo: SSL_load_error_strings()")); diff --git a/zlib/Makefile.am b/zlib/Makefile.am index e94d184a841..11b1991fa62 100644 --- a/zlib/Makefile.am +++ b/zlib/Makefile.am @@ -18,6 +18,8 @@ pkglib_LTLIBRARIES=libz.la +libz_la_LDFLAGS= -version-info 3:3:2 + noinst_HEADERS= crc32.h deflate.h inffast.h inffixed.h inflate.h \ inftrees.h trees.h zconf.h zlib.h zutil.h
Column