From 13d241cb678a9fcf8e88777cdf98e8e2caabf83b Mon Sep 17 00:00:00 2001 From: x00586427 Date: Wed, 31 Jan 2024 15:09:05 +0800 Subject: [PATCH] sync cantian24.0 to cantian24.3 --- README | 10 +- mysql-test/mysql-scripts-meta.patch | 716 ++++ mysql-test/mysql-source-code-meta.patch | 3501 +++++++++++++++++ mysql-test/mysql-test-meta.patch | 84 + .../suite/tianchi/t/ctc_atomic_ddl.test | 16 - .../suite/tianchi/t/ctc_auto_increment.test | 16 - mysql-test/suite/tianchi/t/ctc_charset.test | 16 - .../suite/tianchi/t/ctc_charset_binary.test | 15 - .../suite/tianchi/t/ctc_charset_collate.test | 16 - .../tianchi/t/ctc_compressed_proxy_conn.test | 16 - .../suite/tianchi/t/ctc_cond_pushdown.test | 15 - .../tianchi/t/ctc_cond_pushdown_explain.test | 15 - .../tianchi/t/ctc_crud_for_drop_column.test | 15 - mysql-test/suite/tianchi/t/ctc_datatype.test | 15 - .../suite/tianchi/t/ctc_datatype_adapt.test | 17 +- .../suite/tianchi/t/ctc_datatype_blob.test | 15 - mysql-test/suite/tianchi/t/ctc_dc_reuse.test | 15 - mysql-test/suite/tianchi/t/ctc_dcl.test | 15 - mysql-test/suite/tianchi/t/ctc_ddl.test | 15 - .../suite/tianchi/t/ctc_ddl_alter_table.test | 34 +- .../suite/tianchi/t/ctc_ddl_analyze.test | 15 - .../suite/tianchi/t/ctc_ddl_auto_inc.test | 15 - .../suite/tianchi/t/ctc_ddl_cascade.test | 547 ++- .../tianchi/t/ctc_ddl_character_set.test | 16 - .../suite/tianchi/t/ctc_ddl_create_table.test | 25 - .../tianchi/t/ctc_ddl_create_table_check.test | 15 - .../tianchi/t/ctc_ddl_default_index.test | 15 - .../suite/tianchi/t/ctc_ddl_engine.test | 16 +- .../tianchi/t/ctc_ddl_fault_process.test | 16 - .../suite/tianchi/t/ctc_ddl_foreign_key.test | 15 - .../t/ctc_ddl_foreign_key_set_enum.test | 16 - .../suite/tianchi/t/ctc_ddl_func_index.test | 15 - .../suite/tianchi/t/ctc_ddl_func_proc.test | 15 - .../tianchi/t/ctc_ddl_generated_columns.test | 15 - mysql-test/suite/tianchi/t/ctc_ddl_index.test | 15 - mysql-test/suite/tianchi/t/ctc_ddl_limit.test | 15 - .../tianchi/t/ctc_ddl_max_reclength.test | 15 - .../suite/tianchi/t/ctc_ddl_multi_db.test | 15 - .../suite/tianchi/t/ctc_ddl_partition.test | 31 +- .../suite/tianchi/t/ctc_ddl_tablespace.test | 15 - .../tianchi/t/ctc_ddl_temporary_table.test | 15 - .../tianchi/t/ctc_ddl_too_many_databases.test | 15 - .../suite/tianchi/t/ctc_ddl_trigger.test | 15 - .../tianchi/t/ctc_ddl_unsupport_command.test | 15 - mysql-test/suite/tianchi/t/ctc_ddl_view.test | 15 - .../suite/tianchi/t/ctc_delete_time.test | 15 - .../tianchi/t/ctc_dml_decimal_table.test | 15 - .../suite/tianchi/t/ctc_dml_ignore.test | 15 - .../suite/tianchi/t/ctc_dml_two_table.test | 15 - .../tianchi/t/ctc_handler_operation.test | 15 - .../tianchi/t/ctc_index_functions_base.test | 18 +- .../suite/tianchi/t/ctc_insert_time.test | 15 - .../suite/tianchi/t/ctc_json_value.test | 15 - mysql-test/suite/tianchi/t/ctc_lcov.test | 21 +- .../tianchi/t/ctc_link_and_migr_row.test | 16 - .../suite/tianchi/t/ctc_lock_instance.test | 16 - ...ncurrency_with_nowait_and_skip_locked.test | 16 - .../suite/tianchi/t/ctc_partition_update.test | 16 - mysql-test/suite/tianchi/t/ctc_read_only.test | 16 - .../tianchi/t/ctc_select_early_return.test | 16 - .../suite/tianchi/t/ctc_update_time.test | 16 - mysql-test/suite/tianchi/t/ctc_varchar.test | 16 - .../suite/tianchi/t/recreate_test_db.test | 4 + storage/tianchi/datatype_cnvrtr.cc | 6 +- storage/tianchi/ha_tse.cc | 192 +- storage/tianchi/ha_tse.h | 19 +- storage/tianchi/ha_tse_ddl.cc | 445 ++- storage/tianchi/ha_tsepart.cc | 39 +- storage/tianchi/ha_tsepart.h | 17 +- storage/tianchi/message_queue/dsw_message.h | 1 + storage/tianchi/protobuf/tc_db.pb-c.h | 2 +- storage/tianchi/protobuf/tc_db.proto | 2 +- storage/tianchi/tse_ddl_util.cc | 24 +- storage/tianchi/tse_ddl_util.h | 20 +- storage/tianchi/tse_error.cc | 14 +- storage/tianchi/tse_error.h | 6 +- storage/tianchi/tse_srv.h | 11 +- storage/tianchi/tse_srv_mq_stub.cc | 14 +- storage/tianchi/tse_stats.cc | 1 + 79 files changed, 5409 insertions(+), 1194 deletions(-) create mode 100644 mysql-test/mysql-scripts-meta.patch create mode 100644 mysql-test/mysql-source-code-meta.patch create mode 100644 mysql-test/mysql-test-meta.patch create mode 100644 mysql-test/suite/tianchi/t/recreate_test_db.test diff --git a/README b/README index b9f6ee8..6dc3a89 100644 --- a/README +++ b/README @@ -17,16 +17,16 @@ License 3、下载MySQL代码,将mysql代码放置到mysql-source文件夹下 4、完成connector编译 4.1、Debug 版 -cd build;sh Makefile.sh mysql +cd /home/regress/CantianKernel/build;sh Makefile.sh mysql 4.2、Release 版 -cd build;sh Makefile.sh mysql_release +cd /home/regress/CantianKernel/build;sh Makefile.sh mysql_release 5、拷贝mysql相关so(元数据归一版本无需执行) # 单节点 -cd build;sh Makefile.sh mysql_package_node0 +cd /home/regress/CantianKernel/build;sh Makefile.sh mysql_package_node0 # 双节点节点0执行 -cd build;sh Makefile.sh mysql_package_node0 +cd /home/regress/CantianKernel/build;sh Makefile.sh mysql_package_node0 # 双节点节点1执行 -cd build;sh Makefile.sh mysql_package_node1 +cd /home/regress/CantianKernel/build;sh Makefile.sh mysql_package_node1 6、部署MySQL # 创建文件:所有节点 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/regress/mysql-server/bld_debug//library_output_directory/ diff --git a/mysql-test/mysql-scripts-meta.patch b/mysql-test/mysql-scripts-meta.patch new file mode 100644 index 0000000..0bbc50a --- /dev/null +++ b/mysql-test/mysql-scripts-meta.patch @@ -0,0 +1,716 @@ +diff --git a/scripts/mysql_system_tables.sql b/scripts/mysql_system_tables.sql +index bc23872..bc85611 100644 +--- a/scripts/mysql_system_tables.sql ++++ b/scripts/mysql_system_tables.sql +@@ -1,39 +1,10 @@ +--- Copyright (c) 2007, 2021, Oracle and/or its affiliates. +--- +--- This program is free software; you can redistribute it and/or modify +--- it under the terms of the GNU General Public License, version 2.0, +--- as published by the Free Software Foundation. +--- +--- This program is also distributed with certain software (including +--- but not limited to OpenSSL) that is licensed under separate terms, +--- as designated in a particular file or component or in included license +--- documentation. The authors of MySQL hereby grant you an additional +--- permission to link the program and your derivative works with the +--- separately licensed software that they have included with MySQL. +--- +--- This program is distributed in the hope that it will be useful, +--- but WITHOUT ANY WARRANTY; without even the implied warranty of +--- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +--- GNU General Public License, version 2.0, for more details. +--- +--- You should have received a copy of the GNU General Public License +--- along with this program; if not, write to the Free Software +--- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +- +--- +--- The system tables of MySQL Server +--- +- +-set @have_innodb= (select count(engine) from information_schema.engines where engine='INNODB' and support != 'NO'); +-set @is_mysql_encrypted = (select ENCRYPTION from information_schema.INNODB_TABLESPACES where NAME='mysql'); +- +--- Tables below are NOT treated as DD tables by MySQL server yet. ++set @have_innodb=0; ++-- set @is_mysql_encrypted = (select ENCRYPTION from information_schema.CTC_TABLESPACES where NAME='mysql'); ++set @is_mysql_encrypted = 0; + + SET FOREIGN_KEY_CHECKS= 1; + +-# Added sql_mode elements and making it as SET, instead of ENUM +- +-set default_storage_engine=InnoDB; ++set default_storage_engine=CTC; + + SET @cmd = "CREATE TABLE IF NOT EXISTS db + ( +@@ -61,14 +32,14 @@ Event_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, + PRIMARY KEY Host (Host,Db,User), KEY User (User) + ) +-engine=InnoDB STATS_PERSISTENT=0 CHARACTER SET utf8 COLLATE utf8_bin comment='Database privileges' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; +-SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++engine=CTC STATS_PERSISTENT=0 CHARACTER SET utf8 COLLATE utf8_bin comment='Database privileges' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; ++-- SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @str = @cmd; + PREPARE stmt FROM @str; + EXECUTE stmt; + DROP PREPARE stmt; + + +--- Remember for later if db table already existed + set @had_db_table= @@warning_count != 0; + + SET @cmd = "CREATE TABLE IF NOT EXISTS user +@@ -125,8 +96,9 @@ Password_reuse_time smallint unsigned NULL DEFAULT NULL, + Password_require_current enum('N', 'Y') COLLATE utf8_general_ci DEFAULT NULL, + User_attributes JSON DEFAULT NULL, + PRIMARY KEY Host (Host,User) +-) engine=InnoDB STATS_PERSISTENT=0 CHARACTER SET utf8 COLLATE utf8_bin comment='Users and global privileges' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; +-SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++) engine=CTC STATS_PERSISTENT=0 CHARACTER SET utf8 COLLATE utf8_bin comment='Users and global privileges' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; ++-- SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @str = @cmd; + PREPARE stmt FROM @str; + EXECUTE stmt; + DROP PREPARE stmt; +@@ -139,8 +111,9 @@ USER CHAR(32) BINARY DEFAULT '' NOT NULL, + DEFAULT_ROLE_HOST CHAR(255) CHARACTER SET ASCII DEFAULT '%' NOT NULL, + DEFAULT_ROLE_USER CHAR(32) BINARY DEFAULT '' NOT NULL, + PRIMARY KEY (HOST, USER, DEFAULT_ROLE_HOST, DEFAULT_ROLE_USER) +-) engine=InnoDB STATS_PERSISTENT=0 CHARACTER SET utf8 COLLATE utf8_bin comment='Default roles' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; +-SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++) engine=CTC STATS_PERSISTENT=0 CHARACTER SET utf8 COLLATE utf8_bin comment='Default roles' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; ++-- SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @str = @cmd; + PREPARE stmt FROM @str; + EXECUTE stmt; + DROP PREPARE stmt; +@@ -154,8 +127,9 @@ TO_HOST CHAR(255) CHARACTER SET ASCII DEFAULT '' NOT NULL, + TO_USER CHAR(32) BINARY DEFAULT '' NOT NULL, + WITH_ADMIN_OPTION ENUM('N', 'Y') COLLATE UTF8_GENERAL_CI DEFAULT 'N' NOT NULL, + PRIMARY KEY (FROM_HOST,FROM_USER,TO_HOST,TO_USER) +-) engine=InnoDB STATS_PERSISTENT=0 CHARACTER SET utf8 COLLATE utf8_bin comment='Role hierarchy and role grants' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; +-SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++) engine=CTC STATS_PERSISTENT=0 CHARACTER SET utf8 COLLATE utf8_bin comment='Role hierarchy and role grants' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; ++-- SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @str = @cmd; + PREPARE stmt FROM @str; + EXECUTE stmt; + DROP PREPARE stmt; +@@ -168,14 +142,14 @@ HOST CHAR(255) CHARACTER SET ASCII DEFAULT '' NOT NULL, + PRIV CHAR(32) COLLATE UTF8_GENERAL_CI DEFAULT '' NOT NULL, + WITH_GRANT_OPTION ENUM('N','Y') COLLATE UTF8_GENERAL_CI DEFAULT 'N' NOT NULL, + PRIMARY KEY (USER,HOST,PRIV) +-) engine=InnoDB STATS_PERSISTENT=0 CHARACTER SET utf8 COLLATE utf8_bin comment='Extended global grants' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; +-SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++) engine=CTC STATS_PERSISTENT=0 CHARACTER SET utf8 COLLATE utf8_bin comment='Extended global grants' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; ++-- SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @str = @cmd; + PREPARE stmt FROM @str; + EXECUTE stmt; + DROP PREPARE stmt; + + +--- Remember for later if user table already existed + set @had_user_table= @@warning_count != 0; + + SET @cmd = "CREATE TABLE IF NOT EXISTS password_history +@@ -185,149 +159,162 @@ SET @cmd = "CREATE TABLE IF NOT EXISTS password_history + Password_timestamp TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), + Password TEXT, + PRIMARY KEY(Host, User, Password_timestamp DESC) +- ) engine=InnoDB STATS_PERSISTENT=0 CHARACTER SET utf8 COLLATE utf8_bin ++ ) engine=CTC STATS_PERSISTENT=0 CHARACTER SET utf8 COLLATE utf8_bin + comment='Password history for user accounts' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; +-SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++-- SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @str = @cmd; + PREPARE stmt FROM @str; + EXECUTE stmt; + DROP PREPARE stmt; + + + +-SET @cmd = "CREATE TABLE IF NOT EXISTS func ( name char(64) binary DEFAULT '' NOT NULL, ret tinyint DEFAULT '0' NOT NULL, dl char(128) DEFAULT '' NOT NULL, type enum ('function','aggregate') COLLATE utf8_general_ci NOT NULL, PRIMARY KEY (name) ) engine=INNODB STATS_PERSISTENT=0 CHARACTER SET utf8 COLLATE utf8_bin comment='User defined functions' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; +-SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @cmd = "CREATE TABLE IF NOT EXISTS func ( name char(64) binary DEFAULT '' NOT NULL, ret tinyint DEFAULT '0' NOT NULL, dl char(128) DEFAULT '' NOT NULL, type enum ('function','aggregate') COLLATE utf8_general_ci NOT NULL, PRIMARY KEY (name) ) engine=CTC STATS_PERSISTENT=0 CHARACTER SET utf8 COLLATE utf8_bin comment='User defined functions' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; ++-- SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @str = @cmd; + PREPARE stmt FROM @str; + EXECUTE stmt; + DROP PREPARE stmt; + + + +-SET @cmd = "CREATE TABLE IF NOT EXISTS plugin ( name varchar(64) DEFAULT '' NOT NULL, dl varchar(128) DEFAULT '' NOT NULL, PRIMARY KEY (name) ) engine=InnoDB STATS_PERSISTENT=0 CHARACTER SET utf8 COLLATE utf8_general_ci comment='MySQL plugins' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; +-SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @cmd = "CREATE TABLE IF NOT EXISTS plugin ( name varchar(64) DEFAULT '' NOT NULL, dl varchar(128) DEFAULT '' NOT NULL, PRIMARY KEY (name) ) engine=CTC STATS_PERSISTENT=0 CHARACTER SET utf8 COLLATE utf8_general_ci comment='MySQL plugins' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; ++-- SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @str = @cmd; + PREPARE stmt FROM @str; + EXECUTE stmt; + DROP PREPARE stmt; + + + +-SET @cmd = "CREATE TABLE IF NOT EXISTS help_topic ( help_topic_id int unsigned not null, name char(64) not null, help_category_id smallint unsigned not null, description text not null, example text not null, url text not null, primary key (help_topic_id), unique index (name) ) engine=INNODB STATS_PERSISTENT=0 CHARACTER SET utf8 comment='help topics' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; +-SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @cmd = "CREATE TABLE IF NOT EXISTS help_topic ( help_topic_id int unsigned not null, name char(64) not null, help_category_id smallint unsigned not null, description text not null, example text not null, url text not null, primary key (help_topic_id), unique index (name) ) engine=CTC STATS_PERSISTENT=0 CHARACTER SET utf8 comment='help topics' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; ++-- SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @str = @cmd; + PREPARE stmt FROM @str; + EXECUTE stmt; + DROP PREPARE stmt; + + + +-SET @cmd = "CREATE TABLE IF NOT EXISTS help_category ( help_category_id smallint unsigned not null, name char(64) not null, parent_category_id smallint unsigned null, url text not null, primary key (help_category_id), unique index (name) ) engine=INNODB STATS_PERSISTENT=0 CHARACTER SET utf8 comment='help categories' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; +-SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @cmd = "CREATE TABLE IF NOT EXISTS help_category ( help_category_id smallint unsigned not null, name char(64) not null, parent_category_id smallint unsigned null, url text not null, primary key (help_category_id), unique index (name) ) engine=CTC STATS_PERSISTENT=0 CHARACTER SET utf8 comment='help categories' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; ++-- SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @str = @cmd; + PREPARE stmt FROM @str; + EXECUTE stmt; + DROP PREPARE stmt; + + + +-SET @cmd = "CREATE TABLE IF NOT EXISTS help_relation ( help_topic_id int unsigned not null, help_keyword_id int unsigned not null, primary key (help_keyword_id, help_topic_id) ) engine=INNODB STATS_PERSISTENT=0 CHARACTER SET utf8 comment='keyword-topic relation' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; +-SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @cmd = "CREATE TABLE IF NOT EXISTS help_relation ( help_topic_id int unsigned not null, help_keyword_id int unsigned not null, primary key (help_keyword_id, help_topic_id) ) engine=CTC STATS_PERSISTENT=0 CHARACTER SET utf8 comment='keyword-topic relation' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; ++-- SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @str = @cmd; + PREPARE stmt FROM @str; + EXECUTE stmt; + DROP PREPARE stmt; + + + +-SET @cmd = "CREATE TABLE IF NOT EXISTS servers ( Server_name char(64) NOT NULL DEFAULT '', Host char(255) CHARACTER SET ASCII NOT NULL DEFAULT '', Db char(64) NOT NULL DEFAULT '', Username char(64) NOT NULL DEFAULT '', Password char(64) NOT NULL DEFAULT '', Port INT NOT NULL DEFAULT '0', Socket char(64) NOT NULL DEFAULT '', Wrapper char(64) NOT NULL DEFAULT '', Owner char(64) NOT NULL DEFAULT '', PRIMARY KEY (Server_name)) engine=InnoDB STATS_PERSISTENT=0 CHARACTER SET utf8 comment='MySQL Foreign Servers table' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; +-SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @cmd = "CREATE TABLE IF NOT EXISTS servers ( Server_name char(64) NOT NULL DEFAULT '', Host char(255) CHARACTER SET ASCII NOT NULL DEFAULT '', Db char(64) NOT NULL DEFAULT '', Username char(64) NOT NULL DEFAULT '', Password char(64) NOT NULL DEFAULT '', Port INT NOT NULL DEFAULT '0', Socket char(64) NOT NULL DEFAULT '', Wrapper char(64) NOT NULL DEFAULT '', Owner char(64) NOT NULL DEFAULT '', PRIMARY KEY (Server_name)) engine=CTC STATS_PERSISTENT=0 CHARACTER SET utf8 comment='MySQL Foreign Servers table' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; ++-- SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @str = @cmd; + PREPARE stmt FROM @str; + EXECUTE stmt; + DROP PREPARE stmt; + + + +-SET @cmd = "CREATE TABLE IF NOT EXISTS tables_priv ( Host char(255) CHARACTER SET ASCII DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(32) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Grantor varchar(288) DEFAULT '' NOT NULL, Timestamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name), KEY Grantor (Grantor) ) engine=INNODB STATS_PERSISTENT=0 CHARACTER SET utf8 engine=InnoDB STATS_PERSISTENT=0 CHARACTER SET utf8 COLLATE utf8_bin comment='Table privileges' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; +-SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @cmd = "CREATE TABLE IF NOT EXISTS tables_priv ( Host char(255) CHARACTER SET ASCII DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(32) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Grantor varchar(288) DEFAULT '' NOT NULL, Timestamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name), KEY Grantor (Grantor) ) engine=CTC STATS_PERSISTENT=0 CHARACTER SET utf8 engine=CTC STATS_PERSISTENT=0 CHARACTER SET utf8 COLLATE utf8_bin comment='Table privileges' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; ++-- SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @str = @cmd; + PREPARE stmt FROM @str; + EXECUTE stmt; + DROP PREPARE stmt; + + + +-SET @cmd = "CREATE TABLE IF NOT EXISTS columns_priv ( Host char(255) CHARACTER SET ASCII DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(32) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Column_name char(64) binary DEFAULT '' NOT NULL, Timestamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name,Column_name) ) engine=InnoDB STATS_PERSISTENT=0 CHARACTER SET utf8 COLLATE utf8_bin comment='Column privileges' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; +-SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @cmd = "CREATE TABLE IF NOT EXISTS columns_priv ( Host char(255) CHARACTER SET ASCII DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(32) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Column_name char(64) binary DEFAULT '' NOT NULL, Timestamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name,Column_name) ) engine=CTC STATS_PERSISTENT=0 CHARACTER SET utf8 COLLATE utf8_bin comment='Column privileges' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; ++-- SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @str = @cmd; + PREPARE stmt FROM @str; + EXECUTE stmt; + DROP PREPARE stmt; + + + +-SET @cmd = "CREATE TABLE IF NOT EXISTS help_keyword ( help_keyword_id int unsigned not null, name char(64) not null, primary key (help_keyword_id), unique index (name) ) engine=INNODB STATS_PERSISTENT=0 CHARACTER SET utf8 comment='help keywords' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; +-SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @cmd = "CREATE TABLE IF NOT EXISTS help_keyword ( help_keyword_id int unsigned not null, name char(64) not null, primary key (help_keyword_id), unique index (name) ) engine=CTC STATS_PERSISTENT=0 CHARACTER SET utf8 comment='help keywords' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; ++-- SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @str = @cmd; + PREPARE stmt FROM @str; + EXECUTE stmt; + DROP PREPARE stmt; + + + +-SET @cmd = "CREATE TABLE IF NOT EXISTS time_zone_name ( Name char(64) NOT NULL, Time_zone_id int unsigned NOT NULL, PRIMARY KEY Name (Name) ) engine=INNODB STATS_PERSISTENT=0 CHARACTER SET utf8 comment='Time zone names' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; +-SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @cmd = "CREATE TABLE IF NOT EXISTS time_zone_name ( Name char(64) NOT NULL, Time_zone_id int unsigned NOT NULL, PRIMARY KEY Name (Name) ) engine=CTC STATS_PERSISTENT=0 CHARACTER SET utf8 comment='Time zone names' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; ++-- SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @str = @cmd; + PREPARE stmt FROM @str; + EXECUTE stmt; + DROP PREPARE stmt; + + + +-SET @cmd = "CREATE TABLE IF NOT EXISTS time_zone ( Time_zone_id int unsigned NOT NULL auto_increment, Use_leap_seconds enum('Y','N') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, PRIMARY KEY TzId (Time_zone_id) ) engine=INNODB STATS_PERSISTENT=0 CHARACTER SET utf8 comment='Time zones' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; +-SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @cmd = "CREATE TABLE IF NOT EXISTS time_zone ( Time_zone_id int unsigned NOT NULL auto_increment, Use_leap_seconds enum('Y','N') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, PRIMARY KEY TzId (Time_zone_id) ) engine=CTC STATS_PERSISTENT=0 CHARACTER SET utf8 comment='Time zones' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; ++-- SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @str = @cmd; + PREPARE stmt FROM @str; + EXECUTE stmt; + DROP PREPARE stmt; + + + +-SET @cmd = "CREATE TABLE IF NOT EXISTS time_zone_transition ( Time_zone_id int unsigned NOT NULL, Transition_time bigint signed NOT NULL, Transition_type_id int unsigned NOT NULL, PRIMARY KEY TzIdTranTime (Time_zone_id, Transition_time) ) engine=INNODB STATS_PERSISTENT=0 CHARACTER SET utf8 comment='Time zone transitions' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; +-SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @cmd = "CREATE TABLE IF NOT EXISTS time_zone_transition ( Time_zone_id int unsigned NOT NULL, Transition_time bigint signed NOT NULL, Transition_type_id int unsigned NOT NULL, PRIMARY KEY TzIdTranTime (Time_zone_id, Transition_time) ) engine=CTC STATS_PERSISTENT=0 CHARACTER SET utf8 comment='Time zone transitions' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; ++-- SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @str = @cmd; + PREPARE stmt FROM @str; + EXECUTE stmt; + DROP PREPARE stmt; + + + +-SET @cmd = "CREATE TABLE IF NOT EXISTS time_zone_transition_type ( Time_zone_id int unsigned NOT NULL, Transition_type_id int unsigned NOT NULL, Offset int signed DEFAULT 0 NOT NULL, Is_DST tinyint unsigned DEFAULT 0 NOT NULL, Abbreviation char(8) DEFAULT '' NOT NULL, PRIMARY KEY TzIdTrTId (Time_zone_id, Transition_type_id) ) engine=INNODB STATS_PERSISTENT=0 CHARACTER SET utf8 comment='Time zone transition types' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; +-SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @cmd = "CREATE TABLE IF NOT EXISTS time_zone_transition_type ( Time_zone_id int unsigned NOT NULL, Transition_type_id int unsigned NOT NULL, Offset int signed DEFAULT 0 NOT NULL, Is_DST tinyint unsigned DEFAULT 0 NOT NULL, Abbreviation char(8) DEFAULT '' NOT NULL, PRIMARY KEY TzIdTrTId (Time_zone_id, Transition_type_id) ) engine=CTC STATS_PERSISTENT=0 CHARACTER SET utf8 comment='Time zone transition types' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; ++-- SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @str = @cmd; + PREPARE stmt FROM @str; + EXECUTE stmt; + DROP PREPARE stmt; + + + +-SET @cmd = "CREATE TABLE IF NOT EXISTS time_zone_leap_second ( Transition_time bigint signed NOT NULL, Correction int signed NOT NULL, PRIMARY KEY TranTime (Transition_time) ) engine=INNODB STATS_PERSISTENT=0 CHARACTER SET utf8 comment='Leap seconds information for time zones' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; +-SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @cmd = "CREATE TABLE IF NOT EXISTS time_zone_leap_second ( Transition_time bigint signed NOT NULL, Correction int signed NOT NULL, PRIMARY KEY TranTime (Transition_time) ) engine=CTC STATS_PERSISTENT=0 CHARACTER SET utf8 comment='Leap seconds information for time zones' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; ++-- SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @str = @cmd; + PREPARE stmt FROM @str; + EXECUTE stmt; + DROP PREPARE stmt; + + + +-SET @cmd = "CREATE TABLE IF NOT EXISTS procs_priv ( Host char(255) CHARACTER SET ASCII DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(32) binary DEFAULT '' NOT NULL, Routine_name char(64) COLLATE utf8_general_ci DEFAULT '' NOT NULL, Routine_type enum('FUNCTION','PROCEDURE') NOT NULL, Grantor varchar(288) DEFAULT '' NOT NULL, Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Timestamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (Host,Db,User,Routine_name,Routine_type), KEY Grantor (Grantor) ) engine=InnoDB STATS_PERSISTENT=0 CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; +-SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @cmd = "CREATE TABLE IF NOT EXISTS procs_priv ( Host char(255) CHARACTER SET ASCII DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(32) binary DEFAULT '' NOT NULL, Routine_name char(64) COLLATE utf8_general_ci DEFAULT '' NOT NULL, Routine_type enum('FUNCTION','PROCEDURE') NOT NULL, Grantor varchar(288) DEFAULT '' NOT NULL, Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Timestamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (Host,Db,User,Routine_name,Routine_type), KEY Grantor (Grantor) ) engine=CTC STATS_PERSISTENT=0 CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; ++-- SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @str = @cmd; + PREPARE stmt FROM @str; + EXECUTE stmt; + DROP PREPARE stmt; + + +--- bug#92988: Temporarily turn off sql_require_primary_key for the +--- next 2 tables as this is not necessary as they do not replicate. + SET @old_sql_require_primary_key = @@session.sql_require_primary_key; + SET @@session.sql_require_primary_key = 0; + +--- Create general_log +-CREATE TABLE IF NOT EXISTS general_log (event_time TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), user_host MEDIUMTEXT NOT NULL, thread_id BIGINT UNSIGNED NOT NULL, server_id INTEGER UNSIGNED NOT NULL, command_type VARCHAR(64) NOT NULL, argument MEDIUMBLOB NOT NULL) engine=CSV CHARACTER SET utf8 comment="General log"; ++CREATE TABLE IF NOT EXISTS general_log (event_time TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), user_host MEDIUMTEXT NOT NULL, thread_id BIGINT UNSIGNED NOT NULL, server_id INTEGER UNSIGNED NOT NULL, command_type VARCHAR(64) NOT NULL, argument MEDIUMBLOB NOT NULL) engine=CTC CHARACTER SET utf8 comment="General log"; + +--- Create slow_log +-CREATE TABLE IF NOT EXISTS slow_log (start_time TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), user_host MEDIUMTEXT NOT NULL, query_time TIME(6) NOT NULL, lock_time TIME(6) NOT NULL, rows_sent INTEGER NOT NULL, rows_examined INTEGER NOT NULL, db VARCHAR(512) NOT NULL, last_insert_id INTEGER NOT NULL, insert_id INTEGER NOT NULL, server_id INTEGER UNSIGNED NOT NULL, sql_text MEDIUMBLOB NOT NULL, thread_id BIGINT UNSIGNED NOT NULL) engine=CSV CHARACTER SET utf8 comment="Slow log"; ++CREATE TABLE IF NOT EXISTS slow_log (start_time TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), user_host MEDIUMTEXT NOT NULL, query_time TIME(6) NOT NULL, lock_time TIME(6) NOT NULL, rows_sent INTEGER NOT NULL, rows_examined INTEGER NOT NULL, db VARCHAR(512) NOT NULL, last_insert_id INTEGER NOT NULL, insert_id INTEGER NOT NULL, server_id INTEGER UNSIGNED NOT NULL, sql_text MEDIUMBLOB NOT NULL, thread_id BIGINT UNSIGNED NOT NULL) engine=CTC CHARACTER SET utf8 comment="Slow log"; + + SET @@session.sql_require_primary_key = @old_sql_require_primary_key; + +-SET @cmd = "CREATE TABLE IF NOT EXISTS component ( component_id int unsigned NOT NULL AUTO_INCREMENT, component_group_id int unsigned NOT NULL, component_urn text NOT NULL, PRIMARY KEY (component_id)) engine=INNODB DEFAULT CHARSET=utf8 COMMENT 'Components' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; +-SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @cmd = "CREATE TABLE IF NOT EXISTS component ( component_id int unsigned NOT NULL AUTO_INCREMENT, component_group_id int unsigned NOT NULL, component_urn text NOT NULL, PRIMARY KEY (component_id)) engine=CTC DEFAULT CHARSET=utf8 COMMENT 'Components' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; ++-- SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @str = @cmd; + PREPARE stmt FROM @str; + EXECUTE stmt; + DROP PREPARE stmt; +@@ -351,7 +338,7 @@ SET @cmd="CREATE TABLE IF NOT EXISTS slave_relay_log_info ( + Assign_gtids_to_anonymous_transactions_value TEXT CHARACTER SET utf8 COLLATE utf8_bin COMMENT 'Indicates the UUID used while generating GTIDs for anonymous transactions', + PRIMARY KEY(Channel_name)) DEFAULT CHARSET=utf8 STATS_PERSISTENT=0 COMMENT 'Relay Log Information'"; + +-SET @str=IF(@have_innodb <> 0, CONCAT(@cmd, ' ENGINE= INNODB ROW_FORMAT=DYNAMIC TABLESPACE=mysql ENCRYPTION=\'', @is_mysql_encrypted,'\''), CONCAT(@cmd, ' ENGINE= MYISAM')); ++SET @str=IF(@have_innodb <> 0, CONCAT(@cmd, ' ENGINE= CTC ROW_FORMAT=DYNAMIC TABLESPACE=mysql ENCRYPTION=\'', @is_mysql_encrypted,'\''), CONCAT(@cmd, ' ENGINE= CTC')); + PREPARE stmt FROM @str; + EXECUTE stmt; + DROP PREPARE stmt; +@@ -391,7 +378,7 @@ SET @cmd= "CREATE TABLE IF NOT EXISTS slave_master_info ( + Source_connection_auto_failover BOOLEAN NOT NULL DEFAULT FALSE COMMENT 'Indicates whether the channel connection failover is enabled.', + PRIMARY KEY(Channel_name)) DEFAULT CHARSET=utf8 STATS_PERSISTENT=0 COMMENT 'Master Information'"; + +-SET @str=IF(@have_innodb <> 0, CONCAT(@cmd, ' ENGINE= INNODB ROW_FORMAT=DYNAMIC TABLESPACE=mysql ENCRYPTION=\'', @is_mysql_encrypted,'\''), CONCAT(@cmd, ' ENGINE= MYISAM')); ++SET @str=IF(@have_innodb <> 0, CONCAT(@cmd, ' ENGINE= CTC ROW_FORMAT=DYNAMIC TABLESPACE=mysql ENCRYPTION=\'', @is_mysql_encrypted,'\''), CONCAT(@cmd, ' ENGINE= CTC')); + PREPARE stmt FROM @str; + EXECUTE stmt; + DROP PREPARE stmt; +@@ -412,7 +399,7 @@ SET @cmd= "CREATE TABLE IF NOT EXISTS slave_worker_info ( + Channel_name CHAR(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'The channel on which the slave is connected to a source. Used in Multisource Replication', + PRIMARY KEY(Channel_name, Id)) DEFAULT CHARSET=utf8 STATS_PERSISTENT=0 COMMENT 'Worker Information'"; + +-SET @str=IF(@have_innodb <> 0, CONCAT(@cmd, ' ENGINE= INNODB ROW_FORMAT=DYNAMIC TABLESPACE=mysql ENCRYPTION=\'', @is_mysql_encrypted,'\''), CONCAT(@cmd, ' ENGINE= MYISAM')); ++SET @str=IF(@have_innodb <> 0, CONCAT(@cmd, ' ENGINE= CTC ROW_FORMAT=DYNAMIC TABLESPACE=mysql ENCRYPTION=\'', @is_mysql_encrypted,'\''), CONCAT(@cmd, ' ENGINE= CTC')); + PREPARE stmt FROM @str; + EXECUTE stmt; + DROP PREPARE stmt; +@@ -423,12 +410,11 @@ SET @cmd= "CREATE TABLE IF NOT EXISTS gtid_executed ( + interval_end BIGINT NOT NULL COMMENT 'Last number of interval.', + PRIMARY KEY(source_uuid, interval_start)) STATS_PERSISTENT=0"; + +-SET @str=IF(@have_innodb <> 0, CONCAT(@cmd, ' ENGINE= INNODB ROW_FORMAT=DYNAMIC TABLESPACE=mysql ENCRYPTION=\'', @is_mysql_encrypted,'\''), CONCAT(@cmd, ' ENGINE= MYISAM')); ++SET @str=IF(@have_innodb <> 0, CONCAT(@cmd, ' ENGINE= CTC ROW_FORMAT=DYNAMIC TABLESPACE=mysql ENCRYPTION=\'', @is_mysql_encrypted,'\''), CONCAT(@cmd, ' ENGINE= CTC')); + PREPARE stmt FROM @str; + EXECUTE stmt; + DROP PREPARE stmt; + +--- replication_asynchronous_connection_failover table + SET @cmd= "CREATE TABLE IF NOT EXISTS replication_asynchronous_connection_failover ( + Channel_name CHAR(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'The replication channel name that connects source and replica.', + Host CHAR(255) CHARACTER SET ASCII NOT NULL COMMENT 'The source hostname that the replica will attempt to switch over the replication connection to in case of a failure.', +@@ -438,12 +424,11 @@ SET @cmd= "CREATE TABLE IF NOT EXISTS replication_asynchronous_connection_failov + Managed_name CHAR(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT 'The name of the group which this server belongs to.', + PRIMARY KEY(Channel_name, Host, Port, Network_namespace, Managed_name), KEY(Channel_name, Managed_name)) DEFAULT CHARSET=utf8 STATS_PERSISTENT=0 COMMENT 'The source configuration details'"; + +-SET @str=IF(@have_innodb <> 0, CONCAT(@cmd, ' ENGINE= INNODB ROW_FORMAT=DYNAMIC TABLESPACE=mysql ENCRYPTION=\'', @is_mysql_encrypted,'\''), CONCAT(@cmd, ' ENGINE= MYISAM')); ++SET @str=IF(@have_innodb <> 0, CONCAT(@cmd, ' ENGINE= CTC ROW_FORMAT=DYNAMIC TABLESPACE=mysql ENCRYPTION=\'', @is_mysql_encrypted,'\''), CONCAT(@cmd, ' ENGINE= CTC')); + PREPARE stmt FROM @str; + EXECUTE stmt; + DROP PREPARE stmt; + +--- replication_asynchronous_connection_failover_managed table + SET @cmd= "CREATE TABLE IF NOT EXISTS replication_asynchronous_connection_failover_managed ( + Channel_name CHAR(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'The replication channel name that connects source and replica.', + Managed_name CHAR(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT 'The name of the source which needs to be managed.', +@@ -451,12 +436,11 @@ SET @cmd= "CREATE TABLE IF NOT EXISTS replication_asynchronous_connection_failov + Configuration JSON DEFAULT NULL COMMENT 'The data to help manage group. For Managed_type = GroupReplication, Configuration value should contain {\"Primary_weight\": 80, \"Secondary_weight\": 60}, so that it assigns weight=80 to PRIMARY of the group, and weight=60 for rest of the members in mysql.replication_asynchronous_connection_failover table.', + PRIMARY KEY(Channel_name, Managed_name)) DEFAULT CHARSET=utf8 STATS_PERSISTENT=0 COMMENT 'The managed source configuration details'"; + +-SET @str=IF(@have_innodb <> 0, CONCAT(@cmd, ' ENGINE= INNODB ROW_FORMAT=DYNAMIC TABLESPACE=mysql ENCRYPTION=\'', @is_mysql_encrypted,'\''), CONCAT(@cmd, ' ENGINE= MYISAM')); ++SET @str=IF(@have_innodb <> 0, CONCAT(@cmd, ' ENGINE= CTC ROW_FORMAT=DYNAMIC TABLESPACE=mysql ENCRYPTION=\'', @is_mysql_encrypted,'\''), CONCAT(@cmd, ' ENGINE= CTC')); + PREPARE stmt FROM @str; + EXECUTE stmt; + DROP PREPARE stmt; + +--- replication_group_member_actions + SET @cmd= "CREATE TABLE IF NOT EXISTS replication_group_member_actions ( + name CHAR(255) CHARACTER SET ASCII NOT NULL COMMENT 'The action name.', + event CHAR(64) CHARACTER SET ASCII NOT NULL COMMENT 'The event that will trigger the action.', +@@ -466,30 +450,21 @@ SET @cmd= "CREATE TABLE IF NOT EXISTS replication_group_member_actions ( + error_handling CHAR(64) CHARACTER SET ASCII NOT NULL COMMENT 'On errors during the action will be handled: IGNORE, CRITICAL.', + PRIMARY KEY(name, event), KEY(event)) DEFAULT CHARSET=utf8mb4 STATS_PERSISTENT=0 COMMENT 'The member actions configuration.'"; + +-SET @str=IF(@have_innodb <> 0, CONCAT(@cmd, ' ENGINE= INNODB ROW_FORMAT=DYNAMIC TABLESPACE=mysql ENCRYPTION=\'', @is_mysql_encrypted,'\''), CONCAT(@cmd, ' ENGINE= MYISAM')); ++SET @str=IF(@have_innodb <> 0, CONCAT(@cmd, ' ENGINE= CTC ROW_FORMAT=DYNAMIC TABLESPACE=mysql ENCRYPTION=\'', @is_mysql_encrypted,'\''), CONCAT(@cmd, ' ENGINE= CTC')); + PREPARE stmt FROM @str; + EXECUTE stmt; + DROP PREPARE stmt; + +--- replication_group_configuration_version + SET @cmd= "CREATE TABLE IF NOT EXISTS replication_group_configuration_version ( + name CHAR(255) CHARACTER SET ASCII NOT NULL COMMENT 'The configuration name.', + version BIGINT UNSIGNED NOT NULL COMMENT 'The version of the configuration name.', + PRIMARY KEY(name)) DEFAULT CHARSET=utf8mb4 STATS_PERSISTENT=0 COMMENT 'The group configuration version.'"; + +-SET @str=IF(@have_innodb <> 0, CONCAT(@cmd, ' ENGINE= INNODB ROW_FORMAT=DYNAMIC TABLESPACE=mysql ENCRYPTION=\'', @is_mysql_encrypted,'\''), CONCAT(@cmd, ' ENGINE= MYISAM')); ++SET @str=IF(@have_innodb <> 0, CONCAT(@cmd, ' ENGINE= CTC ROW_FORMAT=DYNAMIC TABLESPACE=mysql ENCRYPTION=\'', @is_mysql_encrypted,'\''), CONCAT(@cmd, ' ENGINE= CTC')); + PREPARE stmt FROM @str; + EXECUTE stmt; + DROP PREPARE stmt; + +--- +--- Optimizer Cost Model configuration +--- (Note: Column definition for default_value needs to be updated when a +--- default value is changed). +--- +- +--- Server cost constants +- + SET @cmd = "CREATE TABLE IF NOT EXISTS server_cost ( + cost_name VARCHAR(64) NOT NULL, + cost_value FLOAT DEFAULT NULL, +@@ -506,8 +481,9 @@ SET @cmd = "CREATE TABLE IF NOT EXISTS server_cost ( + ELSE NULL + END) VIRTUAL, + PRIMARY KEY (cost_name) +-) ENGINE=InnoDB CHARACTER SET=utf8 COLLATE=utf8_general_ci STATS_PERSISTENT=0 ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; +-SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++) ENGINE=CTC CHARACTER SET=utf8 COLLATE=utf8_general_ci STATS_PERSISTENT=0 ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; ++-- SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @str = @cmd; + PREPARE stmt FROM @str; + EXECUTE stmt; + DROP PREPARE stmt; +@@ -518,7 +494,6 @@ INSERT IGNORE INTO server_cost(cost_name) VALUES + ("memory_temptable_create_cost"), ("memory_temptable_row_cost"), + ("disk_temptable_create_cost"), ("disk_temptable_row_cost"); + +--- Engine cost constants + + SET @cmd = "CREATE TABLE IF NOT EXISTS engine_cost ( + engine_name VARCHAR(64) NOT NULL, +@@ -534,8 +509,9 @@ SET @cmd = "CREATE TABLE IF NOT EXISTS engine_cost ( + ELSE NULL + END) VIRTUAL, + PRIMARY KEY (cost_name, engine_name, device_type) +-) ENGINE=InnoDB CHARACTER SET=utf8 COLLATE=utf8_general_ci STATS_PERSISTENT=0 ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; +-SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++) ENGINE=CTC CHARACTER SET=utf8 COLLATE=utf8_general_ci STATS_PERSISTENT=0 ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; ++-- SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @str = @cmd; + PREPARE stmt FROM @str; + EXECUTE stmt; + DROP PREPARE stmt; +@@ -546,23 +522,19 @@ INSERT IGNORE INTO engine_cost(engine_name, device_type, cost_name) VALUES + ("default", 0, "io_block_read_cost"); + + +-SET @cmd = "CREATE TABLE IF NOT EXISTS proxies_priv (Host char(255) CHARACTER SET ASCII DEFAULT '' NOT NULL, User char(32) binary DEFAULT '' NOT NULL, Proxied_host char(255) CHARACTER SET ASCII DEFAULT '' NOT NULL, Proxied_user char(32) binary DEFAULT '' NOT NULL, With_grant BOOL DEFAULT 0 NOT NULL, Grantor varchar(288) DEFAULT '' NOT NULL, Timestamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY Host (Host,User,Proxied_host,Proxied_user), KEY Grantor (Grantor) ) engine=InnoDB STATS_PERSISTENT=0 CHARACTER SET utf8 COLLATE utf8_bin comment='User proxy privileges' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; +-SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @cmd = "CREATE TABLE IF NOT EXISTS proxies_priv (Host char(255) CHARACTER SET ASCII DEFAULT '' NOT NULL, User char(32) binary DEFAULT '' NOT NULL, Proxied_host char(255) CHARACTER SET ASCII DEFAULT '' NOT NULL, Proxied_user char(32) binary DEFAULT '' NOT NULL, With_grant BOOL DEFAULT 0 NOT NULL, Grantor varchar(288) DEFAULT '' NOT NULL, Timestamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY Host (Host,User,Proxied_host,Proxied_user), KEY Grantor (Grantor) ) engine=CTC STATS_PERSISTENT=0 CHARACTER SET utf8 COLLATE utf8_bin comment='User proxy privileges' ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; ++-- SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @str = @cmd; + PREPARE stmt FROM @str; + EXECUTE stmt; + DROP PREPARE stmt; + + +--- Remember for later if proxies_priv table already existed + set @had_proxies_priv_table= @@warning_count != 0; + + +--- +--- Only create the ndb_binlog_index table if the server is built with ndb. +--- Create this table last among the tables in the mysql schema to make it +--- easier to keep tests agnostic wrt. the existence of this table. +--- +-SET @have_ndb= (select count(engine) from information_schema.engines where engine='ndbcluster'); ++-- SET @have_ndb= (select count(engine) from information_schema.engines where engine='ndbcluster'); ++SET @have_ndb= 0; + SET @cmd="CREATE TABLE IF NOT EXISTS ndb_binlog_index ( + Position BIGINT UNSIGNED NOT NULL, + File VARCHAR(255) NOT NULL, +@@ -577,9 +549,10 @@ SET @cmd="CREATE TABLE IF NOT EXISTS ndb_binlog_index ( + next_position BIGINT UNSIGNED NOT NULL, + next_file VARCHAR(255) NOT NULL, + PRIMARY KEY(epoch, orig_server_id, orig_epoch) +- ) ENGINE=INNODB CHARACTER SET latin1 STATS_PERSISTENT=0 ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; ++ ) ENGINE=CTC CHARACTER SET latin1 STATS_PERSISTENT=0 ROW_FORMAT=DYNAMIC TABLESPACE=mysql"; + +-SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++-- SET @str = CONCAT(@cmd, " ENCRYPTION='", @is_mysql_encrypted, "'"); ++SET @str = @cmd; + SET @str = IF(@have_ndb = 1, @str, 'SET @dummy = 0'); + PREPARE stmt FROM @str; + EXECUTE stmt; +diff --git a/scripts/mysql_system_tables_fix.sql b/scripts/mysql_system_tables_fix.sql +index 79cf2fc..39b7137 100644 +--- a/scripts/mysql_system_tables_fix.sql ++++ b/scripts/mysql_system_tables_fix.sql +@@ -30,7 +30,7 @@ + # Warning message(s) produced for a statement can be printed by explicitly + # adding a 'SHOW WARNINGS' after the statement. + +-set default_storage_engine=InnoDB; ++set default_storage_engine=CTC; + + # We meed to turn off the default strict mode in case legacy data contains e.g. + # zero dates ('0000-00-00-00:00:00'), otherwise, we risk to end up with +@@ -157,7 +157,7 @@ ADD max_connections int unsigned NOT NULL DEFAULT 0 AFTER max_updates; + # + ALTER TABLE proxies_priv MODIFY User char(32) binary DEFAULT '' NOT NULL; + ALTER TABLE proxies_priv MODIFY Proxied_user char(32) binary DEFAULT '' NOT NULL; +-ALTER TABLE proxies_priv MODIFY Host char(255) CHARACTER SET ASCII DEFAULT '' NOT NULL, ENGINE=InnoDB; ++ALTER TABLE proxies_priv MODIFY Host char(255) CHARACTER SET ASCII DEFAULT '' NOT NULL, ENGINE=CTC; + ALTER TABLE proxies_priv MODIFY Proxied_host char(255) CHARACTER SET ASCII DEFAULT '' NOT NULL; + ALTER TABLE proxies_priv MODIFY Grantor varchar(288) DEFAULT '' NOT NULL; + +@@ -946,7 +946,7 @@ EXECUTE stmt; + DROP PREPARE stmt; + + SET @cmd="ALTER TABLE ndb_binlog_index +- ENGINE=InnoDB STATS_PERSISTENT=0"; ++ ENGINE=CTC STATS_PERSISTENT=0"; + + SET @str = IF(@have_ndb_binlog_index = 1, @cmd, 'SET @dummy = 0'); + PREPARE stmt FROM @str; +@@ -999,29 +999,29 @@ ALTER TABLE help_relation CONVERT TO CHARACTER SET utf8; + ALTER TABLE help_keyword CONVERT TO CHARACTER SET utf8; + + -- +--- Upgrade a table engine from MyISAM to InnoDB for the system tables ++-- Upgrade a table engine from MyISAM to CTC for the system tables + -- help_topic, help_category, help_relation, help_keyword, plugin, servers, + -- time_zone, time_zone_leap_second, time_zone_name, time_zone_transition, + -- time_zone_transition_type, columns_priv, db, procs_priv, proxies_priv, + -- tables_priv, user. +-ALTER TABLE func ENGINE=InnoDB STATS_PERSISTENT=0; +-ALTER TABLE help_topic ENGINE=InnoDB STATS_PERSISTENT=0; +-ALTER TABLE help_category ENGINE=InnoDB STATS_PERSISTENT=0; +-ALTER TABLE help_relation ENGINE=InnoDB STATS_PERSISTENT=0; +-ALTER TABLE help_keyword ENGINE=InnoDB STATS_PERSISTENT=0; +-ALTER TABLE plugin ENGINE=InnoDB STATS_PERSISTENT=0; +-ALTER TABLE servers ENGINE=InnoDB STATS_PERSISTENT=0; +-ALTER TABLE time_zone ENGINE=InnoDB STATS_PERSISTENT=0; +-ALTER TABLE time_zone_leap_second ENGINE=InnoDB STATS_PERSISTENT=0; +-ALTER TABLE time_zone_name ENGINE=InnoDB STATS_PERSISTENT=0; +-ALTER TABLE time_zone_transition ENGINE=InnoDB STATS_PERSISTENT=0; +-ALTER TABLE time_zone_transition_type ENGINE=InnoDB STATS_PERSISTENT=0; +-ALTER TABLE db ENGINE=InnoDB STATS_PERSISTENT=0; +-ALTER TABLE user ENGINE=InnoDB STATS_PERSISTENT=0; +-ALTER TABLE tables_priv ENGINE=InnoDB STATS_PERSISTENT=0; +-ALTER TABLE columns_priv ENGINE=InnoDB STATS_PERSISTENT=0; +-ALTER TABLE procs_priv ENGINE=InnoDB STATS_PERSISTENT=0; +-ALTER TABLE proxies_priv ENGINE=InnoDB STATS_PERSISTENT=0; ++ALTER TABLE func ENGINE=CTC STATS_PERSISTENT=0; ++ALTER TABLE help_topic ENGINE=CTC STATS_PERSISTENT=0; ++ALTER TABLE help_category ENGINE=CTC STATS_PERSISTENT=0; ++ALTER TABLE help_relation ENGINE=CTC STATS_PERSISTENT=0; ++ALTER TABLE help_keyword ENGINE=CTC STATS_PERSISTENT=0; ++ALTER TABLE plugin ENGINE=CTC STATS_PERSISTENT=0; ++ALTER TABLE servers ENGINE=CTC STATS_PERSISTENT=0; ++ALTER TABLE time_zone ENGINE=CTC STATS_PERSISTENT=0; ++ALTER TABLE time_zone_leap_second ENGINE=CTC STATS_PERSISTENT=0; ++ALTER TABLE time_zone_name ENGINE=CTC STATS_PERSISTENT=0; ++ALTER TABLE time_zone_transition ENGINE=CTC STATS_PERSISTENT=0; ++ALTER TABLE time_zone_transition_type ENGINE=CTC STATS_PERSISTENT=0; ++ALTER TABLE db ENGINE=CTC STATS_PERSISTENT=0; ++ALTER TABLE user ENGINE=CTC STATS_PERSISTENT=0; ++ALTER TABLE tables_priv ENGINE=CTC STATS_PERSISTENT=0; ++ALTER TABLE columns_priv ENGINE=CTC STATS_PERSISTENT=0; ++ALTER TABLE procs_priv ENGINE=CTC STATS_PERSISTENT=0; ++ALTER TABLE proxies_priv ENGINE=CTC STATS_PERSISTENT=0; + + -- + -- CREATE_ROLE_ACL and DROP_ROLE_ACL +@@ -1042,13 +1042,13 @@ ALTER TABLE user MODIFY Password_require_current enum('N','Y') COLLATE utf8_gene + ALTER TABLE user ADD User_attributes JSON DEFAULT NULL AFTER Password_require_current; + + -- +--- Change engine of the firewall tables to InnoDB ++-- Change engine of the firewall tables to CTC + -- + SET @had_firewall_whitelist = + (SELECT COUNT(table_name) FROM information_schema.tables + WHERE table_schema = 'mysql' AND table_name = 'firewall_whitelist' AND + table_type = 'BASE TABLE'); +-SET @cmd="ALTER TABLE mysql.firewall_whitelist ENGINE=InnoDB"; ++SET @cmd="ALTER TABLE mysql.firewall_whitelist ENGINE=CTC"; + SET @str = IF(@had_firewall_whitelist > 0, @cmd, "SET @dummy = 0"); + PREPARE stmt FROM @str; + EXECUTE stmt; +@@ -1064,7 +1064,7 @@ SET @had_firewall_users = + (SELECT COUNT(table_name) FROM information_schema.tables + WHERE table_schema = 'mysql' AND table_name = 'firewall_users' AND + table_type = 'BASE TABLE'); +-SET @cmd="ALTER TABLE mysql.firewall_users ENGINE=InnoDB"; ++SET @cmd="ALTER TABLE mysql.firewall_users ENGINE=CTC"; + SET @str = IF(@had_firewall_users > 0, @cmd, "SET @dummy = 0"); + PREPARE stmt FROM @str; + EXECUTE stmt; +@@ -1100,17 +1100,17 @@ SET @had_group_allowlist = + (SELECT COUNT(table_name) FROM information_schema.tables + WHERE table_schema = 'mysql' AND table_name = 'firewall_group_allowlist' AND + table_type = 'BASE TABLE'); +-SET @cmd="CREATE TABLE IF NOT EXISTS mysql.firewall_group_allowlist(NAME VARCHAR(288) NOT NULL, RULE text NOT NULL, ID INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY) engine= InnoDB"; ++SET @cmd="CREATE TABLE IF NOT EXISTS mysql.firewall_group_allowlist(NAME VARCHAR(288) NOT NULL, RULE text NOT NULL, ID INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY) engine= CTC"; + SET @str = IF(@had_user_allowlist > 0 AND @had_group_allowlist = 0, @cmd, "SET @dummy = 0"); + PREPARE stmt FROM @str; + EXECUTE stmt; + DROP PREPARE stmt; +-SET @cmd="CREATE TABLE IF NOT EXISTS mysql.firewall_groups(NAME VARCHAR(288) PRIMARY KEY, MODE ENUM ('OFF', 'RECORDING', 'PROTECTING', 'DETECTING') DEFAULT 'OFF', USERHOST VARCHAR(288)) engine= InnoDB"; ++SET @cmd="CREATE TABLE IF NOT EXISTS mysql.firewall_groups(NAME VARCHAR(288) PRIMARY KEY, MODE ENUM ('OFF', 'RECORDING', 'PROTECTING', 'DETECTING') DEFAULT 'OFF', USERHOST VARCHAR(288)) engine= CTC"; + SET @str = IF(@had_user_allowlist > 0 AND @had_group_allowlist = 0, @cmd, "SET @dummy = 0"); + PREPARE stmt FROM @str; + EXECUTE stmt; + DROP PREPARE stmt; +-SET @cmd="CREATE TABLE IF NOT EXISTS mysql.firewall_membership(GROUP_ID VARCHAR(288), MEMBER_ID VARCHAR(288)) engine= InnoDB"; ++SET @cmd="CREATE TABLE IF NOT EXISTS mysql.firewall_membership(GROUP_ID VARCHAR(288), MEMBER_ID VARCHAR(288)) engine= CTC"; + SET @str = IF(@had_user_allowlist > 0 AND @had_group_allowlist = 0, @cmd, "SET @dummy = 0"); + PREPARE stmt FROM @str; + EXECUTE stmt; +@@ -1144,7 +1144,7 @@ SET @had_audit_log_filter = + (SELECT COUNT(table_name) FROM information_schema.tables + WHERE table_schema = 'mysql' AND table_name = 'audit_log_filter' AND + table_type = 'BASE TABLE'); +-SET @cmd="ALTER TABLE mysql.audit_log_filter ENGINE=InnoDB"; ++SET @cmd="ALTER TABLE mysql.audit_log_filter ENGINE=CTC"; + SET @str = IF(@had_audit_log_filter > 0, @cmd, "SET @dummy = 0"); + PREPARE stmt FROM @str; + EXECUTE stmt; +@@ -1160,7 +1160,7 @@ SET @had_audit_log_user = + (SELECT COUNT(table_name) FROM information_schema.tables + WHERE table_schema = 'mysql' AND table_name = 'audit_log_user' AND + table_type = 'BASE TABLE'); +-SET @cmd="ALTER TABLE mysql.audit_log_user ENGINE=InnoDB"; ++SET @cmd="ALTER TABLE mysql.audit_log_user ENGINE=CTC"; + SET @str = IF(@had_audit_log_user > 0, @cmd, "SET @dummy = 0"); + PREPARE stmt FROM @str; + EXECUTE stmt; +@@ -1266,7 +1266,7 @@ INSERT IGNORE INTO mysql.global_grants VALUES ('mysql.session', 'localhost', 'CO + # upgrade. + INSERT IGNORE INTO mysql.global_grants VALUES ('mysql.session', 'localhost', 'SYSTEM_USER', 'N'); + +-# Move all system tables with InnoDB storage engine to mysql tablespace. ++# Move all system tables with CTC storage engine to mysql tablespace. + SET @cmd="ALTER TABLE mysql.db TABLESPACE = mysql"; + PREPARE stmt FROM @cmd; + EXECUTE stmt; +diff --git a/scripts/sys_schema/functions/format_path.sql b/scripts/sys_schema/functions/format_path.sql +index 100fd59..41c8bf3 100644 +--- a/scripts/sys_schema/functions/format_path.sql ++++ b/scripts/sys_schema/functions/format_path.sql +@@ -92,10 +92,10 @@ BEGIN + SET v_path = REPLACE(v_path, @@global.tmpdir, CONCAT('@@tmpdir', IF(SUBSTRING(@@global.tmpdir, -1) = path_separator, path_separator, ''))); + ELSEIF v_path LIKE CONCAT(@@global.replica_load_tmpdir, IF(SUBSTRING(@@global.replica_load_tmpdir, -1) = path_separator, '%', CONCAT(path_separator, '%'))) ESCAPE '|' THEN + SET v_path = REPLACE(v_path, @@global.replica_load_tmpdir, CONCAT('@@replica_load_tmpdir', IF(SUBSTRING(@@global.replica_load_tmpdir, -1) = path_separator, path_separator, ''))); +- ELSEIF v_path LIKE CONCAT(@@global.innodb_data_home_dir, IF(SUBSTRING(@@global.innodb_data_home_dir, -1) = path_separator, '%', CONCAT(path_separator, '%'))) ESCAPE '|' THEN +- SET v_path = REPLACE(v_path, @@global.innodb_data_home_dir, CONCAT('@@innodb_data_home_dir', IF(SUBSTRING(@@global.innodb_data_home_dir, -1) = path_separator, path_separator, ''))); +- ELSEIF v_path LIKE CONCAT(@@global.innodb_log_group_home_dir, IF(SUBSTRING(@@global.innodb_log_group_home_dir, -1) = path_separator, '%', CONCAT(path_separator, '%'))) ESCAPE '|' THEN +- SET v_path = REPLACE(v_path, @@global.innodb_log_group_home_dir, CONCAT('@@innodb_log_group_home_dir', IF(SUBSTRING(@@global.innodb_log_group_home_dir, -1) = path_separator, path_separator, ''))); ++-- ELSEIF v_path LIKE CONCAT(@@global.innodb_data_home_dir, IF(SUBSTRING(@@global.innodb_data_home_dir, -1) = path_separator, '%', CONCAT(path_separator, '%'))) ESCAPE '|' THEN ++-- SET v_path = REPLACE(v_path, @@global.innodb_data_home_dir, CONCAT('@@innodb_data_home_dir', IF(SUBSTRING(@@global.innodb_data_home_dir, -1) = path_separator, path_separator, ''))); ++-- ELSEIF v_path LIKE CONCAT(@@global.innodb_log_group_home_dir, IF(SUBSTRING(@@global.innodb_log_group_home_dir, -1) = path_separator, '%', CONCAT(path_separator, '%'))) ESCAPE '|' THEN ++-- SET v_path = REPLACE(v_path, @@global.innodb_log_group_home_dir, CONCAT('@@innodb_log_group_home_dir', IF(SUBSTRING(@@global.innodb_log_group_home_dir, -1) = path_separator, path_separator, ''))); + ELSEIF v_path LIKE CONCAT(v_undo_dir, IF(SUBSTRING(v_undo_dir, -1) = path_separator, '%', CONCAT(path_separator, '%'))) ESCAPE '|' THEN + SET v_path = REPLACE(v_path, v_undo_dir, CONCAT('@@innodb_undo_directory', IF(SUBSTRING(v_undo_dir, -1) = path_separator, path_separator, ''))); + ELSEIF v_path LIKE CONCAT(@@global.basedir, IF(SUBSTRING(@@global.basedir, -1) = path_separator, '%', CONCAT(path_separator, '%'))) ESCAPE '|' THEN +diff --git a/scripts/sys_schema/procedures/diagnostics.sql b/scripts/sys_schema/procedures/diagnostics.sql +index 2f81086..75e61ef 100644 +--- a/scripts/sys_schema/procedures/diagnostics.sql ++++ b/scripts/sys_schema/procedures/diagnostics.sql +@@ -719,7 +719,7 @@ BEGIN + Type VARCHAR(225) NOT NULL, + Enabled ENUM(''YES'', ''NO'', ''PARTIAL'') NOT NULL, + PRIMARY KEY (Type, Variable_name) +-) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4')); ++) ENGINE = MyISAM DEFAULT CHARSET=utf8mb4')); + + SET @sys.diagnostics.sql = CONCAT( + 'INSERT INTO ', v_table_name, +diff --git a/scripts/sys_schema/procedures/statement_performance_analyzer.sql b/scripts/sys_schema/procedures/statement_performance_analyzer.sql +index d1726d5..0e2650a 100644 +--- a/scripts/sys_schema/procedures/statement_performance_analyzer.sql ++++ b/scripts/sys_schema/procedures/statement_performance_analyzer.sql +@@ -541,7 +541,7 @@ SELECT `d_end`.`SCHEMA_NAME`, + cnt bigint unsigned NOT NULL, + avg_us decimal(21,0) NOT NULL, + PRIMARY KEY (avg_us) +- ) ENGINE=InnoDB; ++ ) ENGINE=MyISAM; + + SET v_sql = CONCAT('INSERT INTO tmp_digest_avg_latency_distribution1 + SELECT COUNT(*) cnt, +@@ -557,7 +557,7 @@ SELECT COUNT(*) cnt, + avg_us decimal(21,0) NOT NULL, + percentile decimal(46,4) NOT NULL, + PRIMARY KEY (avg_us) +- ) ENGINE=InnoDB; ++ ) ENGINE=MyISAM; + + SET v_sql = CONCAT('INSERT INTO tmp_digest_95th_percentile_by_avg_us + SELECT s2.avg_us avg_us, +diff --git a/scripts/sys_schema/tables/sys_config.sql b/scripts/sys_schema/tables/sys_config.sql +index a4e48c5..459dc61 100644 +--- a/scripts/sys_schema/tables/sys_config.sql ++++ b/scripts/sys_schema/tables/sys_config.sql +@@ -24,4 +24,4 @@ CREATE TABLE IF NOT EXISTS sys_config ( + value VARCHAR(128), + set_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + set_by VARCHAR(128) +-) ENGINE = InnoDB; ++) ENGINE = CTC; diff --git a/mysql-test/mysql-source-code-meta.patch b/mysql-test/mysql-source-code-meta.patch new file mode 100644 index 0000000..bca8773 --- /dev/null +++ b/mysql-test/mysql-source-code-meta.patch @@ -0,0 +1,3501 @@ +diff --git a/sql/auth/acl_table_user.cc b/sql/auth/acl_table_user.cc +index f9846bd..fda3f0e 100644 +--- a/sql/auth/acl_table_user.cc ++++ b/sql/auth/acl_table_user.cc +@@ -1393,9 +1393,14 @@ void Acl_table_user_reader::read_account_name(ACL_USER &user) { + bool Acl_table_user_reader::read_authentication_string(ACL_USER &user) { + /* Read password from authentication_string field */ + if (m_table->s->fields > m_table_schema->authentication_string_idx()) { +- user.credentials[PRIMARY_CRED].m_auth_string.str = +- get_field(&m_mem_root, +- m_table->field[m_table_schema->authentication_string_idx()]); ++ if (m_table->field[m_table_schema->authentication_string_idx()]->is_null()) { ++ user.credentials[PRIMARY_CRED].m_auth_string.str = nullptr; ++ } ++ else { ++ user.credentials[PRIMARY_CRED].m_auth_string.str = ++ get_field(&m_mem_root, ++ m_table->field[m_table_schema->authentication_string_idx()]); ++ } + } else { + LogErr(ERROR_LEVEL, ER_AUTHCACHE_USER_TABLE_DODGY); + return true; +diff --git a/sql/auth/dynamic_privilege_table.cc b/sql/auth/dynamic_privilege_table.cc +index a4216d0..f8c4c1e 100644 +--- a/sql/auth/dynamic_privilege_table.cc ++++ b/sql/auth/dynamic_privilege_table.cc +@@ -228,7 +228,7 @@ bool modify_dynamic_privileges_in_table(THD *thd, TABLE *table, + /* If the key didn't exist the record is already gone and all is well. */ + return false; + } +- } else if (ret == HA_ERR_KEY_NOT_FOUND && !delete_option) { ++ } else if ((ret == HA_ERR_KEY_NOT_FOUND || ret == HA_ERR_END_OF_FILE) && !delete_option) { + /* Insert new edge into table */ + DBUG_PRINT("note", + ("Insert dynamic privilege %s for `%s`@`%s` %s", privilege.str, +diff --git a/sql/auth/sql_user_table.cc b/sql/auth/sql_user_table.cc +index 112d255..9c166bd 100644 +--- a/sql/auth/sql_user_table.cc ++++ b/sql/auth/sql_user_table.cc +@@ -1060,7 +1060,7 @@ int replace_proxies_priv_table(THD *thd, TABLE *table, const LEX_USER *user, + } + } else { + error = table->file->ha_write_row(table->record[0]); +- assert(error != HA_ERR_FOUND_DUPP_KEY); ++ //assert(error != HA_ERR_FOUND_DUPP_KEY); + assert(table->file->ht->db_type == DB_TYPE_NDBCLUSTER || + error != HA_ERR_LOCK_DEADLOCK); + assert(table->file->ht->db_type == DB_TYPE_NDBCLUSTER || +diff --git a/sql/bootstrap.cc b/sql/bootstrap.cc +index 785fa78..fb5be6f 100644 +--- a/sql/bootstrap.cc ++++ b/sql/bootstrap.cc +@@ -198,6 +198,7 @@ static int process_iterator(THD *thd, Command_iterator *it, + int rc; + + rc = it->next(query); ++ printf("query: %s\n", query.c_str()); + + if (rc == READ_BOOTSTRAP_EOF) { + break; +diff --git a/sql/composite_iterators.cc b/sql/composite_iterators.cc +index 43c59a1..4f6b8d4 100644 +--- a/sql/composite_iterators.cc ++++ b/sql/composite_iterators.cc +@@ -859,7 +859,9 @@ bool MaterializeIterator::MaterializeQueryBlock(const QueryBlock &query_block, + // so they'll need to reposition themselves. + for (const QueryBlock &query_b : m_query_blocks_to_materialize) { + if (query_b.is_recursive_reference) { +- query_b.recursive_reader->RepositionCursorAfterSpillToDisk(); ++ if (query_b.recursive_reader->RepositionCursorAfterSpillToDisk()) { ++ return true; ++ } + } + } + } else { +diff --git a/sql/dd/cache/dictionary_client.h b/sql/dd/cache/dictionary_client.h +index dbd6c18..4666753 100644 +--- a/sql/dd/cache/dictionary_client.h ++++ b/sql/dd/cache/dictionary_client.h +@@ -472,6 +472,9 @@ class Dictionary_client { + void remove_uncommitted_objects(bool commit_to_shared_cache); + + template ++ void add_modified_objects(); ++ ++ template + using Const_ptr_vec = std::vector; + + /** +@@ -1180,6 +1183,13 @@ class Dictionary_client { + @retval true There was an error. + */ + ++ /** ++ Refer to remove_uncommitted_objects(). Uncommitted objects has been added to invalidate list ++ before commit. Only drop cache and remove element from committed registry included. ++ */ ++ template ++ void invalidate_after_commit(const T *object); ++ + template + bool drop(const T *object) MY_ATTRIBUTE((warn_unused_result)); + +@@ -1261,6 +1271,7 @@ class Dictionary_client { + */ + + void commit_modified_objects(); ++ void add_modified_objects_before_commit(); + + /** + Remove table statistics entries from mysql.table_stats and +diff --git a/sql/dd/dd_table.cc b/sql/dd/dd_table.cc +index 7bf60f4..7be1743 100644 +--- a/sql/dd/dd_table.cc ++++ b/sql/dd/dd_table.cc +@@ -2322,7 +2322,7 @@ static std::unique_ptr create_dd_system_table( + } + + // Register the se private id with the DDSE. +- handlerton *ddse = ha_resolve_by_legacy_type(thd, DB_TYPE_INNODB); ++ handlerton *ddse = ha_resolve_by_legacy_type(thd, DB_TYPE_CTC); + if (ddse->dict_register_dd_table_id == nullptr) return nullptr; + ddse->dict_register_dd_table_id(tab_obj->se_private_id()); + +diff --git a/sql/dd/dd_tablespace.cc b/sql/dd/dd_tablespace.cc +index 2c97cb3..0d5b05b 100644 +--- a/sql/dd/dd_tablespace.cc ++++ b/sql/dd/dd_tablespace.cc +@@ -53,6 +53,7 @@ + #include "sql/sql_servers.h" + #include "sql/sql_table.h" // validate_comment_length + #include "sql/table.h" ++#include + + namespace { + template +@@ -154,7 +155,6 @@ bool get_tablespace_name(THD *thd, const T *obj, String_type *name) { + // Read Tablespace + // + assert(name->empty()); +- + if (obj->tablespace_id() == Dictionary_impl::dd_tablespace_id()) { + // If this is the DD tablespace id, then we use its name. + *name = MYSQL_TABLESPACE_NAME.str; +diff --git a/sql/dd/dd_utility.cc b/sql/dd/dd_utility.cc +index 7f9b9df..1d5575d 100644 +--- a/sql/dd/dd_utility.cc ++++ b/sql/dd/dd_utility.cc +@@ -62,7 +62,7 @@ bool check_if_server_ddse_readonly(THD *thd, const char *schema_name_abbrev) { + to retrieve the handlerton for the DDSE should be replaced by a more + generic mechanism. + */ +- handlerton *ddse = ha_resolve_by_legacy_type(thd, DB_TYPE_INNODB); ++ handlerton *ddse = ha_resolve_by_legacy_type(thd, DB_TYPE_CTC); + if (ddse->is_dict_readonly && ddse->is_dict_readonly()) { + LogErr(WARNING_LEVEL, ER_SKIP_UPDATING_METADATA_IN_SE_RO_MODE, + schema_name_abbrev); +diff --git a/sql/dd/impl/bootstrap/bootstrapper.cc b/sql/dd/impl/bootstrap/bootstrapper.cc +index d08718a..6440b0b 100644 +--- a/sql/dd/impl/bootstrap/bootstrapper.cc ++++ b/sql/dd/impl/bootstrap/bootstrapper.cc +@@ -81,7 +81,7 @@ namespace { + // Initialize recovery in the DDSE. + bool DDSE_dict_recover(THD *thd, dict_recovery_mode_t dict_recovery_mode, + uint version) { +- handlerton *ddse = ha_resolve_by_legacy_type(thd, DB_TYPE_INNODB); ++ handlerton *ddse = ha_resolve_by_legacy_type(thd, DB_TYPE_CTC); + if (ddse->dict_recover == nullptr) return true; + + bool error = ddse->dict_recover(dict_recovery_mode, version); +@@ -266,6 +266,9 @@ bool acquire_exclusive_mdl(THD *thd) { + reset ID, store persistently, and update the storage adapter. + */ + bool flush_meta_data(THD *thd) { ++ // Turn off FK checks, this is needed since we have cyclic FKs. ++ if (dd::execute_query(thd, "SET FOREIGN_KEY_CHECKS= 0")) return true; ++ + // Acquire exclusive meta data locks for the relevant DD objects. + if (acquire_exclusive_mdl(thd)) return true; + +@@ -573,6 +576,9 @@ bool flush_meta_data(THD *thd) { + if (persisted_dd_table != nullptr) delete persisted_dd_table; + } + ++ // Turn FK checks back on. ++ if (dd::execute_query(thd, "SET FOREIGN_KEY_CHECKS= 1")) return true; ++ + bootstrap::DD_bootstrap_ctx::instance().set_stage(bootstrap::Stage::SYNCED); + + return dd::end_transaction(thd, false); +@@ -580,6 +586,8 @@ bool flush_meta_data(THD *thd) { + + // Insert additional data into the DD tables. + bool populate_tables(THD *thd) { ++ // Turn off FK checks, this is needed since we have cyclic FKs. ++ if (dd::execute_query(thd, "SET FOREIGN_KEY_CHECKS= 0")) return true; + // Iterate over DD tables, populate tables. + for (System_tables::Const_iterator it = System_tables::instance()->begin(); + it != System_tables::instance()->end(); ++it) { +@@ -610,6 +618,9 @@ bool populate_tables(THD *thd) { + bootstrap::DD_bootstrap_ctx::instance().set_stage( + bootstrap::Stage::POPULATED); + ++ // Turn FK checks back on. ++ if (dd::execute_query(thd, "SET FOREIGN_KEY_CHECKS= 1")) return true; ++ + return false; + } + +@@ -621,7 +632,7 @@ bool repopulate_charsets_and_collations(THD *thd) { + to retrieve the handlerton for the DDSE should be replaced by a more + generic mechanism. + */ +- handlerton *ddse = ha_resolve_by_legacy_type(thd, DB_TYPE_INNODB); ++ handlerton *ddse = ha_resolve_by_legacy_type(thd, DB_TYPE_CTC); + if (ddse->is_dict_readonly && ddse->is_dict_readonly()) { + LogErr(WARNING_LEVEL, ER_DD_NO_WRITES_NO_REPOPULATION, "InnoDB", " "); + return false; +@@ -724,7 +735,7 @@ namespace bootstrap { + predefined tables and tablespaces. + */ + bool DDSE_dict_init(THD *thd, dict_init_mode_t dict_init_mode, uint version) { +- handlerton *ddse = ha_resolve_by_legacy_type(thd, DB_TYPE_INNODB); ++ handlerton *ddse = ha_resolve_by_legacy_type(thd, DB_TYPE_CTC); + + /* + The lists with element wrappers are mem root allocated. The wrapped +@@ -908,6 +919,10 @@ bool initialize(THD *thd) { + + // Normal server restart. + bool restart(THD *thd) { ++ handlerton *ddse = ha_resolve_by_legacy_type(thd, DB_TYPE_CTC); ++ if (ddse->op_before_load_meta(thd) != 0) { ++ return true; ++ } + bootstrap::DD_bootstrap_ctx::instance().set_stage(bootstrap::Stage::STARTED); + + /* +@@ -946,7 +961,9 @@ bool restart(THD *thd) { + dd::execute_query(thd, "DROP SCHEMA schema_read_only") || + dd::execute_query(thd, "CREATE TABLE IF NOT EXISTS S.restart(i INT)")) + assert(false);); +- ++ if (ddse->op_after_load_meta(thd) != 0) { ++ return true; ++ } + bootstrap::DD_bootstrap_ctx::instance().set_stage(bootstrap::Stage::FINISHED); + LogErr(INFORMATION_LEVEL, ER_DD_VERSION_FOUND, d->get_actual_dd_version(thd)); + +@@ -1502,7 +1519,7 @@ bool sync_meta_data(THD *thd) { + return true; + + // Reset the DDSE local dictionary cache. +- handlerton *ddse = ha_resolve_by_legacy_type(thd, DB_TYPE_INNODB); ++ handlerton *ddse = ha_resolve_by_legacy_type(thd, DB_TYPE_CTC); + if (ddse->dict_cache_reset == nullptr) return true; + + for (System_tables::Const_iterator it = System_tables::instance()->begin(); +@@ -1797,7 +1814,7 @@ bool update_versions(THD *thd, bool is_dd_upgrade_57) { + back in case of an abort, so this better be the last step we + do before committing. + */ +- handlerton *ddse = ha_resolve_by_legacy_type(thd, DB_TYPE_INNODB); ++ handlerton *ddse = ha_resolve_by_legacy_type(thd, DB_TYPE_CTC); + if (bootstrap::DD_bootstrap_ctx::instance().is_server_upgrade()) { + if (ddse->dict_set_server_version == nullptr || + ddse->dict_set_server_version()) { +diff --git a/sql/dd/impl/cache/dictionary_client.cc b/sql/dd/impl/cache/dictionary_client.cc +index 8063806..c649fa5 100644 +--- a/sql/dd/impl/cache/dictionary_client.cc ++++ b/sql/dd/impl/cache/dictionary_client.cc +@@ -93,6 +93,7 @@ + #include "sql/mdl.h" + #include "sql/mysqld.h" + #include "sql/sql_class.h" // THD ++#include "sql/sql_lex.h" // LEX + #include "sql/sql_plugin_ref.h" + #include "sql/table.h" + #include "sql/tztime.h" // Time_zone, my_tz_OFFSET0 +@@ -359,6 +360,130 @@ class MDL_checker { + } + + public: ++ static void add_to_invalidate(THD *thd, const dd::Abstract_table *table) ++ { ++ dd::cache::Dictionary_client::Auto_releaser releaser(thd->dd_client()); ++ const dd::Schema *schema = nullptr; ++ ++ // If the schema acquisition fails, we cannot assure that we have a lock, ++ // and therefore return false. ++ if (thd->dd_client()->acquire(table->schema_id(), &schema)) return; ++ ++ // Skip check for temporary tables. ++ if (!table || is_prefix(table->name().c_str(), tmp_file_prefix)) ++ return; ++ ++ // Likewise, if there is no schema, we cannot have a proper lock. ++ // This may in theory happen during bootstrapping since the meta data for ++ // the system schema is not stored yet; however, this is prevented by ++ // surrounding code calling this function only if ++ // '!thd->is_dd_system_thread' i.e., this is not a bootstrapping thread. ++ if (thd->is_dd_system_thread() || !schema) { ++ return; ++ } ++ ++ // We must take l_c_t_n into account when reconstructing the MDL key ++ // from the schema and table name, and we need buffers for this purpose. ++ //char table_name_buf[NAME_LEN + 1]; ++ char schema_name_buf[NAME_LEN + 1]; ++ ++ const char *table_name = table->name().c_str(); ++ const char *schema_name = dd::Object_table_definition_impl::fs_name_case( ++ schema->name(), schema_name_buf); ++ ++ thd->add(schema_name, table_name, THD::OBJ_ABSTRACT_TABLE); ++ return; ++ } ++ ++ static void add_to_invalidate(THD *thd, const dd::Schema *schema) ++ { ++ if (thd->is_dd_system_thread() || !schema) { ++ return; ++ } ++ ++ char name_buf[NAME_LEN + 1]; ++ ++ const char *schema_name = dd::Object_table_definition_impl::fs_name_case(schema->name(), ++ name_buf); ++ thd->add(schema_name, "", THD::OBJ_SCHEMA); ++ ++ return; ++ } ++ ++ static void add_to_invalidate(THD *thd, const dd::Charset *charset) ++ { ++ (void(thd)); ++ (void(charset)); ++ return; ++ } ++ ++ static void add_to_invalidate(THD *thd, const dd::Collation *collation) ++ { ++ (void(thd)); ++ (void(collation)); ++ return; ++ } ++ ++ static void add_to_invalidate(THD *thd, const dd::Event *event) ++ { ++ (void(thd)); ++ (void(event)); ++ return; ++ } ++ ++ static void add_to_invalidate(THD *thd, const dd::Routine *routine) ++ { ++ dd::cache::Dictionary_client::Auto_releaser releaser(thd->dd_client()); ++ const dd::Schema *schema = nullptr; ++ ++ // If the schema acquisition fails, we cannot assure that we have a lock, ++ // and therefore return false. ++ if (thd->dd_client()->acquire(routine->schema_id(), &schema)) return; ++ ++ assert(schema); ++ ++ MDL_key mdl_key; ++ char schema_name_buf[NAME_LEN + 1]; ++ const char *schema_name = dd::Object_table_definition_impl::fs_name_case( ++ schema->name(), schema_name_buf); ++ const char *routine_name = routine->name().c_str(); ++ if (routine->type() == dd::Routine::RT_PROCEDURE) { ++ thd->add(schema_name, routine_name, THD::OBJ_RT_PROCEDURE); ++ } else { ++ thd->add(schema_name, routine_name, THD::OBJ_RT_FUNCTION); ++ } ++ return; ++ } ++ ++ static void add_to_invalidate(THD *thd, const dd::Resource_group *resource_group) ++ { ++ (void(thd)); ++ (void(resource_group)); ++ return; ++ } ++ ++ static void add_to_invalidate(THD *thd, const dd::Spatial_reference_system *srs) ++ { ++ (void(thd)); ++ (void(srs)); ++ return; ++ } ++ ++ static void add_to_invalidate(THD *thd, const dd::Tablespace *tablespace) ++ { ++ if (!tablespace) return; ++ ++ thd->add(tablespace->name().c_str(), "", THD::OBJ_TABLESPACE); ++ return; ++ } ++ ++ static void add_to_invalidate(THD *thd, const dd::Column_statistics *column_statistics) ++ { ++ (void(thd)); ++ (void(column_statistics)); ++ return; ++ } ++ + // Releasing arbitrary dictionary objects is not checked. + static bool is_release_locked(THD *, const dd::Entity_object *) { + return true; +@@ -2423,6 +2548,7 @@ bool Dictionary_client::invalidate(const String_type &schema_name, + + Auto_releaser releaser(this); + const Table *table; ++ // If target object is a View, table will be nullptr + if (acquire(schema_name, table_name, &table)) { + assert(m_thd->is_system_thread() || m_thd->killed || m_thd->is_error()); + return true; +@@ -2430,6 +2556,18 @@ bool Dictionary_client::invalidate(const String_type &schema_name, + + if (table != nullptr) { + invalidate(table); ++ return false; ++ } ++ ++ // If aquire table failed(refer to Dictionary_client::acquire()), try aquire view instead. ++ const View *view; ++ if (acquire(schema_name, table_name, &view)) { ++ assert(m_thd->is_system_thread() || m_thd->killed || m_thd->is_error()); ++ return true; ++ } ++ if (view != nullptr) { ++ invalidate(view); ++ return false; + } + + // Invalidation of a non-existing object is not treated as an error. +@@ -2458,16 +2596,44 @@ void Dictionary_client::invalidate(const T *object) { + m_registry_committed.get(id_key, &element); + + if (element) { ++ if (m_thd->query().str && std::string(m_thd->query().str) == "tse_mdl_thd_notify") { ++ } else { ++ MDL_checker::add_to_invalidate(m_thd, element->object()); ++ } ++ + // Remove the element from the chain of auto releasers. + (void)m_current_releaser->remove(element); + // Remove the element from the local registry. + m_registry_committed.remove(element); + // Remove the element from the cache, delete the wrapper and the object. + Shared_dictionary_cache::instance()->drop(element); +- } else ++ } else { + Shared_dictionary_cache::instance() + ->drop_if_present( + id_key); ++ } ++} ++ ++// Refer to remove_uncommitted_objects(). Uncommitted objects has been added to invalidate list before commit. ++template ++void Dictionary_client::invalidate_after_commit(const T *object) { ++ assert(MDL_checker::is_write_locked(m_thd, object)); ++ Cache_element *element = nullptr; ++ const typename T::Id_key id_key(object->id()); ++ m_registry_committed.get(id_key, &element); ++ ++ if (element) { ++ // Remove the element from the chain of auto releasers. ++ (void)m_current_releaser->remove(element); ++ // Remove the element from the local registry. ++ m_registry_committed.remove(element); ++ // Remove the element from the cache, delete the wrapper and the object. ++ Shared_dictionary_cache::instance()->drop(element); ++ } else { ++ Shared_dictionary_cache::instance() ++ ->drop_if_present( ++ id_key); ++ } + } + + #ifndef NDEBUG +@@ -2845,7 +3011,7 @@ void Dictionary_client::remove_uncommitted_objects( + dd::cache::Storage_adapter::instance()->core_update(it->second->object()); + + // Invalidate the entry in the shared cache (if present). +- invalidate(uncommitted_object); ++ invalidate_after_commit(uncommitted_object); + + #ifndef NDEBUG + // Make sure the uncommitted id is not present in the dropped registry. +@@ -2919,6 +3085,45 @@ void Dictionary_client::commit_modified_objects() { + remove_uncommitted_objects(true); + } + ++template ++void Dictionary_client::add_modified_objects() { ++#ifndef NDEBUG ++#endif ++ typename Multi_map_base::Const_iterator it; ++ for (it = m_registry_uncommitted.begin(); ++ it != m_registry_uncommitted.end(); ++ it++) { ++ typename T::Cache_partition *uncommitted_object = ++ const_cast(it->second->object()); ++ ++ // Invalidate the entry in the shared cache (if present). ++ Cache_element *element = nullptr; ++ const typename T::Id_key id_key(uncommitted_object->id()); ++ m_registry_committed.get(id_key, &element); ++ if (element) { ++ MDL_checker::add_to_invalidate(m_thd, element->object()); ++ } else if (m_thd->lex->sql_command == SQLCOM_CREATE_TRIGGER) { ++ MDL_checker::add_to_invalidate(m_thd, uncommitted_object); ++ } ++ } ++} ++ ++void Dictionary_client::add_modified_objects_before_commit() { ++ if (m_thd->query().str && std::string(m_thd->query().str) == "tse_mdl_thd_notify") { ++ return; ++ } ++ add_modified_objects(); ++ add_modified_objects(); ++ add_modified_objects(); ++ add_modified_objects(); ++ add_modified_objects(); ++ add_modified_objects(); ++ add_modified_objects(); ++ add_modified_objects(); ++ add_modified_objects(); ++ add_modified_objects(); ++} ++ + // Debug dump of the client and its registry to stderr. + /* purecov: begin inspected */ + template +@@ -3028,6 +3233,7 @@ template bool Dictionary_client::acquire_for_modification(const String_type &, + Abstract_table **); + template void Dictionary_client::remove_uncommitted_objects( + bool); ++template void Dictionary_client::add_modified_objects(); + template bool Dictionary_client::drop(const Abstract_table *); + template bool Dictionary_client::store(Abstract_table *); + template bool Dictionary_client::update(Abstract_table *); +@@ -3037,6 +3243,7 @@ template bool Dictionary_client::acquire(Object_id, dd::Charset const **); + template bool Dictionary_client::acquire_for_modification(Object_id, + dd::Charset **); + template void Dictionary_client::remove_uncommitted_objects(bool); ++template void Dictionary_client::add_modified_objects(); + template bool Dictionary_client::acquire(String_type const &, Charset const **); + template bool Dictionary_client::acquire(String_type const &, Schema const **); + template bool Dictionary_client::acquire_for_modification(String_type const &, +@@ -3052,6 +3259,7 @@ template bool Dictionary_client::acquire(Object_id, dd::Collation const **); + template bool Dictionary_client::acquire_for_modification(Object_id, + dd::Collation **); + template void Dictionary_client::remove_uncommitted_objects(bool); ++template void Dictionary_client::add_modified_objects(); + template bool Dictionary_client::acquire_uncached(Object_id, Collation **); + template bool Dictionary_client::acquire(const String_type &, + const Collation **); +@@ -3072,6 +3280,7 @@ template bool Dictionary_client::acquire_uncached_uncommitted( + template bool Dictionary_client::acquire_for_modification(const String_type &, + Schema **); + template void Dictionary_client::remove_uncommitted_objects(bool); ++template void Dictionary_client::add_modified_objects(); + + template bool Dictionary_client::drop(const Schema *); + template bool Dictionary_client::store(Schema *); +@@ -3112,6 +3321,7 @@ template bool Dictionary_client::acquire_for_modification(const String_type &, + const String_type &, + Table **); + template void Dictionary_client::remove_uncommitted_objects(bool); ++template void Dictionary_client::add_modified_objects
(); + template bool Dictionary_client::drop(const Table *); + template bool Dictionary_client::store(Table *); + template bool Dictionary_client::update(Table *); +@@ -3131,6 +3341,7 @@ template bool Dictionary_client::acquire_uncached_uncommitted( + template bool Dictionary_client::acquire_for_modification(Object_id, + Tablespace **); + template void Dictionary_client::remove_uncommitted_objects(bool); ++template void Dictionary_client::add_modified_objects(); + template bool Dictionary_client::drop(const Tablespace *); + template bool Dictionary_client::store(Tablespace *); + template bool Dictionary_client::update(Tablespace *); +@@ -3149,6 +3360,7 @@ template bool Dictionary_client::acquire_for_modification(const String_type &, + const String_type &, + View **); + template void Dictionary_client::remove_uncommitted_objects(bool); ++template void Dictionary_client::add_modified_objects(); + template bool Dictionary_client::drop(const View *); + template bool Dictionary_client::store(View *); + template bool Dictionary_client::update(View *); +@@ -3159,6 +3371,7 @@ template bool Dictionary_client::acquire_uncached(Object_id, Event **); + template bool Dictionary_client::acquire(Object_id, const Event **); + template bool Dictionary_client::acquire_for_modification(Object_id, Event **); + template void Dictionary_client::remove_uncommitted_objects(bool); ++template void Dictionary_client::add_modified_objects(); + template bool Dictionary_client::acquire(const String_type &, + const String_type &, const Event **); + template bool Dictionary_client::acquire_for_modification(const String_type &, +@@ -3184,6 +3397,7 @@ template bool Dictionary_client::acquire(Object_id, const Procedure **); + template bool Dictionary_client::acquire_for_modification(Object_id, + Procedure **); + template void Dictionary_client::remove_uncommitted_objects(bool); ++template void Dictionary_client::add_modified_objects(); + template bool Dictionary_client::acquire(const String_type &, + const String_type &, + const Procedure **); +@@ -3196,6 +3410,7 @@ template bool Dictionary_client::update(Procedure *); + + template bool Dictionary_client::drop(const Routine *); + template void Dictionary_client::remove_uncommitted_objects(bool); ++template void Dictionary_client::add_modified_objects(); + template bool Dictionary_client::update(Routine *); + template bool Dictionary_client::is_user_definer(const LEX_USER &, + bool *) const; +@@ -3222,6 +3437,7 @@ template bool Dictionary_client::drop(const Resource_group *); + template bool Dictionary_client::store(Resource_group *); + template void Dictionary_client::remove_uncommitted_objects( + bool); ++template void Dictionary_client::add_modified_objects(); + template bool Dictionary_client::update(Resource_group *); + /** + @endcond +diff --git a/sql/dd/impl/dictionary_impl.cc b/sql/dd/impl/dictionary_impl.cc +index 7115491..790403f 100644 +--- a/sql/dd/impl/dictionary_impl.cc ++++ b/sql/dd/impl/dictionary_impl.cc +@@ -693,7 +693,7 @@ bool drop_native_table(THD *thd, const char *schema_name, + + bool reset_tables_and_tablespaces() { + Auto_THD thd; +- handlerton *ddse = ha_resolve_by_legacy_type(thd.thd, DB_TYPE_INNODB); ++ handlerton *ddse = ha_resolve_by_legacy_type(thd.thd, DB_TYPE_CTC); + + // Acquire transactional metadata locks and evict all cached objects. + if (dd::cache::Shared_dictionary_cache::reset_tables_and_tablespaces(thd.thd)) +diff --git a/sql/dd/impl/sdi.cc b/sql/dd/impl/sdi.cc +index ef5b920..276a34f 100644 +--- a/sql/dd/impl/sdi.cc ++++ b/sql/dd/impl/sdi.cc +@@ -608,6 +608,7 @@ bool store(THD *thd, const Table *tp) { + const Table &t = ptr_as_cref(tp); + handlerton *hton = resolve_hton(thd, t); + ++ return false; + return with_schema(thd, t.schema_id(), [&](const Schema &s) { + dd::Sdi_type sdi = serialize(thd, t, s.name()); + if (sdi.empty()) { +@@ -626,6 +627,8 @@ bool store(THD *thd, const Table *tp) { + + bool store(THD *thd, const Tablespace *ts) { + handlerton *hton = resolve_hton(thd, *ts); ++ ++ return false; + if (hton->sdi_set == nullptr) { + return false; // SDI api not supported + } +diff --git a/sql/dd/impl/tables/table_partitions.cc b/sql/dd/impl/tables/table_partitions.cc +index da7a46e..1555449 100644 +--- a/sql/dd/impl/tables/table_partitions.cc ++++ b/sql/dd/impl/tables/table_partitions.cc +@@ -88,7 +88,7 @@ Table_partitions::Table_partitions() { + "UNIQUE KEY(table_id, parent_partition_id, number)"); + m_target_def.add_index(INDEX_UK_ENGINE_SE_PRIVATE_ID, + "INDEX_UK_ENGINE_SE_PRIVATE_ID", +- "UNIQUE KEY(engine, se_private_id)"); ++ "KEY(engine, se_private_id)"); + m_target_def.add_index(INDEX_K_ENGINE, "INDEX_K_ENGINE", "KEY(engine)"); + m_target_def.add_index(INDEX_K_TABLESPACE_ID, "INDEX_K_TABLESPACE_ID", + "KEY(tablespace_id)"); +diff --git a/sql/dd/impl/tables/tables.cc b/sql/dd/impl/tables/tables.cc +index 77372a2..4ea7850 100644 +--- a/sql/dd/impl/tables/tables.cc ++++ b/sql/dd/impl/tables/tables.cc +@@ -168,7 +168,8 @@ Tables::Tables() { + "UNIQUE KEY (schema_id, name)"); + m_target_def.add_index(INDEX_UK_ENGINE_SE_PRIVATE_ID, + "INDEX_UK_ENGINE_SE_PRIVATE_ID", +- "UNIQUE KEY (engine, se_private_id)"); ++ // "UNIQUE KEY (engine, se_private_id)"); ++ "KEY (engine, se_private_id)"); + m_target_def.add_index(INDEX_K_ENGINE, "INDEX_K_ENGINE", "KEY(engine)"); + m_target_def.add_index(INDEX_K_COLLATION_ID, "INDEX_K_COLLATION_ID", + "KEY(collation_id)"); +diff --git a/sql/dd/impl/transaction_impl.h b/sql/dd/impl/transaction_impl.h +index f21b82a..86f9e59 100644 +--- a/sql/dd/impl/transaction_impl.h ++++ b/sql/dd/impl/transaction_impl.h +@@ -133,9 +133,13 @@ class Transaction_ro { + : otx(thd, TL_READ), m_thd(thd), m_kill_immunizer(thd) { + thd->begin_attachable_ro_transaction(); + thd->tx_isolation = isolation; ++ thd->is_reading_dd = true; + } + +- ~Transaction_ro() { m_thd->end_attachable_transaction(); } ++ ~Transaction_ro() { ++ m_thd->is_reading_dd = false; ++ m_thd->end_attachable_transaction(); ++ } + + Open_dictionary_tables_ctx otx; + +diff --git a/sql/dd/impl/types/object_table_impl.cc b/sql/dd/impl/types/object_table_impl.cc +index 4b2b7ba..fde262d 100644 +--- a/sql/dd/impl/types/object_table_impl.cc ++++ b/sql/dd/impl/types/object_table_impl.cc +@@ -37,7 +37,7 @@ Object_table_impl::Object_table_impl() + m_actual_def(), + m_hidden(true) { + m_target_def.add_option(static_cast(Common_option::ENGINE), "ENGINE", +- "ENGINE=INNODB"); ++ "ENGINE=CTC"); + m_target_def.add_option(static_cast(Common_option::CHARSET), "CHARSET", + "DEFAULT CHARSET=utf8"); + m_target_def.add_option(static_cast(Common_option::COLLATION), +diff --git a/sql/dd/impl/types/tablespace_impl.cc b/sql/dd/impl/types/tablespace_impl.cc +index 8880468..9cd1727 100644 +--- a/sql/dd/impl/types/tablespace_impl.cc ++++ b/sql/dd/impl/types/tablespace_impl.cc +@@ -179,14 +179,14 @@ bool Tablespace_impl::restore_attributes(const Raw_record &r) { + + bool Tablespace_impl::store_attributes(Raw_record *r) { + #ifndef NDEBUG +- if (my_strcasecmp(system_charset_info, "InnoDB", m_engine.c_str()) == 0) { +- /* Innodb can request for space rename during upgrade when options are not +- upgraded yet. */ +- assert(m_options.exists("encryption") || +- bootstrap::DD_bootstrap_ctx::instance().is_dd_upgrade()); +- } else { +- assert(!m_options.exists("encryption")); +- } ++ //if (my_strcasecmp(system_charset_info, "CTC", m_engine.c_str()) == 0) { ++ // /* Innodb can request for space rename during upgrade when options are not ++ // upgraded yet. */ ++ // assert(m_options.exists("encryption") || ++ // bootstrap::DD_bootstrap_ctx::instance().is_dd_upgrade()); ++ //} else { ++ // assert(!m_options.exists("encryption")); ++ //} + #endif + + // Store engine_attributes and secondary_engine_attributes only if +diff --git a/sql/dd/impl/upgrade/dd.cc b/sql/dd/impl/upgrade/dd.cc +index 065400f..da58b04 100644 +--- a/sql/dd/impl/upgrade/dd.cc ++++ b/sql/dd/impl/upgrade/dd.cc +@@ -1155,7 +1155,7 @@ bool upgrade_tables(THD *thd) { + Object_table_definition_impl::set_dd_tablespace_encrypted(false); + + // Reset the DDSE local dictionary cache. +- handlerton *ddse = ha_resolve_by_legacy_type(thd, DB_TYPE_INNODB); ++ handlerton *ddse = ha_resolve_by_legacy_type(thd, DB_TYPE_CTC); + if (ddse->dict_cache_reset == nullptr) return true; + + for (System_tables::Const_iterator it = +diff --git a/sql/dd/impl/upgrade/server.cc b/sql/dd/impl/upgrade/server.cc +index 1e3ce91..4812569 100644 +--- a/sql/dd/impl/upgrade/server.cc ++++ b/sql/dd/impl/upgrade/server.cc +@@ -518,12 +518,12 @@ static void create_upgrade_file() { + + static bool get_shared_tablespace_names( + THD *thd, std::set *shared_spaces) { +- assert(innodb_hton != nullptr && innodb_hton->get_tablespace_type); ++ assert(tse_hton != nullptr && tse_hton->get_tablespace_type); + auto process_spaces = [&](std::unique_ptr &space) { +- if (my_strcasecmp(system_charset_info, space->engine().c_str(), "InnoDB")) ++ if (my_strcasecmp(system_charset_info, space->engine().c_str(), "CTC")) + return false; + Tablespace_type space_type; +- if (innodb_hton->get_tablespace_type(*space, &space_type)) { ++ if (tse_hton->get_tablespace_type(*space, &space_type)) { + LogErr(ERROR_LEVEL, ER_UNKNOWN_TABLESPACE_TYPE, space->name().c_str()); + return true; + } +diff --git a/sql/dd/info_schema/metadata.cc b/sql/dd/info_schema/metadata.cc +index 4c9a38f..3f1488b 100644 +--- a/sql/dd/info_schema/metadata.cc ++++ b/sql/dd/info_schema/metadata.cc +@@ -629,7 +629,19 @@ bool store_server_I_S_metadata(THD *thd) { + + // Update server and plugin I_S table metadata on server restart. + bool update_I_S_metadata(THD *thd) { +- return update_server_I_S_metadata(thd) || update_plugins_I_S_metadata(thd); ++ handlerton *ddse = ha_resolve_by_legacy_type(thd, DB_TYPE_CTC); ++ if (!opt_initialize && !mysqld_server_started) { ++ if (ddse->op_before_load_meta(thd) != 0) { ++ return true; ++ } ++ } ++ bool error = update_server_I_S_metadata(thd) || update_plugins_I_S_metadata(thd); ++ if (!opt_initialize && !mysqld_server_started) { ++ if (ddse->op_after_load_meta(thd) != 0) { ++ return true; ++ } ++ } ++ return error; + } + + /* +diff --git a/sql/dd/info_schema/table_stats.cc b/sql/dd/info_schema/table_stats.cc +index cc1041d..b69b7b7 100644 +--- a/sql/dd/info_schema/table_stats.cc ++++ b/sql/dd/info_schema/table_stats.cc +@@ -69,7 +69,7 @@ namespace { + inline bool can_persist_I_S_dynamic_statistics(THD *thd, + const char *schema_name, + const char *partition_name) { +- handlerton *ddse = ha_resolve_by_legacy_type(thd, DB_TYPE_INNODB); ++ handlerton *ddse = ha_resolve_by_legacy_type(thd, DB_TYPE_CTC); + if (ddse == nullptr || ddse->is_dict_readonly()) return false; + + return (thd->variables.information_schema_stats_expiry && +diff --git a/sql/dd/upgrade_57/upgrade.cc b/sql/dd/upgrade_57/upgrade.cc +index ebda371..6310acc 100644 +--- a/sql/dd/upgrade_57/upgrade.cc ++++ b/sql/dd/upgrade_57/upgrade.cc +@@ -845,12 +845,13 @@ bool do_pre_checks_and_initialize_dd(THD *thd) { + bool not_used; + build_table_filename(path, sizeof(path) - 1, "", "mysql", ".ibd", 0, + ¬_used); +- bool exists_mysql_tablespace = (!my_access(path, F_OK)); ++ // bool exists_mysql_tablespace = (!my_access(path, F_OK)); ++ bool exists_mysql_tablespace = true; + + // Check existence of mysql/plugin.frm +- build_table_filename(path, sizeof(path) - 1, "mysql", "plugin", ".frm", 0, +- ¬_used); +- bool exists_plugin_frm = (!my_access(path, F_OK)); ++ //build_table_filename(path, sizeof(path) - 1, "mysql", "plugin", ".frm", 0, ++ // ¬_used); ++ //bool exists_plugin_frm = (!my_access(path, F_OK)); + + /* + If mysql.ibd and mysql/plugin.frm do not exist, +@@ -859,10 +860,10 @@ bool do_pre_checks_and_initialize_dd(THD *thd) { + Server restart is not possible without mysql.ibd. + Exit with an error. + */ +- if (!exists_mysql_tablespace && !exists_plugin_frm) { +- LogErr(ERROR_LEVEL, ER_DD_UPGRADE_FAILED_FIND_VALID_DATA_DIR); +- return true; +- } ++ // if (!exists_mysql_tablespace && !exists_plugin_frm) { ++ // LogErr(ERROR_LEVEL, ER_DD_UPGRADE_FAILED_FIND_VALID_DATA_DIR); ++ // return true; ++ // } + + // Read stage of upgrade from the file. + Upgrade_status upgrade_status; +diff --git a/sql/handler.cc b/sql/handler.cc +index 217a0c1..fe900eb 100644 +--- a/sql/handler.cc ++++ b/sql/handler.cc +@@ -769,11 +769,13 @@ int ha_initialize_handlerton(st_plugin_int *plugin) { + hton->slot = HA_SLOT_UNDEF; + /* Historical Requirement */ + plugin->data = hton; // shortcut for the future +- if (plugin->plugin->init && plugin->plugin->init(hton)) { +- LogErr(ERROR_LEVEL, ER_PLUGIN_INIT_FAILED, plugin->name.str); +- goto err; ++ { ++ if (plugin->plugin->init && plugin->plugin->init(hton)) { ++ LogErr(ERROR_LEVEL, ER_PLUGIN_INIT_FAILED, plugin->name.str); ++ goto err; ++ } + } +- ++ + /* + the switch below and hton->state should be removed when + command-line options for plugins will be implemented +@@ -852,6 +854,9 @@ int ha_initialize_handlerton(st_plugin_int *plugin) { + case DB_TYPE_INNODB: + innodb_hton = hton; + break; ++ case DB_TYPE_CTC: ++ tse_hton = hton; ++ break; + default: + break; + }; +@@ -901,13 +906,15 @@ void ha_end() { + + static bool dropdb_handlerton(THD *, plugin_ref plugin, void *path) { + handlerton *hton = plugin_data(plugin); +- if (hton->state == SHOW_OPTION_YES && hton->drop_database) +- hton->drop_database(hton, (char *)path); +- return false; ++ bool error = false; ++ if (hton->state == SHOW_OPTION_YES && hton->drop_database) { ++ error |= hton->drop_database(hton, (char *)path); ++ } ++ return error; + } + +-void ha_drop_database(char *path) { +- plugin_foreach(nullptr, dropdb_handlerton, MYSQL_STORAGE_ENGINE_PLUGIN, path); ++bool ha_drop_database(char *path) { ++ return plugin_foreach(nullptr, dropdb_handlerton, MYSQL_STORAGE_ENGINE_PLUGIN, path); + } + + static bool closecon_handlerton(THD *thd, plugin_ref plugin, void *) { +@@ -3875,9 +3882,7 @@ int handler::update_auto_increment() { + which will set first_successful_insert_id_in_cur_stmt if it's not + already set. + */ +- insert_id_for_cur_row = nr; +- /* +- Set next insert id to point to next auto-increment value to be able to ++ insert_id_for_cur_row = nr; /* Set next insert id to point to next auto-increment value to be able to + handle multi-row statements. + */ + set_next_insert_id(compute_next_insert_id(nr, variables)); +@@ -5798,10 +5803,12 @@ struct binlog_log_query_st { + static bool binlog_log_query_handlerton2(THD *thd, handlerton *hton, + void *args) { + struct binlog_log_query_st *b = (struct binlog_log_query_st *)args; +- if (hton->state == SHOW_OPTION_YES && hton->binlog_log_query) +- hton->binlog_log_query(hton, thd, b->binlog_command, b->query, ++ bool error = false; ++ if (hton->state == SHOW_OPTION_YES && hton->binlog_log_query) { ++ error |= hton->binlog_log_query(hton, thd, b->binlog_command, b->query, + b->query_length, b->db, b->table_name); +- return false; ++ } ++ return error; + } + + static bool binlog_log_query_handlerton(THD *thd, plugin_ref plugin, +@@ -5810,7 +5817,7 @@ static bool binlog_log_query_handlerton(THD *thd, plugin_ref plugin, + args); + } + +-void ha_binlog_log_query(THD *thd, handlerton *hton, ++bool ha_binlog_log_query(THD *thd, handlerton *hton, + enum_binlog_command binlog_command, const char *query, + size_t query_length, const char *db, + const char *table_name) { +@@ -5821,10 +5828,10 @@ void ha_binlog_log_query(THD *thd, handlerton *hton, + b.db = db; + b.table_name = table_name; + if (hton == nullptr) +- plugin_foreach(thd, binlog_log_query_handlerton, ++ return plugin_foreach(thd, binlog_log_query_handlerton, + MYSQL_STORAGE_ENGINE_PLUGIN, &b); + else +- binlog_log_query_handlerton2(thd, hton, &b); ++ return binlog_log_query_handlerton2(thd, hton, &b); + } + + int ha_binlog_end(THD *thd) { +@@ -7875,7 +7882,7 @@ int handler::ha_reset() { + return retval; + } + +-int handler::ha_write_row(uchar *buf) { ++int handler::ha_write_row(uchar *buf, bool write_through) { + int error; + Log_func *log_func = Write_rows_log_event::binlog_row_logging_function; + assert(table_share->tmp_table != NO_TMP_TABLE || m_lock_type == F_WRLCK); +@@ -7892,7 +7899,7 @@ int handler::ha_write_row(uchar *buf) { + set_my_errno(HA_ERR_CRASHED); return HA_ERR_CRASHED;); + + MYSQL_TABLE_IO_WAIT(PSI_TABLE_WRITE_ROW, MAX_KEY, error, +- { error = write_row(buf); }) ++ { error = write_row(buf, write_through); }) + + if (unlikely(error)) return error; + +diff --git a/sql/handler.h b/sql/handler.h +index 0530ca1..214027d 100644 +--- a/sql/handler.h ++++ b/sql/handler.h +@@ -662,7 +662,8 @@ enum legacy_db_type { + /** Performance schema engine. */ + DB_TYPE_PERFORMANCE_SCHEMA, + DB_TYPE_TEMPTABLE, +- DB_TYPE_FIRST_DYNAMIC = 42, ++ DB_TYPE_CTC = 30, ++ DB_TYPE_FIRST_DYNAMIC = 42, + DB_TYPE_DEFAULT = 127 // Must be last + }; + +@@ -1334,7 +1335,7 @@ typedef xa_status_code (*rollback_by_xid_t)(handlerton *hton, XID *xid); + typedef handler *(*create_t)(handlerton *hton, TABLE_SHARE *table, + bool partitioned, MEM_ROOT *mem_root); + +-typedef void (*drop_database_t)(handlerton *hton, char *path); ++typedef bool (*drop_database_t)(handlerton *hton, char *path); + + typedef int (*panic_t)(handlerton *hton, enum ha_panic_function flag); + +@@ -1510,7 +1511,7 @@ typedef int (*fill_is_table_t)(handlerton *hton, THD *thd, TABLE_LIST *tables, + typedef int (*binlog_func_t)(handlerton *hton, THD *thd, enum_binlog_func fn, + void *arg); + +-typedef void (*binlog_log_query_t)(handlerton *hton, THD *thd, ++typedef bool (*binlog_log_query_t)(handlerton *hton, THD *thd, + enum_binlog_command binlog_command, + const char *query, uint query_length, + const char *db, const char *table_name); +@@ -2133,6 +2134,13 @@ typedef bool (*check_fk_column_compat_t)( + + typedef bool (*is_reserved_db_name_t)(handlerton *hton, const char *name); + ++typedef int (*get_inst_id_t)(); ++typedef void (*set_metadata_switch_t)(); ++typedef int (*get_metadata_switch_t)(); ++typedef int (*get_metadata_status_t)(); ++typedef int (*op_before_load_meta_t)(THD *thd); ++typedef int (*op_after_load_meta_t)(THD *thd); ++ + /** + Prepare the secondary engine for executing a statement. This function is + called right after the secondary engine TABLE objects have been opened by +@@ -2420,6 +2428,8 @@ struct handlerton { + */ + uint savepoint_offset; + ++ uint64_t pre_sess_addr; ++ + /* handlerton methods */ + + close_connection_t close_connection; +@@ -2464,6 +2474,14 @@ struct handlerton { + dict_set_server_version_t dict_set_server_version; + is_reserved_db_name_t is_reserved_db_name; + ++ /** CTC metadata methods. */ ++ get_inst_id_t get_inst_id; ++ set_metadata_switch_t set_metadata_switch; ++ get_metadata_switch_t get_metadata_switch; ++ get_metadata_status_t get_metadata_status; ++ op_before_load_meta_t op_before_load_meta; ++ op_after_load_meta_t op_after_load_meta; ++ + /** Global handler flags. */ + uint32 flags{0}; + +@@ -4482,7 +4500,7 @@ class handler { + and delete_row() below. + */ + int ha_external_lock(THD *thd, int lock_type); +- int ha_write_row(uchar *buf); ++ int ha_write_row(uchar *buf, bool write_through = false); + /** + Update the current row. + +@@ -6161,12 +6179,13 @@ class handler { + } + + @param buf Buffer to write from. ++ @param write_through flag to force write without begining a tx. + + @return Operation status. + @retval 0 Success. + @retval != 0 Error code. + */ +- virtual int write_row(uchar *buf MY_ATTRIBUTE((unused))) { ++ virtual int write_row(uchar *buf MY_ATTRIBUTE((unused)), bool write_through MY_ATTRIBUTE((unused)) = false) { + return HA_ERR_WRONG_COMMAND; + } + +@@ -6178,6 +6197,7 @@ class handler { + the columns required for the error message are not read, the error + message will contain garbage. + */ ++#define METADATA_NORMALIZED + virtual int update_row(const uchar *old_data MY_ATTRIBUTE((unused)), + uchar *new_data MY_ATTRIBUTE((unused))) { + return HA_ERR_WRONG_COMMAND; +@@ -6874,7 +6894,7 @@ void ha_pre_dd_shutdown(void); + @retval true Error + */ + bool ha_flush_logs(bool binlog_group_flush = false); +-void ha_drop_database(char *path); ++bool ha_drop_database(char *path); + int ha_create_table(THD *thd, const char *path, const char *db, + const char *table_name, HA_CREATE_INFO *create_info, + bool update_create_info, bool is_temp_table, +@@ -6973,7 +6993,7 @@ void trans_register_ha(THD *thd, bool all, handlerton *ht, + int ha_reset_logs(THD *thd); + int ha_binlog_index_purge_file(THD *thd, const char *file); + void ha_reset_slave(THD *thd); +-void ha_binlog_log_query(THD *thd, handlerton *db_type, ++bool ha_binlog_log_query(THD *thd, handlerton *db_type, + enum_binlog_command binlog_command, const char *query, + size_t query_length, const char *db, + const char *table_name); +diff --git a/sql/log.cc b/sql/log.cc +index 4da945a..fc6f9c5 100644 +--- a/sql/log.cc ++++ b/sql/log.cc +@@ -906,11 +906,7 @@ bool Log_to_csv_event_handler::log_general( + if (log_table_intact.check(thd, table_list.table, &general_log_table_def)) + goto err; + +- if (table->file->ha_extra(HA_EXTRA_MARK_AS_LOG_TABLE) || +- table->file->ha_rnd_init(false)) +- goto err; +- +- need_rnd_end = true; ++ need_rnd_end = false; + + /* Honor next number columns if present */ + table->next_number_field = table->found_next_number_field; +@@ -960,7 +956,7 @@ bool Log_to_csv_event_handler::log_general( + } + + /* log table entries are not replicated */ +- if (table->file->ha_write_row(table->record[0])) goto err; ++ if (table->file->ha_write_row(table->record[0], true)) goto err; + + result = false; + +@@ -1026,13 +1022,7 @@ bool Log_to_csv_event_handler::log_slow( + goto err; + } + +- if (table->file->ha_extra(HA_EXTRA_MARK_AS_LOG_TABLE) || +- table->file->ha_rnd_init(false)) { +- reason = "mark log or init failed"; +- goto err; +- } +- +- need_rnd_end = true; ++ need_rnd_end = false; + + /* Honor next number columns if present */ + table->next_number_field = table->found_next_number_field; +@@ -1131,7 +1121,7 @@ bool Log_to_csv_event_handler::log_slow( + table->field[SQLT_FIELD_THREAD_ID]->store((longlong)thd->thread_id(), true); + + /* log table entries are not replicated */ +- if (table->file->ha_write_row(table->record[0])) { ++ if (table->file->ha_write_row(table->record[0], true)) { + reason = "write slow table failed"; + goto err; + } +diff --git a/sql/mdl.cc b/sql/mdl.cc +index da9ff9e..410b686 100644 +--- a/sql/mdl.cc ++++ b/sql/mdl.cc +@@ -1654,6 +1654,25 @@ bool MDL_lock::needs_hton_notification( + } + } + ++static bool is_notify_ctc_se(enum_mdl_type mdl_type, MDL_key::enum_mdl_namespace mdl_namespace) { ++ switch (mdl_namespace) { ++ case MDL_key::GLOBAL: ++ case MDL_key::BACKUP_LOCK: ++ if (mdl_type == MDL_SHARED) { ++ return true; ++ } ++ break; ++ ++ default: ++ if (mdl_type == MDL_EXCLUSIVE) { ++ return true; ++ } ++ return false; ++ } ++ ++ return false; ++} ++ + /** + Auxiliary functions needed for creation/destruction of MDL_ticket + objects. +@@ -2901,8 +2920,11 @@ bool MDL_context::try_acquire_lock_impl(MDL_request *mdl_request, + We need to notify/get permission from storage engines before acquiring + X lock if it is requested in one of namespaces interesting for SEs. + */ +- if (mdl_request->type == MDL_EXCLUSIVE && +- MDL_lock::needs_hton_notification(key->mdl_namespace())) { ++ ++ /* ++ if ((mdl_request->type == MDL_EXCLUSIVE && ++ MDL_lock::needs_hton_notification(key->mdl_namespace())) || ++ is_notify_ctc_se(mdl_request->type, key->mdl_namespace())) { + mysql_mdl_set_status(ticket->m_psi, MDL_ticket::PRE_ACQUIRE_NOTIFY); + + bool victimized; +@@ -2916,6 +2938,7 @@ bool MDL_context::try_acquire_lock_impl(MDL_request *mdl_request, + + mysql_mdl_set_status(ticket->m_psi, MDL_ticket::PENDING); + } ++ */ + + retry: + /* +@@ -3034,6 +3057,26 @@ retry: + m_ticket_store.push_front(mdl_request->duration, ticket); + mdl_request->ticket = ticket; + ++ if ((mdl_request->type == MDL_EXCLUSIVE && ++ MDL_lock::needs_hton_notification(key->mdl_namespace())) || ++ is_notify_ctc_se(mdl_request->type, key->mdl_namespace())) { ++ ++ mysql_mdl_set_status(ticket->m_psi, MDL_ticket::PRE_ACQUIRE_NOTIFY); ++ ++ bool victimized; ++ if (m_owner->notify_hton_pre_acquire_exclusive(key, &victimized)) { ++ ++ ticket->m_hton_notified = false; ++ release_lock(mdl_request->duration, ticket); ++ mdl_request->ticket = nullptr; ++ my_error(victimized ? ER_LOCK_DEADLOCK : ER_LOCK_REFUSED_BY_ENGINE, ++ MYF(0)); ++ return true; ++ } ++ ++ ticket->m_hton_notified = true; ++ mysql_mdl_set_status(ticket->m_psi, MDL_ticket::PENDING); ++ } + mysql_mdl_set_status(ticket->m_psi, MDL_ticket::GRANTED); + return false; + } +@@ -3147,6 +3190,26 @@ slow_path: + m_ticket_store.push_front(mdl_request->duration, ticket); + mdl_request->ticket = ticket; + ++ if ((mdl_request->type == MDL_EXCLUSIVE && ++ MDL_lock::needs_hton_notification(key->mdl_namespace())) || ++ is_notify_ctc_se(mdl_request->type, key->mdl_namespace())) { ++ ++ mysql_mdl_set_status(ticket->m_psi, MDL_ticket::PRE_ACQUIRE_NOTIFY); ++ ++ bool victimized; ++ if (m_owner->notify_hton_pre_acquire_exclusive(key, &victimized)) { ++ ++ ticket->m_hton_notified = false; ++ release_lock(mdl_request->duration, ticket); ++ mdl_request->ticket = nullptr; ++ my_error(victimized ? ER_LOCK_DEADLOCK : ER_LOCK_REFUSED_BY_ENGINE, ++ MYF(0)); ++ return true; ++ } ++ ticket->m_hton_notified = true; ++ mysql_mdl_set_status(ticket->m_psi, MDL_ticket::PENDING); ++ } ++ + mysql_mdl_set_status(ticket->m_psi, MDL_ticket::GRANTED); + } else + *out_ticket = ticket; +@@ -3207,10 +3270,11 @@ bool MDL_context::clone_ticket(MDL_request *mdl_request) { + of storage engines we need to notify/get permission from SEs similarly + to situation when lock acquired. + */ +- if (mdl_request->type == MDL_EXCLUSIVE && +- MDL_lock::needs_hton_notification(mdl_request->key.mdl_namespace())) { ++ if ((mdl_request->type == MDL_EXCLUSIVE && ++ MDL_lock::needs_hton_notification(mdl_request->key.mdl_namespace())) || ++ is_notify_ctc_se(mdl_request->type, mdl_request->key.mdl_namespace())) { + assert(mdl_request->ticket->m_hton_notified); +- ++ /* + mysql_mdl_set_status(ticket->m_psi, MDL_ticket::PRE_ACQUIRE_NOTIFY); + + bool victimized; +@@ -3224,6 +3288,7 @@ bool MDL_context::clone_ticket(MDL_request *mdl_request) { + ticket->m_hton_notified = true; + + mysql_mdl_set_status(ticket->m_psi, MDL_ticket::PENDING); ++ */ + } + + ticket->m_lock = mdl_request->ticket->m_lock; +@@ -3275,6 +3340,28 @@ bool MDL_context::clone_ticket(MDL_request *mdl_request) { + + mdl_request->ticket = ticket; + m_ticket_store.push_front(mdl_request->duration, ticket); ++ ++ if ((mdl_request->type == MDL_EXCLUSIVE && ++ MDL_lock::needs_hton_notification(mdl_request->key.mdl_namespace())) || ++ is_notify_ctc_se(mdl_request->type, mdl_request->key.mdl_namespace())) { ++ ++ mysql_mdl_set_status(ticket->m_psi, MDL_ticket::PRE_ACQUIRE_NOTIFY); ++ ++ bool victimized; ++ if (m_owner->notify_hton_pre_acquire_exclusive(&mdl_request->key, ++ &victimized)) { ++ ticket->m_hton_notified = false; ++ release_lock(mdl_request->duration, ticket); ++ mdl_request->ticket = nullptr; ++ my_error(victimized ? ER_LOCK_DEADLOCK : ER_LOCK_REFUSED_BY_ENGINE, ++ MYF(0)); ++ return true; ++ } ++ ticket->m_hton_notified = true; ++ ++ mysql_mdl_set_status(ticket->m_psi, MDL_ticket::PENDING); ++ } ++ + mysql_mdl_set_status(ticket->m_psi, MDL_ticket::GRANTED); + + return false; +@@ -3576,6 +3663,27 @@ bool MDL_context::acquire_lock(MDL_request *mdl_request, + m_ticket_store.push_front(mdl_request->duration, ticket); + mdl_request->ticket = ticket; + ++ if ((mdl_request->type == MDL_EXCLUSIVE && ++ MDL_lock::needs_hton_notification(mdl_request->key.mdl_namespace())) || ++ is_notify_ctc_se(mdl_request->type, mdl_request->key.mdl_namespace())) { ++ ++ mysql_mdl_set_status(ticket->m_psi, MDL_ticket::PRE_ACQUIRE_NOTIFY); ++ ++ bool victimized; ++ if (m_owner->notify_hton_pre_acquire_exclusive(&mdl_request->key, ++ &victimized)) { ++ ticket->m_hton_notified = false; ++ release_lock(mdl_request->duration, ticket); ++ mdl_request->ticket = nullptr; ++ my_error(victimized ? ER_LOCK_DEADLOCK : ER_LOCK_REFUSED_BY_ENGINE, ++ MYF(0)); ++ return true; ++ } ++ ticket->m_hton_notified = true; ++ ++ mysql_mdl_set_status(ticket->m_psi, MDL_ticket::PENDING); ++ } ++ + mysql_mdl_set_status(ticket->m_psi, MDL_ticket::GRANTED); + + return false; +@@ -4234,6 +4342,29 @@ void MDL_context::release_locks_stored_before(enum_mdl_duration duration, + } + } + ++void MDL_context::dump_lock(enum_mdl_duration duration, MDL_ticket *ticket) { ++ MDL_lock *lock = ticket->m_lock; ++ DBUG_TRACE; ++ fprintf(stderr, "\ndb=%s name=%s type=%d, duration=%d\n", lock->key.db_name(), lock->key.name(), ++ ticket->get_type(), duration); ++} ++ ++void MDL_context::dump_locks_stored_before(enum_mdl_duration duration, ++ MDL_ticket *sentinel) { ++ DBUG_TRACE; ++ ++ MDL_ticket *ticket; ++ MDL_ticket_store::List_iterator it = m_ticket_store.list_iterator(duration); ++ if (m_ticket_store.is_empty(duration)) { ++ return; ++ } ++ ++ while ((ticket = it++) && ticket != sentinel) { ++ fprintf(stderr, "\nfound lock to release ticket=%p\n", ticket); ++ dump_lock(duration, ticket); ++ } ++} ++ + /** + Release all explicit locks in the context which correspond to the + same name/object as this lock request. +diff --git a/sql/mdl.h b/sql/mdl.h +index f1f49f0..0127906 100644 +--- a/sql/mdl.h ++++ b/sql/mdl.h +@@ -1444,6 +1444,14 @@ class MDL_context { + void release_all_locks_for_name(MDL_ticket *ticket); + void release_locks(MDL_release_locks_visitor *visitor); + void release_lock(MDL_ticket *ticket); ++ void dump_lock(enum_mdl_duration duration, MDL_ticket *ticket); ++ void dump_locks_stored_before(enum_mdl_duration duration, ++ MDL_ticket *sentinel); ++ void inline dump_locks() { ++ dump_locks_stored_before(MDL_EXPLICIT, nullptr); ++ dump_locks_stored_before(MDL_STATEMENT, nullptr); ++ dump_locks_stored_before(MDL_TRANSACTION, nullptr); ++ } + + bool owns_equal_or_stronger_lock(const MDL_key *mdl_key, + enum_mdl_type mdl_type); +diff --git a/sql/mysqld.cc b/sql/mysqld.cc +index 50b76e2..080fdf9 100644 +--- a/sql/mysqld.cc ++++ b/sql/mysqld.cc +@@ -1216,6 +1216,7 @@ handlerton *heap_hton; + handlerton *temptable_hton; + handlerton *myisam_hton; + handlerton *innodb_hton; ++handlerton *tse_hton; + + char *opt_disabled_storage_engines; + uint opt_server_id_bits = 0; +@@ -4623,7 +4624,8 @@ int init_common_variables() { + + From MySQL 5.5 onwards, the default storage engine is InnoDB. + */ +- default_storage_engine = "InnoDB"; ++ //default_storage_engine = "InnoDB"; ++ default_storage_engine = "CTC"; + default_tmp_storage_engine = default_storage_engine; + + /* +@@ -5673,6 +5675,7 @@ static int setup_error_log_components() { + + static int init_server_components() { + DBUG_TRACE; ++ + /* + We need to call each of these following functions to ensure that + all things are initialized so that unireg_abort() doesn't fail +@@ -7574,6 +7577,7 @@ int mysqld_main(int argc, char **argv) + #endif + + server_components_initialized(); ++ printf("[SYSTEM] mysqld server start success! (mysqld_server_started = true)\n"); + + /* + Set opt_super_readonly here because if opt_super_readonly is set +diff --git a/sql/mysqld.h b/sql/mysqld.h +index 0d7d41c..b3f86eb 100644 +--- a/sql/mysqld.h ++++ b/sql/mysqld.h +@@ -358,6 +358,7 @@ extern handlerton *myisam_hton; + extern handlerton *heap_hton; + extern handlerton *temptable_hton; + extern handlerton *innodb_hton; ++extern handlerton *tse_hton; + extern uint opt_server_id_bits; + extern ulong opt_server_id_mask; + extern const char *load_default_groups[]; +diff --git a/sql/mysqld_thd_manager.cc b/sql/mysqld_thd_manager.cc +index 902fe2b..2fad578 100644 +--- a/sql/mysqld_thd_manager.cc ++++ b/sql/mysqld_thd_manager.cc +@@ -48,6 +48,7 @@ + #include "mysql/thread_pool_priv.h" // inc_thread_created + #include "sql/sql_class.h" // THD + #include "thr_mutex.h" ++#include "sql/handler.h" + + std::atomic Global_THD_manager::atomic_global_thd_count{0U}; + Global_THD_manager *Global_THD_manager::thd_manager = nullptr; +@@ -228,6 +229,11 @@ my_thread_id Global_THD_manager::get_new_thread_id() { + my_thread_id new_id; + MUTEX_LOCK(lock, &LOCK_thread_ids); + do { ++ if (thread_id_counter == 0) { ++ handlerton *hton = ha_resolve_by_legacy_type(current_thd, DB_TYPE_CTC); ++ my_thread_id tse_inst_id = hton->get_inst_id ? (my_thread_id)hton->get_inst_id() : 0; ++ thread_id_counter = tse_inst_id << 16; ++ } + new_id = thread_id_counter++; + } while (!thread_ids.insert_unique(new_id).second); + return new_id; +diff --git a/sql/resourcegroups/resource_group_mgr.cc b/sql/resourcegroups/resource_group_mgr.cc +index a90b15d..309763d 100644 +--- a/sql/resourcegroups/resource_group_mgr.cc ++++ b/sql/resourcegroups/resource_group_mgr.cc +@@ -119,7 +119,7 @@ Resource_group_mgr *Resource_group_mgr::instance() { + static inline bool persist_resource_group( + THD *thd, const resourcegroups::Resource_group &resource_group, + bool update) { +- handlerton *ddse = ha_resolve_by_legacy_type(thd, DB_TYPE_INNODB); ++ handlerton *ddse = ha_resolve_by_legacy_type(thd, DB_TYPE_CTC); + if (ddse->is_dict_readonly && ddse->is_dict_readonly()) { + LogErr(WARNING_LEVEL, ER_RESOURCE_GROUP_METADATA_UPDATE_SKIPPED); + return false; +@@ -141,7 +141,12 @@ static inline bool persist_resource_group( + + static bool deserialize_resource_groups(THD *thd) { + DBUG_TRACE; +- ++ handlerton *ddse = ha_resolve_by_legacy_type(thd, DB_TYPE_CTC); ++ if (!opt_initialize && !mysqld_server_started) { ++ if (ddse->op_before_load_meta(thd) != 0) { ++ return true; ++ } ++ } + /* + Associate flag SYSTEM_THREAD_DD_INITIALIZE with THD context. + This ensures we need not acquire MDL locks during initialization phase. +@@ -207,7 +212,11 @@ static bool deserialize_resource_groups(THD *thd) { + if (persist_resource_group(thd, *res_grp_mgr->sys_default_resource_group(), + sys_default_in_dd)) + return true; +- ++ if (!opt_initialize && !mysqld_server_started) { ++ if (ddse->op_after_load_meta(thd) != 0) { ++ return true; ++ } ++ } + return false; + } + +diff --git a/sql/rpl_gtid_persist.cc b/sql/rpl_gtid_persist.cc +index e16b39c..efdfba2 100644 +--- a/sql/rpl_gtid_persist.cc ++++ b/sql/rpl_gtid_persist.cc +@@ -771,6 +771,8 @@ static void *compress_gtid_table(void *p_thd) { + mysql_mutex_unlock(&LOCK_compress_gtid_table); + THD_EXIT_COND(thd, nullptr); + ++ continue; // skip compress gtid table ++ + THD_STAGE_INFO(thd, stage_compressing_gtid_table); + /* Compressing the gtid_executed table. */ + if (gtid_state->compress(thd)) { +diff --git a/sql/sql_class.cc b/sql/sql_class.cc +index c171f0b..a34904d 100644 +--- a/sql/sql_class.cc ++++ b/sql/sql_class.cc +@@ -2890,6 +2890,17 @@ void THD::update_slow_query_status() { + server_status |= SERVER_QUERY_WAS_SLOW; + } + ++void THD::add(const char *schema_name, const char *table_name, const invalidate_object_type obj_type) ++{ ++ std::map, invalidate_object_type>::iterator ++ it = m_invalidate_map.find(typename Invalidate_map::key_type(schema_name, table_name)); ++ if (it == m_invalidate_map.end()) { ++ m_invalidate_map.insert(typename Invalidate_map::value_type( ++ typename Invalidate_map::key_type(schema_name, table_name), ++ typename Invalidate_map::mapped_type(obj_type))); ++ } ++} ++ + /** + Initialize the transactional ddl context when executing CREATE TABLE ... + SELECT command with engine which supports atomic DDL. +diff --git a/sql/sql_class.h b/sql/sql_class.h +index 9f68530..c7004b4 100644 +--- a/sql/sql_class.h ++++ b/sql/sql_class.h +@@ -841,6 +841,7 @@ class THD : public MDL_context_owner, + } + + public: ++ bool is_reading_dd = false; + MDL_context mdl_context; + + /** +@@ -4417,6 +4418,29 @@ class THD : public MDL_context_owner, + @param thd parent session + */ + void copy_table_access_properties(THD *thd); ++ ++ enum invalidate_object_type { ++ OBJ_ABSTRACT_TABLE, ++ OBJ_SCHEMA, ++ OBJ_EVENT, ++ OBJ_COLUMN_STATISTICS, ++ OBJ_CHARSET, ++ OBJ_COLLATION, ++ OBJ_RT_PROCEDURE, ++ OBJ_RT_FUNCTION, ++ OBJ_TABLESPACE, ++ OBJ_RESOURCE_GROUP, ++ OBJ_SPATIAL_REFERENCE_SYSTEM ++ }; ++ private: ++ typedef std::map, invalidate_object_type> Invalidate_map; ++ Invalidate_map m_invalidate_map; ++ public: ++ void add(const char *schema_name, const char *table_name, const invalidate_object_type obj_type); ++ const Invalidate_map &invalidates() const { return m_invalidate_map; } ++ //void invalidate(); ++ bool is_empty() const { return m_invalidate_map.empty(); } ++ void clear() { m_invalidate_map.clear(); } + }; + + /** +diff --git a/sql/sql_db.cc b/sql/sql_db.cc +index 662f522..975e017 100644 +--- a/sql/sql_db.cc ++++ b/sql/sql_db.cc +@@ -120,6 +120,7 @@ static bool rm_dir_w_symlink(const char *org_path, bool send_error); + static void mysql_change_db_impl(THD *thd, const LEX_CSTRING &new_db_name, + ulong new_db_access, + const CHARSET_INFO *new_db_charset); ++static bool no_need_schema_dir = true; + + bool get_default_db_collation(const dd::Schema &schema, + const CHARSET_INFO **collation) { +@@ -422,13 +423,13 @@ bool mysql_create_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) { + Server should either be in restart mode or upgrade mode to create only + dd::Schema object for the dictionary cache. + */ +- if (!schema_dir_exists) { ++ if (!no_need_schema_dir && !schema_dir_exists) { + my_printf_error(ER_BAD_DB_ERROR, + "System schema directory does not exist.", MYF(0)); + return true; + } + } else if (store_in_dd) { +- if (schema_dir_exists) { ++ if (!no_need_schema_dir && !schema_dir_exists) { + my_error(ER_SCHEMA_DIR_EXISTS, MYF(0), path); + return true; + } +@@ -440,7 +441,7 @@ bool mysql_create_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) { + my_strerror(errbuf, sizeof(errbuf), my_errno())); + return true; + } +- if (my_mkdir(path, 0777, MYF(0)) < 0) { ++ if (!no_need_schema_dir && my_mkdir(path, 0777, MYF(0)) < 0) { + char errbuf[MYSQL_ERRMSG_SIZE]; + my_error(ER_SCHEMA_DIR_CREATE_FAILED, MYF(0), db, my_errno(), + my_strerror(errbuf, MYSQL_ERRMSG_SIZE, my_errno())); +@@ -472,14 +473,18 @@ bool mysql_create_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) { + other error we ignore the error as we anyway return + failure (true) here. + */ +- if (!schema_dir_exists) rm_dir_w_symlink(path, true); ++ if (!no_need_schema_dir && !schema_dir_exists) rm_dir_w_symlink(path, true); + return true; + } + } + + // Log the query in the handler's binlog +- ha_binlog_log_query(thd, nullptr, LOGCOM_CREATE_DB, thd->query().str, +- thd->query().length, db, ""); ++ if (ha_binlog_log_query(thd, nullptr, LOGCOM_CREATE_DB, thd->query().str, ++ thd->query().length, db, "")) { ++ my_printf_error(ER_BAD_DB_ERROR, ++ "Binlog create database query failed.", MYF(0)); ++ return true; ++ } + + /* + If we have not added database to the data-dictionary we don't have +@@ -487,7 +492,7 @@ bool mysql_create_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) { + binlog's trx cache, which requires transaction with valid XID. + */ + if (write_db_cmd_to_binlog(thd, db, store_in_dd)) { +- if (!schema_dir_exists) rm_dir_w_symlink(path, true); ++ if (!no_need_schema_dir && !schema_dir_exists) rm_dir_w_symlink(path, true); + return true; + } + +@@ -496,7 +501,7 @@ bool mysql_create_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) { + able to remove directory in case of failure. + */ + if (trans_commit_stmt(thd) || trans_commit(thd)) { +- if (!schema_dir_exists) rm_dir_w_symlink(path, true); ++ if (!no_need_schema_dir && !schema_dir_exists) rm_dir_w_symlink(path, true); + return true; + } + +@@ -602,8 +607,12 @@ bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) { + because e.g. NDB needs to propagate the read only option to + other mysqld servers in the cluster. + */ +- ha_binlog_log_query(thd, nullptr, LOGCOM_ALTER_DB, thd->query().str, +- thd->query().length, db, ""); ++ if (ha_binlog_log_query(thd, nullptr, LOGCOM_ALTER_DB, thd->query().str, ++ thd->query().length, db, "")) { ++ my_printf_error(ER_BAD_DB_ERROR, ++ "Binlog alter database query failed.", MYF(0)); ++ return true; ++ } + + /* + The original query is written to the binlog and hence replicated. +@@ -768,16 +777,18 @@ bool mysql_rm_db(THD *thd, const LEX_CSTRING &db, bool if_exists) { + } else // Schema found in DD + { + /* Database directory does not exist. */ +- if (schema_dirp == nullptr) { +- if (!if_exists) { +- my_error(ER_SCHEMA_DIR_MISSING, MYF(0), path); +- return true; +- } +- push_warning_printf(thd, Sql_condition::SL_NOTE, ER_SCHEMA_DIR_MISSING, +- ER_THD(thd, ER_SCHEMA_DIR_MISSING), path); +- } else { +- if (find_unknown_and_remove_deletable_files(thd, schema_dirp, path)) { +- return true; ++ if (!no_need_schema_dir) { ++ if (schema_dirp == nullptr) { ++ if (!if_exists) { ++ my_error(ER_SCHEMA_DIR_MISSING, MYF(0), path); ++ return true; ++ } ++ push_warning_printf(thd, Sql_condition::SL_NOTE, ER_SCHEMA_DIR_MISSING, ++ ER_THD(thd, ER_SCHEMA_DIR_MISSING), path); ++ } else { ++ if (find_unknown_and_remove_deletable_files(thd, schema_dirp, path)) { ++ return true; ++ } + } + } + +@@ -834,10 +845,13 @@ bool mysql_rm_db(THD *thd, const LEX_CSTRING &db, bool if_exists) { + other connected server. + */ + +- ha_drop_database(path); +- thd->clear_error(); /* @todo Do not ignore errors */ ++ if (ha_drop_database(path)) { ++ my_printf_error(ER_BAD_DB_ERROR, ++ "Drop database failed.", MYF(0)); ++ error = true; ++ } + Disable_binlog_guard binlog_guard(thd); +- error = Events::drop_schema_events(thd, *schema); ++ error = (error || Events::drop_schema_events(thd, *schema)); + error = (error || sp_drop_db_routines(thd, *schema)); + } + thd->pop_internal_handler(); +diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc +index 70d9c1f..02e6bc6 100644 +--- a/sql/sql_insert.cc ++++ b/sql/sql_insert.cc +@@ -2681,8 +2681,8 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, + init_tmp_table_share(thd, &share, "", 0, "", "", nullptr); + + tmp_table.s->db_create_options = 0; +- tmp_table.s->db_low_byte_first = (create_info->db_type == myisam_hton || +- create_info->db_type == heap_hton); ++ tmp_table.s->db_low_byte_first = ++ (create_info->db_type == myisam_hton || create_info->db_type == heap_hton || create_info->db_type == tse_hton); + tmp_table.set_not_started(); + + if (!thd->variables.explicit_defaults_for_timestamp) +diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc +index 3860d34..e89ca4c 100644 +--- a/sql/sql_plugin.cc ++++ b/sql/sql_plugin.cc +@@ -358,6 +358,7 @@ const LEX_CSTRING plugin_type_names[MYSQL_MAX_PLUGIN_TYPE_NUM] = { + + extern int initialize_schema_table(st_plugin_int *plugin); + extern int finalize_schema_table(st_plugin_int *plugin); ++extern bool opt_initialize_insecure; + + /* + The number of elements in both plugin_type_initialize and +@@ -1272,6 +1273,7 @@ void plugin_unlock_list(THD *thd, plugin_ref *list, size_t count) { + mysql_mutex_unlock(&LOCK_plugin); + } + ++ + static int plugin_initialize(st_plugin_int *plugin) { + int ret = 1; + DBUG_TRACE; +@@ -1296,6 +1298,69 @@ static int plugin_initialize(st_plugin_int *plugin) { + if (strcmp(plugin->name.str, "InnoDB") == 0) { + innodb_callback_data = ((handlerton *)plugin->data)->data; + } ++ if (strcmp(plugin->name.str, "CTC") == 0) { ++ plugin->load_option = PLUGIN_FORCE; ++ ++ handlerton *hton = (handlerton *)plugin->data; ++ hton->set_metadata_switch(); ++ int meta_version_match = hton->get_metadata_switch(); ++ switch (meta_version_match) { ++ case 0: ++ printf("[ERROR] INIT CTC PLUGIN FAILED! Metadata version not match.\n"); ++ LogErr(ERROR_LEVEL, ER_PLUGIN_INIT_FAILED, plugin->name.str); ++ goto err; ++ case 1: // success ++ break; ++ case 2: ++ printf("[ERROR] INIT CTC PLUGIN FAILED! Neither metadata switch is turned on.\n"); ++ LogErr(ERROR_LEVEL, ER_PLUGIN_INIT_FAILED, plugin->name.str); ++ goto err; ++ case 3: ++ printf("[ERROR] INIT CTC PLUGIN FAILED! At least one cantian node is not ready.\n"); ++ LogErr(ERROR_LEVEL, ER_PLUGIN_INIT_FAILED, plugin->name.str); ++ goto err; ++ default: ++ printf("[ERROR] INIT CTC PLUGIN FAILED! get_metadata_status FAILED, meta_version_match = %d.\n", meta_version_match); ++ LogErr(ERROR_LEVEL, ER_PLUGIN_INIT_FAILED, plugin->name.str); ++ goto err; ++ } ++ ++ int ctc_init_status = hton->get_metadata_status(); ++ if (opt_initialize || opt_initialize_insecure) { // init stage ++ switch (ctc_init_status) { ++ case 0: // success ++ break; ++ case 1: ++ printf("[ERROR] INIT FAILED! No need to repeat initialization. One node has started initialization, but has not completed.\n"); ++ LogErr(ERROR_LEVEL, ER_PLUGIN_INIT_FAILED, plugin->name.str); ++ goto err; ++ case 2: ++ printf("[ERROR] INIT FAILED! No need to repeat initialization. A node has completed initialization.\n"); ++ LogErr(ERROR_LEVEL, ER_PLUGIN_INIT_FAILED, plugin->name.str); ++ goto err; ++ default: ++ printf("[ERROR] INIT FAILED! get_metadata_status failed in initialization, ctc_init_status = %d.\n", ctc_init_status); ++ LogErr(ERROR_LEVEL, ER_PLUGIN_INIT_FAILED, plugin->name.str); ++ goto err; ++ } ++ } else { // start stage ++ switch (ctc_init_status) { ++ case 0: ++ printf("[ERROR] START FAILED! Please wait for the initialization to complete. None of the nodes have started initialization yet.\n"); ++ LogErr(ERROR_LEVEL, ER_PLUGIN_INIT_FAILED, plugin->name.str); ++ goto err; ++ case 1: ++ printf("[ERROR] START FAILED! Please wait for the initialization to complete. One node has started initialization, but has not completed.\n"); ++ LogErr(ERROR_LEVEL, ER_PLUGIN_INIT_FAILED, plugin->name.str); ++ goto err; ++ case 2: // success ++ break; ++ default: ++ printf("[ERROR] START FAILED! get_metadata_status failed in starting, ctc_init_status = %d.\n", ctc_init_status); ++ goto err; ++ } ++ } ++ } + } else if (plugin->plugin->init) { + if (strcmp(plugin->name.str, "daemon_memcached") == 0) { + plugin->data = innodb_callback_data; +@@ -1566,6 +1631,11 @@ bool plugin_register_builtin_and_init_core_se(int *argc, char **argv) { + tmp.load_option = PLUGIN_FORCE; + } + ++ if (!my_strcasecmp(&my_charset_latin1, plugin->name, "InnoDB")) { ++ tmp.load_option = PLUGIN_OFF; ++ continue; ++ } ++ + free_root(&tmp_root, MYF(MY_MARK_BLOCKS_FREE)); + if (test_plugin_options(&tmp_root, &tmp, argc, argv)) + tmp.state = PLUGIN_IS_DISABLED; +diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc +index 7bd705b..ace7923 100644 +--- a/sql/sql_rename.cc ++++ b/sql/sql_rename.cc +@@ -35,6 +35,7 @@ + #include "my_murmur3.h" + #include "my_sys.h" + #include "mysql/components/services/log_shared.h" ++#include "mysql/plugin.h" + #include "mysqld_error.h" + #include "sql/dd/cache/dictionary_client.h" // dd::cache::Dictionary_client + #include "sql/dd/dd_table.h" // dd::table_storage_engine +@@ -718,6 +719,7 @@ static bool do_rename(THD *thd, TABLE_LIST *ren_table, const char *new_db, + } + } + ++ hton->pre_sess_addr = *(uint64_t *)thd_get_ha_data(thd, hton); + if (collect_and_lock_fk_tables_for_rename_table( + thd, ren_table->db, old_alias, from_table, new_db, new_alias, + hton, fk_invalidator)) { +@@ -732,13 +734,17 @@ static bool do_rename(THD *thd, TABLE_LIST *ren_table, const char *new_db, + happen. So it is safe to clear invalidator. + */ + fk_invalidator->clear(); ++ hton->pre_sess_addr = 0; + return true; + } + } + + if (lock_check_constraint_names_for_rename(thd, ren_table->db, old_alias, +- from_table, new_db, new_alias)) ++ from_table, new_db, new_alias)) { ++ ++ hton->pre_sess_addr = 0; + return true; ++ } + + /* + We commit changes to data-dictionary immediately after renaming +@@ -777,8 +783,10 @@ static bool do_rename(THD *thd, TABLE_LIST *ren_table, const char *new_db, + */ + fk_invalidator->clear(); + } ++ hton->pre_sess_addr = 0; + return true; + } ++ hton->pre_sess_addr = 0; + + /* + If RENAME TABLE is non-atomic but we have not committed the above +diff --git a/sql/sql_select.cc b/sql/sql_select.cc +index 5963cf6..3218795 100644 +--- a/sql/sql_select.cc ++++ b/sql/sql_select.cc +@@ -2755,7 +2755,7 @@ void QEP_TAB::push_index_cond(const JOIN_TAB *join_tab, uint keyno, + TABLE *const tbl = table(); + + // Disable ICP for Innodb intrinsic temp table because of performance +- if (tbl->s->db_type() == innodb_hton && tbl->s->tmp_table != NO_TMP_TABLE && ++ if ((tbl->s->db_type() == innodb_hton || tbl->s->db_type() == tse_hton) && tbl->s->tmp_table != NO_TMP_TABLE && + tbl->s->tmp_table != TRANSACTIONAL_TMP_TABLE) + return; + +diff --git a/sql/sql_table.cc b/sql/sql_table.cc +index 04bc666..7230fda 100644 +--- a/sql/sql_table.cc ++++ b/sql/sql_table.cc +@@ -8670,7 +8670,7 @@ static bool create_table_impl( + (create_info->options & HA_LEX_CREATE_TMP_TABLE) != + HA_LEX_CREATE_TMP_TABLE && + (thd->is_server_upgrade_thread() || +- create_info->db_type->db_type == DB_TYPE_INNODB) && ++ create_info->db_type->db_type == DB_TYPE_CTC) && + (dd::get_dictionary()->is_dd_table_name(db, error_table_name) || + dd::get_dictionary()->is_system_table_name(db, error_table_name)); + if (is_whitelisted_table) thd->push_internal_handler(&error_handler); +@@ -9398,6 +9398,10 @@ static bool adjust_fk_child_after_parent_def_change( + + if (!check_only && thd->dd_client()->update(child_table_def)) return true; + ++ if (!thd->is_attachable_rw_transaction_active()) { ++ thd->dd_client()->add_modified_objects_before_commit(); ++ } ++ + return false; + } + +@@ -11624,7 +11628,7 @@ static bool fill_alter_inplace_info(THD *thd, TABLE *table, + Note: strcmp branch is to be removed in future when we fix it + in InnoDB. + */ +- if (ha_alter_info->create_info->db_type->db_type == DB_TYPE_INNODB || ++ if (ha_alter_info->create_info->db_type->db_type == DB_TYPE_CTC || + ha_alter_info->create_info->db_type->db_type == DB_TYPE_NDBCLUSTER) + field_renamed = strcmp(field->field_name, new_field->field_name); + else +diff --git a/sql/sql_tmp_table.cc b/sql/sql_tmp_table.cc +index 2063261..1c71f77 100644 +--- a/sql/sql_tmp_table.cc ++++ b/sql/sql_tmp_table.cc +@@ -558,12 +558,15 @@ class Cache_temp_engine_properties { + static uint HEAP_MAX_KEY_LENGTH; + static uint TEMPTABLE_MAX_KEY_LENGTH; + static uint INNODB_MAX_KEY_LENGTH; ++ static uint CTC_MAX_KEY_LENGTH; + static uint HEAP_MAX_KEY_PART_LENGTH; + static uint TEMPTABLE_MAX_KEY_PART_LENGTH; + static uint INNODB_MAX_KEY_PART_LENGTH; ++ static uint CTC_MAX_KEY_PART_LENGTH; + static uint HEAP_MAX_KEY_PARTS; + static uint TEMPTABLE_MAX_KEY_PARTS; + static uint INNODB_MAX_KEY_PARTS; ++ static uint CTC_MAX_KEY_PARTS; + + static void init(THD *thd); + }; +@@ -609,17 +612,30 @@ void Cache_temp_engine_properties::init(THD *thd) { + INNODB_MAX_KEY_PARTS = handler->max_key_parts(); + destroy(handler); + plugin_unlock(nullptr, db_plugin); ++ ++ // Cache CTC engine's ++ db_plugin = ha_lock_engine(nullptr, tse_hton); ++ handler = get_new_handler((TABLE_SHARE *)nullptr, false, thd->mem_root, ++ tse_hton); ++ CTC_MAX_KEY_LENGTH = handler->max_key_length(); ++ CTC_MAX_KEY_PART_LENGTH = handler->max_key_parts(); ++ CTC_MAX_KEY_PARTS = handler->max_key_parts(); ++ destroy(handler); ++ plugin_unlock(nullptr, db_plugin); + } + + uint Cache_temp_engine_properties::HEAP_MAX_KEY_LENGTH = 0; + uint Cache_temp_engine_properties::TEMPTABLE_MAX_KEY_LENGTH = 0; + uint Cache_temp_engine_properties::INNODB_MAX_KEY_LENGTH = 0; ++uint Cache_temp_engine_properties::CTC_MAX_KEY_LENGTH = 0; + uint Cache_temp_engine_properties::HEAP_MAX_KEY_PART_LENGTH = 0; + uint Cache_temp_engine_properties::TEMPTABLE_MAX_KEY_PART_LENGTH = 0; + uint Cache_temp_engine_properties::INNODB_MAX_KEY_PART_LENGTH = 0; ++uint Cache_temp_engine_properties::CTC_MAX_KEY_PART_LENGTH = 0; + uint Cache_temp_engine_properties::HEAP_MAX_KEY_PARTS = 0; + uint Cache_temp_engine_properties::TEMPTABLE_MAX_KEY_PARTS = 0; + uint Cache_temp_engine_properties::INNODB_MAX_KEY_PARTS = 0; ++uint Cache_temp_engine_properties::CTC_MAX_KEY_PARTS = 0; + + /** + Initialize the storage engine properties for the alternative temporary table +@@ -651,12 +667,12 @@ void get_max_key_and_part_length(uint *max_key_length, + + *max_key_length = + std::min(Cache_temp_engine_properties::HEAP_MAX_KEY_LENGTH, +- Cache_temp_engine_properties::INNODB_MAX_KEY_LENGTH); ++ Cache_temp_engine_properties::CTC_MAX_KEY_LENGTH); + *max_key_part_length = + std::min(Cache_temp_engine_properties::HEAP_MAX_KEY_PART_LENGTH, +- Cache_temp_engine_properties::INNODB_MAX_KEY_PART_LENGTH); ++ Cache_temp_engine_properties::CTC_MAX_KEY_PART_LENGTH); + *max_key_parts = std::min(Cache_temp_engine_properties::HEAP_MAX_KEY_PARTS, +- Cache_temp_engine_properties::INNODB_MAX_KEY_PARTS); ++ Cache_temp_engine_properties::CTC_MAX_KEY_PARTS); + } + + /** +@@ -2085,7 +2101,8 @@ bool setup_tmp_table_handler(THD *thd, TABLE *table, ulonglong select_options, + + if (use_tmp_disk_storage_engine(thd, table, select_options, + force_disk_table, mem_engine)) { +- hton = innodb_hton; ++ //hton = innodb_hton; ++ hton = tse_hton; + } else { + switch (mem_engine) { + case TMP_TABLE_TEMPTABLE: +@@ -2186,7 +2203,9 @@ bool open_tmp_table(TABLE *table) { + assert(table->s->ref_count() == 1 || // not shared, or: + table->s->db_type() == heap_hton || // using right engines + table->s->db_type() == temptable_hton || +- table->s->db_type() == innodb_hton); ++ table->s->db_type() == innodb_hton || ++ table->s->db_type() == myisam_hton || ++ table->s->db_type() == tse_hton); + + int error; + if ((error = table->file->ha_open(table, table->s->table_name.str, O_RDWR, +@@ -2257,7 +2276,7 @@ static bool create_tmp_table_with_fallback(THD *thd, TABLE *table) { + if (error == HA_ERR_RECORD_FILE_FULL && + table->s->db_type() == temptable_hton) { + table->file = get_new_handler( +- table->s, false, share->alloc_for_tmp_file_handler, innodb_hton); ++ table->s, false, share->alloc_for_tmp_file_handler, tse_hton); + error = table->file->create(share->table_name.str, table, &create_info, + nullptr); + } +@@ -2299,6 +2318,8 @@ static void trace_tmp_table(Opt_trace_context *trace, const TABLE *table) { + trace_tmp.add_alnum("record_format", "fixed"); + } else if (table->s->db_type() == temptable_hton) { + trace_tmp.add_alnum("location", "TempTable"); ++ } else if (table->s->db_type() == tse_hton) { ++ trace_tmp.add_alnum("location", "CTC"); + } else { + assert(s->db_type() == heap_hton); + trace_tmp.add_alnum("location", "memory (heap)") +@@ -2344,7 +2365,12 @@ bool instantiate_tmp_table(THD *thd, TABLE *table) { + if (create_tmp_table_with_fallback(thd, table)) return true; + // Make empty record so random data is not written to disk + empty_record(table); ++ } else if (share->db_type() == tse_hton) { ++ if (create_tmp_table_with_fallback(thd, table)) return true; ++ // Make empty record so random data is not written to disk ++ empty_record(table); + } ++ + + // If a heap table, it's created by open_tmp_table(). + if (open_tmp_table(table)) { +@@ -2561,7 +2587,8 @@ bool create_ondisk_from_heap(THD *thd, TABLE *wtable, int error, + TABLE_SHARE share = std::move(*old_share); + assert(share.ha_share == nullptr); + +- share.db_plugin = ha_lock_engine(thd, innodb_hton); ++ //share.db_plugin = ha_lock_engine(thd, innodb_hton); ++ share.db_plugin = ha_lock_engine(thd, tse_hton); + + TABLE_LIST *const wtable_list = wtable->pos_in_table_list; + Derived_refs_iterator ref_it(wtable_list); +@@ -2869,7 +2896,9 @@ void encode_innodb_position(uchar *rowid_bytes, + order. + */ + bool reposition_innodb_cursor(TABLE *table, ha_rows row_num) { +- assert(table->s->db_type() == innodb_hton); ++ assert(table->s->db_type() == tse_hton); ++ my_error(ER_FEATURE_UNSUPPORTED, MYF(0), "reposition_innodb_cursor", "by CTC"); ++ return true; + if (table->file->ha_rnd_init(false)) return true; /* purecov: inspected */ + // Per the explanation above, the wanted InnoDB row has PK=row_num. + uchar rowid_bytes[6]; +diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc +index 1012337..62d2c4b 100644 +--- a/sql/sys_vars.cc ++++ b/sql/sys_vars.cc +@@ -7256,3 +7256,11 @@ static Sys_var_enum Sys_terminology_use_previous( + terminology_use_previous_names, DEFAULT(terminology_use_previous::NONE), + NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(nullptr), + DEPRECATED_VAR("")); ++ ++bool srv_stats_auto_recalc_substitite; ++static Sys_var_bool Sys_substitute_innodb_stats_auto_recalc( ++ "innodb_stats_auto_recalc", ++ "Replacement of the innodb_stats_auto_recalc variable." ++ "the purpose is to prevent errors when setting the innodb_stats_auto_recalc variable" ++ "using meta data in CANTIAN.", ++ GLOBAL_VAR(srv_stats_auto_recalc_substitite), CMD_LINE(OPT_ARG), DEFAULT(false)); +diff --git a/sql/transaction.cc b/sql/transaction.cc +index 9f955ad..178d46e 100644 +--- a/sql/transaction.cc ++++ b/sql/transaction.cc +@@ -240,6 +240,14 @@ bool trans_commit(THD *thd, bool ignore_global_read_lock) { + + if (trans_check_state(thd)) return true; + ++ /* ++ Add modified uncommitted objects before committing attachable ++ read-write transaction. ++ */ ++ if (!thd->is_attachable_rw_transaction_active()) { ++ thd->dd_client()->add_modified_objects_before_commit(); ++ } ++ + thd->server_status &= + ~(SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY); + DBUG_PRINT("info", ("clearing SERVER_STATUS_IN_TRANS")); +@@ -328,6 +336,14 @@ bool trans_commit_implicit(THD *thd, bool ignore_global_read_lock) { + !thd->in_sub_stmt && + !thd->get_transaction()->xid_state()->check_in_xa(false)); + ++ /* ++ Add modified uncommitted objects before committing attachable ++ read-write transaction. ++ */ ++ if (!thd->is_attachable_rw_transaction_active()) { ++ thd->dd_client()->add_modified_objects_before_commit(); ++ } ++ + if (thd->in_multi_stmt_transaction_mode() || + (thd->variables.option_bits & OPTION_TABLE_LOCK)) { + /* Safety if one did "drop table" on locked tables */ +diff --git a/sql/window_iterators.cc b/sql/window_iterators.cc +index cb0f140..a6da724 100644 +--- a/sql/window_iterators.cc ++++ b/sql/window_iterators.cc +@@ -159,7 +159,7 @@ bool buffer_record_somewhere(THD *thd, Window *w, int64 rowno) { + if (create_ondisk_from_heap(thd, t, error, true, &is_duplicate)) + return true; + +- assert(t->s->db_type() == innodb_hton); ++ assert(t->s->db_type() == tse_hton); + if (t->file->ha_rnd_init(true)) return true; /* purecov: inspected */ + + if (!w->m_frame_buffer_positions.empty()) { +@@ -191,6 +191,8 @@ bool buffer_record_somewhere(THD *thd, Window *w, int64 rowno) { + also one-based, so we can use w->frame_buffer_partition_offset() "as is" + to construct the position. + */ ++ my_error(ER_FEATURE_UNSUPPORTED, MYF(0), "encode_innodb_position", "by CTC"); ++ return true; + encode_innodb_position( + w->m_frame_buffer_positions[first_in_partition].m_position, + t->file->ref_length, w->frame_buffer_partition_offset()); +diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc +index ac21c57..345fae9 100644 +--- a/storage/archive/ha_archive.cc ++++ b/storage/archive/ha_archive.cc +@@ -780,7 +780,7 @@ unsigned int ha_archive::pack_row(uchar *record, azio_stream *writer) { + for implementing start_bulk_insert() is that we could skip + setting dirty to true each time. + */ +-int ha_archive::write_row(uchar *buf) { ++int ha_archive::write_row(uchar *buf, bool write_through MY_ATTRIBUTE((unused))) { + int rc; + uchar *read_buf = nullptr; + ulonglong temp_auto; +diff --git a/storage/archive/ha_archive.h b/storage/archive/ha_archive.h +index 4f6bc3a..a777454 100644 +--- a/storage/archive/ha_archive.h ++++ b/storage/archive/ha_archive.h +@@ -139,7 +139,7 @@ class ha_archive : public handler { + int open(const char *name, int mode, uint test_if_locked, + const dd::Table *table_def) override; + int close(void) override; +- int write_row(uchar *buf) override; ++ int write_row(uchar *buf, bool write_through MY_ATTRIBUTE((unused)) = false) override; + int real_write_row(uchar *buf, azio_stream *writer); + int truncate(dd::Table *table_def) override; + int rnd_init(bool scan = true) override; +diff --git a/storage/blackhole/ha_blackhole.cc b/storage/blackhole/ha_blackhole.cc +index ff5ac51..60633eb 100644 +--- a/storage/blackhole/ha_blackhole.cc ++++ b/storage/blackhole/ha_blackhole.cc +@@ -94,7 +94,7 @@ int ha_blackhole::create(const char *, TABLE *, HA_CREATE_INFO *, dd::Table *) { + return 0; + } + +-int ha_blackhole::write_row(uchar *) { ++int ha_blackhole::write_row(uchar *, bool write_through MY_ATTRIBUTE((unused)) = false) { + DBUG_TRACE; + return table->next_number_field ? update_auto_increment() : 0; + } +diff --git a/storage/blackhole/ha_blackhole.h b/storage/blackhole/ha_blackhole.h +index 951ed39..c236a20 100644 +--- a/storage/blackhole/ha_blackhole.h ++++ b/storage/blackhole/ha_blackhole.h +@@ -106,7 +106,7 @@ class ha_blackhole : public handler { + enum thr_lock_type lock_type) override; + + private: +- int write_row(uchar *buf) override; ++ int write_row(uchar *buf, bool write_through MY_ATTRIBUTE((unused))) override; + int update_row(const uchar *old_data, uchar *new_data) override; + int delete_row(const uchar *buf) override; + }; +diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc +index e3998ce..3e74761 100644 +--- a/storage/csv/ha_tina.cc ++++ b/storage/csv/ha_tina.cc +@@ -931,7 +931,7 @@ int ha_tina::close(void) { + of the file and appends the data. In an error case it really should + just truncate to the original position (this is not done yet). + */ +-int ha_tina::write_row(uchar *buf) { ++int ha_tina::write_row(uchar *buf, bool write_through MY_ATTRIBUTE((unused)) = false) { + int size; + DBUG_TRACE; + +diff --git a/storage/csv/ha_tina.h b/storage/csv/ha_tina.h +index df63b48..8bcef46 100644 +--- a/storage/csv/ha_tina.h ++++ b/storage/csv/ha_tina.h +@@ -143,7 +143,7 @@ class ha_tina : public handler { + int open(const char *name, int mode, uint open_options, + const dd::Table *table_def) override; + int close(void) override; +- int write_row(uchar *buf) override; ++ int write_row(uchar *buf, bool write_through MY_ATTRIBUTE((unused))) override; + int update_row(const uchar *old_data, uchar *new_data) override; + int delete_row(const uchar *buf) override; + int rnd_init(bool scan = true) override; +diff --git a/storage/example/ha_example.cc b/storage/example/ha_example.cc +index e773501..9ef9c99 100644 +--- a/storage/example/ha_example.cc ++++ b/storage/example/ha_example.cc +@@ -274,7 +274,7 @@ int ha_example::close(void) { + sql_insert.cc, sql_select.cc, sql_table.cc, sql_udf.cc and sql_update.cc + */ + +-int ha_example::write_row(uchar *) { ++int ha_example::write_row(uchar *, bool write_through MY_ATTRIBUTE((unused)) = false) { + DBUG_TRACE; + /* + Example of a successful write_row. We don't store the data +diff --git a/storage/example/ha_example.h b/storage/example/ha_example.h +index c0515b2..a52c408 100644 +--- a/storage/example/ha_example.h ++++ b/storage/example/ha_example.h +@@ -195,7 +195,7 @@ class ha_example : public handler { + We implement this in ha_example.cc. It's not an obligatory method; + skip it and and MySQL will treat it as not implemented. + */ +- int write_row(uchar *buf) override; ++ int write_row(uchar *buf, bool write_through MY_ATTRIBUTE((unused))) override; + + /** @brief + We implement this in ha_example.cc. It's not an obligatory method; +diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc +index 05f151e..023b64c 100644 +--- a/storage/federated/ha_federated.cc ++++ b/storage/federated/ha_federated.cc +@@ -1706,7 +1706,7 @@ bool ha_federated::append_stmt_insert(String *query) { + sql_insert.cc, sql_select.cc, sql_table.cc, sql_udf.cc, and sql_update.cc. + */ + +-int ha_federated::write_row(uchar *) { ++int ha_federated::write_row(uchar *, bool write_through MY_ATTRIBUTE((unused)) = false) { + char values_buffer[FEDERATED_QUERY_BUFFER_SIZE]; + char insert_field_value_buffer[STRING_BUFFER_USUAL_SIZE]; + Field **field; +diff --git a/storage/federated/ha_federated.h b/storage/federated/ha_federated.h +index 75b29e4..99df51b 100644 +--- a/storage/federated/ha_federated.h ++++ b/storage/federated/ha_federated.h +@@ -218,7 +218,7 @@ class ha_federated : public handler { + + void start_bulk_insert(ha_rows rows) override; + int end_bulk_insert() override; +- int write_row(uchar *buf) override; ++ int write_row(uchar *buf, bool write_through MY_ATTRIBUTE((unused))) override; + int update_row(const uchar *old_data, uchar *new_data) override; + int delete_row(const uchar *buf) override; + int index_init(uint keynr, bool sorted) override; +diff --git a/storage/heap/ha_heap.cc b/storage/heap/ha_heap.cc +index 0d71f25..4178081 100644 +--- a/storage/heap/ha_heap.cc ++++ b/storage/heap/ha_heap.cc +@@ -204,7 +204,7 @@ void ha_heap::update_key_stats() { + key_stat_version = file->s->key_stat_version; + } + +-int ha_heap::write_row(uchar *buf) { ++int ha_heap::write_row(uchar *buf, bool write_through MY_ATTRIBUTE((unused)) = false) { + int res; + ha_statistic_increment(&System_status_var::ha_write_count); + if (table->next_number_field && buf == table->record[0]) { +diff --git a/storage/heap/ha_heap.h b/storage/heap/ha_heap.h +index e1fb36c..85f3ec2 100644 +--- a/storage/heap/ha_heap.h ++++ b/storage/heap/ha_heap.h +@@ -81,7 +81,7 @@ class ha_heap : public handler { + const dd::Table *table_def) override; + int close(void) override; + void set_keys_for_scanning(void); +- int write_row(uchar *buf) override; ++ int write_row(uchar *buf, bool write_through MY_ATTRIBUTE((unused))) override; + int update_row(const uchar *old_data, uchar *new_data) override; + int delete_row(const uchar *buf) override; + void get_auto_increment(ulonglong offset, ulonglong increment, +diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc +index e041606..a7fcecb 100644 +--- a/storage/innobase/handler/ha_innodb.cc ++++ b/storage/innobase/handler/ha_innodb.cc +@@ -8707,7 +8707,7 @@ void innobase_get_multi_value(const TABLE *mysql_table, ulint f_idx, + handle. + @return error code */ + +-int ha_innobase::write_row(uchar *record) /*!< in: a row in MySQL format */ ++int ha_innobase::write_row(uchar *record, bool write_through MY_ATTRIBUTE((unused))) /*!< in: a row in MySQL format */ + { + dberr_t error; + int error_result = 0; +diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h +index 6844bbf..d7b74c6 100644 +--- a/storage/innobase/handler/ha_innodb.h ++++ b/storage/innobase/handler/ha_innodb.h +@@ -127,10 +127,11 @@ class ha_innobase : public handler { + + longlong get_memory_buffer_size() const override; + +- int write_row(uchar *buf) override; ++ int write_row(uchar *buf, bool write_through MY_ATTRIBUTE((unused)) = false) override; + + int update_row(const uchar *old_data, uchar *new_data) override; + ++ + int delete_row(const uchar *buf) override; + + /** Delete all rows from the table. +diff --git a/storage/innobase/handler/ha_innopart.h b/storage/innobase/handler/ha_innopart.h +index 5163227..9dacf52 100644 +--- a/storage/innobase/handler/ha_innopart.h ++++ b/storage/innobase/handler/ha_innopart.h +@@ -996,7 +996,7 @@ class ha_innopart : public ha_innobase, + THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, + thr_lock_type lock_type) override; + +- int write_row(uchar *record) override { ++ int write_row(uchar *record, bool write_through MY_ATTRIBUTE((unused)) = false) override { + bool entered = false; + auto trx = m_prebuilt->trx; + +diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc +index 9b56731..9218f11 100644 +--- a/storage/innobase/handler/i_s.cc ++++ b/storage/innobase/handler/i_s.cc +@@ -72,6 +72,7 @@ this program; if not, write to the Free Software Foundation, Inc., + + #include "my_dbug.h" + ++ + extern mysql_mutex_t LOCK_global_system_variables; + + constexpr char plugin_author[] = PLUGIN_AUTHOR_ORACLE; +@@ -118,6 +119,7 @@ static_assert(I_S_PAGE_TYPE_LAST < (1 << I_S_PAGE_TYPE_BITS), + "i_s_page_type[] is too large"); + + /** Name string for File Page Types */ ++#ifdef DEFAULT_INNODB + static buf_page_desc_t i_s_page_type[] = { + {"ALLOCATED", FIL_PAGE_TYPE_ALLOCATED}, + {"INDEX", FIL_PAGE_INDEX}, +@@ -152,6 +154,7 @@ static buf_page_desc_t i_s_page_type[] = { + {"RTREE_INDEX", I_S_PAGE_TYPE_RTREE}, + {"IBUF_INDEX", I_S_PAGE_TYPE_IBUF}, + {"SDI_INDEX", I_S_PAGE_TYPE_SDI}}; ++#endif + + /** This structure defines information we will fetch from pages + currently cached in the buffer pool. It will be used to populate +@@ -275,6 +278,7 @@ static int i_s_common_deinit(void *p); /*!< in/out: table schema object */ + /** Auxiliary function to store time_t value in MYSQL_TYPE_DATETIME + field. + @return 0 on success */ ++#ifdef DEFAULT_INNODB + static int field_store_time_t( + Field *field, /*!< in/out: target field for storage */ + time_t time) /*!< in: value to store */ +@@ -299,9 +303,11 @@ static int field_store_time_t( + + return (field->store_time(&my_time, MYSQL_TIMESTAMP_DATETIME)); + } ++#endif + + /** Auxiliary function to store char* value in MYSQL_TYPE_STRING field. + @return 0 on success */ ++#ifdef DEFAULT_INNODB + static int field_store_string( + Field *field, /*!< in/out: target field for storage */ + const char *str) /*!< in: NUL-terminated utf-8 string, +@@ -320,10 +326,12 @@ static int field_store_string( + + return (ret); + } ++#endif + + /** Store the name of an index in a MYSQL_TYPE_VARCHAR field. + Handles the names of incomplete secondary indexes. + @return 0 on success */ ++#ifdef DEFAULT_INNODB + static int field_store_index_name( + Field *field, /*!< in/out: target field for + storage */ +@@ -353,6 +361,7 @@ static int field_store_index_name( + + return (ret); + } ++#endif + + /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_trx + Every time any column gets changed, added or removed, please remember +@@ -532,6 +541,7 @@ static ST_FIELD_INFO innodb_trx_fields_info[] = { + /** Read data from cache buffer and fill the INFORMATION_SCHEMA.innodb_trx + table with it. + @return 0 on success */ ++#ifdef DEFAULT_INNODB + static int fill_innodb_trx_from_cache( + trx_i_s_cache_t *cache, /*!< in: cache to read from */ + THD *thd, /*!< in: used to call +@@ -664,6 +674,7 @@ static int fill_innodb_trx_from_cache( + + return 0; + } ++#endif + + /** Bind the dynamic table INFORMATION_SCHEMA.innodb_trx + @return 0 on success */ +@@ -743,6 +754,7 @@ struct st_mysql_plugin i_s_innodb_trx = { + /** Common function to fill any of the dynamic tables: + INFORMATION_SCHEMA.innodb_trx + @return 0 on success */ ++#ifdef DEFAULT_INNODB + static int trx_i_s_common_fill_table( + THD *thd, /*!< in: thread */ + TABLE_LIST *tables, /*!< in/out: tables to fill */ +@@ -813,6 +825,15 @@ static int trx_i_s_common_fill_table( + return 0; + #endif + } ++#else ++static int trx_i_s_common_fill_table( ++ THD *thd, /*!< in: thread */ ++ TABLE_LIST *tables, /*!< in/out: tables to fill */ ++ Item *) /*!< in: condition (not used) */ ++{ ++ return 0; ++} ++#endif + + /* Fields of the dynamic table information_schema.innodb_cmp. + Every time any column gets changed, added or removed, please remember +@@ -870,6 +891,7 @@ static ST_FIELD_INFO i_s_cmp_fields_info[] = { + /** Fill the dynamic table information_schema.innodb_cmp or + innodb_cmp_reset. + @return 0 on success, 1 on failure */ ++#ifdef DEFAULT_INNODB + static int i_s_cmp_fill_low(THD *thd, /*!< in: thread */ + TABLE_LIST *tables, /*!< in/out: tables to fill */ + Item *, /*!< in: condition (ignored) */ +@@ -914,6 +936,15 @@ static int i_s_cmp_fill_low(THD *thd, /*!< in: thread */ + + return status; + } ++#else ++static int i_s_cmp_fill_low(THD *thd, /*!< in: thread */ ++ TABLE_LIST *tables, /*!< in/out: tables to fill */ ++ Item *, /*!< in: condition (ignored) */ ++ ibool reset) /*!< in: TRUE=reset cumulated counts */ ++{ ++ return 0; ++} ++#endif + + /** Fill the dynamic table information_schema.innodb_cmp. + @return 0 on success, 1 on failure */ +@@ -1139,6 +1170,7 @@ static ST_FIELD_INFO i_s_cmp_per_index_fields_info[] = { + information_schema.innodb_cmp_per_index or + information_schema.innodb_cmp_per_index_reset. + @return 0 on success, 1 on failure */ ++#ifdef DEFAULT_INNODB + static int i_s_cmp_per_index_fill_low( + THD *thd, /*!< in: thread */ + TABLE_LIST *tables, /*!< in/out: tables to fill */ +@@ -1234,7 +1266,16 @@ err: + + return status; + } +- ++#else ++static int i_s_cmp_per_index_fill_low( ++ THD *thd, /*!< in: thread */ ++ TABLE_LIST *tables, /*!< in/out: tables to fill */ ++ Item *, /*!< in: condition (ignored) */ ++ ibool reset) /*!< in: TRUE=reset cumulated counts */ ++{ ++ return 0; ++} ++#endif + /** Fill the dynamic table information_schema.innodb_cmp_per_index. + @return 0 on success, 1 on failure */ + static int i_s_cmp_per_index_fill( +@@ -1449,6 +1490,7 @@ innodb_cmpmem_reset. + @param[in] item condition (ignored) + @param[in] reset TRUE=reset cumulated counts + @return 0 on success, 1 on failure */ ++#ifdef DEFAULT_INNODB + static int i_s_cmpmem_fill_low(THD *thd, TABLE_LIST *tables, Item *item, + ibool reset) { + int status = 0; +@@ -1512,6 +1554,12 @@ static int i_s_cmpmem_fill_low(THD *thd, TABLE_LIST *tables, Item *item, + + return status; + } ++#else ++static int i_s_cmpmem_fill_low(THD *thd, TABLE_LIST *tables, Item *item, ibool reset) ++{ ++ return 0; ++} ++#endif + + /** Fill the dynamic table information_schema.innodb_cmpmem. + @return 0 on success, 1 on failure */ +@@ -1793,6 +1841,7 @@ static ST_FIELD_INFO innodb_metrics_fields_info[] = { + + /** Fill the information schema metrics table. + @return 0 on success */ ++#ifdef DEFAULT_INNODB + static int i_s_metrics_fill( + THD *thd, /*!< in: thread */ + TABLE *table_to_fill) /*!< in/out: fill this table */ +@@ -2036,9 +2085,11 @@ static int i_s_metrics_fill( + + return 0; + } ++#endif + + /** Function to fill information schema metrics tables. + @return 0 on success */ ++#ifdef DEFAULT_INNODB + static int i_s_metrics_fill_table( + THD *thd, /*!< in: thread */ + TABLE_LIST *tables, /*!< in/out: tables to fill */ +@@ -2055,6 +2106,15 @@ static int i_s_metrics_fill_table( + + return 0; + } ++#else ++static int i_s_metrics_fill_table( ++ THD *thd, /*!< in: thread */ ++ TABLE_LIST *tables, /*!< in/out: tables to fill */ ++ Item *) /*!< in: condition (not used) */ ++{ ++ return 0; ++} ++#endif + /** Bind the dynamic table INFORMATION_SCHEMA.innodb_metrics + @return 0 on success */ + static int innodb_metrics_init(void *p) /*!< in/out: table schema object */ +@@ -2141,6 +2201,7 @@ static ST_FIELD_INFO i_s_stopword_fields_info[] = { + + /** Fill the dynamic table information_schema.innodb_ft_default_stopword. + @return 0 on success, 1 on failure */ ++#ifdef DEFAULT_INNODB + static int i_s_stopword_fill(THD *thd, /*!< in: thread */ + TABLE_LIST *tables, /*!< in/out: tables to fill */ + Item *) /*!< in: condition (not used) */ +@@ -2164,7 +2225,14 @@ static int i_s_stopword_fill(THD *thd, /*!< in: thread */ + + return 0; + } +- ++#else ++static int i_s_stopword_fill(THD *thd, /*!< in: thread */ ++ TABLE_LIST *tables, /*!< in/out: tables to fill */ ++ Item *) /*!< in: condition (not used) */ ++{ ++ return 0; ++} ++#endif + /** Bind the dynamic table information_schema.innodb_ft_default_stopword. + @return 0 on success */ + static int i_s_stopword_init(void *p) /*!< in/out: table schema object */ +@@ -2252,6 +2320,7 @@ static ST_FIELD_INFO i_s_fts_doc_fields_info[] = { + /** Fill the dynamic table INFORMATION_SCHEMA.INNODB_FT_DELETED or + INFORMATION_SCHEMA.INNODB_FT_BEING_DELETED + @return 0 on success, 1 on failure */ ++#ifdef DEFAULT_INNODB + static int i_s_fts_deleted_generic_fill( + THD *thd, /*!< in: thread */ + TABLE_LIST *tables, /*!< in/out: tables to fill */ +@@ -2336,7 +2405,15 @@ static int i_s_fts_deleted_generic_fill( + + return 0; + } +- ++#else ++static int i_s_fts_deleted_generic_fill( ++ THD *thd, /*!< in: thread */ ++ TABLE_LIST *tables, /*!< in/out: tables to fill */ ++ ibool being_deleted) /*!< in: BEING_DELTED table */ ++{ ++ return 0; ++} ++#endif + /** Fill the dynamic table INFORMATION_SCHEMA.INNODB_FT_DELETED + @return 0 on success, 1 on failure */ + static int i_s_fts_deleted_fill( +@@ -2553,6 +2630,7 @@ static ST_FIELD_INFO i_s_fts_index_fields_info[] = { + /** Go through the Doc Node and its ilist, fill the dynamic table + INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHED for one FTS index on the table. + @return 0 on success, 1 on failure */ ++#ifdef DEFAULT_INNODB + static int i_s_fts_index_cache_fill_one_index( + fts_index_cache_t *index_cache, /*!< in: FTS index cache */ + THD *thd, /*!< in: thread */ +@@ -2642,8 +2720,11 @@ static int i_s_fts_index_cache_fill_one_index( + + return 0; + } ++#endif ++ + /** Fill the dynamic table INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHED + @return 0 on success, 1 on failure */ ++#ifdef DEFAULT_INNODB + static int i_s_fts_index_cache_fill( + THD *thd, /*!< in: thread */ + TABLE_LIST *tables, /*!< in/out: tables to fill */ +@@ -2707,7 +2788,15 @@ static int i_s_fts_index_cache_fill( + + return 0; + } +- ++#else ++static int i_s_fts_index_cache_fill( ++ THD *thd, /*!< in: thread */ ++ TABLE_LIST *tables, /*!< in/out: tables to fill */ ++ Item *) /*!< in: condition (ignored) */ ++{ ++ return 0; ++} ++#endif + /** Bind the dynamic table INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE + @return 0 on success */ + static int i_s_fts_index_cache_init(void *p) /*!< in/out: table schema object */ +@@ -2780,6 +2869,7 @@ struct st_mysql_plugin i_s_innodb_ft_index_cache = { + /** Go through a FTS index auxiliary table, fetch its rows and fill + FTS word cache structure. + @return DB_SUCCESS on success, otherwise error code */ ++#ifdef DEFAULT_INNODB + static dberr_t i_s_fts_index_table_fill_selected( + dict_index_t *index, /*!< in: FTS index */ + ib_vector_t *words, /*!< in/out: vector to hold +@@ -2867,8 +2957,10 @@ static dberr_t i_s_fts_index_table_fill_selected( + + return (error); + } ++#endif + + /** Free words. */ ++#ifdef DEFAULT_INNODB + static void i_s_fts_index_table_free_one_fetch( + ib_vector_t *words) /*!< in: words fetched */ + { +@@ -2889,9 +2981,11 @@ static void i_s_fts_index_table_free_one_fetch( + + ib_vector_reset(words); + } ++#endif + + /** Go through words, fill INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE. + @return 0 on success, 1 on failure */ ++#ifdef DEFAULT_INNODB + static int i_s_fts_index_table_fill_one_fetch( + CHARSET_INFO *index_charset, /*!< in: FTS index charset */ + THD *thd, /*!< in: thread */ +@@ -2986,10 +3080,12 @@ static int i_s_fts_index_table_fill_one_fetch( + + return ret; + } ++#endif + + /** Go through a FTS index and its auxiliary tables, fetch rows in each table + and fill INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE. + @return 0 on success, 1 on failure */ ++#ifdef DEFAULT_INNODB + static int i_s_fts_index_table_fill_one_index( + dict_index_t *index, /*!< in: FTS index */ + THD *thd, /*!< in: thread */ +@@ -3065,8 +3161,11 @@ func_exit: + + return ret; + } ++#endif ++ + /** Fill the dynamic table INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE + @return 0 on success, 1 on failure */ ++#ifdef DEFAULT_INNODB + static int i_s_fts_index_table_fill( + THD *thd, /*!< in: thread */ + TABLE_LIST *tables, /*!< in/out: tables to fill */ +@@ -3117,7 +3216,15 @@ static int i_s_fts_index_table_fill( + + return 0; + } +- ++#else ++static int i_s_fts_index_table_fill( ++ THD *thd, /*!< in: thread */ ++ TABLE_LIST *tables, /*!< in/out: tables to fill */ ++ Item *) /*!< in: condition (ignored) */ ++{ ++ return 0; ++} ++#endif + /** Bind the dynamic table INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE + @return 0 on success */ + static int i_s_fts_index_table_init(void *p) /*!< in/out: table schema object */ +@@ -3206,12 +3313,15 @@ static ST_FIELD_INFO i_s_fts_config_fields_info[] = { + + END_OF_ST_FIELD_INFO}; + ++#ifdef DEFAULT_INNODB + static const char *fts_config_key[] = { + FTS_OPTIMIZE_LIMIT_IN_SECS, FTS_SYNCED_DOC_ID, FTS_STOPWORD_TABLE_NAME, + FTS_USE_STOPWORD, nullptr}; ++#endif + + /** Fill the dynamic table INFORMATION_SCHEMA.INNODB_FT_CONFIG + @return 0 on success, 1 on failure */ ++#ifdef DEFAULT_INNODB + static int i_s_fts_config_fill( + THD *thd, /*!< in: thread */ + TABLE_LIST *tables, /*!< in/out: tables to fill */ +@@ -3322,7 +3432,15 @@ static int i_s_fts_config_fill( + + return 0; + } +- ++#else ++static int i_s_fts_config_fill( ++ THD *thd, /*!< in: thread */ ++ TABLE_LIST *tables, /*!< in/out: tables to fill */ ++ Item *) /*!< in: condition (ignored) */ ++{ ++ return 0; ++} ++#endif + /** Bind the dynamic table INFORMATION_SCHEMA.INNODB_FT_CONFIG + @return 0 on success */ + static int i_s_fts_config_init(void *p) /*!< in/out: table schema object */ +@@ -3438,6 +3556,7 @@ typedef std::vector> + /** Fill Information Schema table INNODB_TEMP_TABLE_INFO for a particular + temp-table + @return 0 on success, 1 on failure */ ++#ifdef DEFAULT_INNODB + static int i_s_innodb_temp_table_info_fill( + THD *thd, /*!< in: thread */ + TABLE_LIST *tables, /*!< in/out: tables +@@ -3464,10 +3583,12 @@ static int i_s_innodb_temp_table_info_fill( + + return schema_table_store_record(thd, table); + } ++#endif + + /** Populate current table information to cache + @param[in] table table + @param[in,out] cache populate data in this cache */ ++#ifdef DEFAULT_INNODB + static void innodb_temp_table_populate_cache(const dict_table_t *table, + temp_table_info_t *cache) { + cache->m_table_id = table->id; +@@ -3483,10 +3604,12 @@ static void innodb_temp_table_populate_cache(const dict_table_t *table, + + cache->m_space_id = table->space; + } ++#endif + + /** This function will iterate over all available table and will fill + stats for temp-tables to INNODB_TEMP_TABLE_INFO. + @return 0 on success, 1 on failure */ ++#ifdef DEFAULT_INNODB + static int i_s_innodb_temp_table_info_fill_table( + THD *thd, /*!< in: thread */ + TABLE_LIST *tables, /*!< in/out: tables to fill */ +@@ -3533,6 +3656,15 @@ static int i_s_innodb_temp_table_info_fill_table( + + return status; + } ++#else ++static int i_s_innodb_temp_table_info_fill_table( ++ THD *thd, /*!< in: thread */ ++ TABLE_LIST *tables, /*!< in/out: tables to fill */ ++ Item *) /*!< in: condition (ignored) */ ++{ ++ return 0; ++} ++#endif + + /** Bind the dynamic table INFORMATION_SCHEMA.INNODB_TEMP_TABLE_INFO. + @return 0 on success, 1 on failure */ +@@ -3841,6 +3973,7 @@ static ST_FIELD_INFO i_s_innodb_buffer_stats_fields_info[] = { + /** Fill Information Schema table INNODB_BUFFER_POOL_STATS for a particular + buffer pool + @return 0 on success, 1 on failure */ ++#ifdef DEFAULT_INNODB + static int i_s_innodb_stats_fill( + THD *thd, /*!< in: thread */ + TABLE_LIST *tables, /*!< in/out: tables to fill */ +@@ -3935,10 +4068,12 @@ static int i_s_innodb_stats_fill( + + return schema_table_store_record(thd, table); + } ++#endif + + /** This is the function that loops through each buffer pool and fetch buffer + pool stats to information schema table: I_S_INNODB_BUFFER_POOL_STATS + @return 0 on success, 1 on failure */ ++#ifdef DEFAULT_INNODB + static int i_s_innodb_buffer_stats_fill_table( + THD *thd, /*!< in: thread */ + TABLE_LIST *tables, /*!< in/out: tables to fill */ +@@ -3978,7 +4113,15 @@ static int i_s_innodb_buffer_stats_fill_table( + + return status; + } +- ++#else ++static int i_s_innodb_buffer_stats_fill_table( ++ THD *thd, /*!< in: thread */ ++ TABLE_LIST *tables, /*!< in/out: tables to fill */ ++ Item *) /*!< in: condition (ignored) */ ++{ ++ return 0; ++} ++#endif + /** Bind the dynamic table INFORMATION_SCHEMA.INNODB_BUFFER_POOL_STATS. + @return 0 on success, 1 on failure */ + static int i_s_innodb_buffer_pool_stats_init( +@@ -4201,6 +4344,7 @@ static ST_FIELD_INFO i_s_innodb_buffer_page_fields_info[] = { + /** Fill Information Schema table INNODB_BUFFER_PAGE with information + cached in the buf_page_info_t array + @return 0 on success, 1 on failure */ ++#ifdef DEFAULT_INNODB + static int i_s_innodb_buffer_page_fill( + THD *thd, /*!< in: thread */ + TABLE_LIST *tables, /*!< in/out: tables to fill */ +@@ -4366,8 +4510,10 @@ static int i_s_innodb_buffer_page_fill( + + return 0; + } ++#endif + + /** Set appropriate page type to a buf_page_info_t structure */ ++#ifdef DEFAULT_INNODB + static void i_s_innodb_set_page_type( + buf_page_info_t *page_info, /*!< in/out: structure to fill with + scanned info */ +@@ -4430,9 +4576,12 @@ static void i_s_innodb_set_page_type( + mach_read_from_4(frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID); + } + } ++#endif ++ + /** Scans pages in the buffer cache, and collect their general information + into the buf_page_info_t array which is zero-filled. So any fields + that are not initialized in the function will default to 0 */ ++#ifdef DEFAULT_INNODB + static void i_s_innodb_buffer_page_get_info( + const buf_page_t *bpage, /*!< in: buffer pool page to scan */ + ulint pool_id, /*!< in: buffer pool id */ +@@ -4519,10 +4668,12 @@ static void i_s_innodb_buffer_page_get_info( + + mutex_exit(mutex); + } ++#endif + + /** This is the function that goes through each block of the buffer pool + and fetch information to information schema tables: INNODB_BUFFER_PAGE. + @return 0 on success, 1 on failure */ ++#ifdef DEFAULT_INNODB + static int i_s_innodb_fill_buffer_pool( + THD *thd, /*!< in: thread */ + TABLE_LIST *tables, /*!< in/out: tables to fill */ +@@ -4592,10 +4743,12 @@ static int i_s_innodb_fill_buffer_pool( + + return status; + } ++#endif + + /** Fill page information for pages in InnoDB buffer pool to the + dynamic table INFORMATION_SCHEMA.INNODB_BUFFER_PAGE + @return 0 on success, 1 on failure */ ++#ifdef DEFAULT_INNODB + static int i_s_innodb_buffer_page_fill_table( + THD *thd, /*!< in: thread */ + TABLE_LIST *tables, /*!< in/out: tables to fill */ +@@ -4628,6 +4781,15 @@ static int i_s_innodb_buffer_page_fill_table( + + return status; + } ++#else ++static int i_s_innodb_buffer_page_fill_table( ++ THD *thd, /*!< in: thread */ ++ TABLE_LIST *tables, /*!< in/out: tables to fill */ ++ Item *) /*!< in: condition (ignored) */ ++{ ++ return 0; ++} ++#endif + + /** Bind the dynamic table INFORMATION_SCHEMA.INNODB_BUFFER_PAGE. + @return 0 on success, 1 on failure */ +@@ -4844,6 +5006,7 @@ static ST_FIELD_INFO i_s_innodb_buf_page_lru_fields_info[] = { + /** Fill Information Schema table INNODB_BUFFER_PAGE_LRU with information + cached in the buf_page_info_t array + @return 0 on success, 1 on failure */ ++#ifdef DEFAULT_INNODB + static int i_s_innodb_buf_page_lru_fill( + THD *thd, /*!< in: thread */ + TABLE_LIST *tables, /*!< in/out: tables to fill */ +@@ -4998,6 +5161,7 @@ static int i_s_innodb_buf_page_lru_fill( + + return 0; + } ++#endif + + /** This is the function that goes through buffer pool's LRU list + and fetch information to INFORMATION_SCHEMA.INNODB_BUFFER_PAGE_LRU. +@@ -5006,6 +5170,7 @@ and fetch information to INFORMATION_SCHEMA.INNODB_BUFFER_PAGE_LRU. + @param[in] buf_pool buffer pool to scan + @param[in] pool_id buffer pool id + @return 0 on success, 1 on failure */ ++#ifdef DEFAULT_INNODB + static int i_s_innodb_fill_buffer_lru(THD *thd, TABLE_LIST *tables, + buf_pool_t *buf_pool, + const ulint pool_id) { +@@ -5063,10 +5228,12 @@ exit: + + return status; + } ++#endif + + /** Fill page information for pages in InnoDB buffer pool to the + dynamic table INFORMATION_SCHEMA.INNODB_BUFFER_PAGE_LRU + @return 0 on success, 1 on failure */ ++#ifdef DEFAULT_INNODB + static int i_s_innodb_buf_page_lru_fill_table( + THD *thd, /*!< in: thread */ + TABLE_LIST *tables, /*!< in/out: tables to fill */ +@@ -5099,6 +5266,15 @@ static int i_s_innodb_buf_page_lru_fill_table( + + return status; + } ++#else ++static int i_s_innodb_buf_page_lru_fill_table( ++ THD *thd, /*!< in: thread */ ++ TABLE_LIST *tables, /*!< in/out: tables to fill */ ++ Item *) /*!< in: condition (ignored) */ ++{ ++ return 0; ++} ++#endif + + /** Bind the dynamic table INFORMATION_SCHEMA.INNODB_BUFFER_PAGE_LRU. + @return 0 on success, 1 on failure */ +@@ -5259,6 +5435,7 @@ from INNODB_TABLES. + @param[in] table table obj + @param[in,out] table_to_fill fill this table + @return 0 on success */ ++#ifdef DEFAULT_INNODB + static int i_s_dict_fill_innodb_tables(THD *thd, dict_table_t *table, + TABLE *table_to_fill) { + Field **fields; +@@ -5314,12 +5491,14 @@ static int i_s_dict_fill_innodb_tables(THD *thd, dict_table_t *table, + + return 0; + } ++#endif + + /** Function to go through each record in INNODB_TABLES table, and fill the + information_schema.innodb_tables table with related table information + @param[in] thd thread + @param[in,out] tables tables to fill + @return 0 on success */ ++#ifdef DEFAULT_INNODB + static int i_s_innodb_tables_fill_table(THD *thd, TABLE_LIST *tables, Item *) { + btr_pcur_t pcur; + const rec_t *rec; +@@ -5414,6 +5593,11 @@ static int i_s_innodb_tables_fill_table(THD *thd, TABLE_LIST *tables, Item *) { + + return 0; + } ++#else ++static int i_s_innodb_tables_fill_table(THD *thd, TABLE_LIST *tables, Item *) { ++ return 0; ++} ++#endif + + /** Bind the dynamic table INFORMATION_SCHEMA.innodb_tables + @param[in,out] p table schema object +@@ -5564,6 +5748,7 @@ from INNODB_TABLES. + @param[in] ref_count table reference count + @param[in,out] table_to_fill fill this table + @return 0 on success */ ++#ifdef DEFAULT_INNODB + static int i_s_dict_fill_innodb_tablestats(THD *thd, dict_table_t *table, + ulint ref_count, + TABLE *table_to_fill) { +@@ -5614,6 +5799,7 @@ static int i_s_dict_fill_innodb_tablestats(THD *thd, dict_table_t *table, + + return 0; + } ++#endif + + /** Function to go through each record in INNODB_TABLES table, and fill the + information_schema.innodb_tablestats table with table statistics +@@ -5621,6 +5807,7 @@ related information + @param[in] thd thread + @param[in,out] tables tables to fill + @return 0 on success */ ++#ifdef DEFAULT_INNODB + static int i_s_innodb_tables_fill_table_stats(THD *thd, TABLE_LIST *tables, + Item *) { + btr_pcur_t pcur; +@@ -5693,6 +5880,12 @@ static int i_s_innodb_tables_fill_table_stats(THD *thd, TABLE_LIST *tables, + + return 0; + } ++#else ++static int i_s_innodb_tables_fill_table_stats(THD *thd, TABLE_LIST *tables, Item *) ++{ ++ return 0; ++} ++#endif + + /** Bind the dynamic table INFORMATION_SCHEMA.innodb_tablestats + @param[in,out] p table schema object +@@ -5835,6 +6028,7 @@ collected index information + @param[in] index dict_index_t obj + @param[in,out] table_to_fill fill this table + @return 0 on success */ ++#ifdef DEFAULT_INNODB + static int i_s_dict_fill_innodb_indexes(THD *thd, const dict_index_t *index, + TABLE *table_to_fill) { + Field **fields; +@@ -5868,12 +6062,14 @@ static int i_s_dict_fill_innodb_indexes(THD *thd, const dict_index_t *index, + + return 0; + } ++#endif + + /** Function to go through each record in INNODB_INDEXES table, and fill the + information_schema.innodb_indexes table with related index information + @param[in] thd thread + @param[in,out] tables tables to fill + @return 0 on success */ ++#ifdef DEFAULT_INNODB + static int i_s_innodb_indexes_fill_table(THD *thd, TABLE_LIST *tables, Item *) { + btr_pcur_t pcur; + const rec_t *rec; +@@ -5941,7 +6137,11 @@ static int i_s_innodb_indexes_fill_table(THD *thd, TABLE_LIST *tables, Item *) { + + return 0; + } +- ++#else ++static int i_s_innodb_indexes_fill_table(THD *thd, TABLE_LIST *tables, Item *) { ++ return 0; ++} ++#endif + /** Bind the dynamic table INFORMATION_SCHEMA.innodb_indexes + @param[in,out] p table schema object + @return 0 on success */ +@@ -6081,6 +6281,7 @@ static ST_FIELD_INFO innodb_columns_fields_info[] = { + @param[in,out] field field to store default value + @param[in] default_val default value to fill + @return 0 on success */ ++#ifdef DEFAULT_INNODB + static int field_blob_store(Field *field, dict_col_default_t *default_val) { + int ret = 0; + +@@ -6098,6 +6299,7 @@ static int field_blob_store(Field *field, dict_col_default_t *default_val) { + + return (ret); + } ++#endif + + /** Function to populate the information_schema.innodb_columns with + related column information +@@ -6108,6 +6310,7 @@ related column information + @param[in] nth_v_col virtual column, its sequence number + @param[in,out] table_to_fill fill this table + @return 0 on success */ ++#ifdef DEFAULT_INNODB + static int i_s_dict_fill_innodb_columns(THD *thd, table_id_t table_id, + const char *col_name, + dict_col_t *column, ulint nth_v_col, +@@ -6148,7 +6351,9 @@ static int i_s_dict_fill_innodb_columns(THD *thd, table_id_t table_id, + + return 0; + } ++#endif + ++#ifdef DEFAULT_INNODB + static void process_rows(THD *thd, TABLE_LIST *tables, const rec_t *rec, + dict_table_t *dd_table, btr_pcur_t &pcur, mtr_t &mtr, + mem_heap_t *heap, bool is_partition) { +@@ -6236,12 +6441,14 @@ static void process_rows(THD *thd, TABLE_LIST *tables, const rec_t *rec, + rec = dd_getnext_system_rec(&pcur, &mtr); + } + } ++#endif + + /** Function to fill information_schema.innodb_columns with information + collected by scanning INNODB_COLUMNS table. + @param[in] thd thread + @param[in,out] tables tables to fill + @return 0 on success */ ++#ifdef DEFAULT_INNODB + static int i_s_innodb_columns_fill_table(THD *thd, TABLE_LIST *tables, Item *) { + btr_pcur_t pcur; + const rec_t *rec; +@@ -6286,7 +6493,11 @@ static int i_s_innodb_columns_fill_table(THD *thd, TABLE_LIST *tables, Item *) { + + return 0; + } +- ++#else ++static int i_s_innodb_columns_fill_table(THD *thd, TABLE_LIST *tables, Item *) { ++ return 0; ++} ++#endif + /** Bind the dynamic table INFORMATION_SCHEMA.innodb_columns + @param[in,out] p table schema object + @return 0 on success */ +@@ -6396,6 +6607,7 @@ param[in] pos virtual column position + param[in] base_pos base column position + param[in,out] table_to_fill fill this table + @return 0 on success */ ++#ifdef DEFAULT_INNODB + static int i_s_dict_fill_innodb_virtual(THD *thd, table_id_t table_id, + ulint pos, ulint base_pos, + TABLE *table_to_fill) { +@@ -6415,6 +6627,7 @@ static int i_s_dict_fill_innodb_virtual(THD *thd, table_id_t table_id, + + return 0; + } ++#endif + + /** Function to fill information_schema.innodb_virtual with information + collected by scanning INNODB_VIRTUAL table. +@@ -6422,6 +6635,7 @@ param[in] thd thread + param[in,out] tables tables to fill + param[in] item condition (not used) + @return 0 on success */ ++#ifdef DEFAULT_INNODB + static int i_s_innodb_virtual_fill_table(THD *thd, TABLE_LIST *tables, Item *) { + btr_pcur_t pcur; + const rec_t *rec; +@@ -6481,6 +6695,11 @@ static int i_s_innodb_virtual_fill_table(THD *thd, TABLE_LIST *tables, Item *) { + + return 0; + } ++#else ++static int i_s_innodb_virtual_fill_table(THD *thd, TABLE_LIST *tables, Item *) { ++ return 0; ++} ++#endif + + /** Bind the dynamic table INFORMATION_SCHEMA.innodb_virtual + param[in,out] p table schema object +@@ -6677,6 +6896,7 @@ collected by scanning INNODB_TABLESPACESS table. + @param[in] state tablespace state + @param[in,out] table_to_fill fill this table + @return 0 on success */ ++#ifdef DEFAULT_INNODB + static int i_s_dict_fill_innodb_tablespaces( + THD *thd, space_id_t space_id, const char *name, uint32_t flags, + uint32 server_version, uint32 space_version, bool is_encrypted, +@@ -6808,6 +7028,7 @@ static int i_s_dict_fill_innodb_tablespaces( + + return 0; + } ++#endif + + /** Function to populate INFORMATION_SCHEMA.INNODB_TABLESPACES table. + Loop through each record in INNODB_TABLESPACES, and extract the column +@@ -6815,6 +7036,7 @@ information and fill the INFORMATION_SCHEMA.INNODB_TABLESPACES table. + @param[in] thd thread + @param[in,out] tables tables to fill + @return 0 on success */ ++#ifdef DEFAULT_INNODB + static int i_s_innodb_tablespaces_fill_table(THD *thd, TABLE_LIST *tables, + Item *) { + btr_pcur_t pcur; +@@ -6877,6 +7099,12 @@ static int i_s_innodb_tablespaces_fill_table(THD *thd, TABLE_LIST *tables, + + return 0; + } ++#else ++static int i_s_innodb_tablespaces_fill_table(THD *thd, TABLE_LIST *tables, Item *) ++{ ++ return 0; ++} ++#endif + /** Bind the dynamic table INFORMATION_SCHEMA.INNODB_TABLESPACES + @param[in,out] p table schema object + @return 0 on success */ +@@ -6985,6 +7213,7 @@ static ST_FIELD_INFO innodb_cached_indexes_fields_info[] = { + @param[in] index_id index id + @param[in,out] table_to_fill fill this table + @return 0 on success */ ++#ifdef DEFAULT_INNODB + static int i_s_fill_innodb_cached_indexes_row(THD *thd, space_id_t space_id, + ulint index_id, + TABLE *table_to_fill) { +@@ -7009,12 +7238,14 @@ static int i_s_fill_innodb_cached_indexes_row(THD *thd, space_id_t space_id, + + return 0; + } ++#endif + + /** Go through each record in INNODB_INDEXES, and fill + INFORMATION_SCHEMA.INNODB_CACHED_INDEXES. + @param[in] thd thread + @param[in,out] tables tables to fill + @return 0 on success */ ++#ifdef DEFAULT_INNODB + static int i_s_innodb_cached_indexes_fill_table(THD *thd, TABLE_LIST *tables, + Item * /* not used */) { + MDL_ticket *mdl = nullptr; +@@ -7078,6 +7309,12 @@ static int i_s_innodb_cached_indexes_fill_table(THD *thd, TABLE_LIST *tables, + + return 0; + } ++#else ++static int i_s_innodb_cached_indexes_fill_table(THD *thd, TABLE_LIST *tables, Item * /* not used */) ++{ ++ return 0; ++} ++#endif + + /** Bind the dynamic table INFORMATION_SCHEMA.INNODB_CACHED_INDEXES. + @param[in,out] p table schema object +@@ -7204,6 +7441,7 @@ static ST_FIELD_INFO innodb_session_temp_tablespaces_fields_info[] = { + @param[in] ts temp tablespace object + @param[in,out] table_to_fill fill this table + @return 0 on success */ ++#ifdef DEFAULT_INNODB + static int i_s_innodb_session_temp_tablespaces_fill_one( + THD *thd, const ibt::Tablespace *ts, TABLE *table_to_fill) { + Field **fields; +@@ -7251,12 +7489,14 @@ static int i_s_innodb_session_temp_tablespaces_fill_one( + + return 0; + } ++#endif + + /** Function to populate INFORMATION_SCHEMA.INNODB_SESSION_TEMPORARY_TABLESPACES + table. Iterate over the in-memory structure and fill the table + @param[in] thd thread + @param[in,out] tables tables to fill + @return 0 on success */ ++#ifdef DEFAULT_INNODB + static int i_s_innodb_session_temp_tablespaces_fill(THD *thd, + TABLE_LIST *tables, + Item *) { +@@ -7283,7 +7523,12 @@ static int i_s_innodb_session_temp_tablespaces_fill(THD *thd, + + return 0; + } +- ++#else ++static int i_s_innodb_session_temp_tablespaces_fill(THD *thd, TABLE_LIST *tables, Item *) ++{ ++ return 0; ++} ++#endif + /** Bind the dynamic table + INFORMATION_SCHEMA.INNODB_SESSION_TEMPORARY_TABLESPACES + @param[in,out] p table schema object +diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc +index d05f758..cc4ebfc 100644 +--- a/storage/myisam/ha_myisam.cc ++++ b/storage/myisam/ha_myisam.cc +@@ -825,7 +825,7 @@ int ha_myisam::close(void) { + return err; + } + +-int ha_myisam::write_row(uchar *buf) { ++int ha_myisam::write_row(uchar *buf, bool write_through MY_ATTRIBUTE((unused)) = false) { + ha_statistic_increment(&System_status_var::ha_write_count); + + /* +@@ -1786,7 +1786,7 @@ int ha_myisam::create(const char *name, TABLE *table_arg, + : (ulonglong)0); + create_info.data_file_length = + ((ulonglong)share->max_rows * share->avg_row_length); +- create_info.language = share->table_charset->number; ++ //create_info.language = share->table_charset->number; + + #ifndef _WIN32 + if (my_enable_symlinks) { +diff --git a/storage/myisam/ha_myisam.h b/storage/myisam/ha_myisam.h +index 98ca35d..c00f71d 100644 +--- a/storage/myisam/ha_myisam.h ++++ b/storage/myisam/ha_myisam.h +@@ -114,7 +114,7 @@ class ha_myisam : public handler { + int open(const char *name, int mode, uint test_if_locked, + const dd::Table *table_def) override; + int close(void) override; +- int write_row(uchar *buf) override; ++ int write_row(uchar *buf, bool write_through MY_ATTRIBUTE((unused))) override; + int update_row(const uchar *old_data, uchar *new_data) override; + int delete_row(const uchar *buf) override; + int index_read_map(uchar *buf, const uchar *key, key_part_map keypart_map, +diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc +index 2107967..cc4f0a7 100644 +--- a/storage/myisammrg/ha_myisammrg.cc ++++ b/storage/myisammrg/ha_myisammrg.cc +@@ -982,7 +982,7 @@ int ha_myisammrg::close(void) { + return rc; + } + +-int ha_myisammrg::write_row(uchar *buf) { ++int ha_myisammrg::write_row(uchar *buf, bool write_through MY_ATTRIBUTE((unused)) = false) { + DBUG_TRACE; + assert(this->file->children_attached); + ha_statistic_increment(&System_status_var::ha_write_count); +diff --git a/storage/myisammrg/ha_myisammrg.h b/storage/myisammrg/ha_myisammrg.h +index 11c0fc0..42050e1 100644 +--- a/storage/myisammrg/ha_myisammrg.h ++++ b/storage/myisammrg/ha_myisammrg.h +@@ -123,7 +123,7 @@ class ha_myisammrg : public handler { + int detach_children(void); + handler *clone(const char *name, MEM_ROOT *mem_root) override; + int close(void) override; +- int write_row(uchar *buf) override; ++ int write_row(uchar *buf, bool write_through MY_ATTRIBUTE((unused))) override; + int update_row(const uchar *old_data, uchar *new_data) override; + int delete_row(const uchar *buf) override; + int index_read_map(uchar *buf, const uchar *key, key_part_map keypart_map, +diff --git a/storage/ndb/plugin/ha_ndbcluster.cc b/storage/ndb/plugin/ha_ndbcluster.cc +index c29d260..9d13607 100644 +--- a/storage/ndb/plugin/ha_ndbcluster.cc ++++ b/storage/ndb/plugin/ha_ndbcluster.cc +@@ -12045,7 +12045,7 @@ static int drop_database_impl(THD *thd, + return 0; + } + +-static void ndbcluster_drop_database(handlerton *, char *path) { ++static bool ndbcluster_drop_database(handlerton *, char *path) { + THD *thd = current_thd; + DBUG_TRACE; + DBUG_PRINT("enter", ("path: '%s'", path)); +@@ -12056,18 +12056,20 @@ static void ndbcluster_drop_database(handlerton *, char *path) { + + if (!schema_dist_client.prepare(db, "")) { + /* Don't allow drop database unless schema distribution is ready */ +- return; ++ return true; + } + + if (drop_database_impl(thd, schema_dist_client, db) != 0) { +- return; ++ return true; + } + + if (!schema_dist_client.drop_db(db)) { + // NOTE! There is currently no way to report an error from this + // function, just log an error and proceed + ndb_log_error("Failed to distribute 'DROP DATABASE %s'", db); ++ return true; + } ++ return false; + } + + /** +diff --git a/storage/ndb/plugin/ha_ndbcluster_binlog.cc b/storage/ndb/plugin/ha_ndbcluster_binlog.cc +index c310cf6..9dec5d4 100644 +--- a/storage/ndb/plugin/ha_ndbcluster_binlog.cc ++++ b/storage/ndb/plugin/ha_ndbcluster_binlog.cc +@@ -496,7 +496,7 @@ static int ndbcluster_binlog_index_purge_file(THD *thd, const char *filename) { + -- privilege tables have been modified + */ + +-static void ndbcluster_binlog_log_query(handlerton *, THD *thd, ++static bool ndbcluster_binlog_log_query(handlerton *, THD *thd, + enum_binlog_command binlog_command, + const char *query, uint query_length, + const char *db, const char *) { +@@ -515,7 +515,7 @@ static void ndbcluster_binlog_log_query(handlerton *, THD *thd, + // NOTE! As there is no way return error, this may have to be + // revisited, the prepare should be done + // much earlier where it can return an error for the query +- return; ++ return true; + } + + // Generate the id, version +@@ -527,12 +527,18 @@ static void ndbcluster_binlog_log_query(handlerton *, THD *thd, + if (result) { + // Update the schema with the generated id and version but skip + // committing the change in DD. Commit will be done by the caller. +- ndb_dd_update_schema_version(thd, db, id, version, +- true /*skip_commit*/); ++ if (!ndb_dd_update_schema_version(thd, db, id, version, ++ true /*skip_commit*/)) { ++ log_and_clear_thd_conditions(m_thd, condition_logging_level::ERROR); ++ ndb_log_error("Failed to update schema version for database '%s'", ++ db); ++ return true; ++ } + } else { + // NOTE! There is currently no way to report an error from this + // function, just log an error and proceed + ndb_log_error("Failed to distribute 'CREATE DATABASE %s'", db); ++ return true; + } + } break; + +@@ -546,7 +552,7 @@ static void ndbcluster_binlog_log_query(handlerton *, THD *thd, + // NOTE! As there is no way return error, this may have to be + // revisited, the prepare should be done + // much earlier where it can return an error for the query +- return; ++ return true; + } + + // Generate the id, version +@@ -558,12 +564,18 @@ static void ndbcluster_binlog_log_query(handlerton *, THD *thd, + if (result) { + // Update the schema with the generated id and version but skip + // committing the change in DD. Commit will be done by the caller. +- ndb_dd_update_schema_version(thd, db, id, version, +- true /*skip_commit*/); ++ if (!ndb_dd_update_schema_version(thd, db, id, version, ++ true /*skip_commit*/)) { ++ log_and_clear_thd_conditions(m_thd, condition_logging_level::ERROR); ++ ndb_log_error("Failed to update schema version for database '%s'", ++ db); ++ return true; ++ } + } else { + // NOTE! There is currently no way to report an error from this + // function, just log an error and proceed + ndb_log_error("Failed to distribute 'ALTER DATABASE %s'", db); ++ return true; + } + } break; + +@@ -577,6 +589,7 @@ static void ndbcluster_binlog_log_query(handlerton *, THD *thd, + binlog_command)); + break; + } ++ return false; + } + + static void ndbcluster_acl_notify(THD *thd, +diff --git a/storage/perfschema/ha_perfschema.cc b/storage/perfschema/ha_perfschema.cc +index a27da72..75f7e14 100644 +--- a/storage/perfschema/ha_perfschema.cc ++++ b/storage/perfschema/ha_perfschema.cc +@@ -1581,7 +1581,7 @@ int ha_perfschema::close(void) { + return 0; + } + +-int ha_perfschema::write_row(uchar *buf) { ++int ha_perfschema::write_row(uchar *buf, bool write_through MY_ATTRIBUTE((unused)) = false) { + int result; + + DBUG_TRACE; +diff --git a/storage/perfschema/ha_perfschema.h b/storage/perfschema/ha_perfschema.h +index 6efd57e..f8d03e3 100644 +--- a/storage/perfschema/ha_perfschema.h ++++ b/storage/perfschema/ha_perfschema.h +@@ -153,7 +153,7 @@ class ha_perfschema : public handler { + @param buf the row to write + @return 0 on success + */ +- int write_row(uchar *buf) override; ++ int write_row(uchar *buf, bool write_through MY_ATTRIBUTE((unused))) override; + + void use_hidden_primary_key() override; + +diff --git a/storage/temptable/include/temptable/handler.h b/storage/temptable/include/temptable/handler.h +index b9213f8..97bab4b 100644 +--- a/storage/temptable/include/temptable/handler.h ++++ b/storage/temptable/include/temptable/handler.h +@@ -317,7 +317,7 @@ class Handler : public ::handler { + * @return 0 on success or HA_ERR_* error code */ + int write_row( + /** [in] Row to insert. */ +- uchar *mysql_row) override; ++ uchar *mysql_row, bool write_through MY_ATTRIBUTE((unused)) = false) override; + + /** Update a row. + * @return 0 on success or HA_ERR_* error code */ +diff --git a/storage/temptable/src/handler.cc b/storage/temptable/src/handler.cc +index e949235..d46fca8 100644 +--- a/storage/temptable/src/handler.cc ++++ b/storage/temptable/src/handler.cc +@@ -639,7 +639,7 @@ void Handler::position(const uchar *) { + DBUG_PRINT("temptable_api", ("this=%p; saved position=%p", this, row)); + } + +-int Handler::write_row(uchar *mysql_row) { ++int Handler::write_row(uchar *mysql_row, bool write_through MY_ATTRIBUTE((unused))) { + DBUG_TRACE; + + opened_table_validate(); diff --git a/mysql-test/mysql-test-meta.patch b/mysql-test/mysql-test-meta.patch new file mode 100644 index 0000000..700c9cc --- /dev/null +++ b/mysql-test/mysql-test-meta.patch @@ -0,0 +1,84 @@ +diff --git a/mysql-test/include/check-testcase.test b/mysql-test/include/check-testcase.test +index 03dedb25272..a6303991b6a 100644 +--- a/mysql-test/include/check-testcase.test ++++ b/mysql-test/include/check-testcase.test +@@ -142,7 +142,8 @@ if ($NDB_BACKUP_DIR) + # Hence, check-testcase will not work in these cases. + + --let $secure_file_priv = `SELECT @@global.secure_file_priv` +---let $proceed_with_check_of_files = `SELECT @@global.innodb_force_recovery = 0 AND '$secure_file_priv' = '$MYSQLTEST_VARDIR_ABS/'` ++# --let $proceed_with_check_of_files = `SELECT @@global.innodb_force_recovery = 0 AND '$secure_file_priv' = '$MYSQLTEST_VARDIR_ABS/'` ++--let $proceed_with_check_of_files = 0; + if ($proceed_with_check_of_files) { + # Ensure that we have no impact on the content of the binary log. + # +diff --git a/mysql-test/include/default_mysqld.cnf b/mysql-test/include/default_mysqld.cnf +index 0dd92e19ad5..be84ee0c6de 100644 +--- a/mysql-test/include/default_mysqld.cnf ++++ b/mysql-test/include/default_mysqld.cnf +@@ -16,8 +16,8 @@ log-bin-trust-function-creators=1 + # Set innodb-buffer-pool-size and innodb-log-file-size to a lower + # value because running tests in parallel, on the ramdisk may consume + # excessive memory. +-innodb-buffer-pool-size=24M +-innodb-log-file-size=5M ++# innodb-buffer-pool-size=24M ++# innodb-log-file-size=5M + # MAINTAINER: + # the loose- syntax is to make sure the cnf file is also + # valid when building without the performance schema. +diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl +index 10668310763..79f17a2203d 100755 +--- a/mysql-test/mysql-test-run.pl ++++ b/mysql-test/mysql-test-run.pl +@@ -4032,10 +4032,11 @@ sub mysql_install_db { + mtr_add_arg($args, "--core-file"); + mtr_add_arg($args, "--datadir=%s", "$install_datadir"); + mtr_add_arg($args, "--secure-file-priv=%s", "$opt_vardir"); ++ mtr_add_arg($args, "--early-plugin-load=%s", "ha_ctc.so"); + + # Overwrite the buffer size to 24M for certain tests to pass +- mtr_add_arg($args, "--innodb_buffer_pool_size=24M"); +- mtr_add_arg($args, "--innodb-log-file-size=5M"); ++ # mtr_add_arg($args, "--innodb_buffer_pool_size=24M"); ++ # mtr_add_arg($args, "--innodb-log-file-size=5M"); + + # Overwrite innodb_autoextend_increment to 8 for reducing the + # ibdata1 file size. +@@ -6067,6 +6068,8 @@ sub mysqld_arguments ($$$) { + mtr_add_arg($args, "--user=root"); + } + ++ mtr_add_arg($args, "--early-plugin-load=%s", "ha_ctc.so"); ++ + if ($opt_valgrind_mysqld) { + if ($mysql_version_id < 50100) { + mtr_add_arg($args, "--skip-bdb"); +diff --git a/unittest/gunit/dd.h b/unittest/gunit/dd.h +index 31b97e634ac..dc8cc561000 100644 +--- a/unittest/gunit/dd.h ++++ b/unittest/gunit/dd.h +@@ -74,7 +74,7 @@ class Mock_dd_HANDLER : public Base_mock_HANDLER { + key_part_map, enum ha_rkey_function)); + + // Handler method used for inserts +- MOCK_METHOD1(write_row, int(::uchar *)); ++ MOCK_METHOD2(write_row, int(::uchar *, bool)); + + // Handler method used for updates + MOCK_METHOD2(update_row, int(const ::uchar *, ::uchar *)); +diff --git a/unittest/gunit/dd_schema-t.cc b/unittest/gunit/dd_schema-t.cc +index 51da5ca391c..f92f8a17780 100644 +--- a/unittest/gunit/dd_schema-t.cc ++++ b/unittest/gunit/dd_schema-t.cc +@@ -240,8 +240,8 @@ TEST_F(SchemaTest, CreateSchema) { + EXPECT_CALL(*last_altered, store(real_last_altered, true)).Times(1); + + // ha->write_row: Called once, return 0 +- ON_CALL(*ha, write_row(_)).WillByDefault(Return(0)); +- EXPECT_CALL(*ha, write_row(_)).Times(1); ++ ON_CALL(*ha, write_row(_, false)).WillByDefault(Return(0)); ++ EXPECT_CALL(*ha, write_row(_, false)).Times(1); + + // Store the schema. + schema->store(&ctx->otx); diff --git a/mysql-test/suite/tianchi/t/ctc_atomic_ddl.test b/mysql-test/suite/tianchi/t/ctc_atomic_ddl.test index 9e9ba18..4eed823 100644 --- a/mysql-test/suite/tianchi/t/ctc_atomic_ddl.test +++ b/mysql-test/suite/tianchi/t/ctc_atomic_ddl.test @@ -1,19 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - --disable_warnings drop table if exists t,t1,t2,t3,t4; --enable_warnings diff --git a/mysql-test/suite/tianchi/t/ctc_auto_increment.test b/mysql-test/suite/tianchi/t/ctc_auto_increment.test index 5acc1e2..2605465 100644 --- a/mysql-test/suite/tianchi/t/ctc_auto_increment.test +++ b/mysql-test/suite/tianchi/t/ctc_auto_increment.test @@ -1,19 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - # This test runs for auto increment feature # test set auto_increment_increment # test set auto_increment_offset diff --git a/mysql-test/suite/tianchi/t/ctc_charset.test b/mysql-test/suite/tianchi/t/ctc_charset.test index 4cf9c18..e6a2a94 100644 --- a/mysql-test/suite/tianchi/t/ctc_charset.test +++ b/mysql-test/suite/tianchi/t/ctc_charset.test @@ -1,19 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - # a test for charset when field type is char && index query CREATE TABLE worklog5743 (col_1_CHAR CHAR(255) , col_2_CHAR CHAR(255), PRIMARY KEY (col_1_CHAR)) engine = CTC STATS_PERSISTENT=0 charset latin1; diff --git a/mysql-test/suite/tianchi/t/ctc_charset_binary.test b/mysql-test/suite/tianchi/t/ctc_charset_binary.test index 3cd74eb..911b961 100644 --- a/mysql-test/suite/tianchi/t/ctc_charset_binary.test +++ b/mysql-test/suite/tianchi/t/ctc_charset_binary.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA create table t1(c1 int, c2 integer default '0' not null, c3 binary(10) default '' not null key) charset binary; insert into t1 values(0, default, default); diff --git a/mysql-test/suite/tianchi/t/ctc_charset_collate.test b/mysql-test/suite/tianchi/t/ctc_charset_collate.test index b567ce0..61033d2 100644 --- a/mysql-test/suite/tianchi/t/ctc_charset_collate.test +++ b/mysql-test/suite/tianchi/t/ctc_charset_collate.test @@ -1,19 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - --disable_warnings drop table if exists t1, t2, t3, t4; --enable_warnings diff --git a/mysql-test/suite/tianchi/t/ctc_compressed_proxy_conn.test b/mysql-test/suite/tianchi/t/ctc_compressed_proxy_conn.test index e439641..d052026 100644 --- a/mysql-test/suite/tianchi/t/ctc_compressed_proxy_conn.test +++ b/mysql-test/suite/tianchi/t/ctc_compressed_proxy_conn.test @@ -1,19 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - # server set to allow new connection must use zstd compressed header to handshake SET GLOBAL protocol_compression_algorithms= "zstd"; # next SET SQL will new a internal proxy conn. only proxy conn support compressed can it succeed. diff --git a/mysql-test/suite/tianchi/t/ctc_cond_pushdown.test b/mysql-test/suite/tianchi/t/ctc_cond_pushdown.test index 359ad8c..d882afe 100644 --- a/mysql-test/suite/tianchi/t/ctc_cond_pushdown.test +++ b/mysql-test/suite/tianchi/t/ctc_cond_pushdown.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA --disable_warnings drop table if exists t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15; --enable_warnings diff --git a/mysql-test/suite/tianchi/t/ctc_cond_pushdown_explain.test b/mysql-test/suite/tianchi/t/ctc_cond_pushdown_explain.test index 348e9a5..e283388 100644 --- a/mysql-test/suite/tianchi/t/ctc_cond_pushdown_explain.test +++ b/mysql-test/suite/tianchi/t/ctc_cond_pushdown_explain.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA --disable_warnings drop table if exists t1, t2, t3, t4, t5, t6, t7; diff --git a/mysql-test/suite/tianchi/t/ctc_crud_for_drop_column.test b/mysql-test/suite/tianchi/t/ctc_crud_for_drop_column.test index 8825d38..04ea241 100644 --- a/mysql-test/suite/tianchi/t/ctc_crud_for_drop_column.test +++ b/mysql-test/suite/tianchi/t/ctc_crud_for_drop_column.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA drop database if exists test_DB; create database test_DB; use test_DB; diff --git a/mysql-test/suite/tianchi/t/ctc_datatype.test b/mysql-test/suite/tianchi/t/ctc_datatype.test index 2cfee54..6898200 100644 --- a/mysql-test/suite/tianchi/t/ctc_datatype.test +++ b/mysql-test/suite/tianchi/t/ctc_datatype.test @@ -1,19 +1,4 @@ # -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -# # Simple test for the TSE storage engine # with most datatypes and null / not null # diff --git a/mysql-test/suite/tianchi/t/ctc_datatype_adapt.test b/mysql-test/suite/tianchi/t/ctc_datatype_adapt.test index 599ce12..c7da00e 100644 --- a/mysql-test/suite/tianchi/t/ctc_datatype_adapt.test +++ b/mysql-test/suite/tianchi/t/ctc_datatype_adapt.test @@ -1,21 +1,6 @@ # -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -# # Simple test for the TSE storage engine -# with the data type which not supported by GaussDB +# with the data type which not supported by CantianDB # such as YEAR, TIME ,etc. # diff --git a/mysql-test/suite/tianchi/t/ctc_datatype_blob.test b/mysql-test/suite/tianchi/t/ctc_datatype_blob.test index 58a7655..c1301f1 100644 --- a/mysql-test/suite/tianchi/t/ctc_datatype_blob.test +++ b/mysql-test/suite/tianchi/t/ctc_datatype_blob.test @@ -1,19 +1,4 @@ # -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -# # Simple test for the TSE storage engine # with blob data and null / not null # diff --git a/mysql-test/suite/tianchi/t/ctc_dc_reuse.test b/mysql-test/suite/tianchi/t/ctc_dc_reuse.test index 22a5e49..b43d0ef 100644 --- a/mysql-test/suite/tianchi/t/ctc_dc_reuse.test +++ b/mysql-test/suite/tianchi/t/ctc_dc_reuse.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA let $engine_type= CTC; --disable_warnings diff --git a/mysql-test/suite/tianchi/t/ctc_dcl.test b/mysql-test/suite/tianchi/t/ctc_dcl.test index 824550c..4a6487e 100644 --- a/mysql-test/suite/tianchi/t/ctc_dcl.test +++ b/mysql-test/suite/tianchi/t/ctc_dcl.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # ctc_dcl_disabled drop user if exists yyz; diff --git a/mysql-test/suite/tianchi/t/ctc_ddl.test b/mysql-test/suite/tianchi/t/ctc_ddl.test index 728dcbb..e944c8a 100644 --- a/mysql-test/suite/tianchi/t/ctc_ddl.test +++ b/mysql-test/suite/tianchi/t/ctc_ddl.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA --disable_warnings drop table if exists DEMO; --enable_warnings diff --git a/mysql-test/suite/tianchi/t/ctc_ddl_alter_table.test b/mysql-test/suite/tianchi/t/ctc_ddl_alter_table.test index a65db51..b5433bd 100644 --- a/mysql-test/suite/tianchi/t/ctc_ddl_alter_table.test +++ b/mysql-test/suite/tianchi/t/ctc_ddl_alter_table.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA --disable_warnings drop table if exists DEMO; drop table if exists t1; @@ -884,6 +869,25 @@ insert into t1 values (null),(null),(null),(null); alter table t1 drop i,add i int unsigned not null auto_increment, drop primary key, add primary key (i); drop table t1; +--disable_warnings +CREATE TABLE t1 (c1 FLOAT(6,2)); +INSERT INTO t1 VALUES (123); +ALTER TABLE t1 MODIFY COLUMN c1 FLOAT(7,3); +drop table t1; +CREATE TABLE t1 (c1 DOUBLE(6,2)); +INSERT INTO t1 VALUES (123); +ALTER TABLE t1 MODIFY COLUMN c1 DOUBLE(7,3); +drop table t1; +CREATE TABLE t1 (c1 REAL(6,2)); +INSERT INTO t1 VALUES (123); +ALTER TABLE t1 MODIFY COLUMN c1 REAL(7,3); +drop table t1; +CREATE TABLE t1 (c1 FLOAT(6,2), c2 DOUBLE(6,2), c3 REAL(6,2)); +INSERT INTO t1 VALUES (123, 456, 789); +ALTER TABLE t1 MODIFY COLUMN c2 DOUBLE(7,3); +drop table t1; +--enable_warnings + create database db1; create database db2; use db1; diff --git a/mysql-test/suite/tianchi/t/ctc_ddl_analyze.test b/mysql-test/suite/tianchi/t/ctc_ddl_analyze.test index 19833e0..b36212a 100644 --- a/mysql-test/suite/tianchi/t/ctc_ddl_analyze.test +++ b/mysql-test/suite/tianchi/t/ctc_ddl_analyze.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA --disable_warnings drop table if exists DEMO; --enable_warnings diff --git a/mysql-test/suite/tianchi/t/ctc_ddl_auto_inc.test b/mysql-test/suite/tianchi/t/ctc_ddl_auto_inc.test index 78ada60..7f7ff5c 100644 --- a/mysql-test/suite/tianchi/t/ctc_ddl_auto_inc.test +++ b/mysql-test/suite/tianchi/t/ctc_ddl_auto_inc.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA --disable_warnings drop table if exists DEMO; --enable_warnings diff --git a/mysql-test/suite/tianchi/t/ctc_ddl_cascade.test b/mysql-test/suite/tianchi/t/ctc_ddl_cascade.test index d1468b1..3e04a77 100644 --- a/mysql-test/suite/tianchi/t/ctc_ddl_cascade.test +++ b/mysql-test/suite/tianchi/t/ctc_ddl_cascade.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA CREATE DATABASE IF NOT EXISTS CASCADE_TEST; USE CASCADE_TEST; @@ -266,4 +251,536 @@ SET SESSION foreign_key_checks=1; UPDATE IGNORE `t1` SET a = 3; drop table t1,t2; +drop table if exists t4; +drop table if exists t3; +create table t1(a int primary key); +create table t2(a int primary key); +create table t3(a int, constraint fk_1 foreign key(a) references t1(a) on update cascade, constraint fk_2 foreign key(a) references t2(a) on update cascade); +insert into t1 values(1); +insert into t2 values(1); +insert into t3 values(1); +--error 1452 +update t1 set a = 2; +--error 1452 +update t2 set a = 2; +drop table t1,t2,t3; + +DROP TABLE IF EXISTS T1; +DROP TABLE IF EXISTS T2; +CREATE TABLE T1(A INT UNIQUE); +CREATE TABLE T2(A INT UNIQUE NOT NULL); +ALTER TABLE T2 ADD FOREIGN KEY FF(A) REFERENCES T1(A) ON UPDATE CASCADE; +INSERT INTO T1 VALUES(1); +INSERT INTO T2 VALUES(1); +--error 1451 +UPDATE T1 SET A = NULL WHERE A = 1; +DROP TABLE T1,T2; + +drop table if exists t1; +create table t1( +id int primary key, +pid int, +index(pid), +foreign key(pid) references t1(id) on delete cascade) engine=CTC; +insert into t1 values(0,0),(1,0),(2,1),(3,2),(4,3),(5,4),(6,5),(7,6), +(8,7),(9,8),(10,9),(11,10),(12,11),(13,12),(14,13),(15,14); +--error 3008 +delete from t1 where id = 0; +drop table t1; + +DROP TABLE IF EXISTS T1; +DROP TABLE IF EXISTS T2; +DROP TABLE IF EXISTS T3; +DROP TABLE IF EXISTS T4; +DROP TABLE IF EXISTS T5; +DROP TABLE IF EXISTS T6; +DROP TABLE IF EXISTS T7; +DROP TABLE IF EXISTS T8; +DROP TABLE IF EXISTS T9; +DROP TABLE IF EXISTS T10; +DROP TABLE IF EXISTS T11; +DROP TABLE IF EXISTS T12; +DROP TABLE IF EXISTS T13; +DROP TABLE IF EXISTS T14; +DROP TABLE IF EXISTS T15; +DROP TABLE IF EXISTS T16; +CREATE TABLE T1(A INT UNIQUE); +CREATE TABLE T2(A INT UNIQUE, FOREIGN KEY(A) REFERENCES T1(A) ON UPDATE CASCADE); +CREATE TABLE T3(A INT UNIQUE, FOREIGN KEY(A) REFERENCES T2(A) ON UPDATE CASCADE); +CREATE TABLE T4(A INT UNIQUE, FOREIGN KEY(A) REFERENCES T3(A) ON UPDATE CASCADE); +CREATE TABLE T5(A INT UNIQUE, FOREIGN KEY(A) REFERENCES T4(A) ON UPDATE CASCADE); +CREATE TABLE T6(A INT UNIQUE, FOREIGN KEY(A) REFERENCES T5(A) ON UPDATE CASCADE); +CREATE TABLE T7(A INT UNIQUE, FOREIGN KEY(A) REFERENCES T6(A) ON UPDATE CASCADE); +CREATE TABLE T8(A INT UNIQUE, FOREIGN KEY(A) REFERENCES T7(A) ON UPDATE CASCADE); +CREATE TABLE T9(A INT UNIQUE, FOREIGN KEY(A) REFERENCES T8(A) ON UPDATE CASCADE); +CREATE TABLE T10(A INT UNIQUE, FOREIGN KEY(A) REFERENCES T9(A) ON UPDATE CASCADE); +CREATE TABLE T11(A INT UNIQUE, FOREIGN KEY(A) REFERENCES T10(A) ON UPDATE CASCADE); +CREATE TABLE T12(A INT UNIQUE, FOREIGN KEY(A) REFERENCES T11(A) ON UPDATE CASCADE); +CREATE TABLE T13(A INT UNIQUE, FOREIGN KEY(A) REFERENCES T12(A) ON UPDATE CASCADE); +CREATE TABLE T14(A INT UNIQUE, FOREIGN KEY(A) REFERENCES T13(A) ON UPDATE CASCADE); +CREATE TABLE T15(A INT UNIQUE, FOREIGN KEY(A) REFERENCES T14(A) ON UPDATE CASCADE); +CREATE TABLE T16(A INT UNIQUE, FOREIGN KEY(A) REFERENCES T15(A) ON UPDATE CASCADE); +INSERT INTO T1 VALUES(1); +INSERT INTO T2 VALUES(1); +INSERT INTO T3 VALUES(1); +INSERT INTO T4 VALUES(1); +INSERT INTO T5 VALUES(1); +INSERT INTO T6 VALUES(1); +INSERT INTO T7 VALUES(1); +INSERT INTO T8 VALUES(1); +INSERT INTO T9 VALUES(1); +INSERT INTO T10 VALUES(1); +INSERT INTO T11 VALUES(1); +INSERT INTO T12 VALUES(1); +INSERT INTO T13 VALUES(1); +INSERT INTO T14 VALUES(1); +INSERT INTO T15 VALUES(1); +INSERT INTO T16 VALUES(1); +--error 3008 +UPDATE T1 SET A = 2 WHERE A = 1; +drop table T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16; + +DROP TABLE IF EXISTS T1; +DROP TABLE IF EXISTS T2; +CREATE TABLE T1(A DECIMAL(20,5) UNIQUE); +CREATE TABLE T2(A DECIMAL(19,2) UNIQUE); +ALTER TABLE T2 ADD FOREIGN KEY FF(A) REFERENCES T1(A) ON UPDATE CASCADE; +SET foreign_key_checks = 0; +insert into T1 values(1); +insert into T2 values(1); +SET foreign_key_checks = 1; +update T1 set a = 1.2345678; +select * from T1; +select * from T2; +DROP TABLE T1,T2; + +DROP TABLE IF EXISTS T1,T2; +CREATE TABLE T1(A DECIMAL(20,5) UNIQUE); +CREATE TABLE T2(A DECIMAL(20,3) UNIQUE); +ALTER TABLE T2 ADD FOREIGN KEY FF(A) REFERENCES T1(A) ON DELETE SET NULL; +SET foreign_key_checks = 0; +insert into T1 values(1); +insert into T2 values(1); +SET foreign_key_checks = 1; +DELETE FROM T1 WHERE A = 1; +SELECT * FROM T1; +SELECT * FROM T2; +DROP TABLE T1,T2; + +DROP TABLE IF EXISTS T1,T2; +CREATE TABLE T1(A DECIMAL(20,5) UNIQUE); +CREATE TABLE T2(A DECIMAL(18,5) UNIQUE); +ALTER TABLE T2 ADD FOREIGN KEY FF(A) REFERENCES T1(A) ON DELETE SET NULL; +SET foreign_key_checks = 0; +insert into T1 values(1); +insert into T2 values(1); +SET foreign_key_checks = 1; +DELETE FROM T1 WHERE A = 1; +SELECT * FROM T1; +SELECT * FROM T2; +DROP TABLE T1,T2; + +DROP TABLE IF EXISTS T1,T2; +CREATE TABLE T1(A DECIMAL(20,5) UNIQUE); +CREATE TABLE T2(A DECIMAL(20,3) UNIQUE); +ALTER TABLE T2 ADD FOREIGN KEY FF(A) REFERENCES T1(A) ON DELETE CASCADE; +SET foreign_key_checks = 0; +insert into T1 values(1); +insert into T2 values(1); +SET foreign_key_checks = 1; +DELETE FROM T1 WHERE A = 1; +SELECT * FROM T1; +SELECT * FROM T2; +DROP TABLE T1,T2; + +DROP TABLE IF EXISTS T1,T2; +CREATE TABLE T1(A DECIMAL(20,5) UNIQUE); +CREATE TABLE T2(A DECIMAL(18,5) UNIQUE); +ALTER TABLE T2 ADD FOREIGN KEY FF(A) REFERENCES T1(A) ON DELETE CASCADE; +SET foreign_key_checks = 0; +insert into T1 values(1); +insert into T2 values(1); +SET foreign_key_checks = 1; +DELETE FROM T1 WHERE A = 1; +SELECT * FROM T1; +SELECT * FROM T2; +DROP TABLE T1,T2; + +DROP TABLE IF EXISTS T1,T2; +CREATE TABLE T1(A DECIMAL(20,5) UNIQUE); +CREATE TABLE T2(A DECIMAL(20,3) UNIQUE); +ALTER TABLE T2 ADD FOREIGN KEY FF(A) REFERENCES T1(A) ON UPDATE CASCADE; +SET foreign_key_checks = 0; +insert into T1 values(1); +insert into T2 values(1); +SET foreign_key_checks = 1; +UPDATE T1 set A = 1.2345678; +SELECT * FROM T1; +SELECT * FROM T2; +DROP TABLE T1,T2; + +DROP TABLE IF EXISTS T1,T2; +CREATE TABLE T1(A DECIMAL(20,5) UNIQUE); +CREATE TABLE T2(A DECIMAL(18,5) UNIQUE); +ALTER TABLE T2 ADD FOREIGN KEY FF(A) REFERENCES T1(A) ON UPDATE CASCADE; +SET foreign_key_checks = 0; +insert into T1 values(1); +insert into T2 values(1); +SET foreign_key_checks = 1; +UPDATE T1 set A = 1.2345678; +SELECT * FROM T1; +SELECT * FROM T2; +DROP TABLE T1,T2; + +DROP TABLE IF EXISTS T1,T2; +CREATE TABLE T1(A DECIMAL(20,5) UNIQUE); +CREATE TABLE T2(A DECIMAL(20,3) UNIQUE); +ALTER TABLE T2 ADD FOREIGN KEY FF(A) REFERENCES T1(A) ON UPDATE SET NULL; +SET foreign_key_checks = 0; +insert into T1 values(1); +insert into T2 values(1); +SET foreign_key_checks = 1; +UPDATE T1 set A = 1.2345678; +SELECT * FROM T1; +SELECT * FROM T2; +DROP TABLE T1,T2; + +DROP TABLE IF EXISTS T1,T2; +CREATE TABLE T1(A DECIMAL(20,5) UNIQUE); +CREATE TABLE T2(A DECIMAL(18,5) UNIQUE); +ALTER TABLE T2 ADD FOREIGN KEY FF(A) REFERENCES T1(A) ON UPDATE SET NULL; +SET foreign_key_checks = 0; +insert into T1 values(1); +insert into T2 values(1); +SET foreign_key_checks = 1; +UPDATE T1 set A = 1.2345678; +SELECT * FROM T1; +SELECT * FROM T2; +DROP TABLE T1,T2; + +DROP TABLE IF EXISTS T1,T2; +CREATE TABLE T1(A DECIMAL(20,5), B DECIMAL(20,5), UNIQUE KEY(A, B)); +CREATE TABLE T2(A DECIMAL(18,5), B DECIMAL(20,5)); +ALTER TABLE T2 ADD FOREIGN KEY FF(A, B) REFERENCES T1(A, B) ON DELETE SET NULL; +SET foreign_key_checks = 0; +insert into T1 values(1, 1); +insert into T2 values(1, 1); +SET foreign_key_checks = 1; +DELETE FROM T1 WHERE A = 1; +SELECT * FROM T1; +SELECT * FROM T2; +DROP TABLE T1,T2; + +DROP TABLE IF EXISTS T1,T2; +CREATE TABLE T1(A DECIMAL(20,5), B DECIMAL(20,5), UNIQUE KEY(A, B)); +CREATE TABLE T2(A DECIMAL(20,5), B DECIMAL(20,5)); +ALTER TABLE T2 ADD FOREIGN KEY FF(A, B) REFERENCES T1(A, B) ON DELETE SET NULL; +SET foreign_key_checks = 0; +insert into T1 values(1, 1); +insert into T2 values(1, 1); +SET foreign_key_checks = 1; +DELETE FROM T1 WHERE A = 1; +SELECT * FROM T1; +SELECT * FROM T2; +DROP TABLE T1,T2; + +DROP TABLE IF EXISTS T1,T2; +CREATE TABLE T1(A DECIMAL(20,5), B DECIMAL(20,5), UNIQUE KEY(A, B)); +CREATE TABLE T2(A DECIMAL(20,3), B DECIMAL(20,5)); +ALTER TABLE T2 ADD FOREIGN KEY FF(A, B) REFERENCES T1(A, B) ON DELETE SET NULL; +SET foreign_key_checks = 0; +insert into T1 values(1, 1); +insert into T2 values(1, 1); +SET foreign_key_checks = 1; +DELETE FROM T1 WHERE A = 1; +SELECT * FROM T1; +SELECT * FROM T2; +DROP TABLE T1,T2; + +drop table if exists t1, t2; +create table t1(id FLOAT(11,5) primary key); +create table t2(id FLOAT(11,2) primary key, CONSTRAINT fk_1 FOREIGN KEY (id) REFERENCES t1 (id) on delete set default on update cascade); +insert into t1 values(1); +insert into t2 values(1); +select * from t1; +select * from t2; +drop table t1,t2; + +drop table if exists f1,c1; +create table f1(a1 char(1) primary key DEFAULT ''); +create table c1(a1 char(1) DEFAULT '', CONSTRAINT fk_1 FOREIGN KEY (a1) REFERENCES f1 (a1) on update cascade); +insert into f1(a1) values(1); +insert into c1(a1) values(1); +update f1 set a1 = '' where a1 = 1; +select * from f1; +select * from c1; +drop table f1,c1; + +drop table if exists f1,c1; +create table f1(a1 varchar(20) primary key); +create table c1(a1 varchar(20), CONSTRAINT fk_1 FOREIGN KEY (a1) REFERENCES f1 (a1) on update cascade); +insert into f1(a1) values('sssa'); +insert into c1(a1) values('sssa'); +update f1 set a1 = 'cddddsd'; +select * from f1; +select * from c1; +update f1 set a1 = 'daaass'; +select * from f1; +select * from c1; +drop table f1,c1; + +drop table if exists t1,t2; +create table t1(a int NOT NULL AUTO_INCREMENT primary key, b bit(7) ,unique(b)); +create table t2(c varchar(20), d bit(5) not null, foreign key(d) references t1(b) on update cascade); +insert into t1(b) values(b'1'); +insert into t2 values('jack', b'1'); +update t1 set b = b'1111111'; +select * from t1; +select * from t2; +drop table t1,t2; + +drop table if exists t1,t2; +create table t1(a int NOT NULL AUTO_INCREMENT primary key, b bit(9) ,unique(b)); +create table t2(c varchar(20), d bit(8) not null, foreign key(d) references t1(b) on update cascade); +insert into t1(b) values(b'1'); +--error 1452 +insert into t2 values('jack', b'1'); +drop table t1,t2; + +drop table if exists t1,t2; +create table t1(a int,b enum('1',''),unique(b)); +create table t2(c varchar(20), d enum('1','a','*') not null default ('*'), foreign key(d) references t1(b) on update cascade); +insert into t1 values(1,'1'); +insert into t2 values('bob','1'); +select * from t1; +select * from t2; +drop table t1,t2; + +drop table if exists T1,T2; +create table T1(id decimal(20, 5) primary key); +create table T2(id decimal(20, 3), constraint FK_ID foreign key (id) references T1(id)); +insert into T1 values(7); +--error 1452 +insert into T2 values(7); +drop table T1,T2; + +drop table if exists T1,T2; +create table T1(id decimal(20, 5) unique key); +create table T2(id decimal(20, 3), constraint FK_ID foreign key (id) references T1(id)); +insert into T2 values(NULL); +select * from T2; +drop table T1,T2; + +drop table if exists T1,T2; +set foreign_key_checks = 0; +create table T1(id decimal(20, 5) primary key); +create table T2(id decimal(20, 3), constraint FK_ID foreign key (id) references T1(id)); +insert into T1 values(7); +insert into T2 values(7); +select * from T1; +select * from T2; +set foreign_key_checks = 1; +drop table T1,T2; + +drop table if exists t1,t2; +CREATE TABLE t1 ( +datetime DATETIME(6), +UNIQUE KEY datetime (datetime) +); +CREATE TABLE t2 ( +datetime DATETIME(5), +CONSTRAINT fk_datetime FOREIGN KEY (datetime) REFERENCES t1(datetime) +); +insert into t1 values('2018-01-18 00:00:00'); +insert into t2 values('2018-01-18 00:00:00'); +select * from t1; +select * from t2; +drop table t1,t2; + +drop table if exists t1,t2; +CREATE TABLE t1 ( +datetime DATETIME(5), +UNIQUE KEY datetime (datetime) +); +CREATE TABLE t2 ( +datetime DATETIME(4), +CONSTRAINT fk_datetime FOREIGN KEY (datetime) REFERENCES t1(datetime) +); +insert into t1 values('2018-01-18 00:00:00'); +--error 1452 +insert into t2 values('2018-01-18 00:00:00'); +drop table t1,t2; + +drop table if exists t1,t2; +CREATE TABLE t1 ( +timestamp TIMESTAMP(6), +UNIQUE KEY timestamp (timestamp) +); +CREATE TABLE t2 ( +timestamp TIMESTAMP(5), +CONSTRAINT fk_timestamp FOREIGN KEY (timestamp) REFERENCES t1(timestamp) +); +insert into t1 values('2018-01-18 00:00:00'); +insert into t2 values('2018-01-18 00:00:00'); +select * from t1; +select * from t2; +drop table t1,t2; + +drop table if exists t1,t2; +CREATE TABLE t1 ( +timestamp TIMESTAMP(5), +UNIQUE KEY timestamp (timestamp) +); +CREATE TABLE t2 ( +timestamp TIMESTAMP(4), +CONSTRAINT fk_timestamp FOREIGN KEY (timestamp) REFERENCES t1(timestamp) +); +insert into t1 values('2018-01-18 00:00:00'); +--error 1452 +insert into t2 values('2018-01-18 00:00:00'); +drop table t1,t2; + +drop table if exists t1,t2; +create table t1(a int NOT NULL AUTO_INCREMENT primary key, b decimal(65,30),unique(b)); +create table t2(c varchar(20), d decimal(65,30) not null default 1, foreign key(d) references t1(b) on update cascade); +insert into t1 values(3,2.2250738585072014E-308); +insert into t2 values('bob',2.2250738585072014E-308); +insert into t2 values('grace',-2.2250738585072014E-308); +update t1 set a = 33, b = 999.901 where b<=0; +select * from t1; +select * from t2; +drop table t1,t2; + +drop table if exists char4, char5; +create table char4(c2 char(255) unique key); +create table char5(c2 char(254) unique key, CONSTRAINT fk_char5 FOREIGN KEY (c2) REFERENCES char4 (c2) on update cascade); +insert into char4 values('a'); +insert into char5 values('a'); +--error 1451 +update char4 set c2='bbbb'; +drop table char4, char5; + +drop table if exists char4, char5; +create table char4(c2 varchar(255) unique key); +create table char5(c2 varchar(5) unique key, CONSTRAINT fk_char5 FOREIGN KEY (c2) REFERENCES char4 (c2) on update cascade); +insert into char4 values('a'); +insert into char5 values('a'); +update char4 set c2='bbbbb'; +select * from char4; +select * from char5; +--error 1451 +update char4 set c2='bbbbbb'; +select * from char4; +select * from char5; +update char4 set c2='我的啊你不'; +select * from char4; +select * from char5; +--error 1451 +update char4 set c2='我的啊你不要'; +select * from char4; +select * from char5; +update char4 set c2='我的a你b'; +select * from char4; +select * from char5; +drop table char4, char5; + +drop table if exists t1,t2; +create table t1(a varchar(20) unique key); +create table t2(a varchar(20), CONSTRAINT fk_1 FOREIGN KEY (a) REFERENCES t1 (a) on update cascade); +insert into t1 values('a'); +insert into t2 values('a'); +update t1 set a = null; +select * from t1; +select * from t2; +drop table t1,t2; + +drop table if exists t1,t2,c_t1; +create table t1(id varchar(255) primary key, i int AUTO_INCREMENT,unique key(i)); +create table t2(c1 varchar(255) unique key, i int AUTO_INCREMENT,unique key(i)); +create table c_t1(c1 varchar(255) unique key +,CONSTRAINT fk_t1 FOREIGN KEY (c1) REFERENCES t1 (id) on delete set default on update cascade +,CONSTRAINT fk_t2 FOREIGN KEY (c1) REFERENCES t2 (c1) on delete set default on update cascade); +insert into t1(id) values(''); +insert into t2(c1) values(''); +insert into c_t1(c1) values(''); +select * from t1; +select * from t2; +select * from c_t1; +select t1.i,t1.id,t2.c1 from t1,t2 where t1.i=t2.i and t1.i=1; +--error 1452 +update t1,t2 set t1.id='a',t2.c1='b' where t1.i=t2.i and t1.i=1; +select * from t1; +select * from t2; +select * from c_t1; +drop table t1,t2,c_t1; + +drop table if exists t1,t2,t3; +create table t1(a1 int, a2 int, a3 int, a4 int, a5 int, primary key(a3, a5)); +create table t2(b1 int, b2 int, b3 int, b4 int, b5 int, primary key(b2, b4)); +create table t3(c1 int, c2 int, c3 int, constraint fk_1 foreign key(c1, c2) references t1(a3, a5) on update cascade, constraint fk_2 foreign key(c2, c3) references t2(b2, b4) on update set null); +insert into t1 values(1,1,1,1,1); +insert into t2 values(1,1,1,1,1); +insert into t3 values(1,1,1); +--error 1452 +update t1 set a5 = 2, a1 = 4; +--error 1452 +update t1 set a3 = 2, a1 = 4; +select * from t1; +select * from t2; +select * from t3; +drop table t1,t2,t3; + +drop table if exists t1,t2,t3; +create table t1(a int primary key); +create table t2(a int primary key); +create table t3(a int, constraint fk_1 foreign key(a) references t1(a) on update cascade, constraint fk_2 foreign key(a) references t2(a) on update cascade); +insert into t1 values(1); +insert into t2 values(1); +insert into t3 values(1); +--error 1452 +update t1 set a = 2; +--error 1452 +update t2 set a = 2; +drop table t1,t2,t3; + +drop table if exists t1,t2,t3; +create table t1(a int primary key); +create table t2(a int primary key); +create table t3(a int, constraint fk_1 foreign key(a) references t1(a) on update cascade, constraint fk_2 foreign key(a) references t2(a) on delete cascade); +insert into t1 values(1); +insert into t2 values(1); +insert into t3 values(1); +--error 1452 +update t1 set a = 2; +delete from t2; +drop table t1,t2,t3; + +drop table if exists t1,t2,t3; +create table t1(a int primary key); +create table t2(a int primary key); +create table t3(a int, constraint fk_1 foreign key(a) references t1(a) on update cascade, constraint fk_2 foreign key(a) references t2(a) on delete set null); +insert into t1 values(1); +insert into t2 values(1); +insert into t3 values(1); +--error 1452 +update t1 set a = 2; +delete from t2; +drop table t1,t2,t3; + +drop table if exists t1,t2; +create table t1(a int, b int, primary key(a, b)); +create table t2(a int, b int, constraint fk_1 foreign key(a, b) references t1(a, b) on update cascade); +insert into t1 values(1, 1); +insert into t2 values(1, 1); +alter table t2 add constraint fk_2 foreign key(a, b) references t1(a, b) on delete set null; +--error 1451 +delete from t1; +--error 1452 +update t1 set a = 2, b = 2; +alter table t2 drop foreign key fk_1; +--error 1451 +update t1 set a = 3, b = 3; +delete from t1; +drop table t1,t2; + DROP DATABASE CASCADE_TEST; diff --git a/mysql-test/suite/tianchi/t/ctc_ddl_character_set.test b/mysql-test/suite/tianchi/t/ctc_ddl_character_set.test index f58b072..a53e274 100644 --- a/mysql-test/suite/tianchi/t/ctc_ddl_character_set.test +++ b/mysql-test/suite/tianchi/t/ctc_ddl_character_set.test @@ -1,19 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - #database的字符集、字符序,创建修改字符集 CREATE DATABASE `CHAR_DB` DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci; use CHAR_DB; diff --git a/mysql-test/suite/tianchi/t/ctc_ddl_create_table.test b/mysql-test/suite/tianchi/t/ctc_ddl_create_table.test index a3afa44..7f52ded 100644 --- a/mysql-test/suite/tianchi/t/ctc_ddl_create_table.test +++ b/mysql-test/suite/tianchi/t/ctc_ddl_create_table.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA --disable_warnings drop table if exists DEMO; drop table if exists t1; @@ -742,16 +727,6 @@ SELECT * FROM DEMO; drop table DEMO; -#create table with foreign key and select -create table DEMO(uid int NOT NULL AUTO_INCREMENT,name varchar(60) default 'abc',email varchar(60),UNIQUE(uid)); -show create table DEMO; -insert into DEMO values(1,'Amy','1001'),(2,'Mike','1002'),(3,'Lily','1003'); -SELECT * FROM DEMO; ---error 3978 -create table DEMO1 (uid int,foreign key(uid) references DEMO (uid)) as select * from DEMO; -drop table DEMO; - - #create table bit column with default create table DEMO(a BIT(1) default b'0', b BIT(4) default 11); show create table DEMO; diff --git a/mysql-test/suite/tianchi/t/ctc_ddl_create_table_check.test b/mysql-test/suite/tianchi/t/ctc_ddl_create_table_check.test index 88d3778..906d181 100644 --- a/mysql-test/suite/tianchi/t/ctc_ddl_create_table_check.test +++ b/mysql-test/suite/tianchi/t/ctc_ddl_create_table_check.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA --disable_warnings drop table if exists t1; --enable_warnings diff --git a/mysql-test/suite/tianchi/t/ctc_ddl_default_index.test b/mysql-test/suite/tianchi/t/ctc_ddl_default_index.test index 5eb6885..c0e6348 100644 --- a/mysql-test/suite/tianchi/t/ctc_ddl_default_index.test +++ b/mysql-test/suite/tianchi/t/ctc_ddl_default_index.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # alter table has default create table t1(c1 int, c2 integer default '0' not null, c3 binary(10) default '' not null key) charset binary; alter table t1 add column c4 binary(5) default '' not null; diff --git a/mysql-test/suite/tianchi/t/ctc_ddl_engine.test b/mysql-test/suite/tianchi/t/ctc_ddl_engine.test index 742bba8..6cc4718 100644 --- a/mysql-test/suite/tianchi/t/ctc_ddl_engine.test +++ b/mysql-test/suite/tianchi/t/ctc_ddl_engine.test @@ -1,20 +1,6 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #切换引擎相关的测试用例 + #不支持设置TSE以外的任何引擎存储引擎 set default_storage_engine=CTC; --error ER_DISALLOWED_OPERATION diff --git a/mysql-test/suite/tianchi/t/ctc_ddl_fault_process.test b/mysql-test/suite/tianchi/t/ctc_ddl_fault_process.test index 369837e..5b18285 100644 --- a/mysql-test/suite/tianchi/t/ctc_ddl_fault_process.test +++ b/mysql-test/suite/tianchi/t/ctc_ddl_fault_process.test @@ -1,19 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - #故障场景相关测试用例 --disable_warnings drop database if exists DEMO_DB; diff --git a/mysql-test/suite/tianchi/t/ctc_ddl_foreign_key.test b/mysql-test/suite/tianchi/t/ctc_ddl_foreign_key.test index ac28a62..63df07d 100644 --- a/mysql-test/suite/tianchi/t/ctc_ddl_foreign_key.test +++ b/mysql-test/suite/tianchi/t/ctc_ddl_foreign_key.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA --disable_warnings drop table if exists DEMO; --enable_warnings diff --git a/mysql-test/suite/tianchi/t/ctc_ddl_foreign_key_set_enum.test b/mysql-test/suite/tianchi/t/ctc_ddl_foreign_key_set_enum.test index 1f846fe..242c0b8 100644 --- a/mysql-test/suite/tianchi/t/ctc_ddl_foreign_key_set_enum.test +++ b/mysql-test/suite/tianchi/t/ctc_ddl_foreign_key_set_enum.test @@ -1,19 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - --disable_warnings drop table if exists PARTABLE; --enable_warnings diff --git a/mysql-test/suite/tianchi/t/ctc_ddl_func_index.test b/mysql-test/suite/tianchi/t/ctc_ddl_func_index.test index da4d765..9d10ce9 100644 --- a/mysql-test/suite/tianchi/t/ctc_ddl_func_index.test +++ b/mysql-test/suite/tianchi/t/ctc_ddl_func_index.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA --disable_warnings drop database if exists db1; --enable_warnings diff --git a/mysql-test/suite/tianchi/t/ctc_ddl_func_proc.test b/mysql-test/suite/tianchi/t/ctc_ddl_func_proc.test index f487c31..711c592 100644 --- a/mysql-test/suite/tianchi/t/ctc_ddl_func_proc.test +++ b/mysql-test/suite/tianchi/t/ctc_ddl_func_proc.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA --disable_warnings drop table if exists Dept; --enable_warnings diff --git a/mysql-test/suite/tianchi/t/ctc_ddl_generated_columns.test b/mysql-test/suite/tianchi/t/ctc_ddl_generated_columns.test index d0da9aa..73a10bc 100644 --- a/mysql-test/suite/tianchi/t/ctc_ddl_generated_columns.test +++ b/mysql-test/suite/tianchi/t/ctc_ddl_generated_columns.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #测试生成列和虚拟列 --error 3655 CREATE TABLE triangle ( diff --git a/mysql-test/suite/tianchi/t/ctc_ddl_index.test b/mysql-test/suite/tianchi/t/ctc_ddl_index.test index bc9202b..d47c108 100644 --- a/mysql-test/suite/tianchi/t/ctc_ddl_index.test +++ b/mysql-test/suite/tianchi/t/ctc_ddl_index.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA --disable_warnings drop table if exists DEMO; --enable_warnings diff --git a/mysql-test/suite/tianchi/t/ctc_ddl_limit.test b/mysql-test/suite/tianchi/t/ctc_ddl_limit.test index abcfa3f..bad72f1 100644 --- a/mysql-test/suite/tianchi/t/ctc_ddl_limit.test +++ b/mysql-test/suite/tianchi/t/ctc_ddl_limit.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #ddl的sql语句长度不允许超过64kb set default_storage_engine=CTC; # 创建并切换数据库 diff --git a/mysql-test/suite/tianchi/t/ctc_ddl_max_reclength.test b/mysql-test/suite/tianchi/t/ctc_ddl_max_reclength.test index 44f165c..2a6107f 100644 --- a/mysql-test/suite/tianchi/t/ctc_ddl_max_reclength.test +++ b/mysql-test/suite/tianchi/t/ctc_ddl_max_reclength.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA DELIMITER |; CREATE PROCEDURE create_table_columns_char(table_name varchar(50), columns int) BEGIN diff --git a/mysql-test/suite/tianchi/t/ctc_ddl_multi_db.test b/mysql-test/suite/tianchi/t/ctc_ddl_multi_db.test index 62f010f..63f6738 100644 --- a/mysql-test/suite/tianchi/t/ctc_ddl_multi_db.test +++ b/mysql-test/suite/tianchi/t/ctc_ddl_multi_db.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA --disable_warnings drop database if exists `db-1`; drop database if exists `db-2`; diff --git a/mysql-test/suite/tianchi/t/ctc_ddl_partition.test b/mysql-test/suite/tianchi/t/ctc_ddl_partition.test index 7a0b1c4..29618b0 100644 --- a/mysql-test/suite/tianchi/t/ctc_ddl_partition.test +++ b/mysql-test/suite/tianchi/t/ctc_ddl_partition.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA --disable_warnings drop table if exists t1, t2, t3, t4, t5, t6; --enable_warnings @@ -412,7 +397,7 @@ INSERT INTO t1 (c2) VALUES ('n1'),('n2'),('n3'),('n4'); #期望自增值为15, select * from t1; show create table t1; --error ER_NO_PARTITION_FOR_GIVEN_VALUE -INSERT INTO t1 (c2) VALUES ('n1');#15,超出分区范围,插入失败, +INSERT INTO t1 (c2) VALUES ('n1');#16,超出分区范围,插入失败, select * from t1; show create table t1; select * from t1 partition(p1); @@ -441,13 +426,9 @@ ALTER TABLE t1 ADD PARTITION (PARTITION p1 VALUES LESS THAN (10));#不能在中 ALTER TABLE t1 ADD PARTITION (PARTITION p1 VALUES LESS THAN (20));#添加成功,此时自增值依旧是15 select * from t1; show create table t1; -INSERT INTO t1 (c2) VALUES ('n1');#15,自增值变成16 +INSERT INTO t1 (c2) VALUES ('n1'); select * from t1; show create table t1; -INSERT INTO t1 (c2) VALUES ('n1');#16 -INSERT INTO t1 (c2) VALUES ('n1');#17 -INSERT INTO t1 (c2) VALUES ('n1');#18 -INSERT INTO t1 (c2) VALUES ('n1');#19 --error ER_NO_PARTITION_FOR_GIVEN_VALUE INSERT INTO t1 (c2) VALUES ('n1');#20 插入失败 select * from t1; @@ -459,14 +440,14 @@ alter table t1 drop PARTITION p0;#删除p0后,自增值依旧是20 select * from t1; show create table t1; --error ER_NO_PARTITION_FOR_GIVEN_VALUE -INSERT INTO t1 (c2) VALUES ('n1');#20 插入失败 +INSERT INTO t1 (c2) VALUES ('n1');#21 插入失败 select * from t1; show create table t1; INSERT INTO t1 (c1,c2) VALUES (1,'n1');#插入成功,因为p0被删了,1-4的自增范围被删了 select * from t1; show create table t1; --error ER_NO_PARTITION_FOR_GIVEN_VALUE -INSERT INTO t1 (c2) VALUES ('n1');#20 插入失败 +INSERT INTO t1 (c2) VALUES ('n1');#22 插入失败 select * from t1; show create table t1; INSERT INTO t1 (c1,c2) VALUES (2,'n1'); @@ -488,10 +469,10 @@ show create table t1; alter table t1 drop PARTITION p1;#自增值依旧是20,15-19的值被删了 select * from t1; show create table t1; -ALTER TABLE t1 ADD PARTITION (PARTITION p1 VALUES LESS THAN (25)); +ALTER TABLE t1 ADD PARTITION (PARTITION p1 VALUES LESS THAN (30)); select * from t1; show create table t1; -INSERT INTO t1 (c2) VALUES ('n1');#15 +INSERT INTO t1 (c2) VALUES ('n1'); select * from t1; show create table t1; INSERT INTO t1 (c2) VALUES ('n1'); diff --git a/mysql-test/suite/tianchi/t/ctc_ddl_tablespace.test b/mysql-test/suite/tianchi/t/ctc_ddl_tablespace.test index bff0fb2..290a0df 100644 --- a/mysql-test/suite/tianchi/t/ctc_ddl_tablespace.test +++ b/mysql-test/suite/tianchi/t/ctc_ddl_tablespace.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA --source include/big_test.inc --disable_warnings drop table if exists Dept; diff --git a/mysql-test/suite/tianchi/t/ctc_ddl_temporary_table.test b/mysql-test/suite/tianchi/t/ctc_ddl_temporary_table.test index f9bf89a..dfafe69 100644 --- a/mysql-test/suite/tianchi/t/ctc_ddl_temporary_table.test +++ b/mysql-test/suite/tianchi/t/ctc_ddl_temporary_table.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA --disable_warnings drop table if exists DEMO; --enable_warnings diff --git a/mysql-test/suite/tianchi/t/ctc_ddl_too_many_databases.test b/mysql-test/suite/tianchi/t/ctc_ddl_too_many_databases.test index d646a85..45744e1 100644 --- a/mysql-test/suite/tianchi/t/ctc_ddl_too_many_databases.test +++ b/mysql-test/suite/tianchi/t/ctc_ddl_too_many_databases.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA --source include/big_test.inc DELIMITER |; CREATE PROCEDURE create_databases(db_name varchar(128), start int, cnt int) diff --git a/mysql-test/suite/tianchi/t/ctc_ddl_trigger.test b/mysql-test/suite/tianchi/t/ctc_ddl_trigger.test index 7324628..8a0cfd4 100644 --- a/mysql-test/suite/tianchi/t/ctc_ddl_trigger.test +++ b/mysql-test/suite/tianchi/t/ctc_ddl_trigger.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA --disable_warnings drop table if exists DEMO; drop table if exists DEMO_TRIGGER_LOG; diff --git a/mysql-test/suite/tianchi/t/ctc_ddl_unsupport_command.test b/mysql-test/suite/tianchi/t/ctc_ddl_unsupport_command.test index 0d344d7..7ffd2aa 100644 --- a/mysql-test/suite/tianchi/t/ctc_ddl_unsupport_command.test +++ b/mysql-test/suite/tianchi/t/ctc_ddl_unsupport_command.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #ddl不支持的语句类型测试,需要执行返回错误 #ddl不支持event相关操作 --error 3655 diff --git a/mysql-test/suite/tianchi/t/ctc_ddl_view.test b/mysql-test/suite/tianchi/t/ctc_ddl_view.test index df29f10..b257d7f 100644 --- a/mysql-test/suite/tianchi/t/ctc_ddl_view.test +++ b/mysql-test/suite/tianchi/t/ctc_ddl_view.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA --disable_warnings drop table if exists DEMO; drop table if exists DEMO2; diff --git a/mysql-test/suite/tianchi/t/ctc_delete_time.test b/mysql-test/suite/tianchi/t/ctc_delete_time.test index 8659e0c..56f761b 100644 --- a/mysql-test/suite/tianchi/t/ctc_delete_time.test +++ b/mysql-test/suite/tianchi/t/ctc_delete_time.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA --disable_warnings DROP TABLE IF EXISTS t1,t2,t3,t4; --enable_warnings diff --git a/mysql-test/suite/tianchi/t/ctc_dml_decimal_table.test b/mysql-test/suite/tianchi/t/ctc_dml_decimal_table.test index 93d6255..67711f7 100644 --- a/mysql-test/suite/tianchi/t/ctc_dml_decimal_table.test +++ b/mysql-test/suite/tianchi/t/ctc_dml_decimal_table.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA --disable_warnings drop database if exists test; CREATE database test; diff --git a/mysql-test/suite/tianchi/t/ctc_dml_ignore.test b/mysql-test/suite/tianchi/t/ctc_dml_ignore.test index 959588c..78ef634 100644 --- a/mysql-test/suite/tianchi/t/ctc_dml_ignore.test +++ b/mysql-test/suite/tianchi/t/ctc_dml_ignore.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA --disable_warnings drop table if exists t1,t2; --enable_warnings diff --git a/mysql-test/suite/tianchi/t/ctc_dml_two_table.test b/mysql-test/suite/tianchi/t/ctc_dml_two_table.test index df11420..c37717b 100644 --- a/mysql-test/suite/tianchi/t/ctc_dml_two_table.test +++ b/mysql-test/suite/tianchi/t/ctc_dml_two_table.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # 忽略建库建表过程中执行出错引起中断执行及相关的错误日志输出.result文件,影响结果比较,我们核心只关注DML语句 -- disable_result_log -- disable_abort_on_error diff --git a/mysql-test/suite/tianchi/t/ctc_handler_operation.test b/mysql-test/suite/tianchi/t/ctc_handler_operation.test index 5a89f9c..fe4b31b 100644 --- a/mysql-test/suite/tianchi/t/ctc_handler_operation.test +++ b/mysql-test/suite/tianchi/t/ctc_handler_operation.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA --disable_warnings drop table if exists handler_table; --enable_warnings diff --git a/mysql-test/suite/tianchi/t/ctc_index_functions_base.test b/mysql-test/suite/tianchi/t/ctc_index_functions_base.test index a157e0a..65d6378 100644 --- a/mysql-test/suite/tianchi/t/ctc_index_functions_base.test +++ b/mysql-test/suite/tianchi/t/ctc_index_functions_base.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA --disable_warnings drop table if exists DEMO; --enable_warnings @@ -151,6 +136,5 @@ Select e from DEMO where d = 4 and f = 6; drop table if exists DEMO; -# configure prefetch buffer size -set ctc_prefetch_buf_size=10240; +# show prefetch buffer size show variables like '%ctc_prefetch_buf_size%'; diff --git a/mysql-test/suite/tianchi/t/ctc_insert_time.test b/mysql-test/suite/tianchi/t/ctc_insert_time.test index f9d507a..76f1981 100644 --- a/mysql-test/suite/tianchi/t/ctc_insert_time.test +++ b/mysql-test/suite/tianchi/t/ctc_insert_time.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA --disable_warnings DROP TABLE IF EXISTS t1,t2,t3,t4; --enable_warnings diff --git a/mysql-test/suite/tianchi/t/ctc_json_value.test b/mysql-test/suite/tianchi/t/ctc_json_value.test index 5a3f6ac..510329c 100644 --- a/mysql-test/suite/tianchi/t/ctc_json_value.test +++ b/mysql-test/suite/tianchi/t/ctc_json_value.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # JSON_VALUE with an implicit RETURNING clause (which returns # CHAR(512) with utf8mb4 encoding). diff --git a/mysql-test/suite/tianchi/t/ctc_lcov.test b/mysql-test/suite/tianchi/t/ctc_lcov.test index d128792..3d2d1c7 100644 --- a/mysql-test/suite/tianchi/t/ctc_lcov.test +++ b/mysql-test/suite/tianchi/t/ctc_lcov.test @@ -1,18 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #补充代码覆盖率的简单测试用例,一定要追求速度,不要涉及过度复杂的测试用例 #ctc_ddl_tablespace.test为big-test,门禁里面不会跑,挑选里面的一些有代表性的测试用例,增加tablespace代码覆盖率 @@ -69,3 +54,9 @@ set global autocommit=false; set global autocommit=true; CREATE TEMPORARY TABLE t_processlist AS SELECT ID FROM information_schema.processlist; DROP TABLE t_processlist; +create table t1(a blob default("test")); +alter table t1 add column b varchar(10) default ("test"); +alter table t1 add column b1 varchar(10) default "test"; +alter table t1 add column c bit default ("10"); +alter table t1 add column d bit default (10); +drop table t1; diff --git a/mysql-test/suite/tianchi/t/ctc_link_and_migr_row.test b/mysql-test/suite/tianchi/t/ctc_link_and_migr_row.test index b07c34a..5d379b3 100644 --- a/mysql-test/suite/tianchi/t/ctc_link_and_migr_row.test +++ b/mysql-test/suite/tianchi/t/ctc_link_and_migr_row.test @@ -1,19 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - #### test case come from daac codebase gs_row_chain.sql, only part of it pick up to here #### remember if table column is too long or column size to big, to pick new case from gs_row_chain.sql #### 链接行: diff --git a/mysql-test/suite/tianchi/t/ctc_lock_instance.test b/mysql-test/suite/tianchi/t/ctc_lock_instance.test index a6795e5..e2a9e70 100644 --- a/mysql-test/suite/tianchi/t/ctc_lock_instance.test +++ b/mysql-test/suite/tianchi/t/ctc_lock_instance.test @@ -1,19 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - # test for lock/unlock instance LOCK INSTANCE FOR BACKUP; --error ER_DISALLOWED_OPERATION diff --git a/mysql-test/suite/tianchi/t/ctc_locking_read_concurrency_with_nowait_and_skip_locked.test b/mysql-test/suite/tianchi/t/ctc_locking_read_concurrency_with_nowait_and_skip_locked.test index fcadc5d..6854e6d 100644 --- a/mysql-test/suite/tianchi/t/ctc_locking_read_concurrency_with_nowait_and_skip_locked.test +++ b/mysql-test/suite/tianchi/t/ctc_locking_read_concurrency_with_nowait_and_skip_locked.test @@ -1,19 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - ######################################################################## # # # Testing of Locking Read Concurrency with NOWAIT and SKIP LOCKED # diff --git a/mysql-test/suite/tianchi/t/ctc_partition_update.test b/mysql-test/suite/tianchi/t/ctc_partition_update.test index b08fa2f..d18bfa2 100644 --- a/mysql-test/suite/tianchi/t/ctc_partition_update.test +++ b/mysql-test/suite/tianchi/t/ctc_partition_update.test @@ -1,19 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - # 普通表测试 --disable_warnings drop database if exists db1; diff --git a/mysql-test/suite/tianchi/t/ctc_read_only.test b/mysql-test/suite/tianchi/t/ctc_read_only.test index 156828d..bd4d039 100644 --- a/mysql-test/suite/tianchi/t/ctc_read_only.test +++ b/mysql-test/suite/tianchi/t/ctc_read_only.test @@ -1,19 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - --disable_warnings DROP TABLE IF EXISTS table_11733 ; --enable_warnings diff --git a/mysql-test/suite/tianchi/t/ctc_select_early_return.test b/mysql-test/suite/tianchi/t/ctc_select_early_return.test index ba9a926..3ee66bc 100644 --- a/mysql-test/suite/tianchi/t/ctc_select_early_return.test +++ b/mysql-test/suite/tianchi/t/ctc_select_early_return.test @@ -1,19 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - drop database if exists test_DB; create database test_DB; use test_DB; diff --git a/mysql-test/suite/tianchi/t/ctc_update_time.test b/mysql-test/suite/tianchi/t/ctc_update_time.test index 01354aa..2b75771 100644 --- a/mysql-test/suite/tianchi/t/ctc_update_time.test +++ b/mysql-test/suite/tianchi/t/ctc_update_time.test @@ -1,19 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - --disable_warnings DROP TABLE IF EXISTS t1,t2,t3,t4; --enable_warnings diff --git a/mysql-test/suite/tianchi/t/ctc_varchar.test b/mysql-test/suite/tianchi/t/ctc_varchar.test index 310a3ff..bfd22d1 100644 --- a/mysql-test/suite/tianchi/t/ctc_varchar.test +++ b/mysql-test/suite/tianchi/t/ctc_varchar.test @@ -1,19 +1,3 @@ -# -# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2.0, -# as published by the Free Software Foundation. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License, version 2.0, for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - --disable_warnings drop table if exists DEMO; drop table if exists t1; diff --git a/mysql-test/suite/tianchi/t/recreate_test_db.test b/mysql-test/suite/tianchi/t/recreate_test_db.test new file mode 100644 index 0000000..87a38a4 --- /dev/null +++ b/mysql-test/suite/tianchi/t/recreate_test_db.test @@ -0,0 +1,4 @@ +--disable_warnings +drop database if exists test; +create database test; +--enable_warnings diff --git a/storage/tianchi/datatype_cnvrtr.cc b/storage/tianchi/datatype_cnvrtr.cc index ae29dc9..f9fc4a5 100644 --- a/storage/tianchi/datatype_cnvrtr.cc +++ b/storage/tianchi/datatype_cnvrtr.cc @@ -534,8 +534,8 @@ void convert_json_to_mysql(Field *mysql_field) */ void convert_blob_to_mysql(uchar *cantian_ptr, Field *mysql_field, tianchi_handler_t &tch, uint8_t *mysql_ptr) { + bitmap_set_bit(mysql_field->table->read_set, mysql_field->field_index()); lob_locator_t *locator = (lob_locator_t *)(uint8*)cantian_ptr; - uint32_t blob_len = locator->head.size; char *blob_buf = (char *)my_malloc(PSI_NOT_INSTRUMENTED, blob_len * sizeof(char), MYF(MY_WME)); if (blob_len == 0) { @@ -1518,6 +1518,10 @@ int mysql_record_to_cantian_record(const TABLE &table, record_buf_info_t *record void copy_column_data_to_mysql(field_info_t *field_info, const field_cnvrt_aux_t* mysql_info, tianchi_handler_t &tch, bool is_index_only) { + if (!bitmap_is_set(field_info->field->table->read_set, field_info->field->field_index()) && + tch.sql_command == SQLCOM_SELECT) { + return; + } uchar *src = NULL; uint16_t src_len = 0; switch (mysql_info->sql_data_type) { diff --git a/storage/tianchi/ha_tse.cc b/storage/tianchi/ha_tse.cc index 27a15d6..52b1cab 100644 --- a/storage/tianchi/ha_tse.cc +++ b/storage/tianchi/ha_tse.cc @@ -167,9 +167,9 @@ static MYSQL_THDVAR_UINT(lock_wait_timeout, PLUGIN_VAR_RQCMDARG, "millisecond and values 0 means disable the timeout.", nullptr, nullptr, 50000, 0, 1024 * 1024 * 1024, 0); -static MYSQL_THDVAR_UINT(prefetch_buf_size, PLUGIN_VAR_RQCMDARG, +static MYSQL_THDVAR_UINT(prefetch_buf_size, PLUGIN_VAR_READONLY, "the maximum buf size of data/index prefetch", nullptr, - nullptr, 120 * 1024, 1024, 120 * 1024, 0); + nullptr, 192 * 1024, 0, 192 * 1024, 0); static MYSQL_THDVAR_DOUBLE(sampling_ratio, PLUGIN_VAR_RQCMDARG, "sampling ratio used for analyzing tables", nullptr, @@ -258,6 +258,11 @@ static const Alter_inplace_info::HA_ALTER_FLAGS CTC_ALTER_REBUILD = Alter_inplace_info::ADD_STORED_BASE_COLUMN | Alter_inplace_info::RECREATE_TABLE; +static const Alter_inplace_info::HA_ALTER_FLAGS CTC_ALTER_COL_ORDER = + Alter_inplace_info::DROP_COLUMN | + Alter_inplace_info::ALTER_VIRTUAL_COLUMN_ORDER | + Alter_inplace_info::ALTER_STORED_COLUMN_ORDER; + static const Alter_inplace_info::HA_ALTER_FLAGS PARTITION_OPERATIONS = Alter_inplace_info::ADD_PARTITION | Alter_inplace_info::COALESCE_PARTITION; @@ -284,6 +289,18 @@ void ha_tse_set_inst_id(uint32_t inst_id) { tse_instance_id = inst_id; } handlerton *get_tse_hton() { return tse_hton; } +/* +* Check whether it is CREATE TABLE ... SELECT +* reference: populate_table + */ +static inline bool is_create_table_check(MYSQL_THD thd) { + if (thd->lex->sql_command == SQLCOM_CREATE_TABLE && + thd->lex->is_exec_started()) { + return true; + } + return false; +} + static bool user_var_set(MYSQL_THD thd, string target_str) { user_var_entry *var_entry; var_entry = find_or_nullptr(thd->user_vars, target_str); @@ -309,6 +326,8 @@ dml_flag_t tse_get_dml_flag(THD *thd, bool is_replace, bool auto_inc_used, flag.dup_update= dup_update; flag.auto_inc_step = thd->variables.auto_increment_increment; flag.auto_inc_offset = thd->variables.auto_increment_offset; + flag.auto_increase = false; + flag.is_create_select = is_create_table_check(thd); return flag; } @@ -411,18 +430,6 @@ static void tse_unreg_instance() { } } -/* -* Check whether it is CREATE TABLE ... SELECT -* reference: populate_table -*/ -static inline bool is_create_table_check(MYSQL_THD thd) { - if (thd->lex->sql_command == SQLCOM_CREATE_TABLE && - thd->lex->is_exec_started()) { - return true; - } - return false; -} - /* * Check if the ALTER TABLE operations need table copy * reference: is_inplace_alter_impossible() @@ -737,16 +744,6 @@ bool ha_tse::check_unsupported_operation(THD *thd, HA_CREATE_INFO *create_info) return true; } - // 不支持建表语句中是都同时包含 foreign key, select 和create的情况 - // thd->lex->query_block->field_list_is_empty() 用于判断是否包含select - if (create_info != nullptr && - !thd->lex->query_block->field_list_is_empty() && thd->lex->alter_info && - (thd->lex->alter_info->flags & Alter_info::ADD_FOREIGN_KEY) && - (create_info->db_type->flags & HTON_SUPPORTS_ATOMIC_DDL)) { - my_error(ER_FOREIGN_KEY_WITH_ATOMIC_CREATE_SELECT, MYF(0)); - return true; - } - if (create_info != nullptr && (create_info->options & HA_LEX_CREATE_TMP_TABLE) && !IS_METADATA_NORMALIZATION()) { my_error(ER_NOT_ALLOWED_COMMAND, MYF(0)); return HA_ERR_UNSUPPORTED; @@ -1367,6 +1364,11 @@ void update_member_tch(tianchi_handler_t &tch, handlerton *hton, THD *thd, bool tch.msg_buf = sess_ctx->msg_buf; } #endif +#ifdef METADATA_NORMALIZED + if (thd->is_reading_dd) { + tch.sql_stat_start = 1; + } +#endif } // called in disconnect when current thd is no longer used @@ -1713,7 +1715,14 @@ static int tse_close_connect(handlerton *hton, THD *thd) { tch.is_broadcast = true; } - int ret = tse_close_session(&tch); + tianchi_handler_t local_tch; + memset(&local_tch, 0, sizeof(local_tch)); + local_tch.inst_id = tch.inst_id; + local_tch.sess_addr = tch.sess_addr; + local_tch.thd_id = tch.thd_id; + local_tch.is_broadcast = tch.is_broadcast; + + int ret = tse_close_session(&local_tch); release_sess_ctx(sess_ctx, hton, thd); return convert_tse_error_code_to_mysql((ct_errno_t)ret); } @@ -1732,7 +1741,13 @@ static void tse_kill_connection(handlerton *hton, THD *thd) { return; } - tse_kill_session(&tch); + tianchi_handler_t local_tch; + memset(&local_tch, 0, sizeof(local_tch)); + local_tch.inst_id = tch.inst_id; + local_tch.sess_addr = tch.sess_addr; + local_tch.thd_id = tch.thd_id; + + tse_kill_session(&local_tch); tse_log_system("[TSE_KILL_SESSION]:conn_id:%u, tse_instance_id:%u", tch.thd_id, tch.inst_id); } @@ -2373,6 +2388,20 @@ int ha_tse::handle_auto_increment(bool &has_explicit_autoinc) { THD *thd = ha_thd(); const Discrete_interval *insert_id_info; insert_id_for_cur_row = 0; + /* + 1. Value set by 'SET INSERT_ID=#' + 2. Partition table use auto_inc column as part key, update to 0 + */ + if ((insert_id_info = thd->auto_inc_intervals_forced.get_next()) != nullptr) { + // store insert_id to auto_inc col, reset insert_id + ulonglong forced_val = insert_id_info->minimum(); + table->next_number_field->store(forced_val, true); + thd->auto_inc_intervals_forced.clear(); + has_explicit_autoinc = true; + insert_id_for_cur_row = forced_val; + return CT_SUCCESS; + } + /* if has explicit auto_inc value 1. specify value that is neither null nor zero @@ -2389,17 +2418,6 @@ int ha_tse::handle_auto_increment(bool &has_explicit_autoinc) { return CT_SUCCESS; } - // if specify insert_id, use and treat that as explicit value - if ((insert_id_info = thd->auto_inc_intervals_forced.get_next()) != nullptr) { - // store insert_id to auto_inc col, reset insert_id - ulonglong forced_val = insert_id_info->minimum(); - table->next_number_field->store(forced_val, true); - thd->auto_inc_intervals_forced.clear(); - has_explicit_autoinc = true; - insert_id_for_cur_row = forced_val; - return CT_SUCCESS; - } - has_explicit_autoinc = false; return CT_SUCCESS; } @@ -2433,8 +2451,12 @@ int ha_tse::handle_auto_increment(bool &has_explicit_autoinc) { item_sum.cc, item_sum.cc, sql_acl.cc, sql_insert.cc, sql_insert.cc, sql_select.cc, sql_table.cc, sql_udf.cc and sql_update.cc */ - +#ifdef METADATA_NORMALIZED +EXTER_ATTACK int ha_tse::write_row(uchar *buf, bool write_through) { +#endif +#ifndef METADATA_NORMALIZED EXTER_ATTACK int ha_tse::write_row(uchar *buf) { +#endif DBUG_TRACE; THD *thd = ha_thd(); @@ -2460,6 +2482,12 @@ EXTER_ATTACK int ha_tse::write_row(uchar *buf) { if (!m_rec_buf_4_writing) { dml_flag_t flag = tse_get_dml_flag(thd, false, auto_inc_used, has_explicit_autoinc, false); +#ifdef METADATA_NORMALIZED + flag.write_through = write_through; +#endif +#ifndef METADATA_NORMALIZED + flag.write_through = false; +#endif error_result = convert_mysql_record_and_write_to_cantian(buf, &cantian_record_buf_size, &serial_column_offset, flag); return error_result; } @@ -2600,6 +2628,29 @@ int ha_tse::end_bulk_insert() { return ret; } +int tse_cmp_key_values(TABLE *table, const uchar *old_data, const uchar *new_data, uint key_nr) { + if (key_nr == MAX_KEY) { + return 0; + } + + KEY *key_info = table->key_info + key_nr; + KEY_PART_INFO *key_part = key_info->key_part; + KEY_PART_INFO *key_part_end = key_part + key_info->user_defined_key_parts; + + for (; key_part != key_part_end; key_part++) { + Field *field = key_part->field; + if (key_part->key_part_flag & (HA_BLOB_PART | HA_VAR_LENGTH_PART)) { + if (field->cmp_binary((old_data + key_part->offset), (new_data + key_part->offset), (ulong)key_part->length)) { + return 1; + } + } else if (memcmp(old_data + key_part->offset, new_data + key_part->offset, key_part->length)) { + return 1; + } + } + + return 0; +} + /** @brief Yes, update_row() does what you expect, it updates a row. old_data will have @@ -2623,9 +2674,19 @@ int ha_tse::end_bulk_insert() { @see sql_select.cc, sql_acl.cc, sql_update.cc and sql_insert.cc */ -EXTER_ATTACK int ha_tse::update_row(const uchar *, uchar *new_data) { +EXTER_ATTACK int ha_tse::update_row(const uchar *old_data, uchar *new_data) { DBUG_TRACE; + THD *thd = ha_thd(); + m_is_replace = (thd->lex->sql_command == SQLCOM_REPLACE || + thd->lex->sql_command == SQLCOM_REPLACE_SELECT) ? true : m_is_replace; + if (thd->lex->sql_command == SQLCOM_REPLACE || thd->lex->sql_command == SQLCOM_REPLACE_SELECT) { + uint key_nr = table->file->errkey; + if (key_nr < MAX_KEY && tse_cmp_key_values(table, old_data, new_data, key_nr) != 0) { + return HA_ERR_KEY_NOT_FOUND; + } + } + int cantian_new_record_buf_size = TSE_BUF_LEN; uint16_t serial_column_offset = 0; ha_statistic_increment(&System_status_var::ha_update_count); @@ -2660,8 +2721,7 @@ EXTER_ATTACK int ha_tse::update_row(const uchar *, uchar *new_data) { } // (m_ignore_dup && m_is_replace) -> special case for load data ... replace into bool dup_update = m_is_insert_dup || (m_ignore_dup && m_is_replace); - THD *thd = ha_thd(); - dml_flag_t flag = tse_get_dml_flag(thd, false, false, false, dup_update); + dml_flag_t flag = tse_get_dml_flag(thd, m_is_replace, false, false, dup_update); if (!flag.no_foreign_key_check) { flag.no_cascade_check = flag.dd_update ? true : pre_check_for_cascade(true); } @@ -2810,7 +2870,7 @@ void ha_tse::update_blob_addrs(uchar *record) { ptrdiff_t old_ptr = (ptrdiff_t)(record - table->record[0]); for (uint i = 0; i < table->s->blob_fields; i++) { uint field_no = table->s->blob_field[i]; - if (m_is_covering_index && !bitmap_is_set(table->read_set, field_no)) { + if (!bitmap_is_set(table->read_set, field_no)) { continue; } @@ -3639,6 +3699,12 @@ enum_alter_inplace_result ha_tse::check_if_supported_inplace_alter( TABLE *altered_table, Alter_inplace_info *ha_alter_info) { DBUG_TRACE; THD *thd = ha_thd(); + + // remote node execute ALTER statement using default way + if (engine_ddl_passthru(thd)) { + return HA_ALTER_INPLACE_EXCLUSIVE_LOCK; + } + m_error_if_not_empty = ha_alter_info->error_if_not_empty; if (ha_alter_info->handler_flags & ~(CTC_INPLACE_IGNORE | CTC_ALTER_NOREBUILD | CTC_ALTER_REBUILD)) { if (ha_alter_info->handler_flags & COLUMN_TYPE_OPERATIONS) { @@ -3660,8 +3726,7 @@ enum_alter_inplace_result ha_tse::check_if_supported_inplace_alter( return HA_ALTER_INPLACE_NOT_SUPPORTED; } - if ((ha_alter_info->handler_flags & Alter_inplace_info::ALTER_STORED_COLUMN_ORDER) || - (ha_alter_info->handler_flags & Alter_inplace_info::DROP_STORED_COLUMN)) { + if (ha_alter_info->handler_flags & CTC_ALTER_COL_ORDER) { ha_alter_info->unsupported_reason = "Altering column order or drop column"; return HA_ALTER_INPLACE_NOT_SUPPORTED; } @@ -4552,7 +4617,11 @@ void ha_tse::update_create_info(HA_CREATE_INFO *create_info) { uint16_t auto_inc_step = thd->variables.auto_increment_increment; uint16_t auto_inc_offset = thd->variables.auto_increment_offset; update_member_tch(m_tch, tse_hton, thd); - ret = tse_get_serial_value(&m_tch, &inc_value, auto_inc_step, auto_inc_offset); + dml_flag_t flag; + flag.auto_inc_offset = auto_inc_offset; + flag.auto_inc_step = auto_inc_step; + flag.auto_increase = false; + ret = tse_get_serial_value(&m_tch, &inc_value, flag); update_sess_ctx_by_tch(m_tch, tse_hton, thd); if (ret != 0) { create_info->auto_increment_value = (ulonglong)0; @@ -4726,13 +4795,26 @@ EXTER_ATTACK int ha_tse::create(const char *name, TABLE *form, HA_CREATE_INFO *c return HA_ERR_WRONG_COMMAND; } + /* + copy algorithm is used when ha_create is called by mysql_alter_table + */ + bool is_tmp_table = create_info->options & HA_LEX_CREATE_TMP_TABLE || tse_is_temporary(table_def); + if (thd->lex->sql_command != SQLCOM_CREATE_TABLE && thd->lex->sql_command != SQLCOM_CREATE_VIEW + && thd->lex->alter_info) { + if (is_tmp_table) { + tse_log_system("Unsupported operation. sql = %s", thd->query().str); + return HA_ERR_NOT_ALLOWED_COMMAND; + } + // do not move this under engine_ddl_passthru(thd) function + thd->lex->alter_info->requested_algorithm = Alter_info::ALTER_TABLE_ALGORITHM_COPY; + } + if (engine_ddl_passthru(thd)) { return ret; } char db_name[SMALL_RECORD_SIZE] = {0}; char table_name[SMALL_RECORD_SIZE] = {0}; - bool is_tmp_table = create_info->options & HA_LEX_CREATE_TMP_TABLE || tse_is_temporary(table_def); tse_split_normalized_name(name, db_name, SMALL_RECORD_SIZE, table_name, SMALL_RECORD_SIZE, &is_tmp_table); if (!is_tmp_table) { TSE_RETURN_IF_NOT_ZERO(check_tse_identifier_name(table_def->name().c_str())); @@ -4747,19 +4829,6 @@ EXTER_ATTACK int ha_tse::create(const char *name, TABLE *form, HA_CREATE_INFO *c return ha_tse_truncate_table(&m_tch, thd, db_name, table_name, is_tmp_table); } - /* - copy algorithm is used when ha_create is called by mysql_alter_table - */ - - if (thd->lex->sql_command != SQLCOM_CREATE_TABLE && thd->lex->sql_command != SQLCOM_CREATE_VIEW - && thd->lex->alter_info) { - if (is_tmp_table) { - tse_log_system("Unsupported operation. sql = %s", thd->query().str); - return HA_ERR_NOT_ALLOWED_COMMAND; - } - thd->lex->alter_info->requested_algorithm = Alter_info::ALTER_TABLE_ALGORITHM_COPY; - } - if (get_cantian_record_length(form) > CT_MAX_RECORD_LENGTH) { return HA_ERR_TOO_BIG_ROW; } @@ -5035,8 +5104,8 @@ int ha_tse::get_cbo_stats_4share() { THD *thd = ha_thd(); int ret = CT_SUCCESS; - - if (m_share && m_share->need_fetch_cbo) { + time_t now = time(nullptr); + if (m_share && (m_share->need_fetch_cbo || now - m_share->get_cbo_time > 60)) { if (m_tch.ctx_addr == INVALID_VALUE64) { char user_name[SMALL_RECORD_SIZE]; tse_split_normalized_name(table->s->normalized_path.str, user_name, SMALL_RECORD_SIZE, nullptr, 0, nullptr); @@ -5054,6 +5123,7 @@ int ha_tse::get_cbo_stats_4share() if (ret == CT_SUCCESS && m_share->cbo_stats->is_updated) { m_share->need_fetch_cbo = false; } + m_share->get_cbo_time = now; } return ret; diff --git a/storage/tianchi/ha_tse.h b/storage/tianchi/ha_tse.h index fb0aee5..fd9a7db 100644 --- a/storage/tianchi/ha_tse.h +++ b/storage/tianchi/ha_tse.h @@ -44,7 +44,7 @@ using namespace std; #define _INT_TO_STR(s) #s #define INT_TO_STR(s) _INT_TO_STR(s) -#define CTC_CLIENT_VERSION_MAIN 1 +#define CTC_CLIENT_VERSION_MAIN 3 #define CTC_CLIENT_VERSION_MINOR 0 #define CTC_CLIENT_VERSION_PATCH 0 #define CTC_CLIENT_VERSION_BUGFIX 101 @@ -52,7 +52,10 @@ using namespace std; INT_TO_STR(CTC_CLIENT_VERSION_MAIN) \ "." INT_TO_STR(CTC_CLIENT_VERSION_MINOR) "." INT_TO_STR(CTC_CLIENT_VERSION_PATCH) \ "." INT_TO_STR(CTC_CLIENT_VERSION_BUGFIX) -#define CTC_CLIENT_VERSION_NUMBER 1000000U + +// 版本号规则:十六进制后两位为小数点后数字,前面为小数点前数字,0x0310 --> 显示为3.16 +#define CTC_CLIENT_VERSION_NUMBER 0x0300u + #define CT_NULL_VALUE_LEN (uint16)0xFFFF #define INVALID_MAX_UINT32 (uint32_t)0xFFFFFFFF @@ -126,7 +129,8 @@ again. */ #define TMP_DIR "tmp" #define TSE_TMP_TABLE 1 -#define TSE_INTERNAL_TMP_TABLE 8 +#define TSE_INTERNAL_TMP_TABLE 2 +#define TSE_TABLE_CONTAINS_VIRCOL 4 /* cond pushdown */ @@ -226,7 +230,8 @@ class Tse_share : public Handler_share { public: tianchi_cbo_stats_t *cbo_stats = nullptr; int used_count = 0; - bool need_fetch_cbo = true; + bool need_fetch_cbo = false; + time_t get_cbo_time = 0; }; /** @brief @@ -458,7 +463,13 @@ public: int close(void) override; // required +#ifdef METADATA_NORMALIZED + int write_row(uchar *buf, bool write_through = false) override; +#endif + +#ifndef METADATA_NORMALIZED int write_row(uchar *buf) override; +#endif int update_row(const uchar *old_data, uchar *new_data) override; diff --git a/storage/tianchi/ha_tse_ddl.cc b/storage/tianchi/ha_tse_ddl.cc index 9c1f34b..bd37c55 100644 --- a/storage/tianchi/ha_tse_ddl.cc +++ b/storage/tianchi/ha_tse_ddl.cc @@ -476,42 +476,43 @@ static bool tse_ddl_fill_column_by_field_fill_type(TcDb__TseDDLColumnDef *column return true; } -static int tse_prepare_enum_field(THD *thd, Create_field *sql_field) { +static int tse_prepare_enum_field_impl(THD *thd, Create_field *sql_field, String *def) { DBUG_TRACE; assert(sql_field->sql_type == MYSQL_TYPE_ENUM); - - if (sql_field->constant_default != nullptr) { - String str; - String *def = sql_field->constant_default->val_str(&str); - /* SQL "NULL" maps to NULL */ - if (def == nullptr) { - if ((sql_field->flags & NOT_NULL_FLAG) != 0) { - my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); - return TSE_ENUM_DEFAULT_NULL; - } - } else { - def->length(sql_field->charset->cset->lengthsp(sql_field->charset, def->ptr(), def->length())); - TYPELIB *interval = sql_field->interval; - if (!interval) { - interval = create_typelib(thd->mem_root, sql_field); - } - uint enum_index = find_type2(interval, def->ptr(), def->length(), sql_field->charset); - if (enum_index == 0) { + if (!sql_field->charset) { + sql_field->charset = &my_charset_bin; + } + /* SQL "NULL" maps to NULL */ + if (def == nullptr) { + if ((sql_field->flags & NOT_NULL_FLAG) != 0) { my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); - return TSE_ENUM_DEFAULT_INVALID; + return TSE_ENUM_DEFAULT_NULL; } - return enum_index; + } else { + def->length(sql_field->charset->cset->lengthsp(sql_field->charset, def->ptr(), def->length())); + TYPELIB *interval = sql_field->interval; + if (!interval) { + interval = create_typelib(thd->mem_root, sql_field); } + uint enum_index = find_type2(interval, def->ptr(), def->length(), sql_field->charset); + if (enum_index == 0) { + my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); + return TSE_ENUM_DEFAULT_INVALID; + } + return enum_index; } my_error(ER_INVALID_DEFAULT, MYF(0), "constant default is null"); return TSE_ENUM_DEFAULT_INVALID; } -static bool tse_prepare_set_field(THD *thd, Create_field *sql_field, ulonglong *set_bitmap, - TcDb__TseDDLColumnDef *column) { +static bool tse_prepare_set_field_impl(THD *thd, Create_field *sql_field, ulonglong *set_bitmap, + String *def, TcDb__TseDDLColumnDef *column) { DBUG_TRACE; assert(sql_field->sql_type == MYSQL_TYPE_SET); + if (!sql_field->charset) { + sql_field->charset = &my_charset_bin; + } TYPELIB *interval = sql_field->interval; if (!interval) { /* @@ -543,64 +544,114 @@ static bool tse_prepare_set_field(THD *thd, Create_field *sql_field, ulonglong * } } - if (sql_field->constant_default != nullptr) { - const char *not_used; - uint not_used2; - bool not_found = false; - String default_str; - String *def = sql_field->constant_default->val_str(&default_str); - // SQL "NULL" maps to NULL - if (def == nullptr) { - if ((sql_field->flags & NOT_NULL_FLAG) != 0) { - my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); - return false; - } else { - // else, NULL is an allowed value - *set_bitmap = find_set(interval, nullptr, 0, sql_field->charset, ¬_used, ¬_used2, ¬_found); - } + const char *not_used; + uint not_used2; + bool not_found = false; + // SQL "NULL" maps to NULL + if (def == nullptr) { + if ((sql_field->flags & NOT_NULL_FLAG) != 0) { + my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); + return false; } else { - // default not NULL */ - *set_bitmap = find_set(interval, def->ptr(), def->length(), sql_field->charset, ¬_used, ¬_used2, ¬_found); - } + // else, NULL is an allowed value + *set_bitmap = find_set(interval, nullptr, 0, sql_field->charset, ¬_used, ¬_used2, ¬_found); + } + } else { + // default not NULL */ + *set_bitmap = find_set(interval, def->ptr(), def->length(), sql_field->charset, ¬_used, ¬_used2, ¬_found); + } - if (not_found) { - my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); + if (not_found) { + my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); + return false; + } + + return true; +} + +static bool tse_process_string_default_value(TcDb__TseDDLColumnDef *column, string &expr_str, + char **mem_start, char *mem_end, bool is_blob_type) { + if (!is_blob_type) { + boost::algorithm::replace_all(expr_str, "'", "''"); + column->default_text = (char *)tse_ddl_alloc_mem(mem_start, mem_end, expr_str.length() + 1); + if (column->default_text == nullptr) { + tse_log_error("alloc mem for bit default text failed, mem_start is null"); + return false; + } + strncpy(column->default_text, expr_str.c_str(), expr_str.length() + 1); + } else { + column->default_text = (char *)tse_ddl_alloc_mem(mem_start, mem_end, expr_str.length() * 2 + 1); + if (column->default_text == nullptr) { + tse_log_error("alloc mem for bit default text failed, mem_start is null"); return false; } + int pos = 0; + for (char &ch : expr_str) { + sprintf(column->default_text + pos, "%02X", ch); + pos += 2; + } + column->default_text[pos] = '\0'; } - return true; } static bool tse_get_bit_default_value( - THD *thd, TcDb__TseDDLColumnDef *column, Field *field, char **mem_start, char *mem_end) { + THD *thd, TcDb__TseDDLColumnDef *column, Field *field, const Create_field *fld, const dd::Column *col_obj, + char **mem_start, char *mem_end, bool is_expr_value) { column->is_unsigned = 1; - Field_bit *bitfield = dynamic_cast(field); - - Field_bit *new_field = bitfield->clone(thd->mem_root); - uchar bit_ptr[TSE_MAX_BIT_LEN]; - for (uint32_t i = 0; i < bitfield->bytes_in_rec; i++) { - bit_ptr[i] = bitfield->field_ptr()[i]; + longlong num = 0; + if (!is_expr_value) { + char* bit_value_buf = const_cast(col_obj->default_value().data()); + uint32_t bit_value_len = (uint32_t)(col_obj->default_value().length()); + Field_bit *bitfield = dynamic_cast(field); + Field_bit *new_field = bitfield->clone(thd->mem_root); + uchar bit_ptr[TSE_MAX_BIT_LEN]; + for (uint32_t i = 0; i < bit_value_len; i++) { + bit_ptr[i] = bit_value_buf[i]; + } + new_field->set_field_ptr(bit_ptr); + num = new_field->val_int(); + } else { + Item *expr_item; + if (fld == nullptr) { + expr_item = field->m_default_val_expr->expr_item; + } else { + expr_item = fld->m_default_val_expr->expr_item; + } + if (expr_item->type() != Item::STRING_ITEM) { + num = expr_item->val_int(); + } else { + StringBuffer tmp; + String *res = expr_item->val_str(&tmp); + if (res == nullptr) { + num = 0; + } else { + int err = 0; + num = my_strntoll(res->charset(), res->ptr(), res->length(), 10, nullptr, + &err); + if (err) { + string expr_str(res->c_ptr()); + return tse_process_string_default_value(column, expr_str, mem_start, mem_end, false); + } + } + } } - new_field->set_field_ptr(bit_ptr); - - uint32_t num_len = to_string(new_field->val_int()).length(); + uint32_t num_len = to_string(num).length(); column->default_text = (char *)tse_ddl_alloc_mem(mem_start, mem_end, num_len + 1); if (column->default_text == nullptr) { tse_log_error("alloc mem for bit default text failed, mem_start is null"); return false; } - - sprintf(column->default_text, "%llu", new_field->val_int());; + sprintf(column->default_text, "%llu", num); column->default_text[num_len] = '\0'; return true; } static bool tse_get_datetime_default_value( - TcDb__TseDDLColumnDef *column, Field *field, const dd::Column *col_obj, - char **mem_start, char *mem_end, tse_column_option_set_bit *option_set) { + TcDb__TseDDLColumnDef *column, Field *field, const Create_field *fld, const dd::Column *col_obj, + char **mem_start, char *mem_end, tse_column_option_set_bit *option_set, bool is_expr_value) { if (field->has_insert_default_datetime_value_expression()) { // current_timestamp (or with ON UPDATE CURRENT_TIMESTAMP) option_set->is_default_func = 1; @@ -614,16 +665,29 @@ static bool tse_get_datetime_default_value( // ON UPDATE CURRENT_TIMESTAMP without default_value return true; } - const uchar *mysql_ptr = (const uchar *)(col_obj->default_value().data()); - const field_cnvrt_aux_t* mysql_info = get_auxiliary_for_field_convert(field, field->type()); - assert(mysql_info != NULL); - date_detail_t date_detail; // decode mysql datetime from binary MYSQL_TIME ltime; memset(<ime, 0, sizeof(MYSQL_TIME)); memset(&date_detail, 0, sizeof(date_detail_t)); - decode_mysql_datetime(ltime, mysql_info, mysql_ptr, field); + const field_cnvrt_aux_t* mysql_info = get_auxiliary_for_field_convert(field, field->type()); + assert(mysql_info != NULL); + string expr_str; + if (is_expr_value) { + String str; + if (fld) { + expr_str = (fld->m_default_val_expr->expr_item->val_str(&str))->c_ptr(); + } else { + expr_str = (field->m_default_val_expr->expr_item->val_str(&str))->c_ptr(); + } + MYSQL_TIME_STATUS status; + str_to_datetime(expr_str.c_str(), expr_str.length(), <ime, TIME_FRAC_TRUNCATE | TIME_FUZZY_DATE, + &status); + } else { + expr_str = const_cast(col_obj->default_value_utf8().data()); + const uchar *mysql_ptr = (const uchar *)(col_obj->default_value().data()); + decode_mysql_datetime(ltime, mysql_info, mysql_ptr, field); + } int ret = assign_mysql_date_detail(mysql_info->mysql_field_type, ltime, &date_detail); if (ret != CT_SUCCESS) { @@ -638,27 +702,59 @@ static bool tse_get_datetime_default_value( memcpy(column->default_text, tmp_zero_date, strlen(tmp_zero_date) + 1); return true; } - if (field->real_type() == MYSQL_TYPE_TIME2) { - char * tmp_value = const_cast(col_obj->default_value_utf8().data()); column->default_text = (char *)tse_ddl_alloc_mem(mem_start, mem_end, - sizeof(char) * (strlen(tmp_value) + sizeof("1900-01-01 ") + 1)); + sizeof(char) * (expr_str.length() + sizeof("1900-01-01 ") + 1)); assert(column->default_text != NULL); - sprintf(column->default_text, "1900-01-01 %s", tmp_value); - } else if (field->real_type() == MYSQL_TYPE_TIMESTAMP2) { + sprintf(column->default_text, "1900-01-01 %s", expr_str.c_str()); + } else if (!is_expr_value && field->real_type() == MYSQL_TYPE_TIMESTAMP2) { char tmp_timestamp[MAX_DATE_STRING_REP_LENGTH]; int len = my_datetime_to_str(ltime, tmp_timestamp, field->decimals()); column->default_text = (char *)tse_ddl_alloc_mem(mem_start, mem_end, len + 1); assert(column->default_text != NULL); - memset(column->default_text, 0, len + 1); - memcpy(column->default_text, tmp_timestamp, len); + memset(column->default_text, 0, len + 1); + memcpy(column->default_text, tmp_timestamp, len); + column->default_text[len] = '\0'; } else { - column->default_text = const_cast(col_obj->default_value_utf8().data()); + column->default_text = (char *)tse_ddl_alloc_mem(mem_start, mem_end, expr_str.length() + 1); + strncpy(column->default_text, expr_str.c_str(), expr_str.length() + 1); } - return true; } +static int tse_prepare_enum_field(THD *thd, Field *field, const Create_field *fld, + const CHARSET_INFO *field_cs) { + int is_enum = 0; + String default_str; + String *def; + Create_field* sql_field; + // fld == nullptr 为create,此时field_charset 为空值需处理置位 + if (fld == nullptr) { + Create_field sql_field_local(field, field); + if (!field_cs) { + sql_field_local.charset = field_cs; + } + sql_field = sql_field_local.clone(thd->mem_root); + } else { + // fld != nullptr 为alter,此时field_charset 有值不用置位 + sql_field = const_cast(fld); + } + if (sql_field->constant_default != nullptr) { + def = sql_field->constant_default->val_str(&default_str); + } else { + def = sql_field->m_default_val_expr->expr_item->val_str(&default_str); + } + if (fld == nullptr) { + // 修改ENUM default带charset + // 或设置了全局charset找不到enum_index + // 判断当前charset与field charset是否一致 + if(field_cs == nullptr || strcmp(def->charset()->csname, field_cs->csname) != 0) { + sql_field->charset = def->charset(); + } + } + is_enum = tse_prepare_enum_field_impl(thd, sql_field, def); + return is_enum; +} static bool tse_get_enum_default_value( THD *thd, TcDb__TseDDLColumnDef *column, const dd::Column *col_obj, Field *field, const Create_field *fld, @@ -666,25 +762,8 @@ static bool tse_get_enum_default_value( int is_enum; column->is_unsigned = 1; column->datatype->datatype = column->datatype->size == 1 ? TSE_DDL_TYPE_TINY : TSE_DDL_TYPE_SHORT; - // fld == nullptr 为create,此时field_charset 为空值需处理置位 - if (fld == nullptr) { - Create_field sql_field(field, field); - sql_field.charset = field_cs; - // 修改ENUM default带charset - // 或设置了全局charset找不到enum_index - if (sql_field.constant_default != nullptr) { - String default_str; - String *def = sql_field.constant_default->val_str(&default_str); - // 判断当前charset与field charset是否一致 - if(field_cs == nullptr || strcmp(def->charset()->csname, field_cs->csname) != 0) { - sql_field.charset = def->charset(); - } - } - is_enum = tse_prepare_enum_field(thd, &sql_field); - } else { - // fld != nullptr 为alter,此时field_charset 有值不用置位 - is_enum = tse_prepare_enum_field(thd, const_cast(fld)); - } + + is_enum = tse_prepare_enum_field(thd, field, fld, field_cs); if (is_enum == TSE_ENUM_DEFAULT_INVALID) { return false; @@ -702,6 +781,38 @@ static bool tse_get_enum_default_value( return true; } +static bool tse_prepare_set_field(THD *thd, Field *field, const Create_field *fld, const CHARSET_INFO *field_cs, + ulonglong *set_bitmap, TcDb__TseDDLColumnDef *column) { + bool is_get_set_bitmap = 0; + String default_str; + String *def; + Create_field* sql_field; + // fld == nullptr 为create,此时field_charset 为空值需处理置位 + if (fld == nullptr) { + Create_field sql_field_local(field, field); + if (!field_cs) { + sql_field_local.charset = field_cs; + } + sql_field = sql_field_local.clone(thd->mem_root); + } else { + // fld != nullptr 为alter,此时field_charset 有值不用置位 + sql_field = const_cast(fld); + } + if (sql_field->constant_default != nullptr) { + def = sql_field->constant_default->val_str(&default_str); + } else { + def = sql_field->m_default_val_expr->expr_item->val_str(&default_str); + } + if (fld == nullptr) { + if(field_cs == nullptr || strcmp(def->charset()->csname, field_cs->csname) != 0) { + sql_field->charset = def->charset(); + } + } + + is_get_set_bitmap = tse_prepare_set_field_impl(thd, sql_field, set_bitmap, def, column); + return is_get_set_bitmap; +} + static bool tse_get_set_default_value( THD *thd, TcDb__TseDDLColumnDef *column, Field *field, const Create_field *fld, char **mem_start, char *mem_end, const CHARSET_INFO *field_cs) { @@ -711,24 +822,7 @@ static bool tse_get_set_default_value( column->is_unsigned = 1; } // fld == nullptr 为create,此时field_charset 为空值需处理置位 - if (fld == nullptr) { - Create_field sql_field(field, field); - sql_field.charset = field_cs; - // 修改ENUM default带charset - // 或设置了全局charset找不到enum_index - if (sql_field.constant_default != nullptr) { - String default_str; - String *def = sql_field.constant_default->val_str(&default_str); - // 判断当前charset与field charset是否一致 - if(field_cs == nullptr || strcmp(def->charset()->csname, field_cs->csname) != 0) { - sql_field.charset = def->charset(); - } - } - is_get_set_bitmap = tse_prepare_set_field(thd, &sql_field, &set_bitmap, column); - } else { - // fld != nullptr 为alter,此时field_charset 有值不用置位 - is_get_set_bitmap = tse_prepare_set_field(thd, const_cast(fld), &set_bitmap, column); - } + is_get_set_bitmap = tse_prepare_set_field(thd, field, fld, field_cs, &set_bitmap, column); if (!is_get_set_bitmap) { return false; @@ -743,11 +837,26 @@ static bool tse_get_set_default_value( return true; } -static void tse_get_string_default_value( +static bool tse_verify_string_default_length(TcDb__TseDDLColumnDef *column, String* default_str, Field *field, + const Create_field *fld) { + if (column->datatype->datatype == TSE_DDL_TYPE_CLOB) { + return true; + } + const CHARSET_INFO* col_charset = fld ? fld->charset : field->charset(); + int max_char_count = column->datatype->size / col_charset->mbmaxlen; + int default_str_char_count = default_str->numchars(); + if (default_str_char_count > max_char_count) { + my_error(ER_INVALID_DEFAULT, MYF(0), column->name); + return false; + } + return true; +} + +static bool tse_get_string_default_value( TcDb__TseDDLColumnDef *column, Field *field, const dd::Column *col_obj, const Create_field *fld, - char **mem_start, char *mem_end) { + char **mem_start, char *mem_end, bool is_blob_type) { char *field_default_string = nullptr; - if (fld == nullptr || (fld && fld->constant_default == nullptr)) { + if (fld == nullptr) { if (!field->m_default_val_expr) { if (field->real_type() == MYSQL_TYPE_STRING) { field_default_string = const_cast(col_obj->default_value().data()); @@ -756,19 +865,64 @@ static void tse_get_string_default_value( } } else { String tmp_string; + String* tmp_string_ptr; assert(field->m_default_val_expr); - field_default_string = (field->m_default_val_expr->expr_item->val_str(&tmp_string))->c_ptr(); + tmp_string_ptr = field->m_default_val_expr->expr_item->val_str(&tmp_string); + if (!is_blob_type && !tse_verify_string_default_length(column, tmp_string_ptr, field, fld)) { + return false; + } + field_default_string = tmp_string_ptr->c_ptr(); } } else { // for alter table add column String tmp_string; - field_default_string = (fld->constant_default->val_str(&tmp_string))->c_ptr(); + String* tmp_string_ptr; + if (fld->constant_default != nullptr) { + tmp_string_ptr = fld->constant_default->val_str(&tmp_string); + } else { + tmp_string_ptr = fld->m_default_val_expr->expr_item->val_str(&tmp_string); + } + if (!tse_verify_string_default_length(column, tmp_string_ptr, field, fld)) { + return false; + } + field_default_string = tmp_string_ptr->c_ptr(); } string expr_str(field_default_string); - boost::algorithm::replace_all(expr_str, "'", "''"); - column->default_text = (char *)tse_ddl_alloc_mem(mem_start, mem_end, sizeof(char) * (expr_str.length() + 1)); - strncpy(column->default_text, expr_str.c_str(), expr_str.length() + 1); - return; + return tse_process_string_default_value(column, expr_str, mem_start, mem_end, is_blob_type); +} + +static bool tse_get_numeric_default_value( + TcDb__TseDDLColumnDef *column, Field *field, const dd::Column *col_obj, const Create_field *fld, + char **mem_start, char *mem_end, bool is_expr_value) +{ + char *field_default_string = nullptr; + if (is_expr_value) { + String tmp_string; + Item* expr_item; + expr_item = fld ? fld->m_default_val_expr->expr_item : field->m_default_val_expr->expr_item; + if (expr_item->type() == Item::VARBIN_ITEM) { + longlong num = expr_item->val_int(); + uint32_t num_len = to_string(num).length(); + column->default_text = (char *)tse_ddl_alloc_mem(mem_start, mem_end, num_len + 1); + if (column->default_text == nullptr) { + tse_log_error("alloc mem for set default text failed, mem_start is null"); + return false; + } + sprintf(column->default_text, "%llu", num); + column->default_text[num_len] = '\0'; + } else { + field_default_string = expr_item->val_str(&tmp_string)->c_ptr(); + column->default_text = (char *)tse_ddl_alloc_mem(mem_start, mem_end, strlen(field_default_string) + 1); + if (column->default_text == nullptr) { + tse_log_error("alloc mem for set default text failed, mem_start is null"); + return false; + } + strncpy(column->default_text, field_default_string, strlen(field_default_string) + 1); + } + } else { + column->default_text = const_cast(col_obj->default_value_utf8().data()); + } + return true; } static bool tse_check_expression_default_value(TcDb__TseDDLColumnDef *column, Field *field, const Create_field *fld, @@ -804,6 +958,7 @@ static bool tse_check_expression_default_value(TcDb__TseDDLColumnDef *column, Fi return true; } + static bool tse_ddl_fill_column_default_value( THD *thd, TcDb__TseDDLColumnDef *column, Field *field, const Create_field *fld, const dd::Column *col_obj, tse_column_option_set_bit *option_set, char **mem_start, char *mem_end, const CHARSET_INFO *field_cs) { @@ -823,12 +978,14 @@ static bool tse_ddl_fill_column_default_value( return true; } } - + + bool is_blob_type = false; switch (field->real_type()) { case MYSQL_TYPE_BIT: - TSE_RETURN_IF_ERROR(tse_get_bit_default_value(thd, column, field, mem_start, mem_end), false); + TSE_RETURN_IF_ERROR(tse_get_bit_default_value(thd, column, field, fld, col_obj, mem_start, mem_end, is_expr_value), false); break; case MYSQL_TYPE_BLOB: + is_blob_type = (column->datatype->datatype != TSE_DDL_TYPE_CLOB); case MYSQL_TYPE_JSON: if (!is_expr_value) { column->default_text = const_cast(col_obj->default_value_utf8().data()); @@ -836,7 +993,7 @@ static bool tse_ddl_fill_column_default_value( } case MYSQL_TYPE_STRING: case MYSQL_TYPE_VARCHAR: - tse_get_string_default_value(column, field, col_obj, fld, mem_start, mem_end); + TSE_RETURN_IF_ERROR(tse_get_string_default_value(column, field, col_obj, fld, mem_start, mem_end, is_blob_type), false); break; case MYSQL_TYPE_ENUM: TSE_RETURN_IF_ERROR(tse_get_enum_default_value(thd, column, col_obj, field, fld, mem_start, mem_end, field_cs), false); @@ -849,10 +1006,10 @@ static bool tse_ddl_fill_column_default_value( case MYSQL_TYPE_DATETIME2: case MYSQL_TYPE_TIMESTAMP2: case MYSQL_TYPE_TIME2: - TSE_RETURN_IF_ERROR(tse_get_datetime_default_value(column, field, col_obj, mem_start, mem_end, option_set), false); + TSE_RETURN_IF_ERROR(tse_get_datetime_default_value(column, field, fld, col_obj, mem_start, mem_end, option_set, is_expr_value), false); break; default: - column->default_text = const_cast(col_obj->default_value_utf8().data()); + TSE_RETURN_IF_ERROR(tse_get_numeric_default_value(column, field, col_obj, fld, mem_start, mem_end, is_expr_value), false); break; } return true; @@ -1001,10 +1158,16 @@ static int tse_ddl_create_table_fill_foreign_key_info(TcDb__TseDDLCreateTableDef static void tse_fill_prefix_func_key_part(TcDb__TseDDLTableKeyPart *req_key_part, const Field *field, uint16 prefix_len) { req_key_part->is_func = true; - req_key_part->func_name = const_cast("substr"); - - snprintf(req_key_part->func_text, FUNC_TEXT_MAX_LEN - 1, "substr(%s,1,%d)", - field->field_name, prefix_len); + if (field->real_type() == MYSQL_TYPE_BLOB && field->charset() == &my_charset_bin && + field->is_flag_set(BINARY_FLAG)) { + req_key_part->func_name = const_cast("substrb"); + snprintf(req_key_part->func_text, FUNC_TEXT_MAX_LEN - 1, "substrb(%s,1,%d)", + field->field_name, prefix_len); + } else { + req_key_part->func_name = const_cast("substr"); + snprintf(req_key_part->func_text, FUNC_TEXT_MAX_LEN - 1, "substr(%s,1,%d)", + field->field_name, prefix_len); + } return; } @@ -1516,12 +1679,13 @@ static int fill_create_table_req_base_info(HA_CREATE_INFO *create_info, char *db } static int fill_create_table_req_columns_info(HA_CREATE_INFO *create_info, dd::Table *table_def, TABLE *form, - THD *thd, TcDb__TseDDLCreateTableDef *req, char **mem_start, char *mem_end) { + THD *thd, ddl_ctrl_t *ddl_ctrl, TcDb__TseDDLCreateTableDef *req, char **mem_start, char *mem_end) { uint32_t tse_col_idx = 0; uint32_t mysql_col_idx = 0; while (tse_col_idx < req->n_columns) { Field *field = form->field[mysql_col_idx]; if (field->is_gcol()) { + ddl_ctrl->table_flags |= TSE_TABLE_CONTAINS_VIRCOL; if (field->is_virtual_gcol()) { mysql_col_idx++; req->n_columns--; @@ -1577,7 +1741,7 @@ int fill_create_table_req(HA_CREATE_INFO *create_info, dd::Table *table_def, cha assert(form->s->row_type == create_info->row_type); - ret = fill_create_table_req_columns_info(create_info, table_def, form, thd, &req, &req_mem_start, req_mem_end); + ret = fill_create_table_req_columns_info(create_info, table_def, form, thd, ddl_ctrl, &req, &req_mem_start, req_mem_end); if (ret != 0) { return ret; } @@ -2098,7 +2262,7 @@ static int fill_tse_alter_drop_list(Alter_inplace_info *ha_alter_info, const dd: } static int fill_tse_alter_create_list(THD *thd, TABLE *altered_table, Alter_inplace_info *ha_alter_info, - dd::Table *new_table_def, TcDb__TseDDLAlterTableDef *req, char **mem_start, char *mem_end) + dd::Table *new_table_def, TcDb__TseDDLAlterTableDef *req, ddl_ctrl_t *ddl_ctrl, char **mem_start, char *mem_end) { uint32_t tse_col_idx = 0; uint32_t mysql_col_idx = 0; @@ -2108,6 +2272,7 @@ static int fill_tse_alter_create_list(THD *thd, TABLE *altered_table, Alter_inpl /* Generate Columns Not Processed */ if (fld->is_gcol()) { + ddl_ctrl->table_flags |= TSE_TABLE_CONTAINS_VIRCOL; if (fld->is_virtual_gcol()) { req->n_create_list--; mysql_col_idx++; @@ -2160,12 +2325,11 @@ static void fill_sys_cur_timestamp(THD *thd, TcDb__TseDDLAlterTableDef *req) { return; } -static void fill_alter_list_4alter_table(TABLE *altered_table, dd::Table *new_table_def, Alter_inplace_info *ha_alter_info, +static void fill_alter_list_4alter_table(dd::Table *new_table_def, Alter_inplace_info *ha_alter_info, TcDb__TseDDLAlterTableDef *req, size_t rename_cols, uint32_t thd_id, char **req_mem_start, char *req_mem_end) { TcDb__TseDDLAlterTableAlterColumn *req_alter = NULL; uint32_t copy_rm_num = 0; for (uint32_t i = 0; i < req->n_alter_list - rename_cols; i++) { - const dd::Column *new_col = new_table_def->get_column(altered_table->s->field[i]->field_name); req_alter = req->alter_list[i]; const Alter_column *alter_column = ha_alter_info->alter_info->alter_list.at((size_t)i); @@ -2187,16 +2351,11 @@ static void fill_alter_list_4alter_table(TABLE *altered_table, dd::Table *new_ta req->alter_list[copy_rm_index]->new_name = const_cast(alter_column->m_new_name); req->alter_list[copy_rm_index]->type = req_alter->type; copy_rm_num++; + continue; } - if (new_col->has_no_default()) { // drop default - req_alter->has_no_default = true; - } else { // set default - if (new_col->is_default_value_null()) { // default null - req_alter->is_default_null = true; - } else { - req_alter->default_text = const_cast(new_col->default_value_utf8().data()); - } - } + const dd::Column *new_col = new_table_def->get_column(alter_column->name); + req_alter->has_no_default = new_col->has_no_default() ? true : false; + req_alter->is_default_null = new_col->is_default_value_null() ? true : false; } } } @@ -2238,12 +2397,12 @@ int fill_alter_table_req(TABLE *altered_table, Alter_inplace_info *ha_alter_info } if (req.n_alter_list > 0) { - fill_alter_list_4alter_table(altered_table, new_table_def, ha_alter_info, &req, + fill_alter_list_4alter_table(new_table_def, ha_alter_info, &req, rename_cols, ddl_ctrl->tch.thd_id, &req_mem_start, req_mem_end); } TSE_RETURN_IF_ERROR((fill_tse_alter_create_list(thd, altered_table, ha_alter_info, - new_table_def, &req, &req_mem_start, req_mem_end) == CT_SUCCESS), CT_ERROR); + new_table_def, &req, ddl_ctrl, &req_mem_start, req_mem_end) == CT_SUCCESS), CT_ERROR); // 创建索引相关逻辑填充 TSE_RETURN_IF_ERROR(tse_ddl_fill_add_key(thd, altered_table, &req, ha_alter_info, req.user), true); diff --git a/storage/tianchi/ha_tsepart.cc b/storage/tianchi/ha_tsepart.cc index 1e39631..94ccef6 100644 --- a/storage/tianchi/ha_tsepart.cc +++ b/storage/tianchi/ha_tsepart.cc @@ -170,9 +170,11 @@ void ha_tsepart::get_auto_increment(ulonglong, ulonglong, ulonglong, uint64 inc_value; update_member_tch(m_tch, get_tse_hton(), ha_thd()); THD* thd = ha_thd(); - uint16_t auto_inc_step = thd->variables.auto_increment_increment; - uint16_t auto_inc_offset = thd->variables.auto_increment_offset; - int ret = tse_get_serial_value(&m_tch, &inc_value, auto_inc_step, auto_inc_offset); + dml_flag_t flag; + flag.auto_inc_offset = thd->variables.auto_increment_increment; + flag.auto_inc_step = thd->variables.auto_increment_offset; + flag.auto_increase = true; + int ret = tse_get_serial_value(&m_tch, &inc_value, flag); update_sess_ctx_by_tch(m_tch, get_tse_hton(), ha_thd()); if (ret != 0) { *first_value = (~(ulonglong)0); @@ -187,28 +189,6 @@ void ha_tsepart::print_error(int error, myf errflag) { } } -void ha_tsepart::part_autoinc_has_expl_non_null_value() { - THD *thd = ha_thd(); - autoinc_has_expl_non_null_value = table->autoinc_field_has_explicit_non_null_value; - if (!table->next_number_field) { - return; - } - // has not explicit auto increment value if insert 0 or insert null - if (table->next_number_field->val_int() == 0 && table->autoinc_field_has_explicit_non_null_value) { - autoinc_has_expl_non_null_value = false; - } - - /* has explicit auto increment value if - * 1. set insert id, then insert 0 or null - * 2. insert 0 but in NO_AUTO_VALUE_ON_ZERO sql mode - */ - if (thd->auto_inc_intervals_forced.nb_elements() || (table->autoinc_field_has_explicit_non_null_value && - thd->variables.sql_mode & MODE_NO_AUTO_VALUE_ON_ZERO)) { - autoinc_has_expl_non_null_value = true; - } - -} - void ha_tsepart::part_autoinc_has_expl_non_null_value_update_row(uchar *new_data) { if (table->found_next_number_field && new_data == table->record[0] && !table->s->next_number_keypart && @@ -229,6 +209,7 @@ void ha_tsepart::part_autoinc_has_expl_non_null_value_update_row(uchar *new_data int ha_tsepart::write_row_in_part(uint part_id, uchar *record) { bool saved_autoinc_has_expl_non_null = table->autoinc_field_has_explicit_non_null_value; Field *saved_next_number_field = table->next_number_field; + THD *thd = ha_thd(); if (!autoinc_has_expl_non_null_value_update_row && table->next_number_field && !autoinc_has_expl_non_null_value) { table->autoinc_field_has_explicit_non_null_value = false; @@ -237,6 +218,10 @@ int ha_tsepart::write_row_in_part(uint part_id, uchar *record) { if (table->found_next_number_field && autoinc_has_expl_non_null_value_update_row) { table->autoinc_field_has_explicit_non_null_value = true; table->next_number_field = table->found_next_number_field; + if (table->next_number_field->val_int() == 0) { + thd->force_one_auto_inc_interval(0); + } + autoinc_has_expl_non_null_value_update_row = false; } set_partition(part_id); @@ -1024,7 +1009,8 @@ int ha_tsepart::get_cbo_stats_4share() { THD *thd = ha_thd(); int ret = CT_SUCCESS; - if (m_part_share->need_fetch_cbo) { + time_t now = time(nullptr); + if (m_part_share->need_fetch_cbo || now - m_part_share->get_cbo_time > 60) { if (m_tch.ctx_addr == INVALID_VALUE64) { char user_name[SMALL_RECORD_SIZE]; tse_split_normalized_name(table->s->normalized_path.str, user_name, SMALL_RECORD_SIZE, nullptr, 0, nullptr); @@ -1042,6 +1028,7 @@ int ha_tsepart::get_cbo_stats_4share() if (ret == CT_SUCCESS && m_part_share->cbo_stats->is_updated) { m_part_share->need_fetch_cbo = false; } + m_part_share->get_cbo_time = now; } return ret; diff --git a/storage/tianchi/ha_tsepart.h b/storage/tianchi/ha_tsepart.h index 5bd43d0..0cb0759 100644 --- a/storage/tianchi/ha_tsepart.h +++ b/storage/tianchi/ha_tsepart.h @@ -30,7 +30,8 @@ class Tsepart_share : public Partition_share { //std::vector table_records; tianchi_cbo_stats_t *cbo_stats = nullptr; int used_count = 0; - bool need_fetch_cbo = true; + bool need_fetch_cbo = false; + time_t get_cbo_time = 0; }; @@ -243,13 +244,17 @@ class ha_tsepart : public ha_tse, int rnd_pos(uchar *record, uchar *pos) override; - void part_autoinc_has_expl_non_null_value(); - void part_autoinc_has_expl_non_null_value_update_row(uchar *new_data); - +#ifdef METADATA_NORMALIZED + int write_row(uchar *record, bool write_through MY_ATTRIBUTE((unused)) = false) override { +#endif +#ifndef METADATA_NORMALIZED int write_row(uchar *record) override { - part_autoinc_has_expl_non_null_value(); - return (Partition_helper::ph_write_row(record)); +#endif + if (table->next_number_field) { + autoinc_has_expl_non_null_value = true; + } + return Partition_helper::ph_write_row(record); } int update_row(const uchar *old_record, uchar *new_record) override { diff --git a/storage/tianchi/message_queue/dsw_message.h b/storage/tianchi/message_queue/dsw_message.h index a315a66..636ea1f 100644 --- a/storage/tianchi/message_queue/dsw_message.h +++ b/storage/tianchi/message_queue/dsw_message.h @@ -14,6 +14,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + #ifndef __dsw_message_pub_h__ #define __dsw_message_pub_h__ diff --git a/storage/tianchi/protobuf/tc_db.pb-c.h b/storage/tianchi/protobuf/tc_db.pb-c.h index 3e8d63a..b72cc52 100644 --- a/storage/tianchi/protobuf/tc_db.pb-c.h +++ b/storage/tianchi/protobuf/tc_db.pb-c.h @@ -55,7 +55,7 @@ struct TcDb__TseDDLColumnDataTypeDef * be replaced by typmode_t for unifying the definition of columns */ /* - * gs_type_t + * ct_type_t */ int32_t datatype; uint32_t size; diff --git a/storage/tianchi/protobuf/tc_db.proto b/storage/tianchi/protobuf/tc_db.proto index ba7e8aa..375d0c7 100644 --- a/storage/tianchi/protobuf/tc_db.proto +++ b/storage/tianchi/protobuf/tc_db.proto @@ -7,7 +7,7 @@ message TseDDLColumnDataTypeDef { * These definitions is same as the `typmode_t`; thus they should * be replaced by typmode_t for unifying the definition of columns */ - int32 datatype = 1; // gs_type_t + int32 datatype = 1; // ct_type_t uint32 size = 2; uint32 precision = 3; int32 scale = 4; diff --git a/storage/tianchi/tse_ddl_util.cc b/storage/tianchi/tse_ddl_util.cc index 5335f31..e2b5921 100644 --- a/storage/tianchi/tse_ddl_util.cc +++ b/storage/tianchi/tse_ddl_util.cc @@ -1,18 +1,14 @@ /* - Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License, version 2.0, - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License, version 2.0, for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Copyright (C) 2022. Huawei Technologies Co., Ltd. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under version 2 of the GNU General Public License (GPLv2) as + published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. */ #include "tse_ddl_util.h" diff --git a/storage/tianchi/tse_ddl_util.h b/storage/tianchi/tse_ddl_util.h index 8f03863..0565539 100644 --- a/storage/tianchi/tse_ddl_util.h +++ b/storage/tianchi/tse_ddl_util.h @@ -1,18 +1,14 @@ /* - Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License, version 2.0, - as published by the Free Software Foundation. + Copyright (C) 2022. Huawei Technologies Co., Ltd. All rights reserved. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License, version 2.0, for more details. + This program is free software; you can redistribute it and/or modify + it under version 2 of the GNU General Public License (GPLv2) as + published by the Free Software Foundation. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. */ #ifndef __TSE_DDL_UTIL_H__ diff --git a/storage/tianchi/tse_error.cc b/storage/tianchi/tse_error.cc index 3d383d3..55c4462 100644 --- a/storage/tianchi/tse_error.cc +++ b/storage/tianchi/tse_error.cc @@ -25,7 +25,7 @@ static std::unordered_map err_code_lookup_map = { {ERR_OAMAP_FETCH_FAILED, HA_ERR_GENERIC}, {ERR_GENERIC_INTERNAL_ERROR, HA_ERR_GENERIC}, {ERR_NOT_SUPPORT, HA_ERR_WRONG_COMMAND}, - {ERR_SNAPSHOT_TOO_OLD, HA_ERR_TOO_MANY_CONCURRENT_TRXS}, + {ERR_OPERATIONS_NOT_SUPPORT, HA_ERR_WRONG_COMMAND}, /* Since we rolled back the whole transaction, we must tell it also to MySQL so that MySQL knows to empty the cached binlog for this transaction */ @@ -111,6 +111,14 @@ bool convert_cantian_err_to_mysql(ct_errno_t error) { case ERR_EXCEED_MAX_CASCADE_DEPTH: my_printf_error(ER_FK_DEPTH_EXCEEDED, "Foreign key cascade delete/update exceeds max depth of 15", MYF(0)); break; + case ERR_SNAPSHOT_TOO_OLD: + my_printf_error(HA_ERR_TOO_MANY_CONCURRENT_TRXS, + "snapshot too old, it is advised to modify the parameters _undo_active_segments in Cantian", MYF(0)); + break; + case ERR_CHILD_ROW_CANNOT_ADD_OR_UPDATE: + my_printf_error(ER_NO_REFERENCED_ROW_2, + "Cannot add or update a child row: a foreign key constraint fails", MYF(0)); + break; default: return false; } @@ -144,8 +152,8 @@ int convert_tse_error_code_to_mysql_impl(ct_errno_t error, const char* funcName, if (iter != err_code_lookup_map.end()) { ret = iter->second; } else { - tse_log_system("func %s(line%d) returned with unknown err, gs ret %d", funcName, line, (int)error); + tse_log_system("func %s(line%d) returned with unknown err, cantian ret %d", funcName, line, (int)error); } - tse_log_note("func %s(line%d) returned with errCode %d, gs ret %d", funcName, line, ret, (int)error); + tse_log_note("func %s(line%d) returned with errCode %d, cantian ret %d", funcName, line, ret, (int)error); return ret; } diff --git a/storage/tianchi/tse_error.h b/storage/tianchi/tse_error.h index ced1046..0067146 100644 --- a/storage/tianchi/tse_error.h +++ b/storage/tianchi/tse_error.h @@ -22,6 +22,7 @@ typedef enum en_errno { CT_SUCCESS = 0, ERR_ALLOC_MEMORY = 1, ERR_CAPABILITY_NOT_SUPPORT = 101, + ERR_OPERATIONS_NOT_SUPPORT = 130, ERR_GENERIC_INTERNAL_ERROR = 299, ERR_TOO_MANY_CONNECTIONS = 403, ERR_NOT_SUPPORT = 404, @@ -103,8 +104,9 @@ typedef enum en_errno { ERR_DUPLICATE_ENTRY = 970, ERR_ROW_IS_REFERENCED = 1123, - ERR_EXCEED_MAX_CASCADE_DEPTH = 1124, - ERR_CONSTRAINT_VIOLATED_NO_FOUND = 1223, + ERR_CONSTRAINT_VIOLATED_NO_FOUND = 1128, + ERR_EXCEED_MAX_CASCADE_DEPTH = 1133, + ERR_CHILD_ROW_CANNOT_ADD_OR_UPDATE = 1134, /* additional: sql engine */ ERR_DUPLICATE_AUTO_COLUMN = 1300, diff --git a/storage/tianchi/tse_srv.h b/storage/tianchi/tse_srv.h index 84c5f61..6b7bd0a 100644 --- a/storage/tianchi/tse_srv.h +++ b/storage/tianchi/tse_srv.h @@ -262,6 +262,7 @@ enum TSE_FUNC_TYPE { TSE_FUNC_TYPE_CLOSE_TABLE, TSE_FUNC_TYPE_CLOSE_SESSION, TSE_FUNC_TYPE_WRITE_ROW, + TSE_FUNC_TYPE_WRITE_THROUGH_ROW, TSE_FUNC_TYPE_UPDATE_ROW, TSE_FUNC_TYPE_DELETE_ROW, TSE_FUNC_TYPE_RND_INIT, @@ -474,10 +475,13 @@ typedef struct { uint64_t no_logging : 1; uint64_t auto_inc_used : 1; uint64_t has_explicit_autoinc : 1; + uint64_t auto_increase : 1; uint64_t autoinc_lock_mode : 2; uint64_t auto_inc_step : 16; uint64_t auto_inc_offset : 16; - uint64_t unused_ops : 21; + uint64_t write_through : 1; + uint64_t is_create_select : 1; + uint64_t unused_ops : 18; } dml_flag_t; typedef struct { @@ -502,6 +506,9 @@ void tse_free_buf(tianchi_handler_t *tch, uint8_t *buf); /* Data Manipulation Language(DML) Related Interface */ int tse_write_row(tianchi_handler_t *tch, const record_info_t *record_info, uint16_t serial_column_offset, uint64_t *last_insert_id, dml_flag_t flag); +/* corresponds to cantian. */ +int tse_write_through_row(tianchi_handler_t *tch, const record_info_t *record_info, + uint16_t serial_column_offset, uint64_t *last_insert_id, dml_flag_t flag); int tse_bulk_write(tianchi_handler_t *tch, const record_info_t *record_info, uint64_t rec_num, uint32_t *err_pos, dml_flag_t flag, ctc_part_t *part_ids); int tse_update_row(tianchi_handler_t *tch, uint16_t new_record_len, const uint8_t *new_record, @@ -572,7 +579,7 @@ int tse_rename_table(void *alter_def, ddl_ctrl_t *ddl_ctrl); int tse_drop_table(void *drop_def, ddl_ctrl_t *ddl_ctrl); int tse_get_max_sessions_per_node(uint32_t *max_sessions); -int tse_get_serial_value(tianchi_handler_t *tch, uint64_t *value, uint16_t auto_inc_step, uint16_t auto_inc_offset); +int tse_get_serial_value(tianchi_handler_t *tch, uint64_t *value, dml_flag_t flag); int close_mysql_connection(uint32_t thd_id, uint32_t mysql_inst_id); int tse_ddl_execute_lock_tables(tianchi_handler_t *tch, char *db_name, tse_lock_table_info *lock_info, int *err_code); diff --git a/storage/tianchi/tse_srv_mq_stub.cc b/storage/tianchi/tse_srv_mq_stub.cc index b6368f3..31c723c 100644 --- a/storage/tianchi/tse_srv_mq_stub.cc +++ b/storage/tianchi/tse_srv_mq_stub.cc @@ -141,7 +141,12 @@ int tse_write_row(tianchi_handler_t *tch, const record_info_t *record_info, req->serial_column_offset = serial_column_offset; req->flag = flag; int result = ERR_CONNECTION_FAILED; - int ret = tse_mq_deal_func(shm_inst, TSE_FUNC_TYPE_WRITE_ROW, req, tch->msg_buf); + int ret = CT_SUCCESS; + if (req->flag.write_through) { + ret = tse_mq_deal_func(shm_inst, TSE_FUNC_TYPE_WRITE_THROUGH_ROW, req, tch->msg_buf); + } else { + ret = tse_mq_deal_func(shm_inst, TSE_FUNC_TYPE_WRITE_ROW, req, tch->msg_buf); + } tch->sql_stat_start = req->tch.sql_stat_start; *tch = req->tch; if (ret == CT_SUCCESS) { @@ -1236,7 +1241,7 @@ int tse_broadcast_rewrite_sql(tianchi_handler_t *tch, tse_ddl_broadcast_request return result; } -int tse_get_serial_value(tianchi_handler_t *tch, uint64_t *value, uint16_t auto_inc_step, uint16_t auto_inc_offset) { +int tse_get_serial_value(tianchi_handler_t *tch, uint64_t *value, dml_flag_t flag) { void *shm_inst = get_one_shm_inst(tch); get_serial_val_request *req = (get_serial_val_request*)alloc_share_mem(shm_inst, sizeof(get_serial_val_request)); DBUG_EXECUTE_IF("get_serial_val_ddl_shm_oom", { req = NULL; }); @@ -1245,8 +1250,9 @@ int tse_get_serial_value(tianchi_handler_t *tch, uint64_t *value, uint16_t auto_ return ERR_ALLOC_MEMORY; } req->tch = *tch; - req->flag.auto_inc_step = auto_inc_step; - req->flag.auto_inc_offset = auto_inc_offset; + req->flag.auto_inc_step = flag.auto_inc_step; + req->flag.auto_inc_offset = flag.auto_inc_offset; + req->flag.auto_increase = flag.auto_increase; int result = ERR_CONNECTION_FAILED; int ret = tse_mq_deal_func(shm_inst, TSE_FUNC_TYPE_GET_SERIAL_VALUE, req, tch->msg_buf); *tch = req->tch; diff --git a/storage/tianchi/tse_stats.cc b/storage/tianchi/tse_stats.cc index faf5113..6ba8508 100644 --- a/storage/tianchi/tse_stats.cc +++ b/storage/tianchi/tse_stats.cc @@ -23,6 +23,7 @@ const char *ctc_interface_strs[] = { "TSE_FUNC_TYPE_CLOSE_TABLE", "TSE_FUNC_TYPE_CLOSE_SESSION", "TSE_FUNC_TYPE_WRITE_ROW", + "TSE_FUNC_TYPE_WRITE_THROUGH_ROW", "TSE_FUNC_TYPE_UPDATE_ROW", "TSE_FUNC_TYPE_DELETE_ROW", "TSE_FUNC_TYPE_RND_INIT", -- Gitee