From cba07d5bfd547319fd5866d76170e18639827bdc Mon Sep 17 00:00:00 2001 From: Karen Langford Date: Wed, 26 Oct 2011 17:03:53 +0200 Subject: [PATCH 001/135] Raise version number after cloning 5.1.60 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 120717d6afa..080de523c1b 100644 --- a/configure.in +++ b/configure.in @@ -12,7 +12,7 @@ dnl dnl When changing the major version number please also check the switch dnl statement in mysqlbinlog::check_master_version(). You may also need dnl to update version.c in ndb. -AC_INIT([MySQL Server], [5.1.60], [], [mysql]) +AC_INIT([MySQL Server], [5.1.61], [], [mysql]) AC_CONFIG_SRCDIR([sql/mysqld.cc]) AC_CANONICAL_SYSTEM From 9f9b5996f51c27cdfa10dbe7f1c36d8184c9f208 Mon Sep 17 00:00:00 2001 From: Jon Olav Hauglid Date: Tue, 22 Nov 2011 14:16:13 +0100 Subject: [PATCH 002/135] Disabling main.query_cache_28249.test since this test fails sporadically on 5.1. See Bug#12584161. Test runs successfully on 5.5/trunk, so this changeset will be null-merged. --- mysql-test/t/disabled.def | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index 84c981c08c1..bfa051de4b6 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -12,4 +12,4 @@ kill : Bug#11748945 2008-12-03 HHunger need some changes to be robust enough for pushbuild. read_many_rows_innodb : Bug#11748886 2010-11-15 mattiasj report already exists main.log_tables-big : Bug#11756699 2010-11-15 mattiasj report already exists - +query_cache_28249 : Bug#12584161 2011-11-17 joh fails sporadically in 5.1 only From a00f87bf155fda703ffd314e5d8166583db92d93 Mon Sep 17 00:00:00 2001 From: Ashish Agarwal Date: Wed, 23 Nov 2011 18:33:29 +0530 Subject: [PATCH 003/135] BUG#11751793 - 42784: ARCHIVE TABLES CAUSE 100% CPU USAGE AND HANG IN SHOW TABLE STATUS. ISSUE: Table corruption due to concurrent queries. Different threads running insert and check query leads to table corruption. Not properly locked, rows are inserted in between check query. SOLUTION: In check query mutex lock is acquired for a longer time to handle concurrent insert and check query. NOTE: Additionally we backported the fix for CHECKSUM issue(bug#11758979). --- mysql-test/r/archive.result | 19 ++++++++++++++ mysql-test/t/archive.test | 14 ++++++++++ storage/archive/ha_archive.cc | 48 ++++++++++++++++++++++++++++------- 3 files changed, 72 insertions(+), 9 deletions(-) diff --git a/mysql-test/r/archive.result b/mysql-test/r/archive.result index 15ded03f414..69f5adf5b5d 100644 --- a/mysql-test/r/archive.result +++ b/mysql-test/r/archive.result @@ -12772,3 +12772,22 @@ a b c d e f -1 b c d e 1 DROP TABLE t1; SET sort_buffer_size=DEFAULT; +# +# BUG#11758979 - 51252: ARCHIVE TABLES CAUSE 100% CPU USAGE +# AND HANG IN SHOW TABLE STATUS +# (to be executed with valgrind) +CREATE TABLE t1(a BLOB, b VARCHAR(200)) ENGINE=ARCHIVE; +INSERT INTO t1 VALUES(NULL, ''); +FLUSH TABLE t1; +# we need this select to workaround BUG#11764364 +SELECT * FROM t1; +a b +NULL +CHECKSUM TABLE t1 EXTENDED; +Table Checksum +test.t1 286155052 +FLUSH TABLE t1; +OPTIMIZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 optimize status OK +DROP TABLE t1; diff --git a/mysql-test/t/archive.test b/mysql-test/t/archive.test index 98ba5e03ede..0364c95db0b 100644 --- a/mysql-test/t/archive.test +++ b/mysql-test/t/archive.test @@ -1693,3 +1693,17 @@ INSERT INTO t1 SELECT t1.* FROM t1,t1 t2,t1 t3,t1 t4,t1 t5,t1 t6; SELECT * FROM t1 ORDER BY f LIMIT 1; DROP TABLE t1; SET sort_buffer_size=DEFAULT; + +--echo # +--echo # BUG#11758979 - 51252: ARCHIVE TABLES CAUSE 100% CPU USAGE +--echo # AND HANG IN SHOW TABLE STATUS +--echo # (to be executed with valgrind) +CREATE TABLE t1(a BLOB, b VARCHAR(200)) ENGINE=ARCHIVE; +INSERT INTO t1 VALUES(NULL, ''); +FLUSH TABLE t1; +--echo # we need this select to workaround BUG#11764364 +SELECT * FROM t1; +CHECKSUM TABLE t1 EXTENDED; +FLUSH TABLE t1; +OPTIMIZE TABLE t1; +DROP TABLE t1; diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index df5bd8bafb1..79053f284b3 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -760,6 +760,7 @@ uint32 ha_archive::max_row_length(const uchar *buf) ptr != end ; ptr++) { + if (!table->field[*ptr]->is_null()) length += 2 + ((Field_blob*)table->field[*ptr])->get_length(); } @@ -1110,6 +1111,17 @@ int ha_archive::unpack_row(azio_stream *file_to_read, uchar *record) /* Copy null bits */ const uchar *ptr= record_buffer->buffer; + /* + Field::unpack() is not called when field is NULL. For VARCHAR + Field::unpack() only unpacks as much bytes as occupied by field + value. In these cases respective memory area on record buffer is + not initialized. + + These uninitialized areas may be accessed by CHECKSUM TABLE or + by optimizer using temporary table (BUG#12997905). We may remove + this memset() when they're fixed. + */ + memset(record, 0, table->s->reclength); memcpy(record, ptr, table->s->null_bytes); ptr+= table->s->null_bytes; for (Field **field=table->field ; *field ; field++) @@ -1578,13 +1590,15 @@ int ha_archive::check(THD* thd, HA_CHECK_OPT* check_opt) { int rc= 0; const char *old_proc_info; - ha_rows count= share->rows_recorded; + ha_rows count; DBUG_ENTER("ha_archive::check"); old_proc_info= thd_proc_info(thd, "Checking table"); - /* Flush any waiting data */ pthread_mutex_lock(&share->mutex); - azflush(&(share->archive_write), Z_SYNC_FLUSH); + count= share->rows_recorded; + /* Flush any waiting data */ + if (share->archive_write_open) + azflush(&(share->archive_write), Z_SYNC_FLUSH); pthread_mutex_unlock(&share->mutex); if (init_archive_reader()) @@ -1594,18 +1608,34 @@ int ha_archive::check(THD* thd, HA_CHECK_OPT* check_opt) start of the file. */ read_data_header(&archive); + for (ha_rows cur_count= count; cur_count; cur_count--) + { + if ((rc= get_row(&archive, table->record[0]))) + goto error; + } + /* + Now read records that may have been inserted concurrently. + Acquire share->mutex so tail of the table is not modified by + concurrent writers. + */ + pthread_mutex_lock(&share->mutex); + count= share->rows_recorded - count; + if (share->archive_write_open) + azflush(&(share->archive_write), Z_SYNC_FLUSH); while (!(rc= get_row(&archive, table->record[0]))) count--; - - thd_proc_info(thd, old_proc_info); + pthread_mutex_unlock(&share->mutex); if ((rc && rc != HA_ERR_END_OF_FILE) || count) - { - share->crashed= FALSE; - DBUG_RETURN(HA_ADMIN_CORRUPT); - } + goto error; + thd_proc_info(thd, old_proc_info); DBUG_RETURN(HA_ADMIN_OK); + +error: + thd_proc_info(thd, old_proc_info); + share->crashed= FALSE; + DBUG_RETURN(HA_ADMIN_CORRUPT); } /* From c67a91f11afd730ab050e3c5da16411b95c325a7 Mon Sep 17 00:00:00 2001 From: Nirbhay Choubey Date: Tue, 29 Nov 2011 17:59:35 +0530 Subject: [PATCH 004/135] Bug#11756764 48726: MYSQLD KEEPS CRASHING WITH SIGSEGV WITH MYISAM_USE_MMAP ENABLED MySQL server can crash due to segmentation fault when started with myisam_use_mmap. The reason behind this being, while making a request to unmap (munmap) the previously mapped memory (mmap), the size passed was 7 bytes larger than the size requested at the time of mapping. This can eventually unmap the adjacent memory mapped block, belonging to some other memory-map pool. Hence the subsequent call to mmap can map a region which was still a valid memory mapped area. Fixed by removing the extra 7-byte margin which was erroneously added to the size, used for unmappping. storage/myisam/mi_close.c: Bug#11756764 48726: MYSQLD KEEPS CRASHING WITH SIGSEGV WITH MYISAM_USE_MMAP ENABLED Added a condition to call _mi_unmap_file() in case of compressed records. mi_munmap_file() is called otherwise. storage/myisam/mi_packrec.c: Bug#11756764 48726: MYSQLD KEEPS CRASHING WITH SIGSEGV WITH MYISAM_USE_MMAP ENABLED mi_dynmap_file() function, after successfully executing mmap, stores the total size in info->s->mapped_length variable. Now, if mi_dynmap_file() is invoked with a size with an extra 7-byte margin (MEMMAP_EXTRA_MARGIN), the margin will eventually also get stored in mapped_length. So, un-mapping function can simply use the value stored in mapped_length in order to unmap the previously mapped region. --- storage/myisam/mi_close.c | 7 ++++++- storage/myisam/mi_packrec.c | 7 ++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/storage/myisam/mi_close.c b/storage/myisam/mi_close.c index bb95aff24d7..a6911814608 100644 --- a/storage/myisam/mi_close.c +++ b/storage/myisam/mi_close.c @@ -87,7 +87,12 @@ int mi_close(register MI_INFO *info) } #ifdef HAVE_MMAP if (share->file_map) - _mi_unmap_file(info); + { + if (share->options & HA_OPTION_COMPRESS_RECORD) + _mi_unmap_file(info); + else + mi_munmap_file(info); + } #endif if (share->decode_trees) { diff --git a/storage/myisam/mi_packrec.c b/storage/myisam/mi_packrec.c index e6ad4c3defc..005f8c65d71 100644 --- a/storage/myisam/mi_packrec.c +++ b/storage/myisam/mi_packrec.c @@ -1553,13 +1553,14 @@ my_bool _mi_memmap_file(MI_INFO *info) void _mi_unmap_file(MI_INFO *info) { - VOID(my_munmap((char*) info->s->file_map, - (size_t) info->s->mmaped_length + MEMMAP_EXTRA_MARGIN)); + DBUG_ASSERT(info->s->options & HA_OPTION_COMPRESS_RECORD); + + VOID(my_munmap((char*) info->s->file_map, (size_t) info->s->mmaped_length)); if (myisam_mmap_size != SIZE_T_MAX) { pthread_mutex_lock(&THR_LOCK_myisam_mmap); - myisam_mmap_used-= info->s->mmaped_length + MEMMAP_EXTRA_MARGIN; + myisam_mmap_used-= info->s->mmaped_length; pthread_mutex_unlock(&THR_LOCK_myisam_mmap); } } From 98adda50958504db0439ad6c72c96d663fb99bec Mon Sep 17 00:00:00 2001 From: Tor Didriksen Date: Tue, 29 Nov 2011 15:52:47 +0100 Subject: [PATCH 005/135] Build broken for gcc 4.5.1 in optimized mode. readline.cc: In function char* batch_readline(LINE_BUFFER*): readline.cc:60:9: error: out_length may be used uninitialized in this function log.cc: In function int find_uniq_filename(char*): log.cc:1857:8: error: number may be used uninitialized in this function --- client/readline.cc | 2 +- sql/log.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/readline.cc b/client/readline.cc index 0f3fab7e43d..7765a62766f 100644 --- a/client/readline.cc +++ b/client/readline.cc @@ -57,7 +57,7 @@ LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file) char *batch_readline(LINE_BUFFER *line_buff) { char *pos; - ulong out_length; + ulong out_length= 0; if (!(pos=intern_read_line(line_buff, &out_length))) return 0; diff --git a/sql/log.cc b/sql/log.cc index 77d12641442..cca403ca1be 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1854,7 +1854,7 @@ static void setup_windows_event_source() static int find_uniq_filename(char *name) { - long number; + long number= 0; uint i; char buff[FN_REFLEN]; struct st_my_dir *dir_info; From 9a15f2492b1bccfa085a19c252ed5224c1fde3b2 Mon Sep 17 00:00:00 2001 From: Tor Didriksen Date: Wed, 30 Nov 2011 15:39:29 +0100 Subject: [PATCH 006/135] Bug#11761576 54082: HANDLE_SEGFAULT MAKES USE OF UNSAFE FUNCTIONS handle_segfault is the signal handler code of mysqld. however, it makes calls to potentially unsafe functions localtime_r, fprintf, fflush. include/my_stacktrace.h: Add safe versions of itoa() write() and snprintf(). libmysqld/CMakeLists.txt: Move signal handler to separate file. mysys/stacktrace.c: Remove unsafe function calls. sql/CMakeLists.txt: Move signal handler to separate file. sql/Makefile.am: Move signal handler to separate file. sql/mysqld.cc: Move signal handler to separate file. sql/signal_handler.cc: Remove unsafe function calls. --- include/my_stacktrace.h | 69 +++++++- libmysqld/CMakeLists.txt | 1 + mysys/stacktrace.c | 341 +++++++++++++++++++++++++++++++-------- sql/CMakeLists.txt | 3 +- sql/Makefile.am | 1 + sql/mysqld.cc | 190 +++------------------- sql/signal_handler.cc | 257 +++++++++++++++++++++++++++++ 7 files changed, 620 insertions(+), 242 deletions(-) create mode 100644 sql/signal_handler.cc diff --git a/include/my_stacktrace.h b/include/my_stacktrace.h index e7713f46fc3..30cac3871c5 100644 --- a/include/my_stacktrace.h +++ b/include/my_stacktrace.h @@ -1,5 +1,4 @@ -/* - Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -12,8 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _my_stacktrace_h_ #define _my_stacktrace_h_ @@ -63,6 +61,69 @@ void my_set_exception_pointers(EXCEPTION_POINTERS *ep); void my_write_core(int sig); #endif + + +/** + Async-signal-safe utility functions used by signal handler routines. + Declared here in order to unit-test them. + These are not general-purpose, but tailored to the signal handling routines. +*/ +/** + Converts a longlong value to string. + @param base 10 for decimal, 16 for hex values (0..9a..f) + @param val The value to convert + @param buf Assumed to point to the *end* of the buffer. + @returns Pointer to the first character of the converted string. + Negative values: + for base-10 the return string will be prepended with '-' + for base-16 the return string will contain 16 characters + Implemented with simplicity, and async-signal-safety in mind. +*/ +char *my_safe_itoa(int base, longlong val, char *buf); + +/** + Converts a ulonglong value to string. + @param base 10 for decimal, 16 for hex values (0..9a..f) + @param val The value to convert + @param buf Assumed to point to the *end* of the buffer. + @returns Pointer to the first character of the converted string. + Implemented with simplicity, and async-signal-safety in mind. +*/ +char *my_safe_utoa(int base, ulonglong val, char *buf); + +/** + A (very) limited version of snprintf. + @param to Destination buffer. + @param n Size of destination buffer. + @param fmt printf() style format string. + @returns Number of bytes written, including terminating '\0' + Supports 'd' 'i' 'u' 'x' 'p' 's' conversion. + Supports 'l' and 'll' modifiers for integral types. + Does not support any width/precision. + Implemented with simplicity, and async-signal-safety in mind. +*/ +size_t my_safe_snprintf(char* to, size_t n, const char* fmt, ...) + ATTRIBUTE_FORMAT(printf, 3, 4); + +/** + A (very) limited version of snprintf, which writes the result to STDERR. + @sa my_safe_snprintf + Implemented with simplicity, and async-signal-safety in mind. + @note Has an internal buffer capacity of 512 bytes, + which should suffice for our signal handling routines. +*/ +size_t my_safe_printf_stderr(const char* fmt, ...) + ATTRIBUTE_FORMAT(printf, 1, 2); + +/** + Writes up to count bytes from buffer to STDERR. + Implemented with simplicity, and async-signal-safety in mind. + @param buf Buffer containing data to be written. + @param count Number of bytes to write. + @returns Number of bytes written. +*/ +size_t my_write_stderr(const void *buf, size_t count); + C_MODE_END #endif /* _my_stacktrace_h_ */ diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt index 344079cd61e..a1a3dbd6658 100644 --- a/libmysqld/CMakeLists.txt +++ b/libmysqld/CMakeLists.txt @@ -109,6 +109,7 @@ SET(LIBMYSQLD_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc ../sql/password.c ../sql/discover.cc ../sql/derror.cc ../sql/field.cc ../sql/field_conv.cc ../sql/filesort.cc ../sql/gstream.cc ../sql/ha_partition.cc + ../sql/signal_handler.cc ../sql/handler.cc ../sql/hash_filo.cc ../sql/hostname.cc ../sql/init.cc ../sql/item_buff.cc ../sql/item_cmpfunc.cc ../sql/item.cc ../sql/item_create.cc ../sql/item_func.cc diff --git a/mysys/stacktrace.c b/mysys/stacktrace.c index 95f06937faa..b2eae0fb4c6 100644 --- a/mysys/stacktrace.c +++ b/mysys/stacktrace.c @@ -1,5 +1,4 @@ -/* - Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -12,8 +11,8 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + /* Workaround for Bug#32082: VOID redefinition on Win results in compile errors*/ #define DONT_DEFINE_VOID 1 @@ -57,10 +56,11 @@ void my_init_stacktrace() static void print_buffer(char *buffer, size_t count) { + const char s[]= " "; for (; count && *buffer; --count) { - int c= (int) *buffer++; - fputc(isprint(c) ? c : ' ', stderr); + my_write_stderr(isprint(*buffer) ? buffer : s, 1); + ++buffer; } } @@ -124,10 +124,10 @@ static int safe_print_str(const char *addr, int max_len) /* Output a new line if something was printed. */ if (total != (size_t) max_len) - fputc('\n', stderr); + my_safe_printf_stderr("%s", "\n"); if (nbytes == -1) - fprintf(stderr, "Can't read from address %p: %m.\n", addr); + my_safe_printf_stderr("Can't read from address %p\n", addr); close(fd); @@ -149,13 +149,13 @@ void my_safe_print_str(const char* val, int max_len) if (!PTR_SANE(val)) { - fprintf(stderr, "is an invalid pointer\n"); + my_safe_printf_stderr("%s", "is an invalid pointer\n"); return; } for (; max_len && PTR_SANE(val) && *val; --max_len) - fputc(*val++, stderr); - fputc('\n', stderr); + my_write_stderr((val++), 1); + my_safe_printf_stderr("%s", "\n"); } #if defined(HAVE_PRINTSTACK) @@ -167,14 +167,15 @@ void my_print_stacktrace(uchar* stack_bottom __attribute__((unused)), ulong thread_stack __attribute__((unused))) { if (printstack(fileno(stderr)) == -1) - fprintf(stderr, "Error when traversing the stack, stack appears corrupt.\n"); + my_safe_printf_stderr("%s", + "Error when traversing the stack, stack appears corrupt.\n"); else - fprintf(stderr, - "Please read " - "http://dev.mysql.com/doc/refman/5.1/en/resolve-stack-dump.html\n" - "and follow instructions on how to resolve the stack trace.\n" - "Resolved stack trace is much more helpful in diagnosing the\n" - "problem, so please do resolve it\n"); + my_safe_printf_stderr("%s" + "Please read " + "http://dev.mysql.com/doc/refman/5.1/en/resolve-stack-dump.html\n" + "and follow instructions on how to resolve the stack trace.\n" + "Resolved stack trace is much more helpful in diagnosing the\n" + "problem, so please do resolve it\n"); } #elif HAVE_BACKTRACE && (HAVE_BACKTRACE_SYMBOLS || HAVE_BACKTRACE_SYMBOLS_FD) @@ -212,9 +213,9 @@ static void my_demangle_symbols(char **addrs, int n) } if (demangled) - fprintf(stderr, "%s(%s+%s\n", addrs[i], demangled, end); + my_safe_printf_stderr("%s(%s+%s\n", addrs[i], demangled, end); else - fprintf(stderr, "%s\n", addrs[i]); + my_safe_printf_stderr("%s\n", addrs[i]); } } @@ -225,8 +226,8 @@ void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack) void *addrs[128]; char **strings= NULL; int n = backtrace(addrs, array_elements(addrs)); - fprintf(stderr, "stack_bottom = %p thread_stack 0x%lx\n", - stack_bottom, thread_stack); + my_safe_printf_stderr("stack_bottom = %p thread_stack 0x%lx\n", + stack_bottom, thread_stack); #if BACKTRACE_DEMANGLE if ((strings= backtrace_symbols(addrs, n))) { @@ -319,8 +320,9 @@ void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack) #endif if (!fp) { - fprintf(stderr, "frame pointer is NULL, did you compile with\n\ --fomit-frame-pointer? Aborting backtrace!\n"); + my_safe_printf_stderr("%s", + "frame pointer is NULL, did you compile with\n" + "-fomit-frame-pointer? Aborting backtrace!\n"); return; } @@ -328,24 +330,28 @@ void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack) { ulong tmp= min(0x10000,thread_stack); /* Assume that the stack starts at the previous even 65K */ - stack_bottom= (uchar*) (((ulong) &fp + tmp) & - ~(ulong) 0xFFFF); - fprintf(stderr, "Cannot determine thread, fp=%p, backtrace may not be correct.\n", fp); + stack_bottom= (uchar*) (((ulong) &fp + tmp) & ~(ulong) 0xFFFF); + my_safe_printf_stderr("Cannot determine thread, fp=%p, " + "backtrace may not be correct.\n", fp); } if (fp > (uchar**) stack_bottom || fp < (uchar**) stack_bottom - thread_stack) { - fprintf(stderr, "Bogus stack limit or frame pointer,\ - fp=%p, stack_bottom=%p, thread_stack=%ld, aborting backtrace.\n", - fp, stack_bottom, thread_stack); + my_safe_printf_stderr("Bogus stack limit or frame pointer, " + "fp=%p, stack_bottom=%p, thread_stack=%ld, " + "aborting backtrace.\n", + fp, stack_bottom, thread_stack); return; } - fprintf(stderr, "Stack range sanity check OK, backtrace follows:\n"); + my_safe_printf_stderr("%s", + "Stack range sanity check OK, backtrace follows:\n"); #if defined(__alpha__) && defined(__GNUC__) - fprintf(stderr, "Warning: Alpha stacks are difficult -\ - will be taking some wild guesses, stack trace may be incorrect or \ - terminate abruptly\n"); + my_safe_printf_stderr("%s", + "Warning: Alpha stacks are difficult -" + "will be taking some wild guesses, stack trace may be incorrect or " + "terminate abruptly\n"); + /* On Alpha, we need to get pc */ __asm __volatile__ ("bsr %0, do_next; do_next: " :"=r"(pc) @@ -359,8 +365,9 @@ void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack) { #if defined(__i386__) || defined(__x86_64__) uchar** new_fp = (uchar**)*fp; - fprintf(stderr, "%p\n", frame_count == sigreturn_frame_count ? - *(fp + SIGRETURN_FRAME_OFFSET) : *(fp + 1)); + my_safe_printf_stderr("%p\n", + frame_count == sigreturn_frame_count ? + *(fp + SIGRETURN_FRAME_OFFSET) : *(fp + 1)); #endif /* defined(__386__) || defined(__x86_64__) */ #if defined(__alpha__) && defined(__GNUC__) @@ -374,38 +381,40 @@ void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack) { pc = find_prev_pc(pc, fp); if (pc) - fprintf(stderr, "%p\n", pc); + my_safe_printf_stderr("%p\n", pc); else { - fprintf(stderr, "Not smart enough to deal with the rest\ - of this stack\n"); + my_safe_printf_stderr("%s", + "Not smart enough to deal with the rest of this stack\n"); goto end; } } else { - fprintf(stderr, "Not smart enough to deal with the rest of this stack\n"); + my_safe_printf_stderr("%s", + "Not smart enough to deal with the rest of this stack\n"); goto end; } #endif /* defined(__alpha__) && defined(__GNUC__) */ if (new_fp <= fp ) { - fprintf(stderr, "New value of fp=%p failed sanity check,\ - terminating stack trace!\n", new_fp); + my_safe_printf_stderr("New value of fp=%p failed sanity check, " + "terminating stack trace!\n", new_fp); goto end; } fp = new_fp; ++frame_count; } - - fprintf(stderr, "Stack trace seems successful - bottom reached\n"); + my_safe_printf_stderr("%s", + "Stack trace seems successful - bottom reached\n"); end: - fprintf(stderr, - "Please read http://dev.mysql.com/doc/refman/5.1/en/resolve-stack-dump.html\n" - "and follow instructions on how to resolve the stack trace.\n" - "Resolved stack trace is much more helpful in diagnosing the\n" - "problem, so please do resolve it\n"); + my_safe_printf_stderr("%s", + "Please read " + "http://dev.mysql.com/doc/refman/5.1/en/resolve-stack-dump.html\n" + "and follow instructions on how to resolve the stack trace.\n" + "Resolved stack trace is much more helpful in diagnosing the\n" + "problem, so please do resolve it\n"); } #endif /* TARGET_OS_LINUX */ #endif /* HAVE_STACKTRACE */ @@ -670,7 +679,7 @@ void my_print_stacktrace(uchar* unused1, ulong unused2) &(package.sym)); have_source= pSymGetLineFromAddr64(hProcess, addr, &line_offset, &line); - fprintf(stderr, "%p ", addr); + my_safe_printf_stderr("%p ", addr); if(have_module) { char *base_image_name= strrchr(module.ImageName, '\\'); @@ -678,12 +687,13 @@ void my_print_stacktrace(uchar* unused1, ulong unused2) base_image_name++; else base_image_name= module.ImageName; - fprintf(stderr, "%s!", base_image_name); + my_safe_printf_stderr("%s!", base_image_name); } if(have_symbol) - fprintf(stderr, "%s()", package.sym.Name); + my_safe_printf_stderr("%s()", package.sym.Name); + else if(have_module) - fprintf(stderr, "???"); + my_safe_printf_stderr("%s", "???"); if(have_source) { @@ -692,11 +702,11 @@ void my_print_stacktrace(uchar* unused1, ulong unused2) base_file_name++; else base_file_name= line.FileName; - fprintf(stderr,"[%s:%u]", base_file_name, line.LineNumber); + my_safe_printf_stderr("[%s:%u]", + base_file_name, line.LineNumber); } - fprintf(stderr, "\n"); + my_safe_printf_stderr("%s", "\n"); } - fflush(stderr); } @@ -733,22 +743,22 @@ void my_write_core(int unused) if(pMiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &info, 0, 0)) { - fprintf(stderr, "Minidump written to %s\n", - _fullpath(path, dump_fname, sizeof(path)) ? path : dump_fname); + my_safe_printf_stderr("Minidump written to %s\n", + _fullpath(path, dump_fname, sizeof(path)) ? + path : dump_fname); } else { - fprintf(stderr,"MiniDumpWriteDump() failed, last error %u\n", - GetLastError()); + my_safe_printf_stderr("MiniDumpWriteDump() failed, last error %u\n", + (uint) GetLastError()); } CloseHandle(hFile); } else { - fprintf(stderr, "CreateFile(%s) failed, last error %u\n", dump_fname, - GetLastError()); + my_safe_printf_stderr("CreateFile(%s) failed, last error %u\n", + dump_fname, (uint) GetLastError()); } - fflush(stderr); } @@ -756,11 +766,212 @@ void my_safe_print_str(const char *val, int len) { __try { - fprintf(stderr,"=%.*s\n", len, val); + my_write_stderr(val, len); } __except(EXCEPTION_EXECUTE_HANDLER) { - fprintf(stderr,"is an invalid string pointer\n"); + my_safe_printf_stderr("%s", "is an invalid string pointer\n"); } } #endif /*__WIN__*/ + + +#ifdef __WIN__ +size_t my_write_stderr(const void *buf, size_t count) +{ + DWORD bytes_written; + SetFilePointer(GetStdHandle(STD_ERROR_HANDLE), 0, NULL, FILE_END); + WriteFile(GetStdHandle(STD_ERROR_HANDLE), buf, count, &bytes_written, NULL); + return bytes_written; +} +#else +size_t my_write_stderr(const void *buf, size_t count) +{ + return (size_t) write(STDERR_FILENO, buf, count); +} +#endif + + +static const char digits[]= "0123456789abcdef"; + +char *my_safe_utoa(int base, ulonglong val, char *buf) +{ + *buf--= 0; + do { + *buf--= digits[val % base]; + } while ((val /= base) != 0); + return buf + 1; +} + + +char *my_safe_itoa(int base, longlong val, char *buf) +{ + char *orig_buf= buf; + const my_bool is_neg= (val < 0); + *buf--= 0; + + if (is_neg) + val= -val; + if (is_neg && base == 16) + { + int ix; + val-= 1; + for (ix= 0; ix < 16; ++ix) + buf[-ix]= '0'; + } + + do { + *buf--= digits[val % base]; + } while ((val /= base) != 0); + + if (is_neg && base == 10) + *buf--= '-'; + + if (is_neg && base == 16) + { + int ix; + buf= orig_buf - 1; + for (ix= 0; ix < 16; ++ix, --buf) + { + switch (*buf) + { + case '0': *buf= 'f'; break; + case '1': *buf= 'e'; break; + case '2': *buf= 'd'; break; + case '3': *buf= 'c'; break; + case '4': *buf= 'b'; break; + case '5': *buf= 'a'; break; + case '6': *buf= '9'; break; + case '7': *buf= '8'; break; + case '8': *buf= '7'; break; + case '9': *buf= '6'; break; + case 'a': *buf= '5'; break; + case 'b': *buf= '4'; break; + case 'c': *buf= '3'; break; + case 'd': *buf= '2'; break; + case 'e': *buf= '1'; break; + case 'f': *buf= '0'; break; + } + } + } + return buf+1; +} + + +static const char *check_longlong(const char *fmt, my_bool *have_longlong) +{ + *have_longlong= FALSE; + if (*fmt == 'l') + { + fmt++; + if (*fmt != 'l') + *have_longlong= (sizeof(long) == sizeof(longlong)); + else + { + fmt++; + *have_longlong= TRUE; + } + } + return fmt; +} + +static size_t my_safe_vsnprintf(char *to, size_t size, + const char* format, va_list ap) +{ + char *start= to; + char *end= start + size - 1; + for (; *format; ++format) + { + my_bool have_longlong = FALSE; + if (*format != '%') + { + if (to == end) /* end of buffer */ + break; + *to++= *format; /* copy ordinary char */ + continue; + } + ++format; /* skip '%' */ + + format= check_longlong(format, &have_longlong); + + switch (*format) + { + case 'd': + case 'i': + case 'u': + case 'x': + case 'p': + { + longlong ival= 0; + ulonglong uval = 0; + if (*format == 'p') + have_longlong= (sizeof(void *) == sizeof(longlong)); + if (have_longlong) + { + if (*format == 'u') + uval= va_arg(ap, ulonglong); + else + ival= va_arg(ap, longlong); + } + else + { + if (*format == 'u') + uval= va_arg(ap, unsigned int); + else + ival= va_arg(ap, int); + } + + { + char buff[22]; + const int base= (*format == 'x' || *format == 'p') ? 16 : 10; + char *val_as_str= (*format == 'u') ? + my_safe_utoa(base, uval, &buff[sizeof(buff)-1]) : + my_safe_itoa(base, ival, &buff[sizeof(buff)-1]); + + /* Strip off "ffffffff" if we have 'x' format without 'll' */ + if (*format == 'x' && !have_longlong && ival < 0) + val_as_str+= 8; + + while (*val_as_str && to < end) + *to++= *val_as_str++; + continue; + } + } + case 's': + { + const char *val= va_arg(ap, char*); + if (!val) + val= "(null)"; + while (*val && to < end) + *to++= *val++; + continue; + } + } + } + *to= 0; + return to - start; +} + + +size_t my_safe_snprintf(char* to, size_t n, const char* fmt, ...) +{ + size_t result; + va_list args; + va_start(args,fmt); + result= my_safe_vsnprintf(to, n, fmt, args); + va_end(args); + return result; +} + + +size_t my_safe_printf_stderr(const char* fmt, ...) +{ + char to[512]; + size_t result; + va_list args; + va_start(args,fmt); + result= my_safe_vsnprintf(to, sizeof(to), fmt, args); + va_end(args); + my_write_stderr(to, result); + return result; +} diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index c050b329787..8f6e9cc7b32 100755 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -65,6 +65,7 @@ SET (SQL_SOURCE sql_list.cc sql_load.cc sql_manager.cc sql_map.cc sql_parse.cc sql_partition.cc sql_plugin.cc sql_prepare.cc sql_rename.cc debug_sync.cc debug_sync.h + signal_handler.cc sql_repl.cc sql_select.cc sql_show.cc sql_state.c sql_string.cc sql_table.cc sql_test.cc sql_trigger.cc sql_udf.cc sql_union.cc sql_update.cc sql_view.cc strfunc.cc table.cc thr_malloc.cc @@ -113,7 +114,7 @@ IF(MSVC AND NOT WITHOUT_DYNAMIC_PLUGINS) ADD_CUSTOM_COMMAND(TARGET mysqld PRE_LINK COMMAND cscript ARGS //nologo ${PROJECT_SOURCE_DIR}/win/create_def_file.js ${PLATFORM} ${LIB_LOCATIONS} > mysqld.def - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/sql) + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) ENDIF(MSVC AND NOT WITHOUT_DYNAMIC_PLUGINS) ADD_DEPENDENCIES(sql GenError) diff --git a/sql/Makefile.am b/sql/Makefile.am index 6040e4d498d..829523c7ba3 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -103,6 +103,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \ records.cc filesort.cc handler.cc \ ha_partition.cc \ debug_sync.cc \ + signal_handler.cc \ sql_db.cc sql_table.cc sql_rename.cc sql_crypt.cc \ sql_load.cc mf_iocache.cc field_conv.cc sql_show.cc \ sql_udf.cc sql_analyse.cc sql_analyse.h sql_cache.cc \ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 37eb6d95ce8..73b107e4746 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -122,13 +122,6 @@ extern "C" { // Because of SCO 3.2V4.2 #include #endif -#ifdef __WIN__ -#include -#define SIGNAL_FMT "exception 0x%x" -#else -#define SIGNAL_FMT "signal %d" -#endif - #ifdef __NETWARE__ #define zVOLSTATE_ACTIVE 6 #define zVOLSTATE_DEACTIVE 2 @@ -269,7 +262,7 @@ inline void setup_fpu() extern "C" int gethostname(char *name, int namelen); #endif -extern "C" sig_handler handle_segfault(int sig); +extern "C" sig_handler handle_fatal_signal(int sig); #if defined(__linux__) #define ENABLE_TEMP_POOL 1 @@ -415,6 +408,10 @@ TYPELIB log_output_typelib= {array_elements(log_output_names)-1,"", /* static variables */ +#ifdef HAVE_NPTL +volatile sig_atomic_t ld_assume_kernel_is_set= 0; +#endif + /* the default log output is log tables */ static bool lower_case_table_names_used= 0; static bool max_long_data_size_used= false; @@ -424,7 +421,7 @@ static my_bool opt_debugging= 0, opt_external_locking= 0, opt_console= 0; static my_bool opt_short_log_format= 0; static uint kill_cached_threads, wake_thread; static ulong killed_threads, thread_created; -static ulong max_used_connections; + ulong max_used_connections; static ulong my_bind_addr; /**< the address we bind to */ static volatile ulong cached_thread_count= 0; static const char *sql_mode_str= "OFF"; @@ -553,7 +550,7 @@ TYPELIB binlog_format_typelib= ulong opt_binlog_format_id= (ulong) BINLOG_FORMAT_UNSPEC; const char *opt_binlog_format= binlog_format_names[opt_binlog_format_id]; #ifdef HAVE_INITGROUPS -static bool calling_initgroups= FALSE; /**< Used in SIGSEGV handler. */ +volatile sig_atomic_t calling_initgroups= 0; /**< Used in SIGSEGV handler. */ #endif uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options; uint mysqld_port_timeout; @@ -727,7 +724,7 @@ char *opt_logname, *opt_slow_logname; /* Static variables */ -static bool kill_in_progress, segfaulted; +static volatile sig_atomic_t kill_in_progress; #ifdef HAVE_STACK_TRACE_ON_SEGV static my_bool opt_do_pstack; #endif /* HAVE_STACK_TRACE_ON_SEGV */ @@ -1616,9 +1613,9 @@ static void set_user(const char *user, struct passwd *user_info_arg) calling_initgroups as a flag to the SIGSEGV handler that is then used to output a specific message to help the user resolve this problem. */ - calling_initgroups= TRUE; + calling_initgroups= 1; initgroups((char*) user, user_info_arg->pw_gid); - calling_initgroups= FALSE; + calling_initgroups= 0; #endif if (setgid(user_info_arg->pw_gid) == -1) { @@ -2170,7 +2167,7 @@ LONG WINAPI my_unhandler_exception_filter(EXCEPTION_POINTERS *ex_pointers) __try { my_set_exception_pointers(ex_pointers); - handle_segfault(ex_pointers->ExceptionRecord->ExceptionCode); + handle_fatal_signal(ex_pointers->ExceptionRecord->ExceptionCode); } __except(EXCEPTION_EXECUTE_HANDLER) { @@ -2481,161 +2478,6 @@ extern "C" char *my_demangle(const char *mangled_name, int *status) #endif -extern "C" sig_handler handle_segfault(int sig) -{ - time_t curr_time; - struct tm tm; - - /* - Strictly speaking, one needs a mutex here - but since we have got SIGSEGV already, things are a mess - so not having the mutex is not as bad as possibly using a buggy - mutex - so we keep things simple - */ - if (segfaulted) - { - fprintf(stderr, "Fatal " SIGNAL_FMT " while backtracing\n", sig); - exit(1); - } - - segfaulted = 1; - - curr_time= my_time(0); - localtime_r(&curr_time, &tm); - - fprintf(stderr,"\ -%02d%02d%02d %2d:%02d:%02d - mysqld got " SIGNAL_FMT " ;\n\ -This could be because you hit a bug. It is also possible that this binary\n\ -or one of the libraries it was linked against is corrupt, improperly built,\n\ -or misconfigured. This error can also be caused by malfunctioning hardware.\n", - tm.tm_year % 100, tm.tm_mon+1, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec, - sig); - fprintf(stderr, "\ -We will try our best to scrape up some info that will hopefully help diagnose\n\ -the problem, but since we have already crashed, something is definitely wrong\n\ -and this may fail.\n\n"); - fprintf(stderr, "key_buffer_size=%lu\n", - (ulong) dflt_key_cache->key_cache_mem_size); - fprintf(stderr, "read_buffer_size=%ld\n", (long) global_system_variables.read_buff_size); - fprintf(stderr, "max_used_connections=%lu\n", max_used_connections); - fprintf(stderr, "max_threads=%u\n", thread_scheduler.max_threads); - fprintf(stderr, "threads_connected=%u\n", thread_count); - fprintf(stderr, "It is possible that mysqld could use up to \n\ -key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = %lu K\n\ -bytes of memory\n", ((ulong) dflt_key_cache->key_cache_mem_size + - (global_system_variables.read_buff_size + - global_system_variables.sortbuff_size) * - thread_scheduler.max_threads + - max_connections * sizeof(THD)) / 1024); - fprintf(stderr, "Hope that's ok; if not, decrease some variables in the equation.\n\n"); - -#if defined(HAVE_LINUXTHREADS) - if (sizeof(char*) == 4 && thread_count > UNSAFE_DEFAULT_LINUX_THREADS) - { - fprintf(stderr, "\ -You seem to be running 32-bit Linux and have %d concurrent connections.\n\ -If you have not changed STACK_SIZE in LinuxThreads and built the binary \n\ -yourself, LinuxThreads is quite likely to steal a part of the global heap for\n\ -the thread stack. Please read http://dev.mysql.com/doc/mysql/en/linux.html\n\n", - thread_count); - } -#endif /* HAVE_LINUXTHREADS */ - -#ifdef HAVE_STACKTRACE - THD *thd=current_thd; - - if (!(test_flags & TEST_NO_STACKTRACE)) - { - fprintf(stderr, "Thread pointer: 0x%lx\n", (long) thd); - fprintf(stderr, "Attempting backtrace. You can use the following " - "information to find out\nwhere mysqld died. If " - "you see no messages after this, something went\n" - "terribly wrong...\n"); - my_print_stacktrace(thd ? (uchar*) thd->thread_stack : NULL, - my_thread_stack_size); - } - if (thd) - { - const char *kreason= "UNKNOWN"; - switch (thd->killed) { - case THD::NOT_KILLED: - kreason= "NOT_KILLED"; - break; - case THD::KILL_BAD_DATA: - kreason= "KILL_BAD_DATA"; - break; - case THD::KILL_CONNECTION: - kreason= "KILL_CONNECTION"; - break; - case THD::KILL_QUERY: - kreason= "KILL_QUERY"; - break; - case THD::KILLED_NO_VALUE: - kreason= "KILLED_NO_VALUE"; - break; - } - fprintf(stderr, "\nTrying to get some variables.\n" - "Some pointers may be invalid and cause the dump to abort.\n"); - fprintf(stderr, "Query (%p): ", thd->query()); - my_safe_print_str(thd->query(), min(1024, thd->query_length())); - fprintf(stderr, "Connection ID (thread ID): %lu\n", (ulong) thd->thread_id); - fprintf(stderr, "Status: %s\n", kreason); - fputc('\n', stderr); - } - fprintf(stderr, "\ -The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains\n\ -information that should help you find out what is causing the crash.\n"); - fflush(stderr); -#endif /* HAVE_STACKTRACE */ - -#ifdef HAVE_INITGROUPS - if (calling_initgroups) - fprintf(stderr, "\n\ -This crash occured while the server was calling initgroups(). This is\n\ -often due to the use of a mysqld that is statically linked against glibc\n\ -and configured to use LDAP in /etc/nsswitch.conf. You will need to either\n\ -upgrade to a version of glibc that does not have this problem (2.3.4 or\n\ -later when used with nscd), disable LDAP in your nsswitch.conf, or use a\n\ -mysqld that is not statically linked.\n"); -#endif - -#ifdef HAVE_NPTL - if (thd_lib_detected == THD_LIB_LT && !getenv("LD_ASSUME_KERNEL")) - fprintf(stderr,"\n\ -You are running a statically-linked LinuxThreads binary on an NPTL system.\n\ -This can result in crashes on some distributions due to LT/NPTL conflicts.\n\ -You should either build a dynamically-linked binary, or force LinuxThreads\n\ -to be used with the LD_ASSUME_KERNEL environment variable. Please consult\n\ -the documentation for your distribution on how to do that.\n"); -#endif - - if (locked_in_memory) - { - fprintf(stderr, "\n\ -The \"--memlock\" argument, which was enabled, uses system calls that are\n\ -unreliable and unstable on some operating systems and operating-system\n\ -versions (notably, some versions of Linux). This crash could be due to use\n\ -of those buggy OS calls. You should consider whether you really need the\n\ -\"--memlock\" parameter and/or consult the OS distributer about \"mlockall\"\n\ -bugs.\n"); - } - -#ifdef HAVE_WRITE_CORE - if (test_flags & TEST_CORE_ON_SIGNAL) - { - fprintf(stderr, "Writing a core file\n"); - fflush(stderr); - my_write_core(sig); - } -#endif - -#ifndef __WIN__ - /* On Windows, do not terminate, but pass control to exception filter */ - exit(1); -#endif -} - #if !defined(__WIN__) && !defined(__NETWARE__) #ifndef SA_RESETHAND #define SA_RESETHAND 0 @@ -2664,9 +2506,9 @@ static void init_signals(void) my_init_stacktrace(); #endif #if defined(__amiga__) - sa.sa_handler=(void(*)())handle_segfault; + sa.sa_handler=(void(*)())handle_fatal_signal; #else - sa.sa_handler=handle_segfault; + sa.sa_handler=handle_fatal_signal; #endif sigaction(SIGSEGV, &sa, NULL); sigaction(SIGABRT, &sa, NULL); @@ -4363,6 +4205,10 @@ int win_main(int argc, char **argv) int main(int argc, char **argv) #endif { +#ifdef HAVE_NPTL + ld_assume_kernel_is_set= (getenv("LD_ASSUME_KERNEL") != 0); +#endif + MY_INIT(argv[0]); // init my_sys library & pthreads /* nothing should come before this line ^^^ */ @@ -7876,7 +7722,7 @@ static int mysql_init_variables(void) opt_secure_file_priv= 0; opt_bootstrap= opt_myisam_log= 0; mqh_used= 0; - segfaulted= kill_in_progress= 0; + kill_in_progress= 0; cleanup_done= 0; defaults_argc= 0; defaults_argv= 0; diff --git a/sql/signal_handler.cc b/sql/signal_handler.cc new file mode 100644 index 00000000000..54b456ec2c4 --- /dev/null +++ b/sql/signal_handler.cc @@ -0,0 +1,257 @@ +/* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA */ + +#include "my_global.h" +#include + +#include "mysql_priv.h" +#include "my_stacktrace.h" + +#ifdef __WIN__ +#include +#define SIGNAL_FMT "exception 0x%x" +#else +#define SIGNAL_FMT "signal %d" +#endif + +/* + We are handling signals in this file. + Any global variables we read should be 'volatile sig_atomic_t' + to guarantee that we read some consistent value. + */ +static volatile sig_atomic_t segfaulted= 0; +extern ulong max_used_connections; +extern volatile sig_atomic_t calling_initgroups; +#ifdef HAVE_NPTL +extern volatile sig_atomic_t ld_assume_kernel_is_set; +#endif + +/** + * Handler for fatal signals + * + * Fatal events (seg.fault, bus error etc.) will trigger + * this signal handler. The handler will try to dump relevant + * debugging information to stderr and dump a core image. + * + * Signal handlers can only use a set of 'safe' system calls + * and library functions. A list of safe calls in POSIX systems + * are available at: + * http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html + * For MS Windows, guidelines are available at: + * http://msdn.microsoft.com/en-us/library/xdkz3x12(v=vs.71).aspx + * + * @param sig Signal number +*/ +extern "C" sig_handler handle_fatal_signal(int sig) +{ + if (segfaulted) + { + my_safe_printf_stderr("Fatal " SIGNAL_FMT " while backtracing\n", sig); + _exit(1); /* Quit without running destructors */ + } + + segfaulted = 1; + +#ifdef __WIN__ + SYSTEMTIME utc_time; + GetSystemTime(&utc_time); + const long hrs= utc_time.wHour; + const long mins= utc_time.wMinute; + const long secs= utc_time.wSecond; +#else + /* Using time() instead of my_time() to avoid looping */ + const time_t curr_time= time(NULL); + /* Calculate time of day */ + const long tmins = curr_time / 60; + const long thrs = tmins / 60; + const long hrs = thrs % 24; + const long mins = tmins % 60; + const long secs = curr_time % 60; +#endif + + char hrs_buf[3]= "00"; + char mins_buf[3]= "00"; + char secs_buf[3]= "00"; + my_safe_itoa(10, hrs, &hrs_buf[2]); + my_safe_itoa(10, mins, &mins_buf[2]); + my_safe_itoa(10, secs, &secs_buf[2]); + + my_safe_printf_stderr("%s:%s:%s UTC - mysqld got " SIGNAL_FMT " ;\n", + hrs_buf, mins_buf, secs_buf, sig); + + my_safe_printf_stderr("%s", + "This could be because you hit a bug. It is also possible that this binary\n" + "or one of the libraries it was linked against is corrupt, improperly built,\n" + "or misconfigured. This error can also be caused by malfunctioning hardware.\n"); + + my_safe_printf_stderr("%s", + "We will try our best to scrape up some info that will hopefully help\n" + "diagnose the problem, but since we have already crashed, \n" + "something is definitely wrong and this may fail.\n\n"); + + my_safe_printf_stderr("key_buffer_size=%lu\n", + (ulong) dflt_key_cache->key_cache_mem_size); + + my_safe_printf_stderr("read_buffer_size=%ld\n", + (long) global_system_variables.read_buff_size); + + my_safe_printf_stderr("max_used_connections=%lu\n", + (ulong) max_used_connections); + + my_safe_printf_stderr("max_threads=%u\n", + (uint) thread_scheduler.max_threads); + + my_safe_printf_stderr("thread_count=%u\n", (uint) thread_count); + + my_safe_printf_stderr("connection_count=%u\n", (uint) connection_count); + + my_safe_printf_stderr("It is possible that mysqld could use up to \n" + "key_buffer_size + " + "(read_buffer_size + sort_buffer_size)*max_threads = " + "%lu K bytes of memory\n", + ((ulong) dflt_key_cache->key_cache_mem_size + + (global_system_variables.read_buff_size + + global_system_variables.sortbuff_size) * + thread_scheduler.max_threads + + max_connections * sizeof(THD)) / 1024); + + my_safe_printf_stderr("%s", + "Hope that's ok; if not, decrease some variables in the equation.\n\n"); + +#if defined(HAVE_LINUXTHREADS) + if (sizeof(char*) == 4 && thread_count > UNSAFE_DEFAULT_LINUX_THREADS) + { + my_safe_printf_stderr( + "You seem to be running 32-bit Linux and have " + "%d concurrent connections.\n" + "If you have not changed STACK_SIZE in LinuxThreads " + "and built the binary \n" + "yourself, LinuxThreads is quite likely to steal " + "a part of the global heap for\n" + "the thread stack. Please read " + "http://dev.mysql.com/doc/mysql/en/linux-installation.html\n\n" + thread_count); + } +#endif /* HAVE_LINUXTHREADS */ + +#ifdef HAVE_STACKTRACE + THD *thd=current_thd; + + if (!(test_flags & TEST_NO_STACKTRACE)) + { + my_safe_printf_stderr("Thread pointer: 0x%p\n", thd); + my_safe_printf_stderr("%s", + "Attempting backtrace. You can use the following " + "information to find out\n" + "where mysqld died. If you see no messages after this, something went\n" + "terribly wrong...\n"); + my_print_stacktrace(thd ? (uchar*) thd->thread_stack : NULL, + my_thread_stack_size); + } + if (thd) + { + const char *kreason= "UNKNOWN"; + switch (thd->killed) { + case THD::NOT_KILLED: + kreason= "NOT_KILLED"; + break; + case THD::KILL_BAD_DATA: + kreason= "KILL_BAD_DATA"; + break; + case THD::KILL_CONNECTION: + kreason= "KILL_CONNECTION"; + break; + case THD::KILL_QUERY: + kreason= "KILL_QUERY"; + break; + case THD::KILLED_NO_VALUE: + kreason= "KILLED_NO_VALUE"; + break; + } + my_safe_printf_stderr("%s", "\n" + "Trying to get some variables.\n" + "Some pointers may be invalid and cause the dump to abort.\n"); + + my_safe_printf_stderr("Query (%p): ", thd->query()); + my_safe_print_str(thd->query(), min(1024U, thd->query_length())); + my_safe_printf_stderr("Connection ID (thread ID): %lu\n", + (ulong) thd->thread_id); + my_safe_printf_stderr("Status: %s\n\n", kreason); + } + my_safe_printf_stderr("%s", + "The manual page at " + "http://dev.mysql.com/doc/mysql/en/crashing.html contains\n" + "information that should help you find out what is causing the crash.\n"); + +#endif /* HAVE_STACKTRACE */ + +#ifdef HAVE_INITGROUPS + if (calling_initgroups) + { + my_safe_printf_stderr("%s", "\n" + "This crash occured while the server was calling initgroups(). This is\n" + "often due to the use of a mysqld that is statically linked against \n" + "glibc and configured to use LDAP in /etc/nsswitch.conf.\n" + "You will need to either upgrade to a version of glibc that does not\n" + "have this problem (2.3.4 or later when used with nscd),\n" + "disable LDAP in your nsswitch.conf, or use a " + "mysqld that is not statically linked.\n"); + } +#endif + +#ifdef HAVE_NPTL + if (thd_lib_detected == THD_LIB_LT && !ld_assume_kernel_is_set) + { + my_safe_printf_stderr("%s", + "You are running a statically-linked LinuxThreads binary on an NPTL\n" + "system. This can result in crashes on some distributions due to " + "LT/NPTL conflicts.\n" + "You should either build a dynamically-linked binary, " + "or force LinuxThreads\n" + "to be used with the LD_ASSUME_KERNEL environment variable.\n" + "Please consult the documentation for your distribution " + "on how to do that.\n"); + } +#endif + + if (locked_in_memory) + { + my_safe_printf_stderr("%s", "\n" + "The \"--memlock\" argument, which was enabled, " + "uses system calls that are\n" + "unreliable and unstable on some operating systems and " + "operating-system versions (notably, some versions of Linux).\n" + "This crash could be due to use of those buggy OS calls.\n" + "You should consider whether you really need the " + "\"--memlock\" parameter and/or consult the OS distributer about " + "\"mlockall\" bugs.\n"); + } + +#ifdef HAVE_WRITE_CORE + if (test_flags & TEST_CORE_ON_SIGNAL) + { + my_safe_printf_stderr("%s", "Writing a core file\n"); + my_write_core(sig); + } +#endif + +#ifndef __WIN__ + /* + Quit, without running destructors (etc.) + On Windows, do not terminate, but pass control to exception filter. + */ + _exit(1); // Using _exit(), since exit() is not async signal safe +#endif +} From 23dce762a45c634cafaeef73fefd34c0ee2f096f Mon Sep 17 00:00:00 2001 From: Tor Didriksen Date: Wed, 30 Nov 2011 17:11:13 +0100 Subject: [PATCH 007/135] Bug#11761576 54082: HANDLE_SEGFAULT MAKES USE OF UNSAFE FUNCTIONS Post-push fix: build break on windows/optimized --- sql/mysqld.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 73b107e4746..c47d39721b9 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -122,6 +122,10 @@ extern "C" { // Because of SCO 3.2V4.2 #include #endif +#ifdef __WIN__ +#include +#endif + #ifdef __NETWARE__ #define zVOLSTATE_ACTIVE 6 #define zVOLSTATE_DEACTIVE 2 From 3d58fd6900128503d8516515496868c516ce63a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 12 Dec 2011 13:48:24 +0200 Subject: [PATCH 008/135] Bug#13418887 ERROR IN DIAGNOSTIC FUNCTION PAGE_REC_PRINT() When printing information about a ROW_FORMAT=REDUNDANT record, pass the correct flag to rec_get_next_offs(). rb:821 approved by Jimmy Yang --- storage/innodb_plugin/ChangeLog | 5 +++++ storage/innodb_plugin/include/page0page.h | 4 ++++ storage/innodb_plugin/page/page0page.c | 4 +++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 951a1bd9c3b..37668b43697 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,8 @@ +2011-12-10 The InnoDB Team + + * include/page0page.h, page/page0page.c: + Fix Bug#13418887 ERROR IN DIAGNOSTIC FUNCTION PAGE_REC_PRINT() + 2011-11-10 The InnoDB Team * handler/ha_innodb.cc, row/row0ins.c, innodb_replace.test: diff --git a/storage/innodb_plugin/include/page0page.h b/storage/innodb_plugin/include/page0page.h index 12c4fed75d2..ea9c212581c 100644 --- a/storage/innodb_plugin/include/page0page.h +++ b/storage/innodb_plugin/include/page0page.h @@ -892,6 +892,7 @@ page_parse_create( ulint comp, /*!< in: nonzero=compact page format */ buf_block_t* block, /*!< in: block or NULL */ mtr_t* mtr); /*!< in: mtr or NULL */ +#ifndef UNIV_HOTBACKUP /************************************************************//** Prints record contents including the data relevant only in the index page context. */ @@ -901,6 +902,7 @@ page_rec_print( /*===========*/ const rec_t* rec, /*!< in: physical record */ const ulint* offsets);/*!< in: record descriptor */ +# ifdef UNIV_BTR_PRINT /***************************************************************//** This is used to print the contents of the directory for debugging purposes. */ @@ -940,6 +942,8 @@ page_print( in directory */ ulint rn); /*!< in: print rn first and last records in directory */ +# endif /* UNIV_BTR_PRINT */ +#endif /* !UNIV_HOTBACKUP */ /***************************************************************//** The following is used to validate a record on a page. This function differs from rec_validate as it can also check the n_owned field and diff --git a/storage/innodb_plugin/page/page0page.c b/storage/innodb_plugin/page/page0page.c index 93869e997b5..52f6678be0a 100644 --- a/storage/innodb_plugin/page/page0page.c +++ b/storage/innodb_plugin/page/page0page.c @@ -1613,13 +1613,14 @@ page_rec_print( " n_owned: %lu; heap_no: %lu; next rec: %lu\n", (ulong) rec_get_n_owned_old(rec), (ulong) rec_get_heap_no_old(rec), - (ulong) rec_get_next_offs(rec, TRUE)); + (ulong) rec_get_next_offs(rec, FALSE)); } page_rec_check(rec); rec_validate(rec, offsets); } +# ifdef UNIV_BTR_PRINT /***************************************************************//** This is used to print the contents of the directory for debugging purposes. */ @@ -1780,6 +1781,7 @@ page_print( page_dir_print(page, dn); page_print_list(block, index, rn); } +# endif /* UNIV_BTR_PRINT */ #endif /* !UNIV_HOTBACKUP */ /***************************************************************//** From beedf6b261b243ec0a2332162bface6ec7d58dd0 Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Mon, 12 Dec 2011 14:07:02 +0100 Subject: [PATCH 009/135] Bug#12361113: CRASH WHEN "LOAD INDEX INTO CACHE" WITH TOO SMALL KEY CACHE The server crashed on division by zero because the key cache was not initialized and the block length was 0 which was used in a division. The fix was to not allow CACHE INDEX if the key cache was not initiallized. Thus never try LOAD INDEX INTO CACHE for an uninitialized key cache. Also added some windows files/directories to .bzrignore. --- .bzrignore | 9 +++++++++ myisam/mi_preload.c | 3 +++ mysql-test/r/key_cache.result | 16 ++++++++++++++++ mysql-test/t/key_cache.test | 16 ++++++++++++++++ sql/sql_table.cc | 5 +++++ 5 files changed, 49 insertions(+) diff --git a/.bzrignore b/.bzrignore index 2b5b42cb87f..184ed9fe235 100644 --- a/.bzrignore +++ b/.bzrignore @@ -8,6 +8,7 @@ *.core *.d *.da +*.dir *.exe *.gcda *.gcno @@ -25,6 +26,7 @@ *.pdb *.reject *.res +*.rule *.sbr *.so *.so.* @@ -32,13 +34,19 @@ *.user *.vcproj *.vcproj.cmake +*.vcxproj +*.vcxproj.filters */*.dir/* +Debug +MySql.sdf +Win32 */*_pure_*warnings */.deps */.libs/* */.pure */debug/* */release/* +RelWithDebInfo *~ .*.swp ./CMakeCache.txt @@ -83,6 +91,7 @@ BitKeeper/tmp/* BitKeeper/tmp/bkr3sAHD BitKeeper/tmp/gone CMakeFiles/* +CMakeFiles COPYING COPYING.LIB Docs/#manual.texi# diff --git a/myisam/mi_preload.c b/myisam/mi_preload.c index c73c70962ed..f53fcd2e1ee 100644 --- a/myisam/mi_preload.c +++ b/myisam/mi_preload.c @@ -54,6 +54,9 @@ int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves) if (!keys || !mi_is_any_key_active(key_map) || key_file_length == pos) DBUG_RETURN(0); + /* Preload into a non initialized key cache should never happen. */ + DBUG_ASSERT(share->key_cache->key_cache_inited); + block_length= keyinfo[0].block_length; if (ignore_leaves) diff --git a/mysql-test/r/key_cache.result b/mysql-test/r/key_cache.result index 9ada5dc0784..6513c4eb374 100644 --- a/mysql-test/r/key_cache.result +++ b/mysql-test/r/key_cache.result @@ -368,3 +368,19 @@ Variable_name Value key_cache_block_size 1536 SET GLOBAL key_cache_block_size= @bug28478_key_cache_block_size; DROP TABLE t1; +# +# Bug#12361113: crash when load index into cache +# +# Note that this creates an empty disabled key cache! +SET GLOBAL key_cache_none.key_cache_block_size = 1024; +CREATE TABLE t1 (a INT, b INTEGER NOT NULL, KEY (b) ) ENGINE = MYISAM; +INSERT INTO t1 VALUES (1, 1); +CACHE INDEX t1 in key_cache_none; +ERROR HY000: Unknown key cache 'key_cache_none' +# The bug crashed the server at LOAD INDEX below. Now it will succeed +# since the default cache is used due to CACHE INDEX failed for +# key_cache_none. +LOAD INDEX INTO CACHE t1; +Table Op Msg_type Msg_text +test.t1 preload_keys status OK +DROP TABLE t1; diff --git a/mysql-test/t/key_cache.test b/mysql-test/t/key_cache.test index 4c14dc96aaa..9d865b9b5fe 100644 --- a/mysql-test/t/key_cache.test +++ b/mysql-test/t/key_cache.test @@ -247,3 +247,19 @@ SET GLOBAL key_cache_block_size= @bug28478_key_cache_block_size; DROP TABLE t1; # End of 4.1 tests + +--echo # +--echo # Bug#12361113: crash when load index into cache +--echo # + +--echo # Note that this creates an empty disabled key cache! +SET GLOBAL key_cache_none.key_cache_block_size = 1024; +CREATE TABLE t1 (a INT, b INTEGER NOT NULL, KEY (b) ) ENGINE = MYISAM; +INSERT INTO t1 VALUES (1, 1); +--error ER_UNKNOWN_KEY_CACHE +CACHE INDEX t1 in key_cache_none; +--echo # The bug crashed the server at LOAD INDEX below. Now it will succeed +--echo # since the default cache is used due to CACHE INDEX failed for +--echo # key_cache_none. +LOAD INDEX INTO CACHE t1; +DROP TABLE t1; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 4320cef2c49..2bb758f8b86 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2680,6 +2680,11 @@ bool mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables, DBUG_RETURN(TRUE); } pthread_mutex_unlock(&LOCK_global_system_variables); + if (!key_cache->key_cache_inited) + { + my_error(ER_UNKNOWN_KEY_CACHE, MYF(0), key_cache_name->str); + DBUG_RETURN(TRUE); + } check_opt.key_cache= key_cache; DBUG_RETURN(mysql_admin_table(thd, tables, &check_opt, "assign_to_keycache", TL_READ_NO_INSERT, 0, 0, From ad84fb5c3763b3a5c6c2146c8fc824f0d385c77c Mon Sep 17 00:00:00 2001 From: Annamalai Gurusami Date: Tue, 13 Dec 2011 14:26:12 +0530 Subject: [PATCH 010/135] Bug #13117023: Innodb increments handler_read_key when it should not The counter handler_read_key (SSV::ha_read_key_count) is incremented incorrectly. The mysql server maintains a per thread system_status_var (SSV) object. This object contains among other things the counter SSV::ha_read_key_count. The purpose of this counter is to measure the number of requests to read a row based on a key (or the number of index lookups). This counter was wrongly incremented in the ha_innobase::innobase_get_index(). The fix removes this increment statement (for both innodb and innodb_plugin). The various callers of the innobase_get_index() was checked to determine if anybody must increment this counter (if they first call innobase_get_index() and then perform an index lookup). It was found that no caller of innobase_get_index() needs to worry about the SSV::ha_read_key_count counter. --- mysql-test/suite/innodb/r/innodb.result | 5 +++++ mysql-test/suite/innodb/t/innodb.test | 11 +++++++++++ mysql-test/suite/innodb_plugin/r/innodb.result | 11 +++++++++++ mysql-test/suite/innodb_plugin/t/innodb.test | 11 +++++++++++ storage/innobase/handler/ha_innodb.cc | 1 - storage/innodb_plugin/ChangeLog | 6 ++++++ storage/innodb_plugin/handler/ha_innodb.cc | 1 - 7 files changed, 44 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/innodb/r/innodb.result b/mysql-test/suite/innodb/r/innodb.result index ad140cc59be..fd311de001c 100644 --- a/mysql-test/suite/innodb/r/innodb.result +++ b/mysql-test/suite/innodb/r/innodb.result @@ -2365,3 +2365,8 @@ t1 CREATE TABLE `t1` ( ) ENGINE=InnoDB DEFAULT CHARSET=latin1 drop table t1; set storage_engine=MyISAM; +Variable_name Value +Handler_read_key 0 +f1 +Variable_name Value +Handler_read_key 1 diff --git a/mysql-test/suite/innodb/t/innodb.test b/mysql-test/suite/innodb/t/innodb.test index ef050390b48..f20ea46b200 100644 --- a/mysql-test/suite/innodb/t/innodb.test +++ b/mysql-test/suite/innodb/t/innodb.test @@ -1389,6 +1389,17 @@ eval set storage_engine=$default; -- disable_query_log SET GLOBAL innodb_thread_concurrency = @innodb_thread_concurrency_orig; +# +# Test fix for bug 13117023. InnoDB increments HA_READ_KEY_COUNT (aka +# HANDLER_READ_KEY) when it should not. +# +create table t1 (f1 integer primary key) engine=innodb; +flush status; +show status like "handler_read_key"; +select f1 from t1; +show status like "handler_read_key"; +drop table t1; + ####################################################################### # # # Please, DO NOT TOUCH this file as well as the innodb.result file. # diff --git a/mysql-test/suite/innodb_plugin/r/innodb.result b/mysql-test/suite/innodb_plugin/r/innodb.result index cdb61f3ba98..9435670f42d 100644 --- a/mysql-test/suite/innodb_plugin/r/innodb.result +++ b/mysql-test/suite/innodb_plugin/r/innodb.result @@ -3257,3 +3257,14 @@ Handler_update 1 Variable_name Value Handler_delete 1 DROP TABLE bug58912; +create table t1 (f1 integer primary key) engine=innodb; +flush status; +show status like "handler_read_key"; +Variable_name Value +Handler_read_key 0 +select f1 from t1; +f1 +show status like "handler_read_key"; +Variable_name Value +Handler_read_key 1 +drop table t1; diff --git a/mysql-test/suite/innodb_plugin/t/innodb.test b/mysql-test/suite/innodb_plugin/t/innodb.test index 1480492cf2a..d4f2088cc50 100644 --- a/mysql-test/suite/innodb_plugin/t/innodb.test +++ b/mysql-test/suite/innodb_plugin/t/innodb.test @@ -2571,6 +2571,17 @@ SET GLOBAL innodb_thread_concurrency = @innodb_thread_concurrency_orig; # Clean up after the Bug#55284/Bug#58912 test case. DROP TABLE bug58912; +# +# Test fix for bug 13117023. InnoDB increments HA_READ_KEY_COUNT (aka +# HANDLER_READ_KEY) when it should not. +# +create table t1 (f1 integer primary key) engine=innodb; +flush status; +show status like "handler_read_key"; +select f1 from t1; +show status like "handler_read_key"; +drop table t1; + ####################################################################### # # # Please, DO NOT TOUCH this file as well as the innodb.result file. # diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 6709f790994..a4d79a5934e 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -4802,7 +4802,6 @@ ha_innobase::innobase_get_index( dict_index_t* index = 0; DBUG_ENTER("innobase_get_index"); - ha_statistic_increment(&SSV::ha_read_key_count); ut_ad(user_thd == ha_thd()); ut_a(prebuilt->trx == thd_to_trx(user_thd)); diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 37668b43697..5fc0cce3ff2 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,9 @@ +2011-12-13 The InnoDB Team + + * handler/ha_innodb.cc, innodb.test, innodb.result: + Fix Bug#13117023: InnoDB was incrementing the handler_read_key, + also the SSV::ha_read_key_count, at the wrong place. + 2011-12-10 The InnoDB Team * include/page0page.h, page/page0page.c: diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index d84bd38ba7e..122bf1f7846 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -5520,7 +5520,6 @@ ha_innobase::innobase_get_index( dict_index_t* index = 0; DBUG_ENTER("innobase_get_index"); - ha_statistic_increment(&SSV::ha_read_key_count); if (keynr != MAX_KEY && table->s->keys > 0) { key = table->key_info + keynr; From e5cb28793385566e22d5a82efdf3f6cb8dbe5cbc Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Thu, 15 Dec 2011 16:59:18 +0100 Subject: [PATCH 011/135] Post push fix for merge.test and mysqlcheck.test on windows --- mysql-test/r/mysqlcheck.result | 1 + mysql-test/t/merge.test | 10 +++++++--- mysql-test/t/mysqlcheck.test | 1 + 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/mysqlcheck.result b/mysql-test/r/mysqlcheck.result index 5f1a0565b10..ffba0d443e7 100644 --- a/mysql-test/r/mysqlcheck.result +++ b/mysql-test/r/mysqlcheck.result @@ -147,6 +147,7 @@ DROP TABLE `@`; CREATE TABLE `я` (a INT); SET NAMES DEFAULT; mysqlcheck --default-character-set="latin1" --databases test +call mtr.add_suppression("Can't find file: '..test.@003f.frm'"); test.? Error : Table doesn't exist status : Operation failed diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test index a6affbb0540..7954aed6a55 100644 --- a/mysql-test/t/merge.test +++ b/mysql-test/t/merge.test @@ -1817,9 +1817,13 @@ CREATE TABLE t1(a INT); --echo # Test reattach merge failure LOCK TABLES m1 READ; --echo # Replace 't1' with 't3' table using file operations. -remove_file $MYSQLD_DATADIR/test/t1.frm; -remove_file $MYSQLD_DATADIR/test/t1.MYI; -remove_file $MYSQLD_DATADIR/test/t1.MYD; +# move + remove is a work around for windows. +move_file $MYSQLD_DATADIR/test/t1.frm $MYSQLD_DATADIR/test/oldt1.frm; +move_file $MYSQLD_DATADIR/test/t1.MYI $MYSQLD_DATADIR/test/oldt1.MYI; +move_file $MYSQLD_DATADIR/test/t1.MYD $MYSQLD_DATADIR/test/oldt1.MYD; +remove_file $MYSQLD_DATADIR/test/oldt1.frm; +remove_file $MYSQLD_DATADIR/test/oldt1.MYI; +remove_file $MYSQLD_DATADIR/test/oldt1.MYD; copy_file $MYSQLD_DATADIR/test/t3.frm $MYSQLD_DATADIR/test/t1.frm; copy_file $MYSQLD_DATADIR/test/t3.MYI $MYSQLD_DATADIR/test/t1.MYI; copy_file $MYSQLD_DATADIR/test/t3.MYD $MYSQLD_DATADIR/test/t1.MYD; diff --git a/mysql-test/t/mysqlcheck.test b/mysql-test/t/mysqlcheck.test index 986b5aba385..bf99d48fd6a 100644 --- a/mysql-test/t/mysqlcheck.test +++ b/mysql-test/t/mysqlcheck.test @@ -138,6 +138,7 @@ CREATE TABLE `я` (a INT); SET NAMES DEFAULT; --echo mysqlcheck --default-character-set="latin1" --databases test # Error returned depends on platform, replace it with "Table doesn't exist" +call mtr.add_suppression("Can't find file: '..test.@003f.frm'"); --replace_result "Can't find file: './test/@003f.frm' (errno: 22)" "Table doesn't exist" "Table 'test.?' doesn't exist" "Table doesn't exist" --exec $MYSQL_CHECK --default-character-set="latin1" --databases test --echo mysqlcheck --default-character-set="utf8" --databases test From bad3e4179c5471728fb0dc3d72b81db02129128f Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Mon, 19 Dec 2011 14:55:30 -0800 Subject: [PATCH 012/135] Fixed LP bug #906322. If the sorted table belongs to a dependent subquery then the function create_sort_index() should not clear TABLE:: select and TABLE::select for this table after the sort of the table has been performed, because these members are needed for the second execution of the subquery. --- mysql-test/r/subselect.result | 2 -- mysql-test/suite/innodb/r/innodb_mysql.result | 6 +++--- mysql-test/suite/innodb_plugin/r/innodb_mysql.result | 6 +++--- sql/sql_select.cc | 2 -- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 1a56940a560..1f3432ecde1 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -4631,8 +4631,6 @@ SELECT * FROM t1 WHERE EXISTS (SELECT DISTINCT a FROM t2 WHERE t1.a < t2.a ORDER BY b); pk a 1 10 -3 30 -2 20 DROP TABLE t1,t2; CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a), KEY b (b)); INSERT INTO t1 VALUES (1,NULL), (9,NULL); diff --git a/mysql-test/suite/innodb/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result index 42aca8b6464..666d6b7591f 100644 --- a/mysql-test/suite/innodb/r/innodb_mysql.result +++ b/mysql-test/suite/innodb/r/innodb_mysql.result @@ -1739,7 +1739,7 @@ SELECT 1 FROM (SELECT COUNT(DISTINCT c1) FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY system NULL NULL NULL NULL 1 -2 DERIVED t1 ALL c3,c2 c3 5 5 Using filesort +2 DERIVED t1 ALL c3,c2 c3 5 5 Using where; Using filesort DROP TABLE t1; CREATE TABLE t1 (c1 REAL, c2 REAL, c3 REAL, KEY (c3), KEY (c2, c3)) ENGINE=InnoDB; @@ -1753,7 +1753,7 @@ SELECT 1 FROM (SELECT COUNT(DISTINCT c1) FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY system NULL NULL NULL NULL 1 -2 DERIVED t1 ALL c3,c2 c3 9 5 Using filesort +2 DERIVED t1 ALL c3,c2 c3 9 5 Using where; Using filesort DROP TABLE t1; CREATE TABLE t1 (c1 DECIMAL(12,2), c2 DECIMAL(12,2), c3 DECIMAL(12,2), KEY (c3), KEY (c2, c3)) @@ -1768,7 +1768,7 @@ SELECT 1 FROM (SELECT COUNT(DISTINCT c1) FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY system NULL NULL NULL NULL 1 -2 DERIVED t1 ALL c3,c2 c3 7 5 Using filesort +2 DERIVED t1 ALL c3,c2 c3 7 5 Using where; Using filesort DROP TABLE t1; End of 5.1 tests drop table if exists t1, t2, t3; diff --git a/mysql-test/suite/innodb_plugin/r/innodb_mysql.result b/mysql-test/suite/innodb_plugin/r/innodb_mysql.result index 86d83f82b76..987a04eb59d 100644 --- a/mysql-test/suite/innodb_plugin/r/innodb_mysql.result +++ b/mysql-test/suite/innodb_plugin/r/innodb_mysql.result @@ -1739,7 +1739,7 @@ SELECT 1 FROM (SELECT COUNT(DISTINCT c1) FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY system NULL NULL NULL NULL 1 -2 DERIVED t1 ALL c3,c2 c3 5 5 Using filesort +2 DERIVED t1 ALL c3,c2 c3 5 5 Using where; Using filesort DROP TABLE t1; CREATE TABLE t1 (c1 REAL, c2 REAL, c3 REAL, KEY (c3), KEY (c2, c3)) ENGINE=InnoDB; @@ -1753,7 +1753,7 @@ SELECT 1 FROM (SELECT COUNT(DISTINCT c1) FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY system NULL NULL NULL NULL 1 -2 DERIVED t1 ALL c3,c2 c3 9 5 Using filesort +2 DERIVED t1 ALL c3,c2 c3 9 5 Using where; Using filesort DROP TABLE t1; CREATE TABLE t1 (c1 DECIMAL(12,2), c2 DECIMAL(12,2), c3 DECIMAL(12,2), KEY (c3), KEY (c2, c3)) @@ -1768,7 +1768,7 @@ SELECT 1 FROM (SELECT COUNT(DISTINCT c1) FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY system NULL NULL NULL NULL 1 -2 DERIVED t1 ALL c3,c2 c3 7 5 Using filesort +2 DERIVED t1 ALL c3,c2 c3 7 5 Using where; Using filesort DROP TABLE t1; End of 5.1 tests drop table if exists t1, t2, t3; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 3e6fac841b2..219e0ebe406 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -14466,11 +14466,9 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order, table->sort.io_cache= NULL; select->cleanup(); // filesort did select - tab->select= 0; table->quick_keys.clear_all(); // as far as we cleanup select->quick table->sort.io_cache= tablesort_result_cache; } - tab->select_cond=0; tab->last_inner= 0; tab->first_unmatched= 0; tab->type=JT_ALL; // Read with normal read_record From 27380e4fb522062daa0d7775a3205363a5c1b110 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Tue, 20 Dec 2011 01:56:41 -0800 Subject: [PATCH 013/135] Fixed LP bug #794005. The function st_table::mark_virtual_columns_for_write() did not take into account the fact that for any table the value of st_table::vfield is 0 when there are no virtual columns in the table definition. --- mysql-test/r/view.result | 11 +++++++++++ mysql-test/t/view.test | 16 ++++++++++++++++ sql/table.cc | 3 +++ 3 files changed, 30 insertions(+) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 40142c5e0a7..22fd4eb1722 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -3926,3 +3926,14 @@ drop table t1,t2; # ----------------------------------------------------------------- # -- End of 5.1 tests. # ----------------------------------------------------------------- +# +# Bug #794005: crash in st_table::mark_virtual_columns_for_write +# +CREATE TABLE t1 (a int); +CREATE TABLE t2 (a int); +CREATE VIEW v2 AS SELECT * FROM t2; +CREATE VIEW v1 AS SELECT * FROM v2; +CREATE OR REPLACE ALGORITHM = TEMPTABLE VIEW v2 AS SELECT * FROM t1; +UPDATE v1 SET a = 10; +DROP VIEW v1,v2; +DROP TABLE t1,t2; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 644fbe0443f..462118af4ea 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -3976,3 +3976,19 @@ drop table t1,t2; --echo # ----------------------------------------------------------------- --echo # -- End of 5.1 tests. --echo # ----------------------------------------------------------------- + +--echo # +--echo # Bug #794005: crash in st_table::mark_virtual_columns_for_write +--echo # + +CREATE TABLE t1 (a int); +CREATE TABLE t2 (a int); + +CREATE VIEW v2 AS SELECT * FROM t2; +CREATE VIEW v1 AS SELECT * FROM v2; +CREATE OR REPLACE ALGORITHM = TEMPTABLE VIEW v2 AS SELECT * FROM t1; + +UPDATE v1 SET a = 10; + +DROP VIEW v1,v2; +DROP TABLE t1,t2; diff --git a/sql/table.cc b/sql/table.cc index ca5e4678c52..ca14b2ef4d2 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -5161,6 +5161,9 @@ void st_table::mark_virtual_columns_for_write(bool insert_fl) Field **vfield_ptr, *tmp_vfield; bool bitmap_updated= FALSE; + if (!vfield) + return; + for (vfield_ptr= vfield; *vfield_ptr; vfield_ptr++) { tmp_vfield= *vfield_ptr; From 7b29727a5a730d9baef822418e899f8ac5302587 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 21 Dec 2011 12:45:53 +0200 Subject: [PATCH 014/135] Supression condition made wider to cover some other system cases. --- mysql-test/valgrind.supp | 130 +++------------------------------------ 1 file changed, 7 insertions(+), 123 deletions(-) diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp index 26e2c1261ab..30d77fa3e72 100644 --- a/mysql-test/valgrind.supp +++ b/mysql-test/valgrind.supp @@ -386,134 +386,18 @@ fun:__libc_start_main } +# +# dlclose can allocate memory for error message, the memory will be +# freed by dlerror or other dl* function. +# { - dlclose memory loss from udf_free + memory "loss" from dlclose error messages Memcheck:Leak - fun:calloc - fun:_dlerror_run + fun:*alloc + ... fun:dlclose - fun:_Z8udf_freev } -{ - dlsym memory loss from udf_free on SuSE 11.1 x64 variant 2 - Memcheck:Leak - fun:calloc - obj:/lib*/ld-*.so - fun:dlclose - fun:udf_free -} - -{ - dlclose memory loss from plugin variant 1 - Memcheck:Leak - fun:calloc - fun:_dlerror_run - fun:dlclose - fun:plugin_dl_del(st_mysql_lex_string const*) -} - -{ - dlclose memory loss from plugin variant 2 - Memcheck:Leak - fun:malloc - fun:_dl_close_worker - fun:_dl_close - fun:_dl_catch_error - fun:_dlerror_run - fun:dlclose - fun:_Z15free_plugin_memP12st_plugin_dl - fun:_Z13plugin_dl_delPK19st_mysql_lex_string -} - -{ - dlclose memory loss from plugin variant 3 - Memcheck:Leak - fun:malloc - fun:_dl_scope_free - fun:_dl_close_worker - fun:_dl_close - fun:_dl_catch_error - fun:_dlerror_run - fun:dlclose - fun:_Z15free_plugin_memP12st_plugin_dl - fun:_Z13plugin_dl_delPK19st_mysql_lex_string -} - -{ - dlclose memory loss from plugin variant 4 - Memcheck:Leak - fun:malloc - obj:/lib*/ld-*.so - obj:/lib*/ld-*.so - obj:/lib*/ld-*.so - obj:/lib*/libdl-*.so - fun:dlclose - fun:_ZL15free_plugin_memP12st_plugin_dl - fun:_ZL13plugin_dl_delPK19st_mysql_lex_string -} - -{ - dlclose memory loss from plugin variant 5 - Memcheck:Leak - fun:malloc - obj:/lib*/ld-*.so - obj:/lib*/ld-*.so - obj:/lib*/ld-*.so - obj:/lib*/ld-*.so - obj:/lib*/libdl-*.so - fun:dlclose - fun:_ZL15free_plugin_memP12st_plugin_dl -} - -{ - dlclose memory loss from plugin variant 6, seen on Ubuntu Jaunty i686 - Memcheck:Leak - fun:malloc - fun:_dl_scope_free - fun:_dl_close_worker - fun:_dl_close - fun:dlclose_doit - fun:_dl_catch_error - fun:_dlerror_run - fun:dlclose - fun:_ZL15free_plugin_memP12st_plugin_dl - fun:_ZL13plugin_dl_delPK19st_mysql_lex_string -} - -{ - dlclose memory loss from plugin variant 7, seen on Ubuntu Jaunty i686 - Memcheck:Leak - fun:malloc - fun:_dl_close_worker - fun:_dl_close - fun:dlclose_doit - fun:_dl_catch_error - fun:_dlerror_run - fun:dlclose - fun:_ZL15free_plugin_memP12st_plugin_dl - fun:_ZL13plugin_dl_delPK19st_mysql_lex_string -} - -{ - dlclose memory loss from plugin variant 8 - Memcheck:Leak - fun:calloc - fun:_dlerror_run - fun:dlclose - fun:_Z15free_plugin_memP12st_plugin_dl - fun:_Z13plugin_dl_delPK19st_mysql_lex_string -} - -{ - dlclose memory loss from plugin variant 9 - Memcheck:Leak - fun:calloc - fun:_dlerror_run - fun:dlclose - fun:_ZL15free_plugin_memP12st_plugin_dl - fun:_ZL13plugin_dl_delPK19st_mysql_lex_string -} { dlsym memory loss from plugin on SuSE 11.1 x64 From 2be9a419f5e680dbb9b02fe6ce1f07d2442ae938 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Wed, 21 Dec 2011 13:23:15 +0200 Subject: [PATCH 015/135] Fixes lp:907049 "Server started with skip-aria crashes on an attempt to connect to it" sql/sql_parse.cc: Only call ha_maria::implicit_commit if aria is enabled --- sql/sql_parse.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 41f308a2ce4..8c51ea69618 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -190,7 +190,8 @@ bool end_active_trans(THD *thd) if (ha_commit(thd)) error=1; #ifdef WITH_MARIA_STORAGE_ENGINE - ha_maria::implicit_commit(thd, TRUE); + if (ha_storage_engine_is_enabled(maria_hton)) + ha_maria::implicit_commit(thd, TRUE); #endif } thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG); @@ -1297,6 +1298,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, char *beginning_of_next_stmt= (char*) end_of_stmt; #ifdef WITH_MARIA_STORAGE_ENGINE + if (ha_storage_engine_is_enabled(maria_hton)) ha_maria::implicit_commit(thd, FALSE); #endif @@ -1722,7 +1724,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->transaction.stmt.reset(); #ifdef WITH_MARIA_STORAGE_ENGINE - ha_maria::implicit_commit(thd, FALSE); + if (ha_storage_engine_is_enabled(maria_hton)) + ha_maria::implicit_commit(thd, FALSE); #endif if (!(sql_command_flags[thd->lex->sql_command] & CF_CHANGES_DATA)) From a5e92c7e6d8a6540a63038e4b982599cec2d077f Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 22 Dec 2011 11:07:04 +0100 Subject: [PATCH 016/135] compilation warning - unused variable --- storage/maria/ha_maria.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index 99a1e2cc903..04a97da9d8d 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -2430,8 +2430,8 @@ int ha_maria::extra_opt(enum ha_extra_function operation, ulong cache_size) int ha_maria::delete_all_rows() { - THD *thd= table->in_use; #ifdef EXTRA_DEBUG + THD *thd= table->in_use; TRN *trn= file->trn; if (trn && ! (trnman_get_flags(trn) & TRN_STATE_INFO_LOGGED)) { From 0e8f71b2bcd8430fa0f1677fa605a6b0fc5daf7b Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Thu, 22 Dec 2011 15:50:33 +0100 Subject: [PATCH 017/135] LPBUG#906638 : Fixes to build oqgraph with boost 1.48 - dijkstra_shortest_paths() needs a Graph as first parameter, in case of reverse_graph we now need to use its m_g member - use boost::tuples::tie() on all places where tie() was used . Reason - fix the build with Visual Studio 10 SP1 (which includes std:tr1:tie, thus creating ambiguity) --- storage/oqgraph/graphcore.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/storage/oqgraph/graphcore.cc b/storage/oqgraph/graphcore.cc index 0b856ac253f..ba179989ea3 100644 --- a/storage/oqgraph/graphcore.cc +++ b/storage/oqgraph/graphcore.cc @@ -414,7 +414,7 @@ namespace open_query { if (record_weight && u != v) { typename graph_traits::out_edge_iterator ei, ei_end; - for (tie(ei, ei_end)= out_edges(v, g); ei != ei_end; ++ei) + for (boost::tuples::tie(ei, ei_end)= out_edges(v, g); ei != ei_end; ++ei) { if (target(*ei, g) == u) { @@ -479,14 +479,14 @@ namespace open_query if (in_degree(dest, g) >= out_degree(orig, g)) { graph_traits::out_edge_iterator ei, ei_end; - tie(ei, ei_end)= out_edges(orig, g); + boost::tuples::tie(ei, ei_end)= out_edges(orig, g); if ((ei= find_if(ei, ei_end, target_equals(dest, g))) != ei_end) return *ei; } else { graph_traits::in_edge_iterator ei, ei_end; - tie(ei, ei_end)= in_edges(dest, g); + boost::tuples::tie(ei, ei_end)= in_edges(dest, g); if ((ei= find_if(ei, ei_end, source_equals(orig, g))) != ei_end) return *ei; } @@ -727,7 +727,7 @@ namespace open_query if ((cursor= new (std::nothrow) stack_cursor(share)) && orig) { graph_traits::out_edge_iterator ei, ei_end; - for (tie(ei, ei_end)= out_edges(*orig, share->g); ei != ei_end; ++ei) + for (boost::tuples::tie(ei, ei_end)= out_edges(*orig, share->g); ei != ei_end; ++ei) { Vertex v= target(*ei, share->g); static_cast(cursor)-> @@ -741,7 +741,7 @@ namespace open_query dest) { graph_traits::in_edge_iterator ei, ei_end; - for (tie(ei, ei_end)= in_edges(*dest, share->g); ei != ei_end; ++ei) + for (boost::tuples::tie(ei, ei_end)= in_edges(*dest, share->g); ei != ei_end; ++ei) { Vertex v= source(*ei, share->g); static_cast(cursor)-> @@ -876,7 +876,7 @@ namespace open_query switch (ALGORITHM & op) { case DIJKSTRAS: - dijkstra_shortest_paths(r, *dest, + dijkstra_shortest_paths(r.m_g, *dest, weight_map( share->weightmap ). @@ -1067,7 +1067,7 @@ int edges_cursor::fetch_row(const row &row_info, row &result) edge_iterator it, end; reference ref; size_t count= position; - for (tie(it, end)= edges(share->g); count && it != end; ++it, --count) + for (boost::tuples::tie(it, end)= edges(share->g); count && it != end; ++it, --count) ; if (it != end) ref= reference(position+1, *it); From c9259f166bfcc757338c957f806e3d18637da17a Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Tue, 27 Dec 2011 13:19:13 -0800 Subject: [PATCH 018/135] Fixed LP bug #904345. The MIN/MAX optimizer code from the function opt_sum_query erroneously did not take into account conjunctive conditions that did not depend on any table, yet were not identified as constant items. These could be items containing rand() or PS/SP parameters. These items are supposed to be evaluated at the execution phase. That's why if such conditions can be extracted from the WHERE condition the MIN/MAX optimization is not applied as currently it is always done at the optimization phase. (In 5.3 expensive subqueries are also evaluated only at the execution phase. So, if a constant condition with such subquery can be extracted from the WHERE clause the MIN/MAX optimization should not be applied in 5.3.) IF an IN/ALL/SOME predicate with a constant left part is transformed into an EXISTS subquery the resulting subquery should not be considered uncacheable if the right part of the predicate is not uncacheable. Backported the function dbug_print_item() from 5.3. The function is used only for debugging. --- mysql-test/r/func_group.result | 40 +++++++++++++++++++++++- mysql-test/r/ps_11bugs.result | 6 ++-- mysql-test/r/select.result | 8 ++--- mysql-test/r/select_pkeycache.result | 8 ++--- mysql-test/r/subselect.result | 14 ++++----- mysql-test/suite/pbxt/r/ps_11bugs.result | 6 ++-- mysql-test/suite/pbxt/r/select.result | 8 ++--- mysql-test/suite/pbxt/r/subselect.result | 4 +-- mysql-test/t/func_group.test | 27 +++++++++++++++- sql/item.cc | 21 +++++++++++++ sql/item_subselect.cc | 13 +++++--- sql/opt_sum.cc | 3 +- 12 files changed, 123 insertions(+), 35 deletions(-) diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result index 2ff1cd2ec4a..de5672941c7 100644 --- a/mysql-test/r/func_group.result +++ b/mysql-test/r/func_group.result @@ -1767,4 +1767,42 @@ MAX(a) 10 drop table t1; # -End of 5.1 tests +# Bug #904345: MIN/MAX optimization with constant FALSE condition +# +CREATE TABLE t1 (a int NOT NULL, KEY(a)); +INSERT INTO t1 VALUES (10), (8), (11), (7), (15), (12), (9); +CREATE TABLE t2 (a int, b int); +INSERT INTO t2 VALUES +(8,2), (6,9), (8,4), (5,3), (9,1); +EXPLAIN EXTENDED +SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT 3,4) AND a<10; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible HAVING +Warnings: +Note 1003 select max(`test`.`t1`.`a`) AS `MAX(a)` from `test`.`t1` where 0 +SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT 3,4) AND a<10; +MAX(a) +NULL +EXPLAIN EXTENDED +SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT a,b FROM t2 WHERE b<5) and a<10; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where +Warnings: +Note 1003 select max(`test`.`t1`.`a`) AS `MAX(a)` from `test`.`t1` where 0 +SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT a,b FROM t2 WHERE b<5) and a<10; +MAX(a) +NULL +EXPLAIN EXTENDED +SELECT MAX(a) FROM t1 WHERE RAND()*0<>0 AND a<10; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 range a a 4 NULL 4 100.00 Using where; Using index +Warnings: +Note 1003 select max(`test`.`t1`.`a`) AS `MAX(a)` from `test`.`t1` where (((rand() * 0) <> 0) and (`test`.`t1`.`a` < 10)) +SELECT MAX(a) FROM t1 WHERE RAND()*0<>0 AND a<10; +MAX(a) +NULL +DROP TABLE t1,t2; +# +End of 5.2 tests diff --git a/mysql-test/r/ps_11bugs.result b/mysql-test/r/ps_11bugs.result index 5c11163ab9e..3b4d525aeb4 100644 --- a/mysql-test/r/ps_11bugs.result +++ b/mysql-test/r/ps_11bugs.result @@ -120,9 +120,9 @@ 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 Impossible HAVING -3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL Impossible HAVING +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible HAVING +3 UNION NULL NULL NULL NULL NULL NULL NULL Impossible HAVING NULL UNION RESULT ALL NULL NULL NULL NULL NULL select * from t1 where 3 in (select (1+1) union select 1); a diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 5453345d50c..e2c2dcaced4 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -2778,10 +2778,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away explain select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +1 SIMPLE t1 index key1 key1 5 NULL 4 Using where; Using index explain select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +1 SIMPLE t1 range key1 key1 5 NULL 3 Using where; Using index select max(key1) from t1 where key1 <= 0.6158; max(key1) 0.615800023078918 @@ -2800,10 +2800,10 @@ max(key1) min(key2) 0.615800023078918 1.37619996070862 select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5; max(key1) -0.615800023078918 +0.384499996900558 select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5; min(key1) -0.376199990510941 +0.384499996900558 DROP TABLE t1,t2; CREATE TABLE t1 (i BIGINT UNSIGNED NOT NULL); INSERT INTO t1 VALUES (10); diff --git a/mysql-test/r/select_pkeycache.result b/mysql-test/r/select_pkeycache.result index 5453345d50c..e2c2dcaced4 100644 --- a/mysql-test/r/select_pkeycache.result +++ b/mysql-test/r/select_pkeycache.result @@ -2778,10 +2778,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away explain select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +1 SIMPLE t1 index key1 key1 5 NULL 4 Using where; Using index explain select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +1 SIMPLE t1 range key1 key1 5 NULL 3 Using where; Using index select max(key1) from t1 where key1 <= 0.6158; max(key1) 0.615800023078918 @@ -2800,10 +2800,10 @@ max(key1) min(key2) 0.615800023078918 1.37619996070862 select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5; max(key1) -0.615800023078918 +0.384499996900558 select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5; min(key1) -0.376199990510941 +0.384499996900558 DROP TABLE t1,t2; CREATE TABLE t1 (i BIGINT UNSIGNED NOT NULL); INSERT INTO t1 VALUES (10); diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 1f3432ecde1..65e76d04c1f 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -1302,7 +1302,7 @@ SELECT 0 IN (SELECT 1 FROM t1 a); EXPLAIN EXTENDED SELECT 0 IN (SELECT 1 FROM t1 a); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used -2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE Warnings: Note 1003 select (0,(select 1 from `test`.`t1` `a` where 0)) AS `0 IN (SELECT 1 FROM t1 a)` INSERT INTO t1 (pseudo) VALUES ('test1'); @@ -1312,7 +1312,7 @@ SELECT 0 IN (SELECT 1 FROM t1 a); EXPLAIN EXTENDED SELECT 0 IN (SELECT 1 FROM t1 a); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used -2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE Warnings: Note 1003 select (0,(select 1 from `test`.`t1` `a` where 0)) AS `0 IN (SELECT 1 FROM t1 a)` drop table t1; @@ -4476,15 +4476,15 @@ INSERT INTO t1 VALUES (1),(2); EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT 1 FROM t1 GROUP BY a); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 -2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort +2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort Warnings: -Note 1003 select 1 AS `1` from `test`.`t1` where (1,(select 1 from `test`.`t1` group by `test`.`t1`.`a` having 1)) +Note 1003 select 1 AS `1` from `test`.`t1` where 1 EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT 1 FROM t1 WHERE a > 3 GROUP BY a); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables -2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary; Using filesort +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary; Using filesort Warnings: -Note 1003 select 1 AS `1` from `test`.`t1` where (1,(select 1 from `test`.`t1` where (`test`.`t1`.`a` > 3) group by `test`.`t1`.`a` having 1)) +Note 1003 select 1 AS `1` from `test`.`t1` where 0 DROP TABLE t1; # # Bug#45061: Incorrectly market field caused wrong result. diff --git a/mysql-test/suite/pbxt/r/ps_11bugs.result b/mysql-test/suite/pbxt/r/ps_11bugs.result index fad35b97b24..0be781bca27 100644 --- a/mysql-test/suite/pbxt/r/ps_11bugs.result +++ b/mysql-test/suite/pbxt/r/ps_11bugs.result @@ -120,9 +120,9 @@ 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 Impossible HAVING -3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL Impossible HAVING +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible HAVING +3 UNION NULL NULL NULL NULL NULL NULL NULL Impossible HAVING NULL UNION RESULT ALL NULL NULL NULL NULL NULL select * from t1 where 3 in (select (1+1) union select 1); a diff --git a/mysql-test/suite/pbxt/r/select.result b/mysql-test/suite/pbxt/r/select.result index c06dd06ea3e..b98f980f821 100644 --- a/mysql-test/suite/pbxt/r/select.result +++ b/mysql-test/suite/pbxt/r/select.result @@ -2786,10 +2786,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away explain select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +1 SIMPLE t1 index key1 key1 5 NULL 4 Using where; Using index explain select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +1 SIMPLE t1 index key1 key1 5 NULL 4 Using where; Using index select max(key1) from t1 where key1 <= 0.6158; max(key1) 0.615800023078918 @@ -2808,10 +2808,10 @@ max(key1) min(key2) 0.615800023078918 1.37619996070862 select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5; max(key1) -0.615800023078918 +0.384499996900558 select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5; min(key1) -0.376199990510941 +0.384499996900558 DROP TABLE t1,t2; CREATE TABLE t1 (i BIGINT UNSIGNED NOT NULL); INSERT INTO t1 VALUES (10); diff --git a/mysql-test/suite/pbxt/r/subselect.result b/mysql-test/suite/pbxt/r/subselect.result index 0cdec48e192..63b289d259e 100644 --- a/mysql-test/suite/pbxt/r/subselect.result +++ b/mysql-test/suite/pbxt/r/subselect.result @@ -1177,7 +1177,7 @@ SELECT 0 IN (SELECT 1 FROM t1 a); EXPLAIN EXTENDED SELECT 0 IN (SELECT 1 FROM t1 a); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used -2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE Warnings: Note 1003 select (0,(select 1 from `test`.`t1` `a` where 0)) AS `0 IN (SELECT 1 FROM t1 a)` INSERT INTO t1 (pseudo) VALUES ('test1'); @@ -1187,7 +1187,7 @@ SELECT 0 IN (SELECT 1 FROM t1 a); EXPLAIN EXTENDED SELECT 0 IN (SELECT 1 FROM t1 a); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used -2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE Warnings: Note 1003 select (0,(select 1 from `test`.`t1` `a` where 0)) AS `0 IN (SELECT 1 FROM t1 a)` drop table t1; diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test index 8c2be79ee7d..84afe328aeb 100644 --- a/mysql-test/t/func_group.test +++ b/mysql-test/t/func_group.test @@ -1150,4 +1150,29 @@ SELECT MAX(a) FROM t1 WHERE a NOT BETWEEN 3 AND 9; drop table t1; --echo # ---echo End of 5.1 tests +--echo # Bug #904345: MIN/MAX optimization with constant FALSE condition +--echo # + +CREATE TABLE t1 (a int NOT NULL, KEY(a)); +INSERT INTO t1 VALUES (10), (8), (11), (7), (15), (12), (9); + +CREATE TABLE t2 (a int, b int); +INSERT INTO t2 VALUES + (8,2), (6,9), (8,4), (5,3), (9,1); + +EXPLAIN EXTENDED +SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT 3,4) AND a<10; +SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT 3,4) AND a<10; + +EXPLAIN EXTENDED +SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT a,b FROM t2 WHERE b<5) and a<10; +SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT a,b FROM t2 WHERE b<5) and a<10; + +EXPLAIN EXTENDED +SELECT MAX(a) FROM t1 WHERE RAND()*0<>0 AND a<10; +SELECT MAX(a) FROM t1 WHERE RAND()*0<>0 AND a<10; + +DROP TABLE t1,t2; + +--echo # +--echo End of 5.2 tests diff --git a/sql/item.cc b/sql/item.cc index c08333e4b80..72adb9d0b52 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -7915,6 +7915,27 @@ void view_error_processor(THD *thd, void *data) ((TABLE_LIST *)data)->hide_view_error(thd); } +#ifndef DBUG_OFF + +/* Debugger help function */ +static char dbug_item_print_buf[256]; + +const char *dbug_print_item(Item *item) +{ + char *buf= dbug_item_print_buf; + String str(buf, sizeof(dbug_item_print_buf), &my_charset_bin); + str.length(0); + if (!item) + return "(Item*)NULL"; + item->print(&str ,QT_ORDINARY); + if (str.c_ptr() == buf) + return buf; + else + return "Couldn't fit into buffer"; +} + +#endif /*DBUG_OFF*/ + /***************************************************************************** ** Instantiate templates *****************************************************************************/ diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index fa9eff0d95b..82d2313aa2b 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1117,8 +1117,8 @@ Item_in_subselect::single_value_transformer(JOIN *join, (Item**)optimizer->get_cache(), (char *)"", (char *)in_left_expr_name); - - master_unit->uncacheable|= UNCACHEABLE_DEPENDENT; + if (!left_expr->const_item()) + master_unit->uncacheable|= UNCACHEABLE_DEPENDENT; } if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards) { @@ -1127,7 +1127,8 @@ Item_in_subselect::single_value_transformer(JOIN *join, pushed_cond_guards[0]= TRUE; } - select_lex->uncacheable|= UNCACHEABLE_DEPENDENT; + if (!left_expr->const_item()) + select_lex->uncacheable|= UNCACHEABLE_DEPENDENT; if (join->having || select_lex->with_sum_func || select_lex->group_list.elements) { @@ -1338,7 +1339,8 @@ Item_in_subselect::row_value_transformer(JOIN *join) optimizer->keep_top_level_cache(); thd->lex->current_select= current; - master_unit->uncacheable|= UNCACHEABLE_DEPENDENT; + if (!left_expr->const_item()) + master_unit->uncacheable|= UNCACHEABLE_DEPENDENT; if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards) { @@ -1350,7 +1352,8 @@ Item_in_subselect::row_value_transformer(JOIN *join) } } - select_lex->uncacheable|= UNCACHEABLE_DEPENDENT; + if (!left_expr->const_item()) + select_lex->uncacheable|= UNCACHEABLE_DEPENDENT; if (is_having_used) { /* diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index f8a81eac380..27a848cb0ec 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -608,7 +608,8 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo, if (!cond) DBUG_RETURN(TRUE); Field *field= field_part->field; - if (!(cond->used_tables() & field->table->map)) + if (!(cond->used_tables() & field->table->map) && + test(cond->used_tables() & ~PSEUDO_TABLE_BITS)) { /* Condition doesn't restrict the used table */ DBUG_RETURN(TRUE); From 31805e621495e33d4dcf4e4b2180d42367f90894 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Tue, 27 Dec 2011 19:13:53 -0800 Subject: [PATCH 019/135] Fixed LP bug #879860. The MIN/MAX optimization cannot be applied to a subquery if its WHERE clause contains a conjunctive condition depending on an outer reference. --- mysql-test/r/func_group.result | 23 +++++++++++++++++++++++ mysql-test/t/func_group.test | 19 +++++++++++++++++++ sql/opt_sum.cc | 4 ++++ 3 files changed, 46 insertions(+) diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result index de5672941c7..3608f587572 100644 --- a/mysql-test/r/func_group.result +++ b/mysql-test/r/func_group.result @@ -1805,4 +1805,27 @@ MAX(a) NULL DROP TABLE t1,t2; # +# Bug #879860: MIN/MAX for subquery returning empty set +# +CREATE TABLE t1 (a int PRIMARY KEY); +INSERT INTO t1 VALUES (1); +CREATE TABLE t2 (a int NOT NULL); +INSERT INTO t2 VALUES (10); +CREATE TABLE t3 ( a int, b int); +INSERT INTO t3 VALUES (19,1), (20,5); +EXPLAIN EXTENDED +SELECT (SELECT MIN(t1.a) FROM t1,t2 WHERE t2.a = t3.b) FROM t3; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t3 ALL NULL NULL NULL NULL 2 100.00 +2 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 1 100.00 +2 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 1 100.00 +Warnings: +Note 1276 Field or reference 'test.t3.b' of SELECT #2 was resolved in SELECT #1 +Note 1003 select (select min('1') from `test`.`t1` join `test`.`t2` where ('10' = `test`.`t3`.`b`)) AS `(SELECT MIN(t1.a) FROM t1,t2 WHERE t2.a = t3.b)` from `test`.`t3` +SELECT (SELECT MIN(t1.a) FROM t1,t2 WHERE t2.a = t3.b) FROM t3; +(SELECT MIN(t1.a) FROM t1,t2 WHERE t2.a = t3.b) +NULL +NULL +DROP TABLE t1,t2,t3; +# End of 5.2 tests diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test index 84afe328aeb..3939d53cb31 100644 --- a/mysql-test/t/func_group.test +++ b/mysql-test/t/func_group.test @@ -1174,5 +1174,24 @@ SELECT MAX(a) FROM t1 WHERE RAND()*0<>0 AND a<10; DROP TABLE t1,t2; +--echo # +--echo # Bug #879860: MIN/MAX for subquery returning empty set +--echo # + +CREATE TABLE t1 (a int PRIMARY KEY); +INSERT INTO t1 VALUES (1); + +CREATE TABLE t2 (a int NOT NULL); +INSERT INTO t2 VALUES (10); + +CREATE TABLE t3 ( a int, b int); +INSERT INTO t3 VALUES (19,1), (20,5); + +EXPLAIN EXTENDED +SELECT (SELECT MIN(t1.a) FROM t1,t2 WHERE t2.a = t3.b) FROM t3; +SELECT (SELECT MIN(t1.a) FROM t1,t2 WHERE t2.a = t3.b) FROM t3; + +DROP TABLE t1,t2,t3; + --echo # --echo End of 5.2 tests diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index 27a848cb0ec..cd6e7a4ffaa 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -608,6 +608,10 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo, if (!cond) DBUG_RETURN(TRUE); Field *field= field_part->field; + if (cond->used_tables() & OUTER_REF_TABLE_BIT) + { + DBUG_RETURN(FALSE); + } if (!(cond->used_tables() & field->table->map) && test(cond->used_tables() & ~PSEUDO_TABLE_BITS)) { From 5ab628e0240ae280c0b5b03e1d64b2242cd7265e Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Wed, 28 Dec 2011 18:47:01 -0800 Subject: [PATCH 020/135] Fixed LP bug #777654. The method Item_sum_num::fix_fields() calculated the value of the flag Item_sum_num::maybe_null in some cases incorrectly. --- mysql-test/r/sum_distinct.result | 12 ++++++++++++ mysql-test/t/sum_distinct.test | 12 ++++++++++++ sql/item_sum.cc | 3 +-- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/sum_distinct.result b/mysql-test/r/sum_distinct.result index c615817f52d..2746f5a09f4 100644 --- a/mysql-test/r/sum_distinct.result +++ b/mysql-test/r/sum_distinct.result @@ -95,3 +95,15 @@ SELECT SUM(DISTINCT id % 11) FROM t1; SUM(DISTINCT id % 11) 55 DROP TABLE t1; +# +# Bug #777654: empty subselect in FROM clause returning +# SUM(DISTINCT) over non-nullable field +# +CREATE TABLE t1 (a int NOT NULL) ; +SELECT SUM(DISTINCT a) FROM t1; +SUM(DISTINCT a) +NULL +SELECT * FROM (SELECT SUM(DISTINCT a) FROM t1) AS t; +SUM(DISTINCT a) +NULL +DROP TABLE t1; diff --git a/mysql-test/t/sum_distinct.test b/mysql-test/t/sum_distinct.test index c58155a8e25..633a72fddc8 100644 --- a/mysql-test/t/sum_distinct.test +++ b/mysql-test/t/sum_distinct.test @@ -93,3 +93,15 @@ SELECT SUM(DISTINCT id) FROM t1; SELECT SUM(DISTINCT id % 11) FROM t1; DROP TABLE t1; + +--echo # +--echo # Bug #777654: empty subselect in FROM clause returning +--echo # SUM(DISTINCT) over non-nullable field +--echo # + +CREATE TABLE t1 (a int NOT NULL) ; + +SELECT SUM(DISTINCT a) FROM t1; +SELECT * FROM (SELECT SUM(DISTINCT a) FROM t1) AS t; + +DROP TABLE t1; diff --git a/sql/item_sum.cc b/sql/item_sum.cc index ce7602b7f03..ac6ddc0fd54 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -568,13 +568,12 @@ Item_sum_num::fix_fields(THD *thd, Item **ref) return TRUE; decimals=0; - maybe_null=0; + maybe_null= sum_func() != COUNT_FUNC; for (uint i=0 ; i < arg_count ; i++) { if (args[i]->fix_fields(thd, args + i) || args[i]->check_cols(1)) return TRUE; set_if_bigger(decimals, args[i]->decimals); - maybe_null |= args[i]->maybe_null; } result_field=0; max_length=float_length(decimals); From 40c42468bcbe215a971f93edb9af27545156b8a7 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Thu, 29 Dec 2011 15:09:20 -0800 Subject: [PATCH 021/135] Fixed LP bug #806057. A table expression with a natural join or a USING clause is transformed into an equivalent expression with equi-join ON conditions. If a reference to a virtual column happened to occur only in these generated equi-join conditions then it was not erroneously marked in the TABLE::vcol_set bitmap. This could lead to wrong results for queries containing natural join expressions or USING clauses. --- .../suite/vcol/r/vcol_select_myisam.result | 30 +++++++++++++++++++ .../suite/vcol/t/vcol_select_myisam.test | 20 +++++++++++++ sql/sql_base.cc | 7 ++++- 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/vcol/r/vcol_select_myisam.result b/mysql-test/suite/vcol/r/vcol_select_myisam.result index 45e4defd315..04ae7e0f7cd 100644 --- a/mysql-test/suite/vcol/r/vcol_select_myisam.result +++ b/mysql-test/suite/vcol/r/vcol_select_myisam.result @@ -262,3 +262,33 @@ NULL explain select sum(c) from t1 group by b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort +# +# Bug #806057: join with USING over a virtual column +# +CREATE TABLE t1 (b int); +INSERT INTO t1 VALUES (NULL),( 78), (185), (0), (154); +CREATE TABLE t2 (a int, b int AS (a) VIRTUAL); +INSERT INTO t2 VALUES (187,187), (9,9), (187,187); +Warnings: +Warning 1647 The value specified for computed column 'b' in table 't2' ignored +Warning 1647 The value specified for computed column 'b' in table 't2' ignored +Warning 1647 The value specified for computed column 'b' in table 't2' ignored +EXPLAIN EXTENDED +SELECT * FROM t1 JOIN t2 USING (b); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer +Warnings: +Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where (`test`.`t1`.`b` = `test`.`t2`.`b`) +SELECT * FROM t1 JOIN t2 USING (b); +b a +EXPLAIN EXTENDED +SELECT * FROM t1 NATURAL JOIN t2; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer +Warnings: +Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where (`test`.`t1`.`b` = `test`.`t2`.`b`) +SELECT * FROM t1 NATURAL JOIN t2; +b a +DROP TABLE t1,t2; diff --git a/mysql-test/suite/vcol/t/vcol_select_myisam.test b/mysql-test/suite/vcol/t/vcol_select_myisam.test index 855e02ac113..c14faba576d 100644 --- a/mysql-test/suite/vcol/t/vcol_select_myisam.test +++ b/mysql-test/suite/vcol/t/vcol_select_myisam.test @@ -48,3 +48,23 @@ eval SET @@session.storage_engine = 'MyISAM'; #------------------------------------------------------------------------------# # Cleanup --source suite/vcol/inc/vcol_cleanup.inc + +--echo # +--echo # Bug #806057: join with USING over a virtual column +--echo # + +CREATE TABLE t1 (b int); +INSERT INTO t1 VALUES (NULL),( 78), (185), (0), (154); + +CREATE TABLE t2 (a int, b int AS (a) VIRTUAL); +INSERT INTO t2 VALUES (187,187), (9,9), (187,187); + +EXPLAIN EXTENDED +SELECT * FROM t1 JOIN t2 USING (b); +SELECT * FROM t1 JOIN t2 USING (b); + +EXPLAIN EXTENDED +SELECT * FROM t1 NATURAL JOIN t2; +SELECT * FROM t1 NATURAL JOIN t2; + +DROP TABLE t1,t2; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 4616b5c2430..bd02bbca7ea 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -7151,11 +7151,16 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2, if (!(eq_cond= new Item_func_eq(item_ident_1, item_ident_2))) goto err; /* Out of memory. */ + if (field_1 && field_1->vcol_info) + field_1->table->mark_virtual_col(field_1); + if (field_2 && field_2->vcol_info) + field_2->table->mark_virtual_col(field_2); + /* Add the new equi-join condition to the ON clause. Notice that fix_fields() is applied to all ON conditions in setup_conds() so we don't do it here. - */ + */ add_join_on((table_ref_1->outer_join & JOIN_TYPE_RIGHT ? table_ref_1 : table_ref_2), eq_cond); From a0afa025a3f949efe0f414c2bf562139c4069f88 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Mon, 2 Jan 2012 23:52:31 +0100 Subject: [PATCH 022/135] Fix embedded/windows tests- move COND_manager and LOCK_manager to sql_manager.cc, to prevent race condition that results into accessing already destroyed critical section --- sql/mysql_priv.h | 4 ++-- sql/mysqld.cc | 4 ---- sql/sql_manager.cc | 12 ++++++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 065425c4c96..ed23ecb50fe 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -2091,7 +2091,7 @@ extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open, LOCK_lock_db, LOCK_mapped_file,LOCK_user_locks, LOCK_status, LOCK_error_log, LOCK_delayed_insert, LOCK_short_uuid_generator, LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone, - LOCK_slave_list, LOCK_active_mi, LOCK_manager, LOCK_global_read_lock, + LOCK_slave_list, LOCK_active_mi, LOCK_global_read_lock, LOCK_global_system_variables, LOCK_user_conn, LOCK_prepared_stmt_count, LOCK_bytes_sent, LOCK_bytes_received, LOCK_connection_count; @@ -2109,7 +2109,7 @@ extern pthread_mutex_t LOCK_stats; extern int mysqld_server_started; extern rw_lock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave; extern rw_lock_t LOCK_system_variables_hash; -extern pthread_cond_t COND_refresh, COND_thread_count, COND_manager; +extern pthread_cond_t COND_refresh, COND_thread_count; extern pthread_cond_t COND_global_read_lock; extern pthread_attr_t connection_attrib; extern I_List threads; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 0d0ad919515..aa27ea0f582 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1516,7 +1516,6 @@ static void clean_up_mutexes() (void) pthread_mutex_destroy(&LOCK_delayed_insert); (void) pthread_mutex_destroy(&LOCK_delayed_status); (void) pthread_mutex_destroy(&LOCK_delayed_create); - (void) pthread_mutex_destroy(&LOCK_manager); (void) pthread_mutex_destroy(&LOCK_crypt); (void) pthread_mutex_destroy(&LOCK_bytes_sent); (void) pthread_mutex_destroy(&LOCK_bytes_received); @@ -1557,7 +1556,6 @@ static void clean_up_mutexes() (void) pthread_cond_destroy(&COND_global_read_lock); (void) pthread_cond_destroy(&COND_thread_cache); (void) pthread_cond_destroy(&COND_flush_thread_cache); - (void) pthread_cond_destroy(&COND_manager); DBUG_VOID_RETURN; } @@ -3817,7 +3815,6 @@ static int init_thread_environment() (void) pthread_mutex_init(&LOCK_delayed_insert,MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_delayed_status,MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_delayed_create,MY_MUTEX_INIT_SLOW); - (void) pthread_mutex_init(&LOCK_manager,MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_crypt,MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_bytes_sent,MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_bytes_received,MY_MUTEX_INIT_FAST); @@ -3857,7 +3854,6 @@ static int init_thread_environment() (void) pthread_cond_init(&COND_global_read_lock,NULL); (void) pthread_cond_init(&COND_thread_cache,NULL); (void) pthread_cond_init(&COND_flush_thread_cache,NULL); - (void) pthread_cond_init(&COND_manager,NULL); #ifdef HAVE_REPLICATION (void) pthread_mutex_init(&LOCK_rpl_status, MY_MUTEX_INIT_FAST); (void) pthread_cond_init(&COND_rpl_status, NULL); diff --git a/sql/sql_manager.cc b/sql/sql_manager.cc index cf0a73d0ce7..57fe5072dcd 100644 --- a/sql/sql_manager.cc +++ b/sql/sql_manager.cc @@ -44,6 +44,7 @@ static struct handler_cb * volatile cb_list; bool mysql_manager_submit(void (*action)()) { bool result= FALSE; + DBUG_ASSERT(manager_thread_in_use); struct handler_cb * volatile *cb; pthread_mutex_lock(&LOCK_manager); cb= &cb_list; @@ -75,8 +76,9 @@ pthread_handler_t handle_manager(void *arg __attribute__((unused))) pthread_detach_this_thread(); manager_thread = pthread_self(); + (void) pthread_cond_init(&COND_manager,NULL); + (void) pthread_mutex_init(&LOCK_manager,NULL); manager_thread_in_use = 1; - for (;;) { pthread_mutex_lock(&LOCK_manager); @@ -123,6 +125,8 @@ pthread_handler_t handle_manager(void *arg __attribute__((unused))) } } manager_thread_in_use = 0; + (void) pthread_mutex_destroy(&LOCK_manager); + (void) pthread_cond_destroy(&COND_manager); DBUG_LEAVE; // Can't use DBUG_RETURN after my_thread_end my_thread_end(); return (NULL); @@ -149,14 +153,14 @@ void stop_handle_manager() { DBUG_ENTER("stop_handle_manager"); abort_manager = true; - pthread_mutex_lock(&LOCK_manager); if (manager_thread_in_use) { + pthread_mutex_lock(&LOCK_manager); DBUG_PRINT("quit", ("initiate shutdown of handle manager thread: 0x%lx", (ulong)manager_thread)); - pthread_cond_signal(&COND_manager); + pthread_cond_signal(&COND_manager); + pthread_mutex_unlock(&LOCK_manager); } - pthread_mutex_unlock(&LOCK_manager); DBUG_VOID_RETURN; } From d63fc00f35e40315848133991ca6f336e3f87eb9 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Jan 2012 11:06:52 +0200 Subject: [PATCH 023/135] Fix of LP BUG#793589 Wrong result with double ORDER BY Problem was in caching 'eq_ref' dependency between calls of remove_const() for ORDER BY and GROUP BY lists. --- mysql-test/r/order_by.result | 54 ++++++++++++++++++++++++++++++++++++ mysql-test/t/order_by.test | 29 +++++++++++++++++++ sql/sql_select.cc | 9 ++++++ 3 files changed, 92 insertions(+) diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index 0c522aef290..88d4e729c1f 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -1672,3 +1672,57 @@ select 1 order by max(1) + min(1); 1 1 End of 5.1 tests +# +# Fix of LP BUG#793589 Wrong result with double ORDER BY +# +CREATE TABLE t1 ( b int) ; +INSERT INTO t1 VALUES (8),(9); +CREATE TABLE t2 ( a int, b int, PRIMARY KEY (a)) ; +INSERT INTO t2 VALUES (6,7),(7,7),(8,1),(9,7),(10,1),(11,5),(12,2),(13,0),(14,1),(15,8),(16,1),(17,1),(18,9),(19,1),(20,5); +SELECT t2.b AS field1 FROM t1, t2 WHERE t1.b = t2.a GROUP BY field1 ORDER BY t1.b, field1; +field1 +1 +7 +SELECT t2.b, t1.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b, t2.b; +b b +1 8 +7 9 +SELECT t2.b,t1.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b; +b b +1 8 +7 9 +SELECT t2.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b; +b +1 +7 +# field1 removed from ORDER BY +explain extended +SELECT t2.b AS field1 FROM t1, t2 WHERE t1.b = t2.a GROUP BY field1 ORDER BY t1.b, field1; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 100.00 +Warnings: +Note 1003 select `test`.`t2`.`b` AS `field1` from `test`.`t1` join `test`.`t2` where (`test`.`t2`.`a` = `test`.`t1`.`b`) group by `test`.`t2`.`b` order by `test`.`t1`.`b` +explain extended +SELECT t2.b, t1.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b, t2.b; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 100.00 +Warnings: +Note 1003 select `test`.`t2`.`b` AS `b`,`test`.`t1`.`b` AS `b` from `test`.`t1` join `test`.`t2` where (`test`.`t2`.`a` = `test`.`t1`.`b`) group by `test`.`t2`.`b` order by `test`.`t1`.`b` +explain extended +SELECT t2.b,t1.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 100.00 +Warnings: +Note 1003 select `test`.`t2`.`b` AS `b`,`test`.`t1`.`b` AS `b` from `test`.`t1` join `test`.`t2` where (`test`.`t2`.`a` = `test`.`t1`.`b`) group by `test`.`t2`.`b` order by `test`.`t1`.`b` +explain extended +SELECT t2.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 100.00 +Warnings: +Note 1003 select `test`.`t2`.`b` AS `b` from `test`.`t1` join `test`.`t2` where (`test`.`t2`.`a` = `test`.`t1`.`b`) group by `test`.`t2`.`b` order by `test`.`t1`.`b` +drop table t1,t2; +End of 5.2 tests diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test index 2a5f74a3a13..add256a7451 100644 --- a/mysql-test/t/order_by.test +++ b/mysql-test/t/order_by.test @@ -1518,3 +1518,32 @@ DROP TABLE t1; select 1 order by max(1) + min(1); --echo End of 5.1 tests + +--echo # +--echo # Fix of LP BUG#793589 Wrong result with double ORDER BY +--echo # +CREATE TABLE t1 ( b int) ; +INSERT INTO t1 VALUES (8),(9); + +CREATE TABLE t2 ( a int, b int, PRIMARY KEY (a)) ; +INSERT INTO t2 VALUES (6,7),(7,7),(8,1),(9,7),(10,1),(11,5),(12,2),(13,0),(14,1),(15,8),(16,1),(17,1),(18,9),(19,1),(20,5); + +SELECT t2.b AS field1 FROM t1, t2 WHERE t1.b = t2.a GROUP BY field1 ORDER BY t1.b, field1; +SELECT t2.b, t1.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b, t2.b; +SELECT t2.b,t1.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b; +SELECT t2.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b; + +--echo # field1 removed from ORDER BY +explain extended +SELECT t2.b AS field1 FROM t1, t2 WHERE t1.b = t2.a GROUP BY field1 ORDER BY t1.b, field1; +explain extended +SELECT t2.b, t1.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b, t2.b; +explain extended +SELECT t2.b,t1.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b; +explain extended +SELECT t2.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b; + + +drop table t1,t2; + +--echo End of 5.2 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index b066ad1544d..3af05c3015a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -7368,6 +7368,15 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond, table_map ref; DBUG_ENTER("remove_const"); + /* + Cleanup to avoid interference of calls of this function for + ORDER BY and GROUP BY + */ + for (JOIN_TAB *tab= join->join_tab + join->const_tables; + tab < join->join_tab + join->tables; + tab++) + tab->cached_eq_ref_table= FALSE; + prev_ptr= &first_order; *simple_order= *join->join_tab[join->const_tables].on_expr_ref ? 0 : 1; From d725c52d27cb206bb0dc17c629535655a11885c2 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Sat, 7 Jan 2012 10:23:46 +0200 Subject: [PATCH 024/135] Fixed wrong merge --- sql/sql_parse.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 8aed1229f5b..1510ea7bf10 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -190,7 +190,6 @@ bool end_active_trans(THD *thd) if (ha_commit(thd)) error=1; #ifdef WITH_ARIA_STORAGE_ENGINE - ha_maria::implicit_commit(thd, TRUE); if (ha_storage_engine_is_enabled(maria_hton)) ha_maria::implicit_commit(thd, TRUE); #endif @@ -1664,7 +1663,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->transaction.stmt.reset(); #ifdef WITH_ARIA_STORAGE_ENGINE - ha_maria::implicit_commit(thd, FALSE); if (ha_storage_engine_is_enabled(maria_hton)) ha_maria::implicit_commit(thd, FALSE); #endif From 629cdab80827e7ad6bb23f7c8dc20724eb87f4d9 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Sun, 8 Jan 2012 20:29:05 +0200 Subject: [PATCH 025/135] Fixed compiler and test failures found by buildbot configure.in: Added testing of STRNDUP (not found on solaris) mysql-test/include/wait_until_connected_again.inc: Also test for error 2005 (can happen on windows) mysql-test/include/wait_until_disconnected.inc: Also test for error 2005 (can happen on windows) mysql-test/suite/innodb_plugin/r/innodb_bug30423.result: Number of rows is not stable (found difference on Solaris) mysql-test/suite/innodb_plugin/t/innodb_bug30423.test: Number of rows is not stable (found difference on Solaris) plugin/auth_pam/auth_pam.c: Use internal strndup if it doesn't exist on system (solaris) Changed code so that it should also compile on solaris. --- configure.in | 2 +- .../include/wait_until_connected_again.inc | 2 +- .../include/wait_until_disconnected.inc | 2 +- .../innodb_plugin/r/innodb_bug30423.result | 6 ++-- .../innodb_plugin/t/innodb_bug30423.test | 1 + plugin/auth_pam/auth_pam.c | 33 +++++++++++++++++-- 6 files changed, 37 insertions(+), 9 deletions(-) diff --git a/configure.in b/configure.in index a592fb76a0e..9c3cbd283dc 100644 --- a/configure.in +++ b/configure.in @@ -2033,7 +2033,7 @@ dnl Checks for library functions. AC_FUNC_ALLOCA AC_PROG_GCC_TRADITIONAL AC_TYPE_SIGNAL -AC_CHECK_FUNCS(re_comp regcomp strdup) +AC_CHECK_FUNCS(re_comp regcomp strdup strndup) dnl Sun compilers have their own vis.h that is about something dnl totally different. So, not to change the libedit source, we diff --git a/mysql-test/include/wait_until_connected_again.inc b/mysql-test/include/wait_until_connected_again.inc index aff92141a8b..96240e36db7 100644 --- a/mysql-test/include/wait_until_connected_again.inc +++ b/mysql-test/include/wait_until_connected_again.inc @@ -14,7 +14,7 @@ while ($mysql_errno) # Strangely enough, the server might return "Too many connections" # while being shutdown, thus 1040 is an "allowed" error # See BUG#36228 - --error 0,1040,1053,2002,2003,2006,2013 + --error 0,1040,1053,2002,2003,2005,2006,2013 show status; dec $counter; diff --git a/mysql-test/include/wait_until_disconnected.inc b/mysql-test/include/wait_until_disconnected.inc index c274fbbe089..71361682442 100644 --- a/mysql-test/include/wait_until_disconnected.inc +++ b/mysql-test/include/wait_until_disconnected.inc @@ -12,7 +12,7 @@ while (!$mysql_errno) # Strangely enough, the server might return "Too many connections" # while being shutdown, thus 1040 is an "allowed" error. # See BUG#36228. - --error 0,1040,1053,2002,2003,2006,2013 + --error 0,1040,1053,2002,2003,2005,2006,2013 show status; dec $counter; diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug30423.result b/mysql-test/suite/innodb_plugin/r/innodb_bug30423.result index a19809366ae..6071587e888 100644 --- a/mysql-test/suite/innodb_plugin/r/innodb_bug30423.result +++ b/mysql-test/suite/innodb_plugin/r/innodb_bug30423.result @@ -48,9 +48,9 @@ ON orgs.org_id=sa_opportunities.org_id LEFT JOIN bug30243_2 contacts ON orgs.org_id=contacts.org_id ; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE orgs index NULL org_id 4 NULL 128 Using index -1 SIMPLE sa_opportunities ref org_id org_id 5 test.orgs.org_id 1 Using index -1 SIMPLE contacts ref contacts$org_id contacts$org_id 5 test.orgs.org_id 1 Using index +1 SIMPLE orgs index NULL org_id 4 NULL # Using index +1 SIMPLE sa_opportunities ref org_id org_id 5 test.orgs.org_id # Using index +1 SIMPLE contacts ref contacts$org_id contacts$org_id 5 test.orgs.org_id # Using index select @@innodb_stats_method; @@innodb_stats_method nulls_ignored diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug30423.test b/mysql-test/suite/innodb_plugin/t/innodb_bug30423.test index 458c2967e19..da490589400 100644 --- a/mysql-test/suite/innodb_plugin/t/innodb_bug30423.test +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug30423.test @@ -140,6 +140,7 @@ analyze table bug30243_3; # Following query plan shows that we get the correct rows per # unique value (should be approximately 1 row per value) +--replace_column 9 # explain SELECT COUNT(*), 0 FROM bug30243_1 orgs LEFT JOIN bug30243_3 sa_opportunities diff --git a/plugin/auth_pam/auth_pam.c b/plugin/auth_pam/auth_pam.c index 45c49975f6e..0d9cf2ae0af 100644 --- a/plugin/auth_pam/auth_pam.c +++ b/plugin/auth_pam/auth_pam.c @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -8,6 +9,24 @@ struct param { MYSQL_PLUGIN_VIO *vio; }; +/* It least solaris doesn't have strndup */ + +#ifndef HAVE_STRNDUP +char *strndup(const char *from, size_t length) +{ + char *ptr; + size_t max_length= strlen(from); + if (length > max_length) + length= max_length; + if ((ptr= (char*) malloc(length+1)) != 0) + { + memcpy((char*) ptr, (char*) from, length); + ptr[length]=0; + } + return ptr; +} +#endif + static int conv(int n, const struct pam_message **msg, struct pam_response **resp, void *data) { @@ -71,13 +90,21 @@ static int conv(int n, const struct pam_message **msg, #define DO(X) if ((status = (X)) != PAM_SUCCESS) goto end +#ifdef SOLARIS +typedef void** pam_get_item_3_arg; +#else +typedef const void** pam_get_item_3_arg; +#endif + static int pam_auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info) { pam_handle_t *pamh = NULL; int status; const char *new_username; struct param param; - struct pam_conv c = { &conv, ¶m }; + /* The following is written in such a way to make also solaris happy */ + struct pam_conv pam_start_arg = { &conv, NULL }; + pam_start_arg.appdata_ptr= (char*) ¶m; /* get the service name, as specified in @@ -90,10 +117,10 @@ static int pam_auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info) param.ptr = param.buf + 1; param.vio = vio; - DO( pam_start(service, info->user_name, &c, &pamh) ); + DO( pam_start(service, info->user_name, &pam_start_arg, &pamh) ); DO( pam_authenticate (pamh, 0) ); DO( pam_acct_mgmt(pamh, 0) ); - DO( pam_get_item(pamh, PAM_USER, (const void**)&new_username) ); + DO( pam_get_item(pamh, PAM_USER, (pam_get_item_3_arg) &new_username) ); if (new_username && strcmp(new_username, info->user_name)) strncpy(info->authenticated_as, new_username, From 39ebfa51ef1dbb2807ea46063e6a5936103ffb01 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 10 Jan 2012 19:23:00 +0100 Subject: [PATCH 026/135] Fix MDEV-49 : version_compile_machine server variable is 'unknown' for x64 builds --- include/config-win.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/config-win.h b/include/config-win.h index 9369c72e83d..86fcc61aa9b 100644 --- a/include/config-win.h +++ b/include/config-win.h @@ -45,8 +45,8 @@ #define MACHINE_TYPE "ia64" #elif defined(_M_IX86) #define MACHINE_TYPE "ia32" -#elif defined(_M_ALPHA) -#define MACHINE_TYPE "axp" +#elif defined(_M_X64) +#define MACHINE_TYPE "x64" #else #define MACHINE_TYPE "unknown" /* Define to machine type name */ #endif From 22876a5495b5ddb9a310a56953a1b572946712c1 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 10 Jan 2012 19:26:47 +0100 Subject: [PATCH 027/135] MDEV-50 : Fix default compilation comment --- win/cmake/mysql_version.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/cmake/mysql_version.cmake b/win/cmake/mysql_version.cmake index 79e6a18ee1d..e6b64d3003e 100644 --- a/win/cmake/mysql_version.cmake +++ b/win/cmake/mysql_version.cmake @@ -81,7 +81,7 @@ IF(NOT MYSQL_UNIX_ADDR) SET(MYSQL_UNIX_ADDR "/tmp/mysql.sock") ENDIF() IF(NOT COMPILATION_COMMENT) - SET(COMPILATION_COMMENT "Source distribution") + SET(COMPILATION_COMMENT "mariadb.org binary distribution") ENDIF() From 6dfe0956d64b41a2e4eda0f40feaad799cd84058 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Fri, 13 Jan 2012 12:23:19 -0800 Subject: [PATCH 028/135] Back-ported the test cases for bug #12763207 from mysql-5.6 code line into 5.2 Completed the fix for this bug. Note: in 5.3 the affected 'if' statement in Item_in_subselect::single_value_transformer() starting with the condition (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY) should be removed altogether. The change from table.cc is not needed either. This is because in 5.3 - min/max transformation for subqueries are done at the optimization phase - evaluation of the expensive subqueries is done at the execution phase. Added an EXPLAIN EXTENDED to the test case for bug #12329653. --- mysql-test/r/subselect.result | 53 +++++++++++++++++++++++++++++++++++ mysql-test/t/subselect.test | 53 +++++++++++++++++++++++++++++++++++ sql/item_subselect.cc | 3 +- sql/table.cc | 1 + 4 files changed, 109 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 65e76d04c1f..5063b4c6db9 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -4568,6 +4568,13 @@ CREATE TABLE t1(a1 int); INSERT INTO t1 VALUES (1),(2); SELECT @@session.sql_mode INTO @old_sql_mode; SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; +EXPLAIN EXTENDED +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 +2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 +Warnings: +Note 1003 select 1 AS `1` from `test`.`t1` where 1 SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1); 1 1 @@ -5088,4 +5095,50 @@ NULL NULL 5 DROP TABLE t1, t2, t3; +# +# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER +# +CREATE TABLE t1(a1 int); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2(a1 int); +INSERT INTO t2 VALUES (3); +SELECT @@session.sql_mode INTO @old_sql_mode; +SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2 FROM t2); +1 +1 +1 +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2.0 FROM t2); +1 +1 +1 +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 'a' FROM t2); +1 +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t2); +1 +1 +1 +SET SESSION sql_mode=@old_sql_mode; +DROP TABLE t1, t2; +create table t2(i int); +insert into t2 values(0); +SELECT @@session.sql_mode INTO @old_sql_mode; +SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; +CREATE VIEW v1 AS +SELECT 'f' FROM t2 UNION SELECT 'x' FROM t2 +; +CREATE TABLE t1 ( +pk int NOT NULL, +col_varchar_key varchar(1) DEFAULT NULL, +PRIMARY KEY (pk), +KEY col_varchar_key (col_varchar_key) +); +SELECT t1.pk +FROM t1 +WHERE t1.col_varchar_key < ALL ( SELECT * FROM v1 ) +; +pk +SET SESSION sql_mode=@old_sql_mode; +drop table t2, t1; +drop view v1; End of 5.2 tests diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index b918e800dd5..e4ed6188f25 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -3460,6 +3460,8 @@ SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; ## First a simpler query, illustrating the transformation ## '1 < some (...)' => '1 < max(...)' +EXPLAIN EXTENDED +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1); SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1); ## The query which made the server crash. @@ -3958,4 +3960,55 @@ INSERT INTO t3 VALUES (0),(0); SELECT a1.f3 AS r FROM t2 AS a1 , t1 WHERE a1.f3 < ALL ( SELECT f3 FROM t3 WHERE f3 = 1 ) ; DROP TABLE t1, t2, t3; +--echo # +--echo # Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER +--echo # + +CREATE TABLE t1(a1 int); +INSERT INTO t1 VALUES (1),(2); + +CREATE TABLE t2(a1 int); +INSERT INTO t2 VALUES (3); + +SELECT @@session.sql_mode INTO @old_sql_mode; +SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; + +## All these are subject to the transformation +## '1 < some (...)' => '1 < max(...)' +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2 FROM t2); +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2.0 FROM t2); +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 'a' FROM t2); +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t2); + +SET SESSION sql_mode=@old_sql_mode; + +DROP TABLE t1, t2; + +create table t2(i int); +insert into t2 values(0); + +SELECT @@session.sql_mode INTO @old_sql_mode; +SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; + +CREATE VIEW v1 AS +SELECT 'f' FROM t2 UNION SELECT 'x' FROM t2 +; + +CREATE TABLE t1 ( + pk int NOT NULL, + col_varchar_key varchar(1) DEFAULT NULL, + PRIMARY KEY (pk), + KEY col_varchar_key (col_varchar_key) +); + +SELECT t1.pk +FROM t1 +WHERE t1.col_varchar_key < ALL ( SELECT * FROM v1 ) +; + +SET SESSION sql_mode=@old_sql_mode; + +drop table t2, t1; +drop view v1; + --echo End of 5.2 tests diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 82d2313aa2b..2828ae8c4ec 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1057,7 +1057,8 @@ Item_in_subselect::single_value_transformer(JOIN *join, print_where(item, "rewrite with MIN/MAX", QT_ORDINARY);); if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY) { - DBUG_ASSERT(select_lex->non_agg_field_used()); + DBUG_ASSERT(item->get_arg(0)->real_item()->type() != Item::FIELD_ITEM || + select_lex->non_agg_field_used()); select_lex->set_non_agg_field_used(false); } diff --git a/sql/table.cc b/sql/table.cc index ca14b2ef4d2..a3df9023805 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -4467,6 +4467,7 @@ Item *Field_iterator_table::create_item(THD *thd) { select->non_agg_fields.push_back(item); item->marker= select->cur_pos_in_select_list; + select->set_non_agg_field_used(true); } return item; } From 4de7978a3f3e716a6b1b280ce1f30dd501e31545 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Fri, 13 Jan 2012 19:00:50 -0800 Subject: [PATCH 029/135] Back-ported the fix and the test case for bug #50257 from mariadb-5.3 code line. Adjusted results for a few test cases. --- mysql-test/r/index_merge_myisam.result | 2 +- mysql-test/r/subselect.result | 20 ++++++++++++++++--- mysql-test/suite/innodb/r/innodb_mysql.result | 6 +++--- .../suite/innodb_plugin/r/innodb_mysql.result | 6 +++--- mysql-test/suite/pbxt/r/subselect.result | 4 ++-- mysql-test/t/subselect.test | 15 ++++++++++++-- sql/sql_select.cc | 3 +-- 7 files changed, 40 insertions(+), 16 deletions(-) diff --git a/mysql-test/r/index_merge_myisam.result b/mysql-test/r/index_merge_myisam.result index df570e1f4ae..ad44f241f5c 100644 --- a/mysql-test/r/index_merge_myisam.result +++ b/mysql-test/r/index_merge_myisam.result @@ -1486,7 +1486,7 @@ EXPLAIN SELECT t1.f1 FROM t1 WHERE (SELECT COUNT(*) FROM t2 WHERE t2.f3 = 'h' AND t2.f2 = t1.f1) = 0 AND t1.f1 = 2; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 -2 DEPENDENT SUBQUERY t2 ref f2,f3 f2 5 1 Using where +2 DEPENDENT SUBQUERY t2 ref f2,f3 f2 5 const 1 Using where DROP TABLE t1,t2; # # Generic @@optimizer_switch tests (move those into a separate file if diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 5063b4c6db9..f1e65f0fb1f 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -363,9 +363,9 @@ INSERT INTO t8 (pseudo,email) VALUES ('2joce1','2test1'); EXPLAIN EXTENDED SELECT pseudo,(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce')) FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index -4 SUBQUERY t8 const PRIMARY PRIMARY 37 1 100.00 Using index +4 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index 2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 -3 SUBQUERY t8 const PRIMARY PRIMARY 37 1 100.00 Using index +3 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index Warnings: Note 1003 select 'joce' AS `pseudo`,(select 'test' from `test`.`t8` where 1) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where 1 SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM @@ -4780,7 +4780,6 @@ EXPLAIN EXTENDED SELECT DISTINCT 1 FROM t1, WHERE t1.a = d1.a; ERROR 42S22: Unknown column 'd1.a' in 'where clause' DROP TABLE t1; -End of 5.1 tests. Set up test tables. CREATE TABLE t1 ( t1_id INT UNSIGNED, @@ -5141,4 +5140,19 @@ pk SET SESSION sql_mode=@old_sql_mode; drop table t2, t1; drop view v1; +# +# BUG#50257: Missing info in REF column of the EXPLAIN +# lines for subselects +# +CREATE TABLE t1 (a INT, b INT, INDEX (a)); +INSERT INTO t1 VALUES (3, 10), (2, 20), (7, 10), (5, 20); +EXPLAIN SELECT * FROM (SELECT * FROM t1 WHERE a=7) t; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY system NULL NULL NULL NULL 1 +2 DERIVED t1 ref a a 5 const 1 Using where +EXPLAIN SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t1 WHERE a=7); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 +2 SUBQUERY t1 ref a a 5 const 1 Using where; Using index +DROP TABLE t1; End of 5.2 tests diff --git a/mysql-test/suite/innodb/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result index 666d6b7591f..e022bd961d6 100644 --- a/mysql-test/suite/innodb/r/innodb_mysql.result +++ b/mysql-test/suite/innodb/r/innodb_mysql.result @@ -1739,7 +1739,7 @@ SELECT 1 FROM (SELECT COUNT(DISTINCT c1) FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY system NULL NULL NULL NULL 1 -2 DERIVED t1 ALL c3,c2 c3 5 5 Using where; Using filesort +2 DERIVED t1 ALL c3,c2 c3 5 const 5 Using where; Using filesort DROP TABLE t1; CREATE TABLE t1 (c1 REAL, c2 REAL, c3 REAL, KEY (c3), KEY (c2, c3)) ENGINE=InnoDB; @@ -1753,7 +1753,7 @@ SELECT 1 FROM (SELECT COUNT(DISTINCT c1) FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY system NULL NULL NULL NULL 1 -2 DERIVED t1 ALL c3,c2 c3 9 5 Using where; Using filesort +2 DERIVED t1 ALL c3,c2 c3 9 const 5 Using where; Using filesort DROP TABLE t1; CREATE TABLE t1 (c1 DECIMAL(12,2), c2 DECIMAL(12,2), c3 DECIMAL(12,2), KEY (c3), KEY (c2, c3)) @@ -1768,7 +1768,7 @@ SELECT 1 FROM (SELECT COUNT(DISTINCT c1) FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY system NULL NULL NULL NULL 1 -2 DERIVED t1 ALL c3,c2 c3 7 5 Using where; Using filesort +2 DERIVED t1 ALL c3,c2 c3 7 const 5 Using where; Using filesort DROP TABLE t1; End of 5.1 tests drop table if exists t1, t2, t3; diff --git a/mysql-test/suite/innodb_plugin/r/innodb_mysql.result b/mysql-test/suite/innodb_plugin/r/innodb_mysql.result index 987a04eb59d..49e8b44b018 100644 --- a/mysql-test/suite/innodb_plugin/r/innodb_mysql.result +++ b/mysql-test/suite/innodb_plugin/r/innodb_mysql.result @@ -1739,7 +1739,7 @@ SELECT 1 FROM (SELECT COUNT(DISTINCT c1) FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY system NULL NULL NULL NULL 1 -2 DERIVED t1 ALL c3,c2 c3 5 5 Using where; Using filesort +2 DERIVED t1 ALL c3,c2 c3 5 const 5 Using where; Using filesort DROP TABLE t1; CREATE TABLE t1 (c1 REAL, c2 REAL, c3 REAL, KEY (c3), KEY (c2, c3)) ENGINE=InnoDB; @@ -1753,7 +1753,7 @@ SELECT 1 FROM (SELECT COUNT(DISTINCT c1) FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY system NULL NULL NULL NULL 1 -2 DERIVED t1 ALL c3,c2 c3 9 5 Using where; Using filesort +2 DERIVED t1 ALL c3,c2 c3 9 const 5 Using where; Using filesort DROP TABLE t1; CREATE TABLE t1 (c1 DECIMAL(12,2), c2 DECIMAL(12,2), c3 DECIMAL(12,2), KEY (c3), KEY (c2, c3)) @@ -1768,7 +1768,7 @@ SELECT 1 FROM (SELECT COUNT(DISTINCT c1) FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY system NULL NULL NULL NULL 1 -2 DERIVED t1 ALL c3,c2 c3 7 5 Using where; Using filesort +2 DERIVED t1 ALL c3,c2 c3 7 const 5 Using where; Using filesort DROP TABLE t1; End of 5.1 tests drop table if exists t1, t2, t3; diff --git a/mysql-test/suite/pbxt/r/subselect.result b/mysql-test/suite/pbxt/r/subselect.result index 63b289d259e..0b5c98324f4 100644 --- a/mysql-test/suite/pbxt/r/subselect.result +++ b/mysql-test/suite/pbxt/r/subselect.result @@ -363,9 +363,9 @@ INSERT INTO t8 (pseudo,email) VALUES ('2joce1','2test1'); EXPLAIN EXTENDED SELECT pseudo,(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce')) FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index -4 SUBQUERY t8 const PRIMARY PRIMARY 37 1 100.00 Using index +4 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index 2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 -3 SUBQUERY t8 const PRIMARY PRIMARY 37 1 100.00 Using index +3 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index Warnings: Note 1003 select 'joce' AS `pseudo`,(select 'test' from `test`.`t8` where 1) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where 1 SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index e4ed6188f25..1f3c102770c 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -3710,8 +3710,6 @@ WHERE t1.a = d1.a; DROP TABLE t1; ---echo End of 5.1 tests. - # # Bug #47904 Incorrect results w/ table subquery, derived SQs, and LEFT JOIN on index # @@ -4011,4 +4009,17 @@ SET SESSION sql_mode=@old_sql_mode; drop table t2, t1; drop view v1; +--echo # +--echo # BUG#50257: Missing info in REF column of the EXPLAIN +--echo # lines for subselects +--echo # + +CREATE TABLE t1 (a INT, b INT, INDEX (a)); +INSERT INTO t1 VALUES (3, 10), (2, 20), (7, 10), (5, 20); + +EXPLAIN SELECT * FROM (SELECT * FROM t1 WHERE a=7) t; +EXPLAIN SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t1 WHERE a=7); + +DROP TABLE t1; + --echo End of 5.2 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 3af05c3015a..3cf0800a62f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -5913,8 +5913,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, if (keyuse->null_rejecting) j->ref.null_rejecting |= 1 << i; keyuse_uses_no_tables= keyuse_uses_no_tables && !keyuse->used_tables; - if (!keyuse->used_tables && - !(join->select_options & SELECT_DESCRIBE)) + if (!keyuse->used_tables &&!thd->lex->describe) { // Compare against constant store_key_item tmp(thd, keyinfo->key_part[i].field, key_buff + maybe_null, From 4b7919368ebd14ec09eef1e8508ebbab71b86e0c Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Sat, 14 Jan 2012 00:02:02 -0800 Subject: [PATCH 030/135] Back-ported the test case for bug #12616253 from mariadb-5.3 that was actually a duplicate of LP bug #888456 fixed in mariadb-5.2. --- mysql-test/r/subselect.result | 41 +++++++++++++++++++++++++++++++++++ mysql-test/t/subselect.test | 21 ++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index f1e65f0fb1f..101869e2843 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -5155,4 +5155,45 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 2 SUBQUERY t1 ref a a 5 const 1 Using where; Using index DROP TABLE t1; +# +# BUG#12616253 - WRONG RESULT WITH EXISTS(SUBQUERY) (MISSING ROWS) +# (duplicate of LP bug #888456) +CREATE TABLE t1 (f1 varchar(1)); +INSERT INTO t1 VALUES ('v'),('s'); +CREATE TABLE t2 (f1_key varchar(1), KEY (f1_key)); +INSERT INTO t2 VALUES ('j'),('v'),('c'),('m'),('d'), +('d'),('y'),('t'),('d'),('s'); +EXPLAIN +SELECT table1.f1, table2.f1_key FROM t1 AS table1, t2 AS table2 +WHERE EXISTS (SELECT DISTINCT f1_key FROM t2 +WHERE f1_key != table2.f1_key AND f1_key >= table1.f1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY table1 ALL NULL NULL NULL NULL 2 +1 PRIMARY table2 index NULL f1_key 4 NULL 10 Using where; Using index; Using join buffer +2 DEPENDENT SUBQUERY t2 index f1_key f1_key 4 NULL 10 Using where; Using index; Using temporary +SELECT table1.f1, table2.f1_key FROM t1 AS table1, t2 AS table2 +WHERE EXISTS (SELECT DISTINCT f1_key FROM t2 +WHERE f1_key != table2.f1_key AND f1_key >= table1.f1); +f1 f1_key +v j +s j +v v +s v +v c +s c +v m +s m +v d +s d +v d +s d +v y +s y +v t +s t +v d +s d +v s +s s +DROP TABLE t1,t2; End of 5.2 tests diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 1f3c102770c..24aad3a145d 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -4022,4 +4022,25 @@ EXPLAIN SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t1 WHERE a=7); DROP TABLE t1; +--echo # +--echo # BUG#12616253 - WRONG RESULT WITH EXISTS(SUBQUERY) (MISSING ROWS) +--echo # (duplicate of LP bug #888456) + +CREATE TABLE t1 (f1 varchar(1)); +INSERT INTO t1 VALUES ('v'),('s'); + +CREATE TABLE t2 (f1_key varchar(1), KEY (f1_key)); +INSERT INTO t2 VALUES ('j'),('v'),('c'),('m'),('d'), +('d'),('y'),('t'),('d'),('s'); + +EXPLAIN +SELECT table1.f1, table2.f1_key FROM t1 AS table1, t2 AS table2 + WHERE EXISTS (SELECT DISTINCT f1_key FROM t2 + WHERE f1_key != table2.f1_key AND f1_key >= table1.f1); +SELECT table1.f1, table2.f1_key FROM t1 AS table1, t2 AS table2 + WHERE EXISTS (SELECT DISTINCT f1_key FROM t2 + WHERE f1_key != table2.f1_key AND f1_key >= table1.f1); + +DROP TABLE t1,t2; + --echo End of 5.2 tests From 1417606b1f4c5f8a4c24f6a93a77586f9cf5975c Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 29 Dec 2011 22:52:13 +0100 Subject: [PATCH 031/135] on windows: don't link all plugins with mysqld, only do it for storage engines. --- storage/mysql_storage_engine.cmake | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/storage/mysql_storage_engine.cmake b/storage/mysql_storage_engine.cmake index cbe9a310d67..cc3659d51c9 100644 --- a/storage/mysql_storage_engine.cmake +++ b/storage/mysql_storage_engine.cmake @@ -42,7 +42,7 @@ IF(NOT SOURCE_SUBLIBS) ADD_DEFINITIONS(-DMYSQL_DYNAMIC_PLUGIN) ADD_VERSION_INFO(${${engine}_LIB} SHARED ${engine}_SOURCES) ADD_LIBRARY(${${engine}_LIB} MODULE ${${engine}_SOURCES}) - TARGET_LINK_LIBRARIES (${${engine}_LIB} mysqlservices mysqld) + TARGET_LINK_LIBRARIES (${${engine}_LIB} mysqlservices) IF(${engine}_LIBS) TARGET_LINK_LIBRARIES(${${engine}_LIB} ${${engine}_LIBS}) ENDIF(${engine}_LIBS) @@ -61,6 +61,8 @@ IF(NOT SOURCE_SUBLIBS) ${CMAKE_SOURCE_DIR}/extra/yassl/include) IF(${ENGINE_BUILD_TYPE} STREQUAL "STATIC") ADD_DEFINITIONS(-DWITH_${engine}_STORAGE_ENGINE -DMYSQL_SERVER) + ELSEIF(${ENGINE_BUILD_TYPE} STREQUAL "DYNAMIC") + TARGET_LINK_LIBRARIES (${${engine}_LIB} mysqld) ENDIF(${ENGINE_BUILD_TYPE} STREQUAL "STATIC") ENDIF(NOT SOURCE_SUBLIBS) ENDMACRO(MYSQL_STORAGE_ENGINE) From 74fdbec68e81fb30a82ab5f9ff66b748d506f909 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Thu, 29 Dec 2011 21:55:17 -0800 Subject: [PATCH 032/135] Fixed LP bug #848652. The cause of this bug was the same as for bug 902356 fixed for 5.3. --- mysql-test/r/join_outer_innodb.result | 8 ++++++++ mysql-test/t/join_outer_innodb.test | 15 +++++++++++++++ sql/sql_select.cc | 7 ++++--- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/join_outer_innodb.result b/mysql-test/r/join_outer_innodb.result index e8a2d6f668b..c8bc9758408 100644 --- a/mysql-test/r/join_outer_innodb.result +++ b/mysql-test/r/join_outer_innodb.result @@ -17,3 +17,11 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 index NULL fkey 5 NULL 5 Using index 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.fkey 1 Using where DROP TABLE t1,t2; +CREATE TABLE t1(a int, b int, KEY (a), PRIMARY KEY (b)) ENGINE=InnoDB; +CREATE TABLE t2 (b int, PRIMARY KEY (b)); +INSERT INTO t2 VALUES (4),(9); +SELECT STRAIGHT_JOIN t1.a FROM t1 RIGHT JOIN t2 ON t1.b = t2.b +WHERE (t1.b NOT BETWEEN 1 AND 7 OR t1.a IS NULL AND t1.b = t2.b) AND t2.b = 4 +GROUP BY 1; +a +DROP TABLE t1,t2; diff --git a/mysql-test/t/join_outer_innodb.test b/mysql-test/t/join_outer_innodb.test index 40add7f488f..565bb72b152 100644 --- a/mysql-test/t/join_outer_innodb.test +++ b/mysql-test/t/join_outer_innodb.test @@ -24,3 +24,18 @@ SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id WHERE t1.name LIKE 'A%' OR FALSE; DROP TABLE t1,t2; + +# +# Bug #848652: crash with RIGHT JOIN and GROUP BY +# + +CREATE TABLE t1(a int, b int, KEY (a), PRIMARY KEY (b)) ENGINE=InnoDB; + +CREATE TABLE t2 (b int, PRIMARY KEY (b)); +INSERT INTO t2 VALUES (4),(9); + +SELECT STRAIGHT_JOIN t1.a FROM t1 RIGHT JOIN t2 ON t1.b = t2.b + WHERE (t1.b NOT BETWEEN 1 AND 7 OR t1.a IS NULL AND t1.b = t2.b) AND t2.b = 4 +GROUP BY 1; + +DROP TABLE t1,t2; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 8b7261a8712..5963a1c318a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -13725,8 +13725,8 @@ find_field_in_item_list (Field *field, void *data) while ((item= li++)) { - if (item->type() == Item::FIELD_ITEM && - ((Item_field*) item)->field->eq(field)) + if (item->real_item()->type() == Item::FIELD_ITEM && + ((Item_field*) (item->real_item()))->field->eq(field)) { part_found= 1; break; @@ -13994,7 +13994,8 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, uint used_pk_parts= 0; if (used_key_parts > used_index_parts) used_pk_parts= used_key_parts-used_index_parts; - rec_per_key= keyinfo->rec_per_key[used_key_parts-1]; + rec_per_key= used_key_parts ? + keyinfo->rec_per_key[used_key_parts-1] : 1; /* Take into account the selectivity of the used pk prefix */ if (used_pk_parts) { From b8b7b4eb6bef26d05257272be02674ae5514ded9 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 30 Dec 2011 13:57:03 +0100 Subject: [PATCH 033/135] plugin renamed socket_peercred -> unix_socket. test added. --- mysql-test/suite/plugins/r/unix_socket.result | 30 ++++++++++ mysql-test/suite/plugins/t/unix_socket.test | 56 +++++++++++++++++++ plugin/auth/auth_socket.c | 18 +----- 3 files changed, 87 insertions(+), 17 deletions(-) create mode 100644 mysql-test/suite/plugins/r/unix_socket.result create mode 100644 mysql-test/suite/plugins/t/unix_socket.test diff --git a/mysql-test/suite/plugins/r/unix_socket.result b/mysql-test/suite/plugins/r/unix_socket.result new file mode 100644 index 00000000000..45bf608cc93 --- /dev/null +++ b/mysql-test/suite/plugins/r/unix_socket.result @@ -0,0 +1,30 @@ +install plugin unix_socket soname 'auth_socket.so'; +# +# with named user +# +create user USER identified via unix_socket; +# +# name match = ok +# +select user(), current_user(), database(); +user() current_user() database() +USER@localhost USER@% test +# +# name does not match = failure +# +drop user USER; +# +# and now with anonymous user +# +grant SELECT ON test.* TO '' identified via unix_socket; +# +# name match = ok +# +select user(), current_user(), database(); +user() current_user() database() +USER@localhost @% test +# +# name does not match = failure +# +delete from mysql.user where user=''; +uninstall plugin unix_socket; diff --git a/mysql-test/suite/plugins/t/unix_socket.test b/mysql-test/suite/plugins/t/unix_socket.test new file mode 100644 index 00000000000..fc2e6c5b3c6 --- /dev/null +++ b/mysql-test/suite/plugins/t/unix_socket.test @@ -0,0 +1,56 @@ +--source include/not_embedded.inc + +if (!$AUTH_SOCKET_SO) { + skip No auth_socket plugin; +} + +let $plugindir=`SELECT @@global.plugin_dir`; + +eval install plugin unix_socket soname '$AUTH_SOCKET_SO'; + +--echo # +--echo # with named user +--echo # + +--replace_result $USER USER +eval create user $USER identified via unix_socket; + +--write_file $MYSQLTEST_VARDIR/tmp/peercred_test.txt +--replace_result $USER USER +select user(), current_user(), database(); +EOF + +--echo # +--echo # name match = ok +--echo # +--exec $MYSQL_TEST -u $USER --plugin-dir=$plugindir < $MYSQLTEST_VARDIR/tmp/peercred_test.txt + +--echo # +--echo # name does not match = failure +--echo # +--error 1 +--exec $MYSQL_TEST -u foobar --plugin-dir=$plugindir < $MYSQLTEST_VARDIR/tmp/peercred_test.txt + +--replace_result $USER USER +eval drop user $USER; + +--echo # +--echo # and now with anonymous user +--echo # +grant SELECT ON test.* TO '' identified via unix_socket; +--echo # +--echo # name match = ok +--echo # +--exec $MYSQL_TEST -u $USER --plugin-dir=$plugindir < $MYSQLTEST_VARDIR/tmp/peercred_test.txt + +--echo # +--echo # name does not match = failure +--echo # +--error 1 +--exec $MYSQL_TEST -u foobar --plugin-dir=$plugindir < $MYSQLTEST_VARDIR/tmp/peercred_test.txt + +# restoring mysql.user to the original state. +delete from mysql.user where user=''; +uninstall plugin unix_socket; +--remove_file $MYSQLTEST_VARDIR/tmp/peercred_test.txt + diff --git a/plugin/auth/auth_socket.c b/plugin/auth/auth_socket.c index cc406dac331..89d24e46f3c 100644 --- a/plugin/auth/auth_socket.c +++ b/plugin/auth/auth_socket.c @@ -83,27 +83,11 @@ static struct st_mysql_auth socket_auth_handler= socket_auth }; -mysql_declare_plugin(socket_auth) -{ - MYSQL_AUTHENTICATION_PLUGIN, - &socket_auth_handler, - "socket_peercred", - "Sergei Golubchik", - "Unix Socket based authentication", - PLUGIN_LICENSE_GPL, - NULL, - NULL, - 0x0100, - NULL, - NULL, - NULL -} -mysql_declare_plugin_end; maria_declare_plugin(socket_auth) { MYSQL_AUTHENTICATION_PLUGIN, &socket_auth_handler, - "socket_peercred", + "unix_socket", "Sergei Golubchik", "Unix Socket based authentication", PLUGIN_LICENSE_GPL, From ac3c60d5528f3abdd3a1eb9fade6c05c984fe844 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 4 Jan 2012 20:10:15 +0100 Subject: [PATCH 034/135] report innodb_file_per_table, innodb_flush_log_at_trx_commit, innodb_flush_method --- plugin/feedback/feedback.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/plugin/feedback/feedback.cc b/plugin/feedback/feedback.cc index a8c7ee82ac2..e2daa052859 100644 --- a/plugin/feedback/feedback.cc +++ b/plugin/feedback/feedback.cc @@ -126,6 +126,7 @@ static LEX_STRING vars_filter[]= { {C_STRING_WITH_LEN("ft\\_m%")}, {C_STRING_WITH_LEN("have\\_%")}, {C_STRING_WITH_LEN("%\\_size")}, + {C_STRING_WITH_LEN("innodb_f%")}, {C_STRING_WITH_LEN("%\\_length%")}, {C_STRING_WITH_LEN("%\\_timeout")}, {C_STRING_WITH_LEN("large\\_%")}, From 0b590282fc116a1911eabe4cf1c7804a66f9bb48 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Sun, 8 Jan 2012 14:43:14 +0400 Subject: [PATCH 035/135] BUG#912510: Crash in do_copy_not_null with semijoin=ON, firstmatch=ON, aggregate ... - Create/use do_copy_nullable_row_to_notnull() function for ref access, which is used when copying from not-NULL field in table that can be NULL-complemented to not-NULL field. --- mysql-test/r/subselect_sj.result | 17 ++++++++++++++++ mysql-test/r/subselect_sj_jcl6.result | 17 ++++++++++++++++ mysql-test/t/subselect_sj.test | 19 ++++++++++++++++++ sql/field_conv.cc | 29 ++++++++++++++++++++++++++- sql/sql_select.cc | 3 +++ 5 files changed, 84 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/subselect_sj.result b/mysql-test/r/subselect_sj.result index b1b0bde7c57..f5c3f84bcd7 100644 --- a/mysql-test/r/subselect_sj.result +++ b/mysql-test/r/subselect_sj.result @@ -2152,4 +2152,21 @@ c c set optimizer_prune_level= @opl_901399; set optimizer_switch= @os_091399; DROP TABLE t1,t2; +# +# BUG#912510: Crash in do_copy_not_null with semijoin=ON, firstmatch=ON, aggregate ... +# +CREATE TABLE t1 ( a VARCHAR(1) NOT NULL ); +INSERT INTO t1 VALUES ('k'),('l'); +CREATE TABLE t2 ( b VARCHAR(1) NOT NULL, KEY(b) ); +INSERT INTO t2 VALUES ('k'),('l'); +CREATE TABLE t3 ( c VARCHAR(1) NOT NULL, KEY(c) ); +INSERT INTO t3 VALUES ('m'),('n'); +SELECT a, COUNT(*) FROM t1 +WHERE a IN ( +SELECT b FROM t2 force index(b), t3 force index(c) +WHERE c = b AND b = a +); +a COUNT(*) +NULL 0 +DROP TABLE t1, t2, t3; set optimizer_switch=@subselect_sj_tmp; diff --git a/mysql-test/r/subselect_sj_jcl6.result b/mysql-test/r/subselect_sj_jcl6.result index 2df7d99ee64..21a8ea39457 100644 --- a/mysql-test/r/subselect_sj_jcl6.result +++ b/mysql-test/r/subselect_sj_jcl6.result @@ -2166,6 +2166,23 @@ c c set optimizer_prune_level= @opl_901399; set optimizer_switch= @os_091399; DROP TABLE t1,t2; +# +# BUG#912510: Crash in do_copy_not_null with semijoin=ON, firstmatch=ON, aggregate ... +# +CREATE TABLE t1 ( a VARCHAR(1) NOT NULL ); +INSERT INTO t1 VALUES ('k'),('l'); +CREATE TABLE t2 ( b VARCHAR(1) NOT NULL, KEY(b) ); +INSERT INTO t2 VALUES ('k'),('l'); +CREATE TABLE t3 ( c VARCHAR(1) NOT NULL, KEY(c) ); +INSERT INTO t3 VALUES ('m'),('n'); +SELECT a, COUNT(*) FROM t1 +WHERE a IN ( +SELECT b FROM t2 force index(b), t3 force index(c) +WHERE c = b AND b = a +); +a COUNT(*) +NULL 0 +DROP TABLE t1, t2, t3; set optimizer_switch=@subselect_sj_tmp; # # BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off diff --git a/mysql-test/t/subselect_sj.test b/mysql-test/t/subselect_sj.test index aee61e9bca3..f34cf5ba338 100644 --- a/mysql-test/t/subselect_sj.test +++ b/mysql-test/t/subselect_sj.test @@ -1997,6 +1997,25 @@ set optimizer_switch= @os_091399; DROP TABLE t1,t2; +--echo # +--echo # BUG#912510: Crash in do_copy_not_null with semijoin=ON, firstmatch=ON, aggregate ... +--echo # +CREATE TABLE t1 ( a VARCHAR(1) NOT NULL ); +INSERT INTO t1 VALUES ('k'),('l'); + +CREATE TABLE t2 ( b VARCHAR(1) NOT NULL, KEY(b) ); +INSERT INTO t2 VALUES ('k'),('l'); + +CREATE TABLE t3 ( c VARCHAR(1) NOT NULL, KEY(c) ); +INSERT INTO t3 VALUES ('m'),('n'); + +SELECT a, COUNT(*) FROM t1 + WHERE a IN ( + SELECT b FROM t2 force index(b), t3 force index(c) + WHERE c = b AND b = a + ); + +DROP TABLE t1, t2, t3; # The following command must be the last one the file set optimizer_switch=@subselect_sj_tmp; diff --git a/sql/field_conv.cc b/sql/field_conv.cc index ce914f7b368..ed910c4ef70 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -248,6 +248,25 @@ static void do_outer_field_null(Copy_field *copy) } } +/* + Copy: (not-NULL field in table that can be NULL-complemented) -> (not-NULL + field) +*/ +static void do_copy_nullable_row_to_notnull(Copy_field *copy) +{ + if (*copy->null_row || + (copy->from_null_ptr && (*copy->from_null_ptr & copy->from_bit))) + { + copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, + WARN_DATA_TRUNCATED, 1); + copy->to_field->reset(); + } + else + { + (copy->do_copy2)(copy); + } + +} /* Copy: (NULL-able field) -> (not NULL-able field) */ static void do_copy_not_null(Copy_field *copy) @@ -638,7 +657,15 @@ void Copy_field::set(Field *to,Field *from,bool save) else if (to_field == to_field->table->next_number_field) do_copy= do_copy_next_number; else - do_copy= do_copy_not_null; + { + if (!from_null_ptr) + { + null_row= &from->table->null_row; + do_copy= do_copy_nullable_row_to_notnull; + } + else + do_copy= do_copy_not_null; + } } } else if (to_field->real_maybe_null()) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index cb620495897..c332b13dff6 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -646,6 +646,9 @@ JOIN::prepare(Item ***rref_pointer_array, aggregate functions and non-aggregate fields, any non-aggregated field may produce a NULL value. Set all fields of each table as nullable before semantic analysis to take into account this change of nullability. + + Note: this loop doesn't touch tables inside merged semi-joins, because + subquery-to-semijoin conversion has not been done yet. This is intended. */ if (mixed_implicit_grouping) tbl->table->maybe_null= 1; From cf86abffbfe5fb95dc79260e6a21332d1adadd2a Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Sun, 8 Jan 2012 21:14:07 +0100 Subject: [PATCH 036/135] MDEV-77 - possible deadlock in XtraDB async io subsystem on Windows. Split IO threads into ones that handle only read completion and ones that handle only write completion, as it was originally done, but got lost with "completion port" patch. The reason we need to have dedicated read and dedicated write threads is that read completion routine can block waiting for write io to complete, and in rare cases where all io threads are handling async reads, it can deadlock. --- storage/xtradb/os/os0file.c | 56 +++++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 11 deletions(-) diff --git a/storage/xtradb/os/os0file.c b/storage/xtradb/os/os0file.c index ef20869c4c5..810a254f9fc 100644 --- a/storage/xtradb/os/os0file.c +++ b/storage/xtradb/os/os0file.c @@ -249,6 +249,8 @@ UNIV_INTERN ulint os_n_pending_reads = 0; #ifdef _WIN32 /** IO completion port used by background io threads */ static HANDLE completion_port; +/** IO completion port used by background io READ threads */ +static HANDLE read_completion_port; /** Thread local storage index for the per-thread event used for synchronous IO */ static DWORD tls_sync_io = TLS_OUT_OF_INDEXES; #endif @@ -3251,9 +3253,10 @@ os_aio_init( os_last_printout = time(NULL); #ifdef _WIN32 - ut_a(completion_port == 0); + ut_a(completion_port == 0 && read_completion_port == 0); completion_port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0); - ut_a(completion_port); + read_completion_port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0); + ut_a(completion_port && read_completion_port); #endif } @@ -3299,6 +3302,7 @@ os_aio_array_wake_win_aio_at_shutdown( if(completion_port) { PostQueuedCompletionStatus(completion_port, 0, IOCP_SHUTDOWN_KEY, NULL); + PostQueuedCompletionStatus(read_completion_port, 0, IOCP_SHUTDOWN_KEY, NULL); } } #endif @@ -3860,6 +3864,9 @@ try_again: } #ifdef WIN_ASYNC_IO +#define READ_SEGMENT(x) (x < srv_n_read_io_threads) +#define WRITE_SEGMENT(x) !READ_SEGMENT(x) + /**********************************************************************//** This function is only used in Windows asynchronous i/o. Waits for an aio operation to complete. This function is used to wait the @@ -3898,18 +3905,45 @@ os_aio_windows_handle( DWORD len; BOOL retry = FALSE; ULONG_PTR key; + HANDLE port = READ_SEGMENT(segment)? read_completion_port : completion_port; - ret = GetQueuedCompletionStatus(completion_port, &len, &key, - (OVERLAPPED **)&slot, INFINITE); + for(;;) { + ret = GetQueuedCompletionStatus(port, &len, &key, + (OVERLAPPED **)&slot, INFINITE); - /* If shutdown key was received, repost the shutdown message and exit */ - if (ret && (key == IOCP_SHUTDOWN_KEY)) { - PostQueuedCompletionStatus(completion_port, 0, key, NULL); - os_thread_exit(NULL); - } + /* If shutdown key was received, repost the shutdown message and exit */ + if (ret && (key == IOCP_SHUTDOWN_KEY)) { + PostQueuedCompletionStatus(port, 0, key, NULL); + os_thread_exit(NULL); + } - if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) { - os_thread_exit(NULL); + if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) { + os_thread_exit(NULL); + } + + if(WRITE_SEGMENT(segment)&& slot->type == OS_FILE_READ) { + /* + Redirect read completions to the dedicated completion port + and thread. We need to split read and write threads. If we do not + do that, and just allow all io threads process all IO, it is possible + to get stuck in a deadlock in buffer pool code, + + Currently, the problem is solved this way - "write io" threads + always get all completion notifications, from both async reads and + writes. Write completion is handled in the same thread that gets it. + Read completion is forwarded via PostQueueCompletionStatus()) + to the second completion port dedicated solely to reads. One of the + "read io" threads waiting on this port will finally handle the IO. + + Forwarding IO completion this way costs a context switch , and this + seems tolerable since asynchronous reads are by far less frequent. + */ + ut_a(PostQueuedCompletionStatus(read_completion_port, len, key, + &slot->control)); + } + else { + break; + } } From a148cf7fb092578d85f0dd2936e933b2acbb88e5 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Mon, 9 Jan 2012 13:49:47 +0200 Subject: [PATCH 037/135] Fixed that --sorted-result in mysql-test-run also works for exec mysql-test/r/information_schema_all_engines.result: Update result mysql-test/t/information_schema_all_engines.test: Added --sorted-results as tables in information_schema are not sorted. --- client/mysqltest.cc | 50 +++-- .../r/information_schema_all_engines.result | 200 +++++++++--------- .../t/information_schema_all_engines.test | 8 +- 3 files changed, 140 insertions(+), 118 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 6d54fa8ad7b..77fbbb1757e 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. - Copyright (c) 2009-2011 Monty Program Ab. + Copyright (c) 2009-2012 Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -732,7 +732,8 @@ void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val, int len); void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val); void replace_dynstr_append_uint(DYNAMIC_STRING *ds, uint val); -void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING* ds_input); +void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING* ds_input, + bool keep_header); static int match_expected_error(struct st_command *command, unsigned int err_errno, @@ -2790,6 +2791,7 @@ void do_exec(struct st_command *command) FILE *res_file; char *cmd= command->first_argument; DYNAMIC_STRING ds_cmd; + DYNAMIC_STRING ds_sorted, *ds_result; DBUG_ENTER("do_exec"); DBUG_PRINT("enter", ("cmd: '%s'", cmd)); @@ -2835,6 +2837,13 @@ void do_exec(struct st_command *command) die("popen(\"%s\", \"r\") failed", command->first_argument); } + ds_result= &ds_res; + if (display_result_sorted) + { + init_dynamic_string(&ds_sorted, "", 1024, 1024); + ds_result= &ds_sorted; + } + while (fgets(buf, sizeof(buf), res_file)) { if (disable_result_log) @@ -2844,10 +2853,17 @@ void do_exec(struct st_command *command) } else { - replace_dynstr_append(&ds_res, buf); + replace_dynstr_append(ds_result, buf); } } error= pclose(res_file); + + if (display_result_sorted) + { + dynstr_append_sorted(&ds_res, &ds_sorted, 0); + dynstr_free(&ds_sorted); + } + if (error > 0) { uint status= WEXITSTATUS(error); @@ -7743,7 +7759,7 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) if (display_result_sorted) { /* Sort the result set and append it to result */ - dynstr_append_sorted(save_ds, &ds_sorted); + dynstr_append_sorted(save_ds, &ds_sorted, 1); ds= save_ds; dynstr_free(&ds_sorted); } @@ -10125,17 +10141,16 @@ void replace_dynstr_append_uint(DYNAMIC_STRING *ds, uint val) } - /* Build a list of pointer to each line in ds_input, sort the list and use the sorted list to append the strings sorted to the output ds SYNOPSIS - dynstr_append_sorted - ds - string where the sorted output will be appended - ds_input - string to be sorted - + dynstr_append_sorted() + ds string where the sorted output will be appended + ds_input string to be sorted + keep_header If header should not be sorted */ static int comp_lines(const char **a, const char **b) @@ -10143,7 +10158,8 @@ static int comp_lines(const char **a, const char **b) return (strcmp(*a,*b)); } -void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING *ds_input) +void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING *ds_input, + bool keep_header) { unsigned i; char *start= ds_input->str; @@ -10155,11 +10171,14 @@ void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING *ds_input) my_init_dynamic_array(&lines, sizeof(const char*), 32, 32); - /* First line is result header, skip past it */ - while (*start && *start != '\n') - start++; - start++; /* Skip past \n */ - dynstr_append_mem(ds, ds_input->str, start - ds_input->str); + if (keep_header) + { + /* First line is result header, skip past it */ + while (*start && *start != '\n') + start++; + start++; /* Skip past \n */ + dynstr_append_mem(ds, ds_input->str, start - ds_input->str); + } /* Insert line(s) in array */ while (*start) @@ -10237,4 +10256,3 @@ char *mysql_authentication_dialog_ask(MYSQL *mysql, int type, return buf; } - diff --git a/mysql-test/r/information_schema_all_engines.result b/mysql-test/r/information_schema_all_engines.result index 7a2c548a329..c2bcbeb2315 100644 --- a/mysql-test/r/information_schema_all_engines.result +++ b/mysql-test/r/information_schema_all_engines.result @@ -13,9 +13,26 @@ FILES GLOBAL_STATUS GLOBAL_VARIABLES INDEX_STATISTICS +INNODB_BUFFER_POOL_PAGES +INNODB_BUFFER_POOL_PAGES_BLOB +INNODB_BUFFER_POOL_PAGES_INDEX +INNODB_CMP +INNODB_CMPMEM +INNODB_CMPMEM_RESET +INNODB_CMP_RESET +INNODB_INDEX_STATS +INNODB_LOCKS +INNODB_LOCK_WAITS +INNODB_RSEG +INNODB_SYS_INDEXES +INNODB_SYS_STATS +INNODB_SYS_TABLES +INNODB_TABLE_STATS +INNODB_TRX KEY_CACHES KEY_COLUMN_USAGE PARTITIONS +PBXT_STATISTICS PLUGINS PROCESSLIST PROFILING @@ -34,25 +51,8 @@ TRIGGERS USER_PRIVILEGES USER_STATISTICS VIEWS -INNODB_BUFFER_POOL_PAGES -PBXT_STATISTICS -INNODB_CMP -INNODB_RSEG -XTRADB_ENHANCEMENTS -INNODB_BUFFER_POOL_PAGES_INDEX XTRADB_ADMIN_COMMAND -INNODB_TRX -INNODB_SYS_TABLES -INNODB_LOCK_WAITS -INNODB_SYS_STATS -INNODB_LOCKS -INNODB_CMPMEM -INNODB_TABLE_STATS -INNODB_SYS_INDEXES -INNODB_CMP_RESET -INNODB_BUFFER_POOL_PAGES_BLOB -INNODB_CMPMEM_RESET -INNODB_INDEX_STATS +XTRADB_ENHANCEMENTS SELECT t.table_name, c1.column_name FROM information_schema.tables t INNER JOIN @@ -66,7 +66,7 @@ FROM information_schema.columns c2 WHERE c2.table_schema = t.table_schema AND c2.table_name = t.table_name AND c2.column_name LIKE '%SCHEMA%' - ); + ) order by t.table_name; table_name column_name CHARACTER_SETS CHARACTER_SET_NAME CLIENT_STATISTICS CLIENT @@ -80,9 +80,26 @@ FILES TABLE_SCHEMA GLOBAL_STATUS VARIABLE_NAME GLOBAL_VARIABLES VARIABLE_NAME INDEX_STATISTICS TABLE_SCHEMA +INNODB_BUFFER_POOL_PAGES page_type +INNODB_BUFFER_POOL_PAGES_BLOB space_id +INNODB_BUFFER_POOL_PAGES_INDEX index_id +INNODB_CMP page_size +INNODB_CMPMEM page_size +INNODB_CMPMEM_RESET page_size +INNODB_CMP_RESET page_size +INNODB_INDEX_STATS table_schema +INNODB_LOCKS lock_id +INNODB_LOCK_WAITS requesting_trx_id +INNODB_RSEG rseg_id +INNODB_SYS_INDEXES TABLE_ID +INNODB_SYS_STATS INDEX_ID +INNODB_SYS_TABLES SCHEMA +INNODB_TABLE_STATS table_schema +INNODB_TRX trx_id KEY_CACHES KEY_CACHE_NAME KEY_COLUMN_USAGE CONSTRAINT_SCHEMA PARTITIONS TABLE_SCHEMA +PBXT_STATISTICS ID PLUGINS PLUGIN_NAME PROCESSLIST ID PROFILING QUERY_ID @@ -101,25 +118,8 @@ TRIGGERS TRIGGER_SCHEMA USER_PRIVILEGES GRANTEE USER_STATISTICS USER VIEWS TABLE_SCHEMA -INNODB_BUFFER_POOL_PAGES page_type -PBXT_STATISTICS ID -INNODB_CMP page_size -INNODB_RSEG rseg_id -XTRADB_ENHANCEMENTS name -INNODB_BUFFER_POOL_PAGES_INDEX index_id XTRADB_ADMIN_COMMAND result_message -INNODB_TRX trx_id -INNODB_SYS_TABLES SCHEMA -INNODB_LOCK_WAITS requesting_trx_id -INNODB_SYS_STATS INDEX_ID -INNODB_LOCKS lock_id -INNODB_CMPMEM page_size -INNODB_TABLE_STATS table_schema -INNODB_SYS_INDEXES TABLE_ID -INNODB_CMP_RESET page_size -INNODB_BUFFER_POOL_PAGES_BLOB space_id -INNODB_CMPMEM_RESET page_size -INNODB_INDEX_STATS table_schema +XTRADB_ENHANCEMENTS name SELECT t.table_name, c1.column_name FROM information_schema.tables t INNER JOIN @@ -133,7 +133,7 @@ FROM information_schema.columns c2 WHERE c2.table_schema = 'information_schema' AND c2.table_name = t.table_name AND c2.column_name LIKE '%SCHEMA%' - ); + ) order by t.table_name; table_name column_name CHARACTER_SETS CHARACTER_SET_NAME CLIENT_STATISTICS CLIENT @@ -147,9 +147,26 @@ FILES TABLE_SCHEMA GLOBAL_STATUS VARIABLE_NAME GLOBAL_VARIABLES VARIABLE_NAME INDEX_STATISTICS TABLE_SCHEMA +INNODB_BUFFER_POOL_PAGES page_type +INNODB_BUFFER_POOL_PAGES_BLOB space_id +INNODB_BUFFER_POOL_PAGES_INDEX index_id +INNODB_CMP page_size +INNODB_CMPMEM page_size +INNODB_CMPMEM_RESET page_size +INNODB_CMP_RESET page_size +INNODB_INDEX_STATS table_schema +INNODB_LOCKS lock_id +INNODB_LOCK_WAITS requesting_trx_id +INNODB_RSEG rseg_id +INNODB_SYS_INDEXES TABLE_ID +INNODB_SYS_STATS INDEX_ID +INNODB_SYS_TABLES SCHEMA +INNODB_TABLE_STATS table_schema +INNODB_TRX trx_id KEY_CACHES KEY_CACHE_NAME KEY_COLUMN_USAGE CONSTRAINT_SCHEMA PARTITIONS TABLE_SCHEMA +PBXT_STATISTICS ID PLUGINS PLUGIN_NAME PROCESSLIST ID PROFILING QUERY_ID @@ -168,25 +185,8 @@ TRIGGERS TRIGGER_SCHEMA USER_PRIVILEGES GRANTEE USER_STATISTICS USER VIEWS TABLE_SCHEMA -INNODB_BUFFER_POOL_PAGES page_type -PBXT_STATISTICS ID -INNODB_CMP page_size -INNODB_RSEG rseg_id -XTRADB_ENHANCEMENTS name -INNODB_BUFFER_POOL_PAGES_INDEX index_id XTRADB_ADMIN_COMMAND result_message -INNODB_TRX trx_id -INNODB_SYS_TABLES SCHEMA -INNODB_LOCK_WAITS requesting_trx_id -INNODB_SYS_STATS INDEX_ID -INNODB_LOCKS lock_id -INNODB_CMPMEM page_size -INNODB_TABLE_STATS table_schema -INNODB_SYS_INDEXES TABLE_ID -INNODB_CMP_RESET page_size -INNODB_BUFFER_POOL_PAGES_BLOB space_id -INNODB_CMPMEM_RESET page_size -INNODB_INDEX_STATS table_schema +XTRADB_ENHANCEMENTS name select 1 as f1 from information_schema.tables where "CHARACTER_SETS"= (select cast(table_name as char) from information_schema.tables order by table_name limit 1) limit 1; @@ -259,10 +259,11 @@ USER_PRIVILEGES information_schema.USER_PRIVILEGES 1 USER_STATISTICS information_schema.USER_STATISTICS 1 VIEWS information_schema.VIEWS 1 XTRADB_ENHANCEMENTS information_schema.XTRADB_ENHANCEMENTS 1 ++---------------------------------------+ ++---------------------------------------+ ++---------------------------------------+ Database: information_schema -+---------------------------------------+ | Tables | -+---------------------------------------+ | CHARACTER_SETS | | CLIENT_STATISTICS | | COLLATIONS | @@ -275,9 +276,26 @@ Database: information_schema | GLOBAL_STATUS | | GLOBAL_VARIABLES | | INDEX_STATISTICS | +| INNODB_BUFFER_POOL_PAGES | +| INNODB_BUFFER_POOL_PAGES_BLOB | +| INNODB_BUFFER_POOL_PAGES_INDEX | +| INNODB_CMP | +| INNODB_CMPMEM | +| INNODB_CMPMEM_RESET | +| INNODB_CMP_RESET | +| INNODB_INDEX_STATS | +| INNODB_LOCKS | +| INNODB_LOCK_WAITS | +| INNODB_RSEG | +| INNODB_SYS_INDEXES | +| INNODB_SYS_STATS | +| INNODB_SYS_TABLES | +| INNODB_TABLE_STATS | +| INNODB_TRX | | KEY_CACHES | | KEY_COLUMN_USAGE | | PARTITIONS | +| PBXT_STATISTICS | | PLUGINS | | PROCESSLIST | | PROFILING | @@ -296,30 +314,13 @@ Database: information_schema | USER_PRIVILEGES | | USER_STATISTICS | | VIEWS | -| INNODB_BUFFER_POOL_PAGES | -| PBXT_STATISTICS | -| INNODB_CMP | -| INNODB_RSEG | -| XTRADB_ENHANCEMENTS | -| INNODB_BUFFER_POOL_PAGES_INDEX | | XTRADB_ADMIN_COMMAND | -| INNODB_TRX | -| INNODB_SYS_TABLES | -| INNODB_LOCK_WAITS | -| INNODB_SYS_STATS | -| INNODB_LOCKS | -| INNODB_CMPMEM | -| INNODB_TABLE_STATS | -| INNODB_SYS_INDEXES | -| INNODB_CMP_RESET | -| INNODB_BUFFER_POOL_PAGES_BLOB | -| INNODB_CMPMEM_RESET | -| INNODB_INDEX_STATS | +| XTRADB_ENHANCEMENTS | ++---------------------------------------+ ++---------------------------------------+ +---------------------------------------+ Database: INFORMATION_SCHEMA -+---------------------------------------+ | Tables | -+---------------------------------------+ | CHARACTER_SETS | | CLIENT_STATISTICS | | COLLATIONS | @@ -332,9 +333,26 @@ Database: INFORMATION_SCHEMA | GLOBAL_STATUS | | GLOBAL_VARIABLES | | INDEX_STATISTICS | +| INNODB_BUFFER_POOL_PAGES | +| INNODB_BUFFER_POOL_PAGES_BLOB | +| INNODB_BUFFER_POOL_PAGES_INDEX | +| INNODB_CMP | +| INNODB_CMPMEM | +| INNODB_CMPMEM_RESET | +| INNODB_CMP_RESET | +| INNODB_INDEX_STATS | +| INNODB_LOCKS | +| INNODB_LOCK_WAITS | +| INNODB_RSEG | +| INNODB_SYS_INDEXES | +| INNODB_SYS_STATS | +| INNODB_SYS_TABLES | +| INNODB_TABLE_STATS | +| INNODB_TRX | | KEY_CACHES | | KEY_COLUMN_USAGE | | PARTITIONS | +| PBXT_STATISTICS | | PLUGINS | | PROCESSLIST | | PROFILING | @@ -353,32 +371,14 @@ Database: INFORMATION_SCHEMA | USER_PRIVILEGES | | USER_STATISTICS | | VIEWS | -| INNODB_BUFFER_POOL_PAGES | -| PBXT_STATISTICS | -| INNODB_CMP | -| INNODB_RSEG | -| XTRADB_ENHANCEMENTS | -| INNODB_BUFFER_POOL_PAGES_INDEX | | XTRADB_ADMIN_COMMAND | -| INNODB_TRX | -| INNODB_SYS_TABLES | -| INNODB_LOCK_WAITS | -| INNODB_SYS_STATS | -| INNODB_LOCKS | -| INNODB_CMPMEM | -| INNODB_TABLE_STATS | -| INNODB_SYS_INDEXES | -| INNODB_CMP_RESET | -| INNODB_BUFFER_POOL_PAGES_BLOB | -| INNODB_CMPMEM_RESET | -| INNODB_INDEX_STATS | -+---------------------------------------+ +| XTRADB_ENHANCEMENTS | ++--------------------+ ++--------------------+ ++--------------------+ Wildcard: inf_rmation_schema -+--------------------+ | Databases | -+--------------------+ | information_schema | -+--------------------+ SELECT table_schema, count(*) FROM information_schema.TABLES WHERE table_schema IN ('mysql', 'INFORMATION_SCHEMA', 'test', 'mysqltest') AND table_name<>'ndb_binlog_index' AND table_name<>'ndb_apply_status' GROUP BY TABLE_SCHEMA; table_schema count(*) information_schema 52 diff --git a/mysql-test/t/information_schema_all_engines.test b/mysql-test/t/information_schema_all_engines.test index b20ce60985c..9887845cb7e 100644 --- a/mysql-test/t/information_schema_all_engines.test +++ b/mysql-test/t/information_schema_all_engines.test @@ -9,6 +9,7 @@ use INFORMATION_SCHEMA; --replace_result Tables_in_INFORMATION_SCHEMA Tables_in_information_schema +--sorted_result show tables; # @@ -28,7 +29,7 @@ SELECT t.table_name, c1.column_name WHERE c2.table_schema = t.table_schema AND c2.table_name = t.table_name AND c2.column_name LIKE '%SCHEMA%' - ); + ) order by t.table_name; SELECT t.table_name, c1.column_name FROM information_schema.tables t INNER JOIN @@ -42,7 +43,7 @@ SELECT t.table_name, c1.column_name WHERE c2.table_schema = 'information_schema' AND c2.table_name = t.table_name AND c2.column_name LIKE '%SCHEMA%' - ); + ) order by t.table_name; # # Bug#24630 Subselect query crashes mysqld @@ -70,8 +71,11 @@ group by t.table_name order by num1, t.table_name; # # Bug #19147: mysqlshow INFORMATION_SCHEMA does not work # +--sorted_result --exec $MYSQL_SHOW information_schema +--sorted_result --exec $MYSQL_SHOW INFORMATION_SCHEMA +--sorted_result --exec $MYSQL_SHOW inf_rmation_schema # From cf31ccc33c2f5ac5e2ae92c672bd54cc7ce63107 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 10 Jan 2012 23:26:00 +0200 Subject: [PATCH 038/135] Fix for LP BUG#908269 Wrong result with subquery in select list, EXISTS, constant MyISAM/Aria table. Problem: When building the condition for JOIN::outer_ref_cond the optimizer forgot to take into account that this condition could depend on constant tables as well. --- mysql-test/r/subselect.result | 24 ++++++++++++ mysql-test/r/subselect_no_mat.result | 24 ++++++++++++ mysql-test/r/subselect_no_opts.result | 24 ++++++++++++ mysql-test/r/subselect_no_scache.result | 24 ++++++++++++ mysql-test/r/subselect_no_semijoin.result | 24 ++++++++++++ mysql-test/t/subselect.test | 28 ++++++++++++++ sql/sql_select.cc | 46 ++++++++++++++++------- sql/sql_select.h | 3 +- 8 files changed, 183 insertions(+), 14 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 95fc6e03e56..7dfcad074fe 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -5908,5 +5908,29 @@ a 2009-02-02 set @@optimizer_switch=@old_optimizer_switch; drop table t1; +# +# LP BUG#908269 incorrect condition in case of subqueries depending +# on constant tables +# +CREATE TABLE t1 ( a INT ); +INSERT INTO t1 VALUES (1),(5); +CREATE TABLE t2 ( b INT ) ENGINE=MyISAM; +INSERT INTO t2 VALUES (1); +CREATE TABLE t3 ( c INT ); +INSERT INTO t3 VALUES (4),(5); +SET optimizer_switch='subquery_cache=off'; +SELECT ( SELECT b FROM t2 WHERE b = a OR EXISTS ( SELECT c FROM t3 WHERE c = b ) ) FROM t1; +( SELECT b FROM t2 WHERE b = a OR EXISTS ( SELECT c FROM t3 WHERE c = b ) ) +1 +NULL +SELECT ( SELECT b FROM t2 WHERE b = a OR b * 0) FROM t1; +( SELECT b FROM t2 WHERE b = a OR b * 0) +1 +NULL +SELECT ( SELECT b FROM t2 WHERE b = a OR rand() * 0) FROM t1; +( SELECT b FROM t2 WHERE b = a OR rand() * 0) +1 +NULL +drop table t1,t2,t3; # return optimizer switch changed in the beginning of this test set optimizer_switch=@subselect_tmp; diff --git a/mysql-test/r/subselect_no_mat.result b/mysql-test/r/subselect_no_mat.result index 8959853f16f..c7d9fd96e5d 100644 --- a/mysql-test/r/subselect_no_mat.result +++ b/mysql-test/r/subselect_no_mat.result @@ -5909,6 +5909,30 @@ a 2009-02-02 set @@optimizer_switch=@old_optimizer_switch; drop table t1; +# +# LP BUG#908269 incorrect condition in case of subqueries depending +# on constant tables +# +CREATE TABLE t1 ( a INT ); +INSERT INTO t1 VALUES (1),(5); +CREATE TABLE t2 ( b INT ) ENGINE=MyISAM; +INSERT INTO t2 VALUES (1); +CREATE TABLE t3 ( c INT ); +INSERT INTO t3 VALUES (4),(5); +SET optimizer_switch='subquery_cache=off'; +SELECT ( SELECT b FROM t2 WHERE b = a OR EXISTS ( SELECT c FROM t3 WHERE c = b ) ) FROM t1; +( SELECT b FROM t2 WHERE b = a OR EXISTS ( SELECT c FROM t3 WHERE c = b ) ) +1 +NULL +SELECT ( SELECT b FROM t2 WHERE b = a OR b * 0) FROM t1; +( SELECT b FROM t2 WHERE b = a OR b * 0) +1 +NULL +SELECT ( SELECT b FROM t2 WHERE b = a OR rand() * 0) FROM t1; +( SELECT b FROM t2 WHERE b = a OR rand() * 0) +1 +NULL +drop table t1,t2,t3; # return optimizer switch changed in the beginning of this test set optimizer_switch=@subselect_tmp; set optimizer_switch=default; diff --git a/mysql-test/r/subselect_no_opts.result b/mysql-test/r/subselect_no_opts.result index 1a937bbcd5f..3d6efa28e19 100644 --- a/mysql-test/r/subselect_no_opts.result +++ b/mysql-test/r/subselect_no_opts.result @@ -5905,6 +5905,30 @@ a 2009-02-02 set @@optimizer_switch=@old_optimizer_switch; drop table t1; +# +# LP BUG#908269 incorrect condition in case of subqueries depending +# on constant tables +# +CREATE TABLE t1 ( a INT ); +INSERT INTO t1 VALUES (1),(5); +CREATE TABLE t2 ( b INT ) ENGINE=MyISAM; +INSERT INTO t2 VALUES (1); +CREATE TABLE t3 ( c INT ); +INSERT INTO t3 VALUES (4),(5); +SET optimizer_switch='subquery_cache=off'; +SELECT ( SELECT b FROM t2 WHERE b = a OR EXISTS ( SELECT c FROM t3 WHERE c = b ) ) FROM t1; +( SELECT b FROM t2 WHERE b = a OR EXISTS ( SELECT c FROM t3 WHERE c = b ) ) +1 +NULL +SELECT ( SELECT b FROM t2 WHERE b = a OR b * 0) FROM t1; +( SELECT b FROM t2 WHERE b = a OR b * 0) +1 +NULL +SELECT ( SELECT b FROM t2 WHERE b = a OR rand() * 0) FROM t1; +( SELECT b FROM t2 WHERE b = a OR rand() * 0) +1 +NULL +drop table t1,t2,t3; # return optimizer switch changed in the beginning of this test set optimizer_switch=@subselect_tmp; set @optimizer_switch_for_subselect_test=null; diff --git a/mysql-test/r/subselect_no_scache.result b/mysql-test/r/subselect_no_scache.result index 56e06b948a1..602905dd5b8 100644 --- a/mysql-test/r/subselect_no_scache.result +++ b/mysql-test/r/subselect_no_scache.result @@ -5914,6 +5914,30 @@ a 2009-02-02 set @@optimizer_switch=@old_optimizer_switch; drop table t1; +# +# LP BUG#908269 incorrect condition in case of subqueries depending +# on constant tables +# +CREATE TABLE t1 ( a INT ); +INSERT INTO t1 VALUES (1),(5); +CREATE TABLE t2 ( b INT ) ENGINE=MyISAM; +INSERT INTO t2 VALUES (1); +CREATE TABLE t3 ( c INT ); +INSERT INTO t3 VALUES (4),(5); +SET optimizer_switch='subquery_cache=off'; +SELECT ( SELECT b FROM t2 WHERE b = a OR EXISTS ( SELECT c FROM t3 WHERE c = b ) ) FROM t1; +( SELECT b FROM t2 WHERE b = a OR EXISTS ( SELECT c FROM t3 WHERE c = b ) ) +1 +NULL +SELECT ( SELECT b FROM t2 WHERE b = a OR b * 0) FROM t1; +( SELECT b FROM t2 WHERE b = a OR b * 0) +1 +NULL +SELECT ( SELECT b FROM t2 WHERE b = a OR rand() * 0) FROM t1; +( SELECT b FROM t2 WHERE b = a OR rand() * 0) +1 +NULL +drop table t1,t2,t3; # return optimizer switch changed in the beginning of this test set optimizer_switch=@subselect_tmp; set optimizer_switch=default; diff --git a/mysql-test/r/subselect_no_semijoin.result b/mysql-test/r/subselect_no_semijoin.result index b92230cff3b..9b2370efd61 100644 --- a/mysql-test/r/subselect_no_semijoin.result +++ b/mysql-test/r/subselect_no_semijoin.result @@ -5905,6 +5905,30 @@ a 2009-02-02 set @@optimizer_switch=@old_optimizer_switch; drop table t1; +# +# LP BUG#908269 incorrect condition in case of subqueries depending +# on constant tables +# +CREATE TABLE t1 ( a INT ); +INSERT INTO t1 VALUES (1),(5); +CREATE TABLE t2 ( b INT ) ENGINE=MyISAM; +INSERT INTO t2 VALUES (1); +CREATE TABLE t3 ( c INT ); +INSERT INTO t3 VALUES (4),(5); +SET optimizer_switch='subquery_cache=off'; +SELECT ( SELECT b FROM t2 WHERE b = a OR EXISTS ( SELECT c FROM t3 WHERE c = b ) ) FROM t1; +( SELECT b FROM t2 WHERE b = a OR EXISTS ( SELECT c FROM t3 WHERE c = b ) ) +1 +NULL +SELECT ( SELECT b FROM t2 WHERE b = a OR b * 0) FROM t1; +( SELECT b FROM t2 WHERE b = a OR b * 0) +1 +NULL +SELECT ( SELECT b FROM t2 WHERE b = a OR rand() * 0) FROM t1; +( SELECT b FROM t2 WHERE b = a OR rand() * 0) +1 +NULL +drop table t1,t2,t3; # return optimizer switch changed in the beginning of this test set optimizer_switch=@subselect_tmp; set @optimizer_switch_for_subselect_test=null; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 9d87cbc486c..b92fb6f961c 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -4990,5 +4990,33 @@ SELECT * FROM t1 WHERE a IN (SELECT a AS field1 FROM t1 GROUP BY field1); set @@optimizer_switch=@old_optimizer_switch; drop table t1; +--echo # +--echo # LP BUG#908269 incorrect condition in case of subqueries depending +--echo # on constant tables +--echo # +CREATE TABLE t1 ( a INT ); +INSERT INTO t1 VALUES (1),(5); + +# t2 must be MyISAM or Aria and contain 1 row +CREATE TABLE t2 ( b INT ) ENGINE=MyISAM; +INSERT INTO t2 VALUES (1); + +CREATE TABLE t3 ( c INT ); +INSERT INTO t3 VALUES (4),(5); + +SET optimizer_switch='subquery_cache=off'; + +SELECT ( SELECT b FROM t2 WHERE b = a OR EXISTS ( SELECT c FROM t3 WHERE c = b ) ) FROM t1; + +# This query just for example, it should return the same as above (1 and NULL) +SELECT ( SELECT b FROM t2 WHERE b = a OR b * 0) FROM t1; + +# example with "random" +SELECT ( SELECT b FROM t2 WHERE b = a OR rand() * 0) FROM t1; + + +drop table t1,t2,t3; + + --echo # return optimizer switch changed in the beginning of this test set optimizer_switch=@subselect_tmp; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index c332b13dff6..c4a62ce6bc4 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -8033,14 +8033,33 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) DBUG_RETURN(1); // Impossible const condition } - COND *outer_ref_cond= make_cond_for_table(thd, cond, - OUTER_REF_TABLE_BIT, - OUTER_REF_TABLE_BIT, - -1, FALSE, FALSE); - if (outer_ref_cond) - { - add_cond_and_fix(thd, &outer_ref_cond, join->outer_ref_cond); - join->outer_ref_cond= outer_ref_cond; + if (join->table_count != join->const_tables) + { + COND *outer_ref_cond= make_cond_for_table(thd, cond, + join->const_table_map | + OUTER_REF_TABLE_BIT, + OUTER_REF_TABLE_BIT, + -1, FALSE, FALSE); + if (outer_ref_cond) + { + add_cond_and_fix(thd, &outer_ref_cond, join->outer_ref_cond); + join->outer_ref_cond= outer_ref_cond; + } + } + else + { + COND *pseudo_bits_cond= + make_cond_for_table(thd, cond, + join->const_table_map | + PSEUDO_TABLE_BITS, + PSEUDO_TABLE_BITS, + -1, FALSE, FALSE); + if (pseudo_bits_cond) + { + add_cond_and_fix(thd, &pseudo_bits_cond, + join->pseudo_bits_cond); + join->pseudo_bits_cond= pseudo_bits_cond; + } } } } @@ -14927,14 +14946,15 @@ do_select(JOIN *join,List *fields,TABLE *table,Procedure *procedure) /* HAVING will be checked after processing aggregate functions, But WHERE should checked here (we alredy have read tables). - Notice that make_join_select() splits all conditions into three groups - - exec_const_cond, outer_ref_cond, and conditions attached to non-constant - tables. Within this IF the latter do not exist. At the same time + Notice that make_join_select() splits all conditions in this case + into two groups exec_const_cond and outer_ref_cond. + Within this other conditions are not exists. At the same time exec_const_cond is already checked either by make_join_select or in the beginning of JOIN::exec. Therefore here it is sufficient to check only - outer_ref_cond. + pseudo_bits_cond. */ - if (!join->outer_ref_cond || join->outer_ref_cond->val_int()) + DBUG_ASSERT(join->outer_ref_cond == NULL); + if (!join->pseudo_bits_cond || join->pseudo_bits_cond->val_int()) { error= (*end_select)(join, 0, 0); if (error == NESTED_LOOP_OK || error == NESTED_LOOP_QUERY_LIMIT) diff --git a/sql/sql_select.h b/sql/sql_select.h index 8b3da18c976..8b448130eaf 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -1111,6 +1111,7 @@ public: COND *conds; // ---"--- Item *conds_history; // store WHERE for explain COND *outer_ref_cond; /// *join_list; ///< list of joined tables in reverse order COND_EQUAL *cond_equal; @@ -1237,7 +1238,7 @@ public: rollup.state= ROLLUP::STATE_NONE; no_const_tables= FALSE; - outer_ref_cond= 0; + outer_ref_cond= pseudo_bits_cond= NULL; in_to_exists_where= NULL; in_to_exists_having= NULL; } From 296b450d3b58ded0fd4d4972161414c6cc7a80e5 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 11 Jan 2012 10:35:16 +0200 Subject: [PATCH 039/135] Fix the comment. --- sql/sql_select.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index c4a62ce6bc4..fe52bc05465 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -14948,10 +14948,8 @@ do_select(JOIN *join,List *fields,TABLE *table,Procedure *procedure) But WHERE should checked here (we alredy have read tables). Notice that make_join_select() splits all conditions in this case into two groups exec_const_cond and outer_ref_cond. - Within this other conditions are not exists. At the same time - exec_const_cond is already checked either by make_join_select or in the - beginning of JOIN::exec. Therefore here it is sufficient to check only - pseudo_bits_cond. + If join->table_count == join->const_tables then it is + sufficient to check only the condition pseudo_bits_cond. */ DBUG_ASSERT(join->outer_ref_cond == NULL); if (!join->pseudo_bits_cond || join->pseudo_bits_cond->val_int()) From dacaaf22a3f132df5573fe8e58c0617c30c5e9fc Mon Sep 17 00:00:00 2001 From: Karen Langford Date: Wed, 11 Jan 2012 18:40:29 +0100 Subject: [PATCH 040/135] Fixes required to build on AIX --- cmd-line-utils/libedit/chartype.h | 6 +++--- cmd-line-utils/libedit/eln.c | 2 +- cmd-line-utils/libedit/readline.c | 2 +- unittest/mysys/bitmap-t.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cmd-line-utils/libedit/chartype.h b/cmd-line-utils/libedit/chartype.h index 678d13683be..40012afb47d 100644 --- a/cmd-line-utils/libedit/chartype.h +++ b/cmd-line-utils/libedit/chartype.h @@ -45,11 +45,11 @@ * seems to actually advertise this properly, despite Unicode 3.1 having * been around since 2001... */ -/* XXXMYSQL : Added FreeBSD to bypass this check. - TODO : Verify if FreeBSD stores ISO 10646 in wchar_t. */ +/* XXXMYSQL : Added FreeBSD & AIX to bypass this check. + TODO : Verify if FreeBSD & AIX stores ISO 10646 in wchar_t. */ #if !defined(__NetBSD__) && !defined(__sun) \ && !(defined(__APPLE__) && defined(__MACH__)) \ - && !defined(__FreeBSD__) + && !defined(__FreeBSD__) && !defined(_AIX) #ifndef __STDC_ISO_10646__ /* In many places it is assumed that the first 127 code points are ASCII * compatible, so ensure wchar_t indeed does ISO 10646 and not some other diff --git a/cmd-line-utils/libedit/eln.c b/cmd-line-utils/libedit/eln.c index 4b9f16c38f3..f996367115a 100644 --- a/cmd-line-utils/libedit/eln.c +++ b/cmd-line-utils/libedit/eln.c @@ -200,7 +200,7 @@ el_set(EditLine *el, int op, ...) ret = -1; goto out; } - // XXX: The two strdup's leak + /* XXX: The two strdups leak. */ ret = map_addfunc(el, Strdup(wargv[0]), Strdup(wargv[1]), func); ct_free_argv(wargv); diff --git a/cmd-line-utils/libedit/readline.c b/cmd-line-utils/libedit/readline.c index eaf26d4c497..a2a92edc1b4 100644 --- a/cmd-line-utils/libedit/readline.c +++ b/cmd-line-utils/libedit/readline.c @@ -1978,7 +1978,7 @@ rl_callback_read_char() } else wbuf = NULL; (*(void (*)(const char *))rl_linefunc)(wbuf); - //el_set(e, EL_UNBUFFERED, 1); + /*el_set(e, EL_UNBUFFERED, 1);*/ } } diff --git a/unittest/mysys/bitmap-t.c b/unittest/mysys/bitmap-t.c index 0127b7b86f4..9a5337c79b5 100644 --- a/unittest/mysys/bitmap-t.c +++ b/unittest/mysys/bitmap-t.c @@ -429,7 +429,7 @@ my_bool test_intersect(MY_BITMAP *map, uint bitsize) { uint bitsize2 = 1 + get_rand_bit(MAX_TESTED_BITMAP_SIZE - 1); MY_BITMAP map2; - uint32 map2buf[bitsize2]; + uint32 map2buf[MAX_TESTED_BITMAP_SIZE]; uint i, test_bit1, test_bit2, test_bit3; if (bitmap_init(&map2, map2buf, bitsize2, FALSE)) { From 3c1125d4cafdf352ea84d2ff8e06738c4aec2156 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 12 Jan 2012 20:12:14 +0100 Subject: [PATCH 041/135] fixes for get_password(): 1. on windows: don't hang when there's no console, that is, _getch() returns -1. 2. on windows: _getch() returns an int, not char. to distinguish between (char)255 and (int)-1 3. everywhere. isspace(pos[-1]) == ' ' never worked, isspace() returns a boolean, not a char. the never-worked loop was removed to preserve the existing behavior. --- libmysql/get_password.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/libmysql/get_password.c b/libmysql/get_password.c index 747d598d72a..21200acf512 100644 --- a/libmysql/get_password.c +++ b/libmysql/get_password.c @@ -82,9 +82,9 @@ void get_tty_password_buff(const char *opt_message, char *to, size_t length) _cputs(opt_message ? opt_message : "Enter password: "); for (;;) { - char tmp; + int tmp; tmp=_getch(); - if (tmp == '\b' || (int) tmp == 127) + if (tmp == '\b' || tmp == 127) { if (pos != to) { @@ -93,15 +93,13 @@ void get_tty_password_buff(const char *opt_message, char *to, size_t length) continue; } } - if (tmp == '\n' || tmp == '\r' || tmp == 3) + if (tmp == -1 || tmp == '\n' || tmp == '\r' || tmp == 3) break; if (iscntrl(tmp) || pos == end) continue; _cputs("*"); - *(pos++) = tmp; + *(pos++) = (char)tmp; } - while (pos != to && isspace(pos[-1]) == ' ') - pos--; /* Allow dummy space at end */ *pos=0; _cputs("\n"); } @@ -148,8 +146,6 @@ static void get_password(char *to,uint length,int fd, my_bool echo) } *(pos++) = tmp; } - while (pos != to && isspace(pos[-1]) == ' ') - pos--; /* Allow dummy space at end */ *pos=0; return; } From f523df0a04b5c43103d9628f8c714b81b735e838 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 12 Jan 2012 20:12:46 +0100 Subject: [PATCH 042/135] openpam compatibility --- plugin/auth_pam/auth_pam.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin/auth_pam/auth_pam.c b/plugin/auth_pam/auth_pam.c index 0d9cf2ae0af..ee13b37f793 100644 --- a/plugin/auth_pam/auth_pam.c +++ b/plugin/auth_pam/auth_pam.c @@ -131,7 +131,7 @@ end: return status == PAM_SUCCESS ? CR_OK : CR_ERROR; } -static struct st_mysql_auth pam_info = +static struct st_mysql_auth info = { MYSQL_AUTHENTICATION_INTERFACE_VERSION, "dialog", @@ -141,7 +141,7 @@ static struct st_mysql_auth pam_info = maria_declare_plugin(pam) { MYSQL_AUTHENTICATION_PLUGIN, - &pam_info, + &info, "pam", "Sergei Golubchik", "PAM based authentication", From a1e3fa93c74d50de3160545d3d9c18ca06dfcc7e Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 12 Jan 2012 20:13:22 +0100 Subject: [PATCH 043/135] lp:893522 more problems found by PVS Studio --- sql/scheduler.cc | 2 +- sql/winservice.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sql/scheduler.cc b/sql/scheduler.cc index 6dd93640dc5..d301b205b58 100644 --- a/sql/scheduler.cc +++ b/sql/scheduler.cc @@ -514,7 +514,7 @@ static void libevent_connection_close(THD *thd) thd->killed= THD::KILL_CONNECTION; // Avoid error messages - if (thd->net.vio->sd >= 0) // not already closed + if (thd->net.vio->type != VIO_CLOSED) // not already closed { end_connection(thd); close_connection(thd, 0, 1); diff --git a/sql/winservice.c b/sql/winservice.c index 562f047fa79..3ec91c26835 100644 --- a/sql/winservice.c +++ b/sql/winservice.c @@ -116,7 +116,7 @@ int get_mysql_service_properties(const wchar_t *bin_path, wcscat(mysqld_path, L".exe"); if(wcsicmp(file_part, L"mysqld.exe") != 0 && - wcsicmp(file_part, L"mysqld.exe") != 0 && + wcsicmp(file_part, L"mysqld-debug.exe") != 0 && wcsicmp(file_part, L"mysqld-nt.exe") != 0) { /* The service executable is not mysqld. */ @@ -244,4 +244,4 @@ int get_mysql_service_properties(const wchar_t *bin_path, end: LocalFree((HLOCAL)args); return retval; -} \ No newline at end of file +} From e4c61d263bd452200440f38284294170246c73b0 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 12 Jan 2012 20:13:41 +0100 Subject: [PATCH 044/135] lp:901693 dialog.c:perform_dialog treats every password prompt as first --- plugin/auth/dialog.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugin/auth/dialog.c b/plugin/auth/dialog.c index 24765c17d1c..6b54096f8ea 100644 --- a/plugin/auth/dialog.c +++ b/plugin/auth/dialog.c @@ -290,6 +290,8 @@ static int perform_dialog(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) if (res) return CR_ERROR; + first= 0; + /* repeat unless it was the last question */ } while ((cmd & 1) != 1); From 5438d57315a3cb2b75f63f83de7e50d12645e421 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Fri, 13 Jan 2012 14:35:49 +0200 Subject: [PATCH 045/135] Added Handler_read_rnd_deleted, number of deleted rows found with ha_read_rnd_first. --- mysql-test/r/create.result | 1 + mysql-test/r/derived_view.result | 10 +++++++++ mysql-test/r/join_outer.result | 3 +++ mysql-test/r/join_outer_jcl6.result | 3 +++ mysql-test/r/null_key.result | 1 + mysql-test/r/partition.result | 6 +++++ mysql-test/r/partition_pruning.result | 10 +++++++-- mysql-test/r/ps.result | 4 ++++ mysql-test/r/select_pkeycache.result | 1 + mysql-test/r/status.result | 30 ++++++++++++++++++++++++- mysql-test/r/status_user.result | 1 + mysql-test/suite/pbxt/r/null_key.result | 1 + mysql-test/suite/pbxt/r/update.result | 6 +++++ mysql-test/t/partition_pruning.test | 2 ++ mysql-test/t/status.test | 10 +++++++++ sql/ha_partition.cc | 2 ++ sql/mysqld.cc | 1 + sql/sql_class.h | 10 ++++++++- 18 files changed, 98 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index 96abcd34b92..07b3f85d924 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -1556,6 +1556,7 @@ Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 7 drop table t1,t2; CREATE TABLE t1(c1 VARCHAR(33), KEY USING BTREE (c1)); diff --git a/mysql-test/r/derived_view.result b/mysql-test/r/derived_view.result index cee19237230..7636f79189c 100644 --- a/mysql-test/r/derived_view.result +++ b/mysql-test/r/derived_view.result @@ -79,6 +79,7 @@ Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 flush status; select * from (select * from t1 where f1 in (2,3)) tt where f11=2; @@ -91,6 +92,7 @@ Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 12 for merged views create view v1 as select * from t1; @@ -162,6 +164,7 @@ Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 flush status; select * from v4 where f2 in (1,3); @@ -174,6 +177,7 @@ Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 12 for materialized derived tables explain for simple derived @@ -224,6 +228,7 @@ Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 flush status; select * from t1 join (select * from t2 group by f2) tt on f1=f2; @@ -238,6 +243,7 @@ Handler_read_key 11 Handler_read_next 3 Handler_read_prev 0 Handler_read_rnd 11 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 36 for materialized views drop view v1,v2,v3; @@ -311,6 +317,7 @@ Handler_read_key 22 Handler_read_next 22 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 60 explain showing late materialization flush status; @@ -326,6 +333,7 @@ Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 flush status; select * from t1 join v2 on f1=f2; @@ -340,6 +348,7 @@ Handler_read_key 11 Handler_read_next 3 Handler_read_prev 0 Handler_read_rnd 11 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 36 explain extended select * from v1 join v4 on f1=f2; id select_type table type possible_keys key key_len ref rows filtered Extra @@ -433,6 +442,7 @@ Handler_read_key 2 Handler_read_next 2 Handler_read_prev 0 Handler_read_rnd 8 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 39 flush status; merged in merged derived join merged in merged derived diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result index 9e84010d5ce..60defea291b 100644 --- a/mysql-test/r/join_outer.result +++ b/mysql-test/r/join_outer.result @@ -1240,6 +1240,7 @@ Handler_read_key 5 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 6 DROP TABLE t1,t2; CREATE TABLE t1 (c int PRIMARY KEY, e int NOT NULL); @@ -1499,6 +1500,7 @@ Handler_read_key 4 Handler_read_next 5 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 1048581 flush status; select sum(t3.b) from t2 left join t3 on t3.a=t2.a and t2.a <> 10; @@ -1511,6 +1513,7 @@ Handler_read_key 4 Handler_read_next 5 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 1048581 drop table t1,t2,t3; # diff --git a/mysql-test/r/join_outer_jcl6.result b/mysql-test/r/join_outer_jcl6.result index ab9e437c6bf..767d0544f1b 100644 --- a/mysql-test/r/join_outer_jcl6.result +++ b/mysql-test/r/join_outer_jcl6.result @@ -1251,6 +1251,7 @@ Handler_read_key 5 Handler_read_next 9 Handler_read_prev 0 Handler_read_rnd 3 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 6 DROP TABLE t1,t2; CREATE TABLE t1 (c int PRIMARY KEY, e int NOT NULL); @@ -1510,6 +1511,7 @@ Handler_read_key 4 Handler_read_next 5 Handler_read_prev 0 Handler_read_rnd 5 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 1048581 flush status; select sum(t3.b) from t2 left join t3 on t3.a=t2.a and t2.a <> 10; @@ -1522,6 +1524,7 @@ Handler_read_key 4 Handler_read_next 5 Handler_read_prev 0 Handler_read_rnd 5 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 1048581 drop table t1,t2,t3; # diff --git a/mysql-test/r/null_key.result b/mysql-test/r/null_key.result index 488110b88e3..a21f9190069 100644 --- a/mysql-test/r/null_key.result +++ b/mysql-test/r/null_key.result @@ -427,6 +427,7 @@ Handler_read_key 6 Handler_read_next 2 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 5 DROP TABLE t1,t2,t3,t4; CREATE TABLE t1 ( diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result index adf7ddac8b7..866a6fc1197 100644 --- a/mysql-test/r/partition.result +++ b/mysql-test/r/partition.result @@ -382,6 +382,7 @@ Handler_read_key 2 Handler_read_next 4 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 EXPLAIN PARTITIONS SELECT c1 FROM t2 WHERE (c1 > 10 AND c1 < 13) OR (c1 > 17 AND c1 < 20); id select_type table partitions type possible_keys key key_len ref rows Extra @@ -400,6 +401,7 @@ Handler_read_key 2 Handler_read_next 4 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 DROP TABLE t1,t2; CREATE TABLE `t1` ( @@ -430,6 +432,7 @@ Handler_read_key 1 Handler_read_next 2 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 EXPLAIN PARTITIONS SELECT c1 FROM t2 WHERE (c1 > 2 AND c1 < 5); id select_type table partitions type possible_keys key key_len ref rows Extra @@ -446,6 +449,7 @@ Handler_read_key 1 Handler_read_next 2 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 EXPLAIN PARTITIONS SELECT c1 FROM t1 WHERE (c1 > 12 AND c1 < 15); id select_type table partitions type possible_keys key key_len ref rows Extra @@ -462,6 +466,7 @@ Handler_read_key 1 Handler_read_next 2 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 EXPLAIN PARTITIONS SELECT c1 FROM t2 WHERE (c1 > 12 AND c1 < 15); id select_type table partitions type possible_keys key key_len ref rows Extra @@ -478,6 +483,7 @@ Handler_read_key 1 Handler_read_next 2 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 DROP TABLE t1,t2; create table t1 (a int) partition by list ((a/3)*10 div 1) diff --git a/mysql-test/r/partition_pruning.result b/mysql-test/r/partition_pruning.result index 6d6371e263f..d5594c7453e 100644 --- a/mysql-test/r/partition_pruning.result +++ b/mysql-test/r/partition_pruning.result @@ -2639,7 +2639,10 @@ flush status; delete from t2 where b > 5; show status like 'Handler_read_rnd_next'; Variable_name Value -Handler_read_rnd_next 1215 +Handler_read_rnd_next 815 +show status like 'Handler_read_rnd_deleted'; +Variable_name Value +Handler_read_rnd_deleted 400 show status like 'Handler_read_key'; Variable_name Value Handler_read_key 0 @@ -2653,7 +2656,10 @@ flush status; delete from t2 where b < 5 or b > 3; show status like 'Handler_read_rnd_next'; Variable_name Value -Handler_read_rnd_next 1215 +Handler_read_rnd_next 515 +show status like 'Handler_read_rnd_deleted'; +Variable_name Value +Handler_read_rnd_deleted 700 show status like 'Handler_read_key'; Variable_name Value Handler_read_key 0 diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 08944da6182..09b3c1a3c67 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -3082,6 +3082,7 @@ Handler_read_key 1 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 flush status; execute st; @@ -3094,6 +3095,7 @@ Handler_read_key 1 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 flush status; select * from t1 use index() where a=3; @@ -3106,6 +3108,7 @@ Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 8 flush status; execute st; @@ -3118,6 +3121,7 @@ Handler_read_key 1 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 deallocate prepare st; drop table t1; diff --git a/mysql-test/r/select_pkeycache.result b/mysql-test/r/select_pkeycache.result index fc0f7283981..9648860619b 100644 --- a/mysql-test/r/select_pkeycache.result +++ b/mysql-test/r/select_pkeycache.result @@ -4342,6 +4342,7 @@ Handler_read_key 2 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 6 DROP TABLE t1, t2; CREATE TABLE t1 (f1 bigint(20) NOT NULL default '0', diff --git a/mysql-test/r/status.result b/mysql-test/r/status.result index 5579728e0b2..b0744726390 100644 --- a/mysql-test/r/status.result +++ b/mysql-test/r/status.result @@ -281,6 +281,7 @@ Handler_read_key 4 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 7 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 23 Handler_rollback 0 Handler_savepoint 0 @@ -296,7 +297,34 @@ Created_tmp_files 0 Created_tmp_tables 2 Handler_tmp_update 2 Handler_tmp_write 7 -Rows_tmp_read 34 +Rows_tmp_read 35 +drop table t1; +CREATE TABLE t1 (i int(11) DEFAULT NULL, KEY i (i) ) ENGINE=MyISAM; +insert into t1 values (1),(2),(3),(4),(5); +flush status; +select * from t1 where i=5 union select * from t1 where i=5; +i +5 +show status like "handler%"; +Variable_name Value +Handler_commit 0 +Handler_delete 0 +Handler_discover 0 +Handler_prepare 0 +Handler_read_first 0 +Handler_read_key 2 +Handler_read_next 2 +Handler_read_prev 0 +Handler_read_rnd 0 +Handler_read_rnd_deleted 1 +Handler_read_rnd_next 2 +Handler_rollback 0 +Handler_savepoint 0 +Handler_savepoint_rollback 0 +Handler_tmp_update 0 +Handler_tmp_write 2 +Handler_update 0 +Handler_write 0 drop table t1; set @@global.concurrent_insert= @old_concurrent_insert; SET GLOBAL log_output = @old_log_output; diff --git a/mysql-test/r/status_user.result b/mysql-test/r/status_user.result index bc5f0aff7e4..17c44df1d3c 100644 --- a/mysql-test/r/status_user.result +++ b/mysql-test/r/status_user.result @@ -106,6 +106,7 @@ Handler_read_key 3 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 5 Handler_rollback 2 Handler_savepoint 0 diff --git a/mysql-test/suite/pbxt/r/null_key.result b/mysql-test/suite/pbxt/r/null_key.result index bef8c92419a..cc2b417b263 100644 --- a/mysql-test/suite/pbxt/r/null_key.result +++ b/mysql-test/suite/pbxt/r/null_key.result @@ -427,5 +427,6 @@ Handler_read_key 6 Handler_read_next 2 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 5 DROP TABLE t1,t2,t3,t4; diff --git a/mysql-test/suite/pbxt/r/update.result b/mysql-test/suite/pbxt/r/update.result index 9154583fa81..46321d6f3bf 100644 --- a/mysql-test/suite/pbxt/r/update.result +++ b/mysql-test/suite/pbxt/r/update.result @@ -276,6 +276,7 @@ Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 flush status; update t1 set a=9999 order by a limit 1; @@ -290,6 +291,7 @@ Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 2 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 18 flush status; delete from t1 order by a limit 1; @@ -300,6 +302,7 @@ Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 1 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 9 flush status; delete from t1 order by a desc limit 1; @@ -310,6 +313,7 @@ Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 1 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 8 alter table t1 disable keys; Warnings: @@ -323,6 +327,7 @@ Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 1 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 7 select * from t1; a b @@ -376,6 +381,7 @@ Handler_read_key 1 Handler_read_next 1 Handler_read_prev 0 Handler_read_rnd 1 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 drop table t1, t2; create table t1(f1 int, `*f2` int); diff --git a/mysql-test/t/partition_pruning.test b/mysql-test/t/partition_pruning.test index f1ec8964769..f12593d746f 100644 --- a/mysql-test/t/partition_pruning.test +++ b/mysql-test/t/partition_pruning.test @@ -1086,12 +1086,14 @@ show status like 'Handler_read_key'; flush status; delete from t2 where b > 5; show status like 'Handler_read_rnd_next'; +show status like 'Handler_read_rnd_deleted'; show status like 'Handler_read_key'; show status like 'Handler_read_prev'; show status like 'Handler_read_next'; flush status; delete from t2 where b < 5 or b > 3; show status like 'Handler_read_rnd_next'; +show status like 'Handler_read_rnd_deleted'; show status like 'Handler_read_key'; show status like 'Handler_read_prev'; show status like 'Handler_read_next'; diff --git a/mysql-test/t/status.test b/mysql-test/t/status.test index 46e454363cc..8cc938c923e 100644 --- a/mysql-test/t/status.test +++ b/mysql-test/t/status.test @@ -368,6 +368,16 @@ show status like 'Handler%'; show status like '%tmp%'; drop table t1; +# +# Test of handler status counts +# +CREATE TABLE t1 (i int(11) DEFAULT NULL, KEY i (i) ) ENGINE=MyISAM; +insert into t1 values (1),(2),(3),(4),(5); +flush status; +select * from t1 where i=5 union select * from t1 where i=5; +show status like "handler%"; +drop table t1; + # End of 5.3 tests # Restore global concurrent_insert value. Keep in the end of the test file. diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 290224850c7..03a879815e8 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -3938,6 +3938,8 @@ int ha_partition::rnd_next(uchar *buf) int result= HA_ERR_END_OF_FILE; uint part_id= m_part_spec.start_part; DBUG_ENTER("ha_partition::rnd_next"); + + /* upper level will increment this once again at end of call */ decrement_statistics(&SSV::ha_read_rnd_next_count); if (NO_CURRENT_PART_ID == part_id) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 1a60d996fed..1312675f7b4 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -8294,6 +8294,7 @@ SHOW_VAR status_vars[]= { {"Handler_read_next", (char*) offsetof(STATUS_VAR, ha_read_next_count), SHOW_LONG_STATUS}, {"Handler_read_prev", (char*) offsetof(STATUS_VAR, ha_read_prev_count), SHOW_LONG_STATUS}, {"Handler_read_rnd", (char*) offsetof(STATUS_VAR, ha_read_rnd_count), SHOW_LONG_STATUS}, + {"Handler_read_rnd_deleted", (char*) offsetof(STATUS_VAR, ha_read_rnd_deleted_count), SHOW_LONG_STATUS}, {"Handler_read_rnd_next", (char*) offsetof(STATUS_VAR, ha_read_rnd_next_count), SHOW_LONG_STATUS}, {"Handler_rollback", (char*) offsetof(STATUS_VAR, ha_rollback_count), SHOW_LONG_STATUS}, {"Handler_savepoint", (char*) offsetof(STATUS_VAR, ha_savepoint_count), SHOW_LONG_STATUS}, diff --git a/sql/sql_class.h b/sql/sql_class.h index da82ed5beed..f7d44eeec52 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -571,6 +571,7 @@ typedef struct system_status_var ulong ha_read_prev_count; ulong ha_read_rnd_count; ulong ha_read_rnd_next_count; + ulong ha_read_rnd_deleted_count; /* This number doesn't include calls to the default implementation and calls made by range access. The intent is to count only calls made by @@ -3747,10 +3748,17 @@ inline int handler::ha_ft_read(uchar *buf) inline int handler::ha_rnd_next(uchar *buf) { - increment_statistics(&SSV::ha_read_rnd_next_count); int error= rnd_next(buf); if (!error) + { update_rows_read(); + increment_statistics(&SSV::ha_read_rnd_next_count); + } + else if (error == HA_ERR_RECORD_DELETED) + increment_statistics(&SSV::ha_read_rnd_deleted_count); + else + increment_statistics(&SSV::ha_read_rnd_next_count); + table->status=error ? STATUS_NOT_FOUND: 0; return error; } From 6b4c132bc771631e85ca647f0dc4fc098859101a Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 17 Jan 2012 15:16:00 +0200 Subject: [PATCH 046/135] Removed unused code merged from 5.2. In 5.3 we fix this problem by checking if we put max/min group function without GROUP BY artificially in case of MODE_ONLY_FULL_GROUP_BY sql mode. --- sql/item_subselect.cc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 699c6e11cc1..ed556f05466 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1672,10 +1672,6 @@ bool Item_allany_subselect::transform_into_max_min(JOIN *join) DBUG_EXECUTE("where", print_where(item, "rewrite with MIN/MAX", QT_ORDINARY);); - if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY) - { - select_lex->set_non_agg_field_used(false); - } save_allow_sum_func= thd->lex->allow_sum_func; thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level; From 69327e2987f7d5a2749860d269cdb4d75b646f24 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 18 Jan 2012 12:53:50 +0200 Subject: [PATCH 047/135] Adjust test results after Monty's push of the new handler counter Handler_read_rnd_deleted. --- mysql-test/r/insert_select.result | 1 + mysql-test/r/join.result | 2 ++ mysql-test/r/select.result | 1 + mysql-test/r/select_jcl6.result | 3 ++- mysql-test/r/subselect3.result | 1 + mysql-test/r/subselect3_jcl6.result | 1 + mysql-test/r/subselect_cache.result | 34 +++++++++++++++++++++++++++-- mysql-test/r/update.result | 14 ++++++++++-- mysql-test/r/view.result | 2 ++ 9 files changed, 54 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/insert_select.result b/mysql-test/r/insert_select.result index cf3c0b0731e..636eecc085b 100644 --- a/mysql-test/r/insert_select.result +++ b/mysql-test/r/insert_select.result @@ -697,6 +697,7 @@ Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 1 DROP TABLE t1; CREATE TABLE t1 ( diff --git a/mysql-test/r/join.result b/mysql-test/r/join.result index 8a8b9a690a9..b1cfd80490d 100644 --- a/mysql-test/r/join.result +++ b/mysql-test/r/join.result @@ -860,6 +860,7 @@ Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 5 drop table t1, t2, t3; create table t1 (a int); @@ -1269,6 +1270,7 @@ Handler_read_key 1 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 1 DROP TABLE t1, t2; End of 5.1 tests diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index fc0f7283981..9648860619b 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -4342,6 +4342,7 @@ Handler_read_key 2 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 6 DROP TABLE t1, t2; CREATE TABLE t1 (f1 bigint(20) NOT NULL default '0', diff --git a/mysql-test/r/select_jcl6.result b/mysql-test/r/select_jcl6.result index 2d3add1b922..88411e3482f 100644 --- a/mysql-test/r/select_jcl6.result +++ b/mysql-test/r/select_jcl6.result @@ -4353,7 +4353,8 @@ Handler_read_key 2 Handler_read_next 10 Handler_read_prev 0 Handler_read_rnd 10 -Handler_read_rnd_next 7 +Handler_read_rnd_deleted 1 +Handler_read_rnd_next 6 DROP TABLE t1, t2; CREATE TABLE t1 (f1 bigint(20) NOT NULL default '0', f2 int(11) NOT NULL default '0', diff --git a/mysql-test/r/subselect3.result b/mysql-test/r/subselect3.result index ae629ccb928..3f83ac59fed 100644 --- a/mysql-test/r/subselect3.result +++ b/mysql-test/r/subselect3.result @@ -124,6 +124,7 @@ Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 50 select 'No key lookups, seq reads: 29= 5 reads from t2 + 4 * 6 reads from t1.' Z; Z diff --git a/mysql-test/r/subselect3_jcl6.result b/mysql-test/r/subselect3_jcl6.result index 7d20f81fbb9..38284345fc2 100644 --- a/mysql-test/r/subselect3_jcl6.result +++ b/mysql-test/r/subselect3_jcl6.result @@ -134,6 +134,7 @@ Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 50 select 'No key lookups, seq reads: 29= 5 reads from t2 + 4 * 6 reads from t1.' Z; Z diff --git a/mysql-test/r/subselect_cache.result b/mysql-test/r/subselect_cache.result index 1dd1655c2a6..1f9fcdeca6e 100644 --- a/mysql-test/r/subselect_cache.result +++ b/mysql-test/r/subselect_cache.result @@ -36,6 +36,7 @@ Handler_read_key 7 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 31 set optimizer_switch='subquery_cache=off'; flush status; @@ -62,6 +63,7 @@ Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 61 set optimizer_switch='subquery_cache=on'; #single value subquery test (where) @@ -87,6 +89,7 @@ Handler_read_key 7 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 31 set optimizer_switch='subquery_cache=off'; flush status; @@ -111,6 +114,7 @@ Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 61 set optimizer_switch='subquery_cache=on'; #single value subquery test (having) @@ -136,6 +140,7 @@ Handler_read_key 7 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 31 set optimizer_switch='subquery_cache=off'; flush status; @@ -160,6 +165,7 @@ Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 61 set optimizer_switch='subquery_cache=on'; #single value subquery test (OUTER JOIN ON) @@ -257,6 +263,7 @@ Handler_read_key 7 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 442 set optimizer_switch='subquery_cache=off'; flush status; @@ -353,6 +360,7 @@ Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 472 set optimizer_switch='subquery_cache=on'; #single value subquery test (GROUP BY) @@ -374,6 +382,7 @@ Handler_read_key 17 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 4 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 36 set optimizer_switch='subquery_cache=off'; flush status; @@ -394,6 +403,7 @@ Handler_read_key 10 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 4 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 86 set optimizer_switch='subquery_cache=on'; #single value subquery test (distinct GROUP BY) @@ -415,6 +425,7 @@ Handler_read_key 17 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 4 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 41 set optimizer_switch='subquery_cache=off'; flush status; @@ -435,6 +446,7 @@ Handler_read_key 10 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 4 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 91 set optimizer_switch='subquery_cache=on'; #single value subquery test (ORDER BY) @@ -462,6 +474,7 @@ Handler_read_key 7 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 10 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 42 set optimizer_switch='subquery_cache=off'; flush status; @@ -488,6 +501,7 @@ Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 10 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 72 set optimizer_switch='subquery_cache=on'; #single value subquery test (distinct ORDER BY) @@ -509,7 +523,8 @@ Handler_read_key 7 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 4 -Handler_read_rnd_next 37 +Handler_read_rnd_deleted 1 +Handler_read_rnd_next 36 set optimizer_switch='subquery_cache=off'; flush status; select distinct a from t1 ORDER BY (select d from t2 where b=c); @@ -529,7 +544,8 @@ Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 4 -Handler_read_rnd_next 67 +Handler_read_rnd_deleted 1 +Handler_read_rnd_next 66 set optimizer_switch='subquery_cache=on'; #single value subquery test (LEFT JOIN ON) flush status; @@ -626,6 +642,7 @@ Handler_read_key 70 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 141 set optimizer_switch='subquery_cache=off'; flush status; @@ -722,6 +739,7 @@ Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 671 set optimizer_switch='subquery_cache=on'; #single value subquery test (PS) @@ -1345,6 +1363,7 @@ Handler_read_key 11 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 145 set optimizer_switch='subquery_cache=on'; flush status; @@ -1373,6 +1392,7 @@ Handler_read_key 32 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 84 #several subqueries (several levels) set optimizer_switch='subquery_cache=off'; @@ -1404,6 +1424,7 @@ Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 127 set optimizer_switch='subquery_cache=on'; flush status; @@ -1432,6 +1453,7 @@ Handler_read_key 13 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 69 #clean up drop table t1,t2; @@ -1621,6 +1643,7 @@ Handler_read_key 15 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 8 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 57 set optimizer_switch='subquery_cache=on'; flush status; @@ -1645,6 +1668,7 @@ Handler_read_key 21 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 8 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 37 argument of aggregate function as parameter of subquery (illegal use) set optimizer_switch='subquery_cache=off'; @@ -1670,6 +1694,7 @@ Handler_read_key 15 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 8 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 57 set optimizer_switch='subquery_cache=on'; flush status; @@ -1694,6 +1719,7 @@ Handler_read_key 22 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 8 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 41 drop table t1,t2; #test of flattening subquery optimisations and cache @@ -1734,6 +1760,7 @@ Handler_read_key 15 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 16 alter table t2 drop primary key; set optimizer_switch='default,semijoin=off,materialization=off,subquery_cache=off'; @@ -1770,6 +1797,7 @@ Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 151 set optimizer_switch='default,semijoin=off,materialization=off,subquery_cache=on'; explain select * from t1 where a in (select pk from t2); @@ -1805,6 +1833,7 @@ Handler_read_key 15 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 43 set optimizer_switch='default,semijoin=off,materialization=on,subquery_cache=on'; explain select * from t1 where a in (select pk from t2); @@ -1840,6 +1869,7 @@ Handler_read_key 18 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 27 drop table t0,t1,t2; set optimizer_switch='default'; diff --git a/mysql-test/r/update.result b/mysql-test/r/update.result index 63baf639487..4062a92901d 100644 --- a/mysql-test/r/update.result +++ b/mysql-test/r/update.result @@ -276,6 +276,7 @@ Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 flush status; update t1 set a=9999 order by a limit 1; @@ -287,6 +288,7 @@ Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 2 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 9 flush status; delete from t1 order by a limit 1; @@ -297,6 +299,7 @@ Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 flush status; delete from t1 order by a desc limit 1; @@ -307,7 +310,8 @@ Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 1 -Handler_read_rnd_next 9 +Handler_read_rnd_deleted 1 +Handler_read_rnd_next 8 alter table t1 disable keys; flush status; delete from t1 order by a limit 1; @@ -318,7 +322,8 @@ Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 1 -Handler_read_rnd_next 9 +Handler_read_rnd_deleted 2 +Handler_read_rnd_next 7 select * from t1; a b 0 0 @@ -371,6 +376,7 @@ Handler_read_key 1 Handler_read_next 1 Handler_read_prev 0 Handler_read_rnd 1 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 drop table t1, t2; create table t1(f1 int, `*f2` int); @@ -408,6 +414,7 @@ Handler_read_key 1 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 SELECT user_id FROM t1 WHERE request_id=999999999999999999999999999999; user_id @@ -418,6 +425,7 @@ Handler_read_key 2 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 UPDATE t1 SET user_id=null WHERE request_id=9999999999999; show status like '%Handler_read%'; @@ -427,6 +435,7 @@ Handler_read_key 3 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 UPDATE t1 SET user_id=null WHERE request_id=999999999999999999999999999999; show status like '%Handler_read%'; @@ -436,6 +445,7 @@ Handler_read_key 3 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 0 DROP TABLE t1; CREATE TABLE t1 ( diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 644f7f7289e..f3d68e67b61 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -3959,6 +3959,7 @@ Handler_read_key 1 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 17 CREATE VIEW v AS SELECT * FROM t2; EXPLAIN EXTENDED @@ -3980,6 +3981,7 @@ Handler_read_key 1 Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 0 +Handler_read_rnd_deleted 0 Handler_read_rnd_next 17 DROP VIEW v; DROP TABLE t1, t2; From 746dbbe583f8528b34065b0669136842128e27b2 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Wed, 18 Jan 2012 03:31:20 -0800 Subject: [PATCH 048/135] Fixed LP bug #917990. If the expression for a derived table of a query contained a LIMIT clause the estimate of the number of rows in this derived table returned by the EXPLAIN command could be badly off since the optimizer ignored the limit number from the LIMIT clause when getting the estimate. The call of the method SELECT_LEX_UNIT->set_limit added in the code of mysql_derived_optimize() will be needed also in maria-5.5 where parameters in the LIMIT clause are supported. --- mysql-test/r/derived_view.result | 17 +++++++++++++++++ mysql-test/r/view.result | 2 +- mysql-test/suite/vcol/r/vcol_view_innodb.result | 4 ++-- mysql-test/suite/vcol/r/vcol_view_myisam.result | 4 ++-- mysql-test/t/derived_view.test | 14 ++++++++++++++ sql/sql_derived.cc | 1 + sql/sql_select.cc | 1 + 7 files changed, 38 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/derived_view.result b/mysql-test/r/derived_view.result index cee19237230..416c68ffb46 100644 --- a/mysql-test/r/derived_view.result +++ b/mysql-test/r/derived_view.result @@ -1879,5 +1879,22 @@ ORDER BY CONCAT(alias2.col_varchar_nokey); col_varchar_key pk col_varchar_key col_varchar_nokey set max_heap_table_size= @tmp_882994; drop table t1,t2,t3; +# +# LP bug #917990: Bad estimate of #rows for derived table with LIMIT +# +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES +(8), (3), (4), (7), (9), (5), (1), (2); +SELECT * FROM (SELECT * FROM t1 LIMIT 3) t; +a +8 +3 +4 +EXPLAIN +SELECT * FROM (SELECT * FROM t1 LIMIT 3) t; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ALL NULL NULL NULL NULL 3 +2 DERIVED t1 ALL NULL NULL NULL NULL 8 +DROP TABLE t1; set optimizer_switch=@exit_optimizer_switch; set join_cache_level=@exit_join_cache_level; diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 644f7f7289e..8a71d00291c 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -304,7 +304,7 @@ a+1 4 explain select * from v1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 4 +1 PRIMARY ALL NULL NULL NULL NULL 2 2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using filesort drop view v1; drop table t1; diff --git a/mysql-test/suite/vcol/r/vcol_view_innodb.result b/mysql-test/suite/vcol/r/vcol_view_innodb.result index 94c311fb8b9..d117b030f94 100644 --- a/mysql-test/suite/vcol/r/vcol_view_innodb.result +++ b/mysql-test/suite/vcol/r/vcol_view_innodb.result @@ -107,7 +107,7 @@ MariaDB-5.3: the following EXPLAIN produces incorrect #rows for table t1. MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed explain select * from v1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 4 +1 PRIMARY ALL NULL NULL NULL NULL 2 2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using filesort drop view v1; create view v1 as select c+1 from t1 order by 1 desc limit 2; @@ -119,7 +119,7 @@ MariaDB-5.3: the following EXPLAIN produces incorrect #rows for table t1. MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed explain select * from v1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 4 +1 PRIMARY ALL NULL NULL NULL NULL 2 2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using filesort drop view v1; drop table t1; diff --git a/mysql-test/suite/vcol/r/vcol_view_myisam.result b/mysql-test/suite/vcol/r/vcol_view_myisam.result index b96e003e1cc..fe48be4c794 100644 --- a/mysql-test/suite/vcol/r/vcol_view_myisam.result +++ b/mysql-test/suite/vcol/r/vcol_view_myisam.result @@ -107,7 +107,7 @@ MariaDB-5.3: the following EXPLAIN produces incorrect #rows for table t1. MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed explain select * from v1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 4 +1 PRIMARY ALL NULL NULL NULL NULL 2 2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using filesort drop view v1; create view v1 as select c+1 from t1 order by 1 desc limit 2; @@ -119,7 +119,7 @@ MariaDB-5.3: the following EXPLAIN produces incorrect #rows for table t1. MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed explain select * from v1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 4 +1 PRIMARY ALL NULL NULL NULL NULL 2 2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using filesort drop view v1; drop table t1; diff --git a/mysql-test/t/derived_view.test b/mysql-test/t/derived_view.test index b674350af0a..f8ba1f347f3 100644 --- a/mysql-test/t/derived_view.test +++ b/mysql-test/t/derived_view.test @@ -1277,6 +1277,20 @@ ORDER BY CONCAT(alias2.col_varchar_nokey); set max_heap_table_size= @tmp_882994; drop table t1,t2,t3; +--echo # +--echo # LP bug #917990: Bad estimate of #rows for derived table with LIMIT +--echo # + +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES + (8), (3), (4), (7), (9), (5), (1), (2); + +SELECT * FROM (SELECT * FROM t1 LIMIT 3) t; +EXPLAIN +SELECT * FROM (SELECT * FROM t1 LIMIT 3) t; + +DROP TABLE t1; + # The following command must be the last one the file set optimizer_switch=@exit_optimizer_switch; set join_cache_level=@exit_join_cache_level; diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 0e104520fac..0955f9c0982 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -753,6 +753,7 @@ bool mysql_derived_optimize(THD *thd, LEX *lex, TABLE_LIST *derived) if (!derived->is_merged_derived()) { JOIN *join= first_select->join; + unit->set_limit(first_select); unit->optimized= TRUE; if ((res= join->optimize())) goto err; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index fe52bc05465..dc13e1ddcab 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3581,6 +3581,7 @@ make_join_statistics(JOIN *join, List &tables_list, for (i= 0; i < join->table_count ; i++) records*= join->best_positions[i].records_read ? (ha_rows)join->best_positions[i].records_read : 1; + set_if_smaller(records, unit->select_limit_cnt); join->select_lex->increase_derived_records(records); } } From 88f451aa6e6c09b199f5e00f48500157c7f3e245 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 18 Jan 2012 14:52:56 +0100 Subject: [PATCH 049/135] multi-delete should ignore semi-join internal temp tables, when looking for tables to delete from --- sql/sql_delete.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 722b6f7478f..3ce375190a7 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -715,7 +715,7 @@ multi_delete::initialize_tables(JOIN *join) for (JOIN_TAB *tab= first_linear_tab(join, WITH_CONST_TABLES); tab; - tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS)) + tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS)) { if (tab->table->map & tables_to_delete_from) { From 0e975ded65510a85173a6d05b9fd4824fbfd07af Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Thu, 19 Jan 2012 13:46:59 +0100 Subject: [PATCH 050/135] Fix compiler warning on Windows. --- storage/xtradb/row/row0sel.c | 1 + 1 file changed, 1 insertion(+) diff --git a/storage/xtradb/row/row0sel.c b/storage/xtradb/row/row0sel.c index 4ae55b47b5b..226b19359bb 100644 --- a/storage/xtradb/row/row0sel.c +++ b/storage/xtradb/row/row0sel.c @@ -3455,6 +3455,7 @@ row_search_idx_cond_check( } ut_error; + return(ICP_ABORTED_BY_USER); /* Keep compiler happy */ } /********************************************************************//** From 8bedf1ea1c328fabea14a1ce232794d73814b6d7 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Thu, 19 Jan 2012 23:44:43 +0400 Subject: [PATCH 051/135] BUG#912538: Wrong result (missing rows) with semijoin=on, firstmatch=on, ... - setup_semijoin_dups_elimination() would incorrectly set join_tab->do_firstmatch when the join order had outer tables interleaved with inner. --- mysql-test/r/subselect_sj2.result | 14 ++++++++++ mysql-test/r/subselect_sj2_jcl6.result | 23 +++++++++++++--- mysql-test/r/subselect_sj2_mat.result | 14 ++++++++++ mysql-test/t/subselect_sj2.test | 14 ++++++++++ sql/opt_subselect.cc | 37 +++++++++++++++++++++----- 5 files changed, 91 insertions(+), 11 deletions(-) diff --git a/mysql-test/r/subselect_sj2.result b/mysql-test/r/subselect_sj2.result index 8df3bd8f9b8..4e9672446a3 100644 --- a/mysql-test/r/subselect_sj2.result +++ b/mysql-test/r/subselect_sj2.result @@ -889,5 +889,19 @@ a b b a c c NULL NULL DROP VIEW v1; DROP TABLE t1,t2,t3,t4; +# +# BUG#912538: Wrong result (missing rows) with semijoin=on, firstmatch=on, ... +# +CREATE TABLE t1 ( a INT NOT NULL, UNIQUE KEY(a) ); +INSERT INTO t1 VALUES (1),(2),(3),(4); +CREATE TABLE t2 ( b INT, c INT ) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,1); +SELECT * FROM t1, t2 WHERE c IN (SELECT c FROM t1, t2 WHERE a = b); +a b c +1 1 1 +2 1 1 +3 1 1 +4 1 1 +DROP TABLE t1,t2; # This must be the last in the file: set optimizer_switch=@subselect_sj2_tmp; diff --git a/mysql-test/r/subselect_sj2_jcl6.result b/mysql-test/r/subselect_sj2_jcl6.result index 222d34d9bf4..1b7d65275ab 100644 --- a/mysql-test/r/subselect_sj2_jcl6.result +++ b/mysql-test/r/subselect_sj2_jcl6.result @@ -903,6 +903,20 @@ a b b a c c NULL NULL DROP VIEW v1; DROP TABLE t1,t2,t3,t4; +# +# BUG#912538: Wrong result (missing rows) with semijoin=on, firstmatch=on, ... +# +CREATE TABLE t1 ( a INT NOT NULL, UNIQUE KEY(a) ); +INSERT INTO t1 VALUES (1),(2),(3),(4); +CREATE TABLE t2 ( b INT, c INT ) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,1); +SELECT * FROM t1, t2 WHERE c IN (SELECT c FROM t1, t2 WHERE a = b); +a b c +1 1 1 +2 1 1 +3 1 1 +4 1 1 +DROP TABLE t1,t2; # This must be the last in the file: set optimizer_switch=@subselect_sj2_tmp; # @@ -924,9 +938,9 @@ SELECT t3.* FROM t1 JOIN t3 ON t3.b = t1.b WHERE c IN (SELECT t4.b FROM t4 JOIN t2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 1 Using where -1 PRIMARY t2 ALL NULL NULL NULL NULL 1 +1 PRIMARY t2 ALL NULL NULL NULL NULL 1 FirstMatch(t3) 1 PRIMARY t1 ref b b 4 test.t3.b 1 Using index -1 PRIMARY t4 ALL NULL NULL NULL NULL 2 Using where; FirstMatch(t2) +1 PRIMARY t4 ALL NULL NULL NULL NULL 2 Using where; FirstMatch(t1) SELECT t3.* FROM t1 JOIN t3 ON t3.b = t1.b WHERE c IN (SELECT t4.b FROM t4 JOIN t2); b c @@ -952,12 +966,13 @@ EXPLAIN SELECT * FROM t1, t2 WHERE b IN (SELECT a FROM t3, t4 WHERE b = pk); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 1 -1 PRIMARY t4 ALL NULL NULL NULL NULL 1 Using where +1 PRIMARY t4 ALL NULL NULL NULL NULL 1 Using where; FirstMatch(t2) 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 -1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t4.b 1 Using where; FirstMatch(t4) +1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t4.b 1 Using where; FirstMatch(t1) SELECT * FROM t1, t2 WHERE b IN (SELECT a FROM t3, t4 WHERE b = pk); pk a b 1 6 8 +2 8 8 set optimizer_switch=@tmp_optimizer_switch; set join_cache_level=default; DROP TABLE t1,t2,t3,t4; diff --git a/mysql-test/r/subselect_sj2_mat.result b/mysql-test/r/subselect_sj2_mat.result index 252f3c73a55..64d1ce2ef74 100644 --- a/mysql-test/r/subselect_sj2_mat.result +++ b/mysql-test/r/subselect_sj2_mat.result @@ -891,6 +891,20 @@ a b b a c c NULL NULL DROP VIEW v1; DROP TABLE t1,t2,t3,t4; +# +# BUG#912538: Wrong result (missing rows) with semijoin=on, firstmatch=on, ... +# +CREATE TABLE t1 ( a INT NOT NULL, UNIQUE KEY(a) ); +INSERT INTO t1 VALUES (1),(2),(3),(4); +CREATE TABLE t2 ( b INT, c INT ) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,1); +SELECT * FROM t1, t2 WHERE c IN (SELECT c FROM t1, t2 WHERE a = b); +a b c +1 1 1 +2 1 1 +3 1 1 +4 1 1 +DROP TABLE t1,t2; # This must be the last in the file: set optimizer_switch=@subselect_sj2_tmp; set optimizer_switch=default; diff --git a/mysql-test/t/subselect_sj2.test b/mysql-test/t/subselect_sj2.test index 9a664ee9881..30dc20087d1 100644 --- a/mysql-test/t/subselect_sj2.test +++ b/mysql-test/t/subselect_sj2.test @@ -1076,5 +1076,19 @@ SELECT * FROM t3 LEFT JOIN (v1,t2) ON t3.a = t2.a DROP VIEW v1; DROP TABLE t1,t2,t3,t4; +--echo # +--echo # BUG#912538: Wrong result (missing rows) with semijoin=on, firstmatch=on, ... +--echo # +CREATE TABLE t1 ( a INT NOT NULL, UNIQUE KEY(a) ); +INSERT INTO t1 VALUES (1),(2),(3),(4); + +# t2 needs to be InnoDB +CREATE TABLE t2 ( b INT, c INT ) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,1); + +SELECT * FROM t1, t2 WHERE c IN (SELECT c FROM t1, t2 WHERE a = b); + +DROP TABLE t1,t2; + --echo # This must be the last in the file: set optimizer_switch=@subselect_sj2_tmp; diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 1719b5a53d5..8e043b17bcf 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -4162,16 +4162,39 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options, } case SJ_OPT_FIRST_MATCH: { - JOIN_TAB *j, *jump_to= tab-1; + JOIN_TAB *j; + JOIN_TAB *jump_to= tab-1; for (j= tab; j != tab + pos->n_sj_tables; j++) { - /* - NOTE: this loop probably doesn't do the right thing for the case - where FirstMatch's duplicate-generating range is interleaved with - "unrelated" tables (as specified in WL#3750, section 2.2). - */ if (!j->emb_sj_nest) - jump_to= tab; + { + /* + Got a table that's not within any semi-join nest. This is a case + like this: + + SELECT * FROM ot1, nt1 WHERE ot1.col IN (SELECT expr FROM it1, it2) + + with a join order of + + + ot1 it1 nt1 nt2 + | ^ + | +-------- 'j' point here + +------------- SJ_OPT_FIRST_MATCH was set for this table as + it's the first one that produces duplicates + + */ + DBUG_ASSERT(j != tab); /* table ntX must have an itX before it */ + + /* + If the table right before us is an inner table (like it1 in the + picture), it should be set to jump back to previous outer-table + */ + if (j[-1].emb_sj_nest) + j[-1].do_firstmatch= jump_to; + + jump_to= j; /* Jump back to us */ + } else { j->first_sj_inner_tab= tab; From 9f60aa27f707dea88e8882c5aaf096dce35a3a72 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Fri, 20 Jan 2012 02:11:53 +0400 Subject: [PATCH 052/135] BUG#912513: Wrong result (missing rows) with join_cache_hashed+materialization+semijoin=on - equality substitution code was geared towards processing WHERE/ON clauses. that is, it assumed that it was doing substitions on the code that = wasn't attached to any particular join_tab yet = was going to be fed to make_join_select() which would take the condition apart and attach various parts of it to tables inside/outside semi-joins. - However, somebody added equality substition for ref access. That is, if we have a ref access on TBL.key=expr, they would do equality substition in 'expr'. This possibility wasn't accounted for. - Fixed equality substition code by adding a mode that does equality substition under assumption that the processed expression will be attached to a certain particular table TBL. --- mysql-test/r/subselect_sj_jcl6.result | 29 +++++++++++++++ mysql-test/t/subselect_sj_jcl6.test | 26 ++++++++++++++ sql/item.cc | 6 ++-- sql/item.h | 11 ++++++ sql/item_cmpfunc.cc | 10 ++++-- sql/item_cmpfunc.h | 2 +- sql/sql_select.cc | 51 ++++++++++++++++++++++----- 7 files changed, 121 insertions(+), 14 deletions(-) diff --git a/mysql-test/r/subselect_sj_jcl6.result b/mysql-test/r/subselect_sj_jcl6.result index 21a8ea39457..faa4140d375 100644 --- a/mysql-test/r/subselect_sj_jcl6.result +++ b/mysql-test/r/subselect_sj_jcl6.result @@ -2264,6 +2264,35 @@ w 5 19:11:10 set optimizer_switch=@save_optimizer_switch; set join_cache_level=default; DROP TABLE t1,t2,t3; +# +# BUG#912513: Wrong result (missing rows) with join_cache_hashed+materialization+semijoin=on +# +set @os_912513= @@optimizer_switch; +set @jcl_912513= @@join_cache_level; +SET optimizer_switch = 'semijoin=on,materialization=on,join_cache_hashed=on'; +SET join_cache_level = 3; +CREATE TABLE t1 ( a INT, b INT, KEY(a) ); +INSERT INTO t1 VALUES +(1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7); +CREATE TABLE t2 ( c INT ); +INSERT INTO t2 VALUES (1),(2),(3),(4),(5),(6),(7); +SELECT alias1.* FROM +t1 AS alias1 INNER JOIN t1 AS alias2 +ON alias2.a = alias1.b +WHERE alias1.b IN ( +SELECT a FROM t1, t2 +); +a b +1 1 +2 2 +3 3 +4 4 +5 5 +6 6 +7 7 +DROP table t1, t2; +set @@optimizer_switch= @os_912513; +set @@join_cache_level= @jcl_912513; # End set join_cache_level=default; show variables like 'join_cache_level'; diff --git a/mysql-test/t/subselect_sj_jcl6.test b/mysql-test/t/subselect_sj_jcl6.test index 4eeaa465b11..6d563cab3d3 100644 --- a/mysql-test/t/subselect_sj_jcl6.test +++ b/mysql-test/t/subselect_sj_jcl6.test @@ -88,6 +88,32 @@ set join_cache_level=default; DROP TABLE t1,t2,t3; +--echo # +--echo # BUG#912513: Wrong result (missing rows) with join_cache_hashed+materialization+semijoin=on +--echo # +set @os_912513= @@optimizer_switch; +set @jcl_912513= @@join_cache_level; +SET optimizer_switch = 'semijoin=on,materialization=on,join_cache_hashed=on'; +SET join_cache_level = 3; + +CREATE TABLE t1 ( a INT, b INT, KEY(a) ); +INSERT INTO t1 VALUES + (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7); + +CREATE TABLE t2 ( c INT ); +INSERT INTO t2 VALUES (1),(2),(3),(4),(5),(6),(7); + +SELECT alias1.* FROM + t1 AS alias1 INNER JOIN t1 AS alias2 + ON alias2.a = alias1.b +WHERE alias1.b IN ( + SELECT a FROM t1, t2 + ); + +DROP table t1, t2; +set @@optimizer_switch= @os_912513; +set @@join_cache_level= @jcl_912513; + --echo # End set join_cache_level=default; diff --git a/sql/item.cc b/sql/item.cc index d0608e392b3..aaf9b0c2a12 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -5023,7 +5023,8 @@ bool Item_field::set_no_const_sub(uchar *arg) Item *Item_field::replace_equal_field(uchar *arg) { - if (item_equal && item_equal == (Item_equal *) arg) + REPLACE_EQUAL_FIELD_ARG* param= (REPLACE_EQUAL_FIELD_ARG*)arg; + if (item_equal && item_equal == param->item_equal) { Item *const_item= item_equal->get_const(); if (const_item) @@ -5033,7 +5034,8 @@ Item *Item_field::replace_equal_field(uchar *arg) return this; return const_item; } - Item_field *subst= (Item_field *)(item_equal->get_first(this)); + Item_field *subst= + (Item_field *)(item_equal->get_first(param->context_tab, this)); if (subst) subst= (Item_field *) (subst->real_item()); if (subst && !field->eq(subst->field)) diff --git a/sql/item.h b/sql/item.h index d9aa6f3497e..9891d690798 100644 --- a/sql/item.h +++ b/sql/item.h @@ -440,6 +440,16 @@ typedef enum monotonicity_info class sp_rcontext; +class Item_equal; + +struct st_join_table* const NO_PARTICULAR_TAB= (struct st_join_table*)0x1; + +typedef struct replace_equal_field_arg +{ + Item_equal *item_equal; + struct st_join_table *context_tab; +} REPLACE_EQUAL_FIELD_ARG; + class Settable_routine_parameter { public: @@ -1153,6 +1163,7 @@ public: virtual Item *equal_fields_propagator(uchar * arg) { return this; } virtual bool set_no_const_sub(uchar *arg) { return FALSE; } + /* arg points to REPLACE_EQUAL_FIELD_ARG object */ virtual Item *replace_equal_field(uchar * arg) { return this; } /* Check if an expression value has allowed arguments, like DATE/DATETIME diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 5b2c862e9eb..8b8a85ca59b 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -5716,7 +5716,7 @@ longlong Item_equal::val_int() void Item_equal::fix_length_and_dec() { - Item *item= get_first(NULL); + Item *item= get_first(NO_PARTICULAR_TAB, NULL); eval_item= cmp_item::get_comparator(item->cmp_type(), item, item->collation.collation); } @@ -5816,7 +5816,7 @@ CHARSET_INFO *Item_equal::compare_collation() @retval 0 if no field found. */ -Item* Item_equal::get_first(Item *field_item) +Item* Item_equal::get_first(JOIN_TAB *context, Item *field_item) { Item_equal_fields_iterator it(*this); Item *item; @@ -5844,7 +5844,11 @@ Item* Item_equal::get_first(Item *field_item) in presense of SJM nests. */ - TABLE_LIST *emb_nest= field->table->pos_in_table_list->embedding; + TABLE_LIST *emb_nest; + if (context != NO_PARTICULAR_TAB) + emb_nest= context->emb_sj_nest; + else + emb_nest= field->table->pos_in_table_list->embedding; if (emb_nest && emb_nest->sj_mat_info && emb_nest->sj_mat_info->is_used) { diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 81a18bb594e..ad4f889f4df 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -1712,7 +1712,7 @@ public: /** Add a non-constant item to the multiple equality */ void add(Item *f) { equal_items.push_back(f); } bool contains(Field *field); - Item* get_first(Item *field); + Item* get_first(struct st_join_table *context, Item *field); /** Get number of field items / references to field items in this object */ uint n_field_items() { return equal_items.elements-test(with_const); } void merge(Item_equal *item); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index dc13e1ddcab..4058e72c547 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -110,7 +110,8 @@ static COND *build_equal_items(THD *thd, COND *cond, COND_EQUAL *inherited, List *join_list, COND_EQUAL **cond_equal_ref); -static COND* substitute_for_best_equal_field(COND *cond, +static COND* substitute_for_best_equal_field(JOIN_TAB *context_tab, + COND *cond, COND_EQUAL *cond_equal, void *table_join_idx); static COND *simplify_joins(JOIN *join, List *join_list, @@ -1225,7 +1226,8 @@ JOIN::optimize() */ if (conds) { - conds= substitute_for_best_equal_field(conds, cond_equal, map2table); + conds= substitute_for_best_equal_field(NO_PARTICULAR_TAB, conds, + cond_equal, map2table); conds->update_used_tables(); DBUG_EXECUTE("where", print_where(conds, @@ -1242,7 +1244,8 @@ JOIN::optimize() { if (*tab->on_expr_ref) { - *tab->on_expr_ref= substitute_for_best_equal_field(*tab->on_expr_ref, + *tab->on_expr_ref= substitute_for_best_equal_field(NO_PARTICULAR_TAB, + *tab->on_expr_ref, tab->cond_equal, map2table); (*tab->on_expr_ref)->update_used_tables(); @@ -1265,7 +1268,7 @@ JOIN::optimize() continue; COND_EQUAL *equals= tab->first_inner ? tab->first_inner->cond_equal : cond_equal; - ref_item= substitute_for_best_equal_field(ref_item, equals, map2table); + ref_item= substitute_for_best_equal_field(tab, ref_item, equals, map2table); ref_item->update_used_tables(); if (*ref_item_ptr != ref_item) { @@ -11446,7 +11449,7 @@ Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels, else { TABLE_LIST *emb_nest; - head= item_equal->get_first(NULL); + head= item_equal->get_first(NO_PARTICULAR_TAB, NULL); it++; if ((emb_nest= embedding_sjm(head))) { @@ -11555,6 +11558,7 @@ Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels, return cond; } + /** Substitute every field reference in a condition by the best equal field and eliminate all multiple equality predicates. @@ -11569,6 +11573,9 @@ Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels, After this the function retrieves all other conjuncted predicates substitute every field reference by the field reference to the first equal field or equal constant if there are any. + + @param context_tab Join tab that 'cond' will be attached to, or + NO_PARTICULAR_TAB. See notes above. @param cond condition to process @param cond_equal multiple equalities to take into consideration @param table_join_idx index to tables determining field preference @@ -11579,11 +11586,37 @@ Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels, new fields in multiple equality item of lower levels. We want the order in them to comply with the order of upper levels. + context_tab may be used to specify which join tab `cond` will be + attached to. There are two possible cases: + + 1. context_tab != NO_PARTICULAR_TAB + We're doing substitution for an Item which will be evaluated in the + context of a particular item. For example, if the optimizer does a + ref access on "tbl1.key= expr" then + = equality substitution will be perfomed on 'expr' + = it is known in advance that 'expr' will be evaluated when + table t1 is accessed. + Note that in this kind of substution we never have to replace Item_equal + objects. For example, for + + t.key= func(col1=col2 AND col2=const) + + we will not build Item_equal or do equality substution (if we decide to, + this function will need to be fixed to handle it) + + 2. context_tab == NO_PARTICULAR_TAB + We're doing substitution in WHERE/ON condition, which is not yet + attached to any particular join_tab. We will use information about the + chosen join order to make "optimal" substitions, i.e. those that allow + to apply filtering as soon as possible. See eliminate_item_equal() and + Item_equal::get_first() for details. + @return The transformed condition */ -static COND* substitute_for_best_equal_field(COND *cond, +static COND* substitute_for_best_equal_field(JOIN_TAB *context_tab, + COND *cond, COND_EQUAL *cond_equal, void *table_join_idx) { @@ -11612,7 +11645,8 @@ static COND* substitute_for_best_equal_field(COND *cond, Item *item; while ((item= li++)) { - Item *new_item= substitute_for_best_equal_field(item, cond_equal, + Item *new_item= substitute_for_best_equal_field(context_tab, + item, cond_equal, table_join_idx); /* This works OK with PS/SP re-execution as changes are made to @@ -11659,7 +11693,8 @@ static COND* substitute_for_best_equal_field(COND *cond, List_iterator_fast it(cond_equal->current_level); while((item_equal= it++)) { - cond= cond->transform(&Item::replace_equal_field, (uchar *) item_equal); + REPLACE_EQUAL_FIELD_ARG arg= {item_equal, context_tab}; + cond= cond->transform(&Item::replace_equal_field, (uchar *) &arg); } cond_equal= cond_equal->upper_levels; } From bb4053afc3cb30c6016530884061d520350004f1 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Fri, 20 Jan 2012 23:54:43 -0800 Subject: [PATCH 053/135] Fixed LP bug #919427. The function subselect_uniquesubquery_engine::copy_ref_key has to take into account that when EXPLAIN is processed the array of store_key object created for any TABLE_REF may contain elements for constant items. These items should be ignored by thefunction. --- mysql-test/r/subselect.result | 49 +++++++++++++++++++++++++++++++++++ mysql-test/t/subselect.test | 46 ++++++++++++++++++++++++++++++++ sql/item_subselect.cc | 2 ++ sql/sql_select.h | 2 ++ 4 files changed, 99 insertions(+) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 101869e2843..4e12294da79 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -5158,6 +5158,7 @@ DROP TABLE t1; # # BUG#12616253 - WRONG RESULT WITH EXISTS(SUBQUERY) (MISSING ROWS) # (duplicate of LP bug #888456) +# CREATE TABLE t1 (f1 varchar(1)); INSERT INTO t1 VALUES ('v'),('s'); CREATE TABLE t2 (f1_key varchar(1), KEY (f1_key)); @@ -5196,4 +5197,52 @@ s d v s s s DROP TABLE t1,t2; +# +# LP bug 919427: EXPLAIN for a query over a single-row table +# with IN subquery in WHERE condition +# +CREATE TABLE ot ( +col_int_nokey int(11), +col_varchar_nokey varchar(1) +) ; +INSERT INTO ot VALUES (1,'x'); +CREATE TABLE it1( +col_int_key int(11), +col_varchar_key varchar(1), +KEY idx_cvk_cik (col_varchar_key,col_int_key) +); +INSERT INTO it1 VALUES (NULL,'x'), (NULL,'f'); +CREATE TABLE it2 ( +col_int_key int(11), +col_varchar_key varchar(1), +col_varchar_key2 varchar(1), +KEY idx_cvk_cvk2_cik (col_varchar_key, col_varchar_key2, col_int_key), +KEY idx_cvk_cik (col_varchar_key, col_int_key) +); +INSERT INTO it2 VALUES (NULL,'x','x'), (NULL,'f','f'); +EXPLAIN +SELECT col_int_nokey FROM ot +WHERE col_varchar_nokey IN +(SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL); +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 it1 index_subquery idx_cvk_cik idx_cvk_cik 9 func,const 2 Using index; Using where +SELECT col_int_nokey FROM ot +WHERE col_varchar_nokey IN +(SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL); +col_int_nokey +1 +EXPLAIN +SELECT col_int_nokey FROM ot +WHERE (col_varchar_nokey, 'x') IN +(SELECT col_varchar_key, col_varchar_key2 FROM it2); +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 it2 index_subquery idx_cvk_cvk2_cik,idx_cvk_cik idx_cvk_cvk2_cik 8 func,const 1 Using index; Using where +SELECT col_int_nokey FROM ot +WHERE (col_varchar_nokey, 'x') IN +(SELECT col_varchar_key, col_varchar_key2 FROM it2); +col_int_nokey +1 +DROP TABLE ot,it1,it2; End of 5.2 tests diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 24aad3a145d..6bb9a9ae875 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -4025,6 +4025,7 @@ DROP TABLE t1; --echo # --echo # BUG#12616253 - WRONG RESULT WITH EXISTS(SUBQUERY) (MISSING ROWS) --echo # (duplicate of LP bug #888456) +--echo # CREATE TABLE t1 (f1 varchar(1)); INSERT INTO t1 VALUES ('v'),('s'); @@ -4043,4 +4044,49 @@ SELECT table1.f1, table2.f1_key FROM t1 AS table1, t2 AS table2 DROP TABLE t1,t2; +--echo # +--echo # LP bug 919427: EXPLAIN for a query over a single-row table +--echo # with IN subquery in WHERE condition +--echo # + +CREATE TABLE ot ( + col_int_nokey int(11), + col_varchar_nokey varchar(1) +) ; +INSERT INTO ot VALUES (1,'x'); + +CREATE TABLE it1( + col_int_key int(11), + col_varchar_key varchar(1), + KEY idx_cvk_cik (col_varchar_key,col_int_key) +); +INSERT INTO it1 VALUES (NULL,'x'), (NULL,'f'); + +CREATE TABLE it2 ( + col_int_key int(11), + col_varchar_key varchar(1), + col_varchar_key2 varchar(1), + KEY idx_cvk_cvk2_cik (col_varchar_key, col_varchar_key2, col_int_key), + KEY idx_cvk_cik (col_varchar_key, col_int_key) +); +INSERT INTO it2 VALUES (NULL,'x','x'), (NULL,'f','f'); + +EXPLAIN +SELECT col_int_nokey FROM ot + WHERE col_varchar_nokey IN + (SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL); +SELECT col_int_nokey FROM ot + WHERE col_varchar_nokey IN + (SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL); + +EXPLAIN +SELECT col_int_nokey FROM ot + WHERE (col_varchar_nokey, 'x') IN + (SELECT col_varchar_key, col_varchar_key2 FROM it2); +SELECT col_int_nokey FROM ot + WHERE (col_varchar_nokey, 'x') IN + (SELECT col_varchar_key, col_varchar_key2 FROM it2); + +DROP TABLE ot,it1,it2; + --echo End of 5.2 tests diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 2828ae8c4ec..3aa8dcd56f0 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -2171,6 +2171,8 @@ bool subselect_uniquesubquery_engine::copy_ref_key() for (store_key **copy= tab->ref.key_copy ; *copy ; copy++) { + if ((*copy)->store_key_is_const()) + continue; tab->ref.key_err= (*copy)->copy(); /* diff --git a/sql/sql_select.h b/sql/sql_select.h index 1d1a023d9cf..79c07e80b25 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -670,6 +670,7 @@ public: } virtual ~store_key() {} /** Not actually needed */ virtual const char *name() const=0; + virtual bool store_key_is_const() { return false; } /** @brief sets ignore truncation warnings mode and calls the real copy method @@ -784,6 +785,7 @@ public: { } const char *name() const { return "const"; } + bool store_key_is_const() { return true; } protected: enum store_key_result copy_inner() From 80009f586245e6d1a6e4435288a9ae8c93d1c847 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Sat, 21 Jan 2012 20:58:23 -0800 Subject: [PATCH 054/135] Back-ported test cases for bugs #53060, #53305, #50358, #49453 from subquery_sj of mysql-5.6 code line. The bugs could not be reproduced in the latest release of mariadb-5.3 as they were fixed either when the code of subquery optimization was back-ported from mysql-6.0 or later when some other bugs were fixed. --- mysql-test/r/join_cache.result | 97 +++++++++++++++++++++++++++ mysql-test/r/subselect_sj.result | 54 +++++++++++++++ mysql-test/r/subselect_sj_jcl6.result | 54 +++++++++++++++ mysql-test/t/join_cache.test | 82 ++++++++++++++++++++++ mysql-test/t/subselect_sj.test | 51 ++++++++++++++ 5 files changed, 338 insertions(+) diff --git a/mysql-test/r/join_cache.result b/mysql-test/r/join_cache.result index 362158cfdbe..db869ba434a 100644 --- a/mysql-test/r/join_cache.result +++ b/mysql-test/r/join_cache.result @@ -5389,4 +5389,101 @@ x 5 5 4 SET join_cache_level = DEFAULT; SET optimizer_switch=@tmp_optimizer_switch; DROP TABLE t1,t2,t3,t4; +# +# Bug#53305 Duplicate weedout + join buffer (join cache --level=7,8) +# +create table t1 (uid int, fid int, index(uid)); +insert into t1 values +(1,1), (1,2), (1,3), (1,4), +(2,5), (2,6), (2,7), (2,8), +(3,1), (3,2), (3,9); +create table t2 (uid int primary key, name varchar(128), index(name)); +insert into t2 values +(1, "A"), (2, "B"), (3, "C"), (4, "D"), (5, "E"), +(6, "F"), (7, "G"), (8, "H"), (9, "I"); +create table t3 (uid int, fid int, index(uid)); +insert into t3 values +(1,1), (1,2), (1,3),(1,4), +(2,5), (2,6), (2,7), (2,8), +(3,1), (3,2), (3,9); +set @tmp_optimizer_switch=@@optimizer_switch; +set @@optimizer_switch='semijoin=on'; +set optimizer_switch='materialization=off'; +set optimizer_switch='loosescan=off,firstmatch=off'; +set optimizer_switch='mrr_sort_keys=off'; +set join_cache_level=7; +create table t4 (uid int primary key, name varchar(128), index(name)); +insert into t4 values +(1, "A"), (2, "B"), (3, "C"), (4, "D"), (5, "E"), +(6, "F"), (7, "G"), (8, "H"), (9, "I"); +explain select name from t2, t1 +where t1.uid in (select t4.uid from t4, t3 where t3.uid=1 and t4.uid=t3.fid) +and t2.uid=t1.fid; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t3 ref uid uid 5 const 4 Using where; Start temporary +1 PRIMARY t4 eq_ref PRIMARY PRIMARY 4 test.t3.fid 1 Using index +1 PRIMARY t1 ALL uid NULL NULL NULL 11 Using where; End temporary; Using join buffer (flat, BNL join) +1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t1.fid 1 Using join buffer (flat, BKAH join); Rowid-ordered scan +select name from t2, t1 +where t1.uid in (select t4.uid from t4, t3 where t3.uid=1 and t4.uid=t3.fid) +and t2.uid=t1.fid; +name +A +A +B +B +C +D +E +F +G +H +I +set join_cache_level = default; +set optimizer_switch=@tmp_optimizer_switch; +drop table t1,t2,t3,t4; +# +# Bug#50358 - semijoin execution of subquery with outerjoin +# emplying join buffer +# +CREATE TABLE t1 (i int); +CREATE TABLE t2 (i int); +CREATE TABLE t3 (i int); +INSERT INTO t1 VALUES (1), (2); +INSERT INTO t2 VALUES (6); +INSERT INTO t3 VALUES (1), (2); +set @tmp_optimizer_switch=@@optimizer_switch; +set @@optimizer_switch='semijoin=on'; +set optimizer_switch='materialization=on'; +set join_cache_level=0; +EXPLAIN +SELECT * FROM t1 WHERE t1.i IN +(SELECT t3.i FROM t3 LEFT JOIN t2 ON t2.i=t3.i); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ALL distinct_key NULL NULL NULL 2 +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where +2 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 1 Using where +SELECT * FROM t1 WHERE t1.i IN +(SELECT t3.i FROM t3 LEFT JOIN t2 ON t2.i=t3.i); +i +1 +2 +set join_cache_level=2; +EXPLAIN +SELECT * FROM t1 WHERE t1.i IN +(SELECT t3.i FROM t3 LEFT JOIN t2 ON t2.i=t3.i); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ALL distinct_key NULL NULL NULL 2 +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) +2 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (flat, BNL join) +SELECT * FROM t1 WHERE t1.i IN +(SELECT t3.i FROM t3 LEFT JOIN t2 ON t2.i=t3.i); +i +1 +2 +set join_cache_level = default; +set optimizer_switch=@tmp_optimizer_switch; +DROP TABLE t1,t2,t3; set @@optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/r/subselect_sj.result b/mysql-test/r/subselect_sj.result index f5c3f84bcd7..33468198422 100644 --- a/mysql-test/r/subselect_sj.result +++ b/mysql-test/r/subselect_sj.result @@ -1231,6 +1231,60 @@ IN (SELECT t3.pk, t3.pk FROM t2 LEFT JOIN t3 ON t3.varchar_key) AND pk = 9; datetime_key DROP TABLE t1, t2, t3; +# +# BUG#53060: LooseScan semijoin strategy does not return all rows +# +set @save_optimizer_switch=@@optimizer_switch; +set optimizer_switch='semijoin=on,materialization=off'; +set optimizer_switch='firstmatch=off,loosescan=on'; +CREATE TABLE t1 (i INTEGER); +INSERT INTO t1 VALUES (1), (2), (3), (4), (5); +CREATE TABLE t2 (i INTEGER, j INTEGER, KEY k(i, j)); +INSERT INTO t2 VALUES (1, 0), (1, 1), (2, 0), (2, 1); +EXPLAIN +SELECT * FROM t1 WHERE (i) IN (SELECT i FROM t2 where j > 0); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 index k k 10 NULL 4 Using where; Using index; LooseScan +1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join) +SELECT * FROM t1 WHERE (i) IN (SELECT i FROM t2 where j > 0); +i +1 +2 +DROP TABLE t1, t2; +set optimizer_switch=@save_optimizer_switch; +# +# BUG#49453: re-execution of prepared statement with view +# and semijoin crashes +# +CREATE TABLE t1 (city VARCHAR(50), country_id INT); +CREATE TABLE t2 (country_id INT, country VARCHAR(50)); +INSERT INTO t1 VALUES +('Batna',2),('Bchar',2),('Skikda',2),('Tafuna',3),('Algeria',2) ; +INSERT INTO t2 VALUES (2,'Algeria'),(2,'AlgeriaDup'),(3,'XAmerican Samoa'); +CREATE VIEW v1 AS +SELECT country_id as vf_country_id +FROM t2 +WHERE LEFT(country,1) = "A"; +PREPARE stmt FROM " +SELECT city, country_id +FROM t1 +WHERE country_id IN (SELECT vf_country_id FROM v1); +"; + +EXECUTE stmt; +city country_id +Batna 2 +Bchar 2 +Skikda 2 +Algeria 2 +EXECUTE stmt; +city country_id +Batna 2 +Bchar 2 +Skikda 2 +Algeria 2 +DROP TABLE t1,t2; +DROP VIEW v1; # # BUG#784723: Wrong result with semijoin + nested subqueries in maria-5.3 # diff --git a/mysql-test/r/subselect_sj_jcl6.result b/mysql-test/r/subselect_sj_jcl6.result index faa4140d375..c344271ceae 100644 --- a/mysql-test/r/subselect_sj_jcl6.result +++ b/mysql-test/r/subselect_sj_jcl6.result @@ -1244,6 +1244,60 @@ IN (SELECT t3.pk, t3.pk FROM t2 LEFT JOIN t3 ON t3.varchar_key) AND pk = 9; datetime_key DROP TABLE t1, t2, t3; +# +# BUG#53060: LooseScan semijoin strategy does not return all rows +# +set @save_optimizer_switch=@@optimizer_switch; +set optimizer_switch='semijoin=on,materialization=off'; +set optimizer_switch='firstmatch=off,loosescan=on'; +CREATE TABLE t1 (i INTEGER); +INSERT INTO t1 VALUES (1), (2), (3), (4), (5); +CREATE TABLE t2 (i INTEGER, j INTEGER, KEY k(i, j)); +INSERT INTO t2 VALUES (1, 0), (1, 1), (2, 0), (2, 1); +EXPLAIN +SELECT * FROM t1 WHERE (i) IN (SELECT i FROM t2 where j > 0); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 index k k 10 NULL 4 Using where; Using index; LooseScan +1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join) +SELECT * FROM t1 WHERE (i) IN (SELECT i FROM t2 where j > 0); +i +1 +2 +DROP TABLE t1, t2; +set optimizer_switch=@save_optimizer_switch; +# +# BUG#49453: re-execution of prepared statement with view +# and semijoin crashes +# +CREATE TABLE t1 (city VARCHAR(50), country_id INT); +CREATE TABLE t2 (country_id INT, country VARCHAR(50)); +INSERT INTO t1 VALUES +('Batna',2),('Bchar',2),('Skikda',2),('Tafuna',3),('Algeria',2) ; +INSERT INTO t2 VALUES (2,'Algeria'),(2,'AlgeriaDup'),(3,'XAmerican Samoa'); +CREATE VIEW v1 AS +SELECT country_id as vf_country_id +FROM t2 +WHERE LEFT(country,1) = "A"; +PREPARE stmt FROM " +SELECT city, country_id +FROM t1 +WHERE country_id IN (SELECT vf_country_id FROM v1); +"; + +EXECUTE stmt; +city country_id +Batna 2 +Bchar 2 +Skikda 2 +Algeria 2 +EXECUTE stmt; +city country_id +Batna 2 +Bchar 2 +Skikda 2 +Algeria 2 +DROP TABLE t1,t2; +DROP VIEW v1; # # BUG#784723: Wrong result with semijoin + nested subqueries in maria-5.3 # diff --git a/mysql-test/t/join_cache.test b/mysql-test/t/join_cache.test index e39dcb72916..cc1941e16b9 100644 --- a/mysql-test/t/join_cache.test +++ b/mysql-test/t/join_cache.test @@ -3423,5 +3423,87 @@ SET optimizer_switch=@tmp_optimizer_switch; DROP TABLE t1,t2,t3,t4; +--echo # +--echo # Bug#53305 Duplicate weedout + join buffer (join cache --level=7,8) +--echo # + +create table t1 (uid int, fid int, index(uid)); +insert into t1 values + (1,1), (1,2), (1,3), (1,4), + (2,5), (2,6), (2,7), (2,8), + (3,1), (3,2), (3,9); + +create table t2 (uid int primary key, name varchar(128), index(name)); +insert into t2 values + (1, "A"), (2, "B"), (3, "C"), (4, "D"), (5, "E"), + (6, "F"), (7, "G"), (8, "H"), (9, "I"); + +create table t3 (uid int, fid int, index(uid)); +insert into t3 values + (1,1), (1,2), (1,3),(1,4), + (2,5), (2,6), (2,7), (2,8), + (3,1), (3,2), (3,9); + +set @tmp_optimizer_switch=@@optimizer_switch; +set @@optimizer_switch='semijoin=on'; +set optimizer_switch='materialization=off'; +set optimizer_switch='loosescan=off,firstmatch=off'; +set optimizer_switch='mrr_sort_keys=off'; +set join_cache_level=7; + +create table t4 (uid int primary key, name varchar(128), index(name)); +insert into t4 values + (1, "A"), (2, "B"), (3, "C"), (4, "D"), (5, "E"), + (6, "F"), (7, "G"), (8, "H"), (9, "I"); + +explain select name from t2, t1 + where t1.uid in (select t4.uid from t4, t3 where t3.uid=1 and t4.uid=t3.fid) + and t2.uid=t1.fid; + +--sorted_result +select name from t2, t1 + where t1.uid in (select t4.uid from t4, t3 where t3.uid=1 and t4.uid=t3.fid) + and t2.uid=t1.fid; + +set join_cache_level = default; +set optimizer_switch=@tmp_optimizer_switch; + +drop table t1,t2,t3,t4; + +--echo # +--echo # Bug#50358 - semijoin execution of subquery with outerjoin +--echo # emplying join buffer +--echo # + +CREATE TABLE t1 (i int); +CREATE TABLE t2 (i int); +CREATE TABLE t3 (i int); +INSERT INTO t1 VALUES (1), (2); +INSERT INTO t2 VALUES (6); +INSERT INTO t3 VALUES (1), (2); + +set @tmp_optimizer_switch=@@optimizer_switch; +set @@optimizer_switch='semijoin=on'; +set optimizer_switch='materialization=on'; + +set join_cache_level=0; +EXPLAIN +SELECT * FROM t1 WHERE t1.i IN + (SELECT t3.i FROM t3 LEFT JOIN t2 ON t2.i=t3.i); +SELECT * FROM t1 WHERE t1.i IN + (SELECT t3.i FROM t3 LEFT JOIN t2 ON t2.i=t3.i); + +set join_cache_level=2; +EXPLAIN +SELECT * FROM t1 WHERE t1.i IN + (SELECT t3.i FROM t3 LEFT JOIN t2 ON t2.i=t3.i); +SELECT * FROM t1 WHERE t1.i IN + (SELECT t3.i FROM t3 LEFT JOIN t2 ON t2.i=t3.i); + +set join_cache_level = default; +set optimizer_switch=@tmp_optimizer_switch; + +DROP TABLE t1,t2,t3; + # this must be the last command in the file set @@optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/t/subselect_sj.test b/mysql-test/t/subselect_sj.test index f34cf5ba338..64e7bc3236e 100644 --- a/mysql-test/t/subselect_sj.test +++ b/mysql-test/t/subselect_sj.test @@ -1136,6 +1136,57 @@ WHERE (int_nokey, pk) DROP TABLE t1, t2, t3; +--echo # +--echo # BUG#53060: LooseScan semijoin strategy does not return all rows +--echo # + +set @save_optimizer_switch=@@optimizer_switch; +set optimizer_switch='semijoin=on,materialization=off'; +set optimizer_switch='firstmatch=off,loosescan=on'; + +CREATE TABLE t1 (i INTEGER); +INSERT INTO t1 VALUES (1), (2), (3), (4), (5); +CREATE TABLE t2 (i INTEGER, j INTEGER, KEY k(i, j)); +INSERT INTO t2 VALUES (1, 0), (1, 1), (2, 0), (2, 1); + +EXPLAIN +SELECT * FROM t1 WHERE (i) IN (SELECT i FROM t2 where j > 0); +SELECT * FROM t1 WHERE (i) IN (SELECT i FROM t2 where j > 0); + +DROP TABLE t1, t2; + +set optimizer_switch=@save_optimizer_switch; + +--echo # +--echo # BUG#49453: re-execution of prepared statement with view +--echo # and semijoin crashes +--echo # + +CREATE TABLE t1 (city VARCHAR(50), country_id INT); +CREATE TABLE t2 (country_id INT, country VARCHAR(50)); + +INSERT INTO t1 VALUES + ('Batna',2),('Bchar',2),('Skikda',2),('Tafuna',3),('Algeria',2) ; +INSERT INTO t2 VALUES (2,'Algeria'),(2,'AlgeriaDup'),(3,'XAmerican Samoa'); + +CREATE VIEW v1 AS + SELECT country_id as vf_country_id + FROM t2 + WHERE LEFT(country,1) = "A"; + +PREPARE stmt FROM " +SELECT city, country_id +FROM t1 +WHERE country_id IN (SELECT vf_country_id FROM v1); +"; + +--echo +EXECUTE stmt; +EXECUTE stmt; + +DROP TABLE t1,t2; +DROP VIEW v1; + --echo # --echo # BUG#784723: Wrong result with semijoin + nested subqueries in maria-5.3 --echo # From 7bdbdb05cebaf722e44b415631717ed78933e906 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Sun, 22 Jan 2012 12:54:30 -0800 Subject: [PATCH 055/135] Back-ported test cases for bugs #54437, #55955, #52329, #57623 from subquery_sj of mysql-5.6 code line. The bugs could not be reproduced in the latest release of mariadb-5.3 as they were fixed either when the code of subquery optimization was back-ported from mysql-6.0 or later when some other bugs were fixed. --- mysql-test/r/subselect_sj.result | 252 ++++++++++++++++++++++++++ mysql-test/r/subselect_sj_jcl6.result | 252 ++++++++++++++++++++++++++ mysql-test/t/subselect_sj.test | 166 +++++++++++++++++ 3 files changed, 670 insertions(+) diff --git a/mysql-test/r/subselect_sj.result b/mysql-test/r/subselect_sj.result index 33468198422..0c9c2eb3af5 100644 --- a/mysql-test/r/subselect_sj.result +++ b/mysql-test/r/subselect_sj.result @@ -1286,6 +1286,258 @@ Algeria 2 DROP TABLE t1,t2; DROP VIEW v1; # +# Bug#54437 Extra rows with LEFT JOIN + semijoin +# +create table t1 (a int); +create table t2 (a int); +create table t3 (a int); +insert into t1 values(1),(1); +insert into t2 values(1),(1),(1),(1); +insert into t3 values(2),(2); +set @save_optimizer_switch=@@optimizer_switch; +set optimizer_switch='materialization=off'; +set optimizer_switch='semijoin=off'; +explain +select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 4 Using where +2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where +select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.a); +a +1 +1 +set optimizer_switch='semijoin=on'; +explain +select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 +1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where; Start temporary +1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; End temporary +select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.a); +a +1 +1 +set optimizer_switch=@save_optimizer_switch; +drop table t1,t2,t3; +# +# Bug#55955: crash in MEMORY engine with IN(LEFT JOIN (JOIN)) +# +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a INT); +CREATE TABLE t3 (a INT); +INSERT INTO t1 VALUES(1),(1); +INSERT INTO t2 VALUES(1),(1); +INSERT INTO t3 VALUES(2),(2); +set @save_optimizer_switch=@@optimizer_switch; +set optimizer_switch='semijoin=off,materialization=off'; +EXPLAIN +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a +FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY t2inner ALL NULL NULL NULL NULL 2 +2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a +FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); +a +1 +1 +set optimizer_switch='semijoin=off,materialization=on'; +EXPLAIN +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a +FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 +2 MATERIALIZED t2inner ALL NULL NULL NULL NULL 2 +2 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 Using where +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a +FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); +a +1 +1 +set optimizer_switch='semijoin=on,materialization=off'; +EXPLAIN +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a +FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Start temporary +1 PRIMARY t2inner ALL NULL NULL NULL NULL 2 +1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; End temporary +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a +FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); +a +1 +1 +set optimizer_switch=@save_optimizer_switch; +DROP TABLE t1,t2,t3; +# +# BUG#52329 - Wrong result: subquery materialization, IN, +# non-null field followed by nullable +# +CREATE TABLE t1 (a1 CHAR(8) NOT NULL, a2 char(8) NOT NULL); +CREATE TABLE t2a (b1 char(8), b2 char(8)); +CREATE TABLE t2b (b1 CHAR(8), b2 char(8) NOT NULL); +CREATE TABLE t2c (b1 CHAR(8) NOT NULL, b2 char(8)); +INSERT INTO t1 VALUES ('1 - 12', '2 - 22'); +INSERT INTO t2a VALUES ('1 - 11', '2 - 21'), +('1 - 11', '2 - 21'), +('1 - 12', '2 - 22'), +('1 - 12', '2 - 22'), +('1 - 13', '2 - 23'); +INSERT INTO t2b SELECT * FROM t2a; +INSERT INTO t2c SELECT * FROM t2a; +set @save_optimizer_switch=@@optimizer_switch; +set optimizer_switch='semijoin=off,materialization=on'; +SELECT * FROM t1 +WHERE (a1, a2) IN ( +SELECT b1, b2 FROM t2c WHERE b1 > '0' GROUP BY b1, b2); +a1 a2 +1 - 12 2 - 22 +SELECT * FROM t1 +WHERE (a1, a2) IN ( +SELECT b1, b2 FROM t2a WHERE b1 > '0'); +a1 a2 +1 - 12 2 - 22 +SELECT * FROM t1 +WHERE (a1, a2) IN ( +SELECT b1, b2 FROM t2b WHERE b1 > '0'); +a1 a2 +1 - 12 2 - 22 +SELECT * FROM t1 +WHERE (a1, a2) IN ( +SELECT b1, b2 FROM t2c WHERE b1 > '0'); +a1 a2 +1 - 12 2 - 22 +set optimizer_switch=@save_optimizer_switch; +DROP TABLE t1,t2a,t2b,t2c; +# +# Bug#57623: subquery within before insert trigger causes crash (sj=on) +# +CREATE TABLE ot1(a INT); +CREATE TABLE ot2(a INT); +CREATE TABLE ot3(a INT); +CREATE TABLE it1(a INT); +INSERT INTO ot1 VALUES(0),(1),(2),(3),(4),(5),(6),(7); +INSERT INTO ot2 VALUES(0),(2),(4),(6); +INSERT INTO ot3 VALUES(0),(3),(6); +INSERT INTO it1 VALUES(0),(1),(2),(3),(4),(5),(6),(7); +set @save_optimizer_switch=@@optimizer_switch; +set optimizer_switch='semijoin=on'; +set optimizer_switch='materialization=off'; +explain SELECT * +FROM ot1 +LEFT JOIN +(ot2 JOIN ot3 on ot2.a=ot3.a) +ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ot1 ALL NULL NULL NULL NULL 8 +1 PRIMARY ot3 ALL NULL NULL NULL NULL 3 Using where +1 PRIMARY ot2 ALL NULL NULL NULL NULL 4 Using where +2 DEPENDENT SUBQUERY it1 ALL NULL NULL NULL NULL 8 Using where +SELECT * +FROM ot1 +LEFT JOIN +(ot2 JOIN ot3 on ot2.a=ot3.a) +ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1); +a a a +0 0 0 +1 NULL NULL +2 NULL NULL +3 NULL NULL +4 NULL NULL +5 NULL NULL +6 6 6 +7 NULL NULL +prepare s from 'SELECT * +FROM ot1 +LEFT JOIN +(ot2 JOIN ot3 on ot2.a=ot3.a) +ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1)'; +execute s; +a a a +0 0 0 +1 NULL NULL +2 NULL NULL +3 NULL NULL +4 NULL NULL +5 NULL NULL +6 6 6 +7 NULL NULL +execute s; +a a a +0 0 0 +1 NULL NULL +2 NULL NULL +3 NULL NULL +4 NULL NULL +5 NULL NULL +6 6 6 +7 NULL NULL +deallocate prepare s; +set optimizer_switch='materialization=on'; +explain SELECT * +FROM ot1 +LEFT JOIN +(ot2 JOIN ot3 on ot2.a=ot3.a) +ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ot1 ALL NULL NULL NULL NULL 8 +1 PRIMARY ot3 ALL NULL NULL NULL NULL 3 Using where +1 PRIMARY ot2 ALL NULL NULL NULL NULL 4 Using where +2 MATERIALIZED it1 ALL NULL NULL NULL NULL 8 +SELECT * +FROM ot1 +LEFT JOIN +(ot2 JOIN ot3 on ot2.a=ot3.a) +ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1); +a a a +0 0 0 +1 NULL NULL +2 NULL NULL +3 NULL NULL +4 NULL NULL +5 NULL NULL +6 6 6 +7 NULL NULL +prepare s from 'SELECT * +FROM ot1 +LEFT JOIN +(ot2 JOIN ot3 on ot2.a=ot3.a) +ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1)'; +execute s; +a a a +0 0 0 +1 NULL NULL +2 NULL NULL +3 NULL NULL +4 NULL NULL +5 NULL NULL +6 6 6 +7 NULL NULL +execute s; +a a a +0 0 0 +1 NULL NULL +2 NULL NULL +3 NULL NULL +4 NULL NULL +5 NULL NULL +6 6 6 +7 NULL NULL +deallocate prepare s; +set optimizer_switch=@save_optimizer_switch; +DROP TABLE ot1, ot2, ot3, it1; +# # BUG#784723: Wrong result with semijoin + nested subqueries in maria-5.3 # CREATE TABLE t1 ( t1field integer, primary key (t1field)); diff --git a/mysql-test/r/subselect_sj_jcl6.result b/mysql-test/r/subselect_sj_jcl6.result index c344271ceae..a8bc0d120cd 100644 --- a/mysql-test/r/subselect_sj_jcl6.result +++ b/mysql-test/r/subselect_sj_jcl6.result @@ -1299,6 +1299,258 @@ Algeria 2 DROP TABLE t1,t2; DROP VIEW v1; # +# Bug#54437 Extra rows with LEFT JOIN + semijoin +# +create table t1 (a int); +create table t2 (a int); +create table t3 (a int); +insert into t1 values(1),(1); +insert into t2 values(1),(1),(1),(1); +insert into t3 values(2),(2); +set @save_optimizer_switch=@@optimizer_switch; +set optimizer_switch='materialization=off'; +set optimizer_switch='semijoin=off'; +explain +select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 4 Using where +2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) +select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.a); +a +1 +1 +set optimizer_switch='semijoin=on'; +explain +select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 +1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where; Start temporary; Using join buffer (flat, BNL join) +1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (incremental, BNL join) +select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.a); +a +1 +1 +set optimizer_switch=@save_optimizer_switch; +drop table t1,t2,t3; +# +# Bug#55955: crash in MEMORY engine with IN(LEFT JOIN (JOIN)) +# +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a INT); +CREATE TABLE t3 (a INT); +INSERT INTO t1 VALUES(1),(1); +INSERT INTO t2 VALUES(1),(1); +INSERT INTO t3 VALUES(2),(2); +set @save_optimizer_switch=@@optimizer_switch; +set optimizer_switch='semijoin=off,materialization=off'; +EXPLAIN +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a +FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY t2inner ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join) +2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join) +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a +FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); +a +1 +1 +set optimizer_switch='semijoin=off,materialization=on'; +EXPLAIN +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a +FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 +2 MATERIALIZED t2inner ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join) +2 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join) +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a +FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); +a +1 +1 +set optimizer_switch='semijoin=on,materialization=off'; +EXPLAIN +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a +FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Start temporary; Using join buffer (flat, BNL join) +1 PRIMARY t2inner ALL NULL NULL NULL NULL 2 Using join buffer (incremental, BNL join) +1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (incremental, BNL join) +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a +FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); +a +1 +1 +set optimizer_switch=@save_optimizer_switch; +DROP TABLE t1,t2,t3; +# +# BUG#52329 - Wrong result: subquery materialization, IN, +# non-null field followed by nullable +# +CREATE TABLE t1 (a1 CHAR(8) NOT NULL, a2 char(8) NOT NULL); +CREATE TABLE t2a (b1 char(8), b2 char(8)); +CREATE TABLE t2b (b1 CHAR(8), b2 char(8) NOT NULL); +CREATE TABLE t2c (b1 CHAR(8) NOT NULL, b2 char(8)); +INSERT INTO t1 VALUES ('1 - 12', '2 - 22'); +INSERT INTO t2a VALUES ('1 - 11', '2 - 21'), +('1 - 11', '2 - 21'), +('1 - 12', '2 - 22'), +('1 - 12', '2 - 22'), +('1 - 13', '2 - 23'); +INSERT INTO t2b SELECT * FROM t2a; +INSERT INTO t2c SELECT * FROM t2a; +set @save_optimizer_switch=@@optimizer_switch; +set optimizer_switch='semijoin=off,materialization=on'; +SELECT * FROM t1 +WHERE (a1, a2) IN ( +SELECT b1, b2 FROM t2c WHERE b1 > '0' GROUP BY b1, b2); +a1 a2 +1 - 12 2 - 22 +SELECT * FROM t1 +WHERE (a1, a2) IN ( +SELECT b1, b2 FROM t2a WHERE b1 > '0'); +a1 a2 +1 - 12 2 - 22 +SELECT * FROM t1 +WHERE (a1, a2) IN ( +SELECT b1, b2 FROM t2b WHERE b1 > '0'); +a1 a2 +1 - 12 2 - 22 +SELECT * FROM t1 +WHERE (a1, a2) IN ( +SELECT b1, b2 FROM t2c WHERE b1 > '0'); +a1 a2 +1 - 12 2 - 22 +set optimizer_switch=@save_optimizer_switch; +DROP TABLE t1,t2a,t2b,t2c; +# +# Bug#57623: subquery within before insert trigger causes crash (sj=on) +# +CREATE TABLE ot1(a INT); +CREATE TABLE ot2(a INT); +CREATE TABLE ot3(a INT); +CREATE TABLE it1(a INT); +INSERT INTO ot1 VALUES(0),(1),(2),(3),(4),(5),(6),(7); +INSERT INTO ot2 VALUES(0),(2),(4),(6); +INSERT INTO ot3 VALUES(0),(3),(6); +INSERT INTO it1 VALUES(0),(1),(2),(3),(4),(5),(6),(7); +set @save_optimizer_switch=@@optimizer_switch; +set optimizer_switch='semijoin=on'; +set optimizer_switch='materialization=off'; +explain SELECT * +FROM ot1 +LEFT JOIN +(ot2 JOIN ot3 on ot2.a=ot3.a) +ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ot1 ALL NULL NULL NULL NULL 8 +1 PRIMARY ot3 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join) +1 PRIMARY ot2 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (incremental, BNL join) +2 DEPENDENT SUBQUERY it1 ALL NULL NULL NULL NULL 8 Using where +SELECT * +FROM ot1 +LEFT JOIN +(ot2 JOIN ot3 on ot2.a=ot3.a) +ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1); +a a a +0 0 0 +6 6 6 +1 NULL NULL +2 NULL NULL +3 NULL NULL +4 NULL NULL +5 NULL NULL +7 NULL NULL +prepare s from 'SELECT * +FROM ot1 +LEFT JOIN +(ot2 JOIN ot3 on ot2.a=ot3.a) +ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1)'; +execute s; +a a a +0 0 0 +6 6 6 +1 NULL NULL +2 NULL NULL +3 NULL NULL +4 NULL NULL +5 NULL NULL +7 NULL NULL +execute s; +a a a +0 0 0 +6 6 6 +1 NULL NULL +2 NULL NULL +3 NULL NULL +4 NULL NULL +5 NULL NULL +7 NULL NULL +deallocate prepare s; +set optimizer_switch='materialization=on'; +explain SELECT * +FROM ot1 +LEFT JOIN +(ot2 JOIN ot3 on ot2.a=ot3.a) +ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ot1 ALL NULL NULL NULL NULL 8 +1 PRIMARY ot3 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join) +1 PRIMARY ot2 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (incremental, BNL join) +2 MATERIALIZED it1 ALL NULL NULL NULL NULL 8 +SELECT * +FROM ot1 +LEFT JOIN +(ot2 JOIN ot3 on ot2.a=ot3.a) +ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1); +a a a +0 0 0 +6 6 6 +1 NULL NULL +2 NULL NULL +3 NULL NULL +4 NULL NULL +5 NULL NULL +7 NULL NULL +prepare s from 'SELECT * +FROM ot1 +LEFT JOIN +(ot2 JOIN ot3 on ot2.a=ot3.a) +ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1)'; +execute s; +a a a +0 0 0 +6 6 6 +1 NULL NULL +2 NULL NULL +3 NULL NULL +4 NULL NULL +5 NULL NULL +7 NULL NULL +execute s; +a a a +0 0 0 +6 6 6 +1 NULL NULL +2 NULL NULL +3 NULL NULL +4 NULL NULL +5 NULL NULL +7 NULL NULL +deallocate prepare s; +set optimizer_switch=@save_optimizer_switch; +DROP TABLE ot1, ot2, ot3, it1; +# # BUG#784723: Wrong result with semijoin + nested subqueries in maria-5.3 # CREATE TABLE t1 ( t1field integer, primary key (t1field)); diff --git a/mysql-test/t/subselect_sj.test b/mysql-test/t/subselect_sj.test index 64e7bc3236e..62d2fd61721 100644 --- a/mysql-test/t/subselect_sj.test +++ b/mysql-test/t/subselect_sj.test @@ -1187,6 +1187,172 @@ EXECUTE stmt; DROP TABLE t1,t2; DROP VIEW v1; +--echo # +--echo # Bug#54437 Extra rows with LEFT JOIN + semijoin +--echo # + +create table t1 (a int); +create table t2 (a int); +create table t3 (a int); +insert into t1 values(1),(1); +insert into t2 values(1),(1),(1),(1); +insert into t3 values(2),(2); + +set @save_optimizer_switch=@@optimizer_switch; + +set optimizer_switch='materialization=off'; + +set optimizer_switch='semijoin=off'; +explain +select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.a); +select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.a); + +set optimizer_switch='semijoin=on'; +explain +select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.a); +select * from t1 where t1.a in (select t2.a from t2 left join t3 on t2.a=t3.a); + +set optimizer_switch=@save_optimizer_switch; + +drop table t1,t2,t3; + +--echo # +--echo # Bug#55955: crash in MEMORY engine with IN(LEFT JOIN (JOIN)) +--echo # + +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a INT); +CREATE TABLE t3 (a INT); +INSERT INTO t1 VALUES(1),(1); +INSERT INTO t2 VALUES(1),(1); +INSERT INTO t3 VALUES(2),(2); + +set @save_optimizer_switch=@@optimizer_switch; + +set optimizer_switch='semijoin=off,materialization=off'; +EXPLAIN +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a + FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a + FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); + +set optimizer_switch='semijoin=off,materialization=on'; +EXPLAIN +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a + FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a + FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); + +set optimizer_switch='semijoin=on,materialization=off'; +EXPLAIN +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a + FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); +SELECT * FROM t1 +WHERE t1.a IN (SELECT t2.a + FROM t2 LEFT JOIN (t2 AS t2inner, t3) ON t2.a=t3.a); + +set optimizer_switch=@save_optimizer_switch; + +DROP TABLE t1,t2,t3; + +--echo # +--echo # BUG#52329 - Wrong result: subquery materialization, IN, +--echo # non-null field followed by nullable +--echo # + +CREATE TABLE t1 (a1 CHAR(8) NOT NULL, a2 char(8) NOT NULL); + +CREATE TABLE t2a (b1 char(8), b2 char(8)); +CREATE TABLE t2b (b1 CHAR(8), b2 char(8) NOT NULL); +CREATE TABLE t2c (b1 CHAR(8) NOT NULL, b2 char(8)); + +INSERT INTO t1 VALUES ('1 - 12', '2 - 22'); + +INSERT INTO t2a VALUES ('1 - 11', '2 - 21'), + ('1 - 11', '2 - 21'), + ('1 - 12', '2 - 22'), + ('1 - 12', '2 - 22'), + ('1 - 13', '2 - 23'); + +INSERT INTO t2b SELECT * FROM t2a; +INSERT INTO t2c SELECT * FROM t2a; + +set @save_optimizer_switch=@@optimizer_switch; + +set optimizer_switch='semijoin=off,materialization=on'; + +SELECT * FROM t1 +WHERE (a1, a2) IN ( + SELECT b1, b2 FROM t2c WHERE b1 > '0' GROUP BY b1, b2); + +SELECT * FROM t1 +WHERE (a1, a2) IN ( + SELECT b1, b2 FROM t2a WHERE b1 > '0'); + + +SELECT * FROM t1 +WHERE (a1, a2) IN ( + SELECT b1, b2 FROM t2b WHERE b1 > '0'); + + +SELECT * FROM t1 +WHERE (a1, a2) IN ( + SELECT b1, b2 FROM t2c WHERE b1 > '0'); + +set optimizer_switch=@save_optimizer_switch; + +DROP TABLE t1,t2a,t2b,t2c; + +--echo # +--echo # Bug#57623: subquery within before insert trigger causes crash (sj=on) +--echo # + +CREATE TABLE ot1(a INT); +CREATE TABLE ot2(a INT); +CREATE TABLE ot3(a INT); +CREATE TABLE it1(a INT); + +INSERT INTO ot1 VALUES(0),(1),(2),(3),(4),(5),(6),(7); +INSERT INTO ot2 VALUES(0),(2),(4),(6); +INSERT INTO ot3 VALUES(0),(3),(6); +INSERT INTO it1 VALUES(0),(1),(2),(3),(4),(5),(6),(7); + +let $query= +SELECT * +FROM ot1 + LEFT JOIN + (ot2 JOIN ot3 on ot2.a=ot3.a) + ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1); + +set @save_optimizer_switch=@@optimizer_switch; + +set optimizer_switch='semijoin=on'; + +set optimizer_switch='materialization=off'; +eval explain $query; +eval $query; +eval prepare s from '$query'; +execute s; +execute s; +deallocate prepare s; + +set optimizer_switch='materialization=on'; +eval explain $query; +eval $query; +eval prepare s from '$query'; +execute s; +execute s; +deallocate prepare s; + +set optimizer_switch=@save_optimizer_switch; + +DROP TABLE ot1, ot2, ot3, it1; + --echo # --echo # BUG#784723: Wrong result with semijoin + nested subqueries in maria-5.3 --echo # From 81690cf326e09799ca77d9f7bc5601905b706548 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 23 Jan 2012 11:43:28 +0100 Subject: [PATCH 056/135] MDEV-106 my_gethwaddr() does not compile on Solaris 11 --- mysys/my_gethwaddr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mysys/my_gethwaddr.c b/mysys/my_gethwaddr.c index c96af3f1018..c4ab39dbcf1 100644 --- a/mysys/my_gethwaddr.c +++ b/mysys/my_gethwaddr.c @@ -101,14 +101,14 @@ my_bool my_gethwaddr(uchar *to) uint i; for (i= 0; res && i < ifc.ifc_len / sizeof(ifr[0]); i++) { -#ifdef SIOCGIFHWADDR +#ifdef __linux__ if (ioctl(fd, SIOCGIFHWADDR, &ifr[i]) >= 0) res= memcpy_and_test(to, (uchar *)&ifr[i].ifr_hwaddr.sa_data, ETHER_ADDR_LEN); #else /* - A bug in OpenSolaris prevents non-root from getting a mac address: - http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=4720634 + A bug in OpenSolaris used to prevent non-root from getting a mac address: + {no url. Oracle killed the old OpenSolaris bug database} Thus, we'll use an alternative method and extract the address from the arp table. From 5db8b5113b26e4c2c7960ab4d6240fd56ffa3432 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 23 Jan 2012 15:14:13 +0200 Subject: [PATCH 057/135] Fixed creating limit for exists subquery. --- sql/item_subselect.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index ed556f05466..d66dbd12436 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1259,7 +1259,8 @@ void Item_exists_subselect::fix_length_and_dec() We need only 1 row to determine existence (i.e. any EXISTS that is not an IN always requires LIMIT 1) */ - unit->global_parameters->select_limit= new Item_int((int32) 1); + thd->change_item_tree(&unit->global_parameters->select_limit, + new Item_int((int32) 1)); DBUG_PRINT("info", ("Set limit to 1")); DBUG_VOID_RETURN; } From 2ae3fca46536245fd2d7f33f317a9fb3a3097620 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Mon, 23 Jan 2012 23:35:52 +0400 Subject: [PATCH 058/135] Add MRR counters: Handler_mrr_init, Handler_mrr_extra_rowid_sorts, Handler_mrr_extra_key_sorts. --- mysql-test/r/myisam_mrr.result | 77 ++++++++++++++++++++++++++++++++++ mysql-test/t/myisam_mrr.test | 52 +++++++++++++++++++++++ sql/multi_range_read.cc | 23 +++++++++- sql/mysqld.cc | 3 ++ sql/sql_class.h | 2 + 5 files changed, 155 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/myisam_mrr.result b/mysql-test/r/myisam_mrr.result index 4e1e4f01c07..0eeb22d829a 100644 --- a/mysql-test/r/myisam_mrr.result +++ b/mysql-test/r/myisam_mrr.result @@ -557,4 +557,81 @@ COUNT(alias2.f2) set @@join_cache_level= @tmp_730133_jcl; set @@optimizer_switch= @tmp_730133_os; drop table t1; +# +# Test of MRR handler counters +# +flush status; +show status like 'Handler_mrr%'; +Variable_name Value +Handler_mrr_extra_key_sorts 0 +Handler_mrr_extra_rowid_sorts 0 +Handler_mrr_init 0 +create table t0 (a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t1 (a int, b int, filler char(200), key(a)); +insert into t1 +select A.a+10*B.a+100*C.a+1000*D.a, 123,'filler' from t0 A, t0 B, t0 C, t0 D; +explain select sum(b) from t1 where a < 10; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a a 5 NULL 8 Using index condition; Rowid-ordered scan +# This should show one MRR scan and no re-fills: +flush status; +select sum(b) from t1 where a < 10; +sum(b) +1230 +show status like 'handler_mrr%'; +Variable_name Value +Handler_mrr_extra_key_sorts 0 +Handler_mrr_extra_rowid_sorts 0 +Handler_mrr_init 1 +set @mrr_buffer_size_save= @@mrr_buffer_size; +set mrr_buffer_size=128; +explain select sum(b) from t1 where a < 1600; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a a 5 NULL 1380 Using index condition; Rowid-ordered scan +# This should show one MRR scan and one extra rowid sort: +flush status; +select sum(b) from t1 where a < 1600; +sum(b) +196800 +show status like 'handler_mrr%'; +Variable_name Value +Handler_mrr_extra_key_sorts 0 +Handler_mrr_extra_rowid_sorts 1 +Handler_mrr_init 1 +set @@mrr_buffer_size= @mrr_buffer_size_save; +#Now, let's check BKA: +set @join_cache_level_save= @@join_cache_level; +set @join_buffer_size_save= @@join_buffer_size; +set join_cache_level=6; +explain select sum(t1.b) from t0,t1 where t0.a=t1.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t0 ALL NULL NULL NULL NULL 10 Using where +1 SIMPLE t1 ref a a 5 test.t0.a 1 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +flush status; +select sum(t1.b) from t0,t1 where t0.a=t1.a; +sum(t1.b) +1230 +show status like 'handler_mrr%'; +Variable_name Value +Handler_mrr_extra_key_sorts 0 +Handler_mrr_extra_rowid_sorts 0 +Handler_mrr_init 1 +set join_buffer_size=10; +explain select sum(t1.b) from t0,t1 where t0.a=t1.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t0 ALL NULL NULL NULL NULL 10 Using where +1 SIMPLE t1 ref a a 5 test.t0.a 1 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +flush status; +select sum(t1.b) from t0,t1 where t0.a=t1.a; +sum(t1.b) +1230 +show status like 'handler_mrr%'; +Variable_name Value +Handler_mrr_extra_key_sorts 1 +Handler_mrr_extra_rowid_sorts 1 +Handler_mrr_init 2 +set join_cache_level= @join_cache_level_save; +set join_buffer_size= @join_buffer_size_save; +drop table t0, t1; set optimizer_switch= @myisam_mrr_tmp; diff --git a/mysql-test/t/myisam_mrr.test b/mysql-test/t/myisam_mrr.test index 1e070ec9a34..0f916299ae7 100644 --- a/mysql-test/t/myisam_mrr.test +++ b/mysql-test/t/myisam_mrr.test @@ -268,5 +268,57 @@ set @@join_cache_level= @tmp_730133_jcl; set @@optimizer_switch= @tmp_730133_os; drop table t1; +--echo # +--echo # Test of MRR handler counters +--echo # +flush status; +show status like 'Handler_mrr%'; +create table t0 (a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t1 (a int, b int, filler char(200), key(a)); +insert into t1 +select A.a+10*B.a+100*C.a+1000*D.a, 123,'filler' from t0 A, t0 B, t0 C, t0 D; + +explain select sum(b) from t1 where a < 10; +--echo # This should show one MRR scan and no re-fills: +flush status; +select sum(b) from t1 where a < 10; +show status like 'handler_mrr%'; + +set @mrr_buffer_size_save= @@mrr_buffer_size; +--disable_warnings +set mrr_buffer_size=128; +--enable_warnings + +explain select sum(b) from t1 where a < 1600; +--echo # This should show one MRR scan and one extra rowid sort: +flush status; +select sum(b) from t1 where a < 1600; +show status like 'handler_mrr%'; +set @@mrr_buffer_size= @mrr_buffer_size_save; + +--echo #Now, let's check BKA: +set @join_cache_level_save= @@join_cache_level; +set @join_buffer_size_save= @@join_buffer_size; +set join_cache_level=6; + +explain select sum(t1.b) from t0,t1 where t0.a=t1.a; +flush status; +select sum(t1.b) from t0,t1 where t0.a=t1.a; +show status like 'handler_mrr%'; + +--disable_warnings +set join_buffer_size=10; +--enable_warnings +explain select sum(t1.b) from t0,t1 where t0.a=t1.a; +flush status; +select sum(t1.b) from t0,t1 where t0.a=t1.a; +show status like 'handler_mrr%'; + +set join_cache_level= @join_cache_level_save; +set join_buffer_size= @join_buffer_size_save; + +drop table t0, t1; + ## This must be last line in the file: set optimizer_switch= @myisam_mrr_tmp; diff --git a/sql/multi_range_read.cc b/sql/multi_range_read.cc index 055a9268417..6ecc64207de 100644 --- a/sql/multi_range_read.cc +++ b/sql/multi_range_read.cc @@ -466,6 +466,10 @@ void Mrr_ordered_index_reader::resume_read() /** Fill the buffer with (lookup_tuple, range_id) pairs and sort + + @return + 0 OK, the buffer is non-empty and sorted + HA_ERR_END_OF_FILE Source exhausted, the buffer is empty. */ int Mrr_ordered_index_reader::refill_buffer(bool initial) @@ -502,6 +506,13 @@ int Mrr_ordered_index_reader::refill_buffer(bool initial) if (source_exhausted && key_buffer->is_empty()) DBUG_RETURN(HA_ERR_END_OF_FILE); + if (!initial) + { + /* This is a non-initial buffer fill and we've got a non-empty buffer */ + THD *thd= current_thd; + status_var_increment(thd->status_var.ha_mrr_extra_key_sorts); + } + key_buffer->sort((key_buffer->type() == Lifo_buffer::FORWARD)? (qsort2_cmp)Mrr_ordered_index_reader::compare_keys_reverse : (qsort2_cmp)Mrr_ordered_index_reader::compare_keys, @@ -576,6 +587,7 @@ int Mrr_ordered_rndpos_reader::init(handler *h_arg, int Mrr_ordered_rndpos_reader::refill_buffer(bool initial) { int res; + bool first_call= initial; DBUG_ENTER("Mrr_ordered_rndpos_reader::refill_buffer"); if (index_reader_exhausted) @@ -593,6 +605,14 @@ int Mrr_ordered_rndpos_reader::refill_buffer(bool initial) initial= FALSE; index_reader_needs_refill= FALSE; } + + if (!first_call && !index_reader_exhausted) + { + /* Ok, this was a successful buffer refill operation */ + THD *thd= current_thd; + status_var_increment(thd->status_var.ha_mrr_extra_rowid_sorts); + } + DBUG_RETURN(res); } @@ -825,8 +845,7 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs, strategy= disk_strategy= &reader_factory.ordered_rndpos_reader; } - if (is_mrr_assoc) - status_var_increment(thd->status_var.ha_multi_range_read_init_count); + status_var_increment(thd->status_var.ha_multi_range_read_init_count); full_buf= buf->buffer; full_buf_end= buf->buffer_end; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 1312675f7b4..9ecf3466750 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -8303,6 +8303,9 @@ SHOW_VAR status_vars[]= { {"Handler_write", (char*) offsetof(STATUS_VAR, ha_write_count), SHOW_LONG_STATUS}, {"Handler_tmp_update", (char*) offsetof(STATUS_VAR, ha_tmp_update_count), SHOW_LONG_STATUS}, {"Handler_tmp_write", (char*) offsetof(STATUS_VAR, ha_tmp_write_count), SHOW_LONG_STATUS}, + {"Handler_mrr_init", (char*) offsetof(STATUS_VAR, ha_multi_range_read_init_count), SHOW_LONG_STATUS}, + {"Handler_mrr_extra_rowid_sorts", (char*) offsetof(STATUS_VAR, ha_mrr_extra_rowid_sorts), SHOW_LONG_STATUS}, + {"Handler_mrr_extra_key_sorts", (char*) offsetof(STATUS_VAR, ha_mrr_extra_key_sorts), SHOW_LONG_STATUS}, {"Key", (char*) &show_default_keycache, SHOW_FUNC}, {"Last_query_cost", (char*) offsetof(STATUS_VAR, last_query_cost), SHOW_DOUBLE_STATUS}, {"Max_used_connections", (char*) &max_used_connections, SHOW_LONG}, diff --git a/sql/sql_class.h b/sql/sql_class.h index f7d44eeec52..58af7888385 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -578,6 +578,8 @@ typedef struct system_status_var BatchedKeyAccess. */ ulong ha_multi_range_read_init_count; + ulong ha_mrr_extra_key_sorts; + ulong ha_mrr_extra_rowid_sorts; ulong ha_rollback_count; ulong ha_update_count; From 8fedf8ac75dc64eea281df27baa064c00078580a Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 25 Jan 2012 11:34:43 +0100 Subject: [PATCH 059/135] mtr runs only "big" tests, if --big-test is repeated twice --- mysql-test/lib/mtr_cases.pm | 7 +++++++ mysql-test/mysql-test-run.pl | 5 +++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm index 727e56ac77a..8b87ad367e3 100644 --- a/mysql-test/lib/mtr_cases.pm +++ b/mysql-test/lib/mtr_cases.pm @@ -925,6 +925,13 @@ sub collect_one_test_case { return $tinfo } + if ( ! $tinfo->{'big_test'} and $::opt_big_test > 1 ) + { + $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= "Small test"; + return $tinfo + } + if ( $tinfo->{'need_debug'} && ! $::debug_compiled_binaries ) { $tinfo->{'skip'}= 1; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index b2c7ee2fc37..cb6f7b4a486 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -986,7 +986,7 @@ sub command_line_setup { 'skip-test=s' => \&collect_option, 'do-test=s' => \&collect_option, 'start-from=s' => \&collect_option, - 'big-test' => \$opt_big_test, + 'big-test+' => \$opt_big_test, 'combination=s' => \@opt_combinations, 'skip-combinations' => \&collect_option, 'experimental=s' => \@opt_experimentals, @@ -5984,7 +5984,8 @@ Options to control what test suites or cases to run list of suite names. The default is: "$DEFAULT_SUITES" skip-rpl Skip the replication test cases. - big-test Also run tests marked as "big" + big-test Also run tests marked as "big". Repeat this option + twice to run only "big" tests. staging-run Run a limited number of tests (no slow tests). Used for running staging trees with valgrind. enable-disabled Run also tests marked as disabled From e10816118a35cdb67cd9e1e7b671c946741d3f7c Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Wed, 25 Jan 2012 18:27:34 +0400 Subject: [PATCH 060/135] Update handler status variables after the last commit. --- mysql-test/r/myisam_mrr.result | 6 +++--- mysql-test/r/status.result | 8 +++++++- mysql-test/r/status_user.result | 3 +++ mysql-test/t/myisam_mrr.test | 1 + 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/myisam_mrr.result b/mysql-test/r/myisam_mrr.result index 0eeb22d829a..4bb0e29a26e 100644 --- a/mysql-test/r/myisam_mrr.result +++ b/mysql-test/r/myisam_mrr.result @@ -628,9 +628,9 @@ sum(t1.b) 1230 show status like 'handler_mrr%'; Variable_name Value -Handler_mrr_extra_key_sorts 1 -Handler_mrr_extra_rowid_sorts 1 -Handler_mrr_init 2 +Handler_mrr_extra_key_sorts 1or2 +Handler_mrr_extra_rowid_sorts 1or2 +Handler_mrr_init 1or2 set join_cache_level= @join_cache_level_save; set join_buffer_size= @join_buffer_size_save; drop table t0, t1; diff --git a/mysql-test/r/status.result b/mysql-test/r/status.result index b0744726390..c9602ddb8f6 100644 --- a/mysql-test/r/status.result +++ b/mysql-test/r/status.result @@ -275,6 +275,9 @@ Variable_name Value Handler_commit 0 Handler_delete 0 Handler_discover 0 +Handler_mrr_extra_key_sorts 0 +Handler_mrr_extra_rowid_sorts 0 +Handler_mrr_init 0 Handler_prepare 0 Handler_read_first 0 Handler_read_key 4 @@ -297,7 +300,7 @@ Created_tmp_files 0 Created_tmp_tables 2 Handler_tmp_update 2 Handler_tmp_write 7 -Rows_tmp_read 35 +Rows_tmp_read 38 drop table t1; CREATE TABLE t1 (i int(11) DEFAULT NULL, KEY i (i) ) ENGINE=MyISAM; insert into t1 values (1),(2),(3),(4),(5); @@ -310,6 +313,9 @@ Variable_name Value Handler_commit 0 Handler_delete 0 Handler_discover 0 +Handler_mrr_extra_key_sorts 0 +Handler_mrr_extra_rowid_sorts 0 +Handler_mrr_init 0 Handler_prepare 0 Handler_read_first 0 Handler_read_key 2 diff --git a/mysql-test/r/status_user.result b/mysql-test/r/status_user.result index 17c44df1d3c..470c1625b55 100644 --- a/mysql-test/r/status_user.result +++ b/mysql-test/r/status_user.result @@ -100,6 +100,9 @@ Variable_name Value Handler_commit 19 Handler_delete 1 Handler_discover 0 +Handler_mrr_extra_key_sorts 0 +Handler_mrr_extra_rowid_sorts 0 +Handler_mrr_init 0 Handler_prepare 18 Handler_read_first 0 Handler_read_key 3 diff --git a/mysql-test/t/myisam_mrr.test b/mysql-test/t/myisam_mrr.test index 0f916299ae7..28385c61b0f 100644 --- a/mysql-test/t/myisam_mrr.test +++ b/mysql-test/t/myisam_mrr.test @@ -313,6 +313,7 @@ set join_buffer_size=10; explain select sum(t1.b) from t0,t1 where t0.a=t1.a; flush status; select sum(t1.b) from t0,t1 where t0.a=t1.a; +--replace_result 1 1or2 2 1or2 show status like 'handler_mrr%'; set join_cache_level= @join_cache_level_save; From 73cc529b51dd4262e81df86491e3f2803946339c Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Wed, 25 Jan 2012 18:33:57 +0400 Subject: [PATCH 061/135] BUG#920255: Wrong result (extra rows) with loosescan and IN subquery The problem was that LooseScan execution code assumed that tab->key holds the index used for looseScan. This is only true when range or full index scan are used. In case of ref access, the index is in tab->ref.key (and tab->index==0 which explains how LooseScan passed tests with ref access: they used one index) Fixed by setting/using loosescan_key, which always the correct index#. --- mysql-test/r/subselect_sj.result | 34 +++++++++++++++++++++++++++ mysql-test/r/subselect_sj_jcl6.result | 34 +++++++++++++++++++++++++++ mysql-test/t/subselect_sj.test | 19 +++++++++++++++ sql/opt_subselect.cc | 1 + sql/sql_select.cc | 4 ++-- sql/sql_select.h | 6 +++++ 6 files changed, 96 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/subselect_sj.result b/mysql-test/r/subselect_sj.result index f5c3f84bcd7..9e81a0fa1b5 100644 --- a/mysql-test/r/subselect_sj.result +++ b/mysql-test/r/subselect_sj.result @@ -2169,4 +2169,38 @@ WHERE c = b AND b = a a COUNT(*) NULL 0 DROP TABLE t1, t2, t3; +# +# BUG#920255: Wrong result (extra rows) with loosescan and IN subquery +# +CREATE TABLE t1 ( a INT PRIMARY KEY, b INT, KEY(b) ); +INSERT INTO t1 VALUES +(1,2),(2,1),(3,3),(4,2),(5,5), +(6,3),(7,1),(8,4),(9,3),(10,2); +CREATE TABLE t2 ( c INT, d INT, UNIQUE KEY(c) ); +INSERT INTO t2 VALUES +(1,2),(2,1),(3,3),(4,2),(5,5),(6,3),(7,1); +SELECT a, b, d FROM t1, t2 +WHERE ( b, d ) IN +( SELECT b, d FROM t1, t2 WHERE b = c ); +a b d +2 1 2 +7 1 2 +2 1 2 +7 1 2 +1 2 1 +4 2 1 +10 2 1 +1 2 1 +4 2 1 +10 2 1 +3 3 3 +6 3 3 +9 3 3 +3 3 3 +6 3 3 +9 3 3 +8 4 2 +8 4 2 +5 5 5 +DROP TABLE t1, t2; set optimizer_switch=@subselect_sj_tmp; diff --git a/mysql-test/r/subselect_sj_jcl6.result b/mysql-test/r/subselect_sj_jcl6.result index faa4140d375..f632d3bc89d 100644 --- a/mysql-test/r/subselect_sj_jcl6.result +++ b/mysql-test/r/subselect_sj_jcl6.result @@ -2183,6 +2183,40 @@ WHERE c = b AND b = a a COUNT(*) NULL 0 DROP TABLE t1, t2, t3; +# +# BUG#920255: Wrong result (extra rows) with loosescan and IN subquery +# +CREATE TABLE t1 ( a INT PRIMARY KEY, b INT, KEY(b) ); +INSERT INTO t1 VALUES +(1,2),(2,1),(3,3),(4,2),(5,5), +(6,3),(7,1),(8,4),(9,3),(10,2); +CREATE TABLE t2 ( c INT, d INT, UNIQUE KEY(c) ); +INSERT INTO t2 VALUES +(1,2),(2,1),(3,3),(4,2),(5,5),(6,3),(7,1); +SELECT a, b, d FROM t1, t2 +WHERE ( b, d ) IN +( SELECT b, d FROM t1, t2 WHERE b = c ); +a b d +1 2 1 +1 2 1 +2 1 2 +2 1 2 +3 3 3 +3 3 3 +4 2 1 +4 2 1 +5 5 5 +6 3 3 +6 3 3 +7 1 2 +7 1 2 +8 4 2 +8 4 2 +9 3 3 +9 3 3 +10 2 1 +10 2 1 +DROP TABLE t1, t2; set optimizer_switch=@subselect_sj_tmp; # # BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off diff --git a/mysql-test/t/subselect_sj.test b/mysql-test/t/subselect_sj.test index f34cf5ba338..afa471d5889 100644 --- a/mysql-test/t/subselect_sj.test +++ b/mysql-test/t/subselect_sj.test @@ -2017,5 +2017,24 @@ SELECT a, COUNT(*) FROM t1 DROP TABLE t1, t2, t3; +--echo # +--echo # BUG#920255: Wrong result (extra rows) with loosescan and IN subquery +--echo # +CREATE TABLE t1 ( a INT PRIMARY KEY, b INT, KEY(b) ); +INSERT INTO t1 VALUES + (1,2),(2,1),(3,3),(4,2),(5,5), + (6,3),(7,1),(8,4),(9,3),(10,2); + +CREATE TABLE t2 ( c INT, d INT, UNIQUE KEY(c) ); +INSERT INTO t2 VALUES + (1,2),(2,1),(3,3),(4,2),(5,5),(6,3),(7,1); + +SELECT a, b, d FROM t1, t2 +WHERE ( b, d ) IN + ( SELECT b, d FROM t1, t2 WHERE b = c ); + +DROP TABLE t1, t2; + + # The following command must be the last one the file set optimizer_switch=@subselect_sj_tmp; diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 8e043b17bcf..63a90891720 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -4107,6 +4107,7 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options, for (uint kp=0; kp < pos->loosescan_picker.loosescan_parts; kp++) keylen += tab->table->key_info[keyno].key_part[kp].store_length; + tab->loosescan_key= keyno; tab->loosescan_key_len= keylen; if (pos->n_sj_tables > 1) tab[pos->n_sj_tables - 1].do_firstmatch= tab; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 4058e72c547..3991fff6960 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -15372,7 +15372,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records) if (join_tab->loosescan_match_tab && join_tab->loosescan_match_tab->found_match) { - KEY *key= join_tab->table->key_info + join_tab->index; + KEY *key= join_tab->table->key_info + join_tab->loosescan_key; key_copy(join_tab->loosescan_buf, join_tab->table->record[0], key, join_tab->loosescan_key_len); skip_over= TRUE; @@ -15382,7 +15382,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records) if (skip_over && !error) { - if(!key_cmp(join_tab->table->key_info[join_tab->index].key_part, + if(!key_cmp(join_tab->table->key_info[join_tab->loosescan_key].key_part, join_tab->loosescan_buf, join_tab->loosescan_key_len)) { /* diff --git a/sql/sql_select.h b/sql/sql_select.h index 8b448130eaf..185bf90ea17 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -379,6 +379,12 @@ typedef struct st_join_table { /* Buffer to save index tuple to be able to skip duplicates */ uchar *loosescan_buf; + /* + Index used by LooseScan (we store it here separately because ref access + stores it in tab->ref.key, while range scan stores it in tab->index, etc) + */ + uint loosescan_key; + /* Length of key tuple (depends on #keyparts used) to store in the above */ uint loosescan_key_len; From 424f56b3bae1e45c2956bfcd8d92f43569471415 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Wed, 25 Jan 2012 22:05:20 +0400 Subject: [PATCH 062/135] BUG#920713: Wrong result (missing rows) with firstmatch+BNL, IN subquery, ... - Disable use of join cache when we're using FirstMatch strategy, and the join order is such that subquery's inner tables are interleaved with outer. Join buffering code is incapable of handling such join orders. - The testcase requires use of @@debug_optimizer_prefer_join_prefix to hit the bug, but I'm pushing it anyway (including the mention of the variable in .test file), so that it can be found and enabled when/if we get something comparable in the main tree. --- mysql-test/r/subselect_sj.result | 27 +++++++++++++++++++++++++++ mysql-test/r/subselect_sj_jcl6.result | 27 +++++++++++++++++++++++++++ mysql-test/t/subselect_sj.test | 17 +++++++++++++++++ sql/opt_subselect.cc | 19 +++++++++++++++---- sql/sql_select.cc | 7 ++++++- sql/sql_select.h | 7 +++++++ 6 files changed, 99 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/subselect_sj.result b/mysql-test/r/subselect_sj.result index 9c335be4c89..0784b429052 100644 --- a/mysql-test/r/subselect_sj.result +++ b/mysql-test/r/subselect_sj.result @@ -2509,4 +2509,31 @@ a b d 8 4 2 5 5 5 DROP TABLE t1, t2; +# +# BUG#920713: Wrong result (missing rows) with firstmatch+BNL, IN subquery, ... +# +CREATE TABLE t1 ( a VARCHAR(1) ) ENGINE=MyISAM; +INSERT INTO t1 VALUES ('e'),('w'),('a'),('h'),('x'),('k'),('g'); +CREATE TABLE t2 ( b INT, c VARCHAR(1) ); +INSERT INTO t2 VALUES (0,'j'),(8,'v'); +SELECT * FROM t1 alias1, t2 alias2 +WHERE alias2.c IN ( +SELECT alias4.c FROM t1 alias3, t2 alias4 +); +a b c +e 0 j +e 8 v +w 0 j +w 8 v +a 0 j +a 8 v +h 0 j +h 8 v +x 0 j +x 8 v +k 0 j +k 8 v +g 0 j +g 8 v +DROP TABLE t1, t2; set optimizer_switch=@subselect_sj_tmp; diff --git a/mysql-test/r/subselect_sj_jcl6.result b/mysql-test/r/subselect_sj_jcl6.result index af7c3484b1f..b970a01c94e 100644 --- a/mysql-test/r/subselect_sj_jcl6.result +++ b/mysql-test/r/subselect_sj_jcl6.result @@ -2523,6 +2523,33 @@ a b d 10 2 1 10 2 1 DROP TABLE t1, t2; +# +# BUG#920713: Wrong result (missing rows) with firstmatch+BNL, IN subquery, ... +# +CREATE TABLE t1 ( a VARCHAR(1) ) ENGINE=MyISAM; +INSERT INTO t1 VALUES ('e'),('w'),('a'),('h'),('x'),('k'),('g'); +CREATE TABLE t2 ( b INT, c VARCHAR(1) ); +INSERT INTO t2 VALUES (0,'j'),(8,'v'); +SELECT * FROM t1 alias1, t2 alias2 +WHERE alias2.c IN ( +SELECT alias4.c FROM t1 alias3, t2 alias4 +); +a b c +e 0 j +e 8 v +w 0 j +w 8 v +a 0 j +a 8 v +h 0 j +h 8 v +x 0 j +x 8 v +k 0 j +k 8 v +g 0 j +g 8 v +DROP TABLE t1, t2; set optimizer_switch=@subselect_sj_tmp; # # BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off diff --git a/mysql-test/t/subselect_sj.test b/mysql-test/t/subselect_sj.test index 65d74419dbe..b8275f72604 100644 --- a/mysql-test/t/subselect_sj.test +++ b/mysql-test/t/subselect_sj.test @@ -2252,6 +2252,23 @@ WHERE ( b, d ) IN DROP TABLE t1, t2; +--echo # +--echo # BUG#920713: Wrong result (missing rows) with firstmatch+BNL, IN subquery, ... +--echo # +# t1 should be MyISAM or InnoDB +CREATE TABLE t1 ( a VARCHAR(1) ) ENGINE=MyISAM; +INSERT INTO t1 VALUES ('e'),('w'),('a'),('h'),('x'),('k'),('g'); +CREATE TABLE t2 ( b INT, c VARCHAR(1) ); +INSERT INTO t2 VALUES (0,'j'),(8,'v'); + +#SET debug_optimizer_prefer_join_prefix= 'alias2,alias4,alias1,alias3'; + +SELECT * FROM t1 alias1, t2 alias2 +WHERE alias2.c IN ( + SELECT alias4.c FROM t1 alias3, t2 alias4 +); + +DROP TABLE t1, t2; # The following command must be the last one the file set optimizer_switch=@subselect_sj_tmp; diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 63a90891720..75490482d93 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -4079,7 +4079,8 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options, { uint i; DBUG_ENTER("setup_semijoin_dups_elimination"); - + + join->complex_firstmatch_tables= table_map(0); POSITION *pos= join->best_positions + join->const_tables; for (i= join->const_tables ; i < join->top_join_tab_count; ) @@ -4165,8 +4166,13 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options, { JOIN_TAB *j; JOIN_TAB *jump_to= tab-1; + + bool complex_range= FALSE; + table_map tables_in_range= table_map(0); + for (j= tab; j != tab + pos->n_sj_tables; j++) { + tables_in_range |= j->table->map; if (!j->emb_sj_nest) { /* @@ -4176,11 +4182,12 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options, SELECT * FROM ot1, nt1 WHERE ot1.col IN (SELECT expr FROM it1, it2) with a join order of - - ot1 it1 nt1 nt2 + +----- FirstMatch range ----+ + | | + ot1 it1 nt1 nt2 it2 it3 ... | ^ - | +-------- 'j' point here + | +-------- 'j' points here +------------- SJ_OPT_FIRST_MATCH was set for this table as it's the first one that produces duplicates @@ -4195,6 +4202,7 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options, j[-1].do_firstmatch= jump_to; jump_to= j; /* Jump back to us */ + complex_range= TRUE; } else { @@ -4205,6 +4213,9 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options, j[-1].do_firstmatch= jump_to; i+= pos->n_sj_tables; pos+= pos->n_sj_tables; + + if (complex_range) + join->complex_firstmatch_tables|= tables_in_range; break; } case SJ_OPT_NONE: diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 3991fff6960..9d03cdd55a2 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -9153,6 +9153,9 @@ uint check_join_cache_usage(JOIN_TAB *tab, if (tab->use_quick == 2) goto no_join_cache; + + if (tab->table->map & join->complex_firstmatch_tables) + goto no_join_cache; /* Don't use join cache if we're inside a join tab range covered by LooseScan @@ -9363,7 +9366,7 @@ void check_join_cache_usage_for_tables(JOIN *join, ulonglong options, { tab->used_join_cache_level= join->max_allowed_join_cache_level; } - + uint idx= join->const_tables; for (tab= first_linear_tab(join, WITHOUT_CONST_TABLES); tab; @@ -9448,6 +9451,8 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after) bool statistics= test(!(join->select_options & SELECT_DESCRIBE)); bool sorted= 1; + join->complex_firstmatch_tables= table_map(0); + if (!join->select_lex->sj_nests.is_empty() && setup_semijoin_dups_elimination(join, options, no_jbuf_after)) DBUG_RETURN(TRUE); /* purecov: inspected */ diff --git a/sql/sql_select.h b/sql/sql_select.h index 185bf90ea17..002c5a2df5a 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -995,6 +995,13 @@ public: /* We also maintain a stack of join optimization states in * join->positions[] */ /******* Join optimization state members end *******/ + + /* + Tables within complex firstmatch ranges (i.e. those where inner tables are + interleaved with outer tables). Join buffering cannot be used for these. + */ + table_map complex_firstmatch_tables; + /* The cost of best complete join plan found so far during optimization, after optimization phase - cost of picked join order (not taking into From a0c1ada91caca56bab6093fb0a4de05cd1bf936e Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Thu, 26 Jan 2012 12:22:02 +0400 Subject: [PATCH 063/135] Sort counters by name (will this make them show in the same order on all platforms?) --- sql/mysqld.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 9ecf3466750..16254ead03f 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -8288,6 +8288,9 @@ SHOW_VAR status_vars[]= { {"Handler_commit", (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONG_STATUS}, {"Handler_delete", (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONG_STATUS}, {"Handler_discover", (char*) offsetof(STATUS_VAR, ha_discover_count), SHOW_LONG_STATUS}, + {"Handler_mrr_init", (char*) offsetof(STATUS_VAR, ha_multi_range_read_init_count), SHOW_LONG_STATUS}, + {"Handler_mrr_extra_rowid_sorts", (char*) offsetof(STATUS_VAR, ha_mrr_extra_rowid_sorts), SHOW_LONG_STATUS}, + {"Handler_mrr_extra_key_sorts", (char*) offsetof(STATUS_VAR, ha_mrr_extra_key_sorts), SHOW_LONG_STATUS}, {"Handler_prepare", (char*) offsetof(STATUS_VAR, ha_prepare_count), SHOW_LONG_STATUS}, {"Handler_read_first", (char*) offsetof(STATUS_VAR, ha_read_first_count), SHOW_LONG_STATUS}, {"Handler_read_key", (char*) offsetof(STATUS_VAR, ha_read_key_count), SHOW_LONG_STATUS}, @@ -8299,13 +8302,10 @@ SHOW_VAR status_vars[]= { {"Handler_rollback", (char*) offsetof(STATUS_VAR, ha_rollback_count), SHOW_LONG_STATUS}, {"Handler_savepoint", (char*) offsetof(STATUS_VAR, ha_savepoint_count), SHOW_LONG_STATUS}, {"Handler_savepoint_rollback",(char*) offsetof(STATUS_VAR, ha_savepoint_rollback_count), SHOW_LONG_STATUS}, - {"Handler_update", (char*) offsetof(STATUS_VAR, ha_update_count), SHOW_LONG_STATUS}, - {"Handler_write", (char*) offsetof(STATUS_VAR, ha_write_count), SHOW_LONG_STATUS}, {"Handler_tmp_update", (char*) offsetof(STATUS_VAR, ha_tmp_update_count), SHOW_LONG_STATUS}, {"Handler_tmp_write", (char*) offsetof(STATUS_VAR, ha_tmp_write_count), SHOW_LONG_STATUS}, - {"Handler_mrr_init", (char*) offsetof(STATUS_VAR, ha_multi_range_read_init_count), SHOW_LONG_STATUS}, - {"Handler_mrr_extra_rowid_sorts", (char*) offsetof(STATUS_VAR, ha_mrr_extra_rowid_sorts), SHOW_LONG_STATUS}, - {"Handler_mrr_extra_key_sorts", (char*) offsetof(STATUS_VAR, ha_mrr_extra_key_sorts), SHOW_LONG_STATUS}, + {"Handler_update", (char*) offsetof(STATUS_VAR, ha_update_count), SHOW_LONG_STATUS}, + {"Handler_write", (char*) offsetof(STATUS_VAR, ha_write_count), SHOW_LONG_STATUS}, {"Key", (char*) &show_default_keycache, SHOW_FUNC}, {"Last_query_cost", (char*) offsetof(STATUS_VAR, last_query_cost), SHOW_DOUBLE_STATUS}, {"Max_used_connections", (char*) &max_used_connections, SHOW_LONG}, From 8a8e5a50c9fd54f97e01099ff8b1e657932e80cd Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Thu, 26 Jan 2012 14:20:34 +0400 Subject: [PATCH 064/135] Fix compile failure when built without query cache: define QUERY_CACHE_DB_LENGTH_SIZE 0, just like it is done with QUERY_CACHE_FLAGS_SIZE. --- sql/mysql_priv.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index fbd0d8549f7..253acff3405 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1068,6 +1068,7 @@ struct Query_cache_query_flags (((L)->sql_command == SQLCOM_SELECT) && (L)->safe_to_cache_query) #else #define QUERY_CACHE_FLAGS_SIZE 0 +#define QUERY_CACHE_DB_LENGTH_SIZE 0 #define query_cache_store_query(A, B) do { } while(0) #define query_cache_destroy() do { } while(0) #define query_cache_result_size_limit(A) do { } while(0) From 53fde5bb6f98896c0ccd9b60a9576e5c5fef8a91 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Fri, 27 Jan 2012 17:35:26 +0400 Subject: [PATCH 065/135] BUG#922254: Assertion `0' failed at item_cmpfunc.cc:5899: Item* Item_equal::get_first(JOIN_TAB*, Item*) Fixed Item* Item_equal::get_first(JOIN_TAB *context, Item *field_item) to work correctly in the case where: - context!= NO_PARTICULAR_TAB, it points to a table within SJ-Materialization nest - field_item points to an item_equal that has a constant Item_field but does not have any fields from tables that are within semi-join nests. --- mysql-test/r/subselect_mat.result | 20 ++++++++++++++++++++ mysql-test/r/subselect_sj_mat.result | 18 ++++++++++++++++++ mysql-test/t/subselect_sj_mat.test | 19 +++++++++++++++++++ sql/item_cmpfunc.cc | 10 ++++++---- 4 files changed, 63 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/subselect_mat.result b/mysql-test/r/subselect_mat.result index 7225cf7c825..bb30bfaf7f1 100644 --- a/mysql-test/r/subselect_mat.result +++ b/mysql-test/r/subselect_mat.result @@ -1811,6 +1811,26 @@ a b c 4 4 2 4 4 4 DROP TABLE t1,t2; +# +# BUG#922254: Assertion `0' failed at item_cmpfunc.cc:5899: Item* Item_equal::get_first(JOIN_TAB*, Item*) +# +CREATE TABLE t1 ( a VARCHAR(3) ); +CREATE TABLE t2 ( b VARCHAR(3), c VARCHAR(8), KEY(c) ); +INSERT INTO t2 VALUES ('USA','Abilene'),('USA','Akron'); +EXPLAIN +SELECT * FROM +( SELECT * FROM t1 ) AS alias1, +t2 AS alias2 +WHERE b = a AND a IN ( +SELECT alias3.c +FROM t2 AS alias3, t2 AS alias4 +WHERE alias4.c = alias3.b +); +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 +3 MATERIALIZED alias3 ALL NULL NULL NULL NULL 2 +3 MATERIALIZED alias4 index c c 11 NULL 2 Using where; Using index; Using join buffer (flat, BNL join) +DROP TABLE t1,t2; # This must be at the end: set optimizer_switch=@subselect_sj_mat_tmp; set join_cache_level=@save_join_cache_level; diff --git a/mysql-test/r/subselect_sj_mat.result b/mysql-test/r/subselect_sj_mat.result index 82f012bcbf1..44fb9c61f24 100644 --- a/mysql-test/r/subselect_sj_mat.result +++ b/mysql-test/r/subselect_sj_mat.result @@ -1849,6 +1849,24 @@ a b c 4 4 2 4 4 4 DROP TABLE t1,t2; +# +# BUG#922254: Assertion `0' failed at item_cmpfunc.cc:5899: Item* Item_equal::get_first(JOIN_TAB*, Item*) +# +CREATE TABLE t1 ( a VARCHAR(3) ); +CREATE TABLE t2 ( b VARCHAR(3), c VARCHAR(8), KEY(c) ); +INSERT INTO t2 VALUES ('USA','Abilene'),('USA','Akron'); +EXPLAIN +SELECT * FROM +( SELECT * FROM t1 ) AS alias1, +t2 AS alias2 +WHERE b = a AND a IN ( +SELECT alias3.c +FROM t2 AS alias3, t2 AS alias4 +WHERE alias4.c = alias3.b +); +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 +DROP TABLE t1,t2; # This must be at the end: set optimizer_switch=@subselect_sj_mat_tmp; set join_cache_level=@save_join_cache_level; diff --git a/mysql-test/t/subselect_sj_mat.test b/mysql-test/t/subselect_sj_mat.test index 2a5b0f56877..80ba42e7bab 100644 --- a/mysql-test/t/subselect_sj_mat.test +++ b/mysql-test/t/subselect_sj_mat.test @@ -1510,6 +1510,25 @@ SELECT * FROM t1 LEFT JOIN t2 ON ( a = b ) DROP TABLE t1,t2; +--echo # +--echo # BUG#922254: Assertion `0' failed at item_cmpfunc.cc:5899: Item* Item_equal::get_first(JOIN_TAB*, Item*) +--echo # +CREATE TABLE t1 ( a VARCHAR(3) ); +CREATE TABLE t2 ( b VARCHAR(3), c VARCHAR(8), KEY(c) ); +INSERT INTO t2 VALUES ('USA','Abilene'),('USA','Akron'); + +EXPLAIN +SELECT * FROM + ( SELECT * FROM t1 ) AS alias1, + t2 AS alias2 +WHERE b = a AND a IN ( + SELECT alias3.c + FROM t2 AS alias3, t2 AS alias4 + WHERE alias4.c = alias3.b +); + +DROP TABLE t1,t2; + --echo # This must be at the end: set optimizer_switch=@subselect_sj_mat_tmp; set join_cache_level=@save_join_cache_level; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 8b8a85ca59b..ddb80a3ed81 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -5853,13 +5853,15 @@ Item* Item_equal::get_first(JOIN_TAB *context, Item *field_item) if (emb_nest && emb_nest->sj_mat_info && emb_nest->sj_mat_info->is_used) { /* - It's a field from an materialized semi-join. We can substitute it only - for a field from the same semi-join. Find the first of such items. + It's a field from an materialized semi-join. We can substitute it for + - a constant item + - a field from the same semi-join + Find the first of such items: */ - while ((item= it++)) { - if (it.get_curr_field()->table->pos_in_table_list->embedding == emb_nest) + if (item->const_item() || + it.get_curr_field()->table->pos_in_table_list->embedding == emb_nest) { /* If we found given field then return NULL to avoid unnecessary From 4f4047a259015479c6ec85ae3d64a8c59714a3d6 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Fri, 27 Jan 2012 17:51:40 +0400 Subject: [PATCH 066/135] Make testcase stable by adding --sorted_result for SHOW STATUS commands. --- mysql-test/t/myisam_mrr.test | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mysql-test/t/myisam_mrr.test b/mysql-test/t/myisam_mrr.test index 28385c61b0f..3629a9cebed 100644 --- a/mysql-test/t/myisam_mrr.test +++ b/mysql-test/t/myisam_mrr.test @@ -272,6 +272,7 @@ drop table t1; --echo # Test of MRR handler counters --echo # flush status; +--sorted_result show status like 'Handler_mrr%'; create table t0 (a int); insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); @@ -283,6 +284,7 @@ explain select sum(b) from t1 where a < 10; --echo # This should show one MRR scan and no re-fills: flush status; select sum(b) from t1 where a < 10; +--sorted_result show status like 'handler_mrr%'; set @mrr_buffer_size_save= @@mrr_buffer_size; @@ -294,6 +296,7 @@ explain select sum(b) from t1 where a < 1600; --echo # This should show one MRR scan and one extra rowid sort: flush status; select sum(b) from t1 where a < 1600; +--sorted_result show status like 'handler_mrr%'; set @@mrr_buffer_size= @mrr_buffer_size_save; @@ -305,6 +308,7 @@ set join_cache_level=6; explain select sum(t1.b) from t0,t1 where t0.a=t1.a; flush status; select sum(t1.b) from t0,t1 where t0.a=t1.a; +--sorted_result show status like 'handler_mrr%'; --disable_warnings @@ -313,6 +317,7 @@ set join_buffer_size=10; explain select sum(t1.b) from t0,t1 where t0.a=t1.a; flush status; select sum(t1.b) from t0,t1 where t0.a=t1.a; +--sorted_result --replace_result 1 1or2 2 1or2 show status like 'handler_mrr%'; From 4e2b6d45e02bdfa5fbf998a86d5cc020b64be5d9 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Fri, 27 Jan 2012 19:01:26 -0800 Subject: [PATCH 067/135] Back-ported test cases for bug #59919 of mysql-5.6 code line. The bug could not be reproduced in the latest release of mariadb-5.3 as it was was fixed by Sergey Petrunia when working on the problems concerning outer joins within in subqueries converted to semi-joins. --- mysql-test/r/subselect_sj.result | 52 +++++++++++++++++++++++++++ mysql-test/r/subselect_sj_jcl6.result | 52 +++++++++++++++++++++++++++ mysql-test/t/subselect_sj.test | 39 ++++++++++++++++++++ 3 files changed, 143 insertions(+) diff --git a/mysql-test/r/subselect_sj.result b/mysql-test/r/subselect_sj.result index 0c9c2eb3af5..a6f10b21bd2 100644 --- a/mysql-test/r/subselect_sj.result +++ b/mysql-test/r/subselect_sj.result @@ -1538,6 +1538,58 @@ deallocate prepare s; set optimizer_switch=@save_optimizer_switch; DROP TABLE ot1, ot2, ot3, it1; # +# Bug#59919/11766739: Crash in tmp_table_param::init() with semijoin=on +# +CREATE TABLE t1 (f1 INTEGER) ENGINE=MyISAM; +CREATE TABLE t2 (f1 INTEGER, f2 INTEGER) ENGINE=MyISAM; +CREATE TABLE t3 (f1 INTEGER, f2 INTEGER) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1,1), (2,1); +INSERT INTO t3 VALUES +(1,1), (2,1), (5,4), (7,3), (8,2), (8,1), (7,3), +(9,5), (4,3), (7,2), (7,7), (3,1), (5,8), (9,7); +set @save_optimizer_switch=@@optimizer_switch; +set optimizer_switch='semijoin=off,materialization=on'; +EXPLAIN +SELECT * FROM t3 +WHERE f2 IN (SELECT t1.f1 +FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t3 ALL NULL NULL NULL NULL 14 Using where +2 MATERIALIZED t1 system NULL NULL NULL NULL 1 +2 MATERIALIZED b1 ALL NULL NULL NULL NULL 2 Using where +2 MATERIALIZED b2 ALL NULL NULL NULL NULL 2 +SELECT * FROM t3 +WHERE f2 IN (SELECT t1.f1 +FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE); +f1 f2 +1 1 +2 1 +8 1 +3 1 +set optimizer_switch='semijoin=on,materialization=on'; +EXPLAIN +SELECT * FROM t3 +WHERE f2 IN (SELECT t1.f1 +FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 system NULL NULL NULL NULL 1 +1 PRIMARY ALL distinct_key NULL NULL NULL 1 +1 PRIMARY t3 ALL NULL NULL NULL NULL 14 Using where; Using join buffer (flat, BNL join) +2 MATERIALIZED b1 ALL NULL NULL NULL NULL 2 Using where +2 MATERIALIZED b2 ALL NULL NULL NULL NULL 2 +SELECT * FROM t3 +WHERE f2 IN (SELECT t1.f1 +FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE); +f1 f2 +1 1 +2 1 +8 1 +3 1 +set optimizer_switch=@save_optimizer_switch; +DROP TABLE t1, t2, t3 ; +# +# # BUG#784723: Wrong result with semijoin + nested subqueries in maria-5.3 # CREATE TABLE t1 ( t1field integer, primary key (t1field)); diff --git a/mysql-test/r/subselect_sj_jcl6.result b/mysql-test/r/subselect_sj_jcl6.result index a8bc0d120cd..2f53a4855a3 100644 --- a/mysql-test/r/subselect_sj_jcl6.result +++ b/mysql-test/r/subselect_sj_jcl6.result @@ -1551,6 +1551,58 @@ deallocate prepare s; set optimizer_switch=@save_optimizer_switch; DROP TABLE ot1, ot2, ot3, it1; # +# Bug#59919/11766739: Crash in tmp_table_param::init() with semijoin=on +# +CREATE TABLE t1 (f1 INTEGER) ENGINE=MyISAM; +CREATE TABLE t2 (f1 INTEGER, f2 INTEGER) ENGINE=MyISAM; +CREATE TABLE t3 (f1 INTEGER, f2 INTEGER) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1,1), (2,1); +INSERT INTO t3 VALUES +(1,1), (2,1), (5,4), (7,3), (8,2), (8,1), (7,3), +(9,5), (4,3), (7,2), (7,7), (3,1), (5,8), (9,7); +set @save_optimizer_switch=@@optimizer_switch; +set optimizer_switch='semijoin=off,materialization=on'; +EXPLAIN +SELECT * FROM t3 +WHERE f2 IN (SELECT t1.f1 +FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t3 ALL NULL NULL NULL NULL 14 Using where +2 MATERIALIZED t1 system NULL NULL NULL NULL 1 +2 MATERIALIZED b1 ALL NULL NULL NULL NULL 2 Using where +2 MATERIALIZED b2 ALL NULL NULL NULL NULL 2 +SELECT * FROM t3 +WHERE f2 IN (SELECT t1.f1 +FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE); +f1 f2 +1 1 +2 1 +8 1 +3 1 +set optimizer_switch='semijoin=on,materialization=on'; +EXPLAIN +SELECT * FROM t3 +WHERE f2 IN (SELECT t1.f1 +FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 system NULL NULL NULL NULL 1 +1 PRIMARY ALL distinct_key NULL NULL NULL 1 +1 PRIMARY t3 ALL NULL NULL NULL NULL 14 Using where; Using join buffer (flat, BNL join) +2 MATERIALIZED b1 ALL NULL NULL NULL NULL 2 Using where +2 MATERIALIZED b2 ALL NULL NULL NULL NULL 2 +SELECT * FROM t3 +WHERE f2 IN (SELECT t1.f1 +FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE); +f1 f2 +1 1 +2 1 +8 1 +3 1 +set optimizer_switch=@save_optimizer_switch; +DROP TABLE t1, t2, t3 ; +# +# # BUG#784723: Wrong result with semijoin + nested subqueries in maria-5.3 # CREATE TABLE t1 ( t1field integer, primary key (t1field)); diff --git a/mysql-test/t/subselect_sj.test b/mysql-test/t/subselect_sj.test index 62d2fd61721..f906482a3b1 100644 --- a/mysql-test/t/subselect_sj.test +++ b/mysql-test/t/subselect_sj.test @@ -1353,6 +1353,45 @@ set optimizer_switch=@save_optimizer_switch; DROP TABLE ot1, ot2, ot3, it1; +--echo # +--echo # Bug#59919/11766739: Crash in tmp_table_param::init() with semijoin=on +--echo # + +CREATE TABLE t1 (f1 INTEGER) ENGINE=MyISAM; +CREATE TABLE t2 (f1 INTEGER, f2 INTEGER) ENGINE=MyISAM; +CREATE TABLE t3 (f1 INTEGER, f2 INTEGER) ENGINE=MyISAM; + +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1,1), (2,1); +INSERT INTO t3 VALUES + (1,1), (2,1), (5,4), (7,3), (8,2), (8,1), (7,3), + (9,5), (4,3), (7,2), (7,7), (3,1), (5,8), (9,7); + +set @save_optimizer_switch=@@optimizer_switch; + +set optimizer_switch='semijoin=off,materialization=on'; +EXPLAIN +SELECT * FROM t3 +WHERE f2 IN (SELECT t1.f1 + FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE); +SELECT * FROM t3 +WHERE f2 IN (SELECT t1.f1 + FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE); + +set optimizer_switch='semijoin=on,materialization=on'; +EXPLAIN +SELECT * FROM t3 +WHERE f2 IN (SELECT t1.f1 + FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE); +SELECT * FROM t3 +WHERE f2 IN (SELECT t1.f1 + FROM t1 LEFT OUTER JOIN (t2 AS b1 JOIN t2 AS b2 ON TRUE) ON TRUE); + +set optimizer_switch=@save_optimizer_switch; + +DROP TABLE t1, t2, t3 ; + +--echo # --echo # --echo # BUG#784723: Wrong result with semijoin + nested subqueries in maria-5.3 --echo # From 5ca1dd8f0b22d6b5aea06c9ad32481498cb99d6e Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Sat, 28 Jan 2012 01:12:45 -0800 Subject: [PATCH 068/135] Fixed LP bug #922971. Applied the fix for bug #12546542 from the mysql-5.6 code line: JOIN_CACHE::join_records forgot to reset JOIN_TAB::first_unmatched in some cases. --- mysql-test/r/join_cache.result | 48 ++++++++++++++++++++++++++++++++++ mysql-test/t/join_cache.test | 42 +++++++++++++++++++++++++++++ sql/sql_join_cache.cc | 20 +++++++------- 3 files changed, 100 insertions(+), 10 deletions(-) diff --git a/mysql-test/r/join_cache.result b/mysql-test/r/join_cache.result index db869ba434a..11114a032f9 100644 --- a/mysql-test/r/join_cache.result +++ b/mysql-test/r/join_cache.result @@ -5486,4 +5486,52 @@ i set join_cache_level = default; set optimizer_switch=@tmp_optimizer_switch; DROP TABLE t1,t2,t3; +# +# Bug #12546542: missing row with semijoin=off + join cache +# (LP bug #922971) +# +CREATE TABLE t1 (a varchar(1024)); +INSERT INTO t1 VALUES ('v'), ('we'); +CREATE TABLE t2 ( +a varchar(1024) CHARACTER SET utf8 DEFAULT NULL, b int, c int +); +INSERT INTO t2 VALUES ('we',4,NULL), ('v',1305673728,6); +CREATE TABLE t3 (b int, c int); +INSERT INTO t3 VALUES (4,4); +set @tmp_optimizer_switch=@@optimizer_switch; +set optimizer_switch='semijoin=off'; +set optimizer_switch='materialization=off'; +set join_cache_level=0; +EXPLAIN +SELECT * FROM t1 +WHERE a IN (SELECT t2.a FROM t2 LEFT JOIN t3 ON t2.b = t3.b +WHERE t2.c < 10 OR t3.c > 1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 1 Using where +SELECT * FROM t1 +WHERE a IN (SELECT t2.a FROM t2 LEFT JOIN t3 ON t2.b = t3.b +WHERE t2.c < 10 OR t3.c > 1); +a +v +we +set join_cache_level=2; +EXPLAIN +SELECT * FROM t1 +WHERE a IN (SELECT t2.a FROM t2 LEFT JOIN t3 ON t2.b = t3.b +WHERE t2.c < 10 OR t3.c > 1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (flat, BNL join) +SELECT * FROM t1 +WHERE a IN (SELECT t2.a FROM t2 LEFT JOIN t3 ON t2.b = t3.b +WHERE t2.c < 10 OR t3.c > 1); +a +v +we +set join_cache_level = default; +set optimizer_switch=@tmp_optimizer_switch; +DROP TABLE t1,t2,t3; set @@optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/t/join_cache.test b/mysql-test/t/join_cache.test index cc1941e16b9..8a61c00b7d4 100644 --- a/mysql-test/t/join_cache.test +++ b/mysql-test/t/join_cache.test @@ -3505,5 +3505,47 @@ set optimizer_switch=@tmp_optimizer_switch; DROP TABLE t1,t2,t3; +--echo # +--echo # Bug #12546542: missing row with semijoin=off + join cache +--echo # (LP bug #922971) +--echo # + +CREATE TABLE t1 (a varchar(1024)); +INSERT INTO t1 VALUES ('v'), ('we'); +CREATE TABLE t2 ( + a varchar(1024) CHARACTER SET utf8 DEFAULT NULL, b int, c int +); +INSERT INTO t2 VALUES ('we',4,NULL), ('v',1305673728,6); +CREATE TABLE t3 (b int, c int); +INSERT INTO t3 VALUES (4,4); + +set @tmp_optimizer_switch=@@optimizer_switch; +set optimizer_switch='semijoin=off'; +set optimizer_switch='materialization=off'; + +set join_cache_level=0; +EXPLAIN +SELECT * FROM t1 + WHERE a IN (SELECT t2.a FROM t2 LEFT JOIN t3 ON t2.b = t3.b + WHERE t2.c < 10 OR t3.c > 1); + +SELECT * FROM t1 + WHERE a IN (SELECT t2.a FROM t2 LEFT JOIN t3 ON t2.b = t3.b + WHERE t2.c < 10 OR t3.c > 1); + +set join_cache_level=2; +EXPLAIN +SELECT * FROM t1 + WHERE a IN (SELECT t2.a FROM t2 LEFT JOIN t3 ON t2.b = t3.b + WHERE t2.c < 10 OR t3.c > 1); +SELECT * FROM t1 + WHERE a IN (SELECT t2.a FROM t2 LEFT JOIN t3 ON t2.b = t3.b + WHERE t2.c < 10 OR t3.c > 1); + +set join_cache_level = default; +set optimizer_switch=@tmp_optimizer_switch; + +DROP TABLE t1,t2,t3; + # this must be the last command in the file set @@optimizer_switch=@save_optimizer_switch; diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc index af4b157ba90..2a8db8b4fd1 100644 --- a/sql/sql_join_cache.cc +++ b/sql/sql_join_cache.cc @@ -2109,16 +2109,6 @@ enum_nested_loop_state JOIN_CACHE::join_records(bool skip_last) if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS) goto finish; } - if (outer_join_first_inner) - { - /* - All null complemented rows have been already generated for all - outer records from join buffer. Restore the state of the - first_unmatched values to 0 to avoid another null complementing. - */ - for (tab= join_tab->first_inner; tab <= join_tab->last_inner; tab++) - tab->first_unmatched= 0; - } if (skip_last) { @@ -2131,6 +2121,16 @@ enum_nested_loop_state JOIN_CACHE::join_records(bool skip_last) } finish: + if (outer_join_first_inner) + { + /* + All null complemented rows have been already generated for all + outer records from join buffer. Restore the state of the + first_unmatched values to 0 to avoid another null complementing. + */ + for (tab= join_tab->first_inner; tab <= join_tab->last_inner; tab++) + tab->first_unmatched= 0; + } restore_last_record(); reset(TRUE); DBUG_PRINT("exit", ("rc: %d", rc)); From 12bd3dfe29164a4a74a97da5c09d9401491ea27d Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Mon, 30 Jan 2012 20:34:47 +0400 Subject: [PATCH 069/135] BUG#923246: Loosescan reports different result than other semijoin methods - If LooseScan is used with quick select, require that quick select produces data in key order (this disables use of MRR, which can return data in arbitrary order). --- mysql-test/r/subselect3_jcl6.result | 2 +- mysql-test/r/subselect_sj.result | 40 +++++++++++++++++++++++++++ mysql-test/r/subselect_sj_jcl6.result | 40 +++++++++++++++++++++++++++ mysql-test/t/subselect_sj.test | 22 +++++++++++++++ sql/opt_subselect.cc | 5 ++++ 5 files changed, 108 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/subselect3_jcl6.result b/mysql-test/r/subselect3_jcl6.result index 38284345fc2..77b8b5faebc 100644 --- a/mysql-test/r/subselect3_jcl6.result +++ b/mysql-test/r/subselect3_jcl6.result @@ -1156,7 +1156,7 @@ insert into t4 select a from t3; explain select * from t3 where a in (select t1.kp1 from t1,t4 where kp1<20 and t4.pk=t1.c); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 range kp1 kp1 5 NULL 48 Using index condition; Using where; Rowid-ordered scan; LooseScan +1 PRIMARY t1 range kp1 kp1 5 NULL 48 Using index condition; Using where; LooseScan 1 PRIMARY t4 eq_ref PRIMARY PRIMARY 4 test.t1.c 1 Using index; FirstMatch(t1) 1 PRIMARY t3 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join) drop table t1, t3, t4; diff --git a/mysql-test/r/subselect_sj.result b/mysql-test/r/subselect_sj.result index 260cd512863..f92b33ff651 100644 --- a/mysql-test/r/subselect_sj.result +++ b/mysql-test/r/subselect_sj.result @@ -2588,4 +2588,44 @@ k 8 v g 0 j g 8 v DROP TABLE t1, t2; +# +# BUG#923246: Loosescan reports different result than other semijoin methods +# +set @tmp_923246= @@optimizer_switch; +set optimizer_switch='mrr=on,materialization=off'; +create table t0 (a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t1 (kp1 int, kp2 int, c int, filler char(100), key(kp1, kp2)); +insert into t1 select A.a+10*(B.a+10*C.a), 0, 0, 'filler' from t0 A, t0 B, t0 C; +insert into t1 select * from t1 where kp1 < 20; +create table t3 (a int); +insert into t3 select A.a + 10*B.a from t0 A, t0 B; +select * from t3 where a in (select kp1 from t1 where kp1<20); +a +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +explain select * from t3 where a in (select kp1 from t1 where kp1<20); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range kp1 kp1 5 NULL 48 Using where; Using index; LooseScan +1 PRIMARY t3 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join) +drop table t0,t1,t3; +set optimizer_switch= @tmp_923246; set optimizer_switch=@subselect_sj_tmp; diff --git a/mysql-test/r/subselect_sj_jcl6.result b/mysql-test/r/subselect_sj_jcl6.result index a27b6b7b55d..dd358ced14a 100644 --- a/mysql-test/r/subselect_sj_jcl6.result +++ b/mysql-test/r/subselect_sj_jcl6.result @@ -2602,6 +2602,46 @@ k 8 v g 0 j g 8 v DROP TABLE t1, t2; +# +# BUG#923246: Loosescan reports different result than other semijoin methods +# +set @tmp_923246= @@optimizer_switch; +set optimizer_switch='mrr=on,materialization=off'; +create table t0 (a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t1 (kp1 int, kp2 int, c int, filler char(100), key(kp1, kp2)); +insert into t1 select A.a+10*(B.a+10*C.a), 0, 0, 'filler' from t0 A, t0 B, t0 C; +insert into t1 select * from t1 where kp1 < 20; +create table t3 (a int); +insert into t3 select A.a + 10*B.a from t0 A, t0 B; +select * from t3 where a in (select kp1 from t1 where kp1<20); +a +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +explain select * from t3 where a in (select kp1 from t1 where kp1<20); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range kp1 kp1 5 NULL 48 Using where; Using index; LooseScan +1 PRIMARY t3 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join) +drop table t0,t1,t3; +set optimizer_switch= @tmp_923246; set optimizer_switch=@subselect_sj_tmp; # # BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off diff --git a/mysql-test/t/subselect_sj.test b/mysql-test/t/subselect_sj.test index eabdbf33ecd..6b8a757b9e8 100644 --- a/mysql-test/t/subselect_sj.test +++ b/mysql-test/t/subselect_sj.test @@ -2309,5 +2309,27 @@ WHERE alias2.c IN ( DROP TABLE t1, t2; +--echo # +--echo # BUG#923246: Loosescan reports different result than other semijoin methods +--echo # +set @tmp_923246= @@optimizer_switch; +set optimizer_switch='mrr=on,materialization=off'; + +create table t0 (a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); + +create table t1 (kp1 int, kp2 int, c int, filler char(100), key(kp1, kp2)); +insert into t1 select A.a+10*(B.a+10*C.a), 0, 0, 'filler' from t0 A, t0 B, t0 C; +insert into t1 select * from t1 where kp1 < 20; + +create table t3 (a int); +insert into t3 select A.a + 10*B.a from t0 A, t0 B; + +select * from t3 where a in (select kp1 from t1 where kp1<20); +explain select * from t3 where a in (select kp1 from t1 where kp1<20); + +drop table t0,t1,t3; +set optimizer_switch= @tmp_923246; + # The following command must be the last one the file set optimizer_switch=@subselect_sj_tmp; diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 75490482d93..d01ef381806 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -4099,6 +4099,11 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options, { /* We jump from the last table to the first one */ tab->loosescan_match_tab= tab + pos->n_sj_tables - 1; + + /* LooseScan requires records to be produced in order */ + if (tab->select && tab->select->quick) + tab->select->quick->need_sorted_output(); + for (uint j= i; j < i + pos->n_sj_tables; j++) join->join_tab[j].inside_loosescan_range= TRUE; From 7ed15e6e50aec65560d8988fc5713f1f489b6616 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 31 Jan 2012 21:12:26 +0100 Subject: [PATCH 070/135] sort status variables alphabetically in mysqld.cc --- mysql-test/t/myisam_mrr.test | 5 ----- sql/mysqld.cc | 4 ++-- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/mysql-test/t/myisam_mrr.test b/mysql-test/t/myisam_mrr.test index 3629a9cebed..28385c61b0f 100644 --- a/mysql-test/t/myisam_mrr.test +++ b/mysql-test/t/myisam_mrr.test @@ -272,7 +272,6 @@ drop table t1; --echo # Test of MRR handler counters --echo # flush status; ---sorted_result show status like 'Handler_mrr%'; create table t0 (a int); insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); @@ -284,7 +283,6 @@ explain select sum(b) from t1 where a < 10; --echo # This should show one MRR scan and no re-fills: flush status; select sum(b) from t1 where a < 10; ---sorted_result show status like 'handler_mrr%'; set @mrr_buffer_size_save= @@mrr_buffer_size; @@ -296,7 +294,6 @@ explain select sum(b) from t1 where a < 1600; --echo # This should show one MRR scan and one extra rowid sort: flush status; select sum(b) from t1 where a < 1600; ---sorted_result show status like 'handler_mrr%'; set @@mrr_buffer_size= @mrr_buffer_size_save; @@ -308,7 +305,6 @@ set join_cache_level=6; explain select sum(t1.b) from t0,t1 where t0.a=t1.a; flush status; select sum(t1.b) from t0,t1 where t0.a=t1.a; ---sorted_result show status like 'handler_mrr%'; --disable_warnings @@ -317,7 +313,6 @@ set join_buffer_size=10; explain select sum(t1.b) from t0,t1 where t0.a=t1.a; flush status; select sum(t1.b) from t0,t1 where t0.a=t1.a; ---sorted_result --replace_result 1 1or2 2 1or2 show status like 'handler_mrr%'; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 16254ead03f..a090448ebae 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -8288,9 +8288,9 @@ SHOW_VAR status_vars[]= { {"Handler_commit", (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONG_STATUS}, {"Handler_delete", (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONG_STATUS}, {"Handler_discover", (char*) offsetof(STATUS_VAR, ha_discover_count), SHOW_LONG_STATUS}, - {"Handler_mrr_init", (char*) offsetof(STATUS_VAR, ha_multi_range_read_init_count), SHOW_LONG_STATUS}, - {"Handler_mrr_extra_rowid_sorts", (char*) offsetof(STATUS_VAR, ha_mrr_extra_rowid_sorts), SHOW_LONG_STATUS}, {"Handler_mrr_extra_key_sorts", (char*) offsetof(STATUS_VAR, ha_mrr_extra_key_sorts), SHOW_LONG_STATUS}, + {"Handler_mrr_extra_rowid_sorts", (char*) offsetof(STATUS_VAR, ha_mrr_extra_rowid_sorts), SHOW_LONG_STATUS}, + {"Handler_mrr_init", (char*) offsetof(STATUS_VAR, ha_multi_range_read_init_count), SHOW_LONG_STATUS}, {"Handler_prepare", (char*) offsetof(STATUS_VAR, ha_prepare_count), SHOW_LONG_STATUS}, {"Handler_read_first", (char*) offsetof(STATUS_VAR, ha_read_first_count), SHOW_LONG_STATUS}, {"Handler_read_key", (char*) offsetof(STATUS_VAR, ha_read_key_count), SHOW_LONG_STATUS}, From b4643d75fe065d92403817a1dd8785b198b6fdec Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 1 Feb 2012 17:09:49 +0200 Subject: [PATCH 071/135] fix for LP BUG#921878. Problem was in try to check/use Item_direct_ref of derived view when we have to use real Item_field under it. --- mysql-test/r/derived_view.result | 25 ++++++++++++++++++++++++- mysql-test/t/derived_view.test | 30 ++++++++++++++++++++++++++---- sql/item.cc | 10 +++++----- 3 files changed, 55 insertions(+), 10 deletions(-) diff --git a/mysql-test/r/derived_view.result b/mysql-test/r/derived_view.result index e853f5ac526..eceae5cc3d9 100644 --- a/mysql-test/r/derived_view.result +++ b/mysql-test/r/derived_view.result @@ -1800,6 +1800,7 @@ INSERT INTO t2 VALUES (7), (4); CREATE TABLE t1 (b int NOT NULL); INSERT INTO t1 VALUES (5), (7); CREATE ALGORITHM=MERGE VIEW v1 AS SELECT * FROM t1; +SET @save_optimizer_switch=@@optimizer_switch; SET SESSION optimizer_switch='derived_merge=off'; PREPARE st1 FROM 'SELECT * FROM (SELECT * FROM t2 LEFT JOIN v1 ON t2.a = v1.b) AS t'; @@ -1812,9 +1813,9 @@ a b 7 7 4 NULL DEALLOCATE PREPARE st1; +set SESSION optimizer_switch= @save_optimizer_switch; DROP VIEW v1; DROP TABLE t1,t2; -SET SESSION optimizer_switch='derived_merge=on'; # # LP bug #879939: assertion in ha_maria::enable_indexes # with derived_with_keys=on @@ -1832,6 +1833,7 @@ INSERT INTO t1 VALUES ('USA','Mesquite'), ('USA','Metairie'), ('USA','Miami'); CREATE TABLE t3 (a varchar(35)); INSERT INTO t3 VALUES ('Miami'); +SET @save_optimizer_switch=@@optimizer_switch; SET optimizer_switch = 'derived_with_keys=on'; SET @@tmp_table_size=1024*4; explain SELECT * FROM (SELECT t1.* FROM t1, t2) AS t JOIN t3 ON t3.a = t.b; @@ -1855,6 +1857,7 @@ USA Miami Miami USA Miami Miami USA Miami Miami SET @@tmp_table_size=default; +set SESSION optimizer_switch= @save_optimizer_switch; drop table t1,t2,t3; # # BUG#882994: Crash in QUICK_RANGE_SELECT::reset with derived_with_keys @@ -1906,5 +1909,25 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY ALL NULL NULL NULL NULL 3 2 DERIVED t1 ALL NULL NULL NULL NULL 8 DROP TABLE t1; +# +# LP BUG#921878 incorrect check of items during columns union types +# aggregation for merged derived tables +# +SET @save_optimizer_switch=@@optimizer_switch; +SET SESSION optimizer_switch='derived_merge=on'; +CREATE TABLE t1 ( a ENUM( 'x', 'y' ) ); +insert into t1 values ('x'); +CREATE TABLE t2 LIKE t1; +insert into t1 values ('y'); +CREATE TABLE t3 LIKE t1; +INSERT INTO t3 +SELECT * FROM ( SELECT * FROM t1 ) AS A +UNION SELECT * FROM t2; +select * from t3; +a +x +y +drop table t1,t2,t3; +set SESSION optimizer_switch= @save_optimizer_switch; set optimizer_switch=@exit_optimizer_switch; set join_cache_level=@exit_join_cache_level; diff --git a/mysql-test/t/derived_view.test b/mysql-test/t/derived_view.test index f8ba1f347f3..95412426aa0 100644 --- a/mysql-test/t/derived_view.test +++ b/mysql-test/t/derived_view.test @@ -1192,7 +1192,7 @@ INSERT INTO t2 VALUES (7), (4); CREATE TABLE t1 (b int NOT NULL); INSERT INTO t1 VALUES (5), (7); CREATE ALGORITHM=MERGE VIEW v1 AS SELECT * FROM t1; - +SET @save_optimizer_switch=@@optimizer_switch; SET SESSION optimizer_switch='derived_merge=off'; PREPARE st1 FROM @@ -1201,10 +1201,12 @@ EXECUTE st1; EXECUTE st1; DEALLOCATE PREPARE st1; +set SESSION optimizer_switch= @save_optimizer_switch; + DROP VIEW v1; DROP TABLE t1,t2; -SET SESSION optimizer_switch='derived_merge=on'; + --echo # --echo # LP bug #879939: assertion in ha_maria::enable_indexes @@ -1226,7 +1228,7 @@ INSERT INTO t1 VALUES CREATE TABLE t3 (a varchar(35)); INSERT INTO t3 VALUES ('Miami'); - +SET @save_optimizer_switch=@@optimizer_switch; SET optimizer_switch = 'derived_with_keys=on'; SET @@tmp_table_size=1024*4; explain SELECT * FROM (SELECT t1.* FROM t1, t2) AS t JOIN t3 ON t3.a = t.b; @@ -1234,7 +1236,7 @@ SELECT * FROM (SELECT t1.* FROM t1, t2) AS t JOIN t3 ON t3.a = t.b; SET @@tmp_table_size=1024*1024*16; SELECT * FROM (SELECT t1.* FROM t1, t2) AS t JOIN t3 ON t3.a = t.b; SET @@tmp_table_size=default; - +set SESSION optimizer_switch= @save_optimizer_switch; drop table t1,t2,t3; --echo # @@ -1291,6 +1293,26 @@ SELECT * FROM (SELECT * FROM t1 LIMIT 3) t; DROP TABLE t1; +--echo # +--echo # LP BUG#921878 incorrect check of items during columns union types +--echo # aggregation for merged derived tables +--echo # +SET @save_optimizer_switch=@@optimizer_switch; +SET SESSION optimizer_switch='derived_merge=on'; +CREATE TABLE t1 ( a ENUM( 'x', 'y' ) ); +insert into t1 values ('x'); +CREATE TABLE t2 LIKE t1; +insert into t1 values ('y'); +CREATE TABLE t3 LIKE t1; +INSERT INTO t3 + SELECT * FROM ( SELECT * FROM t1 ) AS A + UNION SELECT * FROM t2; +select * from t3; + +drop table t1,t2,t3; + +set SESSION optimizer_switch= @save_optimizer_switch; + # The following command must be the last one the file set optimizer_switch=@exit_optimizer_switch; set join_cache_level=@exit_join_cache_level; diff --git a/sql/item.cc b/sql/item.cc index aaf9b0c2a12..b738d1f00da 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -9052,13 +9052,13 @@ void Item_type_holder::get_full_info(Item *item) DBUG_ASSERT((enum_set_typelib && get_real_type(item) == MYSQL_TYPE_NULL) || (!enum_set_typelib && - item->type() == Item::FIELD_ITEM && - (get_real_type(item) == MYSQL_TYPE_ENUM || - get_real_type(item) == MYSQL_TYPE_SET) && - ((Field_enum*)((Item_field *) item)->field)->typelib)); + item->real_item()->type() == Item::FIELD_ITEM && + (get_real_type(item->real_item()) == MYSQL_TYPE_ENUM || + get_real_type(item->real_item()) == MYSQL_TYPE_SET) && + ((Field_enum*)((Item_field *) item->real_item())->field)->typelib)); if (!enum_set_typelib) { - enum_set_typelib= ((Field_enum*)((Item_field *) item)->field)->typelib; + enum_set_typelib= ((Field_enum*)((Item_field *) item->real_item())->field)->typelib; } } } From 94c316069e7d1be80d81d55c3218d3f29d38f230 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Thu, 2 Feb 2012 22:22:27 -0800 Subject: [PATCH 072/135] Applied the patch from mysql-5.6 code line that fixed a significant performance drop for high concurrency bechmarks (bug #11765850 - 58854). Here's the comment of the patch commit: The bug is that the InnoDB pre-fetch cache was not being used in row_search_for_mysql(). Secondly the changeset that planted the bug also introduced some inefficient code. It would read an extra row, convert it to MySQL row format (for ICP==off), copy the row to the pre-fetch cache row buffer, then check for cache overflow and dequeue the row that was pushed if there was a possibility of a cache overflow. --- storage/xtradb/row/row0sel.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/storage/xtradb/row/row0sel.c b/storage/xtradb/row/row0sel.c index 226b19359bb..f52e782599f 100644 --- a/storage/xtradb/row/row0sel.c +++ b/storage/xtradb/row/row0sel.c @@ -3259,16 +3259,15 @@ row_sel_pop_cached_row_for_mysql( } /********************************************************************//** -Pushes a row for MySQL to the fetch cache. -@return TRUE on success, FALSE if the record contains incomplete BLOBs */ -UNIV_INLINE __attribute__((warn_unused_result)) -ibool +Pushes a row for MySQL to the fetch cache. */ +UNIV_INLINE +void row_sel_push_cache_row_for_mysql( /*=============================*/ byte* mysql_rec, /*!< in/out: MySQL record */ row_prebuilt_t* prebuilt) /*!< in/out: prebuilt struct */ { - ut_ad(prebuilt->n_fetch_cached < MYSQL_FETCH_CACHE_SIZE); + ut_a(prebuilt->n_fetch_cached < MYSQL_FETCH_CACHE_SIZE); ut_a(!prebuilt->templ_contains_blob); if (UNIV_UNLIKELY(prebuilt->fetch_cache[0] == NULL)) { @@ -3300,12 +3299,7 @@ row_sel_push_cache_row_for_mysql( memcpy(prebuilt->fetch_cache[prebuilt->n_fetch_cached], mysql_rec, prebuilt->mysql_row_len); - if (++prebuilt->n_fetch_cached < MYSQL_FETCH_CACHE_SIZE) { - return(FALSE); - } - - row_sel_pop_cached_row_for_mysql(mysql_rec, prebuilt); - return(TRUE); + ++prebuilt->n_fetch_cached; } /*********************************************************************//** @@ -4669,6 +4663,11 @@ requires_clust_rec: not cache rows because there the cursor is a scrollable cursor. */ + ut_a(prebuilt->n_fetch_cached < MYSQL_FETCH_CACHE_SIZE); + + /* We only convert from InnoDB row format to MySQL row + format when ICP is disabled. */ + if (!prebuilt->idx_cond && !row_sel_store_mysql_rec(buf, prebuilt, result_rec, result_rec != rec, offsets)) { @@ -4680,8 +4679,12 @@ requires_clust_rec: transaction. Rollback happens at a lower level, not here. */ goto next_rec; - } else if (row_sel_push_cache_row_for_mysql(buf, prebuilt)) { - goto next_rec; + } + + row_sel_push_cache_row_for_mysql(buf, prebuilt); + + if (prebuilt->n_fetch_cached < MYSQL_FETCH_CACHE_SIZE) { + goto next_rec; } } else { if (UNIV_UNLIKELY From d6e1377ac206718abd039426ab72690a9ee0b48e Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 3 Feb 2012 10:28:23 +0200 Subject: [PATCH 073/135] Fix check of view updatability in case of underlying view changes its updatability. For single table update/insert added deep check of single tables (single_table_updatable()). For multi-table view insert added additional check of target table (check_view_single_update). Multi-update was correct. Test suite for all cases added. --- mysql-test/r/view.result | 27 ++++++++++++++++++++++++++- mysql-test/t/view.test | 22 +++++++++++++++++++++- sql/sql_insert.cc | 17 +++++++++++++---- sql/sql_update.cc | 3 ++- sql/table.cc | 22 ++++++++++++++++++++++ sql/table.h | 3 +++ 6 files changed, 87 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 22fd4eb1722..65d6574ac8b 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -3930,10 +3930,35 @@ drop table t1,t2; # Bug #794005: crash in st_table::mark_virtual_columns_for_write # CREATE TABLE t1 (a int); +insert into t1 values (1); CREATE TABLE t2 (a int); +insert into t2 values (1); CREATE VIEW v2 AS SELECT * FROM t2; CREATE VIEW v1 AS SELECT * FROM v2; +CREATE VIEW v3 AS SELECT t2.a,v1.a as b FROM t2,v1 where t2.a=v1.a; CREATE OR REPLACE ALGORITHM = TEMPTABLE VIEW v2 AS SELECT * FROM t1; UPDATE v1 SET a = 10; -DROP VIEW v1,v2; +ERROR HY000: The target table v1 of the UPDATE is not updatable +REPLACE v1 SET a = 10; +ERROR HY000: The target table v1 of the INSERT is not insertable-into +INSERT into v1 values (20); +ERROR HY000: The target table v1 of the INSERT is not insertable-into +UPDATE v3 SET b= 10; +ERROR HY000: The target table v2 of the UPDATE is not updatable +REPLACE v3 SET b= 10; +ERROR HY000: The target table v3 of the INSERT is not insertable-into +INSERT into v3(b) values (20); +ERROR HY000: The target table v3 of the INSERT is not insertable-into +UPDATE v3 SET a = 10; +REPLACE v3 SET a = 11; +INSERT INTO v3(a) values (20); +select * from t1; +a +1 +select * from t2; +a +10 +11 +20 +DROP VIEW v1,v2,v3; DROP TABLE t1,t2; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 462118af4ea..4be8aa89358 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -3982,13 +3982,33 @@ drop table t1,t2; --echo # CREATE TABLE t1 (a int); +insert into t1 values (1); CREATE TABLE t2 (a int); +insert into t2 values (1); CREATE VIEW v2 AS SELECT * FROM t2; CREATE VIEW v1 AS SELECT * FROM v2; +CREATE VIEW v3 AS SELECT t2.a,v1.a as b FROM t2,v1 where t2.a=v1.a; CREATE OR REPLACE ALGORITHM = TEMPTABLE VIEW v2 AS SELECT * FROM t1; +--error ER_NON_UPDATABLE_TABLE UPDATE v1 SET a = 10; +--error ER_NON_INSERTABLE_TABLE +REPLACE v1 SET a = 10; +--error ER_NON_INSERTABLE_TABLE +INSERT into v1 values (20); +--error ER_NON_UPDATABLE_TABLE +UPDATE v3 SET b= 10; +--error ER_NON_INSERTABLE_TABLE +REPLACE v3 SET b= 10; +--error ER_NON_INSERTABLE_TABLE +INSERT into v3(b) values (20); +UPDATE v3 SET a = 10; +REPLACE v3 SET a = 11; +INSERT INTO v3(a) values (20); -DROP VIEW v1,v2; +select * from t1; +select * from t2; + +DROP VIEW v1,v2,v3; DROP TABLE t1,t2; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 99bebe827a4..c350d2deeee 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -103,7 +103,8 @@ static bool check_view_insertability(THD *thd, TABLE_LIST *view); */ bool check_view_single_update(List &fields, List *values, - TABLE_LIST *view, table_map *map) + TABLE_LIST *view, table_map *map, + bool insert) { /* it is join view => we need to find the table for update */ List_iterator_fast it(fields); @@ -135,6 +136,14 @@ bool check_view_single_update(List &fields, List *values, goto error; view->table= tbl->table; + if (!tbl->single_table_updatable()) + { + if (insert) + my_error(ER_NON_INSERTABLE_TABLE, MYF(0), view->alias, "INSERT"); + else + my_error(ER_NON_UPDATABLE_TABLE, MYF(0), view->alias, "UPDATE"); + return TRUE; + } *map= tables; return FALSE; @@ -179,7 +188,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list, { TABLE *table= table_list->table; - if (!table_list->updatable) + if (!table_list->single_table_updatable()) { my_error(ER_NON_INSERTABLE_TABLE, MYF(0), table_list->alias, "INSERT"); return -1; @@ -251,7 +260,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list, if (check_view_single_update(fields, fields_and_values_from_different_maps ? (List*) 0 : &values, - table_list, map)) + table_list, map, true)) return -1; table= table_list->table; } @@ -337,7 +346,7 @@ static int check_update_fields(THD *thd, TABLE_LIST *insert_table_list, if (insert_table_list->effective_algorithm == VIEW_ALGORITHM_MERGE && check_view_single_update(update_fields, &update_values, - insert_table_list, map)) + insert_table_list, map, false)) return -1; if (table->timestamp_field) diff --git a/sql/sql_update.cc b/sql/sql_update.cc index c6f413e754e..b3c001849b5 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -277,7 +277,8 @@ int mysql_update(THD *thd, { DBUG_RETURN(1); } - if (!table_list->updatable || check_key_in_view(thd, table_list)) + if (!table_list->single_table_updatable() || + check_key_in_view(thd, table_list)) { my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "UPDATE"); DBUG_RETURN(1); diff --git a/sql/table.cc b/sql/table.cc index a3df9023805..e576e5ae25f 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -3722,6 +3722,28 @@ bool TABLE_LIST::prep_where(THD *thd, Item **conds, DBUG_RETURN(FALSE); } +/** + Check that table/view is updatable and if it has single + underlying tables/views it is also updatable + + @return Result of the check. +*/ + +bool TABLE_LIST::single_table_updatable() +{ + if (!updatable) + return false; + if (view_tables && view_tables->elements == 1) + { + /* + We need to check deeply only single table views. Multi-table views + will be turned to multi-table updates and then checked by leaf tables + */ + return view_tables->head()->single_table_updatable(); + } + return true; +} + /* Merge ON expressions for a view diff --git a/sql/table.h b/sql/table.h index 1b7713022ce..fed30722d71 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1606,6 +1606,9 @@ struct TABLE_LIST */ char *get_table_name() { return view != NULL ? view_name.str : table_name; } + + bool single_table_updatable(); + private: bool prep_check_option(THD *thd, uint8 check_opt_type); bool prep_where(THD *thd, Item **conds, bool no_where_clause); From b9616d815d9c318bb2c1028041a210a807d941bc Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 3 Feb 2012 10:31:30 +0200 Subject: [PATCH 074/135] Added 5.2 test result delimiter --- mysql-test/r/view.result | 3 +++ mysql-test/t/view.test | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 65d6574ac8b..8d1237501f3 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -3962,3 +3962,6 @@ a 20 DROP VIEW v1,v2,v3; DROP TABLE t1,t2; +# ----------------------------------------------------------------- +# -- End of 5.2 tests. +# ----------------------------------------------------------------- diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 4be8aa89358..f691a0c528b 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -4012,3 +4012,7 @@ select * from t2; DROP VIEW v1,v2,v3; DROP TABLE t1,t2; + +--echo # ----------------------------------------------------------------- +--echo # -- End of 5.2 tests. +--echo # ----------------------------------------------------------------- From 046988661d330e48e19af9fd7d9d2ad4f6cbcd1e Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Fri, 3 Feb 2012 00:46:34 -0800 Subject: [PATCH 075/135] Back-ported the fix for bug #12831587 from mysql-5.6 code line. The comment for the fix commit says: Due to the changes required by ICP we first copy a row from the InnoDB format to the MySQL row buffer and then copy it to the pre-fetch queue. This was done for the non-ICP code path too. This change removes the double copy for the latter. --- storage/xtradb/row/row0sel.c | 40 +++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/storage/xtradb/row/row0sel.c b/storage/xtradb/row/row0sel.c index f52e782599f..fca3c90109f 100644 --- a/storage/xtradb/row/row0sel.c +++ b/storage/xtradb/row/row0sel.c @@ -3259,12 +3259,12 @@ row_sel_pop_cached_row_for_mysql( } /********************************************************************//** -Pushes a row for MySQL to the fetch cache. */ -UNIV_INLINE -void -row_sel_push_cache_row_for_mysql( -/*=============================*/ - byte* mysql_rec, /*!< in/out: MySQL record */ +Get the last fetch cache buffer from the queue. +@return pointer to buffer. */ +UNIV_INLINE +byte* +row_sel_fetch_last_buf( +/*===================*/ row_prebuilt_t* prebuilt) /*!< in/out: prebuilt struct */ { ut_a(prebuilt->n_fetch_cached < MYSQL_FETCH_CACHE_SIZE); @@ -3296,8 +3296,26 @@ row_sel_push_cache_row_for_mysql( UNIV_MEM_INVALID(prebuilt->fetch_cache[prebuilt->n_fetch_cached], prebuilt->mysql_row_len); - memcpy(prebuilt->fetch_cache[prebuilt->n_fetch_cached], - mysql_rec, prebuilt->mysql_row_len); + return(prebuilt->fetch_cache[prebuilt->n_fetch_cached]); +} + +/********************************************************************//** +Pushes a row for MySQL to the fetch cache. */ +UNIV_INLINE +void +row_sel_push_cache_row_for_mysql( +/*=============================*/ + byte* mysql_rec, /*!< in/out: MySQL record */ + row_prebuilt_t* prebuilt) /*!< in/out: prebuilt struct */ +{ + /* For non ICP code path the row should already exist in the + next fetch cache slot. */ + + if (prebuilt->idx_cond != NULL) { + byte* dest = row_sel_fetch_last_buf(prebuilt); + + ut_memcpy(dest, mysql_rec, prebuilt->mysql_row_len); + } ++prebuilt->n_fetch_cached; } @@ -4669,8 +4687,10 @@ requires_clust_rec: format when ICP is disabled. */ if (!prebuilt->idx_cond - && !row_sel_store_mysql_rec(buf, prebuilt, result_rec, - result_rec != rec, offsets)) { + && !row_sel_store_mysql_rec( + row_sel_fetch_last_buf(prebuilt), + prebuilt, result_rec, + result_rec != rec, offsets)) { /* Only fresh inserts may contain incomplete externally stored columns. Pretend that such records do not exist. Such records may only be From 52d4103ccc02c55e05faef188d73d2b07c00084b Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 3 Feb 2012 12:24:55 +0200 Subject: [PATCH 076/135] Fixed DELETE issues of view over view over table. --- mysql-test/r/view.result | 18 ++++++++++++++++++ mysql-test/t/view.test | 14 ++++++++++++++ sql/sql_delete.cc | 5 +++-- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 8d1237501f3..0ff06ac09d7 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -3943,12 +3943,20 @@ REPLACE v1 SET a = 10; ERROR HY000: The target table v1 of the INSERT is not insertable-into INSERT into v1 values (20); ERROR HY000: The target table v1 of the INSERT is not insertable-into +DELETE from v1; +ERROR HY000: The target table v1 of the DELETE is not updatable UPDATE v3 SET b= 10; ERROR HY000: The target table v2 of the UPDATE is not updatable REPLACE v3 SET b= 10; ERROR HY000: The target table v3 of the INSERT is not insertable-into INSERT into v3(b) values (20); ERROR HY000: The target table v3 of the INSERT is not insertable-into +DELETE from v3 where b=20; +ERROR HY000: Can not delete from join view 'test.v3' +DELETE from v3 where a=20; +ERROR HY000: Can not delete from join view 'test.v3' +DELETE v1 from v1,t1 where v1.a=t1.a; +ERROR HY000: The target table v1 of the DELETE is not updatable UPDATE v3 SET a = 10; REPLACE v3 SET a = 11; INSERT INTO v3(a) values (20); @@ -3960,6 +3968,16 @@ a 10 11 20 +CREATE OR REPLACE ALGORITHM = MERGE VIEW v2 AS SELECT * FROM t2; +DELETE from v1 where a=11; +DELETE v1 from v1,t1 where v1.a=t1.a; +select * from t1; +a +1 +select * from t2; +a +10 +20 DROP VIEW v1,v2,v3; DROP TABLE t1,t2; # ----------------------------------------------------------------- diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index f691a0c528b..762c3121615 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -3998,11 +3998,19 @@ REPLACE v1 SET a = 10; --error ER_NON_INSERTABLE_TABLE INSERT into v1 values (20); --error ER_NON_UPDATABLE_TABLE +DELETE from v1; +--error ER_NON_UPDATABLE_TABLE UPDATE v3 SET b= 10; --error ER_NON_INSERTABLE_TABLE REPLACE v3 SET b= 10; --error ER_NON_INSERTABLE_TABLE INSERT into v3(b) values (20); +--error ER_VIEW_DELETE_MERGE_VIEW +DELETE from v3 where b=20; +--error ER_VIEW_DELETE_MERGE_VIEW +DELETE from v3 where a=20; +--error ER_NON_UPDATABLE_TABLE +DELETE v1 from v1,t1 where v1.a=t1.a; UPDATE v3 SET a = 10; REPLACE v3 SET a = 11; INSERT INTO v3(a) values (20); @@ -4010,6 +4018,12 @@ INSERT INTO v3(a) values (20); select * from t1; select * from t2; +CREATE OR REPLACE ALGORITHM = MERGE VIEW v2 AS SELECT * FROM t2; +DELETE from v1 where a=11; +DELETE v1 from v1,t1 where v1.a=t1.a; +select * from t1; +select * from t2; + DROP VIEW v1,v2,v3; DROP TABLE t1,t2; diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 29cd3262a72..72a5b9703b3 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -508,7 +508,8 @@ int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds) setup_conds(thd, table_list, select_lex->leaf_tables, conds) || setup_ftfuncs(select_lex)) DBUG_RETURN(TRUE); - if (!table_list->updatable || check_key_in_view(thd, table_list)) + if (!table_list->single_table_updatable() || + check_key_in_view(thd, table_list)) { my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "DELETE"); DBUG_RETURN(TRUE); @@ -598,7 +599,7 @@ int mysql_multi_delete_prepare(THD *thd) DBUG_RETURN(TRUE); } - if (!target_tbl->correspondent_table->updatable || + if (!target_tbl->correspondent_table->single_table_updatable() || check_key_in_view(thd, target_tbl->correspondent_table)) { my_error(ER_NON_UPDATABLE_TABLE, MYF(0), From 79a04a2c9c2cb04bc635b609504e2b9fb57fd23d Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 3 Feb 2012 13:01:05 +0200 Subject: [PATCH 077/135] Moving LP BUG#794005 to 5.3 + fixing INSERT of multi-table view. --- mysql-test/r/view.result | 60 ++++++++++++++++++++++++++++++++++++++++ mysql-test/t/view.test | 58 ++++++++++++++++++++++++++++++++++++++ sql/item.cc | 16 +++++++---- sql/sql_base.cc | 5 ++-- sql/sql_delete.cc | 7 +++-- sql/sql_derived.cc | 2 +- sql/sql_insert.cc | 19 +++++++++---- sql/sql_load.cc | 2 +- sql/sql_prepare.cc | 4 +-- sql/sql_update.cc | 4 +-- sql/table.cc | 25 +++++++++++++++++ sql/table.h | 3 ++ 12 files changed, 183 insertions(+), 22 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index d302df2f029..15ef0c088b1 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -3930,6 +3930,63 @@ drop table t1,t2; # -- End of 5.1 tests. # ----------------------------------------------------------------- # +# Bug #794005: crash in st_table::mark_virtual_columns_for_write +# +CREATE TABLE t1 (a int); +insert into t1 values (1); +CREATE TABLE t2 (a int); +insert into t2 values (1); +CREATE VIEW v2 AS SELECT * FROM t2; +CREATE VIEW v1 AS SELECT * FROM v2; +CREATE VIEW v3 AS SELECT t2.a,v1.a as b FROM t2,v1 where t2.a=v1.a; +CREATE OR REPLACE ALGORITHM = TEMPTABLE VIEW v2 AS SELECT * FROM t1; +UPDATE v1 SET a = 10; +ERROR HY000: The target table v1 of the UPDATE is not updatable +REPLACE v1 SET a = 10; +ERROR HY000: The target table v1 of the INSERT is not insertable-into +INSERT into v1 values (20); +ERROR HY000: The target table v1 of the INSERT is not insertable-into +DELETE from v1; +ERROR HY000: The target table v1 of the DELETE is not updatable +UPDATE v3 SET b= 10; +ERROR HY000: The target table v2 of the UPDATE is not updatable +REPLACE v3 SET b= 10; +ERROR HY000: The target table v3 of the INSERT is not insertable-into +INSERT into v3(b) values (20); +ERROR HY000: The target table v3 of the INSERT is not insertable-into +DELETE from v3 where b=20; +ERROR HY000: Can not delete from join view 'test.v3' +DELETE from v3 where a=20; +ERROR HY000: Can not delete from join view 'test.v3' +DELETE v1 from v1,t1 where v1.a=t1.a; +ERROR HY000: The target table v1 of the DELETE is not updatable +UPDATE v3 SET a = 10; +REPLACE v3 SET a = 11; +INSERT INTO v3(a) values (20); +select * from t1; +a +1 +select * from t2; +a +10 +11 +20 +CREATE OR REPLACE ALGORITHM = MERGE VIEW v2 AS SELECT * FROM t2; +DELETE from v1 where a=11; +DELETE v1 from v1,t1 where v1.a=t1.a; +select * from t1; +a +1 +select * from t2; +a +10 +20 +DROP VIEW v1,v2,v3; +DROP TABLE t1,t2; +# ----------------------------------------------------------------- +# -- End of 5.2 tests. +# ----------------------------------------------------------------- +# # Bug #59696 Optimizer does not use equalities for conditions over view # CREATE TABLE t1 (a int NOT NULL); @@ -4376,4 +4433,7 @@ NULL NULL 1 0 NULL NULL 1 0 DROP VIEW v2; DROP TABLE t1, t2, t3; +# ----------------------------------------------------------------- +# -- End of 5.3 tests. +# ----------------------------------------------------------------- SET optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index d4d5f2acc0b..2a9bfd89f3b 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -3980,6 +3980,60 @@ drop table t1,t2; --echo # ----------------------------------------------------------------- --echo # -- End of 5.1 tests. --echo # ----------------------------------------------------------------- +--echo # +--echo # Bug #794005: crash in st_table::mark_virtual_columns_for_write +--echo # + +CREATE TABLE t1 (a int); +insert into t1 values (1); +CREATE TABLE t2 (a int); +insert into t2 values (1); + +CREATE VIEW v2 AS SELECT * FROM t2; +CREATE VIEW v1 AS SELECT * FROM v2; +CREATE VIEW v3 AS SELECT t2.a,v1.a as b FROM t2,v1 where t2.a=v1.a; +CREATE OR REPLACE ALGORITHM = TEMPTABLE VIEW v2 AS SELECT * FROM t1; + +--error ER_NON_UPDATABLE_TABLE +UPDATE v1 SET a = 10; +--error ER_NON_INSERTABLE_TABLE +REPLACE v1 SET a = 10; +--error ER_NON_INSERTABLE_TABLE +INSERT into v1 values (20); +--error ER_NON_UPDATABLE_TABLE +DELETE from v1; +--error ER_NON_UPDATABLE_TABLE +UPDATE v3 SET b= 10; +--error ER_NON_INSERTABLE_TABLE +REPLACE v3 SET b= 10; +--error ER_NON_INSERTABLE_TABLE +INSERT into v3(b) values (20); +--error ER_VIEW_DELETE_MERGE_VIEW +DELETE from v3 where b=20; +--error ER_VIEW_DELETE_MERGE_VIEW +DELETE from v3 where a=20; +--error ER_NON_UPDATABLE_TABLE +DELETE v1 from v1,t1 where v1.a=t1.a; +UPDATE v3 SET a = 10; +REPLACE v3 SET a = 11; +INSERT INTO v3(a) values (20); + +select * from t1; +select * from t2; + +CREATE OR REPLACE ALGORITHM = MERGE VIEW v2 AS SELECT * FROM t2; +DELETE from v1 where a=11; +DELETE v1 from v1,t1 where v1.a=t1.a; +select * from t1; +select * from t2; + +DROP VIEW v1,v2,v3; +DROP TABLE t1,t2; + +--echo # ----------------------------------------------------------------- +--echo # -- End of 5.2 tests. +--echo # ----------------------------------------------------------------- + --echo # --echo # Bug #59696 Optimizer does not use equalities for conditions over view --echo # @@ -4311,4 +4365,8 @@ SELECT * FROM t1 RIGHT JOIN v2 ON ( v2.a = t1.a ) WHERE v2.b IN ( SELECT b FROM DROP VIEW v2; DROP TABLE t1, t2, t3; +--echo # ----------------------------------------------------------------- +--echo # -- End of 5.3 tests. +--echo # ----------------------------------------------------------------- + SET optimizer_switch=@save_optimizer_switch; diff --git a/sql/item.cc b/sql/item.cc index 8bd5b6fe1a4..f9bbc4aeead 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -9143,18 +9143,22 @@ void Item_ref::update_used_tables() } -table_map Item_direct_view_ref::used_tables() const +table_map Item_direct_view_ref::used_tables() const { - return get_depended_from() ? + return get_depended_from() ? OUTER_REF_TABLE_BIT : - (view->merged ? (*ref)->used_tables() : view->table->map); + ((view->merged || !view->table) ? + (*ref)->used_tables() : + view->table->map); } -table_map Item_direct_view_ref::not_null_tables() const +table_map Item_direct_view_ref::not_null_tables() const { - return get_depended_from() ? + return get_depended_from() ? 0 : - (view->merged ? (*ref)->not_null_tables() : view->table->map); + ((view->merged || !view->table) ? + (*ref)->not_null_tables() : + view->table->map); } /* diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 6dd329f8c77..9c5d251c728 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -7927,7 +7927,8 @@ bool setup_tables(THD *thd, Name_resolution_context *context, while ((table_list= ti++)) { TABLE *table= table_list->table; - table->pos_in_table_list= table_list; + if (table) + table->pos_in_table_list= table_list; if (first_select_table && table_list->top_table() == first_select_table) { @@ -7940,7 +7941,7 @@ bool setup_tables(THD *thd, Name_resolution_context *context, { table_list->jtbm_table_no= tablenr; } - else + else if (table) { table->pos_in_table_list= table_list; setup_table_map(table, table_list, tablenr); diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 3ce375190a7..84e88196f20 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -68,7 +68,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, if (mysql_handle_list_of_derived(thd->lex, table_list, DT_PREPARE)) DBUG_RETURN(TRUE); - if (!table_list->updatable) + if (!table_list->single_table_updatable()) { my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "DELETE"); DBUG_RETURN(TRUE); @@ -526,7 +526,8 @@ int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds) setup_conds(thd, table_list, select_lex->leaf_tables, conds) || setup_ftfuncs(select_lex)) DBUG_RETURN(TRUE); - if (!table_list->updatable || check_key_in_view(thd, table_list)) + if (!table_list->single_table_updatable() || + check_key_in_view(thd, table_list)) { my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "DELETE"); DBUG_RETURN(TRUE); @@ -622,7 +623,7 @@ int mysql_multi_delete_prepare(THD *thd) DBUG_RETURN(TRUE); } - if (!target_tbl->correspondent_table->updatable || + if (!target_tbl->correspondent_table->single_table_updatable() || check_key_in_view(thd, target_tbl->correspondent_table)) { my_error(ER_NON_UPDATABLE_TABLE, MYF(0), diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 0955f9c0982..02a26254336 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -483,7 +483,7 @@ bool mysql_derived_merge_for_insert(THD *thd, LEX *lex, TABLE_LIST *derived) return mysql_derived_prepare(thd, lex, derived); if (!derived->is_multitable()) { - if (!derived->updatable) + if (!derived->single_table_updatable()) return derived->create_field_translation(thd); if (derived->merge_underlying_list) { diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index d01a594708e..a4943d5e13a 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -103,7 +103,8 @@ static bool check_view_insertability(THD *thd, TABLE_LIST *view); */ bool check_view_single_update(List &fields, List *values, - TABLE_LIST *view, table_map *map) + TABLE_LIST *view, table_map *map, + bool insert) { /* it is join view => we need to find the table for update */ List_iterator_fast it(fields); @@ -140,6 +141,14 @@ bool check_view_single_update(List &fields, List *values, */ tbl->table->insert_values= view->table->insert_values; view->table= tbl->table; + if (!tbl->single_table_updatable()) + { + if (insert) + my_error(ER_NON_INSERTABLE_TABLE, MYF(0), view->alias, "INSERT"); + else + my_error(ER_NON_UPDATABLE_TABLE, MYF(0), view->alias, "UPDATE"); + return TRUE; + } *map= tables; return FALSE; @@ -184,7 +193,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list, { TABLE *table= table_list->table; - if (!table_list->updatable) + if (!table_list->single_table_updatable()) { my_error(ER_NON_INSERTABLE_TABLE, MYF(0), table_list->alias, "INSERT"); return -1; @@ -260,7 +269,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list, if (check_view_single_update(fields, fields_and_values_from_different_maps ? (List*) 0 : &values, - table_list, map)) + table_list, map, true)) return -1; table= table_list->table; } @@ -347,7 +356,7 @@ static int check_update_fields(THD *thd, TABLE_LIST *insert_table_list, if (insert_table_list->is_view() && insert_table_list->is_merged_derived() && check_view_single_update(update_fields, &update_values, - insert_table_list, map)) + insert_table_list, map, false)) return -1; if (table->timestamp_field) @@ -1159,7 +1168,7 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list, bool insert_into_view= (table_list->view != 0); DBUG_ENTER("mysql_prepare_insert_check_table"); - if (!table_list->updatable) + if (!table_list->single_table_updatable()) { my_error(ER_NON_INSERTABLE_TABLE, MYF(0), table_list->alias, "INSERT"); DBUG_RETURN(TRUE); diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 42a8f001c6f..7fcb52a7b9c 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -187,7 +187,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, INSERT_ACL | UPDATE_ACL, FALSE)) DBUG_RETURN(-1); if (!table_list->table || // do not suport join view - !table_list->updatable || // and derived tables + !table_list->single_table_updatable() || // and derived tables check_key_in_view(thd, table_list)) { my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "LOAD"); diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 611c8ddf944..32ce8dc6fc4 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1274,7 +1274,7 @@ static int mysql_test_update(Prepared_statement *stmt, if (table_list->handle_derived(thd->lex, DT_PREPARE)) goto error; - if (!table_list->updatable) + if (!table_list->single_table_updatable()) { my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "UPDATE"); goto error; @@ -1348,7 +1348,7 @@ static bool mysql_test_delete(Prepared_statement *stmt, if (mysql_handle_derived(thd->lex, DT_PREPARE)) goto error; - if (!table_list->updatable) + if (!table_list->single_table_updatable()) { my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "DELETE"); goto error; diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 80eb823c346..a921a87884e 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -257,7 +257,7 @@ int mysql_update(THD *thd, thd_proc_info(thd, "init"); table= table_list->table; - if (!table_list->updatable) + if (!table_list->single_table_updatable()) { my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "UPDATE"); DBUG_RETURN(1); @@ -1090,7 +1090,7 @@ reopen_tables: /* if table will be updated then check that it is unique */ if (table->map & tables_for_update) { - if (!tl->updatable || check_key_in_view(thd, tl)) + if (!tl->single_table_updatable() || check_key_in_view(thd, tl)) { my_error(ER_NON_UPDATABLE_TABLE, MYF(0), tl->alias, "UPDATE"); DBUG_RETURN(TRUE); diff --git a/sql/table.cc b/sql/table.cc index 5fe2d8afc42..f1ff353a8c4 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -3712,6 +3712,28 @@ bool TABLE_LIST::prep_where(THD *thd, Item **conds, DBUG_RETURN(FALSE); } +/** + Check that table/view is updatable and if it has single + underlying tables/views it is also updatable + + @return Result of the check. +*/ + +bool TABLE_LIST::single_table_updatable() +{ + if (!updatable) + return false; + if (view_tables && view_tables->elements == 1) + { + /* + We need to check deeply only single table views. Multi-table views + will be turned to multi-table updates and then checked by leaf tables + */ + return view_tables->head()->single_table_updatable(); + } + return true; +} + /* Merge ON expressions for a view @@ -5185,6 +5207,9 @@ void st_table::mark_virtual_columns_for_write(bool insert_fl) Field **vfield_ptr, *tmp_vfield; bool bitmap_updated= FALSE; + if (!vfield) + return; + if (!vfield) return; diff --git a/sql/table.h b/sql/table.h index 376aa9824dc..09230e40f7a 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1797,6 +1797,9 @@ struct TABLE_LIST int fetch_number_of_rows(); bool change_refs_to_fields(); + + bool single_table_updatable(); + private: bool prep_check_option(THD *thd, uint8 check_opt_type); bool prep_where(THD *thd, Item **conds, bool no_where_clause); From 74b61f845b26257e7f44a5bb602529b4cb7638a9 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 3 Feb 2012 16:56:12 +0200 Subject: [PATCH 078/135] Fixed typos in Query Cache. --- sql/sql_cache.cc | 8 ++++---- sql/sql_cache.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 16b6d78576a..c45234f2cdf 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -1452,10 +1452,10 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d", In case the wait time can't be determined there is an upper limit which causes try_lock() to abort with a time out. - The 'TRUE' parameter indicate that the lock is allowed to timeout + The 'TIMEOUT' parameter indicate that the lock is allowed to timeout */ - if (try_lock(thd, Query_cache::WAIT)) + if (try_lock(thd, Query_cache::TIMEOUT)) DBUG_VOID_RETURN; if (query_cache_size == 0) { @@ -1781,9 +1781,9 @@ Query_cache::send_result_to_client(THD *thd, char *org_sql, uint query_length) disabled or if a full cache flush is in progress, the attempt to get the lock is aborted. - The WAIT parameter indicate that the lock is allowed to timeout. + The TIMEOUT parameter indicate that the lock is allowed to timeout. */ - if (try_lock(thd, Query_cache::WAIT)) + if (try_lock(thd, Query_cache::TIMEOUT)) goto err; if (query_cache_size == 0) diff --git a/sql/sql_cache.h b/sql/sql_cache.h index eeaac8f6b62..b2e88a3c619 100644 --- a/sql/sql_cache.h +++ b/sql/sql_cache.h @@ -429,8 +429,8 @@ protected: uint def_query_hash_size = QUERY_CACHE_DEF_QUERY_HASH_SIZE, uint def_table_hash_size = QUERY_CACHE_DEF_TABLE_HASH_SIZE); - bool is_disabled(void) { return m_cache_status != OK; } - bool is_disable_in_progress(void) + inline bool is_disabled(void) { return m_cache_status != OK; } + inline bool is_disable_in_progress(void) { return m_cache_status == DISABLE_REQUEST; } /* initialize cache (mutex) */ From 3efc8d016f1e1fbc854a4698e1d06aba5fa2ec15 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Fri, 3 Feb 2012 12:49:17 -0800 Subject: [PATCH 079/135] Made mrr related counters temporarily invisible until we agree upon their names. --- mysql-test/r/myisam_mrr.result | 15 --------------- mysql-test/r/status.result | 8 +------- mysql-test/r/status_user.result | 3 --- sql/mysqld.cc | 3 +++ 4 files changed, 4 insertions(+), 25 deletions(-) diff --git a/mysql-test/r/myisam_mrr.result b/mysql-test/r/myisam_mrr.result index 4bb0e29a26e..c2f382eb9e6 100644 --- a/mysql-test/r/myisam_mrr.result +++ b/mysql-test/r/myisam_mrr.result @@ -563,9 +563,6 @@ drop table t1; flush status; show status like 'Handler_mrr%'; Variable_name Value -Handler_mrr_extra_key_sorts 0 -Handler_mrr_extra_rowid_sorts 0 -Handler_mrr_init 0 create table t0 (a int); insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); create table t1 (a int, b int, filler char(200), key(a)); @@ -581,9 +578,6 @@ sum(b) 1230 show status like 'handler_mrr%'; Variable_name Value -Handler_mrr_extra_key_sorts 0 -Handler_mrr_extra_rowid_sorts 0 -Handler_mrr_init 1 set @mrr_buffer_size_save= @@mrr_buffer_size; set mrr_buffer_size=128; explain select sum(b) from t1 where a < 1600; @@ -596,9 +590,6 @@ sum(b) 196800 show status like 'handler_mrr%'; Variable_name Value -Handler_mrr_extra_key_sorts 0 -Handler_mrr_extra_rowid_sorts 1 -Handler_mrr_init 1 set @@mrr_buffer_size= @mrr_buffer_size_save; #Now, let's check BKA: set @join_cache_level_save= @@join_cache_level; @@ -614,9 +605,6 @@ sum(t1.b) 1230 show status like 'handler_mrr%'; Variable_name Value -Handler_mrr_extra_key_sorts 0 -Handler_mrr_extra_rowid_sorts 0 -Handler_mrr_init 1 set join_buffer_size=10; explain select sum(t1.b) from t0,t1 where t0.a=t1.a; id select_type table type possible_keys key key_len ref rows Extra @@ -628,9 +616,6 @@ sum(t1.b) 1230 show status like 'handler_mrr%'; Variable_name Value -Handler_mrr_extra_key_sorts 1or2 -Handler_mrr_extra_rowid_sorts 1or2 -Handler_mrr_init 1or2 set join_cache_level= @join_cache_level_save; set join_buffer_size= @join_buffer_size_save; drop table t0, t1; diff --git a/mysql-test/r/status.result b/mysql-test/r/status.result index c9602ddb8f6..b0744726390 100644 --- a/mysql-test/r/status.result +++ b/mysql-test/r/status.result @@ -275,9 +275,6 @@ Variable_name Value Handler_commit 0 Handler_delete 0 Handler_discover 0 -Handler_mrr_extra_key_sorts 0 -Handler_mrr_extra_rowid_sorts 0 -Handler_mrr_init 0 Handler_prepare 0 Handler_read_first 0 Handler_read_key 4 @@ -300,7 +297,7 @@ Created_tmp_files 0 Created_tmp_tables 2 Handler_tmp_update 2 Handler_tmp_write 7 -Rows_tmp_read 38 +Rows_tmp_read 35 drop table t1; CREATE TABLE t1 (i int(11) DEFAULT NULL, KEY i (i) ) ENGINE=MyISAM; insert into t1 values (1),(2),(3),(4),(5); @@ -313,9 +310,6 @@ Variable_name Value Handler_commit 0 Handler_delete 0 Handler_discover 0 -Handler_mrr_extra_key_sorts 0 -Handler_mrr_extra_rowid_sorts 0 -Handler_mrr_init 0 Handler_prepare 0 Handler_read_first 0 Handler_read_key 2 diff --git a/mysql-test/r/status_user.result b/mysql-test/r/status_user.result index 470c1625b55..17c44df1d3c 100644 --- a/mysql-test/r/status_user.result +++ b/mysql-test/r/status_user.result @@ -100,9 +100,6 @@ Variable_name Value Handler_commit 19 Handler_delete 1 Handler_discover 0 -Handler_mrr_extra_key_sorts 0 -Handler_mrr_extra_rowid_sorts 0 -Handler_mrr_init 0 Handler_prepare 18 Handler_read_first 0 Handler_read_key 3 diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 7a701217bb0..109d0220a4a 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -8284,9 +8284,12 @@ SHOW_VAR status_vars[]= { {"Handler_commit", (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONG_STATUS}, {"Handler_delete", (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONG_STATUS}, {"Handler_discover", (char*) offsetof(STATUS_VAR, ha_discover_count), SHOW_LONG_STATUS}, +#if 0 + /* Made 3 counters below temporarily invisible until we agree upon their names */ {"Handler_mrr_extra_key_sorts", (char*) offsetof(STATUS_VAR, ha_mrr_extra_key_sorts), SHOW_LONG_STATUS}, {"Handler_mrr_extra_rowid_sorts", (char*) offsetof(STATUS_VAR, ha_mrr_extra_rowid_sorts), SHOW_LONG_STATUS}, {"Handler_mrr_init", (char*) offsetof(STATUS_VAR, ha_multi_range_read_init_count), SHOW_LONG_STATUS}, +#endif {"Handler_prepare", (char*) offsetof(STATUS_VAR, ha_prepare_count), SHOW_LONG_STATUS}, {"Handler_read_first", (char*) offsetof(STATUS_VAR, ha_read_first_count), SHOW_LONG_STATUS}, {"Handler_read_key", (char*) offsetof(STATUS_VAR, ha_read_key_count), SHOW_LONG_STATUS}, From f6cdddf51f385fd7dd9afe286f3bdce0b7e59f60 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 9 Feb 2012 23:35:26 +0200 Subject: [PATCH 080/135] Test case for bug lp:905353 The bug itself is fixed by the patch for bug lp:908269. --- mysql-test/r/subselect.result | 9 +++++++++ mysql-test/r/subselect_no_mat.result | 9 +++++++++ mysql-test/r/subselect_no_opts.result | 9 +++++++++ mysql-test/r/subselect_no_scache.result | 9 +++++++++ mysql-test/r/subselect_no_semijoin.result | 9 +++++++++ mysql-test/t/subselect.test | 11 +++++++++++ 6 files changed, 56 insertions(+) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 47dcafc663b..bca4eb677de 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -5994,5 +5994,14 @@ SELECT ( SELECT b FROM t2 WHERE b = a OR rand() * 0) FROM t1; 1 NULL drop table t1,t2,t3; +# +# LP BUG#905353 Wrong non-empty result with a constant table, +# aggregate function in subquery, MyISAM or Aria +# +CREATE TABLE t1 ( a INT ) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1); +SELECT a FROM t1 WHERE ( SELECT MIN(a) = 100 ); +a +drop table t1; # return optimizer switch changed in the beginning of this test set optimizer_switch=@subselect_tmp; diff --git a/mysql-test/r/subselect_no_mat.result b/mysql-test/r/subselect_no_mat.result index ea832b7f7ce..bcd08b70517 100644 --- a/mysql-test/r/subselect_no_mat.result +++ b/mysql-test/r/subselect_no_mat.result @@ -5993,6 +5993,15 @@ SELECT ( SELECT b FROM t2 WHERE b = a OR rand() * 0) FROM t1; 1 NULL drop table t1,t2,t3; +# +# LP BUG#905353 Wrong non-empty result with a constant table, +# aggregate function in subquery, MyISAM or Aria +# +CREATE TABLE t1 ( a INT ) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1); +SELECT a FROM t1 WHERE ( SELECT MIN(a) = 100 ); +a +drop table t1; # return optimizer switch changed in the beginning of this test set optimizer_switch=@subselect_tmp; set optimizer_switch=default; diff --git a/mysql-test/r/subselect_no_opts.result b/mysql-test/r/subselect_no_opts.result index f86955eadcd..a493722fabe 100644 --- a/mysql-test/r/subselect_no_opts.result +++ b/mysql-test/r/subselect_no_opts.result @@ -5989,6 +5989,15 @@ SELECT ( SELECT b FROM t2 WHERE b = a OR rand() * 0) FROM t1; 1 NULL drop table t1,t2,t3; +# +# LP BUG#905353 Wrong non-empty result with a constant table, +# aggregate function in subquery, MyISAM or Aria +# +CREATE TABLE t1 ( a INT ) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1); +SELECT a FROM t1 WHERE ( SELECT MIN(a) = 100 ); +a +drop table t1; # return optimizer switch changed in the beginning of this test set optimizer_switch=@subselect_tmp; set @optimizer_switch_for_subselect_test=null; diff --git a/mysql-test/r/subselect_no_scache.result b/mysql-test/r/subselect_no_scache.result index fa8342da223..e170debd6d2 100644 --- a/mysql-test/r/subselect_no_scache.result +++ b/mysql-test/r/subselect_no_scache.result @@ -6000,6 +6000,15 @@ SELECT ( SELECT b FROM t2 WHERE b = a OR rand() * 0) FROM t1; 1 NULL drop table t1,t2,t3; +# +# LP BUG#905353 Wrong non-empty result with a constant table, +# aggregate function in subquery, MyISAM or Aria +# +CREATE TABLE t1 ( a INT ) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1); +SELECT a FROM t1 WHERE ( SELECT MIN(a) = 100 ); +a +drop table t1; # return optimizer switch changed in the beginning of this test set optimizer_switch=@subselect_tmp; set optimizer_switch=default; diff --git a/mysql-test/r/subselect_no_semijoin.result b/mysql-test/r/subselect_no_semijoin.result index 985f840f7c2..782aba08d26 100644 --- a/mysql-test/r/subselect_no_semijoin.result +++ b/mysql-test/r/subselect_no_semijoin.result @@ -5989,6 +5989,15 @@ SELECT ( SELECT b FROM t2 WHERE b = a OR rand() * 0) FROM t1; 1 NULL drop table t1,t2,t3; +# +# LP BUG#905353 Wrong non-empty result with a constant table, +# aggregate function in subquery, MyISAM or Aria +# +CREATE TABLE t1 ( a INT ) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1); +SELECT a FROM t1 WHERE ( SELECT MIN(a) = 100 ); +a +drop table t1; # return optimizer switch changed in the beginning of this test set optimizer_switch=@subselect_tmp; set @optimizer_switch_for_subselect_test=null; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index b4e79416c40..e9735dae79f 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -5078,6 +5078,17 @@ SELECT ( SELECT b FROM t2 WHERE b = a OR rand() * 0) FROM t1; drop table t1,t2,t3; +--echo # +--echo # LP BUG#905353 Wrong non-empty result with a constant table, +--echo # aggregate function in subquery, MyISAM or Aria +--echo # + +CREATE TABLE t1 ( a INT ) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1); + +SELECT a FROM t1 WHERE ( SELECT MIN(a) = 100 ); + +drop table t1; --echo # return optimizer switch changed in the beginning of this test set optimizer_switch=@subselect_tmp; From 3d61c1399dc74e651030418730da429ee0b4e38a Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 10 Feb 2012 21:19:12 +0100 Subject: [PATCH 081/135] lp:910817: Race condition in kill_threads_for_user() The code was accessing a pointer in a mem_root that might be freed by another concurrent thread. Fix by moving the access to be done while the LOCK_thd_data is held, preventing the memory from being freed too early. --- sql/sql_parse.cc | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 1676d4a09f4..ef0f784e945 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -7363,13 +7363,23 @@ static uint kill_threads_for_user(THD *thd, LEX_USER *user, if (!threads_to_kill.is_empty()) { List_iterator_fast it(threads_to_kill); - THD *ptr; - while ((ptr= it++)) + THD *next_ptr; + THD *ptr= it++; + do { ptr->awake(kill_signal); + /* + Careful here: The list nodes are allocated on the memroots of the + THDs to be awakened. + But those THDs may be terminated and deleted as soon as we release + LOCK_thd_data, which will make the list nodes invalid. + Since the operation "it++" dereferences the "next" pointer of the + previous list node, we need to do this while holding LOCK_thd_data. + */ + next_ptr= it++; pthread_mutex_unlock(&ptr->LOCK_thd_data); (*rows)++; - } + } while ((ptr= next_ptr)); } DBUG_RETURN(0); } From ea45d770af35e95becc83872bcc7c86b2698550f Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Fri, 10 Feb 2012 22:53:46 +0200 Subject: [PATCH 082/135] Fixed that prepared statements are properly igored (if possible) by query cache. --- sql/sql_cache.cc | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index c45234f2cdf..fbe42c85711 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -1659,6 +1659,17 @@ Query_cache::send_result_to_client(THD *thd, char *org_sql, uint query_length) if (is_disabled() || thd->locked_tables || thd->variables.query_cache_type == 0) goto err; + + /* + The following can only happen for prepared statements that was found + during parsing or later that the query was not cacheable. + */ + if (!thd->lex->safe_to_cache_query) + { + DBUG_PRINT("qcache", ("SELECT is non-cacheable")); + goto err; + } + DBUG_ASSERT(query_cache_size != 0); // otherwise cache would be disabled thd->query_cache_is_applicable= 1; @@ -1950,6 +1961,7 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d", faster. */ thd->query_cache_is_applicable= 0; // Query can't be cached + thd->lex->safe_to_cache_query= 0; // For prepared statements BLOCK_UNLOCK_RD(query_block); DBUG_RETURN(-1); } @@ -1966,6 +1978,7 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d", table_list.db, table_list.alias)); unlock(); thd->query_cache_is_applicable= 0; // Query can't be cached + thd->lex->safe_to_cache_query= 0; // For prepared statements BLOCK_UNLOCK_RD(query_block); DBUG_RETURN(-1); // Privilege error } @@ -1975,6 +1988,7 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d", table_list.db, table_list.alias)); BLOCK_UNLOCK_RD(query_block); thd->query_cache_is_applicable= 0; // Query can't be cached + thd->lex->safe_to_cache_query= 0; // For prepared statements goto err_unlock; // Parse query } #endif /*!NO_EMBEDDED_ACCESS_CHECKS*/ @@ -1998,7 +2012,13 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d", table->key_length()); } else + { + /* + As this can change from call to call, don't reset set + thd->lex->safe_to_cache_query + */ thd->query_cache_is_applicable= 0; // Query can't be cached + } goto err_unlock; // Parse query } else @@ -3886,6 +3906,7 @@ Query_cache::process_and_count_tables(THD *thd, TABLE_LIST *tables_used, DBUG_PRINT("qcache", ("Don't cache statement as it refers to " "tables with column privileges.")); thd->query_cache_is_applicable= 0; // Query can't be cached + thd->lex->safe_to_cache_query= 0; // For prepared statements DBUG_RETURN(0); } #endif @@ -4022,6 +4043,10 @@ my_bool Query_cache::ask_handler_allowance(THD *thd, { DBUG_PRINT("qcache", ("Handler does not allow caching for %s.%s", tables_used->db, tables_used->alias)); + /* + As this can change from call to call, don't reset set + thd->lex->safe_to_cache_query + */ thd->query_cache_is_applicable= 0; // Query can't be cached DBUG_RETURN(1); } From b3e15f838955217125476130766551731f1eaa4c Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Sat, 11 Feb 2012 03:25:49 +0100 Subject: [PATCH 083/135] A recent change in the server protocol code broke SSL connection for some client libraries. Protocol documentation (http://forge.mysql.com/wiki/MySQL_Internals_ClientServer_Protocol) says that initial packet sent by client if client wants SSL, consists of client capability flags only (4 bytes or 2 bytes edependent on protocol versionl). Some clients happen to send more in the initial SSL packet (C client, Python connector), while others (Java, .NET) follow the docs and send only client capability flags. A change that broke Java client was a newly introduced check that frst client packet has 32 or more bytes. This is generally wrong, if client capability flags contains CLIENT_SSL. Also, fixed the code such that read max client packet size and charset in the first packet prior to SSL handshake. With SSL, clients do not have to send this info, they can only send client flags. This is now fixed such that max packet size and charset are not read prior to SSL handshake, in case of SSL they are read from the "complete" client authentication packet after SSL initialization. --- sql/sql_connect.cc | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 7dd15ea731f..13e3a823103 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -810,25 +810,12 @@ static int check_connection(THD *thd) thd->client_capabilities= uint2korr(net->read_pos); if (thd->client_capabilities & CLIENT_PROTOCOL_41) { - if (pkt_len < 32) + if (pkt_len < 4) goto error; thd->client_capabilities|= ((ulong) uint2korr(net->read_pos+2)) << 16; - thd->max_client_packet_length= uint4korr(net->read_pos+4); - DBUG_PRINT("info", ("client_character_set: %d", (uint) net->read_pos[8])); - if (thd_init_client_charset(thd, (uint) net->read_pos[8])) - return 1; - thd->update_charset(); - end= (char*) net->read_pos+32; } - else - { - if (pkt_len < 5) - goto error; - thd->max_client_packet_length= uint3korr(net->read_pos+2); - end= (char*) net->read_pos+5; - } /* Disable those bits which are not supported by the server. This is a precautionary measure, if the client lies. See Bug#27944. @@ -861,6 +848,26 @@ static int check_connection(THD *thd) } } #endif /* HAVE_OPENSSL */ + if (thd->client_capabilities & CLIENT_PROTOCOL_41) + { + if (pkt_len < 32) + goto error; + + thd->max_client_packet_length= uint4korr(net->read_pos+4); + DBUG_PRINT("info", ("client_character_set: %d", (uint) net->read_pos[8])); + if (thd_init_client_charset(thd, (uint) net->read_pos[8])) + return 1; + thd->update_charset(); + end= (char*) net->read_pos+32; + } + else + { + if (pkt_len < 5) + goto error; + + thd->max_client_packet_length= uint3korr(net->read_pos+2); + end= (char*) net->read_pos+5; + } if (end >= (char*) net->read_pos+ pkt_len +2) goto error; From 0c265a5eb8962fba6f0be90946ec8af11b44af45 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Sun, 12 Feb 2012 23:02:56 +0100 Subject: [PATCH 084/135] Use newly released HeidiSQL 7.0 in the MSI installer --- win/packaging/heidisql.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/packaging/heidisql.cmake b/win/packaging/heidisql.cmake index 94a287cba08..f826c9a6633 100644 --- a/win/packaging/heidisql.cmake +++ b/win/packaging/heidisql.cmake @@ -1,4 +1,4 @@ -SET(HEIDISQL_BASE_NAME "HeidiSQL_6.0_Portable") +SET(HEIDISQL_BASE_NAME "HeidiSQL_7.0_Portable") SET(HEIDISQL_ZIP "${HEIDISQL_BASE_NAME}.zip") SET(HEIDISQL_URL "http://heidisql.googlecode.com/files/${HEIDISQL_ZIP}") SET(HEIDISQL_DOWNLOAD_DIR ${THIRD_PARTY_DOWNLOAD_LOCATION}/${HEIDISQL_BASE_NAME}) From 27dfa45e7026f6b632863a37b7dece8ecd480b47 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 13 Feb 2012 17:14:10 +0100 Subject: [PATCH 085/135] When we fail during slave thread initialisation, keep mi->run_lock locked until we have finished clean up. Previously, the code released the lock without marking that the thread was running. This allowed a new slave thread to start while the old one was still in the middle of cleaning up, causing assertions and probably general mayhem. --- sql/slave.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sql/slave.cc b/sql/slave.cc index 363c1eb9a17..7935754e25c 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2683,9 +2683,8 @@ pthread_handler_t handle_slave_io(void *arg) if (init_slave_thread(thd, SLAVE_THD_IO)) { pthread_cond_broadcast(&mi->start_cond); - pthread_mutex_unlock(&mi->run_lock); sql_print_error("Failed during slave I/O thread initialization"); - goto err; + goto err_during_init; } pthread_mutex_lock(&LOCK_thread_count); threads.append(thd); @@ -2953,6 +2952,7 @@ err: thd_proc_info(thd, "Waiting for slave mutex on exit"); pthread_mutex_lock(&mi->run_lock); +err_during_init: /* Forget the relay log's format */ delete mi->rli.relay_log.description_event_for_queue; mi->rli.relay_log.description_event_for_queue= 0; @@ -3076,10 +3076,9 @@ pthread_handler_t handle_slave_sql(void *arg) will be stuck if we fail here */ pthread_cond_broadcast(&rli->start_cond); - pthread_mutex_unlock(&rli->run_lock); rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, "Failed during slave thread initialization"); - goto err; + goto err_during_init; } thd->init_for_queries(); thd->temporary_tables = rli->save_temporary_tables; // restore temp tables @@ -3332,6 +3331,7 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \ thd->reset_db(NULL, 0); thd_proc_info(thd, "Waiting for slave mutex on exit"); pthread_mutex_lock(&rli->run_lock); +err_during_init: /* We need data_lock, at least to wake up any waiting master_pos_wait() */ pthread_mutex_lock(&rli->data_lock); DBUG_ASSERT(rli->slave_running == 1); // tracking buffer overrun From c8bbe06ac7fd536b3e756afc0e2e8c8dc0724119 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Mon, 13 Feb 2012 23:46:57 -0800 Subject: [PATCH 086/135] Fixed LP bug #925985. If the flag 'optimize_join_buffer_size' is set to 'off' and the value of the system variable 'join_buffer_size' is greater than the value of the system variable 'join_buffer_space_limit' than no join cache can be employed to join tables of the executed query. A bug in the function JOIN_CACHE::alloc_buffer allowed to use join buffer even in this case while another bug in the function revise_cache_usage could cause a crash of the server in this case if the chosen execution plan for the query contained outer join or semi-join operation. --- mysql-test/r/join_cache.result | 35 ++++++++++++++++++++++++++++++++++ mysql-test/t/join_cache.test | 35 ++++++++++++++++++++++++++++++++++ sql/sql_join_cache.cc | 2 ++ sql/sql_select.cc | 4 ++-- 4 files changed, 74 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/join_cache.result b/mysql-test/r/join_cache.result index 11114a032f9..dda0f4c8f66 100644 --- a/mysql-test/r/join_cache.result +++ b/mysql-test/r/join_cache.result @@ -5534,4 +5534,39 @@ we set join_cache_level = default; set optimizer_switch=@tmp_optimizer_switch; DROP TABLE t1,t2,t3; +# +# Bug #925985: LEFT JOIN with optimize_join_buffer_size=off + +# join_buffer_size > join_buffer_space_limit +# +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (5), (3); +CREATE TABLE t2 (a int, b int); +INSERT INTO t2 VALUES +(3,30), (1,10), (7,70), (2,20), +(3,31), (1,11), (7,71), (2,21), +(3,32), (1,12), (7,72), (2,22); +CREATE TABLE t3 (b int, c int); +INSERT INTO t3 VALUES (32, 302), (42,400), (30,300); +set @tmp_optimizer_switch=@@optimizer_switch; +set optimizer_switch='optimize_join_buffer_size=off'; +set join_buffer_space_limit=4096; +set join_buffer_size=4096*2; +set join_cache_level=2; +set optimizer_switch='outer_join_with_cache=on'; +EXPLAIN +SELECT * FROM t1, t2 LEFT JOIN t3 ON t2.b=t3.b WHERE t1.a=t2.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 +1 SIMPLE t2 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t3 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (incremental, BNL join) +SELECT * FROM t1, t2 LEFT JOIN t3 ON t2.b=t3.b WHERE t1.a=t2.a; +a a b b c +3 3 30 30 300 +3 3 31 NULL NULL +3 3 32 32 302 +set join_buffer_space_limit=default; +set join_buffer_size=default; +set join_cache_level=default; +set optimizer_switch=@tmp_optimizer_switch; +DROP TABLE t1,t2,t3; set @@optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/t/join_cache.test b/mysql-test/t/join_cache.test index 8a61c00b7d4..9d7b07f6b9e 100644 --- a/mysql-test/t/join_cache.test +++ b/mysql-test/t/join_cache.test @@ -3547,5 +3547,40 @@ set optimizer_switch=@tmp_optimizer_switch; DROP TABLE t1,t2,t3; +--echo # +--echo # Bug #925985: LEFT JOIN with optimize_join_buffer_size=off + +--echo # join_buffer_size > join_buffer_space_limit +--echo # + +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (5), (3); + +CREATE TABLE t2 (a int, b int); +INSERT INTO t2 VALUES + (3,30), (1,10), (7,70), (2,20), + (3,31), (1,11), (7,71), (2,21), + (3,32), (1,12), (7,72), (2,22); + +CREATE TABLE t3 (b int, c int); +INSERT INTO t3 VALUES (32, 302), (42,400), (30,300); + +set @tmp_optimizer_switch=@@optimizer_switch; +set optimizer_switch='optimize_join_buffer_size=off'; +set join_buffer_space_limit=4096; +set join_buffer_size=4096*2; +set join_cache_level=2; +set optimizer_switch='outer_join_with_cache=on'; + +EXPLAIN +SELECT * FROM t1, t2 LEFT JOIN t3 ON t2.b=t3.b WHERE t1.a=t2.a; +SELECT * FROM t1, t2 LEFT JOIN t3 ON t2.b=t3.b WHERE t1.a=t2.a; + +set join_buffer_space_limit=default; +set join_buffer_size=default; +set join_cache_level=default; +set optimizer_switch=@tmp_optimizer_switch; + +DROP TABLE t1,t2,t3; + # this must be the last command in the file set @@optimizer_switch=@save_optimizer_switch; diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc index 2a8db8b4fd1..78f95a7ac7e 100644 --- a/sql/sql_join_cache.cc +++ b/sql/sql_join_cache.cc @@ -898,6 +898,8 @@ int JOIN_CACHE::alloc_buffer() curr_buff_space_sz+= cache->get_join_buffer_size(); } } + curr_min_buff_space_sz+= min_buff_size; + curr_buff_space_sz+= buff_size; if (curr_min_buff_space_sz > join_buff_space_limit || (curr_buff_space_sz > join_buff_space_limit && diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 05fba45792b..aa1090fb03b 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -8903,7 +8903,7 @@ void revise_cache_usage(JOIN_TAB *join_tab) first_inner; first_inner= first_inner->first_upper) { - for (tab= end_tab-1; tab >= first_inner; tab--) + for (tab= end_tab; tab >= first_inner; tab--) set_join_cache_denial(tab); end_tab= first_inner; } @@ -8911,7 +8911,7 @@ void revise_cache_usage(JOIN_TAB *join_tab) else if (join_tab->first_sj_inner_tab) { first_inner= join_tab->first_sj_inner_tab; - for (tab= join_tab-1; tab >= first_inner; tab--) + for (tab= join_tab; tab >= first_inner; tab--) { set_join_cache_denial(tab); } From c9355dc279ac30cc41ff076d20414fd59c36091d Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Tue, 14 Feb 2012 13:58:57 +0400 Subject: [PATCH 087/135] BUG#928048: Query containing IN subquery with OR in the where clause returns a wrong result - Make equality propagation work correctly when done inside the OR branches --- mysql-test/r/subselect_mat.result | 17 +++++++++++++++++ mysql-test/r/subselect_sj_mat.result | 18 ++++++++++++++++++ mysql-test/t/subselect_sj_mat.test | 17 +++++++++++++++++ sql/sql_select.cc | 7 ++++--- 4 files changed, 56 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/subselect_mat.result b/mysql-test/r/subselect_mat.result index 009510276b5..6f90cc868a6 100644 --- a/mysql-test/r/subselect_mat.result +++ b/mysql-test/r/subselect_mat.result @@ -1831,6 +1831,23 @@ id select_type table type possible_keys key key_len ref rows Extra 3 MATERIALIZED alias3 ALL NULL NULL NULL NULL 2 3 MATERIALIZED alias4 index c c 11 NULL 2 Using where; Using index; Using join buffer (flat, BNL join) DROP TABLE t1,t2; +# +# BUG#928048: Query containing IN subquery with OR in the where clause returns a wrong result +# +create table t1 (a int, b int); +insert into t1 values (7,5), (3,3), (5,4), (9,3); +create table t2 (a int, b int, index i_a(a)); +insert into t2 values +(4,2), (7,9), (7,4), (3,1), (5,3), (3,1), (9,4), (8,1); +explain select * from t1 where t1.a in (select a from t2 where t2.a=7 or t2.b<=1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where +2 MATERIALIZED t2 ALL i_a NULL NULL NULL 8 Using where +select * from t1 where t1.a in (select a from t2 where t2.a=7 or t2.b<=1); +a b +7 5 +3 3 +drop table t1,t2; # This must be at the end: set optimizer_switch=@subselect_sj_mat_tmp; set join_cache_level=@save_join_cache_level; diff --git a/mysql-test/r/subselect_sj_mat.result b/mysql-test/r/subselect_sj_mat.result index 44fb9c61f24..964df6735f8 100644 --- a/mysql-test/r/subselect_sj_mat.result +++ b/mysql-test/r/subselect_sj_mat.result @@ -1867,6 +1867,24 @@ WHERE alias4.c = alias3.b 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 DROP TABLE t1,t2; +# +# BUG#928048: Query containing IN subquery with OR in the where clause returns a wrong result +# +create table t1 (a int, b int); +insert into t1 values (7,5), (3,3), (5,4), (9,3); +create table t2 (a int, b int, index i_a(a)); +insert into t2 values +(4,2), (7,9), (7,4), (3,1), (5,3), (3,1), (9,4), (8,1); +explain select * from t1 where t1.a in (select a from t2 where t2.a=7 or t2.b<=1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 +1 PRIMARY eq_ref distinct_key distinct_key 5 func 1 +2 MATERIALIZED t2 ALL i_a NULL NULL NULL 8 Using where +select * from t1 where t1.a in (select a from t2 where t2.a=7 or t2.b<=1); +a b +7 5 +3 3 +drop table t1,t2; # This must be at the end: set optimizer_switch=@subselect_sj_mat_tmp; set join_cache_level=@save_join_cache_level; diff --git a/mysql-test/t/subselect_sj_mat.test b/mysql-test/t/subselect_sj_mat.test index 80ba42e7bab..0840029c5e0 100644 --- a/mysql-test/t/subselect_sj_mat.test +++ b/mysql-test/t/subselect_sj_mat.test @@ -1529,6 +1529,23 @@ WHERE b = a AND a IN ( DROP TABLE t1,t2; +--echo # +--echo # BUG#928048: Query containing IN subquery with OR in the where clause returns a wrong result +--echo # +create table t1 (a int, b int); +insert into t1 values (7,5), (3,3), (5,4), (9,3); + +create table t2 (a int, b int, index i_a(a)); + +insert into t2 values + (4,2), (7,9), (7,4), (3,1), (5,3), (3,1), (9,4), (8,1); + +explain select * from t1 where t1.a in (select a from t2 where t2.a=7 or t2.b<=1); +select * from t1 where t1.a in (select a from t2 where t2.a=7 or t2.b<=1); + +drop table t1,t2; + + --echo # This must be at the end: set optimizer_switch=@subselect_sj_mat_tmp; set join_cache_level=@save_join_cache_level; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 05fba45792b..292ed9439e4 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -11490,7 +11490,7 @@ Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels, } /* - Check if "item_field=head" equality is already guaranteed to be true + Check if "field_item=head" equality is already guaranteed to be true on upper AND-levels. */ if (upper) @@ -11502,7 +11502,8 @@ Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels, Item_equal_fields_iterator li(*item_equal); while ((item= li++) != field_item) { - if (item->find_item_equal(upper_levels) == upper) + if (embedding_sjm(item) == field_sjm && + item->find_item_equal(upper_levels) == upper) break; } } @@ -11646,7 +11647,7 @@ static COND* substitute_for_best_equal_field(JOIN_TAB *context_tab, if (and_level) { cond_equal= &((Item_cond_and *) cond)->cond_equal; - cond_list->disjoin((List *) &cond_equal->current_level); + cond_list->disjoin((List *) &cond_equal->current_level);/* remove Item_equal objects from the AND. */ List_iterator_fast it(cond_equal->current_level); while ((item_equal= it++)) From 7ab53e80627e54c6dece486bf0b059436b7e5777 Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Tue, 14 Feb 2012 16:04:06 +0400 Subject: [PATCH 088/135] MDEV-59 Review and push crashsafe GIS keys. tests for RTree keys recovery. --- .../suite/maria/r/maria-gis-recovery.result | 64 +++++++++++++++++++ .../maria/t/maria-gis-recovery-master.opt | 1 + .../suite/maria/t/maria-gis-recovery.test | 64 +++++++++++++++++++ 3 files changed, 129 insertions(+) create mode 100644 mysql-test/suite/maria/r/maria-gis-recovery.result create mode 100644 mysql-test/suite/maria/t/maria-gis-recovery-master.opt create mode 100644 mysql-test/suite/maria/t/maria-gis-recovery.test diff --git a/mysql-test/suite/maria/r/maria-gis-recovery.result b/mysql-test/suite/maria/r/maria-gis-recovery.result new file mode 100644 index 00000000000..ca406fc46e5 --- /dev/null +++ b/mysql-test/suite/maria/r/maria-gis-recovery.result @@ -0,0 +1,64 @@ +set global aria_log_file_size=4294967295; +drop database if exists mysqltest; +create database mysqltest; +use mysqltest; +* shut down mysqld, removed logs, restarted it +CREATE TABLE t1 ( +i int, +shape GEOMETRY NOT NULL, +SPATIAL (shape) +) ENGINE=ARIA; +insert into t1 values(1,POINT(1, 1)); +* copied t1 for feeding_recovery +insert into t1 values(2,POINT(2, 2)), (3,POINT(3, 3)), (4,POINT(4, 4)); +flush table t1; +* copied t1 for comparison +SET SESSION debug="+d,maria_flush_whole_log,maria_crash"; +* crashing mysqld intentionally +set global aria_checkpoint_interval=1; +ERROR HY000: Lost connection to MySQL server during query +* copied t1 back for feeding_recovery +* recovery happens +check table t1 extended; +Table Op Msg_type Msg_text +mysqltest.t1 check status OK +* testing that checksum after recovery is as expected +Checksum-check +ok +use mysqltest; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) DEFAULT NULL, + `shape` geometry NOT NULL, + SPATIAL KEY `shape` (`shape`) +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +* TEST of UPDATE vs state.auto_increment +* copied t1 for feeding_recovery +update t1 set shape=POINT(5, 5) where i=2; +flush table t1; +* copied t1 for comparison +SET SESSION debug="+d,maria_flush_whole_log,maria_crash"; +* crashing mysqld intentionally +set global aria_checkpoint_interval=1; +ERROR HY000: Lost connection to MySQL server during query +* copied t1 back for feeding_recovery +* recovery happens +check table t1 extended; +Table Op Msg_type Msg_text +mysqltest.t1 check status OK +* testing that checksum after recovery is as expected +Checksum-check +ok +use mysqltest; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) DEFAULT NULL, + `shape` geometry NOT NULL, + SPATIAL KEY `shape` (`shape`) +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +drop table t1; +drop database mysqltest_for_feeding_recovery; +drop database mysqltest_for_comparison; +drop database mysqltest; diff --git a/mysql-test/suite/maria/t/maria-gis-recovery-master.opt b/mysql-test/suite/maria/t/maria-gis-recovery-master.opt new file mode 100644 index 00000000000..58d0d012c54 --- /dev/null +++ b/mysql-test/suite/maria/t/maria-gis-recovery-master.opt @@ -0,0 +1 @@ +--skip-stack-trace --skip-core-file --loose-aria-log-dir-path=$MYSQLTEST_VARDIR/tmp diff --git a/mysql-test/suite/maria/t/maria-gis-recovery.test b/mysql-test/suite/maria/t/maria-gis-recovery.test new file mode 100644 index 00000000000..c40cc3788de --- /dev/null +++ b/mysql-test/suite/maria/t/maria-gis-recovery.test @@ -0,0 +1,64 @@ +--source include/not_embedded.inc +# Don't test this under valgrind, memory leaks will occur as we crash +--source include/not_valgrind.inc +# Binary must be compiled with debug for crash to occur +--source include/have_debug.inc +--source include/have_maria.inc +--source include/have_geometry.inc + +set global aria_log_file_size=4294967295; +let $MARIA_LOG=../../tmp; + +--disable_warnings +drop database if exists mysqltest; +--enable_warnings +create database mysqltest; +let $mms_tname=t; + +# Include scripts can perform SQL. For it to not influence the main test +# they use a separate connection. This way if they use a DDL it would +# not autocommit in the main test. +connect (admin, localhost, root,,mysqltest,,); +--enable_reconnect + +connection default; +use mysqltest; +--enable_reconnect + +-- source include/maria_empty_logs.inc +let $mms_tables=1; +CREATE TABLE t1 ( + i int, + shape GEOMETRY NOT NULL, + SPATIAL (shape) +) ENGINE=ARIA; +insert into t1 values(1,POINT(1, 1)); +-- source include/maria_make_snapshot_for_feeding_recovery.inc +insert into t1 values(2,POINT(2, 2)), (3,POINT(3, 3)), (4,POINT(4, 4)); +-- source include/maria_make_snapshot_for_comparison.inc +let $mvr_restore_old_snapshot=1; +let $mms_compare_physically=0; +let $mvr_debug_option="+d,maria_flush_whole_log,maria_crash"; +let $mvr_crash_statement= set global aria_checkpoint_interval=1; +-- source include/maria_verify_recovery.inc +show create table t1; + +# Test that UPDATE's effect on auto-increment is recovered +--echo * TEST of UPDATE vs state.auto_increment +-- source include/maria_make_snapshot_for_feeding_recovery.inc +update t1 set shape=POINT(5, 5) where i=2; +-- source include/maria_make_snapshot_for_comparison.inc +let $mvr_restore_old_snapshot=1; +let $mms_compare_physically=0; +let $mvr_debug_option="+d,maria_flush_whole_log,maria_crash"; +let $mvr_crash_statement= set global aria_checkpoint_interval=1; +-- source include/maria_verify_recovery.inc +show create table t1; +drop table t1; + +# clean up everything +let $mms_purpose=feeding_recovery; +eval drop database mysqltest_for_$mms_purpose; +let $mms_purpose=comparison; +eval drop database mysqltest_for_$mms_purpose; +drop database mysqltest; From 764eeeee74f999fe2107fc362236563be0025093 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 14 Feb 2012 16:52:56 +0200 Subject: [PATCH 089/135] Fix for LP BUG#910123 MariaDB 5.3.3 causes 1093 error on Drupal Problem was that now we can merge derived table (subquery in the FROM clause). Fix: in case of detected conflict and presence of derived table "over" the table which cased the conflict - try materialization strategy. --- mysql-test/r/derived_opt.result | 9 +++++++++ mysql-test/t/derived_opt.test | 10 ++++++++++ sql/sql_base.cc | 22 ++++++++++++++++++---- sql/sql_lex.cc | 1 + sql/sql_union.cc | 1 + sql/table.cc | 33 ++++++++++++++++++++++++++++++++- sql/table.h | 14 +++++++++++--- 7 files changed, 82 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/derived_opt.result b/mysql-test/r/derived_opt.result index 721d4277775..c5376bee756 100644 --- a/mysql-test/r/derived_opt.result +++ b/mysql-test/r/derived_opt.result @@ -273,4 +273,13 @@ ON alias3.f4 != 0 ) ON alias3.f4 != 0; f4 f4 f2 f4 drop table t1,t2,t3,t4; +# +# LP BUG#910123 MariaDB 5.3.3 causes 1093 error on Drupal +# Fix: force materialization in case of conflict +# +SET optimizer_switch='derived_merge=on'; +CREATE TABLE t1 ( i INT ); +INSERT INTO t1 VALUES ( (SELECT 1 FROM ( SELECT * FROM t1 ) as a) ); +drop table t1; +set optimizer_switch=@save_optimizer_switch; set optimizer_switch=@exit_optimizer_switch; diff --git a/mysql-test/t/derived_opt.test b/mysql-test/t/derived_opt.test index 42f3ce296e1..c2f831036e1 100644 --- a/mysql-test/t/derived_opt.test +++ b/mysql-test/t/derived_opt.test @@ -202,5 +202,15 @@ RIGHT JOIN ( drop table t1,t2,t3,t4; +--echo # +--echo # LP BUG#910123 MariaDB 5.3.3 causes 1093 error on Drupal +--echo # Fix: force materialization in case of conflict +--echo # +SET optimizer_switch='derived_merge=on'; +CREATE TABLE t1 ( i INT ); +INSERT INTO t1 VALUES ( (SELECT 1 FROM ( SELECT * FROM t1 ) as a) ); +drop table t1; +set optimizer_switch=@save_optimizer_switch; + # The following command must be the last one the file set optimizer_switch=@exit_optimizer_switch; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 9c5d251c728..11fd5db2020 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1707,11 +1707,12 @@ TABLE_LIST* unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list, t_name= table->table_name; t_alias= table->alias; +retry: DBUG_PRINT("info", ("real table: %s.%s", d_name, t_name)); - for (;;) + for (TABLE_LIST *tl= table_list;;) { - if (((! (res= find_table_in_global_list(table_list, d_name, t_name))) && - (! (res= mysql_lock_have_duplicate(thd, table, table_list)))) || + if (((! (res= find_table_in_global_list(tl, d_name, t_name))) && + (! (res= mysql_lock_have_duplicate(thd, table, tl)))) || ((!res->table || res->table != table->table) && (!check_alias || !(lower_case_table_names ? my_strcasecmp(files_charset_info, t_alias, res->alias) : @@ -1724,10 +1725,23 @@ TABLE_LIST* unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list, processed in derived table or top select of multi-update/multi-delete (exclude_from_table_unique_test) or prelocking placeholder. */ - table_list= res->next_global; + tl= res->next_global; DBUG_PRINT("info", ("found same copy of table or table which we should skip")); } + if (res && res->belong_to_derived) + { + /* Try to fix */ + TABLE_LIST *derived= res->belong_to_derived; + if (derived->is_merged_derived()) + { + DBUG_PRINT("info", + ("convert merged to materialization to resolve the conflict")); + derived->change_refs_to_fields(); + derived->set_materialized_derived(); + } + goto retry; + } DBUG_RETURN(res); } diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index f29f51325a9..4a69cd3b1fa 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -2885,6 +2885,7 @@ void st_lex::cleanup_after_one_table_open() if (all_selects_list != &select_lex) { derived_tables= 0; + select_lex.exclude_from_table_unique_test= false; /* cleunup underlying units (units of VIEW) */ for (SELECT_LEX_UNIT *un= select_lex.first_inner_unit(); un; diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 90d9405ebe5..599dc993483 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -961,6 +961,7 @@ bool st_select_lex::cleanup() } non_agg_fields.empty(); inner_refs_list.empty(); + exclude_from_table_unique_test= FALSE; DBUG_RETURN(error); } diff --git a/sql/table.cc b/sql/table.cc index f1ff353a8c4..13e643f015b 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -4378,6 +4378,36 @@ bool TABLE_LIST::prepare_security(THD *thd) DBUG_RETURN(FALSE); } +#ifndef DBUG_OFF +void TABLE_LIST::set_check_merged() +{ + DBUG_ASSERT(derived); + /* + It is not simple to check all, but at least this should be checked: + this select is not excluded or the exclusion came from above. + */ + DBUG_ASSERT(!derived->first_select()->exclude_from_table_unique_test || + derived->outer_select()-> + exclude_from_table_unique_test); +} +#endif + +void TABLE_LIST::set_check_materialized() +{ + DBUG_ASSERT(derived); + if (!derived->first_select()->exclude_from_table_unique_test) + derived->set_unique_exclude(); + else + { + /* + The subtree should be already excluded + */ + DBUG_ASSERT(!derived->first_select()->first_inner_unit() || + derived->first_select()->first_inner_unit()->first_select()-> + exclude_from_table_unique_test); + } +} + Natural_join_column::Natural_join_column(Field_translator *field_param, TABLE_LIST *tab) @@ -5919,8 +5949,9 @@ bool TABLE_LIST::init_derived(THD *thd, bool init_view) */ if (is_materialized_derived()) { - unit->master_unit()->set_unique_exclude(); + set_check_materialized(); } + /* Create field translation for mergeable derived tables/views. For derived tables field translation can be created only after diff --git a/sql/table.h b/sql/table.h index 8d91804eb06..8de71658493 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1747,16 +1747,18 @@ struct TABLE_LIST inline void set_merged_derived() { derived_type= ((derived_type & DTYPE_MASK) | - DTYPE_TABLE | DTYPE_MERGE); + DTYPE_TABLE | DTYPE_MERGE); + set_check_merged(); } inline bool is_materialized_derived() { return (derived_type & DTYPE_MATERIALIZE); } - inline void set_materialized_derived() + void set_materialized_derived() { derived_type= ((derived_type & DTYPE_MASK) | - DTYPE_TABLE | DTYPE_MATERIALIZE); + DTYPE_TABLE | DTYPE_MATERIALIZE); + set_check_materialized(); } inline bool is_multitable() { @@ -1802,6 +1804,12 @@ struct TABLE_LIST private: bool prep_check_option(THD *thd, uint8 check_opt_type); bool prep_where(THD *thd, Item **conds, bool no_where_clause); + void set_check_materialized(); +#ifndef DBUG_OFF + void set_check_merged(); +#else + inline void set_check_merged() {} +#endif /* Cleanup for re-execution in a prepared statement or a stored procedure. From 607aab9c1d68a3b80bdb52a6c73fd6be1aa52764 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 16 Feb 2012 08:49:10 +0200 Subject: [PATCH 090/135] Counters for Index Condition Pushdown added (MDEV-130). --- mysql-test/include/icp_tests.inc | 22 ++++++++++++++++++++++ mysql-test/r/innodb_icp.result | 27 +++++++++++++++++++++++++++ mysql-test/r/join_cache.result | 17 +++++++++++++++++ mysql-test/r/maria_icp.result | 27 +++++++++++++++++++++++++++ mysql-test/r/myisam_icp.result | 27 +++++++++++++++++++++++++++ mysql-test/r/status.result | 6 +++++- mysql-test/r/status_user.result | 2 ++ mysql-test/t/join_cache.test | 5 +++++ sql/mysqld.cc | 2 ++ sql/sql_class.h | 2 ++ sql/sql_join_cache.cc | 22 ++++++++++++++++++++-- sql/sql_join_cache.h | 2 ++ storage/maria/ha_maria.cc | 8 +++++++- storage/myisam/ha_myisam.cc | 8 +++++++- storage/xtradb/handler/ha_innodb.cc | 8 +++++++- storage/xtradb/handler/ha_innodb.h | 2 ++ 16 files changed, 181 insertions(+), 6 deletions(-) diff --git a/mysql-test/include/icp_tests.inc b/mysql-test/include/icp_tests.inc index e77cb220375..f412843ded0 100644 --- a/mysql-test/include/icp_tests.inc +++ b/mysql-test/include/icp_tests.inc @@ -852,3 +852,25 @@ SET optimizer_switch=@save_optimizer_switch; DROP TABLE t1,t2; +--echo # check "Handler_pushed" status varuiables +CREATE TABLE t1 ( + c1 CHAR(1), + c2 CHAR(1), + KEY (c1) +); + +INSERT INTO t1 VALUES ('3', '3'),('4','4'),('5','5'); + +flush status; +show status like "Handler_pushed%"; + +SELECT * FROM t1 FORCE INDEX(c1) WHERE (c1='3' or c1='4') and c1 % 2 = 0 ; + +show status like "Handler_pushed%"; + +SELECT * FROM t1 WHERE (c2='3' or c2='4') and c2 % 2 = 0 ; + +show status like "Handler_pushed%"; + +DROP TABLE t1; + diff --git a/mysql-test/r/innodb_icp.result b/mysql-test/r/innodb_icp.result index 08238289330..ccbae98d137 100644 --- a/mysql-test/r/innodb_icp.result +++ b/mysql-test/r/innodb_icp.result @@ -808,5 +808,32 @@ COUNT(*) 1478 SET optimizer_switch=@save_optimizer_switch; DROP TABLE t1,t2; +# check "Handler_pushed" status varuiables +CREATE TABLE t1 ( +c1 CHAR(1), +c2 CHAR(1), +KEY (c1) +); +INSERT INTO t1 VALUES ('3', '3'),('4','4'),('5','5'); +flush status; +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 0 +Handler_pushed_index_cond_filtered 0 +SELECT * FROM t1 FORCE INDEX(c1) WHERE (c1='3' or c1='4') and c1 % 2 = 0 ; +c1 c2 +4 4 +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 2 +Handler_pushed_index_cond_filtered 1 +SELECT * FROM t1 WHERE (c2='3' or c2='4') and c2 % 2 = 0 ; +c1 c2 +4 4 +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 2 +Handler_pushed_index_cond_filtered 1 +DROP TABLE t1; set optimizer_switch=@innodb_icp_tmp; set storage_engine= @save_storage_engine; diff --git a/mysql-test/r/join_cache.result b/mysql-test/r/join_cache.result index dda0f4c8f66..6908f40e854 100644 --- a/mysql-test/r/join_cache.result +++ b/mysql-test/r/join_cache.result @@ -3506,6 +3506,7 @@ insert into t2 values (2,1, 'qwerty'),(2,2, 'qwerty'),(2,3, 'qwerty'), insert into t2 values (3,1, 'qwerty'),(3,4, 'qwerty'); insert into t2 values (4,1, 'qwerty'),(4,2, 'qwerty'),(4,3, 'qwerty'), (4,4, 'qwerty'); +flush status; set join_cache_level=5; select t2.f1, t2.f2, t2.f3 from t1,t2 where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1; @@ -3519,6 +3520,10 @@ where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where 1 SIMPLE t2 ref f1 f1 4 test.t1.f1 3 Using index condition(BKA); Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 20 +Handler_pushed_index_cond_filtered 16 set join_cache_level=6; select t2.f1, t2.f2, t2.f3 from t1,t2 where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1; @@ -3532,6 +3537,10 @@ where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where 1 SIMPLE t2 ref f1 f1 4 test.t1.f1 3 Using index condition(BKA); Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 40 +Handler_pushed_index_cond_filtered 32 set join_cache_level=7; select t2.f1, t2.f2, t2.f3 from t1,t2 where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1; @@ -3545,6 +3554,10 @@ where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where 1 SIMPLE t2 ref f1 f1 4 test.t1.f1 3 Using index condition(BKA); Using where; Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 60 +Handler_pushed_index_cond_filtered 48 set join_cache_level=8; select t2.f1, t2.f2, t2.f3 from t1,t2 where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1; @@ -3558,6 +3571,10 @@ where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where 1 SIMPLE t2 ref f1 f1 4 test.t1.f1 3 Using index condition(BKA); Using where; Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 80 +Handler_pushed_index_cond_filtered 64 drop table t1,t2; set join_cache_level=default; # diff --git a/mysql-test/r/maria_icp.result b/mysql-test/r/maria_icp.result index 2d2b4d0c1f7..b9d3ca6c7c0 100644 --- a/mysql-test/r/maria_icp.result +++ b/mysql-test/r/maria_icp.result @@ -814,5 +814,32 @@ COUNT(*) 1478 SET optimizer_switch=@save_optimizer_switch; DROP TABLE t1,t2; +# check "Handler_pushed" status varuiables +CREATE TABLE t1 ( +c1 CHAR(1), +c2 CHAR(1), +KEY (c1) +); +INSERT INTO t1 VALUES ('3', '3'),('4','4'),('5','5'); +flush status; +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 0 +Handler_pushed_index_cond_filtered 0 +SELECT * FROM t1 FORCE INDEX(c1) WHERE (c1='3' or c1='4') and c1 % 2 = 0 ; +c1 c2 +4 4 +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 2 +Handler_pushed_index_cond_filtered 1 +SELECT * FROM t1 WHERE (c2='3' or c2='4') and c2 % 2 = 0 ; +c1 c2 +4 4 +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 2 +Handler_pushed_index_cond_filtered 1 +DROP TABLE t1; set storage_engine= @save_storage_engine; set optimizer_switch=@maria_icp_tmp; diff --git a/mysql-test/r/myisam_icp.result b/mysql-test/r/myisam_icp.result index c480e35df42..3171753adb4 100644 --- a/mysql-test/r/myisam_icp.result +++ b/mysql-test/r/myisam_icp.result @@ -812,6 +812,33 @@ COUNT(*) 1478 SET optimizer_switch=@save_optimizer_switch; DROP TABLE t1,t2; +# check "Handler_pushed" status varuiables +CREATE TABLE t1 ( +c1 CHAR(1), +c2 CHAR(1), +KEY (c1) +); +INSERT INTO t1 VALUES ('3', '3'),('4','4'),('5','5'); +flush status; +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 0 +Handler_pushed_index_cond_filtered 0 +SELECT * FROM t1 FORCE INDEX(c1) WHERE (c1='3' or c1='4') and c1 % 2 = 0 ; +c1 c2 +4 4 +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 2 +Handler_pushed_index_cond_filtered 1 +SELECT * FROM t1 WHERE (c2='3' or c2='4') and c2 % 2 = 0 ; +c1 c2 +4 4 +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 2 +Handler_pushed_index_cond_filtered 1 +DROP TABLE t1; drop table if exists t0, t1, t1i, t1m; # # BUG#826935 Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed diff --git a/mysql-test/r/status.result b/mysql-test/r/status.result index b0744726390..e75cabe0e58 100644 --- a/mysql-test/r/status.result +++ b/mysql-test/r/status.result @@ -276,6 +276,8 @@ Handler_commit 0 Handler_delete 0 Handler_discover 0 Handler_prepare 0 +Handler_pushed_index_cond_checks 0 +Handler_pushed_index_cond_filtered 0 Handler_read_first 0 Handler_read_key 4 Handler_read_next 0 @@ -297,7 +299,7 @@ Created_tmp_files 0 Created_tmp_tables 2 Handler_tmp_update 2 Handler_tmp_write 7 -Rows_tmp_read 35 +Rows_tmp_read 37 drop table t1; CREATE TABLE t1 (i int(11) DEFAULT NULL, KEY i (i) ) ENGINE=MyISAM; insert into t1 values (1),(2),(3),(4),(5); @@ -311,6 +313,8 @@ Handler_commit 0 Handler_delete 0 Handler_discover 0 Handler_prepare 0 +Handler_pushed_index_cond_checks 0 +Handler_pushed_index_cond_filtered 0 Handler_read_first 0 Handler_read_key 2 Handler_read_next 2 diff --git a/mysql-test/r/status_user.result b/mysql-test/r/status_user.result index 17c44df1d3c..175839b2098 100644 --- a/mysql-test/r/status_user.result +++ b/mysql-test/r/status_user.result @@ -101,6 +101,8 @@ Handler_commit 19 Handler_delete 1 Handler_discover 0 Handler_prepare 18 +Handler_pushed_index_cond_checks 0 +Handler_pushed_index_cond_filtered 0 Handler_read_first 0 Handler_read_key 3 Handler_read_next 0 diff --git a/mysql-test/t/join_cache.test b/mysql-test/t/join_cache.test index 9d7b07f6b9e..6cb8f48bd70 100644 --- a/mysql-test/t/join_cache.test +++ b/mysql-test/t/join_cache.test @@ -1526,12 +1526,14 @@ insert into t2 values (3,1, 'qwerty'),(3,4, 'qwerty'); insert into t2 values (4,1, 'qwerty'),(4,2, 'qwerty'),(4,3, 'qwerty'), (4,4, 'qwerty'); +flush status; set join_cache_level=5; select t2.f1, t2.f2, t2.f3 from t1,t2 where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1; explain select t2.f1, t2.f2, t2.f3 from t1,t2 where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2; +show status like "Handler_pushed%"; set join_cache_level=6; select t2.f1, t2.f2, t2.f3 from t1,t2 @@ -1539,6 +1541,7 @@ where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1; explain select t2.f1, t2.f2, t2.f3 from t1,t2 where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2; +show status like "Handler_pushed%"; set join_cache_level=7; select t2.f1, t2.f2, t2.f3 from t1,t2 @@ -1546,6 +1549,7 @@ where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1; explain select t2.f1, t2.f2, t2.f3 from t1,t2 where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2; +show status like "Handler_pushed%"; set join_cache_level=8; select t2.f1, t2.f2, t2.f3 from t1,t2 @@ -1553,6 +1557,7 @@ where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1; explain select t2.f1, t2.f2, t2.f3 from t1,t2 where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2; +show status like "Handler_pushed%"; drop table t1,t2; set join_cache_level=default; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 109d0220a4a..4e2fa473b8d 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -8291,6 +8291,8 @@ SHOW_VAR status_vars[]= { {"Handler_mrr_init", (char*) offsetof(STATUS_VAR, ha_multi_range_read_init_count), SHOW_LONG_STATUS}, #endif {"Handler_prepare", (char*) offsetof(STATUS_VAR, ha_prepare_count), SHOW_LONG_STATUS}, + {"Handler_pushed_index_cond_checks",(char*) offsetof(STATUS_VAR, ha_pushed_index_cond_checks), SHOW_LONG_STATUS}, + {"Handler_pushed_index_cond_filtered",(char*) offsetof(STATUS_VAR, ha_pushed_index_cond_filtered), SHOW_LONG_STATUS}, {"Handler_read_first", (char*) offsetof(STATUS_VAR, ha_read_first_count), SHOW_LONG_STATUS}, {"Handler_read_key", (char*) offsetof(STATUS_VAR, ha_read_key_count), SHOW_LONG_STATUS}, {"Handler_read_next", (char*) offsetof(STATUS_VAR, ha_read_next_count), SHOW_LONG_STATUS}, diff --git a/sql/sql_class.h b/sql/sql_class.h index 58af7888385..c04af55a127 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -588,6 +588,8 @@ typedef struct system_status_var ulong ha_tmp_update_count; ulong ha_tmp_write_count; ulong ha_prepare_count; + ulong ha_pushed_index_cond_checks; + ulong ha_pushed_index_cond_filtered; ulong ha_discover_count; ulong ha_savepoint_count; ulong ha_savepoint_rollback_count; diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc index 78f95a7ac7e..15b5efbfacb 100644 --- a/sql/sql_join_cache.cc +++ b/sql/sql_join_cache.cc @@ -2576,6 +2576,15 @@ void JOIN_CACHE::print_explain_comment(String *str) str->append(STRING_WITH_LEN(")")); } +/** + get thread handle. +*/ + +THD *JOIN_CACHE::thd() +{ + return join->thd; +} + static void add_mrr_explain_info(String *str, uint mrr_mode, handler *file) { @@ -4015,7 +4024,11 @@ bool bka_skip_index_tuple(range_seq_t rseq, range_id_t range_info) { DBUG_ENTER("bka_skip_index_tuple"); JOIN_CACHE_BKA *cache= (JOIN_CACHE_BKA *) rseq; - bool res= cache->skip_index_tuple(range_info); + THD *thd= cache->thd(); + bool res; + status_var_increment(thd->status_var.ha_pushed_index_cond_checks); + if ((res= cache->skip_index_tuple(range_info))) + status_var_increment(thd->status_var.ha_pushed_index_cond_filtered); DBUG_RETURN(res); } @@ -4490,7 +4503,12 @@ bool bkah_skip_index_tuple(range_seq_t rseq, range_id_t range_info) { DBUG_ENTER("bka_unique_skip_index_tuple"); JOIN_CACHE_BKAH *cache= (JOIN_CACHE_BKAH *) rseq; - DBUG_RETURN(cache->skip_index_tuple(range_info)); + THD *thd= cache->thd(); + bool res; + status_var_increment(thd->status_var.ha_pushed_index_cond_checks); + if ((res= cache->skip_index_tuple(range_info))) + status_var_increment(thd->status_var.ha_pushed_index_cond_filtered); + DBUG_RETURN(res); } diff --git a/sql/sql_join_cache.h b/sql/sql_join_cache.h index f5d64d5530a..ba8e4ba8e4a 100644 --- a/sql/sql_join_cache.h +++ b/sql/sql_join_cache.h @@ -643,6 +643,8 @@ public: /* Add a comment on the join algorithm employed by the join cache */ virtual void print_explain_comment(String *str); + THD *thd(); + virtual ~JOIN_CACHE() {} void reset_join(JOIN *j) { join= j; } void free() diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index 92b2a965706..bee7888eb5d 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -2248,12 +2248,18 @@ C_MODE_START ICP_RESULT index_cond_func_maria(void *arg) { ha_maria *h= (ha_maria*)arg; + THD *thd= ((TABLE*) h->file->external_ref)->in_use; + ICP_RESULT res; if (h->end_range) { if (h->compare_key2(h->end_range) > 0) return ICP_OUT_OF_RANGE; /* caller should return HA_ERR_END_OF_FILE already */ } - return h->pushed_idx_cond->val_int() ? ICP_MATCH : ICP_NO_MATCH; + status_var_increment(thd->status_var.ha_pushed_index_cond_checks); + if ((res= h->pushed_idx_cond->val_int() ? ICP_MATCH : ICP_NO_MATCH) == + ICP_NO_MATCH) + status_var_increment(thd->status_var.ha_pushed_index_cond_filtered); + return res; } C_MODE_END diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 5f1caa31b74..1f6e1fd6838 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -1770,12 +1770,18 @@ C_MODE_START ICP_RESULT index_cond_func_myisam(void *arg) { ha_myisam *h= (ha_myisam*)arg; + THD *thd= ((TABLE*) h->file->external_ref)->in_use; + ICP_RESULT res; if (h->end_range) { if (h->compare_key2(h->end_range) > 0) return ICP_OUT_OF_RANGE; /* caller should return HA_ERR_END_OF_FILE already */ } - return (ICP_RESULT) test(h->pushed_idx_cond->val_int()); + status_var_increment(thd->status_var.ha_pushed_index_cond_checks); + if ((res= (ICP_RESULT) test(h->pushed_idx_cond->val_int())) == + ICP_NO_MATCH) + status_var_increment(thd->status_var.ha_pushed_index_cond_filtered); + return res; } C_MODE_END diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 972a4407eea..9db7e9a715b 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -12583,6 +12583,8 @@ innobase_index_cond( void* file) /*!< in/out: pointer to ha_innobase */ { ha_innobase *h= (ha_innobase*) file; + THD *thd= h->thd(); + enum icp_result res; if (h->is_thd_killed()) return ICP_ABORTED_BY_USER; @@ -12592,7 +12594,11 @@ innobase_index_cond( if (h->compare_key2(h->end_range) > 0) return ICP_OUT_OF_RANGE; /* caller should return HA_ERR_END_OF_FILE already */ } - return h->pushed_idx_cond->val_int()? ICP_MATCH : ICP_NO_MATCH; + status_var_increment(thd->status_var.ha_pushed_index_cond_checks); + if ((res= h->pushed_idx_cond->val_int()? ICP_MATCH : ICP_NO_MATCH) == + ICP_NO_MATCH) + status_var_increment(thd->status_var.ha_pushed_index_cond_filtered); + return res; } /** Attempt to push down an index condition. diff --git a/storage/xtradb/handler/ha_innodb.h b/storage/xtradb/handler/ha_innodb.h index 749438e0c89..6ec036eb8cc 100644 --- a/storage/xtradb/handler/ha_innodb.h +++ b/storage/xtradb/handler/ha_innodb.h @@ -223,6 +223,8 @@ class ha_innobase: public handler bool check_if_incompatible_data(HA_CREATE_INFO *info, uint table_changes); bool check_if_supported_virtual_columns(void) { return TRUE; } + + THD *thd() { return user_thd; } private: /** Builds a 'template' to the prebuilt struct. From e98e05da7a0f817849529dfaf89e9b8010b16f4e Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Thu, 16 Feb 2012 18:56:10 +0400 Subject: [PATCH 091/135] Added comments --- sql/sql_list.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sql/sql_list.h b/sql/sql_list.h index 873a8656ebe..adedd9a3a4d 100644 --- a/sql/sql_list.h +++ b/sql/sql_list.h @@ -257,7 +257,12 @@ public: last= &first; return tmp->info; } - inline void disjoin(base_list *list) + /* + Remove from this list elements that are contained in the passed list. + We assume that the passed list is a tail of this list (that is, the whole + list_node* elements are shared). + */ + inline void disjoin(const base_list *list) { list_node **prev= &first; list_node *node= first; From 541334c5ac11efae4918116b152d9085bd82caee Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Thu, 16 Feb 2012 20:15:57 +0400 Subject: [PATCH 092/135] Backport of: timestamp: Thu 2011-12-01 15:12:10 +0100 Fix for Bug#13430436 PERFORMANCE DEGRADATION IN SYSBENCH ON INNODB DUE TO ICP When running sysbench on InnoDB there is a performance degradation due to index condition pushdown (ICP). Several of the queries in sysbench have a WHERE condition that the optimizer uses for executing these queries as range scans. The upper and lower limit of the range scan will ensure that the WHERE condition is fulfilled. Still, the WHERE condition is part of the queries' condition and if ICP is enabled the condition will be pushed down to InnoDB as an index condition. Due to the range scan's upper and lower limits ensure that the WHERE condition is fulfilled, the pushed index condition will not filter out any records. As a result the use of ICP for these queries results in a performance overhead for sysbench. This overhead comes from using resources for determining the part of the condition that can be pushed down to InnoDB and overhead in InnoDB for executing the pushed index condition. With the default configuration for sysbench the range scans will use the primary key. This is a clustered index in InnoDB. Using ICP on a clustered index provides the lowest performance benefit since the entire record is part of the clustered index and in InnoDB it has the highest relative overhead for executing the pushed index condition. The fix for removing the overhead ICP introduces when running sysbench is to disable use of ICP when the index used by the query is a clustered index. When WL#6061 is implemented this change should be re-evaluated. --- mysql-test/r/index_merge_innodb.result | 2 +- mysql-test/r/innodb.result | 2 +- mysql-test/r/innodb_icp.result | 14 +++++----- mysql-test/r/innodb_mrr_cpk.result | 6 ++-- .../r/range_vs_index_merge_innodb.result | 28 +++++++++---------- mysql-test/suite/innodb/r/innodb.result | 2 +- .../r/innodb_lock_wait_timeout_1.result | 4 +-- mysql-test/suite/innodb/r/innodb_mysql.result | 2 +- .../suite/vcol/r/vcol_select_innodb.result | 6 ++-- sql/opt_index_cond_pushdown.cc | 14 ++++++++-- 10 files changed, 45 insertions(+), 35 deletions(-) diff --git a/mysql-test/r/index_merge_innodb.result b/mysql-test/r/index_merge_innodb.result index 0f9da2ea3b6..50b0147b6ad 100644 --- a/mysql-test/r/index_merge_innodb.result +++ b/mysql-test/r/index_merge_innodb.result @@ -549,7 +549,7 @@ primary key (pk1, pk2) ); explain select * from t1 where pk1 = 1 and pk2 < 80 and key1=0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY,key1 PRIMARY 8 NULL 9 Using index condition; Using where +1 SIMPLE t1 range PRIMARY,key1 PRIMARY 8 NULL 9 Using where select * from t1 where pk1 = 1 and pk2 < 80 and key1=0; pk1 pk2 key1 key2 pktail1ok pktail2ok pktail3bad pktail4bad pktail5bad pk2copy badkey filler1 filler2 1 10 0 0 0 0 0 0 0 10 0 filler-data-10 filler2 diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index 3b69791d373..9ab7ed4eec7 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -783,7 +783,7 @@ create table t1 (a int primary key,b int, c int, d int, e int, f int, g int, h insert into t1 values (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1); explain select * from t1 where a > 0 and a < 50; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL # Using index condition +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL # Using where drop table t1; create table t1 (id int NOT NULL,id2 int NOT NULL,id3 int NOT NULL,dummy1 char(30),primary key (id,id2),index index_id3 (id3)) engine=innodb; insert into t1 values (0,0,0,'ABCDEFGHIJ'),(2,2,2,'BCDEFGHIJK'),(1,1,1,'CDEFGHIJKL'); diff --git a/mysql-test/r/innodb_icp.result b/mysql-test/r/innodb_icp.result index ccbae98d137..d8e41113f63 100644 --- a/mysql-test/r/innodb_icp.result +++ b/mysql-test/r/innodb_icp.result @@ -167,7 +167,7 @@ WHERE ts BETWEEN '0000-00-00' AND '2010-00-01 00:00:00' ORDER BY ts DESC LIMIT 2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using index condition +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where DROP TABLE t1; # @@ -431,7 +431,7 @@ SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON it.i=it.i WHERE it.pk-t1.i<10); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where -2 DEPENDENT SUBQUERY it eq_ref PRIMARY PRIMARY 4 func 1 Using index condition +2 DEPENDENT SUBQUERY it eq_ref PRIMARY PRIMARY 4 func 1 Using where 2 DEPENDENT SUBQUERY t2 index NULL PRIMARY 4 NULL 3 Using where; Using index; Using join buffer (flat, BNL join) SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON it.i=it.i WHERE it.pk-t1.i<10); @@ -452,7 +452,7 @@ PRIMARY KEY (pk) INSERT INTO t1 VALUES (1,9),(2,7),(3,6),(4,3),(5,1); EXPLAIN SELECT pk, c1 FROM t1 WHERE pk <> 3; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using index condition +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where SET SESSION optimizer_switch='index_condition_pushdown=off'; SELECT pk, c1 FROM t1 WHERE pk <> 3; pk c1 @@ -507,8 +507,8 @@ SELECT c2 FROM t1 JOIN t2 ON t1.c1 = t2.c1 WHERE (t2.pk <= 4 AND t1.pk IN (2,1)) OR (t1.pk > 1 AND t2.pk BETWEEN 6 AND 6); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Using where -1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using where; Using join buffer (flat, BNL join) +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 1 Using where +1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 2 Using where; Using join buffer (flat, BNL join) SELECT c2 FROM t1 JOIN t2 ON t1.c1 = t2.c1 WHERE (t2.pk <= 4 AND t1.pk IN (2,1)) OR (t1.pk > 1 AND t2.pk BETWEEN 6 AND 6); @@ -680,7 +680,7 @@ EXPLAIN SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0 HAVING t1.c != 5 ORDER BY t1.c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using where; Using filesort +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where; Using filesort 1 SIMPLE t2 ref a a 515 test.t1.a 1 Using where SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0 HAVING t1.c != 5 ORDER BY t1.c; @@ -793,7 +793,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t ALL PRIMARY,c NULL NULL NULL 64 Using where 1 PRIMARY t2 ref g g 5 test.t.c 9 Using where 2 DEPENDENT SUBQUERY t1 index PRIMARY d 3 NULL 64 Using where; Using index -2 DEPENDENT SUBQUERY t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using index condition; Using where +2 DEPENDENT SUBQUERY t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using where SELECT COUNT(*) FROM t1 AS t, t2 WHERE c = g AND (EXISTS (SELECT * FROM t1, t2 WHERE a = f AND h <= t.e AND a > t.b) diff --git a/mysql-test/r/innodb_mrr_cpk.result b/mysql-test/r/innodb_mrr_cpk.result index 81536f2a43b..90f59b96e61 100644 --- a/mysql-test/r/innodb_mrr_cpk.result +++ b/mysql-test/r/innodb_mrr_cpk.result @@ -82,7 +82,7 @@ insert into t2 values ('a-1010=A', 1010), ('a-1030=A', 1030), ('a-1020=A', 1020) explain select * from t1, t2 where t1.a=t2.a and t1.b=t2.b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where -1 SIMPLE t1 eq_ref PRIMARY PRIMARY 30 test.t2.a,test.t2.b 1 Using index condition(BKA); Using join buffer (flat, BKA join); Key-ordered scan +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 30 test.t2.a,test.t2.b 1 Using where; Using join buffer (flat, BKA join); Key-ordered scan select * from t1, t2 where t1.a=t2.a and t1.b=t2.b; a b filler a b a-1010=A 1010 filler a-1010=A 1010 @@ -91,7 +91,7 @@ a-1030=A 1030 filler a-1030=A 1030 explain select * from t1, t2 where t1.a=t2.a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where -1 SIMPLE t1 ref PRIMARY PRIMARY 26 test.t2.a 1 Using index condition(BKA); Using join buffer (flat, BKA join); Key-ordered scan +1 SIMPLE t1 ref PRIMARY PRIMARY 26 test.t2.a 1 Using where; Using join buffer (flat, BKA join); Key-ordered scan select * from t1, t2 where t1.a=t2.a; a b filler a b a-1010=A 1010 filler a-1010=A 1010 @@ -133,7 +133,7 @@ set join_cache_level=6; explain select * from t1, t2 where t1.a=t2.a and t2.b + t1.b > 100; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where -1 SIMPLE t1 ref PRIMARY PRIMARY 4 test.t2.a 1 Using index condition(BKA); Using join buffer (flat, BKA join); Key-ordered scan +1 SIMPLE t1 ref PRIMARY PRIMARY 4 test.t2.a 1 Using where; Using join buffer (flat, BKA join); Key-ordered scan select * from t1, t2 where t1.a=t2.a and t2.b + t1.b > 100; a b c filler a b set optimizer_switch='index_condition_pushdown=off'; diff --git a/mysql-test/r/range_vs_index_merge_innodb.result b/mysql-test/r/range_vs_index_merge_innodb.result index 57862ded4f2..c42f80f0e85 100644 --- a/mysql-test/r/range_vs_index_merge_innodb.result +++ b/mysql-test/r/range_vs_index_merge_innodb.result @@ -328,15 +328,15 @@ ID Name Country Population EXPLAIN SELECT * FROM City WHERE (ID < 10) OR (ID BETWEEN 100 AND 110); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 20 Using index condition; Using where +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 20 Using where EXPLAIN SELECT * FROM City WHERE (ID < 200) OR (ID BETWEEN 100 AND 200); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 200 Using index condition; Using where +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 200 Using where EXPLAIN SELECT * FROM City WHERE (ID < 600) OR (ID BETWEEN 900 AND 1500); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 1198 Using index condition; Using where +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 1198 Using where EXPLAIN SELECT * FROM City WHERE Country > 'A' AND Country < 'ARG'; id select_type table type possible_keys key key_len ref rows Extra @@ -355,7 +355,7 @@ WHERE ((ID < 10) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 100 AND 110) AND (Name LIKE 'P%' OR (Population > 103000 AND Population < 104000))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 20 Using index condition; Using where +1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 20 Using where EXPLAIN SELECT * FROM City WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) @@ -369,7 +369,7 @@ WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 100 AND 200) AND (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 200 Using index condition; Using where +1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 200 Using where SELECT * FROM City USE INDEX () WHERE ((ID < 10) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 100 AND 110) AND @@ -601,11 +601,11 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT * FROM City WHERE ID BETWEEN 3400 AND 3800; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 400 Using index condition +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 400 Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 3790 AND 3800; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using index condition +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using where EXPLAIN SELECT * FROM City WHERE Name LIKE 'P%'; id select_type table type possible_keys key key_len ref rows Extra @@ -765,27 +765,27 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT * FROM City WHERE ID BETWEEN 3790 AND 3800; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using index condition +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 4025 AND 4035; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using index condition +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 4028 AND 4032; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 5 Using index condition +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 5 Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 3500 AND 3800; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 300 Using index condition +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 300 Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 4000 AND 4300; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 80 Using index condition +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 80 Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 250 and 260 ; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using index condition +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using where EXPLAIN SELECT * FROM City WHERE (Population > 101000 AND Population < 102000); id select_type table type possible_keys key key_len ref rows Extra @@ -1422,7 +1422,7 @@ SELECT * FROM t1 WHERE t1.a>300 AND t1.c!=0 AND t1.b>=350 AND t1.b<=400 AND (t1.c=0 OR t1.a=500); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY,idx PRIMARY 4 NULL 1 Using index condition; Using where +1 SIMPLE t1 range PRIMARY,idx PRIMARY 4 NULL 1 Using where SELECT * FROM t1 WHERE t1.a>300 AND t1.c!=0 AND t1.b>=350 AND t1.b<=400 AND (t1.c=0 OR t1.a=500); diff --git a/mysql-test/suite/innodb/r/innodb.result b/mysql-test/suite/innodb/r/innodb.result index e98d3931020..80ff21230fb 100644 --- a/mysql-test/suite/innodb/r/innodb.result +++ b/mysql-test/suite/innodb/r/innodb.result @@ -778,7 +778,7 @@ create table t1 (a int primary key,b int, c int, d int, e int, f int, g int, h insert into t1 values (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1); explain select * from t1 where a > 0 and a < 50; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL # Using index condition +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL # Using where drop table t1; create table t1 (id int NOT NULL,id2 int NOT NULL,id3 int NOT NULL,dummy1 char(30),primary key (id,id2),index index_id3 (id3)) engine=innodb; insert into t1 values (0,0,0,'ABCDEFGHIJ'),(2,2,2,'BCDEFGHIJK'),(1,1,1,'CDEFGHIJKL'); diff --git a/mysql-test/suite/innodb/r/innodb_lock_wait_timeout_1.result b/mysql-test/suite/innodb/r/innodb_lock_wait_timeout_1.result index 30e58aacff5..2cb761c6ea1 100644 --- a/mysql-test/suite/innodb/r/innodb_lock_wait_timeout_1.result +++ b/mysql-test/suite/innodb/r/innodb_lock_wait_timeout_1.result @@ -121,7 +121,7 @@ key PRIMARY key_len 4 ref t2.a rows 1 -Extra Using index condition; Using where +Extra Using where id 2 select_type DERIVED table NULL @@ -328,7 +328,7 @@ key PRIMARY key_len 4 ref t2.a rows 1 -Extra Using index condition; Using where +Extra Using where id 2 select_type DERIVED table NULL diff --git a/mysql-test/suite/innodb/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result index 4dcce4d0373..62dbc849241 100644 --- a/mysql-test/suite/innodb/r/innodb_mysql.result +++ b/mysql-test/suite/innodb/r/innodb_mysql.result @@ -2839,7 +2839,7 @@ SELECT t1.a FROM t1 LEFT JOIN t2 ON t1.pk = t2.a WHERE t1.pk >= 6 HAVING t1.a<> 0 AND t1.a <> 11 ORDER BY t1.a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using index condition; Using filesort +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where; Using filesort 1 SIMPLE t2 ref a a 5 test.t1.pk 1 Using index SELECT t1.a FROM t1 LEFT JOIN t2 ON t1.pk = t2.a WHERE t1.pk >= 6 HAVING t1.a<> 0 AND t1.a <> 11 diff --git a/mysql-test/suite/vcol/r/vcol_select_innodb.result b/mysql-test/suite/vcol/r/vcol_select_innodb.result index be84fa74c2e..14cf325feb1 100644 --- a/mysql-test/suite/vcol/r/vcol_select_innodb.result +++ b/mysql-test/suite/vcol/r/vcol_select_innodb.result @@ -152,7 +152,7 @@ a b c 2 -2 -2 explain select * from t3 where a between 1 and 2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t3 range PRIMARY PRIMARY 4 NULL 2 Using index condition +1 SIMPLE t3 range PRIMARY PRIMARY 4 NULL 2 Using where # SELECT * FROM tbl_name WHERE select * from t3 where b between -2 and -1; a b c @@ -176,7 +176,7 @@ a b c 1 -1 -1 explain select * from t3 where a between 1 and 2 order by b; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t3 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using filesort +1 SIMPLE t3 range PRIMARY PRIMARY 4 NULL 2 Using where; Using filesort # SELECT * FROM tbl_name WHERE ORDER BY select * from t3 where a between 1 and 2 order by c; a b c @@ -184,7 +184,7 @@ a b c 1 -1 -1 explain select * from t3 where a between 1 and 2 order by c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t3 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using filesort +1 SIMPLE t3 range PRIMARY PRIMARY 4 NULL 2 Using where; Using filesort # SELECT * FROM tbl_name WHERE ORDER BY select * from t3 where b between -2 and -1 order by a; a b c diff --git a/sql/opt_index_cond_pushdown.cc b/sql/opt_index_cond_pushdown.cc index 5240267b4ac..c2b49d863a1 100644 --- a/sql/opt_index_cond_pushdown.cc +++ b/sql/opt_index_cond_pushdown.cc @@ -329,13 +329,23 @@ void push_index_cond(JOIN_TAB *tab, uint keyno) { DBUG_ENTER("push_index_cond"); Item *idx_cond; - + + /* + Backported the following from MySQL 5.6: + 6. The index is not a clustered index. The performance improvement + of pushing an index condition on a clustered key is much lower + than on a non-clustered key. This restriction should be + re-evaluated when WL#6061 is implemented. + */ if ((tab->table->file->index_flags(keyno, 0, 1) & HA_DO_INDEX_COND_PUSHDOWN) && optimizer_flag(tab->join->thd, OPTIMIZER_SWITCH_INDEX_COND_PUSHDOWN) && tab->join->thd->lex->sql_command != SQLCOM_UPDATE_MULTI && tab->join->thd->lex->sql_command != SQLCOM_DELETE_MULTI && - tab->type != JT_CONST && tab->type != JT_SYSTEM) + tab->type != JT_CONST && tab->type != JT_SYSTEM && + !(keyno == tab->table->s->primary_key && // (6) + tab->table->file->primary_key_is_clustered())) // (6) + { DBUG_EXECUTE("where", print_where(tab->select_cond, "full cond", QT_ORDINARY);); From c563ea0717f3de43b7331dd4368e9f9cf4559be0 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Thu, 16 Feb 2012 16:06:49 -0800 Subject: [PATCH 093/135] Fixed LP bug #933117. The bug was fixed with the code back-ported from the patch for LP bug 800184 pushed into mariadb-5.3. --- mysql-test/r/range.result | 15 +++++++++++++++ mysql-test/t/range.test | 14 ++++++++++++++ sql/opt_range.cc | 9 +++++++-- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result index ae63edf87b9..13ae77c13e3 100644 --- a/mysql-test/r/range.result +++ b/mysql-test/r/range.result @@ -1768,3 +1768,18 @@ SELECT * FROM t1, t1 as t2 WHERE t1.i4 BETWEEN t2.pk AND t2.pk; pk i4 pk i4 DROP TABLE t1; End of 5.1 tests +# +# LP Bug #533117: Wrong use_count in SEL_ARG trees +# (Bug #58731) +# +create table t1 (a int, b int, c int, key idx (a,b,c)); +insert into t1 values (0,0,0), (2,2,0), (1,1,1), (2,2,1); +explain +select * from t1 force index (idx) where a >=1 and c <= 1 and a=b and b > 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range idx idx 5 NULL 3 Using where; Using index +select * from t1 force index (idx) where a >=1 and c <= 1 and a=b and b > 1; +a b c +2 2 0 +2 2 1 +drop table t1; diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test index 6c9320b708a..a5ab6905b74 100644 --- a/mysql-test/t/range.test +++ b/mysql-test/t/range.test @@ -1393,3 +1393,17 @@ SELECT * FROM t1, t1 as t2 WHERE t1.i4 BETWEEN t2.pk AND t2.pk; DROP TABLE t1; --echo End of 5.1 tests + +--echo # +--echo # LP Bug #533117: Wrong use_count in SEL_ARG trees +--echo # (Bug #58731) +--echo # + +create table t1 (a int, b int, c int, key idx (a,b,c)); +insert into t1 values (0,0,0), (2,2,0), (1,1,1), (2,2,1); + +explain +select * from t1 force index (idx) where a >=1 and c <= 1 and a=b and b > 1; +select * from t1 force index (idx) where a >=1 and c <= 1 and a=b and b > 1; + +drop table t1; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index bc434e2edc1..185f3eecd3c 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -498,6 +498,11 @@ public: pos->increment_use_count(count); } } + void incr_refs() + { + increment_use_count(1); + use_count++; + } void free_tree() { for (SEL_ARG *pos=first(); pos ; pos=pos->next) @@ -6475,8 +6480,8 @@ key_and(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2, uint clone_flag) continue; SEL_ARG *next=key_and(param, e1->next_key_part, e2->next_key_part, clone_flag); - e1->increment_use_count(1); - e2->increment_use_count(1); + e1->incr_refs(); + e2->incr_refs(); if (!next || next->type != SEL_ARG::IMPOSSIBLE) { SEL_ARG *new_arg= e1->clone_and(e2); From 2d19b077d5816dcd3a8c84bb682cf2d83fa055f5 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Thu, 16 Feb 2012 20:13:28 -0800 Subject: [PATCH 094/135] Fixed LP bug #928352. This bug led to wrong values of the use_count fields in some SEL_ARG trees that triggered complains on the server side when executing the test case for LP bug 800184 if a debug build of the server was used. This was the result of the incomplete fix for bug 800184. To complete it the following corrections had to be made: - the copy constructor for SEL_TREE must call the new function incr_refs_all() instead of the function incr_refs(), because references to next key parts from any SEL_ARG tree belonging to the list of the first key part has to be adjusted. - the method and_sel_tree of the class SEL_IMERGE must use the copy constructor of the SEL_TREE class to make a copy of its second argument before it ANDs it with any SEL_TREE tree from the processed SEL_IMERGE object. --- sql/opt_range.cc | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 8d4b2e971ad..e0841d3a696 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -552,6 +552,14 @@ public: increment_use_count(1); use_count++; } + void incr_refs_all() + { + for (SEL_ARG *pos=first(); pos ; pos=pos->next) + { + pos->increment_use_count(1); + } + use_count++; + } void free_tree() { for (SEL_ARG *pos=first(); pos ; pos=pos->next) @@ -1090,9 +1098,11 @@ int SEL_IMERGE::and_sel_tree(RANGE_OPT_PARAM *param, SEL_TREE *tree, for (SEL_TREE** or_tree= trees; or_tree != trees_next; or_tree++) { SEL_TREE *res_or_tree= 0; - if (!(res_or_tree= new SEL_TREE())) + SEL_TREE *and_tree= 0; + if (!(res_or_tree= new SEL_TREE()) || + !(and_tree= new SEL_TREE(tree, TRUE, param))) return (-1); - if (!and_range_trees(param, *or_tree, tree, res_or_tree)) + if (!and_range_trees(param, *or_tree, and_tree, res_or_tree)) { if (new_imerge->or_sel_tree(param, res_or_tree)) return (-1); @@ -1305,7 +1315,7 @@ SEL_TREE::SEL_TREE(SEL_TREE *arg, bool without_merges, for (uint idx= 0; idx < param->keys; idx++) { if ((keys[idx]= arg->keys[idx])) - keys[idx]->incr_refs(); + keys[idx]->incr_refs_all(); } if (without_merges) From bbb3527635627a404ab4a16be7598339e8e41139 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 17 Feb 2012 13:27:41 +0100 Subject: [PATCH 095/135] Remove engine-specific (but identical) icp callbacks. create one reusable common icp callback in the handler.cc. It can also increment status counters, without making the engine dependent on the exact THD layout (that is different in embedded). --- sql/handler.cc | 21 +++++++++++++++++++ sql/handler.h | 4 ++++ storage/maria/ha_maria.cc | 27 +++---------------------- storage/myisam/ha_myisam.cc | 28 +++----------------------- storage/xtradb/handler/ha_innodb.cc | 28 -------------------------- storage/xtradb/handler/ha_innodb.h | 1 - storage/xtradb/include/ha_prototypes.h | 2 +- storage/xtradb/row/row0sel.c | 2 +- 8 files changed, 33 insertions(+), 80 deletions(-) diff --git a/sql/handler.cc b/sql/handler.cc index e165a16b544..4a8cd77ebc3 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -4555,6 +4555,27 @@ int handler::compare_key2(key_range *range) } +/** + ICP callback - to be called by an engine to check the pushed condition +*/ +extern "C" enum icp_result handler_index_cond_check(void* h_arg) +{ + handler *h= (handler*)h_arg; + THD *thd= h->table->in_use; + enum icp_result res; + + if (thd_killed(thd)) + return ICP_ABORTED_BY_USER; + + if (h->end_range && h->compare_key2(h->end_range) > 0) + return ICP_OUT_OF_RANGE; + h->increment_statistics(&SSV::ha_pushed_index_cond_checks); + if ((res= h->pushed_idx_cond->val_int()? ICP_MATCH : ICP_NO_MATCH) == + ICP_NO_MATCH) + h->increment_statistics(&SSV::ha_pushed_index_cond_filtered); + return res; +} + int handler::index_read_idx_map(uchar * buf, uint index, const uchar * key, key_part_map keypart_map, enum ha_rkey_function find_flag) diff --git a/sql/handler.h b/sql/handler.h index 87ac1ab9ef3..28d8a96a895 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1553,6 +1553,8 @@ public: {} }; +extern "C" enum icp_result handler_index_cond_check(void* h_arg); + uint calculate_key_len(TABLE *, uint, const uchar *, key_part_map); /* bitmap with first N+1 bits set @@ -2632,6 +2634,8 @@ public: { return ht; } inline int ha_write_tmp_row(uchar *buf); inline int ha_update_tmp_row(const uchar * old_data, uchar * new_data); + + friend enum icp_result handler_index_cond_check(void* h_arg); }; #include "multi_range_read.h" diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index bee7888eb5d..407350900bf 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -2243,27 +2243,6 @@ int ha_maria::delete_row(const uchar * buf) return maria_delete(file, buf); } -C_MODE_START - -ICP_RESULT index_cond_func_maria(void *arg) -{ - ha_maria *h= (ha_maria*)arg; - THD *thd= ((TABLE*) h->file->external_ref)->in_use; - ICP_RESULT res; - if (h->end_range) - { - if (h->compare_key2(h->end_range) > 0) - return ICP_OUT_OF_RANGE; /* caller should return HA_ERR_END_OF_FILE already */ - } - status_var_increment(thd->status_var.ha_pushed_index_cond_checks); - if ((res= h->pushed_idx_cond->val_int() ? ICP_MATCH : ICP_NO_MATCH) == - ICP_NO_MATCH) - status_var_increment(thd->status_var.ha_pushed_index_cond_filtered); - return res; -} - -C_MODE_END - int ha_maria::index_read_map(uchar * buf, const uchar * key, key_part_map keypart_map, enum ha_rkey_function find_flag) @@ -2283,7 +2262,7 @@ int ha_maria::index_read_idx_map(uchar * buf, uint index, const uchar * key, /* Use the pushed index condition if it matches the index we're scanning */ end_range= NULL; if (index == pushed_idx_cond_keyno) - ma_set_index_cond_func(file, index_cond_func_maria, this); + ma_set_index_cond_func(file, handler_index_cond_check, this); error= maria_rkey(file, buf, index, key, keypart_map, find_flag); @@ -2364,7 +2343,7 @@ int ha_maria::index_init(uint idx, bool sorted) { active_index=idx; if (pushed_idx_cond_keyno == idx) - ma_set_index_cond_func(file, index_cond_func_maria, this); + ma_set_index_cond_func(file, handler_index_cond_check, this); return 0; } @@ -3797,7 +3776,7 @@ Item *ha_maria::idx_cond_push(uint keyno_arg, Item* idx_cond_arg) pushed_idx_cond= idx_cond_arg; in_range_check_pushed_down= TRUE; if (active_index == pushed_idx_cond_keyno) - ma_set_index_cond_func(file, index_cond_func_maria, this); + ma_set_index_cond_func(file, handler_index_cond_check, this); return NULL; } diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 1f6e1fd6838..a6ece45734a 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -1765,33 +1765,11 @@ int ha_myisam::delete_row(const uchar *buf) } -C_MODE_START - -ICP_RESULT index_cond_func_myisam(void *arg) -{ - ha_myisam *h= (ha_myisam*)arg; - THD *thd= ((TABLE*) h->file->external_ref)->in_use; - ICP_RESULT res; - if (h->end_range) - { - if (h->compare_key2(h->end_range) > 0) - return ICP_OUT_OF_RANGE; /* caller should return HA_ERR_END_OF_FILE already */ - } - status_var_increment(thd->status_var.ha_pushed_index_cond_checks); - if ((res= (ICP_RESULT) test(h->pushed_idx_cond->val_int())) == - ICP_NO_MATCH) - status_var_increment(thd->status_var.ha_pushed_index_cond_filtered); - return res; -} - -C_MODE_END - - int ha_myisam::index_init(uint idx, bool sorted) { active_index=idx; if (pushed_idx_cond_keyno == idx) - mi_set_index_cond_func(file, index_cond_func_myisam, this); + mi_set_index_cond_func(file, handler_index_cond_check, this); return 0; } @@ -1827,7 +1805,7 @@ int ha_myisam::index_read_idx_map(uchar *buf, uint index, const uchar *key, /* Use the pushed index condition if it matches the index we're scanning */ end_range= NULL; if (index == pushed_idx_cond_keyno) - mi_set_index_cond_func(file, index_cond_func_myisam, this); + mi_set_index_cond_func(file, handler_index_cond_check, this); res= mi_rkey(file, buf, index, key, keypart_map, find_flag); mi_set_index_cond_func(file, NULL, 0); return res; @@ -2346,7 +2324,7 @@ Item *ha_myisam::idx_cond_push(uint keyno_arg, Item* idx_cond_arg) pushed_idx_cond= idx_cond_arg; in_range_check_pushed_down= TRUE; if (active_index == pushed_idx_cond_keyno) - mi_set_index_cond_func(file, index_cond_func_myisam, this); + mi_set_index_cond_func(file, handler_index_cond_check, this); return NULL; } diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 9db7e9a715b..0d64a3f8b14 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -12573,34 +12573,6 @@ bool ha_innobase::is_thd_killed() * Index Condition Pushdown interface implementation */ -/*************************************************************//** -InnoDB index push-down condition check -@return ICP_NO_MATCH, ICP_MATCH, or ICP_OUT_OF_RANGE */ -extern "C" UNIV_INTERN -enum icp_result -innobase_index_cond( -/*================*/ - void* file) /*!< in/out: pointer to ha_innobase */ -{ - ha_innobase *h= (ha_innobase*) file; - THD *thd= h->thd(); - enum icp_result res; - - if (h->is_thd_killed()) - return ICP_ABORTED_BY_USER; - - if (h->end_range) - { - if (h->compare_key2(h->end_range) > 0) - return ICP_OUT_OF_RANGE; /* caller should return HA_ERR_END_OF_FILE already */ - } - status_var_increment(thd->status_var.ha_pushed_index_cond_checks); - if ((res= h->pushed_idx_cond->val_int()? ICP_MATCH : ICP_NO_MATCH) == - ICP_NO_MATCH) - status_var_increment(thd->status_var.ha_pushed_index_cond_filtered); - return res; -} - /** Attempt to push down an index condition. * @param[in] keyno MySQL key number * @param[in] idx_cond Index condition to be checked diff --git a/storage/xtradb/handler/ha_innodb.h b/storage/xtradb/handler/ha_innodb.h index 6ec036eb8cc..d234a7236e3 100644 --- a/storage/xtradb/handler/ha_innodb.h +++ b/storage/xtradb/handler/ha_innodb.h @@ -224,7 +224,6 @@ class ha_innobase: public handler uint table_changes); bool check_if_supported_virtual_columns(void) { return TRUE; } - THD *thd() { return user_thd; } private: /** Builds a 'template' to the prebuilt struct. diff --git a/storage/xtradb/include/ha_prototypes.h b/storage/xtradb/include/ha_prototypes.h index db71c37afc3..28c28838400 100644 --- a/storage/xtradb/include/ha_prototypes.h +++ b/storage/xtradb/include/ha_prototypes.h @@ -252,7 +252,7 @@ InnoDB index push-down condition check @return ICP_NO_MATCH, ICP_MATCH, or ICP_OUT_OF_RANGE */ UNIV_INTERN enum icp_result -innobase_index_cond( +handler_index_cond_check( /*================*/ void* file) /*!< in/out: pointer to ha_innobase */ __attribute__((nonnull, warn_unused_result)); diff --git a/storage/xtradb/row/row0sel.c b/storage/xtradb/row/row0sel.c index fca3c90109f..52a6263efe5 100644 --- a/storage/xtradb/row/row0sel.c +++ b/storage/xtradb/row/row0sel.c @@ -3443,7 +3443,7 @@ row_search_idx_cond_check( index, if the case of the column has been updated in the past, or a record has been deleted and a record inserted in a different case. */ - result = innobase_index_cond(prebuilt->idx_cond); + result = handler_index_cond_check(prebuilt->idx_cond); switch (result) { case ICP_MATCH: /* Convert the remaining fields to MySQL format. From cd81f5783071d76d14a7aeb804e874345b1f3254 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Sat, 18 Feb 2012 16:06:38 -0800 Subject: [PATCH 096/135] Fixed LP bug #934342. An outer join query with a semi-join subquery could return a wrong result if the optimizer chose to materialize the subquery. It happened because when substituting for the best field into a ref item used to build access keys not all COND_EQUAL objects that could be employed at substitution were checked. Also refined some code in the function check_join_cache_usage to make it safer. --- mysql-test/r/subselect_sj_jcl6.result | 80 +++++++++++++++++++++++++++ mysql-test/t/subselect_sj_jcl6.test | 54 ++++++++++++++++++ sql/sql_select.cc | 21 +++++-- 3 files changed, 150 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/subselect_sj_jcl6.result b/mysql-test/r/subselect_sj_jcl6.result index dd358ced14a..4ac15ea654f 100644 --- a/mysql-test/r/subselect_sj_jcl6.result +++ b/mysql-test/r/subselect_sj_jcl6.result @@ -2753,6 +2753,86 @@ DROP table t1, t2; set @@optimizer_switch= @os_912513; set @@join_cache_level= @jcl_912513; # End +# +# BUG#934342: outer join + semijoin materialization +# + join_cache_level > 2 +# +CREATE TABLE t1 (a varchar(1), b varchar(1), INDEX idx_a(a) ); +INSERT INTO t1 VALUES ('v','v'), ('w','w'), ('t','t'); +CREATE TABLE t2 (c varchar(1), INDEX idx_c(c) ); +INSERT INTO t2 VALUES ('v'), ('v'), ('s'), ('j'); +CREATE TABLE t3 (c varchar(1), d varchar(1), INDEX idx_c(c) ); +INSERT INTO t3 VALUES ('v','v'), ('v','v'), ('s','s'), ('j','j'); +INSERT INTO t3 VALUES ('m','m'), ('d','d'), ('k','k'), ('m','m'); +set @tmp_otimizer_switch= @@optimizer_switch; +set @tmp_join_cache_level=@@join_cache_level; +set optimizer_switch = 'materialization=on,semijoin=on,join_cache_hashed=on'; +set join_cache_level=0; +EXPLAIN +SELECT * FROM t1 LEFT JOIN t2 ON (c = b) +WHERE (a, b) IN (SELECT a, b FROM t1 t); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL idx_a NULL NULL NULL 3 +1 PRIMARY eq_ref distinct_key distinct_key 10 func,func 1 +1 PRIMARY t2 ref idx_c idx_c 4 test.t1.b 2 Using where; Using index +2 MATERIALIZED t ALL idx_a NULL NULL NULL 3 +SELECT * FROM t1 LEFT JOIN t2 ON (c = b) +WHERE (a, b) IN (SELECT a, b FROM t1 t); +a b c +v v v +v v v +w w NULL +t t NULL +EXPLAIN +SELECT * FROM t1 LEFT JOIN t3 ON (c = b) +WHERE (a, b) IN (SELECT a, b FROM t1 t); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL idx_a NULL NULL NULL 3 +1 PRIMARY eq_ref distinct_key distinct_key 10 func,func 1 +1 PRIMARY t3 ref idx_c idx_c 4 test.t1.b 2 Using where +2 MATERIALIZED t ALL idx_a NULL NULL NULL 3 +SELECT * FROM t1 LEFT JOIN t3 ON (c = b) +WHERE (a, b) IN (SELECT a, b FROM t1 t); +a b c d +v v v v +v v v v +w w NULL NULL +t t NULL NULL +set join_cache_level=6; +EXPLAIN +SELECT * FROM t1 LEFT JOIN t2 ON (c = b) +WHERE (a, b) IN (SELECT a, b FROM t1 t); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL idx_a NULL NULL NULL 3 +1 PRIMARY eq_ref distinct_key distinct_key 10 func,func 1 +1 PRIMARY t2 ref idx_c idx_c 4 test.t1.b 2 Using where; Using index +2 MATERIALIZED t ALL idx_a NULL NULL NULL 3 +SELECT * FROM t1 LEFT JOIN t2 ON (c = b) +WHERE (a, b) IN (SELECT a, b FROM t1 t); +a b c +v v v +v v v +w w NULL +t t NULL +EXPLAIN +SELECT * FROM t1 LEFT JOIN t3 ON (c = b) +WHERE (a, b) IN (SELECT a, b FROM t1 t); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL idx_a NULL NULL NULL 3 +1 PRIMARY eq_ref distinct_key distinct_key 10 func,func 1 +1 PRIMARY t3 ref idx_c idx_c 4 test.t1.b 2 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +2 MATERIALIZED t ALL idx_a NULL NULL NULL 3 +SELECT * FROM t1 LEFT JOIN t3 ON (c = b) +WHERE (a, b) IN (SELECT a, b FROM t1 t); +a b c d +v v v v +v v v v +w w NULL NULL +t t NULL NULL +set optimizer_switch=@tmp_optimizer_switch; +set join_cache_level=@tmp_join_cache_level; +DROP TABLE t1,t2,t3; +# End set join_cache_level=default; show variables like 'join_cache_level'; Variable_name Value diff --git a/mysql-test/t/subselect_sj_jcl6.test b/mysql-test/t/subselect_sj_jcl6.test index 6d563cab3d3..9fe60cdd3d9 100644 --- a/mysql-test/t/subselect_sj_jcl6.test +++ b/mysql-test/t/subselect_sj_jcl6.test @@ -116,6 +116,60 @@ set @@join_cache_level= @jcl_912513; --echo # End +--echo # +--echo # BUG#934342: outer join + semijoin materialization +--echo # + join_cache_level > 2 +--echo # + +CREATE TABLE t1 (a varchar(1), b varchar(1), INDEX idx_a(a) ); +INSERT INTO t1 VALUES ('v','v'), ('w','w'), ('t','t'); + +CREATE TABLE t2 (c varchar(1), INDEX idx_c(c) ); +INSERT INTO t2 VALUES ('v'), ('v'), ('s'), ('j'); + +CREATE TABLE t3 (c varchar(1), d varchar(1), INDEX idx_c(c) ); +INSERT INTO t3 VALUES ('v','v'), ('v','v'), ('s','s'), ('j','j'); +INSERT INTO t3 VALUES ('m','m'), ('d','d'), ('k','k'), ('m','m'); + +set @tmp_otimizer_switch= @@optimizer_switch; +set @tmp_join_cache_level=@@join_cache_level; +set optimizer_switch = 'materialization=on,semijoin=on,join_cache_hashed=on'; + +set join_cache_level=0; + +EXPLAIN +SELECT * FROM t1 LEFT JOIN t2 ON (c = b) + WHERE (a, b) IN (SELECT a, b FROM t1 t); +SELECT * FROM t1 LEFT JOIN t2 ON (c = b) + WHERE (a, b) IN (SELECT a, b FROM t1 t); + +EXPLAIN +SELECT * FROM t1 LEFT JOIN t3 ON (c = b) + WHERE (a, b) IN (SELECT a, b FROM t1 t); +SELECT * FROM t1 LEFT JOIN t3 ON (c = b) + WHERE (a, b) IN (SELECT a, b FROM t1 t); + +set join_cache_level=6; + +EXPLAIN +SELECT * FROM t1 LEFT JOIN t2 ON (c = b) + WHERE (a, b) IN (SELECT a, b FROM t1 t); +SELECT * FROM t1 LEFT JOIN t2 ON (c = b) + WHERE (a, b) IN (SELECT a, b FROM t1 t); + +EXPLAIN +SELECT * FROM t1 LEFT JOIN t3 ON (c = b) + WHERE (a, b) IN (SELECT a, b FROM t1 t); +SELECT * FROM t1 LEFT JOIN t3 ON (c = b) + WHERE (a, b) IN (SELECT a, b FROM t1 t); + +set optimizer_switch=@tmp_optimizer_switch; +set join_cache_level=@tmp_join_cache_level; + +DROP TABLE t1,t2,t3; + +--echo # End + set join_cache_level=default; show variables like 'join_cache_level'; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 8eb29853e8d..d8c4ebddc29 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1266,9 +1266,20 @@ JOIN::optimize() Item *ref_item= *ref_item_ptr; if (!ref_item->used_tables() && !(select_options & SELECT_DESCRIBE)) continue; - COND_EQUAL *equals= tab->first_inner ? tab->first_inner->cond_equal : - cond_equal; - ref_item= substitute_for_best_equal_field(tab, ref_item, equals, map2table); + COND_EQUAL *equals= cond_equal; + JOIN_TAB *first_inner= tab->first_inner; + while (equals) + { + ref_item= substitute_for_best_equal_field(tab, ref_item, + equals, map2table); + if (first_inner) + { + equals= first_inner->cond_equal; + first_inner= first_inner->first_upper; + } + else + equals= 0; + } ref_item->update_used_tables(); if (*ref_item_ptr != ref_item) { @@ -9213,7 +9224,7 @@ uint check_join_cache_usage(JOIN_TAB *tab, Check whether table tab and the previous one belong to the same nest of inner tables and if so do not use join buffer when joining table tab. */ - if (tab->first_inner) + if (tab->first_inner && tab != tab->first_inner) { for (JOIN_TAB *first_inner= tab[-1].first_inner; first_inner; @@ -9223,7 +9234,7 @@ uint check_join_cache_usage(JOIN_TAB *tab, goto no_join_cache; } } - else if (tab->first_sj_inner_tab && + else if (tab->first_sj_inner_tab && tab != tab->first_sj_inner_tab && tab->first_sj_inner_tab == tab[-1].first_sj_inner_tab) goto no_join_cache; } From 3ef46370e9719f12e0f8542ab69063eca3922205 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Sat, 18 Feb 2012 19:11:57 -0800 Subject: [PATCH 097/135] Fixed bug #934348. This bug is the result of an incomplete/inconsistent change introduced into 5.3 code when the cond_equal parameter were added to the function optimize_cond. The change was made during a merge from 5.2 in October 2010. The bug could affect only queries with HAVING. --- mysql-test/r/subselect_sj_jcl6.result | 43 +++++++++++++++++++++++++++ mysql-test/t/subselect_sj_jcl6.test | 38 +++++++++++++++++++++++ sql/sql_select.cc | 5 ++-- 3 files changed, 83 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/subselect_sj_jcl6.result b/mysql-test/r/subselect_sj_jcl6.result index 4ac15ea654f..769373429da 100644 --- a/mysql-test/r/subselect_sj_jcl6.result +++ b/mysql-test/r/subselect_sj_jcl6.result @@ -2833,6 +2833,49 @@ set optimizer_switch=@tmp_optimizer_switch; set join_cache_level=@tmp_join_cache_level; DROP TABLE t1,t2,t3; # End +# +# BUG#934348: GROUP BY with HAVING + semijoin materialization +# + join_cache_level > 2 +# +CREATE TABLE t1 (a varchar(1), INDEX idx_a(a)); +INSERT INTO t1 VALUES ('c'), ('v'), ('c'); +CREATE TABLE t2 (b varchar(1)); +INSERT INTO t2 VALUES ('v'), ('c'); +set @tmp_otimizer_switch= @@optimizer_switch; +set @tmp_join_cache_level=@@join_cache_level; +set optimizer_switch = 'materialization=on,semijoin=on,join_cache_hashed=on'; +set join_cache_level=0; +EXPLAIN +SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a) +GROUP BY a HAVING a != 'z'; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ALL distinct_key NULL NULL NULL 2 Using temporary; Using filesort +1 PRIMARY t ref idx_a idx_a 4 test.t2.b 2 Using index +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 Using where +2 MATERIALIZED t1 ref idx_a idx_a 4 test.t2.b 2 Using index +SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a) +GROUP BY a HAVING a != 'z'; +a +c +v +set join_cache_level=6; +EXPLAIN +SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a) +GROUP BY a HAVING a != 'z'; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ALL distinct_key NULL NULL NULL 2 Using temporary; Using filesort +1 PRIMARY t ref idx_a idx_a 4 test.t2.b 2 Using index +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 Using where +2 MATERIALIZED t1 ref idx_a idx_a 4 test.t2.b 2 Using index +SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a) +GROUP BY a HAVING a != 'z'; +a +c +v +set optimizer_switch=@tmp_optimizer_switch; +set join_cache_level=@tmp_join_cache_level; +DROP TABLE t1,t2; +# End set join_cache_level=default; show variables like 'join_cache_level'; Variable_name Value diff --git a/mysql-test/t/subselect_sj_jcl6.test b/mysql-test/t/subselect_sj_jcl6.test index 9fe60cdd3d9..e86ed017951 100644 --- a/mysql-test/t/subselect_sj_jcl6.test +++ b/mysql-test/t/subselect_sj_jcl6.test @@ -170,6 +170,44 @@ DROP TABLE t1,t2,t3; --echo # End +--echo # +--echo # BUG#934348: GROUP BY with HAVING + semijoin materialization +--echo # + join_cache_level > 2 +--echo # + +CREATE TABLE t1 (a varchar(1), INDEX idx_a(a)); +INSERT INTO t1 VALUES ('c'), ('v'), ('c'); + +CREATE TABLE t2 (b varchar(1)); +INSERT INTO t2 VALUES ('v'), ('c'); + +set @tmp_otimizer_switch= @@optimizer_switch; +set @tmp_join_cache_level=@@join_cache_level; +set optimizer_switch = 'materialization=on,semijoin=on,join_cache_hashed=on'; + +set join_cache_level=0; + +EXPLAIN +SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a) + GROUP BY a HAVING a != 'z'; +SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a) + GROUP BY a HAVING a != 'z'; + +set join_cache_level=6; + +EXPLAIN +SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a) + GROUP BY a HAVING a != 'z'; +SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a) + GROUP BY a HAVING a != 'z'; + +set optimizer_switch=@tmp_optimizer_switch; +set join_cache_level=@tmp_join_cache_level; + +DROP TABLE t1,t2; + +--echo # End + set join_cache_level=default; show variables like 'join_cache_level'; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index d8c4ebddc29..eb4c7f7faad 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -12695,9 +12695,8 @@ optimize_cond(JOIN *join, COND *conds, List *join_list, multiple equality contains a constant. */ DBUG_EXECUTE("where", print_where(conds, "original", QT_ORDINARY);); - conds= build_equal_items(join->thd, conds, NULL, join_list, - &join->cond_equal); - DBUG_EXECUTE("where",print_where(conds,"after equal_items", QT_ORDINARY);); + conds= build_equal_items(join->thd, conds, NULL, join_list, cond_equal); + DBUG_EXECUTE("where",print_where(conds,"after equal_items", QT_ORDINARY);); /* change field = field to field = const for each found field = const */ propagate_cond_constants(thd, (I_List *) 0, conds, conds); From fecad7c945f26a3677b17ae6f831ee222d6fc98a Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Mon, 20 Feb 2012 15:30:54 +0400 Subject: [PATCH 098/135] BUG#933407: Valgrind warnings in mark_as_null_row with materialization+semijoin, STRAIGHT_JOIN, impossible WHERE - In return_zero_rows(), don't call mark_as_null_row() for semi-join materialized tables, because 1) they may have been already freed, and 2)there is no real need to call mark_as_null_row() for them. --- mysql-test/r/subselect_mat.result | 13 +++++++++++++ mysql-test/r/subselect_sj_mat.result | 13 +++++++++++++ mysql-test/t/subselect_sj_mat.test | 13 +++++++++++++ sql/sql_select.cc | 14 +++++++++++++- 4 files changed, 52 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/subselect_mat.result b/mysql-test/r/subselect_mat.result index 6f90cc868a6..4d02e5012e2 100644 --- a/mysql-test/r/subselect_mat.result +++ b/mysql-test/r/subselect_mat.result @@ -1848,6 +1848,19 @@ a b 7 5 3 3 drop table t1,t2; +# +# BUG#933407: Valgrind warnings in mark_as_null_row with materialization+semijoin, STRAIGHT_JOIN, impossible WHERE +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (0),(8); +SELECT STRAIGHT_JOIN MIN(a) FROM t1 +WHERE a IN ( +SELECT a FROM t1 +WHERE 'condition'='impossible' + ); +MIN(a) +NULL +DROP TABLE t1; # This must be at the end: set optimizer_switch=@subselect_sj_mat_tmp; set join_cache_level=@save_join_cache_level; diff --git a/mysql-test/r/subselect_sj_mat.result b/mysql-test/r/subselect_sj_mat.result index 964df6735f8..b21236de7b9 100644 --- a/mysql-test/r/subselect_sj_mat.result +++ b/mysql-test/r/subselect_sj_mat.result @@ -1885,6 +1885,19 @@ a b 7 5 3 3 drop table t1,t2; +# +# BUG#933407: Valgrind warnings in mark_as_null_row with materialization+semijoin, STRAIGHT_JOIN, impossible WHERE +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (0),(8); +SELECT STRAIGHT_JOIN MIN(a) FROM t1 +WHERE a IN ( +SELECT a FROM t1 +WHERE 'condition'='impossible' + ); +MIN(a) +NULL +DROP TABLE t1; # This must be at the end: set optimizer_switch=@subselect_sj_mat_tmp; set join_cache_level=@save_join_cache_level; diff --git a/mysql-test/t/subselect_sj_mat.test b/mysql-test/t/subselect_sj_mat.test index 0840029c5e0..0d04b3f984a 100644 --- a/mysql-test/t/subselect_sj_mat.test +++ b/mysql-test/t/subselect_sj_mat.test @@ -1545,6 +1545,19 @@ select * from t1 where t1.a in (select a from t2 where t2.a=7 or t2.b<=1); drop table t1,t2; +--echo # +--echo # BUG#933407: Valgrind warnings in mark_as_null_row with materialization+semijoin, STRAIGHT_JOIN, impossible WHERE +--echo # +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (0),(8); + +SELECT STRAIGHT_JOIN MIN(a) FROM t1 +WHERE a IN ( + SELECT a FROM t1 + WHERE 'condition'='impossible' + ); + +DROP TABLE t1; --echo # This must be at the end: set optimizer_switch=@subselect_sj_mat_tmp; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 8eb29853e8d..547b0b256b3 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -10431,10 +10431,22 @@ return_zero_rows(JOIN *join, select_result *result, List &tables, if (send_row) { + /* + Set all tables to have NULL row. This is needed as we will be evaluating + HAVING condition. + */ List_iterator ti(tables); TABLE_LIST *table; while ((table= ti++)) - mark_as_null_row(table->table); // All fields are NULL + { + /* + Don't touch semi-join materialization tables, as the above join_free() + call has freed them (and HAVING clause can't have references to them + anyway). + */ + if (!table->is_jtbm()) + mark_as_null_row(table->table); // All fields are NULL + } if (having && !having->walk(&Item::clear_sum_processor, FALSE, NULL) && having->val_int() == 0) From 3c07d04580fe5f28ff8bdabd1249b8123d7da76b Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Mon, 20 Feb 2012 14:03:44 +0200 Subject: [PATCH 099/135] Fixed lp:902654 "MariaDB consistently crashes in collect_tables on Aria checkpoint execution" This happend when you have more than 1024 open Aria tables during checkpoint. mysql-test/mysql-test-run.pl: Fixed that variable names are consistent between external and internal server. mysql-test/suite/maria/suite.pm: Test for aria-block-size instead of 'aria' as 'aria' is not set for embedded server. This should be ok for aria tests, as aria is never disabled for these. storage/maria/ma_checkpoint.c: Fixed bug when there are more than 1024 open Aria tables during checkpoint. --- mysql-test/mysql-test-run.pl | 14 ++++++++++---- mysql-test/suite/maria/suite.pm | 2 +- storage/maria/ma_checkpoint.c | 7 +++++-- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index dc03a6bf5b5..9ccfe5df054 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1758,8 +1758,11 @@ sub collect_mysqld_features { # Put variables into hash if ( $line =~ /^([\S]+)[ \t]+(.*?)\r?$/ ) { - # print "$1=\"$2\"\n"; - $mysqld_variables{$1}= $2; + my $name= $1; + my $value=$2; + $name =~ s/_/-/g; + # print "$name=\"$value\"\n"; + $mysqld_variables{$name}= $value; } else { @@ -1813,8 +1816,11 @@ sub collect_mysqld_features_from_running_server () # Put variables into hash if ( $line =~ /^([\S]+)[ \t]+(.*?)\r?$/ ) { - # print "$1=\"$2\"\n"; - $mysqld_variables{$1}= $2; + my $name= $1; + my $value=$2; + $name =~ s/_/-/g; + # print "$name=\"$value\"\n"; + $mysqld_variables{$name}= $value; } } diff --git a/mysql-test/suite/maria/suite.pm b/mysql-test/suite/maria/suite.pm index e6efcdca829..3176782404b 100644 --- a/mysql-test/suite/maria/suite.pm +++ b/mysql-test/suite/maria/suite.pm @@ -2,7 +2,7 @@ package My::Suite::Maria; @ISA = qw(My::Suite); -return "Need Aria engine" unless $::mysqld_variables{'aria'} eq "ON"; +return "Need Aria engine" unless $::mysqld_variables{'aria-block-size'} > 0; bless { }; diff --git a/storage/maria/ma_checkpoint.c b/storage/maria/ma_checkpoint.c index 6576c365a47..002f2999e6c 100644 --- a/storage/maria/ma_checkpoint.c +++ b/storage/maria/ma_checkpoint.c @@ -908,6 +908,9 @@ static int collect_tables(LEX_STRING *str, LSN checkpoint_start_log_horizon) */ } translog_unlock(); + if (state_copy == state_copies) + break; /* Nothing to do */ + /** We are going to flush these states. Before, all records describing how to undo such state must be @@ -932,13 +935,13 @@ static int collect_tables(LEX_STRING *str, LSN checkpoint_start_log_horizon) if (translog_flush(state_copies_horizon)) goto err; /* now we have cached states and they are WAL-safe*/ - state_copies_end= state_copy; + state_copies_end= state_copy-1; state_copy= state_copies; } /* locate our state among these cached ones */ for ( ; state_copy->index != i; state_copy++) - DBUG_ASSERT(state_copy < state_copies_end); + DBUG_ASSERT(state_copy <= state_copies_end); /* OS file descriptors are ints which we stored in 4 bytes */ compile_time_assert(sizeof(int) <= 4); From 54cad2aae3142e8a123f0d62fc0c2bd67a1dc64a Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Mon, 20 Feb 2012 17:56:47 +0200 Subject: [PATCH 100/135] Fixed compiler warnings --- mysys/stacktrace.c | 2 +- sql/mysqld.cc | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/mysys/stacktrace.c b/mysys/stacktrace.c index dce01a0c3b9..847cc746a76 100644 --- a/mysys/stacktrace.c +++ b/mysys/stacktrace.c @@ -173,7 +173,7 @@ void my_print_stacktrace(uchar* stack_bottom __attribute__((unused)), my_safe_printf_stderr("%s", "Error when traversing the stack, stack appears corrupt.\n"); else - my_safe_printf_stderr("%s" + my_safe_printf_stderr("%s", "Please read " "http://dev.mysql.com/doc/refman/5.1/en/resolve-stack-dump.html\n" "and follow instructions on how to resolve the stack trace.\n" diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 9ca0080e976..63495021841 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -741,7 +741,6 @@ char *opt_logname, *opt_slow_logname; static volatile sig_atomic_t kill_in_progress; #ifdef HAVE_STACKTRACE -static my_bool opt_do_pstack; my_bool opt_stack_trace; #endif /* HAVE_STACKTRACE */ my_bool opt_expect_abort= 0; From 84a3767c1912c34e79cde72a51e4cf69d235587e Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Mon, 20 Feb 2012 17:59:42 +0200 Subject: [PATCH 101/135] Fixed issue found by buildbot mysql-test/suite/innodb/t/innodb_bug51920.test: Add another possible connect error --- mysql-test/suite/innodb/t/innodb_bug51920.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/suite/innodb/t/innodb_bug51920.test b/mysql-test/suite/innodb/t/innodb_bug51920.test index bc3bb006c1c..3c386980ed4 100644 --- a/mysql-test/suite/innodb/t/innodb_bug51920.test +++ b/mysql-test/suite/innodb/t/innodb_bug51920.test @@ -36,7 +36,7 @@ let $wait_condition = # depending on platform. # connection con1; --- error 1317, 2006, 2013 +-- error 1317, 2006, 2013, 1927 reap; connection default; DROP TABLE bug51920; From c381e44050303cf12592ae13f401175fa7171a6f Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Mon, 20 Feb 2012 20:38:05 +0400 Subject: [PATCH 102/135] BUG#933412: Server crashes in _mi_put_key_in_record on KILL QUERY with ICP, STRAIGHT_JOIN - In mi_rkey(), do correct handling of case where mi_yield_and_check_if_killed() detects that the thread was killed (all other similar functions in MyISAM/Aria have slightly different code and do not have this problem). - Also fixed assignment in DBUG_ASSERT - this is 2nd variant of the fix: = make .result file smaller = run KILLable statements in a separate connection, otherwise we could end up trying to KILL the final "DROP TABLE" statement --- mysql-test/r/myisam_icp.result | 15 ++++ mysql-test/t/myisam_icp.test | 129 +++++++++++++++++++++++++++++++++ storage/myisam/mi_rkey.c | 6 +- 3 files changed, 149 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/myisam_icp.result b/mysql-test/r/myisam_icp.result index 3171753adb4..d7442608b59 100644 --- a/mysql-test/r/myisam_icp.result +++ b/mysql-test/r/myisam_icp.result @@ -909,4 +909,19 @@ c NULL NULL c NULL NULL SET optimizer_switch=@save_optimizer_switch; DROP TABLE t1,t2,t3,t4; +# +# BUG#933412: Server crashes in _mi_put_key_in_record on KILL QUERY with ICP, STRAIGHT_JOIN +# +CREATE TABLE t1 ( +b INT, +c VARCHAR(1) NOT NULL, +d DATETIME, +KEY (c, b) +) ENGINE=MyISAM; +# INSERT some data +CREATE TABLE t2 ( a INT ) ENGINE=MyISAM; +INSERT INTO t2 VALUES +(7),(3),(7),(3); +# Now run a number of ICP queries while trying to kill them +DROP TABLE t1,t2; set optimizer_switch=@myisam_icp_tmp; diff --git a/mysql-test/t/myisam_icp.test b/mysql-test/t/myisam_icp.test index 0e306a850c5..39a22d00a1a 100644 --- a/mysql-test/t/myisam_icp.test +++ b/mysql-test/t/myisam_icp.test @@ -262,4 +262,133 @@ SET optimizer_switch=@save_optimizer_switch; DROP TABLE t1,t2,t3,t4; +--echo # +--echo # BUG#933412: Server crashes in _mi_put_key_in_record on KILL QUERY with ICP, STRAIGHT_JOIN +--echo # +CREATE TABLE t1 ( + b INT, + c VARCHAR(1) NOT NULL, + d DATETIME, + KEY (c, b) +) ENGINE=MyISAM; +--echo # INSERT some data +--disable_query_log +INSERT INTO t1 ( b, d, c ) VALUES +(4,'2005-01-08 00:00:00','f'), +(1,'2004-05-20 10:45:51','c'),(2,'2006-08-11 21:33:49','e'), +(5,'2003-05-19 00:20:40','a'),(3,'2005-01-03 06:18:39','a'), +(7,'2008-11-25 18:18:14','b'),(6,'2008-11-09 15:53:46','b'), +(9,'2003-03-01 03:40:36','c'),(8,'2003-09-25 23:14:09','d'), +(0,'2007-01-17 09:18:31','f'),(9,'2008-09-08 09:52:24','c'), +(2,'2008-03-10 00:00:00','a'),(0,'2003-03-14 09:31:07','c'), +(4,'2005-04-25 00:00:00','h'),(6,'2001-08-01 05:55:55','e'), +(3,'2005-04-09 01:22:48','f'),(7,'2009-11-12 13:27:22','r'), +(0,'2009-03-28 05:05:28','h'),(15,'2005-05-16 04:35:41','f'), +(7,'2006-03-26 05:19:58','c'),(9,'2002-10-06 02:17:00','g'), +(4,'2007-01-28 03:28:20','b'),(1,'2009-04-22 10:16:40','c'), +(2,'2003-01-01 19:39:00','f'),(0,'2008-05-03 19:16:29','t'), +(2,'2005-01-28 00:00:00','j'),(8,'2004-01-10 00:00:00','w'), +(8,'2000-06-13 21:56:37','a'),(5,'2001-03-21 19:24:49','o'), +(99,'2003-12-20 21:29:06','f'),(0,'1900-01-01 00:00:00','w'), +(7,'2000-12-19 00:00:00','c'),(0,'2000-03-03 06:10:19','l'), +(3,'2000-08-11 00:00:00','q'),(0,'2007-05-25 03:46:41','e'), +(241,'2005-05-17 00:00:00','j'),(4,'2005-11-02 00:44:06','r'), +(43,'2001-07-11 00:00:00','a'),(1,'2008-12-01 18:30:27','z'), +(4,'2004-10-25 00:00:00','i'),(5,'2000-04-08 12:12:01','c'), +(0,'1900-01-01 00:00:00','f'),(9,'2002-05-13 22:47:02','p'), +(1,'2008-10-09 15:39:40','d'),(3,'2004-06-24 00:00:00','d'), +(0,'2008-03-06 00:00:00','r'),(9,'2007-04-16 18:40:03','i'), +(3,'2008-03-16 19:49:37','t'),(7,'2003-07-15 08:11:21','d'), +(8,'2005-02-11 00:04:53','r'),(0,'2002-09-21 00:00:00','y'), +(3,'2004-11-03 00:37:21','z'),(6,'2007-10-18 00:00:00','e'), +(6,'2007-01-21 10:42:56','o'),(5,'2000-03-26 21:21:04','b'), +(9,'2001-03-15 08:08:21','e'),(1,'2001-10-16 12:56:59','a'), +(6,'2004-05-01 23:45:55','o'),(4,'2000-03-04 00:00:00','f'), +(9,'2002-12-03 16:48:28','e'),(8,'2003-01-09 00:36:07','m'), +(1,'2006-06-22 04:32:41','s'),(8,'2008-09-20 05:01:48','q'), +(4,'2006-06-02 22:15:31','g'),(2,'2002-05-14 07:07:42','e'), +(7,'2005-06-05 01:30:42','r'),(127,'2004-05-11 01:56:48','a'), +(210,'2003-11-05 00:41:34','z'),(5,'1900-01-01 00:00:00','h'), +(1,'2006-04-16 00:00:00','f'),(7,'2000-12-17 00:00:00','x'), +(8,'2009-05-09 20:43:07','b'),(175,'2008-11-26 16:33:09','p'), +(0,'2002-05-09 21:18:44','v'),(8,'2002-06-01 11:32:25','k'), +(1,'2008-11-09 23:56:00','a'),(0,'2008-01-08 10:18:46','c'), +(2,'2005-04-16 00:00:00','o'),(5,'2002-08-25 00:00:00','b'), +(64,'2005-12-05 21:51:52','b'),(4,'2005-08-10 00:00:00','i'), +(6,'2006-03-23 00:00:00','d'),(9,'2007-01-27 00:00:00','i'), +(8,'2008-08-16 00:00:00','a'),(7,'2003-01-16 12:13:18','k'), +(0,'2003-06-22 00:00:00','v'),(5,'2008-06-20 05:43:56','u'), +(8,'2004-09-23 18:57:17','e'),(1,'2000-12-26 00:00:00','y'), +(4,'2009-06-01 13:00:28','e'),(1,'2009-11-18 06:28:48','m'), +(0,'2004-06-12 10:01:10','e'),(2,'2005-10-16 01:48:55','e'), +(5,'2001-12-23 09:50:21','l'),(6,'1900-01-01 00:00:00','a'), +(1,'2001-10-28 00:00:00','d'),(1,'2008-07-12 23:30:19','s'), +(0,'2002-10-11 16:51:16','r'),(4,'2007-09-18 06:27:10','x'), +(1,'2007-02-21 12:28:14','e'),(6,'2001-09-16 00:00:00','f'), +(0,'2007-09-20 02:25:45','c'),(0,'2006-08-07 03:25:56','j'), +(8,'2006-12-04 20:20:32','t'),(7,'2007-09-05 10:13:10','i'), +(9,'2006-04-12 17:59:57','t'),(2,'2009-04-28 00:06:09','b'), +(8,'2000-01-07 00:00:00','b'),(7,'2000-03-25 10:04:41','k'), +(4,'2000-07-10 00:44:55','w'),(9,'2007-09-22 14:26:26','j'), +(9,'2003-09-11 22:41:17','a'),(0,'2004-06-07 13:52:32','c'), +(8,'2008-10-09 00:00:00','p'),(1,'2007-04-01 00:00:00','c'), +(9,'2000-12-05 00:00:00','i'),(3,'1900-01-01 00:00:00','a'), +(3,'2005-12-24 21:50:54','e'),(8,'2009-07-21 19:34:55','n'), +(9,'2005-11-13 17:57:56','d'),(7,'2004-10-07 06:41:39','l'), +(1,'2004-11-20 08:05:08','u'),(3,'2005-05-25 00:00:00','r'), +(1,'2006-09-02 14:16:41','u'),(8,'2006-01-07 00:00:00','a'), +(9,'2003-04-05 00:54:20','w'),(2,'2003-12-22 00:00:00','a'), +(9,'2006-04-16 17:31:40','e'),(6,'2005-02-10 14:22:46','e'), +(7,'2004-04-27 05:54:52','p'),(1,'2005-12-07 00:00:00','t'), +(5,'2004-04-03 20:56:28','d'),(4,'2000-09-07 05:17:16','h'), +(2,'2004-08-04 16:10:42','i'),(1,'2007-03-04 00:00:00','b'), +(9,'1900-01-01 00:00:00','d'),(1,'2000-05-12 23:02:50','m'), +(2,'1900-01-01 00:00:00','l'),(1,'1900-01-01 00:00:00','k'), +(4,'2000-07-14 01:25:18','d'),(5,'2009-08-21 00:00:00','w'), +(6,'2009-05-25 13:33:54','f'),(7,'2006-06-13 00:00:00','e'), +(8,'1900-01-01 00:00:00','a'),(6,'2004-02-24 00:00:00','j'), +(0,'2003-05-21 07:03:46','k'),(9,'1900-01-01 00:00:00','e'), +(2,'1900-01-01 00:00:00','y'),(2,'2000-12-22 00:00:00','e'), +(3,'2003-09-26 00:00:00','f'),(2,'2001-01-13 08:20:19','h'), +(9,'2008-09-23 20:03:28','n'),(5,'2007-03-20 02:41:38','s'), +(1,'2009-02-14 10:27:18','a'),(0,'2001-08-10 17:44:05','s'), +(3,'2008-01-20 12:49:54','v'),(1,'2001-05-05 09:09:59','r'); +--enable_query_log +CREATE TABLE t2 ( a INT ) ENGINE=MyISAM; +INSERT INTO t2 VALUES + (7),(3),(7),(3); + +# 'con2' will be the connection that will run all the KILLable statements +--connect (con2,127.0.0.1,root,,test) + +--let $run = 300 +--let $con_id = `SELECT CONNECTION_ID()` + +--echo # Now run a number of ICP queries while trying to kill them +--disable_query_log +--disable_result_log +while ($run) +{ + --send + SELECT * FROM t1 AS alias1 STRAIGHT_JOIN t1 AS alias2 + ON alias2.c = alias1.c + WHERE alias2.b >= 9; + + --connect (con1,127.0.0.1,root,,test) + --eval KILL QUERY $con_id + --disconnect con1 + + --dec $run + + --connection con2 + --error 0,ER_QUERY_INTERRUPTED + --reap +} +--enable_result_log +--enable_query_log +--disconnect con2 +--connection default +DROP TABLE t1,t2; + set optimizer_switch=@myisam_icp_tmp; + diff --git a/storage/myisam/mi_rkey.c b/storage/myisam/mi_rkey.c index dbe4d59ee90..d2af9a3e5ed 100644 --- a/storage/myisam/mi_rkey.c +++ b/storage/myisam/mi_rkey.c @@ -157,7 +157,11 @@ int mi_rkey(MI_INFO *info, uchar *buf, int inx, const uchar *key, mi_yield_and_check_if_killed(info, inx)) { /* Aborted by user */ + DBUG_ASSERT(info->lastpos == HA_OFFSET_ERROR && + my_errno == HA_ERR_ABORTED_BY_USER); + res= ICP_ERROR; buf= 0; /* Fast abort */ + break; } } if (res == ICP_OUT_OF_RANGE) @@ -179,7 +183,7 @@ int mi_rkey(MI_INFO *info, uchar *buf, int inx, const uchar *key, } else { - DBUG_ASSERT(info->lastpos= HA_OFFSET_ERROR); + DBUG_ASSERT(info->lastpos == HA_OFFSET_ERROR); } } if (share->concurrent_insert) From e7fef1df58559f29c16a4571d4218ff291a8050e Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Mon, 20 Feb 2012 18:07:38 +0100 Subject: [PATCH 103/135] Fix compilation on Windows, and various Windows related mistakes introduced by "safe exception patch". Remove misleading comments suggesting about signal() Windows, the routine here is part of a exception handler, and sig parameter is an exception code. --- sql/signal_handler.cc | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/sql/signal_handler.cc b/sql/signal_handler.cc index 23d898fdb5e..6406cd3bae0 100644 --- a/sql/signal_handler.cc +++ b/sql/signal_handler.cc @@ -28,7 +28,7 @@ #endif /* - We are handling signals in this file. + We are handling signals/exceptions in this file. Any global variables we read should be 'volatile sig_atomic_t' to guarantee that we read some consistent value. */ @@ -40,20 +40,18 @@ extern volatile sig_atomic_t ld_assume_kernel_is_set; #endif /** - * Handler for fatal signals + * Handler for fatal signals on POSIX, exception handler on Windows. * * Fatal events (seg.fault, bus error etc.) will trigger * this signal handler. The handler will try to dump relevant * debugging information to stderr and dump a core image. * - * Signal handlers can only use a set of 'safe' system calls - * and library functions. A list of safe calls in POSIX systems + * POSIX : Signal handlers should, if possible, only use a set of 'safe' system + * calls and library functions. A list of safe calls in POSIX systems * are available at: * http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html - * For MS Windows, guidelines are available at: - * http://msdn.microsoft.com/en-us/library/xdkz3x12(v=vs.71).aspx * - * @param sig Signal number + * @param sig Signal number /Exception code */ extern "C" sig_handler handle_fatal_signal(int sig) { @@ -77,7 +75,13 @@ extern "C" sig_handler handle_fatal_signal(int sig) my_safe_printf_stderr("%02d%02d%02d %2d:%02d:%02d ", tm.tm_year % 100, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); - if (opt_expect_abort && sig == SIGABRT) + if (opt_expect_abort +#ifdef _WIN32 + && sig == EXCEPTION_BREAKPOINT /* __debugbreak in my_sigabrt_hander() */ +#else + && sig == SIGABRT +#endif + ) { fprintf(stderr,"[Note] mysqld did an expected abort\n"); goto end; @@ -252,5 +256,7 @@ end: On Windows, do not terminate, but pass control to exception filter. */ _exit(1); // Using _exit(), since exit() is not async signal safe +#else + return; #endif } From 446554a15bd84f39ec4a8163e9f4456fa9be8fb2 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 20 Feb 2012 21:30:23 +0100 Subject: [PATCH 104/135] fix for "relocation R_X86_64_PC32 against `handler_index_cond_check' can not be used when making a shared object; recompile with -fPIC" don't use visibility=hidden for external functions --- storage/xtradb/include/ha_prototypes.h | 1 - 1 file changed, 1 deletion(-) diff --git a/storage/xtradb/include/ha_prototypes.h b/storage/xtradb/include/ha_prototypes.h index 28c28838400..df7d71af6cf 100644 --- a/storage/xtradb/include/ha_prototypes.h +++ b/storage/xtradb/include/ha_prototypes.h @@ -250,7 +250,6 @@ innobase_get_at_most_n_mbchars( /*************************************************************//** InnoDB index push-down condition check @return ICP_NO_MATCH, ICP_MATCH, or ICP_OUT_OF_RANGE */ -UNIV_INTERN enum icp_result handler_index_cond_check( /*================*/ From 7ed4806b1181c1f003d2d31f997a4ca6609ee794 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Tue, 21 Feb 2012 01:44:50 +0200 Subject: [PATCH 105/135] More general handling of memory loss in dlclose (backported from 5.2) Fixed supression in mysql-test-run so it also works on windows. mysql-test/mysql-test-run.pl: Fixed supression so it also works on windows. mysql-test/valgrind.supp: More general handling of memory loss in dlclose (backported from 5.2) sql/signal_handler.cc: Added newlines around link to how to do bug reports --- mysql-test/mysql-test-run.pl | 4 +- mysql-test/valgrind.supp | 130 ++--------------------------------- sql/signal_handler.cc | 4 +- 3 files changed, 11 insertions(+), 127 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index cb6f7b4a486..3e1be3ab077 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -4443,9 +4443,9 @@ sub extract_warning_lines ($) { qr/Failed on request_dump/, qr/Slave: Can't drop database.* database doesn't exist/, qr/Slave: Operation DROP USER failed for 'create_rout_db'/, - qr|Checking table: '\./mtr/test_suppressions'|, + qr|Checking table: '\..mtr.test_suppressions'|, qr|Table \./test/bug53592 has a primary key in InnoDB data dictionary, but not in MySQL|, - qr|mysqld: Table '\./mtr/test_suppressions' is marked as crashed and should be repaired|, + qr|mysqld: Table '\..mtr.test_suppressions' is marked as crashed and should be repaired|, qr|InnoDB: Error: table 'test/bug39438'|, qr|table.*is full|, ); diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp index ff649db144a..e7f5a7880d2 100644 --- a/mysql-test/valgrind.supp +++ b/mysql-test/valgrind.supp @@ -386,134 +386,18 @@ fun:__libc_start_main } +# +# dlclose can allocate memory for error message, the memory will be +# freed by dlerror or other dl* function. +# { - dlclose memory loss from udf_free + memory "loss" from dlclose error messages Memcheck:Leak - fun:calloc - fun:_dlerror_run + fun:*alloc + ... fun:dlclose - fun:_Z8udf_freev } -{ - dlsym memory loss from udf_free on SuSE 11.1 x64 variant 2 - Memcheck:Leak - fun:calloc - obj:/lib*/ld-*.so - fun:dlclose - fun:udf_free -} - -{ - dlclose memory loss from plugin variant 1 - Memcheck:Leak - fun:calloc - fun:_dlerror_run - fun:dlclose - fun:plugin_dl_del(st_mysql_lex_string const*) -} - -{ - dlclose memory loss from plugin variant 2 - Memcheck:Leak - fun:malloc - fun:_dl_close_worker - fun:_dl_close - fun:_dl_catch_error - fun:_dlerror_run - fun:dlclose - fun:_Z15free_plugin_memP12st_plugin_dl - fun:_Z13plugin_dl_delPK19st_mysql_lex_string -} - -{ - dlclose memory loss from plugin variant 3 - Memcheck:Leak - fun:malloc - fun:_dl_scope_free - fun:_dl_close_worker - fun:_dl_close - fun:_dl_catch_error - fun:_dlerror_run - fun:dlclose - fun:_Z15free_plugin_memP12st_plugin_dl - fun:_Z13plugin_dl_delPK19st_mysql_lex_string -} - -{ - dlclose memory loss from plugin variant 4 - Memcheck:Leak - fun:malloc - obj:/lib*/ld-*.so - obj:/lib*/ld-*.so - obj:/lib*/ld-*.so - obj:/lib*/libdl-*.so - fun:dlclose - fun:_ZL15free_plugin_memP12st_plugin_dl - fun:_ZL13plugin_dl_delPK19st_mysql_lex_string -} - -{ - dlclose memory loss from plugin variant 5 - Memcheck:Leak - fun:malloc - obj:/lib*/ld-*.so - obj:/lib*/ld-*.so - obj:/lib*/ld-*.so - obj:/lib*/ld-*.so - obj:/lib*/libdl-*.so - fun:dlclose - fun:_ZL15free_plugin_memP12st_plugin_dl -} - -{ - dlclose memory loss from plugin variant 6, seen on Ubuntu Jaunty i686 - Memcheck:Leak - fun:malloc - fun:_dl_scope_free - fun:_dl_close_worker - fun:_dl_close - fun:dlclose_doit - fun:_dl_catch_error - fun:_dlerror_run - fun:dlclose - fun:_ZL15free_plugin_memP12st_plugin_dl - fun:_ZL13plugin_dl_delPK19st_mysql_lex_string -} - -{ - dlclose memory loss from plugin variant 7, seen on Ubuntu Jaunty i686 - Memcheck:Leak - fun:malloc - fun:_dl_close_worker - fun:_dl_close - fun:dlclose_doit - fun:_dl_catch_error - fun:_dlerror_run - fun:dlclose - fun:_ZL15free_plugin_memP12st_plugin_dl - fun:_ZL13plugin_dl_delPK19st_mysql_lex_string -} - -{ - dlclose memory loss from plugin variant 8 - Memcheck:Leak - fun:calloc - fun:_dlerror_run - fun:dlclose - fun:_Z15free_plugin_memP12st_plugin_dl - fun:_Z13plugin_dl_delPK19st_mysql_lex_string -} - -{ - dlclose memory loss from plugin variant 9 - Memcheck:Leak - fun:calloc - fun:_dlerror_run - fun:dlclose - fun:_ZL15free_plugin_memP12st_plugin_dl - fun:_ZL13plugin_dl_delPK19st_mysql_lex_string -} { dlsym memory loss from plugin on SuSE 11.1 x64 diff --git a/sql/signal_handler.cc b/sql/signal_handler.cc index 23d898fdb5e..289670ec830 100644 --- a/sql/signal_handler.cc +++ b/sql/signal_handler.cc @@ -88,10 +88,10 @@ extern "C" sig_handler handle_fatal_signal(int sig) my_safe_printf_stderr("%s", "This could be because you hit a bug. It is also possible that this binary\n" "or one of the libraries it was linked against is corrupt, improperly built,\n" - "or misconfigured. This error can also be caused by malfunctioning hardware.\n"); + "or misconfigured. This error can also be caused by malfunctioning hardware.\n\n"); my_safe_printf_stderr("%s", - "To report this bug, see http://kb.askmonty.org/en/reporting-bugs\n"); + "To report this bug, see http://kb.askmonty.org/en/reporting-bugs\n\n"); my_safe_printf_stderr("%s", "We will try our best to scrape up some info that will hopefully help\n" From f4885c092e3414cb4274e055310f27eae1d28819 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Tue, 21 Feb 2012 01:46:51 +0200 Subject: [PATCH 106/135] Added missing signal values to signal_handler.cc sql/signal_handler.cc: Added missing signal values. --- sql/signal_handler.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sql/signal_handler.cc b/sql/signal_handler.cc index 23d898fdb5e..13396551e7d 100644 --- a/sql/signal_handler.cc +++ b/sql/signal_handler.cc @@ -173,6 +173,12 @@ extern "C" sig_handler handle_fatal_signal(int sig) case THD::KILL_QUERY: kreason= "KILL_QUERY"; break; + case THD::KILL_SYSTEM_THREAD: + kreason= "KILL_SYSTEM_THREAD"; + break; + case THD::KILL_SERVER: + kreason= "KILL_SERVER"; + break; case THD::KILLED_NO_VALUE: kreason= "KILLED_NO_VALUE"; break; From 3608ec3036fba4921c11e3d2caa3584c41975187 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Tue, 21 Feb 2012 09:35:46 +0200 Subject: [PATCH 107/135] Fixed wrong test case mysql-test/suite/innodb_plugin/t/innodb_gis.test: Don't run test if innodb_plugin isn't used. --- mysql-test/suite/innodb_plugin/t/innodb_gis.test | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/suite/innodb_plugin/t/innodb_gis.test b/mysql-test/suite/innodb_plugin/t/innodb_gis.test index dec0c8bf725..ad1d081f29c 100644 --- a/mysql-test/suite/innodb_plugin/t/innodb_gis.test +++ b/mysql-test/suite/innodb_plugin/t/innodb_gis.test @@ -1,3 +1,4 @@ +--source include/have_innodb_plugin.inc SET storage_engine=innodb; --source include/gis_generic.inc --source include/gis_keys.inc From 70e6f0d854cb7a47bd24e09f1a1723f106afd53f Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Tue, 21 Feb 2012 14:17:33 +0200 Subject: [PATCH 108/135] Fixed suppression expression. --- mysql-test/mysql-test-run.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 3e1be3ab077..34b018bcc47 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -4445,7 +4445,7 @@ sub extract_warning_lines ($) { qr/Slave: Operation DROP USER failed for 'create_rout_db'/, qr|Checking table: '\..mtr.test_suppressions'|, qr|Table \./test/bug53592 has a primary key in InnoDB data dictionary, but not in MySQL|, - qr|mysqld: Table '\..mtr.test_suppressions' is marked as crashed and should be repaired|, + qr|Table '\..mtr.test_suppressions' is marked as crashed and should be repaired|, qr|InnoDB: Error: table 'test/bug39438'|, qr|table.*is full|, ); From 6fbeed067b25a07542dd989b7a816969615d7df6 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Tue, 21 Feb 2012 17:58:43 +0200 Subject: [PATCH 109/135] Fixed that 'make distcheck' works with automake 1.11.11 Fixed compiler warnings found by buildbot Makefile.am: Removed extra empty line cmd-line-utils/libedit/sys.h: Fixed that strndup() doesn't give compiler warnings mysql-test/Makefile.am: Fixes for 'make distcheck' plugin/auth_pam/auth_pam.c: Ensure that prototype for strndup() is included on linux sql/share/Makefile.am: Fixes for 'make distcheck' storage/innodb_plugin/btr/btr0sea.c: Fixed compiler warning support-files/Makefile.am: Fixes for 'make distcheck' --- Makefile.am | 1 - cmd-line-utils/libedit/sys.h | 22 +++++++++++----------- mysql-test/Makefile.am | 2 ++ plugin/auth_pam/auth_pam.c | 4 ++++ sql/share/Makefile.am | 1 + storage/innodb_plugin/btr/btr0sea.c | 4 ++-- support-files/Makefile.am | 3 +++ 7 files changed, 23 insertions(+), 14 deletions(-) diff --git a/Makefile.am b/Makefile.am index cc1156fce5a..f0b617fcb66 100644 --- a/Makefile.am +++ b/Makefile.am @@ -277,7 +277,6 @@ API_PREPROCESSOR_HEADER = $(top_srcdir)/include/mysql.h \ TEST_PREPROCESSOR_HEADER = $(API_PREPROCESSOR_HEADER) \ $(top_srcdir)/sql/mysql_priv.h - # # Rules for checking that the abi/api has not changed. diff --git a/cmd-line-utils/libedit/sys.h b/cmd-line-utils/libedit/sys.h index 33638d1565b..af55bcd7202 100644 --- a/cmd-line-utils/libedit/sys.h +++ b/cmd-line-utils/libedit/sys.h @@ -40,6 +40,17 @@ #ifndef _h_sys #define _h_sys +#ifdef __linux__ +/* Apparently we need _GNU_SOURCE defined to get access to wcsdup on Linux */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#endif + +#ifndef __USE_XOPEN +#define __USE_XOPEN +#endif + #ifdef HAVE_SYS_CDEFS_H #include #endif @@ -92,17 +103,6 @@ size_t strlcpy(char *dst, const char *src, size_t size); char *fgetln(FILE *fp, size_t *len); #endif -#ifdef __linux__ -/* Apparently we need _GNU_SOURCE defined to get access to wcsdup on Linux */ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif -#endif - -#ifndef __USE_XOPEN -#define __USE_XOPEN -#endif - #include #include diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am index 6a1e677fd79..e1780982b8c 100644 --- a/mysql-test/Makefile.am +++ b/mysql-test/Makefile.am @@ -144,6 +144,8 @@ install-data-local: uninstall-local: @RM@ -f -r $(DESTDIR)$(testdir) +uninstall-am: uninstall-local + # mtr - a shortcut for executing mysql-test-run.pl mtr: $(RM) -f mtr diff --git a/plugin/auth_pam/auth_pam.c b/plugin/auth_pam/auth_pam.c index ee13b37f793..de62ebf8dbd 100644 --- a/plugin/auth_pam/auth_pam.c +++ b/plugin/auth_pam/auth_pam.c @@ -1,3 +1,7 @@ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE /* For strndup() */ +#endif + #include #include #include diff --git a/sql/share/Makefile.am b/sql/share/Makefile.am index 892a720900e..8b7792481e6 100644 --- a/sql/share/Makefile.am +++ b/sql/share/Makefile.am @@ -49,6 +49,7 @@ install-data-local: $(INSTALL_DATA) $(srcdir)/charsets/*.xml $(DESTDIR)$(pkgdatadir)/charsets # FIXME maybe shouldn't remove, could be needed by other installation? +# Note that this removes the directory that support-files are using! uninstall-local: @RM@ -f -r $(DESTDIR)$(pkgdatadir) diff --git a/storage/innodb_plugin/btr/btr0sea.c b/storage/innodb_plugin/btr/btr0sea.c index 3dd30cbc0f3..04c273344f3 100644 --- a/storage/innodb_plugin/btr/btr0sea.c +++ b/storage/innodb_plugin/btr/btr0sea.c @@ -827,7 +827,7 @@ btr_search_guess_on_hash( mtr_t* mtr) /*!< in: mtr */ { buf_block_t* block; - const rec_t* rec; + rec_t* rec; ulint fold; dulint index_id; #ifdef notdefined @@ -913,7 +913,7 @@ btr_search_guess_on_hash( ut_ad(page_rec_is_user_rec(rec)); - btr_cur_position(index, (rec_t*) rec, block, cursor); + btr_cur_position(index, rec, block, cursor); /* Check the validity of the guess within the page */ diff --git a/support-files/Makefile.am b/support-files/Makefile.am index 6b5dfbd7d8d..821ba7ffac9 100644 --- a/support-files/Makefile.am +++ b/support-files/Makefile.am @@ -85,6 +85,9 @@ mysql-@VERSION@.spec: mysql.spec rm -f $@ cp mysql.spec $@ +# We don't need to uninstall as sql/share/Makefile.am is doing that for us +uninstall-am: + SUFFIXES = .sh .sh: From c9fc9f73170a8eb16ea968a2ea51b298eb5cdcfc Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 21 Feb 2012 21:18:41 +0100 Subject: [PATCH 110/135] lp:923429 Crash in decimal_cmp on using UNIX_TIMESTAMP with a wrongly formatted timestamp UNIX_TIMESTAMP() can be null, and returns null for invalid values --- mysql-test/r/type_timestamp.result | 13 +++++++++++++ mysql-test/t/type_timestamp.test | 7 +++++++ sql/item_timefunc.cc | 8 -------- sql/item_timefunc.h | 5 ----- 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/mysql-test/r/type_timestamp.result b/mysql-test/r/type_timestamp.result index cfe229d2d15..5c3c3226bf8 100644 --- a/mysql-test/r/type_timestamp.result +++ b/mysql-test/r/type_timestamp.result @@ -587,3 +587,16 @@ Variable_name Value Handler_read_next 1 DROP TABLE t1, t2; End of 5.1 tests +# +# lp:923429 Crash in decimal_cmp on using UNIX_TIMESTAMP with a wrongly formatted timestamp +# +SELECT UNIX_TIMESTAMP('abc') > 0; +UNIX_TIMESTAMP('abc') > 0 +NULL +Warnings: +Warning 1292 Incorrect datetime value: 'abc' +SELECT UNIX_TIMESTAMP('abc'); +UNIX_TIMESTAMP('abc') +NULL +Warnings: +Warning 1292 Incorrect datetime value: 'abc' diff --git a/mysql-test/t/type_timestamp.test b/mysql-test/t/type_timestamp.test index 533a45ba7fe..674f22cd1c2 100644 --- a/mysql-test/t/type_timestamp.test +++ b/mysql-test/t/type_timestamp.test @@ -410,3 +410,10 @@ SHOW STATUS LIKE 'Handler_read_next'; DROP TABLE t1, t2; --echo End of 5.1 tests + +--echo # +--echo # lp:923429 Crash in decimal_cmp on using UNIX_TIMESTAMP with a wrongly formatted timestamp +--echo # +SELECT UNIX_TIMESTAMP('abc') > 0; +SELECT UNIX_TIMESTAMP('abc'); + diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index e01a4399cbe..1002cf9fea8 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -1134,15 +1134,7 @@ bool Item_func_unix_timestamp::get_timestamp_value(my_time_t *seconds, MYSQL_TIME ltime; if (get_arg0_date(<ime, 0)) - { - /* - We have to set null_value again because get_arg0_date will also set it - to true if we have wrong datetime parameter (and we should return 0 in - this case). - */ - null_value= args[0]->null_value; return 1; - } uint error_code; *seconds= TIME_to_timestamp(current_thd, <ime, &error_code); diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index e1bf53a5baf..8d19e59ddfb 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -385,11 +385,6 @@ public: Item_func_unix_timestamp(Item *a) :Item_func_seconds_hybrid(a) {} const char *func_name() const { return "unix_timestamp"; } bool check_partition_func_processor(uchar *int_arg) {return FALSE;} - void fix_num_length_and_dec() - { - maybe_null= false; - Item_func_seconds_hybrid::fix_num_length_and_dec(); - } /* UNIX_TIMESTAMP() depends on the current timezone (and thus may not be used as a partitioning function) From e0a5319db3f09d2f7b1a5caf358ca2f6e296df74 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Wed, 22 Feb 2012 00:10:39 -0800 Subject: [PATCH 111/135] Back-ported the fix and test cases for bugs #59487 and #43368 from the mysql-5.6 code line. --- mysql-test/r/join.result | 49 ++++++++++ mysql-test/r/join_outer_innodb.result | 127 ++++++++++++++++++++++++++ mysql-test/r/select.result | 4 +- mysql-test/r/select_pkeycache.result | 4 +- mysql-test/t/join.test | 42 ++++++++- mysql-test/t/join_outer_innodb.test | 67 ++++++++++++++ sql/sql_select.cc | 1 + 7 files changed, 289 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/join.result b/mysql-test/r/join.result index dae3d16c781..41a05bb00bd 100644 --- a/mysql-test/r/join.result +++ b/mysql-test/r/join.result @@ -1240,3 +1240,52 @@ f1 MIN(f2) drop table t1,t2; drop view v1,v2; End of 5.1 tests +# +# Bug #43368: STRAIGHT_JOIN DOESN'T WORK FOR NESTED JOINS +# +create table t1(c1 int primary key, c2 char(10)) engine=myisam; +create table t2(c1 int primary key, c2 char(10), ref_t1 int) engine=myisam; +create table t3(c1 int primary key, c2 char(10), ref_t1 int) engine=myisam; +create table t4(c1 int primary key, c2 char(10), ref_t1 int) engine=myisam; +insert into t1 values(1,'a'); +insert into t2 values(1,'a', 1); +insert into t3 values(1,'a', 1); +insert into t3 values(2,'b',2); +insert into t4 values(1,'a', 1); +insert into t4 values(2,'a', 2); +insert into t4 values(3,'a', 3); +insert into t4 values(4,'a', 4); +insert into t1 values(2,'b'); +insert into t1 values(3,'c'); +EXPLAIN +SELECT * +FROM t4 JOIN +(t1 JOIN t3 ON t3.ref_t1=t1.c1 JOIN t2 ON t2.ref_t1=t1.c1) +ON t4.ref_t1=t1.c1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 system NULL NULL NULL NULL 1 +1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using where +1 SIMPLE t4 ALL NULL NULL NULL NULL 4 Using where; Using join buffer +EXPLAIN +SELECT STRAIGHT_JOIN * +FROM t4 JOIN +(t1 JOIN t3 ON t3.ref_t1=t1.c1 JOIN t2 ON t2.ref_t1=t1.c1) +ON t4.ref_t1=t1.c1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL NULL NULL NULL NULL 4 +1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where; Using join buffer +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer +1 SIMPLE t2 ALL NULL NULL NULL NULL 1 Using where; Using join buffer +EXPLAIN +SELECT * +FROM t4 STRAIGHT_JOIN +(t1 JOIN t3 ON t3.ref_t1=t1.c1 JOIN t2 ON t2.ref_t1=t1.c1) +ON t4.ref_t1=t1.c1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL NULL NULL NULL NULL 4 +1 SIMPLE t2 ALL NULL NULL NULL NULL 1 Using where; Using join buffer +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t4.ref_t1 1 +drop table t1,t2,t3,t4; +End of 5.2 tests diff --git a/mysql-test/r/join_outer_innodb.result b/mysql-test/r/join_outer_innodb.result index c8bc9758408..80505be79be 100644 --- a/mysql-test/r/join_outer_innodb.result +++ b/mysql-test/r/join_outer_innodb.result @@ -25,3 +25,130 @@ WHERE (t1.b NOT BETWEEN 1 AND 7 OR t1.a IS NULL AND t1.b = t2.b) AND t2.b = 4 GROUP BY 1; a DROP TABLE t1,t2; +# +Bug #59487: WRONG RESULT WITH STRAIGHT_JOIN AND RIGHT JOIN +# +CREATE TABLE t1 ( +pk int(11) NOT NULL, +col_varchar_10_latin1_key varchar(10) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +INSERT INTO t1 VALUES (1,'1'); +CREATE TABLE t2 ( +pk int(11) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +INSERT INTO t2 VALUES (1); +CREATE TABLE t3 ( +pk int(11) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +INSERT INTO t3 VALUES (1); +CREATE TABLE t4 ( +pk int(11) NOT NULL, +col_int int(11) DEFAULT NULL, +col_int_key int(11) DEFAULT NULL, +col_varchar_10_latin1_key varchar(10) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +INSERT INTO t4 VALUES (1,1,1,'1'); +CREATE TABLE t5 ( +col_int int(11) DEFAULT NULL, +col_varchar_10_utf8_key varchar(10) CHARACTER SET utf8 DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +INSERT INTO t5 VALUES (1,'1'); +CREATE TABLE t6 ( +col_int_key int(11) DEFAULT NULL, +col_varchar_10_latin1_key varchar(10) DEFAULT NULL, +pk int(11) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +INSERT INTO t6 VALUES (1,'1',1); +SELECT STRAIGHT_JOIN t6a.pk, t2.pk +FROM t6 AS t6a +LEFT JOIN +( +t2 +RIGHT JOIN +( +(t1 LEFT JOIN (t4 JOIN t3 ON t4.col_int) ON t4.col_int_key = t1.pk) +LEFT JOIN +(t5 JOIN t6 AS t6b +ON t5.col_varchar_10_utf8_key = t6b.col_varchar_10_latin1_key) +ON t1.pk = t5.col_int +) +ON t4.col_varchar_10_latin1_key = t1.col_varchar_10_latin1_key +AND t5.col_varchar_10_utf8_key = 0 +) +ON t6a.pk IS TRUE +WHERE t6b.col_int_key IS TRUE; +pk pk +1 NULL +EXPLAIN SELECT STRAIGHT_JOIN t6a.pk, t2.pk +FROM t6 AS t6a +LEFT JOIN +( +t2 +RIGHT JOIN +( +(t1 LEFT JOIN (t4 JOIN t3 ON t4.col_int) ON t4.col_int_key = t1.pk) +LEFT JOIN +(t5 JOIN t6 AS t6b +ON t5.col_varchar_10_utf8_key = t6b.col_varchar_10_latin1_key) +ON t1.pk = t5.col_int +) +ON t4.col_varchar_10_latin1_key = t1.col_varchar_10_latin1_key +AND t5.col_varchar_10_utf8_key = 0 +) +ON t6a.pk IS TRUE +WHERE t6b.col_int_key IS TRUE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t6a ALL NULL NULL NULL NULL 1 Using where +1 SIMPLE t1 ALL NULL NULL NULL NULL 1 Using join buffer +1 SIMPLE t4 ALL NULL NULL NULL NULL 1 +1 SIMPLE t3 ALL NULL NULL NULL NULL 1 +1 SIMPLE t5 ALL NULL NULL NULL NULL 1 Using where; Using join buffer +1 SIMPLE t6b ALL NULL NULL NULL NULL 1 Using where; Using join buffer +1 SIMPLE t2 ALL NULL NULL NULL NULL 1 +SELECT t6a.pk, t2.pk +FROM t6 AS t6a +LEFT JOIN +( +t2 +RIGHT JOIN +( +(t1 LEFT JOIN (t4 JOIN t3 ON t4.col_int) ON t4.col_int_key = t1.pk) +LEFT JOIN +(t5 JOIN t6 AS t6b +ON t5.col_varchar_10_utf8_key = t6b.col_varchar_10_latin1_key) +ON t1.pk = t5.col_int +) +ON t4.col_varchar_10_latin1_key = t1.col_varchar_10_latin1_key +AND t5.col_varchar_10_utf8_key = 0 +) +ON t6a.pk IS TRUE +WHERE t6b.col_int_key IS TRUE; +pk pk +1 NULL +EXPLAIN SELECT t6a.pk, t2.pk +FROM t6 AS t6a +LEFT JOIN +( +t2 +RIGHT JOIN +( +(t1 LEFT JOIN (t4 JOIN t3 ON t4.col_int) ON t4.col_int_key = t1.pk) +LEFT JOIN +(t5 JOIN t6 AS t6b +ON t5.col_varchar_10_utf8_key = t6b.col_varchar_10_latin1_key) +ON t1.pk = t5.col_int +) +ON t4.col_varchar_10_latin1_key = t1.col_varchar_10_latin1_key +AND t5.col_varchar_10_utf8_key = 0 +) +ON t6a.pk IS TRUE +WHERE t6b.col_int_key IS TRUE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t6a ALL NULL NULL NULL NULL 1 Using where +1 SIMPLE t1 ALL NULL NULL NULL NULL 1 Using join buffer +1 SIMPLE t4 ALL NULL NULL NULL NULL 1 +1 SIMPLE t3 ALL NULL NULL NULL NULL 1 +1 SIMPLE t5 ALL NULL NULL NULL NULL 1 Using where; Using join buffer +1 SIMPLE t2 ALL NULL NULL NULL NULL 1 +1 SIMPLE t6b ALL NULL NULL NULL NULL 1 Using where; Using join buffer +drop table t1,t2,t3,t4,t5,t6; diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index e2c2dcaced4..8f213121c9a 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -4817,10 +4817,10 @@ SET SESSION join_buffer_size = 9000; EXPLAIN SELECT STRAIGHT_JOIN * FROM t2, (t1 LEFT JOIN (t3,t4) ON t1.f1 = t4.f1), t5, t6; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 system NULL NULL NULL NULL 1 1 SIMPLE t2 ALL NULL NULL NULL NULL 12 +1 SIMPLE t1 ALL NULL NULL NULL NULL 1 Using join buffer 1 SIMPLE t3 ALL NULL NULL NULL NULL 1 -1 SIMPLE t4 eq_ref PRIMARY PRIMARY 4 const 1 +1 SIMPLE t4 eq_ref PRIMARY PRIMARY 4 test.t1.f1 1 1 SIMPLE t5 ALL NULL NULL NULL NULL 2 Using join buffer 1 SIMPLE t6 ALL NULL NULL NULL NULL 2 Using join buffer SELECT STRAIGHT_JOIN * FROM t2, (t1 LEFT JOIN (t3,t4) ON t1.f1 = t4.f1), t5, t6; diff --git a/mysql-test/r/select_pkeycache.result b/mysql-test/r/select_pkeycache.result index e2c2dcaced4..8f213121c9a 100644 --- a/mysql-test/r/select_pkeycache.result +++ b/mysql-test/r/select_pkeycache.result @@ -4817,10 +4817,10 @@ SET SESSION join_buffer_size = 9000; EXPLAIN SELECT STRAIGHT_JOIN * FROM t2, (t1 LEFT JOIN (t3,t4) ON t1.f1 = t4.f1), t5, t6; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 system NULL NULL NULL NULL 1 1 SIMPLE t2 ALL NULL NULL NULL NULL 12 +1 SIMPLE t1 ALL NULL NULL NULL NULL 1 Using join buffer 1 SIMPLE t3 ALL NULL NULL NULL NULL 1 -1 SIMPLE t4 eq_ref PRIMARY PRIMARY 4 const 1 +1 SIMPLE t4 eq_ref PRIMARY PRIMARY 4 test.t1.f1 1 1 SIMPLE t5 ALL NULL NULL NULL NULL 2 Using join buffer 1 SIMPLE t6 ALL NULL NULL NULL NULL 2 Using join buffer SELECT STRAIGHT_JOIN * FROM t2, (t1 LEFT JOIN (t3,t4) ON t1.f1 = t4.f1), t5, t6; diff --git a/mysql-test/t/join.test b/mysql-test/t/join.test index 0a573e7cd4f..dc5fc3a2206 100644 --- a/mysql-test/t/join.test +++ b/mysql-test/t/join.test @@ -938,5 +938,45 @@ SELECT f1 , MIN(f2) FROM v2 GROUP BY f1; drop table t1,t2; drop view v1,v2; - --echo End of 5.1 tests + +--echo # +--echo # Bug #43368: STRAIGHT_JOIN DOESN'T WORK FOR NESTED JOINS +--echo # + +create table t1(c1 int primary key, c2 char(10)) engine=myisam; +create table t2(c1 int primary key, c2 char(10), ref_t1 int) engine=myisam; +create table t3(c1 int primary key, c2 char(10), ref_t1 int) engine=myisam; +create table t4(c1 int primary key, c2 char(10), ref_t1 int) engine=myisam; +insert into t1 values(1,'a'); +insert into t2 values(1,'a', 1); +insert into t3 values(1,'a', 1); +insert into t3 values(2,'b',2); +insert into t4 values(1,'a', 1); +insert into t4 values(2,'a', 2); +insert into t4 values(3,'a', 3); +insert into t4 values(4,'a', 4); +insert into t1 values(2,'b'); +insert into t1 values(3,'c'); + +EXPLAIN +SELECT * +FROM t4 JOIN + (t1 JOIN t3 ON t3.ref_t1=t1.c1 JOIN t2 ON t2.ref_t1=t1.c1) + ON t4.ref_t1=t1.c1; + +EXPLAIN +SELECT STRAIGHT_JOIN * +FROM t4 JOIN + (t1 JOIN t3 ON t3.ref_t1=t1.c1 JOIN t2 ON t2.ref_t1=t1.c1) + ON t4.ref_t1=t1.c1; + +EXPLAIN +SELECT * +FROM t4 STRAIGHT_JOIN + (t1 JOIN t3 ON t3.ref_t1=t1.c1 JOIN t2 ON t2.ref_t1=t1.c1) + ON t4.ref_t1=t1.c1; + +drop table t1,t2,t3,t4; + +--echo End of 5.2 tests diff --git a/mysql-test/t/join_outer_innodb.test b/mysql-test/t/join_outer_innodb.test index 565bb72b152..8d6fa71bc8f 100644 --- a/mysql-test/t/join_outer_innodb.test +++ b/mysql-test/t/join_outer_innodb.test @@ -39,3 +39,70 @@ SELECT STRAIGHT_JOIN t1.a FROM t1 RIGHT JOIN t2 ON t1.b = t2.b GROUP BY 1; DROP TABLE t1,t2; + +--echo # +--echo Bug #59487: WRONG RESULT WITH STRAIGHT_JOIN AND RIGHT JOIN +--echo # + +CREATE TABLE t1 ( + pk int(11) NOT NULL, + col_varchar_10_latin1_key varchar(10) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +INSERT INTO t1 VALUES (1,'1'); +CREATE TABLE t2 ( + pk int(11) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +INSERT INTO t2 VALUES (1); +CREATE TABLE t3 ( + pk int(11) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +INSERT INTO t3 VALUES (1); +CREATE TABLE t4 ( + pk int(11) NOT NULL, + col_int int(11) DEFAULT NULL, + col_int_key int(11) DEFAULT NULL, + col_varchar_10_latin1_key varchar(10) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +INSERT INTO t4 VALUES (1,1,1,'1'); +CREATE TABLE t5 ( + col_int int(11) DEFAULT NULL, + col_varchar_10_utf8_key varchar(10) CHARACTER SET utf8 DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +INSERT INTO t5 VALUES (1,'1'); +CREATE TABLE t6 ( + col_int_key int(11) DEFAULT NULL, + col_varchar_10_latin1_key varchar(10) DEFAULT NULL, + pk int(11) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +INSERT INTO t6 VALUES (1,'1',1); + +# EXPLAIN of query above (t2 is before t5 in plan) + +let $rest_of_query=t6a.pk, t2.pk +FROM t6 AS t6a + LEFT JOIN + ( + t2 + RIGHT JOIN + ( + (t1 LEFT JOIN (t4 JOIN t3 ON t4.col_int) ON t4.col_int_key = t1.pk) + LEFT JOIN + (t5 JOIN t6 AS t6b + ON t5.col_varchar_10_utf8_key = t6b.col_varchar_10_latin1_key) + ON t1.pk = t5.col_int + ) + ON t4.col_varchar_10_latin1_key = t1.col_varchar_10_latin1_key + AND t5.col_varchar_10_utf8_key = 0 + ) + ON t6a.pk IS TRUE +WHERE t6b.col_int_key IS TRUE; + +eval SELECT STRAIGHT_JOIN $rest_of_query; +eval EXPLAIN SELECT STRAIGHT_JOIN $rest_of_query; + +# right result (same query, just remove STRAIGHT_JOIN): + +eval SELECT $rest_of_query; +eval EXPLAIN SELECT $rest_of_query; + +drop table t1,t2,t3,t4,t5,t6; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 3cf0800a62f..7a70c9bdf44 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -9067,6 +9067,7 @@ simplify_joins(JOIN *join, List *join_list, COND *conds, bool top) if (!tbl->embedding && !tbl->on_expr && tbl->table) tbl->table->maybe_null= FALSE; tbl->join_list= table->join_list; + tbl->dep_tables|= table->dep_tables; } li.replace(nested_join->join_list); /* Need to update the name resolution table chain when flattening joins */ From c299e027eeddc35e0197ebc70805e0a303a4b135 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 22 Feb 2012 10:38:28 +0200 Subject: [PATCH 112/135] Changed names of statistic variables and counting matches instaed of rejected rows. --- mysql-test/include/icp_tests.inc | 6 +++--- mysql-test/r/innodb_icp.result | 18 +++++++++--------- mysql-test/r/join_cache.result | 24 ++++++++++++------------ mysql-test/r/maria_icp.result | 18 +++++++++--------- mysql-test/r/myisam_icp.result | 18 +++++++++--------- mysql-test/r/status.result | 8 ++++---- mysql-test/r/status_user.result | 4 ++-- mysql-test/t/join_cache.test | 8 ++++---- sql/handler.cc | 6 +++--- sql/mysqld.cc | 4 ++-- sql/sql_class.h | 4 ++-- sql/sql_join_cache.cc | 12 ++++++------ 12 files changed, 65 insertions(+), 65 deletions(-) diff --git a/mysql-test/include/icp_tests.inc b/mysql-test/include/icp_tests.inc index f412843ded0..e84b8622cdb 100644 --- a/mysql-test/include/icp_tests.inc +++ b/mysql-test/include/icp_tests.inc @@ -862,15 +862,15 @@ CREATE TABLE t1 ( INSERT INTO t1 VALUES ('3', '3'),('4','4'),('5','5'); flush status; -show status like "Handler_pushed%"; +show status like "Handler_icp%"; SELECT * FROM t1 FORCE INDEX(c1) WHERE (c1='3' or c1='4') and c1 % 2 = 0 ; -show status like "Handler_pushed%"; +show status like "Handler_icp%"; SELECT * FROM t1 WHERE (c2='3' or c2='4') and c2 % 2 = 0 ; -show status like "Handler_pushed%"; +show status like "Handler_icp%"; DROP TABLE t1; diff --git a/mysql-test/r/innodb_icp.result b/mysql-test/r/innodb_icp.result index d8e41113f63..2817f83bed5 100644 --- a/mysql-test/r/innodb_icp.result +++ b/mysql-test/r/innodb_icp.result @@ -816,24 +816,24 @@ KEY (c1) ); INSERT INTO t1 VALUES ('3', '3'),('4','4'),('5','5'); flush status; -show status like "Handler_pushed%"; +show status like "Handler_icp%"; Variable_name Value -Handler_pushed_index_cond_checks 0 -Handler_pushed_index_cond_filtered 0 +Handler_icp_attempts 0 +Handler_icp_match 0 SELECT * FROM t1 FORCE INDEX(c1) WHERE (c1='3' or c1='4') and c1 % 2 = 0 ; c1 c2 4 4 -show status like "Handler_pushed%"; +show status like "Handler_icp%"; Variable_name Value -Handler_pushed_index_cond_checks 2 -Handler_pushed_index_cond_filtered 1 +Handler_icp_attempts 2 +Handler_icp_match 1 SELECT * FROM t1 WHERE (c2='3' or c2='4') and c2 % 2 = 0 ; c1 c2 4 4 -show status like "Handler_pushed%"; +show status like "Handler_icp%"; Variable_name Value -Handler_pushed_index_cond_checks 2 -Handler_pushed_index_cond_filtered 1 +Handler_icp_attempts 2 +Handler_icp_match 1 DROP TABLE t1; set optimizer_switch=@innodb_icp_tmp; set storage_engine= @save_storage_engine; diff --git a/mysql-test/r/join_cache.result b/mysql-test/r/join_cache.result index 6908f40e854..9918ad2380d 100644 --- a/mysql-test/r/join_cache.result +++ b/mysql-test/r/join_cache.result @@ -3520,10 +3520,10 @@ where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where 1 SIMPLE t2 ref f1 f1 4 test.t1.f1 3 Using index condition(BKA); Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan -show status like "Handler_pushed%"; +show status like "Handler_icp%"; Variable_name Value -Handler_pushed_index_cond_checks 20 -Handler_pushed_index_cond_filtered 16 +Handler_icp_attempts 20 +Handler_icp_match 4 set join_cache_level=6; select t2.f1, t2.f2, t2.f3 from t1,t2 where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1; @@ -3537,10 +3537,10 @@ where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where 1 SIMPLE t2 ref f1 f1 4 test.t1.f1 3 Using index condition(BKA); Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan -show status like "Handler_pushed%"; +show status like "Handler_icp%"; Variable_name Value -Handler_pushed_index_cond_checks 40 -Handler_pushed_index_cond_filtered 32 +Handler_icp_attempts 40 +Handler_icp_match 8 set join_cache_level=7; select t2.f1, t2.f2, t2.f3 from t1,t2 where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1; @@ -3554,10 +3554,10 @@ where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where 1 SIMPLE t2 ref f1 f1 4 test.t1.f1 3 Using index condition(BKA); Using where; Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan -show status like "Handler_pushed%"; +show status like "Handler_icp%"; Variable_name Value -Handler_pushed_index_cond_checks 60 -Handler_pushed_index_cond_filtered 48 +Handler_icp_attempts 60 +Handler_icp_match 12 set join_cache_level=8; select t2.f1, t2.f2, t2.f3 from t1,t2 where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1; @@ -3571,10 +3571,10 @@ where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where 1 SIMPLE t2 ref f1 f1 4 test.t1.f1 3 Using index condition(BKA); Using where; Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan -show status like "Handler_pushed%"; +show status like "Handler_icp%"; Variable_name Value -Handler_pushed_index_cond_checks 80 -Handler_pushed_index_cond_filtered 64 +Handler_icp_attempts 80 +Handler_icp_match 16 drop table t1,t2; set join_cache_level=default; # diff --git a/mysql-test/r/maria_icp.result b/mysql-test/r/maria_icp.result index b9d3ca6c7c0..97b10fe496c 100644 --- a/mysql-test/r/maria_icp.result +++ b/mysql-test/r/maria_icp.result @@ -822,24 +822,24 @@ KEY (c1) ); INSERT INTO t1 VALUES ('3', '3'),('4','4'),('5','5'); flush status; -show status like "Handler_pushed%"; +show status like "Handler_icp%"; Variable_name Value -Handler_pushed_index_cond_checks 0 -Handler_pushed_index_cond_filtered 0 +Handler_icp_attempts 0 +Handler_icp_match 0 SELECT * FROM t1 FORCE INDEX(c1) WHERE (c1='3' or c1='4') and c1 % 2 = 0 ; c1 c2 4 4 -show status like "Handler_pushed%"; +show status like "Handler_icp%"; Variable_name Value -Handler_pushed_index_cond_checks 2 -Handler_pushed_index_cond_filtered 1 +Handler_icp_attempts 2 +Handler_icp_match 1 SELECT * FROM t1 WHERE (c2='3' or c2='4') and c2 % 2 = 0 ; c1 c2 4 4 -show status like "Handler_pushed%"; +show status like "Handler_icp%"; Variable_name Value -Handler_pushed_index_cond_checks 2 -Handler_pushed_index_cond_filtered 1 +Handler_icp_attempts 2 +Handler_icp_match 1 DROP TABLE t1; set storage_engine= @save_storage_engine; set optimizer_switch=@maria_icp_tmp; diff --git a/mysql-test/r/myisam_icp.result b/mysql-test/r/myisam_icp.result index d7442608b59..85a2ad921c6 100644 --- a/mysql-test/r/myisam_icp.result +++ b/mysql-test/r/myisam_icp.result @@ -820,24 +820,24 @@ KEY (c1) ); INSERT INTO t1 VALUES ('3', '3'),('4','4'),('5','5'); flush status; -show status like "Handler_pushed%"; +show status like "Handler_icp%"; Variable_name Value -Handler_pushed_index_cond_checks 0 -Handler_pushed_index_cond_filtered 0 +Handler_icp_attempts 0 +Handler_icp_match 0 SELECT * FROM t1 FORCE INDEX(c1) WHERE (c1='3' or c1='4') and c1 % 2 = 0 ; c1 c2 4 4 -show status like "Handler_pushed%"; +show status like "Handler_icp%"; Variable_name Value -Handler_pushed_index_cond_checks 2 -Handler_pushed_index_cond_filtered 1 +Handler_icp_attempts 2 +Handler_icp_match 1 SELECT * FROM t1 WHERE (c2='3' or c2='4') and c2 % 2 = 0 ; c1 c2 4 4 -show status like "Handler_pushed%"; +show status like "Handler_icp%"; Variable_name Value -Handler_pushed_index_cond_checks 2 -Handler_pushed_index_cond_filtered 1 +Handler_icp_attempts 2 +Handler_icp_match 1 DROP TABLE t1; drop table if exists t0, t1, t1i, t1m; # diff --git a/mysql-test/r/status.result b/mysql-test/r/status.result index e75cabe0e58..b5bae659eed 100644 --- a/mysql-test/r/status.result +++ b/mysql-test/r/status.result @@ -275,9 +275,9 @@ Variable_name Value Handler_commit 0 Handler_delete 0 Handler_discover 0 +Handler_icp_attempts 0 +Handler_icp_match 0 Handler_prepare 0 -Handler_pushed_index_cond_checks 0 -Handler_pushed_index_cond_filtered 0 Handler_read_first 0 Handler_read_key 4 Handler_read_next 0 @@ -312,9 +312,9 @@ Variable_name Value Handler_commit 0 Handler_delete 0 Handler_discover 0 +Handler_icp_attempts 0 +Handler_icp_match 0 Handler_prepare 0 -Handler_pushed_index_cond_checks 0 -Handler_pushed_index_cond_filtered 0 Handler_read_first 0 Handler_read_key 2 Handler_read_next 2 diff --git a/mysql-test/r/status_user.result b/mysql-test/r/status_user.result index 175839b2098..be0cfef79dc 100644 --- a/mysql-test/r/status_user.result +++ b/mysql-test/r/status_user.result @@ -100,9 +100,9 @@ Variable_name Value Handler_commit 19 Handler_delete 1 Handler_discover 0 +Handler_icp_attempts 0 +Handler_icp_match 0 Handler_prepare 18 -Handler_pushed_index_cond_checks 0 -Handler_pushed_index_cond_filtered 0 Handler_read_first 0 Handler_read_key 3 Handler_read_next 0 diff --git a/mysql-test/t/join_cache.test b/mysql-test/t/join_cache.test index 6cb8f48bd70..0962f1bf766 100644 --- a/mysql-test/t/join_cache.test +++ b/mysql-test/t/join_cache.test @@ -1533,7 +1533,7 @@ where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1; explain select t2.f1, t2.f2, t2.f3 from t1,t2 where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2; -show status like "Handler_pushed%"; +show status like "Handler_icp%"; set join_cache_level=6; select t2.f1, t2.f2, t2.f3 from t1,t2 @@ -1541,7 +1541,7 @@ where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1; explain select t2.f1, t2.f2, t2.f3 from t1,t2 where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2; -show status like "Handler_pushed%"; +show status like "Handler_icp%"; set join_cache_level=7; select t2.f1, t2.f2, t2.f3 from t1,t2 @@ -1549,7 +1549,7 @@ where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1; explain select t2.f1, t2.f2, t2.f3 from t1,t2 where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2; -show status like "Handler_pushed%"; +show status like "Handler_icp%"; set join_cache_level=8; select t2.f1, t2.f2, t2.f3 from t1,t2 @@ -1557,7 +1557,7 @@ where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1; explain select t2.f1, t2.f2, t2.f3 from t1,t2 where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2; -show status like "Handler_pushed%"; +show status like "Handler_icp%"; drop table t1,t2; set join_cache_level=default; diff --git a/sql/handler.cc b/sql/handler.cc index 4a8cd77ebc3..04f10586484 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -4569,10 +4569,10 @@ extern "C" enum icp_result handler_index_cond_check(void* h_arg) if (h->end_range && h->compare_key2(h->end_range) > 0) return ICP_OUT_OF_RANGE; - h->increment_statistics(&SSV::ha_pushed_index_cond_checks); + h->increment_statistics(&SSV::ha_icp_attempts); if ((res= h->pushed_idx_cond->val_int()? ICP_MATCH : ICP_NO_MATCH) == - ICP_NO_MATCH) - h->increment_statistics(&SSV::ha_pushed_index_cond_filtered); + ICP_MATCH) + h->increment_statistics(&SSV::ha_icp_match); return res; } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 70dba70eb15..147c2e80be3 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -8107,9 +8107,9 @@ SHOW_VAR status_vars[]= { {"Handler_mrr_extra_rowid_sorts", (char*) offsetof(STATUS_VAR, ha_mrr_extra_rowid_sorts), SHOW_LONG_STATUS}, {"Handler_mrr_init", (char*) offsetof(STATUS_VAR, ha_multi_range_read_init_count), SHOW_LONG_STATUS}, #endif + {"Handler_icp_attempts ", (char*) offsetof(STATUS_VAR, ha_icp_attempts), SHOW_LONG_STATUS}, + {"Handler_icp_match", (char*) offsetof(STATUS_VAR, ha_icp_match), SHOW_LONG_STATUS}, {"Handler_prepare", (char*) offsetof(STATUS_VAR, ha_prepare_count), SHOW_LONG_STATUS}, - {"Handler_pushed_index_cond_checks",(char*) offsetof(STATUS_VAR, ha_pushed_index_cond_checks), SHOW_LONG_STATUS}, - {"Handler_pushed_index_cond_filtered",(char*) offsetof(STATUS_VAR, ha_pushed_index_cond_filtered), SHOW_LONG_STATUS}, {"Handler_read_first", (char*) offsetof(STATUS_VAR, ha_read_first_count), SHOW_LONG_STATUS}, {"Handler_read_key", (char*) offsetof(STATUS_VAR, ha_read_key_count), SHOW_LONG_STATUS}, {"Handler_read_next", (char*) offsetof(STATUS_VAR, ha_read_next_count), SHOW_LONG_STATUS}, diff --git a/sql/sql_class.h b/sql/sql_class.h index c04af55a127..3b94270ae08 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -588,8 +588,8 @@ typedef struct system_status_var ulong ha_tmp_update_count; ulong ha_tmp_write_count; ulong ha_prepare_count; - ulong ha_pushed_index_cond_checks; - ulong ha_pushed_index_cond_filtered; + ulong ha_icp_attempts; + ulong ha_icp_match; ulong ha_discover_count; ulong ha_savepoint_count; ulong ha_savepoint_rollback_count; diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc index 15b5efbfacb..a960c63e782 100644 --- a/sql/sql_join_cache.cc +++ b/sql/sql_join_cache.cc @@ -4026,9 +4026,9 @@ bool bka_skip_index_tuple(range_seq_t rseq, range_id_t range_info) JOIN_CACHE_BKA *cache= (JOIN_CACHE_BKA *) rseq; THD *thd= cache->thd(); bool res; - status_var_increment(thd->status_var.ha_pushed_index_cond_checks); - if ((res= cache->skip_index_tuple(range_info))) - status_var_increment(thd->status_var.ha_pushed_index_cond_filtered); + status_var_increment(thd->status_var.ha_icp_attempts); + if (!(res= cache->skip_index_tuple(range_info))) + status_var_increment(thd->status_var.ha_icp_match); DBUG_RETURN(res); } @@ -4505,9 +4505,9 @@ bool bkah_skip_index_tuple(range_seq_t rseq, range_id_t range_info) JOIN_CACHE_BKAH *cache= (JOIN_CACHE_BKAH *) rseq; THD *thd= cache->thd(); bool res; - status_var_increment(thd->status_var.ha_pushed_index_cond_checks); - if ((res= cache->skip_index_tuple(range_info))) - status_var_increment(thd->status_var.ha_pushed_index_cond_filtered); + status_var_increment(thd->status_var.ha_icp_attempts); + if (!(res= cache->skip_index_tuple(range_info))) + status_var_increment(thd->status_var.ha_icp_match); DBUG_RETURN(res); } From 59b2bb9aca0fb037ab4c770a8fd684a3d4a40587 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Wed, 22 Feb 2012 16:48:29 +0400 Subject: [PATCH 113/135] Added back MRR counters. The new names are: Handler_mrr_init, Handler_mrr_key_refills, Handler_mrr_rowid_refills. --- mysql-test/r/myisam_mrr.result | 15 +++++++++++++++ mysql-test/r/status.result | 8 +++++++- mysql-test/r/status_user.result | 3 +++ sql/multi_range_read.cc | 12 ++++++++---- sql/mysqld.cc | 11 +++++------ sql/sql_class.h | 6 +++--- 6 files changed, 41 insertions(+), 14 deletions(-) diff --git a/mysql-test/r/myisam_mrr.result b/mysql-test/r/myisam_mrr.result index c2f382eb9e6..0ea75c8aebb 100644 --- a/mysql-test/r/myisam_mrr.result +++ b/mysql-test/r/myisam_mrr.result @@ -563,6 +563,9 @@ drop table t1; flush status; show status like 'Handler_mrr%'; Variable_name Value +Handler_mrr_init 0 +Handler_mrr_key_refills 0 +Handler_mrr_rowid_refills 0 create table t0 (a int); insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); create table t1 (a int, b int, filler char(200), key(a)); @@ -578,6 +581,9 @@ sum(b) 1230 show status like 'handler_mrr%'; Variable_name Value +Handler_mrr_init 1 +Handler_mrr_key_refills 0 +Handler_mrr_rowid_refills 0 set @mrr_buffer_size_save= @@mrr_buffer_size; set mrr_buffer_size=128; explain select sum(b) from t1 where a < 1600; @@ -590,6 +596,9 @@ sum(b) 196800 show status like 'handler_mrr%'; Variable_name Value +Handler_mrr_init 1 +Handler_mrr_key_refills 0 +Handler_mrr_rowid_refills 1 set @@mrr_buffer_size= @mrr_buffer_size_save; #Now, let's check BKA: set @join_cache_level_save= @@join_cache_level; @@ -605,6 +614,9 @@ sum(t1.b) 1230 show status like 'handler_mrr%'; Variable_name Value +Handler_mrr_init 1 +Handler_mrr_key_refills 0 +Handler_mrr_rowid_refills 0 set join_buffer_size=10; explain select sum(t1.b) from t0,t1 where t0.a=t1.a; id select_type table type possible_keys key key_len ref rows Extra @@ -616,6 +628,9 @@ sum(t1.b) 1230 show status like 'handler_mrr%'; Variable_name Value +Handler_mrr_init 1or2 +Handler_mrr_key_refills 1or2 +Handler_mrr_rowid_refills 1or2 set join_cache_level= @join_cache_level_save; set join_buffer_size= @join_buffer_size_save; drop table t0, t1; diff --git a/mysql-test/r/status.result b/mysql-test/r/status.result index b5bae659eed..d3e1d26cbbd 100644 --- a/mysql-test/r/status.result +++ b/mysql-test/r/status.result @@ -277,6 +277,9 @@ Handler_delete 0 Handler_discover 0 Handler_icp_attempts 0 Handler_icp_match 0 +Handler_mrr_init 0 +Handler_mrr_key_refills 0 +Handler_mrr_rowid_refills 0 Handler_prepare 0 Handler_read_first 0 Handler_read_key 4 @@ -299,7 +302,7 @@ Created_tmp_files 0 Created_tmp_tables 2 Handler_tmp_update 2 Handler_tmp_write 7 -Rows_tmp_read 37 +Rows_tmp_read 40 drop table t1; CREATE TABLE t1 (i int(11) DEFAULT NULL, KEY i (i) ) ENGINE=MyISAM; insert into t1 values (1),(2),(3),(4),(5); @@ -314,6 +317,9 @@ Handler_delete 0 Handler_discover 0 Handler_icp_attempts 0 Handler_icp_match 0 +Handler_mrr_init 0 +Handler_mrr_key_refills 0 +Handler_mrr_rowid_refills 0 Handler_prepare 0 Handler_read_first 0 Handler_read_key 2 diff --git a/mysql-test/r/status_user.result b/mysql-test/r/status_user.result index be0cfef79dc..b2d4b6f761f 100644 --- a/mysql-test/r/status_user.result +++ b/mysql-test/r/status_user.result @@ -102,6 +102,9 @@ Handler_delete 1 Handler_discover 0 Handler_icp_attempts 0 Handler_icp_match 0 +Handler_mrr_init 0 +Handler_mrr_key_refills 0 +Handler_mrr_rowid_refills 0 Handler_prepare 18 Handler_read_first 0 Handler_read_key 3 diff --git a/sql/multi_range_read.cc b/sql/multi_range_read.cc index 6ecc64207de..e86c9ca251c 100644 --- a/sql/multi_range_read.cc +++ b/sql/multi_range_read.cc @@ -510,7 +510,7 @@ int Mrr_ordered_index_reader::refill_buffer(bool initial) { /* This is a non-initial buffer fill and we've got a non-empty buffer */ THD *thd= current_thd; - status_var_increment(thd->status_var.ha_mrr_extra_key_sorts); + status_var_increment(thd->status_var.ha_mrr_key_refills_count); } key_buffer->sort((key_buffer->type() == Lifo_buffer::FORWARD)? @@ -610,7 +610,7 @@ int Mrr_ordered_rndpos_reader::refill_buffer(bool initial) { /* Ok, this was a successful buffer refill operation */ THD *thd= current_thd; - status_var_increment(thd->status_var.ha_mrr_extra_rowid_sorts); + status_var_increment(thd->status_var.ha_mrr_rowid_refills_count); } DBUG_RETURN(res); @@ -845,8 +845,6 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs, strategy= disk_strategy= &reader_factory.ordered_rndpos_reader; } - status_var_increment(thd->status_var.ha_multi_range_read_init_count); - full_buf= buf->buffer; full_buf_end= buf->buffer_end; @@ -936,6 +934,12 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs, goto error; } } + + /* + At this point, we're sure that we're running a native MRR scan (i.e. we + didnt fall back to default implementation for some reason). + */ + status_var_increment(thd->status_var.ha_mrr_init_count); res= strategy->refill_buffer(TRUE); if (res) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 147c2e80be3..484bfd168c7 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -8101,12 +8101,11 @@ SHOW_VAR status_vars[]= { {"Handler_commit", (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONG_STATUS}, {"Handler_delete", (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONG_STATUS}, {"Handler_discover", (char*) offsetof(STATUS_VAR, ha_discover_count), SHOW_LONG_STATUS}, -#if 0 - /* Made 3 counters below temporarily invisible until we agree upon their names */ - {"Handler_mrr_extra_key_sorts", (char*) offsetof(STATUS_VAR, ha_mrr_extra_key_sorts), SHOW_LONG_STATUS}, - {"Handler_mrr_extra_rowid_sorts", (char*) offsetof(STATUS_VAR, ha_mrr_extra_rowid_sorts), SHOW_LONG_STATUS}, - {"Handler_mrr_init", (char*) offsetof(STATUS_VAR, ha_multi_range_read_init_count), SHOW_LONG_STATUS}, -#endif + + {"Handler_mrr_key_refills", (char*) offsetof(STATUS_VAR, ha_mrr_key_refills_count), SHOW_LONG_STATUS}, + {"Handler_mrr_rowid_refills", (char*) offsetof(STATUS_VAR, ha_mrr_rowid_refills_count), SHOW_LONG_STATUS}, + {"Handler_mrr_init", (char*) offsetof(STATUS_VAR, ha_mrr_init_count), SHOW_LONG_STATUS}, + {"Handler_icp_attempts ", (char*) offsetof(STATUS_VAR, ha_icp_attempts), SHOW_LONG_STATUS}, {"Handler_icp_match", (char*) offsetof(STATUS_VAR, ha_icp_match), SHOW_LONG_STATUS}, {"Handler_prepare", (char*) offsetof(STATUS_VAR, ha_prepare_count), SHOW_LONG_STATUS}, diff --git a/sql/sql_class.h b/sql/sql_class.h index 3b94270ae08..c5f500a6b18 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -577,9 +577,9 @@ typedef struct system_status_var calls made by range access. The intent is to count only calls made by BatchedKeyAccess. */ - ulong ha_multi_range_read_init_count; - ulong ha_mrr_extra_key_sorts; - ulong ha_mrr_extra_rowid_sorts; + ulong ha_mrr_init_count; + ulong ha_mrr_key_refills_count; + ulong ha_mrr_rowid_refills_count; ulong ha_rollback_count; ulong ha_update_count; From 917455911f1ec995e40ac8b47f3c78ad503e7a95 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Wed, 22 Feb 2012 17:11:33 +0400 Subject: [PATCH 114/135] Sort counters by their names (otherwise, the order of SHOW STATUS output is sometimes sorted and sometimes not) --- sql/mysqld.cc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 484bfd168c7..aa3942521ed 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -8102,12 +8102,13 @@ SHOW_VAR status_vars[]= { {"Handler_delete", (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONG_STATUS}, {"Handler_discover", (char*) offsetof(STATUS_VAR, ha_discover_count), SHOW_LONG_STATUS}, - {"Handler_mrr_key_refills", (char*) offsetof(STATUS_VAR, ha_mrr_key_refills_count), SHOW_LONG_STATUS}, - {"Handler_mrr_rowid_refills", (char*) offsetof(STATUS_VAR, ha_mrr_rowid_refills_count), SHOW_LONG_STATUS}, - {"Handler_mrr_init", (char*) offsetof(STATUS_VAR, ha_mrr_init_count), SHOW_LONG_STATUS}, - {"Handler_icp_attempts ", (char*) offsetof(STATUS_VAR, ha_icp_attempts), SHOW_LONG_STATUS}, {"Handler_icp_match", (char*) offsetof(STATUS_VAR, ha_icp_match), SHOW_LONG_STATUS}, + + {"Handler_mrr_init", (char*) offsetof(STATUS_VAR, ha_mrr_init_count), SHOW_LONG_STATUS}, + {"Handler_mrr_key_refills", (char*) offsetof(STATUS_VAR, ha_mrr_key_refills_count), SHOW_LONG_STATUS}, + {"Handler_mrr_rowid_refills", (char*) offsetof(STATUS_VAR, ha_mrr_rowid_refills_count), SHOW_LONG_STATUS}, + {"Handler_prepare", (char*) offsetof(STATUS_VAR, ha_prepare_count), SHOW_LONG_STATUS}, {"Handler_read_first", (char*) offsetof(STATUS_VAR, ha_read_first_count), SHOW_LONG_STATUS}, {"Handler_read_key", (char*) offsetof(STATUS_VAR, ha_read_key_count), SHOW_LONG_STATUS}, From 567d871ff0c9cbdcaa4f9daa6810760edc901e14 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Wed, 22 Feb 2012 17:38:24 +0400 Subject: [PATCH 115/135] Don't run test for BUG#933412 with embedded server, as it requires concurrent query execution which mtr --embedded does not support --- mysql-test/r/myisam_icp.result | 15 --- mysql-test/r/myisam_icp_notembedded.result | 19 +++ mysql-test/t/myisam_icp.test | 128 ------------------- mysql-test/t/myisam_icp_notembedded.test | 139 +++++++++++++++++++++ 4 files changed, 158 insertions(+), 143 deletions(-) create mode 100644 mysql-test/r/myisam_icp_notembedded.result create mode 100644 mysql-test/t/myisam_icp_notembedded.test diff --git a/mysql-test/r/myisam_icp.result b/mysql-test/r/myisam_icp.result index 85a2ad921c6..188347c3324 100644 --- a/mysql-test/r/myisam_icp.result +++ b/mysql-test/r/myisam_icp.result @@ -909,19 +909,4 @@ c NULL NULL c NULL NULL SET optimizer_switch=@save_optimizer_switch; DROP TABLE t1,t2,t3,t4; -# -# BUG#933412: Server crashes in _mi_put_key_in_record on KILL QUERY with ICP, STRAIGHT_JOIN -# -CREATE TABLE t1 ( -b INT, -c VARCHAR(1) NOT NULL, -d DATETIME, -KEY (c, b) -) ENGINE=MyISAM; -# INSERT some data -CREATE TABLE t2 ( a INT ) ENGINE=MyISAM; -INSERT INTO t2 VALUES -(7),(3),(7),(3); -# Now run a number of ICP queries while trying to kill them -DROP TABLE t1,t2; set optimizer_switch=@myisam_icp_tmp; diff --git a/mysql-test/r/myisam_icp_notembedded.result b/mysql-test/r/myisam_icp_notembedded.result new file mode 100644 index 00000000000..d965cbd980d --- /dev/null +++ b/mysql-test/r/myisam_icp_notembedded.result @@ -0,0 +1,19 @@ +drop table if exists t1,t2; +set @myisam_icp_notembedded_tmp=@@optimizer_switch; +set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; +# +# BUG#933412: Server crashes in _mi_put_key_in_record on KILL QUERY with ICP, STRAIGHT_JOIN +# +CREATE TABLE t1 ( +b INT, +c VARCHAR(1) NOT NULL, +d DATETIME, +KEY (c, b) +) ENGINE=MyISAM; +# INSERT some data +CREATE TABLE t2 ( a INT ) ENGINE=MyISAM; +INSERT INTO t2 VALUES +(7),(3),(7),(3); +# Now run a number of ICP queries while trying to kill them +DROP TABLE t1,t2; +set optimizer_switch=@myisam_icp_notembedded_tmp; diff --git a/mysql-test/t/myisam_icp.test b/mysql-test/t/myisam_icp.test index 39a22d00a1a..5bee6e5acaa 100644 --- a/mysql-test/t/myisam_icp.test +++ b/mysql-test/t/myisam_icp.test @@ -262,133 +262,5 @@ SET optimizer_switch=@save_optimizer_switch; DROP TABLE t1,t2,t3,t4; ---echo # ---echo # BUG#933412: Server crashes in _mi_put_key_in_record on KILL QUERY with ICP, STRAIGHT_JOIN ---echo # -CREATE TABLE t1 ( - b INT, - c VARCHAR(1) NOT NULL, - d DATETIME, - KEY (c, b) -) ENGINE=MyISAM; ---echo # INSERT some data ---disable_query_log -INSERT INTO t1 ( b, d, c ) VALUES -(4,'2005-01-08 00:00:00','f'), -(1,'2004-05-20 10:45:51','c'),(2,'2006-08-11 21:33:49','e'), -(5,'2003-05-19 00:20:40','a'),(3,'2005-01-03 06:18:39','a'), -(7,'2008-11-25 18:18:14','b'),(6,'2008-11-09 15:53:46','b'), -(9,'2003-03-01 03:40:36','c'),(8,'2003-09-25 23:14:09','d'), -(0,'2007-01-17 09:18:31','f'),(9,'2008-09-08 09:52:24','c'), -(2,'2008-03-10 00:00:00','a'),(0,'2003-03-14 09:31:07','c'), -(4,'2005-04-25 00:00:00','h'),(6,'2001-08-01 05:55:55','e'), -(3,'2005-04-09 01:22:48','f'),(7,'2009-11-12 13:27:22','r'), -(0,'2009-03-28 05:05:28','h'),(15,'2005-05-16 04:35:41','f'), -(7,'2006-03-26 05:19:58','c'),(9,'2002-10-06 02:17:00','g'), -(4,'2007-01-28 03:28:20','b'),(1,'2009-04-22 10:16:40','c'), -(2,'2003-01-01 19:39:00','f'),(0,'2008-05-03 19:16:29','t'), -(2,'2005-01-28 00:00:00','j'),(8,'2004-01-10 00:00:00','w'), -(8,'2000-06-13 21:56:37','a'),(5,'2001-03-21 19:24:49','o'), -(99,'2003-12-20 21:29:06','f'),(0,'1900-01-01 00:00:00','w'), -(7,'2000-12-19 00:00:00','c'),(0,'2000-03-03 06:10:19','l'), -(3,'2000-08-11 00:00:00','q'),(0,'2007-05-25 03:46:41','e'), -(241,'2005-05-17 00:00:00','j'),(4,'2005-11-02 00:44:06','r'), -(43,'2001-07-11 00:00:00','a'),(1,'2008-12-01 18:30:27','z'), -(4,'2004-10-25 00:00:00','i'),(5,'2000-04-08 12:12:01','c'), -(0,'1900-01-01 00:00:00','f'),(9,'2002-05-13 22:47:02','p'), -(1,'2008-10-09 15:39:40','d'),(3,'2004-06-24 00:00:00','d'), -(0,'2008-03-06 00:00:00','r'),(9,'2007-04-16 18:40:03','i'), -(3,'2008-03-16 19:49:37','t'),(7,'2003-07-15 08:11:21','d'), -(8,'2005-02-11 00:04:53','r'),(0,'2002-09-21 00:00:00','y'), -(3,'2004-11-03 00:37:21','z'),(6,'2007-10-18 00:00:00','e'), -(6,'2007-01-21 10:42:56','o'),(5,'2000-03-26 21:21:04','b'), -(9,'2001-03-15 08:08:21','e'),(1,'2001-10-16 12:56:59','a'), -(6,'2004-05-01 23:45:55','o'),(4,'2000-03-04 00:00:00','f'), -(9,'2002-12-03 16:48:28','e'),(8,'2003-01-09 00:36:07','m'), -(1,'2006-06-22 04:32:41','s'),(8,'2008-09-20 05:01:48','q'), -(4,'2006-06-02 22:15:31','g'),(2,'2002-05-14 07:07:42','e'), -(7,'2005-06-05 01:30:42','r'),(127,'2004-05-11 01:56:48','a'), -(210,'2003-11-05 00:41:34','z'),(5,'1900-01-01 00:00:00','h'), -(1,'2006-04-16 00:00:00','f'),(7,'2000-12-17 00:00:00','x'), -(8,'2009-05-09 20:43:07','b'),(175,'2008-11-26 16:33:09','p'), -(0,'2002-05-09 21:18:44','v'),(8,'2002-06-01 11:32:25','k'), -(1,'2008-11-09 23:56:00','a'),(0,'2008-01-08 10:18:46','c'), -(2,'2005-04-16 00:00:00','o'),(5,'2002-08-25 00:00:00','b'), -(64,'2005-12-05 21:51:52','b'),(4,'2005-08-10 00:00:00','i'), -(6,'2006-03-23 00:00:00','d'),(9,'2007-01-27 00:00:00','i'), -(8,'2008-08-16 00:00:00','a'),(7,'2003-01-16 12:13:18','k'), -(0,'2003-06-22 00:00:00','v'),(5,'2008-06-20 05:43:56','u'), -(8,'2004-09-23 18:57:17','e'),(1,'2000-12-26 00:00:00','y'), -(4,'2009-06-01 13:00:28','e'),(1,'2009-11-18 06:28:48','m'), -(0,'2004-06-12 10:01:10','e'),(2,'2005-10-16 01:48:55','e'), -(5,'2001-12-23 09:50:21','l'),(6,'1900-01-01 00:00:00','a'), -(1,'2001-10-28 00:00:00','d'),(1,'2008-07-12 23:30:19','s'), -(0,'2002-10-11 16:51:16','r'),(4,'2007-09-18 06:27:10','x'), -(1,'2007-02-21 12:28:14','e'),(6,'2001-09-16 00:00:00','f'), -(0,'2007-09-20 02:25:45','c'),(0,'2006-08-07 03:25:56','j'), -(8,'2006-12-04 20:20:32','t'),(7,'2007-09-05 10:13:10','i'), -(9,'2006-04-12 17:59:57','t'),(2,'2009-04-28 00:06:09','b'), -(8,'2000-01-07 00:00:00','b'),(7,'2000-03-25 10:04:41','k'), -(4,'2000-07-10 00:44:55','w'),(9,'2007-09-22 14:26:26','j'), -(9,'2003-09-11 22:41:17','a'),(0,'2004-06-07 13:52:32','c'), -(8,'2008-10-09 00:00:00','p'),(1,'2007-04-01 00:00:00','c'), -(9,'2000-12-05 00:00:00','i'),(3,'1900-01-01 00:00:00','a'), -(3,'2005-12-24 21:50:54','e'),(8,'2009-07-21 19:34:55','n'), -(9,'2005-11-13 17:57:56','d'),(7,'2004-10-07 06:41:39','l'), -(1,'2004-11-20 08:05:08','u'),(3,'2005-05-25 00:00:00','r'), -(1,'2006-09-02 14:16:41','u'),(8,'2006-01-07 00:00:00','a'), -(9,'2003-04-05 00:54:20','w'),(2,'2003-12-22 00:00:00','a'), -(9,'2006-04-16 17:31:40','e'),(6,'2005-02-10 14:22:46','e'), -(7,'2004-04-27 05:54:52','p'),(1,'2005-12-07 00:00:00','t'), -(5,'2004-04-03 20:56:28','d'),(4,'2000-09-07 05:17:16','h'), -(2,'2004-08-04 16:10:42','i'),(1,'2007-03-04 00:00:00','b'), -(9,'1900-01-01 00:00:00','d'),(1,'2000-05-12 23:02:50','m'), -(2,'1900-01-01 00:00:00','l'),(1,'1900-01-01 00:00:00','k'), -(4,'2000-07-14 01:25:18','d'),(5,'2009-08-21 00:00:00','w'), -(6,'2009-05-25 13:33:54','f'),(7,'2006-06-13 00:00:00','e'), -(8,'1900-01-01 00:00:00','a'),(6,'2004-02-24 00:00:00','j'), -(0,'2003-05-21 07:03:46','k'),(9,'1900-01-01 00:00:00','e'), -(2,'1900-01-01 00:00:00','y'),(2,'2000-12-22 00:00:00','e'), -(3,'2003-09-26 00:00:00','f'),(2,'2001-01-13 08:20:19','h'), -(9,'2008-09-23 20:03:28','n'),(5,'2007-03-20 02:41:38','s'), -(1,'2009-02-14 10:27:18','a'),(0,'2001-08-10 17:44:05','s'), -(3,'2008-01-20 12:49:54','v'),(1,'2001-05-05 09:09:59','r'); ---enable_query_log -CREATE TABLE t2 ( a INT ) ENGINE=MyISAM; -INSERT INTO t2 VALUES - (7),(3),(7),(3); - -# 'con2' will be the connection that will run all the KILLable statements ---connect (con2,127.0.0.1,root,,test) - ---let $run = 300 ---let $con_id = `SELECT CONNECTION_ID()` - ---echo # Now run a number of ICP queries while trying to kill them ---disable_query_log ---disable_result_log -while ($run) -{ - --send - SELECT * FROM t1 AS alias1 STRAIGHT_JOIN t1 AS alias2 - ON alias2.c = alias1.c - WHERE alias2.b >= 9; - - --connect (con1,127.0.0.1,root,,test) - --eval KILL QUERY $con_id - --disconnect con1 - - --dec $run - - --connection con2 - --error 0,ER_QUERY_INTERRUPTED - --reap -} ---enable_result_log ---enable_query_log ---disconnect con2 ---connection default -DROP TABLE t1,t2; - set optimizer_switch=@myisam_icp_tmp; diff --git a/mysql-test/t/myisam_icp_notembedded.test b/mysql-test/t/myisam_icp_notembedded.test new file mode 100644 index 00000000000..139a9edf648 --- /dev/null +++ b/mysql-test/t/myisam_icp_notembedded.test @@ -0,0 +1,139 @@ +-- source include/not_embedded.inc + +--disable_warnings +drop table if exists t1,t2; +--enable_warnings + +set @myisam_icp_notembedded_tmp=@@optimizer_switch; +set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; + +--echo # +--echo # BUG#933412: Server crashes in _mi_put_key_in_record on KILL QUERY with ICP, STRAIGHT_JOIN +--echo # +CREATE TABLE t1 ( + b INT, + c VARCHAR(1) NOT NULL, + d DATETIME, + KEY (c, b) +) ENGINE=MyISAM; +--echo # INSERT some data +--disable_query_log +INSERT INTO t1 ( b, d, c ) VALUES +(4,'2005-01-08 00:00:00','f'), +(1,'2004-05-20 10:45:51','c'),(2,'2006-08-11 21:33:49','e'), +(5,'2003-05-19 00:20:40','a'),(3,'2005-01-03 06:18:39','a'), +(7,'2008-11-25 18:18:14','b'),(6,'2008-11-09 15:53:46','b'), +(9,'2003-03-01 03:40:36','c'),(8,'2003-09-25 23:14:09','d'), +(0,'2007-01-17 09:18:31','f'),(9,'2008-09-08 09:52:24','c'), +(2,'2008-03-10 00:00:00','a'),(0,'2003-03-14 09:31:07','c'), +(4,'2005-04-25 00:00:00','h'),(6,'2001-08-01 05:55:55','e'), +(3,'2005-04-09 01:22:48','f'),(7,'2009-11-12 13:27:22','r'), +(0,'2009-03-28 05:05:28','h'),(15,'2005-05-16 04:35:41','f'), +(7,'2006-03-26 05:19:58','c'),(9,'2002-10-06 02:17:00','g'), +(4,'2007-01-28 03:28:20','b'),(1,'2009-04-22 10:16:40','c'), +(2,'2003-01-01 19:39:00','f'),(0,'2008-05-03 19:16:29','t'), +(2,'2005-01-28 00:00:00','j'),(8,'2004-01-10 00:00:00','w'), +(8,'2000-06-13 21:56:37','a'),(5,'2001-03-21 19:24:49','o'), +(99,'2003-12-20 21:29:06','f'),(0,'1900-01-01 00:00:00','w'), +(7,'2000-12-19 00:00:00','c'),(0,'2000-03-03 06:10:19','l'), +(3,'2000-08-11 00:00:00','q'),(0,'2007-05-25 03:46:41','e'), +(241,'2005-05-17 00:00:00','j'),(4,'2005-11-02 00:44:06','r'), +(43,'2001-07-11 00:00:00','a'),(1,'2008-12-01 18:30:27','z'), +(4,'2004-10-25 00:00:00','i'),(5,'2000-04-08 12:12:01','c'), +(0,'1900-01-01 00:00:00','f'),(9,'2002-05-13 22:47:02','p'), +(1,'2008-10-09 15:39:40','d'),(3,'2004-06-24 00:00:00','d'), +(0,'2008-03-06 00:00:00','r'),(9,'2007-04-16 18:40:03','i'), +(3,'2008-03-16 19:49:37','t'),(7,'2003-07-15 08:11:21','d'), +(8,'2005-02-11 00:04:53','r'),(0,'2002-09-21 00:00:00','y'), +(3,'2004-11-03 00:37:21','z'),(6,'2007-10-18 00:00:00','e'), +(6,'2007-01-21 10:42:56','o'),(5,'2000-03-26 21:21:04','b'), +(9,'2001-03-15 08:08:21','e'),(1,'2001-10-16 12:56:59','a'), +(6,'2004-05-01 23:45:55','o'),(4,'2000-03-04 00:00:00','f'), +(9,'2002-12-03 16:48:28','e'),(8,'2003-01-09 00:36:07','m'), +(1,'2006-06-22 04:32:41','s'),(8,'2008-09-20 05:01:48','q'), +(4,'2006-06-02 22:15:31','g'),(2,'2002-05-14 07:07:42','e'), +(7,'2005-06-05 01:30:42','r'),(127,'2004-05-11 01:56:48','a'), +(210,'2003-11-05 00:41:34','z'),(5,'1900-01-01 00:00:00','h'), +(1,'2006-04-16 00:00:00','f'),(7,'2000-12-17 00:00:00','x'), +(8,'2009-05-09 20:43:07','b'),(175,'2008-11-26 16:33:09','p'), +(0,'2002-05-09 21:18:44','v'),(8,'2002-06-01 11:32:25','k'), +(1,'2008-11-09 23:56:00','a'),(0,'2008-01-08 10:18:46','c'), +(2,'2005-04-16 00:00:00','o'),(5,'2002-08-25 00:00:00','b'), +(64,'2005-12-05 21:51:52','b'),(4,'2005-08-10 00:00:00','i'), +(6,'2006-03-23 00:00:00','d'),(9,'2007-01-27 00:00:00','i'), +(8,'2008-08-16 00:00:00','a'),(7,'2003-01-16 12:13:18','k'), +(0,'2003-06-22 00:00:00','v'),(5,'2008-06-20 05:43:56','u'), +(8,'2004-09-23 18:57:17','e'),(1,'2000-12-26 00:00:00','y'), +(4,'2009-06-01 13:00:28','e'),(1,'2009-11-18 06:28:48','m'), +(0,'2004-06-12 10:01:10','e'),(2,'2005-10-16 01:48:55','e'), +(5,'2001-12-23 09:50:21','l'),(6,'1900-01-01 00:00:00','a'), +(1,'2001-10-28 00:00:00','d'),(1,'2008-07-12 23:30:19','s'), +(0,'2002-10-11 16:51:16','r'),(4,'2007-09-18 06:27:10','x'), +(1,'2007-02-21 12:28:14','e'),(6,'2001-09-16 00:00:00','f'), +(0,'2007-09-20 02:25:45','c'),(0,'2006-08-07 03:25:56','j'), +(8,'2006-12-04 20:20:32','t'),(7,'2007-09-05 10:13:10','i'), +(9,'2006-04-12 17:59:57','t'),(2,'2009-04-28 00:06:09','b'), +(8,'2000-01-07 00:00:00','b'),(7,'2000-03-25 10:04:41','k'), +(4,'2000-07-10 00:44:55','w'),(9,'2007-09-22 14:26:26','j'), +(9,'2003-09-11 22:41:17','a'),(0,'2004-06-07 13:52:32','c'), +(8,'2008-10-09 00:00:00','p'),(1,'2007-04-01 00:00:00','c'), +(9,'2000-12-05 00:00:00','i'),(3,'1900-01-01 00:00:00','a'), +(3,'2005-12-24 21:50:54','e'),(8,'2009-07-21 19:34:55','n'), +(9,'2005-11-13 17:57:56','d'),(7,'2004-10-07 06:41:39','l'), +(1,'2004-11-20 08:05:08','u'),(3,'2005-05-25 00:00:00','r'), +(1,'2006-09-02 14:16:41','u'),(8,'2006-01-07 00:00:00','a'), +(9,'2003-04-05 00:54:20','w'),(2,'2003-12-22 00:00:00','a'), +(9,'2006-04-16 17:31:40','e'),(6,'2005-02-10 14:22:46','e'), +(7,'2004-04-27 05:54:52','p'),(1,'2005-12-07 00:00:00','t'), +(5,'2004-04-03 20:56:28','d'),(4,'2000-09-07 05:17:16','h'), +(2,'2004-08-04 16:10:42','i'),(1,'2007-03-04 00:00:00','b'), +(9,'1900-01-01 00:00:00','d'),(1,'2000-05-12 23:02:50','m'), +(2,'1900-01-01 00:00:00','l'),(1,'1900-01-01 00:00:00','k'), +(4,'2000-07-14 01:25:18','d'),(5,'2009-08-21 00:00:00','w'), +(6,'2009-05-25 13:33:54','f'),(7,'2006-06-13 00:00:00','e'), +(8,'1900-01-01 00:00:00','a'),(6,'2004-02-24 00:00:00','j'), +(0,'2003-05-21 07:03:46','k'),(9,'1900-01-01 00:00:00','e'), +(2,'1900-01-01 00:00:00','y'),(2,'2000-12-22 00:00:00','e'), +(3,'2003-09-26 00:00:00','f'),(2,'2001-01-13 08:20:19','h'), +(9,'2008-09-23 20:03:28','n'),(5,'2007-03-20 02:41:38','s'), +(1,'2009-02-14 10:27:18','a'),(0,'2001-08-10 17:44:05','s'), +(3,'2008-01-20 12:49:54','v'),(1,'2001-05-05 09:09:59','r'); +--enable_query_log +CREATE TABLE t2 ( a INT ) ENGINE=MyISAM; +INSERT INTO t2 VALUES + (7),(3),(7),(3); + +# 'con2' will be the connection that will run all the KILLable statements +--connect (con2,127.0.0.1,root,,test) + +--let $run = 300 +--let $con_id = `SELECT CONNECTION_ID()` + +--echo # Now run a number of ICP queries while trying to kill them +--disable_query_log +--disable_result_log +while ($run) +{ + --send + SELECT * FROM t1 AS alias1 STRAIGHT_JOIN t1 AS alias2 + ON alias2.c = alias1.c + WHERE alias2.b >= 9; + + --connect (con1,127.0.0.1,root,,test) + --eval KILL QUERY $con_id + --disconnect con1 + + --dec $run + + --connection con2 + --error 0,ER_QUERY_INTERRUPTED + --reap +} +--enable_result_log +--enable_query_log +--disconnect con2 +--connection default +DROP TABLE t1,t2; + +set optimizer_switch=@myisam_icp_notembedded_tmp; + From 2b625ac3e0b2173df18c69df63af00dd03e8c672 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Thu, 23 Feb 2012 16:43:35 +0200 Subject: [PATCH 116/135] Fixed lp:933719, "Assertion open_tables == 0 ... " in THD::restore_backup_open_tables_state. This also fixes a (not likely) crashing bug when forcing a thread that was doing a table lock to re-open it's files, for example by creating a trigger. mysys/thr_lock.c: Added more checking to find wrong locks. Removed one, not needed, parameter to thr_lock sql/lock.cc: Fixed mysql_lock_tables() to retry with new sql_lock if lock fails. This was needed as table may be closed and reopened between retry's and then the old sql_lock will point to stale data. sql/mysql_priv.h: Updated prototype sql/sql_base.cc: Ensure that all tables are closed if opening of system table failes; This fixes the assert in THD::restore_backup_open_tables_state sql/sql_handler.cc: Updated variable type --- mysys/thr_lock.c | 41 +++++--- sql/lock.cc | 242 +++++++++++++++++++++++++-------------------- sql/mysql_priv.h | 6 +- sql/sql_base.cc | 11 +-- sql/sql_handler.cc | 2 +- 5 files changed, 176 insertions(+), 126 deletions(-) diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c index 99a498cfdd5..32b38105d1f 100644 --- a/mysys/thr_lock.c +++ b/mysys/thr_lock.c @@ -168,7 +168,8 @@ thr_lock_owner_equal(THR_LOCK_OWNER *rhs, THR_LOCK_OWNER *lhs) static uint found_errors=0; static int check_lock(struct st_lock_list *list, const char* lock_type, - const char *where, my_bool same_owner, my_bool no_cond) + const char *where, my_bool same_owner, my_bool no_cond, + my_bool read_lock) { THR_LOCK_DATA *data,**prev; uint count=0; @@ -181,6 +182,23 @@ static int check_lock(struct st_lock_list *list, const char* lock_type, for (data=list->data; data && count++ < MAX_LOCKS ; data=data->next) { + if (data->type == TL_UNLOCK) + { + fprintf(stderr, + "Warning: Found unlocked lock at %s: %s\n", + lock_type, where); + return 1; + } + if ((read_lock && data->type > TL_READ_NO_INSERT) || + (!read_lock && data->type <= TL_READ_NO_INSERT)) + { + fprintf(stderr, + "Warning: Found %s lock in %s queue at %s: %s\n", + read_lock ? "write" : "read", + read_lock ? "read" : "write", + lock_type, where); + return 1; + } if (data->type != last_lock_type) last_lock_type=TL_IGNORE; if (data->prev != prev) @@ -237,11 +255,14 @@ static void check_locks(THR_LOCK *lock, const char *where, if (found_errors < MAX_FOUND_ERRORS) { - if (check_lock(&lock->write,"write",where,1,1) | - check_lock(&lock->write_wait,"write_wait",where,0,0) | - check_lock(&lock->read,"read",where,0,1) | - check_lock(&lock->read_wait,"read_wait",where,0,0)) + if (check_lock(&lock->write,"write",where,1,1,0) | + check_lock(&lock->write_wait,"write_wait",where,0,0,0) | + check_lock(&lock->read,"read",where,0,1,1) | + check_lock(&lock->read_wait,"read_wait",where,0,0,1)) + { + DBUG_ASSERT(my_assert_on_error == 0); found_errors++; + } if (found_errors < MAX_FOUND_ERRORS) { @@ -592,18 +613,17 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data, static enum enum_thr_lock_result -thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner, - enum thr_lock_type lock_type) +thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner) { THR_LOCK *lock=data->lock; enum enum_thr_lock_result result= THR_LOCK_SUCCESS; struct st_lock_list *wait_queue; THR_LOCK_DATA *lock_owner; + enum thr_lock_type lock_type= data->type; DBUG_ENTER("thr_lock"); data->next=0; data->cond=0; /* safety */ - data->type=lock_type; data->owner= owner; /* Must be reset ! */ data->priority&= ~THR_LOCK_LATE_PRIV; VOID(pthread_mutex_lock(&lock->mutex)); @@ -912,9 +932,7 @@ void thr_unlock(THR_LOCK_DATA *data, uint unlock_flags) if (lock_type == TL_READ_NO_INSERT) lock->read_no_write_count--; data->type=TL_UNLOCK; /* Mark unlocked */ - check_locks(lock,"after releasing lock", lock_type, 1); wake_up_waiters(lock); - check_locks(lock,"end of thr_unlock", lock_type, 1); pthread_mutex_unlock(&lock->mutex); DBUG_VOID_RETURN; } @@ -934,6 +952,7 @@ static void wake_up_waiters(THR_LOCK *lock) enum thr_lock_type lock_type; DBUG_ENTER("wake_up_waiters"); + check_locks(lock, "before waking up waiters", TL_UNLOCK, 1); if (!lock->write.data) /* If no active write locks */ { data=lock->write_wait.data; @@ -1087,7 +1106,7 @@ thr_multi_lock(THR_LOCK_DATA **data, uint count, THR_LOCK_OWNER *owner) /* lock everything */ for (pos=data,end=data+count; pos < end ; pos++) { - enum enum_thr_lock_result result= thr_lock(*pos, owner, (*pos)->type); + enum enum_thr_lock_result result= thr_lock(*pos, owner); if (result != THR_LOCK_SUCCESS) { /* Aborted */ thr_multi_unlock(data,(uint) (pos-data), 0); diff --git a/sql/lock.cc b/sql/lock.cc index 3f9b3a9e18b..57ced99417b 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -195,31 +195,33 @@ int mysql_lock_tables_check(THD *thd, TABLE **tables, uint count, uint flags) MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, uint flags, bool *need_reopen) { - TABLE *write_lock_used; MYSQL_LOCK *sql_lock; + TABLE *write_lock_used; + int rc; DBUG_ENTER("mysql_lock_tables(tables)"); *need_reopen= FALSE; + if (mysql_lock_tables_check(thd, tables, count, flags)) - DBUG_RETURN(NULL); + DBUG_RETURN (NULL); - if (!(sql_lock= get_lock_data(thd, tables, count, GET_LOCK_STORE_LOCKS, - &write_lock_used)) || - ! sql_lock->table_count) - DBUG_RETURN(sql_lock); - - if (mysql_lock_tables(thd, sql_lock, write_lock_used != 0, flags, - need_reopen)) + for (;;) { - /* Clear the lock type of all lock data to avoid reusage. */ - reset_lock_data(sql_lock, 1); + if (!(sql_lock= get_lock_data(thd, tables, count, GET_LOCK_STORE_LOCKS, + &write_lock_used)) || + !sql_lock->table_count) + break; + rc= mysql_lock_tables(thd, sql_lock, write_lock_used != 0, flags, + need_reopen); + if (!rc) + break; // Got lock my_free(sql_lock, MYF(0)); - sql_lock= 0; + if (rc > 0) + DBUG_RETURN(0); // Failed } DBUG_RETURN(sql_lock); } - /** Lock a table based on a MYSQL_LOCK structure. @@ -232,120 +234,150 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, @param need_reopen Out parameter, TRUE if some tables were altered or deleted and should be reopened by caller. - @return 0 ok - @return 1 error + @return 0 ok + @return 1 fatal error + @return -1 retry */ -bool mysql_lock_tables(THD *thd, MYSQL_LOCK *sql_lock, - bool write_lock_used, - uint flags, bool *need_reopen) +int mysql_lock_tables(THD *thd, MYSQL_LOCK *sql_lock, + bool write_lock_used, + uint flags, bool *need_reopen) { + int res= 0; int rc; - bool error= 1; DBUG_ENTER("mysql_lock_tables(sql_lock)"); - *need_reopen= FALSE; - for (;;) + + if (write_lock_used && !(flags & MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK)) { - if (write_lock_used && !(flags & MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK)) - { - if (global_read_lock) - { - /* - Someone has issued LOCK ALL TABLES FOR READ and we want a write lock - Wait until the lock is gone - */ - if (wait_if_global_read_lock(thd, 1, 1)) - break; - if (thd->version != refresh_version) - goto retry; - } - - if (opt_readonly && - !(thd->security_ctx->master_access & SUPER_ACL) && - !thd->slave_thread) - { - /* - Someone has issued SET GLOBAL READ_ONLY=1 and we want a write lock. - We do not wait for READ_ONLY=0, and fail. - */ - my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only"); - break; - } - } - - thd_proc_info(thd, "System lock"); - if (lock_external(thd, sql_lock->table, sql_lock->table_count)) - break; - thd_proc_info(thd, "Table lock"); - /* Copy the lock data array. thr_multi_lock() reorders its contens. */ - memcpy(sql_lock->locks + sql_lock->lock_count, sql_lock->locks, - sql_lock->lock_count * sizeof(*sql_lock->locks)); - /* Lock on the copied half of the lock data array. */ - rc= thr_lock_errno_to_mysql[(int) thr_multi_lock(sql_lock->locks + - sql_lock->lock_count, - sql_lock->lock_count, - thd->lock_id)]; - if (rc) /* Locking failed */ - { - VOID(unlock_external(thd, sql_lock->table, sql_lock->table_count)); - if (rc > 1) - { - /* a timeout or a deadlock */ - my_error(rc, MYF(0)); - break; - } - /* We where aborted and should try again from upper level*/ - thd->some_tables_deleted= 1; - } - else + if (global_read_lock) { /* - Lock worked. Now check that nothing happend while we where waiting - to get the lock that would require us to free it. + Someone has issued LOCK ALL TABLES FOR READ and we want a write lock + Wait until the lock is gone */ - error= 0; - if (!thd->some_tables_deleted || (flags & MYSQL_LOCK_IGNORE_FLUSH)) + if (wait_if_global_read_lock(thd, 1, 1)) { - /* - Table was not signaled for deletion or we don't care if it was. - Return with table as locked. - */ - break; + /* Clear the lock type of all lock data to avoid reusage. */ + reset_lock_data(sql_lock, 1); + DBUG_RETURN(1); // Fatal error } - else if (!thd->open_tables && !(flags & MYSQL_LOCK_NOT_TEMPORARY)) + if (thd->version != refresh_version) { - /* - Only using temporary tables, no need to unlock. - We need the flag as open_tables is not enough to distingush if - we are only using temporary tables for tables used trough - the HANDLER interface. - - We reset some_tables_deleted as it doesn't make sense to have this - one when we are only using temporary tables. - */ - thd->some_tables_deleted=0; - break; + /* Clear the lock type of all lock data to avoid reusage. */ + reset_lock_data(sql_lock, 1); + goto retry; } - /* some table was altered or deleted. reopen tables marked deleted */ - error= 1; - mysql_unlock_tables(thd, sql_lock, 0); } -retry: - if (flags & MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN) + if (opt_readonly && + !(thd->security_ctx->master_access & SUPER_ACL) && + !thd->slave_thread) { - *need_reopen= TRUE; - break; + /* + Someone has issued SET GLOBAL READ_ONLY=1 and we want a write lock. + We do not wait for READ_ONLY=0, and fail. + */ + my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only"); + reset_lock_data(sql_lock, 1); + DBUG_RETURN(1); // Fatal error } - if (wait_for_tables(thd)) - break; // Couldn't open tables - reset_lock_data(sql_lock, 0); // Set org locks and retry } + thd_proc_info(thd, "System lock"); + if (lock_external(thd, sql_lock->table, sql_lock->table_count)) + { + /* Clear the lock type of all lock data to avoid reusage. */ + res= 1; // Fatal error + goto end; + } + thd_proc_info(thd, "Table lock"); + DBUG_PRINT("info", ("thd->proc_info %s", thd->proc_info)); + /* Copy the lock data array. thr_multi_lock() reorders its contens. */ + memcpy(sql_lock->locks + sql_lock->lock_count, sql_lock->locks, + sql_lock->lock_count * sizeof(*sql_lock->locks)); + /* Lock on the copied half of the lock data array. */ + rc= thr_lock_errno_to_mysql[(int) thr_multi_lock(sql_lock->locks + + sql_lock->lock_count, + sql_lock->lock_count, + thd->lock_id)]; + if (rc) // Locking failed + { + if (sql_lock->table_count) + VOID(unlock_external(thd, sql_lock->table, sql_lock->table_count)); + + /* + reset_lock_data is required here. If thr_multi_lock fails it + resets lock type for tables, which were locked before (and + including) one that caused error. Lock type for other tables + preserved. + */ + reset_lock_data(sql_lock, 0); + + if (rc > 1) + { + my_error(rc, MYF(0)); + DBUG_RETURN(1); + } + DBUG_ASSERT(rc == 1); // Timeout + thd->some_tables_deleted= 1; // Reopen tables + sql_lock->lock_count= 0; // Locks are already freed + /* Retry */ + } + else + { + /* + Lock worked. Now check that nothing happend while we where waiting + to get the lock that would require us to free it. + */ + if (!thd->some_tables_deleted || (flags & MYSQL_LOCK_IGNORE_FLUSH)) + { + res= 0; + goto end; /* Lock was not aborted. Return to upper level */ + } + if (!thd->open_tables && !(flags & MYSQL_LOCK_NOT_TEMPORARY)) + { + /* + Only using temporary tables, no need to unlock. + We need the flag as open_tables is not enough to distingush if + we are only using temporary tables for tables used trough + the HANDLER interface. + + We reset some_tables_deleted as it doesn't make sense to have this + one when we are only using temporary tables. + */ + thd->some_tables_deleted=0; + goto end; + } + /* Free lock and retry */ + } + + /* some table was altered or deleted. reopen tables marked deleted */ + mysql_unlock_tables(thd, sql_lock, 0); + +retry: + res= -1; // Retry + if (flags & MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN) + { + *need_reopen= TRUE; // Upper level will retry + DBUG_RETURN(1); // Fatal error + } + if (wait_for_tables(thd)) + res= 1; // Couldn't open tables + +end: thd_proc_info(thd, 0); + if (thd->killed) + { + thd->send_kill_message(); + if (res == 0) + mysql_unlock_tables(thd,sql_lock,0); + else + reset_lock_data(sql_lock, 1); + res= 1; // Fatal + } thd->set_time_after_lock(); - DBUG_RETURN(error); + DBUG_RETURN(res); } diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index f49b7a3c851..94b06add2bd 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -2347,9 +2347,9 @@ extern struct st_VioSSLFd * ssl_acceptor_fd; MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **table, uint count, uint flags, bool *need_reopen); -bool mysql_lock_tables(THD *thd, MYSQL_LOCK *sql_lock, - bool write_lock_used, - uint flags, bool *need_reopen); +int mysql_lock_tables(THD *thd, MYSQL_LOCK *sql_lock, + bool write_lock_used, + uint flags, bool *need_reopen); /* mysql_lock_tables() and open_table() flags bits */ #define MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK 0x0001 diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 11fd5db2020..95a149741de 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -9606,13 +9606,12 @@ open_performance_schema_table(THD *thd, TABLE_LIST *one_table, else { /* - If error in mysql_lock_tables(), open_ltable doesn't close the - table. Thread kill during mysql_lock_tables() is such error. But - open tables cannot be accepted when restoring the open tables - state. + This can happen during a thd->kill or while we are trying to log + data for a stored procedure/trigger and someone causes the table + to be flushed (for example by creating a new trigger for the + table) */ - if (thd->killed) - close_thread_tables(thd); + close_thread_tables(thd); thd->restore_backup_open_tables_state(backup); } diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index d789957ffa4..4f1c63930d6 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -676,7 +676,7 @@ retry: /* save open_tables state */ if (handler->lock->lock_count > 0) { - bool lock_error; + int lock_error; handler->lock->locks[0]->type= handler->lock->locks[0]->org_type; lock_error= mysql_lock_tables(thd, handler->lock, 0, From d395d2514d872bc40374e900979825f81f992890 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Thu, 23 Feb 2012 16:51:58 +0200 Subject: [PATCH 117/135] Fixes for make_binary_distribution and mysql_config for OpenSuse 12.1 BUILD/SETUP.sh: By default, build also with innodb-plugin mysql-test/mysql-test-run.pl: Also search in lib64 directory for plugins (This is used at least on OpenSuse 12.1 when using default build scripts) mysql-test/r/lock_multi.result: Allow test to be re-run even if it crashed. mysql-test/t/lock_multi.test: Allow test to be re-run even if it crashed. scripts/make_binary_distribution.sh: Ensure that libexecdir is named libexec (was not on OpenSuse 12.1) scripts/mysql_config.sh: Fixed detection of lib64 was used. --- BUILD/SETUP.sh | 2 +- mysql-test/mysql-test-run.pl | 3 ++- mysql-test/r/lock_multi.result | 1 + mysql-test/t/lock_multi.test | 1 + scripts/make_binary_distribution.sh | 6 +++++- scripts/mysql_config.sh | 2 +- 6 files changed, 11 insertions(+), 4 deletions(-) diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh index c254304a5a8..c1a05fb1007 100755 --- a/BUILD/SETUP.sh +++ b/BUILD/SETUP.sh @@ -178,7 +178,7 @@ base_configs="--prefix=$prefix --enable-assembler " base_configs="$base_configs --with-extra-charsets=complex " base_configs="$base_configs --enable-thread-safe-client " base_configs="$base_configs --with-big-tables" -base_configs="$base_configs --with-plugin-aria --with-aria-tmp-tables --without-plugin-innodb_plugin" +base_configs="$base_configs --with-plugin-aria --with-aria-tmp-tables" # Compile our client programs with static libraries to allow them to be moved base_configs="$base_configs --with-mysqld-ldflags=-static --with-client-ldflags=-static" diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 4d6269044c1..e6ef03d6ad5 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -2518,7 +2518,8 @@ sub setup_vardir() { else { # hm, what paths work for debs and for rpms ? - for (<$bindir/lib/mysql/plugin/*.so>, + for (<$bindir/lib64/mysql/plugin/*.so>, + <$bindir/lib/mysql/plugin/*.so>, <$bindir/lib/plugin/*.dll>) { my $pname=basename($_); diff --git a/mysql-test/r/lock_multi.result b/mysql-test/r/lock_multi.result index 3fc4de3da06..72f4b22b06a 100644 --- a/mysql-test/r/lock_multi.result +++ b/mysql-test/r/lock_multi.result @@ -1,4 +1,5 @@ drop table if exists t1,t2; +drop DATABASE if exists mysqltest_1; create table t1(n int); insert into t1 values (1); lock tables t1 write; diff --git a/mysql-test/t/lock_multi.test b/mysql-test/t/lock_multi.test index f05821af5a8..044af931489 100644 --- a/mysql-test/t/lock_multi.test +++ b/mysql-test/t/lock_multi.test @@ -5,6 +5,7 @@ --disable_warnings drop table if exists t1,t2; +drop DATABASE if exists mysqltest_1; --enable_warnings # Test to see if select will get the lock ahead of low priority update diff --git a/scripts/make_binary_distribution.sh b/scripts/make_binary_distribution.sh index 789f3e3ce2e..070b396a34c 100644 --- a/scripts/make_binary_distribution.sh +++ b/scripts/make_binary_distribution.sh @@ -285,7 +285,8 @@ if [ x"$BASE_SYSTEM" != x"netware" ] ; then pkgplugindir=@pkgplugindir@ \ pkgsuppdir=@pkgsuppdir@ \ mandir=@mandir@ \ - infodir=@infodir@ + infodir=@infodir@ \ + libexecdir=@prefix@/libexec # ---------------------------------------------------------------------- # Rename top directory, and set DEST to the new directory @@ -301,7 +302,10 @@ if [ x"$BASE_SYSTEM" != x"netware" ] ; then if [ -z "$gcclib" ] ; then echo "Warning: Compiler doesn't tell libgcc.a!" elif [ -f "$gcclib" ] ; then + { + mkdir -p $DEST/lib $CP $gcclib $DEST/lib/libmygcc.a + } else echo "Warning: Compiler result '$gcclib' not found / no file!" fi diff --git a/scripts/mysql_config.sh b/scripts/mysql_config.sh index f1d46c0b2c0..ce61c09aa15 100644 --- a/scripts/mysql_config.sh +++ b/scripts/mysql_config.sh @@ -86,7 +86,7 @@ bindir='@bindir@' # If installed, search for the compiled in directory first (might be "lib64") pkglibdir='@pkglibdir@' pkglibdir_rel=`echo $pkglibdir | sed -e "s;^$basedir/;;"` -fix_path pkglibdir $pkglibdir_rel lib/mysql lib +fix_path pkglibdir $pkglibdir_rel lib64/mysql lib64 lib/mysql lib plugindir='@pkgplugindir@' From c068b831aca6334c6dea01fd9ff54b6140a52ef6 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Fri, 24 Feb 2012 12:34:47 +0200 Subject: [PATCH 118/135] Removed const declarations to get rid of compiler warnings. The changes are similar to what is done in innobase in MySQL 5.5 --- storage/innodb_plugin/btr/btr0sea.c | 2 +- storage/innodb_plugin/ha/ha0ha.c | 6 +++--- storage/innodb_plugin/include/ha0ha.h | 10 +++++----- storage/innodb_plugin/include/ha0ha.ic | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/storage/innodb_plugin/btr/btr0sea.c b/storage/innodb_plugin/btr/btr0sea.c index 04c273344f3..f10c207b76a 100644 --- a/storage/innodb_plugin/btr/btr0sea.c +++ b/storage/innodb_plugin/btr/btr0sea.c @@ -524,7 +524,7 @@ btr_search_update_hash_ref( { dict_index_t* index; ulint fold; - const rec_t* rec; + rec_t* rec; ut_ad(cursor->flag == BTR_CUR_HASH_FAIL); #ifdef UNIV_SYNC_DEBUG diff --git a/storage/innodb_plugin/ha/ha0ha.c b/storage/innodb_plugin/ha/ha0ha.c index 65046138275..594a10dc431 100644 --- a/storage/innodb_plugin/ha/ha0ha.c +++ b/storage/innodb_plugin/ha/ha0ha.c @@ -106,7 +106,7 @@ ha_insert_for_fold_func( #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG buf_block_t* block, /*!< in: buffer block containing the data */ #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ - const rec_t* data) /*!< in: data, must not be NULL */ + rec_t* data) /*!< in: data, must not be NULL */ { hash_cell_t* cell; ha_node_t* node; @@ -238,11 +238,11 @@ ha_search_and_update_if_found_func( /*===============================*/ hash_table_t* table, /*!< in/out: hash table */ ulint fold, /*!< in: folded value of the searched data */ - const rec_t* data, /*!< in: pointer to the data */ + rec_t* data, /*!< in: pointer to the data */ #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG buf_block_t* new_block,/*!< in: block containing new_data */ #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ - const rec_t* new_data)/*!< in: new pointer to the data */ + rec_t* new_data)/*!< in: new pointer to the data */ { ha_node_t* node; diff --git a/storage/innodb_plugin/include/ha0ha.h b/storage/innodb_plugin/include/ha0ha.h index 8bba564d153..83a7394123f 100644 --- a/storage/innodb_plugin/include/ha0ha.h +++ b/storage/innodb_plugin/include/ha0ha.h @@ -38,7 +38,7 @@ Looks for an element in a hash table. @return pointer to the data of the first hash table node in chain having the fold number, NULL if not found */ UNIV_INLINE -const rec_t* +rec_t* ha_search_and_get_data( /*===================*/ hash_table_t* table, /*!< in: hash table */ @@ -52,11 +52,11 @@ ha_search_and_update_if_found_func( /*===============================*/ hash_table_t* table, /*!< in/out: hash table */ ulint fold, /*!< in: folded value of the searched data */ - const rec_t* data, /*!< in: pointer to the data */ + rec_t* data, /*!< in: pointer to the data */ #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG buf_block_t* new_block,/*!< in: block containing new_data */ #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ - const rec_t* new_data);/*!< in: new pointer to the data */ + rec_t* new_data);/*!< in: new pointer to the data */ #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG /** Looks for an element when we know the pointer to the data and @@ -131,7 +131,7 @@ ha_insert_for_fold_func( #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG buf_block_t* block, /*!< in: buffer block containing the data */ #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ - const rec_t* data); /*!< in: data, must not be NULL */ + rec_t* data); /*!< in: data, must not be NULL */ #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG /** @@ -210,7 +210,7 @@ struct ha_node_struct { #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG buf_block_t* block; /*!< buffer block containing the data, or NULL */ #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ - const rec_t* data; /*!< pointer to the data */ + rec_t* data; /*!< pointer to the data */ ulint fold; /*!< fold value for the data */ }; diff --git a/storage/innodb_plugin/include/ha0ha.ic b/storage/innodb_plugin/include/ha0ha.ic index 5656e9b7eba..aec28398b5d 100644 --- a/storage/innodb_plugin/include/ha0ha.ic +++ b/storage/innodb_plugin/include/ha0ha.ic @@ -58,7 +58,7 @@ ha_node_set_data_func( #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG buf_block_t* block, /*!< in: buffer block containing the data */ #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ - const rec_t* data) /*!< in: pointer to the data */ + rec_t* data) /*!< in: pointer to the data */ { #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG node->block = block; @@ -111,7 +111,7 @@ Looks for an element in a hash table. @return pointer to the data of the first hash table node in chain having the fold number, NULL if not found */ UNIV_INLINE -const rec_t* +rec_t* ha_search_and_get_data( /*===================*/ hash_table_t* table, /*!< in: hash table */ From 914245ccd8bb89e1ed473a64bea2466286ec72f7 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Fri, 24 Feb 2012 17:09:13 +0400 Subject: [PATCH 119/135] BUG#934597: Assertion `! is_set()' failed in Diagnostics_area::set_ok_status(THD... - After the exec_const_cond->val_int() call, check for error and return. (if we don't do it, we will eventually hit an error when trying to set status OK in the diagnostics area, which already has an error status). --- mysql-test/r/subselect4.result | 14 ++++++++++++++ mysql-test/t/subselect4.test | 16 ++++++++++++++++ sql/sql_select.cc | 9 +++++++++ 3 files changed, 39 insertions(+) diff --git a/mysql-test/r/subselect4.result b/mysql-test/r/subselect4.result index 4e3247e9da8..70b63a74708 100644 --- a/mysql-test/r/subselect4.result +++ b/mysql-test/r/subselect4.result @@ -2141,6 +2141,20 @@ WHERE t2.b IN (SELECT t3.b FROM t3 WHERE t3.a < ANY (SELECT t4.a FROM t4) and t3 c a b 10 7 0 drop table t2, t3, t4; +# +# BUG#934597: Assertion `! is_set()' failed in Diagnostics_area::set_ok_status(THD... +# +CREATE TABLE t1 ( a VARCHAR(1) ); +INSERT INTO t1 VALUES ('u'),('k'); +CREATE TABLE t2 AS +SELECT a AS field1 FROM t1 +WHERE ( SELECT alias1.a +FROM t1 AS alias1 +) IS NOT NULL; +ERROR 21000: Subquery returns more than 1 row +DROP TABLE t2; +ERROR 42S02: Unknown table 't2' +DROP TABLE t1; set optimizer_switch=@subselect4_tmp; SET optimizer_switch= @@global.optimizer_switch; set @@tmp_table_size= @@global.tmp_table_size; diff --git a/mysql-test/t/subselect4.test b/mysql-test/t/subselect4.test index b2e15c457d7..eee0140815b 100644 --- a/mysql-test/t/subselect4.test +++ b/mysql-test/t/subselect4.test @@ -1779,6 +1779,22 @@ WHERE t2.b IN (SELECT t3.b FROM t3 WHERE t3.a < ANY (SELECT t4.a FROM t4) and t3 drop table t2, t3, t4; +--echo # +--echo # BUG#934597: Assertion `! is_set()' failed in Diagnostics_area::set_ok_status(THD... +--echo # +CREATE TABLE t1 ( a VARCHAR(1) ); +INSERT INTO t1 VALUES ('u'),('k'); +--error ER_SUBQUERY_NO_1_ROW +CREATE TABLE t2 AS + SELECT a AS field1 FROM t1 + WHERE ( SELECT alias1.a + FROM t1 AS alias1 + ) IS NOT NULL; +--error ER_BAD_TABLE_ERROR +DROP TABLE t2; +DROP TABLE t1; + + set optimizer_switch=@subselect4_tmp; SET optimizer_switch= @@global.optimizer_switch; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index f2720513b6f..cb3590756df 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2161,6 +2161,15 @@ JOIN::exec() !exec_const_cond->val_int()) zero_result_cause= "Impossible WHERE noticed after reading const tables"; + /* + We've called exec_const_cond->val_int(). This may have caused an error. + */ + if (thd->is_error()) + { + error= thd->is_error(); + DBUG_VOID_RETURN; + } + if (zero_result_cause) { (void) return_zero_rows(this, result, select_lex->leaf_tables, From 60aad314224227fb5e652bfa094fb01373414a37 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Fri, 24 Feb 2012 17:01:47 +0200 Subject: [PATCH 120/135] Fix for lp:909635: MariaDB crashes on a select with long varchar and blob fields Problem was a crash in internal temporary (Maria) files when row length exceeded 65535 mysql-test/suite/maria/r/maria3.result: Added test case mysql-test/suite/maria/t/maria3.test: Added test case storage/maria/ma_open.c: Added support for row length > 65535. This fixes crash when using tables with longer row lengths. --- mysql-test/suite/maria/r/maria3.result | 24 ++++++++++++++++++++ mysql-test/suite/maria/t/maria3.test | 31 ++++++++++++++++++++++++++ storage/maria/ma_open.c | 12 +++++++--- 3 files changed, 64 insertions(+), 3 deletions(-) diff --git a/mysql-test/suite/maria/r/maria3.result b/mysql-test/suite/maria/r/maria3.result index f7cc08bfd0d..e4d76a308d3 100644 --- a/mysql-test/suite/maria/r/maria3.result +++ b/mysql-test/suite/maria/r/maria3.result @@ -617,3 +617,27 @@ ERROR 23000: Duplicate entry '2' for key 'a' insert into t1 values(3); insert into t2 values(3); drop table t1, t2; +CREATE TABLE t1 ( +a INT PRIMARY KEY, +b CHAR(255), +c VARCHAR(2048), +d VARCHAR(18990), +e CHAR(128), +f CHAR(192) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +INSERT INTO t1 VALUES +(1,'A','B','C','','D'), +(2,'Abcdefghi','E','F','','G'); +CREATE TABLE t2 ( +g INT PRIMARY KEY, +h CHAR(32), +i CHAR(255), +j TEXT +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +INSERT INTO t2 VALUES (1,'M','','H'), +(2,'N','','H'); +SELECT * FROM t1, t2 WHERE a = g ORDER BY b; +a b c d e f g h i j +1 A B C D 1 M H +2 Abcdefghi E F G 2 N H +drop table t1,t2; diff --git a/mysql-test/suite/maria/t/maria3.test b/mysql-test/suite/maria/t/maria3.test index a6dd0ca6639..37417ae3c18 100644 --- a/mysql-test/suite/maria/t/maria3.test +++ b/mysql-test/suite/maria/t/maria3.test @@ -524,6 +524,37 @@ insert into t2 values(3); connection default; drop table t1, t2; +# +# BUG#909635 - MariaDB crashes on a select with long varchar and blob fields +# + +CREATE TABLE t1 ( + a INT PRIMARY KEY, + b CHAR(255), + c VARCHAR(2048), + d VARCHAR(18990), + e CHAR(128), + f CHAR(192) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +INSERT INTO t1 VALUES + (1,'A','B','C','','D'), + (2,'Abcdefghi','E','F','','G'); + +CREATE TABLE t2 ( + g INT PRIMARY KEY, + h CHAR(32), + i CHAR(255), + j TEXT +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +INSERT INTO t2 VALUES (1,'M','','H'), + (2,'N','','H'); + +SELECT * FROM t1, t2 WHERE a = g ORDER BY b; +drop table t1,t2; + + # End of 5.1 tests --disable_result_log diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c index c8e4572b8d4..eb7ef510d88 100644 --- a/storage/maria/ma_open.c +++ b/storage/maria/ma_open.c @@ -1669,9 +1669,11 @@ my_bool _ma_columndef_write(File file, MARIA_COLUMNDEF *columndef) { uchar buff[MARIA_COLUMNDEF_SIZE]; uchar *ptr=buff; + uint low_offset= (uint) (columndef->offset & 0xffff); + uint high_offset= (uint) (columndef->offset >> 16); mi_int2store(ptr,(ulong) columndef->column_nr); ptr+= 2; - mi_int2store(ptr,(ulong) columndef->offset); ptr+= 2; + mi_int2store(ptr, low_offset); ptr+= 2; mi_int2store(ptr,columndef->type); ptr+= 2; mi_int2store(ptr,columndef->length); ptr+= 2; mi_int2store(ptr,columndef->fill_length); ptr+= 2; @@ -1680,12 +1682,14 @@ my_bool _ma_columndef_write(File file, MARIA_COLUMNDEF *columndef) (*ptr++)= columndef->null_bit; (*ptr++)= columndef->empty_bit; - ptr[0]= ptr[1]= ptr[2]= ptr[3]= 0; ptr+= 4; /* For future */ + mi_int2store(ptr, high_offset); ptr+= 2; + ptr[0]= ptr[1]= 0; ptr+= 2; /* For future */ return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0; } uchar *_ma_columndef_read(uchar *ptr, MARIA_COLUMNDEF *columndef) { + uint high_offset; columndef->column_nr= mi_uint2korr(ptr); ptr+= 2; columndef->offset= mi_uint2korr(ptr); ptr+= 2; columndef->type= mi_sint2korr(ptr); ptr+= 2; @@ -1695,7 +1699,9 @@ uchar *_ma_columndef_read(uchar *ptr, MARIA_COLUMNDEF *columndef) columndef->empty_pos= mi_uint2korr(ptr); ptr+= 2; columndef->null_bit= (uint8) *ptr++; columndef->empty_bit= (uint8) *ptr++; - ptr+= 4; + high_offset= mi_uint2korr(ptr); ptr+= 2; + columndef->offset|= ((ulong) high_offset << 16); + ptr+= 2; return ptr; } From 88718067887aafd38474591fe7d3585539f6d2bb Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Fri, 24 Feb 2012 22:42:37 +0400 Subject: [PATCH 121/135] BUG#938131: Subquery materialization is not used in CREATE TABLE SELECT - Enable subquery materialization for CREATE TABLE ... SELECT. --- mysql-test/r/subselect_sj_mat.result | 19 +++++++++++++++++++ mysql-test/t/subselect_sj_mat.test | 14 ++++++++++++++ sql/opt_subselect.cc | 7 ++++--- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/subselect_sj_mat.result b/mysql-test/r/subselect_sj_mat.result index b21236de7b9..500a6ee86c4 100644 --- a/mysql-test/r/subselect_sj_mat.result +++ b/mysql-test/r/subselect_sj_mat.result @@ -1898,6 +1898,25 @@ WHERE 'condition'='impossible' MIN(a) NULL DROP TABLE t1; +# +# BUG#938131: Subquery materialization is not used in CREATE TABLE SELECT +# +CREATE TABLE t1(a int); +INSERT INTO t1 values(1),(2); +CREATE TABLE t2(a int); +INSERT INTO t2 values(1),(2); +# Should use Materialization: +EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT * FROM t2 GROUP BY a HAVING a > 1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where +1 PRIMARY eq_ref distinct_key distinct_key 5 test.t1.a 1 +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 Using temporary +flush status; +CREATE TABLE t3 SELECT * FROM t1 WHERE a IN (SELECT * FROM t2 GROUP BY a HAVING a > 1); +SHOW STATUS LIKE 'Created_tmp_tables'; +Variable_name Value +Created_tmp_tables 2 +DROP TABLE t1,t2,t3; # This must be at the end: set optimizer_switch=@subselect_sj_mat_tmp; set join_cache_level=@save_join_cache_level; diff --git a/mysql-test/t/subselect_sj_mat.test b/mysql-test/t/subselect_sj_mat.test index 0d04b3f984a..f04fb7dc44e 100644 --- a/mysql-test/t/subselect_sj_mat.test +++ b/mysql-test/t/subselect_sj_mat.test @@ -1559,6 +1559,20 @@ WHERE a IN ( DROP TABLE t1; +--echo # +--echo # BUG#938131: Subquery materialization is not used in CREATE TABLE SELECT +--echo # +CREATE TABLE t1(a int); +INSERT INTO t1 values(1),(2); +CREATE TABLE t2(a int); +INSERT INTO t2 values(1),(2); +--echo # Should use Materialization: +EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT * FROM t2 GROUP BY a HAVING a > 1); +flush status; +CREATE TABLE t3 SELECT * FROM t1 WHERE a IN (SELECT * FROM t2 GROUP BY a HAVING a > 1); +SHOW STATUS LIKE 'Created_tmp_tables'; +DROP TABLE t1,t2,t3; + --echo # This must be at the end: set optimizer_switch=@subselect_sj_mat_tmp; set join_cache_level=@save_join_cache_level; diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index d01ef381806..30c3e8bf5d0 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -251,8 +251,8 @@ bool is_materialization_applicable(THD *thd, Item_in_subselect *in_subs, Subquery !contains {GROUP BY, ORDER BY [LIMIT], aggregate functions}) && subquery predicate is not under "NOT IN")) - (*) The subquery must be part of a SELECT statement. The current - condition also excludes multi-table update statements. + (*) The subquery must be part of a SELECT or CREATE TABLE ... SELECT statement. + The current condition also excludes multi-table update statements. A note about prepared statements: we want the if-branch to be taken on PREPARE and each EXECUTE. The rewrites are only done once, but we need select_lex->sj_subselects list to be populated for every EXECUTE. @@ -261,7 +261,8 @@ bool is_materialization_applicable(THD *thd, Item_in_subselect *in_subs, if (optimizer_flag(thd, OPTIMIZER_SWITCH_MATERIALIZATION) && // 0 !child_select->is_part_of_union() && // 1 parent_unit->first_select()->leaf_tables.elements && // 2 - thd->lex->sql_command == SQLCOM_SELECT && // * + (thd->lex->sql_command == SQLCOM_SELECT || // * + thd->lex->sql_command == SQLCOM_CREATE_TABLE) && // * child_select->outer_select()->leaf_tables.elements && // 2A subquery_types_allow_materialization(in_subs) && (in_subs->is_top_level_item() || //3 From 6400df6d715848945d7766e529f941ec17b55618 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Sat, 25 Feb 2012 01:42:28 +0400 Subject: [PATCH 122/135] Update test results. --- mysql-test/r/subselect_mat.result | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/mysql-test/r/subselect_mat.result b/mysql-test/r/subselect_mat.result index 4d02e5012e2..da4a3a1c847 100644 --- a/mysql-test/r/subselect_mat.result +++ b/mysql-test/r/subselect_mat.result @@ -1861,6 +1861,24 @@ WHERE 'condition'='impossible' MIN(a) NULL DROP TABLE t1; +# +# BUG#938131: Subquery materialization is not used in CREATE TABLE SELECT +# +CREATE TABLE t1(a int); +INSERT INTO t1 values(1),(2); +CREATE TABLE t2(a int); +INSERT INTO t2 values(1),(2); +# Should use Materialization: +EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT * FROM t2 GROUP BY a HAVING a > 1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 Using temporary +flush status; +CREATE TABLE t3 SELECT * FROM t1 WHERE a IN (SELECT * FROM t2 GROUP BY a HAVING a > 1); +SHOW STATUS LIKE 'Created_tmp_tables'; +Variable_name Value +Created_tmp_tables 3 +DROP TABLE t1,t2,t3; # This must be at the end: set optimizer_switch=@subselect_sj_mat_tmp; set join_cache_level=@save_join_cache_level; From 841a74a4d6ebdaa2760ce615e7fc18f57100ee19 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Fri, 24 Feb 2012 16:50:22 -0800 Subject: [PATCH 123/135] Fixed LP bug #939009. The result of materialization of the right part of an IN subquery predicate is placed into a temporary table. Each row of the materialized table is distinct. A unique key over all fields of the temporary table is defined and created. It allows to perform key look-ups into the table. The table created for a materialized subquery can be accessed by key as any other table. The function best_access-path search for the best access to join a table to a given partial join. With some where conditions this function considers a possibility of a ref_or_null access. If such access employs the unique key on the temporary table then when estimating the cost this access the function tries to use the array rec_per_key. Yet, such array is not built for this unique key. This causes a crash of the server. Rows returned by the subquery that contain nulls don't have to be placed into temporary table, as they cannot be match any row produced by the left part of the subquery predicate. So all fields of the temporary table can be defined as non-nullable. In this case any ref_or_null access to the temporary table does not make any sense and it does not make sense to estimate such an access. The fix makes sure that the temporary table for a materialized IN subquery is defined with columns that are all non-nullable. The also ensures that any row with nulls returned by the subquery is not placed into the temporary table. --- mysql-test/r/derived_view.result | 4 +- mysql-test/r/func_group.result | 2 +- mysql-test/r/group_min_max.result | 2 +- mysql-test/r/subselect.result | 14 +-- mysql-test/r/subselect4.result | 4 +- mysql-test/r/subselect_mat.result | 37 +++++++- mysql-test/r/subselect_mat_cost.result | 2 +- mysql-test/r/subselect_no_scache.result | 14 +-- mysql-test/r/subselect_sj.result | 14 +-- mysql-test/r/subselect_sj2.result | 10 +- mysql-test/r/subselect_sj2_jcl6.result | 16 ++-- mysql-test/r/subselect_sj2_mat.result | 10 +- mysql-test/r/subselect_sj_jcl6.result | 24 ++--- mysql-test/r/subselect_sj_mat.result | 99 +++++++++++++------- mysql-test/r/subselect_sj_nonmerged.result | 14 +-- mysql-test/suite/pbxt/r/group_min_max.result | 2 +- mysql-test/suite/pbxt/r/subselect.result | 6 +- mysql-test/t/subselect_sj_mat.test | 29 ++++++ sql/field_conv.cc | 10 ++ sql/item_subselect.cc | 5 + sql/opt_subselect.cc | 1 + sql/sql_class.cc | 6 ++ sql/sql_class.h | 5 +- sql/sql_select.cc | 32 +++++-- sql/sql_union.cc | 8 ++ sql/table.h | 23 +++++ 26 files changed, 279 insertions(+), 114 deletions(-) diff --git a/mysql-test/r/derived_view.result b/mysql-test/r/derived_view.result index 49d5c409e31..2f0e0bd371b 100644 --- a/mysql-test/r/derived_view.result +++ b/mysql-test/r/derived_view.result @@ -1458,14 +1458,14 @@ WHERE (t2.a ,t1.b) NOT IN (SELECT DISTINCT c,a FROM t3 t); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) -2 DEPENDENT SUBQUERY t ref PRIMARY,c c 4 func 2 Using where; Using index +2 DEPENDENT SUBQUERY t eq_ref PRIMARY,c PRIMARY 4 func 1 Using where EXPLAIN SELECT * FROM t1 , t2 WHERE (t2.a ,t1.b) NOT IN (SELECT DISTINCT c,a FROM (SELECT * FROM t3) t); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) -2 DEPENDENT SUBQUERY t3 ref PRIMARY,c c 4 func 2 Using where; Using index +2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY,c PRIMARY 4 func 1 Using where SELECT * FROM t1 , t2 WHERE (t2.a ,t1.b) NOT IN (SELECT DISTINCT c,a FROM (SELECT * FROM t3) t); b a diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result index 9660640baaa..f1d3777e097 100644 --- a/mysql-test/r/func_group.result +++ b/mysql-test/r/func_group.result @@ -1845,7 +1845,7 @@ NULL EXPLAIN EXTENDED SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT a,b FROM t2 WHERE b<5) and a<10; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY eq_ref distinct_key distinct_key 10 func,func 1 100.00 +1 PRIMARY eq_ref distinct_key distinct_key 8 func,func 1 100.00 1 PRIMARY t1 range a a 4 NULL 4 100.00 Using where; Using index; Using join buffer (flat, BNL join) 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where Warnings: diff --git a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result index 858d31e05c8..3d0502e163c 100644 --- a/mysql-test/r/group_min_max.result +++ b/mysql-test/r/group_min_max.result @@ -2407,7 +2407,7 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT 1 FROM t1 AS t1_outer WHERE a IN (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL distinct_key NULL NULL NULL 8 Using where +1 PRIMARY ALL distinct_key NULL NULL NULL 8 1 PRIMARY t1_outer ref a a 5 .max(b) 2 Using index 2 MATERIALIZED t1 range NULL a 5 NULL 8 Using index for group-by EXPLAIN SELECT 1 FROM t1 AS t1_outer GROUP BY a HAVING diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index bca4eb677de..327cb5b2563 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -2973,7 +2973,7 @@ Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`, eq_ref distinct_key distinct_key 10 func,func 1 100.00 +1 PRIMARY eq_ref distinct_key distinct_key 8 func,func 1 100.00 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 9 100.00 Using where Warnings: Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`flag` = 'N')) @@ -3563,7 +3563,7 @@ EXPLAIN SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where -1 PRIMARY eq_ref distinct_key distinct_key 23 test.t1.a,test.t1.b 1 +1 PRIMARY eq_ref distinct_key distinct_key 21 test.t1.a,test.t1.b 1 2 MATERIALIZED t1 ALL NULL NULL NULL NULL 9 Using temporary ALTER TABLE t1 ADD INDEX(a); SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a); @@ -3575,7 +3575,7 @@ EXPLAIN SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL a NULL NULL NULL 9 Using where -1 PRIMARY eq_ref distinct_key distinct_key 23 test.t1.a,test.t1.b 1 +1 PRIMARY eq_ref distinct_key distinct_key 21 test.t1.a,test.t1.b 1 2 MATERIALIZED t1 ALL NULL NULL NULL NULL 9 Using temporary DROP TABLE t1; create table t1( f1 int,f2 int); @@ -4471,14 +4471,14 @@ SET @save_join_cache_level=@@join_cache_level; SET join_cache_level=0; EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT min(a) FROM t1 GROUP BY a); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY const distinct_key distinct_key 5 const 1 100.00 +1 PRIMARY const distinct_key distinct_key 4 const 1 100.00 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary Warnings: Note 1003 select 1 AS `1` from (select min(`test`.`t1`.`a`) from `test`.`t1` group by `test`.`t1`.`a`) join `test`.`t1` where (``.`min(a)` = 1) EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT min(a) FROM t1 WHERE a > 3 GROUP BY a); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY const distinct_key distinct_key 5 const 1 100.00 +1 PRIMARY const distinct_key distinct_key 4 const 1 100.00 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary Warnings: @@ -5585,7 +5585,7 @@ WHERE col_varchar_nokey IN (SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY ot system NULL NULL NULL NULL 1 -1 PRIMARY eq_ref distinct_key distinct_key 5 func 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 2 MATERIALIZED it1 ref idx_cvk_cik idx_cvk_cik 9 const,const 1 Using where; Using index SELECT col_int_nokey FROM ot WHERE col_varchar_nokey IN @@ -5598,7 +5598,7 @@ WHERE (col_varchar_nokey, 'x') IN (SELECT col_varchar_key, col_varchar_key2 FROM it2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY ot system NULL NULL NULL NULL 1 -1 PRIMARY eq_ref distinct_key distinct_key 10 func,func 1 +1 PRIMARY eq_ref distinct_key distinct_key 8 func,func 1 2 MATERIALIZED it2 ref idx_cvk_cvk2_cik,idx_cvk_cik idx_cvk_cvk2_cik 8 const,const 1 Using where; Using index SELECT col_int_nokey FROM ot WHERE (col_varchar_nokey, 'x') IN diff --git a/mysql-test/r/subselect4.result b/mysql-test/r/subselect4.result index 4e3247e9da8..b98c058a303 100644 --- a/mysql-test/r/subselect4.result +++ b/mysql-test/r/subselect4.result @@ -1249,7 +1249,7 @@ EXPLAIN SELECT * FROM (t2 LEFT JOIN t1 ON t1.c1) LEFT JOIN t3 on t3.c1 WHERE 's' IN (SELECT c1 FROM t2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found -1 PRIMARY eq_ref distinct_key distinct_key 5 func 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join) 1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using where 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 Using where @@ -1258,7 +1258,7 @@ c1 c1 c1 EXPLAIN SELECT * FROM t4 LEFT JOIN t2 ON t4.c1 WHERE 's' IN (SELECT c1 FROM t2); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY eq_ref distinct_key distinct_key 5 func 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 1 PRIMARY t4 index NULL PRIMARY 3 NULL 2 Using index; Using join buffer (flat, BNL join) 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 Using where diff --git a/mysql-test/r/subselect_mat.result b/mysql-test/r/subselect_mat.result index 4d02e5012e2..baf7e379882 100644 --- a/mysql-test/r/subselect_mat.result +++ b/mysql-test/r/subselect_mat.result @@ -1473,7 +1473,7 @@ SET @@optimizer_switch='semijoin=on,materialization=on'; EXPLAIN SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 -1 PRIMARY eq_ref distinct_key distinct_key 5 func 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 2 MATERIALIZED t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Rowid-ordered scan SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0); pk @@ -1861,6 +1861,39 @@ WHERE 'condition'='impossible' MIN(a) NULL DROP TABLE t1; +# +# BUG#939009: Crash with aggregate function in IN subquery +# +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch='materialization=on,semijoin=on'; +CREATE TABLE t1 (a int, b int); +INSERT INTO t1 VALUES (7,1), (4,2), (7,7); +CREATE TABLE t2 ( c INT ); +INSERT INTO t2 VALUES (4), (7), (6); +EXPLAIN EXTENDED +SELECT * FROM t1 +WHERE a IN (SELECT MAX(c) FROM t2) AND b=7 AND (a IS NULL OR a=b); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY const distinct_key distinct_key 4 const 1 100.00 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00 +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from (select max(`test`.`t2`.`c`) from `test`.`t2`) join `test`.`t1` where ((`test`.`t1`.`a` = ``.`MAX(c)`) and (`test`.`t1`.`b` = 7) and (isnull(``.`MAX(c)`) or (``.`MAX(c)` = 7))) +SELECT * FROM t1 +WHERE a IN (SELECT MAX(c) FROM t2) AND b=7 AND (a IS NULL OR a=b); +a b +EXPLAIN +SELECT * FROM t1 +WHERE a IN (SELECT MAX(c) FROM t2 WHERE c < 4) AND b=7 AND (a IS NULL OR a=b); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY const distinct_key distinct_key 4 const 1 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join) +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where +SELECT * FROM t1 +WHERE a IN (SELECT MAX(c) FROM t2 WHERE c < 4) AND b=7 AND (a IS NULL OR a=b); +a b +SET optimizer_switch=@save_optimizer_switch; +DROP TABLE t1,t2; # This must be at the end: set optimizer_switch=@subselect_sj_mat_tmp; set join_cache_level=@save_join_cache_level; @@ -1983,7 +2016,7 @@ SET @@optimizer_switch='default,semijoin=on,materialization=on'; EXPLAIN SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 -1 PRIMARY eq_ref distinct_key distinct_key 5 func 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 2 MATERIALIZED t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0); pk diff --git a/mysql-test/r/subselect_mat_cost.result b/mysql-test/r/subselect_mat_cost.result index e5f2df1c5c1..900bad0183a 100644 --- a/mysql-test/r/subselect_mat_cost.result +++ b/mysql-test/r/subselect_mat_cost.result @@ -348,7 +348,7 @@ FROM City LEFT JOIN Country ON (Country = Code and City.Population < 10000)) AND Language IN ('English','Spanish'); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY CountryLanguage range Language Language 30 NULL 72 Using index condition; Using where; Rowid-ordered scan -2 DEPENDENT SUBQUERY City ref CityName CityName 35 func 2 Using index condition; Using where +2 DEPENDENT SUBQUERY City ref CityName CityName 35 func 1 Using index condition; Using where 2 DEPENDENT SUBQUERY Country eq_ref PRIMARY PRIMARY 3 world.City.Country 1 Using where; Using index select count(*) from CountryLanguage diff --git a/mysql-test/r/subselect_no_scache.result b/mysql-test/r/subselect_no_scache.result index e170debd6d2..1167e9483c9 100644 --- a/mysql-test/r/subselect_no_scache.result +++ b/mysql-test/r/subselect_no_scache.result @@ -2979,7 +2979,7 @@ Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`, eq_ref distinct_key distinct_key 10 func,func 1 100.00 +1 PRIMARY eq_ref distinct_key distinct_key 8 func,func 1 100.00 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 9 100.00 Using where Warnings: Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`flag` = 'N')) @@ -3569,7 +3569,7 @@ EXPLAIN SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where -1 PRIMARY eq_ref distinct_key distinct_key 23 test.t1.a,test.t1.b 1 +1 PRIMARY eq_ref distinct_key distinct_key 21 test.t1.a,test.t1.b 1 2 MATERIALIZED t1 ALL NULL NULL NULL NULL 9 Using temporary ALTER TABLE t1 ADD INDEX(a); SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a); @@ -3581,7 +3581,7 @@ EXPLAIN SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL a NULL NULL NULL 9 Using where -1 PRIMARY eq_ref distinct_key distinct_key 23 test.t1.a,test.t1.b 1 +1 PRIMARY eq_ref distinct_key distinct_key 21 test.t1.a,test.t1.b 1 2 MATERIALIZED t1 ALL NULL NULL NULL NULL 9 Using temporary DROP TABLE t1; create table t1( f1 int,f2 int); @@ -4477,14 +4477,14 @@ SET @save_join_cache_level=@@join_cache_level; SET join_cache_level=0; EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT min(a) FROM t1 GROUP BY a); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY const distinct_key distinct_key 5 const 1 100.00 +1 PRIMARY const distinct_key distinct_key 4 const 1 100.00 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary Warnings: Note 1003 select 1 AS `1` from (select min(`test`.`t1`.`a`) from `test`.`t1` group by `test`.`t1`.`a`) join `test`.`t1` where (``.`min(a)` = 1) EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT min(a) FROM t1 WHERE a > 3 GROUP BY a); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY const distinct_key distinct_key 5 const 1 100.00 +1 PRIMARY const distinct_key distinct_key 4 const 1 100.00 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary Warnings: @@ -5591,7 +5591,7 @@ WHERE col_varchar_nokey IN (SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY ot system NULL NULL NULL NULL 1 -1 PRIMARY eq_ref distinct_key distinct_key 5 func 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 2 MATERIALIZED it1 ref idx_cvk_cik idx_cvk_cik 9 const,const 1 Using where; Using index SELECT col_int_nokey FROM ot WHERE col_varchar_nokey IN @@ -5604,7 +5604,7 @@ WHERE (col_varchar_nokey, 'x') IN (SELECT col_varchar_key, col_varchar_key2 FROM it2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY ot system NULL NULL NULL NULL 1 -1 PRIMARY eq_ref distinct_key distinct_key 10 func,func 1 +1 PRIMARY eq_ref distinct_key distinct_key 8 func,func 1 2 MATERIALIZED it2 ref idx_cvk_cvk2_cik,idx_cvk_cik idx_cvk_cvk2_cik 8 const,const 1 Using where; Using index SELECT col_int_nokey FROM ot WHERE (col_varchar_nokey, 'x') IN diff --git a/mysql-test/r/subselect_sj.result b/mysql-test/r/subselect_sj.result index f92b33ff651..1d0aae275ed 100644 --- a/mysql-test/r/subselect_sj.result +++ b/mysql-test/r/subselect_sj.result @@ -802,7 +802,7 @@ INSERT INTO t2 VALUES (1,'i','iiii','iiii','iiii','iiii','ffff','ffff','ffff','f EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (a, b) IN (SELECT a, b FROM t2 WHERE pk > 0); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 13 func,func 1 100.00 +1 PRIMARY eq_ref distinct_key distinct_key 11 func,func 1 100.00 2 MATERIALIZED t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Rowid-ordered scan Warnings: Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`pk` > 0)) @@ -1053,8 +1053,8 @@ AND t1.val IN (SELECT t3.val FROM t3 WHERE t3.val LIKE 'a%' OR t3.val LIKE 'e%'); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 5 -1 PRIMARY eq_ref distinct_key distinct_key 14 func 1 -1 PRIMARY eq_ref distinct_key distinct_key 14 func 1 +1 PRIMARY eq_ref distinct_key distinct_key 13 func 1 +1 PRIMARY eq_ref distinct_key distinct_key 13 func 1 3 MATERIALIZED t3 ALL NULL NULL NULL NULL 5 Using where 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 Using where SELECT * @@ -1633,9 +1633,9 @@ select * from t1 A, t1 B where A.a = B.a and A.a in (select a from t2 C) and B.a in (select a from t2 D); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY A ALL NULL NULL NULL NULL 3 -1 PRIMARY eq_ref distinct_key distinct_key 5 func 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 1 PRIMARY B ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join) -1 PRIMARY eq_ref distinct_key distinct_key 5 func 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 2 MATERIALIZED C ALL NULL NULL NULL NULL 3 3 MATERIALIZED D ALL NULL NULL NULL NULL 3 drop table t1, t2; @@ -2323,7 +2323,7 @@ explain SELECT * FROM t1 WHERE (a) IN (SELECT a FROM t2 JOIN t3 ON b = a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 9 -1 PRIMARY eq_ref distinct_key distinct_key 5 func 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 2 MATERIALIZED t3 ALL NULL NULL NULL NULL 13 Using where 2 MATERIALIZED t2 ref b b 4 test.t3.a 1 Using index SELECT * FROM t1 WHERE (a) IN (SELECT a FROM t2 JOIN t3 ON b = a); @@ -2443,7 +2443,7 @@ EXPLAIN SELECT * FROM t1 RIGHT JOIN t2 ON b = a WHERE t2.b IN (SELECT c FROM t3); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 -1 PRIMARY eq_ref distinct_key distinct_key 5 func 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where 2 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 SELECT * FROM t1 RIGHT JOIN t2 ON b = a WHERE t2.b IN (SELECT c FROM t3); diff --git a/mysql-test/r/subselect_sj2.result b/mysql-test/r/subselect_sj2.result index 4e9672446a3..1ee01030b4b 100644 --- a/mysql-test/r/subselect_sj2.result +++ b/mysql-test/r/subselect_sj2.result @@ -183,7 +183,7 @@ a, mid(filler1, 1,10), length(filler1)=length(filler2) from t2 ot where a in (select a from t1 it); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY ot ALL NULL NULL NULL NULL 22 -1 PRIMARY eq_ref distinct_key distinct_key 5 func 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 2 MATERIALIZED it ALL NULL NULL NULL NULL 32 select a, mid(filler1, 1,10), length(filler1)=length(filler2) @@ -251,7 +251,7 @@ a, mid(filler1, 1,10), length(filler1)=length(filler2) from t2 ot where a in (select a from t1 it); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY ot ALL NULL NULL NULL NULL 22 -1 PRIMARY eq_ref distinct_key distinct_key 5 func 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 2 MATERIALIZED it ALL NULL NULL NULL NULL 52 select a, mid(filler1, 1,10), length(filler1)=length(filler2) @@ -292,7 +292,7 @@ from t0 where a in (select t2.a+t3.a from t1 left join (t2 join t3) on t2.a=t1.a and t3.a=t1.a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t0 ALL NULL NULL NULL NULL 10 -1 PRIMARY eq_ref distinct_key distinct_key 9 func 1 Using where +1 PRIMARY eq_ref distinct_key distinct_key 8 func 1 Using where 2 MATERIALIZED t1 index a a 5 NULL 10 Using where; Using index 2 MATERIALIZED t2 ref a a 5 test.t1.a 1 Using index 2 MATERIALIZED t3 ref a a 5 test.t1.a 1 Using index @@ -721,7 +721,7 @@ The following must use loose index scan over t3, key a: explain select count(a) from t2 where a in ( SELECT a FROM t3); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 index a a 5 NULL 1000 Using index -1 PRIMARY eq_ref distinct_key distinct_key 5 func 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 2 MATERIALIZED t3 index a a 5 NULL 30000 Using index select count(a) from t2 where a in ( SELECT a FROM t3); count(a) @@ -878,7 +878,7 @@ SELECT * FROM t3 LEFT JOIN (v1,t2) ON t3.a = t2.a WHERE t3.b IN (SELECT b FROM t4); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 1 -1 PRIMARY eq_ref distinct_key distinct_key 5 func 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where 1 PRIMARY ALL NULL NULL NULL NULL 2 2 MATERIALIZED t4 ALL NULL NULL NULL NULL 2 diff --git a/mysql-test/r/subselect_sj2_jcl6.result b/mysql-test/r/subselect_sj2_jcl6.result index 1b7d65275ab..e69548dcf5f 100644 --- a/mysql-test/r/subselect_sj2_jcl6.result +++ b/mysql-test/r/subselect_sj2_jcl6.result @@ -133,7 +133,7 @@ set max_heap_table_size= @save_max_heap_table_size; explain select * from t1 where a in (select b from t2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 -1 PRIMARY eq_ref distinct_key distinct_key 5 func 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 2 MATERIALIZED t2 index b b 5 NULL 20 Using index select * from t1; a b @@ -195,7 +195,7 @@ a, mid(filler1, 1,10), length(filler1)=length(filler2) from t2 ot where a in (select a from t1 it); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY ot ALL NULL NULL NULL NULL 22 -1 PRIMARY eq_ref distinct_key distinct_key 5 func 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 2 MATERIALIZED it ALL NULL NULL NULL NULL 32 select a, mid(filler1, 1,10), length(filler1)=length(filler2) @@ -263,7 +263,7 @@ a, mid(filler1, 1,10), length(filler1)=length(filler2) from t2 ot where a in (select a from t1 it); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY ot ALL NULL NULL NULL NULL 22 -1 PRIMARY eq_ref distinct_key distinct_key 5 func 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 2 MATERIALIZED it ALL NULL NULL NULL NULL 52 select a, mid(filler1, 1,10), length(filler1)=length(filler2) @@ -304,7 +304,7 @@ from t0 where a in (select t2.a+t3.a from t1 left join (t2 join t3) on t2.a=t1.a and t3.a=t1.a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t0 ALL NULL NULL NULL NULL 10 -1 PRIMARY eq_ref distinct_key distinct_key 9 func 1 Using where +1 PRIMARY eq_ref distinct_key distinct_key 8 func 1 Using where 2 MATERIALIZED t1 index a a 5 NULL 10 Using where; Using index 2 MATERIALIZED t2 ref a a 5 test.t1.a 1 Using index 2 MATERIALIZED t3 ref a a 5 test.t1.a 1 Using index @@ -735,7 +735,7 @@ The following must use loose index scan over t3, key a: explain select count(a) from t2 where a in ( SELECT a FROM t3); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 index a a 5 NULL 1000 Using index -1 PRIMARY eq_ref distinct_key distinct_key 5 func 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 2 MATERIALIZED t3 index a a 5 NULL 30000 Using index select count(a) from t2 where a in ( SELECT a FROM t3); count(a) @@ -892,7 +892,7 @@ SELECT * FROM t3 LEFT JOIN (v1,t2) ON t3.a = t2.a WHERE t3.b IN (SELECT b FROM t4); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 1 -1 PRIMARY eq_ref distinct_key distinct_key 5 func 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 1 PRIMARY t2 hash_ALL NULL #hash#$hj 5 test.t3.a 1 Using where; Using join buffer (flat, BNLH join) 1 PRIMARY ALL NULL NULL NULL NULL 2 Using join buffer (incremental, BNL join) 2 MATERIALIZED t4 ALL NULL NULL NULL NULL 2 @@ -990,7 +990,7 @@ EXPLAIN SELECT * FROM t1 WHERE b IN (SELECT a FROM t2 GROUP BY a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 1 -1 PRIMARY eq_ref distinct_key distinct_key 5 func 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 1 SELECT * FROM t1 WHERE b IN (SELECT a FROM t2 GROUP BY a); a b @@ -999,7 +999,7 @@ EXPLAIN SELECT * FROM t1 WHERE b IN (SELECT max(a) FROM t2 GROUP BY a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 1 Using where -1 PRIMARY hash_ALL distinct_key #hash#distinct_key 5 test.t1.b 1 Using join buffer (flat, BNLH join) +1 PRIMARY hash_ALL distinct_key #hash#distinct_key 4 test.t1.b 1 Using join buffer (flat, BNLH join) 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 1 Using temporary SELECT * FROM t1 WHERE b IN (SELECT max(a) FROM t2 GROUP BY a); a b diff --git a/mysql-test/r/subselect_sj2_mat.result b/mysql-test/r/subselect_sj2_mat.result index 64d1ce2ef74..f6e98a37007 100644 --- a/mysql-test/r/subselect_sj2_mat.result +++ b/mysql-test/r/subselect_sj2_mat.result @@ -185,7 +185,7 @@ a, mid(filler1, 1,10), length(filler1)=length(filler2) from t2 ot where a in (select a from t1 it); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY ot ALL NULL NULL NULL NULL 22 -1 PRIMARY eq_ref distinct_key distinct_key 5 func 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 2 MATERIALIZED it ALL NULL NULL NULL NULL 32 select a, mid(filler1, 1,10), length(filler1)=length(filler2) @@ -253,7 +253,7 @@ a, mid(filler1, 1,10), length(filler1)=length(filler2) from t2 ot where a in (select a from t1 it); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY ot ALL NULL NULL NULL NULL 22 -1 PRIMARY eq_ref distinct_key distinct_key 5 func 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 2 MATERIALIZED it ALL NULL NULL NULL NULL 52 select a, mid(filler1, 1,10), length(filler1)=length(filler2) @@ -294,7 +294,7 @@ from t0 where a in (select t2.a+t3.a from t1 left join (t2 join t3) on t2.a=t1.a and t3.a=t1.a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t0 ALL NULL NULL NULL NULL 10 -1 PRIMARY eq_ref distinct_key distinct_key 9 func 1 Using where +1 PRIMARY eq_ref distinct_key distinct_key 8 func 1 Using where 2 MATERIALIZED t1 index a a 5 NULL 10 Using where; Using index 2 MATERIALIZED t2 ref a a 5 test.t1.a 1 Using index 2 MATERIALIZED t3 ref a a 5 test.t1.a 1 Using index @@ -723,7 +723,7 @@ The following must use loose index scan over t3, key a: explain select count(a) from t2 where a in ( SELECT a FROM t3); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 index a a 5 NULL 1000 Using index -1 PRIMARY eq_ref distinct_key distinct_key 5 func 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 2 MATERIALIZED t3 index a a 5 NULL 30000 Using index select count(a) from t2 where a in ( SELECT a FROM t3); count(a) @@ -880,7 +880,7 @@ SELECT * FROM t3 LEFT JOIN (v1,t2) ON t3.a = t2.a WHERE t3.b IN (SELECT b FROM t4); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 ALL NULL NULL NULL NULL 1 -1 PRIMARY eq_ref distinct_key distinct_key 5 func 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where 1 PRIMARY ALL NULL NULL NULL NULL 2 2 MATERIALIZED t4 ALL NULL NULL NULL NULL 2 diff --git a/mysql-test/r/subselect_sj_jcl6.result b/mysql-test/r/subselect_sj_jcl6.result index 769373429da..baa2aec8aea 100644 --- a/mysql-test/r/subselect_sj_jcl6.result +++ b/mysql-test/r/subselect_sj_jcl6.result @@ -815,7 +815,7 @@ INSERT INTO t2 VALUES (1,'i','iiii','iiii','iiii','iiii','ffff','ffff','ffff','f EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (a, b) IN (SELECT a, b FROM t2 WHERE pk > 0); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 13 func,func 1 100.00 +1 PRIMARY eq_ref distinct_key distinct_key 11 func,func 1 100.00 2 MATERIALIZED t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Rowid-ordered scan Warnings: Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`pk` > 0)) @@ -1066,8 +1066,8 @@ AND t1.val IN (SELECT t3.val FROM t3 WHERE t3.val LIKE 'a%' OR t3.val LIKE 'e%'); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 5 -1 PRIMARY eq_ref distinct_key distinct_key 14 func 1 -1 PRIMARY eq_ref distinct_key distinct_key 14 func 1 +1 PRIMARY eq_ref distinct_key distinct_key 13 func 1 +1 PRIMARY eq_ref distinct_key distinct_key 13 func 1 3 MATERIALIZED t3 ALL NULL NULL NULL NULL 5 Using where 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 Using where SELECT * @@ -1646,9 +1646,9 @@ select * from t1 A, t1 B where A.a = B.a and A.a in (select a from t2 C) and B.a in (select a from t2 D); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY A ALL NULL NULL NULL NULL 3 -1 PRIMARY eq_ref distinct_key distinct_key 5 func 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 1 PRIMARY B ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join) -1 PRIMARY eq_ref distinct_key distinct_key 5 func 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 2 MATERIALIZED C ALL NULL NULL NULL NULL 3 3 MATERIALIZED D ALL NULL NULL NULL NULL 3 drop table t1, t2; @@ -1993,7 +1993,7 @@ explain extended SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE t2.f3 IN (SELECT * FROM t4); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 5 func 1 100.00 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 100.00 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) 1 PRIMARY t3 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (incremental, BNL join) 2 MATERIALIZED t4 index f2 f2 5 NULL 2 100.00 Using index @@ -2337,7 +2337,7 @@ explain SELECT * FROM t1 WHERE (a) IN (SELECT a FROM t2 JOIN t3 ON b = a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 9 -1 PRIMARY eq_ref distinct_key distinct_key 5 func 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 2 MATERIALIZED t3 ALL NULL NULL NULL NULL 13 Using where 2 MATERIALIZED t2 ref b b 4 test.t3.a 1 Using index SELECT * FROM t1 WHERE (a) IN (SELECT a FROM t2 JOIN t3 ON b = a); @@ -2457,7 +2457,7 @@ EXPLAIN SELECT * FROM t1 RIGHT JOIN t2 ON b = a WHERE t2.b IN (SELECT c FROM t3); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 -1 PRIMARY eq_ref distinct_key distinct_key 5 func 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) 2 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 SELECT * FROM t1 RIGHT JOIN t2 ON b = a WHERE t2.b IN (SELECT c FROM t3); @@ -2773,7 +2773,7 @@ SELECT * FROM t1 LEFT JOIN t2 ON (c = b) WHERE (a, b) IN (SELECT a, b FROM t1 t); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL idx_a NULL NULL NULL 3 -1 PRIMARY eq_ref distinct_key distinct_key 10 func,func 1 +1 PRIMARY eq_ref distinct_key distinct_key 8 func,func 1 1 PRIMARY t2 ref idx_c idx_c 4 test.t1.b 2 Using where; Using index 2 MATERIALIZED t ALL idx_a NULL NULL NULL 3 SELECT * FROM t1 LEFT JOIN t2 ON (c = b) @@ -2788,7 +2788,7 @@ SELECT * FROM t1 LEFT JOIN t3 ON (c = b) WHERE (a, b) IN (SELECT a, b FROM t1 t); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL idx_a NULL NULL NULL 3 -1 PRIMARY eq_ref distinct_key distinct_key 10 func,func 1 +1 PRIMARY eq_ref distinct_key distinct_key 8 func,func 1 1 PRIMARY t3 ref idx_c idx_c 4 test.t1.b 2 Using where 2 MATERIALIZED t ALL idx_a NULL NULL NULL 3 SELECT * FROM t1 LEFT JOIN t3 ON (c = b) @@ -2804,7 +2804,7 @@ SELECT * FROM t1 LEFT JOIN t2 ON (c = b) WHERE (a, b) IN (SELECT a, b FROM t1 t); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL idx_a NULL NULL NULL 3 -1 PRIMARY eq_ref distinct_key distinct_key 10 func,func 1 +1 PRIMARY eq_ref distinct_key distinct_key 8 func,func 1 1 PRIMARY t2 ref idx_c idx_c 4 test.t1.b 2 Using where; Using index 2 MATERIALIZED t ALL idx_a NULL NULL NULL 3 SELECT * FROM t1 LEFT JOIN t2 ON (c = b) @@ -2819,7 +2819,7 @@ SELECT * FROM t1 LEFT JOIN t3 ON (c = b) WHERE (a, b) IN (SELECT a, b FROM t1 t); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL idx_a NULL NULL NULL 3 -1 PRIMARY eq_ref distinct_key distinct_key 10 func,func 1 +1 PRIMARY eq_ref distinct_key distinct_key 8 func,func 1 1 PRIMARY t3 ref idx_c idx_c 4 test.t1.b 2 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan 2 MATERIALIZED t ALL idx_a NULL NULL NULL 3 SELECT * FROM t1 LEFT JOIN t3 ON (c = b) diff --git a/mysql-test/r/subselect_sj_mat.result b/mysql-test/r/subselect_sj_mat.result index b21236de7b9..3bec3f541a3 100644 --- a/mysql-test/r/subselect_sj_mat.result +++ b/mysql-test/r/subselect_sj_mat.result @@ -47,7 +47,7 @@ explain extended select * from t1 where a1 in (select b1 from t2 where b1 > '0'); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 9 func 1 100.00 +1 PRIMARY eq_ref distinct_key distinct_key 8 func 1 100.00 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where Warnings: Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b1` > '0')) @@ -59,7 +59,7 @@ explain extended select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 9 func 1 100.00 +1 PRIMARY eq_ref distinct_key distinct_key 8 func 1 100.00 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where Warnings: Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b1` > '0')) @@ -71,7 +71,7 @@ explain extended select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 18 func,func 1 100.00 +1 PRIMARY eq_ref distinct_key distinct_key 16 func,func 1 100.00 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where Warnings: Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b1` > '0')) @@ -83,7 +83,7 @@ explain extended select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where -1 PRIMARY eq_ref distinct_key distinct_key 18 test.t1.a1,test.t1.a2 1 100.00 +1 PRIMARY eq_ref distinct_key distinct_key 16 test.t1.a1,test.t1.a2 1 100.00 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using temporary Warnings: Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from (select `test`.`t2`.`b1`,min(`test`.`t2`.`b2`) from `test`.`t2` where (`test`.`t2`.`b1` > '0') group by `test`.`t2`.`b1`) join `test`.`t1` where ((``.`min(b2)` = `test`.`t1`.`a2`) and (``.`b1` = `test`.`t1`.`a1`)) @@ -106,7 +106,7 @@ explain extended select * from t1i where a1 in (select max(b1) from t2i where b1 > '0' group by b1); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1i index it1i1,it1i3 # 18 # 3 100.00 # -1 PRIMARY eq_ref distinct_key # 9 # 1 100.00 # +1 PRIMARY eq_ref distinct_key # 8 # 1 100.00 # 2 MATERIALIZED t2i index it2i1,it2i3 # 9 # 5 100.00 # Warnings: Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from (select max(`test`.`t2i`.`b1`) from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`) join `test`.`t1i` where (``.`max(b1)` = `test`.`t1i`.`a1`) @@ -153,7 +153,7 @@ explain extended select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where -1 PRIMARY eq_ref distinct_key distinct_key 18 test.t1.a1,test.t1.a2 1 100.00 +1 PRIMARY eq_ref distinct_key distinct_key 16 test.t1.a1,test.t1.a2 1 100.00 2 MATERIALIZED t2i range NULL it2i3 9 NULL 3 100.00 Using index for group-by Warnings: Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from (select `test`.`t2i`.`b1`,max(`test`.`t2i`.`b2`) from `test`.`t2i` group by `test`.`t2i`.`b1`) join `test`.`t1` where ((``.`max(b2)` = `test`.`t1`.`a2`) and (``.`b1` = `test`.`t1`.`a1`)) @@ -165,12 +165,12 @@ prepare st1 from "explain select * from t1 where (a1, a2) in (select b1, max(b2) execute st1; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where -1 PRIMARY eq_ref distinct_key distinct_key 18 test.t1.a1,test.t1.a2 1 +1 PRIMARY eq_ref distinct_key distinct_key 16 test.t1.a1,test.t1.a2 1 2 MATERIALIZED t2i range NULL it2i3 9 NULL 3 Using index for group-by execute st1; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where -1 PRIMARY eq_ref distinct_key distinct_key 18 test.t1.a1,test.t1.a2 1 +1 PRIMARY eq_ref distinct_key distinct_key 16 test.t1.a1,test.t1.a2 1 2 MATERIALIZED t2i range NULL it2i3 9 NULL 3 Using index for group-by prepare st2 from "select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1)"; execute st2; @@ -185,7 +185,7 @@ explain extended select * from t1 where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where -1 PRIMARY eq_ref distinct_key distinct_key 18 test.t1.a1,test.t1.a2 1 100.00 +1 PRIMARY eq_ref distinct_key distinct_key 16 test.t1.a1,test.t1.a2 1 100.00 2 MATERIALIZED t2i range it2i1,it2i3 it2i3 18 NULL 3 100.00 Using where; Using index for group-by Warnings: Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from (select `test`.`t2i`.`b1`,min(`test`.`t2i`.`b2`) from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`) join `test`.`t1` where ((``.`min(b2)` = `test`.`t1`.`a2`) and (``.`b1` = `test`.`t1`.`a1`)) @@ -233,7 +233,7 @@ explain extended select * from t1 where (a1, a2) in (select b1, b2 from t2 order by b1, b2); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where -1 PRIMARY eq_ref distinct_key distinct_key 18 test.t1.a1,test.t1.a2 1 100.00 +1 PRIMARY eq_ref distinct_key distinct_key 16 test.t1.a1,test.t1.a2 1 100.00 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Warnings: Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` order by `test`.`t2`.`b1`,`test`.`t2`.`b2`) join `test`.`t1` where ((``.`b2` = `test`.`t1`.`a2`) and (``.`b1` = `test`.`t1`.`a1`)) @@ -245,7 +245,7 @@ explain extended select * from t1i where (a1, a2) in (select b1, b2 from t2i order by b1, b2); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1i index it1i1,it1i2,it1i3 it1i3 18 NULL 3 100.00 Using where; Using index -1 PRIMARY eq_ref distinct_key distinct_key 18 test.t1i.a1,test.t1i.a2 1 100.00 +1 PRIMARY eq_ref distinct_key distinct_key 16 test.t1i.a1,test.t1i.a2 1 100.00 2 MATERIALIZED t2i index NULL it2i3 18 NULL 5 100.00 Using index Warnings: Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` order by `test`.`t2i`.`b1`,`test`.`t2i`.`b2`) join `test`.`t1i` where ((``.`b2` = `test`.`t1i`.`a2`) and (``.`b1` = `test`.`t1i`.`a1`)) @@ -299,8 +299,8 @@ where (a1, a2) in (select b1, b2 from t2 where b1 > '0') and where (c1, c2) in (select b1, b2 from t2i where b2 > '0')); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 18 func,func 1 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 18 func,func 1 100.00 +1 PRIMARY eq_ref distinct_key distinct_key 16 func,func 1 100.00 +1 PRIMARY eq_ref distinct_key distinct_key 16 func,func 1 100.00 3 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where 3 MATERIALIZED t2i index it2i1,it2i2,it2i3 it2i3 18 NULL 5 80.00 Using where; Using index; Using join buffer (flat, BNL join) 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where @@ -341,8 +341,8 @@ b2 in (select c2 from t3 where c2 LIKE '%03')) and where (c1, c2) in (select b1, b2 from t2i where b2 > '0')); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 18 func,func 1 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 18 func,func 1 100.00 +1 PRIMARY eq_ref distinct_key distinct_key 16 func,func 1 100.00 +1 PRIMARY eq_ref distinct_key distinct_key 16 func,func 1 100.00 5 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where 5 MATERIALIZED t2i index it2i1,it2i2,it2i3 it2i3 18 NULL 5 80.00 Using where; Using index; Using join buffer (flat, BNL join) 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where @@ -367,7 +367,7 @@ b2 in (select c2 from t3 t3b where c2 LIKE '%03')) and where (c1, c2) in (select b1, b2 from t2i where b2 > '0')); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 18 func,func 1 100.00 +1 PRIMARY eq_ref distinct_key distinct_key 16 func,func 1 100.00 1 PRIMARY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) 5 MATERIALIZED t3c ALL NULL NULL NULL NULL 4 100.00 Using where 5 MATERIALIZED t2i index it2i1,it2i2,it2i3 it2i3 18 NULL 5 80.00 Using where; Using index; Using join buffer (flat, BNL join) @@ -436,7 +436,7 @@ where (a1, a2) in (select * from t1 where a1 > '0' UNION select * from t2 where where (c1, c2) in (select b1, b2 from t2i where b2 > '0')); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where -1 PRIMARY eq_ref distinct_key distinct_key 18 func,func 1 100.00 +1 PRIMARY eq_ref distinct_key distinct_key 16 func,func 1 100.00 4 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where 4 MATERIALIZED t2i index it2i1,it2i2,it2i3 it2i3 18 NULL 5 80.00 Using where; Using index; Using join buffer (flat, BNL join) 2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00 Using where @@ -460,7 +460,7 @@ a1 = c1; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where 1 PRIMARY t3 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join) -1 PRIMARY eq_ref distinct_key distinct_key 18 func,func 1 100.00 +1 PRIMARY eq_ref distinct_key distinct_key 16 func,func 1 100.00 4 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where 4 MATERIALIZED t2i index it2i1,it2i2,it2i3 it2i3 18 NULL 5 80.00 Using where; Using index; Using join buffer (flat, BNL join) 2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00 Using where @@ -645,7 +645,7 @@ from t1_16 where a1 in (select substring(b1,1,16) from t2_16 where b1 > '0'); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1_16 ALL NULL NULL NULL NULL 3 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 20 func 1 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 19 func 1 100.00 Using where 2 MATERIALIZED t2_16 ALL NULL NULL NULL NULL 3 100.00 Using where Warnings: Note 1003 select left(`test`.`t1_16`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_16`.`a2`,7) AS `left(a2,7)` from `test`.`t1_16` semi join (`test`.`t2_16`) where ((`test`.`t2_16`.`b1` > '0') and (`test`.`t1_16`.`a1` = substr(`test`.`t2_16`.`b1`,1,16))) @@ -675,7 +675,7 @@ from t1_16 where a1 in (select group_concat(b1) from t2_16 group by b2); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1_16 ALL NULL NULL NULL NULL 3 100.00 Using where -1 PRIMARY eq_ref distinct_key distinct_key 261 test.t1_16.a1 1 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 260 test.t1_16.a1 1 100.00 Using where 2 MATERIALIZED t2_16 ALL NULL NULL NULL NULL 3 100.00 Using filesort Warnings: Note 1003 select left(`test`.`t1_16`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_16`.`a2`,7) AS `left(a2,7)` from (select group_concat(`test`.`t2_16`.`b1` separator ',') from `test`.`t2_16` group by `test`.`t2_16`.`b2`) join `test`.`t1_16` where (`test`.`t1_16`.`a1` = ``.`group_concat(b1)`) @@ -760,7 +760,7 @@ from t1_512 where a1 in (select substring(b1,1,512) from t2_512 where b1 > '0'); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1_512 ALL NULL NULL NULL NULL 3 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 517 func 1 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 516 func 1 100.00 Using where 2 MATERIALIZED t2_512 ALL NULL NULL NULL NULL 3 100.00 Using where Warnings: Note 1003 select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from `test`.`t1_512` semi join (`test`.`t2_512`) where ((`test`.`t2_512`.`b1` > '0') and (`test`.`t1_512`.`a1` = substr(`test`.`t2_512`.`b1`,1,512))) @@ -775,7 +775,7 @@ from t1_512 where a1 in (select group_concat(b1) from t2_512 group by b2); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1_512 ALL NULL NULL NULL NULL 3 100.00 Using where -1 PRIMARY eq_ref distinct_key distinct_key 261 test.t1_512.a1 1 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 260 test.t1_512.a1 1 100.00 Using where 2 MATERIALIZED t2_512 ALL NULL NULL NULL NULL 3 100.00 Using filesort Warnings: Note 1003 select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from (select group_concat(`test`.`t2_512`.`b1` separator ',') from `test`.`t2_512` group by `test`.`t2_512`.`b2`) join `test`.`t1_512` where (`test`.`t1_512`.`a1` = ``.`group_concat(b1)`) @@ -789,7 +789,7 @@ from t1_512 where a1 in (select group_concat(b1) from t2_512 group by b2); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1_512 ALL NULL NULL NULL NULL 3 100.00 Using where -1 PRIMARY eq_ref distinct_key distinct_key 261 test.t1_512.a1 1 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 260 test.t1_512.a1 1 100.00 Using where 2 MATERIALIZED t2_512 ALL NULL NULL NULL NULL 3 100.00 Using filesort Warnings: Note 1003 select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from (select group_concat(`test`.`t2_512`.`b1` separator ',') from `test`.`t2_512` group by `test`.`t2_512`.`b2`) join `test`.`t1_512` where (`test`.`t1_512`.`a1` = ``.`group_concat(b1)`) @@ -870,7 +870,7 @@ from t1_1024 where a1 in (select group_concat(b1) from t2_1024 group by b2); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 100.00 Using where -1 PRIMARY eq_ref distinct_key distinct_key 261 test.t1_1024.a1 1 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 260 test.t1_1024.a1 1 100.00 Using where 2 MATERIALIZED t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using filesort Warnings: Note 1003 select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from (select group_concat(`test`.`t2_1024`.`b1` separator ',') from `test`.`t2_1024` group by `test`.`t2_1024`.`b2`) join `test`.`t1_1024` where (`test`.`t1_1024`.`a1` = ``.`group_concat(b1)`) @@ -884,7 +884,7 @@ from t1_1024 where a1 in (select group_concat(b1) from t2_1024 group by b2); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 100.00 Using where -1 PRIMARY eq_ref distinct_key distinct_key 261 test.t1_1024.a1 1 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 260 test.t1_1024.a1 1 100.00 Using where 2 MATERIALIZED t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using filesort Warnings: Note 1003 select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from (select group_concat(`test`.`t2_1024`.`b1` separator ',') from `test`.`t2_1024` group by `test`.`t2_1024`.`b2`) join `test`.`t1_1024` where (`test`.`t1_1024`.`a1` = ``.`group_concat(b1)`) @@ -965,7 +965,7 @@ from t1_1025 where a1 in (select group_concat(b1) from t2_1025 group by b2); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1_1025 ALL NULL NULL NULL NULL 3 100.00 Using where -1 PRIMARY eq_ref distinct_key distinct_key 261 test.t1_1025.a1 1 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 260 test.t1_1025.a1 1 100.00 Using where 2 MATERIALIZED t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using filesort Warnings: Note 1003 select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from (select group_concat(`test`.`t2_1025`.`b1` separator ',') from `test`.`t2_1025` group by `test`.`t2_1025`.`b2`) join `test`.`t1_1025` where (`test`.`t1_1025`.`a1` = ``.`group_concat(b1)`) @@ -979,7 +979,7 @@ from t1_1025 where a1 in (select group_concat(b1) from t2_1025 group by b2); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1_1025 ALL NULL NULL NULL NULL 3 100.00 Using where -1 PRIMARY eq_ref distinct_key distinct_key 261 test.t1_1025.a1 1 100.00 Using where +1 PRIMARY eq_ref distinct_key distinct_key 260 test.t1_1025.a1 1 100.00 Using where 2 MATERIALIZED t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using filesort Warnings: Note 1003 select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from (select group_concat(`test`.`t2_1025`.`b1` separator ',') from `test`.`t2_1025` group by `test`.`t2_1025`.`b2`) join `test`.`t1_1025` where (`test`.`t1_1025`.`a1` = ``.`group_concat(b1)`) @@ -1001,7 +1001,7 @@ from t1bit where (a1, a2) in (select b1, b2 from t2bit); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1bit ALL NULL NULL NULL NULL 3 100.00 -1 PRIMARY eq_ref distinct_key distinct_key 10 func,func 1 100.00 +1 PRIMARY eq_ref distinct_key distinct_key 8 func,func 1 100.00 2 MATERIALIZED t2bit ALL NULL NULL NULL NULL 3 100.00 Warnings: Note 1003 select conv(`test`.`t1bit`.`a1`,10,2) AS `bin(a1)`,conv(`test`.`t1bit`.`a2`,10,2) AS `bin(a2)` from `test`.`t1bit` semi join (`test`.`t2bit`) where 1 @@ -1187,7 +1187,7 @@ insert into t1 values (5); explain select min(a1) from t1 where 7 in (select max(b1) from t2 group by b1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 -1 PRIMARY const distinct_key distinct_key 5 const 1 +1 PRIMARY const distinct_key distinct_key 4 const 1 2 MATERIALIZED NULL NULL NULL NULL NULL NULL NULL no matching row in const table select min(a1) from t1 where 7 in (select max(b1) from t2 group by b1); min(a1) @@ -1236,7 +1236,7 @@ insert into t1 values ('aa', 'aaaa'); explain select a,b from t1 where b in (select a from t1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 -1 PRIMARY eq_ref distinct_key distinct_key 3 func 1 Using where +1 PRIMARY eq_ref distinct_key distinct_key 2 func 1 Using where 2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 select a,b from t1 where b in (select a from t1); a b @@ -1273,7 +1273,7 @@ GROUP BY t3i ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 -1 PRIMARY eq_ref distinct_key distinct_key 5 const 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 const 1 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) 1 PRIMARY t4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) 3 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 Using temporary @@ -1510,7 +1510,7 @@ SET @@optimizer_switch='semijoin=on,materialization=on'; EXPLAIN SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 -1 PRIMARY eq_ref distinct_key distinct_key 5 func 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 2 MATERIALIZED t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Rowid-ordered scan SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0); pk @@ -1878,7 +1878,7 @@ insert into t2 values explain select * from t1 where t1.a in (select a from t2 where t2.a=7 or t2.b<=1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 -1 PRIMARY eq_ref distinct_key distinct_key 5 func 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 func 1 2 MATERIALIZED t2 ALL i_a NULL NULL NULL 8 Using where select * from t1 where t1.a in (select a from t2 where t2.a=7 or t2.b<=1); a b @@ -1898,6 +1898,39 @@ WHERE 'condition'='impossible' MIN(a) NULL DROP TABLE t1; +# +# BUG#939009: Crash with aggregate function in IN subquery +# +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch='materialization=on,semijoin=on'; +CREATE TABLE t1 (a int, b int); +INSERT INTO t1 VALUES (7,1), (4,2), (7,7); +CREATE TABLE t2 ( c INT ); +INSERT INTO t2 VALUES (4), (7), (6); +EXPLAIN EXTENDED +SELECT * FROM t1 +WHERE a IN (SELECT MAX(c) FROM t2) AND b=7 AND (a IS NULL OR a=b); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY const distinct_key distinct_key 4 const 1 100.00 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00 +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from (select max(`test`.`t2`.`c`) from `test`.`t2`) join `test`.`t1` where ((`test`.`t1`.`a` = ``.`MAX(c)`) and (`test`.`t1`.`b` = 7) and (isnull(``.`MAX(c)`) or (``.`MAX(c)` = 7))) +SELECT * FROM t1 +WHERE a IN (SELECT MAX(c) FROM t2) AND b=7 AND (a IS NULL OR a=b); +a b +EXPLAIN +SELECT * FROM t1 +WHERE a IN (SELECT MAX(c) FROM t2 WHERE c < 4) AND b=7 AND (a IS NULL OR a=b); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY const distinct_key distinct_key 4 const 1 Using where +1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join) +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where +SELECT * FROM t1 +WHERE a IN (SELECT MAX(c) FROM t2 WHERE c < 4) AND b=7 AND (a IS NULL OR a=b); +a b +SET optimizer_switch=@save_optimizer_switch; +DROP TABLE t1,t2; # This must be at the end: set optimizer_switch=@subselect_sj_mat_tmp; set join_cache_level=@save_join_cache_level; diff --git a/mysql-test/r/subselect_sj_nonmerged.result b/mysql-test/r/subselect_sj_nonmerged.result index 8df74536de7..2a3768c8c50 100644 --- a/mysql-test/r/subselect_sj_nonmerged.result +++ b/mysql-test/r/subselect_sj_nonmerged.result @@ -40,14 +40,14 @@ alter table t3 add primary key(a); # (despite that subquery's join output estimate is 50 rows) explain select * from t3 where a in (select max(t2.a) from t1, t2 group by t2.b); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL distinct_key NULL NULL NULL 5 Using where +1 PRIMARY ALL distinct_key NULL NULL NULL 5 1 PRIMARY t3 eq_ref PRIMARY PRIMARY 8 .max(t2.a) 1 Using where; Using index 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 Using temporary 2 MATERIALIZED t1 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join) # Compare to this which really will have 50 record combinations: explain select * from t3 where a in (select max(t2.a) from t1, t2 group by t2.b, t1.b); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL distinct_key NULL NULL NULL 50 Using where +1 PRIMARY ALL distinct_key NULL NULL NULL 50 1 PRIMARY t3 eq_ref PRIMARY PRIMARY 8 .max(t2.a) 1 Using where; Using index 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 Using temporary 2 MATERIALIZED t1 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join) @@ -57,7 +57,7 @@ SET optimizer_switch='outer_join_with_cache=off'; explain select * from t3 where a in (select max(t2.a) from t1 left join t2 on t1.a=t2.a group by t2.b, t1.b); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL distinct_key NULL NULL NULL 50 Using where +1 PRIMARY ALL distinct_key NULL NULL NULL 50 1 PRIMARY t3 eq_ref PRIMARY PRIMARY 8 .max(t2.a) 1 Using where; Using index 2 MATERIALIZED t1 ALL NULL NULL NULL NULL 10 Using temporary 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 Using where @@ -69,7 +69,7 @@ t4.b=t0.a and t4.a in (select max(t2.a) from t1, t2 group by t2.b); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t0 ALL NULL NULL NULL NULL 10 1 PRIMARY t4 ALL a NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join) -1 PRIMARY eq_ref distinct_key distinct_key 5 test.t4.a 1 +1 PRIMARY eq_ref distinct_key distinct_key 4 test.t4.a 1 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 Using temporary 2 MATERIALIZED t1 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join) insert into t4 select 100 + (B.a *100 + A.a), 100 + (B.a*100 + A.a), 'filler' from t4 A, t0 B; @@ -77,8 +77,8 @@ explain select * from t4 where t4.a in (select max(t2.a) from t1, t2 group by t2.b) and t4.b in (select max(t2.a) from t1, t2 group by t2.b); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL distinct_key NULL NULL NULL 5 Using where -1 PRIMARY ALL distinct_key NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join) +1 PRIMARY ALL distinct_key NULL NULL NULL 5 +1 PRIMARY ALL distinct_key NULL NULL NULL 5 Using join buffer (flat, BNL join) 1 PRIMARY t4 ref a a 10 .max(t2.a),.max(t2.a) 12 3 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 Using temporary 3 MATERIALIZED t1 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join) @@ -114,7 +114,7 @@ insert into t1 select A.a + 10*B.a + 100*C.a from t0 A, t0 B, t0 C; # The following must use non-merged SJ-Materialization: explain select * from t1 X join t0 Y on X.a < Y.a where X.a in (select max(a) from t0); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL distinct_key NULL NULL NULL 1 Using where +1 PRIMARY ALL distinct_key NULL NULL NULL 1 1 PRIMARY X ref a a 5 .max(a) 1 Using index 1 PRIMARY Y ALL NULL NULL NULL NULL 10 Using where; Using join buffer (flat, BNL join) 2 MATERIALIZED t0 ALL NULL NULL NULL NULL 10 diff --git a/mysql-test/suite/pbxt/r/group_min_max.result b/mysql-test/suite/pbxt/r/group_min_max.result index b73b393f9da..15554216056 100644 --- a/mysql-test/suite/pbxt/r/group_min_max.result +++ b/mysql-test/suite/pbxt/r/group_min_max.result @@ -2256,7 +2256,7 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT 1 FROM t1 AS t1_outer WHERE a IN (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL distinct_key NULL NULL NULL 15 Using where +1 PRIMARY ALL distinct_key NULL NULL NULL 15 1 PRIMARY t1_outer ref a a 5 .max(b) 1 Using index 2 MATERIALIZED t1 index NULL a 10 NULL 15 Using index EXPLAIN SELECT 1 FROM t1 AS t1_outer GROUP BY a HAVING diff --git a/mysql-test/suite/pbxt/r/subselect.result b/mysql-test/suite/pbxt/r/subselect.result index 0a065e61edf..96e14cdf785 100644 --- a/mysql-test/suite/pbxt/r/subselect.result +++ b/mysql-test/suite/pbxt/r/subselect.result @@ -2842,7 +2842,7 @@ Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`, eq_ref distinct_key distinct_key 10 func,func 1 100.00 +1 PRIMARY eq_ref distinct_key distinct_key 8 func,func 1 100.00 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 9 100.00 Using where Warnings: Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`flag` = 'N')) @@ -3435,7 +3435,7 @@ EXPLAIN SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where -1 PRIMARY eq_ref distinct_key distinct_key 23 test.t1.a,test.t1.b 1 +1 PRIMARY eq_ref distinct_key distinct_key 21 test.t1.a,test.t1.b 1 2 MATERIALIZED t1 ALL NULL NULL NULL NULL 9 Using temporary ALTER TABLE t1 ADD INDEX(a); SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a); @@ -3447,7 +3447,7 @@ EXPLAIN SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL a NULL NULL NULL 9 Using where -1 PRIMARY eq_ref distinct_key distinct_key 23 test.t1.a,test.t1.b 1 +1 PRIMARY eq_ref distinct_key distinct_key 21 test.t1.a,test.t1.b 1 2 MATERIALIZED t1 ALL NULL NULL NULL NULL 9 Using temporary DROP TABLE t1; create table t1( f1 int,f2 int); diff --git a/mysql-test/t/subselect_sj_mat.test b/mysql-test/t/subselect_sj_mat.test index 0d04b3f984a..fba15ede5a2 100644 --- a/mysql-test/t/subselect_sj_mat.test +++ b/mysql-test/t/subselect_sj_mat.test @@ -1559,6 +1559,35 @@ WHERE a IN ( DROP TABLE t1; +--echo # +--echo # BUG#939009: Crash with aggregate function in IN subquery +--echo # + +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch='materialization=on,semijoin=on'; + +CREATE TABLE t1 (a int, b int); +INSERT INTO t1 VALUES (7,1), (4,2), (7,7); + +CREATE TABLE t2 ( c INT ); +INSERT INTO t2 VALUES (4), (7), (6); + +EXPLAIN EXTENDED +SELECT * FROM t1 + WHERE a IN (SELECT MAX(c) FROM t2) AND b=7 AND (a IS NULL OR a=b); +SELECT * FROM t1 + WHERE a IN (SELECT MAX(c) FROM t2) AND b=7 AND (a IS NULL OR a=b); + +EXPLAIN +SELECT * FROM t1 + WHERE a IN (SELECT MAX(c) FROM t2 WHERE c < 4) AND b=7 AND (a IS NULL OR a=b); +SELECT * FROM t1 + WHERE a IN (SELECT MAX(c) FROM t2 WHERE c < 4) AND b=7 AND (a IS NULL OR a=b); + +SET optimizer_switch=@save_optimizer_switch; + +DROP TABLE t1,t2; + --echo # This must be at the end: set optimizer_switch=@subselect_sj_mat_tmp; set join_cache_level=@save_join_cache_level; diff --git a/sql/field_conv.cc b/sql/field_conv.cc index ed910c4ef70..c99eb62eb57 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -117,6 +117,11 @@ static void do_outer_field_to_null_str(Copy_field *copy) int set_field_to_null(Field *field) { + if (field->table->null_catch_flags & CHECK_ROW_FOR_NULLS_TO_REJECT) + { + field->table->null_catch_flags|= REJECT_ROW_DUE_TO_NULL_FIELDS; + return -1; + } if (field->real_maybe_null()) { field->set_null(); @@ -160,6 +165,11 @@ set_field_to_null(Field *field) int set_field_to_null_with_conversions(Field *field, bool no_conversions) { + if (field->table->null_catch_flags & CHECK_ROW_FOR_NULLS_TO_REJECT) + { + field->table->null_catch_flags|= REJECT_ROW_DUE_TO_NULL_FIELDS; + return -1; + } if (field->real_maybe_null()) { field->set_null(); diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 52a2c2a7d8b..b40467eb21c 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -4180,6 +4180,11 @@ bool subselect_hash_sj_engine::init(List *tmp_columns, uint subquery_id) memcpy(name, buf, len+1); result_sink->get_tmp_table_param()->materialized_subquery= true; + if (item->substype() == Item_subselect::IN_SUBS && + ((Item_in_subselect*)item)->is_jtbm_merged) + { + result_sink->get_tmp_table_param()->force_not_null_cols= true; + } if (result_sink->create_result_table(thd, tmp_columns, TRUE, tmp_create_options, name, TRUE, TRUE)) diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index d01ef381806..a1d69ba759f 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -3167,6 +3167,7 @@ bool setup_sj_materialization_part1(JOIN_TAB *sjm_tab) sjm->sjm_table_cols.push_back(*p_item); sjm->sjm_table_param.field_count= subq_select->item_list.elements; + sjm->sjm_table_param.force_not_null_cols= TRUE; if (!(sjm->table= create_tmp_table(thd, &sjm->sjm_table_param, sjm->sjm_table_cols, (ORDER*) 0, diff --git a/sql/sql_class.cc b/sql/sql_class.cc index a0ed1cdc83f..9a72b647261 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -3195,6 +3195,11 @@ int select_materialize_with_stats::send_data(List &items) if ((res= select_union::send_data(items))) return res; + if (table->null_catch_flags & REJECT_ROW_DUE_TO_NULL_FIELDS) + { + table->null_catch_flags&= ~REJECT_ROW_DUE_TO_NULL_FIELDS; + return 0; + } /* Skip duplicate rows. */ if (write_err == HA_ERR_FOUND_DUPP_KEY || write_err == HA_ERR_FOUND_DUPP_UNIQUE) @@ -3236,6 +3241,7 @@ void TMP_TABLE_PARAM::init() precomputed_group_by= 0; bit_fields_as_long= 0; materialized_subquery= 0; + force_not_null_cols= 0; skip_create_table= 0; DBUG_VOID_RETURN; } diff --git a/sql/sql_class.h b/sql/sql_class.h index c5f500a6b18..20ca9bd47c5 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -3081,6 +3081,8 @@ public: bool schema_table; /* TRUE if the temp table is created for subquery materialization. */ bool materialized_subquery; + /* TRUE if all columns of the table are guaranteed to be non-nullable */ + bool force_not_null_cols; /* True if GROUP BY and its aggregate functions are already computed by a table access method (e.g. by loose index scan). In this case @@ -3104,7 +3106,8 @@ public: TMP_TABLE_PARAM() :copy_field(0), group_parts(0), group_length(0), group_null_parts(0), convert_blob_length(0), - schema_table(0), materialized_subquery(0), precomputed_group_by(0), + schema_table(0), materialized_subquery(0), force_not_null_cols(0), + precomputed_group_by(0), force_copy_fields(0), bit_fields_as_long(0), skip_create_table(0) {} ~TMP_TABLE_PARAM() diff --git a/sql/sql_select.cc b/sql/sql_select.cc index f2720513b6f..f893abc6665 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3769,15 +3769,18 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end, { /* field = expression OR field IS NULL */ old->level= and_level; - old->optimize= KEY_OPTIMIZE_REF_OR_NULL; - /* - Remember the NOT NULL value unless the value does not depend - on other tables. - */ - if (!old->val->used_tables() && old->val->is_null()) - old->val= new_fields->val; - /* The referred expression can be NULL: */ - old->null_rejecting= 0; + if (old->field->maybe_null()) + { + old->optimize= KEY_OPTIMIZE_REF_OR_NULL; + /* + Remember the NOT NULL value unless the value does not depend + on other tables. + */ + if (!old->val->used_tables() && old->val->is_null()) + old->val= new_fields->val; + /* The referred expression can be NULL: */ + old->null_rejecting= 0; + } } else { @@ -13577,6 +13580,7 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List &fields, table->merge_keys.init(); table->intersect_keys.init(); table->keys_in_use_for_query.init(); + table->no_rows_with_nulls= param->force_not_null_cols; table->s= share; init_tmp_table_share(thd, share, "", 0, tmpname, tmpname); @@ -13656,6 +13660,11 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List &fields, thd->mem_root= mem_root_save; arg= sum_item->set_arg(i, thd, new Item_field(new_field)); thd->mem_root= &table->mem_root; + if (param->force_not_null_cols) + { + new_field->flags|= NOT_NULL_FLAG; + new_field->null_ptr= NULL; + } if (!(new_field->flags & NOT_NULL_FLAG)) { null_count++; @@ -13731,6 +13740,11 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List &fields, agg_item->result_field= new_field; } tmp_from_field++; + if (param->force_not_null_cols) + { + new_field->flags|= NOT_NULL_FLAG; + new_field->null_ptr= NULL; + } reclength+=new_field->pack_length(); if (!(new_field->flags & NOT_NULL_FLAG)) null_count++; diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 599dc993483..5c235fd1778 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -57,9 +57,17 @@ int select_union::send_data(List &values) unit->offset_limit_cnt--; return 0; } + if (table->no_rows_with_nulls) + table->null_catch_flags= CHECK_ROW_FOR_NULLS_TO_REJECT; fill_record(thd, table->field, values, TRUE, FALSE); if (thd->is_error()) return 1; + if (table->no_rows_with_nulls) + { + table->null_catch_flags&= ~CHECK_ROW_FOR_NULLS_TO_REJECT; + if (table->null_catch_flags) + return 0; + } if ((write_err= table->file->ha_write_tmp_row(table->record[0]))) { diff --git a/sql/table.h b/sql/table.h index 8de71658493..5be5f4b481c 100644 --- a/sql/table.h +++ b/sql/table.h @@ -665,6 +665,9 @@ enum index_hint_type INDEX_HINT_FORCE }; +#define CHECK_ROW_FOR_NULLS_TO_REJECT (1 << 0) +#define REJECT_ROW_DUE_TO_NULL_FIELDS (1 << 1) + struct st_table { st_table() {} /* Remove gcc warning */ @@ -807,6 +810,26 @@ struct st_table { NULL, including columns declared as "not null" (see maybe_null). */ bool null_row; + /* + No rows that contain null values can be placed into this table. + Currently this flag can be set to true only for a temporary table + that used to store the result of materialization of a subquery. + */ + bool no_rows_with_nulls; + /* + This field can contain two bit flags: + CHECK_ROW_FOR_NULLS_TO_REJECT + REJECT_ROW_DUE_TO_NULL_FIELDS + The first flag is set for the dynamic contexts where it is prohibited + to write any null into the table. + The second flag is set only if the first flag is set on. + The informs the outer scope that there was an attept to write null + into a field of the table in the context where it is prohibited. + This flag should be set off as soon as the first flag is set on. + Currently these flags are used only the tables tno_rows_with_nulls set + to true. + */ + uint8 null_catch_flags; /* TODO: Each of the following flags take up 8 bits. They can just as easily From 6a72fbe3968befc63baa3cfed6f0deb76c0b8937 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 25 Feb 2012 09:03:06 +0200 Subject: [PATCH 124/135] Fix of LP bug:938518 (also LP bug:791761 and LP bug:806955) Cause of the bug is uninitialized items before evaluation HAVING clasue in case of empty result. --- mysql-test/r/having.result | 61 +++++++++++++++++++++++++++++++++++ mysql-test/t/having.test | 66 +++++++++++++++++++++++++++++++++++++- sql/sql_select.cc | 20 ++++++------ 3 files changed, 137 insertions(+), 10 deletions(-) diff --git a/mysql-test/r/having.result b/mysql-test/r/having.result index fb229cf9e3b..b5d3d6e30c2 100644 --- a/mysql-test/r/having.result +++ b/mysql-test/r/having.result @@ -570,3 +570,64 @@ ORDER BY t1.f1; f1 DROP TABLE t1,t2; End of 5.1 tests +# +# LP bug:938518 HAVING does not reject the result of aggregation +# +CREATE TABLE t1 (pk INT PRIMARY KEY, a INT); +INSERT INTO t1 VALUES (2,7), (4,7), (6,2), (17,0); +SELECT MIN(t.pk) FROM t1, t1 as t WHERE t1.pk = 1; +MIN(t.pk) +NULL +SELECT MIN(t.pk) FROM t1, t1 as t WHERE t1.pk = 1 HAVING MIN(t.pk) < 10; +MIN(t.pk) +drop table t1; +# +# LP bug #791761: MAX over an empty join + HAVING +# +CREATE TABLE t1 (a int, b int , KEY (b)) ; +INSERT INTO t1 VALUES (3,1); +CREATE TABLE t2 (a int NOT NULL ) ; +INSERT INTO t2 VALUES (29); +SELECT MAX(t1.b) FROM t1,t2 WHERE t2.a > 0 HAVING MAX(t1.b) <> 6; +MAX(t1.b) +1 +SELECT MAX(t1.b) FROM t1,t2 WHERE t2.a > 0 HAVING MAX(t1.b) IS NULL; +MAX(t1.b) +EXPLAIN +SELECT MAX(t1.b) FROM t1,t2 WHERE t2.a < 0 HAVING MAX(t1.b) <> 6; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +SELECT MAX(t1.b) FROM t1,t2 WHERE t2.a < 0 HAVING MAX(t1.b) <> 6; +MAX(t1.b) +CREATE TABLE t3 ( f3 int) ; +INSERT INTO t3 VALUES (NULL); +SELECT MAX(t1.b) AS f FROM t1 JOIN t2 ON t2.a != 0 +WHERE (SELECT f3 FROM t3) <> 0 HAVING f <> 6 ; +f +DROP TABLE t1,t2,t3; +# +# LP bug:806955 HAVING not observed with aggregate +subquery +# +CREATE TABLE t1 (f3 int, f10 varchar(1), f11 int, KEY (f10) ); +INSERT INTO t1 VALUES (NULL,'a',0),(8,'b',0); +CREATE TABLE t2 (f2 int); +INSERT INTO t2 VALUES (7); +CREATE TABLE t3 (f3 int); +INSERT INTO t3 VALUES (0),(8); +SELECT MIN( t1.f10 ) AS field1 +FROM t1 , t2 +WHERE t2.f2 IN ( SELECT f3 FROM t3 ) +HAVING field1 < 's'; +field1 +explain extended +SELECT MIN( t1.f10 ) AS field1 +FROM t1 , t2 +WHERE t2.f2 IN ( SELECT f3 FROM t3 ) +HAVING field1 < 's'; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00 Using where +Warnings: +Note 1003 select min(`test`.`t1`.`f10`) AS `field1` from `test`.`t1` join `test`.`t2` where ('7',(select 1 from `test`.`t3` where (('7') = `test`.`t3`.`f3`))) having (`field1` < 's') +drop table t1,t2,t3; +End of 5.2 tests diff --git a/mysql-test/t/having.test b/mysql-test/t/having.test index 2ed8b40b858..df3f217be85 100644 --- a/mysql-test/t/having.test +++ b/mysql-test/t/having.test @@ -589,5 +589,69 @@ ORDER BY t1.f1; DROP TABLE t1,t2; - --echo End of 5.1 tests + +--echo # +--echo # LP bug:938518 HAVING does not reject the result of aggregation +--echo # +CREATE TABLE t1 (pk INT PRIMARY KEY, a INT); +INSERT INTO t1 VALUES (2,7), (4,7), (6,2), (17,0); +SELECT MIN(t.pk) FROM t1, t1 as t WHERE t1.pk = 1; +SELECT MIN(t.pk) FROM t1, t1 as t WHERE t1.pk = 1 HAVING MIN(t.pk) < 10; +drop table t1; + +--echo # +--echo # LP bug #791761: MAX over an empty join + HAVING +--echo # + +CREATE TABLE t1 (a int, b int , KEY (b)) ; +INSERT INTO t1 VALUES (3,1); + +CREATE TABLE t2 (a int NOT NULL ) ; +INSERT INTO t2 VALUES (29); + +SELECT MAX(t1.b) FROM t1,t2 WHERE t2.a > 0 HAVING MAX(t1.b) <> 6; +SELECT MAX(t1.b) FROM t1,t2 WHERE t2.a > 0 HAVING MAX(t1.b) IS NULL; + +EXPLAIN +SELECT MAX(t1.b) FROM t1,t2 WHERE t2.a < 0 HAVING MAX(t1.b) <> 6; +SELECT MAX(t1.b) FROM t1,t2 WHERE t2.a < 0 HAVING MAX(t1.b) <> 6; + +CREATE TABLE t3 ( f3 int) ; +INSERT INTO t3 VALUES (NULL); + +SELECT MAX(t1.b) AS f FROM t1 JOIN t2 ON t2.a != 0 + WHERE (SELECT f3 FROM t3) <> 0 HAVING f <> 6 ; + +DROP TABLE t1,t2,t3; + +--echo # +--echo # LP bug:806955 HAVING not observed with aggregate +subquery +--echo # + +#in 5.3 here optimizer_switch should be saved, and semijoin switched off +CREATE TABLE t1 (f3 int, f10 varchar(1), f11 int, KEY (f10) ); +INSERT INTO t1 VALUES (NULL,'a',0),(8,'b',0); + +CREATE TABLE t2 (f2 int); +INSERT INTO t2 VALUES (7); + +CREATE TABLE t3 (f3 int); +INSERT INTO t3 VALUES (0),(8); + +SELECT MIN( t1.f10 ) AS field1 +FROM t1 , t2 +WHERE t2.f2 IN ( SELECT f3 FROM t3 ) +HAVING field1 < 's'; + +explain extended +SELECT MIN( t1.f10 ) AS field1 +FROM t1 , t2 +WHERE t2.f2 IN ( SELECT f3 FROM t3 ) +HAVING field1 < 's'; + +#in 5.3 here optimizer_switch should be restored +drop table t1,t2,t3; + + +--echo End of 5.2 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 7a70c9bdf44..49f1c11c4d8 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -104,7 +104,7 @@ static ORDER *remove_const(JOIN *join,ORDER *first_order,COND *cond, static int return_zero_rows(JOIN *join, select_result *res,TABLE_LIST *tables, List &fields, bool send_row, ulonglong select_options, const char *info, - Item *having); + Item *having, List &all_fields); static COND *build_equal_items(THD *thd, COND *cond, COND_EQUAL *inherited, List *join_list, @@ -1854,7 +1854,7 @@ JOIN::exec() send_row_on_empty_set(), select_options, zero_result_cause, - having); + having, all_fields); DBUG_VOID_RETURN; } @@ -7447,7 +7447,7 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond, static int return_zero_rows(JOIN *join, select_result *result,TABLE_LIST *tables, List &fields, bool send_row, ulonglong select_options, - const char *info, Item *having) + const char *info, Item *having, List &all_fields) { DBUG_ENTER("return_zero_rows"); @@ -7461,8 +7461,16 @@ return_zero_rows(JOIN *join, select_result *result,TABLE_LIST *tables, if (send_row) { + List_iterator_fast it(all_fields); + Item *item; for (TABLE_LIST *table= tables; table; table= table->next_leaf) mark_as_null_row(table->table); // All fields are NULL + /* + Inform all items (especially aggregating) to calculate HAVING correctly, + also we will need it for sending results. + */ + while ((item= it++)) + item->no_rows_in_result(); if (having && having->val_int() == 0) send_row=0; } @@ -7471,13 +7479,7 @@ return_zero_rows(JOIN *join, select_result *result,TABLE_LIST *tables, { bool send_error= FALSE; if (send_row) - { - List_iterator_fast it(fields); - Item *item; - while ((item= it++)) - item->no_rows_in_result(); send_error= result->send_data(fields) > 0; - } if (!send_error) result->send_eof(); // Should be safe } From 5db67c721afaa114b036b410096a6876f92371cf Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Sat, 25 Feb 2012 17:10:07 -0800 Subject: [PATCH 125/135] Fixed LP bug #939866. The field key_cache_mem_size of the KEY_CACHE structure must be initialized in the function init_key_cache() and updated in the function resize_key_cache(). --- mysys/mf_keycache.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c index a038061d9d0..e0d495ce8e0 100644 --- a/mysys/mf_keycache.c +++ b/mysys/mf_keycache.c @@ -5945,6 +5945,10 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, ((PARTITIONED_KEY_CACHE_CB *) keycache_cb)->partitions : 0; DBUG_ASSERT(partitions <= MAX_KEY_CACHE_PARTITIONS); + keycache->key_cache_mem_size= + keycache->partitions ? + ((PARTITIONED_KEY_CACHE_CB *) keycache_cb)->key_cache_mem_size : + ((SIMPLE_KEY_CACHE_CB *) keycache_cb)->key_cache_mem_size; if (blocks > 0) keycache->can_be_used= 1; return blocks; @@ -6008,6 +6012,11 @@ int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, ((PARTITIONED_KEY_CACHE_CB *)(keycache->keycache_cb))->partitions; } + keycache->key_cache_mem_size= + keycache->partitions ? + ((PARTITIONED_KEY_CACHE_CB *)(keycache->keycache_cb))->key_cache_mem_size : + ((SIMPLE_KEY_CACHE_CB *)(keycache->keycache_cb))->key_cache_mem_size; + keycache->can_be_used= (blocks >= 0); } return blocks; From ad8ccccc2c087b4e25e364f1fb1f0fe624ed9c9b Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Sun, 26 Feb 2012 11:44:52 +0400 Subject: [PATCH 126/135] Bump the version number. --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 227b7ba2da5..66799d13472 100644 --- a/configure.in +++ b/configure.in @@ -13,7 +13,7 @@ dnl When changing the major version number please also check the switch dnl statement in mysqlbinlog::check_master_version(). You may also need dnl to update version.c in ndb. -AC_INIT([MariaDB Server], [5.3.4-MariaDB-rc], [], [mysql]) +AC_INIT([MariaDB Server], [5.3.5-MariaDB-ga], [], [mysql]) AC_CONFIG_SRCDIR([sql/mysqld.cc]) AC_CANONICAL_SYSTEM From d2e3b33b8c9c18304e652656df22af1401481376 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Sun, 26 Feb 2012 00:19:07 -0800 Subject: [PATCH 127/135] Rolled back the patch for bug 791761. A better fix for this bug will be pulled from mariadb-5.2. --- mysql-test/r/having.result | 24 ------------------------ mysql-test/t/having.test | 25 ------------------------- sql/item.h | 1 - sql/item_sum.h | 1 - sql/sql_select.cc | 4 +--- 5 files changed, 1 insertion(+), 54 deletions(-) diff --git a/mysql-test/r/having.result b/mysql-test/r/having.result index e631c7dbe5a..fc2df2b7fc2 100644 --- a/mysql-test/r/having.result +++ b/mysql-test/r/having.result @@ -570,27 +570,3 @@ ORDER BY t1.f1; f1 DROP TABLE t1,t2; End of 5.1 tests -# -# LP bug #791761: MAX over an empty join + HAVING -# -CREATE TABLE t1 (a int, b int , KEY (b)) ; -INSERT INTO t1 VALUES (3,1); -CREATE TABLE t2 (a int NOT NULL ) ; -INSERT INTO t2 VALUES (29); -SELECT MAX(t1.b) FROM t1,t2 WHERE t2.a > 0 HAVING MAX(t1.b) <> 6; -MAX(t1.b) -1 -SELECT MAX(t1.b) FROM t1,t2 WHERE t2.a > 0 HAVING MAX(t1.b) IS NULL; -MAX(t1.b) -EXPLAIN -SELECT MAX(t1.b) FROM t1,t2 WHERE t2.a < 0 HAVING MAX(t1.b) <> 6; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables -SELECT MAX(t1.b) FROM t1,t2 WHERE t2.a < 0 HAVING MAX(t1.b) <> 6; -MAX(t1.b) -CREATE TABLE t3 ( f3 int) ; -INSERT INTO t3 VALUES (NULL); -SELECT MAX(t1.b) AS f FROM t1 JOIN t2 ON t2.a != 0 -WHERE (SELECT f3 FROM t3) <> 0 HAVING f <> 6 ; -f -DROP TABLE t1,t2,t3; diff --git a/mysql-test/t/having.test b/mysql-test/t/having.test index 01342fdf5fa..2ed8b40b858 100644 --- a/mysql-test/t/having.test +++ b/mysql-test/t/having.test @@ -591,28 +591,3 @@ DROP TABLE t1,t2; --echo End of 5.1 tests - ---echo # ---echo # LP bug #791761: MAX over an empty join + HAVING ---echo # - -CREATE TABLE t1 (a int, b int , KEY (b)) ; -INSERT INTO t1 VALUES (3,1); - -CREATE TABLE t2 (a int NOT NULL ) ; -INSERT INTO t2 VALUES (29); - -SELECT MAX(t1.b) FROM t1,t2 WHERE t2.a > 0 HAVING MAX(t1.b) <> 6; -SELECT MAX(t1.b) FROM t1,t2 WHERE t2.a > 0 HAVING MAX(t1.b) IS NULL; - -EXPLAIN -SELECT MAX(t1.b) FROM t1,t2 WHERE t2.a < 0 HAVING MAX(t1.b) <> 6; -SELECT MAX(t1.b) FROM t1,t2 WHERE t2.a < 0 HAVING MAX(t1.b) <> 6; - -CREATE TABLE t3 ( f3 int) ; -INSERT INTO t3 VALUES (NULL); - -SELECT MAX(t1.b) AS f FROM t1 JOIN t2 ON t2.a != 0 - WHERE (SELECT f3 FROM t3) <> 0 HAVING f <> 6 ; - -DROP TABLE t1,t2,t3; diff --git a/sql/item.h b/sql/item.h index 9891d690798..aeae1b1faf2 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1032,7 +1032,6 @@ public: virtual bool update_table_bitmaps_processor(uchar *arg) { return 0; } virtual bool view_used_tables_processor(uchar *arg) { return 0; } virtual bool eval_not_null_tables(uchar *opt_arg) { return 0; } - virtual bool clear_sum_processor(uchar *opt_arg) { return 0; } virtual bool is_subquery_processor (uchar *opt_arg) { return 0; } virtual bool limit_index_condition_pushdown_processor(uchar *opt_arg) { diff --git a/sql/item_sum.h b/sql/item_sum.h index 11caf37e6fe..c970dec5082 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -390,7 +390,6 @@ public: { return trace_unsupported_by_check_vcol_func_processor(func_name()); } - bool clear_sum_processor(uchar *arg) { clear(); return 0; } }; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index b66d235a2e9..d5a23374455 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -10470,9 +10470,7 @@ return_zero_rows(JOIN *join, select_result *result, List &tables, if (!table->is_jtbm()) mark_as_null_row(table->table); // All fields are NULL } - if (having && - !having->walk(&Item::clear_sum_processor, FALSE, NULL) && - having->val_int() == 0) + if (having && having->val_int() == 0) send_row=0; } if (!(result->send_fields(fields, From cf06b29f603334b7026bc88ad4bca714668411f8 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Tue, 28 Feb 2012 13:39:02 +0200 Subject: [PATCH 128/135] Fixed lp:905716 "Assertion `page->size <= share->max_index_block_size'" The issue was that Aria allowed too long keys to be created (so that the internal buffer was not big enough to hold the whole key). Key lengths is now limited to HA_MAX_KEY_LENGTH (1000), as for MyISAM. Fixed failure in "_ma_apply_redo_index: Assertion `new_page_length == 0", as found by buildbot. mysql-test/suite/maria/r/maria.result: Updated results mysql-test/suite/maria/r/maria3.result: Updated results. Added test for bug fix mysql-test/suite/maria/t/maria3.test: Updated results. Added test for bug fix mysql-test/suite/maria/t/optimize.test: Updated test for new max key length storage/maria/ha_maria.cc: Limit key to HA_MAX_KEY_LENGTH. storage/maria/ma_key_recover.c: Limit used page length to max page size (this is in line with the code that writes the entry to the log). This fixes failure in "_ma_apply_redo_index: Assertion `new_page_length == 0", as found by buildbot. storage/maria/ma_search.c: Extra DBUG storage/maria/ma_write.c: Added test to detect errors earlier. --- mysql-test/suite/maria/r/maria.result | 38 +++++++++++++------------- mysql-test/suite/maria/r/maria3.result | 27 ++++++++++++++++-- mysql-test/suite/maria/t/maria3.test | 21 +++++++++++++- mysql-test/suite/maria/t/optimize.test | 4 +-- storage/maria/ha_maria.cc | 11 +++++--- storage/maria/ma_key_recover.c | 2 +- storage/maria/ma_search.c | 4 +++ storage/maria/ma_write.c | 2 ++ 8 files changed, 80 insertions(+), 29 deletions(-) diff --git a/mysql-test/suite/maria/r/maria.result b/mysql-test/suite/maria/r/maria.result index 217955310f9..74b1694d7d1 100644 --- a/mysql-test/suite/maria/r/maria.result +++ b/mysql-test/suite/maria/r/maria.result @@ -340,14 +340,14 @@ Table Op Msg_type Msg_text test.t1 check status OK drop table t1; CREATE TABLE t1 (a varchar(255), b varchar(255), c varchar(255), d varchar(255), e varchar(255), KEY t1 (a, b, c, d, e)); -ERROR 42000: Specified key was too long; max key length is 1208 bytes +ERROR 42000: Specified key was too long; max key length is 1000 bytes CREATE TABLE t1 (a varchar(32000), unique key(a)); -ERROR 42000: Specified key was too long; max key length is 1208 bytes +ERROR 42000: Specified key was too long; max key length is 1000 bytes CREATE TABLE t1 (a varchar(1), b varchar(1), key (a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b)); ERROR 42000: Too many key parts specified; max 32 parts allowed CREATE TABLE t1 (a varchar(255), b varchar(255), c varchar(255), d varchar(255), e varchar(255)); ALTER TABLE t1 ADD INDEX t1 (a, b, c, d, e); -ERROR 42000: Specified key was too long; max key length is 1208 bytes +ERROR 42000: Specified key was too long; max key length is 1000 bytes DROP TABLE t1; CREATE TABLE t1 (a int not null, b int, c int, key(b), key(c), key(a,b), key(c,a)); INSERT into t1 values (0, null, 0), (0, null, 1), (0, null, 2), (0, null,3), (1,1,4); @@ -1551,7 +1551,7 @@ a b drop table t1; create table t1 (v varchar(65530), key(v)); Warnings: -Warning 1071 Specified key was too long; max key length is 1208 bytes +Warning 1071 Specified key was too long; max key length is 1000 bytes drop table if exists t1; create table t1 (v varchar(65536)); Warnings: @@ -1789,34 +1789,34 @@ t1 CREATE TABLE `t1` ( drop table t1; create table t1 (a varchar(2048), key `a` (a)); Warnings: -Warning 1071 Specified key was too long; max key length is 1208 bytes +Warning 1071 Specified key was too long; max key length is 1000 bytes show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` varchar(2048) DEFAULT NULL, - KEY `a` (`a`(1208)) + KEY `a` (`a`(1000)) ) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 drop table t1; create table t1 (a varchar(2048), key `a` (a) key_block_size=1024); Warnings: -Warning 1071 Specified key was too long; max key length is 1208 bytes +Warning 1071 Specified key was too long; max key length is 1000 bytes show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` varchar(2048) DEFAULT NULL, - KEY `a` (`a`(1208)) KEY_BLOCK_SIZE=8192 + KEY `a` (`a`(1000)) KEY_BLOCK_SIZE=8192 ) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 drop table t1; create table t1 (a int not null, b varchar(2048), key (a), key(b)) key_block_size=1024; Warnings: -Warning 1071 Specified key was too long; max key length is 1208 bytes +Warning 1071 Specified key was too long; max key length is 1000 bytes show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL, `b` varchar(2048) DEFAULT NULL, KEY `a` (`a`) KEY_BLOCK_SIZE=8192, - KEY `b` (`b`(1208)) KEY_BLOCK_SIZE=8192 + KEY `b` (`b`(1000)) KEY_BLOCK_SIZE=8192 ) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 KEY_BLOCK_SIZE=1024 alter table t1 key_block_size=2048; show create table t1; @@ -1825,7 +1825,7 @@ t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL, `b` varchar(2048) DEFAULT NULL, KEY `a` (`a`) KEY_BLOCK_SIZE=8192, - KEY `b` (`b`(1208)) KEY_BLOCK_SIZE=8192 + KEY `b` (`b`(1000)) KEY_BLOCK_SIZE=8192 ) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 KEY_BLOCK_SIZE=2048 alter table t1 add c int, add key (c); show create table t1; @@ -1835,7 +1835,7 @@ t1 CREATE TABLE `t1` ( `b` varchar(2048) DEFAULT NULL, `c` int(11) DEFAULT NULL, KEY `a` (`a`) KEY_BLOCK_SIZE=8192, - KEY `b` (`b`(1208)) KEY_BLOCK_SIZE=8192, + KEY `b` (`b`(1000)) KEY_BLOCK_SIZE=8192, KEY `c` (`c`) KEY_BLOCK_SIZE=8192 ) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 KEY_BLOCK_SIZE=2048 alter table t1 key_block_size=0; @@ -1848,33 +1848,33 @@ t1 CREATE TABLE `t1` ( `c` int(11) DEFAULT NULL, `d` int(11) DEFAULT NULL, KEY `a` (`a`) KEY_BLOCK_SIZE=8192, - KEY `b` (`b`(1208)) KEY_BLOCK_SIZE=8192, + KEY `b` (`b`(1000)) KEY_BLOCK_SIZE=8192, KEY `c` (`c`) KEY_BLOCK_SIZE=8192, KEY `d` (`d`) ) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 drop table t1; create table t1 (a int not null, b varchar(2048), key (a), key(b)) key_block_size=8192; Warnings: -Warning 1071 Specified key was too long; max key length is 1208 bytes +Warning 1071 Specified key was too long; max key length is 1000 bytes show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL, `b` varchar(2048) DEFAULT NULL, KEY `a` (`a`), - KEY `b` (`b`(1208)) + KEY `b` (`b`(1000)) ) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 KEY_BLOCK_SIZE=8192 drop table t1; create table t1 (a int not null, b varchar(2048), key (a) key_block_size=1024, key(b)) key_block_size=8192; Warnings: -Warning 1071 Specified key was too long; max key length is 1208 bytes +Warning 1071 Specified key was too long; max key length is 1000 bytes show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL, `b` varchar(2048) DEFAULT NULL, KEY `a` (`a`), - KEY `b` (`b`(1208)) + KEY `b` (`b`(1000)) ) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 KEY_BLOCK_SIZE=8192 drop table t1; create table t1 (a int not null, b int, key (a) key_block_size=1024, key(b) key_block_size=8192) key_block_size=16384; @@ -1897,12 +1897,12 @@ t1 CREATE TABLE `t1` ( drop table t1; create table t1 (a varchar(2048), key `a` (a) key_block_size=1000000000000000000); Warnings: -Warning 1071 Specified key was too long; max key length is 1208 bytes +Warning 1071 Specified key was too long; max key length is 1000 bytes show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` varchar(2048) DEFAULT NULL, - KEY `a` (`a`(1208)) KEY_BLOCK_SIZE=8192 + KEY `a` (`a`(1000)) KEY_BLOCK_SIZE=8192 ) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 drop table t1; create table t1 (a int not null, key `a` (a) key_block_size=1025); diff --git a/mysql-test/suite/maria/r/maria3.result b/mysql-test/suite/maria/r/maria3.result index aca43beb243..2119d9a1869 100644 --- a/mysql-test/suite/maria/r/maria3.result +++ b/mysql-test/suite/maria/r/maria3.result @@ -17,12 +17,12 @@ t1 CREATE TABLE `t1` ( drop table t1; create table t1 (a varchar(2048), key `a` (a) key_block_size=1000000000000000000); Warnings: -Warning 1071 Specified key was too long; max key length is 1208 bytes +Warning 1071 Specified key was too long; max key length is 1000 bytes show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` varchar(2048) DEFAULT NULL, - KEY `a` (`a`(1208)) KEY_BLOCK_SIZE=8192 + KEY `a` (`a`(1000)) KEY_BLOCK_SIZE=8192 ) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 drop table t1; create table t1 (a int not null, key `a` (a) key_block_size=1025); @@ -645,3 +645,26 @@ a b c d e f g h i j 1 A B C D 1 M H 2 Abcdefghi E F G 2 N H drop table t1,t2; +CREATE TABLE t1 ( a VARCHAR(800),KEY(a) ) +ENGINE=Aria DEFAULT CHARACTER SET latin1; +INSERT INTO t1 VALUES +(REPEAT('abc ',200)), (REPEAT('def ',200)), +(REPEAT('ghi ',200)), (REPEAT('jkl ',200)); +INSERT INTO t1 SELECT * FROM t1; +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +ALTER TABLE t1 MODIFY a VARCHAR(800) CHARSET `ucs2`; +Warnings: +Warning 1071 Specified key was too long; max key length is 1000 bytes +Warning 1071 Specified key was too long; max key length is 1000 bytes +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +SHOW CREATE table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(800) CHARACTER SET ucs2 DEFAULT NULL, + KEY `a` (`a`(500)) +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +DROP TABLE t1; diff --git a/mysql-test/suite/maria/t/maria3.test b/mysql-test/suite/maria/t/maria3.test index ed5b709dbaa..b36851c756b 100644 --- a/mysql-test/suite/maria/t/maria3.test +++ b/mysql-test/suite/maria/t/maria3.test @@ -554,9 +554,28 @@ INSERT INTO t2 VALUES (1,'M','','H'), SELECT * FROM t1, t2 WHERE a = g ORDER BY b; drop table t1,t2; - # End of 5.1 tests +# +# bug#905716: Assertion `page->size <= share->max_index_block_size' +# + +CREATE TABLE t1 ( a VARCHAR(800),KEY(a) ) + ENGINE=Aria DEFAULT CHARACTER SET latin1; +INSERT INTO t1 VALUES + (REPEAT('abc ',200)), (REPEAT('def ',200)), + (REPEAT('ghi ',200)), (REPEAT('jkl ',200)); +INSERT INTO t1 SELECT * FROM t1; +# check table is not needed to reproduce the problem, +# but shows that by this time the table appears to be okay. +CHECK TABLE t1; +ALTER TABLE t1 MODIFY a VARCHAR(800) CHARSET `ucs2`; +CHECK TABLE t1; +SHOW CREATE table t1; +DROP TABLE t1; + +# End of 5.2 tests + --disable_result_log --disable_query_log eval set global storage_engine=$default_engine, diff --git a/mysql-test/suite/maria/t/optimize.test b/mysql-test/suite/maria/t/optimize.test index fe87bc558cb..6b310b1d1a6 100644 --- a/mysql-test/suite/maria/t/optimize.test +++ b/mysql-test/suite/maria/t/optimize.test @@ -11,8 +11,7 @@ drop table if exists t1; --disable_query_log set autocommit=1; --disable_warnings -CREATE TABLE t1 ( `col_varchar_1024_utf8_not_null_key` varchar(1024) CHARACTER SET utf8 not null, `col_varchar_1024_utf8_key` varchar(1024) CHARACTER SET utf8, `col_varchar_1024_utf8_not_null` varchar(1024) CHARACTER SET utf8 not null, `col_varchar_1024_utf8` varchar(1024) CHARACTER SET utf8, pk varchar(1024) not null, `col_varchar_1024_latin1` varchar(1024) CHARACTER SET latin1, `col_varchar_1024_latin1_not_null_key` varchar(1024) CHARACTER SET latin1 not null, `col_varchar_1024_latin1_not_null` varchar(1024) CHARACTER SET latin1 not null, `col_varchar_1024_latin1_key` varchar(1024) CHARACTER SET latin1, /*Indices*/ key (`col_varchar_1024_utf8_not_null_key` ), key (`col_varchar_1024_utf8_key` ), primary key (pk), key (`col_varchar_1024_latin1_not_null_key` ), key (`col_varchar_1024_latin1_key` )) ENGINE=aria; ---enable_warnings +CREATE TABLE t1 ( `col_varchar_1000_utf8_not_null_key` varchar(1000) CHARACTER SET utf8 not null, `col_varchar_1000_utf8_key` varchar(1000) CHARACTER SET utf8, `col_varchar_1000_utf8_not_null` varchar(1000) CHARACTER SET utf8 not null, `col_varchar_1000_utf8` varchar(1000) CHARACTER SET utf8, pk varchar(1000) not null, `col_varchar_1000_latin1` varchar(1000) CHARACTER SET latin1, `col_varchar_1000_latin1_not_null_key` varchar(1000) CHARACTER SET latin1 not null, `col_varchar_1000_latin1_not_null` varchar(1000) CHARACTER SET latin1 not null, `col_varchar_1000_latin1_key` varchar(1000) CHARACTER SET latin1, /*Indices*/ key (`col_varchar_1000_utf8_not_null_key` ), key (`col_varchar_1000_utf8_key` ), primary key (pk), key (`col_varchar_1000_latin1_not_null_key` ), key (`col_varchar_1000_latin1_key` )) ENGINE=aria; INSERT /*! IGNORE */ INTO t1 VALUES ('dbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzb', 'wdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwby', 'something', 'pwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambxrovrpulkkjqccekfbfa', 1, 'dpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjr', 'can', 'hdpwdbhfatqokbosjofmpdxvhq', 'rhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambxrovrpulkkjqccekfbfamsuiwhofodwrlsvwmxtvaoazfufeehwftkaugjsnebabzsscqhnafqodwrvohesokjrzhnkjhqowroirjsmofgfvfuomwlcdytimiwybmtuheejeitapnjnestutftmutidlvdubbjdznrxsrrmahxsxurpkqkedeznqccfidiazhmmasxemcshyvhqcxvmhqqvzowtbnjpxxw') , ('urhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxci', 'turhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambxrovrpulkkjqccekfbfamsuiwhofodwrlsvwmxtvaoazfufeehwftkaugjsnebabzsscqhnafqodwrvohesokjrzhnkjhqowroirjsmofgfvfuomwlcdytimiwybmtuheejeitapnjnestutftmutidl', 'to', 'rturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambxrovrpulkkjqccekfbfamsuiwhofodwrlsvwmxtvaoazfufeehwftka', 2, 'grturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmh', 'ygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambxrovrpulkkjqccekfbfamsuiwhofodwrlsvwmxtvaoazfufeehwftkaugjsnebabzsscqhnafqodwrvohesokjrzhnkjhqowroirjsmofgfvfuomwlcdytimiwybmtuheejeitapnjnestutftmutidlvdubbjdznrxsrrmahxsxurpkqkedeznqccfidiazhmmasxemcshyvh', 'rygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambxrovrpulkkjqccekfbfamsuiwhofodwrlsvwmxtvaoazfufeehwftkaugjsnebabzsscqhnafqodwrvohesokjrzhnkjhqowroirjsmofgfvfuomwlcdytimiwybmtuheejeitapnjnestutftmutidlvdubbjdznrxsrrmahxsxurpkqkedeznqccfidiazhmmasxemcshyvhqcxvmhqqvzowtbnjpxxwmabsoaiqscbnfwvhwdjgrhlfusfplamodraqbpgtdgviqngjtlykclmdokwpttsicss', 'vrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizw') , ('c', 'wvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbld', 'had', 'twvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxw', 3, 'htwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambxrovrpulkkjqccekfbfamsuiwhofodwrlsvwmxtvaoazfufeehwftkaugjsnebabzsscqhnafqodwrvohesokjrzhnkjhqowroirjsmofgfvfuomwlcdytimiwybmtuheejeitapnjnestutftmutidlvdubbjd', 'q', 'z', 'phtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfi') , ('vphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambxrovrpulkkjqccekfbfamsuiwhofodwrlsvwmxtvaoazfufeehwftkaugjsnebabzsscqhnafqodwrvohesokjrzhnkjhqowroirjsmofgfvfuomwlcdytimiwybmtuheejeitapn', 'jvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjv', 'ejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgq', 'vejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqyt', 4, 't', 'why', 'your', 'cvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxrey') , ('v', 'rcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambx', 'frcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilx', 'p', 5, 'kfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambxrovrpulkkjqccekfbfamsuiwhofodwrlsvwmxtvaoazfufeehwftkaugjsnebabzsscqhnafqodwrvohesokjrzhnkjhqowroirjsmofgfvfuomwlcdytimiwybmtuheejeitapnjnestutftmutidlvdubbjdznrxsrrmahxsxurpkqkedeznqccfidiazhmmasxemcshyvhqcxvmhqqvzowtbnjpxxwmabsoaiqscbnfwvhwdjgrhlfusfplamodr', 'i', 'ikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmy', 'jikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmu'); INSERT /*! IGNORE */ INTO t1 VALUES ('wjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcq', 'uwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnng', 'zuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajy', 'i', 6, 'u', 'q', 'd', 'izuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkq') , ('bizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambxrovrpulkkjqccekfbfamsuiwhofodwrlsvwmxtvaoazfufeehwftkaugjsnebabzsscqhnafqodwrvohesokjrzhnkjhqowroirjsmofgfvfuomwlcdytimiwybmtuheejeitapnjnestutftmutidlvdub', 'd', 'lbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambxrovrpulkkjqccekfbfamsuiwhofodwrlsvwmxtvaoazfufeehwftkaugjsnebabzsscqhnafqodwrvohesokjrzhnkjhqowroirjsmofgfvfuomwlcdytimiwybmtuheejeitapnjnestutftmutidlvdubbjdznrxsrrmahxsxurpkqkedeznqccfidiazhmmasxemcshyvhqcxvmhqqvzowtbnjpxxwmabsoaiqscbn', 'llbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfz', 7, 'bllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambxrovrpulkkjqccekfbfamsuiwhofodwrlsvwmxtvaoazfufeehwftkaugjsnebabzsscqhnafqodwrvohesokjrzhnkjhqowroirjsmofgfvfuomwlcdytimiwybmtuheejeitapnjnestutf', 'rbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmf', 'really', 'yrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnngh') , ('tyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwp', 'xtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmsw', 'kxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgkne', 'mkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjv', 8, 'zmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgx', 'ezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambxrovrpulkkjqccekfbfamsuiwhofodwrlsvwmxtvaoazfufeehwftkaugjsnebabzsscqhnafqodwrvohesokjrzhnkjhqowroirjsmofgfvfuomwlcdytimiwybmtuheejeitapnjnestutftmutidlvdubbjdznrxsrrmahxsxurpkqkedeznqccfidiazhmmasxemcshyvhqcxvmhqqvzowtbnjpxxwmabsoaiqscbnfwvhwdjgrhlfusfplamodraqbpgtdgviqngjtlykclm', 'no', 'eezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczs') , ('m', 'keezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfep', 'tkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqh', 'ztkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambxrovrpulkkjqccekfbfamsuiwhofodwrlsvwmxtvaoazfufeehwftkaugjsnebabzsscqhnafqodwrvohesokjrzhnkjhqowroirjsmofgfvfuomwlcdytimiwybmtuheejeitapnjnestutftmutidlvdubbjdznrxsrrmahxsxurpkqkedeznqccfidiazhmmasxemcshyvhqcxvmhqqvzowtbnjpxxwmabsoaiqscbnfwvhwdjgrhlf', 9, 'n', 'hey', 'hztkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxw', 'shztkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveamb') , ('bshztkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvf', 'on', 'look', 'I', 10, 'xbshztkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxz', 'lxbshztkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjr', 'what', 'ilxbshztkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnrolj'); INSERT /*! IGNORE */ INTO t1 VALUES ('he', 'hilxbshztkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambxrovrpulkkj', 'khilxbshztkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecf', 'o', 11, 'i', 'okhilxbshztkeezmkxtyrbllbizuwjikfrcvejvphtwvrygr', 'hokhilxbshztkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpd', 'khokhilxbshztkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveamb') , ('kkhokhilxbshztkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphuni', 'about', 'ckkhokhilxbshztkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeq', 'sckkhokhilxbshztkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambxrovrpulkkjqccekfbfamsuiwhofodwrlsvwmxtvaoazfufeehwftkaugjsnebabzsscqhnafqodwrvohesokjrzhnkjhqowroirjsmofgfvfuomwlcdytimiwybmtuheejeitapnjnestutftmutidlvdubbjdznrxsrrmahxsxurpkqkedeznqccfidiazhmmasxemcshyvhqcxvmhqqvzowtb', 12, 'xsckkhokhilxbshztkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwn', 'at', 'pxsckkhokhilxbshztkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpaj', 'kpxsckkhokhilxbshztkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambxrovrpulkkjqccekfbfamsuiwhofodwrlsvwmxtvaoazfufeehwftkaugjsnebabzsscqhnafqodwrvohesokjrzhnkjhqowroirjsmofgfvfuomwlcdytimiwybmtuheejeitapnjnestutftmutidlvdubbjdznrxsrrmahxsxurpkqkedeznqccfidiazhmmasxemcshyvhqcxvmhqqvzowtbnjpx') , ('in', 'see', 'ikpxsckkhokhilxbshztkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyi', 'say', 13, 'you', 'x', 'wikpxsckkhokhilxbshztkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhit', 'why') , ('mean', 'a', 'now', 'm', 14, 'cwikpxsckkhokhilxbshztkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqo', 'acwikpxsckkhokhilxbshztkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaaht', 'racwikpxsckkhokhilxbshztkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswv', 'hracwikpxsckkhokhilxbshztkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambxrovrpulkkjqccekfbfamsuiwhofodwrlsvwmxtvaoa') , ('v', 'l', 'shracwikpxsckkhokhilx', 'gshracwikpxsckkhokhilxbshztkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwyto', 15, 'fgshracwikpxsckkhokhilxbshztkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambxrovrpulkkjqccekfbfamsuiwhofodwrlsv', 'say', 'nfgshracwikpxsckkhokhilxbshztkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpajyalhsygtjrhjxreywihgnxlevtsvfzsztftgvgzkqhwpnbztbcpoqdmhgjffokjvoaejwgqpnhemopbmrkfnkwngdjiawsiarcbkgoudqpkecymujxlwfzdeqnrumctcfmndgknecfzkndoohlpkgksukysorfgkvvkreijhlyhznczsxfdezymeqjpdeydhvhrxolrlxmxxdmajqwizwmyvustnzbrbopxmspxnazyxzmuysgonfckdeurqnroljslhdnjmdetcftzsrkjzmhimfmsbhnsgriqkaejakxzbldvftdcaugaahtcwtnujxmwqvkfepcswvrvqhibmuutnuhmvcnctfzmswcmtsrpmyedqxpoluufzbhwbrmcdiwytofotjitmaijfpfbpdwickgvibccphunilmnxvdsykirhgxvyehxyhixejfktoptnpveambxrovrpulkkjqccekfbfamsuiwhofodwrlsvwmxtvaoazfufeehwftkaugjsnebabzsscqhnafqodwrvohesokjrzhnkjhqowroirjsmofgfvfu', 'onfgshracwikpxsckkhokhilxbshztkeezmkxtyrbllbizuwjikfrcvejvphtwvrygrturhdpwdbhfatqokbosjofmpdxvhqvfnyxowgqqxermmjkovqnoqhpubzfjxwqacdiwyekwemegyaluzytnccflbvqnqnmfvvlhitckzgppyilihmleccmmxqxcilxqvfikqseftdkgtlqzbwpucapktdeqxndcqytizhxaaiyashfuwbyynvenjcsmasklnxxtbzrqxmoupppjcctptgoksleizxkrbednzzwgvlnnghjvvtlpaj'); @@ -155,6 +154,7 @@ INSERT /*! IGNORE */ INTO t1 VALUES ('doeoynuevifnwbjkchuxoaflreoetapkynriylynp INSERT /*! IGNORE */ INTO t1 VALUES ('her', 'don\'t', 'all', 'mfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjwysttpvvhlnyikususboyudkfewhmbmvjtnwnbxojqdgkbiahlemtcoskaafhqdonuvfakxhrrljevcruxbcnrdoznxnpoiwtycgycyefjmhotkmhogrvoqavbzayrfniickzwbmsaxdbyobeqqxparytdosykjqexwykghbeqndfbgfydxshozxoioadrgolfvnorvljclibamxbcoklfodagontokzcjloncuyoprcuftivejpacltphccnksfneuyevpefbipyzmbgsmbtwknvcnitwmsfsfirtxctuimpkdcjtaxqflvqvisxmpoywtwzntcrgmfkujrdjvqfimeefwyehibfsjptaqiuznnpyowjzzmkqzswalbzhtefijzpybwusrbcnriyiijianfdvcgoamkbzgtchdzvwkuxfowykrrfghjvmz', 986, 'm', 'ymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjwysttpvvhlnyikususboyudkfewhmbmvjtn', 'g', 'zymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjwysttpvvhlnyikususboyudkfewhmbmvjtnwnbxojqdgkbiahlemtcoskaafhqdonuvfakxhrrljevcruxbcnrdoznxnpoiwtycgycyefjmhotkmhogrvoqavbzayrfniickzwbmsaxdbyobeqqxparytdosykjqexwykghbeqndfbgfydxshozxoioadrgolfvnorvljclibamxbcoklfodagontokzcjloncuyoprcuftivejpacltphccnksfneuyevpefbipyzmbgsmbtwknvcnitwmsfsfirtxctuimpkdcjtaxqflvqvisxmpoywtwzntcrgmfkujrdjvqfimeefwyehibfsjptaqiuznnpyowjzzmkqzswalbzhtefijzpybwusrbcn') , ('nzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjwysttpvvhlnyikususboyudkfewhmbmvjtnwnbxojqdgkbiahlemtcoskaafhqdonuvfakxhrrljevcruxbcnrdoznxnpoiwtycgycyefjmhotkmhogrvoqavbzayrfniickzwbmsaxdbyobeqqxparytdosykjqexwykghbeqndfbgfydxshozxoioadrgolfvnorvljclibamxbcoklfodagontokzcjloncuyoprcuftivejpacltphccnksfneuyevpefbipyzmbgsmbtwknvcnitwmsfsfirtxctuimpkdcjtaxqflvqvisxmpoywtwzntcrgmfkujrdjvqfimeefwyehibfsjptaqiuznnpyowjzzmkqzswalbzhtefijzpybwusrbcnriyiijianfdvcgoamkbzgtchdzvwkuxfowykrrfghjvmzyudarthdlmr', 'a', 'pnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjwysttpvvhlnyikususboyudkfewhmbmvjtnwnbxojqdgkbiahlemtcoskaafhqdonuvfakxhrrljevcruxbcnrdoznxnpoiwtycgycyefjmhotkmhogrvoqavbzayrfniickzwbmsaxdbyobeqqxparytdosykjqexwykghbeqndfbgfydxshozxoioadrgolfvnorvljclibamxbcoklfodagontokzcjloncuyoprcuftivejpaclt', 'w', 987, 'don\'t', 'upnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpe', 'eupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjwysttpvvhlnyikususboyudkfewhmbmvjtnwnbxojqdgkbiahlemtcoskaafhqdonuvfakxhrrljevcruxbcnrdoznxnpoiwtycgycyefjmhotkmhogrvoqavbzayrfniickzwbmsaxdbyobeqqxparytdosykjqexwykghbeqndfbgfyd', 'w') , ('leupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjwysttpvvhlnyikususboyudkfewhmbmvjtnwnbxojqdgkbiahlemtcoskaafhqdonuvfakxhrrljevcruxbcnrdoznxnpoiwtycgycyefjmhotkmhogrvoqavbzayrfniickzwbmsaxdbyobeqqxparytdosykjqexwykghbeqndfbgfydxshozxoioadrgolfvnorvljclibamxbcoklfodagontokzcjloncu', 'vleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjwysttpvvhlnyikususboyudkfewhmbmvjtnwnbxojqdgkbiahlemtcoskaafhqdonuvfakxhrrljevcruxbcnrdoznxnpoiwtycgycyefjmhotkmhogrvoqavbzayrfniickzwbmsaxdbyobeqqxparytdosykjqexwykghbeqndfbgfydxshozxoioadrgolfvnorvljclibamxbcoklfodagontokzcjloncuyoprcuftivejpacltphccnksfneuyevpefbipyzmbgsmbtwknvcnitwmsfsfirtxctuimpkdcjtaxqflvqvisxmpoywtwzntcrgmfkujrdjvqfimeefwyehibfsjptaqiuznnpyowjzzmkqzswalbzhtefijzpybwusrbcnriyiijianfdvcgoamkbzgtchdzvwkuxfowykrrfghjvmzyudarthdlmrpvvacmukvrl', 'x', 'ivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeao', 988, 'g', 'sivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucc', 'you\'re', 'nsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufc') , ('znsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqc', 'c', 'oznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjwysttpvvhlnyikususboyudkfewhmbmvjtnwnbxojqdgkbiahlemtcoskaafhqdonuvfakxhrrljevcruxbcnrdoznxnpoiwtycgycyefjmhotkmhogrvoqavbzayrfniickzwbmsaxdbyobeqqxparytdosykjqexwykghbeqndfbgfydxshozxoioadrgolfvnorvljclibamxbcoklfoda', 'hoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjwysttpvvhlnyikususboyudkfewhmbmvjtnwnbxojqdgkbiahlemtcoskaafhqdonuvfakxhrrljevcruxbcnrdoznxnpoiwtycgycyefjmhotkmhogrvoqavbzayrfniickzwbmsaxdbyobeqqxparytdosykjqexwykghbeqndfbgfydxshozxoioadrgolfvnorvljclibamxbcoklfodagontokzcjloncuyoprcuftivejpacltphccnksfneuyevpefbipyzmbgsmbtwknvcnitwmsfsfirtxctuimpkdcjtaxqflvqvisxmpoywtwzntcrgmfkujrdjvqfimeefwyehibfsjptaqiuznnpyowjzzmkqzswalbzhtefijzpybwusrbc', 989, 'uhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujk', 'cuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfzi', 'bcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjwysttpvvhlnyikususboyudkfewhmbmvjtnwnbxojqdgkbiahlemtcoskaafhqdonuvfakxhrrljevcruxbcnrdoznxnpoiwtycgycyefjmhotkmhogrvoqavbzayrfniickzwbmsaxdbyobeqqxparytdosykjqexwykghbeqndfbgfydxshozxoioadrgolfvnorvljclibamxbcoklfodagontokzcjloncuyoprcuftivejpacltphccnksfneuyevpefbipyzmbgsmbtwknvcnitwmsfsfirtxctuimpkdcjtaxqflvqvisxmpoywtwzntcrgmfkujrdjvqfimeefwyehibfsjptaqiuznnpyowjzzmkqzswalbzhtefijzpybwusrbcnriyiijianfdvcgoamk', 'dbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjwysttpvvhlnyikususboyudkfewhmbmvjtnwnbxojqdgkbiahlemtcoskaafhqdonuvfakxhrrljevcruxbcnrdoznxnpoiwtycgycyefjmhotkmhogrvoqavbzayrfniickzwbmsaxdbyobeqqxparyt') , ('adbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsd', 'uadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjwysttpvvhlnyikususboyudkfewhmbmvjtnwnbxojqdgkbiahlemtcoskaafhqdonuvfakxhrrljevcruxbcnrdoznxnpoiwtycgycyefjmhotkmhogrvoqavbzayrfniickzwbmsaxdbyobeqqxparytdosykjqexwykghbeqndfbgfydxshozxoioadrgolfvnorvljclibamxbcoklfodagontokzcjloncuyoprcuftivejpacltphccnksfneuyevpefbipyzmbgsmbtwknvcnitwmsfsfirtxctuimpkdcjtaxqflvqvisxmpoywtwzntcrgmfkuj', 'huadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbec', 'hhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyy', 990, 'uhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoe', 'iuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvt', 'qiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjwysttpvvhlnyikususboyudkfewhmbmvjtnwnbxojqdgkbiahlemtcoskaafhqdonuvfakxhrrljevcruxbcnrdoznxnpoiwtycgycyefjmhotkmhogrvoqavbzayrfniickzwbmsaxdbyobeqqxparytdosykjqex', 'eqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjw'); INSERT /*! IGNORE */ INTO t1 VALUES ('keqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjwysttpvvhlnyi', 'f', 'jkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwo', 'xjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjwysttpvvhlnyikususboyudkfewhmbmvjtnwnbxojqdgkbiahlemtcoskaafhqdonuvfakxhrrljevcruxbcnrdoznxnpoiwtycgycyefjmhotkmhogrvoqavbzayrfniickzwbmsaxdbyobeqqxparytdosykjqexwykghbeqndfbgfydxshozxoioadrgolfvnorvljclibamxbcoklfodagontokzcjloncuyop', 991, 'pxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofne', 'f', 'f', 'dpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdio') , ('xdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjwysttpvvhlnyikususboyudkfewhmbmvjtnwnbxojqdgkbiahlemtcoskaafhqdonuvfakxhrrljevcruxbcnrdoznxnpoiwtycgycyefjmhotkmhogrvoqavbzayrfniickzwbmsaxdbyobeqqxparytdosykjqexwykghbeqndfbgfydxshozxoioadrgolfvnorvljclibamxbcoklfodagontokzc', 's', 'got', 'on', 992, 'bxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjwysttpvvhlnyikususboyudkfewhmbmvjtnwnbxojqdgkbiahlemtcoskaafhqdonuvfakxhrrljevcruxbcnrdoznxnpoiwtycgycyefjmhotkmhogrvoqavbzayrfniickzwbmsaxdbyobeqqxparytdosykjqexwykghbeqndfbgfydxshozxoioadrgolfvnorvljclibamxbcoklfodagontokzcjloncuyoprcuftivejpacltphccnksfneuyevpefbipyzmbgsmbtwknvcnitwmsfsfirtxctuimpkdcjtaxqflvqvisxmpoywtwzntcrgmfkujrdjvqfimeefwyehibfsjptaqiuznnpyowjzzmkqzswalbzhtef', 'xbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfp', 'p', 'x') , ('xxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwas', 'exxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzp', 'vexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowh', 'gvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialk', 993, 'ugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsx', 'pugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjwysttpvvhlnyikususboyudkfewhmbmvjtnwnbxojqdgkbiahlemtcoskaafhqdonuvfakxhrrljevcruxbcnrdoznxnpoiwtycgyc', 'kpugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyy', 'her') , ('d', 'ikpugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckz', 'who', 'bikpugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialk', 994, 'abikpugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaot', 'were', 'wabikpugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznb', 'y') , ('vwabikpugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjwysttpvvhlnyikususboyudkfewhmbmvjtnwnbxojqdgkbiahlemtcoskaafhqdonuvfakxh', 'to', 'qvwabikpugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjwysttpvvhlnyikususboyudkfewhmbmvjtnwnbxojqdgkbiahlemtcoskaafhqdonuvfakxhrrljevcruxbcnrdoznxnpoiwtycgycyefjmhotkmhogrvoqavbzayrfniickzwbmsaxdbyobeqqxparytdosykjqexwykghbeqndfbgfydxshozxoioadrgolfvnorvljclibamxbcoklfodagontokzcjloncuyoprcuftivejpacltphcc', 'xqvwabikpugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjwysttpvvhlnyikususboyudkfewhmbmvjtnwnbxojqdgkbiahlemtcoskaafhqdonuvfakxhrrljevcruxbcnrdoznxnpoiwtycgycyefjmhotkmhogrvoqavbzayrfniickzwbmsaxdbyobeqqxparytdosykjqexwykghbeqndfbgfydxshozxoioadrgolfvnorvljclibamxbcoklfodagontokzcjloncuyoprcuftivejpacltphccnksfneuyevpefbipyzmbgsmbtwknvcnitwmsfsfirtxctuimpkdcjtaxqflvqvisxmpoywtwzntcrgmfkujrdjvqfimeefwyehibfsjp', 995, 'jxqvwabikpugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjwysttpvvhlnyikususboyudkfewhmbmvjtnwnbxojqdgkbiahlemtcoskaafhqdonuvfakxhrrljevcruxbcnrdoznxnpoiwtycgycyefjmhotkmhogrvoqavbzayrfniickzwbmsaxdbyobeqqxparytdosykjqexwykghbeqndfbgfydxshozxoioadrgolfvnorvljclibamxbcoklfodagontokzcjloncuyoprcuftivejpacltphccnksfneuyevpefbipyzmbgsmbtwknvcnitwmsfsfirtxc', 'o', 'xjxqvwabikpugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbj', 'rxjxqvwabikpugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqic'); INSERT /*! IGNORE */ INTO t1 VALUES ('urxjxqvwabikpugvexxbxdpxjkeqiuhhuadbcuhoz', 'curxjxqvwabikpugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzew', 'acurxjxqvwabikpugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamax', 'with', 996, 'was', 'uacurxjxqvwabikpugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjwysttpvvhlnyikususboyudkfewhmbmvjtnwnbxojqdgkbiahlemtcoskaafhqdonuvfakxhrrljevcruxbcnrdoznxnpoiwtycgycyefjmhotkmhogrvoqavbzayrfniickzwbmsaxdbyobeqqxparytdosykjqexwykghbeqndfbgfydxshozxoioadrgolfvnorvljclibamxbcoklfodagontokzcjloncuyoprcuftivejpacltphccnksfneuyevpefbipyzmbgsmbtwknvcnitwmsfsfirtxctuimpkdcjtaxqflvqvisxmpoywtwzntcrgmfkujrdjvqfimeefwyehibfsjptaqiuznnpyowjzzmkqzswalbzhtefijzpybwusrbcnriyiijianfdvcgoamkbzgtchdzvwkuxfowykrrfghjvmzyudarthdlm', 'duacurxjxqvwabikpugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiut', 'nduacurxjxqvwabikpugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjwysttpvvhlnyikususboyudkfewhmbmvjtnwnbxojqdgkbiahlemtcoskaafhqdonuvfakxhrrljevcruxbcnrdoznxnpoiwtycgycyefjmhotkmhogrvoqavbzayrfniickzwbmsaxdbyobeqqxparytdosykjqexwykghbeqndfbgfydxshozxoioadrgolfvnorvljclibamxbcoklfodagontokz') , ('had', 'gnduacurxjxqvwabikpugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfck', 'ognduacurxjxqvwabikpugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvn', 'oognduacurxjxqvwabikpugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjwysttpvvhlnyikususboyudkfewhmbmvjtnwnbxojqdgkbiahlemtcoskaafhqdonuvfakxhrrljevcruxbcnrdoznxnpoiwtycgycyefjmhotkmhogrvoqavbzayrfniickzwbmsaxdbyobeqqxparytdosykjqexwykghbeqndfbgfydxshozxoioadrgolfvnorvljclibamxbcoklfodagontokzcjloncuyoprcuftivejpacltphccnksfneuyevpefbipyzmbgsmbtwknvcnitwmsfsfirtxctu', 997, 'toognduacurxjxqvwabikpugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjwysttpvvhlnyikususboyudkfewhmbmvjtnwnbxojqdgkbiahlemtcoskaafhqdonuvfakxhrrljevcruxbcnrdoznxnpoiwtycgycyefjmhotkmhogrvoqavbzayrfniickzwbmsaxdbyobeqqxparytdosykjqexwykghbeqndfbgfydxshoz', 'ytoognduacurxjxqvwabikpugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjwysttpvvhlnyikususboyudkfewhmbmvjtnwnbxojqdgkbiahlemtcoskaafhqdonuvfakxhrrljevcruxbcnrdoznxnpoiwtycgycyefjmhotkmhogrvoqavbzayrfniickzwbmsaxdbyobeqqxparytdosykjqexwykghbeqndfbgfydxshozxoioadrgolfvnorvljclibamxbcoklfodagontokzcjloncuyopr', 'bytoognduacurxjxqvwabikpugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjwysttpvvhlnyikususboyudkfewhmbmvjtnwnbxojqdgkbiahlemtcoskaafhqdonuvfakxhrrljevcruxbcnrdoznxnpoiwtycgycyefjmhotkmhogrvoqavbzayrfniickzwbmsaxdbyobeqqxparytdosykjqexwykghbeqndfbgfydxshozxoioadrgolfvnorvljclibamxbcoklfodagontokzcjloncuyoprcuftivejpacltphccnksfneuyevpef', 'jbytoognduacurxjxqvwabikpugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjwysttpvvhlnyikususboyudkfewhmbmvjtnwnbxojqdgkbiahlemtcoskaafhqdonuvfakxhrrljevcruxbcnrdoznxnpoiwtycgycyefjmhotkmhogrvoqavbzayrfniickzwbmsaxdbyobeqqxparytdosykjqexwykghbeqndfbgfydxshozxoioadrgolfvnorvljclibamxbcoklfodagontokz') , ('ujbytoognduacurxjxqvwabikpugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutv', 'dujbytoognduacurxjxqvwabikpugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuev', 'are', 'i', 998, 'bdujbytoognduacurxjxqvwabikpugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjwysttpvvhlnyikususboyudkfewhmbmvjtnwnbxojqdgkbiahlemtcos', 'y', 'w', 'b') , ('ybdujbytoognduacurxjxqvwabikpugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriyl', 'go', 'zybdujbytoognduacurxjxqvwabikpugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjwysttpvvhlnyikususboyudkfewhmbmvjtnwnbxojqdgkbiahl', 'ok', 999, 'fzybdujbytoognduacurxjxqvwabikpugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczy', 'l', 'bfzybdujbytoognduacurxjxqvwabikpugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjwysttpvvhlnyikususboyudkfewhmbmvjtnwnbxojqdgkbiahlemtcoskaafhqdonuvfakxhrrljevcruxbcnrdoznxnpoiwtycgycyefjmhotkmhogrvoqavbzayrfniickzwbmsaxdbyobeqqxparytdosykjqexwykghbeqndfbgfydxshozxoioadrgolfvnorvljclibamxbcoklfodagontokzcjloncuyoprcuftivejpacltphccnksfneuyevpefbipyzmbgsmbtwknvcnitwmsfsfirtxctuimpkdcjtaxqflvqvisxmpoywtwzntcrgmfkujrdjvqfimeefwyehibfsjptaqiuznnpyowjzzmkqzswalbzhtefijzpybwus', 'nbfzybdujbytoognduacurxjxqvwabikpugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjwysttpvvhlnyikususboyudkfewhmbmvjtnwnbxojqdgkbiahlemtcoskaafhqdonuvfakxhrrljevcruxbcnrdoznxnpoiwtycgycyefjmhotkmhogrvoqavbzayrfniickzwbmsaxdbyobeqqxparytdosykjqexwykghbeqndfbgfydxshozxoioadrgolfvnorvljclibamxbcoklfodagontokzcjloncuyoprcuftivejpacltphccnksfneuyevpefbipyzmbgsmbtwknvcnitwmsfsfirtxct') , ('nnbfzybdujbytoognduacurxjxqvwabikpugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnr', 'ynnbfzybdujbytoognduacurxjxqvwabikpugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiu', 'b', 'o', 1000, 'fynnbfzybdujbytoognduacurxjxqvwabikpugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyewsfyenmcxdvddqdvjzdmcxycpinvyxdspwajhwpdtzpelbfpteijeisukfgurzqicgvhmvbkhzfziauialkyolxxpwirxkpzawchzbvnrmmzqbdrvorvfbgbecicohkxaevsoapogbwzbjifuboxagzmlfjkazdvpvnghijvamaxjnrfkakkfbtotujswtanfdknssrfmkpqbowhdduqsdypbxsxtysyewyplhughdfnpahtbnzewsqggozswjeaotpesrujknsosizbwqvgwzcfjvdccjwysttpvvhlnyikususboyudkfewhmbmvjtnwnbxojqdgkbia', 'f', 'r', 'ifynnbfzybdujbytoognduacurxjxqvwabikpugvexxbxdpxjkeqiuhhuadbcuhoznsivleupnzymfhieibzvolxmwokzgntahmadoeoynuevifnwbjkchuxoaflreoetapkynriylynprdflglhfazkqtnahvvuthwuprbgmsofnedkykwozxiutvjlihiezrimymgtjfelrowywwwwasriclgihuyytjlntqfxypodnlqcvplkfpvtdiouucczyrnjwbhezsureyaebufctbjfckznbydnjuomgyvasucvdeyew'); +--enable_warnings --enable_query_log check table t1; diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index 04a97da9d8d..1e8a03d3990 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -888,8 +888,11 @@ double ha_maria::scan_time() splitting algorithms depends on this. (With only one key on a page we also can't use any compression, which may make the index file much larger) - We use HA_MAX_KEY_BUFF as this is a stack restriction imposed by the - handler interface. + We use HA_MAX_KEY_LENGTH as this is a stack restriction imposed by the + handler interface. If we want to increase this, we have also to + increase HA_MARIA_KEY_BUFF and MARIA_MAX_KEY_BUFF as the buffer needs + to take be able to store the extra lenght bytes that is part of the stored + key. We also need to reserve place for a record pointer (8) and 3 bytes per key segment to store the length of the segment + possible null bytes. @@ -900,7 +903,7 @@ double ha_maria::scan_time() uint ha_maria::max_supported_key_length() const { uint tmp= (maria_max_key_length() - 8 - HA_MAX_KEY_SEG*3); - return min(HA_MAX_KEY_BUFF, tmp); + return min(HA_MAX_KEY_LENGTH, tmp); } @@ -2948,7 +2951,7 @@ void ha_maria::get_auto_increment(ulonglong offset, ulonglong increment, { ulonglong nr; int error; - uchar key[HA_MAX_KEY_LENGTH]; + uchar key[MARIA_MAX_KEY_BUFF]; if (!table->s->next_number_key_offset) { // Autoincrement at key-start diff --git a/storage/maria/ma_key_recover.c b/storage/maria/ma_key_recover.c index c0d906117b6..16ecfa292a9 100644 --- a/storage/maria/ma_key_recover.c +++ b/storage/maria/ma_key_recover.c @@ -1107,7 +1107,7 @@ uint _ma_apply_redo_index(MARIA_HA *info, DBUG_PRINT("redo", ("org_page_length: %u new_page_length: %u", uint2korr(header), uint2korr(header+2))); DBUG_ASSERT(uint2korr(header) == page_length); - new_page_length= uint2korr(header+2); + new_page_length= min(uint2korr(header+2), max_page_size); header+= 4; break; case KEY_OP_MAX_PAGELENGTH: diff --git a/storage/maria/ma_search.c b/storage/maria/ma_search.c index d6270daacee..166de13831f 100644 --- a/storage/maria/ma_search.c +++ b/storage/maria/ma_search.c @@ -1383,6 +1383,10 @@ uint _ma_get_binary_pack_key(MARIA_KEY *int_key, uint page_flag, uint nod_flag, memcpy(key, from, length + nod_flag); *page_pos= from + length + nod_flag; +#ifdef USEFUL_FOR_DEBUGGING + DBUG_DUMP("key", int_key->data, + (uint) (int_key->data_length + int_key->ref_length)); +#endif DBUG_RETURN(int_key->data_length + int_key->ref_length); } diff --git a/storage/maria/ma_write.c b/storage/maria/ma_write.c index 322bc4fcf20..5db2de51625 100644 --- a/storage/maria/ma_write.c +++ b/storage/maria/ma_write.c @@ -715,6 +715,8 @@ static int w_search(register MARIA_HA *info, uint32 comp_flag, MARIA_KEY *key, { error= _ma_insert(info, key, &page, keypos, keybuff, father_page, father_keypos, insert_last); + if (error < 0) + goto err; page_mark_changed(info, &page); if (_ma_write_keypage(&page, PAGECACHE_LOCK_LEFT_WRITELOCKED, DFLT_INIT_HITS)) From 54f9fe6c8b0472f0e12602eabf94ff4d73161806 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 28 Feb 2012 15:41:55 +0100 Subject: [PATCH 129/135] lp:938977 - Query performance with join/index super slow on MariaDB 5.3.4RC make sure that stored routines are evaluated (that is, de facto - cached) in convert_const_to_int(). revert the fix for lp:806943 because it cannot be repeated anymore. add few tests for convert_const_to_int() --- mysql-test/r/subselect4.result | 31 ------------------------------- mysql-test/r/type_year.result | 22 ++++++++++++++++++++++ mysql-test/t/subselect4.test | 33 --------------------------------- mysql-test/t/type_year.test | 17 +++++++++++++++++ sql/item_cmpfunc.cc | 9 +++++++-- 5 files changed, 46 insertions(+), 66 deletions(-) diff --git a/mysql-test/r/subselect4.result b/mysql-test/r/subselect4.result index e8822ebf6bd..ff822113338 100644 --- a/mysql-test/r/subselect4.result +++ b/mysql-test/r/subselect4.result @@ -1820,37 +1820,6 @@ AND t2.f2 = t1.f1; f1 f2 f1 f2 drop table t1,t2,t3,t4; # -# LP BUG#806943 Second crash with select_describe with nested subqueries in maria-5.3 -# -CREATE TABLE t1 ( f4 int) ; -INSERT INTO t1 VALUES (0),(0); -CREATE TABLE t2 ( f2 int) ; -CREATE TABLE t3 ( f1 int NOT NULL ); -CREATE TABLE t4 ( f2 int, f3 int) ; -INSERT INTO t4 VALUES (8,0),(3,0); -EXPLAIN SELECT * -FROM t2, t3 -WHERE t3.f1 = ( -SELECT SUM( f2 ) -FROM t4 -WHERE EXISTS ( -SELECT DISTINCT f4 -FROM t1)); -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 SUBQUERY t4 ALL NULL NULL NULL NULL 2 -3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 -SELECT * -FROM t2, t3 -WHERE t3.f1 = ( -SELECT SUM( f2 ) -FROM t4 -WHERE EXISTS ( -SELECT DISTINCT f4 -FROM t1)); -f2 f1 -drop table t1, t2, t3, t4; -# # LP BUG#611690 Crash in select_describe() with nested subqueries # CREATE TABLE t1 ( diff --git a/mysql-test/r/type_year.result b/mysql-test/r/type_year.result index 5a484f3ce3c..20cab45c4f7 100644 --- a/mysql-test/r/type_year.result +++ b/mysql-test/r/type_year.result @@ -359,3 +359,25 @@ total_rows min_value MAX(c1+0) DROP TABLE t1; # End of 5.1 tests +create function y2k() returns int deterministic return 2000; +create table t1 (a year(2), b int); +insert t1 values (0,2000); +select a from t1 where a=2000; +a +00 +select a from t1 where a=1000+1000; +a +00 +select a from t1 where a=(select 2000); +a +00 +select a from t1 where a=(select 2000 from dual where 1); +a +00 +select a from t1 where a=y2k(); +a +00 +select a from t1 where a=b; +a +drop table t1; +drop function y2k; diff --git a/mysql-test/t/subselect4.test b/mysql-test/t/subselect4.test index eee0140815b..371ee016fb8 100644 --- a/mysql-test/t/subselect4.test +++ b/mysql-test/t/subselect4.test @@ -1484,39 +1484,6 @@ WHERE t2.f2 = (SELECT f2 FROM t3 drop table t1,t2,t3,t4; ---echo # ---echo # LP BUG#806943 Second crash with select_describe with nested subqueries in maria-5.3 ---echo # - -CREATE TABLE t1 ( f4 int) ; -INSERT INTO t1 VALUES (0),(0); - -CREATE TABLE t2 ( f2 int) ; - -CREATE TABLE t3 ( f1 int NOT NULL ); - -CREATE TABLE t4 ( f2 int, f3 int) ; -INSERT INTO t4 VALUES (8,0),(3,0); - -EXPLAIN SELECT * -FROM t2, t3 -WHERE t3.f1 = ( - SELECT SUM( f2 ) - FROM t4 - WHERE EXISTS ( - SELECT DISTINCT f4 - FROM t1)); -SELECT * -FROM t2, t3 -WHERE t3.f1 = ( - SELECT SUM( f2 ) - FROM t4 - WHERE EXISTS ( - SELECT DISTINCT f4 - FROM t1)); - -drop table t1, t2, t3, t4; - --echo # --echo # LP BUG#611690 Crash in select_describe() with nested subqueries --echo # diff --git a/mysql-test/t/type_year.test b/mysql-test/t/type_year.test index de38306e88f..53cfd3a7c30 100644 --- a/mysql-test/t/type_year.test +++ b/mysql-test/t/type_year.test @@ -163,3 +163,20 @@ DROP TABLE t1; --echo # --echo End of 5.1 tests +# +# fun with convert_const_to_int +# in some cases 00 is equal to 2000, in others it is not. +# +create function y2k() returns int deterministic return 2000; +create table t1 (a year(2), b int); +insert t1 values (0,2000); +select a from t1 where a=2000; # constant. +select a from t1 where a=1000+1000; # still a constant. +select a from t1 where a=(select 2000); # even this is a constant +select a from t1 where a=(select 2000 from dual where 1); # constant, but "expensive" +select a from t1 where a=y2k(); # constant, but "expensive" +select a from t1 where a=b; # not a constant +drop table t1; +drop function y2k; + + diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index ddb80a3ed81..1d9be2d60ec 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -452,12 +452,17 @@ static bool convert_const_to_int(THD *thd, Item_field *field_item, But we still convert it if it is compared with a Field_year, as YEAR(2) may change the value of an integer when converting it to an integer (say, 0 to 70). + + As a special hack, to avoid reevaluation of stored routines + where 5.2 didn't reevaluate them, we "convert" for BIGINT too. + In 5.5 it isn't necessary, as it caches constant expressions correctly. */ if ((*item)->cmp_type() == INT_RESULT && - field_item->field_type() != MYSQL_TYPE_YEAR) + field_item->field_type() != MYSQL_TYPE_YEAR && + field_item->field_type() != MYSQL_TYPE_LONGLONG) return 1; - if ((*item)->const_item() && !(*item)->is_expensive()) + if ((*item)->const_item()) { TABLE *table= field->table; ulong orig_sql_mode= thd->variables.sql_mode; From e4e85cd2ef404958568f967fd7ec780191cd230e Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Tue, 28 Feb 2012 23:18:52 +0200 Subject: [PATCH 130/135] Fixed lp:925377 "Querying myisam table metadata while 'alter table..enable keys' is running may corrupt the table" Fixed wrong mutex order bug in Aria when flush_log_for_bitmap() was called when table is not yet marked for change. include/my_base.h: Added flag that table is opened only for status mysql-test/r/myisam-big.result: Test case for lp:925377 mysql-test/t/myisam-big.test: Test case for lp:925377 sql/sql_base.cc: If thd->version == 0 (happens only when we are opening a table that is flushed under MYSQL_LOCK_IGNORE_FLUSH), open the table in HA_OPEN_FOR_STATUS mode storage/maria/ma_bitmap.c: Fixed wrong mutex order bug in Aria when flush_log_for_bitmap() was called when table is not yet marked for change. storage/maria/ma_dbug.c: Ignore last_version <= 1 as these are either flushed or only opened for status storage/maria/ma_open.c: Use last_version=1 as a marker that table was opened with HA_OPEN_FOR_STATUS. In this case we just open a new version of the table in read only mode. storage/myisam/mi_create.c: Update prototype storage/myisam/mi_dbug.c: Ignore last_version <= 1 as these are either flushed or only opened for status storage/myisam/mi_open.c: Use last_version=1 as a marker that table was opened with HA_OPEN_FOR_STATUS. If HA_OPEN_FOR_STATUS is used, we will not assert if there is an old not-to-be-used version of the table existing. In this case we just open a new version of the table in read only mode. storage/myisam/myisamdef.h: Updated prototype --- include/my_base.h | 1 + mysql-test/r/myisam-big.result | 40 +++++++++++++++++++++ mysql-test/t/myisam-big.test | 64 ++++++++++++++++++++++++++++++++++ sql/sql_base.cc | 17 ++++++--- storage/maria/ma_bitmap.c | 2 +- storage/maria/ma_dbug.c | 2 +- storage/maria/ma_open.c | 10 ++++-- storage/myisam/mi_create.c | 2 +- storage/myisam/mi_dbug.c | 2 +- storage/myisam/mi_open.c | 17 ++++++--- storage/myisam/myisamdef.h | 2 +- 11 files changed, 143 insertions(+), 16 deletions(-) create mode 100644 mysql-test/r/myisam-big.result create mode 100644 mysql-test/t/myisam-big.test diff --git a/include/my_base.h b/include/my_base.h index 361c0aa0b00..16f8803d2d5 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -54,6 +54,7 @@ /* Internal temp table, used for temporary results */ #define HA_OPEN_INTERNAL_TABLE 512 #define HA_OPEN_MERGE_TABLE 1024 +#define HA_OPEN_FOR_STATUS 2048 /* The following is parameter to ha_rkey() how to use key */ diff --git a/mysql-test/r/myisam-big.result b/mysql-test/r/myisam-big.result new file mode 100644 index 00000000000..95a6e91d766 --- /dev/null +++ b/mysql-test/r/myisam-big.result @@ -0,0 +1,40 @@ +drop table if exists t1,t2; +create table t1 (id int, sometext varchar(100)) engine=myisam; +insert into t1 values (1, "hello"),(2, "hello2"),(4, "hello3"),(4, "hello4"); +create table t2 like t1; +insert into t1 select * from t1; +insert into t2 select * from t1; +insert into t1 select * from t1; +insert into t2 select * from t1; +insert into t1 select * from t1; +insert into t2 select * from t1; +insert into t1 select * from t1; +insert into t2 select * from t1; +insert into t1 select * from t1; +insert into t2 select * from t1; +insert into t1 select * from t1; +insert into t2 select * from t1; +insert into t1 select * from t1; +insert into t2 select * from t1; +insert into t1 select * from t1; +insert into t2 select * from t1; +insert into t1 select * from t1; +insert into t2 select * from t1; +insert into t1 select * from t1; +insert into t2 select * from t1; +insert into t1 select * from t1; +insert into t2 select * from t1; +insert into t1 select * from t1; +insert into t2 select * from t1; +insert into t1 select * from t1; +insert into t2 select * from t1; +insert into t1 select * from t1; +insert into t2 select * from t1; +insert into t1 select * from t1; +select count(*) from t1; +count(*) +131072 +alter table t1 add index (id), add index(sometext), add index(sometext,id); +alter table t1 disable keys; +alter table t1 enable keys; +drop table t1,t2; diff --git a/mysql-test/t/myisam-big.test b/mysql-test/t/myisam-big.test new file mode 100644 index 00000000000..2fec2450ecd --- /dev/null +++ b/mysql-test/t/myisam-big.test @@ -0,0 +1,64 @@ +# +# Test bugs in the MyISAM code that require more space/time +--source include/big_test.inc + +# Initialise +--disable_warnings +drop table if exists t1,t2; +--enable_warnings + +# +# BUG#925377: +# Querying myisam table metadata while 'alter table..enable keys' is +# running may corrupt the table +# +create table t1 (id int, sometext varchar(100)) engine=myisam; +insert into t1 values (1, "hello"),(2, "hello2"),(4, "hello3"),(4, "hello4"); +create table t2 like t1; +insert into t1 select * from t1; +insert into t2 select * from t1; +insert into t1 select * from t1; +insert into t2 select * from t1; +insert into t1 select * from t1; +insert into t2 select * from t1; +insert into t1 select * from t1; +insert into t2 select * from t1; +insert into t1 select * from t1; +insert into t2 select * from t1; +insert into t1 select * from t1; +insert into t2 select * from t1; +insert into t1 select * from t1; +insert into t2 select * from t1; +insert into t1 select * from t1; +insert into t2 select * from t1; +insert into t1 select * from t1; +insert into t2 select * from t1; +insert into t1 select * from t1; +insert into t2 select * from t1; +insert into t1 select * from t1; +insert into t2 select * from t1; +insert into t1 select * from t1; +insert into t2 select * from t1; +insert into t1 select * from t1; +insert into t2 select * from t1; +insert into t1 select * from t1; +insert into t2 select * from t1; +insert into t1 select * from t1; +select count(*) from t1; +connect (con2,localhost,root,,); +connection con2; +alter table t1 add index (id), add index(sometext), add index(sometext,id); +alter table t1 disable keys; +send alter table t1 enable keys; +connection default; +--sleep 1 +--disable_query_log +--disable_result_log +show table status like 't1'; +--enable_query_log +--enable_result_log +connection con2; +reap; +disconnect con2; +connection default; +drop table t1,t2; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 95a149741de..877c3dfa82e 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2985,7 +2985,9 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, } error= open_unireg_entry(thd, table, table_list, alias, key, key_length, - mem_root, (flags & OPEN_VIEW_NO_PARSE)); + mem_root, + (flags & (OPEN_VIEW_NO_PARSE | + MYSQL_LOCK_IGNORE_FLUSH))); if (error > 0) { my_free((uchar*)table, MYF(0)); @@ -4074,8 +4076,11 @@ retry: HA_GET_INDEX | HA_TRY_READ_ONLY), READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD | (flags & OPEN_VIEW_NO_PARSE), - thd->open_options, entry, table_list, - mem_root); + thd->open_options | + (thd->version == 0 && + (flags & MYSQL_LOCK_IGNORE_FLUSH) ? + HA_OPEN_FOR_STATUS : 0), + entry, table_list, mem_root); if (error) goto err; /* TODO: Don't free this */ @@ -4113,7 +4118,11 @@ retry: HA_TRY_READ_ONLY), (READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD), - thd->open_options, entry, FALSE))) + thd->open_options | + (thd->version == 0 && + (flags & MYSQL_LOCK_IGNORE_FLUSH) ? + HA_OPEN_FOR_STATUS : 0), + entry, FALSE))) { if (error == 7) // Table def changed { diff --git a/storage/maria/ma_bitmap.c b/storage/maria/ma_bitmap.c index 25ab5c6531e..f5cfa1ce23f 100644 --- a/storage/maria/ma_bitmap.c +++ b/storage/maria/ma_bitmap.c @@ -368,7 +368,7 @@ static inline void _ma_bitmap_mark_file_changed(MARIA_SHARE *share, if (flush_translog && share->now_transactional) (void) translog_flush(share->state.logrec_file_id); - _ma_mark_file_changed(share); + _ma_mark_file_changed_now(share); pthread_mutex_lock(&share->bitmap.bitmap_lock); /* purecov: end */ } diff --git a/storage/maria/ma_dbug.c b/storage/maria/ma_dbug.c index af90a108e2a..8391f1a9d9d 100644 --- a/storage/maria/ma_dbug.c +++ b/storage/maria/ma_dbug.c @@ -186,7 +186,7 @@ my_bool _ma_check_table_is_closed(const char *name, const char *where) MARIA_SHARE *share= info->s; if (!strcmp(share->unique_file_name.str, filename)) { - if (share->last_version) + if (share->last_version > 1) { fprintf(stderr,"Warning: Table: %s is open on %s\n", name,where); DBUG_PRINT("warning",("Table: %s is open on %s", name,where)); diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c index 0b5ee2feb85..5ff4c02a2b5 100644 --- a/storage/maria/ma_open.c +++ b/storage/maria/ma_open.c @@ -62,7 +62,8 @@ MARIA_HA *_ma_test_if_reopen(const char *filename) { MARIA_HA *info=(MARIA_HA*) pos->data; MARIA_SHARE *share= info->s; - if (!strcmp(share->unique_file_name.str,filename) && share->last_version) + if (!strcmp(share->unique_file_name.str,filename) && + share->last_version > 1) return info; } return 0; @@ -840,7 +841,12 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags) share->base.key_parts=key_parts; share->base.all_key_parts=key_parts+unique_key_parts; if (!(share->last_version=share->state.version)) - share->last_version=1; /* Safety */ + share->last_version= 2; /* Safety */ + if (open_flags & HA_OPEN_FOR_STATUS) + { + share->last_version= 1; /* Not reusable version */ + share->options|= HA_OPTION_READ_ONLY_DATA; + } share->rec_reflength=share->base.rec_reflength; /* May be changed */ share->base.margin_key_file_length=(share->base.max_key_file_length - (keys ? MARIA_INDEX_BLOCK_MARGIN * diff --git a/storage/myisam/mi_create.c b/storage/myisam/mi_create.c index 21b683d0d4d..919f0f3e040 100644 --- a/storage/myisam/mi_create.c +++ b/storage/myisam/mi_create.c @@ -643,7 +643,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, NOTE: The filename is compared against unique_file_name of every open table. Hence we need a real path here. */ - if (test_if_reopen(filename)) + if (test_if_reopen(filename, 1)) { my_printf_error(0, "MyISAM table '%s' is in use " "(most likely by a MERGE table). Try FLUSH TABLES.", diff --git a/storage/myisam/mi_dbug.c b/storage/myisam/mi_dbug.c index 61c52b454a0..559fa8710a0 100644 --- a/storage/myisam/mi_dbug.c +++ b/storage/myisam/mi_dbug.c @@ -183,7 +183,7 @@ my_bool check_table_is_closed(const char *name, const char *where) MYISAM_SHARE *share=info->s; if (!strcmp(share->unique_file_name,filename)) { - if (share->last_version) + if (share->last_version > 1) { fprintf(stderr,"Warning: Table: %s is open on %s\n", name,where); DBUG_PRINT("warning",("Table: %s is open on %s", name,where)); diff --git a/storage/myisam/mi_open.c b/storage/myisam/mi_open.c index 744059d941c..46ec10c064e 100644 --- a/storage/myisam/mi_open.c +++ b/storage/myisam/mi_open.c @@ -52,7 +52,8 @@ if (pos > end_pos) \ ** In MySQL the server will handle version issues. ******************************************************************************/ -MI_INFO *test_if_reopen(char *filename) +MI_INFO *test_if_reopen(char *filename, + my_bool ignore_last_version __attribute__((unused))) { LIST *pos; @@ -61,8 +62,8 @@ MI_INFO *test_if_reopen(char *filename) MI_INFO *info=(MI_INFO*) pos->data; MYISAM_SHARE *share=info->s; DBUG_ASSERT(strcmp(share->unique_file_name,filename) || - share->last_version); - if (!strcmp(share->unique_file_name,filename) && share->last_version) + share->last_version > 1 || ignore_last_version); + if (!strcmp(share->unique_file_name,filename) && share->last_version > 1) return info; } return 0; @@ -109,7 +110,8 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) } pthread_mutex_lock(&THR_LOCK_myisam); - if (!(old_info=test_if_reopen(name_buff))) + if (!(old_info=test_if_reopen(name_buff, + test(open_flags & HA_OPEN_FOR_STATUS)))) { share= &share_buff; bzero((uchar*) &share_buff,sizeof(share_buff)); @@ -511,7 +513,12 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) share->base.key_parts=key_parts; share->base.all_key_parts=key_parts+unique_key_parts; if (!(share->last_version=share->state.version)) - share->last_version=1; /* Safety */ + share->last_version= 2; /* Safety */ + if (open_flags & HA_OPEN_FOR_STATUS) + { + share->last_version= 1; /* Not reusable version */ + share->options|= HA_OPTION_READ_ONLY_DATA; + } share->rec_reflength=share->base.rec_reflength; /* May be changed */ share->base.margin_key_file_length=(share->base.max_key_file_length - (keys ? MI_INDEX_BLOCK_MARGIN * diff --git a/storage/myisam/myisamdef.h b/storage/myisam/myisamdef.h index 617ad5e8382..58d69afbea8 100644 --- a/storage/myisam/myisamdef.h +++ b/storage/myisam/myisamdef.h @@ -726,7 +726,7 @@ my_bool mi_check_status(void *param); void mi_fix_status(MI_INFO *org_table, MI_INFO *new_table); void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows); -extern MI_INFO *test_if_reopen(char *filename); +extern MI_INFO *test_if_reopen(char *filename, my_bool ignore_last_version); my_bool check_table_is_closed(const char *name, const char *where); int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, const char *orn_name, File file_to_dup); From 000deedf3b708681951af6a0629af89c1f5ee85a Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Wed, 29 Feb 2012 23:28:16 -0800 Subject: [PATCH 131/135] Fixed LP bug #943543. This bug appeared after the patch for bug 939009 that in the function merge_key_fields forgot to reset a proper value for the val field in the result of the merge operation of the key field created for a regular key access and the key field created to look for a NULL key. Adjusted the results of the test case for bug 939009 that actually were incorrect. --- mysql-test/r/join_outer.result | 84 ++++++++++++++++++++++++++++ mysql-test/r/join_outer_jcl6.result | 84 ++++++++++++++++++++++++++++ mysql-test/r/subselect_mat.result | 5 +- mysql-test/r/subselect_sj_mat.result | 5 +- mysql-test/t/join_outer.test | 61 ++++++++++++++++++++ sql/sql_select.cc | 12 ++-- 6 files changed, 241 insertions(+), 10 deletions(-) diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result index 60defea291b..5624d9467af 100644 --- a/mysql-test/r/join_outer.result +++ b/mysql-test/r/join_outer.result @@ -1656,4 +1656,88 @@ b b a b DEALLOCATE PREPARE stmt; SET SESSION join_cache_level=default; DROP TABLE t1,t2,t3; +# +# LP bug #943543: LEFT JOIN converted to JOIN with +# ORed IS NULL(primary key) in WHERE clause +# +CREATE TABLE t1 ( +a int, b int NOT NULL, pk int NOT NULL, +PRIMARY KEY (pk), INDEX idx(b) +); +INSERT INTO t1 VALUES +(NULL,1,1), (6,2,2), (5,3,3), (NULL,4,4), +(1,9,6), (8,5,7), (NULL,8,8), (8,1,5); +CREATE TABLE t2 (pk int PRIMARY KEY); +INSERT INTO t2 VALUES (3), (8), (5); +EXPLAIN EXTENDED +SELECT t1.pk FROM t2 JOIN t1 ON t2.pk = t1.a +WHERE t1.b BETWEEN 5 AND 6 AND t1.pk IS NULL OR t1.pk = 5 +ORDER BY t1.pk; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 100.00 +1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 100.00 Using index +Warnings: +Note 1003 select 5 AS `pk` from `test`.`t2` join `test`.`t1` where (1) order by 5 +SELECT t1.pk FROM t2 JOIN t1 ON t2.pk = t1.a +WHERE t1.b BETWEEN 5 AND 6 AND t1.pk IS NULL OR t1.pk = 5 +ORDER BY t1.pk; +pk +5 +EXPLAIN EXTENDED +SELECT t1.pk FROM t2 LEFT JOIN t1 ON t2.pk = t1.a +WHERE t1.b BETWEEN 5 AND 6 AND t1.pk IS NULL OR t1.pk = 5 +ORDER BY t1.pk; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 const PRIMARY,idx PRIMARY 4 const 1 100.00 +1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 100.00 Using index +Warnings: +Note 1003 select 5 AS `pk` from `test`.`t2` join `test`.`t1` where ((((1 between 5 and 6) and isnull(5)) or 1)) order by 5 +SELECT t1.pk FROM t2 LEFT JOIN t1 ON t2.pk = t1.a +WHERE t1.b BETWEEN 5 AND 6 AND t1.pk IS NULL OR t1.pk = 5 +ORDER BY t1.pk; +pk +5 +DROP TABLE t2; +CREATE TABLE t2 (c int, d int, KEY (c)); +INSERT INTO t2 VALUES +(3,30), (8,88), (5,50), (8,81), +(4,40), (9,90), (7,70), (9,90), +(13,130), (18,188), (15,150), (18,181), +(14,140), (19,190), (17,170), (19,190); +INSERT INTO t1 VALUES (8,5,9); +EXPLAIN EXTENDED +SELECT t1.b, t2.c, t2.d FROM t2 JOIN t1 ON t2.c = t1.a +WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5 +ORDER BY t1.b; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ref idx idx 4 const 2 100.00 Using where +1 SIMPLE t2 ref c c 5 test.t1.a 2 100.00 +Warnings: +Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2` join `test`.`t1` where ((`test`.`t2`.`c` = `test`.`t1`.`a`) and (`test`.`t1`.`b` = 5)) order by `test`.`t1`.`b` +SELECT t1.b, t2.c, t2.d FROM t2 JOIN t1 ON t2.c = t1.a +WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5 +ORDER BY t1.b; +b c d +5 8 88 +5 8 81 +5 8 88 +5 8 81 +EXPLAIN EXTENDED +SELECT t1.b, t2.c, t2.d FROM t2 LEFT JOIN t1 ON t2.c = t1.a +WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5 +ORDER BY t1.b; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ref PRIMARY,idx idx 4 const 2 100.00 Using where; Using filesort +1 SIMPLE t2 ref c c 5 test.t1.a 2 100.00 +Warnings: +Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2` join `test`.`t1` where ((`test`.`t2`.`c` = `test`.`t1`.`a`) and (((`test`.`t1`.`pk` between 5 and 6) and isnull(`test`.`t1`.`b`)) or (`test`.`t1`.`b` = 5))) order by `test`.`t1`.`b` +SELECT t1.b, t2.c, t2.d FROM t2 LEFT JOIN t1 ON t2.c = t1.a +WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5 +ORDER BY t1.b; +b c d +5 8 88 +5 8 81 +5 8 88 +5 8 81 +DROP TABLE t1,t2; SET optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/r/join_outer_jcl6.result b/mysql-test/r/join_outer_jcl6.result index 767d0544f1b..d80b838e4e7 100644 --- a/mysql-test/r/join_outer_jcl6.result +++ b/mysql-test/r/join_outer_jcl6.result @@ -1667,6 +1667,90 @@ b b a b DEALLOCATE PREPARE stmt; SET SESSION join_cache_level=default; DROP TABLE t1,t2,t3; +# +# LP bug #943543: LEFT JOIN converted to JOIN with +# ORed IS NULL(primary key) in WHERE clause +# +CREATE TABLE t1 ( +a int, b int NOT NULL, pk int NOT NULL, +PRIMARY KEY (pk), INDEX idx(b) +); +INSERT INTO t1 VALUES +(NULL,1,1), (6,2,2), (5,3,3), (NULL,4,4), +(1,9,6), (8,5,7), (NULL,8,8), (8,1,5); +CREATE TABLE t2 (pk int PRIMARY KEY); +INSERT INTO t2 VALUES (3), (8), (5); +EXPLAIN EXTENDED +SELECT t1.pk FROM t2 JOIN t1 ON t2.pk = t1.a +WHERE t1.b BETWEEN 5 AND 6 AND t1.pk IS NULL OR t1.pk = 5 +ORDER BY t1.pk; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 100.00 +1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 100.00 Using index +Warnings: +Note 1003 select 5 AS `pk` from `test`.`t2` join `test`.`t1` where (1) order by 5 +SELECT t1.pk FROM t2 JOIN t1 ON t2.pk = t1.a +WHERE t1.b BETWEEN 5 AND 6 AND t1.pk IS NULL OR t1.pk = 5 +ORDER BY t1.pk; +pk +5 +EXPLAIN EXTENDED +SELECT t1.pk FROM t2 LEFT JOIN t1 ON t2.pk = t1.a +WHERE t1.b BETWEEN 5 AND 6 AND t1.pk IS NULL OR t1.pk = 5 +ORDER BY t1.pk; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 const PRIMARY,idx PRIMARY 4 const 1 100.00 +1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 100.00 Using index +Warnings: +Note 1003 select 5 AS `pk` from `test`.`t2` join `test`.`t1` where ((((1 between 5 and 6) and isnull(5)) or 1)) order by 5 +SELECT t1.pk FROM t2 LEFT JOIN t1 ON t2.pk = t1.a +WHERE t1.b BETWEEN 5 AND 6 AND t1.pk IS NULL OR t1.pk = 5 +ORDER BY t1.pk; +pk +5 +DROP TABLE t2; +CREATE TABLE t2 (c int, d int, KEY (c)); +INSERT INTO t2 VALUES +(3,30), (8,88), (5,50), (8,81), +(4,40), (9,90), (7,70), (9,90), +(13,130), (18,188), (15,150), (18,181), +(14,140), (19,190), (17,170), (19,190); +INSERT INTO t1 VALUES (8,5,9); +EXPLAIN EXTENDED +SELECT t1.b, t2.c, t2.d FROM t2 JOIN t1 ON t2.c = t1.a +WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5 +ORDER BY t1.b; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ref idx idx 4 const 2 100.00 Using where +1 SIMPLE t2 ref c c 5 test.t1.a 2 100.00 +Warnings: +Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2` join `test`.`t1` where ((`test`.`t2`.`c` = `test`.`t1`.`a`) and (`test`.`t1`.`b` = 5)) order by `test`.`t1`.`b` +SELECT t1.b, t2.c, t2.d FROM t2 JOIN t1 ON t2.c = t1.a +WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5 +ORDER BY t1.b; +b c d +5 8 88 +5 8 81 +5 8 88 +5 8 81 +EXPLAIN EXTENDED +SELECT t1.b, t2.c, t2.d FROM t2 LEFT JOIN t1 ON t2.c = t1.a +WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5 +ORDER BY t1.b; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ref PRIMARY,idx idx 4 const 2 100.00 Using where; Using filesort +1 SIMPLE t2 ref c c 5 test.t1.a 2 100.00 +Warnings: +Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2` join `test`.`t1` where ((`test`.`t2`.`c` = `test`.`t1`.`a`) and (((`test`.`t1`.`pk` between 5 and 6) and isnull(`test`.`t1`.`b`)) or (`test`.`t1`.`b` = 5))) order by `test`.`t1`.`b` +SELECT t1.b, t2.c, t2.d FROM t2 LEFT JOIN t1 ON t2.c = t1.a +WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5 +ORDER BY t1.b; +b c d +5 8 88 +5 8 81 +5 8 88 +5 8 81 +DROP TABLE t1,t2; SET optimizer_switch=@save_optimizer_switch; set join_cache_level=default; show variables like 'join_cache_level'; diff --git a/mysql-test/r/subselect_mat.result b/mysql-test/r/subselect_mat.result index b7cc7e8a3ed..97463447e1d 100644 --- a/mysql-test/r/subselect_mat.result +++ b/mysql-test/r/subselect_mat.result @@ -1892,7 +1892,7 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE a IN (SELECT MAX(c) FROM t2) AND b=7 AND (a IS NULL OR a=b); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY const distinct_key distinct_key 4 const 1 100.00 Using where +1 PRIMARY const distinct_key distinct_key 4 const 1 100.00 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00 Warnings: @@ -1900,11 +1900,12 @@ Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from const distinct_key distinct_key 4 const 1 Using where +1 PRIMARY const distinct_key distinct_key 4 const 1 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join) 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where SELECT * FROM t1 diff --git a/mysql-test/r/subselect_sj_mat.result b/mysql-test/r/subselect_sj_mat.result index 9a238eaaccd..db5a27a5d84 100644 --- a/mysql-test/r/subselect_sj_mat.result +++ b/mysql-test/r/subselect_sj_mat.result @@ -1930,7 +1930,7 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE a IN (SELECT MAX(c) FROM t2) AND b=7 AND (a IS NULL OR a=b); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY const distinct_key distinct_key 4 const 1 100.00 Using where +1 PRIMARY const distinct_key distinct_key 4 const 1 100.00 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00 Warnings: @@ -1938,11 +1938,12 @@ Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from const distinct_key distinct_key 4 const 1 Using where +1 PRIMARY const distinct_key distinct_key 4 const 1 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join) 2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where SELECT * FROM t1 diff --git a/mysql-test/t/join_outer.test b/mysql-test/t/join_outer.test index 04816402205..3fae21ac738 100644 --- a/mysql-test/t/join_outer.test +++ b/mysql-test/t/join_outer.test @@ -1221,4 +1221,65 @@ SET SESSION join_cache_level=default; DROP TABLE t1,t2,t3; +--echo # +--echo # LP bug #943543: LEFT JOIN converted to JOIN with +--echo # ORed IS NULL(primary key) in WHERE clause +--echo # + +CREATE TABLE t1 ( + a int, b int NOT NULL, pk int NOT NULL, + PRIMARY KEY (pk), INDEX idx(b) +); +INSERT INTO t1 VALUES + (NULL,1,1), (6,2,2), (5,3,3), (NULL,4,4), + (1,9,6), (8,5,7), (NULL,8,8), (8,1,5); + +CREATE TABLE t2 (pk int PRIMARY KEY); +INSERT INTO t2 VALUES (3), (8), (5); + +EXPLAIN EXTENDED +SELECT t1.pk FROM t2 JOIN t1 ON t2.pk = t1.a + WHERE t1.b BETWEEN 5 AND 6 AND t1.pk IS NULL OR t1.pk = 5 +ORDER BY t1.pk; +SELECT t1.pk FROM t2 JOIN t1 ON t2.pk = t1.a + WHERE t1.b BETWEEN 5 AND 6 AND t1.pk IS NULL OR t1.pk = 5 +ORDER BY t1.pk; + +EXPLAIN EXTENDED +SELECT t1.pk FROM t2 LEFT JOIN t1 ON t2.pk = t1.a + WHERE t1.b BETWEEN 5 AND 6 AND t1.pk IS NULL OR t1.pk = 5 +ORDER BY t1.pk; +SELECT t1.pk FROM t2 LEFT JOIN t1 ON t2.pk = t1.a + WHERE t1.b BETWEEN 5 AND 6 AND t1.pk IS NULL OR t1.pk = 5 +ORDER BY t1.pk; + +DROP TABLE t2; + +CREATE TABLE t2 (c int, d int, KEY (c)); +INSERT INTO t2 VALUES + (3,30), (8,88), (5,50), (8,81), + (4,40), (9,90), (7,70), (9,90), + (13,130), (18,188), (15,150), (18,181), + (14,140), (19,190), (17,170), (19,190); + +INSERT INTO t1 VALUES (8,5,9); + +EXPLAIN EXTENDED +SELECT t1.b, t2.c, t2.d FROM t2 JOIN t1 ON t2.c = t1.a + WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5 +ORDER BY t1.b; +SELECT t1.b, t2.c, t2.d FROM t2 JOIN t1 ON t2.c = t1.a + WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5 +ORDER BY t1.b; + +EXPLAIN EXTENDED +SELECT t1.b, t2.c, t2.d FROM t2 LEFT JOIN t1 ON t2.c = t1.a + WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5 +ORDER BY t1.b; +SELECT t1.b, t2.c, t2.d FROM t2 LEFT JOIN t1 ON t2.c = t1.a + WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5 +ORDER BY t1.b; + +DROP TABLE t1,t2; + SET optimizer_switch=@save_optimizer_switch; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index fcbde9e27d3..c14194d1731 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3781,15 +3781,15 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end, if (old->field->maybe_null()) { old->optimize= KEY_OPTIMIZE_REF_OR_NULL; - /* - Remember the NOT NULL value unless the value does not depend - on other tables. - */ - if (!old->val->used_tables() && old->val->is_null()) - old->val= new_fields->val; /* The referred expression can be NULL: */ old->null_rejecting= 0; } + /* + Remember the NOT NULL value unless the value does not depend + on other tables. + */ + if (!old->val->used_tables() && old->val->is_null()) + old->val= new_fields->val; } else { From 6f3c39a0573e7d6777e4288d2ebe5b770733d4ba Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Sun, 4 Mar 2012 22:38:17 -0800 Subject: [PATCH 132/135] Fixed LP bug #944782. This bug in the function JOIN::drop_unused_derived_keys() could leave the internal structures for a materialized derived table in an inconsistent state. This led to a not quite correct EXPLAIN output when no additional key had been created to access the table. It also may lead to more serious consequences: so, the test case added with this fix caused a crash in mariadb-5.5.20. --- mysql-test/r/derived_view.result | 38 +++++++++++++++++++++++++++++--- mysql-test/r/join_cache.result | 2 +- mysql-test/t/derived_view.test | 34 ++++++++++++++++++++++++++++ sql/sql_select.cc | 9 ++++++-- 4 files changed, 77 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/derived_view.result b/mysql-test/r/derived_view.result index 2f0e0bd371b..49e1422c3d4 100644 --- a/mysql-test/r/derived_view.result +++ b/mysql-test/r/derived_view.result @@ -420,7 +420,7 @@ join (select * from (select * from t1 where f1 < 7 group by f1) tt where f1 > 2) z on x.f1 = z.f1; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE ALL key0 NULL NULL NULL 11 100.00 Using where +1 SIMPLE ALL NULL NULL NULL NULL 11 100.00 Using where 1 SIMPLE ref key0 key0 5 tt.f1 2 100.00 5 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort 3 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort @@ -478,7 +478,7 @@ join (select * from t1 where f1 < 7 group by f1) tt where f1 > 2 group by f1) z on x.f1 = z.f1; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY ALL key0 NULL NULL NULL 11 100.00 Using where +1 PRIMARY ALL NULL NULL NULL NULL 11 100.00 Using where 1 PRIMARY ref key0 key0 5 x.f1 2 100.00 4 DERIVED ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort 5 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort @@ -1585,7 +1585,7 @@ a EXPLAIN SELECT v1.a FROM v1,v2 WHERE v2.b = v1.b ORDER BY 1; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL key0 NULL NULL NULL 3 Using where; Using filesort +1 PRIMARY ALL NULL NULL NULL NULL 3 Using where; Using filesort 1 PRIMARY ref key0 key0 5 v1.b 2 3 DERIVED t2 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort 2 DERIVED t1 ALL NULL NULL NULL NULL 3 Using temporary; Using filesort @@ -1929,5 +1929,37 @@ x y drop table t1,t2,t3; set SESSION optimizer_switch= @save_optimizer_switch; +# +# LP BUG#944782: derived table from an information schema table +# +SET @save_optimizer_switch=@@optimizer_switch; +SET SESSION optimizer_switch='derived_merge=on'; +SET SESSION optimizer_switch='derived_with_keys=on'; +CREATE TABLE t1 (c1 int PRIMARY KEY, c2 char(5)); +EXPLAIN +SELECT COUNT(*) > 0 +FROM INFORMATION_SCHEMA.COLUMNS +INNER JOIN +(SELECT TABLE_SCHEMA, +GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX ASC) AS COL_NAMES +FROM INFORMATION_SCHEMA.STATISTICS +GROUP BY TABLE_SCHEMA) AS UNIQUES +ON ( COLUMNS.TABLE_SCHEMA = UNIQUES.TABLE_SCHEMA); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY COLUMNS ALL NULL NULL NULL NULL NULL Open_frm_only; Scanned all databases +1 PRIMARY ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) +2 DERIVED STATISTICS ALL NULL NULL NULL NULL NULL Open_frm_only; Scanned all databases; Using filesort +SELECT COUNT(*) > 0 +FROM INFORMATION_SCHEMA.COLUMNS +INNER JOIN +(SELECT TABLE_SCHEMA, +GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX ASC) AS COL_NAMES +FROM INFORMATION_SCHEMA.STATISTICS +GROUP BY TABLE_SCHEMA) AS UNIQUES +ON ( COLUMNS.TABLE_SCHEMA = UNIQUES.TABLE_SCHEMA); +COUNT(*) > 0 +1 +DROP TABLE t1; +set SESSION optimizer_switch= @save_optimizer_switch; set optimizer_switch=@exit_optimizer_switch; set join_cache_level=@exit_join_cache_level; diff --git a/mysql-test/r/join_cache.result b/mysql-test/r/join_cache.result index 9918ad2380d..f8db2c8cf72 100644 --- a/mysql-test/r/join_cache.result +++ b/mysql-test/r/join_cache.result @@ -5151,7 +5151,7 @@ EXPLAIN SELECT * FROM (SELECT DISTINCT * FROM t1) t WHERE t.a IN (SELECT t2.a FROM t2); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL key0 NULL NULL NULL 3 +1 PRIMARY ALL NULL NULL NULL NULL 3 1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) 2 DERIVED t1 ALL NULL NULL NULL NULL 3 Using temporary SELECT * FROM (SELECT DISTINCT * FROM t1) t diff --git a/mysql-test/t/derived_view.test b/mysql-test/t/derived_view.test index 95412426aa0..9660dd1e5f5 100644 --- a/mysql-test/t/derived_view.test +++ b/mysql-test/t/derived_view.test @@ -1313,6 +1313,40 @@ drop table t1,t2,t3; set SESSION optimizer_switch= @save_optimizer_switch; +--echo # +--echo # LP BUG#944782: derived table from an information schema table +--echo # + +SET @save_optimizer_switch=@@optimizer_switch; +SET SESSION optimizer_switch='derived_merge=on'; +SET SESSION optimizer_switch='derived_with_keys=on'; + +CREATE TABLE t1 (c1 int PRIMARY KEY, c2 char(5)); + +EXPLAIN +SELECT COUNT(*) > 0 + FROM INFORMATION_SCHEMA.COLUMNS + INNER JOIN + (SELECT TABLE_SCHEMA, + GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX ASC) AS COL_NAMES + FROM INFORMATION_SCHEMA.STATISTICS + GROUP BY TABLE_SCHEMA) AS UNIQUES + ON ( COLUMNS.TABLE_SCHEMA = UNIQUES.TABLE_SCHEMA); + +# this query crashed in mariadb-5.5.20 +SELECT COUNT(*) > 0 + FROM INFORMATION_SCHEMA.COLUMNS + INNER JOIN + (SELECT TABLE_SCHEMA, + GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX ASC) AS COL_NAMES + FROM INFORMATION_SCHEMA.STATISTICS + GROUP BY TABLE_SCHEMA) AS UNIQUES + ON ( COLUMNS.TABLE_SCHEMA = UNIQUES.TABLE_SCHEMA); + +DROP TABLE t1; + +set SESSION optimizer_switch= @save_optimizer_switch; + # The following command must be the last one the file set optimizer_switch=@exit_optimizer_switch; set join_cache_level=@exit_join_cache_level; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index c14194d1731..55fbfae77b7 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -8712,8 +8712,13 @@ void JOIN::drop_unused_derived_keys() continue; if (table->max_keys > 1) table->use_index(tab->ref.key); - if (table->s->keys && tab->ref.key >= 0) - tab->ref.key= 0; + if (table->s->keys) + { + if (tab->ref.key >= 0) + tab->ref.key= 0; + else + table->s->keys= 0; + } tab->keys= (key_map) (table->s->keys ? 1 : 0); } } From 8a5940c4773d3dc7e928e8d9300450a6b5d3b957 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 5 Mar 2012 15:48:12 +0200 Subject: [PATCH 133/135] Fix for LP BUG#944504 Problem is that subquery execution can't be called during prepare/optimize phase. Also small fix for subquery test suite. --- mysql-test/r/ctype_recoding.result | 16 ++++++++++++++++ mysql-test/r/subselect.result | 1 + mysql-test/r/subselect_no_mat.result | 1 + mysql-test/r/subselect_no_opts.result | 1 + mysql-test/r/subselect_no_scache.result | 1 + mysql-test/r/subselect_no_semijoin.result | 1 + mysql-test/t/ctype_recoding.test | 18 ++++++++++++++++++ mysql-test/t/subselect.test | 3 ++- sql/item_strfunc.h | 2 +- 9 files changed, 42 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/ctype_recoding.result b/mysql-test/r/ctype_recoding.result index ee95812c03e..f096620daf0 100644 --- a/mysql-test/r/ctype_recoding.result +++ b/mysql-test/r/ctype_recoding.result @@ -267,3 +267,19 @@ drop table t1; create table t1(a char character set latin1 default _cp1251 0xFF); ERROR 42000: Invalid default value for 'a' End of 4.1 tests +SET CHARACTER SET DEFAULT; +# +# LP BUG#944504 Item_func_conv_charset tries to execute subquery constant +# +SET optimizer_switch = 'in_to_exists=on'; +SET character_set_connection = utf8; +CREATE TABLE t1 ( a VARCHAR(1) ); +INSERT INTO t1 VALUES ('m'),('n'); +CREATE VIEW v1 AS SELECT 'w' ; +SELECT * FROM t1 WHERE a < ALL ( SELECT * FROM v1 ); +ERROR HY000: Illegal mix of collations (utf8_general_ci,COERCIBLE) and (latin1_swedish_ci,IMPLICIT) for operation '<=' +drop view v1; +drop table t1; +SET character_set_connection = default; +SET optimizer_switch= default; +#End of 5.3 tests diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 327cb5b2563..4eec1729fe3 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -5994,6 +5994,7 @@ SELECT ( SELECT b FROM t2 WHERE b = a OR rand() * 0) FROM t1; 1 NULL drop table t1,t2,t3; +set optimizer_switch=@subselect_tmp; # # LP BUG#905353 Wrong non-empty result with a constant table, # aggregate function in subquery, MyISAM or Aria diff --git a/mysql-test/r/subselect_no_mat.result b/mysql-test/r/subselect_no_mat.result index bcd08b70517..0962894bc19 100644 --- a/mysql-test/r/subselect_no_mat.result +++ b/mysql-test/r/subselect_no_mat.result @@ -5993,6 +5993,7 @@ SELECT ( SELECT b FROM t2 WHERE b = a OR rand() * 0) FROM t1; 1 NULL drop table t1,t2,t3; +set optimizer_switch=@subselect_tmp; # # LP BUG#905353 Wrong non-empty result with a constant table, # aggregate function in subquery, MyISAM or Aria diff --git a/mysql-test/r/subselect_no_opts.result b/mysql-test/r/subselect_no_opts.result index a493722fabe..6bd5e0e4ddd 100644 --- a/mysql-test/r/subselect_no_opts.result +++ b/mysql-test/r/subselect_no_opts.result @@ -5989,6 +5989,7 @@ SELECT ( SELECT b FROM t2 WHERE b = a OR rand() * 0) FROM t1; 1 NULL drop table t1,t2,t3; +set optimizer_switch=@subselect_tmp; # # LP BUG#905353 Wrong non-empty result with a constant table, # aggregate function in subquery, MyISAM or Aria diff --git a/mysql-test/r/subselect_no_scache.result b/mysql-test/r/subselect_no_scache.result index 1167e9483c9..d97b95ad314 100644 --- a/mysql-test/r/subselect_no_scache.result +++ b/mysql-test/r/subselect_no_scache.result @@ -6000,6 +6000,7 @@ SELECT ( SELECT b FROM t2 WHERE b = a OR rand() * 0) FROM t1; 1 NULL drop table t1,t2,t3; +set optimizer_switch=@subselect_tmp; # # LP BUG#905353 Wrong non-empty result with a constant table, # aggregate function in subquery, MyISAM or Aria diff --git a/mysql-test/r/subselect_no_semijoin.result b/mysql-test/r/subselect_no_semijoin.result index 782aba08d26..5c8ccfdbda0 100644 --- a/mysql-test/r/subselect_no_semijoin.result +++ b/mysql-test/r/subselect_no_semijoin.result @@ -5989,6 +5989,7 @@ SELECT ( SELECT b FROM t2 WHERE b = a OR rand() * 0) FROM t1; 1 NULL drop table t1,t2,t3; +set optimizer_switch=@subselect_tmp; # # LP BUG#905353 Wrong non-empty result with a constant table, # aggregate function in subquery, MyISAM or Aria diff --git a/mysql-test/t/ctype_recoding.test b/mysql-test/t/ctype_recoding.test index 1f55aea414a..ee07ef24def 100644 --- a/mysql-test/t/ctype_recoding.test +++ b/mysql-test/t/ctype_recoding.test @@ -210,3 +210,21 @@ drop table t1; create table t1(a char character set latin1 default _cp1251 0xFF); --echo End of 4.1 tests + +SET CHARACTER SET DEFAULT; +--echo # +--echo # LP BUG#944504 Item_func_conv_charset tries to execute subquery constant +--echo # +SET optimizer_switch = 'in_to_exists=on'; +SET character_set_connection = utf8; +CREATE TABLE t1 ( a VARCHAR(1) ); +INSERT INTO t1 VALUES ('m'),('n'); +CREATE VIEW v1 AS SELECT 'w' ; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT * FROM t1 WHERE a < ALL ( SELECT * FROM v1 ); +drop view v1; +drop table t1; +SET character_set_connection = default; +SET optimizer_switch= default; + +--echo #End of 5.3 tests diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index e9735dae79f..6e2b2ef86ae 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -5075,8 +5075,8 @@ SELECT ( SELECT b FROM t2 WHERE b = a OR b * 0) FROM t1; # example with "random" SELECT ( SELECT b FROM t2 WHERE b = a OR rand() * 0) FROM t1; - drop table t1,t2,t3; +set optimizer_switch=@subselect_tmp; --echo # --echo # LP BUG#905353 Wrong non-empty result with a constant table, @@ -5090,5 +5090,6 @@ SELECT a FROM t1 WHERE ( SELECT MIN(a) = 100 ); drop table t1; + --echo # return optimizer switch changed in the beginning of this test set optimizer_switch=@subselect_tmp; diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index c4ce09112bc..fc4e888e6ea 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -747,7 +747,7 @@ public: { DBUG_ASSERT(args[0]->fixed); conv_charset= cs; - if (cache_if_const && args[0]->const_item()) + if (cache_if_const && args[0]->const_item() && !args[0]->with_subselect) { uint errors= 0; String tmp, *str= args[0]->val_str(&tmp); From c437506826630d962bafd1e9468eeb6147d03708 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Mon, 5 Mar 2012 21:59:00 +0200 Subject: [PATCH 134/135] Ensure that we mark all processed tables as 'properly closed'. This is needed as last log entry may be a DDL that is not processed and then a table may be left in 'not properly closed state' even if information is correct in it. --- storage/maria/ma_recovery.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/storage/maria/ma_recovery.c b/storage/maria/ma_recovery.c index 37def17c4c3..77091c4747b 100644 --- a/storage/maria/ma_recovery.c +++ b/storage/maria/ma_recovery.c @@ -665,11 +665,13 @@ prototype_redo_exec_hook_dummy(INCOMPLETE_GROUP) prototype_redo_exec_hook(INCOMPLETE_LOG) { MARIA_HA *info; + if (skip_DDLs) { tprint(tracef, "we skip DDLs\n"); return 0; } + if ((info= get_MARIA_HA_from_REDO_record(rec)) == NULL) { /* no such table, don't need to warn */ @@ -1479,7 +1481,13 @@ end: if (error) { if (info != NULL) + { + /* let maria_close() mark the table properly closed */ + info->s->state.open_count= 1; + info->s->global_changed= 1; + info->s->changed= 1; maria_close(info); + } if (error == -1) error= 0; } From 04ee30e75ad31e3cab176df8288dd54b0a4fa23d Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Mon, 5 Mar 2012 20:32:28 -0800 Subject: [PATCH 135/135] Fixed LP bug #946055. The function create_hj_key_for_table() that builds the descriptor of the hash join key to access a table of a materialized subquery must ignore any equi-join predicate depending on the tables not belonging to the subquery. --- mysql-test/r/subselect_mat.result | 51 ++++++++++++++++++++++++++ mysql-test/r/subselect_sj_mat.result | 53 ++++++++++++++++++++++++++++ mysql-test/t/subselect_sj_mat.test | 40 +++++++++++++++++++++ sql/sql_select.cc | 13 ++++--- 4 files changed, 153 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/subselect_mat.result b/mysql-test/r/subselect_mat.result index 97463447e1d..35b46ab975f 100644 --- a/mysql-test/r/subselect_mat.result +++ b/mysql-test/r/subselect_mat.result @@ -1913,6 +1913,57 @@ WHERE a IN (SELECT MAX(c) FROM t2 WHERE c < 4) AND b=7 AND (a IS NULL OR a=b); a b SET optimizer_switch=@save_optimizer_switch; DROP TABLE t1,t2; +# +# BUG#946055: Crash with semijoin IN subquery when hash join is used +# +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (7); +CREATE TABLE t2 (b int, c int, d varchar(1), e varchar(1), KEY (c), KEY (d, c)); +INSERT INTO t2 VALUES +(4,2,'v','v'), (6,1,'v','v'), (0,5,'x','x'), (7,1,'x','x'), +(7,3,'i','i'), (7,1,'e','e'), (1,4,'p','p'), (1,2,'j','j'); +SET @save_optimizer_switch=@@optimizer_switch; +SET @save_join_cache_level=@@join_cache_level; +SET join_cache_level=2; +EXPLAIN +SELECT a, c FROM t1, t2 +WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2 +WHERE s2.d = s1.e AND s1.e = (SELECT MAX(e) FROM t2)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 system NULL NULL NULL NULL 1 +1 PRIMARY t2 index NULL c 5 NULL 8 Using where; Using index +2 MATERIALIZED s2 ref d d 4 const 1 Using where; Using index +2 MATERIALIZED s1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) +3 SUBQUERY t2 ALL NULL NULL NULL NULL 8 +SELECT a, c FROM t1, t2 +WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2 +WHERE s2.d = s1.e AND s1.e = (SELECT MAX(e) FROM t2)); +a c +7 1 +7 1 +7 1 +SET optimizer_switch='join_cache_hashed=on'; +SET join_cache_level=4; +EXPLAIN +SELECT a, c FROM t1, t2 +WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2 +WHERE s2.d = s1.e AND s1.e = (SELECT MAX(e) FROM t2)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 system NULL NULL NULL NULL 1 +1 PRIMARY t2 index NULL c 5 NULL 8 Using where; Using index +2 MATERIALIZED s2 ref d d 4 const 1 Using where; Using index +2 MATERIALIZED s1 hash_ALL NULL #hash#$hj 5 test.s2.d 8 Using where; Using join buffer (flat, BNLH join) +3 SUBQUERY t2 ALL NULL NULL NULL NULL 8 +SELECT a, c FROM t1, t2 +WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2 +WHERE s2.d = s1.e AND s1.e = (SELECT MAX(e) FROM t2)); +a c +7 1 +7 1 +7 1 +SET optimizer_switch=@save_optimizer_switch; +SET join_cache_level=@save_join_cache_level; +DROP TABLE t1,t2; # This must be at the end: set optimizer_switch=@subselect_sj_mat_tmp; set join_cache_level=@save_join_cache_level; diff --git a/mysql-test/r/subselect_sj_mat.result b/mysql-test/r/subselect_sj_mat.result index db5a27a5d84..d13482e9b2d 100644 --- a/mysql-test/r/subselect_sj_mat.result +++ b/mysql-test/r/subselect_sj_mat.result @@ -1951,6 +1951,59 @@ WHERE a IN (SELECT MAX(c) FROM t2 WHERE c < 4) AND b=7 AND (a IS NULL OR a=b); a b SET optimizer_switch=@save_optimizer_switch; DROP TABLE t1,t2; +# +# BUG#946055: Crash with semijoin IN subquery when hash join is used +# +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (7); +CREATE TABLE t2 (b int, c int, d varchar(1), e varchar(1), KEY (c), KEY (d, c)); +INSERT INTO t2 VALUES +(4,2,'v','v'), (6,1,'v','v'), (0,5,'x','x'), (7,1,'x','x'), +(7,3,'i','i'), (7,1,'e','e'), (1,4,'p','p'), (1,2,'j','j'); +SET @save_optimizer_switch=@@optimizer_switch; +SET @save_join_cache_level=@@join_cache_level; +SET join_cache_level=2; +EXPLAIN +SELECT a, c FROM t1, t2 +WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2 +WHERE s2.d = s1.e AND s1.e = (SELECT MAX(e) FROM t2)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 system NULL NULL NULL NULL 1 +1 PRIMARY t2 index c c 5 NULL 8 Using index +1 PRIMARY eq_ref distinct_key distinct_key 8 func,func 1 +2 MATERIALIZED s2 ref d d 4 const 1 Using where; Using index +2 MATERIALIZED s1 ALL c NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) +3 SUBQUERY t2 ALL NULL NULL NULL NULL 8 +SELECT a, c FROM t1, t2 +WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2 +WHERE s2.d = s1.e AND s1.e = (SELECT MAX(e) FROM t2)); +a c +7 1 +7 1 +7 1 +SET optimizer_switch='join_cache_hashed=on'; +SET join_cache_level=4; +EXPLAIN +SELECT a, c FROM t1, t2 +WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2 +WHERE s2.d = s1.e AND s1.e = (SELECT MAX(e) FROM t2)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 system NULL NULL NULL NULL 1 +1 PRIMARY t2 index c c 5 NULL 8 Using index +1 PRIMARY eq_ref distinct_key distinct_key 8 func,func 1 +2 MATERIALIZED s2 ref d d 4 const 1 Using where; Using index +2 MATERIALIZED s1 hash_ALL c #hash#$hj 10 const,test.s2.d 8 Using where; Using join buffer (flat, BNLH join) +3 SUBQUERY t2 ALL NULL NULL NULL NULL 8 +SELECT a, c FROM t1, t2 +WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2 +WHERE s2.d = s1.e AND s1.e = (SELECT MAX(e) FROM t2)); +a c +7 1 +7 1 +7 1 +SET optimizer_switch=@save_optimizer_switch; +SET join_cache_level=@save_join_cache_level; +DROP TABLE t1,t2; # This must be at the end: set optimizer_switch=@subselect_sj_mat_tmp; set join_cache_level=@save_join_cache_level; diff --git a/mysql-test/t/subselect_sj_mat.test b/mysql-test/t/subselect_sj_mat.test index 252fbb525eb..ba260b7d8c3 100644 --- a/mysql-test/t/subselect_sj_mat.test +++ b/mysql-test/t/subselect_sj_mat.test @@ -1602,6 +1602,46 @@ SET optimizer_switch=@save_optimizer_switch; DROP TABLE t1,t2; +--echo # +--echo # BUG#946055: Crash with semijoin IN subquery when hash join is used +--echo # + +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (7); + +CREATE TABLE t2 (b int, c int, d varchar(1), e varchar(1), KEY (c), KEY (d, c)); + +INSERT INTO t2 VALUES + (4,2,'v','v'), (6,1,'v','v'), (0,5,'x','x'), (7,1,'x','x'), + (7,3,'i','i'), (7,1,'e','e'), (1,4,'p','p'), (1,2,'j','j'); + +SET @save_optimizer_switch=@@optimizer_switch; +SET @save_join_cache_level=@@join_cache_level; + +SET join_cache_level=2; +EXPLAIN +SELECT a, c FROM t1, t2 + WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2 + WHERE s2.d = s1.e AND s1.e = (SELECT MAX(e) FROM t2)); +SELECT a, c FROM t1, t2 + WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2 + WHERE s2.d = s1.e AND s1.e = (SELECT MAX(e) FROM t2)); + +SET optimizer_switch='join_cache_hashed=on'; +SET join_cache_level=4; +EXPLAIN +SELECT a, c FROM t1, t2 + WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2 + WHERE s2.d = s1.e AND s1.e = (SELECT MAX(e) FROM t2)); +SELECT a, c FROM t1, t2 + WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2 + WHERE s2.d = s1.e AND s1.e = (SELECT MAX(e) FROM t2)); + +SET optimizer_switch=@save_optimizer_switch; +SET join_cache_level=@save_join_cache_level; + +DROP TABLE t1,t2; + --echo # This must be at the end: set optimizer_switch=@subselect_sj_mat_tmp; set join_cache_level=@save_join_cache_level; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 55fbfae77b7..437833eb90c 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -60,6 +60,7 @@ static bool update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse, static bool sort_and_filter_keyuse(THD *thd, DYNAMIC_ARRAY *keyuse, bool skip_unprefixed_keyparts); static int sort_keyuse(KEYUSE *a,KEYUSE *b); +static bool are_tables_local(JOIN_TAB *jtab, table_map used_tables); static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, bool allow_full_scan, table_map used_tables); void best_access_path(JOIN *join, JOIN_TAB *s, @@ -7262,7 +7263,8 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab, do { - if (!(~used_tables & keyuse->used_tables)) + if (!(~used_tables & keyuse->used_tables) && + are_tables_local(join_tab, keyuse->used_tables)) { if (first_keyuse) { @@ -7275,7 +7277,8 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab, for( ; curr < keyuse; curr++) { if (curr->keypart == keyuse->keypart && - !(~used_tables & curr->used_tables)) + !(~used_tables & curr->used_tables) && + are_tables_local(join_tab, curr->used_tables)) break; } if (curr == keyuse) @@ -7306,7 +7309,8 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab, keyuse= org_keyuse; do { - if (!(~used_tables & keyuse->used_tables)) + if (!(~used_tables & keyuse->used_tables) && + are_tables_local(join_tab, keyuse->used_tables)) { bool add_key_part= TRUE; if (!first_keyuse) @@ -7314,7 +7318,8 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab, for(KEYUSE *curr= org_keyuse; curr < keyuse; curr++) { if (curr->keypart == keyuse->keypart && - !(~used_tables & curr->used_tables)) + !(~used_tables & curr->used_tables) && + are_tables_local(join_tab, curr->used_tables)) { keyuse->keypart= NO_KEYPART; add_key_part= FALSE;