MDEV-36896 - Assertion `marked_for_read()' failed in virtual String *Field_varstring::val_str(String *, String *)#5158
MDEV-36896 - Assertion `marked_for_read()' failed in virtual String *Field_varstring::val_str(String *, String *)#5158pranavktiwari wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
Code Review
This pull request comments out the column_bitmaps_set call in sql/filesort.cc to address an assertion failure. However, the reviewer notes that this is incorrect because it bypasses the temporary read map optimization and pollutes the original read set. The recommended approach is to identify the missing field and ensure it is properly registered instead of disabling the bitmap switch.
834f750 to
5b140dc
Compare
There was a problem hiding this comment.
Pull request overview
Fixes MDEV-36896 where virtual/generated column evaluation during filesort can trip marked_for_read() assertions due to column bitmap aliasing, and adds a regression test to cover the scenario.
Changes:
- Adjusts
TABLE::update_virtual_field()bitmap handling to avoid clearing shared column maps during virtual column evaluation. - Extends
vcol_misctest coverage with a new MDEV-36896 regression case (InnoDB + filesort + virtual column).
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
sql/table.cc |
Changes how the dependency-walk bitmap is handled during single virtual column evaluation. |
mysql-test/suite/vcol/t/vcol_misc.test |
Adds an MDEV-36896 regression scenario and introduces an InnoDB requirement. |
mysql-test/suite/vcol/r/vcol_misc.result |
Updates expected output for the new regression scenario. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| in_use->set_n_backup_active_arena(expr_arena, &backup_arena); | ||
| bitmap_clear_all(&tmp_set); | ||
| vf->vcol_info->expr->walk(&Item::update_vcol_processor, 0, &tmp_set); | ||
| DBUG_FIX_WRITE_SET(vf); |
There was a problem hiding this comment.
not needed, It will add the required ones.
| --source include/have_ucs2.inc | ||
| --source include/have_debug.inc | ||
| --source include/have_innodb.inc |
| SET tx_isolation='READ-UNCOMMITTED'; | ||
| CREATE TABLE t (a VARCHAR(10),b INT,c CHAR(10) GENERATED ALWAYS AS (a) VIRTUAL,KEY(b,c)) ENGINE=InnoDB; | ||
| INSERT INTO t (a) VALUES ('A'); | ||
| SELECT * FROM t WHERE b IS NULL ORDER BY a; |
| SET tx_isolation='READ-UNCOMMITTED'; | ||
| CREATE TABLE t (a VARCHAR(10),b INT,c CHAR(10) GENERATED ALWAYS AS (a) VIRTUAL,KEY(b,c)) ENGINE=InnoDB; | ||
| INSERT INTO t (a) VALUES ('A'); | ||
| SELECT * FROM t WHERE b IS NULL ORDER BY a; | ||
| a b c | ||
| A NULL A |
sanja-byelkin
left a comment
There was a problem hiding this comment.
Main description should be in commit comment. (what is in PR comment irrelevant and will be lost.
Investigate please this statement (not necessary correct):
Since the nested-vcol recursion guard was added (Item_field::update_vcol_processor uses bitmap_fast_test_and_set at item.cc:984), tmp_set doubles as the per-call "visited" set. Deleting the clear means it's never reset across calls on a reused TABLE. For a vcol-on-vcol dependency, the nested column's bit can already be set from a prior call, so it gets silently skipped and reuses a stale value — no error.
| SET tx_isolation='READ-UNCOMMITTED'; | ||
| CREATE TABLE t (a VARCHAR(10),b INT,c CHAR(10) GENERATED ALWAYS AS (a) VIRTUAL,KEY(b,c)) ENGINE=InnoDB; | ||
| INSERT INTO t (a) VALUES ('A'); | ||
| SELECT * FROM t WHERE b IS NULL ORDER BY a; |
| --echo # End of 10.5 tests | ||
| --echo # | ||
|
|
||
| # |
| # | ||
|
|
||
| SET tx_isolation='READ-UNCOMMITTED'; | ||
| CREATE TABLE t (a VARCHAR(10),b INT,c CHAR(10) GENERATED ALWAYS AS (a) VIRTUAL,KEY(b,c)) ENGINE=InnoDB; |
There was a problem hiding this comment.
the test incorrecly cleanup (no DELETE). Have you run the test alone? nothing was suspiciouse?
| # MDEV-36896 Assertion `marked_for_read()' failed in virtual String *Field_varstring::val_str(String *, String *) | ||
| # | ||
|
|
||
| SET tx_isolation='READ-UNCOMMITTED'; |
There was a problem hiding this comment.
the some with the variable. old value should be saved and restored.
| # End of 10.5 tests | ||
| # | ||
| SET tx_isolation='READ-UNCOMMITTED'; | ||
| CREATE TABLE t (a VARCHAR(10),b INT,c CHAR(10) GENERATED ALWAYS AS (a) VIRTUAL,KEY(b,c)) ENGINE=InnoDB; |
There was a problem hiding this comment.
add also test case with nested fields (fields in expression like a=c)
f809da3 to
3dd20f7
Compare
…Field_varstring::val_str(String *, String *) Problem: Executing queries that require virtual/generated column evaluation during filesort trigger sdebug assertions due to missing columns in read_set. Cause: find_all_keys() temporarily assigns TABLE::tmp_set as both read_set and write_set. Later, TABLE::update_virtual_field() clears tmp_set before evaluating virtual column dependencies. Since all three pointers reference the same bitmap, clearing tmp_set also clears the active column maps, causing required columns to be missing during execution. Fix: Remove the bitmap_clear_all(&tmp_set) call from TABLE::update_virtual_field(). The dependency walk populates the required bits for virtual column evaluation, and clearing the shared bitmap can unintentionally invalidate the active read_set/write_set.
3dd20f7 to
4428320
Compare
In this method we are recursively just checking for virtual columns but before calling this method read_set is being cleared, hence it will never have bit set for actual columns. But I think, removing bitmap_clear_all(&tmp_set); this line is definitely not a good solution. Rather this update_vcol_processor method should evolve to handle this case as well. |
| MY_BITMAP local_set; | ||
| my_bitmap_init(&local_set, NULL, s->fields); | ||
| bitmap_set_bit(&local_set, vf->field_index); |
fixes MDEV-36896
Problem:
Executing queries that require virtual/generated column evaluation during filesort trigger sdebug assertions due to missing columns in read_set.
Cause:
find_all_keys() temporarily assigns TABLE::tmp_set as both read_set and write_set. Later, TABLE::update_virtual_field() clears tmp_set before evaluating virtual column dependencies.
Since all three pointers reference the same bitmap, clearing tmp_set also clears the active column maps, causing required columns to be missing during execution.
Fix:
Remove the bitmap_clear_all(&tmp_set) call from TABLE::update_virtual_field(). The dependency walk populates the required bits for virtual column evaluation, and clearing the shared bitmap can unintentionally invalidate the active read_set/write_set.