diff options
author | Jan Lindström <jan.lindstrom@mariadb.com> | 2015-03-30 18:53:10 +0300 |
---|---|---|
committer | Jan Lindström <jan.lindstrom@mariadb.com> | 2015-03-31 09:16:48 +0300 |
commit | b53bcd438f171fcbc3a4ad5051434e1b87c844fe (patch) | |
tree | 230b649b0c39b3e830fed962c0ae186d3d37d269 /storage/xtradb/handler/handler0alter.cc | |
parent | 0563f49ba355e27543e940052f35e1a904ef077b (diff) | |
download | mariadb-git-b53bcd438f171fcbc3a4ad5051434e1b87c844fe.tar.gz |
MDEV-7367: Updating a virtual column corrupts table which crashes server
Analysis: MySQL table definition contains also virtual columns. Similarly,
index fielnr references MySQL table fields. However, InnoDB table definition
does not contain virtual columns. Therefore, when matching MySQL key fieldnr
we need to use actual column name to find out referenced InnoDB dictionary
column name.
Fix: Add new function to match MySQL index key columns to InnoDB dictionary.
Diffstat (limited to 'storage/xtradb/handler/handler0alter.cc')
-rw-r--r-- | storage/xtradb/handler/handler0alter.cc | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc index bb58a92ed1a..b3a41ae70da 100644 --- a/storage/xtradb/handler/handler0alter.cc +++ b/storage/xtradb/handler/handler0alter.cc @@ -1442,8 +1442,9 @@ innobase_create_index_field_def( if a new clustered index is not being created */ const KEY_PART_INFO* key_part, /*!< in: MySQL key definition */ - index_field_t* index_field) /*!< out: index field + index_field_t* index_field, /*!< out: index field definition for key_part */ + const Field** fields) /*!< in: MySQL table fields */ { const Field* field; ibool is_unsigned; @@ -1460,6 +1461,7 @@ innobase_create_index_field_def( ut_a(field); index_field->col_no = key_part->fieldnr; + index_field->col_name = altered_table ? field->field_name : fields[key_part->fieldnr]->field_name; col_type = get_innobase_type_from_mysql_type(&is_unsigned, field); @@ -1494,8 +1496,9 @@ innobase_create_index_def( bool key_clustered, /*!< in: true if this is the new clustered index */ index_def_t* index, /*!< out: index definition */ - mem_heap_t* heap) /*!< in: heap where memory + mem_heap_t* heap, /*!< in: heap where memory is allocated */ + const Field** fields) /*!z in: MySQL table fields */ { const KEY* key = &keys[key_number]; ulint i; @@ -1509,6 +1512,8 @@ innobase_create_index_def( index->fields = static_cast<index_field_t*>( mem_heap_alloc(heap, n_fields * sizeof *index->fields)); + memset(index->fields, 0, n_fields * sizeof *index->fields); + index->ind_type = 0; index->key_number = key_number; index->n_fields = n_fields; @@ -1545,7 +1550,7 @@ innobase_create_index_def( for (i = 0; i < n_fields; i++) { innobase_create_index_field_def( - altered_table, &key->key_part[i], &index->fields[i]); + altered_table, &key->key_part[i], &index->fields[i], fields); } DBUG_VOID_RETURN; @@ -1876,7 +1881,7 @@ innobase_create_key_defs( /* Create the PRIMARY key index definition */ innobase_create_index_def( altered_table, key_info, primary_key_number, - TRUE, TRUE, indexdef++, heap); + TRUE, TRUE, indexdef++, heap, (const Field **)altered_table->field); created_clustered: n_add = 1; @@ -1888,7 +1893,7 @@ created_clustered: /* Copy the index definitions. */ innobase_create_index_def( altered_table, key_info, i, TRUE, FALSE, - indexdef, heap); + indexdef, heap, (const Field **)altered_table->field); if (indexdef->ind_type & DICT_FTS) { n_fts_add++; @@ -1933,7 +1938,7 @@ created_clustered: for (ulint i = 0; i < n_add; i++) { innobase_create_index_def( altered_table, key_info, add[i], FALSE, FALSE, - indexdef, heap); + indexdef, heap, (const Field **)altered_table->field); if (indexdef->ind_type & DICT_FTS) { n_fts_add++; @@ -1950,6 +1955,7 @@ created_clustered: index->fields = static_cast<index_field_t*>( mem_heap_alloc(heap, sizeof *index->fields)); + memset(index->fields, 0, sizeof *index->fields); index->n_fields = 1; index->fields->col_no = fts_doc_id_col; index->fields->prefix_len = 0; |