Skip to content
Permalink
Browse files
MDEV-25858: Query results are incorrect when indexes are added
If test_if_skip_sort_order() decides to use an index to produce required
ordering,  it should disable "Range Checked for each record" optimization.

This is because Range-Checked-for-each-record may decide to use an index
(or an index_merge) which will not produce the required ordering.
  • Loading branch information
spetrunia committed Jul 15, 2021
1 parent da495b1 commit 6a89f34
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 0 deletions.
@@ -147,4 +147,56 @@ i n
656 eight
set optimizer_switch= @save_optimizer_switch;
DROP TABLE t1,t2,t3;
#
# MDEV-25858: Query results are incorrect when indexes are added
#
CREATE TABLE t1 (id int NOT NULL PRIMARY KEY) engine=innodb;
insert into t1 values (1),(2),(3);
CREATE TABLE t2 (
id int NOT NULL PRIMARY KEY,
id2 int NOT NULL,
d1 datetime,
d2 timestamp NOT NULL,
KEY id2 (id2)
) engine=innodb;
insert into t2 values
(1,2,'2019-03-05 00:00:00','2019-03-06 00:00:00'),
(2,3,'2019-03-05 00:00:00','2019-03-06 00:00:00'),
(3,3,'2019-03-06 00:00:00','2019-03-05 00:00:00');
select
t1.id,t2.id
from
t1 left join
t2 on t2.id2 = t1.id and
t2.id = (select dd.id
from t2 dd
where
dd.id2 = t1.id and
d1 > '2019-02-06 00:00:00'
order by
dd.d1 desc, dd.d2 desc, dd.id desc limit 1
);
id id
1 NULL
2 1
3 3
create index for_latest_sort on t2 (d1 desc, d2 desc, id desc);
select
t1.id,t2.id
from
t1 left join
t2 on t2.id2 = t1.id and
t2.id = (select dd.id
from t2 dd
where
dd.id2 = t1.id and
d1 > '2019-02-06 00:00:00'
order by
dd.d1 desc, dd.d2 desc, dd.id desc limit 1
);
id id
1 NULL
2 1
3 3
drop table t1,t2;
# End of 10.2 tests
@@ -135,4 +135,55 @@ set optimizer_switch= @save_optimizer_switch;

DROP TABLE t1,t2,t3;

--echo #
--echo # MDEV-25858: Query results are incorrect when indexes are added
--echo #

CREATE TABLE t1 (id int NOT NULL PRIMARY KEY) engine=innodb;
insert into t1 values (1),(2),(3);

CREATE TABLE t2 (
id int NOT NULL PRIMARY KEY,
id2 int NOT NULL,
d1 datetime,
d2 timestamp NOT NULL,
KEY id2 (id2)
) engine=innodb;

insert into t2 values
(1,2,'2019-03-05 00:00:00','2019-03-06 00:00:00'),
(2,3,'2019-03-05 00:00:00','2019-03-06 00:00:00'),
(3,3,'2019-03-06 00:00:00','2019-03-05 00:00:00');

select
t1.id,t2.id
from
t1 left join
t2 on t2.id2 = t1.id and
t2.id = (select dd.id
from t2 dd
where
dd.id2 = t1.id and
d1 > '2019-02-06 00:00:00'
order by
dd.d1 desc, dd.d2 desc, dd.id desc limit 1
);

create index for_latest_sort on t2 (d1 desc, d2 desc, id desc);

select
t1.id,t2.id
from
t1 left join
t2 on t2.id2 = t1.id and
t2.id = (select dd.id
from t2 dd
where
dd.id2 = t1.id and
d1 > '2019-02-06 00:00:00'
order by
dd.d1 desc, dd.d2 desc, dd.id desc limit 1
);
drop table t1,t2;

--echo # End of 10.2 tests
@@ -21938,6 +21938,12 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
if (select->quick == save_quick)
save_quick= 0; // make_reverse() consumed it
select->set_quick(tmp);
/* Cancel "Range checked for each record" */
if (tab->use_quick == 2)
{
tab->use_quick= 1;
tab->read_first_record= join_init_read_record;
}
}
else if (tab->type != JT_NEXT && tab->type != JT_REF_OR_NULL &&
tab->ref.key >= 0 && tab->ref.key_parts <= used_key_parts)
@@ -21950,6 +21956,12 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
*/
tab->read_first_record= join_read_last_key;
tab->read_record.read_record= join_read_prev_same;
/* Cancel "Range checked for each record" */
if (tab->use_quick == 2)
{
tab->use_quick= 1;
tab->read_first_record= join_init_read_record;
}
/*
Cancel Pushed Index Condition, as it doesn't work for reverse scans.
*/

0 comments on commit 6a89f34

Please sign in to comment.