Below is the list of changes that have just been committed into a local
5.0 repository of psergey. When psergey does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2007-07-12 08:33:07+04:00, sergefp@stripped +4 -0
BUG#29740: Wrong query results for index_merge/union over HEAP table.
- make HEAP table engine return HA_KEY_SCAN_NOT_ROR flag for both
BTREE and HEAP indexes.
mysql-test/r/index_merge.result@stripped, 2007-07-12 08:33:04+04:00, sergefp@stripped +40
-0
BUG#29740: testcase
mysql-test/t/index_merge.test@stripped, 2007-07-12 08:33:04+04:00, sergefp@stripped +29 -0
BUG#29740: testcase
sql/ha_heap.h@stripped, 2007-07-12 08:33:04+04:00, sergefp@stripped +3 -2
BUG#29740: Wrong query results for index_merge/union over HEAP table.
- make HEAP table engine return HA_KEY_SCAN_NOT_ROR flag for both
BTREE and HEAP indexes.
sql/opt_range.cc@stripped, 2007-07-12 08:33:04+04:00, sergefp@stripped +11 -14
BUG#29740: Fix comment about ROR scans.
diff -Nrup a/mysql-test/r/index_merge.result b/mysql-test/r/index_merge.result
--- a/mysql-test/r/index_merge.result 2006-12-26 16:47:29 +03:00
+++ b/mysql-test/r/index_merge.result 2007-07-12 08:33:04 +04:00
@@ -455,3 +455,43 @@ a
1
UNLOCK TABLES;
DROP TABLE t1, t2;
+CREATE TABLE `t1` (
+`a` int(11) DEFAULT NULL,
+`filler` char(200) DEFAULT NULL,
+`b` int(11) DEFAULT NULL,
+KEY `a` (`a`),
+KEY `b` (`b`)
+) ENGINE=MEMORY DEFAULT CHARSET=latin1;
+insert into t1 values
+(0, 'filler', 0), (1, 'filler', 1), (2, 'filler', 2), (3, 'filler', 3),
+(4, 'filler', 4), (5, 'filler', 5), (6, 'filler', 6), (7, 'filler', 7),
+(8, 'filler', 8), (9, 'filler', 9), (0, 'filler', 0), (1, 'filler', 1),
+(2, 'filler', 2), (3, 'filler', 3), (4, 'filler', 4), (5, 'filler', 5),
+(6, 'filler', 6), (7, 'filler', 7), (8, 'filler', 8), (9, 'filler', 9),
+(10, 'filler', 10), (11, 'filler', 11), (12, 'filler', 12), (13, 'filler', 13),
+(14, 'filler', 14), (15, 'filler', 15), (16, 'filler', 16), (17, 'filler', 17),
+(18, 'filler', 18), (19, 'filler', 19), (4, '5 ', 0), (5, '4 ', 0),
+(4, '4 ', 0), (4, 'qq ', 5), (5, 'qq ', 4), (4, 'zz ', 4);
+must use sort-union rather than union:
+explain select * from t1 where a=4 or b=4;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index_merge a,b a,b 5,5 NULL 4 Using sort_union(a,b); Using where
+select * from t1 where a=4 or b=4;
+a filler b
+4 filler 4
+4 filler 4
+4 5 0
+4 4 0
+4 qq 5
+5 qq 4
+4 zz 4
+select * from t1 ignore index(a,b) where a=4 or b=4;
+a filler b
+4 filler 4
+4 filler 4
+4 5 0
+4 4 0
+4 qq 5
+5 qq 4
+4 zz 4
+drop table t1;
diff -Nrup a/mysql-test/t/index_merge.test b/mysql-test/t/index_merge.test
--- a/mysql-test/t/index_merge.test 2006-09-12 17:25:33 +04:00
+++ b/mysql-test/t/index_merge.test 2007-07-12 08:33:04 +04:00
@@ -415,3 +415,32 @@ INSERT INTO t2(a,b) VALUES(1,2);
SELECT t2.a FROM t1,t2 WHERE t2.b=2 AND t2.a=1;
UNLOCK TABLES;
DROP TABLE t1, t2;
+
+#
+# BUG#29740: HA_KEY_SCAN_NOT_ROR wasn't set for HEAP engine
+#
+CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `filler` char(200) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL,
+ KEY `a` (`a`),
+ KEY `b` (`b`)
+) ENGINE=MEMORY DEFAULT CHARSET=latin1;
+
+insert into t1 values
+(0, 'filler', 0), (1, 'filler', 1), (2, 'filler', 2), (3, 'filler', 3),
+(4, 'filler', 4), (5, 'filler', 5), (6, 'filler', 6), (7, 'filler', 7),
+(8, 'filler', 8), (9, 'filler', 9), (0, 'filler', 0), (1, 'filler', 1),
+(2, 'filler', 2), (3, 'filler', 3), (4, 'filler', 4), (5, 'filler', 5),
+(6, 'filler', 6), (7, 'filler', 7), (8, 'filler', 8), (9, 'filler', 9),
+(10, 'filler', 10), (11, 'filler', 11), (12, 'filler', 12), (13, 'filler', 13),
+(14, 'filler', 14), (15, 'filler', 15), (16, 'filler', 16), (17, 'filler', 17),
+(18, 'filler', 18), (19, 'filler', 19), (4, '5 ', 0), (5, '4 ', 0),
+(4, '4 ', 0), (4, 'qq ', 5), (5, 'qq ', 4), (4, 'zz ', 4);
+
+--echo must use sort-union rather than union:
+explain select * from t1 where a=4 or b=4;
+select * from t1 where a=4 or b=4;
+select * from t1 ignore index(a,b) where a=4 or b=4;
+drop table t1;
+
diff -Nrup a/sql/ha_heap.h b/sql/ha_heap.h
--- a/sql/ha_heap.h 2006-12-30 23:02:06 +03:00
+++ b/sql/ha_heap.h 2007-07-12 08:33:04 +04:00
@@ -54,8 +54,9 @@ public:
ulong index_flags(uint inx, uint part, bool all_parts) const
{
return ((table->key_info[inx].algorithm == HA_KEY_ALG_BTREE) ?
- HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | HA_READ_RANGE :
- HA_ONLY_WHOLE_INDEX);
+ HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | HA_READ_RANGE |
+ HA_KEY_SCAN_NOT_ROR :
+ HA_ONLY_WHOLE_INDEX | HA_KEY_SCAN_NOT_ROR);
}
const key_map *keys_to_use_for_scanning() { return &btree_keys; }
uint max_supported_keys() const { return MAX_KEY; }
diff -Nrup a/sql/opt_range.cc b/sql/opt_range.cc
--- a/sql/opt_range.cc 2007-04-13 10:14:38 +04:00
+++ b/sql/opt_range.cc 2007-07-12 08:33:04 +04:00
@@ -6007,27 +6007,24 @@ check_quick_keys(PARAM *param,uint idx,S
ROR (Rowid Ordered Retrieval) key scan is a key scan that produces
ordered sequence of rowids (ha_xxx::cmp_ref is the comparison function)
- An index scan is a ROR scan if it is done using a condition in form
+ This function is needed to handle a practically-important special case:
+ an index scan is a ROR scan if it is done using a condition in form
- "key1_1=c_1 AND ... AND key1_n=c_n" (1)
+ "key1_1=c_1 AND ... AND key1_n=c_n"
where the index is defined on (key1_1, ..., key1_N [,a_1, ..., a_n])
- and the table has a clustered Primary Key
+ and the table has a clustered Primary Key defined as
- PRIMARY KEY(a_1, ..., a_n, b1, ..., b_k) with first key parts being
- identical to uncovered parts ot the key being scanned (2)
-
- Scans on HASH indexes are not ROR scans,
- any range scan on clustered primary key is ROR scan (3)
-
- Check (1) is made in check_quick_keys()
- Check (3) is made check_quick_select()
- Check (2) is made by this function.
+ PRIMARY KEY(a_1, ..., a_n, b1, ..., b_k)
+
+ i.e. the first key parts of it are identical to uncovered parts ot the
+ key being scanned. This function assumes that the index flags do not
+ include HA_KEY_SCAN_NOT_ROR flag (that is checked elsewhere).
RETURN
- TRUE If the scan is ROR-scan
- FALSE otherwise
+ TRUE The scan is ROR-scan
+ FALSE Otherwise
*/
static bool is_key_scan_ror(PARAM *param, uint keynr, uint8 nparts)