Merge jbruehe@bk-internal.mysql.com:/home/bk/mysql-5.1-opt
into trift2.:/MySQL/M51/push-5.1 sql/item_func.cc: Auto merged sql/sql_show.cc: Auto merged
This commit is contained in:
commit
13390debf6
@ -530,7 +530,8 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
EXPLAIN SELECT DISTINCT a,b FROM t1 GROUP BY a,b;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
|
||||
CREATE TABLE t2(a INT, b INT, c INT, d INT, PRIMARY KEY (a,b));
|
||||
CREATE TABLE t2(a INT, b INT NOT NULL, c INT NOT NULL, d INT,
|
||||
PRIMARY KEY (a,b));
|
||||
INSERT INTO t2 VALUES (1,1,1,50), (1,2,3,40), (2,1,3,4);
|
||||
EXPLAIN SELECT DISTINCT a FROM t2;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
@ -644,3 +645,26 @@ SELECT COUNT(*) FROM
|
||||
COUNT(*)
|
||||
2
|
||||
DROP TABLE t1, t2;
|
||||
CREATE TABLE t1 (a INT, UNIQUE (a));
|
||||
INSERT INTO t1 VALUES (4),(null),(2),(1),(null),(3);
|
||||
EXPLAIN SELECT DISTINCT a FROM t1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index NULL a 5 NULL 6 Using index
|
||||
SELECT DISTINCT a FROM t1;
|
||||
a
|
||||
NULL
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
EXPLAIN SELECT a FROM t1 GROUP BY a;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index NULL a 5 NULL 6 Using index
|
||||
SELECT a FROM t1 GROUP BY a;
|
||||
a
|
||||
NULL
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
DROP TABLE t1;
|
||||
|
@ -1183,6 +1183,20 @@ set time_zone= @@global.time_zone;
|
||||
select str_to_date('10:00 PM', '%h:%i %p') + INTERVAL 10 MINUTE;
|
||||
str_to_date('10:00 PM', '%h:%i %p') + INTERVAL 10 MINUTE
|
||||
NULL
|
||||
CREATE TABLE t1 (a int, t1 time, t2 time, d date, PRIMARY KEY (a));
|
||||
INSERT INTO t1 VALUES (1, '10:00:00', NULL, NULL),
|
||||
(2, '11:00:00', '11:15:00', '1972-02-06');
|
||||
SELECT t1, t2, SEC_TO_TIME( TIME_TO_SEC( t2 ) - TIME_TO_SEC( t1 ) ), QUARTER(d)
|
||||
FROM t1;
|
||||
t1 t2 SEC_TO_TIME( TIME_TO_SEC( t2 ) - TIME_TO_SEC( t1 ) ) QUARTER(d)
|
||||
10:00:00 NULL NULL NULL
|
||||
11:00:00 11:15:00 00:15:00 1
|
||||
SELECT t1, t2, SEC_TO_TIME( TIME_TO_SEC( t2 ) - TIME_TO_SEC( t1 ) ), QUARTER(d)
|
||||
FROM t1 ORDER BY a DESC;
|
||||
t1 t2 SEC_TO_TIME( TIME_TO_SEC( t2 ) - TIME_TO_SEC( t1 ) ) QUARTER(d)
|
||||
11:00:00 11:15:00 00:15:00 1
|
||||
10:00:00 NULL NULL NULL
|
||||
DROP TABLE t1;
|
||||
End of 5.0 tests
|
||||
select date_sub("0050-01-01 00:00:01",INTERVAL 2 SECOND);
|
||||
date_sub("0050-01-01 00:00:01",INTERVAL 2 SECOND)
|
||||
|
@ -1037,4 +1037,24 @@ REVOKE EXECUTE ON PROCEDURE p1 FROM 1234567890abcdefGHIKL@localhost;
|
||||
ERROR HY000: String '1234567890abcdefGHIKL' is too long for user name (should be no longer than 16)
|
||||
REVOKE EXECUTE ON PROCEDURE t1 FROM some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY;
|
||||
ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY' is too long for host name (should be no longer than 60)
|
||||
CREATE USER bug23556@localhost;
|
||||
CREATE DATABASE bug23556;
|
||||
GRANT SELECT ON bug23556.* TO bug23556@localhost;
|
||||
USE bug23556;
|
||||
CREATE TABLE t1 (a INT PRIMARY KEY);
|
||||
INSERT INTO t1 VALUES (1),(2),(3),(4),(5);
|
||||
GRANT DELETE ON t1 TO bug23556@localhost;
|
||||
USE bug23556;
|
||||
TRUNCATE t1;
|
||||
ERROR 42000: DROP command denied to user 'bug23556'@'localhost' for table 't1'
|
||||
USE bug23556;
|
||||
REVOKE DELETE ON t1 FROM bug23556@localhost;
|
||||
GRANT DROP ON t1 TO bug23556@localhost;
|
||||
USE bug23556;
|
||||
TRUNCATE t1;
|
||||
USE bug23556;
|
||||
DROP TABLE t1;
|
||||
USE test;
|
||||
DROP DATABASE bug23556;
|
||||
DROP USER bug23556@localhost;
|
||||
End of 5.0 tests
|
||||
|
@ -1342,6 +1342,16 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY <derived2> system NULL NULL NULL NULL 0 const row not found
|
||||
2 DERIVED tables ALL NULL NULL NULL NULL 2
|
||||
drop view v1;
|
||||
create table t1 (f1 int(11));
|
||||
create table t2 (f1 int(11), f2 int(11));
|
||||
select table_name from information_schema.tables
|
||||
where table_schema = 'test' and table_name not in
|
||||
(select table_name from information_schema.columns
|
||||
where table_schema = 'test' and column_name = 'f3');
|
||||
table_name
|
||||
t1
|
||||
t2
|
||||
drop table t1,t2;
|
||||
End of 5.0 tests.
|
||||
select * from information_schema.engines WHERE ENGINE="MyISAM";
|
||||
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
|
||||
|
@ -1605,3 +1605,31 @@ WHERE t1.id='5';
|
||||
id ct pc nm
|
||||
5 NULL NULL NULL
|
||||
DROP TABLE t1,t2,t3,t4;
|
||||
CREATE TABLE t1 (a INT, b INT);
|
||||
CREATE TABLE t2 (a INT);
|
||||
CREATE TABLE t3 (a INT, c INT);
|
||||
CREATE TABLE t4 (a INT, c INT);
|
||||
CREATE TABLE t5 (a INT, c INT);
|
||||
SELECT b FROM t1 JOIN (t2 LEFT JOIN t3 USING (a) LEFT JOIN t4 USING (a)
|
||||
LEFT JOIN t5 USING (a)) USING (a);
|
||||
b
|
||||
SELECT c FROM t1 JOIN (t2 LEFT JOIN t3 USING (a) LEFT JOIN t4 USING (a)
|
||||
LEFT JOIN t5 USING (a)) USING (a);
|
||||
ERROR 23000: Column 'c' in field list is ambiguous
|
||||
SELECT b FROM t1 JOIN (t2 JOIN t3 USING (a) JOIN t4 USING (a)
|
||||
JOIN t5 USING (a)) USING (a);
|
||||
b
|
||||
SELECT c FROM t1 JOIN (t2 JOIN t3 USING (a) JOIN t4 USING (a)
|
||||
JOIN t5 USING (a)) USING (a);
|
||||
ERROR 23000: Column 'c' in field list is ambiguous
|
||||
DROP TABLE t1,t2,t3,t4,t5;
|
||||
CREATE TABLE t1 (a INT, b INT);
|
||||
CREATE TABLE t2 (a INT, b INT);
|
||||
CREATE TABLE t3 (a INT, b INT);
|
||||
INSERT INTO t1 VALUES (1,1);
|
||||
INSERT INTO t2 VALUES (1,1);
|
||||
INSERT INTO t3 VALUES (1,1);
|
||||
SELECT * FROM t1 JOIN (t2 JOIN t3 USING (b)) USING (a);
|
||||
ERROR 23000: Column 'a' in from clause is ambiguous
|
||||
DROP TABLE t1,t2,t3;
|
||||
End of 5.0 tests
|
||||
|
@ -482,3 +482,10 @@ alter table t1 drop index i3, drop index i2, drop index i1;
|
||||
alter table t1 add index i3 (c3), add index i2 (c2), add unique index i1 (c1);
|
||||
ERROR 23000: Duplicate entry '1' for key 'i1'
|
||||
drop table t1;
|
||||
CREATE TABLE t1( a TINYINT, KEY(a) ) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES( 1 );
|
||||
ALTER TABLE t1 DISABLE KEYS;
|
||||
EXPLAIN SELECT MAX(a) FROM t1 FORCE INDEX(a);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 system NULL NULL NULL NULL 1
|
||||
drop table t1;
|
||||
|
@ -417,12 +417,12 @@ a b c
|
||||
9199 9200 NULL
|
||||
223456 223457 NULL
|
||||
245651 245652 2005-12-08 15:58:27
|
||||
select c, count(*)
|
||||
select t21.c, count(*)
|
||||
from t21
|
||||
inner join t22 using (a)
|
||||
where t22.b in (2,256,257,1121,1134,4102,9200,223457,245652)
|
||||
group by c
|
||||
order by c;
|
||||
group by t21.c
|
||||
order by t21.c;
|
||||
c count(*)
|
||||
NULL 7
|
||||
2005-12-08 15:58:27 1
|
||||
|
@ -30,7 +30,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref a,b a 5 const 3 Using where; Using index
|
||||
explain select * from t1 where a is null and b=9 or a is null and b=7 limit 3;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref a,b a 5 const 2 Using where; Using index
|
||||
1 SIMPLE t1 range a,b a 9 NULL 3 Using where; Using index
|
||||
explain select * from t1 where a > 1 and a < 3 limit 1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 range a a 5 NULL 1 Using where; Using index
|
||||
@ -258,7 +258,7 @@ INSERT INTO t1 VALUES (1,NULL),(2,NULL),(3,1),(4,2),(5,NULL),(6,NULL),(7,3),(8,4
|
||||
INSERT INTO t2 VALUES (1,NULL),(2,NULL),(3,1),(4,2),(5,NULL),(6,NULL),(7,3),(8,4),(9,NULL),(10,NULL);
|
||||
explain select id from t1 where uniq_id is null;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref idx1 idx1 5 const 1 Using where
|
||||
1 SIMPLE t1 ref idx1 idx1 5 const 5 Using where
|
||||
explain select id from t1 where uniq_id =1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 const idx1 idx1 5 const 1
|
||||
|
@ -3642,3 +3642,89 @@ INSERT into t1 values (1), (2), (3);
|
||||
SELECT * FROM t1 LIMIT 2, -1;
|
||||
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 '-1' at line 1
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (
|
||||
ID_with_null int NULL,
|
||||
ID_better int NOT NULL,
|
||||
INDEX idx1 (ID_with_null),
|
||||
INDEX idx2 (ID_better)
|
||||
);
|
||||
INSERT INTO t1 VALUES (1,1), (2,1), (null,3), (null,3), (null,3), (null,3);
|
||||
INSERT INTO t1 SELECT * FROM t1 WHERE ID_with_null IS NULL;
|
||||
INSERT INTO t1 SELECT * FROM t1 WHERE ID_with_null IS NULL;
|
||||
INSERT INTO t1 SELECT * FROM t1 WHERE ID_with_null IS NULL;
|
||||
INSERT INTO t1 SELECT * FROM t1 WHERE ID_with_null IS NULL;
|
||||
INSERT INTO t1 SELECT * FROM t1 WHERE ID_with_null IS NULL;
|
||||
SELECT COUNT(*) FROM t1 WHERE ID_with_null IS NULL;
|
||||
COUNT(*)
|
||||
128
|
||||
SELECT COUNT(*) FROM t1 WHERE ID_better=1;
|
||||
COUNT(*)
|
||||
2
|
||||
EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID_with_null IS NULL;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where
|
||||
DROP INDEX idx1 ON t1;
|
||||
CREATE UNIQUE INDEX idx1 ON t1(ID_with_null);
|
||||
EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID_with_null IS NULL;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (
|
||||
ID1_with_null int NULL,
|
||||
ID2_with_null int NULL,
|
||||
ID_better int NOT NULL,
|
||||
INDEX idx1 (ID1_with_null, ID2_with_null),
|
||||
INDEX idx2 (ID_better)
|
||||
);
|
||||
INSERT INTO t1 VALUES (1,1,1), (2,2,1), (3,null,3), (null,3,3), (null,null,3),
|
||||
(3,null,3), (null,3,3), (null,null,3), (3,null,3), (null,3,3), (null,null,3);
|
||||
INSERT INTO t1 SELECT * FROM t1 WHERE ID1_with_null IS NULL;
|
||||
INSERT INTO t1 SELECT * FROM t1 WHERE ID2_with_null IS NULL;
|
||||
INSERT INTO t1 SELECT * FROM t1 WHERE ID1_with_null IS NULL;
|
||||
INSERT INTO t1 SELECT * FROM t1 WHERE ID2_with_null IS NULL;
|
||||
INSERT INTO t1 SELECT * FROM t1 WHERE ID1_with_null IS NULL;
|
||||
INSERT INTO t1 SELECT * FROM t1 WHERE ID2_with_null IS NULL;
|
||||
SELECT COUNT(*) FROM t1 WHERE ID1_with_null IS NULL AND ID2_with_null=3;
|
||||
COUNT(*)
|
||||
24
|
||||
SELECT COUNT(*) FROM t1 WHERE ID1_with_null=3 AND ID2_with_null IS NULL;
|
||||
COUNT(*)
|
||||
24
|
||||
SELECT COUNT(*) FROM t1 WHERE ID1_with_null IS NULL AND ID2_with_null IS NULL;
|
||||
COUNT(*)
|
||||
192
|
||||
SELECT COUNT(*) FROM t1 WHERE ID_better=1;
|
||||
COUNT(*)
|
||||
2
|
||||
EXPLAIN SELECT * FROM t1
|
||||
WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null=3 ;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where
|
||||
EXPLAIN SELECT * FROM t1
|
||||
WHERE ID_better=1 AND ID1_with_null=3 AND ID2_with_null=3 IS NULL ;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where
|
||||
EXPLAIN SELECT * FROM t1
|
||||
WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null IS NULL;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where
|
||||
DROP INDEX idx1 ON t1;
|
||||
CREATE UNIQUE INDEX idx1 ON t1(ID1_with_null,ID2_with_null);
|
||||
EXPLAIN SELECT * FROM t1
|
||||
WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null=3 ;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where
|
||||
EXPLAIN SELECT * FROM t1
|
||||
WHERE ID_better=1 AND ID1_with_null=3 AND ID2_with_null IS NULL ;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where
|
||||
EXPLAIN SELECT * FROM t1
|
||||
WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null IS NULL;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where
|
||||
EXPLAIN SELECT * FROM t1
|
||||
WHERE ID_better=1 AND ID1_with_null IS NULL AND
|
||||
(ID2_with_null=1 OR ID2_with_null=2);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where
|
||||
DROP TABLE t1;
|
||||
|
@ -3046,6 +3046,80 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
|
||||
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a int);
|
||||
INSERT INTO t1 VALUES (2), (4), (1), (3);
|
||||
CREATE TABLE t2 (b int, c int);
|
||||
INSERT INTO t2 VALUES
|
||||
(2,1), (1,3), (2,1), (4,4), (2,2), (1,4);
|
||||
SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 2 );
|
||||
a
|
||||
2
|
||||
4
|
||||
1
|
||||
3
|
||||
SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 1);
|
||||
ERROR 21000: Subquery returns more than 1 row
|
||||
SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 2), a;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 1), a;
|
||||
ERROR 21000: Subquery returns more than 1 row
|
||||
SELECT b, MAX(c) FROM t2 GROUP BY b, (SELECT c FROM t2 WHERE b > 2);
|
||||
b MAX(c)
|
||||
1 4
|
||||
2 2
|
||||
4 4
|
||||
SELECT b, MAX(c) FROM t2 GROUP BY b, (SELECT c FROM t2 WHERE b > 1);
|
||||
ERROR 21000: Subquery returns more than 1 row
|
||||
SELECT a FROM t1 GROUP BY a
|
||||
HAVING IFNULL((SELECT b FROM t2 WHERE b > 2),
|
||||
(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
SELECT a FROM t1 GROUP BY a
|
||||
HAVING IFNULL((SELECT b FROM t2 WHERE b > 1),
|
||||
(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3;
|
||||
ERROR 21000: Subquery returns more than 1 row
|
||||
SELECT a FROM t1 GROUP BY a
|
||||
HAVING IFNULL((SELECT b FROM t2 WHERE b > 4),
|
||||
(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3;
|
||||
a
|
||||
4
|
||||
SELECT a FROM t1 GROUP BY a
|
||||
HAVING IFNULL((SELECT b FROM t2 WHERE b > 4),
|
||||
(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b)) > 3;
|
||||
ERROR 21000: Subquery returns more than 1 row
|
||||
SELECT a FROM t1
|
||||
ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 2),
|
||||
(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b));
|
||||
a
|
||||
2
|
||||
4
|
||||
1
|
||||
3
|
||||
SELECT a FROM t1
|
||||
ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 1),
|
||||
(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b));
|
||||
ERROR 21000: Subquery returns more than 1 row
|
||||
SELECT a FROM t1
|
||||
ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 4),
|
||||
(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b));
|
||||
a
|
||||
2
|
||||
1
|
||||
3
|
||||
4
|
||||
SELECT a FROM t1
|
||||
ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 4),
|
||||
(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b));
|
||||
ERROR 21000: Subquery returns more than 1 row
|
||||
DROP TABLE t1,t2;
|
||||
create table t1 (df decimal(5,1));
|
||||
insert into t1 values(1.1);
|
||||
insert into t1 values(2.2);
|
||||
|
@ -629,3 +629,19 @@ cc NULL NULL
|
||||
aa 1 1
|
||||
bb NULL NULL
|
||||
drop table t1,t2;
|
||||
create table t1 (a int, b int);
|
||||
insert into t1 values (0,0), (2,2), (3,3);
|
||||
create table t2 (a int, b int);
|
||||
insert into t2 values (1,1), (3,3);
|
||||
select a, b, (a,b) in (select a, min(b) from t2 group by a) Z from t1;
|
||||
a b Z
|
||||
0 0 0
|
||||
2 2 0
|
||||
3 3 1
|
||||
insert into t2 values (NULL,4);
|
||||
select a, b, (a,b) in (select a, min(b) from t2 group by a) Z from t1;
|
||||
a b Z
|
||||
0 0 0
|
||||
2 2 0
|
||||
3 3 1
|
||||
drop table t1,t2;
|
||||
|
@ -14,8 +14,8 @@ CREATE TABLE t1(num_value INT);
|
||||
CREATE TABLE t2(user_str TEXT);
|
||||
|
||||
---> connection: default
|
||||
GRANT INSERT, DELETE ON mysqltest_db1.t1 TO mysqltest_dfn@localhost;
|
||||
GRANT INSERT, DELETE ON mysqltest_db1.t2 TO mysqltest_dfn@localhost;
|
||||
GRANT INSERT, DROP ON mysqltest_db1.t1 TO mysqltest_dfn@localhost;
|
||||
GRANT INSERT, DROP ON mysqltest_db1.t2 TO mysqltest_dfn@localhost;
|
||||
|
||||
---> connection: default
|
||||
GRANT SUPER ON *.* TO mysqltest_dfn@localhost;
|
||||
|
@ -1241,6 +1241,31 @@ i j
|
||||
2 2
|
||||
13 13
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (a INT PRIMARY KEY);
|
||||
CREATE TABLE t2 (a INT PRIMARY KEY);
|
||||
INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8);
|
||||
CREATE TRIGGER trg_t1 BEFORE DELETE on t1 FOR EACH ROW
|
||||
INSERT INTO t2 VALUES (OLD.a);
|
||||
FLUSH STATUS;
|
||||
TRUNCATE t1;
|
||||
SHOW STATUS LIKE 'handler_delete';
|
||||
Variable_name Value
|
||||
Handler_delete 0
|
||||
SELECT COUNT(*) FROM t2;
|
||||
COUNT(*)
|
||||
0
|
||||
INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8);
|
||||
DELETE FROM t2;
|
||||
FLUSH STATUS;
|
||||
DELETE FROM t1;
|
||||
SHOW STATUS LIKE 'handler_delete';
|
||||
Variable_name Value
|
||||
Handler_delete 8
|
||||
SELECT COUNT(*) FROM t2;
|
||||
COUNT(*)
|
||||
8
|
||||
DROP TRIGGER trg_t1;
|
||||
DROP TABLE t1,t2;
|
||||
drop table if exists t1;
|
||||
drop function if exists f1;
|
||||
create table t1 (i int);
|
||||
|
@ -364,7 +364,8 @@ EXPLAIN SELECT a FROM t1 GROUP BY a;
|
||||
EXPLAIN SELECT a,b FROM t1 GROUP BY a,b;
|
||||
EXPLAIN SELECT DISTINCT a,b FROM t1 GROUP BY a,b;
|
||||
|
||||
CREATE TABLE t2(a INT, b INT, c INT, d INT, PRIMARY KEY (a,b));
|
||||
CREATE TABLE t2(a INT, b INT NOT NULL, c INT NOT NULL, d INT,
|
||||
PRIMARY KEY (a,b));
|
||||
INSERT INTO t2 VALUES (1,1,1,50), (1,2,3,40), (2,1,3,4);
|
||||
EXPLAIN SELECT DISTINCT a FROM t2;
|
||||
EXPLAIN SELECT DISTINCT a,a FROM t2;
|
||||
@ -525,3 +526,17 @@ SELECT COUNT(*) FROM
|
||||
(SELECT DISTINCT a FROM t2 WHERE a='oe' COLLATE latin1_german2_ci) dt;
|
||||
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
#
|
||||
# Bug #25551: inconsistent behaviour in grouping NULL, depending on index type
|
||||
#
|
||||
CREATE TABLE t1 (a INT, UNIQUE (a));
|
||||
INSERT INTO t1 VALUES (4),(null),(2),(1),(null),(3);
|
||||
EXPLAIN SELECT DISTINCT a FROM t1;
|
||||
#result must have one row with NULL
|
||||
SELECT DISTINCT a FROM t1;
|
||||
EXPLAIN SELECT a FROM t1 GROUP BY a;
|
||||
#result must have one row with NULL
|
||||
SELECT a FROM t1 GROUP BY a;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
@ -692,6 +692,18 @@ set time_zone= @@global.time_zone;
|
||||
#
|
||||
|
||||
select str_to_date('10:00 PM', '%h:%i %p') + INTERVAL 10 MINUTE;
|
||||
|
||||
#
|
||||
# Bug #25643: SEC_TO_TIME function problem
|
||||
#
|
||||
CREATE TABLE t1 (a int, t1 time, t2 time, d date, PRIMARY KEY (a));
|
||||
INSERT INTO t1 VALUES (1, '10:00:00', NULL, NULL),
|
||||
(2, '11:00:00', '11:15:00', '1972-02-06');
|
||||
SELECT t1, t2, SEC_TO_TIME( TIME_TO_SEC( t2 ) - TIME_TO_SEC( t1 ) ), QUARTER(d)
|
||||
FROM t1;
|
||||
SELECT t1, t2, SEC_TO_TIME( TIME_TO_SEC( t2 ) - TIME_TO_SEC( t1 ) ), QUARTER(d)
|
||||
FROM t1 ORDER BY a DESC;
|
||||
DROP TABLE t1;
|
||||
--echo End of 5.0 tests
|
||||
|
||||
#
|
||||
|
@ -939,4 +939,39 @@ REVOKE EXECUTE ON PROCEDURE p1 FROM 1234567890abcdefGHIKL@localhost;
|
||||
|
||||
--error ER_WRONG_STRING_LENGTH
|
||||
REVOKE EXECUTE ON PROCEDURE t1 FROM some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY;
|
||||
|
||||
|
||||
#
|
||||
# BUG#23556: TRUNCATE TABLE still maps to DELETE
|
||||
#
|
||||
CREATE USER bug23556@localhost;
|
||||
CREATE DATABASE bug23556;
|
||||
GRANT SELECT ON bug23556.* TO bug23556@localhost;
|
||||
connect (bug23556,localhost,bug23556,,bug23556);
|
||||
|
||||
connection default;
|
||||
USE bug23556;
|
||||
CREATE TABLE t1 (a INT PRIMARY KEY); INSERT INTO t1 VALUES (1),(2),(3),(4),(5);
|
||||
GRANT DELETE ON t1 TO bug23556@localhost;
|
||||
|
||||
connection bug23556;
|
||||
USE bug23556;
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
TRUNCATE t1;
|
||||
|
||||
connection default;
|
||||
USE bug23556;
|
||||
REVOKE DELETE ON t1 FROM bug23556@localhost;
|
||||
GRANT DROP ON t1 TO bug23556@localhost;
|
||||
|
||||
connection bug23556;
|
||||
USE bug23556;
|
||||
TRUNCATE t1;
|
||||
|
||||
connection default;
|
||||
USE bug23556;
|
||||
DROP TABLE t1;
|
||||
USE test;
|
||||
DROP DATABASE bug23556;
|
||||
DROP USER bug23556@localhost;
|
||||
--echo End of 5.0 tests
|
||||
|
@ -988,6 +988,18 @@ explain select * from v1;
|
||||
explain select * from (select table_name from information_schema.tables) as a;
|
||||
drop view v1;
|
||||
|
||||
#
|
||||
# Bug#23299 Some queries against INFORMATION_SCHEMA with subqueries fail
|
||||
#
|
||||
create table t1 (f1 int(11));
|
||||
create table t2 (f1 int(11), f2 int(11));
|
||||
|
||||
select table_name from information_schema.tables
|
||||
where table_schema = 'test' and table_name not in
|
||||
(select table_name from information_schema.columns
|
||||
where table_schema = 'test' and column_name = 'f3');
|
||||
drop table t1,t2;
|
||||
|
||||
--echo End of 5.0 tests.
|
||||
#
|
||||
# Show engines
|
||||
|
@ -1045,3 +1045,42 @@ SELECT t1.*, t4.nm
|
||||
WHERE t1.id='5';
|
||||
|
||||
DROP TABLE t1,t2,t3,t4;
|
||||
|
||||
#
|
||||
# BUG#25575: ERROR 1052 (Column in from clause is ambiguous) with sub-join
|
||||
#
|
||||
CREATE TABLE t1 (a INT, b INT);
|
||||
CREATE TABLE t2 (a INT);
|
||||
CREATE TABLE t3 (a INT, c INT);
|
||||
CREATE TABLE t4 (a INT, c INT);
|
||||
CREATE TABLE t5 (a INT, c INT);
|
||||
|
||||
SELECT b FROM t1 JOIN (t2 LEFT JOIN t3 USING (a) LEFT JOIN t4 USING (a)
|
||||
LEFT JOIN t5 USING (a)) USING (a);
|
||||
|
||||
--error ER_NON_UNIQ_ERROR
|
||||
SELECT c FROM t1 JOIN (t2 LEFT JOIN t3 USING (a) LEFT JOIN t4 USING (a)
|
||||
LEFT JOIN t5 USING (a)) USING (a);
|
||||
|
||||
SELECT b FROM t1 JOIN (t2 JOIN t3 USING (a) JOIN t4 USING (a)
|
||||
JOIN t5 USING (a)) USING (a);
|
||||
|
||||
--error ER_NON_UNIQ_ERROR
|
||||
SELECT c FROM t1 JOIN (t2 JOIN t3 USING (a) JOIN t4 USING (a)
|
||||
JOIN t5 USING (a)) USING (a);
|
||||
|
||||
DROP TABLE t1,t2,t3,t4,t5;
|
||||
CREATE TABLE t1 (a INT, b INT);
|
||||
CREATE TABLE t2 (a INT, b INT);
|
||||
CREATE TABLE t3 (a INT, b INT);
|
||||
|
||||
INSERT INTO t1 VALUES (1,1);
|
||||
INSERT INTO t2 VALUES (1,1);
|
||||
INSERT INTO t3 VALUES (1,1);
|
||||
|
||||
--error ER_NON_UNIQ_ERROR
|
||||
SELECT * FROM t1 JOIN (t2 JOIN t3 USING (b)) USING (a);
|
||||
|
||||
DROP TABLE t1,t2,t3;
|
||||
|
||||
--echo End of 5.0 tests
|
||||
|
@ -442,3 +442,14 @@ alter table t1 drop index i3, drop index i2, drop index i1;
|
||||
alter table t1 add index i3 (c3), add index i2 (c2), add unique index i1 (c1);
|
||||
drop table t1;
|
||||
|
||||
|
||||
#
|
||||
# Bug #20604: Test for disabled keys with aggregate functions and FORCE INDEX.
|
||||
#
|
||||
|
||||
CREATE TABLE t1( a TINYINT, KEY(a) ) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES( 1 );
|
||||
ALTER TABLE t1 DISABLE KEYS;
|
||||
EXPLAIN SELECT MAX(a) FROM t1 FORCE INDEX(a);
|
||||
|
||||
drop table t1;
|
||||
|
@ -249,12 +249,12 @@ t22.a in (select t12.a from t11, t12 where t11.a in(255,256) and t11.a = t12.a a
|
||||
delete from t22 where a > 245651;
|
||||
update t22 set b = a + 1;
|
||||
select * from t22 order by 1,2,3;
|
||||
select c, count(*)
|
||||
select t21.c, count(*)
|
||||
from t21
|
||||
inner join t22 using (a)
|
||||
where t22.b in (2,256,257,1121,1134,4102,9200,223457,245652)
|
||||
group by c
|
||||
order by c;
|
||||
group by t21.c
|
||||
order by t21.c;
|
||||
|
||||
DROP TABLE t1, t11, t12, t21, t22;
|
||||
|
||||
|
@ -579,7 +579,7 @@ prepare stmt1 from ' rename table t5 to t6, t7 to t8 ' ;
|
||||
create table t5 (a int) ;
|
||||
# rename must fail, t7 does not exist
|
||||
# Clean up the filename here because embedded server reports whole path
|
||||
--replace_result \\ / $MYSQL_TEST_DIR . /var/master-data/ "" t7.frm t7
|
||||
--replace_result \\ / $MYSQLTEST_VARDIR . /master-data/ "" t7.frm t7
|
||||
--error 1017
|
||||
execute stmt1 ;
|
||||
create table t7 (a int) ;
|
||||
|
@ -3134,3 +3134,77 @@ SELECT * FROM t1 LIMIT 2, -1;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# 25407: wrong estimate of NULL keys for unique indexes
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (
|
||||
ID_with_null int NULL,
|
||||
ID_better int NOT NULL,
|
||||
INDEX idx1 (ID_with_null),
|
||||
INDEX idx2 (ID_better)
|
||||
);
|
||||
|
||||
INSERT INTO t1 VALUES (1,1), (2,1), (null,3), (null,3), (null,3), (null,3);
|
||||
INSERT INTO t1 SELECT * FROM t1 WHERE ID_with_null IS NULL;
|
||||
INSERT INTO t1 SELECT * FROM t1 WHERE ID_with_null IS NULL;
|
||||
INSERT INTO t1 SELECT * FROM t1 WHERE ID_with_null IS NULL;
|
||||
INSERT INTO t1 SELECT * FROM t1 WHERE ID_with_null IS NULL;
|
||||
INSERT INTO t1 SELECT * FROM t1 WHERE ID_with_null IS NULL;
|
||||
|
||||
SELECT COUNT(*) FROM t1 WHERE ID_with_null IS NULL;
|
||||
SELECT COUNT(*) FROM t1 WHERE ID_better=1;
|
||||
|
||||
EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID_with_null IS NULL;
|
||||
|
||||
DROP INDEX idx1 ON t1;
|
||||
CREATE UNIQUE INDEX idx1 ON t1(ID_with_null);
|
||||
|
||||
EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID_with_null IS NULL;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (
|
||||
ID1_with_null int NULL,
|
||||
ID2_with_null int NULL,
|
||||
ID_better int NOT NULL,
|
||||
INDEX idx1 (ID1_with_null, ID2_with_null),
|
||||
INDEX idx2 (ID_better)
|
||||
);
|
||||
|
||||
INSERT INTO t1 VALUES (1,1,1), (2,2,1), (3,null,3), (null,3,3), (null,null,3),
|
||||
(3,null,3), (null,3,3), (null,null,3), (3,null,3), (null,3,3), (null,null,3);
|
||||
|
||||
INSERT INTO t1 SELECT * FROM t1 WHERE ID1_with_null IS NULL;
|
||||
INSERT INTO t1 SELECT * FROM t1 WHERE ID2_with_null IS NULL;
|
||||
INSERT INTO t1 SELECT * FROM t1 WHERE ID1_with_null IS NULL;
|
||||
INSERT INTO t1 SELECT * FROM t1 WHERE ID2_with_null IS NULL;
|
||||
INSERT INTO t1 SELECT * FROM t1 WHERE ID1_with_null IS NULL;
|
||||
INSERT INTO t1 SELECT * FROM t1 WHERE ID2_with_null IS NULL;
|
||||
|
||||
SELECT COUNT(*) FROM t1 WHERE ID1_with_null IS NULL AND ID2_with_null=3;
|
||||
SELECT COUNT(*) FROM t1 WHERE ID1_with_null=3 AND ID2_with_null IS NULL;
|
||||
SELECT COUNT(*) FROM t1 WHERE ID1_with_null IS NULL AND ID2_with_null IS NULL;
|
||||
SELECT COUNT(*) FROM t1 WHERE ID_better=1;
|
||||
|
||||
EXPLAIN SELECT * FROM t1
|
||||
WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null=3 ;
|
||||
EXPLAIN SELECT * FROM t1
|
||||
WHERE ID_better=1 AND ID1_with_null=3 AND ID2_with_null=3 IS NULL ;
|
||||
EXPLAIN SELECT * FROM t1
|
||||
WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null IS NULL;
|
||||
|
||||
DROP INDEX idx1 ON t1;
|
||||
CREATE UNIQUE INDEX idx1 ON t1(ID1_with_null,ID2_with_null);
|
||||
|
||||
EXPLAIN SELECT * FROM t1
|
||||
WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null=3 ;
|
||||
EXPLAIN SELECT * FROM t1
|
||||
WHERE ID_better=1 AND ID1_with_null=3 AND ID2_with_null IS NULL ;
|
||||
EXPLAIN SELECT * FROM t1
|
||||
WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null IS NULL;
|
||||
EXPLAIN SELECT * FROM t1
|
||||
WHERE ID_better=1 AND ID1_with_null IS NULL AND
|
||||
(ID2_with_null=1 OR ID2_with_null=2);
|
||||
|
||||
DROP TABLE t1;
|
||||
|
@ -2000,6 +2000,65 @@ SELECT a FROM t1 WHERE (SELECT 1 FROM DUAL WHERE 1=0) IS NULL;
|
||||
EXPLAIN SELECT a FROM t1 WHERE (SELECT 1 FROM DUAL WHERE 1=0) IS NULL;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Bug 24653: sorting by expressions containing subselects
|
||||
# that return more than one row
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (a int);
|
||||
INSERT INTO t1 VALUES (2), (4), (1), (3);
|
||||
|
||||
CREATE TABLE t2 (b int, c int);
|
||||
INSERT INTO t2 VALUES
|
||||
(2,1), (1,3), (2,1), (4,4), (2,2), (1,4);
|
||||
|
||||
SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 2 );
|
||||
--error 1242
|
||||
SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 1);
|
||||
SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 2), a;
|
||||
--error 1242
|
||||
SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 1), a;
|
||||
|
||||
SELECT b, MAX(c) FROM t2 GROUP BY b, (SELECT c FROM t2 WHERE b > 2);
|
||||
--error 1242
|
||||
SELECT b, MAX(c) FROM t2 GROUP BY b, (SELECT c FROM t2 WHERE b > 1);
|
||||
|
||||
|
||||
SELECT a FROM t1 GROUP BY a
|
||||
HAVING IFNULL((SELECT b FROM t2 WHERE b > 2),
|
||||
(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3;
|
||||
--error 1242
|
||||
SELECT a FROM t1 GROUP BY a
|
||||
HAVING IFNULL((SELECT b FROM t2 WHERE b > 1),
|
||||
(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3;
|
||||
|
||||
SELECT a FROM t1 GROUP BY a
|
||||
HAVING IFNULL((SELECT b FROM t2 WHERE b > 4),
|
||||
(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3;
|
||||
--error 1242
|
||||
SELECT a FROM t1 GROUP BY a
|
||||
HAVING IFNULL((SELECT b FROM t2 WHERE b > 4),
|
||||
(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b)) > 3;
|
||||
|
||||
SELECT a FROM t1
|
||||
ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 2),
|
||||
(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b));
|
||||
--error 1242
|
||||
SELECT a FROM t1
|
||||
ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 1),
|
||||
(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b));
|
||||
|
||||
SELECT a FROM t1
|
||||
ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 4),
|
||||
(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b));
|
||||
--error 1242
|
||||
SELECT a FROM t1
|
||||
ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 4),
|
||||
(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b));
|
||||
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
||||
#
|
||||
|
@ -472,3 +472,20 @@ select oref, a, a in (select min(ie) from t1 where oref=t2.oref group by grp) Z
|
||||
|
||||
drop table t1,t2;
|
||||
|
||||
#
|
||||
# BUG#24420: row-based IN suqueries with aggregation when the left operand
|
||||
# of the subquery predicate may contain NULL values
|
||||
#
|
||||
|
||||
create table t1 (a int, b int);
|
||||
insert into t1 values (0,0), (2,2), (3,3);
|
||||
create table t2 (a int, b int);
|
||||
insert into t2 values (1,1), (3,3);
|
||||
|
||||
select a, b, (a,b) in (select a, min(b) from t2 group by a) Z from t1;
|
||||
|
||||
insert into t2 values (NULL,4);
|
||||
select a, b, (a,b) in (select a, min(b) from t2 group by a) Z from t1;
|
||||
|
||||
drop table t1,t2;
|
||||
|
||||
|
@ -60,8 +60,8 @@ CREATE TABLE t2(user_str TEXT);
|
||||
--echo
|
||||
--echo ---> connection: default
|
||||
|
||||
GRANT INSERT, DELETE ON mysqltest_db1.t1 TO mysqltest_dfn@localhost;
|
||||
GRANT INSERT, DELETE ON mysqltest_db1.t2 TO mysqltest_dfn@localhost;
|
||||
GRANT INSERT, DROP ON mysqltest_db1.t1 TO mysqltest_dfn@localhost;
|
||||
GRANT INSERT, DROP ON mysqltest_db1.t2 TO mysqltest_dfn@localhost;
|
||||
|
||||
#
|
||||
# Check that the user must have TRIGGER privilege to create a trigger.
|
||||
|
@ -1505,6 +1505,31 @@ update t1 set i= i+ 10 where j > 2;
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug#23556 TRUNCATE TABLE still maps to DELETE
|
||||
#
|
||||
CREATE TABLE t1 (a INT PRIMARY KEY);
|
||||
CREATE TABLE t2 (a INT PRIMARY KEY);
|
||||
INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8);
|
||||
|
||||
CREATE TRIGGER trg_t1 BEFORE DELETE on t1 FOR EACH ROW
|
||||
INSERT INTO t2 VALUES (OLD.a);
|
||||
|
||||
FLUSH STATUS;
|
||||
TRUNCATE t1;
|
||||
SHOW STATUS LIKE 'handler_delete';
|
||||
SELECT COUNT(*) FROM t2;
|
||||
|
||||
INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8);
|
||||
DELETE FROM t2;
|
||||
|
||||
FLUSH STATUS;
|
||||
DELETE FROM t1;
|
||||
SHOW STATUS LIKE 'handler_delete';
|
||||
SELECT COUNT(*) FROM t2;
|
||||
|
||||
DROP TRIGGER trg_t1;
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
#
|
||||
# Bug #23651 "Server crashes when trigger which uses stored function
|
||||
|
@ -434,7 +434,8 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
|
||||
byte *ref_pos,*next_pos,ref_buff[MAX_REFLENGTH];
|
||||
my_off_t record;
|
||||
TABLE *sort_form;
|
||||
volatile THD::killed_state *killed= ¤t_thd->killed;
|
||||
THD *thd= current_thd;
|
||||
volatile THD::killed_state *killed= &thd->killed;
|
||||
handler *file;
|
||||
MY_BITMAP *save_read_set, *save_write_set;
|
||||
DBUG_ENTER("find_all_keys");
|
||||
@ -547,6 +548,9 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
|
||||
}
|
||||
else
|
||||
file->unlock_row();
|
||||
/* It does not make sense to read more keys in case of a fatal error */
|
||||
if (thd->net.report_error)
|
||||
DBUG_RETURN(HA_POS_ERROR);
|
||||
}
|
||||
if (quick_select)
|
||||
{
|
||||
|
@ -1270,7 +1270,10 @@ void Item::split_sum_func2(THD *thd, Item **ref_pointer_array,
|
||||
if (type() == SUM_FUNC_ITEM && skip_registered &&
|
||||
((Item_sum *) this)->ref_by)
|
||||
return;
|
||||
if (type() != SUM_FUNC_ITEM && with_sum_func)
|
||||
if ((type() != SUM_FUNC_ITEM && with_sum_func) ||
|
||||
(type() == FUNC_ITEM &&
|
||||
(((Item_func *) this)->functype() == Item_func::ISNOTNULLTEST_FUNC ||
|
||||
((Item_func *) this)->functype() == Item_func::TRIG_COND_FUNC)))
|
||||
{
|
||||
/* Will split complicated items and ignore simple ones */
|
||||
split_sum_func(thd, ref_pointer_array, fields);
|
||||
|
@ -238,6 +238,10 @@ bool Item_subselect::exec()
|
||||
{
|
||||
int res;
|
||||
|
||||
if (thd->net.report_error)
|
||||
/* Do not execute subselect in case of a fatal error */
|
||||
return 1;
|
||||
|
||||
res= engine->exec();
|
||||
|
||||
if (engine_changed)
|
||||
|
@ -1007,7 +1007,8 @@ longlong Item_func_quarter::val_int()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
TIME ltime;
|
||||
(void) get_arg0_date(<ime, TIME_FUZZY_DATE);
|
||||
if (get_arg0_date(<ime, TIME_FUZZY_DATE))
|
||||
return 0;
|
||||
return (longlong) ((ltime.month+2)/3);
|
||||
}
|
||||
|
||||
@ -1647,6 +1648,7 @@ String *Item_func_sec_to_time::val_str(String *str)
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
TIME ltime;
|
||||
longlong arg_val= args[0]->val_int();
|
||||
|
||||
if ((null_value=args[0]->null_value) || str->alloc(19))
|
||||
{
|
||||
@ -1654,7 +1656,7 @@ String *Item_func_sec_to_time::val_str(String *str)
|
||||
return (String*) 0;
|
||||
}
|
||||
|
||||
sec_to_time(args[0]->val_int(), args[0]->unsigned_flag, <ime);
|
||||
sec_to_time(arg_val, args[0]->unsigned_flag, <ime);
|
||||
|
||||
make_time((DATE_TIME_FORMAT *) 0, <ime, str);
|
||||
return str;
|
||||
@ -1665,11 +1667,12 @@ longlong Item_func_sec_to_time::val_int()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
TIME ltime;
|
||||
longlong arg_val= args[0]->val_int();
|
||||
|
||||
if ((null_value=args[0]->null_value))
|
||||
return 0;
|
||||
|
||||
sec_to_time(args[0]->val_int(), args[0]->unsigned_flag, <ime);
|
||||
sec_to_time(arg_val, args[0]->unsigned_flag, <ime);
|
||||
|
||||
return (ltime.neg ? -1 : 1) *
|
||||
((ltime.hour)*10000 + ltime.minute*100 + ltime.second);
|
||||
|
@ -1151,7 +1151,8 @@ bool push_new_name_resolution_context(THD *thd,
|
||||
TABLE_LIST *left_op,
|
||||
TABLE_LIST *right_op);
|
||||
void add_join_on(TABLE_LIST *b,Item *expr);
|
||||
void add_join_natural(TABLE_LIST *a,TABLE_LIST *b,List<String> *using_fields);
|
||||
void add_join_natural(TABLE_LIST *a,TABLE_LIST *b,List<String> *using_fields,
|
||||
SELECT_LEX *lex);
|
||||
bool add_proc_to_list(THD *thd, Item *item);
|
||||
TABLE *unlink_open_table(THD *thd,TABLE *list,TABLE *find);
|
||||
void update_non_unique_table_error(TABLE_LIST *update,
|
||||
|
@ -219,6 +219,8 @@ public:
|
||||
}
|
||||
inline void merge_flags(SEL_ARG *arg) { maybe_flag|=arg->maybe_flag; }
|
||||
inline void maybe_smaller() { maybe_flag=1; }
|
||||
/* Return true iff it's a single-point null interval */
|
||||
inline bool is_null_interval() { return maybe_null && max_value[0] == 1; }
|
||||
inline int cmp_min_to_min(SEL_ARG* arg)
|
||||
{
|
||||
return sel_cmp(field,min_value, arg->min_value, min_flag, arg->min_flag);
|
||||
@ -560,6 +562,7 @@ public:
|
||||
bool is_ror_scan;
|
||||
/* Number of ranges in the last checked tree->key */
|
||||
uint n_ranges;
|
||||
uint8 first_null_comp; /* first null component if any, 0 - otherwise */
|
||||
};
|
||||
|
||||
class TABLE_READ_PLAN;
|
||||
@ -7016,6 +7019,7 @@ check_quick_select(PARAM *param,uint idx,SEL_ARG *tree, bool update_tbl_stats)
|
||||
DBUG_ENTER("check_quick_select");
|
||||
|
||||
param->is_ror_scan= FALSE;
|
||||
param->first_null_comp= 0;
|
||||
|
||||
if (!tree)
|
||||
DBUG_RETURN(HA_POS_ERROR); // Can't use it
|
||||
@ -7116,6 +7120,7 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree,
|
||||
ha_rows records=0, tmp;
|
||||
uint tmp_min_flag, tmp_max_flag, keynr, min_key_length, max_key_length;
|
||||
char *tmp_min_key, *tmp_max_key;
|
||||
uint8 save_first_null_comp= param->first_null_comp;
|
||||
|
||||
param->max_key_part=max(param->max_key_part,key_tree->part);
|
||||
if (key_tree->left != &null_element)
|
||||
@ -7153,6 +7158,9 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree,
|
||||
param->is_ror_scan= FALSE;
|
||||
}
|
||||
|
||||
if (!param->first_null_comp && key_tree->is_null_interval())
|
||||
param->first_null_comp= key_tree->part+1;
|
||||
|
||||
if (key_tree->next_key_part &&
|
||||
key_tree->next_key_part->part == key_tree->part+1 &&
|
||||
key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
|
||||
@ -7196,7 +7204,8 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree,
|
||||
(param->table->key_info[keynr].flags & (HA_NOSAME | HA_END_SPACE_KEY)) ==
|
||||
HA_NOSAME &&
|
||||
min_key_length == max_key_length &&
|
||||
!memcmp(param->min_key,param->max_key,min_key_length))
|
||||
!memcmp(param->min_key,param->max_key,min_key_length) &&
|
||||
!param->first_null_comp)
|
||||
{
|
||||
tmp=1; // Max one record
|
||||
param->n_ranges++;
|
||||
@ -7271,6 +7280,7 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree,
|
||||
return tmp;
|
||||
records+=tmp;
|
||||
}
|
||||
param->first_null_comp= save_first_null_comp;
|
||||
return records;
|
||||
}
|
||||
|
||||
|
@ -97,9 +97,9 @@ static ulonglong get_exact_record_count(TABLE_LIST *tables)
|
||||
GROUP BY part.
|
||||
|
||||
RETURN VALUES
|
||||
0 No errors
|
||||
1 if all items were resolved
|
||||
-1 on impossible conditions
|
||||
0 no errors
|
||||
1 if all items were resolved
|
||||
HA_ERR_KEY_NOT_FOUND on impossible conditions
|
||||
OR an error number from my_base.h HA_ERR_... if a deadlock or a lock
|
||||
wait timeout happens, for example
|
||||
*/
|
||||
@ -267,7 +267,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
|
||||
if (error)
|
||||
{
|
||||
if (error == HA_ERR_KEY_NOT_FOUND || error == HA_ERR_END_OF_FILE)
|
||||
return -1; // No rows matching WHERE
|
||||
return HA_ERR_KEY_NOT_FOUND; // No rows matching WHERE
|
||||
/* HA_ERR_LOCK_DEADLOCK or some other error */
|
||||
table->file->print_error(error, MYF(0));
|
||||
return(error);
|
||||
@ -354,7 +354,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
|
||||
if (error)
|
||||
{
|
||||
if (error == HA_ERR_KEY_NOT_FOUND || error == HA_ERR_END_OF_FILE)
|
||||
return -1; // No rows matching WHERE
|
||||
return HA_ERR_KEY_NOT_FOUND; // No rows matching WHERE
|
||||
/* HA_ERR_LOCK_DEADLOCK or some other error */
|
||||
table->file->print_error(error, MYF(0));
|
||||
return(error);
|
||||
|
@ -3764,7 +3764,7 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
|
||||
{
|
||||
List_iterator_fast<Natural_join_column>
|
||||
field_it(*(table_ref->join_columns));
|
||||
Natural_join_column *nj_col;
|
||||
Natural_join_column *nj_col, *curr_nj_col;
|
||||
Field *found_field;
|
||||
Query_arena *arena, backup;
|
||||
DBUG_ENTER("find_field_in_natural_join");
|
||||
@ -3776,14 +3776,21 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
|
||||
LINT_INIT(arena);
|
||||
LINT_INIT(found_field);
|
||||
|
||||
for (;;)
|
||||
for (nj_col= NULL, curr_nj_col= field_it++; curr_nj_col;
|
||||
curr_nj_col= field_it++)
|
||||
{
|
||||
if (!(nj_col= field_it++))
|
||||
DBUG_RETURN(NULL);
|
||||
|
||||
if (!my_strcasecmp(system_charset_info, nj_col->name(), name))
|
||||
break;
|
||||
if (!my_strcasecmp(system_charset_info, curr_nj_col->name(), name))
|
||||
{
|
||||
if (nj_col)
|
||||
{
|
||||
my_error(ER_NON_UNIQ_ERROR, MYF(0), name, thd->where);
|
||||
DBUG_RETURN(NULL);
|
||||
}
|
||||
nj_col= curr_nj_col;
|
||||
}
|
||||
}
|
||||
if (!nj_col)
|
||||
DBUG_RETURN(NULL);
|
||||
|
||||
if (nj_col->view_field)
|
||||
{
|
||||
@ -4684,9 +4691,16 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
|
||||
{
|
||||
bool found= FALSE;
|
||||
const char *field_name_1;
|
||||
/* true if field_name_1 is a member of using_fields */
|
||||
bool is_using_column_1;
|
||||
if (!(nj_col_1= it_1.get_or_create_column_ref(leaf_1)))
|
||||
goto err;
|
||||
field_name_1= nj_col_1->name();
|
||||
is_using_column_1= using_fields &&
|
||||
test_if_string_in_list(field_name_1, using_fields);
|
||||
DBUG_PRINT ("info", ("field_name_1=%s.%s",
|
||||
nj_col_1->table_name() ? nj_col_1->table_name() : "",
|
||||
field_name_1));
|
||||
|
||||
/*
|
||||
Find a field with the same name in table_ref_2.
|
||||
@ -4703,6 +4717,10 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
|
||||
if (!(cur_nj_col_2= it_2.get_or_create_column_ref(leaf_2)))
|
||||
goto err;
|
||||
cur_field_name_2= cur_nj_col_2->name();
|
||||
DBUG_PRINT ("info", ("cur_field_name_2=%s.%s",
|
||||
cur_nj_col_2->table_name() ?
|
||||
cur_nj_col_2->table_name() : "",
|
||||
cur_field_name_2));
|
||||
|
||||
/*
|
||||
Compare the two columns and check for duplicate common fields.
|
||||
@ -4710,10 +4728,16 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
|
||||
table_ref_2 (then found == TRUE), or if a field in table_ref_2
|
||||
was already matched by some previous field in table_ref_1
|
||||
(then cur_nj_col_2->is_common == TRUE).
|
||||
Note that it is too early to check the columns outside of the
|
||||
USING list for ambiguity because they are not actually "referenced"
|
||||
here. These columns must be checked only on unqualified reference
|
||||
by name (e.g. in SELECT list).
|
||||
*/
|
||||
if (!my_strcasecmp(system_charset_info, field_name_1, cur_field_name_2))
|
||||
{
|
||||
if (found || cur_nj_col_2->is_common)
|
||||
DBUG_PRINT ("info", ("match c1.is_common=%d", nj_col_1->is_common));
|
||||
if (cur_nj_col_2->is_common ||
|
||||
(found && (!using_fields || is_using_column_1)))
|
||||
{
|
||||
my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1, thd->where);
|
||||
goto err;
|
||||
@ -4739,9 +4763,7 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
|
||||
clause (if present), mark them as common fields, and add a new
|
||||
equi-join condition to the ON clause.
|
||||
*/
|
||||
if (nj_col_2 &&
|
||||
(!using_fields ||
|
||||
test_if_string_in_list(field_name_1, using_fields)))
|
||||
if (nj_col_2 && (!using_fields ||is_using_column_1))
|
||||
{
|
||||
Item *item_1= nj_col_1->create_item(thd);
|
||||
Item *item_2= nj_col_2->create_item(thd);
|
||||
@ -4796,6 +4818,13 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
|
||||
eq_cond);
|
||||
|
||||
nj_col_1->is_common= nj_col_2->is_common= TRUE;
|
||||
DBUG_PRINT ("info", ("%s.%s and %s.%s are common",
|
||||
nj_col_1->table_name() ?
|
||||
nj_col_1->table_name() : "",
|
||||
nj_col_1->name(),
|
||||
nj_col_2->table_name() ?
|
||||
nj_col_2->table_name() : "",
|
||||
nj_col_2->name()));
|
||||
|
||||
if (field_1)
|
||||
{
|
||||
@ -5462,7 +5491,12 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
|
||||
get_key_map_from_key_list(&map, table, table_list->use_index);
|
||||
if (map.is_set_all())
|
||||
DBUG_RETURN(1);
|
||||
table->keys_in_use_for_query=map;
|
||||
/*
|
||||
Don't introduce keys in keys_in_use_for_query that weren't there
|
||||
before. FORCE/USE INDEX should not add keys, it should only remove
|
||||
all keys except the key(s) specified in the hint.
|
||||
*/
|
||||
table->keys_in_use_for_query.intersect(map);
|
||||
}
|
||||
if (table_list->ignore_index)
|
||||
{
|
||||
|
@ -69,13 +69,13 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
||||
Test if the user wants to delete all rows and deletion doesn't have
|
||||
any side-effects (because of triggers), so we can use optimized
|
||||
handler::delete_all_rows() method.
|
||||
|
||||
If row-based replication is used, we also delete the table row by
|
||||
row.
|
||||
We implement fast TRUNCATE for InnoDB even if triggers are present.
|
||||
TRUNCATE ignores triggers.
|
||||
*/
|
||||
if (!using_limit && const_cond && (!conds || conds->val_int()) &&
|
||||
!(specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE)) &&
|
||||
!(table->triggers && table->triggers->has_delete_triggers()) &&
|
||||
(thd->lex->sql_command == SQLCOM_TRUNCATE ||
|
||||
!(table->triggers && table->triggers->has_delete_triggers())) &&
|
||||
!thd->current_stmt_binlog_row_based)
|
||||
{
|
||||
/* Update the table->file->stats.records number */
|
||||
|
@ -620,6 +620,21 @@ public:
|
||||
/* index in the select list of the expression currently being fixed */
|
||||
int cur_pos_in_select_list;
|
||||
|
||||
List<udf_func> udf_list; /* udf function calls stack */
|
||||
/*
|
||||
This is a copy of the original JOIN USING list that comes from
|
||||
the parser. The parser :
|
||||
1. Sets the natural_join of the second TABLE_LIST in the join
|
||||
and the st_select_lex::prev_join_using.
|
||||
2. Makes a parent TABLE_LIST and sets its is_natural_join/
|
||||
join_using_fields members.
|
||||
3. Uses the wrapper TABLE_LIST as a table in the upper level.
|
||||
We cannot assign directly to join_using_fields in the parser because
|
||||
at stage (1.) the parent TABLE_LIST is not constructed yet and
|
||||
the assignment will override the JOIN USING fields of the lower level
|
||||
joins on the right.
|
||||
*/
|
||||
List<String> *prev_join_using;
|
||||
void init_query();
|
||||
void init_select();
|
||||
st_select_lex_unit* master_unit();
|
||||
|
@ -3555,7 +3555,7 @@ end_with_restore_list:
|
||||
break;
|
||||
}
|
||||
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
||||
if (check_one_table_access(thd, DELETE_ACL, all_tables))
|
||||
if (check_one_table_access(thd, DROP_ACL, all_tables))
|
||||
goto error;
|
||||
/*
|
||||
Don't allow this within a transaction because we want to use
|
||||
@ -6666,11 +6666,8 @@ TABLE_LIST *st_select_lex::nest_last_join(THD *thd)
|
||||
If this is a JOIN ... USING, move the list of joined fields to the
|
||||
table reference that describes the join.
|
||||
*/
|
||||
if (table->join_using_fields)
|
||||
{
|
||||
ptr->join_using_fields= table->join_using_fields;
|
||||
table->join_using_fields= NULL;
|
||||
}
|
||||
if (prev_join_using)
|
||||
ptr->join_using_fields= prev_join_using;
|
||||
}
|
||||
}
|
||||
join_list->push_front(ptr);
|
||||
@ -6926,6 +6923,7 @@ void add_join_on(TABLE_LIST *b, Item *expr)
|
||||
a Left join argument
|
||||
b Right join argument
|
||||
using_fields Field names from USING clause
|
||||
lex The current st_select_lex
|
||||
|
||||
IMPLEMENTATION
|
||||
This function marks that table b should be joined with a either via
|
||||
@ -6954,10 +6952,11 @@ void add_join_on(TABLE_LIST *b, Item *expr)
|
||||
None
|
||||
*/
|
||||
|
||||
void add_join_natural(TABLE_LIST *a, TABLE_LIST *b, List<String> *using_fields)
|
||||
void add_join_natural(TABLE_LIST *a, TABLE_LIST *b, List<String> *using_fields,
|
||||
SELECT_LEX *lex)
|
||||
{
|
||||
b->natural_join= a;
|
||||
b->join_using_fields= using_fields;
|
||||
lex->prev_join_using= using_fields;
|
||||
}
|
||||
|
||||
|
||||
|
@ -717,11 +717,20 @@ JOIN::optimize()
|
||||
{
|
||||
int res;
|
||||
/*
|
||||
opt_sum_query() returns -1 if no rows match to the WHERE conditions,
|
||||
or 1 if all items were resolved, or 0, or an error number HA_ERR_...
|
||||
opt_sum_query() returns HA_ERR_KEY_NOT_FOUND if no rows match
|
||||
to the WHERE conditions,
|
||||
or 1 if all items were resolved,
|
||||
or 0, or an error number HA_ERR_...
|
||||
*/
|
||||
if ((res=opt_sum_query(select_lex->leaf_tables, all_fields, conds)))
|
||||
{
|
||||
if (res == HA_ERR_KEY_NOT_FOUND)
|
||||
{
|
||||
DBUG_PRINT("info",("No matching min/max row"));
|
||||
zero_result_cause= "No matching min/max row";
|
||||
error=0;
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
if (res > 1)
|
||||
{
|
||||
thd->fatal_error();
|
||||
@ -729,13 +738,6 @@ JOIN::optimize()
|
||||
DBUG_PRINT("error",("Error from opt_sum_query"));
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if (res < 0)
|
||||
{
|
||||
DBUG_PRINT("info",("No matching min/max row"));
|
||||
zero_result_cause= "No matching min/max row";
|
||||
error=0;
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
DBUG_PRINT("info",("Select tables optimized away"));
|
||||
zero_result_cause= "Select tables optimized away";
|
||||
tables_list= 0; // All tables resolved
|
||||
@ -865,6 +867,13 @@ JOIN::optimize()
|
||||
{
|
||||
ORDER *org_order= order;
|
||||
order=remove_const(this, order,conds,1, &simple_order);
|
||||
if (thd->net.report_error)
|
||||
{
|
||||
error= 1;
|
||||
DBUG_PRINT("error",("Error from remove_const"));
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
/*
|
||||
If we are using ORDER BY NULL or ORDER BY const_expression,
|
||||
return result in any order (even if we are using a GROUP BY)
|
||||
@ -874,10 +883,11 @@ JOIN::optimize()
|
||||
}
|
||||
/*
|
||||
Check if we can optimize away GROUP BY/DISTINCT.
|
||||
We can do that if there are no aggregate functions and the
|
||||
We can do that if there are no aggregate functions, the
|
||||
fields in DISTINCT clause (if present) and/or columns in GROUP BY
|
||||
(if present) contain direct references to all key parts of
|
||||
an unique index (in whatever order).
|
||||
an unique index (in whatever order) and if the key parts of the
|
||||
unique index cannot contain NULLs.
|
||||
Note that the unique keys for DISTINCT and GROUP BY should not
|
||||
be the same (as long as they are unique).
|
||||
|
||||
@ -972,6 +982,12 @@ JOIN::optimize()
|
||||
group_list= remove_const(this, (old_group_list= group_list), conds,
|
||||
rollup.state == ROLLUP::STATE_NONE,
|
||||
&simple_group);
|
||||
if (thd->net.report_error)
|
||||
{
|
||||
error= 1;
|
||||
DBUG_PRINT("error",("Error from remove_const"));
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if (old_group_list && !group_list)
|
||||
select_distinct= 0;
|
||||
}
|
||||
@ -988,6 +1004,12 @@ JOIN::optimize()
|
||||
{
|
||||
group_list= procedure->group= remove_const(this, procedure->group, conds,
|
||||
1, &simple_group);
|
||||
if (thd->net.report_error)
|
||||
{
|
||||
error= 1;
|
||||
DBUG_PRINT("error",("Error from remove_const"));
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
calc_group_buffer(this, group_list);
|
||||
}
|
||||
|
||||
@ -6578,6 +6600,8 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond,
|
||||
*simple_order=0; // Must do a temp table to sort
|
||||
else if (!(order_tables & not_const_tables))
|
||||
{
|
||||
if (order->item[0]->with_subselect)
|
||||
order->item[0]->val_str(&order->item[0]->str_value);
|
||||
DBUG_PRINT("info",("removing: %s", order->item[0]->full_name()));
|
||||
continue; // skip const item
|
||||
}
|
||||
@ -12107,7 +12131,7 @@ test_if_subkey(ORDER *order, TABLE *table, uint ref, uint ref_key_parts,
|
||||
|
||||
|
||||
/*
|
||||
Check if GROUP BY/DISTINCT can be optimized away because the set is
|
||||
Check if GROUP BY/DISTINCT can be optimized away because the set is
|
||||
already known to be distinct.
|
||||
|
||||
SYNOPSIS
|
||||
@ -12115,7 +12139,7 @@ test_if_subkey(ORDER *order, TABLE *table, uint ref, uint ref_key_parts,
|
||||
table The table to operate on.
|
||||
find_func function to iterate over the list and search
|
||||
for a field
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
Used in removing the GROUP BY/DISTINCT of the following types of
|
||||
statements:
|
||||
@ -12126,12 +12150,13 @@ test_if_subkey(ORDER *order, TABLE *table, uint ref, uint ref_key_parts,
|
||||
then <any combination of a,b,c>,{whatever} is also distinct
|
||||
|
||||
This function checks if all the key parts of any of the unique keys
|
||||
of the table are referenced by a list : either the select list
|
||||
of the table are referenced by a list : either the select list
|
||||
through find_field_in_item_list or GROUP BY list through
|
||||
find_field_in_order_list.
|
||||
If the above holds then we can safely remove the GROUP BY/DISTINCT,
|
||||
If the above holds and the key parts cannot contain NULLs then we
|
||||
can safely remove the GROUP BY/DISTINCT,
|
||||
as no result set can be more distinct than an unique key.
|
||||
|
||||
|
||||
RETURN VALUE
|
||||
1 found
|
||||
0 not found.
|
||||
@ -12154,7 +12179,8 @@ list_contains_unique_index(TABLE *table,
|
||||
key_part < key_part_end;
|
||||
key_part++)
|
||||
{
|
||||
if (!find_func(key_part->field, data))
|
||||
if (key_part->field->maybe_null() ||
|
||||
!find_func(key_part->field, data))
|
||||
break;
|
||||
}
|
||||
if (key_part == key_part_end)
|
||||
@ -12262,13 +12288,14 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
|
||||
DBUG_ENTER("test_if_skip_sort_order");
|
||||
LINT_INIT(ref_key_parts);
|
||||
|
||||
/* Check which keys can be used to resolve ORDER BY. */
|
||||
usable_keys= table->keys_in_use_for_query;
|
||||
|
||||
/*
|
||||
Check which keys can be used to resolve ORDER BY.
|
||||
We must not try to use disabled keys.
|
||||
Keys disabled by ALTER TABLE ... DISABLE KEYS should have already
|
||||
been taken into account.
|
||||
*/
|
||||
usable_keys= table->s->keys_in_use;
|
||||
/* we must not consider keys that are disabled by IGNORE INDEX */
|
||||
usable_keys.intersect(table->keys_in_use_for_query);
|
||||
DBUG_ASSERT(usable_keys.is_subset(table->s->keys_in_use));
|
||||
|
||||
for (ORDER *tmp_order=order; tmp_order ; tmp_order=tmp_order->next)
|
||||
{
|
||||
|
@ -5077,6 +5077,7 @@ bool get_schema_tables_result(JOIN *join)
|
||||
|
||||
if (is_subselect) // is subselect
|
||||
{
|
||||
table_list->table->file->extra(HA_EXTRA_NO_CACHE);
|
||||
table_list->table->file->extra(HA_EXTRA_RESET_STATE);
|
||||
table_list->table->file->delete_all_rows();
|
||||
free_io_cache(table_list->table);
|
||||
|
@ -7116,11 +7116,11 @@ join_table:
|
||||
YYERROR_UNLESS($1 && $3);
|
||||
}
|
||||
'(' using_list ')'
|
||||
{ add_join_natural($1,$3,$7); $$=$3; }
|
||||
{ add_join_natural($1,$3,$7,Select); $$=$3; }
|
||||
| table_ref NATURAL JOIN_SYM table_factor
|
||||
{
|
||||
YYERROR_UNLESS($1 && ($$=$4));
|
||||
add_join_natural($1,$4,NULL);
|
||||
add_join_natural($1,$4,NULL,Select);
|
||||
}
|
||||
|
||||
/* LEFT JOIN variants */
|
||||
@ -7147,11 +7147,15 @@ join_table:
|
||||
YYERROR_UNLESS($1 && $5);
|
||||
}
|
||||
USING '(' using_list ')'
|
||||
{ add_join_natural($1,$5,$9); $5->outer_join|=JOIN_TYPE_LEFT; $$=$5; }
|
||||
{
|
||||
add_join_natural($1,$5,$9,Select);
|
||||
$5->outer_join|=JOIN_TYPE_LEFT;
|
||||
$$=$5;
|
||||
}
|
||||
| table_ref NATURAL LEFT opt_outer JOIN_SYM table_factor
|
||||
{
|
||||
YYERROR_UNLESS($1 && $6);
|
||||
add_join_natural($1,$6,NULL);
|
||||
add_join_natural($1,$6,NULL,Select);
|
||||
$6->outer_join|=JOIN_TYPE_LEFT;
|
||||
$$=$6;
|
||||
}
|
||||
@ -7185,12 +7189,12 @@ join_table:
|
||||
LEX *lex= Lex;
|
||||
if (!($$= lex->current_select->convert_right_join()))
|
||||
YYABORT;
|
||||
add_join_natural($$,$5,$9);
|
||||
add_join_natural($$,$5,$9,Select);
|
||||
}
|
||||
| table_ref NATURAL RIGHT opt_outer JOIN_SYM table_factor
|
||||
{
|
||||
YYERROR_UNLESS($1 && $6);
|
||||
add_join_natural($6,$1,NULL);
|
||||
add_join_natural($6,$1,NULL,Select);
|
||||
LEX *lex= Lex;
|
||||
if (!($$= lex->current_select->convert_right_join()))
|
||||
YYABORT;
|
||||
|
@ -3430,6 +3430,7 @@ Field *Natural_join_column::field()
|
||||
|
||||
const char *Natural_join_column::table_name()
|
||||
{
|
||||
DBUG_ASSERT(table_ref);
|
||||
return table_ref->alias;
|
||||
}
|
||||
|
||||
|
23
sql/table.h
23
sql/table.h
@ -158,7 +158,12 @@ typedef struct st_table_share
|
||||
LEX_STRING path; /* Path to .frm file (from datadir) */
|
||||
LEX_STRING normalized_path; /* unpack_filename(path) */
|
||||
LEX_STRING connect_string;
|
||||
key_map keys_in_use; /* Keys in use for table */
|
||||
|
||||
/*
|
||||
Set of keys in use, implemented as a Bitmap.
|
||||
Excludes keys disabled by ALTER TABLE ... DISABLE KEYS.
|
||||
*/
|
||||
key_map keys_in_use;
|
||||
key_map keys_for_keyread;
|
||||
ha_rows min_rows, max_rows; /* create information */
|
||||
ulong avg_row_length; /* create information */
|
||||
@ -313,7 +318,21 @@ struct st_table {
|
||||
byte *write_row_record; /* Used as optimisation in
|
||||
THD::write_row */
|
||||
byte *insert_values; /* used by INSERT ... UPDATE */
|
||||
key_map quick_keys, used_keys, keys_in_use_for_query, merge_keys;
|
||||
key_map quick_keys, used_keys;
|
||||
|
||||
/*
|
||||
A set of keys that can be used in the query that references this
|
||||
table.
|
||||
|
||||
All indexes disabled on the table's TABLE_SHARE (see TABLE::s) will be
|
||||
subtracted from this set upon instantiation. Thus for any TABLE t it holds
|
||||
that t.keys_in_use_for_query is a subset of t.s.keys_in_use. Generally we
|
||||
must not introduce any new keys here (see setup_tables).
|
||||
|
||||
The set is implemented as a bitmap.
|
||||
*/
|
||||
key_map keys_in_use_for_query;
|
||||
key_map merge_keys;
|
||||
KEY *key_info; /* data of keys in database */
|
||||
|
||||
Field *next_number_field; /* Set if next_number is activated */
|
||||
|
Loading…
x
Reference in New Issue
Block a user