From 1d0a11fd159fb05cd1c5c553b152c3848ceb552f Mon Sep 17 00:00:00 2001 From: "Tatiana A. Nurnberg" Date: Thu, 11 Nov 2010 09:46:49 +0000 Subject: [PATCH 01/24] Bug#55436: buffer overflow in debug binary of dbug_buff in Field_new_decimal::store_value There were some misunderstandings about parameters pertaining to buffer-size. Patches fixes the reported off by one and clarifies the documentation. --- mysql-test/r/type_newdecimal.result | 13 +++++++++++++ mysql-test/t/type_newdecimal.test | 14 ++++++++++++++ sql/field.cc | 6 +++--- sql/my_decimal.cc | 11 ++++++----- sql/my_decimal.h | 3 ++- strings/decimal.c | 5 +++-- 6 files changed, 41 insertions(+), 11 deletions(-) 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/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/field.cc b/sql/field.cc index c887a5f1c9b..cb23ae4fe9f 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -2583,7 +2583,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 +2598,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 +2673,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 diff --git a/sql/my_decimal.cc b/sql/my_decimal.cc index 3aa01880b83..a38dc341684 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) @@ -275,7 +276,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 21669e82c44..2c13142bb60 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/strings/decimal.c b/strings/decimal.c index bda296ce832..c91a5d1a7ec 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 ? From b8fe42d1275d2683790f213fe7baac3293812049 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Tue, 3 May 2011 16:08:25 +0200 Subject: [PATCH 02/24] Bug #11752142 43247: SUITE//INCLUDE: NO SUCH FILE OR DIRECTORY The originally reported dirs have been removed But found suite/bugs, removed from mysql-test/Makefile.am --- mysql-test/Makefile.am | 1 - 1 file changed, 1 deletion(-) 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 \ From ce2ed6197c42f4aedc1323e63603f5dabc8e0c67 Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Wed, 4 May 2011 03:06:21 -0700 Subject: [PATCH 03/24] Fix bug #11796673 address backward compatibility on index with large prefix (>=768). Table with such large prefix index will not be loaded into memory (for its metadata), unless innodb_force_recovery is on. rb://604 Approved by Marko --- storage/innobase/dict/dict0load.c | 64 +++++++++++++++++++++++--- storage/innodb_plugin/dict/dict0load.c | 63 ++++++++++++++++++++++--- 2 files changed, 115 insertions(+), 12 deletions(-) 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/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) { From e8b54a7ce935a6a66d7abe18d60a6cf4b9ddbac9 Mon Sep 17 00:00:00 2001 From: Serge Kozlov Date: Mon, 9 May 2011 23:14:24 +0400 Subject: [PATCH 04/24] WL#5867 Replaced the error code by error name --- mysql-test/suite/binlog/t/binlog_bug23533.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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%'; From 6209f47fd2658886a348bcf6c12903998a74bf31 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 10 May 2011 15:43:30 +0300 Subject: [PATCH 05/24] Increment InnoDB Plugin version from 1.0.16 to 1.0.17. InnoDB Plugin 1.0.16 has been released with MySQL 5.1.57. --- storage/innodb_plugin/include/univ.i | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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; From 473173632021092d09c8955b2d260cb9a0c5fa5e Mon Sep 17 00:00:00 2001 From: Vinay Fisrekar Date: Sat, 14 May 2011 21:44:49 +0530 Subject: [PATCH 06/24] Adding bug scenario for data types in main suite Impementing Test Review Comment. Bug test scenario: SELECT is not returning result set for "equal" (=) and "NULL safe equal operator" (<=>) on BIT data type. Extending this scenario for all data types --- .../r/implicit_char_to_num_conversion.result | 366 ++++++++++++++++++ .../t/implicit_char_to_num_conversion.test | 174 +++++++++ 2 files changed, 540 insertions(+) create mode 100644 mysql-test/r/implicit_char_to_num_conversion.result create mode 100644 mysql-test/t/implicit_char_to_num_conversion.test 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 = ; +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 = ; +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 = ; +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 = ; +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 = ; +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 = ; +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 = ; +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 = ; +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 = ; +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 = ; +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/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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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; From 25221cccd2dde986c91c1ad3bdca3ee2869ed2ac Mon Sep 17 00:00:00 2001 From: Guilhem Bichot Date: Mon, 16 May 2011 22:04:01 +0200 Subject: [PATCH 07/24] Fix for BUG#11755168 '46895: test "outfile_loaddata" fails (reproducible)'. In sql_class.cc, 'row_count', of type 'ha_rows', was used as last argument for ER_TRUNCATED_WRONG_VALUE_FOR_FIELD which is "Incorrect %-.32s value: '%-.128s' for column '%.192s' at row %ld". So 'ha_rows' was used as 'long'. On SPARC32 Solaris builds, 'long' is 4 bytes and 'ha_rows' is 'longlong' i.e. 8 bytes. So the printf-like code was reading only the first 4 bytes. Because the CPU is big-endian, 1LL is 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x01 so the first four bytes yield 0. So the warning message had "row 0" instead of "row 1" in test outfile_loaddata.test: -Warning 1366 Incorrect string value: '\xE1\xE2\xF7' for column 'b' at row 1 +Warning 1366 Incorrect string value: '\xE1\xE2\xF7' for column 'b' at row 0 All error-messaging functions which internally invoke some printf-life function are potential candidate for such mistakes. One apparently easy way to catch such mistakes is to use ATTRIBUTE_FORMAT (from my_attribute.h). But this works only when call site has both: a) the format as a string literal b) the types of arguments. So: func(ER(ER_BLAH), 10); will silently not be checked, because ER(ER_BLAH) is not known at compile time (it is known at run-time, and depends on the chosen language). And func("%s", a va_list argument); has the same problem, as the *real* type of arguments is not known at this site at compile time (it's known in some caller). Moreover, func(ER(ER_BLAH)); though possibly correct (if ER(ER_BLAH) has no '%' markers), will not compile (gcc says "error: format not a string literal and no format arguments"). Consequences: 1) ATTRIBUTE_FORMAT is here added only to functions which in practice take "string literal" formats: "my_error_reporter" and "print_admin_msg". 2) it cannot be added to the other functions: my_error(), push_warning_printf(), Table_check_intact::report_error(), general_log_print(). To do a one-time check of functions listed in (2), the following "static code analysis" has been done: 1) replace my_error(ER_xxx, arguments for substitution in format) with the equivalent my_printf_error(ER_xxx,ER(ER_xxx), arguments for substitution in format), so that we have ER(ER_xxx) and the arguments *in the same call site* 2) add ATTRIBUTE_FORMAT to push_warning_printf(), Table_check_intact::report_error(), general_log_print() 3) replace ER(xxx) with the hard-coded English text found in errmsg.txt (like: ER(ER_UNKNOWN_ERROR) is replaced with "Unknown error"), so that a call site has the format as string literal 4) this way, ATTRIBUTE_FORMAT can effectively do its job 5) compile, fix errors detected by ATTRIBUTE_FORMAT 6) revert steps 1-2-3. The present patch has no compiler error when submitted again to the static code analysis above. It cannot catch all problems though: see Field::set_warning(), in which a call to push_warning_printf() has a variable error (thus, not replacable by a string literal); I checked set_warning() calls by hand though. See also WL 5883 for one proposal to avoid such bugs from appearing again in the future. The issues fixed in the patch are: a) mismatch in types (like 'int' passed to '%ld') b) more arguments passed than specified in the format. This patch resolves mismatches by changing the type/number of arguments, not by changing error messages of sql/share/errmsg.txt. The latter would be wrong, per the following old rule: errmsg.txt must be as stable as possible; no insertions or deletions of messages, no changes of type or number of printf-like format specifiers, are allowed, as long as the change impacts a message already released in a GA version. If this rule is not followed: - Connectors, which use error message numbers, will be confused (by insertions/deletions of messages) - using errmsg.sys of MySQL 5.1.n with mysqld of MySQL 5.1.(n+1) could produce wrong messages or crash; such usage can easily happen if installing 5.1.(n+1) while /etc/my.cnf still has --language=/path/to/5.1.n/xxx; or if copying mysqld from 5.1.(n+1) into a 5.1.n installation. When fixing b), I have verified that the superfluous arguments were not used in the format in the first 5.1 GA (5.1.30 'bteam@astra04-20081114162938-z8mctjp6st27uobm'). Had they been used, then passing them today, even if the message doesn't use them anymore, would have been necessary, as explained above. --- include/my_getopt.h | 8 +++--- mysql-test/collections/default.experimental | 1 - sql/derror.cc | 21 ++++------------ sql/events.cc | 8 +++--- sql/field.cc | 13 +++++----- sql/ha_ndbcluster.cc | 7 +++--- sql/ha_ndbcluster_binlog.cc | 15 +++++------ sql/ha_partition.cc | 8 ++++-- sql/handler.cc | 5 ++-- sql/item_create.cc | 18 ++++++------- sql/item_func.cc | 9 +++---- sql/item_strfunc.cc | 8 +++--- sql/mysql_priv.h | 6 ++--- sql/sp_head.cc | 6 ++--- sql/sql_acl.cc | 5 ++-- sql/sql_base.cc | 4 +-- sql/sql_binlog.cc | 4 +-- sql/sql_class.cc | 9 +++---- sql/sql_connect.cc | 28 ++++++++++----------- sql/sql_insert.cc | 7 +++--- sql/sql_parse.cc | 11 ++++---- sql/sql_partition.cc | 2 +- sql/sql_plugin.cc | 21 ++++++++++------ sql/sql_prepare.cc | 16 ++++++------ sql/sql_show.cc | 2 +- sql/sql_table.cc | 6 +++-- sql/table.cc | 5 ++-- sql/unireg.cc | 17 +++++++------ 28 files changed, 133 insertions(+), 137 deletions(-) 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/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index fb8c6845a5f..da2df7a72e8 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -19,7 +19,6 @@ innodb_plugin.* @solaris # Bug#56063 InnoDB Plugin mysql-tests f 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 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/events.cc b/sql/events.cc index afae512c61d..7edd863ac41 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" @@ -547,7 +547,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 +1150,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 a5f946d600c..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 @@ -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(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(length), + fld_name, static_cast(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(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(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. @@ -1023,6 +1023,10 @@ static int handle_opt_part(THD *thd, HA_CHECK_OPT *check_opt, (modelled after mi_check_print_msg) TODO: move this into the handler, or rewrite mysql_admin_table. */ +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, ...) 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(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(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(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(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(len), a->name, + static_cast(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(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..b1398b78b84 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; } @@ -2851,7 +2850,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(current_thd->variables. + max_allowed_packet)); goto err; } if (buffer.realloc((uint32)new_size)) diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 8f9a9080d12..664092adbc1 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 @@ -829,7 +829,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, diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 2473abea3c7..a4dd51d8a4a 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(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(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..100ccc46371 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 */ /***************************************************************************** ** @@ -2040,7 +2039,7 @@ bool select_export::send_data(List &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(row_count)); } else if (from_end_pos < res->ptr() + res->length()) { @@ -2049,7 +2048,7 @@ bool select_export::send_data(List &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(row_count)); } cvt_str.length(bytes); res= &cvt_str; diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 406998537e4..1b27efdd39a 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 @@ -342,7 +341,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); } @@ -373,7 +372,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 */ @@ -773,7 +772,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)))) @@ -873,8 +872,7 @@ static int check_connection(THD *thd) pkt_len < MIN_HANDSHAKE_SIZE) { 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; } } @@ -918,7 +916,7 @@ static int check_connection(THD *thd) if (!ssl_acceptor_fd) { 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; } DBUG_PRINT("info", ("IO layer change in progress...")); @@ -926,7 +924,7 @@ static int check_connection(THD *thd) { DBUG_PRINT("error", ("Failed to accept new SSL connection")); 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; } DBUG_PRINT("info", ("Reading user information over SSL layer")); @@ -936,7 +934,7 @@ static int check_connection(THD *thd) DBUG_PRINT("error", ("Failed to read user information (pkt_len= %lu)", pkt_len)); 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; } } @@ -945,7 +943,7 @@ static int check_connection(THD *thd) if (end > (char *)net->read_pos + pkt_len) { 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; } @@ -968,7 +966,7 @@ static int check_connection(THD *thd) if (user == NULL) { 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; } @@ -1000,7 +998,7 @@ static int check_connection(THD *thd) if (passwd == NULL) { 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; } @@ -1014,7 +1012,7 @@ static int check_connection(THD *thd) if (db == NULL) { 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 &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 d10f695f535..d743c5908ca 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(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 @@ -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(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(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(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(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(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(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(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(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(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(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(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(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..3c185e4c088 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -7150,7 +7150,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(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(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(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(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(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(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(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(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(file->max_record_length())); DBUG_RETURN(1); } /* Hack to avoid bugs with small static rows in MySQL */ From a7cd008e12875d21d37ae92ccbef50d87d4fbd35 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Wed, 18 May 2011 10:47:43 +0400 Subject: [PATCH 08/24] Bug#12403504 AFTER FIX FOR #11889186 : ASSERTION FAILED: DELSUM+(INT) Y/4-TEMP > 0 There are two problems: 1. There is a missing check for 'year' parameter(year can not be greater than 9999) in makedate function. fix: added check that year can not be greater than 9999. 2. There is a missing check for zero date in from_days() function. fix: added zero date check into Item_func_from_days::get_date() function. --- mysql-test/r/func_time.result | 9 +++++++++ mysql-test/t/func_time.test | 7 +++++++ sql/item_timefunc.cc | 9 +++++++-- 3 files changed, 23 insertions(+), 2 deletions(-) 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/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/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) From 33a9d9fa65a430d566cfdbebc549039751fdddcc Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Wed, 18 May 2011 14:01:43 +0400 Subject: [PATCH 09/24] BUG#12402794 - 60976: CRASH, VALGRIND WARNING AND MEMORY LEAK WITH PARTITIONED ARCHIVE TABLES CHECK TABLE against archive table, when file descriptors are exhausted, caused server crash. Archive didn't handle errors when opening data file for CHECK TABLE. --- mysql-test/r/archive_debug.result | 12 ++++++++++++ mysql-test/t/archive_debug.test | 13 +++++++++++++ storage/archive/azio.c | 9 +++++++++ storage/archive/ha_archive.cc | 3 ++- 4 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 mysql-test/r/archive_debug.result create mode 100644 mysql-test/t/archive_debug.test 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/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/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--; From 55d3381cc7bdde44d7f040921e5df1d7c229b846 Mon Sep 17 00:00:00 2001 From: Mayank Prasad Date: Wed, 18 May 2011 20:10:01 +0530 Subject: [PATCH 10/24] Bug#11764633 : 57491: THD->MAIN_DA.IS_OK() ASSERT IN EMBEDDED Issue: While running embedded server, if client issues TEE command (\T foo/bar) and "foo/bar" directory doesn't exist, it is suppose to give error. But it was aborting. This was happening because wrong error handler was being called. Solution: Modified calls to correct error handler. In embedded server case, there are two error handler (client and server) which are supposed to be called based on which context code is in. If it is in client context, client error handler should be called otherwise server. Test case: Test case automation is not possible as current (following) code doesn't allow '\T' to be executed from command line (OR command read from a file): [client/mysql.cc] ... static int com_tee(String *buffer __attribute__((unused)), char *line __attribute__((unused))) { char file_name[FN_REFLEN], *end, *param; if (status.batch) << THIS IS TRUE WHILE EXECUTING FROM COMMAND LINE. return 0; ... So, not adding test case in GA. WIll add a test case in mysql-trunk after removing above code so that this could be properly tested before GA. --- libmysqld/lib_sql.cc | 28 ++++++++++++++++++++++++++-- sql/mysql_priv.h | 8 ++++++++ sql/sql_class.cc | 19 +++++++++++++++++++ sql/sql_class.h | 1 + 4 files changed, 54 insertions(+), 2 deletions(-) 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/sql/mysql_priv.h b/sql/mysql_priv.h index 8f9a9080d12..3ce73291206 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -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) { @@ -2022,6 +2026,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/sql_class.cc b/sql/sql_class.cc index ae21a5335fd..04f981c6d6a 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1196,6 +1196,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. 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) { From 21163d68c31eb9e9183b5d1e1ed09a8114511029 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Thu, 19 May 2011 16:45:45 +0100 Subject: [PATCH 11/24] BUG#11746302: 25228: RPL_RELAYSPACE.TEST FAILS ON POWERMACG5, VM-WIN2003-32-A, SLES10-IA64-A The test case waits for master_pos_wait not to timeout, which means that the deadlock between SQL and IO threads was succesfully and automatically dealt with. However, very rarely, master_pos_wait reports a timeout. This happens because the time set for master_pos_wait to wait was too small (6 seconds). On slow test env this could be a problem. We fix this by setting the timeout inline with the one used in sync_slave_with_master (300 seconds). In addition we refactored the test case and refined some comments. --- mysql-test/suite/rpl/r/rpl_relayspace.result | 10 ++--- mysql-test/suite/rpl/t/rpl_relayspace.test | 42 +++++++++++++------- 2 files changed, 32 insertions(+), 20 deletions(-) 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/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 From 967cf758197281d68eac58dede6bb5cf959e3282 Mon Sep 17 00:00:00 2001 From: Dmitry Shulga Date: Fri, 20 May 2011 23:52:52 +0700 Subject: [PATCH 12/24] Fixed bug#11749345 (formerly bug#38813) - increasing memory consumption when selecting from I_S and views exist, in SP. Symptoms: re-execution of prepared statement (or statement in a stored routine) which read from one of I_S tables and which in order to fill this I_S table had to open a view led to increasing memory consumption. What happened in this situation was that during the process of view opening for purpose of I_S filling view-related structures (like its LEX) were allocated on persistent MEM_ROOT of prepared statement (or stored routine). Since this MEM_ROOT is not freed until prepared statement deallocation (or expulsion of stored routine from the cache) and code responsible for filling I_S is not able to re-use results of view opening from previous executions this allocation ended up in memory hogging. This patch solves the problem by ensuring that when a view opened for the purpose of I_S filling all its structures are allocated on non-persistent runtime MEM_ROOT. This is achieved by activating a temporary Query_arena bound to this MEM_ROOT. Since this step makes impossible linking of view structures into LEX of our prepared statement (or stored routine statement) this patch also changes code filling I_S table to install a proxy LEX before trying to open a view or a table. Consequently some code which was responsible for backing-up/restoring parts of LEX when view/table was opened during filling of I_S table became redundant and was removed. This patch doesn't contain test case for this bug as it is hard to test memory hogging in our test suite. --- sql/sql_show.cc | 314 +++++++++++++++++++++++++++--------------------- 1 file changed, 177 insertions(+), 137 deletions(-) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 5b835096042..310ec3b8e4f 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 *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[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 + @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. - @return Operation status - @retval 0 success - @retval 1 error + @retval FALSE - Success. + @retval TRUE - Failure. */ -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) +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) { - 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"); + 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; - 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. + 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). + + 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. */ - thd->temporary_tables= open_tables_state_backup->temporary_tables; + 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; + + /* + Some of process_table() functions rely on wildcard being passed from + old LEX (or at least being initialized). + */ + 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; - + lex->sql_command= old_lex->sql_command; - 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); + /* + 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 db_names; List_iterator_fast 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); } From 607c95c013b57ef359ed56754131e0b1ebca92d5 Mon Sep 17 00:00:00 2001 From: Anitha Gopi Date: Tue, 24 May 2011 09:56:24 +0530 Subject: [PATCH 13/24] Bug#12584161 - Moved test from disabled to experimental group --- mysql-test/collections/default.experimental | 2 ++ mysql-test/t/disabled.def | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index da2df7a72e8..d8acbfd03c3 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -19,6 +19,8 @@ innodb_plugin.* @solaris # Bug#56063 InnoDB Plugin mysql-tests f 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 +query_cache_28249 # Bug#12584161 2009-03-25 main.query_cache_28249 fails sporadically + ndb.* # joro : NDB tests marked as experimental as agreed with bochklin diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index c244d08e308..2fe8f5c32ae 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -10,6 +10,5 @@ # ############################################################################## 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 From 4f816f784285880cc1cb9066e044d752df00d06a Mon Sep 17 00:00:00 2001 From: Anitha Gopi Date: Tue, 24 May 2011 10:22:00 +0530 Subject: [PATCH 14/24] Bug#11756699: Move test from disabled to experimental group --- mysql-test/collections/default.experimental | 3 ++- mysql-test/t/disabled.def | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index d8acbfd03c3..680f05e9f24 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -19,7 +19,8 @@ innodb_plugin.* @solaris # Bug#56063 InnoDB Plugin mysql-tests f 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 -query_cache_28249 # Bug#12584161 2009-03-25 main.query_cache_28249 fails sporadically +main.query_cache_28249 # Bug#12584161 2009-03-25 main.query_cache_28249 fails sporadically +main.log_tables-big # Bug#11756699 2010-11-15 mattiasj report already exists ndb.* # joro : NDB tests marked as experimental as agreed with bochklin diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index 2fe8f5c32ae..4d26b80c0f8 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -10,5 +10,4 @@ # ############################################################################## kill : Bug#37780 2008-12-03 HHunger need some changes to be robust enough for pushbuild. -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 From 5c0e02259042b79232cdfbc20c0dff0e64254d89 Mon Sep 17 00:00:00 2001 From: Anitha Gopi Date: Tue, 24 May 2011 12:08:13 +0530 Subject: [PATCH 15/24] Changed to Oracle bug numbers --- mysql-test/collections/default.experimental | 20 ++++++++++---------- mysql-test/suite/binlog/t/disabled.def | 4 ++-- mysql-test/suite/federated/disabled.def | 2 +- mysql-test/suite/funcs_1/t/disabled.def | 2 +- mysql-test/suite/funcs_2/t/disabled.def | 8 ++++---- mysql-test/suite/ndb/t/disabled.def | 2 +- mysql-test/suite/ndb_team/t/disabled.def | 4 ++-- mysql-test/suite/parts/t/disabled.def | 4 ++-- mysql-test/suite/rpl/t/disabled.def | 4 ++-- mysql-test/suite/rpl_ndb/t/disabled.def | 2 +- mysql-test/suite/sys_vars/t/disabled.def | 4 ++-- mysql-test/t/disabled.def | 4 ++-- 12 files changed, 30 insertions(+), 30 deletions(-) diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index 680f05e9f24..9996da1dfb4 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -14,23 +14,23 @@ 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#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.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.log_tables-big # Bug#11756699 2010-11-15 mattiasj report already exists 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 @@ -48,6 +48,6 @@ 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 +main.gis-rtree # svoj: due to BUG#11749418 +main.type_float # svoj: due to BUG#11749418 +main.type_newdecimal # svoj: due to BUG#11749418 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/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/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_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/disabled.def b/mysql-test/t/disabled.def index 4d26b80c0f8..f33fd0352a0 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -9,5 +9,5 @@ # Do not use any TAB characters for whitespace. # ############################################################################## -kill : Bug#37780 2008-12-03 HHunger need some changes to be robust enough for pushbuild. -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 From 90df87e46c22b95561cc951ed0c3eeefc2edbb05 Mon Sep 17 00:00:00 2001 From: Anitha Gopi Date: Tue, 24 May 2011 15:46:14 +0530 Subject: [PATCH 16/24] BUG#12371924 # Bug is fixed. Move test out of experimental group --- mysql-test/collections/default.experimental | 1 - 1 file changed, 1 deletion(-) diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index 9996da1dfb4..cae23aa94d3 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 From aa0c8235a4fed513982cf3f576184404cf357826 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Thu, 26 May 2011 14:06:39 +0400 Subject: [PATCH 17/24] Bug#12392636 ASSERTION FAILED: SCALE >= 0 && PRECISION > 0 && SCALE <= PRECISION Assertion happens due to missing NULL value check in Item_func_round::fix_length_and_dec() function. The fix: added NULL value check for second parameter. --- mysql-test/r/func_math.result | 6 ++++++ mysql-test/t/func_math.test | 6 ++++++ sql/item_func.cc | 3 +++ 3 files changed, 15 insertions(+) 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/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/sql/item_func.cc b/sql/item_func.cc index b1398b78b84..feb87fe5fd7 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1972,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; From b76c277a8f46f7e1047099df4686cb06c26a08fa Mon Sep 17 00:00:00 2001 From: Sven Sandberg Date: Thu, 26 May 2011 12:50:43 +0200 Subject: [PATCH 18/24] BUG#12574820: binlog.binlog_tmp_table timing out in daily and weekly trunk run Problem: MYSQL_BIN_LOG::reset_logs acquires mutexes in wrong order. The correct order is first LOCK_thread_count and then LOCK_log. This function does it the other way around. This leads to deadlock when run in parallel with a thread that takes the two locks in correct order. For example, a thread that disconnects will take the locks in the correct order. Fix: change order of the locks in MYSQL_BIN_LOG::reset_logs: first LOCK_thread_count and then LOCK_log. --- .../suite/binlog/r/binlog_reset_master.result | 1 + .../suite/binlog/t/binlog_reset_master.test | 26 +++++++++++++++++++ sql/log.cc | 15 ++++++----- sql/mysqld.cc | 6 +++++ 4 files changed, 41 insertions(+), 7 deletions(-) create mode 100644 mysql-test/suite/binlog/r/binlog_reset_master.result create mode 100644 mysql-test/suite/binlog/t/binlog_reset_master.test 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_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/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/mysqld.cc b/sql/mysqld.cc index 54850f36d10..2d1290bf88a 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1903,6 +1903,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; From d076be2a3234a7b0d7ad1e77cc82ca84cfa9dd11 Mon Sep 17 00:00:00 2001 From: Dmitry Lenev Date: Thu, 26 May 2011 17:14:47 +0400 Subject: [PATCH 19/24] Fix for bug #11762012 - "54553: INNODB ASSERTS IN HA_INNOBASE::UPDATE_ROW, TEMPORARY TABLE, TABLE LOCK". Attempt to update an InnoDB temporary table under LOCK TABLES led to assertion failure in both debug and production builds if this temporary table was explicitly locked for READ. The same scenario works fine for MyISAM temporary tables. The assertion failure was caused by discrepancy between lock that was requested on the rows of temporary table at LOCK TABLES time and by update operation. Since SQL-layer requested a read-lock at LOCK TABLES time InnoDB engine assumed that upcoming statements which are going to be executed under LOCK TABLES will only read table and therefore should acquire only S-lock. An update operation broken this assumption by requesting X-lock. Possible approaches to fixing this problem are: 1) Skip locking of temporary tables as locking doesn't make any sense for connection-local objects. 2) Prohibit changing of temporary table locked by LOCK TABLES ... READ. Unfortunately both of these approaches have drawbacks which make them unviable for stable versions of server. So this patch takes another approach and changes code in such way that LOCK TABLES for a temporary table will always request write lock. In 5.1 version of this patch switch from read lock to write lock is done inside of InnoDBs handler methods as doing it on SQL-layer causes compatibility troubles with FLUSH TABLES WITH READ LOCK. --- mysql-test/suite/innodb/r/innodb_mysql.result | 18 ++++++++++++- mysql-test/suite/innodb/t/innodb_mysql.test | 25 ++++++++++++++++--- .../suite/innodb_plugin/r/innodb_mysql.result | 16 ++++++++++++ .../suite/innodb_plugin/t/innodb_mysql.test | 20 +++++++++++++++ storage/innobase/handler/ha_innodb.cc | 12 +++++++-- storage/innodb_plugin/handler/ha_innodb.cc | 12 +++++++-- 6 files changed, 95 insertions(+), 8 deletions(-) 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/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/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; } From 8bb8385f02d36c6ca31ec2036876d891d56134b5 Mon Sep 17 00:00:00 2001 From: Dmitry Shulga Date: Fri, 27 May 2011 16:23:08 +0700 Subject: [PATCH 20/24] Fixed bug#12546938 (formerly known as 61005) - CREATE IF NOT EXIST EVENT will create multiple running events. A CREATE IF NOT EXIST on an event that existed and was enabled caused multiple instances of the event to run. Disabling the event didn't help. If the event was dropped, the event stopped running, but when created again, multiple instances of the event were still running. The only way to get out of this situation was to restart the server. The problem was that Event_db_repository::create_event() didn't return enough information to discriminate between situation when event didn't exist and was created and when event did exist and was not created (but a warning was emitted). As result in the latter case event was added to in-memory queue of events second time. And this led to unwarranted multiple executions of the same event. The solution is to add out-parameter to Event_db_repository::create_event() method which will signal that event was not created because it already exists and so it should not be added to the in-memory queue. --- mysql-test/r/events_bugs.result | 40 +++++++++++++++++++++++ mysql-test/t/events_bugs.test | 50 +++++++++++++++++++++++++++++ sql/event_db_repository.cc | 20 +++++++----- sql/event_db_repository.h | 3 +- sql/events.cc | 56 ++++++++++++++++++--------------- 5 files changed, 136 insertions(+), 33 deletions(-) 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/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/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 7edd863ac41..08360ee5f04 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -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 (!event_already_exists) { - 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); + 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); From 79de9c71887aafe46efd005be65e8cc596eff5cb Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Fri, 27 May 2011 08:09:25 -0300 Subject: [PATCH 21/24] BUG 11763056 - 55721: AIX 5.1.50 build failing, cannot locate bzero The problem is that although AIX implements bzero, its prototype is not declared by default. Since AC_CHECK_FUNC(bzero) succeeds even though a prototype is not declared, this breaks compilation in C++ files where a prototype is required. The solution is to only use bzero if a prototype is also declared. --- configure.in | 7 +------ include/m_string.h | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/configure.in b/configure.in index 8ba208b1ef5..3603512f3f1 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 -#endif -]) +AC_CHECK_DECLS([fdatasync, bzero]) AC_CHECK_FUNCS(alarm bfill bmove bsearch bzero \ chsize cuserid fchmod fcntl \ 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 From c20552e1c7cb99568f09aeb820c9bdb35e105278 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Mon, 30 May 2011 07:42:30 -0300 Subject: [PATCH 22/24] Bug#12563279: REGRESSION IN HANDLING PRE-4.1 AUTHENTICATION PACKET The problem is that clients implementing the 4.0 version of the protocol (that is, mysql-4.0) do not null terminate a string at the end of the authentication packet. These clients denote the end of the string with the end of the packet. Although this goes against the documented (see MySQL Internals ClientServer Protocol wiki) description of the protocol, these old clients still need to be supported. The solution is to support the documented and actual behavior of the clients. If a client is using the pre-4.1 version of the protocol, the end of a string in the authentication packet can either be denoted with a null character or by the end of the packet. This restores backwards compatibility with old clients implementing either the documented or actual behavior. --- sql/password.c | 32 ++++++------ sql/sql_connect.cc | 123 ++++++++++++++++++++++++++++++++++++--------- 2 files changed, 116 insertions(+), 39 deletions(-) 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/sql_connect.cc b/sql/sql_connect.cc index 1b27efdd39a..26600584256 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -653,14 +653,21 @@ bool init_new_connection_handler_thread() } #ifndef EMBEDDED_LIBRARY -/** - Get a null character terminated string from a user-supplied buffer. - @param buffer[in, out] Pointer to the buffer to be scanned. +/** 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 string formatted according to the 4.1 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 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 @@ -671,9 +678,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); @@ -683,7 +690,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; } @@ -695,7 +755,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. @@ -854,7 +914,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; @@ -952,7 +1012,20 @@ static int check_connection(THD *thd) if ((thd->client_capabilities & CLIENT_TRANSACTIONS) && opt_using_transactions) net->return_status= &thd->server_status; - + + /* + 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; + /* In order to safely scan a head for '\0' string terminators we must keep track of how many bytes remain in the allocated @@ -961,8 +1034,7 @@ static int check_connection(THD *thd) size_t bytes_remaining_in_packet= pkt_len - (end - (char *)net->read_pos); size_t user_len; - char *user= get_null_terminated_string(&end, &bytes_remaining_in_packet, - &user_len); + char *user= get_string(&end, &bytes_remaining_in_packet, &user_len); if (user == NULL) { inc_host_errors(&thd->remote.sin_addr); @@ -991,8 +1063,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) @@ -1007,8 +1078,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) { inc_host_errors(&thd->remote.sin_addr); @@ -1021,19 +1091,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 */ From 52c52b5fdf410fe918cb79b6bb1fdf8e6a749b03 Mon Sep 17 00:00:00 2001 From: Anitha Gopi Date: Fri, 3 Jun 2011 14:13:10 +0530 Subject: [PATCH 23/24] Bug#11756699 : Move test to disabled group --- mysql-test/collections/default.experimental | 1 - mysql-test/t/disabled.def | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index cae23aa94d3..941606a37a5 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -19,7 +19,6 @@ main.ctype_gbk_binlog @solaris # Bug#11754407: main.ctype_gbk_binlog f 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.log_tables-big # Bug#11756699 2010-11-15 mattiasj report already exists ndb.* # joro : NDB tests marked as experimental as agreed with bochklin diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index f33fd0352a0..84c981c08c1 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -11,3 +11,5 @@ ############################################################################## 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 + From 29d840ee47c0e6406cbde7b1d878643d0b25e1ce Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Mon, 6 Jun 2011 13:13:54 +0300 Subject: [PATCH 24/24] Bug #11749418: 38965: TEST CASES GIS-RTREE, TYPE_FLOAT, TYPE_NEWDECIMAL FAIL IN EMBEDDED SERVER FreeBSD 64 bit needs the FP_X_DNML to fpsetmask() to prevent exceptions from propagating into mysql (as a threaded application). However fpsetmask() itself is deprecated in favor of fedisableexcept(). 1. Fixed the #ifdef to check for FP_X_DNML instead of i386. 2. Added a configure.in check for fedisableexcept() and, if present, this function is called insted of the fpsetmask(). No need for new tests, as the existing tests cover this already. Removed the affected tests from the experimental list. --- configure.in | 3 ++- mysql-test/collections/default.experimental | 3 --- sql/mysqld.cc | 19 ++++++++++++------- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/configure.in b/configure.in index 3603512f3f1..901515fecb6 100644 --- a/configure.in +++ b/configure.in @@ -2061,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/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index 941606a37a5..8883acfa606 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -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#11749418 -main.type_float # svoj: due to BUG#11749418 -main.type_newdecimal # svoj: due to BUG#11749418 diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 2d1290bf88a..36f195e6232 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 #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 @@ -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" */