Commit 71c781bf authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-18090 Assertion failures due to virtual columns after upgrading to 10.2

MariaDB before MDEV-5800 in version 10.2.2 did not support
indexed virtual columns. Non-persistent virtual columns were
hidden from storage engines. Only starting with MDEV-5800, InnoDB
would create internal metadata on virtual columns.

Similar to what was done in MDEV-18084 and MDEV-18960, we adjust two more
code paths for the old tables.

ha_innobase::build_template(): Do not invoke
dict_index_contains_col_or_prefix() for virtual columns if InnoDB
does not store the metadata.

innobase_build_col_map(): Relax an assertion about the number of columns.

ha_innobase::omits_virtual_cols(): Renamed from omits_virtual_cols().
parent 77e2aca3
......@@ -275,12 +275,6 @@ void set_my_errno(int err)
errno = err;
}
static uint omits_virtual_cols(const TABLE_SHARE &share)
{
return share.frm_version < FRM_VER_EXPRESSSIONS &&
share.virtual_fields;
}
/** Checks whether the file name belongs to a partition of a table.
@param[in] file_name file name
@return pointer to the end of the table name part of the file name, or NULL */
......@@ -7475,7 +7469,8 @@ build_template_needs_field(
{
const Field* field = table->field[i];
if (!field->stored_in_db() && omits_virtual_cols(*table->s)) {
if (!field->stored_in_db()
&& ha_innobase::omits_virtual_cols(*table->s)) {
return NULL;
}
......@@ -7632,7 +7627,7 @@ build_template_field(
&templ->rec_prefix_field_no);
}
} else {
ut_ad(!omits_virtual_cols(*table->s));
DBUG_ASSERT(!ha_innobase::omits_virtual_cols(*table->s));
col = &dict_table_get_nth_v_col(index->table, v_no)->m_col;
templ->clust_rec_field_no = v_no;
templ->rec_prefix_field_no = ULINT_UNDEFINED;
......@@ -8019,7 +8014,8 @@ ha_innobase::build_template(
contain = dict_index_contains_col_or_prefix(
index, i - num_v,
false);
} else if (dict_index_is_clust(index)) {
} else if (skip_virtual
|| dict_index_is_clust(index)) {
num_v++;
continue;
} else {
......@@ -8521,7 +8517,7 @@ calc_row_difference(
trx_t* const trx = prebuilt->trx;
doc_id_t doc_id = FTS_NULL_DOC_ID;
ulint num_v = 0;
const bool skip_virtual = omits_virtual_cols(*table->s);
const bool skip_virtual = ha_innobase::omits_virtual_cols(*table->s);
ut_ad(!srv_read_only_mode);
......@@ -11063,7 +11059,7 @@ create_table_info_t::create_table_def()
/* Find out the number of virtual columns. */
ulint num_v = 0;
const bool omit_virtual = omits_virtual_cols(*m_form->s);
const bool omit_virtual = ha_innobase::omits_virtual_cols(*m_form->s);
const ulint n_cols = omit_virtual
? m_form->s->stored_fields : m_form->s->fields;
......
......@@ -22,6 +22,8 @@ this program; if not, write to the Free Software Foundation, Inc.,
# include "../../../wsrep/wsrep_api.h"
#endif /* WITH_WSREP */
#include "table.h"
/* The InnoDB handler: the interface between MySQL and InnoDB. */
/** "GEN_CLUST_INDEX" is the name reserved for InnoDB default
......@@ -412,8 +414,15 @@ class ha_innobase: public handler
Item* idx_cond_push(uint keyno, Item* idx_cond);
/* @} */
protected:
/** Check if InnoDB is not storing virtual column metadata for a table.
@param s table definition (based on .frm file)
@return whether InnoDB will omit virtual column metadata */
static bool omits_virtual_cols(const TABLE_SHARE& s)
{
return s.frm_version<FRM_VER_EXPRESSSIONS && s.virtual_fields;
}
protected:
/**
MySQL calls this method at the end of each statement. This method
exists for readability only, called from reset(). The name reset()
......@@ -430,7 +439,6 @@ class ha_innobase: public handler
@see build_template() */
void reset_template();
protected:
inline void update_thd(THD* thd);
void update_thd();
......
......@@ -3036,7 +3036,8 @@ innobase_build_col_map(
>= altered_table->s->fields + DATA_N_SYS_COLS);
DBUG_ASSERT(dict_table_get_n_cols(old_table)
+ dict_table_get_n_v_cols(old_table)
>= table->s->fields + DATA_N_SYS_COLS);
>= table->s->fields + DATA_N_SYS_COLS
|| ha_innobase::omits_virtual_cols(*table->s));
DBUG_ASSERT(!!add_cols == !!(ha_alter_info->handler_flags
& Alter_inplace_info::ADD_COLUMN));
DBUG_ASSERT(!add_cols || dtuple_get_n_fields(add_cols)
......
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