From ae42cbf296bf4bcf731faf66226516c225c07f1f Mon Sep 17 00:00:00 2001 From: DandreChen Date: Tue, 21 Feb 2023 11:16:56 +0800 Subject: [PATCH 1/2] feat(sql):add NO_KEY_ERROR to sql_mode for ignoring unsupported error.(#1318) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add NO_KEY_ERROR to sql_mode. Add judgement for secondary index、unique index、trigger、etc. --- sql/auth/sql_authorization.cc | 3 ++- sql/sql_class.h | 3 ++- sql/sql_table.cc | 25 ++++++++++++++++--------- sql/sql_trigger.cc | 3 ++- sql/sys_vars.cc | 2 +- storage/tianmu/handler/ha_tianmu.cpp | 7 +++++++ 6 files changed, 30 insertions(+), 13 deletions(-) diff --git a/sql/auth/sql_authorization.cc b/sql/auth/sql_authorization.cc index 443b3cece..6167d0e06 100644 --- a/sql/auth/sql_authorization.cc +++ b/sql/auth/sql_authorization.cc @@ -4390,7 +4390,8 @@ bool check_fk_parent_table_access(THD *thd, // Return if engine does not support Foreign key Constraint. if (!ha_check_storage_engine_flag(db_type, HTON_SUPPORTS_FOREIGN_KEYS)) { if (db_type == tianmu_hton && - (alter_info->flags & Alter_info::ADD_FOREIGN_KEY)) { + (alter_info->flags & Alter_info::ADD_FOREIGN_KEY) && + (!(thd->variables.sql_mode & MODE_NO_KEY_ERROR))) { my_error(ER_TIANMU_NOT_SUPPORTED_FOREIGN_KEY, MYF(0)); return true; } diff --git a/sql/sql_class.h b/sql/sql_class.h index d46c533cd..73e35a69a 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -180,7 +180,8 @@ enum enum_binlog_format { #define MODE_NO_ENGINE_SUBSTITUTION (MODE_HIGH_NOT_PRECEDENCE*2) #define MODE_PAD_CHAR_TO_FULL_LENGTH (1ULL << 31) //Force the engine to be tianmu when acting as a slave library -#define MODE_MANDATORY_TIANMU (1ULL << 32) +#define MODE_MANDATORY_TIANMU (1ULL << 32) +#define MODE_NO_KEY_ERROR (1ULL << 33) /* Replication uses 8 bytes to store SQL_MODE in the binary log. The day you diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 59f0259ac..5ab818036 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -3927,21 +3927,24 @@ mysql_prepare_create_table(THD *thd, const char *error_schema_name, (fk_key->name.str ? fk_key->name.str : "foreign key without name"), ER(ER_KEY_REF_DO_NOT_MATCH_TABLE_REF)); - DBUG_RETURN(TRUE); + DBUG_RETURN(TRUE); } continue; } (*key_count)++; tmp=file->max_key_parts(); - if (create_info->db_type->db_type == DB_TYPE_TIANMU) { + if ((create_info->db_type->db_type == DB_TYPE_TIANMU) && + (thd->lex->sql_command != SQLCOM_CREATE_TABLE)) { if ((file->ha_table_flags() & HA_NON_SECONDARY_KEY) && - key->type == KEYTYPE_MULTIPLE) { + (key->type == KEYTYPE_MULTIPLE) && + !(thd->variables.sql_mode & MODE_NO_KEY_ERROR)) { my_error(ER_TIANMU_NOT_SUPPORTED_SECONDARY_INDEX, MYF(0)); DBUG_RETURN(TRUE); } - if (file->ha_table_flags() & HA_NON_UNIQUE_KEY && - key->type == KEYTYPE_UNIQUE) { + if ((file->ha_table_flags() & HA_NON_UNIQUE_KEY) && + (key->type == KEYTYPE_UNIQUE) && + (!(thd->variables.sql_mode & MODE_NO_KEY_ERROR))) { my_error(ER_TIANMU_NOT_SUPPORTED_UNIQUE_INDEX, MYF(0)); DBUG_RETURN(TRUE); } @@ -4078,7 +4081,8 @@ mysql_prepare_create_table(THD *thd, const char *error_schema_name, MYF(0)); DBUG_RETURN(TRUE); } - if (create_info->db_type->db_type == DB_TYPE_TIANMU) { + if ((create_info->db_type->db_type == DB_TYPE_TIANMU) && + (!(thd->variables.sql_mode & MODE_NO_KEY_ERROR))) { my_message(ER_TIANMU_NOT_SUPPORTED_FULLTEXT_INDEX, ER(ER_TIANMU_NOT_SUPPORTED_FULLTEXT_INDEX), MYF(0)); } else { @@ -8493,7 +8497,8 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, while ((drop=drop_it++)) { switch (drop->type) { case Alter_drop::KEY: - if (create_info->db_type->db_type == DB_TYPE_TIANMU) { + if ((create_info->db_type->db_type == DB_TYPE_TIANMU) && + (!(thd->variables.sql_mode & MODE_NO_KEY_ERROR))) { my_error(ER_TIANMU_NOT_FOUND_INDEX, MYF(0)); goto err; } @@ -8503,7 +8508,8 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, alter_info->drop_list.head()->name); goto err; case Alter_drop::FOREIGN_KEY: - if (create_info->db_type->db_type == DB_TYPE_TIANMU) { + if ((create_info->db_type->db_type == DB_TYPE_TIANMU) && + (!(thd->variables.sql_mode & MODE_NO_KEY_ERROR))) { my_error(ER_TIANMU_NOT_SUPPORTED_FOREIGN_KEY, MYF(0)); } break; @@ -8517,7 +8523,8 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, } if (rename_key_list.elements) { - if (create_info->db_type->db_type == DB_TYPE_TIANMU) { + if ((create_info->db_type->db_type == DB_TYPE_TIANMU) && + (!(thd->variables.sql_mode & MODE_NO_KEY_ERROR))) { my_error(ER_TIANMU_NOT_FOUND_INDEX, MYF(0)); } else { my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), rename_key_list.head()->old_name, diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 1e358a019..ccafc6dae 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -226,7 +226,8 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) } table= tables->table; table->pos_in_table_list= tables; - if (table->file && table->file->ht == tianmu_hton) { + if ((table->file && table->file->ht == tianmu_hton) && + (!(thd->variables.sql_mode & MODE_NO_KEY_ERROR))) { my_error(ER_TIANMU_NOT_SUPPORTED_TRIGGER, MYF(0)); goto end; } diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index dd38b60f4..452b2481c 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -3904,7 +3904,7 @@ static const char *sql_mode_names[]= "STRICT_ALL_TABLES", "NO_ZERO_IN_DATE", "NO_ZERO_DATE", "ALLOW_INVALID_DATES", "ERROR_FOR_DIVISION_BY_ZERO", "TRADITIONAL", "NO_AUTO_CREATE_USER", "HIGH_NOT_PRECEDENCE", "NO_ENGINE_SUBSTITUTION", - "PAD_CHAR_TO_FULL_LENGTH", "MANDATORY_TIANMU", + "PAD_CHAR_TO_FULL_LENGTH", "MANDATORY_TIANMU", "NO_KEY_ERROR", 0 }; export bool sql_mode_string_representation(THD *thd, sql_mode_t sql_mode, diff --git a/storage/tianmu/handler/ha_tianmu.cpp b/storage/tianmu/handler/ha_tianmu.cpp index 295c633b5..1e2d8d4f9 100644 --- a/storage/tianmu/handler/ha_tianmu.cpp +++ b/storage/tianmu/handler/ha_tianmu.cpp @@ -1682,6 +1682,13 @@ enum_alter_inplace_result ha_tianmu::check_if_supported_inplace_alter([[maybe_un if (ha_alter_info->handler_flags & Alter_inplace_info::ADD_PK_INDEX || ha_alter_info->handler_flags & Alter_inplace_info::DROP_PK_INDEX) DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); + // support alter table: mix add/drop key + if ((ha_alter_info->handler_flags & Alter_inplace_info::ADD_INDEX || + ha_alter_info->handler_flags & Alter_inplace_info::DROP_INDEX || + ha_alter_info->handler_flags & Alter_inplace_info::ADD_UNIQUE_INDEX || + ha_alter_info->handler_flags & Alter_inplace_info::DROP_UNIQUE_INDEX) && + (ha_thd()->variables.sql_mode & MODE_NO_KEY_ERROR)) + DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); DBUG_RETURN(HA_ALTER_ERROR); } From 923c991772edcc81700b87b2b2187000604592d0 Mon Sep 17 00:00:00 2001 From: DandreChen Date: Tue, 21 Feb 2023 11:27:39 +0800 Subject: [PATCH 2/2] feat(mtr): add test cases for NO_KEY_ERROR of sql_mode.(#1318) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add test cases for NO_KEY_ERROR to test secondary index、unique index and trigger. --- mysql-test/suite/tianmu/r/issue1318.result | 52 ++++++++++++ .../suite/tianmu/t/issue1318-master.opt | 1 + mysql-test/suite/tianmu/t/issue1318.test | 85 +++++++++++++++++++ sql/sql_table.cc | 3 +- storage/tianmu/handler/ha_tianmu.cpp | 6 +- 5 files changed, 142 insertions(+), 5 deletions(-) create mode 100644 mysql-test/suite/tianmu/r/issue1318.result create mode 100644 mysql-test/suite/tianmu/t/issue1318-master.opt create mode 100644 mysql-test/suite/tianmu/t/issue1318.test diff --git a/mysql-test/suite/tianmu/r/issue1318.result b/mysql-test/suite/tianmu/r/issue1318.result new file mode 100644 index 000000000..acaed7d57 --- /dev/null +++ b/mysql-test/suite/tianmu/r/issue1318.result @@ -0,0 +1,52 @@ +DROP DATABASE IF EXISTS issue1318_test; +CREATE DATABASE issue1318_test; +USE issue1318_test; +# +# Secondary INDEX +# +CREATE TABLE tb_stu_info1 (id int(11) NOT NULL, height int(11) DEFAULT NULL,KEY height (height)) ENGINE=TIANMU; +CREATE TABLE tb_stu_info2 (id int(11) NOT NULL, height int(11) DEFAULT NULL,INDEX height (height)) ENGINE=TIANMU; +CREATE TABLE tb_stu_info3 (id int, col_name varchar(10)) ENGINE=TIANMU; +CREATE INDEX index_name ON tb_stu_info3(col_name); +ALTER TABLE tb_stu_info3 DROP INDEX index_name; +ALTER TABLE tb_stu_info3 add INDEX index_name (col_name) ; +# +# UNIQUE INDEX +# +CREATE TABLE tb_stu_info_1 (id int(11) NOT NULL, height int(11) DEFAULT NULL,UNIQUE KEY height (height)) ENGINE=TIANMU; +CREATE TABLE tb_stu_info_2 (id int(11) NOT NULL, height int(11) DEFAULT NULL,UNIQUE INDEX height (height)) ENGINE=TIANMU; +CREATE TABLE tb_stu_info_3 (id int(11) NOT NULL, height int(11) DEFAULT NULL) ENGINE=TIANMU; +ALTER TABLE tb_stu_info_3 ADD CONSTRAINT constraint_name UNIQUE INDEX(height); +ALTER TABLE tb_stu_info_3 DROP INDEX constraint_name; +# +# TRIGGER +# +CREATE TABLE employees( +id INT auto_increment PRIMARY KEY, +employeeNumber INT NOT NULL, +lastname VARCHAR(50) NOT NULL, +action VARCHAR(50) DEFAULT NULL) ENGINE=TIANMU; +CREATE TABLE employees_audit( +id INT auto_increment PRIMARY KEY, +employeeNumber INT NOT NULL, +lastname VARCHAR(50) NOT NULL, +action VARCHAR(50) DEFAULT NULL) ENGINE=TIANMU; +CREATE TABLE employees_audit2( +id INT auto_increment PRIMARY KEY, +employeeNumber INT NOT NULL, +lastname VARCHAR(50) NOT NULL, +action VARCHAR(50) DEFAULT NULL) ENGINE=TIANMU; +CREATE TRIGGER before_employee_update +BEFORE UPDATE ON employees +FOR EACH ROW +BEGIN +INSERT INTO employees_audit +SET action = 'update', +employeeNumber = 1, +lastname = "nihao", +new_lastname = "niyehao"; +END | +# +# END +# +DROP DATABASE issue1318_test; diff --git a/mysql-test/suite/tianmu/t/issue1318-master.opt b/mysql-test/suite/tianmu/t/issue1318-master.opt new file mode 100644 index 000000000..4494579d7 --- /dev/null +++ b/mysql-test/suite/tianmu/t/issue1318-master.opt @@ -0,0 +1 @@ +--sql_mode=NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,NO_KEY_ERROR diff --git a/mysql-test/suite/tianmu/t/issue1318.test b/mysql-test/suite/tianmu/t/issue1318.test new file mode 100644 index 000000000..303dad63b --- /dev/null +++ b/mysql-test/suite/tianmu/t/issue1318.test @@ -0,0 +1,85 @@ +--source include/have_tianmu.inc + +--disable_warnings +DROP DATABASE IF EXISTS issue1318_test; +--enable_warnings + +CREATE DATABASE issue1318_test; + +USE issue1318_test; + +--echo # +--echo # Secondary INDEX +--echo # + +CREATE TABLE tb_stu_info1 (id int(11) NOT NULL, height int(11) DEFAULT NULL,KEY height (height)) ENGINE=TIANMU; + +CREATE TABLE tb_stu_info2 (id int(11) NOT NULL, height int(11) DEFAULT NULL,INDEX height (height)) ENGINE=TIANMU; + +CREATE TABLE tb_stu_info3 (id int, col_name varchar(10)) ENGINE=TIANMU; + +CREATE INDEX index_name ON tb_stu_info3(col_name); + +ALTER TABLE tb_stu_info3 DROP INDEX index_name; + +ALTER TABLE tb_stu_info3 add INDEX index_name (col_name) ; + + +--echo # +--echo # UNIQUE INDEX +--echo # + +CREATE TABLE tb_stu_info_1 (id int(11) NOT NULL, height int(11) DEFAULT NULL,UNIQUE KEY height (height)) ENGINE=TIANMU; + +CREATE TABLE tb_stu_info_2 (id int(11) NOT NULL, height int(11) DEFAULT NULL,UNIQUE INDEX height (height)) ENGINE=TIANMU; + +CREATE TABLE tb_stu_info_3 (id int(11) NOT NULL, height int(11) DEFAULT NULL) ENGINE=TIANMU; + +ALTER TABLE tb_stu_info_3 ADD CONSTRAINT constraint_name UNIQUE INDEX(height); + +ALTER TABLE tb_stu_info_3 DROP INDEX constraint_name; + + +--echo # +--echo # TRIGGER +--echo # + +CREATE TABLE employees( + id INT auto_increment PRIMARY KEY, + employeeNumber INT NOT NULL, + lastname VARCHAR(50) NOT NULL, + action VARCHAR(50) DEFAULT NULL) ENGINE=TIANMU; + +CREATE TABLE employees_audit( + id INT auto_increment PRIMARY KEY, + employeeNumber INT NOT NULL, + lastname VARCHAR(50) NOT NULL, + action VARCHAR(50) DEFAULT NULL) ENGINE=TIANMU; + +CREATE TABLE employees_audit2( + id INT auto_increment PRIMARY KEY, + employeeNumber INT NOT NULL, + lastname VARCHAR(50) NOT NULL, + action VARCHAR(50) DEFAULT NULL) ENGINE=TIANMU; + + +DELIMITER |; +CREATE TRIGGER before_employee_update + BEFORE UPDATE ON employees + FOR EACH ROW +BEGIN + INSERT INTO employees_audit + SET action = 'update', + employeeNumber = 1, + lastname = "nihao", + new_lastname = "niyehao"; +END | +DELIMITER ;| + + +--echo # +--echo # END +--echo # + +DROP DATABASE issue1318_test; + diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 5ab818036..9d87a11be 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -3934,8 +3934,7 @@ mysql_prepare_create_table(THD *thd, const char *error_schema_name, (*key_count)++; tmp=file->max_key_parts(); - if ((create_info->db_type->db_type == DB_TYPE_TIANMU) && - (thd->lex->sql_command != SQLCOM_CREATE_TABLE)) { + if ((create_info->db_type->db_type == DB_TYPE_TIANMU)) { if ((file->ha_table_flags() & HA_NON_SECONDARY_KEY) && (key->type == KEYTYPE_MULTIPLE) && !(thd->variables.sql_mode & MODE_NO_KEY_ERROR)) { diff --git a/storage/tianmu/handler/ha_tianmu.cpp b/storage/tianmu/handler/ha_tianmu.cpp index 1e2d8d4f9..ae1e63b69 100644 --- a/storage/tianmu/handler/ha_tianmu.cpp +++ b/storage/tianmu/handler/ha_tianmu.cpp @@ -1684,9 +1684,9 @@ enum_alter_inplace_result ha_tianmu::check_if_supported_inplace_alter([[maybe_un DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); // support alter table: mix add/drop key if ((ha_alter_info->handler_flags & Alter_inplace_info::ADD_INDEX || - ha_alter_info->handler_flags & Alter_inplace_info::DROP_INDEX || - ha_alter_info->handler_flags & Alter_inplace_info::ADD_UNIQUE_INDEX || - ha_alter_info->handler_flags & Alter_inplace_info::DROP_UNIQUE_INDEX) && + ha_alter_info->handler_flags & Alter_inplace_info::DROP_INDEX || + ha_alter_info->handler_flags & Alter_inplace_info::ADD_UNIQUE_INDEX || + ha_alter_info->handler_flags & Alter_inplace_info::DROP_UNIQUE_INDEX) && (ha_thd()->variables.sql_mode & MODE_NO_KEY_ERROR)) DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);