summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2010-09-19 18:46:39 -0700
committerIgor Babaev <igor@askmonty.org>2010-09-19 18:46:39 -0700
commit3c313312bbcd76cf9f8e34fd82622240b6a7c337 (patch)
tree551be33d932cb25674b613a5ca4be404d1e38e07
parent65d66ae1fcfe54cee33ff4402a8791ae3db52863 (diff)
downloadmariadb-git-3c313312bbcd76cf9f8e34fd82622240b6a7c337.tar.gz
Fixed bug #56862 (lp bug #640419).
Made sure that rr_quick is used to read the next record whenever a quick select is used to retrieve the table records.
-rw-r--r--mysql-test/r/index_merge_innodb.result55
-rw-r--r--mysql-test/t/index_merge_innodb.test53
-rw-r--r--sql/records.cc3
3 files changed, 110 insertions, 1 deletions
diff --git a/mysql-test/r/index_merge_innodb.result b/mysql-test/r/index_merge_innodb.result
index ff00654aed8..bd49af16105 100644
--- a/mysql-test/r/index_merge_innodb.result
+++ b/mysql-test/r/index_merge_innodb.result
@@ -581,3 +581,58 @@ WHERE
`RUNID`= '' AND `SUBMITNR`= '' AND `ORDERNR`='' AND `PROGRAMM`='' AND
`TESTID`='' AND `UCCHECK`='';
drop table t1;
+#
+# BUG#56862/640419: Wrong result with sort_union index merge when one
+# of the merged index scans is the primary key scan
+#
+CREATE TABLE t1 (
+pk int NOT NULL AUTO_INCREMENT PRIMARY KEY,
+a int,
+b int,
+INDEX idx(a))
+ENGINE=INNODB;
+INSERT INTO t1(a,b) VALUES
+(11, 1100), (2, 200), (1, 100), (14, 1400), (5, 500),
+(3, 300), (17, 1700), (4, 400), (12, 1200), (8, 800),
+(6, 600), (18, 1800), (9, 900), (10, 1000), (7, 700),
+(13, 1300), (15, 1500), (19, 1900), (16, 1600), (20, 2000);
+INSERT INTO t1(a,b) SELECT a+20, b+2000 FROM t1;
+INSERT INTO t1(a,b) SELECT a+40, b+4000 FROM t1;
+INSERT INTO t1(a,b) SELECT a+80, b+8000 FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1 VALUES (1000000, 0, 0);
+SET SESSION sort_buffer_size = 1024*36;
+EXPLAIN
+SELECT COUNT(*) FROM
+(SELECT * FROM t1
+WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+2 DERIVED t1 index_merge PRIMARY,idx idx,PRIMARY 5,4 NULL 11419 Using sort_union(idx,PRIMARY); Using where
+SELECT COUNT(*) FROM
+(SELECT * FROM t1
+WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
+COUNT(*)
+6145
+EXPLAIN
+SELECT COUNT(*) FROM
+(SELECT * FROM t1 IGNORE INDEX(idx)
+WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL # Select tables optimized away
+2 DERIVED t1 ALL PRIMARY NULL NULL NULL # Using where
+SELECT COUNT(*) FROM
+(SELECT * FROM t1 IGNORE INDEX(idx)
+WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
+COUNT(*)
+6145
+DROP TABLE t1;
diff --git a/mysql-test/t/index_merge_innodb.test b/mysql-test/t/index_merge_innodb.test
index 7d4a27d9204..e68f414e0bc 100644
--- a/mysql-test/t/index_merge_innodb.test
+++ b/mysql-test/t/index_merge_innodb.test
@@ -29,3 +29,56 @@ let $merge_table_support= 0;
--source include/index_merge2.inc
--source include/index_merge_2sweeps.inc
--source include/index_merge_ror_cpk.inc
+
+--echo #
+--echo # BUG#56862/640419: Wrong result with sort_union index merge when one
+--echo # of the merged index scans is the primary key scan
+--echo #
+
+CREATE TABLE t1 (
+ pk int NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ a int,
+ b int,
+ INDEX idx(a))
+ENGINE=INNODB;
+
+INSERT INTO t1(a,b) VALUES
+ (11, 1100), (2, 200), (1, 100), (14, 1400), (5, 500),
+ (3, 300), (17, 1700), (4, 400), (12, 1200), (8, 800),
+ (6, 600), (18, 1800), (9, 900), (10, 1000), (7, 700),
+ (13, 1300), (15, 1500), (19, 1900), (16, 1600), (20, 2000);
+INSERT INTO t1(a,b) SELECT a+20, b+2000 FROM t1;
+INSERT INTO t1(a,b) SELECT a+40, b+4000 FROM t1;
+INSERT INTO t1(a,b) SELECT a+80, b+8000 FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1 VALUES (1000000, 0, 0);
+
+SET SESSION sort_buffer_size = 1024*36;
+
+EXPLAIN
+SELECT COUNT(*) FROM
+ (SELECT * FROM t1
+ WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
+SELECT COUNT(*) FROM
+ (SELECT * FROM t1
+ WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
+
+--replace_column 9 #
+EXPLAIN
+SELECT COUNT(*) FROM
+ (SELECT * FROM t1 IGNORE INDEX(idx)
+ WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
+SELECT COUNT(*) FROM
+ (SELECT * FROM t1 IGNORE INDEX(idx)
+ WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
+
+DROP TABLE t1;
diff --git a/sql/records.cc b/sql/records.cc
index 2fc5a26a210..827450201c9 100644
--- a/sql/records.cc
+++ b/sql/records.cc
@@ -196,7 +196,8 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
tempfile= &select->file;
else
tempfile= table->sort.io_cache;
- if (tempfile && my_b_inited(tempfile)) // Test if ref-records was used
+ if (tempfile && my_b_inited(tempfile) &&
+ !(select && select->quick))
{
DBUG_PRINT("info",("using rr_from_tempfile"));
info->read_record= (table->sort.addon_field ?