From c00ad6c0b30e407164a69c00674cbc8119f73e8a Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 29 May 2007 14:36:21 +0300 Subject: [PATCH 1/8] Bug #28366: multiple load_file('a: ... ') causes entire mysqld process to hang When a Windows console application that has an open console (e.g. mysqld-nt started with the --console option) encounters certain type of errors (like no floppy disk in a floppy drive) the OS will pop-up an "abort/retry/ignore" dialog and block the application (depending on a registry setting : see http://msdn2.microsoft.com/en-us/embedded/aa731206.aspx for details). Fixed by disabling the dialog popups for every error except a GPF and alignment errors. This is safe to do as the actual error gets reported (and handled) to mysqld. sql/mysqld.cc: Bug #28366: disable the system error messageboxes. --- sql/mysqld.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 051bad5b310..be0bc875509 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3574,6 +3574,11 @@ we force server id to 2, but this MySQL server will not act as a slave."); freopen(log_error_file,"a+",stderr); FreeConsole(); // Remove window } + else + { + /* Don't show error dialog box when on foreground: it stops the server */ + SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS); + } #endif /* From cfd1e67ae404887496682c74abb24a1adedab4e9 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 2 Jun 2007 01:21:18 +0400 Subject: [PATCH 2/8] Bug#28427: Columns were renamed instead of moving by ALTER TABLE. To avoid unnecessary work the mysql_alter_table function takes the list of table fields and applies all changes to it (drops/moves/renames/etc). Then this function compares the new list and the old one. If the changes require only .frm to be modified then the actual data isn't copied. To detect changes all columns attributes but names are compared. When a column has been moved and has replaced another column with the same attributes except name the mysql_alter_table function wrongly decides that two fields has been just renamed. As a result the data from the moved column and from all columns after it is not copied. Now the mysql_alter_table function forces table data copying by setting the need_copy_table flag when it finds a moved column. The flag is set at the stage when the modified fields are created. sql/sql_table.cc: Bug#28427: Columns were renamed instead of moving by ALTER TABLE. Now the mysql_alter_table function forces table data copying by setting the need_copy_table flag when it finds a moved column. The flag is set at the stage when the modified fields are created. mysql-test/r/alter_table.result: Added a test case for the bug#28427: Columns were renamed instead of moving by ALTER TABLE. mysql-test/t/alter_table.test: Added a test case for the bug#28427: Columns were renamed instead of moving by ALTER TABLE. --- mysql-test/r/alter_table.result | 14 ++++++++++++++ mysql-test/t/alter_table.test | 12 ++++++++++++ sql/sql_table.cc | 5 ++++- 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result index 3fa12f2997a..c9e3655660b 100644 --- a/mysql-test/r/alter_table.result +++ b/mysql-test/r/alter_table.result @@ -1103,3 +1103,17 @@ Field Type Null Key Default Extra unsigned_int_field bigint(20) unsigned NO MUL char_field char(10) YES NULL DROP TABLE t2; +CREATE TABLE t1 (f1 INT, f2 INT, f3 INT); +INSERT INTO t1 VALUES (1, 2, NULL); +SELECT * FROM t1; +f1 f2 f3 +1 2 NULL +ALTER TABLE t1 MODIFY COLUMN f3 INT AFTER f1; +SELECT * FROM t1; +f1 f3 f2 +1 NULL 2 +ALTER TABLE t1 MODIFY COLUMN f3 INT AFTER f2; +SELECT * FROM t1; +f1 f2 f3 +1 2 NULL +DROP TABLE t1; diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test index 70fd1dfa898..7c1c096534e 100644 --- a/mysql-test/t/alter_table.test +++ b/mysql-test/t/alter_table.test @@ -839,3 +839,15 @@ ALTER TABLE t2 MODIFY unsigned_int_field BIGINT UNSIGNED NOT NULL; DESCRIBE t2; DROP TABLE t2; + +# +# Bug#28427: Columns were renamed instead of moving by ALTER TABLE. +# +CREATE TABLE t1 (f1 INT, f2 INT, f3 INT); +INSERT INTO t1 VALUES (1, 2, NULL); +SELECT * FROM t1; +ALTER TABLE t1 MODIFY COLUMN f3 INT AFTER f1; +SELECT * FROM t1; +ALTER TABLE t1 MODIFY COLUMN f3 INT AFTER f2; +SELECT * FROM t1; +DROP TABLE t1; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 11d7d15c685..a77ed172478 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -5932,6 +5932,7 @@ view_err: goto err; } find_it.after(def); // Put element after this + need_copy_table= ALTER_TABLE_DATA_CHANGED; } } if (alter_info->alter_list.elements) @@ -6170,12 +6171,14 @@ view_err: (uint*) thd->alloc(sizeof(uint) * prepared_key_list.elements))) goto err; /* Check how much the tables differ. */ - need_copy_table= compare_tables(table, &prepared_create_list, + bool res= compare_tables(table, &prepared_create_list, key_info_buffer, key_count, create_info, alter_info, order_num, index_drop_buffer, &index_drop_count, index_add_buffer, &index_add_count, varchar); + if (!need_copy_table) + need_copy_table= res; } /* From b85d7da25dcec055de80ef0b4d9b886c55f38432 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 2 Jun 2007 21:43:04 +0400 Subject: [PATCH 3/8] BUG#28427: fix typo, s/bool/uint/ --- sql/sql_table.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index a77ed172478..6d5860240be 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -6171,7 +6171,7 @@ view_err: (uint*) thd->alloc(sizeof(uint) * prepared_key_list.elements))) goto err; /* Check how much the tables differ. */ - bool res= compare_tables(table, &prepared_create_list, + uint res= compare_tables(table, &prepared_create_list, key_info_buffer, key_count, create_info, alter_info, order_num, index_drop_buffer, &index_drop_count, From 8ab1830f9a4cca12420e2cd9756983707bca9af2 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 2 Jun 2007 23:17:46 +0400 Subject: [PATCH 4/8] Bug#28494: Grouping by Item_func_set_user_var produces incorrect result. This is an additional fix. Item::val_xxx methods are supposed to use original data source and Item::val_xxx_result methods to use the item's result field. But for the Item_func_set_user_var class val_xxx_result methods were mapped to val_xxx methods. This leads, in particular, to producing bad sort keys and thus wrong order of the result set of queries with group by/order by clauses. The set of val_xxx_result methods is added to the Item_func_set_user_var class. It's the same as the val_xxx set of method but uses the result_field to return a value. mysql-test/t/user_var.test: Corrected test case for hte bug#28494. mysql-test/r/user_var.result: Corrected test case for hte bug#28494. sql/item_func.cc: Bug#28494: Grouping by Item_func_set_user_var produces incorrect result. The set of val_xxx_result methods is added to the Item_func_set_user_var class. It's the same as the val_xxx set of method but uses the result_field to return a value. sql/item_func.h: Bug#28494: Grouping by Item_func_set_user_var produces incorrect result. The set of val_xxx_result methods is added to the Item_func_set_user_var class. --- mysql-test/r/user_var.result | 14 +++++++++++--- mysql-test/t/user_var.test | 5 +++-- sql/item_func.cc | 34 ++++++++++++++++++++++++++++++++++ sql/item_func.h | 4 ++++ 4 files changed, 52 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result index b9f58b60d9b..b90bb1f062b 100644 --- a/mysql-test/r/user_var.result +++ b/mysql-test/r/user_var.result @@ -318,9 +318,17 @@ SHOW COUNT(*) ERRORS; @@session.error_count 1 create table t1(f1 int); -insert into t1 values(1),(1),(2); -select @a:=f1, count(f1) from t1 group by 1; +insert into t1 values(1),(1),(2),(3),(4),(1),(3),(1); +select @a:=f1, count(f1) from t1 group by 1 desc; @a:=f1 count(f1) -1 2 +4 1 +3 2 2 1 +1 4 +select @a:=f1, count(f1) from t1 group by 1 asc; +@a:=f1 count(f1) +1 4 +2 1 +3 2 +4 1 drop table t1; diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test index 7919b663a73..3df949ae669 100644 --- a/mysql-test/t/user_var.test +++ b/mysql-test/t/user_var.test @@ -227,6 +227,7 @@ SHOW COUNT(*) ERRORS; # Bug#28494: Grouping by Item_func_set_user_var produces incorrect result. # create table t1(f1 int); -insert into t1 values(1),(1),(2); -select @a:=f1, count(f1) from t1 group by 1; +insert into t1 values(1),(1),(2),(3),(4),(1),(3),(1); +select @a:=f1, count(f1) from t1 group by 1 desc; +select @a:=f1, count(f1) from t1 group by 1 asc; drop table t1; diff --git a/sql/item_func.cc b/sql/item_func.cc index 95ff432ca5a..aa1d54b0ebd 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -4208,6 +4208,40 @@ my_decimal *Item_func_set_user_var::val_decimal(my_decimal *val) } +double Item_func_set_user_var::val_real_result() +{ + DBUG_ASSERT(fixed == 1); + check(TRUE); + update(); // Store expression + return entry->val_real(&null_value); +} + +longlong Item_func_set_user_var::val_int_result() +{ + DBUG_ASSERT(fixed == 1); + check(TRUE); + update(); // Store expression + return entry->val_int(&null_value); +} + +String *Item_func_set_user_var::val_str_result(String *str) +{ + DBUG_ASSERT(fixed == 1); + check(TRUE); + update(); // Store expression + return entry->val_str(&null_value, str, decimals); +} + + +my_decimal *Item_func_set_user_var::val_decimal_result(my_decimal *val) +{ + DBUG_ASSERT(fixed == 1); + check(TRUE); + update(); // Store expression + return entry->val_decimal(&null_value, val); +} + + void Item_func_set_user_var::print(String *str) { str->append(STRING_WITH_LEN("(@")); diff --git a/sql/item_func.h b/sql/item_func.h index 18cd87d2de4..c8ea79b9747 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1208,6 +1208,10 @@ public: longlong val_int(); String *val_str(String *str); my_decimal *val_decimal(my_decimal *); + double val_real_result(); + longlong val_int_result(); + String *val_str_result(String *str); + my_decimal *val_decimal_result(my_decimal *); bool update_hash(void *ptr, uint length, enum Item_result type, CHARSET_INFO *cs, Derivation dv, bool unsigned_arg); bool send(Protocol *protocol, String *str_arg); From 684653b89eee128a1085caa3c58304d60683ccc0 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 3 Jun 2007 01:24:56 +0400 Subject: [PATCH 5/8] item_func.cc: Post fix for bug#28494. The Item_func_set_user_var::check method now silently doesn't use result_field if it isn't defined. sql/item_func.cc: Post fix for bug#28494. The Item_func_set_user_var::check method now silently doesn't use result_field if it isn't defined. --- sql/item_func.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/item_func.cc b/sql/item_func.cc index aa1d54b0ebd..ca8b0af865d 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -4063,8 +4063,8 @@ bool Item_func_set_user_var::check(bool use_result_field) { DBUG_ENTER("Item_func_set_user_var::check"); - if (use_result_field) - DBUG_ASSERT(result_field); + if (use_result_field && !result_field) + use_result_field= FALSE; switch (cached_result_type) { case REAL_RESULT: From 4ef028600a3a0f13ef29a8b356e9ce5883080a84 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 3 Jun 2007 14:46:09 +0400 Subject: [PATCH 6/8] user_var.result, user_var.test: Extended test case for the bug#28494. mysql-test/t/user_var.test: Extended test case for the bug#28494. mysql-test/r/user_var.result: Extended test case for the bug#28494. --- mysql-test/r/user_var.result | 25 +++++++++++++++++++++++-- mysql-test/t/user_var.test | 10 ++++++++-- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result index b90bb1f062b..15a9fe2ecda 100644 --- a/mysql-test/r/user_var.result +++ b/mysql-test/r/user_var.result @@ -317,8 +317,11 @@ SHOW COUNT(*) WARNINGS; SHOW COUNT(*) ERRORS; @@session.error_count 1 -create table t1(f1 int); -insert into t1 values(1),(1),(2),(3),(4),(1),(3),(1); +create table t1(f1 int, f2 varchar(2), f3 float, f4 decimal(2,1)); +insert into t1 values +(1, "a", 1.5, 1.6), (1, "a", 1.5, 1.6), (2, "b", 2.5, 2.6), +(3, "c", 3.5, 3.6), (4, "d", 4.5, 4.6), (1, "a", 1.5, 1.6), +(3, "c", 3.5, 3.6), (1, "a", 1.5, 1.6); select @a:=f1, count(f1) from t1 group by 1 desc; @a:=f1 count(f1) 4 1 @@ -331,4 +334,22 @@ select @a:=f1, count(f1) from t1 group by 1 asc; 2 1 3 2 4 1 +select @a:=f2, count(f2) from t1 group by 1 desc; +@a:=f2 count(f2) +a 4 +b 1 +c 2 +d 1 +select @a:=f3, count(f3) from t1 group by 1 desc; +@a:=f3 count(f3) +1.5 4 +2.5 1 +3.5 2 +4.5 1 +select @a:=f4, count(f4) from t1 group by 1 desc; +@a:=f4 count(f4) +4.6 1 +3.6 2 +2.6 1 +1.6 4 drop table t1; diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test index 3df949ae669..3a3e8f88f83 100644 --- a/mysql-test/t/user_var.test +++ b/mysql-test/t/user_var.test @@ -226,8 +226,14 @@ SHOW COUNT(*) ERRORS; # # Bug#28494: Grouping by Item_func_set_user_var produces incorrect result. # -create table t1(f1 int); -insert into t1 values(1),(1),(2),(3),(4),(1),(3),(1); +create table t1(f1 int, f2 varchar(2), f3 float, f4 decimal(2,1)); +insert into t1 values + (1, "a", 1.5, 1.6), (1, "a", 1.5, 1.6), (2, "b", 2.5, 2.6), + (3, "c", 3.5, 3.6), (4, "d", 4.5, 4.6), (1, "a", 1.5, 1.6), + (3, "c", 3.5, 3.6), (1, "a", 1.5, 1.6); select @a:=f1, count(f1) from t1 group by 1 desc; select @a:=f1, count(f1) from t1 group by 1 asc; +select @a:=f2, count(f2) from t1 group by 1 desc; +select @a:=f3, count(f3) from t1 group by 1 desc; +select @a:=f4, count(f4) from t1 group by 1 desc; drop table t1; From e19dcfa91f63a7ff310a11a00ac670a04dfdd1fb Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 3 Jun 2007 15:56:48 +0400 Subject: [PATCH 7/8] user_var.result: Corrected test case result for the bug#28494. item_func.h, item_func.cc: Corrected function names after fix for the bug#28494. mysql-test/r/user_var.result: Corrected test case result for the bug#28494. sql/item_func.h: Corrected function names after fix for the bug#28494. sql/item_func.cc: Corrected function names after fix for the bug#28494. --- mysql-test/r/user_var.result | 12 ++++++------ sql/item_func.cc | 4 ++-- sql/item_func.h | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result index 15a9fe2ecda..80b5dccc198 100644 --- a/mysql-test/r/user_var.result +++ b/mysql-test/r/user_var.result @@ -336,16 +336,16 @@ select @a:=f1, count(f1) from t1 group by 1 asc; 4 1 select @a:=f2, count(f2) from t1 group by 1 desc; @a:=f2 count(f2) -a 4 -b 1 -c 2 d 1 +c 2 +b 1 +a 4 select @a:=f3, count(f3) from t1 group by 1 desc; @a:=f3 count(f3) -1.5 4 -2.5 1 -3.5 2 4.5 1 +3.5 2 +2.5 1 +1.5 4 select @a:=f4, count(f4) from t1 group by 1 desc; @a:=f4 count(f4) 4.6 1 diff --git a/sql/item_func.cc b/sql/item_func.cc index ca8b0af865d..580d19fbd4e 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -4208,7 +4208,7 @@ my_decimal *Item_func_set_user_var::val_decimal(my_decimal *val) } -double Item_func_set_user_var::val_real_result() +double Item_func_set_user_var::val_result() { DBUG_ASSERT(fixed == 1); check(TRUE); @@ -4224,7 +4224,7 @@ longlong Item_func_set_user_var::val_int_result() return entry->val_int(&null_value); } -String *Item_func_set_user_var::val_str_result(String *str) +String *Item_func_set_user_var::str_result(String *str) { DBUG_ASSERT(fixed == 1); check(TRUE); diff --git a/sql/item_func.h b/sql/item_func.h index c8ea79b9747..9a0201cb28b 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1208,9 +1208,9 @@ public: longlong val_int(); String *val_str(String *str); my_decimal *val_decimal(my_decimal *); - double val_real_result(); + double val_result(); longlong val_int_result(); - String *val_str_result(String *str); + String *str_result(String *str); my_decimal *val_decimal_result(my_decimal *); bool update_hash(void *ptr, uint length, enum Item_result type, CHARSET_INFO *cs, Derivation dv, bool unsigned_arg); From 92fb5da3728651ee4f2f72d73efa8a89a5d4f764 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 3 Jun 2007 21:52:00 +0400 Subject: [PATCH 8/8] item_func.h, item_func.cc: Post merge fix for the bug#28494. sql/item_func.h: Post merge fix for the bug#28494. sql/item_func.cc: Post merge fix for the bug#28494. --- sql/item_func.cc | 17 +++++++++++++++++ sql/item_func.h | 1 + 2 files changed, 18 insertions(+) diff --git a/sql/item_func.cc b/sql/item_func.cc index e6c59ae466b..7806a37d8d0 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -3799,6 +3799,23 @@ Item_func_set_user_var::fix_length_and_dec() } +/* + Mark field in read_map + + NOTES + This is used by filesort to register used fields in a a temporary + column read set or to register used fields in a view +*/ + +bool Item_func_set_user_var::register_field_in_read_map(uchar *arg) +{ + TABLE *table= (TABLE *) arg; + if (result_field->table == table || !table) + bitmap_set_bit(result_field->table->read_set, result_field->field_index); + return 0; +} + + /* Set value to user variable. diff --git a/sql/item_func.h b/sql/item_func.h index 7bb0ebfb1bf..d2ed0404dac 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1259,6 +1259,7 @@ public: return save_in_field(field, no_conversions, 1); } void save_org_in_field(Field *field) { (void)save_in_field(field, 1, 0); } + bool register_field_in_read_map(uchar *arg); };