Commit e46a3aa4 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-17881 Assertion failure in cmp_dtuple_rec_with_match_bytes after instant ADD COLUMN

The special flag REC_INFO_MIN_REC_FLAG used to be only set on the
first record in the leftmost node pointer page of each level of the tree.
It was never set on leaf pages.

MDEV-11369 Instant ADD COLUMN in MariaDB Server 10.3 repurposed the flag
to identify a hidden metadata record, which is stored in the first record
on the leftmost leaf page.

If the adaptive hash index points to records in the leftmost leaf page
after instant ALTER TABLE, we would have such a metadata record in the
table, an assertion could fail when trying to validate the index record.
In a release build, we might wrongly qualify the hidden metadata record
and thus return garbage results.

cmp_dtuple_rec_with_match_bytes(): If the REC_INFO_MIN_REC_FLAG is
set on the record, assert that this is the first record on the
leftmost page and that the record is a metadata record, and finally
return 1, because by definition, anything is greater than the
minimum record.
parent 0abd2766
......@@ -25,6 +25,7 @@ Created 7/1/1994 Heikki Tuuri
#include "rem0cmp.h"
#include "rem0rec.h"
#include "page0page.h"
#include "dict0mem.h"
#include "handler0alter.h"
......@@ -787,20 +788,23 @@ cmp_dtuple_rec_with_match_bytes(
ulint* matched_fields,
ulint* matched_bytes)
{
ulint n_cmp = dtuple_get_n_fields_cmp(dtuple);
ulint cur_field; /* current field number */
ulint cur_bytes;
int ret; /* return value */
ut_ad(dtuple_check_typed(dtuple));
ut_ad(rec_offs_validate(rec, index, offsets));
ut_ad(!(REC_INFO_MIN_REC_FLAG
& dtuple_get_info_bits(dtuple)));
ut_ad(!(REC_INFO_MIN_REC_FLAG
& rec_get_info_bits(rec, rec_offs_comp(offsets))));
cur_field = *matched_fields;
cur_bytes = *matched_bytes;
if (UNIV_UNLIKELY(REC_INFO_MIN_REC_FLAG
& rec_get_info_bits(rec, rec_offs_comp(offsets)))) {
ut_ad(page_rec_is_first(rec, page_align(rec)));
ut_ad(!page_has_prev(page_align(rec)));
ut_ad(rec_is_metadata(rec, *index));
return 1;
}
ulint cur_field = *matched_fields;
ulint cur_bytes = *matched_bytes;
ulint n_cmp = dtuple_get_n_fields_cmp(dtuple);
int ret;
ut_ad(n_cmp <= dtuple_get_n_fields(dtuple));
ut_ad(cur_field <= n_cmp);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment