Commit 9471dbaf authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-18960: Assertion !omits_virtual_cols(*form->s) on TRUNCATE

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.

On TRUNCATE TABLE, an old .frm file from before MDEV-5800 may be
used as the table schema. When the table is being re-created by
InnoDB, the old schema must be used. That is, we may hide
the existence of virtual columns from InnoDB.

create_table_check_doc_id_col(): Remove the assertion that failed.
This function can actually correctly deal with virtual columns
that could have been created before MariaDB 10.2.2 introduced MDEV-5800.

create_table_info_t::create_table_def(): Do not create metadata for
virtual columns if the table definition was created before MariaDB 10.2.2.
parent 00572a0b
...@@ -10847,8 +10847,6 @@ create_table_check_doc_id_col( ...@@ -10847,8 +10847,6 @@ create_table_check_doc_id_col(
ULINT_UNDEFINED if column is of the ULINT_UNDEFINED if column is of the
wrong type/name/size */ wrong type/name/size */
{ {
ut_ad(!omits_virtual_cols(*form->s));
for (ulint i = 0; i < form->s->fields; i++) { for (ulint i = 0; i < form->s->fields; i++) {
const Field* field; const Field* field;
ulint col_type; ulint col_type;
...@@ -11022,7 +11020,6 @@ int ...@@ -11022,7 +11020,6 @@ int
create_table_info_t::create_table_def() create_table_info_t::create_table_def()
{ {
dict_table_t* table; dict_table_t* table;
ulint n_cols;
ulint col_type; ulint col_type;
ulint col_len; ulint col_len;
ulint nulls_allowed; ulint nulls_allowed;
...@@ -11030,14 +11027,11 @@ create_table_info_t::create_table_def() ...@@ -11030,14 +11027,11 @@ create_table_info_t::create_table_def()
ulint binary_type; ulint binary_type;
ulint long_true_varchar; ulint long_true_varchar;
ulint charset_no; ulint charset_no;
ulint i;
ulint j = 0; ulint j = 0;
ulint doc_id_col = 0; ulint doc_id_col = 0;
ibool has_doc_id_col = FALSE; ibool has_doc_id_col = FALSE;
mem_heap_t* heap; mem_heap_t* heap;
ulint num_v = 0;
ulint space_id = 0; ulint space_id = 0;
ulint actual_n_cols;
ha_table_option_struct *options= m_form->s->option_struct; ha_table_option_struct *options= m_form->s->option_struct;
dberr_t err = DB_SUCCESS; dberr_t err = DB_SUCCESS;
...@@ -11068,14 +11062,15 @@ create_table_info_t::create_table_def() ...@@ -11068,14 +11062,15 @@ create_table_info_t::create_table_def()
DBUG_RETURN(ER_WRONG_TABLE_NAME); DBUG_RETURN(ER_WRONG_TABLE_NAME);
} }
n_cols = m_form->s->fields; /* Find out the number of virtual columns. */
ulint num_v = 0;
/* Find out any virtual column */ const bool omit_virtual = omits_virtual_cols(*m_form->s);
for (i = 0; i < n_cols; i++) { const ulint n_cols = omit_virtual
Field* field = m_form->field[i]; ? m_form->s->stored_fields : m_form->s->fields;
if (innobase_is_v_fld(field)) { if (!omit_virtual) {
num_v++; for (ulint i = 0; i < n_cols; i++) {
num_v += !m_form->field[i]->stored_in_db();
} }
} }
...@@ -11086,7 +11081,9 @@ create_table_info_t::create_table_def() ...@@ -11086,7 +11081,9 @@ create_table_info_t::create_table_def()
if (doc_id_col == ULINT_UNDEFINED) { if (doc_id_col == ULINT_UNDEFINED) {
err = DB_ERROR; err = DB_ERROR;
goto error_ret; error_ret:
DBUG_RETURN(convert_error_code_to_mysql(err, m_flags,
m_thd));
} else { } else {
has_doc_id_col = TRUE; has_doc_id_col = TRUE;
} }
...@@ -11096,10 +11093,8 @@ create_table_info_t::create_table_def() ...@@ -11096,10 +11093,8 @@ create_table_info_t::create_table_def()
determine the actual space id when the tablespace is created. */ determine the actual space id when the tablespace is created. */
/* Adjust the number of columns for the FTS hidden field */ /* Adjust the number of columns for the FTS hidden field */
actual_n_cols = n_cols; const ulint actual_n_cols = n_cols
if (m_flags2 & DICT_TF2_FTS && !has_doc_id_col) { + (m_flags2 & DICT_TF2_FTS && !has_doc_id_col);
actual_n_cols += 1;
}
table = dict_mem_table_create(m_table_name, space_id, table = dict_mem_table_create(m_table_name, space_id,
actual_n_cols, num_v, m_flags, m_flags2); actual_n_cols, num_v, m_flags, m_flags2);
...@@ -11122,10 +11117,7 @@ create_table_info_t::create_table_def() ...@@ -11122,10 +11117,7 @@ create_table_info_t::create_table_def()
heap = mem_heap_create(1000); heap = mem_heap_create(1000);
for (i = 0; i < n_cols; i++) { for (ulint i = 0; i < n_cols; i++) {
ulint is_virtual;
bool is_stored = false;
Field* field = m_form->field[i]; Field* field = m_form->field[i];
col_type = get_innobase_type_from_mysql_type( col_type = get_innobase_type_from_mysql_type(
...@@ -11191,9 +11183,6 @@ create_table_info_t::create_table_def() ...@@ -11191,9 +11183,6 @@ create_table_info_t::create_table_def()
} }
} }
is_virtual = (innobase_is_v_fld(field)) ? DATA_VIRTUAL : 0;
is_stored = innobase_is_s_fld(field);
/* First check whether the column to be added has a /* First check whether the column to be added has a
system reserved name. */ system reserved name. */
if (dict_col_name_is_reserved(field->field_name)){ if (dict_col_name_is_reserved(field->field_name)){
...@@ -11207,6 +11196,8 @@ create_table_info_t::create_table_def() ...@@ -11207,6 +11196,8 @@ create_table_info_t::create_table_def()
goto error_ret; goto error_ret;
} }
ulint is_virtual = !field->stored_in_db() ? DATA_VIRTUAL : 0;
if (!is_virtual) { if (!is_virtual) {
dict_mem_table_add_col(table, heap, dict_mem_table_add_col(table, heap,
field->field_name, col_type, field->field_name, col_type,
...@@ -11216,7 +11207,7 @@ create_table_info_t::create_table_def() ...@@ -11216,7 +11207,7 @@ create_table_info_t::create_table_def()
| binary_type | long_true_varchar, | binary_type | long_true_varchar,
charset_no), charset_no),
col_len); col_len);
} else { } else if (!omit_virtual) {
dict_mem_table_add_v_col(table, heap, dict_mem_table_add_v_col(table, heap,
field->field_name, col_type, field->field_name, col_type,
dtype_form_prtype( dtype_form_prtype(
...@@ -11228,7 +11219,7 @@ create_table_info_t::create_table_def() ...@@ -11228,7 +11219,7 @@ create_table_info_t::create_table_def()
col_len, i, 0); col_len, i, 0);
} }
if (is_stored) { if (innobase_is_s_fld(field)) {
ut_ad(!is_virtual); ut_ad(!is_virtual);
/* Added stored column in m_s_cols list. */ /* Added stored column in m_s_cols list. */
dict_mem_table_add_s_col( dict_mem_table_add_s_col(
...@@ -11237,12 +11228,12 @@ create_table_info_t::create_table_def() ...@@ -11237,12 +11228,12 @@ create_table_info_t::create_table_def()
} }
if (num_v) { if (num_v) {
for (i = 0; i < n_cols; i++) { for (ulint i = 0; i < n_cols; i++) {
dict_v_col_t* v_col; dict_v_col_t* v_col;
Field* field = m_form->field[i]; const Field* field = m_form->field[i];
if (!innobase_is_v_fld(field)) { if (field->stored_in_db()) {
continue; continue;
} }
...@@ -11256,8 +11247,7 @@ create_table_info_t::create_table_def() ...@@ -11256,8 +11247,7 @@ create_table_info_t::create_table_def()
/** Fill base columns for the stored column present in the list. */ /** Fill base columns for the stored column present in the list. */
if (table->s_cols && table->s_cols->size()) { if (table->s_cols && table->s_cols->size()) {
for (ulint i = 0; i < n_cols; i++) {
for (i = 0; i < n_cols; i++) {
Field* field = m_form->field[i]; Field* field = m_form->field[i];
if (!innobase_is_s_fld(field)) { if (!innobase_is_s_fld(field)) {
...@@ -11334,8 +11324,7 @@ create_table_info_t::create_table_def() ...@@ -11334,8 +11324,7 @@ create_table_info_t::create_table_def()
: ER_TABLESPACE_EXISTS, MYF(0), display_name); : ER_TABLESPACE_EXISTS, MYF(0), display_name);
} }
error_ret: goto error_ret;
DBUG_RETURN(convert_error_code_to_mysql(err, m_flags, m_thd));
} }
/*****************************************************************//** /*****************************************************************//**
......
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