From e4eadcfbddddce94da909f5248f6c68242ec6e3b Mon Sep 17 00:00:00 2001 From: "gshchepa/uchum@gleb.loc" <> Date: Thu, 13 Sep 2007 18:41:50 +0500 Subject: [PATCH 1/4] Fixed bug #27695. Declaring an all space column name in the SELECT FROM DUAL or in a view leads to misleading warning message: "Leading spaces are removed from name ' '". The Item::set_name method has been modified to raise warnings like "Name ' ' has become ''" in case of the truncation of an all space identifier to an empty string identifier instead of the "Leading spaces are removed from name ' '" warning message. --- mysql-test/r/select.result | 34 ++++++++++++++++++++++++++++++++++ mysql-test/t/select.test | 20 ++++++++++++++++++++ sql/item.cc | 14 ++++++++++---- sql/share/errmsg.txt | 2 ++ 4 files changed, 66 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 2cf1316bb47..ed120a1bbb8 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -4062,4 +4062,38 @@ SHOW WARNINGS; Level Code Message Note 1003 select '0' AS `c1` from `test`.`t1` `join_0` join `test`.`t1` `join_1` join `test`.`t1` `join_2` join `test`.`t1` `join_3` join `test`.`t1` `join_4` join `test`.`t1` `join_5` join `test`.`t1` `join_6` join `test`.`t1` `join_7` where 0 group by '0','0','0','0','0' DROP TABLE t1; +SELECT 1 AS ` `; + +1 +Warnings: +Warning 1474 Name ' ' has become '' +SELECT 1 AS ` `; + +1 +Warnings: +Warning 1474 Name ' ' has become '' +SELECT 1 AS ` x`; +x +1 +Warnings: +Warning 1466 Leading spaces are removed from name ' x' +CREATE VIEW v1 AS SELECT 1 AS ` `; +Warnings: +Warning 1474 Name ' ' has become '' +SELECT `` FROM v1; + +1 +CREATE VIEW v2 AS SELECT 1 AS ` `; +Warnings: +Warning 1474 Name ' ' has become '' +SELECT `` FROM v2; + +1 +CREATE VIEW v3 AS SELECT 1 AS ` x`; +Warnings: +Warning 1466 Leading spaces are removed from name ' x' +SELECT `x` FROM v3; +x +1 +DROP VIEW v1, v2, v3; End of 5.0 tests diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index abf55745080..851e8164c44 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -3460,4 +3460,24 @@ SHOW WARNINGS; DROP TABLE t1; +# +# Bug #27695: Misleading warning when declaring all space column names and +# truncation of one-space column names to zero length names. +# + +SELECT 1 AS ` `; +SELECT 1 AS ` `; +SELECT 1 AS ` x`; + +CREATE VIEW v1 AS SELECT 1 AS ` `; +SELECT `` FROM v1; + +CREATE VIEW v2 AS SELECT 1 AS ` `; +SELECT `` FROM v2; + +CREATE VIEW v3 AS SELECT 1 AS ` x`; +SELECT `x` FROM v3; + +DROP VIEW v1, v2, v3; + --echo End of 5.0 tests diff --git a/sql/item.cc b/sql/item.cc index 66379d5dcf9..e9b2904e3da 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -700,10 +700,16 @@ void Item::set_name(const char *str, uint length, CHARSET_INFO *cs) str++; } if (orig_len != length && !is_autogenerated_name) - push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_REMOVED_SPACES, ER(ER_REMOVED_SPACES), - str + length - orig_len); - + { + if (length == 0) + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_NAME_BECOMES_EMPTY, ER(ER_NAME_BECOMES_EMPTY), + str + length - orig_len); + else + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_REMOVED_SPACES, ER(ER_REMOVED_SPACES), + str + length - orig_len); + } } if (!my_charset_same(cs, system_charset_info)) { diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 6d4ca33ccc7..709cd1fc0a9 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5637,3 +5637,5 @@ ER_ADMIN_WRONG_MRG_TABLE eng "Table '%-.64s' is differently defined or of non-MyISAM type or doesn't exist" ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT eng "Too high level of nesting for select" +ER_NAME_BECOMES_EMPTY + eng "Name '%-.64s' has become ''" From 8a3e6201b3b4e806b28e95069965d76815469780 Mon Sep 17 00:00:00 2001 From: "sergefp@mysql.com" <> Date: Fri, 14 Sep 2007 14:53:13 +0400 Subject: [PATCH 2/4] BUG#30324: Grouping queries with COUNT(DISTINCT bit column) return wrong results - The bug was caused by COUNT(DISTINCT ...) code using Unique object in a way that assumed that BIT(N) column occupies a contiguous space in temp_table->record[0] buffer. - The fix is to make COUNT(DISTINCT ...) code instruct create_tmp_table to create temporary table with column of type BIGINT, not BIT(N). --- mysql-test/r/type_bit.result | 15 +++++++++++++++ mysql-test/t/type_bit.test | 14 ++++++++++++++ sql/item_sum.cc | 17 +++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/mysql-test/r/type_bit.result b/mysql-test/r/type_bit.result index 5356f7e0712..4c1b80c2fd5 100644 --- a/mysql-test/r/type_bit.result +++ b/mysql-test/r/type_bit.result @@ -657,4 +657,19 @@ b # # DROP TABLE t1; +CREATE TABLE t1 (a int, b bit(2)); +INSERT INTO t1 VALUES (3, 2), (2, 3), (2, 0), (3, 2), (3, 1); +SELECT COUNT(DISTINCT b) FROM t1 GROUP BY a; +COUNT(DISTINCT b) +2 +2 +DROP TABLE t1; +create table t2 (a int, b bit(2), c char(10)); +INSERT INTO t2 VALUES (3, 2, 'two'), (2, 3, 'three'), (2, 0, 'zero'), +(3, 2, 'two'), (3, 1, 'one'); +SELECT COUNT(DISTINCT b,c) FROM t2 GROUP BY a; +COUNT(DISTINCT b,c) +2 +2 +DROP TABLE t2; End of 5.0 tests diff --git a/mysql-test/t/type_bit.test b/mysql-test/t/type_bit.test index 66538f59c6f..4978f55d776 100644 --- a/mysql-test/t/type_bit.test +++ b/mysql-test/t/type_bit.test @@ -304,4 +304,18 @@ SELECT b FROM t1 GROUP BY b; --disable_metadata DROP TABLE t1; +# +# BUG#30324 Wrong query result for COUNT(DISTINCT(bit_column)) +# +CREATE TABLE t1 (a int, b bit(2)); +INSERT INTO t1 VALUES (3, 2), (2, 3), (2, 0), (3, 2), (3, 1); +SELECT COUNT(DISTINCT b) FROM t1 GROUP BY a; +DROP TABLE t1; + +create table t2 (a int, b bit(2), c char(10)); +INSERT INTO t2 VALUES (3, 2, 'two'), (2, 3, 'three'), (2, 0, 'zero'), + (3, 2, 'two'), (3, 1, 'one'); +SELECT COUNT(DISTINCT b,c) FROM t2 GROUP BY a; +DROP TABLE t2; + --echo End of 5.0 tests diff --git a/sql/item_sum.cc b/sql/item_sum.cc index fe9f58d84e1..c20d3fba705 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -2464,6 +2464,23 @@ bool Item_sum_count_distinct::setup(THD *thd) count_field_types(select_lex, tmp_table_param, list, 0); tmp_table_param->force_copy_fields= force_copy_fields; DBUG_ASSERT(table == 0); + /* + Make create_tmp_table() convert BIT columns to BIGINT. + This is needed because BIT fields store parts of their data in table's + null bits, and we don't have methods to compare two table records, which + is needed by Unique which is used when HEAP table is used. + */ + { + List_iterator_fast li(list); + Item *item; + while ((item= li++)) + { + if (item->type() == Item::FIELD_ITEM && + ((Item_field*)item)->field->type() == FIELD_TYPE_BIT) + item->marker=4; + } + } + if (!(table= create_tmp_table(thd, tmp_table_param, list, (ORDER*) 0, 1, 0, (select_lex->options | thd->options), From a2afc56f61c7c347be0e721093b496b6aa230c40 Mon Sep 17 00:00:00 2001 From: "gkodinov/kgeorge@magare.gmz" <> Date: Fri, 14 Sep 2007 17:43:14 +0300 Subject: [PATCH 3/4] Bug #31001: ORDER BY DESC in InnoDB not working The optimizer sets index traversal in reverse order only if there are used key parts that are not compared to a constant. However using the primary key as an ORDER BY suffix rendered the check incomplete : going in reverse order must still be used even if all the parts of the secondary key are compared to a constant. Fixed by relaxing the check and set reverse traversal even when all the secondary index keyparts are compared to a const. Also account for the case when all the primary keys are compared to a constant. --- mysql-test/r/innodb_mysql.result | 97 ++++++++++++++++++++++++++++++++ mysql-test/t/innodb_mysql.test | 23 ++++++++ sql/sql_select.cc | 8 ++- 3 files changed, 127 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index be678efd0ef..d5f014b6840 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -1114,4 +1114,101 @@ c b 3 1 3 2 DROP TABLE t1; +CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a), INDEX b (b)) ENGINE=InnoDB; +INSERT INTO t1(a,b) VALUES (1,1), (2,2), (3,2); +EXPLAIN SELECT * FROM t1 WHERE b=2 ORDER BY a ASC; +id 1 +select_type SIMPLE +table t1 +type ref +possible_keys b +key b +key_len 5 +ref const +rows 1 +Extra Using where; Using index +SELECT * FROM t1 WHERE b=2 ORDER BY a ASC; +a b +2 2 +3 2 +EXPLAIN SELECT * FROM t1 WHERE b=2 ORDER BY a DESC; +id 1 +select_type SIMPLE +table t1 +type ref +possible_keys b +key b +key_len 5 +ref const +rows 1 +Extra Using where; Using index +SELECT * FROM t1 WHERE b=2 ORDER BY a DESC; +a b +3 2 +2 2 +EXPLAIN SELECT * FROM t1 ORDER BY b ASC, a ASC; +id 1 +select_type SIMPLE +table t1 +type index +possible_keys NULL +key b +key_len 5 +ref NULL +rows 3 +Extra Using index +SELECT * FROM t1 ORDER BY b ASC, a ASC; +a b +1 1 +2 2 +3 2 +EXPLAIN SELECT * FROM t1 ORDER BY b DESC, a DESC; +id 1 +select_type SIMPLE +table t1 +type index +possible_keys NULL +key b +key_len 5 +ref NULL +rows 3 +Extra Using index +SELECT * FROM t1 ORDER BY b DESC, a DESC; +a b +3 2 +2 2 +1 1 +EXPLAIN SELECT * FROM t1 ORDER BY b ASC, a DESC; +id 1 +select_type SIMPLE +table t1 +type index +possible_keys NULL +key b +key_len 5 +ref NULL +rows 3 +Extra Using index; Using filesort +SELECT * FROM t1 ORDER BY b ASC, a DESC; +a b +1 1 +3 2 +2 2 +EXPLAIN SELECT * FROM t1 ORDER BY b DESC, a ASC; +id 1 +select_type SIMPLE +table t1 +type index +possible_keys NULL +key b +key_len 5 +ref NULL +rows 3 +Extra Using index; Using filesort +SELECT * FROM t1 ORDER BY b DESC, a ASC; +a b +2 2 +3 2 +1 1 +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test index c39c88096c4..f64efd600c5 100644 --- a/mysql-test/t/innodb_mysql.test +++ b/mysql-test/t/innodb_mysql.test @@ -937,4 +937,27 @@ SELECT c,b FROM t1 GROUP BY c,b; DROP TABLE t1; +# +# Bug #31001: ORDER BY DESC in InnoDB not working +# +CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a), INDEX b (b)) ENGINE=InnoDB; +INSERT INTO t1(a,b) VALUES (1,1), (2,2), (3,2); + +#The two queries below should produce different results, but they don't. +query_vertical EXPLAIN SELECT * FROM t1 WHERE b=2 ORDER BY a ASC; +SELECT * FROM t1 WHERE b=2 ORDER BY a ASC; +query_vertical EXPLAIN SELECT * FROM t1 WHERE b=2 ORDER BY a DESC; +SELECT * FROM t1 WHERE b=2 ORDER BY a DESC; + +query_vertical EXPLAIN SELECT * FROM t1 ORDER BY b ASC, a ASC; +SELECT * FROM t1 ORDER BY b ASC, a ASC; +query_vertical EXPLAIN SELECT * FROM t1 ORDER BY b DESC, a DESC; +SELECT * FROM t1 ORDER BY b DESC, a DESC; +query_vertical EXPLAIN SELECT * FROM t1 ORDER BY b ASC, a DESC; +SELECT * FROM t1 ORDER BY b ASC, a DESC; +query_vertical EXPLAIN SELECT * FROM t1 ORDER BY b DESC, a ASC; +SELECT * FROM t1 ORDER BY b DESC, a ASC; + +DROP TABLE t1; + --echo End of 5.0 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index bd93a7ae203..453bf7c3b63 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -12063,6 +12063,12 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx, for (; const_key_parts & 1 ; const_key_parts>>= 1) key_part++; + /* + The primary and secondary key parts were all const (i.e. there's + one row). The sorting doesn't matter. + */ + if (key_part == key_part_end && reverse == 0) + DBUG_RETURN(1); } else DBUG_RETURN(0); @@ -12480,7 +12486,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, } DBUG_RETURN(1); } - if (tab->ref.key_parts < used_key_parts) + if (tab->ref.key_parts <= used_key_parts) { /* SELECT * FROM t1 WHERE a=1 ORDER BY a DESC,b DESC From 0aa6e957681c03637e261c3b6c3924baa86c9f54 Mon Sep 17 00:00:00 2001 From: "gshchepa@devsrv-b.mysql.com" <> Date: Sat, 15 Sep 2007 07:04:32 +0200 Subject: [PATCH 4/4] select.test: Post-fix for bug#27695. --- mysql-test/t/select.test | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index 851e8164c44..5c30a17e08e 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -3465,6 +3465,8 @@ DROP TABLE t1; # truncation of one-space column names to zero length names. # +--disable_ps_protocol + SELECT 1 AS ` `; SELECT 1 AS ` `; SELECT 1 AS ` x`; @@ -3480,4 +3482,6 @@ SELECT `x` FROM v3; DROP VIEW v1, v2, v3; +--enable_ps_protocol + --echo End of 5.0 tests