diff options
author | unknown <hf@deer.(none)> | 2004-09-02 11:11:16 +0500 |
---|---|---|
committer | unknown <hf@deer.(none)> | 2004-09-02 11:11:16 +0500 |
commit | c4711fb9ea7fac5d10011d57f554be286d60d718 (patch) | |
tree | 3729cbd0d52a55298b6e3fb82a92f86590944869 | |
parent | 848414cf11bb77fe20b583eece29bccb0d25338d (diff) | |
parent | 0ceb4ddc9f9212a1f9caf6b2179c59158677a91f (diff) | |
download | mariadb-git-c4711fb9ea7fac5d10011d57f554be286d60d718.tar.gz |
Merge bk@192.168.21.1:/usr/home/bk/mysql-4.1
into deer.(none):/home/hf/work/mysql-4.1.4815
sql/sql_class.cc:
Auto merged
197 files changed, 2938 insertions, 1066 deletions
diff --git a/.bzrignore b/.bzrignore index 87735d5bf18..162872e39cf 100644 --- a/.bzrignore +++ b/.bzrignore @@ -14,6 +14,7 @@ */.pure *~ .*.swp +./config.h .defs.mk .depend .depend.mk @@ -258,7 +259,7 @@ cmd-line-utils/libedit/common.h cmd-line-utils/libedit/makelist comon.h config.cache -./config.h +config.h config.h.in config.log config.status @@ -830,6 +831,7 @@ support-files/MacOSX/postinstall support-files/MacOSX/preinstall support-files/binary-configure support-files/my-huge.cnf +support-files/my-innodb-heavy-4G.cnf support-files/my-large.cnf support-files/my-medium.cnf support-files/my-small.cnf diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 76a72fc9b4a..0eb4289c1d5 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -80,6 +80,7 @@ jcole@mugatu.jcole.us jcole@mugatu.spaceapes.com jcole@sarvik.tfr.cafe.ee jcole@tetra.spaceapes.com +joerg@mysql.com joreland@mysql.com jorge@linux.jorge.mysql.com jplindst@t41.(none) diff --git a/Build-tools/Do-compile b/Build-tools/Do-compile index c17995f5779..f3c20c81a9f 100755 --- a/Build-tools/Do-compile +++ b/Build-tools/Do-compile @@ -376,7 +376,7 @@ if ($opt_stage <= 5 && !$opt_no_test && !$opt_no_mysqltest) log_timestamp(); system("mkdir $bench_tmpdir") if (! -d $bench_tmpdir); safe_cd("${test_dir}/mysql-test"); - check_system("./mysql-test-run $flags --warnings --tmpdir=$bench_tmpdir --master_port=$mysql_tcp_port --slave_port=$slave_port --ndbcluster_port=$ndbcluster_port --manager-port=$manager_port --no-manager --sleep=10", "tests were successful"); + check_system("./mysql-test-run $flags --tmpdir=$bench_tmpdir --master_port=$mysql_tcp_port --slave_port=$slave_port --ndbcluster_port=$ndbcluster_port --manager-port=$manager_port --no-manager --sleep=10", "tests were successful"); } # diff --git a/Build-tools/mysql-copyright b/Build-tools/mysql-copyright index 92b8f13bf48..77a90fbf4e4 100755 --- a/Build-tools/mysql-copyright +++ b/Build-tools/mysql-copyright @@ -204,7 +204,7 @@ sub trim_the_fat open(CONFIGURE,">configure.in") or die "Unable to open configure.in for write: $!\n"; print CONFIGURE $configure; close(CONFIGURE); - `autoconf`; + `aclocal && autoheader && aclocal && automake && autoconf`; die "'./configure' was not produced!" unless (-f "configure"); chdir("$cwd"); } diff --git a/VC++Files/sql/message.mc b/VC++Files/sql/message.mc new file mode 100644 index 00000000000..a1a7c8cff7e --- /dev/null +++ b/VC++Files/sql/message.mc @@ -0,0 +1,8 @@ +MessageId = 100 +Severity = Error +Facility = Application +SymbolicName = MSG_DEFAULT +Language = English +%1For more information, see Help and Support Center at http://www.mysql.com. + + diff --git a/VC++Files/sql/mysqld.dsp b/VC++Files/sql/mysqld.dsp index 9bcdb4be24f..31c52009d9f 100644 --- a/VC++Files/sql/mysqld.dsp +++ b/VC++Files/sql/mysqld.dsp @@ -920,6 +920,89 @@ SOURCE=.\log_event.cpp # End Source File # Begin Source File +SOURCE=.\message.mc + +!IF "$(CFG)" == "mysqld - Win32 Release" + +!ELSEIF "$(CFG)" == "mysqld - Win32 Debug" + +!ELSEIF "$(CFG)" == "mysqld - Win32 nt" + +# Begin Custom Build - Compiling messages +InputDir=. +InputPath=.\message.mc +InputName=message + +BuildCmds= \ + mc.exe "$(InputDir)\$(InputName).mc" + +"$(InputDir)\$(InputName).rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"$(InputDir)\$(InputName).h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) +# End Custom Build + +!ELSEIF "$(CFG)" == "mysqld - Win32 Max nt" +# Begin Custom Build - Compiling messages +InputDir=. +InputPath=.\message.mc +InputName=message + +BuildCmds= \ + mc.exe "$(InputDir)\$(InputName).mc" + +"$(InputDir)\$(InputName).rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"$(InputDir)\$(InputName).h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) +# End Custom Build +!ELSEIF "$(CFG)" == "mysqld - Win32 Max" + +!ELSEIF "$(CFG)" == "mysqld - Win32 classic" + +!ELSEIF "$(CFG)" == "mysqld - Win32 pro" + +!ELSEIF "$(CFG)" == "mysqld - Win32 classic nt" +# Begin Custom Build - Compiling messages +InputDir=. +InputPath=.\message.mc +InputName=message + +BuildCmds= \ + mc.exe "$(InputDir)\$(InputName).mc" + +"$(InputDir)\$(InputName).rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"$(InputDir)\$(InputName).h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) +# End Custom Build +!ELSEIF "$(CFG)" == "mysqld - Win32 pro nt" +# Begin Custom Build - Compiling messages +InputDir=. +InputPath=.\message.mc +InputName=message + +BuildCmds= \ + mc.exe "$(InputDir)\$(InputName).mc" + +"$(InputDir)\$(InputName).rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) + +"$(InputDir)\$(InputName).h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + $(BuildCmds) +# End Custom Build +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\message.rc +# End Source File +# Begin Source File + SOURCE=.\mf_iocache.cpp !IF "$(CFG)" == "mysqld - Win32 Release" diff --git a/acinclude.m4 b/acinclude.m4 index 1b49f2bbdf4..f634784ea34 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -6,7 +6,6 @@ AC_DEFUN(MYSQL_CHECK_READLINE_DECLARES_HIST_ENTRY,[ AC_TRY_COMPILE( [ #include "stdio.h" - #undef __P // readline-4.2 declares own __P #include "readline/readline.h" ], [ @@ -27,7 +26,6 @@ AC_DEFUN(MYSQL_CHECK_LIBEDIT_INTERFACE,[ AC_TRY_COMPILE( [ #include "stdio.h" - #undef __P // readline-4.2 declares own __P #include "readline/readline.h" ], [ @@ -49,7 +47,6 @@ AC_DEFUN(MYSQL_CHECK_NEW_RL_INTERFACE,[ AC_TRY_COMPILE( [ #include "stdio.h" - #undef __P // readline-4.2 declares own __P #include "readline/readline.h" ], [ @@ -668,6 +665,41 @@ AC_DEFINE(STRUCT_DIRENT_HAS_D_INO, [1], fi ]) +AC_DEFUN(MYSQL_STRUCT_DIRENT_D_NAMLEN, +[AC_REQUIRE([AC_HEADER_DIRENT]) +AC_MSG_CHECKING(if struct dirent has a d_namlen member) +AC_CACHE_VAL(mysql_cv_dirent_has_dnamlen, +[AC_TRY_COMPILE([ +#include <stdio.h> +#include <sys/types.h> +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif /* HAVE_UNISTD_H */ +#if defined(HAVE_DIRENT_H) +# include <dirent.h> +#else +# define dirent direct +# ifdef HAVE_SYS_NDIR_H +# include <sys/ndir.h> +# endif /* SYSNDIR */ +# ifdef HAVE_SYS_DIR_H +# include <sys/dir.h> +# endif /* SYSDIR */ +# ifdef HAVE_NDIR_H +# include <ndir.h> +# endif +#endif /* HAVE_DIRENT_H */ +],[ +struct dirent d; int z; z = (int)d.d_namlen; +], mysql_cv_dirent_has_dnamlen=yes, mysql_cv_dirent_has_dnamlen=no)]) +AC_MSG_RESULT($mysql_cv_dirent_has_dnamlen) +if test "$mysql_cv_dirent_has_dnamlen" = "yes"; then +AC_DEFINE(STRUCT_DIRENT_HAS_D_NAMLEN, [1], + [d_namlen member present in struct dirent]) +fi +]) + + AC_DEFUN(MYSQL_TYPE_SIGHANDLER, [AC_MSG_CHECKING([whether signal handlers are of type void]) AC_CACHE_VAL(mysql_cv_void_sighandler, diff --git a/client/mysql.cc b/client/mysql.cc index 0fb6184e78a..8de9995f173 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -44,7 +44,7 @@ #include <locale.h> #endif -const char *VER= "14.5"; +const char *VER= "14.6"; /* Don't try to make a nice table if the data is too big */ #define MAX_COLUMN_LENGTH 1024 @@ -84,7 +84,6 @@ extern "C" { #if defined( __WIN__) || defined(OS2) #include <conio.h> #elif !defined(__NETWARE__) -#undef __P // readline-4.2 declares own __P #include <readline/readline.h> #define HAVE_READLINE #endif @@ -608,7 +607,7 @@ static struct my_option my_long_options[] = {"silent", 's', "Be more silent. Print results with a tab as separator, each row on new line.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #ifdef HAVE_SMEM - {"shared_memory_base_name", OPT_SHARED_MEMORY_BASE_NAME, + {"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME, "Base name of shared memory.", (gptr*) &shared_memory_base_name, (gptr*) &shared_memory_base_name, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #endif @@ -793,6 +792,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), while (*argument) *argument++= 'x'; // Destroy argument if (*start) start[1]=0 ; + tty_password= 0; } else tty_password= 1; @@ -859,7 +859,7 @@ static int get_options(int argc, char **argv) opt_max_allowed_packet= *mysql_params->p_max_allowed_packet; opt_net_buffer_length= *mysql_params->p_net_buffer_length; - if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) + if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option, 0))) exit(ho_error); *mysql_params->p_max_allowed_packet= opt_max_allowed_packet; @@ -1670,15 +1670,15 @@ static int com_server_help(String *buffer __attribute__((unused)), if (num_fields == 2) { put_info("Many help items for your request exist", INFO_INFO); - put_info("For more specific request please type 'help <item>' where item is one of next", INFO_INFO); + put_info("To make a more specific request, please type 'help <item>',\nwhere item is one of next", INFO_INFO); num_name= 0; num_cat= 1; last_char= '_'; } else if ((cur= mysql_fetch_row(result))) { - tee_fprintf(PAGER, "You asked help about help category: \"%s\"\n", cur[0]); - put_info("For a more information type 'help <item>' where item is one of the following", INFO_INFO); + tee_fprintf(PAGER, "You asked for help about help category: \"%s\"\n", cur[0]); + put_info("For more information, type 'help <item>', where item is one of the following", INFO_INFO); num_name= 1; num_cat= 2; print_help_item(&cur,1,2,&last_char); @@ -1692,7 +1692,7 @@ static int com_server_help(String *buffer __attribute__((unused)), else { put_info("\nNothing found", INFO_INFO); - put_info("Please try to run 'help contents' for list of all accessible topics\n", INFO_INFO); + put_info("Please try to run 'help contents' for a list of all accessible topics\n", INFO_INFO); } } @@ -1711,9 +1711,9 @@ 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 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("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); @@ -2020,21 +2020,27 @@ print_table_data(MYSQL_RES *result) while ((cur= mysql_fetch_row(result))) { + ulong *lengths= mysql_fetch_lengths(result); (void) tee_fputs("|", PAGER); mysql_field_seek(result, 0); for (uint off= 0; off < mysql_num_fields(result); off++) { const char *str= cur[off] ? cur[off] : "NULL"; field= mysql_fetch_field(result); - uint length= field->max_length; - if (length > MAX_COLUMN_LENGTH) + uint maxlength= field->max_length; + if (maxlength > MAX_COLUMN_LENGTH) { tee_fputs(str, PAGER); tee_fputs(" |", PAGER); } else - tee_fprintf(PAGER, num_flag[off] ? "%*s |" : " %-*s|", - length, str); + { + uint currlength= (uint) lengths[off]; + uint numcells= charset_info->cset->numcells(charset_info, + str, str + currlength); + tee_fprintf(PAGER, num_flag[off] ? "%*s |" : " %-*s|", + maxlength + currlength - numcells, str); + } } (void) tee_fputs("\n", PAGER); } diff --git a/client/mysqladmin.c b/client/mysqladmin.c index a3bb0fea180..d8842d98c6b 100644 --- a/client/mysqladmin.c +++ b/client/mysqladmin.c @@ -151,7 +151,7 @@ static struct my_option my_long_options[] = "Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #ifdef HAVE_SMEM - {"shared_memory_base_name", OPT_SHARED_MEMORY_BASE_NAME, + {"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME, "Base name of shared memory.", (gptr*) &shared_memory_base_name, (gptr*) &shared_memory_base_name, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #endif @@ -276,7 +276,7 @@ int main(int argc,char *argv[]) mysql_init(&mysql); load_defaults("my",load_default_groups,&argc,&argv); save_argv = argv; /* Save for free_defaults */ - if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) + if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option, 0))) { free_defaults(save_argv); exit(ho_error); diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 5f9a499bd31..6d8ff665393 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -666,7 +666,7 @@ static int parse_args(int *argc, char*** argv) result_file = stdout; load_defaults("my",load_default_groups,argc,argv); - if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option))) + if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option, NULL))) exit(ho_error); return 0; diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index 47512b2a277..904b234be64 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -125,7 +125,7 @@ static struct my_option my_long_options[] = "Can fix almost anything except unique keys that aren't unique.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #ifdef HAVE_SMEM - {"shared_memory_base_name", OPT_SHARED_MEMORY_BASE_NAME, + {"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME, "Base name of shared memory.", (gptr*) &shared_memory_base_name, (gptr*) &shared_memory_base_name, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #endif @@ -295,7 +295,7 @@ static int get_options(int *argc, char ***argv) load_defaults("my", load_default_groups, argc, argv); - if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option))) + if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option, 0))) exit(ho_error); if (!what_to_do) diff --git a/client/mysqldump.c b/client/mysqldump.c index 8fcf1bb1781..631f328a2f7 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -276,7 +276,7 @@ static struct my_option my_long_options[] = "Direct output to a given file. This option should be used in MSDOS, because it prevents new line '\\n' from being converted to '\\r\\n' (carriage return + line feed).", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #ifdef HAVE_SMEM - {"shared_memory_base_name", OPT_SHARED_MEMORY_BASE_NAME, + {"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME, "Base name of shared memory.", (gptr*) &shared_memory_base_name, (gptr*) &shared_memory_base_name, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #endif @@ -604,7 +604,7 @@ static int get_options(int *argc, char ***argv) md_result_file= stdout; load_defaults("my",load_default_groups,argc,argv); - if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option))) + if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option, 0))) exit(ho_error); *mysql_params->p_max_allowed_packet= opt_max_allowed_packet; diff --git a/client/mysqlimport.c b/client/mysqlimport.c index 86f373d75fe..73f7e0a9006 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -123,7 +123,7 @@ static struct my_option my_long_options[] = {"replace", 'r', "If duplicate unique key was found, replace old row.", (gptr*) &replace, (gptr*) &replace, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, #ifdef HAVE_SMEM - {"shared_memory_base_name", OPT_SHARED_MEMORY_BASE_NAME, + {"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME, "Base name of shared memory.", (gptr*) &shared_memory_base_name, (gptr*) &shared_memory_base_name, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #endif @@ -228,7 +228,7 @@ static int get_options(int *argc, char ***argv) { int ho_error; - if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option))) + if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option, 0))) exit(ho_error); if (enclosed && opt_enclosed) diff --git a/client/mysqlmanager-pwgen.c b/client/mysqlmanager-pwgen.c index 1d942e207ad..4c6fbf14dd9 100644 --- a/client/mysqlmanager-pwgen.c +++ b/client/mysqlmanager-pwgen.c @@ -95,7 +95,7 @@ int parse_args(int argc, char** argv) { int ho_error; - if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) + if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option, NULL))) exit(ho_error); return 0; diff --git a/client/mysqlmanagerc.c b/client/mysqlmanagerc.c index 0001a0266e6..78485427473 100644 --- a/client/mysqlmanagerc.c +++ b/client/mysqlmanagerc.c @@ -133,7 +133,7 @@ int parse_args(int argc, char **argv) load_defaults("my",load_default_groups,&argc,&argv); default_argv= argv; - if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) + if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option, NULL))) exit(ho_error); return 0; diff --git a/client/mysqlshow.c b/client/mysqlshow.c index 05108bd03c8..5d64c94ef1a 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -188,7 +188,7 @@ static struct my_option my_long_options[] = {"protocol", OPT_MYSQL_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #ifdef HAVE_SMEM - {"shared_memory_base_name", OPT_SHARED_MEMORY_BASE_NAME, + {"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME, "Base name of shared memory.", (gptr*) &shared_memory_base_name, (gptr*) &shared_memory_base_name, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #endif @@ -297,7 +297,7 @@ get_options(int *argc,char ***argv) { int ho_error; - if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option))) + if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option, 0))) exit(ho_error); if (tty_password) diff --git a/client/mysqltest.c b/client/mysqltest.c index 3287c9738d3..98818022047 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -2100,7 +2100,7 @@ int parse_args(int argc, char **argv) load_defaults("my",load_default_groups,&argc,&argv); default_argv= argv; - if ((handle_options(&argc, &argv, my_long_options, get_one_option))) + if ((handle_options(&argc, &argv, my_long_options, get_one_option, 0))) exit(1); if (argc > 1) diff --git a/cmd-line-utils/libedit/Makefile.am b/cmd-line-utils/libedit/Makefile.am index c532884ca7d..c6f9ccf06ff 100644 --- a/cmd-line-utils/libedit/Makefile.am +++ b/cmd-line-utils/libedit/Makefile.am @@ -23,14 +23,14 @@ libedit_a_DEPENDENCIES = @LIBEDIT_LOBJECTS@ pkginclude_HEADERS = readline/readline.h noinst_HEADERS = chared.h el.h histedit.h key.h parse.h refresh.h sig.h \ - sys.h tokenizer.h config.h hist.h map.h prompt.h \ - search.h tty.h + sys.h tokenizer.h config.h hist.h map.h prompt.h read.h \ + search.h tty.h libedit_term.h term.h -EXTRA_DIST = makelist.sh np/unvis.c np/strlcpy.c np/vis.c np/strlcat.c np/fgetln.c +EXTRA_DIST = makelist.sh np/unvis.c np/strlcpy.c np/vis.c np/vis.h np/strlcat.c np/fgetln.c CLEANFILES = makelist common.h emacs.h vi.h fcns.h help.h fcns.c help.c -DEFS = -DUNDEF_THREADS_HACK -DHAVE_CONFIG_H -DNO_KILL_INTR '-D__RCSID(x)=' '-D__COPYRIGHT(x)=' '-D__RENAME(x)=' '-D_DIAGASSERT(x)=' +DEFS = -DUNDEF_THREADS_HACK -DHAVE_CONFIG_H -DNO_KILL_INTR SUFFIXES = .sh diff --git a/cmd-line-utils/libedit/chared.c b/cmd-line-utils/libedit/chared.c index 559e714d9fd..62a407e66a8 100644 --- a/cmd-line-utils/libedit/chared.c +++ b/cmd-line-utils/libedit/chared.c @@ -62,13 +62,13 @@ cv_undo(EditLine *el) { c_undo_t *vu = &el->el_chared.c_undo; c_redo_t *r = &el->el_chared.c_redo; - uint size; + int size; /* Save entire line for undo */ size = el->el_line.lastchar - el->el_line.buffer; vu->len = size; vu->cursor = el->el_line.cursor - el->el_line.buffer; - memcpy(vu->buf, el->el_line.buffer, size); + memcpy(vu->buf, el->el_line.buffer, (size_t)size); /* save command info for redo */ r->count = el->el_state.doingarg ? el->el_state.argument : 0; diff --git a/cmd-line-utils/libedit/config.h b/cmd-line-utils/libedit/config.h new file mode 100644 index 00000000000..b6f002d5b9e --- /dev/null +++ b/cmd-line-utils/libedit/config.h @@ -0,0 +1,14 @@ + +#include "my_config.h" +#include "sys.h" + +#define __RCSID(x) +#define __COPYRIGHT(x) +#define __RENAME(x) +#define _DIAGASSERT(x) + +#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ < 8) +#define __attribute__(A) +#endif + + diff --git a/cmd-line-utils/libedit/history.c b/cmd-line-utils/libedit/history.c index 0294734b9a3..53648203bf0 100644 --- a/cmd-line-utils/libedit/history.c +++ b/cmd-line-utils/libedit/history.c @@ -661,12 +661,6 @@ history_load(History *h, const char *fname) if ((fp = fopen(fname, "r")) == NULL) return (i); - if ((line = fgetln(fp, &sz)) == NULL) - goto done; - - if (strncmp(line, hist_cookie, sz) != 0) - goto done; - ptr = h_malloc(max_size = 1024); if (ptr == NULL) goto done; @@ -720,8 +714,6 @@ history_save(History *h, const char *fname) if (fchmod(fileno(fp), S_IRUSR|S_IWUSR) == -1) goto done; - if (fputs(hist_cookie, fp) == EOF) - goto done; ptr = h_malloc(max_size = 1024); if (ptr == NULL) goto done; @@ -740,7 +732,7 @@ history_save(History *h, const char *fname) ptr = nptr; } (void) strvis(ptr, ev.str, VIS_WHITE); - (void) fprintf(fp, "%s\n", ptr); + (void) fprintf(fp, "%s\n", ev.str); } oomem: h_free((ptr_t)ptr); diff --git a/cmd-line-utils/libedit/np/unvis.c b/cmd-line-utils/libedit/np/unvis.c index 01056c776e9..895ff2059ac 100644 --- a/cmd-line-utils/libedit/np/unvis.c +++ b/cmd-line-utils/libedit/np/unvis.c @@ -33,6 +33,7 @@ * SUCH DAMAGE. */ +#include "config.h" #if defined(LIBC_SCCS) && !defined(lint) #if 0 static char sccsid[] = "@(#)unvis.c 8.1 (Berkeley) 6/4/93"; diff --git a/cmd-line-utils/libedit/np/vis.c b/cmd-line-utils/libedit/np/vis.c index 9abc2e6e478..db42443800b 100644 --- a/cmd-line-utils/libedit/np/vis.c +++ b/cmd-line-utils/libedit/np/vis.c @@ -34,12 +34,12 @@ * SUCH DAMAGE. */ +#include "config.h" + #if defined(LIBC_SCCS) && !defined(lint) __RCSID("$NetBSD: vis.c,v 1.22 2002/03/23 17:38:27 christos Exp $"); #endif /* LIBC_SCCS and not lint */ -#include "config.h" - #include <sys/types.h> #include <assert.h> #ifdef HAVE_ALLOCA_H diff --git a/cmd-line-utils/libedit/readline.c b/cmd-line-utils/libedit/readline.c index 13b0369de96..5b40ade582c 100644 --- a/cmd-line-utils/libedit/readline.c +++ b/cmd-line-utils/libedit/readline.c @@ -1345,7 +1345,7 @@ filename_completion_function(const char *text, int state) /* otherwise, get first entry where first */ /* filename_len characters are equal */ if (entry->d_name[0] == filename[0] -#if defined(__SVR4) || defined(__linux__) +#ifndef STRUCT_DIRENT_HAS_D_NAMLEN && strlen(entry->d_name) >= filename_len #else && entry->d_namlen >= filename_len @@ -1358,7 +1358,7 @@ filename_completion_function(const char *text, int state) if (entry) { /* match found */ struct stat stbuf; -#if defined(__SVR4) || defined(__linux__) +#ifndef STRUCT_DIRENT_HAS_D_NAMLEN len = strlen(entry->d_name) + #else len = entry->d_namlen + diff --git a/cmd-line-utils/libedit/search.c b/cmd-line-utils/libedit/search.c index 48049687875..0957529485c 100644 --- a/cmd-line-utils/libedit/search.c +++ b/cmd-line-utils/libedit/search.c @@ -50,6 +50,7 @@ __RCSID("$NetBSD: search.c,v 1.14 2002/11/20 16:50:08 christos Exp $"); */ #include <stdlib.h> #if defined(REGEX) +#include <sys/types.h> #include <regex.h> #elif defined(REGEXP) #include <regexp.h> diff --git a/configure.in b/configure.in index d40cfbbae19..7c48eddf952 100644 --- a/configure.in +++ b/configure.in @@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script. AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! -AM_INIT_AUTOMAKE(mysql, 4.1.4-gamma) +AM_INIT_AUTOMAKE(mysql, 4.1.5-gamma) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 @@ -972,8 +972,8 @@ MAX_CXX_OPTIMIZE="-O3" # workaround for Sun Forte/x86 see BUG#4681 case $SYSTEM_TYPE-$MACHINE_TYPE-$ac_cv_prog_gcc in *solaris*-i?86-no) - CFLAGS="$CFLAGS -DBIG_FILES" - CXXFLAGS="$CXXFLAGS -DBIG_FILES" + CFLAGS="$CFLAGS -DBIG_TABLES" + CXXFLAGS="$CXXFLAGS -DBIG_TABLES" ;; *) ;; esac @@ -1865,6 +1865,7 @@ MYSQL_HAVE_TIOCGWINSZ MYSQL_HAVE_FIONREAD MYSQL_HAVE_TIOCSTAT MYSQL_STRUCT_DIRENT_D_INO +MYSQL_STRUCT_DIRENT_D_NAMLEN MYSQL_TYPE_SIGHANDLER if test "$with_named_curses" = "no" then @@ -2402,7 +2403,7 @@ dnl you must also create strings/ctype-$charset_name.c AC_DIVERT_PUSH(0) define(CHARSETS_AVAILABLE0,binary) -define(CHARSETS_AVAILABLE1,ascii armscii8 ascii big5 cp1250 cp1251 cp1256 cp1257) +define(CHARSETS_AVAILABLE1,armscii8 ascii big5 cp1250 cp1251 cp1256 cp1257) define(CHARSETS_AVAILABLE2,cp850 cp852 cp866 dec8 euckr gb2312 gbk geostd8) define(CHARSETS_AVAILABLE3,greek hebrew hp8 keybcs2 koi8r koi8u) define(CHARSETS_AVAILABLE4,latin1 latin2 latin5 latin7 macce macroman) diff --git a/extra/my_print_defaults.c b/extra/my_print_defaults.c index f4da839f8e2..a0af98e5f1c 100644 --- a/extra/my_print_defaults.c +++ b/extra/my_print_defaults.c @@ -99,7 +99,7 @@ static int get_options(int *argc,char ***argv) { int ho_error; - if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option))) + if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option, NULL))) exit(ho_error); if (*argc < 1) diff --git a/extra/mysql_waitpid.c b/extra/mysql_waitpid.c index bff1752ec21..0894d81a5ae 100644 --- a/extra/mysql_waitpid.c +++ b/extra/mysql_waitpid.c @@ -20,6 +20,7 @@ #include <my_global.h> #include <m_string.h> +#include <my_sys.h> #include <my_getopt.h> #include <signal.h> #include <errno.h> @@ -66,7 +67,7 @@ int main(int argc, char *argv[]) progname= argv[0]; - if (handle_options(&argc, &argv, my_long_options, get_one_option)) + if (handle_options(&argc, &argv, my_long_options, get_one_option, NULL)) exit(-1); if (!argv[0] || !argv[1] || (pid= atoi(argv[0])) <= 0 || (t= atoi(argv[1])) <= 0) diff --git a/extra/perror.c b/extra/perror.c index a28626fd873..b029d87040f 100644 --- a/extra/perror.c +++ b/extra/perror.c @@ -157,7 +157,7 @@ static int get_options(int *argc,char ***argv) { int ho_error; - if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option))) + if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option, NULL))) exit(ho_error); if (!*argc && !print_all_codes) diff --git a/extra/resolve_stack_dump.c b/extra/resolve_stack_dump.c index 06a670b935d..3c26c315dea 100644 --- a/extra/resolve_stack_dump.c +++ b/extra/resolve_stack_dump.c @@ -121,7 +121,7 @@ static int parse_args(int argc, char **argv) { int ho_error; - if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) + if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option, NULL))) exit(ho_error); /* diff --git a/extra/resolveip.c b/extra/resolveip.c index f8cff2a976c..a995b038770 100644 --- a/extra/resolveip.c +++ b/extra/resolveip.c @@ -90,7 +90,7 @@ static int get_options(int *argc,char ***argv) { int ho_error; - if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option))) + if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option, NULL))) exit(ho_error); if (*argc == 0) diff --git a/heap/hp_hash.c b/heap/hp_hash.c index 8feae19a480..71eecc8bdf2 100644 --- a/heap/hp_hash.c +++ b/heap/hp_hash.c @@ -246,12 +246,12 @@ ulong hp_hashnr(register HP_KEYDEF *keydef, register const byte *key) if (seg->type == HA_KEYTYPE_TEXT) { CHARSET_INFO *cs= seg->charset; - uint length= ((uchar*)key) - pos; - uint char_length= length / cs->mbmaxlen; - if (length > char_length) + uint char_length= (uint) ((uchar*) key - pos); + if (cs->mbmaxlen > 1) { - char_length= my_charpos(cs, pos, pos + length, char_length); - set_if_smaller(char_length, length); + uint length= char_length; + char_length= my_charpos(cs, pos, pos + length, length/cs->mbmaxlen); + set_if_smaller(char_length, length); /* QQ: ok to remove? */ } cs->coll->hash_sort(cs, pos, char_length, &nr, &nr2); } @@ -289,11 +289,12 @@ ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec) if (seg->type == HA_KEYTYPE_TEXT) { CHARSET_INFO *cs= seg->charset; - uint char_length= seg->length / cs->mbmaxlen; - if (seg->length > char_length) + uint char_length= seg->length; + if (cs->mbmaxlen > 1) { - char_length= my_charpos(cs, pos, pos + seg->length, char_length); - set_if_smaller(char_length, seg->length); + char_length= my_charpos(cs, pos, pos + char_length, + char_length / cs->mbmaxlen); + set_if_smaller(char_length, seg->length); /* QQ: ok to remove? */ } cs->coll->hash_sort(cs, pos, char_length, &nr, &nr2); } @@ -417,17 +418,17 @@ int hp_rec_key_cmp(HP_KEYDEF *keydef, const byte *rec1, const byte *rec2) if (seg->type == HA_KEYTYPE_TEXT) { CHARSET_INFO *cs= seg->charset; - uint char_length= seg->length / cs->mbmaxlen; uint char_length1; uint char_length2; uchar *pos1= (uchar*)rec1 + seg->start; uchar *pos2= (uchar*)rec2 + seg->start; - if (seg->length > char_length) + if (cs->mbmaxlen > 1) { + uint char_length= seg->length / cs->mbmaxlen; char_length1= my_charpos(cs, pos1, pos1 + seg->length, char_length); - set_if_smaller(char_length1, seg->length); + set_if_smaller(char_length1, seg->length); /* QQ: ok to remove? */ char_length2= my_charpos(cs, pos2, pos2 + seg->length, char_length); - set_if_smaller(char_length2, seg->length); + set_if_smaller(char_length2, seg->length); /* QQ: ok to remove? */ } else { @@ -468,12 +469,12 @@ int hp_key_cmp(HP_KEYDEF *keydef, const byte *rec, const byte *key) if (seg->type == HA_KEYTYPE_TEXT) { CHARSET_INFO *cs= seg->charset; - uint char_length= seg->length / cs->mbmaxlen; uint char_length_key; uint char_length_rec; uchar *pos= (uchar*) rec + seg->start; - if (seg->length > char_length) + if (cs->mbmaxlen > 1) { + uint char_length= seg->length / cs->mbmaxlen; char_length_key= my_charpos(cs, key, key + seg->length, char_length); set_if_smaller(char_length_key, seg->length); char_length_rec= my_charpos(cs, pos, pos + seg->length, char_length); @@ -509,21 +510,22 @@ void hp_make_key(HP_KEYDEF *keydef, byte *key, const byte *rec) for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++) { CHARSET_INFO *cs= seg->charset; - uint char_length= (cs && cs->mbmaxlen > 1) ? seg->length / cs->mbmaxlen : - seg->length; + uint char_length= seg->length; uchar *pos= (uchar*) rec + seg->start; if (seg->null_bit) *key++= test(rec[seg->null_pos] & seg->null_bit); - if (seg->length > char_length) + if (cs->mbmaxlen > 1) { - char_length= my_charpos(cs, pos, pos + seg->length, char_length); - set_if_smaller(char_length, seg->length); + char_length= my_charpos(cs, pos, pos + seg->length, + char_length / cs->mbmaxlen); + set_if_smaller(char_length, seg->length); /* QQ: ok to remove? */ } memcpy(key,rec+seg->start,(size_t) char_length); key+= char_length; } } + uint hp_rb_make_key(HP_KEYDEF *keydef, byte *key, const byte *rec, byte *recpos) { @@ -575,13 +577,13 @@ uint hp_rb_make_key(HP_KEYDEF *keydef, byte *key, } continue; } - char_length= seg->length / (seg->charset ? seg->charset->mbmaxlen : 1); - if (seg->length > char_length) + char_length= seg->length; + if (seg->charset->mbmaxlen > 1) { char_length= my_charpos(seg->charset, - rec + seg->start, rec + seg->start + seg->length, - char_length); - set_if_smaller(char_length, seg->length); + rec + seg->start, rec + seg->start + char_length, + char_length / seg->charset->mbmaxlen); + set_if_smaller(char_length, seg->length); /* QQ: ok to remove? */ if (char_length < seg->length) seg->charset->cset->fill(seg->charset, key + char_length, seg->length - char_length, ' '); @@ -593,7 +595,9 @@ uint hp_rb_make_key(HP_KEYDEF *keydef, byte *key, return key - start_key; } -uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old, uint k_len) + +uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old, + uint k_len) { HA_KEYSEG *seg, *endseg; uchar *start_key= key; @@ -623,11 +627,12 @@ uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old, uint k_len) } continue; } - char_length= seg->length / (seg->charset ? seg->charset->mbmaxlen : 1); - if (seg->length > char_length) + char_length= seg->length; + if (seg->charset->mbmaxlen > 1) { - char_length= my_charpos(seg->charset, old, old+seg->length, char_length); - set_if_smaller(char_length, seg->length); + char_length= my_charpos(seg->charset, old, old+char_length, + char_length / seg->charset->mbmaxlen); + set_if_smaller(char_length, seg->length); /* QQ: ok to remove? */ if (char_length < seg->length) seg->charset->cset->fill(seg->charset, key + char_length, seg->length - char_length, ' '); @@ -639,12 +644,14 @@ uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old, uint k_len) return key - start_key; } + uint hp_rb_key_length(HP_KEYDEF *keydef, const byte *key __attribute__((unused))) { return keydef->length; } + uint hp_rb_null_key_length(HP_KEYDEF *keydef, const byte *key) { const byte *start_key= key; diff --git a/include/m_ctype.h b/include/m_ctype.h index 1b6e7bf6739..65b11f4c06a 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -149,6 +149,7 @@ typedef struct my_charset_handler_st uint (*well_formed_len)(struct charset_info_st *, const char *b,const char *e, uint nchars); uint (*lengthsp)(struct charset_info_st *, const char *ptr, uint length); + uint (*numcells)(struct charset_info_st *, const char *b, const char *e); /* Unicode convertion */ int (*mb_wc)(struct charset_info_st *cs,my_wc_t *wc, @@ -325,6 +326,7 @@ int my_wildcmp_8bit(CHARSET_INFO *, int escape, int w_one, int w_many); uint my_numchars_8bit(CHARSET_INFO *, const char *b, const char *e); +uint my_numcells_8bit(CHARSET_INFO *, const char *b, const char *e); uint my_charpos_8bit(CHARSET_INFO *, const char *b, const char *e, uint pos); uint my_well_formed_len_8bit(CHARSET_INFO *, const char *b, const char *e, uint pos); int my_mbcharlen_8bit(CHARSET_INFO *, uint c); @@ -342,6 +344,7 @@ int my_wildcmp_mb(CHARSET_INFO *, const char *wildstr,const char *wildend, int escape, int w_one, int w_many); uint my_numchars_mb(CHARSET_INFO *, const char *b, const char *e); +uint my_numcells_mb(CHARSET_INFO *, const char *b, const char *e); uint my_charpos_mb(CHARSET_INFO *, const char *b, const char *e, uint pos); uint my_well_formed_len_mb(CHARSET_INFO *, const char *b, const char *e, uint pos); uint my_instr_mb(struct charset_info_st *, diff --git a/include/m_string.h b/include/m_string.h index 0709dbaffb4..97d34421537 100644 --- a/include/m_string.h +++ b/include/m_string.h @@ -238,6 +238,9 @@ longlong my_strtoll10(const char *nptr, char **endptr, int *error); #ifndef HAVE_STRTOULL #define HAVE_STRTOULL #endif +#ifndef HAVE_STRTOLL +#define HAVE_STRTOLL +#endif #else #ifdef HAVE_LONG_LONG extern char *longlong2str(longlong val,char *dst,int radix); diff --git a/include/my_getopt.h b/include/my_getopt.h index bf119892a31..9d6ef40b399 100644 --- a/include/my_getopt.h +++ b/include/my_getopt.h @@ -14,6 +14,9 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#ifndef _my_getopt_h +#define _my_getopt_h + C_MODE_START #define GET_NO_ARG 1 @@ -54,11 +57,12 @@ struct my_option extern char *disabled_my_option; extern my_bool my_getopt_print_errors; +typedef my_bool (* my_get_one_option) (int, const struct my_option *, char * ); +typedef void (* my_error_reporter) (enum loglevel level, const char *format, ... ); + extern int handle_options (int *argc, char ***argv, - const struct my_option *longopts, - my_bool (*get_one_option)(int, - const struct my_option *, - char *)); + const struct my_option *longopts, my_get_one_option, + my_error_reporter ); extern void my_print_help(const struct my_option *options); extern void my_print_variables(const struct my_option *options); extern void my_getopt_register_get_addr(gptr* (*func_addr)(const char *, uint, @@ -66,4 +70,8 @@ extern void my_getopt_register_get_addr(gptr* (*func_addr)(const char *, uint, ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp); my_bool getopt_compare_strings(const char *s, const char *t, uint length); + C_MODE_END + +#endif /* _my_getopt_h */ + diff --git a/include/my_sys.h b/include/my_sys.h index 922e6d8cff4..ad1966ba67f 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -244,6 +244,12 @@ typedef struct wild_file_pack /* Struct to hold info when selecting files */ my_string *wild; /* Pointer to wildcards */ } WF_PACK; +enum loglevel { + ERROR_LEVEL, + WARNING_LEVEL, + INFORMATION_LEVEL +}; + enum cache_type { READ_CACHE,WRITE_CACHE, diff --git a/include/mysql.h b/include/mysql.h index e2ed3ab59af..cf5af6ce189 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -99,7 +99,7 @@ typedef struct st_mysql_field { unsigned int flags; /* Div flags */ unsigned int decimals; /* Number of decimals in field */ unsigned int charsetnr; /* Character set */ - enum enum_field_types type; /* Type of field. Se mysql_com.h for types */ + enum enum_field_types type; /* Type of field. See mysql_com.h for types */ } MYSQL_FIELD; typedef char **MYSQL_ROW; /* return data as array of strings */ @@ -175,7 +175,7 @@ struct st_mysql_options { */ my_bool rpl_parse; /* - If set, never read from a master,only from slave, when doing + If set, never read from a master, only from slave, when doing a read that is replication-aware */ my_bool no_master_reads; @@ -538,7 +538,7 @@ enum enum_mysql_stmt_state typedef struct st_mysql_bind { unsigned long *length; /* output length pointer */ - my_bool *is_null; /* Pointer to null indicators */ + my_bool *is_null; /* Pointer to null indicator */ void *buffer; /* buffer to get/put data */ enum enum_field_types buffer_type; /* buffer type */ unsigned long buffer_length; /* buffer length, must be set for str/binary */ @@ -581,7 +581,7 @@ typedef struct st_mysql_stmt unsigned char **row); unsigned long stmt_id; /* Id for prepared statement */ unsigned int last_errno; /* error code */ - unsigned int param_count; /* inpute parameters count */ + unsigned int param_count; /* input parameter count */ unsigned int field_count; /* number of columns in result set */ enum enum_mysql_stmt_state state; /* statement state */ char last_error[MYSQL_ERRMSG_SIZE]; /* error message */ diff --git a/include/mysqld_error.h b/include/mysqld_error.h index 4d65515d6ce..776869ff045 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -318,4 +318,5 @@ #define ER_WARN_INVALID_TIMESTAMP 1299 #define ER_INVALID_CHARACTER_STRING 1300 #define ER_WARN_ALLOWED_PACKET_OVERFLOWED 1301 -#define ER_ERROR_MESSAGES 302 +#define ER_CONFLICTING_DECLARATIONS 1302 +#define ER_ERROR_MESSAGES 303 diff --git a/innobase/buf/buf0rea.c b/innobase/buf/buf0rea.c index 71e885ff439..11107d777c8 100644 --- a/innobase/buf/buf0rea.c +++ b/innobase/buf/buf0rea.c @@ -629,6 +629,8 @@ buf_read_ibuf_merge_pages( } } + os_aio_simulated_wake_handler_threads(); + /* Flush pages from the end of the LRU list if necessary */ buf_flush_free_margin(); diff --git a/isam/isamchk.c b/isam/isamchk.c index 5dd20c14063..c0ba810ef64 100644 --- a/isam/isamchk.c +++ b/isam/isamchk.c @@ -671,7 +671,7 @@ static void get_options(register int *argc, register char ***argv) if (isatty(fileno(stdout))) testflag|=T_WRITE_LOOP; - if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option))) + if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option, NULL))) exit(ho_error); if (*argc == 0) diff --git a/isam/pack_isam.c b/isam/pack_isam.c index aa83b2b2a96..6e03df100a2 100644 --- a/isam/pack_isam.c +++ b/isam/pack_isam.c @@ -337,7 +337,7 @@ static void get_options(int *argc, char ***argv) { int ho_error; - if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option))) + if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option, NULL))) exit(ho_error); my_progname= argv[0][0]; diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index cea8ce3a499..380e53d7d47 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -3339,6 +3339,7 @@ static void fetch_string_with_conversion(MYSQL_BIND *param, char *value, } case MYSQL_TYPE_DATE: case MYSQL_TYPE_DATETIME: + case MYSQL_TYPE_TIMESTAMP: { MYSQL_TIME *tm= (MYSQL_TIME *)buffer; str_to_datetime(value, length, tm, 0, &err); @@ -3393,7 +3394,7 @@ static void fetch_long_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field, longlong value) { char *buffer= (char *)param->buffer; - uint field_is_unsigned= (field->flags & UNSIGNED_FLAG); + uint field_is_unsigned= field->flags & UNSIGNED_FLAG; switch (param->buffer_type) { case MYSQL_TYPE_NULL: /* do nothing */ @@ -3429,7 +3430,7 @@ static void fetch_long_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field, char buff[22]; /* Enough for longlong */ char *end= longlong10_to_str(value, buff, field_is_unsigned ? 10: -10); /* Resort to string conversion which supports all typecodes */ - fetch_string_with_conversion(param, buff, end - buff); + fetch_string_with_conversion(param, buff, (uint) (end - buff)); break; } } @@ -3505,7 +3506,7 @@ static void fetch_float_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field, sprintf(buff, "%.*f", (int) field->decimals, value); end= strend(buff); } - fetch_string_with_conversion(param, buff, end - buff); + fetch_string_with_conversion(param, buff, (uint) (end - buff)); break; } } @@ -3590,14 +3591,14 @@ static void fetch_result_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field, { ulong length; enum enum_field_types field_type= field->type; + uint field_is_unsigned= field->flags & UNSIGNED_FLAG; switch (field_type) { case MYSQL_TYPE_TINY: { char value= (char) **row; - uint field_is_unsigned= (field->flags & UNSIGNED_FLAG); - longlong data= (field_is_unsigned) ? (longlong) (unsigned char) value: - (longlong) value; + longlong data= field_is_unsigned ? (longlong) (unsigned char) value : + (longlong) value; fetch_long_with_conversion(param, field, data); length= 1; break; @@ -3606,19 +3607,18 @@ static void fetch_result_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field, case MYSQL_TYPE_YEAR: { short value= sint2korr(*row); - uint field_is_unsigned= (field->flags & UNSIGNED_FLAG); - longlong data= ((field_is_unsigned) ? (longlong) (unsigned short) value: - (longlong) value); + longlong data= field_is_unsigned ? (longlong) (unsigned short) value : + (longlong) value; fetch_long_with_conversion(param, field, data); length= 2; break; } + case MYSQL_TYPE_INT24: /* mediumint is sent as 4 bytes int */ case MYSQL_TYPE_LONG: { long value= sint4korr(*row); - uint field_is_unsigned= (field->flags & UNSIGNED_FLAG); - longlong data= ((field_is_unsigned) ? (longlong) (unsigned long) value: - (longlong) value); + longlong data= field_is_unsigned ? (longlong) (unsigned long) value : + (longlong) value; fetch_long_with_conversion(param, field, data); length= 4; break; diff --git a/libmysqld/libmysqld.rc b/libmysqld/libmysqld.rc new file mode 100755 index 00000000000..5b6142faddf --- /dev/null +++ b/libmysqld/libmysqld.rc @@ -0,0 +1,125 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 4,0,20,0 + PRODUCTVERSION 4,0,20,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x9L +#else + FILEFLAGS 0x8L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN +#ifdef _DEBUG + VALUE "Comments", "Embedded Server\0" + VALUE "CompanyName", "MySQL AB\0" + VALUE "FileDescription", "Embedded Server\0" + VALUE "FileVersion", "4.0.20\0" + VALUE "InternalName", "Embedded Server\0" + VALUE "LegalCopyright", "Copyright 2004\0" + VALUE "LegalTrademarks", "MySQL and MySQL AB\0" + VALUE "OriginalFilename", "libmysqld.dll debug\0" + VALUE "PrivateBuild", "libmysqld.dll debug \0" + VALUE "ProductName", "libmysqld.dll debug\0" + VALUE "ProductVersion", "4.0.20\0" + VALUE "SpecialBuild", "\0" +#else + VALUE "Comments", "Embedded Server\0" + VALUE "CompanyName", "MySQL AB\0" + VALUE "FileDescription", "Embedded Server\0" + VALUE "FileVersion", "4.0.20\0" + VALUE "InternalName", "Embedded Server\0" + VALUE "LegalCopyright", "Copyright 2004\0" + VALUE "LegalTrademarks", "MySQL and MySQL AB\0" + VALUE "OriginalFilename", "libmysqld.dll release\0" + VALUE "PrivateBuild", "libmysqld.dll release \0" + VALUE "ProductName", "libmysqld.dll release\0" + VALUE "ProductVersion", "4.0.20\0" + VALUE "SpecialBuild", "\0" +#endif + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // !_MAC + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/libmysqld/resource.h b/libmysqld/resource.h new file mode 100755 index 00000000000..f770fe490a6 --- /dev/null +++ b/libmysqld/resource.h @@ -0,0 +1,15 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by libmysqld.rc +// + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/myisam/ftdefs.h b/myisam/ftdefs.h index e23bc3b75ac..e7a0829e140 100644 --- a/myisam/ftdefs.h +++ b/myisam/ftdefs.h @@ -27,7 +27,7 @@ #define misc_word_char(X) ((X)=='\'') #define word_char(s,X) (true_word_char(s,X) || misc_word_char(X)) -#define FT_MAX_WORD_LEN_FOR_SORT 20 +#define FT_MAX_WORD_LEN_FOR_SORT 31 #define COMPILE_STOPWORDS_IN diff --git a/myisam/mi_check.c b/myisam/mi_check.c index 052fa55a559..a1c3698b3e9 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -2020,12 +2020,14 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, if (sort_param.keyinfo->flag & HA_FULLTEXT) { + uint ft_max_word_len_for_sort=FT_MAX_WORD_LEN_FOR_SORT* + sort_param.keyinfo->seg->charset->mbmaxlen; sort_info.max_records= - (ha_rows) (sort_info.filelength/FT_MAX_WORD_LEN_FOR_SORT+1); + (ha_rows) (sort_info.filelength/ft_max_word_len_for_sort+1); sort_param.key_read=sort_ft_key_read; sort_param.key_write=sort_ft_key_write; - sort_param.key_length+=FT_MAX_WORD_LEN_FOR_SORT-HA_FT_MAXBYTELEN; + sort_param.key_length+=ft_max_word_len_for_sort-HA_FT_MAXBYTELEN; } else { @@ -2425,7 +2427,11 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info, total_key_length+=sort_param[i].key_length; if (sort_param[i].keyinfo->flag & HA_FULLTEXT) - sort_param[i].key_length+=FT_MAX_WORD_LEN_FOR_SORT-HA_FT_MAXBYTELEN; + { + uint ft_max_word_len_for_sort=FT_MAX_WORD_LEN_FOR_SORT* + sort_param[i].keyinfo->seg->charset->mbmaxlen; + sort_param[i].key_length+=ft_max_word_len_for_sort-HA_FT_MAXBYTELEN; + } } sort_info.total_keys=i; sort_param[0].master= 1; @@ -2634,7 +2640,6 @@ static int sort_key_read(MI_SORT_PARAM *sort_param, void *key) DBUG_RETURN(sort_write_record(sort_param)); } /* sort_key_read */ - static int sort_ft_key_read(MI_SORT_PARAM *sort_param, void *key) { int error; @@ -3950,25 +3955,28 @@ static ha_checksum mi_byte_checksum(const byte *buf, uint length) return crc; } -/* - Deactive all not unique index that can be recreated fast - These include packed keys on which sorting will use more temporary - space than the max allowed file length or for which the unpacked keys - will take much more space than packed keys. - Note that 'rows' may be zero for the case when we don't know how many - rows we will put into the file. - */ - static my_bool mi_too_big_key_for_sort(MI_KEYDEF *key, ha_rows rows) { uint key_maxlength=key->maxlength; if (key->flag & HA_FULLTEXT) - key_maxlength+=FT_MAX_WORD_LEN_FOR_SORT-HA_FT_MAXBYTELEN; + { + uint ft_max_word_len_for_sort=FT_MAX_WORD_LEN_FOR_SORT* + key->seg->charset->mbmaxlen; + key_maxlength+=ft_max_word_len_for_sort-HA_FT_MAXBYTELEN; + } return (key->flag & (HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY | HA_FULLTEXT) && ((ulonglong) rows * key_maxlength > (ulonglong) myisam_max_temp_length)); } +/* + Deactivate all not unique index that can be recreated fast + These include packed keys on which sorting will use more temporary + space than the max allowed file length or for which the unpacked keys + will take much more space than packed keys. + Note that 'rows' may be zero for the case when we don't know how many + rows we will put into the file. + */ void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows) { diff --git a/myisam/mi_key.c b/myisam/mi_key.c index 8f5f0e829ef..3545756779f 100644 --- a/myisam/mi_key.c +++ b/myisam/mi_key.c @@ -23,11 +23,14 @@ #include <ieeefp.h> #endif -#define CHECK_KEYS +#define CHECK_KEYS /* Enable safety checks */ -#define FIX_LENGTH if (length > char_length) \ - char_length= my_charpos(cs, pos, pos+length, char_length); \ - set_if_smaller(char_length,length); \ +#define FIX_LENGTH(cs, pos, length, char_length) \ + do { \ + if (length > char_length) \ + char_length= my_charpos(cs, pos, pos+length, char_length); \ + set_if_smaller(char_length,length); \ + } while(0) static int _mi_put_key_in_record(MI_INFO *info,uint keynr,byte *record); @@ -45,7 +48,7 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key, my_bool is_ft= info->s->keyinfo[keynr].flag & HA_FULLTEXT; DBUG_ENTER("_mi_make_key"); - if(info->s->keyinfo[keynr].flag & HA_SPATIAL) + if (info->s->keyinfo[keynr].flag & HA_SPATIAL) { /* TODO: nulls processing @@ -75,7 +78,8 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key, *key++=1; /* Not NULL */ } - char_length= (!is_ft && cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen : length; + char_length= ((!is_ft && cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen : + length); pos= (byte*) record+keyseg->start; if (keyseg->flag & HA_SPACE_PACK) @@ -92,7 +96,7 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key, pos++; } length=(uint) (end-pos); - FIX_LENGTH; + FIX_LENGTH(cs, pos, length, char_length); store_key_length_inc(key,char_length); memcpy((byte*) key,(byte*) pos,(size_t) char_length); key+=char_length; @@ -103,7 +107,7 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key, uint tmp_length=uint2korr(pos); pos+=2; /* Skip VARCHAR length */ set_if_smaller(length,tmp_length); - FIX_LENGTH; + FIX_LENGTH(cs, pos, length, char_length); store_key_length_inc(key,char_length); memcpy((byte*) key,(byte*) pos,(size_t) char_length); key+= char_length; @@ -114,7 +118,7 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key, uint tmp_length=_mi_calc_blob_length(keyseg->bit_start,pos); memcpy_fixed((byte*) &pos,pos+keyseg->bit_start,sizeof(char*)); set_if_smaller(length,tmp_length); - FIX_LENGTH; + FIX_LENGTH(cs, pos, length, char_length); store_key_length_inc(key,char_length); memcpy((byte*) key,(byte*) pos,(size_t) char_length); key+= char_length; @@ -154,10 +158,10 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key, } continue; } - FIX_LENGTH; + FIX_LENGTH(cs, pos, length, char_length); memcpy((byte*) key, pos, char_length); if (length > char_length) - bfill(key+char_length, length-char_length, ' '); + cs->cset->fill(cs, key+char_length, length-char_length, ' '); key+= length; } _mi_dpointer(info,key,filepos); @@ -234,7 +238,7 @@ uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old, } k_length-=length; length=(uint) (end-pos); - FIX_LENGTH; + FIX_LENGTH(cs, pos, length, char_length); store_key_length_inc(key,char_length); memcpy((byte*) key,pos,(size_t) char_length); key+= char_length; @@ -247,7 +251,7 @@ uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old, k_length-= 2+length; pos+=2; set_if_smaller(length,tmp_length); /* Safety */ - FIX_LENGTH; + FIX_LENGTH(cs, pos, length, char_length); store_key_length_inc(key,char_length); old+=2; /* Skip length */ memcpy((byte*) key, pos,(size_t) char_length); @@ -264,10 +268,10 @@ uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old, } continue; } - FIX_LENGTH; + FIX_LENGTH(cs, pos, length, char_length); memcpy((byte*) key, pos, char_length); if (length > char_length) - bfill(key+char_length, length-char_length, ' '); + cs->cset->fill(cs,key+char_length, length-char_length, ' '); key+= length; k_length-=length; } diff --git a/myisam/mi_search.c b/myisam/mi_search.c index 24f5db1401d..bc8be9c2732 100644 --- a/myisam/mi_search.c +++ b/myisam/mi_search.c @@ -451,9 +451,8 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, /* We have to compare k and vseg as if they where space extended */ for (end=vseg + (len-cmplen) ; vseg < end && *vseg == (uchar) ' '; - vseg++) ; - if (vseg == end) - goto cmp_rest; /* should never happen */ + vseg++, matched++) ; + DBUG_ASSERT(vseg < end); if (*vseg > (uchar) ' ') { diff --git a/myisam/mi_test1.c b/myisam/mi_test1.c index 77c4d3dfbad..5574eaba101 100644 --- a/myisam/mi_test1.c +++ b/myisam/mi_test1.c @@ -644,7 +644,7 @@ static void get_options(int argc, char *argv[]) { int ho_error; - if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) + if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option, NULL))) exit(ho_error); return; diff --git a/myisam/myisam_ftdump.c b/myisam/myisam_ftdump.c index eeee96d0ff2..cbc8437da79 100644 --- a/myisam/myisam_ftdump.c +++ b/myisam/myisam_ftdump.c @@ -68,7 +68,7 @@ int main(int argc,char *argv[]) struct { MI_INFO *info; } aio0, *aio=&aio0; /* for GWS_IN_USE */ MY_INIT(argv[0]); - if ((error=handle_options(&argc, &argv, my_long_options, get_one_option))) + if ((error=handle_options(&argc, &argv, my_long_options, get_one_option, 0))) exit(error); if (count || dump) verbose=0; diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c index 2c44953ccc9..649b28a93e3 100644 --- a/myisam/myisamchk.c +++ b/myisam/myisamchk.c @@ -154,7 +154,7 @@ enum options_mc { OPT_KEY_CACHE_BLOCK_SIZE, OPT_MYISAM_BLOCK_SIZE, OPT_READ_BUFFER_SIZE, OPT_WRITE_BUFFER_SIZE, OPT_SORT_BUFFER_SIZE, OPT_SORT_KEY_BLOCKS, OPT_DECODE_BITS, OPT_FT_MIN_WORD_LEN, - OPT_FT_MAX_WORD_LEN, OPT_FT_MAX_WORD_LEN_FOR_SORT, OPT_FT_STOPWORD_FILE, + OPT_FT_MAX_WORD_LEN, OPT_FT_STOPWORD_FILE, OPT_MAX_RECORD_LENGTH }; @@ -696,7 +696,7 @@ static void get_options(register int *argc,register char ***argv) if (isatty(fileno(stdout))) check_param.testflag|=T_WRITE_LOOP; - if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option))) + if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option, NULL))) exit(ho_error); /* If using repair, then update checksum if one uses --update-state */ diff --git a/myisam/myisampack.c b/myisam/myisampack.c index de4bd80805a..d3241467d23 100644 --- a/myisam/myisampack.c +++ b/myisam/myisampack.c @@ -350,7 +350,7 @@ static void get_options(int *argc,char ***argv) if (isatty(fileno(stdout))) write_loop=1; - if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option))) + if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option, NULL))) exit(ho_error); if (!*argc) diff --git a/myisam/sort.c b/myisam/sort.c index 509365b89a5..3dc066e877c 100644 --- a/myisam/sort.c +++ b/myisam/sort.c @@ -204,7 +204,7 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages, reinit_io_cache(&tempfile,READ_CACHE,0L,0,0)) goto err; /* purecov: inspected */ if (!no_messages) - puts(" - Last merge and dumping keys\n"); /* purecov: tested */ + printf(" - Last merge and dumping keys\n"); /* purecov: tested */ if (merge_index(info,keys,sort_keys,dynamic_element(&buffpek,0,BUFFPEK *), maxbuffer,&tempfile)) goto err; /* purecov: inspected */ @@ -219,6 +219,8 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages, uint keyno=info->key; uint key_length, ref_length=index->s->rec_reflength; + if (!no_messages) + printf(" - Adding exceptions\n"); /* purecov: tested */ if (flush_io_cache(&tempfile_for_exceptions) || reinit_io_cache(&tempfile_for_exceptions,READ_CACHE,0L,0,0)) goto err; diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index 58d7af75284..454dc7b327b 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -367,10 +367,12 @@ while test $# -gt 0; do VALGRIND=`which valgrind` # this will print an error if not found # Give good warning to the user and stop if [ -z "$VALGRIND" ] ; then - $ECHO "You need to have the 'valgrind' program in your PATH to run mysql-test-run with option --valgrind. Valgrind's home page is http://developer.kde.org/~sewardj ." + $ECHO "You need to have the 'valgrind' program in your PATH to run mysql-test-run with option --valgrind. Valgrind's home page is http://valgrind.kde.org ." exit 1 fi - VALGRIND="$VALGRIND --tool=memcheck --alignment=8 --leak-check=yes --num-callers=16" + # >=2.1.2 requires the --tool option, some versions write to stdout, some to stderr + valgrind --help 2>&1 | grep "\-\-tool" > /dev/null && VALGRIND="$VALGRIND --tool=memcheck" + VALGRIND="$VALGRIND --alignment=8 --leak-check=yes --num-callers=16" EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT --skip-safemalloc --skip-bdb" EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --skip-safemalloc --skip-bdb" SLEEP_TIME_AFTER_RESTART=10 diff --git a/mysql-test/ndb/ndb_config_2_node.ini b/mysql-test/ndb/ndb_config_2_node.ini index 259a1741710..bf5c67cd1d6 100644 --- a/mysql-test/ndb/ndb_config_2_node.ini +++ b/mysql-test/ndb/ndb_config_2_node.ini @@ -24,13 +24,13 @@ ExecuteOnComputer: 2 [MGM] PortNumber: CHOOSE_PORT_MGM -[API] +[MYSQLD] -[API] +[MYSQLD] -[API] +[MYSQLD] -[API] +[MYSQLD] [TCP DEFAULT] PortNumber: CHOOSE_PORT_TRANSPORTER diff --git a/mysql-test/r/binary.result b/mysql-test/r/binary.result index 68b507d1089..405de1158d6 100644 --- a/mysql-test/r/binary.result +++ b/mysql-test/r/binary.result @@ -111,10 +111,10 @@ a b aaa bbb select charset(a), charset(b), charset(binary 'ccc') from t1 limit 1; charset(a) charset(b) charset(binary 'ccc') -latin1 binary latin1 +latin1 binary binary select collation(a), collation(b), collation(binary 'ccc') from t1 limit 1; collation(a) collation(b) collation(binary 'ccc') -latin1_bin binary latin1_bin +latin1_bin binary binary drop table t1; create table t1( firstname char(20), lastname char(20)); insert into t1 values ("john","doe"),("John","Doe"); diff --git a/mysql-test/r/connect.result b/mysql-test/r/connect.result index ae0def02399..edf30e7f6e4 100644 --- a/mysql-test/r/connect.result +++ b/mysql-test/r/connect.result @@ -40,6 +40,7 @@ show tables; Tables_in_test update mysql.user set password=old_password("gambling2") where user=_binary"test"; flush privileges; +set password=""; set password='gambling3'; ERROR HY000: Password hash should be a 41-digit hexadecimal number set password=old_password('gambling3'); diff --git a/mysql-test/r/create_select_tmp.result b/mysql-test/r/create_select_tmp.result index 09ffc9013c7..b99bf3e3591 100644 --- a/mysql-test/r/create_select_tmp.result +++ b/mysql-test/r/create_select_tmp.result @@ -1,19 +1,19 @@ drop table if exists t1, t2; CREATE TABLE t1 ( a int ); INSERT INTO t1 VALUES (1),(2),(1); -CREATE TABLE t2 ( PRIMARY KEY (a) ) TYPE=INNODB SELECT a FROM t1; +CREATE TABLE t2 ( PRIMARY KEY (a) ) ENGINE=INNODB SELECT a FROM t1; ERROR 23000: Duplicate entry '1' for key 1 select * from t2; ERROR 42S02: Table 'test.t2' doesn't exist -CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) TYPE=INNODB SELECT a FROM t1; +CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) ENGINE=INNODB SELECT a FROM t1; ERROR 23000: Duplicate entry '1' for key 1 select * from t2; ERROR 42S02: Table 'test.t2' doesn't exist -CREATE TABLE t2 ( PRIMARY KEY (a) ) TYPE=MYISAM SELECT a FROM t1; +CREATE TABLE t2 ( PRIMARY KEY (a) ) ENGINE=MYISAM SELECT a FROM t1; ERROR 23000: Duplicate entry '1' for key 1 select * from t2; ERROR 42S02: Table 'test.t2' doesn't exist -CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) TYPE=MYISAM SELECT a FROM t1; +CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) ENGINE=MYISAM SELECT a FROM t1; ERROR 23000: Duplicate entry '1' for key 1 select * from t2; ERROR 42S02: Table 'test.t2' doesn't exist diff --git a/mysql-test/r/ctype_cp1251.result b/mysql-test/r/ctype_cp1251.result index 2a59f976156..3793e962d40 100644 --- a/mysql-test/r/ctype_cp1251.result +++ b/mysql-test/r/ctype_cp1251.result @@ -49,8 +49,8 @@ a b aaa bbb select charset(a), charset(b), charset(binary 'ccc') from t1 limit 1; charset(a) charset(b) charset(binary 'ccc') -cp1251 binary cp1251 +cp1251 binary binary select collation(a), collation(b), collation(binary 'ccc') from t1 limit 1; collation(a) collation(b) collation(binary 'ccc') -cp1251_bin binary cp1251_bin +cp1251_bin binary binary drop table t1; diff --git a/mysql-test/r/ctype_create.result b/mysql-test/r/ctype_create.result index 0da76c556e2..b35131f62a4 100644 --- a/mysql-test/r/ctype_create.result +++ b/mysql-test/r/ctype_create.result @@ -54,4 +54,12 @@ t1 CREATE TABLE `t1` ( `a` char(10) collate latin1_german1_ci default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci DROP TABLE t1; +create table t1 (a char) character set latin1 character set latin2; +ERROR HY000: Conflicting declarations: 'CHARACTER SET latin1' and 'CHARACTER SET latin2' +create table t1 (a char) character set latin1 collate latin2_bin; +ERROR 42000: COLLATION 'latin2_bin' is not valid for CHARACTER SET 'latin1' +create database d1 default character set latin1 character set latin2; +ERROR HY000: Conflicting declarations: 'CHARACTER SET latin1' and 'CHARACTER SET latin2' +create database d1 default character set latin1 collate latin2_bin; +ERROR 42000: COLLATION 'latin2_bin' is not valid for CHARACTER SET 'latin1' DROP DATABASE mysqltest1; diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index ef5ec012078..f3be539251a 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -1,5 +1,4 @@ -drop table if exists t1; -drop table if exists t2; +drop table if exists t1,t2; set names utf8; select left(_utf8 0xD0B0D0B1D0B2,1); left(_utf8 0xD0B0D0B1D0B2,1) @@ -412,6 +411,36 @@ select c as c_a from t1 where c='б'; c_a б drop table t1; +create table t1 ( +c char(10) character set utf8, +unique key a (c(1)) +) engine=bdb; +insert into t1 values ('a'),('b'),('c'),('d'),('e'),('f'); +insert into t1 values ('aa'); +ERROR 23000: Duplicate entry 'aa' for key 1 +insert into t1 values ('aaa'); +ERROR 23000: Duplicate entry 'aaa' for key 1 +insert into t1 values ('б'); +insert into t1 values ('бб'); +ERROR 23000: Duplicate entry 'б' for key 1 +insert into t1 values ('ббб'); +ERROR 23000: Duplicate entry 'б' for key 1 +select c as c_all from t1 order by c; +c_all +a +b +c +d +e +f +б +select c as c_a from t1 where c='a'; +c_a +a +select c as c_a from t1 where c='б'; +c_a +б +drop table t1; create table t1 (c varchar(30) character set utf8 collate utf8_bin, unique(c(10))); insert into t1 values ('1'),('2'),('3'),('x'),('y'),('z'); insert into t1 values ('aaaaaaaaaa'); @@ -541,6 +570,36 @@ c_a б drop table t1; create table t1 ( +c char(10) character set utf8 collate utf8_bin, +unique key a (c(1)) +) engine=bdb; +insert into t1 values ('a'),('b'),('c'),('d'),('e'),('f'); +insert into t1 values ('aa'); +ERROR 23000: Duplicate entry 'aa' for key 1 +insert into t1 values ('aaa'); +ERROR 23000: Duplicate entry 'aaa' for key 1 +insert into t1 values ('б'); +insert into t1 values ('бб'); +ERROR 23000: Duplicate entry 'б' for key 1 +insert into t1 values ('ббб'); +ERROR 23000: Duplicate entry 'б' for key 1 +select c as c_all from t1 order by c; +c_all +a +b +c +d +e +f +б +select c as c_a from t1 where c='a'; +c_a +a +select c as c_a from t1 where c='б'; +c_a +б +drop table t1; +create table t1 ( str varchar(255) character set utf8 not null, key str (str(2)) ) engine=myisam; @@ -570,3 +629,13 @@ select * from t1 where str='str'; str str drop table t1; +create table t1 ( +str varchar(255) character set utf8 not null, +key str (str(2)) +) engine=bdb; +INSERT INTO t1 VALUES ('str'); +INSERT INTO t1 VALUES ('str2'); +select * from t1 where str='str'; +str +str +drop table t1; diff --git a/mysql-test/r/endspace.result b/mysql-test/r/endspace.result index 167adea6674..96210a0e16d 100644 --- a/mysql-test/r/endspace.result +++ b/mysql-test/r/endspace.result @@ -19,7 +19,7 @@ select 'a a' > 'a', 'a \0' < 'a'; 1 1 select binary 'a a' > 'a', binary 'a \0' > 'a', binary 'a\0' > 'a'; binary 'a a' > 'a' binary 'a \0' > 'a' binary 'a\0' > 'a' -1 0 0 +1 1 1 create table t1 (text1 varchar(32) not NULL, KEY key1 (text1)); insert into t1 values ('teststring'), ('nothing'), ('teststring\t'); check table t1; @@ -52,13 +52,13 @@ select * from t1 ignore key (key1) where text1='teststring' or text1 like 'tests text1 teststring teststring -select * from t1 where text1='teststring' or text1 like 'teststring_%'; -text1 -teststring -teststring -select * from t1 where text1='teststring' or text1 > 'teststring\t'; -text1 -teststring +select concat('|', text1, '|') from t1 where text1='teststring' or text1 like 'teststring_%'; +concat('|', text1, '|') +|teststring | +|teststring| +select concat('|', text1, '|') from t1 where text1='teststring' or text1 > 'teststring\t'; +concat('|', text1, '|') +|teststring| select text1, length(text1) from t1 order by text1; text1 length(text1) nothing 7 @@ -77,7 +77,28 @@ concat('|', text1, '|') |teststring| |teststring | |teststring | +select concat('|', text1, '|') from t1 where text1='teststring' or text1 > 'teststring\t'; +concat('|', text1, '|') +|teststring| +|teststring | +select concat('|', text1, '|') from t1 where text1='teststring'; +concat('|', text1, '|') +|teststring| +select concat('|', text1, '|') from t1 where text1='teststring '; +concat('|', text1, '|') +|teststring | alter table t1 modify text1 text not null, pack_keys=1; +select concat('|', text1, '|') from t1 where text1='teststring'; +concat('|', text1, '|') +|teststring| +|teststring | +select concat('|', text1, '|') from t1 where text1='teststring '; +concat('|', text1, '|') +|teststring| +|teststring | +explain select concat('|', text1, '|') from t1 where text1='teststring '; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range key1 key1 22 NULL 2 Using where select * from t1 where text1 like 'teststring_%'; text1 teststring @@ -87,10 +108,10 @@ text1 teststring teststring teststring -select * from t1 where text1='teststring' or text1 > 'teststring\t'; -text1 -teststring -teststring +select concat('|', text1, '|') from t1 where text1='teststring' or text1 > 'teststring\t'; +concat('|', text1, '|') +|teststring| +|teststring | select concat('|', text1, '|') from t1 order by text1; concat('|', text1, '|') |nothing| diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index 5c98bc5b612..e0883a6297e 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -18,7 +18,7 @@ explain extended select grp,group_concat(c) from t1 group by grp; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 9 Using filesort Warnings: -Note 1003 select test.t1.grp AS `grp`,group_concat(test.t1.c seperator ',') AS `group_concat(c)` from test.t1 group by test.t1.grp +Note 1003 select test.t1.grp AS `grp`,group_concat(test.t1.c separator ',') AS `group_concat(c)` from test.t1 group by test.t1.grp select grp,group_concat(a,c) from t1 group by grp; grp group_concat(a,c) 1 1a @@ -93,7 +93,7 @@ explain extended select grp,group_concat(distinct c order by c desc) from t1 gro id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 9 Using filesort Warnings: -Note 1003 select test.t1.grp AS `grp`,group_concat(distinct test.t1.c order by test.t1.c seperator ',') AS `group_concat(distinct c order by c desc)` from test.t1 group by test.t1.grp +Note 1003 select test.t1.grp AS `grp`,group_concat(distinct test.t1.c order by test.t1.c separator ',') AS `group_concat(distinct c order by c desc)` from test.t1 group by test.t1.grp select grp,group_concat(c order by c separator ",") from t1 group by grp; grp group_concat(c order by c separator ",") 1 a @@ -113,7 +113,7 @@ explain extended select grp,group_concat(distinct c order by c separator ",") fr id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 9 Using filesort Warnings: -Note 1003 select test.t1.grp AS `grp`,group_concat(distinct test.t1.c order by test.t1.c seperator ',') AS `group_concat(distinct c order by c separator ",")` from test.t1 group by test.t1.grp +Note 1003 select test.t1.grp AS `grp`,group_concat(distinct test.t1.c order by test.t1.c separator ',') AS `group_concat(distinct c order by c separator ",")` from test.t1 group by test.t1.grp select grp,group_concat(distinct c order by c desc separator ",") from t1 group by grp; grp group_concat(distinct c order by c desc separator ",") 1 a diff --git a/mysql-test/r/func_if.result b/mysql-test/r/func_if.result index 4c8a0561b0a..dd916d06372 100644 --- a/mysql-test/r/func_if.result +++ b/mysql-test/r/func_if.result @@ -43,7 +43,7 @@ explain extended select if(u=1,st,binary st) s from t1 where st like "%a%" order id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 7 Using where; Using filesort Warnings: -Note 1003 select if((test.t1.u = 1),test.t1.st,(test.t1.st collate _latin1'BINARY')) AS `s` from test.t1 where (test.t1.st like _latin1'%a%') order by if((test.t1.u = 1),test.t1.st,(test.t1.st collate _latin1'BINARY')) +Note 1003 select if((test.t1.u = 1),test.t1.st,cast(test.t1.st as char charset binary)) AS `s` from test.t1 where (test.t1.st like _latin1'%a%') order by if((test.t1.u = 1),test.t1.st,cast(test.t1.st as char charset binary)) select nullif(u=0, 'test') from t1; nullif(u=0, 'test') NULL diff --git a/mysql-test/r/func_in.result b/mysql-test/r/func_in.result index f66b3dea94b..374affce8c5 100644 --- a/mysql-test/r/func_in.result +++ b/mysql-test/r/func_in.result @@ -148,6 +148,16 @@ id select_type table type possible_keys key key_len ref rows Extra Warnings: Note 1003 select test.t1.a AS `a`,test.t1.b AS `b`,test.t1.c AS `c` from test.t1 where (_latin1'a' in (test.t1.a,test.t1.b,(test.t1.c collate _latin1'latin1_bin'))) drop table t1; +set names utf8; +create table t1 (a char(10) character set utf8 not null); +insert into t1 values ('bbbb'),(_koi8r''),(_latin1''); +select a from t1 where a in ('bbbb',_koi8r'',_latin1'') order by a; +a +ÄÄÄÄ +bbbb +цццц +drop table t1; +set names latin1; select '1.0' in (1,2); '1.0' in (1,2) 1 diff --git a/mysql-test/r/func_set.result b/mysql-test/r/func_set.result index 4918617f85f..2431406c128 100644 --- a/mysql-test/r/func_set.result +++ b/mysql-test/r/func_set.result @@ -41,8 +41,7 @@ interval(null, 1, 10, 100) -1 drop table if exists t1,t2; create table t1 (id int(10) not null unique); -create table t2 (id int(10) not null primary key, -val int(10) not null); +create table t2 (id int(10) not null primary key, val int(10) not null); insert into t1 values (1),(2),(4); insert into t2 values (1,1),(2,1),(3,1),(4,2); select one.id, elt(two.val,'one','two') from t1 one, t2 two where two.id=one.id; @@ -56,3 +55,12 @@ id elt(two.val,'one','two') 2 one 4 two drop table t1,t2; +select find_in_set(binary 'a',binary 'A,B,C'); +find_in_set(binary 'a',binary 'A,B,C') +0 +select find_in_set('a',binary 'A,B,C'); +find_in_set('a',binary 'A,B,C') +0 +select find_in_set(binary 'a', 'A,B,C'); +find_in_set(binary 'a', 'A,B,C') +0 diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 345832387bd..7b2fc4b21a5 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -638,7 +638,7 @@ explain extended select md5('hello'), sha('abc'), sha1('abc'), soundex(''), 'moo id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 select md5(_latin1'hello') AS `md5('hello')`,sha(_latin1'abc') AS `sha('abc')`,sha(_latin1'abc') AS `sha1('abc')`,soundex(_latin1'') AS `soundex('')`,(soundex(_latin1'mood') = soundex(_latin1'mud')) AS `'mood' sounds like 'mud'`,aes_decrypt(aes_encrypt(_latin1'abc',_latin1'1'),_latin1'1') AS `aes_decrypt(aes_encrypt('abc','1'),'1')`,concat(_latin1'*',repeat(_latin1' ',5),_latin1'*') AS `concat('*',space(5),'*')`,reverse(_latin1'abc') AS `reverse('abc')`,rpad(_latin1'a',4,_latin1'1') AS `rpad('a',4,'1')`,lpad(_latin1'a',4,_latin1'1') AS `lpad('a',4,'1')`,concat_ws(_latin1',',_latin1'',NULL,_latin1'a') AS `concat_ws(',','',NULL,'a')`,make_set(255,_latin2'a',_latin2'b',_latin2'c') AS `make_set(255,_latin2'a',_latin2'b',_latin2'c')`,elt(2,1) AS `elt(2,1)`,locate(_latin1'a',_latin1'b',2) AS `locate("a","b",2)`,format(130,10) AS `format(130,10)`,char(0) AS `char(0)`,conv(130,16,10) AS `conv(130,16,10)`,hex(130) AS `hex(130)`,(_latin1'HE' collate _latin1'BINARY') AS `binary 'HE'`,export_set(255,_latin2'y',_latin2'n',_latin2' ') AS `export_set(255,_latin2'y',_latin2'n',_latin2' ')`,field((_latin1'b' collate _latin1'latin1_bin'),_latin1'A',_latin1'B') AS `FIELD('b' COLLATE latin1_bin,'A','B')`,find_in_set(_latin1'B',_latin1'a,b,c,d') AS `FIND_IN_SET(_latin1'B',_latin1'a,b,c,d')`,collation(conv(130,16,10)) AS `collation(conv(130,16,10))`,coercibility(conv(130,16,10)) AS `coercibility(conv(130,16,10))`,length(_latin1'\n \r\0\\_\\%\\') AS `length('\n\t\r\b\0\_\%\\')`,bit_length(_latin1'\n \r\0\\_\\%\\') AS `bit_length('\n\t\r\b\0\_\%\\')`,bit_length(_latin1'\n \r\0\\_\\%\\') AS `bit_length('\n\t\r\b\0\_\%\\')`,concat(_latin1'monty',_latin1' was here ',_latin1'again') AS `concat('monty',' was here ','again')`,length(_latin1'hello') AS `length('hello')`,char(ascii(_latin1'h')) AS `char(ascii('h'))`,ord(_latin1'h') AS `ord('h')`,quote((1 / 0)) AS `quote(1/0)`,crc32(_latin1'123') AS `crc32("123")`,replace(_latin1'aaaa',_latin1'a',_latin1'b') AS `replace('aaaa','a','b')`,insert(_latin1'txs',2,1,_latin1'hi') AS `insert('txs',2,1,'hi')`,left(_latin2'a',1) AS `left(_latin2'a',1)`,right(_latin2'a',1) AS `right(_latin2'a',1)`,lcase(_latin2'a') AS `lcase(_latin2'a')`,ucase(_latin2'a') AS `ucase(_latin2'a')`,substr(_latin1'abcdefg',3,2) AS `SUBSTR('abcdefg',3,2)`,substr_index(_latin1'1abcd;2abcd;3abcd;4abcd',_latin1';',2) AS `substring_index("1abcd;2abcd;3abcd;4abcd", ';', 2)`,trim(_latin2' a ') AS `trim(_latin2' a ')`,ltrim(_latin2' a ') AS `ltrim(_latin2' a ')`,rtrim(_latin2' a ') AS `rtrim(_latin2' a ')`,decode(encode(repeat(_latin1'a',100000))) AS `decode(encode(repeat("a",100000),"monty"),"monty")` +Note 1003 select md5(_latin1'hello') AS `md5('hello')`,sha(_latin1'abc') AS `sha('abc')`,sha(_latin1'abc') AS `sha1('abc')`,soundex(_latin1'') AS `soundex('')`,(soundex(_latin1'mood') = soundex(_latin1'mud')) AS `'mood' sounds like 'mud'`,aes_decrypt(aes_encrypt(_latin1'abc',_latin1'1'),_latin1'1') AS `aes_decrypt(aes_encrypt('abc','1'),'1')`,concat(_latin1'*',repeat(_latin1' ',5),_latin1'*') AS `concat('*',space(5),'*')`,reverse(_latin1'abc') AS `reverse('abc')`,rpad(_latin1'a',4,_latin1'1') AS `rpad('a',4,'1')`,lpad(_latin1'a',4,_latin1'1') AS `lpad('a',4,'1')`,concat_ws(_latin1',',_latin1'',NULL,_latin1'a') AS `concat_ws(',','',NULL,'a')`,make_set(255,_latin2'a',_latin2'b',_latin2'c') AS `make_set(255,_latin2'a',_latin2'b',_latin2'c')`,elt(2,1) AS `elt(2,1)`,locate(_latin1'a',_latin1'b',2) AS `locate("a","b",2)`,format(130,10) AS `format(130,10)`,char(0) AS `char(0)`,conv(130,16,10) AS `conv(130,16,10)`,hex(130) AS `hex(130)`,cast(_latin1'HE' as char charset binary) AS `binary 'HE'`,export_set(255,_latin2'y',_latin2'n',_latin2' ') AS `export_set(255,_latin2'y',_latin2'n',_latin2' ')`,field((_latin1'b' collate _latin1'latin1_bin'),_latin1'A',_latin1'B') AS `FIELD('b' COLLATE latin1_bin,'A','B')`,find_in_set(_latin1'B',_latin1'a,b,c,d') AS `FIND_IN_SET(_latin1'B',_latin1'a,b,c,d')`,collation(conv(130,16,10)) AS `collation(conv(130,16,10))`,coercibility(conv(130,16,10)) AS `coercibility(conv(130,16,10))`,length(_latin1'\n \r\0\\_\\%\\') AS `length('\n\t\r\b\0\_\%\\')`,bit_length(_latin1'\n \r\0\\_\\%\\') AS `bit_length('\n\t\r\b\0\_\%\\')`,bit_length(_latin1'\n \r\0\\_\\%\\') AS `bit_length('\n\t\r\b\0\_\%\\')`,concat(_latin1'monty',_latin1' was here ',_latin1'again') AS `concat('monty',' was here ','again')`,length(_latin1'hello') AS `length('hello')`,char(ascii(_latin1'h')) AS `char(ascii('h'))`,ord(_latin1'h') AS `ord('h')`,quote((1 / 0)) AS `quote(1/0)`,crc32(_latin1'123') AS `crc32("123")`,replace(_latin1'aaaa',_latin1'a',_latin1'b') AS `replace('aaaa','a','b')`,insert(_latin1'txs',2,1,_latin1'hi') AS `insert('txs',2,1,'hi')`,left(_latin2'a',1) AS `left(_latin2'a',1)`,right(_latin2'a',1) AS `right(_latin2'a',1)`,lcase(_latin2'a') AS `lcase(_latin2'a')`,ucase(_latin2'a') AS `ucase(_latin2'a')`,substr(_latin1'abcdefg',3,2) AS `SUBSTR('abcdefg',3,2)`,substr_index(_latin1'1abcd;2abcd;3abcd;4abcd',_latin1';',2) AS `substring_index("1abcd;2abcd;3abcd;4abcd", ';', 2)`,trim(_latin2' a ') AS `trim(_latin2' a ')`,ltrim(_latin2' a ') AS `ltrim(_latin2' a ')`,rtrim(_latin2' a ') AS `rtrim(_latin2' a ')`,decode(encode(repeat(_latin1'a',100000))) AS `decode(encode(repeat("a",100000),"monty"),"monty")` SELECT lpad(12345, 5, "#"); lpad(12345, 5, "#") 12345 diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index c2fd7855c85..9f5dd286cf9 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -466,3 +466,22 @@ insert IGNORE into t1 values ('Garbage'); ERROR HY000: Unknown error alter table t1 add spatial index(a); drop table t1; +create table t1(a geometry not null, spatial index(a)); +insert into t1 values +(GeomFromText('POINT(1 1)')), (GeomFromText('POINT(3 3)')), +(GeomFromText('POINT(4 4)')), (GeomFromText('POINT(6 6)')); +select AsText(a) from t1 where +MBRContains(GeomFromText('Polygon((0 0, 0 2, 2 2, 2 0, 0 0))'), a) +or +MBRContains(GeomFromText('Polygon((2 2, 2 5, 5 5, 5 2, 2 2))'), a); +AsText(a) +POINT(1 1) +POINT(3 3) +POINT(4 4) +select AsText(a) from t1 where +MBRContains(GeomFromText('Polygon((0 0, 0 2, 2 2, 2 0, 0 0))'), a) +and +MBRContains(GeomFromText('Polygon((0 0, 0 7, 7 7, 7 0, 0 0))'), a); +AsText(a) +POINT(1 1) +drop table t1; diff --git a/mysql-test/r/having.result b/mysql-test/r/having.result index f7e0bbf3e2c..218276406b1 100644 --- a/mysql-test/r/having.result +++ b/mysql-test/r/having.result @@ -127,3 +127,4 @@ having (a.description is not null) and (c=0); id description c 1 test 0 2 test2 0 +drop table t1,t2,t3; diff --git a/mysql-test/r/lowercase_table.result b/mysql-test/r/lowercase_table.result index 8bf3db8cad0..2f71e4c2f57 100644 --- a/mysql-test/r/lowercase_table.result +++ b/mysql-test/r/lowercase_table.result @@ -58,3 +58,10 @@ ERROR 42000: Not unique table/alias: 'C' drop table t1, t2; show tables; Tables_in_test +create table t1 (a int); +select TEST.t1.* from TEST.t1; +a +alter table t1 rename to T1; +select TEST.t1.* from TEST.t1; +a +drop table t1; diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index 0109097d3a1..26dcce43d08 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -412,7 +412,6 @@ aaa. aaa . select concat(a,'.') from t1 where binary a='aaa'; concat(a,'.') -aaa . aaa. update t1 set a='bbb' where a='aaa'; select concat(a,'.') from t1; @@ -429,6 +428,22 @@ select * from t1 where a='807780' and b='477' and c='165'; a b c 807780 477 165 drop table t1; +DROP TABLE IF EXISTS t1; +Warnings: +Note 1051 Unknown table 't1' +CREATE TABLE t1 (a varchar(150) NOT NULL, KEY (a)); +INSERT t1 VALUES ("can \tcan"); +INSERT t1 VALUES ("can can"); +INSERT t1 VALUES ("can"); +SELECT * FROM t1; +a +can can +can +can can +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; create table t1 (a blob); insert into t1 values('a '),('a'); select concat(a,'.') from t1 where a='a'; diff --git a/mysql-test/r/ndb_autodiscover.result b/mysql-test/r/ndb_autodiscover.result index b0e2aa04f3e..f5b908c39e2 100644 --- a/mysql-test/r/ndb_autodiscover.result +++ b/mysql-test/r/ndb_autodiscover.result @@ -35,10 +35,10 @@ update t1 set name="Autodiscover" where id = 2; show status like 'handler_discover%'; Variable_name Value Handler_discover 4 -select * from t1 order by name; +select * from t1 order by id; id name -2 Autodiscover 1 Autodiscover +2 Autodiscover 3 Discover 3 show status like 'handler_discover%'; Variable_name Value diff --git a/mysql-test/r/ndb_basic.result b/mysql-test/r/ndb_basic.result index f2727c91628..f5815cc11d9 100644 --- a/mysql-test/r/ndb_basic.result +++ b/mysql-test/r/ndb_basic.result @@ -234,6 +234,18 @@ select * from t4 where a = 7 and b = 17 order by a; a b c d select * from t4 where a = 7 and b != 16 order by b; a b c d +delete from t2 where a > 5; +select x1.a, x1.b from t2 x1, t2 x2 where x1.b = x2.b order by x1.a; +a b +1 10 +3 12 +5 14 +select a, b FROM t2 outer_table where +a = (select a from t2 where b = outer_table.b ) order by a; +a b +1 10 +3 12 +5 14 delete from t2; delete from t3; delete from t4; diff --git a/mysql-test/r/ndb_index_ordered.result b/mysql-test/r/ndb_index_ordered.result index 75de1ac4a7f..2f1ad251e40 100644 --- a/mysql-test/r/ndb_index_ordered.result +++ b/mysql-test/r/ndb_index_ordered.result @@ -205,4 +205,55 @@ a b c select * from t1 where b<=5 and c=0 or b<=5 and c=2; a b c 19 4 0 +select count(*) from t1 where b = 0; +count(*) +0 +select count(*) from t1 where b = 1; +count(*) +1 +drop table t1; +CREATE TABLE t1 ( +a int unsigned NOT NULL PRIMARY KEY, +b int unsigned, +c int unsigned, +KEY bc(b,c) +) engine = ndb; +insert into t1 values(1,1,1),(2,NULL,2),(3,NULL,NULL),(4,4,NULL); +select * from t1 use index (bc) where b IS NULL; +a b c +3 NULL NULL +2 NULL 2 +select * from t1 use index (bc)order by a; +a b c +1 1 1 +2 NULL 2 +3 NULL NULL +4 4 NULL +select * from t1 use index (bc) order by a; +a b c +1 1 1 +2 NULL 2 +3 NULL NULL +4 4 NULL +select * from t1 use index (PRIMARY) where b IS NULL order by a; +a b c +2 NULL 2 +3 NULL NULL +select * from t1 use index (bc) where b IS NULL order by a; +a b c +2 NULL 2 +3 NULL NULL +select * from t1 use index (bc) where b IS NULL and c IS NULL order by a; +a b c +3 NULL NULL +select * from t1 use index (bc) where b IS NULL and c = 2 order by a; +a b c +2 NULL 2 +select * from t1 use index (bc) where b < 4 order by a; +a b c +1 1 1 +select * from t1 use index (bc) where b IS NOT NULL order by a; +a b c +1 1 1 +4 4 NULL drop table t1; diff --git a/mysql-test/r/ndb_index_unique.result b/mysql-test/r/ndb_index_unique.result index 7ec2ef3a2f1..4362de94b48 100644 --- a/mysql-test/r/ndb_index_unique.result +++ b/mysql-test/r/ndb_index_unique.result @@ -109,6 +109,68 @@ a b c 3 4 6 drop table t3; CREATE TABLE t1 ( +pk int NOT NULL PRIMARY KEY, +a int unsigned, +UNIQUE KEY (a) +) engine=ndbcluster; +insert into t1 values (-1,NULL), (0,0), (1,NULL),(2,2),(3,NULL),(4,4); +select * from t1 order by pk; +pk a +-1 NULL +0 0 +1 NULL +2 2 +3 NULL +4 4 +insert into t1 values (5,0); +ERROR 23000: Can't write, because of unique constraint, to table 't1' +select * from t1 order by pk; +pk a +-1 NULL +0 0 +1 NULL +2 2 +3 NULL +4 4 +delete from t1 where a = 0; +insert into t1 values (5,0); +select * from t1 order by pk; +pk a +-1 NULL +1 NULL +2 2 +3 NULL +4 4 +5 0 +CREATE TABLE t2 ( +pk int NOT NULL PRIMARY KEY, +a int unsigned, +b tinyint NOT NULL, +c VARCHAR(10), +UNIQUE KEY si(a, c) +) engine=ndbcluster; +insert into t2 values (-1,1,17,NULL),(0,NULL,18,NULL),(1,3,19,'abc'); +select * from t2 order by pk; +pk a b c +-1 1 17 NULL +0 NULL 18 NULL +1 3 19 abc +insert into t2 values(2,3,19,'abc'); +ERROR 23000: Can't write, because of unique constraint, to table 't2' +select * from t2 order by pk; +pk a b c +-1 1 17 NULL +0 NULL 18 NULL +1 3 19 abc +delete from t2 where c IS NOT NULL; +insert into t2 values(2,3,19,'abc'); +select * from t2 order by pk; +pk a b c +-1 1 17 NULL +0 NULL 18 NULL +2 3 19 abc +drop table t1, t2; +CREATE TABLE t1 ( cid smallint(5) unsigned NOT NULL default '0', cv varchar(250) NOT NULL default '', PRIMARY KEY (cid), diff --git a/mysql-test/r/ndb_replace.result b/mysql-test/r/ndb_replace.result index 45af0f7fcb5..63fd8b55c8e 100644 --- a/mysql-test/r/ndb_replace.result +++ b/mysql-test/r/ndb_replace.result @@ -11,7 +11,7 @@ insert into t1 (gesuchnr, benutzer_id) value (3,2); replace into t1 (gesuchnr,benutzer_id) values (1,1); replace into t1 (gesuchnr,benutzer_id) values (1,1); insert into t1 (gesuchnr,benutzer_id) values (1,1); -ERROR 23000: Can't write; duplicate key in table 't1' +ERROR 23000: Duplicate entry '1-1' for key 1 replace into t1 (gesuchnr,benutzer_id) values (1,1); select * from t1 order by gesuchnr; gesuchnr benutzer_id diff --git a/mysql-test/r/negation_elimination.result b/mysql-test/r/negation_elimination.result index a3a2bad7ec6..9193a125cd1 100644 --- a/mysql-test/r/negation_elimination.result +++ b/mysql-test/r/negation_elimination.result @@ -375,4 +375,17 @@ a 13 14 15 +delete from t1 where a > 3; +select a, not(not(a)) from t1; +a not(not(a)) +NULL NULL +0 0 +1 1 +2 1 +3 1 +explain extended select a, not(not(a)), not(a <= 2 and not(a)), not(a not like "1"), not (a not in (1,2)), not(a != 2) from t1 where not(not(a)) having not(not(a)); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL a 5 NULL 5 Using where; Using index +Warnings: +Note 1003 select test.t1.a AS `a`,(test.t1.a <> 0) AS `not(not(a))`,((test.t1.a > 2) or test.t1.a) AS `not(a <= 2 and not(a))`,(test.t1.a like _latin1'1') AS `not(a not like "1")`,(test.t1.a in (1,2)) AS `not (a not in (1,2))`,(test.t1.a = 2) AS `not(a != 2)` from test.t1 where test.t1.a having test.t1.a drop table t1; diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 0523143f91d..e161904cd6f 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -226,3 +226,36 @@ a b execute stmt1; a b deallocate prepare stmt1; +drop table t1; +prepare stmt1 from "select 1 into @var"; +execute stmt1; +execute stmt1; +prepare stmt1 from "create table t1 select 1 as i"; +execute stmt1; +drop table t1; +execute stmt1; +prepare stmt1 from "insert into t1 select i from t1"; +execute stmt1; +execute stmt1; +prepare stmt1 from "select * from t1 into outfile 'f1.txt'"; +execute stmt1; +deallocate prepare stmt1; +drop table t1; +prepare stmt1 from 'select 1'; +prepare STMT1 from 'select 2'; +execute sTmT1; +2 +2 +deallocate prepare StMt1; +deallocate prepare Stmt1; +ERROR HY000: Unknown prepared statement handler (Stmt1) given to DEALLOCATE PREPARE +set names utf8; +prepare `ü` from 'select 1234'; +execute `ü` ; +1234 +1234 +set names latin1; +execute ``; +1234 +1234 +set names default; diff --git a/mysql-test/r/truncate.result b/mysql-test/r/truncate.result index d777bd184b2..74a6cb72cc6 100644 --- a/mysql-test/r/truncate.result +++ b/mysql-test/r/truncate.result @@ -31,4 +31,25 @@ SELECT * from t1; a 1 2 +delete from t1; +insert into t1 (a) values (NULL),(NULL); +SELECT * from t1; +a +3 +4 +drop table t1; +create temporary table t1 (a integer auto_increment primary key); +insert into t1 (a) values (NULL),(NULL); +truncate table t1; +insert into t1 (a) values (NULL),(NULL); +SELECT * from t1; +a +1 +2 +delete from t1; +insert into t1 (a) values (NULL),(NULL); +SELECT * from t1; +a +3 +4 drop table t1; diff --git a/mysql-test/r/type_blob.result b/mysql-test/r/type_blob.result index 580fc9a8d0b..95bba1d4ec7 100644 --- a/mysql-test/r/type_blob.result +++ b/mysql-test/r/type_blob.result @@ -593,9 +593,12 @@ create table t1 (id integer primary key auto_increment, txt text, unique index t insert into t1 (txt) values ('Chevy'), ('Chevy '), (NULL); select * from t1 where txt='Chevy' or txt is NULL; id txt +3 NULL 1 Chevy 2 Chevy -3 NULL +explain select * from t1 where txt='Chevy' or txt is NULL; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range txt_index txt_index 23 NULL 2 Using where select * from t1 where txt='Chevy '; id txt 1 Chevy @@ -663,6 +666,21 @@ id txt 1 Chevy 2 Chevy 4 Ford +alter table t1 modify column txt blob; +explain select * from t1 where txt='Chevy' or txt is NULL; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref_or_null txt_index txt_index 23 const 2 Using where +select * from t1 where txt='Chevy' or txt is NULL; +id txt +1 Chevy +3 NULL +explain select * from t1 where txt='Chevy' or txt is NULL order by txt; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref_or_null txt_index txt_index 23 const 2 Using where; Using filesort +select * from t1 where txt='Chevy' or txt is NULL order by txt; +id txt +3 NULL +1 Chevy drop table t1; CREATE TABLE t1 ( i int(11) NOT NULL default '0', c text NOT NULL, PRIMARY KEY (i), KEY (c(1),c(1))); INSERT t1 VALUES (1,''),(2,''),(3,'asdfh'),(4,''); diff --git a/mysql-test/r/type_ranges.result b/mysql-test/r/type_ranges.result index e803fde14a6..5a65c90c5c7 100644 --- a/mysql-test/r/type_ranges.result +++ b/mysql-test/r/type_ranges.result @@ -272,7 +272,7 @@ auto bigint(17) unsigned NULL PRI 0 select,insert,update,references t1 bigint(1) NULL 0 select,insert,update,references t2 char(1) latin1_swedish_ci select,insert,update,references t3 longtext latin1_swedish_ci select,insert,update,references -t4 longtext latin1_bin select,insert,update,references +t4 longblob NULL select,insert,update,references select * from t2; auto t1 t2 t3 t4 11 1 a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb diff --git a/mysql-test/r/type_timestamp.result b/mysql-test/r/type_timestamp.result index aa8c0903558..425e4a05586 100644 --- a/mysql-test/r/type_timestamp.result +++ b/mysql-test/r/type_timestamp.result @@ -365,3 +365,15 @@ select * from t1; t1 i 2004-04-01 00:00:00 10 drop table t1; +create table t1 (ts timestamp(19)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `ts` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +set TIMESTAMP=1000000000; +insert into t1 values (); +select * from t1; +ts +2001-09-09 04:46:40 +drop table t1; diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index 41ea95cf933..5d3f32cdd55 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -436,3 +436,19 @@ SELECT @@global.session.key_buffer_size; 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 'key_buffer_size' at line 1 SELECT @@global.local.key_buffer_size; 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 'key_buffer_size' at line 1 +set @tstlw = @@log_warnings; +show global variables like 'log_warnings'; +Variable_name Value +log_warnings 1 +set global log_warnings = 0; +show global variables like 'log_warnings'; +Variable_name Value +log_warnings 0 +set global log_warnings = 42; +show global variables like 'log_warnings'; +Variable_name Value +log_warnings 42 +set global log_warnings = @tstlw; +show global variables like 'log_warnings'; +Variable_name Value +log_warnings 1 diff --git a/mysql-test/t/connect.test b/mysql-test/t/connect.test index c1ecf176470..4598ca5ea15 100644 --- a/mysql-test/t/connect.test +++ b/mysql-test/t/connect.test @@ -48,6 +48,7 @@ flush privileges; #connect (con1,localhost,test,gambling2,""); #show tables; connect (con1,localhost,test,gambling2,mysql); +set password=""; --error 1105 set password='gambling3'; set password=old_password('gambling3'); diff --git a/mysql-test/t/create_select_tmp.test b/mysql-test/t/create_select_tmp.test index 166d32fb17c..d81a3799d98 100644 --- a/mysql-test/t/create_select_tmp.test +++ b/mysql-test/t/create_select_tmp.test @@ -12,18 +12,18 @@ drop table if exists t1, t2; CREATE TABLE t1 ( a int ); INSERT INTO t1 VALUES (1),(2),(1); --error 1062; -CREATE TABLE t2 ( PRIMARY KEY (a) ) TYPE=INNODB SELECT a FROM t1; +CREATE TABLE t2 ( PRIMARY KEY (a) ) ENGINE=INNODB SELECT a FROM t1; --error 1146; select * from t2; --error 1062; -CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) TYPE=INNODB SELECT a FROM t1; +CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) ENGINE=INNODB SELECT a FROM t1; --error 1146; select * from t2; --error 1062; -CREATE TABLE t2 ( PRIMARY KEY (a) ) TYPE=MYISAM SELECT a FROM t1; +CREATE TABLE t2 ( PRIMARY KEY (a) ) ENGINE=MYISAM SELECT a FROM t1; --error 1146; select * from t2; --error 1062; -CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) TYPE=MYISAM SELECT a FROM t1; +CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) ENGINE=MYISAM SELECT a FROM t1; --error 1146; select * from t2; diff --git a/mysql-test/t/ctype_create.test b/mysql-test/t/ctype_create.test index 6d7ed6fc205..9a5cb025474 100644 --- a/mysql-test/t/ctype_create.test +++ b/mysql-test/t/ctype_create.test @@ -71,6 +71,18 @@ SHOW CREATE TABLE t1; DROP TABLE t1; # +# Bug# +# CREATE TABLE and CREATE DATABASE didn't fail in some cases +# +--error 1302 +create table t1 (a char) character set latin1 character set latin2; +--error 1253 +create table t1 (a char) character set latin1 collate latin2_bin; +--error 1302 +create database d1 default character set latin1 character set latin2; +--error 1253 +create database d1 default character set latin1 collate latin2_bin; + # # DROP DATABASE mysqltest1; diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index 83055d05830..2c531d4e5d2 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -3,8 +3,7 @@ # --disable_warnings -drop table if exists t1; -drop table if exists t2; +drop table if exists t1,t2; --enable_warnings set names utf8; @@ -294,6 +293,30 @@ select c as c_a from t1 where c='a'; select c as c_a from t1 where c='б'; drop table t1; +# +# Bug 4531: unique key prefix interacts poorly with utf8 +# Check BDB, case insensitive collation +# +--disable_warnings +create table t1 ( +c char(10) character set utf8, +unique key a (c(1)) +) engine=bdb; +--enable_warnings +insert into t1 values ('a'),('b'),('c'),('d'),('e'),('f'); +--error 1062 +insert into t1 values ('aa'); +--error 1062 +insert into t1 values ('aaa'); +insert into t1 values ('б'); +--error 1062 +insert into t1 values ('бб'); +--error 1062 +insert into t1 values ('ббб'); +select c as c_all from t1 order by c; +select c as c_a from t1 where c='a'; +select c as c_a from t1 where c='б'; +drop table t1; # # Bug 4521: unique key prefix interacts poorly with utf8 @@ -393,6 +416,31 @@ select c as c_a from t1 where c='a'; select c as c_a from t1 where c='б'; drop table t1; +# +# Bug 4531: unique key prefix interacts poorly with utf8 +# Check BDB, binary collation +# +--disable_warnings +create table t1 ( +c char(10) character set utf8 collate utf8_bin, +unique key a (c(1)) +) engine=bdb; +--enable_warnings +insert into t1 values ('a'),('b'),('c'),('d'),('e'),('f'); +--error 1062 +insert into t1 values ('aa'); +--error 1062 +insert into t1 values ('aaa'); +insert into t1 values ('б'); +--error 1062 +insert into t1 values ('бб'); +--error 1062 +insert into t1 values ('ббб'); +select c as c_all from t1 order by c; +select c as c_a from t1 where c='a'; +select c as c_a from t1 where c='б'; +drop table t1; + # Bug#4594: column index make = failed for gbk, but like works # Check MYISAM @@ -429,3 +477,18 @@ INSERT INTO t1 VALUES ('str'); INSERT INTO t1 VALUES ('str2'); select * from t1 where str='str'; drop table t1; + +# the same for BDB +# + +--disable_warnings +create table t1 ( + str varchar(255) character set utf8 not null, + key str (str(2)) +) engine=bdb; +--enable_warnings +INSERT INTO t1 VALUES ('str'); +INSERT INTO t1 VALUES ('str2'); +select * from t1 where str='str'; +drop table t1; + diff --git a/mysql-test/t/endspace.test b/mysql-test/t/endspace.test index a9933ff93b5..9ee5e32967a 100644 --- a/mysql-test/t/endspace.test +++ b/mysql-test/t/endspace.test @@ -31,19 +31,25 @@ explain select * from t1 order by text1; alter table t1 modify text1 char(32) binary not null; check table t1; select * from t1 ignore key (key1) where text1='teststring' or text1 like 'teststring_%'; -select * from t1 where text1='teststring' or text1 like 'teststring_%'; -select * from t1 where text1='teststring' or text1 > 'teststring\t'; +select concat('|', text1, '|') from t1 where text1='teststring' or text1 like 'teststring_%'; +select concat('|', text1, '|') from t1 where text1='teststring' or text1 > 'teststring\t'; select text1, length(text1) from t1 order by text1; select text1, length(text1) from t1 order by binary text1; alter table t1 modify text1 blob not null, drop key key1, add key key1 (text1(20)); insert into t1 values ('teststring '); select concat('|', text1, '|') from t1 order by text1; +select concat('|', text1, '|') from t1 where text1='teststring' or text1 > 'teststring\t'; +select concat('|', text1, '|') from t1 where text1='teststring'; +select concat('|', text1, '|') from t1 where text1='teststring '; alter table t1 modify text1 text not null, pack_keys=1; +select concat('|', text1, '|') from t1 where text1='teststring'; +select concat('|', text1, '|') from t1 where text1='teststring '; +explain select concat('|', text1, '|') from t1 where text1='teststring '; select * from t1 where text1 like 'teststring_%'; select * from t1 where text1='teststring' or text1 like 'teststring_%'; -select * from t1 where text1='teststring' or text1 > 'teststring\t'; +select concat('|', text1, '|') from t1 where text1='teststring' or text1 > 'teststring\t'; select concat('|', text1, '|') from t1 order by text1; drop table t1; diff --git a/mysql-test/t/func_in.test b/mysql-test/t/func_in.test index 855a7cbd28f..22079377ad2 100644 --- a/mysql-test/t/func_in.test +++ b/mysql-test/t/func_in.test @@ -75,6 +75,13 @@ select * from t1 where 'a' in (a,b,c collate latin1_bin); explain extended select * from t1 where 'a' in (a,b,c collate latin1_bin); drop table t1; +set names utf8; +create table t1 (a char(10) character set utf8 not null); +insert into t1 values ('bbbb'),(_koi8r''),(_latin1''); +select a from t1 where a in ('bbbb',_koi8r'',_latin1'') order by a; +drop table t1; +set names latin1; + select '1.0' in (1,2); select 1 in ('1.0',2); select 1 in (1,'2.0'); diff --git a/mysql-test/t/func_set.test b/mysql-test/t/func_set.test index 03843fd3da5..d669739bcb4 100644 --- a/mysql-test/t/func_set.test +++ b/mysql-test/t/func_set.test @@ -31,11 +31,19 @@ drop table if exists t1,t2; --enable_warnings create table t1 (id int(10) not null unique); -create table t2 (id int(10) not null primary key, -val int(10) not null); +create table t2 (id int(10) not null primary key, val int(10) not null); insert into t1 values (1),(2),(4); insert into t2 values (1,1),(2,1),(3,1),(4,2); select one.id, elt(two.val,'one','two') from t1 one, t2 two where two.id=one.id; select one.id, elt(two.val,'one','two') from t1 one, t2 two where two.id=one.id order by one.id; drop table t1,t2; + +# +# Bug4340: find_in_set is case insensitive even on binary operators +# + +select find_in_set(binary 'a',binary 'A,B,C'); +select find_in_set('a',binary 'A,B,C'); +select find_in_set(binary 'a', 'A,B,C'); + diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test index 590007caba1..e35b9996a44 100644 --- a/mysql-test/t/gis.test +++ b/mysql-test/t/gis.test @@ -172,3 +172,21 @@ insert IGNORE into t1 values ('Garbage'); alter table t1 add spatial index(a); drop table t1; + +# +# Bug #5219: problem with range optimizer +# + +create table t1(a geometry not null, spatial index(a)); +insert into t1 values +(GeomFromText('POINT(1 1)')), (GeomFromText('POINT(3 3)')), +(GeomFromText('POINT(4 4)')), (GeomFromText('POINT(6 6)')); +select AsText(a) from t1 where + MBRContains(GeomFromText('Polygon((0 0, 0 2, 2 2, 2 0, 0 0))'), a) + or + MBRContains(GeomFromText('Polygon((2 2, 2 5, 5 5, 5 2, 2 2))'), a); +select AsText(a) from t1 where + MBRContains(GeomFromText('Polygon((0 0, 0 2, 2 2, 2 0, 0 0))'), a) + and + MBRContains(GeomFromText('Polygon((0 0, 0 7, 7 7, 7 0, 0 0))'), a); +drop table t1; diff --git a/mysql-test/t/having.test b/mysql-test/t/having.test index 870f57a4483..12a44fd75dc 100644 --- a/mysql-test/t/having.test +++ b/mysql-test/t/having.test @@ -121,3 +121,4 @@ select from t1 a left join t3 b on a.id=b.order_id group by a.id, a.description having (a.description is not null) and (c=0); +drop table t1,t2,t3; diff --git a/mysql-test/t/lowercase_table.test b/mysql-test/t/lowercase_table.test index db46f3d432d..bdfa8dfc132 100644 --- a/mysql-test/t/lowercase_table.test +++ b/mysql-test/t/lowercase_table.test @@ -54,3 +54,13 @@ select C.a, c.a from t1 c, t2 C; drop table t1, t2; show tables; + +# +# Test all caps database name +# +create table t1 (a int); +select TEST.t1.* from TEST.t1; +alter table t1 rename to T1; +select TEST.t1.* from TEST.t1; +drop table t1; + diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index e6d47b5c570..f9081e8769b 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -423,6 +423,18 @@ select * from t1 where a='807780' and b='477' and c='165'; drop table t1; # +# space-stripping in _mi_prefix_search: BUG#5284 +# +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (a varchar(150) NOT NULL, KEY (a)); +INSERT t1 VALUES ("can \tcan"); +INSERT t1 VALUES ("can can"); +INSERT t1 VALUES ("can"); +SELECT * FROM t1; +CHECK TABLE t1; +DROP TABLE t1; + +# # Verify blob handling # create table t1 (a blob); diff --git a/mysql-test/t/ndb_autodiscover.test b/mysql-test/t/ndb_autodiscover.test index d04599f223e..371a130291b 100644 --- a/mysql-test/t/ndb_autodiscover.test +++ b/mysql-test/t/ndb_autodiscover.test @@ -50,7 +50,7 @@ flush tables; system rm var/master-data/test/t1.frm ; update t1 set name="Autodiscover" where id = 2; show status like 'handler_discover%'; -select * from t1 order by name; +select * from t1 order by id; show status like 'handler_discover%'; # diff --git a/mysql-test/t/ndb_basic.test b/mysql-test/t/ndb_basic.test index ea2a70e1837..448db0a9165 100644 --- a/mysql-test/t/ndb_basic.test +++ b/mysql-test/t/ndb_basic.test @@ -221,6 +221,12 @@ while ($1) } enable_query_log; +delete from t2 where a > 5; +select x1.a, x1.b from t2 x1, t2 x2 where x1.b = x2.b order by x1.a; +select a, b FROM t2 outer_table where +a = (select a from t2 where b = outer_table.b ) order by a; + + delete from t2; delete from t3; delete from t4; diff --git a/mysql-test/t/ndb_index_ordered.test b/mysql-test/t/ndb_index_ordered.test index 3def52e865c..00807bfcb98 100644 --- a/mysql-test/t/ndb_index_ordered.test +++ b/mysql-test/t/ndb_index_ordered.test @@ -113,24 +113,31 @@ select * from t1 where b<=5 and c=0; select * from t1 where b=4 and c<=5 order by a; select * from t1 where b<=4 and c<=5 order by a; select * from t1 where b<=5 and c=0 or b<=5 and c=2; + +select count(*) from t1 where b = 0; +select count(*) from t1 where b = 1; drop table t1; # # Indexing NULL values # -#CREATE TABLE t1 ( -# a int unsigned NOT NULL PRIMARY KEY, -# b int unsigned, -# c int unsigned, -# KEY bc(b,c) -#) engine = ndb; - -#insert into t1 values(1,1,1),(2,NULL,2),(3,NULL,NULL),(4,4,NULL); -#select * from t1 use index (bc); -#select count(*) from t1 use index (bc); -#select count(*) from t1 use index (PRIMARY) where b IS NULL; -#select count(*) from t1 use index (bc) where b IS NULL; -#select count(*) from t1 use index (bc) where b IS NULL and c = 2; -#select count(*) from t1 use index (bc) where b IS NOT NULL; -#drop table t1; +CREATE TABLE t1 ( + a int unsigned NOT NULL PRIMARY KEY, + b int unsigned, + c int unsigned, + KEY bc(b,c) +) engine = ndb; + +insert into t1 values(1,1,1),(2,NULL,2),(3,NULL,NULL),(4,4,NULL); +select * from t1 use index (bc) where b IS NULL; + +select * from t1 use index (bc)order by a; +select * from t1 use index (bc) order by a; +select * from t1 use index (PRIMARY) where b IS NULL order by a; +select * from t1 use index (bc) where b IS NULL order by a; +select * from t1 use index (bc) where b IS NULL and c IS NULL order by a; +select * from t1 use index (bc) where b IS NULL and c = 2 order by a; +select * from t1 use index (bc) where b < 4 order by a; +select * from t1 use index (bc) where b IS NOT NULL order by a; +drop table t1; diff --git a/mysql-test/t/ndb_index_unique.test b/mysql-test/t/ndb_index_unique.test index 96abc842639..4a0c689bafb 100644 --- a/mysql-test/t/ndb_index_unique.test +++ b/mysql-test/t/ndb_index_unique.test @@ -82,43 +82,43 @@ drop table t3; # Indexes on NULL-able columns # -#CREATE TABLE t1 ( -# pk int NOT NULL PRIMARY KEY, -# a int unsigned, -# UNIQUE KEY (a) -#) engine=ndbcluster; +CREATE TABLE t1 ( + pk int NOT NULL PRIMARY KEY, + a int unsigned, + UNIQUE KEY (a) +) engine=ndbcluster; -#insert into t1 values (-1,NULL), (0,0), (1,NULL),(2,2),(3,NULL),(4,4); - -#select * from t1 order by pk; - -#--error 1169 -#insert into t1 values (5,0); -#select * from t1 order by pk; -#delete from t1 where a = 0; -#insert into t1 values (5,0); -#select * from t1 order by pk; - -#CREATE TABLE t2 ( -# pk int NOT NULL PRIMARY KEY, -# a int unsigned, -# b tinyint NOT NULL, -# c VARCHAR(10), -# UNIQUE KEY si(a, c) -#) engine=ndbcluster; - -#insert into t2 values (-1,1,17,NULL),(0,NULL,18,NULL),(1,3,19,'abc'); - -#select * from t2 order by pk; - -#--error 1169 -#insert into t2 values(2,3,19,'abc'); -#select * from t2 order by pk; -#delete from t2 where c IS NOT NULL; -#insert into t2 values(2,3,19,'abc'); -#select * from t2 order by pk; +insert into t1 values (-1,NULL), (0,0), (1,NULL),(2,2),(3,NULL),(4,4); + +select * from t1 order by pk; + +--error 1169 +insert into t1 values (5,0); +select * from t1 order by pk; +delete from t1 where a = 0; +insert into t1 values (5,0); +select * from t1 order by pk; + +CREATE TABLE t2 ( + pk int NOT NULL PRIMARY KEY, + a int unsigned, + b tinyint NOT NULL, + c VARCHAR(10), + UNIQUE KEY si(a, c) +) engine=ndbcluster; + +insert into t2 values (-1,1,17,NULL),(0,NULL,18,NULL),(1,3,19,'abc'); + +select * from t2 order by pk; + +--error 1169 +insert into t2 values(2,3,19,'abc'); +select * from t2 order by pk; +delete from t2 where c IS NOT NULL; +insert into t2 values(2,3,19,'abc'); +select * from t2 order by pk; -#drop table t1, t2; +drop table t1, t2; # # More complex tables diff --git a/mysql-test/t/ndb_replace.test b/mysql-test/t/ndb_replace.test index 8ba332fc7af..59454b5a9fa 100644 --- a/mysql-test/t/ndb_replace.test +++ b/mysql-test/t/ndb_replace.test @@ -20,7 +20,7 @@ replace into t1 (gesuchnr,benutzer_id) values (1,1); insert into t1 (gesuchnr, benutzer_id) value (3,2); replace into t1 (gesuchnr,benutzer_id) values (1,1); replace into t1 (gesuchnr,benutzer_id) values (1,1); ---error 1022 +--error 1062 insert into t1 (gesuchnr,benutzer_id) values (1,1); replace into t1 (gesuchnr,benutzer_id) values (1,1); select * from t1 order by gesuchnr; diff --git a/mysql-test/t/negation_elimination.test b/mysql-test/t/negation_elimination.test index 49428cc238b..c50a9678edb 100644 --- a/mysql-test/t/negation_elimination.test +++ b/mysql-test/t/negation_elimination.test @@ -65,4 +65,8 @@ select * from t1 where not((a < 5 and a < 10) and (not(a > 16) or a > 17)); explain select * from t1 where ((a between 5 and 15) and (not(a like 10))); select * from t1 where ((a between 5 and 15) and (not(a like 10))); +delete from t1 where a > 3; +select a, not(not(a)) from t1; +explain extended select a, not(not(a)), not(a <= 2 and not(a)), not(a not like "1"), not (a not in (1,2)), not(a != 2) from t1 where not(not(a)) having not(not(a)); + drop table t1; diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 9d23c795e05..e54bf8076e0 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -209,7 +209,7 @@ drop table t1; # # Bug#4912 "mysqld crashs in case a statement is executed a second time": -# negation elimination should and prepared statemens +# negation elimination should work once and not break prepared statements # create table t1(a varchar(2), b varchar(3)); @@ -217,4 +217,47 @@ prepare stmt1 from "select a, b from t1 where (not (a='aa' and b < 'zzz'))"; execute stmt1; execute stmt1; deallocate prepare stmt1; +drop table t1; + +# +# Bug#5034 "prepared "select 1 into @arg15", second execute crashes +# server". +# Check that descendands of select_result can be reused in prepared +# statements or are correctly created and deleted on each execute +# + +prepare stmt1 from "select 1 into @var"; +execute stmt1; +execute stmt1; +prepare stmt1 from "create table t1 select 1 as i"; +execute stmt1; +drop table t1; +execute stmt1; +prepare stmt1 from "insert into t1 select i from t1"; +execute stmt1; +execute stmt1; +prepare stmt1 from "select * from t1 into outfile 'f1.txt'"; +execute stmt1; +deallocate prepare stmt1; +drop table t1; + +# +# BUG#5242 "Prepared statement names are case sensitive" +# +prepare stmt1 from 'select 1'; +prepare STMT1 from 'select 2'; +execute sTmT1; +deallocate prepare StMt1; + +--error 1243 +deallocate prepare Stmt1; + +# also check that statement names are in right charset. +set names utf8; +prepare `ü` from 'select 1234'; +execute `ü` ; +set names latin1; +execute ``; +set names default; + diff --git a/mysql-test/t/truncate.test b/mysql-test/t/truncate.test index 434a1907e42..b7ec506ecf1 100644 --- a/mysql-test/t/truncate.test +++ b/mysql-test/t/truncate.test @@ -26,7 +26,7 @@ drop table t1; truncate non_existing_table; # -# test autoincrement with TRUNCATE +# test autoincrement with TRUNCATE; verifying difference with DELETE # create table t1 (a integer auto_increment primary key); @@ -34,5 +34,19 @@ insert into t1 (a) values (NULL),(NULL); truncate table t1; insert into t1 (a) values (NULL),(NULL); SELECT * from t1; +delete from t1; +insert into t1 (a) values (NULL),(NULL); +SELECT * from t1; drop table t1; +# Verifying that temp tables are handled the same way + +create temporary table t1 (a integer auto_increment primary key); +insert into t1 (a) values (NULL),(NULL); +truncate table t1; +insert into t1 (a) values (NULL),(NULL); +SELECT * from t1; +delete from t1; +insert into t1 (a) values (NULL),(NULL); +SELECT * from t1; +drop table t1; diff --git a/mysql-test/t/type_blob.test b/mysql-test/t/type_blob.test index 8c6cabd997b..bd571deff49 100644 --- a/mysql-test/t/type_blob.test +++ b/mysql-test/t/type_blob.test @@ -340,6 +340,7 @@ drop table t1; create table t1 (id integer primary key auto_increment, txt text, unique index txt_index (txt (20))); insert into t1 (txt) values ('Chevy'), ('Chevy '), (NULL); select * from t1 where txt='Chevy' or txt is NULL; +explain select * from t1 where txt='Chevy' or txt is NULL; select * from t1 where txt='Chevy '; select * from t1 where txt='Chevy ' or txt='Chevy'; select * from t1 where txt='Chevy' or txt='Chevy '; @@ -358,7 +359,13 @@ select * from t1 where txt < 'Chevy ' or txt is NULL; select * from t1 where txt <= 'Chevy'; select * from t1 where txt > 'Chevy'; select * from t1 where txt >= 'Chevy'; +alter table t1 modify column txt blob; +explain select * from t1 where txt='Chevy' or txt is NULL; +select * from t1 where txt='Chevy' or txt is NULL; +explain select * from t1 where txt='Chevy' or txt is NULL order by txt; +select * from t1 where txt='Chevy' or txt is NULL order by txt; drop table t1; + CREATE TABLE t1 ( i int(11) NOT NULL default '0', c text NOT NULL, PRIMARY KEY (i), KEY (c(1),c(1))); INSERT t1 VALUES (1,''),(2,''),(3,'asdfh'),(4,''); select max(i) from t1 where c = ''; diff --git a/mysql-test/t/type_timestamp.test b/mysql-test/t/type_timestamp.test index 9b3abc9f155..a644197f757 100644 --- a/mysql-test/t/type_timestamp.test +++ b/mysql-test/t/type_timestamp.test @@ -234,3 +234,13 @@ alter table t1 add i int default 10; select * from t1; drop table t1; + +# Test for bug #4491, TIMESTAMP(19) should be possible to create and not +# only read in 4.0 +# +create table t1 (ts timestamp(19)); +show create table t1; +set TIMESTAMP=1000000000; +insert into t1 values (); +select * from t1; +drop table t1; diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index 60ebeb045f5..a480ecb570a 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -324,3 +324,14 @@ SELECT @@global.global.key_buffer_size; SELECT @@global.session.key_buffer_size; --error 1064 SELECT @@global.local.key_buffer_size; + +# BUG#5135: cannot turn on log_warnings with SET in 4.1 (and 4.0) +set @tstlw = @@log_warnings; +show global variables like 'log_warnings'; +set global log_warnings = 0; +show global variables like 'log_warnings'; +set global log_warnings = 42; +show global variables like 'log_warnings'; +set global log_warnings = @tstlw; +show global variables like 'log_warnings'; + diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index d7a9babe5e7..07a8f199b3b 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -17,9 +17,9 @@ #include <my_global.h> #include <m_string.h> #include <stdlib.h> -#include <my_getopt.h> #include <my_sys.h> #include <mysys_err.h> +#include <my_getopt.h> static int findopt(char *optpat, uint length, const struct my_option **opt_res, @@ -56,6 +56,13 @@ char *disabled_my_option= (char*) "0"; my_bool my_getopt_print_errors= 1; +void default_reporter(enum loglevel level, const char *format, ...) +{ + va_list args; + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); +} /* function: handle_options @@ -76,10 +83,8 @@ void my_getopt_register_get_addr(gptr* (*func_addr)(const char *, uint, } int handle_options(int *argc, char ***argv, - const struct my_option *longopts, - my_bool (*get_one_option)(int, - const struct my_option *, - char *)) + const struct my_option *longopts, my_get_one_option get_one_option, + my_error_reporter reporter) { uint opt_found, argvpos= 0, length, i; my_bool end_of_options= 0, must_be_var, set_maximum_value, @@ -95,6 +100,8 @@ int handle_options(int *argc, char ***argv, (*argv)++; /* --- || ---- */ init_variables(longopts); + if (! reporter) reporter = &default_reporter; + for (pos= *argv, pos_end=pos+ *argc; pos != pos_end ; pos++) { char *cur_arg= *pos; @@ -118,8 +125,8 @@ int handle_options(int *argc, char ***argv, if (!*++pos) { if (my_getopt_print_errors) - fprintf(stderr, "%s: Option '-O' requires an argument\n", - my_progname); + reporter(ERROR_LEVEL, "%s: Option '-O' requires an argument\n", + my_progname); return EXIT_ARGUMENT_REQUIRED; } cur_arg= *pos; @@ -135,9 +142,8 @@ int handle_options(int *argc, char ***argv, if (!*cur_arg) { if (my_getopt_print_errors) - fprintf(stderr, - "%s: Option '--set-variable' requires an argument\n", - my_progname); + reporter(ERROR_LEVEL, "%s: Option '--set-variable' requires an argument\n", + my_progname); return EXIT_ARGUMENT_REQUIRED; } } @@ -149,9 +155,8 @@ int handle_options(int *argc, char ***argv, if (!*++pos) { if (my_getopt_print_errors) - fprintf(stderr, - "%s: Option '--set-variable' requires an argument\n", - my_progname); + reporter(ERROR_LEVEL, "%s: Option '--set-variable' requires an argument\n", + my_progname); return EXIT_ARGUMENT_REQUIRED; } cur_arg= *pos; @@ -210,7 +215,7 @@ int handle_options(int *argc, char ***argv, if (opt_found > 1) { if (my_getopt_print_errors) - fprintf(stderr, + reporter(ERROR_LEVEL, "%s: ambiguous option '--%s-%s' (--%s-%s)\n", my_progname, special_opt_prefix[i], opt_str, special_opt_prefix[i], prev_found); @@ -245,18 +250,16 @@ int handle_options(int *argc, char ***argv, if (must_be_var) { if (my_getopt_print_errors) - fprintf(stderr, - "%s: %s: unknown variable '%s'\n", my_progname, - option_is_loose ? "WARNING" : "ERROR", opt_str); + reporter(option_is_loose ? WARNING_LEVEL : ERROR_LEVEL, + "%s: unknown variable '%s'\n", my_progname, cur_arg); if (!option_is_loose) return EXIT_UNKNOWN_VARIABLE; } else { if (my_getopt_print_errors) - fprintf(stderr, - "%s: %s: unknown option '--%s'\n", my_progname, - option_is_loose ? "WARNING" : "ERROR", opt_str); + reporter(option_is_loose ? WARNING_LEVEL : ERROR_LEVEL, + "%s: unknown option '--%s'\n", my_progname, cur_arg); if (!option_is_loose) return EXIT_UNKNOWN_OPTION; } @@ -272,14 +275,14 @@ int handle_options(int *argc, char ***argv, if (must_be_var) { if (my_getopt_print_errors) - fprintf(stderr, "%s: variable prefix '%s' is not unique\n", + reporter(ERROR_LEVEL, "%s: variable prefix '%s' is not unique\n", my_progname, opt_str); return EXIT_VAR_PREFIX_NOT_UNIQUE; } else { if (my_getopt_print_errors) - fprintf(stderr, "%s: ambiguous option '--%s' (%s, %s)\n", + reporter(ERROR_LEVEL, "%s: ambiguous option '--%s' (%s, %s)\n", my_progname, opt_str, prev_found, optp->name); return EXIT_AMBIGUOUS_OPTION; } @@ -300,7 +303,7 @@ int handle_options(int *argc, char ***argv, if (must_be_var && (optp->var_type & GET_TYPE_MASK) == GET_NO_ARG) { if (my_getopt_print_errors) - fprintf(stderr, "%s: option '%s' cannot take an argument\n", + reporter(ERROR_LEVEL, "%s: option '%s' cannot take an argument\n", my_progname, optp->name); return EXIT_NO_ARGUMENT_ALLOWED; } @@ -312,7 +315,7 @@ int handle_options(int *argc, char ***argv, if (optend && (optp->var_type & GET_TYPE_MASK) != GET_BOOL) { if (my_getopt_print_errors) - fprintf(stderr, "%s: option '--%s' cannot take an argument\n", + reporter(ERROR_LEVEL, "%s: option '--%s' cannot take an argument\n", my_progname, optp->name); return EXIT_NO_ARGUMENT_ALLOWED; } @@ -351,7 +354,7 @@ int handle_options(int *argc, char ***argv, if (!*++pos) { if (my_getopt_print_errors) - fprintf(stderr, "%s: option '--%s' requires an argument\n", + reporter(ERROR_LEVEL, "%s: option '--%s' requires an argument\n", my_progname, optp->name); return EXIT_ARGUMENT_REQUIRED; } @@ -410,7 +413,7 @@ int handle_options(int *argc, char ***argv, if (!pos[1]) { if (my_getopt_print_errors) - fprintf(stderr, + reporter(ERROR_LEVEL, "%s: option '-%c' requires an argument\n", my_progname, optp->id); return EXIT_ARGUMENT_REQUIRED; @@ -423,7 +426,7 @@ int handle_options(int *argc, char ***argv, if ((error= setval(optp, optp->value, argument, set_maximum_value))) { - fprintf(stderr, + reporter(ERROR_LEVEL, "%s: Error while setting value '%s' to '%s'\n", my_progname, argument, optp->name); return error; @@ -435,7 +438,7 @@ int handle_options(int *argc, char ***argv, if (!opt_found) { if (my_getopt_print_errors) - fprintf(stderr, + reporter(ERROR_LEVEL, "%s: unknown option '-%c'\n", my_progname, *optend); return EXIT_UNKNOWN_OPTION; } @@ -445,7 +448,7 @@ int handle_options(int *argc, char ***argv, } if ((error= setval(optp, value, argument, set_maximum_value))) { - fprintf(stderr, + reporter(ERROR_LEVEL, "%s: Error while setting value '%s' to '%s'\n", my_progname, argument, optp->name); return error; diff --git a/ndb/include/ndb_global.h b/ndb/include/ndb_global.h index 038950a7a32..b8fcca6dbb1 100644 --- a/ndb/include/ndb_global.h +++ b/ndb/include/ndb_global.h @@ -94,6 +94,14 @@ extern int strcasecmp(const char *s1, const char *s2); extern int strncasecmp(const char *s1, const char *s2, size_t n); #endif +#ifdef SCO + +#ifndef PATH_MAX +#define PATH_MAX 1024 +#endif + +#endif /* SCO */ + #ifdef __cplusplus } #endif diff --git a/ndb/include/util/Properties.hpp b/ndb/include/util/Properties.hpp index 2c30f7f7e3c..df8e2887001 100644 --- a/ndb/include/util/Properties.hpp +++ b/ndb/include/util/Properties.hpp @@ -55,7 +55,7 @@ public: static const char delimiter = ':'; static const char version[]; - Properties(); + Properties(bool case_insensitive= false); Properties(const Properties &); Properties(const Property *, int len); virtual ~Properties(); diff --git a/ndb/src/common/logger/FileLogHandler.cpp b/ndb/src/common/logger/FileLogHandler.cpp index d13dd7b2a78..632db71db15 100644 --- a/ndb/src/common/logger/FileLogHandler.cpp +++ b/ndb/src/common/logger/FileLogHandler.cpp @@ -14,8 +14,8 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <ndb_global.h> #include <FileLogHandler.hpp> - #include <File.hpp> // @@ -146,7 +146,7 @@ FileLogHandler::createNewFile() { bool rc = true; int fileNo = 1; - char newName[MAXPATHLEN]; + char newName[PATH_MAX]; do { diff --git a/ndb/src/common/mgmcommon/ConfigInfo.cpp b/ndb/src/common/mgmcommon/ConfigInfo.cpp index 997c26a95d6..552b49727fb 100644 --- a/ndb/src/common/mgmcommon/ConfigInfo.cpp +++ b/ndb/src/common/mgmcommon/ConfigInfo.cpp @@ -25,6 +25,15 @@ /**************************************************************************** * Section names ****************************************************************************/ + +const ConfigInfo::AliasPair +ConfigInfo::m_sectionNameAliases[]={ + {"API", "MYSQLD"}, + {"DB", "NDBD"}, + {"MGM", "NDB_MGMD"}, + {0, 0} +}; + const char* ConfigInfo::m_sectionNames[]={ "SYSTEM", @@ -153,14 +162,14 @@ const int ConfigInfo::m_NoOfRules = sizeof(m_SectionRules)/sizeof(SectionRule); * Config Rules declarations ****************************************************************************/ static bool add_node_connections(Vector<ConfigInfo::ConfigRuleSection>§ions, - struct InitConfigFileParser::Context &ctx, - const char * rule_data); + struct InitConfigFileParser::Context &ctx, + const char * rule_data); static bool add_server_ports(Vector<ConfigInfo::ConfigRuleSection>§ions, - struct InitConfigFileParser::Context &ctx, - const char * rule_data); + struct InitConfigFileParser::Context &ctx, + const char * rule_data); static bool check_node_vs_replicas(Vector<ConfigInfo::ConfigRuleSection>§ions, - struct InitConfigFileParser::Context &ctx, - const char * rule_data); + struct InitConfigFileParser::Context &ctx, + const char * rule_data); const ConfigInfo::ConfigRule ConfigInfo::m_ConfigRules[] = { @@ -432,7 +441,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { 8192, 0, MAX_INT_RNIL - }, + }, { CFG_DB_NO_TRIGGERS, @@ -1885,21 +1894,19 @@ const int ConfigInfo::m_NoOfParams = sizeof(m_ParamInfo) / sizeof(ParamInfo); ****************************************************************************/ static void require(bool v) { if(!v) abort();} -ConfigInfo::ConfigInfo() { +ConfigInfo::ConfigInfo() + : m_info(true), m_systemDefaults(true) +{ int i; Properties *section; const Properties *oldpinfo; - m_info.setCaseInsensitiveNames(true); - m_systemDefaults.setCaseInsensitiveNames(true); - for (i=0; i<m_NoOfParams; i++) { const ParamInfo & param = m_ParamInfo[i]; // Create new section if it did not exist if (!m_info.getCopy(param._section, §ion)) { - Properties newsection; - newsection.setCaseInsensitiveNames(true); + Properties newsection(true); m_info.put(param._section, &newsection); } @@ -1907,7 +1914,7 @@ ConfigInfo::ConfigInfo() { m_info.getCopy(param._section, §ion); // Create pinfo (parameter info) entry - Properties pinfo; + Properties pinfo(true); pinfo.put("Id", param._paramId); pinfo.put("Fname", param._fname); pinfo.put("Description", param._description); @@ -1935,8 +1942,7 @@ ConfigInfo::ConfigInfo() { if(param._type != ConfigInfo::SECTION){ Properties * p; if(!m_systemDefaults.getCopy(param._section, &p)){ - p = new Properties(); - p->setCaseInsensitiveNames(true); + p = new Properties(true); } if(param._type != STRING && param._default != UNDEFINED && @@ -2063,6 +2069,14 @@ ConfigInfo::isSection(const char * section) const { return false; } +const char* +ConfigInfo::getAlias(const char * section) const { + for (int i = 0; m_sectionNameAliases[i].name != 0; i++) + if(!strcmp(section, m_sectionNameAliases[i].alias)) + return m_sectionNameAliases[i].name; + return 0; +} + bool ConfigInfo::verify(const Properties * section, const char* fname, Uint64 value) const { @@ -2819,7 +2833,7 @@ fixDepricated(InitConfigFileParser::Context & ctx, const char * data){ * Transform old values to new values * Transform new values to old values (backward compatible) */ - Properties tmp; + Properties tmp(true); Properties::Iterator it(ctx.m_currentSection); for (name = it.first(); name != NULL; name = it.next()) { const DepricationTransform * p = &f_deprication[0]; @@ -2951,8 +2965,8 @@ add_node_connections(Vector<ConfigInfo::ConfigRuleSection>§ions, { Uint32 i; Properties * props= ctx.m_config; - Properties p_connections; - Properties p_connections2; + Properties p_connections(true); + Properties p_connections2(true); for (i = 0;; i++){ const Properties * tmp; @@ -2972,8 +2986,8 @@ add_node_connections(Vector<ConfigInfo::ConfigRuleSection>§ions, Uint32 nNodes; ctx.m_userProperties.get("NoOfNodes", &nNodes); - Properties p_db_nodes; - Properties p_api_mgm_nodes; + Properties p_db_nodes(true); + Properties p_api_mgm_nodes(true); Uint32 i_db= 0, i_api_mgm= 0, n; for (i= 0, n= 0; n < nNodes; i++){ @@ -2999,7 +3013,7 @@ add_node_connections(Vector<ConfigInfo::ConfigRuleSection>§ions, if(!p_connections2.get("", nodeId1+nodeId2<<16, &dummy)) { ConfigInfo::ConfigRuleSection s; s.m_sectionType= BaseString("TCP"); - s.m_sectionData= new Properties; + s.m_sectionData= new Properties(true); char buf[16]; snprintf(buf, sizeof(buf), "%u", nodeId1); s.m_sectionData->put("NodeId1", buf); @@ -3016,7 +3030,7 @@ add_node_connections(Vector<ConfigInfo::ConfigRuleSection>§ions, if(!p_db_nodes.get("", j, &nodeId2)) break; ConfigInfo::ConfigRuleSection s; s.m_sectionType= BaseString("TCP"); - s.m_sectionData= new Properties; + s.m_sectionData= new Properties(true); char buf[16]; snprintf(buf, sizeof(buf), "%u", nodeId1); s.m_sectionData->put("NodeId1", buf); @@ -3037,7 +3051,7 @@ static bool add_server_ports(Vector<ConfigInfo::ConfigRuleSection>§ions, { #if 0 Properties * props= ctx.m_config; - Properties computers; + Properties computers(true); Uint32 port_base = NDB_BASE_PORT+2; Uint32 nNodes; diff --git a/ndb/src/common/mgmcommon/ConfigInfo.hpp b/ndb/src/common/mgmcommon/ConfigInfo.hpp index 79c17b436fe..9a954fe78d5 100644 --- a/ndb/src/common/mgmcommon/ConfigInfo.hpp +++ b/ndb/src/common/mgmcommon/ConfigInfo.hpp @@ -61,6 +61,11 @@ public: Uint64 _max; }; + struct AliasPair{ + const char * name; + const char * alias; + }; + /** * Entry for one section rule */ @@ -100,6 +105,7 @@ public: * @note Result is not defined if section/name are wrong! */ bool verify(const Properties* secti, const char* fname, Uint64 value) const; + const char* getAlias(const char*) const; bool isSection(const char*) const; const char* getDescription(const Properties * sec, const char* fname) const; @@ -123,6 +129,7 @@ private: static const ParamInfo m_ParamInfo[]; static const int m_NoOfParams; + static const AliasPair m_sectionNameAliases[]; static const char* m_sectionNames[]; static const int m_noOfSectionNames; diff --git a/ndb/src/common/mgmcommon/InitConfigFileParser.cpp b/ndb/src/common/mgmcommon/InitConfigFileParser.cpp index d52bc54db52..7c842508491 100644 --- a/ndb/src/common/mgmcommon/InitConfigFileParser.cpp +++ b/ndb/src/common/mgmcommon/InitConfigFileParser.cpp @@ -43,10 +43,10 @@ InitConfigFileParser::~InitConfigFileParser() { // Read Config File //**************************************************************************** InitConfigFileParser::Context::Context(const ConfigInfo * info) - : m_configValues(1000, 20) { + : m_configValues(1000, 20), m_userProperties(true) { - m_config = new Properties(); - m_defaults = new Properties(); + m_config = new Properties(true); + m_defaults = new Properties(true); } InitConfigFileParser::Context::~Context(){ @@ -115,7 +115,7 @@ InitConfigFileParser::parseConfig(FILE * file) { snprintf(ctx.fname, sizeof(ctx.fname), section); free(section); ctx.type = InitConfigFileParser::DefaultSection; ctx.m_sectionLineno = ctx.m_lineno; - ctx.m_currentSection = new Properties(); + ctx.m_currentSection = new Properties(true); ctx.m_userDefaults = NULL; ctx.m_currentInfo = m_info->getInfo(ctx.fname); ctx.m_systemDefaults = m_info->getDefaults(ctx.fname); @@ -137,7 +137,7 @@ InitConfigFileParser::parseConfig(FILE * file) { free(section); ctx.type = InitConfigFileParser::Section; ctx.m_sectionLineno = ctx.m_lineno; - ctx.m_currentSection = new Properties(); + ctx.m_currentSection = new Properties(true); ctx.m_userDefaults = getSection(ctx.fname, ctx.m_defaults); ctx.m_currentInfo = m_info->getInfo(ctx.fname); ctx.m_systemDefaults = m_info->getDefaults(ctx.fname); @@ -222,6 +222,8 @@ bool InitConfigFileParser::parseNameValuePair(Context& ctx, const char* line) { char tmpLine[MAX_LINE_LENGTH]; char fname[MAX_LINE_LENGTH], rest[MAX_LINE_LENGTH]; char* t; + const char *separator_list[]= {":", "=", 0}; + const char *separator= 0; if (ctx.m_currentSection == NULL){ ctx.reportError("Value specified outside section"); @@ -233,7 +235,14 @@ bool InitConfigFileParser::parseNameValuePair(Context& ctx, const char* line) { // ************************************* // Check if a separator exists in line // ************************************* - if (!strchr(tmpLine, ':')) { + for(int i= 0; separator_list[i] != 0; i++) { + if(strchr(tmpLine, separator_list[i][0])) { + separator= separator_list[i]; + break; + } + } + + if (separator == 0) { ctx.reportError("Parse error"); return false; } @@ -241,13 +250,13 @@ bool InitConfigFileParser::parseNameValuePair(Context& ctx, const char* line) { // ******************************************* // Get pointer to substring before separator // ******************************************* - t = strtok(tmpLine, ":"); + t = strtok(tmpLine, separator); // ***************************************** // Count number of tokens before separator // ***************************************** if (sscanf(t, "%120s%120s", fname, rest) != 1) { - ctx.reportError("Multiple names before \':\'"); + ctx.reportError("Multiple names before \'%c\'", separator[0]); return false; } if (!ctx.m_currentInfo->contains(fname)) { @@ -475,8 +484,24 @@ InitConfigFileParser::parseSectionHeader(const char* line) const { tmp[0] = ' '; trim(tmp); + // Convert section header to upper + for(int i= strlen(tmp)-1; i >= 0; i--) + tmp[i]= toupper(tmp[i]); + + // Get the correct header name if an alias + { + const char *tmp_alias= m_info->getAlias(tmp); + if (tmp_alias) { + free(tmp); + tmp= strdup(tmp_alias); + } + } + // Lookup token among sections - if(!m_info->isSection(tmp)) return NULL; + if(!m_info->isSection(tmp)) { + free(tmp); + return NULL; + } if(m_info->getInfo(tmp)) return tmp; free(tmp); @@ -497,7 +522,7 @@ InitConfigFileParser::parseDefaultSectionHeader(const char* line) const { if (no != 2) return NULL; // Not correct keyword at end - if (!strcmp(token2, "DEFAULT") == 0) return NULL; + if (!strcasecmp(token2, "DEFAULT") == 0) return NULL; if(m_info->getInfo(token1)){ return strdup(token1); diff --git a/ndb/src/common/mgmcommon/NdbConfig.c b/ndb/src/common/mgmcommon/NdbConfig.c index 26eb6b5af34..6b609b22fa4 100644 --- a/ndb/src/common/mgmcommon/NdbConfig.c +++ b/ndb/src/common/mgmcommon/NdbConfig.c @@ -32,7 +32,7 @@ NdbConfig_AllocHomePath(int _len) len+= path_len; buf= malloc(len); if (path_len > 0) - snprintf(buf, len, "%s%c", path, DIR_SEPARATOR); + snprintf(buf, len, "%s%s", path, DIR_SEPARATOR); else buf[0]= 0; diff --git a/ndb/src/common/util/Properties.cpp b/ndb/src/common/util/Properties.cpp index 8db7b075d1b..80fb0027830 100644 --- a/ndb/src/common/util/Properties.cpp +++ b/ndb/src/common/util/Properties.cpp @@ -56,7 +56,7 @@ class PropertiesImpl { PropertiesImpl(const PropertiesImpl &); // Not implemented PropertiesImpl& operator=(const PropertiesImpl&); // Not implemented public: - PropertiesImpl(Properties *); + PropertiesImpl(Properties *, bool case_insensitive); PropertiesImpl(Properties *, const PropertiesImpl &); ~PropertiesImpl(); @@ -69,6 +69,7 @@ public: bool m_insensitive; int (* compare)(const char *s1, const char *s2); + void setCaseInsensitiveNames(bool value); void grow(int sizeToAdd); PropertyImpl * get(const char * name) const; @@ -113,9 +114,9 @@ Property::~Property(){ /** * Methods for Properties */ -Properties::Properties(){ +Properties::Properties(bool case_insensitive){ parent = 0; - impl = new PropertiesImpl(this); + impl = new PropertiesImpl(this, case_insensitive); } Properties::Properties(const Properties & org){ @@ -124,7 +125,7 @@ Properties::Properties(const Properties & org){ } Properties::Properties(const Property * anArray, int arrayLen){ - impl = new PropertiesImpl(this); + impl = new PropertiesImpl(this, false); put(anArray, arrayLen); } @@ -479,13 +480,12 @@ Properties::unpack(const Uint32 * buf, Uint32 bufLen){ /** * Methods for PropertiesImpl */ -PropertiesImpl::PropertiesImpl(Properties * p){ +PropertiesImpl::PropertiesImpl(Properties * p, bool case_insensitive){ this->properties = p; items = 0; size = 25; content = new PropertyImpl * [size]; - this->m_insensitive = false; - this->compare = strcmp; + setCaseInsensitiveNames(case_insensitive); } PropertiesImpl::PropertiesImpl(Properties * p, const PropertiesImpl & org){ @@ -506,6 +506,15 @@ PropertiesImpl::~PropertiesImpl(){ delete [] content; } +void +PropertiesImpl::setCaseInsensitiveNames(bool value){ + m_insensitive = value; + if(value) + compare = strcasecmp; + else + compare = strcmp; +} + void PropertiesImpl::grow(int sizeToAdd){ PropertyImpl ** newContent = new PropertyImpl * [size + sizeToAdd]; @@ -523,9 +532,11 @@ PropertiesImpl::get(const char * name) const { return 0; } - for(unsigned int i = 0; i<tmp->items; i++) + for(unsigned int i = 0; i<tmp->items; i++) { if((* compare)(tmp->content[i]->name, short_name) == 0) return tmp->content[i]; + } + return 0; } @@ -1110,11 +1121,7 @@ Properties::getCopy(const char * name, Uint32 no, Properties ** value) const { void Properties::setCaseInsensitiveNames(bool value){ - impl->m_insensitive = value; - if(value) - impl->compare = strcasecmp; - else - impl->compare = strcmp; + impl->setCaseInsensitiveNames(value); } bool diff --git a/ndb/src/ndbapi/NdbBlob.cpp b/ndb/src/ndbapi/NdbBlob.cpp index 65e1aeedda7..7939f54d846 100644 --- a/ndb/src/ndbapi/NdbBlob.cpp +++ b/ndb/src/ndbapi/NdbBlob.cpp @@ -145,6 +145,7 @@ NdbBlob::init() theNdbOp = NULL; theTable = NULL; theAccessTable = NULL; + theBlobTable = NULL; theColumn = NULL; theFillChar = 0; theInlineSize = 0; @@ -1028,9 +1029,9 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl* // sanity check assert((NDB_BLOB_HEAD_SIZE << 2) == sizeof(Head)); assert(theColumn->m_attrSize * theColumn->m_arraySize == sizeof(Head) + theInlineSize); - const NdbDictionary::Table* bt; - const NdbDictionary::Column* bc; if (thePartSize > 0) { + const NdbDictionary::Table* bt = NULL; + const NdbDictionary::Column* bc = NULL; if (theStripeSize == 0 || (bt = theColumn->getBlobTable()) == NULL || (bc = bt->getColumn("DATA")) == NULL || @@ -1039,8 +1040,8 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl* setErrorCode(ErrTable); return -1; } + theBlobTable = &NdbTableImpl::getImpl(*bt); } - theBlobTable = & NdbTableImpl::getImpl(*bt); // buffers theKeyBuf.alloc(theTable->m_sizeOfKeysInWords << 2); theAccessKeyBuf.alloc(theAccessTable->m_sizeOfKeysInWords << 2); diff --git a/ndb/src/ndbapi/NdbScanOperation.cpp b/ndb/src/ndbapi/NdbScanOperation.cpp index 52cb4cecb02..0aa40f968bb 100644 --- a/ndb/src/ndbapi/NdbScanOperation.cpp +++ b/ndb/src/ndbapi/NdbScanOperation.cpp @@ -1188,13 +1188,11 @@ NdbIndexScanOperation::fix_get_values(){ for(Uint32 i = 0; i<cnt; i++){ Uint32 val = theTupleKeyDefined[i][0]; switch(val){ - case FAKE_PTR:{ - NdbColumnImpl * key = idx->m_columns[i]; - NdbColumnImpl * col = tab->getColumn(key->m_keyInfoPos); - curr->setup(col, 0); - } - break; + case FAKE_PTR: + curr->setup(curr->m_column, 0); case API_PTR: + curr = curr->next(); + break; case SETBOUND_EQ: break; #ifdef VM_TRACE @@ -1202,7 +1200,6 @@ NdbIndexScanOperation::fix_get_values(){ abort(); #endif } - curr = curr->next(); } } diff --git a/scripts/mysql_create_system_tables.sh b/scripts/mysql_create_system_tables.sh index 7a30bcdbeca..5a6ea6025f2 100644 --- a/scripts/mysql_create_system_tables.sh +++ b/scripts/mysql_create_system_tables.sh @@ -231,11 +231,11 @@ then c_ht="$c_ht CREATE TABLE help_topic (" c_ht="$c_ht help_topic_id int unsigned not null," - c_ht="$c_ht name varchar(64) not null," + c_ht="$c_ht name nvarchar(64) not null," c_ht="$c_ht help_category_id smallint unsigned not null," c_ht="$c_ht description text not null," c_ht="$c_ht example text not null," - c_ht="$c_ht url varchar(128) not null," + c_ht="$c_ht url nvarchar(128) not null," c_ht="$c_ht primary key (help_topic_id)," c_ht="$c_ht unique index (name)" c_ht="$c_ht )" @@ -252,9 +252,9 @@ then c_hc="$c_hc CREATE TABLE help_category (" c_hc="$c_hc help_category_id smallint unsigned not null," - c_hc="$c_hc name varchar(64) not null," + c_hc="$c_hc name nvarchar(64) not null," c_hc="$c_hc parent_category_id smallint unsigned null," - c_hc="$c_hc url varchar(128) not null," + c_hc="$c_hc url nvarchar(128) not null," c_hc="$c_hc primary key (help_category_id)," c_hc="$c_hc unique index (name)" c_hc="$c_hc )" @@ -269,7 +269,7 @@ then c_hk="$c_hk CREATE TABLE help_keyword (" c_hk="$c_hk help_keyword_id int unsigned not null," - c_hk="$c_hk name varchar(64) not null," + c_hk="$c_hk name nvarchar(64) not null," c_hk="$c_hk primary key (help_keyword_id)," c_hk="$c_hk unique index (name)" c_hk="$c_hk )" diff --git a/sql/field.cc b/sql/field.cc index 96f4fa8fd86..5356fbc773a 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1753,7 +1753,7 @@ void Field_medium::sql_type(String &res) const int Field_long::store(const char *from,uint len,CHARSET_INFO *cs) { long tmp; - int error= 0, cuted_fields= 0; + int error= 0; char *end; tmp= cs->cset->scan(cs, from, from+len, MY_SEQ_SPACES); @@ -1781,7 +1781,7 @@ int Field_long::store(const char *from,uint len,CHARSET_INFO *cs) #if SIZEOF_LONG > 4 if (unsigned_flag) { - if (tmp > UINT_MAX32) + if ((ulong) tmp > UINT_MAX32) { tmp= UINT_MAX32; error= 1; @@ -4277,27 +4277,17 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs) int Field_str::store(double nr) { - bool use_scientific_notation=TRUE; char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE]; uint length; - if (field_length < 32 && nr > 1) // TODO: negative numbers - { - if (ceiling == 0) - { - static double e[]= {1e1, 1e2, 1e4, 1e8, 1e16 }; - double p= 1; - for (int i= sizeof(e)/sizeof(e[0]), j= 1<<i ; j; i--, j>>= 1 ) - { - if (field_length & j) - p*= e[i]; - } - ceiling= p-1; - } - use_scientific_notation= (ceiling < nr); - } - length= (uint)sprintf(buff, "%-.*g", - use_scientific_notation ? max(0,(int)field_length-5) : field_length, - nr); + bool use_scientific_notation= TRUE; + use_scientific_notation= TRUE; +if (field_length < 32 && fabs(nr) < log_10[field_length]-1) + use_scientific_notation= FALSE; + length= (uint) my_sprintf(buff, (buff, "%-.*g", + (use_scientific_notation ? + max(0, (int)field_length-5) : + field_length), + nr)); /* +1 below is because "precision" in %g above means the max. number of significant digits, not the output width. @@ -4310,6 +4300,7 @@ int Field_str::store(double nr) return store((const char *)buff, min(length, field_length), charset()); } + int Field_string::store(longlong nr) { char buff[64]; @@ -4382,7 +4373,7 @@ void Field_string::sql_type(String &res) const (field_length > 3 && (table->db_options_in_use & HA_OPTION_PACK_RECORD) ? - (has_charset() ? "varchar" : "varbinary") : + (has_charset() ? "varchar" : "varbinary") : (has_charset() ? "char" : "binary")), (int) field_length / charset()->mbmaxlen); res.length(length); @@ -4401,6 +4392,21 @@ char *Field_string::pack(char *to, const char *from, uint max_length) } +char *Field_string::pack_key(char *to, const char *from, uint max_length) +{ + uint length= min(field_length,max_length); + uint char_length= max_length/field_charset->mbmaxlen; + if (length > char_length) + char_length= my_charpos(field_charset, from, from+length, char_length); + set_if_smaller(length, char_length); + while (length && from[length-1] == ' ') + length--; + *to= (uchar)length; + memcpy(to+1, from, length); + return to+1+length; +} + + const char *Field_string::unpack(char *to, const char *from) { uint length= (uint) (uchar) *from++; @@ -4564,6 +4570,24 @@ char *Field_varstring::pack(char *to, const char *from, uint max_length) } +char *Field_varstring::pack_key(char *to, const char *from, uint max_length) +{ + uint length=uint2korr(from); + uint char_length= (field_charset->mbmaxlen > 1) ? + max_length/field_charset->mbmaxlen : max_length; + from+=HA_KEY_BLOB_LENGTH; + if (length > char_length) + char_length= my_charpos(field_charset, from, from+length, char_length); + set_if_smaller(length, char_length); + *to++= (char) (length & 255); + if (max_length > 255) + *to++= (char) (length >> 8); + if (length) + memcpy(to, from, length); + return to+length; +} + + const char *Field_varstring::unpack(char *to, const char *from) { uint length; @@ -5139,16 +5163,17 @@ char *Field_blob::pack_key(char *to, const char *from, uint max_length) char *save=ptr; ptr=(char*) from; uint32 length=get_length(); // Length of from string - if (length > max_length) - length=max_length; + uint char_length= (field_charset->mbmaxlen > 1) ? + max_length/field_charset->mbmaxlen : max_length; + if (length) + get_ptr((char**) &from); + if (length > char_length) + char_length= my_charpos(field_charset, from, from+length, char_length); + set_if_smaller(length, char_length); *to++= (uchar) length; if (max_length > 255) // 2 byte length *to++= (uchar) (length >> 8); - if (length) - { - get_ptr((char**) &from); - memcpy(to, from, length); - } + memcpy(to, from, length); ptr=save; // Restore org row pointer return to+length; } diff --git a/sql/field.h b/sql/field.h index 843961e64c3..9cce7b9541b 100644 --- a/sql/field.h +++ b/sql/field.h @@ -336,14 +336,13 @@ public: class Field_str :public Field { protected: CHARSET_INFO *field_charset; - double ceiling; // for ::store(double nr) public: Field_str(char *ptr_arg,uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, utype unireg_check_arg, const char *field_name_arg, struct st_table *table_arg,CHARSET_INFO *charset) :Field(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, - unireg_check_arg, field_name_arg, table_arg), ceiling(0.0) + unireg_check_arg, field_name_arg, table_arg) { field_charset=charset; if (charset->state & MY_CS_BINSORT) @@ -917,6 +916,7 @@ public: void sort_string(char *buff,uint length); void sql_type(String &str) const; char *pack(char *to, const char *from, uint max_length=~(uint) 0); + char *pack_key(char *to, const char *from, uint max_length); const char *unpack(char* to, const char *from); int pack_cmp(const char *a,const char *b,uint key_length); int pack_cmp(const char *b,uint key_length); @@ -965,6 +965,7 @@ public: void set_key_image(char *buff,uint length, CHARSET_INFO *cs); void sql_type(String &str) const; char *pack(char *to, const char *from, uint max_length=~(uint) 0); + char *pack_key(char *to, const char *from, uint max_length); const char *unpack(char* to, const char *from); int pack_cmp(const char *a, const char *b, uint key_length); int pack_cmp(const char *b, uint key_length); diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc index 7a445ed8c4d..cb97febea32 100644 --- a/sql/gen_lex_hash.cc +++ b/sql/gen_lex_hash.cc @@ -362,7 +362,7 @@ static int get_options(int argc, char **argv) { int ho_error; - if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) + if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option, 0))) exit(ho_error); if (argc >= 1) diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 1a11f0d3073..815aed13ce3 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -144,6 +144,7 @@ static int ndb_to_mysql_error(const NdbError *err) int ha_ndbcluster::ndb_err(NdbConnection *trans) { + int res; const NdbError err= trans->getNdbError(); if (!err.code) return 0; // Don't log things to DBUG log if no error @@ -161,7 +162,13 @@ int ha_ndbcluster::ndb_err(NdbConnection *trans) default: break; } - DBUG_RETURN(ndb_to_mysql_error(&err)); + res= ndb_to_mysql_error(&err); + DBUG_PRINT("info", ("transformed ndbcluster error %d to mysql error %d", + err.code, res)); + if (res == HA_ERR_FOUND_DUPP_KEY) + dupkey= table->primary_key; + + DBUG_RETURN(res); } @@ -1075,11 +1082,13 @@ int ha_ndbcluster::set_bounds(NdbIndexScanOperation *op, const key_range *key, int bound) { - uint i, tot_len; + uint key_len, key_store_len, tot_len, key_tot_len; byte *key_ptr; KEY* key_info= table->key_info + active_index; KEY_PART_INFO* key_part= key_info->key_part; KEY_PART_INFO* end= key_part+key_info->key_parts; + Field* field; + bool key_nullable, key_null; DBUG_ENTER("set_bounds"); DBUG_PRINT("enter", ("bound: %d", bound)); @@ -1089,29 +1098,37 @@ int ha_ndbcluster::set_bounds(NdbIndexScanOperation *op, // Set bounds using key data tot_len= 0; - key_ptr= (byte *) key->key; + key_ptr= (byte *) key->key; + key_tot_len= key->length; for (; key_part != end; key_part++) { - Field* field= key_part->field; - uint32 field_len= field->pack_length(); - tot_len+= field_len; + field= key_part->field; + key_len= key_part->length; + key_store_len= key_part->store_length; + key_nullable= (bool) key_part->null_bit; + key_null= (field->maybe_null() && *key_ptr); + tot_len+= key_store_len; const char* bounds[]= {"LE", "LT", "GE", "GT", "EQ"}; DBUG_ASSERT(bound >= 0 && bound <= 4); - DBUG_PRINT("info", ("Set Bound%s on %s", + DBUG_PRINT("info", ("Set Bound%s on %s %s %s %s", bounds[bound], - field->field_name)); - DBUG_DUMP("key", (char*)key_ptr, field_len); + field->field_name, + key_nullable ? "NULLABLE" : "", + key_null ? "NULL":"")); + DBUG_PRINT("info", ("Total length %ds", tot_len)); + + DBUG_DUMP("key", (char*) key_ptr, key_store_len); if (op->setBound(field->field_name, bound, - field->is_null() ? 0 : key_ptr, - field->is_null() ? 0 : field_len) != 0) + key_null ? 0 : (key_nullable ? key_ptr + 1 : key_ptr), + key_null ? 0 : key_len) != 0) ERR_RETURN(op->getNdbError()); - key_ptr+= field_len; - - if (tot_len >= key->length) + key_ptr+= key_store_len; + + if (tot_len >= key_tot_len) break; /* @@ -2013,10 +2030,12 @@ int ha_ndbcluster::rnd_init(bool scan) DBUG_ENTER("rnd_init"); DBUG_PRINT("enter", ("scan: %d", scan)); // Check if scan is to be restarted - if (cursor && scan) + if (cursor) + { + if (!scan) + DBUG_RETURN(1); cursor->restart(); - else - DBUG_RETURN(1); + } index_init(table->primary_key); DBUG_RETURN(0); } @@ -2155,7 +2174,10 @@ void ha_ndbcluster::info(uint flag) if (flag & HA_STATUS_VARIABLE) DBUG_PRINT("info", ("HA_STATUS_VARIABLE")); if (flag & HA_STATUS_ERRKEY) + { DBUG_PRINT("info", ("HA_STATUS_ERRKEY")); + errkey= dupkey; + } if (flag & HA_STATUS_AUTO) DBUG_PRINT("info", ("HA_STATUS_AUTO")); DBUG_VOID_RETURN; @@ -2609,7 +2631,7 @@ int ndbcluster_commit(THD *thd, void *ndb_transaction) const NdbOperation *error_op= trans->getNdbErrorOperation(); ERR_PRINT(err); res= ndb_to_mysql_error(&err); - if (res != -1) + if (res != -1) ndbcluster_print_error(res, error_op); } ndb->closeTransaction(trans); @@ -3102,7 +3124,7 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg): m_ndb(NULL), m_table(NULL), m_table_flags(HA_REC_NOT_IN_SEQ | - //HA_NULL_IN_KEY | + HA_NULL_IN_KEY | HA_NOT_EXACT_COUNT | HA_NO_PREFIX_CHAR_KEYS), m_use_write(false), @@ -3114,7 +3136,8 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg): ops_pending(0), skip_auto_increment(true), blobs_buffer(0), - blobs_buffer_size(0) + blobs_buffer_size(0), + dupkey((uint) -1) { int i; diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h index 0d9c28723ce..c49a6078e7a 100644 --- a/sql/ha_ndbcluster.h +++ b/sql/ha_ndbcluster.h @@ -237,6 +237,7 @@ class ha_ndbcluster: public handler // memory for blobs in one tuple char *blobs_buffer; uint32 blobs_buffer_size; + uint dupkey; }; bool ndbcluster_init(void); diff --git a/sql/item.cc b/sql/item.cc index 2c98aad2074..e9ef3b6a763 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -265,8 +265,9 @@ CHARSET_INFO *Item::default_charset() return current_thd->variables.collation_connection; } -bool DTCollation::aggregate(DTCollation &dt) +bool DTCollation::aggregate(DTCollation &dt, bool superset_conversion) { + nagg++; if (!my_charset_same(collation, dt.collation)) { /* @@ -280,15 +281,39 @@ bool DTCollation::aggregate(DTCollation &dt) if (derivation <= dt.derivation) ; // Do nothing else - set(dt); + { + set(dt); + strong= nagg; + } } else if (dt.collation == &my_charset_bin) { if (dt.derivation <= derivation) + { set(dt); + strong= nagg; + } else ; // Do nothing } + else if (superset_conversion) + { + if (derivation < dt.derivation && + collation->state & MY_CS_UNICODE) + ; // Do nothing + else if (dt.derivation < derivation && + dt.collation->state & MY_CS_UNICODE) + { + set(dt); + strong= nagg; + } + else + { + // Cannot convert to superset + set(0, DERIVATION_NONE); + return 1; + } + } else { set(0, DERIVATION_NONE); @@ -302,6 +327,7 @@ bool DTCollation::aggregate(DTCollation &dt) else if (dt.derivation < derivation) { set(dt); + strong= nagg; } else { diff --git a/sql/item.h b/sql/item.h index 6900fa11b90..23c5c844f21 100644 --- a/sql/item.h +++ b/sql/item.h @@ -41,16 +41,22 @@ class DTCollation { public: CHARSET_INFO *collation; enum Derivation derivation; + uint nagg; // Total number of aggregated collations. + uint strong; // Number of the strongest collation. DTCollation() { collation= &my_charset_bin; derivation= DERIVATION_NONE; + nagg= 0; + strong= 0; } DTCollation(CHARSET_INFO *collation_arg, Derivation derivation_arg) { collation= collation_arg; derivation= derivation_arg; + nagg= 0; + strong= 0; } void set(DTCollation &dt) { @@ -66,9 +72,9 @@ public: { collation= collation_arg; } void set(Derivation derivation_arg) { derivation= derivation_arg; } - bool aggregate(DTCollation &dt); - bool set(DTCollation &dt1, DTCollation &dt2) - { set(dt1); return aggregate(dt2); } + bool aggregate(DTCollation &dt, bool superset_conversion= FALSE); + bool set(DTCollation &dt1, DTCollation &dt2, bool superset_conversion= FALSE) + { set(dt1); return aggregate(dt2, superset_conversion); } const char *derivation_name() const { switch(derivation) @@ -239,6 +245,7 @@ public: virtual void top_level_item() {} virtual void set_result_field(Field *field) {} virtual bool is_result_field() { return 0; } + virtual bool is_bool_func() { return 0; } virtual void save_in_result_field(bool no_conversions) {} virtual void no_rows_in_result() {} virtual Item *copy_or_same(THD *thd) { return this; } @@ -268,8 +275,7 @@ public: virtual void bring_value() {} Field *tmp_table_field_from_field_type(TABLE *table); - - /* Used in sql_select.cc:eliminate_not_funcs() */ + virtual Item *neg_transformer(THD *thd) { return NULL; } void delete_self() { diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 5ad4cf92959..4ddb648399a 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -188,25 +188,17 @@ void Item_bool_func2::fix_length_and_dec() { uint strong= 0; uint weak= 0; + DTCollation coll; - if ((args[0]->collation.derivation < args[1]->collation.derivation) && - !my_charset_same(args[0]->collation.collation, - args[1]->collation.collation) && - (args[0]->collation.collation->state & MY_CS_UNICODE)) - { - weak= 1; - } - else if ((args[1]->collation.derivation < args[0]->collation.derivation) && - !my_charset_same(args[0]->collation.collation, - args[1]->collation.collation) && - (args[1]->collation.collation->state & MY_CS_UNICODE)) - { - strong= 1; - } - - if (strong || weak) + if (args[0]->result_type() == STRING_RESULT && + args[1]->result_type() == STRING_RESULT && + !my_charset_same(args[0]->collation.collation, + args[1]->collation.collation) && + !coll.set(args[0]->collation, args[1]->collation, TRUE)) { Item* conv= 0; + strong= coll.strong; + weak= strong ? 0 : 1; if (args[weak]->type() == STRING_ITEM) { String tmp, cstr; @@ -1732,8 +1724,8 @@ bool Item_func_in::nulls_in_row() static int srtcmp_in(CHARSET_INFO *cs, const String *x,const String *y) { return cs->coll->strnncollsp(cs, - (unsigned char *) x->ptr(),x->length(), - (unsigned char *) y->ptr(),y->length()); + (uchar *) x->ptr(),x->length(), + (uchar *) y->ptr(),y->length()); } @@ -1743,12 +1735,58 @@ void Item_func_in::fix_length_and_dec() uint const_itm= 1; agg_cmp_type(&cmp_type, args, arg_count); - if ((cmp_type == STRING_RESULT) && - (agg_arg_collations_for_comparison(cmp_collation, args, arg_count))) - return; - + for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++) const_itm&= arg[0]->const_item(); + + + if (cmp_type == STRING_RESULT) + { + /* + We allow consts character set conversion for + + item IN (const1, const2, const3, ...) + + if item is in a superset for all arguments, + and if it is a stong side according to coercibility rules. + + TODO: add covnersion for non-constant IN values + via creating Item_func_conv_charset(). + */ + + if (agg_arg_collations_for_comparison(cmp_collation, + args, arg_count, TRUE)) + return; + if ((!my_charset_same(args[0]->collation.collation, + cmp_collation.collation) || !const_itm)) + { + if (agg_arg_collations_for_comparison(cmp_collation, + args, arg_count, FALSE)) + return; + } + else + { + /* + Conversion is possible: + All IN arguments are constants. + */ + for (arg= args+1, arg_end= args+arg_count; arg < arg_end; arg++) + { + if (!my_charset_same(cmp_collation.collation, + arg[0]->collation.collation)) + { + Item_string *conv; + String tmp, cstr, *ostr= arg[0]->val_str(&tmp); + cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), + cmp_collation.collation); + conv= new Item_string(cstr.ptr(),cstr.length(), cstr.charset(), + arg[0]->collation.derivation); + conv->str_value.copy(); + arg[0]= conv; + } + } + } + } /* Row item with NULLs inside can return NULL or FALSE => @@ -2030,15 +2068,6 @@ void Item_cond::neg_arguments(THD *thd) { if (!(new_item= new Item_func_not(item))) return; // Fatal OEM error - /* - We can use 0 as tables list because Item_func_not do not use it - on fix_fields and its arguments are already fixed. - - We do not check results of fix_fields, because there are not way - to return error in this functions interface, thd->net.report_error - will be checked on upper level call. - */ - new_item->fix_fields(thd, 0, &new_item); } VOID(li.replace(new_item)); } @@ -2716,9 +2745,6 @@ longlong Item_cond_xor::val_int() IS NULL(a) -> IS NOT NULL(a) IS NOT NULL(a) -> IS NULL(a) - NOTE - This method is used in the eliminate_not_funcs() function. - RETURN New item or NULL if we cannot apply NOT transformation (see Item::neg_transformer()). @@ -2727,25 +2753,13 @@ longlong Item_cond_xor::val_int() Item *Item_func_not::neg_transformer(THD *thd) /* NOT(x) -> x */ { // We should apply negation elimination to the argument of the NOT function - return eliminate_not_funcs(thd, args[0]); + return args[0]; } Item *Item_bool_rowready_func2::neg_transformer(THD *thd) { Item *item= negated_item(); - if (item) - { - /* - We can use 0 as tables list because Item_func* family do not use it - on fix_fields and its arguments are already fixed. - - We do not check results of fix_fields, because there are not way - to return error in this functions interface, thd->net.report_error - will be checked on upper level call. - */ - item->fix_fields(thd, 0, &item); - } return item; } @@ -2754,9 +2768,6 @@ Item *Item_bool_rowready_func2::neg_transformer(THD *thd) Item *Item_func_isnull::neg_transformer(THD *thd) { Item *item= new Item_func_isnotnull(args[0]); - // see comment before fix_fields in Item_bool_rowready_func2::neg_transformer - if (item) - item->fix_fields(thd, 0, &item); return item; } @@ -2765,9 +2776,6 @@ Item *Item_func_isnull::neg_transformer(THD *thd) Item *Item_func_isnotnull::neg_transformer(THD *thd) { Item *item= new Item_func_isnull(args[0]); - // see comment before fix_fields in Item_bool_rowready_func2::neg_transformer - if (item) - item->fix_fields(thd, 0, &item); return item; } @@ -2777,9 +2785,6 @@ Item *Item_cond_and::neg_transformer(THD *thd) /* NOT(a AND b AND ...) -> */ { neg_arguments(thd); Item *item= new Item_cond_or(list); - // see comment before fix_fields in Item_bool_rowready_func2::neg_transformer - if (item) - item->fix_fields(thd, 0, &item); return item; } @@ -2789,9 +2794,6 @@ Item *Item_cond_or::neg_transformer(THD *thd) /* NOT(a OR b OR ...) -> */ { neg_arguments(thd); Item *item= new Item_cond_and(list); - // see comment before fix_fields in Item_bool_rowready_func2::neg_transformer - if (item) - item->fix_fields(thd, 0, &item); return item; } diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 4f2dcb6a412..f1a2b11aaa8 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -89,6 +89,7 @@ public: Item_bool_func(Item *a) :Item_int_func(a) {} Item_bool_func(Item *a,Item *b) :Item_int_func(a,b) {} Item_bool_func(THD *thd, Item_bool_func *item) :Item_int_func(thd, item) {} + bool is_bool_func() { return 1; } void fix_length_and_dec() { decimals=0; max_length=1; } }; @@ -201,6 +202,7 @@ public: bool have_rev_func() const { return rev_functype() != UNKNOWN_FUNC; } void print(String *str) { Item_func::print_op(str); } bool is_null() { return test(args[0]->is_null() || args[1]->is_null()); } + bool is_bool_func() { return 1; } CHARSET_INFO *compare_collation() { return cmp.cmp_collation.collation; } friend class Arg_comparator; @@ -274,7 +276,7 @@ public: enum Functype rev_functype() const { return EQUAL_FUNC; } cond_result eq_cmp_result() const { return COND_TRUE; } const char *func_name() const { return "<=>"; } - Item* neg_transformer(THD *thd) { return 0; } + Item *neg_transformer(THD *thd) { return 0; } }; @@ -748,6 +750,7 @@ class Item_func_in :public Item_int_func enum Functype functype() const { return IN_FUNC; } const char *func_name() const { return " IN "; } bool nulls_in_row(); + bool is_bool_func() { return 1; } CHARSET_INFO *compare_collation() { return cmp_collation.collation; } }; diff --git a/sql/item_func.cc b/sql/item_func.cc index c90a70a6bb6..ef845bb8266 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -75,13 +75,16 @@ static void my_coll_agg_error(Item** args, uint count, const char *fname) } -bool Item_func::agg_arg_collations(DTCollation &c, Item **av, uint count) +bool Item_func::agg_arg_collations(DTCollation &c, Item **av, uint count, + bool allow_superset_conversion) { uint i; + c.nagg= 0; + c.strong= 0; c.set(av[0]->collation); for (i= 1; i < count; i++) { - if (c.aggregate(av[i]->collation)) + if (c.aggregate(av[i]->collation, allow_superset_conversion)) { my_coll_agg_error(av, count, func_name()); return TRUE; @@ -92,9 +95,10 @@ bool Item_func::agg_arg_collations(DTCollation &c, Item **av, uint count) bool Item_func::agg_arg_collations_for_comparison(DTCollation &c, - Item **av, uint count) + Item **av, uint count, + bool allow_superset_conv) { - if (agg_arg_collations(c, av, count)) + if (agg_arg_collations(c, av, count, allow_superset_conv)) return TRUE; if (c.derivation == DERIVATION_NONE) @@ -1435,30 +1439,43 @@ longlong Item_func_find_in_set::val_int() int diff; if ((diff=buffer->length() - find->length()) >= 0) { - const char *f_pos=find->ptr(); - const char *f_end=f_pos+find->length(); - const char *str=buffer->ptr(); - const char *end=str+diff+1; - const char *real_end=str+buffer->length(); - uint position=1; - do + my_wc_t wc; + CHARSET_INFO *cs= cmp_collation.collation; + const char *str_begin= buffer->ptr(); + const char *str_end= buffer->ptr(); + const char *real_end= str_end+buffer->length(); + const uchar *find_str= (const uchar *) find->ptr(); + uint find_str_len= find->length(); + int position= 0; + while (1) { - const char *pos= f_pos; - while (pos != f_end) + int symbol_len; + if ((symbol_len= cs->cset->mb_wc(cs, &wc, (uchar*) str_end, + (uchar*) real_end)) > 0) { - if (my_toupper(cmp_collation.collation,*str) != - my_toupper(cmp_collation.collation,*pos)) - goto not_found; - str++; - pos++; + const char *substr_end= str_end + symbol_len; + bool is_last_item= (substr_end == real_end); + if (wc == (my_wc_t) separator || is_last_item) + { + position++; + if (is_last_item) + str_end= substr_end; + if (!my_strnncoll(cs, (const uchar *) str_begin, + str_end - str_begin, + find_str, find_str_len)) + return (longlong) position; + else + str_begin= substr_end; + } + str_end= substr_end; } - if (str == real_end || str[0] == separator) - return (longlong) position; - not_found: - while (str < end && str[0] != separator) - str++; - position++; - } while (++str <= end); + else if (str_end - str_begin == 0 && + find_str_len == 0 && + wc == (my_wc_t) separator) + return (longlong) ++position; + else + return (longlong) 0; + } } return 0; } diff --git a/sql/item_func.h b/sql/item_func.h index eaa0a044fd6..d45f7244e55 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -140,8 +140,11 @@ public: Field *tmp_table_field(TABLE *t_arg); Item *get_tmp_table_item(THD *thd); - bool agg_arg_collations(DTCollation &c, Item **items, uint nitems); - bool agg_arg_collations_for_comparison(DTCollation &c, Item **items, uint nitems); + bool agg_arg_collations(DTCollation &c, Item **items, uint nitems, + bool allow_superset_conversion= FALSE); + bool agg_arg_collations_for_comparison(DTCollation &c, + Item **items, uint nitems, + bool allow_superset_comversion= FALSE); bool walk(Item_processor processor, byte *arg); }; diff --git a/sql/item_row.cc b/sql/item_row.cc index c7e4bc0acf4..f6623e80734 100644 --- a/sql/item_row.cc +++ b/sql/item_row.cc @@ -66,7 +66,8 @@ bool Item_row::fix_fields(THD *thd, TABLE_LIST *tabl, Item **ref) // we can't assign 'item' before, because fix_fields() can change arg Item *item= *arg; used_tables_cache |= item->used_tables(); - if (const_item_cache&= item->const_item() && !with_null) + const_item_cache&= item->const_item() && !with_null; + if (const_item_cache) { if (item->cols() > 1) with_null|= item->null_inside(); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index ecfeff02cac..fac73a1a759 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -39,7 +39,8 @@ C_MODE_END String my_empty_string("",default_charset_info); -static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fname) +static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, + const char *fname) { my_error(ER_CANT_AGGREGATE_2COLLATIONS,MYF(0), c1.collation->name,c1.derivation_name(), @@ -62,8 +63,9 @@ double Item_str_func::val() { DBUG_ASSERT(fixed == 1); int err; - String *res; - res=val_str(&str_value); + char buff[64]; + String *res, tmp(buff,sizeof(buff), &my_charset_bin); + res= val_str(&tmp); return res ? my_strntod(res->charset(), (char*) res->ptr(),res->length(), NULL, &err) : 0.0; } @@ -72,8 +74,9 @@ longlong Item_str_func::val_int() { DBUG_ASSERT(fixed == 1); int err; - String *res; - res=val_str(&str_value); + char buff[22]; + String *res, tmp(buff,sizeof(buff), &my_charset_bin); + res= val_str(&tmp); return (res ? my_strntoll(res->charset(), res->ptr(), res->length(), 10, NULL, &err) : @@ -986,10 +989,7 @@ String *Item_func_left::val_str(String *str) if (res->length() <= (uint) length || res->length() <= (char_pos= res->charpos(length))) return res; - if (&str_value == res) - str_value.length(char_pos); - else - str_value.set(*res, 0, char_pos); + str_value.set(*res, 0, char_pos); return &str_value; } @@ -2200,7 +2200,8 @@ String *Item_func_conv_charset::val_str(String *str) null_value=1; return 0; } - null_value= str_value.copy(arg->ptr(),arg->length(),arg->charset(),conv_charset); + null_value= str_value.copy(arg->ptr(),arg->length(),arg->charset(), + conv_charset); return null_value ? 0 : &str_value; } diff --git a/sql/item_sum.cc b/sql/item_sum.cc index cbb4cd41046..79c1be57625 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1945,13 +1945,12 @@ void Item_func_group_concat::reset_field() bool Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { + uint i; /* for loop variable */ DBUG_ASSERT(fixed == 0); if (save_args_for_prepared_statement(thd)) return 1; - uint i; /* for loop variable */ - if (!thd->allow_sum_func) { my_error(ER_INVALID_GROUP_FUNC_USE,MYF(0)); @@ -1971,7 +1970,7 @@ Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) if (args[i]->fix_fields(thd, tables, args + i) || args[i]->check_cols(1)) return 1; if (i < arg_count_field) - maybe_null |= args[i]->maybe_null; + maybe_null|= args[i]->maybe_null; } result_field= 0; @@ -2048,7 +2047,8 @@ bool Item_func_group_concat::setup(THD *thd) of a record instead of a pointer of one. */ if (!(table=create_tmp_table(thd, tmp_table_param, all_fields, - (ORDER*) 0, 0, TRUE,select_lex->options | thd->options, + (ORDER*) 0, 0, TRUE, + select_lex->options | thd->options, HA_POS_ERROR,(char *) ""))) DBUG_RETURN(1); table->file->extra(HA_EXTRA_NO_ROWS); @@ -2157,7 +2157,7 @@ void Item_func_group_concat::print(String *str) (*order[i]->item)->print(str); } } - str->append(" seperator \'", 12); + str->append(" separator \'", 12); str->append(*separator); str->append("\')", 2); } diff --git a/sql/log.cc b/sql/log.cc index 240965fdca3..f4ec5d9c731 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1,15 +1,15 @@ /* Copyright (C) 2000-2003 MySQL AB - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -31,12 +31,51 @@ #include <stdarg.h> #include <m_ctype.h> // For test_if_number +#ifdef __NT__ +#include "message.h" +#endif + MYSQL_LOG mysql_log,mysql_update_log,mysql_slow_log,mysql_bin_log; ulong sync_binlog_counter= 0; static bool test_if_number(const char *str, long *res, bool allow_wildcards); +#ifdef __NT__ +static int eventSource = 0; +void setupWindowsEventSource() +{ + if (eventSource) return; + + eventSource = 1; + HKEY hRegKey = NULL; + DWORD dwError = 0; + TCHAR szPath[ MAX_PATH ]; + + // Create the event source registry key + dwError = RegCreateKey(HKEY_LOCAL_MACHINE, + "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\MySQL", + &hRegKey); + + // Name of the PE module that contains the message resource + GetModuleFileName(NULL, szPath, MAX_PATH); + + // Register EventMessageFile + dwError = RegSetValueEx(hRegKey, "EventMessageFile", 0, REG_EXPAND_SZ, + (PBYTE) szPath, strlen(szPath)+1); + + + // Register supported event types + DWORD dwTypes = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE; + dwError = RegSetValueEx(hRegKey, "TypesSupported", 0, REG_DWORD, + (LPBYTE) &dwTypes, sizeof dwTypes); + + RegCloseKey(hRegKey); +} + +#endif + + /**************************************************************************** ** Find a uniq filename for 'filename.#'. ** Set # to a number as low as possible @@ -230,7 +269,7 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg, "started with:\nTcp port: %d Unix socket: %s\n", my_progname,server_version,mysqld_port,mysqld_unix_port #endif - ); + ); end=strnmov(buff+len,"Time Id Command Argument\n", sizeof(buff)-len); if (my_b_write(&log_file, (byte*) buff,(uint) (end-buff)) || @@ -1940,41 +1979,33 @@ static bool test_if_number(register const char *str, } /* test_if_number */ -void sql_print_error(const char *format,...) +void print_buffer_to_file(enum loglevel level, const char *buffer) { - va_list args; time_t skr; struct tm tm_tmp; struct tm *start; - va_start(args,format); - DBUG_ENTER("sql_print_error"); + + DBUG_ENTER("print_buffer_to_log"); VOID(pthread_mutex_lock(&LOCK_error_log)); -#ifndef DBUG_OFF - { - char buff[1024]; - my_vsnprintf(buff,sizeof(buff)-1,format,args); - DBUG_PRINT("error",("%s",buff)); - va_end(args); - va_start(args,format); - } -#endif + skr=time(NULL); - localtime_r(&skr,&tm_tmp); + localtime_r(&skr, &tm_tmp); start=&tm_tmp; - fprintf(stderr,"%02d%02d%02d %2d:%02d:%02d ", - start->tm_year % 100, - start->tm_mon+1, + fprintf(stderr, "%02d%02d%02d %2d:%02d:%02d [%s] %s\n", + start->tm_year % 100, + start->tm_mon+1, start->tm_mday, start->tm_hour, start->tm_min, - start->tm_sec); - (void) vfprintf(stderr,format,args); - (void) fputc('\n',stderr); + start->tm_sec, + level == ERROR_LEVEL ? "ERROR" : level == WARNING_LEVEL ? "WARNING" : "INFORMATION", + buffer); + fflush(stderr); - va_end(args); VOID(pthread_mutex_unlock(&LOCK_error_log)); + DBUG_VOID_RETURN; } @@ -2171,3 +2202,122 @@ void MYSQL_LOG::report_pos_in_innodb() #endif DBUG_VOID_RETURN; } + +#ifdef __NT__ +void print_buffer_to_nt_eventlog(enum loglevel level, char *buff, int buffLen) +{ + HANDLE event; + char *buffptr; + LPCSTR *buffmsgptr; + + DBUG_ENTER("print_buffer_to_nt_eventlog"); + + buffptr = buff; + if (strlen(buff) > (uint)(buffLen-4)) + { + char *newBuff = new char[ strlen(buff) + 4 ]; + strcpy(newBuff, buff); + buffptr = newBuff; + } + strcat(buffptr, "\r\n\r\n"); + buffmsgptr = (LPCSTR*)&buffptr; + + setupWindowsEventSource(); + if (event = RegisterEventSource(NULL,"MySQL")) + { + switch (level){ + case ERROR_LEVEL: + ReportEvent(event, EVENTLOG_ERROR_TYPE, 0, MSG_DEFAULT, NULL, 1, 0, buffmsgptr, NULL); + break; + case WARNING_LEVEL: + ReportEvent(event, EVENTLOG_WARNING_TYPE, 0, MSG_DEFAULT, NULL, 1, 0, buffmsgptr, NULL); + break; + case INFORMATION_LEVEL: + ReportEvent(event, EVENTLOG_INFORMATION_TYPE, 0, MSG_DEFAULT, NULL, 1, 0, buffmsgptr, NULL); + break; + } + DeregisterEventSource(event); + } + + // if we created a string buffer, then delete it + if (buffptr != buff) + delete[] buffptr; + + DBUG_VOID_RETURN; +} +#endif + +/* + Prints a printf style message to the error log and, under NT, to the Windows event log. + + SYNOPSIS + vprint_msg_to_log() + event_type Type of event to write (Error, Warning, or Info) + format Printf style format of message + args va_list list of arguments for the message + + NOTE + + IMPLEMENTATION + This function prints the message into a buffer and then sends that buffer to other + functions to write that message to other logging sources. + + RETURN VALUES + void +*/ +void vprint_msg_to_log(enum loglevel level, const char *format, va_list args) +{ + char buff[1024]; + DBUG_ENTER("vprint_msg_to_log"); + + my_vsnprintf(buff, sizeof(buff)-5, format, args); + + print_buffer_to_file(level, buff); + +#ifndef DBUG_OFF + DBUG_PRINT("error",("%s",buff)); +#endif + +#ifdef __NT__ + print_buffer_to_nt_eventlog(level, buff, sizeof(buff)); +#endif + + DBUG_VOID_RETURN; +} + + +void sql_print_error(const char *format, ...) +{ + DBUG_ENTER("sql_print_error"); + + va_list args; + va_start(args, format); + vprint_msg_to_log(ERROR_LEVEL, format, args); + va_end(args); + + DBUG_VOID_RETURN; +} + +void sql_print_warning(const char *format, ...) +{ + DBUG_ENTER("sql_print_warning"); + + va_list args; + va_start(args, format); + vprint_msg_to_log(WARNING_LEVEL, format, args); + va_end(args); + + DBUG_VOID_RETURN; +} + +void sql_print_information(const char *format, ...) +{ + DBUG_ENTER("sql_print_information"); + + va_list args; + va_start(args, format); + vprint_msg_to_log(INFORMATION_LEVEL, format, args); + va_end(args); + + DBUG_VOID_RETURN; +} diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 2037cf48616..b1b184eb9eb 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -297,7 +297,8 @@ enum enum_parsing_place { NO_MATTER, IN_HAVING, - SELECT_LIST + SELECT_LIST, + IN_WHERE }; struct st_table; @@ -376,6 +377,7 @@ int delete_precheck(THD *thd, TABLE_LIST *tables); int insert_precheck(THD *thd, TABLE_LIST *tables, bool update); int create_table_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *create_table); +Item *negate_expression(THD *thd, Item *expr); #include "sql_class.h" #include "opt_range.h" @@ -576,7 +578,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table,List<Item> &fields, int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds); int mysql_delete(THD *thd, TABLE_LIST *table, COND *conds, SQL_LIST *order, ha_rows rows, ulong options); -int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok=0); +int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok); TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update); TABLE *open_table(THD *thd,const char *db,const char *table,const char *alias, bool *refresh); @@ -782,8 +784,14 @@ int key_cmp(KEY_PART_INFO *key_part, const byte *key, uint key_length); bool init_errmessage(void); void sql_perror(const char *message); -void sql_print_error(const char *format,...) - __attribute__ ((format (printf, 1, 2))); + +void vprint_msg_to_log(enum loglevel level, const char *format, va_list args); +void sql_print_error(const char *format, ...); +void sql_print_warning(const char *format, ...); +void sql_print_information(const char *format, ...); + + + bool fn_format_relative_to_data_home(my_string to, const char *name, const char *dir, const char *extension); bool open_log(MYSQL_LOG *log, const char *hostname, diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 9b40768f0da..e7638f13526 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -762,7 +762,7 @@ void kill_mysql(void) abort_loop=1; if (pthread_create(&tmp,&connection_attrib, kill_server_thread, (void*) 0)) - sql_print_error("Error: Can't create thread to kill server"); + sql_print_error("Can't create thread to kill server"); } #endif DBUG_VOID_RETURN; @@ -791,7 +791,7 @@ static void __cdecl kill_server(int sig_ptr) abort_loop=1; // This should be set signal(sig,SIG_IGN); if (sig == MYSQL_KILL_SIGNAL || sig == 0) - sql_print_error(ER(ER_NORMAL_SHUTDOWN),my_progname); + sql_print_information(ER(ER_NORMAL_SHUTDOWN),my_progname); else sql_print_error(ER(ER_GOT_SIGNAL),my_progname,sig); /* purecov: inspected */ @@ -806,7 +806,7 @@ static void __cdecl kill_server(int sig_ptr) #ifdef __NETWARE__ pthread_join(select_thread, NULL); // wait for main thread #endif /* __NETWARE__ */ - + pthread_exit(0); /* purecov: deadcode */ #endif /* EMBEDDED_LIBRARY */ @@ -834,7 +834,7 @@ extern "C" sig_handler print_signal_warning(int sig) if (!DBUG_IN_USE) { if (global_system_variables.log_warnings) - sql_print_error("Warning: Got signal %d from thread %d", + sql_print_warning("Got signal %d from thread %d", sig,my_thread_id()); } #ifdef DONT_REMEMBER_SIGNAL @@ -961,7 +961,7 @@ void clean_up(bool print_message) #endif if (print_message && errmesg) - sql_print_error(ER(ER_SHUTDOWN_COMPLETE),my_progname); + sql_print_information(ER(ER_SHUTDOWN_COMPLETE),my_progname); #if !defined(__WIN__) && !defined(EMBEDDED_LIBRARY) if (!opt_bootstrap) (void) my_delete(pidfile_name,MYF(0)); // This may not always exist @@ -1062,8 +1062,8 @@ static void set_user(const char *user) struct passwd *user_info= getpwnam(user); if ((!user_info || user_id != user_info->pw_uid) && global_system_variables.log_warnings) - fprintf(stderr, - "Warning: One can only use the --user switch if running as root\n"); + sql_print_warning( + "One can only use the --user switch if running as root\n"); } return; } @@ -1183,7 +1183,7 @@ static void server_init(void) if (listen(ip_sock,(int) back_log) < 0) { sql_perror("Can't start server: listen() on TCP/IP port"); - sql_print_error("Error: listen() on TCP/IP failed with error %d", + sql_print_error("listen() on TCP/IP failed with error %d", socket_errno); unireg_abort(1); } @@ -1278,7 +1278,7 @@ static void server_init(void) (void) chmod(mysqld_unix_port,S_IFSOCK); /* Fix solaris 2.6 bug */ #endif if (listen(unix_sock,(int) back_log) < 0) - sql_print_error("Warning: listen() on Unix socket failed with error %d", + sql_print_warning("listen() on Unix socket failed with error %d", socket_errno); } #endif @@ -1870,7 +1870,7 @@ static void init_signals(void) struct rlimit rl; rl.rlim_cur = rl.rlim_max = RLIM_INFINITY; if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings) - sql_print_error("Warning: setrlimit could not change the size of core files to 'infinity'; We may not be able to generate a core file on signals"); + sql_print_warning("setrlimit could not change the size of core files to 'infinity'; We may not be able to generate a core file on signals"); } #endif (void) sigemptyset(&set); @@ -2024,7 +2024,7 @@ extern "C" void *signal_hand(void *arg __attribute__((unused))) case SIGQUIT: case SIGKILL: #ifdef EXTRA_DEBUG - sql_print_error("Got signal %d to shutdown mysqld",sig); + sql_print_information("Got signal %d to shutdown mysqld",sig); #endif DBUG_PRINT("info",("Got signal: %d abort_loop: %d",sig,abort_loop)); if (!abort_loop) @@ -2036,7 +2036,7 @@ extern "C" void *signal_hand(void *arg __attribute__((unused))) my_pthread_attr_setprio(&connection_attrib,INTERRUPT_PRIOR); if (pthread_create(&tmp,&connection_attrib, kill_server_thread, (void*) sig)) - sql_print_error("Error: Can't create thread to kill server"); + sql_print_error("Can't create thread to kill server"); #else kill_server((void*) sig); // MIT THREAD has a alarm thread #endif @@ -2060,7 +2060,7 @@ extern "C" void *signal_hand(void *arg __attribute__((unused))) #endif default: #ifdef EXTRA_DEBUG - sql_print_error("Warning: Got signal: %d error: %d",sig,error); /* purecov: tested */ + sql_print_warning("Got signal: %d error: %d",sig,error); /* purecov: tested */ #endif break; /* purecov: tested */ } @@ -2339,11 +2339,11 @@ static int init_common_variables(const char *conf_file_name, int argc, ("Changed limits: max_open_files: %u max_connections: %ld table_cache: %ld", files, max_connections, table_cache_size)); if (global_system_variables.log_warnings) - sql_print_error("Warning: Changed limits: max_open_files: %u max_connections: %ld table_cache: %ld", + sql_print_warning("Changed limits: max_open_files: %u max_connections: %ld table_cache: %ld", files, max_connections, table_cache_size); } else if (global_system_variables.log_warnings) - sql_print_error("Warning: Could not increase number of max_open_files to more than %u (request: %u)", files, wanted_files); + sql_print_warning("Could not increase number of max_open_files to more than %u (request: %u)", files, wanted_files); } open_files_limit= files; } @@ -2523,8 +2523,8 @@ static int init_server_components() } else if (opt_log_slave_updates) { - sql_print_error("\ -Warning: you need to use --log-bin to make --log-slave-updates work. \ + sql_print_warning("\ +you need to use --log-bin to make --log-slave-updates work. \ Now disabling --log-slave-updates."); } @@ -2532,7 +2532,7 @@ Now disabling --log-slave-updates."); if (opt_log_slave_updates && replicate_same_server_id) { sql_print_error("\ -Error: using --replicate-same-server-id in conjunction with \ +using --replicate-same-server-id in conjunction with \ --log-slave-updates is impossible, it would lead to infinite loops in this \ server."); unireg_abort(1); @@ -2561,12 +2561,12 @@ server."); if (opt_innodb_safe_binlog) { if (have_innodb != SHOW_OPTION_YES) - sql_print_error("Warning: --innodb-safe-binlog is meaningful only if " + sql_print_warning("--innodb-safe-binlog is meaningful only if " "the InnoDB storage engine is enabled in the server."); #ifdef HAVE_INNOBASE_DB if (innobase_flush_log_at_trx_commit != 1) { - sql_print_error("Warning: --innodb-safe-binlog is meaningful only if " + sql_print_warning("--innodb-safe-binlog is meaningful only if " "innodb_flush_log_at_trx_commit is 1; now setting it " "to 1."); innobase_flush_log_at_trx_commit= 1; @@ -2578,14 +2578,14 @@ server."); good (especially "littlesync", and on Windows... see srv/srv0start.c). */ - sql_print_error("Warning: --innodb-safe-binlog requires that " + sql_print_warning("--innodb-safe-binlog requires that " "the innodb_flush_method actually synchronizes the " "InnoDB log to disk; it is your responsibility " "to verify that the method you chose does it."); } if (sync_binlog_period != 1) { - sql_print_error("Warning: --innodb-safe-binlog is meaningful only if " + sql_print_warning("--innodb-safe-binlog is meaningful only if " "the global sync_binlog variable is 1; now setting it " "to 1."); sync_binlog_period= 1; @@ -2624,7 +2624,7 @@ server."); if (mlockall(MCL_CURRENT)) { if (global_system_variables.log_warnings) - sql_print_error("Warning: Failed to lock memory. Errno: %d\n",errno); + sql_print_warning("Failed to lock memory. Errno: %d\n",errno); locked_in_memory= 0; } } @@ -2650,7 +2650,7 @@ static void create_maintenance_thread() { pthread_t hThread; if (pthread_create(&hThread,&connection_attrib,handle_manager,0)) - sql_print_error("Warning: Can't create thread to manage maintenance"); + sql_print_warning("Can't create thread to manage maintenance"); } } @@ -2662,7 +2662,7 @@ static void create_shutdown_thread() hEventShutdown=CreateEvent(0, FALSE, FALSE, shutdown_event_name); pthread_t hThread; if (pthread_create(&hThread,&connection_attrib,handle_shutdown,0)) - sql_print_error("Warning: Can't create thread to handle shutdown requests"); + sql_print_warning("Can't create thread to handle shutdown requests"); // On "Stop Service" we have to do regular shutdown Service.SetShutdownEvent(hEventShutdown); @@ -2671,7 +2671,7 @@ static void create_shutdown_thread() pthread_cond_init(&eventShutdown, NULL); pthread_t hThread; if (pthread_create(&hThread,&connection_attrib,handle_shutdown,0)) - sql_print_error("Warning: Can't create thread to handle shutdown requests"); + sql_print_warning("Can't create thread to handle shutdown requests"); #endif #endif // EMBEDDED_LIBRARY } @@ -2687,7 +2687,7 @@ static void handle_connections_methods() (!have_tcpip || opt_disable_networking) && !opt_enable_shared_memory) { - sql_print_error("TCP/IP,--shared-memory or --named-pipe should be configured on NT OS"); + sql_print_error("TCP/IP, --shared-memory, or --named-pipe should be configured on NT OS"); unireg_abort(1); // Will not return } #endif @@ -2702,7 +2702,7 @@ static void handle_connections_methods() if (pthread_create(&hThread,&connection_attrib, handle_connections_namedpipes, 0)) { - sql_print_error("Warning: Can't create thread to handle named pipes"); + sql_print_warning("Can't create thread to handle named pipes"); handler_count--; } } @@ -2713,7 +2713,7 @@ static void handle_connections_methods() if (pthread_create(&hThread,&connection_attrib, handle_connections_sockets, 0)) { - sql_print_error("Warning: Can't create thread to handle TCP/IP"); + sql_print_warning("Can't create thread to handle TCP/IP"); handler_count--; } } @@ -2724,7 +2724,7 @@ static void handle_connections_methods() if (pthread_create(&hThread,&connection_attrib, handle_connections_shared_memory, 0)) { - sql_print_error("Warning: Can't create thread to handle shared memory"); + sql_print_warning("Can't create thread to handle shared memory"); handler_count--; } } @@ -2784,7 +2784,7 @@ int main(int argc, char **argv) if (stack_size && stack_size < thread_stack) { if (global_system_variables.log_warnings) - sql_print_error("Warning: Asked for %ld thread stack, but got %ld", + sql_print_warning("Asked for %ld thread stack, but got %ld", thread_stack, stack_size); thread_stack= stack_size; } @@ -2807,8 +2807,8 @@ int main(int argc, char **argv) if (lower_case_table_names_used) { if (global_system_variables.log_warnings) - sql_print_error("\ -Warning: You have forced lower_case_table_names to 0 through a command-line \ + sql_print_warning("\ +You have forced lower_case_table_names to 0 through a command-line \ option, even though your file system '%s' is case insensitive. This means \ that you can corrupt a MyISAM table by accessing it with different cases. \ You should consider changing lower_case_table_names to 1 or 2", @@ -2817,7 +2817,7 @@ You should consider changing lower_case_table_names to 1 or 2", else { if (global_system_variables.log_warnings) - sql_print_error("Warning: Setting lower_case_table_names=2 because file system for %s is case insensitive", mysql_real_data_home); + sql_print_warning("Setting lower_case_table_names=2 because file system for %s is case insensitive", mysql_real_data_home); lower_case_table_names= 2; } } @@ -2850,14 +2850,14 @@ You should consider changing lower_case_table_names to 1 or 2", #ifdef EXTRA_DEBUG switch (server_id) { case 1: - sql_print_error("\ -Warning: You have enabled the binary log, but you haven't set server-id to \ + sql_print_warning("\ +You have enabled the binary log, but you haven't set server-id to \ a non-zero value: we force server id to 1; updates will be logged to the \ binary log, but connections from slaves will not be accepted."); break; case 2: - sql_print_error("\ -Warning: You should set server-id to a non-0 value if master_host is set; \ + sql_print_warning("\ +You should set server-id to a non-0 value if master_host is set; \ we force server id to 2, but this MySQL server will not act as a slave."); break; } @@ -3197,7 +3197,7 @@ static int bootstrap(FILE *file) if (pthread_create(&thd->real_id,&connection_attrib,handle_bootstrap, (void*) thd)) { - sql_print_error("Warning: Can't create thread to handle bootstrap"); + sql_print_warning("Can't create thread to handle bootstrap"); DBUG_RETURN(-1); } /* Wait for thread to die */ @@ -4241,7 +4241,7 @@ Disable with --skip-isam.", OPT_ARG, 0, 0, 0, 0, 0, 0}, {"log-warnings", 'W', "Log some non-critical warnings to the error log file. Use this option twice or --log-warnings=2 if you also want 'Aborted connections' warnings.", (gptr*) &global_system_variables.log_warnings, - (gptr*) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG, 1, 0, 0, + (gptr*) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG, 1, 0, ~0L, 0, 0, 0}, {"low-priority-updates", OPT_LOW_PRIORITY_UPDATES, "INSERT/DELETE/UPDATE has lower priority than selects.", @@ -4551,7 +4551,7 @@ replicating a LOAD DATA INFILE command.", NO_ARG, 0, 0, 0, 0, 0, 0}, {"warnings", 'W', "Deprecated; use --log-warnings instead.", (gptr*) &global_system_variables.log_warnings, - (gptr*) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG, 1, 0, 0, + (gptr*) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG, 1, 0, ~0L, 0, 0, 0}, { "back_log", OPT_BACK_LOG, "The number of outstanding connection requests MySQL can have. This comes into play when the main MySQL thread gets very many connection requests in a very short time.", @@ -5606,7 +5606,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), if (!mysqld_user || !strcmp(mysqld_user, argument)) mysqld_user= argument; else - fprintf(stderr, "Warning: Ignoring user change to '%s' because the user was set to '%s' earlier on the command line\n", argument, mysqld_user); + sql_print_warning("Ignoring user change to '%s' because the user was set to '%s' earlier on the command line\n", argument, mysqld_user); break; case 'L': strmake(language, argument, sizeof(language)-1); @@ -6078,7 +6078,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), } return 0; } - + /* Initiates DEBUG - but no debugging here ! */ extern "C" gptr * mysql_getopt_value(const char *keyname, uint key_length, @@ -6108,6 +6108,13 @@ mysql_getopt_value(const char *keyname, uint key_length, return option->value; } +void option_error_reporter( enum loglevel level, const char *format, ... ) +{ + va_list args; + va_start( args, format ); + vprint_msg_to_log( level, format, args ); + va_end( args ); +} static void get_options(int argc,char **argv) { @@ -6116,7 +6123,7 @@ static void get_options(int argc,char **argv) my_getopt_register_get_addr(mysql_getopt_value); strmake(def_ft_boolean_syntax, ft_boolean_syntax, sizeof(ft_boolean_syntax)-1); - if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)) != 0) + if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option, option_error_reporter))) exit(ho_error); if (argc > 0) { @@ -6384,7 +6391,7 @@ static int test_if_case_insensitive(const char *dir_name) (void) my_delete(buff2, MYF(0)); if ((file= my_create(buff, 0666, O_RDWR, MYF(0))) < 0) { - sql_print_error("Warning: Can't create test file %s", buff); + sql_print_warning("Can't create test file %s", buff); DBUG_RETURN(-1); } my_close(file, MYF(0)); diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 40e3ffebe56..f11ed31950a 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1302,14 +1302,14 @@ tree_and(PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2) if (*key2 && !(*key2)->simple_key()) flag|=CLONE_KEY2_MAYBE; *key1=key_and(*key1,*key2,flag); - if ((*key1)->type == SEL_ARG::IMPOSSIBLE) + if (*key1 && (*key1)->type == SEL_ARG::IMPOSSIBLE) { tree1->type= SEL_TREE::IMPOSSIBLE; - break; - } #ifdef EXTRA_DEBUG - (*key1)->test_use_count(*key1); + (*key1)->test_use_count(*key1); #endif + break; + } } } DBUG_RETURN(tree1); @@ -1456,6 +1456,13 @@ key_and(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag) return key1; } + if ((key1->min_flag | key2->min_flag) & GEOM_FLAG) + { + key1->free_tree(); + key2->free_tree(); + return 0; // Can't optimize this + } + key1->use_count--; key2->use_count--; SEL_ARG *e1=key1->first(), *e2=key2->first(), *new_tree=0; @@ -1538,7 +1545,8 @@ key_or(SEL_ARG *key1,SEL_ARG *key2) key1->use_count--; key2->use_count--; - if (key1->part != key2->part) + if (key1->part != key2->part || + (key1->min_flag | key2->min_flag) & GEOM_FLAG) { key1->free_tree(); key2->free_tree(); diff --git a/sql/protocol.cc b/sql/protocol.cc index 7c4b09ac3e3..da2a285fffc 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -200,7 +200,7 @@ net_printf(THD *thd, uint errcode, ...) 2+SQLSTATE_LENGTH+1 : 2) : 0); #ifndef EMBEDDED_LIBRARY text_pos=(char*) net->buff + head_length + offset + 1; - length=(char*)net->buff_end-text_pos; + length= (uint) ((char*)net->buff_end - text_pos); #else length=sizeof(text_pos)-1; #endif diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index ee75210d4fe..047db57c86c 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -314,3 +314,4 @@ character-set=latin2 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 408f86b0445..168cddec81d 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -308,3 +308,4 @@ character-set=latin1 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 95af6aaa01f..32d8a2ba168 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -316,3 +316,4 @@ character-set=latin1 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 5ad23b92a5a..3303cd0666a 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -305,3 +305,4 @@ character-set=latin1 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 36e0b8409e9..cdfb5e9d170 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -310,3 +310,4 @@ character-set=latin7 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 3bd6835908e..72c2381dc70 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -305,3 +305,4 @@ character-set=latin1 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index bf5a36a887a..0818895dacb 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -317,3 +317,4 @@ character-set=latin1 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 9703bad11a1..4ee82d91566 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -305,3 +305,4 @@ character-set=greek "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 1f71086ff69..6be3add430e 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -307,3 +307,4 @@ character-set=latin2 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 21158fcb567..fd2d33c5e2e 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -305,3 +305,4 @@ character-set=latin1 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 3a6dd644d8b..7ebce1cf662 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -307,3 +307,4 @@ character-set=ujis "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 356f0a63540..f389feb7e40 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -305,3 +305,4 @@ character-set=euckr "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index b5564cb264e..088adb43c96 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -307,3 +307,4 @@ character-set=latin1 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index fcea45b06ac..0e92867a201 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -307,3 +307,4 @@ character-set=latin1 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 2a18e4de020..c61db27cd58 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -309,3 +309,4 @@ character-set=latin2 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 6ba0fbca014..66b3d9a516b 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -306,3 +306,4 @@ character-set=latin1 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 50b2b36c959..43c669cb4f9 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -309,3 +309,4 @@ character-set=latin2 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index d8641d1dd14..311cfd35cb5 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -307,3 +307,4 @@ character-set=koi8r "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index a8cde5a56b1..45b56c8269c 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -311,3 +311,4 @@ character-set=cp1250 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 42ef7f62076..e45858805db 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -313,3 +313,4 @@ character-set=latin2 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index b82712be350..9a3296cb405 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -307,3 +307,4 @@ character-set=latin1 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 78620b28a2f..85271f81b2b 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -305,3 +305,4 @@ character-set=latin1 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 6d07eb1a656..87789018185 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -310,3 +310,4 @@ character-set=koi8u "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index f60897bf62b..9c6853187f6 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -251,9 +251,9 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) { global_system_variables.old_passwords= 1; pthread_mutex_unlock(&LOCK_global_system_variables); - sql_print_error("mysql.user table is not updated to new password format; " - "Disabling new password usage until " - "mysql_fix_privilege_tables is run"); + sql_print_warning("mysql.user table is not updated to new password format; " + "Disabling new password usage until " + "mysql_fix_privilege_tables is run"); } thd->variables.old_passwords= 1; } @@ -551,21 +551,19 @@ static ulong get_sort(uint count,...) uint chars= 0; uint wild_pos= 0; /* first wildcard position */ - if (start= str) + if ((start= str)) { for (; *str ; str++) { if (*str == wild_many || *str == wild_one || *str == wild_prefix) { - wild_pos= str - start + 1; + wild_pos= (uint) (str - start) + 1; break; } - else - chars++; + chars= 128; // Marker that chars existed } } - sort= (sort << 8) + (wild_pos ? (wild_pos > 127 ? 127 : wild_pos) : - (chars ? 128 : 0)); + sort= (sort << 8) + (wild_pos ? min(wild_pos, 127) : chars); } va_end(args); return sort; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index dede280325d..ea7b4521247 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2441,9 +2441,20 @@ bool insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name, const char *table_name, List_iterator<Item> *it) { + char name_buff[NAME_LEN+1]; uint found; DBUG_ENTER("insert_fields"); + + if (db_name && lower_case_table_names) + { + /* convert database to lower case for comparison */ + strmake(name_buff, db_name, sizeof(name_buff)-1); + my_casedn_str(system_charset_info,name_buff); + db_name = name_buff; + } + + found=0; for (; tables ; tables=tables->next) { diff --git a/sql/sql_class.cc b/sql/sql_class.cc index b6b9a316cc6..36b1b89f6bf 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -708,6 +708,12 @@ void select_result::send_error(uint errcode,const char *err) ::send_error(thd, errcode, err); } + +void select_result::cleanup() +{ + /* do nothing */ +} + static String default_line_term("\n",default_charset_info); static String default_escaped("\\",default_charset_info); static String default_field_term("\t",default_charset_info); @@ -813,6 +819,32 @@ void select_to_file::send_error(uint errcode,const char *err) } +bool select_to_file::send_eof() +{ + int error= test(end_io_cache(&cache)); + if (my_close(file,MYF(MY_WME))) + error= 1; + if (!error) + ::send_ok(thd,row_count); + file= -1; + return error; +} + + +void select_to_file::cleanup() +{ + /* In case of error send_eof() may be not called: close the file here. */ + if (file >= 0) + { + (void) end_io_cache(&cache); + (void) my_close(file,MYF(0)); + file= -1; + } + path[0]= '\0'; + row_count= 0; +} + + select_to_file::~select_to_file() { if (file >= 0) @@ -1064,18 +1096,6 @@ err: } -bool select_export::send_eof() -{ - int error=test(end_io_cache(&cache)); - if (my_close(file,MYF(MY_WME))) - error=1; - if (!error) - ::send_ok(thd,row_count); - file= -1; - return error; -} - - /*************************************************************************** ** Dump of select to a binary file ***************************************************************************/ @@ -1129,18 +1149,6 @@ err: } -bool select_dump::send_eof() -{ - int error=test(end_io_cache(&cache)); - if (my_close(file,MYF(MY_WME))) - error=1; - if (!error) - ::send_ok(thd,row_count); - file= -1; - return error; -} - - select_subselect::select_subselect(Item_subselect *item_arg) { item= item_arg; @@ -1307,9 +1315,16 @@ int select_dumpvar::prepare(List<Item> &list, SELECT_LEX_UNIT *u) } +void select_dumpvar::cleanup() +{ + vars.empty(); + row_count=0; +} + + Item_arena::Item_arena(THD* thd) :free_list(0), - state((int)INITIALIZED) + state(INITIALIZED) { init_sql_alloc(&mem_root, thd->variables.query_alloc_block_size, @@ -1321,7 +1336,7 @@ Item_arena::Item_arena(THD* thd) Item_arena::Item_arena() :free_list(0), - state((int)CONVENTIONAL_EXECUTION) + state(CONVENTIONAL_EXECUTION) { clear_alloc_root(&mem_root); } @@ -1329,7 +1344,7 @@ Item_arena::Item_arena() Item_arena::Item_arena(bool init_mem_root) :free_list(0), - state((int)INITIALIZED) + state(INITIALIZED) { if (init_mem_root) clear_alloc_root(&mem_root); @@ -1411,6 +1426,21 @@ void Statement::restore_backup_statement(Statement *stmt, Statement *backup) } +void Statement::end_statement() +{ + /* Cleanup SQL processing state to resuse this statement in next query. */ + lex_end(lex); + delete lex->result; + lex->result= 0; + free_items(free_list); + free_list= 0; + /* + Don't free mem_root, as mem_root is freed in the end of dispatch_command + (once for any command). + */ +} + + void Item_arena::set_n_backup_item_arena(Item_arena *set, Item_arena *backup) { backup->set_item_arena(this); @@ -1474,7 +1504,7 @@ Statement_map::Statement_map() : hash_init(&st_hash, default_charset_info, START_STMT_HASH_SIZE, 0, 0, get_statement_id_as_hash_key, delete_statement_as_hash_key, MYF(0)); - hash_init(&names_hash, &my_charset_bin, START_NAME_HASH_SIZE, 0, 0, + hash_init(&names_hash, system_charset_info, START_NAME_HASH_SIZE, 0, 0, (hash_get_key) get_stmt_name_hash_key, NULL,MYF(0)); } diff --git a/sql/sql_class.h b/sql/sql_class.h index 713609b3d32..a8035cffd96 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -427,13 +427,13 @@ public: */ Item *free_list; MEM_ROOT mem_root; - enum + enum enum_state { INITIALIZED= 0, PREPARED= 1, EXECUTED= 3, CONVENTIONAL_EXECUTION= 2, ERROR= -1 }; - int state; + enum_state state; /* We build without RTTI, so dynamic_cast can't be used. */ enum Type @@ -447,8 +447,8 @@ public: virtual Type type() const; virtual ~Item_arena(); - inline bool is_stmt_prepare() const { return state < (int)PREPARED; } - inline bool is_first_stmt_execute() const { return state == (int)PREPARED; } + inline bool is_stmt_prepare() const { return (int)state < (int)PREPARED; } + inline bool is_first_stmt_execute() const { return state == PREPARED; } inline gptr alloc(unsigned int size) { return alloc_root(&mem_root,size); } inline gptr calloc(unsigned int size) { @@ -551,6 +551,12 @@ public: void restore_backup_statement(Statement *stmt, Statement *backup); /* return class type */ virtual Type type() const; + + /* + Cleanup statement parse state (parse tree, lex) after execution of + a non-prepared SQL statement. + */ + void end_statement(); }; @@ -1033,10 +1039,13 @@ public: ~Disable_binlog(); }; + /* Used to hold information about file and file structure in exchainge via non-DB file (...INTO OUTFILE..., ...LOAD DATA...) + XXX: We never call destructor for objects of this class. */ + class sql_exchange :public Sql_alloc { public: @@ -1046,7 +1055,6 @@ public: bool dumpfile; ulong skip_lines; sql_exchange(char *name,bool dumpfile_flag); - ~sql_exchange() {} }; #include "log_event.h" @@ -1077,6 +1085,11 @@ public: virtual void send_error(uint errcode,const char *err); virtual bool send_eof()=0; virtual void abort() {} + /* + Cleanup instance of this class for next execution of a prepared + statement/stored procedure. + */ + virtual void cleanup(); }; @@ -1103,6 +1116,8 @@ public: ~select_to_file(); bool send_fields(List<Item> &list, uint flag) { return 0; } void send_error(uint errcode,const char *err); + bool send_eof(); + void cleanup(); }; @@ -1115,7 +1130,6 @@ public: ~select_export(); int prepare(List<Item> &list, SELECT_LEX_UNIT *u); bool send_data(List<Item> &items); - bool send_eof(); }; @@ -1124,7 +1138,6 @@ public: select_dump(sql_exchange *ex) :select_to_file(ex) {} int prepare(List<Item> &list, SELECT_LEX_UNIT *u); bool send_data(List<Item> &items); - bool send_eof(); }; @@ -1149,6 +1162,8 @@ class select_insert :public select_result { bool send_data(List<Item> &items); void send_error(uint errcode,const char *err); bool send_eof(); + /* not implemented: select_insert is never re-used in prepared statements */ + void cleanup(); }; @@ -1449,4 +1464,5 @@ public: bool send_fields(List<Item> &list, uint flag) {return 0;} bool send_data(List<Item> &items); bool send_eof(); + void cleanup(); }; diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index b76bad2805b..ffeeb98488a 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -607,17 +607,13 @@ int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) int error; DBUG_ENTER("mysql_truncate"); + bzero((char*) &create_info,sizeof(create_info)); /* If it is a temporary table, close and regenerate it */ if (!dont_send_ok && (table_ptr=find_temporary_table(thd,table_list->db, table_list->real_name))) { TABLE *table= *table_ptr; - HA_CREATE_INFO create_info; table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK); - bzero((char*) &create_info,sizeof(create_info)); - create_info.auto_increment_value= table->file->auto_increment_value; - create_info.default_table_charset= table->table_charset; - db_type table_type=table->db_type; strmov(path,table->path); *table_ptr= table->next; // Unlink table from list @@ -659,8 +655,6 @@ int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) DBUG_RETURN(-1); } - bzero((char*) &create_info,sizeof(create_info)); - *fn_ext(path)=0; // Remove the .frm extension error= ha_create_table(path,&create_info,1) ? -1 : 0; query_cache_invalidate3(thd, table_list, 0); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 406bff6d273..4cbd11c6a15 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1465,6 +1465,13 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u) DBUG_RETURN(0); } + +void select_insert::cleanup() +{ + /* select_insert/select_create are never re-used in prepared statement */ + DBUG_ASSERT(0); +} + select_insert::~select_insert() { if (table) diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index ccbc015533b..fab047002ad 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1653,6 +1653,11 @@ void st_select_lex::print_limit(THD *thd, String *str) } +st_lex::st_lex() + :result(0) +{} + + /* Unlink first table from global table list and first table from outer select list (lex->select_lex) diff --git a/sql/sql_lex.h b/sql/sql_lex.h index da2c3fba097..7342902c086 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -633,7 +633,7 @@ typedef struct st_lex list of those tables after they are opened. */ TABLE_LIST *time_zone_tables_used; - st_lex() {} + st_lex(); inline void uncacheable(uint8 cause) { safe_to_cache_query= 0; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 66eebba74c9..79a011b9501 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1967,8 +1967,6 @@ mysql_execute_command(THD *thd) else thd->send_explain_fields(result); res= mysql_explain_union(thd, &thd->lex->unit, result); - MYSQL_LOCK *save_lock= thd->lock; - thd->lock= (MYSQL_LOCK *)0; if (lex->describe & DESCRIBE_EXTENDED) { char buff[1024]; @@ -1980,20 +1978,19 @@ mysql_execute_command(THD *thd) ER_YES, str.ptr()); } result->send_eof(); - thd->lock= save_lock; + delete result; } else { - if (!result) + if (!result && !(result= new select_send())) { - if (!(result=new select_send())) - { - res= -1; - break; - } + res= -1; + break; } query_cache_store_query(thd, tables); - res=handle_select(thd, lex, result); + res= handle_select(thd, lex, result); + if (result != lex->result) + delete result; } } break; @@ -2708,23 +2705,24 @@ unsent_create_error: } - if (!(res=open_and_lock_tables(thd, tables))) + if (!(res= open_and_lock_tables(thd, tables)) && + (result= new select_insert(tables->table, &lex->field_list, + lex->duplicates))) { - if ((result=new select_insert(tables->table,&lex->field_list, - lex->duplicates))) - /* Skip first table, which is the table we are inserting in */ - lex->select_lex.table_list.first= (byte*) first_local_table->next; - /* - insert/replace from SELECT give its SELECT_LEX for SELECT, - and item_list belong to SELECT - */ - lex->select_lex.resolve_mode= SELECT_LEX::SELECT_MODE; - res=handle_select(thd,lex,result); - /* revert changes for SP */ - lex->select_lex.table_list.first= (byte*) first_local_table; - lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE; + /* Skip first table, which is the table we are inserting in */ + lex->select_lex.table_list.first= (byte*) first_local_table->next; + /* + insert/replace from SELECT give its SELECT_LEX for SELECT, + and item_list belong to SELECT + */ + lex->select_lex.resolve_mode= SELECT_LEX::SELECT_MODE; + res= handle_select(thd, lex, result); + /* revert changes for SP */ + lex->select_lex.table_list.first= (byte*) first_local_table; + lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE; + delete result; if (thd->net.report_error) - res= -1; + res= -1; } else res= -1; @@ -2742,7 +2740,7 @@ unsent_create_error: send_error(thd,ER_LOCK_OR_ACTIVE_TRANSACTION,NullS); goto error; } - res=mysql_truncate(thd,tables); + res=mysql_truncate(thd, tables, 0); break; case SQLCOM_DELETE: { @@ -3904,8 +3902,8 @@ mysql_init_select(LEX *lex) select_lex->select_limit= HA_POS_ERROR; if (select_lex == &lex->select_lex) { + DBUG_ASSERT(lex->result == 0); lex->exchange= 0; - lex->result= 0; lex->proc_list.first= 0; } } @@ -4047,9 +4045,7 @@ void mysql_parse(THD *thd, char *inBuf, uint length) query_cache_abort(&thd->net); } thd->proc_info="freeing items"; - free_items(thd->free_list); /* Free strings used by items */ - thd->free_list= 0; - lex_end(lex); + thd->end_statement(); } DBUG_VOID_RETURN; } @@ -4074,10 +4070,7 @@ bool mysql_test_parse_for_slave(THD *thd, char *inBuf, uint length) if (!yyparse((void*) thd) && ! thd->is_fatal_error && all_tables_not_ok(thd,(TABLE_LIST*) lex->select_lex.table_list.first)) error= 1; /* Ignore question */ - free_items(thd->free_list); /* Free strings used by items */ - thd->free_list= 0; - lex_end(lex); - + thd->end_statement(); return error; } #endif @@ -5408,3 +5401,39 @@ int create_table_precheck(THD *thd, TABLE_LIST *tables, check_grant(thd, want_priv, create_table, 0, UINT_MAX, 0)) ? 1 : 0); } + + +/* + negate given expression + + SYNOPSIS + negate_expression() + thd therad handler + expr expression for negation + + RETURN + negated expression +*/ + +Item *negate_expression(THD *thd, Item *expr) +{ + Item *negated; + if (expr->type() == Item::FUNC_ITEM && + ((Item_func *) expr)->functype() == Item_func::NOT_FUNC) + { + /* it is NOT(NOT( ... )) */ + Item *arg= ((Item_func *) expr)->arguments()[0]; + enum_parsing_place place= thd->lex->current_select->parsing_place; + if (arg->is_bool_func() || place == IN_WHERE || place == IN_HAVING) + return arg; + /* + if it is not boolean function then we have to emulate value of + not(not(a)), it will be a != 0 + */ + return new Item_func_ne(arg, new Item_int((char*) "0", 0, 1)); + } + + if ((negated= expr->neg_transformer(thd)) != 0) + return negated; + return new Item_func_not(expr); +} diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 94b6ab103da..708ca3a516f 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -132,7 +132,7 @@ find_prepared_statement(THD *thd, ulong id, const char *where, { Statement *stmt= thd->stmt_map.find(id); - if (stmt == 0 || stmt->type() != (int)Item_arena::PREPARED_STATEMENT) + if (stmt == 0 || stmt->type() != Item_arena::PREPARED_STATEMENT) { char llbuf[22]; my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), 22, llstr(id, llbuf), where); @@ -1619,7 +1619,7 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, { sl->prep_where= sl->where; } - stmt->state= (int)Prepared_statement::PREPARED; + stmt->state= Item_arena::PREPARED; } DBUG_RETURN(!stmt); @@ -1630,7 +1630,8 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, static void reset_stmt_for_execute(Prepared_statement *stmt) { THD *thd= stmt->thd; - SELECT_LEX *sl= stmt->lex->all_selects_list; + LEX *lex= stmt->lex; + SELECT_LEX *sl= lex->all_selects_list; for (; sl; sl= sl->next_select_in_list()) { @@ -1678,7 +1679,9 @@ static void reset_stmt_for_execute(Prepared_statement *stmt) unit->reinit_exec_mechanism(); } } - stmt->lex->current_select= &stmt->lex->select_lex; + lex->current_select= &lex->select_lex; + if (lex->result) + lex->result->cleanup(); } @@ -1733,7 +1736,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length) DBUG_PRINT("exec_query:", ("%s", stmt->query)); /* Check if we got an error when sending long data */ - if (stmt->state == (int)Item_arena::ERROR) + if (stmt->state == Item_arena::ERROR) { send_error(thd, stmt->last_errno, stmt->last_error); DBUG_VOID_RETURN; @@ -1850,7 +1853,7 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt, transformations of the query tree (i.e. negations elimination). This should be done permanently on the parse tree of this statement. */ - if (stmt->state == (int)Item_arena::PREPARED) + if (stmt->state == Item_arena::PREPARED) thd->current_arena= stmt; if (!(specialflag & SPECIAL_NO_PRIOR)) @@ -1863,10 +1866,10 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt, /* Free Items that were created during this execution of the PS. */ free_items(thd->free_list); thd->free_list= 0; - if (stmt->state == (int)Item_arena::PREPARED) + if (stmt->state == Item_arena::PREPARED) { thd->current_arena= thd; - stmt->state= (int)Item_arena::EXECUTED; + stmt->state= Item_arena::EXECUTED; } cleanup_items(stmt->free_list); reset_stmt_params(stmt); @@ -1905,7 +1908,7 @@ void mysql_stmt_reset(THD *thd, char *packet) SEND_ERROR))) DBUG_VOID_RETURN; - stmt->state= (int)Item_arena::PREPARED; + stmt->state= Item_arena::PREPARED; /* Clear parameters from data which could be set by @@ -1993,7 +1996,7 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length) if (param_number >= stmt->param_count) { /* Error will be sent in execute call */ - stmt->state= (int)Item_arena::ERROR; + stmt->state= Item_arena::ERROR; stmt->last_errno= ER_WRONG_ARGUMENTS; sprintf(stmt->last_error, ER(ER_WRONG_ARGUMENTS), "mysql_stmt_send_long_data"); @@ -2009,7 +2012,7 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length) if (param->set_longdata(thd->extra_data, thd->extra_length)) #endif { - stmt->state= (int)Item_arena::ERROR; + stmt->state= Item_arena::ERROR; stmt->last_errno= ER_OUTOFMEMORY; sprintf(stmt->last_error, ER(ER_OUTOFMEMORY), 0); } @@ -2053,6 +2056,7 @@ void Prepared_statement::setup_set_params() Prepared_statement::~Prepared_statement() { free_items(free_list); + delete lex->result; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 630a520066a..72e169c77af 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -199,16 +199,10 @@ int handle_select(THD *thd, LEX *lex, select_result *result) res= 1; if (res) { - if (result) - { - result->send_error(0, NullS); - result->abort(); - } - else - send_error(thd, 0, NullS); + result->send_error(0, NullS); + result->abort(); res= 1; // Error sent to client } - delete result; DBUG_RETURN(res); } @@ -839,7 +833,8 @@ JOIN::optimize() ((group_list && const_tables != tables && (!simple_group || !test_if_skip_sort_order(&join_tab[const_tables], group_list, - unit->select_limit_cnt, 0))) || select_distinct) && + unit->select_limit_cnt, 0))) || + select_distinct) && tmp_table_param.quick_group && !procedure) { need_tmp=1; simple_order=simple_group=0; // Force tmp table without sort @@ -2169,22 +2164,32 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, COND *cond, number. cmp_type() is checked to allow compare of dates to numbers. eq_func is NEVER true when num_values > 1 */ - if (!eq_func || - field->result_type() == STRING_RESULT && - (*value)->result_type() != STRING_RESULT && - field->cmp_type() != (*value)->result_type()) - return; - - /* - We can't use indexes if the effective collation - of the operation differ from the field collation. - */ - if (field->result_type() == STRING_RESULT && - (*value)->result_type() == STRING_RESULT && - field->cmp_type() == STRING_RESULT && - ((Field_str*)field)->charset() != cond->compare_collation()) - return; + if (!eq_func) + return; + if (field->result_type() == STRING_RESULT) + { + if ((*value)->result_type() != STRING_RESULT) + { + if (field->cmp_type() != (*value)->result_type()) + return; + } + else + { + /* + We can't use indexes if the effective collation + of the operation differ from the field collation. + We can also not used index on a text column, as the column may + contain 'x' 'x\t' 'x ' and 'read_next_same' will stop after + 'x' when searching for WHERE col='x ' + */ + if (field->cmp_type() == STRING_RESULT && + (((Field_str*)field)->charset() != cond->compare_collation() || + ((*value)->type() != Item::NULL_ITEM && + (field->flags & BLOB_FLAG) && !field->binary()))) + return; + } + } } } DBUG_ASSERT(num_values == 1); @@ -4334,60 +4339,6 @@ propagate_cond_constants(I_List<COND_CMP> *save_list,COND *and_father, } -/* - Eliminate NOT functions from the condition tree. - - SYNPOSIS - eliminate_not_funcs() - thd thread handler - cond condition tree - - DESCRIPTION - Eliminate NOT functions from the condition tree where it's possible. - Recursively traverse condition tree to find all NOT functions. - Call neg_transformer() method for negated arguments. - - NOTE - If neg_transformer() returned a new condition we call fix_fields(). - We don't delete any items as it's not needed. They will be deleted - later at once. - - RETURN - New condition tree -*/ - -COND *eliminate_not_funcs(THD *thd, COND *cond) -{ - if (!cond) - return cond; - if (cond->type() == Item::COND_ITEM) /* OR or AND */ - { - List_iterator<Item> li(*((Item_cond*) cond)->argument_list()); - Item *item; - while ((item= li++)) - { - Item *new_item= eliminate_not_funcs(thd, item); - if (item != new_item) - VOID(li.replace(new_item)); /* replace item with a new condition */ - } - } - else if (cond->type() == Item::FUNC_ITEM && /* 'NOT' operation? */ - ((Item_func*) cond)->functype() == Item_func::NOT_FUNC) - { - COND *new_cond= ((Item_func*) cond)->arguments()[0]->neg_transformer(thd); - if (new_cond) - { - /* - Here we can delete the NOT function. Something like: delete cond; - But we don't need to do it. All items will be deleted later at once. - */ - cond= new_cond; - } - } - return cond; -} - - static COND * optimize_cond(THD *thd, COND *conds, Item::cond_result *cond_value) { @@ -4396,19 +4347,6 @@ optimize_cond(THD *thd, COND *conds, Item::cond_result *cond_value) if (conds) { DBUG_EXECUTE("where", print_where(conds, "original");); - /* Eliminate NOT operators; in case of PS/SP do it once */ - if (thd->current_arena->is_first_stmt_execute()) - { - Item_arena *arena= thd->current_arena, backup; - thd->set_n_backup_item_arena(arena, &backup); - conds= eliminate_not_funcs(thd, conds); - select->prep_where= conds->copy_andor_structure(thd); - thd->restore_backup_item_arena(arena, &backup); - } - else - conds= eliminate_not_funcs(thd, conds); - DBUG_EXECUTE("where", print_where(conds, "after negation elimination");); - /* change field = field to field = const for each found field = const */ propagate_cond_constants((I_List<COND_CMP> *) 0, conds, conds); /* @@ -5570,9 +5508,7 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param, table->file->info(HA_STATUS_VARIABLE); /* update table->file->records */ new_table.file->start_bulk_insert(table->file->records); #else - /* - HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it explicitly. - */ + /* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */ new_table.file->extra(HA_EXTRA_WRITE_CACHE); #endif @@ -7240,9 +7176,9 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, keys.merge(table->used_keys); /* - We are adding here also the index speified in FORCE INDEX clause, + We are adding here also the index specified in FORCE INDEX clause, if any. - This is to allow users to use index in ORDER BY. + This is to allow users to use index in ORDER BY. */ if (table->force_index) keys.merge(table->keys_in_use_for_query); diff --git a/sql/sql_select.h b/sql/sql_select.h index 8aca43484d2..34eaa7e272d 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -438,4 +438,3 @@ bool cp_buffer_from_ref(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 *eliminate_not_funcs(THD *thd, COND *cond); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 9cc39fe5104..79cfb1f0adb 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1049,7 +1049,10 @@ create: lex->col_list.empty(); } | CREATE DATABASE opt_if_not_exists ident - { Lex->create_info.default_table_charset=NULL; } + { + Lex->create_info.default_table_charset= NULL; + Lex->create_info.used_fields= 0; + } opt_create_database_options { LEX *lex=Lex; @@ -1136,11 +1139,8 @@ create_database_options: | create_database_options create_database_option {}; create_database_option: - opt_default COLLATE_SYM collation_name_or_default - { Lex->create_info.default_table_charset=$3; } - | opt_default charset charset_name_or_default - { Lex->create_info.default_table_charset=$3; } - ; + default_collation {} + | default_charset {}; opt_table_options: /* empty */ { $$= 0; } @@ -1200,21 +1200,46 @@ create_table_option: table_list->next=0; lex->create_info.used_fields|= HA_CREATE_USED_UNION; } - | opt_default charset opt_equal charset_name_or_default - { - Lex->create_info.default_table_charset= $4; - Lex->create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET; - } - | opt_default COLLATE_SYM opt_equal collation_name_or_default - { - Lex->create_info.default_table_charset= $4; - Lex->create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET; - } + | default_charset + | default_collation | INSERT_METHOD opt_equal merge_insert_types { Lex->create_info.merge_insert_method= $3; Lex->create_info.used_fields|= HA_CREATE_USED_INSERT_METHOD;} | DATA_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys { Lex->create_info.data_file_name= $4.str; } | INDEX_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys { Lex->create_info.index_file_name= $4.str; }; +default_charset: + opt_default charset opt_equal charset_name_or_default + { + HA_CREATE_INFO *cinfo= &Lex->create_info; + if ((cinfo->used_fields & HA_CREATE_USED_DEFAULT_CHARSET) && + cinfo->default_table_charset && $4 && + !my_charset_same(cinfo->default_table_charset,$4)) + { + net_printf(YYTHD, ER_CONFLICTING_DECLARATIONS, + "CHARACTER SET ", cinfo->default_table_charset->csname, + "CHARACTER SET ", $4->csname); + YYABORT; + } + Lex->create_info.default_table_charset= $4; + Lex->create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET; + }; + +default_collation: + opt_default COLLATE_SYM opt_equal collation_name_or_default + { + HA_CREATE_INFO *cinfo= &Lex->create_info; + if ((cinfo->used_fields & HA_CREATE_USED_DEFAULT_CHARSET) && + cinfo->default_table_charset && $4 && + !my_charset_same(cinfo->default_table_charset,$4)) + { + net_printf(YYTHD,ER_COLLATION_CHARSET_MISMATCH, + $4->name, cinfo->default_table_charset->csname); + YYABORT; + } + Lex->create_info.default_table_charset= $4; + Lex->create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET; + }; + storage_engines: ident_or_text { @@ -1824,7 +1849,12 @@ alter: } alter_list {} - | ALTER DATABASE ident opt_create_database_options + | ALTER DATABASE ident + { + Lex->create_info.default_table_charset= NULL; + Lex->create_info.used_fields= 0; + } + opt_create_database_options { LEX *lex=Lex; lex->sql_command=SQLCOM_ALTER_DB; @@ -2722,8 +2752,14 @@ simple_expr: | '+' expr %prec NEG { $$= $2; } | '-' expr %prec NEG { $$= new Item_func_neg($2); } | '~' expr %prec NEG { $$= new Item_func_bit_neg($2); } - | NOT expr %prec NEG { $$= new Item_func_not($2); } - | '!' expr %prec NEG { $$= new Item_func_not($2); } + | NOT expr %prec NEG + { + $$= negate_expression(YYTHD, $2); + } + | '!' expr %prec NEG + { + $$= negate_expression(YYTHD, $2); + } | '(' expr ')' { $$= $2; } | '(' expr ',' expr_list ')' { @@ -2745,8 +2781,7 @@ simple_expr: | ASCII_SYM '(' expr ')' { $$= new Item_func_ascii($3); } | BINARY expr %prec NEG { - $$= new Item_func_set_collation($2,new Item_string(binary_keyword, - 6, &my_charset_latin1)); + $$= create_func_cast($2, ITEM_CAST_CHAR, -1, &my_charset_bin); } | CAST_SYM '(' expr AS cast_type ')' { @@ -3566,11 +3601,17 @@ opt_all: where_clause: /* empty */ { Select->where= 0; } - | WHERE expr + | WHERE + { + Select->parsing_place= IN_WHERE; + } + expr { - Select->where= $2; - if ($2) - $2->top_level_item(); + SELECT_LEX *select= Select; + select->where= $3; + select->parsing_place= NO_MATTER; + if ($3) + $3->top_level_item(); } ; diff --git a/sql/tztime.cc b/sql/tztime.cc index 757272d332f..af9af530fec 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -1560,8 +1560,8 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) if (open_tables(thd, tables_buff, &counter) || lock_tables(thd, tables_buff, counter)) { - sql_print_error("Warning: Can't open and lock time zone table: %s " - "trying to live without them", thd->net.last_error); + sql_print_warning("Can't open and lock time zone table: %s " + "trying to live without them", thd->net.last_error); /* We will try emulate that everything is ok */ return_val= time_zone_tables_exist= 0; goto end_with_setting_default_tz; @@ -1740,8 +1740,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) if (!(alloc_buff= alloc_root(&tz_storage, sizeof(TIME_ZONE_INFO) + tz_name->length() + 1))) { - sql_print_error("Error: Out of memory while loading time zone " - "description"); + sql_print_error("Out of memory while loading time zone description"); return 0; } tz_info= (TIME_ZONE_INFO *)alloc_buff; @@ -1757,7 +1756,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) Let us find out time zone id by its name (there is only one index and it is specifically for this purpose). */ - table= tz_tables->table; + table= tz_tables->table; tz_tables= tz_tables->next; table->field[0]->store(tz_name->ptr(), tz_name->length(), &my_charset_latin1); /* @@ -1770,7 +1769,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) if (table->file->index_read(table->record[0], (byte*)table->field[0]->ptr, 0, HA_READ_KEY_EXACT)) { - sql_print_error("Error: Can't find description of time zone."); + sql_print_error("Can't find description of time zone."); goto end; } @@ -1783,7 +1782,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) understand whenever this timezone uses leap seconds (again we are using the only index in this table). */ - table= tz_tables->table; + table= tz_tables->table; tz_tables= tz_tables->next; table->field[0]->store((longlong)tzid); (void)table->file->ha_index_init(0); @@ -1791,7 +1790,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) if (table->file->index_read(table->record[0], (byte*)table->field[0]->ptr, 0, HA_READ_KEY_EXACT)) { - sql_print_error("Error: Can't find description of time zone."); + sql_print_error("Can't find description of time zone."); goto end; } @@ -1810,7 +1809,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) only for our time zone guess what are we doing? Right - using special index. */ - table= tz_tables->table; + table= tz_tables->table; tz_tables= tz_tables->next; table->field[0]->store((longlong)tzid); (void)table->file->ha_index_init(0); @@ -1948,8 +1947,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) #endif sizeof(TRAN_TYPE_INFO) * tz_info->typecnt))) { - sql_print_error("Error: Out of memory while loading time zone " - "description"); + sql_print_error("Out of memory while loading time zone description"); goto end; } @@ -1974,12 +1972,12 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) */ if (tz_info->typecnt < 1) { - sql_print_error("Error: loading time zone without transition types"); + sql_print_error("loading time zone without transition types"); goto end; } if (prepare_tz_info(tz_info, &tz_storage)) { - sql_print_error("Error: Unable to build mktime map for time zone"); + sql_print_error("Unable to build mktime map for time zone"); goto end; } @@ -1991,7 +1989,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) &my_charset_latin1), my_hash_insert(&tz_names, (const byte *)tmp_tzname))) { - sql_print_error("Error: Out of memory while loading time zone"); + sql_print_error("Out of memory while loading time zone"); goto end; } @@ -2158,20 +2156,21 @@ my_tz_find(const String * name, TABLE_LIST *tz_tables) if (!(result_tz= new (&tz_storage) Time_zone_offset(offset)) || my_hash_insert(&offset_tzs, (const byte *) result_tz)) { + result_tz= 0; sql_print_error("Fatal error: Out of memory " "while setting new time zone"); - result_tz= 0; } } - } else { + } + else + { + result_tz= 0; if ((tmp_tzname= (TZ_NAMES_ENTRY *)hash_search(&tz_names, (const byte *)name->ptr(), name->length()))) result_tz= tmp_tzname->tz; - else if(time_zone_tables_exist) + else if (time_zone_tables_exist) result_tz= tz_load_from_open_tables(name, tz_tables); - else - result_tz= 0; } VOID(pthread_mutex_unlock(&tz_LOCK)); diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c index 0955372e8c0..3f35f7504ac 100644 --- a/strings/ctype-big5.c +++ b/strings/ctype-big5.c @@ -6290,6 +6290,7 @@ static MY_CHARSET_HANDLER my_charset_big5_handler= my_charpos_mb, my_well_formed_len_mb, my_lengthsp_8bit, + my_numcells_mb, my_mb_wc_big5, /* mb_wc */ my_wc_mb_big5, /* wc_mb */ my_caseup_str_mb, diff --git a/strings/ctype-bin.c b/strings/ctype-bin.c index e759a5654f1..42dc0ab086d 100644 --- a/strings/ctype-bin.c +++ b/strings/ctype-bin.c @@ -93,7 +93,7 @@ static int my_strnncoll_binary(CHARSET_INFO * cs __attribute__((unused)), NOTE This function is used for real binary strings, i.e. for BLOB, BINARY(N) and VARBINARY(N). - It does not ignore trailing spaces. + It compares trailing spaces as spaces. RETURN < 0 s < t @@ -133,7 +133,8 @@ static int my_strnncoll_8bit_bin(CHARSET_INFO * cs __attribute__((unused)), NOTE This function is used for character strings with binary collations. - It ignores trailing spaces. + The shorter string is extended with end space to be as long as the longer + one. RETURN < 0 s < t @@ -448,6 +449,7 @@ static MY_CHARSET_HANDLER my_charset_handler= my_charpos_8bit, my_well_formed_len_8bit, my_lengthsp_8bit, + my_numcells_8bit, my_mb_wc_bin, my_wc_mb_bin, my_case_str_bin, @@ -478,7 +480,7 @@ CHARSET_INFO my_charset_bin = ctype_bin, /* ctype */ bin_char_array, /* to_lower */ bin_char_array, /* to_upper */ - bin_char_array, /* sort_order */ + NULL, /* sort_order */ NULL, /* contractions */ NULL, /* sort_order_big*/ NULL, /* tab_to_uni */ diff --git a/strings/ctype-euc_kr.c b/strings/ctype-euc_kr.c index bcf66e2a828..43a50b0dfbe 100644 --- a/strings/ctype-euc_kr.c +++ b/strings/ctype-euc_kr.c @@ -8657,6 +8657,7 @@ static MY_CHARSET_HANDLER my_charset_handler= my_charpos_mb, my_well_formed_len_mb, my_lengthsp_8bit, + my_numcells_mb, my_mb_wc_euc_kr, /* mb_wc */ my_wc_mb_euc_kr, /* wc_mb */ my_caseup_str_mb, diff --git a/strings/ctype-gb2312.c b/strings/ctype-gb2312.c index e4e14259620..8d97ac9ca1d 100644 --- a/strings/ctype-gb2312.c +++ b/strings/ctype-gb2312.c @@ -5708,6 +5708,7 @@ static MY_CHARSET_HANDLER my_charset_handler= my_charpos_mb, my_well_formed_len_mb, my_lengthsp_8bit, + my_numcells_mb, my_mb_wc_gb2312, /* mb_wc */ my_wc_mb_gb2312, /* wc_mb */ my_caseup_str_mb, diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c index 80876cac41f..9400fb08f2b 100644 --- a/strings/ctype-gbk.c +++ b/strings/ctype-gbk.c @@ -9939,6 +9939,7 @@ static MY_CHARSET_HANDLER my_charset_handler= my_charpos_mb, my_well_formed_len_mb, my_lengthsp_8bit, + my_numcells_mb, my_mb_wc_gbk, my_wc_mb_gbk, my_caseup_str_mb, diff --git a/strings/ctype-latin1.c b/strings/ctype-latin1.c index f4717c51a1e..aea517811ab 100644 --- a/strings/ctype-latin1.c +++ b/strings/ctype-latin1.c @@ -387,6 +387,7 @@ static MY_CHARSET_HANDLER my_charset_handler= my_charpos_8bit, my_well_formed_len_8bit, my_lengthsp_8bit, + my_numcells_8bit, my_mb_wc_latin1, my_wc_mb_latin1, my_caseup_str_8bit, diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c index ecafa6356d5..2548a68ab19 100644 --- a/strings/ctype-mb.c +++ b/strings/ctype-mb.c @@ -237,7 +237,8 @@ int my_wildcmp_mb(CHARSET_INFO *cs, if (str++ == str_end) return (-1); } { - int tmp=my_wildcmp_mb(cs,str,str_end,wildstr,wildend,escape,w_one,w_many); + int tmp=my_wildcmp_mb(cs,str,str_end,wildstr,wildend,escape,w_one, + w_many); if (tmp <= 0) return (tmp); } @@ -248,41 +249,46 @@ int my_wildcmp_mb(CHARSET_INFO *cs, return (str != str_end ? 1 : 0); } + uint my_numchars_mb(CHARSET_INFO *cs __attribute__((unused)), - const char *b, const char *e) + const char *pos, const char *end) { - register uint32 n=0,mblen; - while (b < e) + register uint32 count=0; + while (pos < end) { - b+= (mblen= my_ismbchar(cs,b,e)) ? mblen : 1; - ++n; + uint mblen; + pos+= (mblen= my_ismbchar(cs,pos,end)) ? mblen : 1; + count++; } - return n; + return count; } + uint my_charpos_mb(CHARSET_INFO *cs __attribute__((unused)), - const char *b, const char *e, uint pos) + const char *pos, const char *end, uint length) { - uint mblen; - const char *b0=b; + const char *start= pos; - while (pos && b<e) + while (length && pos < end) { - b+= (mblen= my_ismbchar(cs,b,e)) ? mblen : 1; - pos--; + uint mblen; + pos+= (mblen= my_ismbchar(cs, pos, end)) ? mblen : 1; + length--; } - return pos ? e+2-b0 : b-b0; + return length ? end+2-start : pos-start; } + uint my_well_formed_len_mb(CHARSET_INFO *cs, const char *b, const char *e, uint pos) { - my_wc_t wc; - int mblen; const char *b_start= b; while (pos) { + my_wc_t wc; + int mblen; + if ((mblen= cs->cset->mb_wc(cs, &wc, (uchar*) b, (uchar*) e)) <0) break; b+= mblen; @@ -374,7 +380,8 @@ static int my_strnncoll_mb_bin(CHARSET_INFO * cs __attribute__((unused)), NOTE This function is used for character strings with binary collations. - It ignores trailing spaces. + The shorter string is extended with end space to be as long as the longer + one. RETURN A negative number if s < t @@ -570,6 +577,238 @@ static int my_wildcmp_mb_bin(CHARSET_INFO *cs, } +/* + Data was produced from EastAsianWidth.txt + using utt11-dump utility. +*/ +static char pg11[256]= +{ +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1, +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, +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, +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, +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, +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 +}; + +static char pg23[256]= +{ +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, +0,0,0,0,0,0,0,0,0,1,1,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +}; + +static char pg2E[256]= +{ +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, +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, +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, +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, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +}; + +static char pg2F[256]= +{ +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0 +}; + +static char pg30[256]= +{ +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 +}; + +static char pg31[256]= +{ +0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 +}; + +static char pg32[256]= +{ +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 +}; + +static char pg4D[256]= +{ +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,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,0,0,0,0,0,0,0,0,0,0 +}; + +static char pg9F[256]= +{ +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,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,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,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 +}; + +static char pgA4[256]= +{ +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,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,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 +}; + +static char pgD7[256]= +{ +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,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,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,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 +}; + +static char pgFA[256]= +{ +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +}; + +static char pgFE[256]= +{ +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, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,0,1,1,1,1,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +}; + +static char pgFF[256]= +{ +0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,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,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,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,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, +1,1,1,1,1,1,1,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 +}; + +static struct {int page; char *p;} utr11_data[256]= +{ +{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL}, +{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL}, +{0,NULL},{0,pg11},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL}, +{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL}, +{0,NULL},{0,NULL},{0,NULL},{0,pg23},{0,NULL},{0,NULL},{0,NULL},{0,NULL}, +{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,pg2E},{0,pg2F}, +{0,pg30},{0,pg31},{0,pg32},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL}, +{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL}, +{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL}, +{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{0,pg4D},{1,NULL},{1,NULL}, +{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL}, +{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL}, +{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL}, +{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL}, +{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL}, +{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL}, +{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL}, +{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL}, +{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL}, +{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{0,pg9F}, +{1,NULL},{1,NULL},{1,NULL},{1,NULL},{0,pgA4},{0,NULL},{0,NULL},{0,NULL}, +{0,NULL},{0,NULL},{0,NULL},{0,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL}, +{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL}, +{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL}, +{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL}, +{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL}, +{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{1,NULL},{0,pgD7}, +{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL}, +{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL}, +{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL}, +{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL},{0,NULL}, +{0,NULL},{1,NULL},{0,pgFA},{0,NULL},{0,NULL},{0,NULL},{0,pgFE},{0,pgFF} +}; + +uint my_numcells_mb(CHARSET_INFO *cs, const char *b, const char *e) +{ + my_wc_t wc; + int clen= 0; + + while (b < e) + { + int mblen; + uint pg; + if ((mblen= cs->cset->mb_wc(cs, &wc, (uchar*) b, (uchar*) e)) <= 0) + { + mblen= 1; /* Let's think a wrong sequence takes 1 dysplay cell */ + b++; + continue; + } + b+= mblen; + pg= (wc >> 8) & 0xFF; + clen+= utr11_data[pg].p ? utr11_data[pg].p[wc & 0xFF] : utr11_data[pg].page; + clen++; + } + return clen; +} + + MY_COLLATION_HANDLER my_collation_mb_bin_handler = { NULL, /* init */ diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c index fbe702d27ad..84bfcb0b171 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -1056,6 +1056,13 @@ uint my_numchars_8bit(CHARSET_INFO *cs __attribute__((unused)), } +uint my_numcells_8bit(CHARSET_INFO *cs __attribute__((unused)), + const char *b, const char *e) +{ + return e-b; +} + + uint my_charpos_8bit(CHARSET_INFO *cs __attribute__((unused)), const char *b __attribute__((unused)), const char *e __attribute__((unused)), @@ -1287,6 +1294,7 @@ MY_CHARSET_HANDLER my_charset_8bit_handler= my_charpos_8bit, my_well_formed_len_8bit, my_lengthsp_8bit, + my_numcells_8bit, my_mb_wc_8bit, my_wc_mb_8bit, my_caseup_str_8bit, diff --git a/strings/ctype-sjis.c b/strings/ctype-sjis.c index 65d096b96fc..b4cfee0f24a 100644 --- a/strings/ctype-sjis.c +++ b/strings/ctype-sjis.c @@ -4558,6 +4558,7 @@ static MY_CHARSET_HANDLER my_charset_handler= my_charpos_mb, my_well_formed_len_mb, my_lengthsp_8bit, + my_numcells_mb, my_mb_wc_sjis, /* mb_wc */ my_wc_mb_sjis, /* wc_mb */ my_caseup_str_8bit, diff --git a/strings/ctype-tis620.c b/strings/ctype-tis620.c index 60f02e3146d..420c5b5582e 100644 --- a/strings/ctype-tis620.c +++ b/strings/ctype-tis620.c @@ -930,6 +930,7 @@ static MY_CHARSET_HANDLER my_charset_handler= my_charpos_8bit, my_well_formed_len_8bit, my_lengthsp_8bit, + my_numcells_8bit, my_mb_wc_tis620, /* mb_wc */ my_wc_mb_tis620, /* wc_mb */ my_caseup_str_8bit, diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index 645e2e49fc1..c6e55ee8f0e 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -1423,6 +1423,7 @@ MY_CHARSET_HANDLER my_charset_ucs2_handler= my_charpos_ucs2, my_well_formed_len_ucs2, my_lengthsp_ucs2, + my_numcells_mb, my_ucs2_uni, /* mb_wc */ my_uni_ucs2, /* wc_mb */ my_caseup_str_ucs2, diff --git a/strings/ctype-ujis.c b/strings/ctype-ujis.c index 746c31f37a0..37c26a3bbc4 100644 --- a/strings/ctype-ujis.c +++ b/strings/ctype-ujis.c @@ -8443,6 +8443,7 @@ static MY_CHARSET_HANDLER my_charset_handler= my_charpos_mb, my_well_formed_len_mb, my_lengthsp_8bit, + my_numcells_mb, my_mb_wc_euc_jp, /* mb_wc */ my_wc_mb_euc_jp, /* wc_mb */ my_caseup_str_mb, diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index f7a70afcb92..5e339725b1a 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -1,15 +1,15 @@ /* Copyright (C) 2000 MySQL AB - + This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. - + You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, @@ -1524,7 +1524,7 @@ MY_UNICASE_INFO *uni_plane[256]={ #ifdef HAVE_CHARSET_utf8 -/* +/* We consider bytes with code more than 127 as a letter. This garantees that word boundaries work fine with regular expressions. Note, there is no need to mark byte 255 as a @@ -1590,99 +1590,108 @@ static uchar to_upper_utf8[] = { 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 }; +static inline int bincmp(const uchar *s, const uchar *se, + const uchar *t, const uchar *te) +{ + int slen=se-s, tlen=te-t; + int len=min(slen,tlen); + int cmp= memcmp(s,t,len); + return cmp ? cmp : slen-tlen; +} + static int my_utf8_uni(CHARSET_INFO *cs __attribute__((unused)), - my_wc_t * pwc, const uchar *s, const uchar *e) + my_wc_t * pwc, const uchar *s, const uchar *e) { unsigned char c; - + if (s >= e) return MY_CS_TOOFEW(0); c= s[0]; - if (c < 0x80) + if (c < 0x80) { *pwc = c; return 1; - } - else if (c < 0xc2) + } + else if (c < 0xc2) return MY_CS_ILSEQ; - else if (c < 0xe0) + else if (c < 0xe0) { - if (s+2 > e) /* We need 2 characters */ + if (s+2 > e) /* We need 2 characters */ return MY_CS_TOOFEW(0); - + if (!((s[1] ^ 0x80) < 0x40)) return MY_CS_ILSEQ; - + *pwc = ((my_wc_t) (c & 0x1f) << 6) | (my_wc_t) (s[1] ^ 0x80); return 2; - } - else if (c < 0xf0) + } + else if (c < 0xf0) { if (s+3 > e) /* We need 3 characters */ return MY_CS_TOOFEW(0); - + if (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 && (c >= 0xe1 || s[1] >= 0xa0))) return MY_CS_ILSEQ; - - *pwc = ((my_wc_t) (c & 0x0f) << 12) | - ((my_wc_t) (s[1] ^ 0x80) << 6) | + + *pwc = ((my_wc_t) (c & 0x0f) << 12) | + ((my_wc_t) (s[1] ^ 0x80) << 6) | (my_wc_t) (s[2] ^ 0x80); - + return 3; - } + } #ifdef UNICODE_32BIT - else if (c < 0xf8 && sizeof(my_wc_t)*8 >= 32) + else if (c < 0xf8 && sizeof(my_wc_t)*8 >= 32) { if (s+4 > e) /* We need 4 characters */ return MY_CS_TOOFEW(0); - - if (!((s[1] ^ 0x80) < 0x40 && - (s[2] ^ 0x80) < 0x40 && - (s[3] ^ 0x80) < 0x40 && + + if (!((s[1] ^ 0x80) < 0x40 && + (s[2] ^ 0x80) < 0x40 && + (s[3] ^ 0x80) < 0x40 && (c >= 0xf1 || s[1] >= 0x90))) return MY_CS_ILSEQ; - - *pwc = ((my_wc_t) (c & 0x07) << 18) | - ((my_wc_t) (s[1] ^ 0x80) << 12) | - ((my_wc_t) (s[2] ^ 0x80) << 6) | + + *pwc = ((my_wc_t) (c & 0x07) << 18) | + ((my_wc_t) (s[1] ^ 0x80) << 12) | + ((my_wc_t) (s[2] ^ 0x80) << 6) | (my_wc_t) (s[3] ^ 0x80); - + return 4; } - else if (c < 0xfc && sizeof(my_wc_t)*8 >= 32) + else if (c < 0xfc && sizeof(my_wc_t)*8 >= 32) { if (s+5 >e) /* We need 5 characters */ return MY_CS_TOOFEW(0); - - if (!((s[1] ^ 0x80) < 0x40 && - (s[2] ^ 0x80) < 0x40 && - (s[3] ^ 0x80) < 0x40 && - (s[4] ^ 0x80) < 0x40 && + + if (!((s[1] ^ 0x80) < 0x40 && + (s[2] ^ 0x80) < 0x40 && + (s[3] ^ 0x80) < 0x40 && + (s[4] ^ 0x80) < 0x40 && (c >= 0xf9 || s[1] >= 0x88))) return MY_CS_ILSEQ; - - *pwc = ((my_wc_t) (c & 0x03) << 24) | + + *pwc = ((my_wc_t) (c & 0x03) << 24) | ((my_wc_t) (s[1] ^ 0x80) << 18) | ((my_wc_t) (s[2] ^ 0x80) << 12) | ((my_wc_t) (s[3] ^ 0x80) << 6) | (my_wc_t) (s[4] ^ 0x80); return 5; - } - else if (c < 0xfe && sizeof(my_wc_t)*8 >= 32) + } + else if (c < 0xfe && sizeof(my_wc_t)*8 >= 32) { if ( s+6 >e ) /* We need 6 characters */ return MY_CS_TOOFEW(0); - - if (!((s[1] ^ 0x80) < 0x40 && - (s[2] ^ 0x80) < 0x40 && - (s[3] ^ 0x80) < 0x40 && - (s[4] ^ 0x80) < 0x40 && - (s[5] ^ 0x80) < 0x40 && + + if (!((s[1] ^ 0x80) < 0x40 && + (s[2] ^ 0x80) < 0x40 && + (s[3] ^ 0x80) < 0x40 && + (s[4] ^ 0x80) < 0x40 && + (s[5] ^ 0x80) < 0x40 && (c >= 0xfd || s[1] >= 0x84))) return MY_CS_ILSEQ; - + *pwc = ((my_wc_t) (c & 0x01) << 30) | ((my_wc_t) (s[1] ^ 0x80) << 24) | ((my_wc_t) (s[2] ^ 0x80) << 18) @@ -1702,12 +1711,12 @@ static int my_uni_utf8 (CHARSET_INFO *cs __attribute__((unused)) , if (r >= e) return MY_CS_TOOSMALL; - - if (wc < 0x80) + + if (wc < 0x80) count = 1; - else if (wc < 0x800) + else if (wc < 0x800) count = 2; - else if (wc < 0x10000) + else if (wc < 0x10000) count = 3; #ifdef UNICODE_32BIT else if (wc < 0x200000) @@ -1718,15 +1727,15 @@ static int my_uni_utf8 (CHARSET_INFO *cs __attribute__((unused)) , count = 6; #endif else return MY_CS_ILUNI; - - /* - e is a character after the string r, not the last character of it. + + /* + e is a character after the string r, not the last character of it. Because of it (r+count > e), not (r+count-1 >e ) */ - if ( r+count > e ) + if ( r+count > e ) return MY_CS_TOOSMALL; - - switch (count) { + + switch (count) { /* Fall through all cases!!! */ #ifdef UNICODE_32BIT case 6: r[5] = (uchar) (0x80 | (wc & 0x3f)); wc = wc >> 6; wc |= 0x4000000; @@ -1806,8 +1815,8 @@ static void my_casedn_str_utf8(CHARSET_INFO *cs, char * s) } -static int my_strnncoll_utf8(CHARSET_INFO *cs, - const uchar *s, uint slen, +static int my_strnncoll_utf8(CHARSET_INFO *cs, + const uchar *s, uint slen, const uchar *t, uint tlen, my_bool t_is_prefix) { @@ -1821,13 +1830,13 @@ static int my_strnncoll_utf8(CHARSET_INFO *cs, int plane; s_res=my_utf8_uni(cs,&s_wc, s, se); t_res=my_utf8_uni(cs,&t_wc, t, te); - + if ( s_res <= 0 || t_res <= 0 ) { - /* Incorrect string, compare by char value */ - return ((int)s[0]-(int)t[0]); + /* Incorrect string, compare byte by byte value */ + return bincmp(s, se, t, te); } - + plane=(s_wc>>8) & 0xFF; s_wc = uni_plane[plane] ? uni_plane[plane][s_wc & 0xFF].sort : s_wc; plane=(t_wc>>8) & 0xFF; @@ -1836,7 +1845,7 @@ static int my_strnncoll_utf8(CHARSET_INFO *cs, { return ((int) s_wc) - ((int) t_wc); } - + s+=s_res; t+=t_res; } @@ -1850,11 +1859,11 @@ static int my_strnncoll_utf8(CHARSET_INFO *cs, SYNOPSIS my_strnncollsp_utf8() - cs character set handler - a First string to compare - a_length Length of 'a' - b Second string to compare - b_length Length of 'b' + cs character set handler + a First string to compare + a_length Length of 'a' + b Second string to compare + b_length Length of 'b' IMPLEMENTATION If one string is shorter as the other, then we space extend the other @@ -1867,32 +1876,32 @@ static int my_strnncoll_utf8(CHARSET_INFO *cs, "a\0" < "a " RETURN - < 0 a < b - = 0 a == b - > 0 a > b + < 0 a < b + = 0 a == b + > 0 a > b */ -static int my_strnncollsp_utf8(CHARSET_INFO *cs, - const uchar *s, uint slen, - const uchar *t, uint tlen) +static int my_strnncollsp_utf8(CHARSET_INFO *cs, + const uchar *s, uint slen, + const uchar *t, uint tlen) { int s_res,t_res; my_wc_t s_wc,t_wc; const uchar *se= s+slen; const uchar *te= t+tlen; - + while ( s < se && t < te ) { int plane; s_res=my_utf8_uni(cs,&s_wc, s, se); t_res=my_utf8_uni(cs,&t_wc, t, te); - + if ( s_res <= 0 || t_res <= 0 ) { - /* Incorrect string, compare by char value */ - return ((int)s[0]-(int)t[0]); + /* Incorrect string, compare byte by byte value */ + return bincmp(s, se, t, te); } - + plane=(s_wc>>8) & 0xFF; s_wc = uni_plane[plane] ? uni_plane[plane][s_wc & 0xFF].sort : s_wc; plane=(t_wc>>8) & 0xFF; @@ -1901,14 +1910,14 @@ static int my_strnncollsp_utf8(CHARSET_INFO *cs, { return ((int) s_wc) - ((int) t_wc); } - + s+=s_res; t+=t_res; } - + slen= se-s; tlen= te-t; - + if (slen != tlen) { int swap= 0; @@ -1940,35 +1949,35 @@ static int my_strnncollsp_utf8(CHARSET_INFO *cs, static int my_strncasecmp_utf8(CHARSET_INFO *cs, - const char *s, const char *t, uint len) + const char *s, const char *t, uint len) { int s_res,t_res; my_wc_t s_wc,t_wc; const char *se=s+len; const char *te=t+len; - + while ( s < se && t < te ) { int plane; - + s_res=my_utf8_uni(cs,&s_wc, (const uchar*)s, (const uchar*)se); t_res=my_utf8_uni(cs,&t_wc, (const uchar*)t, (const uchar*)te); - + if ( s_res <= 0 || t_res <= 0 ) { - /* Incorrect string, compare by char value */ - return ((int)s[0]-(int)t[0]); + /* Incorrect string, compare byte by byte value */ + return bincmp(s, se, t, te); } - + plane=(s_wc>>8) & 0xFF; s_wc = uni_plane[plane] ? uni_plane[plane][s_wc & 0xFF].tolower : s_wc; plane=(t_wc>>8) & 0xFF; t_wc = uni_plane[plane] ? uni_plane[plane][t_wc & 0xFF].tolower : t_wc; - + if ( s_wc != t_wc ) return ((int) s_wc) - ((int) t_wc); - + s+=s_res; t+=t_res; } @@ -1983,9 +1992,9 @@ static int my_strcasecmp_utf8(CHARSET_INFO *cs, const char *s, const char *t) return my_strncasecmp_utf8(cs, s, t, len); } -static int my_strnxfrm_utf8(CHARSET_INFO *cs, - uchar *dst, uint dstlen, - const uchar *src, uint srclen) +static int my_strnxfrm_utf8(CHARSET_INFO *cs, + uchar *dst, uint dstlen, + const uchar *src, uint srclen) { my_wc_t wc; int res; @@ -2002,10 +2011,10 @@ static int my_strnxfrm_utf8(CHARSET_INFO *cs, } src+=res; srclen-=res; - + plane=(wc>>8) & 0xFF; wc = uni_plane[plane] ? uni_plane[plane][wc & 0xFF].sort : wc; - + if ((res=my_uni_utf8(cs,wc,dst,de)) <0) { break; @@ -2026,18 +2035,18 @@ static int my_mbcharlen_utf8(CHARSET_INFO *cs __attribute__((unused)) , uint c) { if (c < 0x80) return 1; - else if (c < 0xc2) + else if (c < 0xc2) return 0; /* Illegal mb head */ - else if (c < 0xe0) + else if (c < 0xe0) return 2; - else if (c < 0xf0) + else if (c < 0xf0) return 3; #ifdef UNICODE_32BIT - else if (c < 0xf8) + else if (c < 0xf8) return 4; - else if (c < 0xfc) + else if (c < 0xfc) return 5; - else if (c < 0xfe) + else if (c < 0xfe) return 6; #endif return 0; /* Illegal mb head */; @@ -2046,7 +2055,7 @@ static int my_mbcharlen_utf8(CHARSET_INFO *cs __attribute__((unused)) , uint c) static MY_COLLATION_HANDLER my_collation_ci_handler = { - NULL, /* init */ + NULL, /* init */ my_strnncoll_utf8, my_strnncollsp_utf8, my_strnxfrm_utf8, @@ -2059,13 +2068,14 @@ static MY_COLLATION_HANDLER my_collation_ci_handler = MY_CHARSET_HANDLER my_charset_utf8_handler= { - NULL, /* init */ + NULL, /* init */ my_ismbchar_utf8, my_mbcharlen_utf8, my_numchars_mb, my_charpos_mb, my_well_formed_len_mb, my_lengthsp_8bit, + my_numcells_mb, my_utf8_uni, my_uni_utf8, my_caseup_str_utf8, @@ -2088,27 +2098,27 @@ MY_CHARSET_HANDLER my_charset_utf8_handler= CHARSET_INFO my_charset_utf8_general_ci= { - 33,0,0, /* number */ - MY_CS_COMPILED|MY_CS_PRIMARY|MY_CS_STRNXFRM|MY_CS_UNICODE, /* state */ - "utf8", /* cs name */ - "utf8_general_ci", /* name */ - "", /* comment */ - NULL, /* tailoring */ - ctype_utf8, /* ctype */ - to_lower_utf8, /* to_lower */ - to_upper_utf8, /* to_upper */ - to_upper_utf8, /* sort_order */ - NULL, /* contractions */ - NULL, /* sort_order_big*/ - NULL, /* tab_to_uni */ - NULL, /* tab_from_uni */ - NULL, /* state_map */ - NULL, /* ident_map */ - 1, /* strxfrm_multiply */ - 1, /* mbminlen */ - 3, /* mbmaxlen */ - 0, /* min_sort_char */ - 255, /* max_sort_char */ + 33,0,0, /* number */ + MY_CS_COMPILED|MY_CS_PRIMARY|MY_CS_STRNXFRM|MY_CS_UNICODE, /* state */ + "utf8", /* cs name */ + "utf8_general_ci", /* name */ + "", /* comment */ + NULL, /* tailoring */ + ctype_utf8, /* ctype */ + to_lower_utf8, /* to_lower */ + to_upper_utf8, /* to_upper */ + to_upper_utf8, /* sort_order */ + NULL, /* contractions */ + NULL, /* sort_order_big*/ + NULL, /* tab_to_uni */ + NULL, /* tab_from_uni */ + NULL, /* state_map */ + NULL, /* ident_map */ + 1, /* strxfrm_multiply */ + 1, /* mbminlen */ + 3, /* mbmaxlen */ + 0, /* min_sort_char */ + 255, /* max_sort_char */ &my_charset_utf8_handler, &my_collation_ci_handler }; @@ -2116,27 +2126,27 @@ CHARSET_INFO my_charset_utf8_general_ci= CHARSET_INFO my_charset_utf8_bin= { - 83,0,0, /* number */ - MY_CS_COMPILED|MY_CS_BINSORT|MY_CS_UNICODE, /* state */ - "utf8", /* cs name */ - "utf8_bin", /* name */ - "", /* comment */ - NULL, /* tailoring */ - ctype_utf8, /* ctype */ - to_lower_utf8, /* to_lower */ - to_upper_utf8, /* to_upper */ - NULL, /* sort_order */ - NULL, /* contractions */ - NULL, /* sort_order_big*/ - NULL, /* tab_to_uni */ - NULL, /* tab_from_uni */ - NULL, /* state_map */ - NULL, /* ident_map */ - 1, /* strxfrm_multiply */ - 1, /* mbminlen */ - 3, /* mbmaxlen */ - 0, /* min_sort_char */ - 255, /* max_sort_char */ + 83,0,0, /* number */ + MY_CS_COMPILED|MY_CS_BINSORT|MY_CS_UNICODE, /* state */ + "utf8", /* cs name */ + "utf8_bin", /* name */ + "", /* comment */ + NULL, /* tailoring */ + ctype_utf8, /* ctype */ + to_lower_utf8, /* to_lower */ + to_upper_utf8, /* to_upper */ + NULL, /* sort_order */ + NULL, /* contractions */ + NULL, /* sort_order_big*/ + NULL, /* tab_to_uni */ + NULL, /* tab_from_uni */ + NULL, /* state_map */ + NULL, /* ident_map */ + 1, /* strxfrm_multiply */ + 1, /* mbminlen */ + 3, /* mbmaxlen */ + 0, /* min_sort_char */ + 255, /* max_sort_char */ &my_charset_utf8_handler, &my_collation_mb_bin_handler }; @@ -2154,8 +2164,8 @@ static void test_mb(CHARSET_INFO *cs, uchar *s) int len=my_mbcharlen_utf8(cs,*s); while(len--) { - printf("%c",*s); - s++; + printf("%c",*s); + s++; } printf("\n"); } @@ -2171,23 +2181,23 @@ int main() { char str[1024]=" utf8 test проба ПЕРА по-РУССКИ"; CHARSET_INFO *cs; - + test_mb(cs,(uchar*)str); - + printf("orig :'%s'\n",str); - + my_caseup_utf8(cs,str,15); printf("caseup :'%s'\n",str); - + my_caseup_str_utf8(cs,str); printf("caseup_str:'%s'\n",str); - + my_casedn_utf8(cs,str,15); printf("casedn :'%s'\n",str); - + my_casedn_str_utf8(cs,str); printf("casedn_str:'%s'\n",str); - + return 0; } diff --git a/strings/my_vsnprintf.c b/strings/my_vsnprintf.c index 71b5f345fda..268f7d18f2a 100644 --- a/strings/my_vsnprintf.c +++ b/strings/my_vsnprintf.c @@ -33,17 +33,6 @@ length of result string */ -int my_snprintf(char* to, size_t n, const char* fmt, ...) -{ - int result; - va_list args; - va_start(args,fmt); - result= my_vsnprintf(to, n, fmt, args); - va_end(args); - return result; -} - - int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap) { char *start=to, *end=to+n-1; @@ -141,6 +130,15 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap) return (uint) (to - start); } +int my_snprintf(char* to, size_t n, const char* fmt, ...) +{ + int result; + va_list args; + va_start(args,fmt); + result= my_vsnprintf(to, n, fmt, args); + va_end(args); + return result; +} #ifdef MAIN #define OVERRUN_SENTRY 250 diff --git a/strings/strto.c b/strings/strto.c index 52efec6e087..9e10b935834 100644 --- a/strings/strto.c +++ b/strings/strto.c @@ -35,8 +35,12 @@ it can be compiled with the UNSIGNED and/or LONGLONG flag set */ -#include <my_global.h> -#include "m_string.h" + +#if !defined(_global_h) || !defined(_m_string_h) +# error Calling file must include 'my_global.h' and 'm_string.h' + /* see 'strtoll.c' and 'strtoull.c' for the reasons */ +#endif + #include "m_ctype.h" #include "my_sys.h" /* defines errno */ #include <errno.h> diff --git a/strings/strtol.c b/strings/strtol.c index 10d7f8f9da6..ed4ca86c846 100644 --- a/strings/strtol.c +++ b/strings/strtol.c @@ -14,9 +14,16 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* This defines strtol() if neaded */ +/* This implements strtol() if needed */ +/* + These includes are mandatory because they check for type sizes and + functions, especially they handle tricks for Tru64 where 'long' is + 64 bit already and our 'longlong' is just a 'long'. + */ #include <my_global.h> +#include <m_string.h> + #if !defined(MSDOS) && !defined(HAVE_STRTOL) && !defined(__WIN__) #include "strto.c" #endif diff --git a/strings/strtoll.c b/strings/strtoll.c index b0b4ef328fc..45352ffd360 100644 --- a/strings/strtoll.c +++ b/strings/strtoll.c @@ -14,11 +14,20 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* This is defines strtoll() if neaded */ +/* This implements strtoll() if needed */ -#define strtoll glob_strtoll /* Fix for True64 */ +/* + These includes are mandatory because they check for type sizes and + functions, especially they handle tricks for Tru64 where 'long' is + 64 bit already and our 'longlong' is just a 'long'. + This solves a problem on Tru64 where the C99 compiler has a prototype + for 'strtoll()' but no implementation, see "6.1 New C99 library functions" + in file '/usr/share/doclib/cc.dtk/release_notes.txt'. + */ #include <my_global.h> +#include <m_string.h> + #if !defined(HAVE_STRTOLL) && defined(HAVE_LONG_LONG) #define USE_LONGLONG #include "strto.c" diff --git a/strings/strtoul.c b/strings/strtoul.c index 00e1f820942..32a7bc62298 100644 --- a/strings/strtoul.c +++ b/strings/strtoul.c @@ -14,9 +14,16 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* This is defines strtoul() if neaded */ +/* This implements strtol() if needed */ +/* + These includes are mandatory because they check for type sizes and + functions, especially they handle tricks for Tru64 where 'long' is + 64 bit already and our 'longlong' is just a 'long'. + */ #include <my_global.h> +#include <m_string.h> + #if !defined(MSDOS) && !defined(HAVE_STRTOUL) #define USE_UNSIGNED #include "strto.c" diff --git a/strings/strtoull.c b/strings/strtoull.c index f4f3ce19bf7..0c2788bc188 100644 --- a/strings/strtoull.c +++ b/strings/strtoull.c @@ -14,9 +14,20 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* This is defines strtoull() */ +/* This implements strtoull() if needed */ + +/* + These includes are mandatory because they check for type sizes and + functions, especially they handle tricks for Tru64 where 'long' is + 64 bit already and our 'longlong' is just a 'long'. + This solves a problem on Tru64 where the C99 compiler has a prototype + for 'strtoull()' but no implementation, see "6.1 New C99 library functions" + in file '/usr/share/doclib/cc.dtk/release_notes.txt'. + */ #include <my_global.h> +#include <m_string.h> + #if !defined(HAVE_STRTOULL) && defined(HAVE_LONG_LONG) #define USE_UNSIGNED #define USE_LONGLONG diff --git a/strings/utr11-dump.c b/strings/utr11-dump.c new file mode 100644 index 00000000000..c1b5a923946 --- /dev/null +++ b/strings/utr11-dump.c @@ -0,0 +1,112 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + + +/* + Dump an EastAsianWidth.txt file. + See http://www.unicode.org/reports/tr11/ for details. + Character types: + F - Full width = 1 + H - Half width = 0 + W - Wide = 1 + Na - Narrow = 0 + A - Ambiguous = 0 + N - Neutral = 0 +*/ + + +int main(int ac, char **av) +{ + char str[128]; + int errors= 0; + int plane[0x10000]; + int page[256]; + int i; + + memset(plane, 0, sizeof(plane)); + memset(page, 0, sizeof(page)); + + while (fgets(str, sizeof(str), stdin)) + { + int code1, code2, width; + char *end; + + if (str[0] == '#') + continue; + code1= strtol(str, &end, 16); + if (code1 < 0 || code1 > 0xFFFF) + continue; + if (end[0] == ';') /* One character */ + { + code2= code1; + } + else if (end[0] == '.' && end[1] == '.') /* Range */ + { + end+= 2; + code2= strtol(end, &end, 16); + if (code2 < 0 || code2 > 0xFFFF) + continue; + if (end[0] != ';') + { + errors++; + fprintf(stderr, "error: %s", str); + continue; + } + } + else + { + errors++; + fprintf(stderr, "error: %s", str); + continue; + } + + end++; + width= (end[0] == 'F' || end[0] == 'W') ? 1 : 0; + + for ( ; code1 <= code2; code1++) + { + plane[code1]= width; + } + } + + if (errors) + return 1; + + for (i=0; i < 256; i++) + { + int j; + int *p= plane + 256 * i; + page[i]= 0; + for (j=0; j < 256; j++) + { + page[i]+= p[j]; + } + if (page[i] != 0 && page[i] != 256) + { + printf("static char pg%02X[256]=\n{\n", i); + for (j=0; j < 256; j++) + { + printf("%d%s%s", p[j], j < 255 ? "," : "", (j + 1) % 32 ? "" : "\n"); + } + printf("};\n\n"); + } + } + + printf("static struct {int page; char *p;} utr11_data[256]=\n{\n"); + for (i=0; i < 256; i++) + { + if (page[i] == 0 || page[i] == 256) + { + int width= (page[i] == 256) ? 1 : 0; + printf("{%d,NULL}", width); + } + else + { + printf("{0,pg%02X}", i); + } + printf("%s%s", i < 255 ? "," : "", (i+1) % 8 ? "" : "\n"); + } + printf("};\n"); + return 0; +} diff --git a/support-files/Makefile.am b/support-files/Makefile.am index 196da3d8744..7ae1071f9ec 100644 --- a/support-files/Makefile.am +++ b/support-files/Makefile.am @@ -22,6 +22,7 @@ EXTRA_DIST = mysql.spec.sh \ my-medium.cnf.sh \ my-large.cnf.sh \ my-huge.cnf.sh \ + my-innodb-heavy-4G.cnf.sh \ mysql-log-rotate.sh \ mysql.server.sh \ binary-configure.sh \ @@ -34,6 +35,7 @@ pkgdata_DATA = my-small.cnf \ my-medium.cnf \ my-large.cnf \ my-huge.cnf \ + my-innodb-heavy-4G.cnf \ mysql-log-rotate \ mysql-@VERSION@.spec \ MySQL-shared-compat.spec @@ -44,6 +46,7 @@ CLEANFILES = my-small.cnf \ my-medium.cnf \ my-large.cnf \ my-huge.cnf \ + my-innodb-heavy-4G.cnf \ mysql.spec \ mysql-@VERSION@.spec \ mysql-log-rotate \ diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 6ec05433bef..e7f8a035a15 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -156,7 +156,7 @@ Summary: MySQL - server with Berkeley DB, RAID and UDF support Group: Applications/Databases Provides: mysql-Max Obsoletes: mysql-Max -Requires: MySQL >= 4.0 +Requires: MySQL-server >= 4.0 %description Max Optional MySQL server binary that supports additional features like @@ -594,8 +594,13 @@ fi %attr(644, root, root) %{_libdir}/mysql/libmysqld.a # The spec file changelog only includes changes made to the spec file -# itself +# itself - note that they must be ordered by date (important when +# merging BK trees) %changelog +* Thu Aug 26 2004 Lenz Grimmer <lenz@mysql.com> + +- MySQL-Max now requires MySQL-server instead of MySQL (BUG 3860) + * Fri Aug 20 2004 Lenz Grimmer <lenz@mysql.com> - do not link statically on IA64/AMD64 as these systems do not have diff --git a/tests/client_test.c b/tests/client_test.c index de77d4517dd..552e49ec862 100644 --- a/tests/client_test.c +++ b/tests/client_test.c @@ -1790,7 +1790,7 @@ static void test_ps_conj_select() MYSQL_STMT *stmt; int rc; MYSQL_BIND bind[2]; - long int int_data; + int32 int_data; char str_data[32]; unsigned long str_length; myheader("test_ps_conj_select"); @@ -3227,7 +3227,7 @@ static void bind_fetch(int row_count) { MYSQL_STMT *stmt; int rc, i, count= row_count; - long data[10]; + int32 data[10]; int8 i8_data; int16 i16_data; int32 i32_data; @@ -4546,7 +4546,7 @@ static void test_multi_stmt() MYSQL_STMT *stmt, *stmt1, *stmt2; int rc; - ulong id; + uint32 id; char name[50]; MYSQL_BIND bind[2]; ulong length[2]; @@ -4605,7 +4605,7 @@ static void test_multi_stmt() rc= mysql_stmt_fetch(stmt); check_execute(stmt, rc); - fprintf(stdout, "\n int_data: %lu(%lu)", id, length[0]); + fprintf(stdout, "\n int_data: %lu(%lu)", (ulong) id, length[0]); fprintf(stdout, "\n str_data: %s(%lu)", name, length[1]); assert(id == 10); assert(strcmp(name, "mysql") == 0); @@ -4634,7 +4634,7 @@ static void test_multi_stmt() rc= mysql_stmt_fetch(stmt); check_execute(stmt, rc); - fprintf(stdout, "\n int_data: %lu(%lu)", id, length[0]); + fprintf(stdout, "\n int_data: %lu(%lu)", (ulong) id, length[0]); fprintf(stdout, "\n str_data: %s(%lu)", name, length[1]); assert(id == 10); assert(strcmp(name, "updated") == 0); @@ -5042,7 +5042,7 @@ static void test_store_result() { MYSQL_STMT *stmt; int rc; - long nData; + int32 nData; char szData[100]; MYSQL_BIND bind[2]; ulong length, length1; @@ -5094,7 +5094,7 @@ static void test_store_result() rc= mysql_stmt_fetch(stmt); check_execute(stmt, rc); - fprintf(stdout, "\n row 1: %ld, %s(%lu)", nData, szData, length1); + fprintf(stdout, "\n row 1: %ld, %s(%lu)", (long) nData, szData, length1); assert(nData == 10); assert(strcmp(szData, "venu") == 0); assert(length1 == 4); @@ -5102,7 +5102,7 @@ static void test_store_result() rc= mysql_stmt_fetch(stmt); check_execute(stmt, rc); - fprintf(stdout, "\n row 2: %ld, %s(%lu)", nData, szData, length1); + fprintf(stdout, "\n row 2: %ld, %s(%lu)", (long) nData, szData, length1); assert(nData == 20); assert(strcmp(szData, "mysql") == 0); assert(length1 == 5); @@ -5129,7 +5129,7 @@ static void test_store_result() rc= mysql_stmt_fetch(stmt); check_execute(stmt, rc); - fprintf(stdout, "\n row 1: %ld, %s(%lu)", nData, szData, length1); + fprintf(stdout, "\n row 1: %ld, %s(%lu)", (long) nData, szData, length1); assert(nData == 10); assert(strcmp(szData, "venu") == 0); assert(length1 == 4); @@ -5137,7 +5137,7 @@ static void test_store_result() rc= mysql_stmt_fetch(stmt); check_execute(stmt, rc); - fprintf(stdout, "\n row 2: %ld, %s(%lu)", nData, szData, length1); + fprintf(stdout, "\n row 2: %ld, %s(%lu)", (long) nData, szData, length1); assert(nData == 20); assert(strcmp(szData, "mysql") == 0); assert(length1 == 5); @@ -5984,7 +5984,7 @@ static void test_ushort_bug() MYSQL_STMT *stmt; MYSQL_BIND bind[4]; ushort short_value; - ulong long_value; + uint32 long_value; ulong s_length, l_length, ll_length, t_length; ulonglong longlong_value; int rc; @@ -6038,7 +6038,7 @@ static void test_ushort_bug() check_execute(stmt, rc); fprintf(stdout, "\n ushort : %d (%ld)", short_value, s_length); - fprintf(stdout, "\n ulong : %ld (%ld)", long_value, l_length); + fprintf(stdout, "\n ulong : %lu (%ld)", (ulong) long_value, l_length); fprintf(stdout, "\n longlong : %lld (%ld)", longlong_value, ll_length); fprintf(stdout, "\n tinyint : %d (%ld)", tiny_value, t_length); @@ -6068,7 +6068,7 @@ static void test_sshort_bug() MYSQL_STMT *stmt; MYSQL_BIND bind[4]; short short_value; - long long_value; + int32 long_value; ulong s_length, l_length, ll_length, t_length; ulonglong longlong_value; int rc; @@ -6122,7 +6122,7 @@ static void test_sshort_bug() check_execute(stmt, rc); fprintf(stdout, "\n sshort : %d (%ld)", short_value, s_length); - fprintf(stdout, "\n slong : %ld (%ld)", long_value, l_length); + fprintf(stdout, "\n slong : %ld (%ld)", (long) long_value, l_length); fprintf(stdout, "\n longlong : %lld (%ld)", longlong_value, ll_length); fprintf(stdout, "\n tinyint : %d (%ld)", tiny_value, t_length); @@ -6152,7 +6152,7 @@ static void test_stiny_bug() MYSQL_STMT *stmt; MYSQL_BIND bind[4]; short short_value; - long long_value; + int32 long_value; ulong s_length, l_length, ll_length, t_length; ulonglong longlong_value; int rc; @@ -6206,7 +6206,7 @@ static void test_stiny_bug() check_execute(stmt, rc); fprintf(stdout, "\n sshort : %d (%ld)", short_value, s_length); - fprintf(stdout, "\n slong : %ld (%ld)", long_value, l_length); + fprintf(stdout, "\n slong : %ld (%ld)", (long) long_value, l_length); fprintf(stdout, "\n longlong : %lld (%ld)", longlong_value, ll_length); fprintf(stdout, "\n tinyint : %d (%ld)", tiny_value, t_length); @@ -7251,7 +7251,7 @@ static void test_fetch_seek() MYSQL_BIND bind[3]; MYSQL_ROW_OFFSET row; int rc; - long c1; + int32 c1; char c2[11], c3[20]; myheader("test_fetch_seek"); @@ -7296,7 +7296,7 @@ static void test_fetch_seek() rc= mysql_stmt_fetch(stmt); check_execute(stmt, rc); - fprintf(stdout, "\n row 0: %ld, %s, %s", c1, c2, c3); + fprintf(stdout, "\n row 0: %ld, %s, %s", (long) c1, c2, c3); row= mysql_stmt_row_tell(stmt); @@ -7305,21 +7305,21 @@ static void test_fetch_seek() rc= mysql_stmt_fetch(stmt); check_execute(stmt, rc); - fprintf(stdout, "\n row 2: %ld, %s, %s", c1, c2, c3); + fprintf(stdout, "\n row 2: %ld, %s, %s", (long) c1, c2, c3); row= mysql_stmt_row_seek(stmt, row); rc= mysql_stmt_fetch(stmt); check_execute(stmt, rc); - fprintf(stdout, "\n row 2: %ld, %s, %s", c1, c2, c3); + fprintf(stdout, "\n row 2: %ld, %s, %s", (long) c1, c2, c3); mysql_stmt_data_seek(stmt, 0); rc= mysql_stmt_fetch(stmt); check_execute(stmt, rc); - fprintf(stdout, "\n row 0: %ld, %s, %s", c1, c2, c3); + fprintf(stdout, "\n row 0: %ld, %s, %s", (long) c1, c2, c3); rc= mysql_stmt_fetch(stmt); check_execute(stmt, rc); @@ -8050,7 +8050,7 @@ static void test_bug1500() MYSQL_STMT *stmt; MYSQL_BIND bind[3]; int rc; - long int_data[3]= {2, 3, 4}; + int32 int_data[3]= {2, 3, 4}; const char *data; myheader("test_bug1500"); @@ -8836,7 +8836,7 @@ static void test_multi() char *query; MYSQL_BIND bind[1]; int rc, i; - long param= 1; + int32 param= 1; ulong length= 1; myheader("test_multi"); @@ -8888,11 +8888,11 @@ static void test_multi() rc= mysql_stmt_execute(stmt_update); check_execute(stmt_update, rc); - fprintf(stdout, "update %ld\n", param); + fprintf(stdout, "update %ld\n", (long) param); rc= mysql_stmt_execute(stmt_delete); check_execute(stmt_delete, rc); - fprintf(stdout, "delete %ld\n", param); + fprintf(stdout, "delete %ld\n", (long) param); rc= mysql_stmt_execute(stmt_select1); check_execute(stmt_select1, rc); @@ -8966,9 +8966,9 @@ static void test_bind_nagative() char *query; int rc; MYSQL_BIND bind[1]; - long my_val= 0L; + int32 my_val= 0; ulong my_length= 0L; - long my_null= 0L; + my_bool my_null= FALSE; myheader("test_insert_select"); rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1"); @@ -9010,9 +9010,9 @@ static void test_derived() MYSQL_STMT *stmt; int rc, i; MYSQL_BIND bind[1]; - long my_val= 0L; + int32 my_val= 0; ulong my_length= 0L; - long my_null= 0L; + my_bool my_null= FALSE; const char *query= "select count(1) from (select f.id from t1 f where f.id=?) as x"; @@ -9520,7 +9520,7 @@ static void test_union_param() MYSQL_BIND bind[2]; char my_val[4]; ulong my_length= 3L; - long my_null= 0L; + my_bool my_null= FALSE; myheader("test_union_param"); strcpy(my_val, "abc"); @@ -9904,7 +9904,7 @@ static void test_bug4079() MYSQL_STMT *stmt; MYSQL_BIND bind[1]; const char *stmt_text; - unsigned long res; + uint32 res; int rc; myheader("test_bug4079"); @@ -10044,6 +10044,53 @@ static void test_bug4030() } +static void test_bug5126() +{ + MYSQL_STMT *stmt; + MYSQL_BIND bind[2]; + int32 c1, c2; + const char *stmt_text; + int rc; + + myheader("test_bug5126"); + + stmt_text= "DROP TABLE IF EXISTS t1"; + rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); + myquery(rc); + + stmt_text= "CREATE TABLE t1 (a mediumint, b int)"; + rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); + myquery(rc); + + stmt_text= "INSERT INTO t1 VALUES (8386608, 1)"; + rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); + myquery(rc); + + stmt= mysql_stmt_init(mysql); + stmt_text= "SELECT a, b FROM t1"; + rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); + check_execute(stmt, rc); + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + + /* Bind output buffers */ + bzero(bind, sizeof(bind)); + + bind[0].buffer_type= MYSQL_TYPE_LONG; + bind[0].buffer= &c1; + bind[1].buffer_type= MYSQL_TYPE_LONG; + bind[1].buffer= &c2; + + mysql_stmt_bind_result(stmt, bind); + + rc= mysql_stmt_fetch(stmt); + assert(rc == 0); + assert(c1 == 8386608 && c2 == 1); + printf("%ld, %ld\n", (long) c1, (long) c2); + mysql_stmt_close(stmt); +} + + /* Read and parse arguments and MySQL options from my.cnf */ @@ -10142,7 +10189,7 @@ static void get_options(int argc, char **argv) int ho_error; if ((ho_error= handle_options(&argc, &argv, client_test_long_options, - get_one_option))) + get_one_option, 0))) exit(ho_error); if (tty_password) @@ -10341,6 +10388,7 @@ int main(int argc, char **argv) test_bug4236(); /* init -> execute */ test_bug4030(); /* test conversion string -> time types in libmysql */ + test_bug5126(); /* support for mediumint type in libmysql */ /* XXX: PLEASE RUN THIS PROGRAM UNDER VALGRIND AND VERIFY THAT YOUR TEST DOESN'T CONTAIN WARNINGS/ERRORS BEFORE YOU PUSH. diff --git a/tools/mysqlmanager.c b/tools/mysqlmanager.c index bb0a76d6c49..36a8b2f394c 100644 --- a/tools/mysqlmanager.c +++ b/tools/mysqlmanager.c @@ -1335,7 +1335,7 @@ static int parse_args(int argc, char **argv) { int ho_error; - if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) + if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option, NULL))) exit(ho_error); return 0; |