Skip to content

Commit fca37e4

Browse files
spetruniavuvova
authored andcommitted
MDEV-27529 Wrong result upon query using index_merge with DESC key (#2)
ROR-index_merge relies on Rowid-ordered-retrieval property: a ROR scan, e.g. a scan on equality range tbl.key=const should return rows ordered by their Rowid. Also, handler->cmp_ref() should compare rowids according to the Rowid ordering. When the table's primary key uses DESC keyparts, ROR scans return rows according to the PK's ordering. But ha_innobase::cmp_ref() compared rowids as if PK used ASC keyparts. This caused wrong query results with index_merge. Fixed this by making ha_innobase::cmp_ref() compare according to the PK defintion, including keypart's DESC property.
1 parent 62760af commit fca37e4

File tree

3 files changed

+53
-2
lines changed

3 files changed

+53
-2
lines changed

mysql-test/main/desc_index_range.result

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,29 @@ CREATE OR REPLACE TABLE t1 (pk INT, a INT, b int, KEY(a), PRIMARY KEY(pk DESC))
186186
INSERT INTO t1 VALUES (1,4,5),(2,9,6),(3,NULL,7),(4,NULL,8);
187187
SELECT * FROM t1 WHERE pk > 10 OR a > 0;
188188
pk a b
189-
1 4 5
190189
2 9 6
190+
1 4 5
191191
DROP TABLE t1;
192+
#
193+
# MDEV-27529: Wrong result upon query using index_merge with DESC key (#2)
194+
#
195+
create table t1 (
196+
pk int,
197+
a int,
198+
b int,
199+
primary key(pk desc),
200+
key(a),
201+
key(b)
202+
) engine=innodb;
203+
insert into t1 values (0, 111111, 255);
204+
insert into t1 select seq+50000, NULL, seq+1000 from seq_1_to_260;
205+
insert into t1 values (10000, NULL, 255);
206+
insert into t1 select seq+20000, seq+20000, seq+20000 from seq_1_to_1500;
207+
# Must use ROR-intersect:
208+
explain select * from t1 where b = 255 AND a IS NULL;
209+
id select_type table type possible_keys key key_len ref rows Extra
210+
1 SIMPLE t1 index_merge a,b b,a 5,5 NULL 1 Using intersect(b,a); Using where; Using index
211+
select * from t1 where b = 255 AND a IS NULL;
212+
pk a b
213+
10000 NULL 255
214+
drop table t1;

mysql-test/main/desc_index_range.test

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,30 @@ INSERT INTO t1 VALUES (1,4,5),(2,9,6),(3,NULL,7),(4,NULL,8);
9696

9797
SELECT * FROM t1 WHERE pk > 10 OR a > 0;
9898
DROP TABLE t1;
99+
100+
101+
--echo #
102+
--echo # MDEV-27529: Wrong result upon query using index_merge with DESC key (#2)
103+
--echo #
104+
105+
create table t1 (
106+
pk int,
107+
a int,
108+
b int,
109+
primary key(pk desc),
110+
key(a),
111+
key(b)
112+
) engine=innodb;
113+
114+
insert into t1 values (0, 111111, 255);
115+
116+
insert into t1 select seq+50000, NULL, seq+1000 from seq_1_to_260;
117+
118+
insert into t1 values (10000, NULL, 255);
119+
insert into t1 select seq+20000, seq+20000, seq+20000 from seq_1_to_1500;
120+
121+
--echo # Must use ROR-intersect:
122+
explain select * from t1 where b = 255 AND a IS NULL;
123+
select * from t1 where b = 255 AND a IS NULL;
124+
125+
drop table t1;

storage/innobase/handler/ha_innodb.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16772,7 +16772,8 @@ ha_innobase::cmp_ref(
1677216772
}
1677316773

1677416774
if (result) {
16775-
16775+
if (key_part->key_part_flag & HA_REVERSE_SORT)
16776+
result = -result;
1677616777
return(result);
1677716778
}
1677816779

0 commit comments

Comments
 (0)