diff --git a/.bzrignore b/.bzrignore index d92477463ed..73cb4341beb 100644 --- a/.bzrignore +++ b/.bzrignore @@ -384,6 +384,7 @@ client/sql_string.cpp client/ssl_test client/thimble client/thread_test +client/tmp.diff client_debug/* client_release/* client_test @@ -1330,10 +1331,12 @@ mysql-test/r/slave-running.eval mysql-test/r/slave-stopped.eval mysql-test/r/symlink.log mysql-test/r/system_mysql_db.log +mysql-test/r/tmp.result mysql-test/r/udf.log mysql-test/share/mysql mysql-test/std_data/*.pem mysql-test/t/index_merge.load +mysql-test/t/tmp.test mysql-test/var mysql-test/var/* mysql.kdevprj diff --git a/BitKeeper/etc/collapsed b/BitKeeper/etc/collapsed index f934fa44580..a10f87c8529 100644 --- a/BitKeeper/etc/collapsed +++ b/BitKeeper/etc/collapsed @@ -16,7 +16,17 @@ 45214a07hVsIGwvwa-WrO-jpeaSwVw 452a92d0-31-8wSzSfZi165fcGcXPA 454a7ef8gdvE_ddMlJyghvOAkKPNOQ +454bb488ijVLOUK_GFjcoISE0GxPUA +454bb9a8AwlGRC_wWLS2sNMoRBMRGw +454c946ciQoR4dfTBZ0RTBmGJKp6lw +454f6e7eAnfLD9OCbGr5X9KiKvfKcQ +454f704bJiJy0_Nx2drY9P5kK3uOzg 454f8960jsVT_kMKJtZ9OCgXoba0xQ +454fa71cxshxszXJQYa9jbo0-_hAHw +4550b0ceIcozdgQhWFUTAtWkN196lA +4554a95d7txO1DuO9G3nAizI3SkFAA +4554b3722d71SbPiI2Gx-RhbZjmuIQ +4558b3d73Cxjlb7Wv1oytdSTthxDfw 4561b2ecZbhuAc0TTDdCdultxUYaMw 4561bde4qWhz1I8tkItXKex5uniipA 4562ba016dYH0JzszOqZ8p6psbKfnQ diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index b2b734a48f4..c3dd57f098b 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -65,8 +65,8 @@ TARGET_LINK_LIBRARIES(mysqldump mysqlclient mysys dbug yassl taocrypt zlib wsock ADD_EXECUTABLE(mysqlimport mysqlimport.c) TARGET_LINK_LIBRARIES(mysqlimport mysqlclient mysys dbug yassl taocrypt zlib wsock32) -ADD_EXECUTABLE(mysql_upgrade mysql_upgrade.c) -TARGET_LINK_LIBRARIES(mysql_upgrade mysqlclient mysys dbug yassl taocrypt zlib wsock32) +ADD_EXECUTABLE(mysql_upgrade mysql_upgrade.c ../mysys/my_getpagesize.c) +TARGET_LINK_LIBRARIES(mysql_upgrade mysqlclient dbug yassl taocrypt zlib wsock32) ADD_EXECUTABLE(mysqlshow mysqlshow.c) TARGET_LINK_LIBRARIES(mysqlshow mysqlclient mysys dbug yassl taocrypt zlib wsock32) diff --git a/client/Makefile.am b/client/Makefile.am index 7d48e34b37b..9c3861483bf 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -1,84 +1,102 @@ # Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult 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 # This file is public domain and comes with NO WARRANTY of any kind -if HAVE_YASSL - yassl_dummy_link_fix= $(top_srcdir)/extra/yassl/src/dummy.cpp -else - yassl_dummy_link_fix= -endif - if THREAD_SAFE_CLIENT LIBMYSQLCLIENT_LA = $(top_builddir)/libmysql_r/libmysqlclient_r.la else LIBMYSQLCLIENT_LA = $(top_builddir)/libmysql/libmysqlclient.la endif -#AUTOMAKE_OPTIONS = nostdinc INCLUDES = -I$(top_builddir)/include \ -I$(top_srcdir)/include \ -I$(top_srcdir)/regex \ $(openssl_includes) + LIBS = @CLIENT_LIBS@ + LDADD= @CLIENT_EXTRA_LDFLAGS@ $(CLIENT_THREAD_LIBS) \ $(top_builddir)/libmysql/libmysqlclient.la -bin_PROGRAMS = mysql mysqladmin mysqlcheck mysqlshow \ - mysqldump mysqlimport mysqltest mysqlbinlog \ - mysqlslap mysql_upgrade + noinst_HEADERS = sql_string.h completion_hash.h my_readline.h \ client_priv.h -mysql_SOURCES = mysql.cc readline.cc sql_string.cc completion_hash.cc + +EXTRA_DIST = get_password.c CMakeLists.txt + +bin_PROGRAMS = mysql \ + mysqladmin \ + mysqlbinlog \ + mysqlcheck \ + mysqldump \ + mysqlimport \ + mysqlshow \ + mysqlslap \ + mysqltest \ + mysql_upgrade + +mysql_SOURCES = mysql.cc readline.cc sql_string.cc \ + completion_hash.cc +mysql_LDADD = @readline_link@ @TERMCAP_LIB@ \ + $(LDADD) $(CXXLDFLAGS) mysqladmin_SOURCES = mysqladmin.cc -mysql_LDADD = @readline_link@ @TERMCAP_LIB@ $(LDADD) $(CXXLDFLAGS) -mysqltest_SOURCES= mysqltest.c $(top_srcdir)/mysys/my_getsystime.c \ - $(yassl_dummy_link_fix) -mysqltest_LDADD = $(top_builddir)/regex/libregex.a $(LDADD) \ - $(top_builddir)/mysys/libmysys.a -mysqlbinlog_SOURCES = mysqlbinlog.cc $(top_srcdir)/mysys/mf_tempdir.c \ + +mysqlbinlog_SOURCES = mysqlbinlog.cc \ + $(top_srcdir)/mysys/mf_tempdir.c \ $(top_srcdir)/mysys/my_new.cc \ $(top_srcdir)/mysys/my_bit.c \ $(top_srcdir)/mysys/my_bitmap.c \ $(top_srcdir)/mysys/my_vle.c \ $(top_srcdir)/mysys/base64.c mysqlbinlog_LDADD = $(LDADD) $(CXXLDFLAGS) -mysqlslap_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \ - @CLIENT_EXTRA_LDFLAGS@ \ - $(LIBMYSQLCLIENT_LA) \ - $(top_builddir)/mysys/libmysys.a + +mysqldump_SOURCES= mysqldump.c \ + my_user.c \ + $(top_srcdir)/mysys/mf_getdate.c + +mysqlimport_SOURCES= mysqlimport.c + mysqlimport_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \ @CLIENT_EXTRA_LDFLAGS@ \ $(LIBMYSQLCLIENT_LA) \ - $(top_builddir)/mysys/libmysys.a -mysqlcheck_SOURCES= mysqlcheck.c $(yassl_dummy_link_fix) -mysqlshow_SOURCES= mysqlshow.c $(yassl_dummy_link_fix) -mysqlslap_SOURCES= mysqlslap.c $(yassl_dummy_link_fix) -mysqldump_SOURCES= mysqldump.c my_user.c \ - $(top_srcdir)/mysys/mf_getdate.c \ - $(yassl_dummy_link_fix) -mysqlimport_SOURCES= mysqlimport.c $(yassl_dummy_link_fix) -mysql_upgrade_SOURCES= mysql_upgrade.c $(yassl_dummy_link_fix) -sql_src=log_event.h mysql_priv.h log_event.cc my_decimal.h my_decimal.cc -strings_src=decimal.c + $(top_builddir)/mysys/libmysys.a + +mysqlshow_SOURCES= mysqlshow.c + +mysqlslap_SOURCES= mysqlslap.c +mysqlslap_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \ + @CLIENT_EXTRA_LDFLAGS@ \ + $(LIBMYSQLCLIENT_LA) \ + $(top_builddir)/mysys/libmysys.a + +mysqltest_SOURCES= mysqltest.c \ + $(top_srcdir)/mysys/my_getsystime.c \ + $(top_srcdir)/mysys/my_copy.c +mysqltest_LDADD = $(top_builddir)/regex/libregex.a $(LDADD) + +mysql_upgrade_SOURCES= mysql_upgrade.c \ + $(top_srcdir)/mysys/my_getpagesize.c # Fix for mit-threads DEFS = -DUNDEF_THREADS_HACK \ -DDEFAULT_MYSQL_HOME="\"$(prefix)\"" \ - -DDATADIR="\"$(localstatedir)\"" -EXTRA_DIST = get_password.c CMakeLists.txt + -DDATADIR="\"$(localstatedir)\"" + +sql_src=log_event.h mysql_priv.h log_event.cc my_decimal.h my_decimal.cc +strings_src=decimal.c link_sources: for f in $(sql_src) ; do \ @@ -92,6 +110,5 @@ link_sources: rm -f $(srcdir)/my_user.c; \ @LN_CP_F@ $(top_srcdir)/sql-common/my_user.c my_user.c; - # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/client/mysql.cc b/client/mysql.cc index 5269cb9b26c..603d7720e1e 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -829,10 +829,23 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), default_charset_used= 1; break; case OPT_DELIMITER: - if (argument == disabled_my_option) + if (argument == disabled_my_option) + { strmov(delimiter, DEFAULT_DELIMITER); - else - strmake(delimiter, argument, sizeof(delimiter) - 1); + } + else + { + /* Check that delimiter does not contain a backslash */ + if (!strstr(argument, "\\")) + { + strmake(delimiter, argument, sizeof(delimiter) - 1); + } + else + { + put_info("DELIMITER cannot contain a backslash character", INFO_ERROR); + return 0; + } + } delimiter_length= (uint)strlen(delimiter); delimiter_str= delimiter; break; @@ -3032,6 +3045,14 @@ com_delimiter(String *buffer __attribute__((unused)), char *line) INFO_ERROR); return 0; } + else + { + if (strstr(tmp, "\\")) + { + put_info("DELIMITER cannot contain a backslash character", INFO_ERROR); + return 0; + } + } strmake(delimiter, tmp, sizeof(delimiter) - 1); delimiter_length= (int)strlen(delimiter); delimiter_str= delimiter; diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 46862dd1da6..411d3029c14 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -31,10 +31,12 @@ const char *mysqlcheck_name= "mysqlcheck.exe"; const char *mysql_name= "mysql.exe"; const char *mysqld_name= "mysqld.exe"; +#define EXTRA_CLIENT_PATHS "client/release", "client/debug" #else const char *mysqlcheck_name= "mysqlcheck"; const char *mysql_name= "mysql"; const char *mysqld_name= "mysqld"; +#define EXTRA_CLIENT_PATHS "client" #endif /*__WIN__*/ extern TYPELIB sql_protocol_typelib; @@ -499,8 +501,9 @@ int main(int argc, char **argv) "mysql", NullS)) { ret= 1; - puts("Can't find data directory. Please restart with" - " --datadir=path-to-writable-data-dir"); + fprintf(stderr, + "Can't find data directory. Please restart with" + " --datadir=path-to-writable-data-dir"); goto error; } @@ -543,11 +546,13 @@ int main(int argc, char **argv) } if (find_file(mysqlcheck_name, basedir, MYF(0), path, sizeof(path), - "bin", NullS)) + "bin", EXTRA_CLIENT_PATHS, NullS)) { ret= 1; - printf("Can't find program '%s'\n", mysqlcheck_name); - puts("Please restart with --basedir=mysql-install-directory"); + fprintf(stderr, + "Can't find program '%s'\n" + "Please restart with --basedir=mysql-install-directory", + mysqlcheck_name); goto error; } else @@ -569,7 +574,7 @@ int main(int argc, char **argv) ret= system(cmdline.str); if (ret) { - printf("Error executing '%s'\n", cmdline.str); + fprintf(stderr, "Error executing '%s'\n", cmdline.str); goto error; } @@ -580,12 +585,13 @@ int main(int argc, char **argv) fix_priv_tables: if (find_file(mysql_name, basedir, MYF(0), path, sizeof(path), - "bin", NullS)) + "bin", EXTRA_CLIENT_PATHS, NullS)) { ret= 1; - puts("Could not find MySQL command-line client (mysql).\n" - "Please use --basedir to specify the directory" - " where MySQL is installed."); + fprintf(stderr, + "Could not find MySQL command-line client (mysql).\n" + "Please use --basedir to specify the directory" + " where MySQL is installed."); goto error; } else @@ -593,16 +599,17 @@ fix_priv_tables: if (find_file(MYSQL_FIX_PRIV_TABLES_NAME, basedir, MYF(0), path, sizeof(path), - "support_files", "share/mysql", "scripts", + "support_files", "share", "share/mysql", "scripts", NullS) && find_file(MYSQL_FIX_PRIV_TABLES_NAME, "/usr/local/mysql", MYF(0), path, sizeof(path), "share/mysql", NullS)) { ret= 1; - puts("Could not find file " MYSQL_FIX_PRIV_TABLES_NAME "\n" - "Please use --basedir to specify the directory" - " where MySQL is installed"); + fprintf(stderr, + "Could not find file " MYSQL_FIX_PRIV_TABLES_NAME "\n" + "Please use --basedir to specify the directory" + " where MySQL is installed"); goto error; } else @@ -623,7 +630,7 @@ fix_priv_tables: ret= system(cmdline.str); if (ret) - printf("Error executing '%s'\n", cmdline.str); + fprintf(stderr, "Error executing '%s'\n", cmdline.str); error: dynstr_free(&cmdline); diff --git a/client/mysqltest.c b/client/mysqltest.c index 284dc8307af..8de3022c4fe 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -32,7 +32,7 @@ Holyfoot */ -#define MTEST_VERSION "3.0" +#define MTEST_VERSION "3.1" #include <my_global.h> #include <mysql_embed.h> @@ -275,6 +275,7 @@ enum enum_commands { Q_DISABLE_PARSING, Q_ENABLE_PARSING, Q_REPLACE_REGEX, Q_REMOVE_FILE, Q_FILE_EXIST, Q_WRITE_FILE, Q_COPY_FILE, Q_PERL, Q_DIE, Q_EXIT, + Q_CHMOD_FILE, Q_UNKNOWN, /* Unknown command. */ Q_COMMENT, /* Comments, ignored. */ @@ -357,6 +358,7 @@ const char *command_names[]= "die", /* Don't execute any more commands, compare result */ "exit", + "chmod", 0 }; @@ -1811,6 +1813,46 @@ void do_copy_file(struct st_command *command) } +/* + SYNOPSIS + do_chmod_file + command command handle + + DESCRIPTION + chmod <octal> <file> + Change file permission of <file> + +*/ + +void do_chmod_file(struct st_command *command) +{ + ulong mode= 0; + static DYNAMIC_STRING ds_mode; + static DYNAMIC_STRING ds_file; + const struct command_arg chmod_file_args[] = { + "mode", ARG_STRING, TRUE, &ds_mode, "Mode of file", + "file", ARG_STRING, TRUE, &ds_file, "Filename of file to modify" + }; + DBUG_ENTER("do_chmod_file"); + + check_command_args(command, command->first_argument, + chmod_file_args, + sizeof(chmod_file_args)/sizeof(struct command_arg), + ' '); + + /* Parse what mode to set */ + if (ds_mode.length != 4 || + str2int(ds_mode.str, 8, 0, INT_MAX, &mode) == NullS) + die("You must write a 4 digit octal number for mode"); + + DBUG_PRINT("info", ("chmod %o %s", (uint)mode, ds_file.str)); + handle_command_error(command, chmod(ds_file.str, mode)); + dynstr_free(&ds_mode); + dynstr_free(&ds_file); + DBUG_VOID_RETURN; +} + + /* SYNOPSIS do_file_exists @@ -4204,8 +4246,9 @@ void init_win_path_patterns() /* List of string patterns to match in order to find paths */ const char* paths[] = { "$MYSQL_TEST_DIR", "$MYSQL_TMP_DIR", - "./test/", 0 }; - int num_paths= 3; + "$MYSQLTEST_VARDIR", + "./test/" }; + int num_paths= sizeof(paths)/sizeof(char*); int i; char* p; @@ -4225,6 +4268,13 @@ void init_win_path_patterns() else p= my_strdup(paths[i], MYF(MY_FAE)); + /* Don't insert zero length strings in patterns array */ + if (strlen(p) == 0) + { + my_free(p, MYF(0)); + continue; + } + if (insert_dynamic(&patterns, (gptr) &p)) die(NullS); @@ -4274,7 +4324,7 @@ void fix_win_paths(const char *val, int len) { const char** pattern= dynamic_element(&patterns, i, const char**); DBUG_PRINT("info", ("pattern: %s", *pattern)); - if (strlen(*pattern) == 0) continue; + /* Search for the path in string */ while ((p= strstr(val, *pattern))) { @@ -5695,6 +5745,7 @@ int main(int argc, char **argv) case Q_FILE_EXIST: do_file_exist(command); break; case Q_WRITE_FILE: do_write_file(command); break; case Q_COPY_FILE: do_copy_file(command); break; + case Q_CHMOD_FILE: do_chmod_file(command); break; case Q_PERL: do_perl(command); break; case Q_DELIMITER: do_delimiter(command); @@ -6527,7 +6578,7 @@ int reg_replace(char** buf_p, int* buf_len_p, char *pattern, { my_regex_t r; my_regmatch_t *subs; - char *buf_end, *replace_end; + char *replace_end; char *buf= *buf_p; int len; int buf_len, need_buf_len; @@ -6547,8 +6598,6 @@ int reg_replace(char** buf_p, int* buf_len_p, char *pattern, SECURE_REG_BUF - buf_end= buf + buf_len; - if (icase) cflags|= REG_ICASE; diff --git a/client/readline.cc b/client/readline.cc index 3d524633d69..52abe1045b7 100644 --- a/client/readline.cc +++ b/client/readline.cc @@ -51,7 +51,8 @@ char *batch_readline(LINE_BUFFER *line_buff) if (!(pos=intern_read_line(line_buff,&out_length))) return 0; if (out_length && pos[out_length-1] == '\n') - out_length--; /* Remove '\n' */ + if (--out_length && pos[out_length-1] == '\r') /* Remove '\n' */ + out_length--; /* Remove '\r' */ line_buff->read_length=out_length; pos[out_length]=0; return pos; diff --git a/configure.in b/configure.in index 9b8ff116720..3555e453ef3 100644 --- a/configure.in +++ b/configure.in @@ -1955,7 +1955,7 @@ fi # Check definition of gethostbyname_r (glibc2.0.100 is different from Solaris) ac_save_CXXFLAGS="$CXXFLAGS" -AC_CACHE_CHECK([style of gethostname_r routines], mysql_cv_gethostname_style, +AC_CACHE_CHECK([style of gethostbyname_r routines], mysql_cv_gethostbyname_style, AC_LANG_SAVE AC_LANG_CPLUSPLUS if test "$ac_cv_prog_gxx" = "yes" -a "$with_other_libc" = "no" @@ -1977,10 +1977,10 @@ AC_TRY_COMPILE( skr = gethostbyname_r((const char *) 0, (struct hostent*) 0, (char*) 0, 0, (struct hostent **) 0, &skr);], -mysql_cv_gethostname_style=glibc2, mysql_cv_gethostname_style=other)) +mysql_cv_gethostbyname_style=glibc2, mysql_cv_gethostbyname_style=other)) AC_LANG_RESTORE CXXFLAGS="$ac_save_CXXFLAGS" -if test "$mysql_cv_gethostname_style" = "glibc2" +if test "$mysql_cv_gethostbyname_style" = "glibc2" then AC_DEFINE([HAVE_GETHOSTBYNAME_R_GLIBC2_STYLE], [1], [Solaris define gethostbyname_r with 5 arguments. glibc2 defines this with 6 arguments]) @@ -1988,7 +1988,7 @@ fi # Check 3rd argument of getthostbyname_r ac_save_CXXFLAGS="$CXXFLAGS" -AC_CACHE_CHECK([3 argument to gethostname_r routines], mysql_cv_gethostname_arg, +AC_CACHE_CHECK([3 argument to gethostbyname_r routines], mysql_cv_gethostbyname_arg, AC_LANG_SAVE AC_LANG_CPLUSPLUS if test "$ac_cv_prog_gxx" = "yes" -a "$with_other_libc" = "no" @@ -2009,13 +2009,13 @@ AC_TRY_COMPILE( [int skr; skr = gethostbyname_r((const char *) 0, (struct hostent*) 0, (struct hostent_data*) 0);], -mysql_cv_gethostname_arg=hostent_data, mysql_cv_gethostname_arg=char)) +mysql_cv_gethostbyname_arg=hostent_data, mysql_cv_gethostbyname_arg=char)) AC_LANG_RESTORE CXXFLAGS="$ac_save_CXXFLAGS" -if test "$mysql_cv_gethostname_arg" = "hostent_data" +if test "$mysql_cv_gethostbyname_arg" = "hostent_data" then AC_DEFINE([HAVE_GETHOSTBYNAME_R_RETURN_INT], [1], - [In OSF 4.0f the 3'd argument to gethostname_r is hostent_data *]) + [In OSF 4.0f the 3'd argument to gethostbyname_r is hostent_data *]) fi @@ -2425,7 +2425,7 @@ then sql_client_dirs="libmysql_r $sql_client_dirs" linked_client_targets="$linked_client_targets linked_libmysql_r_sources" AC_CONFIG_FILES(libmysql_r/Makefile) - AC_DEFINE([THREAD_SAFE_CLIENT], [1], [Should be client be thread safe]) + AC_DEFINE([THREAD_SAFE_CLIENT], [1], [Should the client be thread safe]) fi CLIENT_LIBS="$NON_THREADED_LIBS $openssl_libs $ZLIB_LIBS $STATIC_NSS_FLAGS" diff --git a/extra/yassl/README b/extra/yassl/README index 2af4e98fe4c..fbeffd9db77 100644 --- a/extra/yassl/README +++ b/extra/yassl/README @@ -1,4 +1,56 @@ -yaSSL Release notes, version 1.4.0 (08/13/06) +yaSSL Release notes, version 1.5.0 (11/09/06) + + This release of yaSSL contains bug fixes, portability enhancements, + and full TLS 1.1 support. Use the functions: + + SSL_METHOD *TLSv1_1_server_method(void); + SSL_METHOD *TLSv1_1_client_method(void); + + or the SSLv23 versions (even though yaSSL doesn't support SSL 2.0 the v23 + means to pick the highest of SSL 3.0, TLS 1.0, or TLS 1.1. + + +See normal build instructions below under 1.0.6. +See libcurl build instructions below under 1.3.0. + + + +****************yaSSL Release notes, version 1.4.5 (10/15/06) + + + This release of yaSSL contains bug fixes, portability enhancements, + zlib compression support, removal of assembly instructions at runtime if + not supported, and initial TLS 1.1 support. + + + Compression Notes: yaSSL uses zlib for compression and the compression + should only be used if yaSSL is at both ends because the implementation + details aren't yet standard. If you'd like to turn compression on use + the SSL_set_compression() function on the client before calling + SSL_connect(). If both the client and server were built with zlib support + then the connection will use compression. If the client isn't built with + support then SSL_set_compression() will return an error (-1). + + To build yaSSL with zlib support on Unix simply have zlib support on your + system and configure will find it if it's in the standard locations. If + it's somewhere else use the option ./configure --with-zlib=DIR. If you'd + like to disable compression support in yaSSL use ./configure --without-zlib. + + To build yaSSL with zlib support on Windows: + + 1) download zlib from http://www.zlib.net/ + 2) follow the instructions in zlib from projects/visualc6/README.txt + for how to add the zlib project into the yaSSL workspace noting that + you'll need to add configuration support for "Win32 Debug" and + "Win32 Release" in note 3 under "To use:". + 3) define HAVE_LIBZ when building yaSSL + + +See normal build instructions below under 1.0.6. +See libcurl build instructions below under 1.3.0. + + +********************yaSSL Release notes, version 1.4.0 (08/13/06) This release of yaSSL contains bug fixes, portability enhancements, @@ -122,18 +174,6 @@ Choose (Re)Build All from the project workspace run Debug\testsuite.exe from yaSSL-Home\testsuite to test the build ---To enable ia32 assembly for TaoCrypt ciphers and message digests - - On MSVC this is always on - - On GCC **, use ./configure --enable-ia32-asm - - ** This isn't on by default because of the use of intel syntax and the - problem that olders versions of gas have with some addressing statements. - If you enable this and get assemler errors during compilation or can't - pass the TaoCrypt tests, please send todd@yassl.com a message and disable - this option in the meantime. - ***************** yaSSL Release notes, version 1.0.5 diff --git a/extra/yassl/examples/client/client.cpp b/extra/yassl/examples/client/client.cpp index d655011deb6..6c3cdf04dc1 100644 --- a/extra/yassl/examples/client/client.cpp +++ b/extra/yassl/examples/client/client.cpp @@ -5,6 +5,35 @@ //#define TEST_RESUME +void ClientError(SSL_CTX* ctx, SSL* ssl, SOCKET_T& sockfd, const char* msg) +{ + SSL_CTX_free(ctx); + SSL_free(ssl); + tcp_close(sockfd); + err_sys(msg); +} + + +#ifdef NON_BLOCKING + void NonBlockingSSL_Connect(SSL* ssl, SSL_CTX* ctx, SOCKET_T& sockfd) + { + int ret = SSL_connect(ssl); + while (ret =! SSL_SUCCESS && SSL_get_error(ssl, 0) == + SSL_ERROR_WANT_READ) { + printf("... client would block\n"); + #ifdef _WIN32 + Sleep(1000); + #else + sleep(1); + #endif + ret = SSL_connect(ssl); + } + if (ret != SSL_SUCCESS) + ClientError(ctx, ssl, sockfd, "SSL_connect failed"); + } +#endif + + void client_test(void* args) { #ifdef _WIN32 @@ -18,6 +47,9 @@ void client_test(void* args) set_args(argc, argv, *static_cast<func_args*>(args)); tcp_connect(sockfd); +#ifdef NON_BLOCKING + tcp_set_nonblocking(sockfd); +#endif SSL_METHOD* method = TLSv1_client_method(); SSL_CTX* ctx = SSL_CTX_new(method); @@ -27,13 +59,13 @@ void client_test(void* args) SSL_set_fd(ssl, sockfd); + +#ifdef NON_BLOCKING + NonBlockingSSL_Connect(ssl, ctx, sockfd); +#else if (SSL_connect(ssl) != SSL_SUCCESS) - { - SSL_CTX_free(ctx); - SSL_free(ssl); - tcp_close(sockfd); - err_sys("SSL_connect failed"); - } + ClientError(ctx, ssl, sockfd, "SSL_connect failed"); +#endif showPeer(ssl); const char* cipher = 0; @@ -49,16 +81,14 @@ void client_test(void* args) char msg[] = "hello yassl!"; if (SSL_write(ssl, msg, sizeof(msg)) != sizeof(msg)) - { - SSL_CTX_free(ctx); - SSL_free(ssl); - tcp_close(sockfd); - err_sys("SSL_write failed"); - } + ClientError(ctx, ssl, sockfd, "SSL_write failed"); char reply[1024]; - reply[SSL_read(ssl, reply, sizeof(reply))] = 0; + int input = SSL_read(ssl, reply, sizeof(reply)); + if (input > 0) { + reply[input] = 0; printf("Server response: %s\n", reply); + } #ifdef TEST_RESUME SSL_SESSION* session = SSL_get_session(ssl); @@ -75,24 +105,17 @@ void client_test(void* args) SSL_set_session(sslResume, session); if (SSL_connect(sslResume) != SSL_SUCCESS) - { - SSL_CTX_free(ctx); - SSL_free(ssl); - tcp_close(sockfd); - err_sys("SSL resume failed"); - } + ClientError(ctx, sslResume, sockfd, "SSL_resume failed"); showPeer(sslResume); if (SSL_write(sslResume, msg, sizeof(msg)) != sizeof(msg)) - { - SSL_CTX_free(ctx); - SSL_free(ssl); - tcp_close(sockfd); - err_sys("SSL_write failed"); - } + ClientError(ctx, sslResume, sockfd, "SSL_write failed"); - reply[SSL_read(sslResume, reply, sizeof(reply))] = 0; + input = SSL_read(sslResume, reply, sizeof(reply)); + if (input > 0) { + reply[input] = 0; printf("Server response: %s\n", reply); + } SSL_shutdown(sslResume); SSL_free(sslResume); diff --git a/extra/yassl/examples/echoclient/echoclient.cpp b/extra/yassl/examples/echoclient/echoclient.cpp index 983254bf8a7..e2c33c7cda2 100644 --- a/extra/yassl/examples/echoclient/echoclient.cpp +++ b/extra/yassl/examples/echoclient/echoclient.cpp @@ -3,6 +3,15 @@ #include "../../testsuite/test.hpp" +void EchoClientError(SSL_CTX* ctx, SSL* ssl, SOCKET_T& sockfd, const char* msg) +{ + SSL_CTX_free(ctx); + SSL_free(ssl); + tcp_close(sockfd); + err_sys(msg); +} + + void echoclient_test(void* args) { #ifdef _WIN32 @@ -35,7 +44,7 @@ void echoclient_test(void* args) tcp_connect(sockfd); - SSL_METHOD* method = TLSv1_client_method(); + SSL_METHOD* method = SSLv23_client_method(); SSL_CTX* ctx = SSL_CTX_new(method); set_certs(ctx); SSL* ssl = SSL_new(ctx); @@ -43,12 +52,7 @@ void echoclient_test(void* args) SSL_set_fd(ssl, sockfd); if (SSL_connect(ssl) != SSL_SUCCESS) - { - SSL_CTX_free(ctx); - SSL_free(ssl); - tcp_close(sockfd); - err_sys("SSL_connect failed"); - } + EchoClientError(ctx, ssl, sockfd, "SSL_connect failed"); char send[1024]; char reply[1024]; @@ -57,12 +61,7 @@ void echoclient_test(void* args) int sendSz = strlen(send) + 1; if (SSL_write(ssl, send, sendSz) != sendSz) - { - SSL_CTX_free(ctx); - SSL_free(ssl); - tcp_close(sockfd); - err_sys("SSL_write failed"); - } + EchoClientError(ctx, ssl, sockfd, "SSL_write failed"); if (strncmp(send, "quit", 4) == 0) { fputs("sending server shutdown command: quit!\n", fout); diff --git a/extra/yassl/examples/echoserver/echoserver.cpp b/extra/yassl/examples/echoserver/echoserver.cpp index cd31fedddd8..92613744ba0 100644 --- a/extra/yassl/examples/echoserver/echoserver.cpp +++ b/extra/yassl/examples/echoserver/echoserver.cpp @@ -56,7 +56,7 @@ THREAD_RETURN YASSL_API echoserver_test(void* args) tcp_listen(sockfd); - SSL_METHOD* method = TLSv1_server_method(); + SSL_METHOD* method = SSLv23_server_method(); SSL_CTX* ctx = SSL_CTX_new(method); set_serverCerts(ctx); @@ -87,8 +87,12 @@ THREAD_RETURN YASSL_API echoserver_test(void* args) SSL* ssl = SSL_new(ctx); SSL_set_fd(ssl, clientfd); - if (SSL_accept(ssl) != SSL_SUCCESS) - EchoError(ctx, ssl, sockfd, clientfd, "SSL_accept failed"); + if (SSL_accept(ssl) != SSL_SUCCESS) { + printf("SSL_accept failed\n"); + SSL_free(ssl); + tcp_close(clientfd); + continue; + } char command[1024]; int echoSz(0); @@ -130,6 +134,7 @@ THREAD_RETURN YASSL_API echoserver_test(void* args) if (SSL_write(ssl, command, echoSz) != echoSz) EchoError(ctx, ssl, sockfd, clientfd, "SSL_write failed"); } + SSL_shutdown(ssl); SSL_free(ssl); tcp_close(clientfd); } diff --git a/extra/yassl/examples/server/server.cpp b/extra/yassl/examples/server/server.cpp index d0bf70cd634..75ce4224770 100644 --- a/extra/yassl/examples/server/server.cpp +++ b/extra/yassl/examples/server/server.cpp @@ -13,6 +13,26 @@ void ServerError(SSL_CTX* ctx, SSL* ssl, SOCKET_T& sockfd, const char* msg) } +#ifdef NON_BLOCKING + void NonBlockingSSL_Accept(SSL* ssl, SSL_CTX* ctx, SOCKET_T& clientfd) + { + int ret = SSL_accept(ssl); + while (ret != SSL_SUCCESS && SSL_get_error(ssl, 0) == + SSL_ERROR_WANT_READ) { + printf("... server would block\n"); + #ifdef _WIN32 + Sleep(1000); + #else + sleep(1); + #endif + ret = SSL_accept(ssl); + } + if (ret != SSL_SUCCESS) + ServerError(ctx, ssl, clientfd, "SSL_accept failed"); + } +#endif + + THREAD_RETURN YASSL_API server_test(void* args) { #ifdef _WIN32 @@ -33,7 +53,7 @@ THREAD_RETURN YASSL_API server_test(void* args) SSL_METHOD* method = TLSv1_server_method(); SSL_CTX* ctx = SSL_CTX_new(method); - //SSL_CTX_set_cipher_list(ctx, "RC4-SHA"); + //SSL_CTX_set_cipher_list(ctx, "RC4-SHA:RC4-MD5"); SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, 0); set_serverCerts(ctx); DH* dh = set_tmpDH(ctx); @@ -41,15 +61,22 @@ THREAD_RETURN YASSL_API server_test(void* args) SSL* ssl = SSL_new(ctx); SSL_set_fd(ssl, clientfd); +#ifdef NON_BLOCKING + NonBlockingSSL_Accept(ssl, ctx, clientfd); +#else if (SSL_accept(ssl) != SSL_SUCCESS) ServerError(ctx, ssl, clientfd, "SSL_accept failed"); +#endif showPeer(ssl); printf("Using Cipher Suite: %s\n", SSL_get_cipher(ssl)); char command[1024]; - command[SSL_read(ssl, command, sizeof(command))] = 0; + int input = SSL_read(ssl, command, sizeof(command)); + if (input > 0) { + command[input] = 0; printf("First client command: %s\n", command); + } char msg[] = "I hear you, fa shizzle!"; if (SSL_write(ssl, msg, sizeof(msg)) != sizeof(msg)) @@ -57,6 +84,7 @@ THREAD_RETURN YASSL_API server_test(void* args) DH_free(dh); SSL_CTX_free(ctx); + SSL_shutdown(ssl); SSL_free(ssl); tcp_close(clientfd); @@ -82,3 +110,4 @@ THREAD_RETURN YASSL_API server_test(void* args) } #endif // NO_MAIN_DRIVER + diff --git a/extra/yassl/include/factory.hpp b/extra/yassl/include/factory.hpp index 04d742431dc..dc25cf0ee70 100644 --- a/extra/yassl/include/factory.hpp +++ b/extra/yassl/include/factory.hpp @@ -42,12 +42,7 @@ namespace STL = STL_NAMESPACE; -// VC60 workaround: it doesn't allow typename in some places -#if defined(_MSC_VER) && (_MSC_VER < 1300) - #define CPP_TYPENAME -#else - #define CPP_TYPENAME typename -#endif + namespace yaSSL { diff --git a/extra/yassl/include/openssl/prefix_ssl.h b/extra/yassl/include/openssl/prefix_ssl.h index aa3f799cf80..dc6e3ef81f0 100644 --- a/extra/yassl/include/openssl/prefix_ssl.h +++ b/extra/yassl/include/openssl/prefix_ssl.h @@ -52,6 +52,7 @@ #define SSL_set_session yaSSL_set_session #define SSL_get_session yaSSL_get_session #define SSL_SESSION_set_timeout yaSSL_SESSION_set_timeout +#define SSL_CTX_set_session_cache_mode yaSSL_CTX_set_session_cache_mode #define SSL_get_peer_certificate yaSSL_get_peer_certificate #define SSL_get_verify_result yaSSL_get_verify_result #define SSL_CTX_set_verify yaSSL_CTX_set_verify @@ -98,6 +99,8 @@ #define SSLv3_client_method yaSSLv3_client_method #define TLSv1_server_method yaTLSv1_server_method #define TLSv1_client_method yaTLSv1_client_method +#define TLSv1_1_server_method yaTLSv1_1_server_method +#define TLSv1_1_client_method yaTLSv1_1_client_method #define SSLv23_server_method yaSSLv23_server_method #define SSL_CTX_use_certificate_file yaSSL_CTX_use_certificate_file #define SSL_CTX_use_PrivateKey_file yaSSL_CTX_use_PrivateKey_file @@ -159,3 +162,4 @@ #define MD5_Init yaMD5_Init #define MD5_Update yaMD5_Update #define MD5_Final yaMD5_Final +#define SSL_set_compression yaSSL_set_compression diff --git a/extra/yassl/include/openssl/ssl.h b/extra/yassl/include/openssl/ssl.h index 5e7290d2a7a..67c49a808fd 100644 --- a/extra/yassl/include/openssl/ssl.h +++ b/extra/yassl/include/openssl/ssl.h @@ -41,7 +41,7 @@ #include "rsa.h" -#define YASSL_VERSION "1.4.3" +#define YASSL_VERSION "1.5.0" #if defined(__cplusplus) @@ -228,6 +228,7 @@ void SSL_load_error_strings(void); int SSL_set_session(SSL *ssl, SSL_SESSION *session); SSL_SESSION* SSL_get_session(SSL* ssl); long SSL_SESSION_set_timeout(SSL_SESSION*, long); +long SSL_CTX_set_session_cache_mode(SSL_CTX* ctx, long mode); X509* SSL_get_peer_certificate(SSL*); long SSL_get_verify_result(SSL*); @@ -361,6 +362,8 @@ SSL_METHOD *SSLv3_server_method(void); SSL_METHOD *SSLv3_client_method(void); SSL_METHOD *TLSv1_server_method(void); SSL_METHOD *TLSv1_client_method(void); +SSL_METHOD *TLSv1_1_server_method(void); +SSL_METHOD *TLSv1_1_client_method(void); SSL_METHOD *SSLv23_server_method(void); int SSL_CTX_use_certificate_file(SSL_CTX*, const char*, int); @@ -531,6 +534,10 @@ void MD5_Final(unsigned char*, MD5_CTX*); #define SSL_DEFAULT_CIPHER_LIST "" /* default all */ +/* yaSSL adds */ +int SSL_set_compression(SSL*); /* turn on yaSSL zlib compression */ + + #if defined(__cplusplus) && !defined(YASSL_MYSQL_COMPATIBLE) diff --git a/extra/yassl/include/socket_wrapper.hpp b/extra/yassl/include/socket_wrapper.hpp index 9fc0d62f90e..bc82384d85e 100644 --- a/extra/yassl/include/socket_wrapper.hpp +++ b/extra/yassl/include/socket_wrapper.hpp @@ -70,8 +70,8 @@ typedef unsigned char byte; // Wraps Windows Sockets and BSD Sockets class Socket { socket_t socket_; // underlying socket descriptor - bool wouldBlock_; // for non-blocking data - bool blocking_; // is option set + bool wouldBlock_; // if non-blocking data, for last read + bool nonBlocking_; // is option set public: explicit Socket(socket_t s = INVALID_SOCKET); ~Socket(); @@ -85,7 +85,7 @@ public: bool wait(); bool WouldBlock() const; - bool IsBlocking() const; + bool IsNonBlocking() const; void closeSocket(); void shutDown(int how = SD_SEND); diff --git a/extra/yassl/include/yassl_error.hpp b/extra/yassl/include/yassl_error.hpp index 72b79b05dbd..f820e5811d9 100644 --- a/extra/yassl/include/yassl_error.hpp +++ b/extra/yassl/include/yassl_error.hpp @@ -56,7 +56,10 @@ enum YasslError { receive_error = 114, certificate_error = 115, privateKey_error = 116, - badVersion_error = 117 + badVersion_error = 117, + compress_error = 118, + decompress_error = 119, + pms_version_error = 120 // !!!! add error message to .cpp !!!! diff --git a/extra/yassl/include/yassl_imp.hpp b/extra/yassl/include/yassl_imp.hpp index 180d7fe7fe1..f51a902b2a5 100644 --- a/extra/yassl/include/yassl_imp.hpp +++ b/extra/yassl/include/yassl_imp.hpp @@ -132,7 +132,6 @@ class Data : public Message { public: Data(); Data(uint16 len, opaque* b); - Data(uint16 len, const opaque* w); friend output_buffer& operator<<(output_buffer&, const Data&); @@ -141,9 +140,9 @@ public: ContentType get_type() const; uint16 get_length() const; - const opaque* get_buffer() const; void set_length(uint16 l); opaque* set_buffer(); + void SetData(uint16, const opaque*); void Process(input_buffer&, SSL&); private: Data(const Data&); // hide copy @@ -232,11 +231,11 @@ public: void Process(input_buffer&, SSL&); const opaque* get_random() const; - friend void buildClientHello(SSL&, ClientHello&, CompressionMethod); + friend void buildClientHello(SSL&, ClientHello&); friend void ProcessOldClientHello(input_buffer& input, SSL& ssl); ClientHello(); - explicit ClientHello(ProtocolVersion pv); + ClientHello(ProtocolVersion pv, bool useCompression); private: ClientHello(const ClientHello&); // hide copy ClientHello& operator=(const ClientHello&); // and assign @@ -253,7 +252,7 @@ class ServerHello : public HandShakeBase { opaque cipher_suite_[SUITE_LEN]; CompressionMethod compression_method_; public: - explicit ServerHello(ProtocolVersion pv); + ServerHello(ProtocolVersion pv, bool useCompression); ServerHello(); friend input_buffer& operator>>(input_buffer&, ServerHello&); @@ -629,8 +628,11 @@ struct Connection { bool send_server_key_; // server key exchange? bool master_clean_; // master secret clean? bool TLS_; // TLSv1 or greater + bool TLSv1_1_; // TLSv1.1 or greater bool sessionID_Set_; // do we have a session - ProtocolVersion version_; + bool compression_; // zlib compression? + ProtocolVersion version_; // negotiated version + ProtocolVersion chVersion_; // client hello version RandomPool& random_; Connection(ProtocolVersion v, RandomPool& ran); @@ -640,6 +642,7 @@ struct Connection { void CleanPreMaster(); void CleanMaster(); void TurnOffTLS(); + void TurnOffTLS1_1(); private: Connection(const Connection&); // hide copy Connection& operator=(const Connection&); // and assign diff --git a/extra/yassl/include/yassl_int.hpp b/extra/yassl/include/yassl_int.hpp index 0edff289b61..4a3c0ba4e20 100644 --- a/extra/yassl/include/yassl_int.hpp +++ b/extra/yassl/include/yassl_int.hpp @@ -431,6 +431,7 @@ private: DH_Parms dhParms_; pem_password_cb passwordCb_; void* userData_; + bool sessionCacheOff_; Stats stats_; Mutex mutex_; // for Stats public: @@ -445,6 +446,7 @@ public: const Stats& GetStats() const; pem_password_cb GetPasswordCb() const; void* GetUserData() const; + bool GetSessionCacheOff() const; void setVerifyPeer(); void setVerifyNone(); @@ -453,6 +455,7 @@ public: bool SetDH(const DH&); void SetPasswordCb(pem_password_cb cb); void SetUserData(void*); + void SetSessionCacheOff(); void IncrementStats(StatsField); void AddCA(x509* ca); @@ -600,6 +603,7 @@ public: const Socket& getSocket() const; YasslError GetError() const; bool GetMultiProtocol() const; + bool CompressionOn() const; Crypto& useCrypto(); Security& useSecurity(); @@ -617,9 +621,12 @@ public: void set_preMaster(const opaque*, uint); void set_masterSecret(const opaque*); void SetError(YasslError); + int SetCompression(); + void UnSetCompression(); // helpers bool isTLS() const; + bool isTLSv1_1() const; void order_error(); void makeMasterSecret(); void makeTLSMasterSecret(); @@ -653,6 +660,10 @@ private: }; +// compression +int Compress(const byte*, int, input_buffer&); +int DeCompress(input_buffer&, int, input_buffer&); + // conversion functions void c32to24(uint32, uint24&); diff --git a/extra/yassl/include/yassl_types.hpp b/extra/yassl/include/yassl_types.hpp index e602ee180bf..646c71afddf 100644 --- a/extra/yassl/include/yassl_types.hpp +++ b/extra/yassl/include/yassl_types.hpp @@ -211,6 +211,7 @@ const int FINISHED_LABEL_SZ = 15; // TLS finished lable length const int SEED_LEN = RAN_LEN * 2; // TLS seed, client + server random const int DEFAULT_TIMEOUT = 500; // Default Session timeout in seconds const int MAX_RECORD_SIZE = 16384; // 2^14, max size by standard +const int COMPRESS_EXTRA = 1024; // extra compression possible addition typedef uint8 Cipher; // first byte is always 0x00 for SSLv3 & TLS @@ -222,7 +223,7 @@ typedef opaque* DistinguishedName; typedef bool IsExportable; -enum CompressionMethod { no_compression = 0 }; +enum CompressionMethod { no_compression = 0, zlib = 221 }; enum CipherType { stream, block }; diff --git a/extra/yassl/src/handshake.cpp b/extra/yassl/src/handshake.cpp index 25f36c4ea8c..c03d72ff2ef 100644 --- a/extra/yassl/src/handshake.cpp +++ b/extra/yassl/src/handshake.cpp @@ -40,9 +40,11 @@ namespace yaSSL { // Build a client hello message from cipher suites and compression method -void buildClientHello(SSL& ssl, ClientHello& hello, - CompressionMethod compression = no_compression) +void buildClientHello(SSL& ssl, ClientHello& hello) { + // store for pre master secret + ssl.useSecurity().use_connection().chVersion_ = hello.client_version_; + ssl.getCrypto().get_random().Fill(hello.random_, RAN_LEN); if (ssl.getSecurity().get_resuming()) { hello.id_len_ = ID_LEN; @@ -55,7 +57,6 @@ void buildClientHello(SSL& ssl, ClientHello& hello, memcpy(hello.cipher_suites_, ssl.getSecurity().get_parms().suites_, hello.suite_len_); hello.comp_len_ = 1; - hello.compression_methods_ = compression; hello.set_length(sizeof(ProtocolVersion) + RAN_LEN + @@ -83,7 +84,7 @@ void buildServerHello(SSL& ssl, ServerHello& hello) hello.cipher_suite_[0] = ssl.getSecurity().get_parms().suite_[0]; hello.cipher_suite_[1] = ssl.getSecurity().get_parms().suite_[1]; - hello.compression_method_ = no_compression; + hello.compression_method_ = hello.compression_method_; hello.set_length(sizeof(ProtocolVersion) + RAN_LEN + ID_LEN + sizeof(hello.id_len_) + SUITE_LEN + SIZEOF_ENUM); @@ -151,12 +152,18 @@ void buildHeaders(SSL& ssl, HandShakeHeader& hsHeader, // add handshake from buffer into md5 and sha hashes, exclude record header -void hashHandShake(SSL& ssl, const output_buffer& output) +void hashHandShake(SSL& ssl, const output_buffer& output, bool removeIV = false) { uint sz = output.get_size() - RECORD_HEADER; const opaque* buffer = output.get_buffer() + RECORD_HEADER; + if (removeIV) { // TLSv1_1 IV + uint blockSz = ssl.getCrypto().get_cipher().get_blockSize(); + sz -= blockSz; + buffer += blockSz; + } + ssl.useHashes().use_MD5().update(buffer, sz); ssl.useHashes().use_SHA().update(buffer, sz); } @@ -229,6 +236,18 @@ void decrypt_message(SSL& ssl, input_buffer& input, uint sz) ssl.useCrypto().use_cipher().decrypt(plain.get_buffer(), cipher, sz); memcpy(cipher, plain.get_buffer(), sz); ssl.useSecurity().use_parms().encrypt_size_ = sz; + + if (ssl.isTLSv1_1()) // IV + input.set_current(input.get_current() + + ssl.getCrypto().get_cipher().get_blockSize()); +} + + +// output operator for input_buffer +output_buffer& operator<<(output_buffer& output, const input_buffer& input) +{ + output.write(input.get_buffer(), input.get_size()); + return output; } @@ -239,9 +258,12 @@ void cipherFinished(SSL& ssl, Finished& fin, output_buffer& output) uint finishedSz = ssl.isTLS() ? TLS_FINISHED_SZ : FINISHED_SZ; uint sz = RECORD_HEADER + HANDSHAKE_HEADER + finishedSz + digestSz; uint pad = 0; + uint blockSz = ssl.getCrypto().get_cipher().get_blockSize(); + if (ssl.getSecurity().get_parms().cipher_type_ == block) { + if (ssl.isTLSv1_1()) + sz += blockSz; // IV sz += 1; // pad byte - uint blockSz = ssl.getCrypto().get_cipher().get_blockSize(); pad = (sz - RECORD_HEADER) % blockSz; pad = blockSz - pad; sz += pad; @@ -252,14 +274,21 @@ void cipherFinished(SSL& ssl, Finished& fin, output_buffer& output) buildHeaders(ssl, hsHeader, rlHeader, fin); rlHeader.length_ = sz - RECORD_HEADER; // record header includes mac // and pad, hanshake doesn't + input_buffer iv; + if (ssl.isTLSv1_1() && ssl.getSecurity().get_parms().cipher_type_== block){ + iv.allocate(blockSz); + ssl.getCrypto().get_random().Fill(iv.get_buffer(), blockSz); + iv.add_size(blockSz); + } + uint ivSz = iv.get_size(); output.allocate(sz); - output << rlHeader << hsHeader << fin; + output << rlHeader << iv << hsHeader << fin; - hashHandShake(ssl, output); + hashHandShake(ssl, output, ssl.isTLSv1_1() ? true : false); opaque digest[SHA_LEN]; // max size if (ssl.isTLS()) - TLS_hmac(ssl, digest, output.get_buffer() + RECORD_HEADER, - output.get_size() - RECORD_HEADER, handshake); + TLS_hmac(ssl, digest, output.get_buffer() + RECORD_HEADER + ivSz, + output.get_size() - RECORD_HEADER - ivSz, handshake); else hmac(ssl, digest, output.get_buffer() + RECORD_HEADER, output.get_size() - RECORD_HEADER, handshake); @@ -282,9 +311,12 @@ void buildMessage(SSL& ssl, output_buffer& output, const Message& msg) uint digestSz = ssl.getCrypto().get_digest().get_digestSize(); uint sz = RECORD_HEADER + msg.get_length() + digestSz; uint pad = 0; + uint blockSz = ssl.getCrypto().get_cipher().get_blockSize(); + if (ssl.getSecurity().get_parms().cipher_type_ == block) { + if (ssl.isTLSv1_1()) // IV + sz += blockSz; sz += 1; // pad byte - uint blockSz = ssl.getCrypto().get_cipher().get_blockSize(); pad = (sz - RECORD_HEADER) % blockSz; pad = blockSz - pad; sz += pad; @@ -294,13 +326,21 @@ void buildMessage(SSL& ssl, output_buffer& output, const Message& msg) buildHeader(ssl, rlHeader, msg); rlHeader.length_ = sz - RECORD_HEADER; // record header includes mac // and pad, hanshake doesn't + input_buffer iv; + if (ssl.isTLSv1_1() && ssl.getSecurity().get_parms().cipher_type_== block){ + iv.allocate(blockSz); + ssl.getCrypto().get_random().Fill(iv.get_buffer(), blockSz); + iv.add_size(blockSz); + } + + uint ivSz = iv.get_size(); output.allocate(sz); - output << rlHeader << msg; + output << rlHeader << iv << msg; opaque digest[SHA_LEN]; // max size if (ssl.isTLS()) - TLS_hmac(ssl, digest, output.get_buffer() + RECORD_HEADER, - output.get_size() - RECORD_HEADER, msg.get_type()); + TLS_hmac(ssl, digest, output.get_buffer() + RECORD_HEADER + ivSz, + output.get_size() - RECORD_HEADER - ivSz, msg.get_type()); else hmac(ssl, digest, output.get_buffer() + RECORD_HEADER, output.get_size() - RECORD_HEADER, msg.get_type()); @@ -456,6 +496,10 @@ void buildSHA_CertVerify(SSL& ssl, byte* digest) // some clients still send sslv2 client hello void ProcessOldClientHello(input_buffer& input, SSL& ssl) { + if (input.get_remaining() < 2) { + ssl.SetError(bad_input); + return; + } byte b0 = input[AUTO]; byte b1 = input[AUTO]; @@ -721,6 +765,7 @@ int DoProcessReply(SSL& ssl) // each message in record, can be more than 1 if not encrypted if (ssl.getSecurity().get_parms().pending_ == false) // cipher on decrypt_message(ssl, buffer, hdr.length_); + mySTL::auto_ptr<Message> msg(mf.CreateObject(hdr.type_)); if (!msg.get()) { ssl.SetError(factory_error); @@ -744,13 +789,13 @@ void processReply(SSL& ssl) if (DoProcessReply(ssl)) // didn't complete process - if (!ssl.getSocket().IsBlocking()) { - // keep trying now + if (!ssl.getSocket().IsNonBlocking()) { + // keep trying now, blocking ok while (!ssl.GetError()) if (DoProcessReply(ssl) == 0) break; } else - // user will have try again later + // user will have try again later, non blocking ssl.SetError(YasslError(SSL_ERROR_WANT_READ)); } @@ -761,7 +806,8 @@ void sendClientHello(SSL& ssl) ssl.verifyState(serverNull); if (ssl.GetError()) return; - ClientHello ch(ssl.getSecurity().get_connection().version_); + ClientHello ch(ssl.getSecurity().get_connection().version_, + ssl.getSecurity().get_connection().compression_); RecordLayerHeader rlHeader; HandShakeHeader hsHeader; output_buffer out; @@ -859,6 +905,7 @@ void sendFinished(SSL& ssl, ConnectionEnd side, BufferOutput buffer) buildFinished(ssl, ssl.useHashes().use_verify(), client); // client } else { + if (!ssl.getSecurity().GetContext()->GetSessionCacheOff()) GetSessions().add(ssl); // store session if (side == client_end) buildFinished(ssl, ssl.useHashes().use_verify(), server); // server @@ -885,7 +932,20 @@ int sendData(SSL& ssl, const void* buffer, int sz) for (;;) { int len = min(sz - sent, MAX_RECORD_SIZE); output_buffer out; - const Data data(len, static_cast<const opaque*>(buffer) + sent); + input_buffer tmp; + + Data data; + + if (ssl.CompressionOn()) { + if (Compress(static_cast<const opaque*>(buffer) + sent, len, + tmp) == -1) { + ssl.SetError(compress_error); + return -1; + } + data.SetData(tmp.get_size(), tmp.get_buffer()); + } + else + data.SetData(len, static_cast<const opaque*>(buffer) + sent); buildMessage(ssl, out, data); ssl.Send(out.get_buffer(), out.get_size()); @@ -947,7 +1007,8 @@ void sendServerHello(SSL& ssl, BufferOutput buffer) ssl.verifyState(clientHelloComplete); if (ssl.GetError()) return; - ServerHello sh(ssl.getSecurity().get_connection().version_); + ServerHello sh(ssl.getSecurity().get_connection().version_, + ssl.getSecurity().get_connection().compression_); RecordLayerHeader rlHeader; HandShakeHeader hsHeader; mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer); diff --git a/extra/yassl/src/make.bat b/extra/yassl/src/make.bat index 148427a6f41..dde305721a7 100644 --- a/extra/yassl/src/make.bat +++ b/extra/yassl/src/make.bat @@ -1,7 +1,7 @@ REM quick and dirty build file for testing different MSDEVs setlocal -set myFLAGS= /I../include /I../mySTL /I../taocrypt/include /W3 /c /ZI +set myFLAGS= /I../include /I../taocrypt/mySTL /I../taocrypt/include /W3 /c /ZI cl %myFLAGS% buffer.cpp cl %myFLAGS% cert_wrapper.cpp diff --git a/extra/yassl/src/socket_wrapper.cpp b/extra/yassl/src/socket_wrapper.cpp index 70944831884..f281b81a24a 100644 --- a/extra/yassl/src/socket_wrapper.cpp +++ b/extra/yassl/src/socket_wrapper.cpp @@ -63,7 +63,7 @@ namespace yaSSL { Socket::Socket(socket_t s) - : socket_(s), wouldBlock_(false), blocking_(false) + : socket_(s), wouldBlock_(false), nonBlocking_(false) {} @@ -148,8 +148,8 @@ uint Socket::receive(byte* buf, unsigned int sz, int flags) if (recvd == -1) { if (get_lastError() == SOCKET_EWOULDBLOCK || get_lastError() == SOCKET_EAGAIN) { - wouldBlock_ = true; - blocking_ = true; // socket can block, only way to tell for win32 + wouldBlock_ = true; // would have blocked this time only + nonBlocking_ = true; // socket nonblocking, win32 only way to tell return 0; } } @@ -191,9 +191,9 @@ bool Socket::WouldBlock() const } -bool Socket::IsBlocking() const +bool Socket::IsNonBlocking() const { - return blocking_; + return nonBlocking_; } diff --git a/extra/yassl/src/ssl.cpp b/extra/yassl/src/ssl.cpp index fe4661b5946..ec2e99adecb 100644 --- a/extra/yassl/src/ssl.cpp +++ b/extra/yassl/src/ssl.cpp @@ -184,10 +184,22 @@ SSL_METHOD* TLSv1_client_method() } +SSL_METHOD* TLSv1_1_server_method() +{ + return NEW_YS SSL_METHOD(server_end, ProtocolVersion(3,2)); +} + + +SSL_METHOD* TLSv1_1_client_method() +{ + return NEW_YS SSL_METHOD(client_end, ProtocolVersion(3,2)); +} + + SSL_METHOD* SSLv23_server_method() { // compatibility only, no version 2 support, but does SSL 3 and TLS 1 - return NEW_YS SSL_METHOD(server_end, ProtocolVersion(3,1), true); + return NEW_YS SSL_METHOD(server_end, ProtocolVersion(3,2), true); } @@ -196,7 +208,7 @@ SSL_METHOD* SSLv23_client_method() // compatibility only, no version 2 support, but does SSL 3 and TLS 1 // though it sends TLS1 hello not SSLv2 so SSLv3 only servers will decline // TODO: maybe add support to send SSLv2 hello ??? - return NEW_YS SSL_METHOD(client_end, ProtocolVersion(3,1), true); + return NEW_YS SSL_METHOD(client_end, ProtocolVersion(3,2), true); } @@ -407,7 +419,6 @@ int SSL_shutdown(SSL* ssl) Alert alert(warning, close_notify); sendAlert(*ssl, alert); ssl->useLog().ShowTCP(ssl->getSocket().get_fd(), true); - ssl->useSocket().closeSocket(); GetErrors().Remove(); @@ -415,8 +426,21 @@ int SSL_shutdown(SSL* ssl) } +/* on by default but allow user to turn off */ +long SSL_CTX_set_session_cache_mode(SSL_CTX* ctx, long mode) +{ + if (mode == SSL_SESS_CACHE_OFF) + ctx->SetSessionCacheOff(); + + return SSL_SUCCESS; +} + + SSL_SESSION* SSL_get_session(SSL* ssl) { + if (ssl->getSecurity().GetContext()->GetSessionCacheOff()) + return 0; + return GetSessions().lookup( ssl->getSecurity().get_connection().sessionID_); } @@ -424,6 +448,9 @@ SSL_SESSION* SSL_get_session(SSL* ssl) int SSL_set_session(SSL* ssl, SSL_SESSION* session) { + if (ssl->getSecurity().GetContext()->GetSessionCacheOff()) + return SSL_FAILURE; + ssl->set_session(session); return SSL_SUCCESS; } @@ -512,6 +539,19 @@ int SSL_get_error(SSL* ssl, int /*previous*/) } + +/* turn on yaSSL zlib compression + returns 0 for success, else error (not built in) + only need to turn on for client, becuase server on by default if built in + but calling for server will tell you whether it's available or not +*/ +int SSL_set_compression(SSL* ssl) +{ + return ssl->SetCompression(); +} + + + X509* SSL_get_peer_certificate(SSL* ssl) { return ssl->getCrypto().get_certManager().get_peerX509(); @@ -1359,6 +1399,56 @@ int SSL_pending(SSL* ssl) } +void SSL_CTX_set_default_passwd_cb(SSL_CTX* ctx, pem_password_cb cb) +{ + ctx->SetPasswordCb(cb); +} + + +int SSLeay_add_ssl_algorithms() // compatibility only +{ + return 1; +} + + +void ERR_remove_state(unsigned long) +{ + GetErrors().Remove(); +} + + +int ERR_GET_REASON(int l) +{ + return l & 0xfff; +} + + +unsigned long err_helper(bool peek = false) +{ + int ysError = GetErrors().Lookup(peek); + + // translate cert error for libcurl, it uses OpenSSL hex code + switch (ysError) { + case TaoCrypt::SIG_OTHER_E: + return CERTFICATE_ERROR; + break; + default : + return 0; + } +} + + +unsigned long ERR_peek_error() +{ + return err_helper(true); +} + + +unsigned long ERR_get_error() +{ + return err_helper(); +} + // functions for stunnel @@ -1477,13 +1567,6 @@ int SSL_pending(SSL* ssl) } - long SSL_CTX_set_session_cache_mode(SSL_CTX*, long) - { - // TDOD: - return SSL_SUCCESS; - } - - long SSL_CTX_set_timeout(SSL_CTX*, long) { // TDOD: @@ -1498,12 +1581,6 @@ int SSL_pending(SSL* ssl) } - void SSL_CTX_set_default_passwd_cb(SSL_CTX* ctx, pem_password_cb cb) - { - ctx->SetPasswordCb(cb); - } - - int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX*, const char*, int) { // TDOD: @@ -1555,49 +1632,6 @@ int SSL_pending(SSL* ssl) } - int SSLeay_add_ssl_algorithms() // compatibility only - { - return 1; - } - - - void ERR_remove_state(unsigned long) - { - GetErrors().Remove(); - } - - - int ERR_GET_REASON(int l) - { - return l & 0xfff; - } - - unsigned long err_helper(bool peek = false) - { - int ysError = GetErrors().Lookup(peek); - - // translate cert error for libcurl, it uses OpenSSL hex code - switch (ysError) { - case TaoCrypt::SIG_OTHER_E: - return CERTFICATE_ERROR; - break; - default : - return 0; - } - } - - - unsigned long ERR_peek_error() - { - return err_helper(true); - } - - - unsigned long ERR_get_error() - { - return err_helper(); - } - // end stunnel needs diff --git a/extra/yassl/src/yassl_error.cpp b/extra/yassl/src/yassl_error.cpp index 3531c0a2c74..25c595f40bc 100644 --- a/extra/yassl/src/yassl_error.cpp +++ b/extra/yassl/src/yassl_error.cpp @@ -133,6 +133,18 @@ void SetErrorString(YasslError error, char* buffer) strncpy(buffer, "protocl version mismatch", max); break; + case compress_error : + strncpy(buffer, "compression error", max); + break; + + case decompress_error : + strncpy(buffer, "decompression error", max); + break; + + case pms_version_error : + strncpy(buffer, "bad PreMasterSecret version error", max); + break; + // openssl errors case SSL_ERROR_WANT_READ : strncpy(buffer, "the read operation would block", max); diff --git a/extra/yassl/src/yassl_imp.cpp b/extra/yassl/src/yassl_imp.cpp index bd07f8b70f2..bf10c4b8932 100644 --- a/extra/yassl/src/yassl_imp.cpp +++ b/extra/yassl/src/yassl_imp.cpp @@ -87,7 +87,7 @@ void EncryptedPreMasterSecret::build(SSL& ssl) opaque tmp[SECRET_LEN]; memset(tmp, 0, sizeof(tmp)); ssl.getCrypto().get_random().Fill(tmp, SECRET_LEN); - ProtocolVersion pv = ssl.getSecurity().get_connection().version_; + ProtocolVersion pv = ssl.getSecurity().get_connection().chVersion_; tmp[0] = pv.major_; tmp[1] = pv.minor_; ssl.set_preMaster(tmp, SECRET_LEN); @@ -233,6 +233,10 @@ void EncryptedPreMasterSecret::read(SSL& ssl, input_buffer& input) rsa.decrypt(preMasterSecret, secret_, length_, ssl.getCrypto().get_random()); + ProtocolVersion pv = ssl.getSecurity().get_connection().chVersion_; + if (pv.major_ != preMasterSecret[0] || pv.minor_ != preMasterSecret[1]) + ssl.SetError(pms_version_error); // continue deriving for timing attack + ssl.set_preMaster(preMasterSecret, SECRET_LEN); ssl.makeMasterSecret(); } @@ -437,6 +441,7 @@ Parameters::Parameters(ConnectionEnd ce, const Ciphers& ciphers, ProtocolVersion pv, bool haveDH) : entity_(ce) { pending_ = true; // suite not set yet + strncpy(cipher_name_, "NONE", 5); if (ciphers.setSuites_) { // use user set list suites_size_ = ciphers.suiteSz_; @@ -445,6 +450,7 @@ Parameters::Parameters(ConnectionEnd ce, const Ciphers& ciphers, } else SetSuites(pv, ce == server_end && !haveDH); // defaults + } @@ -613,14 +619,18 @@ output_buffer& operator<<(output_buffer& output, const HandShakeHeader& hdr) void HandShakeHeader::Process(input_buffer& input, SSL& ssl) { ssl.verifyState(*this); + if (ssl.GetError()) return; const HandShakeFactory& hsf = ssl.getFactory().getHandShake(); mySTL::auto_ptr<HandShakeBase> hs(hsf.CreateObject(type_)); if (!hs.get()) { ssl.SetError(factory_error); return; } - hashHandShake(ssl, input, c24to32(length_)); + uint len = c24to32(length_); + hashHandShake(ssl, input, len); + + hs->set_length(len); input >> *hs; hs->Process(input, ssl); } @@ -849,11 +859,17 @@ void Alert::Process(input_buffer& input, SSL& ssl) opaque mac[SHA_LEN]; input.read(mac, digestSz); + if (ssl.getSecurity().get_parms().cipher_type_ == block) { + int ivExtra = 0; opaque fill; - int padSz = ssl.getSecurity().get_parms().encrypt_size_ - aSz - - digestSz; + + if (ssl.isTLSv1_1()) + ivExtra = ssl.getCrypto().get_cipher().get_blockSize(); + int padSz = ssl.getSecurity().get_parms().encrypt_size_ - ivExtra - + aSz - digestSz; for (int i = 0; i < padSz; i++) fill = input[AUTO]; + } // verify if (memcmp(mac, verify, digestSz)) { @@ -879,9 +895,13 @@ Data::Data(uint16 len, opaque* b) {} -Data::Data(uint16 len, const opaque* w) - : length_(len), buffer_(0), write_buffer_(w) -{} +void Data::SetData(uint16 len, const opaque* buffer) +{ + assert(write_buffer_ == 0); + + length_ = len; + write_buffer_ = buffer; +} input_buffer& Data::set(input_buffer& in) { @@ -907,17 +927,12 @@ uint16 Data::get_length() const } -const opaque* Data::get_buffer() const -{ - return write_buffer_; -} - - void Data::set_length(uint16 l) { length_ = l; } + opaque* Data::set_buffer() { return buffer_; @@ -937,27 +952,42 @@ void Data::Process(input_buffer& input, SSL& ssl) { int msgSz = ssl.getSecurity().get_parms().encrypt_size_; int pad = 0, padByte = 0; + int ivExtra = 0; + if (ssl.getSecurity().get_parms().cipher_type_ == block) { - pad = *(input.get_buffer() + input.get_current() + msgSz - 1); + if (ssl.isTLSv1_1()) // IV + ivExtra = ssl.getCrypto().get_cipher().get_blockSize(); + pad = *(input.get_buffer() + input.get_current() + msgSz -ivExtra - 1); padByte = 1; } int digestSz = ssl.getCrypto().get_digest().get_digestSize(); - int dataSz = msgSz - digestSz - pad - padByte; + int dataSz = msgSz - ivExtra - digestSz - pad - padByte; opaque verify[SHA_LEN]; + const byte* rawData = input.get_buffer() + input.get_current(); + // read data - if (dataSz) { + if (dataSz) { // could be compressed + if (ssl.CompressionOn()) { + input_buffer tmp; + if (DeCompress(input, dataSz, tmp) == -1) { + ssl.SetError(decompress_error); + return; + } + ssl.addData(NEW_YS input_buffer(tmp.get_size(), + tmp.get_buffer(), tmp.get_size())); + } + else { input_buffer* data; ssl.addData(data = NEW_YS input_buffer(dataSz)); input.read(data->get_buffer(), dataSz); data->add_size(dataSz); + } if (ssl.isTLS()) - TLS_hmac(ssl, verify, data->get_buffer(), dataSz, application_data, - true); + TLS_hmac(ssl, verify, rawData, dataSz, application_data, true); else - hmac(ssl, verify, data->get_buffer(), dataSz, application_data, - true); + hmac(ssl, verify, rawData, dataSz, application_data, true); } // read mac and fill @@ -1220,6 +1250,13 @@ void ServerHello::Process(input_buffer&, SSL& ssl) if (ssl.isTLS() && server_version_.minor_ < 1) // downgrade to SSLv3 ssl.useSecurity().use_connection().TurnOffTLS(); + else if (ssl.isTLSv1_1() && server_version_.minor_ == 1) + // downdrage to TLSv1 + ssl.useSecurity().use_connection().TurnOffTLS1_1(); + } + else if (ssl.isTLSv1_1() && server_version_.minor_ < 2) { + ssl.SetError(badVersion_error); + return; } else if (ssl.isTLS() && server_version_.minor_ < 1) { ssl.SetError(badVersion_error); @@ -1252,6 +1289,10 @@ void ServerHello::Process(input_buffer&, SSL& ssl) ssl.useSecurity().set_resuming(false); ssl.useLog().Trace("server denied resumption"); } + + if (ssl.CompressionOn() && !compression_method_) + ssl.UnSetCompression(); // server isn't supporting yaSSL zlib request + ssl.useStates().useClient() = serverHelloComplete; } @@ -1263,8 +1304,9 @@ ServerHello::ServerHello() } -ServerHello::ServerHello(ProtocolVersion pv) - : server_version_(pv) +ServerHello::ServerHello(ProtocolVersion pv, bool useCompression) + : server_version_(pv), + compression_method_(useCompression ? zlib : no_compression) { memset(random_, 0, RAN_LEN); memset(session_id_, 0, ID_LEN); @@ -1341,6 +1383,8 @@ opaque* ClientKeyBase::get_clientKey() const // input operator for Client Hello input_buffer& operator>>(input_buffer& input, ClientHello& hello) { + uint begin = input.get_current(); // could have extensions at end + // Protocol hello.client_version_.major_ = input[AUTO]; hello.client_version_.minor_ = input[AUTO]; @@ -1361,8 +1405,19 @@ input_buffer& operator>>(input_buffer& input, ClientHello& hello) // Compression hello.comp_len_ = input[AUTO]; - while (hello.comp_len_--) // ignore for now - hello.compression_methods_ = CompressionMethod(input[AUTO]); + hello.compression_methods_ = no_compression; + while (hello.comp_len_--) { + CompressionMethod cm = CompressionMethod(input[AUTO]); + if (cm == zlib) + hello.compression_methods_ = zlib; + } + + uint read = input.get_current() - begin; + uint expected = hello.get_length(); + + // ignore client hello extensions for now + if (read < expected) + input.set_current(input.get_current() + expected - read); return input; } @@ -1400,6 +1455,13 @@ output_buffer& operator<<(output_buffer& output, const ClientHello& hello) // Client Hello processing handler void ClientHello::Process(input_buffer&, SSL& ssl) { + // store version for pre master secret + ssl.useSecurity().use_connection().chVersion_ = client_version_; + + if (client_version_.major_ != 3) { + ssl.SetError(badVersion_error); + return; + } if (ssl.GetMultiProtocol()) { // SSLv23 support if (ssl.isTLS() && client_version_.minor_ < 1) { // downgrade to SSLv3 @@ -1407,20 +1469,29 @@ void ClientHello::Process(input_buffer&, SSL& ssl) ProtocolVersion pv = ssl.getSecurity().get_connection().version_; ssl.useSecurity().use_parms().SetSuites(pv); // reset w/ SSL suites } + else if (ssl.isTLSv1_1() && client_version_.minor_ == 1) + // downgrade to TLSv1, but use same suites + ssl.useSecurity().use_connection().TurnOffTLS1_1(); + } + else if (ssl.isTLSv1_1() && client_version_.minor_ < 2) { + ssl.SetError(badVersion_error); + return; } else if (ssl.isTLS() && client_version_.minor_ < 1) { ssl.SetError(badVersion_error); return; } - else if (!ssl.isTLS() && (client_version_.major_ == 3 && - client_version_.minor_ >= 1)) { + else if (!ssl.isTLS() && client_version_.minor_ >= 1) { ssl.SetError(badVersion_error); return; } + ssl.set_random(random_, client_end); while (id_len_) { // trying to resume - SSL_SESSION* session = GetSessions().lookup(session_id_); + SSL_SESSION* session = 0; + if (!ssl.getSecurity().GetContext()->GetSessionCacheOff()) + session = GetSessions().lookup(session_id_); if (!session) { ssl.useLog().Trace("session lookup failed"); break; @@ -1444,6 +1515,9 @@ void ClientHello::Process(input_buffer&, SSL& ssl) ssl.matchSuite(cipher_suites_, suite_len_); ssl.set_pending(ssl.getSecurity().get_parms().suite_[1]); + if (compression_methods_ == zlib) + ssl.SetCompression(); + ssl.useStates().useServer() = clientHelloComplete; } @@ -1478,8 +1552,9 @@ ClientHello::ClientHello() } -ClientHello::ClientHello(ProtocolVersion pv) - : client_version_(pv) +ClientHello::ClientHello(ProtocolVersion pv, bool useCompression) + : client_version_(pv), + compression_methods_(useCompression ? zlib : no_compression) { memset(random_, 0, RAN_LEN); } @@ -1943,8 +2018,13 @@ void Finished::Process(input_buffer& input, SSL& ssl) int digestSz = ssl.getCrypto().get_digest().get_digestSize(); input.read(mac, digestSz); + uint ivExtra = 0; + if (ssl.getSecurity().get_parms().cipher_type_ == block) + if (ssl.isTLSv1_1()) + ivExtra = ssl.getCrypto().get_cipher().get_blockSize(); + opaque fill; - int padSz = ssl.getSecurity().get_parms().encrypt_size_ - + int padSz = ssl.getSecurity().get_parms().encrypt_size_ - ivExtra - HANDSHAKE_HEADER - finishedSz - digestSz; for (int i = 0; i < padSz; i++) fill = input[AUTO]; @@ -2018,7 +2098,9 @@ void clean(volatile opaque* p, uint sz, RandomPool& ran) Connection::Connection(ProtocolVersion v, RandomPool& ran) : pre_master_secret_(0), sequence_number_(0), peer_sequence_number_(0), pre_secret_len_(0), send_server_key_(false), master_clean_(false), - TLS_(v.major_ >= 3 && v.minor_ >= 1), version_(v), random_(ran) + TLS_(v.major_ >= 3 && v.minor_ >= 1), + TLSv1_1_(v.major_ >= 3 && v.minor_ >= 2), compression_(false), + version_(v), random_(ran) { memset(sessionID_, 0, sizeof(sessionID_)); } @@ -2043,6 +2125,13 @@ void Connection::TurnOffTLS() } +void Connection::TurnOffTLS1_1() +{ + TLSv1_1_ = false; + version_.minor_ = 1; +} + + // wipeout master secret void Connection::CleanMaster() { diff --git a/extra/yassl/src/yassl_int.cpp b/extra/yassl/src/yassl_int.cpp index 5288acb2bcd..1a407ca8ba5 100644 --- a/extra/yassl/src/yassl_int.cpp +++ b/extra/yassl/src/yassl_int.cpp @@ -38,6 +38,11 @@ #endif +#ifdef HAVE_LIBZ + #include "zlib.h" +#endif + + #ifdef YASSL_PURE_C void* operator new(size_t sz, yaSSL::new_t) @@ -727,6 +732,32 @@ void SSL::set_preMaster(const opaque* pre, uint sz) } +// set yaSSL zlib type compression +int SSL::SetCompression() +{ +#ifdef HAVE_LIBZ + secure_.use_connection().compression_ = true; + return 0; +#else + return -1; // not built in +#endif +} + + +// unset yaSSL zlib type compression +void SSL::UnSetCompression() +{ + secure_.use_connection().compression_ = false; +} + + +// is yaSSL zlib compression on +bool SSL::CompressionOn() const +{ + return secure_.get_connection().compression_; +} + + // store master secret void SSL::set_masterSecret(const opaque* sec) { @@ -1109,6 +1140,11 @@ void SSL::verifyState(const RecordLayerHeader& rlHeader) { if (GetError()) return; + if (rlHeader.version_.major_ != 3 || rlHeader.version_.minor_ > 2) { + SetError(badVersion_error); + return; + } + if (states_.getRecord() == recordNotReady || (rlHeader.type_ == application_data && // data and handshake states_.getHandShake() != handShakeReady) ) // isn't complete yet @@ -1247,6 +1283,9 @@ void SSL::matchSuite(const opaque* peer, uint length) void SSL::set_session(SSL_SESSION* s) { + if (getSecurity().GetContext()->GetSessionCacheOff()) + return; + if (s && GetSessions().lookup(s->GetID(), &secure_.use_resume())) { secure_.set_resuming(true); crypto_.use_certManager().setPeerX509(s->GetPeerX509()); @@ -1344,6 +1383,12 @@ bool SSL::isTLS() const } +bool SSL::isTLSv1_1() const +{ + return secure_.get_connection().TLSv1_1_; +} + + void SSL::addData(input_buffer* data) { buffers_.useData().push_back(data); @@ -1703,7 +1748,7 @@ bool SSL_METHOD::multipleProtocol() const SSL_CTX::SSL_CTX(SSL_METHOD* meth) : method_(meth), certificate_(0), privateKey_(0), passwordCb_(0), - userData_(0) + userData_(0), sessionCacheOff_(false) {} @@ -1784,12 +1829,24 @@ void* SSL_CTX::GetUserData() const } +bool SSL_CTX::GetSessionCacheOff() const +{ + return sessionCacheOff_; +} + + void SSL_CTX::SetUserData(void* data) { userData_ = data; } +void SSL_CTX::SetSessionCacheOff() +{ + sessionCacheOff_ = true; +} + + void SSL_CTX::setVerifyPeer() { method_->setVerifyPeer(); @@ -2312,9 +2369,110 @@ ASN1_STRING* StringHolder::GetString() } +#ifdef HAVE_LIBZ + + void* myAlloc(void* /* opaque */, unsigned int item, unsigned int size) + { + return NEW_YS unsigned char[item * size]; + } + + + void myFree(void* /* opaque */, void* memory) + { + unsigned char* ptr = static_cast<unsigned char*>(memory); + yaSSL::ysArrayDelete(ptr); + } + + + // put size in front of compressed data + int Compress(const byte* in, int sz, input_buffer& buffer) + { + byte tmp[LENGTH_SZ]; + z_stream c_stream; /* compression stream */ + + buffer.allocate(sz + sizeof(uint16) + COMPRESS_EXTRA); + + c_stream.zalloc = myAlloc; + c_stream.zfree = myFree; + c_stream.opaque = (voidpf)0; + + c_stream.next_in = const_cast<byte*>(in); + c_stream.avail_in = sz; + c_stream.next_out = buffer.get_buffer() + sizeof(tmp); + c_stream.avail_out = buffer.get_capacity() - sizeof(tmp); + + if (deflateInit(&c_stream, 8) != Z_OK) return -1; + int err = deflate(&c_stream, Z_FINISH); + deflateEnd(&c_stream); + if (err != Z_OK && err != Z_STREAM_END) return -1; + + c16toa(sz, tmp); + memcpy(buffer.get_buffer(), tmp, sizeof(tmp)); + buffer.add_size(c_stream.total_out + sizeof(tmp)); + + return 0; + } + + + // get uncompressed size in front + int DeCompress(input_buffer& in, int sz, input_buffer& out) + { + byte tmp[LENGTH_SZ]; + + in.read(tmp, sizeof(tmp)); + + uint16 len; + ato16(tmp, len); + + out.allocate(len); + + z_stream d_stream; /* decompression stream */ + + d_stream.zalloc = myAlloc; + d_stream.zfree = myFree; + d_stream.opaque = (voidpf)0; + + d_stream.next_in = in.get_buffer() + in.get_current(); + d_stream.avail_in = sz - sizeof(tmp); + d_stream.next_out = out.get_buffer(); + d_stream.avail_out = out.get_capacity(); + + if (inflateInit(&d_stream) != Z_OK) return -1; + int err = inflate(&d_stream, Z_FINISH); + inflateEnd(&d_stream); + if (err != Z_OK && err != Z_STREAM_END) return -1; + + out.add_size(d_stream.total_out); + in.set_current(in.get_current() + sz - sizeof(tmp)); + + return 0; + } + + +#else // LIBZ + + // these versions should never get called + int Compress(const byte* in, int sz, input_buffer& buffer) + { + assert(0); + return -1; + } + + + int DeCompress(input_buffer& in, int sz, input_buffer& out) + { + assert(0); + return -1; + } + + +#endif // LIBZ + + } // namespace + extern "C" void yaSSL_CleanUp() { TaoCrypt::CleanUp(); diff --git a/extra/yassl/taocrypt/benchmark/make.bat b/extra/yassl/taocrypt/benchmark/make.bat index 4ebe4b32417..bf1383f5e97 100644 --- a/extra/yassl/taocrypt/benchmark/make.bat +++ b/extra/yassl/taocrypt/benchmark/make.bat @@ -1,7 +1,7 @@ REM quick and dirty build file for testing different MSDEVs setlocal -set myFLAGS= /I../include /I../../mySTL /c /W3 /G6 /O2 +set myFLAGS= /I../include /I../mySTL /c /W3 /G6 /O2 cl %myFLAGS% benchmark.cpp diff --git a/extra/yassl/taocrypt/include/aes.hpp b/extra/yassl/taocrypt/include/aes.hpp index cb70f5c0e7e..5c53fc39411 100644 --- a/extra/yassl/taocrypt/include/aes.hpp +++ b/extra/yassl/taocrypt/include/aes.hpp @@ -34,6 +34,12 @@ #include "modes.hpp" +#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM) + #define DO_AES_ASM +#endif + + + namespace TaoCrypt { @@ -46,15 +52,14 @@ public: enum { BLOCK_SIZE = AES_BLOCK_SIZE }; AES(CipherDir DIR, Mode MODE) - : Mode_BASE(BLOCK_SIZE), dir_(DIR), mode_(MODE) {} + : Mode_BASE(BLOCK_SIZE, DIR, MODE) {} +#ifdef DO_AES_ASM void Process(byte*, const byte*, word32); +#endif void SetKey(const byte* key, word32 sz, CipherDir fake = ENCRYPTION); void SetIV(const byte* iv) { memcpy(r_, iv, BLOCK_SIZE); } private: - CipherDir dir_; - Mode mode_; - static const word32 rcon_[]; word32 rounds_; diff --git a/extra/yassl/taocrypt/include/algebra.hpp b/extra/yassl/taocrypt/include/algebra.hpp index 535ce2599c4..9cfbcf06ece 100644 --- a/extra/yassl/taocrypt/include/algebra.hpp +++ b/extra/yassl/taocrypt/include/algebra.hpp @@ -75,7 +75,8 @@ public: typedef Integer Element; AbstractRing() : AbstractGroup() {m_mg.m_pRing = this;} - AbstractRing(const AbstractRing &source) :AbstractGroup() {m_mg.m_pRing = this;} + AbstractRing(const AbstractRing &source) : AbstractGroup() + {m_mg.m_pRing = this;} AbstractRing& operator=(const AbstractRing &source) {return *this;} virtual bool IsUnit(const Element &a) const =0; diff --git a/extra/yassl/taocrypt/include/arc4.hpp b/extra/yassl/taocrypt/include/arc4.hpp index 05b0921f5a1..ddd5082f557 100644 --- a/extra/yassl/taocrypt/include/arc4.hpp +++ b/extra/yassl/taocrypt/include/arc4.hpp @@ -46,7 +46,6 @@ public: ARC4() {} void Process(byte*, const byte*, word32); - void AsmProcess(byte*, const byte*, word32); void SetKey(const byte*, word32); private: byte x_; @@ -55,6 +54,8 @@ private: ARC4(const ARC4&); // hide copy const ARC4 operator=(const ARC4&); // and assign + + void AsmProcess(byte*, const byte*, word32); }; } // namespace diff --git a/extra/yassl/taocrypt/include/asn.hpp b/extra/yassl/taocrypt/include/asn.hpp index dbee54be6f1..1151f3c944e 100644 --- a/extra/yassl/taocrypt/include/asn.hpp +++ b/extra/yassl/taocrypt/include/asn.hpp @@ -34,7 +34,11 @@ #include "misc.hpp" #include "block.hpp" #include "error.hpp" -#include STL_LIST_FILE +#ifdef USE_SYS_STL + #include <list> +#else + #include "list.hpp" +#endif namespace STL = STL_NAMESPACE; diff --git a/extra/yassl/taocrypt/include/block.hpp b/extra/yassl/taocrypt/include/block.hpp index a931158a83d..0cf27d0b6b5 100644 --- a/extra/yassl/taocrypt/include/block.hpp +++ b/extra/yassl/taocrypt/include/block.hpp @@ -34,7 +34,12 @@ #include "misc.hpp" #include <string.h> // memcpy #include <stddef.h> // ptrdiff_t -#include STL_ALGORITHM_FILE + +#ifdef USE_SYS_STL + #include <algorithm> +#else + #include "algorithm.hpp" +#endif namespace STL = STL_NAMESPACE; diff --git a/extra/yassl/taocrypt/include/blowfish.hpp b/extra/yassl/taocrypt/include/blowfish.hpp index 40953624232..4d6ad1b034b 100644 --- a/extra/yassl/taocrypt/include/blowfish.hpp +++ b/extra/yassl/taocrypt/include/blowfish.hpp @@ -32,12 +32,21 @@ #include "misc.hpp" #include "modes.hpp" -#include STL_ALGORITHM_FILE +#ifdef USE_SYS_STL + #include <algorithm> +#else + #include "algorithm.hpp" +#endif namespace STL = STL_NAMESPACE; +#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM) + #define DO_BLOWFISH_ASM +#endif + + namespace TaoCrypt { enum { BLOWFISH_BLOCK_SIZE = 8 }; @@ -49,15 +58,14 @@ public: enum { BLOCK_SIZE = BLOWFISH_BLOCK_SIZE, ROUNDS = 16 }; Blowfish(CipherDir DIR, Mode MODE) - : Mode_BASE(BLOCK_SIZE), dir_(DIR), mode_(MODE) {} + : Mode_BASE(BLOCK_SIZE, DIR, MODE) {} +#ifdef DO_BLOWFISH_ASM void Process(byte*, const byte*, word32); +#endif void SetKey(const byte* key, word32 sz, CipherDir fake = ENCRYPTION); void SetIV(const byte* iv) { memcpy(r_, iv, BLOCK_SIZE); } private: - CipherDir dir_; - Mode mode_; - static const word32 p_init_[ROUNDS + 2]; static const word32 s_init_[4 * 256]; diff --git a/extra/yassl/taocrypt/include/des.hpp b/extra/yassl/taocrypt/include/des.hpp index 48bb1e9119d..19273821f98 100644 --- a/extra/yassl/taocrypt/include/des.hpp +++ b/extra/yassl/taocrypt/include/des.hpp @@ -34,6 +34,12 @@ #include "misc.hpp" #include "modes.hpp" + +#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM) + #define DO_DES_ASM +#endif + + namespace TaoCrypt { @@ -53,13 +59,9 @@ protected: class DES : public Mode_BASE, public BasicDES { public: DES(CipherDir DIR, Mode MODE) - : Mode_BASE(DES_BLOCK_SIZE), dir_(DIR), mode_(MODE) {} + : Mode_BASE(DES_BLOCK_SIZE, DIR, MODE) {} - void Process(byte*, const byte*, word32); private: - CipherDir dir_; - Mode mode_; - void ProcessAndXorBlock(const byte*, const byte*, byte*) const; DES(const DES&); // hide copy @@ -71,14 +73,10 @@ private: class DES_EDE2 : public Mode_BASE { public: DES_EDE2(CipherDir DIR, Mode MODE) - : Mode_BASE(DES_BLOCK_SIZE), dir_(DIR), mode_(MODE) {} + : Mode_BASE(DES_BLOCK_SIZE, DIR, MODE) {} void SetKey(const byte*, word32, CipherDir dir); - void Process(byte*, const byte*, word32); private: - CipherDir dir_; - Mode mode_; - BasicDES des1_; BasicDES des2_; @@ -94,15 +92,14 @@ private: class DES_EDE3 : public Mode_BASE { public: DES_EDE3(CipherDir DIR, Mode MODE) - : Mode_BASE(DES_BLOCK_SIZE), dir_(DIR), mode_(MODE) {} + : Mode_BASE(DES_BLOCK_SIZE, DIR, MODE) {} void SetKey(const byte*, word32, CipherDir dir); void SetIV(const byte* iv) { memcpy(r_, iv, DES_BLOCK_SIZE); } +#ifdef DO_DES_ASM void Process(byte*, const byte*, word32); +#endif private: - CipherDir dir_; - Mode mode_; - BasicDES des1_; BasicDES des2_; BasicDES des3_; diff --git a/extra/yassl/taocrypt/include/integer.hpp b/extra/yassl/taocrypt/include/integer.hpp index 70b4dc79e73..751c79102c4 100644 --- a/extra/yassl/taocrypt/include/integer.hpp +++ b/extra/yassl/taocrypt/include/integer.hpp @@ -45,7 +45,11 @@ #include "random.hpp" #include "file.hpp" #include <string.h> -#include STL_ALGORITHM_FILE +#ifdef USE_SYS_STL + #include <algorithm> +#else + #include "algorithm.hpp" +#endif #ifdef TAOCRYPT_X86ASM_AVAILABLE @@ -67,7 +71,8 @@ #endif // SSE2 intrinsics work in GCC 3.3 or later -#if defined(__SSE2__) && (__GNUC_MAJOR__ > 3 || __GNUC_MINOR__ > 2) +#if defined(__SSE2__) && (__GNUC__ == 4 || __GNUC_MAJOR__ > 3 || \ + __GNUC_MINOR__ > 2) #define SSE2_INTRINSICS_AVAILABLE #endif @@ -106,7 +111,6 @@ namespace TaoCrypt { #endif }; - template class TAOCRYPT_DLL AlignedAllocator<word>; typedef Block<word, AlignedAllocator<word> > AlignedWordBlock; #else typedef WordBlock AlignedWordBlock; diff --git a/extra/yassl/taocrypt/include/md5.hpp b/extra/yassl/taocrypt/include/md5.hpp index 30d14d54fbf..f607a922155 100644 --- a/extra/yassl/taocrypt/include/md5.hpp +++ b/extra/yassl/taocrypt/include/md5.hpp @@ -31,6 +31,11 @@ #include "hash.hpp" + +#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM) + #define DO_MD5_ASM +#endif + namespace TaoCrypt { @@ -49,7 +54,9 @@ public: MD5(const MD5&); MD5& operator= (const MD5&); +#ifdef DO_MD5_ASM void Update(const byte*, word32); +#endif void Init(); void Swap(MD5&); diff --git a/extra/yassl/taocrypt/include/misc.hpp b/extra/yassl/taocrypt/include/misc.hpp index 3d2d4c62466..cc20b60d528 100644 --- a/extra/yassl/taocrypt/include/misc.hpp +++ b/extra/yassl/taocrypt/include/misc.hpp @@ -151,6 +151,17 @@ void CleanUp(); #endif +#ifdef TAOCRYPT_X86ASM_AVAILABLE + bool HaveCpuId(); + bool IsPentium(); + void CpuId(word32 input, word32 *output); + + extern bool isMMX; +#endif + + + + // Turn on ia32 ASM for Ciphers and Message Digests // Seperate define since these are more complex, use member offsets // and user may want to turn off while leaving Big Integer optos on @@ -200,17 +211,9 @@ void CleanUp(); #ifdef USE_SYS_STL // use system STL - #define STL_VECTOR_FILE <vector> - #define STL_LIST_FILE <list> - #define STL_ALGORITHM_FILE <algorithm> - #define STL_MEMORY_FILE <memory> #define STL_NAMESPACE std #else // use mySTL - #define STL_VECTOR_FILE "vector.hpp" - #define STL_LIST_FILE "list.hpp" - #define STL_ALGORITHM_FILE "algorithm.hpp" - #define STL_MEMORY_FILE "memory.hpp" #define STL_NAMESPACE mySTL #endif diff --git a/extra/yassl/taocrypt/include/modes.hpp b/extra/yassl/taocrypt/include/modes.hpp index 65b7318661e..d77f855385c 100644 --- a/extra/yassl/taocrypt/include/modes.hpp +++ b/extra/yassl/taocrypt/include/modes.hpp @@ -38,6 +38,7 @@ namespace TaoCrypt { enum Mode { ECB, CBC }; + // BlockCipher abstraction template<CipherDir DIR, class T, Mode MODE> class BlockCipher { @@ -63,14 +64,16 @@ class Mode_BASE : public virtual_base { public: enum { MaxBlockSz = 16 }; - explicit Mode_BASE(int sz) + explicit Mode_BASE(int sz, CipherDir dir, Mode mode) : blockSz_(sz), reg_(reinterpret_cast<byte*>(r_)), - tmp_(reinterpret_cast<byte*>(t_)) + tmp_(reinterpret_cast<byte*>(t_)), dir_(dir), mode_(mode) { assert(sz <= MaxBlockSz); } virtual ~Mode_BASE() {} + virtual void Process(byte*, const byte*, word32); + void SetIV(const byte* iv) { memcpy(reg_, iv, blockSz_); } protected: int blockSz_; @@ -80,6 +83,9 @@ protected: word32 r_[MaxBlockSz / sizeof(word32)]; // align reg_ on word32 word32 t_[MaxBlockSz / sizeof(word32)]; // align tmp_ on word32 + CipherDir dir_; + Mode mode_; + void ECB_Process(byte*, const byte*, word32); void CBC_Encrypt(byte*, const byte*, word32); void CBC_Decrypt(byte*, const byte*, word32); @@ -92,6 +98,18 @@ private: }; +inline void Mode_BASE::Process(byte* out, const byte* in, word32 sz) +{ + if (mode_ == ECB) + ECB_Process(out, in, sz); + else if (mode_ == CBC) + if (dir_ == ENCRYPTION) + CBC_Encrypt(out, in, sz); + else + CBC_Decrypt(out, in, sz); +} + + // ECB Process blocks inline void Mode_BASE::ECB_Process(byte* out, const byte* in, word32 sz) { diff --git a/extra/yassl/taocrypt/include/ripemd.hpp b/extra/yassl/taocrypt/include/ripemd.hpp index 2e594b7604d..5d443769662 100644 --- a/extra/yassl/taocrypt/include/ripemd.hpp +++ b/extra/yassl/taocrypt/include/ripemd.hpp @@ -31,6 +31,11 @@ #include "hash.hpp" + +#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM) + #define DO_RIPEMD_ASM +#endif + namespace TaoCrypt { @@ -49,7 +54,9 @@ public: RIPEMD160(const RIPEMD160&); RIPEMD160& operator= (const RIPEMD160&); +#ifdef DO_RIPEMD_ASM void Update(const byte*, word32); +#endif void Init(); void Swap(RIPEMD160&); private: diff --git a/extra/yassl/taocrypt/include/rsa.hpp b/extra/yassl/taocrypt/include/rsa.hpp index 1b531b9d0c0..c33e21b76a3 100644 --- a/extra/yassl/taocrypt/include/rsa.hpp +++ b/extra/yassl/taocrypt/include/rsa.hpp @@ -239,7 +239,8 @@ bool RSA_Encryptor<Pad>::SSL_Verify(const byte* message, word32 sz, const byte* sig) { ByteBlock plain(PK_Lengths(key_.GetModulus()).FixedMaxPlaintextLength()); - SSL_Decrypt(key_, sig, plain.get_buffer()); + if (SSL_Decrypt(key_, sig, plain.get_buffer()) != sz) + return false; // not right justified or bad padding if ( (memcmp(plain.get_buffer(), message, sz)) == 0) return true; diff --git a/extra/yassl/taocrypt/include/sha.hpp b/extra/yassl/taocrypt/include/sha.hpp index 2d65932dc17..510c516b1a4 100644 --- a/extra/yassl/taocrypt/include/sha.hpp +++ b/extra/yassl/taocrypt/include/sha.hpp @@ -31,6 +31,11 @@ #include "hash.hpp" + +#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM) + #define DO_SHA_ASM +#endif + namespace TaoCrypt { @@ -46,7 +51,9 @@ public: word32 getDigestSize() const { return DIGEST_SIZE; } word32 getPadSize() const { return PAD_SIZE; } +#ifdef DO_SHA_ASM void Update(const byte* data, word32 len); +#endif void Init(); SHA(const SHA&); diff --git a/extra/yassl/taocrypt/include/twofish.hpp b/extra/yassl/taocrypt/include/twofish.hpp index ba144d2defb..8cad4923262 100644 --- a/extra/yassl/taocrypt/include/twofish.hpp +++ b/extra/yassl/taocrypt/include/twofish.hpp @@ -32,12 +32,20 @@ #include "misc.hpp" #include "modes.hpp" -#include STL_ALGORITHM_FILE +#ifdef USE_SYS_STL + #include <algorithm> +#else + #include "algorithm.hpp" +#endif namespace STL = STL_NAMESPACE; +#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM) + #define DO_TWOFISH_ASM +#endif + namespace TaoCrypt { enum { TWOFISH_BLOCK_SIZE = 16 }; @@ -49,15 +57,14 @@ public: enum { BLOCK_SIZE = TWOFISH_BLOCK_SIZE }; Twofish(CipherDir DIR, Mode MODE) - : Mode_BASE(BLOCK_SIZE), dir_(DIR), mode_(MODE) {} + : Mode_BASE(BLOCK_SIZE, DIR, MODE) {} +#ifdef DO_TWOFISH_ASM void Process(byte*, const byte*, word32); +#endif void SetKey(const byte* key, word32 sz, CipherDir fake = ENCRYPTION); void SetIV(const byte* iv) { memcpy(r_, iv, BLOCK_SIZE); } private: - CipherDir dir_; - Mode mode_; - static const byte q_[2][256]; static const word32 mds_[4][256]; diff --git a/extra/yassl/taocrypt/src/aes.cpp b/extra/yassl/taocrypt/src/aes.cpp index 574a88a736c..2940f06c074 100644 --- a/extra/yassl/taocrypt/src/aes.cpp +++ b/extra/yassl/taocrypt/src/aes.cpp @@ -34,33 +34,19 @@ #include "aes.hpp" -#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM) - #define DO_AES_ASM -#endif - - namespace TaoCrypt { -#if !defined(DO_AES_ASM) - -// Generic Version -void AES::Process(byte* out, const byte* in, word32 sz) -{ - if (mode_ == ECB) - ECB_Process(out, in, sz); - else if (mode_ == CBC) - if (dir_ == ENCRYPTION) - CBC_Encrypt(out, in, sz); - else - CBC_Decrypt(out, in, sz); -} - -#else +#if defined(DO_AES_ASM) // ia32 optimized version void AES::Process(byte* out, const byte* in, word32 sz) { + if (!isMMX) { + Mode_BASE::Process(out, in, sz); + return; + } + word32 blocks = sz / BLOCK_SIZE; if (mode_ == ECB) diff --git a/extra/yassl/taocrypt/src/algebra.cpp b/extra/yassl/taocrypt/src/algebra.cpp index 375cd6cd524..76c4e99323d 100644 --- a/extra/yassl/taocrypt/src/algebra.cpp +++ b/extra/yassl/taocrypt/src/algebra.cpp @@ -29,7 +29,11 @@ #include "runtime.hpp" #include "algebra.hpp" -#include STL_VECTOR_FILE +#ifdef USE_SYS_STL + #include <vector> +#else + #include "vector.hpp" +#endif namespace STL = STL_NAMESPACE; diff --git a/extra/yassl/taocrypt/src/arc4.cpp b/extra/yassl/taocrypt/src/arc4.cpp index ea1e084014c..90b5170c59e 100644 --- a/extra/yassl/taocrypt/src/arc4.cpp +++ b/extra/yassl/taocrypt/src/arc4.cpp @@ -80,12 +80,18 @@ inline unsigned int MakeByte(word32& x, word32& y, byte* s) } // namespace -#ifndef DO_ARC4_ASM void ARC4::Process(byte* out, const byte* in, word32 length) { if (length == 0) return; +#ifdef DO_ARC4_ASM + if (isMMX) { + AsmProcess(out, in, length); + return; + } +#endif + byte *const s = state_; word32 x = x_; word32 y = y_; @@ -100,13 +106,16 @@ void ARC4::Process(byte* out, const byte* in, word32 length) y_ = y; } -#else // DO_ARC4_ASM +#ifdef DO_ARC4_ASM + #ifdef _MSC_VER __declspec(naked) +#else + __attribute__ ((noinline)) #endif -void ARC4::Process(byte* out, const byte* in, word32 length) +void ARC4::AsmProcess(byte* out, const byte* in, word32 length) { #ifdef __GNUC__ #define AS1(x) asm(#x); diff --git a/extra/yassl/taocrypt/src/blowfish.cpp b/extra/yassl/taocrypt/src/blowfish.cpp index 40ae1a17e6c..d736292fb19 100644 --- a/extra/yassl/taocrypt/src/blowfish.cpp +++ b/extra/yassl/taocrypt/src/blowfish.cpp @@ -37,34 +37,21 @@ -#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM) - #define DO_BLOWFISH_ASM -#endif - namespace TaoCrypt { -#if !defined(DO_BLOWFISH_ASM) - -// Generic Version -void Blowfish::Process(byte* out, const byte* in, word32 sz) -{ - if (mode_ == ECB) - ECB_Process(out, in, sz); - else if (mode_ == CBC) - if (dir_ == ENCRYPTION) - CBC_Encrypt(out, in, sz); - else - CBC_Decrypt(out, in, sz); -} - -#else +#if defined(DO_BLOWFISH_ASM) // ia32 optimized version void Blowfish::Process(byte* out, const byte* in, word32 sz) { + if (!isMMX) { + Mode_BASE::Process(out, in, sz); + return; + } + word32 blocks = sz / BLOCK_SIZE; if (mode_ == ECB) diff --git a/extra/yassl/taocrypt/src/des.cpp b/extra/yassl/taocrypt/src/des.cpp index 2628e142bae..94428ac587e 100644 --- a/extra/yassl/taocrypt/src/des.cpp +++ b/extra/yassl/taocrypt/src/des.cpp @@ -34,16 +34,16 @@ #include "runtime.hpp" #include "des.hpp" -#include STL_ALGORITHM_FILE +#ifdef USE_SYS_STL + #include <algorithm> +#else + #include "algorithm.hpp" +#endif namespace STL = STL_NAMESPACE; -#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM) - #define DO_DES_ASM -#endif - namespace TaoCrypt { @@ -357,18 +357,6 @@ void BasicDES::RawProcessBlock(word32& lIn, word32& rIn) const } -void DES::Process(byte* out, const byte* in, word32 sz) -{ - if (mode_ == ECB) - ECB_Process(out, in, sz); - else if (mode_ == CBC) - if (dir_ == ENCRYPTION) - CBC_Encrypt(out, in, sz); - else - CBC_Decrypt(out, in, sz); -} - - typedef BlockGetAndPut<word32, BigEndian> Block; @@ -386,17 +374,6 @@ void DES::ProcessAndXorBlock(const byte* in, const byte* xOr, byte* out) const } -void DES_EDE2::Process(byte* out, const byte* in, word32 sz) -{ - if (mode_ == ECB) - ECB_Process(out, in, sz); - else if (mode_ == CBC) - if (dir_ == ENCRYPTION) - CBC_Encrypt(out, in, sz); - else - CBC_Decrypt(out, in, sz); -} - void DES_EDE2::SetKey(const byte* key, word32 sz, CipherDir dir) { des1_.SetKey(key, sz, dir); @@ -429,25 +406,16 @@ void DES_EDE3::SetKey(const byte* key, word32 sz, CipherDir dir) -#if !defined(DO_DES_ASM) - -// Generic Version -void DES_EDE3::Process(byte* out, const byte* in, word32 sz) -{ - if (mode_ == ECB) - ECB_Process(out, in, sz); - else if (mode_ == CBC) - if (dir_ == ENCRYPTION) - CBC_Encrypt(out, in, sz); - else - CBC_Decrypt(out, in, sz); -} - -#else +#if defined(DO_DES_ASM) // ia32 optimized version void DES_EDE3::Process(byte* out, const byte* in, word32 sz) { + if (!isMMX) { + Mode_BASE::Process(out, in, sz); + return; + } + word32 blocks = sz / DES_BLOCK_SIZE; if (mode_ == CBC) diff --git a/extra/yassl/taocrypt/src/integer.cpp b/extra/yassl/taocrypt/src/integer.cpp index 500160cfe37..1ed69ce34dc 100644 --- a/extra/yassl/taocrypt/src/integer.cpp +++ b/extra/yassl/taocrypt/src/integer.cpp @@ -55,12 +55,15 @@ extern "C" word myUMULH(word, word); #pragma intrinsic (myUMULH) #endif +#ifdef __GNUC__ + #include <signal.h> + #include <setjmp.h> +#endif + #ifdef SSE2_INTRINSICS_AVAILABLE #ifdef __GNUC__ #include <xmmintrin.h> - #include <signal.h> - #include <setjmp.h> #ifdef TAOCRYPT_MEMALIGN_AVAILABLE #include <malloc.h> #else @@ -1015,44 +1018,20 @@ void Portable::Multiply8Bottom(word *R, const word *A, const word *B) // ************** x86 feature detection *************** -static bool s_sse2Enabled = true; - -static void CpuId(word32 input, word32 *output) -{ -#ifdef __GNUC__ - __asm__ - ( - // save ebx in case -fPIC is being used - "push %%ebx; cpuid; mov %%ebx, %%edi; pop %%ebx" - : "=a" (output[0]), "=D" (output[1]), "=c" (output[2]), "=d"(output[3]) - : "a" (input) - ); -#else - __asm - { - mov eax, input - cpuid - mov edi, output - mov [edi], eax - mov [edi+4], ebx - mov [edi+8], ecx - mov [edi+12], edx - } -#endif -} #ifdef SSE2_INTRINSICS_AVAILABLE + #ifndef _MSC_VER -static jmp_buf s_env; -static void SigIllHandler(int) -{ + static jmp_buf s_env; + static void SigIllHandler(int) + { longjmp(s_env, 1); -} + } #endif static bool HasSSE2() { - if (!s_sse2Enabled) + if (!IsPentium()) return false; word32 cpuid[4]; @@ -1081,23 +1060,22 @@ static bool HasSSE2() if (setjmp(s_env)) result = false; else - __asm __volatile ("xorps %xmm0, %xmm0"); + __asm __volatile ("xorpd %xmm0, %xmm0"); signal(SIGILL, oldHandler); return result; #endif } -#endif +#endif // SSE2_INTRINSICS_AVAILABLE + static bool IsP4() { - word32 cpuid[4]; - - CpuId(0, cpuid); - STL::swap(cpuid[2], cpuid[3]); - if (memcmp(cpuid+1, "GenuineIntel", 12) != 0) + if (!IsPentium()) return false; + word32 cpuid[4]; + CpuId(1, cpuid); return ((cpuid[0] >> 8) & 0xf) == 0xf; } @@ -1147,7 +1125,12 @@ static PMul s_pMul4, s_pMul8, s_pMul8B; static void SetPentiumFunctionPointers() { - if (IsP4()) + if (!IsPentium()) + { + s_pAdd = &Portable::Add; + s_pSub = &Portable::Subtract; + } + else if (IsP4()) { s_pAdd = &P4Optimized::Add; s_pSub = &P4Optimized::Subtract; @@ -1159,7 +1142,13 @@ static void SetPentiumFunctionPointers() } #ifdef SSE2_INTRINSICS_AVAILABLE - if (HasSSE2()) + if (!IsPentium()) + { + s_pMul4 = &Portable::Multiply4; + s_pMul8 = &Portable::Multiply8; + s_pMul8B = &Portable::Multiply8Bottom; + } + else if (HasSSE2()) { s_pMul4 = &P4Optimized::Multiply4; s_pMul8 = &P4Optimized::Multiply8; @@ -1177,11 +1166,6 @@ static void SetPentiumFunctionPointers() static const char s_RunAtStartupSetPentiumFunctionPointers = (SetPentiumFunctionPointers(), 0); -void DisableSSE2() -{ - s_sse2Enabled = false; - SetPentiumFunctionPointers(); -} class LowLevel : public PentiumOptimized { @@ -3984,6 +3968,9 @@ Integer CRT(const Integer &xp, const Integer &p, const Integer &xq, template hword DivideThreeWordsByTwo<hword, Word>(hword*, hword, hword, Word*); #endif template word DivideThreeWordsByTwo<word, DWord>(word*, word, word, DWord*); +#ifdef SSE2_INTRINSICS_AVAILABLE +template class AlignedAllocator<word>; +#endif #endif diff --git a/extra/yassl/taocrypt/src/make.bat b/extra/yassl/taocrypt/src/make.bat index ecf7e8f8469..0aa1350f7d8 100644 --- a/extra/yassl/taocrypt/src/make.bat +++ b/extra/yassl/taocrypt/src/make.bat @@ -1,7 +1,7 @@ REM quick and dirty build file for testing different MSDEVs setlocal -set myFLAGS= /I../include /I../../mySTL /c /W3 /G6 /O2 +set myFLAGS= /I../include /I../mySTL /c /W3 /G6 /O2 cl %myFLAGS% aes.cpp cl %myFLAGS% aestables.cpp @@ -21,6 +21,7 @@ cl %myFLAGS% file.cpp cl %myFLAGS% hash.cpp cl %myFLAGS% integer.cpp cl %myFLAGS% md2.cpp +cl %myFLAGS% md4.cpp cl %myFLAGS% md5.cpp cl %myFLAGS% misc.cpp @@ -33,5 +34,5 @@ cl %myFLAGS% template_instnt.cpp cl %myFLAGS% tftables.cpp cl %myFLAGS% twofish.cpp -link.exe -lib /out:taocrypt.lib aes.obj aestables.obj algebra.obj arc4.obj asn.obj bftables.obj blowfish.obj coding.obj des.obj dh.obj dsa.obj file.obj hash.obj integer.obj md2.obj md5.obj misc.obj random.obj ripemd.obj rsa.obj sha.obj template_instnt.obj tftables.obj twofish.obj +link.exe -lib /out:taocrypt.lib aes.obj aestables.obj algebra.obj arc4.obj asn.obj bftables.obj blowfish.obj coding.obj des.obj dh.obj dsa.obj file.obj hash.obj integer.obj md2.obj md4.obj md5.obj misc.obj random.obj ripemd.obj rsa.obj sha.obj template_instnt.obj tftables.obj twofish.obj diff --git a/extra/yassl/taocrypt/src/md4.cpp b/extra/yassl/taocrypt/src/md4.cpp index 0dee8bf40cb..1efda04fbb8 100644 --- a/extra/yassl/taocrypt/src/md4.cpp +++ b/extra/yassl/taocrypt/src/md4.cpp @@ -28,7 +28,11 @@ #include "runtime.hpp" #include "md4.hpp" -#include STL_ALGORITHM_FILE +#ifdef USE_SYS_STL + #include <algorithm> +#else + #include "algorithm.hpp" +#endif namespace STL = STL_NAMESPACE; diff --git a/extra/yassl/taocrypt/src/md5.cpp b/extra/yassl/taocrypt/src/md5.cpp index 2bddc7fe308..bf485d11b95 100644 --- a/extra/yassl/taocrypt/src/md5.cpp +++ b/extra/yassl/taocrypt/src/md5.cpp @@ -28,15 +28,16 @@ #include "runtime.hpp" #include "md5.hpp" -#include STL_ALGORITHM_FILE +#ifdef USE_SYS_STL + #include <algorithm> +#else + #include "algorithm.hpp" +#endif namespace STL = STL_NAMESPACE; -#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM) - #define DO_MD5_ASM -#endif namespace TaoCrypt { @@ -84,10 +85,17 @@ void MD5::Swap(MD5& other) } -// Update digest with data of size len, do in blocks +#ifdef DO_MD5_ASM + +// Update digest with data of size len void MD5::Update(const byte* data, word32 len) { - byte* local = (byte*)buffer_; + if (!isMMX) { + HASHwithTransform::Update(data, len); + return; + } + + byte* local = reinterpret_cast<byte*>(buffer_); // remove buffered data if possible if (buffLen_) { @@ -99,27 +107,14 @@ void MD5::Update(const byte* data, word32 len) len -= add; if (buffLen_ == BLOCK_SIZE) { - ByteReverseIf(local, local, BLOCK_SIZE, LittleEndianOrder); Transform(); AddLength(BLOCK_SIZE); buffLen_ = 0; } } - // do block size transforms or all at once for asm + // at once for asm if (buffLen_ == 0) { - #ifndef DO_MD5_ASM - while (len >= BLOCK_SIZE) { - memcpy(&local[0], data, BLOCK_SIZE); - - data += BLOCK_SIZE; - len -= BLOCK_SIZE; - - ByteReverseIf(local, local, BLOCK_SIZE, LittleEndianOrder); - Transform(); - AddLength(BLOCK_SIZE); - } - #else word32 times = len / BLOCK_SIZE; if (times) { AsmTransform(data, times); @@ -128,7 +123,6 @@ void MD5::Update(const byte* data, word32 len) len -= add; data += add; } - #endif } // cache any data left @@ -139,7 +133,6 @@ void MD5::Update(const byte* data, word32 len) } -#ifdef DO_MD5_ASM /* diff --git a/extra/yassl/taocrypt/src/misc.cpp b/extra/yassl/taocrypt/src/misc.cpp index 084a263a4ae..7ab05582e95 100644 --- a/extra/yassl/taocrypt/src/misc.cpp +++ b/extra/yassl/taocrypt/src/misc.cpp @@ -30,6 +30,20 @@ #include "misc.hpp" +#ifdef __GNUC__ + #include <signal.h> + #include <setjmp.h> +#endif + +#ifdef USE_SYS_STL + #include <algorithm> +#else + #include "algorithm.hpp" +#endif + +namespace STL = STL_NAMESPACE; + + #ifdef YASSL_PURE_C void* operator new(size_t sz, TaoCrypt::new_t) @@ -156,5 +170,129 @@ unsigned long Crop(unsigned long value, unsigned int size) } + +#ifdef TAOCRYPT_X86ASM_AVAILABLE + +#ifndef _MSC_VER + static jmp_buf s_env; + static void SigIllHandler(int) + { + longjmp(s_env, 1); + } +#endif + + +bool HaveCpuId() +{ +#ifdef _MSC_VER + __try + { + __asm + { + mov eax, 0 + cpuid + } + } + __except (1) + { + return false; + } + return true; +#else + typedef void (*SigHandler)(int); + + SigHandler oldHandler = signal(SIGILL, SigIllHandler); + if (oldHandler == SIG_ERR) + return false; + + bool result = true; + if (setjmp(s_env)) + result = false; + else + __asm__ __volatile + ( + // save ebx in case -fPIC is being used + "push %%ebx; mov $0, %%eax; cpuid; pop %%ebx" + : + : + : "%eax", "%ecx", "%edx" + ); + + signal(SIGILL, oldHandler); + return result; +#endif +} + + +void CpuId(word32 input, word32 *output) +{ +#ifdef __GNUC__ + __asm__ + ( + // save ebx in case -fPIC is being used + "push %%ebx; cpuid; mov %%ebx, %%edi; pop %%ebx" + : "=a" (output[0]), "=D" (output[1]), "=c" (output[2]), "=d"(output[3]) + : "a" (input) + ); +#else + __asm + { + mov eax, input + cpuid + mov edi, output + mov [edi], eax + mov [edi+4], ebx + mov [edi+8], ecx + mov [edi+12], edx + } +#endif +} + + +bool IsPentium() +{ + if (!HaveCpuId()) + return false; + + word32 cpuid[4]; + + CpuId(0, cpuid); + STL::swap(cpuid[2], cpuid[3]); + if (memcmp(cpuid+1, "GenuineIntel", 12) != 0) + return false; + + CpuId(1, cpuid); + byte family = ((cpuid[0] >> 8) & 0xf); + if (family < 5) + return false; + + return true; +} + + + +static bool IsMmx() +{ + if (!IsPentium()) + return false; + + word32 cpuid[4]; + + CpuId(1, cpuid); + if ((cpuid[3] & (1 << 23)) == 0) + return false; + + return true; +} + + +bool isMMX = IsMmx(); + + +#endif // TAOCRYPT_X86ASM_AVAILABLE + + + + } // namespace diff --git a/extra/yassl/taocrypt/src/random.cpp b/extra/yassl/taocrypt/src/random.cpp index c7bb6ae9549..3fab1ddba23 100644 --- a/extra/yassl/taocrypt/src/random.cpp +++ b/extra/yassl/taocrypt/src/random.cpp @@ -50,8 +50,11 @@ namespace TaoCrypt { RandomNumberGenerator::RandomNumberGenerator() { byte key[32]; + byte junk[256]; + seed_.GenerateSeed(key, sizeof(key)); cipher_.SetKey(key, sizeof(key)); + GenerateBlock(junk, sizeof(junk)); // rid initial state } diff --git a/extra/yassl/taocrypt/src/ripemd.cpp b/extra/yassl/taocrypt/src/ripemd.cpp index 03c09edde84..98bfe4b2645 100644 --- a/extra/yassl/taocrypt/src/ripemd.cpp +++ b/extra/yassl/taocrypt/src/ripemd.cpp @@ -28,15 +28,16 @@ #include "runtime.hpp" #include "ripemd.hpp" -#include STL_ALGORITHM_FILE +#ifdef USE_SYS_STL + #include <algorithm> +#else + #include "algorithm.hpp" +#endif namespace STL = STL_NAMESPACE; -#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM) - #define DO_RIPEMD_ASM -#endif namespace TaoCrypt { @@ -86,10 +87,17 @@ void RIPEMD160::Swap(RIPEMD160& other) } -// Update digest with data of size len, do in blocks +#ifdef DO_RIPEMD_ASM + +// Update digest with data of size len void RIPEMD160::Update(const byte* data, word32 len) { - byte* local = (byte*)buffer_; + if (!isMMX) { + HASHwithTransform::Update(data, len); + return; + } + + byte* local = reinterpret_cast<byte*>(buffer_); // remove buffered data if possible if (buffLen_) { @@ -101,27 +109,14 @@ void RIPEMD160::Update(const byte* data, word32 len) len -= add; if (buffLen_ == BLOCK_SIZE) { - ByteReverseIf(local, local, BLOCK_SIZE, LittleEndianOrder); Transform(); AddLength(BLOCK_SIZE); buffLen_ = 0; } } - // do block size transforms or all at once for asm + // all at once for asm if (buffLen_ == 0) { - #ifndef DO_RIPEMD_ASM - while (len >= BLOCK_SIZE) { - memcpy(&local[0], data, BLOCK_SIZE); - - data += BLOCK_SIZE; - len -= BLOCK_SIZE; - - ByteReverseIf(local, local, BLOCK_SIZE, LittleEndianOrder); - Transform(); - AddLength(BLOCK_SIZE); - } - #else word32 times = len / BLOCK_SIZE; if (times) { AsmTransform(data, times); @@ -130,7 +125,6 @@ void RIPEMD160::Update(const byte* data, word32 len) len -= add; data += add; } - #endif } // cache any data left @@ -140,6 +134,8 @@ void RIPEMD160::Update(const byte* data, word32 len) } } +#endif // DO_RIPEMD_ASM + // for all #define F(x, y, z) (x ^ y ^ z) diff --git a/extra/yassl/taocrypt/src/sha.cpp b/extra/yassl/taocrypt/src/sha.cpp index 280d42fb3d4..b1273d9da8f 100644 --- a/extra/yassl/taocrypt/src/sha.cpp +++ b/extra/yassl/taocrypt/src/sha.cpp @@ -28,16 +28,16 @@ #include "runtime.hpp" #include <string.h> #include "sha.hpp" -#include STL_ALGORITHM_FILE +#ifdef USE_SYS_STL + #include <algorithm> +#else + #include "algorithm.hpp" +#endif namespace STL = STL_NAMESPACE; -#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM) - #define DO_SHA_ASM -#endif - namespace TaoCrypt { @@ -108,10 +108,18 @@ void SHA::Swap(SHA& other) } -// Update digest with data of size len, do in blocks + +#ifdef DO_SHA_ASM + +// Update digest with data of size len void SHA::Update(const byte* data, word32 len) { - byte* local = (byte*)buffer_; + if (!isMMX) { + HASHwithTransform::Update(data, len); + return; + } + + byte* local = reinterpret_cast<byte*>(buffer_); // remove buffered data if possible if (buffLen_) { @@ -123,27 +131,15 @@ void SHA::Update(const byte* data, word32 len) len -= add; if (buffLen_ == BLOCK_SIZE) { - ByteReverseIf(local, local, BLOCK_SIZE, BigEndianOrder); + ByteReverse(local, local, BLOCK_SIZE); Transform(); AddLength(BLOCK_SIZE); buffLen_ = 0; } } - // do block size transforms or all at once for asm + // all at once for asm if (buffLen_ == 0) { - #ifndef DO_SHA_ASM - while (len >= BLOCK_SIZE) { - memcpy(&local[0], data, BLOCK_SIZE); - - data += BLOCK_SIZE; - len -= BLOCK_SIZE; - - ByteReverseIf(local, local, BLOCK_SIZE, BigEndianOrder); - Transform(); - AddLength(BLOCK_SIZE); - } - #else word32 times = len / BLOCK_SIZE; if (times) { AsmTransform(data, times); @@ -152,7 +148,6 @@ void SHA::Update(const byte* data, word32 len) len -= add; data += add; } - #endif } // cache any data left @@ -162,6 +157,8 @@ void SHA::Update(const byte* data, word32 len) } } +#endif // DO_SHA_ASM + void SHA::Transform() { diff --git a/extra/yassl/taocrypt/src/twofish.cpp b/extra/yassl/taocrypt/src/twofish.cpp index a16a8f0d169..bb385331519 100644 --- a/extra/yassl/taocrypt/src/twofish.cpp +++ b/extra/yassl/taocrypt/src/twofish.cpp @@ -35,33 +35,20 @@ #include "twofish.hpp" -#if defined(TAOCRYPT_X86ASM_AVAILABLE) && defined(TAO_ASM) - #define DO_TWOFISH_ASM -#endif - namespace TaoCrypt { -#if !defined(DO_TWOFISH_ASM) - -// Generic Version -void Twofish::Process(byte* out, const byte* in, word32 sz) -{ - if (mode_ == ECB) - ECB_Process(out, in, sz); - else if (mode_ == CBC) - if (dir_ == ENCRYPTION) - CBC_Encrypt(out, in, sz); - else - CBC_Decrypt(out, in, sz); -} - -#else +#if defined(DO_TWOFISH_ASM) // ia32 optimized version void Twofish::Process(byte* out, const byte* in, word32 sz) { + if (!isMMX) { + Mode_BASE::Process(out, in, sz); + return; + } + word32 blocks = sz / BLOCK_SIZE; if (mode_ == ECB) diff --git a/extra/yassl/taocrypt/test/make.bat b/extra/yassl/taocrypt/test/make.bat index 5f01db68d0d..7b53e9abc90 100644 --- a/extra/yassl/taocrypt/test/make.bat +++ b/extra/yassl/taocrypt/test/make.bat @@ -1,7 +1,7 @@ REM quick and dirty build file for testing different MSDEVs setlocal -set myFLAGS= /I../include /I../../mySTL /c /W3 /G6 /O2 +set myFLAGS= /I../include /I../mySTL /c /W3 /G6 /O2 cl %myFLAGS% test.cpp diff --git a/extra/yassl/taocrypt/test/test.cpp b/extra/yassl/taocrypt/test/test.cpp index 28ef73dfac8..9e3ef709a78 100644 --- a/extra/yassl/taocrypt/test/test.cpp +++ b/extra/yassl/taocrypt/test/test.cpp @@ -247,6 +247,8 @@ void taocrypt_test(void* args) args.argv = argv; taocrypt_test(&args); + TaoCrypt::CleanUp(); + return args.return_code; } diff --git a/extra/yassl/testsuite/make.bat b/extra/yassl/testsuite/make.bat index 1bc7ce0513d..ea2677db481 100644 --- a/extra/yassl/testsuite/make.bat +++ b/extra/yassl/testsuite/make.bat @@ -1,7 +1,7 @@ REM quick and dirty build file for testing different MSDEVs setlocal -set myFLAGS= /I../include /I../taocrypt/include /I../mySTL /c /W3 /G6 /O2 /MT /D"WIN32" /D"NO_MAIN_DRIVER" +set myFLAGS= /I../include /I../taocrypt/include /I../taocrypt/mySTL /c /W3 /G6 /O2 /MT /D"WIN32" /D"NO_MAIN_DRIVER" cl %myFLAGS% testsuite.cpp cl %myFLAGS% ../examples/client/client.cpp diff --git a/extra/yassl/testsuite/test.hpp b/extra/yassl/testsuite/test.hpp index b23b36f0ba2..b2fed37f4e5 100644 --- a/extra/yassl/testsuite/test.hpp +++ b/extra/yassl/testsuite/test.hpp @@ -9,6 +9,8 @@ #include <stdlib.h> #include <assert.h> +//#define NON_BLOCKING // test server and client example (not echos) + #ifdef _WIN32 #include <winsock2.h> #include <process.h> @@ -23,16 +25,17 @@ #include <sys/types.h> #include <sys/socket.h> #include <pthread.h> +#ifdef NON_BLOCKING + #include <fcntl.h> +#endif #define SOCKET_T int #endif /* _WIN32 */ -#if !defined(_SOCKLEN_T) && defined(_WIN32) +#if !defined(_SOCKLEN_T) && \ + (defined(_WIN32) || defined(__NETWARE__) || defined(__APPLE__)) typedef int socklen_t; #endif -#if !defined(_SOCKLEN_T) && defined(__NETWARE__) - typedef size_t socklen_t; -#endif // Check type of third arg to accept @@ -262,6 +265,20 @@ inline void set_args(int& argc, char**& argv, func_args& args) } +inline void tcp_set_nonblocking(SOCKET_T& sockfd) +{ +#ifdef NON_BLOCKING + #ifdef _WIN32 + unsigned long blocking = 1; + int ret = ioctlsocket(sockfd, FIONBIO, &blocking); + #else + int flags = fcntl(sockfd, F_GETFL, 0); + int ret = fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); + #endif +#endif +} + + inline void tcp_socket(SOCKET_T& sockfd, sockaddr_in& addr) { sockfd = socket(AF_INET, SOCK_STREAM, 0); @@ -289,8 +306,7 @@ inline void tcp_connect(SOCKET_T& sockfd) sockaddr_in addr; tcp_socket(sockfd, addr); - if (connect(sockfd, (const sockaddr*)&addr, sizeof(addr)) != 0) - { + if (connect(sockfd, (const sockaddr*)&addr, sizeof(addr)) != 0) { tcp_close(sockfd); err_sys("tcp connect failed"); } @@ -302,19 +318,18 @@ inline void tcp_listen(SOCKET_T& sockfd) sockaddr_in addr; tcp_socket(sockfd, addr); - if (bind(sockfd, (const sockaddr*)&addr, sizeof(addr)) != 0) - { + if (bind(sockfd, (const sockaddr*)&addr, sizeof(addr)) != 0) { tcp_close(sockfd); err_sys("tcp bind failed"); } - if (listen(sockfd, 3) != 0) - { + if (listen(sockfd, 3) != 0) { tcp_close(sockfd); err_sys("tcp listen failed"); } } + inline void tcp_accept(SOCKET_T& sockfd, SOCKET_T& clientfd, func_args& args) { tcp_listen(sockfd); @@ -333,11 +348,14 @@ inline void tcp_accept(SOCKET_T& sockfd, SOCKET_T& clientfd, func_args& args) clientfd = accept(sockfd, (sockaddr*)&client, (ACCEPT_THIRD_T)&client_len); - if (clientfd == -1) - { + if (clientfd == -1) { tcp_close(sockfd); err_sys("tcp accept failed"); } + +#ifdef NON_BLOCKING + tcp_set_nonblocking(clientfd); +#endif } @@ -363,25 +381,30 @@ inline void showPeer(SSL* ssl) inline DH* set_tmpDH(SSL_CTX* ctx) { - static unsigned char dh512_p[] = + static unsigned char dh1024_p[] = { - 0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75, - 0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F, - 0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3, - 0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12, - 0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C, - 0x47,0x74,0xE8,0x33, + 0xE6, 0x96, 0x9D, 0x3D, 0x49, 0x5B, 0xE3, 0x2C, 0x7C, 0xF1, 0x80, 0xC3, + 0xBD, 0xD4, 0x79, 0x8E, 0x91, 0xB7, 0x81, 0x82, 0x51, 0xBB, 0x05, 0x5E, + 0x2A, 0x20, 0x64, 0x90, 0x4A, 0x79, 0xA7, 0x70, 0xFA, 0x15, 0xA2, 0x59, + 0xCB, 0xD5, 0x23, 0xA6, 0xA6, 0xEF, 0x09, 0xC4, 0x30, 0x48, 0xD5, 0xA2, + 0x2F, 0x97, 0x1F, 0x3C, 0x20, 0x12, 0x9B, 0x48, 0x00, 0x0E, 0x6E, 0xDD, + 0x06, 0x1C, 0xBC, 0x05, 0x3E, 0x37, 0x1D, 0x79, 0x4E, 0x53, 0x27, 0xDF, + 0x61, 0x1E, 0xBB, 0xBE, 0x1B, 0xAC, 0x9B, 0x5C, 0x60, 0x44, 0xCF, 0x02, + 0x3D, 0x76, 0xE0, 0x5E, 0xEA, 0x9B, 0xAD, 0x99, 0x1B, 0x13, 0xA6, 0x3C, + 0x97, 0x4E, 0x9E, 0xF1, 0x83, 0x9E, 0xB5, 0xDB, 0x12, 0x51, 0x36, 0xF7, + 0x26, 0x2E, 0x56, 0xA8, 0x87, 0x15, 0x38, 0xDF, 0xD8, 0x23, 0xC6, 0x50, + 0x50, 0x85, 0xE2, 0x1F, 0x0D, 0xD5, 0xC8, 0x6B, }; - static unsigned char dh512_g[] = + static unsigned char dh1024_g[] = { 0x02, }; DH* dh; if ( (dh = DH_new()) ) { - dh->p = BN_bin2bn(dh512_p, sizeof(dh512_p), 0); - dh->g = BN_bin2bn(dh512_g, sizeof(dh512_g), 0); + dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), 0); + dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), 0); } if (!dh->p || !dh->g) { DH_free(dh); diff --git a/include/Makefile.am b/include/Makefile.am index 814badc24be..8651a2dd9b1 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -70,6 +70,7 @@ abi_check: $(HEADERS_ABI) mysql_version.h mysql_h.ic if [ @ICHECK@ != no ] ; then \ @ICHECK@ --canonify --skip-from-re /usr/ -o $@.ic mysql.h; \ @ICHECK@ --compare mysql_h.ic $@.ic; \ + $(RM) -f $@.ic; \ fi; \ touch abi_check; diff --git a/include/my_sys.h b/include/my_sys.h index d185913cda1..7faffd6a18f 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -857,12 +857,6 @@ extern int my_getncpus(); #else #define my_mmap(a,b,c,d,e,f) mmap(a,b,c,d,e,f) #endif -#ifdef HAVE_GETPAGESIZE -#define my_getpagesize() getpagesize() -#else -/* qnx ? */ -#define my_getpagesize() 8192 -#endif #define my_munmap(a,b) munmap((a),(b)) #else @@ -880,16 +874,17 @@ extern int my_getncpus(); #define HAVE_MMAP #endif -#ifndef __NETWARE__ -int my_getpagesize(void); -#else -#define my_getpagesize() 8192 -#endif - void *my_mmap(void *, size_t, int, int, int, my_off_t); int my_munmap(void *, size_t); #endif +/* my_getpagesize */ +#ifdef HAVE_GETPAGESIZE +#define my_getpagesize() getpagesize() +#else +int my_getpagesize(void); +#endif + int my_msync(int, void *, size_t, int); /* character sets */ diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am index e8f00902a33..aa5c2106e8b 100644 --- a/mysql-test/Makefile.am +++ b/mysql-test/Makefile.am @@ -66,6 +66,7 @@ dist-hook: $(INSTALL_DATA) $(srcdir)/std_data/des_key_file $(distdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/*.pem $(distdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/*.frm $(distdir)/std_data + $(INSTALL_DATA) $(srcdir)/std_data/*.MY* $(distdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/*.cnf $(distdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/ndb_backup50/BACKUP* $(distdir)/std_data/ndb_backup50 $(INSTALL_DATA) $(srcdir)/std_data/ndb_backup51/BACKUP* $(distdir)/std_data/ndb_backup51 @@ -107,6 +108,7 @@ install-data-local: $(INSTALL_DATA) $(srcdir)/std_data/Moscow_leap $(DESTDIR)$(testdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/*.pem $(DESTDIR)$(testdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/*.frm $(DESTDIR)$(testdir)/std_data + $(INSTALL_DATA) $(srcdir)/std_data/*.MY* $(distdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/*.cnf $(DESTDIR)$(testdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/ndb_backup50/BACKUP* $(DESTDIR)$(testdir)/std_data/ndb_backup50 $(INSTALL_DATA) $(srcdir)/std_data/ndb_backup51/BACKUP* $(DESTDIR)$(testdir)/std_data/ndb_backup51 diff --git a/mysql-test/extra/rpl_tests/rpl_deadlock.test b/mysql-test/extra/rpl_tests/rpl_deadlock.test index 526925d6a83..236a5f801b0 100644 --- a/mysql-test/extra/rpl_tests/rpl_deadlock.test +++ b/mysql-test/extra/rpl_tests/rpl_deadlock.test @@ -101,7 +101,7 @@ show slave status; # Now we repeat 2), but with BEGIN in the same relay log as # COMMIT (to see if seeking into hot log is ok). - +set @my_max_relay_log_size= @@global.max_relay_log_size; set global max_relay_log_size=0; # This is really copy-paste of 2) of above @@ -126,5 +126,6 @@ show slave status; connection master; drop table t1,t2,t3,t4; sync_slave_with_master; +set global max_relay_log_size= @my_max_relay_log_size; --echo End of 5.1 tests diff --git a/mysql-test/extra/rpl_tests/rpl_max_relay_size.test b/mysql-test/extra/rpl_tests/rpl_max_relay_size.test index 50325f83358..5b995374ba0 100644 --- a/mysql-test/extra/rpl_tests/rpl_max_relay_size.test +++ b/mysql-test/extra/rpl_tests/rpl_max_relay_size.test @@ -34,6 +34,7 @@ reset slave; --echo # Test 1 --echo # +set @my_max_binlog_size= @@global.max_binlog_size; set global max_binlog_size=8192; set global max_relay_log_size=8192-1; # mapped to 4096 select @@global.max_relay_log_size; @@ -130,6 +131,10 @@ flush logs; -- replace_column 3 <Binlog_Ignore_DB> show master status; +# Restore max_binlog_size +connection slave; +set global max_binlog_size= @my_max_binlog_size; + --echo # --echo # End of 4.1 tests --echo # diff --git a/mysql-test/lib/mtr_cases.pl b/mysql-test/lib/mtr_cases.pl index d270d72d526..9e943fec9ef 100644 --- a/mysql-test/lib/mtr_cases.pl +++ b/mysql-test/lib/mtr_cases.pl @@ -593,6 +593,10 @@ sub mtr_options_from_test_file($$) { while ( my $line= <$F> ) { + + # Skip line if it start's with # + next if ( $line =~ /^#/ ); + # Match this line against tag in "tags" array foreach my $tag (@tags) { diff --git a/mysql-test/lib/mtr_io.pl b/mysql-test/lib/mtr_io.pl index 5be1d2ffddb..842dc09413d 100644 --- a/mysql-test/lib/mtr_io.pl +++ b/mysql-test/lib/mtr_io.pl @@ -13,6 +13,8 @@ sub mtr_tofile ($@); sub mtr_tonewfile($@); sub mtr_lastlinefromfile($); sub mtr_appendfile_to_file ($$); +sub mtr_grab_file($); + ############################################################################## # @@ -129,6 +131,7 @@ sub unspace { return "$quote$string$quote"; } +# Read a whole file, stripping leading and trailing whitespace. sub mtr_fromfile ($) { my $file= shift; @@ -182,5 +185,16 @@ sub mtr_appendfile_to_file ($$) { close TOFILE; } +# Read a whole file verbatim. +sub mtr_grab_file($) { + my $file= shift; + open(FILE, '<', $file) + or return undef; + local $/= undef; + my $data= scalar(<FILE>); + close FILE; + return $data; +} + 1; diff --git a/mysql-test/lib/mtr_process.pl b/mysql-test/lib/mtr_process.pl index 8a8b8d0858a..330dfddf1d3 100644 --- a/mysql-test/lib/mtr_process.pl +++ b/mysql-test/lib/mtr_process.pl @@ -708,7 +708,7 @@ sub mtr_wait_blocking($) { } } -# Start "mysqladmin shutdown" for a specific mysqld +# Start "mysqladmin <command>" for a specific mysqld sub mtr_mysqladmin_start($$$) { my $srv= shift; my $command= shift; @@ -738,9 +738,8 @@ sub mtr_mysqladmin_start($$$) { # Shutdown time must be high as slave may be in reconnect mtr_add_arg($args, "--shutdown_timeout=$adm_shutdown_tmo"); mtr_add_arg($args, "$command"); - my $path_mysqladmin_log= "$::opt_vardir/log/mysqladmin.log"; my $pid= mtr_spawn($::exe_mysqladmin, $args, - "", $path_mysqladmin_log, $path_mysqladmin_log, "", + "", "", "", "", { append_log_file => 1 }); mtr_verbose("mtr_mysqladmin_start, pid: $pid"); return $pid; diff --git a/mysql-test/lib/mtr_report.pl b/mysql-test/lib/mtr_report.pl index abf9cd066b1..f840c1275d3 100644 --- a/mysql-test/lib/mtr_report.pl +++ b/mysql-test/lib/mtr_report.pl @@ -34,7 +34,12 @@ sub mtr_verbose (@); # We can't use diff -u or diff -a as these are not portable sub mtr_show_failed_diff ($) { - my $tname= shift; + my $result_file_name= shift; + + # The reject and log files have been dumped to + # to filenames based on the result_file's name + my $tname= basename($result_file_name); + $tname=~ s/\..*$//; my $reject_file= "r/$tname.reject"; my $result_file= "r/$tname.result"; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 2ad24786358..73755cd2df9 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -103,7 +103,6 @@ our $glob_mysql_bench_dir= undef; our $glob_hostname= undef; our $glob_scriptname= undef; our $glob_timers= undef; -our $glob_use_running_server= 0; our $glob_use_running_ndbcluster= 0; our $glob_use_running_ndbcluster_slave= 0; our $glob_use_embedded_server= 0; @@ -141,6 +140,7 @@ our $opt_verbose= 0; # Verbose output, enable with --verbose our $exe_master_mysqld; our $exe_mysql; our $exe_mysqladmin; +our $exe_mysql_upgrade; our $exe_mysqlbinlog; our $exe_mysql_client_test; our $exe_mysqld; @@ -150,6 +150,7 @@ our $exe_mysqlslap; our $exe_mysqlimport; our $exe_mysqlshow; our $exe_mysql_fix_system_tables; +our $file_mysql_fix_privilege_tables; our $exe_mysqltest; our $exe_ndbd; our $exe_ndb_mgmd; @@ -162,7 +163,7 @@ our $exe_libtool; our $opt_bench= 0; our $opt_small_bench= 0; -our $opt_big_test= 0; # Send --big-test to mysqltest +our $opt_big_test= 0; our @opt_extra_mysqld_opt; @@ -179,7 +180,10 @@ our $opt_debug; our $opt_do_test; our @opt_cases; # The test cases names in argv our $opt_embedded_server; -our $opt_extern; + +our $opt_extern= 0; +our $opt_socket; + our $opt_fast; our $opt_force; our $opt_reorder= 0; @@ -224,8 +228,8 @@ our $opt_ndbcluster_port_slave; our $opt_ndbconnectstring_slave; our $opt_record; +my $opt_report_features; our $opt_check_testcases; -my $opt_report_features; our $opt_skip; our $opt_skip_rpl; @@ -236,17 +240,11 @@ our $opt_skip_im; our $opt_sleep; -our $opt_sleep_time_after_restart= 1; -our $opt_sleep_time_for_delete= 10; our $opt_testcase_timeout; our $opt_suite_timeout; my $default_testcase_timeout= 15; # 15 min max my $default_suite_timeout= 180; # 3 hours max -our $opt_socket; - -our $opt_source_dist; - our $opt_start_and_exit; our $opt_start_dirty; our $opt_start_from; @@ -256,7 +254,6 @@ our $opt_strace_client; our $opt_timer= 1; our $opt_user; -our $opt_user_test; our $opt_valgrind= 0; our $opt_valgrind_mysqld= 0; @@ -278,7 +275,6 @@ our $opt_stress_test_file= ""; our $opt_wait_for_master; our $opt_wait_for_slave; -our $opt_wait_timeout= 10; our $opt_warnings; @@ -308,6 +304,8 @@ our $glob_tot_real_time= 0; our %mysqld_variables; +my $source_dist= 0; + ###################################################################### # @@ -319,11 +317,12 @@ sub main (); sub initial_setup (); sub command_line_setup (); sub set_mtr_build_thread_ports($); -sub datadir_setup (); +sub datadir_list_setup (); sub executable_setup (); sub environment_setup (); sub kill_running_servers (); -sub cleanup_stale_files (); +sub remove_stale_vardir (); +sub setup_vardir (); sub check_ssl_support ($); sub check_running_as_root(); sub check_ndbcluster_support ($); @@ -467,6 +466,15 @@ sub command_line_setup () { $im_port= 9312; $im_mysqld1_port= 9313; $im_mysqld2_port= 9314; + + # If so requested, we try to avail ourselves of a unique build thread number. + if ( $ENV{'MTR_BUILD_THREAD'} ) { + if ( lc($ENV{'MTR_BUILD_THREAD'}) eq 'auto' ) { + print "Requesting build thread... "; + $ENV{'MTR_BUILD_THREAD'} = mtr_require_unique_id_and_wait("/tmp/mysql-test-ports", 200, 299); + print "got ".$ENV{'MTR_BUILD_THREAD'}."\n"; + } + } if ( $ENV{'MTR_BUILD_THREAD'} ) { @@ -574,7 +582,7 @@ sub command_line_setup () { 'tmpdir=s' => \$opt_tmpdir, 'vardir=s' => \$opt_vardir, 'benchdir=s' => \$glob_mysql_bench_dir, - 'mem:s' => \$opt_mem, + 'mem' => \$opt_mem, # Misc 'report-features' => \$opt_report_features, @@ -591,9 +599,7 @@ sub command_line_setup () { 'start-and-exit' => \$opt_start_and_exit, 'timer!' => \$opt_timer, 'unified-diff|udiff' => \$opt_udiff, - 'user-test=s' => \$opt_user_test, 'user=s' => \$opt_user, - 'wait-timeout=i' => \$opt_wait_timeout, 'testcase-timeout=i' => \$opt_testcase_timeout, 'suite-timeout=i' => \$opt_suite_timeout, 'warnings|log-warnings' => \$opt_warnings, @@ -625,7 +631,7 @@ sub command_line_setup () { if ( -d "../sql" ) { - $opt_source_dist= 1; + $source_dist= 1; } $glob_hostname= mtr_short_hostname(); @@ -649,7 +655,7 @@ sub command_line_setup () { # directory. And we install "/usr/share/mysql-test". Moving up one # more directory relative to "mysql-test" gives us a usable base # directory for RPM installs. - if ( ! $opt_source_dist and ! -d "$glob_basedir/bin" ) + if ( ! $source_dist and ! -d "$glob_basedir/bin" ) { $glob_basedir= dirname($glob_basedir); } @@ -661,7 +667,7 @@ sub command_line_setup () { unless -d $glob_mysql_bench_dir; $path_my_basedir= - $opt_source_dist ? $glob_mysql_test_dir : $glob_basedir; + $source_dist ? $glob_mysql_test_dir : $glob_basedir; $glob_timers= mtr_init_timers(); @@ -670,10 +676,10 @@ sub command_line_setup () { # number as early as possible # - # Look for the client binaries - $path_client_bindir= mtr_path_exists(vs_config_dirs('client', ''), - "$glob_basedir/client_release", + # Look for the client binaries directory + $path_client_bindir= mtr_path_exists("$glob_basedir/client_release", "$glob_basedir/client_debug", + vs_config_dirs('client', ''), "$glob_basedir/client", "$glob_basedir/bin"); @@ -804,27 +810,12 @@ sub command_line_setup () { $opt_vardir= "$glob_mysql_test_dir/$opt_vardir"; } - # Ensure a proper error message - mkpath("$opt_vardir"); - unless ( -d $opt_vardir and -w $opt_vardir ) - { - mtr_error("Writable 'var' directory is needed, use the '--vardir' option"); - } - # -------------------------------------------------------------------------- # Set tmpdir # -------------------------------------------------------------------------- $opt_tmpdir= "$opt_vardir/tmp" unless $opt_tmpdir; $opt_tmpdir =~ s,/+$,,; # Remove ending slash if any - # -------------------------------------------------------------------------- - # Set socket - # -------------------------------------------------------------------------- - if (!$opt_socket) - { - $opt_socket= $mysqld_variables{'socket'}; - } - # -------------------------------------------------------------------------- # Check im suport # -------------------------------------------------------------------------- @@ -922,17 +913,17 @@ sub command_line_setup () { } # -------------------------------------------------------------------------- - # Sleep flag + # Big test flags # -------------------------------------------------------------------------- - if ( $opt_sleep ) - { - $opt_sleep_time_after_restart= $opt_sleep; - } + if ( $opt_big_test ) + { + $ENV{'BIG_TEST'}= 1; + } # -------------------------------------------------------------------------- # Gcov flag # -------------------------------------------------------------------------- - if ( $opt_gcov and ! $opt_source_dist ) + if ( $opt_gcov and ! $source_dist ) { mtr_error("Coverage test needs the source - please use source dist"); } @@ -946,8 +937,6 @@ sub command_line_setup () { { # Indicate that we are using debugger $glob_debugger= 1; - # Increase timeouts - $opt_wait_timeout= 300; if ( $opt_extern ) { mtr_error("Can't use --extern when using debugger"); @@ -1013,16 +1002,9 @@ sub command_line_setup () { $opt_suite_timeout*= 6 if $opt_valgrind; } - # Increase times to wait for executables to start if using valgrind - if ( $opt_valgrind ) - { - $opt_sleep_time_after_restart= 10; - $opt_sleep_time_for_delete= 60; - } - if ( ! $opt_user ) { - if ( $glob_use_running_server ) + if ( $opt_extern ) { $opt_user= "test"; } @@ -1204,9 +1186,17 @@ sub command_line_setup () { if ( $opt_extern ) { - $glob_use_running_server= 1; - $opt_skip_rpl= 1; # We don't run rpl test cases - $master->[0]->{'path_sock'}= $opt_socket; + # Turn off features not supported when running with extern server + $opt_skip_rpl= 1; + + # Setup master->[0] with the settings for the extern server + $master->[0]->{'path_sock'}= $opt_socket if $opt_socket; + mtr_report("Using extern server at '$master->[0]->{path_sock}'"); + } + else + { + mtr_error("--socket can only be used in combination with --extern") + if $opt_socket; } $path_timefile= "$opt_vardir/log/mysqltest-time"; @@ -1260,7 +1250,7 @@ sub set_mtr_build_thread_ports($) { } -sub datadir_setup () { +sub datadir_list_setup () { # Make a list of all data_dirs @data_dir_lst = ( @@ -1290,26 +1280,15 @@ sub datadir_setup () { sub collect_mysqld_features () { - # - # Execute "mysqld --no-defaults --help --verbose", that will - # print out version and a list of all features and settings - # my $found_variable_list_start= 0; - my $spec_file= "$glob_mysql_test_dir/mysqld.spec.$$"; - if ( mtr_run($exe_mysqld, - ["--no-defaults", - "--verbose", - "--help"], - "", "$spec_file", "$spec_file", "") != 0 ) - { - mtr_error("Failed to get version and list of features from %s", - $exe_mysqld); - } - my $F= IO::File->new($spec_file) or - mtr_error("can't open file \"$spec_file\": $!"); + # + # Execute "mysqld --no-defaults --help --verbose" to get a + # of all features and settings + # + my $list= `$exe_mysqld --no-defaults --verbose --help`; - while ( my $line= <$F> ) + foreach my $line (split('\n', $list)) { # First look for version if ( !$mysql_version_id ) @@ -1362,7 +1341,7 @@ sub collect_mysqld_features () { } } } - unlink($spec_file); + mtr_error("Could not find version of MySQL") unless $mysql_version_id; mtr_error("Could not find variabes list") unless $found_variable_list_start; @@ -1465,7 +1444,15 @@ sub executable_setup () { $exe_mysql= mtr_exe_exists("$path_client_bindir/mysql"); if ( $mysql_version_id >= 50100 ) { - $exe_mysqlslap= mtr_exe_exists("$path_client_bindir/mysqlslap"); + $exe_mysqlslap= mtr_exe_exists("$path_client_bindir/mysqlslap"); + } + if ( $mysql_version_id >= 50000 and !$glob_use_embedded_server ) + { + $exe_mysql_upgrade= mtr_exe_exists("$path_client_bindir/mysql_upgrade") + } + else + { + $exe_mysql_upgrade= ""; } if ( ! $glob_win32 ) @@ -1476,6 +1463,10 @@ sub executable_setup () { "$path_client_bindir/mysql_fix_privilege_tables"); } + # Look for mysql_fix_privilege_tables.sql script + $file_mysql_fix_privilege_tables= + mtr_file_exists("$glob_basedir/scripts/mysql_fix_privilege_tables.sql", + "$glob_basedir/share/mysql_fix_privilege_tables.sql"); if ( ! $opt_skip_ndbcluster and executable_setup_ndb()) { @@ -1506,13 +1497,13 @@ sub executable_setup () { if ( $glob_use_embedded_server ) { $exe_mysqltest= - mtr_exe_exists(vs_config_dirs('libmysqld/examples', 'mysqltest_embedded'), - "$glob_basedir/libmysqld/examples/mysqltest_embedded", + mtr_exe_exists(vs_config_dirs('libmysqld/examples','mysqltest_embedded'), + "$glob_basedir/libmysqld/examples/mysqltest_embedded", "$path_client_bindir/mysqltest_embedded"); } else { - $exe_mysqltest= mtr_exe_exists("$path_client_bindir/mysqltest"); + $exe_mysqltest= mtr_exe_exists("$path_client_bindir/mysqltest"); } # Look for mysql_client_test executable which may _not_ exist in @@ -1591,6 +1582,33 @@ sub mysql_client_test_arguments() return join(" ", $exe, @$args); } +sub mysql_upgrade_arguments() +{ + my $exe= $exe_mysql_upgrade; + + my $args; + mtr_init_args(\$args); +# if ( $opt_valgrind_mysql_ugrade ) +# { +# valgrind_arguments($args, \$exe); +# } + + mtr_add_arg($args, "--no-defaults"); + mtr_add_arg($args, "--user=root"); + mtr_add_arg($args, "--port=$master->[0]->{'port'}"); + mtr_add_arg($args, "--socket=$master->[0]->{'path_sock'}"); + mtr_add_arg($args, "--datadir=$master->[0]->{'path_myddir'}"); + mtr_add_arg($args, "--basedir=$glob_basedir"); + + if ( $opt_debug ) + { + mtr_add_arg($args, + "--debug=d:t:A,$path_vardir_trace/log/mysql_upgrade.trace"); + } + + return join(" ", $exe, @$args); +} + # Note that some env is setup in spawn/run, in "mtr_process.pl" sub environment_setup () { @@ -1603,7 +1621,7 @@ sub environment_setup () { # Setup LD_LIBRARY_PATH so the libraries from this distro/clone # are used in favor of the system installed ones # -------------------------------------------------------------------------- - if ( $opt_source_dist ) + if ( $source_dist ) { push(@ld_library_paths, "$glob_basedir/libmysql/.libs/", "$glob_basedir/libmysql_r/.libs/", @@ -1635,9 +1653,17 @@ sub environment_setup () { # impossible to add correct supressions, that means if "/usr/lib/debug" # is available, it should be added to # LD_LIBRARY_PATH + # + # But pthread is broken in libc6-dbg on Debian <= 3.1 (see Debian + # bug 399035, http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=399035), + # so don't change LD_LIBRARY_PATH on that platform. # -------------------------------------------------------------------------- my $debug_libraries_path= "/usr/lib/debug"; - if ( $opt_valgrind and -d $debug_libraries_path ) + my $deb_version; + if ( $opt_valgrind and -d $debug_libraries_path and + (! -e '/etc/debian_version' or + ($deb_version= mtr_grab_file('/etc/debian_version')) == 0 or + $deb_version > 3.1 ) ) { push(@ld_library_paths, $debug_libraries_path); } @@ -1661,7 +1687,7 @@ sub environment_setup () { $ENV{'UMASK'}= "0660"; # The octal *string* $ENV{'UMASK_DIR'}= "0770"; # The octal *string* $ENV{'LC_COLLATE'}= "C"; - $ENV{'USE_RUNNING_SERVER'}= $glob_use_running_server; + $ENV{'USE_RUNNING_SERVER'}= $opt_extern; $ENV{'MYSQL_TEST_DIR'}= $glob_mysql_test_dir; $ENV{'MYSQLTEST_VARDIR'}= $opt_vardir; $ENV{'MYSQL_TMP_DIR'}= $opt_tmpdir; @@ -1674,6 +1700,7 @@ sub environment_setup () { $ENV{'SLAVE_MYPORT1'}= $slave->[1]->{'port'}; $ENV{'SLAVE_MYPORT2'}= $slave->[2]->{'port'}; $ENV{'MYSQL_TCP_PORT'}= $mysqld_variables{'port'}; + $ENV{'DEFAULT_MASTER_PORT'}= $mysqld_variables{'master-port'}; $ENV{'IM_PATH_SOCK'}= $instance_manager->{path_sock}; $ENV{'IM_USERNAME'}= $instance_manager->{admin_login}; @@ -1851,6 +1878,14 @@ sub environment_setup () { # ---------------------------------------------------- $ENV{'MYSQL_CLIENT_TEST'}= mysql_client_test_arguments(); + # ---------------------------------------------------- + # Setup env so childs can execute mysql_upgrade + # ---------------------------------------------------- + if ( $mysql_version_id >= 50000 ) + { + $ENV{'MYSQL_UPGRADE'}= mysql_upgrade_arguments(); + } + # ---------------------------------------------------- # Setup env so childs can execute mysql_fix_system_tables # ---------------------------------------------------- @@ -1864,12 +1899,17 @@ sub environment_setup () { "--socket=$master->[0]->{'path_sock'}"; $ENV{'MYSQL_FIX_SYSTEM_TABLES'}= $cmdline_mysql_fix_system_tables; } + $ENV{'MYSQL_FIX_PRIVILEGE_TABLES'}= $file_mysql_fix_privilege_tables; # ---------------------------------------------------- # Setup env so childs can execute my_print_defaults # ---------------------------------------------------- $ENV{'MYSQL_MY_PRINT_DEFAULTS'}= $exe_my_print_defaults; + # ---------------------------------------------------- + # Setup env so childs can execute mysqladmin + # ---------------------------------------------------- + $ENV{'MYSQLADMIN'}= $exe_mysqladmin; # ---------------------------------------------------- # Setup env so childs can execute perror @@ -1890,7 +1930,7 @@ sub environment_setup () { # ---------------------------------------------------- # We are nice and report a bit about our settings # ---------------------------------------------------- - if (!$opt_extern && $opt_verbose) + if (!$opt_extern) { print "Using MTR_BUILD_THREAD = $ENV{MTR_BUILD_THREAD}\n"; print "Using MASTER_MYPORT = $ENV{MASTER_MYPORT}\n"; @@ -1964,29 +2004,23 @@ sub kill_running_servers () { # This is different from terminating processes we have # started from this run of the script, this is terminating # leftovers from previous runs. - - if ( ! -d $opt_vardir ) - { - if ( -l $opt_vardir and ! -d readlink($opt_vardir) ) - { - mtr_report("Removing $opt_vardir symlink without destination"); - unlink($opt_vardir); - } - # The "var" dir does not exist already - # the processes that mtr_kill_leftovers start will write - # their log files to var/log so it should be created - mkpath("$opt_vardir/log"); - } mtr_kill_leftovers(); } } -sub cleanup_stale_files () { - - my $created_by_mem_file= "$glob_mysql_test_dir/var/created_by_mem"; +# +# Remove var and any directories in var/ created by previous +# tests +# +sub remove_stale_vardir () { mtr_report("Removing Stale Files"); + # Safety! + mtr_error("No, don't remove the vardir when running with --extern") + if $opt_extern; + + mtr_verbose("opt_vardir: $opt_vardir"); if ( $opt_vardir eq $default_vardir ) { # @@ -1995,29 +2029,47 @@ sub cleanup_stale_files () { if ( -l $opt_vardir) { # var is a symlink - if (-f $created_by_mem_file) + + if ( $opt_mem and readlink($opt_vardir) eq $opt_mem ) { # Remove the directory which the link points at + mtr_verbose("Removing " . readlink($opt_vardir)); rmtree(readlink($opt_vardir)); - # Remove the entire "var" dir - rmtree("$opt_vardir/"); + # Remove the "var" symlink + mtr_verbose("unlink($opt_vardir)"); + unlink($opt_vardir); + } + elsif ( $opt_mem ) + { + # Just remove the "var" symlink + mtr_report("WARNING: Removing '$opt_vardir' symlink it's wrong"); + + mtr_verbose("unlink($opt_vardir)"); unlink($opt_vardir); } else { # Some users creates a soft link in mysql-test/var to another area - # - allow it + # - allow it, but remove all files in it + mtr_report("WARNING: Using the 'mysql-test/var' symlink"); - rmtree("$opt_vardir/log"); - rmtree("$opt_vardir/ndbcluster-$opt_ndbcluster_port"); - rmtree("$opt_vardir/run"); - rmtree("$opt_vardir/tmp"); + + # Make sure the directory where it points exist + mtr_error("The destination for symlink $opt_vardir does not exist") + if ! -d readlink($opt_vardir); + + foreach my $bin ( glob("$opt_vardir/*") ) + { + mtr_verbose("Removing bin $bin"); + rmtree($bin); + } } } else { # Remove the entire "var" dir + mtr_verbose("Removing $opt_vardir/"); rmtree("$opt_vardir/"); } } @@ -2029,21 +2081,56 @@ sub cleanup_stale_files () { # Remove the var/ dir in mysql-test dir if any # this could be an old symlink that shouldn't be there + mtr_verbose("Removing $default_vardir"); rmtree($default_vardir); # Remove the "var" dir + mtr_verbose("Removing $opt_vardir/"); rmtree("$opt_vardir/"); } +} - if ( $opt_mem ) +# +# Create var and the directories needed in var +# +sub setup_vardir() { + mtr_report("Creating Directories"); + + if ( $opt_vardir eq $default_vardir ) { - # Runinng with var as a link to some "memory" location, normally tmpfs - rmtree($opt_mem); - mkpath($opt_mem); - mtr_report("Creating symlink from $opt_vardir to $opt_mem"); - symlink($opt_mem, $opt_vardir); - # Put a small file to recognize this dir was created by --mem - mtr_tofile($created_by_mem_file, $opt_mem); + # + # Running with "var" in mysql-test dir + # + if ( -l $opt_vardir ) + { + # it's a symlink + + # Make sure the directory where it points exist + mtr_error("The destination for symlink $opt_vardir does not exist") + if ! -d readlink($opt_vardir); + } + elsif ( $opt_mem ) + { + # Runinng with "var" as a link to some "memory" location, normally tmpfs + mtr_verbose("Creating $opt_mem"); + mkpath($opt_mem); + + mtr_report("Symlinking 'var' to '$opt_mem'"); + symlink($opt_mem, $opt_vardir); + } + } + + if ( ! -d $opt_vardir ) + { + mtr_verbose("Creating $opt_vardir"); + mkpath($opt_vardir); + } + + # Ensure a proper error message if vardir couldn't be created + unless ( -d $opt_vardir and -w $opt_vardir ) + { + mtr_error("Writable 'var' directory is needed, use the " . + "'--vardir=<path>' option"); } mkpath("$opt_vardir/log"); @@ -2051,10 +2138,9 @@ sub cleanup_stale_files () { mkpath("$opt_vardir/tmp"); mkpath($opt_tmpdir) if $opt_tmpdir ne "$opt_vardir/tmp"; - # Remove old and create new data dirs + # Create new data dirs foreach my $data_dir (@data_dir_lst) { - rmtree("$data_dir"); mkpath("$data_dir/mysql"); mkpath("$data_dir/test"); } @@ -2568,7 +2654,7 @@ sub run_suite () { mtr_print_line(); if ( ! $glob_debugger and - ! $glob_use_running_server and + ! $opt_extern and ! $glob_use_embedded_server ) { stop_all_servers(); @@ -2597,28 +2683,41 @@ sub run_suite () { sub initialize_servers () { - datadir_setup(); + datadir_list_setup(); - if ( ! $glob_use_running_server ) + if ( $opt_extern ) + { + # Running against an already started server, if the specified + # vardir does not already exist it should be created + if ( ! -d $opt_vardir ) + { + mtr_report("Creating '$opt_vardir'"); + setup_vardir(); + } + else + { + mtr_report("No need to create '$opt_vardir' it already exists"); + } + } + else { kill_running_servers(); if ( ! $opt_start_dirty ) { - cleanup_stale_files(); + remove_stale_vardir(); + setup_vardir(); + mysql_install_db(); if ( $opt_force ) { + # Save a snapshot of the freshly installed db + # to make it possible to restore to a known point in time save_installed_db(); } } - check_running_as_root(); - } - else - { - # We have to create the 'var' and related directories - cleanup_stale_files(); } + check_running_as_root(); } sub mysql_install_db () { @@ -2985,29 +3084,15 @@ sub do_before_run_mysqltest($) unlink("$result_dir/$tname.log"); unlink("$result_dir/$tname.warnings"); - if (!$opt_extern) - { - mtr_tonewfile($path_current_test_log,"$tname\n"); # Always tell where we are - - # output current test to ndbcluster log file to enable diagnostics - mtr_tofile($path_ndb_testrun_log,"CURRENT TEST $tname\n"); - - mtr_tofile($master->[0]->{'path_myerr'},"CURRENT_TEST: $tname\n"); - if ( $master->[1]->{'pid'} ) - { - mtr_tofile($master->[1]->{'path_myerr'},"CURRENT_TEST: $tname\n"); - } - } - if ( $mysql_version_id < 50000 ) { - # Set envirnoment variable NDB_STATUS_OK to 1 + # Set environment variable NDB_STATUS_OK to 1 # if script decided to run mysqltest cluster _is_ installed ok $ENV{'NDB_STATUS_OK'} = "1"; } elsif ( $mysql_version_id < 50100 ) { - # Set envirnoment variable NDB_STATUS_OK to YES + # Set environment variable NDB_STATUS_OK to YES # if script decided to run mysqltest cluster _is_ installed ok $ENV{'NDB_STATUS_OK'} = "YES"; } @@ -3018,14 +3103,34 @@ sub do_after_run_mysqltest($) my $tinfo= shift; my $tname= $tinfo->{'name'}; - mtr_tofile($path_mysqltest_log,"CURRENT TEST $tname\n"); - # Save info from this testcase run to mysqltest.log + mtr_appendfile_to_file($path_current_test_log, $path_mysqltest_log) + if -f $path_current_test_log; mtr_appendfile_to_file($path_timefile, $path_mysqltest_log) if -f $path_timefile; } +sub run_testcase_mark_logs($) +{ + my ($log_msg)= @_; + + # Write a marker to all log files + + # The file indicating current test name + mtr_tonewfile($path_current_test_log, $log_msg); + + # each mysqld's .err file + foreach my $mysqld (@{$master}, @{$slave}) + { + mtr_tofile($mysqld->{path_myerr}, $log_msg); + } + + # ndbcluster log file + mtr_tofile($path_ndb_testrun_log, $log_msg); + +} + sub find_testcase_skipped_reason($) { my ($tinfo)= @_; @@ -3127,7 +3232,7 @@ sub run_testcase ($) { # ------------------------------------------------------- $ENV{'TZ'}= $tinfo->{'timezone'}; - mtr_verbose("Starting server with timezone: $tinfo->{'timezone'}"); + mtr_verbose("Setting timezone: $tinfo->{'timezone'}"); my $master_restart= run_testcase_need_master_restart($tinfo); my $slave_restart= run_testcase_need_slave_restart($tinfo); @@ -3135,7 +3240,7 @@ sub run_testcase ($) { if ($master_restart or $slave_restart) { # Can't restart a running server that may be in use - if ( $glob_use_running_server ) + if ( $opt_extern ) { mtr_report_test_name($tinfo); $tinfo->{comment}= "Can't restart a running server"; @@ -3145,6 +3250,10 @@ sub run_testcase ($) { run_testcase_stop_servers($tinfo, $master_restart, $slave_restart); } + + # Write to all log files to indicate start of testcase + run_testcase_mark_logs("CURRENT_TEST: $tinfo->{name}\n"); + my $died= mtr_record_dead_children(); if ($died or $master_restart or $slave_restart) { @@ -3301,7 +3410,7 @@ sub report_failure_and_restart ($) { my $tinfo= shift; mtr_report_test_failed($tinfo); - mtr_show_failed_diff($tinfo->{'name'}); + mtr_show_failed_diff($tinfo->{'result_file'}); print "\n"; if ( $opt_force ) { @@ -3318,7 +3427,7 @@ sub report_failure_and_restart ($) { print "Aborting: $tinfo->{'name'} failed in $test_mode mode. "; print "To continue, re-run with '--force'.\n"; if ( ! $glob_debugger and - ! $glob_use_running_server and + ! $opt_extern and ! $glob_use_embedded_server ) { stop_all_servers(); @@ -3490,6 +3599,17 @@ sub mysqld_arguments ($$$$$) { mtr_add_arg($args, "%s--ndb-extra-logging", $prefix); } } + + if ( $mysql_version_id <= 50106 ) + { + # Force mysqld to use log files up until 5.1.6 + mtr_add_arg($args, "%s--log=%s", $prefix, $master->[0]->{'path_mylog'}); + } + else + { + # Turn on logging, will be sent to tables + mtr_add_arg($args, "%s--log=", $prefix); + } } if ( $type eq 'slave' ) @@ -3507,8 +3627,6 @@ sub mysqld_arguments ($$$$$) { mtr_add_arg($args, "%s--log-slave-updates", $prefix); } - mtr_add_arg($args, "%s--log=%s", $prefix, - $slave->[$idx]->{'path_mylog'}); mtr_add_arg($args, "%s--master-retry-count=10", $prefix); mtr_add_arg($args, "%s--pid-file=%s", $prefix, $slave->[$idx]->{'path_pid'}); @@ -3569,6 +3687,18 @@ sub mysqld_arguments ($$$$$) { mtr_add_arg($args, "%s--ndb-extra-logging", $prefix); } } + + if ( $mysql_version_id <= 50106 ) + { + # Force mysqld to use log files up until 5.1.6 + mtr_add_arg($args, "%s--log=%s", $prefix, $master->[0]->{'path_mylog'}); + } + else + { + # Turn on logging, will be sent to tables + mtr_add_arg($args, "%s--log=", $prefix); + } + } # end slave if ( $opt_debug ) @@ -3645,7 +3775,6 @@ sub mysqld_arguments ($$$$$) { elsif ( $type eq 'master' ) { mtr_add_arg($args, "%s--open-files-limit=1024", $prefix); - mtr_add_arg($args, "%s--log=%s", $prefix, $master->[0]->{'path_mylog'}); } return $args; @@ -3894,10 +4023,17 @@ sub run_testcase_need_master_restart($) } elsif( ! $master->[0]->{'pid'} ) { - $do_restart= 1; - mtr_verbose("Restart master: master is not started"); + if ( $opt_extern ) + { + $do_restart= 0; + mtr_verbose("No restart: using extern master"); + } + else + { + $do_restart= 1; + mtr_verbose("Restart master: master is not started"); + } } - return $do_restart; } @@ -4018,6 +4154,7 @@ sub run_testcase_stop_servers($$$) { if ( $do_restart || $do_slave_restart ) { + delete $slave->[0]->{'running_slave_options'}; # Forget history # Start shutdown of all started slaves @@ -4142,8 +4279,6 @@ sub run_testcase_start_servers($) { return 1; } } - mtr_tofile($master->[1]->{'path_myerr'},"CURRENT_TEST: $tname\n"); - mysqld_start($master->[1],$tinfo->{'master_opt'},[]); } @@ -4171,8 +4306,6 @@ sub run_testcase_start_servers($) { # ---------------------------------------------------------------------- if ( $tinfo->{'slave_num'} ) { - mtr_tofile($slave->[0]->{'path_myerr'},"CURRENT_TEST: $tname\n"); - restore_slave_databases($tinfo->{'slave_num'}); do_before_start_slave($tinfo); @@ -4388,11 +4521,6 @@ sub run_mysqltest ($) { mtr_add_arg($args, "--timer-file=%s/log/timer", $opt_vardir); } - if ( $opt_big_test ) - { - mtr_add_arg($args, "--big-test"); - } - if ( $opt_compress ) { mtr_add_arg($args, "--compress"); @@ -4513,6 +4641,7 @@ sub run_mysqltest ($) { } return $res; + } @@ -4762,9 +4891,9 @@ Options to control directories to use vardir=DIR The directory where files generated from the test run is stored (default: ./var). Specifying a ramdisk or tmpfs will speed up tests. - mem[=DIR] Run testsuite in "memory" using tmpfs or ramdisk - Attempts to use DIR first if specified else - uses as builtin list of standard locations + mem Run testsuite in "memory" using tmpfs or ramdisk + Attempts to find a suitable location + using a builtin list of standard locations for tmpfs (/dev/shm) The option can also be set using environment variable MTR_MEM=[DIR] @@ -4782,9 +4911,8 @@ Options to control what test suites or cases to run skip-rpl Skip the replication test cases. skip-im Don't start IM, and skip the IM test cases skip-test=PREFIX Skip test cases which name are prefixed with PREFIX - big-test Pass "--big-test" to mysqltest which will set the - environment variable BIG_TEST, which can be checked - from test cases. + big-test Set the environment variable BIG_TEST, which can be + checked from test cases. Options that specify ports @@ -4806,10 +4934,11 @@ Options that pass on options Options to run test on running server - extern Use running server for tests FIXME DANGEROUS + extern Use running server for tests ndb-connectstring=STR Use running cluster, and connect using STR ndb-connectstring-slave=STR Use running slave cluster, and connect using STR - user=USER User for connect to server + user=USER User for connection to extern server + socket=PATH Socket for connection to extern server Options for debugging the product @@ -4858,23 +4987,15 @@ Misc options unified-diff | udiff When presenting differences, use unified diff testcase-timeout=MINUTES Max test case run time (default $default_testcase_timeout) - suite-timeout=MINUTES Max test suite run time (default $default_suite_timeout) + suite-timeout=MINUTES Max test suite run time (default $default_suite_timeout) + warnings | log-warnings Pass --log-warnings to mysqld + sleep=SECONDS Passed to mysqltest, will be used as fixed sleep time Deprecated options with-openssl Deprecated option for ssl -Options not yet described, or that I want to look into more - local - netware - sleep=SECONDS - socket=PATH - user-test=s - wait-timeout=SECONDS - warnings - log-warnings - HERE mtr_exit(1); diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result index d3657d84678..89b7f31d00b 100644 --- a/mysql-test/r/alter_table.result +++ b/mysql-test/r/alter_table.result @@ -541,6 +541,127 @@ create table t1 ( a timestamp ); alter table t1 add unique ( a(1) ); ERROR HY000: Incorrect sub part key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique sub keys drop table t1; +drop table if exists t1; +create table t1 (a int, key(a)); +show indexes from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 1 a 1 a A NULL NULL NULL YES BTREE +"this used not to disable the index" +alter table t1 modify a int, disable keys; +show indexes from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 1 a 1 a A NULL NULL NULL YES BTREE disabled +alter table t1 enable keys; +show indexes from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 1 a 1 a A NULL NULL NULL YES BTREE +alter table t1 modify a bigint, disable keys; +show indexes from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 1 a 1 a A NULL NULL NULL YES BTREE disabled +alter table t1 enable keys; +show indexes from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 1 a 1 a A NULL NULL NULL YES BTREE +alter table t1 add b char(10), disable keys; +show indexes from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 1 a 1 a A NULL NULL NULL YES BTREE disabled +alter table t1 add c decimal(10,2), enable keys; +show indexes from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 1 a 1 a A NULL NULL NULL YES BTREE +"this however did" +alter table t1 disable keys; +show indexes from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 1 a 1 a A NULL NULL NULL YES BTREE disabled +desc t1; +Field Type Null Key Default Extra +a bigint(20) YES MUL NULL +b char(10) YES NULL +c decimal(10,2) YES NULL +alter table t1 add d decimal(15,5); +"The key should still be disabled" +show indexes from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 1 a 1 a A NULL NULL NULL YES BTREE disabled +drop table t1; +"Now will test with one unique index" +create table t1(a int, b char(10), unique(a)); +show indexes from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 a 1 a A NULL NULL NULL YES BTREE +alter table t1 disable keys; +show indexes from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 a 1 a A NULL NULL NULL YES BTREE +alter table t1 enable keys; +"If no copy on noop change, this won't touch the data file" +"Unique index, no change" +alter table t1 modify a int, disable keys; +show indexes from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 a 1 a A NULL NULL NULL YES BTREE +"Change the type implying data copy" +"Unique index, no change" +alter table t1 modify a bigint, disable keys; +show indexes from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 a 1 a A NULL NULL NULL YES BTREE +alter table t1 modify a bigint; +show indexes from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 a 1 a A NULL NULL NULL YES BTREE +alter table t1 modify a int; +show indexes from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 a 1 a A NULL NULL NULL YES BTREE +drop table t1; +"Now will test with one unique and one non-unique index" +create table t1(a int, b char(10), unique(a), key(b)); +show indexes from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 a 1 a A NULL NULL NULL YES BTREE +t1 1 b 1 b A NULL NULL NULL YES BTREE +alter table t1 disable keys; +show indexes from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 a 1 a A NULL NULL NULL YES BTREE +t1 1 b 1 b A NULL NULL NULL YES BTREE disabled +alter table t1 enable keys; +"If no copy on noop change, this won't touch the data file" +"The non-unique index will be disabled" +alter table t1 modify a int, disable keys; +show indexes from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 a 1 a A NULL NULL NULL YES BTREE +t1 1 b 1 b A NULL NULL NULL YES BTREE disabled +alter table t1 enable keys; +show indexes from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 a 1 a A NULL NULL NULL YES BTREE +t1 1 b 1 b A NULL NULL NULL YES BTREE +"Change the type implying data copy" +"The non-unique index will be disabled" +alter table t1 modify a bigint, disable keys; +show indexes from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 a 1 a A NULL NULL NULL YES BTREE +t1 1 b 1 b A NULL NULL NULL YES BTREE disabled +"Change again the type, but leave the indexes as_is" +alter table t1 modify a int; +show indexes from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 a 1 a A NULL NULL NULL YES BTREE +t1 1 b 1 b A NULL NULL NULL YES BTREE disabled +"Try the same. When data is no copied on similar tables, this is noop" +alter table t1 modify a int; +show indexes from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 a 1 a A NULL NULL NULL YES BTREE +t1 1 b 1 b A NULL NULL NULL YES BTREE disabled +drop table t1; create database mysqltest; create table t1 (c1 int); alter table t1 rename mysqltest.t1; @@ -556,6 +677,17 @@ ERROR 3D000: No database selected alter table test.t1 rename test.t1; use test; drop table t1; +DROP TABLE IF EXISTS bug24219; +DROP TABLE IF EXISTS bug24219_2; +CREATE TABLE bug24219 (a INT, INDEX(a)); +SHOW INDEX FROM bug24219; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +bug24219 1 a 1 a A NULL NULL NULL YES BTREE +ALTER TABLE bug24219 RENAME TO bug24219_2, DISABLE KEYS; +SHOW INDEX FROM bug24219_2; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +bug24219_2 1 a 1 a A NULL NULL NULL YES BTREE disabled +DROP TABLE bug24219_2; create table t1 (mycol int(10) not null); alter table t1 alter column mycol set default 0; desc t1; diff --git a/mysql-test/r/bigint.result b/mysql-test/r/bigint.result index c27ce18cfd3..d8f78cd5103 100644 --- a/mysql-test/r/bigint.result +++ b/mysql-test/r/bigint.result @@ -341,3 +341,14 @@ select * from t1 where bigint_col='17666000000000000000'; bigint_col 17666000000000000000 drop table t1; + +bug 19955 -- mod is signed with bigint +select cast(10000002383263201056 as unsigned) mod 50 as result; +result +6 +create table t1 (c1 bigint unsigned); +insert into t1 values (10000002383263201056); +select c1 mod 50 as result from t1; +result +6 +drop table t1; diff --git a/mysql-test/r/date_formats.result b/mysql-test/r/date_formats.result index 017631bf8d1..cf3495ef26d 100644 --- a/mysql-test/r/date_formats.result +++ b/mysql-test/r/date_formats.result @@ -189,12 +189,12 @@ date format datetime 2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02 02:11:12.123450 2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 00:11:12.123450 2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 2003-01-02 23:11:12 -10:20:10 %H:%i:%s 0000-00-00 10:20:10 -10:20:10 %h:%i:%s.%f 0000-00-00 10:20:10 -10:20:10 %T 0000-00-00 10:20:10 -10:20:10AM %h:%i:%s%p 0000-00-00 10:20:10 -10:20:10AM %r 0000-00-00 10:20:10 -10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 10:20:10.440000 +10:20:10 %H:%i:%s 0000-00-00 00:00:00 +10:20:10 %h:%i:%s.%f 0000-00-00 00:00:00 +10:20:10 %T 0000-00-00 00:00:00 +10:20:10AM %h:%i:%s%p 0000-00-00 00:00:00 +10:20:10AM %r 0000-00-00 00:00:00 +10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 00:00:00 15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 2001-01-15 12:59:58 15 September 2001 %d %M %Y 2001-09-15 00:00:00 15 SEPTEMB 2001 %d %M %Y 2001-09-15 00:00:00 @@ -211,6 +211,13 @@ Tuesday 52 2001 %W %V %X 2002-01-01 00:00:00 15-01-2001 %d-%m-%Y %H:%i:%S 2001-01-15 00:00:00 15-01-20 %d-%m-%y 2020-01-15 00:00:00 15-2001-1 %d-%Y-%c 2001-01-15 00:00:00 +Warnings: +Warning 1292 Incorrect datetime value: '0000-00-00 10:20:10' +Warning 1292 Incorrect datetime value: '0000-00-00 10:20:10' +Warning 1292 Incorrect datetime value: '0000-00-00 10:20:10' +Warning 1292 Incorrect datetime value: '0000-00-00 10:20:10' +Warning 1292 Incorrect datetime value: '0000-00-00 10:20:10' +Warning 1292 Incorrect datetime value: '0000-00-00 10:20:10.440000' select date,format,DATE(str_to_date(date, format)) as date2 from t1; date format date2 2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 2003-01-02 @@ -251,12 +258,12 @@ date format time 2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 02:11:12.123450 2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 00:11:12.123450 2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 23:11:12 -10:20:10 %H:%i:%s 10:20:10 -10:20:10 %h:%i:%s.%f 10:20:10 -10:20:10 %T 10:20:10 -10:20:10AM %h:%i:%s%p 10:20:10 -10:20:10AM %r 10:20:10 -10:20:10.44AM %h:%i:%s.%f%p 10:20:10.440000 +10:20:10 %H:%i:%s NULL +10:20:10 %h:%i:%s.%f NULL +10:20:10 %T NULL +10:20:10AM %h:%i:%s%p NULL +10:20:10AM %r NULL +10:20:10.44AM %h:%i:%s.%f%p NULL 15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 12:59:58 15 September 2001 %d %M %Y 00:00:00 15 SEPTEMB 2001 %d %M %Y 00:00:00 @@ -273,6 +280,13 @@ Tuesday 52 2001 %W %V %X 00:00:00 15-01-2001 %d-%m-%Y %H:%i:%S 00:00:00 15-01-20 %d-%m-%y 00:00:00 15-2001-1 %d-%Y-%c 00:00:00 +Warnings: +Warning 1292 Truncated incorrect time value: '0000-00-00 10:20:10' +Warning 1292 Truncated incorrect time value: '0000-00-00 10:20:10' +Warning 1292 Truncated incorrect time value: '0000-00-00 10:20:10' +Warning 1292 Truncated incorrect time value: '0000-00-00 10:20:10' +Warning 1292 Truncated incorrect time value: '0000-00-00 10:20:10' +Warning 1292 Truncated incorrect time value: '0000-00-00 10:20:10.440000' select date,format,concat(TIME(str_to_date(date, format))) as time2 from t1; date format time2 2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 10:11:12 @@ -282,12 +296,12 @@ date format time2 2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 02:11:12.123450 2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 00:11:12.123450 2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 23:11:12 -10:20:10 %H:%i:%s 10:20:10 -10:20:10 %h:%i:%s.%f 10:20:10 -10:20:10 %T 10:20:10 -10:20:10AM %h:%i:%s%p 10:20:10 -10:20:10AM %r 10:20:10 -10:20:10.44AM %h:%i:%s.%f%p 10:20:10.440000 +10:20:10 %H:%i:%s NULL +10:20:10 %h:%i:%s.%f NULL +10:20:10 %T NULL +10:20:10AM %h:%i:%s%p NULL +10:20:10AM %r NULL +10:20:10.44AM %h:%i:%s.%f%p NULL 15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 12:59:58 15 September 2001 %d %M %Y 00:00:00 15 SEPTEMB 2001 %d %M %Y 00:00:00 @@ -304,6 +318,13 @@ Tuesday 52 2001 %W %V %X 00:00:00 15-01-2001 %d-%m-%Y %H:%i:%S 00:00:00 15-01-20 %d-%m-%y 00:00:00 15-2001-1 %d-%Y-%c 00:00:00 +Warnings: +Warning 1292 Truncated incorrect time value: '0000-00-00 10:20:10' +Warning 1292 Truncated incorrect time value: '0000-00-00 10:20:10' +Warning 1292 Truncated incorrect time value: '0000-00-00 10:20:10' +Warning 1292 Truncated incorrect time value: '0000-00-00 10:20:10' +Warning 1292 Truncated incorrect time value: '0000-00-00 10:20:10' +Warning 1292 Truncated incorrect time value: '0000-00-00 10:20:10.440000' select concat('',str_to_date('8:11:2.123456 03-01-02','%H:%i:%S.%f %y-%m-%d')); concat('',str_to_date('8:11:2.123456 03-01-02','%H:%i:%S.%f %y-%m-%d')) 2003-01-02 08:11:02.123456 @@ -574,4 +595,13 @@ DATE_FORMAT('%Y-%m-%d %H:%i:%s', 1151414896) NULL Warnings: Warning 1292 Incorrect datetime value: '%Y-%m-%d %H:%i:%s' +select str_to_date('04 /30/2004', '%m /%d/%Y'); +str_to_date('04 /30/2004', '%m /%d/%Y') +2004-04-30 +select str_to_date('04/30 /2004', '%m /%d /%Y'); +str_to_date('04/30 /2004', '%m /%d /%Y') +2004-04-30 +select str_to_date('04/30/2004 ', '%m/%d/%Y '); +str_to_date('04/30/2004 ', '%m/%d/%Y ') +2004-04-30 "End of 4.1 tests" diff --git a/mysql-test/r/default.result b/mysql-test/r/default.result index 697b0976cee..9bef2e2fdbf 100644 --- a/mysql-test/r/default.result +++ b/mysql-test/r/default.result @@ -104,3 +104,95 @@ a b c d e f g h i j k l m n o p q r s t u v w x y z a1 b1 1 0000 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL drop table t1; drop table t2; +create table bug20691 (i int, d datetime NOT NULL, dn datetime not null default '0000-00-00 00:00:00'); +insert into bug20691 values (1, DEFAULT, DEFAULT), (1, '1975-07-10 07:10:03', '1978-01-13 14:08:51'), (1, DEFAULT, DEFAULT); +Warnings: +Warning 1364 Field 'd' doesn't have a default value +Warning 1364 Field 'd' doesn't have a default value +insert into bug20691 (i) values (2); +Warnings: +Warning 1364 Field 'd' doesn't have a default value +desc bug20691; +Field Type Null Key Default Extra +i int(11) YES NULL +d datetime NO +dn datetime NO 0000-00-00 00:00:00 +insert into bug20691 values (3, DEFAULT, DEFAULT), (3, '1975-07-10 07:10:03', '1978-01-13 14:08:51'), (3, DEFAULT, DEFAULT); +Warnings: +Warning 1364 Field 'd' doesn't have a default value +Warning 1364 Field 'd' doesn't have a default value +insert into bug20691 (i) values (4); +Warnings: +Warning 1364 Field 'd' doesn't have a default value +insert into bug20691 values (5, DEFAULT, DEFAULT), (5, '1975-07-10 07:10:03', '1978-01-13 14:08:51'), (5, DEFAULT, DEFAULT); +Warnings: +Warning 1364 Field 'd' doesn't have a default value +Warning 1364 Field 'd' doesn't have a default value +SET sql_mode = 'ALLOW_INVALID_DATES'; +insert into bug20691 values (6, DEFAULT, DEFAULT), (6, '1975-07-10 07:10:03', '1978-01-13 14:08:51'), (6, DEFAULT, DEFAULT); +Warnings: +Warning 1364 Field 'd' doesn't have a default value +Warning 1364 Field 'd' doesn't have a default value +SET sql_mode = 'STRICT_ALL_TABLES'; +insert into bug20691 values (7, DEFAULT, DEFAULT), (7, '1975-07-10 07:10:03', '1978-01-13 14:08:51'), (7, DEFAULT, DEFAULT); +ERROR HY000: Field 'd' doesn't have a default value +select * from bug20691 order by i asc; +i d dn +1 0000-00-00 00:00:00 0000-00-00 00:00:00 +1 1975-07-10 07:10:03 1978-01-13 14:08:51 +1 0000-00-00 00:00:00 0000-00-00 00:00:00 +2 0000-00-00 00:00:00 0000-00-00 00:00:00 +3 0000-00-00 00:00:00 0000-00-00 00:00:00 +3 1975-07-10 07:10:03 1978-01-13 14:08:51 +3 0000-00-00 00:00:00 0000-00-00 00:00:00 +4 0000-00-00 00:00:00 0000-00-00 00:00:00 +5 0000-00-00 00:00:00 0000-00-00 00:00:00 +5 1975-07-10 07:10:03 1978-01-13 14:08:51 +5 0000-00-00 00:00:00 0000-00-00 00:00:00 +6 0000-00-00 00:00:00 0000-00-00 00:00:00 +6 1975-07-10 07:10:03 1978-01-13 14:08:51 +6 0000-00-00 00:00:00 0000-00-00 00:00:00 +drop table bug20691; +SET sql_mode = ''; +create table bug20691 ( +a set('one', 'two', 'three') not null, +b enum('small', 'medium', 'large', 'enormous', 'ellisonego') not null, +c time not null, +d date not null, +e int not null, +f long not null, +g blob not null, +h datetime not null, +i decimal not null, +x int); +insert into bug20691 values (2, 3, 5, '0007-01-01', 11, 13, 17, '0019-01-01 00:00:00', 23, 1); +insert into bug20691 (x) values (2); +Warnings: +Warning 1364 Field 'a' doesn't have a default value +Warning 1364 Field 'c' doesn't have a default value +Warning 1364 Field 'd' doesn't have a default value +Warning 1364 Field 'e' doesn't have a default value +Warning 1364 Field 'f' doesn't have a default value +Warning 1364 Field 'g' doesn't have a default value +Warning 1364 Field 'h' doesn't have a default value +Warning 1364 Field 'i' doesn't have a default value +insert into bug20691 values (2, 3, 5, '0007-01-01', 11, 13, 17, '0019-01-01 00:00:00', 23, 3); +insert into bug20691 values (DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, 4); +Warnings: +Warning 1364 Field 'a' doesn't have a default value +Warning 1364 Field 'b' doesn't have a default value +Warning 1364 Field 'c' doesn't have a default value +Warning 1364 Field 'd' doesn't have a default value +Warning 1364 Field 'e' doesn't have a default value +Warning 1364 Field 'f' doesn't have a default value +Warning 1364 Field 'g' doesn't have a default value +Warning 1364 Field 'h' doesn't have a default value +Warning 1364 Field 'i' doesn't have a default value +select * from bug20691 order by x asc; +a b c d e f g h i x +two large 00:00:05 0007-01-01 11 13 17 0019-01-01 00:00:00 23 1 + small 00:00:00 0000-00-00 0 0000-00-00 00:00:00 0 2 +two large 00:00:05 0007-01-01 11 13 17 0019-01-01 00:00:00 23 3 + small 00:00:00 0000-00-00 0 0000-00-00 00:00:00 0 4 +drop table bug20691; +End of 5.0 tests. diff --git a/mysql-test/r/fix_priv_tables.result b/mysql-test/r/fix_priv_tables.result new file mode 100644 index 00000000000..e54330a5520 --- /dev/null +++ b/mysql-test/r/fix_priv_tables.result @@ -0,0 +1,36 @@ +drop table if exists t1,t1aa,t2aa; +DROP DATABASE IF EXISTS testdb; +CREATE DATABASE testdb; +CREATE TABLE testdb.t1 ( +c1 INT, +c3 INT NOT NULL AUTO_INCREMENT PRIMARY KEY); +CREATE VIEW testdb.v1 AS +SELECT * FROM testdb.t1; +GRANT CREATE VIEW, SHOW VIEW ON testdb.v1 TO 'show_view_tbl'@'localhost'; +SHOW GRANTS FOR 'show_view_tbl'@'localhost'; +Grants for show_view_tbl@localhost +GRANT USAGE ON *.* TO 'show_view_tbl'@'localhost' +GRANT CREATE VIEW, SHOW VIEW ON `testdb`.`v1` TO 'show_view_tbl'@'localhost' + +GRANT SELECT(c1) on testdb.v1 to 'select_only_c1'@localhost; +SHOW GRANTS FOR 'select_only_c1'@'localhost'; +Grants for select_only_c1@localhost +GRANT USAGE ON *.* TO 'select_only_c1'@'localhost' +GRANT SELECT (c1) ON `testdb`.`v1` TO 'select_only_c1'@'localhost' + +"after fix privs" +SHOW GRANTS FOR 'show_view_tbl'@'localhost'; +Grants for show_view_tbl@localhost +GRANT USAGE ON *.* TO 'show_view_tbl'@'localhost' +GRANT CREATE VIEW, SHOW VIEW ON `testdb`.`v1` TO 'show_view_tbl'@'localhost' + +SHOW GRANTS FOR 'select_only_c1'@'localhost'; +Grants for select_only_c1@localhost +GRANT USAGE ON *.* TO 'select_only_c1'@'localhost' +GRANT SELECT (c1) ON `testdb`.`v1` TO 'select_only_c1'@'localhost' + +DROP USER 'show_view_tbl'@'localhost'; +DROP USER 'select_only_c1'@'localhost'; +DROP VIEW testdb.v1; +DROP TABLE testdb.t1; +DROP DATABASE testdb; diff --git a/mysql-test/r/fix_priv_tabs.result b/mysql-test/r/fix_priv_tabs.result new file mode 100644 index 00000000000..e69de29bb2d diff --git a/mysql-test/r/flush2.result b/mysql-test/r/flush2.result new file mode 100644 index 00000000000..7c94219fd71 --- /dev/null +++ b/mysql-test/r/flush2.result @@ -0,0 +1,24 @@ +flush logs; +set global expire_logs_days = 3; +show variables like 'log%'; +Variable_name Value +log ON +log_bin OFF +log_bin_trust_function_creators ON +log_error +log_queries_not_using_indexes OFF +log_slave_updates OFF +log_slow_queries OFF +log_warnings 1 +flush logs; +show variables like 'log%'; +Variable_name Value +log ON +log_bin OFF +log_bin_trust_function_creators ON +log_error +log_queries_not_using_indexes OFF +log_slave_updates OFF +log_slow_queries OFF +log_warnings 1 +set global expire_logs_days = 0; diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result index 3ebf071a5bb..84974f845c5 100644 --- a/mysql-test/r/func_misc.result +++ b/mysql-test/r/func_misc.result @@ -134,4 +134,11 @@ timediff(b, a) >= '00:00:03' drop table t2; drop table t1; set global query_cache_size=default; +create table t1 select INET_ATON('255.255.0.1') as `a`; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` bigint(21) unsigned DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; End of 5.0 tests diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index d7f65e84462..1f52076f3d2 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -1047,6 +1047,9 @@ union (select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 HOUR)),'%k') As H); H 5 +select last_day('0000-00-00'); +last_day('0000-00-00') +NULL End of 4.1 tests explain extended select timestampdiff(SQL_TSI_WEEK, '2001-02-01', '2001-05-01') as a1, timestampdiff(SQL_TSI_FRAC_SECOND, '2001-02-01 12:59:59.120000', '2001-05-01 12:58:58.119999') as a2; @@ -1057,6 +1060,7 @@ Note 1003 select timestampdiff(WEEK,_latin1'2001-02-01',_latin1'2001-05-01') AS select time_format('100:00:00', '%H %k %h %I %l'); time_format('100:00:00', '%H %k %h %I %l') 100 100 04 04 4 +SET GLOBAL log_bin_trust_function_creators = 1; create table t1 (a timestamp default '2005-05-05 01:01:01', b timestamp default '2005-05-05 01:01:01'); drop function if exists t_slow_sysdate; @@ -1080,6 +1084,7 @@ a != b drop trigger t_before; drop function t_slow_sysdate; drop table t1; +SET GLOBAL log_bin_trust_function_creators = 0; create table t1 (a datetime, i int, b datetime); insert into t1 select sysdate(), sleep(1), sysdate() from dual; select a != b from t1; @@ -1175,6 +1180,9 @@ id day id day 3 2005-07-01 3 2005-07-15 DROP TABLE t1,t2; set time_zone= @@global.time_zone; +select str_to_date('10:00 PM', '%h:%i %p') + INTERVAL 10 MINUTE; +str_to_date('10:00 PM', '%h:%i %p') + INTERVAL 10 MINUTE +NULL End of 5.0 tests select date_sub("0050-01-01 00:00:01",INTERVAL 2 SECOND); date_sub("0050-01-01 00:00:01",INTERVAL 2 SECOND) diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index 6a90ad27625..3848368fedd 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -679,10 +679,11 @@ insert into t1 values (null,null); ERROR 23000: Column 's1' cannot be null drop table t1; drop procedure if exists fn3; -create function fn3 () returns point return GeomFromText("point(1 1)"); +create function fn3 () returns point deterministic return GeomFromText("point(1 1)"); show create function fn3; Function sql_mode Create Function fn3 CREATE DEFINER=`root`@`localhost` FUNCTION `fn3`() RETURNS point + DETERMINISTIC return GeomFromText("point(1 1)") select astext(fn3()); astext(fn3()) diff --git a/mysql-test/r/grant2.result b/mysql-test/r/grant2.result index 4b089c1d5e9..03019bd5c1f 100644 --- a/mysql-test/r/grant2.result +++ b/mysql-test/r/grant2.result @@ -365,13 +365,14 @@ insert into mysql.user select * from t1; drop table t1, t2; drop database TESTDB; flush privileges; +SET GLOBAL log_bin_trust_function_creators = 1; grant all privileges on test.* to `a@`@localhost; grant execute on * to `a@`@localhost; create table t2 (s1 int); insert into t2 values (1); drop function if exists f2; -create function f2 () returns int begin declare v int; select s1 from t2 -into v; return v; end// +create function f2 () returns int +begin declare v int; select s1 from t2 into v; return v; end// select f2(); f2() 1 @@ -379,3 +380,4 @@ drop function f2; drop table t2; REVOKE ALL PRIVILEGES, GRANT OPTION FROM `a@`@localhost; drop user `a@`@localhost; +SET GLOBAL log_bin_trust_function_creators = 0; diff --git a/mysql-test/r/have_mysql_upgrade.result b/mysql-test/r/have_mysql_upgrade.result new file mode 100644 index 00000000000..952bea420f9 --- /dev/null +++ b/mysql-test/r/have_mysql_upgrade.result @@ -0,0 +1,2 @@ +have_mysql_upgrade +1 diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index e8f7eed54f4..ac51bfe2a36 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -1077,7 +1077,7 @@ CREATE PROCEDURE p1 () BEGIN SELECT 'foo' FROM DUAL; END | -ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema' +ERROR 42000: Unknown database 'information_schema' select ROUTINE_NAME from routines; ROUTINE_NAME grant all on information_schema.* to 'user1'@'localhost'; diff --git a/mysql-test/r/init_connect.result b/mysql-test/r/init_connect.result index f90ee5913a1..f5ec0bdc932 100644 --- a/mysql-test/r/init_connect.result +++ b/mysql-test/r/init_connect.result @@ -132,7 +132,7 @@ x 17 19 drop trigger trg1; -set global init_connect=default; +set global init_connect="set @a='a\\0c'"; revoke all privileges, grant option from mysqltest1@localhost; drop user mysqltest1@localhost; drop table t1, t2; diff --git a/mysql-test/r/innodb_notembedded.result b/mysql-test/r/innodb_notembedded.result index cc13a429dfc..36714eb62fb 100644 --- a/mysql-test/r/innodb_notembedded.result +++ b/mysql-test/r/innodb_notembedded.result @@ -1,4 +1,5 @@ drop table if exists t1; +SET GLOBAL log_bin_trust_function_creators = 1; create table t1 (col1 integer primary key, col2 integer) engine=innodb; insert t1 values (1,100); create function f1 () returns integer begin @@ -18,3 +19,4 @@ rollback; rollback; drop table t1; drop function f1; +SET GLOBAL log_bin_trust_function_creators = 0; diff --git a/mysql-test/r/key_cache.result b/mysql-test/r/key_cache.result index 406a92b9a08..a1bf3d0e128 100644 --- a/mysql-test/r/key_cache.result +++ b/mysql-test/r/key_cache.result @@ -284,12 +284,15 @@ insert t1 values ('aaabbb'); check table t1; Table Op Msg_type Msg_text test.t1 check status OK +set @my_key_cache_block_size= @@global.key_cache_block_size; set GLOBAL key_cache_block_size=2048; check table t1; Table Op Msg_type Msg_text test.t1 check status OK drop table t1; +set global key_cache_block_size= @my_key_cache_block_size; CREATE TABLE t1(a int NOT NULL AUTO_INCREMENT PRIMARY KEY); +SET @my_key_cache_block_size= @@global.key_cache_block_size; SET GLOBAL key_cache_block_size=1536; INSERT INTO t1 VALUES (1); SELECT @@key_cache_block_size; @@ -331,6 +334,7 @@ CHECK TABLE t1; Table Op Msg_type Msg_text test.t1 check status OK DROP TABLE t1,t2; +set global key_cache_block_size= @my_key_cache_block_size; set @@global.key_buffer_size=0; Warnings: Warning 1438 Cannot drop default keycache diff --git a/mysql-test/r/limit.result b/mysql-test/r/limit.result index be2776ef533..ac96ac8ff17 100644 --- a/mysql-test/r/limit.result +++ b/mysql-test/r/limit.result @@ -90,3 +90,4 @@ id select_type table type possible_keys key key_len ref rows Extra select sum(a) c FROM t1 WHERE a > 0 ORDER BY c LIMIT 3; c 28 +drop table t1; diff --git a/mysql-test/r/lowercase_fs_off.result b/mysql-test/r/lowercase_fs_off.result index f610b959a47..ecb21261987 100644 --- a/mysql-test/r/lowercase_fs_off.result +++ b/mysql-test/r/lowercase_fs_off.result @@ -8,4 +8,5 @@ create database d2; ERROR 42000: Access denied for user 'sample'@'localhost' to database 'd2' create database D1; ERROR 42000: Access denied for user 'sample'@'localhost' to database 'D1' +drop user 'sample'@'localhost'; drop database if exists d1; diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result index 14267afc27e..3bba1944c52 100644 --- a/mysql-test/r/mysql.result +++ b/mysql-test/r/mysql.result @@ -36,6 +36,8 @@ Tables_in_test t1 t2 t3 +Tables_in_test +t1 _ Test delimiter : from command line a @@ -178,4 +180,8 @@ Too long dbname ERROR 1049 (42000) at line 1: Unknown database 'test_really_long_dbnamexxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' Too long hostname ERROR 2005 (HY000) at line 1: Unknown MySQL server host 'cyrils_superlonghostnameXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' (errno) +1 +1 +ERROR at line 1: DELIMITER cannot contain a backslash character +ERROR at line 1: DELIMITER cannot contain a backslash character End of 5.0 tests diff --git a/mysql-test/r/mysql_upgrade.result b/mysql-test/r/mysql_upgrade.result new file mode 100644 index 00000000000..434b7b2d23f --- /dev/null +++ b/mysql-test/r/mysql_upgrade.result @@ -0,0 +1,173 @@ +Run mysql_upgrade once +mysql.binlog_index OK +mysql.columns_priv OK +mysql.db OK +mysql.event OK +mysql.func OK +mysql.general_log OK +mysql.help_category OK +mysql.help_keyword OK +mysql.help_relation OK +mysql.help_topic OK +mysql.host OK +mysql.plugin OK +mysql.proc OK +mysql.procs_priv OK +mysql.slow_log OK +mysql.tables_priv OK +mysql.time_zone OK +mysql.time_zone_leap_second OK +mysql.time_zone_name OK +mysql.time_zone_transition OK +mysql.time_zone_transition_type OK +mysql.user OK +@hadGrantPriv:=1 +1 +1 +1 +1 +1 +@hadShowDbPriv:=1 +1 +1 +1 +1 +1 +@hadCreateViewPriv:=1 +1 +1 +1 +1 +1 +@hadCreateRoutinePriv:=1 +1 +1 +1 +1 +1 +@hadCreateUserPriv:=1 +1 +1 +1 +1 +1 +@hadEventPriv :=1 +1 +1 +1 +1 +1 +@hadTriggerPriv :=1 +1 +1 +1 +1 +1 +Run it again - should say already completed +@hadGrantPriv:=1 +1 +1 +1 +1 +1 +@hadShowDbPriv:=1 +1 +1 +1 +1 +1 +@hadCreateViewPriv:=1 +1 +1 +1 +1 +1 +@hadCreateRoutinePriv:=1 +1 +1 +1 +1 +1 +@hadCreateUserPriv:=1 +1 +1 +1 +1 +1 +@hadEventPriv :=1 +1 +1 +1 +1 +1 +@hadTriggerPriv :=1 +1 +1 +1 +1 +1 +Force should run it regardless of wheter it's been run before +mysql.binlog_index OK +mysql.columns_priv OK +mysql.db OK +mysql.event OK +mysql.func OK +mysql.general_log OK +mysql.help_category OK +mysql.help_keyword OK +mysql.help_relation OK +mysql.help_topic OK +mysql.host OK +mysql.plugin OK +mysql.proc OK +mysql.procs_priv OK +mysql.slow_log OK +mysql.tables_priv OK +mysql.time_zone OK +mysql.time_zone_leap_second OK +mysql.time_zone_name OK +mysql.time_zone_transition OK +mysql.time_zone_transition_type OK +mysql.user OK +@hadGrantPriv:=1 +1 +1 +1 +1 +1 +@hadShowDbPriv:=1 +1 +1 +1 +1 +1 +@hadCreateViewPriv:=1 +1 +1 +1 +1 +1 +@hadCreateRoutinePriv:=1 +1 +1 +1 +1 +1 +@hadCreateUserPriv:=1 +1 +1 +1 +1 +1 +@hadEventPriv :=1 +1 +1 +1 +1 +1 +@hadTriggerPriv :=1 +1 +1 +1 +1 +1 diff --git a/mysql-test/r/mysqladmin.result b/mysql-test/r/mysqladmin.result new file mode 100644 index 00000000000..57927f8aa67 --- /dev/null +++ b/mysql-test/r/mysqladmin.result @@ -0,0 +1,4 @@ +mysqld is alive +mysqladmin: unknown variable 'database=db1' +Warning: mysqladmin: unknown variable 'loose-database=db2' +mysqld is alive diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index 54c68701f78..4ac1dfc938f 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -3088,7 +3088,7 @@ drop user mysqltest_1@localhost; # create database mysqldump_myDB; use mysqldump_myDB; -create user myDB_User; +create user myDB_User@localhost; grant create, create view, select, insert on mysqldump_myDB.* to myDB_User@localhost; create table t1 (c1 int); insert into t1 values (3); @@ -3101,7 +3101,7 @@ drop view v1; drop table t1; drop table u1; revoke all privileges on mysqldump_myDB.* from myDB_User@localhost; -drop user myDB_User; +drop user myDB_User@localhost; drop database mysqldump_myDB; flush privileges; # Bug #21424 continues from here. @@ -3119,7 +3119,7 @@ drop view v1; drop table t1; drop table u1; revoke all privileges on mysqldump_myDB.* from myDB_User@localhost; -drop user myDB_User; +drop user myDB_User@localhost; drop database mysqldump_myDB; use test; # diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index 1cfc482416e..12a35fcf48b 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -512,6 +512,12 @@ mysqltest: At line 1: End of line junk detected: "write_file filename "; mysqltest: At line 1: Missing required argument 'filename' to command 'file_exists' mysqltest: At line 1: Missing required argument 'from_file' to command 'copy_file' mysqltest: At line 1: Missing required argument 'to_file' to command 'copy_file' +mysqltest: At line 1: Missing required argument 'mode' to command 'chmod' +mysqltest: At line 1: You must write a 4 digit octal number for mode +mysqltest: At line 1: You must write a 4 digit octal number for mode +mysqltest: At line 1: Missing required argument 'file' to command 'chmod' +mysqltest: At line 1: You must write a 4 digit octal number for mode +mysqltest: At line 1: You must write a 4 digit octal number for mode hello hello hello diff --git a/mysql-test/r/parser.result b/mysql-test/r/parser.result index df446e01601..49008eb818b 100644 --- a/mysql-test/r/parser.result +++ b/mysql-test/r/parser.result @@ -373,3 +373,104 @@ select yearweek(); ERROR 42000: Incorrect parameter count in the call to native function 'yearweek' select yearweek(1, 2, 3); ERROR 42000: Incorrect parameter count in the call to native function 'yearweek' +select abs(3); +abs(3) +3 +select abs(3 AS three); +ERROR 42000: Incorrect parameters in the call to native function 'abs' +select abs(3 three); +ERROR 42000: Incorrect parameters in the call to native function 'abs' +select abs(3 AS "three"); +ERROR 42000: Incorrect parameters in the call to native function 'abs' +select abs(3 "three"); +ERROR 42000: Incorrect parameters in the call to native function 'abs' +set @bar="bar"; +set @foobar="foobar"; +select instr("foobar", "bar"); +instr("foobar", "bar") +4 +select instr("foobar" AS p1, "bar"); +ERROR 42000: Incorrect parameters in the call to native function 'instr' +select instr("foobar" p1, "bar"); +ERROR 42000: Incorrect parameters in the call to native function 'instr' +select instr("foobar" AS "p1", "bar"); +ERROR 42000: Incorrect parameters in the call to native function 'instr' +select instr("foobar" "p1", "bar"); +instr("foobar" "p1", "bar") +4 +select instr(@foobar "p1", "bar"); +ERROR 42000: Incorrect parameters in the call to native function 'instr' +select instr("foobar", "bar" AS p2); +ERROR 42000: Incorrect parameters in the call to native function 'instr' +select instr("foobar", "bar" p2); +ERROR 42000: Incorrect parameters in the call to native function 'instr' +select instr("foobar", "bar" AS "p2"); +ERROR 42000: Incorrect parameters in the call to native function 'instr' +select instr("foobar", "bar" "p2"); +instr("foobar", "bar" "p2") +0 +select instr("foobar", @bar "p2"); +ERROR 42000: Incorrect parameters in the call to native function 'instr' +select instr("foobar" AS p1, "bar" AS p2); +ERROR 42000: Incorrect parameters in the call to native function 'instr' +select conv(255, 10, 16); +conv(255, 10, 16) +FF +select conv(255 AS p1, 10, 16); +ERROR 42000: Incorrect parameters in the call to native function 'conv' +select conv(255 p1, 10, 16); +ERROR 42000: Incorrect parameters in the call to native function 'conv' +select conv(255 AS "p1", 10, 16); +ERROR 42000: Incorrect parameters in the call to native function 'conv' +select conv(255 "p1", 10, 16); +ERROR 42000: Incorrect parameters in the call to native function 'conv' +select conv(255, 10 AS p2, 16); +ERROR 42000: Incorrect parameters in the call to native function 'conv' +select conv(255, 10 p2, 16); +ERROR 42000: Incorrect parameters in the call to native function 'conv' +select conv(255, 10 AS "p2", 16); +ERROR 42000: Incorrect parameters in the call to native function 'conv' +select conv(255, 10 "p2", 16); +ERROR 42000: Incorrect parameters in the call to native function 'conv' +select conv(255, 10, 16 AS p3); +ERROR 42000: Incorrect parameters in the call to native function 'conv' +select conv(255, 10, 16 p3); +ERROR 42000: Incorrect parameters in the call to native function 'conv' +select conv(255, 10, 16 AS "p3"); +ERROR 42000: Incorrect parameters in the call to native function 'conv' +select conv(255, 10, 16 "p3"); +ERROR 42000: Incorrect parameters in the call to native function 'conv' +select conv(255 AS p1, 10 AS p2, 16 AS p3); +ERROR 42000: Incorrect parameters in the call to native function 'conv' +select atan(10); +atan(10) +1.4711276743037 +select atan(10 AS p1); +ERROR 42000: Incorrect parameters in the call to native function 'atan' +select atan(10 p1); +ERROR 42000: Incorrect parameters in the call to native function 'atan' +select atan(10 AS "p1"); +ERROR 42000: Incorrect parameters in the call to native function 'atan' +select atan(10 "p1"); +ERROR 42000: Incorrect parameters in the call to native function 'atan' +select atan(10, 20); +atan(10, 20) +0.46364760900081 +select atan(10 AS p1, 20); +ERROR 42000: Incorrect parameters in the call to native function 'atan' +select atan(10 p1, 20); +ERROR 42000: Incorrect parameters in the call to native function 'atan' +select atan(10 AS "p1", 20); +ERROR 42000: Incorrect parameters in the call to native function 'atan' +select atan(10 "p1", 20); +ERROR 42000: Incorrect parameters in the call to native function 'atan' +select atan(10, 20 AS p2); +ERROR 42000: Incorrect parameters in the call to native function 'atan' +select atan(10, 20 p2); +ERROR 42000: Incorrect parameters in the call to native function 'atan' +select atan(10, 20 AS "p2"); +ERROR 42000: Incorrect parameters in the call to native function 'atan' +select atan(10, 20 "p2"); +ERROR 42000: Incorrect parameters in the call to native function 'atan' +select atan(10 AS p1, 20 AS p2); +ERROR 42000: Incorrect parameters in the call to native function 'atan' diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index a44125d4bed..4988b1139e9 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -1527,9 +1527,9 @@ create procedure proc_1() reset query cache; call proc_1(); call proc_1(); call proc_1(); -create function func_1() returns int begin reset query cache; return 1; end| +create function func_1() returns int deterministic begin reset query cache; return 1; end| ERROR 0A000: RESET is not allowed in stored function or trigger -create function func_1() returns int begin call proc_1(); return 1; end| +create function func_1() returns int deterministic begin call proc_1(); return 1; end| select func_1(), func_1(), func_1() from dual; ERROR 0A000: RESET is not allowed in stored function or trigger drop function func_1; diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result index fac026047de..54b35827cea 100644 --- a/mysql-test/r/query_cache.result +++ b/mysql-test/r/query_cache.result @@ -1077,10 +1077,12 @@ create procedure `p1`() begin select a, f1() from t1; end// +SET GLOBAL log_bin_trust_function_creators = 1; call p1()// a f1() 1 2 2 2 +SET GLOBAL log_bin_trust_function_creators = 0; drop procedure p1// drop function f1// drop table t1// diff --git a/mysql-test/r/query_cache_notembedded.result b/mysql-test/r/query_cache_notembedded.result index 8e5df012cfb..05ef28a3180 100644 --- a/mysql-test/r/query_cache_notembedded.result +++ b/mysql-test/r/query_cache_notembedded.result @@ -314,6 +314,7 @@ drop procedure f2; drop procedure f3; drop procedure f4; drop table t1; +SET GLOBAL log_bin_trust_function_creators = 1; reset query cache; drop function if exists f1; create table t1 (id int); @@ -345,3 +346,4 @@ id drop table t1; drop function f1; set GLOBAL query_cache_size=0; +SET GLOBAL log_bin_trust_function_creators = 0; diff --git a/mysql-test/r/read_only.result b/mysql-test/r/read_only.result index 1a1991a6255..69d25fbef6f 100644 --- a/mysql-test/r/read_only.result +++ b/mysql-test/r/read_only.result @@ -39,6 +39,11 @@ delete t1 from t1,t3 where t1.a=t3.a; drop table t1; insert into t1 values(1); ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement +drop temporary table ttt; +ERROR 42S02: Unknown table 'ttt' +drop temporary table if exists ttt; +Warnings: +Note 1051 Unknown table 'ttt' drop table t1,t2; drop user test@localhost; set global read_only=0; diff --git a/mysql-test/r/rpl_000015.result b/mysql-test/r/rpl_000015.result index a2763d4f023..a53750f82ad 100644 --- a/mysql-test/r/rpl_000015.result +++ b/mysql-test/r/rpl_000015.result @@ -8,7 +8,7 @@ Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File change master to master_host='127.0.0.1'; show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master -# 127.0.0.1 test MASTER_PORT 7 4 # # No No 0 0 0 # None 0 No # +# 127.0.0.1 test DEFAULT_MASTER_PORT 7 4 # # No No 0 0 0 # None 0 No # change master to master_host='127.0.0.1',master_user='root', master_password='',master_port=MASTER_PORT; show slave status; diff --git a/mysql-test/r/rpl_deadlock_innodb.result b/mysql-test/r/rpl_deadlock_innodb.result index 9a67391cd4d..caf040c0997 100644 --- a/mysql-test/r/rpl_deadlock_innodb.result +++ b/mysql-test/r/rpl_deadlock_innodb.result @@ -132,6 +132,7 @@ Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master # +set @my_max_relay_log_size= @@global.max_relay_log_size; set global max_relay_log_size=0; stop slave; delete from t3; @@ -191,4 +192,5 @@ Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master # drop table t1,t2,t3,t4; +set global max_relay_log_size= @my_max_relay_log_size; End of 5.1 tests diff --git a/mysql-test/r/rpl_drop_db.result b/mysql-test/r/rpl_drop_db.result index 51d6d71ca95..c0efdf5290d 100644 --- a/mysql-test/r/rpl_drop_db.result +++ b/mysql-test/r/rpl_drop_db.result @@ -31,7 +31,8 @@ use test; select * from t1; n 1234 -DROP DATABASE mysqltest1; stop slave; +drop database mysqltest1; +drop database mysqltest1; use test; drop table t1; diff --git a/mysql-test/r/rpl_ignore_revoke.result b/mysql-test/r/rpl_ignore_revoke.result index 42625119f28..b1ccd2f0442 100644 --- a/mysql-test/r/rpl_ignore_revoke.result +++ b/mysql-test/r/rpl_ignore_revoke.result @@ -27,3 +27,4 @@ select_priv Y revoke select on *.* FROM 'user_foo'; delete from mysql.user where user="user_foo"; +delete from mysql.user where user="user_foo"; diff --git a/mysql-test/r/rpl_init_slave.result b/mysql-test/r/rpl_init_slave.result index 83d0a3289a2..740c918976c 100644 --- a/mysql-test/r/rpl_init_slave.result +++ b/mysql-test/r/rpl_init_slave.result @@ -16,9 +16,12 @@ Variable_name Value init_slave show variables like 'max_connections'; Variable_name Value -max_connections 100 +max_connections 151 +set @my_global_init_connect= @@global.init_connect; set global init_connect="set @c=1"; show variables like 'init_connect'; Variable_name Value init_connect set @c=1 stop slave; +set global init_connect= @my_global_init_connect; +set global max_connections= default; diff --git a/mysql-test/r/rpl_row_max_relay_size.result b/mysql-test/r/rpl_row_max_relay_size.result index 163e8231de5..8bb10ffb080 100644 --- a/mysql-test/r/rpl_row_max_relay_size.result +++ b/mysql-test/r/rpl_row_max_relay_size.result @@ -16,6 +16,7 @@ reset slave; # # Test 1 # +set @my_max_binlog_size= @@global.max_binlog_size; set global max_binlog_size=8192; set global max_relay_log_size=8192-1; select @@global.max_relay_log_size; @@ -268,6 +269,7 @@ File master-bin.000002 Position 102 Binlog_Do_DB <Binlog_Ignore_DB> Binlog_Ignore_DB +set global max_binlog_size= @my_max_binlog_size; # # End of 4.1 tests # diff --git a/mysql-test/r/rpl_sf.result b/mysql-test/r/rpl_sf.result new file mode 100644 index 00000000000..46defc6908a --- /dev/null +++ b/mysql-test/r/rpl_sf.result @@ -0,0 +1,23 @@ +set global log_bin_trust_function_creators=0; +set binlog_format=STATEMENT; +create function fn16456() +returns int +begin +return unix_timestamp(); +end| +ERROR HY000: This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable) +set global log_bin_trust_function_creators=1; +create function fn16456() +returns int +begin +return unix_timestamp(); +end| +set global log_bin_trust_function_creators=0; +set binlog_format=ROW; +select fn16456(); +fn16456() +timestamp +set binlog_format=STATEMENT; +select fn16456(); +ERROR HY000: Slave running with --log-slave-updates must use row-based binary logging to be able to replicate row-based binary log events +drop function fn16456; diff --git a/mysql-test/r/rpl_sp.result b/mysql-test/r/rpl_sp.result index 261e7cb072c..fe54b1cbeb4 100644 --- a/mysql-test/r/rpl_sp.result +++ b/mysql-test/r/rpl_sp.result @@ -104,10 +104,10 @@ begin insert into t2 values(20),(20); end| call foo4(); -ERROR 23000: Duplicate entry '20' for key 1 +ERROR 23000: Duplicate entry '20' for key 'a' show warnings; Level Code Message -Error 1062 Duplicate entry '20' for key 1 +Error 1062 Duplicate entry '20' for key 'a' select * from t2; a 20 @@ -181,7 +181,7 @@ end| ERROR HY000: You do not have the SUPER privilege and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable) set global log_bin_trust_routine_creators=1; Warnings: -Warning 1287 'log_bin_trust_routine_creators' is deprecated; use 'log_bin_trust_function_creators' instead +Warning 1541 The syntax 'log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 5.2. Please use 'log_bin_trust_function_creators' instead set global log_bin_trust_function_creators=0; set global log_bin_trust_function_creators=1; set global log_bin_trust_function_creators=1; @@ -241,9 +241,9 @@ return 10; end| do fn1(100); Warnings: -Error 1062 Duplicate entry '100' for key 1 +Error 1062 Duplicate entry '100' for key 'a' select fn1(20); -ERROR 23000: Duplicate entry '20' for key 1 +ERROR 23000: Duplicate entry '20' for key 'a' select * from t2; a 20 @@ -253,7 +253,7 @@ a 20 100 create trigger trg before insert on t1 for each row set new.a= 10; -ERROR 42000: Access denied; you need the SUPER privilege for this operation +ERROR 42000: TRIGGER command denied to user 'zedjzlcsjhd'@'localhost' for table 't1' delete from t1; create trigger trg before insert on t1 for each row set new.a= 10; insert into t1 values (1); @@ -465,3 +465,29 @@ RETURN 0 DROP PROCEDURE p1; DROP FUNCTION f1; drop table t1; +set global log_bin_trust_function_creators=0; +set global log_bin_trust_function_creators=0; +End of 5.0 tests +reset master; +drop database if exists mysqltest; +drop database if exists mysqltest2; +create database mysqltest; +create database mysqltest2; +use mysqltest2; +create table t ( t integer ); +create procedure mysqltest.test() begin end; +insert into t values ( 1 ); +show binlog events in 'master-bin.000001' from 102; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 102 Query 1 203 drop database if exists mysqltest +master-bin.000001 203 Query 1 306 drop database if exists mysqltest2 +master-bin.000001 306 Query 1 399 create database mysqltest +master-bin.000001 399 Query 1 494 create database mysqltest2 +master-bin.000001 494 Query 1 591 use `mysqltest2`; create table t ( t integer ) +master-bin.000001 591 Query 1 730 use `mysqltest2`; CREATE DEFINER=`root`@`localhost` procedure mysqltest.test() begin end +master-bin.000001 730 Query 1 825 use `mysqltest2`; insert into t values ( 1 ) +create procedure `\\`.test() begin end; +ERROR 42000: Unknown database '\\' +drop database mysqltest; +drop database mysqltest2; +End of 5.1 tests diff --git a/mysql-test/r/rpl_sp_effects.result b/mysql-test/r/rpl_sp_effects.result index b42fe64e603..c2c44b06972 100644 --- a/mysql-test/r/rpl_sp_effects.result +++ b/mysql-test/r/rpl_sp_effects.result @@ -10,6 +10,7 @@ drop function if exists f1; drop table if exists t1,t2; drop view if exists v1; create table t1 (a int); +SET GLOBAL log_bin_trust_function_creators = 1; create procedure p1() begin declare spv int default 0; @@ -234,3 +235,4 @@ drop table t1; drop function f1; drop function f2; drop procedure p1; +SET GLOBAL log_bin_trust_function_creators = 0; diff --git a/mysql-test/r/rpl_stm_max_relay_size.result b/mysql-test/r/rpl_stm_max_relay_size.result index 7882bd1aa46..c4a9a5bd3ff 100644 --- a/mysql-test/r/rpl_stm_max_relay_size.result +++ b/mysql-test/r/rpl_stm_max_relay_size.result @@ -14,6 +14,7 @@ reset slave; # # Test 1 # +set @my_max_binlog_size= @@global.max_binlog_size; set global max_binlog_size=8192; set global max_relay_log_size=8192-1; select @@global.max_relay_log_size; @@ -266,6 +267,7 @@ File master-bin.000002 Position 102 Binlog_Do_DB <Binlog_Ignore_DB> Binlog_Ignore_DB +set global max_binlog_size= @my_max_binlog_size; # # End of 4.1 tests # diff --git a/mysql-test/r/rpl_timezone.result b/mysql-test/r/rpl_timezone.result index 4ad6afa8c94..47ef16b9d49 100644 --- a/mysql-test/r/rpl_timezone.result +++ b/mysql-test/r/rpl_timezone.result @@ -4,6 +4,7 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; +set @my_time_zone= @@global.time_zone; set timestamp=100000000; create table t1 (t timestamp, n int not null auto_increment, PRIMARY KEY(n)); create table t2 (t char(32), n int not null auto_increment, PRIMARY KEY(n)); @@ -103,3 +104,4 @@ t n 2003-12-31 23:00:00 16 2005-01-01 08:00:00 17 drop table t1, t2; +set global time_zone= @my_time_zone; diff --git a/mysql-test/r/rpl_variables.result b/mysql-test/r/rpl_variables.result index bbfe8373a46..605a48859a0 100644 --- a/mysql-test/r/rpl_variables.result +++ b/mysql-test/r/rpl_variables.result @@ -4,6 +4,7 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; +set @my_slave_net_timeout =@@global.slave_net_timeout; set global slave_net_timeout=100; set global sql_slave_skip_counter=100; show variables like 'slave_compressed_protocol'; diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 60363b06ea0..7ec930cc087 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -243,7 +243,7 @@ set x = (select sum(t.i) from test.t2 t); insert into test.t1 values (id, x); end| drop procedure if exists sub3| -create function sub3(i int) returns int +create function sub3(i int) returns int deterministic return i+1| call sub1("sub1a", (select 7))| call sub1("sub1b", (select max(i) from t2))| @@ -2710,11 +2710,11 @@ row_count() call bug4905()| select row_count()| row_count() -0 +-1 call bug4905()| select row_count()| row_count() -0 +-1 select * from t3| s1 1 @@ -5735,4 +5735,85 @@ drop function test.current_user; drop function md5; use test; End of 5.1 tests +DROP TABLE IF EXISTS bug23760| +DROP TABLE IF EXISTS bug23760_log| +DROP PROCEDURE IF EXISTS bug23760_update_log| +DROP PROCEDURE IF EXISTS bug23760_test_row_count| +DROP FUNCTION IF EXISTS bug23760_rc_test| +CREATE TABLE bug23760 ( +id INT NOT NULL AUTO_INCREMENT , +num INT NOT NULL , +PRIMARY KEY ( id ) +)| +CREATE TABLE bug23760_log ( +id INT NOT NULL AUTO_INCREMENT , +reason VARCHAR(50)NULL , +ammount INT NOT NULL , +PRIMARY KEY ( id ) +)| +CREATE PROCEDURE bug23760_update_log(r Varchar(50), a INT) +BEGIN +INSERT INTO bug23760_log (reason, ammount) VALUES(r, a); +END| +CREATE PROCEDURE bug23760_test_row_count() +BEGIN +UPDATE bug23760 SET num = num + 1; +CALL bug23760_update_log('Test is working', ROW_COUNT()); +UPDATE bug23760 SET num = num - 1; +END| +CREATE PROCEDURE bug23760_test_row_count2(level INT) +BEGIN +IF level THEN +UPDATE bug23760 SET num = num + 1; +CALL bug23760_update_log('Test2 is working', ROW_COUNT()); +CALL bug23760_test_row_count2(level - 1); +END IF; +END| +CREATE FUNCTION bug23760_rc_test(in_var INT) RETURNS INT RETURN in_var| +INSERT INTO bug23760 (num) VALUES (0), (1), (1), (2), (3), (5), (8)| +SELECT ROW_COUNT()| +ROW_COUNT() +7 +CALL bug23760_test_row_count()| +SELECT * FROM bug23760_log ORDER BY id| +id reason ammount +1 Test is working 7 +SET @save_max_sp_recursion= @@max_sp_recursion_depth| +SELECT @save_max_sp_recursion| +@save_max_sp_recursion +0 +SET max_sp_recursion_depth= 5| +SELECT @@max_sp_recursion_depth| +@@max_sp_recursion_depth +5 +CALL bug23760_test_row_count2(2)| +SELECT ROW_COUNT()| +ROW_COUNT() +1 +SELECT * FROM bug23760_log ORDER BY id| +id reason ammount +1 Test is working 7 +2 Test2 is working 7 +3 Test2 is working 7 +SELECT * FROM bug23760 ORDER by ID| +id num +1 2 +2 3 +3 3 +4 4 +5 5 +6 7 +7 10 +SET max_sp_recursion_depth= @save_max_sp_recursion| +SELECT bug23760_rc_test(123)| +bug23760_rc_test(123) +123 +INSERT INTO bug23760 (num) VALUES (13), (21), (34), (55)| +SELECT bug23760_rc_test(ROW_COUNT())| +bug23760_rc_test(ROW_COUNT()) +4 +DROP TABLE bug23760, bug23760_log| +DROP PROCEDURE bug23760_update_log| +DROP PROCEDURE bug23760_test_row_count| +DROP FUNCTION bug23760_rc_test| drop table t1,t2; diff --git a/mysql-test/r/timezone2.result b/mysql-test/r/timezone2.result index 6fd67d00259..f7631e9657a 100644 --- a/mysql-test/r/timezone2.result +++ b/mysql-test/r/timezone2.result @@ -269,6 +269,7 @@ select * from t1; convert_tz(NULL, NULL, NULL) NULL drop table t1; +SET GLOBAL log_bin_trust_function_creators = 1; create table t1 (ldt datetime, udt datetime); create function f1(i datetime) returns datetime return convert_tz(i, 'UTC', 'Europe/Moscow'); @@ -283,3 +284,4 @@ ldt ldt2 2006-04-19 16:30:00 2006-04-19 16:30:00 drop table t1; drop function f1; +SET GLOBAL log_bin_trust_function_creators = 0; diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result index d28131cc456..73f5e54ecc3 100644 --- a/mysql-test/r/type_float.result +++ b/mysql-test/r/type_float.result @@ -264,7 +264,7 @@ a decimal(21,2) NO 0.00 drop table t1,t2,t3; select 1e-308, 1.00000001e-300, 100000000e-300; 1e-308 1.00000001e-300 100000000e-300 -0 1.00000001e-300 1e-292 +1e-308 1.00000001e-300 1e-292 select 10e307; 10e307 1e+308 diff --git a/mysql-test/r/udf.result b/mysql-test/r/udf.result index 1308980ca96..abc654c4b74 100644 --- a/mysql-test/r/udf.result +++ b/mysql-test/r/udf.result @@ -132,9 +132,9 @@ a c 1 1 2 2 SELECT a, fn(MIN(b) xx) as c FROM t1 GROUP BY a; -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 'xx) as c FROM t1 GROUP BY a' at line 1 +ERROR 42000: Incorrect parameters in the call to stored function 'fn' SELECT myfunc_int(fn(MIN(b) xx)) as c FROM t1 GROUP BY a; -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 'xx)) as c FROM t1 GROUP BY a' at line 1 +ERROR 42000: Incorrect parameters in the call to stored function 'fn' SELECT myfunc_int(test.fn(MIN(b) xx)) as c FROM t1 GROUP BY a; 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 'xx)) as c FROM t1 GROUP BY a' at line 1 SELECT myfunc_int(fn(MIN(b)) xx) as c FROM t1 GROUP BY a; @@ -185,6 +185,28 @@ DROP VIEW v1; DROP TABLE t1; DROP FUNCTION fn; End of 5.0 tests. +select myfunc_double(3); +myfunc_double(3) +51.00 +select myfunc_double(3 AS three); +myfunc_double(3 AS three) +51.00 +select myfunc_double(abs(3)); +myfunc_double(abs(3)) +51.00 +select myfunc_double(abs(3) AS named_param); +myfunc_double(abs(3) AS named_param) +51.00 +select abs(myfunc_double(3)); +abs(myfunc_double(3)) +51.00 +select abs(myfunc_double(3 AS three)); +abs(myfunc_double(3 AS three)) +51.00 +select myfunc_double(abs(3 AS wrong)); +ERROR 42000: Incorrect parameters in the call to native function 'abs' +select abs(myfunc_double(3) AS wrong); +ERROR 42000: Incorrect parameters in the call to native function 'abs' drop function if exists pi; CREATE FUNCTION pi RETURNS STRING SONAME "should_not_parse.so"; ERROR HY000: This function 'pi' has the same name as a native function. @@ -210,3 +232,38 @@ DROP FUNCTION sequence; DROP FUNCTION lookup; DROP FUNCTION reverse_lookup; DROP FUNCTION avgcost; +CREATE FUNCTION is_const RETURNS STRING SONAME "UDF_EXAMPLE_LIB"; +select +is_const(3) as const, +is_const(3.14) as const, +is_const('fnord') as const, +is_const(2+3) as const, +is_const(rand()) as 'nc rand()', +is_const(sin(3.14)) as const, +is_const(upper('test')) as const; +const const const const nc rand() const const +const const const const not const const const +create table bug18761 (n int); +insert into bug18761 values (null),(2); +select +is_const(3) as const, +is_const(3.14) as const, +is_const('fnord') as const, +is_const(2+3) as const, +is_const(2+n) as 'nc 2+n ', +is_const(sin(n)) as 'nc sin(n)', +is_const(sin(3.14)) as const, +is_const(upper('test')) as const, +is_const(rand()) as 'nc rand()', +is_const(n) as 'nc n ', +is_const(is_const(n)) as 'nc ic?(n)', +is_const(is_const('c')) as const +from +bug18761; +const const const const nc 2+n nc sin(n) const const nc rand() nc n nc ic?(n) const +const const const const not const not const const const not const not const not const const +const const const const not const not const const const not const not const not const const +drop table bug18761; +select is_const((1,2,3)); +ERROR 21000: Operand should contain 1 column(s) +drop function if exists is_const; diff --git a/mysql-test/r/varbinary.result b/mysql-test/r/varbinary.result index 1841dc9f0a9..e1ac58ecd52 100644 --- a/mysql-test/r/varbinary.result +++ b/mysql-test/r/varbinary.result @@ -26,3 +26,55 @@ select x,xx from t1; x xx 1 2 drop table t1; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varbinary(255) DEFAULT NULL, + `b` varchar(255) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +select length(a), length(b) from t1; +length(a) length(b) +255 3 +255 3 +CHECK TABLE t1 FOR UPGRADE; +Table Op Msg_type Msg_text +test.t1 check error Table upgrade required. Please do "REPAIR TABLE `t1`" to fix it! +REPAIR TABLE t1; +Table Op Msg_type Msg_text +test.t1 repair status OK +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varbinary(255) DEFAULT NULL, + `b` varchar(255) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +select length(a), length(b) from t1; +length(a) length(b) +3 3 +3 3 +insert into t1 values("ccc", "ddd"); +select length(a), length(b) from t1; +length(a) length(b) +3 3 +3 3 +3 3 +select hex(a), hex(b) from t1; +hex(a) hex(b) +616161 636363 +626262 646464 +636363 646464 +select concat("'", a, "'"), concat("'", b, "'") from t1; +concat("'", a, "'") concat("'", b, "'") +'aaa' 'ccc' +'bbb' 'ddd' +'ccc' 'ddd' +drop table t1; +create table t1(a varbinary(255)); +insert into t1 values("aaa "); +select length(a) from t1; +length(a) +6 +alter table t1 modify a varchar(255); +select length(a) from t1; +length(a) +6 diff --git a/mysql-test/r/view_grant.result b/mysql-test/r/view_grant.result index 80851d8dd3c..e05a84a8f2d 100644 --- a/mysql-test/r/view_grant.result +++ b/mysql-test/r/view_grant.result @@ -546,13 +546,13 @@ CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_tu AS SELECT * FROM mysqltest1.t1; CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_tus AS SELECT * FROM mysqltest1.t1; CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_td AS SELECT * FROM mysqltest1.t1; CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_tds AS SELECT * FROM mysqltest1.t1; -GRANT SELECT, INSERT, UPDATE, DELETE ON mysqltest1.v_t1 TO readonly; -GRANT SELECT ON mysqltest1.v_ts TO readonly; -GRANT INSERT ON mysqltest1.v_ti TO readonly; -GRANT UPDATE ON mysqltest1.v_tu TO readonly; -GRANT UPDATE,SELECT ON mysqltest1.v_tus TO readonly; -GRANT DELETE ON mysqltest1.v_td TO readonly; -GRANT DELETE,SELECT ON mysqltest1.v_tds TO readonly; +GRANT SELECT, INSERT, UPDATE, DELETE ON mysqltest1.v_t1 TO readonly@localhost; +GRANT SELECT ON mysqltest1.v_ts TO readonly@localhost; +GRANT INSERT ON mysqltest1.v_ti TO readonly@localhost; +GRANT UPDATE ON mysqltest1.v_tu TO readonly@localhost; +GRANT UPDATE,SELECT ON mysqltest1.v_tus TO readonly@localhost; +GRANT DELETE ON mysqltest1.v_td TO readonly@localhost; +GRANT DELETE,SELECT ON mysqltest1.v_tds TO readonly@localhost; SELECT * FROM mysqltest1.v_t1; ERROR HY000: View 'mysqltest1.v_t1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them INSERT INTO mysqltest1.v_t1 VALUES(4); diff --git a/mysql-test/std_data/bug19371.MYD b/mysql-test/std_data/bug19371.MYD new file mode 100644 index 00000000000..1b58a70832f Binary files /dev/null and b/mysql-test/std_data/bug19371.MYD differ diff --git a/mysql-test/std_data/bug19371.MYI b/mysql-test/std_data/bug19371.MYI new file mode 100644 index 00000000000..06ee5b2d766 Binary files /dev/null and b/mysql-test/std_data/bug19371.MYI differ diff --git a/mysql-test/std_data/bug19371.frm b/mysql-test/std_data/bug19371.frm new file mode 100644 index 00000000000..7be45d6f8da Binary files /dev/null and b/mysql-test/std_data/bug19371.frm differ diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test index 78bbd23adf1..406854ebaed 100644 --- a/mysql-test/t/alter_table.test +++ b/mysql-test/t/alter_table.test @@ -371,6 +371,103 @@ create table t1 ( a timestamp ); alter table t1 add unique ( a(1) ); drop table t1; +# +# Bug #24395: ALTER TABLE DISABLE KEYS doesn't work when modifying the table +# +# This problem happens if the data change is compatible. +# Changing to the same type is compatible for example. +# +--disable_warnings +drop table if exists t1; +--enable_warnings +create table t1 (a int, key(a)); +show indexes from t1; +--echo "this used not to disable the index" +alter table t1 modify a int, disable keys; +show indexes from t1; + +alter table t1 enable keys; +show indexes from t1; + +alter table t1 modify a bigint, disable keys; +show indexes from t1; + +alter table t1 enable keys; +show indexes from t1; + +alter table t1 add b char(10), disable keys; +show indexes from t1; + +alter table t1 add c decimal(10,2), enable keys; +show indexes from t1; + +--echo "this however did" +alter table t1 disable keys; +show indexes from t1; + +desc t1; + +alter table t1 add d decimal(15,5); +--echo "The key should still be disabled" +show indexes from t1; + +drop table t1; + +--echo "Now will test with one unique index" +create table t1(a int, b char(10), unique(a)); +show indexes from t1; +alter table t1 disable keys; +show indexes from t1; +alter table t1 enable keys; + +--echo "If no copy on noop change, this won't touch the data file" +--echo "Unique index, no change" +alter table t1 modify a int, disable keys; +show indexes from t1; + +--echo "Change the type implying data copy" +--echo "Unique index, no change" +alter table t1 modify a bigint, disable keys; +show indexes from t1; + +alter table t1 modify a bigint; +show indexes from t1; + +alter table t1 modify a int; +show indexes from t1; + +drop table t1; + +--echo "Now will test with one unique and one non-unique index" +create table t1(a int, b char(10), unique(a), key(b)); +show indexes from t1; +alter table t1 disable keys; +show indexes from t1; +alter table t1 enable keys; + + +--echo "If no copy on noop change, this won't touch the data file" +--echo "The non-unique index will be disabled" +alter table t1 modify a int, disable keys; +show indexes from t1; +alter table t1 enable keys; +show indexes from t1; + +--echo "Change the type implying data copy" +--echo "The non-unique index will be disabled" +alter table t1 modify a bigint, disable keys; +show indexes from t1; + +--echo "Change again the type, but leave the indexes as_is" +alter table t1 modify a int; +show indexes from t1; +--echo "Try the same. When data is no copied on similar tables, this is noop" +alter table t1 modify a int; +show indexes from t1; + +drop table t1; + + # # Bug#11493 - Alter table rename to default database does not work without # db name qualifying @@ -402,6 +499,24 @@ alter table test.t1 rename test.t1; use test; drop table t1; +# +# Bug#24219 - ALTER TABLE ... RENAME TO ... , DISABLE KEYS leads to crash +# +--disable_warnings +DROP TABLE IF EXISTS bug24219; +DROP TABLE IF EXISTS bug24219_2; +--enable_warnings + +CREATE TABLE bug24219 (a INT, INDEX(a)); + +SHOW INDEX FROM bug24219; + +ALTER TABLE bug24219 RENAME TO bug24219_2, DISABLE KEYS; + +SHOW INDEX FROM bug24219_2; + +DROP TABLE bug24219_2; + # End of 4.1 tests # diff --git a/mysql-test/t/bigint.test b/mysql-test/t/bigint.test index 35cda11646a..6c1229db83f 100644 --- a/mysql-test/t/bigint.test +++ b/mysql-test/t/bigint.test @@ -278,4 +278,13 @@ select * from t1 where bigint_col=17666000000000000000; select * from t1 where bigint_col='17666000000000000000'; drop table t1; +--echo +--echo bug 19955 -- mod is signed with bigint + +select cast(10000002383263201056 as unsigned) mod 50 as result; + +create table t1 (c1 bigint unsigned); +insert into t1 values (10000002383263201056); +select c1 mod 50 as result from t1; +drop table t1; diff --git a/mysql-test/t/date_formats.test b/mysql-test/t/date_formats.test index c19ebeb2e28..64bd69c1855 100644 --- a/mysql-test/t/date_formats.test +++ b/mysql-test/t/date_formats.test @@ -329,4 +329,12 @@ SELECT TIME_FORMAT("25:00:00", '%l %p'); # SELECT DATE_FORMAT('%Y-%m-%d %H:%i:%s', 1151414896); +# +# Bug #22029: str_to_date returning NULL +# + +select str_to_date('04 /30/2004', '%m /%d/%Y'); +select str_to_date('04/30 /2004', '%m /%d /%Y'); +select str_to_date('04/30/2004 ', '%m/%d/%Y '); + --echo "End of 4.1 tests" diff --git a/mysql-test/t/default.test b/mysql-test/t/default.test index b5522394d2d..225ddbc3ee2 100644 --- a/mysql-test/t/default.test +++ b/mysql-test/t/default.test @@ -82,3 +82,61 @@ SELECT * from t2; drop table t1; drop table t2; + +# +# Bug#20691: DATETIME col (NOT NULL, NO DEFAULT) may insert garbage when specifying DEFAULT +# +# From the docs: +# If the column can take NULL as a value, the column is defined with an +# explicit DEFAULT NULL clause. This is the same as before 5.0.2. +# +# If the column cannot take NULL as the value, MySQL defines the column with +# no explicit DEFAULT clause. For data entry, if an INSERT or REPLACE +# statement includes no value for the column, MySQL handles the column +# according to the SQL mode in effect at the time: +# +# * If strict SQL mode is not enabled, MySQL sets the column to the +# implicit default value for the column data type. +# +# * If strict mode is enabled, an error occurs for transactional tables and +# the statement is rolled back. For non-transactional tables, an error +# occurs, but if this happens for the second or subsequent row of a +# multiple-row statement, the preceding rows will have been inserted. +# +create table bug20691 (i int, d datetime NOT NULL, dn datetime not null default '0000-00-00 00:00:00'); +insert into bug20691 values (1, DEFAULT, DEFAULT), (1, '1975-07-10 07:10:03', '1978-01-13 14:08:51'), (1, DEFAULT, DEFAULT); +insert into bug20691 (i) values (2); +desc bug20691; +insert into bug20691 values (3, DEFAULT, DEFAULT), (3, '1975-07-10 07:10:03', '1978-01-13 14:08:51'), (3, DEFAULT, DEFAULT); +insert into bug20691 (i) values (4); +insert into bug20691 values (5, DEFAULT, DEFAULT), (5, '1975-07-10 07:10:03', '1978-01-13 14:08:51'), (5, DEFAULT, DEFAULT); +SET sql_mode = 'ALLOW_INVALID_DATES'; +insert into bug20691 values (6, DEFAULT, DEFAULT), (6, '1975-07-10 07:10:03', '1978-01-13 14:08:51'), (6, DEFAULT, DEFAULT); +SET sql_mode = 'STRICT_ALL_TABLES'; +--error 1364 +insert into bug20691 values (7, DEFAULT, DEFAULT), (7, '1975-07-10 07:10:03', '1978-01-13 14:08:51'), (7, DEFAULT, DEFAULT); +select * from bug20691 order by i asc; +drop table bug20691; + +SET sql_mode = ''; +create table bug20691 ( + a set('one', 'two', 'three') not null, + b enum('small', 'medium', 'large', 'enormous', 'ellisonego') not null, + c time not null, + d date not null, + e int not null, + f long not null, + g blob not null, + h datetime not null, + i decimal not null, + x int); +insert into bug20691 values (2, 3, 5, '0007-01-01', 11, 13, 17, '0019-01-01 00:00:00', 23, 1); +insert into bug20691 (x) values (2); +insert into bug20691 values (2, 3, 5, '0007-01-01', 11, 13, 17, '0019-01-01 00:00:00', 23, 3); +insert into bug20691 values (DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, 4); +select * from bug20691 order by x asc; +drop table bug20691; + +### +--echo End of 5.0 tests. + diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index e48108af9ce..b541b6d8d33 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -28,7 +28,6 @@ rpl_ndb_ddl : BUG#18946 result file needs update + test needs to ch rpl_ndb_innodb2ndb : Bug #19710 Cluster replication to partition table fails on DELETE FROM statement rpl_ndb_myisam2ndb : Bug #19710 Cluster replication to partition table fails on DELETE FROM statement rpl_row_blob_innodb : BUG#18980 2006-04-10 kent Test fails randomly -rpl_sp : BUG#16456 2006-02-16 jmiller rpl_multi_engine : BUG#22583 2006-09-23 lars synchronization : Bug#24529 Test 'synchronization' fails on Mac pushbuild; Also on Linux 64 bit. diff --git a/mysql-test/t/events_bugs.test b/mysql-test/t/events_bugs.test index 81988818809..605eaa431d0 100644 --- a/mysql-test/t/events_bugs.test +++ b/mysql-test/t/events_bugs.test @@ -280,7 +280,7 @@ create event e22830_3 on schedule every 1 hour do alter event e22830_3 on schedu create event e22830_4 on schedule every 1 hour do alter event e22830_4 on schedule every (select f22830() from dual) hour; select event_name, event_definition, interval_value, interval_field from information_schema.events order by event_name; set global event_scheduler=on; ---sleep 2.0 +--sleep 2.4 set global event_scheduler=off; select event_name, event_definition, interval_value, interval_field from information_schema.events order by event_name; drop function f22830; diff --git a/mysql-test/t/fix_priv_tables.test b/mysql-test/t/fix_priv_tables.test new file mode 100644 index 00000000000..3a91f41dfcc --- /dev/null +++ b/mysql-test/t/fix_priv_tables.test @@ -0,0 +1,66 @@ +# Embedded server doesn't support external clients +--source include/not_embedded.inc + +# +# This is the test for mysql_fix_privilege_tables +# It checks that a system tables from mysql 4.1.23 +# can be upgraded to current system table format +# +# Note: If this test fails, don't be confused about the errors reported +# by mysql-test-run This shows warnings generated by +# mysql_fix_system_tables which should be ignored. +# Instead, concentrate on the errors in r/system_mysql_db.reject + +--disable_warnings +drop table if exists t1,t1aa,t2aa; +--enable_warnings + +# +# Bug #20589 Missing some table level privileges after upgrade +# +# Add some grants that should survive the "upgrade" + +--disable_warnings +DROP DATABASE IF EXISTS testdb; +--enable_warnings +CREATE DATABASE testdb; +CREATE TABLE testdb.t1 ( + c1 INT, + c3 INT NOT NULL AUTO_INCREMENT PRIMARY KEY); + +CREATE VIEW testdb.v1 AS + SELECT * FROM testdb.t1; + +GRANT CREATE VIEW, SHOW VIEW ON testdb.v1 TO 'show_view_tbl'@'localhost'; +SHOW GRANTS FOR 'show_view_tbl'@'localhost'; +echo; + +# Some extra GRANTS for more complete test +GRANT SELECT(c1) on testdb.v1 to 'select_only_c1'@localhost; +SHOW GRANTS FOR 'select_only_c1'@'localhost'; +echo; + +-- disable_result_log +-- disable_query_log + +# Run the mysql_fix_privilege_tables.sql using "mysql --force" +--exec $MYSQL --force mysql < $MYSQL_FIX_PRIVILEGE_TABLES > $MYSQLTEST_VARDIR/log/fix_priv_tables.log 2>&1 + +-- enable_query_log +-- enable_result_log + +echo "after fix privs"; + +SHOW GRANTS FOR 'show_view_tbl'@'localhost'; +echo; +SHOW GRANTS FOR 'select_only_c1'@'localhost'; +echo; + +DROP USER 'show_view_tbl'@'localhost'; +DROP USER 'select_only_c1'@'localhost'; + +DROP VIEW testdb.v1; +DROP TABLE testdb.t1; +DROP DATABASE testdb; + +# End of 4.1 tests diff --git a/mysql-test/t/flush2-master.opt b/mysql-test/t/flush2-master.opt new file mode 100644 index 00000000000..ccbd01c91d3 --- /dev/null +++ b/mysql-test/t/flush2-master.opt @@ -0,0 +1 @@ +--disable-log-bin diff --git a/mysql-test/t/flush2.test b/mysql-test/t/flush2.test new file mode 100644 index 00000000000..fc9e88e3141 --- /dev/null +++ b/mysql-test/t/flush2.test @@ -0,0 +1,9 @@ +# +# Bug#17733 Flushing logs causes daily server crash +# +flush logs; +set global expire_logs_days = 3; +show variables like 'log%'; +flush logs; +show variables like 'log%'; +set global expire_logs_days = 0; diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test index 52a5512d070..5cac6c45f65 100644 --- a/mysql-test/t/func_misc.test +++ b/mysql-test/t/func_misc.test @@ -125,4 +125,11 @@ drop table t2; drop table t1; set global query_cache_size=default; +# +# Bug #21466: INET_ATON() returns signed, not unsigned +# + +create table t1 select INET_ATON('255.255.0.1') as `a`; +show create table t1; +drop table t1; --echo End of 5.0 tests diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index a6cbca61b84..ebaa6d84bd3 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -565,6 +565,12 @@ union union (select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 HOUR)),'%k') As H); +# +# Bug #23653: crash if last_day('0000-00-00') +# + +select last_day('0000-00-00'); + --echo End of 4.1 tests explain extended select timestampdiff(SQL_TSI_WEEK, '2001-02-01', '2001-05-01') as a1, @@ -580,6 +586,8 @@ select time_format('100:00:00', '%H %k %h %I %l'); # Bug #12562: Make SYSDATE behave like it does in Oracle: always the current # time, regardless of magic to make NOW() always the same for the # entirety of a statement. +SET GLOBAL log_bin_trust_function_creators = 1; + create table t1 (a timestamp default '2005-05-05 01:01:01', b timestamp default '2005-05-05 01:01:01'); delimiter //; @@ -609,6 +617,8 @@ drop trigger t_before; drop function t_slow_sysdate; drop table t1; +SET GLOBAL log_bin_trust_function_creators = 0; + create table t1 (a datetime, i int, b datetime); insert into t1 select sysdate(), sleep(1), sysdate() from dual; select a != b from t1; @@ -676,6 +686,12 @@ DROP TABLE t1,t2; # Restore timezone to default set time_zone= @@global.time_zone; + +# +# Bug #22229: bug in DATE_ADD() +# + +select str_to_date('10:00 PM', '%h:%i %p') + INTERVAL 10 MINUTE; --echo End of 5.0 tests # diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test index 7bba34be3ff..4e5a21c6789 100644 --- a/mysql-test/t/gis.test +++ b/mysql-test/t/gis.test @@ -393,7 +393,7 @@ drop table t1; --disable_warnings drop procedure if exists fn3; --enable_warnings -create function fn3 () returns point return GeomFromText("point(1 1)"); +create function fn3 () returns point deterministic return GeomFromText("point(1 1)"); show create function fn3; select astext(fn3()); drop function fn3; diff --git a/mysql-test/t/grant2.test b/mysql-test/t/grant2.test index 99da1fa1ee7..a533af995dc 100644 --- a/mysql-test/t/grant2.test +++ b/mysql-test/t/grant2.test @@ -484,6 +484,8 @@ flush privileges; # BUG#13310 incorrect user parsing by SP # +SET GLOBAL log_bin_trust_function_creators = 1; + grant all privileges on test.* to `a@`@localhost; grant execute on * to `a@`@localhost; connect (bug13310,localhost,'a@',,test); @@ -494,11 +496,10 @@ insert into t2 values (1); drop function if exists f2; --enable_warnings delimiter //; -create function f2 () returns int begin declare v int; select s1 from t2 -into v; return v; end// +create function f2 () returns int +begin declare v int; select s1 from t2 into v; return v; end// delimiter ;// select f2(); - drop function f2; drop table t2; disconnect bug13310; @@ -506,3 +507,5 @@ disconnect bug13310; connection default; REVOKE ALL PRIVILEGES, GRANT OPTION FROM `a@`@localhost; drop user `a@`@localhost; + +SET GLOBAL log_bin_trust_function_creators = 0; diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index 6cf26acd40d..6d98e4c4aa9 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -721,7 +721,7 @@ create temporary table schemata(f1 char(10)); # Bug #10708 SP's can use INFORMATION_SCHEMA as ROUTINE_SCHEMA # delimiter |; ---error 1044 +--error ER_BAD_DB_ERROR CREATE PROCEDURE p1 () BEGIN SELECT 'foo' FROM DUAL; diff --git a/mysql-test/t/init_connect.test b/mysql-test/t/init_connect.test index 31a98df33df..cf98f608982 100644 --- a/mysql-test/t/init_connect.test +++ b/mysql-test/t/init_connect.test @@ -232,7 +232,9 @@ connection con0; disconnect con1; drop trigger trg1; -set global init_connect=default; +# Set init connect back to the value provided in init_connect-master.opt +# doesn't matter as server will be restarted +set global init_connect="set @a='a\\0c'"; revoke all privileges, grant option from mysqltest1@localhost; drop user mysqltest1@localhost; diff --git a/mysql-test/t/innodb_notembedded.test b/mysql-test/t/innodb_notembedded.test index 53332d9fda4..2731f8e33ed 100644 --- a/mysql-test/t/innodb_notembedded.test +++ b/mysql-test/t/innodb_notembedded.test @@ -13,6 +13,7 @@ connect (b,localhost,root,,); # BUG#11238 - in prelocking mode SELECT .. FOR UPDATE is changed to # non-blocking SELECT # +SET GLOBAL log_bin_trust_function_creators = 1; create table t1 (col1 integer primary key, col2 integer) engine=innodb; insert t1 values (1,100); delimiter |; @@ -38,3 +39,4 @@ drop table t1; drop function f1; disconnect a; disconnect b; +SET GLOBAL log_bin_trust_function_creators = 0; diff --git a/mysql-test/t/key_cache.test b/mysql-test/t/key_cache.test index 4001e0df4af..3044964ebc3 100644 --- a/mysql-test/t/key_cache.test +++ b/mysql-test/t/key_cache.test @@ -164,16 +164,19 @@ create table t1 (mytext text, FULLTEXT (mytext)); insert t1 values ('aaabbb'); check table t1; +set @my_key_cache_block_size= @@global.key_cache_block_size; set GLOBAL key_cache_block_size=2048; check table t1; - drop table t1; +# Restore the changed variable value +set global key_cache_block_size= @my_key_cache_block_size; # # Bug #19079: corrupted index when key_cache_block_size is not multiple of # myisam_block_size CREATE TABLE t1(a int NOT NULL AUTO_INCREMENT PRIMARY KEY); +SET @my_key_cache_block_size= @@global.key_cache_block_size; SET GLOBAL key_cache_block_size=1536; INSERT INTO t1 VALUES (1); SELECT @@key_cache_block_size; @@ -206,6 +209,8 @@ SELECT COUNT(*) FROM t1; SELECT @@key_cache_block_size; CHECK TABLE t1; DROP TABLE t1,t2; +# Restore changed variables +set global key_cache_block_size= @my_key_cache_block_size; # # Bug#10473 - Can't set 'key_buffer_size' system variable to ZERO diff --git a/mysql-test/t/limit.test b/mysql-test/t/limit.test index 2eb4e6cbbb2..bc599b20d36 100644 --- a/mysql-test/t/limit.test +++ b/mysql-test/t/limit.test @@ -69,5 +69,5 @@ explain select count(*) c FROM t1 WHERE a > 0 ORDER BY c LIMIT 3; select count(*) c FROM t1 WHERE a > 0 ORDER BY c LIMIT 3; explain select sum(a) c FROM t1 WHERE a > 0 ORDER BY c LIMIT 3; select sum(a) c FROM t1 WHERE a > 0 ORDER BY c LIMIT 3; - +drop table t1; # End of 4.1 tests diff --git a/mysql-test/t/lowercase_fs_off.test b/mysql-test/t/lowercase_fs_off.test index 883315994fe..414027cb485 100644 --- a/mysql-test/t/lowercase_fs_off.test +++ b/mysql-test/t/lowercase_fs_off.test @@ -21,6 +21,7 @@ create database D1; disconnect sample; connection master; +drop user 'sample'@'localhost'; drop database if exists d1; disconnect master; connection default; diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test index cb4a5593de7..c9fec6deb35 100644 --- a/mysql-test/t/mysql.test +++ b/mysql-test/t/mysql.test @@ -241,4 +241,23 @@ drop table t17583; --error 1 --exec $MYSQL test -e "\r test cyrils_superlonghostnameXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" 2>&1 + +# +# Bug #21412: mysql cmdline client allows backslash(es) +# as delimiter but can't recognize them +# + +# This should work just fine... +--exec echo "DELIMITER /" > $MYSQLTEST_VARDIR/tmp/bug21412.sql +--exec echo "SELECT 1/" >> $MYSQLTEST_VARDIR/tmp/bug21412.sql +--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug21412.sql 2>&1 + +# This should give an error... +--exec echo "DELIMITER \\" > $MYSQLTEST_VARDIR/tmp/bug21412.sql +--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug21412.sql 2>&1 + +# As should this... +--exec echo "DELIMITER \\\\" > $MYSQLTEST_VARDIR/tmp/bug21412.sql +--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug21412.sql 2>&1 + --echo End of 5.0 tests diff --git a/mysql-test/t/mysql_client_test-master.opt b/mysql-test/t/mysql_client_test-master.opt index 3711946168d..2dfcc4a2fb9 100644 --- a/mysql-test/t/mysql_client_test-master.opt +++ b/mysql-test/t/mysql_client_test-master.opt @@ -1 +1 @@ ---log --log-output=FILE +--log=$MYSQLTEST_VARDIR/log/master.log --log-output=FILE diff --git a/mysql-test/t/mysql_delimiter.sql b/mysql-test/t/mysql_delimiter.sql index fa80c980b29..db679c3b06b 100644 --- a/mysql-test/t/mysql_delimiter.sql +++ b/mysql-test/t/mysql_delimiter.sql @@ -49,3 +49,13 @@ delimiter ; # Reset delimiter # Bug #11523: \d works differently than delimiter # source t/mysql_delimiter_source.sql +delimiter ; # Reset delimiter + +# +# Bug #19799: delimiter command not working correctly when sourcing a sql file +# with Windows style line endings. +# +source t/mysql_delimiter_19799.sql +use test// +show tables// +delimiter ; # Reset delimiter diff --git a/mysql-test/t/mysql_delimiter_19799.sql b/mysql-test/t/mysql_delimiter_19799.sql new file mode 100755 index 00000000000..2a3d4378492 --- /dev/null +++ b/mysql-test/t/mysql_delimiter_19799.sql @@ -0,0 +1 @@ +delimiter // diff --git a/mysql-test/t/mysql_upgrade.test b/mysql-test/t/mysql_upgrade.test new file mode 100644 index 00000000000..4200ba844f7 --- /dev/null +++ b/mysql-test/t/mysql_upgrade.test @@ -0,0 +1,20 @@ +# Only run test if "mysql_upgrade" is found +--require r/have_mysql_upgrade.result +--disable_query_log +select LENGTH("$MYSQL_UPGRADE")>0 as have_mysql_upgrade; +--enable_query_log + +# +# Basic test thta we can run mysql_upgrde and that it finds the +# expected binaries it uses. +# +--echo Run mysql_upgrade once +--exec $MYSQL_UPGRADE 2> $MYSQLTEST_VARDIR/log/mysql_upgrade.err + +--echo Run it again - should say already completed +--exec $MYSQL_UPGRADE 2> $MYSQLTEST_VARDIR/log/mysql_upgrade.err + +--echo Force should run it regardless of wheter it's been run before +--exec $MYSQL_UPGRADE --force 2> $MYSQLTEST_VARDIR/log/mysql_upgrade.err + + diff --git a/mysql-test/t/mysqladmin.test b/mysql-test/t/mysqladmin.test new file mode 100644 index 00000000000..7c016fd7416 --- /dev/null +++ b/mysql-test/t/mysqladmin.test @@ -0,0 +1,32 @@ +# +# Test "mysqladmin ping" +# + +--exec $MYSQLADMIN --no-defaults -S $MASTER_MYSOCK -P $MASTER_MYPORT -u root --password= ping 2>&1 + + +# +# Bug#10608 mysqladmin breaks on "database" variable in my.cnf +# + +# When mysqladmin finds database in .cnf file it shall fail +--write_file $MYSQLTEST_VARDIR/tmp/bug10608.cnf +[client] +database=db1 +EOF + +--replace_regex /\/.*mysqladmin/mysqladmin/ +--error 7 +--exec $MYSQLADMIN --defaults-file=$MYSQLTEST_VARDIR/tmp/bug10608.cnf -S $MASTER_MYSOCK -P $MASTER_MYPORT -u root --password= ping 2>&1 + + +# When mysqladmin finds "loose-database" in .cnf file it shall print +# a warning and continue +--write_file $MYSQLTEST_VARDIR/tmp/bug10608.cnf +[client] +loose-database=db2 +EOF + +--replace_regex /Warning: .*mysqladmin/Warning: mysqladmin/ +--exec $MYSQLADMIN --defaults-file=$MYSQLTEST_VARDIR/tmp/bug10608.cnf -S $MASTER_MYSOCK -P $MASTER_MYPORT -u root --password= ping 2>&1 + diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 05b15cdad17..b7ff8bbdfdb 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -1343,7 +1343,7 @@ connect (root,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK); connection root; create database mysqldump_myDB; use mysqldump_myDB; -create user myDB_User; +create user myDB_User@localhost; grant create, create view, select, insert on mysqldump_myDB.* to myDB_User@localhost; create table t1 (c1 int); insert into t1 values (3); @@ -1366,7 +1366,7 @@ drop view v1; drop table t1; drop table u1; revoke all privileges on mysqldump_myDB.* from myDB_User@localhost; -drop user myDB_User; +drop user myDB_User@localhost; drop database mysqldump_myDB; flush privileges; @@ -1391,7 +1391,7 @@ drop view v1; drop table t1; drop table u1; revoke all privileges on mysqldump_myDB.* from myDB_User@localhost; -drop user myDB_User; +drop user myDB_User@localhost; drop database mysqldump_myDB; use test; connection default; diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index 3c20b38722f..c06d51d9d49 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -1521,6 +1521,46 @@ remove_file $MYSQLTEST_VARDIR/tmp/file2.tmp; --error 1 --exec echo "copy_file from_file;" | $MYSQL_TEST 2>&1 +# ---------------------------------------------------------------------------- +# test for chmod +# ---------------------------------------------------------------------------- +--write_file $MYSQLTEST_VARDIR/tmp/file1.tmp +file1 +EOF + +chmod 0000 $MYSQLTEST_VARDIR/tmp/file1.tmp; +# The below write fails, but --error is not implemented +# for write_file +#--write_file $MYSQLTEST_VARDIR/tmp/file1.tmp +#test should fail +#EOF + +chmod 0777 $MYSQLTEST_VARDIR/tmp/file1.tmp; +--write_file $MYSQLTEST_VARDIR/tmp/file1.tmp +test2 +EOF + +remove_file $MYSQLTEST_VARDIR/tmp/file1.tmp; + +--error 1 +--exec echo "chmod ;" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "chmod 0 from_file;" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "chmod 08 from_file;" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "chmod from_file;" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "chmod ABZD from_file;" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "chmod 06789 from_file;" | $MYSQL_TEST 2>&1 + + # ---------------------------------------------------------------------------- # test for perl # ---------------------------------------------------------------------------- diff --git a/mysql-test/t/parser.test b/mysql-test/t/parser.test index 39c8d8e2bf4..13b4338701e 100644 --- a/mysql-test/t/parser.test +++ b/mysql-test/t/parser.test @@ -493,3 +493,113 @@ select yearweek(); -- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT select yearweek(1, 2, 3); +# +# Bug#24736: UDF functions parsed as Stored Functions +# + +# Verify that the syntax for calling UDF : foo(expr AS param, ...) +# can not be used when calling native functions + +# Native function with 1 argument + +select abs(3); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select abs(3 AS three); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select abs(3 three); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select abs(3 AS "three"); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select abs(3 "three"); + +# Native function with 2 arguments + +set @bar="bar"; +set @foobar="foobar"; + +select instr("foobar", "bar"); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select instr("foobar" AS p1, "bar"); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select instr("foobar" p1, "bar"); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select instr("foobar" AS "p1", "bar"); +## String concatenation, valid syntax +select instr("foobar" "p1", "bar"); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select instr(@foobar "p1", "bar"); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select instr("foobar", "bar" AS p2); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select instr("foobar", "bar" p2); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select instr("foobar", "bar" AS "p2"); +## String concatenation, valid syntax +select instr("foobar", "bar" "p2"); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select instr("foobar", @bar "p2"); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select instr("foobar" AS p1, "bar" AS p2); + +# Native function with 3 arguments + +select conv(255, 10, 16); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select conv(255 AS p1, 10, 16); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select conv(255 p1, 10, 16); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select conv(255 AS "p1", 10, 16); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select conv(255 "p1", 10, 16); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select conv(255, 10 AS p2, 16); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select conv(255, 10 p2, 16); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select conv(255, 10 AS "p2", 16); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select conv(255, 10 "p2", 16); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select conv(255, 10, 16 AS p3); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select conv(255, 10, 16 p3); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select conv(255, 10, 16 AS "p3"); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select conv(255, 10, 16 "p3"); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select conv(255 AS p1, 10 AS p2, 16 AS p3); + +# Native function with a variable number of arguments + +select atan(10); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select atan(10 AS p1); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select atan(10 p1); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select atan(10 AS "p1"); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select atan(10 "p1"); + +select atan(10, 20); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select atan(10 AS p1, 20); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select atan(10 p1, 20); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select atan(10 AS "p1", 20); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select atan(10 "p1", 20); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select atan(10, 20 AS p2); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select atan(10, 20 p2); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select atan(10, 20 AS "p2"); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select atan(10, 20 "p2"); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select atan(10 AS p1, 20 AS p2); + diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 0e96a7aad10..15b0a476279 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -1587,8 +1587,8 @@ call proc_1(); call proc_1(); delimiter |; --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG -create function func_1() returns int begin reset query cache; return 1; end| -create function func_1() returns int begin call proc_1(); return 1; end| +create function func_1() returns int deterministic begin reset query cache; return 1; end| +create function func_1() returns int deterministic begin call proc_1(); return 1; end| delimiter ;| --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG select func_1(), func_1(), func_1() from dual; diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test index cb4e5f97c3a..ad7fd90ed63 100644 --- a/mysql-test/t/query_cache.test +++ b/mysql-test/t/query_cache.test @@ -788,7 +788,9 @@ create procedure `p1`() begin select a, f1() from t1; end// +SET GLOBAL log_bin_trust_function_creators = 1; call p1()// +SET GLOBAL log_bin_trust_function_creators = 0; drop procedure p1// drop function f1// diff --git a/mysql-test/t/query_cache_notembedded.test b/mysql-test/t/query_cache_notembedded.test index 97be9f9f7ca..802022d061b 100644 --- a/mysql-test/t/query_cache_notembedded.test +++ b/mysql-test/t/query_cache_notembedded.test @@ -183,6 +183,8 @@ drop table t1; # # bug#14767: INSERT in SF + concurrent SELECT with query cache # +SET GLOBAL log_bin_trust_function_creators = 1; + reset query cache; --disable_warnings drop function if exists f1; @@ -222,3 +224,4 @@ disconnect con2; connection default; set GLOBAL query_cache_size=0; +SET GLOBAL log_bin_trust_function_creators = 0; diff --git a/mysql-test/t/read_only.test b/mysql-test/t/read_only.test index 175a5bba6fa..8e14b310f4c 100644 --- a/mysql-test/t/read_only.test +++ b/mysql-test/t/read_only.test @@ -101,6 +101,18 @@ drop table t1; --error 1290 insert into t1 values(1); +# +# BUG #22077 "DROP TEMPORARY TABLE fails with wrong error if read_only is set" +# +# check if DROP TEMPORARY on a non-existing temporary table returns the right +# error + +--error ER_BAD_TABLE_ERROR +drop temporary table ttt; + +# check if DROP TEMPORARY TABLE IF EXISTS produces a warning with read_only set +drop temporary table if exists ttt; + connection default; drop table t1,t2; drop user test@localhost; diff --git a/mysql-test/t/rpl_000015.test b/mysql-test/t/rpl_000015.test index cf93beb2bfe..ffe7ab87632 100644 --- a/mysql-test/t/rpl_000015.test +++ b/mysql-test/t/rpl_000015.test @@ -18,7 +18,7 @@ show slave status; change master to master_host='127.0.0.1'; # The following needs to be cleaned up when change master is fixed ---replace_result $MYSQL_TCP_PORT MASTER_PORT +--replace_result $DEFAULT_MASTER_PORT DEFAULT_MASTER_PORT --replace_column 1 # 8 # 9 # 23 # 33 # show slave status; --replace_result $MASTER_MYPORT MASTER_PORT diff --git a/mysql-test/t/rpl_drop_db.test b/mysql-test/t/rpl_drop_db.test index ffdc605b402..7f4a7843c4a 100644 --- a/mysql-test/t/rpl_drop_db.test +++ b/mysql-test/t/rpl_drop_db.test @@ -46,17 +46,16 @@ show tables; use test; select * from t1; -system rm $MYSQLTEST_VARDIR/master-data/mysqltest1/f1.txt; -connection master; -DROP DATABASE mysqltest1; -sync_slave_with_master; - #cleanup connection slave; stop slave; -#system rm -rf $MYSQLTEST_VARDIR/master-data/mysqltest1; +drop database mysqltest1; connection master; +# Remove the "extra" file created above +--remove_file $MYSQLTEST_VARDIR/master-data/mysqltest1/f1.txt +drop database mysqltest1; + use test; drop table t1; diff --git a/mysql-test/t/rpl_ignore_revoke.test b/mysql-test/t/rpl_ignore_revoke.test index cdeb40df069..00171605a92 100644 --- a/mysql-test/t/rpl_ignore_revoke.test +++ b/mysql-test/t/rpl_ignore_revoke.test @@ -45,3 +45,7 @@ revoke select on *.* FROM 'user_foo'; connection master; delete from mysql.user where user="user_foo"; sync_slave_with_master; + +# Since changes to mysql.* are ignored, the revoke need to +# be done on slave as well +delete from mysql.user where user="user_foo"; diff --git a/mysql-test/t/rpl_init_slave.test b/mysql-test/t/rpl_init_slave.test index cefb04a7b75..139b4902e12 100644 --- a/mysql-test/t/rpl_init_slave.test +++ b/mysql-test/t/rpl_init_slave.test @@ -17,6 +17,8 @@ show variables like 'max_connections'; save_master_pos; connection slave; sync_with_master; +# Save variable value +set @my_global_init_connect= @@global.init_connect; set global init_connect="set @c=1"; show variables like 'init_connect'; connection master; @@ -25,4 +27,8 @@ connection slave; sync_with_master; stop slave; +# Restore changed global variable +set global init_connect= @my_global_init_connect; +set global max_connections= default; + # End of 4.1 tests diff --git a/mysql-test/t/rpl_sf.test b/mysql-test/t/rpl_sf.test new file mode 100644 index 00000000000..2b1e0350f1b --- /dev/null +++ b/mysql-test/t/rpl_sf.test @@ -0,0 +1,68 @@ +# Bug#16456 RBR: rpl_sp.test expects query to fail, but passes in RBR + +# save status + +let $oblf=`select @@SESSION.BINLOG_FORMAT`; +let $otfc=`select @@log_bin_trust_function_creators`; + +set global log_bin_trust_function_creators=0; + + + +# fail *on definition* + +set binlog_format=STATEMENT; + +delimiter |; +--error ER_BINLOG_UNSAFE_ROUTINE +create function fn16456() + returns int +begin + return unix_timestamp(); +end| +delimiter ;| + + + +# force in definition, so we can see whether we fail on call + +set global log_bin_trust_function_creators=1; + +delimiter |; +create function fn16456() + returns int +begin + return unix_timestamp(); +end| +delimiter ;| + +set global log_bin_trust_function_creators=0; + + + +# allow funcall in RBR + +set binlog_format=ROW; + +--replace_column 1 timestamp +select fn16456(); + + + +# fail funcall in SBR + +set binlog_format=STATEMENT; + +--error ER_BINLOG_ROW_RBR_TO_SBR +select fn16456(); + + + +# restore status + +drop function fn16456; + +--disable_query_log +eval set binlog_format=$oblf; +eval set global log_bin_trust_function_creators=$otfc; +--enable_query_log diff --git a/mysql-test/t/rpl_sp.test b/mysql-test/t/rpl_sp.test index 22ab72df104..3a93a6608cd 100644 --- a/mysql-test/t/rpl_sp.test +++ b/mysql-test/t/rpl_sp.test @@ -8,6 +8,7 @@ # still accepted (this test also checks that the new name is # accepted). The old name could be removed in 5.1 or 6.0. +source include/have_binlog_format_mixed.inc; source include/master-slave.inc; # we need a db != test, where we don't have automatic grants @@ -319,7 +320,9 @@ select * from t2; # ********************** PART 3 : TRIGGERS *************** connection con1; ---error 1227 +# now fails due to missing trigger grant (err 1142 i/o 1227) due to new +# check in sql_trigger.cc (v1.44) by anozdrin on 2006/02/01 --azundris +--error ER_TABLEACCESS_DENIED_ERROR create trigger trg before insert on t1 for each row set new.a= 10; connection master; @@ -519,6 +522,33 @@ connection master; drop table t1; sync_slave_with_master; +# Restore log_bin_trust_function_creators to original value +set global log_bin_trust_function_creators=0; +connection master; +set global log_bin_trust_function_creators=0; --echo End of 5.0 tests + +# +# Bug22043: MySQL don't add "USE <DATABASE>" before "DROP PROCEDURE IF EXISTS" +# +connection master; +reset master; +--disable_warnings +drop database if exists mysqltest; +drop database if exists mysqltest2; +--enable_warnings +create database mysqltest; +create database mysqltest2; +use mysqltest2; +create table t ( t integer ); +create procedure mysqltest.test() begin end; +insert into t values ( 1 ); +show binlog events in 'master-bin.000001' from 102; +--error ER_BAD_DB_ERROR +create procedure `\\`.test() begin end; +# Clean up +drop database mysqltest; +drop database mysqltest2; + --echo End of 5.1 tests diff --git a/mysql-test/t/rpl_sp_effects.test b/mysql-test/t/rpl_sp_effects.test index e1746682b76..027bfd69f36 100644 --- a/mysql-test/t/rpl_sp_effects.test +++ b/mysql-test/t/rpl_sp_effects.test @@ -20,6 +20,8 @@ drop view if exists v1; --enable_warnings create table t1 (a int); +SET GLOBAL log_bin_trust_function_creators = 1; + # 1. Test simple variables use. delimiter //; create procedure p1() @@ -205,3 +207,5 @@ drop function f1; drop function f2; drop procedure p1; sync_slave_with_master; + +SET GLOBAL log_bin_trust_function_creators = 0; diff --git a/mysql-test/t/rpl_timezone.test b/mysql-test/t/rpl_timezone.test index 5a6c1cd06f8..4b8c8152c82 100644 --- a/mysql-test/t/rpl_timezone.test +++ b/mysql-test/t/rpl_timezone.test @@ -17,6 +17,9 @@ source include/master-slave.inc; +# Save original timezone +set @my_time_zone= @@global.time_zone; + # Some preparations let $VERSION=`select version()`; set timestamp=100000000; # for fixed output of mysqlbinlog @@ -133,3 +136,7 @@ connection master; drop table t1, t2; sync_slave_with_master; + +# Restore original timezone +connection master; +set global time_zone= @my_time_zone; diff --git a/mysql-test/t/rpl_variables.test b/mysql-test/t/rpl_variables.test index b1744c57c9b..84dc3acfe6e 100644 --- a/mysql-test/t/rpl_variables.test +++ b/mysql-test/t/rpl_variables.test @@ -1,5 +1,8 @@ source include/master-slave.inc; +# Init for rstore of variable values +set @my_slave_net_timeout =@@global.slave_net_timeout; + set global slave_net_timeout=100; set global sql_slave_skip_counter=100; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 8f4763c636a..ba1180ffaff 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -359,7 +359,7 @@ end| --disable_warnings drop procedure if exists sub3| --enable_warnings -create function sub3(i int) returns int +create function sub3(i int) returns int deterministic return i+1| call sub1("sub1a", (select 7))| @@ -6706,6 +6706,83 @@ delimiter |; --echo End of 5.1 tests +# +# BUG#23760: ROW_COUNT() and store procedure not owrking together +# +--disable_warnings +DROP TABLE IF EXISTS bug23760| +DROP TABLE IF EXISTS bug23760_log| +DROP PROCEDURE IF EXISTS bug23760_update_log| +DROP PROCEDURE IF EXISTS bug23760_test_row_count| +DROP FUNCTION IF EXISTS bug23760_rc_test| +--enable_warnings +CREATE TABLE bug23760 ( + id INT NOT NULL AUTO_INCREMENT , + num INT NOT NULL , + PRIMARY KEY ( id ) +)| + +CREATE TABLE bug23760_log ( + id INT NOT NULL AUTO_INCREMENT , + reason VARCHAR(50)NULL , + ammount INT NOT NULL , + PRIMARY KEY ( id ) +)| + +CREATE PROCEDURE bug23760_update_log(r Varchar(50), a INT) +BEGIN + INSERT INTO bug23760_log (reason, ammount) VALUES(r, a); +END| + +CREATE PROCEDURE bug23760_test_row_count() +BEGIN + UPDATE bug23760 SET num = num + 1; + CALL bug23760_update_log('Test is working', ROW_COUNT()); + UPDATE bug23760 SET num = num - 1; +END| + + +CREATE PROCEDURE bug23760_test_row_count2(level INT) +BEGIN + IF level THEN + UPDATE bug23760 SET num = num + 1; + CALL bug23760_update_log('Test2 is working', ROW_COUNT()); + CALL bug23760_test_row_count2(level - 1); + END IF; +END| + +CREATE FUNCTION bug23760_rc_test(in_var INT) RETURNS INT RETURN in_var| + +INSERT INTO bug23760 (num) VALUES (0), (1), (1), (2), (3), (5), (8)| +SELECT ROW_COUNT()| + +CALL bug23760_test_row_count()| +SELECT * FROM bug23760_log ORDER BY id| + +SET @save_max_sp_recursion= @@max_sp_recursion_depth| +SELECT @save_max_sp_recursion| +SET max_sp_recursion_depth= 5| +SELECT @@max_sp_recursion_depth| +CALL bug23760_test_row_count2(2)| +SELECT ROW_COUNT()| +SELECT * FROM bug23760_log ORDER BY id| +SELECT * FROM bug23760 ORDER by ID| +SET max_sp_recursion_depth= @save_max_sp_recursion| + +SELECT bug23760_rc_test(123)| +INSERT INTO bug23760 (num) VALUES (13), (21), (34), (55)| +SELECT bug23760_rc_test(ROW_COUNT())| + +DROP TABLE bug23760, bug23760_log| +DROP PROCEDURE bug23760_update_log| +DROP PROCEDURE bug23760_test_row_count| +DROP FUNCTION bug23760_rc_test| + +# +# NOTE: The delimiter is `|`, and not `;`. It is changed to `;` +# at the end of the file! +# + # # BUG#NNNN: New bug synopsis # diff --git a/mysql-test/t/system_mysql_db_fix-master.opt b/mysql-test/t/system_mysql_db_fix30020-master.opt similarity index 100% rename from mysql-test/t/system_mysql_db_fix-master.opt rename to mysql-test/t/system_mysql_db_fix30020-master.opt diff --git a/mysql-test/t/system_mysql_db_fix.test b/mysql-test/t/system_mysql_db_fix30020.test similarity index 92% rename from mysql-test/t/system_mysql_db_fix.test rename to mysql-test/t/system_mysql_db_fix30020.test index cccf1d5767b..6188aebb9f5 100644 --- a/mysql-test/t/system_mysql_db_fix.test +++ b/mysql-test/t/system_mysql_db_fix30020.test @@ -10,9 +10,11 @@ # # This is the test for mysql_fix_privilege_tables +# It checks that a system tables from mysql 3.20 +# can be upgraded to current system table format # # Note: If this test fails, don't be confused about the errors reported -# by mysql-test-run; This shows warnings from generated by +# by mysql-test-run This shows warnings generated by # mysql_fix_system_tables which should be ignored. # Instead, concentrate on the errors in r/system_mysql_db.reject @@ -85,7 +87,7 @@ INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y',' INSERT INTO user VALUES ('localhost','', '','N','N','N','N','N','N','N','N','N'); # Call the "shell script" $MYSQL_FIX_SYSTEM_TABLES using system --- system $MYSQL_FIX_SYSTEM_TABLES --database=test > /dev/null +-- system $MYSQL_FIX_SYSTEM_TABLES --database=test > $MYSQLTEST_VARDIR/log/system_mysql_db_fix30020.log 2>&1 -- enable_query_log -- enable_result_log diff --git a/mysql-test/t/system_mysql_db_fix40123-master.opt b/mysql-test/t/system_mysql_db_fix40123-master.opt new file mode 100644 index 00000000000..7e4fa9a3ee8 --- /dev/null +++ b/mysql-test/t/system_mysql_db_fix40123-master.opt @@ -0,0 +1 @@ +--result-file=system_mysql_db diff --git a/mysql-test/t/system_mysql_db_fix40123.test b/mysql-test/t/system_mysql_db_fix40123.test new file mode 100644 index 00000000000..2d4fd1e920f --- /dev/null +++ b/mysql-test/t/system_mysql_db_fix40123.test @@ -0,0 +1,79 @@ +# Embedded server doesn't support external clients +--source include/not_embedded.inc + +# +# This is the test for mysql_fix_privilege_tables +# It checks that a system tables from mysql 4.1.23 +# can be upgraded to current system table format +# +# Note: If this test fails, don't be confused about the errors reported +# by mysql-test-run This shows warnings generated by +# mysql_fix_system_tables which should be ignored. +# Instead, concentrate on the errors in r/system_mysql_db.reject + +--disable_warnings +drop table if exists t1,t1aa,t2aa; +--enable_warnings + +-- disable_result_log +-- disable_query_log + +use test; + +# create system tables as in mysql-4.1.23 +# created by executing "./mysql_create_system_tables real ." + +set table_type=myisam; +CREATE TABLE db ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, PRIMARY KEY Host (Host,Db,User), KEY User (User) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Database privileges'; +INSERT INTO db VALUES ('%','test','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y'); +INSERT INTO db VALUES ('%','test\_%','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y'); + +CREATE TABLE host ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, PRIMARY KEY Host (Host,Db) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Host privileges; Merged with database privileges'; + + +CREATE TABLE user ( Host char(60) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Password char(41) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Reload_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Shutdown_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Process_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, File_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_db_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Super_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Repl_slave_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Repl_client_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, ssl_type enum('','ANY','X509', 'SPECIFIED') COLLATE utf8_general_ci DEFAULT '' NOT NULL, ssl_cipher BLOB NOT NULL, x509_issuer BLOB NOT NULL, x509_subject BLOB NOT NULL, max_questions int(11) unsigned DEFAULT 0 NOT NULL, max_updates int(11) unsigned DEFAULT 0 NOT NULL, max_connections int(11) unsigned DEFAULT 0 NOT NULL, PRIMARY KEY Host (Host,User) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Users and global privileges'; +INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0); + INSERT INTO user VALUES ('localhost','','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0); + +CREATE TABLE func ( name char(64) binary DEFAULT '' NOT NULL, ret tinyint(1) DEFAULT '0' NOT NULL, dl char(128) DEFAULT '' NOT NULL, type enum ('function','aggregate') COLLATE utf8_general_ci NOT NULL, PRIMARY KEY (name) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='User defined functions'; + + +CREATE TABLE tables_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Timestamp timestamp(14), Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Table privileges'; +CREATE TABLE columns_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Column_name char(64) binary DEFAULT '' NOT NULL, Timestamp timestamp(14), Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name,Column_name) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Column privileges'; + +CREATE TABLE help_topic ( help_topic_id int unsigned not null, name varchar(64) not null, help_category_id smallint unsigned not null, description text not null, example text not null, url varchar(128) not null, primary key (help_topic_id), unique index (name) ) engine=MyISAM CHARACTER SET utf8 comment='help topics'; +CREATE TABLE help_category ( help_category_id smallint unsigned not null, name varchar(64) not null, parent_category_id smallint unsigned null, url varchar(128) not null, primary key (help_category_id), unique index (name) ) engine=MyISAM CHARACTER SET utf8 comment='help categories'; +CREATE TABLE help_relation ( help_topic_id int unsigned not null references help_topic, help_keyword_id int unsigned not null references help_keyword, primary key (help_keyword_id, help_topic_id) ) engine=MyISAM CHARACTER SET utf8 comment='keyword-topic relation'; +CREATE TABLE help_keyword ( help_keyword_id int unsigned not null, name varchar(64) not null, primary key (help_keyword_id), unique index (name) ) engine=MyISAM CHARACTER SET utf8 comment='help keywords'; + +CREATE TABLE time_zone_name ( Name char(64) NOT NULL, Time_zone_id int unsigned NOT NULL, PRIMARY KEY Name (Name) ) engine=MyISAM CHARACTER SET utf8 comment='Time zone names'; + +CREATE TABLE time_zone ( Time_zone_id int unsigned NOT NULL auto_increment, Use_leap_seconds enum('Y','N') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, PRIMARY KEY TzId (Time_zone_id) ) engine=MyISAM CHARACTER SET utf8 comment='Time zones'; + +CREATE TABLE time_zone_transition ( Time_zone_id int unsigned NOT NULL, Transition_time bigint signed NOT NULL, Transition_type_id int unsigned NOT NULL, PRIMARY KEY TzIdTranTime (Time_zone_id, Transition_time) ) engine=MyISAM CHARACTER SET utf8 comment='Time zone transitions'; + +CREATE TABLE time_zone_transition_type ( Time_zone_id int unsigned NOT NULL, Transition_type_id int unsigned NOT NULL, Offset int signed DEFAULT 0 NOT NULL, Is_DST tinyint unsigned DEFAULT 0 NOT NULL, Abbreviation char(8) DEFAULT '' NOT NULL, PRIMARY KEY TzIdTrTId (Time_zone_id, Transition_type_id) ) engine=MyISAM CHARACTER SET utf8 comment='Time zone transition types'; + +CREATE TABLE time_zone_leap_second ( Transition_time bigint signed NOT NULL, Correction int signed NOT NULL, PRIMARY KEY TranTime (Transition_time) ) engine=MyISAM CHARACTER SET utf8 comment='Leap seconds information for time zones'; + + +# Run the mysql_fix_privilege_tables.sql using "mysql --force" +--exec $MYSQL --force test < $MYSQL_FIX_PRIVILEGE_TABLES > $MYSQLTEST_VARDIR/log/system_mysql_db_fix40123.log 2>&1 + +-- enable_query_log +-- enable_result_log + +# Dump the tables that should be compared +-- source include/system_db_struct.inc + +-- disable_query_log + +# Drop all tables created by this test +DROP TABLE db, host, user, func, plugin, tables_priv, columns_priv, procs_priv, help_category, help_keyword, help_relation, help_topic, proc, time_zone, time_zone_leap_second, time_zone_name, time_zone_transition, time_zone_transition_type, general_log, slow_log, event, binlog_index; + +-- enable_query_log + +# check that we dropped all system tables +show tables; + +# End of 4.1 tests diff --git a/mysql-test/t/system_mysql_db_fix50030-master.opt b/mysql-test/t/system_mysql_db_fix50030-master.opt new file mode 100644 index 00000000000..7e4fa9a3ee8 --- /dev/null +++ b/mysql-test/t/system_mysql_db_fix50030-master.opt @@ -0,0 +1 @@ +--result-file=system_mysql_db diff --git a/mysql-test/t/system_mysql_db_fix50030.test b/mysql-test/t/system_mysql_db_fix50030.test new file mode 100644 index 00000000000..78ecf1e573c --- /dev/null +++ b/mysql-test/t/system_mysql_db_fix50030.test @@ -0,0 +1,82 @@ +# Embedded server doesn't support external clients +--source include/not_embedded.inc + +# +# This is the test for mysql_fix_privilege_tables +# It checks that a system tables from mysql 5.0.30 +# can be upgraded to current system table format +# +# Note: If this test fails, don't be confused about the errors reported +# by mysql-test-run This shows warnings generated by +# mysql_fix_system_tables which should be ignored. +# Instead, concentrate on the errors in r/system_mysql_db.reject + +--disable_warnings +drop table if exists t1,t1aa,t2aa; +--enable_warnings + +-- disable_result_log +-- disable_query_log + +use test; + +# create system tables as in mysql-5.0.30 +# created by executing "./mysql_create_system_tables real ." + +set table_type=myisam; +CREATE TABLE db ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, PRIMARY KEY Host (Host,Db,User), KEY User (User) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Database privileges'; +INSERT INTO db VALUES ('%','test','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y','Y','Y','Y','N','N'); +INSERT INTO db VALUES ('%','test\_%','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y','Y','Y','Y','N','N'); + +CREATE TABLE host ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, PRIMARY KEY Host (Host,Db) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Host privileges; Merged with database privileges'; + +CREATE TABLE user ( Host char(60) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Password char(41) character set latin1 collate latin1_bin DEFAULT '' NOT NULL, Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Reload_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Shutdown_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Process_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, File_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_db_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Super_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Repl_slave_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Repl_client_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_user_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, ssl_type enum('','ANY','X509', 'SPECIFIED') COLLATE utf8_general_ci DEFAULT '' NOT NULL, ssl_cipher BLOB NOT NULL, x509_issuer BLOB NOT NULL, x509_subject BLOB NOT NULL, max_questions int(11) unsigned DEFAULT 0 NOT NULL, max_updates int(11) unsigned DEFAULT 0 NOT NULL, max_connections int(11) unsigned DEFAULT 0 NOT NULL, max_user_connections int(11) unsigned DEFAULT 0 NOT NULL, PRIMARY KEY Host (Host,User) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Users and global privileges'; +INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0); +INSERT INTO user VALUES ('localhost','','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0, 0); + +CREATE TABLE func ( name char(64) binary DEFAULT '' NOT NULL, ret tinyint(1) DEFAULT '0' NOT NULL, dl char(128) DEFAULT '' NOT NULL, type enum ('function','aggregate') COLLATE utf8_general_ci NOT NULL, PRIMARY KEY (name) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='User defined functions'; + +CREATE TABLE tables_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Timestamp timestamp(14), Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Table privileges'; + +CREATE TABLE columns_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Column_name char(64) binary DEFAULT '' NOT NULL, Timestamp timestamp(14), Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name,Column_name) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Column privileges'; + +CREATE TABLE help_topic ( help_topic_id int unsigned not null, name char(64) not null, help_category_id smallint unsigned not null, description text not null, example text not null, url char(128) not null, primary key (help_topic_id), unique index (name) ) engine=MyISAM CHARACTER SET utf8 comment='help topics'; +CREATE TABLE help_category ( help_category_id smallint unsigned not null, name char(64) not null, parent_category_id smallint unsigned null, url char(128) not null, primary key (help_category_id), unique index (name) ) engine=MyISAM CHARACTER SET utf8 comment='help categories'; +CREATE TABLE help_relation ( help_topic_id int unsigned not null references help_topic, help_keyword_id int unsigned not null references help_keyword, primary key (help_keyword_id, help_topic_id) ) engine=MyISAM CHARACTER SET utf8 comment='keyword-topic relation'; +CREATE TABLE help_keyword ( help_keyword_id int unsigned not null, name char(64) not null, primary key (help_keyword_id), unique index (name) ) engine=MyISAM CHARACTER SET utf8 comment='help keywords'; + +CREATE TABLE time_zone_name ( Name char(64) NOT NULL, Time_zone_id int unsigned NOT NULL, PRIMARY KEY Name (Name) ) engine=MyISAM CHARACTER SET utf8 comment='Time zone names'; + +CREATE TABLE time_zone ( Time_zone_id int unsigned NOT NULL auto_increment, Use_leap_seconds enum('Y','N') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, PRIMARY KEY TzId (Time_zone_id) ) engine=MyISAM CHARACTER SET utf8 comment='Time zones'; + +CREATE TABLE time_zone_transition ( Time_zone_id int unsigned NOT NULL, Transition_time bigint signed NOT NULL, Transition_type_id int unsigned NOT NULL, PRIMARY KEY TzIdTranTime (Time_zone_id, Transition_time) ) engine=MyISAM CHARACTER SET utf8 comment='Time zone transitions'; + +CREATE TABLE time_zone_transition_type ( Time_zone_id int unsigned NOT NULL, Transition_type_id int unsigned NOT NULL, Offset int signed DEFAULT 0 NOT NULL, Is_DST tinyint unsigned DEFAULT 0 NOT NULL, Abbreviation char(8) DEFAULT '' NOT NULL, PRIMARY KEY TzIdTrTId (Time_zone_id, Transition_type_id) ) engine=MyISAM CHARACTER SET utf8 comment='Time zone transition types'; + +CREATE TABLE time_zone_leap_second ( Transition_time bigint signed NOT NULL, Correction int signed NOT NULL, PRIMARY KEY TranTime (Transition_time) ) engine=MyISAM CHARACTER SET utf8 comment='Leap seconds information for time zones'; + +CREATE TABLE proc ( db char(64) collate utf8_bin DEFAULT '' NOT NULL, name char(64) DEFAULT '' NOT NULL, type enum('FUNCTION','PROCEDURE') NOT NULL, specific_name char(64) DEFAULT '' NOT NULL, language enum('SQL') DEFAULT 'SQL' NOT NULL, sql_data_access enum('CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA' ) DEFAULT 'CONTAINS_SQL' NOT NULL, is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL, security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, param_list blob DEFAULT '' NOT NULL, returns char(64) DEFAULT '' NOT NULL, body longblob DEFAULT '' NOT NULL, definer char(77) collate utf8_bin DEFAULT '' NOT NULL, created timestamp, modified timestamp, sql_mode set( 'REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', 'NOT_USED', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', 'POSTGRESQL', 'ORACLE', 'MSSQL', 'DB2', 'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS', 'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI', 'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES', 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE' ) DEFAULT '' NOT NULL, comment char(64) collate utf8_bin DEFAULT '' NOT NULL, PRIMARY KEY (db,name,type) ) engine=MyISAM character set utf8 comment='Stored Procedures'; + +CREATE TABLE procs_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Routine_name char(64) binary DEFAULT '' NOT NULL, Routine_type enum('FUNCTION','PROCEDURE') NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Timestamp timestamp(14), PRIMARY KEY (Host,Db,User,Routine_name,Routine_type), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges'; + + +# Run the mysql_fix_privilege_tables.sql using "mysql --force" +--exec $MYSQL --force test < $MYSQL_FIX_PRIVILEGE_TABLES > $MYSQLTEST_VARDIR/log/system_mysql_db_fix50030.log 2>&1 + +-- enable_query_log +-- enable_result_log + +# Dump the tables that should be compared +-- source include/system_db_struct.inc + +-- disable_query_log + +# Drop all tables created by this test +DROP TABLE db, host, user, func, plugin, tables_priv, columns_priv, procs_priv, help_category, help_keyword, help_relation, help_topic, proc, time_zone, time_zone_leap_second, time_zone_name, time_zone_transition, time_zone_transition_type, general_log, slow_log, event, binlog_index; + +-- enable_query_log + +# check that we dropped all system tables +show tables; + +# End of 4.1 tests diff --git a/mysql-test/t/timezone2.test b/mysql-test/t/timezone2.test index 862b9cc58d1..5e1f74d388f 100644 --- a/mysql-test/t/timezone2.test +++ b/mysql-test/t/timezone2.test @@ -228,6 +228,8 @@ drop table t1; # Test for bug #11081 "Using a CONVERT_TZ function in a stored function # or trigger fails". # +SET GLOBAL log_bin_trust_function_creators = 1; + create table t1 (ldt datetime, udt datetime); create function f1(i datetime) returns datetime return convert_tz(i, 'UTC', 'Europe/Moscow'); @@ -241,4 +243,6 @@ select ldt, f1(udt) as ldt2 from t1; drop table t1; drop function f1; +SET GLOBAL log_bin_trust_function_creators = 0; + # End of 5.0 tests diff --git a/mysql-test/t/udf.test b/mysql-test/t/udf.test index 01aac24ded4..b0580faea3d 100644 --- a/mysql-test/t/udf.test +++ b/mysql-test/t/udf.test @@ -149,9 +149,9 @@ EXPLAIN EXTENDED SELECT myfunc_int(a AS attr_name) FROM t1; EXPLAIN EXTENDED SELECT myfunc_int(a) FROM t1; SELECT a,c FROM v1; ---error ER_PARSE_ERROR +--error ER_WRONG_PARAMETERS_TO_STORED_FCT SELECT a, fn(MIN(b) xx) as c FROM t1 GROUP BY a; ---error ER_PARSE_ERROR +--error ER_WRONG_PARAMETERS_TO_STORED_FCT SELECT myfunc_int(fn(MIN(b) xx)) as c FROM t1 GROUP BY a; --error ER_PARSE_ERROR SELECT myfunc_int(test.fn(MIN(b) xx)) as c FROM t1 GROUP BY a; @@ -173,6 +173,22 @@ DROP FUNCTION fn; --echo End of 5.0 tests. +# +# Bug#24736: UDF functions parsed as Stored Functions +# + +select myfunc_double(3); +select myfunc_double(3 AS three); +select myfunc_double(abs(3)); +select myfunc_double(abs(3) AS named_param); +select abs(myfunc_double(3)); +select abs(myfunc_double(3 AS three)); + +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select myfunc_double(abs(3 AS wrong)); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select abs(myfunc_double(3) AS wrong); + # # BUG#18239: Possible to overload internal functions with stored functions # @@ -223,4 +239,41 @@ DROP FUNCTION lookup; DROP FUNCTION reverse_lookup; DROP FUNCTION avgcost; +# +# Bug#18761: constant expression as UDF parameters not passed in as constant +# +--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB +eval CREATE FUNCTION is_const RETURNS STRING SONAME "$UDF_EXAMPLE_LIB"; +select + is_const(3) as const, + is_const(3.14) as const, + is_const('fnord') as const, + is_const(2+3) as const, + is_const(rand()) as 'nc rand()', + is_const(sin(3.14)) as const, + is_const(upper('test')) as const; + +create table bug18761 (n int); +insert into bug18761 values (null),(2); +select + is_const(3) as const, + is_const(3.14) as const, + is_const('fnord') as const, + is_const(2+3) as const, + is_const(2+n) as 'nc 2+n ', + is_const(sin(n)) as 'nc sin(n)', + is_const(sin(3.14)) as const, + is_const(upper('test')) as const, + is_const(rand()) as 'nc rand()', + is_const(n) as 'nc n ', + is_const(is_const(n)) as 'nc ic?(n)', + is_const(is_const('c')) as const +from + bug18761; +drop table bug18761; + +--error 1241 +select is_const((1,2,3)); + +drop function if exists is_const; diff --git a/mysql-test/t/varbinary.test b/mysql-test/t/varbinary.test index 5fbd116d7b8..0e45bfb5e1b 100644 --- a/mysql-test/t/varbinary.test +++ b/mysql-test/t/varbinary.test @@ -37,3 +37,46 @@ select x,xx from t1; drop table t1; # End of 4.1 tests + +# +# Bug #19371 VARBINARY() have trailing zeros after upgrade from 4.1 +# + +# Test with a saved table from 4.1 +copy_file std_data/bug19371.frm $MYSQLTEST_VARDIR/master-data/test/t1.frm; +chmod 0777 $MYSQLTEST_VARDIR/master-data/test/t1.frm; +copy_file std_data/bug19371.MYD $MYSQLTEST_VARDIR/master-data/test/t1.MYD; +chmod 0777 $MYSQLTEST_VARDIR/master-data/test/t1.MYD; +copy_file std_data/bug19371.MYI $MYSQLTEST_VARDIR/master-data/test/t1.MYI; +chmod 0777 $MYSQLTEST_VARDIR/master-data/test/t1.MYI; + +# Everything _looks_ fine +show create table t1; + +# But the length of the varbinary columns are too long +select length(a), length(b) from t1; + +# Run CHECK TABLE, it should indicate table need a REPAIR TABLE +CHECK TABLE t1 FOR UPGRADE; + +# Run REPAIR TABLE to alter the table and repair +# the varbinary fields +REPAIR TABLE t1; + +# Now check it's back to normal +show create table t1; +select length(a), length(b) from t1; +insert into t1 values("ccc", "ddd"); +select length(a), length(b) from t1; +select hex(a), hex(b) from t1; +select concat("'", a, "'"), concat("'", b, "'") from t1; + +drop table t1; + +# Check that the fix does not affect table created with current version +create table t1(a varbinary(255)); +insert into t1 values("aaa "); +select length(a) from t1; +alter table t1 modify a varchar(255); +select length(a) from t1; + diff --git a/mysql-test/t/view_grant.test b/mysql-test/t/view_grant.test index 5c920a2fc4c..9c06e79e2ca 100644 --- a/mysql-test/t/view_grant.test +++ b/mysql-test/t/view_grant.test @@ -733,13 +733,13 @@ CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_tu AS SELECT * FROM mysqltest1.t1; CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_tus AS SELECT * FROM mysqltest1.t1; CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_td AS SELECT * FROM mysqltest1.t1; CREATE SQL SECURITY DEFINER VIEW mysqltest1.v_tds AS SELECT * FROM mysqltest1.t1; -GRANT SELECT, INSERT, UPDATE, DELETE ON mysqltest1.v_t1 TO readonly; -GRANT SELECT ON mysqltest1.v_ts TO readonly; -GRANT INSERT ON mysqltest1.v_ti TO readonly; -GRANT UPDATE ON mysqltest1.v_tu TO readonly; -GRANT UPDATE,SELECT ON mysqltest1.v_tus TO readonly; -GRANT DELETE ON mysqltest1.v_td TO readonly; -GRANT DELETE,SELECT ON mysqltest1.v_tds TO readonly; +GRANT SELECT, INSERT, UPDATE, DELETE ON mysqltest1.v_t1 TO readonly@localhost; +GRANT SELECT ON mysqltest1.v_ts TO readonly@localhost; +GRANT INSERT ON mysqltest1.v_ti TO readonly@localhost; +GRANT UPDATE ON mysqltest1.v_tu TO readonly@localhost; +GRANT UPDATE,SELECT ON mysqltest1.v_tus TO readonly@localhost; +GRANT DELETE ON mysqltest1.v_td TO readonly@localhost; +GRANT DELETE,SELECT ON mysqltest1.v_tds TO readonly@localhost; CONNECT (n1,localhost,readonly,,); CONNECTION n1; @@ -797,7 +797,7 @@ DROP VIEW mysqltest1.v_ti; DROP VIEW mysqltest1.v_ts; DROP VIEW mysqltest1.v_t1; DROP TABLE mysqltest1.t1; -DROP USER readonly@localhost; +DROP USER readonly@localhost; DROP DATABASE mysqltest1; # diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt index 7b362b4c1f9..ddbb5f5c328 100644 --- a/mysys/CMakeLists.txt +++ b/mysys/CMakeLists.txt @@ -26,4 +26,4 @@ ADD_LIBRARY(mysys array.c charset-def.c charset.c checksum.c default.c default_m my_static.c my_symlink.c my_symlink2.c my_sync.c my_thr_init.c my_wincond.c my_windac.c my_winsem.c my_winthread.c my_write.c ptr_cmp.c queues.c rijndael.c safemalloc.c sha1.c string.c thr_alarm.c thr_lock.c thr_mutex.c - thr_rwlock.c tree.c typelib.c my_vle.c base64.c my_memmem.c) + thr_rwlock.c tree.c typelib.c my_vle.c base64.c my_memmem.c my_getpagesize.c) diff --git a/mysys/Makefile.am b/mysys/Makefile.am index e115739b421..fb3f0e1688e 100644 --- a/mysys/Makefile.am +++ b/mysys/Makefile.am @@ -25,7 +25,7 @@ noinst_HEADERS = mysys_priv.h my_static.h libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \ mf_path.c mf_loadpath.c my_file.c \ my_open.c my_create.c my_dup.c my_seek.c my_read.c \ - my_pread.c my_write.c \ + my_pread.c my_write.c my_getpagesize.c \ mf_keycache.c mf_keycaches.c my_crc32.c \ mf_iocache.c mf_iocache2.c mf_cache.c mf_tempfile.c \ mf_tempdir.c my_lock.c mf_brkhant.c my_alarm.c \ diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 13524ce4e13..c26c3dd46e0 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -59,11 +59,15 @@ char *disabled_my_option= (char*) "0"; my_bool my_getopt_print_errors= 1; -static void default_reporter(enum loglevel level __attribute__((unused)), +static void default_reporter(enum loglevel level, const char *format, ...) { va_list args; va_start(args, format); + if (level == WARNING_LEVEL) + fprintf(stderr, "%s", "Warning: "); + else if (level == INFORMATION_LEVEL) + fprintf(stderr, "%s", "Info: "); vfprintf(stderr, format, args); va_end(args); } diff --git a/mysys/my_getpagesize.c b/mysys/my_getpagesize.c new file mode 100644 index 00000000000..ac4bd775ba9 --- /dev/null +++ b/mysys/my_getpagesize.c @@ -0,0 +1,41 @@ +/* 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 */ + +#include "mysys_priv.h" + +#ifndef HAVE_GETPAGESIZE + +#if defined __WIN__ + +int my_getpagesize(void) +{ + SYSTEM_INFO si; + GetSystemInfo(&si); + return si.dwPageSize; +} + +#else + +/* Default implementation */ +int my_getpagesize(void) +{ + return (int)8192; +} + +#endif + +#endif + diff --git a/mysys/my_mmap.c b/mysys/my_mmap.c index 19d9541a967..79030c0a695 100644 --- a/mysys/my_mmap.c +++ b/mysys/my_mmap.c @@ -33,13 +33,6 @@ int my_msync(int fd, void *addr, size_t len, int flags) static SECURITY_ATTRIBUTES mmap_security_attributes= {sizeof(SECURITY_ATTRIBUTES), 0, TRUE}; -int my_getpagesize(void) -{ - SYSTEM_INFO si; - GetSystemInfo(&si); - return si.dwPageSize; -} - void *my_mmap(void *addr, size_t len, int prot, int flags, int fd, my_off_t offset) { diff --git a/scripts/mysql_fix_privilege_tables.sh b/scripts/mysql_fix_privilege_tables.sh index 8c0c539f3f2..932857890e6 100644 --- a/scripts/mysql_fix_privilege_tables.sh +++ b/scripts/mysql_fix_privilege_tables.sh @@ -119,9 +119,6 @@ then fi cmd="$bindir/mysql --no-defaults --force --user=$user --host=$host" -if test ! -z "$password" ; then - cmd="$cmd --password=$password" -fi if test ! -z "$port"; then cmd="$cmd --port=$port" fi @@ -174,11 +171,22 @@ then s_echo "" fi +run_cmd() { + # Password argument is added here to allow for spaces in password. + + if test ! -z "$password" + then + cat $sql_file | $cmd --password="$password" + else + cat $sql_file | $cmd + fi +} + if test $verbose = 0 then - cat $sql_file | $cmd > /dev/null 2>&1 + run_cmd > /dev/null 2>&1 else - cat $sql_file | $cmd > /dev/null + run_cmd > /dev/null fi if test $? = 0 then diff --git a/scripts/mysql_fix_privilege_tables.sql b/scripts/mysql_fix_privilege_tables.sql index 1a52ee1d51b..37bd17c03d6 100644 --- a/scripts/mysql_fix_privilege_tables.sql +++ b/scripts/mysql_fix_privilege_tables.sql @@ -1,6 +1,5 @@ # This script converts any old privilege tables to privilege tables suitable # for this version of MySQL - # You can safely ignore all 'Duplicate column' and 'Unknown column' errors" # because these just mean that your tables are already up to date. # This script is safe to run even if your tables are already up to date! @@ -52,9 +51,8 @@ ADD x509_subject BLOB NOT NULL; ALTER TABLE user MODIFY ssl_type enum('','ANY','X509', 'SPECIFIED') NOT NULL; # -# Create tables_priv and columns_priv if they don't exists +# tables_priv # - CREATE TABLE IF NOT EXISTS tables_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, @@ -62,22 +60,38 @@ CREATE TABLE IF NOT EXISTS tables_priv ( Table_name char(64) binary DEFAULT '' NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Timestamp timestamp(14), - Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter') COLLATE utf8_general_ci DEFAULT '' NOT NULL, - Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL, + Table_priv set('Select','Insert','Update','Delete','Create', + 'Drop','Grant','References','Index','Alter') + COLLATE utf8_general_ci DEFAULT '' NOT NULL, + Column_priv set('Select','Insert','Update','References') + COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name) ) CHARACTER SET utf8 COLLATE utf8_bin; # Fix collation of set fields ALTER TABLE tables_priv - modify Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter') COLLATE utf8_general_ci DEFAULT '' NOT NULL, - modify Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL; -ALTER TABLE procs_priv ENGINE=MyISAM, CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin; -ALTER TABLE procs_priv - modify Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL; -ALTER TABLE procs_priv - add Routine_type enum('FUNCTION','PROCEDURE') COLLATE utf8_general_ci NOT NULL AFTER Routine_name; -ALTER TABLE procs_priv - modify Timestamp timestamp(14) AFTER Proc_priv; + ADD KEY Grantor (Grantor); +ALTER TABLE tables_priv + MODIFY Host char(60) NOT NULL default '', + MODIFY Db char(64) NOT NULL default '', + MODIFY User char(16) NOT NULL default '', + MODIFY Table_name char(64) NOT NULL default '', + MODIFY Grantor char(77) NOT NULL default '', + ENGINE=MyISAM, + CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin; + +ALTER TABLE tables_priv + MODIFY Column_priv set('Select','Insert','Update','References') + COLLATE utf8_general_ci DEFAULT '' NOT NULL, + MODIFY Table_priv set('Select','Insert','Update','Delete','Create', + 'Drop','Grant','References','Index','Alter', + 'Create View','Show view') + COLLATE utf8_general_ci DEFAULT '' NOT NULL, + COMMENT='Table privileges'; + +# +# columns_priv +# CREATE TABLE IF NOT EXISTS columns_priv ( Host char(60) DEFAULT '' NOT NULL, Db char(64) DEFAULT '' NOT NULL, @@ -88,16 +102,26 @@ CREATE TABLE IF NOT EXISTS columns_priv ( Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name,Column_name) ) CHARACTER SET utf8 COLLATE utf8_bin; -# Fix collation of set fields -ALTER TABLE columns_priv - MODIFY Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL; - - # # Name change of Type -> Column_priv from MySQL 3.22.12 # +ALTER TABLE columns_priv + CHANGE Type Column_priv set('Select','Insert','Update','References') + COLLATE utf8_general_ci DEFAULT '' NOT NULL; -ALTER TABLE columns_priv change Type Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL; +ALTER TABLE columns_priv + MODIFY Host char(60) NOT NULL default '', + MODIFY Db char(64) NOT NULL default '', + MODIFY User char(16) NOT NULL default '', + MODIFY Table_name char(64) NOT NULL default '', + MODIFY Column_name char(64) NOT NULL default '', + ENGINE=MyISAM, + CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin, + COMMENT='Column privileges'; + +ALTER TABLE columns_priv + MODIFY Column_priv set('Select','Insert','Update','References') + COLLATE utf8_general_ci DEFAULT '' NOT NULL; # # Add the new 'type' column to the func table. @@ -147,14 +171,12 @@ ADD Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL, ADD Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL; alter table user change max_questions max_questions int(11) unsigned DEFAULT 0 NOT NULL; -alter table tables_priv add KEY Grantor (Grantor); + alter table db comment='Database privileges'; alter table host comment='Host privileges; Merged with database privileges'; alter table user comment='Users and global privileges'; alter table func comment='User defined functions'; -alter table tables_priv comment='Table privileges'; -alter table columns_priv comment='Column privileges'; # Convert all tables to UTF-8 with binary collation # and reset all char columns to correct width @@ -186,6 +208,7 @@ ALTER TABLE user MODIFY Repl_slave_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, MODIFY Repl_client_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, MODIFY ssl_type enum('','ANY','X509', 'SPECIFIED') COLLATE utf8_general_ci DEFAULT '' NOT NULL; + ALTER TABLE db MODIFY Host char(60) NOT NULL default '', MODIFY Db char(64) NOT NULL default '', @@ -204,6 +227,7 @@ ALTER TABLE db MODIFY Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, MODIFY Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, MODIFY Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; + ALTER TABLE host MODIFY Host char(60) NOT NULL default '', MODIFY Db char(64) NOT NULL default '', @@ -221,29 +245,11 @@ ALTER TABLE host MODIFY Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, MODIFY Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, MODIFY Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; + ALTER TABLE func ENGINE=MyISAM, CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin; ALTER TABLE func MODIFY type enum ('function','aggregate') COLLATE utf8_general_ci NOT NULL; -ALTER TABLE columns_priv - MODIFY Host char(60) NOT NULL default '', - MODIFY Db char(64) NOT NULL default '', - MODIFY User char(16) NOT NULL default '', - MODIFY Table_name char(64) NOT NULL default '', - MODIFY Column_name char(64) NOT NULL default '', - ENGINE=MyISAM, CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin; -ALTER TABLE columns_priv - MODIFY Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL; -ALTER TABLE tables_priv - MODIFY Host char(60) NOT NULL default '', - MODIFY Db char(64) NOT NULL default '', - MODIFY User char(16) NOT NULL default '', - MODIFY Table_name char(64) NOT NULL default '', - MODIFY Grantor char(77) NOT NULL default '', - ENGINE=MyISAM, CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin; -ALTER TABLE tables_priv - MODIFY Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter') COLLATE utf8_general_ci DEFAULT '' NOT NULL, - MODIFY Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL; # # Detect whether we had Create_view_priv @@ -255,20 +261,25 @@ SELECT @hadCreateViewPriv:=1 FROM user WHERE Create_view_priv LIKE '%'; # Create VIEWs privileges (v5.0) # ALTER TABLE db ADD Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Lock_tables_priv; +ALTER TABLE db MODIFY Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Lock_tables_priv; + ALTER TABLE host ADD Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Lock_tables_priv; +ALTER TABLE host MODIFY Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Lock_tables_priv; + ALTER TABLE user ADD Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Repl_client_priv; +ALTER TABLE user MODIFY Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Repl_client_priv; # # Show VIEWs privileges (v5.0) # ALTER TABLE db ADD Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Create_view_priv; -ALTER TABLE host ADD Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Create_view_priv; -ALTER TABLE user ADD Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Create_view_priv; +ALTER TABLE db MODIFY Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Create_view_priv; -# -# Show/Create views table privileges (v5.0) -# -ALTER TABLE tables_priv MODIFY Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view') COLLATE utf8_general_ci DEFAULT '' NOT NULL; +ALTER TABLE host ADD Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Create_view_priv; +ALTER TABLE host MODIFY Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Create_view_priv; + +ALTER TABLE user ADD Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Create_view_priv; +ALTER TABLE user MODIFY Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Create_view_priv; # # Assign create/show view privileges to people who have create provileges @@ -285,18 +296,31 @@ SELECT @hadCreateRoutinePriv:=1 FROM user WHERE Create_routine_priv LIKE '%'; # Create PROCEDUREs privileges (v5.0) # ALTER TABLE db ADD Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Show_view_priv; +ALTER TABLE db MODIFY Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Show_view_priv; + ALTER TABLE host ADD Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Show_view_priv; +ALTER TABLE host MODIFY Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Show_view_priv; + ALTER TABLE user ADD Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Show_view_priv; +ALTER TABLE user MODIFY Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Show_view_priv; # # Alter PROCEDUREs privileges (v5.0) # ALTER TABLE db ADD Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Create_routine_priv; +ALTER TABLE db MODIFY Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Create_routine_priv; + ALTER TABLE host ADD Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Create_routine_priv; +ALTER TABLE host MODIFY Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Create_routine_priv; + ALTER TABLE user ADD Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Create_routine_priv; +ALTER TABLE user MODIFY Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Create_routine_priv; ALTER TABLE db ADD Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Alter_routine_priv; +ALTER TABLE db MODIFY Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Alter_routine_priv; + ALTER TABLE host ADD Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Alter_routine_priv; +ALTER TABLE host MODIFY Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Alter_routine_priv; # # Assign create/alter routine privileges to people who have create privileges @@ -318,26 +342,46 @@ SET @hadCreateUserPriv:=0; SELECT @hadCreateUserPriv:=1 FROM user WHERE Create_user_priv LIKE '%'; ALTER TABLE user ADD Create_user_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Alter_routine_priv; +ALTER TABLE user MODIFY Create_user_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Alter_routine_priv; UPDATE user LEFT JOIN db USING (Host,User) SET Create_user_priv='Y' WHERE @hadCreateUserPriv = 0 AND (user.Grant_priv = 'Y' OR db.Grant_priv = 'Y'); -# -# Create some possible missing tables -# +-- +-- procs_priv +-- CREATE TABLE IF NOT EXISTS procs_priv ( -Host char(60) binary DEFAULT '' NOT NULL, -Db char(64) binary DEFAULT '' NOT NULL, -User char(16) binary DEFAULT '' NOT NULL, -Routine_name char(64) binary DEFAULT '' NOT NULL, -Routine_type enum('FUNCTION','PROCEDURE') NOT NULL, -Grantor char(77) DEFAULT '' NOT NULL, -Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, -Timestamp timestamp(14), -PRIMARY KEY (Host,Db,User,Routine_name,Routine_type), -KEY Grantor (Grantor) + Host char(60) binary DEFAULT '' NOT NULL, + Db char(64) binary DEFAULT '' NOT NULL, + User char(16) binary DEFAULT '' NOT NULL, + Routine_name char(64) binary DEFAULT '' NOT NULL, + Routine_type enum('FUNCTION','PROCEDURE') NOT NULL, + Grantor char(77) DEFAULT '' NOT NULL, + Proc_priv set('Execute','Alter Routine','Grant') + COLLATE utf8_general_ci DEFAULT '' NOT NULL, + Timestamp timestamp(14), + PRIMARY KEY (Host, Db, User, Routine_name, Routine_type), + KEY Grantor (Grantor) ) CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges'; +ALTER TABLE procs_priv + ENGINE=MyISAM, + CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin; + +ALTER TABLE procs_priv + MODIFY Proc_priv set('Execute','Alter Routine','Grant') + COLLATE utf8_general_ci DEFAULT '' NOT NULL; + +ALTER TABLE procs_priv + ADD Routine_type enum('FUNCTION','PROCEDURE') + COLLATE utf8_general_ci NOT NULL AFTER Routine_name; + +ALTER TABLE procs_priv + MODIFY Timestamp timestamp(14) AFTER Proc_priv; + +-- +-- help_topic +-- CREATE TABLE IF NOT EXISTS help_topic ( help_topic_id int unsigned not null, name varchar(64) not null, @@ -413,7 +457,7 @@ PRIMARY KEY TranTime (Transition_time) # -# Create proc table if it doesn't exists +# Create proc table if it does not exists # CREATE TABLE IF NOT EXISTS proc ( @@ -634,7 +678,11 @@ SET @hadEventPriv := 0; SELECT @hadEventPriv :=1 FROM user WHERE Event_priv LIKE '%'; ALTER TABLE user add Event_priv enum('N','Y') character set utf8 DEFAULT 'N' NOT NULL AFTER Create_user_priv; +ALTER TABLE user MODIFY Event_priv enum('N','Y') character set utf8 DEFAULT 'N' NOT NULL AFTER Create_user_priv; + ALTER TABLE db add Event_priv enum('N','Y') character set utf8 DEFAULT 'N' NOT NULL; +ALTER TABLE db MODIFY Event_priv enum('N','Y') character set utf8 DEFAULT 'N' NOT NULL; + ALTER TABLE event DROP PRIMARY KEY; ALTER TABLE event ADD PRIMARY KEY(db, name); ALTER TABLE event ADD sql_mode @@ -681,8 +729,14 @@ SET @hadTriggerPriv := 0; SELECT @hadTriggerPriv :=1 FROM user WHERE Trigger_priv LIKE '%'; ALTER TABLE user ADD Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Event_priv; +ALTER TABLE user MODIFY Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Event_priv; + ALTER TABLE host ADD Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; -ALTER TABLE db ADD Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; +ALTER TABLE host MODIFY Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; + +ALTER TABLE db ADD Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; +ALTER TABLE db MODIFY Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; + ALTER TABLE tables_priv MODIFY Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger') COLLATE utf8_general_ci DEFAULT '' NOT NULL; UPDATE user SET Trigger_priv=Super_priv WHERE @hadTriggerPriv = 0; diff --git a/sql-common/my_time.c b/sql-common/my_time.c index fe6933c1c96..dcbd2eacdc1 100644 --- a/sql-common/my_time.c +++ b/sql-common/my_time.c @@ -411,7 +411,9 @@ str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time, if (number_of_fields < 3 || l_time->year > 9999 || l_time->month > 12 || l_time->day > 31 || l_time->hour > 23 || - l_time->minute > 59 || l_time->second > 59) + l_time->minute > 59 || l_time->second > 59 || + (l_time->year == 0 && l_time->month == 0 && l_time->day == 0 && + (l_time->hour != 0 || l_time->minute != 0 || l_time->second != 0))) { /* Only give warning for a zero date if there is some garbage after */ if (!not_zero_date) /* If zero date */ diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 01b5306f5a4..5fde5ecb2e8 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -308,6 +308,21 @@ static void do_field_string(Copy_field *copy) } +static void do_field_varbinary_pre50(Copy_field *copy) +{ + char buff[MAX_FIELD_WIDTH]; + copy->tmp.set_quick(buff,sizeof(buff),copy->tmp.charset()); + copy->from_field->val_str(©->tmp); + + /* Use the same function as in 4.1 to trim trailing spaces */ + uint length= my_lengthsp_8bit(&my_charset_bin, copy->tmp.c_ptr_quick(), + copy->from_field->field_length); + + copy->to_field->store(copy->tmp.c_ptr_quick(), length, + copy->tmp.charset()); +} + + static void do_field_int(Copy_field *copy) { longlong value= copy->from_field->val_int(); @@ -569,6 +584,15 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*) // Check if identical fields if (from->result_type() == STRING_RESULT) { + /* + Detect copy from pre 5.0 varbinary to varbinary as of 5.0 and + use special copy function that removes trailing spaces and thus + repairs data. + */ + if (from->type() == MYSQL_TYPE_VAR_STRING && !from->has_charset() && + to->type() == MYSQL_TYPE_VARCHAR && !to->has_charset()) + return do_field_varbinary_pre50; + /* If we are copying date or datetime's we have to check the dates if we don't allow 'all' dates. diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index fa69c113a69..0362b8bf215 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -7325,6 +7325,8 @@ static void print_ndbcluster_open_tables() DBUG_UNLOCK_FILE; } +#endif + #define dbug_print_open_tables() \ DBUG_EXECUTE("info", \ @@ -7336,7 +7338,6 @@ static void print_ndbcluster_open_tables() print_share((t), (s));); \ DBUG_UNLOCK_FILE; -#endif #ifdef HAVE_NDB_BINLOG /* diff --git a/sql/handler.cc b/sql/handler.cc index b134814db1e..ce9dc342713 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -2304,6 +2304,10 @@ int handler::check_old_types() { return HA_ADMIN_NEEDS_ALTER; } + if ((*field)->type() == MYSQL_TYPE_VAR_STRING) + { + return HA_ADMIN_NEEDS_ALTER; + } } } return 0; diff --git a/sql/item.cc b/sql/item.cc index b310c81af5c..e2ab28dd452 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -5574,6 +5574,7 @@ int Item_default_value::save_in_field(Field *field_arg, bool no_conversions) ER(ER_NO_DEFAULT_FOR_FIELD), field_arg->field_name); } + field_arg->set_default(); return 1; } field_arg->set_default(); diff --git a/sql/item_create.cc b/sql/item_create.cc index da8954910c8..80b5e946ae7 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -27,6 +27,37 @@ ============================================================================= */ +/** + Adapter for native functions with a variable number of arguments. + The main use of this class is to discard the following calls: + <code>foo(expr1 AS name1, expr2 AS name2, ...)</code> + which are syntactically correct (the syntax can refer to a UDF), + but semantically invalid for native functions. +*/ + +class Create_native_func : public Create_func +{ +public: + virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list); + + /** + Builder method, with no arguments. + @param thd The current thread + @param name The native function name + @param item_list The function parameters, none of which are named + @return An item representing the function call + */ + virtual Item* create_native(THD *thd, LEX_STRING name, + List<Item> *item_list) = 0; + +protected: + /** Constructor. */ + Create_native_func() {} + /** Destructor. */ + virtual ~Create_native_func() {} +}; + + /** Adapter for functions that takes exactly zero arguments. */ @@ -302,10 +333,10 @@ protected: }; -class Create_func_atan : public Create_func +class Create_func_atan : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *item_list); static Create_func_atan s_singleton; @@ -434,10 +465,10 @@ protected: }; -class Create_func_concat : public Create_func +class Create_func_concat : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *item_list); static Create_func_concat s_singleton; @@ -447,10 +478,10 @@ protected: }; -class Create_func_concat_ws : public Create_func +class Create_func_concat_ws : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *item_list); static Create_func_concat_ws s_singleton; @@ -672,10 +703,10 @@ protected: }; -class Create_func_des_decrypt : public Create_func +class Create_func_des_decrypt : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *item_list); static Create_func_des_decrypt s_singleton; @@ -685,10 +716,10 @@ protected: }; -class Create_func_des_encrypt : public Create_func +class Create_func_des_encrypt : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *item_list); static Create_func_des_encrypt s_singleton; @@ -728,10 +759,10 @@ protected: #endif -class Create_func_elt : public Create_func +class Create_func_elt : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *item_list); static Create_func_elt s_singleton; @@ -754,10 +785,10 @@ protected: }; -class Create_func_encrypt : public Create_func +class Create_func_encrypt : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *item_list); static Create_func_encrypt s_singleton; @@ -825,10 +856,10 @@ protected: }; -class Create_func_export_set : public Create_func +class Create_func_export_set : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *item_list); static Create_func_export_set s_singleton; @@ -853,10 +884,10 @@ protected: #endif -class Create_func_field : public Create_func +class Create_func_field : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *item_list); static Create_func_field s_singleton; @@ -931,10 +962,10 @@ protected: }; -class Create_func_from_unixtime : public Create_func +class Create_func_from_unixtime : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *item_list); static Create_func_from_unixtime s_singleton; @@ -945,10 +976,10 @@ protected: #ifdef HAVE_SPATIAL -class Create_func_geometry_from_text : public Create_func +class Create_func_geometry_from_text : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *item_list); static Create_func_geometry_from_text s_singleton; @@ -960,10 +991,10 @@ protected: #ifdef HAVE_SPATIAL -class Create_func_geometry_from_wkb : public Create_func +class Create_func_geometry_from_wkb : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *item_list); static Create_func_geometry_from_wkb s_singleton; @@ -1032,10 +1063,10 @@ protected: #endif -class Create_func_greatest : public Create_func +class Create_func_greatest : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *item_list); static Create_func_greatest s_singleton; @@ -1237,10 +1268,10 @@ protected: }; -class Create_func_last_insert_id : public Create_func +class Create_func_last_insert_id : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *item_list); static Create_func_last_insert_id s_singleton; @@ -1263,10 +1294,10 @@ protected: }; -class Create_func_least : public Create_func +class Create_func_least : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *item_list); static Create_func_least s_singleton; @@ -1315,10 +1346,10 @@ protected: }; -class Create_func_locate : public Create_func +class Create_func_locate : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *item_list); static Create_func_locate s_singleton; @@ -1328,10 +1359,10 @@ protected: }; -class Create_func_log : public Create_func +class Create_func_log : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *item_list); static Create_func_log s_singleton; @@ -1419,10 +1450,10 @@ protected: }; -class Create_func_make_set : public Create_func +class Create_func_make_set : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *item_list); static Create_func_make_set s_singleton; @@ -1432,10 +1463,10 @@ protected: }; -class Create_func_master_pos_wait : public Create_func +class Create_func_master_pos_wait : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *item_list); static Create_func_master_pos_wait s_singleton; @@ -1676,10 +1707,10 @@ protected: }; -class Create_func_rand : public Create_func +class Create_func_rand : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *item_list); static Create_func_rand s_singleton; @@ -1715,10 +1746,10 @@ protected: }; -class Create_func_round : public Create_func +class Create_func_round : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *item_list); static Create_func_round s_singleton; @@ -2085,10 +2116,10 @@ protected: }; -class Create_func_unix_timestamp : public Create_func +class Create_func_unix_timestamp : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *item_list); static Create_func_unix_timestamp s_singleton; @@ -2221,10 +2252,10 @@ protected: #endif -class Create_func_year_week : public Create_func +class Create_func_year_week : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List<Item> *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *item_list); static Create_func_year_week s_singleton; @@ -2240,6 +2271,29 @@ protected: ============================================================================= */ +/** + Checks if there are named parameters in a parameter list. + The syntax to name parameters in a function call is as follow: + <code>foo(expr AS named, expr named, expr AS "named", expr "named")</code> + @param params The parameter list, can be null + @return true if one or more parameter is named +*/ +static bool has_named_parameters(List<Item> *params) +{ + if (params) + { + Item *param; + List_iterator<Item> it(*params); + while ((param= it++)) + { + if (! param->is_autogenerated_name) + return true; + } + } + + return false; +} + #ifndef HAVE_SPATIAL Create_func_no_geom Create_func_no_geom::s_singleton; @@ -2387,11 +2441,27 @@ Create_sp_func::create(THD *thd, LEX_STRING db, LEX_STRING name, int arg_count= 0; Item *func= NULL; LEX *lex= thd->lex; - sp_name *qname= new (thd->mem_root) sp_name(db, name); + sp_name *qname; + + if (has_named_parameters(item_list)) + { + /* + The syntax "db.foo(expr AS p1, expr AS p2, ...) is invalid, + and has been rejected during syntactic parsing already, + because a stored function call may not have named parameters. + + The syntax "foo(expr AS p1, expr AS p2, ...)" is correct, + because it can refer to a User Defined Function call. + For a Stored Function however, this has no semantic. + */ + my_error(ER_WRONG_PARAMETERS_TO_STORED_FCT, MYF(0), name.str); + return NULL; + } if (item_list != NULL) arg_count= item_list->elements; + qname= new (thd->mem_root) sp_name(db, name); qname->init_qname(thd); sp_add_used_routine(lex, thd, qname, TYPE_ENUM_FUNCTION); @@ -2406,6 +2476,19 @@ Create_sp_func::create(THD *thd, LEX_STRING db, LEX_STRING name, } +Item* +Create_native_func::create(THD *thd, LEX_STRING name, List<Item> *item_list) +{ + if (has_named_parameters(item_list)) + { + my_error(ER_WRONG_PARAMETERS_TO_NATIVE_FCT, MYF(0), name.str); + return NULL; + } + + return create_native(thd, name, item_list); +} + + Item* Create_func_arg0::create(THD *thd, LEX_STRING name, List<Item> *item_list) { @@ -2439,6 +2522,13 @@ Create_func_arg1::create(THD *thd, LEX_STRING name, List<Item> *item_list) } Item *param_1= item_list->pop(); + + if (! param_1->is_autogenerated_name) + { + my_error(ER_WRONG_PARAMETERS_TO_NATIVE_FCT, MYF(0), name.str); + return NULL; + } + return create(thd, param_1); } @@ -2459,6 +2549,14 @@ Create_func_arg2::create(THD *thd, LEX_STRING name, List<Item> *item_list) Item *param_1= item_list->pop(); Item *param_2= item_list->pop(); + + if ( (! param_1->is_autogenerated_name) + || (! param_2->is_autogenerated_name)) + { + my_error(ER_WRONG_PARAMETERS_TO_NATIVE_FCT, MYF(0), name.str); + return NULL; + } + return create(thd, param_1, param_2); } @@ -2480,6 +2578,15 @@ Create_func_arg3::create(THD *thd, LEX_STRING name, List<Item> *item_list) Item *param_1= item_list->pop(); Item *param_2= item_list->pop(); Item *param_3= item_list->pop(); + + if ( (! param_1->is_autogenerated_name) + || (! param_2->is_autogenerated_name) + || (! param_3->is_autogenerated_name)) + { + my_error(ER_WRONG_PARAMETERS_TO_NATIVE_FCT, MYF(0), name.str); + return NULL; + } + return create(thd, param_1, param_2, param_3); } @@ -2574,7 +2681,8 @@ Create_func_asin::create(THD *thd, Item *arg1) Create_func_atan Create_func_atan::s_singleton; Item* -Create_func_atan::create(THD *thd, LEX_STRING name, List<Item> *item_list) +Create_func_atan::create_native(THD *thd, LEX_STRING name, + List<Item> *item_list) { Item* func= NULL; int arg_count= 0; @@ -2687,7 +2795,8 @@ Create_func_coercibility::create(THD *thd, Item *arg1) Create_func_concat Create_func_concat::s_singleton; Item* -Create_func_concat::create(THD *thd, LEX_STRING name, List<Item> *item_list) +Create_func_concat::create_native(THD *thd, LEX_STRING name, + List<Item> *item_list) { int arg_count= 0; @@ -2707,7 +2816,8 @@ Create_func_concat::create(THD *thd, LEX_STRING name, List<Item> *item_list) Create_func_concat_ws Create_func_concat_ws::s_singleton; Item* -Create_func_concat_ws::create(THD *thd, LEX_STRING name, List<Item> *item_list) +Create_func_concat_ws::create_native(THD *thd, LEX_STRING name, + List<Item> *item_list) { int arg_count= 0; @@ -2897,8 +3007,8 @@ Create_func_degrees::create(THD *thd, Item *arg1) Create_func_des_decrypt Create_func_des_decrypt::s_singleton; Item* -Create_func_des_decrypt::create(THD *thd, LEX_STRING name, - List<Item> *item_list) +Create_func_des_decrypt::create_native(THD *thd, LEX_STRING name, + List<Item> *item_list) { Item *func= NULL; int arg_count= 0; @@ -2934,8 +3044,8 @@ Create_func_des_decrypt::create(THD *thd, LEX_STRING name, Create_func_des_encrypt Create_func_des_encrypt::s_singleton; Item* -Create_func_des_encrypt::create(THD *thd, LEX_STRING name, - List<Item> *item_list) +Create_func_des_encrypt::create_native(THD *thd, LEX_STRING name, + List<Item> *item_list) { Item *func= NULL; int arg_count= 0; @@ -2994,7 +3104,8 @@ Create_func_disjoint::create(THD *thd, Item *arg1, Item *arg2) Create_func_elt Create_func_elt::s_singleton; Item* -Create_func_elt::create(THD *thd, LEX_STRING name, List<Item> *item_list) +Create_func_elt::create_native(THD *thd, LEX_STRING name, + List<Item> *item_list) { int arg_count= 0; @@ -3023,7 +3134,8 @@ Create_func_encode::create(THD *thd, Item *arg1, Item *arg2) Create_func_encrypt Create_func_encrypt::s_singleton; Item* -Create_func_encrypt::create(THD *thd, LEX_STRING name, List<Item> *item_list) +Create_func_encrypt::create_native(THD *thd, LEX_STRING name, + List<Item> *item_list) { Item *func= NULL; int arg_count= 0; @@ -3104,7 +3216,8 @@ Create_func_exp::create(THD *thd, Item *arg1) Create_func_export_set Create_func_export_set::s_singleton; Item* -Create_func_export_set::create(THD *thd, LEX_STRING name, List<Item> *item_list) +Create_func_export_set::create_native(THD *thd, LEX_STRING name, + List<Item> *item_list) { Item *func= NULL; int arg_count= 0; @@ -3168,7 +3281,8 @@ Create_func_exteriorring::create(THD *thd, Item *arg1) Create_func_field Create_func_field::s_singleton; Item* -Create_func_field::create(THD *thd, LEX_STRING name, List<Item> *item_list) +Create_func_field::create_native(THD *thd, LEX_STRING name, + List<Item> *item_list) { int arg_count= 0; @@ -3234,8 +3348,8 @@ Create_func_from_days::create(THD *thd, Item *arg1) Create_func_from_unixtime Create_func_from_unixtime::s_singleton; Item* -Create_func_from_unixtime::create(THD *thd, LEX_STRING name, - List<Item> *item_list) +Create_func_from_unixtime::create_native(THD *thd, LEX_STRING name, + List<Item> *item_list) { Item *func= NULL; int arg_count= 0; @@ -3273,8 +3387,8 @@ Create_func_from_unixtime::create(THD *thd, LEX_STRING name, Create_func_geometry_from_text Create_func_geometry_from_text::s_singleton; Item* -Create_func_geometry_from_text::create(THD *thd, LEX_STRING name, - List<Item> *item_list) +Create_func_geometry_from_text::create_native(THD *thd, LEX_STRING name, + List<Item> *item_list) { Item *func= NULL; int arg_count= 0; @@ -3313,8 +3427,8 @@ Create_func_geometry_from_text::create(THD *thd, LEX_STRING name, Create_func_geometry_from_wkb Create_func_geometry_from_wkb::s_singleton; Item* -Create_func_geometry_from_wkb::create(THD *thd, LEX_STRING name, - List<Item> *item_list) +Create_func_geometry_from_wkb::create_native(THD *thd, LEX_STRING name, + List<Item> *item_list) { Item *func= NULL; int arg_count= 0; @@ -3396,7 +3510,8 @@ Create_func_glength::create(THD *thd, Item *arg1) Create_func_greatest Create_func_greatest::s_singleton; Item* -Create_func_greatest::create(THD *thd, LEX_STRING name, List<Item> *item_list) +Create_func_greatest::create_native(THD *thd, LEX_STRING name, + List<Item> *item_list) { int arg_count= 0; @@ -3556,8 +3671,8 @@ Create_func_last_day::create(THD *thd, Item *arg1) Create_func_last_insert_id Create_func_last_insert_id::s_singleton; Item* -Create_func_last_insert_id::create(THD *thd, LEX_STRING name, - List<Item> *item_list) +Create_func_last_insert_id::create_native(THD *thd, LEX_STRING name, + List<Item> *item_list) { Item *func= NULL; int arg_count= 0; @@ -3602,7 +3717,8 @@ Create_func_lcase::create(THD *thd, Item *arg1) Create_func_least Create_func_least::s_singleton; Item* -Create_func_least::create(THD *thd, LEX_STRING name, List<Item> *item_list) +Create_func_least::create_native(THD *thd, LEX_STRING name, + List<Item> *item_list) { int arg_count= 0; @@ -3650,7 +3766,8 @@ Create_func_load_file::create(THD *thd, Item *arg1) Create_func_locate Create_func_locate::s_singleton; Item* -Create_func_locate::create(THD *thd, LEX_STRING name, List<Item> *item_list) +Create_func_locate::create_native(THD *thd, LEX_STRING name, + List<Item> *item_list) { Item *func= NULL; int arg_count= 0; @@ -3690,7 +3807,8 @@ Create_func_locate::create(THD *thd, LEX_STRING name, List<Item> *item_list) Create_func_log Create_func_log::s_singleton; Item* -Create_func_log::create(THD *thd, LEX_STRING name, List<Item> *item_list) +Create_func_log::create_native(THD *thd, LEX_STRING name, + List<Item> *item_list) { Item *func= NULL; int arg_count= 0; @@ -3780,7 +3898,8 @@ Create_func_maketime::create(THD *thd, Item *arg1, Item *arg2, Item *arg3) Create_func_make_set Create_func_make_set::s_singleton; Item* -Create_func_make_set::create(THD *thd, LEX_STRING name, List<Item> *item_list) +Create_func_make_set::create_native(THD *thd, LEX_STRING name, + List<Item> *item_list) { int arg_count= 0; @@ -3801,8 +3920,8 @@ Create_func_make_set::create(THD *thd, LEX_STRING name, List<Item> *item_list) Create_func_master_pos_wait Create_func_master_pos_wait::s_singleton; Item* -Create_func_master_pos_wait::create(THD *thd, LEX_STRING name, - List<Item> *item_list) +Create_func_master_pos_wait::create_native(THD *thd, LEX_STRING name, + List<Item> *item_list) { Item *func= NULL; int arg_count= 0; @@ -4010,7 +4129,8 @@ Create_func_radians::create(THD *thd, Item *arg1) Create_func_rand Create_func_rand::s_singleton; Item* -Create_func_rand::create(THD *thd, LEX_STRING name, List<Item> *item_list) +Create_func_rand::create_native(THD *thd, LEX_STRING name, + List<Item> *item_list) { Item *func= NULL; int arg_count= 0; @@ -4065,7 +4185,8 @@ Create_func_reverse::create(THD *thd, Item *arg1) Create_func_round Create_func_round::s_singleton; Item* -Create_func_round::create(THD *thd, LEX_STRING name, List<Item> *item_list) +Create_func_round::create_native(THD *thd, LEX_STRING name, + List<Item> *item_list) { Item *func= NULL; int arg_count= 0; @@ -4374,8 +4495,8 @@ Create_func_unhex::create(THD *thd, Item *arg1) Create_func_unix_timestamp Create_func_unix_timestamp::s_singleton; Item* -Create_func_unix_timestamp::create(THD *thd, LEX_STRING name, - List<Item> *item_list) +Create_func_unix_timestamp::create_native(THD *thd, LEX_STRING name, + List<Item> *item_list) { Item *func= NULL; int arg_count= 0; @@ -4506,7 +4627,8 @@ Create_func_y::create(THD *thd, Item *arg1) Create_func_year_week Create_func_year_week::s_singleton; Item* -Create_func_year_week::create(THD *thd, LEX_STRING name, List<Item> *item_list) +Create_func_year_week::create_native(THD *thd, LEX_STRING name, + List<Item> *item_list) { Item *func= NULL; int arg_count= 0; diff --git a/sql/item_func.cc b/sql/item_func.cc index 08e417d8322..0f5faf93cc3 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1362,6 +1362,10 @@ longlong Item_func_mod::int_op() signal_divide_by_null(); return 0; } + + if (args[0]->unsigned_flag) + return ((ulonglong) value) % val2; + return value % val2; } @@ -2730,39 +2734,47 @@ udf_handler::fix_fields(THD *thd, Item_result_field *func, char *to=num_buffer; for (uint i=0; i < arg_count; i++) { - f_args.args[i]=0; + /* + For a constant argument i, args->args[i] points to the argument value. + For non-constant, args->args[i] is NULL. + */ + f_args.args[i]= NULL; /* Non-const unless updated below. */ + f_args.lengths[i]= arguments[i]->max_length; f_args.maybe_null[i]= (char) arguments[i]->maybe_null; f_args.attributes[i]= arguments[i]->name; f_args.attribute_lengths[i]= arguments[i]->name_length; - switch(arguments[i]->type()) { - case Item::STRING_ITEM: // Constant string ! + if (arguments[i]->const_item()) { - String *res=arguments[i]->val_str(&buffers[i]); - if (arguments[i]->null_value) - continue; - f_args.args[i]= (char*) res->ptr(); - break; - } - case Item::INT_ITEM: - *((longlong*) to) = arguments[i]->val_int(); - if (!arguments[i]->null_value) - { - f_args.args[i]=to; - to+= ALIGN_SIZE(sizeof(longlong)); - } - break; - case Item::REAL_ITEM: - *((double*) to)= arguments[i]->val_real(); - if (!arguments[i]->null_value) - { - f_args.args[i]=to; - to+= ALIGN_SIZE(sizeof(double)); - } - break; - default: // Skip these - break; + if (arguments[i]->null_value) + continue; + + switch (arguments[i]->result_type()) + { + case STRING_RESULT: + case DECIMAL_RESULT: + { + String *res= arguments[i]->val_str(&buffers[i]); + f_args.args[i]= (char*) res->ptr(); + break; + } + case INT_RESULT: + *((longlong*) to)= arguments[i]->val_int(); + f_args.args[i]= to; + to+= ALIGN_SIZE(sizeof(longlong)); + break; + case REAL_RESULT: + *((double*) to)= arguments[i]->val_real(); + f_args.args[i]= to; + to+= ALIGN_SIZE(sizeof(double)); + break; + case ROW_RESULT: + default: + // This case should never be chosen + DBUG_ASSERT(0); + break; + } } } thd->net.last_error[0]=0; @@ -5024,6 +5036,18 @@ Item_func_sp::execute_impl(THD *thd, Field *return_value_fld) if (find_and_check_access(thd)) goto error; + /* + Throw an error if a non-deterministic function is called while + statement-based replication (SBR) is active. + */ + if (!m_sp->m_chistics->detistic && !trust_function_creators && + (mysql_bin_log.is_open() && + thd->variables.binlog_format == BINLOG_FORMAT_STMT)) + { + my_error(ER_BINLOG_ROW_RBR_TO_SBR, MYF(0)); + goto error; + } + /* Disable the binlogging if this is not a SELECT statement. If this is a SELECT, leave binlogging on, so execute_function() code writes the diff --git a/sql/item_func.h b/sql/item_func.h index 9139e30483d..9130ef0a0c4 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1315,10 +1315,10 @@ public: class Item_func_inet_aton : public Item_int_func { public: - Item_func_inet_aton(Item *a) :Item_int_func(a) {} - longlong val_int(); - const char *func_name() const { return "inet_aton"; } - void fix_length_and_dec() { decimals = 0; max_length = 21; maybe_null=1;} + Item_func_inet_aton(Item *a) :Item_int_func(a) {} + longlong val_int(); + const char *func_name() const { return "inet_aton"; } + void fix_length_and_dec() { decimals= 0; max_length= 21; maybe_null= 1; unsigned_flag= 1;} bool check_partition_func_processor(byte *int_arg) {return FALSE;} }; diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 76ab70cca96..ff688e15307 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -289,15 +289,16 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, for (; ptr != end && val != val_end; ptr++) { + /* Skip pre-space between each argument */ + while (val != val_end && my_isspace(cs, *val)) + val++; + if (*ptr == '%' && ptr+1 != end) { int val_len; char *tmp; error= 0; - /* Skip pre-space between each argument */ - while (val != val_end && my_isspace(cs, *val)) - val++; val_len= (uint) (val_end - val); switch (*++ptr) { @@ -3193,7 +3194,9 @@ bool Item_func_str_to_date::get_date(TIME *ltime, uint fuzzy_date) date_time_format.format.str= (char*) format->ptr(); date_time_format.format.length= format->length(); if (extract_date_time(&date_time_format, val->ptr(), val->length(), - ltime, cached_timestamp_type, 0, "datetime")) + ltime, cached_timestamp_type, 0, "datetime") || + ((fuzzy_date & TIME_NO_ZERO_DATE) && + (ltime->year == 0 || ltime->month == 0 || ltime->day == 0))) goto null_date; if (cached_timestamp_type == MYSQL_TIMESTAMP_TIME && ltime->day) { @@ -3230,8 +3233,13 @@ String *Item_func_str_to_date::val_str(String *str) bool Item_func_last_day::get_date(TIME *ltime, uint fuzzy_date) { - if (get_arg0_date(ltime, fuzzy_date & ~TIME_FUZZY_DATE)) + if (get_arg0_date(ltime, fuzzy_date & ~TIME_FUZZY_DATE) || + (ltime->month == 0)) + { + null_value= 1; return 1; + } + null_value= 0; uint month_idx= ltime->month-1; ltime->day= days_in_month[month_idx]; if ( month_idx == 1 && calc_days_in_year(ltime->year) == 366) diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index a75f204ae33..58e38362544 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1112,6 +1112,7 @@ bool mysql_ha_read(THD *, TABLE_LIST *,enum enum_ha_read_modes,char *, List<Item> *,enum ha_rkey_function,Item *,ha_rows,ha_rows); int mysql_ha_flush(THD *thd, TABLE_LIST *tables, uint mode_flags, bool is_locked); +void mysql_ha_mark_tables_for_reopen(THD *thd, TABLE *table); /* mysql_ha_flush mode_flags bits */ #define MYSQL_HA_CLOSE_FINAL 0x00 #define MYSQL_HA_REOPEN_ON_USAGE 0x01 diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 6921fe3e6d8..ee64a247e5a 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -346,7 +346,7 @@ bool opt_error_log= IF_WIN(1,0); bool opt_disable_networking=0, opt_skip_show_db=0; my_bool opt_character_set_client_handshake= 1; bool server_id_supplied = 0; -bool opt_endinfo,using_udf_functions; +bool opt_endinfo, using_udf_functions; my_bool locked_in_memory; bool opt_using_transactions, using_update_log; bool volatile abort_loop; @@ -2155,13 +2155,24 @@ later when used with nscd), disable LDAP in your nsswitch.conf, or use a\n\ mysqld that is not statically linked.\n"); #endif - if (test_flags & TEST_CORE_ON_SIGNAL) - { - fprintf(stderr, "Writing a core file\n"); - fflush(stderr); - write_core(sig); - } - exit(1); + if (locked_in_memory) + { + fprintf(stderr, "\n\ +The \"--memlock\" argument, which was enabled, uses system calls that are\n\ +unreliable and unstable on some operating systems and operating-system\n\ +versions (notably, some versions of Linux). This crash could be due to use\n\ +of those buggy OS calls. You should consider whether you really need the\n\ +\"--memlock\" parameter and/or consult the OS distributer about \"mlockall\"\n\ +bugs.\n"); + } + + if (test_flags & TEST_CORE_ON_SIGNAL) + { + fprintf(stderr, "Writing a core file\n"); + fflush(stderr); + write_core(sig); + } + exit(1); } #ifndef SA_RESETHAND @@ -2784,13 +2795,13 @@ static int init_common_variables(const char *conf_file_name, int argc, !(log_output_options & LOG_NONE)) sql_print_warning("Although a path was specified for the " "--log option, log tables are used. " - "To enable logging to file use the --log-output option."); + "To enable logging to files use the --log-output option."); if (opt_slow_log && opt_slow_logname && !(log_output_options & LOG_FILE) && !(log_output_options & LOG_NONE)) sql_print_warning("Although a path was specified for the " "--log-slow-queries option, log tables are used. " - "To enable logging to file use the --log-output option."); + "To enable logging to files use the --log-output option."); if (!opt_logname) opt_logname= make_default_log_name(buff, ".log"); @@ -5932,9 +5943,11 @@ The minimum value for this variable is 4096.", "If there is more than this number of interrupted connections from a host this host will be blocked from further connections.", (gptr*) &max_connect_errors, (gptr*) &max_connect_errors, 0, GET_ULONG, REQUIRED_ARG, MAX_CONNECT_ERRORS, 1, ~0L, 0, 1, 0}, + // Default max_connections of 151 is larger than Apache's default max + // children, to avoid "too many connections" error in a common setup {"max_connections", OPT_MAX_CONNECTIONS, "The number of simultaneous clients allowed.", (gptr*) &max_connections, - (gptr*) &max_connections, 0, GET_ULONG, REQUIRED_ARG, 100, 1, 16384, 0, 1, + (gptr*) &max_connections, 0, GET_ULONG, REQUIRED_ARG, 151, 1, 16384, 0, 1, 0}, {"max_delayed_threads", OPT_MAX_DELAYED_THREADS, "Don't start more than this number of threads to handle INSERT DELAYED statements. If set to zero, which means INSERT DELAYED is not used.", @@ -6624,6 +6637,7 @@ SHOW_VAR status_vars[]= { {"Com_create_function", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_FUNCTION]), SHOW_LONG_STATUS}, {"Com_create_index", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_INDEX]), SHOW_LONG_STATUS}, {"Com_create_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_TABLE]), SHOW_LONG_STATUS}, + {"Com_create_user", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_USER]), SHOW_LONG_STATUS}, {"Com_dealloc_sql", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DEALLOCATE_PREPARE]), SHOW_LONG_STATUS}, {"Com_delete", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DELETE]), SHOW_LONG_STATUS}, {"Com_delete_multi", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DELETE_MULTI]), SHOW_LONG_STATUS}, diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index cfeca697692..c64f4da045e 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -6010,6 +6010,8 @@ ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT 42000 eng "Incorrect parameter count in the call to native function '%-.64s'" ER_WRONG_PARAMETERS_TO_NATIVE_FCT 42000 eng "Incorrect parameters in the call to native function '%-.64s'" +ER_WRONG_PARAMETERS_TO_STORED_FCT 42000 + eng "Incorrect parameters in the call to stored function '%-.64s'" ER_NATIVE_FCT_NAME_COLLISION eng "This function '%-.64s' has the same name as a native function." ER_BINLOG_PURGE_EMFILE diff --git a/sql/sp.cc b/sql/sp.cc index 45a177d3e7a..9e53aff742e 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -497,17 +497,10 @@ db_create_routine(THD *thd, int type, sp_head *sp) char definer[USER_HOST_BUFF_SIZE]; char old_db_buf[NAME_LEN+1]; LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) }; - bool dbchanged; DBUG_ENTER("db_create_routine"); DBUG_PRINT("enter", ("type: %d name: %.*s",type,sp->m_name.length, sp->m_name.str)); - if ((ret= sp_use_new_db(thd, sp->m_db, &old_db, 0, &dbchanged))) - { - ret= SP_NO_DB_ERROR; - goto done; - } - if (!(table= open_proc_table_for_update(thd))) ret= SP_OPEN_TABLE_FAILED; else @@ -631,8 +624,6 @@ db_create_routine(THD *thd, int type, sp_head *sp) done: close_thread_tables(thd); - if (dbchanged) - (void) mysql_change_db(thd, old_db.str, 1); DBUG_RETURN(ret); } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index db6baac8681..3fd09d909a4 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1089,6 +1089,13 @@ void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived) DBUG_PRINT("info", ("thd->open_tables: 0x%lx", (long) thd->open_tables)); + /* + End open index scans and table scans and remove references to the tables + from the handler tables hash. After this preparation it is safe to close + the tables. + */ + mysql_ha_mark_tables_for_reopen(thd, thd->open_tables); + found_old_table= 0; while (thd->open_tables) found_old_table|= close_thread_table(thd, &thd->open_tables); diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index c448be04ac5..5951acdcc40 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -757,3 +757,41 @@ static int mysql_ha_flush_table(THD *thd, TABLE **table_ptr, uint mode_flags) DBUG_RETURN(0); } + + +/* + Mark tables for reopen. + + SYNOPSIS + mysql_ha_mark_tables_for_reopen() + thd Thread identifier. + table Table list to mark for reopen. + + DESCRIPTION + For each table found in the handler hash mark it as closed + (ready for reopen) and end all index/table scans. + + NOTE + The caller must lock LOCK_open. +*/ + +void mysql_ha_mark_tables_for_reopen(THD *thd, TABLE *table) +{ + DBUG_ENTER("mysql_ha_mark_tables_for_reopen"); + + safe_mutex_assert_owner(&LOCK_open); + for (; table; table= table->next) + { + TABLE_LIST *hash_tables; + if ((hash_tables= (TABLE_LIST*) hash_search(&thd->handler_tables_hash, + (byte*) table->alias, + strlen(table->alias) + 1))) + { + /* Mark table as ready for reopen. */ + hash_tables->table= NULL; + /* End open index/table scans. */ + table->file->ha_index_or_rnd_end(); + } + } + DBUG_VOID_RETURN; +} diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 47704570720..d156973a790 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -164,7 +164,6 @@ void lex_start(THD *thd, const uchar *buf, uint length) lex->select_lex.ftfunc_list= &lex->select_lex.ftfunc_list_alloc; lex->select_lex.group_list.empty(); lex->select_lex.order_list.empty(); - lex->select_lex.udf_list.empty(); lex->ignore_space=test(thd->variables.sql_mode & MODE_IGNORE_SPACE); lex->sql_command= SQLCOM_END; lex->duplicates= DUP_ERROR; @@ -1182,7 +1181,6 @@ void st_select_lex::init_select() braces= 0; when_list.empty(); expr_list.empty(); - udf_list.empty(); interval_list.empty(); use_index.empty(); ftfunc_list_alloc.empty(); diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 4af767b25db..7fd60cbfa58 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -609,8 +609,6 @@ public: /* exclude this select from check of unique_table() */ bool exclude_from_table_unique_test; - List<udf_func> udf_list; /* udf function calls stack */ - void init_query(); void init_select(); st_select_lex_unit* master_unit(); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 401285c2f8b..3f06c0680e2 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -57,10 +57,6 @@ (LP)->sql_command == SQLCOM_DROP_FUNCTION ? \ "FUNCTION" : "PROCEDURE") -#ifdef SOLARIS -extern "C" int gethostname(char *name, int namelen); -#endif - static void time_out_user_resource_limits(THD *thd, USER_CONN *uc); #ifndef NO_EMBEDDED_ACCESS_CHECKS static int check_for_max_user_connections(THD *thd, USER_CONN *uc); @@ -2631,10 +2627,11 @@ mysql_execute_command(THD *thd) if (opt_readonly && !(thd->security_ctx->master_access & SUPER_ACL) && (sql_command_flags[lex->sql_command] & CF_CHANGES_DATA) && - !((lex->sql_command == SQLCOM_CREATE_TABLE) && - (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)) && - ((lex->sql_command != SQLCOM_UPDATE_MULTI) && - some_non_temp_table_to_be_updated(thd, all_tables))) + !((lex->sql_command == SQLCOM_CREATE_TABLE) && + (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)) && + !((lex->sql_command == SQLCOM_DROP_TABLE) && lex->drop_temporary) && + ((lex->sql_command != SQLCOM_UPDATE_MULTI) && + some_non_temp_table_to_be_updated(thd, all_tables))) { my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only"); DBUG_RETURN(-1); @@ -4229,6 +4226,7 @@ end_with_restore_list: bool write_to_binlog; if (check_global_access(thd,RELOAD_ACL)) goto error; + /* reload_acl_and_cache() will tell us if we are allowed to write to the binlog or not. @@ -4249,7 +4247,8 @@ end_with_restore_list: } } send_ok(thd); - } + } + break; } case SQLCOM_KILL: @@ -4434,25 +4433,37 @@ end_with_restore_list: { uint namelen; char *name; - int result; + int result= SP_INTERNAL_ERROR; DBUG_ASSERT(lex->sphead != 0); DBUG_ASSERT(lex->sphead->m_db.str); /* Must be initialized in the parser */ + /* + Verify that the database name is allowed, optionally + lowercase it. + */ + if (check_db_name(&lex->sphead->m_db)) + { + my_error(ER_WRONG_DB_NAME, MYF(0), lex->sphead->m_db.str); + goto create_sp_error; + } + + /* + Check that a database directory with this name + exists. Design note: This won't work on virtual databases + like information_schema. + */ + if (check_db_dir_existence(lex->sphead->m_db.str)) + { + my_error(ER_BAD_DB_ERROR, MYF(0), lex->sphead->m_db.str); + goto create_sp_error; + } if (check_access(thd, CREATE_PROC_ACL, lex->sphead->m_db.str, 0, 0, 0, is_schema_db(lex->sphead->m_db.str))) - { - delete lex->sphead; - lex->sphead= 0; - goto error; - } + goto create_sp_error; - if (end_active_trans(thd)) - { - delete lex->sphead; - lex->sphead= 0; - goto error; - } + if (end_active_trans(thd)) + goto create_sp_error; name= lex->sphead->name(&namelen); #ifdef HAVE_DLOPEN @@ -4462,10 +4473,8 @@ end_with_restore_list: if (udf) { - my_error(ER_UDF_EXISTS, MYF(0), name); - delete lex->sphead; - lex->sphead= 0; - goto error; + my_error(ER_UDF_EXISTS, MYF(0), name); + goto create_sp_error; } } #endif @@ -4473,7 +4482,7 @@ end_with_restore_list: /* If the definer is not specified, this means that CREATE-statement missed DEFINER-clause. DEFINER-clause can be missed in two cases: - + - The user submitted a statement w/o the clause. This is a normal case, we should assign CURRENT_USER as definer. @@ -4482,7 +4491,7 @@ end_with_restore_list: CURRENT_USER as definer here, but also we should mark this routine as NON-SUID. This is essential for the sake of backward compatibility. - + The problem is the slave thread is running under "special" user (@), that actually does not exist. In the older versions we do not fail execution of a stored routine if its definer does not exist and @@ -4507,13 +4516,9 @@ end_with_restore_list: if (ps_arena) thd->restore_active_arena(ps_arena, &original_arena); + /* Error has been already reported. */ if (res) - { - /* Error has been already reported. */ - delete lex->sphead; - lex->sphead= 0; - goto error; - } + goto create_sp_error; if (thd->slave_thread) lex->sphead->m_chistics->suid= SP_IS_NOT_SUID; @@ -4524,7 +4529,7 @@ end_with_restore_list: that the current user has SUPER privilege (in order to create a stored routine under another user one must have SUPER privilege). */ - + else if (strcmp(lex->definer->user.str, thd->security_ctx->priv_user) || my_strcasecmp(system_charset_info, lex->definer->host.str, @@ -4533,9 +4538,7 @@ end_with_restore_list: if (check_global_access(thd, SUPER_ACL)) { my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER"); - delete lex->sphead; - lex->sphead= 0; - goto error; + goto create_sp_error; } } @@ -4555,54 +4558,51 @@ end_with_restore_list: #endif /* NO_EMBEDDED_ACCESS_CHECKS */ res= (result= lex->sphead->create(thd)); - if (result == SP_OK) - { + switch (result) { + case SP_OK: #ifndef NO_EMBEDDED_ACCESS_CHECKS /* only add privileges if really neccessary */ if (sp_automatic_privileges && !opt_noacl && check_routine_access(thd, DEFAULT_CREATE_PROC_ACLS, - lex->sphead->m_db.str, name, + lex->sphead->m_db.str, name, lex->sql_command == SQLCOM_CREATE_PROCEDURE, 1)) { if (sp_grant_privileges(thd, lex->sphead->m_db.str, name, lex->sql_command == SQLCOM_CREATE_PROCEDURE)) - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_PROC_AUTO_GRANT_FAIL, - ER(ER_PROC_AUTO_GRANT_FAIL)); + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_PROC_AUTO_GRANT_FAIL, + ER(ER_PROC_AUTO_GRANT_FAIL)); close_thread_tables(thd); } #endif - lex->unit.cleanup(); - delete lex->sphead; - lex->sphead= 0; - send_ok(thd); - } - else - { - switch (result) { - case SP_WRITE_ROW_FAILED: - my_error(ER_SP_ALREADY_EXISTS, MYF(0), SP_TYPE_STRING(lex), name); - break; - case SP_NO_DB_ERROR: - my_error(ER_BAD_DB_ERROR, MYF(0), lex->sphead->m_db.str); - break; - case SP_BAD_IDENTIFIER: - my_error(ER_TOO_LONG_IDENT, MYF(0), name); - break; - case SP_BODY_TOO_LONG: - my_error(ER_TOO_LONG_BODY, MYF(0), name); - break; - default: - my_error(ER_SP_STORE_FAILED, MYF(0), SP_TYPE_STRING(lex), name); - break; - } - lex->unit.cleanup(); - delete lex->sphead; - lex->sphead= 0; - goto error; - } break; - } + case SP_WRITE_ROW_FAILED: + my_error(ER_SP_ALREADY_EXISTS, MYF(0), SP_TYPE_STRING(lex), name); + break; + case SP_BAD_IDENTIFIER: + my_error(ER_TOO_LONG_IDENT, MYF(0), name); + break; + case SP_BODY_TOO_LONG: + my_error(ER_TOO_LONG_BODY, MYF(0), name); + break; + default: + my_error(ER_SP_STORE_FAILED, MYF(0), SP_TYPE_STRING(lex), name); + break; + } /* end switch */ + + /* + Capture all errors within this CASE and + clean up the environment. + */ +create_sp_error: + lex->unit.cleanup(); + delete lex->sphead; + lex->sphead= 0; + if (result != SP_OK ) + goto error; + send_ok(thd); + break; /* break super switch */ + } /* end case group bracket */ case SQLCOM_CALL: { sp_head *sp; @@ -4678,8 +4678,6 @@ end_with_restore_list: select_limit= thd->variables.select_limit; thd->variables.select_limit= HA_POS_ERROR; - thd->row_count_func= 0; - /* We never write CALL statements into binlog: - If the mode is non-prelocked, each statement will be logged @@ -6974,7 +6972,10 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, than it would help them) */ tmp_write_to_binlog= 0; - mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE); + if( mysql_bin_log.is_open() ) + { + mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE); + } #ifdef HAVE_REPLICATION pthread_mutex_lock(&LOCK_active_mi); rotate_relay_log(active_mi); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 75d7f4c9fbf..165a82e4b27 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -37,7 +37,9 @@ static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end); static int copy_data_between_tables(TABLE *from,TABLE *to, List<create_field> &create, bool ignore, uint order_num, ORDER *order, - ha_rows *copied,ha_rows *deleted); + ha_rows *copied,ha_rows *deleted, + enum enum_enable_or_disable keys_onoff); + static bool prepare_blob_field(THD *thd, create_field *sql_field); static bool check_engine(THD *thd, const char *table_name, HA_CREATE_INFO *create_info); @@ -5195,6 +5197,54 @@ static uint compare_tables(TABLE *table, List<create_field> *create_list, } +/* + Manages enabling/disabling of indexes for ALTER TABLE + + SYNOPSIS + alter_table_manage_keys() + table Target table + indexes_were_disabled Whether the indexes of the from table + were disabled + keys_onoff ENABLE | DISABLE | LEAVE_AS_IS + + RETURN VALUES + FALSE OK + TRUE Error +*/ + +static +bool alter_table_manage_keys(TABLE *table, int indexes_were_disabled, + enum enum_enable_or_disable keys_onoff) +{ + int error= 0; + DBUG_ENTER("alter_table_manage_keys"); + DBUG_PRINT("enter", ("table=%p were_disabled=%d on_off=%d", + table, indexes_were_disabled, keys_onoff)); + + switch (keys_onoff) { + case ENABLE: + error= table->file->enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); + break; + case LEAVE_AS_IS: + if (!indexes_were_disabled) + break; + /* fall-through: disabled indexes */ + case DISABLE: + error= table->file->disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); + } + + if (error == HA_ERR_WRONG_COMMAND) + { + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_NOTE, + ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA), table->s->table_name); + error= 0; + } else if (error) + table->file->print_error(error, MYF(0)); + + DBUG_RETURN(error); +} + + /* Alter table */ @@ -5443,13 +5493,35 @@ view_err: if (!(alter_info->flags & ~(ALTER_RENAME | ALTER_KEYS_ONOFF)) && !table->s->tmp_table) // no need to touch frm { - error=0; VOID(pthread_mutex_lock(&LOCK_open)); - if (new_name != table_name || new_db != db) + + switch (alter_info->keys_onoff) { + case LEAVE_AS_IS: + error= 0; + break; + case ENABLE: + wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN); + error= table->file->enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); + /* COND_refresh will be signaled in close_thread_tables() */ + break; + case DISABLE: + wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN); + error=table->file->disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); + /* COND_refresh will be signaled in close_thread_tables() */ + break; + } + if (error == HA_ERR_WRONG_COMMAND) + { + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, + ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA), + table->alias); + error= 0; + } + + if (!error && (new_name != table_name || new_db != db)) { thd->proc_info="rename"; /* Then do a 'simple' rename of the table */ - error=0; if (!access(new_name_buff,F_OK)) { my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name); @@ -5472,31 +5544,14 @@ view_err: } } - if (!error) - { - switch (alter_info->keys_onoff) { - case LEAVE_AS_IS: - break; - case ENABLE: - wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN); - error= table->file->enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); - /* COND_refresh will be signaled in close_thread_tables() */ - break; - case DISABLE: - wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN); - error=table->file->disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); - /* COND_refresh will be signaled in close_thread_tables() */ - break; - } - } - if (error == HA_ERR_WRONG_COMMAND) { push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA), table->alias); - error=0; + error= 0; } + if (!error) { write_bin_log(thd, TRUE, thd->query, thd->query_length); @@ -5509,7 +5564,7 @@ view_err: error= -1; } VOID(pthread_mutex_unlock(&LOCK_open)); - table_list->table=0; // For query cache + table_list->table= NULL; // For query cache query_cache_invalidate3(thd, table_list, 0); DBUG_RETURN(error); } @@ -6112,7 +6167,18 @@ view_err: new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET; new_table->next_number_field=new_table->found_next_number_field; error=copy_data_between_tables(table, new_table, create_list, ignore, - order_num, order, &copied, &deleted); + order_num, order, &copied, &deleted, + alter_info->keys_onoff); + } + else + { + VOID(pthread_mutex_lock(&LOCK_open)); + wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN); + table->file->ha_external_lock(thd, F_WRLCK); + alter_table_manage_keys(table, table->file->indexes_are_disabled(), + alter_info->keys_onoff); + table->file->ha_external_lock(thd, F_UNLCK); + VOID(pthread_mutex_unlock(&LOCK_open)); } thd->count_cuted_fields= CHECK_FIELD_IGNORE; @@ -6529,7 +6595,8 @@ copy_data_between_tables(TABLE *from,TABLE *to, bool ignore, uint order_num, ORDER *order, ha_rows *copied, - ha_rows *deleted) + ha_rows *deleted, + enum enum_enable_or_disable keys_onoff) { int error; Copy_field *copy,*copy_end; @@ -6563,6 +6630,9 @@ copy_data_between_tables(TABLE *from,TABLE *to, if (to->file->ha_external_lock(thd, F_WRLCK)) DBUG_RETURN(-1); + /* We need external lock before we can disable/enable keys */ + alter_table_manage_keys(to, from->file->indexes_are_disabled(), keys_onoff); + /* We can abort alter table for any table type */ thd->no_trans_update= 0; thd->abort_on_warning= !ignore && test(thd->variables.sql_mode & diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index fcac7eb8e05..434cd0e4cd5 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -6426,7 +6426,7 @@ function_call_generic: } } /* Temporary placing the result of find_udf in $3 */ - lex->current_select->udf_list.push_front(udf); + $<udf>$= udf; #endif } udf_expr_list ')' @@ -6454,10 +6454,10 @@ function_call_generic: { #ifdef HAVE_DLOPEN /* Retrieving the result of find_udf */ - udf_func *udf; + udf_func *udf= $<udf>3; LEX *lex= Lex; - if (NULL != (udf= lex->current_select->udf_list.pop())) + if (udf) { if (udf->type == UDFTYPE_AGGREGATE) { @@ -6553,7 +6553,6 @@ udf_expr_list3: udf_expr: remember_name expr remember_end select_alias { - udf_func *udf= Select->udf_list.head(); /* Use Item::name as a storage for the attribute value of user defined function argument. It is safe to use Item::name @@ -6562,20 +6561,10 @@ udf_expr: */ if ($4.str) { - if (!udf) - { - /* - Disallow using AS to specify explicit names for the arguments - of stored routine calls - */ - yyerror(ER(ER_SYNTAX_ERROR)); - YYABORT; - } - $2->is_autogenerated_name= FALSE; $2->set_name($4.str, $4.length, system_charset_info); } - else if (udf) + else $2->set_name($1, (uint) ($3 - $1), YYTHD->charset()); $$= $2; } diff --git a/sql/udf_example.c b/sql/udf_example.c index 2fa7474eb16..bbab47e253d 100644 --- a/sql/udf_example.c +++ b/sql/udf_example.c @@ -165,6 +165,9 @@ void avgcost_reset( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error void avgcost_clear( UDF_INIT* initid, char* is_null, char *error ); void avgcost_add( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error ); double avgcost( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error ); +my_bool is_const_init(UDF_INIT *initid, UDF_ARGS *args, char *message); +char *is_const(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long + *length, char *is_null, char *error); /************************************************************************* @@ -1075,4 +1078,32 @@ char *myfunc_argument_name(UDF_INIT *initid __attribute__((unused)), return result; } + + +my_bool is_const_init(UDF_INIT *initid, UDF_ARGS *args, char *message) +{ + if (args->arg_count != 1) + { + strmov(message, "IS_CONST accepts only one argument"); + return 1; + } + initid->ptr= (char*)((args->args[0] != NULL) ? 1 : 0); + return 0; +} + +char * is_const(UDF_INIT *initid, UDF_ARGS *args __attribute__((unused)), + char *result, unsigned long *length, + char *is_null, char *error __attribute__((unused))) +{ + if (initid->ptr != 0) { + sprintf(result, "const"); + } else { + sprintf(result, "not const"); + } + *is_null= 0; + *length= strlen(result); + return result; +} + + #endif /* HAVE_DLOPEN */ diff --git a/sql/udf_example.def b/sql/udf_example.def index d3081ca7768..ee107d58e51 100644 --- a/sql/udf_example.def +++ b/sql/udf_example.def @@ -22,3 +22,5 @@ EXPORTS avgcost_add avgcost_clear avgcost + is_const + is_const_init diff --git a/storage/myisam/mi_open.c b/storage/myisam/mi_open.c index 010f7233c32..bc705a3bf7a 100644 --- a/storage/myisam/mi_open.c +++ b/storage/myisam/mi_open.c @@ -1282,13 +1282,30 @@ int mi_enable_indexes(MI_INFO *info) RETURN 0 indexes are not disabled 1 all indexes are disabled - [2 non-unique indexes are disabled - NOT YET IMPLEMENTED] + 2 non-unique indexes are disabled */ int mi_indexes_are_disabled(MI_INFO *info) { MYISAM_SHARE *share= info->s; - return (! mi_is_any_key_active(share->state.key_map) && share->base.keys); + /* + No keys or all are enabled. keys is the number of keys. Left shifted + gives us only one bit set. When decreased by one, gives us all all bits + up to this one set and it gets unset. + */ + if (!share->base.keys || + (mi_is_all_keys_active(share->state.key_map, share->base.keys))) + return 0; + + /* All are disabled */ + if (mi_is_any_key_active(share->state.key_map)) + return 1; + + /* + We have keys. Some enabled, some disabled. + Don't check for any non-unique disabled but return directly 2 + */ + return 2; } diff --git a/storage/myisam/myisampack.c b/storage/myisam/myisampack.c index d16821d3cda..2753ed5f7b2 100644 --- a/storage/myisam/myisampack.c +++ b/storage/myisam/myisampack.c @@ -2923,6 +2923,8 @@ static void flush_bits(void) bits-= 8; *file_buffer.pos++= (uchar) (bit_buffer >> bits); } + if (file_buffer.pos >= file_buffer.end) + VOID(flush_buffer(~ (ulong) 0)); file_buffer.bits= BITS_SAVED; file_buffer.bitbucket= 0; } diff --git a/strings/strtod.c b/strings/strtod.c index ddb570718a0..932a34f921d 100644 --- a/strings/strtod.c +++ b/strings/strtod.c @@ -31,7 +31,6 @@ #define MAX_DBL_EXP 308 #define MAX_RESULT_FOR_MAX_EXP 1.7976931348623157 -#define MIN_RESULT_FOR_MIN_EXP 2.225073858507202 static double scaler10[] = { 1.0, 1e10, 1e20, 1e30, 1e40, 1e50, 1e60, 1e70, 1e80, 1e90 }; @@ -161,26 +160,15 @@ double my_strtod(const char *str, char **end_ptr, int *error) order= exp + (neg_exp ? -1 : 1) * (ndigits - 1); if (order < 0) order= -order; - if (order >= MAX_DBL_EXP && result) + if (order >= MAX_DBL_EXP && !neg_exp && result) { double c; /* Compute modulus of C (see comment above) */ c= result / scaler * 10.0; - if (neg_exp) + if (order > MAX_DBL_EXP || c > MAX_RESULT_FOR_MAX_EXP) { - if (order > MAX_DBL_EXP || c < MIN_RESULT_FOR_MIN_EXP) - { - result= 0.0; - goto done; - } - } - else - { - if (order > MAX_DBL_EXP || c > MAX_RESULT_FOR_MAX_EXP) - { - overflow= 1; - goto done; - } + overflow= 1; + goto done; } } diff --git a/support-files/mysql.server.sh b/support-files/mysql.server.sh index 459699988ab..b84ae85f524 100644 --- a/support-files/mysql.server.sh +++ b/support-files/mysql.server.sh @@ -82,7 +82,7 @@ datadir_set= # lsb_functions="/lib/lsb/init-functions" if test -f $lsb_functions ; then - source $lsb_functions + . $lsb_functions else log_success_msg() { diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 33e1cb4ae2d..c16282c6281 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -193,8 +193,6 @@ necessary to develop MySQL client applications. %package shared Summary: MySQL - Shared libraries Group: Applications/Databases -Provides: mysql-shared -Obsoletes: mysql-shared %description shared This package contains the shared libraries (*.so*) which certain @@ -689,17 +687,17 @@ fi # itself - note that they must be ordered by date (important when # merging BK trees) %changelog -* Thu Nov 30 2006 Joerg Bruehe <joerg@mysql.com> - -- Call "make install" using "benchdir_root=%{_datadir}", - because that is affecting the regression test suite as well. - * Thu Nov 16 2006 Joerg Bruehe <joerg@mysql.com> - Explicitly note that the "MySQL-shared" RPMs (as built by MySQL AB) replace "mysql-shared" (as distributed by SuSE) to allow easy upgrading (bug#22081). +* Thu Nov 30 2006 Joerg Bruehe <joerg@mysql.com> + +- Call "make install" using "benchdir_root=%{_datadir}", + because that is affecting the regression test suite as well. + * Mon Nov 13 2006 Joerg Bruehe <joerg@mysql.com> - Add "--with-partition" to all server builds. diff --git a/tests/Makefile.am b/tests/Makefile.am index e9bcb4693fd..43d90a9e03c 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -17,11 +17,6 @@ ## Process this file with automake to create Makefile.in -if HAVE_YASSL - yassl_dummy_link_fix= $(top_srcdir)/extra/yassl/src/dummy.cpp -else - yassl_dummy_link_fix= -endif if THREAD_SAFE_CLIENT LIBMYSQLCLIENT_LA = $(top_builddir)/libmysql_r/libmysqlclient_r.la @@ -42,9 +37,6 @@ EXTRA_DIST = auto_increment.res auto_increment.tst \ bin_PROGRAMS = mysql_client_test noinst_PROGRAMS = insert_test select_test thread_test -# -# C Test for 4.1 protocol -# INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \ $(openssl_includes) LIBS = @CLIENT_LIBS@ @@ -52,11 +44,11 @@ LDADD = @CLIENT_EXTRA_LDFLAGS@ \ $(LIBMYSQLCLIENT_LA) mysql_client_test_LDADD= $(LDADD) $(CXXLDFLAGS) -mysql_client_test_SOURCES= mysql_client_test.c $(yassl_dummy_link_fix) \ +mysql_client_test_SOURCES= mysql_client_test.c\ $(top_srcdir)/mysys/my_memmem.c -insert_test_SOURCES= insert_test.c $(yassl_dummy_link_fix) -select_test_SOURCES= select_test.c $(yassl_dummy_link_fix) +insert_test_SOURCES= insert_test.c +select_test_SOURCES= select_test.c insert_test_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) select_test_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) diff --git a/vio/Makefile.am b/vio/Makefile.am index b57f2453f41..107ad7870bb 100644 --- a/vio/Makefile.am +++ b/vio/Makefile.am @@ -1,43 +1,28 @@ # Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult 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 -if HAVE_YASSL - yassl_dummy_link_fix= $(top_srcdir)/extra/yassl/src/dummy.cpp -else - yassl_dummy_link_fix= -endif -INCLUDES= -I$(top_builddir)/include -I$(top_srcdir)/include \ +INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \ $(openssl_includes) -LDADD= @CLIENT_EXTRA_LDFLAGS@ $(openssl_libs) $(yassl_libs) -pkglib_LIBRARIES= libvio.a -noinst_PROGRAMS = test-ssl test-sslserver test-sslclient -noinst_HEADERS= vio_priv.h -test_ssl_SOURCES= test-ssl.c $(yassl_dummy_link_fix) -test_ssl_LDADD= @CLIENT_EXTRA_LDFLAGS@ ../dbug/libdbug.a libvio.a \ - ../mysys/libmysys.a ../strings/libmystrings.a \ - $(openssl_libs) $(yassl_libs) -test_sslserver_SOURCES= test-sslserver.c $(yassl_dummy_link_fix) -test_sslserver_LDADD= @CLIENT_EXTRA_LDFLAGS@ ../dbug/libdbug.a libvio.a \ - ../mysys/libmysys.a ../strings/libmystrings.a \ - $(openssl_libs) $(yassl_libs) -test_sslclient_SOURCES= test-sslclient.c $(yassl_dummy_link_fix) -test_sslclient_LDADD= @CLIENT_EXTRA_LDFLAGS@ ../dbug/libdbug.a libvio.a \ - ../mysys/libmysys.a ../strings/libmystrings.a \ - $(openssl_libs) $(yassl_libs) -libvio_a_SOURCES= vio.c viosocket.c viossl.c viosslfactories.c +LDADD = @CLIENT_EXTRA_LDFLAGS@ $(openssl_libs) $(yassl_libs) +pkglib_LIBRARIES = libvio.a + +noinst_HEADERS = vio_priv.h + +libvio_a_SOURCES = vio.c viosocket.c viossl.c viosslfactories.c + EXTRA_DIST= CMakeLists.txt # Don't update the files from bitkeeper