mirror of
https://github.com/MariaDB/server.git
synced 2026-10-23 18:49:29 +03:00
MDEV-28610 : Assertion marked_for_read() failed upon range select with virtual column in index.
Problem: Executing a range select using an index that includes virtual/generated columns (e.g. SELECT ... WHERE c BETWEEN ... ORDER BY d) could trigger: Assertion 'marked_for_read()' failed in Field access during execution. Cause: The keyread initialization path was populating table->read_set using mark_index_columns(), which follows the non-recursive index marking path. This only marks direct index fields and does not resolve dependencies of virtual/generated columns. As a result, when an index contained virtual columns, their dependent base columns were not included in read_set, leading to invalid access during later evaluation of virtual columns. Fix: Replace mark_index_columns() with mark_index_columns_for_read() in the keyread initialization path. This ensures the recursive read-marking logic is used, so virtual/generated column dependencies are correctly propagated into read_set before execution.
This commit is contained in:
committed by
Pranav Tiwari
parent
209c510d9e
commit
885587d369
@@ -618,4 +618,22 @@ NULL
|
||||
NULL
|
||||
NULL
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# MDEV-28610 Assertion `marked_for_read()' failed upon range select with virtual column in index
|
||||
#
|
||||
CREATE TABLE t (
|
||||
a INT UNSIGNED NOT NULL DEFAULT 0,
|
||||
b INT AS (a) VIRTUAL,
|
||||
c TIME,
|
||||
d INT,
|
||||
e DATE,
|
||||
f VARCHAR(1024),
|
||||
PRIMARY KEY(c),
|
||||
KEY(c,b,d,f(64))
|
||||
);
|
||||
INSERT INTO t (c) VALUES ('00:00:00'),('00:00:04');
|
||||
SELECT c FROM t WHERE c BETWEEN '00:00:00' AND '00:00:00' ORDER BY d;
|
||||
c
|
||||
00:00:00
|
||||
DROP TABLE t;
|
||||
# End of 10.11 tests
|
||||
|
||||
@@ -592,4 +592,24 @@ SELECT VALUE( vid ) FROM (select * from t1)dt;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-28610 Assertion `marked_for_read()' failed upon range select with virtual column in index
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t (
|
||||
a INT UNSIGNED NOT NULL DEFAULT 0,
|
||||
b INT AS (a) VIRTUAL,
|
||||
c TIME,
|
||||
d INT,
|
||||
e DATE,
|
||||
f VARCHAR(1024),
|
||||
PRIMARY KEY(c),
|
||||
KEY(c,b,d,f(64))
|
||||
);
|
||||
INSERT INTO t (c) VALUES ('00:00:00'),('00:00:04');
|
||||
SELECT c FROM t WHERE c BETWEEN '00:00:00' AND '00:00:00' ORDER BY d;
|
||||
|
||||
# Cleanup
|
||||
DROP TABLE t;
|
||||
|
||||
--echo # End of 10.11 tests
|
||||
|
||||
@@ -11699,7 +11699,7 @@ bool Field::save_in_field_ignore_value(bool view_error_processing)
|
||||
|
||||
void Field::register_field_in_read_map()
|
||||
{
|
||||
if (vcol_info)
|
||||
if (!stored_in_db())
|
||||
{
|
||||
Item *vcol_item= vcol_info->expr;
|
||||
vcol_item->walk(&Item::register_field_in_read_map, 1, 0);
|
||||
|
||||
@@ -33052,9 +33052,9 @@ void JOIN::init_join_cache_and_keyread()
|
||||
depends on are automatically added to the read_set - because they're
|
||||
needed to calculate the vcol.
|
||||
But if we're doing keyread, vcol is taken
|
||||
from the index, not calculated, and base columns do not need to be
|
||||
in the read set. To ensure this we try to set the read_set to only
|
||||
the key-parts of the indexes.
|
||||
from the index, not calculated. The below call adds the key-parts
|
||||
to the read_set, and for virtual columns also adds any base columns
|
||||
they depend on.
|
||||
|
||||
Another side effect of this is
|
||||
Lets say you have a query
|
||||
@@ -33066,7 +33066,10 @@ void JOIN::init_join_cache_and_keyread()
|
||||
tuple.
|
||||
*/
|
||||
if (!(table->file->index_flags(table->file->keyread, 0, 1) & HA_CLUSTERED_INDEX))
|
||||
table->mark_index_columns(table->file->keyread, table->read_set);
|
||||
{
|
||||
bitmap_clear_all(table->read_set);
|
||||
table->mark_index_columns_for_read(table->file->keyread);
|
||||
}
|
||||
}
|
||||
bool init_for_explain= false;
|
||||
|
||||
|
||||
@@ -7819,7 +7819,7 @@ inline void TABLE::mark_index_columns_no_reset(uint index, MY_BITMAP *bitmap)
|
||||
}
|
||||
|
||||
|
||||
inline void TABLE::mark_index_columns_for_read(uint index)
|
||||
void TABLE::mark_index_columns_for_read(uint index)
|
||||
{
|
||||
do_mark_index_columns(this, index, read_set, true);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user