Skip to content

Commit

Permalink
feat(tianmu): unsupported DDL in SQL layer should report error. (ston…
Browse files Browse the repository at this point in the history
  • Loading branch information
lujiashun committed Jan 5, 2023
1 parent f88fde8 commit 53b536d
Show file tree
Hide file tree
Showing 11 changed files with 462 additions and 33 deletions.
12 changes: 12 additions & 0 deletions include/mysqld_error.h
Original file line number Diff line number Diff line change
Expand Up @@ -1129,4 +1129,16 @@ static const int errmsg_section_size[] = { 889, 234 };
#define ER_WRITE_SET_EXCEEDS_LIMIT 3231
#define ER_DEPRECATED_TLS_VERSION_SESSION 3232
#define ER_WARN_DEPRECATED_TLS_VERSION 3233
#define ER_TIANMU_NOT_SUPPORTED_SECONDARY_INDEX 3234
#define ER_TIANMU_NOT_SUPPORTED_UNIQUE_INDEX 3235
#define ER_TIANMU_NOT_SUPPORTED_FULLTEXT_INDEX 3236
#define ER_TIANMU_NOT_SUPPORTED_GEOMETRY 3237
#define ER_TIANMU_NOT_SUPPORTED_ENUM 3238
#define ER_TIANMU_NOT_SUPPORTED_SET 3239
#define ER_TIANMU_NOT_SUPPORTED_TRIGGER 3240
#define ER_TIANMU_NOT_SUPPORTED_FOREIGN_KEY 3241
#define ER_TIANMU_NOT_SUPPORTED_PARTITION 3242
#define ER_TIANMU_NOT_FOUND_INDEX 3243
#define ER_NOT_SUPPORTED_FOREIGN_KEY 3244

#endif
331 changes: 331 additions & 0 deletions mysql-test/suite/tianmu/t/issue1185.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,331 @@
--source include/have_tianmu.inc

--disable_warnings
DROP DATABASE IF EXISTS issue1185_test;
--enable_warnings

CREATE DATABASE issue1185_test;

USE issue1185_test;

--echo #
--echo # Secondary INDEX
--echo #

CREATE TABLE tb_stu_info (id int(11) NOT NULL, height int(11) DEFAULT NULL,KEY height (height)) ENGINE=TIANMU;
CREATE TABLE tb_stu_info (id int(11) NOT NULL, height int(11) DEFAULT NULL,INDEX height (height)) ENGINE=TIANMU;

CREATE TABLE tb_stu_info (id int, col_name varchar(10)) ENGINE=TIANMU;
CREATE INDEX index_name ON tb_stu_info(column_name);
ALTER TABLE tb_stu_info add INDEX index_name (col_name) ;
ALTER TABLE tb_stu_info add KEY index_name (col_name) ;

ALTER TABLE tb_stu_info DROP INDEX indx_name;
ALTER TABLE tb_stu_info DROP KEY indx_name;

ALTER TABLE tb_stu_info RENAME INDEX old_index_name TO new_index_name;
ALTER TABLE tb_stu_info RENAME KEY old_index_name TO new_index_name;

--echo #
--echo # UNIQUE INDEX
--echo #
CREATE TABLE tb_stu_info_2 (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_2 (id int(11) NOT NULL, height int(11) DEFAULT NULL) ENGINE=TIANMU;
ALTER TABLE tb_stu_info_2 ADD CONSTRAINT constraint_name UNIQUE KEY(height);
ALTER TABLE tb_stu_info_2 ADD CONSTRAINT constraint_name UNIQUE INDEX(height);
CREATE UNIQUE INDEX index_name ON tb_stu_info_2(height);

ALTER TABLE tb_stu_info_2 DROP INDEX c;
ALTER TABLE tb_stu_info_2 DROP KEY c;

ALTER TABLE tb_stu_info_2 RENAME INDEX old_index_name TO new_index_name;
ALTER TABLE tb_stu_info_2 RENAME KEY old_index_name TO new_index_name;

--echo #
--echo # FULL INDEX
--echo #
CREATE TABLE tb_posts (id int(4) NOT NULL AUTO_INCREMENT,
title varchar(255) NOT NULL,
post_content text,
PRIMARY KEY (id),
FULLTEXT KEY post_content (post_content)
)ENGINE=TIANMU;

CREATE TABLE tb_posts (id int(4) NOT NULL AUTO_INCREMENT,
title varchar(255) NOT NULL,
post_content text,
PRIMARY KEY (id)
)ENGINE=TIANMU;
ALTER TABLE tb_posts ADD FULLTEXT INDEX index_name (post_content);
CREATE FULLTEXT INDEX index_name ON tb_posts (post_content);
ALTER TABLE tb_posts DROP INDEX index_name;
ALTER TABLE tb_posts DROP KEY index_name;
DROP INDEX index_name ON tb_posts;

--echo #
--echo # SPATIAL INDEX
--echo #
CREATE TABLE geom (g GEOMETRY NOT NULL, SPATIAL INDEX(g));

--echo #
--echo # FOREIGN KEY
--echo #
CREATE TABLE customer (id int) ENGINE=TIANMU;
CREATE TABLE product_order (
no INT NOT NULL AUTO_INCREMENT,
customer_id INT NOT NULL,
FOREIGN KEY (customer_id)
REFERENCES customer(id)) ENGINE=TIANMU;
CREATE TABLE product_order (
no INT NOT NULL,
customer_id INT NOT NULL) ENGINE=TIANMU;
ALTER TABLE product_order ADD CONSTRAINT fk_custome_key FOREIGN KEY(customer_id) REFERENCES customer(id);
ALTER TABLE product_order DROP FOREIGN KEY customer_id;

---echo #
---echo # PARTITION
---echo #
CREATE TABLE t1 (id INT, amount DECIMAL(7,2), tr_date DATE) ENGINE=TIANMU PARTITION BY HASH( MONTH(tr_date)) PARTITIONS 6;
CREATE TABLE t1 (id INT, amount DECIMAL(7,2), tr_date DATE) ENGINE=TIANMU;
ALTER TABLE t1 ADD PARTITION (PARTITION p3 VALUES LESS THAN (2002));
ALTER TABLE t1 DROP PARTITION p0, p1;

---echo #
---echo # GEOMETRY
---echo #
CREATE TABLE geom (g GEOMETRY NOT NULL) engine=tianmu;
CREATE TABLE my_enum(gender enum('male', 'female', 'secret'))engine=tianmu;
CREATE TABLE myset_test(Myset SET('Java','Python','C++','PHP'))engine=tianmu;

---echo #
---echo # TRIGGER
---echo #
CREATE TABLE employees(
id INT auto_increment PRIMARY KEY,
employeeNumber INT NOT NULL,
lastname VARCHAR(50) NOT NULL,
changedat DATATIME DEFAULT 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,
changedat DATATIME DEFAULT 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,
changedat DATATIME DEFAULT 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 = OLD.employeeNumber,
lastname = OLD.lastname,
new_lastname = NEW.lastname,
changedat = NOW( );
END $$
DELIMITER ;

DELIMITER $$
CREATE TRIGGER after_employee_update
after UPDATE ON employees
FOR EACH ROW
BEGIN
INSERT INTO employees_audit2
SET action = 'update',
employeeNumber = OLD.employeeNumber,
lastname = OLD.firstName,
new_lastname = NEW.firstName,
changedat = NOW( );
END $$
DELIMITER ;

DELIMITER $$
CREATE TRIGGER before_employee_insert
BEFORE INSERT ON employees
FOR EACH ROW
BEGIN
INSERT INTO employees_audit
SET action = 'insert',
employeeNumber = NEW.employeeNumber,
lastname = NEW.lastname,
new_lastname = NEW.lastname,
changedat = NOW( );
END $$
DELIMITER ;

DELIMITER $$
CREATE TRIGGER AFTER_employee_insert
AFTER INSERT ON employees
FOR EACH ROW
BEGIN
INSERT INTO employees_audit2
SET action = 'insert',
employeeNumber = NEW.employeeNumber,
lastname = NEW.lastname,
new_lastname = NEW.lastname,
changedat = NOW( );
END $$
DELIMITER ;

DELIMITER $$
CREATE TRIGGER BEFORE_employee_delete
BEFORE DELETE ON employees
FOR EACH ROW
BEGIN
INSERT INTO employees_audit
SET action = 'delete',
employeeNumber = OLD.employeeNumber,
lastname = OLD.lastname,
new_lastname = OLD.lastname,
changedat = NOW( );
END $$
DELIMITER ;

DELIMITER $$
CREATE TRIGGER after_employee_delete
after DELETE ON employees
FOR EACH ROW
BEGIN
INSERT INTO employees_audit2
SET action = 'delete',
employeeNumber = OLD.employeeNumber,
lastname = OLD.lastname,
new_lastname = OLD.lastname,
changedat = NOW( );
END $$
DELIMITER ;

---echo #
---echo # TRIGGER BEFORE PRECEDES/FOLLOWS
---echo #
CREATE TABLE price_logs (
id INT(11) NOT NULL AUTO_INCREMENT,
product_code VARCHAR(15) NOT NULL,
price DOUBLE NOT NULL,
updated_at TIMESTAMP NOT NULL DEFAULT
) ENGINE=tianmu;

CREATE TABLE user_change_logs (
id int(11) NOT NULL AUTO_INCREMENT,
product_code varchar(15) DEFAULT NULL,
updated_at timestamp NOT NULL;,
updated_by varchar(30) NOT NULL,
) ENGINE=tianmu;

CREATE TABLE `products` (
`productCode` varchar(15) NOT NULL DEFAULT '' COMMENT '',
`productName` varchar(70) NOT NULL COMMENT '',
`productLine` varchar(50) NOT NULL COMMENT '',
`productScale` varchar(10) NOT NULL,
`productVendor` varchar(50) NOT NULL,
`productDescription` text NOT NULL,
`quantityInStock` smallint(6) NOT NULL COMMENT '',
`buyPrice` decimal(10,2) NOT NULL COMMENT '',
`MSRP` decimal(10,2) NOT NULL COMMENT '',
PRIMARY KEY (`productCode`)
) ENGINE=TIANMU DEFAULT CHARSET=utf8;

DELIMITER $$
CREATE TRIGGER before_products_update
BEFORE UPDATE ON products
FOR EACH ROW
BEGIN
INSERT INTO price_logs ( product_code, price )
VALUES(old.productCode, old.msrp);
END $$
DELIMITER ;

DELIMITER $$
CREATE TRIGGER before_products_update_2
BEFORE UPDATE ON products
FOR EACH ROW FOLLOWS before_products_update
BEGIN
INSERT INTO user_change_logs ( product_code, updated_by )
VALUES(old.productCode, USER ());
END $$
DELIMITER ;

DELIMITER $$
CREATE TRIGGER before_products_update_2
BEFORE UPDATE ON products
FOR EACH ROW PRECEDES before_products_update
BEGIN
INSERT INTO user_change_logs ( product_code, updated_by )
VALUES(old.productCode, USER ());
END $$
DELIMITER ;

DELIMITER $$
CREATE TRIGGER before_products_insert_2
BEFORE INSERT ON products
FOR EACH ROW FOLLOWS before_products_insert
BEGIN
INSERT INTO user_change_logs ( product_code, updated_by )
VALUES(new.productCode, USER ());
END $$
DELIMITER ;

DELIMITER $$
CREATE TRIGGER before_products_insert
BEFORE INSERT ON products
FOR EACH ROW
BEGIN
INSERT INTO price_logs ( product_code, price )
VALUES(new.productCode, new.msrp);
END $$
DELIMITER ;

DELIMITER $$
CREATE TRIGGER before_products_insert_2
BEFORE INSERT ON products
FOR EACH ROW PRECEDES before_products_insert
BEGIN
INSERT INTO user_change_logs ( product_code, updated_by )
VALUES(new.productCode, USER ());
END $$
DELIMITER ;

DELIMITER $$
CREATE TRIGGER before_products_delete
BEFORE DELETE ON products
FOR EACH ROW
BEGIN
INSERT INTO price_logs ( product_code, price )
VALUES(old.productCode, old.msrp);
END $$
DELIMITER ;

DELIMITER $$
CREATE TRIGGER before_products_delete_2
BEFORE delete ON products
FOR EACH ROW FOLLOWS before_products_delete
BEGIN
INSERT INTO user_change_logs ( product_code, updated_by )
VALUES(old.productCode, USER ());
END $$
DELIMITER ;

DELIMITER $$
CREATE TRIGGER before_products_delete_2
BEFORE delete ON products
FOR EACH ROW PRECEDES before_products_delete
BEGIN
INSERT INTO user_change_logs ( product_code, updated_by )
VALUES(old.productCode, USER ());
END $$
DELIMITER ;

drop trigger before_products_delete_2;

DROP DATABASE issue1185_test;
11 changes: 9 additions & 2 deletions sql/auth/sql_authorization.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4388,8 +4388,15 @@ bool check_fk_parent_table_access(THD *thd,
ha_default_handlerton(thd);

// Return if engine does not support Foreign key Constraint.
if (!ha_check_storage_engine_flag(db_type, HTON_SUPPORTS_FOREIGN_KEYS))
return false;
if ((alter_info->flags & Alter_info::ADD_FOREIGN_KEY) &&
!ha_check_storage_engine_flag(db_type, HTON_SUPPORTS_FOREIGN_KEYS)) {
if (create_info->db_type->db_type == DB_TYPE_TIANMU) {
my_error(ER_TIANMU_NOT_SUPPORTED_FOREIGN_KEY, MYF(0));
} else {
my_error(ER_NOT_SUPPORTED_FOREIGN_KEY, MYF(0));

This comment has been minimized.

Copy link
@wisehead

wisehead Jan 5, 2023

innodb也要返回不支持外键的错误吗?

This comment has been minimized.

Copy link
@lujiashun

lujiashun Jan 6, 2023

Owner

innodb is the only enginer that supports foreign key, it does not return erros, Maybe the mysql5.7 has some bug, it does not report any error for this case, so i modify the code.

}
return true;
}

while ((key= key_iterator++))
{
Expand Down
8 changes: 8 additions & 0 deletions sql/handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,14 @@ enum enum_alter_inplace_result {
The handler supports non-KEY auto_increment column
*/
#define HA_NON_KEY_AUTO_INC (1LL << 48) //TIANMU UPGRADE
/*
The handler does not support secondary key
*/
#define HA_NON_SECONDARY_KEY (1LL << 49)
/*
The handler does not support unique key
*/
#define HA_NON_UNIQUE_KEY (1LL << 50)

/* bits in index_flags(index_number) for what you can do with index */
#define HA_READ_NEXT 1 /* TODO really use this flag */
Expand Down
6 changes: 5 additions & 1 deletion sql/partition_info.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1212,7 +1212,11 @@ bool partition_info::check_engine_mix(handlerton *engine_type,
engine_type= old_engine_type;
if (engine_type->flags & HTON_NO_PARTITION)
{
my_error(ER_PARTITION_MERGE_ERROR, MYF(0));
if (engine_type == tianmu_hton) {
my_error(ER_TIANMU_NOT_SUPPORTED_PARTITION, MYF(0));
} else {
my_error(ER_PARTITION_MERGE_ERROR, MYF(0));
}
DBUG_RETURN(TRUE);
}
DBUG_PRINT("info", ("out: engine_type = %s",
Expand Down
Loading

0 comments on commit 53b536d

Please sign in to comment.