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

MDEV-27798 SIGSEGV in dict_index_t::reconstruct_fields()

When recovery is rolling back an incomplete instant DROP COLUMN
operation, it may access non-existing fields. Let us avoid
invoking std::find_if() outside the valid bounds of the array.

This bug was reproduced with the Random Query Generator, using a
combination of instant DROP, ADD...FIRST, CHANGE (renaming a column).
Unfortunately, we were unable to create an mtr test case for
reproducing this, despite spending considerable effort on it.
parent 0b849a44
......@@ -2,7 +2,7 @@
Copyright (c) 1996, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
Copyright (c) 2013, 2021, MariaDB Corporation.
Copyright (c) 2013, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
......@@ -1217,6 +1217,8 @@ inline bool dict_index_t::reconstruct_fields()
{
DBUG_ASSERT(is_primary());
const auto old_n_fields = n_fields;
n_fields += table->instant->n_dropped;
n_def += table->instant->n_dropped;
......@@ -1241,11 +1243,11 @@ inline bool dict_index_t::reconstruct_fields()
} else {
DBUG_ASSERT(!c.is_not_null());
const auto old = std::find_if(
fields + n_first, fields + n_fields,
fields + n_first, fields + old_n_fields,
[c](const dict_field_t& o)
{ return o.col->ind == c.ind(); });
if (old >= fields + n_fields
if (old >= fields + old_n_fields
|| old->prefix_len
|| old->col != &table->cols[c.ind()]) {
return true;
......
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