summaryrefslogtreecommitdiff
path: root/sql/multi_range_read.cc
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2020-01-18 13:26:03 -0800
committerIgor Babaev <igor@askmonty.org>2020-01-18 13:26:19 -0800
commit4de32015be82d0f484a7b49a427853ea7b6da5fd (patch)
tree5054ffc5f75627e44eb40c9b851b6e45ed30d0d2 /sql/multi_range_read.cc
parent057fbfa3563d1161ce9400fb4368035d84334f04 (diff)
downloadmariadb-git-4de32015be82d0f484a7b49a427853ea7b6da5fd.tar.gz
MDEV-21356 ERROR 1032 Can't find record when running simple, single-table query
This bug could happen when both optimizer switches 'mrr' and 'mrr_sort_keys' are enabled and the optimizer decided to use a rowid filter when accessing an InnoDB table by a secondary key. With the above setting any access by a secondary is converted to the rndpos access. In InnoDB the rndpos access uses the primary key. Currently usage of a rowid filter within InnoDB engine is not supported if the table is accessed by the primary key. Do not use pushed rowid filter if the table is accessed actually by the primary key. Use the rowid filter outside the egine code instead.
Diffstat (limited to 'sql/multi_range_read.cc')
-rw-r--r--sql/multi_range_read.cc24
1 files changed, 24 insertions, 0 deletions
diff --git a/sql/multi_range_read.cc b/sql/multi_range_read.cc
index 4fc386a0afe..7e4c2ed1f53 100644
--- a/sql/multi_range_read.cc
+++ b/sql/multi_range_read.cc
@@ -19,6 +19,7 @@
#include "sql_select.h"
#include "key.h"
#include "sql_statistics.h"
+#include "rowid_filter.h"
static ulonglong key_block_no(TABLE *table, uint keyno, ha_rows keyentry_pos)
{
@@ -709,6 +710,20 @@ int Mrr_ordered_rndpos_reader::init(handler *h_arg,
is_mrr_assoc= !MY_TEST(mode & HA_MRR_NO_ASSOCIATION);
index_reader_exhausted= FALSE;
index_reader_needs_refill= TRUE;
+
+ /*
+ Currently usage of a rowid filter within InnoDB engine is not supported
+ if the table is accessed by the primary key.
+ With optimizer switches ''mrr' and 'mrr_sort_keys' are both enabled
+ any access by a secondary index is converted to the rndpos access. In
+ InnoDB the rndpos access is always uses the primary key.
+ Do not use pushed rowid filter if the table is accessed actually by the
+ primary key. Use the rowid filter outside the engine code (see
+ Mrr_ordered_rndpos_reader::refill_from_index_reader).
+ */
+ if (file->pushed_rowid_filter && file->primary_key_is_clustered())
+ file->cancel_pushed_rowid_filter();
+
return 0;
}
@@ -801,6 +816,15 @@ int Mrr_ordered_rndpos_reader::refill_from_index_reader()
index_reader->position();
+ /*
+ If the built rowid filter cannot be used at the engine level use it here.
+ */
+ Rowid_filter *rowid_filter=
+ file->get_table()->reginfo.join_tab->rowid_filter;
+ if (rowid_filter && !file->pushed_rowid_filter &&
+ !rowid_filter->check((char *)index_rowid))
+ continue;
+
/* Put rowid, or {rowid, range_id} pair into the buffer */
rowid_buffer->write_ptr1= index_rowid;
rowid_buffer->write_ptr2= (uchar*)&range_info;