From e3673793ca833f9154185e8b06822b6a0e545bb0 Mon Sep 17 00:00:00 2001 From: lujiashun Date: Thu, 3 Nov 2022 10:38:44 +0800 Subject: [PATCH] feat(tianmu): support 'ALTER TABLE t1 CHARACTER SET = ...' clause. (#848) [summary] 1 add implement in check_if_supported_inplace_alter of tianmu handler; 2 add implement in inplace_alter_table of tianmu handler; 3 add implement in commit_inplace_alter_table of tianmu handler; --- mysql-test/suite/tianmu/r/issue848.result | 70 +++++++++++++++++++++++ mysql-test/suite/tianmu/t/issue848.test | 34 +++++++++++ storage/tianmu/handler/tianmu_handler.cpp | 35 +++++++++--- storage/tianmu/handler/tianmu_handler.h | 1 + 4 files changed, 131 insertions(+), 9 deletions(-) create mode 100644 mysql-test/suite/tianmu/r/issue848.result create mode 100644 mysql-test/suite/tianmu/t/issue848.test diff --git a/mysql-test/suite/tianmu/r/issue848.result b/mysql-test/suite/tianmu/r/issue848.result new file mode 100644 index 000000000..e37ed1c6d --- /dev/null +++ b/mysql-test/suite/tianmu/r/issue848.result @@ -0,0 +1,70 @@ +create database test_issue848; +use test_issue848; +CREATE TABLE `t1` ( +`c_char` char(10) DEFAULT NULL COMMENT 'char', +`c_varchar` varchar(10) DEFAULT NULL COMMENT 'varchar', +`c_text` text COMMENT 'text') +ENGINE=TIANMU DEFAULT CHARSET=GBK; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c_char` char(10) DEFAULT NULL COMMENT 'char', + `c_varchar` varchar(10) DEFAULT NULL COMMENT 'varchar', + `c_text` text COMMENT 'text' +) ENGINE=TIANMU DEFAULT CHARSET=gbk +insert into t1(c_char,c_varchar,c_text) values(x'D6D0B9FA',x'D5E3BDAD',x'BABCD6DD'); +ALTER TABLE t1 DEFAULT CHARACTER SET gbk; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c_char` char(10) DEFAULT NULL COMMENT 'char', + `c_varchar` varchar(10) DEFAULT NULL COMMENT 'varchar', + `c_text` text COMMENT 'text' +) ENGINE=TIANMU DEFAULT CHARSET=gbk +ALTER TABLE t1 CHARACTER SET latin1; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c_char` char(10) CHARACTER SET gbk DEFAULT NULL COMMENT 'char', + `c_varchar` varchar(10) CHARACTER SET gbk DEFAULT NULL COMMENT 'varchar', + `c_text` text CHARACTER SET gbk COMMENT 'text' +) ENGINE=TIANMU DEFAULT CHARSET=latin1 +alter table t1 add column ex_column char(30); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c_char` char(10) CHARACTER SET gbk DEFAULT NULL COMMENT 'char', + `c_varchar` varchar(10) CHARACTER SET gbk DEFAULT NULL COMMENT 'varchar', + `c_text` text CHARACTER SET gbk COMMENT 'text', + `ex_column` char(30) DEFAULT NULL +) ENGINE=TIANMU DEFAULT CHARSET=latin1 +ALTER TABLE t1 MODIFY c_char char(10) CHARACTER SET UTF8MB4; +ALTER TABLE t1 MODIFY c_varchar char(10) CHARACTER SET UTF8MB4; +ALTER TABLE t1 MODIFY c_text char(10) CHARACTER SET UTF8MB4; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c_char` char(10) CHARACTER SET utf8mb4 DEFAULT NULL, + `c_varchar` char(10) CHARACTER SET utf8mb4 DEFAULT NULL, + `c_text` char(10) CHARACTER SET utf8mb4 DEFAULT NULL, + `ex_column` char(30) DEFAULT NULL +) ENGINE=TIANMU DEFAULT CHARSET=latin1 +select hex(c_char),hex(c_varchar),hex(c_text) from t1; +hex(c_char) hex(c_varchar) hex(c_text) +E4B8ADE59BBD E6B599E6B19F E69DADE5B79E +ALTER TABLE t1 CHANGE c_char c_char char(10) CHARACTER SET GBK; +ALTER TABLE t1 CHANGE c_varchar c_varchar char(10) CHARACTER SET GBK; +ALTER TABLE t1 CHANGE c_text c_text char(10) CHARACTER SET GBK; +select hex(c_char),hex(c_varchar),hex(c_text) from t1; +hex(c_char) hex(c_varchar) hex(c_text) +D6D0B9FA D5E3BDAD BABCD6DD +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c_char` char(10) CHARACTER SET gbk DEFAULT NULL, + `c_varchar` char(10) CHARACTER SET gbk DEFAULT NULL, + `c_text` char(10) CHARACTER SET gbk DEFAULT NULL, + `ex_column` char(30) DEFAULT NULL +) ENGINE=TIANMU DEFAULT CHARSET=latin1 +drop table t1; +drop database test_issue848; diff --git a/mysql-test/suite/tianmu/t/issue848.test b/mysql-test/suite/tianmu/t/issue848.test new file mode 100644 index 000000000..1fb1f3435 --- /dev/null +++ b/mysql-test/suite/tianmu/t/issue848.test @@ -0,0 +1,34 @@ +--source include/have_tianmu.inc +create database test_issue848; +use test_issue848; +CREATE TABLE `t1` ( + `c_char` char(10) DEFAULT NULL COMMENT 'char', + `c_varchar` varchar(10) DEFAULT NULL COMMENT 'varchar', + `c_text` text COMMENT 'text') +ENGINE=TIANMU DEFAULT CHARSET=GBK; +show create table t1; + +insert into t1(c_char,c_varchar,c_text) values(x'D6D0B9FA',x'D5E3BDAD',x'BABCD6DD'); +ALTER TABLE t1 DEFAULT CHARACTER SET gbk; +show create table t1; + +ALTER TABLE t1 CHARACTER SET latin1; +show create table t1; + +alter table t1 add column ex_column char(30); +show create table t1; + +ALTER TABLE t1 MODIFY c_char char(10) CHARACTER SET UTF8MB4; +ALTER TABLE t1 MODIFY c_varchar char(10) CHARACTER SET UTF8MB4; +ALTER TABLE t1 MODIFY c_text char(10) CHARACTER SET UTF8MB4; +show create table t1; +select hex(c_char),hex(c_varchar),hex(c_text) from t1; + +ALTER TABLE t1 CHANGE c_char c_char char(10) CHARACTER SET GBK; +ALTER TABLE t1 CHANGE c_varchar c_varchar char(10) CHARACTER SET GBK; +ALTER TABLE t1 CHANGE c_text c_text char(10) CHARACTER SET GBK; +select hex(c_char),hex(c_varchar),hex(c_text) from t1; +show create table t1; + +drop table t1; +drop database test_issue848; diff --git a/storage/tianmu/handler/tianmu_handler.cpp b/storage/tianmu/handler/tianmu_handler.cpp index 951d7de3a..74beb015e 100644 --- a/storage/tianmu/handler/tianmu_handler.cpp +++ b/storage/tianmu/handler/tianmu_handler.cpp @@ -41,6 +41,8 @@ const Alter_inplace_info::HA_ALTER_FLAGS ha_tianmu::TIANMU_SUPPORTED_ALTER_ADD_D Alter_inplace_info::ADD_COLUMN | Alter_inplace_info::DROP_COLUMN | Alter_inplace_info::ALTER_STORED_COLUMN_ORDER; const Alter_inplace_info::HA_ALTER_FLAGS ha_tianmu::TIANMU_SUPPORTED_ALTER_COLUMN_NAME = Alter_inplace_info::ALTER_COLUMN_DEFAULT | Alter_inplace_info::ALTER_COLUMN_NAME; +const Alter_inplace_info::HA_ALTER_FLAGS ha_tianmu::TIANMU_SUPPORTED_ALTER_TABLE_OPTIONS = + Alter_inplace_info::CHANGE_CREATE_OPTION; ///////////////////////////////////////////////////////////////////// // // NOTICE: ALL EXCEPTIONS SHOULD BE CAUGHT in the handler API!!! @@ -1271,7 +1273,7 @@ int ha_tianmu::truncate() { DBUG_RETURN(ret); } -uint ha_tianmu::max_supported_key_part_length(HA_CREATE_INFO *create_info) const { +uint ha_tianmu::max_supported_key_part_length([[maybe_unused]] HA_CREATE_INFO *create_info) const { if (tianmu_sysvar_large_prefix) return (Tianmu::common::TIANMU_MAX_INDEX_COL_LEN_LARGE); else @@ -1501,6 +1503,11 @@ int ha_tianmu::reset() { enum_alter_inplace_result ha_tianmu::check_if_supported_inplace_alter([[maybe_unused]] TABLE *altered_table, Alter_inplace_info *ha_alter_info) { DBUG_ENTER(__PRETTY_FUNCTION__); + if ((ha_alter_info->handler_flags & TIANMU_SUPPORTED_ALTER_TABLE_OPTIONS) && + (ha_alter_info->create_info->used_fields & HA_CREATE_USED_DEFAULT_CHARSET)) { + DBUG_RETURN(HA_ALTER_INPLACE_EXCLUSIVE_LOCK); + } + if ((ha_alter_info->handler_flags & ~TIANMU_SUPPORTED_ALTER_ADD_DROP_ORDER) && (ha_alter_info->handler_flags != TIANMU_SUPPORTED_ALTER_COLUMN_NAME)) { // support alter table column type @@ -1519,14 +1526,18 @@ enum_alter_inplace_result ha_tianmu::check_if_supported_inplace_alter([[maybe_un } bool ha_tianmu::inplace_alter_table(TABLE *altered_table, Alter_inplace_info *ha_alter_info) { + DBUG_ENTER(__PRETTY_FUNCTION__); try { - if (!(ha_alter_info->handler_flags & ~TIANMU_SUPPORTED_ALTER_ADD_DROP_ORDER)) { + if ((ha_alter_info->handler_flags & TIANMU_SUPPORTED_ALTER_TABLE_OPTIONS) && + (ha_alter_info->create_info->used_fields & HA_CREATE_USED_DEFAULT_CHARSET)) { + DBUG_RETURN(false); + } else if (!(ha_alter_info->handler_flags & ~TIANMU_SUPPORTED_ALTER_ADD_DROP_ORDER)) { std::vector v_old(table_share->field, table_share->field + table_share->fields); std::vector v_new(altered_table->s->field, altered_table->s->field + altered_table->s->fields); ha_rcengine_->PrepareAlterTable(table_name_, v_new, v_old, ha_thd()); - return false; + DBUG_RETURN(false); } else if (ha_alter_info->handler_flags == TIANMU_SUPPORTED_ALTER_COLUMN_NAME) { - return false; + DBUG_RETURN(false); } } catch (std::exception &e) { TIANMU_LOG(LogCtl_Level::ERROR, "An exception is caught: %s", e.what()); @@ -1536,21 +1547,27 @@ bool ha_tianmu::inplace_alter_table(TABLE *altered_table, Alter_inplace_info *ha my_message(static_cast(common::ErrorCode::UNKNOWN_ERROR), "Unable to inplace alter table", MYF(0)); - return true; + DBUG_RETURN(true); } bool ha_tianmu::commit_inplace_alter_table([[maybe_unused]] TABLE *altered_table, Alter_inplace_info *ha_alter_info, bool commit) { + DBUG_ENTER(__PRETTY_FUNCTION__); if (!commit) { TIANMU_LOG(LogCtl_Level::INFO, "Alter table failed : %s%s", table_name_.c_str(), " rollback"); - return true; + DBUG_RETURN(true); + } + if ((ha_alter_info->handler_flags & TIANMU_SUPPORTED_ALTER_TABLE_OPTIONS) && + (ha_alter_info->create_info->used_fields & HA_CREATE_USED_DEFAULT_CHARSET)) { + DBUG_RETURN(false); } if (ha_alter_info->handler_flags == TIANMU_SUPPORTED_ALTER_COLUMN_NAME) { - return false; + DBUG_RETURN(false); } if ((ha_alter_info->handler_flags & ~TIANMU_SUPPORTED_ALTER_ADD_DROP_ORDER)) { TIANMU_LOG(LogCtl_Level::INFO, "Altered table not support type %lu", ha_alter_info->handler_flags); return true; + DBUG_RETURN(true); } fs::path tmp_dir(table_name_ + ".tmp"); fs::path tab_dir(table_name_ + common::TIANMU_EXT); @@ -1583,9 +1600,9 @@ bool ha_tianmu::commit_inplace_alter_table([[maybe_unused]] TABLE *altered_table TIANMU_LOG(LogCtl_Level::ERROR, "file system error: %s %s|%s", e.what(), e.path1().string().c_str(), e.path2().string().c_str()); my_message(static_cast(common::ErrorCode::UNKNOWN_ERROR), "Failed to commit alter table", MYF(0)); - return true; + DBUG_RETURN(true); } - return false; + DBUG_RETURN(false); } /* key: mysql format, may be union key, need changed to kvstore key format diff --git a/storage/tianmu/handler/tianmu_handler.h b/storage/tianmu/handler/tianmu_handler.h index 500ee94a5..6d3b24177 100644 --- a/storage/tianmu/handler/tianmu_handler.h +++ b/storage/tianmu/handler/tianmu_handler.h @@ -158,6 +158,7 @@ class ha_tianmu final : public handler { public: static const Alter_inplace_info::HA_ALTER_FLAGS TIANMU_SUPPORTED_ALTER_ADD_DROP_ORDER; static const Alter_inplace_info::HA_ALTER_FLAGS TIANMU_SUPPORTED_ALTER_COLUMN_NAME; + static const Alter_inplace_info::HA_ALTER_FLAGS TIANMU_SUPPORTED_ALTER_TABLE_OPTIONS; protected: int set_cond_iter();