From 228b7e4db59441656abfb194da0e239fd091cfd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 8 Nov 2023 12:17:14 +0200 Subject: [PATCH] MDEV-13626 Merge InnoDB test cases from MySQL 5.7 This imports and adapts a number of MySQL 5.7 test cases that are applicable to MariaDB. Some tests for old bug fixes are not that relevant because the code has been refactored since then (especially starting with MariaDB Server 10.6), and the tests would not reproduce the original bug if the fix was reverted. In the test innodb_fts.opt, there are many duplicate MATCH ranks, which would make the results nondeterministic. The test was stabilized by changing some LIMIT clauses or by adding sorted_result in those cases where the purpose of a test was to show that no sorting took place in the server. In the test innodb_fts.phrase, MySQL 5.7 would generate FTS_DOC_ID that are 1 larger than in MariaDB. In innodb_fts.index_table the difference is 2. This is because in MariaDB, fts_get_next_doc_id() post-increments cache->next_doc_id, while MySQL 5.7 pre-increments it. Reviewed by: Thirunarayanan Balathandayuthapani --- .../gcol/r/innodb_prefix_index_check.result | 29 + .../gcol/t/innodb_prefix_index_check.test | 43 + .../suite/innodb/r/add_foreign_key.result | 31 + .../suite/innodb/r/cascade_lock_wait.result | 76 + .../suite/innodb/r/import_update_stats.result | 72 + mysql-test/suite/innodb/r/index_length.result | 23 + mysql-test/suite/innodb/r/innodb-32k.result | 20 + mysql-test/suite/innodb/r/innodb-64k.result | 20 + .../r/innodb-ac-non-locking-select.result | 62 + mysql-test/suite/innodb/r/innodb-alter.result | 56 + .../innodb/r/innodb-index-online-fk.result | 36 + .../innodb-lock-inherit-read_commited.result | 124 ++ .../suite/innodb/r/innodb-read-view.result | 41 +- .../innodb/r/innodb_i_s_innodb_locks.result | Bin 0 -> 5451 bytes .../innodb/r/innodb_i_s_innodb_trx.result | 90 + .../r/innodb_information_schema_tables.result | 1 + .../innodb/r/innodb_stats_auto_recalc.result | 44 + .../r/innodb_stats_auto_recalc_ddl.result | 34 + .../r/innodb_stats_auto_recalc_lots.result | 202 ++ ...db_stats_auto_recalc_on_nonexistent.result | 57 + .../r/innodb_stats_external_pages.result | 10 + .../r/innodb_stats_flag_global,off.rdiff | 34 + .../innodb/r/innodb_stats_flag_global.result | 207 ++ .../innodb/r/innodb_stats_persistent.result | 26 +- .../innodb/r/innodb_stats_sample_pages.result | 29 + ...innodb_stats_table_flag_auto_recalc.result | 82 + ...nnodb_stats_table_flag_sample_pages.result | 95 + .../innodb/r/innodb_ut_format_name.result | 5 + .../suite/innodb/r/records_in_range,4k.rdiff | 8 + .../suite/innodb/r/records_in_range,8k.rdiff | 8 + .../suite/innodb/r/records_in_range.result | 1275 +++++++++++ .../r/tablespace_per_table_not_windows.result | 134 ++ .../r/tablespace_per_table_windows.result | 51 + .../suite/innodb/t/add_foreign_key.test | 38 + .../suite/innodb/t/cascade_lock_wait.test | 45 + .../suite/innodb/t/import_update_stats.test | 81 + mysql-test/suite/innodb/t/index_length.test | 23 + mysql-test/suite/innodb/t/innodb-32k.test | 13 + mysql-test/suite/innodb/t/innodb-64k.test | 13 + .../t/innodb-ac-non-locking-select.test | 117 + mysql-test/suite/innodb/t/innodb-alter.test | 26 + .../innodb/t/innodb-index-online-fk.test | 29 + .../t/innodb-lock-inherit-read_commited.test | 115 + .../suite/innodb/t/innodb-read-view.test | 48 +- .../innodb/t/innodb_i_s_innodb_locks.test | 169 ++ .../suite/innodb/t/innodb_i_s_innodb_trx.test | 95 + .../t/innodb_information_schema_tables.opt | 1 + .../t/innodb_information_schema_tables.test | 4 + .../innodb/t/innodb_stats_auto_recalc.opt | 1 + .../innodb/t/innodb_stats_auto_recalc.test | 48 + .../innodb/t/innodb_stats_auto_recalc_ddl.opt | 1 + .../t/innodb_stats_auto_recalc_ddl.test | 49 + .../t/innodb_stats_auto_recalc_lots.opt | 1 + .../t/innodb_stats_auto_recalc_lots.test | 45 + ...nnodb_stats_auto_recalc_on_nonexistent.opt | 1 + ...nodb_stats_auto_recalc_on_nonexistent.test | 85 + .../innodb/t/innodb_stats_external_pages.test | 79 + .../t/innodb_stats_flag_global.combinations | 4 + .../innodb/t/innodb_stats_flag_global.test | 91 + .../t/innodb_stats_flag_global_analyze.inc | 13 + .../innodb/t/innodb_stats_persistent.test | 39 + .../innodb/t/innodb_stats_sample_pages.opt | 1 + .../innodb/t/innodb_stats_sample_pages.test | 53 + .../innodb_stats_table_flag_auto_recalc.test | 83 + .../innodb_stats_table_flag_sample_pages.test | 103 + .../suite/innodb/t/innodb_ut_format_name.test | 17 + .../suite/innodb/t/records_in_range.test | 432 ++++ .../t/tablespace_per_table_not_windows.opt | 2 + .../t/tablespace_per_table_not_windows.test | 164 ++ .../innodb/t/tablespace_per_table_windows.opt | 2 + .../t/tablespace_per_table_windows.test | 79 + .../innodb_fts/r/foreign_key_check.result | 27 + .../innodb_fts/r/foreign_key_update.result | 34 + .../suite/innodb_fts/r/index_table.result | 265 +++ .../innodb_fts/r/innodb_fts_proximity.result | 5 +- .../suite/innodb_fts/r/limit_union.result | 157 ++ mysql-test/suite/innodb_fts/r/misc.result | 1878 +++++++++++++++++ mysql-test/suite/innodb_fts/r/misc_1.result | 922 ++++++++ mysql-test/suite/innodb_fts/r/opt.result | 1650 +++++++++++++++ mysql-test/suite/innodb_fts/r/phrase.result | 84 + .../innodb_fts/r/result_cache_limit.result | 31 + .../suite/innodb_fts/r/savepoint.result | 318 +++ mysql-test/suite/innodb_fts/r/subexpr.result | 105 + .../suite/innodb_fts/t/foreign_key_check.test | 41 + .../innodb_fts/t/foreign_key_update.test | 34 + mysql-test/suite/innodb_fts/t/index_table.opt | 2 + .../suite/innodb_fts/t/index_table.test | 121 ++ .../innodb_fts/t/innodb_fts_proximity.test | 2 + .../suite/innodb_fts/t/limit_union.test | 143 ++ mysql-test/suite/innodb_fts/t/misc.test | 1511 +++++++++++++ mysql-test/suite/innodb_fts/t/misc_1.test | 894 ++++++++ mysql-test/suite/innodb_fts/t/opt.opt | 1 + mysql-test/suite/innodb_fts/t/opt.test | 1086 ++++++++++ mysql-test/suite/innodb_fts/t/phrase.opt | 2 + mysql-test/suite/innodb_fts/t/phrase.test | 39 + .../innodb_fts/t/result_cache_limit.test | 52 + mysql-test/suite/innodb_fts/t/savepoint.test | 475 +++++ mysql-test/suite/innodb_fts/t/subexpr.test | 58 + .../innodb_gis/r/rtree_create_inplace.result | 36 +- .../innodb_gis/t/rtree_create_inplace.opt | 1 + .../innodb_gis/t/rtree_create_inplace.test | 36 +- 101 files changed, 15119 insertions(+), 126 deletions(-) create mode 100644 mysql-test/suite/innodb/r/add_foreign_key.result create mode 100644 mysql-test/suite/innodb/r/cascade_lock_wait.result create mode 100644 mysql-test/suite/innodb/r/import_update_stats.result create mode 100644 mysql-test/suite/innodb/r/index_length.result create mode 100644 mysql-test/suite/innodb/r/innodb-ac-non-locking-select.result create mode 100644 mysql-test/suite/innodb/r/innodb-lock-inherit-read_commited.result create mode 100644 mysql-test/suite/innodb/r/innodb_i_s_innodb_locks.result create mode 100644 mysql-test/suite/innodb/r/innodb_i_s_innodb_trx.result create mode 100644 mysql-test/suite/innodb/r/innodb_stats_auto_recalc.result create mode 100644 mysql-test/suite/innodb/r/innodb_stats_auto_recalc_ddl.result create mode 100644 mysql-test/suite/innodb/r/innodb_stats_auto_recalc_lots.result create mode 100644 mysql-test/suite/innodb/r/innodb_stats_auto_recalc_on_nonexistent.result create mode 100644 mysql-test/suite/innodb/r/innodb_stats_external_pages.result create mode 100644 mysql-test/suite/innodb/r/innodb_stats_flag_global,off.rdiff create mode 100644 mysql-test/suite/innodb/r/innodb_stats_flag_global.result create mode 100644 mysql-test/suite/innodb/r/innodb_stats_sample_pages.result create mode 100644 mysql-test/suite/innodb/r/innodb_stats_table_flag_auto_recalc.result create mode 100644 mysql-test/suite/innodb/r/innodb_stats_table_flag_sample_pages.result create mode 100644 mysql-test/suite/innodb/r/innodb_ut_format_name.result create mode 100644 mysql-test/suite/innodb/r/records_in_range,4k.rdiff create mode 100644 mysql-test/suite/innodb/r/records_in_range,8k.rdiff create mode 100644 mysql-test/suite/innodb/r/records_in_range.result create mode 100644 mysql-test/suite/innodb/r/tablespace_per_table_not_windows.result create mode 100644 mysql-test/suite/innodb/r/tablespace_per_table_windows.result create mode 100644 mysql-test/suite/innodb/t/add_foreign_key.test create mode 100644 mysql-test/suite/innodb/t/cascade_lock_wait.test create mode 100644 mysql-test/suite/innodb/t/import_update_stats.test create mode 100644 mysql-test/suite/innodb/t/index_length.test create mode 100644 mysql-test/suite/innodb/t/innodb-ac-non-locking-select.test create mode 100644 mysql-test/suite/innodb/t/innodb-lock-inherit-read_commited.test create mode 100644 mysql-test/suite/innodb/t/innodb_i_s_innodb_locks.test create mode 100644 mysql-test/suite/innodb/t/innodb_i_s_innodb_trx.test create mode 100644 mysql-test/suite/innodb/t/innodb_stats_auto_recalc.opt create mode 100644 mysql-test/suite/innodb/t/innodb_stats_auto_recalc.test create mode 100644 mysql-test/suite/innodb/t/innodb_stats_auto_recalc_ddl.opt create mode 100644 mysql-test/suite/innodb/t/innodb_stats_auto_recalc_ddl.test create mode 100644 mysql-test/suite/innodb/t/innodb_stats_auto_recalc_lots.opt create mode 100644 mysql-test/suite/innodb/t/innodb_stats_auto_recalc_lots.test create mode 100644 mysql-test/suite/innodb/t/innodb_stats_auto_recalc_on_nonexistent.opt create mode 100644 mysql-test/suite/innodb/t/innodb_stats_auto_recalc_on_nonexistent.test create mode 100644 mysql-test/suite/innodb/t/innodb_stats_external_pages.test create mode 100644 mysql-test/suite/innodb/t/innodb_stats_flag_global.combinations create mode 100644 mysql-test/suite/innodb/t/innodb_stats_flag_global.test create mode 100644 mysql-test/suite/innodb/t/innodb_stats_flag_global_analyze.inc create mode 100644 mysql-test/suite/innodb/t/innodb_stats_sample_pages.opt create mode 100644 mysql-test/suite/innodb/t/innodb_stats_sample_pages.test create mode 100644 mysql-test/suite/innodb/t/innodb_stats_table_flag_auto_recalc.test create mode 100644 mysql-test/suite/innodb/t/innodb_stats_table_flag_sample_pages.test create mode 100644 mysql-test/suite/innodb/t/innodb_ut_format_name.test create mode 100644 mysql-test/suite/innodb/t/records_in_range.test create mode 100644 mysql-test/suite/innodb/t/tablespace_per_table_not_windows.opt create mode 100644 mysql-test/suite/innodb/t/tablespace_per_table_not_windows.test create mode 100644 mysql-test/suite/innodb/t/tablespace_per_table_windows.opt create mode 100644 mysql-test/suite/innodb/t/tablespace_per_table_windows.test create mode 100644 mysql-test/suite/innodb_fts/r/foreign_key_check.result create mode 100644 mysql-test/suite/innodb_fts/r/foreign_key_update.result create mode 100644 mysql-test/suite/innodb_fts/r/index_table.result create mode 100644 mysql-test/suite/innodb_fts/r/limit_union.result create mode 100644 mysql-test/suite/innodb_fts/r/misc.result create mode 100644 mysql-test/suite/innodb_fts/r/misc_1.result create mode 100644 mysql-test/suite/innodb_fts/r/opt.result create mode 100644 mysql-test/suite/innodb_fts/r/phrase.result create mode 100644 mysql-test/suite/innodb_fts/r/result_cache_limit.result create mode 100644 mysql-test/suite/innodb_fts/r/savepoint.result create mode 100644 mysql-test/suite/innodb_fts/r/subexpr.result create mode 100644 mysql-test/suite/innodb_fts/t/foreign_key_check.test create mode 100644 mysql-test/suite/innodb_fts/t/foreign_key_update.test create mode 100644 mysql-test/suite/innodb_fts/t/index_table.opt create mode 100644 mysql-test/suite/innodb_fts/t/index_table.test create mode 100644 mysql-test/suite/innodb_fts/t/limit_union.test create mode 100644 mysql-test/suite/innodb_fts/t/misc.test create mode 100644 mysql-test/suite/innodb_fts/t/misc_1.test create mode 100644 mysql-test/suite/innodb_fts/t/opt.opt create mode 100644 mysql-test/suite/innodb_fts/t/opt.test create mode 100644 mysql-test/suite/innodb_fts/t/phrase.opt create mode 100644 mysql-test/suite/innodb_fts/t/phrase.test create mode 100644 mysql-test/suite/innodb_fts/t/result_cache_limit.test create mode 100644 mysql-test/suite/innodb_fts/t/savepoint.test create mode 100644 mysql-test/suite/innodb_fts/t/subexpr.test create mode 100644 mysql-test/suite/innodb_gis/t/rtree_create_inplace.opt diff --git a/mysql-test/suite/gcol/r/innodb_prefix_index_check.result b/mysql-test/suite/gcol/r/innodb_prefix_index_check.result index 01dbe4a6592..ea84cd154ad 100644 --- a/mysql-test/suite/gcol/r/innodb_prefix_index_check.result +++ b/mysql-test/suite/gcol/r/innodb_prefix_index_check.result @@ -13,3 +13,32 @@ key(f1,f2(1)) )ENGINE=INNODB; REPLACE INTO t1(f3) VALUES (1),(1); DROP TABLE t1; +#Create and alter table examples for full column index followed by prefix index. +CREATE TABLE t1( +f1 VARCHAR(100), +f2 char(2), +KEY(f1,f2), +KEY(f1(5)))ENGINE=INNODB; +REPLACE INTO t1(f2) VALUES (1),(1); +ALTER TABLE t1 ADD INDEX(f2,f1); +DROP TABLE t1; +#Create and alter table examples for small prefix index followed by large +#prefix index. +CREATE TABLE t1( +f1 VARCHAR(100), +f2 char(2), +KEY(f1(5),f2), +KEY(f1(10)))ENGINE=INNODB; +REPLACE INTO t1(f2) VALUES (1),(1); +ALTER TABLE t1 ADD INDEX(f2,f1); +DROP TABLE t1; +#Create and alter table examples for prefix index followed by full column +#index. +CREATE TABLE t1( +f1 VARCHAR(100), +f2 char(2), +KEY(f1(5),f2), +KEY(f1))ENGINE=INNODB; +REPLACE INTO t1(f2) VALUES (1),(1); +ALTER TABLE t1 ADD INDEX(f2,f1); +DROP TABLE t1; diff --git a/mysql-test/suite/gcol/t/innodb_prefix_index_check.test b/mysql-test/suite/gcol/t/innodb_prefix_index_check.test index 4923ead91ac..5cc46e16dde 100644 --- a/mysql-test/suite/gcol/t/innodb_prefix_index_check.test +++ b/mysql-test/suite/gcol/t/innodb_prefix_index_check.test @@ -20,3 +20,46 @@ REPLACE INTO t1(f3) VALUES (1),(1); DROP TABLE t1; +--echo #Create and alter table examples for full column index followed by prefix index. + +CREATE TABLE t1( +f1 VARCHAR(100), +f2 char(2), +KEY(f1,f2), +KEY(f1(5)))ENGINE=INNODB; + +REPLACE INTO t1(f2) VALUES (1),(1); + +ALTER TABLE t1 ADD INDEX(f2,f1); + +DROP TABLE t1; + +--echo #Create and alter table examples for small prefix index followed by large +--echo #prefix index. + +CREATE TABLE t1( +f1 VARCHAR(100), +f2 char(2), +KEY(f1(5),f2), +KEY(f1(10)))ENGINE=INNODB; + +REPLACE INTO t1(f2) VALUES (1),(1); + +ALTER TABLE t1 ADD INDEX(f2,f1); + +DROP TABLE t1; + +--echo #Create and alter table examples for prefix index followed by full column +--echo #index. + +CREATE TABLE t1( +f1 VARCHAR(100), +f2 char(2), +KEY(f1(5),f2), +KEY(f1))ENGINE=INNODB; + +REPLACE INTO t1(f2) VALUES (1),(1); + +ALTER TABLE t1 ADD INDEX(f2,f1); + +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/add_foreign_key.result b/mysql-test/suite/innodb/r/add_foreign_key.result new file mode 100644 index 00000000000..75177478e60 --- /dev/null +++ b/mysql-test/suite/innodb/r/add_foreign_key.result @@ -0,0 +1,31 @@ +# +# Bug #19471516 SERVER CRASHES WHEN EXECUTING ALTER TABLE ADD +# FOREIGN KEY +# +CREATE TABLE `parent` (`parent_id` INT, PRIMARY KEY (`parent_id`)); +CREATE TABLE `child1` (`id` INT ,`child1_fk1` INT, `child1_fk2` INT, +PRIMARY KEY (`id`)); +CREATE TABLE `child2` (`id` INT, `child2_fk1` INT, `child2_fk2` INT, +PRIMARY KEY (`id`)); +CREATE TABLE `child3` (`id` INT , `child3_fk1` INT, PRIMARY KEY (`id`)); +ALTER TABLE `child1` ADD FOREIGN KEY (`child1_fk1`) REFERENCES `parent` +(`parent_id`); +ALTER TABLE `child1` ADD FOREIGN KEY (`child1_fk1`) REFERENCES +`parent` (`parent_id`); +ALTER TABLE `child1` ADD FOREIGN KEY (`child1_fk2`) REFERENCES `parent` +(`parent_id`); +ALTER TABLE `child2` ADD FOREIGN KEY (`child2_fk1`) REFERENCES `parent` +(`parent_id`); +ALTER TABLE `child2` ADD FOREIGN KEY (`child2_fk2`) REFERENCES `parent` +(`parent_id`); +ALTER TABLE `child3` ADD FOREIGN KEY (`child3_fk1`) REFERENCES `parent` +(`parent_id`); +ALTER TABLE `child1` ADD FOREIGN KEY (`child1_fk2`) REFERENCES +`parent` (`parent_id`); +ALTER TABLE `child2` ADD FOREIGN KEY (`child2_fk1`) REFERENCES +`parent` (`parent_id`); +ALTER TABLE `child2` ADD FOREIGN KEY (`child2_fk2`) REFERENCES +`parent` (`parent_id`); +ALTER TABLE `child3` ADD FOREIGN KEY (`child3_fk1`) REFERENCES +`parent` (`parent_id`); +drop table child3, child2, child1, parent; diff --git a/mysql-test/suite/innodb/r/cascade_lock_wait.result b/mysql-test/suite/innodb/r/cascade_lock_wait.result new file mode 100644 index 00000000000..9cc05df739e --- /dev/null +++ b/mysql-test/suite/innodb/r/cascade_lock_wait.result @@ -0,0 +1,76 @@ +create table t1 (f1 int primary key) engine=innodb; +create table t2 (f1 int primary key, +constraint c1 foreign key (f1) references t1(f1) +on update cascade +on delete cascade) engine=innodb; +create table t3 (f1 int primary key, +constraint c2 foreign key (f1) references t1(f1) +on update cascade +on delete cascade) engine=innodb; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) NOT NULL, + PRIMARY KEY (`f1`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `f1` int(11) NOT NULL, + PRIMARY KEY (`f1`), + CONSTRAINT `c1` FOREIGN KEY (`f1`) REFERENCES `t1` (`f1`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +show create table t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `f1` int(11) NOT NULL, + PRIMARY KEY (`f1`), + CONSTRAINT `c2` FOREIGN KEY (`f1`) REFERENCES `t1` (`f1`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +insert into t1 values (1); +insert into t1 values (2); +insert into t1 values (3); +insert into t2 values (1); +insert into t2 values (2); +insert into t2 values (3); +insert into t3 values (1); +insert into t3 values (2); +insert into t3 values (3); +select f1 from t1; +f1 +1 +2 +3 +select f1 from t2; +f1 +1 +2 +3 +select f1 from t3; +f1 +1 +2 +3 +set @save_dbug = @@debug_dbug; +set debug_dbug = '+d,dml_cascade_only_once'; +set debug_dbug = '+d,row_upd_cascade_lock_wait_err'; +update t1 set f1 = 100 where f1 = 2; +select f1 from t1; +f1 +1 +3 +100 +select f1 from t2; +f1 +1 +3 +100 +select f1 from t3; +f1 +1 +3 +100 +set debug_dbug = @save_dbug; +drop table t2; +drop table t3; +drop table t1; diff --git a/mysql-test/suite/innodb/r/import_update_stats.result b/mysql-test/suite/innodb/r/import_update_stats.result new file mode 100644 index 00000000000..57b3abf42af --- /dev/null +++ b/mysql-test/suite/innodb/r/import_update_stats.result @@ -0,0 +1,72 @@ +SET @old_innodb_file_per_table = @@innodb_file_per_table; +SET GLOBAL innodb_file_per_table = 1; +SELECT @@innodb_file_per_table; +@@innodb_file_per_table +1 +CREATE TABLE t1 ( +col_1 CHAR (255), +col_2 VARCHAR (255) +) ENGINE = InnoDB; +CREATE INDEX idx1 ON t1(col_1); +CREATE INDEX idx2 ON t1(col_2); +SHOW INDEXES FROM t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +t1 1 idx1 1 col_1 A 0 NULL NULL YES BTREE +t1 1 idx2 1 col_2 A 0 NULL NULL YES BTREE +INSERT INTO t1 VALUES ("col1_00001", "col2_00001"), ("col1_00002", "col2_00002"); +SHOW INDEXES FROM t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +t1 1 idx1 1 col_1 A 2 NULL NULL YES BTREE +t1 1 idx2 1 col_2 A 2 NULL NULL YES BTREE +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +SHOW INDEXES FROM t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +t1 1 idx1 1 col_1 A 2 NULL NULL YES BTREE +t1 1 idx2 1 col_2 A 2 NULL NULL YES BTREE +FLUSH TABLES t1 FOR EXPORT; +backup: t1 +UNLOCK TABLES; +DROP TABLE t1; +CREATE TABLE t1 ( +col_1 CHAR (255), +col_2 VARCHAR (255) +) ENGINE = InnoDB STATS_PERSISTENT=1; +CREATE INDEX idx1 ON t1(col_1); +CREATE INDEX idx2 ON t1(col_2); +SHOW INDEXES FROM t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +t1 1 idx1 1 col_1 A 0 NULL NULL YES BTREE +t1 1 idx2 1 col_2 A 0 NULL NULL YES BTREE +INSERT INTO t1 VALUES ("col1_00001", "col2_00001"); +SHOW INDEXES FROM t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +t1 1 idx1 1 col_1 A 1 NULL NULL YES BTREE +t1 1 idx2 1 col_2 A 1 NULL NULL YES BTREE +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +SHOW INDEXES FROM t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +t1 1 idx1 1 col_1 A 1 NULL NULL YES BTREE +t1 1 idx2 1 col_2 A 1 NULL NULL YES BTREE +ALTER TABLE t1 DISCARD TABLESPACE; +restore: t1 .ibd and .cfg files +ALTER TABLE t1 IMPORT TABLESPACE; +SHOW INDEXES FROM t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +t1 1 idx1 1 col_1 A 2 NULL NULL YES BTREE +t1 1 idx2 1 col_2 A 2 NULL NULL YES BTREE +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +SHOW INDEXES FROM t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +t1 1 idx1 1 col_1 A 2 NULL NULL YES BTREE +t1 1 idx2 1 col_2 A 2 NULL NULL YES BTREE +DROP TABLE t1; +SET GLOBAL innodb_file_per_table = @old_innodb_file_per_table; diff --git a/mysql-test/suite/innodb/r/index_length.result b/mysql-test/suite/innodb/r/index_length.result new file mode 100644 index 00000000000..cc92780ac32 --- /dev/null +++ b/mysql-test/suite/innodb/r/index_length.result @@ -0,0 +1,23 @@ +connect stop_purge,localhost,root; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +connection default; +CREATE TABLE t1(a INT PRIMARY KEY, b VARCHAR(1024)) +ENGINE=InnoDB STATS_PERSISTENT=1; +INSERT INTO t1 VALUES (1,REPEAT('b',1024)); +SELECT index_length FROM information_schema.tables +WHERE table_schema = 'test' AND table_name = 't1'; +index_length +0 +ALTER TABLE t1 ADD INDEX b (b(800)); +SELECT FLOOR(index_length/@@innodb_page_size) FROM information_schema.tables +WHERE table_schema = 'test' AND table_name = 't1'; +FLOOR(index_length/@@innodb_page_size) +1 +ALTER TABLE t1 ADD INDEX ba (b(800),a); +SELECT FLOOR(index_length/@@innodb_page_size) FROM information_schema.tables +WHERE table_schema = 'test' AND table_name = 't1'; +FLOOR(index_length/@@innodb_page_size) +2 +disconnect stop_purge; +DROP TABLE t1; +# End of 10.4 tests diff --git a/mysql-test/suite/innodb/r/innodb-32k.result b/mysql-test/suite/innodb/r/innodb-32k.result index e39939b5d13..e4a980a83be 100644 --- a/mysql-test/suite/innodb/r/innodb-32k.result +++ b/mysql-test/suite/innodb/r/innodb-32k.result @@ -1,4 +1,24 @@ call mtr.add_suppression("Innodb: Cannot add field.*row size is"); +SET SESSION innodb_strict_mode=ON; +CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB KEY_BLOCK_SIZE=4; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +SET SESSION innodb_strict_mode=OFF; +CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +Warnings: +Warning 1478 InnoDB: Cannot create a COMPRESSED table when innodb_page_size > 16k. Assuming ROW_FORMAT=DYNAMIC. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: Cannot create a COMPRESSED table when innodb_page_size > 16k. Assuming ROW_FORMAT=DYNAMIC. +DROP TABLE t1; +CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB KEY_BLOCK_SIZE=4; +Warnings: +Warning 1478 InnoDB: Cannot create a COMPRESSED table when innodb_page_size > 16k. Assuming ROW_FORMAT=DYNAMIC. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: Cannot create a COMPRESSED table when innodb_page_size > 16k. Assuming ROW_FORMAT=DYNAMIC. +DROP TABLE t1; # Test 1) Show the page size from Information Schema SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_page_size'; diff --git a/mysql-test/suite/innodb/r/innodb-64k.result b/mysql-test/suite/innodb/r/innodb-64k.result index 758179568b9..c172483905e 100644 --- a/mysql-test/suite/innodb/r/innodb-64k.result +++ b/mysql-test/suite/innodb/r/innodb-64k.result @@ -1,4 +1,24 @@ call mtr.add_suppression('InnoDB: Cannot add field.*because after adding it, the row size is'); +SET SESSION innodb_strict_mode=ON; +CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB KEY_BLOCK_SIZE=4; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +SET SESSION innodb_strict_mode=OFF; +CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +Warnings: +Warning 1478 InnoDB: Cannot create a COMPRESSED table when innodb_page_size > 16k. Assuming ROW_FORMAT=DYNAMIC. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: Cannot create a COMPRESSED table when innodb_page_size > 16k. Assuming ROW_FORMAT=DYNAMIC. +DROP TABLE t1; +CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB KEY_BLOCK_SIZE=4; +Warnings: +Warning 1478 InnoDB: Cannot create a COMPRESSED table when innodb_page_size > 16k. Assuming ROW_FORMAT=DYNAMIC. +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: Cannot create a COMPRESSED table when innodb_page_size > 16k. Assuming ROW_FORMAT=DYNAMIC. +DROP TABLE t1; # Test 1) Show the page size from Information Schema SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_page_size'; diff --git a/mysql-test/suite/innodb/r/innodb-ac-non-locking-select.result b/mysql-test/suite/innodb/r/innodb-ac-non-locking-select.result new file mode 100644 index 00000000000..5d12c1076e7 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb-ac-non-locking-select.result @@ -0,0 +1,62 @@ +CREATE TABLE t1 (c1 INT , c2 CHAR(10), PRIMARY KEY (c1)) ENGINE = InnoDB; +INSERT INTO t1 VALUES(0, "0"); +INSERT INTO t1 VALUES(1, "1"); +INSERT INTO t1 VALUES(2, "2"); +INSERT INTO t1 VALUES(3, "3"); +connect con1,localhost,root,,; +connect con2,localhost,root,,; +connect con3,localhost,root,,; +connect con4,localhost,root,,; +connect con5,localhost,root,,; +connect con6,localhost,root,,; +connection default; +SET AUTOCOMMIT=0; +BEGIN; +SELECT * FROM t1 FOR UPDATE; +c1 c2 +0 0 +1 1 +2 2 +3 3 +SELECT * FROM t1 WHERE c1 <= 3; +c1 c2 +0 0 +1 1 +2 2 +3 3 +connection default; +SET DEBUG_SYNC='now WAIT_FOR waiting4'; +SET DEBUG_SYNC= 'RESET'; +SELECT trx_state, trx_query, trx_autocommit_non_locking +FROM INFORMATION_SCHEMA.INNODB_TRX +WHERE trx_state = 'LOCK WAIT' +ORDER BY trx_query; +trx_state trx_query trx_autocommit_non_locking +LOCK WAIT SELECT COUNT(*) FROM t1 LOCK IN SHARE MODE 0 +LOCK WAIT SELECT COUNT(*) FROM t1 WHERE c1 >= 0 0 +INSERT INTO t1 VALUES(4, '4'); +COMMIT; +connection con6; +SELECT * FROM t1 WHERE c1 <= 4; +c1 c2 +0 0 +1 1 +2 2 +3 3 +XA END '1'; +XA PREPARE '1'; +XA ROLLBACK '1'; +disconnect con6; +disconnect con2; +disconnect con3; +disconnect con5; +connection con1; +COUNT(*) +5 +disconnect con1; +connection con4; +COUNT(*) +5 +disconnect con4; +connection default; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/innodb-alter.result b/mysql-test/suite/innodb/r/innodb-alter.result index 2b3120016aa..126821de203 100644 --- a/mysql-test/suite/innodb/r/innodb-alter.result +++ b/mysql-test/suite/innodb/r/innodb-alter.result @@ -1090,3 +1090,59 @@ ALTER TABLE t1 ADD COLUMN b DATETIME NOT NULL, LOCK=NONE; # Cleanup SET @@SQL_MODE= @OLD_SQL_MODE; DROP TABLE t1; +# +# Bug#20977779 CANNOT IMPORT TABLES CONTAINING PREFIX INDEXES +# +CREATE TABLE t1 (c1 VARCHAR(32), c2 VARCHAR(32), c3 VARCHAR(32), +PRIMARY KEY (c1, c2, c3)) +ENGINE=InnoDB; +ALTER TABLE t1 ADD INDEX ind1(c1(5), c2, c3); +ALTER TABLE t1 ADD INDEX ind2(c3, c1(10), c2); +ALTER TABLE t1 ADD INDEX ind3(c2, c3, c1(20)); +INSERT INTO t1 VALUES ('Test Data -1', 'Test Data -2', 'Test Data -3'); +# Test with 2ndary index having prefix +FLUSH TABLES test.t1 FOR EXPORT; +UNLOCK TABLES; +ALTER TABLE test.t1 DISCARD TABLESPACE; +ALTER TABLE test.t1 IMPORT TABLESPACE; +CHECK TABLE test.t1; +Table Op Msg_type Msg_text +test.t1 check status OK +SHOW CREATE TABLE test.t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` varchar(32) NOT NULL, + `c2` varchar(32) NOT NULL, + `c3` varchar(32) NOT NULL, + PRIMARY KEY (`c1`,`c2`,`c3`), + KEY `ind1` (`c1`(5),`c2`,`c3`), + KEY `ind2` (`c3`,`c1`(10),`c2`), + KEY `ind3` (`c2`,`c3`,`c1`(20)) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SELECT * FROM test.t1; +c1 c2 c3 +Test Data -1 Test Data -2 Test Data -3 +# Test with PK & 2ndary index with prefix +ALTER TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY(c1(5), c2(10), c3(20)); +FLUSH TABLES test.t1 FOR EXPORT; +UNLOCK TABLES; +ALTER TABLE test.t1 DISCARD TABLESPACE; +ALTER TABLE test.t1 IMPORT TABLESPACE; +CHECK TABLE test.t1; +Table Op Msg_type Msg_text +test.t1 check status OK +SHOW CREATE TABLE test.t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` varchar(32) NOT NULL, + `c2` varchar(32) NOT NULL, + `c3` varchar(32) NOT NULL, + PRIMARY KEY (`c1`(5),`c2`(10),`c3`(20)), + KEY `ind1` (`c1`(5),`c2`,`c3`), + KEY `ind2` (`c3`,`c1`(10),`c2`), + KEY `ind3` (`c2`,`c3`,`c1`(20)) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SELECT * FROM test.t1; +c1 c2 c3 +Test Data -1 Test Data -2 Test Data -3 +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/innodb-index-online-fk.result b/mysql-test/suite/innodb/r/innodb-index-online-fk.result index b610d7a00b5..afe55543e55 100644 --- a/mysql-test/suite/innodb/r/innodb-index-online-fk.result +++ b/mysql-test/suite/innodb/r/innodb-index-online-fk.result @@ -618,3 +618,39 @@ test/e d a 0 test/fw c a 0 DROP TABLE t2; DROP TABLE t3; +# Bug #17449901 TABLE DISAPPEARS WHEN ALTERING +# WITH FOREIGN KEY CHECKS OFF +create table t1(f1 int,primary key(f1))engine=innodb; +create table t2(f2 int,f3 int,key t(f2,f3),foreign key(f2) references t1(f1))engine=innodb; +SET foreign_key_checks=0; +drop index t on t2; +drop table t2; +drop table t1; +create table t1(f1 int ,primary key(f1))engine=innodb; +create table t2(f2 int,f3 int, key t(f2),foreign key(f2) references t1(f1))engine=innodb; +SET foreign_key_checks = 0; +alter table t2 drop key t,algorithm=inplace; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `f2` int(11) DEFAULT NULL, + `f3` int(11) DEFAULT NULL, + CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f2`) REFERENCES `t1` (`f1`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +drop table t2; +drop table t1; +create table t1(f1 int ,primary key(f1))engine=innodb; +create table t2(f2 int,f3 int, key t(f2),key t1(f2,f3), +foreign key(f2) references t1(f1))engine=innodb; +SET foreign_key_checks = 0; +alter table t2 drop key t,algorithm=inplace; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `f2` int(11) DEFAULT NULL, + `f3` int(11) DEFAULT NULL, + KEY `t1` (`f2`,`f3`), + CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f2`) REFERENCES `t1` (`f1`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +drop table t2; +drop table t1; diff --git a/mysql-test/suite/innodb/r/innodb-lock-inherit-read_commited.result b/mysql-test/suite/innodb/r/innodb-lock-inherit-read_commited.result new file mode 100644 index 00000000000..1fe569d28ef --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb-lock-inherit-read_commited.result @@ -0,0 +1,124 @@ +# +# Bug #21025880 DUPLICATE UK VALUES IN READ-COMMITTED(AGAIN) +# +SET @save_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; +SET GLOBAL innodb_purge_rseg_truncate_frequency=1; +CREATE TABLE t1 ( +a INT NOT NULL, +b INT NOT NULL, +PRIMARY KEY(b), +UNIQUE KEY(a)) +ENGINE=INNODB; +SET @old_innodb_stats_auto_recalc = @@innodb_stats_auto_recalc; +SET GLOBAL innodb_stats_auto_recalc = OFF; +connect purge_control,localhost,root; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +connection default; +SET @old_tx_isolation = @@tx_isolation; +SET GLOBAL tx_isolation = 'READ-COMMITTED'; +SET @old_innodb_lock_wait_timeout = @@innodb_lock_wait_timeout; +SET GLOBAL innodb_lock_wait_timeout = 1; +connect con1,localhost,root,,; +INSERT INTO t1 VALUES (1,1),(2,2); +DELETE FROM t1; +SET debug_sync = 'row_ins_sec_index_entry_dup_locks_created SIGNAL +con1_locks_done WAIT_FOR con1_go'; +SET debug_sync = 'ha_commit_trans_after_acquire_commit_lock SIGNAL +con1_insert_done WAIT_FOR con1_finish'; +REPLACE INTO t1 VALUES (1,2); +connect con2,localhost,root,,; +SET debug_sync = 'now WAIT_FOR con1_locks_done'; +SET debug_sync = 'lock_wait_suspend_thread_enter SIGNAL con2_blocked +WAIT_FOR con2_go'; +SET debug_sync = 'ha_commit_trans_after_acquire_commit_lock +WAIT_FOR con2_finish'; +SET debug_sync = 'ib_after_row_insert SIGNAL con2_insert_done'; +REPLACE INTO t1 VALUES (1,3); +connection default; +SET debug_sync = 'now WAIT_FOR con2_blocked'; +connection purge_control; +COMMIT; +disconnect purge_control; +connection default; +InnoDB 0 transactions not purged +SET debug_sync = 'now SIGNAL con2_go WAIT_FOR con2_insert_done'; +SET debug_sync = 'now SIGNAL con1_go WAIT_FOR con1_insert_done'; +SET debug_sync = 'now SIGNAL con1_finish'; +connection con1; +disconnect con1; +connection default; +SET debug_sync = 'now SIGNAL con2_finish'; +connection con2; +disconnect con2; +connection default; +SET DEBUG_SYNC= 'RESET'; +SELECT * FROM t1; +a b +1 2 +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; +SET GLOBAL innodb_stats_auto_recalc = @old_innodb_stats_auto_recalc; +SET GLOBAL tx_isolation = @old_tx_isolation; +SET GLOBAL innodb_lock_wait_timeout = @old_innodb_lock_wait_timeout; +CREATE TABLE t1 ( +a INT NOT NULL, +b INT NOT NULL, +PRIMARY KEY(b), +UNIQUE KEY(a)) +ENGINE=INNODB; +SET @old_innodb_stats_auto_recalc = @@innodb_stats_auto_recalc; +SET GLOBAL innodb_stats_auto_recalc = OFF; +connect purge_control,localhost,root; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +connection default; +SET @old_tx_isolation = @@tx_isolation; +SET GLOBAL tx_isolation = 'READ-COMMITTED'; +SET @old_innodb_lock_wait_timeout = @@innodb_lock_wait_timeout; +SET GLOBAL innodb_lock_wait_timeout = 1; +connect con1,localhost,root,,; +INSERT INTO t1 VALUES (1,1),(2,2); +DELETE FROM t1; +SET debug_sync = 'row_ins_sec_index_entry_dup_locks_created SIGNAL +con1_locks_done WAIT_FOR con1_go'; +SET debug_sync = 'ha_commit_trans_after_acquire_commit_lock SIGNAL +con1_insert_done WAIT_FOR con1_finish'; +INSERT INTO t1 values (1,2) ON DUPLICATE KEY UPDATE a=2; +connect con2,localhost,root,,; +SET debug_sync = 'now WAIT_FOR con1_locks_done'; +SET debug_sync = 'lock_wait_suspend_thread_enter SIGNAL con2_blocked +WAIT_FOR con2_go'; +SET debug_sync = 'ha_commit_trans_after_acquire_commit_lock +WAIT_FOR con2_finish'; +SET debug_sync = 'ib_after_row_insert SIGNAL con2_insert_done'; +REPLACE INTO t1 VALUES (1,3); +connection default; +SET debug_sync = 'now WAIT_FOR con2_blocked'; +connection purge_control; +COMMIT; +disconnect purge_control; +connection default; +InnoDB 0 transactions not purged +SET debug_sync = 'now SIGNAL con2_go WAIT_FOR con2_insert_done'; +SET debug_sync = 'now SIGNAL con1_go WAIT_FOR con1_insert_done'; +SET debug_sync = 'now SIGNAL con1_finish'; +connection con1; +disconnect con1; +connection default; +SET debug_sync = 'now SIGNAL con2_finish'; +connection con2; +disconnect con2; +connection default; +SET DEBUG_SYNC= 'RESET'; +SELECT * FROM t1; +a b +1 2 +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; +SET GLOBAL innodb_stats_auto_recalc = @old_innodb_stats_auto_recalc; +SET GLOBAL tx_isolation = @old_tx_isolation; +SET GLOBAL innodb_lock_wait_timeout = @old_innodb_lock_wait_timeout; +SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_frequency; diff --git a/mysql-test/suite/innodb/r/innodb-read-view.result b/mysql-test/suite/innodb/r/innodb-read-view.result index e01d8a110e6..f3084fbdc52 100644 --- a/mysql-test/suite/innodb/r/innodb-read-view.result +++ b/mysql-test/suite/innodb/r/innodb-read-view.result @@ -9,9 +9,6 @@ INSERT INTO t2 VALUES(1, "b"); INSERT INTO t2 VALUES(2, "c"); INSERT INTO t2 VALUES(3, "d"); connect con1,localhost,root,,; -connect con2,localhost,root,,; -connection con1; -'T1' SET AUTOCOMMIT=0; BEGIN; SELECT * FROM t2; @@ -21,7 +18,6 @@ c1 c2 2 c 3 d connection default; -'T2' SET AUTOCOMMIT=0; BEGIN; SELECT * FROM t1; @@ -30,8 +26,7 @@ c1 c2 1 1 2 2 3 3 -connection con2; -'T3' +connect con2,localhost,root,,; SET AUTOCOMMIT=0; SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; BEGIN; @@ -48,7 +43,6 @@ c1 c2 2 c 3 d connection con1; -'T1' UPDATE t2 SET c1 = c1 + 100; SELECT * FROM t2; c1 c2 @@ -58,7 +52,6 @@ c1 c2 103 d COMMIT; connection default; -'T2' UPDATE t1 SET c1 = c1 + 100; SELECT * FROM t1; c1 c2 @@ -68,42 +61,29 @@ c1 c2 103 3 COMMIT; connection con2; -'T3' SET DEBUG_SYNC='row_search_for_mysql_before_return WAIT_FOR waiting1'; SELECT * FROM t1;; connection default; -'T2' SET DEBUG_SYNC='now SIGNAL waiting1'; -'Signalled T3' connection con2; -'T3' c1 c2 0 0 1 1 2 2 3 3 connection con2; -'T3' SET DEBUG_SYNC='row_search_for_mysql_before_return WAIT_FOR waiting1'; SELECT * FROM t2;; connection default; -'T2' SET DEBUG_SYNC='now SIGNAL waiting1'; -'Signalled T3' connection con2; -'T3' c1 c2 0 a 1 b 2 c 3 d connection default; -disconnect con1; -disconnect con2; -connect con1,localhost,root,,; -connect con2,localhost,root,,; connection con1; -'T1' SET AUTOCOMMIT=0; BEGIN; SELECT * FROM t1; @@ -113,7 +93,6 @@ c1 c2 102 2 103 3 connection default; -'T2' SET AUTOCOMMIT=0; BEGIN; SELECT * FROM t2; @@ -131,7 +110,6 @@ c1 c2 203 d COMMIT; connection con2; -'T3' SET AUTOCOMMIT=0; SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; BEGIN; @@ -148,7 +126,6 @@ c1 c2 202 c 203 d connection con1; -'T1' UPDATE t1 SET c1 = c1 + 100; SELECT * FROM t1; c1 c2 @@ -158,44 +135,34 @@ c1 c2 203 3 COMMIT; connection con2; -'T3' SET DEBUG_SYNC='row_select_wait WAIT_FOR waiting1'; SELECT * FROM t1;; connection con1; -'T2' SET DEBUG_SYNC='now SIGNAL waiting1'; -'Signalled T3' connection con2; -'T3' c1 c2 100 0 101 1 102 2 103 3 -connection con2; -'T3' SET DEBUG_SYNC='row_select_wait WAIT_FOR waiting1'; SELECT * FROM t2;; connection default; -'T2' SET DEBUG_SYNC='now SIGNAL waiting1'; -'Signalled T3' connection con2; -'T3' c1 c2 200 a 201 b 202 c 203 d -connection default; -disconnect con1; disconnect con2; +connection default; DROP TABLE t1; DROP TABLE t2; # # Bug 21433768: NON-REPEATABLE READ WITH REPEATABLE READ ISOLATION # -connect con1,localhost,root,,; +connection con1; CREATE TABLE t1(col1 INT PRIMARY KEY, col2 INT) ENGINE = InnoDB; INSERT INTO t1 values (1, 0), (2, 0); SELECT * FROM t1 ORDER BY col1; @@ -218,5 +185,5 @@ SET DEBUG_SYNC = 'now SIGNAL s2'; connection con1; disconnect con1; connection default; -DROP TABLE t1; SET DEBUG_SYNC= 'RESET'; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/innodb_i_s_innodb_locks.result b/mysql-test/suite/innodb/r/innodb_i_s_innodb_locks.result new file mode 100644 index 0000000000000000000000000000000000000000..a410362ab525f846535b8d12f6b86fd9527d6b05 GIT binary patch literal 5451 zcmeGgYj4^}FkjcdV&yMRDiZl^5JCz8H$erQ8o0YimW&Io4qd=GFl}SX-JQoy>?yt61z$oxUaiAuA9pStik$q~LeI6kQ=3k^S3{e|{(7~cr@}&3=yWi?8;qw7K-3hWv+-nb zJ+}Ku)#zl@9S##7J;Mr21|8Y`!EBUpnFqAMX3>P9i9n&NMXv_eyjPJEILC174n|$~ zj()K3PC@Mk1$D8}u+gzGuraZ*uxVn`f<}?ggfnW7LAc!+jK@y@s@)a_S{}GnU>lDdUY3Y zSX0+cOV?#fv*eaxD5heRH)cMc$C4-dyLdat{ZT+Gw|CQZPc`)nZh%_CwGytEaHE8q zCEP0Fg_Dg38_zW!YdqC>sPRl&)iYc;!i6=YMwJw)L8ai+0{^5GKwM%SlEk|L1~3}u zf_@3Cl)od#Cs1<}h{;6oCo-~_NQZw$Kn78)Cs@k~_Pm2+&tn~)m&itd(-@Zrzj_ns zhY93ISvD0@HNoieBZp*}!_bq_Ib7^P{|c5`M4L^xh$#htIqL>^?BM>-XcsrOQ4}{C zB_8mPO!h)?80sA@AePdaJ^r@CLM>c=(3HzDsN#{-@>fDg;{@% z`AfK6eSU(KX0dVi{E$_&$##WD&0rr#i)g)G#T^+bL%TPn@92Bi86~0Mz2nl^Z65+A zY@4hQh&AwO@agaw@R{&g@HOFU5r{DYh7BSU9yAb0LI#4F%VHc=M+M}n9^f6nMGx?# z1RN=0ev~jbN)j(hQYT6>g)DM#p`@yqMUFYplCA~UP*52x2ZjT?f!V-nU^Gim2;63Z z&IkdC1mJ{NBQc^R2`b}2Z-IbF0&pO#5eau8g2p(|Eg;~L0K5QeJc2~e6LiLLl5m`m z-~>6K;o!+hdS%n&k-LyJ&IG^i+1SGkJu?!kG$=sC0T^z_{sPg7rs z48pbR%x<&D5Tl4BG%%Q?(uCB}!zn{st9im|lPBaC0O{^7jFUI3-QV{<#yUtBE-zCA zL*bN8J`Vkn)3-ZP7ao-Sk27a#Po!d)WC}HCs?iT#pNN4>yb#&?L|9*ru-fDa>t<8 literal 0 HcmV?d00001 diff --git a/mysql-test/suite/innodb/r/innodb_i_s_innodb_trx.result b/mysql-test/suite/innodb/r/innodb_i_s_innodb_trx.result new file mode 100644 index 00000000000..e4bb83a3b24 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_i_s_innodb_trx.result @@ -0,0 +1,90 @@ +SET @save_timeout=@@GLOBAL.innodb_lock_wait_timeout; +SET GLOBAL innodb_lock_wait_timeout=100000000; +DESCRIBE INFORMATION_SCHEMA.INNODB_TRX; +Field Type Null Key Default Extra +trx_id varchar(18) NO NULL +trx_state varchar(13) NO NULL +trx_started datetime NO NULL +trx_requested_lock_id varchar(81) YES NULL +trx_wait_started datetime YES NULL +trx_weight bigint(21) unsigned NO NULL +trx_mysql_thread_id bigint(21) unsigned NO NULL +trx_query varchar(1024) YES NULL +trx_operation_state varchar(64) YES NULL +trx_tables_in_use bigint(21) unsigned NO NULL +trx_tables_locked bigint(21) unsigned NO NULL +trx_lock_structs bigint(21) unsigned NO NULL +trx_lock_memory_bytes bigint(21) unsigned NO NULL +trx_rows_locked bigint(21) unsigned NO NULL +trx_rows_modified bigint(21) unsigned NO NULL +trx_concurrency_tickets bigint(21) unsigned NO NULL +trx_isolation_level varchar(16) NO NULL +trx_unique_checks int(1) NO NULL +trx_foreign_key_checks int(1) NO NULL +trx_last_foreign_key_error varchar(256) YES NULL +trx_is_read_only int(1) NO NULL +trx_autocommit_non_locking int(1) NO NULL +CREATE TABLE t1 ( +c01 INT, +c02 INT, +PRIMARY KEY (c01) +) ENGINE=INNODB STATS_AUTO_RECALC=0; +INSERT INTO t1 VALUES +(1,2),(2,4),(3,6),(4,8); +CREATE TABLE t2 ( +c01 INT, +c02 INT, +PRIMARY KEY (c01), +FOREIGN KEY fk1 (c02) REFERENCES t1 (c01) +) ENGINE=INNODB STATS_AUTO_RECALC=0; +INSERT INTO t2 VALUES +(1,1),(2,2),(3,3); +connect con_trx,localhost,root,,; +connect con_verify_innodb_trx,localhost,root,,; +connection con_trx; +SET autocommit=0; +INSERT INTO t1 VALUES (5,10); +SELECT * FROM t1 FOR UPDATE; +c01 c02 +1 2 +2 4 +3 6 +4 8 +5 10 +connection con_verify_innodb_trx; +SELECT trx_state, trx_weight, trx_tables_in_use, trx_tables_locked, +trx_rows_locked, trx_rows_modified, trx_concurrency_tickets, +trx_isolation_level, trx_unique_checks, trx_foreign_key_checks +FROM INFORMATION_SCHEMA.INNODB_TRX; +trx_state trx_weight trx_tables_in_use trx_tables_locked trx_rows_locked trx_rows_modified trx_concurrency_tickets trx_isolation_level trx_unique_checks trx_foreign_key_checks +RUNNING 3 0 1 6 1 0 REPEATABLE READ 1 1 +connection con_trx; +ROLLBACK; +SET FOREIGN_KEY_CHECKS = 0; +SET UNIQUE_CHECKS = 0; +SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; +BEGIN; +INSERT INTO t1 VALUES (6,12); +connection con_verify_innodb_trx; +SELECT trx_isolation_level, trx_unique_checks, trx_foreign_key_checks +FROM INFORMATION_SCHEMA.INNODB_TRX; +trx_isolation_level trx_unique_checks trx_foreign_key_checks +SERIALIZABLE 0 0 +connection con_trx; +ROLLBACK; +SET FOREIGN_KEY_CHECKS = 1; +SET UNIQUE_CHECKS = 1; +BEGIN; +INSERT INTO t2 VALUES (4,10); +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `fk1` FOREIGN KEY (`c02`) REFERENCES `t1` (`c01`)) +disconnect con_trx; +connection con_verify_innodb_trx; +SELECT trx_state, trx_isolation_level, trx_last_foreign_key_error +FROM INFORMATION_SCHEMA.INNODB_TRX; +trx_state trx_isolation_level trx_last_foreign_key_error +RUNNING REPEATABLE READ `test`.`t2`, CONSTRAINT `fk1` FOREIGN KEY (`c02`) REFERENCES `t1` (`c01`) +disconnect con_verify_innodb_trx; +connection default; +DROP TABLE t2; +DROP TABLE t1; +SET GLOBAL innodb_lock_wait_timeout=@save_timeout; diff --git a/mysql-test/suite/innodb/r/innodb_information_schema_tables.result b/mysql-test/suite/innodb/r/innodb_information_schema_tables.result index ea713ea6f6a..87ff94a9ab1 100644 --- a/mysql-test/suite/innodb/r/innodb_information_schema_tables.result +++ b/mysql-test/suite/innodb/r/innodb_information_schema_tables.result @@ -1,2 +1,3 @@ +FOUND 1 /\[Warning\] InnoDB: innodb_open_files 1000000 should not be greater than the open_files_limit [0-9]+/ in mysqld.1.err CREATE TABLE t1 ENGINE=InnoDB AS SELECT * FROM mysql.help_topic; DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/innodb_stats_auto_recalc.result b/mysql-test/suite/innodb/r/innodb_stats_auto_recalc.result new file mode 100644 index 00000000000..40eae0a9385 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_stats_auto_recalc.result @@ -0,0 +1,44 @@ +CREATE TABLE autorecalc (a INT, PRIMARY KEY (a)) ENGINE=INNODB; +SELECT n_rows, clustered_index_size FROM mysql.innodb_table_stats WHERE table_name = 'autorecalc'; +n_rows 0 +clustered_index_size 1 +SELECT index_name, stat_name, stat_value FROM mysql.innodb_index_stats WHERE table_name = 'autorecalc'; +index_name PRIMARY +stat_name n_diff_pfx01 +stat_value 0 +index_name PRIMARY +stat_name n_leaf_pages +stat_value 1 +index_name PRIMARY +stat_name size +stat_value 1 +INSERT INTO autorecalc VALUES (1); +INSERT INTO autorecalc VALUES (2); +SELECT n_rows, clustered_index_size FROM mysql.innodb_table_stats WHERE table_name = 'autorecalc'; +n_rows 2 +clustered_index_size 1 +SELECT index_name, stat_name, stat_value FROM mysql.innodb_index_stats WHERE table_name = 'autorecalc'; +index_name PRIMARY +stat_name n_diff_pfx01 +stat_value 2 +index_name PRIMARY +stat_name n_leaf_pages +stat_value 1 +index_name PRIMARY +stat_name size +stat_value 1 +DELETE FROM autorecalc; +SELECT n_rows, clustered_index_size FROM mysql.innodb_table_stats WHERE table_name = 'autorecalc'; +n_rows 0 +clustered_index_size 1 +SELECT index_name, stat_name, stat_value FROM mysql.innodb_index_stats WHERE table_name = 'autorecalc'; +index_name PRIMARY +stat_name n_diff_pfx01 +stat_value 0 +index_name PRIMARY +stat_name n_leaf_pages +stat_value 1 +index_name PRIMARY +stat_name size +stat_value 1 +DROP TABLE autorecalc; diff --git a/mysql-test/suite/innodb/r/innodb_stats_auto_recalc_ddl.result b/mysql-test/suite/innodb/r/innodb_stats_auto_recalc_ddl.result new file mode 100644 index 00000000000..8c68fe74504 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_stats_auto_recalc_ddl.result @@ -0,0 +1,34 @@ +CREATE TABLE arddl (a INT, b INT, PRIMARY KEY (a)) ENGINE=INNODB; +INSERT INTO arddl VALUES (1, 10); +INSERT INTO arddl VALUES (2, 10); +ALTER TABLE arddl ADD INDEX (b); +SELECT n_rows FROM mysql.innodb_table_stats WHERE table_name = 'arddl' ORDER BY 1; +n_rows 2 +SELECT index_name, stat_name, stat_value FROM mysql.innodb_index_stats WHERE table_name = 'arddl' AND index_name = 'PRIMARY' ORDER BY 1, 2, 3; +index_name PRIMARY +stat_name n_diff_pfx01 +stat_value 2 +index_name PRIMARY +stat_name n_leaf_pages +stat_value 1 +index_name PRIMARY +stat_name size +stat_value 1 +DROP TABLE arddl; +CREATE TABLE arddl (a INT, b INT, PRIMARY KEY (a), KEY (b)) ENGINE=INNODB; +INSERT INTO arddl VALUES (3, 10); +INSERT INTO arddl VALUES (4, 10); +ALTER TABLE arddl DROP INDEX b; +SELECT n_rows FROM mysql.innodb_table_stats WHERE table_name = 'arddl' ORDER BY 1; +n_rows 2 +SELECT index_name, stat_name, stat_value FROM mysql.innodb_index_stats WHERE table_name = 'arddl' AND index_name = 'PRIMARY' ORDER BY 1, 2, 3; +index_name PRIMARY +stat_name n_diff_pfx01 +stat_value 2 +index_name PRIMARY +stat_name n_leaf_pages +stat_value 1 +index_name PRIMARY +stat_name size +stat_value 1 +DROP TABLE arddl; diff --git a/mysql-test/suite/innodb/r/innodb_stats_auto_recalc_lots.result b/mysql-test/suite/innodb/r/innodb_stats_auto_recalc_lots.result new file mode 100644 index 00000000000..746bce5687e --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_stats_auto_recalc_lots.result @@ -0,0 +1,202 @@ +SELECT table_name, n_rows FROM mysql.innodb_table_stats WHERE table_name LIKE 'ar_%' ORDER BY table_name; +table_name n_rows +ar_1001 0 +ar_1002 0 +ar_1003 0 +ar_1004 0 +ar_1005 0 +ar_1006 0 +ar_1007 0 +ar_1008 0 +ar_1009 0 +ar_1010 0 +ar_1011 0 +ar_1012 0 +ar_1013 0 +ar_1014 0 +ar_1015 0 +ar_1016 0 +ar_1017 0 +ar_1018 0 +ar_1019 0 +ar_1020 0 +ar_1021 0 +ar_1022 0 +ar_1023 0 +ar_1024 0 +ar_1025 0 +ar_1026 0 +ar_1027 0 +ar_1028 0 +ar_1029 0 +ar_1030 0 +ar_1031 0 +ar_1032 0 +ar_1033 0 +ar_1034 0 +ar_1035 0 +ar_1036 0 +ar_1037 0 +ar_1038 0 +ar_1039 0 +ar_1040 0 +ar_1041 0 +ar_1042 0 +ar_1043 0 +ar_1044 0 +ar_1045 0 +ar_1046 0 +ar_1047 0 +ar_1048 0 +ar_1049 0 +ar_1050 0 +ar_1051 0 +ar_1052 0 +ar_1053 0 +ar_1054 0 +ar_1055 0 +ar_1056 0 +ar_1057 0 +ar_1058 0 +ar_1059 0 +ar_1060 0 +ar_1061 0 +ar_1062 0 +ar_1063 0 +ar_1064 0 +ar_1065 0 +ar_1066 0 +ar_1067 0 +ar_1068 0 +ar_1069 0 +ar_1070 0 +ar_1071 0 +ar_1072 0 +ar_1073 0 +ar_1074 0 +ar_1075 0 +ar_1076 0 +ar_1077 0 +ar_1078 0 +ar_1079 0 +ar_1080 0 +ar_1081 0 +ar_1082 0 +ar_1083 0 +ar_1084 0 +ar_1085 0 +ar_1086 0 +ar_1087 0 +ar_1088 0 +ar_1089 0 +ar_1090 0 +ar_1091 0 +ar_1092 0 +ar_1093 0 +ar_1094 0 +ar_1095 0 +ar_1096 0 +ar_1097 0 +ar_1098 0 +ar_1099 0 +ar_1100 0 +ar_1101 0 +ar_1102 0 +ar_1103 0 +ar_1104 0 +ar_1105 0 +ar_1106 0 +ar_1107 0 +ar_1108 0 +ar_1109 0 +ar_1110 0 +ar_1111 0 +ar_1112 0 +ar_1113 0 +ar_1114 0 +ar_1115 0 +ar_1116 0 +ar_1117 0 +ar_1118 0 +ar_1119 0 +ar_1120 0 +ar_1121 0 +ar_1122 0 +ar_1123 0 +ar_1124 0 +ar_1125 0 +ar_1126 0 +ar_1127 0 +ar_1128 0 +ar_1129 0 +ar_1130 0 +ar_1131 0 +ar_1132 0 +ar_1133 0 +ar_1134 0 +ar_1135 0 +ar_1136 0 +ar_1137 0 +ar_1138 0 +ar_1139 0 +ar_1140 0 +ar_1141 0 +ar_1142 0 +ar_1143 0 +ar_1144 0 +ar_1145 0 +ar_1146 0 +ar_1147 0 +ar_1148 0 +ar_1149 0 +ar_1150 0 +ar_1151 0 +ar_1152 0 +ar_1153 0 +ar_1154 0 +ar_1155 0 +ar_1156 0 +ar_1157 0 +ar_1158 0 +ar_1159 0 +ar_1160 0 +ar_1161 0 +ar_1162 0 +ar_1163 0 +ar_1164 0 +ar_1165 0 +ar_1166 0 +ar_1167 0 +ar_1168 0 +ar_1169 0 +ar_1170 0 +ar_1171 0 +ar_1172 0 +ar_1173 0 +ar_1174 0 +ar_1175 0 +ar_1176 0 +ar_1177 0 +ar_1178 0 +ar_1179 0 +ar_1180 0 +ar_1181 0 +ar_1182 0 +ar_1183 0 +ar_1184 0 +ar_1185 0 +ar_1186 0 +ar_1187 0 +ar_1188 0 +ar_1189 0 +ar_1190 0 +ar_1191 0 +ar_1192 0 +ar_1193 0 +ar_1194 0 +ar_1195 0 +ar_1196 0 +ar_1197 0 +ar_1198 0 +ar_1199 0 +ar_1200 0 diff --git a/mysql-test/suite/innodb/r/innodb_stats_auto_recalc_on_nonexistent.result b/mysql-test/suite/innodb/r/innodb_stats_auto_recalc_on_nonexistent.result new file mode 100644 index 00000000000..25a97935223 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_stats_auto_recalc_on_nonexistent.result @@ -0,0 +1,57 @@ +Test with default setting +CREATE TABLE t (a INT, PRIMARY KEY (a)) ENGINE=INNODB; +SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE table_name = 't'; +COUNT(*) 1 +SELECT COUNT(*) FROM mysql.innodb_index_stats WHERE table_name = 't'; +COUNT(*) 3 +FLUSH TABLE t; +DELETE FROM mysql.innodb_index_stats WHERE table_name = 't'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 't'; +SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE table_name = 't'; +COUNT(*) 0 +SELECT COUNT(*) FROM mysql.innodb_index_stats WHERE table_name = 't'; +COUNT(*) 0 +SELECT * FROM t; +SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE table_name = 't'; +COUNT(*) 1 +SELECT COUNT(*) FROM mysql.innodb_index_stats WHERE table_name = 't'; +COUNT(*) 3 +DROP TABLE t; +Test with explicit enable +CREATE TABLE t (a INT, PRIMARY KEY (a)) ENGINE=INNODB STATS_AUTO_RECALC=1; +SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE table_name = 't'; +COUNT(*) 1 +SELECT COUNT(*) FROM mysql.innodb_index_stats WHERE table_name = 't'; +COUNT(*) 3 +FLUSH TABLE t; +DELETE FROM mysql.innodb_index_stats WHERE table_name = 't'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 't'; +SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE table_name = 't'; +COUNT(*) 0 +SELECT COUNT(*) FROM mysql.innodb_index_stats WHERE table_name = 't'; +COUNT(*) 0 +SELECT * FROM t; +SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE table_name = 't'; +COUNT(*) 1 +SELECT COUNT(*) FROM mysql.innodb_index_stats WHERE table_name = 't'; +COUNT(*) 3 +DROP TABLE t; +Test with explicit disable +CREATE TABLE t (a INT, PRIMARY KEY (a)) ENGINE=INNODB STATS_AUTO_RECALC=0; +SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE table_name = 't'; +COUNT(*) 1 +SELECT COUNT(*) FROM mysql.innodb_index_stats WHERE table_name = 't'; +COUNT(*) 3 +FLUSH TABLE t; +DELETE FROM mysql.innodb_index_stats WHERE table_name = 't'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 't'; +SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE table_name = 't'; +COUNT(*) 0 +SELECT COUNT(*) FROM mysql.innodb_index_stats WHERE table_name = 't'; +COUNT(*) 0 +SELECT * FROM t; +SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE table_name = 't'; +COUNT(*) 0 +SELECT COUNT(*) FROM mysql.innodb_index_stats WHERE table_name = 't'; +COUNT(*) 0 +DROP TABLE t; diff --git a/mysql-test/suite/innodb/r/innodb_stats_external_pages.result b/mysql-test/suite/innodb/r/innodb_stats_external_pages.result new file mode 100644 index 00000000000..52e1e153059 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_stats_external_pages.result @@ -0,0 +1,10 @@ +CREATE TABLE bug18384390 ( +id INT AUTO_INCREMENT PRIMARY KEY, +txt VARCHAR(10000) +) ENGINE=INNODB STATS_PERSISTENT=1 STATS_AUTO_RECALC=0; +INSERT INTO bug18384390 (txt) SELECT REPEAT('0', 10000) FROM seq_1_to_1024; +set use_stat_tables=never; +ANALYZE TABLE bug18384390; +Table Op Msg_type Msg_text +test.bug18384390 analyze status OK +DROP TABLE bug18384390; diff --git a/mysql-test/suite/innodb/r/innodb_stats_flag_global,off.rdiff b/mysql-test/suite/innodb/r/innodb_stats_flag_global,off.rdiff new file mode 100644 index 00000000000..f5b235438aa --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_stats_flag_global,off.rdiff @@ -0,0 +1,34 @@ +@@ -18,7 +18,7 @@ + test.test_ps_flag analyze status OK + SELECT COUNT(*) AS cnt_after FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; + cnt_after +-1 ++0 + DROP TABLE test_ps_flag; + CREATE TABLE test_ps_flag (a INT) ENGINE=INNODB STATS_PERSISTENT=default; + SHOW CREATE TABLE test_ps_flag; +@@ -37,7 +37,7 @@ + test.test_ps_flag analyze status OK + SELECT COUNT(*) AS cnt_after FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; + cnt_after +-1 ++0 + DROP TABLE test_ps_flag; + ===== + === Test ANALYZE behavior after creation with explicit PS=OFF +@@ -142,7 +142,7 @@ + test.test_ps_flag analyze status OK + SELECT COUNT(*) AS cnt_after FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; + cnt_after +-1 ++0 + DROP TABLE test_ps_flag; + ===== + === Test ANALYZE behavior after creation with explicit PS=ON, +@@ -203,5 +203,5 @@ + test.test_ps_flag analyze status OK + SELECT COUNT(*) AS cnt_after FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; + cnt_after +-1 ++0 + DROP TABLE test_ps_flag; diff --git a/mysql-test/suite/innodb/r/innodb_stats_flag_global.result b/mysql-test/suite/innodb/r/innodb_stats_flag_global.result new file mode 100644 index 00000000000..8bafb725d89 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_stats_flag_global.result @@ -0,0 +1,207 @@ +===== +=== Test ANALYZE behavior after default creation +===== +CREATE TABLE test_ps_flag (a INT) ENGINE=INNODB; +SHOW CREATE TABLE test_ps_flag; +Table Create Table +test_ps_flag CREATE TABLE `test_ps_flag` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +DELETE FROM mysql.innodb_index_stats WHERE table_name = 'test_ps_flag'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +SELECT COUNT(*) AS cnt_before FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_before +0 +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE test_ps_flag; +Table Op Msg_type Msg_text +test.test_ps_flag analyze status OK +SELECT COUNT(*) AS cnt_after FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_after +1 +DROP TABLE test_ps_flag; +CREATE TABLE test_ps_flag (a INT) ENGINE=INNODB STATS_PERSISTENT=default; +SHOW CREATE TABLE test_ps_flag; +Table Create Table +test_ps_flag CREATE TABLE `test_ps_flag` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +DELETE FROM mysql.innodb_index_stats WHERE table_name = 'test_ps_flag'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +SELECT COUNT(*) AS cnt_before FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_before +0 +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE test_ps_flag; +Table Op Msg_type Msg_text +test.test_ps_flag analyze status OK +SELECT COUNT(*) AS cnt_after FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_after +1 +DROP TABLE test_ps_flag; +===== +=== Test ANALYZE behavior after creation with explicit PS=OFF +===== +CREATE TABLE test_ps_flag (a INT) ENGINE=INNODB STATS_PERSISTENT=0; +SHOW CREATE TABLE test_ps_flag; +Table Create Table +test_ps_flag CREATE TABLE `test_ps_flag` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci STATS_PERSISTENT=0 +DELETE FROM mysql.innodb_index_stats WHERE table_name = 'test_ps_flag'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +SELECT COUNT(*) AS cnt_before FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_before +0 +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE test_ps_flag; +Table Op Msg_type Msg_text +test.test_ps_flag analyze status OK +SELECT COUNT(*) AS cnt_after FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_after +0 +DROP TABLE test_ps_flag; +===== +=== Test ANALYZE behavior after creation with explicit PS=ON +===== +CREATE TABLE test_ps_flag (a INT) ENGINE=INNODB STATS_PERSISTENT=1; +SHOW CREATE TABLE test_ps_flag; +Table Create Table +test_ps_flag CREATE TABLE `test_ps_flag` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci STATS_PERSISTENT=1 +DELETE FROM mysql.innodb_index_stats WHERE table_name = 'test_ps_flag'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +SELECT COUNT(*) AS cnt_before FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_before +0 +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE test_ps_flag; +Table Op Msg_type Msg_text +test.test_ps_flag analyze status OK +SELECT COUNT(*) AS cnt_after FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_after +1 +DROP TABLE test_ps_flag; +===== +=== Test ANALYZE behavior after creation with explicit PS=OFF, +=== then ALTER to ON, then ALTER to OFF, then ALTER to default +===== +CREATE TABLE test_ps_flag (a INT) ENGINE=INNODB STATS_PERSISTENT=0; +ALTER TABLE test_ps_flag STATS_PERSISTENT=1; +# restart +SHOW CREATE TABLE test_ps_flag; +Table Create Table +test_ps_flag CREATE TABLE `test_ps_flag` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci STATS_PERSISTENT=1 +DELETE FROM mysql.innodb_index_stats WHERE table_name = 'test_ps_flag'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +SELECT COUNT(*) AS cnt_before FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_before +0 +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE test_ps_flag; +Table Op Msg_type Msg_text +test.test_ps_flag analyze status OK +SELECT COUNT(*) AS cnt_after FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_after +1 +ALTER TABLE test_ps_flag STATS_PERSISTENT=0; +SHOW CREATE TABLE test_ps_flag; +Table Create Table +test_ps_flag CREATE TABLE `test_ps_flag` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci STATS_PERSISTENT=0 +DELETE FROM mysql.innodb_index_stats WHERE table_name = 'test_ps_flag'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +SELECT COUNT(*) AS cnt_before FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_before +0 +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE test_ps_flag; +Table Op Msg_type Msg_text +test.test_ps_flag analyze status OK +SELECT COUNT(*) AS cnt_after FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_after +0 +ALTER TABLE test_ps_flag STATS_PERSISTENT=default; +SHOW CREATE TABLE test_ps_flag; +Table Create Table +test_ps_flag CREATE TABLE `test_ps_flag` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +DELETE FROM mysql.innodb_index_stats WHERE table_name = 'test_ps_flag'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +SELECT COUNT(*) AS cnt_before FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_before +0 +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE test_ps_flag; +Table Op Msg_type Msg_text +test.test_ps_flag analyze status OK +SELECT COUNT(*) AS cnt_after FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_after +1 +DROP TABLE test_ps_flag; +===== +=== Test ANALYZE behavior after creation with explicit PS=ON, +=== then ALTER to OFF, then ALTER to ON, then ALTER to default +===== +CREATE TABLE test_ps_flag (a INT) ENGINE=INNODB STATS_PERSISTENT=1; +ALTER TABLE test_ps_flag STATS_PERSISTENT=0; +# restart +SHOW CREATE TABLE test_ps_flag; +Table Create Table +test_ps_flag CREATE TABLE `test_ps_flag` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci STATS_PERSISTENT=0 +DELETE FROM mysql.innodb_index_stats WHERE table_name = 'test_ps_flag'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +SELECT COUNT(*) AS cnt_before FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_before +0 +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE test_ps_flag; +Table Op Msg_type Msg_text +test.test_ps_flag analyze status OK +SELECT COUNT(*) AS cnt_after FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_after +0 +ALTER TABLE test_ps_flag STATS_PERSISTENT=1; +SHOW CREATE TABLE test_ps_flag; +Table Create Table +test_ps_flag CREATE TABLE `test_ps_flag` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci STATS_PERSISTENT=1 +DELETE FROM mysql.innodb_index_stats WHERE table_name = 'test_ps_flag'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +SELECT COUNT(*) AS cnt_before FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_before +0 +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE test_ps_flag; +Table Op Msg_type Msg_text +test.test_ps_flag analyze status OK +SELECT COUNT(*) AS cnt_after FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_after +1 +ALTER TABLE test_ps_flag STATS_PERSISTENT=default; +SHOW CREATE TABLE test_ps_flag; +Table Create Table +test_ps_flag CREATE TABLE `test_ps_flag` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +DELETE FROM mysql.innodb_index_stats WHERE table_name = 'test_ps_flag'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +SELECT COUNT(*) AS cnt_before FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_before +0 +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE test_ps_flag; +Table Op Msg_type Msg_text +test.test_ps_flag analyze status OK +SELECT COUNT(*) AS cnt_after FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; +cnt_after +1 +DROP TABLE test_ps_flag; diff --git a/mysql-test/suite/innodb/r/innodb_stats_persistent.result b/mysql-test/suite/innodb/r/innodb_stats_persistent.result index e25ab2a8a24..7778f8da84d 100644 --- a/mysql-test/suite/innodb/r/innodb_stats_persistent.result +++ b/mysql-test/suite/innodb/r/innodb_stats_persistent.result @@ -10,9 +10,9 @@ CREATE TABLE t1 (id SERIAL, val INT UNSIGNED NOT NULL, KEY(val)) ENGINE=INNODB STATS_PERSISTENT=1,STATS_AUTO_RECALC=1; CREATE TABLE t2 LIKE t1; INSERT INTO t1 (val) SELECT 4 FROM seq_1_to_16; +SET STATEMENT use_stat_tables=never FOR ANALYZE TABLE t1; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK connect con1, localhost, root,,; START TRANSACTION; @@ -91,7 +91,7 @@ COUNT(*) # ha_innobase::records_in_range() would count the delete-marked records. EXPLAIN SELECT * FROM t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL val 4 NULL 16 Using index +1 SIMPLE t1 index NULL val 4 NULL 1 Using index ROLLBACK; EXPLAIN SELECT * FROM t1; id select_type table type possible_keys key key_len ref rows Extra @@ -106,3 +106,25 @@ SET GLOBAL innodb_stats_include_delete_marked = @saved_include_delete_marked; SET GLOBAL innodb_stats_traditional = @saved_traditional; SET GLOBAL innodb_stats_modified_counter = @saved_modified_counter; SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; +CREATE TABLE bug12429573 (i INTEGER PRIMARY KEY, j INTEGER, KEY(j)) +ENGINE=INNODB STATS_PERSISTENT=1; +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE bug12429573; +Table Op Msg_type Msg_text +test.bug12429573 analyze status OK +SELECT last_update INTO @last FROM mysql.innodb_table_stats +WHERE table_name = 'bug12429573'; +SELECT * FROM mysql.innodb_index_stats +WHERE table_name = 'bug12429573' AND last_update!=@last; +database_name table_name index_name last_update stat_name stat_value sample_size stat_description +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE bug12429573; +Table Op Msg_type Msg_text +test.bug12429573 analyze status OK +SELECT * FROM mysql.innodb_table_stats +WHERE table_name = 'bug12429573' AND last_update=@last; +database_name table_name last_update n_rows clustered_index_size sum_of_other_index_sizes +SELECT * FROM mysql.innodb_index_stats +WHERE table_name = 'bug12429573' AND last_update=@last; +database_name table_name index_name last_update stat_name stat_value sample_size stat_description +DROP TABLE bug12429573; diff --git a/mysql-test/suite/innodb/r/innodb_stats_sample_pages.result b/mysql-test/suite/innodb/r/innodb_stats_sample_pages.result new file mode 100644 index 00000000000..a24d9aa8b62 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_stats_sample_pages.result @@ -0,0 +1,29 @@ +SET GLOBAL innodb_stats_persistent_sample_pages=17; +CREATE TABLE test_ps_sample_pages_used ( +a VARCHAR(512), PRIMARY KEY (a) +) ENGINE=INNODB STATS_SAMPLE_PAGES=default; +BEGIN; +COMMIT; +ANALYZE TABLE test_ps_sample_pages_used; +Table Op Msg_type Msg_text +test.test_ps_sample_pages_used analyze status Engine-independent statistics collected +test.test_ps_sample_pages_used analyze status OK +SELECT stat_name, stat_value FROM mysql.innodb_index_stats +WHERE table_name='test_ps_sample_pages_used' AND stat_name='n_leaf_pages'; +stat_name stat_value +n_leaf_pages 37 +SELECT sample_size FROM mysql.innodb_index_stats +WHERE table_name='test_ps_sample_pages_used' AND stat_name='n_diff_pfx01'; +sample_size +17 +ALTER TABLE test_ps_sample_pages_used STATS_SAMPLE_PAGES=14; +ANALYZE TABLE test_ps_sample_pages_used; +Table Op Msg_type Msg_text +test.test_ps_sample_pages_used analyze status Engine-independent statistics collected +test.test_ps_sample_pages_used analyze status OK +SELECT sample_size FROM mysql.innodb_index_stats +WHERE table_name='test_ps_sample_pages_used' AND stat_name='n_diff_pfx01'; +sample_size +14 +DROP TABLE test_ps_sample_pages_used; +SET GLOBAL innodb_stats_persistent_sample_pages=default; diff --git a/mysql-test/suite/innodb/r/innodb_stats_table_flag_auto_recalc.result b/mysql-test/suite/innodb/r/innodb_stats_table_flag_auto_recalc.result new file mode 100644 index 00000000000..5585d3f654e --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_stats_table_flag_auto_recalc.result @@ -0,0 +1,82 @@ +CREATE TABLE test_ps_auto_recalc (a INT, PRIMARY KEY (a)) ENGINE=INNODB; +SHOW CREATE TABLE test_ps_auto_recalc; +Table test_ps_auto_recalc +Create Table CREATE TABLE `test_ps_auto_recalc` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_auto_recalc'; +create_options +ALTER TABLE test_ps_auto_recalc STATS_AUTO_RECALC=1; +# restart +SHOW CREATE TABLE test_ps_auto_recalc; +Table test_ps_auto_recalc +Create Table CREATE TABLE `test_ps_auto_recalc` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci STATS_AUTO_RECALC=1 +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_auto_recalc'; +create_options stats_auto_recalc=1 +DROP TABLE test_ps_auto_recalc; +CREATE TABLE test_ps_auto_recalc (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_AUTO_RECALC=default; +SHOW CREATE TABLE test_ps_auto_recalc; +Table test_ps_auto_recalc +Create Table CREATE TABLE `test_ps_auto_recalc` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_auto_recalc'; +create_options +DROP TABLE test_ps_auto_recalc; +CREATE TABLE test_ps_auto_recalc (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_AUTO_RECALC=0; +# restart +SHOW CREATE TABLE test_ps_auto_recalc; +Table test_ps_auto_recalc +Create Table CREATE TABLE `test_ps_auto_recalc` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci STATS_AUTO_RECALC=0 +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_auto_recalc'; +create_options stats_auto_recalc=0 +ALTER TABLE test_ps_auto_recalc STATS_AUTO_RECALC=1; +# restart +SHOW CREATE TABLE test_ps_auto_recalc; +Table test_ps_auto_recalc +Create Table CREATE TABLE `test_ps_auto_recalc` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci STATS_AUTO_RECALC=1 +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_auto_recalc'; +create_options stats_auto_recalc=1 +DROP TABLE test_ps_auto_recalc; +CREATE TABLE test_ps_auto_recalc (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_AUTO_RECALC=1; +# restart +SHOW CREATE TABLE test_ps_auto_recalc; +Table test_ps_auto_recalc +Create Table CREATE TABLE `test_ps_auto_recalc` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci STATS_AUTO_RECALC=1 +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_auto_recalc'; +create_options stats_auto_recalc=1 +ALTER TABLE test_ps_auto_recalc STATS_AUTO_RECALC=0; +# restart +SHOW CREATE TABLE test_ps_auto_recalc; +Table test_ps_auto_recalc +Create Table CREATE TABLE `test_ps_auto_recalc` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci STATS_AUTO_RECALC=0 +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_auto_recalc'; +create_options stats_auto_recalc=0 +DROP TABLE test_ps_auto_recalc; diff --git a/mysql-test/suite/innodb/r/innodb_stats_table_flag_sample_pages.result b/mysql-test/suite/innodb/r/innodb_stats_table_flag_sample_pages.result new file mode 100644 index 00000000000..b26b0150c8d --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_stats_table_flag_sample_pages.result @@ -0,0 +1,95 @@ +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB; +SHOW CREATE TABLE test_ps_sample_pages; +Table test_ps_sample_pages +Create Table CREATE TABLE `test_ps_sample_pages` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_sample_pages'; +create_options +ALTER TABLE test_ps_sample_pages STATS_SAMPLE_PAGES=12345; +# restart +SHOW CREATE TABLE test_ps_sample_pages; +Table test_ps_sample_pages +Create Table CREATE TABLE `test_ps_sample_pages` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci STATS_SAMPLE_PAGES=12345 +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_sample_pages'; +create_options stats_sample_pages=12345 +DROP TABLE test_ps_sample_pages; +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=default; +SHOW CREATE TABLE test_ps_sample_pages; +Table test_ps_sample_pages +Create Table CREATE TABLE `test_ps_sample_pages` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_sample_pages'; +create_options +DROP TABLE test_ps_sample_pages; +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=-5; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '-5' at line 2 +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=0; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '0' at line 2 +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=67000; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '67000' at line 2 +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=670000; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '670000' at line 2 +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=65536; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '65536' at line 2 +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=65535; +SHOW CREATE TABLE test_ps_sample_pages; +Table test_ps_sample_pages +Create Table CREATE TABLE `test_ps_sample_pages` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci STATS_SAMPLE_PAGES=65535 +DROP TABLE test_ps_sample_pages; +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=1; +# restart +SHOW CREATE TABLE test_ps_sample_pages; +Table test_ps_sample_pages +Create Table CREATE TABLE `test_ps_sample_pages` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci STATS_SAMPLE_PAGES=1 +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_sample_pages'; +create_options stats_sample_pages=1 +DROP TABLE test_ps_sample_pages; +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=5678; +# restart +SHOW CREATE TABLE test_ps_sample_pages; +Table test_ps_sample_pages +Create Table CREATE TABLE `test_ps_sample_pages` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci STATS_SAMPLE_PAGES=5678 +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_sample_pages'; +create_options stats_sample_pages=5678 +ALTER TABLE test_ps_sample_pages STATS_SAMPLE_PAGES=default; +# restart +SHOW CREATE TABLE test_ps_sample_pages; +Table test_ps_sample_pages +Create Table CREATE TABLE `test_ps_sample_pages` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_sample_pages'; +create_options +DROP TABLE test_ps_sample_pages; diff --git a/mysql-test/suite/innodb/r/innodb_ut_format_name.result b/mysql-test/suite/innodb/r/innodb_ut_format_name.result new file mode 100644 index 00000000000..41a5b0f7149 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_ut_format_name.result @@ -0,0 +1,5 @@ +CREATE TABLE t (c INT) ENGINE=INNODB; +SET @save_dbug = @@debug_dbug; +SET debug_dbug = '+d,test_ut_format_name'; +DROP TABLE t; +SET debug_dbug = @save_dbug; diff --git a/mysql-test/suite/innodb/r/records_in_range,4k.rdiff b/mysql-test/suite/innodb/r/records_in_range,4k.rdiff new file mode 100644 index 00000000000..12b857ece22 --- /dev/null +++ b/mysql-test/suite/innodb/r/records_in_range,4k.rdiff @@ -0,0 +1,8 @@ +@@ -39,7 +39,7 @@ + WHERE + table_name='records_in_range_test' AND stat_name = 'size'; + index_name stat_name stat_value +-PRIMARY size 1 ++PRIMARY size 5 + SET @save_dbug = @@debug_dbug; + SET DEBUG_DBUG='+d,print_btr_estimate_n_rows_in_range_return_value'; diff --git a/mysql-test/suite/innodb/r/records_in_range,8k.rdiff b/mysql-test/suite/innodb/r/records_in_range,8k.rdiff new file mode 100644 index 00000000000..bd24af160ba --- /dev/null +++ b/mysql-test/suite/innodb/r/records_in_range,8k.rdiff @@ -0,0 +1,8 @@ +@@ -39,7 +39,7 @@ + WHERE + table_name='records_in_range_test' AND stat_name = 'size'; + index_name stat_name stat_value +-PRIMARY size 1 ++PRIMARY size 3 + SET @save_dbug = @@debug_dbug; + SET DEBUG_DBUG='+d,print_btr_estimate_n_rows_in_range_return_value'; diff --git a/mysql-test/suite/innodb/r/records_in_range.result b/mysql-test/suite/innodb/r/records_in_range.result new file mode 100644 index 00000000000..e5a698f59cc --- /dev/null +++ b/mysql-test/suite/innodb/r/records_in_range.result @@ -0,0 +1,1275 @@ +CREATE TABLE records_in_range_test ( +c1 VARCHAR(16), +c2 VARCHAR(512), +PRIMARY KEY (c1) +) ENGINE=INNODB STATS_PERSISTENT=1; +INSERT INTO records_in_range_test VALUES +('ccc', REPEAT('v', 512)), +('kkk01', REPEAT('v', 512)), +('kkk02', REPEAT('v', 512)), +('kkk03', REPEAT('v', 512)), +('kkk04', REPEAT('v', 512)), +('kkk05', REPEAT('v', 512)), +('kkk06', REPEAT('v', 512)), +('kkk07', REPEAT('v', 512)), +('kkk08', REPEAT('v', 512)), +('mmm', REPEAT('v', 512)), +('nnn', REPEAT('v', 512)), +('uuu01', REPEAT('v', 512)), +('uuu02', REPEAT('v', 512)), +('uuu03', REPEAT('v', 512)), +('uuu04', REPEAT('v', 512)), +('uuu05', REPEAT('v', 512)), +('uuu06', REPEAT('v', 512)), +('uuu07', REPEAT('v', 512)), +('uuu08', REPEAT('v', 512)), +('xxx', REPEAT('v', 512)); +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE records_in_range_test; +Table Op Msg_type Msg_text +test.records_in_range_test analyze status OK +SELECT index_name, stat_name, stat_value +FROM mysql.innodb_index_stats +WHERE +table_name='records_in_range_test' AND stat_name = 'n_leaf_pages'; +index_name stat_name stat_value +PRIMARY n_leaf_pages 1 +SELECT index_name, stat_name, stat_value +FROM mysql.innodb_index_stats +WHERE +table_name='records_in_range_test' AND stat_name = 'size'; +index_name stat_name stat_value +PRIMARY size 1 +SET @save_dbug = @@debug_dbug; +SET DEBUG_DBUG='+d,print_btr_estimate_n_rows_in_range_return_value'; + +In all SELECTs below the number of the records in the range returned +by COUNT(*) must be the same as the number returned by +btr_estimate_n_rows_in_range() which can be seen inside the artificial +warning + +Test left-unbounded, right-open intervals + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'aaa'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'ccc'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'eee'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'mmm'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'nnn'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'qqq'; +COUNT(*) +11 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 11 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'xxx'; +COUNT(*) +19 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 19 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'zzz'; +COUNT(*) +20 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 20 + +Test left-unbounded, right-closed intervals + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'aaa'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'ccc'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'eee'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'mmm'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'nnn'; +COUNT(*) +11 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 11 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'qqq'; +COUNT(*) +11 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 11 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'xxx'; +COUNT(*) +20 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 20 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'zzz'; +COUNT(*) +20 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 20 + +Test left-open, right-unbounded intervals + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa'; +COUNT(*) +20 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 20 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc'; +COUNT(*) +19 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 19 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee'; +COUNT(*) +19 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 19 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 + +Test left-closed, right-unbounded intervals + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa'; +COUNT(*) +20 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 20 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc'; +COUNT(*) +20 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 20 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee'; +COUNT(*) +19 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 19 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm'; +COUNT(*) +11 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 11 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 + +Test left-open, right-open intervals +In some cases here the optimizer is smart enough not to call +ha_innobase::records_in_range() at all, so we get no warning containing +the value returned from btr_estimate_n_rows_in_range() + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'bbb'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'ccc'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'eee'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'mmm'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'nnn'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'qqq'; +COUNT(*) +11 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 11 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'xxx'; +COUNT(*) +19 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 19 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'zzz'; +COUNT(*) +20 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 20 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'eee'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'mmm'; +COUNT(*) +8 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 8 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'nnn'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'qqq'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'xxx'; +COUNT(*) +18 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 18 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'zzz'; +COUNT(*) +19 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 19 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'mmm'; +COUNT(*) +8 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 8 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'nnn'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'qqq'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'xxx'; +COUNT(*) +18 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 18 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'zzz'; +COUNT(*) +19 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 19 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'nnn'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'qqq'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'xxx'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'zzz'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'nnn'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'qqq'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'xxx'; +COUNT(*) +8 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 8 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'zzz'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'nnn'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'qqq'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'xxx'; +COUNT(*) +8 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 8 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'zzz'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'nnn'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'qqq'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'xxx'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'zzz'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'nnn'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'qqq'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'xxx'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'zzz'; +COUNT(*) +0 + +Test left-closed, right-open intervals +In some cases here the optimizer is smart enough not to call +ha_innobase::records_in_range() at all, so we get no warning containing +the value returned from btr_estimate_n_rows_in_range() + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'bbb'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'ccc'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'eee'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'mmm'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'nnn'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'qqq'; +COUNT(*) +11 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 11 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'xxx'; +COUNT(*) +19 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 19 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'zzz'; +COUNT(*) +20 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 20 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'eee'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'mmm'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'nnn'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'qqq'; +COUNT(*) +11 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 11 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'xxx'; +COUNT(*) +19 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 19 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'zzz'; +COUNT(*) +20 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 20 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'mmm'; +COUNT(*) +8 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 8 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'nnn'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'qqq'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'xxx'; +COUNT(*) +18 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 18 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'zzz'; +COUNT(*) +19 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 19 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'nnn'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'qqq'; +COUNT(*) +2 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 2 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'xxx'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'zzz'; +COUNT(*) +11 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 11 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'nnn'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'qqq'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'xxx'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'zzz'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'nnn'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'qqq'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'xxx'; +COUNT(*) +8 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 8 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'zzz'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'nnn'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'qqq'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'xxx'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'zzz'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'nnn'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'qqq'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'xxx'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'zzz'; +COUNT(*) +0 + +Test left-open, right-closed intervals +In some cases here the optimizer is smart enough not to call +ha_innobase::records_in_range() at all, so we get no warning containing +the value returned from btr_estimate_n_rows_in_range() + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'bbb'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'ccc'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'eee'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'mmm'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'nnn'; +COUNT(*) +11 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 11 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'qqq'; +COUNT(*) +11 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 11 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'xxx'; +COUNT(*) +20 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 20 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'zzz'; +COUNT(*) +20 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 20 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'eee'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'mmm'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'nnn'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'qqq'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'xxx'; +COUNT(*) +19 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 19 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'zzz'; +COUNT(*) +19 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 19 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'mmm'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'nnn'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'qqq'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'xxx'; +COUNT(*) +19 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 19 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'zzz'; +COUNT(*) +19 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 19 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'nnn'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'qqq'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'xxx'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'zzz'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'nnn'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'qqq'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'xxx'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'zzz'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'nnn'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'qqq'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'xxx'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'zzz'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'nnn'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'qqq'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'xxx'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'zzz'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'nnn'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'qqq'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'xxx'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'zzz'; +COUNT(*) +0 + +Test left-closed, right-closed intervals +In some cases here the optimizer is smart enough not to call +ha_innobase::records_in_range() at all, so we get no warning containing +the value returned from btr_estimate_n_rows_in_range() + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'bbb'; +COUNT(*) +0 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'ccc'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'eee'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'mmm'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'nnn'; +COUNT(*) +11 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 11 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'qqq'; +COUNT(*) +11 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 11 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'xxx'; +COUNT(*) +20 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 20 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'zzz'; +COUNT(*) +20 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 20 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'ccc'; +COUNT(*) +1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'eee'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'mmm'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'nnn'; +COUNT(*) +11 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 11 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'qqq'; +COUNT(*) +11 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 11 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'xxx'; +COUNT(*) +20 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 20 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'zzz'; +COUNT(*) +20 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 20 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'mmm'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'nnn'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'qqq'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'xxx'; +COUNT(*) +19 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 19 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'zzz'; +COUNT(*) +19 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 19 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'mmm'; +COUNT(*) +1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'nnn'; +COUNT(*) +2 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 2 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'qqq'; +COUNT(*) +2 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 2 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'xxx'; +COUNT(*) +11 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 11 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'zzz'; +COUNT(*) +11 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 11 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'nnn'; +COUNT(*) +1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'qqq'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'xxx'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'zzz'; +COUNT(*) +10 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 10 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'nnn'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'qqq'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'xxx'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'zzz'; +COUNT(*) +9 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 9 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'nnn'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'qqq'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'xxx'; +COUNT(*) +1 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'zzz'; +COUNT(*) +1 +Warnings: +Warning 1230 btr_estimate_n_rows_in_range(): 1 + +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'bbb'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'ccc'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'eee'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'mmm'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'nnn'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'qqq'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'xxx'; +COUNT(*) +0 +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'zzz'; +COUNT(*) +0 +SET DEBUG_DBUG = @save_dbug; +DROP TABLE records_in_range_test; diff --git a/mysql-test/suite/innodb/r/tablespace_per_table_not_windows.result b/mysql-test/suite/innodb/r/tablespace_per_table_not_windows.result new file mode 100644 index 00000000000..580269182ec --- /dev/null +++ b/mysql-test/suite/innodb/r/tablespace_per_table_not_windows.result @@ -0,0 +1,134 @@ +# +# Test the limits of a file-per-table tablespace name. MySQL combines +# the database name with the table name to make a unique table name. +# +SET default_storage_engine=InnoDB; +# +# MySQL limits each database and tablename identifier to 64 characters +# of up to 3 bytes per character, corresponding to 192 bytes. +# +CREATE DATABASE `this_sixty_five_byte_name_is_too_long____________________________`; +ERROR 42000: Incorrect database name 'this_sixty_five_byte_name_is_too_long____________________________' +CREATE DATABASE `this_sixty_four_byte_name_is_not_too_long_______________________`; +USE `this_sixty_four_byte_name_is_not_too_long_______________________`; +# +# A 64 character tablename can be created in a 64 character database name +# +CREATE TABLE `this_sixty_four_byte_name_is_not_too_long_______________________`.`this_sixty_four_byte_name_is_not_too_long_______________________` (a SERIAL); +# +# A 65 character tablename is too long. +# +CREATE TABLE `test`.`this_sixty_five_byte_name_is_too_long____________________________` (a SERIAL); +ERROR 42000: Incorrect table name 'this_sixty_five_byte_name_is_too_long____________________________' +CREATE TABLE `this_sixty_four_byte_name_is_not_too_long_______________________`.`this_sixty_five_byte_name_is_too_long____________________________` (a SERIAL); +ERROR 42000: Incorrect table name 'this_sixty_five_byte_name_is_too_long____________________________' +# +# Non-non-filename-safe characters like '#' are expanded to '@0023'. +# On many file systems, such as Linux extfs, you can create a database name +# that expands to up to 255 bytes long. +# `##################################################_long` is expanded to +# (50 * 5) + 5 = 255. +# +CREATE DATABASE `##################################################_long`;; +USE `##################################################_long`; +# +# This 256-byte name is only one byte longer but fails with an error code +# from the stat operation. +# `##################################################_long_` is expanded to +# (50 * 5) + 6 = 256. +# +CREATE DATABASE `##################################################_long_`; +ERROR HY000: Can't get stat of './##################################################_long_' (Errcode: ## "File name too long") +# +# This 300-byte name which is the longest name that gets an error code +# from the stat operation. +# `###########################################################_long` is expanded to +# (59 * 5) + 5 = 300. +# +CREATE DATABASE `###########################################################_long`; +ERROR HY000: Can't get stat of './###########################################################_long' (Errcode: ## "File name too long") +# +# This 301-byte name which is only one byte longer but fails with ER_TOO_LONG_IDENT. +# `###########################################################_long_` is expanded to +# (59 * 5) + 6 = 301. +# +CREATE DATABASE `###########################################################_long_`; +ERROR 42000: Incorrect database name '###########################################################_long_' +USE test; +# +# An expanded table name is limited to 251 bytes +# +CREATE TABLE `test`.`#################################################_long_` (a SERIAL); +# +# A 252-byte tablename is too long +# +CREATE TABLE `test`.`#################################################_long___` (a SERIAL); +ERROR HY000: Can't create table `test`.`#################################################_long___` (errno: ## "File name too long") +CREATE DATABASE twenty_byte_db_name_; +USE `twenty_byte_db_name_`; +# +# A 251 byte expanded table name will fit with a longer database name +# +CREATE TABLE `twenty_byte_db_name_`.`#################################################_long_` (a SERIAL); +# +# A 252 byte expanded table name is also too long in a longer database name +# +CREATE TABLE `twenty_byte_db_name_`.`#################################################_long___` (a SERIAL); +ERROR HY000: Can't create table `twenty_byte_db_name_`.`#################################################_long___` (errno: ## "File name too long") +# +# Another limitation is a 512 byte length to an expanded path that includes +# the datadir which is './' in this test, the expanded database name, +# the directory separator '/', the expanded table name, and the file extension. +# './long_db_name.long_250_byte_table_name.frm' +# 2+ 255 +1+ 250 +1+3 = 512 +# +CREATE TABLE `##################################################_long`.`#################################################_long` (a SERIAL); +CREATE TABLE `##################################################_long`.`#################################################_long_` (a SERIAL); +ERROR HY000: Long database name and identifier for object resulted in path length exceeding 512 characters. Path: './@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023_long/@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@ +SHOW WARNINGS; +Level Code Message +Error 1860 Long database name and identifier for object resulted in path length exceeding 512 characters. Path: './@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023_long/@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@ +# +# Show the successfully created databases and tables +# +---- list_files MYSQLD_DATADIR/test +#################################################_long_.frm +#################################################_long_.ibd +db.opt +---- list_files MYSQLD_DATADIR/this_sixty_four_byte_name_is_not_too_long_______________________ +db.opt +this_sixty_four_byte_name_is_not_too_long_______________________.frm +this_sixty_four_byte_name_is_not_too_long_______________________.ibd +---- list_files MYSQLD_DATADIR/##################################################_long +#################################################_long.frm +#################################################_long.ibd +db.opt +SELECT name FROM information_schema.innodb_sys_tables WHERE name LIKE '%long%'; +name +##################################################_long/#################################################_long +test/#################################################_long_ +this_sixty_four_byte_name_is_not_too_long_______________________/this_sixty_four_byte_name_is_not_too_long_______________________ +twenty_byte_db_name_/#################################################_long_ +SELECT name FROM information_schema.innodb_sys_tablespaces WHERE name LIKE '%long%'; +name +this_sixty_four_byte_name_is_not_too_long_______________________/this_sixty_four_byte_name_is_not_too_long_______________________ +test/#################################################_long_ +twenty_byte_db_name_/#################################################_long_ +##################################################_long/#################################################_long +SELECT path FROM information_schema.innodb_sys_datafiles WHERE path LIKE '%long%'; +path +./this_sixty_four_byte_name_is_not_too_long_______________________/this_sixty_four_byte_name_is_not_too_long_______________________.ibd +./test/#################################################_long_.ibd +./twenty_byte_db_name_/#################################################_long_.ibd +./##################################################_long/#################################################_long.ibd +SELECT file_name, tablespace_name FROM information_schema.files WHERE file_name LIKE '%long%'; +# +# Cleanup +# +DROP TABLE `this_sixty_four_byte_name_is_not_too_long_______________________`.`this_sixty_four_byte_name_is_not_too_long_______________________`; +DROP TABLE `test`.`#################################################_long_`; +DROP TABLE `twenty_byte_db_name_`.`#################################################_long_`; +DROP TABLE `##################################################_long`.`#################################################_long`; +DROP DATABASE `this_sixty_four_byte_name_is_not_too_long_______________________`; +DROP DATABASE `##################################################_long`; +DROP DATABASE `twenty_byte_db_name_`; diff --git a/mysql-test/suite/innodb/r/tablespace_per_table_windows.result b/mysql-test/suite/innodb/r/tablespace_per_table_windows.result new file mode 100644 index 00000000000..9d46557056b --- /dev/null +++ b/mysql-test/suite/innodb/r/tablespace_per_table_windows.result @@ -0,0 +1,51 @@ +# +# Test the limits of a file-per-table tablespace name. MySQL combines +# the database name with the table name to make a unique table name. +# +SET default_storage_engine=InnoDB; +# +# MySQL limits each database and tablename identifier to 64 characters +# of up to 3 bytes per character, corresponding to 192 bytes. +# +CREATE DATABASE `this_sixty_five_byte_name_is_too_long____________________________`; +ERROR 42000: Incorrect database name 'this_sixty_five_byte_name_is_too_long____________________________' +CREATE DATABASE `this_sixty_four_byte_name_is_not_too_long_______________________`; +USE `this_sixty_four_byte_name_is_not_too_long_______________________`; +# +# A 64 character tablename can be created in a 64 character database name +# +CREATE TABLE `this_sixty_four_byte_name_is_not_too_long_______________________`.`this_sixty_four_byte_name_is_not_too_long_______________________` (a SERIAL); +# +# A 65 character tablename is too long. +# +CREATE TABLE `test`.`this_sixty_five_byte_name_is_too_long____________________________` (a SERIAL); +ERROR 42000: Incorrect table name 'this_sixty_five_byte_name_is_too_long____________________________' +CREATE TABLE `this_sixty_four_byte_name_is_not_too_long_______________________`.`this_sixty_five_byte_name_is_too_long____________________________` (a SERIAL); +ERROR 42000: Incorrect table name 'this_sixty_five_byte_name_is_too_long____________________________' +# +# Show the successfully created database and table +# +SHOW CREATE TABLE `this_sixty_four_byte_name_is_not_too_long_______________________`.`this_sixty_four_byte_name_is_not_too_long_______________________`; +Table Create Table +this_sixty_four_byte_name_is_not_too_long_______________________ CREATE TABLE `this_sixty_four_byte_name_is_not_too_long_______________________` ( + `a` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + UNIQUE KEY `a` (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +---- list_files MYSQLD_DATADIR/this_sixty_four_byte_name_is_not_too_long_______________________ +db.opt +this_sixty_four_byte_name_is_not_too_long_______________________.frm +this_sixty_four_byte_name_is_not_too_long_______________________.ibd +SELECT name FROM information_schema.innodb_sys_tables WHERE name LIKE '%long%'; +name +this_sixty_four_byte_name_is_not_too_long_______________________/this_sixty_four_byte_name_is_not_too_long_______________________ +SELECT name FROM information_schema.innodb_sys_tablespaces WHERE name LIKE '%long%'; +name +this_sixty_four_byte_name_is_not_too_long_______________________/this_sixty_four_byte_name_is_not_too_long_______________________ +SELECT path FROM information_schema.innodb_sys_datafiles WHERE path LIKE '%long%'; +path +.\this_sixty_four_byte_name_is_not_too_long_______________________\this_sixty_four_byte_name_is_not_too_long_______________________.ibd +SELECT file_name, tablespace_name FROM information_schema.files WHERE file_name LIKE '%long%'; +# +# Cleanup +# +DROP DATABASE `this_sixty_four_byte_name_is_not_too_long_______________________`; diff --git a/mysql-test/suite/innodb/t/add_foreign_key.test b/mysql-test/suite/innodb/t/add_foreign_key.test new file mode 100644 index 00000000000..d0febfd62f0 --- /dev/null +++ b/mysql-test/suite/innodb/t/add_foreign_key.test @@ -0,0 +1,38 @@ +--source include/have_innodb.inc + +--echo # +--echo # Bug #19471516 SERVER CRASHES WHEN EXECUTING ALTER TABLE ADD +--echo # FOREIGN KEY +--echo # + +CREATE TABLE `parent` (`parent_id` INT, PRIMARY KEY (`parent_id`)); +CREATE TABLE `child1` (`id` INT ,`child1_fk1` INT, `child1_fk2` INT, +PRIMARY KEY (`id`)); +CREATE TABLE `child2` (`id` INT, `child2_fk1` INT, `child2_fk2` INT, +PRIMARY KEY (`id`)); +CREATE TABLE `child3` (`id` INT , `child3_fk1` INT, PRIMARY KEY (`id`)); +ALTER TABLE `child1` ADD FOREIGN KEY (`child1_fk1`) REFERENCES `parent` +(`parent_id`); +ALTER TABLE `child1` ADD FOREIGN KEY (`child1_fk1`) REFERENCES +`parent` (`parent_id`); +ALTER TABLE `child1` ADD FOREIGN KEY (`child1_fk2`) REFERENCES `parent` +(`parent_id`); + +ALTER TABLE `child2` ADD FOREIGN KEY (`child2_fk1`) REFERENCES `parent` +(`parent_id`); + +ALTER TABLE `child2` ADD FOREIGN KEY (`child2_fk2`) REFERENCES `parent` +(`parent_id`); + +ALTER TABLE `child3` ADD FOREIGN KEY (`child3_fk1`) REFERENCES `parent` +(`parent_id`); +ALTER TABLE `child1` ADD FOREIGN KEY (`child1_fk2`) REFERENCES +`parent` (`parent_id`); +ALTER TABLE `child2` ADD FOREIGN KEY (`child2_fk1`) REFERENCES +`parent` (`parent_id`); +ALTER TABLE `child2` ADD FOREIGN KEY (`child2_fk2`) REFERENCES +`parent` (`parent_id`); +ALTER TABLE `child3` ADD FOREIGN KEY (`child3_fk1`) REFERENCES +`parent` (`parent_id`); + +drop table child3, child2, child1, parent; diff --git a/mysql-test/suite/innodb/t/cascade_lock_wait.test b/mysql-test/suite/innodb/t/cascade_lock_wait.test new file mode 100644 index 00000000000..4489c9aefac --- /dev/null +++ b/mysql-test/suite/innodb/t/cascade_lock_wait.test @@ -0,0 +1,45 @@ +--source include/have_innodb.inc +--source include/have_debug.inc + +create table t1 (f1 int primary key) engine=innodb; +create table t2 (f1 int primary key, + constraint c1 foreign key (f1) references t1(f1) + on update cascade + on delete cascade) engine=innodb; +create table t3 (f1 int primary key, + constraint c2 foreign key (f1) references t1(f1) + on update cascade + on delete cascade) engine=innodb; +show create table t1; +show create table t2; +show create table t3; + +insert into t1 values (1); +insert into t1 values (2); +insert into t1 values (3); + +insert into t2 values (1); +insert into t2 values (2); +insert into t2 values (3); + +insert into t3 values (1); +insert into t3 values (2); +insert into t3 values (3); + +select f1 from t1; +select f1 from t2; +select f1 from t3; + +set @save_dbug = @@debug_dbug; +set debug_dbug = '+d,dml_cascade_only_once'; +set debug_dbug = '+d,row_upd_cascade_lock_wait_err'; +update t1 set f1 = 100 where f1 = 2; + +select f1 from t1; +select f1 from t2; +select f1 from t3; + +set debug_dbug = @save_dbug; +drop table t2; +drop table t3; +drop table t1; diff --git a/mysql-test/suite/innodb/t/import_update_stats.test b/mysql-test/suite/innodb/t/import_update_stats.test new file mode 100644 index 00000000000..128213c77b2 --- /dev/null +++ b/mysql-test/suite/innodb/t/import_update_stats.test @@ -0,0 +1,81 @@ +# +# BUG#20125349 - PERSISTANT STATS IS NOT UPDATED WHEN TTS IS IMPORTED. +# + +--source include/not_embedded.inc +--source include/have_innodb.inc +--source include/not_valgrind.inc # MDEV-32725 FIXME + +let MYSQLD_DATADIR =`SELECT @@datadir`; +SET @old_innodb_file_per_table = @@innodb_file_per_table; + +SET GLOBAL innodb_file_per_table = 1; +SELECT @@innodb_file_per_table; + +CREATE TABLE t1 ( + col_1 CHAR (255), + col_2 VARCHAR (255) +) ENGINE = InnoDB; + +CREATE INDEX idx1 ON t1(col_1); +CREATE INDEX idx2 ON t1(col_2); + +SHOW INDEXES FROM t1; + +INSERT INTO t1 VALUES ("col1_00001", "col2_00001"), ("col1_00002", "col2_00002"); + +SHOW INDEXES FROM t1; + +ANALYZE TABLE t1; +SHOW INDEXES FROM t1; + +FLUSH TABLES t1 FOR EXPORT; +perl; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; +ib_backup_tablespaces("test", "t1"); +EOF + +UNLOCK TABLES; + +DROP TABLE t1; + +CREATE TABLE t1 ( + col_1 CHAR (255), + col_2 VARCHAR (255) +) ENGINE = InnoDB STATS_PERSISTENT=1; + +CREATE INDEX idx1 ON t1(col_1); +CREATE INDEX idx2 ON t1(col_2); + +SHOW INDEXES FROM t1; + +INSERT INTO t1 VALUES ("col1_00001", "col2_00001"); + +SHOW INDEXES FROM t1; + +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE t1; +SHOW INDEXES FROM t1; + +ALTER TABLE t1 DISCARD TABLESPACE; + +perl; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF + +ALTER TABLE t1 IMPORT TABLESPACE; + +SHOW INDEXES FROM t1; + +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE t1; +SHOW INDEXES FROM t1; + +DROP TABLE t1; + +SET GLOBAL innodb_file_per_table = @old_innodb_file_per_table; + +--remove_files_wildcard $MYSQLTEST_VARDIR/tmp t1*.ibd +--remove_files_wildcard $MYSQLTEST_VARDIR/tmp t1*.cfg diff --git a/mysql-test/suite/innodb/t/index_length.test b/mysql-test/suite/innodb/t/index_length.test new file mode 100644 index 00000000000..bf4940d4b39 --- /dev/null +++ b/mysql-test/suite/innodb/t/index_length.test @@ -0,0 +1,23 @@ +--source include/have_innodb.inc + +--connect (stop_purge,localhost,root) +# Prevent the purge of history from acquiring a table handle. +START TRANSACTION WITH CONSISTENT SNAPSHOT; +--connection default + +CREATE TABLE t1(a INT PRIMARY KEY, b VARCHAR(1024)) +ENGINE=InnoDB STATS_PERSISTENT=1; +INSERT INTO t1 VALUES (1,REPEAT('b',1024)); + +SELECT index_length FROM information_schema.tables +WHERE table_schema = 'test' AND table_name = 't1'; +ALTER TABLE t1 ADD INDEX b (b(800)); +SELECT FLOOR(index_length/@@innodb_page_size) FROM information_schema.tables +WHERE table_schema = 'test' AND table_name = 't1'; +ALTER TABLE t1 ADD INDEX ba (b(800),a); +SELECT FLOOR(index_length/@@innodb_page_size) FROM information_schema.tables +WHERE table_schema = 'test' AND table_name = 't1'; +disconnect stop_purge; +DROP TABLE t1; + +--echo # End of 10.4 tests diff --git a/mysql-test/suite/innodb/t/innodb-32k.test b/mysql-test/suite/innodb/t/innodb-32k.test index a9645d65998..7cf28ed79c6 100644 --- a/mysql-test/suite/innodb/t/innodb-32k.test +++ b/mysql-test/suite/innodb/t/innodb-32k.test @@ -7,6 +7,19 @@ call mtr.add_suppression("Innodb: Cannot add field.*row size is"); let $MYSQLD_DATADIR= `select @@datadir`; +SET SESSION innodb_strict_mode=ON; +--error ER_CANT_CREATE_TABLE +CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +--error ER_CANT_CREATE_TABLE +CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB KEY_BLOCK_SIZE=4; +SET SESSION innodb_strict_mode=OFF; +CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +SHOW WARNINGS; +DROP TABLE t1; +CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB KEY_BLOCK_SIZE=4; +SHOW WARNINGS; +DROP TABLE t1; + --echo # Test 1) Show the page size from Information Schema SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_page_size'; diff --git a/mysql-test/suite/innodb/t/innodb-64k.test b/mysql-test/suite/innodb/t/innodb-64k.test index 972ba6bb8b8..d89370ff538 100644 --- a/mysql-test/suite/innodb/t/innodb-64k.test +++ b/mysql-test/suite/innodb/t/innodb-64k.test @@ -8,6 +8,19 @@ call mtr.add_suppression('InnoDB: Cannot add field.*because after adding it, the let $MYSQLD_DATADIR= `select @@datadir`; +SET SESSION innodb_strict_mode=ON; +--error ER_CANT_CREATE_TABLE +CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +--error ER_CANT_CREATE_TABLE +CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB KEY_BLOCK_SIZE=4; +SET SESSION innodb_strict_mode=OFF; +CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +SHOW WARNINGS; +DROP TABLE t1; +CREATE TABLE t1(a int PRIMARY KEY) ENGINE=InnoDB KEY_BLOCK_SIZE=4; +SHOW WARNINGS; +DROP TABLE t1; + --echo # Test 1) Show the page size from Information Schema SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_page_size'; diff --git a/mysql-test/suite/innodb/t/innodb-ac-non-locking-select.test b/mysql-test/suite/innodb/t/innodb-ac-non-locking-select.test new file mode 100644 index 00000000000..9ecddacba52 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-ac-non-locking-select.test @@ -0,0 +1,117 @@ +# DEBUG_SYNC must be compiled in. +--source include/have_debug_sync.inc +--source include/have_debug.inc +--source include/have_innodb.inc + +CREATE TABLE t1 (c1 INT , c2 CHAR(10), PRIMARY KEY (c1)) ENGINE = InnoDB; +INSERT INTO t1 VALUES(0, "0"); +INSERT INTO t1 VALUES(1, "1"); +INSERT INTO t1 VALUES(2, "2"); +INSERT INTO t1 VALUES(3, "3"); + +--connect (con1,localhost,root,,) +--connect (con2,localhost,root,,) +--connect (con3,localhost,root,,) +--connect (con4,localhost,root,,) +--connect (con5,localhost,root,,) +--connect (con6,localhost,root,,) + +connection default; +# Disable query log to avoid non-deterministic output conflicts +SET AUTOCOMMIT=0; +BEGIN; +# Lock all the records +SELECT * FROM t1 FOR UPDATE; +--disable_query_log + +connection con1; +SET AUTOCOMMIT=1; +# Test if locking autocommit selects end up in the trx_sys_t::trx_list. +# We check this via the INFORMATION_SCHEMA.INNODB_TRX. +# This should block and show up in the I_S. +SET DEBUG_SYNC='lock_wait_suspend_thread_enter SIGNAL waiting1'; +--send +SELECT COUNT(*) FROM t1 LOCK IN SHARE MODE; + +connection con2; +SET AUTOCOMMIT=1; +# Test if non-locking autocommit selects end up in the trx_sys_t::trx_list. +# We check this via the INFORMATION_SCHEMA.INNODB_TRX. +# This should not block and should not show up in the I_S. +--send +SELECT COUNT(*) FROM t1; + +connection con3; +SET AUTOCOMMIT=1; +# Note: autocommit non-locking selects are not converted to locking selects +# Therefore this should not block; +SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; +--send +SELECT COUNT(*) FROM t1; + +connection con4; +SET AUTOCOMMIT=0; +# Note: Non-locking selects are converted to locking selects +# therefore this should block; +SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; +SET DEBUG_SYNC='now WAIT_FOR waiting1'; +SET DEBUG_SYNC='lock_wait_suspend_thread_enter SIGNAL waiting4'; +--send +SELECT COUNT(*) FROM t1 WHERE c1 >= 0; + +connection con5; +SET AUTOCOMMIT=1; +# This should not block +BEGIN; +--send +SELECT COUNT(*) FROM t1; + +connection con6; +SET AUTOCOMMIT=1; +# This will ignore the auto-commit setting but wont block because it is +# a non-locking select. +XA START '1'; +--enable_query_log +SELECT * FROM t1 WHERE c1 <= 3; + +connection default; +# Wait for SELECTs to get into the lock wait queue +SET DEBUG_SYNC='now WAIT_FOR waiting4'; +SET DEBUG_SYNC= 'RESET'; + +# Check the number of non-locking transactions +let $wait_condition = + SELECT COUNT(*) = 5 + FROM INFORMATION_SCHEMA.INNODB_TRX + WHERE trx_autocommit_non_locking = 0; +--source include/wait_condition.inc + +# Check the waiting transactions +SELECT trx_state, trx_query, trx_autocommit_non_locking +FROM INFORMATION_SCHEMA.INNODB_TRX +WHERE trx_state = 'LOCK WAIT' +ORDER BY trx_query; + +INSERT INTO t1 VALUES(4, '4'); +COMMIT; + +connection con6; +SELECT * FROM t1 WHERE c1 <= 4; +XA END '1'; +XA PREPARE '1'; +XA ROLLBACK '1'; +disconnect con6; +disconnect con2; +disconnect con3; +disconnect con5; + +connection con1; +reap; +disconnect con1; + +connection con4; +reap; +disconnect con4; + +connection default; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/innodb-alter.test b/mysql-test/suite/innodb/t/innodb-alter.test index 0bedbdc7bbb..60ce7d4f707 100644 --- a/mysql-test/suite/innodb/t/innodb-alter.test +++ b/mysql-test/suite/innodb/t/innodb-alter.test @@ -690,6 +690,32 @@ ALTER TABLE t1 ADD COLUMN b DATETIME NOT NULL, LOCK=NONE; SET @@SQL_MODE= @OLD_SQL_MODE; DROP TABLE t1; +--echo # +--echo # Bug#20977779 CANNOT IMPORT TABLES CONTAINING PREFIX INDEXES +--echo # + +CREATE TABLE t1 (c1 VARCHAR(32), c2 VARCHAR(32), c3 VARCHAR(32), +PRIMARY KEY (c1, c2, c3)) +ENGINE=InnoDB; + +ALTER TABLE t1 ADD INDEX ind1(c1(5), c2, c3); +ALTER TABLE t1 ADD INDEX ind2(c3, c1(10), c2); +ALTER TABLE t1 ADD INDEX ind3(c2, c3, c1(20)); + +INSERT INTO t1 VALUES ('Test Data -1', 'Test Data -2', 'Test Data -3'); + +let $source_db = test; +let $dest_db = test; + +--echo # Test with 2ndary index having prefix +--source suite/innodb/include/import.inc + +--echo # Test with PK & 2ndary index with prefix +ALTER TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY(c1(5), c2(10), c3(20)); +--source suite/innodb/include/import.inc + +DROP TABLE t1; + # # End of 10.2 tests # diff --git a/mysql-test/suite/innodb/t/innodb-index-online-fk.test b/mysql-test/suite/innodb/t/innodb-index-online-fk.test index 5c8954064ce..12a6eea49c2 100644 --- a/mysql-test/suite/innodb/t/innodb-index-online-fk.test +++ b/mysql-test/suite/innodb/t/innodb-index-online-fk.test @@ -482,3 +482,32 @@ SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS; DROP TABLE t2; DROP TABLE t3; + +--echo # Bug #17449901 TABLE DISAPPEARS WHEN ALTERING +--echo # WITH FOREIGN KEY CHECKS OFF + +# Drop index via inplace algorithm +create table t1(f1 int,primary key(f1))engine=innodb; +create table t2(f2 int,f3 int,key t(f2,f3),foreign key(f2) references t1(f1))engine=innodb; +SET foreign_key_checks=0; +drop index t on t2; +drop table t2; +drop table t1; + +# Drop index using alter statement via inplace +create table t1(f1 int ,primary key(f1))engine=innodb; +create table t2(f2 int,f3 int, key t(f2),foreign key(f2) references t1(f1))engine=innodb; +SET foreign_key_checks = 0; +alter table t2 drop key t,algorithm=inplace; +show create table t2; +drop table t2; +drop table t1; + +create table t1(f1 int ,primary key(f1))engine=innodb; +create table t2(f2 int,f3 int, key t(f2),key t1(f2,f3), +foreign key(f2) references t1(f1))engine=innodb; +SET foreign_key_checks = 0; +alter table t2 drop key t,algorithm=inplace; +show create table t2; +drop table t2; +drop table t1; diff --git a/mysql-test/suite/innodb/t/innodb-lock-inherit-read_commited.test b/mysql-test/suite/innodb/t/innodb-lock-inherit-read_commited.test new file mode 100644 index 00000000000..d9c933fa9b5 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-lock-inherit-read_commited.test @@ -0,0 +1,115 @@ +--echo # +--echo # Bug #21025880 DUPLICATE UK VALUES IN READ-COMMITTED(AGAIN) +--echo # + +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc + +SET @save_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; +SET GLOBAL innodb_purge_rseg_truncate_frequency=1; + +let $i=0; + +while ($i <=1 ) +{ + +CREATE TABLE t1 ( + a INT NOT NULL, + b INT NOT NULL, + PRIMARY KEY(b), + UNIQUE KEY(a)) +ENGINE=INNODB; + +SET @old_innodb_stats_auto_recalc = @@innodb_stats_auto_recalc; +SET GLOBAL innodb_stats_auto_recalc = OFF; + +# Block purge +connect purge_control,localhost,root; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +connection default; + +SET @old_tx_isolation = @@tx_isolation; +SET GLOBAL tx_isolation = 'READ-COMMITTED'; + +SET @old_innodb_lock_wait_timeout = @@innodb_lock_wait_timeout; +SET GLOBAL innodb_lock_wait_timeout = 1; + +--connect(con1,localhost,root,,) + +# Create and delete-mark an index record + +INSERT INTO t1 VALUES (1,1),(2,2); +DELETE FROM t1; + +SET debug_sync = 'row_ins_sec_index_entry_dup_locks_created SIGNAL +con1_locks_done WAIT_FOR con1_go'; +SET debug_sync = 'ha_commit_trans_after_acquire_commit_lock SIGNAL +con1_insert_done WAIT_FOR con1_finish'; +--send + +if ($i == 0) +{ +REPLACE INTO t1 VALUES (1,2); +} + +if ( $i == 1) +{ +INSERT INTO t1 values (1,2) ON DUPLICATE KEY UPDATE a=2; +} +--connect(con2,localhost,root,,) + +SET debug_sync = 'now WAIT_FOR con1_locks_done'; + +SET debug_sync = 'lock_wait_suspend_thread_enter SIGNAL con2_blocked +WAIT_FOR con2_go'; +SET debug_sync = 'ha_commit_trans_after_acquire_commit_lock +WAIT_FOR con2_finish'; +SET debug_sync = 'ib_after_row_insert SIGNAL con2_insert_done'; + +--send +REPLACE INTO t1 VALUES (1,3); + +--connection default +SET debug_sync = 'now WAIT_FOR con2_blocked'; + +connection purge_control; +COMMIT; +disconnect purge_control; +connection default; + +# Wait for purge to delete the delete-marked record +--source ../../innodb/include/wait_all_purged.inc + +SET debug_sync = 'now SIGNAL con2_go WAIT_FOR con2_insert_done'; +SET debug_sync = 'now SIGNAL con1_go WAIT_FOR con1_insert_done'; + +SET debug_sync = 'now SIGNAL con1_finish'; + +--connection con1 +--reap +--disconnect con1 +--connection default +SET debug_sync = 'now SIGNAL con2_finish'; + +--connection con2 +--error 0,ER_LOCK_WAIT_TIMEOUT +--reap +--disconnect con2 + +--connection default +SET DEBUG_SYNC= 'RESET'; + +SELECT * FROM t1; +CHECK TABLE t1; + +DROP TABLE t1; + +SET GLOBAL innodb_stats_auto_recalc = @old_innodb_stats_auto_recalc; +SET GLOBAL tx_isolation = @old_tx_isolation; +SET GLOBAL innodb_lock_wait_timeout = @old_innodb_lock_wait_timeout; + +--inc $i +} + +SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_frequency; diff --git a/mysql-test/suite/innodb/t/innodb-read-view.test b/mysql-test/suite/innodb/t/innodb-read-view.test index 425cbeb08c8..21c79cf6566 100644 --- a/mysql-test/suite/innodb/t/innodb-read-view.test +++ b/mysql-test/suite/innodb/t/innodb-read-view.test @@ -1,7 +1,6 @@ # DEBUG_SYNC must be compiled in. --source include/have_debug_sync.inc --source include/have_debug.inc - # We need to test the use case: # a. Create a transaction T1 that will be promoted to RW. # b. Create a transaction T2 that will be promoted to RW. @@ -27,22 +26,16 @@ INSERT INTO t2 VALUES(2, "c"); INSERT INTO t2 VALUES(3, "d"); --connect (con1,localhost,root,,) ---connect (con2,localhost,root,,) - -connection con1; ---echo 'T1' SET AUTOCOMMIT=0; BEGIN; SELECT * FROM t2; connection default; ---echo 'T2' SET AUTOCOMMIT=0; BEGIN; SELECT * FROM t1; -connection con2; ---echo 'T3' +--connect (con2,localhost,root,,) SET AUTOCOMMIT=0; SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; BEGIN; @@ -50,48 +43,36 @@ SELECT * FROM t1; SELECT * FROM t2; connection con1; ---echo 'T1' UPDATE t2 SET c1 = c1 + 100; SELECT * FROM t2; COMMIT; connection default; ---echo 'T2' UPDATE t1 SET c1 = c1 + 100; SELECT * FROM t1; COMMIT; connection con2; ---echo 'T3' SET DEBUG_SYNC='row_search_for_mysql_before_return WAIT_FOR waiting1'; --send SELECT * FROM t1; connection default; ---echo 'T2' SET DEBUG_SYNC='now SIGNAL waiting1'; ---echo 'Signalled T3' connection con2; ---echo 'T3' reap; connection con2; ---echo 'T3' SET DEBUG_SYNC='row_search_for_mysql_before_return WAIT_FOR waiting1'; --send SELECT * FROM t2; connection default; ---echo 'T2' SET DEBUG_SYNC='now SIGNAL waiting1'; ---echo 'Signalled T3' connection con2; ---echo 'T3' reap; connection default; -disconnect con1; -disconnect con2; # We need to test the use case: # a. Create a transaction T1 that will be promoted to RW. @@ -105,17 +86,12 @@ disconnect con2; # i. T3 Does a select - it should not see the changes made by T1 but should # see the changes by T2 ---connect (con1,localhost,root,,) ---connect (con2,localhost,root,,) - connection con1; ---echo 'T1' SET AUTOCOMMIT=0; BEGIN; SELECT * FROM t1; connection default; ---echo 'T2' SET AUTOCOMMIT=0; BEGIN; SELECT * FROM t2; @@ -124,7 +100,6 @@ SELECT * FROM t2; COMMIT; connection con2; ---echo 'T3' SET AUTOCOMMIT=0; SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; BEGIN; @@ -132,42 +107,30 @@ SELECT * FROM t1; SELECT * FROM t2; connection con1; ---echo 'T1' UPDATE t1 SET c1 = c1 + 100; SELECT * FROM t1; COMMIT; connection con2; ---echo 'T3' SET DEBUG_SYNC='row_select_wait WAIT_FOR waiting1'; --send SELECT * FROM t1; connection con1; ---echo 'T2' SET DEBUG_SYNC='now SIGNAL waiting1'; ---echo 'Signalled T3' connection con2; ---echo 'T3' reap; - -connection con2; ---echo 'T3' SET DEBUG_SYNC='row_select_wait WAIT_FOR waiting1'; --send SELECT * FROM t2; connection default; ---echo 'T2' SET DEBUG_SYNC='now SIGNAL waiting1'; ---echo 'Signalled T3' connection con2; ---echo 'T3' reap; +disconnect con2; connection default; -disconnect con1; -disconnect con2; DROP TABLE t1; DROP TABLE t2; @@ -176,8 +139,7 @@ DROP TABLE t2; --echo # Bug 21433768: NON-REPEATABLE READ WITH REPEATABLE READ ISOLATION --echo # ---connect (con1,localhost,root,,) - +connection con1; CREATE TABLE t1(col1 INT PRIMARY KEY, col2 INT) ENGINE = InnoDB; INSERT INTO t1 values (1, 0), (2, 0); SELECT * FROM t1 ORDER BY col1; @@ -200,9 +162,7 @@ reap; disconnect con1; connection default; - +SET DEBUG_SYNC= 'RESET'; DROP TABLE t1; -# Clean up resources used in this test case. -SET DEBUG_SYNC= 'RESET'; --source include/wait_until_count_sessions.inc diff --git a/mysql-test/suite/innodb/t/innodb_i_s_innodb_locks.test b/mysql-test/suite/innodb/t/innodb_i_s_innodb_locks.test new file mode 100644 index 00000000000..e6e46dbf556 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_i_s_innodb_locks.test @@ -0,0 +1,169 @@ +# +# Test that user data is correctly "visualized" in +# INFORMATION_SCHEMA.innodb_locks.lock_data +# + +-- source include/have_innodb.inc + +SET @save_timeout=@@GLOBAL.innodb_lock_wait_timeout; +SET GLOBAL innodb_lock_wait_timeout=100000000; + +let $table_def = +( + c01 TINYINT, + c02 TINYINT UNSIGNED, + c03 SMALLINT, + c04 SMALLINT UNSIGNED, + c05 MEDIUMINT, + c06 MEDIUMINT UNSIGNED, + c07 INT, + c08 INT UNSIGNED, + c09 BIGINT, + c10 BIGINT UNSIGNED, + PRIMARY KEY(c01, c02, c03, c04, c05, c06, c07, c08, c09, c10) +) ENGINE=INNODB; + +-- eval CREATE TABLE t_min $table_def; +INSERT INTO t_min VALUES +(-128, 0, + -32768, 0, + -8388608, 0, + -2147483648, 0, + -9223372036854775808, 0); + +-- eval CREATE TABLE t_max $table_def; +INSERT INTO t_max VALUES +(127, 255, + 32767, 65535, + 8388607, 16777215, + 2147483647, 4294967295, + 9223372036854775807, 18446744073709551615); + +CREATE TABLE ```t'\"_str` ( + c1 VARCHAR(32), + c2 VARCHAR(32), + c3 VARCHAR(32), + c4 VARCHAR(32), + c5 VARCHAR(32), + c6 VARCHAR(32), + c7 VARCHAR(32), + PRIMARY KEY(c1, c2, c3, c4, c5, c6, c7) +) ENGINE=INNODB; +INSERT INTO ```t'\"_str` VALUES +('1', 'abc', '''abc', 'abc''', 'a''bc', 'a''bc''', '''abc'''''); +INSERT INTO ```t'\"_str` VALUES +('2', 'abc', '"abc', 'abc"', 'a"bc', 'a"bc"', '"abc""'); +INSERT INTO ```t'\"_str` VALUES +('3', 'abc', '\\abc', 'abc\\', 'a\\bc', 'a\\bc\\', '\\abc\\\\'); +INSERT INTO ```t'\"_str` VALUES +('4', 'abc', 0x00616263, 0x61626300, 0x61006263, 0x6100626300, 0x610062630000); + +-- source include/count_sessions.inc + +-- connect (con_lock,localhost,root,,) +-- connect (con_min_trylock,localhost,root,,) +-- connect (con_max_trylock,localhost,root,,) +-- connect (con_str_insert_supremum,localhost,root,,) +-- connect (con_str_lock_row1,localhost,root,,) +-- connect (con_str_lock_row2,localhost,root,,) +-- connect (con_str_lock_row3,localhost,root,,) +-- connect (con_str_lock_row4,localhost,root,,) +-- connect (con_verify_innodb_locks,localhost,root,,) + +-- connection con_lock +SET autocommit=0; +SELECT * FROM t_min FOR UPDATE; +SELECT * FROM t_max FOR UPDATE; +SELECT * FROM ```t'\"_str` FOR UPDATE; + +-- connection con_min_trylock +-- send +SELECT * FROM t_min FOR UPDATE; + +-- connection con_max_trylock +-- send +SELECT * FROM t_max FOR UPDATE; + +-- connection con_str_insert_supremum +-- send +INSERT INTO ```t'\"_str` VALUES +('z', 'z', 'z', 'z', 'z', 'z', 'z'); + +-- connection con_str_lock_row1 +-- send +SELECT * FROM ```t'\"_str` WHERE c1 = '1' FOR UPDATE; + +-- connection con_str_lock_row2 +-- send +SELECT * FROM ```t'\"_str` WHERE c1 = '2' FOR UPDATE; + +-- connection con_str_lock_row3 +-- send +SELECT * FROM ```t'\"_str` WHERE c1 = '3' FOR UPDATE; + +-- connection con_str_lock_row4 +-- send +SELECT * FROM ```t'\"_str` WHERE c1 = '4' FOR UPDATE; + +-- connection con_verify_innodb_locks +# Wait for the above queries to execute before continuing. +# Without this, it sometimes happens that the SELECT from innodb_locks +# executes before some of them, resulting in less than expected number +# of rows being selected from innodb_locks. If there is a bug and there +# are no 14 rows in innodb_locks then this test will fail with timeout. +# Notice that if we query INNODB_LOCKS more often than once per 0.1 sec +# then its contents will never change because the cache from which it is +# filled is updated only if it has not been read for 0.1 seconds. See +# CACHE_MIN_IDLE_TIME_US in trx/trx0i_s.c. +let $cnt=10; +while ($cnt) +{ + let $success=`SELECT COUNT(*) = 14 FROM INFORMATION_SCHEMA.INNODB_LOCKS`; + if ($success) + { + let $cnt=0; + } + if (!$success) + { + real_sleep 0.2; + dec $cnt; + } +} +if (!$success) +{ + -- echo Timeout waiting for rows in INNODB_LOCKS to appear +} + +SELECT lock_mode, lock_type, lock_table, lock_index, lock_rec, lock_data +FROM INFORMATION_SCHEMA.INNODB_LOCKS ORDER BY lock_data; + +SELECT lock_table, COUNT(*) FROM INFORMATION_SCHEMA.INNODB_LOCKS +GROUP BY lock_table; + +set @save_sql_mode = @@sql_mode; +SET SQL_MODE='ANSI_QUOTES'; +SELECT lock_table, COUNT(*) FROM INFORMATION_SCHEMA.INNODB_LOCKS +GROUP BY lock_table; +SET @@sql_mode=@save_sql_mode; + +# Release all the locks; +-- connection con_lock +COMMIT; + +-- connection default + +-- disconnect con_lock +-- disconnect con_min_trylock +-- disconnect con_max_trylock +-- disconnect con_str_insert_supremum +-- disconnect con_str_lock_row1 +-- disconnect con_str_lock_row2 +-- disconnect con_str_lock_row3 +-- disconnect con_str_lock_row4 +-- disconnect con_verify_innodb_locks + +DROP TABLE t_min, t_max, ```t'\"_str`; + +-- source include/wait_until_count_sessions.inc + +SET GLOBAL innodb_lock_wait_timeout=@save_timeout; diff --git a/mysql-test/suite/innodb/t/innodb_i_s_innodb_trx.test b/mysql-test/suite/innodb/t/innodb_i_s_innodb_trx.test new file mode 100644 index 00000000000..745e1d94a12 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_i_s_innodb_trx.test @@ -0,0 +1,95 @@ +--source include/have_innodb.inc + +# +# Test that transaction data is correctly "visualized" in +# INFORMATION_SCHEMA.INNODB_TRX +# + +SET @save_timeout=@@GLOBAL.innodb_lock_wait_timeout; +SET GLOBAL innodb_lock_wait_timeout=100000000; + +DESCRIBE INFORMATION_SCHEMA.INNODB_TRX; + +CREATE TABLE t1 ( + c01 INT, + c02 INT, + PRIMARY KEY (c01) +) ENGINE=INNODB STATS_AUTO_RECALC=0; + +INSERT INTO t1 VALUES +(1,2),(2,4),(3,6),(4,8); + +CREATE TABLE t2 ( + c01 INT, + c02 INT, + PRIMARY KEY (c01), + FOREIGN KEY fk1 (c02) REFERENCES t1 (c01) +) ENGINE=INNODB STATS_AUTO_RECALC=0; + +INSERT INTO t2 VALUES +(1,1),(2,2),(3,3); + +-- source include/count_sessions.inc + +-- connect (con_trx,localhost,root,,) +-- connect (con_verify_innodb_trx,localhost,root,,) + +-- connection con_trx +SET autocommit=0; +INSERT INTO t1 VALUES (5,10); +SELECT * FROM t1 FOR UPDATE; + +let $wait_timeout= 300; +let $wait_condition= + SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.INNODB_TRX; +-- source include/wait_condition.inc + +-- connection con_verify_innodb_trx +SELECT trx_state, trx_weight, trx_tables_in_use, trx_tables_locked, +trx_rows_locked, trx_rows_modified, trx_concurrency_tickets, +trx_isolation_level, trx_unique_checks, trx_foreign_key_checks +FROM INFORMATION_SCHEMA.INNODB_TRX; + +-- connection con_trx +ROLLBACK; +SET FOREIGN_KEY_CHECKS = 0; +SET UNIQUE_CHECKS = 0; +SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; +BEGIN; +INSERT INTO t1 VALUES (6,12); + +let $wait_timeout= 300; +let $wait_condition= + SELECT trx_unique_checks = 0 FROM INFORMATION_SCHEMA.INNODB_TRX; +-- source include/wait_condition.inc + +-- connection con_verify_innodb_trx +SELECT trx_isolation_level, trx_unique_checks, trx_foreign_key_checks +FROM INFORMATION_SCHEMA.INNODB_TRX; + +-- connection con_trx +ROLLBACK; +SET FOREIGN_KEY_CHECKS = 1; +SET UNIQUE_CHECKS = 1; +BEGIN; +--error ER_NO_REFERENCED_ROW_2 +INSERT INTO t2 VALUES (4,10); + +let $wait_timeout= 300; +let $wait_condition= + SELECT trx_unique_checks = 1 FROM INFORMATION_SCHEMA.INNODB_TRX; +-- source include/wait_condition.inc +-- disconnect con_trx + +-- connection con_verify_innodb_trx +SELECT trx_state, trx_isolation_level, trx_last_foreign_key_error +FROM INFORMATION_SCHEMA.INNODB_TRX; +-- disconnect con_verify_innodb_trx + +-- connection default +DROP TABLE t2; +DROP TABLE t1; + +-- source include/wait_until_count_sessions.inc + +SET GLOBAL innodb_lock_wait_timeout=@save_timeout; diff --git a/mysql-test/suite/innodb/t/innodb_information_schema_tables.opt b/mysql-test/suite/innodb/t/innodb_information_schema_tables.opt index 9f30d81ef9c..1e45e63659f 100644 --- a/mysql-test/suite/innodb/t/innodb_information_schema_tables.opt +++ b/mysql-test/suite/innodb/t/innodb_information_schema_tables.opt @@ -27,3 +27,4 @@ --loose-innodb_buffer_pool_pages --loose-innodb_buffer_pool_pages_index --loose-innodb_buffer_pool_pages_blob +--innodb-open-files=1000000 diff --git a/mysql-test/suite/innodb/t/innodb_information_schema_tables.test b/mysql-test/suite/innodb/t/innodb_information_schema_tables.test index 15b3bf4f561..c62705da84b 100644 --- a/mysql-test/suite/innodb/t/innodb_information_schema_tables.test +++ b/mysql-test/suite/innodb/t/innodb_information_schema_tables.test @@ -1,6 +1,10 @@ -- source include/have_innodb.inc -- source include/not_embedded.inc +let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err; +let SEARCH_PATTERN= \[Warning\] InnoDB: innodb_open_files 1000000 should not be greater than the open_files_limit [0-9]+; +--source include/search_pattern_in_file.inc + # # MDEV-7762 InnoDB: Failing assertion: block->page.buf_fix_count > 0 in buf0buf.ic line 730 # diff --git a/mysql-test/suite/innodb/t/innodb_stats_auto_recalc.opt b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc.opt new file mode 100644 index 00000000000..aa53ff2e659 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc.opt @@ -0,0 +1 @@ +--innodb-stats-persistent diff --git a/mysql-test/suite/innodb/t/innodb_stats_auto_recalc.test b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc.test new file mode 100644 index 00000000000..e441a795540 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc.test @@ -0,0 +1,48 @@ +# +# Test the persistent stats auto recalc +# + +-- source include/have_innodb.inc +# Page numbers printed by this test depend on the page size +-- source include/have_innodb_16k.inc + +-- vertical_results + +-- let $check_stats1 = SELECT n_rows, clustered_index_size FROM mysql.innodb_table_stats WHERE table_name = 'autorecalc' +-- let $check_stats2 = SELECT index_name, stat_name, stat_value FROM mysql.innodb_index_stats WHERE table_name = 'autorecalc' + +CREATE TABLE autorecalc (a INT, PRIMARY KEY (a)) ENGINE=INNODB; + +# the CREATE should have inserted zeroed stats +-- eval $check_stats1 +-- eval $check_stats2 + +INSERT INTO autorecalc VALUES (1); +INSERT INTO autorecalc VALUES (2); + +# wait for the bg stats thread to update the stats, notice we wait on +# innodb_index_stats because innodb_table_stats gets updated first and +# it is possible that (if we wait on innodb_table_stats) the wait cond +# gets satisfied before innodb_index_stats is updated +let $wait_condition = SELECT stat_value = 2 FROM mysql.innodb_index_stats WHERE table_name = 'autorecalc' AND index_name = 'PRIMARY' AND stat_name = 'n_diff_pfx01'; +-- source include/wait_condition.inc + +# the second INSERT from above should have triggered an auto-recalc +-- eval $check_stats1 +-- eval $check_stats2 + +# now DELETE the rows and trigger a second auto-recalc, InnoDB may wait a +# few seconds before triggering an auto-recalc again (it tries not to be too +# aggressive) + +DELETE FROM autorecalc; + +let $wait_timeout = 25; +let $wait_condition = SELECT stat_value = 0 FROM mysql.innodb_index_stats WHERE table_name = 'autorecalc' AND index_name = 'PRIMARY' AND stat_name = 'n_diff_pfx01'; +-- source include/wait_condition.inc + +# the DELETE from above should have triggered an auto-recalc +-- eval $check_stats1 +-- eval $check_stats2 + +DROP TABLE autorecalc; diff --git a/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_ddl.opt b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_ddl.opt new file mode 100644 index 00000000000..aa53ff2e659 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_ddl.opt @@ -0,0 +1 @@ +--innodb-stats-persistent diff --git a/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_ddl.test b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_ddl.test new file mode 100644 index 00000000000..aeb5b5c291e --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_ddl.test @@ -0,0 +1,49 @@ +# +# Test the persistent stats auto recalc during DDL +# + +-- source include/have_innodb.inc + +-- vertical_results + +-- let $check_stats1 = SELECT n_rows FROM mysql.innodb_table_stats WHERE table_name = 'arddl' ORDER BY 1 +-- let $check_stats2 = SELECT index_name, stat_name, stat_value FROM mysql.innodb_index_stats WHERE table_name = 'arddl' AND index_name = 'PRIMARY' ORDER BY 1, 2, 3 + +# Test ADD INDEX during background stats gathering + +CREATE TABLE arddl (a INT, b INT, PRIMARY KEY (a)) ENGINE=INNODB; + +INSERT INTO arddl VALUES (1, 10); +INSERT INTO arddl VALUES (2, 10); + +ALTER TABLE arddl ADD INDEX (b); + +# wait for the bg stats thread to update the stats, notice we wait on +# innodb_index_stats because innodb_table_stats gets updated first and +# it is possible that (if we wait on innodb_table_stats) the wait cond +# gets satisfied before innodb_index_stats is updated +let $wait_condition = SELECT stat_value = 2 FROM mysql.innodb_index_stats WHERE table_name = 'arddl' AND index_name = 'PRIMARY' AND stat_name = 'n_diff_pfx01'; +-- source include/wait_condition.inc + +# the second INSERT from above should have triggered an auto-recalc +-- eval $check_stats1 +-- eval $check_stats2 + +DROP TABLE arddl; + +# Test DROP INDEX during background stats gathering + +CREATE TABLE arddl (a INT, b INT, PRIMARY KEY (a), KEY (b)) ENGINE=INNODB; + +INSERT INTO arddl VALUES (3, 10); +INSERT INTO arddl VALUES (4, 10); + +ALTER TABLE arddl DROP INDEX b; + +let $wait_condition = SELECT stat_value = 2 FROM mysql.innodb_index_stats WHERE table_name = 'arddl' AND index_name = 'PRIMARY' AND stat_name = 'n_diff_pfx01'; +-- source include/wait_condition.inc + +-- eval $check_stats1 +-- eval $check_stats2 + +DROP TABLE arddl; diff --git a/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_lots.opt b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_lots.opt new file mode 100644 index 00000000000..aa53ff2e659 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_lots.opt @@ -0,0 +1 @@ +--innodb-stats-persistent diff --git a/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_lots.test b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_lots.test new file mode 100644 index 00000000000..88ca8910cd2 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_lots.test @@ -0,0 +1,45 @@ +# +# Test the persistent stats auto recalc on lots of tables +# + +--source include/no_valgrind_without_big.inc +-- source include/have_innodb.inc + +let $check_stats = SELECT table_name, n_rows FROM mysql.innodb_table_stats WHERE table_name LIKE 'ar_%' ORDER BY table_name; + +-- disable_query_log +let $i = 1200; +while ($i > 1000) { + eval CREATE TABLE ar_$i (a INT, PRIMARY KEY (a)) ENGINE=INNODB; + dec $i; +} +-- enable_query_log + +# the CREATEs above should have inserted zeroed stats +-- eval $check_stats + +-- disable_query_log +let $i = 1200; +while ($i > 1000) { + eval INSERT INTO ar_$i VALUES (1), (2); + dec $i; +} +-- enable_query_log + +-- disable_query_log +let $i = 1200; +while ($i > 1000) { + eval INSERT INTO ar_$i VALUES (3), (4); + dec $i; +} +-- enable_query_log + +# would be too long to wait for stats to become up to date here + +-- disable_query_log +let $i = 1200; +while ($i > 1000) { + eval DROP TABLE ar_$i; + dec $i; +} +-- enable_query_log diff --git a/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_on_nonexistent.opt b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_on_nonexistent.opt new file mode 100644 index 00000000000..aa53ff2e659 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_on_nonexistent.opt @@ -0,0 +1 @@ +--innodb-stats-persistent diff --git a/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_on_nonexistent.test b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_on_nonexistent.test new file mode 100644 index 00000000000..d8e7332958d --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_auto_recalc_on_nonexistent.test @@ -0,0 +1,85 @@ +# +# Test the persistent stats auto recalc when persistent stats do not exist +# + +-- source include/have_innodb.inc + +-- vertical_results + +-- let $check_stats1 = SELECT COUNT(*) FROM mysql.innodb_table_stats WHERE table_name = 't' +-- let $check_stats2 = SELECT COUNT(*) FROM mysql.innodb_index_stats WHERE table_name = 't' + +-- echo Test with default setting + +CREATE TABLE t (a INT, PRIMARY KEY (a)) ENGINE=INNODB; + +# the CREATE should have inserted zeroed stats +-- eval $check_stats1 +-- eval $check_stats2 + +# close the table +FLUSH TABLE t; + +DELETE FROM mysql.innodb_index_stats WHERE table_name = 't'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 't'; + +-- eval $check_stats1 +-- eval $check_stats2 + +# open the table, causing stats recalc/save +SELECT * FROM t; + +-- eval $check_stats1 +-- eval $check_stats2 + +DROP TABLE t; + +-- echo Test with explicit enable + +CREATE TABLE t (a INT, PRIMARY KEY (a)) ENGINE=INNODB STATS_AUTO_RECALC=1; + +# the CREATE should have inserted zeroed stats +-- eval $check_stats1 +-- eval $check_stats2 + +# close the table +FLUSH TABLE t; + +DELETE FROM mysql.innodb_index_stats WHERE table_name = 't'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 't'; + +-- eval $check_stats1 +-- eval $check_stats2 + +# open the table, causing stats recalc/save +SELECT * FROM t; + +-- eval $check_stats1 +-- eval $check_stats2 + +DROP TABLE t; + +-- echo Test with explicit disable + +CREATE TABLE t (a INT, PRIMARY KEY (a)) ENGINE=INNODB STATS_AUTO_RECALC=0; + +# the CREATE should have inserted zeroed stats +-- eval $check_stats1 +-- eval $check_stats2 + +# close the table +FLUSH TABLE t; + +DELETE FROM mysql.innodb_index_stats WHERE table_name = 't'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 't'; + +-- eval $check_stats1 +-- eval $check_stats2 + +# open the table, stats should not be present, since autorecalc is disabled +SELECT * FROM t; + +-- eval $check_stats1 +-- eval $check_stats2 + +DROP TABLE t; diff --git a/mysql-test/suite/innodb/t/innodb_stats_external_pages.test b/mysql-test/suite/innodb/t/innodb_stats_external_pages.test new file mode 100644 index 00000000000..da0dce9a454 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_external_pages.test @@ -0,0 +1,79 @@ +# +# Bug#18384390 WRONG STATISTICS WITH BIG ROW LENGTH AND PERSISTENT STATS +# + +--source include/have_innodb.inc +--source include/have_innodb_max_16k.inc +--source include/have_sequence.inc + +CREATE TABLE bug18384390 ( + id INT AUTO_INCREMENT PRIMARY KEY, + txt VARCHAR(10000) +) ENGINE=INNODB STATS_PERSISTENT=1 STATS_AUTO_RECALC=0; + +let $count=1024; +eval +INSERT INTO bug18384390 (txt) SELECT REPEAT('0', 10000) FROM seq_1_to_$count; + +set use_stat_tables=never; +ANALYZE TABLE bug18384390; + +-- let $n_rows = `SELECT n_rows FROM mysql.innodb_table_stats WHERE table_name = 'bug18384390'` + +-- let $table_rows = `SELECT table_rows FROM information_schema.tables WHERE table_name = 'bug18384390'` + +-- let $n_diff = `SELECT stat_value FROM mysql.innodb_index_stats WHERE table_name = 'bug18384390' AND stat_name = 'n_diff_pfx01'` + +-- let $cardinality = `SELECT cardinality FROM information_schema.statistics WHERE table_name = 'bug18384390'` + +-- let $margin_of_err_pct = 30 +-- let $margin_of_err_rows = `SELECT ROUND($count * $margin_of_err_pct / 100)` + +-- let $min_allowed = `SELECT $count - $margin_of_err_rows` +-- let $max_allowed = `SELECT $count + $margin_of_err_rows` + +-- let $dump_sql = SELECT COUNT(*) FROM bug18384390; SELECT * FROM mysql.innodb_table_stats; SELECT * FROM mysql.innodb_index_stats; SELECT * FROM information_schema.tables WHERE table_name = 'bug18384390'; SELECT * FROM information_schema.statistics WHERE table_name = 'bug18384390'; + +-- vertical_results + +if ($n_rows < $min_allowed) { + -- echo mysql.innodb_table_stats.n_rows is too small ($n_rows < $min_allowed) + -- eval $dump_sql +} + +if ($n_rows > $max_allowed) { + -- echo mysql.innodb_table_stats.n_rows is too big ($n_rows > $max_allowed) + -- eval $dump_sql +} + +if ($table_rows < $min_allowed) { + -- echo information_schema.tables.table_rows is too small ($table_rows < $min_allowed) + -- eval $dump_sql +} + +if ($table_rows > $max_allowed) { + -- echo information_schema.tables.table_rows is too big ($table_rows > $max_allowed) + -- eval $dump_sql +} + +if ($n_diff < $min_allowed) { + -- echo mysql.innodb_index_stats.stat_value is too small ($n_diff < $min_allowed) + -- eval $dump_sql +} + +if ($n_diff > $max_allowed) { + -- echo mysql.innodb_index_stats.stat_value is too big ($n_diff > $max_allowed) + -- eval $dump_sql +} + +if ($cardinality < $min_allowed) { + -- echo information_schema.statistics.cardinality is too small ($cardinality < $min_allowed) + -- eval $dump_sql +} + +if ($cardinality > $max_allowed) { + -- echo information_schema.statistics.cardinality is too big ($cardinality > $max_allowed) + -- eval $dump_sql +} + +DROP TABLE bug18384390; diff --git a/mysql-test/suite/innodb/t/innodb_stats_flag_global.combinations b/mysql-test/suite/innodb/t/innodb_stats_flag_global.combinations new file mode 100644 index 00000000000..561eb72d9a9 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_flag_global.combinations @@ -0,0 +1,4 @@ +[on] +--innodb-stats-persistent=1 +[off] +--innodb-stats-persistent=0 diff --git a/mysql-test/suite/innodb/t/innodb_stats_flag_global.test b/mysql-test/suite/innodb/t/innodb_stats_flag_global.test new file mode 100644 index 00000000000..88f0ed7c16d --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_flag_global.test @@ -0,0 +1,91 @@ +-- source include/have_innodb.inc +-- source include/not_embedded.inc + +# +-- echo ===== +-- echo === Test ANALYZE behavior after default creation +-- echo ===== + +CREATE TABLE test_ps_flag (a INT) ENGINE=INNODB; + +-- source innodb_stats_flag_global_analyze.inc + +DROP TABLE test_ps_flag; + +CREATE TABLE test_ps_flag (a INT) ENGINE=INNODB STATS_PERSISTENT=default; + +-- source innodb_stats_flag_global_analyze.inc + +DROP TABLE test_ps_flag; + +# +-- echo ===== +-- echo === Test ANALYZE behavior after creation with explicit PS=OFF +-- echo ===== + +CREATE TABLE test_ps_flag (a INT) ENGINE=INNODB STATS_PERSISTENT=0; + +-- source innodb_stats_flag_global_analyze.inc + +DROP TABLE test_ps_flag; + +# +-- echo ===== +-- echo === Test ANALYZE behavior after creation with explicit PS=ON +-- echo ===== + +CREATE TABLE test_ps_flag (a INT) ENGINE=INNODB STATS_PERSISTENT=1; + +-- source innodb_stats_flag_global_analyze.inc + +DROP TABLE test_ps_flag; + +# +-- echo ===== +-- echo === Test ANALYZE behavior after creation with explicit PS=OFF, +-- echo === then ALTER to ON, then ALTER to OFF, then ALTER to default +-- echo ===== + +CREATE TABLE test_ps_flag (a INT) ENGINE=INNODB STATS_PERSISTENT=0; + +ALTER TABLE test_ps_flag STATS_PERSISTENT=1; + +# also check that the change from the ALTER TABLE survives server restart +-- source include/restart_mysqld.inc + +-- source innodb_stats_flag_global_analyze.inc + +ALTER TABLE test_ps_flag STATS_PERSISTENT=0; + +-- source innodb_stats_flag_global_analyze.inc + +ALTER TABLE test_ps_flag STATS_PERSISTENT=default; + +-- source innodb_stats_flag_global_analyze.inc + +DROP TABLE test_ps_flag; + +# +-- echo ===== +-- echo === Test ANALYZE behavior after creation with explicit PS=ON, +-- echo === then ALTER to OFF, then ALTER to ON, then ALTER to default +-- echo ===== + +CREATE TABLE test_ps_flag (a INT) ENGINE=INNODB STATS_PERSISTENT=1; + +ALTER TABLE test_ps_flag STATS_PERSISTENT=0; + +# also check that the change from the ALTER TABLE survives server restart +-- source include/restart_mysqld.inc + +-- source innodb_stats_flag_global_analyze.inc + +ALTER TABLE test_ps_flag STATS_PERSISTENT=1; + +-- source innodb_stats_flag_global_analyze.inc + +ALTER TABLE test_ps_flag STATS_PERSISTENT=default; + +-- source innodb_stats_flag_global_analyze.inc + +DROP TABLE test_ps_flag; diff --git a/mysql-test/suite/innodb/t/innodb_stats_flag_global_analyze.inc b/mysql-test/suite/innodb/t/innodb_stats_flag_global_analyze.inc new file mode 100644 index 00000000000..8a68677e8ee --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_flag_global_analyze.inc @@ -0,0 +1,13 @@ +SHOW CREATE TABLE test_ps_flag; + +DELETE FROM mysql.innodb_index_stats WHERE table_name = 'test_ps_flag'; +DELETE FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; + +# must be 0, we have just deleted the rows +SELECT COUNT(*) AS cnt_before FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; + +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE test_ps_flag; + +# if the table is PS enabled, then this should be 1 and 0 otherwise +SELECT COUNT(*) AS cnt_after FROM mysql.innodb_table_stats WHERE table_name = 'test_ps_flag'; diff --git a/mysql-test/suite/innodb/t/innodb_stats_persistent.test b/mysql-test/suite/innodb/t/innodb_stats_persistent.test index f79ae37e8de..cfcd7c2128d 100644 --- a/mysql-test/suite/innodb/t/innodb_stats_persistent.test +++ b/mysql-test/suite/innodb/t/innodb_stats_persistent.test @@ -15,6 +15,7 @@ ENGINE=INNODB STATS_PERSISTENT=1,STATS_AUTO_RECALC=1; CREATE TABLE t2 LIKE t1; INSERT INTO t1 (val) SELECT 4 FROM seq_1_to_16; +SET STATEMENT use_stat_tables=never FOR ANALYZE TABLE t1; connect(con1, localhost, root,,); @@ -85,3 +86,41 @@ SET GLOBAL innodb_stats_include_delete_marked = @saved_include_delete_marked; SET GLOBAL innodb_stats_traditional = @saved_traditional; SET GLOBAL innodb_stats_modified_counter = @saved_modified_counter; SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; + +# +# Bug#12429573 TIMESTAMP COLUMN OF INNODB.INDEX_STATS ARE NOT UPDATED +# WHEN RE-RUNNING ANALYZE +# +CREATE TABLE bug12429573 (i INTEGER PRIMARY KEY, j INTEGER, KEY(j)) +ENGINE=INNODB STATS_PERSISTENT=1; + +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE bug12429573; + +# Cannot check the exact timestamp here because it is always different +# but at least check that both timestamps in innodb_table_stats and in +# innodb_index_stats have been updated to the same value. If the bug is +# present this check will fail. + +SELECT last_update INTO @last FROM mysql.innodb_table_stats +WHERE table_name = 'bug12429573'; +SELECT * FROM mysql.innodb_index_stats +WHERE table_name = 'bug12429573' AND last_update!=@last; + +# The first ANALYZE would insert timestamp e.g. 17:23:39 in both +# innodb_table_stats and innodb_index_stats. The bug is that the second +# ANALYZE only updates the timestamp in innodb_table_stats. In order to +# check if the timestamp in innodb_index_stats has really been updated we +# need it to be different from the previous one (17:23:39) with at least +# one second. +-- sleep 1 + +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE bug12429573; + +SELECT * FROM mysql.innodb_table_stats +WHERE table_name = 'bug12429573' AND last_update=@last; +SELECT * FROM mysql.innodb_index_stats +WHERE table_name = 'bug12429573' AND last_update=@last; + +DROP TABLE bug12429573; diff --git a/mysql-test/suite/innodb/t/innodb_stats_sample_pages.opt b/mysql-test/suite/innodb/t/innodb_stats_sample_pages.opt new file mode 100644 index 00000000000..aa53ff2e659 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_sample_pages.opt @@ -0,0 +1 @@ +--innodb-stats-persistent diff --git a/mysql-test/suite/innodb/t/innodb_stats_sample_pages.test b/mysql-test/suite/innodb/t/innodb_stats_sample_pages.test new file mode 100644 index 00000000000..1aac71a0450 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_sample_pages.test @@ -0,0 +1,53 @@ +# +# Test that the table option STATS_SAMPLE_PAGES=N|default is indeed +# used by InnoDB +# + +-- source include/have_innodb.inc +# Page numbers printed by this test depend on the page size +-- source include/have_innodb_16k.inc + +SET GLOBAL innodb_stats_persistent_sample_pages=17; + +CREATE TABLE test_ps_sample_pages_used ( + a VARCHAR(512), PRIMARY KEY (a) +) ENGINE=INNODB STATS_SAMPLE_PAGES=default; + +# Insert enough records into the table so that it has more than 2*17+1 pages +# If we ask to scan more than the half of the leaf pages, then the sampling +# will do full scan and we cannot check whether the sample_pages variable was +# honored. +BEGIN; +-- disable_query_log +let $i=999; +while ($i) { + eval INSERT INTO test_ps_sample_pages_used VALUES (REPEAT(1000+$i, 128)); + dec $i; +} +-- enable_query_log +COMMIT; + +ANALYZE TABLE test_ps_sample_pages_used; + +# confirm the big number of leaf pages in the index +SELECT stat_name, stat_value FROM mysql.innodb_index_stats +WHERE table_name='test_ps_sample_pages_used' AND stat_name='n_leaf_pages'; + +# confirm that 17 pages were sampled, that is - the global +# innodb_stats_persistent_sample_pages is used when the table option +# STATS_SAMPLE_PAGES is set to 'default'. +SELECT sample_size FROM mysql.innodb_index_stats +WHERE table_name='test_ps_sample_pages_used' AND stat_name='n_diff_pfx01'; + +ALTER TABLE test_ps_sample_pages_used STATS_SAMPLE_PAGES=14; + +ANALYZE TABLE test_ps_sample_pages_used; + +# confirm that 14 pages were sampled, that is - the table option +# STATS_SAMPLE_PAGES is used when it is set. +SELECT sample_size FROM mysql.innodb_index_stats +WHERE table_name='test_ps_sample_pages_used' AND stat_name='n_diff_pfx01'; + +DROP TABLE test_ps_sample_pages_used; + +SET GLOBAL innodb_stats_persistent_sample_pages=default; diff --git a/mysql-test/suite/innodb/t/innodb_stats_table_flag_auto_recalc.test b/mysql-test/suite/innodb/t/innodb_stats_table_flag_auto_recalc.test new file mode 100644 index 00000000000..01fe4331926 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_table_flag_auto_recalc.test @@ -0,0 +1,83 @@ +# +# Test CREATE TABLE ... STATS_AUTO_RECALC=0|1|default +# + +-- source include/no_valgrind_without_big.inc +-- source include/have_innodb.inc +-- source include/not_embedded.inc + +-- vertical_results + +CREATE TABLE test_ps_auto_recalc (a INT, PRIMARY KEY (a)) ENGINE=INNODB; + +SHOW CREATE TABLE test_ps_auto_recalc; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_auto_recalc'; + +ALTER TABLE test_ps_auto_recalc STATS_AUTO_RECALC=1; + +# confirm that the flag survives server restart +-- source include/restart_mysqld.inc + +SHOW CREATE TABLE test_ps_auto_recalc; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_auto_recalc'; + +DROP TABLE test_ps_auto_recalc; + +## + +CREATE TABLE test_ps_auto_recalc (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_AUTO_RECALC=default; + +SHOW CREATE TABLE test_ps_auto_recalc; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_auto_recalc'; + +DROP TABLE test_ps_auto_recalc; + +## + +CREATE TABLE test_ps_auto_recalc (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_AUTO_RECALC=0; + +# confirm that the flag survives server restart +-- source include/restart_mysqld.inc + +SHOW CREATE TABLE test_ps_auto_recalc; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_auto_recalc'; + +ALTER TABLE test_ps_auto_recalc STATS_AUTO_RECALC=1; + +# confirm that the flag survives server restart +-- source include/restart_mysqld.inc + +SHOW CREATE TABLE test_ps_auto_recalc; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_auto_recalc'; + +DROP TABLE test_ps_auto_recalc; + +## + +CREATE TABLE test_ps_auto_recalc (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_AUTO_RECALC=1; + +# confirm that the flag survives server restart +-- source include/restart_mysqld.inc + +SHOW CREATE TABLE test_ps_auto_recalc; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_auto_recalc'; + +ALTER TABLE test_ps_auto_recalc STATS_AUTO_RECALC=0; + +# confirm that the flag survives server restart +-- source include/restart_mysqld.inc + +SHOW CREATE TABLE test_ps_auto_recalc; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_auto_recalc'; + +DROP TABLE test_ps_auto_recalc; diff --git a/mysql-test/suite/innodb/t/innodb_stats_table_flag_sample_pages.test b/mysql-test/suite/innodb/t/innodb_stats_table_flag_sample_pages.test new file mode 100644 index 00000000000..a5c3c8624b1 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_stats_table_flag_sample_pages.test @@ -0,0 +1,103 @@ +# +# Test CREATE TABLE ... STATS_SAMPLE_PAGES=N|default +# + +-- source include/have_innodb.inc +# include/restart_mysqld.inc does not work in embedded mode +-- source include/not_embedded.inc + +-- vertical_results + +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB; + +SHOW CREATE TABLE test_ps_sample_pages; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_sample_pages'; + +ALTER TABLE test_ps_sample_pages STATS_SAMPLE_PAGES=12345; + +# confirm that the flag survives server restart +-- source include/restart_mysqld.inc + +SHOW CREATE TABLE test_ps_sample_pages; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_sample_pages'; + +DROP TABLE test_ps_sample_pages; + +## + +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=default; + +SHOW CREATE TABLE test_ps_sample_pages; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_sample_pages'; + +DROP TABLE test_ps_sample_pages; + +## + +-- error ER_PARSE_ERROR +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=-5; + +-- error ER_PARSE_ERROR +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=0; + +-- error ER_PARSE_ERROR +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=67000; + +-- error ER_PARSE_ERROR +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=670000; + +-- error ER_PARSE_ERROR +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=65536; + +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=65535; + +SHOW CREATE TABLE test_ps_sample_pages; + +DROP TABLE test_ps_sample_pages; + +## + +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=1; + +# confirm that the flag survives server restart +-- source include/restart_mysqld.inc + +SHOW CREATE TABLE test_ps_sample_pages; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_sample_pages'; + +DROP TABLE test_ps_sample_pages; + +## + +CREATE TABLE test_ps_sample_pages (a INT, PRIMARY KEY (a)) ENGINE=INNODB +STATS_SAMPLE_PAGES=5678; + +# confirm that the flag survives server restart +-- source include/restart_mysqld.inc + +SHOW CREATE TABLE test_ps_sample_pages; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_sample_pages'; + +ALTER TABLE test_ps_sample_pages STATS_SAMPLE_PAGES=default; + +# confirm that the flag survives server restart +-- source include/restart_mysqld.inc + +SHOW CREATE TABLE test_ps_sample_pages; +SELECT create_options FROM information_schema.tables +WHERE table_name='test_ps_sample_pages'; + +DROP TABLE test_ps_sample_pages; diff --git a/mysql-test/suite/innodb/t/innodb_ut_format_name.test b/mysql-test/suite/innodb/t/innodb_ut_format_name.test new file mode 100644 index 00000000000..6e4023c7088 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_ut_format_name.test @@ -0,0 +1,17 @@ +# +# Test ut_format_name() +# + +-- source include/have_debug.inc +-- source include/have_innodb.inc + +CREATE TABLE t (c INT) ENGINE=INNODB; + +# This will invoke test_ut_format_name() in debug builds + +SET @save_dbug = @@debug_dbug; +SET debug_dbug = '+d,test_ut_format_name'; + +DROP TABLE t; + +SET debug_dbug = @save_dbug; diff --git a/mysql-test/suite/innodb/t/records_in_range.test b/mysql-test/suite/innodb/t/records_in_range.test new file mode 100644 index 00000000000..697dbc1e8dd --- /dev/null +++ b/mysql-test/suite/innodb/t/records_in_range.test @@ -0,0 +1,432 @@ +# +# Test btr_estimate_n_rows_in_range() which is used by +# ha_innobase::records_in_range() +# + +-- source include/have_debug.inc +-- source include/have_innodb.inc +-- source include/innodb_page_size_small.inc + +CREATE TABLE records_in_range_test ( + c1 VARCHAR(16), + c2 VARCHAR(512), + PRIMARY KEY (c1) +) ENGINE=INNODB STATS_PERSISTENT=1; + +# Insert some records so that they cannot fit in one page for some page sizes +# in order to exercise records_in_range() where 1, 2 or more pages are sampled +INSERT INTO records_in_range_test VALUES +('ccc', REPEAT('v', 512)), +('kkk01', REPEAT('v', 512)), +('kkk02', REPEAT('v', 512)), +('kkk03', REPEAT('v', 512)), +('kkk04', REPEAT('v', 512)), +('kkk05', REPEAT('v', 512)), +('kkk06', REPEAT('v', 512)), +('kkk07', REPEAT('v', 512)), +('kkk08', REPEAT('v', 512)), +('mmm', REPEAT('v', 512)), +('nnn', REPEAT('v', 512)), +('uuu01', REPEAT('v', 512)), +('uuu02', REPEAT('v', 512)), +('uuu03', REPEAT('v', 512)), +('uuu04', REPEAT('v', 512)), +('uuu05', REPEAT('v', 512)), +('uuu06', REPEAT('v', 512)), +('uuu07', REPEAT('v', 512)), +('uuu08', REPEAT('v', 512)), +('xxx', REPEAT('v', 512)); + +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE records_in_range_test; + +# 16k or bigger page size: 1 leaf page +# 8k page size: 2 leaf pages +# 4k page size: 4 leaf pages +SELECT index_name, stat_name, stat_value +FROM mysql.innodb_index_stats +WHERE +table_name='records_in_range_test' AND stat_name = 'n_leaf_pages'; + +# 16k or bigger page size: 1 page in total (leaf + nonleaf) +# 8k page size: 3 pages in total (leaf + nonleaf) +# 4k page size: 5 pages in total (leaf + nonleaf) +SELECT index_name, stat_name, stat_value +FROM mysql.innodb_index_stats +WHERE +table_name='records_in_range_test' AND stat_name = 'size'; + +# We exploit the warning mechanism here to display the return value from +# btr_estimate_n_rows_in_range() +SET @save_dbug = @@debug_dbug; +SET DEBUG_DBUG='+d,print_btr_estimate_n_rows_in_range_return_value'; + +-- echo +-- echo In all SELECTs below the number of the records in the range returned +-- echo by COUNT(*) must be the same as the number returned by +-- echo btr_estimate_n_rows_in_range() which can be seen inside the artificial +-- echo warning + +-- echo +-- echo Test left-unbounded, right-open intervals +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'aaa'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 < 'zzz'; + +-- echo +-- echo Test left-unbounded, right-closed intervals +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'aaa'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 <= 'zzz'; + +-- echo +-- echo Test left-open, right-unbounded intervals +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz'; + +-- echo +-- echo Test left-closed, right-unbounded intervals +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz'; + +-- echo +-- echo Test left-open, right-open intervals +-- echo In some cases here the optimizer is smart enough not to call +-- echo ha_innobase::records_in_range() at all, so we get no warning containing +-- echo the value returned from btr_estimate_n_rows_in_range() +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 < 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 < 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 < 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 < 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 < 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 < 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 < 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 < 'zzz'; + +-- echo +-- echo Test left-closed, right-open intervals +-- echo In some cases here the optimizer is smart enough not to call +-- echo ha_innobase::records_in_range() at all, so we get no warning containing +-- echo the value returned from btr_estimate_n_rows_in_range() +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 < 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 < 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 < 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 < 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 < 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 < 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 < 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 < 'zzz'; + +-- echo +-- echo Test left-open, right-closed intervals +-- echo In some cases here the optimizer is smart enough not to call +-- echo ha_innobase::records_in_range() at all, so we get no warning containing +-- echo the value returned from btr_estimate_n_rows_in_range() +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'aaa' AND c1 <= 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'ccc' AND c1 <= 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'eee' AND c1 <= 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'mmm' AND c1 <= 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'nnn' AND c1 <= 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'qqq' AND c1 <= 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'xxx' AND c1 <= 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 > 'zzz' AND c1 <= 'zzz'; + +-- echo +-- echo Test left-closed, right-closed intervals +-- echo In some cases here the optimizer is smart enough not to call +-- echo ha_innobase::records_in_range() at all, so we get no warning containing +-- echo the value returned from btr_estimate_n_rows_in_range() +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'aaa' AND c1 <= 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'ccc' AND c1 <= 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'eee' AND c1 <= 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'mmm' AND c1 <= 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'nnn' AND c1 <= 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'qqq' AND c1 <= 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'xxx' AND c1 <= 'zzz'; +-- echo +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'bbb'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'ccc'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'eee'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'mmm'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'nnn'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'qqq'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'xxx'; +SELECT COUNT(*) FROM records_in_range_test WHERE c1 >= 'zzz' AND c1 <= 'zzz'; + +SET DEBUG_DBUG = @save_dbug; + +DROP TABLE records_in_range_test; diff --git a/mysql-test/suite/innodb/t/tablespace_per_table_not_windows.opt b/mysql-test/suite/innodb/t/tablespace_per_table_not_windows.opt new file mode 100644 index 00000000000..bd6d9db453b --- /dev/null +++ b/mysql-test/suite/innodb/t/tablespace_per_table_not_windows.opt @@ -0,0 +1,2 @@ +--innodb-sys-tablespaces +--innodb-sys-datafiles diff --git a/mysql-test/suite/innodb/t/tablespace_per_table_not_windows.test b/mysql-test/suite/innodb/t/tablespace_per_table_not_windows.test new file mode 100644 index 00000000000..2cc2460e517 --- /dev/null +++ b/mysql-test/suite/innodb/t/tablespace_per_table_not_windows.test @@ -0,0 +1,164 @@ +--echo # +--echo # Test the limits of a file-per-table tablespace name. MySQL combines +--echo # the database name with the table name to make a unique table name. +--echo # + +--source include/have_innodb.inc +--source include/not_windows.inc +# This will test the limit of a filename in MySQL at 512 bytes. +# We control that by making it a relative path starting with "./". +# The embedded server uses an absolute path as the datadir +# which has a non-deterministic length. +--source include/not_embedded.inc + +SET default_storage_engine=InnoDB; +LET $MYSQLD_DATADIR = `select @@datadir`; + +--echo # +--echo # MySQL limits each database and tablename identifier to 64 characters +--echo # of up to 3 bytes per character, corresponding to 192 bytes. +--echo # +LET $too_long_name = this_sixty_five_byte_name_is_too_long____________________________; +--error ER_WRONG_DB_NAME +--eval CREATE DATABASE `$too_long_name` + +LET $long_name = this_sixty_four_byte_name_is_not_too_long_______________________; +--eval CREATE DATABASE `$long_name` +--eval USE `$long_name` + +--echo # +--echo # A 64 character tablename can be created in a 64 character database name +--echo # +--eval CREATE TABLE `$long_name`.`$long_name` (a SERIAL) + +--echo # +--echo # A 65 character tablename is too long. +--echo # +--error ER_WRONG_TABLE_NAME +--eval CREATE TABLE `test`.`$too_long_name` (a SERIAL) +--error ER_WRONG_TABLE_NAME +--eval CREATE TABLE `$long_name`.`$too_long_name` (a SERIAL) + +--echo # +--echo # Non-non-filename-safe characters like '#' are expanded to '@0023'. +--echo # On many file systems, such as Linux extfs, you can create a database name +--echo # that expands to up to 255 bytes long. +--echo # `##################################################_long` is expanded to +--echo # (50 * 5) + 5 = 255. +--echo # +LET $long_db_name = ##################################################_long; +--eval CREATE DATABASE `$long_db_name`; +--eval USE `$long_db_name` + +--echo # +--echo # This 256-byte name is only one byte longer but fails with an error code +--echo # from the stat operation. +--echo # `##################################################_long_` is expanded to +--echo # (50 * 5) + 6 = 256. +--echo # +--replace_regex /Errcode: [0-9]+/Errcode: ##/ /@0023/#/ +--error 13 +CREATE DATABASE `##################################################_long_`; + +--echo # +--echo # This 300-byte name which is the longest name that gets an error code +--echo # from the stat operation. +--echo # `###########################################################_long` is expanded to +--echo # (59 * 5) + 5 = 300. +--echo # +--replace_regex /Errcode: [0-9]+/Errcode: ##/ /@0023/#/ +--error 13 +CREATE DATABASE `###########################################################_long`; + +--echo # +--echo # This 301-byte name which is only one byte longer but fails with ER_TOO_LONG_IDENT. +--echo # `###########################################################_long_` is expanded to +--echo # (59 * 5) + 6 = 301. +--echo # +--replace_result @0023 # +--error ER_WRONG_DB_NAME +CREATE DATABASE `###########################################################_long_`; + +USE test; + +LET $long_249_byte_table_name = #################################################long; +LET $long_250_byte_table_name = #################################################_long; +LET $long_251_byte_table_name = #################################################_long_; +LET $long_252_byte_table_name = #################################################_long___; + +--echo # +--echo # An expanded table name is limited to 251 bytes +--echo # +--eval CREATE TABLE `test`.`$long_251_byte_table_name` (a SERIAL) + +--echo # +--echo # A 252-byte tablename is too long +--echo # +--replace_regex /errno: [0-9]+/errno: ##/ /@0023/#/ +--error ER_CANT_CREATE_TABLE +--eval CREATE TABLE `test`.`$long_252_byte_table_name` (a SERIAL) + +CREATE DATABASE twenty_byte_db_name_; +USE `twenty_byte_db_name_`; + +--echo # +--echo # A 251 byte expanded table name will fit with a longer database name +--echo # +--eval CREATE TABLE `twenty_byte_db_name_`.`$long_251_byte_table_name` (a SERIAL) + +--echo # +--echo # A 252 byte expanded table name is also too long in a longer database name +--echo # +--replace_regex /errno: [0-9]+/errno: ##/ /@0023/#/ +--error ER_CANT_CREATE_TABLE +--eval CREATE TABLE `twenty_byte_db_name_`.`$long_252_byte_table_name` (a SERIAL) + +--echo # +--echo # Another limitation is a 512 byte length to an expanded path that includes +--echo # the datadir which is './' in this test, the expanded database name, +--echo # the directory separator '/', the expanded table name, and the file extension. +--echo # './long_db_name.long_250_byte_table_name.frm' +--echo # 2+ 255 +1+ 250 +1+3 = 512 +--echo # +--eval CREATE TABLE `$long_db_name`.`$long_250_byte_table_name` (a SERIAL) + +--error ER_IDENT_CAUSES_TOO_LONG_PATH +--eval CREATE TABLE `$long_db_name`.`$long_251_byte_table_name` (a SERIAL) +SHOW WARNINGS; + +--echo # +--echo # Show the successfully created databases and tables +--echo # +--echo ---- list_files MYSQLD_DATADIR/test +--replace_result @0023 # +--list_files $MYSQLD_DATADIR/test +--echo ---- list_files MYSQLD_DATADIR/$long_name +--replace_result @0023 # +--list_files $MYSQLD_DATADIR/$long_name +--echo ---- list_files MYSQLD_DATADIR/$long_db_name +--replace_result @0023 # +--list_files $MYSQLD_DATADIR/@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023_long + +--replace_result @0023 # +SELECT name FROM information_schema.innodb_sys_tables WHERE name LIKE '%long%'; +--replace_result @0023 # +SELECT name FROM information_schema.innodb_sys_tablespaces WHERE name LIKE '%long%'; +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR @0023 # +SELECT path FROM information_schema.innodb_sys_datafiles WHERE path LIKE '%long%'; +--vertical_results +--replace_regex /innodb_file_per_table_[0-9]*/innodb_file_per_table_##/ +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR @0023 # +SELECT file_name, tablespace_name FROM information_schema.files WHERE file_name LIKE '%long%'; +--horizontal_results + +--echo # +--echo # Cleanup +--echo # + +--eval DROP TABLE `$long_name`.`$long_name` +--eval DROP TABLE `test`.`$long_251_byte_table_name` +--eval DROP TABLE `twenty_byte_db_name_`.`$long_251_byte_table_name` +--eval DROP TABLE `$long_db_name`.`$long_250_byte_table_name` +--eval DROP DATABASE `$long_name` +--eval DROP DATABASE `$long_db_name` +DROP DATABASE `twenty_byte_db_name_`; diff --git a/mysql-test/suite/innodb/t/tablespace_per_table_windows.opt b/mysql-test/suite/innodb/t/tablespace_per_table_windows.opt new file mode 100644 index 00000000000..bd6d9db453b --- /dev/null +++ b/mysql-test/suite/innodb/t/tablespace_per_table_windows.opt @@ -0,0 +1,2 @@ +--innodb-sys-tablespaces +--innodb-sys-datafiles diff --git a/mysql-test/suite/innodb/t/tablespace_per_table_windows.test b/mysql-test/suite/innodb/t/tablespace_per_table_windows.test new file mode 100644 index 00000000000..c556a3ed23c --- /dev/null +++ b/mysql-test/suite/innodb/t/tablespace_per_table_windows.test @@ -0,0 +1,79 @@ +--echo # +--echo # Test the limits of a file-per-table tablespace name. MySQL combines +--echo # the database name with the table name to make a unique table name. +--echo # + +# There is no use in testing the maximum expanded filename using "#" or +# some other character that is expanded by MySQL to "@0023" because +# Windows imposes a maximum absolute path length of 260 bytes. So the +# results will depend upon what local directory this test is run in. +# See https://msdn.microsoft.com/en-us/library/aa365247.aspx +# "Maximum Path Length Limitation +# In the Windows API, the maximum length for a path is MAX_PATH, which is +# defined as 260 characters. A local path is structured in the following +# order: drive letter, colon, backslash, name components separated by +# backslashes, and a terminating null character. For example, the maximum +# path on drive D is "D:\some 256-character path string" where +# "" represents the invisible terminating null character for the +# current system codepage. (The characters < > are used here for visual +# clarity and cannot be part of a valid path string.)" + +--source include/have_innodb.inc +--source include/windows.inc +# This will test the limit of a filename in MySQL at 512 bytes. +# We control that by making it a relative path starting with "./". +# The embedded server uses an absolute path as the datadir +# which has a non-deterministic length. +--source include/not_embedded.inc + +SET default_storage_engine=InnoDB; +LET $MYSQLD_DATADIR = `select @@datadir`; + +--echo # +--echo # MySQL limits each database and tablename identifier to 64 characters +--echo # of up to 3 bytes per character, corresponding to 192 bytes. +--echo # +LET $too_long_name = this_sixty_five_byte_name_is_too_long____________________________; +--error ER_WRONG_DB_NAME +--eval CREATE DATABASE `$too_long_name` + +LET $long_name = this_sixty_four_byte_name_is_not_too_long_______________________; +--eval CREATE DATABASE `$long_name` +--eval USE `$long_name` + +--echo # +--echo # A 64 character tablename can be created in a 64 character database name +--echo # +--eval CREATE TABLE `$long_name`.`$long_name` (a SERIAL) + +--echo # +--echo # A 65 character tablename is too long. +--echo # +--error ER_WRONG_TABLE_NAME +--eval CREATE TABLE `test`.`$too_long_name` (a SERIAL) +--error ER_WRONG_TABLE_NAME +--eval CREATE TABLE `$long_name`.`$too_long_name` (a SERIAL) + +--echo # +--echo # Show the successfully created database and table +--echo # +--eval SHOW CREATE TABLE `$long_name`.`$long_name` + +--echo ---- list_files MYSQLD_DATADIR/$long_name +--list_files $MYSQLD_DATADIR/$long_name + +SELECT name FROM information_schema.innodb_sys_tables WHERE name LIKE '%long%'; +SELECT name FROM information_schema.innodb_sys_tablespaces WHERE name LIKE '%long%'; +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +SELECT path FROM information_schema.innodb_sys_datafiles WHERE path LIKE '%long%'; +--vertical_results +--replace_regex /innodb_file_per_table_[0-9]*/innodb_file_per_table_##/ +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +SELECT file_name, tablespace_name FROM information_schema.files WHERE file_name LIKE '%long%'; +--horizontal_results + +--echo # +--echo # Cleanup +--echo # + +--eval DROP DATABASE `$long_name` diff --git a/mysql-test/suite/innodb_fts/r/foreign_key_check.result b/mysql-test/suite/innodb_fts/r/foreign_key_check.result new file mode 100644 index 00000000000..38f46d5ff3c --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/foreign_key_check.result @@ -0,0 +1,27 @@ +CREATE TABLE t1 ( +id INT NOT NULL, +title TEXT, +PRIMARY KEY (id), +FULLTEXT KEY (title), +FOREIGN KEY (id) REFERENCES t2 (id) +) ENGINE=InnoDB; +ERROR HY000: Can't create table `test`.`t1` (errno: 150 "Foreign key constraint is incorrectly formed") +CREATE TABLE t1 ( +id INT NOT NULL, +title TEXT, +PRIMARY KEY (id) +) ENGINE=InnoDB; +ALTER TABLE t1 ADD FULLTEXT KEY (title), ADD FOREIGN KEY (id) REFERENCES t2 (id); +ERROR HY000: Can't create table `test`.`t1` (errno: 150 "Foreign key constraint is incorrectly formed") +SET FOREIGN_KEY_CHECKS = 0; +ALTER TABLE t1 ADD FULLTEXT KEY (title), ADD FOREIGN KEY (id) REFERENCES t2 (id); +DROP TABLE t1; +CREATE TABLE t1 ( +id INT NOT NULL, +title TEXT, +PRIMARY KEY (id), +FULLTEXT KEY (title), +FOREIGN KEY (id) REFERENCES t2 (id) +) ENGINE=InnoDB; +DROP TABLE t1; +SET FOREIGN_KEY_CHECKS = 1; diff --git a/mysql-test/suite/innodb_fts/r/foreign_key_update.result b/mysql-test/suite/innodb_fts/r/foreign_key_update.result new file mode 100644 index 00000000000..f2d47da78c5 --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/foreign_key_update.result @@ -0,0 +1,34 @@ +CREATE TABLE t1 ( +a varchar(40), +KEY a(a) +) ENGINE=InnoDB; +CREATE TABLE t1_fk ( +a varchar(40), +KEY a(a), +FULLTEXT KEY (a), +CONSTRAINT fk FOREIGN KEY (a) REFERENCES t1 (a) ON UPDATE CASCADE +) ENGINE=InnoDB; +INSERT INTO t1 VALUES('mysql'); +INSERT INTO t1_fk VALUES('mysql'); +INSERT INTO t1_fk VALUES('mysql'); +SELECT * FROM t1_fk; +a +mysql +mysql +SELECT * FROM t1_fk WHERE MATCH(a) AGAINST('mysql'); +a +mysql +mysql +UPDATE t1 SET a = 'database' WHERE a = 'mysql'; +SELECT * FROM t1_fk; +a +database +database +SELECT * FROM t1_fk WHERE MATCH(a) AGAINST('mysql'); +a +SELECT * FROM t1_fk WHERE MATCH(a) AGAINST('database'); +a +database +database +DROP TABLE t1_fk; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb_fts/r/index_table.result b/mysql-test/suite/innodb_fts/r/index_table.result new file mode 100644 index 00000000000..570e367a7d4 --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/index_table.result @@ -0,0 +1,265 @@ +SET @optimize=@@GLOBAL.INNODB_OPTIMIZE_FULLTEXT_ONLY; +SET GLOBAL INNODB_OPTIMIZE_FULLTEXT_ONLY=1; +CREATE TABLE articles ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), +content TEXT +) ENGINE= InnoDB; +CREATE FULLTEXT INDEX idx ON articles (title, content); +INSERT INTO articles (title, content) VALUES +('MySQL Tutorial','DBMS stands for MySQL DataBase ...'), +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'), +('1001 MySQL Tricks','How to use full-text search engine'), +('Go MySQL Tricks','How to use full text search engine'); +SET @aux=@@GLOBAL.innodb_ft_aux_table; +SET GLOBAL innodb_ft_aux_table='test/articles'; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +1001 4 4 1 4 0 +after 2 2 1 2 22 +database 1 1 1 1 37 +dbms 1 1 1 1 15 +engine 4 5 2 4 46 +engine 4 5 2 5 44 +full 4 5 2 4 29 +full 4 5 2 5 27 +mysql 1 5 5 1 0 +mysql 1 5 5 1 31 +mysql 1 5 5 2 11 +mysql 1 5 5 3 11 +mysql 1 5 5 4 5 +mysql 1 5 5 5 3 +optimizing 3 3 1 3 0 +search 4 5 2 4 39 +search 4 5 2 5 37 +show 3 3 1 3 42 +stands 1 1 1 1 20 +text 4 5 2 4 34 +text 4 5 2 5 32 +through 2 2 1 2 37 +tricks 4 5 2 4 11 +tricks 4 5 2 5 9 +tutorial 1 3 2 1 6 +tutorial 1 3 2 3 25 +use 2 5 3 2 7 +use 2 5 3 4 25 +use 2 5 3 5 23 +well 2 2 1 2 17 +went 2 2 1 2 32 +you 2 2 1 2 28 +OPTIMIZE TABLE articles; +Table Op Msg_type Msg_text +test.articles optimize status OK +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +1001 4 4 1 4 0 +after 2 2 1 2 22 +database 1 1 1 1 37 +dbms 1 1 1 1 15 +engine 4 5 2 4 46 +engine 4 5 2 5 44 +full 4 5 2 4 29 +full 4 5 2 5 27 +mysql 1 5 5 1 0 +mysql 1 5 5 1 31 +mysql 1 5 5 2 11 +mysql 1 5 5 3 11 +mysql 1 5 5 4 5 +mysql 1 5 5 5 3 +optimizing 3 3 1 3 0 +search 4 5 2 4 39 +search 4 5 2 5 37 +show 3 3 1 3 42 +stands 1 1 1 1 20 +text 4 5 2 4 34 +text 4 5 2 5 32 +through 2 2 1 2 37 +tricks 4 5 2 4 11 +tricks 4 5 2 5 9 +tutorial 1 3 2 1 6 +tutorial 1 3 2 3 25 +use 2 5 3 2 7 +use 2 5 3 4 25 +use 2 5 3 5 23 +well 2 2 1 2 17 +went 2 2 1 2 32 +you 2 2 1 2 28 +SET @save_dbug=@@debug_dbug; +SET debug_dbug='+d,fts_instrument_result_cache_limit'; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +1001 4 4 1 4 0 +after 2 2 1 2 22 +database 1 1 1 1 37 +dbms 1 1 1 1 15 +engine 4 5 2 4 46 +engine 4 5 2 5 44 +full 4 5 2 4 29 +full 4 5 2 5 27 +mysql 1 5 5 1 0 +mysql 1 5 5 1 31 +mysql 1 5 5 2 11 +mysql 1 5 5 3 11 +mysql 1 5 5 4 5 +mysql 1 5 5 5 3 +optimizing 3 3 1 3 0 +search 4 5 2 4 39 +search 4 5 2 5 37 +show 3 3 1 3 42 +stands 1 1 1 1 20 +text 4 5 2 4 34 +text 4 5 2 5 32 +through 2 2 1 2 37 +tricks 4 5 2 4 11 +tricks 4 5 2 5 9 +tutorial 1 3 2 1 6 +tutorial 1 3 2 3 25 +use 2 5 3 2 7 +use 2 5 3 4 25 +use 2 5 3 5 23 +well 2 2 1 2 17 +went 2 2 1 2 32 +you 2 2 1 2 28 +SET debug_dbug=@save_dbug; +DROP TABLE articles; +SET GLOBAL innodb_ft_result_cache_limit=default; +CREATE TABLE articles ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), +content TEXT +) ENGINE= InnoDB; +CREATE FULLTEXT INDEX idx_t ON articles (title); +CREATE FULLTEXT INDEX idx_c ON articles (content); +INSERT INTO articles (title, content) VALUES +('MySQL Tutorial','DBMS stands for MySQL DataBase ...'), +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'), +('1001 MySQL Tricks','How to use full-text search engine'), +('Go MySQL Tricks','How to use full text search engine'); +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +SET GLOBAL innodb_ft_aux_table='test/articles'; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +1001 4 4 1 4 0 +mysql 1 5 5 1 0 +mysql 1 5 5 2 11 +mysql 1 5 5 3 11 +mysql 1 5 5 4 5 +mysql 1 5 5 5 3 +optimizing 3 3 1 3 0 +tricks 4 5 2 4 11 +tricks 4 5 2 5 9 +tutorial 1 1 1 1 6 +use 2 2 1 2 7 +well 2 2 1 2 17 +after 2 2 1 2 0 +database 1 1 1 1 22 +dbms 1 1 1 1 0 +engine 4 5 2 4 28 +engine 4 5 2 5 28 +full 4 5 2 4 11 +full 4 5 2 5 11 +mysql 1 1 1 1 16 +search 4 5 2 4 21 +search 4 5 2 5 21 +show 3 3 1 3 25 +stands 1 1 1 1 5 +text 4 5 2 4 16 +text 4 5 2 5 16 +through 2 2 1 2 15 +tutorial 3 3 1 3 8 +use 4 5 2 4 7 +use 4 5 2 5 7 +went 2 2 1 2 10 +you 2 2 1 2 6 +OPTIMIZE TABLE articles; +Table Op Msg_type Msg_text +test.articles optimize status OK +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +1001 4 4 1 4 0 +mysql 1 5 5 1 0 +mysql 1 5 5 2 11 +mysql 1 5 5 3 11 +mysql 1 5 5 4 5 +mysql 1 5 5 5 3 +optimizing 3 3 1 3 0 +tricks 4 5 2 4 11 +tricks 4 5 2 5 9 +tutorial 1 1 1 1 6 +use 2 2 1 2 7 +well 2 2 1 2 17 +after 2 2 1 2 0 +database 1 1 1 1 22 +dbms 1 1 1 1 0 +engine 4 5 2 4 28 +engine 4 5 2 5 28 +full 4 5 2 4 11 +full 4 5 2 5 11 +mysql 1 1 1 1 16 +search 4 5 2 4 21 +search 4 5 2 5 21 +show 3 3 1 3 25 +stands 1 1 1 1 5 +text 4 5 2 4 16 +text 4 5 2 5 16 +through 2 2 1 2 15 +tutorial 3 3 1 3 8 +use 4 5 2 4 7 +use 4 5 2 5 7 +went 2 2 1 2 10 +you 2 2 1 2 6 +DROP TABLE articles; +SET NAMES utf8; +CREATE TABLE articles ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200) +) ENGINE=InnoDB DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; +CREATE FULLTEXT INDEX idx ON articles (title); +INSERT INTO articles (title) VALUES +('相亲相爱'),('怜香惜爱'),('充满可爱'),('爱恨交织'); +SET GLOBAL innodb_ft_aux_table="test/articles"; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +充满可爱 3 3 1 3 0 +怜香惜爱 2 2 1 2 0 +爱恨交织 4 4 1 4 0 +相亲相爱 1 1 1 1 0 +OPTIMIZE TABLE articles; +Table Op Msg_type Msg_text +test.articles optimize status OK +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +充满可爱 3 3 1 3 0 +怜香惜爱 2 2 1 2 0 +爱恨交织 4 4 1 4 0 +相亲相爱 1 1 1 1 0 +DROP TABLE articles; +CREATE TABLE articles ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200) +) ENGINE=InnoDB DEFAULT CHARACTER SET gb2312 COLLATE gb2312_chinese_ci; +CREATE FULLTEXT INDEX idx ON articles (title); +INSERT INTO articles (title) VALUES +('相亲相爱'),('怜香惜爱'),('充满可爱'),('爱恨交织'); +SET GLOBAL innodb_ft_aux_table="test/articles"; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +爱恨交织 4 4 1 4 0 +充满可爱 3 3 1 3 0 +怜香惜爱 2 2 1 2 0 +相亲相爱 1 1 1 1 0 +OPTIMIZE TABLE articles; +Table Op Msg_type Msg_text +test.articles optimize status OK +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +怜香惜爱 2 2 1 2 0 +充满可爱 3 3 1 3 0 +相亲相爱 1 1 1 1 0 +爱恨交织 4 4 1 4 0 +DROP TABLE articles; +SET GLOBAL innodb_ft_aux_table=@aux; +SET GLOBAL INNODB_OPTIMIZE_FULLTEXT_ONLY=@optimize; diff --git a/mysql-test/suite/innodb_fts/r/innodb_fts_proximity.result b/mysql-test/suite/innodb_fts/r/innodb_fts_proximity.result index d67981e0851..a53fca51c6c 100644 --- a/mysql-test/suite/innodb_fts/r/innodb_fts_proximity.result +++ b/mysql-test/suite/innodb_fts/r/innodb_fts_proximity.result @@ -134,6 +134,7 @@ count(*) 2 DROP TABLE t1; set global innodb_file_per_table=1; +set names utf8; CREATE TABLE t1 ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, a TEXT, @@ -160,7 +161,7 @@ SELECT count(*) FROM t1 WHERE MATCH (a,b,c) AGAINST ('"very blob"@4' IN BOOLEAN MODE); count(*) -4 +5 SELECT count(*) FROM t1 WHERE MATCH (a,b,c) AGAINST ('"interesting blob"@9' IN BOOLEAN MODE); @@ -175,7 +176,7 @@ SELECT COUNT(*) FROM t1 WHERE MATCH (a,b,c) AGAINST ('"very blob"@4 - "interesting blob"@9' IN BOOLEAN MODE); COUNT(*) -3 +4 DROP TABLE t1; CREATE TABLE t1 ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, diff --git a/mysql-test/suite/innodb_fts/r/limit_union.result b/mysql-test/suite/innodb_fts/r/limit_union.result new file mode 100644 index 00000000000..843d55d23e4 --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/limit_union.result @@ -0,0 +1,157 @@ +# Bug #22709692 FTS QUERY EXCEEDS RESULT CACHE LIMIT +CREATE TABLE articles ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), +body TEXT, +FULLTEXT (title,body), +FULLTEXT (body))ENGINE=InnoDB; +INSERT INTO articles (title,body) VALUES +('MySQL Tutorial','DBMS stands for DataBase ...'), +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'), +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('MySQL vs. YourSQL','In the following database comparison ...'), +('MySQL Security','When configured properly, MySQL ...'); +SET @default_cache_size = @@GLOBAL.query_cache_size; +SET GLOBAL query_cache_size=0; +# Query involves Ranking +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('MySQL' IN NATURAL LANGUAGE MODE) LIMIT 1; +id title body +6 MySQL Security When configured properly, MySQL ... +# Without optimization +SET @save_dbug = @@debug_dbug; +SET debug_dbug = '+d,fts_union_limit_off'; +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('MySQL' IN NATURAL LANGUAGE MODE) LIMIT 1; +id title body +6 MySQL Security When configured properly, MySQL ... +SET debug_dbug = @save_dbug; +# Query involves No Ranking and fts_union operations +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('MySQL' IN BOOLEAN MODE) limit 1; +id title body +6 MySQL Security When configured properly, MySQL ... +# Without optimization +SET debug_dbug = '+d,fts_union_limit_off'; +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('MySQL' IN BOOLEAN MODE) limit 1; +id title body +6 MySQL Security When configured properly, MySQL ... +SET debug_dbug = @save_dbug; +# Query involves No ranking and fts_union, fts_ignore +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('MySQL -YourSQL' IN BOOLEAN MODE) limit 1; +id title body +6 MySQL Security When configured properly, MySQL ... +# Without optimization +SET debug_dbug = '+d,fts_union_limit_off'; +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('MySQL -YourSQL' IN BOOLEAN MODE) limit 1; +id title body +6 MySQL Security When configured properly, MySQL ... +SET debug_dbug = @save_dbug; +# Query with fts_intersect +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('MySQL +YourSQL' IN BOOLEAN MODE) limit 1; +id title body +5 MySQL vs. YourSQL In the following database comparison ... +# Without optimization +SET debug_dbug = '+d,fts_union_limit_off'; +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('MySQL +YourSQL' IN BOOLEAN MODE) limit 1; +id title body +5 MySQL vs. YourSQL In the following database comparison ... +SET debug_dbug = @save_dbug; +INSERT INTO articles (title,body) VALUES +('MySQL Tutorial','request doc@oraclehelp.com ...'), +('MySQL Tutorial','request support@oraclehelp.com ...'), +('Trial version','query performace @1255 minute on 2.1Hz + Memory 2GB...'), +('when To Use MySQL Well','for free faq mail@xyz.com ...'); +# Query with @distance +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"MySQL request"@3' IN BOOLEAN MODE) limit 1; +id title body +7 MySQL Tutorial request doc@oraclehelp.com ... +# Without optimization +SET debug_dbug = '+d,fts_union_limit_off'; +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"MySQL request"@3' IN BOOLEAN MODE) limit 1; +id title body +7 MySQL Tutorial request doc@oraclehelp.com ... +SET debug_dbug = @save_dbug; +# Query with subexpression +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('+MySQL +(-support +doc)' IN BOOLEAN MODE) limit 1; +id title body +7 MySQL Tutorial request doc@oraclehelp.com ... +# Without optimization +SET debug_dbug = '+d,fts_union_limit_off'; +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('+MySQL +(-support +doc)' IN BOOLEAN MODE) limit 1; +id title body +7 MySQL Tutorial request doc@oraclehelp.com ... +SET debug_dbug = @save_dbug; +# limit num1 OFFSET num2 +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('MySQL' in boolean mode) limit 4 offset 2; +id title body +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +5 MySQL vs. YourSQL In the following database comparison ... +# Without optimization +SET debug_dbug = '+d,fts_union_limit_off'; +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('MySQL' in boolean mode) limit 4 offset 2; +id title body +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +5 MySQL vs. YourSQL In the following database comparison ... +SET debug_dbug = @save_dbug; +# wild card search +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('ru*' IN BOOLEAN MODE) limit 1; +id title body +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +# Without optimization +SET debug_dbug = '+d,fts_union_limit_off'; +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('ru*' IN BOOLEAN MODE) limit 1; +id title body +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +SET debug_dbug = @save_dbug; +# phrase search +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"request support"' IN BOOLEAN MODE) limit 1; +id title body +8 MySQL Tutorial request support@oraclehelp.com ... +# Without optimization +SET debug_dbug = '+d,fts_union_limit_off'; +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"request support"' IN BOOLEAN MODE) limit 1; +id title body +8 MySQL Tutorial request support@oraclehelp.com ... +SET debug_dbug = @save_dbug; +DROP TABLE articles; +SET GLOBAL query_cache_size = @default_cache_size; diff --git a/mysql-test/suite/innodb_fts/r/misc.result b/mysql-test/suite/innodb_fts/r/misc.result new file mode 100644 index 00000000000..684996fb748 --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/misc.result @@ -0,0 +1,1878 @@ +CREATE TABLE t1 ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +a VARCHAR(200), +b TEXT +) ENGINE = InnoDB; +INSERT INTO t1 (a,b) VALUES +('MySQL Tutorial','DBMS stands for DataBase ...') , +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'); +ALTER TABLE t1 ADD FULLTEXT INDEX idx (a,b); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `a` varchar(200) DEFAULT NULL, + `b` text DEFAULT NULL, + PRIMARY KEY (`id`), + FULLTEXT KEY `idx` (`a`,`b`) +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +INSERT INTO t1 (a,b) VALUES +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('MySQL vs. YourSQL','In the following database comparison ...'), +('MySQL Security','When configured properly, MySQL ...'); +SELECT id FROM t1 WHERE MATCH (a,b) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); +id +1 +3 +select id from t1 where MATCH(a,b) AGAINST("+support +collections" IN BOOLEAN MODE); +id +select id from t1 where MATCH(a,b) AGAINST("+search" IN BOOLEAN MODE); +id +select id from t1 where MATCH(a,b) AGAINST("+search +(support vector)" IN BOOLEAN MODE); +id +select id from t1 where MATCH(a,b) AGAINST("+search -(support vector)" IN BOOLEAN MODE); +id +select id, MATCH(a,b) AGAINST("support collections" IN BOOLEAN MODE) as x from t1; +id x +1 0 +2 0 +3 0 +4 0 +5 0 +6 0 +select id, MATCH(a,b) AGAINST("collections support" IN BOOLEAN MODE) as x from t1; +id x +1 0 +2 0 +3 0 +4 0 +5 0 +6 0 +select id from t1 where MATCH a,b AGAINST ("+call* +coll*" IN BOOLEAN MODE); +id +select id from t1 where MATCH a,b AGAINST ('"support now"' IN BOOLEAN MODE); +id +select id from t1 where MATCH a,b AGAINST ('"Now sUPPort"' IN BOOLEAN MODE); +id +select id from t1 where MATCH(a,b) AGAINST ("collections" WITH QUERY EXPANSION); +id +select id from t1 where MATCH(a,b) AGAINST ("indexes" WITH QUERY EXPANSION); +id +select id from t1 where MATCH(a,b) AGAINST ("indexes collections" WITH QUERY EXPANSION); +id +ALTER TABLE t1 DROP INDEX idx; +CREATE FULLTEXT INDEX idx on t1 (a,b); +SELECT id FROM t1 WHERE MATCH (a,b) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); +id +1 +3 +select id from t1 where MATCH(a,b) AGAINST("+support +collections" IN BOOLEAN MODE); +id +select id from t1 where MATCH(a,b) AGAINST("+search" IN BOOLEAN MODE); +id +select id from t1 where MATCH(a,b) AGAINST("+search +(support vector)" IN BOOLEAN MODE); +id +select id from t1 where MATCH(a,b) AGAINST("+search -(support vector)" IN BOOLEAN MODE); +id +select id, MATCH(a,b) AGAINST("support collections" IN BOOLEAN MODE) as x from t1; +id x +1 0 +2 0 +3 0 +4 0 +5 0 +6 0 +select id, MATCH(a,b) AGAINST("collections support" IN BOOLEAN MODE) as x from t1; +id x +1 0 +2 0 +3 0 +4 0 +5 0 +6 0 +select id from t1 where MATCH a,b AGAINST ("+call* +coll*" IN BOOLEAN MODE); +id +select id from t1 where MATCH a,b AGAINST ('"support now"' IN BOOLEAN MODE); +id +select id from t1 where MATCH a,b AGAINST ('"Now sUPPort"' IN BOOLEAN MODE); +id +select id from t1 where MATCH(a,b) AGAINST ("collections" WITH QUERY EXPANSION); +id +select id from t1 where MATCH(a,b) AGAINST ("indexes" WITH QUERY EXPANSION); +id +select id from t1 where MATCH(a,b) AGAINST ("indexes collections" WITH QUERY EXPANSION); +id +INSERT INTO t1 (a,b) VALUES ('test query expansion','for database ...'); +INSERT INTO t1 (a,b) VALUES +('test proximity search, test, proximity and phrase', +'search, with proximity innodb'); +INSERT INTO t1 (a,b) VALUES +('test proximity fts search, test, proximity and phrase', +'search, with proximity innodb'); +INSERT INTO t1 (a,b) VALUES +('test more proximity fts search, test, more proximity and phrase', +'search, with proximity innodb'); +SELECT id FROM t1 +WHERE MATCH (a,b) +AGAINST ('"proximity search"@2' IN BOOLEAN MODE); +id +8 +SELECT id FROM t1 +WHERE MATCH (a,b) +AGAINST ('"proximity search"@1' IN BOOLEAN MODE); +id +SELECT id FROM t1 +WHERE MATCH (a,b) +AGAINST ('"proximity search"@3' IN BOOLEAN MODE); +id +8 +9 +10 +SELECT id FROM t1 +WHERE MATCH (a,b) +AGAINST ('"test proximity"@3' IN BOOLEAN MODE); +id +8 +9 +10 +SELECT id FROM t1 +WHERE MATCH (a,b) +AGAINST ('"more test proximity"@3' IN BOOLEAN MODE); +id +10 +SELECT id FROM t1 +WHERE MATCH (a,b) +AGAINST ('"more test proximity"@2' IN BOOLEAN MODE); +id +SELECT id FROM t1 +WHERE MATCH (a,b) +AGAINST ('"more fts proximity"@02' IN BOOLEAN MODE); +id +DROP TABLE t1; +CREATE TABLE t1 ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +a VARCHAR(200), +b TEXT +) ENGINE = InnoDB; +CREATE FULLTEXT INDEX idx on t1 (a,b); +INSERT INTO t1 (a,b) VALUES +('MySQL Tutorial','DBMS stands for DataBase ...') , +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'); +INSERT INTO t1 (a,b) VALUES +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('MySQL vs. YourSQL','In the following database comparison ...'), +('MySQL Security','When configured properly, MySQL ...'); +SELECT id FROM t1 WHERE MATCH (a,b) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); +id +1 +3 +SELECT id FROM t1 WHERE id = (SELECT MAX(id) FROM t1 WHERE MATCH (a,b) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE)); +id +3 +SELECT id FROM t1 WHERE id = (SELECT MIN(id) FROM t1 WHERE MATCH (a,b) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE)); +id +1 +SELECT id FROM t1 WHERE id = (SELECT MIN(id) FROM t1 WHERE MATCH (a,b) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE)) OR id = 3 ; +id +1 +3 +SELECT id FROM t1 WHERE CONCAT(t1.a,t1.b) IN ( +SELECT CONCAT(a,b) FROM t1 AS t2 WHERE +MATCH (t2.a,t2.b) AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE) +) OR t1.id = 3 ; +id +1 +3 +SELECT id FROM t1 WHERE CONCAT(t1.a,t1.b) IN ( +SELECT CONCAT(a,b) FROM t1 AS t2 +WHERE MATCH (t2.a,t2.b) AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE) +AND t2.id != 3) ; +id +1 +SELECT id FROM t1 WHERE id IN (SELECT MIN(id) FROM t1 WHERE +MATCH (a,b) AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE)) OR id = 3 ; +id +1 +3 +SELECT id FROM t1 WHERE id NOT IN (SELECT MIN(id) FROM t1 +WHERE MATCH (a,b) AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE)) ; +id +2 +3 +4 +5 +6 +SELECT id FROM t1 WHERE EXISTS (SELECT t2.id FROM t1 AS t2 WHERE +MATCH (t2.a,t2.b) AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE) +AND t1.id = t2.id) ; +id +1 +3 +SELECT id FROM t1 WHERE NOT EXISTS (SELECT t2.id FROM t1 AS t2 WHERE +MATCH (t2.a,t2.b) AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE) +AND t1.id = t2.id) ; +id +2 +4 +5 +6 +DROP TABLE t1; +CREATE TABLE t1 ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +a VARCHAR(200), +b TEXT , +FULLTEXT (a,b) +) ENGINE = InnoDB; +INSERT INTO t1(a,b) VALUES('MySQL has now support', 'for full-text search'), +('Full-text indexes', 'are called collections'), +('Only MyISAM tables','support collections'), +('Function MATCH ... AGAINST()','is used to do a search'), +('Full-text search in MySQL', 'implements vector space model'); +SELECT id FROM t1 WHERE t1.id = (SELECT MAX(t2.id) FROM t1 AS t2 WHERE +MATCH(t2.a,t2.b) AGAINST("+support +collections" IN BOOLEAN MODE)); +id +3 +SELECT id FROM t1 WHERE t1.id != (SELECT MIN(t2.id) FROM t1 AS t2 WHERE +MATCH(t2.a,t2.b) AGAINST("+search" IN BOOLEAN MODE)); +id +2 +3 +4 +5 +SELECT id FROM t1 WHERE t1.id IN (SELECT t2.id FROM t1 AS t2 WHERE +MATCH (t2.a,t2.b) AGAINST ("+call* +coll*" IN BOOLEAN MODE)); +id +2 +SELECT id FROM t1 WHERE EXISTS (SELECT id FROM t1 AS t2 WHERE +MATCH t2.a,t2.b AGAINST ('"Now sUPPort"' IN BOOLEAN MODE) AND t2.id=t1.id); +id +1 +INSERT INTO t1 (a,b) VALUES ('test query expansion','for database ...'); +INSERT INTO t1 (a,b) VALUES +('test proximity search, test, proximity and phrase', +'search, with proximity innodb'); +INSERT INTO t1 (a,b) VALUES +('test proximity fts search, test, proximity and phrase', +'search, with proximity innodb'); +INSERT INTO t1 (a,b) VALUES +('test more proximity fts search, test, more proximity and phrase', +'search, with proximity innodb'); +SELECT id FROM t1 WHERE t1.id = (SELECT MAX(t2.id) FROM t1 AS t2 WHERE +MATCH(t2.a,t2.b) AGAINST ('"proximity search"@2' IN BOOLEAN MODE)); +id +7 +SELECT id FROM t1 WHERE t1.id > (SELECT MIN(t2.id) FROM t1 AS t2 WHERE +MATCH(t2.a,t2.b) AGAINST ('"proximity search"@2' IN BOOLEAN MODE)); +id +8 +9 +SELECT id FROM t1 WHERE t1.id IN (SELECT t2.id FROM t1 AS t2 WHERE +MATCH (t2.a,t2.b) AGAINST ('"proximity search"@2' IN BOOLEAN MODE)); +id +7 +SELECT id FROM t1 WHERE EXISTS (SELECT id FROM t1 AS t2 WHERE +MATCH t2.a,t2.b AGAINST ('"proximity search"@2' IN BOOLEAN MODE) +AND t2.id=t1.id); +id +7 +SELECT id FROM t1 WHERE EXISTS (SELECT id FROM t1 AS t2 WHERE +MATCH t2.a,t2.b AGAINST ('"more test proximity"@3' IN BOOLEAN MODE) +AND t2.id=t1.id); +id +9 +SELECT id FROM t1 WHERE EXISTS (SELECT id FROM t1 AS t2 WHERE +MATCH t2.a,t2.b AGAINST ('"more test proximity"@2' IN BOOLEAN MODE) +AND t2.id=t1.id); +id +CREATE TABLE t2 ENGINE = InnoDB AS SELECT id FROM t1 WHERE +MATCH a,b AGAINST ('support') ; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `id` int(10) unsigned NOT NULL DEFAULT 0 +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SELECT id FROM t2; +id +1 +3 +DROP TABLE t2; +CREATE TABLE t2 ENGINE = InnoDB AS SELECT id FROM t1 WHERE +MATCH a,b AGAINST("+support +collections" IN BOOLEAN MODE); +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `id` int(10) unsigned NOT NULL DEFAULT 0 +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SELECT id FROM t2; +id +3 +DROP TABLE t2; +CREATE TABLE t2 ENGINE = InnoDB AS SELECT id FROM t1 WHERE +MATCH a,b AGAINST ('"proximity search"@10' IN BOOLEAN MODE); +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `id` int(10) unsigned NOT NULL DEFAULT 0 +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SELECT id FROM t2; +id +7 +8 +9 +DROP TABLE t2; +DROP TABLE t1; +CREATE TABLE t1 ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +a VARCHAR(200), +b TEXT +) ENGINE = InnoDB; +CREATE FULLTEXT INDEX idx on t1 (a,b); +INSERT INTO t1 (a,b) VALUES +('MySQL from Tutorial','DBMS stands for DataBase ...'); +INSERT INTO t1 (a,b) VALUES +('when To Use MySQL Well','After that you went through a ...'); +INSERT INTO t1 (a,b) VALUES +('where will Optimizing MySQL','what In this tutorial we will show ...'); +INSERT INTO t1 (a,b) VALUES +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('MySQL vs. YourSQL','In the following database comparison ...'), +('MySQL Security','When configured properly, MySQL null...'); +SELECT COUNT(*) FROM t1; +COUNT(*) +106 +SELECT COUNT(*) FROM t1 WHERE a IS NULL; +COUNT(*) +100 +SELECT COUNT(*) FROM t1 WHERE b IS NOT NULL; +COUNT(*) +6 +SELECT id FROM t1 +WHERE MATCH (a,b) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); +id +1 +103 +SELECT id FROM t1 +WHERE MATCH (a,b) +AGAINST (NULL IN NATURAL LANGUAGE MODE); +id +SELECT id FROM t1 +WHERE MATCH (a,b) +AGAINST (NULL WITH QUERY EXPANSION); +id +SELECT id FROM t1 +WHERE MATCH (a,b) +AGAINST ('null' IN NATURAL LANGUAGE MODE); +id +106 +SELECT id FROM t1 WHERE MATCH (a,b) +AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE); +id +106 +1 +52 +103 +104 +SELECT id FROM t1 WHERE MATCH (a,b) +AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE) AND (a IS NOT NULL OR b IS NOT NULL); +id +106 +1 +52 +103 +104 +SELECT id FROM t1 WHERE MATCH (a,b) +AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE) AND (a IS NULL AND b IS NOT NULL); +id +SELECT id FROM t1 WHERE MATCH (a,b) +AGAINST ('DBMS Security' IN BOOLEAN MODE); +id +1 +106 +SELECT COUNT(*) FROM t1 +WHERE MATCH (a,b) +AGAINST ('database' WITH QUERY EXPANSION); +COUNT(*) +6 +SELECT id FROM t1 +WHERE MATCH (a,b) +AGAINST ('"following database"@10' IN BOOLEAN MODE); +id +105 +DROP TABLE t1; +drop table if exists t50; +set names utf8; +"----------Test1---------" +create table t50 (s1 varchar(60) character set utf8 collate utf8_bin) engine = innodb; +create fulltext index i on t50 (s1); +insert into t50 values ('ABCDE'),('FGHIJ'),('KLMNO'),('VÐƷWİ'); +select * from t50 where match(s1) against ('VÐƷWİ'); +s1 +VÐƷWİ +drop table t50; +"----------Test2---------" +create table t50 (s1 int unsigned primary key auto_increment, s2 +varchar(60) character set utf8) engine = innodb; +create fulltext index i on t50 (s2); +insert into t50 (s2) values ('FGHIJ'),('KLMNO'),('VÐƷWİ'),('ABCDE'); +select * from t50 order by s2; +s1 s2 +4 ABCDE +1 FGHIJ +2 KLMNO +3 VÐƷWİ +drop table t50; +"----------Test3---------" +create table t50 (id int unsigned primary key auto_increment, s2 +varchar(60) character set utf8) engine = innodb; +create fulltext index i on t50 (s2); +insert into t50 (s2) values ('FGHIJ'),('KLMNO'),('VÐƷWİ'),('ABCDE'); +set @@autocommit=0; +update t50 set s2 = lower(s2); +update t50 set s2 = upper(s2); +commit; +select * from t50 where match(s2) against ('VÐƷWİ FGHIJ KLMNO ABCDE' in boolean mode); +id s2 +1 FGHIJ +2 KLMNO +3 VÐƷWI +4 ABCDE +select * from t50; +id s2 +1 FGHIJ +2 KLMNO +3 VÐƷWI +4 ABCDE +drop table t50; +set @@autocommit=1; +"----------Test4---------" +create table t50 (id int unsigned primary key auto_increment, s2 +varchar(60) character set utf8) engine = innodb; +create fulltext index i on t50 (s2); +insert into t50 (s2) values ('FGHIJ'),('KLMNO'),('VÐƷWİ'),('ABCD*'); +select * from t50 where match(s2) against ('abcd*' in natural language +mode); +id s2 +4 ABCD* +select * from t50 where match(s2) against ('abcd*' in boolean mode); +id s2 +4 ABCD* +drop table t50; +"----------Test5---------" +create table t50 (s1 int, s2 varchar(200), fulltext key(s2)) engine = innodb; +set @@autocommit=0; +insert into t50 values (1,'Sunshine'),(2,'Lollipops'); +select * from t50 where match(s2) against('Rainbows'); +s1 s2 +rollback; +select * from t50; +s1 s2 +drop table t50; +set @@autocommit=1; +"----------Test6---------" +CREATE TABLE t1 ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +a VARCHAR(200), +b TEXT +) ENGINE = InnoDB; +INSERT INTO t1 (a,b) VALUES +('aab` MySQL Tutorial','DBMS stands for DataBase ...') , +('aas How To Use MySQL Well','After you went through a ...'), +('aac Optimizing MySQL','In this tutorial we will show ...'); +INSERT INTO t1 (a,b) VALUES +('aac 1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('aab MySQL vs. YourSQL','In the following database comparison ...'), +('aaa MySQL Security','When configured properly, MySQL ...'); +ALTER TABLE t1 ADD FULLTEXT INDEX idx (a,b); +SELECT * FROM t1 ORDER BY MATCH(a,b) AGAINST ('aac') DESC; +id a b +3 aac Optimizing MySQL In this tutorial we will show ... +4 aac 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +1 aab` MySQL Tutorial DBMS stands for DataBase ... +2 aas How To Use MySQL Well After you went through a ... +5 aab MySQL vs. YourSQL In the following database comparison ... +6 aaa MySQL Security When configured properly, MySQL ... +SELECT * FROM t1 ORDER BY MATCH(a,b) AGAINST ('aab') DESC; +id a b +1 aab` MySQL Tutorial DBMS stands for DataBase ... +5 aab MySQL vs. YourSQL In the following database comparison ... +2 aas How To Use MySQL Well After you went through a ... +3 aac Optimizing MySQL In this tutorial we will show ... +4 aac 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +6 aaa MySQL Security When configured properly, MySQL ... +"----------Test7---------" +select * from t1 where match(a,b) against ('aaa') +union select * from t1 where match(a,b) against ('aab') +union select * from t1 where match(a,b) against ('aac'); +id a b +6 aaa MySQL Security When configured properly, MySQL ... +1 aab` MySQL Tutorial DBMS stands for DataBase ... +5 aab MySQL vs. YourSQL In the following database comparison ... +3 aac Optimizing MySQL In this tutorial we will show ... +4 aac 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +select * from t1 where match(a,b) against ('aaa') +or match(a,b) against ('aab') +or match(a,b) against ('aac'); +id a b +1 aab` MySQL Tutorial DBMS stands for DataBase ... +3 aac Optimizing MySQL In this tutorial we will show ... +4 aac 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +5 aab MySQL vs. YourSQL In the following database comparison ... +6 aaa MySQL Security When configured properly, MySQL ... +DROP TABLE t1; +"----------Test8---------" +CREATE TABLE t1 ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +a VARCHAR(200), +b TEXT +) ENGINE = InnoDB; +INSERT INTO t1 (a,b) VALUES +('MySQL Tutorial','DBMS stands for DataBase ... abcd') , +('How To Use MySQL Well','After you went through a q ...abdd'), +('Optimizing MySQL','In this tutorial we will show ...abed'); +ALTER TABLE t1 ADD FULLTEXT INDEX idx (a,b); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `a` varchar(200) DEFAULT NULL, + `b` text DEFAULT NULL, + PRIMARY KEY (`id`), + FULLTEXT KEY `idx` (`a`,`b`) +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +INSERT INTO t1 (a,b) VALUES +('1001 MySQL Tricks','1. Never run mysqld as root. 2. q ...'), +('MySQL vs. YourSQL use','In the following database comparison ...'), +('MySQL Security','When run configured properly, MySQL ...'); +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ('run'); +id a b +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. q ... +6 MySQL Security When run configured properly, MySQL ... +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ('use'); +id a b +2 How To Use MySQL Well After you went through a q ...abdd +5 MySQL vs. YourSQL use In the following database comparison ... +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ('went'); +id a b +2 How To Use MySQL Well After you went through a q ...abdd +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ('run') AND NOT MATCH(a,b) AGAINST ('q'); +id a b +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. q ... +6 MySQL Security When run configured properly, MySQL ... +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ('use') AND NOT MATCH(a,b) AGAINST ('q'); +id a b +2 How To Use MySQL Well After you went through a q ...abdd +5 MySQL vs. YourSQL use In the following database comparison ... +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ('went') AND NOT MATCH(a,b) AGAINST ('q'); +id a b +2 How To Use MySQL Well After you went through a q ...abdd +"----------Test9---------" +CREATE TABLE t2 AS SELECT * FROM t1; +ALTER TABLE t2 ENGINE=MYISAM; +CREATE FULLTEXT INDEX i ON t2 (a,b); +SET @x = (SELECT COUNT(*) FROM t1 WHERE MATCH(a,b) AGAINST ('run')); +SET @x = @x + (SELECT COUNT(*) FROM t1 WHERE MATCH(a,b) AGAINST ('use')); +SET @x = @x + (SELECT COUNT(*) FROM t1 WHERE MATCH(a,b) AGAINST ('went')); +SET @x = @x + (SELECT COUNT(*) FROM t1 WHERE MATCH(a,b) AGAINST ('run')); +SET @x2 = (SELECT COUNT(*) FROM t2 WHERE MATCH(a,b) AGAINST ('run')); +SET @x2 = @x2 + (SELECT COUNT(*) FROM t2 WHERE MATCH(a,b) AGAINST ('use')); +SET @x2 = @x2 + (SELECT COUNT(*) FROM t2 WHERE MATCH(a,b) AGAINST ('went')); +SET @x2 = @x2 + (SELECT COUNT(*) FROM t2 WHERE MATCH(a,b) AGAINST ('run')); +SELECT @x, @x2; +@x @x2 +7 0 +DROP TABLE t2; +"----------Test10---------" +CREATE TABLE t2 AS SELECT * FROM t1; +ALTER TABLE t2 ENGINE=MYISAM; +CREATE FULLTEXT INDEX i ON t2 (a,b); +SELECT COUNT(*) FROM t2 WHERE MATCH(a,b) AGAINST ('abc*' IN BOOLEAN MODE); +COUNT(*) +1 +SELECT COUNT(*) FROM t1 WHERE MATCH(a,b) AGAINST ('abc*' IN BOOLEAN MODE); +COUNT(*) +1 +DROP TABLE t2; +"----------Test11---------" +CREATE TABLE t2 AS SELECT * FROM t1; +ALTER TABLE t2 ENGINE = MYISAM; +CREATE FULLTEXT INDEX i ON t2 (a,b); +ALTER TABLE t2 ENGINE=InnoDB; +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ('run'); +id a b +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. q ... +6 MySQL Security When run configured properly, MySQL ... +SELECT COUNT(*) FROM t2 WHERE MATCH(a,b) AGAINST ('abc*' IN BOOLEAN MODE); +COUNT(*) +1 +DROP TABLE t2,t1; +"----------Test13---------" +set names utf8; +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200) CHARACTER SET UTF8 COLLATE UTF8_SPANISH_CI) ENGINE = InnoDB; +CREATE FULLTEXT INDEX i ON t1 (s2); +INSERT INTO t1 VALUES (1,'aaCen'),(2,'aaCha'),(3,'aaCio'),(4,'aaçen'),(5,'aaçha'),(6,'aaçio'); +SELECT * FROM t1 WHERE MATCH(s2) AGAINST ('aach*' IN BOOLEAN MODE); +s1 s2 +2 aaCha +5 aaçha +SELECT * FROM t1 WHERE MATCH(s2) AGAINST ('aaC*' IN BOOLEAN MODE); +s1 s2 +1 aaCen +2 aaCha +3 aaCio +4 aaçen +5 aaçha +6 aaçio +DROP TABLE t1; +"----------Test14---------" +CREATE TABLE t1(s1 INT , s2 VARCHAR(100) CHARACTER SET sjis) ENGINE = InnoDB; +CREATE FULLTEXT INDEX i ON t1 (s2); +INSERT INTO t1 VALUES (1,'ペペペ'),(2,'テテテ'),(3,'ルルル'),(4,'グググ'); +DROP TABLE t1; +"----------Test15---------" +CREATE TABLE t1 (s1 VARCHAR (60) CHARACTER SET UTF8 COLLATE UTF8_UNICODE_520_CI) ENGINE = MyISAM; +CREATE FULLTEXT INDEX i ON t1 (s1); +INSERT INTO t1 VALUES +('a'),('b'),('c'),('d'),('ŁŁŁŁ'),('LLLL'),(NULL),('ŁŁŁŁ ŁŁŁŁ'),('LLLLLLLL'); +SELECT * FROM t1 WHERE MATCH(s1) AGAINST ('LLLL' COLLATE UTF8_UNICODE_520_CI); +s1 +ŁŁŁŁ +LLLL +ŁŁŁŁ ŁŁŁŁ +DROP TABLE if EXISTS t2; +Warnings: +Note 1051 Unknown table 'test.t2' +CREATE TABLE t2 (s1 VARCHAR(60) CHARACTER SET UTF8 COLLATE UTF8_POLISH_CI) ENGINE = InnoDB; +CREATE FULLTEXT INDEX i ON t2 ( s1); +INSERT INTO t2 VALUES +('a'),('b'),('c'),('d'),('ŁŁŁŁ'),('LLLL'),(NULL),('ŁŁŁŁ ŁŁŁŁ'),('LLLLLLLL'); +SELECT * FROM t2 WHERE MATCH(s1) AGAINST ('LLLL' COLLATE UTF8_UNICODE_520_CI); +s1 +LLLL +DROP TABLE t1,t2; +"----------Test16---------" +CREATE TABLE t1 (s1 INT, s2 VARCHAR(50) CHARACTER SET UTF8) ENGINE = InnoDB; +CREATE FULLTEXT INDEX i ON t1(s2); +INSERT INTO t1 VALUES (2, 'ğė Daśi p '); +SELECT * FROM t1 WHERE MATCH(s2) AGAINST ('+p +"ğė Daśi*"' IN BOOLEAN MODE); +s1 s2 +DROP TABLE t1; +"----------Test19---------" +CREATE TABLE t1 ( id INT , char_column VARCHAR(60) CHARACTER SET UTF8) ENGINE = InnoDB; +INSERT INTO t1 VALUES (1,'İóëɠ'); +CREATE FULLTEXT INDEX i ON t1 (char_column); +SELECT * FROM t1 WHERE MATCH(char_column) AGAINST ('"İóëɠ"' IN BOOLEAN MODE); +id char_column +1 İóëɠ +DROP TABLE t1; +"----------Test20---------" +CREATE TABLE t1 ( id INT , char_column VARCHAR(60) CHARACTER SET UTF32, char_column2 VARCHAR(60) character set utf8) ENGINE = InnoDB; +INSERT INTO t1 (char_column) VALUES ('abcde'),('fghij'),('klmno'),('qrstu'); +UPDATE t1 SET char_column2 = char_column; +CREATE FULLTEXT INDEX i ON t1 (char_column2); +SELECT * FROM t1 WHERE MATCH(char_column) AGAINST ('abc*' IN BOOLEAN MODE); +ERROR HY000: Can't find FULLTEXT index matching the column list +DROP TABLE t1; +"----------Test22---------" +CREATE TABLE t1 ( id INT , char_column VARCHAR(60) CHARACTER SET UTF8) ENGINE = InnoDB; +INSERT INTO t1 VALUES (1,'aaa'),(2,'bbb'),(3,'ccc'); +CREATE FULLTEXT INDEX i ON t1 (char_column); +HANDLER t1 OPEN; +HANDLER t1 READ i = ('aaa'); +ERROR HY000: FULLTEXT index `i` does not support this operation +DROP TABLE t1; +"----------Test25---------" +CREATE TABLE t1 ( id INT , char_column VARCHAR(60) CHARACTER SET UTF8 COLLATE UTF8_CROATIAN_CI) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,'LJin'),(2,'ljin'),(3,'lmin'),(4,'LJLJLJLJLJ'); +CREATE FULLTEXT INDEX i ON t1 (char_column); +SELECT count(*) FROM t1 WHERE MATCH (char_column) AGAINST ('lj*' IN BOOLEAN MODE); +count(*) +3 +DROP TABLE t1; +"----------Test27---------" +CREATE TABLE t1 (id INT,char_column VARCHAR(60)) ENGINE=InnoDB; +SET @@autocommit=0; +CREATE FULLTEXT INDEX i ON t1 (char_column); +INSERT INTO t1 values (1,'aaa'); +"restart server..." +# Restart the server +--source include/restart_mysqld.inc +DELETE FROM t1 WHERE MATCH(char_column) AGAINST ('bbb') +SET @@autocommit=1; +DROP TABLE t1; +"----------Test28---------" +drop table if exists `fts_test`; +Warnings: +Note 1051 Unknown table 'test.fts_test' +create table `fts_test`(`a` text,fulltext key(`a`))engine=innodb; +set session autocommit=0; +insert into `fts_test` values (''); +savepoint `b`; +savepoint `b`; +set session autocommit=1; +DROP TABLE fts_test; +"----------Test29---------" +CREATE TABLE articles ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), +body TEXT, +FULLTEXT (title,body) +) ENGINE=InnoDB; +INSERT INTO articles (title,body) VALUES +('MySQL Tutorial','DBMS stands for DataBase ...'); +start transaction; +INSERT INTO articles (title,body) VALUES +('How To Use MySQL Well','After you went through a ...'); +savepoint `a1`; +INSERT INTO articles (title,body) VALUES +('Optimizing MySQL','In this tutorial we will show ...'); +savepoint `a2`; +INSERT INTO articles (title,body) VALUES +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'); +savepoint `a3`; +INSERT INTO articles (title,body) VALUES +('MySQL vs. YourSQL','In the following database comparison ...'); +savepoint `a4`; +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('Database' IN NATURAL LANGUAGE MODE); +id title body +1 MySQL Tutorial DBMS stands for DataBase ... +rollback to savepoint a3; +select title, body from articles; +title body +MySQL Tutorial DBMS stands for DataBase ... +How To Use MySQL Well After you went through a ... +Optimizing MySQL In this tutorial we will show ... +1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +INSERT INTO articles (title,body) VALUES +('MySQL Security','When configured properly, MySQL ...'); +savepoint `a5`; +select title, body from articles; +title body +MySQL Tutorial DBMS stands for DataBase ... +How To Use MySQL Well After you went through a ... +Optimizing MySQL In this tutorial we will show ... +1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +MySQL Security When configured properly, MySQL ... +rollback to savepoint a2; +select title, body from articles; +title body +MySQL Tutorial DBMS stands for DataBase ... +How To Use MySQL Well After you went through a ... +Optimizing MySQL In this tutorial we will show ... +commit; +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('Database' IN NATURAL LANGUAGE MODE); +id title body +1 MySQL Tutorial DBMS stands for DataBase ... +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); +id title body +1 MySQL Tutorial DBMS stands for DataBase ... +3 Optimizing MySQL In this tutorial we will show ... +DROP TABLE articles; +"----------Test30---------" +CREATE TABLE articles ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), +body TEXT, +FULLTEXT (title,body) +) ENGINE=InnoDB; +INSERT INTO articles (title,body) VALUES +('MySQL Tutorial','DBMS stands for DataBase ...'); +start transaction; +INSERT INTO articles (title,body) VALUES +('How To Use MySQL Well','After you went through a ...'); +savepoint `a1`; +INSERT INTO articles (title,body) VALUES +('Optimizing MySQL','In this tutorial we will show ...'); +savepoint `a2`; +INSERT INTO articles (title,body) VALUES +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'); +savepoint `a3`; +INSERT INTO articles (title,body) VALUES +('MySQL vs. YourSQL','In the following database comparison ...'); +savepoint `a4`; +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('Database' IN NATURAL LANGUAGE MODE); +id title body +1 MySQL Tutorial DBMS stands for DataBase ... +rollback to savepoint a3; +select title, body from articles; +title body +MySQL Tutorial DBMS stands for DataBase ... +How To Use MySQL Well After you went through a ... +Optimizing MySQL In this tutorial we will show ... +1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +INSERT INTO articles (title,body) VALUES +('MySQL Security','When configured properly, MySQL ...'); +savepoint `a5`; +select title, body from articles; +title body +MySQL Tutorial DBMS stands for DataBase ... +How To Use MySQL Well After you went through a ... +Optimizing MySQL In this tutorial we will show ... +1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +MySQL Security When configured properly, MySQL ... +rollback to savepoint a2; +select title, body from articles; +title body +MySQL Tutorial DBMS stands for DataBase ... +How To Use MySQL Well After you went through a ... +Optimizing MySQL In this tutorial we will show ... +rollback; +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('Database' IN NATURAL LANGUAGE MODE); +id title body +1 MySQL Tutorial DBMS stands for DataBase ... +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); +id title body +1 MySQL Tutorial DBMS stands for DataBase ... +DROP TABLE articles; +CREATE TABLE articles ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), +body TEXT, +FULLTEXT (title,body) +) ENGINE=InnoDB; +INSERT INTO articles (title,body) VALUES +('MySQL Tutorial','DBMS stands for DataBase ...') , +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'), +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('MySQL vs. YourSQL','In the following database comparison ...'), +('MySQL Security','When configured properly, MySQL ...'); +ANALYZE TABLE articles; +SELECT *, MATCH(title, body) AGAINST ('-database +MySQL' IN BOOLEAN MODE) AS score from articles; +id title body score +1 MySQL Tutorial DBMS stands for DataBase ... 0 +2 How To Use MySQL Well After you went through a ... 0.000000001885928302414186 +3 Optimizing MySQL In this tutorial we will show ... 0.000000001885928302414186 +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... 0.000000001885928302414186 +5 MySQL vs. YourSQL In the following database comparison ... 0 +6 MySQL Security When configured properly, MySQL ... 0.000000003771856604828372 +SELECT *, MATCH(title, body) AGAINST ('+MySQL -database' IN BOOLEAN MODE) AS score FROM articles; +id title body score +1 MySQL Tutorial DBMS stands for DataBase ... 0 +2 How To Use MySQL Well After you went through a ... 0.000000001885928302414186 +3 Optimizing MySQL In this tutorial we will show ... 0.000000001885928302414186 +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... 0.000000001885928302414186 +5 MySQL vs. YourSQL In the following database comparison ... 0 +6 MySQL Security When configured properly, MySQL ... 0.000000003771856604828372 +SELECT * FROM articles where MATCH(title, body) AGAINST ('MySQL - (database - tutorial)' IN BOOLEAN MODE); +id title body +6 MySQL Security When configured properly, MySQL ... +1 MySQL Tutorial DBMS stands for DataBase ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +SELECT * FROM articles where MATCH(title, body) AGAINST ('MySQL - (- tutorial database)' IN BOOLEAN MODE); +id title body +6 MySQL Security When configured properly, MySQL ... +1 MySQL Tutorial DBMS stands for DataBase ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +SELECT * FROM articles where MATCH(title, body) AGAINST ('MySQL - (- tutorial database) -Tricks' IN BOOLEAN MODE); +id title body +6 MySQL Security When configured properly, MySQL ... +1 MySQL Tutorial DBMS stands for DataBase ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +SELECT * FROM articles where MATCH(title, body) AGAINST ('-Tricks MySQL - (- tutorial database)' IN BOOLEAN MODE); +id title body +6 MySQL Security When configured properly, MySQL ... +1 MySQL Tutorial DBMS stands for DataBase ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +DROP TABLE articles; +drop table if exists t1; +Warnings: +Note 1051 Unknown table 'test.t1' +create table t1 (FTS_DOC_ID bigint unsigned auto_increment not null primary key, +title varchar(200),body text,fulltext(title,body)) engine=innodb; +insert into t1 set body='test'; +select * from t1 where match(title,body) against('%test'); +FTS_DOC_ID title body +1 NULL test +select * from t1 where match(title,body) against('%'); +FTS_DOC_ID title body +select * from t1 where match(title,body) against('%%%%'); +FTS_DOC_ID title body +drop table t1; +CREATE DATABASE `benu database`; +USE `benu database`; +CREATE TABLE t1 ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +a VARCHAR(200), +b TEXT +) ENGINE = InnoDB; +INSERT INTO t1 (a,b) VALUES +('MySQL Tutorial','DBMS stands for DataBase ...') , +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'); +ALTER TABLE t1 ADD FULLTEXT INDEX idx (a,b); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `a` varchar(200) DEFAULT NULL, + `b` text DEFAULT NULL, + PRIMARY KEY (`id`), + FULLTEXT KEY `idx` (`a`,`b`) +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +INSERT INTO t1 (a,b) VALUES +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('MySQL vs. YourSQL','In the following database comparison ...'), +('MySQL Security','When configured properly, MySQL ...'); +SELECT id FROM t1 WHERE MATCH (a,b) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); +id +1 +3 +select id from t1 where MATCH(a,b) AGAINST("+support +collections" IN BOOLEAN MODE); +id +select id from t1 where MATCH(a,b) AGAINST("+search" IN BOOLEAN MODE); +id +select id from t1 where MATCH(a,b) AGAINST("+search +(support vector)" IN BOOLEAN MODE); +id +select id from t1 where MATCH(a,b) AGAINST("+search -(support vector)" IN BOOLEAN MODE); +id +select id, MATCH(a,b) AGAINST("support collections" IN BOOLEAN MODE) as x from t1; +id x +1 0 +2 0 +3 0 +4 0 +5 0 +6 0 +select id, MATCH(a,b) AGAINST("collections support" IN BOOLEAN MODE) as x from t1; +id x +1 0 +2 0 +3 0 +4 0 +5 0 +6 0 +select id from t1 where MATCH a,b AGAINST ("+call* +coll*" IN BOOLEAN MODE); +id +select id from t1 where MATCH a,b AGAINST ('"support now"' IN BOOLEAN MODE); +id +select id from t1 where MATCH a,b AGAINST ('"Now sUPPort"' IN BOOLEAN MODE); +id +DROP DATABASE `benu database`; +USE test; +CREATE TABLE `t21` (`a` text, `b` int not null, +fulltext key (`a`), fulltext key (`a`) +) ENGINE=INNODB DEFAULT CHARSET=LATIN1; +Warnings: +Note 1831 Duplicate index `a_2`. This is deprecated and will be disallowed in a future release +ALTER TABLE `t21` ADD UNIQUE INDEX (`b`), ALGORITHM=INPLACE; +ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: InnoDB presently supports one FULLTEXT index creation at a time. Try ALGORITHM=COPY +ALTER TABLE `t21` ADD UNIQUE INDEX (`b`); +DROP TABLE t21; +CREATE TABLE `t21` (`a` text, `b` int not null, +fulltext key (`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1; +ALTER TABLE `t21` ADD UNIQUE INDEX (`b`); +DROP TABLE t21; +CREATE TABLE t1 ( +id INT NOT NULL, +a VARCHAR(200), +b TEXT +) ENGINE = InnoDB; +INSERT INTO t1 VALUES +(1, 'MySQL Tutorial','DBMS stands for DataBase ...') , +(2, 'How To Use MySQL Well','After you went through a ...'), +(3, 'Optimizing MySQL','In this tutorial we will show ...'); +ALTER TABLE t1 ADD FULLTEXT INDEX idx (a,b); +ALTER TABLE t1 ADD UNIQUE INDEX (`id`); +SELECT id FROM t1 WHERE MATCH (a,b) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); +id +1 +3 +select id from t1 where MATCH(a,b) AGAINST("+support +collections" IN BOOLEAN MODE); +id +select id from t1 where MATCH(a,b) AGAINST("+search" IN BOOLEAN MODE); +id +select id from t1 where MATCH(a,b) AGAINST("+search +(support vector)" IN BOOLEAN MODE); +id +select id from t1 where MATCH(a,b) AGAINST("+search -(support vector)" IN BOOLEAN MODE); +id +select id, MATCH(a,b) AGAINST("support collections" IN BOOLEAN MODE) as x from t1; +id x +1 0 +2 0 +3 0 +DROP TABLE t1; +CREATE TABLE t1 ( +id INT NOT NULL, +a VARCHAR(200), +b TEXT +) ENGINE = InnoDB; +INSERT INTO t1 VALUES +(1, 'MySQL Tutorial','DBMS stands for DataBase ...') , +(2, 'How To Use MySQL Well','After you went through a ...'), +(3, 'Optimizing MySQL','In this tutorial we will show ...'); +ALTER TABLE t1 ADD UNIQUE INDEX (`id`), ADD FULLTEXT INDEX idx (a,b); +SELECT id FROM t1 WHERE MATCH (a,b) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); +id +1 +3 +select id from t1 where MATCH(a,b) AGAINST("+support +collections" IN BOOLEAN MODE); +id +select id from t1 where MATCH(a,b) AGAINST("+search" IN BOOLEAN MODE); +id +select id from t1 where MATCH(a,b) AGAINST("+search +(support vector)" IN BOOLEAN MODE); +id +select id from t1 where MATCH(a,b) AGAINST("+search -(support vector)" IN BOOLEAN MODE); +id +DROP TABLE t1; +CREATE TABLE t1 ( +FTS_DOC_ID BIGINT UNSIGNED NOT NULL, +a VARCHAR(200), +b TEXT +) ENGINE = InnoDB; +INSERT INTO t1 VALUES +(1, 'MySQL Tutorial','DBMS stands for DataBase ...') , +(2, 'How To Use MySQL Well','After you went through a ...'), +(3, 'Optimizing MySQL','In this tutorial we will show ...'); +ALTER TABLE t1 ADD FULLTEXT INDEX idx (a,b); +ALTER TABLE t1 ADD UNIQUE INDEX (`FTS_DOC_ID`); +SELECT FTS_DOC_ID FROM t1 WHERE MATCH (a,b) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); +FTS_DOC_ID +1 +3 +select FTS_DOC_ID from t1 where MATCH(a,b) AGAINST("+support +collections" IN BOOLEAN MODE); +FTS_DOC_ID +select FTS_DOC_ID from t1 where MATCH(a,b) AGAINST("+search" IN BOOLEAN MODE); +FTS_DOC_ID +select FTS_DOC_ID from t1 where MATCH(a,b) AGAINST("+search +(support vector)" IN BOOLEAN MODE); +FTS_DOC_ID +select FTS_DOC_ID from t1 where MATCH(a,b) AGAINST("+search -(support vector)" IN BOOLEAN MODE); +FTS_DOC_ID +select FTS_DOC_ID, MATCH(a,b) AGAINST("support collections" IN BOOLEAN MODE) as x from t1; +FTS_DOC_ID x +1 0 +2 0 +3 0 +DROP TABLE t1; +CREATE TABLE t1 ( +FTS_DOC_ID BIGINT UNSIGNED NOT NULL, +a VARCHAR(200), +b TEXT +) ENGINE = InnoDB; +INSERT INTO t1 VALUES +(1, 'MySQL Tutorial','DBMS stands for DataBase ...') , +(2, 'How To Use MySQL Well','After you went through a ...'), +(3, 'Optimizing MySQL','In this tutorial we will show ...'); +ALTER TABLE t1 ADD FULLTEXT INDEX idx (a,b), ADD UNIQUE INDEX FTS_DOC_ID_INDEX (FTS_DOC_ID); +SELECT FTS_DOC_ID FROM t1 WHERE MATCH (a,b) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); +FTS_DOC_ID +1 +3 +select FTS_DOC_ID from t1 where MATCH(a,b) AGAINST("+support +collections" IN BOOLEAN MODE); +FTS_DOC_ID +select FTS_DOC_ID from t1 where MATCH(a,b) AGAINST("+search" IN BOOLEAN MODE); +FTS_DOC_ID +select FTS_DOC_ID from t1 where MATCH(a,b) AGAINST("+search +(support vector)" IN BOOLEAN MODE); +FTS_DOC_ID +select FTS_DOC_ID from t1 where MATCH(a,b) AGAINST("+search -(support vector)" IN BOOLEAN MODE); +FTS_DOC_ID +select FTS_DOC_ID, MATCH(a,b) AGAINST("support collections" IN BOOLEAN MODE) as x from t1; +FTS_DOC_ID x +1 0 +2 0 +3 0 +DROP TABLE t1; +CREATE TABLE t2 (`b` char(2),fulltext(`b`)) ENGINE=INNODB +DEFAULT CHARSET=LATIN1; +CREATE TABLE t3 LIKE t2; +INSERT INTO `t2` VALUES(); +COMMIT WORK AND CHAIN; +INSERT INTO `t3` VALUES (); +UPDATE `t2` SET `b` = 'a'; +SAVEPOINT BATCH1; +DROP TABLE t2; +DROP TABLE t3; +CREATE TABLE t1 ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +a VARCHAR(200), +b TEXT +) ENGINE = InnoDB; +INSERT INTO t1 (a,b) VALUES +('MySQL Tutorial','DBMS stands for DataBase ...') , +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'); +ALTER TABLE t1 ADD FULLTEXT INDEX idx (a,b); +COMMIT WORK AND CHAIN; +INSERT INTO t1 (a,b) VALUES +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('MySQL vs. YourSQL','In the following database comparison ...'), +('MySQL Security','When configured properly, MySQL ...'); +SAVEPOINT BATCH1; +SELECT id FROM t1 WHERE MATCH (a,b) +AGAINST ('MySQL' IN NATURAL LANGUAGE MODE); +id +1 +2 +3 +INSERT INTO t1 (a,b) VALUES +('1002 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('MySQL vs. YourSQL','In the following database comparison ...'), +('MySQL Security','When configured properly, MySQL ...'); +ROLLBACK TO SAVEPOINT BATCH1; +COMMIT; +SELECT id FROM t1 WHERE MATCH (a,b) +AGAINST ('MySQL' IN NATURAL LANGUAGE MODE); +id +6 +1 +2 +3 +4 +5 +DROP TABLE t1; +CREATE TABLE `t` (`a` char(20) character set utf8 default null, +fulltext key (`a`)) ENGINE=INNODB; +INSERT INTO `t` VALUES ('a'); +INSERT INTO `t` VALUES ('aaa'); +SELECT MATCH(`a`) AGAINST (0x22dd22) FROM `t`; +MATCH(`a`) AGAINST (0x22dd22) +0 +0 +SELECT MATCH(`a`) AGAINST (0x2222) FROM `t`; +MATCH(`a`) AGAINST (0x2222) +0 +0 +SELECT MATCH(`a`) AGAINST (0x22) FROM `t`; +MATCH(`a`) AGAINST (0x22) +0 +0 +SELECT MATCH(`a`) AGAINST (0x2261616122) FROM `t`; +MATCH(`a`) AGAINST (0x2261616122) +0 +0.0906190574169159 +SELECT MATCH(`a`) AGAINST (0x2261dd6122) FROM `t`; +MATCH(`a`) AGAINST (0x2261dd6122) +0 +0 +SELECT MATCH(`a`) AGAINST (0x2261dd612222226122) FROM `t`; +MATCH(`a`) AGAINST (0x2261dd612222226122) +0 +0 +DROP TABLE t; +CREATE TABLE t(a CHAR(1),FULLTEXT KEY(a)) ENGINE=INNODB; +HANDLER t OPEN; +HANDLER t READ a NEXT; +a +HANDLER t READ a PREV; +a +DROP TABLE t; +CREATE TABLE `%`(a TEXT, FULLTEXT INDEX(a)) ENGINE=INNODB; +CREATE TABLE `A B`(a TEXT, FULLTEXT INDEX(a)) ENGINE=INNODB; +DROP TABLE `%`; +DROP TABLE `A B`; +CREATE TABLE `t-26`(a VARCHAR(10),FULLTEXT KEY(a)) ENGINE=INNODB; +INSERT INTO `t-26` VALUES('117'); +DROP TABLE `t-26`; +CREATE TABLE `t1` ( +`id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, +`content` TEXT NOT NULL, +PRIMARY KEY (`id`), +FULLTEXT INDEX `IDX_CONTEXT_FULLTEXT`(`content`) +) +ENGINE = InnoDB; +insert into t1 (content) +values +('This is a story which has has a complicated phrase structure here in the +middle'), +('This is a story which doesn''t have that text'), +('This is a story that has complicated the phrase structure'); +select * from t1 +where match(content) against('"complicated phrase structure"' in boolean +mode); +id content +1 This is a story which has has a complicated phrase structure here in the +middle +select * from t1 +where match(content) against('+"complicated phrase structure"' in boolean +mode); +id content +1 This is a story which has has a complicated phrase structure here in the +middle +select * from t1 +where match(content) against('"complicated the phrase structure"' in boolean +mode); +id content +3 This is a story that has complicated the phrase structure +select * from t1 where match(content) against('+"this is a story which" +"complicated the phrase structure"' in boolean mode); +id content +select * from t1 where match(content) against('"the complicated the phrase structure"' in boolean mode); +id content +3 This is a story that has complicated the phrase structure +select * from t1 where match(content) against('"complicated a phrase structure"' in boolean mode); +id content +DROP TABLE t1; +CREATE TABLE my (id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, +c VARCHAR(32), FULLTEXT(c)) ENGINE = INNODB; +INSERT INTO my (c) VALUES ('green-iguana'); +SELECT * FROM my WHERE MATCH(c) AGAINST ('green-iguana'); +id c +1 green-iguana +DROP TABLE my; +CREATE TABLE ift ( +`a` int(11) NOT NULL, +`b` text, +PRIMARY KEY (`a`), +FULLTEXT KEY `b` (`b`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +INSERT INTO ift values (1, "skip"); +INSERT INTO ift values (2, "skip and networking"); +INSERT INTO ift values (3, "--skip-networking"); +INSERT INTO ift values (4, "-donot--skip-networking"); +SELECT * FROM ift WHERE MATCH (b) AGAINST ('--skip-networking'); +a b +2 skip and networking +3 --skip-networking +4 -donot--skip-networking +1 skip +SELECT * FROM ift WHERE MATCH (b) AGAINST ('skip-networking'); +a b +2 skip and networking +3 --skip-networking +4 -donot--skip-networking +1 skip +SELECT * FROM ift WHERE MATCH (b) AGAINST ('----'); +a b +SELECT * FROM ift WHERE MATCH (b) AGAINST ('-donot--skip-networking'); +a b +4 -donot--skip-networking +2 skip and networking +3 --skip-networking +1 skip +DROP TABLE ift; +CREATE TABLE articles ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), +body TEXT, +FULLTEXT (title,body) +) ENGINE=InnoDB; +INSERT INTO articles (title,body) VALUES +('MySQL Tutorial','DBMS stands for DataBase ...') , +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'), +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('MySQL vs. YourSQL','In the following database comparison ...'), +('( that''s me )','When configured properly, MySQL ...'); +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('( yours''s* )' IN BOOLEAN MODE); +id title body +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('s*' IN BOOLEAN MODE); +id title body +1 MySQL Tutorial DBMS stands for DataBase ... +3 Optimizing MySQL In this tutorial we will show ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('stands\'] | * | show[@database' IN NATURAL LANGUAGE MODE); +id title body +1 MySQL Tutorial DBMS stands for DataBase ... +3 Optimizing MySQL In this tutorial we will show ... +5 MySQL vs. YourSQL In the following database comparison ... +DROP TABLE articles; +CREATE TABLE t1(a TEXT CHARACTER SET LATIN1, FULLTEXT INDEX(a)) ENGINE=INNODB; +SELECT * FROM t1 WHERE MATCH(a) AGAINST("*"); +ERROR 42000: syntax error, unexpected $end, expecting FTS_TERM or FTS_NUMB or '*' +DROP TABLE t1; +CREATE TABLE t1 ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +a VARCHAR(200), +FULLTEXT (a) +) ENGINE= InnoDB; +INSERT INTO t1 (a) VALUES +('Do you know MySQL is a good database'), +('How to build a good database'), +('Do you know'), +('Do you know MySQL'), +('How to use MySQL'), +('Do you feel good'), +('MySQL is good'), +('MySQL is good to know'), +('What is database'); +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+"know mysql"' IN BOOLEAN MODE); +id a +1 Do you know MySQL is a good database +4 Do you know MySQL +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+("know mysql")' IN BOOLEAN MODE); +id a +1 Do you know MySQL is a good database +4 Do you know MySQL +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('("know mysql" good)' IN BOOLEAN MODE); +id a +1 Do you know MySQL is a good database +4 Do you know MySQL +2 How to build a good database +6 Do you feel good +7 MySQL is good +8 MySQL is good to know +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+("know mysql" good)' IN BOOLEAN MODE); +id a +1 Do you know MySQL is a good database +4 Do you know MySQL +2 How to build a good database +6 Do you feel good +7 MySQL is good +8 MySQL is good to know +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('(good "know mysql")' IN BOOLEAN MODE); +id a +1 Do you know MySQL is a good database +4 Do you know MySQL +2 How to build a good database +6 Do you feel good +7 MySQL is good +8 MySQL is good to know +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+(good "know mysql")' IN BOOLEAN MODE); +id a +1 Do you know MySQL is a good database +4 Do you know MySQL +2 How to build a good database +6 Do you feel good +7 MySQL is good +8 MySQL is good to know +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+("know mysql" "good database")' IN BOOLEAN MODE); +id a +1 Do you know MySQL is a good database +2 How to build a good database +4 Do you know MySQL +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+"know mysql" +"good database"' IN BOOLEAN MODE); +id a +1 Do you know MySQL is a good database +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+"know database"@4' IN BOOLEAN MODE); +id a +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+"know database"@8' IN BOOLEAN MODE); +id a +1 Do you know MySQL is a good database +DROP TABLE t1; +CREATE TABLE t1 ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +a VARCHAR(200), +FULLTEXT (a) +) ENGINE= InnoDB; +INSERT INTO t1 (a) VALUES +('know mysql good database'); +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+"good database"' IN BOOLEAN MODE); +id a +1 know mysql good database +DROP TABLE t1; +CREATE TABLE articles ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), +body TEXT, +FULLTEXT (title,body) +) ENGINE=InnoDB; +INSERT INTO articles (title,body) VALUES ('Test Article','blah blah +blah'),("Matt's Noise",'this is noisy'),('February Weather','It was terrible +this year.'),('Peter Pan','Tis a kids story.'),('Test1','nada'),('Database +database database','foo database database database'),('Database article +title','body with lots of words.'),('myfulltext database', 'my test fulltext +database'); +SELECT id, title, body FROM articles ORDER BY MATCH (title,body) AGAINST ('database' IN BOOLEAN MODE) DESC; +id title body +6 Database +database database foo database database database +8 myfulltext database my test fulltext +database +7 Database article +title body with lots of words. +1 Test Article blah blah +blah +2 Matt's Noise this is noisy +3 February Weather It was terrible +this year. +4 Peter Pan Tis a kids story. +5 Test1 nada +DELETE from articles WHERE title like "myfulltext database"; +INSERT INTO articles (title,body) VALUES ('myfulltext database', 'my test fulltext database'); +SELECT id, title, body FROM articles ORDER BY MATCH (title,body) AGAINST ('database' IN BOOLEAN MODE) DESC; +id title body +6 Database +database database foo database database database +9 myfulltext database my test fulltext database +7 Database article +title body with lots of words. +1 Test Article blah blah +blah +2 Matt's Noise this is noisy +3 February Weather It was terrible +this year. +4 Peter Pan Tis a kids story. +5 Test1 nada +DELETE from articles WHERE title like "myfulltext database"; +INSERT INTO articles (title,body) VALUES ('myfulltext database', 'my test fulltext database'); +SELECT id, title, body FROM articles ORDER BY MATCH (title,body) AGAINST ('database' IN BOOLEAN MODE) DESC; +id title body +6 Database +database database foo database database database +10 myfulltext database my test fulltext database +7 Database article +title body with lots of words. +1 Test Article blah blah +blah +2 Matt's Noise this is noisy +3 February Weather It was terrible +this year. +4 Peter Pan Tis a kids story. +5 Test1 nada +DROP TABLE articles; +CREATE TABLE t1( +a TEXT CHARSET ujis COLLATE ujis_japanese_ci, +b TEXT CHARSET utf8mb4 COLLATE utf8mb4_turkish_ci, +c TEXT CHARSET eucjpms COLLATE eucjpms_bin, +d TEXT CHARSET utf8mb4, +FULLTEXT INDEX(a), +FULLTEXT INDEX(b), +FULLTEXT INDEX(c), +FULLTEXT INDEX(d) +) ENGINE = InnoDB; +INSERT INTO t1 VALUES +('myisam', 'myisam', 'myisam', 'myisam'), +('innodb', 'innodb', 'innodb', 'innodb'), +('innodb myisam', 'innodb myisam', 'innodb myisam', 'innodb myisam'), +('memory', 'memory', 'memory', 'memory'), +('archive', 'archive', 'archive', 'archive'), +('federated', 'federated', 'federated', 'federated'), +('storage engine innodb', 'storage engine innodb', 'storage engine innodb', 'storage engine innodb'), +('storage engine myisam', 'storage engine myisam', 'storage engine myisam', 'storage engine myisam'), +('innobase', 'innobase', 'innobase', 'innobase'), +('myisam innodb', 'myisam innodb', 'myisam innodb', 'myisam innodb'), +('innodb myisam engines', 'innodb myisam engines', 'innodb myisam engines', 'innodb myisam engines'); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"')); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00)); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', '"')); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', ' ', '"')); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, '"')); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00, '"', 0x00, '"', 0x00)); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', '&', 0x00, '"')); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, '&', '"')); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', '%', '"')); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '"')); +a +innodb +innodb myisam +storage engine innodb +myisam innodb +innodb myisam engines +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '"')); +a +innodb +innodb myisam +storage engine innodb +myisam innodb +innodb myisam engines +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00, '"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', 0x00, 0x00, 0x00, '"')); +a +innodb +innodb myisam +storage engine innodb +myisam innodb +innodb myisam engines +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00, '"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00)); +a +innodb myisam +myisam innodb +innodb myisam engines +myisam +innodb +storage engine innodb +storage engine myisam +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00)); +a +innodb myisam +myisam innodb +innodb myisam engines +myisam +innodb +storage engine innodb +storage engine myisam +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00, '"')); +a +innodb myisam +innodb myisam engines +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', '(', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', ')')); +a +innodb myisam +myisam innodb +innodb myisam engines +myisam +innodb +storage engine innodb +storage engine myisam +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', 'm', 'y', 'i', 's', 'a', 'm')); +a +innodb myisam +myisam innodb +innodb myisam engines +myisam +innodb +storage engine innodb +storage engine myisam +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', 'm', 'y', 'i', 's', 'a', 'm', '"')); +a +innodb myisam +innodb myisam engines +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00, '"','@', '2') IN BOOLEAN MODE); +a +innodb myisam +myisam innodb +innodb myisam engines +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', '$', 'm', 'y', 'i', 's', 'a', 'm', '"','@', '4') IN BOOLEAN MODE); +a +innodb myisam +myisam innodb +innodb myisam engines +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00, '"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', '$', 's', 't', 'o', 'r', 'a', 'g', 'e', '"','@', '4', 0x00) IN BOOLEAN MODE); +ERROR 42000: syntax error, unexpected FTS_TERM, expecting FTS_NUMB +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"')); +b +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT(0x00)); +b +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', '"')); +b +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', ' ', '"')); +b +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', 0x00, '"')); +b +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT(0x00, '"', 0x00, '"', 0x00)); +b +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', '&', 0x00, '"')); +b +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', 0x00, '&', '"')); +b +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', '%', '"')); +b +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '"')); +b +innodb +innodb myisam +storage engine innodb +myisam innodb +innodb myisam engines +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '"')); +b +innodb +innodb myisam +storage engine innodb +myisam innodb +innodb myisam engines +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT(0x00, '"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', 0x00, 0x00, 0x00, '"')); +b +innodb +innodb myisam +storage engine innodb +myisam innodb +innodb myisam engines +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT(0x00, '"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00)); +b +innodb myisam +myisam innodb +innodb myisam engines +myisam +innodb +storage engine innodb +storage engine myisam +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00, '"','@', '2') IN BOOLEAN MODE); +b +innodb myisam +myisam innodb +innodb myisam engines +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', '$', 'm', 'y', 'i', 's', 'a', 'm', '"','@', '4') IN BOOLEAN MODE); +b +innodb myisam +myisam innodb +innodb myisam engines +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT(0x00, '"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', '$', 's', 't', 'o', 'r', 'a', 'g', 'e', '"','@', '4', 0x00) IN BOOLEAN MODE); +ERROR 42000: syntax error, unexpected FTS_TERM, expecting FTS_NUMB +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"')); +c +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT(0x00)); +c +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', '"')); +c +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', ' ', '"')); +c +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 0x00, '"')); +c +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT(0x00, '"', 0x00, '"', 0x00)); +c +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', '&', 0x00, '"')); +c +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 0x00, '&', '"')); +c +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', '%', '"')); +c +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '"')); +c +innodb +innodb myisam +storage engine innodb +myisam innodb +innodb myisam engines +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '"')); +c +innodb +innodb myisam +storage engine innodb +myisam innodb +innodb myisam engines +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT(0x00, '"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', 0x00, 0x00, 0x00, '"')); +c +innodb +innodb myisam +storage engine innodb +myisam innodb +innodb myisam engines +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT(0x00, '"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00)); +c +innodb myisam +myisam innodb +innodb myisam engines +myisam +innodb +storage engine innodb +storage engine myisam +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00)); +c +innodb myisam +myisam innodb +innodb myisam engines +myisam +innodb +storage engine innodb +storage engine myisam +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00, '"')); +c +innodb myisam +innodb myisam engines +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', '(', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', ')')); +c +innodb myisam +myisam innodb +innodb myisam engines +myisam +innodb +storage engine innodb +storage engine myisam +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', 'm', 'y', 'i', 's', 'a', 'm')); +c +innodb myisam +myisam innodb +innodb myisam engines +myisam +innodb +storage engine innodb +storage engine myisam +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', 'm', 'y', 'i', 's', 'a', 'm', '"')); +c +innodb myisam +innodb myisam engines +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00, '"','@', '2') IN BOOLEAN MODE); +c +innodb myisam +myisam innodb +innodb myisam engines +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', '$', 'm', 'y', 'i', 's', 'a', 'm', '"','@', '4') IN BOOLEAN MODE); +c +innodb myisam +myisam innodb +innodb myisam engines +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT(0x00, '"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', '$', 's', 't', 'o', 'r', 'a', 'g', 'e', '"','@', '4', 0x00) IN BOOLEAN MODE); +ERROR 42000: syntax error, unexpected FTS_TERM, expecting FTS_NUMB +ALTER TABLE t1 ENGINE = MyISAM; +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"')); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00)); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', '"')); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', ' ', '"')); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, '"')); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00, '"', 0x00, '"', 0x00)); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', '&', 0x00, '"')); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, '&', '"')); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', '%', '"')); +a +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '"')); +a +innodb +innodb myisam +myisam innodb +storage engine innodb +innodb myisam engines +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '"')); +a +innodb +innodb myisam +myisam innodb +storage engine innodb +innodb myisam engines +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00, '"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', 0x00, 0x00, 0x00, '"')); +a +innodb +innodb myisam +myisam innodb +storage engine innodb +innodb myisam engines +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00, '"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00)); +a +innodb myisam +myisam innodb +innodb myisam engines +myisam +innodb +storage engine innodb +storage engine myisam +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00)); +a +innodb myisam +myisam innodb +innodb myisam engines +myisam +innodb +storage engine innodb +storage engine myisam +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00, '"')); +a +innodb myisam +myisam innodb +innodb myisam engines +myisam +innodb +storage engine innodb +storage engine myisam +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', '(', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', ')')); +a +innodb myisam +myisam innodb +innodb myisam engines +myisam +innodb +storage engine innodb +storage engine myisam +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', 'm', 'y', 'i', 's', 'a', 'm')); +a +innodb myisam +myisam innodb +innodb myisam engines +myisam +innodb +storage engine innodb +storage engine myisam +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', 'm', 'y', 'i', 's', 'a', 'm', '"')); +a +innodb myisam +myisam innodb +innodb myisam engines +myisam +innodb +storage engine innodb +storage engine myisam +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00, '"','@', '2') IN BOOLEAN MODE); +a +innodb myisam +innodb myisam engines +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', '$', 'm', 'y', 'i', 's', 'a', 'm', '"','@', '4') IN BOOLEAN MODE); +a +innodb myisam +innodb myisam engines +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00, '"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', '$', 's', 't', 'o', 'r', 'a', 'g', 'e', '"','@', '4', 0x00) IN BOOLEAN MODE); +a +DROP TABLE t1; +CREATE TABLE t1 ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +a VARCHAR(200), +FULLTEXT (a) +) ENGINE= InnoDB; +INSERT INTO t1 (a) VALUES +('know database'),('good database'), ('gmail email'), ('ghome windows'); +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('g *' IN NATURAL LANGUAGE MODE); +id a +2 good database +3 gmail email +4 ghome windows +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('g *' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION); +id a +3 gmail email +4 ghome windows +2 good database +1 know database +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('g * k *' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION); +id a +1 know database +3 gmail email +4 ghome windows +2 good database +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('g * k * d *' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION); +id a +1 know database +3 gmail email +4 ghome windows +2 good database +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('g * go *' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION); +id a +2 good database +3 gmail email +4 ghome windows +1 know database +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('g * good' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION); +id a +2 good database +3 gmail email +4 ghome windows +1 know database +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('gm * go *' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION); +id a +3 gmail email +2 good database +1 know database +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('good *' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION); +id a +2 good database +1 know database +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('g* database' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION); +id a +1 know database +2 good database +DROP TABLE t1; diff --git a/mysql-test/suite/innodb_fts/r/misc_1.result b/mysql-test/suite/innodb_fts/r/misc_1.result new file mode 100644 index 00000000000..2b26a87c3d7 --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/misc_1.result @@ -0,0 +1,922 @@ +set names utf8; +call mtr.add_suppression("\\[Warning\\] InnoDB: A new Doc ID must be supplied while updating FTS indexed columns."); +call mtr.add_suppression("\\[Warning\\] InnoDB: FTS Doc ID must be larger than [0-9]+ for table `test`.`t1`"); +CREATE TABLE t1 ( +id1 INT , +a1 VARCHAR(200) , +b1 TEXT , +FULLTEXT KEY (a1,b1), PRIMARY KEY (a1, id1) +) CHARACTER SET = utf8 , ENGINE = InnoDB; +CREATE TABLE t2 ( +id2 INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +a2 VARCHAR(200), +b2 TEXT , +FOREIGN KEY (a2) REFERENCES t1(a1) ON UPDATE CASCADE, +FULLTEXT KEY (b2,a2) +) CHARACTER SET = utf8 ,ENGINE = InnoDB; +INSERT INTO t1 (id1,a1,b1) VALUES +(1,'MySQL Tutorial','DBMS stands for DataBase VÐƷWİ...') , +(2,'How To Use MySQL Well','After you went through a ...'), +(3,'Optimizing MySQL','In this tutorial we will show ...'); +INSERT INTO t1 (id1,a1,b1) VALUES +(4,'1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +(5,'MySQL vs. YourSQL','In the following database comparison ...'), +(6,'MySQL Security','When configured properly, MySQL ...'); +INSERT INTO t2 (a2,b2) VALUES +('MySQL Tutorial','DBMS stands for DataBase VÐƷWİ...') , +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'); +INSERT INTO t2 (a2,b2) VALUES +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('MySQL vs. YourSQL','In the following database comparison ...'), +('MySQL Security','When configured properly, MySQL ...'); +INSERT INTO t2 (a2,b2) VALUES +('MySQL Tricks','1. Never run mysqld as root. 2. ...'); +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a2`) REFERENCES `t1` (`a1`) ON UPDATE CASCADE) +DELETE FROM t1; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a2`) REFERENCES `t1` (`a1`) ON UPDATE CASCADE) +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze Warning Engine-independent statistics are not collected for column 'b1' +test.t1 analyze status OK +ANALYZE TABLE t2; +Table Op Msg_type Msg_text +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze Warning Engine-independent statistics are not collected for column 'b2' +test.t2 analyze status OK +SELECT id1 FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial') ORDER BY id1; +id1 +1 +3 +SELECT id2 FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial') ORDER BY id2; +id2 +1 +3 +SELECT id1 FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial (+mysql -VÐƷWİ)' IN BOOLEAN MODE) ORDER BY id1; +id1 +1 +2 +3 +4 +5 +6 +SELECT id2 FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial (+mysql -VÐƷWİ)' IN BOOLEAN MODE) ORDER BY id2; +id2 +1 +2 +3 +4 +5 +6 +SELECT id1 FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial' WITH QUERY EXPANSION) ORDER BY id1; +id1 +1 +2 +3 +4 +5 +6 +SELECT id2 FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial' WITH QUERY EXPANSION) ORDER BY id2; +id2 +1 +2 +3 +4 +5 +6 +SELECT id1 FROM t1 WHERE MATCH (a1,b1) AGAINST ('"dbms database"@4' IN BOOLEAN MODE) ; +id1 +1 +SELECT id2 FROM t2 WHERE MATCH (a2,b2) AGAINST ('"dbms database"@4' IN BOOLEAN MODE) ; +id2 +1 +set global innodb_optimize_fulltext_only=1; +optimize table t1; +Table Op Msg_type Msg_text +test.t1 optimize status OK +set global innodb_optimize_fulltext_only=0; +UPDATE t1 SET a1 = "changing column - on update cascade" , b1 = "to check foreign constraint" WHERE +MATCH (a1,b1) AGAINST ('tutorial (+mysql -VÐƷWİ)' IN BOOLEAN MODE) ; +SELECT id1 FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial (+mysql -VÐƷWİ)' IN BOOLEAN MODE) ; +id1 +SELECT id2 FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial (+mysql -VÐƷWİ)' IN BOOLEAN MODE) ; +id2 +3 +6 +SELECT id1 FROM t1 WHERE MATCH (a1,b1) AGAINST ('+update +cascade' IN BOOLEAN MODE) ORDER BY id1; +id1 +1 +2 +3 +4 +5 +6 +SELECT id2 FROM t2 WHERE MATCH (a2,b2) AGAINST ('+update +cascade' IN BOOLEAN MODE) ORDER BY id2; +id2 +1 +2 +3 +4 +5 +6 +SELECT id2 FROM t2 WHERE a2 LIKE '%UPDATE CASCADE%' ORDER BY id2; +id2 +1 +2 +3 +4 +5 +6 +DROP TABLE t2 , t1; +create table t1 (s1 int, s2 varchar(200), primary key (s1,s2)) ENGINE = InnoDB; +create table t2 (s1 int, s2 varchar(200), +fulltext key(s2), +foreign key (s1,s2) references t1 (s1,s2) on update cascade) ENGINE = InnoDB; +insert into t1 values (1,'Sunshine'),(2,'Lollipops'); +insert into t2 values (1,'Sunshine'),(2,'Lollipops'); +update t1 set s2 = 'Rainbows' where s2 <> 'Sunshine'; +commit; +select * from t2 where match(s2) against ('Lollipops'); +s1 s2 +DROP TABLE t2 , t1; +create table t1 (s1 int, s2 varchar(200), primary key (s1,s2)) ENGINE = InnoDB; +create table t2 (s1 int, s2 varchar(200), +fulltext key(s2), +foreign key (s1,s2) references t1 (s1,s2) on delete cascade) ENGINE = InnoDB; +insert into t1 values (1,'Sunshine'),(2,'Lollipops'); +insert into t2 values (1,'Sunshine'),(2,'Lollipops'); +delete from t1 where s2 <> 'Sunshine'; +select * from t2 where match(s2) against ('Lollipops'); +s1 s2 +DROP TABLE t2 , t1; +create table t1 (s1 int, s2 varchar(200), primary key (s1,s2)) ENGINE = InnoDB; +create table t2 (s1 int, s2 varchar(200), +fulltext key(s2), +foreign key (s1,s2) references t1 (s1,s2) on delete set null) ENGINE = InnoDB; +insert into t1 values (1,'Sunshine'),(2,'Lollipops'); +insert into t2 values (1,'Sunshine'),(2,'Lollipops'); +delete from t1 where s2 <> 'Sunshine'; +select * from t2 where match(s2) against ('Lollipops'); +s1 s2 +DROP TABLE t2 , t1; +create table t1 (s1 int, s2 varchar(200), primary key (s1,s2)) ENGINE = InnoDB; +create table t2 (s1 int, s2 varchar(200), +fulltext key(s2), +foreign key (s1,s2) references t1 (s1,s2) on update set null) ENGINE = InnoDB; +insert into t1 values (1,'Sunshine'),(2,'Lollipops'); +insert into t2 values (1,'Sunshine'),(2,'Lollipops'); +update t1 set s2 = 'Rainbows' where s2 <> 'Sunshine'; +commit; +select * from t2 where match(s2) against ('Lollipops'); +s1 s2 +DROP TABLE t2 , t1; +create table t1 (s1 bigint unsigned not null, s2 varchar(200), +primary key (s1,s2)) ENGINE = InnoDB; +create table t2 (FTS_DOC_ID BIGINT UNSIGNED NOT NULL, s2 varchar(200), +foreign key (FTS_DOC_ID) references t1 (s1) +on update cascade) ENGINE = InnoDB; +create fulltext index idx on t2(s2); +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `FTS_DOC_ID` bigint(20) unsigned NOT NULL, + `s2` varchar(200) DEFAULT NULL, + KEY `FTS_DOC_ID` (`FTS_DOC_ID`), + FULLTEXT KEY `idx` (`s2`), + CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`FTS_DOC_ID`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +insert into t1 values (1,'Sunshine'),(2,'Lollipops'); +insert into t2 values (1,'Sunshine'),(2,'Lollipops'); +update t1 set s1 = 3 where s1=1; +select * from t2 where match(s2) against ('sunshine'); +FTS_DOC_ID s2 +3 Sunshine +update t1 set s1 = 1 where s1=3; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`FTS_DOC_ID`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE) +DROP TABLE t2 , t1; +CREATE TABLE t1 ( +id1 INT , +a1 VARCHAR(200) PRIMARY KEY, +b1 TEXT character set utf8 , +FULLTEXT KEY (a1,b1) +) CHARACTER SET = utf8 ,ENGINE = InnoDB; +CREATE TABLE t2 ( +id2 INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +a2 VARCHAR(200), +b2 TEXT character set utf8 , +FOREIGN KEY (a2) REFERENCES t1(a1) ON DELETE CASCADE, +FULLTEXT KEY (b2,a2) +) CHARACTER SET = utf8 ,ENGINE = InnoDB; +INSERT INTO t1 (id1,a1,b1) VALUES +(1,'MySQL Tutorial','DBMS stands for DataBase VÐƷWİ...') , +(2,'How To Use MySQL Well','After you went through a ...'), +(3,'Optimizing MySQL','In this tutorial we will show ...'), +(4,'1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +(5,'MySQL vs. YourSQL','In the following database comparison ...'), +(6,'MySQL Security','When configured properly, MySQL ...'); +INSERT INTO t2 (a2,b2) VALUES +('MySQL Tutorial','DBMS stands for DataBase VÐƷWİ...') , +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'), +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('MySQL vs. YourSQL','In the following database comparison ...'), +('MySQL Security','When configured properly, MySQL ...'); +DELETE FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial (+mysql -VÐƷWİ)' IN BOOLEAN MODE) ; +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial (+mysql -VÐƷWİ)' IN BOOLEAN MODE) ; +id1 a1 b1 +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial (+mysql -VÐƷWİ)' IN BOOLEAN MODE) ; +id2 a2 b2 +SELECT * FROM t1 WHERE a1 LIKE '%tutorial%'; +id1 a1 b1 +SELECT * FROM t2 WHERE a2 LIKE '%tutorial%'; +id2 a2 b2 +DROP TABLE t2 , t1; +call mtr.add_suppression("\\[ERROR\\] InnoDB: FTS Doc ID must be larger than 3 for table `test`.`t2`"); +CREATE TABLE t1 ( +id1 INT , +a1 VARCHAR(200) , +b1 TEXT , +FULLTEXT KEY (a1,b1), PRIMARY KEY(a1, id1) +) CHARACTER SET = utf8 , ENGINE = InnoDB; +CREATE TABLE t2 ( +id2 INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +a2 VARCHAR(200), +b2 TEXT , +FOREIGN KEY (a2) REFERENCES t1(a1) ON UPDATE CASCADE, +FULLTEXT KEY (b2,a2) +) CHARACTER SET = utf8 ,ENGINE = InnoDB; +INSERT INTO t1 (id1,a1,b1) VALUES +(1,'MySQL Tutorial','DBMS stands for DataBase VÐƷWİ...') , +(2,'How To Use MySQL Well','After you went through a ...'), +(3,'Optimizing MySQL','In this tutorial we will show ...'); +INSERT INTO t2 (a2,b2) VALUES +('MySQL Tutorial','DBMS stands for DataBase VÐƷWİ...') , +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'); +START TRANSACTION; +INSERT INTO t1 (id1,a1,b1) VALUES +(4,'1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +(5,'MySQL vs. YourSQL','In the following database comparison ...'), +(6,'MySQL Security','When configured properly, MySQL ...'); +INSERT INTO t2 (a2,b2) VALUES +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('MySQL vs. YourSQL','In the following database comparison ...'), +('MySQL Security','When configured properly, MySQL ...'); +INSERT INTO t2 (a2,b2) VALUES +('MySQL Tricks','1. Never run mysqld as root. 2. ...'); +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a2`) REFERENCES `t1` (`a1`) ON UPDATE CASCADE) +DELETE FROM t1; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a2`) REFERENCES `t1` (`a1`) ON UPDATE CASCADE) +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial') ORDER BY id1; +id1 a1 b1 +1 MySQL Tutorial DBMS stands for DataBase VÐƷWİ... +3 Optimizing MySQL In this tutorial we will show ... +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial') ORDER BY id2; +id2 a2 b2 +1 MySQL Tutorial DBMS stands for DataBase VÐƷWİ... +3 Optimizing MySQL In this tutorial we will show ... +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial (+mysql -VÐƷWİ)' IN BOOLEAN MODE) ORDER BY id1; +id1 a1 b1 +1 MySQL Tutorial DBMS stands for DataBase VÐƷWİ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial (+mysql -VÐƷWİ)' IN BOOLEAN MODE) ORDER BY id2; +id2 a2 b2 +1 MySQL Tutorial DBMS stands for DataBase VÐƷWİ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial' WITH QUERY EXPANSION) ORDER BY id1; +id1 a1 b1 +1 MySQL Tutorial DBMS stands for DataBase VÐƷWİ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial' WITH QUERY EXPANSION) ORDER BY id2; +id2 a2 b2 +1 MySQL Tutorial DBMS stands for DataBase VÐƷWİ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('"dbms database"@4' IN BOOLEAN MODE) ; +id1 a1 b1 +1 MySQL Tutorial DBMS stands for DataBase VÐƷWİ... +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('"dbms database"@4' IN BOOLEAN MODE) ; +id2 a2 b2 +1 MySQL Tutorial DBMS stands for DataBase VÐƷWİ... +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('root') ; +id1 a1 b1 +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('root') ; +id2 a2 b2 +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('mysqld (+root)' IN BOOLEAN MODE) ; +id1 a1 b1 +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('mysqld (-root)' IN BOOLEAN MODE) ; +id2 a2 b2 +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('root' WITH QUERY EXPANSION) ; +id1 a1 b1 +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('root' WITH QUERY EXPANSION) ; +id2 a2 b2 +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('"database comparison"@02' IN BOOLEAN MODE) ; +id1 a1 b1 +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('"database comparison"@02' IN BOOLEAN MODE) ; +id2 a2 b2 +SELECT * FROM t1 ORDER BY id1; +id1 a1 b1 +1 MySQL Tutorial DBMS stands for DataBase VÐƷWİ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +5 MySQL vs. YourSQL In the following database comparison ... +6 MySQL Security When configured properly, MySQL ... +SELECT * FROM t2 ORDER BY id2; +id2 a2 b2 +1 MySQL Tutorial DBMS stands for DataBase VÐƷWİ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +5 MySQL vs. YourSQL In the following database comparison ... +6 MySQL Security When configured properly, MySQL ... +COMMIT; +START TRANSACTION; +UPDATE t1 SET a1 = "changing column - on UPDATE cascade" , b1 = "to check foreign constraint" WHERE +MATCH (a1,b1) AGAINST ('tutorial (+mysql -VÐƷWİ)' IN BOOLEAN MODE) ; +COMMIT; +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial (+mysql -VÐƷWİ)' IN BOOLEAN MODE) ; +id1 a1 b1 +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial (+mysql -VÐƷWİ)' IN BOOLEAN MODE) ; +id2 a2 b2 +3 changing column - on UPDATE cascade In this tutorial we will show ... +6 changing column - on UPDATE cascade When configured properly, MySQL ... +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('+UPDATE +cascade' IN BOOLEAN MODE) ORDER BY id1; +id1 a1 b1 +1 changing column - on UPDATE cascade to check foreign constraint +2 changing column - on UPDATE cascade to check foreign constraint +3 changing column - on UPDATE cascade to check foreign constraint +4 changing column - on UPDATE cascade to check foreign constraint +5 changing column - on UPDATE cascade to check foreign constraint +6 changing column - on UPDATE cascade to check foreign constraint +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('+UPDATE +cascade' IN BOOLEAN MODE) ORDER BY id2; +id2 a2 b2 +1 changing column - on UPDATE cascade DBMS stands for DataBase VÐƷWİ... +2 changing column - on UPDATE cascade After you went through a ... +3 changing column - on UPDATE cascade In this tutorial we will show ... +4 changing column - on UPDATE cascade 1. Never run mysqld as root. 2. ... +5 changing column - on UPDATE cascade In the following database comparison ... +6 changing column - on UPDATE cascade When configured properly, MySQL ... +SELECT * FROM t2 WHERE a2 LIKE '%UPDATE CASCADE%' ORDER BY id2; +id2 a2 b2 +1 changing column - on UPDATE cascade DBMS stands for DataBase VÐƷWİ... +2 changing column - on UPDATE cascade After you went through a ... +3 changing column - on UPDATE cascade In this tutorial we will show ... +4 changing column - on UPDATE cascade 1. Never run mysqld as root. 2. ... +5 changing column - on UPDATE cascade In the following database comparison ... +6 changing column - on UPDATE cascade When configured properly, MySQL ... +DROP TABLE t2 , t1; +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200), PRIMARY KEY (s1,s2)) ENGINE = InnoDB; +CREATE TABLE t2 (s1 INT, s2 VARCHAR(200), +FULLTEXT KEY(s2), +FOREIGN KEY (s1,s2) REFERENCES t1 (s1,s2) on UPDATE cascade) ENGINE = InnoDB; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'Sunshine'),(2,'Lollipops'); +INSERT INTO t2 VALUES (1,'Sunshine'),(2,'Lollipops'); +UPDATE t1 set s2 = 'Rainbows' WHERE s2 <> 'Sunshine'; +COMMIT; +SELECT * FROM t2 WHERE MATCH(s2) AGAINST ('Lollipops'); +s1 s2 +DROP TABLE t2 , t1; +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200), PRIMARY KEY (s1,s2)) ENGINE = InnoDB; +CREATE TABLE t2 (s1 INT, s2 VARCHAR(200), +FULLTEXT KEY(s2), +FOREIGN KEY (s1,s2) REFERENCES t1 (s1,s2) on DELETE cascade) ENGINE = InnoDB; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'Sunshine'),(2,'Lollipops'); +INSERT INTO t2 VALUES (1,'Sunshine'),(2,'Lollipops'); +DELETE FROM t1 WHERE s2 <> 'Sunshine'; +COMMIT; +SELECT * FROM t2 WHERE MATCH(s2) AGAINST ('Lollipops'); +s1 s2 +DROP TABLE t2 , t1; +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200), PRIMARY KEY (s1,s2)) ENGINE = InnoDB; +CREATE TABLE t2 (s1 INT, s2 VARCHAR(200), +FULLTEXT KEY(s2), +FOREIGN KEY (s1,s2) REFERENCES t1 (s1,s2) on DELETE SET NULL) ENGINE = InnoDB; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'Sunshine'),(2,'Lollipops'); +INSERT INTO t2 VALUES (1,'Sunshine'),(2,'Lollipops'); +DELETE FROM t1 WHERE s2 <> 'Sunshine'; +COMMIT; +SELECT * FROM t2 WHERE MATCH(s2) AGAINST ('Lollipops'); +s1 s2 +DROP TABLE t2 , t1; +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200), PRIMARY KEY (s1,s2)) ENGINE = InnoDB; +CREATE TABLE t2 (s1 INT, s2 VARCHAR(200), +FULLTEXT KEY(s2), +FOREIGN KEY (s1,s2) REFERENCES t1 (s1,s2) on UPDATE SET NULL) ENGINE = InnoDB; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'Sunshine'),(2,'Lollipops'); +INSERT INTO t2 VALUES (1,'Sunshine'),(2,'Lollipops'); +UPDATE t1 set s2 = 'Rainbows' WHERE s2 <> 'Sunshine'; +COMMIT; +SELECT * FROM t2 WHERE MATCH(s2) AGAINST ('Lollipops'); +s1 s2 +DROP TABLE t2 , t1; +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200), PRIMARY KEY (s1,s2)) ENGINE = InnoDB; +CREATE TABLE t2 (s1 INT, s2 VARCHAR(200), +FULLTEXT KEY(s2), +FOREIGN KEY (s1,s2) REFERENCES t1 (s1,s2) on UPDATE cascade) ENGINE = InnoDB; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'Sunshine'),(2,'Lollipops'); +INSERT INTO t2 VALUES (1,'Sunshine'),(2,'Lollipops'); +UPDATE t1 set s2 = 'Rainbows' WHERE s2 <> 'Sunshine'; +ROLLBACK; +SELECT * FROM t2 WHERE MATCH(s2) AGAINST ('Lollipops'); +s1 s2 +DROP TABLE t2 , t1; +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200), PRIMARY KEY (s1,s2)) ENGINE = InnoDB; +CREATE TABLE t2 (s1 INT, s2 VARCHAR(200), +FULLTEXT KEY(s2), +FOREIGN KEY (s1,s2) REFERENCES t1 (s1,s2) on DELETE cascade) ENGINE = InnoDB; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'Sunshine'),(2,'Lollipops'); +INSERT INTO t2 VALUES (1,'Sunshine'),(2,'Lollipops'); +DELETE FROM t1 WHERE s2 <> 'Sunshine'; +ROLLBACK; +SELECT * FROM t2 WHERE MATCH(s2) AGAINST ('Lollipops'); +s1 s2 +DROP TABLE t2 , t1; +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200), PRIMARY KEY (s1,s2)) ENGINE = InnoDB; +CREATE TABLE t2 (s1 INT, s2 VARCHAR(200), +FULLTEXT KEY(s2), +FOREIGN KEY (s1,s2) REFERENCES t1 (s1,s2) on DELETE SET NULL) ENGINE = InnoDB; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'Sunshine'),(2,'Lollipops'); +INSERT INTO t2 VALUES (1,'Sunshine'),(2,'Lollipops'); +DELETE FROM t1 WHERE s2 <> 'Sunshine'; +ROLLBACK; +SELECT * FROM t2 WHERE MATCH(s2) AGAINST ('Lollipops'); +s1 s2 +DROP TABLE t2 , t1; +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200), PRIMARY KEY (s1,s2)) ENGINE = InnoDB; +CREATE TABLE t2 (s1 INT, s2 VARCHAR(200), +FULLTEXT KEY(s2), +FOREIGN KEY (s1,s2) REFERENCES t1 (s1,s2) on UPDATE SET NULL) ENGINE = InnoDB; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'Sunshine'),(2,'Lollipops'); +INSERT INTO t2 VALUES (1,'Sunshine'),(2,'Lollipops'); +UPDATE t1 set s2 = 'Rainbows' WHERE s2 <> 'Sunshine'; +ROLLBACK; +SELECT * FROM t2 WHERE MATCH(s2) AGAINST ('Lollipops'); +s1 s2 +DROP TABLE t2 , t1; +set global innodb_file_per_table=1; +CREATE TABLE t1 ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +a VARCHAR(200), +b TEXT +) CHARACTER SET = utf8, ROW_FORMAT=COMPRESSED, ENGINE = InnoDB; +INSERT INTO t1 (a,b) VALUES +('MySQL Tutorial','DBMS stands for DataBase VÐƷWİ...') , +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'); +ALTER TABLE t1 ADD FULLTEXT INDEX idx (a,b); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `a` varchar(200) DEFAULT NULL, + `b` text DEFAULT NULL, + PRIMARY KEY (`id`), + FULLTEXT KEY `idx` (`a`,`b`) +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci ROW_FORMAT=COMPRESSED +SELECT count(*) FROM information_schema.innodb_sys_tables WHERE name LIKE "%FTS_%" AND space !=0; +count(*) +11 +INSERT INTO t1 (a,b) VALUES +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('MySQL vs. YourSQL','In the following database comparison ...'), +('MySQL Security','When configured properly, MySQL ...'); +ANALYZE TABLE t1; +SELECT * FROM t1 WHERE MATCH (a,b) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE) ORDER BY id; +id a b +1 MySQL Tutorial DBMS stands for DataBase VÐƷWİ... +3 Optimizing MySQL In this tutorial we will show ... +select * from t1 where MATCH(a,b) AGAINST("+tutorial +VÐƷWİ" IN BOOLEAN MODE); +id a b +1 MySQL Tutorial DBMS stands for DataBase VÐƷWİ... +select * from t1 where MATCH(a,b) AGAINST("+-VÐƷWİ" IN BOOLEAN MODE); +ERROR 42000: syntax error, unexpected '-' +select * from t1 where MATCH(a,b) AGAINST("+Mysql +(tricks never)" IN BOOLEAN MODE); +id a b +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +select * from t1 where MATCH(a,b) AGAINST("+mysql -(tricks never)" IN BOOLEAN MODE) ORDER BY id; +id a b +1 MySQL Tutorial DBMS stands for DataBase VÐƷWİ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +5 MySQL vs. YourSQL In the following database comparison ... +6 MySQL Security When configured properly, MySQL ... +select *, MATCH(a,b) AGAINST("mysql stands" IN BOOLEAN MODE) as x from t1 ORDER BY id; +id a b x +1 MySQL Tutorial DBMS stands for DataBase VÐƷWİ... 0.6055193543434143 +2 How To Use MySQL Well After you went through a ... 0.000000001885928302414186 +3 Optimizing MySQL In this tutorial we will show ... 0.000000001885928302414186 +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... 0.000000001885928302414186 +5 MySQL vs. YourSQL In the following database comparison ... 0.000000001885928302414186 +6 MySQL Security When configured properly, MySQL ... 0.000000003771856604828372 +select * from t1 where MATCH a,b AGAINST ("+database* +VÐƷW*" IN BOOLEAN MODE); +id a b +1 MySQL Tutorial DBMS stands for DataBase VÐƷWİ... +select * from t1 where MATCH a,b AGAINST ('"security mysql"' IN BOOLEAN MODE); +id a b +select * from t1 where MATCH(a,b) AGAINST ("VÐƷWİ" WITH QUERY EXPANSION) ORDER BY id; +id a b +1 MySQL Tutorial DBMS stands for DataBase VÐƷWİ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +5 MySQL vs. YourSQL In the following database comparison ... +6 MySQL Security When configured properly, MySQL ... +ALTER TABLE t1 DROP INDEX idx; +CREATE FULLTEXT INDEX idx on t1 (a,b); +SELECT * FROM t1 WHERE MATCH (a,b) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE) ORDER BY id; +id a b +1 MySQL Tutorial DBMS stands for DataBase VÐƷWİ... +3 Optimizing MySQL In this tutorial we will show ... +select * from t1 where MATCH(a,b) AGAINST("+tutorial +VÐƷWİ" IN BOOLEAN MODE); +id a b +1 MySQL Tutorial DBMS stands for DataBase VÐƷWİ... +select * from t1 where MATCH(a,b) AGAINST("+dbms" IN BOOLEAN MODE); +id a b +1 MySQL Tutorial DBMS stands for DataBase VÐƷWİ... +select * from t1 where MATCH(a,b) AGAINST("+Mysql +(tricks never)" IN BOOLEAN MODE); +id a b +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +select * from t1 where MATCH(a,b) AGAINST("+mysql -(tricks never)" IN BOOLEAN MODE) ORDER BY id; +id a b +1 MySQL Tutorial DBMS stands for DataBase VÐƷWİ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +5 MySQL vs. YourSQL In the following database comparison ... +6 MySQL Security When configured properly, MySQL ... +select *, MATCH(a,b) AGAINST("mysql VÐƷWİ" IN BOOLEAN MODE) as x from t1 ORDER BY id; +id a b x +1 MySQL Tutorial DBMS stands for DataBase VÐƷWİ... 0.6055193543434143 +2 How To Use MySQL Well After you went through a ... 0.000000001885928302414186 +3 Optimizing MySQL In this tutorial we will show ... 0.000000001885928302414186 +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... 0.000000001885928302414186 +5 MySQL vs. YourSQL In the following database comparison ... 0.000000001885928302414186 +6 MySQL Security When configured properly, MySQL ... 0.000000003771856604828372 +select * from t1 where MATCH a,b AGAINST ('"security mysql"' IN BOOLEAN MODE); +id a b +select * from t1 where MATCH(a,b) AGAINST ("VÐƷWİ" WITH QUERY EXPANSION) ORDER BY id; +id a b +1 MySQL Tutorial DBMS stands for DataBase VÐƷWİ... +2 How To Use MySQL Well After you went through a ... +3 Optimizing MySQL In this tutorial we will show ... +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +5 MySQL vs. YourSQL In the following database comparison ... +6 MySQL Security When configured properly, MySQL ... +INSERT INTO t1 (a,b) VALUES ('test query expansion','for database ...'); +INSERT INTO t1 (a,b) VALUES +('test proximity search, test, proximity and phrase', +'search, with proximity innodb'); +INSERT INTO t1 (a,b) VALUES +('test proximity fts search, test, proximity and phrase', +'search, with proximity innodb'); +INSERT INTO t1 (a,b) VALUES +('test more proximity fts search, test, more proximity and phrase', +'search, with proximity innodb'); +SELECT * FROM t1 +WHERE MATCH (a,b) +AGAINST ('"proximity search"@2' IN BOOLEAN MODE); +id a b +8 test proximity search, test, proximity and phrase search, with proximity innodb +SELECT * FROM t1 +WHERE MATCH (a,b) +AGAINST ('"proximity search"@1' IN BOOLEAN MODE); +id a b +SELECT * FROM t1 +WHERE MATCH (a,b) +AGAINST ('"proximity search"@3' IN BOOLEAN MODE) ORDER BY id; +id a b +8 test proximity search, test, proximity and phrase search, with proximity innodb +9 test proximity fts search, test, proximity and phrase search, with proximity innodb +10 test more proximity fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM t1 +WHERE MATCH (a,b) +AGAINST ('"test proximity"@5' IN BOOLEAN MODE) ORDER BY id; +id a b +8 test proximity search, test, proximity and phrase search, with proximity innodb +9 test proximity fts search, test, proximity and phrase search, with proximity innodb +10 test more proximity fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM t1 +WHERE MATCH (a,b) +AGAINST ('"more test proximity"@2' IN BOOLEAN MODE); +id a b +SELECT * FROM t1 +WHERE MATCH (a,b) +AGAINST ('"more test proximity"@3' IN BOOLEAN MODE); +id a b +10 test more proximity fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM t1 +WHERE MATCH (a,b) +AGAINST ('"more fts proximity"@03' IN BOOLEAN MODE); +id a b +10 test more proximity fts search, test, more proximity and phrase search, with proximity innodb +UPDATE t1 SET a = UPPER(a) , b = UPPER(b) ; +UPDATE t1 SET a = UPPER(a) , b = LOWER(b) ; +select * from t1 where MATCH(a,b) AGAINST("+tutorial +dbms" IN BOOLEAN MODE); +id a b +1 MYSQL TUTORIAL dbms stands for database vðʒwi... +select * from t1 where MATCH(a,b) AGAINST("+VÐƷWİ" IN BOOLEAN MODE); +id a b +1 MYSQL TUTORIAL dbms stands for database vðʒwi... +SELECT * FROM t1 WHERE MATCH (a,b) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE) ORDER BY id; +id a b +1 MYSQL TUTORIAL dbms stands for database vðʒwi... +3 OPTIMIZING MYSQL in this tutorial we will show ... +DELETE FROM t1 WHERE MATCH (a,b) AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); +DELETE FROM t1 WHERE MATCH (a,b) AGAINST ('"proximity search"@14' IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH (a,b) +AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); +id a b +SELECT * FROM t1 ORDER BY id; +id a b +2 HOW TO USE MYSQL WELL after you went through a ... +4 1001 MYSQL TRICKS 1. never run mysqld as root. 2. ... +5 MYSQL VS. YOURSQL in the following database comparison ... +6 MYSQL SECURITY when configured properly, mysql ... +7 TEST QUERY EXPANSION for database ... +DROP TABLE t1; +SET GLOBAL innodb_file_per_table=1; +CREATE TABLE t1 ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +a VARCHAR(200), +b TEXT +) CHARACTER SET = utf8, ENGINE=InnoDB; +INSERT INTO t1 (a,b) VALUES +('Я могу есть стекло', 'оно мне не вредит'), +('Мога да ям стъкло', 'то не ми вреди'), +('Μπορῶ νὰ φάω σπασμένα' ,'γυαλιὰ χωρὶς νὰ πάθω τίποτα'), +('Příliš žluťoučký kůň', 'úpěl ďábelské kódy'), +('Sævör grét', 'áðan því úlpan var ónýt'), +('うゐのおくやま','けふこえて'), +('いろはにほへど ちりぬる','あさきゆめみじ ゑひもせず'); +INSERT INTO t1 (a,b) VALUES +('MySQL Tutorial','request docteam@oraclehelp.com ...') , +('Trial version','query performace @1255 minute on 2.1Hz Memory 2GB...') , +('when To Use MySQL Well','for free faq mail@xyz.com ...'); +CREATE FULLTEXT INDEX idx on t1 (a,b); +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ("вредит χωρὶς") ORDER BY id; +id a b +1 Я могу есть стекло оно мне не вредит +3 Μπορῶ νὰ φάω σπασμένα γυαλιὰ χωρὶς νὰ πάθω τίποτα +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ("оно" WITH QUERY EXPANSION); +id a b +1 Я могу есть стекло оно мне не вредит +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST("вред*" IN BOOLEAN MODE) ORDER BY id; +id a b +1 Я могу есть стекло оно мне не вредит +2 Мога да ям стъкло то не ми вреди +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST("+γυαλιὰ +tutorial" IN BOOLEAN MODE); +id a b +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST("+tutorial +(Мога τίποτα)" IN BOOLEAN MODE); +id a b +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ("あさきゆめみじ ゑひもせず"); +id a b +7 いろはにほへど ちりぬる あさきゆめみじ ゑひもせず +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ("ちりぬる" WITH QUERY EXPANSION); +id a b +7 いろはにほへど ちりぬる あさきゆめみじ ゑひもせず +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ("+あさきゆめみじ +ゑひもせず" IN BOOLEAN MODE); +id a b +7 いろはにほへど ちりぬる あさきゆめみじ ゑひもせず +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST("うゐのおく*" IN BOOLEAN MODE); +id a b +6 うゐのおくやま けふこえて +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST("+Sævör +úlpan" IN BOOLEAN MODE); +id a b +5 Sævör grét áðan því úlpan var ónýt +SELECT * FROM t1 +WHERE MATCH (a,b) +AGAINST ('"γυαλιὰ χωρὶς"@2' IN BOOLEAN MODE); +id a b +3 Μπορῶ νὰ φάω σπασμένα γυαλιὰ χωρὶς νὰ πάθω τίποτα +SELECT * FROM t1 +WHERE MATCH (a,b) +AGAINST ('"query performace"@02' IN BOOLEAN MODE); +id a b +9 Trial version query performace @1255 minute on 2.1Hz Memory 2GB... +SELECT * FROM t1 +WHERE MATCH (a,b) +AGAINST ('"πάθω τίποτα"@2' IN BOOLEAN MODE); +id a b +3 Μπορῶ νὰ φάω σπασμένα γυαλιὰ χωρὶς νὰ πάθω τίποτα +SELECT * FROM t1 +WHERE MATCH (a,b) +AGAINST ('"あさきゆめみじ ゑひもせず"@1' IN BOOLEAN MODE); +id a b +SELECT * FROM t1 +WHERE MATCH (a,b) +AGAINST ('"あさきゆめみじ ゑひもせず"@2' IN BOOLEAN MODE); +id a b +7 いろはにほへど ちりぬる あさきゆめみじ ゑひもせず +ALTER TABLE t1 DROP INDEX idx; +CREATE FULLTEXT INDEX idx on t1 (a,b); +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ("あさきゆめみじ ゑひもせず"); +id a b +7 いろはにほへど ちりぬる あさきゆめみじ ゑひもせず +UPDATE t1 SET a = "Pchnąć w tę łódź jeża" , b = "lub osiem skrzyń fig" WHERE MATCH(a,b) AGAINST ("あさきゆめみじ ゑひもせず"); +UPDATE t1 SET a = "В чащах юга жил-был цитрус? Да", b = "но фальшивый экземпляр! ёъ" WHERE MATCH(a,b) AGAINST ("вред*" IN BOOLEAN MODE); +DELETE FROM t1 WHERE MATCH(a,b) AGAINST("+Sævör +úlpan" IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ("あさきゆめみじ ゑひもせず"); +id a b +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ("łódź osiem"); +id a b +7 Pchnąć w tę łódź jeża lub osiem skrzyń fig +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST("вред*" IN BOOLEAN MODE); +id a b +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST("фальшив*" IN BOOLEAN MODE) ORDER BY id; +id a b +1 В чащах юга жил-был цитрус? Да но фальшивый экземпляр! ёъ +2 В чащах юга жил-был цитрус? Да но фальшивый экземпляр! ёъ +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST("+Sævör +úlpan" IN BOOLEAN MODE); +id a b +SELECT * FROM t1 +WHERE MATCH (a,b) +AGAINST ('"łódź jeża"@2' IN BOOLEAN MODE); +id a b +7 Pchnąć w tę łódź jeża lub osiem skrzyń fig +SELECT * FROM t1 ORDER BY id; +id a b +1 В чащах юга жил-был цитрус? Да но фальшивый экземпляр! ёъ +2 В чащах юга жил-был цитрус? Да но фальшивый экземпляр! ёъ +3 Μπορῶ νὰ φάω σπασμένα γυαλιὰ χωρὶς νὰ πάθω τίποτα +4 Příliš žluťoučký kůň úpěl ďábelské kódy +6 うゐのおくやま けふこえて +7 Pchnąć w tę łódź jeża lub osiem skrzyń fig +8 MySQL Tutorial request docteam@oraclehelp.com ... +9 Trial version query performace @1255 minute on 2.1Hz Memory 2GB... +10 when To Use MySQL Well for free faq mail@xyz.com ... +DROP TABLE t1; +CREATE TABLE t1(ID INT PRIMARY KEY, +no_fts_field VARCHAR(10), +fts_field VARCHAR(10), +FULLTEXT INDEX f(fts_field)) ENGINE=INNODB; +INSERT INTO t1 VALUES (1, 'AAA', 'BBB'); +SELECT * FROM t1 WHERE MATCH(fts_field) against("BBB"); +ID no_fts_field fts_field +1 AAA BBB +UPDATE t1 SET fts_field='anychange' where id = 1; +SELECT * FROM t1 WHERE MATCH(fts_field) against("anychange"); +ID no_fts_field fts_field +1 AAA anychange +UPDATE t1 SET no_fts_field='anychange' where id = 1; +SELECT * FROM t1 WHERE MATCH(fts_field) against("anychange"); +ID no_fts_field fts_field +1 anychange anychange +UPDATE t1 SET no_fts_field='anychange', fts_field='other' where id = 1; +SELECT * FROM t1 WHERE MATCH(fts_field) against("other"); +ID no_fts_field fts_field +1 anychange other +SELECT * FROM t1 WHERE MATCH(fts_field) against("BBB"); +ID no_fts_field fts_field +DROP INDEX f on t1; +UPDATE t1 SET fts_field='anychange' where id = 1; +UPDATE t1 SET no_fts_field='anychange' where id = 1; +UPDATE t1 SET no_fts_field='anychange', fts_field='other' where id = 1; +CREATE FULLTEXT INDEX f ON t1(FTS_FIELD); +SELECT * FROM t1 WHERE MATCH(fts_field) against("other"); +ID no_fts_field fts_field +1 anychange other +DROP TABLE t1; +CREATE TABLE t1(`FTS_DOC_ID` serial, +no_fts_field VARCHAR(10), +fts_field VARCHAR(10), +FULLTEXT INDEX f(fts_field)) ENGINE=INNODB; +INSERT INTO t1 VALUES (1, 'AAA', 'BBB'); +UPDATE t1 SET fts_field='anychange' where FTS_DOC_ID = 1; +ERROR HY000: Invalid InnoDB FTS Doc ID +UPDATE t1 SET fts_field='anychange', FTS_DOC_ID = 2 where FTS_DOC_ID = 1; +SELECT * FROM t1 WHERE MATCH(fts_field) against("anychange"); +FTS_DOC_ID no_fts_field fts_field +2 AAA anychange +SELECT * FROM t1 WHERE MATCH(fts_field) against("BBB"); +FTS_DOC_ID no_fts_field fts_field +UPDATE t1 SET no_fts_field='anychange' where FTS_DOC_ID = 2; +SELECT * FROM t1 WHERE MATCH(fts_field) against("anychange"); +FTS_DOC_ID no_fts_field fts_field +2 anychange anychange +UPDATE t1 SET no_fts_field='anychange', fts_field='other' where FTS_DOC_ID = 2; +ERROR HY000: Invalid InnoDB FTS Doc ID +SELECT * FROM t1 WHERE MATCH(fts_field) against("other"); +FTS_DOC_ID no_fts_field fts_field +UPDATE t1 SET FTS_DOC_ID = 1 where FTS_DOC_ID = 2; +ERROR HY000: Invalid InnoDB FTS Doc ID +DROP INDEX f ON t1; +UPDATE t1 SET fts_field='newchange' where FTS_DOC_ID = 2; +UPDATE t1 SET no_fts_field='anychange' where FTS_DOC_ID = 2; +SELECT * FROM t1; +FTS_DOC_ID no_fts_field fts_field +2 anychange newchange +DROP TABLE t1; +CREATE TABLE t1(ID INT PRIMARY KEY, +no_fts_field VARCHAR(10), +fts_field VARCHAR(10), +FULLTEXT INDEX f(fts_field), index k(fts_field)) ENGINE=INNODB; +CREATE TABLE t2(ID INT PRIMARY KEY, +no_fts_field VARCHAR(10), +fts_field VARCHAR(10), +FULLTEXT INDEX f(fts_field), +INDEX k2(fts_field), +FOREIGN KEY(fts_field) REFERENCES +t1(fts_field) ON UPDATE CASCADE) ENGINE=INNODB; +INSERT INTO t1 VALUES (1, 'AAA', 'BBB'); +INSERT INTO t2 VALUES (1, 'AAA', 'BBB'); +update t1 set fts_field='newchange' where id =1; +SELECT * FROM t1 WHERE MATCH(fts_field) against("BBB"); +ID no_fts_field fts_field +SELECT * FROM t2 WHERE MATCH(fts_field) against("BBB"); +ID no_fts_field fts_field +SELECT * FROM t1 WHERE MATCH(fts_field) against("newchange"); +ID no_fts_field fts_field +1 AAA newchange +SELECT * FROM t2 WHERE MATCH(fts_field) against("newchange"); +ID no_fts_field fts_field +1 AAA newchange +DROP TABLE t2; +DROP TABLE t1; +CREATE TABLE t1(id INT PRIMARY KEY, +fts_field VARCHAR(10), +FULLTEXT INDEX f(fts_field)) ENGINE=INNODB; +CREATE TABLE t2(id INT PRIMARY KEY, +fts_field VARCHAR(10), +FULLTEXT INDEX f(fts_field)) ENGINE=INNODB; +INSERT INTO t1 values (1,'100'),(2,'200'),(3,'300'),(4,'400'),(5,'500'),(6,'600'), (7,'700'),(8,'800'),(9,'900'),(10,'1000'),(11,'1100'),(12,'1200'); +INSERT INTO t2 values (1,'100'),(2,'200'),(3,'300'),(4,'400'),(5,'500'),(6,'600'), (7,'700'),(8,'800'); +UPDATE t1, t2 set t1.fts_field = CONCAT(t1.fts_field, 'foo'); +UPDATE t1, t2 set t1.fts_field = CONCAT(t1.fts_field, 'foo') WHERE t1.fts_field = "100foo"; +UPDATE t1, t2 set t1.fts_field = CONCAT(t1.fts_field, 'xoo'), t2.fts_field = CONCAT(t1.fts_field, 'xoo') where t1.fts_field=CONCAT(t2.fts_field, 'foo'); +SELECT * FROM t1 WHERE MATCH(fts_field) against("100foofoo"); +id fts_field +1 100foofoo +SELECT * FROM t1 WHERE MATCH(fts_field) against("100foo"); +id fts_field +SELECT * FROM t1 WHERE MATCH(fts_field) against("100"); +id fts_field +SELECT * FROM t2 WHERE MATCH(fts_field) against("400fooxoo"); +id fts_field +4 400fooxoo +SELECT * FROM t2 WHERE MATCH(fts_field) against("100"); +id fts_field +1 100 +SELECT * FROM t2 WHERE MATCH(fts_field) against("200"); +id fts_field +SELECT * FROM t2 WHERE MATCH(fts_field) against("400"); +id fts_field +DROP TABLE t1; +DROP TABLE t2; + +BUG#13701973/64274: MYSQL THREAD WAS SUSPENDED WHEN EXECUTE UPDATE QUERY + +SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; +CREATE TABLE t1 ( +t1_id INT(10) UNSIGNED NOT NULL, +t2_id INT(10) UNSIGNED DEFAULT NULL, +PRIMARY KEY (t1_id), +FOREIGN KEY (t2_id) REFERENCES t2 (t2_id) +ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB; +CREATE TABLE t2 ( +t1_id INT(10) UNSIGNED NOT NULL, +t2_id INT(10) UNSIGNED NOT NULL, +t3_id INT(10) UNSIGNED NOT NULL, +t4_id INT(10) UNSIGNED NOT NULL, +PRIMARY KEY (t2_id), +FOREIGN KEY (t1_id) REFERENCES t1 (t1_id), +FOREIGN KEY (t3_id) REFERENCES t3 (t3_id) +ON DELETE CASCADE ON UPDATE CASCADE, +FOREIGN KEY (t4_id) REFERENCES t4 (t4_id) +) ENGINE=InnoDB; +CREATE TABLE t3 ( +t3_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, +payload char(3), +PRIMARY KEY (t3_id) +) ENGINE=InnoDB; +INSERT INTO t3 VALUES (1, '100'); +CREATE TABLE t4 ( +t2_id INT(10) UNSIGNED DEFAULT NULL, +t4_id INT(10) UNSIGNED NOT NULL, +PRIMARY KEY (t4_id), +FOREIGN KEY (t2_id) REFERENCES t2 (t2_id) +ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB; +SET FOREIGN_KEY_CHECKS=1; +UPDATE t3 SET payload='101' WHERE t3_id=1; +SET FOREIGN_KEY_CHECKS=0; +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; +DROP TABLE t4; +SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; diff --git a/mysql-test/suite/innodb_fts/r/opt.result b/mysql-test/suite/innodb_fts/r/opt.result new file mode 100644 index 00000000000..6385ea2a778 --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/opt.result @@ -0,0 +1,1650 @@ +CREATE TABLE wp( +FTS_DOC_ID BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, +title VARCHAR(255) NOT NULL DEFAULT '', +text MEDIUMTEXT NOT NULL, +dummy INTEGER, +PRIMARY KEY (FTS_DOC_ID), +UNIQUE KEY FTS_DOC_ID_INDEX (FTS_DOC_ID), +FULLTEXT KEY idx (title,text) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +INSERT INTO wp (title, text) VALUES +('MySQL Tutorial','DBMS stands for MySQL DataBase ...'), +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'), +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('MySQL vs. YourSQL','In the following database to database comparison ...'), +('MySQL Security','When configured properly, MySQL ...'); +CREATE TABLE t1 (i INTEGER); +INSERT INTO t1 SELECT FTS_DOC_ID FROM wp; +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE wp; +Table Op Msg_type Msg_text +test.wp analyze status OK +SELECT FTS_DOC_ID, title, MATCH(title, text) AGAINST ('database') AS score1, +MATCH(title, text) AGAINST ('mysql') AS score2 +FROM wp; +FTS_DOC_ID title score1 score2 +1 MySQL Tutorial 0.22764469683170319 0.000000003771856604828372 +2 How To Use MySQL Well 0 0.000000001885928302414186 +3 Optimizing MySQL 0 0.000000001885928302414186 +4 1001 MySQL Tricks 0 0.000000001885928302414186 +5 MySQL vs. YourSQL 0.45528939366340637 0.000000001885928302414186 +6 MySQL Security 0 0.000000003771856604828372 +No sorting for this query +FLUSH STATUS; +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score DESC; +title score +MySQL vs. YourSQL 0.45528939366340637 +MySQL Tutorial 0.22764469683170319 +SHOW SESSION STATUS LIKE 'Sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 0 +Sort_range 0 +Sort_rows 2 +Sort_scan 1 +No sorting for this query even if MATCH is part of an expression +FLUSH STATUS; +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') > 0.1 +ORDER BY score DESC; +title score +MySQL vs. YourSQL 0.45528939366340637 +MySQL Tutorial 0.22764469683170319 +SHOW SESSION STATUS LIKE 'Sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 0 +Sort_range 0 +Sort_rows 2 +Sort_scan 1 +No sorting even if there are several MATCH expressions as long as the +right one is used in ORDER BY +FLUSH STATUS; +SELECT title, MATCH(title, text) AGAINST ('database') AS score1, +MATCH(title, text) AGAINST ('mysql') AS score2 +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score1 DESC; +title score1 score2 +MySQL vs. YourSQL 0.45528939366340637 0.000000001885928302414186 +MySQL Tutorial 0.22764469683170319 0.000000003771856604828372 +SHOW SESSION STATUS LIKE 'Sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 0 +Sort_range 0 +Sort_rows 2 +Sort_scan 1 +No Sorting since FT table is first table in query +FLUSH STATUS; +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp, t1 +WHERE MATCH(title, text) AGAINST ('database') AND FTS_DOC_ID = t1.i +ORDER BY score DESC; +title score +MySQL vs. YourSQL 0.45528939366340637 +MySQL Tutorial 0.22764469683170319 +SHOW SESSION STATUS LIKE 'Sort_rows%'; +Variable_name Value +Sort_rows 2 +Sorting since there is no WHERE clause +FLUSH STATUS; +SELECT MATCH(title, text) AGAINST ('database'), title AS score +FROM wp +ORDER BY score DESC; +MATCH(title, text) AGAINST ('database') score +0 1001 MySQL Tricks +0 How To Use MySQL Well +0 MySQL Security +0 Optimizing MySQL +0.22764469683170319 MySQL Tutorial +0.45528939366340637 MySQL vs. YourSQL +SHOW SESSION STATUS LIKE 'Sort_rows%'; +Variable_name Value +Sort_rows 6 +Sorting since ordering on multiple columns +FLUSH STATUS; +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score DESC, FTS_DOC_ID; +title score +MySQL vs. YourSQL 0.45528939366340637 +MySQL Tutorial 0.22764469683170319 +SHOW SESSION STATUS LIKE 'Sort_rows%'; +Variable_name Value +Sort_rows 2 +Sorting since ordering is not descending +FLUSH STATUS; +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score ASC; +title score +MySQL Tutorial 0.22764469683170319 +MySQL vs. YourSQL 0.45528939366340637 +SHOW SESSION STATUS LIKE 'Sort_rows%'; +Variable_name Value +Sort_rows 2 +Sorting because one is ordering on a different MATCH expression +FLUSH STATUS; +SELECT title, MATCH(title, text) AGAINST ('mysql') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score DESC; +title score +MySQL Tutorial 0.000000003771856604828372 +MySQL vs. YourSQL 0.000000001885928302414186 +SHOW SESSION STATUS LIKE 'Sort_rows%'; +Variable_name Value +Sort_rows 2 +No sorting for this query +FLUSH STATUS; +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +ORDER BY score DESC LIMIT 2; +title score +MySQL vs. YourSQL 0.45528939366340637 +MySQL Tutorial 0.22764469683170319 +SHOW SESSION STATUS LIKE 'Sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 1 +Sort_range 0 +Sort_rows 2 +Sort_scan 1 +Revert to table scan and sorting for this query since not +enough matching rows to satisfy LIMIT clause +FLUSH STATUS; +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +ORDER BY score DESC LIMIT 2; +title score +MySQL vs. YourSQL 0.45528939366340637 +MySQL Tutorial 0.22764469683170319 +SHOW SESSION STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 2 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 14 +SHOW SESSION STATUS LIKE 'Sort_rows%'; +Variable_name Value +Sort_rows 2 +Sorting since no LIMIT clause +FLUSH STATUS; +SELECT MATCH(title, text) AGAINST ('database') AS score, title +FROM wp +ORDER BY score DESC; +score title +0 1001 MySQL Tricks +0 How To Use MySQL Well +0 MySQL Security +0 Optimizing MySQL +0.22764469683170319 MySQL Tutorial +0.45528939366340637 MySQL vs. YourSQL +SHOW SESSION STATUS LIKE 'Sort_rows%'; +Variable_name Value +Sort_rows 6 +Sorting since there is a WHERE clause +FLUSH STATUS; +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE dummy IS NULL +ORDER BY score DESC LIMIT 2; +title score +MySQL vs. YourSQL 0.45528939366340637 +MySQL Tutorial 0.22764469683170319 +SHOW SESSION STATUS LIKE 'Sort_rows%'; +Variable_name Value +Sort_rows 2 +Sorting since ordering is not on a simple MATCH expressions +FLUSH STATUS; +SELECT title, (MATCH(title, text) AGAINST ('database')) * 100 AS score +FROM wp +ORDER BY score DESC LIMIT 2; +title score +MySQL vs. YourSQL 45.52893936634064 +MySQL Tutorial 22.76446968317032 +SHOW SESSION STATUS LIKE 'Sort_rows%'; +Variable_name Value +Sort_rows 2 +No ordinary handler accesses when only accessing FTS_DOC_ID and MATCH +FLUSH STATUS; +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database'); +docid score +5 0.45528939366340637 +1 0.22764469683170319 +SHOW SESSION STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 0 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 0 +Still no handler accesses when adding FTS_DOC_ID to WHERE clause +FLUSH STATUS; +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') AND FTS_DOC_ID > 2; +docid score +5 0.45528939366340637 +SHOW SESSION STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 0 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 0 +Still no handler accesses when ordering by MATCH expression +FLUSH STATUS; +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score; +docid score +1 0.22764469683170319 +5 0.45528939366340637 +SHOW SESSION STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 2 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 3 +Optimization is disabled when ordering on FTS_DOC_ID +FLUSH STATUS; +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY 1 DESC; +docid score +5 0.45528939366340637 +1 0.22764469683170319 +SHOW SESSION STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 2 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 0 +Optimization also work with several MATCH expressions +FLUSH STATUS; +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score1, +MATCH(title, text) AGAINST ('mysql') AS score2 +FROM wp +WHERE MATCH(title, text) AGAINST ('database'); +docid score1 score2 +5 0.45528939366340637 0.000000001885928302414186 +1 0.22764469683170319 0.000000003771856604828372 +SHOW SESSION STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 0 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 0 +Optimization does not apply if sorting on a different MATCH expressions +from the one used to access the +FLUSH STATUS; +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score1, +MATCH(title, text) AGAINST ('mysql') AS score2 +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score2 DESC; +docid score1 score2 +1 0.22764469683170319 0.000000003771856604828372 +5 0.45528939366340637 0.000000001885928302414186 +SHOW SESSION STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 2 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 3 +FLUSH STATUS; +Optimization does not apply for GROUP BY +SET @save_mode = @@sql_mode; +SET sql_mode = (select replace(@@sql_mode,'ONLY_FULL_GROUP_BY','')); +SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +GROUP BY score; +FTS_DOC_ID score +1 0.22764469683170319 +5 0.45528939366340637 +SHOW SESSION STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 2 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 3 +SET sql_mode = @save_mode; +No sorting and no table access with LIMIT clause and only information +from FTS result +FLUSH STATUS; +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score +FROM wp +ORDER BY score DESC LIMIT 2; +docid score +5 0.45528939366340637 +1 0.22764469683170319 +SHOW STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 2 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 14 +SHOW SESSION STATUS LIKE 'Sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 1 +Sort_range 0 +Sort_rows 2 +Sort_scan 1 +If count optimization applies, EXPLAIN shows +"Select tables optimized away." +EXPLAIN SELECT COUNT(*) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE wp fulltext idx idx 0 1 Using where +FLUSH STATUS; +SELECT COUNT(*) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE); +COUNT(*) +2 +Verify that there was no table access +SHOW STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 0 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 0 +Optimization applies also to COUNT(expr) as long as expr is not nullable +EXPLAIN SELECT COUNT(title) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE wp fulltext idx idx 0 1 Using where +SELECT COUNT(title) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE); +COUNT(title) +2 +Optimization does not apply if not a single table query. +EXPLAIN SELECT count(*) +FROM wp, t1 +WHERE MATCH(title, text) AGAINST ('database'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE wp fulltext idx idx 0 1 Using where +1 SIMPLE t1 ALL NULL NULL NULL NULL 6 +SELECT count(*) +FROM wp, t1 +WHERE MATCH(title, text) AGAINST ('database'); +count(*) +12 +Optimization does not apply if MATCH is part of an expression +EXPLAIN SELECT COUNT(title) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE) > 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE wp fulltext idx idx 0 1 Using where +SELECT COUNT(title) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE) > 0; +COUNT(title) +2 +Optimization does not apply if MATCH is part of an expression +EXPLAIN SELECT COUNT(title) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE) > 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE wp fulltext idx idx 0 1 Using where +SELECT COUNT(title) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE) > 0; +COUNT(title) +2 +Optimization does not apply if COUNT expression is nullable +EXPLAIN SELECT COUNT(dummy) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE wp fulltext idx idx 0 1 Using where +SELECT COUNT(dummy) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE); +COUNT(dummy) +0 +FLUSH STATUS; +SELECT MATCH(title, text) AGAINST ('database' WITH QUERY EXPANSION) AS score, +title +FROM wp +WHERE MATCH(title, text) AGAINST ('database' WITH QUERY EXPANSION) +ORDER BY score DESC; +score title +0.000000001885928302414186 1001 MySQL Tricks +0.000000001885928302414186 How To Use MySQL Well +0.000000003771856604828372 MySQL Security +0.22764469683170319 Optimizing MySQL +1.6663280725479126 MySQL Tutorial +2.2718474864959717 MySQL vs. YourSQL +SHOW SESSION STATUS LIKE 'Sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 0 +Sort_range 0 +Sort_rows 6 +Sort_scan 1 +FLUSH STATUS; +SELECT title, +MATCH(title, text) AGAINST ('database' WITH QUERY EXPANSION) AS score +FROM wp +ORDER BY score DESC LIMIT 2; +title score +MySQL vs. YourSQL 2.2718474864959717 +MySQL Tutorial 1.6663280725479126 +SHOW SESSION STATUS LIKE 'Sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 1 +Sort_range 0 +Sort_rows 2 +Sort_scan 1 +FLUSH STATUS; +SELECT FTS_DOC_ID docid, +MATCH(title, text) AGAINST ('database' WITH QUERY EXPANSION) AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database'); +docid score +5 2.2718474864959717 +1 1.6663280725479126 +SHOW SESSION STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 0 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 0 +FLUSH STATUS; +SELECT FTS_DOC_ID docid, +MATCH(title, text) AGAINST ('database' WITH QUERY EXPANSION) AS score +FROM wp +ORDER BY score DESC LIMIT 2; +docid score +5 2.2718474864959717 +1 1.6663280725479126 +SHOW STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 2 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 14 +SHOW SESSION STATUS LIKE 'Sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 1 +Sort_range 0 +Sort_rows 2 +Sort_scan 1 +EXPLAIN SELECT COUNT(*) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' WITH QUERY EXPANSION); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE wp fulltext idx idx 0 1 Using where +FLUSH STATUS; +SELECT COUNT(*) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' WITH QUERY EXPANSION); +COUNT(*) +6 +SHOW STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 0 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 0 +FLUSH STATUS; +SELECT MATCH(title, text) AGAINST ('+MySQL -database' IN BOOLEAN MODE) score, +title +FROM wp +WHERE MATCH(title, text) AGAINST ('+MySQL -database' IN BOOLEAN MODE) +ORDER BY score DESC; +score title +0.000000001885928302414186 1001 MySQL Tricks +0.000000001885928302414186 How To Use MySQL Well +0.000000001885928302414186 Optimizing MySQL +0.000000003771856604828372 MySQL Security +SHOW SESSION STATUS LIKE 'Sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 0 +Sort_range 0 +Sort_rows 4 +Sort_scan 1 +FLUSH STATUS; +SELECT MATCH(title, text) AGAINST ('+MySQL -database' IN BOOLEAN MODE) score, +title +FROM wp +ORDER BY score DESC; +score title +0 MySQL Tutorial +0 MySQL vs. YourSQL +0.000000001885928302414186 1001 MySQL Tricks +0.000000001885928302414186 How To Use MySQL Well +0.000000001885928302414186 Optimizing MySQL +0.000000003771856604828372 MySQL Security +SHOW SESSION STATUS LIKE 'Sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 0 +Sort_range 0 +Sort_rows 6 +Sort_scan 1 +FLUSH STATUS; +SELECT FTS_DOC_ID docid, +MATCH(title, text) AGAINST ('+MySQL -database' IN BOOLEAN MODE) AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('+MySQL -database'); +docid score +5 0 +1 0 +6 0.000000003771856604828372 +2 0.000000001885928302414186 +3 0.000000001885928302414186 +4 0.000000001885928302414186 +SHOW SESSION STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 0 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 0 +FLUSH STATUS; +SELECT FTS_DOC_ID docid, +MATCH(title, text) AGAINST ('+MySQL -database' IN BOOLEAN MODE) AS score +FROM wp +ORDER BY score DESC LIMIT 1; +docid score +6 0.000000003771856604828372 +SHOW STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 1 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 14 +SHOW SESSION STATUS LIKE 'Sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 1 +Sort_range 0 +Sort_rows 1 +Sort_scan 1 +EXPLAIN SELECT COUNT(*) +FROM wp +WHERE MATCH(title,text) AGAINST ('+MySQL -database' IN BOOLEAN MODE); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE wp fulltext idx idx 0 1 Using where +FLUSH STATUS; +SELECT COUNT(*) +FROM wp +WHERE MATCH(title,text) AGAINST ('+MySQL -database' IN BOOLEAN MODE); +COUNT(*) +4 +SHOW STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 0 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 0 +FLUSH STATUS; +SELECT title, +MATCH(title, text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE) AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE) +ORDER BY score DESC; +title score +MySQL Tutorial 0.22764469683170319 +SHOW SESSION STATUS LIKE 'Sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 0 +Sort_range 0 +Sort_rows 1 +Sort_scan 1 +FLUSH STATUS; +SELECT title, +MATCH(title, text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE) AS score +FROM wp +ORDER BY score DESC LIMIT 1; +title score +MySQL Tutorial 0.22764469683170319 +SHOW SESSION STATUS LIKE 'Sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 1 +Sort_range 0 +Sort_rows 1 +Sort_scan 1 +FLUSH STATUS; +SELECT FTS_DOC_ID docid, +MATCH(title, text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE) AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('"MySQL database"@5'); +docid score +1 0.22764469683170319 +SHOW SESSION STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 0 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 0 +FLUSH STATUS; +SELECT FTS_DOC_ID docid, +MATCH(title, text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE) AS score +FROM wp +ORDER BY score DESC LIMIT 1; +docid score +1 0.22764469683170319 +SHOW STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 1 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 14 +SHOW SESSION STATUS LIKE 'Sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 1 +Sort_range 0 +Sort_rows 1 +Sort_scan 1 +EXPLAIN SELECT COUNT(*) +FROM wp +WHERE MATCH(title,text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE wp fulltext idx idx 0 1 Using where +FLUSH STATUS; +SELECT COUNT(*) +FROM wp +WHERE MATCH(title,text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE); +COUNT(*) +1 +SHOW STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 0 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 0 +SELECT title, +MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database' WITH QUERY EXPANSION) +ORDER BY score DESC, title ASC; +title score +MySQL vs. YourSQL 0.45528939366340637 +MySQL Tutorial 0.22764469683170319 +1001 MySQL Tricks 0 +How To Use MySQL Well 0 +MySQL Security 0 +Optimizing MySQL 0 +SELECT title, +MATCH(title, text) AGAINST ('+MySQL -database' IN BOOLEAN MODE) AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('MySQL database' WITH QUERY EXPANSION) +ORDER BY score DESC, title ASC; +title score +MySQL Security 0.000000003771856604828372 +1001 MySQL Tricks 0.000000001885928302414186 +How To Use MySQL Well 0.000000001885928302414186 +Optimizing MySQL 0.000000001885928302414186 +MySQL Tutorial 0 +MySQL vs. YourSQL 0 +SELECT title, +MATCH(title, text) AGAINST ('+MySQL -database' IN BOOLEAN MODE) AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE) +ORDER BY score DESC, title ASC; +title score +MySQL Tutorial 0 +ALTER TABLE wp ENGINE=myisam; +FLUSH STATUS; +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score DESC; +title score +MySQL vs. YourSQL 0.9562782645225525 +MySQL Tutorial 0.5756555199623108 +SHOW SESSION STATUS LIKE 'Sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 0 +Sort_range 0 +Sort_rows 2 +Sort_scan 1 +FLUSH STATUS; +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +ORDER BY score DESC LIMIT 2; +title score +MySQL vs. YourSQL 0.9562782645225525 +MySQL Tutorial 0.5756555199623108 +SHOW SESSION STATUS LIKE 'Sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 1 +Sort_range 0 +Sort_rows 2 +Sort_scan 1 +FLUSH STATUS; +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database'); +docid score +5 0.9562782645225525 +1 0.5756555199623108 +SHOW SESSION STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 3 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 0 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 0 +FLUSH STATUS; +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score +FROM wp +ORDER BY score DESC LIMIT 2; +docid score +5 0.9562782645225525 +1 0.5756555199623108 +SHOW STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 2 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 14 +SHOW SESSION STATUS LIKE 'Sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 1 +Sort_range 0 +Sort_rows 2 +Sort_scan 1 +EXPLAIN SELECT COUNT(*) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE wp fulltext idx idx 0 1 Using where +FLUSH STATUS; +SELECT COUNT(*) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE); +COUNT(*) +2 +SHOW STATUS LIKE 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 0 +Handler_read_last 0 +Handler_read_next 3 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 0 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 0 +DROP TABLE wp, t1; +CREATE TABLE t1 +( +FTS_DOC_ID BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, +title VARCHAR(255) DEFAULT '', +text MEDIUMTEXT , +PRIMARY KEY (FTS_DOC_ID), +UNIQUE KEY FTS_DOC_ID_INDEX (FTS_DOC_ID), +FULLTEXT KEY ft_idx (title,text) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +INSERT INTO t1 (title, text) VALUES +('MySQL Tutorial','DBMS stands for MySQL DataBase ...'), +('How To Use MySQL Well','After you went through a ...'), +('Optimizing MySQL','In this tutorial we will show ...'), +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('MySQL vs. YourSQL database','In the following database to database comparison ...'), +('MySQL Security','When configured properly, MySQL ...'), +('InnoDB', 'InnoDB is a transaction-safe (ACID compliant) storage engine'), +('MySQL is a database management system', 'A database is a structured collection of data...'), +('MySQL databases are relational', 'A relational database stores data in separate tables rather than putting all the data in one big storeroom...'), +('MySQL software is Open Source', 'Open Source means that it is possible for anyone to use and modify the software...'), +('The MySQL Database Server is very fast, reliable, scalable, and easy to use', 'MySQL Server can run comfortably on a desktop or laptop...'), +('MySQL Server works in client/server or embedded systems', 'The MySQL Database Software is a client/server system...'), +('MyISAM', 'MyISAM is based on the older (and no longer available) ISAM storage engine but has many useful extensions'), +('A large amount of contributed MySQL software is available', 'MySQL Server has a practical set of features developed in close cooperation with our users'), +(NULL,NULL); +ANALYZE TABLE t1; +# No ranking +EXPLAIN +SELECT count(*) FROM t1 WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where +SELECT count(*) FROM t1 WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE); +count(*) +6 +EXPLAIN +SELECT count(*) FROM t1 WHERE MATCH (title, text) AGAINST ('data*' IN BOOLEAN MODE) ORDER BY title LIMIT 3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where +SELECT count(*) FROM t1 WHERE MATCH (title, text) AGAINST ('data*' IN BOOLEAN MODE) ORDER BY title LIMIT 3; +count(*) +6 +EXPLAIN +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('+fast +database' IN BOOLEAN MODE); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('+fast +database' IN BOOLEAN MODE); +FTS_DOC_ID title +11 The MySQL Database Server is very fast, reliable, scalable, and easy to use +EXPLAIN +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION); +FTS_DOC_ID title +11 The MySQL Database Server is very fast, reliable, scalable, and easy to use +12 MySQL Server works in client/server or embedded systems +10 MySQL software is Open Source +4 1001 MySQL Tricks +14 A large amount of contributed MySQL software is available +2 How To Use MySQL Well +13 MyISAM +5 MySQL vs. YourSQL database +8 MySQL is a database management system +1 MySQL Tutorial +9 MySQL databases are relational +6 MySQL Security +3 Optimizing MySQL +EXPLAIN +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('"very fast"@3' IN BOOLEAN MODE); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('"very fast"@3' IN BOOLEAN MODE); +FTS_DOC_ID title +11 The MySQL Database Server is very fast, reliable, scalable, and easy to use +EXPLAIN SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+for' IN BOOLEAN MODE); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+for' IN BOOLEAN MODE); +FTS_DOC_ID +# No sorting by rank +EXPLAIN SELECT FTS_DOC_ID, TITLE FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY title; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where; Using filesort +SELECT FTS_DOC_ID, TITLE FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY title; +FTS_DOC_ID TITLE +9 MySQL databases are relational +8 MySQL is a database management system +12 MySQL Server works in client/server or embedded systems +1 MySQL Tutorial +5 MySQL vs. YourSQL database +11 The MySQL Database Server is very fast, reliable, scalable, and easy to use +EXPLAIN SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+fast +database' IN BOOLEAN MODE); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+fast +database' IN BOOLEAN MODE); +FTS_DOC_ID +11 +EXPLAIN +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) ORDER BY title; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where; Using filesort +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) ORDER BY title; +FTS_DOC_ID title +4 1001 MySQL Tricks +14 A large amount of contributed MySQL software is available +2 How To Use MySQL Well +13 MyISAM +9 MySQL databases are relational +8 MySQL is a database management system +6 MySQL Security +12 MySQL Server works in client/server or embedded systems +10 MySQL software is Open Source +1 MySQL Tutorial +5 MySQL vs. YourSQL database +3 Optimizing MySQL +11 The MySQL Database Server is very fast, reliable, scalable, and easy to use +EXPLAIN +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('"very fast"@3' IN BOOLEAN MODE) ORDER BY title; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where; Using filesort +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('"very fast"@3' IN BOOLEAN MODE) ORDER BY title; +FTS_DOC_ID title +11 The MySQL Database Server is very fast, reliable, scalable, and easy to use +# LIMIT optimization +EXPLAIN SELECT FTS_DOC_ID, TITLE FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +LIMIT 3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where +SELECT FTS_DOC_ID, TITLE FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +LIMIT 3; +FTS_DOC_ID TITLE +11 The MySQL Database Server is very fast, reliable, scalable, and easy to use +5 MySQL vs. YourSQL database +8 MySQL is a database management system +EXPLAIN SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+fast +database' IN BOOLEAN MODE) +LIMIT 3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+fast +database' IN BOOLEAN MODE) +LIMIT 3; +FTS_DOC_ID +11 +EXPLAIN SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+fast +database' IN BOOLEAN MODE) +ORDER BY title +LIMIT 3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where; Using filesort +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+fast +database' IN BOOLEAN MODE) +ORDER BY title +LIMIT 3; +FTS_DOC_ID +11 +EXPLAIN +SELECT FTS_DOC_ID FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) ORDER BY title LIMIT 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where; Using filesort +SELECT FTS_DOC_ID FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) ORDER BY title LIMIT 1; +FTS_DOC_ID +4 +EXPLAIN +SELECT FTS_DOC_ID FROM t1 WHERE MATCH(title, text) AGAINST ('"very fast"@3' IN BOOLEAN MODE) ORDER BY title LIMIT 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where; Using filesort +SELECT FTS_DOC_ID FROM t1 WHERE MATCH(title, text) AGAINST ('"very fast"@3' IN BOOLEAN MODE) ORDER BY title LIMIT 1; +FTS_DOC_ID +11 +EXPLAIN +SELECT FTS_DOC_ID, MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) as rank +FROM t1 WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY rank, FTS_DOC_ID +LIMIT 3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where; Using temporary; Using filesort +SELECT FTS_DOC_ID, MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) as rank +FROM t1 WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY rank, FTS_DOC_ID +LIMIT 3; +FTS_DOC_ID rank +1 0.15835624933242798 +9 0.15835624933242798 +12 0.15835624933242798 +EXPLAIN +SELECT FTS_DOC_ID, MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) as rank +FROM t1 WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY rank DESC, FTS_DOC_ID ASC +LIMIT 3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where; Using temporary; Using filesort +SELECT FTS_DOC_ID, MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) as rank +FROM t1 WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY rank DESC, FTS_DOC_ID ASC +LIMIT 3; +FTS_DOC_ID rank +11 1.5415468215942383 +5 0.47506874799728394 +8 0.31671249866485596 +EXPLAIN SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) as rank +FROM t1 +ORDER BY rank DESC +LIMIT 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 15 Using temporary; Using filesort +SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) as rank +FROM t1 +ORDER BY rank DESC +LIMIT 2; +FTS_DOC_ID rank +5 0.47506874799728394 +8 0.31671249866485596 +EXPLAIN SELECT FTS_DOC_ID, MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) as rank +FROM t1 +ORDER BY rank DESC +LIMIT 3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 15 Using temporary; Using filesort +SELECT FTS_DOC_ID, MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) as rank +FROM t1 +ORDER BY rank DESC +LIMIT 3; +FTS_DOC_ID rank +11 1.5415468215942383 +5 0.47506874799728394 +8 0.31671249866485596 +EXPLAIN SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) +ORDER BY MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) DESC, +FTS_DOC_ID ASC; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where; Using temporary; Using filesort +SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) +ORDER BY MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) DESC, +FTS_DOC_ID ASC; +FTS_DOC_ID rank +5 0.47506874799728394 +8 0.31671249866485596 +1 0.15835624933242798 +9 0.15835624933242798 +11 0.15835624933242798 +12 0.15835624933242798 +EXPLAIN SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) and FTS_DOC_ID > 1 +ORDER BY MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) DESC +LIMIT 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext PRIMARY,FTS_DOC_ID_INDEX,ft_idx ft_idx 0 1 Using where; Using temporary; Using filesort +SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) and FTS_DOC_ID > 1 +ORDER BY MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) DESC +LIMIT 2; +FTS_DOC_ID rank +5 0.47506874799728394 +8 0.31671249866485596 +EXPLAIN +SELECT FTS_DOC_ID,MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) +ORDER BY rank +LIMIT 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where; Using temporary; Using filesort +SELECT FTS_DOC_ID,MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) +ORDER BY rank +LIMIT 1; +FTS_DOC_ID rank +3 0.009391550906002522 +EXPLAIN +SELECT FTS_DOC_ID,MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) +ORDER BY rank DESC +LIMIT 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where; Using temporary; Using filesort +SELECT FTS_DOC_ID,MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) +ORDER BY rank DESC +LIMIT 1; +FTS_DOC_ID rank +11 15.345823287963867 +EXPLAIN +SELECT FTS_DOC_ID,MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) +ORDER BY MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) +LIMIT 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where; Using temporary; Using filesort +SELECT FTS_DOC_ID,MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) +ORDER BY MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) DESC +LIMIT 1; +FTS_DOC_ID rank +11 15.345823287963867 +# WHERE optimization on MATCH > 'some_rank' +EXPLAIN SELECT FTS_DOC_ID FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) > 0.1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) > 0.1; +FTS_DOC_ID +11 +5 +8 +1 +9 +12 +# additional test for correct behaviour +EXPLAIN SELECT * FROM t1 ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC LIMIT 10; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 15 Using temporary; Using filesort +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) AND +MATCH (title, text) AGAINST ('mysql' IN NATURAL LANGUAGE MODE) +LIMIT 6; +FTS_DOC_ID +11 +5 +8 +1 +9 +12 +# test OR condition +SELECT FTS_DOC_ID +FROM t1 +WHERE MATCH(title, text) AGAINST ('database') +OR MATCH(title, text) AGAINST ('mysql') +ORDER BY MATCH(title, text) AGAINST ('database') DESC, FTS_DOC_ID ASC; +FTS_DOC_ID +5 +8 +1 +9 +11 +12 +2 +3 +4 +6 +10 +14 +EXPLAIN SELECT FTS_DOC_ID +FROM t1 +WHERE MATCH(title, text) AGAINST ('database') +OR MATCH(title, text) AGAINST ('mysql') +ORDER BY MATCH(title, text) AGAINST ('database') DESC, FTS_DOC_ID ASC; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 15 Using where; Using temporary; Using filesort +# MATCH and GROUP BY, DISTINCT +SET sql_mode = (select replace(@@sql_mode,'ONLY_FULL_GROUP_BY','')); +EXPLAIN SELECT FTS_DOC_ID FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +GROUP BY FTS_DOC_ID +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where; Using temporary; Using filesort +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +GROUP BY FTS_DOC_ID +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; +FTS_DOC_ID +11 +5 +8 +EXPLAIN SELECT FTS_DOC_ID FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +GROUP BY title +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where; Using temporary; Using filesort +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +GROUP BY title +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; +FTS_DOC_ID +11 +5 +8 +EXPLAIN SELECT MAX(FTS_DOC_ID) FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where +SELECT MAX(FTS_DOC_ID) FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; +MAX(FTS_DOC_ID) +12 +EXPLAIN SELECT DISTINCT(title) FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where; Using temporary; Using filesort +SELECT DISTINCT(title) FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; +title +The MySQL Database Server is very fast, reliable, scalable, and easy to use +MySQL vs. YourSQL database +MySQL is a database management system +EXPLAIN SELECT DISTINCT(FTS_DOC_ID) FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext ft_idx ft_idx 0 1 Using where; Using temporary; Using filesort +SELECT DISTINCT(FTS_DOC_ID) FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; +FTS_DOC_ID +11 +5 +8 +SET sql_mode = @save_mode; +# FTS index access +SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) as rank +FROM t1 +ORDER BY rank DESC +LIMIT 2; +FTS_DOC_ID rank +5 0.47506874799728394 +8 0.31671249866485596 +EXPLAIN SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) as rank +FROM t1 +ORDER BY rank DESC +LIMIT 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 15 Using temporary; Using filesort +SELECT a.FTS_DOC_ID, b.FTS_DOC_ID +FROM t1 a, t1 b +WHERE MATCH(a.title, a.text) AGAINST ('+database' IN BOOLEAN MODE) and +MATCH(b.title, b.text) AGAINST ('+mysql' IN BOOLEAN MODE) and +a.FTS_DOC_ID = b.FTS_DOC_ID; +FTS_DOC_ID FTS_DOC_ID +5 5 +8 8 +1 1 +9 9 +11 11 +12 12 +EXPLAIN SELECT a.FTS_DOC_ID, b.FTS_DOC_ID +FROM t1 a, t1 b +WHERE MATCH(a.title, a.text) AGAINST ('+database' IN BOOLEAN MODE) and +MATCH(b.title, b.text) AGAINST ('+mysql' IN BOOLEAN MODE) and +a.FTS_DOC_ID = b.FTS_DOC_ID; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE a fulltext PRIMARY,FTS_DOC_ID_INDEX,ft_idx ft_idx 0 1 Using where +1 SIMPLE b eq_ref PRIMARY,FTS_DOC_ID_INDEX,ft_idx PRIMARY 8 test.a.FTS_DOC_ID 1 Using where +SELECT a.FTS_DOC_ID, MATCH(a.title, a.text) AGAINST ('+database' IN BOOLEAN MODE), +b.FTS_DOC_ID, MATCH(b.title, b.text) AGAINST ('+database' IN BOOLEAN MODE) +FROM t1 a, t1 b +WHERE MATCH(a.title, a.text) AGAINST ('+database' IN BOOLEAN MODE) and +MATCH(b.title, b.text) AGAINST ('+database' IN BOOLEAN MODE); +FTS_DOC_ID MATCH(a.title, a.text) AGAINST ('+database' IN BOOLEAN MODE) FTS_DOC_ID MATCH(b.title, b.text) AGAINST ('+database' IN BOOLEAN MODE) +5 0.47506874799728394 5 0.47506874799728394 +5 0.47506874799728394 8 0.31671249866485596 +5 0.47506874799728394 1 0.15835624933242798 +5 0.47506874799728394 9 0.15835624933242798 +5 0.47506874799728394 11 0.15835624933242798 +5 0.47506874799728394 12 0.15835624933242798 +8 0.31671249866485596 5 0.47506874799728394 +8 0.31671249866485596 8 0.31671249866485596 +8 0.31671249866485596 1 0.15835624933242798 +8 0.31671249866485596 9 0.15835624933242798 +8 0.31671249866485596 11 0.15835624933242798 +8 0.31671249866485596 12 0.15835624933242798 +1 0.15835624933242798 5 0.47506874799728394 +1 0.15835624933242798 8 0.31671249866485596 +1 0.15835624933242798 1 0.15835624933242798 +1 0.15835624933242798 9 0.15835624933242798 +1 0.15835624933242798 11 0.15835624933242798 +1 0.15835624933242798 12 0.15835624933242798 +9 0.15835624933242798 5 0.47506874799728394 +9 0.15835624933242798 8 0.31671249866485596 +9 0.15835624933242798 1 0.15835624933242798 +9 0.15835624933242798 9 0.15835624933242798 +9 0.15835624933242798 11 0.15835624933242798 +9 0.15835624933242798 12 0.15835624933242798 +11 0.15835624933242798 5 0.47506874799728394 +11 0.15835624933242798 8 0.31671249866485596 +11 0.15835624933242798 1 0.15835624933242798 +11 0.15835624933242798 9 0.15835624933242798 +11 0.15835624933242798 11 0.15835624933242798 +11 0.15835624933242798 12 0.15835624933242798 +12 0.15835624933242798 5 0.47506874799728394 +12 0.15835624933242798 8 0.31671249866485596 +12 0.15835624933242798 1 0.15835624933242798 +12 0.15835624933242798 9 0.15835624933242798 +12 0.15835624933242798 11 0.15835624933242798 +12 0.15835624933242798 12 0.15835624933242798 +EXPLAIN SELECT a.FTS_DOC_ID, MATCH(a.title, a.text) AGAINST ('+database' IN BOOLEAN MODE), +b.FTS_DOC_ID, MATCH(b.title, b.text) AGAINST ('+database' IN BOOLEAN MODE) +FROM t1 a, t1 b +WHERE MATCH(a.title, a.text) AGAINST ('+database' IN BOOLEAN MODE) and +MATCH(b.title, b.text) AGAINST ('+database' IN BOOLEAN MODE); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE a fulltext ft_idx ft_idx 0 1 Using where +1 SIMPLE b fulltext ft_idx ft_idx 0 1 Using where +EXPLAIN SELECT FTS_DOC_ID FROM t1 WHERE MATCH(title, text) AGAINST ("data*" IN BOOLEAN MODE) * 100; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 15 Using where +SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ("data*" IN BOOLEAN MODE) * 100 +FROM t1 WHERE MATCH(title, text) AGAINST ("data*" IN BOOLEAN MODE) * 100; +FTS_DOC_ID MATCH(title, text) AGAINST ("data*" IN BOOLEAN MODE) * 100 +1 4.92168664932251 +5 14.76505994796753 +8 9.84337329864502 +9 4.92168664932251 +11 4.92168664932251 +12 4.92168664932251 +SELECT * FROM t1 WHERE title IS NULL AND text IS NULL; +FTS_DOC_ID title text +15 NULL NULL +CREATE TABLE t2 SELECT FTS_DOC_ID as doc_id, title, text FROM t1; +ALTER TABLE t2 ADD PRIMARY KEY (doc_id); +ALTER TABLE t2 ADD FULLTEXT KEY ft_idx (title,text); +ANALYZE TABLE t2; +EXPLAIN SELECT DOC_ID FROM t2 WHERE MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) * 100; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 15 Using where +SELECT DOC_ID FROM t2 WHERE MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) * 100; +DOC_ID +1 +5 +8 +9 +11 +12 +EXPLAIN SELECT FTS_DOC_ID FROM t1 WHERE MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) * 100; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 15 Using where +SELECT FTS_DOC_ID FROM t1 WHERE MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) * 100; +FTS_DOC_ID +1 +5 +8 +9 +11 +12 +DROP TABLE t1, t2; +"Check hints with uft8 charset for 2 cases" +set names utf8; +CREATE TABLE t1 ( +FTS_DOC_ID BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), +text TEXT +) CHARACTER SET = utf8, ENGINE=InnoDB; +INSERT INTO t1 (title, text) VALUES +('Я могу есть стекло', 'оно мне не вредит'), +('Мога да ям стъкло', 'то не ми вреди'), +('Μπορῶ νὰ φάω σπασμένα' ,'γυαλιὰ χωρὶς νὰ πάθω τίποτα'), +('Příliš žluťoučký kůň', 'úpěl ďábelské kódy'), +('Sævör grét', 'áðan því úlpan var ónýt'), +('うゐのおくやま','けふこえて'), +('いろはにほへど ちりぬる','あさきゆめみじ ゑひもせず'); +CREATE FULLTEXT INDEX idx on t1 (title, text); +# No ranking +EXPLAIN +SELECT count(*) FROM t1 WHERE MATCH (title, text) AGAINST ('вредит' IN NATURAL LANGUAGE MODE); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext idx idx 0 1 Using where +SELECT count(*) FROM t1 WHERE MATCH (title, text) AGAINST ('вредит' IN NATURAL LANGUAGE MODE); +count(*) +1 +EXPLAIN +SELECT * FROM t1 WHERE MATCH(title, text) AGAINST ("оно" WITH QUERY EXPANSION); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext idx idx 0 1 Using where +SELECT * FROM t1 WHERE MATCH(title, text) AGAINST ("оно" WITH QUERY EXPANSION); +FTS_DOC_ID title text +1 Я могу есть стекло оно мне не вредит +# No sorting by rank +EXPLAIN SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+(Мога τίποτα)' IN BOOLEAN MODE); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext idx idx 0 1 Using where +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+(Мога τίποτα)' IN BOOLEAN MODE); +FTS_DOC_ID +2 +3 +DROP TABLE t1; +# +# Bug #18924341 CRASH IN TEST_IF_SKIP_SORT_ORDER, GROUP BY MATCH AGAINST DESC +# +CREATE TABLE t1 (f1 CHAR(1), FULLTEXT KEY (f1)); +SELECT 1 FROM t1 NATURAL JOIN t1 a GROUP BY MATCH(t1.f1) AGAINST ("1") DESC; +1 +DROP TABLE t1; +# +# Bug#20261601 ASSERTION FAILED: !FIRST_QEP_TAB->TABLE()->NO_KEYREAD +# +CREATE TABLE t1(a INT PRIMARY KEY); +INSERT INTO t1 VALUES(1),(2); +SELECT (SELECT MATCH(`a`)AGAINST('1') FROM t1) FROM t1; +ERROR HY000: Can't find FULLTEXT index matching the column list +SELECT 1, a IN (SELECT a FROM t1) FROM t1; +1 a IN (SELECT a FROM t1) +1 1 +1 1 +DROP TABLE t1; +# +# Bug#20442572 ASSERTION `!FIRST_QEP_TAB->TABLE()->NO_KEYREAD' FAILED. +# Bug#75688 Assertion `!first_qep_tab->table()->no_keyread' failed. +# +CREATE TABLE t1(a INT,b POINT NOT NULL,KEY(a)); +HANDLER t1 OPEN; +select * from t1 where MATCH a,b AGAINST('"Now sUPPort"' IN BOOLEAN MODE); +a b +prepare stmt1 from "truncate t1"; +SELECT a IN(SELECT a FROM t1)FROM t1; +a IN(SELECT a FROM t1) +deallocate prepare stmt1; +DROP TABLE t1; +# +# Bug #20685427 INVALID WRITE OF FREED MEMORY IN ITEM_FUNC_MATCH::CLEANUP +# +CREATE TABLE t1(a TEXT CHARSET LATIN1, FULLTEXT KEY(a)) ENGINE=INNODB; +SELECT MATCH(a) AGAINST ('') FROM (SELECT a FROM t1 LIMIT 1) q; +ERROR HY000: Can't find FULLTEXT index matching the column list +DROP TABLE t1; +# +# Bug#21140067 EXPLAIN .. MATCH AGAINST: ASSERTION FAILED: TO <= END +# +CREATE TABLE t1(f1 CHAR(1) CHARSET latin1, FULLTEXT(f1)) ENGINE=INNODB; +EXPLAIN SELECT 1 FROM t1 WHERE 1.238585e+308 <= MATCH(f1) AGAINST ('1' IN BOOLEAN MODE); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext f1 f1 0 1 Using where +EXPLAIN FORMAT = JSON SELECT 1 FROM t1 WHERE 1.238585e+308 <= MATCH(f1) AGAINST ('1' IN BOOLEAN MODE); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t1", + "access_type": "fulltext", + "possible_keys": ["f1"], + "key": "f1", + "key_length": "0", + "used_key_parts": ["f1"], + "rows": 1, + "filtered": 100, + "attached_condition": "1.238585e+308 <= (match t1.f1 against ('1' in boolean mode))" + } + } +} +DROP TABLE t1; +# +# Bug#21140088 MATCH AGAINST: ASSERTION FAILED: !TABLE || (!TABLE->READ_SET || BITMAP_IS_SET +# +SET sql_mode=''; +CREATE TABLE t1(a INT) ENGINE=INNODB; +CREATE TABLE t2(b TEXT CHARSET LATIN1, FULLTEXT(b), PRIMARY KEY(b(10))) ENGINE=INNODB; +INSERT INTO t2 VALUES ('a'),('b'); +SELECT NOT EXISTS (SELECT MATCH(b) AGAINST ('1') FROM t1) FROM t2 GROUP BY "a"; +ERROR HY000: Incorrect arguments to MATCH +DROP TABLE t1, t2; +CREATE TABLE t1(a INT) ENGINE=MyISAM; +CREATE TABLE t2(b TEXT CHARSET LATIN1, FULLTEXT(b), PRIMARY KEY(b(10))) ENGINE=MyISAM; +INSERT INTO t2 VALUES ('a'),('b'); +SELECT NOT EXISTS (SELECT MATCH(b) AGAINST ('1' in BOOLEAN MODE) FROM t1) FROM t2 GROUP BY "a"; +NOT EXISTS (SELECT MATCH(b) AGAINST ('1' in BOOLEAN MODE) FROM t1) +1 +DROP TABLE t1, t2; +SET sql_mode=default; +# +# Bug#21140039 ASSERTION FAILED: !FIRST_QEP_TAB->TABLE()->NO_KEYREAD MATCH AGAINST..... +# +CREATE TABLE t1 +( +a INT, +b INT, +c CHAR(1) CHARSET latin1, +PRIMARY KEY (b,a), +FULLTEXT KEY (c) +) ENGINE=INNODB; +SELECT "a" NOT IN(SELECT b FROM t1 WHERE MATCH(c) AGAINST ('a' IN BOOLEAN MODE)); +"a" NOT IN(SELECT b FROM t1 WHERE MATCH(c) AGAINST ('a' IN BOOLEAN MODE)) +1 +DROP TABLE t1; +# +# Bug#21300774 ASSERT `!INIT_FTFUNCS(THD, SELECT_LEX)` IN JOIN::RESET AT SQL/SQL_SELECT.CC:874 +# +CREATE TABLE t1 (f1 INT); +INSERT INTO t1 VALUES (1); +INSERT INTO t1 VALUES (2); +CREATE TABLE t2 (ft TEXT, FULLTEXT KEY ft(ft)); +INSERT INTO t2 VALUES ('abc'); +INSERT INTO t2 VALUES ('def'); +UPDATE t1 SET f1 = +(SELECT t1.f1 FROM t2 WHERE NOT TRUE AND +MATCH (ft) AGAINST ((SELECT 'xyz' FROM t2))); +ERROR 21000: Subquery returns more than 1 row +DROP TABLE t1, t2; +# +# Bug#22679209: FULL-TEXT QUERIES WITH ADDITIONAL SECONDARY INDEX +# GIVES NULL OR ZERO ROWS +# +CREATE TABLE t1 ( +f1 INTEGER, +title varchar(255), +body mediumtext, +KEY f1 (f1), +FULLTEXT KEY title (title), +FULLTEXT KEY body (body) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES +(1, 'Insert into table', 'insert into table select from'), +(1, 'Delete from table', 'insert into table select from'), +(1, 'Update', 'perform update'), +(2, 'Insert into table', 'insert into table select from'), +( 2, 'Delete from table', 'some body text here'), +( 2, 'Update', 'perform update'), +( 3, 'Insert into table', 'insert into table select from'), +( 3, 'Delete from table', 'some body text here'); +SELECT f1 FROM t1 WHERE f1=1 AND +(MATCH (title) AGAINST ('table' IN BOOLEAN MODE) OR +MATCH (body) AGAINST ('table' IN BOOLEAN MODE)); +f1 +1 +1 +DROP TABLE t1; +# End of test for Bug#22679209 diff --git a/mysql-test/suite/innodb_fts/r/phrase.result b/mysql-test/suite/innodb_fts/r/phrase.result new file mode 100644 index 00000000000..efcbaeac66c --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/phrase.result @@ -0,0 +1,84 @@ +CREATE TABLE articles ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), +body TEXT, +FULLTEXT (title,body) +) ENGINE=InnoDB; +INSERT INTO articles (title,body) VALUES +(NULL, 'mysql good database'), +(NULL, ' mysql good database'), +('', 'mysql good database'), +('', ' mysql good database'), +(' ', 'mysql good database'), +('mysql', 'good database'), +('mysql ', 'good database'), +('mysql', ' good database'), +('mysql good database', ''), +('mysql good database', NULL); +SET GLOBAL innodb_ft_aux_table="test/articles"; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION +database 1 10 10 1 11 +database 1 10 10 2 12 +database 1 10 10 3 11 +database 1 10 10 4 12 +database 1 10 10 5 13 +database 1 10 10 6 11 +database 1 10 10 7 12 +database 1 10 10 8 12 +database 1 10 10 9 11 +database 1 10 10 10 11 +good 1 10 10 1 6 +good 1 10 10 2 7 +good 1 10 10 3 6 +good 1 10 10 4 7 +good 1 10 10 5 8 +good 1 10 10 6 6 +good 1 10 10 7 7 +good 1 10 10 8 7 +good 1 10 10 9 6 +good 1 10 10 10 6 +mysql 1 10 10 1 0 +mysql 1 10 10 2 1 +mysql 1 10 10 3 0 +mysql 1 10 10 4 1 +mysql 1 10 10 5 2 +mysql 1 10 10 6 0 +mysql 1 10 10 7 0 +mysql 1 10 10 8 0 +mysql 1 10 10 9 0 +mysql 1 10 10 10 0 +SET GLOBAL innodb_ft_aux_table=default; +SELECT * FROM articles; +id title body +1 NULL mysql good database +2 NULL mysql good database +3 mysql good database +4 mysql good database +5 mysql good database +6 mysql good database +7 mysql good database +8 mysql good database +9 mysql good database +10 mysql good database NULL +SELECT * FROM articles WHERE MATCH(title, body) +AGAINST('"mysql good database"' IN BOOLEAN MODE); +id title body +1 NULL mysql good database +2 NULL mysql good database +3 mysql good database +4 mysql good database +5 mysql good database +9 mysql good database +10 mysql good database NULL +SELECT * FROM articles WHERE MATCH(title, body) +AGAINST('("mysql good database")' IN BOOLEAN MODE); +id title body +1 NULL mysql good database +2 NULL mysql good database +3 mysql good database +4 mysql good database +5 mysql good database +9 mysql good database +10 mysql good database NULL +DROP TABLE articles; diff --git a/mysql-test/suite/innodb_fts/r/result_cache_limit.result b/mysql-test/suite/innodb_fts/r/result_cache_limit.result new file mode 100644 index 00000000000..4f13f4e702e --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/result_cache_limit.result @@ -0,0 +1,31 @@ +CREATE TABLE t1 ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +a VARCHAR(200), +b TEXT +) ENGINE= InnoDB; +CREATE FULLTEXT INDEX idx on t1 (a,b); +INSERT INTO t1 (a,b) VALUES +('MySQL from Tutorial','DBMS stands for DataBase ...') , +('when To Use MySQL Well','After that you went through a ...'), +('where will Optimizing MySQL','what In this tutorial we will show ...'), +('MySQL from Tutorial','DBMS stands for DataBase ...') , +('when To Use MySQL Well','After that you went through a ...'), +('where will Optimizing MySQL','what In this tutorial we will show ...'), +('MySQL from Tutorial','DBMS stands for DataBase ...') , +('when To Use MySQL Well','After that you went through a ...'), +('where will Optimizing MySQL','what In this tutorial we will show ...'); +SET @save_limit=@@GLOBAL.innodb_ft_result_cache_limit; +SET @save_dbug=@@debug_dbug; +SET debug_dbug="+d,fts_instrument_result_cache_limit"; +SELECT COUNT(*) FROM t1 WHERE MATCH (a,b) AGAINST ('mysql' IN BOOLEAN MODE); +COUNT(*) +9 +SELECT COUNT(*) FROM t1 WHERE MATCH (a,b) AGAINST ('mysql' WITH QUERY EXPANSION); +ERROR HY000: Table handler out of memory +SELECT COUNT(*) FROM t1 WHERE MATCH (a,b) AGAINST ('"mysql database"' IN BOOLEAN MODE); +ERROR HY000: Table handler out of memory +SELECT COUNT(*) FROM t1 WHERE MATCH (a,b) AGAINST ('"mysql database" @ 5' IN BOOLEAN MODE); +ERROR HY000: Table handler out of memory +SET debug_dbug=@save_dbug; +DROP TABLE t1; +SET GLOBAL innodb_ft_result_cache_limit=@save_limit; diff --git a/mysql-test/suite/innodb_fts/r/savepoint.result b/mysql-test/suite/innodb_fts/r/savepoint.result new file mode 100644 index 00000000000..1abfc961d0a --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/savepoint.result @@ -0,0 +1,318 @@ +CREATE TABLE articles ( +id INT UNSIGNED NOT NULL PRIMARY KEY, +title VARCHAR(200), +FULLTEXT (title) +) ENGINE= InnoDB; +TRUNCATE TABLE articles; +INSERT INTO articles(id, title) VALUES(1, 'mysql'); +BEGIN; +INSERT INTO articles(id, title) VALUES(2, 'mysql'); +SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(3, 'mysql'); +ROLLBACK TO SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(4, 'mysql'); +COMMIT; +INSERT INTO articles(id, title) VALUES(5, 'mysql'); +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); +id title +1 mysql +2 mysql +4 mysql +5 mysql +TRUNCATE TABLE articles; +INSERT INTO articles(id, title) VALUES(1, 'mysql'); +BEGIN; +INSERT INTO articles(id, title) VALUES(2, 'mysql'); +SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(3, 'mysql'); +ROLLBACK TO SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(4, 'mysql'); +SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(5, 'mysql'); +ROLLBACK TO SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(6, 'mysql'); +COMMIT; +INSERT INTO articles(id, title) VALUES(7, 'mysql'); +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); +id title +1 mysql +2 mysql +4 mysql +6 mysql +7 mysql +TRUNCATE TABLE articles; +INSERT INTO articles(id, title) VALUES(1, 'mysql'); +BEGIN; +INSERT INTO articles(id, title) VALUES(2, 'mysql'); +SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(3, 'mysql'); +SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(4, 'mysql'); +ROLLBACK TO SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(5, 'mysql'); +COMMIT; +INSERT INTO articles(id, title) VALUES(6, 'mysql'); +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); +id title +1 mysql +2 mysql +5 mysql +6 mysql +TRUNCATE TABLE articles; +INSERT INTO articles(id, title) VALUES(1, 'mysql'); +BEGIN; +INSERT INTO articles(id, title) VALUES(2, 'mysql'); +SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(3, 'mysql'); +SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(4, 'mysql'); +ROLLBACK TO SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(5, 'mysql'); +ROLLBACK TO SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(6, 'mysql'); +COMMIT; +INSERT INTO articles(id, title) VALUES(7, 'mysql'); +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); +id title +1 mysql +2 mysql +6 mysql +7 mysql +TRUNCATE TABLE articles; +INSERT INTO articles(id, title) VALUES(1, 'mysql'); +BEGIN; +INSERT INTO articles(id, title) VALUES(2, 'mysql'); +SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(3, 'mysql'); +RELEASE SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(4, 'mysql'); +COMMIT; +INSERT INTO articles(id, title) VALUES(5, 'mysql'); +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); +id title +1 mysql +2 mysql +3 mysql +4 mysql +5 mysql +TRUNCATE TABLE articles; +INSERT INTO articles(id, title) VALUES(1, 'mysql'); +BEGIN; +INSERT INTO articles(id, title) VALUES(2, 'mysql'); +SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(3, 'mysql'); +RELEASE SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(4, 'mysql'); +SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(5, 'mysql'); +RELEASE SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(6, 'mysql'); +COMMIT; +INSERT INTO articles(id, title) VALUES(7, 'mysql'); +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); +id title +1 mysql +2 mysql +3 mysql +4 mysql +5 mysql +6 mysql +7 mysql +TRUNCATE TABLE articles; +INSERT INTO articles(id, title) VALUES(1, 'mysql'); +BEGIN; +INSERT INTO articles(id, title) VALUES(2, 'mysql'); +SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(3, 'mysql'); +SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(4, 'mysql'); +RELEASE SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(5, 'mysql'); +COMMIT; +INSERT INTO articles(id, title) VALUES(6, 'mysql'); +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); +id title +1 mysql +2 mysql +3 mysql +4 mysql +5 mysql +6 mysql +TRUNCATE TABLE articles; +INSERT INTO articles(id, title) VALUES(1, 'mysql'); +BEGIN; +INSERT INTO articles(id, title) VALUES(2, 'mysql'); +SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(3, 'mysql'); +SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(4, 'mysql'); +RELEASE SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(5, 'mysql'); +RELEASE SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(6, 'mysql'); +COMMIT; +INSERT INTO articles(id, title) VALUES(7, 'mysql'); +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); +id title +1 mysql +2 mysql +3 mysql +4 mysql +5 mysql +6 mysql +7 mysql +TRUNCATE TABLE articles; +INSERT INTO articles(id, title) VALUES(1, 'mysql'); +BEGIN; +INSERT INTO articles(id, title) VALUES(2, 'mysql'); +SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(3, 'mysql'); +ROLLBACK TO SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(4, 'mysql'); +SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(5, 'mysql'); +RELEASE SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(6, 'mysql'); +COMMIT; +INSERT INTO articles(id, title) VALUES(7, 'mysql'); +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); +id title +1 mysql +2 mysql +4 mysql +5 mysql +6 mysql +7 mysql +TRUNCATE TABLE articles; +INSERT INTO articles(id, title) VALUES(1, 'mysql'); +BEGIN; +INSERT INTO articles(id, title) VALUES(2, 'mysql'); +SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(3, 'mysql'); +RELEASE SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(4, 'mysql'); +SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(5, 'mysql'); +ROLLBACK TO SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(6, 'mysql'); +COMMIT; +INSERT INTO articles(id, title) VALUES(7, 'mysql'); +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); +id title +1 mysql +2 mysql +3 mysql +4 mysql +6 mysql +7 mysql +TRUNCATE TABLE articles; +INSERT INTO articles(id, title) VALUES(1, 'mysql'); +BEGIN; +INSERT INTO articles(id, title) VALUES(2, 'mysql'); +SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(3, 'mysql'); +SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(4, 'mysql'); +RELEASE SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(5, 'mysql'); +ROLLBACK TO SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(6, 'mysql'); +COMMIT; +INSERT INTO articles(id, title) VALUES(7, 'mysql'); +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); +id title +1 mysql +2 mysql +6 mysql +7 mysql +TRUNCATE TABLE articles; +INSERT INTO articles(id, title) VALUES(1, 'mysql'); +BEGIN; +INSERT INTO articles(id, title) VALUES(2, 'mysql'); +SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(3, 'mysql'); +SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(4, 'mysql'); +ROLLBACK TO SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(5, 'mysql'); +RELEASE SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(6, 'mysql'); +COMMIT; +INSERT INTO articles(id, title) VALUES(7, 'mysql'); +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); +id title +1 mysql +2 mysql +3 mysql +5 mysql +6 mysql +7 mysql +TRUNCATE TABLE articles; +INSERT INTO articles(id, title) VALUES(1, 'mysql'); +BEGIN; +INSERT INTO articles(id, title) VALUES(2, 'mysql'); +ROLLBACK; +INSERT INTO articles(id, title) VALUES(3, 'mysql'); +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); +id title +1 mysql +3 mysql +TRUNCATE TABLE articles; +INSERT INTO articles(id, title) VALUES(1, 'mysql'); +BEGIN; +INSERT INTO articles(id, title) VALUES(2, 'mysql'); +SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(3, 'mysql'); +ROLLBACK; +INSERT INTO articles(id, title) VALUES(4, 'mysql'); +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); +id title +1 mysql +4 mysql +TRUNCATE TABLE articles; +INSERT INTO articles(id, title) VALUES(1, 'mysql'); +BEGIN; +INSERT INTO articles(id, title) VALUES(2, 'mysql'); +SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(3, 'mysql'); +RELEASE SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(4, 'mysql'); +ROLLBACK; +INSERT INTO articles(id, title) VALUES(5, 'mysql'); +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); +id title +1 mysql +5 mysql +TRUNCATE TABLE articles; +INSERT INTO articles(id, title) VALUES(1, 'mysql'); +BEGIN; +INSERT INTO articles(id, title) VALUES(2, 'mysql'); +SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(3, 'mysql'); +ROLLBACK TO SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(4, 'mysql'); +ROLLBACK; +INSERT INTO articles(id, title) VALUES(5, 'mysql'); +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); +id title +1 mysql +5 mysql +TRUNCATE TABLE articles; +INSERT INTO articles(id, title) VALUES(1, 'mysql'); +BEGIN; +INSERT INTO articles(id, title) VALUES(2, 'mysql'); +SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(3, 'mysql'); +SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(4, 'mysql'); +ROLLBACK TO SAVEPOINT sp2; +INSERT INTO articles(id, title) VALUES(5, 'mysql'); +RELEASE SAVEPOINT sp1; +INSERT INTO articles(id, title) VALUES(6, 'mysql'); +ROLLBACK; +INSERT INTO articles(id, title) VALUES(7, 'mysql'); +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); +id title +1 mysql +7 mysql +DROP TABLE articles; diff --git a/mysql-test/suite/innodb_fts/r/subexpr.result b/mysql-test/suite/innodb_fts/r/subexpr.result new file mode 100644 index 00000000000..cf476abb893 --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/subexpr.result @@ -0,0 +1,105 @@ +# +# Bug #20028323 INNODB FULLTEXT BOOLEAN SEARCH INCORRECTLY HANDLES +# PARENTHESES +# +CREATE TABLE t1 ( +f1 INT NOT NULL AUTO_INCREMENT, +f2 TEXT NOT NULL, +PRIMARY KEY (f1), +FULLTEXT (f2) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +INSERT INTO t1 (f2) VALUES +('Pumpkin soup with cheese bread'), +('Yellow chicken curry'), +('Fresh green vegetables with garlic'); +SELECT * FROM t1 WHERE MATCH(f2) AGAINST('+pumpkin' IN BOOLEAN MODE); +f1 f2 +1 Pumpkin soup with cheese bread +SELECT * FROM t1 WHERE MATCH(f2) AGAINST('+cheese' IN BOOLEAN MODE); +f1 f2 +1 Pumpkin soup with cheese bread +SELECT * FROM t1 WHERE MATCH(f2) AGAINST('+(pumpkin cheese)' IN BOOLEAN MODE); +f1 f2 +1 Pumpkin soup with cheese bread +SELECT * FROM t1 WHERE MATCH(f2) +AGAINST('+pumpkin +(souffle)' IN BOOLEAN MODE); +f1 f2 +SELECT * FROM t1 WHERE MATCH(f2) +AGAINST('+pumpkin +(souffle tart)' IN BOOLEAN MODE); +f1 f2 +SELECT * FROM t1 WHERE MATCH(f2) +AGAINST('+pumpkin +(>souffle souffle = 1 +#AND t1.id <=3 ; + +# proximity search +# insert for proximity search +INSERT INTO t1 (a,b) VALUES ('test query expansion','for database ...'); +# Insert into table with similar word of different distances +INSERT INTO t1 (a,b) VALUES + ('test proximity search, test, proximity and phrase', + 'search, with proximity innodb'); + +INSERT INTO t1 (a,b) VALUES + ('test proximity fts search, test, proximity and phrase', + 'search, with proximity innodb'); + +INSERT INTO t1 (a,b) VALUES + ('test more proximity fts search, test, more proximity and phrase', + 'search, with proximity innodb'); + + +SELECT id FROM t1 WHERE t1.id = (SELECT MAX(t2.id) FROM t1 AS t2 WHERE +MATCH(t2.a,t2.b) AGAINST ('"proximity search"@2' IN BOOLEAN MODE)); +SELECT id FROM t1 WHERE t1.id > (SELECT MIN(t2.id) FROM t1 AS t2 WHERE +MATCH(t2.a,t2.b) AGAINST ('"proximity search"@2' IN BOOLEAN MODE)); + +SELECT id FROM t1 WHERE t1.id IN (SELECT t2.id FROM t1 AS t2 WHERE +MATCH (t2.a,t2.b) AGAINST ('"proximity search"@2' IN BOOLEAN MODE)); + +SELECT id FROM t1 WHERE EXISTS (SELECT id FROM t1 AS t2 WHERE +MATCH t2.a,t2.b AGAINST ('"proximity search"@2' IN BOOLEAN MODE) +AND t2.id=t1.id); + +SELECT id FROM t1 WHERE EXISTS (SELECT id FROM t1 AS t2 WHERE +MATCH t2.a,t2.b AGAINST ('"more test proximity"@3' IN BOOLEAN MODE) +AND t2.id=t1.id); + +SELECT id FROM t1 WHERE EXISTS (SELECT id FROM t1 AS t2 WHERE +MATCH t2.a,t2.b AGAINST ('"more test proximity"@2' IN BOOLEAN MODE) +AND t2.id=t1.id); + + +#------------------------------------------------------------------------------ +# create table AS SELECT from fts indexed table +#------------------------------------------------------------------------------ +CREATE TABLE t2 ENGINE = InnoDB AS SELECT id FROM t1 WHERE +MATCH a,b AGAINST ('support') ; +SHOW CREATE TABLE t2; +SELECT id FROM t2; +DROP TABLE t2; + +CREATE TABLE t2 ENGINE = InnoDB AS SELECT id FROM t1 WHERE +MATCH a,b AGAINST("+support +collections" IN BOOLEAN MODE); +SHOW CREATE TABLE t2; +SELECT id FROM t2; +DROP TABLE t2; + +CREATE TABLE t2 ENGINE = InnoDB AS SELECT id FROM t1 WHERE +MATCH a,b AGAINST ('"proximity search"@10' IN BOOLEAN MODE); +SHOW CREATE TABLE t2; +SELECT id FROM t2; +DROP TABLE t2; + +DROP TABLE t1; + + +#------------------------------------------------------------------------------ +# Verift FTS with NULL records +#------------------------------------------------------------------------------ +# Create FTS table +EVAL CREATE TABLE t1 ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + a VARCHAR(200), + b TEXT + ) ENGINE = InnoDB; + +# Create the FTS index again +CREATE FULLTEXT INDEX idx on t1 (a,b); + + +# Insert rows +INSERT INTO t1 (a,b) VALUES +('MySQL from Tutorial','DBMS stands for DataBase ...'); + +let $counter = 50; +--disable_query_log +WHILE ($counter > 0) { + INSERT INTO t1 (a,b) VALUES (NULL,NULL); + dec $counter; +} +--enable_query_log +INSERT INTO t1 (a,b) VALUES +('when To Use MySQL Well','After that you went through a ...'); + +let $counter = 50; +--disable_query_log +WHILE ($counter > 0) { + INSERT INTO t1 (a,b) VALUES (NULL,NULL); + dec $counter; +} +--enable_query_log +INSERT INTO t1 (a,b) VALUES +('where will Optimizing MySQL','what In this tutorial we will show ...'); + +INSERT INTO t1 (a,b) VALUES +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), +('MySQL vs. YourSQL','In the following database comparison ...'), +('MySQL Security','When configured properly, MySQL null...'); + +SELECT COUNT(*) FROM t1; +SELECT COUNT(*) FROM t1 WHERE a IS NULL; +SELECT COUNT(*) FROM t1 WHERE b IS NOT NULL; + +SELECT id FROM t1 + WHERE MATCH (a,b) + AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); + +SELECT id FROM t1 + WHERE MATCH (a,b) + AGAINST (NULL IN NATURAL LANGUAGE MODE); +SELECT id FROM t1 + WHERE MATCH (a,b) + AGAINST (NULL WITH QUERY EXPANSION); +SELECT id FROM t1 + WHERE MATCH (a,b) + AGAINST ('null' IN NATURAL LANGUAGE MODE); +# Boolean search +# Select rows contain "MySQL" but not "YourSQL" +SELECT id FROM t1 WHERE MATCH (a,b) +AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE); +SELECT id FROM t1 WHERE MATCH (a,b) +AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE) AND (a IS NOT NULL OR b IS NOT NULL); +SELECT id FROM t1 WHERE MATCH (a,b) +AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE) AND (a IS NULL AND b IS NOT NULL); + +# Select rows contain at least one of the two words +SELECT id FROM t1 WHERE MATCH (a,b) +AGAINST ('DBMS Security' IN BOOLEAN MODE); + +# Test query expansion +SELECT COUNT(*) FROM t1 +WHERE MATCH (a,b) +AGAINST ('database' WITH QUERY EXPANSION); + +# proximity +SELECT id FROM t1 +WHERE MATCH (a,b) +AGAINST ('"following database"@10' IN BOOLEAN MODE); + + +DROP TABLE t1; + + + +#------------------------------------------------------------------------------ +# More FTS test from peter's testing +#------------------------------------------------------------------------------ +--disable_warnings +drop table if exists t50; +--enable_warnings + +set names utf8; + + +--echo "----------Test1---------" +# Create FTS table +create table t50 (s1 varchar(60) character set utf8 collate utf8_bin) engine = innodb; +create fulltext index i on t50 (s1); +# INNODB_FTS: Assert - fixed +# Assert : InnoDB: Failing assertion: rbt_validate(result_doc->tokens) +insert into t50 values ('ABCDE'),('FGHIJ'),('KLMNO'),('VÐƷWİ'); +# it was giving empty result set instead of one record +select * from t50 where match(s1) against ('VÐƷWİ'); +drop table t50; + + +--echo "----------Test2---------" +create table t50 (s1 int unsigned primary key auto_increment, s2 +varchar(60) character set utf8) engine = innodb; +create fulltext index i on t50 (s2); +insert into t50 (s2) values ('FGHIJ'),('KLMNO'),('VÐƷWİ'),('ABCDE'); +# INNODB_FTS: RESULT DIFF +# Order by does not sort result. +# Optimizer's Evgeny is investigate a similar issue. InnoDB FTS is used only +# for FT search, and should not be used as regular index for such order by query. +# Correct the result file when fixed. +select * from t50 order by s2; +drop table t50; + + +--echo "----------Test3---------" +create table t50 (id int unsigned primary key auto_increment, s2 +varchar(60) character set utf8) engine = innodb; +create fulltext index i on t50 (s2); +insert into t50 (s2) values ('FGHIJ'),('KLMNO'),('VÐƷWİ'),('ABCDE'); +set @@autocommit=0; +update t50 set s2 = lower(s2); +update t50 set s2 = upper(s2); +commit; +select * from t50 where match(s2) against ('VÐƷWİ FGHIJ KLMNO ABCDE' in boolean mode); +select * from t50; +drop table t50; +set @@autocommit=1; + +--echo "----------Test4---------" +create table t50 (id int unsigned primary key auto_increment, s2 +varchar(60) character set utf8) engine = innodb; +create fulltext index i on t50 (s2); +insert into t50 (s2) values ('FGHIJ'),('KLMNO'),('VÐƷWİ'),('ABCD*'); +select * from t50 where match(s2) against ('abcd*' in natural language +mode); +# INNODB_FTS: RESULT DIFF(Expected). InnoDB do not index "*", so +# word "ABCD" indexed, instead of "ABCD*" +select * from t50 where match(s2) against ('abcd*' in boolean mode); +drop table t50; + + +--echo "----------Test5---------" +create table t50 (s1 int, s2 varchar(200), fulltext key(s2)) engine = innodb; +set @@autocommit=0; +insert into t50 values (1,'Sunshine'),(2,'Lollipops'); +select * from t50 where match(s2) against('Rainbows'); +rollback; +select * from t50; +drop table t50; +set @@autocommit=1; + +--echo "----------Test6---------" +CREATE TABLE t1 ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + a VARCHAR(200), + b TEXT + ) ENGINE = InnoDB; + +# Insert rows +INSERT INTO t1 (a,b) VALUES + ('aab` MySQL Tutorial','DBMS stands for DataBase ...') , + ('aas How To Use MySQL Well','After you went through a ...'), + ('aac Optimizing MySQL','In this tutorial we will show ...'); +# Insert rows +INSERT INTO t1 (a,b) VALUES + ('aac 1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), + ('aab MySQL vs. YourSQL','In the following database comparison ...'), + ('aaa MySQL Security','When configured properly, MySQL ...'); +# Create the FTS index Using Alter Table +ALTER TABLE t1 ADD FULLTEXT INDEX idx (a,b); + +-- disable_query_log +-- disable_result_log +ANALYZE TABLE t1; +-- enable_result_log +-- enable_query_log + +SELECT * FROM t1 ORDER BY MATCH(a,b) AGAINST ('aac') DESC; +SELECT * FROM t1 ORDER BY MATCH(a,b) AGAINST ('aab') DESC; + +--echo "----------Test7---------" +select * from t1 where match(a,b) against ('aaa') +union select * from t1 where match(a,b) against ('aab') +union select * from t1 where match(a,b) against ('aac'); + +select * from t1 where match(a,b) against ('aaa') + or match(a,b) against ('aab') + or match(a,b) against ('aac'); + +DROP TABLE t1; + +--echo "----------Test8---------" +# Create FTS table +CREATE TABLE t1 ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + a VARCHAR(200), + b TEXT + ) ENGINE = InnoDB; + +# Insert rows +INSERT INTO t1 (a,b) VALUES + ('MySQL Tutorial','DBMS stands for DataBase ... abcd') , + ('How To Use MySQL Well','After you went through a q ...abdd'), + ('Optimizing MySQL','In this tutorial we will show ...abed'); + +# Create the FTS index Using Alter Table +ALTER TABLE t1 ADD FULLTEXT INDEX idx (a,b); +EVAL SHOW CREATE TABLE t1; + +# Insert rows +INSERT INTO t1 (a,b) VALUES + ('1001 MySQL Tricks','1. Never run mysqld as root. 2. q ...'), + ('MySQL vs. YourSQL use','In the following database comparison ...'), + ('MySQL Security','When run configured properly, MySQL ...'); + +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ('run'); +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ('use'); +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ('went'); +# rows should be matched as 'q' is single char its not indexed +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ('run') AND NOT MATCH(a,b) AGAINST ('q'); +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ('use') AND NOT MATCH(a,b) AGAINST ('q'); +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ('went') AND NOT MATCH(a,b) AGAINST ('q'); + +--echo "----------Test9---------" +CREATE TABLE t2 AS SELECT * FROM t1; +ALTER TABLE t2 ENGINE=MYISAM; +CREATE FULLTEXT INDEX i ON t2 (a,b); +SET @x = (SELECT COUNT(*) FROM t1 WHERE MATCH(a,b) AGAINST ('run')); +SET @x = @x + (SELECT COUNT(*) FROM t1 WHERE MATCH(a,b) AGAINST ('use')); +SET @x = @x + (SELECT COUNT(*) FROM t1 WHERE MATCH(a,b) AGAINST ('went')); +SET @x = @x + (SELECT COUNT(*) FROM t1 WHERE MATCH(a,b) AGAINST ('run')); +SET @x2 = (SELECT COUNT(*) FROM t2 WHERE MATCH(a,b) AGAINST ('run')); +SET @x2 = @x2 + (SELECT COUNT(*) FROM t2 WHERE MATCH(a,b) AGAINST ('use')); +SET @x2 = @x2 + (SELECT COUNT(*) FROM t2 WHERE MATCH(a,b) AGAINST ('went')); +SET @x2 = @x2 + (SELECT COUNT(*) FROM t2 WHERE MATCH(a,b) AGAINST ('run')); +# Innodb returns value for x which is correct +SELECT @x, @x2; + + +DROP TABLE t2; + +--echo "----------Test10---------" +CREATE TABLE t2 AS SELECT * FROM t1; +ALTER TABLE t2 ENGINE=MYISAM; +CREATE FULLTEXT INDEX i ON t2 (a,b); +SELECT COUNT(*) FROM t2 WHERE MATCH(a,b) AGAINST ('abc*' IN BOOLEAN MODE); +SELECT COUNT(*) FROM t1 WHERE MATCH(a,b) AGAINST ('abc*' IN BOOLEAN MODE); + +DROP TABLE t2; + + +--echo "----------Test11---------" +CREATE TABLE t2 AS SELECT * FROM t1; +ALTER TABLE t2 ENGINE = MYISAM; +CREATE FULLTEXT INDEX i ON t2 (a,b); +ALTER TABLE t2 ENGINE=InnoDB; +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ('run'); +SELECT COUNT(*) FROM t2 WHERE MATCH(a,b) AGAINST ('abc*' IN BOOLEAN MODE); +DROP TABLE t2,t1; + + +--echo "----------Test13---------" +set names utf8; + +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200) CHARACTER SET UTF8 COLLATE UTF8_SPANISH_CI) ENGINE = InnoDB; +CREATE FULLTEXT INDEX i ON t1 (s2); +INSERT INTO t1 VALUES (1,'aaCen'),(2,'aaCha'),(3,'aaCio'),(4,'aaçen'),(5,'aaçha'),(6,'aaçio'); +SELECT * FROM t1 WHERE MATCH(s2) AGAINST ('aach*' IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH(s2) AGAINST ('aaC*' IN BOOLEAN MODE); +DROP TABLE t1; + +--echo "----------Test14---------" +CREATE TABLE t1(s1 INT , s2 VARCHAR(100) CHARACTER SET sjis) ENGINE = InnoDB; +CREATE FULLTEXT INDEX i ON t1 (s2); +INSERT INTO t1 VALUES (1,'ペペペ'),(2,'テテテ'),(3,'ルルル'),(4,'グググ'); +# Innodb Asset : file ha_innodb.cc line 4557 +#SELECT * FROM t1 WHERE MATCH(s2) AGAINST ('テテ*' IN BOOLEAN MODE); +DROP TABLE t1; + + +--echo "----------Test15---------" +CREATE TABLE t1 (s1 VARCHAR (60) CHARACTER SET UTF8 COLLATE UTF8_UNICODE_520_CI) ENGINE = MyISAM; +CREATE FULLTEXT INDEX i ON t1 (s1); +INSERT INTO t1 VALUES +('a'),('b'),('c'),('d'),('ŁŁŁŁ'),('LLLL'),(NULL),('ŁŁŁŁ ŁŁŁŁ'),('LLLLLLLL'); +SELECT * FROM t1 WHERE MATCH(s1) AGAINST ('LLLL' COLLATE UTF8_UNICODE_520_CI); +DROP TABLE if EXISTS t2; +CREATE TABLE t2 (s1 VARCHAR(60) CHARACTER SET UTF8 COLLATE UTF8_POLISH_CI) ENGINE = InnoDB; +CREATE FULLTEXT INDEX i ON t2 ( s1); +INSERT INTO t2 VALUES +('a'),('b'),('c'),('d'),('ŁŁŁŁ'),('LLLL'),(NULL),('ŁŁŁŁ ŁŁŁŁ'),('LLLLLLLL'); +SELECT * FROM t2 WHERE MATCH(s1) AGAINST ('LLLL' COLLATE UTF8_UNICODE_520_CI); +--disable_warnings +DROP TABLE t1,t2; +--enable_warnings + +--echo "----------Test16---------" +CREATE TABLE t1 (s1 INT, s2 VARCHAR(50) CHARACTER SET UTF8) ENGINE = InnoDB; +CREATE FULLTEXT INDEX i ON t1(s2); +INSERT INTO t1 VALUES (2, 'ğė Daśi p '); +SELECT * FROM t1 WHERE MATCH(s2) AGAINST ('+p +"ğė Daśi*"' IN BOOLEAN MODE); +DROP TABLE t1; + + +--echo "----------Test19---------" +#19 Failure with Boolean quoted search +CREATE TABLE t1 ( id INT , char_column VARCHAR(60) CHARACTER SET UTF8) ENGINE = InnoDB; +INSERT INTO t1 VALUES (1,'İóëɠ'); +CREATE FULLTEXT INDEX i ON t1 (char_column); +SELECT * FROM t1 WHERE MATCH(char_column) AGAINST ('"İóëɠ"' IN BOOLEAN MODE); +DROP TABLE t1; + +--echo "----------Test20---------" +#20 Crash with utf32 and boolean mode. +CREATE TABLE t1 ( id INT , char_column VARCHAR(60) CHARACTER SET UTF32, char_column2 VARCHAR(60) character set utf8) ENGINE = InnoDB; +INSERT INTO t1 (char_column) VALUES ('abcde'),('fghij'),('klmno'),('qrstu'); +UPDATE t1 SET char_column2 = char_column; +CREATE FULLTEXT INDEX i ON t1 (char_column2); +--error ER_FT_MATCHING_KEY_NOT_FOUND +SELECT * FROM t1 WHERE MATCH(char_column) AGAINST ('abc*' IN BOOLEAN MODE); +DROP TABLE t1; + +--echo "----------Test22---------" +# case 22 +CREATE TABLE t1 ( id INT , char_column VARCHAR(60) CHARACTER SET UTF8) ENGINE = InnoDB; +INSERT INTO t1 VALUES (1,'aaa'),(2,'bbb'),(3,'ccc'); +CREATE FULLTEXT INDEX i ON t1 (char_column); +HANDLER t1 OPEN; +--error ER_KEY_DOESNT_SUPPORT +HANDLER t1 READ i = ('aaa'); +DROP TABLE t1; +#23. Duplicate key error when there are no unique indexes (procedure test) +#24 Failure after cascading update - already have tests + +--echo "----------Test25---------" +#25 Failure with Croatian boolean truncated search. +CREATE TABLE t1 ( id INT , char_column VARCHAR(60) CHARACTER SET UTF8 COLLATE UTF8_CROATIAN_CI) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,'LJin'),(2,'ljin'),(3,'lmin'),(4,'LJLJLJLJLJ'); +CREATE FULLTEXT INDEX i ON t1 (char_column); +#inndob:error incorrect result correct it after fix +SELECT count(*) FROM t1 WHERE MATCH (char_column) AGAINST ('lj*' IN BOOLEAN MODE); +DROP TABLE t1; + +#26. Index error when run procedure call from multiple clients + +--echo "----------Test27---------" +#27 Crash after server restart +CREATE TABLE t1 (id INT,char_column VARCHAR(60)) ENGINE=InnoDB; +SET @@autocommit=0; +CREATE FULLTEXT INDEX i ON t1 (char_column); +INSERT INTO t1 values (1,'aaa'); +echo "restart server..." +# Restart the server +--source include/restart_mysqld.inc +DELETE FROM t1 WHERE MATCH(char_column) AGAINST ('bbb'); +SET @@autocommit=1; +DROP TABLE t1; + +--echo "----------Test28---------" +drop table if exists `fts_test`; +create table `fts_test`(`a` text,fulltext key(`a`))engine=innodb; +set session autocommit=0; +insert into `fts_test` values (''); +savepoint `b`; +savepoint `b`; +set session autocommit=1; +DROP TABLE fts_test; + +# Continue test savepoint related operations. With a commit after +# multiple rollback to savepoints +--echo "----------Test29---------" +CREATE TABLE articles ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + body TEXT, + FULLTEXT (title,body) + ) ENGINE=InnoDB; + +INSERT INTO articles (title,body) VALUES + ('MySQL Tutorial','DBMS stands for DataBase ...'); + + +start transaction; + +INSERT INTO articles (title,body) VALUES +('How To Use MySQL Well','After you went through a ...'); + +savepoint `a1`; + +INSERT INTO articles (title,body) VALUES +('Optimizing MySQL','In this tutorial we will show ...'); + +savepoint `a2`; + +INSERT INTO articles (title,body) VALUES +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'); + +savepoint `a3`; + +INSERT INTO articles (title,body) VALUES +('MySQL vs. YourSQL','In the following database comparison ...'); + +savepoint `a4`; + +# FTS do not parse those uncommitted rows, only one row should show up +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('Database' IN NATURAL LANGUAGE MODE); + +rollback to savepoint a3; + +# The last inserted row should not be there +select title, body from articles; + +INSERT INTO articles (title,body) VALUES +('MySQL Security','When configured properly, MySQL ...'); + +savepoint `a5`; + +select title, body from articles; + +rollback to savepoint a2; + +select title, body from articles; + +commit; + +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('Database' IN NATURAL LANGUAGE MODE); + +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); + +DROP TABLE articles; + +# Continue test savepoint related operations. With a rollback after +# multiple rollback to savepoints +--echo "----------Test30---------" +CREATE TABLE articles ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + body TEXT, + FULLTEXT (title,body) + ) ENGINE=InnoDB; + +INSERT INTO articles (title,body) VALUES + ('MySQL Tutorial','DBMS stands for DataBase ...'); + +start transaction; + +INSERT INTO articles (title,body) VALUES +('How To Use MySQL Well','After you went through a ...'); + +savepoint `a1`; + +INSERT INTO articles (title,body) VALUES +('Optimizing MySQL','In this tutorial we will show ...'); + +savepoint `a2`; + +INSERT INTO articles (title,body) VALUES +('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'); + +savepoint `a3`; + +INSERT INTO articles (title,body) VALUES +('MySQL vs. YourSQL','In the following database comparison ...'); + +savepoint `a4`; + +# FTS do not parse those uncommitted rows, only one row should show up +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('Database' IN NATURAL LANGUAGE MODE); + +rollback to savepoint a3; + +# The last inserted row should not be there +select title, body from articles; + +INSERT INTO articles (title,body) VALUES +('MySQL Security','When configured properly, MySQL ...'); + +savepoint `a5`; + +select title, body from articles; + +rollback to savepoint a2; + +select title, body from articles; + +rollback; + +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('Database' IN NATURAL LANGUAGE MODE); + +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); + +DROP TABLE articles; + +# Test for Bug #13907075 - DIFFERENT RESULTS FOR DIFFERENT TERM ORDER +# WITH INNODB BOOLEAN FULLTEXT SEARCH. The FTS_IGNORE ("-") operation +# is orderless +# Create FTS table +CREATE TABLE articles ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + body TEXT, + FULLTEXT (title,body) + ) ENGINE=InnoDB; + +# Insert six rows +INSERT INTO articles (title,body) VALUES + ('MySQL Tutorial','DBMS stands for DataBase ...') , + ('How To Use MySQL Well','After you went through a ...'), + ('Optimizing MySQL','In this tutorial we will show ...'), + ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), + ('MySQL vs. YourSQL','In the following database comparison ...'), + ('MySQL Security','When configured properly, MySQL ...'); + +-- disable_result_log +ANALYZE TABLE articles; +-- enable_result_log + +SELECT *, MATCH(title, body) AGAINST ('-database +MySQL' IN BOOLEAN MODE) AS score from articles; + +SELECT *, MATCH(title, body) AGAINST ('+MySQL -database' IN BOOLEAN MODE) AS score FROM articles; + +# With subquery +SELECT * FROM articles where MATCH(title, body) AGAINST ('MySQL - (database - tutorial)' IN BOOLEAN MODE); + +SELECT * FROM articles where MATCH(title, body) AGAINST ('MySQL - (- tutorial database)' IN BOOLEAN MODE); + +# More complex query +SELECT * FROM articles where MATCH(title, body) AGAINST ('MySQL - (- tutorial database) -Tricks' IN BOOLEAN MODE); + +SELECT * FROM articles where MATCH(title, body) AGAINST ('-Tricks MySQL - (- tutorial database)' IN BOOLEAN MODE); + +DROP TABLE articles; + +# Test for Bug 13940669 - 64901: INNODB: ASSERTION FAILURE IN +# THREAD 34387022112 IN FILE REM0CMP.CC LINE 5 + +drop table if exists t1; + +create table t1 (FTS_DOC_ID bigint unsigned auto_increment not null primary key, +title varchar(200),body text,fulltext(title,body)) engine=innodb; + +insert into t1 set body='test'; + +select * from t1 where match(title,body) against('%test'); + +select * from t1 where match(title,body) against('%'); + +select * from t1 where match(title,body) against('%%%%'); + +drop table t1; + +# Test for Bug 13881758 - 64745: CREATE FULLTEXT INDEX CAUSES CRASH +# Create a database with empty space in its name +CREATE DATABASE `benu database`; + +USE `benu database`; + +# Create FTS table +CREATE TABLE t1 ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + a VARCHAR(200), + b TEXT + ) ENGINE = InnoDB; + +# Insert rows +INSERT INTO t1 (a,b) VALUES + ('MySQL Tutorial','DBMS stands for DataBase ...') , + ('How To Use MySQL Well','After you went through a ...'), + ('Optimizing MySQL','In this tutorial we will show ...'); + +# Create the FTS index Using Alter Table +ALTER TABLE t1 ADD FULLTEXT INDEX idx (a,b); +EVAL SHOW CREATE TABLE t1; + +# Insert rows +INSERT INTO t1 (a,b) VALUES + ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), + ('MySQL vs. YourSQL','In the following database comparison ...'), + ('MySQL Security','When configured properly, MySQL ...'); + +# Select word "tutorial" in the table +SELECT id FROM t1 WHERE MATCH (a,b) + AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); + +# boolean mode +select id from t1 where MATCH(a,b) AGAINST("+support +collections" IN BOOLEAN MODE); +select id from t1 where MATCH(a,b) AGAINST("+search" IN BOOLEAN MODE); +select id from t1 where MATCH(a,b) AGAINST("+search +(support vector)" IN BOOLEAN MODE); +select id from t1 where MATCH(a,b) AGAINST("+search -(support vector)" IN BOOLEAN MODE); +select id, MATCH(a,b) AGAINST("support collections" IN BOOLEAN MODE) as x from t1; +select id, MATCH(a,b) AGAINST("collections support" IN BOOLEAN MODE) as x from t1; +select id from t1 where MATCH a,b AGAINST ("+call* +coll*" IN BOOLEAN MODE); +select id from t1 where MATCH a,b AGAINST ('"support now"' IN BOOLEAN MODE); +select id from t1 where MATCH a,b AGAINST ('"Now sUPPort"' IN BOOLEAN MODE); + +DROP DATABASE `benu database`; + +USE test; + +# Test for Bug #14101706 - CRASH WITH DDL IN ROW_MERGE_BUILD_INDEXES +# WHEN FULLTEXT INDEXES EXIST + +CREATE TABLE `t21` (`a` text, `b` int not null, +fulltext key (`a`), fulltext key (`a`) +) ENGINE=INNODB DEFAULT CHARSET=LATIN1; + +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +ALTER TABLE `t21` ADD UNIQUE INDEX (`b`), ALGORITHM=INPLACE; +ALTER TABLE `t21` ADD UNIQUE INDEX (`b`); + +DROP TABLE t21; + +CREATE TABLE `t21` (`a` text, `b` int not null, +fulltext key (`a`)) ENGINE=INNODB DEFAULT CHARSET=LATIN1; + +ALTER TABLE `t21` ADD UNIQUE INDEX (`b`); + +DROP TABLE t21; + +# Test primary index rebuild +CREATE TABLE t1 ( + id INT NOT NULL, + a VARCHAR(200), + b TEXT + ) ENGINE = InnoDB; + +# Insert rows +INSERT INTO t1 VALUES + (1, 'MySQL Tutorial','DBMS stands for DataBase ...') , + (2, 'How To Use MySQL Well','After you went through a ...'), + (3, 'Optimizing MySQL','In this tutorial we will show ...'); + +ALTER TABLE t1 ADD FULLTEXT INDEX idx (a,b); + +ALTER TABLE t1 ADD UNIQUE INDEX (`id`); + +# Select word "tutorial" in the table +SELECT id FROM t1 WHERE MATCH (a,b) + AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); + +# boolean mode +select id from t1 where MATCH(a,b) AGAINST("+support +collections" IN BOOLEAN MODE); +select id from t1 where MATCH(a,b) AGAINST("+search" IN BOOLEAN MODE); +select id from t1 where MATCH(a,b) AGAINST("+search +(support vector)" IN BOOLEAN MODE); +select id from t1 where MATCH(a,b) AGAINST("+search -(support vector)" IN BOOLEAN MODE); +select id, MATCH(a,b) AGAINST("support collections" IN BOOLEAN MODE) as x from t1; + +DROP TABLE t1; + +# Test create the FTS and primary index in the same clause +CREATE TABLE t1 ( + id INT NOT NULL, + a VARCHAR(200), + b TEXT + ) ENGINE = InnoDB; + +# Insert rows +INSERT INTO t1 VALUES + (1, 'MySQL Tutorial','DBMS stands for DataBase ...') , + (2, 'How To Use MySQL Well','After you went through a ...'), + (3, 'Optimizing MySQL','In this tutorial we will show ...'); + +ALTER TABLE t1 ADD UNIQUE INDEX (`id`), ADD FULLTEXT INDEX idx (a,b); + +# Select word "tutorial" in the table +SELECT id FROM t1 WHERE MATCH (a,b) + AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); + +# boolean mode +select id from t1 where MATCH(a,b) AGAINST("+support +collections" IN BOOLEAN MODE); +select id from t1 where MATCH(a,b) AGAINST("+search" IN BOOLEAN MODE); +select id from t1 where MATCH(a,b) AGAINST("+search +(support vector)" IN BOOLEAN MODE); +select id from t1 where MATCH(a,b) AGAINST("+search -(support vector)" IN BOOLEAN MODE); + +DROP TABLE t1; + +# Create FTS table with FTS_DOC_ID already existed +CREATE TABLE t1 ( + FTS_DOC_ID BIGINT UNSIGNED NOT NULL, + a VARCHAR(200), + b TEXT + ) ENGINE = InnoDB; + +# Insert rows +INSERT INTO t1 VALUES + (1, 'MySQL Tutorial','DBMS stands for DataBase ...') , + (2, 'How To Use MySQL Well','After you went through a ...'), + (3, 'Optimizing MySQL','In this tutorial we will show ...'); + +ALTER TABLE t1 ADD FULLTEXT INDEX idx (a,b); + +ALTER TABLE t1 ADD UNIQUE INDEX (`FTS_DOC_ID`); + +# Select word "tutorial" in the table +SELECT FTS_DOC_ID FROM t1 WHERE MATCH (a,b) + AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); + +# boolean mode +select FTS_DOC_ID from t1 where MATCH(a,b) AGAINST("+support +collections" IN BOOLEAN MODE); +select FTS_DOC_ID from t1 where MATCH(a,b) AGAINST("+search" IN BOOLEAN MODE); +select FTS_DOC_ID from t1 where MATCH(a,b) AGAINST("+search +(support vector)" IN BOOLEAN MODE); +select FTS_DOC_ID from t1 where MATCH(a,b) AGAINST("+search -(support vector)" IN BOOLEAN MODE); +select FTS_DOC_ID, MATCH(a,b) AGAINST("support collections" IN BOOLEAN MODE) as x from t1; + +DROP TABLE t1; + +# Create FTS table with FTS_DOC_ID and FTS_DOC_ID_INDEX +CREATE TABLE t1 ( + FTS_DOC_ID BIGINT UNSIGNED NOT NULL, + a VARCHAR(200), + b TEXT + ) ENGINE = InnoDB; + +# Insert rows +INSERT INTO t1 VALUES + (1, 'MySQL Tutorial','DBMS stands for DataBase ...') , + (2, 'How To Use MySQL Well','After you went through a ...'), + (3, 'Optimizing MySQL','In this tutorial we will show ...'); + +ALTER TABLE t1 ADD FULLTEXT INDEX idx (a,b), ADD UNIQUE INDEX FTS_DOC_ID_INDEX (FTS_DOC_ID); + +# Select word "tutorial" in the table +SELECT FTS_DOC_ID FROM t1 WHERE MATCH (a,b) + AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); + +# boolean mode +select FTS_DOC_ID from t1 where MATCH(a,b) AGAINST("+support +collections" IN BOOLEAN MODE); +select FTS_DOC_ID from t1 where MATCH(a,b) AGAINST("+search" IN BOOLEAN MODE); +select FTS_DOC_ID from t1 where MATCH(a,b) AGAINST("+search +(support vector)" IN BOOLEAN MODE); +select FTS_DOC_ID from t1 where MATCH(a,b) AGAINST("+search -(support vector)" IN BOOLEAN MODE); +select FTS_DOC_ID, MATCH(a,b) AGAINST("support collections" IN BOOLEAN MODE) as x from t1; + +DROP TABLE t1; + +# Test for bug #14079609 - FTS: CRASH IN FTS_TRX_TABLE_CMP WITH SAVEPOINTS, XA + +CREATE TABLE t2 (`b` char(2),fulltext(`b`)) ENGINE=INNODB +DEFAULT CHARSET=LATIN1; + +CREATE TABLE t3 LIKE t2; + +INSERT INTO `t2` VALUES(); + +COMMIT WORK AND CHAIN; + +INSERT INTO `t3` VALUES (); +UPDATE `t2` SET `b` = 'a'; + +SAVEPOINT BATCH1; + +DROP TABLE t2; +DROP TABLE t3; + +# Create FTS table +CREATE TABLE t1 ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + a VARCHAR(200), + b TEXT + ) ENGINE = InnoDB; + +# Insert rows +INSERT INTO t1 (a,b) VALUES + ('MySQL Tutorial','DBMS stands for DataBase ...') , + ('How To Use MySQL Well','After you went through a ...'), + ('Optimizing MySQL','In this tutorial we will show ...'); + +# Create the FTS index Using Alter Table +ALTER TABLE t1 ADD FULLTEXT INDEX idx (a,b); + +COMMIT WORK AND CHAIN; + +INSERT INTO t1 (a,b) VALUES + ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), + ('MySQL vs. YourSQL','In the following database comparison ...'), + ('MySQL Security','When configured properly, MySQL ...'); + +SAVEPOINT BATCH1; + +SELECT id FROM t1 WHERE MATCH (a,b) + AGAINST ('MySQL' IN NATURAL LANGUAGE MODE); + +INSERT INTO t1 (a,b) VALUES + ('1002 MySQL Tricks','1. Never run mysqld as root. 2. ...'), + ('MySQL vs. YourSQL','In the following database comparison ...'), + ('MySQL Security','When configured properly, MySQL ...'); + + +ROLLBACK TO SAVEPOINT BATCH1; + +COMMIT; + +SELECT id FROM t1 WHERE MATCH (a,b) + AGAINST ('MySQL' IN NATURAL LANGUAGE MODE); + +DROP TABLE t1; + +# Test for Bug 14588091 - FTS: BUFFER OVERFLOW IN FTS_AST_CREATE_NODE_TEXT +CREATE TABLE `t` (`a` char(20) character set utf8 default null, +fulltext key (`a`)) ENGINE=INNODB; +INSERT INTO `t` VALUES ('a'); +INSERT INTO `t` VALUES ('aaa'); + +# 0x22 is the '"', 0xdd is not encoded in utf8 +SELECT MATCH(`a`) AGAINST (0x22dd22) FROM `t`; +SELECT MATCH(`a`) AGAINST (0x2222) FROM `t`; +SELECT MATCH(`a`) AGAINST (0x22) FROM `t`; + +# this should show one match +SELECT MATCH(`a`) AGAINST (0x2261616122) FROM `t`; + +# again 0xdd should be ignored +SELECT MATCH(`a`) AGAINST (0x2261dd6122) FROM `t`; + +SELECT MATCH(`a`) AGAINST (0x2261dd612222226122) FROM `t`; + +DROP TABLE t; + +# InnoDB FTS does not support index scan from handler +CREATE TABLE t(a CHAR(1),FULLTEXT KEY(a)) ENGINE=INNODB; +HANDLER t OPEN; +HANDLER t READ a NEXT; +HANDLER t READ a PREV; +DROP TABLE t; + +CREATE TABLE `%`(a TEXT, FULLTEXT INDEX(a)) ENGINE=INNODB; +CREATE TABLE `A B`(a TEXT, FULLTEXT INDEX(a)) ENGINE=INNODB; +DROP TABLE `%`; +DROP TABLE `A B`; + +CREATE TABLE `t-26`(a VARCHAR(10),FULLTEXT KEY(a)) ENGINE=INNODB; +INSERT INTO `t-26` VALUES('117'); +DROP TABLE `t-26`; + +# Test on phrase search with stopwords contained in the search string +CREATE TABLE `t1` ( + `id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, + `content` TEXT NOT NULL, + PRIMARY KEY (`id`), + FULLTEXT INDEX `IDX_CONTEXT_FULLTEXT`(`content`) +) +ENGINE = InnoDB; + +insert into t1 (content) +values +('This is a story which has has a complicated phrase structure here in the +middle'), +('This is a story which doesn''t have that text'), +('This is a story that has complicated the phrase structure'); + +select * from t1 +where match(content) against('"complicated phrase structure"' in boolean +mode); + +# Test single phrase search with "+" symbol, one row should be returned +select * from t1 +where match(content) against('+"complicated phrase structure"' in boolean +mode); + +# Test phrase search with stopwords in between, one row should be returned +select * from t1 +where match(content) against('"complicated the phrase structure"' in boolean +mode); + +# Test phrase search with multiple "+" symbols +select * from t1 where match(content) against('+"this is a story which" +"complicated the phrase structure"' in boolean mode); + +# Test phrase search with leading word is a stopword, such stopword would be +# ignored +select * from t1 where match(content) against('"the complicated the phrase structure"' in boolean mode); + +# Test phrase search with non-matching stopword in between, no row should be +# returned +select * from t1 where match(content) against('"complicated a phrase structure"' in boolean mode); + +DROP TABLE t1; + +CREATE TABLE my (id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, +c VARCHAR(32), FULLTEXT(c)) ENGINE = INNODB; + +INSERT INTO my (c) VALUES ('green-iguana'); + +SELECT * FROM my WHERE MATCH(c) AGAINST ('green-iguana'); + +DROP TABLE my; + +CREATE TABLE ift ( + `a` int(11) NOT NULL, + `b` text, + PRIMARY KEY (`a`), + FULLTEXT KEY `b` (`b`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +INSERT INTO ift values (1, "skip"); +INSERT INTO ift values (2, "skip and networking"); +INSERT INTO ift values (3, "--skip-networking"); +INSERT INTO ift values (4, "-donot--skip-networking"); + +SELECT * FROM ift WHERE MATCH (b) AGAINST ('--skip-networking'); +SELECT * FROM ift WHERE MATCH (b) AGAINST ('skip-networking'); +SELECT * FROM ift WHERE MATCH (b) AGAINST ('----'); +SELECT * FROM ift WHERE MATCH (b) AGAINST ('-donot--skip-networking'); + +DROP TABLE ift; + +# Test special cases of wildword. +# Create FTS table +CREATE TABLE articles ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + body TEXT, + FULLTEXT (title,body) + ) ENGINE=InnoDB; + +# Insert six rows +INSERT INTO articles (title,body) VALUES + ('MySQL Tutorial','DBMS stands for DataBase ...') , + ('How To Use MySQL Well','After you went through a ...'), + ('Optimizing MySQL','In this tutorial we will show ...'), + ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), + ('MySQL vs. YourSQL','In the following database comparison ...'), + ('( that''s me )','When configured properly, MySQL ...'); + +SELECT * FROM articles WHERE MATCH (title,body) + AGAINST ('( yours''s* )' IN BOOLEAN MODE); + +SELECT * FROM articles WHERE MATCH (title,body) + AGAINST ('s*' IN BOOLEAN MODE); + +SELECT * FROM articles WHERE MATCH (title,body) + AGAINST ('stands\'] | * | show[@database' IN NATURAL LANGUAGE MODE); + +DROP TABLE articles; + +# Test for BUG#16429688 - FTS: SYNTAX ERROR, UNEXPECTED '*', EXPECTING $END +CREATE TABLE t1(a TEXT CHARACTER SET LATIN1, FULLTEXT INDEX(a)) ENGINE=INNODB; + +--error ER_PARSE_ERROR +SELECT * FROM t1 WHERE MATCH(a) AGAINST("*"); + +DROP TABLE t1; + +# Test for BUG#16516193 - LITERAL PHRASES CANNOT BE COMBINED WITH + OR - OPERATOR +# Create FTS table +CREATE TABLE t1 ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + a VARCHAR(200), + FULLTEXT (a) + ) ENGINE= InnoDB; + +# Insert rows +INSERT INTO t1 (a) VALUES + ('Do you know MySQL is a good database'), + ('How to build a good database'), + ('Do you know'), + ('Do you know MySQL'), + ('How to use MySQL'), + ('Do you feel good'), + ('MySQL is good'), + ('MySQL is good to know'), + ('What is database'); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+"know mysql"' IN BOOLEAN MODE); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+("know mysql")' IN BOOLEAN MODE); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('("know mysql" good)' IN BOOLEAN MODE); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+("know mysql" good)' IN BOOLEAN MODE); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('(good "know mysql")' IN BOOLEAN MODE); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+(good "know mysql")' IN BOOLEAN MODE); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+("know mysql" "good database")' IN BOOLEAN MODE); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+"know mysql" +"good database"' IN BOOLEAN MODE); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+"know database"@4' IN BOOLEAN MODE); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+"know database"@8' IN BOOLEAN MODE); + +# Drop table +DROP TABLE t1; + +# Test for BUG#16885178 - INNODB FULLTEXT PHRASE SEARCH VALGRIND ERROR +CREATE TABLE t1 ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + a VARCHAR(200), + FULLTEXT (a) + ) ENGINE= InnoDB; + +# Insert a special row +INSERT INTO t1 (a) VALUES + ('know mysql good database'); + +# This phrase search fails in valgrind test before the fix. +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('+"good database"' IN BOOLEAN MODE); + +DROP TABLE t1; + +# Test single term ranking +CREATE TABLE articles ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + body TEXT, + FULLTEXT (title,body) + ) ENGINE=InnoDB; + +# Repeatedly insert/delete records, the ranking should be the same for +# each of them +INSERT INTO articles (title,body) VALUES ('Test Article','blah blah +blah'),("Matt's Noise",'this is noisy'),('February Weather','It was terrible +this year.'),('Peter Pan','Tis a kids story.'),('Test1','nada'),('Database +database database','foo database database database'),('Database article +title','body with lots of words.'),('myfulltext database', 'my test fulltext +database'); + +SELECT id, title, body FROM articles ORDER BY MATCH (title,body) AGAINST ('database' IN BOOLEAN MODE) DESC; +DELETE from articles WHERE title like "myfulltext database"; + +INSERT INTO articles (title,body) VALUES ('myfulltext database', 'my test fulltext database'); + +SELECT id, title, body FROM articles ORDER BY MATCH (title,body) AGAINST ('database' IN BOOLEAN MODE) DESC; +DELETE from articles WHERE title like "myfulltext database"; + +INSERT INTO articles (title,body) VALUES ('myfulltext database', 'my test fulltext database'); + +SELECT id, title, body FROM articles ORDER BY MATCH (title,body) AGAINST ('database' IN BOOLEAN MODE) DESC; + +DROP TABLE articles; + +# Test for BUG 18277305 - FTS: FAILING ASSERTION: PTR[1] == '\"' +# IN FTS_AST_CREATE_NODE_TEXT +CREATE TABLE t1( + a TEXT CHARSET ujis COLLATE ujis_japanese_ci, + b TEXT CHARSET utf8mb4 COLLATE utf8mb4_turkish_ci, + c TEXT CHARSET eucjpms COLLATE eucjpms_bin, + d TEXT CHARSET utf8mb4, + FULLTEXT INDEX(a), + FULLTEXT INDEX(b), + FULLTEXT INDEX(c), + FULLTEXT INDEX(d) +) ENGINE = InnoDB; + +INSERT INTO t1 VALUES + ('myisam', 'myisam', 'myisam', 'myisam'), + ('innodb', 'innodb', 'innodb', 'innodb'), + ('innodb myisam', 'innodb myisam', 'innodb myisam', 'innodb myisam'), + ('memory', 'memory', 'memory', 'memory'), + ('archive', 'archive', 'archive', 'archive'), + ('federated', 'federated', 'federated', 'federated'), + ('storage engine innodb', 'storage engine innodb', 'storage engine innodb', 'storage engine innodb'), + ('storage engine myisam', 'storage engine myisam', 'storage engine myisam', 'storage engine myisam'), + ('innobase', 'innobase', 'innobase', 'innobase'), + ('myisam innodb', 'myisam innodb', 'myisam innodb', 'myisam innodb'), + ('innodb myisam engines', 'innodb myisam engines', 'innodb myisam engines', 'innodb myisam engines'); + +# Test the ujis_japanese_ci +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00)); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', ' ', '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00, '"', 0x00, '"', 0x00)); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', '&', 0x00, '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, '&', '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', '%', '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00, '"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', 0x00, 0x00, 0x00, '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00, '"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00)); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00)); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00, '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', '(', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', ')')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', 'm', 'y', 'i', 's', 'a', 'm')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', 'm', 'y', 'i', 's', 'a', 'm', '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00, '"','@', '2') IN BOOLEAN MODE); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', '$', 'm', 'y', 'i', 's', 'a', 'm', '"','@', '4') IN BOOLEAN MODE); +--error ER_PARSE_ERROR +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00, '"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', '$', 's', 't', 'o', 'r', 'a', 'g', 'e', '"','@', '4', 0x00) IN BOOLEAN MODE); + + +# Test the utf8mb4_turkish_ci +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"')); +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT(0x00)); +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', '"')); +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', ' ', '"')); +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', 0x00, '"')); +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT(0x00, '"', 0x00, '"', 0x00)); +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', '&', 0x00, '"')); +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', 0x00, '&', '"')); +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', '%', '"')); +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '"')); +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '"')); +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT(0x00, '"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', 0x00, 0x00, 0x00, '"')); +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT(0x00, '"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00)); +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00, '"','@', '2') IN BOOLEAN MODE); +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', '$', 'm', 'y', 'i', 's', 'a', 'm', '"','@', '4') IN BOOLEAN MODE); +--error ER_PARSE_ERROR +SELECT b FROM t1 WHERE MATCH (b) AGAINST (CONCAT(0x00, '"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', '$', 's', 't', 'o', 'r', 'a', 'g', 'e', '"','@', '4', 0x00) IN BOOLEAN MODE); + +# Test the eucjpms_bin +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"')); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT(0x00)); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', '"')); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', ' ', '"')); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 0x00, '"')); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT(0x00, '"', 0x00, '"', 0x00)); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', '&', 0x00, '"')); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 0x00, '&', '"')); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', '%', '"')); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '"')); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '"')); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT(0x00, '"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', 0x00, 0x00, 0x00, '"')); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT(0x00, '"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00)); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00)); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00, '"')); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', '(', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', ')')); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', 'm', 'y', 'i', 's', 'a', 'm')); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', 'm', 'y', 'i', 's', 'a', 'm', '"')); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00, '"','@', '2') IN BOOLEAN MODE); +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', '$', 'm', 'y', 'i', 's', 'a', 'm', '"','@', '4') IN BOOLEAN MODE); +--error ER_PARSE_ERROR +SELECT c FROM t1 WHERE MATCH (c) AGAINST (CONCAT(0x00, '"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', '$', 's', 't', 'o', 'r', 'a', 'g', 'e', '"','@', '4', 0x00) IN BOOLEAN MODE); + +ALTER TABLE t1 ENGINE = MyISAM; + +# Test the query against myisam to verify +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00)); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', ' ', '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00, '"', 0x00, '"', 0x00)); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', '&', 0x00, '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, '&', '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', '%', '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00, '"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', 0x00, 0x00, 0x00, '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00, '"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', 0x00, '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00)); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00)); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00, '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', '(', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', ')')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', 'm', 'y', 'i', 's', 'a', 'm')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', 'm', 'y', 'i', 's', 'a', 'm', '"')); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 0x00, 'i', 'n', 'n', 'o', 'd', 'b', '@', '$', 'm', 'y', 'i', 's', 'a', 'm', '%', 0x00, 0x00, '"','@', '2') IN BOOLEAN MODE); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT('"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', '$', 'm', 'y', 'i', 's', 'a', 'm', '"','@', '4') IN BOOLEAN MODE); +SELECT a FROM t1 WHERE MATCH (a) AGAINST (CONCAT(0x00, '"', 'i', 'n', 'n', 'o', 'd', 'b', ' ', '$', 's', 't', 'o', 'r', 'a', 'g', 'e', '"','@', '4', 0x00) IN BOOLEAN MODE); + +DROP TABLE t1; + +# Test for BUG#18229097 - FTS: DID NOT FIND WORD 0 IN DOC 39161 FOR QUERY EXPANSION SEARCH. +CREATE TABLE t1 ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + a VARCHAR(200), + FULLTEXT (a) +) ENGINE= InnoDB; + +INSERT INTO t1 (a) VALUES + ('know database'),('good database'), ('gmail email'), ('ghome windows'); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('g *' IN NATURAL LANGUAGE MODE); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('g *' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('g * k *' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('g * k * d *' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('g * go *' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('g * good' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('gm * go *' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('good *' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION); + +SELECT * FROM t1 WHERE MATCH (a) AGAINST ('g* database' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION); + +DROP TABLE t1; diff --git a/mysql-test/suite/innodb_fts/t/misc_1.test b/mysql-test/suite/innodb_fts/t/misc_1.test new file mode 100644 index 00000000000..45eaf447978 --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/misc_1.test @@ -0,0 +1,894 @@ +--source include/have_innodb.inc +--source include/innodb_page_size_small.inc +--source include/no_valgrind_without_big.inc + +#------------------------------------------------------------------------------ +# FTS with FK and update cascade +#------------------------------------------------------------------------------- +set names utf8; + +call mtr.add_suppression("\\[Warning\\] InnoDB: A new Doc ID must be supplied while updating FTS indexed columns."); +call mtr.add_suppression("\\[Warning\\] InnoDB: FTS Doc ID must be larger than [0-9]+ for table `test`.`t1`"); + +# Create FTS table +CREATE TABLE t1 ( + id1 INT , + a1 VARCHAR(200) , + b1 TEXT , + FULLTEXT KEY (a1,b1), PRIMARY KEY (a1, id1) + ) CHARACTER SET = utf8 , ENGINE = InnoDB; + +CREATE TABLE t2 ( + id2 INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + a2 VARCHAR(200), + b2 TEXT , + FOREIGN KEY (a2) REFERENCES t1(a1) ON UPDATE CASCADE, + FULLTEXT KEY (b2,a2) + ) CHARACTER SET = utf8 ,ENGINE = InnoDB; + +# Insert rows +INSERT INTO t1 (id1,a1,b1) VALUES + (1,'MySQL Tutorial','DBMS stands for DataBase VÐƷWİ...') , + (2,'How To Use MySQL Well','After you went through a ...'), + (3,'Optimizing MySQL','In this tutorial we will show ...'); + +# Insert rows +INSERT INTO t1 (id1,a1,b1) VALUES + (4,'1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), + (5,'MySQL vs. YourSQL','In the following database comparison ...'), + (6,'MySQL Security','When configured properly, MySQL ...'); + +# Insert rows in t2 fk table +INSERT INTO t2 (a2,b2) VALUES + ('MySQL Tutorial','DBMS stands for DataBase VÐƷWİ...') , + ('How To Use MySQL Well','After you went through a ...'), + ('Optimizing MySQL','In this tutorial we will show ...'); + +# Insert rows t2 fk table +INSERT INTO t2 (a2,b2) VALUES + ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), + ('MySQL vs. YourSQL','In the following database comparison ...'), + ('MySQL Security','When configured properly, MySQL ...'); + +# error on violating fk constraint +--error 1452 +INSERT INTO t2 (a2,b2) VALUES + ('MySQL Tricks','1. Never run mysqld as root. 2. ...'); + +# error on delete from parent table +--error 1451 +DELETE FROM t1; + +ANALYZE TABLE t1; +ANALYZE TABLE t2; + +SELECT id1 FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial') ORDER BY id1; +SELECT id2 FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial') ORDER BY id2; + +SELECT id1 FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial (+mysql -VÐƷWİ)' IN BOOLEAN MODE) ORDER BY id1; +SELECT id2 FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial (+mysql -VÐƷWİ)' IN BOOLEAN MODE) ORDER BY id2; + +SELECT id1 FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial' WITH QUERY EXPANSION) ORDER BY id1; +SELECT id2 FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial' WITH QUERY EXPANSION) ORDER BY id2; + + +SELECT id1 FROM t1 WHERE MATCH (a1,b1) AGAINST ('"dbms database"@4' IN BOOLEAN MODE) ; +SELECT id2 FROM t2 WHERE MATCH (a2,b2) AGAINST ('"dbms database"@4' IN BOOLEAN MODE) ; + +set global innodb_optimize_fulltext_only=1; +optimize table t1; +set global innodb_optimize_fulltext_only=0; +# Updating parent table hence child table should get updated due to 'update cascade' clause +UPDATE t1 SET a1 = "changing column - on update cascade" , b1 = "to check foreign constraint" WHERE +MATCH (a1,b1) AGAINST ('tutorial (+mysql -VÐƷWİ)' IN BOOLEAN MODE) ; + +# no records expected +SELECT id1 FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial (+mysql -VÐƷWİ)' IN BOOLEAN MODE) ; +# InnoDB:Error child table shows records which is incorrect - UPADTE on Fix +SELECT id2 FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial (+mysql -VÐƷWİ)' IN BOOLEAN MODE) ; + +# it shows updated record +SELECT id1 FROM t1 WHERE MATCH (a1,b1) AGAINST ('+update +cascade' IN BOOLEAN MODE) ORDER BY id1; +# InnoDB:Error child table does not show the expected record +SELECT id2 FROM t2 WHERE MATCH (a2,b2) AGAINST ('+update +cascade' IN BOOLEAN MODE) ORDER BY id2; +SELECT id2 FROM t2 WHERE a2 LIKE '%UPDATE CASCADE%' ORDER BY id2; + +DROP TABLE t2 , t1; + +# on update cascade +create table t1 (s1 int, s2 varchar(200), primary key (s1,s2)) ENGINE = InnoDB; +create table t2 (s1 int, s2 varchar(200), + fulltext key(s2), + foreign key (s1,s2) references t1 (s1,s2) on update cascade) ENGINE = InnoDB; +insert into t1 values (1,'Sunshine'),(2,'Lollipops'); +insert into t2 values (1,'Sunshine'),(2,'Lollipops'); +update t1 set s2 = 'Rainbows' where s2 <> 'Sunshine'; +commit; +select * from t2 where match(s2) against ('Lollipops'); +DROP TABLE t2 , t1; + +# on delete cascade +create table t1 (s1 int, s2 varchar(200), primary key (s1,s2)) ENGINE = InnoDB; +create table t2 (s1 int, s2 varchar(200), + fulltext key(s2), + foreign key (s1,s2) references t1 (s1,s2) on delete cascade) ENGINE = InnoDB; +insert into t1 values (1,'Sunshine'),(2,'Lollipops'); +insert into t2 values (1,'Sunshine'),(2,'Lollipops'); +delete from t1 where s2 <> 'Sunshine'; +select * from t2 where match(s2) against ('Lollipops'); +DROP TABLE t2 , t1; + +# on delete set NULL +create table t1 (s1 int, s2 varchar(200), primary key (s1,s2)) ENGINE = InnoDB; +create table t2 (s1 int, s2 varchar(200), + fulltext key(s2), + foreign key (s1,s2) references t1 (s1,s2) on delete set null) ENGINE = InnoDB; +insert into t1 values (1,'Sunshine'),(2,'Lollipops'); +insert into t2 values (1,'Sunshine'),(2,'Lollipops'); +delete from t1 where s2 <> 'Sunshine'; +select * from t2 where match(s2) against ('Lollipops'); +DROP TABLE t2 , t1; + + +# on update set NULL +create table t1 (s1 int, s2 varchar(200), primary key (s1,s2)) ENGINE = InnoDB; +create table t2 (s1 int, s2 varchar(200), + fulltext key(s2), + foreign key (s1,s2) references t1 (s1,s2) on update set null) ENGINE = InnoDB; +insert into t1 values (1,'Sunshine'),(2,'Lollipops'); +insert into t2 values (1,'Sunshine'),(2,'Lollipops'); +update t1 set s2 = 'Rainbows' where s2 <> 'Sunshine'; +commit; +select * from t2 where match(s2) against ('Lollipops'); +DROP TABLE t2 , t1; + +# When Doc ID is involved +create table t1 (s1 bigint unsigned not null, s2 varchar(200), + primary key (s1,s2)) ENGINE = InnoDB; +create table t2 (FTS_DOC_ID BIGINT UNSIGNED NOT NULL, s2 varchar(200), + foreign key (FTS_DOC_ID) references t1 (s1) + on update cascade) ENGINE = InnoDB; + +create fulltext index idx on t2(s2); + +show create table t2; + +insert into t1 values (1,'Sunshine'),(2,'Lollipops'); +insert into t2 values (1,'Sunshine'),(2,'Lollipops'); + +update t1 set s1 = 3 where s1=1; + +select * from t2 where match(s2) against ('sunshine'); + +# FTS Doc ID cannot be reused +--error 1451 +update t1 set s1 = 1 where s1=3; + +DROP TABLE t2 , t1; + +#------------------------------------------------------------------------------ +# FTS with FK and delete casecade +#------------------------------------------------------------------------------ + +# Create FTS table +CREATE TABLE t1 ( + id1 INT , + a1 VARCHAR(200) PRIMARY KEY, + b1 TEXT character set utf8 , + FULLTEXT KEY (a1,b1) + ) CHARACTER SET = utf8 ,ENGINE = InnoDB; + +CREATE TABLE t2 ( + id2 INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + a2 VARCHAR(200), + b2 TEXT character set utf8 , + FOREIGN KEY (a2) REFERENCES t1(a1) ON DELETE CASCADE, + FULLTEXT KEY (b2,a2) + ) CHARACTER SET = utf8 ,ENGINE = InnoDB; + +# Insert rows +INSERT INTO t1 (id1,a1,b1) VALUES + (1,'MySQL Tutorial','DBMS stands for DataBase VÐƷWİ...') , + (2,'How To Use MySQL Well','After you went through a ...'), + (3,'Optimizing MySQL','In this tutorial we will show ...'), + (4,'1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), + (5,'MySQL vs. YourSQL','In the following database comparison ...'), + (6,'MySQL Security','When configured properly, MySQL ...'); + +# Insert rows in t2 +INSERT INTO t2 (a2,b2) VALUES + ('MySQL Tutorial','DBMS stands for DataBase VÐƷWİ...') , + ('How To Use MySQL Well','After you went through a ...'), + ('Optimizing MySQL','In this tutorial we will show ...'), + ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), + ('MySQL vs. YourSQL','In the following database comparison ...'), + ('MySQL Security','When configured properly, MySQL ...'); + +# delete records from parent +DELETE FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial (+mysql -VÐƷWİ)' IN BOOLEAN MODE) ; + +# no records expected +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial (+mysql -VÐƷWİ)' IN BOOLEAN MODE) ; +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial (+mysql -VÐƷWİ)' IN BOOLEAN MODE) ; + +SELECT * FROM t1 WHERE a1 LIKE '%tutorial%'; +SELECT * FROM t2 WHERE a2 LIKE '%tutorial%'; + +DROP TABLE t2 , t1; + +#------------------------------------------------------------------------------ +# FTS with FK+transactions and UPDATE casecade with transaction +#------------------------------------------------------------------------------- + +call mtr.add_suppression("\\[ERROR\\] InnoDB: FTS Doc ID must be larger than 3 for table `test`.`t2`"); + +# Create FTS table +CREATE TABLE t1 ( + id1 INT , + a1 VARCHAR(200) , + b1 TEXT , + FULLTEXT KEY (a1,b1), PRIMARY KEY(a1, id1) + ) CHARACTER SET = utf8 , ENGINE = InnoDB; + +CREATE TABLE t2 ( + id2 INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + a2 VARCHAR(200), + b2 TEXT , + FOREIGN KEY (a2) REFERENCES t1(a1) ON UPDATE CASCADE, + FULLTEXT KEY (b2,a2) + ) CHARACTER SET = utf8 ,ENGINE = InnoDB; + +# Insert rows +INSERT INTO t1 (id1,a1,b1) VALUES + (1,'MySQL Tutorial','DBMS stands for DataBase VÐƷWİ...') , + (2,'How To Use MySQL Well','After you went through a ...'), + (3,'Optimizing MySQL','In this tutorial we will show ...'); + +# Insert rows in t2 fk table +INSERT INTO t2 (a2,b2) VALUES + ('MySQL Tutorial','DBMS stands for DataBase VÐƷWİ...') , + ('How To Use MySQL Well','After you went through a ...'), + ('Optimizing MySQL','In this tutorial we will show ...'); + +START TRANSACTION; +# Insert rows +INSERT INTO t1 (id1,a1,b1) VALUES + (4,'1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), + (5,'MySQL vs. YourSQL','In the following database comparison ...'), + (6,'MySQL Security','When configured properly, MySQL ...'); + +# Insert rows t2 fk table +INSERT INTO t2 (a2,b2) VALUES + ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), + ('MySQL vs. YourSQL','In the following database comparison ...'), + ('MySQL Security','When configured properly, MySQL ...'); + +# error on violating fk constraint +--error 1452 +INSERT INTO t2 (a2,b2) VALUES + ('MySQL Tricks','1. Never run mysqld as root. 2. ...'); + +# error on DELETE FROM parent table +--error 1451 +DELETE FROM t1; + +# records expected +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial') ORDER BY id1; +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial') ORDER BY id2; +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial (+mysql -VÐƷWİ)' IN BOOLEAN MODE) ORDER BY id1; +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial (+mysql -VÐƷWİ)' IN BOOLEAN MODE) ORDER BY id2; +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial' WITH QUERY EXPANSION) ORDER BY id1; +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial' WITH QUERY EXPANSION) ORDER BY id2; +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('"dbms database"@4' IN BOOLEAN MODE) ; +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('"dbms database"@4' IN BOOLEAN MODE) ; + +# no records as data not COMMITted. +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('root') ; +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('root') ; +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('mysqld (+root)' IN BOOLEAN MODE) ; +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('mysqld (-root)' IN BOOLEAN MODE) ; +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('root' WITH QUERY EXPANSION) ; +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('root' WITH QUERY EXPANSION) ; +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('"database comparison"@02' IN BOOLEAN MODE) ; +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('"database comparison"@02' IN BOOLEAN MODE) ; + +SELECT * FROM t1 ORDER BY id1; +SELECT * FROM t2 ORDER BY id2; + +COMMIT; + +START TRANSACTION; +# Updating parent table hence child table should get updated due to 'UPDATE cascade' clause +UPDATE t1 SET a1 = "changing column - on UPDATE cascade" , b1 = "to check foreign constraint" WHERE +MATCH (a1,b1) AGAINST ('tutorial (+mysql -VÐƷWİ)' IN BOOLEAN MODE) ; +COMMIT; + +# no records expected +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('tutorial (+mysql -VÐƷWİ)' IN BOOLEAN MODE) ; +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('tutorial (+mysql -VÐƷWİ)' IN BOOLEAN MODE) ; + +# it shows updated record +SELECT * FROM t1 WHERE MATCH (a1,b1) AGAINST ('+UPDATE +cascade' IN BOOLEAN MODE) ORDER BY id1; +SELECT * FROM t2 WHERE MATCH (a2,b2) AGAINST ('+UPDATE +cascade' IN BOOLEAN MODE) ORDER BY id2; +SELECT * FROM t2 WHERE a2 LIKE '%UPDATE CASCADE%' ORDER BY id2; + +DROP TABLE t2 , t1; + + +# FTS with FK+transactions - UPDATE cascade +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200), PRIMARY KEY (s1,s2)) ENGINE = InnoDB; +CREATE TABLE t2 (s1 INT, s2 VARCHAR(200), + FULLTEXT KEY(s2), + FOREIGN KEY (s1,s2) REFERENCES t1 (s1,s2) on UPDATE cascade) ENGINE = InnoDB; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'Sunshine'),(2,'Lollipops'); +INSERT INTO t2 VALUES (1,'Sunshine'),(2,'Lollipops'); +UPDATE t1 set s2 = 'Rainbows' WHERE s2 <> 'Sunshine'; +COMMIT; +SELECT * FROM t2 WHERE MATCH(s2) AGAINST ('Lollipops'); +DROP TABLE t2 , t1; + +# FTS with FK+transactions - on DELETE cascade +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200), PRIMARY KEY (s1,s2)) ENGINE = InnoDB; +CREATE TABLE t2 (s1 INT, s2 VARCHAR(200), + FULLTEXT KEY(s2), + FOREIGN KEY (s1,s2) REFERENCES t1 (s1,s2) on DELETE cascade) ENGINE = InnoDB; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'Sunshine'),(2,'Lollipops'); +INSERT INTO t2 VALUES (1,'Sunshine'),(2,'Lollipops'); +DELETE FROM t1 WHERE s2 <> 'Sunshine'; +COMMIT; +SELECT * FROM t2 WHERE MATCH(s2) AGAINST ('Lollipops'); +DROP TABLE t2 , t1; + +# FTS with FK+transactions - DELETE SET NULL +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200), PRIMARY KEY (s1,s2)) ENGINE = InnoDB; +CREATE TABLE t2 (s1 INT, s2 VARCHAR(200), + FULLTEXT KEY(s2), + FOREIGN KEY (s1,s2) REFERENCES t1 (s1,s2) on DELETE SET NULL) ENGINE = InnoDB; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'Sunshine'),(2,'Lollipops'); +INSERT INTO t2 VALUES (1,'Sunshine'),(2,'Lollipops'); +DELETE FROM t1 WHERE s2 <> 'Sunshine'; +COMMIT; +SELECT * FROM t2 WHERE MATCH(s2) AGAINST ('Lollipops'); +DROP TABLE t2 , t1; + + +# FTS with FK+transactions - UPDATE SET NULL +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200), PRIMARY KEY (s1,s2)) ENGINE = InnoDB; +CREATE TABLE t2 (s1 INT, s2 VARCHAR(200), + FULLTEXT KEY(s2), + FOREIGN KEY (s1,s2) REFERENCES t1 (s1,s2) on UPDATE SET NULL) ENGINE = InnoDB; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'Sunshine'),(2,'Lollipops'); +INSERT INTO t2 VALUES (1,'Sunshine'),(2,'Lollipops'); +UPDATE t1 set s2 = 'Rainbows' WHERE s2 <> 'Sunshine'; +COMMIT; +SELECT * FROM t2 WHERE MATCH(s2) AGAINST ('Lollipops'); +DROP TABLE t2 , t1; + + +#----------------------------------------------------------------------------- + +# FTS with FK+transactions - UPDATE cascade +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200), PRIMARY KEY (s1,s2)) ENGINE = InnoDB; +CREATE TABLE t2 (s1 INT, s2 VARCHAR(200), + FULLTEXT KEY(s2), + FOREIGN KEY (s1,s2) REFERENCES t1 (s1,s2) on UPDATE cascade) ENGINE = InnoDB; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'Sunshine'),(2,'Lollipops'); +INSERT INTO t2 VALUES (1,'Sunshine'),(2,'Lollipops'); +UPDATE t1 set s2 = 'Rainbows' WHERE s2 <> 'Sunshine'; +ROLLBACK; +SELECT * FROM t2 WHERE MATCH(s2) AGAINST ('Lollipops'); +DROP TABLE t2 , t1; + +# FTS with FK+transactions - DELETE cascade +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200), PRIMARY KEY (s1,s2)) ENGINE = InnoDB; +CREATE TABLE t2 (s1 INT, s2 VARCHAR(200), + FULLTEXT KEY(s2), + FOREIGN KEY (s1,s2) REFERENCES t1 (s1,s2) on DELETE cascade) ENGINE = InnoDB; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'Sunshine'),(2,'Lollipops'); +INSERT INTO t2 VALUES (1,'Sunshine'),(2,'Lollipops'); +DELETE FROM t1 WHERE s2 <> 'Sunshine'; +ROLLBACK; +SELECT * FROM t2 WHERE MATCH(s2) AGAINST ('Lollipops'); +DROP TABLE t2 , t1; + +# FTS with FK+transactions - DELETE SET NULL +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200), PRIMARY KEY (s1,s2)) ENGINE = InnoDB; +CREATE TABLE t2 (s1 INT, s2 VARCHAR(200), + FULLTEXT KEY(s2), + FOREIGN KEY (s1,s2) REFERENCES t1 (s1,s2) on DELETE SET NULL) ENGINE = InnoDB; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'Sunshine'),(2,'Lollipops'); +INSERT INTO t2 VALUES (1,'Sunshine'),(2,'Lollipops'); +DELETE FROM t1 WHERE s2 <> 'Sunshine'; +ROLLBACK; +SELECT * FROM t2 WHERE MATCH(s2) AGAINST ('Lollipops'); +DROP TABLE t2 , t1; + + +# FTS with FK+transactions - UPDATE SET NULL +CREATE TABLE t1 (s1 INT, s2 VARCHAR(200), PRIMARY KEY (s1,s2)) ENGINE = InnoDB; +CREATE TABLE t2 (s1 INT, s2 VARCHAR(200), + FULLTEXT KEY(s2), + FOREIGN KEY (s1,s2) REFERENCES t1 (s1,s2) on UPDATE SET NULL) ENGINE = InnoDB; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'Sunshine'),(2,'Lollipops'); +INSERT INTO t2 VALUES (1,'Sunshine'),(2,'Lollipops'); +UPDATE t1 set s2 = 'Rainbows' WHERE s2 <> 'Sunshine'; +ROLLBACK; +SELECT * FROM t2 WHERE MATCH(s2) AGAINST ('Lollipops'); +DROP TABLE t2 , t1; + + +#------------------------------------------------------------------------------ +# FTS index with compressed row format +#------------------------------------------------------------------------------ + +# Save innodb variables +let $innodb_file_per_table_orig=`select @@innodb_file_per_table`; + +set global innodb_file_per_table=1; + +# Create FTS table +CREATE TABLE t1 ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + a VARCHAR(200), + b TEXT + ) CHARACTER SET = utf8, ROW_FORMAT=COMPRESSED, ENGINE = InnoDB; + +# Insert rows +INSERT INTO t1 (a,b) VALUES + ('MySQL Tutorial','DBMS stands for DataBase VÐƷWİ...') , + ('How To Use MySQL Well','After you went through a ...'), + ('Optimizing MySQL','In this tutorial we will show ...'); + +# Create the FTS index Using Alter Table +ALTER TABLE t1 ADD FULLTEXT INDEX idx (a,b); +EVAL SHOW CREATE TABLE t1; + +# Check whether individual space id created for AUX tables +SELECT count(*) FROM information_schema.innodb_sys_tables WHERE name LIKE "%FTS_%" AND space !=0; + +# Insert rows +INSERT INTO t1 (a,b) VALUES + ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), + ('MySQL vs. YourSQL','In the following database comparison ...'), + ('MySQL Security','When configured properly, MySQL ...'); + +-- disable_result_log +ANALYZE TABLE t1; +-- enable_result_log + +# Select word "tutorial" in the table +SELECT * FROM t1 WHERE MATCH (a,b) + AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE) ORDER BY id; + +# boolean mode +select * from t1 where MATCH(a,b) AGAINST("+tutorial +VÐƷWİ" IN BOOLEAN MODE); +--error ER_PARSE_ERROR +select * from t1 where MATCH(a,b) AGAINST("+-VÐƷWİ" IN BOOLEAN MODE); +select * from t1 where MATCH(a,b) AGAINST("+Mysql +(tricks never)" IN BOOLEAN MODE); +select * from t1 where MATCH(a,b) AGAINST("+mysql -(tricks never)" IN BOOLEAN MODE) ORDER BY id; +select *, MATCH(a,b) AGAINST("mysql stands" IN BOOLEAN MODE) as x from t1 ORDER BY id; +select * from t1 where MATCH a,b AGAINST ("+database* +VÐƷW*" IN BOOLEAN MODE); +select * from t1 where MATCH a,b AGAINST ('"security mysql"' IN BOOLEAN MODE); + +# query expansion +select * from t1 where MATCH(a,b) AGAINST ("VÐƷWİ" WITH QUERY EXPANSION) ORDER BY id; + +# Drop index +ALTER TABLE t1 DROP INDEX idx; + +# Create the FTS index again +CREATE FULLTEXT INDEX idx on t1 (a,b); + +-- disable_query_log +-- disable_result_log +ANALYZE TABLE t1; +-- enable_result_log +-- enable_query_log + +# Select word "tutorial" in the table +SELECT * FROM t1 WHERE MATCH (a,b) + AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE) ORDER BY id; + +# boolean mode +select * from t1 where MATCH(a,b) AGAINST("+tutorial +VÐƷWİ" IN BOOLEAN MODE); +select * from t1 where MATCH(a,b) AGAINST("+dbms" IN BOOLEAN MODE); +select * from t1 where MATCH(a,b) AGAINST("+Mysql +(tricks never)" IN BOOLEAN MODE); +select * from t1 where MATCH(a,b) AGAINST("+mysql -(tricks never)" IN BOOLEAN MODE) ORDER BY id; +select *, MATCH(a,b) AGAINST("mysql VÐƷWİ" IN BOOLEAN MODE) as x from t1 ORDER BY id; +# Innodb:Assert eval0eval.c line 148 +#select * from t1 where MATCH a,b AGAINST ("+database* +VÐƷWİ*" IN BOOLEAN MODE); +select * from t1 where MATCH a,b AGAINST ('"security mysql"' IN BOOLEAN MODE); + +# query expansion +select * from t1 where MATCH(a,b) AGAINST ("VÐƷWİ" WITH QUERY EXPANSION) ORDER BY id; + + +# insert for proximity search +INSERT INTO t1 (a,b) VALUES ('test query expansion','for database ...'); +# Insert into table with similar word of different distances +INSERT INTO t1 (a,b) VALUES + ('test proximity search, test, proximity and phrase', + 'search, with proximity innodb'); + +INSERT INTO t1 (a,b) VALUES + ('test proximity fts search, test, proximity and phrase', + 'search, with proximity innodb'); + +INSERT INTO t1 (a,b) VALUES + ('test more proximity fts search, test, more proximity and phrase', + 'search, with proximity innodb'); + +# This should only return the first document +SELECT * FROM t1 + WHERE MATCH (a,b) + AGAINST ('"proximity search"@2' IN BOOLEAN MODE); + +# This would return no document +SELECT * FROM t1 + WHERE MATCH (a,b) + AGAINST ('"proximity search"@1' IN BOOLEAN MODE); + +# This give you all three documents +SELECT * FROM t1 + WHERE MATCH (a,b) + AGAINST ('"proximity search"@3' IN BOOLEAN MODE) ORDER BY id; + +# Similar boundary testing for the words +SELECT * FROM t1 + WHERE MATCH (a,b) + AGAINST ('"test proximity"@5' IN BOOLEAN MODE) ORDER BY id; + +# Test with more word The last document will return, please notice there +# is no ordering requirement for proximity search. +SELECT * FROM t1 + WHERE MATCH (a,b) + AGAINST ('"more test proximity"@2' IN BOOLEAN MODE); + +SELECT * FROM t1 + WHERE MATCH (a,b) + AGAINST ('"more test proximity"@3' IN BOOLEAN MODE); + +# The phrase search will not require exact word ordering +SELECT * FROM t1 + WHERE MATCH (a,b) + AGAINST ('"more fts proximity"@03' IN BOOLEAN MODE); + + +UPDATE t1 SET a = UPPER(a) , b = UPPER(b) ; +UPDATE t1 SET a = UPPER(a) , b = LOWER(b) ; + +select * from t1 where MATCH(a,b) AGAINST("+tutorial +dbms" IN BOOLEAN MODE); +select * from t1 where MATCH(a,b) AGAINST("+VÐƷWİ" IN BOOLEAN MODE); + +SELECT * FROM t1 WHERE MATCH (a,b) + AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE) ORDER BY id; + +DELETE FROM t1 WHERE MATCH (a,b) AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); +DELETE FROM t1 WHERE MATCH (a,b) AGAINST ('"proximity search"@14' IN BOOLEAN MODE); + + +SELECT * FROM t1 WHERE MATCH (a,b) + AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); + +SELECT * FROM t1 ORDER BY id; + +DROP TABLE t1; +eval SET GLOBAL innodb_file_per_table=$innodb_file_per_table_orig; + +#------------------------------------------------------------------------------ +# FTS index with utf8 character testcase +#------------------------------------------------------------------------------ + +# Create FTS table +EVAL CREATE TABLE t1 ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + a VARCHAR(200), + b TEXT + ) CHARACTER SET = utf8, ENGINE=InnoDB; + + +# Insert rows from different languages +INSERT INTO t1 (a,b) VALUES +('Я могу есть стекло', 'оно мне не вредит'), +('Мога да ям стъкло', 'то не ми вреди'), +('Μπορῶ νὰ φάω σπασμένα' ,'γυαλιὰ χωρὶς νὰ πάθω τίποτα'), +('Příliš žluťoučký kůň', 'úpěl ďábelské kódy'), +('Sævör grét', 'áðan því úlpan var ónýt'), +('うゐのおくやま','けふこえて'), +('いろはにほへど ちりぬる','あさきゆめみじ ゑひもせず'); + +# insert english text +INSERT INTO t1 (a,b) VALUES + ('MySQL Tutorial','request docteam@oraclehelp.com ...') , + ('Trial version','query performace @1255 minute on 2.1Hz Memory 2GB...') , + ('when To Use MySQL Well','for free faq mail@xyz.com ...'); + +# Create the FTS index again +CREATE FULLTEXT INDEX idx on t1 (a,b); + +# FTS Queries +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ("вредит χωρὶς") ORDER BY id; +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ("оно" WITH QUERY EXPANSION); + +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST("вред*" IN BOOLEAN MODE) ORDER BY id; +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST("+γυαλιὰ +tutorial" IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST("+tutorial +(Мога τίποτα)" IN BOOLEAN MODE); + +# Innodb:error - no result returned (update result of query once fixed) (innodb limit , does not understand character boundry for japanses like charcter set) +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ("あさきゆめみじ ゑひもせず"); +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ("ちりぬる" WITH QUERY EXPANSION); + +# Innodb:error - no result returned (update result of query once fixed) (innodb limit , does not understand character boundry for japanses like charcter set) +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ("+あさきゆめみじ +ゑひもせず" IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST("うゐのおく*" IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST("+Sævör +úlpan" IN BOOLEAN MODE); + +SELECT * FROM t1 + WHERE MATCH (a,b) + AGAINST ('"γυαλιὰ χωρὶς"@2' IN BOOLEAN MODE); + +SELECT * FROM t1 + WHERE MATCH (a,b) + AGAINST ('"query performace"@02' IN BOOLEAN MODE); + +SELECT * FROM t1 + WHERE MATCH (a,b) + AGAINST ('"πάθω τίποτα"@2' IN BOOLEAN MODE); + +SELECT * FROM t1 + WHERE MATCH (a,b) + AGAINST ('"あさきゆめみじ ゑひもせず"@1' IN BOOLEAN MODE); + +SELECT * FROM t1 + WHERE MATCH (a,b) + AGAINST ('"あさきゆめみじ ゑひもせず"@2' IN BOOLEAN MODE); + +ALTER TABLE t1 DROP INDEX idx; +# Create the FTS index again +CREATE FULLTEXT INDEX idx on t1 (a,b); + +# Innodb:error - no result returned (update result of query once fixed) (innodb limit , does not understand character boundry for japanses like charcter set) +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ("あさきゆめみじ ゑひもせず"); +# Update fails because where condition do not succeed which is incorrect (update result of query once fixed) +UPDATE t1 SET a = "Pchnąć w tę łódź jeża" , b = "lub osiem skrzyń fig" WHERE MATCH(a,b) AGAINST ("あさきゆめみじ ゑひもせず"); +UPDATE t1 SET a = "В чащах юга жил-был цитрус? Да", b = "но фальшивый экземпляр! ёъ" WHERE MATCH(a,b) AGAINST ("вред*" IN BOOLEAN MODE); +DELETE FROM t1 WHERE MATCH(a,b) AGAINST("+Sævör +úlpan" IN BOOLEAN MODE); + +# Innodb error - no result returned +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ("あさきゆめみじ ゑひもせず"); +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST ("łódź osiem"); +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST("вред*" IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST("фальшив*" IN BOOLEAN MODE) ORDER BY id; +SELECT * FROM t1 WHERE MATCH(a,b) AGAINST("+Sævör +úlpan" IN BOOLEAN MODE); + +SELECT * FROM t1 + WHERE MATCH (a,b) + AGAINST ('"łódź jeża"@2' IN BOOLEAN MODE); + +SELECT * FROM t1 ORDER BY id; +DROP TABLE t1; + +# This is to test the update operation on FTS indexed and non-indexed +# column +CREATE TABLE t1(ID INT PRIMARY KEY, + no_fts_field VARCHAR(10), + fts_field VARCHAR(10), + FULLTEXT INDEX f(fts_field)) ENGINE=INNODB; + +INSERT INTO t1 VALUES (1, 'AAA', 'BBB'); + +SELECT * FROM t1 WHERE MATCH(fts_field) against("BBB"); + +# Update FULLTEXT indexed column, Doc ID will be updated +UPDATE t1 SET fts_field='anychange' where id = 1; + +SELECT * FROM t1 WHERE MATCH(fts_field) against("anychange"); + +# Update non-FULLTEXT indexed column, Doc ID stay to be the same +UPDATE t1 SET no_fts_field='anychange' where id = 1; + +SELECT * FROM t1 WHERE MATCH(fts_field) against("anychange"); + +# Update both FULLTEXT indexed and non-indexed column, Doc ID will be updated +UPDATE t1 SET no_fts_field='anychange', fts_field='other' where id = 1; + +SELECT * FROM t1 WHERE MATCH(fts_field) against("other"); + +SELECT * FROM t1 WHERE MATCH(fts_field) against("BBB"); + +# FTS index dropped, the DOC_ID column is kept, however, the ID will not +# change +DROP INDEX f on t1; + +UPDATE t1 SET fts_field='anychange' where id = 1; + +UPDATE t1 SET no_fts_field='anychange' where id = 1; + +UPDATE t1 SET no_fts_field='anychange', fts_field='other' where id = 1; + +CREATE FULLTEXT INDEX f ON t1(FTS_FIELD); + +SELECT * FROM t1 WHERE MATCH(fts_field) against("other"); + +DROP TABLE t1; + +# Test on user supplied 'FTS_DOC_ID' +CREATE TABLE t1(`FTS_DOC_ID` serial, + no_fts_field VARCHAR(10), + fts_field VARCHAR(10), + FULLTEXT INDEX f(fts_field)) ENGINE=INNODB; + +INSERT INTO t1 VALUES (1, 'AAA', 'BBB'); + +# Doc ID must be updated as well (HA_FTS_INVALID_DOCID). +--error 182 +UPDATE t1 SET fts_field='anychange' where FTS_DOC_ID = 1; + +UPDATE t1 SET fts_field='anychange', FTS_DOC_ID = 2 where FTS_DOC_ID = 1; + +SELECT * FROM t1 WHERE MATCH(fts_field) against("anychange"); + +# "BBB" should be marked as deleted. +SELECT * FROM t1 WHERE MATCH(fts_field) against("BBB"); + +UPDATE t1 SET no_fts_field='anychange' where FTS_DOC_ID = 2; + +SELECT * FROM t1 WHERE MATCH(fts_field) against("anychange"); + +# "HA_FTS_INVALID_DOCID" +--error 182 +UPDATE t1 SET no_fts_field='anychange', fts_field='other' where FTS_DOC_ID = 2; + +SELECT * FROM t1 WHERE MATCH(fts_field) against("other"); + +# Doc ID must be monotonically increase (HA_FTS_INVALID_DOCID) +--error 182 +UPDATE t1 SET FTS_DOC_ID = 1 where FTS_DOC_ID = 2; + +DROP INDEX f ON t1; + +# After FULLTEXT index dropped, we can update the fields freely +UPDATE t1 SET fts_field='newchange' where FTS_DOC_ID = 2; + +UPDATE t1 SET no_fts_field='anychange' where FTS_DOC_ID = 2; + +SELECT * FROM t1; + +DROP TABLE t1; + +CREATE TABLE t1(ID INT PRIMARY KEY, + no_fts_field VARCHAR(10), + fts_field VARCHAR(10), + FULLTEXT INDEX f(fts_field), index k(fts_field)) ENGINE=INNODB; + +CREATE TABLE t2(ID INT PRIMARY KEY, + no_fts_field VARCHAR(10), + fts_field VARCHAR(10), + FULLTEXT INDEX f(fts_field), + INDEX k2(fts_field), + FOREIGN KEY(fts_field) REFERENCES + t1(fts_field) ON UPDATE CASCADE) ENGINE=INNODB; + +INSERT INTO t1 VALUES (1, 'AAA', 'BBB'); + +INSERT INTO t2 VALUES (1, 'AAA', 'BBB'); + +update t1 set fts_field='newchange' where id =1; + +SELECT * FROM t1 WHERE MATCH(fts_field) against("BBB"); +SELECT * FROM t2 WHERE MATCH(fts_field) against("BBB"); +SELECT * FROM t1 WHERE MATCH(fts_field) against("newchange"); +SELECT * FROM t2 WHERE MATCH(fts_field) against("newchange"); + +DROP TABLE t2; + +DROP TABLE t1; + +# Testcases adopted from innodb_multi_update.test + +CREATE TABLE t1(id INT PRIMARY KEY, + fts_field VARCHAR(10), + FULLTEXT INDEX f(fts_field)) ENGINE=INNODB; + + +CREATE TABLE t2(id INT PRIMARY KEY, + fts_field VARCHAR(10), + FULLTEXT INDEX f(fts_field)) ENGINE=INNODB; + +INSERT INTO t1 values (1,'100'),(2,'200'),(3,'300'),(4,'400'),(5,'500'),(6,'600'), (7,'700'),(8,'800'),(9,'900'),(10,'1000'),(11,'1100'),(12,'1200'); +INSERT INTO t2 values (1,'100'),(2,'200'),(3,'300'),(4,'400'),(5,'500'),(6,'600'), (7,'700'),(8,'800'); + +UPDATE t1, t2 set t1.fts_field = CONCAT(t1.fts_field, 'foo'); + +UPDATE t1, t2 set t1.fts_field = CONCAT(t1.fts_field, 'foo') WHERE t1.fts_field = "100foo"; + +# Update two tables in the same statement +UPDATE t1, t2 set t1.fts_field = CONCAT(t1.fts_field, 'xoo'), t2.fts_field = CONCAT(t1.fts_field, 'xoo') where t1.fts_field=CONCAT(t2.fts_field, 'foo'); + +# Following selects shows whether the correct Doc ID are updated + +# This row should present in table t1 +SELECT * FROM t1 WHERE MATCH(fts_field) against("100foofoo"); + +# Following rows should be dropped +SELECT * FROM t1 WHERE MATCH(fts_field) against("100foo"); +SELECT * FROM t1 WHERE MATCH(fts_field) against("100"); + +# This row should present in table t2 +SELECT * FROM t2 WHERE MATCH(fts_field) against("400fooxoo"); +SELECT * FROM t2 WHERE MATCH(fts_field) against("100"); + +# Follow rows should be marked as dropped +SELECT * FROM t2 WHERE MATCH(fts_field) against("200"); +SELECT * FROM t2 WHERE MATCH(fts_field) against("400"); + + +DROP TABLE t1; + +DROP TABLE t2; + + +--echo +--echo BUG#13701973/64274: MYSQL THREAD WAS SUSPENDED WHEN EXECUTE UPDATE QUERY +--echo +# FTS setup did not track which tables it had already looked at to see whether +# they need initialization. Hilarity ensued when hitting circular dependencies. + +SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; + +CREATE TABLE t1 ( + t1_id INT(10) UNSIGNED NOT NULL, + t2_id INT(10) UNSIGNED DEFAULT NULL, + PRIMARY KEY (t1_id), + FOREIGN KEY (t2_id) REFERENCES t2 (t2_id) + ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB; + +CREATE TABLE t2 ( + t1_id INT(10) UNSIGNED NOT NULL, + t2_id INT(10) UNSIGNED NOT NULL, + t3_id INT(10) UNSIGNED NOT NULL, + t4_id INT(10) UNSIGNED NOT NULL, + PRIMARY KEY (t2_id), + FOREIGN KEY (t1_id) REFERENCES t1 (t1_id), + FOREIGN KEY (t3_id) REFERENCES t3 (t3_id) + ON DELETE CASCADE ON UPDATE CASCADE, + FOREIGN KEY (t4_id) REFERENCES t4 (t4_id) +) ENGINE=InnoDB; + +CREATE TABLE t3 ( + t3_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, + payload char(3), + PRIMARY KEY (t3_id) +) ENGINE=InnoDB; + +INSERT INTO t3 VALUES (1, '100'); + +CREATE TABLE t4 ( + t2_id INT(10) UNSIGNED DEFAULT NULL, + t4_id INT(10) UNSIGNED NOT NULL, + PRIMARY KEY (t4_id), + FOREIGN KEY (t2_id) REFERENCES t2 (t2_id) + ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB; + +SET FOREIGN_KEY_CHECKS=1; + +UPDATE t3 SET payload='101' WHERE t3_id=1; + +SET FOREIGN_KEY_CHECKS=0; + +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; +DROP TABLE t4; + +SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; diff --git a/mysql-test/suite/innodb_fts/t/opt.opt b/mysql-test/suite/innodb_fts/t/opt.opt new file mode 100644 index 00000000000..d7d47164883 --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/opt.opt @@ -0,0 +1 @@ +--query_cache_type=0 diff --git a/mysql-test/suite/innodb_fts/t/opt.test b/mysql-test/suite/innodb_fts/t/opt.test new file mode 100644 index 00000000000..19dfdcad8fd --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/opt.test @@ -0,0 +1,1086 @@ +--source include/have_innodb.inc + +# +# Tests for optimizations for InnoDB fulltext search (WL#6043) +# + +CREATE TABLE wp( + FTS_DOC_ID BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, + title VARCHAR(255) NOT NULL DEFAULT '', + text MEDIUMTEXT NOT NULL, + dummy INTEGER, + PRIMARY KEY (FTS_DOC_ID), + UNIQUE KEY FTS_DOC_ID_INDEX (FTS_DOC_ID), + FULLTEXT KEY idx (title,text) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +INSERT INTO wp (title, text) VALUES + ('MySQL Tutorial','DBMS stands for MySQL DataBase ...'), + ('How To Use MySQL Well','After you went through a ...'), + ('Optimizing MySQL','In this tutorial we will show ...'), + ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), + ('MySQL vs. YourSQL','In the following database to database comparison ...'), + ('MySQL Security','When configured properly, MySQL ...'); + +CREATE TABLE t1 (i INTEGER); +INSERT INTO t1 SELECT FTS_DOC_ID FROM wp; + +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE t1; +SET STATEMENT use_stat_tables=never FOR +ANALYZE TABLE wp; + +--disable_ps2_protocol + +# +# Show results of MATCH expressions for reference +# +SELECT FTS_DOC_ID, title, MATCH(title, text) AGAINST ('database') AS score1, + MATCH(title, text) AGAINST ('mysql') AS score2 +FROM wp; + +# +# Test that filesort is not used if ordering on same match expression +# as where clause +# +--echo No sorting for this query +FLUSH STATUS; + +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score DESC; + +SHOW SESSION STATUS LIKE 'Sort%'; + +--echo No sorting for this query even if MATCH is part of an expression +FLUSH STATUS; + +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') > 0.1 +ORDER BY score DESC; + +SHOW SESSION STATUS LIKE 'Sort%'; + +--echo No sorting even if there are several MATCH expressions as long as the +--echo right one is used in ORDER BY +FLUSH STATUS; + +SELECT title, MATCH(title, text) AGAINST ('database') AS score1, + MATCH(title, text) AGAINST ('mysql') AS score2 +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score1 DESC; + +SHOW SESSION STATUS LIKE 'Sort%'; + +--echo No Sorting since FT table is first table in query +FLUSH STATUS; + +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp, t1 +WHERE MATCH(title, text) AGAINST ('database') AND FTS_DOC_ID = t1.i +ORDER BY score DESC; + +SHOW SESSION STATUS LIKE 'Sort_rows%'; + +--echo Sorting since there is no WHERE clause +FLUSH STATUS; + +--sorted_result +SELECT MATCH(title, text) AGAINST ('database'), title AS score +FROM wp +ORDER BY score DESC; + +SHOW SESSION STATUS LIKE 'Sort_rows%'; + +--echo Sorting since ordering on multiple columns +FLUSH STATUS; + +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score DESC, FTS_DOC_ID; + +SHOW SESSION STATUS LIKE 'Sort_rows%'; + +--echo Sorting since ordering is not descending +FLUSH STATUS; + +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score ASC; + +SHOW SESSION STATUS LIKE 'Sort_rows%'; + +--echo Sorting because one is ordering on a different MATCH expression +FLUSH STATUS; + +SELECT title, MATCH(title, text) AGAINST ('mysql') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score DESC; + +SHOW SESSION STATUS LIKE 'Sort_rows%'; + +# +# Tests for ORDER BY/LIMIT optimzation +# +--echo No sorting for this query +FLUSH STATUS; + +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +ORDER BY score DESC LIMIT 2; + +SHOW SESSION STATUS LIKE 'Sort%'; + +--echo Revert to table scan and sorting for this query since not +--echo enough matching rows to satisfy LIMIT clause +FLUSH STATUS; + +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +ORDER BY score DESC LIMIT 2; + +SHOW SESSION STATUS LIKE 'Handler_read%'; +SHOW SESSION STATUS LIKE 'Sort_rows%'; + +--echo Sorting since no LIMIT clause +FLUSH STATUS; + +--sorted_result +SELECT MATCH(title, text) AGAINST ('database') AS score, title +FROM wp +ORDER BY score DESC; + +SHOW SESSION STATUS LIKE 'Sort_rows%'; + +--echo Sorting since there is a WHERE clause +FLUSH STATUS; + +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE dummy IS NULL +ORDER BY score DESC LIMIT 2; + +SHOW SESSION STATUS LIKE 'Sort_rows%'; + +--echo Sorting since ordering is not on a simple MATCH expressions +FLUSH STATUS; + +SELECT title, (MATCH(title, text) AGAINST ('database')) * 100 AS score +FROM wp +ORDER BY score DESC LIMIT 2; + +SHOW SESSION STATUS LIKE 'Sort_rows%'; + +# +# Test that there is no row accesses if all necessary information is +# available in FTS result +# +--echo No ordinary handler accesses when only accessing FTS_DOC_ID and MATCH +FLUSH STATUS; + +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database'); + +SHOW SESSION STATUS LIKE 'Handler_read%'; + +--echo Still no handler accesses when adding FTS_DOC_ID to WHERE clause +FLUSH STATUS; + +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') AND FTS_DOC_ID > 2; + +SHOW SESSION STATUS LIKE 'Handler_read%'; + +--echo Still no handler accesses when ordering by MATCH expression +FLUSH STATUS; + +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score; + +SHOW SESSION STATUS LIKE 'Handler_read%'; + +--echo Optimization is disabled when ordering on FTS_DOC_ID +FLUSH STATUS; + +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY 1 DESC; + +SHOW SESSION STATUS LIKE 'Handler_read%'; + +--echo Optimization also work with several MATCH expressions +FLUSH STATUS; + +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score1, + MATCH(title, text) AGAINST ('mysql') AS score2 +FROM wp +WHERE MATCH(title, text) AGAINST ('database'); + +SHOW SESSION STATUS LIKE 'Handler_read%'; + +--echo Optimization does not apply if sorting on a different MATCH expressions +--echo from the one used to access the +FLUSH STATUS; + +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score1, + MATCH(title, text) AGAINST ('mysql') AS score2 +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score2 DESC; + +SHOW SESSION STATUS LIKE 'Handler_read%'; + +FLUSH STATUS; + +--echo Optimization does not apply for GROUP BY +SET @save_mode = @@sql_mode; +SET sql_mode = (select replace(@@sql_mode,'ONLY_FULL_GROUP_BY','')); +SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +GROUP BY score; + +SHOW SESSION STATUS LIKE 'Handler_read%'; +SET sql_mode = @save_mode; + +# +# Putting all three optimizations together +# +--echo No sorting and no table access with LIMIT clause and only information +--echo from FTS result +FLUSH STATUS; + +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score +FROM wp +ORDER BY score DESC LIMIT 2; + +SHOW STATUS LIKE 'Handler_read%'; +SHOW SESSION STATUS LIKE 'Sort%'; + +# +# Count optimization +# +let $query = +SELECT COUNT(*) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE); + +--echo If count optimization applies, EXPLAIN shows +--echo "Select tables optimized away." +eval EXPLAIN $query; +FLUSH STATUS; +eval $query; +--echo Verify that there was no table access +SHOW STATUS LIKE 'Handler_read%'; + +let $query = +SELECT COUNT(title) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE); + +--echo Optimization applies also to COUNT(expr) as long as expr is not nullable +eval EXPLAIN $query; +eval $query; + +let $query = +SELECT count(*) +FROM wp, t1 +WHERE MATCH(title, text) AGAINST ('database'); + +--echo Optimization does not apply if not a single table query. +eval EXPLAIN $query; +eval $query; + +let $query = +SELECT COUNT(title) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE) > 0; + +--echo Optimization does not apply if MATCH is part of an expression +eval EXPLAIN $query; +eval $query; + +let $query = +SELECT COUNT(title) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE) > 0; + +--echo Optimization does not apply if MATCH is part of an expression +eval EXPLAIN $query; +eval $query; + +let $query = +SELECT COUNT(dummy) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE); + +--echo Optimization does not apply if COUNT expression is nullable +eval EXPLAIN $query; +eval $query; + +# +# Verify that the queries optimized for InnoDB works with QUERY EXPANSION +# + +# Query will also avoid sorting when query expansion is used +FLUSH STATUS; +--sorted_result +SELECT MATCH(title, text) AGAINST ('database' WITH QUERY EXPANSION) AS score, +title +FROM wp +WHERE MATCH(title, text) AGAINST ('database' WITH QUERY EXPANSION) +ORDER BY score DESC; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check ORDER BY/LIMIT query with no WHERE clause +FLUSH STATUS; +SELECT title, + MATCH(title, text) AGAINST ('database' WITH QUERY EXPANSION) AS score +FROM wp +ORDER BY score DESC LIMIT 2; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check query where FTS result is "covering" +FLUSH STATUS; +SELECT FTS_DOC_ID docid, + MATCH(title, text) AGAINST ('database' WITH QUERY EXPANSION) AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database'); +SHOW SESSION STATUS LIKE 'Handler_read%'; + +# Check the combination of all three +FLUSH STATUS; +SELECT FTS_DOC_ID docid, + MATCH(title, text) AGAINST ('database' WITH QUERY EXPANSION) AS score +FROM wp +ORDER BY score DESC LIMIT 2; +SHOW STATUS LIKE 'Handler_read%'; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check the count optimization +let $query = +SELECT COUNT(*) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' WITH QUERY EXPANSION); +eval EXPLAIN $query; +FLUSH STATUS; +eval $query; +SHOW STATUS LIKE 'Handler_read%'; + +# +# Verify that the queries optimized for InnoDB works with BOOLEAN MODE +# + +# Query will also avoid sorting when Boolean mode is used +FLUSH STATUS; +--sorted_result +SELECT MATCH(title, text) AGAINST ('+MySQL -database' IN BOOLEAN MODE) score, +title +FROM wp +WHERE MATCH(title, text) AGAINST ('+MySQL -database' IN BOOLEAN MODE) +ORDER BY score DESC; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check ORDER BY/LIMIT query with no WHERE clause +FLUSH STATUS; +--sorted_result +SELECT MATCH(title, text) AGAINST ('+MySQL -database' IN BOOLEAN MODE) score, +title +FROM wp +ORDER BY score DESC; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check query where FTS result is "covering" +FLUSH STATUS; +SELECT FTS_DOC_ID docid, + MATCH(title, text) AGAINST ('+MySQL -database' IN BOOLEAN MODE) AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('+MySQL -database'); +SHOW SESSION STATUS LIKE 'Handler_read%'; + +# Check the combination of all three +FLUSH STATUS; +SELECT FTS_DOC_ID docid, + MATCH(title, text) AGAINST ('+MySQL -database' IN BOOLEAN MODE) AS score +FROM wp +ORDER BY score DESC LIMIT 1; +SHOW STATUS LIKE 'Handler_read%'; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check the count optimization +let $query = +SELECT COUNT(*) +FROM wp +WHERE MATCH(title,text) AGAINST ('+MySQL -database' IN BOOLEAN MODE); +eval EXPLAIN $query; +FLUSH STATUS; +eval $query; +SHOW STATUS LIKE 'Handler_read%'; + + +# +# Verify that the queries optimized for InnoDB works with +# BOOLEAN proximity search +# + +# Query will also avoid sorting when Boolean mode is used +FLUSH STATUS; +SELECT title, + MATCH(title, text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE) AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE) +ORDER BY score DESC; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check ORDER BY/LIMIT query with no WHERE clause +FLUSH STATUS; +SELECT title, + MATCH(title, text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE) AS score +FROM wp +ORDER BY score DESC LIMIT 1; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check query where FTS result is "covering" +FLUSH STATUS; +SELECT FTS_DOC_ID docid, + MATCH(title, text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE) AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('"MySQL database"@5'); +SHOW SESSION STATUS LIKE 'Handler_read%'; + +# Check the combination of all three +FLUSH STATUS; +SELECT FTS_DOC_ID docid, + MATCH(title, text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE) AS score +FROM wp +ORDER BY score DESC LIMIT 1; +SHOW STATUS LIKE 'Handler_read%'; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check the count optimization +let $query = +SELECT COUNT(*) +FROM wp +WHERE MATCH(title,text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE); +eval EXPLAIN $query; +FLUSH STATUS; +eval $query; +SHOW STATUS LIKE 'Handler_read%'; + +# +# Check that nothing goes wrong when combining different modes +# +SELECT title, + MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database' WITH QUERY EXPANSION) +ORDER BY score DESC, title ASC; + +SELECT title, + MATCH(title, text) AGAINST ('+MySQL -database' IN BOOLEAN MODE) AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('MySQL database' WITH QUERY EXPANSION) +ORDER BY score DESC, title ASC; + +SELECT title, + MATCH(title, text) AGAINST ('+MySQL -database' IN BOOLEAN MODE) AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('"MySQL database"@5' IN BOOLEAN MODE) +ORDER BY score DESC, title ASC; + + +# +# Verify that the queries optimized for InnoDB still works with MyISAM +# +ALTER TABLE wp ENGINE=myisam; + +# Check avoid sorting query +FLUSH STATUS; +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database') +ORDER BY score DESC; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check ORDER BY/LIMIT query with no WHERE clause +FLUSH STATUS; +SELECT title, MATCH(title, text) AGAINST ('database') AS score +FROM wp +ORDER BY score DESC LIMIT 2; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check query where FTS result is "covering" +FLUSH STATUS; +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score +FROM wp +WHERE MATCH(title, text) AGAINST ('database'); +SHOW SESSION STATUS LIKE 'Handler_read%'; + +# Check the combination of all three +FLUSH STATUS; +SELECT FTS_DOC_ID docid, MATCH(title, text) AGAINST ('database') AS score +FROM wp +ORDER BY score DESC LIMIT 2; +SHOW STATUS LIKE 'Handler_read%'; +SHOW SESSION STATUS LIKE 'Sort%'; + +# Check the count optimization +let $query = +SELECT COUNT(*) +FROM wp +WHERE MATCH(title,text) AGAINST ('database' IN NATURAL LANGUAGE MODE); +eval EXPLAIN $query; +FLUSH STATUS; +eval $query; +SHOW STATUS LIKE 'Handler_read%'; + + +DROP TABLE wp, t1; + +--enable_ps2_protocol + +# Tests for FT hints. + +CREATE TABLE t1 +( + FTS_DOC_ID BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, + title VARCHAR(255) DEFAULT '', + text MEDIUMTEXT , + PRIMARY KEY (FTS_DOC_ID), + UNIQUE KEY FTS_DOC_ID_INDEX (FTS_DOC_ID), + FULLTEXT KEY ft_idx (title,text) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + + +INSERT INTO t1 (title, text) VALUES + ('MySQL Tutorial','DBMS stands for MySQL DataBase ...'), + ('How To Use MySQL Well','After you went through a ...'), + ('Optimizing MySQL','In this tutorial we will show ...'), + ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), + ('MySQL vs. YourSQL database','In the following database to database comparison ...'), + ('MySQL Security','When configured properly, MySQL ...'), + ('InnoDB', 'InnoDB is a transaction-safe (ACID compliant) storage engine'), + ('MySQL is a database management system', 'A database is a structured collection of data...'), + ('MySQL databases are relational', 'A relational database stores data in separate tables rather than putting all the data in one big storeroom...'), + ('MySQL software is Open Source', 'Open Source means that it is possible for anyone to use and modify the software...'), + ('The MySQL Database Server is very fast, reliable, scalable, and easy to use', 'MySQL Server can run comfortably on a desktop or laptop...'), + ('MySQL Server works in client/server or embedded systems', 'The MySQL Database Software is a client/server system...'), + ('MyISAM', 'MyISAM is based on the older (and no longer available) ISAM storage engine but has many useful extensions'), + ('A large amount of contributed MySQL software is available', 'MySQL Server has a practical set of features developed in close cooperation with our users'), + (NULL,NULL); + +-- disable_result_log +ANALYZE TABLE t1; +-- enable_result_log + +--echo # No ranking + +EXPLAIN +SELECT count(*) FROM t1 WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE); +SELECT count(*) FROM t1 WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE); + +# Atm opt_sum_query does not support COUNT optimization if +# ORDER BY is present. TODO: fix it. +EXPLAIN +SELECT count(*) FROM t1 WHERE MATCH (title, text) AGAINST ('data*' IN BOOLEAN MODE) ORDER BY title LIMIT 3; +SELECT count(*) FROM t1 WHERE MATCH (title, text) AGAINST ('data*' IN BOOLEAN MODE) ORDER BY title LIMIT 3; + +EXPLAIN +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('+fast +database' IN BOOLEAN MODE); +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('+fast +database' IN BOOLEAN MODE); + +EXPLAIN +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION); +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION); + +EXPLAIN +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('"very fast"@3' IN BOOLEAN MODE); +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('"very fast"@3' IN BOOLEAN MODE); + +# check case with 'for' stopword +EXPLAIN SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+for' IN BOOLEAN MODE); +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+for' IN BOOLEAN MODE); + + +--echo # No sorting by rank + +EXPLAIN SELECT FTS_DOC_ID, TITLE FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY title; +SELECT FTS_DOC_ID, TITLE FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY title; + +EXPLAIN SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+fast +database' IN BOOLEAN MODE); +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+fast +database' IN BOOLEAN MODE); + +EXPLAIN +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) ORDER BY title; +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) ORDER BY title; + +EXPLAIN +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('"very fast"@3' IN BOOLEAN MODE) ORDER BY title; +SELECT FTS_DOC_ID, title FROM t1 WHERE MATCH(title, text) AGAINST ('"very fast"@3' IN BOOLEAN MODE) ORDER BY title; + +--echo # LIMIT optimization + +EXPLAIN SELECT FTS_DOC_ID, TITLE FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +LIMIT 3; +SELECT FTS_DOC_ID, TITLE FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +LIMIT 3; + +EXPLAIN SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+fast +database' IN BOOLEAN MODE) +LIMIT 3; +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+fast +database' IN BOOLEAN MODE) +LIMIT 3; + +EXPLAIN SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+fast +database' IN BOOLEAN MODE) +ORDER BY title +LIMIT 3; +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+fast +database' IN BOOLEAN MODE) +ORDER BY title +LIMIT 3; + + +EXPLAIN +SELECT FTS_DOC_ID FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) ORDER BY title LIMIT 1; +SELECT FTS_DOC_ID FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) ORDER BY title LIMIT 1; + +EXPLAIN +SELECT FTS_DOC_ID FROM t1 WHERE MATCH(title, text) AGAINST ('"very fast"@3' IN BOOLEAN MODE) ORDER BY title LIMIT 1; +SELECT FTS_DOC_ID FROM t1 WHERE MATCH(title, text) AGAINST ('"very fast"@3' IN BOOLEAN MODE) ORDER BY title LIMIT 1; + +EXPLAIN +SELECT FTS_DOC_ID, MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) as rank +FROM t1 WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY rank, FTS_DOC_ID +LIMIT 3; +SELECT FTS_DOC_ID, MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) as rank +FROM t1 WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY rank, FTS_DOC_ID +LIMIT 3; + +EXPLAIN +SELECT FTS_DOC_ID, MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) as rank +FROM t1 WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY rank DESC, FTS_DOC_ID ASC +LIMIT 3; +SELECT FTS_DOC_ID, MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) as rank +FROM t1 WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY rank DESC, FTS_DOC_ID ASC +LIMIT 3; + +EXPLAIN SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) as rank +FROM t1 +ORDER BY rank DESC +LIMIT 2; +SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) as rank +FROM t1 +ORDER BY rank DESC +LIMIT 2; + +EXPLAIN SELECT FTS_DOC_ID, MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) as rank +FROM t1 +ORDER BY rank DESC +LIMIT 3; +SELECT FTS_DOC_ID, MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) as rank +FROM t1 +ORDER BY rank DESC +LIMIT 3; + +EXPLAIN SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) +ORDER BY MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) DESC, +FTS_DOC_ID ASC; +SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) +ORDER BY MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) DESC, +FTS_DOC_ID ASC; + +EXPLAIN SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) and FTS_DOC_ID > 1 +ORDER BY MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) DESC +LIMIT 2; +SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) and FTS_DOC_ID > 1 +ORDER BY MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) DESC +LIMIT 2; + + +EXPLAIN +SELECT FTS_DOC_ID,MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) +ORDER BY rank +LIMIT 1; +SELECT FTS_DOC_ID,MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) +ORDER BY rank +LIMIT 1; + +EXPLAIN +SELECT FTS_DOC_ID,MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) +ORDER BY rank DESC +LIMIT 1; +SELECT FTS_DOC_ID,MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) +ORDER BY rank DESC +LIMIT 1; + + +EXPLAIN +SELECT FTS_DOC_ID,MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) +ORDER BY MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) +LIMIT 1; +SELECT FTS_DOC_ID,MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) as rank +FROM t1 WHERE MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) +ORDER BY MATCH(title, text) AGAINST ('+very +fast' WITH QUERY EXPANSION) DESC +LIMIT 1; + +--echo # WHERE optimization on MATCH > 'some_rank' + +EXPLAIN SELECT FTS_DOC_ID FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) > 0.1; + +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) > 0.1; + + +--echo # additional test for correct behaviour + +EXPLAIN SELECT * FROM t1 ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC LIMIT 10; + +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) AND +MATCH (title, text) AGAINST ('mysql' IN NATURAL LANGUAGE MODE) +LIMIT 6; + +--echo # test OR condition + +SELECT FTS_DOC_ID +FROM t1 +WHERE MATCH(title, text) AGAINST ('database') + OR MATCH(title, text) AGAINST ('mysql') +ORDER BY MATCH(title, text) AGAINST ('database') DESC, FTS_DOC_ID ASC; + +EXPLAIN SELECT FTS_DOC_ID +FROM t1 +WHERE MATCH(title, text) AGAINST ('database') + OR MATCH(title, text) AGAINST ('mysql') +ORDER BY MATCH(title, text) AGAINST ('database') DESC, FTS_DOC_ID ASC; + +--echo # MATCH and GROUP BY, DISTINCT + +SET sql_mode = (select replace(@@sql_mode,'ONLY_FULL_GROUP_BY','')); + +EXPLAIN SELECT FTS_DOC_ID FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +GROUP BY FTS_DOC_ID +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +GROUP BY FTS_DOC_ID +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; + +EXPLAIN SELECT FTS_DOC_ID FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +GROUP BY title +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; + +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +GROUP BY title +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; + +EXPLAIN SELECT MAX(FTS_DOC_ID) FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; +SELECT MAX(FTS_DOC_ID) FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; + +EXPLAIN SELECT DISTINCT(title) FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; +SELECT DISTINCT(title) FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; + +EXPLAIN SELECT DISTINCT(FTS_DOC_ID) FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; +SELECT DISTINCT(FTS_DOC_ID) FROM t1 +WHERE MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) +ORDER BY MATCH (title, text) AGAINST ('fast database' IN NATURAL LANGUAGE MODE) DESC +LIMIT 3; + +SET sql_mode = @save_mode; + +--echo # FTS index access + +SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) as rank +FROM t1 +ORDER BY rank DESC +LIMIT 2; +EXPLAIN SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) as rank +FROM t1 +ORDER BY rank DESC +LIMIT 2; + +SELECT a.FTS_DOC_ID, b.FTS_DOC_ID +FROM t1 a, t1 b +WHERE MATCH(a.title, a.text) AGAINST ('+database' IN BOOLEAN MODE) and + MATCH(b.title, b.text) AGAINST ('+mysql' IN BOOLEAN MODE) and + a.FTS_DOC_ID = b.FTS_DOC_ID; +EXPLAIN SELECT a.FTS_DOC_ID, b.FTS_DOC_ID +FROM t1 a, t1 b +WHERE MATCH(a.title, a.text) AGAINST ('+database' IN BOOLEAN MODE) and + MATCH(b.title, b.text) AGAINST ('+mysql' IN BOOLEAN MODE) and + a.FTS_DOC_ID = b.FTS_DOC_ID; + +SELECT a.FTS_DOC_ID, MATCH(a.title, a.text) AGAINST ('+database' IN BOOLEAN MODE), + b.FTS_DOC_ID, MATCH(b.title, b.text) AGAINST ('+database' IN BOOLEAN MODE) +FROM t1 a, t1 b +WHERE MATCH(a.title, a.text) AGAINST ('+database' IN BOOLEAN MODE) and + MATCH(b.title, b.text) AGAINST ('+database' IN BOOLEAN MODE); + +EXPLAIN SELECT a.FTS_DOC_ID, MATCH(a.title, a.text) AGAINST ('+database' IN BOOLEAN MODE), + b.FTS_DOC_ID, MATCH(b.title, b.text) AGAINST ('+database' IN BOOLEAN MODE) +FROM t1 a, t1 b +WHERE MATCH(a.title, a.text) AGAINST ('+database' IN BOOLEAN MODE) and + MATCH(b.title, b.text) AGAINST ('+database' IN BOOLEAN MODE); + +# Index only access by non-FTS index + +EXPLAIN SELECT FTS_DOC_ID FROM t1 WHERE MATCH(title, text) AGAINST ("data*" IN BOOLEAN MODE) * 100; +SELECT FTS_DOC_ID, MATCH(title, text) AGAINST ("data*" IN BOOLEAN MODE) * 100 +FROM t1 WHERE MATCH(title, text) AGAINST ("data*" IN BOOLEAN MODE) * 100; +# Run query returning null record +SELECT * FROM t1 WHERE title IS NULL AND text IS NULL; + +# More testing of index only access by non-FTS index + +CREATE TABLE t2 SELECT FTS_DOC_ID as doc_id, title, text FROM t1; +ALTER TABLE t2 ADD PRIMARY KEY (doc_id); +ALTER TABLE t2 ADD FULLTEXT KEY ft_idx (title,text); + +-- disable_result_log +ANALYZE TABLE t2; +-- enable_result_log + +# No index access +EXPLAIN SELECT DOC_ID FROM t2 WHERE MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) * 100; +SELECT DOC_ID FROM t2 WHERE MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) * 100; +# Index access +EXPLAIN SELECT FTS_DOC_ID FROM t1 WHERE MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) * 100; +SELECT FTS_DOC_ID FROM t1 WHERE MATCH(title, text) AGAINST ('+database' IN BOOLEAN MODE) * 100; + +DROP TABLE t1, t2; + +--echo "Check hints with uft8 charset for 2 cases" +set names utf8; +EVAL CREATE TABLE t1 ( + FTS_DOC_ID BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + text TEXT + ) CHARACTER SET = utf8, ENGINE=InnoDB; + +INSERT INTO t1 (title, text) VALUES +('Я могу есть стекло', 'оно мне не вредит'), +('Мога да ям стъкло', 'то не ми вреди'), +('Μπορῶ νὰ φάω σπασμένα' ,'γυαλιὰ χωρὶς νὰ πάθω τίποτα'), +('Příliš žluťoučký kůň', 'úpěl ďábelské kódy'), +('Sævör grét', 'áðan því úlpan var ónýt'), +('うゐのおくやま','けふこえて'), +('いろはにほへど ちりぬる','あさきゆめみじ ゑひもせず'); +CREATE FULLTEXT INDEX idx on t1 (title, text); + +--echo # No ranking + +EXPLAIN +SELECT count(*) FROM t1 WHERE MATCH (title, text) AGAINST ('вредит' IN NATURAL LANGUAGE MODE); +SELECT count(*) FROM t1 WHERE MATCH (title, text) AGAINST ('вредит' IN NATURAL LANGUAGE MODE); + +EXPLAIN +SELECT * FROM t1 WHERE MATCH(title, text) AGAINST ("оно" WITH QUERY EXPANSION); +SELECT * FROM t1 WHERE MATCH(title, text) AGAINST ("оно" WITH QUERY EXPANSION); +--echo # No sorting by rank +EXPLAIN SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+(Мога τίποτα)' IN BOOLEAN MODE); +SELECT FTS_DOC_ID FROM t1 +WHERE MATCH(title, text) AGAINST ('+(Мога τίποτα)' IN BOOLEAN MODE); +DROP TABLE t1; + + +--echo # +--echo # Bug #18924341 CRASH IN TEST_IF_SKIP_SORT_ORDER, GROUP BY MATCH AGAINST DESC +--echo # + +CREATE TABLE t1 (f1 CHAR(1), FULLTEXT KEY (f1)); +SELECT 1 FROM t1 NATURAL JOIN t1 a GROUP BY MATCH(t1.f1) AGAINST ("1") DESC; +DROP TABLE t1; + + +--echo # +--echo # Bug#20261601 ASSERTION FAILED: !FIRST_QEP_TAB->TABLE()->NO_KEYREAD +--echo # + +CREATE TABLE t1(a INT PRIMARY KEY); +INSERT INTO t1 VALUES(1),(2); +--error ER_FT_MATCHING_KEY_NOT_FOUND +SELECT (SELECT MATCH(`a`)AGAINST('1') FROM t1) FROM t1; +SELECT 1, a IN (SELECT a FROM t1) FROM t1; +DROP TABLE t1; + +--echo # +--echo # Bug#20442572 ASSERTION `!FIRST_QEP_TAB->TABLE()->NO_KEYREAD' FAILED. +--echo # Bug#75688 Assertion `!first_qep_tab->table()->no_keyread' failed. +--echo # + +CREATE TABLE t1(a INT,b POINT NOT NULL,KEY(a)); + +HANDLER t1 OPEN; +#--error ER_FT_MATCHING_KEY_NOT_FOUND +select * from t1 where MATCH a,b AGAINST('"Now sUPPort"' IN BOOLEAN MODE); +prepare stmt1 from "truncate t1"; +SELECT a IN(SELECT a FROM t1)FROM t1; + +deallocate prepare stmt1; +DROP TABLE t1; + +--echo # +--echo # Bug #20685427 INVALID WRITE OF FREED MEMORY IN ITEM_FUNC_MATCH::CLEANUP +--echo # + +CREATE TABLE t1(a TEXT CHARSET LATIN1, FULLTEXT KEY(a)) ENGINE=INNODB; +--error ER_FT_MATCHING_KEY_NOT_FOUND +SELECT MATCH(a) AGAINST ('') FROM (SELECT a FROM t1 LIMIT 1) q; +DROP TABLE t1; + +--echo # +--echo # Bug#21140067 EXPLAIN .. MATCH AGAINST: ASSERTION FAILED: TO <= END +--echo # + +CREATE TABLE t1(f1 CHAR(1) CHARSET latin1, FULLTEXT(f1)) ENGINE=INNODB; +EXPLAIN SELECT 1 FROM t1 WHERE 1.238585e+308 <= MATCH(f1) AGAINST ('1' IN BOOLEAN MODE); + +EXPLAIN FORMAT = JSON SELECT 1 FROM t1 WHERE 1.238585e+308 <= MATCH(f1) AGAINST ('1' IN BOOLEAN MODE); + +DROP TABLE t1; + +--echo # +--echo # Bug#21140088 MATCH AGAINST: ASSERTION FAILED: !TABLE || (!TABLE->READ_SET || BITMAP_IS_SET +--echo # + +SET sql_mode=''; +CREATE TABLE t1(a INT) ENGINE=INNODB; +CREATE TABLE t2(b TEXT CHARSET LATIN1, FULLTEXT(b), PRIMARY KEY(b(10))) ENGINE=INNODB; +INSERT INTO t2 VALUES ('a'),('b'); +--error ER_WRONG_ARGUMENTS +SELECT NOT EXISTS (SELECT MATCH(b) AGAINST ('1') FROM t1) FROM t2 GROUP BY "a"; +DROP TABLE t1, t2; + +CREATE TABLE t1(a INT) ENGINE=MyISAM; +CREATE TABLE t2(b TEXT CHARSET LATIN1, FULLTEXT(b), PRIMARY KEY(b(10))) ENGINE=MyISAM; +INSERT INTO t2 VALUES ('a'),('b'); +#--error ER_WRONG_ARGUMENTS +SELECT NOT EXISTS (SELECT MATCH(b) AGAINST ('1' in BOOLEAN MODE) FROM t1) FROM t2 GROUP BY "a"; +DROP TABLE t1, t2; + +SET sql_mode=default; + +--echo # +--echo # Bug#21140039 ASSERTION FAILED: !FIRST_QEP_TAB->TABLE()->NO_KEYREAD MATCH AGAINST..... +--echo # + +CREATE TABLE t1 +( + a INT, + b INT, + c CHAR(1) CHARSET latin1, + PRIMARY KEY (b,a), + FULLTEXT KEY (c) +) ENGINE=INNODB; +SELECT "a" NOT IN(SELECT b FROM t1 WHERE MATCH(c) AGAINST ('a' IN BOOLEAN MODE)); +DROP TABLE t1; + +--echo # +--echo # Bug#21300774 ASSERT `!INIT_FTFUNCS(THD, SELECT_LEX)` IN JOIN::RESET AT SQL/SQL_SELECT.CC:874 +--echo # + +CREATE TABLE t1 (f1 INT); +INSERT INTO t1 VALUES (1); +INSERT INTO t1 VALUES (2); +CREATE TABLE t2 (ft TEXT, FULLTEXT KEY ft(ft)); +INSERT INTO t2 VALUES ('abc'); +INSERT INTO t2 VALUES ('def'); + +--error ER_SUBQUERY_NO_1_ROW +UPDATE t1 SET f1 = +(SELECT t1.f1 FROM t2 WHERE NOT TRUE AND + MATCH (ft) AGAINST ((SELECT 'xyz' FROM t2))); + +DROP TABLE t1, t2; + +--echo # +--echo # Bug#22679209: FULL-TEXT QUERIES WITH ADDITIONAL SECONDARY INDEX +--echo # GIVES NULL OR ZERO ROWS +--echo # + +CREATE TABLE t1 ( +f1 INTEGER, +title varchar(255), +body mediumtext, +KEY f1 (f1), +FULLTEXT KEY title (title), +FULLTEXT KEY body (body) +) ENGINE=InnoDB; + +INSERT INTO t1 VALUES +(1, 'Insert into table', 'insert into table select from'), +(1, 'Delete from table', 'insert into table select from'), +(1, 'Update', 'perform update'), +(2, 'Insert into table', 'insert into table select from'), +( 2, 'Delete from table', 'some body text here'), +( 2, 'Update', 'perform update'), +( 3, 'Insert into table', 'insert into table select from'), +( 3, 'Delete from table', 'some body text here'); + +SELECT f1 FROM t1 WHERE f1=1 AND +(MATCH (title) AGAINST ('table' IN BOOLEAN MODE) OR +MATCH (body) AGAINST ('table' IN BOOLEAN MODE)); + +DROP TABLE t1; + +--echo # End of test for Bug#22679209 diff --git a/mysql-test/suite/innodb_fts/t/phrase.opt b/mysql-test/suite/innodb_fts/t/phrase.opt new file mode 100644 index 00000000000..7724f97647f --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/phrase.opt @@ -0,0 +1,2 @@ +--innodb-ft-index-cache +--innodb-ft-index-table diff --git a/mysql-test/suite/innodb_fts/t/phrase.test b/mysql-test/suite/innodb_fts/t/phrase.test new file mode 100644 index 00000000000..fb0d29f369a --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/phrase.test @@ -0,0 +1,39 @@ +-- source include/have_innodb.inc + +# +# BUG#20465273 - FULLTEXT SEARCH BEHAVIOUR WITH MYISAM VS. INNODB (WRONG RESULT WITH INNODB) +# + +CREATE TABLE articles ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + body TEXT, + FULLTEXT (title,body) +) ENGINE=InnoDB; + +INSERT INTO articles (title,body) VALUES + (NULL, 'mysql good database'), + (NULL, ' mysql good database'), + ('', 'mysql good database'), + ('', ' mysql good database'), + (' ', 'mysql good database'), + ('mysql', 'good database'), + ('mysql ', 'good database'), + ('mysql', ' good database'), + ('mysql good database', ''), + ('mysql good database', NULL); + + +SET GLOBAL innodb_ft_aux_table="test/articles"; +SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE; +SET GLOBAL innodb_ft_aux_table=default; + +SELECT * FROM articles; + +SELECT * FROM articles WHERE MATCH(title, body) + AGAINST('"mysql good database"' IN BOOLEAN MODE); + +SELECT * FROM articles WHERE MATCH(title, body) + AGAINST('("mysql good database")' IN BOOLEAN MODE); + +DROP TABLE articles; diff --git a/mysql-test/suite/innodb_fts/t/result_cache_limit.test b/mysql-test/suite/innodb_fts/t/result_cache_limit.test new file mode 100644 index 00000000000..b19907a5052 --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/result_cache_limit.test @@ -0,0 +1,52 @@ +# This is a basic test for innodb fts result cache limit. + +-- source include/have_innodb.inc + +# Must have debug code to use SET SESSION debug +--source include/have_debug.inc + +# Create FTS table +CREATE TABLE t1 ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + a VARCHAR(200), + b TEXT + ) ENGINE= InnoDB; + +# Create the FTS index again +CREATE FULLTEXT INDEX idx on t1 (a,b); + +# Insert rows +INSERT INTO t1 (a,b) VALUES + ('MySQL from Tutorial','DBMS stands for DataBase ...') , + ('when To Use MySQL Well','After that you went through a ...'), + ('where will Optimizing MySQL','what In this tutorial we will show ...'), + ('MySQL from Tutorial','DBMS stands for DataBase ...') , + ('when To Use MySQL Well','After that you went through a ...'), + ('where will Optimizing MySQL','what In this tutorial we will show ...'), + ('MySQL from Tutorial','DBMS stands for DataBase ...') , + ('when To Use MySQL Well','After that you went through a ...'), + ('where will Optimizing MySQL','what In this tutorial we will show ...'); + +SET @save_limit=@@GLOBAL.innodb_ft_result_cache_limit; +SET @save_dbug=@@debug_dbug; +SET debug_dbug="+d,fts_instrument_result_cache_limit"; + +# Simple term search +SELECT COUNT(*) FROM t1 WHERE MATCH (a,b) AGAINST ('mysql' IN BOOLEAN MODE); + +# Query expansion +--error 128 +SELECT COUNT(*) FROM t1 WHERE MATCH (a,b) AGAINST ('mysql' WITH QUERY EXPANSION); + +# Simple phrase search +--error 128 +SELECT COUNT(*) FROM t1 WHERE MATCH (a,b) AGAINST ('"mysql database"' IN BOOLEAN MODE); + +# Simple proximity search +--error 128 +SELECT COUNT(*) FROM t1 WHERE MATCH (a,b) AGAINST ('"mysql database" @ 5' IN BOOLEAN MODE); + +SET debug_dbug=@save_dbug; + +DROP TABLE t1; +SET GLOBAL innodb_ft_result_cache_limit=@save_limit; diff --git a/mysql-test/suite/innodb_fts/t/savepoint.test b/mysql-test/suite/innodb_fts/t/savepoint.test new file mode 100644 index 00000000000..09ccb383bb9 --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/savepoint.test @@ -0,0 +1,475 @@ +# This is the basic function tests for innodb FTS savepoint + +-- source include/have_innodb.inc + + +CREATE TABLE articles ( + id INT UNSIGNED NOT NULL PRIMARY KEY, + title VARCHAR(200), + FULLTEXT (title) + ) ENGINE= InnoDB; + +# Test Part 1: ROLLBACK TO SAVEPOINT +# Test rollback to savepoint 1(S1,RB1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +ROLLBACK TO SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test rollback to savepoint 2(S1,RB1,S2,RB2) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +ROLLBACK TO SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +ROLLBACK TO SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(6, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(7, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test rollback to savepoint 3(S1,S2,RB1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +ROLLBACK TO SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(6, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test rollback to savepoint 4(S1,S2,RB2,RB1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +ROLLBACK TO SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +ROLLBACK TO SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(6, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(7, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test Part 2: RELEASE SAVEPOINT +# Test release savepoint 1(S1,RL1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +RELEASE SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test release savepoint 2(S1,RL1,S2,RL2) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +RELEASE SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +RELEASE SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(6, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(7, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test release savepoint 3(S1,S2,RL1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +RELEASE SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(6, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test release savepoint 4(S1,S2,RL2,RL1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +RELEASE SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +RELEASE SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(6, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(7, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test Part 3: RELEASE & ROLLBACK TO SAVEPOINT +# Test release & rollback to savepoint 1(S1,RB1,S2,RL2) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +ROLLBACK TO SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +RELEASE SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(6, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(7, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test release & rollback to savepoint 2(S1,RL1,S2,RB2) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +RELEASE SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +ROLLBACK TO SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(6, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(7, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test release & rollback to savepoint 3(S1,S2,RL2,RB1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +RELEASE SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +ROLLBACK TO SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(6, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(7, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test release & rollback to savepoint 4(S1,S2,RB2,RL1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +ROLLBACK TO SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +RELEASE SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(6, 'mysql'); + +COMMIT; + +INSERT INTO articles(id, title) VALUES(7, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test Part 4: ROLLBACK & SAVEPOINT +# Test rollback 1 +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +ROLLBACK; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test rollback 2(S1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +ROLLBACK; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test rollback 3(S1,RL1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +RELEASE SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +ROLLBACK; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test rollback 4(S1,RB1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +ROLLBACK TO SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +ROLLBACK; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +# Test rollback 5(S1,S2,RB2,RL1) +TRUNCATE TABLE articles; + +INSERT INTO articles(id, title) VALUES(1, 'mysql'); + +BEGIN; + +INSERT INTO articles(id, title) VALUES(2, 'mysql'); + +SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(3, 'mysql'); + +SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(4, 'mysql'); + +ROLLBACK TO SAVEPOINT sp2; + +INSERT INTO articles(id, title) VALUES(5, 'mysql'); + +RELEASE SAVEPOINT sp1; + +INSERT INTO articles(id, title) VALUES(6, 'mysql'); + +ROLLBACK; + +INSERT INTO articles(id, title) VALUES(7, 'mysql'); + +SELECT * FROM articles WHERE MATCH(title) AGAINST('mysql'); + +DROP TABLE articles; diff --git a/mysql-test/suite/innodb_fts/t/subexpr.test b/mysql-test/suite/innodb_fts/t/subexpr.test new file mode 100644 index 00000000000..632940661b5 --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/subexpr.test @@ -0,0 +1,58 @@ +--source include/have_innodb.inc + +--echo # +--echo # Bug #20028323 INNODB FULLTEXT BOOLEAN SEARCH INCORRECTLY HANDLES +--echo # PARENTHESES +--echo # + +CREATE TABLE t1 ( + f1 INT NOT NULL AUTO_INCREMENT, + f2 TEXT NOT NULL, + PRIMARY KEY (f1), + FULLTEXT (f2) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +INSERT INTO t1 (f2) VALUES +('Pumpkin soup with cheese bread'), +('Yellow chicken curry'), +('Fresh green vegetables with garlic'); + +SELECT * FROM t1 WHERE MATCH(f2) AGAINST('+pumpkin' IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH(f2) AGAINST('+cheese' IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH(f2) AGAINST('+(pumpkin cheese)' IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH(f2) + AGAINST('+pumpkin +(souffle)' IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH(f2) + AGAINST('+pumpkin +(souffle tart)' IN BOOLEAN MODE); +SELECT * FROM t1 WHERE MATCH(f2) + AGAINST('+pumpkin +(>souffle souffle