1
0
mirror of https://github.com/MariaDB/server.git synced 2026-10-23 18:49:29 +03:00

MDEV-39644 Evaluate ICP on the current row in reverse partition scans

Ordered reverse scans read partition rows into private buffers, while
index condition pushdown evaluates fields in table->record[0]. The
condition can therefore see a stale row and discard matching rows.

Use the current record for pushed conditions in both the initial and
subsequent reads of an ordered reverse scan. Copy it to the queue buffer
only after a successful read, preserving the buffer on EOF or errors.
Add a focused regression with matching and rejected rows across two
MyISAM partitions.

Bug report: https://jira.mariadb.org/browse/MDEV-39644
This commit is contained in:
DerZc
2026-09-28 14:18:20 +08:00
parent 30728cb672
commit 3e2225b252
3 changed files with 33 additions and 3 deletions

View File

@@ -796,3 +796,13 @@ a b
2 2
3 3
drop table t1;
# MDEV-39644 Evaluate ICP on the current row in reverse partition scans
CREATE TABLE t1 (c1 INT,c2 INT,c3 INT,KEY k(c2,c3))
ENGINE=MyISAM PARTITION BY HASH(c1) PARTITIONS 2;
INSERT INTO t1 VALUES (1,4,1),(2,3,1),(3,2,0),(4,1,1);
SELECT * FROM t1 WHERE c2>=1 AND c3=1 ORDER BY c2 DESC;
c1 c2 c3
1 4 1
2 3 1
4 1 1
DROP TABLE t1;

View File

@@ -846,3 +846,9 @@ insert into t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6);
explain select * from t1 order by a limit 3;
select * from t1 order by a limit 3;
drop table t1;
--echo # MDEV-39644 Evaluate ICP on the current row in reverse partition scans
CREATE TABLE t1 (c1 INT,c2 INT,c3 INT,KEY k(c2,c3))
ENGINE=MyISAM PARTITION BY HASH(c1) PARTITIONS 2;
INSERT INTO t1 VALUES (1,4,1),(2,3,1),(3,2,0),(4,1,1);
SELECT * FROM t1 WHERE c2>=1 AND c3=1 ORDER BY c2 DESC;
DROP TABLE t1;

View File

@@ -104,7 +104,8 @@ static int read_with_icp(TABLE* table,
return func(record_buf);
int error= func(table->record[0]);
memcpy(record_buf, table->record[0], record_buf_len);
if (likely(!error))
memcpy(record_buf, table->record[0], record_buf_len);
return error;
}
@@ -8212,7 +8213,13 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order)
reverse_order= FALSE;
break;
case partition_index_last:
error= file->ha_index_last(rec_buf_ptr);
error= read_with_icp(table,
pushed_idx_cond != nullptr,
rec_buf_ptr,
m_rec_length,
[file] (uchar* read_buf) {
return file->ha_index_last(read_buf);
});
reverse_order= TRUE;
break;
case partition_read_range:
@@ -8738,7 +8745,14 @@ int ha_partition::handle_ordered_prev(uchar *buf)
uchar *rec_buf= queue_top(&m_queue) + ORDERED_REC_OFFSET;
handler *file= m_file[part_id];
if (unlikely((error= file->ha_index_prev(rec_buf))))
error= read_with_icp(table,
pushed_idx_cond != nullptr,
rec_buf,
m_rec_length,
[file] (uchar* read_buf) {
return file->ha_index_prev(read_buf);
});
if (unlikely(error))
{
if (error == HA_ERR_END_OF_FILE && m_queue.elements)
{