diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index 4033996b239f4e2f9c4d6cf46193c7d4a547d22a..006b507d409eac29aa5e52c76481a74c7de7b892 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -611,3 +611,35 @@ a b 5 2 6 2 drop table t1; +create table t1 (a int not null auto_increment, b int not null, c int not null, d int not null, +key(a,b,d), key(c,b,a)); +create table t2 like t1; +insert into t1 values (NULL, 1, 2, 0), (NULL, 2, 1, 1), (NULL, 3, 4, 2), (NULL, 4, 3, 3); +insert into t2 select null, b, c, d from t1; +insert into t1 select null, b, c, d from t2; +insert into t2 select null, b, c, d from t1; +insert into t1 select null, b, c, d from t2; +insert into t2 select null, b, c, d from t1; +insert into t1 select null, b, c, d from t2; +insert into t2 select null, b, c, d from t1; +insert into t1 select null, b, c, d from t2; +insert into t2 select null, b, c, d from t1; +insert into t1 select null, b, c, d from t2; +optimize table t1; +Table Op Msg_type Msg_text +test.t1 optimize status OK +set @row=10; +insert into t1 select 1, b, c + (@row:=@row - 1) * 10, d - @row from t2 limit 10; +select * from t1 where a=1 and b in (1) order by c, b, a; +a b c d +1 1 2 0 +1 1 12 -1 +1 1 52 -5 +1 1 92 -9 +select * from t1 where a=1 and b in (1); +a b c d +1 1 92 -9 +1 1 52 -5 +1 1 12 -1 +1 1 2 0 +drop table t1, t2; diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 1bfd74f01edf94e79bdf4167958a2d9066dd4c96..9650b7bb591689d6fbe2a37d1df70b0c8b817b45 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -1624,6 +1624,14 @@ select 2 in (select * from t1); 1 SET SQL_SELECT_LIMIT=default; drop table t1; +CREATE TABLE t1 (a int, b int, INDEX (a)); +INSERT INTO t1 VALUES (1, 1), (1, 2), (1, 3); +SELECT * FROM t1 WHERE a = (SELECT MAX(a) FROM t1 WHERE a = 1) ORDER BY b; +a b +1 1 +1 2 +1 3 +DROP TABLE t1; create table t1(val varchar(10)); insert into t1 values ('aaa'), ('bbb'),('eee'),('mmm'),('ppp'); select count(*) from t1 as w1 where w1.val in (select w2.val from t1 as w2 where w2.val like 'm%') and w1.val in (select w3.val from t1 as w3 where w3.val like 'e%'); diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test index bbb0046b47ff6650302ba0e7aa0bfeb59a815cb3..2cd8dbbb95aad35df5bdc9e0105d2b44ad9b526d 100644 --- a/mysql-test/t/order_by.test +++ b/mysql-test/t/order_by.test @@ -393,3 +393,28 @@ select * from t1 where b=1 or b is null order by a; explain select * from t1 where b=2 or b is null order by a; select * from t1 where b=2 or b is null order by a; drop table t1; + +# +# Bug #3155 +# + +create table t1 (a int not null auto_increment, b int not null, c int not null, d int not null, +key(a,b,d), key(c,b,a)); +create table t2 like t1; +insert into t1 values (NULL, 1, 2, 0), (NULL, 2, 1, 1), (NULL, 3, 4, 2), (NULL, 4, 3, 3); +insert into t2 select null, b, c, d from t1; +insert into t1 select null, b, c, d from t2; +insert into t2 select null, b, c, d from t1; +insert into t1 select null, b, c, d from t2; +insert into t2 select null, b, c, d from t1; +insert into t1 select null, b, c, d from t2; +insert into t2 select null, b, c, d from t1; +insert into t1 select null, b, c, d from t2; +insert into t2 select null, b, c, d from t1; +insert into t1 select null, b, c, d from t2; +optimize table t1; +set @row=10; +insert into t1 select 1, b, c + (@row:=@row - 1) * 10, d - @row from t2 limit 10; +select * from t1 where a=1 and b in (1) order by c, b, a; +select * from t1 where a=1 and b in (1); +drop table t1, t2; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 6d766f8f8f8feb48b71ef351be92cdae745ecf1b..8da67f84c8686d2e844bf9afac3ecdcaa82611af 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -1067,6 +1067,14 @@ SET SQL_SELECT_LIMIT=default; drop table t1; # +# Bug #3118: subselect + order by +# + +CREATE TABLE t1 (a int, b int, INDEX (a)); +INSERT INTO t1 VALUES (1, 1), (1, 2), (1, 3); +SELECT * FROM t1 WHERE a = (SELECT MAX(a) FROM t1 WHERE a = 1) ORDER BY b; +DROP TABLE t1; + # Item_cond fix field # create table t1(val varchar(10)); diff --git a/sql/item.h b/sql/item.h index 832fc77501657efe3cd028b3e7e16d0e3a56dfd0..984c4d0c7f52b929b9499f7baaa4dc739f01a1f2 100644 --- a/sql/item.h +++ b/sql/item.h @@ -422,18 +422,14 @@ class Item_uint :public Item_int { public: Item_uint(const char *str_arg, uint length) : - Item_int(str_arg, (longlong) strtoull(str_arg,(char**) 0,10), length) {} - Item_uint(uint32 i) :Item_int((longlong) i, 10) {} + Item_int(str_arg, (longlong) strtoull(str_arg,(char**) 0,10), length) + { unsigned_flag= 1; } + Item_uint(uint32 i) :Item_int((longlong) i, 10) + { unsigned_flag= 1; } double val() { return ulonglong2double((ulonglong)value); } String *val_str(String*); Item *new_item() { return new Item_uint(name,max_length); } int save_in_field(Field *field, bool no_conversions); - bool fix_fields(THD *thd, struct st_table_list *list, Item **item) - { - bool res= Item::fix_fields(thd, list, item); - unsigned_flag= 1; - return res; - } void print(String *str); }; diff --git a/sql/item_func.cc b/sql/item_func.cc index e365398127aa4182c87fb8ef68517a6afe96b9c4..2d98a7b8391d337392c26b5850e9e7eabb0b1b32 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -215,7 +215,8 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { Item *item; /* We can't yet set item to *arg as fix_fields may change *arg */ - if ((*arg)->fix_fields(thd, tables, arg) || + /* We shouldn't call fix_fields() twice, so check 'fixed' field first */ + if ((!(*arg)->fixed && (*arg)->fix_fields(thd, tables, arg)) || (*arg)->check_cols(allowed_arg_cols)) return 1; /* purecov: inspected */ item= *arg; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index e49aff6d82ccc090898aa8064622fd1bbbf7a3d5..13efad05eb91de964a3452bf32ee847c75792deb 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3451,6 +3451,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) tab->type=JT_ALL; use_quick_range=1; tab->use_quick=1; + tab->ref.key= -1; tab->ref.key_parts=0; // Don't use ref key. join->best_positions[i].records_read= rows2double(tab->quick->records); } @@ -7023,7 +7024,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, ref_key= -1; /* Test if constant range in WHERE */ - if (tab->ref.key >= 0) + if (tab->ref.key >= 0 && tab->ref.key_parts) { ref_key= tab->ref.key; ref_key_parts= tab->ref.key_parts;