diff options
author | Georgi Kodinov <Georgi.Kodinov@Oracle.com> | 2011-06-06 16:53:46 +0300 |
---|---|---|
committer | Georgi Kodinov <Georgi.Kodinov@Oracle.com> | 2011-06-06 16:53:46 +0300 |
commit | 1dcd90b80b105422052a130937131f149d61e583 (patch) | |
tree | 6f31262b2aae660a5536bb962c312d14b320ed47 | |
parent | dd7e8529e0901d8ac69fef7cb0ad7c003d20a7ed (diff) | |
parent | b502a64bba3143a77632042f02876086ab7dff7b (diff) | |
download | mariadb-git-1dcd90b80b105422052a130937131f149d61e583.tar.gz |
merge of mysql-5.1->mysql-5.1-security
81 files changed, 1599 insertions, 456 deletions
diff --git a/configure.in b/configure.in index 8ba208b1ef5..901515fecb6 100644 --- a/configure.in +++ b/configure.in @@ -2042,12 +2042,7 @@ MYSQL_TYPE_QSORT AC_FUNC_UTIME_NULL AC_FUNC_VPRINTF -AC_CHECK_DECLS([fdatasync],,, -[ -#ifdef HAVE_UNISTD_H -# include <unistd.h> -#endif -]) +AC_CHECK_DECLS([fdatasync, bzero]) AC_CHECK_FUNCS(alarm bfill bmove bsearch bzero \ chsize cuserid fchmod fcntl \ @@ -2066,7 +2061,8 @@ AC_CHECK_FUNCS(alarm bfill bmove bsearch bzero \ sighold sigset sigthreadmask port_create sleep \ snprintf socket stpcpy strcasecmp strerror strsignal strnlen strpbrk strstr \ strtol strtoll strtoul strtoull tell tempnam thr_setconcurrency vidattr \ - posix_fallocate backtrace backtrace_symbols backtrace_symbols_fd printstack) + posix_fallocate backtrace backtrace_symbols backtrace_symbols_fd printstack \ + fedisableexcept) # # diff --git a/include/m_string.h b/include/m_string.h index 0d248ea0ad3..53572a4ac9e 100644 --- a/include/m_string.h +++ b/include/m_string.h @@ -58,7 +58,7 @@ # define bfill(A,B,C) memset((A),(C),(B)) #endif -#if !defined(bzero) && !defined(HAVE_BZERO) +#if !defined(bzero) && (!defined(HAVE_BZERO) || !defined(HAVE_DECL_BZERO)) # define bzero(A,B) memset((A),0,(B)) #endif diff --git a/include/my_getopt.h b/include/my_getopt.h index d7c996302fd..a379e8c4716 100644 --- a/include/my_getopt.h +++ b/include/my_getopt.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2004 MySQL AB +/* Copyright (c) 2002, 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 @@ -11,7 +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 */ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _my_getopt_h #define _my_getopt_h @@ -59,7 +59,9 @@ struct my_option }; typedef my_bool (*my_get_one_option)(int, const struct my_option *, char *); -typedef void (*my_error_reporter)(enum loglevel level, const char *format, ...); +typedef void (*my_error_reporter)(enum loglevel level, const char *format, ...) + ATTRIBUTE_FORMAT_FPTR(printf, 2, 3); + /** Used to retrieve a reference to the object (variable) that holds the value for the given option. For example, if var_type is GET_UINT, the function diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 778d4874ad4..b6da6172039 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -51,6 +51,23 @@ extern "C" void unireg_clear(int exit_code) DBUG_VOID_RETURN; } +/* + Wrapper error handler for embedded server to call client/server error + handler based on whether thread is in client/server context +*/ + +static int embedded_error_handler(uint error, const char *str, myf MyFlags) +{ + DBUG_ENTER("embedded_error_handler"); + + /* + If current_thd is NULL, it means restore_global has been called and + thread is in client context, then call client error handler else call + server error handler. + */ + DBUG_RETURN(current_thd ? my_message_sql(error, str, MyFlags): + my_message_no_curses(error, str, MyFlags)); +} /* Reads error information from the MYSQL_DATA and puts @@ -107,7 +124,8 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command, if (mysql->status != MYSQL_STATUS_READY) { set_mysql_error(mysql, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate); - return 1; + result= 1; + goto end; } /* Clear result variables */ @@ -147,6 +165,9 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command, #if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER) thd->profiling.finish_current_query(); #endif + +end: + thd->restore_globals(); return result; } @@ -525,7 +546,10 @@ int init_embedded_server(int argc, char **argv, char **groups) return 1; } - error_handler_hook = my_message_sql; + /* + set error_handler_hook to embedded_error_handler wrapper. + */ + error_handler_hook= embedded_error_handler; acl_error= 0; #ifndef NO_EMBEDDED_ACCESS_CHECKS diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am index f3b4343f9a0..aa4c8bad141 100644 --- a/mysql-test/Makefile.am +++ b/mysql-test/Makefile.am @@ -80,7 +80,6 @@ TEST_DIRS = t r include std_data std_data/parts collections \ std_data/funcs_1 \ extra/binlog_tests/ extra/rpl_tests \ suite/binlog suite/binlog/t suite/binlog/r suite/binlog/std_data \ - suite/bugs suite/bugs/data suite/bugs/t suite/bugs/r \ suite/federated \ suite/funcs_1 suite/funcs_1/bitdata \ suite/funcs_1/include suite/funcs_1/lib suite/funcs_1/r \ diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index fb8c6845a5f..8883acfa606 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -2,7 +2,6 @@ # in alphabetical order. This also helps with merge conflict resolution. binlog.binlog_multi_engine # joro : NDB tests marked as experimental as agreed with bochklin -binlog.binlog_bug23533 # skozlov: BUG#12371924 funcs_1.charset_collation_1 # depends on compile-time decisions @@ -14,21 +13,22 @@ funcs_1.ndb* # joro : NDB tests marked as experiment funcs_2.ndb_charset # joro : NDB tests marked as experimental as agreed with bochklin -innodb_plugin.* @solaris # Bug#56063 InnoDB Plugin mysql-tests fail on Solaris +innodb_plugin.* @solaris # Bug#11763366 InnoDB Plugin mysql-tests fail on Solaris + +main.ctype_gbk_binlog @solaris # Bug#11754407: main.ctype_gbk_binlog fails sporadically : Table 't2' already exists +main.func_str @solaris # joro: Bug#11750406 +main.sp @solaris # joro : Bug#11761625 +main.query_cache_28249 # Bug#12584161 2009-03-25 main.query_cache_28249 fails sporadically -main.ctype_gbk_binlog @solaris # Bug#46010: main.ctype_gbk_binlog fails sporadically : Table 't2' already exists -main.func_str @solaris # joro: Bug#40928 -main.sp @solaris # joro : Bug#54138 -main.outfile_loaddata @solaris # joro : Bug #46895 ndb.* # joro : NDB tests marked as experimental as agreed with bochklin -rpl.rpl_innodb_bug28430 @solaris # Bug#46029 -rpl.rpl_row_sp011 @solaris # Joro : Bug #45445 +rpl.rpl_innodb_bug28430 @solaris # Bug#11754425 +rpl.rpl_row_sp011 @solaris # Joro : Bug #11753919 rpl.rpl_stop_slave # Sven : BUG#12345981 rpl_ndb.* # joro : NDB tests marked as experimental as agreed with bochklin -rpl_ndb.rpl_ndb_log # Bug#38998 +rpl_ndb.rpl_ndb_log # Bug#11749433 stress.ddl_ndb # joro : NDB tests marked as experimental as agreed with bochklin @@ -46,6 +46,3 @@ parts.partition_mgm_lc1_ndb # joro : NDB tests marked as experiment parts.partition_mgm_lc2_ndb # joro : NDB tests marked as experimental as agreed with bochklin parts.partition_syntax_ndb # joro : NDB tests marked as experimental as agreed with bochklin parts.partition_value_ndb # joro : NDB tests marked as experimental as agreed with bochklin -main.gis-rtree # svoj: due to BUG#38965 -main.type_float # svoj: due to BUG#38965 -main.type_newdecimal # svoj: due to BUG#38965 diff --git a/mysql-test/r/archive_debug.result b/mysql-test/r/archive_debug.result new file mode 100644 index 00000000000..cc5a3761a99 --- /dev/null +++ b/mysql-test/r/archive_debug.result @@ -0,0 +1,12 @@ +# +# BUG#12402794 - 60976: CRASH, VALGRIND WARNING AND MEMORY LEAK +# WITH PARTITIONED ARCHIVE TABLES +# +CREATE TABLE t1(a INT) ENGINE=ARCHIVE; +INSERT INTO t1 VALUES(1); +SET SESSION debug='d,simulate_archive_open_failure'; +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check error Corrupt +SET SESSION debug=DEFAULT; +DROP TABLE t1; diff --git a/mysql-test/r/events_bugs.result b/mysql-test/r/events_bugs.result index dfb8f008c5a..740f94fb061 100644 --- a/mysql-test/r/events_bugs.result +++ b/mysql-test/r/events_bugs.result @@ -535,6 +535,7 @@ DROP EVENT e3; DROP EVENT e2; DROP EVENT e1; SET TIME_ZONE=@save_time_zone; +SET TIMESTAMP=DEFAULT; drop event if exists new_event; CREATE EVENT new_event ON SCHEDULE EVERY 0 SECOND DO SELECT 1; ERROR HY000: INTERVAL is either not positive or too big @@ -756,6 +757,45 @@ SHOW EVENTS; Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation DROP DATABASE event_test1; DROP DATABASE event_test12; +# +# Bug#12546938 (formerly known as bug#61005): +# CREATE IF NOT EXIST EVENT WILL CREATE MULTIPLE RUNNING EVENTS +# +USE events_test; +SET GLOBAL event_scheduler = ON; +DROP TABLE IF EXISTS table_bug12546938; +DROP EVENT IF EXISTS event_Bug12546938; +CREATE TABLE table_bug12546938 (i INT); +# Create an event which will be executed with a small delay +# and won't be automatically dropped after that. +CREATE EVENT event_Bug12546938 +ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 SECOND ON COMPLETION PRESERVE +ENABLE DO +BEGIN +INSERT INTO table_bug12546938 VALUES(1); +END +| +# Now try to create the same event using CREATE EVENT IF NOT EXISTS. +# A warning should be emitted. A new event should not be created nor +# the old event should be re-executed. +CREATE EVENT IF NOT EXISTS event_bug12546938 +ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 SECOND ON COMPLETION PRESERVE +ENABLE DO +BEGIN +INSERT INTO table_bug12546938 VALUES (1); +END +| +Warnings: +Note 1537 Event 'event_bug12546938' already exists +# Wait until at least one instance of event is executed. +# Check that only one instance of our event was executed. +SELECT COUNT(*) FROM table_bug12546938; +COUNT(*) +1 +# Clean-up. +DROP EVENT IF EXISTS event_Bug12546938; +DROP TABLE table_bug12546938; +SET GLOBAL EVENT_SCHEDULER = OFF; DROP DATABASE events_test; SET GLOBAL event_scheduler= 'ON'; SET @@global.concurrent_insert= @concurrent_insert; diff --git a/mysql-test/r/func_math.result b/mysql-test/r/func_math.result index b9118feab1a..4e3608240d4 100644 --- a/mysql-test/r/func_math.result +++ b/mysql-test/r/func_math.result @@ -540,4 +540,10 @@ ROUND(LEAST(15, -4939092, 0.2704), STDDEV('a')) -4939092.0000 Warnings: Warning 1292 Truncated incorrect DOUBLE value: 'a' +# +# Bug#12392636 ASSERTION FAILED: SCALE >= 0 && PRECISION > 0 && SCALE <= PRECISION +# +SELECT SUM(DISTINCT (TRUNCATE((.1), NULL))); +SUM(DISTINCT (TRUNCATE((.1), NULL))) +NULL End of 5.1 tests diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index 1e05443d8ac..63744d4ef29 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -1417,4 +1417,13 @@ NULL SELECT DATE_FORMAT('0000-00-11', '%w'); DATE_FORMAT('0000-00-11', '%w') NULL +# +# Bug#12403504 AFTER FIX FOR #11889186 : ASSERTION FAILED: DELSUM+(INT) Y/4-TEMP > 0 +# +SELECT MAKEDATE(11111111,1); +MAKEDATE(11111111,1) +NULL +SELECT WEEK(DATE_ADD(FROM_DAYS(1),INTERVAL 1 MONTH), 1); +WEEK(DATE_ADD(FROM_DAYS(1),INTERVAL 1 MONTH), 1) +NULL End of 5.1 tests diff --git a/mysql-test/r/implicit_char_to_num_conversion.result b/mysql-test/r/implicit_char_to_num_conversion.result new file mode 100644 index 00000000000..8f24a6b293c --- /dev/null +++ b/mysql-test/r/implicit_char_to_num_conversion.result @@ -0,0 +1,366 @@ +DROP TABLE IF EXISTS t5; +CREATE TABLE t5(c1 BIT(2) PRIMARY KEY) ENGINE = <default_engine>; +INSERT INTO t5 VALUES (0), (1), (2); +SELECT HEX(c1) FROM t5 ORDER BY c1; +HEX(c1) +0 +1 +2 +SELECT HEX(c1) FROM t5 WHERE c1 = b'1' ORDER BY c1; +HEX(c1) +1 +SELECT HEX(c1) FROM t5 WHERE c1 <=> b'1' ORDER BY c1; +HEX(c1) +1 +SELECT HEX(c1) FROM t5 WHERE c1 != b'1' ORDER BY c1; +HEX(c1) +0 +2 +SELECT HEX(c1) FROM t5 WHERE c1 >= '1' ORDER BY c1; +HEX(c1) +1 +2 +SELECT HEX(c1) FROM t5 WHERE c1 <= '1' ORDER BY c1; +HEX(c1) +0 +1 +SELECT HEX(c1) FROM t5 WHERE c1 < '1' ORDER BY c1; +HEX(c1) +0 +SELECT HEX(c1) FROM t5 WHERE c1 > '0' ORDER BY c1; +HEX(c1) +1 +2 +DROP TABLE t5; +CREATE TABLE t5(c1 FLOAT(5,2) PRIMARY KEY) ENGINE = <default_engine>; +INSERT INTO t5 VALUES (95.95), (-10.10), (1), (0); +SELECT c1 FROM t5 ORDER BY c1; +c1 +-10.10 +0.00 +1.00 +95.95 +SELECT c1 FROM t5 WHERE c1 >= '95' ORDER BY c1; +c1 +95.95 +SELECT c1 FROM t5 WHERE c1 <= '10.10' ORDER BY c1; +c1 +-10.10 +0.00 +1.00 +SELECT c1 FROM t5 WHERE c1 != '1' ORDER BY c1; +c1 +-10.10 +0.00 +95.95 +SELECT c1 FROM t5 WHERE c1 < '1' ORDER BY c1; +c1 +-10.10 +0.00 +SELECT c1 FROM t5 WHERE c1 > '0' ORDER BY c1; +c1 +1.00 +95.95 +DROP TABLE t5; +CREATE TABLE t5(c1 TINYINT PRIMARY KEY) ENGINE = <default_engine>; +INSERT INTO t5 VALUES (95), (10),(11),(-8); +SELECT c1 FROM t5 ORDER BY c1; +c1 +-8 +10 +11 +95 +SELECT c1 FROM t5 WHERE c1 = '10' ORDER BY c1; +c1 +10 +SELECT c1 FROM t5 WHERE c1 <=> '10' ORDER BY c1; +c1 +10 +SELECT c1 FROM t5 WHERE c1 >= '95' ORDER BY c1; +c1 +95 +SELECT c1 FROM t5 WHERE c1 <= '11' ORDER BY c1; +c1 +-8 +10 +11 +SELECT c1 FROM t5 WHERE c1 != '-8' ORDER BY c1; +c1 +10 +11 +95 +SELECT c1 FROM t5 WHERE c1 < '11' ORDER BY c1; +c1 +-8 +10 +SELECT c1 FROM t5 WHERE c1 > '10' ORDER BY c1; +c1 +11 +95 +DROP TABLE t5; +CREATE TABLE t5(c1 SMALLINT PRIMARY KEY) ENGINE = <default_engine>; +INSERT INTO t5 VALUES (395), (-200), (100), (111); +SELECT c1 FROM t5 ORDER BY c1; +c1 +-200 +100 +111 +395 +SELECT c1 FROM t5 WHERE c1 = '100' ORDER BY c1; +c1 +100 +SELECT c1 FROM t5 WHERE c1 <=> '100' ORDER BY c1; +c1 +100 +SELECT c1 FROM t5 WHERE c1 >= '395' ORDER BY c1; +c1 +395 +SELECT c1 FROM t5 WHERE c1 <= '-200' ORDER BY c1; +c1 +-200 +SELECT c1 FROM t5 WHERE c1 != '100' ORDER BY c1; +c1 +-200 +111 +395 +SELECT c1 FROM t5 WHERE c1 < '111' ORDER BY c1; +c1 +-200 +100 +SELECT c1 FROM t5 WHERE c1 > '111' ORDER BY c1; +c1 +395 +DROP TABLE t5; +CREATE TABLE t5(c1 MEDIUMINT PRIMARY KEY) ENGINE = <default_engine>; +INSERT INTO t5 VALUES (-8388607), (311),(215),(88608); +SELECT c1 FROM t5 ORDER BY c1; +c1 +-8388607 +215 +311 +88608 +SELECT c1 FROM t5 WHERE c1 = '311' ORDER BY c1; +c1 +311 +SELECT c1 FROM t5 WHERE c1 <=> '311' ORDER BY c1; +c1 +311 +SELECT c1 FROM t5 WHERE c1 >= '215' ORDER BY c1; +c1 +215 +311 +88608 +SELECT c1 FROM t5 WHERE c1 <= '88608' ORDER BY c1; +c1 +-8388607 +215 +311 +88608 +SELECT c1 FROM t5 WHERE c1 != '-8388607' ORDER BY c1; +c1 +215 +311 +88608 +SELECT c1 FROM t5 WHERE c1 < '215' ORDER BY c1; +c1 +-8388607 +SELECT c1 FROM t5 WHERE c1 > '215' ORDER BY c1; +c1 +311 +88608 +DROP TABLE t5; +CREATE TABLE t5(c1 INT PRIMARY KEY) ENGINE = <default_engine>; +INSERT INTO t5 VALUES (-2147483647), (1011),(15),(9388607); +SELECT c1 FROM t5 ORDER BY c1; +c1 +-2147483647 +15 +1011 +9388607 +SELECT c1 FROM t5 WHERE c1 = '9388607' ORDER BY c1; +c1 +9388607 +SELECT c1 FROM t5 WHERE c1 <=> '9388607' ORDER BY c1; +c1 +9388607 +SELECT c1 FROM t5 WHERE c1 >= '15' ORDER BY c1; +c1 +15 +1011 +9388607 +SELECT c1 FROM t5 WHERE c1 <= '1011' ORDER BY c1; +c1 +-2147483647 +15 +1011 +SELECT c1 FROM t5 WHERE c1 != '-2147483647' ORDER BY c1; +c1 +15 +1011 +9388607 +SELECT c1 FROM t5 WHERE c1 < '15' ORDER BY c1; +c1 +-2147483647 +SELECT c1 FROM t5 WHERE c1 > '15' ORDER BY c1; +c1 +1011 +9388607 +DROP TABLE t5; +CREATE TABLE t5(c1 BIGINT PRIMARY KEY) ENGINE = <default_engine>; +INSERT INTO t5 VALUES (-9223372036854775807), (12011),(500),(3372036854775808); +SELECT c1 FROM t5 ORDER BY c1; +c1 +-9223372036854775807 +500 +12011 +3372036854775808 +SELECT c1 FROM t5 WHERE c1 = '-9223372036854775807' ORDER BY c1; +c1 +-9223372036854775807 +SELECT c1 FROM t5 WHERE c1 <=> '-9223372036854775807' ORDER BY c1; +c1 +-9223372036854775807 +SELECT c1 FROM t5 WHERE c1 >= '12011' ORDER BY c1; +c1 +12011 +3372036854775808 +SELECT c1 FROM t5 WHERE c1 <= '500' ORDER BY c1; +c1 +-9223372036854775807 +500 +SELECT c1 FROM t5 WHERE c1 != '3372036854775808' ORDER BY c1; +c1 +-9223372036854775807 +500 +12011 +SELECT c1 FROM t5 WHERE c1 < '12011' ORDER BY c1; +c1 +-9223372036854775807 +500 +SELECT c1 FROM t5 WHERE c1 > '12011' ORDER BY c1; +c1 +3372036854775808 +DROP TABLE t5; +CREATE TABLE t5(c1 DOUBLE(5,2) PRIMARY KEY) ENGINE = <default_engine>; +INSERT INTO t5 VALUES (95.95), (11.11),(5),(-908.92); +SELECT c1 FROM t5 ORDER BY c1; +c1 +-908.92 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 = '11.11' ORDER BY c1; +c1 +11.11 +SELECT c1 FROM t5 WHERE c1 <=> '11.11' ORDER BY c1; +c1 +11.11 +SELECT c1 FROM t5 WHERE c1 >= '5' ORDER BY c1; +c1 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 <= '95.95' ORDER BY c1; +c1 +-908.92 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 != '-908.92' ORDER BY c1; +c1 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 < '95.95' ORDER BY c1; +c1 +-908.92 +5.00 +11.11 +SELECT c1 FROM t5 WHERE c1 > '-908.92' ORDER BY c1; +c1 +5.00 +11.11 +95.95 +DROP TABLE t5; +CREATE TABLE t5(c1 NUMERIC(5,2) PRIMARY KEY) ENGINE = <default_engine>; +INSERT INTO t5 VALUES (95.95), (11.11),(5),(-908.92); +SELECT c1 FROM t5 ORDER BY c1; +c1 +-908.92 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 = '11.11' ORDER BY c1; +c1 +11.11 +SELECT c1 FROM t5 WHERE c1 <=> '11.11' ORDER BY c1; +c1 +11.11 +SELECT c1 FROM t5 WHERE c1 >= '5' ORDER BY c1; +c1 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 <= '95.95' ORDER BY c1; +c1 +-908.92 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 != '-908.92' ORDER BY c1; +c1 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 < '95.95' ORDER BY c1; +c1 +-908.92 +5.00 +11.11 +SELECT c1 FROM t5 WHERE c1 > '-908.92' ORDER BY c1; +c1 +5.00 +11.11 +95.95 +DROP TABLE t5; +CREATE TABLE t5(c1 DECIMAL(5,2) PRIMARY KEY) ENGINE = <default_engine>; +INSERT INTO t5 VALUES (95.95), (11.11),(5),(-908.92); +SELECT c1 FROM t5 ORDER BY c1; +c1 +-908.92 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 = '11.11' ORDER BY c1; +c1 +11.11 +SELECT c1 FROM t5 WHERE c1 <=> '11.11' ORDER BY c1; +c1 +11.11 +SELECT c1 FROM t5 WHERE c1 >= '5' ORDER BY c1; +c1 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 <= '95.95' ORDER BY c1; +c1 +-908.92 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 != '-908.92' ORDER BY c1; +c1 +5.00 +11.11 +95.95 +SELECT c1 FROM t5 WHERE c1 < '95.95' ORDER BY c1; +c1 +-908.92 +5.00 +11.11 +SELECT c1 FROM t5 WHERE c1 > '-908.92' ORDER BY c1; +c1 +5.00 +11.11 +95.95 +DROP TABLE t5; diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result index 70ee3a56cf3..c301a7dd629 100644 --- a/mysql-test/r/type_newdecimal.result +++ b/mysql-test/r/type_newdecimal.result @@ -1913,4 +1913,17 @@ group by PAY.id + 1; mult v_net_with_discount v_total 1.0000 27.18 27.180000 DROP TABLE currencies, payments, sub_tasks; +# +# Bug#55436: buffer overflow in debug binary of dbug_buff in +# Field_new_decimal::store_value +# +SET SQL_MODE=''; +CREATE TABLE t1(f1 DECIMAL(44,24)) ENGINE=MYISAM; +INSERT INTO t1 SET f1 = -64878E-85; +Warnings: +Note 1265 Data truncated for column 'f1' at row 1 +SELECT f1 FROM t1; +f1 +0.000000000000000000000000 +DROP TABLE IF EXISTS t1; End of 5.1 tests diff --git a/mysql-test/suite/binlog/r/binlog_reset_master.result b/mysql-test/suite/binlog/r/binlog_reset_master.result new file mode 100644 index 00000000000..b3d605560ff --- /dev/null +++ b/mysql-test/suite/binlog/r/binlog_reset_master.result @@ -0,0 +1 @@ +RESET MASTER; diff --git a/mysql-test/suite/binlog/t/binlog_bug23533.test b/mysql-test/suite/binlog/t/binlog_bug23533.test index c05abe788c6..ca610e399e4 100644 --- a/mysql-test/suite/binlog/t/binlog_bug23533.test +++ b/mysql-test/suite/binlog/t/binlog_bug23533.test @@ -35,7 +35,7 @@ connect(default,localhost,root,,test); # Copied data from t1 into t2 large than max_binlog_cache_size START TRANSACTION; ---error 1197 +--error ER_TRANS_CACHE_FULL CREATE TABLE t2 SELECT * FROM t1; COMMIT; SHOW TABLES LIKE 't%'; diff --git a/mysql-test/suite/binlog/t/binlog_reset_master.test b/mysql-test/suite/binlog/t/binlog_reset_master.test new file mode 100644 index 00000000000..b7ad69da3ea --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_reset_master.test @@ -0,0 +1,26 @@ +# ==== Purpose ==== +# +# Test bugs in RESET MASTER. + +--source include/have_debug.inc +--source include/have_log_bin.inc + +####################################################################### +# BUG#12574820: binlog.binlog_tmp_table timing out in daily and weekly trunk run +# Problem: MYSQL_BIN_LOG::reset_logs acquired LOCK_thread_count and +# LOCK_log in the wrong order. This could cause a deadlock when +# RESET MASTER was run concurrently with a disconnecting thread. +####################################################################### + +# We use sleep, not debug_sync, because the sync point needs to be in +# the thread shut down code after the debug sync facility has been +# shut down. +--let $write_var= SET DEBUG="+d,sleep_after_lock_thread_count_before_delete_thd"; CREATE TEMPORARY TABLE test.t1 (a INT); +--let $write_to_file= GENERATE +--disable_query_log +--source include/write_var_to_file.inc +--enable_query_log + +--exec $MYSQL < $write_to_file +RESET MASTER; +--remove_file $write_to_file diff --git a/mysql-test/suite/binlog/t/disabled.def b/mysql-test/suite/binlog/t/disabled.def index 85313982869..0c8884488cc 100644 --- a/mysql-test/suite/binlog/t/disabled.def +++ b/mysql-test/suite/binlog/t/disabled.def @@ -9,5 +9,5 @@ # Do not use any TAB characters for whitespace. # ############################################################################## -binlog_truncate_innodb : BUG#57291 2010-10-20 anitha Originally disabled due to BUG#42643. Product bug fixed, but test changes needed -binlog_row_failure_mixing_engines : BUG#58416 2010-11-23 ramil Fails on win x86 debug_max +binlog_truncate_innodb : BUG#11764459 2010-10-20 anitha Originally disabled due to BUG#42643. Product bug fixed, but test changes needed +binlog_row_failure_mixing_engines : BUG#11765446 2010-11-23 ramil Fails on win x86 debug_max diff --git a/mysql-test/suite/federated/disabled.def b/mysql-test/suite/federated/disabled.def index 9a9149ec80a..3b114aa380b 100644 --- a/mysql-test/suite/federated/disabled.def +++ b/mysql-test/suite/federated/disabled.def @@ -9,4 +9,4 @@ # Do not use any TAB characters for whitespace. # ############################################################################## -federated_transactions : Bug#29523 Transactions do not work +federated_transactions : Bug#11746899 Transactions do not work diff --git a/mysql-test/suite/funcs_1/t/disabled.def b/mysql-test/suite/funcs_1/t/disabled.def index 3f260ca49ba..032a8f59d2e 100644 --- a/mysql-test/suite/funcs_1/t/disabled.def +++ b/mysql-test/suite/funcs_1/t/disabled.def @@ -10,4 +10,4 @@ # ############################################################################## -ndb_trig_1011ext: Bug#32656 NDB: Duplicate key error aborts transaction in handler. Doesn't talk back to SQL +ndb_trig_1011ext: Bug#11747493 NDB: Duplicate key error aborts transaction in handler. Doesn't talk back to SQL diff --git a/mysql-test/suite/funcs_2/t/disabled.def b/mysql-test/suite/funcs_2/t/disabled.def index da6230bd7ed..50c65c30ed0 100644 --- a/mysql-test/suite/funcs_2/t/disabled.def +++ b/mysql-test/suite/funcs_2/t/disabled.def @@ -1,6 +1,6 @@ # Disabled by hhunger (2008-03-03) due to WL4204 -innodb_charset : Bug#20447 Problem with prefix keys with contractions and expansions -myisam_charset : Bug#20447 Problem with prefix keys with contractions and expansions -memory_charset : Bug#20447 Problem with prefix keys with contractions and expansions -ndb_charset : Bug#20447 Problem with prefix keys with contractions and expansions +innodb_charset : Bug#11745840 Problem with prefix keys with contractions and expansions +myisam_charset : Bug#11745840 Problem with prefix keys with contractions and expansions +memory_charset : Bug#11745840 Problem with prefix keys with contractions and expansions +ndb_charset : Bug#11745840 Problem with prefix keys with contractions and expansions diff --git a/mysql-test/suite/innodb/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result index fa26b8b1d01..a7feb692091 100644 --- a/mysql-test/suite/innodb/r/innodb_mysql.result +++ b/mysql-test/suite/innodb/r/innodb_mysql.result @@ -2639,7 +2639,6 @@ COUNT(*) 1537 SET SESSION sort_buffer_size = DEFAULT; DROP TABLE t1; -End of 5.1 tests # # Test for bug #39932 "create table fails if column for FK is in different # case than in corr index". @@ -2668,3 +2667,20 @@ DROP TABLE IF EXISTS t1, t2; CREATE TABLE t1 (a INT, INDEX(a)) engine=innodb; ALTER TABLE t1 RENAME TO t2, DISABLE KEYS; DROP TABLE IF EXISTS t1, t2; +# +# Test for bug #11762012 - "54553: INNODB ASSERTS IN HA_INNOBASE:: +# UPDATE_ROW, TEMPORARY TABLE, TABLE LOCK". +# +DROP TABLE IF EXISTS t1; +CREATE TEMPORARY TABLE t1 (c int) ENGINE = InnoDB; +INSERT INTO t1 VALUES (1); +LOCK TABLES t1 READ; +# Even though temporary table was locked for READ we +# still allow writes to it to be compatible with MyISAM. +# This is possible since due to fact that temporary tables +# are specific to connection and therefore locking for them +# is irrelevant. +UPDATE t1 SET c = 5; +UNLOCK TABLES; +DROP TEMPORARY TABLE t1; +End of 5.1 tests diff --git a/mysql-test/suite/innodb/t/innodb_mysql.test b/mysql-test/suite/innodb/t/innodb_mysql.test index cb6082be0d0..12bd2801556 100644 --- a/mysql-test/suite/innodb/t/innodb_mysql.test +++ b/mysql-test/suite/innodb/t/innodb_mysql.test @@ -868,9 +868,6 @@ SET SESSION sort_buffer_size = DEFAULT; DROP TABLE t1; ---echo End of 5.1 tests - - --echo # --echo # Test for bug #39932 "create table fails if column for FK is in different --echo # case than in corr index". @@ -900,3 +897,25 @@ CREATE TABLE t1 (a INT, INDEX(a)) engine=innodb; ALTER TABLE t1 RENAME TO t2, DISABLE KEYS; DROP TABLE IF EXISTS t1, t2; --enable_warnings + + +--echo # +--echo # Test for bug #11762012 - "54553: INNODB ASSERTS IN HA_INNOBASE:: +--echo # UPDATE_ROW, TEMPORARY TABLE, TABLE LOCK". +--echo # +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings +CREATE TEMPORARY TABLE t1 (c int) ENGINE = InnoDB; +INSERT INTO t1 VALUES (1); +LOCK TABLES t1 READ; +--echo # Even though temporary table was locked for READ we +--echo # still allow writes to it to be compatible with MyISAM. +--echo # This is possible since due to fact that temporary tables +--echo # are specific to connection and therefore locking for them +--echo # is irrelevant. +UPDATE t1 SET c = 5; +UNLOCK TABLES; +DROP TEMPORARY TABLE t1; + +--echo End of 5.1 tests diff --git a/mysql-test/suite/innodb_plugin/r/innodb_mysql.result b/mysql-test/suite/innodb_plugin/r/innodb_mysql.result index 448bf54ce51..ebaa52d3b4d 100644 --- a/mysql-test/suite/innodb_plugin/r/innodb_mysql.result +++ b/mysql-test/suite/innodb_plugin/r/innodb_mysql.result @@ -2438,4 +2438,20 @@ COUNT(*) 1537 SET SESSION sort_buffer_size = DEFAULT; DROP TABLE t1; +# +# Test for bug #11762012 - "54553: INNODB ASSERTS IN HA_INNOBASE:: +# UPDATE_ROW, TEMPORARY TABLE, TABLE LOCK". +# +DROP TABLE IF EXISTS t1; +CREATE TEMPORARY TABLE t1 (c int) ENGINE = InnoDB; +INSERT INTO t1 VALUES (1); +LOCK TABLES t1 READ; +# Even though temporary table was locked for READ we +# still allow writes to it to be compatible with MyISAM. +# This is possible since due to fact that temporary tables +# are specific to connection and therefore locking for them +# is irrelevant. +UPDATE t1 SET c = 5; +UNLOCK TABLES; +DROP TEMPORARY TABLE t1; End of 5.1 tests diff --git a/mysql-test/suite/innodb_plugin/t/innodb_mysql.test b/mysql-test/suite/innodb_plugin/t/innodb_mysql.test index 08d77ba448a..24beaef2fe7 100644 --- a/mysql-test/suite/innodb_plugin/t/innodb_mysql.test +++ b/mysql-test/suite/innodb_plugin/t/innodb_mysql.test @@ -689,4 +689,24 @@ SET SESSION sort_buffer_size = DEFAULT; DROP TABLE t1; + +--echo # +--echo # Test for bug #11762012 - "54553: INNODB ASSERTS IN HA_INNOBASE:: +--echo # UPDATE_ROW, TEMPORARY TABLE, TABLE LOCK". +--echo # +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings +CREATE TEMPORARY TABLE t1 (c int) ENGINE = InnoDB; +INSERT INTO t1 VALUES (1); +LOCK TABLES t1 READ; +--echo # Even though temporary table was locked for READ we +--echo # still allow writes to it to be compatible with MyISAM. +--echo # This is possible since due to fact that temporary tables +--echo # are specific to connection and therefore locking for them +--echo # is irrelevant. +UPDATE t1 SET c = 5; +UNLOCK TABLES; +DROP TEMPORARY TABLE t1; + --echo End of 5.1 tests diff --git a/mysql-test/suite/ndb/t/disabled.def b/mysql-test/suite/ndb/t/disabled.def index 0fc9a5d3ad6..1b730642235 100644 --- a/mysql-test/suite/ndb/t/disabled.def +++ b/mysql-test/suite/ndb/t/disabled.def @@ -10,6 +10,6 @@ # ############################################################################## -ndb_partition_error2 : Bug#40989 ndb_partition_error2 needs maintenance +ndb_partition_error2 : Bug#11750448 ndb_partition_error2 needs maintenance # the below testcase have been reworked to avoid the bug, test contains comment, keep bug open diff --git a/mysql-test/suite/ndb_team/t/disabled.def b/mysql-test/suite/ndb_team/t/disabled.def index 714f1014a10..e70e23b8303 100644 --- a/mysql-test/suite/ndb_team/t/disabled.def +++ b/mysql-test/suite/ndb_team/t/disabled.def @@ -9,8 +9,8 @@ # Do not use any TAB characters for whitespace. # ############################################################################## -ndb_autodiscover : BUG#18952 2006-02-16 jmiller Needs to be fixed w.r.t binlog -ndb_autodiscover2 : BUG#18952 2006-02-16 jmiller Needs to be fixed w.r.t binlog +ndb_autodiscover : BUG#11745709 2006-02-16 jmiller Needs to be fixed w.r.t binlog +ndb_autodiscover2 : BUG#11745709 2006-02-16 jmiller Needs to be fixed w.r.t binlog # the below testcase have been reworked to avoid the bug, test contains comment, keep bug open #ndb_autodiscover3 : bug#21806 diff --git a/mysql-test/suite/parts/t/disabled.def b/mysql-test/suite/parts/t/disabled.def index 518a3c90422..113fe6fdd44 100644 --- a/mysql-test/suite/parts/t/disabled.def +++ b/mysql-test/suite/parts/t/disabled.def @@ -1,3 +1,3 @@ -partition_basic_ndb : Bug#19899 Crashing the server +partition_basic_ndb : Bug#11745782 Crashing the server # http://dev.mysql.com/doc/refman/5.1/en/mysql-cluster-limitations-syntax.html -partition_syntax_ndb : Bug#36735 Not supported +partition_syntax_ndb : Bug#11748568 Not supported diff --git a/mysql-test/suite/rpl/r/rpl_relayspace.result b/mysql-test/suite/rpl/r/rpl_relayspace.result index f12f177ff7c..fb21540aa31 100644 --- a/mysql-test/suite/rpl/r/rpl_relayspace.result +++ b/mysql-test/suite/rpl/r/rpl_relayspace.result @@ -1,6 +1,6 @@ include/master-slave.inc [connection master] -stop slave; +include/stop_slave.inc create table t1 (a int); drop table t1; create table t1 (a int); @@ -8,10 +8,8 @@ drop table t1; reset slave; start slave io_thread; include/wait_for_slave_param.inc [Slave_IO_State] -stop slave io_thread; +include/stop_slave_io.inc reset slave; -start slave; -select master_pos_wait('master-bin.001',200,6)=-1; -master_pos_wait('master-bin.001',200,6)=-1 -0 +include/start_slave.inc +include/assert.inc [Assert that master_pos_wait does not timeout nor it returns NULL] include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/disabled.def b/mysql-test/suite/rpl/t/disabled.def index 33f65ff3ecc..0a8f3cb2a50 100644 --- a/mysql-test/suite/rpl/t/disabled.def +++ b/mysql-test/suite/rpl/t/disabled.def @@ -10,7 +10,7 @@ # ############################################################################## -rpl_row_create_table : Bug#51574 Feb 27 2010 andrei failed different way than earlier with bug#45576 -rpl_get_master_version_and_clock : Bug#59178 Jan 05 2011 joro Valgrind warnings rpl_get_master_version_and_clock +rpl_row_create_table : Bug#11759274 Feb 27 2010 andrei failed different way than earlier with bug#45576 +rpl_get_master_version_and_clock : Bug#11766137 Jan 05 2011 joro Valgrind warnings rpl_get_master_version_and_clock rpl_row_until : BUG#59543 Jan 26 2011 alfranio Replication test from eits suite rpl_row_until times out rpl_stm_until : BUG#59543 Jan 26 2011 alfranio Replication test from eits suite rpl_row_until times out diff --git a/mysql-test/suite/rpl/t/rpl_relayspace.test b/mysql-test/suite/rpl/t/rpl_relayspace.test index bb34ec25bcd..fc33d6bc0ba 100644 --- a/mysql-test/suite/rpl/t/rpl_relayspace.test +++ b/mysql-test/suite/rpl/t/rpl_relayspace.test @@ -2,8 +2,9 @@ # to force the deadlock after one event. source include/master-slave.inc; +--let $master_log_file= query_get_value(SHOW MASTER STATUS, File, 1) connection slave; -stop slave; +--source include/stop_slave.inc connection master; # This will generate a master's binlog > 10 bytes create table t1 (a int); @@ -19,20 +20,33 @@ let $slave_param_value= Waiting for the slave SQL thread to free enough relay lo source include/wait_for_slave_param.inc; # A bug caused the I/O thread to refuse stopping. -stop slave io_thread; +--source include/stop_slave_io.inc reset slave; -start slave; -# The I/O thread stops filling the relay log when -# it's >10b. And the SQL thread cannot purge this relay log -# as purge is done only when the SQL thread switches to another -# relay log, which does not exist here. -# So we should have a deadlock. -# if it is not resolved automatically we'll detect -# it with master_pos_wait that waits for farther than 1Ob; -# it will timeout after 10 seconds; -# also the slave will probably not cooperate to shutdown -# (as 2 threads are locked) -select master_pos_wait('master-bin.001',200,6)=-1; +--source include/start_slave.inc + +# The I/O thread stops filling the relay log when it's >10b. And the +# SQL thread cannot purge this relay log as purge is done only when +# the SQL thread switches to another relay log, which does not exist +# here. So we should have a deadlock. If it is not resolved +# automatically we'll detect it with master_pos_wait that waits for +# farther than 1Ob; it will timeout after 300 seconds (which is inline +# with the default used for sync_slave_with_master and will protect us +# against slow test envs); also the slave will probably not cooperate +# to shutdown (as 2 threads are locked) +--let $outcome= `SELECT MASTER_POS_WAIT('$master_log_file',200,300) AS mpw;` + +# master_pos_wait returns: +# +# * >= 0, the number of events the slave had to wait to advance to the +# position +# +# * -1, if there was a timeout +# +# * NULL, if an error occurred, or the SQL thread was not started, +# slave master info is not initialized, the arguments are incorrect +--let $assert_text= Assert that master_pos_wait does not timeout nor it returns NULL +--let $assert_cond= $outcome IS NOT NULL AND $outcome <> -1 +--source include/assert.inc # End of 4.1 tests --source include/rpl_end.inc diff --git a/mysql-test/suite/rpl_ndb/t/disabled.def b/mysql-test/suite/rpl_ndb/t/disabled.def index 2f15112515e..8fa6e9c099e 100644 --- a/mysql-test/suite/rpl_ndb/t/disabled.def +++ b/mysql-test/suite/rpl_ndb/t/disabled.def @@ -11,4 +11,4 @@ ############################################################################## # the below testcase have been reworked to avoid the bug, test contains comment, keep bug open -rpl_ndb_2ndb : Bug#45974: rpl_ndb_2ndb fails sporadically +rpl_ndb_2ndb : Bug#11754374 : rpl_ndb_2ndb fails sporadically diff --git a/mysql-test/suite/sys_vars/t/disabled.def b/mysql-test/suite/sys_vars/t/disabled.def index 915ea7a6f5c..866172fb51a 100644 --- a/mysql-test/suite/sys_vars/t/disabled.def +++ b/mysql-test/suite/sys_vars/t/disabled.def @@ -9,5 +9,5 @@ # Do not use any TAB characters for whitespace. # ############################################################################## -sys_vars.max_binlog_cache_size_basic_64 : bug#56408 2010-08-31 Horst -sys_vars.max_binlog_cache_size_basic_32 : bug#56408 2010-08-31 Horst +sys_vars.max_binlog_cache_size_basic_64 : bug#11763668 2010-08-31 Horst +sys_vars.max_binlog_cache_size_basic_32 : bug#11763668 2010-08-31 Horst diff --git a/mysql-test/t/archive_debug.test b/mysql-test/t/archive_debug.test new file mode 100644 index 00000000000..9cece254140 --- /dev/null +++ b/mysql-test/t/archive_debug.test @@ -0,0 +1,13 @@ +--source include/have_archive.inc +--source include/have_debug.inc + +--echo # +--echo # BUG#12402794 - 60976: CRASH, VALGRIND WARNING AND MEMORY LEAK +--echo # WITH PARTITIONED ARCHIVE TABLES +--echo # +CREATE TABLE t1(a INT) ENGINE=ARCHIVE; +INSERT INTO t1 VALUES(1); +SET SESSION debug='d,simulate_archive_open_failure'; +CHECK TABLE t1; +SET SESSION debug=DEFAULT; +DROP TABLE t1; diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index c244d08e308..84c981c08c1 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -9,7 +9,7 @@ # Do not use any TAB characters for whitespace. # ############################################################################## -kill : Bug#37780 2008-12-03 HHunger need some changes to be robust enough for pushbuild. -query_cache_28249 : Bug#43861 2009-03-25 main.query_cache_28249 fails sporadically -log_tables-big : Bug#48646 2010-11-15 mattiasj report already exists -read_many_rows_innodb : Bug#37635 2010-11-15 mattiasj report already exists +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 + diff --git a/mysql-test/t/events_bugs.test b/mysql-test/t/events_bugs.test index 420e7183621..4601448763c 100644 --- a/mysql-test/t/events_bugs.test +++ b/mysql-test/t/events_bugs.test @@ -857,6 +857,7 @@ DROP EVENT e2; DROP EVENT e1; SET TIME_ZONE=@save_time_zone; +SET TIMESTAMP=DEFAULT; # # START - BUG#28666 CREATE EVENT ... EVERY 0 SECOND let server crash @@ -1235,6 +1236,55 @@ SHOW EVENTS; DROP DATABASE event_test1; DROP DATABASE event_test12; +--echo # +--echo # Bug#12546938 (formerly known as bug#61005): +--echo # CREATE IF NOT EXIST EVENT WILL CREATE MULTIPLE RUNNING EVENTS +--echo # +USE events_test; +SET GLOBAL event_scheduler = ON; + +--disable_warnings +DROP TABLE IF EXISTS table_bug12546938; +DROP EVENT IF EXISTS event_Bug12546938; +--enable_warnings +CREATE TABLE table_bug12546938 (i INT); + +delimiter |; + +--echo # Create an event which will be executed with a small delay +--echo # and won't be automatically dropped after that. +CREATE EVENT event_Bug12546938 +ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 SECOND ON COMPLETION PRESERVE +ENABLE DO +BEGIN + INSERT INTO table_bug12546938 VALUES(1); +END +| + +--echo # Now try to create the same event using CREATE EVENT IF NOT EXISTS. +--echo # A warning should be emitted. A new event should not be created nor +--echo # the old event should be re-executed. +CREATE EVENT IF NOT EXISTS event_bug12546938 +ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 SECOND ON COMPLETION PRESERVE +ENABLE DO +BEGIN + INSERT INTO table_bug12546938 VALUES (1); +END +| + +delimiter ;| + +--echo # Wait until at least one instance of event is executed. +let $wait_condition= SELECT COUNT(*) FROM table_bug12546938; +--source include/wait_condition.inc + +--echo # Check that only one instance of our event was executed. +SELECT COUNT(*) FROM table_bug12546938; + +--echo # Clean-up. +DROP EVENT IF EXISTS event_Bug12546938; +DROP TABLE table_bug12546938; +SET GLOBAL EVENT_SCHEDULER = OFF; ########################################################################### # diff --git a/mysql-test/t/func_math.test b/mysql-test/t/func_math.test index 9d51a5c94f9..1906d2d347a 100644 --- a/mysql-test/t/func_math.test +++ b/mysql-test/t/func_math.test @@ -349,4 +349,10 @@ DROP TABLE t1; SELECT ROUND(LEAST(15, -4939092, 0.2704), STDDEV('a')); +--echo # +--echo # Bug#12392636 ASSERTION FAILED: SCALE >= 0 && PRECISION > 0 && SCALE <= PRECISION +--echo # + +SELECT SUM(DISTINCT (TRUNCATE((.1), NULL))); + --echo End of 5.1 tests diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index 2000d81f80d..de92f313992 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -921,4 +921,11 @@ SELECT DATE_FORMAT('0000-00-11', '%W'); SELECT DATE_FORMAT('0000-00-11', '%a'); SELECT DATE_FORMAT('0000-00-11', '%w'); +--echo # +--echo # Bug#12403504 AFTER FIX FOR #11889186 : ASSERTION FAILED: DELSUM+(INT) Y/4-TEMP > 0 +--echo # + +SELECT MAKEDATE(11111111,1); +SELECT WEEK(DATE_ADD(FROM_DAYS(1),INTERVAL 1 MONTH), 1); + --echo End of 5.1 tests diff --git a/mysql-test/t/implicit_char_to_num_conversion.test b/mysql-test/t/implicit_char_to_num_conversion.test new file mode 100644 index 00000000000..b4948fbc69f --- /dev/null +++ b/mysql-test/t/implicit_char_to_num_conversion.test @@ -0,0 +1,174 @@ +########### implicit_char_to_num_conversion.test ####################### +# # +# This test aims at using string/char literal in comparison operators # +# without explicit type-cast. This is a bug test for Bug#11766521 # +# - Incorrect result is returned if string/char literal is used with # +# comparision operator and bit data type column. Test is extended to # +# include numeric data type comparison with string/char literal # +# # +# # +# Creation: # +# 2011-05-10 vfisrekar Implement this test as part of Bug#11766521 # +# # +######################################################################## + +--disable_warnings +DROP TABLE IF EXISTS t5; +--enable_warnings + +let $default_engine = `select @@SESSION.storage_engine`; + +# Bug#11766521 - BIT Datatype comparison in where clause return incorrect +# result for '=' , '<=>' operators +--replace_result $default_engine <default_engine> +eval CREATE TABLE t5(c1 BIT(2) PRIMARY KEY) ENGINE = $default_engine; +INSERT INTO t5 VALUES (0), (1), (2); +SELECT HEX(c1) FROM t5 ORDER BY c1; +# Enable Following two select after Bug#11766521 fix +# SELECT HEX(c1) FROM t5 WHERE c1 = '1' ORDER BY c1; +# SELECT HEX(c1) FROM t5 WHERE c1 <=> '1' ORDER BY c1; +SELECT HEX(c1) FROM t5 WHERE c1 = b'1' ORDER BY c1; +SELECT HEX(c1) FROM t5 WHERE c1 <=> b'1' ORDER BY c1; +SELECT HEX(c1) FROM t5 WHERE c1 != b'1' ORDER BY c1; +SELECT HEX(c1) FROM t5 WHERE c1 >= '1' ORDER BY c1; +SELECT HEX(c1) FROM t5 WHERE c1 <= '1' ORDER BY c1; +SELECT HEX(c1) FROM t5 WHERE c1 < '1' ORDER BY c1; +SELECT HEX(c1) FROM t5 WHERE c1 > '0' ORDER BY c1; +DROP TABLE t5; + +# FLOAT Data-type +--replace_result $default_engine <default_engine> +eval CREATE TABLE t5(c1 FLOAT(5,2) PRIMARY KEY) ENGINE = $default_engine; +INSERT INTO t5 VALUES (95.95), (-10.10), (1), (0); +SELECT c1 FROM t5 ORDER BY c1; +# Compare with string literal +# Following two queries does not return result may be due to Bug#11766521. +# Enable them after Bug#11766521 fix. +# SELECT c1 FROM t5 WHERE c1 = '10.10' ORDER BY c1; +# SELECT c1 FROM t5 WHERE c2 <=> '11.11' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 >= '95' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <= '10.10' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 != '1' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 < '1' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 > '0' ORDER BY c1; +DROP TABLE t5; + +# TINYINT Datatype +--replace_result $default_engine <default_engine> +eval CREATE TABLE t5(c1 TINYINT PRIMARY KEY) ENGINE = $default_engine; +INSERT INTO t5 VALUES (95), (10),(11),(-8); +SELECT c1 FROM t5 ORDER BY c1; +# Compare with string literal +SELECT c1 FROM t5 WHERE c1 = '10' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <=> '10' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 >= '95' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <= '11' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 != '-8' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 < '11' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 > '10' ORDER BY c1; +DROP TABLE t5; + +# SMALLINT Datatype +--replace_result $default_engine <default_engine> +eval CREATE TABLE t5(c1 SMALLINT PRIMARY KEY) ENGINE = $default_engine; +INSERT INTO t5 VALUES (395), (-200), (100), (111); +SELECT c1 FROM t5 ORDER BY c1; +# Compare with string literal +SELECT c1 FROM t5 WHERE c1 = '100' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <=> '100' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 >= '395' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <= '-200' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 != '100' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 < '111' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 > '111' ORDER BY c1; +DROP TABLE t5; + +# MEDIUMINT Datatype +--replace_result $default_engine <default_engine> +eval CREATE TABLE t5(c1 MEDIUMINT PRIMARY KEY) ENGINE = $default_engine; +INSERT INTO t5 VALUES (-8388607), (311),(215),(88608); +SELECT c1 FROM t5 ORDER BY c1; +# Compare with string literal +SELECT c1 FROM t5 WHERE c1 = '311' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <=> '311' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 >= '215' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <= '88608' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 != '-8388607' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 < '215' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 > '215' ORDER BY c1; +DROP TABLE t5; + +# INT Datatype +--replace_result $default_engine <default_engine> +eval CREATE TABLE t5(c1 INT PRIMARY KEY) ENGINE = $default_engine; +INSERT INTO t5 VALUES (-2147483647), (1011),(15),(9388607); +SELECT c1 FROM t5 ORDER BY c1; +# Compare with string literal +SELECT c1 FROM t5 WHERE c1 = '9388607' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <=> '9388607' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 >= '15' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <= '1011' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 != '-2147483647' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 < '15' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 > '15' ORDER BY c1; +DROP TABLE t5; + +# BIGINT Data-type +--replace_result $default_engine <default_engine> +eval CREATE TABLE t5(c1 BIGINT PRIMARY KEY) ENGINE = $default_engine; +INSERT INTO t5 VALUES (-9223372036854775807), (12011),(500),(3372036854775808); +SELECT c1 FROM t5 ORDER BY c1; +# Compare with string literal +SELECT c1 FROM t5 WHERE c1 = '-9223372036854775807' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <=> '-9223372036854775807' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 >= '12011' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <= '500' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 != '3372036854775808' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 < '12011' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 > '12011' ORDER BY c1; +DROP TABLE t5; + +# DOUBLE Datatype +--replace_result $default_engine <default_engine> +eval CREATE TABLE t5(c1 DOUBLE(5,2) PRIMARY KEY) ENGINE = $default_engine; +INSERT INTO t5 VALUES (95.95), (11.11),(5),(-908.92); +SELECT c1 FROM t5 ORDER BY c1; +# Compare with string literal +SELECT c1 FROM t5 WHERE c1 = '11.11' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <=> '11.11' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 >= '5' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <= '95.95' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 != '-908.92' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 < '95.95' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 > '-908.92' ORDER BY c1; +DROP TABLE t5; + +# NUMERIC Datatype +--replace_result $default_engine <default_engine> +eval CREATE TABLE t5(c1 NUMERIC(5,2) PRIMARY KEY) ENGINE = $default_engine; +INSERT INTO t5 VALUES (95.95), (11.11),(5),(-908.92); +SELECT c1 FROM t5 ORDER BY c1; +# Compare with string literal +SELECT c1 FROM t5 WHERE c1 = '11.11' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <=> '11.11' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 >= '5' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <= '95.95' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 != '-908.92' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 < '95.95' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 > '-908.92' ORDER BY c1; +DROP TABLE t5; + +# DECIMAL Datatype +--replace_result $default_engine <default_engine> +eval CREATE TABLE t5(c1 DECIMAL(5,2) PRIMARY KEY) ENGINE = $default_engine; +INSERT INTO t5 VALUES (95.95), (11.11),(5),(-908.92); +SELECT c1 FROM t5 ORDER BY c1; +# Compare with string literal +SELECT c1 FROM t5 WHERE c1 = '11.11' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <=> '11.11' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 >= '5' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 <= '95.95' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 != '-908.92' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 < '95.95' ORDER BY c1; +SELECT c1 FROM t5 WHERE c1 > '-908.92' ORDER BY c1; +DROP TABLE t5; diff --git a/mysql-test/t/type_newdecimal.test b/mysql-test/t/type_newdecimal.test index 2cf7ab8fbdf..31a8808da55 100644 --- a/mysql-test/t/type_newdecimal.test +++ b/mysql-test/t/type_newdecimal.test @@ -1510,5 +1510,19 @@ group by PAY.id + 1; DROP TABLE currencies, payments, sub_tasks; +--echo # +--echo # Bug#55436: buffer overflow in debug binary of dbug_buff in +--echo # Field_new_decimal::store_value +--echo # + +# this threw memory warnings on Windows. Also make sure future changes +# don't change these results, as per usual. +SET SQL_MODE=''; +CREATE TABLE t1(f1 DECIMAL(44,24)) ENGINE=MYISAM; +INSERT INTO t1 SET f1 = -64878E-85; +SELECT f1 FROM t1; +DROP TABLE IF EXISTS t1; + + --echo End of 5.1 tests diff --git a/sql/derror.cc b/sql/derror.cc index a8cfa00ad1d..fa10a22dca4 100644 --- a/sql/derror.cc +++ b/sql/derror.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2005 MySQL AB +/* Copyright (c) 2000, 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 @@ -11,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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /** @file @@ -96,7 +95,6 @@ static bool read_texts(const char *file_name,const char ***point, char name[FN_REFLEN]; uchar *buff; uchar head[32],*pos; - const char *errmsg; DBUG_ENTER("read_texts"); LINT_INIT(buff); @@ -168,18 +166,9 @@ Check that the above file is the right version for this program!", DBUG_RETURN(0); err: - switch (funktpos) { - case 2: - errmsg= "Not enough memory for messagefile '%s'"; - break; - case 1: - errmsg= "Can't read from messagefile '%s'"; - break; - default: - errmsg= "Can't find messagefile '%s'"; - break; - } - sql_print_error(errmsg, name); + sql_print_error((funktpos == 2) ? "Not enough memory for messagefile '%s'" : + ((funktpos == 1) ? "Can't read from messagefile '%s'" : + "Can't find messagefile '%s'"), name); err1: if (file != FERR) VOID(my_close(file,MYF(MY_WME))); diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc index a0765dc6d15..9efd3bca675 100644 --- a/sql/event_db_repository.cc +++ b/sql/event_db_repository.cc @@ -604,18 +604,21 @@ Event_db_repository::open_event_table(THD *thd, enum thr_lock_type lock_type, only creates a record on disk. @pre The thread handle has no open tables. - @param[in,out] thd THD - @param[in] parse_data Parsed event definition - @param[in] create_if_not TRUE if IF NOT EXISTS clause was provided - to CREATE EVENT statement - + @param[in,out] thd THD + @param[in] parse_data Parsed event definition + @param[in] create_if_not TRUE if IF NOT EXISTS clause was provided + to CREATE EVENT statement + @param[out] event_already_exists When method is completed successfully + set to true if event already exists else + set to false @retval FALSE success @retval TRUE error */ bool Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data, - my_bool create_if_not) + bool create_if_not, + bool *event_already_exists) { int ret= 1; TABLE *table= NULL; @@ -641,6 +644,7 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data, { if (create_if_not) { + *event_already_exists= true; push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_EVENT_ALREADY_EXISTS, ER(ER_EVENT_ALREADY_EXISTS), parse_data->name.str); @@ -648,8 +652,10 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data, } else my_error(ER_EVENT_ALREADY_EXISTS, MYF(0), parse_data->name.str); + goto end; - } + } else + *event_already_exists= false; DBUG_PRINT("info", ("non-existent, go forward")); diff --git a/sql/event_db_repository.h b/sql/event_db_repository.h index ef778407d1e..a7d7b97ae3c 100644 --- a/sql/event_db_repository.h +++ b/sql/event_db_repository.h @@ -73,7 +73,8 @@ public: Event_db_repository(){} bool - create_event(THD *thd, Event_parse_data *parse_data, my_bool create_if_not); + create_event(THD *thd, Event_parse_data *parse_data, bool create_if_not, + bool *event_already_exists); bool update_event(THD *thd, Event_parse_data *parse_data, LEX_STRING *new_dbname, diff --git a/sql/events.cc b/sql/events.cc index afae512c61d..08360ee5f04 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2004-2006 MySQL AB +/* Copyright (c) 2004, 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 @@ -11,7 +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 */ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "mysql_priv.h" #include "events.h" @@ -370,6 +370,7 @@ create_query_string(THD *thd, String *buf) return 0; } + /** Create a new event. @@ -390,8 +391,8 @@ bool Events::create_event(THD *thd, Event_parse_data *parse_data, bool if_not_exists) { - int ret; - bool save_binlog_row_based; + bool ret; + bool save_binlog_row_based, event_already_exists; DBUG_ENTER("Events::create_event"); /* @@ -440,28 +441,32 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, pthread_mutex_lock(&LOCK_event_metadata); /* On error conditions my_error() is called so no need to handle here */ - if (!(ret= db_repository->create_event(thd, parse_data, if_not_exists))) + if (!(ret= db_repository->create_event(thd, parse_data, if_not_exists, + &event_already_exists))) { Event_queue_element *new_element; bool dropped= 0; - if (!(new_element= new Event_queue_element())) - ret= TRUE; // OOM - else if ((ret= db_repository->load_named_event(thd, parse_data->dbname, - parse_data->name, - new_element))) - { - if (!db_repository->drop_event(thd, parse_data->dbname, parse_data->name, - TRUE)) - dropped= 1; - delete new_element; - } - else + if (!event_already_exists) { - /* TODO: do not ignore the out parameter and a possible OOM error! */ - bool created; - if (event_queue) - event_queue->create_event(thd, new_element, &created); + if (!(new_element= new Event_queue_element())) + ret= TRUE; // OOM + else if ((ret= db_repository->load_named_event(thd, parse_data->dbname, + parse_data->name, + new_element))) + { + if (!db_repository->drop_event(thd, parse_data->dbname, parse_data->name, + TRUE)) + dropped= 1; + delete new_element; + } + else + { + /* TODO: do not ignore the out parameter and a possible OOM error! */ + bool created; + if (event_queue) + event_queue->create_event(thd, new_element, &created); + } } /* binlog the create event unless it's been successfully dropped @@ -475,13 +480,14 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, { sql_print_error("Event Error: An error occurred while creating query string, " "before writing it into binary log."); - /* Restore the state of binlog format */ - thd->current_stmt_binlog_row_based= save_binlog_row_based; - DBUG_RETURN(TRUE); + ret= true; } - /* If the definer is not set or set to CURRENT_USER, the value of CURRENT_USER - will be written into the binary log as the definer for the SQL thread. */ - ret= write_bin_log(thd, TRUE, log_query.c_ptr(), log_query.length()); + else + /* + If the definer is not set or set to CURRENT_USER, the value of CURRENT_USER + will be written into the binary log as the definer for the SQL thread. + */ + ret= write_bin_log(thd, TRUE, log_query.c_ptr(), log_query.length()); } } pthread_mutex_unlock(&LOCK_event_metadata); @@ -547,7 +553,7 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, !sortcmp_lex_string(parse_data->name, *new_name, system_charset_info)) { - my_error(ER_EVENT_SAME_NAME, MYF(0), parse_data->name.str); + my_error(ER_EVENT_SAME_NAME, MYF(0)); DBUG_RETURN(TRUE); } @@ -1150,7 +1156,7 @@ Events::switch_event_scheduler_state(enum_opt_event_scheduler new_state) if (ret) { - my_error(ER_EVENT_SET_VAR_ERROR, MYF(0)); + my_error(ER_EVENT_SET_VAR_ERROR, MYF(0), 0); goto end; } diff --git a/sql/field.cc b/sql/field.cc index 3707c5b056f..6bd4e4beda1 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 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 @@ -11,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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /** @file @@ -2583,7 +2582,7 @@ bool Field_new_decimal::store_value(const my_decimal *decimal_value) DBUG_ENTER("Field_new_decimal::store_value"); #ifndef DBUG_OFF { - char dbug_buff[DECIMAL_MAX_STR_LENGTH+1]; + char dbug_buff[DECIMAL_MAX_STR_LENGTH+2]; DBUG_PRINT("enter", ("value: %s", dbug_decimal_as_string(dbug_buff, decimal_value))); } #endif @@ -2598,7 +2597,7 @@ bool Field_new_decimal::store_value(const my_decimal *decimal_value) } #ifndef DBUG_OFF { - char dbug_buff[DECIMAL_MAX_STR_LENGTH+1]; + char dbug_buff[DECIMAL_MAX_STR_LENGTH+2]; DBUG_PRINT("info", ("saving with precision %d scale: %d value %s", (int)precision, (int)dec, dbug_decimal_as_string(dbug_buff, decimal_value))); @@ -2673,7 +2672,7 @@ int Field_new_decimal::store(const char *from, uint length, } #ifndef DBUG_OFF - char dbug_buff[DECIMAL_MAX_STR_LENGTH+1]; + char dbug_buff[DECIMAL_MAX_STR_LENGTH+2]; DBUG_PRINT("enter", ("value: %s", dbug_decimal_as_string(dbug_buff, &decimal_value))); #endif @@ -9585,7 +9584,7 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, if (decimals >= NOT_FIXED_DEC) { my_error(ER_TOO_BIG_SCALE, MYF(0), decimals, fld_name, - NOT_FIXED_DEC-1); + static_cast<ulong>(NOT_FIXED_DEC - 1)); DBUG_RETURN(TRUE); } @@ -9655,8 +9654,8 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, my_decimal_trim(&length, &decimals); if (length > DECIMAL_MAX_PRECISION) { - my_error(ER_TOO_BIG_PRECISION, MYF(0), length, fld_name, - DECIMAL_MAX_PRECISION); + my_error(ER_TOO_BIG_PRECISION, MYF(0), static_cast<int>(length), + fld_name, static_cast<ulong>(DECIMAL_MAX_PRECISION)); DBUG_RETURN(TRUE); } if (length < decimals) @@ -9881,7 +9880,7 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, if (length > MAX_BIT_FIELD_LENGTH) { my_error(ER_TOO_BIG_DISPLAYWIDTH, MYF(0), fld_name, - MAX_BIT_FIELD_LENGTH); + static_cast<ulong>(MAX_BIT_FIELD_LENGTH)); DBUG_RETURN(TRUE); } pack_length= (length + 7) / 8; diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 4f99d354754..eefdbd3b01b 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2003 MySQL AB +/* Copyright (c) 2000, 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 @@ -11,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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /** @file @@ -8411,7 +8410,7 @@ NDB_SHARE *ndbcluster_get_share(const char *key, TABLE *table, DBUG_PRINT("error", ("get_share: failed to alloc share")); if (!have_lock) pthread_mutex_unlock(&ndbcluster_mutex); - my_error(ER_OUTOFMEMORY, MYF(0), sizeof(*share)); + my_error(ER_OUTOFMEMORY, MYF(0), static_cast<int>(sizeof(*share))); DBUG_RETURN(0); } } diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc index 27af3f2cf2f..631391e7408 100644 --- a/sql/ha_ndbcluster_binlog.cc +++ b/sql/ha_ndbcluster_binlog.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2003 MySQL AB +/* Copyright (c) 2000, 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 @@ -11,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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "mysql_priv.h" #include "sql_show.h" @@ -1198,12 +1197,14 @@ ndbcluster_update_slock(THD *thd, } if (ndb_error) + { + char buf[1024]; + my_snprintf(buf, sizeof(buf), "Could not release lock on '%s.%s'", + db, table_name); push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, ER_GET_ERRMSG, ER(ER_GET_ERRMSG), - ndb_error->code, - ndb_error->message, - "Could not release lock on '%s.%s'", - db, table_name); + ndb_error->code, ndb_error->message, buf); + } if (trans) ndb->closeTransaction(trans); ndb->setDatabaseName(save_db); diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index d3858eae0d4..b5363f8235c 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -1,4 +1,4 @@ -/* Copyright 2005-2008 MySQL AB, 2008 Sun Microsystems, Inc. +/* Copyright (c) 2005, 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 @@ -11,7 +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 */ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* This handler was developed by Mikael Ronstrom for version 5.1 of MySQL. @@ -1026,6 +1026,10 @@ static int handle_opt_part(THD *thd, HA_CHECK_OPT *check_opt, static bool print_admin_msg(THD* thd, const char* msg_type, const char* db_name, const char* table_name, const char* op_name, const char *fmt, ...) + ATTRIBUTE_FORMAT(printf, 6, 7); +static bool print_admin_msg(THD* thd, const char* msg_type, + const char* db_name, const char* table_name, + const char* op_name, const char *fmt, ...) { va_list args; Protocol *protocol= thd->protocol; diff --git a/sql/handler.cc b/sql/handler.cc index 718529fa5fc..82f5f2ee841 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -275,7 +275,7 @@ handler *get_ha_partition(partition_info *part_info) } else { - my_error(ER_OUTOFMEMORY, MYF(0), sizeof(ha_partition)); + my_error(ER_OUTOFMEMORY, MYF(0), static_cast<int>(sizeof(ha_partition))); } DBUG_RETURN(((handler*) partition)); } @@ -1604,7 +1604,8 @@ int ha_recover(HASH *commit_list) } if (!info.list) { - sql_print_error(ER(ER_OUTOFMEMORY), info.len*sizeof(XID)); + sql_print_error(ER(ER_OUTOFMEMORY), + static_cast<int>(info.len*sizeof(XID))); DBUG_RETURN(1); } diff --git a/sql/item_create.cc b/sql/item_create.cc index 5726e987ef6..d1938abf264 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2010 Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 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 @@ -11,7 +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 */ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /** @file @@ -5083,8 +5083,8 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type, decoded_size= strtoul(c_len, NULL, 10); if (errno != 0) { - my_error(ER_TOO_BIG_PRECISION, MYF(0), c_len, a->name, - DECIMAL_MAX_PRECISION); + my_error(ER_TOO_BIG_PRECISION, MYF(0), INT_MAX, a->name, + static_cast<ulong>(DECIMAL_MAX_PRECISION)); return NULL; } len= decoded_size; @@ -5097,8 +5097,8 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type, decoded_size= strtoul(c_dec, NULL, 10); if ((errno != 0) || (decoded_size > UINT_MAX)) { - my_error(ER_TOO_BIG_SCALE, MYF(0), c_dec, a->name, - DECIMAL_MAX_SCALE); + my_error(ER_TOO_BIG_SCALE, MYF(0), INT_MAX, a->name, + static_cast<ulong>(DECIMAL_MAX_SCALE)); return NULL; } dec= decoded_size; @@ -5111,14 +5111,14 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type, } if (len > DECIMAL_MAX_PRECISION) { - my_error(ER_TOO_BIG_PRECISION, MYF(0), len, a->name, - DECIMAL_MAX_PRECISION); + my_error(ER_TOO_BIG_PRECISION, MYF(0), static_cast<int>(len), a->name, + static_cast<ulong>(DECIMAL_MAX_PRECISION)); return 0; } if (dec > DECIMAL_MAX_SCALE) { my_error(ER_TOO_BIG_SCALE, MYF(0), dec, a->name, - DECIMAL_MAX_SCALE); + static_cast<ulong>(DECIMAL_MAX_SCALE)); return 0; } res= new (thd->mem_root) Item_decimal_typecast(a, len, dec); diff --git a/sql/item_func.cc b/sql/item_func.cc index 6a9c47954b7..feb87fe5fd7 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 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 @@ -11,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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /** @file @@ -1066,7 +1065,7 @@ err: push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR, ER_WARN_DATA_OUT_OF_RANGE, ER(ER_WARN_DATA_OUT_OF_RANGE), - name, 1); + name, 1L); return dec; } @@ -1973,6 +1972,9 @@ void Item_func_round::fix_length_and_dec() } val1= args[1]->val_int(); + if ((null_value= args[1]->is_null())) + return; + val1_unsigned= args[1]->unsigned_flag; if (val1 < 0) decimals_to_set= val1_unsigned ? INT_MAX : 0; @@ -2851,7 +2853,7 @@ udf_handler::fix_fields(THD *thd, Item_result_field *func, if (!tmp_udf) { - my_error(ER_CANT_FIND_UDF, MYF(0), u_d->name.str, errno); + my_error(ER_CANT_FIND_UDF, MYF(0), u_d->name.str); DBUG_RETURN(TRUE); } u_d=tmp_udf; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index affe0f8e17d..d72e15c3636 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2006 MySQL AB +/* Copyright (c) 2000, 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 @@ -11,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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /** @file @@ -3465,7 +3464,8 @@ String *Item_func_uncompress::val_str(String *str) push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR, ER_TOO_BIG_FOR_UNCOMPRESS, ER(ER_TOO_BIG_FOR_UNCOMPRESS), - current_thd->variables.max_allowed_packet); + static_cast<int>(current_thd->variables. + max_allowed_packet)); goto err; } if (buffer.realloc((uint32)new_size)) diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index a96922b94a1..9b312247017 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -1519,6 +1519,11 @@ bool Item_func_from_days::get_date(MYSQL_TIME *ltime, uint fuzzy_date) return 1; bzero(ltime, sizeof(MYSQL_TIME)); get_date_from_daynr((long) value, <ime->year, <ime->month, <ime->day); + + if ((null_value= (fuzzy_date & TIME_NO_ZERO_DATE) && + (ltime->year == 0 || ltime->month == 0 || ltime->day == 0))) + return TRUE; + ltime->time_type= MYSQL_TIMESTAMP_DATE; return 0; } @@ -2697,7 +2702,7 @@ String *Item_func_makedate::val_str(String *str) long days; if (args[0]->null_value || args[1]->null_value || - year < 0 || daynr <= 0) + year < 0 || year > 9999 || daynr <= 0) goto err; if (year < 100) @@ -2740,7 +2745,7 @@ longlong Item_func_makedate::val_int() long days; if (args[0]->null_value || args[1]->null_value || - year < 0 || daynr <= 0) + year < 0 || year > 9999 || daynr <= 0) goto err; if (year < 100) diff --git a/sql/log.cc b/sql/log.cc index 17642696e7d..77d12641442 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -2989,12 +2989,6 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd) DBUG_ENTER("reset_logs"); ha_reset_logs(thd); - /* - We need to get both locks to be sure that no one is trying to - write to the index log file. - */ - pthread_mutex_lock(&LOCK_log); - pthread_mutex_lock(&LOCK_index); /* The following mutex is needed to ensure that no threads call @@ -3002,7 +2996,14 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd) thread. If the transaction involved MyISAM tables, it should go into binlog even on rollback. */ - VOID(pthread_mutex_lock(&LOCK_thread_count)); + pthread_mutex_lock(&LOCK_thread_count); + + /* + We need to get both locks to be sure that no one is trying to + write to the index log file. + */ + pthread_mutex_lock(&LOCK_log); + pthread_mutex_lock(&LOCK_index); /* Save variables so that we can reopen the log */ save_name=name; diff --git a/sql/my_decimal.cc b/sql/my_decimal.cc index 26377bc1562..d3db28e370f 100644 --- a/sql/my_decimal.cc +++ b/sql/my_decimal.cc @@ -95,10 +95,11 @@ int my_decimal2string(uint mask, const my_decimal *d, UNSIGNED. Hence the buffer for a ZEROFILLed value is the length the user requested, plus one for a possible decimal point, plus one if the user only wanted decimal places, but we force a leading - zero on them. Because the type is implicitly UNSIGNED, we do not - need to reserve a character for the sign. For all other cases, - fixed_prec will be 0, and my_decimal_string_length() will be called - instead to calculate the required size of the buffer. + zero on them, plus one for the '\0' terminator. Because the type + is implicitly UNSIGNED, we do not need to reserve a character for + the sign. For all other cases, fixed_prec will be 0, and + my_decimal_string_length() will be called instead to calculate the + required size of the buffer. */ int length= (fixed_prec ? (fixed_prec + ((fixed_prec == fixed_dec) ? 1 : 0) + 1) @@ -276,7 +277,7 @@ print_decimal_buff(const my_decimal *dec, const uchar* ptr, int length) const char *dbug_decimal_as_string(char *buff, const my_decimal *val) { - int length= DECIMAL_MAX_STR_LENGTH; + int length= DECIMAL_MAX_STR_LENGTH + 1; /* minimum size for buff */ if (!val) return "NULL"; (void)decimal2string((decimal_t*) val, buff, &length, 0,0,0); diff --git a/sql/my_decimal.h b/sql/my_decimal.h index a5077f397e3..97546c91da1 100644 --- a/sql/my_decimal.h +++ b/sql/my_decimal.h @@ -55,7 +55,7 @@ C_MODE_END /** maximum length of string representation (number of maximum decimal - digits + 1 position for sign + 1 position for decimal point) + digits + 1 position for sign + 1 position for decimal point, no terminator) */ #define DECIMAL_MAX_STR_LENGTH (DECIMAL_MAX_POSSIBLE_PRECISION + 2) @@ -212,6 +212,7 @@ inline uint32 my_decimal_precision_to_length(uint precision, uint8 scale, inline int my_decimal_string_length(const my_decimal *d) { + /* length of string representation including terminating '\0' */ return decimal_string_size(d); } diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index f482754baaa..2ec4d94ac2c 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1,4 +1,4 @@ -/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc. +/* Copyright (c) 2000, 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 @@ -11,7 +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 */ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /** @file @@ -670,6 +670,10 @@ enum enum_check_fields extern "C" THD *_current_thd_noinline(); #define _current_thd() _current_thd_noinline() #else +/* + THR_THD is a key which will be used to set/get THD* for a thread, + using my_pthread_setspecific_ptr()/my_thread_getspecific_ptr(). +*/ extern pthread_key(THD*, THR_THD); inline THD *_current_thd(void) { @@ -829,7 +833,7 @@ void sql_print_warning(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2); void sql_print_information(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2); typedef void (*sql_print_message_func)(const char *format, ...) - ATTRIBUTE_FORMAT(printf, 1, 2); + ATTRIBUTE_FORMAT_FPTR(printf, 1, 2); extern sql_print_message_func sql_print_message_handlers[]; int error_log_print(enum loglevel level, const char *format, @@ -2015,6 +2019,10 @@ extern TABLE_LIST general_log, slow_log; extern FILE *bootstrap_file; extern int bootstrap_error; extern FILE *stderror_file; +/* + THR_MALLOC is a key which will be used to set/get MEM_ROOT** for a thread, + using my_pthread_setspecific_ptr()/my_thread_getspecific_ptr(). +*/ extern pthread_key(MEM_ROOT**,THR_MALLOC); extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open, LOCK_lock_db, LOCK_mapped_file,LOCK_user_locks, LOCK_status, diff --git a/sql/mysqld.cc b/sql/mysqld.cc index d92fd6708c0..7775e18f4cf 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -171,12 +171,12 @@ static void getvolumeID(BYTE *volumeName); int initgroups(const char *,unsigned int); #endif -#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H) +#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H) && !defined(HAVE_FEDISABLEEXCEPT) #include <ieeefp.h> #ifdef HAVE_FP_EXCEPT // Fix type conflict typedef fp_except fp_except_t; #endif -#endif /* __FreeBSD__ && HAVE_IEEEFP_H */ +#endif /* __FreeBSD__ && HAVE_IEEEFP_H && !HAVE_FEDISABLEEXCEPT */ #ifdef HAVE_SYS_FPU_H /* for IRIX to use set_fpc_csr() */ #include <sys/fpu.h> @@ -202,19 +202,24 @@ extern "C" my_bool reopen_fstreams(const char *filename, inline void setup_fpu() { -#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H) +#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H) && !defined(HAVE_FEDISABLEEXCEPT) /* We can't handle floating point exceptions with threads, so disable this on freebsd - Don't fall for overflow, underflow,divide-by-zero or loss of precision + Don't fall for overflow, underflow,divide-by-zero or loss of precision. + fpsetmask() is deprecated in favor of fedisableexcept() in C99. */ -#if defined(__i386__) +#if defined(FP_X_DNML) fpsetmask(~(FP_X_INV | FP_X_DNML | FP_X_OFL | FP_X_UFL | FP_X_DZ | FP_X_IMP)); #else fpsetmask(~(FP_X_INV | FP_X_OFL | FP_X_UFL | FP_X_DZ | FP_X_IMP)); -#endif /* __i386__ */ -#endif /* __FreeBSD__ && HAVE_IEEEFP_H */ +#endif /* FP_X_DNML */ +#endif /* __FreeBSD__ && HAVE_IEEEFP_H && !HAVE_FEDISABLEEXCEPT */ + +#ifdef HAVE_FEDISABLEEXCEPT + fedisableexcept(FE_ALL_EXCEPT); +#endif #ifdef HAVE_FESETROUND /* Set FPU rounding mode to "round-to-nearest" */ @@ -1903,6 +1908,12 @@ void unlink_thd(THD *thd) pthread_mutex_unlock(&LOCK_connection_count); (void) pthread_mutex_lock(&LOCK_thread_count); + /* + Used by binlog_reset_master. It would be cleaner to use + DEBUG_SYNC here, but that's not possible because the THD's debug + sync feature has been shut down at this point. + */ + DBUG_EXECUTE_IF("sleep_after_lock_thread_count_before_delete_thd", sleep(5);); thread_count--; delete thd; DBUG_VOID_RETURN; diff --git a/sql/password.c b/sql/password.c index 9204c660b77..29a501986f4 100644 --- a/sql/password.c +++ b/sql/password.c @@ -204,21 +204,16 @@ void scramble_323(char *to, const char *message, const char *password) } -/* - Check scrambled message - Used in pre 4.1 password handling - SYNOPSIS - check_scramble_323() - scrambled scrambled message to check. - message original random message which was used for scrambling; must - be exactly SCRAMBLED_LENGTH_323 bytes long and - NULL-terminated. - hash_pass password which should be used for scrambling - All params are IN. +/** + Check scrambled message. Used in pre 4.1 password handling. - RETURN VALUE - 0 - password correct - !0 - password invalid + @param scrambled Scrambled message to check. + @param message Original random message which was used for scrambling. + @param hash_pass Password which should be used for scrambling. + + @remark scrambled and message must be SCRAMBLED_LENGTH_323 bytes long. + + @return FALSE if password is correct, TRUE otherwise. */ my_bool @@ -227,9 +222,16 @@ check_scramble_323(const char *scrambled, const char *message, { struct rand_struct rand_st; ulong hash_message[2]; - char buff[16],*to,extra; /* Big enough for check */ + /* Big enough for checks. */ + char buff[16], scrambled_buff[SCRAMBLE_LENGTH_323 + 1]; + char *to, extra; const char *pos; + /* Ensure that the scrambled message is null-terminated. */ + memcpy(scrambled_buff, scrambled, SCRAMBLE_LENGTH_323); + scrambled_buff[SCRAMBLE_LENGTH_323]= '\0'; + scrambled= scrambled_buff; + hash_password(hash_message, message, SCRAMBLE_LENGTH_323); randominit(&rand_st,hash_pass[0] ^ hash_message[0], hash_pass[1] ^ hash_message[1]); diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 19bee87c9ca..411b18e86ea 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1,4 +1,4 @@ -/* Copyright 2002-2008 MySQL AB, 2008 Sun Microsystems, Inc. +/* Copyright (c) 2002, 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 @@ -11,7 +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 */ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "mysql_priv.h" #ifdef USE_PRAGMA_IMPLEMENTATION @@ -1060,7 +1060,7 @@ void sp_head::recursion_level_error(THD *thd) if (m_type == TYPE_ENUM_PROCEDURE) { my_error(ER_SP_RECURSION_LIMIT, MYF(0), - thd->variables.max_sp_recursion_depth, + static_cast<int>(thd->variables.max_sp_recursion_depth), m_name.str); } else diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 718da07bc86..6d5d34d0602 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1970,13 +1970,12 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, */ else if (!password_len && no_auto_create) { - my_error(ER_PASSWORD_NO_MATCH, MYF(0), combo.user.str, combo.host.str); + my_error(ER_PASSWORD_NO_MATCH, MYF(0)); goto end; } else if (!can_create_user) { - my_error(ER_CANT_CREATE_USER_WITH_GRANT, MYF(0), - thd->security_ctx->user, thd->security_ctx->host_or_ip); + my_error(ER_CANT_CREATE_USER_WITH_GRANT, MYF(0)); goto end; } old_row_exists = 0; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index dc78f3b84c6..87d28402e01 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -4008,7 +4008,7 @@ retry: { /* Give right error message */ thd->clear_error(); - my_error(ER_NOT_KEYFILE, MYF(0), share->table_name.str, my_errno); + my_error(ER_NOT_KEYFILE, MYF(0), share->table_name.str); sql_print_error("Couldn't repair table: %s.%s", share->db.str, share->table_name.str); if (entry->file) @@ -7686,7 +7686,7 @@ bool setup_tables(THD *thd, Name_resolution_context *context, } if (tablenr > MAX_TABLES) { - my_error(ER_TOO_MANY_TABLES,MYF(0),MAX_TABLES); + my_error(ER_TOO_MANY_TABLES, MYF(0), static_cast<int>(MAX_TABLES)); DBUG_RETURN(1); } for (table_list= tables; diff --git a/sql/sql_binlog.cc b/sql/sql_binlog.cc index 31fd2de3722..6cd747de492 100644 --- a/sql/sql_binlog.cc +++ b/sql/sql_binlog.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2005-2006 MySQL AB +/* Copyright (c) 2005, 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 @@ -232,7 +232,7 @@ void mysql_client_binlog_statement(THD* thd) TODO: Maybe a better error message since the BINLOG statement now contains several events. */ - my_error(ER_UNKNOWN_ERROR, MYF(0), "Error executing BINLOG statement"); + my_error(ER_UNKNOWN_ERROR, MYF(0)); goto end; } } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index ae21a5335fd..5fc5df300f5 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1,4 +1,4 @@ -/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc. +/* Copyright (c) 2000, 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 @@ -11,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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /***************************************************************************** ** @@ -1196,6 +1195,25 @@ bool THD::store_globals() return 0; } +/* + Remove the thread specific info (THD and mem_root pointer) stored during + store_global call for this thread. +*/ +bool THD::restore_globals() +{ + /* + Assert that thread_stack is initialized: it's necessary to be able + to track stack overrun. + */ + DBUG_ASSERT(thread_stack); + + /* Undocking the thread specific data. */ + my_pthread_setspecific_ptr(THR_THD, NULL); + my_pthread_setspecific_ptr(THR_MALLOC, NULL); + + return 0; +} + /* Cleanup after query. @@ -2040,7 +2058,7 @@ bool select_export::send_data(List<Item> &items) ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD), "string", printable_buff, - item->name, row_count); + item->name, static_cast<long>(row_count)); } else if (from_end_pos < res->ptr() + res->length()) { @@ -2049,7 +2067,7 @@ bool select_export::send_data(List<Item> &items) */ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, ER(WARN_DATA_TRUNCATED), - item->full_name(), row_count); + item->full_name(), static_cast<long>(row_count)); } cvt_str.length(bytes); res= &cvt_str; diff --git a/sql/sql_class.h b/sql/sql_class.h index b3e8fde8cda..6b82512677a 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1943,6 +1943,7 @@ public: void cleanup(void); void cleanup_after_query(); bool store_globals(); + bool restore_globals(); #ifdef SIGNAL_WITH_VIO_CLOSE inline void set_active_vio(Vio* vio) { diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 26e8c9c3c76..a019c653cfc 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2007 MySQL AB +/* Copyright (c) 2007, 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 @@ -11,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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* Functions to autenticate and handle reqests for a connection @@ -328,7 +327,7 @@ check_user(THD *thd, enum enum_server_command command, passwd_len != SCRAMBLE_LENGTH && passwd_len != SCRAMBLE_LENGTH_323) { - my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip); + my_error(ER_HANDSHAKE_ERROR, MYF(0)); DBUG_RETURN(1); } @@ -359,7 +358,7 @@ check_user(THD *thd, enum enum_server_command command, my_net_read(net) != SCRAMBLE_LENGTH_323 + 1) { inc_host_errors(&thd->remote.sin_addr); - my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip); + my_error(ER_HANDSHAKE_ERROR, MYF(0)); DBUG_RETURN(1); } /* Final attempt to check the user based on reply */ @@ -640,14 +639,21 @@ bool init_new_connection_handler_thread() } #ifndef EMBEDDED_LIBRARY + +/** Get a string according to the protocol of the underlying buffer. */ +typedef char * (*get_proto_string_func_t) (char **, size_t *, size_t *); + /** - Get a null character terminated string from a user-supplied buffer. + Get a string formatted according to the 4.1 version of the MySQL protocol. - @param buffer[in, out] Pointer to the buffer to be scanned. + @param buffer[in, out] Pointer to the user-supplied buffer to be scanned. @param max_bytes_available[in, out] Limit the bytes to scan. @param string_length[out] The number of characters scanned not including the null character. + @remark Strings are always null character terminated in this version of the + protocol. + @remark The string_length does not include the terminating null character. However, after the call, the buffer is increased by string_length+1 bytes, beyond the null character if there still available bytes to @@ -658,9 +664,9 @@ bool init_new_connection_handler_thread() */ static -char *get_null_terminated_string(char **buffer, - size_t *max_bytes_available, - size_t *string_length) +char *get_41_protocol_string(char **buffer, + size_t *max_bytes_available, + size_t *string_length) { char *str= (char *)memchr(*buffer, '\0', *max_bytes_available); @@ -670,7 +676,60 @@ char *get_null_terminated_string(char **buffer, *string_length= (size_t)(str - *buffer); *max_bytes_available-= *string_length + 1; str= *buffer; - *buffer += *string_length + 1; + *buffer += *string_length + 1; + + return str; +} + + +/** + Get a string formatted according to the 4.0 version of the MySQL protocol. + + @param buffer[in, out] Pointer to the user-supplied buffer to be scanned. + @param max_bytes_available[in, out] Limit the bytes to scan. + @param string_length[out] The number of characters scanned not including + the null character. + + @remark If there are not enough bytes left after the current position of + the buffer to satisfy the current string, the string is considered + to be empty and a pointer to empty_c_string is returned. + + @remark A string at the end of the packet is not null terminated. + + @return Pointer to beginning of the string scanned, or a pointer to a empty + string. +*/ +static +char *get_40_protocol_string(char **buffer, + size_t *max_bytes_available, + size_t *string_length) +{ + char *str; + size_t len; + + /* No bytes to scan left, treat string as empty. */ + if ((*max_bytes_available) == 0) + { + *string_length= 0; + return empty_c_string; + } + + str= (char *) memchr(*buffer, '\0', *max_bytes_available); + + /* + If the string was not null terminated by the client, + the remainder of the packet is the string. Otherwise, + advance the buffer past the end of the null terminated + string. + */ + if (str == NULL) + len= *string_length= *max_bytes_available; + else + len= (*string_length= (size_t)(str - *buffer)) + 1; + + str= *buffer; + *buffer+= len; + *max_bytes_available-= len; return str; } @@ -682,7 +741,7 @@ char *get_null_terminated_string(char **buffer, @param buffer[in, out] The buffer to scan; updates position after scan. @param max_bytes_available[in, out] Limit the number of bytes to scan @param string_length[out] Number of characters scanned - + @remark In case the length is zero, then the total size of the string is considered to be 1 byte; the size byte. @@ -767,7 +826,7 @@ static int check_connection(THD *thd) if (vio_peer_addr(net->vio, ip, &thd->peer_port)) { - my_error(ER_BAD_HOST_ERROR, MYF(0), thd->main_security_ctx.host_or_ip); + my_error(ER_BAD_HOST_ERROR, MYF(0)); return 1; } if (!(thd->main_security_ctx.ip= my_strdup(ip,MYF(MY_WME)))) @@ -849,7 +908,7 @@ static int check_connection(THD *thd) part at the end of packet. */ end= strmake(end, thd->scramble, SCRAMBLE_LENGTH_323) + 1; - + int2store(end, server_capabilites); /* write server characteristics: up to 16 bytes allowed */ end[2]=(char) default_charset_info->number; @@ -866,8 +925,7 @@ static int check_connection(THD *thd) (pkt_len= my_net_read(net)) == packet_error) { inc_host_errors(&thd->remote.sin_addr); - my_error(ER_HANDSHAKE_ERROR, MYF(0), - thd->main_security_ctx.host_or_ip); + my_error(ER_HANDSHAKE_ERROR, MYF(0)); return 1; } } @@ -1009,9 +1067,21 @@ static int check_connection(THD *thd) if ((thd->client_capabilities & CLIENT_TRANSACTIONS) && opt_using_transactions) net->return_status= &thd->server_status; - - user= get_null_terminated_string(&end, &bytes_remaining_in_packet, - &user_len); + + /* + The 4.0 and 4.1 versions of the protocol differ on how strings + are terminated. In the 4.0 version, if a string is at the end + of the packet, the string is not null terminated. Do not assume + that the returned string is always null terminated. + */ + get_proto_string_func_t get_string; + + if (thd->client_capabilities & CLIENT_PROTOCOL_41) + get_string= get_41_protocol_string; + else + get_string= get_40_protocol_string; + + user= get_string(&end, &bytes_remaining_in_packet, &user_len); if (user == NULL) goto error; @@ -1036,8 +1106,7 @@ static int check_connection(THD *thd) /* Old passwords are zero terminated strings. */ - passwd= get_null_terminated_string(&end, &bytes_remaining_in_packet, - &passwd_len); + passwd= get_string(&end, &bytes_remaining_in_packet, &passwd_len); } if (passwd == NULL) @@ -1048,8 +1117,7 @@ static int check_connection(THD *thd) if (thd->client_capabilities & CLIENT_CONNECT_WITH_DB) { - db= get_null_terminated_string(&end, &bytes_remaining_in_packet, - &db_len); + db= get_string(&end, &bytes_remaining_in_packet, &db_len); if (db == NULL) goto error; } @@ -1058,19 +1126,24 @@ static int check_connection(THD *thd) char user_buff[USERNAME_LENGTH + 1]; // buffer to store user in utf8 uint dummy_errors; - /* Since 4.1 all database names are stored in utf8 */ + /* + Copy and convert the user and database names to the character set used + by the server. Since 4.1 all database names are stored in UTF-8. Also, + ensure that the names are properly null-terminated as this is relied + upon later. + */ if (db) { - db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1, - system_charset_info, - db, db_len, - thd->charset(), &dummy_errors)]= 0; + db_len= copy_and_convert(db_buff, sizeof(db_buff)-1, system_charset_info, + db, db_len, thd->charset(), &dummy_errors); + db_buff[db_len]= '\0'; db= db_buff; } - user_buff[user_len= copy_and_convert(user_buff, sizeof(user_buff)-1, - system_charset_info, user, user_len, - thd->charset(), &dummy_errors)]= '\0'; + user_len= copy_and_convert(user_buff, sizeof(user_buff)-1, + system_charset_info, user, user_len, + thd->charset(), &dummy_errors); + user_buff[user_len]= '\0'; user= user_buff; /* If username starts and ends in "'", chop them off */ @@ -1100,7 +1173,7 @@ static int check_connection(THD *thd) error: inc_host_errors(&thd->remote.sin_addr); - my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip); + my_error(ER_HANDSHAKE_ERROR, MYF(0)); return 1; } diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index e2f93ee4de5..19f3255184e 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1,4 +1,4 @@ -/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc. +/* Copyright (c) 2000, 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 @@ -11,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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* Insert of records */ @@ -3780,7 +3779,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u) if (table->s->fields < values.elements) { - my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1); + my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1L); DBUG_RETURN(-1); } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 8ef23806d91..ecc43f54fa5 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 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 @@ -11,7 +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 */ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #define MYSQL_LEX 1 #include "mysql_priv.h" @@ -3981,8 +3981,7 @@ end_with_restore_list: hostname_requires_resolving(user->host.str)) push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_HOSTNAME_WONT_WORK, - ER(ER_WARN_HOSTNAME_WONT_WORK), - user->host.str); + ER(ER_WARN_HOSTNAME_WONT_WORK)); // Are we trying to change a password of another user DBUG_ASSERT(user->host.str != 0); if (strcmp(thd->security_ctx->user, user->user.str) || @@ -5889,7 +5888,7 @@ mysql_new_select(LEX *lex, bool move_down) lex->nest_level++; if (lex->nest_level > (int) MAX_SELECT_NESTING) { - my_error(ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT,MYF(0),MAX_SELECT_NESTING); + my_error(ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT, MYF(0)); DBUG_RETURN(1); } select_lex->nest_level= lex->nest_level; @@ -6936,7 +6935,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, When an error is returned, my_message may have not been called and the client will hang waiting for a response. */ - my_error(ER_UNKNOWN_ERROR, MYF(0), "FLUSH PRIVILEGES failed"); + my_error(ER_UNKNOWN_ERROR, MYF(0)); } } diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 30bfa9eb35f..0b103dcbda9 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -6571,7 +6571,7 @@ void set_key_field_ptr(KEY *key_info, const uchar *new_buf, void mem_alloc_error(size_t size) { - my_error(ER_OUTOFMEMORY, MYF(0), size); + my_error(ER_OUTOFMEMORY, MYF(0), static_cast<int>(size)); } #ifdef WITH_PARTITION_STORAGE_ENGINE diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 03a729258ca..15e2f2494b7 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2005 MySQL AB +/* Copyright (c) 2005, 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 @@ -11,7 +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 */ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "mysql_priv.h" #include <my_pthread.h> @@ -495,9 +495,11 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report) { free_plugin_mem(&plugin_dl); if (report & REPORT_TO_USER) - my_error(ER_OUTOFMEMORY, MYF(0), plugin_dl.dl.length); + my_error(ER_OUTOFMEMORY, MYF(0), + static_cast<int>(plugin_dl.dl.length)); if (report & REPORT_TO_LOG) - sql_print_error(ER(ER_OUTOFMEMORY), plugin_dl.dl.length); + sql_print_error(ER(ER_OUTOFMEMORY), + static_cast<int>(plugin_dl.dl.length)); DBUG_RETURN(0); } /* @@ -520,9 +522,10 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report) { free_plugin_mem(&plugin_dl); if (report & REPORT_TO_USER) - my_error(ER_OUTOFMEMORY, MYF(0), plugin_dl.dl.length); + my_error(ER_OUTOFMEMORY, MYF(0), static_cast<int>(plugin_dl.dl.length)); if (report & REPORT_TO_LOG) - sql_print_error(ER(ER_OUTOFMEMORY), plugin_dl.dl.length); + sql_print_error(ER(ER_OUTOFMEMORY), + static_cast<int>(plugin_dl.dl.length)); DBUG_RETURN(0); } plugin_dl.dl.length= copy_and_convert(plugin_dl.dl.str, plugin_dl.dl.length, @@ -534,9 +537,11 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report) { free_plugin_mem(&plugin_dl); if (report & REPORT_TO_USER) - my_error(ER_OUTOFMEMORY, MYF(0), sizeof(struct st_plugin_dl)); + my_error(ER_OUTOFMEMORY, MYF(0), + static_cast<int>(sizeof(struct st_plugin_dl))); if (report & REPORT_TO_LOG) - sql_print_error(ER(ER_OUTOFMEMORY), sizeof(struct st_plugin_dl)); + sql_print_error(ER(ER_OUTOFMEMORY), + static_cast<int>(sizeof(struct st_plugin_dl))); DBUG_RETURN(0); } DBUG_RETURN(tmp); diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index a94d1e519db..b296eb22cdb 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2002, 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 @@ -11,7 +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 */ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /** @file @@ -1375,7 +1375,7 @@ static int mysql_test_select(Prepared_statement *stmt, if (!lex->result && !(lex->result= new (stmt->mem_root) select_send)) { - my_error(ER_OUTOFMEMORY, MYF(0), sizeof(select_send)); + my_error(ER_OUTOFMEMORY, MYF(0), static_cast<int>(sizeof(select_send))); goto error; } @@ -2478,7 +2478,7 @@ void mysqld_stmt_execute(THD *thd, char *packet_arg, uint packet_length) if (!(stmt= find_prepared_statement(thd, stmt_id))) { char llbuf[22]; - my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), sizeof(llbuf), + my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), static_cast<int>(sizeof(llbuf)), llstr(stmt_id, llbuf), "mysqld_stmt_execute"); DBUG_VOID_RETURN; } @@ -2536,7 +2536,7 @@ void mysql_sql_stmt_execute(THD *thd) if (!(stmt= (Prepared_statement*) thd->stmt_map.find_by_name(name))) { my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), - name->length, name->str, "EXECUTE"); + static_cast<int>(name->length), name->str, "EXECUTE"); DBUG_VOID_RETURN; } @@ -2578,7 +2578,7 @@ void mysqld_stmt_fetch(THD *thd, char *packet, uint packet_length) if (!(stmt= find_prepared_statement(thd, stmt_id))) { char llbuf[22]; - my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), sizeof(llbuf), + my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), static_cast<int>(sizeof(llbuf)), llstr(stmt_id, llbuf), "mysqld_stmt_fetch"); DBUG_VOID_RETURN; } @@ -2645,7 +2645,7 @@ void mysqld_stmt_reset(THD *thd, char *packet) if (!(stmt= find_prepared_statement(thd, stmt_id))) { char llbuf[22]; - my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), sizeof(llbuf), + my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), static_cast<int>(sizeof(llbuf)), llstr(stmt_id, llbuf), "mysqld_stmt_reset"); DBUG_VOID_RETURN; } @@ -2720,7 +2720,7 @@ void mysql_sql_stmt_close(THD *thd) if (! (stmt= (Prepared_statement*) thd->stmt_map.find_by_name(name))) my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), - name->length, name->str, "DEALLOCATE PREPARE"); + static_cast<int>(name->length), name->str, "DEALLOCATE PREPARE"); else if (stmt->is_in_use()) my_error(ER_PS_NO_RECURSION, MYF(0)); else diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 5b835096042..da77bf329b1 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2428,12 +2428,11 @@ bool schema_table_store_record(THD *thd, TABLE *table) } -int make_table_list(THD *thd, SELECT_LEX *sel, - LEX_STRING *db_name, LEX_STRING *table_name) +static int make_table_list(THD *thd, SELECT_LEX *sel, + LEX_STRING *db_name, LEX_STRING *table_name) { Table_ident *table_ident; table_ident= new Table_ident(thd, *db_name, *table_name, 1); - sel->init_query(); if (!sel->add_table_to_list(thd, table_ident, 0, 0, TL_READ)) return 1; return 0; @@ -3003,79 +3002,179 @@ make_table_name_list(THD *thd, List<LEX_STRING> *table_names, LEX *lex, /** - @brief Fill I_S table for SHOW COLUMNS|INDEX commands + Fill I_S table with data obtained by performing full-blown table open. + + @param thd Thread handler. + @param is_show_fields_or_keys Indicates whether it is a legacy SHOW + COLUMNS or SHOW KEYS statement. + @param table TABLE object for I_S table to be filled. + @param schema_table I_S table description structure. + @param orig_db_name Database name. + @param orig_table_name Table name. + @param open_tables_state_backup Open_tables_state object which is used + to save/restore original status of + variables related to open tables state. + + @retval FALSE - Success. + @retval TRUE - Failure. +*/ - @param[in] thd thread handler - @param[in] tables TABLE_LIST for I_S table - @param[in] schema_table pointer to I_S structure - @param[in] open_tables_state_backup pointer to Open_tables_state object - which is used to save|restore original - status of variables related to - open tables state +static bool +fill_schema_table_by_open(THD *thd, bool is_show_fields_or_keys, + TABLE *table, ST_SCHEMA_TABLE *schema_table, + LEX_STRING *orig_db_name, + LEX_STRING *orig_table_name, + Open_tables_state *open_tables_state_backup) +{ + Query_arena i_s_arena(thd->mem_root, + Query_arena::CONVENTIONAL_EXECUTION), + backup_arena, *old_arena; + LEX *old_lex= thd->lex, temp_lex, *lex; + LEX_STRING db_name, table_name; + TABLE_LIST *table_list; + bool result= true; - @return Operation status - @retval 0 success - @retval 1 error -*/ + /* + When a view is opened its structures are allocated on a permanent + statement arena and linked into the LEX tree for the current statement + (this happens even in cases when view is handled through TEMPTABLE + algorithm). -static int -fill_schema_show_cols_or_idxs(THD *thd, TABLE_LIST *tables, - ST_SCHEMA_TABLE *schema_table, - Open_tables_state *open_tables_state_backup) -{ - LEX *lex= thd->lex; - bool res; - LEX_STRING tmp_lex_string, tmp_lex_string1, *db_name, *table_name; - enum_sql_command save_sql_command= lex->sql_command; - TABLE_LIST *show_table_list= tables->schema_select_lex->table_list.first; - TABLE *table= tables->table; - int error= 1; - DBUG_ENTER("fill_schema_show"); + To prevent this process from unnecessary hogging of memory in the permanent + arena of our I_S query and to avoid damaging its LEX we use temporary + arena and LEX for table/view opening. + + Use temporary arena instead of statement permanent arena. Also make + it active arena and save original one for successive restoring. + */ + old_arena= thd->stmt_arena; + thd->stmt_arena= &i_s_arena; + thd->set_n_backup_active_arena(&i_s_arena, &backup_arena); + + /* Prepare temporary LEX. */ + thd->lex= lex= &temp_lex; + lex_start(thd); + + /* Disable constant subquery evaluation as we won't be locking tables. */ + lex->context_analysis_only= CONTEXT_ANALYSIS_ONLY_VIEW; - lex->all_selects_list= tables->schema_select_lex; /* - Restore thd->temporary_tables to be able to process - temporary tables(only for 'show index' & 'show columns'). - This should be changed when processing of temporary tables for - I_S tables will be done. + Some of process_table() functions rely on wildcard being passed from + old LEX (or at least being initialized). */ - thd->temporary_tables= open_tables_state_backup->temporary_tables; + lex->wild= old_lex->wild; + + /* + Since make_table_list() might change database and table name passed + to it we create copies of orig_db_name and orig_table_name here. + These copies are used for make_table_list() while unaltered values + are passed to process_table() functions. + */ + if (!thd->make_lex_string(&db_name, orig_db_name->str, + orig_db_name->length, FALSE) || + !thd->make_lex_string(&table_name, orig_table_name->str, + orig_table_name->length, FALSE)) + goto end; + + /* + Create table list element for table to be open. Link it with the + temporary LEX. The latter is required to correctly open views and + produce table describing their structure. + */ + if (make_table_list(thd, &lex->select_lex, &db_name, &table_name)) + goto end; + + table_list= lex->select_lex.table_list.first; + + if (is_show_fields_or_keys) + { + /* + Restore thd->temporary_tables to be able to process + temporary tables (only for 'show index' & 'show columns'). + This should be changed when processing of temporary tables for + I_S tables will be done. + */ + thd->temporary_tables= open_tables_state_backup->temporary_tables; + } + else + { + /* + Apply optimization flags for table opening which are relevant for + this I_S table. We can't do this for SHOW COLUMNS/KEYS because of + backward compatibility. + */ + table_list->i_s_requested_object= schema_table->i_s_requested_object; + } + /* Let us set fake sql_command so views won't try to merge themselves into main statement. If we don't do this, SELECT * from information_schema.xxxx will cause problems. - SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()' + SQLCOM_SHOW_FIELDS is used because it satisfies + 'only_view_structure()'. */ lex->sql_command= SQLCOM_SHOW_FIELDS; - res= open_normal_and_derived_tables(thd, show_table_list, - MYSQL_LOCK_IGNORE_FLUSH); - lex->sql_command= save_sql_command; + + result= open_normal_and_derived_tables(thd, table_list, + MYSQL_LOCK_IGNORE_FLUSH); + /* - get_all_tables() returns 1 on failure and 0 on success thus - return only these and not the result code of ::process_table() - - We should use show_table_list->alias instead of - show_table_list->table_name because table_name - could be changed during opening of I_S tables. It's safe - to use alias because alias contains original table name - in this case(this part of code is used only for - 'show columns' & 'show statistics' commands). + Restore old value of sql_command back as it is being looked at in + process_table() function. */ - table_name= thd->make_lex_string(&tmp_lex_string1, show_table_list->alias, - strlen(show_table_list->alias), FALSE); - if (!show_table_list->view) - db_name= thd->make_lex_string(&tmp_lex_string, show_table_list->db, - show_table_list->db_length, FALSE); - else - db_name= &show_table_list->view_db; - - - error= test(schema_table->process_table(thd, show_table_list, - table, res, db_name, - table_name)); - thd->temporary_tables= 0; - close_tables_for_reopen(thd, &show_table_list); - DBUG_RETURN(error); + lex->sql_command= old_lex->sql_command; + + /* + XXX: show_table_list has a flag i_is_requested, + and when it's set, open_normal_and_derived_tables() + can return an error without setting an error message + in THD, which is a hack. This is why we have to + check for res, then for thd->is_error() and only then + for thd->main_da.sql_errno(). + + Again we don't do this for SHOW COLUMNS/KEYS because + of backward compatibility. + */ + if (!is_show_fields_or_keys && result && thd->is_error() && + thd->main_da.sql_errno() == ER_NO_SUCH_TABLE) + { + /* + Hide error for a non-existing table. + For example, this error can occur when we use a where condition + with a db name and table, but the table does not exist. + */ + result= 0; + thd->clear_error(); + } + else + { + result= schema_table->process_table(thd, table_list, + table, result, + orig_db_name, + orig_table_name); + } + +end: + lex->unit.cleanup(); + + /* Restore original LEX value, statement's arena and THD arena values. */ + lex_end(thd->lex); + + if (i_s_arena.free_list) + i_s_arena.free_items(); + + /* + For safety reset list of open temporary tables before closing + all tables open within this Open_tables_state. + */ + thd->temporary_tables= NULL; + close_thread_tables(thd); + thd->lex= old_lex; + + thd->stmt_arena= old_arena; + thd->restore_active_arena(&i_s_arena, &backup_arena); + + return result; } @@ -3300,11 +3399,8 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) { LEX *lex= thd->lex; TABLE *table= tables->table; - SELECT_LEX *old_all_select_lex= lex->all_selects_list; - enum_sql_command save_sql_command= lex->sql_command; SELECT_LEX *lsel= tables->schema_select_lex; ST_SCHEMA_TABLE *schema_table= tables->schema_table; - SELECT_LEX sel; LOOKUP_FIELD_VALUES lookup_field_vals; LEX_STRING *db_name, *table_name; bool with_i_schema; @@ -3312,20 +3408,14 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) List<LEX_STRING> db_names; List_iterator_fast<LEX_STRING> it(db_names); COND *partial_cond= 0; - uint derived_tables= lex->derived_tables; int error= 1; Open_tables_state open_tables_state_backup; - uint8 save_context_analysis_only= lex->context_analysis_only; - Query_tables_list query_tables_list_backup; #ifndef NO_EMBEDDED_ACCESS_CHECKS Security_context *sctx= thd->security_ctx; #endif uint table_open_method; DBUG_ENTER("get_all_tables"); - lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW; - lex->reset_n_backup_query_tables_list(&query_tables_list_backup); - /* We should not introduce deadlocks even if we already have some tables open and locked, since we won't lock tables which we will @@ -3340,8 +3430,18 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) */ if (lsel && lsel->table_list.first) { - error= fill_schema_show_cols_or_idxs(thd, tables, schema_table, - &open_tables_state_backup); + LEX_STRING db_name, table_name; + + db_name.str= lsel->table_list.first->db; + db_name.length= lsel->table_list.first->db_length; + + table_name.str= lsel->table_list.first->table_name; + table_name.length= lsel->table_list.first->table_name_length; + + error= fill_schema_table_by_open(thd, TRUE, + table, schema_table, + &db_name, &table_name, + &open_tables_state_backup); goto err; } @@ -3399,12 +3499,6 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) it.rewind(); /* To get access to new elements in basis list */ while ((db_name= it++)) { - LEX_STRING orig_db_name; - - /* db_name can be changed in make_table_list() func */ - if (!thd->make_lex_string(&orig_db_name, db_name->str, - db_name->length, FALSE)) - goto err; #ifndef NO_EMBEDDED_ACCESS_CHECKS if (!(check_access(thd,SELECT_ACL, db_name->str, &thd->col_access, 0, 1, with_i_schema) || @@ -3466,64 +3560,14 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) continue; } - int res; - LEX_STRING tmp_lex_string; - /* - Set the parent lex of 'sel' because it is needed by - sel.init_query() which is called inside make_table_list. - */ thd->no_warnings_for_error= 1; - sel.parent_lex= lex; - if (make_table_list(thd, &sel, db_name, table_name)) - goto err; - TABLE_LIST *show_table_list= sel.table_list.first; - lex->all_selects_list= &sel; - lex->derived_tables= 0; - lex->sql_command= SQLCOM_SHOW_FIELDS; - show_table_list->i_s_requested_object= - schema_table->i_s_requested_object; + DEBUG_SYNC(thd, "before_open_in_get_all_tables"); - res= open_normal_and_derived_tables(thd, show_table_list, - MYSQL_LOCK_IGNORE_FLUSH); - lex->sql_command= save_sql_command; - /* - XXX: show_table_list has a flag i_is_requested, - and when it's set, open_normal_and_derived_tables() - can return an error without setting an error message - in THD, which is a hack. This is why we have to - check for res, then for thd->is_error() only then - for thd->main_da.sql_errno(). - */ - if (res && thd->is_error() && - thd->main_da.sql_errno() == ER_NO_SUCH_TABLE) - { - /* - Hide error for not existing table. - This error can occur for example when we use - where condition with db name and table name and this - table does not exist. - */ - res= 0; - thd->clear_error(); - } - else - { - /* - We should use show_table_list->alias instead of - show_table_list->table_name because table_name - could be changed during opening of I_S tables. It's safe - to use alias because alias contains original table name - in this case. - */ - thd->make_lex_string(&tmp_lex_string, show_table_list->alias, - strlen(show_table_list->alias), FALSE); - res= schema_table->process_table(thd, show_table_list, table, - res, &orig_db_name, - &tmp_lex_string); - close_tables_for_reopen(thd, &show_table_list); - } - DBUG_ASSERT(!lex->query_tables_own_last); - if (res) + + if (fill_schema_table_by_open(thd, FALSE, + table, schema_table, + db_name, table_name, + &open_tables_state_backup)) goto err; } } @@ -3539,11 +3583,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) error= 0; err: thd->restore_backup_open_tables_state(&open_tables_state_backup); - lex->restore_backup_query_tables_list(&query_tables_list_backup); - lex->derived_tables= derived_tables; - lex->all_selects_list= old_all_select_lex; - lex->context_analysis_only= save_context_analysis_only; - lex->sql_command= save_sql_command; + DBUG_RETURN(error); } @@ -7150,7 +7190,7 @@ static TABLE_LIST *get_trigger_table_impl( if (!(table= (TABLE_LIST *)thd->calloc(sizeof(TABLE_LIST)))) { - my_error(ER_OUTOFMEMORY, MYF(0), sizeof(TABLE_LIST)); + my_error(ER_OUTOFMEMORY, MYF(0), static_cast<int>(sizeof(TABLE_LIST))); return NULL; } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index c5fc037a49e..58e2684e5b7 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2452,7 +2452,8 @@ int prepare_create_field(Create_field *sql_field, MAX_FIELD_CHARLENGTH) { my_printf_error(ER_TOO_BIG_FIELDLENGTH, ER(ER_TOO_BIG_FIELDLENGTH), - MYF(0), sql_field->field_name, MAX_FIELD_CHARLENGTH); + MYF(0), sql_field->field_name, + static_cast<ulong>(MAX_FIELD_CHARLENGTH)); DBUG_RETURN(1); } } @@ -3504,7 +3505,8 @@ static bool prepare_blob_field(THD *thd, Create_field *sql_field) MODE_STRICT_ALL_TABLES))) { my_error(ER_TOO_BIG_FIELDLENGTH, MYF(0), sql_field->field_name, - MAX_FIELD_VARCHARLENGTH / sql_field->charset->mbmaxlen); + static_cast<ulong>(MAX_FIELD_VARCHARLENGTH / + sql_field->charset->mbmaxlen)); DBUG_RETURN(1); } sql_field->sql_type= MYSQL_TYPE_BLOB; diff --git a/sql/table.cc b/sql/table.cc index 7dbf02027fa..22333a2b76b 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -2265,7 +2265,7 @@ void open_table_error(TABLE_SHARE *share, int error, int db_errno, int errarg) default: /* Better wrong error than none */ case 4: strxmov(buff, share->normalized_path.str, reg_ext, NullS); - my_error(ER_NOT_FORM_FILE, errortype, buff, 0); + my_error(ER_NOT_FORM_FILE, errortype, buff); break; } DBUG_VOID_RETURN; @@ -2835,7 +2835,8 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def) report_error(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE, ER(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE), table->alias, table_def->count, table->s->fields, - table->s->mysql_version, MYSQL_VERSION_ID); + static_cast<int>(table->s->mysql_version), + MYSQL_VERSION_ID); DBUG_RETURN(TRUE); } else if (MYSQL_VERSION_ID == table->s->mysql_version) diff --git a/sql/unireg.cc b/sql/unireg.cc index 84160da9d77..e4fdf2af713 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2006 MySQL AB +/* Copyright (c) 2000, 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 @@ -11,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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* Functions to create a unireg form-file from a FIELD and a fieldname-fieldinfo @@ -237,13 +236,14 @@ bool mysql_create_frm(THD *thd, const char *file_name, if ((thd->variables.sql_mode & (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES))) { - my_error(ER_TOO_LONG_TABLE_COMMENT, MYF(0), table, tmp_len); + my_error(ER_TOO_LONG_TABLE_COMMENT, MYF(0), table, + static_cast<ulong>(tmp_len)); goto err; } push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_TOO_LONG_TABLE_COMMENT, ER(ER_TOO_LONG_TABLE_COMMENT), - table, tmp_len); + table, static_cast<ulong>(tmp_len)); create_info->comment.length= tmp_len; } @@ -621,13 +621,14 @@ static bool pack_header(uchar *forminfo, enum legacy_db_type table_type, if ((current_thd->variables.sql_mode & (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES))) { - my_error(ER_TOO_LONG_FIELD_COMMENT, MYF(0), field->field_name, tmp_len); + my_error(ER_TOO_LONG_FIELD_COMMENT, MYF(0), field->field_name, + static_cast<ulong>(tmp_len)); DBUG_RETURN(1); } push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_TOO_LONG_FIELD_COMMENT, ER(ER_TOO_LONG_FIELD_COMMENT), - field->field_name, tmp_len); + field->field_name, static_cast<ulong>(tmp_len)); field->comment.length= tmp_len; } @@ -711,7 +712,7 @@ static bool pack_header(uchar *forminfo, enum legacy_db_type table_type, if (reclength > (ulong) file->max_record_length()) { - my_error(ER_TOO_BIG_ROWSIZE, MYF(0), (uint) file->max_record_length()); + my_error(ER_TOO_BIG_ROWSIZE, MYF(0), static_cast<long>(file->max_record_length())); DBUG_RETURN(1); } /* Hack to avoid bugs with small static rows in MySQL */ diff --git a/storage/archive/azio.c b/storage/archive/azio.c index c1dd6e6f38c..aaf8233a30c 100644 --- a/storage/archive/azio.c +++ b/storage/archive/azio.c @@ -114,6 +114,15 @@ int az_open (azio_stream *s, const char *path, int Flags, File fd) errno = 0; s->file = fd < 0 ? my_open(path, Flags, MYF(0)) : fd; + DBUG_EXECUTE_IF("simulate_archive_open_failure", + { + if (s->file >= 0) + { + my_close(s->file, MYF(0)); + s->file= -1; + my_errno= EMFILE; + } + }); if (s->file < 0 ) { diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index e5c483daac5..4da98507dcf 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -1586,11 +1586,12 @@ int ha_archive::check(THD* thd, HA_CHECK_OPT* check_opt) azflush(&(share->archive_write), Z_SYNC_FLUSH); pthread_mutex_unlock(&share->mutex); + if (init_archive_reader()) + DBUG_RETURN(HA_ADMIN_CORRUPT); /* Now we will rewind the archive file so that we are positioned at the start of the file. */ - init_archive_reader(); read_data_header(&archive); while (!(rc= get_row(&archive, table->record[0]))) count--; diff --git a/storage/innobase/dict/dict0load.c b/storage/innobase/dict/dict0load.c index c505bfbd6c4..7e820cfb08d 100644 --- a/storage/innobase/dict/dict0load.c +++ b/storage/innobase/dict/dict0load.c @@ -454,9 +454,11 @@ dict_load_report_deleted_index( /************************************************************************ Loads definitions for index fields. */ static -void +ulint dict_load_fields( /*=============*/ + /* out: DB_SUCCESS if ok, DB_CORRUPTION + if failed */ dict_table_t* table, /* in: table */ dict_index_t* index, /* in: index whose fields to load */ mem_heap_t* heap) /* in: memory heap for temporary storage */ @@ -474,6 +476,7 @@ dict_load_fields( byte* buf; ulint i; mtr_t mtr; + ulint error = DB_SUCCESS; ut_ad(mutex_own(&(dict_sys->mutex))); @@ -535,6 +538,26 @@ dict_load_fields( field = rec_get_nth_field_old(rec, 4, &len); + if (prefix_len >= DICT_MAX_INDEX_COL_LEN) { + fprintf(stderr, "InnoDB: Error: load index" + " '%s' failed.\n" + "InnoDB: index field '%s' has a prefix" + " length of %lu bytes,\n" + "InnoDB: which exceeds the" + " maximum limit of %lu bytes.\n" + "InnoDB: Please use server that" + " supports long index prefix\n" + "InnoDB: or turn on" + " innodb_force_recovery to load" + " the table\n", + index->name, mem_heap_strdupl( + heap, (char*) field, len), + (ulong) prefix_len, + (ulong) (DICT_MAX_INDEX_COL_LEN - 1)); + error = DB_CORRUPTION; + goto func_exit; + } + dict_mem_index_add_field(index, mem_heap_strdupl(heap, (char*) field, len), @@ -543,8 +566,10 @@ dict_load_fields( btr_pcur_move_to_next_user_rec(&pcur, &mtr); } +func_exit: btr_pcur_close(&pcur); mtr_commit(&mtr); + return(error); } /************************************************************************ @@ -701,10 +726,28 @@ dict_load_indexes( space, type, n_fields); index->id = id; - dict_load_fields(table, index, heap); + error = dict_load_fields(table, index, heap); + + if (error != DB_SUCCESS) { + fprintf(stderr, "InnoDB: Error: load index '%s'" + " for table '%s' failed\n", + index->name, table->name); + + /* If the force recovery flag is set, and + if the failed index is not the primary index, we + will continue and open other indexes */ + if (srv_force_recovery + && !(index->type & DICT_CLUSTERED)) { + error = DB_SUCCESS; + goto next_rec; + } else { + goto func_exit; + } + } + dict_index_add_to_cache(table, index, page_no); } - +next_rec: btr_pcur_move_to_next_user_rec(&pcur, &mtr); } @@ -881,9 +924,18 @@ err_exit: } else { table->fk_max_recusive_level = 0; } - } else if (!srv_force_recovery) { - dict_table_remove_from_cache(table); - table = NULL; + } else { + dict_index_t* index; + + /* Make sure that at least the clustered index was loaded. + Otherwise refuse to load the table */ + index = dict_table_get_first_index(table); + + if (!srv_force_recovery || !index + || !(index->type & DICT_CLUSTERED)) { + dict_table_remove_from_cache(table); + table = NULL; + } } #if 0 if (err != DB_SUCCESS && table != NULL) { diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 2afacf6d2a8..dfe13ccbbfe 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -7325,10 +7325,18 @@ ha_innobase::external_lock( reset_template(prebuilt); - if (lock_type == F_WRLCK) { + if (lock_type == F_WRLCK + || (table->s->tmp_table + && thd_sql_command(thd) == SQLCOM_LOCK_TABLES)) { /* If this is a SELECT, then it is in UPDATE TABLE ... - or SELECT ... FOR UPDATE */ + or SELECT ... FOR UPDATE + + For temporary tables which are locked for READ by LOCK TABLES + updates are still allowed by SQL-layer. In order to accomodate + for such a situation we always request X-lock for such table + at LOCK TABLES time. + */ prebuilt->select_lock_type = LOCK_X; prebuilt->stored_select_lock_type = LOCK_X; } diff --git a/storage/innodb_plugin/dict/dict0load.c b/storage/innodb_plugin/dict/dict0load.c index c3825902536..7a0b6edcb08 100644 --- a/storage/innodb_plugin/dict/dict0load.c +++ b/storage/innodb_plugin/dict/dict0load.c @@ -553,9 +553,10 @@ dict_load_columns( } /********************************************************************//** -Loads definitions for index fields. */ +Loads definitions for index fields. +@return DB_SUCCESS if ok, DB_CORRUPTION if failed */ static -void +ulint dict_load_fields( /*=============*/ dict_index_t* index, /*!< in: index whose fields to load */ @@ -574,6 +575,7 @@ dict_load_fields( byte* buf; ulint i; mtr_t mtr; + ulint error = DB_SUCCESS; ut_ad(mutex_own(&(dict_sys->mutex))); @@ -640,6 +642,26 @@ dict_load_fields( field = rec_get_nth_field_old(rec, 4, &len); + if (prefix_len >= DICT_MAX_INDEX_COL_LEN) { + fprintf(stderr, "InnoDB: Error: load index" + " '%s' failed.\n" + "InnoDB: index field '%s' has a prefix" + " length of %lu bytes,\n" + "InnoDB: which exceeds the" + " maximum limit of %lu bytes.\n" + "InnoDB: Please use server that" + " supports long index prefix\n" + "InnoDB: or turn on" + " innodb_force_recovery to load" + " the table\n", + index->name, mem_heap_strdupl( + heap, (char*) field, len), + (ulong) prefix_len, + (ulong) (DICT_MAX_INDEX_COL_LEN - 1)); + error = DB_CORRUPTION; + goto func_exit; + } + dict_mem_index_add_field(index, mem_heap_strdupl(heap, (char*) field, len), @@ -649,8 +671,10 @@ next_rec: btr_pcur_move_to_next_user_rec(&pcur, &mtr); } +func_exit: btr_pcur_close(&pcur); mtr_commit(&mtr); + return(error); } /********************************************************************//** @@ -801,7 +825,25 @@ dict_load_indexes( space, type, n_fields); index->id = id; - dict_load_fields(index, heap); + error = dict_load_fields(index, heap); + + if (error != DB_SUCCESS) { + fprintf(stderr, "InnoDB: Error: load index '%s'" + " for table '%s' failed\n", + index->name, table->name); + + /* If the force recovery flag is set, and + if the failed index is not the primary index, we + will continue and open other indexes */ + if (srv_force_recovery + && !(index->type & DICT_CLUSTERED)) { + error = DB_SUCCESS; + goto next_rec; + } else { + goto func_exit; + } + } + error = dict_index_add_to_cache(table, index, page_no, FALSE); /* The data dictionary tables should never contain @@ -1027,9 +1069,18 @@ err_exit: } else { table->fk_max_recusive_level = 0; } - } else if (!srv_force_recovery) { - dict_table_remove_from_cache(table); - table = NULL; + } else { + dict_index_t* index; + + /* Make sure that at least the clustered index was loaded. + Otherwise refuse to load the table */ + index = dict_table_get_first_index(table); + + if (!srv_force_recovery || !index + || !(index->type & DICT_CLUSTERED)) { + dict_table_remove_from_cache(table); + table = NULL; + } } #if 0 if (err != DB_SUCCESS && table != NULL) { diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index 2b0dbf82b34..a9c9f379528 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -8642,10 +8642,18 @@ ha_innobase::external_lock( reset_template(prebuilt); - if (lock_type == F_WRLCK) { + if (lock_type == F_WRLCK + || (table->s->tmp_table + && thd_sql_command(thd) == SQLCOM_LOCK_TABLES)) { /* If this is a SELECT, then it is in UPDATE TABLE ... - or SELECT ... FOR UPDATE */ + or SELECT ... FOR UPDATE + + For temporary tables which are locked for READ by LOCK TABLES + updates are still allowed by SQL-layer. In order to accomodate + for such a situation we always request X-lock for such table + at LOCK TABLES time. + */ prebuilt->select_lock_type = LOCK_X; prebuilt->stored_select_lock_type = LOCK_X; } diff --git a/storage/innodb_plugin/include/univ.i b/storage/innodb_plugin/include/univ.i index dc75879dbad..6ac227a59a6 100644 --- a/storage/innodb_plugin/include/univ.i +++ b/storage/innodb_plugin/include/univ.i @@ -46,7 +46,7 @@ Created 1/20/1994 Heikki Tuuri #define INNODB_VERSION_MAJOR 1 #define INNODB_VERSION_MINOR 0 -#define INNODB_VERSION_BUGFIX 16 +#define INNODB_VERSION_BUGFIX 17 /* The following is the InnoDB version as shown in SELECT plugin_version FROM information_schema.plugins; diff --git a/strings/decimal.c b/strings/decimal.c index e89669c3de5..32e35a64de7 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -320,8 +320,8 @@ int decimal_actual_fraction(decimal_t *from) from - value to convert to - points to buffer where string representation should be stored - *to_len - in: size of to buffer - out: length of the actually written string + *to_len - in: size of to buffer (incl. terminating '\0') + out: length of the actually written string (excl. '\0') fixed_precision - 0 if representation can be variable length and fixed_decimals will not be checked in this case. Put number as with fixed point position with this @@ -338,6 +338,7 @@ int decimal2string(decimal_t *from, char *to, int *to_len, int fixed_precision, int fixed_decimals, char filler) { + /* {intg_len, frac_len} output widths; {intg, frac} places in input */ int len, intg, frac= from->frac, i, intg_len, frac_len, fill; /* number digits before decimal point */ int fixed_intg= (fixed_precision ? |