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