summaryrefslogtreecommitdiff
path: root/storage/xtradb/handler/handler0alter.cc
diff options
context:
space:
mode:
authorJan Lindström <jan.lindstrom@mariadb.com>2015-03-30 18:53:10 +0300
committerJan Lindström <jan.lindstrom@mariadb.com>2015-03-31 09:16:48 +0300
commitb53bcd438f171fcbc3a4ad5051434e1b87c844fe (patch)
tree230b649b0c39b3e830fed962c0ae186d3d37d269 /storage/xtradb/handler/handler0alter.cc
parent0563f49ba355e27543e940052f35e1a904ef077b (diff)
downloadmariadb-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.cc18
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;