Analysis:
The send_data method of the result sink class used to collect
data statistics about materialized subqueries incorrectly assumed
that duplicate rows are removed prior to calling send_data. As
a result the collected statistics was wrong, which resulted in
an incorrect maximal number of keys in the Ordered_key buffer.
Solution:
Try to insert each row into the materialized temp table before
collecting statistics, and if the insertion results in a duplicate
row, do not count the current row.
The set of Ordered keys of a rowid merge engine is dense. Thus when
we decide not to create a key for a column that has only NULLs, this
column shouldn't be counted.
Notice that the caller has already precomputed the correct total
number of keys that should be created.
The cause for this bug is that MariaDB 5.3 still processes derived tables
(subqueries in the FROM clause) by fully executing them during the parse
phase. This will be remedied by MWL#106 once merged into the main 5.3.
The assert statement is triggered when MATERIALIZATION is ON for EXPLAIN
EXTENDED for derived tables with an IN subquery as follows:
- mysql_parse calls JOIN::exec for the derived table as if it is regular
execution (not explain).
- When materialization is ON, this call goes all the way to
subselect_hash_sj_engine::exec, which creates a partial match engine
because of NULL presence.
- In order to proceed with normal execution, the hash_sj engine substitutes
itself with the created partial match engine.
- After the parse phase it turns out that this execution was part of
EXPLAIN EXTENDED, which in turn calls
Item_cond::print -> ... -> Item_subselect::print,
which calls engine->print().
Since subselect_hash_sj_engine::exec substituted the current
Item_subselect engine with a partial match engine, eventually we call
its ::print() method. However the partial match engines are designed only
for execution, hence there is no implementation of this print() method.
The fix temporarily removes the assert, until this code is merged with
MWL#106.
The bug is a result of the following change by Monty:
Revision Id: monty@askmonty.org-20100716073301-gstby2062nqd42qv
Timestamp: Fri 2010-07-16 10:33:01 +0300
Where Monty changed the queues interface and implementation.
The fix adjusts the queue_remove call to the new interface.
mysql-test/r/subselect_partial_match.result:
Added new file for tests related to MWL#89.
mysql-test/t/subselect_partial_match.test:
Added new file for tests related to MWL#89.