You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Bug#21872184 CONDITIONAL JUMP AT JOIN_CACHE::WRITE_RECORD_DATA IN SQL_JOIN_BUFFER.CC
When a query using join buffering and one of the tables inserted into
the join buffer was accessed using "dynamic range scan" on an index
containing a virtual column, a valgrind error occurred when writing
columns to the join buffer.
Using the query from the added test case as example:
SELECT t1.c1, t2.i1
FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2
WHERE ( t3.pk IN
(
SELECT t4.i1
FROM t4
WHERE t4.c1 < 'o'
)
)
AND t1.i1 <= t3.i2_key;
This query joins three tables in the following order:
t1 -> t3 -> t2
The access methods used are:
t1: table scan
t3: dynamic range scan
t2: join buffering
The table t3 is defined as follows:
CREATE TABLE t3 (
pk INTEGER NOT NULL,
i1 INTEGER,
i2_key INTEGER GENERATED ALWAYS AS (i1 + i1) VIRTUAL NOT NULL,
PRIMARY KEY (pk),
KEY (i2_key)
);
The issue arises when we write the (t1, t3) rows into the
join buffer. The join buffer has been configured to include all
columns marked in the read_set for t1 and t3. For the table t3, the
read set contains (pk, i1, i2_key). Out of these, pk and i2_key are
included in the read set due to they are needed for evaluating query
conditions. i1 is included in the read set since it is needed for
computing the value for the virtual column i2_key.
This works fine when t3 is accessed using a table scan but for the
rows where we switch to use "dynamic range scan", a valgrind error is
reported. The valgrind error occurs when we want to copy the i1 field
from the record buffer into the join cache buffer. Since this is a
range scan on the i2_key index, the value for i1 has not been read
into the record buffer (it is not needed). But it is still copied into
the join buffer and the valgrind error happens when the code
checks the null value for this field.
The underlying cause for this problem, is that in order to support
reading the table t3 from the storage engine as a table scan, we add
the i1 field to the TABLE::read_set. When setting up join buffering
for the query, we analyze which fields to include in the join
buffer. This is done in
JOIN_CACHE::filter_virtual_gcol_base_cols(). For table scans, all
fields included in TABLE::read_set is copied to the join buffer. For
access methods that read an index, only the fields included in the
index is copied to the join buffer. When "dynamic range scan" is used,
we do not know at the time when setting up the join buffer whether a table
scan or an index read will be used (or which index that will be
used). So in this case, all fields in the TABLE::read_set is set up to
be copied to the join buffer.
This patch extends JOIN_CACHE::filter_virtual_gcol_base_cols() to
handle dynamic range scan. If any of the indexes that are candidates
for the dynamic range scan is covering, then the table's read set is
adjusted to only contain the columns that can be read by the
alternative covering indexes.
0 commit comments