From ae0029041136a7bc4f6493954aa005c530344100 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 5 Oct 2010 14:18:16 +0200 Subject: [PATCH 01/11] Bug#55629 5.5.x goes into infinite loop and high cpu after error flushing io cache The reason for the error was incorrect return code from my_win_write() in case of error on 64 bit Windows. Error should be indicated by return code (size_t)-1 == 2^64 -1, but due to cast it was (DWORD)-1 = 2^32 -1 The caller of this function would fail to recognize the error and continue looping. Fix is to return correct error code (size_t)-1 in case of error as expected by caller. Also minimal cleanup is done : my_win_write() now uses the same parameter checks as related functions (0 and overflow handling for count parameter). --- mysys/my_winfile.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/mysys/my_winfile.c b/mysys/my_winfile.c index 6c0b191ca2c..4d80d774dad 100644 --- a/mysys/my_winfile.c +++ b/mysys/my_winfile.c @@ -97,7 +97,7 @@ HANDLE my_get_osfhandle(File fd) static int my_get_open_flags(File fd) { - DBUG_ENTER("my_get_osfhandle"); + DBUG_ENTER("my_get_open_flags"); DBUG_ASSERT(fd >= MY_FILE_MIN && fd < (int)my_file_limit); DBUG_RETURN(my_file_info[fd].oflag); } @@ -321,7 +321,7 @@ size_t my_win_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset) if(lastError == ERROR_HANDLE_EOF || lastError == ERROR_BROKEN_PIPE) DBUG_RETURN(0); /*return 0 at EOF*/ my_osmaperr(lastError); - DBUG_RETURN(-1); + DBUG_RETURN((size_t)-1); } DBUG_RETURN(nBytesRead); } @@ -352,7 +352,7 @@ size_t my_win_read(File Filedes, uchar *Buffer, size_t Count) if(lastError == ERROR_HANDLE_EOF || lastError == ERROR_BROKEN_PIPE) DBUG_RETURN(0); /*return 0 at EOF*/ my_osmaperr(lastError); - DBUG_RETURN(-1); + DBUG_RETURN((size_t)-1); } DBUG_RETURN(nBytesRead); } @@ -386,7 +386,7 @@ size_t my_win_pwrite(File Filedes, const uchar *Buffer, size_t Count, if(!WriteFile(hFile, Buffer, (DWORD)Count, &nBytesWritten, &ov)) { my_osmaperr(GetLastError()); - DBUG_RETURN(-1); + DBUG_RETURN((size_t)-1); } else DBUG_RETURN(nBytesWritten); @@ -427,6 +427,15 @@ size_t my_win_write(File fd, const uchar *Buffer, size_t Count) DBUG_ENTER("my_win_write"); DBUG_PRINT("my",("Filedes: %d, Buffer: %p, Count %llu", fd, Buffer, (ulonglong)Count)); + + if(!Count) + DBUG_RETURN(0); + +#ifdef _WIN64 + if(Count > UINT_MAX) + Count= UINT_MAX; +#endif + if(my_get_open_flags(fd) & _O_APPEND) { /* @@ -442,10 +451,10 @@ size_t my_win_write(File fd, const uchar *Buffer, size_t Count) hFile= my_get_osfhandle(fd); if(!WriteFile(hFile, Buffer, (DWORD)Count, &nWritten, pov)) { - nWritten= (size_t)-1; my_osmaperr(GetLastError()); + DBUG_RETURN((size_t)-1); } - DBUG_RETURN((size_t)nWritten); + DBUG_RETURN(nWritten); } From 5df8fd90beb7877cc81ccfd60e2fca38fd8e7c71 Mon Sep 17 00:00:00 2001 From: Calvin Sun Date: Tue, 5 Oct 2010 13:38:30 -0500 Subject: [PATCH 02/11] bug#56318: Replication aborts with ER_TOO_BIG_ROWSIZE if innodb parameters don't match Revert the changes of the default values of innodb_file_per_table and innobase_file_format in 5.5, until WL#5135 is implemented. --- .../sys_vars/r/innodb_file_format_basic.result | 14 +++++++------- storage/innobase/handler/ha_innodb.cc | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/mysql-test/suite/sys_vars/r/innodb_file_format_basic.result b/mysql-test/suite/sys_vars/r/innodb_file_format_basic.result index 41369038cf6..58e009ea705 100644 --- a/mysql-test/suite/sys_vars/r/innodb_file_format_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_file_format_basic.result @@ -1,28 +1,28 @@ SET @start_global_value = @@global.innodb_file_format; SELECT @start_global_value; @start_global_value -Barracuda +Antelope Valid values are 'Antelope' and 'Barracuda' select @@global.innodb_file_format in ('Antelope', 'Barracuda'); @@global.innodb_file_format in ('Antelope', 'Barracuda') 1 select @@global.innodb_file_format; @@global.innodb_file_format -Barracuda +Antelope select @@session.innodb_file_format; ERROR HY000: Variable 'innodb_file_format' is a GLOBAL variable show global variables like 'innodb_file_format'; Variable_name Value -innodb_file_format Barracuda +innodb_file_format Antelope show session variables like 'innodb_file_format'; Variable_name Value -innodb_file_format Barracuda +innodb_file_format Antelope select * from information_schema.global_variables where variable_name='innodb_file_format'; VARIABLE_NAME VARIABLE_VALUE -INNODB_FILE_FORMAT Barracuda +INNODB_FILE_FORMAT Antelope select * from information_schema.session_variables where variable_name='innodb_file_format'; VARIABLE_NAME VARIABLE_VALUE -INNODB_FILE_FORMAT Barracuda +INNODB_FILE_FORMAT Antelope set global innodb_file_format='Antelope'; select @@global.innodb_file_format; @@global.innodb_file_format @@ -56,4 +56,4 @@ ERROR 42000: Variable 'innodb_file_format' can't be set to the value of 'Salmon' SET @@global.innodb_file_format = @start_global_value; SELECT @@global.innodb_file_format; @@global.innodb_file_format -Barracuda +Antelope diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index bbf3c5aa3c8..83fa1853e25 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -10835,13 +10835,13 @@ static MYSQL_SYSVAR_ULONG(fast_shutdown, innobase_fast_shutdown, static MYSQL_SYSVAR_BOOL(file_per_table, srv_file_per_table, PLUGIN_VAR_NOCMDARG, "Stores each InnoDB table to an .ibd file in the database dir.", - NULL, NULL, TRUE); + NULL, NULL, FALSE); static MYSQL_SYSVAR_STR(file_format, innobase_file_format_name, PLUGIN_VAR_RQCMDARG, "File format to use for new tables in .ibd files.", innodb_file_format_name_validate, - innodb_file_format_name_update, "Barracuda"); + innodb_file_format_name_update, "Antelope"); /* "innobase_file_format_check" decides whether we would continue booting the server if the file format stamped on the system From d09c19f7063813a3812e4c3c511ede6f28105496 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Wed, 6 Oct 2010 11:48:46 +0100 Subject: [PATCH 03/11] BUG#52202: mysqlbinlog_row* fail in daily-trunk on Sol10 x86_64 debug_max Removed test cases affected by this bug from experimental list. --- mysql-test/collections/default.experimental | 3 --- 1 file changed, 3 deletions(-) diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index b292356f1c7..48e10511b80 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -15,9 +15,6 @@ main.lock_multi_bug38499 # Bug#47448 2009-09-19 alik main.lock_m main.lock_multi_bug38691 @solaris # Bug#47792 2009-10-02 alik main.lock_multi_bug38691 times out sporadically on Solaris 10 main.log_tables # Bug#47924 2009-10-08 alik main.log_tables times out sporadically main.lowercase_table2 @darwin # Bug#55509 2010-07-26 alik main.lowercase_table2 fails on Mac OSX (again) -main.mysqlbinlog_row @solaris # Bug#52202 2010-03-22 alik mysqlbinlog_row* fail in daily-trunk on Sol10 x86_64 debug_max -main.mysqlbinlog_row_innodb @solaris # Bug#52202 2010-03-22 alik mysqlbinlog_row* fail in daily-trunk on Sol10 x86_64 debug_max -main.mysqlbinlog_row_myisam @solaris # Bug#52202 2010-03-22 alik mysqlbinlog_row* fail in daily-trunk on Sol10 x86_64 debug_max main.outfile_loaddata @solaris # Bug#46895 2010-01-20 alik Test "outfile_loaddata" fails (reproducible) main.signal_demo3 @solaris # Bug#47791 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun main.sp @solaris # Bug#47791 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun From ab15833ac265e11710e4de1390a82678011aab59 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Wed, 6 Oct 2010 16:15:59 +0400 Subject: [PATCH 04/11] Bug#55744 GROUP_CONCAT + CASE + ucs return garbage Problem: CASE didn't work with a mixture of different character sets in THEN/ELSE in some cases. This happened because after character set aggregation newly created Item_func_conv_charset items corresponding to THEN/ELSE arguments were not put back to args[] array. Fix: put all Item_func_conv_charset back to args[]. @ mysql-test/include/ctype_numconv.inc @ mysql-test/r/ctype_ucs.result Adding tests @ sql/item_cmpfunc.cc Put "agg" back to args[] after character set aggregation. --- mysql-test/include/ctype_numconv.inc | 7 +------ mysql-test/r/ctype_ucs.result | 3 +++ sql/item_cmpfunc.cc | 8 ++++++++ 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/mysql-test/include/ctype_numconv.inc b/mysql-test/include/ctype_numconv.inc index 06a9107e963..c4a39879947 100644 --- a/mysql-test/include/ctype_numconv.inc +++ b/mysql-test/include/ctype_numconv.inc @@ -1635,12 +1635,7 @@ CREATE TABLE t1 (a MEDIUMINT NULL) ENGINE=MYISAM; INSERT INTO t1 VALUES (1234567); SELECT GROUP_CONCAT(IFNULL(a,'')) FROM t1; SELECT GROUP_CONCAT(IF(a,a,'')) FROM t1; -if (`SELECT @@character_set_connection != 'ucs2'`) -{ - # Temporarily disable for ucs2 - # For details, see Bug#55744 GROUP_CONCAT + CASE + ucs return garbage - SELECT GROUP_CONCAT(CASE WHEN a THEN a ELSE '' END) FROM t1; -} +SELECT GROUP_CONCAT(CASE WHEN a THEN a ELSE '' END) FROM t1; --enable_metadata SELECT COALESCE(a,'') FROM t1 GROUP BY 1; --disable_metadata diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result index 1215eb1db02..c2fb90ecfa6 100644 --- a/mysql-test/r/ctype_ucs.result +++ b/mysql-test/r/ctype_ucs.result @@ -3853,6 +3853,9 @@ GROUP_CONCAT(IFNULL(a,'')) SELECT GROUP_CONCAT(IF(a,a,'')) FROM t1; GROUP_CONCAT(IF(a,a,'')) 1234567 +SELECT GROUP_CONCAT(CASE WHEN a THEN a ELSE '' END) FROM t1; +GROUP_CONCAT(CASE WHEN a THEN a ELSE '' END) +1234567 SELECT COALESCE(a,'') FROM t1 GROUP BY 1; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr def COALESCE(a,'') 253 9 7 Y 0 31 8 diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index b7aad733e67..b04ec105468 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -3029,6 +3029,14 @@ void Item_func_case::fix_length_and_dec() { if (agg_arg_charsets_for_string_result(collation, agg, nagg)) return; + /* + Copy all THEN and ELSE items back to args[] array. + Some of the items might have been changed to Item_func_conv_charset. + */ + for (nagg= 0 ; nagg < ncases / 2 ; nagg++) + args[nagg * 2 + 1]= agg[nagg]; + if (else_expr_num != -1) + args[else_expr_num]= agg[nagg++]; } else collation.set_numeric(); From f79f6e0c3429329c3a6be968827d91237a7df899 Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Wed, 6 Oct 2010 19:06:13 +0400 Subject: [PATCH 05/11] Fix for Bug#57094 (Copyright notice incorrect?). The fix is to: - introduce ORACLE_WELCOME_COPYRIGHT_NOTICE define to have a single place to specify copyright notice; - replace custom copyright notices with ORACLE_WELCOME_COPYRIGHT_NOTICE in programs. --- client/mysql.cc | 10 +++------- client/mysql_upgrade.c | 5 ++++- client/mysqladmin.cc | 9 ++++----- client/mysqlbinlog.cc | 8 +++----- client/mysqlcheck.c | 9 +++------ client/mysqldump.c | 7 ++++--- client/mysqlimport.c | 7 ++++--- client/mysqlshow.c | 6 +++--- client/mysqlslap.c | 13 ++++--------- client/mysqltest.cc | 7 ++++--- include/welcome_copyright_notice.h | 31 ++++++++++++++++++++++++++++++ sql/mysqld.cc | 11 ++++------- 12 files changed, 71 insertions(+), 52 deletions(-) create mode 100644 include/welcome_copyright_notice.h diff --git a/client/mysql.cc b/client/mysql.cc index 14473ba4b51..4a8579bbd4d 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -13,11 +13,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#define COPYRIGHT_NOTICE "\ -Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.\n\ -This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\ -and you are welcome to modify and redistribute it under the GPL v2 license\n" - /* mysql command tool * Commands compatible with mSQL by David J. Hughes * @@ -110,6 +105,7 @@ extern "C" { #endif #include "completion_hash.h" +#include // ORACLE_WELCOME_COPYRIGHT_NOTICE #define PROMPT_CHAR '\\' #define DEFAULT_DELIMITER ";" @@ -1177,7 +1173,7 @@ int main(int argc,char *argv[]) mysql_thread_id(&mysql), server_version_string(&mysql)); put_info((char*) glob_buffer.ptr(),INFO_INFO); - put_info(COPYRIGHT_NOTICE, INFO_INFO); + put_info(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2010"), INFO_INFO); #ifdef HAVE_READLINE initialize_readline((char*) my_progname); @@ -1595,7 +1591,7 @@ static void usage(int version) if (version) return; - printf("%s", COPYRIGHT_NOTICE); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2010")); printf("Usage: %s [OPTIONS] [database]\n", my_progname); my_print_help(my_long_options); print_defaults("my", load_default_groups); diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 882350f813b..4fbf08102bd 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2010, 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 @@ -17,6 +17,8 @@ #include #include "../scripts/mysql_fix_privilege_tables_sql.c" +#include /* ORACLE_WELCOME_COPYRIGHT_NOTICE */ + #define VER "1.1" #ifdef HAVE_SYS_WAIT_H @@ -232,6 +234,7 @@ get_one_option(int optid, const struct my_option *opt, case '?': printf("%s Ver %s Distrib %s, for %s (%s)\n", my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2010")); puts("MySQL utility for upgrading databases to new MySQL versions.\n"); my_print_help(my_long_options); exit(0); diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index 69381b749a1..342a67fbc29 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2006 MySQL AB +/* Copyright (c) 2000, 2010, 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 @@ -23,6 +23,7 @@ #include #include #include +#include /* ORACLE_WELCOME_COPYRIGHT_NOTICE */ #define ADMIN_VERSION "8.42" #define MAX_MYSQL_VAR 512 @@ -671,8 +672,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) case ADMIN_VER: new_line=1; print_version(); - puts("Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc."); - puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n"); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2010")); printf("Server version\t\t%s\n", mysql_get_server_info(mysql)); printf("Protocol version\t%d\n", mysql_get_proto_info(mysql)); printf("Connection\t\t%s\n",mysql_get_host_info(mysql)); @@ -1070,8 +1070,7 @@ static void print_version(void) static void usage(void) { print_version(); - puts("Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc."); - puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n"); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2010")); puts("Administration program for the mysqld daemon."); printf("Usage: %s [OPTIONS] command command....\n", my_progname); my_print_help(my_long_options); diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 277c2d62544..226776e4404 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2004 MySQL AB +/* Copyright (c) 2001, 2010, 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 @@ -34,6 +34,7 @@ #include "sql_priv.h" #include "log_event.h" #include "sql_common.h" +#include // ORACLE_WELCOME_COPYRIGHT_NOTICE #define BIN_LOG_HEADER_SIZE 4 #define PROBE_HEADER_LEN (EVENT_LEN_OFFSET+4) @@ -1239,10 +1240,7 @@ static void print_version() static void usage() { print_version(); - puts("By Monty and Sasha, for your professional use\n\ -This software comes with NO WARRANTY: This is free software,\n\ -and you are welcome to modify and redistribute it under the GPL license.\n"); - + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2001, 2010")); printf("\ Dumps a MySQL binary log in a format usable for viewing or for piping to\n\ the mysql command line client.\n\n"); diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index ce733e57db6..aebe80b9ba6 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB, 2009 Sun Microsystems, Inc +/* Copyright (c) 2000, 2010, 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 @@ -13,8 +13,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* By Jani Tolonen, 2001-04-20, MySQL Development Team */ - #define CHECK_VERSION "2.5.0" #include "client_priv.h" @@ -22,6 +20,7 @@ #include #include #include +#include /* ORACLE_WELCOME_COPYRIGHT_NOTICE */ /* Exit codes */ @@ -215,9 +214,7 @@ static void print_version(void) static void usage(void) { print_version(); - puts("By Jani Tolonen, 2001-04-20, MySQL Development Team.\n"); - puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n"); - puts("and you are welcome to modify and redistribute it under the GPL license.\n"); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2010")); puts("This program can be used to CHECK (-c, -m, -C), REPAIR (-r), ANALYZE (-a),"); puts("or OPTIMIZE (-o) tables. Some of the options (like -e or -q) can be"); puts("used at the same time. Not all options are supported by all storage engines."); diff --git a/client/mysqldump.c b/client/mysqldump.c index ac704f152de..b47d88290a5 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -1,4 +1,4 @@ -/* Copyright 2000-2008 MySQL AB, 2008, 2009 Sun Microsystems, Inc. +/* Copyright (c) 2000, 2010, 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 @@ -51,6 +51,8 @@ #include "mysql_version.h" #include "mysqld_error.h" +#include /* ORACLE_WELCOME_COPYRIGHT_NOTICE */ + /* Exit codes */ #define EX_USAGE 1 @@ -584,8 +586,7 @@ static void short_usage_sub(void) static void usage(void) { print_version(); - puts("By Igor Romanenko, Monty, Jani & Sinisa."); - puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license.\n"); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2010")); puts("Dumping structure and contents of MySQL databases and tables."); short_usage_sub(); print_defaults("my",load_default_groups); diff --git a/client/mysqlimport.c b/client/mysqlimport.c index 3d71e437e40..aea1cb79e74 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2006 MySQL AB, 2009 Sun Microsystems, Inc. +/* Copyright (c) 2000, 2010, 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 @@ -32,6 +32,8 @@ #include #endif +#include /* ORACLE_WELCOME_COPYRIGHT_NOTICE */ + /* Global Thread counter */ uint counter; @@ -191,8 +193,7 @@ static void print_version(void) static void usage(void) { print_version(); - puts("Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc."); - puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license.\n"); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2010")); printf("\ Loads tables from text files in various formats. The base name of the\n\ text file must be the name of the table that should be used.\n\ diff --git a/client/mysqlshow.c b/client/mysqlshow.c index bb05400e0d8..8cd70db1424 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2006 MySQL AB +/* Copyright (c) 2000, 2010, 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 @@ -25,6 +25,7 @@ #include #include #include +#include /* ORACLE_WELCOME_COPYRIGHT_NOTICE */ static char * host=0, *opt_password=0, *user=0; static my_bool opt_show_keys= 0, opt_compress= 0, opt_count=0, opt_status= 0; @@ -247,8 +248,7 @@ static void print_version(void) static void usage(void) { print_version(); - puts("Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc."); - puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license.\n"); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2010)")); puts("Shows the structure of a MySQL database (databases, tables, and columns).\n"); printf("Usage: %s [OPTIONS] [database [table [column]]]\n",my_progname); puts("\n\ diff --git a/client/mysqlslap.c b/client/mysqlslap.c index e605e2d522c..4e8e4f1aa67 100644 --- a/client/mysqlslap.c +++ b/client/mysqlslap.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2005 MySQL AB, 2009 Sun Microsystems, Inc. +/* Copyright (c) 2005, 2010, 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 @@ -11,12 +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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - original idea: Brian Aker via playing with ab for too many years - coded by: Patrick Galbraith -*/ - + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* MySQL Slap @@ -94,6 +89,7 @@ TODO: #include #endif #include +#include /* ORACLE_WELCOME_COPYRIGHT_NOTICE */ #ifdef __WIN__ #define srandom srand @@ -686,8 +682,7 @@ static void print_version(void) static void usage(void) { print_version(); - puts("Copyright (C) 2005 MySQL AB"); - puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license.\n"); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2005, 2010")); puts("Run a query multiple times against the server.\n"); printf("Usage: %s [OPTIONS]\n",my_progname); print_defaults("my",load_default_groups); diff --git a/client/mysqltest.cc b/client/mysqltest.cc index b75fae7b685..376ce0fa59d 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2010, 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 @@ -52,6 +52,8 @@ #include #include +#include // ORACLE_WELCOME_COPYRIGHT_NOTICE + #ifdef __WIN__ #include #define SIGNAL_FMT "exception 0x%x" @@ -6260,8 +6262,7 @@ void print_version(void) void usage() { print_version(); - printf("MySQL AB, by Sasha, Matt, Monty & Jani\n"); - printf("This software comes with ABSOLUTELY NO WARRANTY\n\n"); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2010")); printf("Runs a test against the mysql server and compares output with a results file.\n\n"); printf("Usage: %s [OPTIONS] [database] < test_file\n", my_progname); my_print_help(my_long_options); diff --git a/include/welcome_copyright_notice.h b/include/welcome_copyright_notice.h new file mode 100644 index 00000000000..c3ffad1527d --- /dev/null +++ b/include/welcome_copyright_notice.h @@ -0,0 +1,31 @@ +/* Copyright (c) 2010, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifndef _welcome_copyright_notice_h_ +#define _welcome_copyright_notice_h_ + +/* + This define specifies copyright notice which is displayed by every MySQL + program on start, or on help screen. +*/ + +#define ORACLE_WELCOME_COPYRIGHT_NOTICE(years) \ + "Copyright (c) " years ", Oracle and/or its affiliates. All rights reserved.\n" \ + "\n" \ + "Oracle is a registered trademark of Oracle Corporation and/or its\n" \ + "affiliates. Other names may be trademarks of their respective\n" \ + "owners.\n" + +#endif /* _welcome_copyright_notice_h_ */ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 1ab335eb106..e43320f12a5 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -265,6 +265,8 @@ extern "C" sig_handler handle_segfault(int sig); /* Constants */ +#include // ORACLE_WELCOME_COPYRIGHT_NOTICE + const char *show_comp_option_name[]= {"YES", "NO", "DISABLED"}; static const char *tc_heuristic_recover_names[]= @@ -6593,13 +6595,8 @@ static void usage(void) if (!default_collation_name) default_collation_name= (char*) default_charset_info->name; print_version(); - puts("\ -Copyright (C) 2000-2008 MySQL AB, by Monty and others.\n\ -Copyright (C) 2008,2009 Sun Microsystems, Inc.\n\ -This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\ -and you are welcome to modify and redistribute it under the GPL license\n\n\ -Starts the MySQL database server.\n"); - + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2010")); + puts("Starts the MySQL database server.\n"); printf("Usage: %s [OPTIONS]\n", my_progname); if (!opt_verbose) puts("\nFor more help options (several pages), use mysqld --verbose --help."); From 4bfec5733d8a6c5096a65032a6036e17ddbdbd3e Mon Sep 17 00:00:00 2001 From: Evgeny Potemkin Date: Thu, 7 Oct 2010 11:07:56 +0400 Subject: [PATCH 06/11] Bug#57039: constant subtime expression returns incorrect result. The subtime function wasn't able to produce correct int representation of its result. For constant expressions the Item_datetime_cache is used to speedup evaluation and Item_datetime_cache expects underlying item to return correct int representation of DATETIME value. These two factors combined led to a wrong query result. Now the Item_func_add_time has function val_datetime which performs the calculation and saves result into given MYSQL_TIME struct, it also sets null_value to appropriate value. val_int and val_str member functions convert the result obtained from val_datetime to int or string respectively and returns it. --- mysql-test/r/func_time.result | 11 ++++++ mysql-test/t/func_time.test | 11 ++++++ sql/item_timefunc.cc | 70 +++++++++++++++++++++++++---------- sql/item_timefunc.h | 2 + 4 files changed, 74 insertions(+), 20 deletions(-) diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index f2c26110d8a..f1b2196ebfa 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -1316,3 +1316,14 @@ SELECT 1 FROM t1 ORDER BY @x:=makedate(a,a); 1 DROP TABLE t1; End of 5.1 tests +# +# Bug#57039: constant subtime expression returns incorrect result. +# +CREATE TABLE t1 (`date_date` datetime NOT NULL); +INSERT INTO t1 VALUES ('2008-01-03 00:00:00'), ('2008-01-03 00:00:00'); +SELECT * FROM t1 WHERE date_date >= subtime(now(), "00:30:00"); +date_date +SELECT * FROM t1 WHERE date_date <= addtime(date_add("2000-1-1", INTERVAL "1:1:1" HOUR_SECOND), "00:20:00"); +date_date +DROP TABLE t1; +# diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index 1f6001219a3..08c09adb093 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -833,3 +833,14 @@ SELECT 1 FROM t1 ORDER BY @x:=makedate(a,a); DROP TABLE t1; --echo End of 5.1 tests + +--echo # +--echo # Bug#57039: constant subtime expression returns incorrect result. +--echo # +CREATE TABLE t1 (`date_date` datetime NOT NULL); +INSERT INTO t1 VALUES ('2008-01-03 00:00:00'), ('2008-01-03 00:00:00'); +SELECT * FROM t1 WHERE date_date >= subtime(now(), "00:30:00"); +SELECT * FROM t1 WHERE date_date <= addtime(date_add("2000-1-1", INTERVAL "1:1:1" HOUR_SECOND), "00:20:00"); +DROP TABLE t1; +--echo # + diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index cc363398fdd..e53558a3385 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2857,10 +2857,11 @@ void Item_func_add_time::fix_length_and_dec() Result: Time value or datetime value */ -String *Item_func_add_time::val_str(String *str) +MYSQL_TIME *Item_func_add_time::val_datetime(MYSQL_TIME *time, + date_time_format_types *format) { DBUG_ASSERT(fixed == 1); - MYSQL_TIME l_time1, l_time2, l_time3; + MYSQL_TIME l_time1, l_time2; bool is_time= 0; long days, microseconds; longlong seconds; @@ -2886,41 +2887,38 @@ String *Item_func_add_time::val_str(String *str) if (l_time1.neg != l_time2.neg) l_sign= -l_sign; - bzero((char *)&l_time3, sizeof(l_time3)); + bzero((char *)time, sizeof(MYSQL_TIME)); - l_time3.neg= calc_time_diff(&l_time1, &l_time2, -l_sign, - &seconds, µseconds); + time->neg= calc_time_diff(&l_time1, &l_time2, -l_sign, + &seconds, µseconds); /* If first argument was negative and diff between arguments is non-zero we need to swap sign to get proper result. */ if (l_time1.neg && (seconds || microseconds)) - l_time3.neg= 1-l_time3.neg; // Swap sign of result + time->neg= 1 - time->neg; // Swap sign of result - if (!is_time && l_time3.neg) + if (!is_time && time->neg) goto null_date; days= (long)(seconds/86400L); - calc_time_from_sec(&l_time3, (long)(seconds%86400L), microseconds); + calc_time_from_sec(time, (long)(seconds%86400L), microseconds); if (!is_time) { - get_date_from_daynr(days,&l_time3.year,&l_time3.month,&l_time3.day); - if (l_time3.day && - !make_datetime(l_time1.second_part || l_time2.second_part ? - DATE_TIME_MICROSECOND : DATE_TIME, - &l_time3, str)) - return str; + get_date_from_daynr(days, &time->year, &time->month, &time->day); + *format= l_time1.second_part || l_time2.second_part ? + DATE_TIME_MICROSECOND : DATE_TIME; + if (time->day) + return time; goto null_date; } - - l_time3.hour+= days*24; - if (!make_datetime_with_warn(l_time1.second_part || l_time2.second_part ? - TIME_MICROSECOND : TIME_ONLY, - &l_time3, str)) - return str; + *format= l_time1.second_part || l_time2.second_part ? + TIME_MICROSECOND : TIME_ONLY; + time->hour+= days*24; + return time; null_date: null_value=1; @@ -2928,6 +2926,38 @@ null_date: } +String *Item_func_add_time::val_str(String *str) +{ + MYSQL_TIME ltime; + date_time_format_types format; + + val_datetime(<ime, &format); + + if (null_value) + return 0; + + if (!make_datetime_with_warn(format, <ime, str)) + return str; + + null_value= 1; + return 0; +} + + +longlong Item_func_add_time::val_int() +{ + MYSQL_TIME ltime; + date_time_format_types format; + + val_datetime(<ime, &format); + + if (null_value) + return 0; + + return TIME_to_ulonglong_datetime(<ime); +} + + void Item_func_add_time::print(String *str, enum_query_type query_type) { if (is_date) diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 6e31b5c6705..d82a8f9e969 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -949,6 +949,8 @@ public: return save_date_in_field(field); return Item_str_func::save_in_field(field, no_conversions); } + longlong val_int(); + MYSQL_TIME *val_datetime(MYSQL_TIME *time, date_time_format_types *format); }; class Item_func_timediff :public Item_str_timefunc From 9c82ecec3790614af7a5b4575758c0a003ef6bbd Mon Sep 17 00:00:00 2001 From: Martin Hansson Date: Thu, 7 Oct 2010 10:13:11 +0200 Subject: [PATCH 07/11] Bug#56423: Different count with SELECT and CREATE SELECT queries This is a regression from the fix for bug no 38999. A storage engine capable of reading only a subset of a table's columns updates corresponding bits in the read buffer to signal that it has read NULL values for the corresponding columns. It cannot, and should not, update any other bits. Bug no 38999 occurred because the implementation of UPDATE statements compare the NULL bits using memcmp, inadvertently comparing bits that were never requested from the storage engine. The regression was caused by the storage engine trying to alleviate the situation by writing to all NULL bits, even those that it had no knowledge of. This has devastating effects for the index merge algorithm, which relies on all NULL bits, except those explicitly requested, being left unchanged. The fix reverts the fix for bug no 38999 in both InnoDB and InnoDB plugin and changes the server's method of comparing records. For engines that always read entire rows, we proceed as usual. For engines capable of reading only select columns, the record buffers are now compared on a column by column basis. An assertion was also added so that non comparable buffers are never read. Some relevant copy-pasted code was also consolidated in a new function. --- mysql-test/include/index_merge2.inc | 52 ++++++++++++++ mysql-test/r/index_merge_innodb.result | 55 +++++++++++++++ mysql-test/r/index_merge_myisam.result | 55 +++++++++++++++ sql/mysql_priv.h | 3 +- sql/sql_insert.cc | 4 +- sql/sql_update.cc | 93 +++++++++++++++++--------- storage/innobase/row/row0sel.c | 6 -- storage/innodb_plugin/row/row0sel.c | 6 -- 8 files changed, 227 insertions(+), 47 deletions(-) diff --git a/mysql-test/include/index_merge2.inc b/mysql-test/include/index_merge2.inc index d65115eac0f..d21562d000c 100644 --- a/mysql-test/include/index_merge2.inc +++ b/mysql-test/include/index_merge2.inc @@ -343,3 +343,55 @@ explain select * from t1 where (key3 > 30 and key3<35) or (key2 >32 and key2 < 4 select * from t1 where (key3 > 30 and key3<35) or (key2 >32 and key2 < 40); drop table t1; +--echo # +--echo # Bug#56423: Different count with SELECT and CREATE SELECT queries +--echo # + +CREATE TABLE t1 ( + a INT, + b INT, + c INT, + d INT, + PRIMARY KEY (a), + KEY (c), + KEY bd (b,d) +); + +INSERT INTO t1 VALUES +(1, 0, 1, 0), +(2, 1, 1, 1), +(3, 1, 1, 1), +(4, 0, 1, 1); + +EXPLAIN +SELECT a +FROM t1 +WHERE c = 1 AND b = 1 AND d = 1; + +CREATE TABLE t2 ( a INT ) +SELECT a +FROM t1 +WHERE c = 1 AND b = 1 AND d = 1; + +SELECT * FROM t2; + +DROP TABLE t1, t2; + +CREATE TABLE t1( a INT, b INT, KEY(a), KEY(b) ); +INSERT INTO t1 VALUES (1, 2), (1, 2), (1, 2), (1, 2); +SELECT * FROM t1 FORCE INDEX(a, b) WHERE a = 1 AND b = 2; + +DROP TABLE t1; + +--echo # Code coverage of fix. +CREATE TABLE t1 ( a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b INT); +INSERT INTO t1 (b) VALUES (1); +UPDATE t1 SET b = 2 WHERE a = 1; +SELECT * FROM t1; + +CREATE TABLE t2 ( a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b VARCHAR(1) ); +INSERT INTO t2 (b) VALUES ('a'); +UPDATE t2 SET b = 'b' WHERE a = 1; +SELECT * FROM t2; + +DROP TABLE t1, t2; diff --git a/mysql-test/r/index_merge_innodb.result b/mysql-test/r/index_merge_innodb.result index 58ed99b1e67..eaff7df280d 100644 --- a/mysql-test/r/index_merge_innodb.result +++ b/mysql-test/r/index_merge_innodb.result @@ -324,6 +324,61 @@ key1 key2 key3 38 38 38 39 39 39 drop table t1; +# +# Bug#56423: Different count with SELECT and CREATE SELECT queries +# +CREATE TABLE t1 ( +a INT, +b INT, +c INT, +d INT, +PRIMARY KEY (a), +KEY (c), +KEY bd (b,d) +); +INSERT INTO t1 VALUES +(1, 0, 1, 0), +(2, 1, 1, 1), +(3, 1, 1, 1), +(4, 0, 1, 1); +EXPLAIN +SELECT a +FROM t1 +WHERE c = 1 AND b = 1 AND d = 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge c,bd c,bd 5,10 NULL 1 Using intersect(c,bd); Using where; Using index +CREATE TABLE t2 ( a INT ) +SELECT a +FROM t1 +WHERE c = 1 AND b = 1 AND d = 1; +SELECT * FROM t2; +a +2 +3 +DROP TABLE t1, t2; +CREATE TABLE t1( a INT, b INT, KEY(a), KEY(b) ); +INSERT INTO t1 VALUES (1, 2), (1, 2), (1, 2), (1, 2); +SELECT * FROM t1 FORCE INDEX(a, b) WHERE a = 1 AND b = 2; +a b +1 2 +1 2 +1 2 +1 2 +DROP TABLE t1; +# Code coverage of fix. +CREATE TABLE t1 ( a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b INT); +INSERT INTO t1 (b) VALUES (1); +UPDATE t1 SET b = 2 WHERE a = 1; +SELECT * FROM t1; +a b +1 2 +CREATE TABLE t2 ( a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b VARCHAR(1) ); +INSERT INTO t2 (b) VALUES ('a'); +UPDATE t2 SET b = 'b' WHERE a = 1; +SELECT * FROM t2; +a b +1 b +DROP TABLE t1, t2; #---------------- 2-sweeps read Index merge test 2 ------------------------------- SET SESSION STORAGE_ENGINE = InnoDB; drop table if exists t1; diff --git a/mysql-test/r/index_merge_myisam.result b/mysql-test/r/index_merge_myisam.result index 6bfec69fad9..1ebc94dff5d 100644 --- a/mysql-test/r/index_merge_myisam.result +++ b/mysql-test/r/index_merge_myisam.result @@ -1158,6 +1158,61 @@ key1 key2 key3 38 38 38 39 39 39 drop table t1; +# +# Bug#56423: Different count with SELECT and CREATE SELECT queries +# +CREATE TABLE t1 ( +a INT, +b INT, +c INT, +d INT, +PRIMARY KEY (a), +KEY (c), +KEY bd (b,d) +); +INSERT INTO t1 VALUES +(1, 0, 1, 0), +(2, 1, 1, 1), +(3, 1, 1, 1), +(4, 0, 1, 1); +EXPLAIN +SELECT a +FROM t1 +WHERE c = 1 AND b = 1 AND d = 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref c,bd bd 10 const,const 2 Using where +CREATE TABLE t2 ( a INT ) +SELECT a +FROM t1 +WHERE c = 1 AND b = 1 AND d = 1; +SELECT * FROM t2; +a +2 +3 +DROP TABLE t1, t2; +CREATE TABLE t1( a INT, b INT, KEY(a), KEY(b) ); +INSERT INTO t1 VALUES (1, 2), (1, 2), (1, 2), (1, 2); +SELECT * FROM t1 FORCE INDEX(a, b) WHERE a = 1 AND b = 2; +a b +1 2 +1 2 +1 2 +1 2 +DROP TABLE t1; +# Code coverage of fix. +CREATE TABLE t1 ( a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b INT); +INSERT INTO t1 (b) VALUES (1); +UPDATE t1 SET b = 2 WHERE a = 1; +SELECT * FROM t1; +a b +1 2 +CREATE TABLE t2 ( a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b VARCHAR(1) ); +INSERT INTO t2 (b) VALUES ('a'); +UPDATE t2 SET b = 'b' WHERE a = 1; +SELECT * FROM t2; +a b +1 b +DROP TABLE t1, t2; #---------------- 2-sweeps read Index merge test 2 ------------------------------- SET SESSION STORAGE_ENGINE = MyISAM; drop table if exists t1; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 9f2c0b04f2c..709a49b2036 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1047,7 +1047,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd, char* packet, uint packet_length); void log_slow_statement(THD *thd); bool check_dup(const char *db, const char *name, TABLE_LIST *tables); -bool compare_record(TABLE *table); +bool records_are_comparable(const TABLE *table); +bool compare_records(const TABLE *table); bool append_file_to_dir(THD *thd, const char **filename_ptr, const char *table_name); void wait_while_table_is_used(THD *thd, TABLE *table, diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 567c7ff2b30..f0735a9e093 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1483,9 +1483,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) table->file->adjust_next_insert_id_after_explicit_value( table->next_number_field->val_int()); info->touched++; - if ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ && - !bitmap_is_subset(table->write_set, table->read_set)) || - compare_record(table)) + if (!records_are_comparable(table) || compare_records(table)) { if ((error=table->file->ha_update_row(table->record[1], table->record[0])) && diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 7da8a68546f..01c70a7a268 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -25,11 +25,68 @@ #include "sql_trigger.h" #include "debug_sync.h" -/* Return 0 if row hasn't changed */ -bool compare_record(TABLE *table) +/** + True if the table's input and output record buffers are comparable using + compare_records(TABLE*). + */ +bool records_are_comparable(const TABLE *table) { + return ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) == 0) || + bitmap_is_subset(table->write_set, table->read_set); +} + + +/** + Compares the input and outbut record buffers of the table to see if a row + has changed. The algorithm iterates over updated columns and if they are + nullable compares NULL bits in the buffer before comparing actual + data. Special care must be taken to compare only the relevant NULL bits and + mask out all others as they may be undefined. The storage engine will not + and should not touch them. + + @param table The table to evaluate. + + @return true if row has changed. + @return false otherwise. +*/ +bool compare_records(const TABLE *table) { + DBUG_ASSERT(records_are_comparable(table)); + + if ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) != 0) + { + /* + Storage engine may not have read all columns of the record. Fields + (including NULL bits) not in the write_set may not have been read and + can therefore not be compared. + */ + for (Field **ptr= table->field ; *ptr != NULL; ptr++) + { + Field *field= *ptr; + if (bitmap_is_set(table->write_set, field->field_index)) + { + if (field->real_maybe_null()) + { + uchar null_byte_index= field->null_ptr - table->record[0]; + + if (((table->record[0][null_byte_index]) & field->null_bit) != + ((table->record[1][null_byte_index]) & field->null_bit)) + return TRUE; + } + if (field->cmp_binary_offset(table->s->rec_buff_length)) + return TRUE; + } + } + return FALSE; + } + + /* + The storage engine has read all columns, so it's safe to compare all bits + including those not in the write_set. This is cheaper than the field-by-field + comparison done above. + */ if (table->s->blob_fields + table->s->varchar_fields == 0) + // Fixed-size record: do bitwise comparison of the records return cmp_record(table,record[1]); /* Compare null bits */ if (memcmp(table->null_flags, @@ -186,7 +243,6 @@ int mysql_update(THD *thd, bool using_limit= limit != HA_POS_ERROR; bool safe_update= test(thd->options & OPTION_SAFE_UPDATES); bool used_key_is_modified, transactional_table, will_batch; - bool can_compare_record; int res; int error, loc_error; uint used_index= MAX_KEY, dup_key_found; @@ -575,15 +631,6 @@ int mysql_update(THD *thd, if (table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) table->prepare_for_position(); - /* - We can use compare_record() to optimize away updates if - the table handler is returning all columns OR if - if all updated columns are read - */ - can_compare_record= (!(table->file->ha_table_flags() & - HA_PARTIAL_COLUMN_READ) || - bitmap_is_subset(table->write_set, table->read_set)); - while (!(error=info.read_record(&info)) && !thd->killed) { thd->examined_row_count++; @@ -601,7 +648,7 @@ int mysql_update(THD *thd, found++; - if (!can_compare_record || compare_record(table)) + if (!records_are_comparable(table) || compare_records(table)) { if ((res= table_list->view_check_option(thd, ignore)) != VIEW_CHECK_OK) @@ -1695,18 +1742,8 @@ bool multi_update::send_data(List ¬_used_values) if (table->status & (STATUS_NULL_ROW | STATUS_UPDATED)) continue; - /* - We can use compare_record() to optimize away updates if - the table handler is returning all columns OR if - if all updated columns are read - */ if (table == table_to_update) { - bool can_compare_record; - can_compare_record= (!(table->file->ha_table_flags() & - HA_PARTIAL_COLUMN_READ) || - bitmap_is_subset(table->write_set, - table->read_set)); table->status|= STATUS_UPDATED; store_record(table,record[1]); if (fill_record_n_invoke_before_triggers(thd, *fields_for_table[offset], @@ -1721,7 +1758,7 @@ bool multi_update::send_data(List ¬_used_values) */ table->auto_increment_field_not_null= FALSE; found++; - if (!can_compare_record || compare_record(table)) + if (!records_are_comparable(table) || compare_records(table)) { int error; if ((error= cur_table->view_check_option(thd, ignore)) != @@ -1908,7 +1945,6 @@ int multi_update::do_updates() DBUG_RETURN(0); for (cur_table= update_tables; cur_table; cur_table= cur_table->next_local) { - bool can_compare_record; uint offset= cur_table->shared; table = cur_table->table; @@ -1945,11 +1981,6 @@ int multi_update::do_updates() if ((local_error = tmp_table->file->ha_rnd_init(1))) goto err; - can_compare_record= (!(table->file->ha_table_flags() & - HA_PARTIAL_COLUMN_READ) || - bitmap_is_subset(table->write_set, - table->read_set)); - for (;;) { if (thd->killed && trans_safe) @@ -1990,7 +2021,7 @@ int multi_update::do_updates() TRG_ACTION_BEFORE, TRUE)) goto err2; - if (!can_compare_record || compare_record(table)) + if (!records_are_comparable(table) || compare_records(table)) { int error; if ((error= cur_table->view_check_option(thd, ignore)) != diff --git a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c index a64dd3151ee..ecc5b47d377 100644 --- a/storage/innobase/row/row0sel.c +++ b/storage/innobase/row/row0sel.c @@ -2621,12 +2621,6 @@ row_sel_store_mysql_rec( prebuilt->blob_heap = NULL; } - /* init null bytes with default values as they might be - left uninitialized in some cases and this uninited bytes - might be copied into mysql record buffer that leads to - valgrind warnings */ - memcpy(mysql_rec, prebuilt->default_rec, prebuilt->null_bitmap_len); - for (i = 0; i < prebuilt->n_template; i++) { templ = prebuilt->mysql_template + i; diff --git a/storage/innodb_plugin/row/row0sel.c b/storage/innodb_plugin/row/row0sel.c index 8b17bdc6ad3..b19651735d8 100644 --- a/storage/innodb_plugin/row/row0sel.c +++ b/storage/innodb_plugin/row/row0sel.c @@ -2696,12 +2696,6 @@ row_sel_store_mysql_rec( prebuilt->blob_heap = NULL; } - /* init null bytes with default values as they might be - left uninitialized in some cases and these uninited bytes - might be copied into mysql record buffer that leads to - valgrind warnings */ - memcpy(mysql_rec, prebuilt->default_rec, prebuilt->null_bitmap_len); - for (i = 0; i < prebuilt->n_template; i++) { templ = prebuilt->mysql_template + i; From 455d1f6ade5070f7ffa81e355bc3715bed1d92ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20Bl=C3=A5udd?= Date: Thu, 7 Oct 2010 11:02:16 +0200 Subject: [PATCH 08/11] WL#5503 SEAGULL: Move config/ac-macros/ha_ndbcluster.m4 to storage/ndb/ - Move file ha_ndbcluster.m4 - Move "sinclude" directive from configure.in to storag/ndb/plug.in --- configure.in | 1 - .../ac-macros/ha_ndbcluster.m4 => storage/ndb/ndb_configure.m4 | 0 storage/ndb/plug.in | 2 ++ 3 files changed, 2 insertions(+), 1 deletion(-) rename config/ac-macros/ha_ndbcluster.m4 => storage/ndb/ndb_configure.m4 (100%) diff --git a/configure.in b/configure.in index a5fe8d292da..c272efe9214 100644 --- a/configure.in +++ b/configure.in @@ -87,7 +87,6 @@ sinclude(config/ac-macros/character_sets.m4) sinclude(config/ac-macros/compiler_flag.m4) sinclude(config/ac-macros/plugins.m4) sinclude(config/ac-macros/dtrace.m4) -sinclude(config/ac-macros/ha_ndbcluster.m4) sinclude(config/ac-macros/large_file.m4) sinclude(config/ac-macros/misc.m4) sinclude(config/ac-macros/readline.m4) diff --git a/config/ac-macros/ha_ndbcluster.m4 b/storage/ndb/ndb_configure.m4 similarity index 100% rename from config/ac-macros/ha_ndbcluster.m4 rename to storage/ndb/ndb_configure.m4 diff --git a/storage/ndb/plug.in b/storage/ndb/plug.in index a7e351417b1..d3395b66771 100644 --- a/storage/ndb/plug.in +++ b/storage/ndb/plug.in @@ -1,3 +1,5 @@ +sinclude(storage/ndb/ndb_configure.m4) + MYSQL_STORAGE_ENGINE(ndbcluster, ndbcluster, [Cluster Storage Engine], [High Availability Clustered tables], [max]) MYSQL_PLUGIN_DIRECTORY(ndbcluster,[storage/ndb]) From ef7300b838c0a9637912d3cc581873b21951094d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20Bl=C3=A5udd?= Date: Thu, 7 Oct 2010 11:13:30 +0200 Subject: [PATCH 09/11] Bug#56397 The version of NDB in MySQL Server should be constant - Fix the version of NDB in MySQL Server to 5.5.7(although it's actually 6.2.18) --- storage/ndb/ndb_configure.m4 | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/storage/ndb/ndb_configure.m4 b/storage/ndb/ndb_configure.m4 index 533dba09feb..21e4627515f 100644 --- a/storage/ndb/ndb_configure.m4 +++ b/storage/ndb/ndb_configure.m4 @@ -2,10 +2,16 @@ dnl --------------------------------------------------------------------------- dnl Macro: MYSQL_CHECK_NDBCLUSTER dnl --------------------------------------------------------------------------- -NDB_VERSION_MAJOR=`echo $MYSQL_NUMERIC_VERSION | cut -d. -f1` -NDB_VERSION_MINOR=`echo $MYSQL_NUMERIC_VERSION | cut -d. -f2` -NDB_VERSION_BUILD=`echo $MYSQL_NUMERIC_VERSION | cut -d. -f3` -NDB_VERSION_STATUS=`echo $VERSION | sed 's/^[[-.0-9]]*//'` +# The version of NDB in this version of MySQL is currently fixed +# and not supposed to be changed unless major changes happen in +# storage/ndb directory. +# NOTE! To avoid mixup with MySQL Cluster's version numbers +# this version of NDB is set to 5.5.7 although it's basically +# a copy of MySQL Cluster 6.2.18 +NDB_VERSION_MAJOR=5 +NDB_VERSION_MINOR=5 +NDB_VERSION_BUILD=7 +NDB_VERSION_STATUS="" TEST_NDBCLUSTER="" dnl for build ndb docs From d6ee2ecf90b8ad7110bef3aae9d447b8908f8cfb Mon Sep 17 00:00:00 2001 From: Martin Hansson Date: Thu, 7 Oct 2010 12:01:51 +0200 Subject: [PATCH 10/11] Bug#56423: Different count with SELECT and CREATE SELECT queries This is the 5.5 version of the fix. The 5.1 version was too complicated to merge and was null merged. This is a regression from the fix for bug no 38999. A storage engine capable of reading only a subset of a table's columns updates corresponding bits in the read buffer to signal that it has read NULL values for the corresponding columns. It cannot, and should not, update any other bits. Bug no 38999 occurred because the implementation of UPDATE statements compare the NULL bits using memcmp, inadvertently comparing bits that were never requested from the storage engine. The regression was caused by the storage engine trying to alleviate the situation by writing to all NULL bits, even those that it had no knowledge of. This has devastating effects for the index merge algorithm, which relies on all NULL bits, except those explicitly requested, being left unchanged. The fix reverts the fix for bug no 38999 in both InnoDB and InnoDB plugin and changes the server's method of comparing records. For engines that always read entire rows, we proceed as usual. For engines capable of reading only select columns, the record buffers are now compared on a column by column basis. An assertion was also added so that non comparable buffers are never read. Some relevant copy-pasted code was also consolidated in a new function. --- mysql-test/include/index_merge2.inc | 112 +++++++++++++++++++++++++ mysql-test/r/index_merge_myisam.result | 55 ++++++++++++ sql/sql_insert.cc | 4 +- sql/sql_update.cc | 93 +++++++++++++------- sql/sql_update.h | 3 +- storage/innobase/row/row0sel.c | 6 -- 6 files changed, 232 insertions(+), 41 deletions(-) diff --git a/mysql-test/include/index_merge2.inc b/mysql-test/include/index_merge2.inc index 9b98eb3ebf2..23c8c6466c7 100644 --- a/mysql-test/include/index_merge2.inc +++ b/mysql-test/include/index_merge2.inc @@ -351,3 +351,115 @@ explain select * from t1 where (key3 > 30 and key3<35) or (key2 >32 and key2 < 4 select * from t1 where (key3 > 30 and key3<35) or (key2 >32 and key2 < 40); drop table t1; +--echo # +--echo # Bug#56423: Different count with SELECT and CREATE SELECT queries +--echo # + +CREATE TABLE t1 ( + a INT, + b INT, + c INT, + d INT, + PRIMARY KEY (a), + KEY (c), + KEY bd (b,d) +); + +INSERT INTO t1 VALUES +(1, 0, 1, 0), +(2, 1, 1, 1), +(3, 1, 1, 1), +(4, 0, 1, 1); + +EXPLAIN +SELECT a +FROM t1 +WHERE c = 1 AND b = 1 AND d = 1; + +CREATE TABLE t2 ( a INT ) +SELECT a +FROM t1 +WHERE c = 1 AND b = 1 AND d = 1; + +SELECT * FROM t2; + +DROP TABLE t1, t2; + +CREATE TABLE t1( a INT, b INT, KEY(a), KEY(b) ); +INSERT INTO t1 VALUES (1, 2), (1, 2), (1, 2), (1, 2); +SELECT * FROM t1 FORCE INDEX(a, b) WHERE a = 1 AND b = 2; + +DROP TABLE t1; + +--echo # Code coverage of fix. +CREATE TABLE t1 ( a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b INT); +INSERT INTO t1 (b) VALUES (1); +UPDATE t1 SET b = 2 WHERE a = 1; +SELECT * FROM t1; + +CREATE TABLE t2 ( a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b VARCHAR(1) ); +INSERT INTO t2 (b) VALUES ('a'); +UPDATE t2 SET b = 'b' WHERE a = 1; +SELECT * FROM t2; + +DROP TABLE t1, t2; + +# The test was inactive for InnoDB at the time of pushing. The following is +# expected result for the Bug#56423 test. It can be uncommented and pasted +# into result file when reactivating the test. + +## +## Bug#56423: Different count with SELECT and CREATE SELECT queries +## +#CREATE TABLE t1 ( +#a INT, +#b INT, +#c INT, +#d INT, +#PRIMARY KEY (a), +#KEY (c), +#KEY bd (b,d) +#); +#INSERT INTO t1 VALUES +#(1, 0, 1, 0), +#(2, 1, 1, 1), +#(3, 1, 1, 1), +#(4, 0, 1, 1); +#EXPLAIN +#SELECT a +#FROM t1 +#WHERE c = 1 AND b = 1 AND d = 1; +#id select_type table type possible_keys key key_len ref rows Extra +#1 SIMPLE t1 ref c,bd bd 10 const,const 2 Using where +#CREATE TABLE t2 ( a INT ) +#SELECT a +#FROM t1 +#WHERE c = 1 AND b = 1 AND d = 1; +#SELECT * FROM t2; +#a +#2 +#3 +#DROP TABLE t1, t2; +#CREATE TABLE t1( a INT, b INT, KEY(a), KEY(b) ); +#INSERT INTO t1 VALUES (1, 2), (1, 2), (1, 2), (1, 2); +#SELECT * FROM t1 FORCE INDEX(a, b) WHERE a = 1 AND b = 2; +#a b +#1 2 +#1 2 +#1 2 +#1 2 +#DROP TABLE t1; +## Code coverage of fix. +#CREATE TABLE t1 ( a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b INT); +#INSERT INTO t1 (b) VALUES (1); +#UPDATE t1 SET b = 2 WHERE a = 1; +#SELECT * FROM t1; +#a b +#1 2 +#CREATE TABLE t2 ( a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b VARCHAR(1) ); +#INSERT INTO t2 (b) VALUES ('a'); +#UPDATE t2 SET b = 'b' WHERE a = 1; +#SELECT * FROM t2; +#a b +#1 b +#DROP TABLE t1, t2; diff --git a/mysql-test/r/index_merge_myisam.result b/mysql-test/r/index_merge_myisam.result index 7377b450872..cfe0c841c0c 100644 --- a/mysql-test/r/index_merge_myisam.result +++ b/mysql-test/r/index_merge_myisam.result @@ -1156,6 +1156,61 @@ key1 key2 key3 38 38 38 39 39 39 drop table t1; +# +# Bug#56423: Different count with SELECT and CREATE SELECT queries +# +CREATE TABLE t1 ( +a INT, +b INT, +c INT, +d INT, +PRIMARY KEY (a), +KEY (c), +KEY bd (b,d) +); +INSERT INTO t1 VALUES +(1, 0, 1, 0), +(2, 1, 1, 1), +(3, 1, 1, 1), +(4, 0, 1, 1); +EXPLAIN +SELECT a +FROM t1 +WHERE c = 1 AND b = 1 AND d = 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref c,bd bd 10 const,const 2 Using where +CREATE TABLE t2 ( a INT ) +SELECT a +FROM t1 +WHERE c = 1 AND b = 1 AND d = 1; +SELECT * FROM t2; +a +2 +3 +DROP TABLE t1, t2; +CREATE TABLE t1( a INT, b INT, KEY(a), KEY(b) ); +INSERT INTO t1 VALUES (1, 2), (1, 2), (1, 2), (1, 2); +SELECT * FROM t1 FORCE INDEX(a, b) WHERE a = 1 AND b = 2; +a b +1 2 +1 2 +1 2 +1 2 +DROP TABLE t1; +# Code coverage of fix. +CREATE TABLE t1 ( a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b INT); +INSERT INTO t1 (b) VALUES (1); +UPDATE t1 SET b = 2 WHERE a = 1; +SELECT * FROM t1; +a b +1 2 +CREATE TABLE t2 ( a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b VARCHAR(1) ); +INSERT INTO t2 (b) VALUES ('a'); +UPDATE t2 SET b = 'b' WHERE a = 1; +SELECT * FROM t2; +a b +1 b +DROP TABLE t1, t2; #---------------- 2-sweeps read Index merge test 2 ------------------------------- SET SESSION STORAGE_ENGINE = MyISAM; drop table if exists t1; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 3ac6cf28c90..1f8da3fab5c 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1620,9 +1620,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) table->file->adjust_next_insert_id_after_explicit_value( table->next_number_field->val_int()); info->touched++; - if ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ && - !bitmap_is_subset(table->write_set, table->read_set)) || - compare_record(table)) + if (!records_are_comparable(table) || compare_records(table)) { if ((error=table->file->ha_update_row(table->record[1], table->record[0])) && diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 68440f6623a..96b1ac67b49 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -42,11 +42,68 @@ // mysql_handle_derived, // mysql_derived_filling -/* Return 0 if row hasn't changed */ -bool compare_record(TABLE *table) +/** + True if the table's input and output record buffers are comparable using + compare_records(TABLE*). + */ +bool records_are_comparable(const TABLE *table) { + return ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) == 0) || + bitmap_is_subset(table->write_set, table->read_set); +} + + +/** + Compares the input and outbut record buffers of the table to see if a row + has changed. The algorithm iterates over updated columns and if they are + nullable compares NULL bits in the buffer before comparing actual + data. Special care must be taken to compare only the relevant NULL bits and + mask out all others as they may be undefined. The storage engine will not + and should not touch them. + + @param table The table to evaluate. + + @return true if row has changed. + @return false otherwise. +*/ +bool compare_records(const TABLE *table) { + DBUG_ASSERT(records_are_comparable(table)); + + if ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) != 0) + { + /* + Storage engine may not have read all columns of the record. Fields + (including NULL bits) not in the write_set may not have been read and + can therefore not be compared. + */ + for (Field **ptr= table->field ; *ptr != NULL; ptr++) + { + Field *field= *ptr; + if (bitmap_is_set(table->write_set, field->field_index)) + { + if (field->real_maybe_null()) + { + uchar null_byte_index= field->null_ptr - table->record[0]; + + if (((table->record[0][null_byte_index]) & field->null_bit) != + ((table->record[1][null_byte_index]) & field->null_bit)) + return TRUE; + } + if (field->cmp_binary_offset(table->s->rec_buff_length)) + return TRUE; + } + } + return FALSE; + } + + /* + The storage engine has read all columns, so it's safe to compare all bits + including those not in the write_set. This is cheaper than the field-by-field + comparison done above. + */ if (table->s->blob_fields + table->s->varchar_fields == 0) + // Fixed-size record: do bitwise comparison of the records return cmp_record(table,record[1]); /* Compare null bits */ if (memcmp(table->null_flags, @@ -204,7 +261,6 @@ int mysql_update(THD *thd, bool using_limit= limit != HA_POS_ERROR; bool safe_update= test(thd->variables.option_bits & OPTION_SAFE_UPDATES); bool used_key_is_modified= FALSE, transactional_table, will_batch; - bool can_compare_record; int res; int error, loc_error; uint used_index, dup_key_found; @@ -579,15 +635,6 @@ int mysql_update(THD *thd, if (table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) table->prepare_for_position(); - /* - We can use compare_record() to optimize away updates if - the table handler is returning all columns OR if - if all updated columns are read - */ - can_compare_record= (!(table->file->ha_table_flags() & - HA_PARTIAL_COLUMN_READ) || - bitmap_is_subset(table->write_set, table->read_set)); - while (!(error=info.read_record(&info)) && !thd->killed) { thd->examined_row_count++; @@ -605,7 +652,7 @@ int mysql_update(THD *thd, found++; - if (!can_compare_record || compare_record(table)) + if (!records_are_comparable(table) || compare_records(table)) { if ((res= table_list->view_check_option(thd, ignore)) != VIEW_CHECK_OK) @@ -1645,18 +1692,8 @@ bool multi_update::send_data(List ¬_used_values) if (table->status & (STATUS_NULL_ROW | STATUS_UPDATED)) continue; - /* - We can use compare_record() to optimize away updates if - the table handler is returning all columns OR if - if all updated columns are read - */ if (table == table_to_update) { - bool can_compare_record; - can_compare_record= (!(table->file->ha_table_flags() & - HA_PARTIAL_COLUMN_READ) || - bitmap_is_subset(table->write_set, - table->read_set)); table->status|= STATUS_UPDATED; store_record(table,record[1]); if (fill_record_n_invoke_before_triggers(thd, *fields_for_table[offset], @@ -1671,7 +1708,7 @@ bool multi_update::send_data(List ¬_used_values) */ table->auto_increment_field_not_null= FALSE; found++; - if (!can_compare_record || compare_record(table)) + if (!records_are_comparable(table) || compare_records(table)) { int error; if ((error= cur_table->view_check_option(thd, ignore)) != @@ -1860,7 +1897,6 @@ int multi_update::do_updates() DBUG_RETURN(0); for (cur_table= update_tables; cur_table; cur_table= cur_table->next_local) { - bool can_compare_record; uint offset= cur_table->shared; table = cur_table->table; @@ -1897,11 +1933,6 @@ int multi_update::do_updates() if ((local_error = tmp_table->file->ha_rnd_init(1))) goto err; - can_compare_record= (!(table->file->ha_table_flags() & - HA_PARTIAL_COLUMN_READ) || - bitmap_is_subset(table->write_set, - table->read_set)); - for (;;) { if (thd->killed && trans_safe) @@ -1942,7 +1973,7 @@ int multi_update::do_updates() TRG_ACTION_BEFORE, TRUE)) goto err2; - if (!can_compare_record || compare_record(table)) + if (!records_are_comparable(table) || compare_records(table)) { int error; if ((error= cur_table->view_check_option(thd, ignore)) != diff --git a/sql/sql_update.h b/sql/sql_update.h index 6bf022a171c..50ff50f025d 100644 --- a/sql/sql_update.h +++ b/sql/sql_update.h @@ -38,6 +38,7 @@ bool mysql_multi_update(THD *thd, TABLE_LIST *table_list, enum enum_duplicates handle_duplicates, bool ignore, SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex, multi_update **result); -bool compare_record(TABLE *table); +bool records_are_comparable(const TABLE *table); +bool compare_records(const TABLE *table); #endif /* SQL_UPDATE_INCLUDED */ diff --git a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c index 61ef4edb7a6..0bbca7c2147 100644 --- a/storage/innobase/row/row0sel.c +++ b/storage/innobase/row/row0sel.c @@ -2688,12 +2688,6 @@ row_sel_store_mysql_rec( prebuilt->blob_heap = NULL; } - /* init null bytes with default values as they might be - left uninitialized in some cases and these uninited bytes - might be copied into mysql record buffer that leads to - valgrind warnings */ - memcpy(mysql_rec, prebuilt->default_rec, prebuilt->null_bitmap_len); - for (i = 0; i < prebuilt->n_template; i++) { templ = prebuilt->mysql_template + i; From 2913b025daaa62f376529d70acd4328d171c64f6 Mon Sep 17 00:00:00 2001 From: Calvin Sun Date: Thu, 7 Oct 2010 06:00:22 -0500 Subject: [PATCH 11/11] bug#56318: adjust the result files. --- mysql-test/suite/innodb/r/innodb-index.result | 6 +++--- mysql-test/suite/innodb/r/innodb-zip.result | 4 ++-- mysql-test/suite/innodb/r/innodb_bug52745.result | 4 ++-- mysql-test/suite/innodb/r/innodb_bug53591.result | 4 ++-- mysql-test/suite/innodb/r/innodb_file_format.result | 8 ++++---- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/mysql-test/suite/innodb/r/innodb-index.result b/mysql-test/suite/innodb/r/innodb-index.result index 1aeca2c226a..e43f70a2365 100644 --- a/mysql-test/suite/innodb/r/innodb-index.result +++ b/mysql-test/suite/innodb/r/innodb-index.result @@ -918,9 +918,9 @@ ERROR HY000: Too big row alter table t1 row_format=compact; create index t1u on t1 (u(1)); drop table t1; -set global innodb_file_per_table=1; -set global innodb_file_format=Barracuda; -set global innodb_file_format_max=Barracuda; +set global innodb_file_per_table=0; +set global innodb_file_format=Antelope; +set global innodb_file_format_max=Antelope; SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0; SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; CREATE TABLE t1( diff --git a/mysql-test/suite/innodb/r/innodb-zip.result b/mysql-test/suite/innodb/r/innodb-zip.result index da2be2bb07d..18fdb63d889 100644 --- a/mysql-test/suite/innodb/r/innodb-zip.result +++ b/mysql-test/suite/innodb/r/innodb-zip.result @@ -394,8 +394,8 @@ table_schema table_name row_format test t8 Compact test t9 Redundant drop table t8, t9; -set global innodb_file_per_table=1; -set global innodb_file_format=Barracuda; +set global innodb_file_per_table=0; +set global innodb_file_format=Antelope; set global innodb_file_per_table=on; set global innodb_file_format=`Barracuda`; set global innodb_file_format_max=`Antelope`; diff --git a/mysql-test/suite/innodb/r/innodb_bug52745.result b/mysql-test/suite/innodb/r/innodb_bug52745.result index 16dd356997e..d746fb427b5 100644 --- a/mysql-test/suite/innodb/r/innodb_bug52745.result +++ b/mysql-test/suite/innodb/r/innodb_bug52745.result @@ -125,6 +125,6 @@ Warning 1264 Out of range value for column 'col78' at row 1 Warning 1265 Data truncated for column 'col79' at row 1 Warning 1264 Out of range value for column 'col84' at row 1 DROP TABLE bug52745; -SET GLOBAL innodb_file_format=Barracuda; +SET GLOBAL innodb_file_format=Antelope; SET GLOBAL innodb_file_format_max=Antelope; -SET GLOBAL innodb_file_per_table=1; +SET GLOBAL innodb_file_per_table=0; diff --git a/mysql-test/suite/innodb/r/innodb_bug53591.result b/mysql-test/suite/innodb/r/innodb_bug53591.result index 8573fb60718..d3f8dfeafc2 100644 --- a/mysql-test/suite/innodb/r/innodb_bug53591.result +++ b/mysql-test/suite/innodb/r/innodb_bug53591.result @@ -11,6 +11,6 @@ Error 139 Too big row Error 1118 Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs Error 1030 Got error 139 from storage engine DROP TABLE bug53591; -SET GLOBAL innodb_file_format=Barracuda; +SET GLOBAL innodb_file_format=Antelope; SET GLOBAL innodb_file_format_max=Antelope; -SET GLOBAL innodb_file_per_table=1; +SET GLOBAL innodb_file_per_table=0; diff --git a/mysql-test/suite/innodb/r/innodb_file_format.result b/mysql-test/suite/innodb/r/innodb_file_format.result index 447e13f0d60..70cfc9e4f47 100644 --- a/mysql-test/suite/innodb/r/innodb_file_format.result +++ b/mysql-test/suite/innodb/r/innodb_file_format.result @@ -1,6 +1,6 @@ select @@innodb_file_format; @@innodb_file_format -Barracuda +Antelope select @@innodb_file_format_check; @@innodb_file_format_check 1 @@ -17,14 +17,14 @@ Barracuda set global innodb_file_format=default; select @@innodb_file_format; @@innodb_file_format -Barracuda +Antelope set global innodb_file_format=on; ERROR 42000: Variable 'innodb_file_format' can't be set to the value of 'ON' set global innodb_file_format=off; ERROR 42000: Variable 'innodb_file_format' can't be set to the value of 'off' select @@innodb_file_format; @@innodb_file_format -Barracuda +Antelope set global innodb_file_format_max=antelope; set global innodb_file_format_max=barracuda; set global innodb_file_format_max=cheetah; @@ -46,5 +46,5 @@ Antelope set global innodb_file_format_max=antelope; set global innodb_file_format_check=off; ERROR HY000: Variable 'innodb_file_format_check' is a read only variable -SET GLOBAL innodb_file_format=Barracuda; +SET GLOBAL innodb_file_format=Antelope; SET GLOBAL innodb_file_format_max=Antelope;