diff options
author | Igor Babaev <igor@askmonty.org> | 2022-01-07 11:52:25 -0800 |
---|---|---|
committer | Igor Babaev <igor@askmonty.org> | 2022-01-07 11:52:25 -0800 |
commit | 8265d6d9f632add97f0d13cdfca7188164ba8f2c (patch) | |
tree | d8e1a1034fef783dd0e1475fbb73c637790a9d7f /sql/item_subselect.cc | |
parent | c18896f9c1ce6e4b9a8519a2d5155698d82ae45a (diff) | |
download | mariadb-git-8265d6d9f632add97f0d13cdfca7188164ba8f2c.tar.gz |
MDEV-22846 Server crashes in handler_index_cond_check on SELECT
If the optimizer decides to rewrites a NOT IN predicand of the form
outer_expr IN (SELECT inner_col FROM ... WHERE subquery_where)
into the EXISTS subquery
EXISTS (SELECT 1 FROM ... WHERE subquery_where AND
(outer_expr=inner_col OR inner_col IS NULL))
then the pushed equality predicate outer_expr=inner_col can be used for
ref[or_null] access if inner_col is a reference to an indexed column.
In this case if there is a selective range condition over this column then
a Rowid filter may be employed coupled the with ref[or_null] access. The
filter is 'pushed' into the engine and in InnoDB currently it cannot be
used with index look-ups by primary key. The ref[or_null] access can be
used only when outer_expr is not NULL. Otherwise the original predicand
is evaluated to TRUE only if the result set returned by the query
SELECT 1 FROM ... WHERE subquery_where
is empty. When performing this evaluation the executor switches to the
table scan by primary key. Before this patch the pushed filter still
remained marked as active and the engine tried to apply the filter. This
was incorrect and in InnoDB this attempt to use the filter led to an
assertion failure.
This patch fixes the problem by disabling usage of the filter when
outer_expr is evaluated to NULL.
Diffstat (limited to 'sql/item_subselect.cc')
-rw-r--r-- | sql/item_subselect.cc | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 82b40966e4f..56ab0f648ee 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -4026,6 +4026,8 @@ int subselect_single_select_engine::exec() tab->save_read_record= tab->read_record.read_record_func; tab->read_record.read_record_func= rr_sequential; tab->read_first_record= read_first_record_seq; + if (tab->rowid_filter) + tab->table->file->disable_pushed_rowid_filter(); tab->read_record.thd= join->thd; tab->read_record.ref_length= tab->table->file->ref_length; tab->read_record.unlock_row= rr_unlock_row; @@ -4046,6 +4048,8 @@ int subselect_single_select_engine::exec() tab->read_record.ref_length= 0; tab->read_first_record= tab->save_read_first_record; tab->read_record.read_record_func= tab->save_read_record; + if (tab->rowid_filter) + tab->table->file->enable_pushed_rowid_filter(); } executed= 1; if (!(uncacheable() & ~UNCACHEABLE_EXPLAIN) && |