Browse Source

5.3 merge

pull/57/head
Sergei Golubchik 14 years ago
parent
commit
867296c3ed
  1. 8
      mysql-test/r/innodb_ext_key.result
  2. 194
      mysql-test/r/subselect_sj2.result
  3. 16
      mysql-test/r/subselect_sj2_jcl6,innodb_plugin.rdiff
  4. 204
      mysql-test/r/subselect_sj2_jcl6.result
  5. 194
      mysql-test/r/subselect_sj2_mat.result
  6. 30
      mysql-test/suite/innodb/r/innodb-autoinc-61209.result
  7. 178
      mysql-test/suite/innodb/r/innodb-autoinc.result
  8. 61
      mysql-test/suite/innodb/t/innodb-autoinc-61209.test
  9. 138
      mysql-test/t/subselect_sj2.test
  10. 3
      mysys/thr_lock.c
  11. 95
      scripts/mytop.sh
  12. 4
      sql/item_cmpfunc.cc
  13. 11
      sql/item_cmpfunc.h
  14. 263
      sql/opt_subselect.cc
  15. 18
      sql/sql_select.cc
  16. 67
      storage/innobase/handler/ha_innodb.cc
  17. 67
      storage/xtradb/handler/ha_innodb.cc

8
mysql-test/r/innodb_ext_key.result

@ -681,9 +681,9 @@ SELECT a FROM t1 AS t, t2
WHERE c = a AND b IN (SELECT b FROM t1, t2 WHERE b = t.b);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t index a,b b 7 NULL 10 Using index
1 PRIMARY t1 ref b b 3 test.t.b 2 Using index; FirstMatch(t)
1 PRIMARY t1 ref b b 3 test.t.b 2 Using index
1 PRIMARY t2 index NULL PRIMARY 4 NULL 11 Using index; FirstMatch(t)
1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t.a 1 Using index
1 PRIMARY t2 index NULL PRIMARY 4 NULL 11 Using index; FirstMatch(t2)
SELECT a FROM t1 AS t, t2
WHERE c = a AND b IN (SELECT b FROM t1, t2 WHERE b = t.b);
a
@ -694,9 +694,9 @@ SELECT a FROM t1 AS t, t2
WHERE c = a AND b IN (SELECT b FROM t1, t2 WHERE b = t.b);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t index a,b b 7 NULL 10 Using index
1 PRIMARY t1 ref b b 3 test.t.b 2 Using index; FirstMatch(t)
1 PRIMARY t1 ref b b 3 test.t.b 2 Using index
1 PRIMARY t2 index NULL PRIMARY 4 NULL 11 Using index; FirstMatch(t)
1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t.a 1 Using index
1 PRIMARY t2 index NULL PRIMARY 4 NULL 11 Using index; FirstMatch(t2)
SELECT a FROM t1 AS t, t2
WHERE c = a AND b IN (SELECT b FROM t1, t2 WHERE b = t.b);
a

194
mysql-test/r/subselect_sj2.result

@ -900,5 +900,199 @@ a b c
3 1 1
4 1 1
DROP TABLE t1,t2;
#
# BUG#962667: Assertion `0' failed in QUICK_INDEX_SORT_SELECT::need_sorted_output()
# with index_merge+index_merge_sort_union+loosescan+semijoin
#
CREATE TABLE t1 (
a INT, b VARCHAR(1), c INT,
KEY(a), KEY(b)
) ENGINE=InnoDB;
INSERT INTO t1 VALUES
(1,'v',9),(2,'v',8),(3,'c',7),(4,'m',6),(5,'x',5),
(6,'i',4),(7,'e',3),(8,'p',2),(9,'s',1),(10,'j',9),
(11,'z',8),(12,'c',7),(13,'a',6),(14,'q',5),(15,'y',4),
(16,'n',3),(17,'r',2),(18,'v',1),(19,'p',0);
CREATE TABLE t2 (
pk INT, d VARCHAR(1), e INT,
PRIMARY KEY(pk), KEY(d,e)
) ENGINE=InnoDB;
INSERT INTO t2 VALUES
(1,'x',1),(2,'d',2),(3,'r',3),(4,'f',4),(5,'y',5),
(6,'u',6),(7,'m',7),(8,'k',8),(9,'o',9),(10,'w',1),
(11,'m',2),(12,'q',3),(13,'m',4),(14,'d',5),
(15,'g',6),(16,'x',7),(17,'f',8);
explain
SELECT * FROM t1 WHERE b IN (
SELECT d FROM t2, t1
WHERE a = d AND ( pk < 2 OR d = 'z' )
);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL b NULL NULL NULL 19
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
2 MATERIALIZED t2 index PRIMARY,d d 9 NULL 17 Using where; Using index
2 MATERIALIZED t1 ref a a 5 test.t2.d 1 Using where; Using index
SELECT * FROM t1 WHERE b IN (
SELECT d FROM t2, t1
WHERE a = d AND ( pk < 2 OR d = 'z' )
);
a b c
DROP TABLE t1, t2;
#
# BUG#951937: Wrong result (missing rows) with semijoin+materialization, IN subquery, InnoDB, TEMPTABLE view
#
CREATE TABLE t1 (
a VARCHAR(1),
b VARCHAR(1) NOT NULL,
KEY(a)
) ENGINE=InnoDB;
INSERT INTO t1 VALUES
('j','j'),('v','v'),('c','c'),('m','m'),('d','d'),
('y','y'),('t','t'),('d','d'),('s','s'),('r','r'),
('m','m'),('b','b'),('x','x'),('g','g'),('p','p'),
('q','q'),('w','w'),('d','d'),('e','e');
CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
# This query returned 6 rows instead of 19
SELECT * FROM v1
WHERE ( a, a ) IN (
SELECT alias2.b, alias2.a
FROM t1 AS alias1, t1 AS alias2
WHERE alias2.b = alias1.a
AND ( alias1.b >= alias1.a OR alias2.b = 'z' )
);
a b
b b
c c
d d
d d
d d
e e
g g
j j
m m
m m
p p
q q
r r
s s
t t
v v
w w
x x
y y
# Another testcase, without the VIEW:
CREATE TABLE t2 (a VARCHAR(1), b VARCHAR(1) NOT NULL, KEY(a)) ENGINE=InnoDB;
INSERT INTO t2 SELECT * FROM t1;
INSERT INTO t2 SELECT * FROM t1;
EXPLAIN
SELECT * FROM t2
WHERE (a, a) IN (SELECT alias2.b, alias2.a FROM t1 AS alias1, t1 AS alias2
WHERE
alias2.b = alias1.a AND
(alias1.b >= alias1.a OR alias2.b = 'z'));
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 19
1 PRIMARY t2 ref a a 4 test.alias1.a 1
2 MATERIALIZED alias1 ALL a NULL NULL NULL 19 Using where
2 MATERIALIZED alias2 ref a a 4 test.alias1.a 1 Using where
SELECT * FROM t2
WHERE (a, a) IN (SELECT alias2.b, alias2.a FROM t1 AS alias1, t1 AS alias2
WHERE
alias2.b = alias1.a AND
(alias1.b >= alias1.a OR alias2.b = 'z'));
a b
b b
b b
c c
c c
d d
d d
d d
d d
d d
d d
e e
e e
g g
g g
j j
j j
m m
m m
m m
m m
p p
p p
q q
q q
r r
r r
s s
s s
t t
t t
v v
v v
w w
w w
x x
x x
y y
y y
DROP VIEW v1;
DROP TABLE t1, t2;
#
# BUG#965872: Server crashes in embedding_sjm on a simple 1-table select with AND and OR
# (this is a regression caused by the fix for BUG#951937)
CREATE TABLE t1 ( a INT, b INT, c INT, d INT );
INSERT INTO t1 VALUES (4,2,8,9),(4,2,7,8);
SELECT * FROM t1
WHERE a = d AND ( b = 50 AND b = d OR a = c );
a b c d
DROP TABLE t1;
#
# BUG#951283: Wrong result (missing rows) with semijoin+firstmatch, IN/ANY subquery
#
set @tmp_951283=@@optimizer_prune_level;
SET optimizer_prune_level=0;
CREATE TABLE t1 ( a INT ) ENGINE=InnoDB;
INSERT INTO t1 VALUES
(10),(11),(12),(13),(14),(15),(16),
(17),(18),(19),(20),(21),(22),(23);
CREATE TABLE t2 (
b INT PRIMARY KEY,
c VARCHAR(1),
d VARCHAR(1),
KEY(c)
) ENGINE=InnoDB;
INSERT INTO t2 VALUES
(1,'j','j'),(2,'v','v'),(3,'c','c'),(4,'m','m'),
(5,'d','d'),(6,'d','d'),(7,'y','y'),(8,'t','t'),
(9,'d','d'),(10,'s','s'),(11,'r','r'),(12,'m','m'),
(13,'b','b'),(14,'x','x'),(15,'g','g'),(16,'p','p'),
(17,'q','q'),(18,'w','w'),(19,'d','d');
EXPLAIN
SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3
WHERE alias3.d IN (
SELECT alias4.c FROM t2 AS alias4, t2 AS alias5
WHERE alias5.b = alias4.b
AND ( alias5.b >= alias3.b OR alias5.c != alias3.c )
);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL 19 Using where
1 PRIMARY alias4 ref PRIMARY,c c 4 test.alias3.d 1 Using index
1 PRIMARY alias5 eq_ref PRIMARY PRIMARY 4 test.alias4.b 1 Using where; FirstMatch(alias3)
1 PRIMARY alias2 ALL NULL NULL NULL NULL 14 Using join buffer (flat, BNL join)
1 PRIMARY alias1 ALL NULL NULL NULL NULL 14 Using join buffer (flat, BNL join)
SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3
WHERE alias3.d IN (
SELECT alias4.c FROM t2 AS alias4, t2 AS alias5
WHERE alias5.b = alias4.b
AND ( alias5.b >= alias3.b OR alias5.c != alias3.c )
);
COUNT(*)
3724
set optimizer_prune_level=@tmp_951283;
DROP TABLE t1,t2;
# This must be the last in the file:
set optimizer_switch=@subselect_sj2_tmp;

16
mysql-test/r/subselect_sj2_jcl6,innodb_plugin.rdiff

@ -1,5 +1,5 @@
--- r/subselect_sj2_jcl6.result 2012-01-11 18:05:14.000000000 +0100
+++ r/subselect_sj2_jcl6.reject 2012-02-07 12:52:32.000000000 +0100
--- r/subselect_sj2_jcl6.result 2012-03-28 20:10:41.000000000 +0200
+++ r/subselect_sj2_jcl6,innodb_plugin.reject 2012-03-28 20:21:14.000000000 +0200
@@ -81,7 +81,7 @@
explain select * from t3 where b in (select a from t1);
id select_type table type possible_keys key key_len ref rows Extra
@ -18,3 +18,15 @@
2 MATERIALIZED t0 ALL NULL NULL NULL NULL 10 Using where
select * from t3 where b in (select A.a+B.a from t0 A, t0 B where B.a<5);
a b pk1 pk2
@@ -1006,9 +1006,9 @@
(alias1.b >= alias1.a OR alias2.b = 'z'));
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 19
-1 PRIMARY t2 ref a a 4 test.alias1.a 1 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+1 PRIMARY t2 ref a a 4 test.alias1.a 1
2 MATERIALIZED alias1 ALL a NULL NULL NULL 19 Using where
-2 MATERIALIZED alias2 ref a a 4 test.alias1.a 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+2 MATERIALIZED alias2 ref a a 4 test.alias1.a 1 Using where
SELECT * FROM t2
WHERE (a, a) IN (SELECT alias2.b, alias2.a FROM t1 AS alias1, t1 AS alias2
WHERE

204
mysql-test/r/subselect_sj2_jcl6.result

@ -914,6 +914,200 @@ a b c
3 1 1
4 1 1
DROP TABLE t1,t2;
#
# BUG#962667: Assertion `0' failed in QUICK_INDEX_SORT_SELECT::need_sorted_output()
# with index_merge+index_merge_sort_union+loosescan+semijoin
#
CREATE TABLE t1 (
a INT, b VARCHAR(1), c INT,
KEY(a), KEY(b)
) ENGINE=InnoDB;
INSERT INTO t1 VALUES
(1,'v',9),(2,'v',8),(3,'c',7),(4,'m',6),(5,'x',5),
(6,'i',4),(7,'e',3),(8,'p',2),(9,'s',1),(10,'j',9),
(11,'z',8),(12,'c',7),(13,'a',6),(14,'q',5),(15,'y',4),
(16,'n',3),(17,'r',2),(18,'v',1),(19,'p',0);
CREATE TABLE t2 (
pk INT, d VARCHAR(1), e INT,
PRIMARY KEY(pk), KEY(d,e)
) ENGINE=InnoDB;
INSERT INTO t2 VALUES
(1,'x',1),(2,'d',2),(3,'r',3),(4,'f',4),(5,'y',5),
(6,'u',6),(7,'m',7),(8,'k',8),(9,'o',9),(10,'w',1),
(11,'m',2),(12,'q',3),(13,'m',4),(14,'d',5),
(15,'g',6),(16,'x',7),(17,'f',8);
explain
SELECT * FROM t1 WHERE b IN (
SELECT d FROM t2, t1
WHERE a = d AND ( pk < 2 OR d = 'z' )
);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL b NULL NULL NULL 19
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
2 MATERIALIZED t2 index PRIMARY,d d 9 NULL 17 Using where; Using index
2 MATERIALIZED t1 ref a a 5 test.t2.d 1 Using where; Using index
SELECT * FROM t1 WHERE b IN (
SELECT d FROM t2, t1
WHERE a = d AND ( pk < 2 OR d = 'z' )
);
a b c
DROP TABLE t1, t2;
#
# BUG#951937: Wrong result (missing rows) with semijoin+materialization, IN subquery, InnoDB, TEMPTABLE view
#
CREATE TABLE t1 (
a VARCHAR(1),
b VARCHAR(1) NOT NULL,
KEY(a)
) ENGINE=InnoDB;
INSERT INTO t1 VALUES
('j','j'),('v','v'),('c','c'),('m','m'),('d','d'),
('y','y'),('t','t'),('d','d'),('s','s'),('r','r'),
('m','m'),('b','b'),('x','x'),('g','g'),('p','p'),
('q','q'),('w','w'),('d','d'),('e','e');
CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
# This query returned 6 rows instead of 19
SELECT * FROM v1
WHERE ( a, a ) IN (
SELECT alias2.b, alias2.a
FROM t1 AS alias1, t1 AS alias2
WHERE alias2.b = alias1.a
AND ( alias1.b >= alias1.a OR alias2.b = 'z' )
);
a b
b b
c c
d d
d d
d d
e e
g g
j j
m m
m m
p p
q q
r r
s s
t t
v v
w w
x x
y y
# Another testcase, without the VIEW:
CREATE TABLE t2 (a VARCHAR(1), b VARCHAR(1) NOT NULL, KEY(a)) ENGINE=InnoDB;
INSERT INTO t2 SELECT * FROM t1;
INSERT INTO t2 SELECT * FROM t1;
EXPLAIN
SELECT * FROM t2
WHERE (a, a) IN (SELECT alias2.b, alias2.a FROM t1 AS alias1, t1 AS alias2
WHERE
alias2.b = alias1.a AND
(alias1.b >= alias1.a OR alias2.b = 'z'));
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 19
1 PRIMARY t2 ref a a 4 test.alias1.a 1 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
2 MATERIALIZED alias1 ALL a NULL NULL NULL 19 Using where
2 MATERIALIZED alias2 ref a a 4 test.alias1.a 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
SELECT * FROM t2
WHERE (a, a) IN (SELECT alias2.b, alias2.a FROM t1 AS alias1, t1 AS alias2
WHERE
alias2.b = alias1.a AND
(alias1.b >= alias1.a OR alias2.b = 'z'));
a b
b b
b b
c c
c c
d d
d d
d d
d d
d d
d d
e e
e e
g g
g g
j j
j j
m m
m m
m m
m m
p p
p p
q q
q q
r r
r r
s s
s s
t t
t t
v v
v v
w w
w w
x x
x x
y y
y y
DROP VIEW v1;
DROP TABLE t1, t2;
#
# BUG#965872: Server crashes in embedding_sjm on a simple 1-table select with AND and OR
# (this is a regression caused by the fix for BUG#951937)
CREATE TABLE t1 ( a INT, b INT, c INT, d INT );
INSERT INTO t1 VALUES (4,2,8,9),(4,2,7,8);
SELECT * FROM t1
WHERE a = d AND ( b = 50 AND b = d OR a = c );
a b c d
DROP TABLE t1;
#
# BUG#951283: Wrong result (missing rows) with semijoin+firstmatch, IN/ANY subquery
#
set @tmp_951283=@@optimizer_prune_level;
SET optimizer_prune_level=0;
CREATE TABLE t1 ( a INT ) ENGINE=InnoDB;
INSERT INTO t1 VALUES
(10),(11),(12),(13),(14),(15),(16),
(17),(18),(19),(20),(21),(22),(23);
CREATE TABLE t2 (
b INT PRIMARY KEY,
c VARCHAR(1),
d VARCHAR(1),
KEY(c)
) ENGINE=InnoDB;
INSERT INTO t2 VALUES
(1,'j','j'),(2,'v','v'),(3,'c','c'),(4,'m','m'),
(5,'d','d'),(6,'d','d'),(7,'y','y'),(8,'t','t'),
(9,'d','d'),(10,'s','s'),(11,'r','r'),(12,'m','m'),
(13,'b','b'),(14,'x','x'),(15,'g','g'),(16,'p','p'),
(17,'q','q'),(18,'w','w'),(19,'d','d');
EXPLAIN
SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3
WHERE alias3.d IN (
SELECT alias4.c FROM t2 AS alias4, t2 AS alias5
WHERE alias5.b = alias4.b
AND ( alias5.b >= alias3.b OR alias5.c != alias3.c )
);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL 19 Using where
1 PRIMARY alias4 ref PRIMARY,c c 4 test.alias3.d 1 Using index
1 PRIMARY alias5 eq_ref PRIMARY PRIMARY 4 test.alias4.b 1 Using where; FirstMatch(alias3)
1 PRIMARY alias2 ALL NULL NULL NULL NULL 14 Using join buffer (flat, BNL join)
1 PRIMARY alias1 ALL NULL NULL NULL NULL 14 Using join buffer (incremental, BNL join)
SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3
WHERE alias3.d IN (
SELECT alias4.c FROM t2 AS alias4, t2 AS alias5
WHERE alias5.b = alias4.b
AND ( alias5.b >= alias3.b OR alias5.c != alias3.c )
);
COUNT(*)
3724
set optimizer_prune_level=@tmp_951283;
DROP TABLE t1,t2;
# This must be the last in the file:
set optimizer_switch=@subselect_sj2_tmp;
#
@ -935,9 +1129,9 @@ SELECT t3.* FROM t1 JOIN t3 ON t3.b = t1.b
WHERE c IN (SELECT t4.b FROM t4 JOIN t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 1 Using where
1 PRIMARY t2 ALL NULL NULL NULL NULL 1 FirstMatch(t3)
1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join)
1 PRIMARY t4 ALL NULL NULL NULL NULL 2 Using where; FirstMatch(t3); Using join buffer (incremental, BNL join)
1 PRIMARY t1 ref b b 4 test.t3.b 1 Using index
1 PRIMARY t4 ALL NULL NULL NULL NULL 2 Using where; FirstMatch(t1)
SELECT t3.* FROM t1 JOIN t3 ON t3.b = t1.b
WHERE c IN (SELECT t4.b FROM t4 JOIN t2);
b c
@ -963,9 +1157,9 @@ EXPLAIN
SELECT * FROM t1, t2 WHERE b IN (SELECT a FROM t3, t4 WHERE b = pk);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 1
1 PRIMARY t4 ALL NULL NULL NULL NULL 1 Using where; FirstMatch(t2)
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t4.b 1 Using where; FirstMatch(t1)
1 PRIMARY t4 ALL NULL NULL NULL NULL 1 Using where
1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t4.b 1 Using where; FirstMatch(t2)
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
SELECT * FROM t1, t2 WHERE b IN (SELECT a FROM t3, t4 WHERE b = pk);
pk a b
1 6 8

194
mysql-test/r/subselect_sj2_mat.result

@ -902,6 +902,200 @@ a b c
3 1 1
4 1 1
DROP TABLE t1,t2;
#
# BUG#962667: Assertion `0' failed in QUICK_INDEX_SORT_SELECT::need_sorted_output()
# with index_merge+index_merge_sort_union+loosescan+semijoin
#
CREATE TABLE t1 (
a INT, b VARCHAR(1), c INT,
KEY(a), KEY(b)
) ENGINE=InnoDB;
INSERT INTO t1 VALUES
(1,'v',9),(2,'v',8),(3,'c',7),(4,'m',6),(5,'x',5),
(6,'i',4),(7,'e',3),(8,'p',2),(9,'s',1),(10,'j',9),
(11,'z',8),(12,'c',7),(13,'a',6),(14,'q',5),(15,'y',4),
(16,'n',3),(17,'r',2),(18,'v',1),(19,'p',0);
CREATE TABLE t2 (
pk INT, d VARCHAR(1), e INT,
PRIMARY KEY(pk), KEY(d,e)
) ENGINE=InnoDB;
INSERT INTO t2 VALUES
(1,'x',1),(2,'d',2),(3,'r',3),(4,'f',4),(5,'y',5),
(6,'u',6),(7,'m',7),(8,'k',8),(9,'o',9),(10,'w',1),
(11,'m',2),(12,'q',3),(13,'m',4),(14,'d',5),
(15,'g',6),(16,'x',7),(17,'f',8);
explain
SELECT * FROM t1 WHERE b IN (
SELECT d FROM t2, t1
WHERE a = d AND ( pk < 2 OR d = 'z' )
);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL b NULL NULL NULL 19
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
2 MATERIALIZED t2 index PRIMARY,d d 9 NULL 17 Using where; Using index
2 MATERIALIZED t1 ref a a 5 test.t2.d 1 Using where; Using index
SELECT * FROM t1 WHERE b IN (
SELECT d FROM t2, t1
WHERE a = d AND ( pk < 2 OR d = 'z' )
);
a b c
DROP TABLE t1, t2;
#
# BUG#951937: Wrong result (missing rows) with semijoin+materialization, IN subquery, InnoDB, TEMPTABLE view
#
CREATE TABLE t1 (
a VARCHAR(1),
b VARCHAR(1) NOT NULL,
KEY(a)
) ENGINE=InnoDB;
INSERT INTO t1 VALUES
('j','j'),('v','v'),('c','c'),('m','m'),('d','d'),
('y','y'),('t','t'),('d','d'),('s','s'),('r','r'),
('m','m'),('b','b'),('x','x'),('g','g'),('p','p'),
('q','q'),('w','w'),('d','d'),('e','e');
CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
# This query returned 6 rows instead of 19
SELECT * FROM v1
WHERE ( a, a ) IN (
SELECT alias2.b, alias2.a
FROM t1 AS alias1, t1 AS alias2
WHERE alias2.b = alias1.a
AND ( alias1.b >= alias1.a OR alias2.b = 'z' )
);
a b
b b
c c
d d
d d
d d
e e
g g
j j
m m
m m
p p
q q
r r
s s
t t
v v
w w
x x
y y
# Another testcase, without the VIEW:
CREATE TABLE t2 (a VARCHAR(1), b VARCHAR(1) NOT NULL, KEY(a)) ENGINE=InnoDB;
INSERT INTO t2 SELECT * FROM t1;
INSERT INTO t2 SELECT * FROM t1;
EXPLAIN
SELECT * FROM t2
WHERE (a, a) IN (SELECT alias2.b, alias2.a FROM t1 AS alias1, t1 AS alias2
WHERE
alias2.b = alias1.a AND
(alias1.b >= alias1.a OR alias2.b = 'z'));
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 19
1 PRIMARY t2 ref a a 4 test.alias1.a 1
2 MATERIALIZED alias1 ALL a NULL NULL NULL 19 Using where
2 MATERIALIZED alias2 ref a a 4 test.alias1.a 1 Using where
SELECT * FROM t2
WHERE (a, a) IN (SELECT alias2.b, alias2.a FROM t1 AS alias1, t1 AS alias2
WHERE
alias2.b = alias1.a AND
(alias1.b >= alias1.a OR alias2.b = 'z'));
a b
b b
b b
c c
c c
d d
d d
d d
d d
d d
d d
e e
e e
g g
g g
j j
j j
m m
m m
m m
m m
p p
p p
q q
q q
r r
r r
s s
s s
t t
t t
v v
v v
w w
w w
x x
x x
y y
y y
DROP VIEW v1;
DROP TABLE t1, t2;
#
# BUG#965872: Server crashes in embedding_sjm on a simple 1-table select with AND and OR
# (this is a regression caused by the fix for BUG#951937)
CREATE TABLE t1 ( a INT, b INT, c INT, d INT );
INSERT INTO t1 VALUES (4,2,8,9),(4,2,7,8);
SELECT * FROM t1
WHERE a = d AND ( b = 50 AND b = d OR a = c );
a b c d
DROP TABLE t1;
#
# BUG#951283: Wrong result (missing rows) with semijoin+firstmatch, IN/ANY subquery
#
set @tmp_951283=@@optimizer_prune_level;
SET optimizer_prune_level=0;
CREATE TABLE t1 ( a INT ) ENGINE=InnoDB;
INSERT INTO t1 VALUES
(10),(11),(12),(13),(14),(15),(16),
(17),(18),(19),(20),(21),(22),(23);
CREATE TABLE t2 (
b INT PRIMARY KEY,
c VARCHAR(1),
d VARCHAR(1),
KEY(c)
) ENGINE=InnoDB;
INSERT INTO t2 VALUES
(1,'j','j'),(2,'v','v'),(3,'c','c'),(4,'m','m'),
(5,'d','d'),(6,'d','d'),(7,'y','y'),(8,'t','t'),
(9,'d','d'),(10,'s','s'),(11,'r','r'),(12,'m','m'),
(13,'b','b'),(14,'x','x'),(15,'g','g'),(16,'p','p'),
(17,'q','q'),(18,'w','w'),(19,'d','d');
EXPLAIN
SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3
WHERE alias3.d IN (
SELECT alias4.c FROM t2 AS alias4, t2 AS alias5
WHERE alias5.b = alias4.b
AND ( alias5.b >= alias3.b OR alias5.c != alias3.c )
);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL 19 Using where
1 PRIMARY alias4 ref PRIMARY,c c 4 test.alias3.d 1 Using index
1 PRIMARY alias5 eq_ref PRIMARY PRIMARY 4 test.alias4.b 1 Using where; FirstMatch(alias3)
1 PRIMARY alias2 ALL NULL NULL NULL NULL 14 Using join buffer (flat, BNL join)
1 PRIMARY alias1 ALL NULL NULL NULL NULL 14 Using join buffer (flat, BNL join)
SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3
WHERE alias3.d IN (
SELECT alias4.c FROM t2 AS alias4, t2 AS alias5
WHERE alias5.b = alias4.b
AND ( alias5.b >= alias3.b OR alias5.c != alias3.c )
);
COUNT(*)
3724
set optimizer_prune_level=@tmp_951283;
DROP TABLE t1,t2;
# This must be the last in the file:
set optimizer_switch=@subselect_sj2_tmp;
set optimizer_switch=default;

30
mysql-test/suite/innodb/r/innodb-autoinc-61209.result

@ -0,0 +1,30 @@
DROP TABLE IF EXISTS bug_61209;
CREATE TABLE bug_61209 (a INT auto_increment, PRIMARY KEY(a)) ENGINE=InnoDB;
INSERT INTO bug_61209 VALUES (), ();
# Connect con1
# Connect con2
# Connection con1
SET SESSION auto_increment_increment=3;
SET SESSION auto_increment_offset=2;
SELECT GET_LOCK('a', 10);
# Connection con2
SET SESSION auto_increment_increment=3;
SET SESSION auto_increment_offset=2;
INSERT INTO bug_61209 (a) VALUES (NULL), (NULL), (NULL + GET_LOCK('a', 10));
# Connection con1 reap
GET_LOCK('a', 10)
1
INSERT INTO bug_61209 (a) VALUES (NULL), (NULL), (NULL);
SELECT RELEASE_LOCK('a');
# Connection con2 reap
# Connection con1 reap
RELEASE_LOCK('a')
1
DROP TABLE bug_61209;

178
mysql-test/suite/innodb/r/innodb-autoinc.result

@ -366,7 +366,7 @@ c1
310
400
1000
1010
1110
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
@ -648,7 +648,7 @@ t2 CREATE TABLE `t2` (
`n` int(10) unsigned NOT NULL,
`o` enum('FALSE','TRUE') DEFAULT NULL,
PRIMARY KEY (`m`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=latin1
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=latin1
INSERT INTO t1 (b,c) SELECT n,o FROM t2 ;
SHOW CREATE TABLE t1;
Table Create Table
@ -657,7 +657,7 @@ t1 CREATE TABLE `t1` (
`b` int(10) unsigned NOT NULL,
`c` enum('FALSE','TRUE') DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=latin1
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=latin1
INSERT INTO t1 (b,c) SELECT n,o FROM t2 ;
SELECT * FROM t1;
a b c
@ -671,16 +671,16 @@ a b c
8 4 FALSE
9 5 TRUE
10 5 FALSE
13 1 TRUE
14 1 FALSE
15 2 TRUE
16 2 FALSE
17 3 TRUE
18 3 FALSE
19 4 TRUE
20 4 FALSE
21 5 TRUE
22 5 FALSE
16 1 TRUE
17 1 FALSE
18 2 TRUE
19 2 FALSE
20 3 TRUE
21 3 FALSE
22 4 TRUE
23 4 FALSE
24 5 TRUE
25 5 FALSE
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@ -688,7 +688,7 @@ t1 CREATE TABLE `t1` (
`b` int(10) unsigned NOT NULL,
`c` enum('FALSE','TRUE') DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=latin1
) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=latin1
INSERT INTO t1 (b,c) SELECT n,o FROM t2 WHERE o = 'false';
SELECT * FROM t1;
a b c
@ -702,21 +702,21 @@ a b c
8 4 FALSE
9 5 TRUE
10 5 FALSE
13 1 TRUE
14 1 FALSE
15 2 TRUE
16 2 FALSE
17 3 TRUE
18 3 FALSE
19 4 TRUE
20 4 FALSE
21 5 TRUE
22 5 FALSE
23 1 FALSE
24 2 FALSE
25 3 FALSE
26 4 FALSE
27 5 FALSE
16 1 TRUE
17 1 FALSE
18 2 TRUE
19 2 FALSE
20 3 TRUE
21 3 FALSE
22 4 TRUE
23 4 FALSE
24 5 TRUE
25 5 FALSE
31 1 FALSE
32 2 FALSE
33 3 FALSE
34 4 FALSE
35 5 FALSE
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@ -724,7 +724,7 @@ t1 CREATE TABLE `t1` (
`b` int(10) unsigned NOT NULL,
`c` enum('FALSE','TRUE') DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARSET=latin1
) ENGINE=InnoDB AUTO_INCREMENT=38 DEFAULT CHARSET=latin1
INSERT INTO t1 (b,c) SELECT n,o FROM t2 WHERE o = 'false';
SELECT * FROM t1;
a b c
@ -738,26 +738,26 @@ a b c
8 4 FALSE
9 5 TRUE
10 5 FALSE
13 1 TRUE
14 1 FALSE
15 2 TRUE
16 2 FALSE
17 3 TRUE
18 3 FALSE
19 4 TRUE
20 4 FALSE
21 5 TRUE
22 5 FALSE
23 1 FALSE
24 2 FALSE
25 3 FALSE
26 4 FALSE
27 5 FALSE
30 1 FALSE
31 2 FALSE
32 3 FALSE
33 4 FALSE
34 5 FALSE
16 1 TRUE
17 1 FALSE
18 2 TRUE
19 2 FALSE
20 3 TRUE
21 3 FALSE
22 4 TRUE
23 4 FALSE
24 5 TRUE
25 5 FALSE
31 1 FALSE
32 2 FALSE
33 3 FALSE
34 4 FALSE
35 5 FALSE
38 1 FALSE
39 2 FALSE
40 3 FALSE
41 4 FALSE
42 5 FALSE
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@ -765,7 +765,7 @@ t1 CREATE TABLE `t1` (
`b` int(10) unsigned NOT NULL,
`c` enum('FALSE','TRUE') DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB AUTO_INCREMENT=37 DEFAULT CHARSET=latin1
) ENGINE=InnoDB AUTO_INCREMENT=45 DEFAULT CHARSET=latin1
INSERT INTO t1 (b,c) SELECT n,o FROM t2 WHERE o = 'false';
SHOW CREATE TABLE t1;
Table Create Table
@ -774,7 +774,7 @@ t1 CREATE TABLE `t1` (
`b` int(10) unsigned NOT NULL,
`c` enum('FALSE','TRUE') DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB AUTO_INCREMENT=44 DEFAULT CHARSET=latin1
) ENGINE=InnoDB AUTO_INCREMENT=52 DEFAULT CHARSET=latin1
INSERT INTO t1 (b,c) SELECT n,o FROM t2 WHERE o = 'false';
SHOW CREATE TABLE t1;
Table Create Table
@ -783,7 +783,7 @@ t1 CREATE TABLE `t1` (
`b` int(10) unsigned NOT NULL,
`c` enum('FALSE','TRUE') DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB AUTO_INCREMENT=51 DEFAULT CHARSET=latin1
) ENGINE=InnoDB AUTO_INCREMENT=59 DEFAULT CHARSET=latin1
INSERT INTO t1 (b,c) SELECT n,o FROM t2 WHERE o = 'false';
SELECT * FROM t1;
a b c
@ -797,41 +797,41 @@ a b c
8 4 FALSE
9 5 TRUE
10 5 FALSE
13 1 TRUE
14 1 FALSE
15 2 TRUE
16 2 FALSE
17 3 TRUE
18 3 FALSE
19 4 TRUE
20 4 FALSE
21 5 TRUE
22 5 FALSE
23 1 FALSE
24 2 FALSE
25 3 FALSE
26 4 FALSE
27 5 FALSE
30 1 FALSE
31 2 FALSE
32 3 FALSE
33 4 FALSE
34 5 FALSE
37 1 FALSE
38 2 FALSE
39 3 FALSE
40 4 FALSE
41 5 FALSE
44 1 FALSE
45 2 FALSE
46 3 FALSE
47 4 FALSE
48 5 FALSE
51 1 FALSE
52 2 FALSE
53 3 FALSE
54 4 FALSE
55 5 FALSE
16 1 TRUE
17 1 FALSE
18 2 TRUE
19 2 FALSE
20 3 TRUE
21 3 FALSE
22 4 TRUE
23 4 FALSE
24 5 TRUE
25 5 FALSE
31 1 FALSE
32 2 FALSE
33 3 FALSE
34 4 FALSE
35 5 FALSE
38 1 FALSE
39 2 FALSE
40 3 FALSE
41 4 FALSE
42 5 FALSE
45 1 FALSE
46 2 FALSE
47 3 FALSE
48 4 FALSE
49 5 FALSE
52 1 FALSE
53 2 FALSE
54 3 FALSE
55 4 FALSE
56 5 FALSE
59 1 FALSE
60 2 FALSE
61 3 FALSE
62 4 FALSE
63 5 FALSE
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
@ -839,7 +839,7 @@ t1 CREATE TABLE `t1` (
`b` int(10) unsigned NOT NULL,
`c` enum('FALSE','TRUE') DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB AUTO_INCREMENT=58 DEFAULT CHARSET=latin1
) ENGINE=InnoDB AUTO_INCREMENT=66 DEFAULT CHARSET=latin1
DROP TABLE t1;
DROP TABLE t2;
DROP TABLE IF EXISTS t1;

61
mysql-test/suite/innodb/t/innodb-autoinc-61209.test

@ -0,0 +1,61 @@
# This is the test case for bug #61209 - duplicate key errors
# when using auto_increment_increment > 1 and auto_increment_offset > 1
#
--source include/have_innodb.inc
#
# Precautionary clean up.
#
--disable_warnings
DROP TABLE IF EXISTS bug_61209;
--enable_warnings
#
# Create test data.
#
CREATE TABLE bug_61209 (a INT auto_increment, PRIMARY KEY(a)) ENGINE=InnoDB;
INSERT INTO bug_61209 VALUES (), ();
--echo
--echo # Connect con1
--connect (con1,localhost,root,,)
--echo
--echo # Connect con2
--connect (con2,localhost,root,,)
--echo
--echo # Connection con1
--connection con1
SET SESSION auto_increment_increment=3;
SET SESSION auto_increment_offset=2;
send SELECT GET_LOCK('a', 10);
--echo
--echo # Connection con2
--connection con2
SET SESSION auto_increment_increment=3;
SET SESSION auto_increment_offset=2;
send INSERT INTO bug_61209 (a) VALUES (NULL), (NULL), (NULL + GET_LOCK('a', 10));
--echo
--echo # Connection con1 reap
--connection con1
reap;
INSERT INTO bug_61209 (a) VALUES (NULL), (NULL), (NULL);
send SELECT RELEASE_LOCK('a');
--echo
--echo # Connection con2 reap
--connection con2
reap;
--echo
--echo # Connection con1 reap
--connection con1
reap;
#
# Clean up
#
DROP TABLE bug_61209;

138
mysql-test/t/subselect_sj2.test

@ -1093,5 +1093,143 @@ SELECT * FROM t1, t2 WHERE c IN (SELECT c FROM t1, t2 WHERE a = b);
DROP TABLE t1,t2;
--echo #
--echo # BUG#962667: Assertion `0' failed in QUICK_INDEX_SORT_SELECT::need_sorted_output()
--echo # with index_merge+index_merge_sort_union+loosescan+semijoin
--echo #
CREATE TABLE t1 (
a INT, b VARCHAR(1), c INT,
KEY(a), KEY(b)
) ENGINE=InnoDB;
INSERT INTO t1 VALUES
(1,'v',9),(2,'v',8),(3,'c',7),(4,'m',6),(5,'x',5),
(6,'i',4),(7,'e',3),(8,'p',2),(9,'s',1),(10,'j',9),
(11,'z',8),(12,'c',7),(13,'a',6),(14,'q',5),(15,'y',4),
(16,'n',3),(17,'r',2),(18,'v',1),(19,'p',0);
CREATE TABLE t2 (
pk INT, d VARCHAR(1), e INT,
PRIMARY KEY(pk), KEY(d,e)
) ENGINE=InnoDB;
INSERT INTO t2 VALUES
(1,'x',1),(2,'d',2),(3,'r',3),(4,'f',4),(5,'y',5),
(6,'u',6),(7,'m',7),(8,'k',8),(9,'o',9),(10,'w',1),
(11,'m',2),(12,'q',3),(13,'m',4),(14,'d',5),
(15,'g',6),(16,'x',7),(17,'f',8);
explain
SELECT * FROM t1 WHERE b IN (
SELECT d FROM t2, t1
WHERE a = d AND ( pk < 2 OR d = 'z' )
);
SELECT * FROM t1 WHERE b IN (
SELECT d FROM t2, t1
WHERE a = d AND ( pk < 2 OR d = 'z' )
);
DROP TABLE t1, t2;
--echo #
--echo # BUG#951937: Wrong result (missing rows) with semijoin+materialization, IN subquery, InnoDB, TEMPTABLE view
--echo #
CREATE TABLE t1 (
a VARCHAR(1),
b VARCHAR(1) NOT NULL,
KEY(a)
) ENGINE=InnoDB;
INSERT INTO t1 VALUES
('j','j'),('v','v'),('c','c'),('m','m'),('d','d'),
('y','y'),('t','t'),('d','d'),('s','s'),('r','r'),
('m','m'),('b','b'),('x','x'),('g','g'),('p','p'),
('q','q'),('w','w'),('d','d'),('e','e');
CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
--echo # This query returned 6 rows instead of 19
--sorted_result
SELECT * FROM v1
WHERE ( a, a ) IN (
SELECT alias2.b, alias2.a
FROM t1 AS alias1, t1 AS alias2
WHERE alias2.b = alias1.a
AND ( alias1.b >= alias1.a OR alias2.b = 'z' )
);
--echo # Another testcase, without the VIEW:
CREATE TABLE t2 (a VARCHAR(1), b VARCHAR(1) NOT NULL, KEY(a)) ENGINE=InnoDB;
INSERT INTO t2 SELECT * FROM t1;
INSERT INTO t2 SELECT * FROM t1;
EXPLAIN
SELECT * FROM t2
WHERE (a, a) IN (SELECT alias2.b, alias2.a FROM t1 AS alias1, t1 AS alias2
WHERE
alias2.b = alias1.a AND
(alias1.b >= alias1.a OR alias2.b = 'z'));
--sorted_result
SELECT * FROM t2
WHERE (a, a) IN (SELECT alias2.b, alias2.a FROM t1 AS alias1, t1 AS alias2
WHERE
alias2.b = alias1.a AND
(alias1.b >= alias1.a OR alias2.b = 'z'));
DROP VIEW v1;
DROP TABLE t1, t2;
--echo #
--echo # BUG#965872: Server crashes in embedding_sjm on a simple 1-table select with AND and OR
--echo # (this is a regression caused by the fix for BUG#951937)
CREATE TABLE t1 ( a INT, b INT, c INT, d INT );
INSERT INTO t1 VALUES (4,2,8,9),(4,2,7,8);
SELECT * FROM t1
WHERE a = d AND ( b = 50 AND b = d OR a = c );
DROP TABLE t1;
--echo #
--echo # BUG#951283: Wrong result (missing rows) with semijoin+firstmatch, IN/ANY subquery
--echo #
set @tmp_951283=@@optimizer_prune_level;
SET optimizer_prune_level=0;
CREATE TABLE t1 ( a INT ) ENGINE=InnoDB;
INSERT INTO t1 VALUES
(10),(11),(12),(13),(14),(15),(16),
(17),(18),(19),(20),(21),(22),(23);
CREATE TABLE t2 (
b INT PRIMARY KEY,
c VARCHAR(1),
d VARCHAR(1),
KEY(c)
) ENGINE=InnoDB;
INSERT INTO t2 VALUES
(1,'j','j'),(2,'v','v'),(3,'c','c'),(4,'m','m'),
(5,'d','d'),(6,'d','d'),(7,'y','y'),(8,'t','t'),
(9,'d','d'),(10,'s','s'),(11,'r','r'),(12,'m','m'),
(13,'b','b'),(14,'x','x'),(15,'g','g'),(16,'p','p'),
(17,'q','q'),(18,'w','w'),(19,'d','d');
EXPLAIN
SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3
WHERE alias3.d IN (
SELECT alias4.c FROM t2 AS alias4, t2 AS alias5
WHERE alias5.b = alias4.b
AND ( alias5.b >= alias3.b OR alias5.c != alias3.c )
);
SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3
WHERE alias3.d IN (
SELECT alias4.c FROM t2 AS alias4, t2 AS alias5
WHERE alias5.b = alias4.b
AND ( alias5.b >= alias3.b OR alias5.c != alias3.c )
);
set optimizer_prune_level=@tmp_951283;
DROP TABLE t1,t2;
--echo # This must be the last in the file:
set optimizer_switch=@subselect_sj2_tmp;

3
mysys/thr_lock.c

@ -1168,6 +1168,9 @@ thr_multi_lock(THR_LOCK_DATA **data, uint count, THR_LOCK_INFO *owner,
if (result != THR_LOCK_SUCCESS)
{ /* Aborted */
thr_multi_unlock(data,(uint) (pos-data), 0);
/* Mark all requested locks as TL_UNLOCK (to simplify lock checking) */
for ( ; pos < end ; pos++)
(*pos)->type= TL_UNLOCK;
DBUG_RETURN(result);
}
DEBUG_SYNC_C("thr_multi_lock_after_thr_lock");

95
scripts/mytop.sh

@ -18,8 +18,10 @@ use DBI;
use Getopt::Long;
use Socket;
use List::Util qw(min max);
use File::Basename;
$main::VERSION = "1.9a";
my $path_for_script= dirname($0);
$|=1;
$0 = 'mytop';
@ -95,7 +97,8 @@ my %config = (
slow => 10, # slow query time
socket => '',
sort => 0, # default or reverse sort ("s")
user => 'root'
user => 'root',
fullqueries => 0
);
my %qcache = (); ## The query cache--used for full query info support.
@ -112,6 +115,17 @@ my $CLEAR = $WIN ? '': `clear`;
my $RM_RESET = 0;
my $RM_NOBLKRD = 3; ## using 4 traps Ctrl-C :-(
# Add options from .my.cnf first
my $my_print_defaults;
if (!defined($my_print_defaults=my_which("my_print_defaults")))
{
print "Warning: Can't find my_print_defaults. Please add it to your PATH!\n";
exit(1);
}
unshift @ARGV, split "\n", `$my_print_defaults client mytop`;
## Read the user's config file, if it exists.
my $config = "$ENV{HOME}/.mytop";
@ -160,7 +174,8 @@ GetOptions(
"long_nums!" => \$config{long_nums},
"mode|m=s" => \$config{mode},
"slow=i" => \$config{slow},
"sort=s" => \$config{sort}
"sort=s" => \$config{sort},
"fullqueries|L!" => \$config{fullqueries}
);
## User may have put the port with the host.
@ -744,6 +759,25 @@ while (1)
{
$config{mode} = 'status';
}
## L - full queries toggle
if ($key eq 'L')
{
if ($config{fullqueries})
{
$config{fullqueries} = 0;
print RED(), "-- full queries OFF --", RESET();
sleep 1;
}
else
{
$config{fullqueries} = 1;
print RED(), "-- full queries ON --", RESET();
sleep 1;
}
}
}
ReadMode($RM_RESET) unless $config{batchmode};
@ -1115,7 +1149,13 @@ sub GetData()
my $state= $width <= 80 ? 6 : int(min(6+($width-80)/3, 15));
my $free = $width - $used - ($state - 6);
my $format= "%9s %8s %15s %9s %6s %5s %6s %${state}s %-.${free}s\n";
my $format2= "%9d %8.8s %15.15s %9.9s %6d %5.1f %6.6s %${state}.${state}s %-${free}.${free}s\n";
my $format2;
if ($config{fullqueries})
{
$format2 = "%9d %8.8s %15.15s %9.9s %6d %5.1f %6.6s %${state}.${state}s %-${free}s\n";
} else {
$format2 = "%9d %8.8s %15.15s %9.9s %6d %5.1f %6.6s %${state}.${state}s %-${free}.${free}s\n";
}
print BOLD() if ($HAS_COLOR);
printf $format,
@ -1244,7 +1284,12 @@ sub GetData()
if ($thread->{Info})
{
$smInfo = substr $thread->{Info}, 0, $free;
if ($config{fullqueries})
{
$smInfo = $thread->{Info};
} else {
$smInfo = substr $thread->{Info}, 0, $free;
}
}
# if ($thread->{State})
# {
@ -1690,6 +1735,7 @@ Origional work by Jeremy D. Zawodny <${YELLOW}Jeremy\@Zawodny.com${RESET}>
u - show only a specific user
V - show variablesi
: - enter a command (not yet implemented)
L - show full queries (do not strip to terminal width)
Base version from ${GREEN}http://www.mysqlfanboy.com/mytop${RESET}
This version comes as part of the ${GREEN}MariaDB${RESET} distribution.
@ -1789,6 +1835,35 @@ sub FindProg($)
return $found;
}
####
#### my_which is used, because we can't assume that every system has the
#### which -command. my_which can take only one argument at a time.
#### Return values: requested system command with the first found path,
#### or undefined, if not found.
####
sub my_which
{
my ($command) = @_;
my (@paths, $path);
return $command if (-f $command && -x $command);
# Check first if this is a source distribution, then if this binary
# distribution and last in the path
push @paths, "./extra";
push @paths, $path_for_script;
push @paths, split(':', $ENV{'PATH'});
foreach $path (@paths)
{
$path .= "/$command";
return $path if (-f $path && -x $path);
}
return undef();
}
=pod
=head1 SYNOPSIS
@ -2056,11 +2131,15 @@ command-line arguments are applied.
=head2 Config File
Instead of always using bulky command-line parameters, you can also
use a config file in your home directory (C<~/.mytop>). If present,
B<mytop> will read it automatically. It is read I<before> any of your
use a config files for the default value of your options.
mytop will first read the [client] and [mytop] sections from your
my.cnf files. After that it will read the (C<~/.mytop>) file from your
home directory (if present). These are read I<before> any of your
command-line arguments are processed, so your command-line arguments
will override directives in the config file.
Here is a sample config file C<~/.mytop> which implements the defaults
described above.
@ -2275,6 +2354,10 @@ Many thanks go to these fine folks:
=over
=Item Jean Weisbuch
Added --fullqueries and reading of .my.cnf
=item Sami Ahlroos (sami@avis-net.de)
Suggested the idle/noidle stuff.

4
sql/item_cmpfunc.cc

@ -5463,7 +5463,7 @@ Item *Item_bool_rowready_func2::negated_item()
*/
Item_equal::Item_equal(Item *f1, Item *f2, bool with_const_item)
: Item_bool_func(), eval_item(0), cond_false(0)
: Item_bool_func(), eval_item(0), cond_false(0), context_field(NULL)
{
const_item_cache= 0;
with_const= with_const_item;
@ -5486,7 +5486,7 @@ Item_equal::Item_equal(Item *f1, Item *f2, bool with_const_item)
*/
Item_equal::Item_equal(Item_equal *item_equal)
: Item_bool_func(), eval_item(0), cond_false(0)
: Item_bool_func(), eval_item(0), cond_false(0), context_field(NULL)
{
const_item_cache= 0;
List_iterator_fast<Item> li(item_equal->equal_items);

11
sql/item_cmpfunc.h

@ -1693,9 +1693,16 @@ class Item_equal: public Item_bool_func
as datetimes. The comparator is used only if compare_as_dates=TRUE
*/
Arg_comparator cmp;
/*
For Item_equal objects inside an OR clause: one of the fields that were
used in the original equality.
*/
Item_field *context_field;
public:
inline Item_equal()
: Item_bool_func(), with_const(FALSE), eval_item(0), cond_false(0)
: Item_bool_func(), with_const(FALSE), eval_item(0), cond_false(0),
context_field(NULL)
{ const_item_cache=0 ;}
Item_equal(Item *f1, Item *f2, bool with_const_item);
Item_equal(Item_equal *item_equal);
@ -1722,6 +1729,8 @@ public:
Item *transform(Item_transformer transformer, uchar *arg);
virtual void print(String *str, enum_query_type query_type);
CHARSET_INFO *compare_collation();
void set_context_field(Item_field *ctx_field) { context_field= ctx_field; }
friend class Item_equal_fields_iterator;
friend Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
Item_equal *item_equal);

263
sql/opt_subselect.cc

@ -188,6 +188,252 @@
*/
/*
EqualityPropagationAndSjmNests
******************************
Equalities are used for:
P1. Equality propagation
P2. Equality substitution [for a certain join order]
The equality propagation is not affected by SJM nests. In fact, it is done
before we determine the execution plan, i.e. before we even know we will use
SJM-nests for execution.
The equality substitution is affected.
Substitution without SJMs
=========================
When one doesn't have SJM nests, tables have a strict join order:
--------------------------------->
t1 -- t2 -- t3 -- t4 --- t5
? ^
\
--(part-of-WHERE)
parts WHERE/ON and ref. expressions are attached at some point along the axis.
Expression is allowed to refer to a table column if the table is to the left of
the attachment point. For any given expression, we have a goal:
"Move leftmost allowed attachment point as much as possible to the left"
Substitution with SJMs - task setting
=====================================
When SJM nests are present, there is no global strict table ordering anymore:
--------------------------------->
ot1 -- ot2 --- sjm -- ot4 --- ot5
|
| Main execution
- - - - - - - - - - - - - - - - - - - - - - - -
| Materialization
it1 -- it2 --/
Besides that, we must take into account that
- values for outer table columns, otN.col, are inaccessible at
materialization step (SJM-RULE)
- values for inner table columns, itN.col, are inaccessible at Main execution
step, except for SJ-Materialization-Scan and columns that are in the
subquery's select list. (SJM-RULE)
Substitution with SJMs - solution
=================================
First, we introduce global strict table ordering like this:
ot1 - ot2 --\ /--- ot3 -- ot5
\--- it1 --- it2 --/
Now, let's see how to meet (SJM-RULE).
SJ-Materialization is only applicable for uncorrelated subqueries. From this, it
follows that any multiple equality will either
1. include only columns of outer tables, or
2. include only columns of inner tables, or
3. include columns of inner and outer tables, joined together through one
of IN-equalities.
Cases #1 and #2 can be handled in the same way as with regular inner joins.
Case #3 requires special handling, so that we don't construct violations of
(SJM-RULE). Let's consider possible ways to build violations.
Equality propagation starts with the clause in this form
top_query_where AND subquery_where AND in_equalities
First, it builds multi-equalities. It can also build a mixed multi-equality
multiple-equal(ot1.col, ot2.col, ... it1.col, itN.col)
Multi-equalities are pushed down the OR-clauses in top_query_where and in
subquery_where, so it's possible that clauses like this one are built:
subquery_cond OR (multiple-equal(it1.col, ot1.col,...) AND ...)
^^^^^^^^^^^^^ \
| this must be evaluated
\- can only be evaluated at the main phase.
at the materialization phase
Finally, equality substitution is started. It does two operations:
1. Field reference substitution
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(In the code, this is Item_field::replace_equal_field)
This is a process of replacing each reference to "tblX.col"
with the first element of the multi-equality. (REF-SUBST-ORIG)
This behaviour can cause problems with Semi-join nests. Suppose, we have a
condition:
func(it1.col, it2.col)
and a multi-equality(ot1.col, it1.col). Then, reference to "it1.col" will be
replaced with "ot1.col", constructing a condition
func(ot1.col, it2.col)
which will be a violation of (SJM-RULE).
In order to avoid this, (REF-SUBST-ORIG) is amended as follows:
- references to tables "itX.col" that are inner wrt some SJM nest, are
replaced with references to the first inner table from the same SJM nest.
- references to top-level tables "otX.col" are replaced with references to
the first element of the multi-equality, no matter if that first element is
a column of a top-level table or of table from some SJM nest.
(REF-SUBST-SJM)
The case where the first element is a table from an SJM nest $SJM is ok,
because it can be proven that $SJM uses SJ-Materialization-Scan, and
"unpacks" correct column values to the first element during the main
execution phase.
2. Item_equal elimination
~~~~~~~~~~~~~~~~~~~~~~~~~
(In the code: eliminate_item_equal) This is a process of taking
multiple-equal(a,b,c,d,e)
and replacing it with an equivalent expression which is an AND of pair-wise
equalities:
a=b AND a=c AND ...
The equalities are picked such that for any given join prefix (t1,t2...) the
subset of equalities that can be evaluated gives the most restrictive
filtering.
Without SJM nests, it is sufficient to compare every multi-equality member
with the first one:
elem1=elem2 AND elem1=elem3 AND elem1=elem4 ...
When SJM nests are present, we should take care not to construct equalities
that violate the (SJM-RULE). This is achieved by generating separate sets of
equalites for top-level tables and for inner tables. That is, for the join
order
ot1 - ot2 --\ /--- ot3 -- ot5
\--- it1 --- it2 --/
we will generate
ot1.col=ot2.col
ot1.col=ot3.col
ot1.col=ot5.col
it2.col=it1.col
2.1 The problem with Item_equals and ORs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
As has been mentioned above, multiple equalities are pushed down into OR
clauses, possibly building clauses like this:
func(it.col2) OR multiple-equal(it1.col1, it1.col2, ot1.col) (1)
where the first part of the clause has references to inner tables, while the
second has references to the top-level tables, which is a violation of
(SJM-RULE).
AND-clauses of this kind do not create problems, because make_cond_for_table()
will take them apart. OR-clauses will not be split. It is possible to
split-out the part that's dependent on the inner table:
func(it.col2) OR it1.col1=it1.col2
but this is a less-restrictive condition than condition (1). Current execution
scheme will still try to generate the "remainder" condition:
func(it.col2) OR it1.col1=ot1.col
which is a violation of (SJM-RULE).
QQ: "ot1.col=it1.col" is checked at the upper level. Why was it not removed
here?
AA: because has a proper subset of conditions that are found on this level.
consider a join order of ot, sjm(it)
and a condition
ot.col=it.col AND ( ot.col=it.col='foo' OR it.col2='bar')
we will produce:
table ot: nothing
table it: ot.col=it.col AND (ot.col='foo' OR it.col2='bar')
^^^^ ^^^^^^^^^^^^^^^^
| \ the problem is that
| this part condition didnt
| receive a substitution
|
+--- it was correct to subst, 'ot' is
the left-most.
Does it make sense to push "inner=outer" down into ORs?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Yes. Consider the query:
select * from ot
where ot.col in (select it.col from it where (it.col='foo' OR it.col='bar'))
here, it may be useful to infer that
(ot.col='foo' OR ot.col='bar') (CASE-FOR-SUBST)
and attach that condition to the table 'ot'.
Possible solutions for Item_equals and ORs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Solution #1
~~~~~~~~~~~
Let make_cond_for_table() chop analyze the OR clauses it has produced and
discard them if they violate (SJM-RULE). This solution would allow to handle
cases like (CASE-FOR-SUBST) at the expense of making semantics of
make_cond_for_table() complicated.
Solution #2
~~~~~~~~~~~
Before the equality propagation phase, none of the OR clauses violate the
(SJM-RULE). This way, if we remember which tables the original equality
referred to, we can only generate equalities that refer to the outer (or inner)
tables. Note that this will disallow handling of cases like (CASE-FOR-SUBST).
Currently, solution #2 is implemented.
*/
static
bool subquery_types_allow_materialization(Item_in_subselect *in_subs);
@ -2673,6 +2919,8 @@ bool Firstmatch_picker::check_qep(JOIN *join,
}
}
}
else
invalidate_firstmatch_prefix();
return FALSE;
}
@ -3100,7 +3348,22 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
record_count, join->best_positions + idx,
&loose_scan_pos);
if (idx==first)
{
join->best_positions[idx]= loose_scan_pos;
/*
If LooseScan is based on ref access (including the "degenerate"
one with 0 key parts), we should use full index scan.
Unfortunately, lots of code assumes that if tab->type==JT_ALL &&
tab->quick!=NULL, then quick select should be used. The only
simple way to fix this is to remove the quick select:
*/
if (join->best_positions[idx].key)
{
delete join->best_positions[idx].table->quick;
join->best_positions[idx].table->quick= NULL;
}
}
}
rem_tables &= ~join->best_positions[idx].table->table->map;
record_count *= join->best_positions[idx].records_read;

18
sql/sql_select.cc

@ -10859,6 +10859,9 @@ finish:
acceptable, as this happens rarely. The implementation without
copying would be much more complicated.
For description of how equality propagation works with SJM nests, grep
for EqualityPropagationAndSjmNests.
@param left_item left term of the quality to be checked
@param right_item right term of the equality to be checked
@param item equality item if the equality originates from a condition
@ -10932,12 +10935,14 @@ static bool check_simple_equality(Item *left_item, Item *right_item,
{
/* left_item_equal of an upper level contains left_item */
left_item_equal= new Item_equal(left_item_equal);
left_item_equal->set_context_field(((Item_field*) left_item));
cond_equal->current_level.push_back(left_item_equal);
}
if (right_copyfl)
{
/* right_item_equal of an upper level contains right_item */
right_item_equal= new Item_equal(right_item_equal);
right_item_equal->set_context_field(((Item_field*) right_item));
cond_equal->current_level.push_back(right_item_equal);
}
@ -10967,6 +10972,7 @@ static bool check_simple_equality(Item *left_item, Item *right_item,
Item_equal *item_equal= new Item_equal(orig_left_item,
orig_right_item,
FALSE);
item_equal->set_context_field((Item_field*)left_item);
cond_equal->current_level.push_back(item_equal);
}
}
@ -11023,6 +11029,7 @@ static bool check_simple_equality(Item *left_item, Item *right_item,
{
item_equal= new Item_equal(item_equal);
cond_equal->current_level.push_back(item_equal);
item_equal->set_context_field(field_item);
}
if (item_equal)
{
@ -11036,6 +11043,7 @@ static bool check_simple_equality(Item *left_item, Item *right_item,
else
{
item_equal= new Item_equal(const_item, orig_field_item, TRUE);
item_equal->set_context_field(field_item);
cond_equal->current_level.push_back(item_equal);
}
return TRUE;
@ -11672,6 +11680,8 @@ static TABLE_LIST* embedding_sjm(Item *item)
Item_equal::get_first() also takes similar measures for dealing with
equality substitution in presense of SJM nests.
Grep for EqualityPropagationAndSjmNests for a more verbose description.
@return
- The condition with generated simple equalities or
a pointer to the simple generated equality, if success.
@ -11735,9 +11745,13 @@ Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
on upper AND-levels.
*/
if (upper)
{
{
TABLE_LIST *native_sjm= embedding_sjm(item_equal->context_field);
if (item_const && upper->get_const())
{
/* Upper item also has "field_item=const". Don't produce equality here */
item= 0;
}
else
{
Item_equal_fields_iterator li(*item_equal);
@ -11748,6 +11762,8 @@ Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
break;
}
}
if (embedding_sjm(field_item) != native_sjm)
item= NULL; /* Don't produce equality */
}
bool produce_equality= test(item == field_item);

67
storage/innobase/handler/ha_innodb.cc

@ -1459,7 +1459,8 @@ innobase_next_autoinc(
ulonglong current, /*!< in: Current value */
ulonglong increment, /*!< in: increment current by */
ulonglong offset, /*!< in: AUTOINC offset */
ulonglong max_value) /*!< in: max value for type */
ulonglong max_value, /*!< in: max value for type */
ulonglong reserve) /*!< in: how many values to reserve */
{
ulonglong next_value;
@ -1468,51 +1469,16 @@ innobase_next_autoinc(
/* According to MySQL documentation, if the offset is greater than
the increment then the offset is ignored. */
if (offset > increment) {
if (offset >= increment)
offset = 0;
}
if (max_value <= current) {
next_value = max_value;
} else if (offset <= 1) {
/* Offset 0 and 1 are the same, because there must be at
least one node in the system. */
if (max_value - current <= increment) {
next_value = max_value;
} else {
next_value = current + increment;
}
} else if (max_value > current) {
if (current > offset) {
next_value = ((current - offset) / increment) + 1;
} else {
next_value = ((offset - current) / increment) + 1;
}
ut_a(increment > 0);
ut_a(next_value > 0);
/* Check for multiplication overflow. */
if (increment > (max_value / next_value)) {
next_value = max_value;
} else {
next_value *= increment;
ut_a(max_value >= next_value);
/* Check for overflow. */
if (max_value - next_value <= offset) {
next_value = max_value;
} else {
next_value += offset;
}
}
} else {
next_value = max_value;
}
ut_a(next_value <= max_value);
if (max_value <= current)
return max_value;
next_value = (current / increment) + reserve;
next_value = next_value * increment + offset;
/* Check for overflow. */
if (next_value < current || next_value > max_value)
next_value = max_value;
return(next_value);
}
@ -3799,8 +3765,7 @@ ha_innobase::innobase_initialize_autoinc()
nor the offset, so use a default increment of 1. */
auto_inc = innobase_next_autoinc(
read_auto_inc, 1, 1, col_max_value);
read_auto_inc, 1, 1, col_max_value, 1);
break;
}
case DB_RECORD_NOT_FOUND:
@ -5281,7 +5246,7 @@ set_max_autoinc:
auto_inc = innobase_next_autoinc(
auto_inc,
need, offset, col_max_value);
need, offset, col_max_value, 1);
err = innobase_set_max_autoinc(
auto_inc);
@ -5556,7 +5521,7 @@ ha_innobase::update_row(
need = prebuilt->autoinc_increment;
auto_inc = innobase_next_autoinc(
auto_inc, need, offset, col_max_value);
auto_inc, need, offset, col_max_value, 1);
error = innobase_set_max_autoinc(auto_inc);
}
@ -10213,16 +10178,14 @@ ha_innobase::get_auto_increment(
/* With old style AUTOINC locking we only update the table's
AUTOINC counter after attempting to insert the row. */
if (innobase_autoinc_lock_mode != AUTOINC_OLD_STYLE_LOCKING) {
ulonglong need;
ulonglong current;
ulonglong next_value;
current = *first_value > col_max_value ? autoinc : *first_value;
need = *nb_reserved_values * increment;
/* Compute the last value in the interval */
next_value = innobase_next_autoinc(
current, need, offset, col_max_value);
current, increment, offset, col_max_value, *nb_reserved_values);
prebuilt->autoinc_last_value = next_value;

67
storage/xtradb/handler/ha_innodb.cc

@ -1629,7 +1629,8 @@ innobase_next_autoinc(
ulonglong current, /*!< in: Current value */
ulonglong increment, /*!< in: increment current by */
ulonglong offset, /*!< in: AUTOINC offset */
ulonglong max_value) /*!< in: max value for type */
ulonglong max_value, /*!< in: max value for type */
ulonglong reserve) /*!< in: how many values to reserve */
{
ulonglong next_value;
@ -1638,51 +1639,16 @@ innobase_next_autoinc(
/* According to MySQL documentation, if the offset is greater than
the increment then the offset is ignored. */
if (offset > increment) {
if (offset >= increment)
offset = 0;
}
if (max_value <= current) {
next_value = max_value;
} else if (offset <= 1) {
/* Offset 0 and 1 are the same, because there must be at
least one node in the system. */
if (max_value - current <= increment) {
next_value = max_value;
} else {
next_value = current + increment;
}
} else if (max_value > current) {
if (current > offset) {
next_value = ((current - offset) / increment) + 1;
} else {
next_value = ((offset - current) / increment) + 1;
}
ut_a(increment > 0);
ut_a(next_value > 0);
/* Check for multiplication overflow. */
if (increment > (max_value / next_value)) {
next_value = max_value;
} else {
next_value *= increment;
ut_a(max_value >= next_value);
/* Check for overflow. */
if (max_value - next_value <= offset) {
next_value = max_value;
} else {
next_value += offset;
}
}
} else {
next_value = max_value;
}
ut_a(next_value <= max_value);
if (max_value <= current)
return max_value;
next_value = (current / increment) + reserve;
next_value = next_value * increment + offset;
/* Check for overflow. */
if (next_value < current || next_value > max_value)
next_value = max_value;
return(next_value);
}
@ -4190,8 +4156,7 @@ ha_innobase::innobase_initialize_autoinc()
nor the offset, so use a default increment of 1. */
auto_inc = innobase_next_autoinc(
read_auto_inc, 1, 1, col_max_value);
read_auto_inc, 1, 1, col_max_value, 1);
break;
}
case DB_RECORD_NOT_FOUND:
@ -5876,7 +5841,7 @@ set_max_autoinc:
auto_inc = innobase_next_autoinc(
auto_inc,
need, offset, col_max_value);
need, offset, col_max_value, 1);
err = innobase_set_max_autoinc(
auto_inc);
@ -6147,7 +6112,7 @@ ha_innobase::update_row(
need = prebuilt->autoinc_increment;
auto_inc = innobase_next_autoinc(
auto_inc, need, offset, col_max_value);
auto_inc, need, offset, col_max_value, 1);
error = innobase_set_max_autoinc(auto_inc);
}
@ -10968,16 +10933,14 @@ ha_innobase::get_auto_increment(
/* With old style AUTOINC locking we only update the table's
AUTOINC counter after attempting to insert the row. */
if (innobase_autoinc_lock_mode != AUTOINC_OLD_STYLE_LOCKING) {
ulonglong need;
ulonglong current;
ulonglong next_value;
current = *first_value > col_max_value ? autoinc : *first_value;
need = *nb_reserved_values * increment;
/* Compute the last value in the interval */
next_value = innobase_next_autoinc(
current, need, offset, col_max_value);
current, increment, offset, col_max_value, *nb_reserved_values);
prebuilt->autoinc_last_value = next_value;

Loading…
Cancel
Save