diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2019-03-25 10:29:25 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2019-03-25 10:29:48 +0200 |
commit | 71c781bfe758c1296095f99fa529276442b3a1ac (patch) | |
tree | a5ea16fd2157ff0f630f3a35e8ec2ed0b4b6dbc0 | |
parent | 77e2aca3f0795884e8221b30973709b62119fade (diff) | |
download | mariadb-git-71c781bfe758c1296095f99fa529276442b3a1ac.tar.gz |
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().
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 18 | ||||
-rw-r--r-- | storage/innobase/handler/ha_innodb.h | 12 | ||||
-rw-r--r-- | storage/innobase/handler/handler0alter.cc | 3 |
3 files changed, 19 insertions, 14 deletions
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 9366b2db30b..b448f71d6d0 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -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; diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index 76a9b08c4c6..9311056bde5 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -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(); diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 095fad367b3..3faf62479ff 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -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) |