Skip to content

MDEV-36896 - Assertion `marked_for_read()' failed in virtual String *Field_varstring::val_str(String *, String *)#5158

Open
pranavktiwari wants to merge 3 commits into
10.11from
10.11-MDEV-36896
Open

MDEV-36896 - Assertion `marked_for_read()' failed in virtual String *Field_varstring::val_str(String *, String *)#5158
pranavktiwari wants to merge 3 commits into
10.11from
10.11-MDEV-36896

Conversation

@pranavktiwari

@pranavktiwari pranavktiwari commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

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.

@pranavktiwari pranavktiwari marked this pull request as draft June 1, 2026 13:06

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread sql/filesort.cc Outdated
@pranavktiwari pranavktiwari changed the title DRAFT - Assertion `marked_for_read()' failed in virtual String *Field_varstring::val_str(String *, String *) MDEV-36896 - Assertion `marked_for_read()' failed in virtual String *Field_varstring::val_str(String *, String *) Jun 2, 2026
@pranavktiwari pranavktiwari marked this pull request as ready for review June 2, 2026 06:24
@sanja-byelkin sanja-byelkin requested a review from Copilot June 23, 2026 09:54

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_misc test 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.

Comment thread sql/table.cc
Comment on lines 9189 to 9191
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);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not needed, It will add the required ones.

Comment thread mysql-test/suite/vcol/t/vcol_misc.test Outdated
Comment on lines +1 to +3
--source include/have_ucs2.inc
--source include/have_debug.inc
--source include/have_innodb.inc

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment thread mysql-test/suite/vcol/t/vcol_misc.test Outdated
Comment on lines +569 to +572
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;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines +594 to +599
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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@sanja-byelkin sanja-byelkin left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread mysql-test/suite/vcol/t/vcol_misc.test Outdated
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;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Version end marking.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment thread mysql-test/suite/vcol/t/vcol_misc.test Outdated
--echo # End of 10.5 tests
--echo #

#

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--echo is absent

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment thread mysql-test/suite/vcol/t/vcol_misc.test Outdated
#

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;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the test incorrecly cleanup (no DELETE). Have you run the test alone? nothing was suspiciouse?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment thread mysql-test/suite/vcol/t/vcol_misc.test Outdated
# MDEV-36896 Assertion `marked_for_read()' failed in virtual String *Field_varstring::val_str(String *, String *)
#

SET tx_isolation='READ-UNCOMMITTED';

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the some with the variable. old value should be saved and restored.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

# 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;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add also test case with nested fields (fields in expression like a=c)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@pranavktiwari pranavktiwari force-pushed the 10.11-MDEV-36896 branch 2 times, most recently from f809da3 to 3dd20f7 Compare June 24, 2026 07:22
…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.
@pranavktiwari

Copy link
Copy Markdown
Contributor Author

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.

bool Item_field::update_vcol_processor(void *arg)
{
  MY_BITMAP *map= (MY_BITMAP *) arg;
  if (field->vcol_info &&
      !bitmap_fast_test_and_set(map, field->field_index))
  {
    field->vcol_info->expr->walk(&Item::update_vcol_processor, 0, arg);
    field->vcol_info->expr->save_in_field(field, 0);
  }
  return 0;
}

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.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Comment thread sql/table.cc
Comment on lines +9191 to +9193
MY_BITMAP local_set;
my_bitmap_init(&local_set, NULL, s->fields);
bitmap_set_bit(&local_set, vf->field_index);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

4 participants