From e8bb94ccc80d02a9792257b971b748b389a014a1 Mon Sep 17 00:00:00 2001 From: Eugene Kosov Date: Fri, 30 Nov 2018 01:15:30 +0300 Subject: [PATCH] MDEV-16499 [10.1] ER_NO_SUCH_TABLE_IN_ENGINE followed by "Please drop the table and recreate" upon adding FULLTEXT key to table with virtual column There was an incorrect check for MariaDB and InnoDB tables fields count. Corruption was reported when there was no corruption. Also, a warning message had incorrect field numbers for both MariaDB and InnoDB tables. ha_innobase::open(): fixed check and message --- .../suite/innodb/r/innodb-virtual-columns.result | 15 +++++++++++++++ .../suite/innodb/t/innodb-virtual-columns.test | 11 +++++++++++ storage/innobase/handler/ha_innodb.cc | 16 +++++++++------- storage/xtradb/handler/ha_innodb.cc | 16 +++++++++------- 4 files changed, 44 insertions(+), 14 deletions(-) diff --git a/mysql-test/suite/innodb/r/innodb-virtual-columns.result b/mysql-test/suite/innodb/r/innodb-virtual-columns.result index 558bb23de0a..900fca8309e 100644 --- a/mysql-test/suite/innodb/r/innodb-virtual-columns.result +++ b/mysql-test/suite/innodb/r/innodb-virtual-columns.result @@ -320,3 +320,18 @@ term uw_id plan wdraw_rsn admit_term 1035 2 CSM ACAD 1009 drop table grad_degree; drop table gso_grad_supr; +CREATE TABLE t1 (a INT, b CHAR(12), c INT AS (a) VIRTUAL, FULLTEXT KEY(b)) ENGINE=InnoDB; +INSERT INTO t1 (a,b) VALUES (1,'foo'); +SELECT * FROM t1; +a b c +1 foo 1 +DROP TABLE t1; +CREATE TABLE t1 (a INT, b CHAR(12), c INT AS (a) VIRTUAL) ENGINE=InnoDB; +INSERT INTO t1 (a,b) VALUES (1,'foo'); +ALTER TABLE t1 ADD FULLTEXT KEY(b); +Warnings: +Warning 124 InnoDB rebuilding table to add column FTS_DOC_ID +SELECT * FROM t1; +a b c +1 foo 1 +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/innodb-virtual-columns.test b/mysql-test/suite/innodb/t/innodb-virtual-columns.test index 368c6fc8cb1..99f550eb667 100644 --- a/mysql-test/suite/innodb/t/innodb-virtual-columns.test +++ b/mysql-test/suite/innodb/t/innodb-virtual-columns.test @@ -300,3 +300,14 @@ select * from gso_grad_supr; drop table grad_degree; drop table gso_grad_supr; + +CREATE TABLE t1 (a INT, b CHAR(12), c INT AS (a) VIRTUAL, FULLTEXT KEY(b)) ENGINE=InnoDB; +INSERT INTO t1 (a,b) VALUES (1,'foo'); +SELECT * FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a INT, b CHAR(12), c INT AS (a) VIRTUAL) ENGINE=InnoDB; +INSERT INTO t1 (a,b) VALUES (1,'foo'); +ALTER TABLE t1 ADD FULLTEXT KEY(b); +SELECT * FROM t1; +DROP TABLE t1; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 85c5529a096..33ece9c47af 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -5312,19 +5312,21 @@ ha_innobase::open( ib_table = dict_table_open_on_name(norm_name, FALSE, TRUE, ignore_err); if (ib_table - && ((!DICT_TF2_FLAG_IS_SET(ib_table, DICT_TF2_FTS_HAS_DOC_ID) - && table->s->stored_fields != dict_table_get_n_user_cols(ib_table)) - || (DICT_TF2_FLAG_IS_SET(ib_table, DICT_TF2_FTS_HAS_DOC_ID) - && (table->s->fields - != dict_table_get_n_user_cols(ib_table) - 1)))) { + && (table->s->stored_fields != dict_table_get_n_user_cols(ib_table) + - (DICT_TF2_FLAG_IS_SET(ib_table, DICT_TF2_FTS_HAS_DOC_ID) + ? 1 : 0))) { ib_logf(IB_LOG_LEVEL_WARN, "table %s contains %lu user defined columns " "in InnoDB, but %lu columns in MySQL. Please " "check INFORMATION_SCHEMA.INNODB_SYS_COLUMNS and " REFMAN "innodb-troubleshooting.html " "for how to resolve it", - norm_name, (ulong) dict_table_get_n_user_cols(ib_table), - (ulong) table->s->fields); + norm_name, + (ulong) (dict_table_get_n_user_cols(ib_table) + - DICT_TF2_FLAG_IS_SET(ib_table, + DICT_TF2_FTS_HAS_DOC_ID) + ? 1 : 0), + (ulong) table->s->stored_fields); /* Mark this table as corrupted, so the drop table or force recovery can still use it, but not others. */ diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 52ef0b01534..320f7b3d088 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -5984,19 +5984,21 @@ ha_innobase::open( ib_table = dict_table_open_on_name(norm_name, FALSE, TRUE, ignore_err); if (ib_table - && ((!DICT_TF2_FLAG_IS_SET(ib_table, DICT_TF2_FTS_HAS_DOC_ID) - && table->s->stored_fields != dict_table_get_n_user_cols(ib_table)) - || (DICT_TF2_FLAG_IS_SET(ib_table, DICT_TF2_FTS_HAS_DOC_ID) - && (table->s->fields - != dict_table_get_n_user_cols(ib_table) - 1)))) { + && (table->s->stored_fields != dict_table_get_n_user_cols(ib_table) + - (DICT_TF2_FLAG_IS_SET(ib_table, DICT_TF2_FTS_HAS_DOC_ID) + ? 1 : 0))) { ib_logf(IB_LOG_LEVEL_WARN, "table %s contains %lu user defined columns " "in InnoDB, but %lu columns in MySQL. Please " "check INFORMATION_SCHEMA.INNODB_SYS_COLUMNS and " REFMAN "innodb-troubleshooting.html " "for how to resolve it", - norm_name, (ulong) dict_table_get_n_user_cols(ib_table), - (ulong) table->s->fields); + norm_name, + (ulong) (dict_table_get_n_user_cols(ib_table) + - DICT_TF2_FLAG_IS_SET(ib_table, + DICT_TF2_FTS_HAS_DOC_ID) + ? 1 : 0), + (ulong) table->s->stored_fields); /* Mark this table as corrupted, so the drop table or force recovery can still use it, but not others. */