From dc01e1d612d8526fe94939a37818993e4cd15f29 Mon Sep 17 00:00:00 2001 From: "sergefp@mysql.com" <> Date: Tue, 22 Apr 2008 02:53:12 +0400 Subject: [PATCH 01/11] BUG#36139 "float, zerofill, crash with subquery" - Make convert_zerofill_number_to_string() take into account that the constant it is converting may evaluate to NULL. --- mysql-test/r/subselect.result | 7 +++++++ mysql-test/t/subselect.test | 12 ++++++++++++ sql/item.cc | 11 ++++++++--- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 2de2589fc92..349b874cbb9 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -4374,4 +4374,11 @@ a4 f3 a6 1 NULL NULL 2 NULL NULL DROP TABLE t1, t2, t3, t4; +create table t1 (a float(5,4) zerofill); +create table t2 (a float(5,4),b float(2,0)); +select t1.a from t1 where +t1.a= (select b from t2 limit 1) and not +t1.a= (select a from t2 limit 1) ; +a +drop table t1; End of 5.0 tests. diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index c5edd5414e3..a60159381e1 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -3259,5 +3259,17 @@ GROUP BY a4; DROP TABLE t1, t2, t3, t4; +# +# BUG#36139 "float, zerofill, crash with subquery" +# +create table t1 (a float(5,4) zerofill); +create table t2 (a float(5,4),b float(2,0)); + +select t1.a from t1 where + t1.a= (select b from t2 limit 1) and not + t1.a= (select a from t2 limit 1) ; + +drop table t1; + --echo End of 5.0 tests. diff --git a/sql/item.cc b/sql/item.cc index 553ba1b152c..9ff1f8c0084 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -4156,9 +4156,14 @@ static void convert_zerofill_number_to_string(Item **item, Field_num *field) String tmp(buff,sizeof(buff), field->charset()), *res; res= (*item)->val_str(&tmp); - field->prepend_zeros(res); - pos= (char *) sql_strmake (res->ptr(), res->length()); - *item= new Item_string(pos, res->length(), field->charset()); + if ((*item)->is_null()) + *item= new Item_null(); + else + { + field->prepend_zeros(res); + pos= (char *) sql_strmake (res->ptr(), res->length()); + *item= new Item_string(pos, res->length(), field->charset()); + } } From 9028d2e43668686d0dfa1678c2b0a48890dde01b Mon Sep 17 00:00:00 2001 From: "gshchepa/uchum@host.loc" <> Date: Wed, 23 Apr 2008 02:14:58 +0500 Subject: [PATCH 02/11] Fixed bug #35993: memory corruption and crash with multibyte conversion. Grouping or ordering of long values in not indexed BLOB/TEXT columns with GBK or BIG5 charsets crashes the server. MySQL server uses sorting (the filesort procedure) in the temporary table to evaluate the GROUP BY clause in case of lack of suitable index. That procedure takes into account only first @max_sort_length bytes (system variable, usually 1024) of TEXT/BLOB sorting key string. The my_strnxfrm_gbk and my_strnxfrm_big5 fill temporary keys with data of whole blob length instead of @max_sort_length bytes length. That buffer overrun has been fixed. --- mysql-test/r/ctype_gbk.result | 7 +++++++ mysql-test/t/ctype_gbk.test | 14 ++++++++++++++ strings/ctype-big5.c | 6 ++++-- strings/ctype-gbk.c | 6 ++++-- 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/ctype_gbk.result b/mysql-test/r/ctype_gbk.result index 6066246a2ef..1b425134095 100644 --- a/mysql-test/r/ctype_gbk.result +++ b/mysql-test/r/ctype_gbk.result @@ -247,4 +247,11 @@ t1 CREATE TABLE `t1` ( `c2` text NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=gbk drop table t1; +CREATE TABLE t1(a MEDIUMTEXT CHARACTER SET gbk, +b MEDIUMTEXT CHARACTER SET big5); +INSERT INTO t1 VALUES +(REPEAT(0x1125,200000), REPEAT(0x1125,200000)), ('', ''), ('', ''); +SELECT a FROM t1 GROUP BY 1 LIMIT 1 INTO @nullll; +SELECT b FROM t1 GROUP BY 1 LIMIT 1 INTO @nullll; +DROP TABLES t1; End of 5.0 tests diff --git a/mysql-test/t/ctype_gbk.test b/mysql-test/t/ctype_gbk.test index 3ea696338dc..91fe50d89b9 100644 --- a/mysql-test/t/ctype_gbk.test +++ b/mysql-test/t/ctype_gbk.test @@ -53,4 +53,18 @@ alter table t1 change c1 c1 mediumtext character set gbk not null; show create table t1; drop table t1; +# +# Bug#35993: severe memory corruption and crash with multibyte conversion +# + +CREATE TABLE t1(a MEDIUMTEXT CHARACTER SET gbk, + b MEDIUMTEXT CHARACTER SET big5); +INSERT INTO t1 VALUES + (REPEAT(0x1125,200000), REPEAT(0x1125,200000)), ('', ''), ('', ''); + +SELECT a FROM t1 GROUP BY 1 LIMIT 1 INTO @nullll; +SELECT b FROM t1 GROUP BY 1 LIMIT 1 INTO @nullll; + +DROP TABLES t1; + --echo End of 5.0 tests diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c index 44b9951657d..c73247db404 100644 --- a/strings/ctype-big5.c +++ b/strings/ctype-big5.c @@ -307,15 +307,17 @@ static int my_strnxfrm_big5(CHARSET_INFO *cs __attribute__((unused)), { uint16 e; uint dstlen= len; + uchar *dest_end= dest + dstlen; len = srclen; - while (len--) + while (len-- && dest < dest_end) { if ((len > 0) && isbig5code(*src, *(src+1))) { e = big5strokexfrm((uint16) big5code(*src, *(src+1))); *dest++ = big5head(e); - *dest++ = big5tail(e); + if (dest < dest_end) + *dest++ = big5tail(e); src +=2; len--; } else diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c index 8ac7d62c9da..d0ba33aa3cc 100644 --- a/strings/ctype-gbk.c +++ b/strings/ctype-gbk.c @@ -2668,15 +2668,17 @@ static int my_strnxfrm_gbk(CHARSET_INFO *cs __attribute__((unused)), { uint16 e; uint dstlen= len; + uchar *dest_end= dest + dstlen; len = srclen; - while (len--) + while (len-- && dest < dest_end) { if ((len > 0) && isgbkcode(*src, *(src+1))) { e = gbksortorder((uint16) gbkcode(*src, *(src+1))); *dest++ = gbkhead(e); - *dest++ = gbktail(e); + if (dest < dest_end) + *dest++ = gbktail(e); src+=2; len--; } else From a0c5b495cb25af8154850519e55c11c024414af3 Mon Sep 17 00:00:00 2001 From: "gshchepa/uchum@host.loc" <> Date: Wed, 23 Apr 2008 02:27:23 +0500 Subject: [PATCH 03/11] Fixed bug#36005: server crashes inside NOT IN clause subquery with impossible WHERE/HAVING clause (subselect_single_select_engine::exec). Allocation and initialization of joined table list t1, t2... of subqueries like: NOT IN (SELECT ... FROM t1,t2,... WHERE 0) is optimized out, however server tries to traverse this list. --- mysql-test/r/subselect3.result | 9 +++++++++ mysql-test/t/subselect3.test | 13 +++++++++++++ sql/sql_select.cc | 1 + 3 files changed, 23 insertions(+) diff --git a/mysql-test/r/subselect3.result b/mysql-test/r/subselect3.result index c194ba33756..5221fa09744 100644 --- a/mysql-test/r/subselect3.result +++ b/mysql-test/r/subselect3.result @@ -770,4 +770,13 @@ SELECT ROW(1, 2) IN (SELECT t1.a, 2 FROM t2) FROM t1 GROUP BY t1.a; ROW(1, 2) IN (SELECT t1.a, 2 FROM t2) 1 DROP TABLE t1, t2; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2),(3); +CREATE TABLE t2 SELECT * FROM t1; +SELECT 1 FROM t1 WHERE t1.a NOT IN (SELECT 1 FROM t1, t2 WHERE 0); +1 +1 +1 +1 +DROP TABLE t1, t2; End of 5.0 tests diff --git a/mysql-test/t/subselect3.test b/mysql-test/t/subselect3.test index cfbde8c29cd..d7bb1f7186a 100644 --- a/mysql-test/t/subselect3.test +++ b/mysql-test/t/subselect3.test @@ -605,4 +605,17 @@ SELECT ROW(1, 2) IN (SELECT t1.a, 2 FROM t2) FROM t1 GROUP BY t1.a; DROP TABLE t1, t2; +# +# Bug #36005: crash in subselect with single row +# (subselect_single_select_engine::exec) +# + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2),(3); +CREATE TABLE t2 SELECT * FROM t1; + +SELECT 1 FROM t1 WHERE t1.a NOT IN (SELECT 1 FROM t1, t2 WHERE 0); + +DROP TABLE t1, t2; + --echo End of 5.0 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 976d7322f56..11062998e6a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -832,6 +832,7 @@ JOIN::optimize() "Impossible HAVING" : "Impossible WHERE")); zero_result_cause= having_value == Item::COND_FALSE ? "Impossible HAVING" : "Impossible WHERE"; + tables= 0; error= 0; DBUG_RETURN(0); } From b210e5df6de43338607fd28d9b1c71298033723d Mon Sep 17 00:00:00 2001 From: "igor@olga.mysql.com" <> Date: Tue, 22 Apr 2008 21:49:39 -0700 Subject: [PATCH 04/11] Fixed bug#35844. The function test_if_skip_sort_order ignored any covering index used for ref access of a table in a query with ORDER BY if this index was incompatible with the ORDER BY list and there was another covering index compatible with this list. As a result sub-optimal execution plans were chosen for some queries with ORDER BY clause. --- mysql-test/r/distinct.result | 2 +- mysql-test/r/order_by.result | 26 ++++++++++++++++++++++++++ mysql-test/t/order_by.test | 32 ++++++++++++++++++++++++++++++++ sql/sql_select.cc | 7 ++++++- 4 files changed, 65 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/distinct.result b/mysql-test/r/distinct.result index 15e4c3f15b3..1fbda27f5da 100644 --- a/mysql-test/r/distinct.result +++ b/mysql-test/r/distinct.result @@ -694,7 +694,7 @@ INSERT INTO t1(a, b, c) VALUES (1, 1, 1), (1, 2, 3); EXPLAIN SELECT DISTINCT a, b, d, c FROM t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL a 16 NULL 6 Using index +1 SIMPLE t1 range NULL PRIMARY 16 NULL 7 Using index for group-by; Using temporary SELECT DISTINCT a, b, d, c FROM t1; a b d c 1 1 0 1 diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index faab8e49880..e70ce75797d 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -1458,3 +1458,29 @@ ORDER BY t2.c LIMIT 1; d 52.5 DROP TABLE t1,t2,t3; +CREATE TABLE t1 ( +id1 INT NULL, +id2 INT NOT NULL, +junk INT NOT NULL, +PRIMARY KEY (id1, id2, junk), +INDEX id2_j_id1 (id2, junk, id1) +); +INSERT INTO t1 VALUES (1, 1, 1), (2, 1, 2), (3, 1, 3), (4, 1, 4); +INSERT INTO t1 VALUES (5, 2, 1), (6, 2, 2), (7, 2, 3), (8, 2, 4); +INSERT INTO t1 VALUES (9, 3, 1), (10, 3, 2), (11, 3, 3), (12, 3, 4); +INSERT INTO t1 VALUES (13, 4, 1), (14, 4, 2), (15, 4, 3), (16, 4, 4); +INSERT INTO t1 VALUES (17, 5, 1), (18, 5, 2), (19, 5, 3), (20, 5, 4); +INSERT INTO t1 VALUES (21, 6, 1), (22, 6, 2), (23, 6, 3), (24, 6, 4); +INSERT INTO t1 VALUES (25, 7, 1), (26, 7, 2), (27, 7, 3), (28, 7, 4); +INSERT INTO t1 VALUES (29, 8, 1), (30, 8, 2), (31, 8, 3), (32, 8, 4); +INSERT INTO t1 VALUES (33, 9, 1), (34, 9, 2), (35, 9, 3), (36, 9, 4); +EXPLAIN SELECT id1 FROM t1 WHERE id2 = 4 ORDER BY id1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref id2_j_id1 id2_j_id1 4 const 4 Using where; Using index; Using filesort +SELECT id1 FROM t1 WHERE id2 = 4 ORDER BY id1; +id1 +13 +14 +15 +16 +DROP TABLE t1; diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test index 64665c6b5bd..bf4cc37a80f 100644 --- a/mysql-test/t/order_by.test +++ b/mysql-test/t/order_by.test @@ -1309,3 +1309,35 @@ WHERE t2.b=14 AND t2.a=t1.a AND 5.1join_tab; ha_rows table_records= table->file->stats.records; bool group= join->group && order == join->group_list; + ha_rows ref_key_quick_rows= HA_POS_ERROR; LINT_INIT(best_key_parts); LINT_INIT(best_key_direction); LINT_INIT(best_records); @@ -12999,6 +13000,9 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, else keys= usable_keys; + if (ref_key >= 0 && table->covering_keys.is_set(ref_key)) + ref_key_quick_rows= table->quick_rows[ref_key]; + read_time= join->best_positions[tablenr].read_time; for (uint i= tablenr+1; i < join->tables; i++) fanout*= join->best_positions[i].records_read; // fanout is always >= 1 @@ -13093,7 +13097,8 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, index_scan_time < read_time) { ha_rows quick_records= table_records; - if (is_best_covering && !is_covering) + if (is_best_covering && !is_covering || + is_covering && ref_key_quick_rows < select_limit) continue; if (table->quick_keys.is_set(nr)) quick_records= table->quick_rows[nr]; From 9c707374101044d6fa437b56f1dad710b49e3319 Mon Sep 17 00:00:00 2001 From: "gshchepa/uchum@host.loc" <> Date: Wed, 23 Apr 2008 14:22:49 +0500 Subject: [PATCH 05/11] subselect.test, subselect.result: Post-commit minor cleanup of testcase (bug#36139). --- mysql-test/r/subselect.result | 2 +- mysql-test/t/subselect.test | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 349b874cbb9..e56c2f07d80 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -4380,5 +4380,5 @@ select t1.a from t1 where t1.a= (select b from t2 limit 1) and not t1.a= (select a from t2 limit 1) ; a -drop table t1; +drop table t1, t2; End of 5.0 tests. diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index a60159381e1..527bd528f79 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -3269,7 +3269,7 @@ select t1.a from t1 where t1.a= (select b from t2 limit 1) and not t1.a= (select a from t2 limit 1) ; -drop table t1; +drop table t1, t2; --echo End of 5.0 tests. From d365bd3d4a17b085319ab70d5dc801417f0e6f91 Mon Sep 17 00:00:00 2001 From: "ramil/ram@mysql.com/ramil.myoffice.izhnet.ru" <> Date: Thu, 24 Apr 2008 16:43:08 +0500 Subject: [PATCH 06/11] Enabled rpl: rpl_view, rpl_ndb_multi, rpl_log_pos and main: user_limits, concurrent_innodb, lowercase_table3, ctype_create tests. --- mysql-test/suite/ndb/t/disabled.def | 2 -- mysql-test/suite/rpl/t/disabled.def | 3 --- mysql-test/t/disabled.def | 5 ----- 3 files changed, 10 deletions(-) diff --git a/mysql-test/suite/ndb/t/disabled.def b/mysql-test/suite/ndb/t/disabled.def index f876039a042..c638c7b4774 100644 --- a/mysql-test/suite/ndb/t/disabled.def +++ b/mysql-test/suite/ndb/t/disabled.def @@ -14,5 +14,3 @@ partition_03ndb : BUG#16385 2006-03-24 mikael Partitions: crash when up ndb_partition_error2 : HF is not sure if the test can work as internded on all the platforms # the below testcase have been reworked to avoid the bug, test contains comment, keep bug open -#ndb_binlog_ddl_multi : BUG#18976 2006-04-10 kent CRBR: multiple binlog, second binlog may miss schema log events -#ndb_binlog_discover : bug#21806 2006-08-24 diff --git a/mysql-test/suite/rpl/t/disabled.def b/mysql-test/suite/rpl/t/disabled.def index 4375a2a8aa5..62acae3b15e 100644 --- a/mysql-test/suite/rpl/t/disabled.def +++ b/mysql-test/suite/rpl/t/disabled.def @@ -12,6 +12,3 @@ rpl_ddl : BUG#26418 2007-03-01 mleich Slave out of sync after CREATE/DROP TEMPORARY TABLE + ROLLBACK on master rpl_innodb_bug28430 : Bug #32247 2007-11-27 mats Test reports wrong value of "AUTO_INCREMENT" (on a partitioned InnoDB table) -rpl_view : Bug#32654: rpl_view.test fails randomly -rpl_ndb_multi : Bug#30751: rpl_ndb_multi missing row in output -rpl_log_pos : Bug#8693 Test 'rpl_log_pos' fails sometimes diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index 89979ef8dee..2025725fbdc 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -9,13 +9,8 @@ # Do not use any TAB characters for whitespace. # ############################################################################## -user_limits : Bug#23921 random failure of user_limits.test - -concurrent_innodb : BUG#21579 2006-08-11 mleich innodb_concurrent random failures with varying differences federated_transactions : Bug#29523 Transactions do not work -lowercase_table3 : Bug#32667 lowercase_table3.test reports to error log innodb_mysql : Bug#32724: innodb_mysql.test fails randomly -ctype_create : Bug#32965 main.ctype_create fails status : Bug#32966 main.status fails ps_ddl : Bug#12093 2007-12-14 pending WL#4165 / WL#4166 csv_alter_table : Bug#33696 2008-01-21 pcrews no .result file - bug allows NULL columns in CSV tables From e9e6679381bf1b3c114302a338b66beee59e9bef Mon Sep 17 00:00:00 2001 From: "evgen@moonbone.local" <> Date: Fri, 25 Apr 2008 00:39:37 +0400 Subject: [PATCH 07/11] Bug#36023: Incorrect handling of zero length caused an assertion to fail. When a zero length is provided to the my_decimal_length_to_precision function along with unsigned_flag set to false it returns a negative value. For queries that employs temporary tables may cause failed assertion or excessive memory consumption while temporary table creation. Now the my_decimal_length_to_precision and the my_decimal_precision_to_length functions take unsigned_flag into account only if the length/precision argument is non-zero. --- mysql-test/r/type_decimal.result | 7 +++++++ mysql-test/t/type_decimal.test | 8 ++++++++ sql/my_decimal.h | 13 +++++++++++-- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/type_decimal.result b/mysql-test/r/type_decimal.result index 2afd42f702e..03fbc898cc5 100644 --- a/mysql-test/r/type_decimal.result +++ b/mysql-test/r/type_decimal.result @@ -946,4 +946,11 @@ SELECT ROUND(20061108085411.000002); ROUND(20061108085411.000002) 20061108085411 DROP TABLE t1, t2, t3, t4, t5, t6; +create table t1(`c` decimal(9,2)); +insert into t1 values (300),(201.11); +select max(case 1 when 1 then c else null end) from t1 group by c; +max(case 1 when 1 then c else null end) +201.11 +300.00 +drop table t1; End of 5.0 tests diff --git a/mysql-test/t/type_decimal.test b/mysql-test/t/type_decimal.test index 6841b3cdd68..8a81908296f 100644 --- a/mysql-test/t/type_decimal.test +++ b/mysql-test/t/type_decimal.test @@ -521,4 +521,12 @@ SELECT ROUND(20061108085411.000002); DROP TABLE t1, t2, t3, t4, t5, t6; +# +# Bug#36023: Incorrect handling of zero length caused an assertion to fail. +# +create table t1(`c` decimal(9,2)); +insert into t1 values (300),(201.11); +select max(case 1 when 1 then c else null end) from t1 group by c; +drop table t1; + --echo End of 5.0 tests diff --git a/sql/my_decimal.h b/sql/my_decimal.h index c661579ea66..6a0d05921ec 100644 --- a/sql/my_decimal.h +++ b/sql/my_decimal.h @@ -164,14 +164,23 @@ inline int check_result_and_overflow(uint mask, int result, my_decimal *val) inline uint my_decimal_length_to_precision(uint length, uint scale, bool unsigned_flag) { - return (uint) (length - (scale>0 ? 1:0) - (unsigned_flag ? 0:1)); + /* Precision can't be negative thus ignore unsigned_flag when length is 0. */ + DBUG_ASSERT(length || !scale); + return (uint) (length - (scale>0 ? 1:0) - + (unsigned_flag || !length ? 0:1)); } inline uint32 my_decimal_precision_to_length(uint precision, uint8 scale, bool unsigned_flag) { + /* + When precision is 0 it means that original length was also 0. Thus + unsigned_flag is ignored in this case. + */ + DBUG_ASSERT(precision || !scale); set_if_smaller(precision, DECIMAL_MAX_PRECISION); - return (uint32)(precision + (scale>0 ? 1:0) + (unsigned_flag ? 0:1)); + return (uint32)(precision + (scale>0 ? 1:0) + + (unsigned_flag || !precision ? 0:1)); } inline From 107b84f9bd34cddb5fa13969d4156e73ccf477bf Mon Sep 17 00:00:00 2001 From: "gshchepa/uchum@host.loc" <> Date: Sat, 26 Apr 2008 02:45:58 +0500 Subject: [PATCH 08/11] Fixed bug#36006: Optimizer does table scan for SELECT COUNT(*) for ENGINE=MRG_MYISAM (should be optimized out). Before WL#3281 MERGE engine had the HA_NOT_EXACT_COUNT flag unset, and it worked with COUNT optimization as desired. After the removal of the HA_NOT_EXACT_COUNT flag neither HA_STATS_RECORDS_IS_EXACT (opposite to former HA_NOT_EXACT_COUNT flag) nor modern HA_HAS_RECORDS flag were not added to MERGE table flag mask. 1. The HA_HAS_RECORDS table flag has been set. 2. The ha_myisammrg::records method has been overridden to calculate total number of records in underlying tables. --- include/myisammrg.h | 1 + mysql-test/r/merge.result | 16 ++++++++++++++++ mysql-test/t/merge.test | 16 ++++++++++++++++ storage/myisammrg/CMakeLists.txt | 2 +- storage/myisammrg/Makefile.am | 2 +- storage/myisammrg/ha_myisammrg.cc | 6 ++++++ storage/myisammrg/ha_myisammrg.h | 2 ++ storage/myisammrg/myrg_records.c | 27 +++++++++++++++++++++++++++ 8 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 storage/myisammrg/myrg_records.c diff --git a/include/myisammrg.h b/include/myisammrg.h index cc6e6aac6cd..dafae157ee0 100644 --- a/include/myisammrg.h +++ b/include/myisammrg.h @@ -112,6 +112,7 @@ extern int myrg_reset(MYRG_INFO *info); extern void myrg_extrafunc(MYRG_INFO *info,invalidator_by_filename inv); extern ha_rows myrg_records_in_range(MYRG_INFO *info, int inx, key_range *min_key, key_range *max_key); +extern ha_rows myrg_records(MYRG_INFO *info); extern ulonglong myrg_position(MYRG_INFO *info); #ifdef __cplusplus diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index 4c05000573c..ef623b343e9 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -2006,3 +2006,19 @@ test.t1 optimize status OK FLUSH TABLES m1, t1; UNLOCK TABLES; DROP TABLE t1, m1; +CREATE TABLE t1(C1 INT, C2 INT, KEY C1(C1), KEY C2(C2)) ENGINE=MYISAM; +CREATE TABLE t2(C1 INT, C2 INT, KEY C1(C1), KEY C2(C2)) ENGINE=MYISAM; +CREATE TABLE t3(C1 INT, C2 INT, KEY C1(C1), KEY C2(C2)) ENGINE=MYISAM; +CREATE TABLE t4(C1 INT, C2 INT, KEY C1(C1), KEY C2(C2)) +ENGINE=MRG_MYISAM UNION=(t1, t2, t3); +INSERT INTO t1 VALUES (1,1), (1,2),(1,3), (1,4); +INSERT INTO t2 VALUES (2,1), (2,2),(2,3), (2,4); +INSERT INTO t3 VALUES (3,1), (3,2),(3,3), (3,4); +EXPLAIN SELECT COUNT(*) FROM t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +EXPLAIN SELECT COUNT(*) FROM t4; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +DROP TABLE t1, t2, t3, t4; +End of 5.1 tests diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test index a4602a3b82a..76e746db037 100644 --- a/mysql-test/t/merge.test +++ b/mysql-test/t/merge.test @@ -1394,3 +1394,19 @@ FLUSH TABLES m1, t1; UNLOCK TABLES; DROP TABLE t1, m1; +# +# Bug#36006 - Optimizer does table scan for select count(*) +# +CREATE TABLE t1(C1 INT, C2 INT, KEY C1(C1), KEY C2(C2)) ENGINE=MYISAM; +CREATE TABLE t2(C1 INT, C2 INT, KEY C1(C1), KEY C2(C2)) ENGINE=MYISAM; +CREATE TABLE t3(C1 INT, C2 INT, KEY C1(C1), KEY C2(C2)) ENGINE=MYISAM; +CREATE TABLE t4(C1 INT, C2 INT, KEY C1(C1), KEY C2(C2)) + ENGINE=MRG_MYISAM UNION=(t1, t2, t3); +INSERT INTO t1 VALUES (1,1), (1,2),(1,3), (1,4); +INSERT INTO t2 VALUES (2,1), (2,2),(2,3), (2,4); +INSERT INTO t3 VALUES (3,1), (3,2),(3,3), (3,4); +EXPLAIN SELECT COUNT(*) FROM t1; +EXPLAIN SELECT COUNT(*) FROM t4; +DROP TABLE t1, t2, t3, t4; + +--echo End of 5.1 tests diff --git a/storage/myisammrg/CMakeLists.txt b/storage/myisammrg/CMakeLists.txt index 403ca6c2776..1c94e2bd50c 100755 --- a/storage/myisammrg/CMakeLists.txt +++ b/storage/myisammrg/CMakeLists.txt @@ -26,7 +26,7 @@ SET(MYISAMMRG_SOURCES myrg_close.c myrg_create.c myrg_delete.c myrg_extra.c myr myrg_locking.c myrg_open.c myrg_panic.c myrg_queue.c myrg_range.c myrg_rfirst.c myrg_rkey.c myrg_rlast.c myrg_rnext.c myrg_rnext_same.c myrg_rprev.c myrg_rrnd.c myrg_rsame.c myrg_static.c myrg_update.c - myrg_write.c) + myrg_write.c myrg_records.c) IF(NOT SOURCE_SUBLIBS) ADD_LIBRARY(myisammrg ${MYISAMMRG_SOURCES}) diff --git a/storage/myisammrg/Makefile.am b/storage/myisammrg/Makefile.am index e058dfdbb5e..1ca51bc9d03 100644 --- a/storage/myisammrg/Makefile.am +++ b/storage/myisammrg/Makefile.am @@ -35,7 +35,7 @@ libmyisammrg_a_SOURCES = myrg_open.c myrg_extra.c myrg_info.c myrg_locking.c \ myrg_rkey.c myrg_rfirst.c myrg_rlast.c myrg_rnext.c \ myrg_rprev.c myrg_queue.c myrg_write.c myrg_range.c \ ha_myisammrg.cc \ - myrg_rnext_same.c + myrg_rnext_same.c myrg_records.c EXTRA_DIST = CMakeLists.txt plug.in diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index ea7021325e3..956f0e421cc 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -1154,6 +1154,12 @@ int ha_myisammrg::check(THD* thd, HA_CHECK_OPT* check_opt) } +ha_rows ha_myisammrg::records() +{ + return myrg_records(file); +} + + extern int myrg_panic(enum ha_panic_function flag); int myisammrg_panic(handlerton *hton, ha_panic_function flag) { diff --git a/storage/myisammrg/ha_myisammrg.h b/storage/myisammrg/ha_myisammrg.h index 977c45d1435..4e7ddebb836 100644 --- a/storage/myisammrg/ha_myisammrg.h +++ b/storage/myisammrg/ha_myisammrg.h @@ -42,6 +42,7 @@ class ha_myisammrg: public handler HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE | HA_NULL_IN_KEY | HA_CAN_INDEX_BLOBS | HA_FILE_BASED | HA_ANY_INDEX_MAY_BE_UNIQUE | HA_CAN_BIT_FIELD | + HA_HAS_RECORDS | HA_NO_COPY_ON_ALTER); } ulong index_flags(uint inx, uint part, bool all_parts) const @@ -94,4 +95,5 @@ class ha_myisammrg: public handler TABLE *table_ptr() { return table; } bool check_if_incompatible_data(HA_CREATE_INFO *info, uint table_changes); int check(THD* thd, HA_CHECK_OPT* check_opt); + ha_rows records(); }; diff --git a/storage/myisammrg/myrg_records.c b/storage/myisammrg/myrg_records.c new file mode 100644 index 00000000000..03815d934a8 --- /dev/null +++ b/storage/myisammrg/myrg_records.c @@ -0,0 +1,27 @@ +/* Copyright (C) 2008 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include "myrg_def.h" + +ha_rows myrg_records(MYRG_INFO *info) +{ + ha_rows records=0; + MYRG_TABLE *file; + DBUG_ENTER("myrg_records"); + + for (file=info->open_tables ; file != info->end_table ; file++) + records+= file->table->s->state.state.records; + DBUG_RETURN(records); +} From ae0082799a5804aeb919d566dd3892bbd29e4a67 Mon Sep 17 00:00:00 2001 From: "pcrews@pcrews-mac-local.local" <> Date: Sat, 26 Apr 2008 19:52:43 -0400 Subject: [PATCH 09/11] Bug#36032 - Test funcs_1.processlist_priv_ps fails on Windows Bug#36033 - Test funcs_1.processlist_val_ps fails on Windows Bug#36034 - Test parts.part_supported_sql_func_ fails on Windows Bug#36036 - Test parts.partition_alter1_ fails on Windows Bug#36037 - Test parts.partition_alter2_ fails on Windows Bug#36038 - Test parts.partition_basic_ failing on Windows Bug#36039 - Test parts.partition_engine_ fails on Windows Bug#36040 - Test parts.partition_syntax_ fails on Windows Changeset to fix multiple 5.1.24-rc build bugs on Windows platforms. Many of these bugs had the same root causes. --- mysql-test/mysql-test-run.pl | 8 +- .../funcs_1/datadict/processlist_priv.inc | 61 ++--- .../funcs_1/datadict/processlist_val.inc | 22 +- .../funcs_1/r/processlist_priv_no_prot.result | 222 +++++++++--------- .../funcs_1/r/processlist_priv_ps.result | 222 +++++++++--------- .../funcs_1/r/processlist_val_no_prot.result | 24 +- .../suite/funcs_1/r/processlist_val_ps.result | 24 +- .../parts/inc/partition_layout_check1.inc | 36 +-- .../parts/inc/partition_layout_check2.inc | 23 +- .../r/partition_basic_symlink_myisam.result | 1 - 10 files changed, 323 insertions(+), 320 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 9f84b49de3a..55fd70b80b7 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -2420,13 +2420,7 @@ sub setup_vardir() { { # on windows, copy all files from std_data into var/std_data_ln mkpath("$opt_vardir/std_data_ln"); - opendir(DIR, "$glob_mysql_test_dir/std_data") - or mtr_error("Can't find the std_data directory: $!"); - for(readdir(DIR)) { - next if -d "$glob_mysql_test_dir/std_data/$_"; - copy("$glob_mysql_test_dir/std_data/$_", "$opt_vardir/std_data_ln/$_"); - } - closedir(DIR); + mtr_copy_dir("$glob_mysql_test_dir/std_data", "$opt_vardir/std_data_ln"); } # Remove old log files diff --git a/mysql-test/suite/funcs_1/datadict/processlist_priv.inc b/mysql-test/suite/funcs_1/datadict/processlist_priv.inc index 24df7ef8948..66c43c750fd 100644 --- a/mysql-test/suite/funcs_1/datadict/processlist_priv.inc +++ b/mysql-test/suite/funcs_1/datadict/processlist_priv.inc @@ -53,8 +53,9 @@ # WL#3982 Test information_schema.processlist # # # # Last update: # -# 2007-08-14 mleich Corrections # -# # +# 2008-04-14 pcrews replace HOST to account for Windows' use of # +# localhost (host: causing diffs on Windows # +# test runs # ######################################################################## # The following variables are used in "datadict_priv.inc" and here. @@ -112,11 +113,11 @@ connect (con100,localhost,ddicttestuser1,ddictpass,information_schema); --echo #################################################################################### connection default; eval SHOW CREATE TABLE $table; ---replace_column 1 ID 6 TIME +--replace_column 1 ID 3 HOST_NAME 6 TIME eval SHOW $table; ---replace_column 1 ID 6 TIME +--replace_column 1 ID 3 HOST_NAME 6 TIME eval SELECT * FROM $table $select_where ORDER BY id; ---replace_column 1 ID 6 TIME +--replace_column 1 ID 3 HOST_NAME 6 TIME eval SELECT $columns FROM $table $select_where ORDER BY id; --source suite/funcs_1/datadict/datadict_priv.inc --real_sleep 0.3 @@ -128,11 +129,11 @@ connection con100; --echo SHOW/SELECT shows only the processes (1) of the user. --echo #################################################################################### eval SHOW CREATE TABLE $table; ---replace_column 1 ID 6 TIME +--replace_column 1 ID 3 HOST_NAME 6 TIME eval SHOW $table; ---replace_column 1 ID 6 TIME +--replace_column 1 ID 3 HOST_NAME 6 TIME eval SELECT * FROM $table $select_where ORDER BY id; ---replace_column 1 ID 6 TIME +--replace_column 1 ID 3 HOST_NAME 6 TIME eval SELECT $columns FROM $table $select_where ORDER BY id; --source suite/funcs_1/datadict/datadict_priv.inc --real_sleep 0.3 @@ -154,9 +155,9 @@ GRANT PROCESS ON *.* TO ddicttestuser1@'localhost' IDENTIFIED BY 'ddictpass'; --echo #################################################################################### connection con100; SHOW GRANTS; ---replace_column 1 ID 6 TIME +--replace_column 1 ID 3 HOST_NAME 6 TIME SHOW processlist; ---replace_column 1 ID 6 TIME +--replace_column 1 ID 3 HOST_NAME 6 TIME SELECT * FROM information_schema.processlist; --real_sleep 0.3 @@ -166,9 +167,9 @@ SELECT * FROM information_schema.processlist; --echo #################################################################################### connect (con101,localhost,ddicttestuser1,ddictpass,information_schema); SHOW GRANTS; ---replace_column 1 ID 6 TIME +--replace_column 1 ID 3 HOST_NAME 6 TIME SHOW processlist; ---replace_column 1 ID 6 TIME +--replace_column 1 ID 3 HOST_NAME 6 TIME SELECT * FROM information_schema.processlist; --real_sleep 0.3 @@ -188,9 +189,9 @@ GRANT PROCESS ON *.* TO ''@'localhost'; --echo #################################################################################### connect (anonymous1,localhost,'',,information_schema); SHOW GRANTS; ---replace_column 1 ID 6 TIME +--replace_column 1 ID 3 HOST_NAME 6 TIME SHOW processlist; ---replace_column 1 ID 6 TIME +--replace_column 1 ID 3 HOST_NAME 6 TIME SELECT * FROM information_schema.processlist; --real_sleep 0.3 @@ -210,9 +211,9 @@ connect (con102,localhost,ddicttestuser1,ddictpass,information_schema); --echo ddicttestuser1 are visible. --echo #################################################################################### SHOW GRANTS; ---replace_column 1 ID 6 TIME +--replace_column 1 ID 3 HOST_NAME 6 TIME SHOW processlist; ---replace_column 1 ID 6 TIME +--replace_column 1 ID 3 HOST_NAME 6 TIME SELECT * FROM information_schema.processlist; --real_sleep 0.3 @@ -235,10 +236,10 @@ SHOW GRANTS FOR ''@'localhost'; if ($fixed_bug_30395) { # Bug#30395 strange results after REVOKE PROCESS ON *.* FROM ... ---replace_column 1 ID 6 TIME +--replace_column 1 ID 3 HOST_NAME 6 TIME SHOW processlist; } ---replace_column 1 ID 6 TIME +--replace_column 1 ID 3 HOST_NAME 6 TIME SELECT * FROM information_schema.processlist; --real_sleep 0.3 @@ -257,9 +258,9 @@ connect (con103,localhost,ddicttestuser1,ddictpass,information_schema); --echo Only the processes of ddicttestuser1 user are visible. --echo #################################################################################### SHOW GRANTS FOR 'ddicttestuser1'@'localhost'; ---replace_column 1 ID 6 TIME +--replace_column 1 ID 3 HOST_NAME 6 TIME SHOW processlist; ---replace_column 1 ID 6 TIME +--replace_column 1 ID 3 HOST_NAME 6 TIME SELECT * FROM information_schema.processlist; --real_sleep 0.3 @@ -279,9 +280,9 @@ connect (con104,localhost,ddicttestuser1,ddictpass,information_schema); --echo Only the processes of ddicttestuser1 are visible. --echo #################################################################################### SHOW GRANTS FOR 'ddicttestuser1'@'localhost'; ---replace_column 1 ID 6 TIME +--replace_column 1 ID 3 HOST_NAME 6 TIME SHOW processlist; ---replace_column 1 ID 6 TIME +--replace_column 1 ID 3 HOST_NAME 6 TIME SELECT * FROM information_schema.processlist; --real_sleep 0.3 @@ -326,9 +327,9 @@ connect (con200,localhost,ddicttestuser2,ddictpass,information_schema); --echo ddicttestuser2 has now the PROCESS privilege and sees all connections --echo #################################################################################### SHOW GRANTS FOR 'ddicttestuser2'@'localhost'; ---replace_column 1 ID 6 TIME +--replace_column 1 ID 3 HOST_NAME 6 TIME SHOW processlist; ---replace_column 1 ID 6 TIME +--replace_column 1 ID 3 HOST_NAME 6 TIME SELECT * FROM information_schema.processlist; --real_sleep 0.3 @@ -347,9 +348,9 @@ connect (con201,localhost,ddicttestuser2,ddictpass,information_schema); --echo ddicttestuser2 has no more the PROCESS privilege and can only see own connects --echo #################################################################################### SHOW GRANTS; ---replace_column 1 ID 6 TIME +--replace_column 1 ID 3 HOST_NAME 6 TIME SHOW processlist; ---replace_column 1 ID 6 TIME +--replace_column 1 ID 3 HOST_NAME 6 TIME SELECT * FROM information_schema.processlist; --real_sleep 0.3 @@ -370,9 +371,9 @@ connect (con107,localhost,ddicttestuser1,ddictpass,information_schema); SHOW GRANTS FOR 'ddicttestuser1'@'localhost'; --error ER_ACCESS_DENIED_ERROR GRANT PROCESS ON *.* TO 'ddicttestuser2'@'localhost'; ---replace_column 1 ID 6 TIME +--replace_column 1 ID 3 HOST_NAME 6 TIME SHOW processlist; ---replace_column 1 ID 6 TIME +--replace_column 1 ID 3 HOST_NAME 6 TIME SELECT * FROM information_schema.processlist; --real_sleep 0.3 @@ -394,9 +395,9 @@ connect (con108,localhost,ddicttestuser1,ddictpass,information_schema); --echo Therefore the missing SELECT privilege does not affect SELECTs on PROCESSLIST. --echo #################################################################################### SHOW GRANTS FOR 'ddicttestuser1'@'localhost'; ---replace_column 1 ID 6 TIME +--replace_column 1 ID 3 HOST_NAME 6 TIME SHOW processlist; ---replace_column 1 ID 6 TIME +--replace_column 1 ID 3 HOST_NAME 6 TIME SELECT * FROM information_schema.processlist; --real_sleep 0.3 diff --git a/mysql-test/suite/funcs_1/datadict/processlist_val.inc b/mysql-test/suite/funcs_1/datadict/processlist_val.inc index 69a32553f65..29fbd5f616d 100644 --- a/mysql-test/suite/funcs_1/datadict/processlist_val.inc +++ b/mysql-test/suite/funcs_1/datadict/processlist_val.inc @@ -34,7 +34,11 @@ # WL#3982 Test information_schema.processlist # # 2008-01-05 HHunger Changed time test and long statement test. # # It could happen that the long statement test # -# fail due to timing problems. # # # +# fail due to timing problems. # +# 2008-04-14 pcrews Changed --replace_columns to include host # +# this is due to failure occurring on Windows # +# Win results included port number as well causing # +# test failures # ######################################################################## # Basic preparations @@ -76,9 +80,9 @@ SHOW FULL PROCESSLIST; # # Expect to see now DB = 'information_schema' USE information_schema; ---replace_column 1 6