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:
unknown 2007-02-02 13:57:19 +01:00
commit 13390debf6
42 changed files with 809 additions and 81 deletions

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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
#

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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) ;

View File

@ -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;

View File

@ -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
#

View File

@ -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;

View File

@ -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.

View File

@ -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

View File

@ -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= &current_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)
{

View File

@ -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);

View File

@ -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)

View File

@ -1007,7 +1007,8 @@ longlong Item_func_quarter::val_int()
{
DBUG_ASSERT(fixed == 1);
TIME ltime;
(void) get_arg0_date(&ltime, TIME_FUZZY_DATE);
if (get_arg0_date(&ltime, 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, &ltime);
sec_to_time(arg_val, args[0]->unsigned_flag, &ltime);
make_time((DATE_TIME_FORMAT *) 0, &ltime, 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, &ltime);
sec_to_time(arg_val, args[0]->unsigned_flag, &ltime);
return (ltime.neg ? -1 : 1) *
((ltime.hour)*10000 + ltime.minute*100 + ltime.second);

View File

@ -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,

View File

@ -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;
}

View File

@ -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);

View File

@ -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)
{

View File

@ -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 */

View File

@ -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();

View File

@ -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;
}

View File

@ -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)
{

View File

@ -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);

View File

@ -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;

View File

@ -3430,6 +3430,7 @@ Field *Natural_join_column::field()
const char *Natural_join_column::table_name()
{
DBUG_ASSERT(table_ref);
return table_ref->alias;
}

View File

@ -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 */