diff --git a/mysql-test/main/partition_order.result b/mysql-test/main/partition_order.result index d4a0c133d1091..998e4c01b430d 100644 --- a/mysql-test/main/partition_order.result +++ b/mysql-test/main/partition_order.result @@ -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; diff --git a/mysql-test/main/partition_order.test b/mysql-test/main/partition_order.test index f5cd4c2507417..3fee60a3e3d4d 100644 --- a/mysql-test/main/partition_order.test +++ b/mysql-test/main/partition_order.test @@ -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; diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 343ab395ffc32..ca3d6211e1e35 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -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; } @@ -8208,11 +8209,22 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order) /* Caller has specified reverse_order */ break; case partition_index_first: + /* + We don't call read_with_icp() here as full index scans are not done + with ICP. + */ + DBUG_ASSERT(!pushed_idx_cond); error= file->ha_index_first(rec_buf_ptr); 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 +8750,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) {