Skip to content

10.11 bugfixes#4939

Open
midenok wants to merge 7 commits into10.11from
bb-10.11-midenok
Open

10.11 bugfixes#4939
midenok wants to merge 7 commits into10.11from
bb-10.11-midenok

Conversation

@midenok
Copy link
Copy Markdown
Contributor

@midenok midenok commented Apr 14, 2026

No description provided.

midenok added 3 commits April 14, 2026 15:14
Usage:

  mtr --mysqld=--debug=d,ref_array,query:i:o,/tmp/mdl.log
…h versioned column

In MDEV-25644 vers_check_update() sets vers_write to false in case it
returns false. It is ok for UPDATE but is not correct for ODKU is bulk
insert requires vers_write on next tuple.

The fix return vers_write value back when vers_check_update() and
related vers_insert_history_row() are done in ODKU.
row_sel_store_mysql_field() does:

3113                    mysql_rec[templ->mysql_null_byte_offset]
3114                            &= static_cast<byte>(~templ->mysql_null_bit_mask);

but mysql_rec[] which is prefetch buffer was allocated without
initialization. Prefetch buffers are allocated by
row_sel_prefetch_cache_init():

3881            ptr = static_cast<byte*>(ut_malloc_nokey(sz));

and then it initializes the buffers with the magic numbers.

The fix initializes the buffers with null bytes as well for nullable
fields.
@midenok midenok requested a review from Copilot April 14, 2026 12:15
@CLAassistant

This comment was marked as outdated.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR delivers a set of 10.11 bugfixes across InnoDB row prefetch caching, SELECT ref-pointer-array diagnostics, sequence-function parsing restrictions in clauses that disallow subqueries/stored functions, and versioned-table ODKU behavior—along with regression tests for the reported MDEV issues.

Changes:

  • Initialize parts of the InnoDB fetch-cache row buffer to avoid uninitialized NULL-bitmap content.
  • Add DBUG instrumentation to track ref_ptrs/all_fields element consumption during JOIN::prepare().
  • Disallow sequence functions (nextval/lastval/setval) when LEX::clause_that_disallows_subselect is set; adjust tests and expected errors accordingly.
  • Fix versioning ODKU behavior by ensuring table->vers_write is set for the next bulk iteration; add regression tests.
  • Add an InnoDB suite regression test for the partition swap_blobs sanitizer/valgrind issue.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
storage/innobase/row/row0sel.cc Initializes fetch-cache row buffers (incl. NULL-bitmap handling) during prefetch-cache allocation.
sql/sql_select.cc Adds debug tracing for ref-array element usage through major phases of JOIN::prepare().
sql/sql_lex.h Clarifies comment docs for clause_that_disallows_subselect.
sql/sql_lex.cc Adds ref-array reservation debug prints; blocks sequence functions in clauses that disallow subqueries/stored functions.
sql/sql_insert.cc Adjusts versioned ODKU flow to ensure vers_write remains set for subsequent bulk iterations; keeps history-row insertion semantics.
mysql-test/suite/versioning/t/update.test Adds regression test for MDEV-38854.
mysql-test/suite/versioning/r/update.result Updates expected output for MDEV-38854 test.
mysql-test/suite/versioning/t/partition.test Adds regression tests for MDEV-36362 expecting ER_SUBQUERIES_NOT_SUPPORTED.
mysql-test/suite/versioning/r/partition.result Updates expected errors/messages for new partition regression tests.
mysql-test/suite/sql_sequence/other.test Updates CHECK-clause expectations to ER_SUBQUERIES_NOT_SUPPORTED for sequence functions.
mysql-test/suite/sql_sequence/other.result Updates expected CHECK-clause error messages/codes accordingly.
mysql-test/suite/innodb/t/bug.test Adds regression test for MDEV-27569 (partition swap_blobs sanitizer/valgrind).
mysql-test/suite/innodb/r/bug.result Expected output for the new InnoDB regression test.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread storage/innobase/row/row0sel.cc
Comment thread mysql-test/suite/innodb/t/bug.test
Copy link
Copy Markdown

Copilot AI left a comment

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 13 out of 13 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread storage/innobase/row/row0sel.cc Outdated
Copy link
Copy Markdown

Copilot AI left a comment

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 13 out of 13 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +3892 to +3897
for (ulint j = 0; j < prebuilt->n_template; j++) {
const mysql_row_templ_t*templ = &prebuilt->mysql_template[j];
if (templ->mysql_null_bit_mask) {
ptr[templ->mysql_null_byte_offset] = 0;
}
}
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

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

The fetch-cache rows are later copied with memcpy(buf, cached_rec, prebuilt->null_bitmap_len), so all bytes of the MySQL NULL-bitmap in each cached row must be initialized. This loop only clears bytes for nullable columns present in mysql_template; if the template does not cover all nullable columns, some NULL-bitmap bytes can remain uninitialized and still get copied, triggering MSAN/valgrind warnings. Consider zero-initializing the full NULL-bitmap region (e.g., the first prebuilt->null_bitmap_len bytes) for each cache slot instead of only template offsets.

Suggested change
for (ulint j = 0; j < prebuilt->n_template; j++) {
const mysql_row_templ_t*templ = &prebuilt->mysql_template[j];
if (templ->mysql_null_bit_mask) {
ptr[templ->mysql_null_byte_offset] = 0;
}
}
/* Initialize the full MySQL NULL-bitmap because fetch-cache
rows may later be copied based on prebuilt->null_bitmap_len. */
memset(ptr, 0, prebuilt->null_bitmap_len);

Copilot uses AI. Check for mistakes.
Comment on lines +3923 to 3924
MEM_UNDEFINED(prebuilt->fetch_cache[0], prebuilt->mysql_row_len);
row_sel_prefetch_cache_init(prebuilt);
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

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

When prebuilt->fetch_cache[0] == NULL, prebuilt->fetch_cache[0] is still a null pointer until row_sel_prefetch_cache_init() sets it. Calling MEM_UNDEFINED(prebuilt->fetch_cache[0], prebuilt->mysql_row_len) here therefore passes a NULL address to MSAN/valgrind instrumentation and can crash or misbehave. Move the MEM_UNDEFINED() call to after row_sel_prefetch_cache_init(prebuilt) (or apply it to the pointer returned/assigned by the init).

Copilot uses AI. Check for mistakes.
midenok added 2 commits April 15, 2026 17:45
Function calls in INTERVAL expression of DDL have little
sense. SETVAL() fails because sequences require opened tables and
vers_set_interval() is called at earlier stage.

The fix throws ER_SUBQUERIES_NOT_SUPPORTED for sequence functions
SETVAL(), NEXTVAL(), LASTVAL() when the context does not allow
subselect (determined by clause_that_disallows_subselect).
midenok added 2 commits April 15, 2026 17:48
The problem with the current initialization is that TABLE_LIST ctors
as well as init_one_table*() functions call reset() that byte-zeroes
the object after encapsulated objects were initialized by their
constructors. That specifically creates the wrong value for
mdl_request.type which must be MDL_NOT_INITIALIZED (-1) by default and
bzero() reverts it to MDL_INTENTION_EXCLUSIVE (0). And these constant
values is not easy (if not possible) to change.

The fix introduces utility base class Byte_zero which moves bzero()
call before the encapsulated ctors (as parent classes' ctors are
called first). So now encapsulated ctors are not called redundantly
and no double initialization is needed.

All the C++-constructed objects call init_one_table*() as before, only
without reset(). The C-alloced objects call init_one_tab*_r() versions
that call reset(). These will be replaced back to no-reset() versions
after their allocation is refactored to C++ version.
As C++ style initialization of TABLE_LIST now works correctly after
Byte_zero refactoring. We may remove MDL_NOT_INITIALIZED double
initialiation.
@RazvanLiviuVarzaru
Copy link
Copy Markdown

RazvanLiviuVarzaru commented Apr 15, 2026

Hi @midenok !

If you don’t mind, may I kindly suggest that you avoid using a bb- branch and a Pull Request at the same time for the pull requests you open? This ends up duplicating builds in Buildbot. I’m working on a solution to cancel the unnecessary ones, but it would really help me a lot if your source branch for this Pull Request (or others) didn’t include bb- in its name.

Also, one more thing please: pushes that happen more frequently than once per minute, but still quite often, generate a very large number of builds. Again, I’m working on a solution here as well to cancel the older ones.

Thank you very much for your understanding!

Copy link
Copy Markdown

Copilot AI left a comment

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 30 out of 30 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread sql/table.h
}

TABLE_LIST(TABLE *table_arg, thr_lock_type lock_type)
TABLE_LIST(TABLE *table_arg, thr_lock_type lock_type) : Byte_zero(*this)
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

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

TABLE_LIST(TABLE *table_arg, ...) initializes the Byte_zero base with *this, but Byte_zero expects a size_t. This should not compile, and even if it did, the intent appears to be zeroing sizeof(*this) like the other constructors.

Suggested change
TABLE_LIST(TABLE *table_arg, thr_lock_type lock_type) : Byte_zero(*this)
TABLE_LIST(TABLE *table_arg, thr_lock_type lock_type) : Byte_zero(sizeof(*this))

Copilot uses AI. Check for mistakes.
@midenok
Copy link
Copy Markdown
Contributor Author

midenok commented Apr 15, 2026

Hi @midenok !

If you don’t mind, may I kindly suggest that you avoid using a bb- branch and a Pull Request at the same time for the pull requests you open? This ends up duplicating builds in Buildbot. I’m working on a solution to cancel the unnecessary ones, but it would really help me a lot if your source branch for this Pull Request (or others) didn’t include bb- in its name.

Also, one more thing please: pushes that happen more frequently than once per minute, but still quite often, generate a very large number of builds. Again, I’m working on a solution here as well to cancel the older ones.

Thank you very much for your understanding!

I thought it was fixed long ago, but it was not actually... @RazvanLiviuVarzaru, do you know the solution?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants