mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
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().
This commit is contained in:
parent
77e2aca3f0
commit
71c781bfe7
3 changed files with 19 additions and 14 deletions
|
@ -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 @@ no_icp:
|
|||
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 @@ public:
|
|||
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 @@ protected:
|
|||
@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)
|
||||
|
|
Loading…
Reference in a new issue