diff options
author | Eugene Kosov <eugene.kosov@mariadb.com> | 2022-02-01 17:40:35 +0600 |
---|---|---|
committer | Eugene Kosov <eugene.kosov@mariadb.com> | 2022-02-03 01:47:46 +0600 |
commit | ab2414a6ceb376a8c03569a7d63d747ff215afdc (patch) | |
tree | 480eef426165743644b741e2ca0099896c00b5aa | |
parent | 12cad0c3468d734e041d4ef0cd5a26d2a28606fc (diff) | |
download | mariadb-git-bb-10.4-MDEV-26294-instant-alter-charset.tar.gz |
-rw-r--r-- | mysql-test/suite/innodb/t/1.test | 48 | ||||
-rw-r--r-- | storage/innobase/include/row0merge.h | 3 | ||||
-rw-r--r-- | storage/innobase/rem/rem0rec.cc | 6 | ||||
-rw-r--r-- | storage/innobase/row/row0ftsort.cc | 2 | ||||
-rw-r--r-- | storage/innobase/row/row0log.cc | 20 | ||||
-rw-r--r-- | storage/innobase/row/row0merge.cc | 38 |
6 files changed, 107 insertions, 10 deletions
diff --git a/mysql-test/suite/innodb/t/1.test b/mysql-test/suite/innodb/t/1.test new file mode 100644 index 00000000000..c974b88a02f --- /dev/null +++ b/mysql-test/suite/innodb/t/1.test @@ -0,0 +1,48 @@ +--source include/have_innodb.inc + +# CREATE TABLE t1 ( +# id INT PRIMARY KEY, +# msg VARCHAR(100) CHARACTER SET utf8 COLLATE utf8_bin, +# UNIQUE(msg) +# ) ENGINE=INNODB; + +# INSERT INTO t1 VALUES (1, 'aaa'); +# INSERT INTO t1 VALUES (2, 'AAA'); + +# # --error ER_DUP_ENTRY +# # ALTER TABLE t1 MODIFY msg VARCHAR(100) CHARACTER SET utf8 COLLATE utf8_unicode_ci, ALGORITHM=COPY; +# --error ER_DUP_ENTRY +# ALTER TABLE t1 MODIFY msg VARCHAR(100) CHARACTER SET utf8 COLLATE utf8_unicode_ci, ALGORITHM=NOCOPY; + +# # ALTER TABLE t1 MODIFY msg VARCHAR(100) CHARACTER SET utf8 COLLATE utf8_unicode_ci, FORCE, ALGORITHM=INPLACE; + +# DROP TABLE t1; + + +CREATE TABLE t1 ( + id INT PRIMARY KEY, + msg VARCHAR(100) CHARACTER SET utf8 COLLATE utf8_bin, + UNIQUE(msg) +) ENGINE=INNODB; + +INSERT INTO t1 VALUES (1, 'aaa'); + +SET DEBUG_SYNC = 'RESET'; +SET DEBUG_SYNC = 'row_log_apply_before SIGNAL before_apply WAIT_FOR go_ahead'; +--send +ALTER TABLE t1 MODIFY msg VARCHAR(100) CHARACTER SET utf8 COLLATE utf8_unicode_ci, ALGORITHM=NOCOPY; + +connect (con1,localhost,root,,); +connection con1; + +SET DEBUG_SYNC = 'now WAIT_FOR before_apply'; +INSERT INTO t1 VALUES (2, 'AAA'); +SET DEBUG_SYNC = 'now SIGNAL go_ahead'; +SET DEBUG_SYNC = 'RESET'; + +connection default; + +--error ER_DUP_ENTRY +reap; + +DROP TABLE t1; diff --git a/storage/innobase/include/row0merge.h b/storage/innobase/include/row0merge.h index 3252af0062b..c8ee7430205 100644 --- a/storage/innobase/include/row0merge.h +++ b/storage/innobase/include/row0merge.h @@ -94,6 +94,7 @@ struct row_merge_buf_t { mtuple_t* tuples; /*!< array of data tuples */ mtuple_t* tmp_tuples; /*!< temporary copy of tuples, for sorting */ + unsigned* prtype_list; }; /** Information about temporary files used in merge sort */ @@ -431,7 +432,7 @@ Allocate a sort buffer. row_merge_buf_t* row_merge_buf_create( /*=================*/ - dict_index_t* index) /*!< in: secondary index */ + dict_index_t* index, const TABLE *mariadb_table) /*!< in: secondary index */ MY_ATTRIBUTE((warn_unused_result, nonnull, malloc)); /*********************************************************************//** diff --git a/storage/innobase/rem/rem0rec.cc b/storage/innobase/rem/rem0rec.cc index 08682304410..bcc683449f2 100644 --- a/storage/innobase/rem/rem0rec.cc +++ b/storage/innobase/rem/rem0rec.cc @@ -1198,9 +1198,9 @@ rec_get_converted_size_comp_prefix_low( field->col, &dfield->type)); } } else { - ut_ad(field->col->is_dropped() - || dict_col_type_assert_equal(field->col, - &dfield->type)); + // ut_ad(field->col->is_dropped() + // || dict_col_type_assert_equal(field->col, + // &dfield->type)); } #endif diff --git a/storage/innobase/row/row0ftsort.cc b/storage/innobase/row/row0ftsort.cc index 8d1dbad22cb..707945786cd 100644 --- a/storage/innobase/row/row0ftsort.cc +++ b/storage/innobase/row/row0ftsort.cc @@ -245,7 +245,7 @@ row_fts_psort_info_init( } psort_info[j].merge_buf[i] = row_merge_buf_create( - dup->index); + dup->index, dup->table); if (row_merge_file_create(psort_info[j].merge_file[i], path) == OS_FILE_CLOSED) { diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index c0396c33cc4..6040b690c8e 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -3652,6 +3652,26 @@ corrupted: indexes, which never contain off-page columns. */ ut_ad(dtuple_get_n_ext(entry) == 0); + for (unsigned i = 0; i < index->n_fields; i++) { + if (index->fields[i].col->mtype != DATA_VARMYSQL) { + continue; + } + + auto *field_name = static_cast<const char*>(index->fields[i].name); + + for (uint j = 0; j < dup->table->s->fields; j++) { + if (!strcmp(field_name, dup->table->field[j]->field_name.str)) { + ut_ad(dup->table->field[j]->type() == MYSQL_TYPE_VARCHAR); + auto *field = static_cast<Field_varstring*>(dup->table->field[j]); + uint cs_number= field->charset()->number; + entry->fields[i].type.prtype &= ~((uint) CHAR_COLL_MASK << 16); + entry->fields[i].type.prtype |= cs_number << 16; + break; + } + + } + } + row_log_apply_op_low(index, dup, error, offsets_heap, has_index_lock, op, trx_id, entry); return(mrec); diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index a81e47edaf5..2f5777b188b 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -338,7 +338,7 @@ row_merge_buf_create_low( dict_index_t* index, /*!< in: secondary index */ ulint max_tuples, /*!< in: maximum number of data tuples */ - ulint buf_size) /*!< in: size of the buffer, + ulint buf_size, const TABLE* mariadb_table) /*!< in: size of the buffer, in bytes */ { row_merge_buf_t* buf; @@ -354,6 +354,29 @@ row_merge_buf_create_low( buf->tuples = static_cast<mtuple_t*>( ut_malloc_nokey(2 * max_tuples * sizeof *buf->tuples)); buf->tmp_tuples = buf->tuples + max_tuples; + buf->prtype_list = static_cast<unsigned*>(mem_heap_zalloc(heap, + sizeof(unsigned) * index->n_fields)); + + for (unsigned i = 0; i< index->n_fields; i++) { + if (index->fields[i].col->mtype != DATA_VARMYSQL) { + continue; + } + + auto *field_name = static_cast<const char*>( + index->fields[i].name); + + for (uint j = 0; j < mariadb_table->s->fields; j++) { + Field* field = mariadb_table->field[j]; + if (!strcmp(field_name, field->field_name.str)) { + ut_ad(field->type() == MYSQL_TYPE_VARCHAR); + uint cs_number = field->charset()->number; + auto& prtype = buf->prtype_list[i]; + prtype = index->fields[i].col->prtype; + prtype &= ~((uint) CHAR_COLL_MASK << 16); + prtype |= cs_number << 16; + } + } + } return(buf); } @@ -364,7 +387,7 @@ Allocate a sort buffer. row_merge_buf_t* row_merge_buf_create( /*=================*/ - dict_index_t* index) /*!< in: secondary index */ + dict_index_t* index, const TABLE *mariadb_table) /*!< in: secondary index */ { row_merge_buf_t* buf; ulint max_tuples; @@ -379,7 +402,8 @@ row_merge_buf_create( heap = mem_heap_create(buf_size); - buf = row_merge_buf_create_low(heap, index, max_tuples, buf_size); + buf = row_merge_buf_create_low(heap, index, max_tuples, buf_size, + mariadb_table); return(buf); } @@ -709,6 +733,10 @@ error: ut_ad(index->table->not_redundant()); } } + + if (buf->prtype_list[i]) { + field->type.prtype = buf->prtype_list[i]; + } } len = dfield_get_len(field); @@ -1778,7 +1806,7 @@ row_merge_read_clustered_index( fts_index = index[i]; - merge_buf[i] = row_merge_buf_create(fts_sort_idx); + merge_buf[i] = row_merge_buf_create(fts_sort_idx, table); add_doc_id = DICT_TF2_FLAG_IS_SET( new_table, DICT_TF2_FTS_ADD_DOC_ID); @@ -1801,7 +1829,7 @@ row_merge_read_clustered_index( num_spatial++; } - merge_buf[i] = row_merge_buf_create(index[i]); + merge_buf[i] = row_merge_buf_create(index[i], table); } } |