mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Backport of:
revno: 2876.47.174 revision-id: jorgen.loland@oracle.com-20110519120355-qn7eprkad9jqwu5j parent: mayank.prasad@oracle.com-20110518143645-bdxv4udzrmqsjmhq committer: Jorgen Loland <jorgen.loland@oracle.com> branch nick: mysql-trunk-11765831 timestamp: Thu 2011-05-19 14:03:55 +0200 message: BUG#11765831: 'RANGE ACCESS' MAY INCORRECTLY FILTER AWAY QUALIFYING ROWS The problem was that the ranges created when OR'ing two conditions could be incorrect. Without the bugfix, "I <> 6 OR (I <> 8 AND J = 5)" would create these ranges: "NULL < I < 6", "6 <= I <= 6 AND 5 <= J <= 5", "6 < I < 8", "8 <= I <= 8 AND 5 <= J <= 5", "8 < I" While the correct ranges is "NULL < I < 6", "6 <= I <= 6 AND 5 <= J <= 5", "6 < I" The problem occurs when key_or() ORs (1) "NULL < I < 6, 6 <= I <= 6 AND 5 <= J <= 5, 6 < I" with (2) "8 < I AND 5 <= J <= 5" The reason for the bug is that in key_or(), SEL_ARG *tmp is used to point to the range in (1) above that is merged with (2) while key1 points to the root of the red-black tree of (1). When merging (1) and (2), tmp refers to the "6 < I" part whereas the root is the "6 <= ... AND 5 <= J <= 5" part. key_or() decides that the tmp range needs to be split into "6 < I < 8, 8 <= I <= 8, 8 < I", in which next_key_part of the second range should be that of tmp. However, next_key_part is set to key1->next_key_part ("5 <= J <= 5") instead of tmp->next_key_part (empty). Fixing this gives the correct but not optimal ranges: "NULL < I < 6", "6 <= I <= 6 AND 5 <= J <= 5", "6 < I < 8", "8 <= I <= 8", "8 < I" A second problem can be seen above: key_or() may create adjacent ranges that could be replaced with a single range. Fixes for this is also included in the patch so that the range above becomes correct AND optimal: "NULL < I < 6", "6 <= I <= 6 AND 5 <= J <= 5", "6 < I" Merging adjacent ranges like this gives a slightly lower cost estimate for the range access.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
drop table if exists t1, t2, t3;
|
||||
drop table if exists t1, t2, t3, t10, t100;
|
||||
CREATE TABLE t1 (
|
||||
event_date date DEFAULT '0000-00-00' NOT NULL,
|
||||
type int(11) DEFAULT '0' NOT NULL,
|
||||
@@ -1763,3 +1763,49 @@ select min(f1) from t1 where f1 >= '2006-05-25 07:00:20' and f1 between '2003-
|
||||
min(f1)
|
||||
NULL
|
||||
drop table t1;
|
||||
#
|
||||
# BUG#11765831: 'RANGE ACCESS' MAY INCORRECTLY FILTER
|
||||
# AWAY QUALIFYING ROWS
|
||||
#
|
||||
CREATE TABLE t10(
|
||||
K INT NOT NULL AUTO_INCREMENT,
|
||||
I INT, J INT,
|
||||
PRIMARY KEY(K),
|
||||
KEY(I,J)
|
||||
);
|
||||
INSERT INTO t10(I,J) VALUES (6,1),(6,2),(6,3),(6,4),(6,5),
|
||||
(6,6),(6,7),(6,8),(6,9),(6,0);
|
||||
CREATE TABLE t100 LIKE t10;
|
||||
INSERT INTO t100(I,J) SELECT X.I, X.K+(10*Y.K) FROM t10 AS X,t10 AS Y;
|
||||
INSERT INTO t100(I,J) VALUES(8,26);
|
||||
|
||||
EXPLAIN SELECT * FROM t100 WHERE I <> 6 OR (I <> 8 AND J = 5);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t100 range I I 10 NULL 4 Using where
|
||||
|
||||
SELECT * FROM t100 WHERE I <> 6 OR (I <> 8 AND J = 5);
|
||||
K I J
|
||||
101 8 26
|
||||
DROP TABLE t10,t100;
|
||||
#
|
||||
# lp:817363: Wrong result with sort_union and multipart key in maria-5.3
|
||||
#
|
||||
CREATE TABLE t1 (a int NOT NULL , b int, c int, d varchar(32), KEY (d,b), PRIMARY KEY (a)) ;
|
||||
INSERT INTO t1 VALUES (7,7,NULL,'e'),(8,1,0,'p'),(9,7,1,'s'),(10,1,1,'j'),(12,2,0,'c'),(13,0,0,'a'),(14,1,1,'q');
|
||||
SELECT c FROM t1 WHERE d='q' OR d>='q' OR a > 97 OR (d IN ('j','s','i') AND b = 102);
|
||||
c
|
||||
1
|
||||
1
|
||||
SELECT c FROM t1 ignore index (d) WHERE d='q' OR d>='q' OR a > 97 OR (d IN ('j','s','i') AND b = 102);
|
||||
c
|
||||
1
|
||||
1
|
||||
SELECT * FROM t1 ignore index(d) WHERE d = 'q' OR d >= 'q' OR (d IN ( 'j' , 's' , 'i' ) AND ( b = 102 ));
|
||||
a b c d
|
||||
9 7 1 s
|
||||
14 1 1 q
|
||||
SELECT * FROM t1 force index(d) WHERE d = 'q' OR d >= 'q' OR (d IN ( 'j' , 's' , 'i' ) AND ( b = 102 ));
|
||||
a b c d
|
||||
14 1 1 q
|
||||
9 7 1 s
|
||||
DROP TABLE t1;
|
||||
|
Reference in New Issue
Block a user