diff options
109 files changed, 1653 insertions, 422 deletions
diff --git a/Docs/changelog-4.0.xml b/Docs/changelog-4.0.xml deleted file mode 100755 index f0f9aa881f1..00000000000 --- a/Docs/changelog-4.0.xml +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE appendix PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" -"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"> -<!-- -This is a dummy changelog file. Don't use it yet. -It merges upward without conflict. ---> -<appendix id="news-4-0-x"> - - <title> - Changes in release 4.0.x - </title> - - <para> - This is a dummy changelog file. Don't use it yet. - </para> - -</appendix> diff --git a/Docs/changelog-4.1.xml b/Docs/changelog-4.1.xml deleted file mode 100755 index 644f2940d0f..00000000000 --- a/Docs/changelog-4.1.xml +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE appendix PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" -"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"> -<!-- -This is a dummy changelog file. Don't use it yet. -It merges upward without conflict. ---> -<appendix id="news-4-1-x"> - - <title> - Changes in release 4.1.x - </title> - - <para> - This is a dummy changelog file. Don't use it yet. - </para> - -</appendix> diff --git a/acinclude.m4 b/acinclude.m4 index 8a55c1fdb20..102f869e0d4 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -310,9 +310,11 @@ case $SYSTEM_TYPE in fi ;; *) - # Just to be safe, we test for ".so" anyway - if test \( -f "$mysql_zlib_dir/lib/libz.a" -o -f "$mysql_zlib_dir/lib/libz.so" -o \ - -f "$mysql_zlib_dir/lib/libz$shrext_cmds" \) \ + # Test for libz using all known library file endings + if test \( -f "$mysql_zlib_dir/lib/libz.a" -o \ + -f "$mysql_zlib_dir/lib/libz.so" -o \ + -f "$mysql_zlib_dir/lib/libz.sl" -o \ + -f "$mysql_zlib_dir/lib/libz.dylib" \) \ -a -f "$mysql_zlib_dir/include/zlib.h"; then ZLIB_INCLUDES="-I$mysql_zlib_dir/include" ZLIB_LIBS="-L$mysql_zlib_dir/lib -lz" @@ -980,8 +982,9 @@ AC_DEFUN([MYSQL_FIND_OPENSSL], [ for d in /usr/ssl/lib /usr/local/ssl/lib /usr/lib/openssl \ /usr/lib /usr/lib64 /opt/ssl/lib /opt/openssl/lib \ /usr/freeware/lib32 /usr/local/lib/ ; do - # Just to be safe, we test for ".so" anyway - if test -f $d/libssl.a || test -f $d/libssl.so || test -f $d/libssl$shrext_cmds ; then + # Test for libssl using all known library file endings + if test -f $d/libssl.a || test -f $d/libssl.so || \ + test -f $d/libssl.sl || test -f $d/libssl.dylib ; then OPENSSL_LIB=$d fi done @@ -993,8 +996,9 @@ AC_DEFUN([MYSQL_FIND_OPENSSL], [ if test -f $incs/openssl/ssl.h ; then OPENSSL_INCLUDE=-I$incs fi - # Just to be safe, we test for ".so" anyway - if test -f $libs/libssl.a || test -f $libs/libssl.so || test -f $libs/libssl$shrext_cmds ; then + # Test for libssl using all known library file endings + if test -f $libs/libssl.a || test -f $libs/libssl.so || \ + test -f $libs/libssl.sl || test -f $d/libssl.dylib ; then OPENSSL_LIB=$libs fi ;; diff --git a/client/mysqldump.c b/client/mysqldump.c index 64629bcf608..e8f96016153 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -2215,14 +2215,13 @@ static int dump_all_tables_in_db(char *database) different case (e.g. T1 vs t1) RETURN - int - 0 if a tablename was retrieved. 1 if not + pointer to the table name + 0 if error */ -static int get_actual_table_name(const char *old_table_name, - char *new_table_name, - int buf_size) +static char *get_actual_table_name(const char *old_table_name, MEM_ROOT *root) { - int retval; + char *name= 0; MYSQL_RES *tableRes; MYSQL_ROW row; char query[50 + 2*NAME_LEN]; @@ -2241,40 +2240,36 @@ static int get_actual_table_name(const char *old_table_name, } tableRes= mysql_store_result( sock ); - retval = 1; if (tableRes != NULL) { my_ulonglong numRows= mysql_num_rows(tableRes); if (numRows > 0) { row= mysql_fetch_row( tableRes ); - strmake(new_table_name, row[0], buf_size-1); - retval= 0; - DBUG_PRINT("info", ("new_table_name: %s", new_table_name)); + ulong *lengths= mysql_fetch_lengths(tableRes); + name= strmake_root(root, row[0], lengths[0]); } mysql_free_result(tableRes); } - DBUG_PRINT("exit", ("retval: %d", retval)); - DBUG_RETURN(retval); + DBUG_PRINT("exit", ("new_table_name: %s", name)); + DBUG_RETURN(name); } static int dump_selected_tables(char *db, char **table_names, int tables) { - uint numrows, i; + uint numrows; char table_buff[NAME_LEN*+3]; - char new_table_name[NAME_LEN]; DYNAMIC_STRING lock_tables_query; - HASH dump_tables; + MEM_ROOT root; + char **dump_tables, **pos; DBUG_ENTER("dump_selected_tables"); if (init_dumping(db)) return 1; - /* Init hash table for storing the actual name of tables to dump */ - if (hash_init(&dump_tables, charset_info, 16, 0, 0, - (hash_get_key) get_table_key, (hash_free_key) free_table_ent, - 0)) + init_alloc_root(&root, 8192, 0); + if (!(dump_tables= pos= (char**) alloc_root(&root, tables * sizeof(char *)))) exit(EX_EOM); init_dynamic_string(&lock_tables_query, "LOCK TABLES ", 256, 1024); @@ -2282,22 +2277,16 @@ static int dump_selected_tables(char *db, char **table_names, int tables) { /* the table name passed on commandline may be wrong case */ - if (!get_actual_table_name(*table_names, - new_table_name, sizeof(new_table_name) )) + if ((*pos= get_actual_table_name(*table_names, &root))) { /* Add found table name to lock_tables_query */ if (lock_tables) { dynstr_append(&lock_tables_query, - quote_name(new_table_name, table_buff, 1)); + quote_name(*pos, table_buff, 1)); dynstr_append(&lock_tables_query, " READ /*!32311 LOCAL */,"); } - - /* Add found table name to dump_tables list */ - if (my_hash_insert(&dump_tables, - (byte*)my_strdup(new_table_name, MYF(0)))) - exit(EX_EOM); - + pos++; } else { @@ -2326,15 +2315,14 @@ static int dump_selected_tables(char *db, char **table_names, int tables) print_xml_tag1(md_result_file, "", "database name=", db, "\n"); /* Dump each selected table */ - for (i= 0 ; i < dump_tables.records ; i++) + for (; dump_tables < pos; dump_tables++) { - const char *table_name= hash_element(&dump_tables, i); - DBUG_PRINT("info",("Dumping table %s", table_name)); - numrows= getTableStructure((char*) table_name, db); + DBUG_PRINT("info",("Dumping table %s", *dump_tables)); + numrows= getTableStructure(*dump_tables, db); if (!dFlag && numrows > 0) - dumpTable(numrows, (char*) table_name); + dumpTable(numrows, *dump_tables); } - hash_free(&dump_tables); + free_root(&root, MYF(0)); my_free(order_by, MYF(MY_ALLOW_ZERO_PTR)); order_by= 0; if (opt_xml) diff --git a/configure.in b/configure.in index a7ef6546425..2dfa2d0b420 100644 --- a/configure.in +++ b/configure.in @@ -5,7 +5,7 @@ AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! # remember to also change ndb version below and update version.c in ndb -AM_INIT_AUTOMAKE(mysql, 4.1.19) +AM_INIT_AUTOMAKE(mysql, 4.1.20) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 @@ -17,7 +17,7 @@ SHARED_LIB_VERSION=$SHARED_LIB_MAJOR_VERSION:0:0 # ndb version NDB_VERSION_MAJOR=4 NDB_VERSION_MINOR=1 -NDB_VERSION_BUILD=19 +NDB_VERSION_BUILD=20 NDB_VERSION_STATUS="" # Set all version vars based on $VERSION. How do we do this more elegant ? @@ -827,9 +827,8 @@ AC_CHECK_FUNC(yp_get_default_domain, , AC_CHECK_FUNC(p2open, , AC_CHECK_LIB(gen, p2open)) # This may get things to compile even if bind-8 is installed AC_CHECK_FUNC(bind, , AC_CHECK_LIB(bind, bind)) -# For crypt() on Linux -AC_CHECK_LIB(crypt, crypt) -AC_CHECK_FUNC(crypt, AC_DEFINE([HAVE_CRYPT], [1], [crypt])) +# Check if crypt() exists in libc or libcrypt, sets LIBS if needed +AC_SEARCH_LIBS(crypt, crypt, AC_DEFINE(HAVE_CRYPT, 1, [crypt])) # For sem_xxx functions on Solaris 2.6 AC_CHECK_FUNC(sem_init, , AC_CHECK_LIB(posix4, sem_init)) diff --git a/include/config-win.h b/include/config-win.h index 03f130ad37e..bb54a43b8bb 100644 --- a/include/config-win.h +++ b/include/config-win.h @@ -22,6 +22,11 @@ functions */ #define _WIN32_WINNT 0x0500 #endif +#if defined(_MSC_VER) && _MSC_VER >= 1400 +/* Avoid endless warnings about sprintf() etc. being unsafe. */ +#define _CRT_SECURE_NO_DEPRECATE 1 +#endif + #include <sys/locking.h> #include <windows.h> #include <math.h> /* Because of rint() */ @@ -195,7 +200,7 @@ typedef uint rf_SetTimer; #define my_sigset(A,B) signal((A),(B)) #define finite(A) _finite(A) #define sleep(A) Sleep((A)*1000) -#define popen(A) popen(A,B) _popen((A),(B)) +#define popen(A,B) _popen((A),(B)) #define pclose(A) _pclose(A) #ifndef __BORLANDC__ @@ -385,7 +390,7 @@ inline double ulonglong2double(ulonglong value) #else #define MYSQL_DEFAULT_CHARSET_NAME "latin1" #define MYSQL_DEFAULT_COLLATION_NAME "latin1_swedish_ci" -#enfif +#endif #define HAVE_SPATIAL 1 #define HAVE_RTREE_KEYS 1 diff --git a/include/my_pthread.h b/include/my_pthread.h index b6b65d4389a..8d03de49574 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -329,12 +329,14 @@ int sigwait(sigset_t *setp, int *sigp); /* Use our implemention */ we want to make sure that no such flags are set. */ #if defined(HAVE_SIGACTION) && !defined(my_sigset) -#define my_sigset(A,B) do { struct sigaction s; sigset_t set; \ +#define my_sigset(A,B) do { struct sigaction s; sigset_t set; int rc; \ + DBUG_ASSERT((A) != 0); \ sigemptyset(&set); \ s.sa_handler = (B); \ s.sa_mask = set; \ s.sa_flags = 0; \ - sigaction((A), &s, (struct sigaction *) NULL); \ + rc= sigaction((A), &s, (struct sigaction *) NULL);\ + DBUG_ASSERT(rc == 0); \ } while (0) #elif defined(HAVE_SIGSET) && !defined(my_sigset) #define my_sigset(A,B) sigset((A),(B)) diff --git a/innobase/include/dict0dict.ic b/innobase/include/dict0dict.ic index 85e4aaf1a05..4c1a88cfd1b 100644 --- a/innobase/include/dict0dict.ic +++ b/innobase/include/dict0dict.ic @@ -93,7 +93,6 @@ dict_table_get_n_user_cols( { ut_ad(table); ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); - ut_ad(table->cached); return(table->n_cols - DATA_N_SYS_COLS); } @@ -127,7 +126,6 @@ dict_table_get_n_cols( { ut_ad(table); ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); - ut_ad(table->cached); return(table->n_cols); } diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index 6ef6f7cd545..4c90c95c0bd 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -3614,6 +3614,37 @@ os_aio_posix_handle( #endif /************************************************************************** +Do a 'last millisecond' check that the page end is sensible; +reported page checksum errors from Linux seem to wipe over the page end. */ +static +void +os_file_check_page_trailers( +/*========================*/ + byte* combined_buf, /* in: combined write buffer */ + ulint total_len) /* in: size of combined_buf, in bytes + (a multiple of UNIV_PAGE_SIZE) */ +{ + ulint len; + + for (len = 0; len + UNIV_PAGE_SIZE <= total_len; + len += UNIV_PAGE_SIZE) { + byte* buf = combined_buf + len; + + if (memcmp(buf + (FIL_PAGE_LSN + 4), buf + (UNIV_PAGE_SIZE + - FIL_PAGE_END_LSN_OLD_CHKSUM + 4), 4)) { + ut_print_timestamp(stderr); + fprintf(stderr, +" InnoDB: ERROR: The page to be written seems corrupt!\n" +"InnoDB: Writing a block of %lu bytes, currently at offset %lu\n", + (ulong)total_len, (ulong)len); + buf_page_print(buf); + fprintf(stderr, +"InnoDB: ERROR: The page to be written seems corrupt!\n"); + } + } +} + +/************************************************************************** Does simulated aio. This function should be called by an i/o-handler thread. */ @@ -3650,7 +3681,6 @@ os_aio_simulated_handle( ibool ret; ulint n; ulint i; - ulint len2; segment = os_aio_get_array_and_local_segment(&array, global_segment); @@ -3857,33 +3887,16 @@ consecutive_loop: (ulong) total_len); ut_error; } - - /* Do a 'last millisecond' check that the page end - is sensible; reported page checksum errors from - Linux seem to wipe over the page end */ - - for (len2 = 0; len2 + UNIV_PAGE_SIZE <= total_len; - len2 += UNIV_PAGE_SIZE) { - if (mach_read_from_4(combined_buf + len2 - + FIL_PAGE_LSN + 4) - != mach_read_from_4(combined_buf + len2 - + UNIV_PAGE_SIZE - - FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) { - ut_print_timestamp(stderr); - fprintf(stderr, -" InnoDB: ERROR: The page to be written seems corrupt!\n"); - fprintf(stderr, -"InnoDB: Writing a block of %lu bytes, currently writing at offset %lu\n", - (ulong)total_len, (ulong)len2); - buf_page_print(combined_buf + len2); - fprintf(stderr, -"InnoDB: ERROR: The page to be written seems corrupt!\n"); - } - } + + os_file_check_page_trailers(combined_buf, total_len); } - + ret = os_file_write(slot->name, slot->file, combined_buf, slot->offset, slot->offset_high, total_len); + + if (array == os_aio_write_array) { + os_file_check_page_trailers(combined_buf, total_len); + } } else { ret = os_file_read(slot->file, combined_buf, slot->offset, slot->offset_high, total_len); diff --git a/myisam/mi_check.c b/myisam/mi_check.c index 15d1cceebfe..2395640d5bf 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -3790,6 +3790,7 @@ int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename) ha_rows max_records; ulonglong file_length,tmp_length; MI_CREATE_INFO create_info; + DBUG_ENTER("recreate_table"); error=1; /* Default error */ info= **org_info; @@ -3799,7 +3800,7 @@ int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename) unpack= (share.options & HA_OPTION_COMPRESS_RECORD) && (param->testflag & T_UNPACK); if (!(keyinfo=(MI_KEYDEF*) my_alloca(sizeof(MI_KEYDEF)*share.base.keys))) - return 0; + DBUG_RETURN(0); memcpy((byte*) keyinfo,(byte*) share.keyinfo, (size_t) (sizeof(MI_KEYDEF)*share.base.keys)); @@ -3808,14 +3809,14 @@ int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename) (key_parts+share.base.keys)))) { my_afree((gptr) keyinfo); - return 1; + DBUG_RETURN(1); } if (!(recdef=(MI_COLUMNDEF*) my_alloca(sizeof(MI_COLUMNDEF)*(share.base.fields+1)))) { my_afree((gptr) keyinfo); my_afree((gptr) keysegs); - return 1; + DBUG_RETURN(1); } if (!(uniquedef=(MI_UNIQUEDEF*) my_alloca(sizeof(MI_UNIQUEDEF)*(share.state.header.uniques+1)))) @@ -3823,7 +3824,7 @@ int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename) my_afree((gptr) recdef); my_afree((gptr) keyinfo); my_afree((gptr) keysegs); - return 1; + DBUG_RETURN(1); } /* Copy the column definitions */ @@ -3896,6 +3897,11 @@ int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename) create_info.language = (param->language ? param->language : share.state.header.language); create_info.key_file_length= status_info.key_file_length; + /* + Allow for creating an auto_increment key. This has an effect only if + an auto_increment key exists in the original table. + */ + create_info.with_auto_increment= TRUE; /* We don't have to handle symlinks here because we are using HA_DONT_TOUCH_DATA */ if (mi_create(filename, @@ -3940,7 +3946,7 @@ end: my_afree((gptr) keyinfo); my_afree((gptr) recdef); my_afree((gptr) keysegs); - return error; + DBUG_RETURN(error); } @@ -4043,6 +4049,8 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info, my_bool repair_only) { byte *record; + DBUG_ENTER("update_auto_increment_key"); + if (!info->s->base.auto_key || !(((ulonglong) 1 << (info->s->base.auto_key-1) & info->s->state.key_map))) @@ -4051,7 +4059,7 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info, mi_check_print_info(param, "Table: %s doesn't have an auto increment key\n", param->isam_file_name); - return; + DBUG_VOID_RETURN; } if (!(param->testflag & T_SILENT) && !(param->testflag & T_REP)) @@ -4064,7 +4072,7 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info, MYF(0)))) { mi_check_print_error(param,"Not enough memory for extra record"); - return; + DBUG_VOID_RETURN; } mi_extra(info,HA_EXTRA_KEYREAD,0); @@ -4075,7 +4083,7 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info, mi_extra(info,HA_EXTRA_NO_KEYREAD,0); my_free((char*) record, MYF(0)); mi_check_print_error(param,"%d when reading last record",my_errno); - return; + DBUG_VOID_RETURN; } if (!repair_only) info->s->state.auto_increment=param->auto_increment_value; @@ -4091,7 +4099,7 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info, mi_extra(info,HA_EXTRA_NO_KEYREAD,0); my_free((char*) record, MYF(0)); update_state_info(param, info, UPDATE_AUTO_INC); - return; + DBUG_VOID_RETURN; } diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 121102ec262..4e0020b79a2 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -678,6 +678,7 @@ sub command_line_setup () { $glob_use_embedded_server= 1; push(@glob_test_mode, "embedded"); $opt_skip_rpl= 1; # We never run replication with embedded + $opt_skip_ndbcluster= 1; if ( $opt_extern ) { diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index c8d54d7e86c..e74a5ac82d0 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -279,6 +279,7 @@ while test $# -gt 0; do USE_EMBEDDED_SERVER=1 USE_MANAGER=0 NO_SLAVE=1 USE_RUNNING_SERVER="" + USE_NDBCLUSTER="" TEST_MODE="$TEST_MODE embedded" ;; --purify) USE_PURIFY=1 diff --git a/mysql-test/r/analyze.result b/mysql-test/r/analyze.result index 796b382f5d6..bded22c4859 100644 --- a/mysql-test/r/analyze.result +++ b/mysql-test/r/analyze.result @@ -37,3 +37,12 @@ Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_ execute stmt1; Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype deallocate prepare stmt1; +create temporary table t1(a int, index(a)); +insert into t1 values('1'),('2'),('3'),('4'),('5'); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +show index from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 1 a 1 a A 5 NULL NULL YES BTREE +drop table t1; diff --git a/mysql-test/r/ansi.result b/mysql-test/r/ansi.result index 212d28f918b..4eda9654efc 100644 --- a/mysql-test/r/ansi.result +++ b/mysql-test/r/ansi.result @@ -2,7 +2,7 @@ drop table if exists t1; set sql_mode="MySQL40"; select @@sql_mode; @@sql_mode -NO_FIELD_OPTIONS,MYSQL40 +MYSQL40 set @@sql_mode="ANSI"; select @@sql_mode; @@sql_mode @@ -17,3 +17,32 @@ SELECT id FROM t1 GROUP BY id2; id drop table t1; SET @@SQL_MODE=""; +CREATE TABLE t1 (i int auto_increment NOT NULL, PRIMARY KEY (i)); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) NOT NULL auto_increment, + PRIMARY KEY (`i`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SET @@SQL_MODE="MYSQL323"; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) NOT NULL auto_increment, + PRIMARY KEY (`i`) +) TYPE=MyISAM +SET @@SQL_MODE="MYSQL40"; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) NOT NULL auto_increment, + PRIMARY KEY (`i`) +) TYPE=MyISAM +SET @@SQL_MODE="NO_FIELD_OPTIONS"; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) NOT NULL, + PRIMARY KEY (`i`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; diff --git a/mysql-test/r/auto_increment.result b/mysql-test/r/auto_increment.result index 9f3695cb1b1..426f20212c3 100644 --- a/mysql-test/r/auto_increment.result +++ b/mysql-test/r/auto_increment.result @@ -355,3 +355,27 @@ CHECK TABLE t1; Table Op Msg_type Msg_text test.t1 check status OK DROP TABLE IF EXISTS t1; +CREATE TABLE `t1` ( +t1_name VARCHAR(255) DEFAULT NULL, +t1_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, +KEY (t1_name), +PRIMARY KEY (t1_id) +) AUTO_INCREMENT = 1000; +INSERT INTO t1 (t1_name) VALUES('MySQL'); +INSERT INTO t1 (t1_name) VALUES('MySQL'); +INSERT INTO t1 (t1_name) VALUES('MySQL'); +SELECT * from t1; +t1_name t1_id +MySQL 1000 +MySQL 1001 +MySQL 1002 +SHOW CREATE TABLE `t1`; +Table Create Table +t1 CREATE TABLE `t1` ( + `t1_name` varchar(255) default NULL, + `t1_id` int(10) unsigned NOT NULL auto_increment, + PRIMARY KEY (`t1_id`), + KEY `t1_name` (`t1_name`) +) ENGINE=MyISAM AUTO_INCREMENT=1003 DEFAULT CHARSET=latin1 +DROP TABLE `t1`; +End of 4.1 tests diff --git a/mysql-test/r/date_formats.result b/mysql-test/r/date_formats.result index 014eeed27e7..24abdfcf148 100644 --- a/mysql-test/r/date_formats.result +++ b/mysql-test/r/date_formats.result @@ -473,3 +473,39 @@ NULL select str_to_date( 1, IF(1=1,NULL,NULL) ); str_to_date( 1, IF(1=1,NULL,NULL) ) NULL +SELECT TIME_FORMAT("24:00:00", '%r'); +TIME_FORMAT("24:00:00", '%r') +12:00:00 AM +SELECT TIME_FORMAT("00:00:00", '%r'); +TIME_FORMAT("00:00:00", '%r') +12:00:00 AM +SELECT TIME_FORMAT("12:00:00", '%r'); +TIME_FORMAT("12:00:00", '%r') +12:00:00 PM +SELECT TIME_FORMAT("15:00:00", '%r'); +TIME_FORMAT("15:00:00", '%r') +03:00:00 PM +SELECT TIME_FORMAT("01:00:00", '%r'); +TIME_FORMAT("01:00:00", '%r') +01:00:00 AM +SELECT TIME_FORMAT("25:00:00", '%r'); +TIME_FORMAT("25:00:00", '%r') +01:00:00 AM +SELECT TIME_FORMAT("00:00:00", '%l %p'); +TIME_FORMAT("00:00:00", '%l %p') +12 AM +SELECT TIME_FORMAT("01:00:00", '%l %p'); +TIME_FORMAT("01:00:00", '%l %p') +1 AM +SELECT TIME_FORMAT("12:00:00", '%l %p'); +TIME_FORMAT("12:00:00", '%l %p') +12 PM +SELECT TIME_FORMAT("23:00:00", '%l %p'); +TIME_FORMAT("23:00:00", '%l %p') +11 PM +SELECT TIME_FORMAT("24:00:00", '%l %p'); +TIME_FORMAT("24:00:00", '%l %p') +12 AM +SELECT TIME_FORMAT("25:00:00", '%l %p'); +TIME_FORMAT("25:00:00", '%l %p') +1 AM diff --git a/mysql-test/r/drop_temp_table.result b/mysql-test/r/drop_temp_table.result index 5f1f142cde5..40afd621676 100644 --- a/mysql-test/r/drop_temp_table.result +++ b/mysql-test/r/drop_temp_table.result @@ -17,6 +17,7 @@ master-bin.000001 # Query 1 # create database `drop-temp+table-test` master-bin.000001 # Query 1 # use `drop-temp+table-test`; create temporary table shortn1 (a int) master-bin.000001 # Query 1 # use `drop-temp+table-test`; create temporary table `table:name` (a int) master-bin.000001 # Query 1 # use `drop-temp+table-test`; create temporary table shortn2 (a int) +master-bin.000001 # Query 1 # use `drop-temp+table-test`; SET ONE_SHOT CHARACTER_SET_CLIENT=33,COLLATION_CONNECTION=8,COLLATION_DATABASE=8,COLLATION_SERVER=8 master-bin.000001 # Query 1 # use `drop-temp+table-test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `drop-temp+table-test`.`shortn2`,`drop-temp+table-test`.`table:name`,`drop-temp+table-test`.`shortn1` master-bin.000001 # Query 1 # use `drop-temp+table-test`; DO RELEASE_LOCK("a") drop database `drop-temp+table-test`; diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result index 181ecf7b65b..8bcdd8b7cbc 100644 --- a/mysql-test/r/func_misc.result +++ b/mysql-test/r/func_misc.result @@ -57,3 +57,39 @@ t1 CREATE TABLE `t1` ( `length(uuid())` int(10) NOT NULL default '0' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (conn CHAR(7), connection_id INT); +INSERT INTO t1 VALUES ('default', CONNECTION_ID()); +SELECT GET_LOCK('bug16501',600); +GET_LOCK('bug16501',600) +1 +INSERT INTO t1 VALUES ('con1', CONNECTION_ID()); +SELECT IS_USED_LOCK('bug16501') = connection_id +FROM t1 +WHERE conn = 'default'; +IS_USED_LOCK('bug16501') = connection_id +1 + SELECT GET_LOCK('bug16501',600); +SELECT IS_USED_LOCK('bug16501') = CONNECTION_ID(); +IS_USED_LOCK('bug16501') = CONNECTION_ID() +1 +SELECT RELEASE_LOCK('bug16501'); +RELEASE_LOCK('bug16501') +1 +GET_LOCK('bug16501',600) +1 +SELECT IS_USED_LOCK('bug16501') = connection_id +FROM t1 +WHERE conn = 'con1'; +IS_USED_LOCK('bug16501') = connection_id +1 +SELECT IS_USED_LOCK('bug16501') = CONNECTION_ID(); +IS_USED_LOCK('bug16501') = CONNECTION_ID() +1 +SELECT RELEASE_LOCK('bug16501'); +RELEASE_LOCK('bug16501') +1 +SELECT IS_USED_LOCK('bug16501'); +IS_USED_LOCK('bug16501') +NULL +DROP TABLE t1; diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index ae6578795f6..0609624af18 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -1000,3 +1000,10 @@ t 1000000 1 drop table t1; +select load_file("lkjlkj"); +load_file("lkjlkj") +NULL +select ifnull(load_file("lkjlkj"),"it's null"); +ifnull(load_file("lkjlkj"),"it's null") +it's null +End of 4.1 tests diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index fc872285acb..02f3d2f7273 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -626,3 +626,7 @@ last_day('2005-01-00') NULL Warnings: Warning 1292 Truncated incorrect datetime value: '2005-01-00' +select monthname(str_to_date(null, '%m')), monthname(str_to_date(null, '%m')), +monthname(str_to_date(1, '%m')), monthname(str_to_date(0, '%m')); +monthname(str_to_date(null, '%m')) monthname(str_to_date(null, '%m')) monthname(str_to_date(1, '%m')) monthname(str_to_date(0, '%m')) +NULL NULL January NULL diff --git a/mysql-test/r/gis-rtree.result b/mysql-test/r/gis-rtree.result index 5283ef4d889..f479fc41ffb 100644 --- a/mysql-test/r/gis-rtree.result +++ b/mysql-test/r/gis-rtree.result @@ -294,7 +294,7 @@ t2 CREATE TABLE `t2` ( `g` geometry NOT NULL default '', PRIMARY KEY (`fid`), SPATIAL KEY `g` (`g`(32)) -) ENGINE=MyISAM DEFAULT CHARSET=latin1 +) ENGINE=MyISAM AUTO_INCREMENT=101 DEFAULT CHARSET=latin1 SELECT count(*) FROM t2; count(*) 100 diff --git a/mysql-test/r/having.result b/mysql-test/r/having.result index 9730f9f81bf..ccd1f0e61e7 100644 --- a/mysql-test/r/having.result +++ b/mysql-test/r/having.result @@ -141,3 +141,20 @@ SUM(a) 6 4 DROP TABLE t1; +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (1), (2), (1), (3), (2), (1); +SELECT a FROM t1 GROUP BY a HAVING a > 1; +a +2 +3 +SELECT a FROM t1 GROUP BY a HAVING 1 != 1 AND a > 1; +a +SELECT 0 AS x, a FROM t1 GROUP BY x,a HAVING x=1 AND a > 1; +x a +EXPLAIN SELECT a FROM t1 GROUP BY a HAVING 1 != 1 AND a > 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible HAVING +EXPLAIN SELECT 0 AS x, a FROM t1 GROUP BY x,a HAVING x=1 AND a > 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible HAVING +DROP table t1; diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index 878c5cb5451..2a4e3555e3b 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -1 +1,56 @@ -drop table if exists t1; +drop table if exists t1,t2; +create table t1 ( +c_id int(11) not null default '0', +org_id int(11) default null, +unique key contacts$c_id (c_id), +key contacts$org_id (org_id) +) engine=innodb; +insert into t1 values +(2,null),(120,null),(141,null),(218,7), (128,1), +(151,2),(234,2),(236,2),(243,2),(255,2),(259,2),(232,3),(235,3),(238,3), +(246,3),(253,3),(269,3),(285,3),(291,3),(293,3),(131,4),(230,4),(231,4); +create table t2 ( +slai_id int(11) not null default '0', +owner_tbl int(11) default null, +owner_id int(11) default null, +sla_id int(11) default null, +inc_web int(11) default null, +inc_email int(11) default null, +inc_chat int(11) default null, +inc_csr int(11) default null, +inc_total int(11) default null, +time_billed int(11) default null, +activedate timestamp null default null, +expiredate timestamp null default null, +state int(11) default null, +sla_set int(11) default null, +unique key t2$slai_id (slai_id), +key t2$owner_id (owner_id), +key t2$sla_id (sla_id) +) engine=innodb; +insert into t2(slai_id, owner_tbl, owner_id, sla_id) values +(1,3,1,1), (3,3,10,2), (4,3,3,6), (5,3,2,5), (6,3,8,3), (7,3,9,7), +(8,3,6,8), (9,3,4,9), (10,3,5,10), (11,3,11,11), (12,3,7,12); +flush tables; +select si.slai_id +from t1 c join t2 si on +((si.owner_tbl = 3 and si.owner_id = c.org_id) or +( si.owner_tbl = 2 and si.owner_id = c.c_id)) +where +c.c_id = 218 and expiredate is null; +slai_id +12 +select * from t1 where org_id is null; +c_id org_id +2 NULL +120 NULL +141 NULL +select si.slai_id +from t1 c join t2 si on +((si.owner_tbl = 3 and si.owner_id = c.org_id) or +( si.owner_tbl = 2 and si.owner_id = c.c_id)) +where +c.c_id = 218 and expiredate is null; +slai_id +12 +drop table t1, t2; diff --git a/mysql-test/r/mix_innodb_myisam_binlog.result b/mysql-test/r/mix_innodb_myisam_binlog.result index e9613bac833..8cf99e8d623 100644 --- a/mysql-test/r/mix_innodb_myisam_binlog.result +++ b/mysql-test/r/mix_innodb_myisam_binlog.result @@ -249,7 +249,8 @@ master-bin.000001 1056 Query 1 1056 use `test`; insert t0 select * from t1 master-bin.000001 1117 Query 1 1117 use `test`; DO RELEASE_LOCK("a") master-bin.000001 1172 Query 1 1172 use `test`; insert into t0 select GET_LOCK("lock1",null) master-bin.000001 1251 Query 1 1251 use `test`; create table t2 (n int) engine=innodb -master-bin.000001 1323 Query 1 1323 use `test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `test`.`t1`,`test`.`ti` -master-bin.000001 1424 Query 1 1424 use `test`; DO RELEASE_LOCK("lock1") +master-bin.000001 1323 Query 1 1323 use `test`; SET ONE_SHOT CHARACTER_SET_CLIENT=33,COLLATION_CONNECTION=8,COLLATION_DATABASE=8,COLLATION_SERVER=8 +master-bin.000001 1457 Query 1 1457 use `test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `test`.`t1`,`test`.`ti` +master-bin.000001 1558 Query 1 1558 use `test`; DO RELEASE_LOCK("lock1") do release_lock("lock1"); drop table t0,t2; diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result index dba10296063..ee62bd3bce6 100644 --- a/mysql-test/r/multi_update.result +++ b/mysql-test/r/multi_update.result @@ -475,3 +475,8 @@ aclid bigint, index idx_acl(aclid) insert into t2 values(1,null); delete t2, t1 from t2 left join t1 on (t2.aclid=t1.aclid) where t2.refid='1'; drop table t1, t2; +create table t1(a int); +create table t2(a int); +delete from t1,t2 using t1,t2 where t1.a=(select a from t1); +ERROR HY000: You can't specify target table 't1' for update in FROM clause +drop table t1, t2; diff --git a/mysql-test/r/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result index adaf0dad56b..bade0ca9b46 100644 --- a/mysql-test/r/mysqlbinlog.result +++ b/mysql-test/r/mysqlbinlog.result @@ -101,4 +101,9 @@ HEX(f) select HEX(f) from t4; HEX(f) 835C -drop table t1, t2, t03, t04, t3, t4; +flush logs; +select * from t5 /* must be (1),(1) */; +a +1 +1 +drop table t1, t2, t03, t04, t3, t4, t5; diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index fb72abe9b45..ca2643b081a 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -1,4 +1,4 @@ -DROP TABLE IF EXISTS t1, `"t"1`; +DROP TABLE IF EXISTS t1, `"t"1`, t2, t3; CREATE TABLE t1(a int); INSERT INTO t1 VALUES (1), (2); <?xml version="1.0"?> @@ -1503,3 +1503,75 @@ select * from t1; a b Osnabrück Köln drop table t1; +create table `t1` ( +t1_name varchar(255) default null, +t1_id int(10) unsigned not null auto_increment, +key (t1_name), +primary key (t1_id) +) auto_increment = 1000 default charset=latin1; +insert into t1 (t1_name) values('bla'); +insert into t1 (t1_name) values('bla'); +insert into t1 (t1_name) values('bla'); +select * from t1; +t1_name t1_id +bla 1000 +bla 1001 +bla 1002 +show create table `t1`; +Table Create Table +t1 CREATE TABLE `t1` ( + `t1_name` varchar(255) default NULL, + `t1_id` int(10) unsigned NOT NULL auto_increment, + PRIMARY KEY (`t1_id`), + KEY `t1_name` (`t1_name`) +) ENGINE=MyISAM AUTO_INCREMENT=1003 DEFAULT CHARSET=latin1 +DROP TABLE `t1`; +select * from t1; +t1_name t1_id +bla 1000 +bla 1001 +bla 1002 +show create table `t1`; +Table Create Table +t1 CREATE TABLE `t1` ( + `t1_name` varchar(255) default NULL, + `t1_id` int(10) unsigned NOT NULL auto_increment, + PRIMARY KEY (`t1_id`), + KEY `t1_name` (`t1_name`) +) ENGINE=MyISAM AUTO_INCREMENT=1003 DEFAULT CHARSET=latin1 +drop table `t1`; +create table t1(a int); +create table t2(a int); +create table t3(a int); + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; +DROP TABLE IF EXISTS `t3`; +CREATE TABLE `t3` ( + `a` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +DROP TABLE IF EXISTS `t1`; +CREATE TABLE `t1` ( + `a` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +DROP TABLE IF EXISTS `t2`; +CREATE TABLE `t2` ( + `a` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +drop table t1, t2, t3; +End of 4.1 tests diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index 990f04e5ba9..091a3c0547d 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -1,6 +1,6 @@ -select -1 as "before_use_test" ; +select 0 as "before_use_test" ; before_use_test --1 +0 select otto from (select 1 as otto) as t1; otto 1 diff --git a/mysql-test/r/ndb_autodiscover3.result b/mysql-test/r/ndb_autodiscover3.result new file mode 100644 index 00000000000..8bc1b968436 --- /dev/null +++ b/mysql-test/r/ndb_autodiscover3.result @@ -0,0 +1,45 @@ +drop table if exists t1, t2; +create table t1 (a int key) engine=ndbcluster; +begin; +insert into t1 values (1); +insert into t1 values (2); +ERROR HY000: Got temporary error 4025 'Node failure caused abort of transaction' from ndbcluster +commit; +ERROR HY000: Got error 4350 'Transaction already aborted' from ndbcluster +drop table t1; +create table t2 (a int, b int, primary key(a,b)) engine=ndbcluster; +insert into t2 values (1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1),(9,1),(10,1); +select * from t2 order by a limit 3; +a b +1 1 +2 1 +3 1 +create table t2 (a int key) engine=ndbcluster; +insert into t2 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); +select * from t2 order by a limit 3; +a +1 +2 +3 +select * from t2 order by a limit 3; +ERROR HY000: Can't lock file (errno: 241) +select * from t2 order by a limit 3; +a +1 +2 +3 +show tables; +Tables_in_test +create table t2 (a int key) engine=ndbcluster; +insert into t2 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); +select * from t2 order by a limit 3; +a +1 +2 +3 +select * from t2 order by a limit 3; +a +1 +2 +3 +drop table t2; diff --git a/mysql-test/r/ndb_blob.result b/mysql-test/r/ndb_blob.result index bcf867a4edd..e3289961fb8 100644 --- a/mysql-test/r/ndb_blob.result +++ b/mysql-test/r/ndb_blob.result @@ -481,14 +481,22 @@ msg text NOT NULL insert into t1 (msg) values( 'Tries to validate (8 byte length + inline bytes) as UTF8 :( Fast fix: removed validation for Text. It is not yet indexable -so bad data will not crash kernel. -Proper fix: Set inline bytes to multiple of mbmaxlen and -validate it (after the 8 byte length).'); +so bad data will not crash kernel.'); select * from t1; id msg 1 Tries to validate (8 byte length + inline bytes) as UTF8 :( Fast fix: removed validation for Text. It is not yet indexable so bad data will not crash kernel. -Proper fix: Set inline bytes to multiple of mbmaxlen and -validate it (after the 8 byte length). +drop table t1; +create table t1 ( +a int primary key not null auto_increment, +b text +) engine=ndbcluster; +select count(*) from t1; +count(*) +500 +truncate t1; +select count(*) from t1; +count(*) +0 drop table t1; diff --git a/mysql-test/r/null.result b/mysql-test/r/null.result index 3e233eb512a..4d90aac0e68 100644 --- a/mysql-test/r/null.result +++ b/mysql-test/r/null.result @@ -269,3 +269,45 @@ field('str1', null, 'STR1') as c05, c01 c02 c03 c04 c05 c08 c09 str str 0 1 2 1 1 set names latin1; +create table bug19145a (e enum('a','b','c') default 'b' , s set('x', 'y', 'z') default 'y' ) engine=MyISAM; +create table bug19145b (e enum('a','b','c') default null, s set('x', 'y', 'z') default null) engine=MyISAM; +create table bug19145c (e enum('a','b','c') not null default 'b' , s set('x', 'y', 'z') not null default 'y' ) engine=MyISAM; +create table bug19145setnotnulldefaultnull (e enum('a','b','c') default null, s set('x', 'y', 'z') not null default null) engine=MyISAM; +ERROR 42000: Invalid default value for 's' +create table bug19145enumnotnulldefaultnull (e enum('a','b','c') not null default null, s set('x', 'y', 'z') default null) engine=MyISAM; +ERROR 42000: Invalid default value for 'e' +alter table bug19145a alter column e set default null; +alter table bug19145a alter column s set default null; +alter table bug19145a add column (i int); +alter table bug19145b alter column e set default null; +alter table bug19145b alter column s set default null; +alter table bug19145b add column (i int); +alter table bug19145c alter column e set default null; +ERROR 42000: Invalid default value for 'e' +alter table bug19145c alter column s set default null; +ERROR 42000: Invalid default value for 's' +alter table bug19145c add column (i int); +show create table bug19145a; +Table Create Table +bug19145a CREATE TABLE `bug19145a` ( + `e` enum('a','b','c') default NULL, + `s` set('x','y','z') default NULL, + `i` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +show create table bug19145b; +Table Create Table +bug19145b CREATE TABLE `bug19145b` ( + `e` enum('a','b','c') default NULL, + `s` set('x','y','z') default NULL, + `i` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +show create table bug19145c; +Table Create Table +bug19145c CREATE TABLE `bug19145c` ( + `e` enum('a','b','c') NOT NULL default 'b', + `s` set('x','y','z') NOT NULL default 'y', + `i` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table bug19145a; +drop table bug19145b; +drop table bug19145c; diff --git a/mysql-test/r/outfile.result b/mysql-test/r/outfile.result Binary files differindex 5eb24a78ef0..bcafae831d5 100644 --- a/mysql-test/r/outfile.result +++ b/mysql-test/r/outfile.result diff --git a/mysql-test/r/ps_11bugs.result b/mysql-test/r/ps_11bugs.result index c0d7fe502af..c849c25d646 100644 --- a/mysql-test/r/ps_11bugs.result +++ b/mysql-test/r/ps_11bugs.result @@ -116,3 +116,17 @@ execute st_1676 using @arg0, @arg1, @arg2; cola colb cold aaaa yyyy R drop table t1, t2; +create table t1 (a int primary key); +insert into t1 values (1); +explain select * from t1 where 3 in (select (1+1) union select 1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used +3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL +select * from t1 where 3 in (select (1+1) union select 1); +a +prepare st_18492 from 'select * from t1 where 3 in (select (1+1) union select 1)'; +execute st_18492; +a +drop table t1; diff --git a/mysql-test/r/rpl_temporary.result b/mysql-test/r/rpl_temporary.result index cd67d2592a8..943da0ccb76 100644 --- a/mysql-test/r/rpl_temporary.result +++ b/mysql-test/r/rpl_temporary.result @@ -89,17 +89,24 @@ f 7 drop table t1,t2; create temporary table t3 (f int); -set @session.pseudo_thread_id=100; +set @@session.pseudo_thread_id=100; create temporary table t101 (id int); create temporary table t102 (id int); -set @session.pseudo_thread_id=200; +set @@session.pseudo_thread_id=200; create temporary table t201 (id int); -create temporary table `#not_user_table_prefixed_with_hash_sign_no_harm` (id int); -set @con1_id=connection_id(); -kill @con1_id; +create temporary table `t``201` (id int); +create temporary table `#sql_not_user_table202` (id int); +set @@session.pseudo_thread_id=300; +create temporary table t301 (id int); +create temporary table t302 (id int); +create temporary table `#sql_not_user_table303` (id int); create table t1(f int); insert into t1 values (1); select * from t1 /* must be 1 */; f 1 drop table t1; +select * from t1; +a +1 +drop table t1; diff --git a/mysql-test/r/rpl_user_variables.result b/mysql-test/r/rpl_user_variables.result index 85768270ba3..8af2c3e0b22 100644 --- a/mysql-test/r/rpl_user_variables.result +++ b/mysql-test/r/rpl_user_variables.result @@ -105,5 +105,6 @@ slave-bin.000001 1370 User var 2 1370 @`a`=5 slave-bin.000001 1412 Query 1 1412 use `test`; insert into t1 values (@a),(@a) slave-bin.000001 1478 User var 2 1478 @`a`=NULL slave-bin.000001 1503 Query 1 1503 use `test`; insert into t1 values (@a),(@a),(@a*5) +insert into t1 select * FROM (select @var1 union select @var2) AS t2; drop table t1; stop slave; diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 500aa4b1728..7925715a8b7 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -734,7 +734,7 @@ id select_type table type possible_keys key key_len ref rows Extra 3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL No tables used NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL Warnings: -Note 1003 select test.t2.id AS `id` from test.t2 where <in_optimizer>(test.t2.id,<exists>(select 1 AS `Not_used` having (<cache>(test.t2.id) = <null_helper>(1)) union select 1 AS `Not_used` having (<cache>(test.t2.id) = <null_helper>(3)))) +Note 1003 select test.t2.id AS `id` from test.t2 where <in_optimizer>(test.t2.id,<exists>(select 1 AS `1` having (<cache>(test.t2.id) = <ref_null_helper>(1)) union select 3 AS `3` having (<cache>(test.t2.id) = <ref_null_helper>(3)))) SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 3); id SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 2); diff --git a/mysql-test/r/symlink.result b/mysql-test/r/symlink.result index 26612ec81fd..caff53f8fd7 100644 --- a/mysql-test/r/symlink.result +++ b/mysql-test/r/symlink.result @@ -40,7 +40,7 @@ t9 CREATE TABLE `t9` ( `b` char(16) NOT NULL default '', `c` int(11) NOT NULL default '0', PRIMARY KEY (`a`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1 DATA DIRECTORY='TEST_DIR/var/tmp/' INDEX DIRECTORY='TEST_DIR/var/run/' +) ENGINE=MyISAM AUTO_INCREMENT=16725 DEFAULT CHARSET=latin1 DATA DIRECTORY='TEST_DIR/var/tmp/' INDEX DIRECTORY='TEST_DIR/var/run/' alter table t9 rename t8, add column d int not null; alter table t8 rename t7; rename table t7 to t9; @@ -62,7 +62,7 @@ t9 CREATE TABLE `t9` ( `c` int(11) NOT NULL default '0', `d` int(11) NOT NULL default '0', PRIMARY KEY (`a`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1 DATA DIRECTORY='TEST_DIR/var/tmp/' INDEX DIRECTORY='TEST_DIR/var/run/' +) ENGINE=MyISAM AUTO_INCREMENT=16725 DEFAULT CHARSET=latin1 DATA DIRECTORY='TEST_DIR/var/tmp/' INDEX DIRECTORY='TEST_DIR/var/run/' drop database mysqltest; create table t1 (a int not null) engine=myisam; show create table t1; diff --git a/mysql-test/t/analyze.test b/mysql-test/t/analyze.test index 5d653b65579..a4694c32d3c 100644 --- a/mysql-test/t/analyze.test +++ b/mysql-test/t/analyze.test @@ -48,4 +48,13 @@ execute stmt1; execute stmt1; deallocate prepare stmt1; +# +# bug#15225 (ANALYZE temporary has no effect) +# +create temporary table t1(a int, index(a)); +insert into t1 values('1'),('2'),('3'),('4'),('5'); +analyze table t1; +show index from t1; +drop table t1; + # End of 4.1 tests diff --git a/mysql-test/t/ansi.test b/mysql-test/t/ansi.test index 444bf982b8a..fa7f999954e 100644 --- a/mysql-test/t/ansi.test +++ b/mysql-test/t/ansi.test @@ -26,4 +26,16 @@ drop table t1; SET @@SQL_MODE=""; +# Bug#14515 + +CREATE TABLE t1 (i int auto_increment NOT NULL, PRIMARY KEY (i)); +SHOW CREATE TABLE t1; +SET @@SQL_MODE="MYSQL323"; +SHOW CREATE TABLE t1; +SET @@SQL_MODE="MYSQL40"; +SHOW CREATE TABLE t1; +SET @@SQL_MODE="NO_FIELD_OPTIONS"; +SHOW CREATE TABLE t1; +DROP TABLE t1; + # End of 4.1 tests diff --git a/mysql-test/t/auto_increment.test b/mysql-test/t/auto_increment.test index b6a0aeb9a19..eed2ea44d05 100644 --- a/mysql-test/t/auto_increment.test +++ b/mysql-test/t/auto_increment.test @@ -219,4 +219,23 @@ INSERT INTO t1 (b) VALUES ('bbbb'); CHECK TABLE t1; DROP TABLE IF EXISTS t1; -# End of 4.1 tests +# BUG #19025: + +CREATE TABLE `t1` ( + t1_name VARCHAR(255) DEFAULT NULL, + t1_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, + KEY (t1_name), + PRIMARY KEY (t1_id) +) AUTO_INCREMENT = 1000; + +INSERT INTO t1 (t1_name) VALUES('MySQL'); +INSERT INTO t1 (t1_name) VALUES('MySQL'); +INSERT INTO t1 (t1_name) VALUES('MySQL'); + +SELECT * from t1; + +SHOW CREATE TABLE `t1`; + +DROP TABLE `t1`; + +--echo End of 4.1 tests diff --git a/mysql-test/t/date_formats.test b/mysql-test/t/date_formats.test index 78b4482a94a..f3d507e69e6 100644 --- a/mysql-test/t/date_formats.test +++ b/mysql-test/t/date_formats.test @@ -276,3 +276,25 @@ select str_to_date( 1, NULL ); select str_to_date( NULL, 1 ); select str_to_date( 1, IF(1=1,NULL,NULL) ); # End of 4.1 tests + +# +# Bug#11326 +# + +SELECT TIME_FORMAT("24:00:00", '%r'); +SELECT TIME_FORMAT("00:00:00", '%r'); +SELECT TIME_FORMAT("12:00:00", '%r'); +SELECT TIME_FORMAT("15:00:00", '%r'); +SELECT TIME_FORMAT("01:00:00", '%r'); +SELECT TIME_FORMAT("25:00:00", '%r'); + +# +# Bug#11324 +# + +SELECT TIME_FORMAT("00:00:00", '%l %p'); +SELECT TIME_FORMAT("01:00:00", '%l %p'); +SELECT TIME_FORMAT("12:00:00", '%l %p'); +SELECT TIME_FORMAT("23:00:00", '%l %p'); +SELECT TIME_FORMAT("24:00:00", '%l %p'); +SELECT TIME_FORMAT("25:00:00", '%l %p'); diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test index 87d9d601c87..e2641f8d6cd 100644 --- a/mysql-test/t/func_misc.test +++ b/mysql-test/t/func_misc.test @@ -43,4 +43,44 @@ create table t1 as select uuid(), length(uuid()); show create table t1; drop table t1; + +# +# Bug#16501: IS_USED_LOCK does not appear to work +# +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +CREATE TABLE t1 (conn CHAR(7), connection_id INT); +INSERT INTO t1 VALUES ('default', CONNECTION_ID()); + +SELECT GET_LOCK('bug16501',600); + +connect (con1,localhost,root,,); +INSERT INTO t1 VALUES ('con1', CONNECTION_ID()); +SELECT IS_USED_LOCK('bug16501') = connection_id +FROM t1 +WHERE conn = 'default'; +send SELECT GET_LOCK('bug16501',600); + +connection default; +SELECT IS_USED_LOCK('bug16501') = CONNECTION_ID(); +SELECT RELEASE_LOCK('bug16501'); +connection con1; +reap; +connection default; +SELECT IS_USED_LOCK('bug16501') = connection_id +FROM t1 +WHERE conn = 'con1'; + +connection con1; +SELECT IS_USED_LOCK('bug16501') = CONNECTION_ID(); +SELECT RELEASE_LOCK('bug16501'); +SELECT IS_USED_LOCK('bug16501'); + +disconnect con1; +connection default; + +DROP TABLE t1; + # End of 4.1 tests diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index 8afbe673ce3..c2f76dbac43 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -662,4 +662,11 @@ select rpad(i, 7, ' ') as t from t1; --disable_metadata drop table t1; -# End of 4.1 tests +# +# Bug #10418: LOAD_FILE does not behave like in manual if file does not exist +# + +select load_file("lkjlkj"); +select ifnull(load_file("lkjlkj"),"it's null"); + +--echo End of 4.1 tests diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index 68a33afd85c..01e4e47d318 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -315,4 +315,11 @@ select last_day('2005-00-00'); select last_day('2005-00-01'); select last_day('2005-01-00'); +# +# Bug #18501: monthname and NULLs +# + +select monthname(str_to_date(null, '%m')), monthname(str_to_date(null, '%m')), + monthname(str_to_date(1, '%m')), monthname(str_to_date(0, '%m')); + # End of 4.1 tests diff --git a/mysql-test/t/having.test b/mysql-test/t/having.test index 3dd9ace6a1b..8b39e3bd454 100644 --- a/mysql-test/t/having.test +++ b/mysql-test/t/having.test @@ -135,4 +135,20 @@ SELECT SUM(a) FROM t1 GROUP BY a HAVING SUM(a); DROP TABLE t1; +# +# Bug #14927: HAVING clause containing constant false conjunct +# + +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (1), (2), (1), (3), (2), (1); + +SELECT a FROM t1 GROUP BY a HAVING a > 1; +SELECT a FROM t1 GROUP BY a HAVING 1 != 1 AND a > 1; +SELECT 0 AS x, a FROM t1 GROUP BY x,a HAVING x=1 AND a > 1; + +EXPLAIN SELECT a FROM t1 GROUP BY a HAVING 1 != 1 AND a > 1; +EXPLAIN SELECT 0 AS x, a FROM t1 GROUP BY x,a HAVING x=1 AND a > 1; + +DROP table t1; + # End of 4.1 tests diff --git a/mysql-test/t/init_connect.test b/mysql-test/t/init_connect.test index f90d1b8670d..7ceaef1aad7 100644 --- a/mysql-test/t/init_connect.test +++ b/mysql-test/t/init_connect.test @@ -2,6 +2,8 @@ # Test of init_connect variable # +# should work with embedded server after mysqltest is fixed +-- source include/not_embedded.inc connect (con0,localhost,root,,); connection con0; select hex(@a); diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test index b942b9fbc0d..f31e4d64789 100644 --- a/mysql-test/t/innodb_mysql.test +++ b/mysql-test/t/innodb_mysql.test @@ -1,5 +1,59 @@ -- source include/have_innodb.inc --disable_warnings -drop table if exists t1; +drop table if exists t1,t2; --enable_warnings + +# BUG#16798: Uninitialized row buffer reads in ref-or-null optimizer +# (repeatable only w/innodb). +create table t1 ( + c_id int(11) not null default '0', + org_id int(11) default null, + unique key contacts$c_id (c_id), + key contacts$org_id (org_id) +) engine=innodb; +insert into t1 values + (2,null),(120,null),(141,null),(218,7), (128,1), + (151,2),(234,2),(236,2),(243,2),(255,2),(259,2),(232,3),(235,3),(238,3), + (246,3),(253,3),(269,3),(285,3),(291,3),(293,3),(131,4),(230,4),(231,4); + +create table t2 ( + slai_id int(11) not null default '0', + owner_tbl int(11) default null, + owner_id int(11) default null, + sla_id int(11) default null, + inc_web int(11) default null, + inc_email int(11) default null, + inc_chat int(11) default null, + inc_csr int(11) default null, + inc_total int(11) default null, + time_billed int(11) default null, + activedate timestamp null default null, + expiredate timestamp null default null, + state int(11) default null, + sla_set int(11) default null, + unique key t2$slai_id (slai_id), + key t2$owner_id (owner_id), + key t2$sla_id (sla_id) +) engine=innodb; +insert into t2(slai_id, owner_tbl, owner_id, sla_id) values + (1,3,1,1), (3,3,10,2), (4,3,3,6), (5,3,2,5), (6,3,8,3), (7,3,9,7), + (8,3,6,8), (9,3,4,9), (10,3,5,10), (11,3,11,11), (12,3,7,12); + +flush tables; +select si.slai_id +from t1 c join t2 si on + ((si.owner_tbl = 3 and si.owner_id = c.org_id) or + ( si.owner_tbl = 2 and si.owner_id = c.c_id)) +where + c.c_id = 218 and expiredate is null; + +select * from t1 where org_id is null; +select si.slai_id +from t1 c join t2 si on + ((si.owner_tbl = 3 and si.owner_id = c.org_id) or + ( si.owner_tbl = 2 and si.owner_id = c.c_id)) +where + c.c_id = 218 and expiredate is null; + +drop table t1, t2; diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test index 27bdf4df3d7..e628e900c73 100644 --- a/mysql-test/t/multi_update.test +++ b/mysql-test/t/multi_update.test @@ -448,4 +448,12 @@ insert into t2 values(1,null); delete t2, t1 from t2 left join t1 on (t2.aclid=t1.aclid) where t2.refid='1'; drop table t1, t2; +# +# Bug#19225: unchecked error leads to server crash +# +create table t1(a int); +create table t2(a int); +--error 1093 +delete from t1,t2 using t1,t2 where t1.a=(select a from t1); +drop table t1, t2; # End of 4.1 tests diff --git a/mysql-test/t/mysql_client_test.test b/mysql-test/t/mysql_client_test.test index 66b57dd5fb7..1225bf73009 100644 --- a/mysql-test/t/mysql_client_test.test +++ b/mysql-test/t/mysql_client_test.test @@ -1,3 +1,6 @@ +# This test should work in embedded server after we fix mysqltest +-- source include/not_embedded.inc + # We run with different binaries for normal and --embedded-server # # If this test fails with "command "$MYSQL_CLIENT_TEST" failed", diff --git a/mysql-test/t/mysqlbinlog.test b/mysql-test/t/mysqlbinlog.test index 871886331f6..6e3daaef0c3 100644 --- a/mysql-test/t/mysqlbinlog.test +++ b/mysql-test/t/mysqlbinlog.test @@ -114,8 +114,17 @@ select HEX(f) from t3; select HEX(f) from t04; select HEX(f) from t4; +# +#14157: utf8 encoding in binlog without set character_set_client +# +flush logs; +--exec $MYSQL --character-sets-dir=../sql/share/charsets/ --default-character-set=koi8r test -e 'create table if not exists t5 (a int); set names koi8r; create temporary table `ÑÝÉË` (a int); insert into `ÑÝÉË` values (1); insert into t5 select * from `ÑÝÉË`' + +# resulted log is client charset insensitive (latin1 not koi8r) as it must be +--exec $MYSQL_BINLOG --short-form $MYSQL_TEST_DIR/var/log/master-bin.000006 | $MYSQL --default-character-set=latin1 +select * from t5 /* must be (1),(1) */; # clean up -drop table t1, t2, t03, t04, t3, t4; +drop table t1, t2, t03, t04, t3, t4, t5; # End of 4.1 tests diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index ad1fb534836..f24899fd8ae 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -2,7 +2,7 @@ --source include/not_embedded.inc --disable_warnings -DROP TABLE IF EXISTS t1, `"t"1`; +DROP TABLE IF EXISTS t1, `"t"1`, t2, t3; --enable_warnings # XML output @@ -647,4 +647,45 @@ select * from t1; select * from t1; drop table t1; -# End of 4.1 tests + +# +# BUG #19025 mysqldump doesn't correctly dump "auto_increment = [int]" +# +create table `t1` ( + t1_name varchar(255) default null, + t1_id int(10) unsigned not null auto_increment, + key (t1_name), + primary key (t1_id) +) auto_increment = 1000 default charset=latin1; + +insert into t1 (t1_name) values('bla'); +insert into t1 (t1_name) values('bla'); +insert into t1 (t1_name) values('bla'); + +select * from t1; + +show create table `t1`; + +--exec $MYSQL_DUMP --skip-comments test t1 > $MYSQLTEST_VARDIR/tmp/bug19025.sql +DROP TABLE `t1`; + +--exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/bug19025.sql + +select * from t1; + +show create table `t1`; + +drop table `t1`; + +# +# Bug #18536: wrong table order +# + +create table t1(a int); +create table t2(a int); +create table t3(a int); +--error 6 +--exec $MYSQL_DUMP --skip-comments --force --no-data test t3 t1 non_existing t2 +drop table t1, t2, t3; + +--echo End of 4.1 tests diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index f5c6a7617c5..a15a143e9f4 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -1,3 +1,4 @@ +-- source include/not_embedded.inc # ============================================================================ # diff --git a/mysql-test/t/ndb_autodiscover3.test b/mysql-test/t/ndb_autodiscover3.test new file mode 100644 index 00000000000..73b4bf8b94f --- /dev/null +++ b/mysql-test/t/ndb_autodiscover3.test @@ -0,0 +1,65 @@ +-- source include/have_ndb.inc +-- source include/have_multi_ndb.inc +-- source include/not_embedded.inc + + +--disable_warnings +drop table if exists t1, t2; +--enable_warnings + +# +# Transaction ongoing while cluster is restarted +# +--connection server1 +create table t1 (a int key) engine=ndbcluster; + +begin; +insert into t1 values (1); + +--exec $NDB_MGM --no-defaults -e "all restart" >> $NDB_TOOLS_OUTPUT +--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults >> $NDB_TOOLS_OUTPUT + +--error 1297 +insert into t1 values (2); +--error 1296 +commit; + +drop table t1; + +# +# Stale cache after restart -i +# +--connection server1 +create table t2 (a int, b int, primary key(a,b)) engine=ndbcluster; +insert into t2 values (1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1),(9,1),(10,1); +select * from t2 order by a limit 3; + +--exec $NDB_MGM --no-defaults -e "all restart -i" >> $NDB_TOOLS_OUTPUT +--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults >> $NDB_TOOLS_OUTPUT + +--connection server2 +create table t2 (a int key) engine=ndbcluster; +insert into t2 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); +select * from t2 order by a limit 3; + +# server 1 should have a stale cache, and in this case wrong frm, transaction must be retried +--connection server1 +--error 1015 +select * from t2 order by a limit 3; +select * from t2 order by a limit 3; + +--exec $NDB_MGM --no-defaults -e "all restart -i" >> $NDB_TOOLS_OUTPUT +--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults >> $NDB_TOOLS_OUTPUT + +--connection server1 +show tables; +create table t2 (a int key) engine=ndbcluster; +insert into t2 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); +select * from t2 order by a limit 3; + +# server 2 should have a stale cache, but with right frm, transaction need not be retried +--connection server2 +select * from t2 order by a limit 3; + +drop table t2; +# End of 4.1 tests diff --git a/mysql-test/t/ndb_blob.test b/mysql-test/t/ndb_blob.test index f80b7f71281..bf82a793049 100644 --- a/mysql-test/t/ndb_blob.test +++ b/mysql-test/t/ndb_blob.test @@ -403,10 +403,29 @@ create table t1 ( insert into t1 (msg) values( 'Tries to validate (8 byte length + inline bytes) as UTF8 :( Fast fix: removed validation for Text. It is not yet indexable -so bad data will not crash kernel. -Proper fix: Set inline bytes to multiple of mbmaxlen and -validate it (after the 8 byte length).'); +so bad data will not crash kernel.'); select * from t1; drop table t1; +# -- bug #19201 +create table t1 ( + a int primary key not null auto_increment, + b text +) engine=ndbcluster; +--disable_query_log +set autocommit=1; +# more rows than batch size (64) +# for this bug no blob parts would be necessary +let $1 = 500; +while ($1) +{ + insert into t1 (b) values (repeat('x',4000)); + dec $1; +} +--enable_query_log +select count(*) from t1; +truncate t1; +select count(*) from t1; +drop table t1; + # End of 4.1 tests diff --git a/mysql-test/t/null.test b/mysql-test/t/null.test index 731f0a4cb34..b405b8fb852 100644 --- a/mysql-test/t/null.test +++ b/mysql-test/t/null.test @@ -187,4 +187,45 @@ select # Restore charset to the default value. set names latin1; +# +# Bug#19145: mysqld crashes if you set the default value of an enum field to NULL +# +create table bug19145a (e enum('a','b','c') default 'b' , s set('x', 'y', 'z') default 'y' ) engine=MyISAM; +create table bug19145b (e enum('a','b','c') default null, s set('x', 'y', 'z') default null) engine=MyISAM; + +create table bug19145c (e enum('a','b','c') not null default 'b' , s set('x', 'y', 'z') not null default 'y' ) engine=MyISAM; + +# Invalid default value for 's' +--error 1067 +create table bug19145setnotnulldefaultnull (e enum('a','b','c') default null, s set('x', 'y', 'z') not null default null) engine=MyISAM; + +# Invalid default value for 'e' +--error 1067 +create table bug19145enumnotnulldefaultnull (e enum('a','b','c') not null default null, s set('x', 'y', 'z') default null) engine=MyISAM; + +alter table bug19145a alter column e set default null; +alter table bug19145a alter column s set default null; +alter table bug19145a add column (i int); + +alter table bug19145b alter column e set default null; +alter table bug19145b alter column s set default null; +alter table bug19145b add column (i int); + +# Invalid default value for 'e' +--error 1067 +alter table bug19145c alter column e set default null; + +# Invalid default value for 's' +--error 1067 +alter table bug19145c alter column s set default null; +alter table bug19145c add column (i int); + +show create table bug19145a; +show create table bug19145b; +show create table bug19145c; + +drop table bug19145a; +drop table bug19145b; +drop table bug19145c; + # End of 4.1 tests diff --git a/mysql-test/t/outfile.test b/mysql-test/t/outfile.test index a74bebe1460..81fcc7fd564 100644 --- a/mysql-test/t/outfile.test +++ b/mysql-test/t/outfile.test @@ -38,7 +38,6 @@ select load_file(concat(@tmpdir,"/outfile-test.3")); #--error 1086 #eval select * into dumpfile "$MYSQL_TEST_DIR/var/tmp/outfile-test.3" from t1; #enable_query_log; ---error 13,2 select load_file(concat(@tmpdir,"/outfile-test.not-exist")); --exec rm $MYSQL_TEST_DIR/var/tmp/outfile-test.1 --exec rm $MYSQL_TEST_DIR/var/tmp/outfile-test.2 diff --git a/mysql-test/t/ps_11bugs.test b/mysql-test/t/ps_11bugs.test index e214afeaaf3..ff1c87f3bd8 100644 --- a/mysql-test/t/ps_11bugs.test +++ b/mysql-test/t/ps_11bugs.test @@ -130,3 +130,17 @@ drop table t1, t2; # end of bug#1676 # End of 4.1 tests + +# bug#18492: mysqld reports ER_ILLEGAL_REFERENCE in --ps-protocol + +create table t1 (a int primary key); +insert into t1 values (1); + +explain select * from t1 where 3 in (select (1+1) union select 1); + +select * from t1 where 3 in (select (1+1) union select 1); + +prepare st_18492 from 'select * from t1 where 3 in (select (1+1) union select 1)'; +execute st_18492; + +drop table t1; diff --git a/mysql-test/t/rpl_temporary.test b/mysql-test/t/rpl_temporary.test index 71d7b32b7c9..bc1b0e64565 100644 --- a/mysql-test/t/rpl_temporary.test +++ b/mysql-test/t/rpl_temporary.test @@ -135,14 +135,19 @@ sync_with_master; # value was set up at the moment of temp table creation # connection con1; -set @session.pseudo_thread_id=100; +set @@session.pseudo_thread_id=100; create temporary table t101 (id int); create temporary table t102 (id int); -set @session.pseudo_thread_id=200; +set @@session.pseudo_thread_id=200; create temporary table t201 (id int); -create temporary table `#not_user_table_prefixed_with_hash_sign_no_harm` (id int); -set @con1_id=connection_id(); -kill @con1_id; +create temporary table `t``201` (id int); +# emulate internal temp table not to come to binlog +create temporary table `#sql_not_user_table202` (id int); +set @@session.pseudo_thread_id=300; +create temporary table t301 (id int); +create temporary table t302 (id int); +create temporary table `#sql_not_user_table303` (id int); +disconnect con1; #now do something to show that slave is ok after DROP temp tables connection master; @@ -156,4 +161,16 @@ select * from t1 /* must be 1 */; connection master; drop table t1; +# +#14157: utf8 encoding in binlog without set character_set_client +# +--exec $MYSQL --character-sets-dir=../sql/share/charsets/ --default-character-set=latin1 test -e 'create table t1 (a int); set names latin1; create temporary table `äöüÄÖÜ` (a int); insert into `äöüÄÖÜ` values (1); insert into t1 select * from `äöüÄÖÜ`' + +sync_slave_with_master; +#connection slave; +select * from t1; + +connection master; +drop table t1; + # End of 4.1 tests diff --git a/mysql-test/t/rpl_user_variables.test b/mysql-test/t/rpl_user_variables.test index 5cf502e05bd..6597413c22e 100644 --- a/mysql-test/t/rpl_user_variables.test +++ b/mysql-test/t/rpl_user_variables.test @@ -47,9 +47,15 @@ connection slave; sync_with_master; select * from t1; show binlog events from 141; + +# +# BUG19136: Crashing log-bin and uninitialized user variables in a derived table +# just to check nothing bad happens anymore connection master; +insert into t1 select * FROM (select @var1 union select @var2) AS t2; drop table t1; save_master_pos; + connection slave; sync_with_master; stop slave; diff --git a/mysql-test/t/wait_timeout.test b/mysql-test/t/wait_timeout.test index 26f91569868..4c1aeee5c04 100644 --- a/mysql-test/t/wait_timeout.test +++ b/mysql-test/t/wait_timeout.test @@ -1,3 +1,6 @@ +# This tests not performed with embedded server +-- source include/not_embedded.inc + # # Bug #8731: wait_timeout does not work on Mac OS X # diff --git a/ndb/include/kernel/signaldata/TcKeyReq.hpp b/ndb/include/kernel/signaldata/TcKeyReq.hpp index 9e42f2a70d5..820425b97e2 100644 --- a/ndb/include/kernel/signaldata/TcKeyReq.hpp +++ b/ndb/include/kernel/signaldata/TcKeyReq.hpp @@ -39,6 +39,7 @@ class TcKeyReq { friend class NdbOperation; friend class NdbIndexOperation; friend class NdbScanOperation; + friend class NdbBlob; friend class DbUtil; /** diff --git a/ndb/include/mgmapi/mgmapi_config_parameters.h b/ndb/include/mgmapi/mgmapi_config_parameters.h index 9076f18c5ac..ec69be74d12 100644 --- a/ndb/include/mgmapi/mgmapi_config_parameters.h +++ b/ndb/include/mgmapi/mgmapi_config_parameters.h @@ -65,6 +65,7 @@ #define CFG_DB_BACKUP_DATA_BUFFER_MEM 134 #define CFG_DB_BACKUP_LOG_BUFFER_MEM 135 #define CFG_DB_BACKUP_WRITE_SIZE 136 +#define CFG_DB_BACKUP_MAX_WRITE_SIZE 139 #define CFG_LOG_DESTINATION 147 diff --git a/ndb/include/ndbapi/NdbBlob.hpp b/ndb/include/ndbapi/NdbBlob.hpp index a04f4f72bc9..f2c215ba14d 100644 --- a/ndb/include/ndbapi/NdbBlob.hpp +++ b/ndb/include/ndbapi/NdbBlob.hpp @@ -275,6 +275,7 @@ private: bool isWriteOp(); bool isDeleteOp(); bool isScanOp(); + bool isTakeOverOp(); // computations Uint32 getPartNumber(Uint64 pos); Uint32 getPartCount(); diff --git a/ndb/include/ndbapi/ndb_cluster_connection.hpp b/ndb/include/ndbapi/ndb_cluster_connection.hpp index 0e559700716..3fe66bd2d44 100644 --- a/ndb/include/ndbapi/ndb_cluster_connection.hpp +++ b/ndb/include/ndbapi/ndb_cluster_connection.hpp @@ -83,6 +83,7 @@ public: void set_optimized_node_selection(int val); unsigned no_db_nodes(); + unsigned get_connect_count() const; #endif private: diff --git a/ndb/include/util/SocketServer.hpp b/ndb/include/util/SocketServer.hpp index ee2dd31c41f..02a0a6b5d92 100644 --- a/ndb/include/util/SocketServer.hpp +++ b/ndb/include/util/SocketServer.hpp @@ -74,7 +74,7 @@ public: /** * Constructor / Destructor */ - SocketServer(int maxSessions = 32); + SocketServer(unsigned maxSessions = ~(unsigned)0); ~SocketServer(); /** diff --git a/ndb/src/common/transporter/Transporter.cpp b/ndb/src/common/transporter/Transporter.cpp index 328ce2816de..902dfea9c8e 100644 --- a/ndb/src/common/transporter/Transporter.cpp +++ b/ndb/src/common/transporter/Transporter.cpp @@ -100,10 +100,10 @@ Transporter::connect_server(NDB_SOCKET_TYPE sockfd) { } { - struct sockaddr addr; + struct sockaddr_in addr; SOCKET_SIZE_TYPE addrlen= sizeof(addr); - int r= getpeername(sockfd, &addr, &addrlen); - m_connect_address= ((struct sockaddr_in *)&addr)->sin_addr; + int r= getpeername(sockfd, (struct sockaddr*)&addr, &addrlen); + m_connect_address= (&addr)->sin_addr; } bool res = connect_server_impl(sockfd); @@ -173,10 +173,10 @@ Transporter::connect_client() { } { - struct sockaddr addr; + struct sockaddr_in addr; SOCKET_SIZE_TYPE addrlen= sizeof(addr); - int r= getpeername(sockfd, &addr, &addrlen); - m_connect_address= ((struct sockaddr_in *)&addr)->sin_addr; + int r= getpeername(sockfd, (struct sockaddr*)&addr, &addrlen); + m_connect_address= (&addr)->sin_addr; } bool res = connect_client_impl(sockfd); diff --git a/ndb/src/common/util/SocketServer.cpp b/ndb/src/common/util/SocketServer.cpp index db5c03f925a..755764c7700 100644 --- a/ndb/src/common/util/SocketServer.cpp +++ b/ndb/src/common/util/SocketServer.cpp @@ -27,7 +27,7 @@ #define DEBUG(x) ndbout << x << endl; -SocketServer::SocketServer(int maxSessions) : +SocketServer::SocketServer(unsigned maxSessions) : m_sessions(10), m_services(5) { @@ -124,7 +124,7 @@ SocketServer::setup(SocketServer::Service * service, DBUG_RETURN(false); } - if (listen(sock, m_maxSessions) == -1){ + if (listen(sock, m_maxSessions > 32 ? 32 : m_maxSessions) == -1){ DBUG_PRINT("error",("listen() - %d - %s", errno, strerror(errno))); NDB_CLOSE_SOCKET(sock); diff --git a/ndb/src/kernel/blocks/backup/BackupInit.cpp b/ndb/src/kernel/blocks/backup/BackupInit.cpp index 7cd9c61f010..dfda31e9b48 100644 --- a/ndb/src/kernel/blocks/backup/BackupInit.cpp +++ b/ndb/src/kernel/blocks/backup/BackupInit.cpp @@ -66,15 +66,16 @@ Backup::Backup(const Configuration & conf) : Uint32 szDataBuf = (2 * 1024 * 1024); Uint32 szLogBuf = (2 * 1024 * 1024); - Uint32 szWrite = 32768; + Uint32 szWrite = 32768, maxWriteSize = (256 * 1024); ndb_mgm_get_int_parameter(p, CFG_DB_BACKUP_DATA_BUFFER_MEM, &szDataBuf); ndb_mgm_get_int_parameter(p, CFG_DB_BACKUP_LOG_BUFFER_MEM, &szLogBuf); ndb_mgm_get_int_parameter(p, CFG_DB_BACKUP_WRITE_SIZE, &szWrite); + ndb_mgm_get_int_parameter(p, CFG_DB_BACKUP_MAX_WRITE_SIZE, &maxWriteSize); c_defaults.m_logBufferSize = szLogBuf; c_defaults.m_dataBufferSize = szDataBuf; c_defaults.m_minWriteSize = szWrite; - c_defaults.m_maxWriteSize = szWrite; + c_defaults.m_maxWriteSize = maxWriteSize; { // Init all tables ArrayList<Table> tables(c_tablePool); diff --git a/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp b/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp index f99b4bf15af..2b1f079ea17 100644 --- a/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp +++ b/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp @@ -190,7 +190,7 @@ Dbtc::Dbtc(const class Configuration & conf): ndb_mgm_get_int_parameter(p, CFG_DB_TRANS_BUFFER_MEM, &transactionBufferMemory); - ndb_mgm_get_int_parameter(p, CFG_DB_NO_UNIQUE_HASH_INDEXES, + ndb_mgm_get_int_parameter(p, CFG_DICT_TABLE, &maxNoOfIndexes); ndb_mgm_get_int_parameter(p, CFG_DB_NO_INDEX_OPS, &maxNoOfConcurrentIndexOperations); diff --git a/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp b/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp index 8e3ca6528c2..8171fa65771 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp @@ -1494,6 +1494,7 @@ int Dbtup::interpreterNextLab(Signal* signal, // word read. Thus we set the register to be a 32 bit register. /* ------------------------------------------------------------- */ TregMemBuffer[theRegister] = 0x50; + // arithmetic conversion if big-endian * (Int64*)(TregMemBuffer+theRegister+2) = TregMemBuffer[theRegister+1]; } else if (TnoDataRW == 3) { /* ------------------------------------------------------------- */ @@ -1557,6 +1558,11 @@ int Dbtup::interpreterNextLab(Signal* signal, Tlen = TattrNoOfWords + 1; if (Toptype == ZUPDATE) { if (TattrNoOfWords <= 2) { + if (TattrNoOfWords == 1) { + // arithmetic conversion if big-endian + TdataForUpdate[1] = *(Int64*)&TregMemBuffer[theRegister + 2]; + TdataForUpdate[2] = 0; + } if (TregType == 0) { /* --------------------------------------------------------- */ // Write a NULL value into the attribute diff --git a/ndb/src/mgmapi/mgmapi.cpp b/ndb/src/mgmapi/mgmapi.cpp index 06b534ac0ca..fc9e5a20f4e 100644 --- a/ndb/src/mgmapi/mgmapi.cpp +++ b/ndb/src/mgmapi/mgmapi.cpp @@ -638,10 +638,12 @@ ndb_mgm_get_status(NdbMgmHandle handle) Vector<BaseString> split; tmp.split(split, ":"); if(split.size() != 2){ + SET_ERROR(handle, NDB_MGM_ILLEGAL_NODE_STATUS, buf); return NULL; } if(!(split[0].trim() == "nodes")){ + SET_ERROR(handle, NDB_MGM_ILLEGAL_NODE_STATUS, buf); return NULL; } @@ -690,6 +692,7 @@ ndb_mgm_get_status(NdbMgmHandle handle) if(i+1 != noOfNodes){ free(state); + SET_ERROR(handle, NDB_MGM_ILLEGAL_NODE_STATUS, "Node count mismatch"); return NULL; } diff --git a/ndb/src/mgmsrv/ConfigInfo.cpp b/ndb/src/mgmsrv/ConfigInfo.cpp index 36a72dcb975..66a400a3e22 100644 --- a/ndb/src/mgmsrv/ConfigInfo.cpp +++ b/ndb/src/mgmsrv/ConfigInfo.cpp @@ -1191,7 +1191,19 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { false, ConfigInfo::CI_INT, "32K", - "0", + "2K", + STR_VALUE(MAX_INT_RNIL) }, + + { + CFG_DB_BACKUP_MAX_WRITE_SIZE, + "BackupMaxWriteSize", + DB_TOKEN, + "Max size of filesystem writes made by backup (in bytes)", + ConfigInfo::CI_USED, + false, + ConfigInfo::CI_INT, + "256K", + "2K", STR_VALUE(MAX_INT_RNIL) }, /*************************************************************************** diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp index 47d156c1f9e..c9e8535b75c 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.cpp +++ b/ndb/src/mgmsrv/MgmtSrvr.cpp @@ -2107,6 +2107,7 @@ int MgmtSrvr::abortBackup(Uint32 backupId) { SignalSender ss(theFacade); + ss.lock(); // lock will be released on exit bool next; NodeId nodeId = 0; diff --git a/ndb/src/mgmsrv/Services.cpp b/ndb/src/mgmsrv/Services.cpp index 1a5b0592066..0ce89aacefc 100644 --- a/ndb/src/mgmsrv/Services.cpp +++ b/ndb/src/mgmsrv/Services.cpp @@ -427,9 +427,9 @@ MgmApiSession::get_nodeid(Parser_t::Context &, return; } - struct sockaddr addr; + struct sockaddr_in addr; SOCKET_SIZE_TYPE addrlen= sizeof(addr); - int r = getpeername(m_socket, &addr, &addrlen); + int r = getpeername(m_socket, (struct sockaddr*)&addr, &addrlen); if (r != 0 ) { m_output->println(cmd); m_output->println("result: getpeername(%d) failed, err= %d", m_socket, r); @@ -441,7 +441,7 @@ MgmApiSession::get_nodeid(Parser_t::Context &, if(tmp == 0 || !m_allocated_resources->is_reserved(tmp)){ BaseString error_string; if (!m_mgmsrv.alloc_node_id(&tmp, (enum ndb_mgm_node_type)nodetype, - &addr, &addrlen, error_string)){ + (struct sockaddr*)&addr, &addrlen, error_string)){ const char *alias; const char *str; alias= ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type) diff --git a/ndb/src/ndbapi/ClusterMgr.cpp b/ndb/src/ndbapi/ClusterMgr.cpp index 543bdf1155e..cd559a544a8 100644 --- a/ndb/src/ndbapi/ClusterMgr.cpp +++ b/ndb/src/ndbapi/ClusterMgr.cpp @@ -70,6 +70,7 @@ ClusterMgr::ClusterMgr(TransporterFacade & _facade): noOfAliveNodes= 0; noOfConnectedNodes= 0; theClusterMgrThread= 0; + m_connect_count = 0; DBUG_VOID_RETURN; } @@ -456,6 +457,10 @@ ClusterMgr::reportNodeFailed(NodeId nodeId){ theNode.nfCompleteRep = false; if(noOfAliveNodes == 0){ + theFacade.m_globalDictCache.lock(); + theFacade.m_globalDictCache.invalidate_all(); + theFacade.m_globalDictCache.unlock(); + m_connect_count ++; NFCompleteRep rep; for(Uint32 i = 1; i<MAX_NODES; i++){ if(theNodes[i].defined && theNodes[i].nfCompleteRep == false){ diff --git a/ndb/src/ndbapi/ClusterMgr.hpp b/ndb/src/ndbapi/ClusterMgr.hpp index d75b820e9cb..3a2005127cd 100644 --- a/ndb/src/ndbapi/ClusterMgr.hpp +++ b/ndb/src/ndbapi/ClusterMgr.hpp @@ -78,6 +78,7 @@ public: const Node & getNodeInfo(NodeId) const; Uint32 getNoOfConnectedNodes() const; + Uint32 m_connect_count; private: Uint32 noOfAliveNodes; diff --git a/ndb/src/ndbapi/DictCache.cpp b/ndb/src/ndbapi/DictCache.cpp index ca361e900b1..9b6449e8ec5 100644 --- a/ndb/src/ndbapi/DictCache.cpp +++ b/ndb/src/ndbapi/DictCache.cpp @@ -255,6 +255,42 @@ GlobalDictCache::drop(NdbTableImpl * tab) abort(); } + +unsigned +GlobalDictCache::get_size() +{ + NdbElement_t<Vector<TableVersion> > * curr = m_tableHash.getNext(0); + int sz = 0; + while(curr != 0){ + sz += curr->theData->size(); + curr = m_tableHash.getNext(curr); + } + return sz; +} + +void +GlobalDictCache::invalidate_all() +{ + DBUG_ENTER("GlobalDictCache::invalidate_all"); + NdbElement_t<Vector<TableVersion> > * curr = m_tableHash.getNext(0); + while(curr != 0){ + Vector<TableVersion> * vers = curr->theData; + if (vers->size()) + { + TableVersion * ver = & vers->back(); + ver->m_impl->m_status = NdbDictionary::Object::Invalid; + ver->m_status = DROPPED; + if (ver->m_refCount == 0) + { + delete ver->m_impl; + vers->erase(vers->size() - 1); + } + } + curr = m_tableHash.getNext(curr); + } + DBUG_VOID_RETURN; +} + void GlobalDictCache::release(NdbTableImpl * tab){ unsigned i; diff --git a/ndb/src/ndbapi/DictCache.hpp b/ndb/src/ndbapi/DictCache.hpp index 7f2ee457476..52bd57ea217 100644 --- a/ndb/src/ndbapi/DictCache.hpp +++ b/ndb/src/ndbapi/DictCache.hpp @@ -71,6 +71,9 @@ public: void alter_table_rep(const char * name, Uint32 tableId, Uint32 tableVersion, bool altered); + + unsigned get_size(); + void invalidate_all(); public: enum Status { OK = 0, diff --git a/ndb/src/ndbapi/NdbBlob.cpp b/ndb/src/ndbapi/NdbBlob.cpp index 416e983ec14..e595b4b6472 100644 --- a/ndb/src/ndbapi/NdbBlob.cpp +++ b/ndb/src/ndbapi/NdbBlob.cpp @@ -23,6 +23,7 @@ #include <NdbBlob.hpp> #include "NdbBlobImpl.hpp" #include <NdbScanOperation.hpp> +#include <signaldata/TcKeyReq.hpp> #ifdef NDB_BLOB_DEBUG #define DBG(x) \ @@ -290,6 +291,13 @@ NdbBlob::isScanOp() theNdbOp->theOperationType == NdbOperation::OpenRangeScanRequest; } +inline bool +NdbBlob::isTakeOverOp() +{ + return + TcKeyReq::getTakeOverScanFlag(theNdbOp->theScanInfo); +} + // computations (inline) inline Uint32 @@ -1218,8 +1226,22 @@ NdbBlob::preExecute(ExecType anExecType, bool& batch) if (isUpdateOp() || isWriteOp() || isDeleteOp()) { // add operation before this one to read head+inline NdbOperation* tOp = theNdbCon->getNdbOperation(theTable, theNdbOp); + /* + * If main op is from take over scan lock, the added read is done + * as committed read: + * + * In normal transactional case, the row is locked by us and + * committed read returns same as normal read. + * + * In current TRUNCATE TABLE, the deleting trans is committed in + * batches and then restarted with new trans id. A normal read + * would hang on the scan delete lock and then fail. + */ + NdbOperation::LockMode lockMode = + ! isTakeOverOp() ? + NdbOperation::LM_Read : NdbOperation::LM_CommittedRead; if (tOp == NULL || - tOp->readTuple() == -1 || + tOp->readTuple(lockMode) == -1 || setTableKeyValue(tOp) == -1 || getHeadInlineValue(tOp) == -1) { setErrorCode(tOp); diff --git a/ndb/src/ndbapi/SignalSender.cpp b/ndb/src/ndbapi/SignalSender.cpp index a29fe68937b..0ecc98f5f29 100644 --- a/ndb/src/ndbapi/SignalSender.cpp +++ b/ndb/src/ndbapi/SignalSender.cpp @@ -75,7 +75,9 @@ SignalSender::SignalSender(TransporterFacade *facade) { m_cond = NdbCondition_Create(); theFacade = facade; + lock(); m_blockNo = theFacade->open(this, execSignal, execNodeStatus); + unlock(); assert(m_blockNo > 0); } diff --git a/ndb/src/ndbapi/TransporterFacade.hpp b/ndb/src/ndbapi/TransporterFacade.hpp index 7e010d45945..b8963b8d0e1 100644 --- a/ndb/src/ndbapi/TransporterFacade.hpp +++ b/ndb/src/ndbapi/TransporterFacade.hpp @@ -265,6 +265,12 @@ TransporterFacade::unlock_mutex() #include "ClusterMgr.hpp" inline +unsigned Ndb_cluster_connection_impl::get_connect_count() const +{ + return TransporterFacade::instance()->theClusterMgr->m_connect_count; +} + +inline bool TransporterFacade::check_send_size(Uint32 node_id, Uint32 send_size) { diff --git a/ndb/src/ndbapi/ndb_cluster_connection.cpp b/ndb/src/ndbapi/ndb_cluster_connection.cpp index a313a973a42..df744fb3261 100644 --- a/ndb/src/ndbapi/ndb_cluster_connection.cpp +++ b/ndb/src/ndbapi/ndb_cluster_connection.cpp @@ -236,6 +236,12 @@ Ndb_cluster_connection::wait_until_ready(int timeout, } while (1); } +unsigned Ndb_cluster_connection::get_connect_count() const +{ + return m_impl.get_connect_count(); +} + + /* diff --git a/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp b/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp index 620eac296a3..ee561c1d6af 100644 --- a/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp +++ b/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp @@ -49,6 +49,7 @@ class Ndb_cluster_connection_impl : public Ndb_cluster_connection void init_get_next_node(Ndb_cluster_connection_node_iter &iter); Uint32 get_next_node(Ndb_cluster_connection_node_iter &iter); + inline unsigned get_connect_count() const; private: friend class Ndb; friend class NdbImpl; diff --git a/ndb/test/ndbapi/Makefile.am b/ndb/test/ndbapi/Makefile.am index 7b4a96f5890..29bbbb74422 100644 --- a/ndb/test/ndbapi/Makefile.am +++ b/ndb/test/ndbapi/Makefile.am @@ -24,6 +24,7 @@ testOIBasic \ testOperations \ testRestartGci \ testScan \ +testInterpreter \ testScanInterpreter \ testScanPerf \ testSystemRestart \ @@ -61,6 +62,7 @@ testOIBasic_SOURCES = testOIBasic.cpp testOperations_SOURCES = testOperations.cpp testRestartGci_SOURCES = testRestartGci.cpp testScan_SOURCES = testScan.cpp ScanFunctions.hpp +testInterpreter_SOURCES = testInterpreter.cpp testScanInterpreter_SOURCES = testScanInterpreter.cpp ScanFilter.hpp ScanInterpretTest.hpp testScanPerf_SOURCES = testScanPerf.cpp testSystemRestart_SOURCES = testSystemRestart.cpp @@ -152,3 +154,4 @@ testScan.dsp: Makefile \ @$(top_srcdir)/ndb/config/win-includes $@ $(INCLUDES) @$(top_srcdir)/ndb/config/win-sources $@ $(testScan_SOURCES) @$(top_srcdir)/ndb/config/win-libraries $@ LINK $(LDADD) + diff --git a/ndb/test/ndbapi/testBlobs.cpp b/ndb/test/ndbapi/testBlobs.cpp index 4c82f718788..05a462c12c6 100644 --- a/ndb/test/ndbapi/testBlobs.cpp +++ b/ndb/test/ndbapi/testBlobs.cpp @@ -45,6 +45,7 @@ struct Opt { bool m_dbg; bool m_dbgall; const char* m_dbug; + bool m_fac; bool m_full; unsigned m_loop; unsigned m_parts; @@ -73,6 +74,7 @@ struct Opt { m_dbg(false), m_dbgall(false), m_dbug(0), + m_fac(false), m_full(false), m_loop(1), m_parts(10), @@ -111,6 +113,7 @@ printusage() << " -dbg print debug" << endl << " -dbgall print also NDB API debug (if compiled in)" << endl << " -dbug opt dbug options" << endl + << " -fac fetch across commit in scan delete [" << d.m_fac << "]" << endl << " -full read/write only full blob values" << endl << " -loop N loop N times 0=forever [" << d.m_loop << "]" << endl << " -parts N max parts in blob value [" << d.m_parts << "]" << endl @@ -1260,23 +1263,11 @@ deleteScan(bool idx) CHK((ret = rs->nextResult(false)) == 0 || ret == 1 || ret == 2); if (++n == g_opt.m_batch || ret == 2) { DBG("execute batch: n=" << n << " ret=" << ret); - switch (0) { - case 0: // works normally + if (! g_opt.m_fac) { CHK(g_con->execute(NoCommit) == 0); - CHK(true || g_con->restart() == 0); - break; - case 1: // nonsense - g_con is invalid for 2nd batch - CHK(g_con->execute(Commit) == 0); - CHK(true || g_con->restart() == 0); - break; - case 2: // DBTC sendSignalErrorRefuseLab - CHK(g_con->execute(NoCommit) == 0); - CHK(g_con->restart() == 0); - break; - case 3: // 266 time-out + } else { CHK(g_con->execute(Commit) == 0); CHK(g_con->restart() == 0); - break; } n = 0; } @@ -1824,6 +1815,10 @@ NDB_COMMAND(testOdbcDriver, "testBlobs", "testBlobs", "testBlobs", 65535) continue; } } + if (strcmp(arg, "-fac") == 0) { + g_opt.m_fac = true; + continue; + } if (strcmp(arg, "-full") == 0) { g_opt.m_full = true; continue; diff --git a/ndb/test/ndbapi/testInterpreter.cpp b/ndb/test/ndbapi/testInterpreter.cpp index 0baba33d2b2..5d930d3d555 100644 --- a/ndb/test/ndbapi/testInterpreter.cpp +++ b/ndb/test/ndbapi/testInterpreter.cpp @@ -79,46 +79,46 @@ int runTestIncValue32(NDBT_Context* ctx, NDBT_Step* step){ Ndb* pNdb = GETNDB(step); - NdbConnection* pTrans = pNdb->startTransaction(); - if (pTrans == NULL){ - ERR(pNdb->getNdbError()); - return NDBT_FAILED; - } - - NdbOperation* pOp = pTrans->getNdbOperation(pTab->getName()); - if (pOp == NULL) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - - int check = pOp->interpretedUpdateTuple(); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - - - // Primary keys - Uint32 pkVal = 1; - check = pOp->equal("KOL1", pkVal ); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - - // Attributes - - // Update column - Uint32 valToIncWith = 1; - check = pOp->incValue("KOL2", valToIncWith); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } + NdbConnection* pTrans = pNdb->startTransaction(); + if (pTrans == NULL){ + ERR(pNdb->getNdbError()); + return NDBT_FAILED; + } + + NdbOperation* pOp = pTrans->getNdbOperation(pTab->getName()); + if (pOp == NULL) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + int check = pOp->interpretedUpdateTuple(); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + + // Primary keys + Uint32 pkVal = 1; + check = pOp->equal("KOL1", pkVal ); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + // Attributes + + // Update column + Uint32 valToIncWith = 1; + check = pOp->incValue("KOL2", valToIncWith); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } NdbRecAttr* valueRec = pOp->getValue("KOL2"); if( valueRec == NULL ) { @@ -142,6 +142,122 @@ int runTestIncValue32(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_OK; } +int runTestBug19537(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + const NdbDictionary::Table * pTab = ctx->getTab(); + Ndb* pNdb = GETNDB(step); + + if (strcmp(pTab->getName(), "T1") != 0) { + g_err << "runTestBug19537: skip, table != T1" << endl; + return NDBT_OK; + } + + + NdbConnection* pTrans = pNdb->startTransaction(); + if (pTrans == NULL){ + ERR(pNdb->getNdbError()); + return NDBT_FAILED; + } + + NdbOperation* pOp = pTrans->getNdbOperation(pTab->getName()); + if (pOp == NULL) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + if (pOp->interpretedUpdateTuple() == -1) { + ERR(pOp->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + + // Primary keys + const Uint32 pkVal = 1; + if (pOp->equal("KOL1", pkVal) == -1) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + // Load 64-bit constant into register 1 and + // write from register 1 to 32-bit column KOL2 + const Uint64 reg_val = 0x0102030405060708ULL; + + const Uint32* reg_ptr32 = (const Uint32*)®_val; + if (reg_ptr32[0] == 0x05060708 && reg_ptr32[1] == 0x01020304) { + g_err << "runTestBug19537: platform is LITTLE endian" << endl; + } else if (reg_ptr32[0] == 0x01020304 && reg_ptr32[1] == 0x05060708) { + g_err << "runTestBug19537: platform is BIG endian" << endl; + } else { + g_err << "runTestBug19537: impossible platform" + << hex << " [0]=" << reg_ptr32[0] << " [1]=" <<reg_ptr32[1] << endl; + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + if (pOp->load_const_u64(1, reg_val) == -1 || + pOp->write_attr("KOL2", 1) == -1) { + ERR(pOp->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + if (pTrans->execute(Commit) == -1) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + // Read value via a new transaction + + pTrans = pNdb->startTransaction(); + if (pTrans == NULL){ + ERR(pNdb->getNdbError()); + return NDBT_FAILED; + } + + pOp = pTrans->getNdbOperation(pTab->getName()); + if (pOp == NULL) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + Uint32 kol2 = 0x09090909; + if (pOp->readTuple() == -1 || + pOp->equal("KOL1", pkVal) == -1 || + pOp->getValue("KOL2", (char*)&kol2) == 0) { + ERR(pOp->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + if (pTrans->execute(Commit) == -1) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + // Expected conversion as in C - truncate to lower (logical) word + + if (kol2 == 0x01020304) { + g_err << "runTestBug19537: the bug manifests itself !" << endl; + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + if (kol2 != 0x05060708) { + g_err << "runTestBug19537: impossible KOL2 " << hex << kol2 << endl; + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + pNdb->closeTransaction(pTrans); + return NDBT_OK; +} + NDBT_TESTSUITE(testInterpreter); TESTCASE("IncValue32", @@ -156,6 +272,12 @@ TESTCASE("IncValue64", INITIALIZER(runTestIncValue64); FINALIZER(runClearTable); } +TESTCASE("Bug19537", + "Test big-endian write_attr of 32 bit integer\n"){ + INITIALIZER(runLoadTable); + INITIALIZER(runTestBug19537); + FINALIZER(runClearTable); +} #if 0 TESTCASE("MaxTransactions", "Start transactions until no more can be created\n"){ diff --git a/ndb/tools/delete_all.cpp b/ndb/tools/delete_all.cpp index d4a07fdf505..c1ab77cb39f 100644 --- a/ndb/tools/delete_all.cpp +++ b/ndb/tools/delete_all.cpp @@ -23,17 +23,21 @@ #include <NDBT.hpp> static int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab, - bool commit_across_open_cursor, int parallelism=240); + bool fetch_across_commit, int parallelism=240); NDB_STD_OPTS_VARS; static const char* _dbname = "TEST_DB"; +static my_bool _transactional = false; static struct my_option my_long_options[] = { NDB_STD_OPTS("ndb_desc"), { "database", 'd', "Name of database table is in", (gptr*) &_dbname, (gptr*) &_dbname, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, + { "transactional", 't', "Single transaction (may run out of operations)", + (gptr*) &_transactional, (gptr*) &_transactional, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; static void usage() @@ -82,18 +86,11 @@ int main(int argc, char** argv){ ndbout << " Table " << argv[i] << " does not exist!" << endl; return NDBT_ProgramExit(NDBT_WRONGARGS); } - // Check if we have any blobs - bool commit_across_open_cursor = true; - for (int j = 0; j < pTab->getNoOfColumns(); j++) { - NdbDictionary::Column::Type t = pTab->getColumn(j)->getType(); - if (t == NdbDictionary::Column::Blob || - t == NdbDictionary::Column::Text) { - commit_across_open_cursor = false; - break; - } - } - ndbout << "Deleting all from " << argv[i] << "..."; - if(clear_table(&MyNdb, pTab, commit_across_open_cursor) == NDBT_FAILED){ + ndbout << "Deleting all from " << argv[i]; + if (! _transactional) + ndbout << " (non-transactional)"; + ndbout << " ..."; + if(clear_table(&MyNdb, pTab, ! _transactional) == NDBT_FAILED){ res = NDBT_FAILED; ndbout << "FAILED" << endl; } @@ -103,7 +100,7 @@ int main(int argc, char** argv){ int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab, - bool commit_across_open_cursor, int parallelism) + bool fetch_across_commit, int parallelism) { // Scan all records exclusive and delete // them one by one @@ -134,7 +131,7 @@ int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab, } goto failed; } - + pOp = pTrans->getNdbScanOperation(pTab->getName()); if (pOp == NULL) { goto failed; @@ -165,7 +162,7 @@ int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab, } while((check = rs->nextResult(false)) == 0); if(check != -1){ - if (commit_across_open_cursor) { + if (fetch_across_commit) { check = pTrans->execute(Commit); pTrans->restart(); // new tx id } else { @@ -196,7 +193,7 @@ int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab, } goto failed; } - if (! commit_across_open_cursor && pTrans->execute(Commit) != 0) { + if (! fetch_across_commit && pTrans->execute(Commit) != 0) { err = pTrans->getNdbError(); goto failed; } diff --git a/ndb/tools/waiter.cpp b/ndb/tools/waiter.cpp index cc6a21428c8..9bd2befce15 100644 --- a/ndb/tools/waiter.cpp +++ b/ndb/tools/waiter.cpp @@ -129,6 +129,12 @@ getStatus(){ ndbout << "status==NULL, retries="<<retries<<endl; MGMERR(handle); retries++; + ndb_mgm_disconnect(handle); + if (ndb_mgm_connect(handle,0,0,1)) { + MGMERR(handle); + g_err << "Reconnect failed" << endl; + break; + } continue; } int count = status->no_of_nodes; diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 8455bbaf4d0..6c93ac293d0 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -3431,6 +3431,8 @@ ha_innobase::index_prev( mysql_byte* buf) /* in/out: buffer for previous row in MySQL format */ { + statistic_increment(ha_read_prev_count, &LOCK_status); + return(general_fetch(buf, ROW_SEL_PREV, 0)); } diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 876d5d2f8fd..c0eae685a52 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -3306,8 +3306,23 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type) { m_table= (void *)tab; m_table_version = tab->getObjectVersion(); - if (!(my_errno= build_index_list(ndb, table, ILBP_OPEN))) + if ((my_errno= build_index_list(ndb, table, ILBP_OPEN))) DBUG_RETURN(my_errno); + + const void *data, *pack_data; + uint length, pack_length; + if (readfrm(table->path, &data, &length) || + packfrm(data, length, &pack_data, &pack_length) || + pack_length != tab->getFrmLength() || + memcmp(pack_data, tab->getFrmData(), pack_length)) + { + my_free((char*)data, MYF(MY_ALLOW_ZERO_PTR)); + my_free((char*)pack_data, MYF(MY_ALLOW_ZERO_PTR)); + NdbError err= ndb->getNdbError(NDB_INVALID_SCHEMA_OBJECT); + DBUG_RETURN(ndb_to_mysql_error(&err)); + } + my_free((char*)data, MYF(MY_ALLOW_ZERO_PTR)); + my_free((char*)pack_data, MYF(MY_ALLOW_ZERO_PTR)); } m_table_info= tab_info; } diff --git a/sql/item.cc b/sql/item.cc index 5964ed388c6..7c9f6ec77fb 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2716,14 +2716,6 @@ void Item_ref_null_helper::print(String *str) } -void Item_null_helper::print(String *str) -{ - str->append("<null_helper>(", 14); - store->print(str); - str->append(')'); -} - - bool Item_default_value::eq(const Item *item, bool binary_cmp) const { return item->type() == DEFAULT_VALUE_ITEM && diff --git a/sql/item.h b/sql/item.h index 1d01ce0d3f3..66da7ad4e74 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1045,19 +1045,6 @@ public: } }; -class Item_null_helper :public Item_ref_null_helper -{ - Item *store; -public: - Item_null_helper(Item_in_subselect* master, Item *item, - const char *table_name_par, const char *field_name_par) - :Item_ref_null_helper(master, &item, table_name_par, field_name_par), - store(item) - { ref= &store; } - void print(String *str); -}; - - /* The following class is used to optimize comparing of date and bigint columns We need to save the original item ('ref') to be able to call diff --git a/sql/item_func.cc b/sql/item_func.cc index 174a8c55d01..66300d129d4 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1972,6 +1972,7 @@ void item_user_lock_free(void) void item_user_lock_release(User_level_lock *ull) { ull->locked=0; + ull->thread_id= 0; if (mysql_bin_log.is_open()) { char buf[256]; @@ -2170,6 +2171,7 @@ longlong Item_func_get_lock::val_int() { ull->locked=1; ull->thread=thd->real_id; + ull->thread_id= thd->thread_id; thd->ull=ull; error=0; } @@ -2733,14 +2735,24 @@ int get_var_with_binlog(THD *thd, LEX_STRING &name, sql_set_variables(), we could instead manually call check() and update(); this would save memory and time; but calling sql_set_variables() makes one unique place to maintain (sql_set_variables()). + + Manipulation with lex is necessary since free_underlaid_joins + is going to release memory belonging to the main query. */ List<set_var_base> tmp_var_list; + LEX *sav_lex= thd->lex, lex_tmp; + thd->lex= &lex_tmp; + lex_start(thd, NULL, 0); tmp_var_list.push_back(new set_var_user(new Item_func_set_user_var(name, new Item_null()))); /* Create the variable */ if (sql_set_variables(thd, &tmp_var_list)) + { + thd->lex= sav_lex; goto err; + } + thd->lex= sav_lex; if (!(var_entry= get_variable(&thd->user_vars, name, 0))) goto err; } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index f0127ed2a5d..e74d0100b55 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2489,7 +2489,7 @@ String *Item_load_file::val_str(String *str) (void) fn_format(path, file_name->c_ptr(), mysql_real_data_home, "", MY_RELATIVE_PATH | MY_UNPACK_FILENAME); - if (!my_stat(path, &stat_info, MYF(MY_WME))) + if (!my_stat(path, &stat_info, MYF(0))) goto err; if (!(stat_info.st_mode & S_IROTH)) diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index c8405a9f8f4..8241a8e0402 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -822,13 +822,13 @@ Item_in_subselect::single_value_transformer(JOIN *join, } else { - select_lex->item_list.empty(); - select_lex->item_list.push_back(new Item_int("Not_used", - (longlong) 1, 21)); - select_lex->ref_pointer_array[0]= select_lex->item_list.head(); if (select_lex->table_list.elements) { Item *having= item, *orig_item= item; + select_lex->item_list.empty(); + select_lex->item_list.push_back(new Item_int("Not_used", + (longlong) 1, 21)); + select_lex->ref_pointer_array[0]= select_lex->item_list.head(); item= func->create(expr, item); if (!abort_on_null && orig_item->maybe_null) { @@ -875,9 +875,11 @@ Item_in_subselect::single_value_transformer(JOIN *join, select_lex->having= join->having= func->create(expr, - new Item_null_helper(this, item, - (char *)"<no matter>", - (char *)"<result>")); + new Item_ref_null_helper(this, + select_lex->ref_pointer_array, + (char *)"<no matter>", + (char *)"<result>")); + select_lex->having_fix_field= 1; if (join->having->fix_fields(thd, join->tables_list, 0)) diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index f3d6858755c..5fdbd968df1 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -609,7 +609,7 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time, break; case 'l': days_i= l_time->hour/24; - hours_i= (l_time->hour%24 + 11)%12+1 + 24*days_i; + hours_i= (l_time->hour%24 + 11)%12+1; length= int10_to_str(hours_i, intbuff, 10) - intbuff; str->append_with_prefill(intbuff, length, 1, '0'); break; @@ -620,7 +620,8 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time, case 'r': length= my_sprintf(intbuff, (intbuff, - (l_time->hour < 12) ? "%02d:%02d:%02d AM" : "%02d:%02d:%02d PM", + ((l_time->hour % 24) < 12) ? + "%02d:%02d:%02d AM" : "%02d:%02d:%02d PM", (l_time->hour+11)%12+1, l_time->minute, l_time->second)); @@ -905,9 +906,9 @@ String* Item_func_monthname::val_str(String* str) { DBUG_ASSERT(fixed == 1); const char *month_name; - uint month=(uint) Item_func_month::val_int(); + uint month= (uint) val_int(); - if (!month) // This is also true for NULL + if (null_value || !month) { null_value=1; return (String*) 0; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 6676d994cfa..4bbbb629d20 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1275,6 +1275,29 @@ inline int hexchar_to_int(char c) return -1; } +/* + wrapper to use instead of mysql_bin_log.write when + query is generated by the server using system_charset encoding +*/ + +inline void write_binlog_with_system_charset(THD * thd, Query_log_event * qinfo) +{ + CHARSET_INFO * cs_save= thd->variables.character_set_client; + thd->variables.character_set_client= system_charset_info; + mysql_bin_log.write(qinfo); + thd->variables.character_set_client= cs_save; +} + +/* + is_user_table() + return true if the table was created explicitly +*/ + +inline bool is_user_table(TABLE * table) +{ + const char *name= table->real_name; + return strncmp(name, tmp_file_prefix, tmp_file_prefix_length); +} /* Some functions that are different in the embedded library and the normal diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 740e1a419c7..fc3ca5085cf 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -863,7 +863,20 @@ void kill_mysql(void) DBUG_VOID_RETURN; } - /* Force server down. kill all connections and threads and exit */ +/* + Force server down. Kill all connections and threads and exit + + SYNOPSIS + kill_server + + sig_ptr Signal number that caused kill_server to be called. + + NOTE! + A signal number of 0 mean that the function was not called + from a signal handler and there is thus no signal to block + or stop, we just want to kill the server. + +*/ #if defined(OS2) || defined(__NETWARE__) extern "C" void kill_server(int sig_ptr) @@ -884,7 +897,8 @@ static void __cdecl kill_server(int sig_ptr) RETURN_FROM_KILL_SERVER; kill_in_progress=TRUE; abort_loop=1; // This should be set - my_sigset(sig,SIG_IGN); + if (sig != 0) // 0 is not a valid signal number + my_sigset(sig,SIG_IGN); if (sig == MYSQL_KILL_SIGNAL || sig == 0) sql_print_information(ER(ER_NORMAL_SHUTDOWN),my_progname); else diff --git a/sql/set_var.cc b/sql/set_var.cc index f845cdd0c5d..bf68a102537 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -3207,10 +3207,6 @@ ulong fix_sql_mode(ulong sql_mode) MODE_IGNORE_SPACE | MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS | MODE_NO_FIELD_OPTIONS); - if (sql_mode & MODE_MYSQL40) - sql_mode|= MODE_NO_FIELD_OPTIONS; - if (sql_mode & MODE_MYSQL323) - sql_mode|= MODE_NO_FIELD_OPTIONS; return sql_mode; } diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 4626e5892a4..204a38dfb64 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -894,6 +894,8 @@ static void acl_update_user(const char *user, const char *host, USER_RESOURCES *mqh, ulong privileges) { + safe_mutex_assert_owner(&acl_cache->lock); + for (uint i=0 ; i < acl_users.elements ; i++) { ACL_USER *acl_user=dynamic_element(&acl_users,i,ACL_USER*); @@ -942,6 +944,9 @@ static void acl_insert_user(const char *user, const char *host, ulong privileges) { ACL_USER acl_user; + + safe_mutex_assert_owner(&acl_cache->lock); + acl_user.user=*user ? strdup_root(&mem,user) : 0; update_hostname(&acl_user.host, *host ? strdup_root(&mem, host): 0); acl_user.access=privileges; @@ -973,6 +978,8 @@ static void acl_insert_user(const char *user, const char *host, static void acl_update_db(const char *user, const char *host, const char *db, ulong privileges) { + safe_mutex_assert_owner(&acl_cache->lock); + for (uint i=0 ; i < acl_dbs.elements ; i++) { ACL_DB *acl_db=dynamic_element(&acl_dbs,i,ACL_DB*); @@ -1358,6 +1365,9 @@ find_acl_user(const char *host, const char *user, my_bool exact) { DBUG_ENTER("find_acl_user"); DBUG_PRINT("enter",("host: '%s' user: '%s'",host,user)); + + safe_mutex_assert_owner(&acl_cache->lock); + for (uint i=0 ; i < acl_users.elements ; i++) { ACL_USER *acl_user=dynamic_element(&acl_users,i,ACL_USER*); @@ -1370,7 +1380,7 @@ find_acl_user(const char *host, const char *user, my_bool exact) if (!acl_user->user && !user[0] || acl_user->user && !strcmp(user,acl_user->user)) { - if (exact ? !my_strcasecmp(&my_charset_latin1, host, + if (exact ? !my_strcasecmp(system_charset_info, host, acl_user->host.hostname ? acl_user->host.hostname : "") : compare_hostname(&acl_user->host,host,host)) @@ -2445,6 +2455,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, create_new_users= test_if_create_new_users(thd); int result=0; rw_wrlock(&LOCK_grant); + pthread_mutex_lock(&acl_cache->lock); MEM_ROOT *old_root= thd->mem_root; thd->mem_root= &memex; @@ -2460,10 +2471,8 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, continue; } /* Create user if needed */ - pthread_mutex_lock(&acl_cache->lock); error=replace_user_table(thd, tables[0].table, *Str, 0, revoke_grant, create_new_users); - pthread_mutex_unlock(&acl_cache->lock); if (error) { result= -1; // Remember error @@ -2552,6 +2561,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, } grant_option=TRUE; thd->mem_root= old_root; + pthread_mutex_unlock(&acl_cache->lock); rw_unlock(&LOCK_grant); if (!result) send_ok(thd); @@ -3203,6 +3213,9 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) DBUG_RETURN(-1); } + rw_rdlock(&LOCK_grant); + VOID(pthread_mutex_lock(&acl_cache->lock)); + for (counter=0 ; counter < acl_users.elements ; counter++) { const char *user,*host; @@ -3217,6 +3230,9 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) } if (counter == acl_users.elements) { + VOID(pthread_mutex_unlock(&acl_cache->lock)); + rw_unlock(&LOCK_grant); + my_error(ER_NONEXISTING_GRANT, MYF(0), lex_user->user.str, lex_user->host.str); DBUG_RETURN(-1); @@ -3230,10 +3246,12 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) lex_user->host.str,NullS); field_list.push_back(field); if (protocol->send_fields(&field_list,1)) - DBUG_RETURN(-1); + { + VOID(pthread_mutex_unlock(&acl_cache->lock)); + rw_unlock(&LOCK_grant); - rw_wrlock(&LOCK_grant); - VOID(pthread_mutex_lock(&acl_cache->lock)); + DBUG_RETURN(-1); + } /* Add first global access grants */ { @@ -3540,10 +3558,15 @@ void get_privilege_desc(char *to, uint max_length, ulong access) void get_mqh(const char *user, const char *host, USER_CONN *uc) { ACL_USER *acl_user; + + pthread_mutex_lock(&acl_cache->lock); + if (initialized && (acl_user= find_acl_user(host,user, FALSE))) uc->user_resources= acl_user->user_resource; else bzero((char*) &uc->user_resources, sizeof(uc->user_resources)); + + pthread_mutex_unlock(&acl_cache->lock); } int open_grant_tables(THD *thd, TABLE_LIST *tables) @@ -3602,6 +3625,8 @@ ACL_USER *check_acl_user(LEX_USER *user_name, ACL_USER *acl_user= 0; uint counter; + safe_mutex_assert_owner(&acl_cache->lock); + for (counter= 0 ; counter < acl_users.elements ; counter++) { const char *user,*host; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 60e91aff3f9..4f18b2ea99f 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -493,118 +493,107 @@ static inline uint tmpkeyval(THD *thd, TABLE *table) void close_temporary_tables(THD *thd) { - TABLE *next, - *prev_table /* prev link is not maintained in TABLE's double-linked list */, - *table; - char *query= (gptr) 0, *end; - uint query_buf_size, max_names_len; - bool found_user_tables; - + TABLE *table; if (!thd->temporary_tables) return; - LINT_INIT(end); - query_buf_size= 50; // Enough for DROP ... TABLE IF EXISTS + if (!mysql_bin_log.is_open()) + { + for (table= thd->temporary_tables; table; table= table->next) + { + close_temporary(table, 1); + } + thd->temporary_tables= 0; + return; + } + TABLE *next, + *prev_table /* prev link is not maintained in TABLE's double-linked list */; + bool was_quote_show= true; /* to assume thd->options has OPTION_QUOTE_SHOW_CREATE */ + // Better add "if exists", in case a RESET MASTER has been done + const char stub[]= "DROP /*!40005 TEMPORARY */ TABLE IF EXISTS "; + uint stub_len= sizeof(stub) - 1; + char buf[256]; + memcpy(buf, stub, stub_len); + String s_query= String(buf, sizeof(buf), system_charset_info); + bool found_user_tables= false; + LINT_INIT(next); + /* insertion sort of temp tables by pseudo_thread_id to build ordered list of sublists of equal pseudo_thread_id */ - for (prev_table= thd->temporary_tables, - table= prev_table->next, - found_user_tables= (prev_table->real_name[0] != '#'); + + for (prev_table= thd->temporary_tables, table= prev_table->next; table; prev_table= table, table= table->next) { - TABLE *prev_sorted /* same as for prev_table */, - *sorted; - /* - table not created directly by the user is moved to the tail. - Fixme/todo: nothing (I checked the manual) prevents user to create temp - with `#' - */ - if (table->real_name[0] == '#') - continue; - else - { - found_user_tables = 1; - } - for (prev_sorted= NULL, sorted= thd->temporary_tables; sorted != table; - prev_sorted= sorted, sorted= sorted->next) + TABLE *prev_sorted /* same as for prev_table */, *sorted; + if (is_user_table(table)) { - if (sorted->real_name[0] == '#' || tmpkeyval(thd, sorted) > tmpkeyval(thd, table)) + if (!found_user_tables) + found_user_tables= true; + for (prev_sorted= NULL, sorted= thd->temporary_tables; sorted != table; + prev_sorted= sorted, sorted= sorted->next) { - /* move into the sorted part of the list from the unsorted */ - prev_table->next= table->next; - table->next= sorted; - if (prev_sorted) - { - prev_sorted->next= table; - } - else + if (!is_user_table(sorted) || + tmpkeyval(thd, sorted) > tmpkeyval(thd, table)) { - thd->temporary_tables= table; + /* move into the sorted part of the list from the unsorted */ + prev_table->next= table->next; + table->next= sorted; + if (prev_sorted) + { + prev_sorted->next= table; + } + else + { + thd->temporary_tables= table; + } + table= prev_table; + break; } - table= prev_table; - break; } } - } - /* - calc query_buf_size as max per sublists, one sublist per pseudo thread id. - Also stop at first occurence of `#'-named table that starts - all implicitly created temp tables - */ - for (max_names_len= 0, table=thd->temporary_tables; - table && table->real_name[0] != '#'; - table=table->next) + } + + /* We always quote db,table names though it is slight overkill */ + if (found_user_tables && + !(was_quote_show= (thd->options & OPTION_QUOTE_SHOW_CREATE))) { - uint tmp_names_len; - for (tmp_names_len= table->key_length + 1; - table->next && table->real_name[0] != '#' && - tmpkeyval(thd, table) == tmpkeyval(thd, table->next); - table=table->next) - { - /* - We are going to add 4 ` around the db/table names, so 1 might not look - enough; indeed it is enough, because table->key_length is greater (by 8, - because of server_id and thread_id) than db||table. - */ - tmp_names_len += table->next->key_length + 1; - } - if (tmp_names_len > max_names_len) max_names_len= tmp_names_len; + thd->options |= OPTION_QUOTE_SHOW_CREATE; } - /* allocate */ - if (found_user_tables && mysql_bin_log.is_open() && - (query = alloc_root(thd->mem_root, query_buf_size+= max_names_len))) - // Better add "if exists", in case a RESET MASTER has been done - end= strmov(query, "DROP /*!40005 TEMPORARY */ TABLE IF EXISTS "); - /* scan sorted tmps to generate sequence of DROP */ - for (table=thd->temporary_tables; table; table= next) + for (table= thd->temporary_tables; table; table= next) { - if (query // we might be out of memory, but this is not fatal - && table->real_name[0] != '#') + if (is_user_table(table)) { - char *end_cur; /* Set pseudo_thread_id to be that of the processed table */ thd->variables.pseudo_thread_id= tmpkeyval(thd, table); /* Loop forward through all tables within the sublist of common pseudo_thread_id to create single DROP query */ - for (end_cur= end; - table && table->real_name[0] != '#' && + for (s_query.length(stub_len); + table && is_user_table(table) && tmpkeyval(thd, table) == thd->variables.pseudo_thread_id; table= next) { - end_cur= strxmov(end_cur, "`", table->table_cache_key, "`.`", - table->real_name, "`,", NullS); + /* + We are going to add 4 ` around the db/table names and possible more + due to special characters in the names + */ + append_identifier(thd, &s_query, table->table_cache_key, strlen(table->table_cache_key)); + s_query.q_append('.'); + append_identifier(thd, &s_query, table->real_name, + strlen(table->real_name)); + s_query.q_append(','); next= table->next; close_temporary(table, 1); } thd->clear_error(); - /* The -1 is to remove last ',' */ - Query_log_event qinfo(thd, query, (ulong)(end_cur - query) - 1, 0, FALSE); + Query_log_event qinfo(thd, s_query.ptr(), + s_query.length() - 1 /* to remove trailing ',' */, + 0, FALSE); /* Imagine the thread had created a temp table, then was doing a SELECT, and the SELECT was killed. Then it's not clever to mark the statement above as @@ -615,7 +604,7 @@ void close_temporary_tables(THD *thd) rightfully causing the slave to stop. */ qinfo.error_code= 0; - mysql_bin_log.write(&qinfo); + write_binlog_with_system_charset(thd, &qinfo); } else { @@ -623,6 +612,8 @@ void close_temporary_tables(THD *thd) close_temporary(table, 1); } } + if (!was_quote_show) + thd->options &= ~OPTION_QUOTE_SHOW_CREATE; /* restore option */ thd->temporary_tables=0; } diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 16641ad6dd5..7348816ea27 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1074,6 +1074,7 @@ void st_select_lex::init_query() item_list.empty(); join= 0; where= 0; + having= 0; olap= UNSPECIFIED_OLAP_TYPE; having_fix_field= 0; resolve_mode= NOMATTER_MODE; @@ -1081,6 +1082,7 @@ void st_select_lex::init_query() ref_pointer_array= 0; select_n_having_items= 0; prep_where= 0; + prep_having= 0; subquery_in_having= explicit_limit= 0; parsing_place= NO_MATTER; is_item_list_lookup= 0; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index bd79a194122..35f02db6cf9 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -422,6 +422,7 @@ public: char *db, *db1, *table1, *db2, *table2; /* For outer join using .. */ Item *where, *having; /* WHERE & HAVING clauses */ Item *prep_where; /* saved WHERE clause for prepared statement processing */ + Item *prep_having;/* saved HAVING clause for prepared statement processing */ enum olap_type olap; SQL_LIST table_list, group_list; /* FROM & GROUP BY clauses */ List<Item> item_list; /* list of fields & expressions */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 51ef3f31b26..06005f31198 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3047,8 +3047,8 @@ unsent_create_error: } } - if (!thd->is_fatal_error && (result= new multi_delete(thd,aux_tables, - table_count))) + if (!res && !thd->is_fatal_error && + (result= new multi_delete(thd,aux_tables, table_count))) { res= mysql_select(thd, &select_lex->ref_pointer_array, select_lex->get_table_list(), diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 741d84eab44..2d9e80df63c 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1667,10 +1667,11 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, for (; sl; sl= sl->next_select_in_list()) { /* - Save WHERE clause pointers, because they may be changed + Save WHERE, HAVING clause pointers, because they may be changed during query optimisation. */ sl->prep_where= sl->where; + sl->prep_having= sl->having; /* Switch off a temporary flag that prevents evaluation of subqueries in statement prepare. @@ -1696,13 +1697,18 @@ static void reset_stmt_for_execute(Prepared_statement *stmt) /* remove option which was put by mysql_explain_union() */ sl->options&= ~SELECT_DESCRIBE; /* - Copy WHERE clause pointers to avoid damaging they by optimisation + Copy WHERE, HAVING clause pointers to avoid damaging they by optimisation */ if (sl->prep_where) { sl->where= sl->prep_where->copy_andor_structure(thd); sl->where->cleanup(); } + if (sl->prep_having) + { + sl->having= sl->prep_having->copy_andor_structure(thd); + sl->having->cleanup(); + } DBUG_ASSERT(sl->join == 0); ORDER *order; /* Fix GROUP list */ diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 46dba61cfc5..57fb9738612 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -501,12 +501,24 @@ JOIN::optimize() DBUG_RETURN(1); } - if (cond_value == Item::COND_FALSE || - (!unit->select_limit_cnt && !(select_options & OPTION_FOUND_ROWS))) - { /* Impossible cond */ - zero_result_cause= "Impossible WHERE"; - error= 0; - DBUG_RETURN(0); + { + Item::cond_result having_value; + having= optimize_cond(thd, having, &having_value); + if (thd->net.report_error) + { + error= 1; + DBUG_PRINT("error",("Error from optimize_cond")); + DBUG_RETURN(1); + } + + if (cond_value == Item::COND_FALSE || having_value == Item::COND_FALSE || + (!unit->select_limit_cnt && !(select_options & OPTION_FOUND_ROWS))) + { /* Impossible cond */ + zero_result_cause= having_value == Item::COND_FALSE ? + "Impossible HAVING" : "Impossible WHERE"; + error= 0; + DBUG_RETURN(0); + } } /* Optimize count(*), min() and max() */ @@ -2090,7 +2102,8 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end, new_fields->null_rejecting); } else if (old->eq_func && new_fields->eq_func && - (old->val->is_null() || new_fields->val->is_null())) + ((!old->val->used_tables() && old->val->is_null()) || + new_fields->val->is_null())) { /* field = expression OR field IS NULL */ old->level= and_level; @@ -4611,10 +4624,8 @@ optimize_cond(THD *thd, COND *conds, Item::cond_result *cond_value) DBUG_EXECUTE("info", print_where(conds, "after remove");); } else - { *cond_value= Item::COND_TRUE; - select->prep_where= 0; - } + DBUG_RETURN(conds); } diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 268292022e4..41e145790e9 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1344,8 +1344,8 @@ store_create_info(THD *thd, TABLE *table, String *packet) has_default= (field->type() != FIELD_TYPE_BLOB && field->unireg_check != Field::NEXT_NUMBER && - !((thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40)) && - has_now_default)); + !((thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40)) + && has_now_default)); if (has_default) { @@ -1374,8 +1374,7 @@ store_create_info(THD *thd, TABLE *table, String *packet) packet->append(tmp); } - if (!(thd->variables.sql_mode & MODE_NO_FIELD_OPTIONS) && - table->timestamp_field == field && + if (!limited_mysql_mode && table->timestamp_field == field && field->unireg_check != Field::TIMESTAMP_DN_FIELD) packet->append(" on update CURRENT_TIMESTAMP",28); @@ -1480,6 +1479,24 @@ store_create_info(THD *thd, TABLE *table, String *packet) packet->append(" ENGINE=", 8); packet->append(file->table_type()); + /* + Add AUTO_INCREMENT=... if there is an AUTO_INCREMENT column, + and NEXT_ID > 1 (the default). We must not print the clause + for engines that do not support this as it would break the + import of dumps, but as of this writing, the test for whether + AUTO_INCREMENT columns are allowed and wether AUTO_INCREMENT=... + is supported is identical, !(file->table_flags() & HA_NO_AUTO_INCREMENT)) + Because of that, we do not explicitly test for the feature, + but may extrapolate its existence from that of an AUTO_INCREMENT column. + */ + + if(create_info.auto_increment_value > 1) + { + packet->append(" AUTO_INCREMENT=", 16); + end= longlong10_to_str(create_info.auto_increment_value, buff,10); + packet->append(buff, (uint) (end - buff)); + } + if (table->table_charset && !(thd->variables.sql_mode & MODE_MYSQL323) && !(thd->variables.sql_mode & MODE_MYSQL40)) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index c9513ec71ab..631d2d89bbb 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -601,7 +601,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, if (need_to_change_arena) thd->restore_backup_item_arena(thd->current_arena, &backup_arena); - if (! sql_field->def) + if (sql_field->def == NULL) { /* Could not convert */ my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); @@ -611,15 +611,30 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, if (sql_field->sql_type == FIELD_TYPE_SET) { - if (sql_field->def) + if (sql_field->def != NULL) { char *not_used; uint not_used2; bool not_found= 0; String str, *def= sql_field->def->val_str(&str); - def->length(cs->cset->lengthsp(cs, def->ptr(), def->length())); - (void) find_set(interval, def->ptr(), def->length(), - cs, ¬_used, ¬_used2, ¬_found); + if (def == NULL) /* SQL "NULL" maps to NULL */ + { + if ((sql_field->flags & NOT_NULL_FLAG) != 0) + { + my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); + DBUG_RETURN(-1); + } + + /* else, NULL is an allowed value */ + (void) find_set(interval, NULL, 0, + cs, ¬_used, ¬_used2, ¬_found); + } + else /* not NULL */ + { + (void) find_set(interval, def->ptr(), def->length(), + cs, ¬_used, ¬_used2, ¬_found); + } + if (not_found) { my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); @@ -631,14 +646,28 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, } else /* FIELD_TYPE_ENUM */ { - if (sql_field->def) + DBUG_ASSERT(sql_field->sql_type == FIELD_TYPE_ENUM); + if (sql_field->def != NULL) { String str, *def= sql_field->def->val_str(&str); - def->length(cs->cset->lengthsp(cs, def->ptr(), def->length())); - if (!find_type2(interval, def->ptr(), def->length(), cs)) + if (def == NULL) /* SQL "NULL" maps to NULL */ { - my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); - DBUG_RETURN(-1); + if ((sql_field->flags & NOT_NULL_FLAG) != 0) + { + my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); + DBUG_RETURN(-1); + } + + /* else, the defaults yield the correct length for NULLs. */ + } + else /* not NULL */ + { + def->length(cs->cset->lengthsp(cs, def->ptr(), def->length())); + if (find_type2(interval, def->ptr(), def->length(), cs) == 0) /* not found */ + { + my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); + DBUG_RETURN(-1); + } } } calculate_interval_lengths(cs, interval, &sql_field->length, &dummy); @@ -1677,7 +1706,9 @@ mysql_rename_table(enum db_type base, } } delete file; - if (error) + if (error == HA_ERR_WRONG_COMMAND) + my_error(ER_NOT_SUPPORTED_YET, MYF(0), "ALTER TABLE"); + else if (error) my_error(ER_ERROR_ON_RENAME, MYF(0), from, to, error); DBUG_RETURN(error != 0); } @@ -2164,10 +2195,15 @@ send_result_message: table->table->version=0; // Force close of table else if (open_for_modify) { - pthread_mutex_lock(&LOCK_open); - remove_table_from_cache(thd, table->table->table_cache_key, - table->table->real_name, RTFC_NO_FLAG); - pthread_mutex_unlock(&LOCK_open); + if (table->table->tmp_table) + table->table->file->info(HA_STATUS_CONST); + else + { + pthread_mutex_lock(&LOCK_open); + remove_table_from_cache(thd, table->table->table_cache_key, + table->table->real_name, RTFC_NO_FLAG); + pthread_mutex_unlock(&LOCK_open); + } /* May be something modified consequently we have to invalidate cache */ query_cache_invalidate3(thd, table->table, 0); } diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index b161ec13073..9656851dc9c 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -28,7 +28,7 @@ Release: %{release} License: %{license} Source: http://www.mysql.com/Downloads/MySQL-@MYSQL_BASE_VERSION@/mysql-%{mysql_version}.tar.gz URL: http://www.mysql.com/ -Packager: Lenz Grimmer <build@mysql.com> +Packager: MySQL Production Engineering Team <build@mysql.com> Vendor: MySQL AB Provides: msqlormysql MySQL-server mysql BuildRequires: ncurses-devel @@ -238,8 +238,8 @@ sh -c "PATH=\"${MYSQL_BUILD_PATH:-$PATH}\" \ --enable-local-infile \ --with-mysqld-user=%{mysqld_user} \ --with-unix-socket-path=/var/lib/mysql/mysql.sock \ + --with-pic \ --prefix=/ \ - --with-extra-charsets=complex \ --exec-prefix=%{_exec_prefix} \ --libexecdir=%{_sbindir} \ --libdir=%{_libdir} \ @@ -297,7 +297,7 @@ then fi BuildMySQL "--enable-shared \ - --without-openssl \ + --with-extra-charsets=all \ --with-berkeley-db \ --with-innodb \ --with-ndbcluster \ @@ -307,16 +307,23 @@ BuildMySQL "--enable-shared \ --with-example-storage-engine \ --with-blackhole-storage-engine \ --with-embedded-server \ - --with-comment=\"MySQL Community Edition - Max (GPL)\" \ - --with-server-suffix='-Max'" + --with-comment=\"MySQL Community Edition - Experimental (GPL)\" \ + --with-server-suffix='-max'" + +# We might want to save the config log file +if test -n "$MYSQL_MAXCONFLOG_DEST" +then + cp -fp config.log "$MYSQL_MAXCONFLOG_DEST" +fi make -i test-force || true # Save mysqld-max -mv sql/mysqld sql/mysqld-max -nm --numeric-sort sql/mysqld-max > sql/mysqld-max.sym +./libtool --mode=execute cp sql/mysqld sql/mysqld-max +./libtool --mode=execute nm --numeric-sort sql/mysqld-max > sql/mysqld-max.sym + # Save the perror binary so it supports the NDB error codes (BUG#13740) -mv extra/perror extra/perror.ndb +./libtool --mode=execute cp extra/perror extra/perror.ndb # Install the ndb binaries (cd ndb; make install DESTDIR=$RBR) @@ -355,6 +362,7 @@ BuildMySQL "--disable-shared \ %else --with-zlib-dir=bundled \ %endif + --with-extra-charsets=complex \ --with-comment=\"MySQL Community Edition - Standard (GPL)\" \ --with-server-suffix='%{server_suffix}' \ --without-embedded-server \ @@ -362,7 +370,14 @@ BuildMySQL "--disable-shared \ --with-innodb \ --without-vio \ --without-openssl" -nm --numeric-sort sql/mysqld > sql/mysqld.sym + +./libtool --mode=execute nm --numeric-sort sql/mysqld > sql/mysqld.sym + +# We might want to save the config log file +if test -n "$MYSQL_CONFLOG_DEST" +then + cp -fp config.log "$MYSQL_CONFLOG_DEST" +fi make -i test-force || true @@ -456,7 +471,7 @@ usermod -g %{mysqld_group} %{mysqld_user} 2> /dev/null || true # owns all database files. chown -R %{mysqld_user}:%{mysqld_group} $mysql_datadir -# Initiate databases +# Initiate databases if needed %{_bindir}/mysql_install_db --rpm --user=%{mysqld_user} # Change permissions again to fix any new files. @@ -543,31 +558,31 @@ fi %attr(755, root, root) %{_bindir}/isamchk %attr(755, root, root) %{_bindir}/isamlog -%attr(755, root, root) %{_bindir}/myisamchk +%attr(755, root, root) %{_bindir}/my_print_defaults %attr(755, root, root) %{_bindir}/myisam_ftdump +%attr(755, root, root) %{_bindir}/myisamchk %attr(755, root, root) %{_bindir}/myisamlog %attr(755, root, root) %{_bindir}/myisampack -%attr(755, root, root) %{_bindir}/my_print_defaults -%attr(755, root, root) %{_bindir}/mysqlbug %attr(755, root, root) %{_bindir}/mysql_convert_table_format %attr(755, root, root) %{_bindir}/mysql_create_system_tables -%attr(755, root, root) %{_bindir}/mysqld_multi -%attr(755, root, root) %{_bindir}/mysqld_safe %attr(755, root, root) %{_bindir}/mysql_explain_log %attr(755, root, root) %{_bindir}/mysql_fix_extensions %attr(755, root, root) %{_bindir}/mysql_fix_privilege_tables -%attr(755, root, root) %{_bindir}/mysqlhotcopy %attr(755, root, root) %{_bindir}/mysql_install_db %attr(755, root, root) %{_bindir}/mysql_secure_installation %attr(755, root, root) %{_bindir}/mysql_setpermission -%attr(755, root, root) %{_bindir}/mysqltest %attr(755, root, root) %{_bindir}/mysql_tzinfo_to_sql %attr(755, root, root) %{_bindir}/mysql_zap +%attr(755, root, root) %{_bindir}/mysqlbug +%attr(755, root, root) %{_bindir}/mysqld_multi +%attr(755, root, root) %{_bindir}/mysqld_safe +%attr(755, root, root) %{_bindir}/mysqlhotcopy +%attr(755, root, root) %{_bindir}/mysqltest %attr(755, root, root) %{_bindir}/pack_isam %attr(755, root, root) %{_bindir}/perror %attr(755, root, root) %{_bindir}/replace -%attr(755, root, root) %{_bindir}/resolveip %attr(755, root, root) %{_bindir}/resolve_stack_dump +%attr(755, root, root) %{_bindir}/resolveip %attr(755, root, root) %{_bindir}/safe_mysqld %attr(755, root, root) %{_sbindir}/mysqld @@ -630,6 +645,7 @@ fi %attr(755, root, root) %{_bindir}/ndb_desc %attr(755, root, root) %{_bindir}/ndb_show_tables %attr(755, root, root) %{_bindir}/ndb_test_platform +%attr(755, root, root) %{_bindir}/ndb_config %files ndb-extra %defattr(-,root,root,0755) @@ -662,6 +678,11 @@ fi %{_libdir}/mysql/libmysys.a %{_libdir}/mysql/libnisam.a %{_libdir}/mysql/libvio.a +%if %{STATIC_BUILD} +%else +%{_libdir}/mysql/libz.a +%{_libdir}/mysql/libz.la +%endif %files shared %defattr(-, root, root, 0755) @@ -690,15 +711,45 @@ fi # itself - note that they must be ordered by date (important when # merging BK trees) %changelog +* Sat May 20 2006 Kent Boortz <kent@mysql.com> + +- Always compile for PIC, position independent code. + +* Wed May 10 2006 Kent Boortz <kent@mysql.com> + +- Use character set "all" for the "max", to make Cluster nodes + independent on the character set directory, and the problem that + two RPM sub packages both wants to install this directory. + +* Mon May 01 2006 Kent Boortz <kent@mysql.com> + +- Use "./libtool --mode=execute" instead of searching for the + executable in current directory and ".libs". + * Sat Apr 01 2006 Kent Boortz <kent@mysql.com> - Set $LDFLAGS from $MYSQL_BUILD_LDFLAGS +* Fri Mar 03 2006 Kent Boortz <kent@mysql.com> + +- Can't use bundled zlib when doing static build. Might be a + automake/libtool problem, having two .la files, "libmysqlclient.la" + and "libz.la", on the same command line to link "thread_test" + expands to too many "-lc", "-lpthread" and other libs giving hard + to nail down duplicate symbol defintion problems. + * Fri Jan 10 2006 Joerg Bruehe <joerg@mysql.com> - Use "-i" on "make test-force"; this is essential for later evaluation of this log file. +* Fri Dec 12 2005 Rodrigo Novo <rodrigo@mysql.com> + +- Added zlib to the list of (static) libraries installed +- Added check against libtool wierdness (WRT: sql/mysqld || sql/.libs/mysqld) +- Compile MySQL with bundled zlib +- Fixed %packager name to "MySQL Production Engineering Team" + * Mon Dec 05 2005 Joerg Bruehe <joerg@mysql.com> - Avoid using the "bundled" zlib on "shared" builds: |