diff --git a/mysql-test/include/mix1.inc b/mysql-test/include/mix1.inc index e863e59fad6..591971a32a4 100644 --- a/mysql-test/include/mix1.inc +++ b/mysql-test/include/mix1.inc @@ -814,6 +814,91 @@ create table t1 (a int) engine=innodb; alter table t1 alter a set default 1; drop table t1; +# +# Bug #28591: MySQL need not sort the records in case of ORDER BY +# primary_key on InnoDB table +# + +CREATE TABLE t1 (a int, b int, PRIMARY KEY (a), KEY bkey (b)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,2),(3,2),(2,2),(4,2),(5,2),(6,2),(7,2),(8,2); +INSERT INTO t1 SELECT a + 8, 2 FROM t1; +INSERT INTO t1 SELECT a + 16, 1 FROM t1; +query_vertical EXPLAIN SELECT * FROM t1 WHERE b=2 ORDER BY a; +SELECT * FROM t1 WHERE b=2 ORDER BY a; +query_vertical EXPLAIN SELECT * FROM t1 WHERE b BETWEEN 1 AND 2 ORDER BY a; +SELECT * FROM t1 WHERE b BETWEEN 1 AND 2 ORDER BY a; +query_vertical EXPLAIN SELECT * FROM t1 WHERE b BETWEEN 1 AND 2 ORDER BY b,a; +SELECT * FROM t1 WHERE b BETWEEN 1 AND 2 ORDER BY b,a; + +CREATE TABLE t2 (a int, b int, c int, PRIMARY KEY (a), KEY bkey (b,c)) + ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,1,1),(3,1,1),(2,1,1),(4,1,1); +INSERT INTO t2 SELECT a + 4, 1, 1 FROM t2; +INSERT INTO t2 SELECT a + 8, 1, 1 FROM t2; + +query_vertical EXPLAIN SELECT * FROM t2 WHERE b=1 ORDER BY a; +SELECT * FROM t2 WHERE b=1 ORDER BY a; +query_vertical EXPLAIN SELECT * FROM t2 WHERE b=1 AND c=1 ORDER BY a; +SELECT * FROM t2 WHERE b=1 AND c=1 ORDER BY a; +query_vertical EXPLAIN SELECT * FROM t2 WHERE b=1 AND c=1 ORDER BY b,c,a; +SELECT * FROM t2 WHERE b=1 AND c=1 ORDER BY b,c,a; +query_vertical EXPLAIN SELECT * FROM t2 WHERE b=1 AND c=1 ORDER BY c,a; +SELECT * FROM t2 WHERE b=1 AND c=1 ORDER BY c,a; + +DROP TABLE t1,t2; + + +# +# Bug #29644: alter table hangs if records locked in share mode by long +# running transaction +# + +CREATE TABLE t1 (a INT, PRIMARY KEY (a)) ENGINE=InnoDB; + +INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8); +INSERT INTO t1 SELECT a + 8 FROM t1; +INSERT INTO t1 SELECT a + 16 FROM t1; + +DELIMITER |; +CREATE PROCEDURE p1 () +BEGIN + DECLARE i INT DEFAULT 50; + DECLARE cnt INT; + START TRANSACTION; + ALTER TABLE t1 ENGINE=InnoDB; + COMMIT; + START TRANSACTION; + WHILE (i > 0) DO + SET i = i - 1; + SELECT COUNT(*) INTO cnt FROM t1 LOCK IN SHARE MODE; + END WHILE; + COMMIT; +END;| + +DELIMITER ;| + +CONNECT (con1,localhost,root,,); +CONNECT (con2,localhost,root,,); + +CONNECTION con1; +SEND CALL p1(); +CONNECTION con2; +SEND CALL p1(); +CONNECTION default; +CALL p1(); + +CONNECTION con1; +REAP; +CONNECTION con2; +REAP; +CONNECTION default; +DISCONNECT con1; +DISCONNECT con2; + +DROP PROCEDURE p1; +DROP TABLE t1; + + --echo End of 5.0 tests diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index de25fb754e4..84a620336dc 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -1532,6 +1532,19 @@ create table t2(a int not null, b int not null, c int not null, primary key (a), foreign key fk_bug26104 (b,c) references t1(a)); ERROR 42000: Incorrect foreign key definition for 'fk_bug26104': Key reference and table reference don't match drop table t1; +create table t1(f1 int,f2 int); +insert into t1 value(1,1),(1,2),(1,3),(2,1),(2,2),(2,3); +flush status; +create table t2 select sql_big_result f1,count(f2) from t1 group by f1; +show status like 'handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_rnd 0 +Handler_read_rnd_next 7 +drop table t1,t2; End of 5.0 tests CREATE TABLE t1 (a int, b int); insert into t1 values (1,1),(1,2); diff --git a/mysql-test/r/having.result b/mysql-test/r/having.result index 149391396b6..a5a96fd4958 100644 --- a/mysql-test/r/having.result +++ b/mysql-test/r/having.result @@ -158,6 +158,25 @@ EXPLAIN SELECT 0 AS x, a FROM t1 GROUP BY x,a HAVING x=1 AND a > 1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible HAVING DROP table t1; +CREATE TABLE t1 (a int PRIMARY KEY); +CREATE TABLE t2 (b int PRIMARY KEY, a int); +CREATE TABLE t3 (b int, flag int); +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1,1), (2,1), (3,1); +INSERT INTO t3(b,flag) VALUES (2, 1); +SELECT t1.a +FROM t1 INNER JOIN t2 ON t1.a=t2.a LEFT JOIN t3 ON t2.b=t3.b +GROUP BY t1.a, t2.b HAVING MAX(t3.flag)=0; +a +SELECT DISTINCT t1.a, MAX(t3.flag) +FROM t1 INNER JOIN t2 ON t1.a=t2.a LEFT JOIN t3 ON t2.b=t3.b +GROUP BY t1.a, t2.b HAVING MAX(t3.flag)=0; +a MAX(t3.flag) +SELECT DISTINCT t1.a +FROM t1 INNER JOIN t2 ON t1.a=t2.a LEFT JOIN t3 ON t2.b=t3.b +GROUP BY t1.a, t2.b HAVING MAX(t3.flag)=0; +a +DROP TABLE t1,t2,t3; create table t1 (col1 int, col2 varchar(5), col_t1 int); create table t2 (col1 int, col2 varchar(5), col_t2 int); create table t3 (col1 int, col2 varchar(5), col_t3 int); diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index 3dc134352db..273374d016b 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -814,6 +814,274 @@ drop table if exists t1; create table t1 (a int) engine=innodb; alter table t1 alter a set default 1; drop table t1; +CREATE TABLE t1 (a int, b int, PRIMARY KEY (a), KEY bkey (b)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,2),(3,2),(2,2),(4,2),(5,2),(6,2),(7,2),(8,2); +INSERT INTO t1 SELECT a + 8, 2 FROM t1; +INSERT INTO t1 SELECT a + 16, 1 FROM t1; +EXPLAIN SELECT * FROM t1 WHERE b=2 ORDER BY a; +id 1 +select_type SIMPLE +table t1 +type ref +possible_keys bkey +key bkey +key_len 5 +ref const +rows 16 +Extra Using where; Using index +SELECT * FROM t1 WHERE b=2 ORDER BY a; +a b +1 2 +2 2 +3 2 +4 2 +5 2 +6 2 +7 2 +8 2 +9 2 +10 2 +11 2 +12 2 +13 2 +14 2 +15 2 +16 2 +EXPLAIN SELECT * FROM t1 WHERE b BETWEEN 1 AND 2 ORDER BY a; +id 1 +select_type SIMPLE +table t1 +type range +possible_keys bkey +key bkey +key_len 5 +ref NULL +rows 16 +Extra Using where; Using index; Using filesort +SELECT * FROM t1 WHERE b BETWEEN 1 AND 2 ORDER BY a; +a b +1 2 +2 2 +3 2 +4 2 +5 2 +6 2 +7 2 +8 2 +9 2 +10 2 +11 2 +12 2 +13 2 +14 2 +15 2 +16 2 +17 1 +18 1 +19 1 +20 1 +21 1 +22 1 +23 1 +24 1 +25 1 +26 1 +27 1 +28 1 +29 1 +30 1 +31 1 +32 1 +EXPLAIN SELECT * FROM t1 WHERE b BETWEEN 1 AND 2 ORDER BY b,a; +id 1 +select_type SIMPLE +table t1 +type range +possible_keys bkey +key bkey +key_len 5 +ref NULL +rows 16 +Extra Using where; Using index +SELECT * FROM t1 WHERE b BETWEEN 1 AND 2 ORDER BY b,a; +a b +17 1 +18 1 +19 1 +20 1 +21 1 +22 1 +23 1 +24 1 +25 1 +26 1 +27 1 +28 1 +29 1 +30 1 +31 1 +32 1 +1 2 +2 2 +3 2 +4 2 +5 2 +6 2 +7 2 +8 2 +9 2 +10 2 +11 2 +12 2 +13 2 +14 2 +15 2 +16 2 +CREATE TABLE t2 (a int, b int, c int, PRIMARY KEY (a), KEY bkey (b,c)) +ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,1,1),(3,1,1),(2,1,1),(4,1,1); +INSERT INTO t2 SELECT a + 4, 1, 1 FROM t2; +INSERT INTO t2 SELECT a + 8, 1, 1 FROM t2; +EXPLAIN SELECT * FROM t2 WHERE b=1 ORDER BY a; +id 1 +select_type SIMPLE +table t2 +type ref +possible_keys bkey +key bkey +key_len 5 +ref const +rows 8 +Extra Using where; Using index; Using filesort +SELECT * FROM t2 WHERE b=1 ORDER BY a; +a b c +1 1 1 +2 1 1 +3 1 1 +4 1 1 +5 1 1 +6 1 1 +7 1 1 +8 1 1 +9 1 1 +10 1 1 +11 1 1 +12 1 1 +13 1 1 +14 1 1 +15 1 1 +16 1 1 +EXPLAIN SELECT * FROM t2 WHERE b=1 AND c=1 ORDER BY a; +id 1 +select_type SIMPLE +table t2 +type ref +possible_keys bkey +key bkey +key_len 10 +ref const,const +rows 8 +Extra Using where; Using index +SELECT * FROM t2 WHERE b=1 AND c=1 ORDER BY a; +a b c +1 1 1 +2 1 1 +3 1 1 +4 1 1 +5 1 1 +6 1 1 +7 1 1 +8 1 1 +9 1 1 +10 1 1 +11 1 1 +12 1 1 +13 1 1 +14 1 1 +15 1 1 +16 1 1 +EXPLAIN SELECT * FROM t2 WHERE b=1 AND c=1 ORDER BY b,c,a; +id 1 +select_type SIMPLE +table t2 +type ref +possible_keys bkey +key bkey +key_len 10 +ref const,const +rows 8 +Extra Using where; Using index +SELECT * FROM t2 WHERE b=1 AND c=1 ORDER BY b,c,a; +a b c +1 1 1 +2 1 1 +3 1 1 +4 1 1 +5 1 1 +6 1 1 +7 1 1 +8 1 1 +9 1 1 +10 1 1 +11 1 1 +12 1 1 +13 1 1 +14 1 1 +15 1 1 +16 1 1 +EXPLAIN SELECT * FROM t2 WHERE b=1 AND c=1 ORDER BY c,a; +id 1 +select_type SIMPLE +table t2 +type ref +possible_keys bkey +key bkey +key_len 10 +ref const,const +rows 8 +Extra Using where; Using index +SELECT * FROM t2 WHERE b=1 AND c=1 ORDER BY c,a; +a b c +1 1 1 +2 1 1 +3 1 1 +4 1 1 +5 1 1 +6 1 1 +7 1 1 +8 1 1 +9 1 1 +10 1 1 +11 1 1 +12 1 1 +13 1 1 +14 1 1 +15 1 1 +16 1 1 +DROP TABLE t1,t2; +CREATE TABLE t1 (a INT, PRIMARY KEY (a)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8); +INSERT INTO t1 SELECT a + 8 FROM t1; +INSERT INTO t1 SELECT a + 16 FROM t1; +CREATE PROCEDURE p1 () +BEGIN +DECLARE i INT DEFAULT 50; +DECLARE cnt INT; +START TRANSACTION; +ALTER TABLE t1 ENGINE=InnoDB; +COMMIT; +START TRANSACTION; +WHILE (i > 0) DO +SET i = i - 1; +SELECT COUNT(*) INTO cnt FROM t1 LOCK IN SHARE MODE; +END WHILE; +COMMIT; +END;| +CALL p1(); +CALL p1(); +CALL p1(); +DROP PROCEDURE p1; +DROP TABLE t1; End of 5.0 tests CREATE TABLE `t2` ( `k` int(11) NOT NULL auto_increment, diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index e8c971a41bc..1fa18482b9c 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -3573,6 +3573,28 @@ SELECT * FROM v1; 1 DROP VIEW v1; # +# Bug #29788: mysqldump discards the NO_AUTO_VALUE_ON_ZERO value of +# the SQL_MODE variable after the dumping of triggers. +# +CREATE TABLE t1 (c1 INT); +CREATE TRIGGER t1bd BEFORE DELETE ON t1 FOR EACH ROW BEGIN END; +CREATE TABLE t2 (c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY); +SET @TMP_SQL_MODE = @@SQL_MODE; +SET SQL_MODE = 'NO_AUTO_VALUE_ON_ZERO'; +INSERT INTO t2 VALUES (0), (1), (2); +SET SQL_MODE = @TMP_SQL_MODE; +SELECT * FROM t2; +c1 +0 +1 +2 +SELECT * FROM t2; +c1 +0 +1 +2 +DROP TABLE t1,t2; +# # End of 5.0 tests # drop table if exists t1; diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 273c60110b3..07661f9ae54 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -1,5 +1,7 @@ use test; drop table if exists t1,t2,t3,t4; +drop function if exists f1; +drop function if exists f2; create table t1 ( id char(16) not null default '', data int not null @@ -6249,7 +6251,7 @@ drop table t1,t2; CREATE TABLE t1 (a int auto_increment primary key) engine=MyISAM; CREATE TABLE t2 (a int auto_increment primary key, b int) engine=innodb; set @a=0; -CREATE function bug27354() RETURNS int deterministic +CREATE function bug27354() RETURNS int not deterministic begin insert into t1 values (null); set @a=@a+1; @@ -6433,3 +6435,34 @@ where ROUTINE_NAME = "proc_26302"; ROUTINE_NAME ROUTINE_DEFINITION proc_26302 select 1 /* testing */ drop procedure proc_26302; +CREATE FUNCTION f1() RETURNS INT DETERMINISTIC RETURN 2; +CREATE FUNCTION f2(I INT) RETURNS INT DETERMINISTIC RETURN 3; +CREATE TABLE t1 (c1 INT, INDEX(c1)); +INSERT INTO t1 VALUES (1), (2), (3), (4), (5); +CREATE VIEW v1 AS SELECT c1 FROM t1; +EXPLAIN SELECT * FROM t1 WHERE c1=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref c1 c1 5 const 1 Using where; Using index +EXPLAIN SELECT * FROM t1 WHERE c1=f1(); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref c1 c1 5 const 1 Using where; Using index +EXPLAIN SELECT * FROM v1 WHERE c1=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref c1 c1 5 const 1 Using where; Using index +EXPLAIN SELECT * FROM v1 WHERE c1=f1(); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref c1 c1 5 const 1 Using where; Using index +EXPLAIN SELECT * FROM t1 WHERE c1=f2(10); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref c1 c1 5 const 1 Using where; Using index +EXPLAIN SELECT * FROM t1 WHERE c1=f2(c1); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL c1 5 NULL 5 Using where; Using index +EXPLAIN SELECT * FROM t1 WHERE c1=f2(rand()); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL c1 5 NULL 5 Using where; Using index +DROP VIEW v1; +DROP FUNCTION f1; +DROP FUNCTION f2; +DROP TABLE t1; +End of 5.0 tests diff --git a/mysql-test/r/type_enum.result b/mysql-test/r/type_enum.result index ec72a6eb995..051cfe61384 100644 --- a/mysql-test/r/type_enum.result +++ b/mysql-test/r/type_enum.result @@ -1829,4 +1829,28 @@ c1 + 0 0 2 DROP TABLE t1,t2; +CREATE TABLE t1(a enum('a','b','c','d')); +INSERT INTO t1 VALUES (4),(1),(0),(3); +Warnings: +Warning 1265 Data truncated for column 'a' at row 3 +SELECT a FROM t1; +a +d +a + +c +EXPLAIN SELECT a FROM t1 WHERE a=0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where +SELECT a FROM t1 WHERE a=0; +a + +ALTER TABLE t1 ADD PRIMARY KEY (a); +EXPLAIN SELECT a FROM t1 WHERE a=0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 const PRIMARY PRIMARY 1 const 1 Using index +SELECT a FROM t1 WHERE a=0; +a + +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index 8b1de227ab8..341c019af6e 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -1142,6 +1142,16 @@ create table t2(a int not null, b int not null, c int not null, primary key (a), foreign key fk_bug26104 (b,c) references t1(a)); drop table t1; +# +# Bug#15130:CREATE .. SELECT was denied to use advantages of the SQL_BIG_RESULT. +# +create table t1(f1 int,f2 int); +insert into t1 value(1,1),(1,2),(1,3),(2,1),(2,2),(2,3); +flush status; +create table t2 select sql_big_result f1,count(f2) from t1 group by f1; +show status like 'handler_read%'; +drop table t1,t2; + --echo End of 5.0 tests # diff --git a/mysql-test/t/having.test b/mysql-test/t/having.test index 41266cc6d32..683abfd3783 100644 --- a/mysql-test/t/having.test +++ b/mysql-test/t/having.test @@ -151,6 +151,32 @@ EXPLAIN SELECT 0 AS x, a FROM t1 GROUP BY x,a HAVING x=1 AND a > 1; DROP table t1; +# +# Bug #29911: HAVING clause depending on constant table and evaluated to false +# + +CREATE TABLE t1 (a int PRIMARY KEY); +CREATE TABLE t2 (b int PRIMARY KEY, a int); +CREATE TABLE t3 (b int, flag int); + +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1,1), (2,1), (3,1); +INSERT INTO t3(b,flag) VALUES (2, 1); + +SELECT t1.a + FROM t1 INNER JOIN t2 ON t1.a=t2.a LEFT JOIN t3 ON t2.b=t3.b + GROUP BY t1.a, t2.b HAVING MAX(t3.flag)=0; + +SELECT DISTINCT t1.a, MAX(t3.flag) + FROM t1 INNER JOIN t2 ON t1.a=t2.a LEFT JOIN t3 ON t2.b=t3.b + GROUP BY t1.a, t2.b HAVING MAX(t3.flag)=0; + +SELECT DISTINCT t1.a + FROM t1 INNER JOIN t2 ON t1.a=t2.a LEFT JOIN t3 ON t2.b=t3.b + GROUP BY t1.a, t2.b HAVING MAX(t3.flag)=0; + +DROP TABLE t1,t2,t3; + # End of 4.1 tests # diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 38d8a07fe48..4e8d3ae916e 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -1554,6 +1554,28 @@ DROP VIEW v1; SELECT * FROM v1; DROP VIEW v1; +--echo # +--echo # Bug #29788: mysqldump discards the NO_AUTO_VALUE_ON_ZERO value of +--echo # the SQL_MODE variable after the dumping of triggers. +--echo # + +CREATE TABLE t1 (c1 INT); +CREATE TRIGGER t1bd BEFORE DELETE ON t1 FOR EACH ROW BEGIN END; + +CREATE TABLE t2 (c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY); + +SET @TMP_SQL_MODE = @@SQL_MODE; +SET SQL_MODE = 'NO_AUTO_VALUE_ON_ZERO'; +INSERT INTO t2 VALUES (0), (1), (2); +SET SQL_MODE = @TMP_SQL_MODE; +SELECT * FROM t2; + +--exec $MYSQL_DUMP --routines test >$MYSQLTEST_VARDIR/tmp/bug29788.sql +--exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/bug29788.sql +SELECT * FROM t2; + +DROP TABLE t1,t2; + --echo # --echo # End of 5.0 tests --echo # diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 7bd20d226c2..dfda1b7a6ab 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -24,6 +24,8 @@ use test; # --disable_warnings drop table if exists t1,t2,t3,t4; +drop function if exists f1; +drop function if exists f2; --enable_warnings create table t1 ( id char(16) not null default '', @@ -7214,7 +7216,7 @@ CREATE TABLE t2 (a int auto_increment primary key, b int) engine=innodb; set @a=0; delimiter |; -CREATE function bug27354() RETURNS int deterministic +CREATE function bug27354() RETURNS int not deterministic begin insert into t1 values (null); set @a=@a+1; @@ -7368,3 +7370,33 @@ where ROUTINE_NAME = "proc_26302"; drop procedure proc_26302; +# Bug #29338: no optimization for stored functions with a trivial body +# always returning constant. +# + +CREATE FUNCTION f1() RETURNS INT DETERMINISTIC RETURN 2; +CREATE FUNCTION f2(I INT) RETURNS INT DETERMINISTIC RETURN 3; + +CREATE TABLE t1 (c1 INT, INDEX(c1)); + +INSERT INTO t1 VALUES (1), (2), (3), (4), (5); + +CREATE VIEW v1 AS SELECT c1 FROM t1; + +EXPLAIN SELECT * FROM t1 WHERE c1=1; +EXPLAIN SELECT * FROM t1 WHERE c1=f1(); + +EXPLAIN SELECT * FROM v1 WHERE c1=1; +EXPLAIN SELECT * FROM v1 WHERE c1=f1(); + +EXPLAIN SELECT * FROM t1 WHERE c1=f2(10); +EXPLAIN SELECT * FROM t1 WHERE c1=f2(c1); +EXPLAIN SELECT * FROM t1 WHERE c1=f2(rand()); + + +DROP VIEW v1; +DROP FUNCTION f1; +DROP FUNCTION f2; +DROP TABLE t1; + +--echo End of 5.0 tests diff --git a/mysql-test/t/type_enum.test b/mysql-test/t/type_enum.test index 4d5d5ec8a86..2043342e2c8 100644 --- a/mysql-test/t/type_enum.test +++ b/mysql-test/t/type_enum.test @@ -200,4 +200,24 @@ CREATE TABLE t2 SELECT * FROM t1; SELECT c1 + 0 FROM t2; DROP TABLE t1,t2; + +# +# Bug#29661: Lookup by 0 for a primary index over a enum type +# + +CREATE TABLE t1(a enum('a','b','c','d')); +INSERT INTO t1 VALUES (4),(1),(0),(3); + +SELECT a FROM t1; + +EXPLAIN SELECT a FROM t1 WHERE a=0; +SELECT a FROM t1 WHERE a=0; + +ALTER TABLE t1 ADD PRIMARY KEY (a); + +EXPLAIN SELECT a FROM t1 WHERE a=0; +SELECT a FROM t1 WHERE a=0; + +DROP TABLE t1; + --echo End of 5.1 tests diff --git a/sql-common/client.c b/sql-common/client.c index 6d63c457390..cdf9eed8574 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -1226,12 +1226,12 @@ unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields, /* fields count may be wrong */ DBUG_ASSERT((uint) (field - result) < fields); cli_fetch_lengths(&lengths[0], row->data, default_value ? 8 : 7); - field->catalog = strdup_root(alloc,(char*) row->data[0]); - field->db = strdup_root(alloc,(char*) row->data[1]); - field->table = strdup_root(alloc,(char*) row->data[2]); - field->org_table= strdup_root(alloc,(char*) row->data[3]); - field->name = strdup_root(alloc,(char*) row->data[4]); - field->org_name = strdup_root(alloc,(char*) row->data[5]); + field->catalog= strmake_root(alloc,(char*) row->data[0], lengths[0]); + field->db= strmake_root(alloc,(char*) row->data[1], lengths[1]); + field->table= strmake_root(alloc,(char*) row->data[2], lengths[2]); + field->org_table= strmake_root(alloc,(char*) row->data[3], lengths[3]); + field->name= strmake_root(alloc,(char*) row->data[4], lengths[4]); + field->org_name= strmake_root(alloc,(char*) row->data[5], lengths[5]); field->catalog_length= lengths[0]; field->db_length= lengths[1]; @@ -1252,7 +1252,7 @@ unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields, field->flags|= NUM_FLAG; if (default_value && row->data[7]) { - field->def=strdup_root(alloc,(char*) row->data[7]); + field->def=strmake_root(alloc,(char*) row->data[7], lengths[7]); field->def_length= lengths[7]; } else diff --git a/sql/field.cc b/sql/field.cc index a970a6e4318..3213f84ee3e 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -7901,8 +7901,11 @@ int Field_enum::store(longlong nr, bool unsigned_val) if ((ulonglong) nr > typelib->count || nr == 0) { set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1); - nr=0; - error=1; + if (nr != 0 || table->in_use->count_cuted_fields) + { + nr= 0; + error= 1; + } } store_type((ulonglong) (uint) nr); return error; diff --git a/sql/item_func.cc b/sql/item_func.cc index f14091b4592..4012371bedb 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -5599,10 +5599,20 @@ Item_func_sp::fix_fields(THD *thd, Item **ref) #endif /* ! NO_EMBEDDED_ACCESS_CHECKS */ } + if (!m_sp->m_chistics->detistic) + used_tables_cache |= RAND_TABLE_BIT; DBUG_RETURN(res); } +void Item_func_sp::update_used_tables() +{ + Item_func::update_used_tables(); + if (!m_sp->m_chistics->detistic) + used_tables_cache |= RAND_TABLE_BIT; +} + + /* uuid_short handling. diff --git a/sql/item_func.h b/sql/item_func.h index 568effb2f63..ea22e35773d 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1472,7 +1472,7 @@ public: virtual ~Item_func_sp() {} - table_map used_tables() const { return RAND_TABLE_BIT; } + void update_used_tables(); void cleanup(); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 0cd46a7c6fb..f1319010270 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -3797,13 +3797,6 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type) if (table) { -#if defined( __WIN__) - /* Win32 can't drop a file that is open */ - if (lock_type == TL_WRITE_ALLOW_READ) - { - lock_type= TL_WRITE; - } -#endif /* __WIN__ */ table_list->lock_type= lock_type; table_list->table= table; table->grant= table_list->grant; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index e493dc05047..8ab4dee12ac 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1770,7 +1770,7 @@ TABLE_LIST *st_select_lex_node::add_table_to_list (THD *thd, Table_ident *table, LEX_STRING *alias, ulong table_join_options, thr_lock_type flags, - List *hints, + List *hints, LEX_STRING *option) { return 0; @@ -2723,7 +2723,7 @@ void st_select_lex::set_index_hint_type(enum index_hint_type type, void st_select_lex::alloc_index_hints (THD *thd) { - index_hints= new (thd->mem_root) List(); + index_hints= new (thd->mem_root) List(); } @@ -2744,7 +2744,7 @@ void st_select_lex::alloc_index_hints (THD *thd) bool st_select_lex::add_index_hint (THD *thd, char *str, uint length) { return index_hints->push_front (new (thd->mem_root) - index_hint(current_index_hint_type, + Index_hint(current_index_hint_type, current_index_hint_clause, str, length)); } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 9ac7f2835f0..b769930958e 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -236,7 +236,7 @@ typedef uchar index_clause_map; INDEX_HINT_MASK_ORDER) /* Single element of an USE/FORCE/IGNORE INDEX list specified as a SQL hint */ -class index_hint : public Sql_alloc +class Index_hint : public Sql_alloc { public: /* The type of the hint : USE/FORCE/IGNORE */ @@ -249,7 +249,7 @@ public: */ LEX_STRING key_name; - index_hint (enum index_hint_type type_arg, index_clause_map clause_arg, + Index_hint (enum index_hint_type type_arg, index_clause_map clause_arg, char *str, uint length) : type(type_arg), clause(clause_arg) { @@ -441,7 +441,7 @@ public: LEX_STRING *alias, ulong table_options, thr_lock_type flags= TL_UNLOCK, - List *hints= 0, + List *hints= 0, LEX_STRING *option= 0); virtual void set_lock_for_tables(thr_lock_type lock_type) {} @@ -719,7 +719,7 @@ public: LEX_STRING *alias, ulong table_options, thr_lock_type flags= TL_UNLOCK, - List *hints= 0, + List *hints= 0, LEX_STRING *option= 0); TABLE_LIST* get_table_list(); bool init_nested_join(THD *thd); @@ -779,9 +779,9 @@ public: /* make a list to hold index hints */ void alloc_index_hints (THD *thd); /* read and clear the index hints */ - List* pop_index_hints(void) + List* pop_index_hints(void) { - List *hints= index_hints; + List *hints= index_hints; index_hints= NULL; return hints; } @@ -793,7 +793,7 @@ private: enum index_hint_type current_index_hint_type; index_clause_map current_index_hint_clause; /* a list of USE/FORCE/IGNORE INDEX */ - List *index_hints; + List *index_hints; }; typedef class st_select_lex SELECT_LEX; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index f2a61b7f7c5..93887db88e1 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -5636,7 +5636,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, LEX_STRING *alias, ulong table_options, thr_lock_type lock_type, - List *index_hints_arg, + List *index_hints_arg, LEX_STRING *option) { register TABLE_LIST *ptr; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index be6d1f74852..668b7e99549 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -12289,6 +12289,7 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx, key_part_end=key_part+table->key_info[idx].key_parts; key_part_map const_key_parts=table->const_key_parts[idx]; int reverse=0; + my_bool on_primary_key= FALSE; DBUG_ENTER("test_if_order_by_key"); for (; order ; order=order->next, const_key_parts>>=1) @@ -12303,7 +12304,31 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx, for (; const_key_parts & 1 ; const_key_parts>>= 1) key_part++; - if (key_part == key_part_end || key_part->field != field) + if (key_part == key_part_end) + { + /* + We are at the end of the key. Check if the engine has the primary + key as a suffix to the secondary keys. If it has continue to check + the primary key as a suffix. + */ + if (!on_primary_key && + (table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) && + ha_legacy_type(table->s->db_type()) == DB_TYPE_INNODB && + table->s->primary_key != MAX_KEY) + { + on_primary_key= TRUE; + key_part= table->key_info[table->s->primary_key].key_part; + key_part_end=key_part+table->key_info[table->s->primary_key].key_parts; + const_key_parts=table->const_key_parts[table->s->primary_key]; + + for (; const_key_parts & 1 ; const_key_parts>>= 1) + key_part++; + } + else + DBUG_RETURN(0); + } + + if (key_part->field != field) DBUG_RETURN(0); /* set flag to 1 if we can use read-next on key, else to -1 */ @@ -12314,7 +12339,8 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx, reverse=flag; // Remember if reverse key_part++; } - *used_key_parts= (uint) (key_part - table->key_info[idx].key_part); + *used_key_parts= on_primary_key ? table->key_info[idx].key_parts : + (uint) (key_part - table->key_info[idx].key_part); if (reverse == -1 && !(table->file->index_flags(idx, *used_key_parts-1, 1) & HA_READ_PREV)) reverse= 0; // Index can't be used @@ -13030,7 +13056,7 @@ remove_duplicates(JOIN *join, TABLE *entry,List &fields, Item *having) field_count++; } - if (!field_count && !(join->select_options & OPTION_FOUND_ROWS)) + if (!field_count && !(join->select_options & OPTION_FOUND_ROWS) && !having) { // only const items with no OPTION_FOUND_ROWS join->unit->select_limit_cnt= 1; // Only send first row DBUG_RETURN(0); diff --git a/sql/table.cc b/sql/table.cc index a58f59d3a75..e6f9b1086c7 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1349,7 +1349,12 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, the primary key, then we can use any key to find this column */ if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX) + { field->part_of_key= share->keys_in_use; + if (ha_legacy_type(share->db_type()) == DB_TYPE_INNODB && + field->part_of_sortkey.is_set(key)) + field->part_of_sortkey= share->keys_in_use; + } } if (field->key_length() != key_part->length) { @@ -4642,11 +4647,11 @@ bool TABLE_LIST::process_index_hints(TABLE *table) key_map index_join[INDEX_HINT_FORCE + 1]; key_map index_order[INDEX_HINT_FORCE + 1]; key_map index_group[INDEX_HINT_FORCE + 1]; - index_hint *hint; + Index_hint *hint; int type; bool have_empty_use_join= FALSE, have_empty_use_order= FALSE, have_empty_use_group= FALSE; - List_iterator iter(*index_hints); + List_iterator iter(*index_hints); /* initialize temporary variables used to collect hints of each kind */ for (type= INDEX_HINT_IGNORE; type <= INDEX_HINT_FORCE; type++) diff --git a/sql/table.h b/sql/table.h index 494b74d564c..a276a9f32fd 100644 --- a/sql/table.h +++ b/sql/table.h @@ -754,7 +754,7 @@ public: (TABLE_LIST::join_using_fields != NULL) */ -class index_hint; +class Index_hint; struct TABLE_LIST { TABLE_LIST() {} /* Remove gcc warning */ @@ -826,7 +826,7 @@ struct TABLE_LIST */ TABLE_LIST *next_name_resolution_table; /* Index names in a "... JOIN ... USE/IGNORE INDEX ..." clause. */ - List *index_hints; + List *index_hints; TABLE *table; /* opened table */ uint table_id; /* table id (from binlog) for opened table */ /* diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index b7d0c4417c3..840a0ec7e3b 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -7042,18 +7042,6 @@ ha_innobase::store_lock( && !thd_tablespace_op(thd) && sql_command != SQLCOM_TRUNCATE && sql_command != SQLCOM_OPTIMIZE - -#ifdef __WIN__ - /* For alter table on win32 for successful - operation completion it is used TL_WRITE(=10) lock - instead of TL_WRITE_ALLOW_READ(=6), however here - in innodb handler TL_WRITE is lifted to - TL_WRITE_ALLOW_WRITE, which causes race condition - when several clients do alter table simultaneously - (bug #17264). This fix avoids the problem. */ - && sql_command != SQLCOM_ALTER_TABLE -#endif - && sql_command != SQLCOM_CREATE_TABLE) { lock_type = TL_WRITE_ALLOW_WRITE;