diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index 50c5a71e252..214b732e5cb 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -1,6 +1,5 @@ funcs_1.charset_collation_1 # depends on compile-time decisions main.plugin_load @solaris # Bug#42144 -binlog.binlog_tmp_table* # Bug#45578: Test binlog_tmp_table fails ramdonly on PB2: Unknown table 't2' main.ctype_gbk_binlog @solaris # Bug#46010: main.ctype_gbk_binlog fails sporadically : Table 't2' already exists rpl.rpl_row_create_table* # Bug#45576: rpl_row_create_table fails on PB2 rpl_ndb.rpl_ndb_log # Bug#38998 diff --git a/mysql-test/r/ctype_ldml.result b/mysql-test/r/ctype_ldml.result index 711921eb526..fe870f82743 100644 --- a/mysql-test/r/ctype_ldml.result +++ b/mysql-test/r/ctype_ldml.result @@ -321,3 +321,11 @@ Vv Xx YyÝýỲỳỴỵỶỷỸỹ drop table t1; +Bug#46448 trailing spaces are not ignored when user collation maps space != 0x20 +set names latin1; +show collation like 'latin1_test'; +Collation Charset Id Default Compiled Sortlen +latin1_test latin1 99 Yes 1 +select "foo" = "foo " collate latin1_test; +"foo" = "foo " collate latin1_test +1 diff --git a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result index ac9a53ca238..620f5dc19ec 100644 --- a/mysql-test/r/group_min_max.result +++ b/mysql-test/r/group_min_max.result @@ -876,10 +876,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range NULL idx_t1_1 163 NULL 17 Using where; Using index for group-by explain select a1,a2,b, max(c) from t1 where (c > 'b1') or (c <= 'g1') group by a1,a2,b; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL idx_t1_1 147 NULL 17 Using where; Using index for group-by +1 SIMPLE t1 range NULL idx_t1_1 163 NULL 17 Using where; Using index for group-by explain select a1,a2,b,min(c),max(c) from t1 where (c > 'b1') or (c <= 'g1') group by a1,a2,b; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL idx_t1_1 147 NULL 17 Using where; Using index for group-by +1 SIMPLE t1 range NULL idx_t1_1 163 NULL 17 Using where; Using index for group-by explain select a1,a2,b,min(c),max(c) from t1 where (c > 'b111') and (c <= 'g112') group by a1,a2,b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range NULL idx_t1_1 163 NULL 17 Using where; Using index for group-by @@ -924,7 +924,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 range NULL idx_t2_1 163 NULL # Using where; Using index for group-by explain select a1,a2,b, max(c) from t2 where (c > 'b1') or (c <= 'g1') group by a1,a2,b; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range NULL idx_t2_1 146 NULL # Using where; Using index for group-by +1 SIMPLE t2 range NULL idx_t2_1 163 NULL # Using where; Using index for group-by explain select a1,a2,b,min(c),max(c) from t2 where (c > 'b1') or (c <= 'g1') group by a1,a2,b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 range NULL idx_t2_1 163 NULL # Using where; Using index for group-by diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index 58e2e451a0d..df97e96c334 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -2271,4 +2271,32 @@ checksum table t3; Table Checksum test.t3 326284887 drop table t1,t2,t3; +CREATE TABLE t1(a INT, b CHAR(10), KEY(a), KEY(b)); +INSERT INTO t1 VALUES(1,'0'),(2,'0'),(3,'0'),(4,'0'),(5,'0'), +(6,'0'),(7,'0'); +INSERT INTO t1 SELECT a+10,b FROM t1; +INSERT INTO t1 SELECT a+20,b FROM t1; +INSERT INTO t1 SELECT a+40,b FROM t1; +INSERT INTO t1 SELECT a+80,b FROM t1; +INSERT INTO t1 SELECT a+160,b FROM t1; +INSERT INTO t1 SELECT a+320,b FROM t1; +INSERT INTO t1 SELECT a+640,b FROM t1; +INSERT INTO t1 SELECT a+1280,b FROM t1; +INSERT INTO t1 SELECT a+2560,b FROM t1; +INSERT INTO t1 SELECT a+5120,b FROM t1; +SET myisam_sort_buffer_size=4; +REPAIR TABLE t1; +Table Op Msg_type Msg_text +test.t1 repair error myisam_sort_buffer_size is too small +test.t1 repair warning Number of rows changed from 0 to 7168 +test.t1 repair status OK +SET myisam_repair_threads=2; +REPAIR TABLE t1; +Table Op Msg_type Msg_text +test.t1 repair error myisam_sort_buffer_size is too small +test.t1 repair warning Number of rows changed from # to 7168 +test.t1 repair status OK +SET myisam_repair_threads=@@global.myisam_repair_threads; +SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size; +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result index 2d54a66fe11..6611d39628f 100644 --- a/mysql-test/r/partition.result +++ b/mysql-test/r/partition.result @@ -50,6 +50,21 @@ t1 CREATE TABLE `t1` ( PARTITION p3 VALUES LESS THAN (733969) ENGINE = MyISAM, PARTITION pmax VALUES LESS THAN MAXVALUE ENGINE = MyISAM) */ DROP TABLE t1; +create table t1 (a int, b int, key(a)) +partition by list (a) +( partition p0 values in (1), +partition p1 values in (2)); +insert into t1 values (1,1),(2,1),(2,2),(2,3); +show indexes from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 1 a 1 a A NULL NULL NULL YES BTREE +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +show indexes from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 1 a 1 a A 1 NULL NULL YES BTREE +drop table t1; CREATE TABLE t1 (a INT, FOREIGN KEY (a) REFERENCES t0 (a)) ENGINE=MyISAM PARTITION BY HASH (a); diff --git a/mysql-test/r/partition_open_files_limit.result b/mysql-test/r/partition_open_files_limit.result new file mode 100644 index 00000000000..1441ba4e78e --- /dev/null +++ b/mysql-test/r/partition_open_files_limit.result @@ -0,0 +1,22 @@ +DROP TABLE IF EXISTS `t1`; +# Bug#46922: crash when adding partitions and open_files_limit is reached +CREATE TABLE t1 (a INT PRIMARY KEY) +ENGINE=MyISAM PARTITION BY KEY () PARTITIONS 1; +INSERT INTO t1 VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11); +# if the bug exists, then crash will happen here +ALTER TABLE t1 ADD PARTITION PARTITIONS 511; +ERROR HY000: Out of resources when opening file '' (Errcode: 24) +SELECT * FROM t1; +a +1 +10 +11 +2 +3 +4 +5 +6 +7 +8 +9 +DROP TABLE t1; diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result index cc5e8d2be96..c98a7696ea6 100644 --- a/mysql-test/r/range.result +++ b/mysql-test/r/range.result @@ -1219,3 +1219,182 @@ explain select * from t2 where a=1000 and b<11; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ref a a 5 const 502 Using where drop table t1, t2; +CREATE TABLE t1( a INT, b INT, KEY( a, b ) ); +CREATE TABLE t2( a INT, b INT, KEY( a, b ) ); +CREATE TABLE t3( a INT, b INT, KEY( a, b ) ); +INSERT INTO t1( a, b ) +VALUES (0, 1), (1, 2), (1, 4), (2, 3), (5, 0), (9, 7); +INSERT INTO t2( a, b ) +VALUES ( 1, 1), ( 2, 1), ( 3, 1), ( 4, 1), ( 5, 1), +( 6, 1), ( 7, 1), ( 8, 1), ( 9, 1), (10, 1), +(11, 1), (12, 1), (13, 1), (14, 1), (15, 1), +(16, 1), (17, 1), (18, 1), (19, 1), (20, 1); +INSERT INTO t2 SELECT a, 2 FROM t2 WHERE b = 1; +INSERT INTO t2 SELECT a, 3 FROM t2 WHERE b = 1; +INSERT INTO t2 SELECT -1, -1 FROM t2; +INSERT INTO t2 SELECT -1, -1 FROM t2; +INSERT INTO t2 SELECT -1, -1 FROM t2; +INSERT INTO t3 +VALUES (1, 0), (2, 0), (3, 0), (4, 0), (5, 0), +(6, 0), (7, 0), (8, 0), (9, 0), (10, 0); +INSERT INTO t3 SELECT * FROM t3 WHERE a = 10; +INSERT INTO t3 SELECT * FROM t3 WHERE a = 10; +SELECT * FROM t1 WHERE +3 <= a AND a < 5 OR +5 < a AND b = 3 OR +3 <= a; +a b +5 0 +9 7 +EXPLAIN +SELECT * FROM t1 WHERE +3 <= a AND a < 5 OR +5 < a AND b = 3 OR +3 <= a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index +SELECT * FROM t1 WHERE +3 <= a AND a < 5 OR +5 <= a AND b = 3 OR +3 <= a; +a b +5 0 +9 7 +EXPLAIN +SELECT * FROM t1 WHERE +3 <= a AND a < 5 OR +5 <= a AND b = 3 OR +3 <= a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a a 5 NULL 4 Using where; Using index +SELECT * FROM t1 WHERE +3 <= a AND a <= 5 OR +5 <= a AND b = 3 OR +3 <= a; +a b +5 0 +9 7 +EXPLAIN +SELECT * FROM t1 WHERE +3 <= a AND a <= 5 OR +5 <= a AND b = 3 OR +3 <= a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index +SELECT * FROM t1 WHERE +3 <= a AND a <= 5 OR +3 <= a; +a b +5 0 +9 7 +EXPLAIN +SELECT * FROM t1 WHERE +3 <= a AND a <= 5 OR +3 <= a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index +SELECT * FROM t2 WHERE +5 <= a AND a < 10 AND b = 1 OR +15 <= a AND a < 20 AND b = 3 +OR +1 <= a AND b = 1; +a b +1 1 +2 1 +3 1 +4 1 +5 1 +6 1 +7 1 +8 1 +9 1 +10 1 +11 1 +12 1 +13 1 +14 1 +15 1 +15 3 +16 1 +16 3 +17 1 +17 3 +18 1 +18 3 +19 1 +19 3 +20 1 +EXPLAIN +SELECT * FROM t2 WHERE +5 <= a AND a < 10 AND b = 1 OR +15 <= a AND a < 20 AND b = 3 +OR +1 <= a AND b = 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 range a a 10 NULL 50 Using where; Using index +SELECT * FROM t2 WHERE +5 <= a AND a < 10 AND b = 2 OR +15 <= a AND a < 20 AND b = 3 +OR +1 <= a AND b = 1; +a b +1 1 +2 1 +3 1 +4 1 +5 1 +5 2 +6 1 +6 2 +7 1 +7 2 +8 1 +8 2 +9 1 +9 2 +10 1 +11 1 +12 1 +13 1 +14 1 +15 1 +15 3 +16 1 +16 3 +17 1 +17 3 +18 1 +18 3 +19 1 +19 3 +20 1 +EXPLAIN +SELECT * FROM t2 WHERE +5 <= a AND a < 10 AND b = 2 OR +15 <= a AND a < 20 AND b = 3 +OR +1 <= a AND b = 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 range a a 10 NULL 50 Using where; Using index +SELECT * FROM t3 WHERE +5 <= a AND a < 10 AND b = 3 OR +a < 5 OR +a < 10; +a b +1 0 +2 0 +3 0 +4 0 +5 0 +6 0 +7 0 +8 0 +9 0 +EXPLAIN +SELECT * FROM t3 WHERE +5 <= a AND a < 10 AND b = 3 OR +a < 5 OR +a < 10; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 range a a 5 NULL 8 Using where; Using index +DROP TABLE t1, t2, t3; diff --git a/mysql-test/std_data/Index.xml b/mysql-test/std_data/Index.xml index 988dddcc68a..3dc647d8195 100644 --- a/mysql-test/std_data/Index.xml +++ b/mysql-test/std_data/Index.xml @@ -68,4 +68,17 @@ + + Western + cp1252 West European + csisolatin1 + iso-8859-1 + iso-ir-100 + iso_8859-1 + iso_8859-1:1987 + l1 + latin1 + + + diff --git a/mysql-test/std_data/latin1.xml b/mysql-test/std_data/latin1.xml new file mode 100644 index 00000000000..458b1c34da1 --- /dev/null +++ b/mysql-test/std_data/latin1.xml @@ -0,0 +1,135 @@ + + + + + + Copyright (C) 2009 Sun Microsystems, Inc + + 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 + + + + + + + 00 + 20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20 + 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 + 48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 + 84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10 + 10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10 + 10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 20 + 10 00 10 02 10 10 10 10 10 10 01 10 01 00 01 00 + 00 10 10 10 10 10 10 10 10 10 02 10 02 00 02 01 + 48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 + 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 + 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 10 01 01 01 01 01 01 01 02 + 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 10 02 02 02 02 02 02 02 02 + + + + + + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 5B 5C 5D 5E 5F + 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 D7 F8 F9 FA FB FC FD FE DF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + + + + + + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 F7 D8 D9 DA DB DC DD DE FF + + + + + + + 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F + 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F + 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F + 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F + 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F + 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F + 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F + 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F + 20AC 0081 201A 0192 201E 2026 2020 2021 02C6 2030 0160 2039 0152 008D 017D 008F + 0090 2018 2019 201C 201D 2022 2013 2014 02DC 2122 0161 203A 0153 009D 017E 0178 + 00A0 00A1 00A2 00A3 00A4 00A5 00A6 00A7 00A8 00A9 00AA 00AB 00AC 00AD 00AE 00AF + 00B0 00B1 00B2 00B3 00B4 00B5 00B6 00B7 00B8 00B9 00BA 00BB 00BC 00BD 00BE 00BF + 00C0 00C1 00C2 00C3 00C4 00C5 00C6 00C7 00C8 00C9 00CA 00CB 00CC 00CD 00CE 00CF + 00D0 00D1 00D2 00D3 00D4 00D5 00D6 00D7 00D8 00D9 00DA 00DB 00DC 00DD 00DE 00DF + 00E0 00E1 00E2 00E3 00E4 00E5 00E6 00E7 00E8 00E9 00EA 00EB 00EC 00ED 00EE 00EF + 00F0 00F1 00F2 00F3 00F4 00F5 00F6 00F7 00F8 00F9 00FA 00FB 00FC 00FD 00FE 00FF + + + + + + 00 01 02 03 37 2D 2E 2F 16 05 25 0B 0C 0D 0E 0F + 10 11 12 13 3C 3D 32 26 18 19 3F 27 1C 1D 1E 1F + 40 4F 7F 7B 5B 6C 50 7D 4D 5D 5C 4E 6B 60 4B 61 + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 7A 5E 4C 7E 6E 6F + 7C C1 C2 C3 C4 C5 C6 C7 C8 C9 D1 D2 D3 D4 D5 D6 + D7 D8 D9 E2 E3 E4 E5 E6 E7 E8 E9 4A E0 5A 5F 6D + 79 81 82 83 84 85 86 87 88 89 91 92 93 94 95 96 + 97 98 99 A2 A3 A4 A5 A6 A7 A8 A9 C0 6A D0 A1 07 + 20 21 22 23 24 15 06 17 28 29 2A 2B 2C 09 0A 1B + 30 31 1A 33 34 35 36 08 38 39 3A 3B 04 14 3E E1 + 41 42 43 44 45 46 47 48 49 51 52 53 54 55 56 57 + 58 59 62 63 64 65 66 67 68 69 70 71 72 73 74 75 + 76 77 78 80 8A 8B 8C 8D 8E 8F 90 9A 9B 9C 9D 9E + 9F A0 AA AB AC AD AE AF B0 B1 B2 B3 B4 B5 B6 B7 + B8 B9 BA BB BC BD BE BF CA CB CC CD CE CF DA DB + DC DD DE DF EA EB EC ED EE EF FA FB FC FD FE FF + + + + + + diff --git a/mysql-test/t/ctype_ldml.test b/mysql-test/t/ctype_ldml.test index db9461bfbf7..bc04b93a935 100644 --- a/mysql-test/t/ctype_ldml.test +++ b/mysql-test/t/ctype_ldml.test @@ -86,3 +86,8 @@ select hex(c1) as h, c1 from t1 order by c1, h; select group_concat(hex(c1) order by hex(c1)) from t1 group by c1; select group_concat(c1 order by hex(c1) SEPARATOR '') from t1 group by c1; drop table t1; + +--echo Bug#46448 trailing spaces are not ignored when user collation maps space != 0x20 +set names latin1; +show collation like 'latin1_test'; +select "foo" = "foo " collate latin1_test; diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index 5de7c997a24..faeb5ee686a 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -1518,5 +1518,33 @@ CREATE TABLE t3 select * from t1; checksum table t3; drop table t1,t2,t3; + +# +# BUG#47073 - valgrind errs, corruption,failed repair of partition, +# low myisam_sort_buffer_size +# +CREATE TABLE t1(a INT, b CHAR(10), KEY(a), KEY(b)); +INSERT INTO t1 VALUES(1,'0'),(2,'0'),(3,'0'),(4,'0'),(5,'0'), + (6,'0'),(7,'0'); +INSERT INTO t1 SELECT a+10,b FROM t1; +INSERT INTO t1 SELECT a+20,b FROM t1; +INSERT INTO t1 SELECT a+40,b FROM t1; +INSERT INTO t1 SELECT a+80,b FROM t1; +INSERT INTO t1 SELECT a+160,b FROM t1; +INSERT INTO t1 SELECT a+320,b FROM t1; +INSERT INTO t1 SELECT a+640,b FROM t1; +INSERT INTO t1 SELECT a+1280,b FROM t1; +INSERT INTO t1 SELECT a+2560,b FROM t1; +INSERT INTO t1 SELECT a+5120,b FROM t1; +SET myisam_sort_buffer_size=4; +REPAIR TABLE t1; +SET myisam_repair_threads=2; +# May report different values depending on threads activity. +--replace_regex /changed from [0-9]+/changed from #/ +REPAIR TABLE t1; +SET myisam_repair_threads=@@global.myisam_repair_threads; +SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size; +DROP TABLE t1; + --echo End of 5.1 tests diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test index c5ed098b678..1dfc53c6232 100644 --- a/mysql-test/t/partition.test +++ b/mysql-test/t/partition.test @@ -61,6 +61,19 @@ SELECT * FROM t1; SHOW CREATE TABLE t1; DROP TABLE t1; +# +# Bug#44059: rec_per_key on empty partition gives weird optimiser results +# +create table t1 (a int, b int, key(a)) +partition by list (a) +( partition p0 values in (1), + partition p1 values in (2)); +insert into t1 values (1,1),(2,1),(2,2),(2,3); +show indexes from t1; +analyze table t1; +show indexes from t1; +drop table t1; + # # Bug#36001: Partitions: spelling and using some error messages # diff --git a/mysql-test/t/partition_open_files_limit-master.opt b/mysql-test/t/partition_open_files_limit-master.opt new file mode 100644 index 00000000000..4c1ed0c3da3 --- /dev/null +++ b/mysql-test/t/partition_open_files_limit-master.opt @@ -0,0 +1 @@ +--open-files-limit=5 --max_connections=2 --table_open_cache=1 diff --git a/mysql-test/t/partition_open_files_limit.test b/mysql-test/t/partition_open_files_limit.test new file mode 100644 index 00000000000..e62ebd0ade7 --- /dev/null +++ b/mysql-test/t/partition_open_files_limit.test @@ -0,0 +1,26 @@ +--source include/have_partition.inc + +--disable_warnings +DROP TABLE IF EXISTS `t1`; +--enable_warnings + +# On some platforms the lowest possible open_files_limit is too high... +let $max_open_files_limit= `SELECT @@open_files_limit > 511`; +if ($max_open_files_limit) +{ + skip Need open_files_limit to be lower than 512; +} + +# +--echo # Bug#46922: crash when adding partitions and open_files_limit is reached +# +CREATE TABLE t1 (a INT PRIMARY KEY) +ENGINE=MyISAM PARTITION BY KEY () PARTITIONS 1; +INSERT INTO t1 VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11); +--echo # if the bug exists, then crash will happen here +--replace_regex /file '.*'/file ''/ +--error 23 +ALTER TABLE t1 ADD PARTITION PARTITIONS 511; +--sorted_result +SELECT * FROM t1; +DROP TABLE t1; diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test index e1411e7fd46..dc119b6a77e 100644 --- a/mysql-test/t/range.test +++ b/mysql-test/t/range.test @@ -1046,3 +1046,128 @@ explain select * from t2 where a=1000 and b<11; drop table t1, t2; +# +# Bug#42846: wrong result returned for range scan when using covering index +# +CREATE TABLE t1( a INT, b INT, KEY( a, b ) ); + +CREATE TABLE t2( a INT, b INT, KEY( a, b ) ); + +CREATE TABLE t3( a INT, b INT, KEY( a, b ) ); + +INSERT INTO t1( a, b ) +VALUES (0, 1), (1, 2), (1, 4), (2, 3), (5, 0), (9, 7); + +INSERT INTO t2( a, b ) +VALUES ( 1, 1), ( 2, 1), ( 3, 1), ( 4, 1), ( 5, 1), + ( 6, 1), ( 7, 1), ( 8, 1), ( 9, 1), (10, 1), + (11, 1), (12, 1), (13, 1), (14, 1), (15, 1), + (16, 1), (17, 1), (18, 1), (19, 1), (20, 1); + +INSERT INTO t2 SELECT a, 2 FROM t2 WHERE b = 1; +INSERT INTO t2 SELECT a, 3 FROM t2 WHERE b = 1; + +# To make range scan compelling to the optimizer +INSERT INTO t2 SELECT -1, -1 FROM t2; +INSERT INTO t2 SELECT -1, -1 FROM t2; +INSERT INTO t2 SELECT -1, -1 FROM t2; + +INSERT INTO t3 +VALUES (1, 0), (2, 0), (3, 0), (4, 0), (5, 0), + (6, 0), (7, 0), (8, 0), (9, 0), (10, 0); + +# To make range scan compelling to the optimizer +INSERT INTO t3 SELECT * FROM t3 WHERE a = 10; +INSERT INTO t3 SELECT * FROM t3 WHERE a = 10; + + +# +# Problem#1 Test queries. Will give missing results unless Problem#1 is fixed. +# With one exception, they are independent of Problem#2. +# +SELECT * FROM t1 WHERE +3 <= a AND a < 5 OR +5 < a AND b = 3 OR +3 <= a; + +EXPLAIN +SELECT * FROM t1 WHERE +3 <= a AND a < 5 OR +5 < a AND b = 3 OR +3 <= a; + +# Query below: Tests both Problem#1 and Problem#2 (EXPLAIN differs as well) +SELECT * FROM t1 WHERE +3 <= a AND a < 5 OR +5 <= a AND b = 3 OR +3 <= a; + +EXPLAIN +SELECT * FROM t1 WHERE +3 <= a AND a < 5 OR +5 <= a AND b = 3 OR +3 <= a; + +SELECT * FROM t1 WHERE +3 <= a AND a <= 5 OR +5 <= a AND b = 3 OR +3 <= a; + +EXPLAIN +SELECT * FROM t1 WHERE +3 <= a AND a <= 5 OR +5 <= a AND b = 3 OR +3 <= a; + +SELECT * FROM t1 WHERE +3 <= a AND a <= 5 OR +3 <= a; + +EXPLAIN +SELECT * FROM t1 WHERE +3 <= a AND a <= 5 OR +3 <= a; + +# +# Problem#2 Test queries. +# These queries will give missing results if Problem#1 is fixed. +# But Problem#1 also hides this bug. +# +SELECT * FROM t2 WHERE +5 <= a AND a < 10 AND b = 1 OR +15 <= a AND a < 20 AND b = 3 +OR +1 <= a AND b = 1; + +EXPLAIN +SELECT * FROM t2 WHERE +5 <= a AND a < 10 AND b = 1 OR +15 <= a AND a < 20 AND b = 3 +OR +1 <= a AND b = 1; + +SELECT * FROM t2 WHERE +5 <= a AND a < 10 AND b = 2 OR +15 <= a AND a < 20 AND b = 3 +OR +1 <= a AND b = 1; + +EXPLAIN +SELECT * FROM t2 WHERE +5 <= a AND a < 10 AND b = 2 OR +15 <= a AND a < 20 AND b = 3 +OR +1 <= a AND b = 1; + +SELECT * FROM t3 WHERE +5 <= a AND a < 10 AND b = 3 OR +a < 5 OR +a < 10; + +EXPLAIN +SELECT * FROM t3 WHERE +5 <= a AND a < 10 AND b = 3 OR +a < 5 OR +a < 10; + +DROP TABLE t1, t2, t3; diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index df5badccb1e..451631ff373 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -1280,10 +1280,10 @@ void ha_partition::cleanup_new_partition(uint part_count) m_file= m_added_file; m_added_file= NULL; + external_lock(ha_thd(), F_UNLCK); /* delete_table also needed, a bit more complex */ close(); - m_added_file= m_file; m_file= save_m_file; } DBUG_VOID_RETURN; @@ -5011,8 +5011,9 @@ int ha_partition::info(uint flag) If the handler doesn't support statistics, it should set all of the above to 0. - We will allow the first handler to set the rec_per_key and use - this as an estimate on the total table. + We first scans through all partitions to get the one holding most rows. + We will then allow the handler with the most rows to set + the rec_per_key and use this as an estimate on the total table. max_data_file_length: Maximum data file length We ignore it, is only used in @@ -5024,14 +5025,33 @@ int ha_partition::info(uint flag) ref_length: We set this to the value calculated and stored in local object create_time: Creation time of table - Set by first handler - So we calculate these constants by using the variables on the first - handler. + So we calculate these constants by using the variables from the + handler with most rows. */ - handler *file; + handler *file, **file_array; + ulonglong max_records= 0; + uint32 i= 0; + uint32 handler_instance= 0; - file= m_file[0]; + file_array= m_file; + do + { + file= *file_array; + /* Get variables if not already done */ + if (!(flag & HA_STATUS_VARIABLE) || + !bitmap_is_set(&(m_part_info->used_partitions), + (file_array - m_file))) + file->info(HA_STATUS_VARIABLE); + if (file->stats.records > max_records) + { + max_records= file->stats.records; + handler_instance= i; + } + i++; + } while (*(++file_array)); + + file= m_file[handler_instance]; file->info(HA_STATUS_CONST); stats.create_time= file->stats.create_time; ref_length= m_ref_length; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 1b1d948b3b9..119f90bc97a 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -6512,6 +6512,63 @@ get_range(SEL_ARG **e1,SEL_ARG **e2,SEL_ARG *root1) } +/** + Combine two range expression under a common OR. On a logical level, the + transformation is key_or( expr1, expr2 ) => expr1 OR expr2. + + Both expressions are assumed to be in the SEL_ARG format. In a logic sense, + theformat is reminiscent of DNF, since an expression such as the following + + ( 1 < kp1 < 10 AND p1 ) OR ( 10 <= kp2 < 20 AND p2 ) + + where there is a key consisting of keyparts ( kp1, kp2, ..., kpn ) and p1 + and p2 are valid SEL_ARG expressions over keyparts kp2 ... kpn, is a valid + SEL_ARG condition. The disjuncts appear ordered by the minimum endpoint of + the first range and ranges must not overlap. It follows that they are also + ordered by maximum endpoints. Thus + + ( 1 < kp1 <= 2 AND ( kp2 = 2 OR kp2 = 3 ) ) OR kp1 = 3 + + Is a a valid SER_ARG expression for a key of at least 2 keyparts. + + For simplicity, we will assume that expr2 is a single range predicate, + i.e. on the form ( a < x < b AND ... ). It is easy to generalize to a + disjunction of several predicates by subsequently call key_or for each + disjunct. + + The algorithm iterates over each disjunct of expr1, and for each disjunct + where the first keypart's range overlaps with the first keypart's range in + expr2: + + If the predicates are equal for the rest of the keyparts, or if there are + no more, the range in expr2 has its endpoints copied in, and the SEL_ARG + node in expr2 is deallocated. If more ranges became connected in expr1, the + surplus is also dealocated. If they differ, two ranges are created. + + - The range leading up to the overlap. Empty if endpoints are equal. + + - The overlapping sub-range. May be the entire range if they are equal. + + Finally, there may be one more range if expr2's first keypart's range has a + greater maximum endpoint than the last range in expr1. + + For the overlapping sub-range, we recursively call key_or. Thus in order to + compute key_or of + + (1) ( 1 < kp1 < 10 AND 1 < kp2 < 10 ) + + (2) ( 2 < kp1 < 20 AND 4 < kp2 < 20 ) + + We create the ranges 1 < kp <= 2, 2 < kp1 < 10, 10 <= kp1 < 20. For the + first one, we simply hook on the condition for the second keypart from (1) + : 1 < kp2 < 10. For the second range 2 < kp1 < 10, key_or( 1 < kp2 < 10, 4 + < kp2 < 20 ) is called, yielding 1 < kp2 < 20. For the last range, we reuse + the range 4 < kp2 < 20 from (2) for the second keypart. The result is thus + + ( 1 < kp1 <= 2 AND 1 < kp2 < 10 ) OR + ( 2 < kp1 < 10 AND 1 < kp2 < 20 ) OR + ( 10 <= kp1 < 20 AND 4 < kp2 < 20 ) +*/ static SEL_ARG * key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2) { @@ -6663,7 +6720,21 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2) key1=key1->tree_delete(save); } last->copy_min(tmp); - if (last->copy_min(key2) || last->copy_max(key2)) + bool full_range= last->copy_min(key2); + if (!full_range) + { + if (last->next && key2->cmp_max_to_min(last->next) >= 0) + { + last->max_value= last->next->min_value; + if (last->next->min_flag & NEAR_MIN) + last->max_flag&= ~NEAR_MAX; + else + last->max_flag|= NEAR_MAX; + } + else + full_range= last->copy_max(key2); + } + if (full_range) { // Full range key1->free_tree(); for (; key2 ; key2=key2->next) @@ -6673,8 +6744,6 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2) return 0; } } - key2=key2->next; - continue; } if (cmp >= 0 && tmp->cmp_min_to_min(key2) < 0) diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 5198e685817..aa9a2eeb77a 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -1087,22 +1087,6 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool do_optimize) ha_rows rows= file->state->records; DBUG_ENTER("ha_myisam::repair"); - /* - Normally this method is entered with a properly opened table. If the - repair fails, it can be repeated with more elaborate options. Under - special circumstances it can happen that a repair fails so that it - closed the data file and cannot re-open it. In this case file->dfile - is set to -1. We must not try another repair without an open data - file. (Bug #25289) - */ - if (file->dfile == -1) - { - sql_print_information("Retrying repair of: '%s' failed. " - "Please try REPAIR EXTENDED or myisamchk", - table->s->path.str); - DBUG_RETURN(HA_ADMIN_FAILED); - } - param.db_name= table->s->db.str; param.table_name= table->alias; param.tmpfile_createflag = O_RDWR | O_TRUNC; diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c index 1c33ffa90f5..8f7b1399aa2 100644 --- a/storage/myisam/mi_check.c +++ b/storage/myisam/mi_check.c @@ -2561,8 +2561,9 @@ err: VOID(my_close(new_file,MYF(0))); VOID(my_raid_delete(param->temp_filename,share->base.raid_chunks, MYF(MY_WME))); - if (info->dfile == new_file) - info->dfile= -1; + if (info->dfile == new_file) /* Retry with key cache */ + if (unlikely(mi_open_datafile(info, share, name, -1))) + param->retry_repair= 0; /* Safety */ } mi_mark_crashed_on_repair(info); } @@ -3095,8 +3096,9 @@ err: VOID(my_close(new_file,MYF(0))); VOID(my_raid_delete(param->temp_filename,share->base.raid_chunks, MYF(MY_WME))); - if (info->dfile == new_file) - info->dfile= -1; + if (info->dfile == new_file) /* Retry with key cache */ + if (unlikely(mi_open_datafile(info, share, name, -1))) + param->retry_repair= 0; /* Safety */ } mi_mark_crashed_on_repair(info); } diff --git a/storage/myisam/sort.c b/storage/myisam/sort.c index f31edbe1249..fb16af9cddf 100644 --- a/storage/myisam/sort.c +++ b/storage/myisam/sort.c @@ -788,7 +788,11 @@ static int NEAR_F merge_many_buff(MI_SORT_PARAM *info, uint keys, cleanup: close_cached_file(to_file); /* This holds old result */ if (to_file == t_file) + { *t_file=t_file2; /* Copy result file */ + t_file->current_pos= &t_file->write_pos; + t_file->current_end= &t_file->write_end; + } DBUG_RETURN(*maxbuffer >= MERGEBUFF2); /* Return 1 if interrupted */ } /* merge_many_buff */ diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c index 7de00025eda..4f3aaa6f668 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -185,8 +185,8 @@ int my_strnncollsp_simple(CHARSET_INFO * cs, const uchar *a, size_t a_length, } for (end= a + a_length-length; a < end ; a++) { - if (map[*a] != ' ') - return (map[*a] < ' ') ? -swap : swap; + if (map[*a] != map[' ']) + return (map[*a] < map[' ']) ? -swap : swap; } } return res;