diff options
-rw-r--r-- | mysql-test/r/ctype_utf8.result | 46 | ||||
-rw-r--r-- | mysql-test/r/func_gconcat.result | 15 | ||||
-rw-r--r-- | mysql-test/r/having.result | 2 | ||||
-rw-r--r-- | mysql-test/r/select.result | 19 | ||||
-rw-r--r-- | mysql-test/r/subselect.result | 2 | ||||
-rw-r--r-- | mysql-test/r/varbinary.result | 2 | ||||
-rw-r--r-- | mysql-test/t/ctype_utf8.test | 34 | ||||
-rw-r--r-- | mysql-test/t/func_gconcat.test | 8 | ||||
-rw-r--r-- | mysql-test/t/select.test | 23 | ||||
-rw-r--r-- | sql/ha_heap.cc | 2 | ||||
-rw-r--r-- | sql/item.cc | 2 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 37 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 1 | ||||
-rw-r--r-- | sql/item_sum.cc | 7 | ||||
-rw-r--r-- | sql/item_sum.h | 7 | ||||
-rw-r--r-- | sql/mysql_priv.h | 1 | ||||
-rw-r--r-- | sql/sql_class.h | 3 | ||||
-rw-r--r-- | sql/sql_select.cc | 95 | ||||
-rw-r--r-- | sql/sql_table.cc | 2 | ||||
-rw-r--r-- | storage/myisam/mi_search.c | 11 |
20 files changed, 287 insertions, 32 deletions
diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index fe4dc9f1a66..44f6945238c 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -1066,6 +1066,52 @@ LENGTH(bug) 100 DROP TABLE t2; DROP TABLE t1; +SET NAMES utf8; +DROP TABLE IF EXISTS t1; +Warnings: +Note 1051 Unknown table 't1' +CREATE TABLE t1(a VARCHAR(255), KEY(a)) ENGINE=MyISAM DEFAULT CHARSET=utf8; +INSERT INTO t1 VALUES('uuABCDEFGHIGKLMNOPRSTUVWXYZ̈bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'); +INSERT INTO t1 VALUES('uu'); +check table t1; +Table Op Msg_type Msg_text +test.t1 check status OK +INSERT INTO t1 VALUES('uU'); +check table t1; +Table Op Msg_type Msg_text +test.t1 check status OK +INSERT INTO t1 VALUES('uu'); +check table t1; +Table Op Msg_type Msg_text +test.t1 check status OK +INSERT INTO t1 VALUES('uuABC'); +check table t1; +Table Op Msg_type Msg_text +test.t1 check status OK +INSERT INTO t1 VALUES('UuABC'); +check table t1; +Table Op Msg_type Msg_text +test.t1 check status OK +INSERT INTO t1 VALUES('uuABC'); +check table t1; +Table Op Msg_type Msg_text +test.t1 check status OK +alter table t1 add b int; +INSERT INTO t1 VALUES('uuABCDEFGHIGKLMNOPRSTUVWXYZ̈bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',1); +INSERT INTO t1 VALUES('uuABCDEFGHIGKLMNOPRSTUVWXYZ̈bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',2); +delete from t1 where b=1; +INSERT INTO t1 VALUES('UUABCDEFGHIGKLMNOPRSTUVWXYZ̈bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',1); +check table t1; +Table Op Msg_type Msg_text +test.t1 check status OK +INSERT INTO t1 VALUES('uuABCDEFGHIGKLMNOPRSTUVWXYZ̈bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',3); +INSERT INTO t1 VALUES('uuABCDEFGHIGKLMNOPRSTUVWXYZ̈bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',4); +delete from t1 where b=3; +INSERT INTO t1 VALUES('uUABCDEFGHIGKLMNOPRSTUVWXYZ̈bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',3); +check table t1; +Table Op Msg_type Msg_text +test.t1 check status OK +drop table t1; CREATE TABLE t1(id varchar(20) NOT NULL) DEFAULT CHARSET=utf8; INSERT INTO t1 VALUES ('xxx'), ('aa'), ('yyy'), ('aa'); SELECT id FROM t1; diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index 33ec9d0cfcf..b0a6d91ee40 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -596,6 +596,21 @@ GROUP_CONCAT(a ORDER BY a) ,x ,z DROP TABLE t1; +create table t1(f1 int); +insert into t1 values(1),(2),(3); +select f1, group_concat(f1+1) from t1 group by f1 with rollup; +f1 group_concat(f1+1) +1 2 +2 3 +3 4 +NULL 2,3,4 +select count(distinct (f1+1)) from t1 group by f1 with rollup; +count(distinct (f1+1)) +1 +1 +1 +3 +drop table t1; set names latin1; create table t1 (a char, b char); insert into t1 values ('a', 'a'), ('a', 'b'), ('b', 'a'), ('b', 'b'); diff --git a/mysql-test/r/having.result b/mysql-test/r/having.result index e54f6d7f2a4..225d5a475ff 100644 --- a/mysql-test/r/having.result +++ b/mysql-test/r/having.result @@ -12,7 +12,7 @@ explain extended select count(a) as b from t1 where a=0 having b >=0; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables Warnings: -Note 1003 select count(`test`.`t1`.`a`) AS `b` from `test`.`t1` where (`test`.`t1`.`a` = 0) having (count(`test`.`t1`.`a`) >= 0) +Note 1003 select count(`test`.`t1`.`a`) AS `b` from `test`.`t1` where 0 having (count(`test`.`t1`.`a`) >= 0) drop table t1; CREATE TABLE t1 ( raw_id int(10) NOT NULL default '0', diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index df68cdfff53..9b9f67efeb5 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -3371,3 +3371,22 @@ NULL a NULL drop table t1,t2; select * from (select * left join t on f1=f2) tt; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'on f1=f2) tt' at line 1 +CREATE TABLE t1 (sku int PRIMARY KEY, pr int); +CREATE TABLE t2 (sku int PRIMARY KEY, sppr int, name varchar(255)); +INSERT INTO t1 VALUES +(10, 10), (20, 10), (30, 20), (40, 30), (50, 10), (60, 10); +INSERT INTO t2 VALUES +(10, 10, 'aaa'), (20, 10, 'bbb'), (30, 10, 'ccc'), (40, 20, 'ddd'), +(50, 10, 'eee'), (60, 20, 'fff'), (70, 20, 'ggg'), (80, 30, 'hhh'); +SELECT t2.sku, t2.sppr, t2.name, t1.sku, t1.pr +FROM t2, t1 WHERE t2.sku=20 AND (t2.sku=t1.sku OR t2.sppr=t1.sku); +sku sppr name sku pr +20 10 bbb 10 10 +20 10 bbb 20 10 +EXPLAIN +SELECT t2.sku, t2.sppr, t2.name, t1.sku, t1.pr +FROM t2, t1 WHERE t2.sku=20 AND (t2.sku=t1.sku OR t2.sppr=t1.sku); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where +DROP TABLE t1,t2; diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 5f7d58f959b..37823c66de9 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -547,7 +547,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 Using index 2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away Warnings: -Note 1003 select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numreponse` = (select max(`test`.`t1`.`numreponse`) AS `MAX(numreponse)` from `test`.`t1` where (`test`.`t1`.`numeropost` = _latin1'1'))) and (`test`.`t1`.`numeropost` = _latin1'1')) +Note 1003 select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numeropost` = _latin1'1')) drop table t1; CREATE TABLE t1 (a int(1)); INSERT INTO t1 VALUES (1); diff --git a/mysql-test/r/varbinary.result b/mysql-test/r/varbinary.result index e55e6b35915..e62051df5cd 100644 --- a/mysql-test/r/varbinary.result +++ b/mysql-test/r/varbinary.result @@ -15,7 +15,7 @@ explain extended select * from t1 where UNIQ=0x38afba1d73e6a18a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 const UNIQ UNIQ 8 const 1 Warnings: -Note 1003 select `test`.`t1`.`ID` AS `ID`,`test`.`t1`.`UNIQ` AS `UNIQ` from `test`.`t1` where (`test`.`t1`.`UNIQ` = 4084688022709641610) +Note 1003 select `test`.`t1`.`ID` AS `ID`,`test`.`t1`.`UNIQ` AS `UNIQ` from `test`.`t1` where 1 drop table t1; select x'hello'; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'x'hello'' at line 1 diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index c9b2b9fc18f..5ca1f58d233 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -878,6 +878,40 @@ SELECT LENGTH(bug) FROM t2; DROP TABLE t2; DROP TABLE t1; +# +# Bug#17705: Corruption of compressed index when index length changes between +# 254 and 256 +# + +SET NAMES utf8; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1(a VARCHAR(255), KEY(a)) ENGINE=MyISAM DEFAULT CHARSET=utf8; +INSERT INTO t1 VALUES('uuABCDEFGHIGKLMNOPRSTUVWXYZ̈bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'); +INSERT INTO t1 VALUES('uu'); +check table t1; +INSERT INTO t1 VALUES('uU'); +check table t1; +INSERT INTO t1 VALUES('uu'); +check table t1; +INSERT INTO t1 VALUES('uuABC'); +check table t1; +INSERT INTO t1 VALUES('UuABC'); +check table t1; +INSERT INTO t1 VALUES('uuABC'); +check table t1; +alter table t1 add b int; +INSERT INTO t1 VALUES('uuABCDEFGHIGKLMNOPRSTUVWXYZ̈bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',1); +INSERT INTO t1 VALUES('uuABCDEFGHIGKLMNOPRSTUVWXYZ̈bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',2); +delete from t1 where b=1; +INSERT INTO t1 VALUES('UUABCDEFGHIGKLMNOPRSTUVWXYZ̈bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',1); +check table t1; +INSERT INTO t1 VALUES('uuABCDEFGHIGKLMNOPRSTUVWXYZ̈bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',3); +INSERT INTO t1 VALUES('uuABCDEFGHIGKLMNOPRSTUVWXYZ̈bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',4); +delete from t1 where b=3; +INSERT INTO t1 VALUES('uUABCDEFGHIGKLMNOPRSTUVWXYZ̈bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',3); +check table t1; +drop table t1; + # End of 4.1 tests # diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test index 058df9af56b..1b88ed90fa3 100644 --- a/mysql-test/t/func_gconcat.test +++ b/mysql-test/t/func_gconcat.test @@ -389,6 +389,14 @@ SELECT GROUP_CONCAT(a ORDER BY a) FROM t1 GROUP BY id; DROP TABLE t1; +# +# Bug #15560: GROUP_CONCAT wasn't ready for WITH ROLLUP queries +# +create table t1(f1 int); +insert into t1 values(1),(2),(3); +select f1, group_concat(f1+1) from t1 group by f1 with rollup; +select count(distinct (f1+1)) from t1 group by f1 with rollup; +drop table t1; # End of 4.1 tests # diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index 01d5f2eb4d1..c4fe1906cbc 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -2848,3 +2848,26 @@ drop table t1,t2; # --error 1064 select * from (select * left join t on f1=f2) tt; + +# +# Bug #16504: re-evaluation of Item_equal object after reading const table +# + +CREATE TABLE t1 (sku int PRIMARY KEY, pr int); +CREATE TABLE t2 (sku int PRIMARY KEY, sppr int, name varchar(255)); + +INSERT INTO t1 VALUES + (10, 10), (20, 10), (30, 20), (40, 30), (50, 10), (60, 10); + +INSERT INTO t2 VALUES + (10, 10, 'aaa'), (20, 10, 'bbb'), (30, 10, 'ccc'), (40, 20, 'ddd'), + (50, 10, 'eee'), (60, 20, 'fff'), (70, 20, 'ggg'), (80, 30, 'hhh'); + +SELECT t2.sku, t2.sppr, t2.name, t1.sku, t1.pr + FROM t2, t1 WHERE t2.sku=20 AND (t2.sku=t1.sku OR t2.sppr=t1.sku); +EXPLAIN +SELECT t2.sku, t2.sppr, t2.name, t1.sku, t1.pr + FROM t2, t1 WHERE t2.sku=20 AND (t2.sku=t1.sku OR t2.sppr=t1.sku); + + +DROP TABLE t1,t2; diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index fc5cf8bbd2c..f20dfe259fb 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -561,7 +561,7 @@ ha_rows ha_heap::records_in_range(uint inx, key_range *min_key, return records; /* Assert that info() did run. We need current statistics here. */ - DBUG_ASSERT(key_stat_version); + DBUG_ASSERT(key_stat_version == file->s->key_stat_version); return key->rec_per_key[key->key_parts-1]; } diff --git a/sql/item.cc b/sql/item.cc index 37fde11ad7f..885617669a9 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -3756,7 +3756,7 @@ Item *Item_field::replace_equal_field(byte *arg) if (item_equal) { Item_field *subst= item_equal->get_first(); - if (!field->eq(subst->field)) + if (subst && !field->eq(subst->field)) return subst; } return this; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index e2ea592403e..62533d12090 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -3602,7 +3602,8 @@ void Item_equal::add(Item *c) Item_func_eq *func= new Item_func_eq(c, const_item); func->set_cmp_func(); func->quick_fix_field(); - cond_false = !(func->val_int()); + if ((cond_false= !func->val_int())) + const_item_cache= 1; } void Item_equal::add(Item_field *f) @@ -3734,13 +3735,45 @@ void Item_equal::sort(Item_field_cmpfunc cmp, void *arg) } while (swap); } + +/* + Check appearance of new constant items in the multiple equality object + + SYNOPSIS + check() + + DESCRIPTION + The function checks appearance of new constant items among + the members of multiple equalities. Each new constant item is + compared with the designated constant item if there is any in the + multiple equality. If there is none the first new constant item + becomes designated. + + RETURN VALUES + none +*/ + +void Item_equal::check_const() +{ + List_iterator<Item_field> it(fields); + Item *item; + while ((item= it++)) + { + if (item->const_item()) + { + it.remove(); + add(item); + } + } +} + bool Item_equal::fix_fields(THD *thd, Item **ref) { List_iterator_fast<Item_field> li(fields); Item *item; not_null_tables_cache= used_tables_cache= 0; const_item_cache= 0; - while ((item=li++)) + while ((item= li++)) { table_map tmp_table_map; used_tables_cache|= item->used_tables(); diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 89aafa5721e..3d94832412e 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -1196,6 +1196,7 @@ public: bool contains(Field *field); Item_field* get_first() { return fields.head(); } void merge(Item_equal *item); + void check_const(); enum Functype functype() const { return MULT_EQUAL_FUNC; } longlong val_int(); const char *func_name() const { return "multiple equal"; } diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 1ff82af1e2d..f28f8b668e2 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -2495,6 +2495,7 @@ void Item_sum_count_distinct::make_unique() { table=0; original= 0; + force_copy_fields= 1; tree= 0; tmp_table_param= 0; always_null= FALSE; @@ -2538,6 +2539,7 @@ bool Item_sum_count_distinct::setup(THD *thd) if (always_null) return FALSE; count_field_types(tmp_table_param,list,0); + tmp_table_param->force_copy_fields= force_copy_fields; DBUG_ASSERT(table == 0); if (!(table= create_tmp_table(thd, tmp_table_param, list, (ORDER*) 0, 1, 0, @@ -3052,7 +3054,7 @@ Item_func_group_concat(Name_resolution_context *context_arg, count_cut_values(0), distinct(distinct_arg), warning_for_row(FALSE), - original(0) + force_copy_fields(0), original(0) { Item *item_select; Item **arg_ptr; @@ -3109,6 +3111,7 @@ Item_func_group_concat::Item_func_group_concat(THD *thd, distinct(item->distinct), warning_for_row(item->warning_for_row), always_null(item->always_null), + force_copy_fields(item->force_copy_fields), original(item) { quick_group= item->quick_group; @@ -3310,6 +3313,7 @@ bool Item_func_group_concat::setup(THD *thd) DBUG_RETURN(TRUE); count_field_types(tmp_table_param,all_fields,0); + tmp_table_param->force_copy_fields= force_copy_fields; DBUG_ASSERT(table == 0); /* We have to create a temporary table to get descriptions of fields @@ -3372,6 +3376,7 @@ void Item_func_group_concat::make_unique() tmp_table_param= 0; table=0; original= 0; + force_copy_fields= 1; tree= 0; } diff --git a/sql/item_sum.h b/sql/item_sum.h index a38530a502c..328f8dd8400 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -501,6 +501,7 @@ class Item_sum_count_distinct :public Item_sum_int TABLE *table; uint32 *field_lengths; TMP_TABLE_PARAM *tmp_table_param; + bool force_copy_fields; /* If there are no blobs, we can use a tree, which is faster than heap table. In that case, we still use the table @@ -524,13 +525,14 @@ class Item_sum_count_distinct :public Item_sum_int public: Item_sum_count_distinct(List<Item> &list) :Item_sum_int(list), table(0), field_lengths(0), tmp_table_param(0), - tree(0), original(0), always_null(FALSE) + force_copy_fields(0), tree(0), original(0), always_null(FALSE) { quick_group= 0; } Item_sum_count_distinct(THD *thd, Item_sum_count_distinct *item) :Item_sum_int(thd, item), table(item->table), field_lengths(item->field_lengths), tmp_table_param(item->tmp_table_param), - tree(item->tree), original(item), tree_key_length(item->tree_key_length), + force_copy_fields(0), tree(item->tree), original(item), + tree_key_length(item->tree_key_length), always_null(item->always_null) {} ~Item_sum_count_distinct(); @@ -1086,6 +1088,7 @@ class Item_func_group_concat : public Item_sum bool distinct; bool warning_for_row; bool always_null; + bool force_copy_fields; bool no_appended; /* Following is 0 normal object and pointer to original one for copy diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index f79472a54f8..85b96d7e690 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -756,6 +756,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, Item ***copy_func, Field **from_field, bool group, bool modify_item, bool table_cant_handle_bit_fields, + bool make_copy_field, uint convert_blob_length); void sp_prepare_create_field(THD *thd, create_field *sql_field); int prepare_create_field(create_field *sql_field, diff --git a/sql/sql_class.h b/sql/sql_class.h index cc1c5488ae5..60ff558ac48 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1656,11 +1656,12 @@ public: aggregate functions as normal functions. */ bool precomputed_group_by; + bool force_copy_fields; TMP_TABLE_PARAM() :copy_field(0), group_parts(0), group_length(0), group_null_parts(0), convert_blob_length(0), - schema_table(0), precomputed_group_by(0) + schema_table(0), precomputed_group_by(0), force_copy_fields(0) {} ~TMP_TABLE_PARAM() { diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 524f9c7b09b..76bb7f088b5 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -136,7 +136,7 @@ static enum_nested_loop_state end_write_group(JOIN *join, JOIN_TAB *join_tab, bool end_of_records); static int test_if_group_changed(List<Cached_item> &list); -static int join_read_const_table(JOIN_TAB *tab, POSITION *pos); +static int join_read_const_table(JOIN *join, JOIN_TAB *tab, POSITION *pos); static int join_read_system(JOIN_TAB *tab); static int join_read_const(JOIN_TAB *tab); static int join_read_key(JOIN_TAB *tab); @@ -2153,7 +2153,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, s= p_pos->table; s->type=JT_SYSTEM; join->const_table_map|=s->table->map; - if ((tmp=join_read_const_table(s, p_pos))) + if ((tmp=join_read_const_table(join, s, p_pos))) { if (tmp > 0) DBUG_RETURN(1); // Fatal error @@ -2190,7 +2190,8 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, s->type=JT_SYSTEM; join->const_table_map|=table->map; set_position(join,const_count++,s,(KEYUSE*) 0); - if ((tmp= join_read_const_table(s,join->positions+const_count-1))) + if ((tmp= join_read_const_table(join, s, + join->positions+const_count-1))) { if (tmp > 0) DBUG_RETURN(1); // Fatal error @@ -2242,7 +2243,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, if (create_ref_for_key(join, s, start_keyuse, found_const_table_map)) DBUG_RETURN(1); - if ((tmp=join_read_const_table(s, + if ((tmp=join_read_const_table(join, s, join->positions+const_count-1))) { if (tmp > 0) @@ -6844,8 +6845,8 @@ static COND *build_equal_items_for_cond(COND *cond, return item_equal; } /* - For each field reference in cond, not from equalitym predicates, - set a pointer to the multiple equality if belongs to (if there is any) + For each field reference in cond, not from equal item predicates, + set a pointer to the multiple equality it belongs to (if there is any) */ cond= cond->transform(&Item::equal_fields_propagator, (byte *) inherited); @@ -7030,7 +7031,7 @@ static int compare_fields_by_table_order(Item_field *field1, NOTES Before generating an equality function checks that it has not - been generated for multiple equalies of the upper levels. + been generated for multiple equalities of the upper levels. E.g. for the following where condition WHERE a=5 AND ((a=b AND b=c) OR c>4) the upper level AND condition will contain =(5,a), @@ -7203,7 +7204,7 @@ static COND* substitute_for_best_equal_field(COND *cond, { cond= eliminate_item_equal(cond, cond_equal->upper_levels, item_equal); // This occurs when eliminate_item_equal() founds that cond is - // always false and substitues it with Item_int 0. + // always false and substitutes it with Item_int 0. // Due to this, value of item_equal will be 0, so just return it. if (cond->type() != Item::COND_ITEM) break; @@ -7225,6 +7226,45 @@ static COND* substitute_for_best_equal_field(COND *cond, } +/* + Check appearance of new constant items in multiple equalities + of a condition after reading a constant table + + SYNOPSIS + check_const_equal_item() + cond condition whose multiple equalities are to be checked + table constant table that has been read + + DESCRIPTION + The function retrieves the cond condition and for each encountered + multiple equality checks whether new constants have appeared after + reading the constant (single row) table tab. If so it adjusts + the multiple equality appropriately. +*/ + +static void check_const_equal_items(COND *cond, + JOIN_TAB *tab) +{ + if (!(cond->used_tables() & tab->table->map)) + return; + + if (cond->type() == Item::COND_ITEM) + { + List<Item> *cond_list= ((Item_cond*) cond)->argument_list(); + List_iterator_fast<Item> li(*cond_list); + Item *item; + while ((item= li++)) + check_const_equal_items(item, tab); + } + else if (cond->type() == Item::FUNC_ITEM && + ((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC) + { + Item_equal *item_equal= (Item_equal *) cond; + item_equal->check_const(); + } +} + + /* change field = field to field = const for each found field = const in the and_level @@ -8355,6 +8395,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, Item ***copy_func, Field **from_field, bool group, bool modify_item, bool table_cant_handle_bit_fields, + bool make_copy_field, uint convert_blob_length) { Item::Type orig_type= type; @@ -8436,7 +8477,13 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, case Item::REF_ITEM: case Item::NULL_ITEM: case Item::VARBIN_ITEM: - return create_tmp_field_from_item(thd, item, table, copy_func, modify_item, + if (make_copy_field) + { + DBUG_ASSERT(((Item_result_field*)item)->result_field); + *from_field= ((Item_result_field*)item)->result_field; + } + return create_tmp_field_from_item(thd, item, table, (make_copy_field ? 0 : + copy_func), modify_item, convert_blob_length); case Item::TYPE_HOLDER: return ((Item_type_holder *)item)->make_field_by_type(table); @@ -8509,6 +8556,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, Item **copy_func; MI_COLUMNDEF *recinfo; uint total_uneven_bit_length= 0; + bool force_copy_fields= param->force_copy_fields; DBUG_ENTER("create_tmp_table"); DBUG_PRINT("enter",("distinct: %d save_sum_fields: %d rows_limit: %lu group: %d", (int) distinct, (int) save_sum_fields, @@ -8668,7 +8716,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, Field *new_field= create_tmp_field(thd, table, arg, arg->type(), ©_func, tmp_from_field, group != 0,not_all_columns, - distinct, + distinct, 0, param->convert_blob_length); if (!new_field) goto err; // Should be OOM @@ -8725,8 +8773,9 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, create_tmp_field_for_schema(thd, item, table) : create_tmp_field(thd, table, item, type, ©_func, tmp_from_field, group != 0, - not_all_columns || group != 0, - item->marker == 4, + !force_copy_fields && + (not_all_columns || group !=0), + item->marker == 4, force_copy_fields, param->convert_blob_length); if (!new_field) @@ -10163,7 +10212,7 @@ int safe_index_read(JOIN_TAB *tab) static int -join_read_const_table(JOIN_TAB *tab, POSITION *pos) +join_read_const_table(JOIN *join, JOIN_TAB *tab, POSITION *pos) { int error; DBUG_ENTER("join_read_const_table"); @@ -10215,6 +10264,26 @@ join_read_const_table(JOIN_TAB *tab, POSITION *pos) } if (!table->null_row) table->maybe_null=0; + + /* Check appearance of new constant items in Item_equal objects */ + if (join->conds) + check_const_equal_items(join->conds, tab); + TABLE_LIST *tbl; + for (tbl= join->select_lex->leaf_tables; tbl; tbl= tbl->next_leaf) + { + TABLE_LIST *embedded; + TABLE_LIST *embedding= tbl; + do + { + embedded= embedding; + if (embedded->on_expr) + check_const_equal_items(embedded->on_expr, tab); + embedding= embedded->embedding; + } + while (embedding && + embedding->nested_join->join_list.head() == embedded); + } + DBUG_RETURN(0); } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 633558de914..ed875d321bc 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2464,7 +2464,7 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, field=item->tmp_table_field(&tmp_table); else field=create_tmp_field(thd, &tmp_table, item, item->type(), - (Item ***) 0, &tmp_field, 0, 0, 0, 0); + (Item ***) 0, &tmp_field, 0, 0, 0, 0, 0); if (!field || !(cr_field=new create_field(field,(item->type() == Item::FIELD_ITEM ? ((Item_field *)item)->field : diff --git a/storage/myisam/mi_search.c b/storage/myisam/mi_search.c index a6c2cbd6082..05f8459a4b4 100644 --- a/storage/myisam/mi_search.c +++ b/storage/myisam/mi_search.c @@ -1471,7 +1471,7 @@ _mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key, if (!*key++) { s_temp->key=key; - s_temp->ref_length=s_temp->key_length=0; + s_temp->key_length= 0; s_temp->totlength=key_length-1+diff_flag; s_temp->next_key_pos=0; /* No next key */ return (s_temp->totlength); @@ -1626,12 +1626,12 @@ _mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key, s_temp->prev_length= org_key_length; s_temp->n_ref_length=s_temp->n_length= org_key_length; length+= org_key_length; - /* +get_pack_length(org_key_length); */ } return (int) length; } ref_length=n_length; + /* Get information about not packed key suffix */ get_key_pack_length(n_length,next_length_pack,next_key); /* Test if new keys has fewer characters that match the previous key */ @@ -1640,7 +1640,6 @@ _mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key, s_temp->part_of_prev_key= 0; s_temp->prev_length= ref_length; s_temp->n_ref_length= s_temp->n_length= n_length+ref_length; - /* s_temp->prev_key+= get_pack_length(org_key_length); */ return (int) length+ref_length-next_length_pack; } if (ref_length+pack_marker > new_ref_length) @@ -1651,9 +1650,7 @@ _mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key, s_temp->prev_length= ref_length - new_pack_length; s_temp->n_ref_length=s_temp->n_length=n_length + s_temp->prev_length; s_temp->prev_key+= new_pack_length; -/* +get_pack_length(org_key_length); */ - length= length-get_pack_length(ref_length)+ - get_pack_length(new_pack_length); + length-= (next_length_pack - get_pack_length(s_temp->n_length)); return (int) length + s_temp->prev_length; } } @@ -1662,7 +1659,7 @@ _mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint nod_flag,uchar *next_key, /* Next key wasn't a prefix of previous key */ ref_length=0; next_length_pack=0; - } + } DBUG_PRINT("test",("length: %d next_key: %lx", length, (long) next_key)); |