From e056efdd6cfa62cc4c978fce5730af0b8d4c3c6b Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Tue, 27 Dec 2022 00:02:02 +0300 Subject: [PATCH] MDEV-25004 Missing row in FTS_DOC_ID_INDEX during DELETE HISTORY 1. In case of system-versioned table add row_end into FTS_DOC_ID index in fts_create_common_tables() and innobase_create_key_defs(). fts_n_uniq() returns 1 or 2 depending on whether the table is system-versioned. After this patch recreate of FTS_DOC_ID index is required for existing system-versioned tables. If you see this message in error log or server warnings: "InnoDB: Table db/t1 contains 2 indexes inside InnoDB, which is different from the number of indexes 1 defined in the MariaDB" use this command to fix the table: ALTER TABLE db.t1 FORCE; 2. Fix duplicate history for secondary unique index like it was done in MDEV-23644 for clustered index (932ec586aad). In case of existing history row which conflicts with currently inseted row we check in row_ins_scan_sec_index_for_duplicate() whether that row was inserted as part of current transaction. In that case we indicate with DB_FOREIGN_DUPLICATE_KEY that new history row is not needed and should be silently skipped. 3. Some parts of MDEV-21138 (7410ff436e9) reverted. Skipping of FTS_DOC_ID index for history rows made problems with purge system. Now this is fixed differently by p.2. 4. wait_all_purged.inc checks that we didn't affect non-history rows so they are deleted and purged correctly. Additional FTS fixes fts_init_get_doc_id(): exclude history rows from max_doc_id calculation. fts_init_get_doc_id() callback is used only for crash recovery. fts_add_doc_by_id(): set max value for row_end field. fts_read_stopword(): stopwords table can be system-versioned too. We now read stopwords only for current data. row_insert_for_mysql(): exclude history rows from doc_id validation. row_merge_read_clustered_index(): exclude history_rows from doc_id processing. fts_load_user_stopword(): for versioned table retrieve row_end field and skip history rows. For non-versioned table we retrieve 'value' field twice (just for uniformity). FTS tests for System Versioning now include maybe_versioning.inc which adds 3 combinations: 'vers' for debug build sets sysvers_force and sysvers_hide. sysvers_force makes every created table system-versioned, sysvers_hide hides WITH SYSTEM VERSIONING for SHOW CREATE. Note: basic.test, stopword.test and versioning.test do not require debug for 'vers' combination. This is controlled by $modify_create_table in maybe_versioning.inc and these tests run WITH SYSTEM VERSIONING explicitly which allows to test 'vers' combination on non-debug builds. 'vers_trx' like 'vers' sets sysvers_force_trx and sysvers_hide. That tests FTS with trx_id-based System Versioning. 'orig' works like before: no System Versioning is added, no debug is required. Upgrade/downgrade test for System Versioning is done by innodb_fts.versioning. It has 2 combinations: 'prepare' makes binaries in std_data (requires old server and OLD_BINDIR). It tests upgrade/downgrade against old server as well. 'upgrade' tests upgrade against binaries in std_data. Cleanups: Removed innodb-fts-stopword.test as it duplicates stopword.test --- mysql-test/include/have_gzip.inc | 6 + .../include/maybe_versioning.combinations | 7 + mysql-test/include/maybe_versioning.inc | 47 ++ .../std_data/versioning/articles.frm.gz | Bin 0 -> 287 bytes .../std_data/versioning/articles2.frm.gz | Bin 0 -> 291 bytes mysql-test/std_data/versioning/ibdata1.gz | Bin 0 -> 51165 bytes .../std_data/versioning/user_stopword.frm.gz | Bin 0 -> 199 bytes mysql-test/suite/innodb_fts/r/basic.result | 6 - .../innodb_fts/r/innodb-fts-stopword.result | 757 ------------------ .../suite/innodb_fts/r/stopword,vers.rdiff | 192 +++++ mysql-test/suite/innodb_fts/r/stopword.result | 12 +- .../innodb_fts/r/versioning,prepare.result | 695 ++++++++++++++++ .../suite/innodb_fts/r/versioning.result | 303 +++++++ mysql-test/suite/innodb_fts/t/basic.inc | 264 ++++++ mysql-test/suite/innodb_fts/t/basic.test | 251 +----- .../suite/innodb_fts/t/crash_recovery.test | 34 + mysql-test/suite/innodb_fts/t/create.test | 1 + mysql-test/suite/innodb_fts/t/fulltext2.test | 1 + mysql-test/suite/innodb_fts/t/fulltext3.test | 1 + .../suite/innodb_fts/t/fulltext_cache.test | 1 + .../suite/innodb_fts/t/fulltext_distinct.test | 1 + .../innodb_fts/t/fulltext_left_join.test | 1 + .../suite/innodb_fts/t/fulltext_multi.test | 1 + .../suite/innodb_fts/t/fulltext_order_by.test | 1 + .../suite/innodb_fts/t/fulltext_update.test | 1 + .../suite/innodb_fts/t/fulltext_var.test | 1 + .../suite/innodb_fts/t/innodb-fts-ddl.test | 1 + .../suite/innodb_fts/t/innodb-fts-fic.test | 1 + .../innodb_fts/t/innodb-fts-stopword.opt | 1 - .../innodb_fts/t/innodb-fts-stopword.test | 664 --------------- .../innodb_fts/t/innodb_ft_aux_table.test | 1 + .../t/innodb_fts_large_records.test | 1 + .../t/innodb_fts_multiple_index.test | 1 + .../innodb_fts/t/innodb_fts_proximity.test | 1 + .../t/innodb_fts_result_cache_limit.test | 1 + .../t/innodb_fts_stopword_charset.test | 1 + .../innodb_fts/t/innodb_fts_transaction.test | 1 + mysql-test/suite/innodb_fts/t/misc_debug.test | 1 + mysql-test/suite/innodb_fts/t/stopword.inc | 55 ++ mysql-test/suite/innodb_fts/t/stopword.test | 100 +-- mysql-test/suite/innodb_fts/t/sync.test | 1 + mysql-test/suite/innodb_fts/t/sync_block.test | 1 + mysql-test/suite/innodb_fts/t/sync_ddl.test | 1 + .../innodb_fts/t/versioning.combinations | 2 + mysql-test/suite/innodb_fts/t/versioning.opt | 2 + mysql-test/suite/innodb_fts/t/versioning.test | 126 +++ mysql-test/suite/versioning/r/alter.result | 5 + mysql-test/suite/versioning/r/debug.result | 4 +- mysql-test/suite/versioning/r/delete.result | 1 - .../suite/versioning/r/delete_history.result | 22 + mysql-test/suite/versioning/r/foreign.result | 37 + mysql-test/suite/versioning/t/alter.test | 2 + .../suite/versioning/t/delete_history.test | 25 + mysql-test/suite/versioning/t/foreign.test | 33 + sql/sql_show.cc | 2 +- storage/innobase/dict/dict0mem.cc | 14 + storage/innobase/fts/fts0fts.cc | 147 +++- storage/innobase/handler/ha_innodb.cc | 48 +- storage/innobase/handler/handler0alter.cc | 32 +- storage/innobase/include/dict0mem.h | 3 + storage/innobase/include/fts0fts.h | 17 +- storage/innobase/include/row0ins.h | 1 - storage/innobase/include/row0upd.h | 16 +- storage/innobase/row/row0ins.cc | 107 ++- storage/innobase/row/row0merge.cc | 33 +- storage/innobase/row/row0mysql.cc | 9 +- storage/innobase/row/row0upd.cc | 13 + 67 files changed, 2269 insertions(+), 1849 deletions(-) create mode 100644 mysql-test/include/have_gzip.inc create mode 100644 mysql-test/include/maybe_versioning.combinations create mode 100644 mysql-test/include/maybe_versioning.inc create mode 100644 mysql-test/std_data/versioning/articles.frm.gz create mode 100644 mysql-test/std_data/versioning/articles2.frm.gz create mode 100644 mysql-test/std_data/versioning/ibdata1.gz create mode 100644 mysql-test/std_data/versioning/user_stopword.frm.gz delete mode 100644 mysql-test/suite/innodb_fts/r/innodb-fts-stopword.result create mode 100644 mysql-test/suite/innodb_fts/r/stopword,vers.rdiff create mode 100644 mysql-test/suite/innodb_fts/r/versioning,prepare.result create mode 100644 mysql-test/suite/innodb_fts/r/versioning.result create mode 100644 mysql-test/suite/innodb_fts/t/basic.inc delete mode 100644 mysql-test/suite/innodb_fts/t/innodb-fts-stopword.opt delete mode 100644 mysql-test/suite/innodb_fts/t/innodb-fts-stopword.test create mode 100644 mysql-test/suite/innodb_fts/t/stopword.inc create mode 100644 mysql-test/suite/innodb_fts/t/versioning.combinations create mode 100644 mysql-test/suite/innodb_fts/t/versioning.opt create mode 100644 mysql-test/suite/innodb_fts/t/versioning.test diff --git a/mysql-test/include/have_gzip.inc b/mysql-test/include/have_gzip.inc new file mode 100644 index 00000000000..09f282b73de --- /dev/null +++ b/mysql-test/include/have_gzip.inc @@ -0,0 +1,6 @@ +--error 0,1,127 +--exec gzip --version > /dev/null 2> /dev/null +if ($sys_errno) +{ + --skip Requires gzip executable +} diff --git a/mysql-test/include/maybe_versioning.combinations b/mysql-test/include/maybe_versioning.combinations new file mode 100644 index 00000000000..246ad30ce7e --- /dev/null +++ b/mysql-test/include/maybe_versioning.combinations @@ -0,0 +1,7 @@ +[orig] + +[vers] +system_versioning_alter_history=keep + +[vers_trx] +system_versioning_alter_history=keep diff --git a/mysql-test/include/maybe_versioning.inc b/mysql-test/include/maybe_versioning.inc new file mode 100644 index 00000000000..8a7d7dad44f --- /dev/null +++ b/mysql-test/include/maybe_versioning.inc @@ -0,0 +1,47 @@ +# include file for test files that can be run with and without debug +# having debug and non-debug tests. + +# If $modify_create_table is true CREATE statement must be evaluated with +# $create_options that adds WITH SYSTEM VERSIONING to the statement. Otherwise +# system versioning is added implicitly via debug options. The second variant +# can easily be added to any test but works only for debug builds. + +if ($modify_create_table) +{ + if ($MTR_COMBINATION_VERS) + { + let $create_options= `select ' WITH SYSTEM VERSIONING'`; + } + + if ($MTR_COMBINATION_VERS_TRX) + { + --skip Not tested + } +} + +if (!$modify_create_table) +{ + let $have_debug=`select version() like '%debug%'`; + + if ($MTR_COMBINATION_VERS) + { + if (!$have_debug) + { + --skip Requires debug + } + --disable_query_log + set debug_dbug="d,sysvers_force_trx,sysvers_hide"; + --enable_query_log + } + + if ($MTR_COMBINATION_VERS_TRX) + { + if (!$have_debug) + { + --skip Requires debug + } + --disable_query_log + set debug_dbug="d,sysvers_force,sysvers_hide"; + --enable_query_log + } +} diff --git a/mysql-test/std_data/versioning/articles.frm.gz b/mysql-test/std_data/versioning/articles.frm.gz new file mode 100644 index 0000000000000000000000000000000000000000..fd3a0a8c0d4bb79cb9084b872f25649f51b36b45 GIT binary patch literal 287 zcmV+)0pR{0iwFo0`&(lI17UJ>X=7|XtOib25 ziiw2*te%^J2}m+F07)sJ3f6`P3=CZi>D&zTpVepJW2`(1E zAO;Ibab`U4S=Vz>#a7Jxud5i0NiN#K8G l3bZyz%1^2MUzA@SUtE${R03wD=B4~+003?WMN`rS006iX=7|Ja&ydW($Z&~`f#DJJGX^+d z@?hX(U|C#8wlgvaz*Pxse_P=lc0=%OgG0$NYrmgKEG*0nEDVhxeN0T& zK#GZlfq@Um<7Qw2l8g;NQVOVowc!B+Ll+x6!%BveU>T+cpbHopPB1VxoCliQ!pQJH zAjs3#F(~qXW=h3>hEXsIM!{eNBPDOLF?iS25?yqWc`5%NHN?5RSQ6tAWYx^k^rzO p_+OG)l9T#BDLeOkXf!VR+md~D>I-6cQvYtv~ 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

C2)~{vK2P!}8B_X5Z<3 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 yN&qE*5Ja%aF*x$RNYSz#zb& z#{dUR91NTc46Gm~2TV)=h(ES7f@!G8_LqjNVK)TdHaL_Vv-bO$#KOYJz{JqV%)rF7 z9%d55f4F)Ci#Wi>;F*_~@8SgEU7#e_> z9};a+42ld4T_BdAB2+*FN#K83Voqu5|Dycz_~Mepq7pDGH815q0{{gFMB*F*0085C BR?Pqa literal 0 HcmV?d00001 diff --git a/mysql-test/suite/innodb_fts/r/basic.result b/mysql-test/suite/innodb_fts/r/basic.result index a98de60674a..a8ab0c043e4 100644 --- a/mysql-test/suite/innodb_fts/r/basic.result +++ b/mysql-test/suite/innodb_fts/r/basic.result @@ -5,12 +5,6 @@ body TEXT, FULLTEXT (title,body) ) ENGINE=InnoDB; ERROR HY000: Cannot create FULLTEXT index on temporary InnoDB table -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 ...'), diff --git a/mysql-test/suite/innodb_fts/r/innodb-fts-stopword.result b/mysql-test/suite/innodb_fts/r/innodb-fts-stopword.result deleted file mode 100644 index 8cc3cbe5ae3..00000000000 --- a/mysql-test/suite/innodb_fts/r/innodb-fts-stopword.result +++ /dev/null @@ -1,757 +0,0 @@ -select * from information_schema.innodb_ft_default_stopword; -value -a -about -an -are -as -at -be -by -com -de -en -for -from -how -i -in -is -it -la -of -on -or -that -the -this -to -was -what -when -where -who -will -with -und -the -www -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 ...'); -SELECT * FROM articles WHERE MATCH (title,body) -AGAINST ('the' IN NATURAL LANGUAGE MODE); -id title body -select @@innodb_ft_server_stopword_table; -@@innodb_ft_server_stopword_table -NULL -select @@innodb_ft_enable_stopword; -@@innodb_ft_enable_stopword -1 -select @@innodb_ft_user_stopword_table; -@@innodb_ft_user_stopword_table -NULL -set global innodb_ft_server_stopword_table = "not_defined"; -ERROR 42000: Variable 'innodb_ft_server_stopword_table' can't be set to the value of 'not_defined' -create table user_stopword(value varchar(30)) engine = innodb; -set global innodb_ft_server_stopword_table = "test/user_stopword"; -drop index title on articles; -create fulltext index idx on articles(title, body); -SELECT * FROM articles WHERE MATCH (title,body) -AGAINST ('the' IN NATURAL LANGUAGE MODE); -id title body -5 MySQL vs. YourSQL In the following database comparison ... -CREATE TABLE articles_2 ( -id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, -title VARCHAR(200), -body TEXT, -FULLTEXT (title,body) -) ENGINE=InnoDB; -INSERT INTO articles_2 (title, body) -VALUES ('test for stopwords','this is it...'); -SELECT * FROM articles_2 WHERE MATCH (title,body) -AGAINST ('this' IN NATURAL LANGUAGE MODE); -id title body -1 test for stopwords this is it... -insert into user_stopword values("this"); -CREATE TABLE articles_3 ( -id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, -title VARCHAR(200), -body TEXT, -FULLTEXT (title,body) -) ENGINE=InnoDB; -INSERT INTO articles_3 (title, body) -VALUES ('test for stopwords','this is it...'); -SELECT * FROM articles_3 WHERE MATCH (title,body) -AGAINST ('this' IN NATURAL LANGUAGE MODE); -id title body -create table user_stopword_session(value varchar(30)) engine = innodb; -insert into user_stopword_session values("session"); -set session innodb_ft_user_stopword_table="test/user_stopword_session"; -CREATE TABLE articles_4 ( -id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, -title VARCHAR(200), -body TEXT, -FULLTEXT (title,body) -) ENGINE=InnoDB; -INSERT INTO articles_4 (title, body) -VALUES ('test for session stopwords','this should also be excluded...'); -SELECT * FROM articles_4 WHERE MATCH (title,body) -AGAINST ('session' IN NATURAL LANGUAGE MODE); -id title body -SELECT * FROM articles_4 WHERE MATCH (title,body) -AGAINST ('this' IN NATURAL LANGUAGE MODE); -id title body -1 test for session stopwords this should also be excluded... -connect con1,localhost,root,,; -CREATE TABLE articles_5 ( -id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, -title VARCHAR(200), -body TEXT, -FULLTEXT (title,body) -) ENGINE=InnoDB; -INSERT INTO articles_5 (title, body) -VALUES ('test for session stopwords','this should also be excluded...'); -SELECT * FROM articles_5 WHERE MATCH (title,body) -AGAINST ('session' IN NATURAL LANGUAGE MODE); -id title body -1 test for session stopwords this should also be excluded... -connection default; -drop table articles; -drop table articles_2; -drop table articles_3; -drop table articles_4; -drop table articles_5; -drop table user_stopword; -drop table user_stopword_session; -SET GLOBAL innodb_ft_enable_stopword=1; -SET GLOBAL innodb_ft_server_stopword_table=default; -CREATE TABLE articles ( -id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, -title VARCHAR(200), -body TEXT, -FULLTEXT `idx` (title,body) -) ENGINE=InnoDB; -SHOW CREATE TABLE articles; -Table Create Table -articles CREATE TABLE `articles` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `title` varchar(200) DEFAULT NULL, - `body` text DEFAULT NULL, - PRIMARY KEY (`id`), - FULLTEXT KEY `idx` (`title`,`body`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci -INSERT INTO articles (title,body) VALUES -('MySQL from Tutorial','DBMS stands for DataBase ...') , -('when To Use MySQL Well','After that you went through a ...'), -('where will Optimizing MySQL','In what 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 ...'); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will"); -id title body -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when"); -id title body -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION); -id title body -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE); -id title body -INSERT INTO articles(title,body) values ('the record will' , 'not index the , will words'); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"the will"@11' IN BOOLEAN MODE); -id title body -UPDATE articles SET title = "update the record" , body = 'to see will is indexed or not' -WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE); -UPDATE articles SET title = "update the record" , body = 'to see will is indexed or not' -WHERE id = 7; -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will'); -id title body -DELETE FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE); -SELECT * FROM articles WHERE id = 7; -id title body -7 update the record to see will is indexed or not -DELETE FROM articles WHERE id = 7; -SET SESSION innodb_ft_enable_stopword = 0; -select @@innodb_ft_enable_stopword; -@@innodb_ft_enable_stopword -0 -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will"); -id title body -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when"); -id title body -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION); -id title body -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE); -id title body -INSERT INTO articles(title,body) values ('the record will' , 'not index the , will words'); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"the will"@11' IN BOOLEAN MODE); -id title body -UPDATE articles SET title = "update the record" , body = 'to see will is indexed or not' -WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE); -UPDATE articles SET title = "update the record" , body = 'to see will is indexed or not' -WHERE id = 8; -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will'); -id title body -SELECT * FROM articles WHERE id = 8; -id title body -8 update the record to see will is indexed or not -DELETE FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE); -SELECT * FROM articles WHERE id = 8; -id title body -8 update the record to see will is indexed or not -DELETE FROM articles WHERE id = 8; -ALTER TABLE articles DROP INDEX idx; -SHOW CREATE TABLE articles; -Table Create Table -articles CREATE TABLE `articles` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `title` varchar(200) DEFAULT NULL, - `body` text DEFAULT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci -ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body); -ANALYZE TABLE articles; -Table Op Msg_type Msg_text -test.articles analyze status OK -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will"); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when"); -id title body -2 when To Use MySQL Well After that you went through a ... -6 MySQL Security When configured properly, MySQL ... -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -1 MySQL from Tutorial DBMS stands for DataBase ... -6 MySQL Security When configured properly, MySQL ... -2 when To Use MySQL Well After that you went through a ... -4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... -5 MySQL vs. YourSQL In the following database comparison ... -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE); -id title body -2 when To Use MySQL Well After that you went through a ... -3 where will Optimizing MySQL In what tutorial we will show ... -6 MySQL Security When configured properly, MySQL ... -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE); -id title body -1 MySQL from Tutorial DBMS stands for DataBase ... -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -INSERT INTO articles(title,body) values ('the record will' , 'not index the , will words'); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE); -id title body -9 the record will not index the , will words -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"the will"@11' IN BOOLEAN MODE); -id title body -9 the record will not index the , will words -UPDATE articles SET title = "update the record" , body = 'to see will is indexed or not' -WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE); -SELECT COUNT(*),max(id) FROM articles; -COUNT(*) max(id) -7 9 -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE); -id title body -9 update the record to see will is indexed or not -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will'); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -9 update the record to see will is indexed or not -DELETE FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE); -SELECT * FROM articles WHERE id = 9; -id title body -DROP TABLE articles; -SET SESSION innodb_ft_enable_stopword=1; -SET GLOBAL innodb_ft_server_stopword_table=default; -SET SESSION innodb_ft_user_stopword_table=default; -select @@innodb_ft_server_stopword_table; -@@innodb_ft_server_stopword_table -NULL -select @@innodb_ft_enable_stopword; -@@innodb_ft_enable_stopword -1 -select @@innodb_ft_user_stopword_table; -@@innodb_ft_user_stopword_table -NULL -CREATE TABLE articles ( -id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, -title VARCHAR(200), -body TEXT, -FULLTEXT `idx` (title,body) -) ENGINE=InnoDB; -INSERT INTO articles (title,body) VALUES -('MySQL from Tutorial','DBMS stands for DataBase ...') , -('when To Use MySQL Well','After that you went through a ...'), -('where will Optimizing MySQL','In what 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 ...'); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will'); -id title body -create table user_stopword(value varchar(30)) engine = innodb; -set session innodb_ft_user_stopword_table = "test/user_stopword"; -create table server_stopword(value varchar(30)) engine = innodb; -set global innodb_ft_server_stopword_table = "test/server_stopword"; -insert into user_stopword values("this"),("will"),("the"); -ALTER TABLE articles DROP INDEX idx; -ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will'); -id title body -insert into server_stopword values("what"),("where"); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what'); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -DELETE FROM user_stopword; -ALTER TABLE articles DROP INDEX idx; -ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what'); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will'); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -insert into user_stopword values("this"),("will"),("the"); -ALTER TABLE articles DROP INDEX idx; -SET SESSION innodb_ft_enable_stopword = 0; -ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what'); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will'); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -SET SESSION innodb_ft_enable_stopword = 1; -ALTER TABLE articles DROP INDEX idx; -ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what'); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will'); -id title body -SET SESSION innodb_ft_enable_stopword = 1; -SET SESSION innodb_ft_user_stopword_table = default; -ALTER TABLE articles DROP INDEX idx; -ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what'); -id title body -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will'); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -DROP TABLE articles,user_stopword,server_stopword; -SET SESSION innodb_ft_enable_stopword=1; -SET GLOBAL innodb_ft_server_stopword_table=default; -SET SESSION innodb_ft_user_stopword_table=default; -select @@innodb_ft_server_stopword_table; -@@innodb_ft_server_stopword_table -NULL -select @@innodb_ft_enable_stopword; -@@innodb_ft_enable_stopword -1 -select @@innodb_ft_user_stopword_table; -@@innodb_ft_user_stopword_table -NULL -CREATE TABLE articles ( -id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, -title VARCHAR(200), -body TEXT, -FULLTEXT `idx` (title,body) -) ENGINE=InnoDB; -SHOW CREATE TABLE articles; -Table Create Table -articles CREATE TABLE `articles` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `title` varchar(200) DEFAULT NULL, - `body` text DEFAULT NULL, - PRIMARY KEY (`id`), - FULLTEXT KEY `idx` (`title`,`body`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci -INSERT INTO articles (title,body) VALUES -('MySQL from Tutorial','DBMS stands for DataBase ...') , -('when To Use MySQL Well','After that you went through a ...'), -('where will Optimizing MySQL','In what 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 ...'); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will'); -id title body -create table user_stopword(value varchar(30)) engine = innodb; -set session innodb_ft_user_stopword_table = "test/user_stopword"; -insert into user_stopword values("mysqld"),("DBMS"); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what'); -id title body -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+DBMS +mysql" IN BOOLEAN MODE); -id title body -1 MySQL from Tutorial DBMS stands for DataBase ... -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('mysqld'); -id title body -4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... -ALTER TABLE articles DROP INDEX idx; -ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what'); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+DBMS +mysql" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('mysqld'); -id title body -set session innodb_ft_user_stopword_table = default; -create table server_stopword(value varchar(30)) engine = innodb; -set global innodb_ft_server_stopword_table = "test/server_stopword"; -insert into server_stopword values("root"),("properly"); -ALTER TABLE articles DROP INDEX idx; -ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what'); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+root +mysql" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('properly'); -id title body -set session innodb_ft_user_stopword_table = "test/user_stopword"; -set global innodb_ft_server_stopword_table = "test/server_stopword"; -ALTER TABLE articles DROP INDEX idx; -ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what'); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+root +mysql" IN BOOLEAN MODE); -id title body -4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('properly'); -id title body -6 MySQL Security When configured properly, MySQL ... -set session innodb_ft_user_stopword_table = "test/user_stopword"; -DELETE FROM user_stopword; -set global innodb_ft_server_stopword_table = "test/server_stopword"; -DELETE FROM server_stopword; -ALTER TABLE articles DROP INDEX idx; -ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what'); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+root +mysql" IN BOOLEAN MODE); -id title body -4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('properly'); -id title body -6 MySQL Security When configured properly, MySQL ... -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+DBMS +mysql" IN BOOLEAN MODE); -id title body -1 MySQL from Tutorial DBMS stands for DataBase ... -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('mysqld'); -id title body -4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... -DROP TABLE articles,user_stopword,server_stopword; -SET SESSION innodb_ft_enable_stopword=1; -SET GLOBAL innodb_ft_server_stopword_table=default; -SET SESSION innodb_ft_user_stopword_table=default; -CREATE TABLE articles ( -id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, -title VARCHAR(200), -body TEXT, -FULLTEXT `idx` (title,body) -) ENGINE=InnoDB; -SHOW CREATE TABLE articles; -Table Create Table -articles CREATE TABLE `articles` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `title` varchar(200) DEFAULT NULL, - `body` text DEFAULT NULL, - PRIMARY KEY (`id`), - FULLTEXT KEY `idx` (`title`,`body`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci -INSERT INTO articles (title,body) VALUES -('MySQL from Tutorial','DBMS stands for DataBase ...') , -('when To Use MySQL Well','After that you went through a ...'), -('where will Optimizing MySQL','In what 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 SESSION innodb_ft_enable_stopword = 0; -select @@innodb_ft_enable_stopword; -@@innodb_ft_enable_stopword -0 -ALTER TABLE articles DROP INDEX idx; -ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body); -connection con1; -select @@innodb_ft_enable_stopword; -@@innodb_ft_enable_stopword -1 -ANALYZE TABLE articles; -Table Op Msg_type Msg_text -test.articles analyze status OK -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will"); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when"); -id title body -2 when To Use MySQL Well After that you went through a ... -6 MySQL Security When configured properly, MySQL ... -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -1 MySQL from Tutorial DBMS stands for DataBase ... -6 MySQL Security When configured properly, MySQL ... -2 when To Use MySQL Well After that you went through a ... -4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... -5 MySQL vs. YourSQL In the following database comparison ... -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE); -id title body -2 when To Use MySQL Well After that you went through a ... -3 where will Optimizing MySQL In what tutorial we will show ... -6 MySQL Security When configured properly, MySQL ... -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE); -id title body -1 MySQL from Tutorial DBMS stands for DataBase ... -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -SET SESSION innodb_ft_enable_stopword = 1; -select @@innodb_ft_enable_stopword; -@@innodb_ft_enable_stopword -1 -ALTER TABLE articles DROP INDEX idx; -ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will"); -id title body -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when"); -id title body -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION); -id title body -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE); -id title body -connection default; -select @@innodb_ft_enable_stopword; -@@innodb_ft_enable_stopword -0 -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will"); -id title body -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when"); -id title body -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION); -id title body -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE); -id title body -INSERT INTO articles(title,body) values ('the record will' , 'not index the , will words'); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"the will"@11' IN BOOLEAN MODE); -id title body -SET SESSION innodb_ft_enable_stopword = 1; -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"the will"@11' IN BOOLEAN MODE); -id title body -connection con1; -SET SESSION innodb_ft_enable_stopword = 1; -create table user_stopword(value varchar(30)) engine = innodb; -set session innodb_ft_user_stopword_table = "test/user_stopword"; -insert into user_stopword values("this"),("will"),("the"); -ALTER TABLE articles DROP INDEX idx; -ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will'); -id title body -connection default; -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will'); -id title body -select @@innodb_ft_user_stopword_table; -@@innodb_ft_user_stopword_table -NULL -create table user_stopword_1(value varchar(30)) engine = innodb; -set session innodb_ft_user_stopword_table = "test/user_stopword_1"; -insert into user_stopword_1 values("when"); -SET SESSION innodb_ft_enable_stopword = 1; -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+when" IN BOOLEAN MODE); -id title body -2 when To Use MySQL Well After that you went through a ... -6 MySQL Security When configured properly, MySQL ... -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('when'); -id title body -2 when To Use MySQL Well After that you went through a ... -6 MySQL Security When configured properly, MySQL ... -ALTER TABLE articles DROP INDEX idx; -ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+when" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('when'); -id title body -connection con1; -SET SESSION innodb_ft_enable_stopword = 1; -SET SESSION innodb_ft_user_stopword_table=default; -select @@innodb_ft_user_stopword_table; -@@innodb_ft_user_stopword_table -NULL -select @@innodb_ft_server_stopword_table; -@@innodb_ft_server_stopword_table -NULL -create table server_stopword(value varchar(30)) engine = innodb; -SET GLOBAL innodb_ft_server_stopword_table = "test/server_stopword"; -select @@innodb_ft_server_stopword_table; -@@innodb_ft_server_stopword_table -test/server_stopword -insert into server_stopword values("when"),("the"); -ALTER TABLE articles DROP INDEX idx; -ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+when" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('the'); -id title body -disconnect con1; -connection default; -SET SESSION innodb_ft_enable_stopword = 1; -SET SESSION innodb_ft_user_stopword_table=default; -select @@innodb_ft_server_stopword_table; -@@innodb_ft_server_stopword_table -test/server_stopword -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+will +where" IN BOOLEAN MODE); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('where'); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -insert into server_stopword values("where"),("will"); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+will +where" IN BOOLEAN MODE); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('where'); -id title body -3 where will Optimizing MySQL In what tutorial we will show ... -ALTER TABLE articles DROP INDEX idx; -ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+when" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('the'); -id title body -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+will +where" IN BOOLEAN MODE); -id title body -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('where'); -id title body -DROP TABLE articles,user_stopword,user_stopword_1,server_stopword; -SET SESSION innodb_ft_enable_stopword=1; -SET GLOBAL innodb_ft_server_stopword_table=default; -SET SESSION innodb_ft_user_stopword_table=default; diff --git a/mysql-test/suite/innodb_fts/r/stopword,vers.rdiff b/mysql-test/suite/innodb_fts/r/stopword,vers.rdiff new file mode 100644 index 00000000000..7405c47c41d --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/stopword,vers.rdiff @@ -0,0 +1,192 @@ +--- stopword.result ++++ stopword,vers.reject +@@ -46,7 +46,7 @@ + title VARCHAR(200), + body TEXT, + FULLTEXT (title,body) +-) ENGINE=InnoDB; ++) WITH SYSTEM VERSIONING ENGINE=InnoDB; + INSERT INTO articles (title,body) VALUES + ('MySQL Tutorial','DBMS stands for DataBase ...') , + ('How To Use MySQL Well','After you went through a ...'), +@@ -60,7 +60,7 @@ + set global innodb_ft_server_stopword_table = "not_defined"; + ERROR 42000: Variable 'innodb_ft_server_stopword_table' can't be set to the value of 'not_defined' + set global innodb_ft_server_stopword_table = NULL; +-create table user_stopword(value varchar(30)) engine = innodb; ++create table user_stopword(value varchar(30)) WITH SYSTEM VERSIONING engine = innodb; + set global innodb_ft_server_stopword_table = "test/user_stopword"; + drop index title on articles; + create fulltext index idx on articles(title, body); +@@ -73,7 +73,7 @@ + title VARCHAR(200), + body TEXT, + FULLTEXT (title,body) +-) ENGINE=InnoDB; ++) WITH SYSTEM VERSIONING ENGINE=InnoDB; + INSERT INTO articles_2 (title, body) + VALUES ('test for stopwords','this is it...'); + SELECT * FROM articles_2 WHERE MATCH (title,body) +@@ -88,13 +88,13 @@ + title VARCHAR(200), + body TEXT, + FULLTEXT (title,body) +-) ENGINE=InnoDB; ++) WITH SYSTEM VERSIONING ENGINE=InnoDB; + INSERT INTO articles_3 (title, body) + VALUES ('test for stopwords','this is it...'); + SELECT * FROM articles_3 WHERE MATCH (title,body) + AGAINST ('this' IN NATURAL LANGUAGE MODE); + id title body +-create table user_stopword_session(value varchar(30)) engine = innodb; ++create table user_stopword_session(value varchar(30)) WITH SYSTEM VERSIONING engine = innodb; + insert into user_stopword values("this"); + delete from user_stopword; + insert into user_stopword_session values("session"); +@@ -104,7 +104,7 @@ + title VARCHAR(200), + body TEXT, + FULLTEXT (title,body) +-) ENGINE=InnoDB; ++) WITH SYSTEM VERSIONING ENGINE=InnoDB; + INSERT INTO articles_4 (title, body) + VALUES ('test for session stopwords','this should also be excluded...'); + SELECT * FROM articles_4 WHERE MATCH (title,body) +@@ -120,7 +120,7 @@ + title VARCHAR(200), + body TEXT, + FULLTEXT (title,body) +-) ENGINE=InnoDB; ++) WITH SYSTEM VERSIONING ENGINE=InnoDB; + INSERT INTO articles_5 (title, body) + VALUES ('test for session stopwords','this should also be excluded...'); + SELECT * FROM articles_5 WHERE MATCH (title,body) +@@ -142,7 +142,7 @@ + title VARCHAR(200), + body TEXT, + FULLTEXT `idx` (title,body) +-) ENGINE=InnoDB; ++) WITH SYSTEM VERSIONING ENGINE=InnoDB; + SHOW CREATE TABLE articles; + Table Create Table + articles CREATE TABLE `articles` ( +@@ -151,7 +151,7 @@ + `body` text DEFAULT NULL, + PRIMARY KEY (`id`), + FULLTEXT KEY `idx` (`title`,`body`) +-) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ++) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING + INSERT INTO articles (title,body) VALUES + ('MySQL from Tutorial','DBMS stands for DataBase ...') , + ('when To Use MySQL Well','After that you went through a ...'), +@@ -248,7 +248,7 @@ + `title` varchar(200) DEFAULT NULL, + `body` text DEFAULT NULL, + PRIMARY KEY (`id`) +-) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ++) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING + ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body); + ANALYZE TABLE articles; + Table Op Msg_type Msg_text +@@ -320,7 +320,7 @@ + title VARCHAR(200), + body TEXT, + FULLTEXT `idx` (title,body) +-) ENGINE=InnoDB; ++) WITH SYSTEM VERSIONING ENGINE=InnoDB; + INSERT INTO articles (title,body) VALUES + ('MySQL from Tutorial','DBMS stands for DataBase ...') , + ('when To Use MySQL Well','After that you went through a ...'), +@@ -332,9 +332,9 @@ + id title body + SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will'); + id title body +-create table user_stopword(value varchar(30)) engine = innodb; ++create table user_stopword(value varchar(30)) WITH SYSTEM VERSIONING engine = innodb; + set session innodb_ft_user_stopword_table = "test/user_stopword"; +-create table server_stopword(value varchar(30)) engine = innodb; ++create table server_stopword(value varchar(30)) WITH SYSTEM VERSIONING engine = innodb; + set global innodb_ft_server_stopword_table = "test/server_stopword"; + insert into user_stopword values("when"),("where"); + delete from user_stopword; +@@ -419,7 +419,7 @@ + title VARCHAR(200), + body TEXT, + FULLTEXT `idx` (title,body) +-) ENGINE=InnoDB; ++) WITH SYSTEM VERSIONING ENGINE=InnoDB; + SHOW CREATE TABLE articles; + Table Create Table + articles CREATE TABLE `articles` ( +@@ -428,7 +428,7 @@ + `body` text DEFAULT NULL, + PRIMARY KEY (`id`), + FULLTEXT KEY `idx` (`title`,`body`) +-) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ++) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING + INSERT INTO articles (title,body) VALUES + ('MySQL from Tutorial','DBMS stands for DataBase ...') , + ('when To Use MySQL Well','After that you went through a ...'), +@@ -440,7 +440,7 @@ + id title body + SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will'); + id title body +-create table user_stopword(value varchar(30)) engine = innodb; ++create table user_stopword(value varchar(30)) WITH SYSTEM VERSIONING engine = innodb; + set session innodb_ft_user_stopword_table = "test/user_stopword"; + insert into user_stopword values("mysqld"),("DBMS"); + SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE); +@@ -466,7 +466,7 @@ + SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('mysqld'); + id title body + set session innodb_ft_user_stopword_table = default; +-create table server_stopword(value varchar(30)) engine = innodb; ++create table server_stopword(value varchar(30)) WITH SYSTEM VERSIONING engine = innodb; + set global innodb_ft_server_stopword_table = "test/server_stopword"; + insert into server_stopword values("root"),("properly"); + ALTER TABLE articles DROP INDEX idx; +@@ -530,7 +530,7 @@ + title VARCHAR(200), + body TEXT, + FULLTEXT `idx` (title,body) +-) ENGINE=InnoDB; ++) WITH SYSTEM VERSIONING ENGINE=InnoDB; + SHOW CREATE TABLE articles; + Table Create Table + articles CREATE TABLE `articles` ( +@@ -539,7 +539,7 @@ + `body` text DEFAULT NULL, + PRIMARY KEY (`id`), + FULLTEXT KEY `idx` (`title`,`body`) +-) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ++) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING + INSERT INTO articles (title,body) VALUES + ('MySQL from Tutorial','DBMS stands for DataBase ...') , + ('when To Use MySQL Well','After that you went through a ...'), +@@ -656,7 +656,7 @@ + "In connection 1" + connection con1; + SET SESSION innodb_ft_enable_stopword = 1; +-create table user_stopword(value varchar(30)) engine = innodb; ++create table user_stopword(value varchar(30)) WITH SYSTEM VERSIONING engine = innodb; + set session innodb_ft_user_stopword_table = "test/user_stopword"; + insert into user_stopword values("this"),("will"),("the"); + ALTER TABLE articles DROP INDEX idx; +@@ -674,7 +674,7 @@ + select @@innodb_ft_user_stopword_table; + @@innodb_ft_user_stopword_table + NULL +-create table user_stopword_1(value varchar(30)) engine = innodb; ++create table user_stopword_1(value varchar(30)) WITH SYSTEM VERSIONING engine = innodb; + set session innodb_ft_user_stopword_table = "test/user_stopword_1"; + insert into user_stopword_1 values("when"); + SET SESSION innodb_ft_enable_stopword = 1; +@@ -702,7 +702,7 @@ + select @@innodb_ft_server_stopword_table; + @@innodb_ft_server_stopword_table + NULL +-create table server_stopword(value varchar(30)) engine = innodb; ++create table server_stopword(value varchar(30)) WITH SYSTEM VERSIONING engine = innodb; + SET GLOBAL innodb_ft_server_stopword_table = "test/server_stopword"; + select @@innodb_ft_server_stopword_table; + @@innodb_ft_server_stopword_table diff --git a/mysql-test/suite/innodb_fts/r/stopword.result b/mysql-test/suite/innodb_fts/r/stopword.result index 1465e1713fd..8f3cf9d6a20 100644 --- a/mysql-test/suite/innodb_fts/r/stopword.result +++ b/mysql-test/suite/innodb_fts/r/stopword.result @@ -1,3 +1,6 @@ +SET @innodb_ft_server_stopword_table_orig=@@innodb_ft_server_stopword_table; +SET @innodb_ft_enable_stopword_orig=@@innodb_ft_enable_stopword; +SET @innodb_ft_user_stopword_table_orig=@@innodb_ft_user_stopword_table; call mtr.add_suppression("\\[ERROR\\] InnoDB: user stopword table not_defined does not exist."); call mtr.add_suppression("\\[ERROR\\] InnoDB: user stopword table test/user_stopword_session does not exist."); select * from information_schema.innodb_ft_default_stopword; @@ -54,9 +57,6 @@ INSERT INTO articles (title,body) VALUES SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('the' IN NATURAL LANGUAGE MODE); id title body -SET @innodb_ft_server_stopword_table_orig=@@innodb_ft_server_stopword_table; -SET @innodb_ft_enable_stopword_orig=@@innodb_ft_enable_stopword; -SET @innodb_ft_user_stopword_table_orig=@@innodb_ft_user_stopword_table; set global innodb_ft_server_stopword_table = "not_defined"; ERROR 42000: Variable 'innodb_ft_server_stopword_table' can't be set to the value of 'not_defined' set global innodb_ft_server_stopword_table = NULL; @@ -80,6 +80,8 @@ SELECT * FROM articles_2 WHERE MATCH (title,body) AGAINST ('this' IN NATURAL LANGUAGE MODE); id title body 1 test for stopwords this is it... +insert into user_stopword values("the"); +delete from user_stopword; insert into user_stopword values("this"); CREATE TABLE articles_3 ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, @@ -93,6 +95,8 @@ SELECT * FROM articles_3 WHERE MATCH (title,body) AGAINST ('this' IN NATURAL LANGUAGE MODE); id title body create table user_stopword_session(value varchar(30)) engine = innodb; +insert into user_stopword values("this"); +delete from user_stopword; insert into user_stopword_session values("session"); set session innodb_ft_user_stopword_table="test/user_stopword_session"; CREATE TABLE articles_4 ( @@ -332,6 +336,8 @@ create table user_stopword(value varchar(30)) engine = innodb; set session innodb_ft_user_stopword_table = "test/user_stopword"; create table server_stopword(value varchar(30)) engine = innodb; set global innodb_ft_server_stopword_table = "test/server_stopword"; +insert into user_stopword values("when"),("where"); +delete from user_stopword; insert into user_stopword values("this"),("will"),("the"); ALTER TABLE articles DROP INDEX idx; ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body); diff --git a/mysql-test/suite/innodb_fts/r/versioning,prepare.result b/mysql-test/suite/innodb_fts/r/versioning,prepare.result new file mode 100644 index 00000000000..ada4f30d80c --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/versioning,prepare.result @@ -0,0 +1,695 @@ +# Upgrade test +CREATE TEMPORARY TABLE articles ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), +body TEXT, +FULLTEXT (title,body) +) ENGINE=InnoDB; +ERROR HY000: Cannot create FULLTEXT index on temporary InnoDB table +CREATE TABLE articles ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), +body TEXT, +FULLTEXT (title,body) +)with system versioning 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 ...'); +INSERT INTO articles (title,body) VALUES +('test query expansion','for database ...'); +INSERT INTO articles (title,body) VALUES +('test proximity search, test, proximity and phrase', +'search, with proximity innodb'); +INSERT INTO articles (title,body) VALUES +('test my proximity fts new search, test, proximity and phrase', +'search, with proximity innodb'); +INSERT INTO articles (title,body) VALUES +('test more of proximity fts search, test, more proximity and phrase', +'search, with proximity innodb'); +call mtr.add_suppression("\\[ERROR\\] InnoDB: user stopword table not_defined does not exist."); +call mtr.add_suppression("\\[ERROR\\] InnoDB: user stopword table test/user_stopword_session does not exist."); +select * from information_schema.innodb_ft_default_stopword; +value +a +about +an +are +as +at +be +by +com +de +en +for +from +how +i +in +is +it +la +of +on +or +that +the +this +to +was +what +when +where +who +will +with +und +the +www +CREATE TABLE articles2 ( +id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, +title VARCHAR(200), +body TEXT, +FULLTEXT (title,body) +)with system versioning ENGINE=InnoDB; +INSERT INTO articles2 (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 ...'); +SELECT * FROM articles2 WHERE MATCH (title,body) +AGAINST ('the' IN NATURAL LANGUAGE MODE); +id title body +set global innodb_ft_server_stopword_table = "not_defined"; +ERROR 42000: Variable 'innodb_ft_server_stopword_table' can't be set to the value of 'not_defined' +set global innodb_ft_server_stopword_table = NULL; +create table user_stopword(value varchar(30)) engine = innodb; +set global innodb_ft_server_stopword_table = "test/user_stopword"; +drop index title on articles2; +create fulltext index idx on articles2(title, body); +insert into articles2 (title, body) +values ('test for stopwords','this is it...'); +insert into user_stopword values("the"); +delete from user_stopword; +insert into user_stopword values("this"); +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('Database' IN NATURAL LANGUAGE MODE); +ERROR HY000: Index articles is corrupted +call mtr.add_suppression("test/articles.? contains 3 indexes inside InnoDB"); +alter table articles force; +Warnings: +Warning 1082 InnoDB: Table test/articles contains 3 indexes inside InnoDB, which is different from the number of indexes 2 defined in the MariaDB +flush tables; +show create table articles; +Table Create Table +articles CREATE TABLE `articles` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `title` varchar(200) DEFAULT NULL, + `body` text DEFAULT NULL, + PRIMARY KEY (`id`), + FULLTEXT KEY `title` (`title`,`body`) +) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('Database' IN NATURAL LANGUAGE MODE); +id title body +1 MySQL Tutorial DBMS stands for DataBase ... +5 MySQL vs. YourSQL In the following database comparison ... +7 test query expansion for database ... +SELECT COUNT(*) FROM articles +WHERE MATCH (title,body) +AGAINST ('database' IN NATURAL LANGUAGE MODE); +COUNT(*) +3 +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 ... +SELECT COUNT(IF(MATCH (title,body) +AGAINST ('database' IN NATURAL LANGUAGE MODE), 1, NULL)) +AS count FROM articles; +count +3 +SELECT id, body, MATCH (title,body) +AGAINST ('Database' IN NATURAL LANGUAGE MODE) AS score +FROM articles; +id body score +1 DBMS stands for DataBase ... 0.2734021842479706 +2 After you went through a ... 0 +3 In this tutorial we will show ... 0 +4 1. Never run mysqld as root. 2. ... 0 +5 In the following database comparison ... 0.2734021842479706 +6 When configured properly, MySQL ... 0 +7 for database ... 0.2734021842479706 +8 search, with proximity innodb 0 +9 search, with proximity innodb 0 +10 search, with proximity innodb 0 +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('MySQL' IN NATURAL LANGUAGE 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. ... +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('+MySQL -YourSQL' 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 ('DBMS Security' IN BOOLEAN MODE); +id title body +1 MySQL Tutorial DBMS stands for DataBase ... +6 MySQL Security When configured properly, MySQL ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('+MySQL +YourSQL' IN BOOLEAN MODE); +id title body +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('+MySQL YourSQL' IN BOOLEAN MODE); +id title body +5 MySQL vs. YourSQL In the following database comparison ... +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 ~YourSQL' 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. ... +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('t*' IN BOOLEAN MODE); +id title body +8 test proximity search, test, proximity and phrase search, with proximity innodb +9 test my proximity fts new search, test, proximity and phrase search, with proximity innodb +10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb +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. ... +7 test query expansion for database ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('MY*' 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. ... +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('ru*' IN BOOLEAN MODE); +id title body +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('+ MySQL >Well < stands' IN BOOLEAN MODE); +id title body +2 How To Use MySQL Well After you went through a ... +6 MySQL Security When configured properly, MySQL ... +1 MySQL Tutorial DBMS stands for DataBase ... +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 ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('+ MySQL - (Well stands)' IN BOOLEAN MODE); +id title body +6 MySQL Security When configured properly, MySQL ... +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 ... +SELECT * FROM articles WHERE MATCH (title,body) AGAINST +('(((((((((((((((((((((((((((((((((Security)))))))))))))))))))))))))))))))))' + IN BOOLEAN MODE); +ERROR HY000: Table handler out of memory +SELECT * FROM articles WHERE MATCH (title,body) AGAINST +('((((((((((((((((((((((((((((((((Security))))))))))))))))))))))))))))))))' + IN BOOLEAN MODE); +id title body +6 MySQL Security When configured properly, MySQL ... +SELECT * FROM articles WHERE MATCH (title,body) AGAINST +('(((((((((((((((((((((((((((((((vs))))))))))))))))))))))))))))))),(((to)))' + IN BOOLEAN MODE); +id title body +SELECT * FROM articles WHERE MATCH (title,body) AGAINST +('((((((((((((((((((((((((((((((((Security)))))))))))))))))))))))))))))))' + IN BOOLEAN MODE); +ERROR 42000: syntax error, unexpected $end +SELECT * FROM articles WHERE MATCH (title,body) AGAINST +('(((((((((((((((((((((((((((((((((Security))))))))))))))))))))))))))))))))' + IN BOOLEAN MODE); +ERROR 42000: syntax error, unexpected $end +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('+ MySQL + (>Well < stands)' IN BOOLEAN MODE); +id title body +2 How To Use MySQL Well After you went through a ... +1 MySQL Tutorial DBMS stands for DataBase ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('YourSQL + (+MySQL - (Tricks Security))' IN BOOLEAN MODE); +id title body +5 MySQL vs. YourSQL In the following database comparison ... +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 ('(+MySQL - (Tricks Security)) - YourSQL' IN BOOLEAN MODE); +id title body +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 ('mysql - Security&DBMS' IN BOOLEAN MODE); +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 ... +SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('mysql - (Security DBMS)' IN BOOLEAN MODE); +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 ... +SELECT * FROM articles WHERE MATCH (title,body) AGAINST (' - Security&DBMS + YourSQL' IN BOOLEAN MODE); +id title body +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('+YourSQL - Security&DBMS' IN BOOLEAN MODE); +id title body +5 MySQL vs. YourSQL In the following database comparison ... +SELECT COUNT(*) FROM articles +WHERE MATCH (title,body) +AGAINST ('database' WITH QUERY EXPANSION); +COUNT(*) +10 +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('test' WITH QUERY EXPANSION); +id title body +10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb +9 test my proximity fts new search, test, proximity and phrase search, with proximity innodb +8 test proximity search, test, proximity and phrase search, with proximity innodb +7 test query expansion for database ... +1 MySQL Tutorial DBMS stands for DataBase ... +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"following comparison"@3' IN BOOLEAN MODE); +id title body +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"following comparison"@2' IN BOOLEAN MODE); +id title body +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"following database"' IN BOOLEAN MODE); +id title body +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"proximity search"@3' IN BOOLEAN MODE); +id title body +8 test proximity search, test, proximity and phrase search, with proximity innodb +9 test my proximity fts new search, test, proximity and phrase search, with proximity innodb +10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"proximity search"@2' IN BOOLEAN MODE); +id title body +8 test proximity search, test, proximity and phrase search, with proximity innodb +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"proximity search"@5' IN BOOLEAN MODE); +id title body +8 test proximity search, test, proximity and phrase search, with proximity innodb +9 test my proximity fts new search, test, proximity and phrase search, with proximity innodb +10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"test proximity"@5' IN BOOLEAN MODE); +id title body +8 test proximity search, test, proximity and phrase search, with proximity innodb +9 test my proximity fts new search, test, proximity and phrase search, with proximity innodb +10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"test proximity"@1' IN BOOLEAN MODE); +id title body +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"test proximity"@4' IN BOOLEAN MODE); +id title body +8 test proximity search, test, proximity and phrase search, with proximity innodb +9 test my proximity fts new search, test, proximity and phrase search, with proximity innodb +10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"test proximity"@3' IN BOOLEAN MODE); +id title body +8 test proximity search, test, proximity and phrase search, with proximity innodb +9 test my proximity fts new search, test, proximity and phrase search, with proximity innodb +10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"more test proximity"@4' IN BOOLEAN MODE); +id title body +10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"more test proximity"@3' IN BOOLEAN MODE); +id title body +10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"more test proximity"' IN BOOLEAN MODE); +id title body +set global innodb_ft_server_stopword_table= "test/user_stopword"; +SELECT * FROM articles2 WHERE MATCH (title,body) +AGAINST ('the' IN NATURAL LANGUAGE MODE); +SELECT * FROM articles2 WHERE MATCH (title,body) +AGAINST ('this' IN NATURAL LANGUAGE MODE); +drop index idx on articles2; +Warnings: +Warning 1082 InnoDB: Table test/articles2 contains 3 indexes inside InnoDB, which is different from the number of indexes 1 defined in the MariaDB +create fulltext index idx on articles2(title, body); +SELECT * FROM articles2 WHERE MATCH (title,body) +AGAINST ('the' IN NATURAL LANGUAGE MODE); +id title body +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles2 WHERE MATCH (title,body) +AGAINST ('this' IN NATURAL LANGUAGE MODE); +id title body +# Downgrade test +alter table articles force; +Warnings: +Warning 1082 InnoDB: Table test/articles contains 3 indexes inside InnoDB, which is different from the number of indexes 2 defined in the MariaDB +Warning 1082 InnoDB: Table test/articles contains 3 indexes inside InnoDB, which is different from the number of indexes 2 defined in the MariaDB +flush tables; +show create table articles; +Table Create Table +articles CREATE TABLE `articles` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `title` varchar(200) DEFAULT NULL, + `body` text DEFAULT NULL, + PRIMARY KEY (`id`), + FULLTEXT KEY `title` (`title`,`body`) +) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('Database' IN NATURAL LANGUAGE MODE); +id title body +1 MySQL Tutorial DBMS stands for DataBase ... +5 MySQL vs. YourSQL In the following database comparison ... +7 test query expansion for database ... +SELECT COUNT(*) FROM articles +WHERE MATCH (title,body) +AGAINST ('database' IN NATURAL LANGUAGE MODE); +COUNT(*) +3 +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 ... +SELECT COUNT(IF(MATCH (title,body) +AGAINST ('database' IN NATURAL LANGUAGE MODE), 1, NULL)) +AS count FROM articles; +count +3 +SELECT id, body, MATCH (title,body) +AGAINST ('Database' IN NATURAL LANGUAGE MODE) AS score +FROM articles; +id body score +1 DBMS stands for DataBase ... 0.2734021842479706 +2 After you went through a ... 0 +3 In this tutorial we will show ... 0 +4 1. Never run mysqld as root. 2. ... 0 +5 In the following database comparison ... 0.2734021842479706 +6 When configured properly, MySQL ... 0 +7 for database ... 0.2734021842479706 +8 search, with proximity innodb 0 +9 search, with proximity innodb 0 +10 search, with proximity innodb 0 +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('MySQL' IN NATURAL LANGUAGE 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. ... +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('+MySQL -YourSQL' 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 ('DBMS Security' IN BOOLEAN MODE); +id title body +1 MySQL Tutorial DBMS stands for DataBase ... +6 MySQL Security When configured properly, MySQL ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('+MySQL +YourSQL' IN BOOLEAN MODE); +id title body +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('+MySQL YourSQL' IN BOOLEAN MODE); +id title body +5 MySQL vs. YourSQL In the following database comparison ... +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 ~YourSQL' 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. ... +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('t*' IN BOOLEAN MODE); +id title body +8 test proximity search, test, proximity and phrase search, with proximity innodb +9 test my proximity fts new search, test, proximity and phrase search, with proximity innodb +10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb +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. ... +7 test query expansion for database ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('MY*' 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. ... +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('ru*' IN BOOLEAN MODE); +id title body +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('+ MySQL >Well < stands' IN BOOLEAN MODE); +id title body +2 How To Use MySQL Well After you went through a ... +6 MySQL Security When configured properly, MySQL ... +1 MySQL Tutorial DBMS stands for DataBase ... +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 ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('+ MySQL - (Well stands)' IN BOOLEAN MODE); +id title body +6 MySQL Security When configured properly, MySQL ... +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 ... +SELECT * FROM articles WHERE MATCH (title,body) AGAINST +('(((((((((((((((((((((((((((((((((Security)))))))))))))))))))))))))))))))))' + IN BOOLEAN MODE); +ERROR HY000: Table handler out of memory +SELECT * FROM articles WHERE MATCH (title,body) AGAINST +('((((((((((((((((((((((((((((((((Security))))))))))))))))))))))))))))))))' + IN BOOLEAN MODE); +id title body +6 MySQL Security When configured properly, MySQL ... +SELECT * FROM articles WHERE MATCH (title,body) AGAINST +('(((((((((((((((((((((((((((((((vs))))))))))))))))))))))))))))))),(((to)))' + IN BOOLEAN MODE); +id title body +SELECT * FROM articles WHERE MATCH (title,body) AGAINST +('((((((((((((((((((((((((((((((((Security)))))))))))))))))))))))))))))))' + IN BOOLEAN MODE); +ERROR 42000: syntax error, unexpected $end +SELECT * FROM articles WHERE MATCH (title,body) AGAINST +('(((((((((((((((((((((((((((((((((Security))))))))))))))))))))))))))))))))' + IN BOOLEAN MODE); +ERROR 42000: syntax error, unexpected $end +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('+ MySQL + (>Well < stands)' IN BOOLEAN MODE); +id title body +2 How To Use MySQL Well After you went through a ... +1 MySQL Tutorial DBMS stands for DataBase ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('YourSQL + (+MySQL - (Tricks Security))' IN BOOLEAN MODE); +id title body +5 MySQL vs. YourSQL In the following database comparison ... +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 ('(+MySQL - (Tricks Security)) - YourSQL' IN BOOLEAN MODE); +id title body +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 ('mysql - Security&DBMS' IN BOOLEAN MODE); +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 ... +SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('mysql - (Security DBMS)' IN BOOLEAN MODE); +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 ... +SELECT * FROM articles WHERE MATCH (title,body) AGAINST (' - Security&DBMS + YourSQL' IN BOOLEAN MODE); +id title body +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('+YourSQL - Security&DBMS' IN BOOLEAN MODE); +id title body +5 MySQL vs. YourSQL In the following database comparison ... +SELECT COUNT(*) FROM articles +WHERE MATCH (title,body) +AGAINST ('database' WITH QUERY EXPANSION); +COUNT(*) +10 +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('test' WITH QUERY EXPANSION); +id title body +10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb +9 test my proximity fts new search, test, proximity and phrase search, with proximity innodb +8 test proximity search, test, proximity and phrase search, with proximity innodb +7 test query expansion for database ... +1 MySQL Tutorial DBMS stands for DataBase ... +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"following comparison"@3' IN BOOLEAN MODE); +id title body +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"following comparison"@2' IN BOOLEAN MODE); +id title body +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"following database"' IN BOOLEAN MODE); +id title body +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"proximity search"@3' IN BOOLEAN MODE); +id title body +8 test proximity search, test, proximity and phrase search, with proximity innodb +9 test my proximity fts new search, test, proximity and phrase search, with proximity innodb +10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"proximity search"@2' IN BOOLEAN MODE); +id title body +8 test proximity search, test, proximity and phrase search, with proximity innodb +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"proximity search"@5' IN BOOLEAN MODE); +id title body +8 test proximity search, test, proximity and phrase search, with proximity innodb +9 test my proximity fts new search, test, proximity and phrase search, with proximity innodb +10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"test proximity"@5' IN BOOLEAN MODE); +id title body +8 test proximity search, test, proximity and phrase search, with proximity innodb +9 test my proximity fts new search, test, proximity and phrase search, with proximity innodb +10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"test proximity"@1' IN BOOLEAN MODE); +id title body +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"test proximity"@4' IN BOOLEAN MODE); +id title body +8 test proximity search, test, proximity and phrase search, with proximity innodb +9 test my proximity fts new search, test, proximity and phrase search, with proximity innodb +10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"test proximity"@3' IN BOOLEAN MODE); +id title body +8 test proximity search, test, proximity and phrase search, with proximity innodb +9 test my proximity fts new search, test, proximity and phrase search, with proximity innodb +10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"more test proximity"@4' IN BOOLEAN MODE); +id title body +10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"more test proximity"@3' IN BOOLEAN MODE); +id title body +10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"more test proximity"' IN BOOLEAN MODE); +id title body +set global innodb_ft_server_stopword_table= "test/user_stopword"; +drop index idx on articles2; +Warnings: +Warning 1082 InnoDB: Table test/articles2 contains 3 indexes inside InnoDB, which is different from the number of indexes 2 defined in the MariaDB +Warning 1082 InnoDB: Table test/articles2 contains 3 indexes inside InnoDB, which is different from the number of indexes 1 defined in the MariaDB +create fulltext index idx on articles2(title, body); +SELECT * FROM articles2 WHERE MATCH (title,body) +AGAINST ('the' IN NATURAL LANGUAGE MODE); +id title body +SELECT * FROM articles2 WHERE MATCH (title,body) +AGAINST ('this' IN NATURAL LANGUAGE MODE); +id title body +# Cleanup +drop tables articles, articles2, user_stopword; +set global innodb_ft_server_stopword_table= default; diff --git a/mysql-test/suite/innodb_fts/r/versioning.result b/mysql-test/suite/innodb_fts/r/versioning.result new file mode 100644 index 00000000000..73ce8f838fd --- /dev/null +++ b/mysql-test/suite/innodb_fts/r/versioning.result @@ -0,0 +1,303 @@ +# Upgrade test +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('Database' IN NATURAL LANGUAGE MODE); +ERROR HY000: Index articles is corrupted +call mtr.add_suppression("test/articles.? contains 3 indexes inside InnoDB"); +alter table articles force; +Warnings: +Warning 1082 InnoDB: Table test/articles contains 3 indexes inside InnoDB, which is different from the number of indexes 2 defined in the MariaDB +flush tables; +show create table articles; +Table Create Table +articles CREATE TABLE `articles` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `title` varchar(200) DEFAULT NULL, + `body` text DEFAULT NULL, + PRIMARY KEY (`id`), + FULLTEXT KEY `title` (`title`,`body`) +) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('Database' IN NATURAL LANGUAGE MODE); +id title body +1 MySQL Tutorial DBMS stands for DataBase ... +5 MySQL vs. YourSQL In the following database comparison ... +7 test query expansion for database ... +SELECT COUNT(*) FROM articles +WHERE MATCH (title,body) +AGAINST ('database' IN NATURAL LANGUAGE MODE); +COUNT(*) +3 +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 ... +SELECT COUNT(IF(MATCH (title,body) +AGAINST ('database' IN NATURAL LANGUAGE MODE), 1, NULL)) +AS count FROM articles; +count +3 +SELECT id, body, MATCH (title,body) +AGAINST ('Database' IN NATURAL LANGUAGE MODE) AS score +FROM articles; +id body score +1 DBMS stands for DataBase ... 0.2734021842479706 +2 After you went through a ... 0 +3 In this tutorial we will show ... 0 +4 1. Never run mysqld as root. 2. ... 0 +5 In the following database comparison ... 0.2734021842479706 +6 When configured properly, MySQL ... 0 +7 for database ... 0.2734021842479706 +8 search, with proximity innodb 0 +9 search, with proximity innodb 0 +10 search, with proximity innodb 0 +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('MySQL' IN NATURAL LANGUAGE 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. ... +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('+MySQL -YourSQL' 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 ('DBMS Security' IN BOOLEAN MODE); +id title body +1 MySQL Tutorial DBMS stands for DataBase ... +6 MySQL Security When configured properly, MySQL ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('+MySQL +YourSQL' IN BOOLEAN MODE); +id title body +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('+MySQL YourSQL' IN BOOLEAN MODE); +id title body +5 MySQL vs. YourSQL In the following database comparison ... +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 ~YourSQL' 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. ... +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('t*' IN BOOLEAN MODE); +id title body +8 test proximity search, test, proximity and phrase search, with proximity innodb +9 test my proximity fts new search, test, proximity and phrase search, with proximity innodb +10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb +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. ... +7 test query expansion for database ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('MY*' 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. ... +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('ru*' IN BOOLEAN MODE); +id title body +4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('+ MySQL >Well < stands' IN BOOLEAN MODE); +id title body +2 How To Use MySQL Well After you went through a ... +6 MySQL Security When configured properly, MySQL ... +1 MySQL Tutorial DBMS stands for DataBase ... +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 ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('+ MySQL - (Well stands)' IN BOOLEAN MODE); +id title body +6 MySQL Security When configured properly, MySQL ... +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 ... +SELECT * FROM articles WHERE MATCH (title,body) AGAINST +('(((((((((((((((((((((((((((((((((Security)))))))))))))))))))))))))))))))))' + IN BOOLEAN MODE); +ERROR HY000: Table handler out of memory +SELECT * FROM articles WHERE MATCH (title,body) AGAINST +('((((((((((((((((((((((((((((((((Security))))))))))))))))))))))))))))))))' + IN BOOLEAN MODE); +id title body +6 MySQL Security When configured properly, MySQL ... +SELECT * FROM articles WHERE MATCH (title,body) AGAINST +('(((((((((((((((((((((((((((((((vs))))))))))))))))))))))))))))))),(((to)))' + IN BOOLEAN MODE); +id title body +SELECT * FROM articles WHERE MATCH (title,body) AGAINST +('((((((((((((((((((((((((((((((((Security)))))))))))))))))))))))))))))))' + IN BOOLEAN MODE); +ERROR 42000: syntax error, unexpected $end +SELECT * FROM articles WHERE MATCH (title,body) AGAINST +('(((((((((((((((((((((((((((((((((Security))))))))))))))))))))))))))))))))' + IN BOOLEAN MODE); +ERROR 42000: syntax error, unexpected $end +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('+ MySQL + (>Well < stands)' IN BOOLEAN MODE); +id title body +2 How To Use MySQL Well After you went through a ... +1 MySQL Tutorial DBMS stands for DataBase ... +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('YourSQL + (+MySQL - (Tricks Security))' IN BOOLEAN MODE); +id title body +5 MySQL vs. YourSQL In the following database comparison ... +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 ('(+MySQL - (Tricks Security)) - YourSQL' IN BOOLEAN MODE); +id title body +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 ('mysql - Security&DBMS' IN BOOLEAN MODE); +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 ... +SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('mysql - (Security DBMS)' IN BOOLEAN MODE); +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 ... +SELECT * FROM articles WHERE MATCH (title,body) AGAINST (' - Security&DBMS + YourSQL' IN BOOLEAN MODE); +id title body +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('+YourSQL - Security&DBMS' IN BOOLEAN MODE); +id title body +5 MySQL vs. YourSQL In the following database comparison ... +SELECT COUNT(*) FROM articles +WHERE MATCH (title,body) +AGAINST ('database' WITH QUERY EXPANSION); +COUNT(*) +10 +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('test' WITH QUERY EXPANSION); +id title body +10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb +9 test my proximity fts new search, test, proximity and phrase search, with proximity innodb +8 test proximity search, test, proximity and phrase search, with proximity innodb +7 test query expansion for database ... +1 MySQL Tutorial DBMS stands for DataBase ... +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"following comparison"@3' IN BOOLEAN MODE); +id title body +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"following comparison"@2' IN BOOLEAN MODE); +id title body +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"following database"' IN BOOLEAN MODE); +id title body +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"proximity search"@3' IN BOOLEAN MODE); +id title body +8 test proximity search, test, proximity and phrase search, with proximity innodb +9 test my proximity fts new search, test, proximity and phrase search, with proximity innodb +10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"proximity search"@2' IN BOOLEAN MODE); +id title body +8 test proximity search, test, proximity and phrase search, with proximity innodb +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"proximity search"@5' IN BOOLEAN MODE); +id title body +8 test proximity search, test, proximity and phrase search, with proximity innodb +9 test my proximity fts new search, test, proximity and phrase search, with proximity innodb +10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"test proximity"@5' IN BOOLEAN MODE); +id title body +8 test proximity search, test, proximity and phrase search, with proximity innodb +9 test my proximity fts new search, test, proximity and phrase search, with proximity innodb +10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"test proximity"@1' IN BOOLEAN MODE); +id title body +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"test proximity"@4' IN BOOLEAN MODE); +id title body +8 test proximity search, test, proximity and phrase search, with proximity innodb +9 test my proximity fts new search, test, proximity and phrase search, with proximity innodb +10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"test proximity"@3' IN BOOLEAN MODE); +id title body +8 test proximity search, test, proximity and phrase search, with proximity innodb +9 test my proximity fts new search, test, proximity and phrase search, with proximity innodb +10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"more test proximity"@4' IN BOOLEAN MODE); +id title body +10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"more test proximity"@3' IN BOOLEAN MODE); +id title body +10 test more of proximity fts search, test, more proximity and phrase search, with proximity innodb +SELECT * FROM articles +WHERE MATCH (title,body) +AGAINST ('"more test proximity"' IN BOOLEAN MODE); +id title body +set global innodb_ft_server_stopword_table= "test/user_stopword"; +SELECT * FROM articles2 WHERE MATCH (title,body) +AGAINST ('the' IN NATURAL LANGUAGE MODE); +SELECT * FROM articles2 WHERE MATCH (title,body) +AGAINST ('this' IN NATURAL LANGUAGE MODE); +drop index idx on articles2; +Warnings: +Warning 1082 InnoDB: Table test/articles2 contains 3 indexes inside InnoDB, which is different from the number of indexes 1 defined in the MariaDB +create fulltext index idx on articles2(title, body); +SELECT * FROM articles2 WHERE MATCH (title,body) +AGAINST ('the' IN NATURAL LANGUAGE MODE); +id title body +5 MySQL vs. YourSQL In the following database comparison ... +SELECT * FROM articles2 WHERE MATCH (title,body) +AGAINST ('this' IN NATURAL LANGUAGE MODE); +id title body +# Cleanup +drop tables articles, articles2, user_stopword; +set global innodb_ft_server_stopword_table= default; diff --git a/mysql-test/suite/innodb_fts/t/basic.inc b/mysql-test/suite/innodb_fts/t/basic.inc new file mode 100644 index 00000000000..fd7d09208bc --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/basic.inc @@ -0,0 +1,264 @@ +if ($basic_stage == create_table) +{ +# Create FTS table +--error ER_INNODB_NO_FT_TEMP_TABLE +CREATE TEMPORARY TABLE articles ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + body TEXT, + FULLTEXT (title,body) + ) ENGINE=InnoDB; + +--disable_query_log +eval CREATE TABLE articles ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + body TEXT, + FULLTEXT (title,body) + )$create_options ENGINE=InnoDB; +--enable_query_log +} + +if ($basic_stage == insert_1) +{ +# 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 ...'); +} + +if ($basic_stage == select_1) +{ +# Look for 'Database' in table article +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('Database' IN NATURAL LANGUAGE MODE); + +SELECT COUNT(*) 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); + + +SELECT COUNT(IF(MATCH (title,body) + AGAINST ('database' IN NATURAL LANGUAGE MODE), 1, NULL)) + AS count FROM articles; + +# Select Relevance Ranking +SELECT id, body, MATCH (title,body) + AGAINST ('Database' IN NATURAL LANGUAGE MODE) AS score + FROM articles; + +# 'MySQL' treated as stopword (stopword functionality not yet supported) +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('MySQL' IN NATURAL LANGUAGE MODE); + +# Boolean search +# Select rows contain "MySQL" but not "YourSQL" +SELECT * FROM articles WHERE MATCH (title,body) + AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE); + +# Select rows contain at least one of the two words +SELECT * FROM articles WHERE MATCH (title,body) + AGAINST ('DBMS Security' IN BOOLEAN MODE); + +# Select rows contain both "MySQL" and "YourSQL" +SELECT * FROM articles WHERE MATCH (title,body) + AGAINST ('+MySQL +YourSQL' IN BOOLEAN MODE); + +# Select rows contain "MySQL" but rank rows with "YourSQL" higher +SELECT * FROM articles WHERE MATCH (title,body) + AGAINST ('+MySQL YourSQL' IN BOOLEAN MODE); + +# Test negation operator. Select rows contain MySQL, +# if the row contains "YourSQL", rank it lower +SELECT * FROM articles WHERE MATCH (title,body) + AGAINST ('+MySQL ~YourSQL' IN BOOLEAN MODE); + +# Test wild card search operator +# Notice row with "the" will not get fetched due to +# stopword filtering +SELECT * FROM articles WHERE MATCH (title,body) + AGAINST ('t*' IN BOOLEAN MODE); + +# Test wild card search, notice row 6 with 2 "MySQL" rank first +SELECT * FROM articles WHERE MATCH (title,body) + AGAINST ('MY*' IN BOOLEAN MODE); + +# Another wild card search +SELECT * FROM articles WHERE MATCH (title,body) + AGAINST ('ru*' IN BOOLEAN MODE); + +# Test ">" and "<" Operator, the ">" operator increases +# the word relevance rank and the "<" operator decreases it +# Following test puts rows with "Well" on top and rows +# with "stands" at the bottom +SELECT * FROM articles WHERE MATCH (title,body) + AGAINST ('+ MySQL >Well < stands' IN BOOLEAN MODE); + +# Test sub-expression boolean search. Find rows contain +# "MySQL" but not "Well" or "stands". +SELECT * FROM articles WHERE MATCH (title,body) + AGAINST ('+ MySQL - (Well stands)' IN BOOLEAN MODE); + +--error 128 +SELECT * FROM articles WHERE MATCH (title,body) AGAINST +('(((((((((((((((((((((((((((((((((Security)))))))))))))))))))))))))))))))))' + IN BOOLEAN MODE); +SELECT * FROM articles WHERE MATCH (title,body) AGAINST +('((((((((((((((((((((((((((((((((Security))))))))))))))))))))))))))))))))' + IN BOOLEAN MODE); +SELECT * FROM articles WHERE MATCH (title,body) AGAINST +('(((((((((((((((((((((((((((((((vs))))))))))))))))))))))))))))))),(((to)))' + IN BOOLEAN MODE); + +--error ER_PARSE_ERROR +SELECT * FROM articles WHERE MATCH (title,body) AGAINST +('((((((((((((((((((((((((((((((((Security)))))))))))))))))))))))))))))))' + IN BOOLEAN MODE); +--error ER_PARSE_ERROR +SELECT * FROM articles WHERE MATCH (title,body) AGAINST +('(((((((((((((((((((((((((((((((((Security))))))))))))))))))))))))))))))))' + IN BOOLEAN MODE); + +# Test sub-expression boolean search. Find rows contain +# "MySQL" and "Well" or "MySQL" and "stands". But rank the +# doc with "Well" higher, and doc with "stands" lower. +SELECT * FROM articles WHERE MATCH (title,body) + AGAINST ('+ MySQL + (>Well < stands)' IN BOOLEAN MODE); + +# Test nested sub-expression. +SELECT * FROM articles WHERE MATCH (title,body) + AGAINST ('YourSQL + (+MySQL - (Tricks Security))' IN BOOLEAN MODE); + +# Find rows with "MySQL" but not "Tricks", "Security" nor "YourSQL" +SELECT * FROM articles WHERE MATCH (title,body) + AGAINST ('(+MySQL - (Tricks Security)) - YourSQL' IN BOOLEAN MODE); + +# Test non-word delimiter combined with negate "-" operator +# This should return the same result as 'mysql - (Security DBMS)' +SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('mysql - Security&DBMS' IN BOOLEAN MODE); +SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('mysql - (Security DBMS)' IN BOOLEAN MODE); + +# Again, the operator sequence should not matter +SELECT * FROM articles WHERE MATCH (title,body) AGAINST (' - Security&DBMS + YourSQL' IN BOOLEAN MODE); + +SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('+YourSQL - Security&DBMS' IN BOOLEAN MODE); + +# Test query expansion +SELECT COUNT(*) FROM articles + WHERE MATCH (title,body) + AGAINST ('database' WITH QUERY EXPANSION); +} + +if ($basic_stage == insert_2) +{ +INSERT INTO articles (title,body) VALUES + ('test query expansion','for database ...'); +} + +if ($basic_stage == select_2) +{ +# This query will return result containing word "database" as +# the query expand from "test" to words in document just +# inserted above +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('test' WITH QUERY EXPANSION); + +# This is to test the proximity search, search two word +# "following" and "comparison" within 19 character space +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('"following comparison"@3' IN BOOLEAN MODE); + +# This is to test the proximity search, search two word +# "following" and "comparison" within 19 character space +# This search should come with no return result +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('"following comparison"@2' IN BOOLEAN MODE); + +# This is to test the phrase search, searching phrase +# "following database" +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('"following database"' IN BOOLEAN MODE); +} + +if ($basic_stage == insert_3) +{ +# Insert into table with similar word of different distances +INSERT INTO articles (title,body) VALUES + ('test proximity search, test, proximity and phrase', + 'search, with proximity innodb'); + +INSERT INTO articles (title,body) VALUES + ('test my proximity fts new search, test, proximity and phrase', + 'search, with proximity innodb'); + +INSERT INTO articles (title,body) VALUES + ('test more of proximity fts search, test, more proximity and phrase', + 'search, with proximity innodb'); +} + +if ($basic_stage == select_3) +{ +# This should only return the first document +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('"proximity search"@3' IN BOOLEAN MODE); + +# This would return no document +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('"proximity search"@2' IN BOOLEAN MODE); + +# This give you all three documents +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('"proximity search"@5' IN BOOLEAN MODE); + +# Similar boundary testing for the words +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('"test proximity"@5' IN BOOLEAN MODE); + +# No document will be returned +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('"test proximity"@1' IN BOOLEAN MODE); + +# All three documents will be returned +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('"test proximity"@4' IN BOOLEAN MODE); + +# Only two document will be returned. +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('"test proximity"@3' IN BOOLEAN MODE); + +# Test with more word The last document will return, please notice there +# is no ordering requirement for proximity search. +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('"more test proximity"@4' IN BOOLEAN MODE); + +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('"more test proximity"@3' IN BOOLEAN MODE); + +# The phrase search will not require exact word ordering +SELECT * FROM articles + WHERE MATCH (title,body) + AGAINST ('"more test proximity"' IN BOOLEAN MODE); +} diff --git a/mysql-test/suite/innodb_fts/t/basic.test b/mysql-test/suite/innodb_fts/t/basic.test index 53ad978a5b1..df2e24fae8e 100644 --- a/mysql-test/suite/innodb_fts/t/basic.test +++ b/mysql-test/suite/innodb_fts/t/basic.test @@ -1,252 +1,33 @@ # This is the basic function tests for innodb FTS -- source include/have_innodb.inc +--let $modify_create_table= 1 +-- source include/maybe_versioning.inc -# Create FTS table ---error ER_INNODB_NO_FT_TEMP_TABLE -CREATE TEMPORARY TABLE articles ( - id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, - title VARCHAR(200), - body TEXT, - FULLTEXT (title,body) - ) ENGINE=InnoDB; +let $basic_stage= create_table; +--source basic.inc -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 ...'); +let $basic_stage= insert_1; +--source basic.inc -- disable_result_log ANALYZE TABLE articles; -- enable_result_log -# Look for 'Database' in table article -SELECT * FROM articles - WHERE MATCH (title,body) - AGAINST ('Database' IN NATURAL LANGUAGE MODE); +let $basic_stage= select_1; +--source basic.inc -SELECT COUNT(*) FROM articles - WHERE MATCH (title,body) - AGAINST ('database' IN NATURAL LANGUAGE MODE); +let $basic_stage= insert_2; +--source basic.inc -SELECT * FROM articles - WHERE MATCH (title, body) - AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE); +let $basic_stage= select_2; +--source basic.inc +let $basic_stage= insert_3; +--source basic.inc -SELECT COUNT(IF(MATCH (title,body) - AGAINST ('database' IN NATURAL LANGUAGE MODE), 1, NULL)) - AS count FROM articles; - -# Select Relevance Ranking -SELECT id, body, MATCH (title,body) - AGAINST ('Database' IN NATURAL LANGUAGE MODE) AS score - FROM articles; - -# 'MySQL' treated as stopword (stopword functionality not yet supported) -SELECT * FROM articles - WHERE MATCH (title,body) - AGAINST ('MySQL' IN NATURAL LANGUAGE MODE); - -# Boolean search -# Select rows contain "MySQL" but not "YourSQL" -SELECT * FROM articles WHERE MATCH (title,body) - AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE); - -# Select rows contain at least one of the two words -SELECT * FROM articles WHERE MATCH (title,body) - AGAINST ('DBMS Security' IN BOOLEAN MODE); - -# Select rows contain both "MySQL" and "YourSQL" -SELECT * FROM articles WHERE MATCH (title,body) - AGAINST ('+MySQL +YourSQL' IN BOOLEAN MODE); - -# Select rows contain "MySQL" but rank rows with "YourSQL" higher -SELECT * FROM articles WHERE MATCH (title,body) - AGAINST ('+MySQL YourSQL' IN BOOLEAN MODE); - -# Test negation operator. Select rows contain MySQL, -# if the row contains "YourSQL", rank it lower -SELECT * FROM articles WHERE MATCH (title,body) - AGAINST ('+MySQL ~YourSQL' IN BOOLEAN MODE); - -# Test wild card search operator -# Notice row with "the" will not get fetched due to -# stopword filtering -SELECT * FROM articles WHERE MATCH (title,body) - AGAINST ('t*' IN BOOLEAN MODE); - -# Test wild card search, notice row 6 with 2 "MySQL" rank first -SELECT * FROM articles WHERE MATCH (title,body) - AGAINST ('MY*' IN BOOLEAN MODE); - -# Another wild card search -SELECT * FROM articles WHERE MATCH (title,body) - AGAINST ('ru*' IN BOOLEAN MODE); - -# Test ">" and "<" Operator, the ">" operator increases -# the word relevance rank and the "<" operator decreases it -# Following test puts rows with "Well" on top and rows -# with "stands" at the bottom -SELECT * FROM articles WHERE MATCH (title,body) - AGAINST ('+ MySQL >Well < stands' IN BOOLEAN MODE); - -# Test sub-expression boolean search. Find rows contain -# "MySQL" but not "Well" or "stands". -SELECT * FROM articles WHERE MATCH (title,body) - AGAINST ('+ MySQL - (Well stands)' IN BOOLEAN MODE); - ---error 128 -SELECT * FROM articles WHERE MATCH (title,body) AGAINST -('(((((((((((((((((((((((((((((((((Security)))))))))))))))))))))))))))))))))' - IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST -('((((((((((((((((((((((((((((((((Security))))))))))))))))))))))))))))))))' - IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST -('(((((((((((((((((((((((((((((((vs))))))))))))))))))))))))))))))),(((to)))' - IN BOOLEAN MODE); - ---error ER_PARSE_ERROR -SELECT * FROM articles WHERE MATCH (title,body) AGAINST -('((((((((((((((((((((((((((((((((Security)))))))))))))))))))))))))))))))' - IN BOOLEAN MODE); ---error ER_PARSE_ERROR -SELECT * FROM articles WHERE MATCH (title,body) AGAINST -('(((((((((((((((((((((((((((((((((Security))))))))))))))))))))))))))))))))' - IN BOOLEAN MODE); - -# Test sub-expression boolean search. Find rows contain -# "MySQL" and "Well" or "MySQL" and "stands". But rank the -# doc with "Well" higher, and doc with "stands" lower. -SELECT * FROM articles WHERE MATCH (title,body) - AGAINST ('+ MySQL + (>Well < stands)' IN BOOLEAN MODE); - -# Test nested sub-expression. -SELECT * FROM articles WHERE MATCH (title,body) - AGAINST ('YourSQL + (+MySQL - (Tricks Security))' IN BOOLEAN MODE); - -# Find rows with "MySQL" but not "Tricks", "Security" nor "YourSQL" -SELECT * FROM articles WHERE MATCH (title,body) - AGAINST ('(+MySQL - (Tricks Security)) - YourSQL' IN BOOLEAN MODE); - -# Test non-word delimiter combined with negate "-" operator -# This should return the same result as 'mysql - (Security DBMS)' -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('mysql - Security&DBMS' IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('mysql - (Security DBMS)' IN BOOLEAN MODE); - -# Again, the operator sequence should not matter -SELECT * FROM articles WHERE MATCH (title,body) AGAINST (' - Security&DBMS + YourSQL' IN BOOLEAN MODE); - -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('+YourSQL - Security&DBMS' IN BOOLEAN MODE); - -# Test query expansion -SELECT COUNT(*) FROM articles - WHERE MATCH (title,body) - AGAINST ('database' WITH QUERY EXPANSION); - -INSERT INTO articles (title,body) VALUES - ('test query expansion','for database ...'); - -# This query will return result containing word "database" as -# the query expand from "test" to words in document just -# inserted above -SELECT * FROM articles - WHERE MATCH (title,body) - AGAINST ('test' WITH QUERY EXPANSION); - -# This is to test the proximity search, search two word -# "following" and "comparison" within 19 character space -SELECT * FROM articles - WHERE MATCH (title,body) - AGAINST ('"following comparison"@3' IN BOOLEAN MODE); - -# This is to test the proximity search, search two word -# "following" and "comparison" within 19 character space -# This search should come with no return result -SELECT * FROM articles - WHERE MATCH (title,body) - AGAINST ('"following comparison"@2' IN BOOLEAN MODE); - -# This is to test the phrase search, searching phrase -# "following database" -SELECT * FROM articles - WHERE MATCH (title,body) - AGAINST ('"following database"' IN BOOLEAN MODE); - -# Insert into table with similar word of different distances -INSERT INTO articles (title,body) VALUES - ('test proximity search, test, proximity and phrase', - 'search, with proximity innodb'); - -INSERT INTO articles (title,body) VALUES - ('test my proximity fts new search, test, proximity and phrase', - 'search, with proximity innodb'); - -INSERT INTO articles (title,body) VALUES - ('test more of proximity fts search, test, more proximity and phrase', - 'search, with proximity innodb'); - -# This should only return the first document -SELECT * FROM articles - WHERE MATCH (title,body) - AGAINST ('"proximity search"@3' IN BOOLEAN MODE); - -# This would return no document -SELECT * FROM articles - WHERE MATCH (title,body) - AGAINST ('"proximity search"@2' IN BOOLEAN MODE); - -# This give you all three documents -SELECT * FROM articles - WHERE MATCH (title,body) - AGAINST ('"proximity search"@5' IN BOOLEAN MODE); - -# Similar boundary testing for the words -SELECT * FROM articles - WHERE MATCH (title,body) - AGAINST ('"test proximity"@5' IN BOOLEAN MODE); - -# No document will be returned -SELECT * FROM articles - WHERE MATCH (title,body) - AGAINST ('"test proximity"@1' IN BOOLEAN MODE); - -# All three documents will be returned -SELECT * FROM articles - WHERE MATCH (title,body) - AGAINST ('"test proximity"@4' IN BOOLEAN MODE); - -# Only two document will be returned. -SELECT * FROM articles - WHERE MATCH (title,body) - AGAINST ('"test proximity"@3' IN BOOLEAN MODE); - -# Test with more word The last document will return, please notice there -# is no ordering requirement for proximity search. -SELECT * FROM articles - WHERE MATCH (title,body) - AGAINST ('"more test proximity"@4' IN BOOLEAN MODE); - -SELECT * FROM articles - WHERE MATCH (title,body) - AGAINST ('"more test proximity"@3' IN BOOLEAN MODE); - -# The phrase search will not require exact word ordering -SELECT * FROM articles - WHERE MATCH (title,body) - AGAINST ('"more test proximity"' IN BOOLEAN MODE); +let $basic_stage= select_3; +--source basic.inc drop table articles; diff --git a/mysql-test/suite/innodb_fts/t/crash_recovery.test b/mysql-test/suite/innodb_fts/t/crash_recovery.test index 0e32608a81a..7bece572827 100644 --- a/mysql-test/suite/innodb_fts/t/crash_recovery.test +++ b/mysql-test/suite/innodb_fts/t/crash_recovery.test @@ -7,6 +7,7 @@ # The embedded server tests do not support restarting. --source include/not_embedded.inc --source include/maybe_debug.inc +--source include/maybe_versioning.inc FLUSH TABLES; # Following are test for crash recovery on FTS index, the first scenario @@ -22,6 +23,16 @@ CREATE TABLE articles ( FULLTEXT (title,body) ) ENGINE=InnoDB; +let $vers= $MTR_COMBINATION_VERS + $MTR_COMBINATION_VERS_TRX; +if ($vers) +{ + --disable_query_log + INSERT INTO articles (title,body) VALUES + ('history','Deleted row ...'); + DELETE FROM articles; + --enable_query_log +} + # Drop the FTS index before more insertion. The FTS_DOC_ID should # be kept DROP INDEX title ON articles; @@ -59,6 +70,13 @@ INSERT INTO articles (title,body) VALUES # Recreate fulltext index to see if everything is OK CREATE FULLTEXT INDEX idx ON articles (title,body); +if ($vers) +{ + --disable_query_log + UPDATE articles SET id= id - 1; + --enable_query_log +} + # Should return 3 rows SELECT * FROM articles WHERE MATCH (title,body) @@ -98,6 +116,13 @@ disconnect dml; INSERT INTO articles (title,body) VALUES ('MySQL Tutorial','DBMS stands for DataBase ...'); +if ($vers) +{ + --disable_query_log + UPDATE articles SET id= id - 1 WHERE id > 8; + --enable_query_log +} + # Should return 6 rows SELECT * FROM articles WHERE MATCH (title,body) @@ -134,6 +159,15 @@ BEGIN; INSERT INTO articles VALUES (100, 200, 'MySQL Tutorial','DBMS stands for DataBase ...'); +if ($vers) +{ + --disable_query_log + DELETE FROM articles WHERE id = 100; + INSERT INTO articles VALUES + (100, 200, 'MySQL Tutorial','DBMS stands for DataBase ...'); + --enable_query_log +} + connect(dml2, localhost, root,,); --echo # diff --git a/mysql-test/suite/innodb_fts/t/create.test b/mysql-test/suite/innodb_fts/t/create.test index 38c93de4982..710fd9cb99b 100644 --- a/mysql-test/suite/innodb_fts/t/create.test +++ b/mysql-test/suite/innodb_fts/t/create.test @@ -1,4 +1,5 @@ --source include/have_innodb.inc +--source include/maybe_versioning.inc SET NAMES utf8mb4; --echo # diff --git a/mysql-test/suite/innodb_fts/t/fulltext2.test b/mysql-test/suite/innodb_fts/t/fulltext2.test index 25a4d5b24f9..a66f804b7ff 100644 --- a/mysql-test/suite/innodb_fts/t/fulltext2.test +++ b/mysql-test/suite/innodb_fts/t/fulltext2.test @@ -7,6 +7,7 @@ # --source include/have_innodb.inc +--source include/maybe_versioning.inc CREATE TABLE t1 ( i int(10) unsigned not null auto_increment primary key, diff --git a/mysql-test/suite/innodb_fts/t/fulltext3.test b/mysql-test/suite/innodb_fts/t/fulltext3.test index 9c7941d7b5c..f28ca2c7d77 100644 --- a/mysql-test/suite/innodb_fts/t/fulltext3.test +++ b/mysql-test/suite/innodb_fts/t/fulltext3.test @@ -3,6 +3,7 @@ # test of new fulltext search features # --source include/have_innodb.inc +--source include/maybe_versioning.inc --disable_warnings DROP TABLE IF EXISTS t1; diff --git a/mysql-test/suite/innodb_fts/t/fulltext_cache.test b/mysql-test/suite/innodb_fts/t/fulltext_cache.test index fa7ad49e881..37926c1e7f1 100644 --- a/mysql-test/suite/innodb_fts/t/fulltext_cache.test +++ b/mysql-test/suite/innodb_fts/t/fulltext_cache.test @@ -2,6 +2,7 @@ # Bugreport due to Roy Nasser # --source include/have_innodb.inc +--source include/maybe_versioning.inc --disable_warnings drop table if exists t1, t2; diff --git a/mysql-test/suite/innodb_fts/t/fulltext_distinct.test b/mysql-test/suite/innodb_fts/t/fulltext_distinct.test index f6232704543..bb390a08384 100644 --- a/mysql-test/suite/innodb_fts/t/fulltext_distinct.test +++ b/mysql-test/suite/innodb_fts/t/fulltext_distinct.test @@ -3,6 +3,7 @@ # bug reported by Tibor Simko # --source include/have_innodb.inc +--source include/maybe_versioning.inc --disable_warnings DROP TABLE IF EXISTS t1, t2; diff --git a/mysql-test/suite/innodb_fts/t/fulltext_left_join.test b/mysql-test/suite/innodb_fts/t/fulltext_left_join.test index 23bbd5ddc10..0a1e1748769 100644 --- a/mysql-test/suite/innodb_fts/t/fulltext_left_join.test +++ b/mysql-test/suite/innodb_fts/t/fulltext_left_join.test @@ -2,6 +2,7 @@ # Test for bug from Jean-Cédric COSTA # --source include/have_innodb.inc +--source include/maybe_versioning.inc --disable_warnings drop table if exists t1, t2; diff --git a/mysql-test/suite/innodb_fts/t/fulltext_multi.test b/mysql-test/suite/innodb_fts/t/fulltext_multi.test index 274027ea10b..81ab7e1b071 100644 --- a/mysql-test/suite/innodb_fts/t/fulltext_multi.test +++ b/mysql-test/suite/innodb_fts/t/fulltext_multi.test @@ -1,5 +1,6 @@ # several FULLTEXT indexes in one table test --source include/have_innodb.inc +--source include/maybe_versioning.inc --disable_warnings DROP TABLE IF EXISTS t1; diff --git a/mysql-test/suite/innodb_fts/t/fulltext_order_by.test b/mysql-test/suite/innodb_fts/t/fulltext_order_by.test index d2194f22e2a..f14681b934d 100644 --- a/mysql-test/suite/innodb_fts/t/fulltext_order_by.test +++ b/mysql-test/suite/innodb_fts/t/fulltext_order_by.test @@ -1,5 +1,6 @@ --source include/have_innodb.inc +--source include/maybe_versioning.inc --disable_warnings DROP TABLE IF EXISTS t1,t2,t3; diff --git a/mysql-test/suite/innodb_fts/t/fulltext_update.test b/mysql-test/suite/innodb_fts/t/fulltext_update.test index 336e8de1d1b..bda97cd4a21 100644 --- a/mysql-test/suite/innodb_fts/t/fulltext_update.test +++ b/mysql-test/suite/innodb_fts/t/fulltext_update.test @@ -2,6 +2,7 @@ # Test for bug by voi@ims.at # --source include/have_innodb.inc +--source include/maybe_versioning.inc --disable_warnings drop table if exists test; diff --git a/mysql-test/suite/innodb_fts/t/fulltext_var.test b/mysql-test/suite/innodb_fts/t/fulltext_var.test index 2b94aa58424..e8e4bf93303 100644 --- a/mysql-test/suite/innodb_fts/t/fulltext_var.test +++ b/mysql-test/suite/innodb_fts/t/fulltext_var.test @@ -2,6 +2,7 @@ # Fulltext configurable parameters # --source include/have_innodb.inc +--source include/maybe_versioning.inc # Save ft_boolean_syntax variable let $saved_ft_boolean_syntax=`select @@global.ft_boolean_syntax`; diff --git a/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test b/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test index 1ed164492d5..17a800c7663 100644 --- a/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test +++ b/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test @@ -1,6 +1,7 @@ # This is the DDL function tests for innodb FTS -- source include/have_innodb.inc +-- source include/maybe_versioning.inc # Create FTS table CREATE TABLE fts_test ( diff --git a/mysql-test/suite/innodb_fts/t/innodb-fts-fic.test b/mysql-test/suite/innodb_fts/t/innodb-fts-fic.test index 669aa69e835..2d94c21398c 100644 --- a/mysql-test/suite/innodb_fts/t/innodb-fts-fic.test +++ b/mysql-test/suite/innodb_fts/t/innodb-fts-fic.test @@ -1,6 +1,7 @@ # This is the basic function tests for innodb FTS -- source include/have_innodb.inc +-- source include/maybe_versioning.inc 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`.`articles`"); diff --git a/mysql-test/suite/innodb_fts/t/innodb-fts-stopword.opt b/mysql-test/suite/innodb_fts/t/innodb-fts-stopword.opt deleted file mode 100644 index 2b0652d08c3..00000000000 --- a/mysql-test/suite/innodb_fts/t/innodb-fts-stopword.opt +++ /dev/null @@ -1 +0,0 @@ ---loose-innodb-ft-default-stopword diff --git a/mysql-test/suite/innodb_fts/t/innodb-fts-stopword.test b/mysql-test/suite/innodb_fts/t/innodb-fts-stopword.test deleted file mode 100644 index de14deab328..00000000000 --- a/mysql-test/suite/innodb_fts/t/innodb-fts-stopword.test +++ /dev/null @@ -1,664 +0,0 @@ -# This is the basic function tests for innodb FTS - --- source include/have_innodb.inc - - -select * from information_schema.innodb_ft_default_stopword; - -# 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 ...'); - -# "the" is in the default stopword, it would not be selected -SELECT * FROM articles WHERE MATCH (title,body) - AGAINST ('the' IN NATURAL LANGUAGE MODE); - -let $innodb_ft_server_stopword_table_orig=`select @@innodb_ft_server_stopword_table`; -let $innodb_ft_enable_stopword_orig=`select @@innodb_ft_enable_stopword`; -let $innodb_ft_user_stopword_table_orig=`select @@innodb_ft_user_stopword_table`; - -select @@innodb_ft_server_stopword_table; -select @@innodb_ft_enable_stopword; -select @@innodb_ft_user_stopword_table; - -# Provide user defined stopword table, if not (correctly) defined, -# it will be rejected ---error 1231 -set global innodb_ft_server_stopword_table = "not_defined"; - -# Define a correct formatted user stopword table -create table user_stopword(value varchar(30)) engine = innodb; - -# The set operation should be successful -set global innodb_ft_server_stopword_table = "test/user_stopword"; - -drop index title on articles; - -create fulltext index idx on articles(title, body); - -# Now we should be able to find "the" -SELECT * FROM articles WHERE MATCH (title,body) - AGAINST ('the' IN NATURAL LANGUAGE MODE); - -# Nothing inserted into the default stopword, so essentially -# nothing get screened. The new stopword could only be -# effective for table created thereafter -CREATE TABLE articles_2 ( - id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, - title VARCHAR(200), - body TEXT, - FULLTEXT (title,body) - ) ENGINE=InnoDB; - -INSERT INTO articles_2 (title, body) - VALUES ('test for stopwords','this is it...'); - -# Now we can find record with "this" -SELECT * FROM articles_2 WHERE MATCH (title,body) - AGAINST ('this' IN NATURAL LANGUAGE MODE); - -# Ok, let's instantiate some value into user supplied stop word -# table -insert into user_stopword values("this"); - -# Ok, let's repeat with the new table again. -CREATE TABLE articles_3 ( - id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, - title VARCHAR(200), - body TEXT, - FULLTEXT (title,body) - ) ENGINE=InnoDB; - -INSERT INTO articles_3 (title, body) - VALUES ('test for stopwords','this is it...'); - -# Now we should NOT find record with "this" -SELECT * FROM articles_3 WHERE MATCH (title,body) - AGAINST ('this' IN NATURAL LANGUAGE MODE); - -# Test session level stopword control "innodb_user_stopword_table" -create table user_stopword_session(value varchar(30)) engine = innodb; - -insert into user_stopword_session values("session"); - -set session innodb_ft_user_stopword_table="test/user_stopword_session"; - -CREATE TABLE articles_4 ( - id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, - title VARCHAR(200), - body TEXT, - FULLTEXT (title,body) - ) ENGINE=InnoDB; - -INSERT INTO articles_4 (title, body) - VALUES ('test for session stopwords','this should also be excluded...'); - -# "session" is excluded -SELECT * FROM articles_4 WHERE MATCH (title,body) - AGAINST ('session' IN NATURAL LANGUAGE MODE); - -# But we can find record with "this" -SELECT * FROM articles_4 WHERE MATCH (title,body) - AGAINST ('this' IN NATURAL LANGUAGE MODE); - ---connect (con1,localhost,root,,) -CREATE TABLE articles_5 ( - id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, - title VARCHAR(200), - body TEXT, - FULLTEXT (title,body) - ) ENGINE=InnoDB; - -INSERT INTO articles_5 (title, body) - VALUES ('test for session stopwords','this should also be excluded...'); - -# "session" should be found since the stopword table is session specific -SELECT * FROM articles_5 WHERE MATCH (title,body) - AGAINST ('session' IN NATURAL LANGUAGE MODE); - ---connection default -drop table articles; -drop table articles_2; -drop table articles_3; -drop table articles_4; -drop table articles_5; -drop table user_stopword; -drop table user_stopword_session; - -eval SET GLOBAL innodb_ft_enable_stopword=$innodb_ft_enable_stopword_orig; -eval SET GLOBAL innodb_ft_server_stopword_table=default; - -#--------------------------------------------------------------------------------------- -# Behavior : -# The stopword is loaded into memory at -# 1) create fulltext index time, -# 2) boot server, -# 3) first time FTs is used -# So if you already created a FTS index, and then turn off stopword -# or change stopword table content it won't affect the FTS -# that already created since the stopword list are already loaded. -# It will only affect the new FTS index created after you changed -# the settings. - -# Create FTS table -CREATE TABLE articles ( - id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, - title VARCHAR(200), - body TEXT, - FULLTEXT `idx` (title,body) - ) ENGINE=InnoDB; - -SHOW CREATE TABLE articles; - -# Insert six rows -INSERT INTO articles (title,body) VALUES - ('MySQL from Tutorial','DBMS stands for DataBase ...') , - ('when To Use MySQL Well','After that you went through a ...'), - ('where will Optimizing MySQL','In what 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 ...'); - -# Case : server_stopword=default -# Try to Search default stopword from innodb, "where", "will", "what" -# and "when" are all stopwords -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will"); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when"); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION); -# boolean No result expected -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE); -# no result expected -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE); -# no result expected -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE); - -INSERT INTO articles(title,body) values ('the record will' , 'not index the , will words'); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"the will"@11' IN BOOLEAN MODE); -# Not going to update as where condition can not find record -UPDATE articles SET title = "update the record" , body = 'to see will is indexed or not' -WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE); -# Update the record -UPDATE articles SET title = "update the record" , body = 'to see will is indexed or not' -WHERE id = 7; -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will'); -# Delete will not work as where condition do not return -DELETE FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE); -SELECT * FROM articles WHERE id = 7; -DELETE FROM articles WHERE id = 7; - - - -# Case : Turn OFF stopword list variable and search stopword on OLD index. -# disable stopword list -#SET global innodb_ft_server_stopword_table = ""; -SET SESSION innodb_ft_enable_stopword = 0; -select @@innodb_ft_enable_stopword; -#SET global innodb_ft_user_stopword_table = ""; - -# search default stopword with innodb_ft_enable_stopword is OFF. -# No records expected even though we turned OFF stopwod filtering -# (refer Behavior (at the top of the test) for explanation ) -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will"); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when"); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE); - -INSERT INTO articles(title,body) values ('the record will' , 'not index the , will words'); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"the will"@11' IN BOOLEAN MODE); -# Not going to update as where condition can not find record -UPDATE articles SET title = "update the record" , body = 'to see will is indexed or not' -WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE); -# Update the record -UPDATE articles SET title = "update the record" , body = 'to see will is indexed or not' -WHERE id = 8; -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will'); -SELECT * FROM articles WHERE id = 8; -# Delete will not work as where condition do not return -DELETE FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE); -SELECT * FROM articles WHERE id = 8; -DELETE FROM articles WHERE id = 8; - -# Case : Turn OFF stopword list variable and search stopword on NEW index. -# Drop index -ALTER TABLE articles DROP INDEX idx; -SHOW CREATE TABLE articles; - -# Create the FTS index Using Alter Table. -ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body); - -ANALYZE TABLE articles; - -# search default stopword with innodb_ft_enable_stopword is OFF. -# All records expected as stopwod filtering is OFF and we created -# new FTS index. -# (refer Behavior (at the top of the test) for explanation ) -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will"); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when"); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE); - -INSERT INTO articles(title,body) values ('the record will' , 'not index the , will words'); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"the will"@11' IN BOOLEAN MODE); -# Update will succeed. -UPDATE articles SET title = "update the record" , body = 'to see will is indexed or not' -WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE); - -SELECT COUNT(*),max(id) FROM articles; -# Update the record - uncommet on fix -#UPDATE articles SET title = "update the record" , body = 'to see will is indexed or not' -#WHERE id = 9; -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will'); -# Delete will succeed. -DELETE FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE); -SELECT * FROM articles WHERE id = 9; - - -DROP TABLE articles; - -eval SET SESSION innodb_ft_enable_stopword=$innodb_ft_enable_stopword_orig; -#eval SET GLOBAL innodb_ft_server_stopword_table=$innodb_ft_server_stopword_table_orig; -eval SET GLOBAL innodb_ft_server_stopword_table=default; -#eval SET GLOBAL innodb_ft_user_stopword_table=$innodb_ft_user_stopword_table_orig; -eval SET SESSION innodb_ft_user_stopword_table=default; - -#--------------------------------------------------------------------------------------- - -select @@innodb_ft_server_stopword_table; -select @@innodb_ft_enable_stopword; -select @@innodb_ft_user_stopword_table; - -# Create FTS table -CREATE TABLE articles ( - id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, - title VARCHAR(200), - body TEXT, - FULLTEXT `idx` (title,body) - ) ENGINE=InnoDB; - -# Insert six rows -INSERT INTO articles (title,body) VALUES - ('MySQL from Tutorial','DBMS stands for DataBase ...') , - ('when To Use MySQL Well','After that you went through a ...'), - ('where will Optimizing MySQL','In what 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 ...'); - -# No records expeced for select -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will'); -# Define a correct formatted user stopword table -create table user_stopword(value varchar(30)) engine = innodb; -# The set operation should be successful -set session innodb_ft_user_stopword_table = "test/user_stopword"; -# Define a correct formatted server stopword table -create table server_stopword(value varchar(30)) engine = innodb; -# The set operation should be successful -set global innodb_ft_server_stopword_table = "test/server_stopword"; -# Add values into user supplied stop word table -insert into user_stopword values("this"),("will"),("the"); - -# Drop existing index and create the FTS index Using Alter Table. -ALTER TABLE articles DROP INDEX idx; -ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will'); - -# Add values into server supplied stop word table -insert into server_stopword values("what"),("where"); -# Follwoing should return result as server stopword list was empty at create index time -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what'); - -# Delete stopword from user list -DELETE FROM user_stopword; -# Drop existing index and create the FTS index Using Alter Table. -ALTER TABLE articles DROP INDEX idx; -ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body); -# Follwoing should return result even though to server stopword list -# conatin these words. Session level stopword list takes priority -# Here user_stopword is set using innodb_ft_user_stopword_table -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what'); - -# Follwoing should return result as user stopword list was empty at create index time -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will'); - -# Add values into user supplied stop word table -insert into user_stopword values("this"),("will"),("the"); - -# Drop existing index and create the FTS index Using Alter Table. -ALTER TABLE articles DROP INDEX idx; -SET SESSION innodb_ft_enable_stopword = 0; -ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what'); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will'); - -# Session level stopword list takes priority -SET SESSION innodb_ft_enable_stopword = 1; -ALTER TABLE articles DROP INDEX idx; -ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what'); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will'); - -# Make user stopword list deafult so as to server stopword list takes priority -SET SESSION innodb_ft_enable_stopword = 1; -SET SESSION innodb_ft_user_stopword_table = default; -ALTER TABLE articles DROP INDEX idx; -ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what'); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will'); - - -DROP TABLE articles,user_stopword,server_stopword; - -# Restore Defaults -eval SET SESSION innodb_ft_enable_stopword=$innodb_ft_enable_stopword_orig; -eval SET GLOBAL innodb_ft_server_stopword_table=default; -eval SET SESSION innodb_ft_user_stopword_table=default; -select @@innodb_ft_server_stopword_table; -select @@innodb_ft_enable_stopword; -select @@innodb_ft_user_stopword_table; - -#--------------------------------------------------------------------------------------- -# Create FTS table -CREATE TABLE articles ( - id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, - title VARCHAR(200), - body TEXT, - FULLTEXT `idx` (title,body) - ) ENGINE=InnoDB; - -SHOW CREATE TABLE articles; - -# Insert six rows -INSERT INTO articles (title,body) VALUES - ('MySQL from Tutorial','DBMS stands for DataBase ...') , - ('when To Use MySQL Well','After that you went through a ...'), - ('where will Optimizing MySQL','In what 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 ...'); - -# No records expeced for select -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will'); -# Define a correct formatted user stopword table -create table user_stopword(value varchar(30)) engine = innodb; -# The set operation should be successful -set session innodb_ft_user_stopword_table = "test/user_stopword"; -insert into user_stopword values("mysqld"),("DBMS"); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what'); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+DBMS +mysql" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('mysqld'); - - -# Drop existing index and create the FTS index Using Alter Table. -# user stopword list will take effect. -ALTER TABLE articles DROP INDEX idx; -ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what'); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+DBMS +mysql" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('mysqld'); - -# set user stopword list empty -set session innodb_ft_user_stopword_table = default; -# Define a correct formatted user stopword table -create table server_stopword(value varchar(30)) engine = innodb; -# The set operation should be successful -set global innodb_ft_server_stopword_table = "test/server_stopword"; -insert into server_stopword values("root"),("properly"); -ALTER TABLE articles DROP INDEX idx; -ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what'); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+root +mysql" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('properly'); - - -# set user stopword list empty -set session innodb_ft_user_stopword_table = "test/user_stopword"; -# The set operation should be successful -set global innodb_ft_server_stopword_table = "test/server_stopword"; -# user stopword list take effect as its session level -# Result expected for select -ALTER TABLE articles DROP INDEX idx; -ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what'); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+root +mysql" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('properly'); - -# set user stopword list -set session innodb_ft_user_stopword_table = "test/user_stopword"; -DELETE FROM user_stopword; -# The set operation should be successful -set global innodb_ft_server_stopword_table = "test/server_stopword"; -DELETE FROM server_stopword; -# user stopword list take affect as its session level -ALTER TABLE articles DROP INDEX idx; -ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what'); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+root +mysql" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('properly'); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+DBMS +mysql" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('mysqld'); - -DROP TABLE articles,user_stopword,server_stopword; - -# Restore Values -eval SET SESSION innodb_ft_enable_stopword=$innodb_ft_enable_stopword_orig; -eval SET GLOBAL innodb_ft_server_stopword_table=default; -eval SET SESSION innodb_ft_user_stopword_table=default; - - -#------------------------------------------------------------------------------ -# FTS stopword list test - check varaibles across sessions - -# Create FTS table -CREATE TABLE articles ( - id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, - title VARCHAR(200), - body TEXT, - FULLTEXT `idx` (title,body) - ) ENGINE=InnoDB; - -SHOW CREATE TABLE articles; - -# Insert six rows -INSERT INTO articles (title,body) VALUES - ('MySQL from Tutorial','DBMS stands for DataBase ...') , - ('when To Use MySQL Well','After that you went through a ...'), - ('where will Optimizing MySQL','In what 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 ...'); - -# session varaible innodb_ft_enable_stopword=0 will take effect for new FTS index -SET SESSION innodb_ft_enable_stopword = 0; -select @@innodb_ft_enable_stopword; - -ALTER TABLE articles DROP INDEX idx; -ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body); - - ---connection con1 -select @@innodb_ft_enable_stopword; - -ANALYZE TABLE articles; - -# result expected as index created before setting innodb_ft_enable_stopword varaible off -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will"); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when"); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE); - -SET SESSION innodb_ft_enable_stopword = 1; -select @@innodb_ft_enable_stopword; -ALTER TABLE articles DROP INDEX idx; -ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body); -# no result expected turned innodb_ft_enable_stopword is ON -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will"); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when"); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE); - - ---connection default -select @@innodb_ft_enable_stopword; -# no result expected as word not indexed from connection 1 -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will"); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when"); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE); - -INSERT INTO articles(title,body) values ('the record will' , 'not index the , will words'); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"the will"@11' IN BOOLEAN MODE); - -SET SESSION innodb_ft_enable_stopword = 1; -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"the will"@11' IN BOOLEAN MODE); - - ---connection con1 -SET SESSION innodb_ft_enable_stopword = 1; -# Define a correct formatted user stopword table -create table user_stopword(value varchar(30)) engine = innodb; -# The set operation should be successful -set session innodb_ft_user_stopword_table = "test/user_stopword"; -# Add values into user supplied stop word table -insert into user_stopword values("this"),("will"),("the"); -# Drop existing index and create the FTS index Using Alter Table. -ALTER TABLE articles DROP INDEX idx; -ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body); -# no result expected as innodb_ft_user_stopword_table filter it -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will'); - - ---connection default -# no result expected as innodb_ft_user_stopword_table filter it from connection1 -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will'); -select @@innodb_ft_user_stopword_table; -# Define a correct formatted user stopword table -create table user_stopword_1(value varchar(30)) engine = innodb; -# The set operation should be successful -set session innodb_ft_user_stopword_table = "test/user_stopword_1"; -insert into user_stopword_1 values("when"); -SET SESSION innodb_ft_enable_stopword = 1; -# result expected -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+when" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('when'); -# Drop existing index and create the FTS index Using Alter Table. -ALTER TABLE articles DROP INDEX idx; -ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body); -# no result expected -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+when" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('when'); - ---connection con1 -SET SESSION innodb_ft_enable_stopword = 1; -SET SESSION innodb_ft_user_stopword_table=default; -select @@innodb_ft_user_stopword_table; -select @@innodb_ft_server_stopword_table; -# Define a correct formatted server stopword table -create table server_stopword(value varchar(30)) engine = innodb; -# The set operation should be successful -SET GLOBAL innodb_ft_server_stopword_table = "test/server_stopword"; -select @@innodb_ft_server_stopword_table; -insert into server_stopword values("when"),("the"); -# Drop existing index and create the FTS index Using Alter Table. -ALTER TABLE articles DROP INDEX idx; -ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body); -# no result expected -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+when" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('the'); - -disconnect con1; ---source include/wait_until_disconnected.inc - ---connection default -SET SESSION innodb_ft_enable_stopword = 1; -SET SESSION innodb_ft_user_stopword_table=default; -select @@innodb_ft_server_stopword_table; -# result expected -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+will +where" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('where'); -insert into server_stopword values("where"),("will"); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+will +where" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('where'); -ALTER TABLE articles DROP INDEX idx; -ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body); -# no result expected -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+when" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('the'); -SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+will +where" IN BOOLEAN MODE); -SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('where'); - - -DROP TABLE articles,user_stopword,user_stopword_1,server_stopword; - -# Restore Values -eval SET SESSION innodb_ft_enable_stopword=$innodb_ft_enable_stopword_orig; -eval SET GLOBAL innodb_ft_server_stopword_table=default; -eval SET SESSION innodb_ft_user_stopword_table=default; - diff --git a/mysql-test/suite/innodb_fts/t/innodb_ft_aux_table.test b/mysql-test/suite/innodb_fts/t/innodb_ft_aux_table.test index 48964aef4fd..f9447aada60 100644 --- a/mysql-test/suite/innodb_fts/t/innodb_ft_aux_table.test +++ b/mysql-test/suite/innodb_fts/t/innodb_ft_aux_table.test @@ -1,4 +1,5 @@ --source include/have_innodb.inc +--source include/maybe_versioning.inc CREATE TABLE t1 (v VARCHAR(100), FULLTEXT INDEX (v)) ENGINE=InnoDB; diff --git a/mysql-test/suite/innodb_fts/t/innodb_fts_large_records.test b/mysql-test/suite/innodb_fts/t/innodb_fts_large_records.test index e200cff6c39..c84cd0685ed 100644 --- a/mysql-test/suite/innodb_fts/t/innodb_fts_large_records.test +++ b/mysql-test/suite/innodb_fts/t/innodb_fts_large_records.test @@ -3,6 +3,7 @@ # b) more words across records --source include/have_innodb.inc +--source include/maybe_versioning.inc --disable_warnings DROP TABLE IF EXISTS t1; diff --git a/mysql-test/suite/innodb_fts/t/innodb_fts_multiple_index.test b/mysql-test/suite/innodb_fts/t/innodb_fts_multiple_index.test index c8293655d1b..f9535c729ff 100644 --- a/mysql-test/suite/innodb_fts/t/innodb_fts_multiple_index.test +++ b/mysql-test/suite/innodb_fts/t/innodb_fts_multiple_index.test @@ -2,6 +2,7 @@ # Test With two FTS index on same table + alter/create/drop index + tnx #------------------------------------------------------------------------------ --source include/have_innodb.inc +--source include/maybe_versioning.inc --disable_warnings drop table if exists t1; diff --git a/mysql-test/suite/innodb_fts/t/innodb_fts_proximity.test b/mysql-test/suite/innodb_fts/t/innodb_fts_proximity.test index 20eee3fac23..e3d8eb0c13b 100644 --- a/mysql-test/suite/innodb_fts/t/innodb_fts_proximity.test +++ b/mysql-test/suite/innodb_fts/t/innodb_fts_proximity.test @@ -1,4 +1,5 @@ --source include/have_innodb.inc +--source include/maybe_versioning.inc # This is the DDL function tests for innodb FTS # Functional testing with FTS proximity search using '@' diff --git a/mysql-test/suite/innodb_fts/t/innodb_fts_result_cache_limit.test b/mysql-test/suite/innodb_fts/t/innodb_fts_result_cache_limit.test index 669808edbf6..1ec37532a71 100644 --- a/mysql-test/suite/innodb_fts/t/innodb_fts_result_cache_limit.test +++ b/mysql-test/suite/innodb_fts/t/innodb_fts_result_cache_limit.test @@ -4,6 +4,7 @@ # Must have debug code to use SET SESSION debug --source include/have_debug.inc +--source include/maybe_versioning.inc # Create FTS table CREATE TABLE t1 ( diff --git a/mysql-test/suite/innodb_fts/t/innodb_fts_stopword_charset.test b/mysql-test/suite/innodb_fts/t/innodb_fts_stopword_charset.test index 16ee91c30f4..3fe99dab2c3 100644 --- a/mysql-test/suite/innodb_fts/t/innodb_fts_stopword_charset.test +++ b/mysql-test/suite/innodb_fts/t/innodb_fts_stopword_charset.test @@ -4,6 +4,7 @@ # Embedded server tests do not support restarting --source include/not_embedded.inc +--source include/maybe_versioning.inc SELECT @@innodb_ft_server_stopword_table; SELECT @@innodb_ft_enable_stopword; diff --git a/mysql-test/suite/innodb_fts/t/innodb_fts_transaction.test b/mysql-test/suite/innodb_fts/t/innodb_fts_transaction.test index 11571f346a2..026aeb635cd 100644 --- a/mysql-test/suite/innodb_fts/t/innodb_fts_transaction.test +++ b/mysql-test/suite/innodb_fts/t/innodb_fts_transaction.test @@ -5,6 +5,7 @@ # 3) UNCOMMITTED RECORDS CAN BE SEEN WITH QURIES WHICH DO NOT USE FTS INDEX # this behavior do not break integratity of tables and "select" which do not use FTS still can view them. --source include/have_innodb.inc +--source include/maybe_versioning.inc --disable_warnings diff --git a/mysql-test/suite/innodb_fts/t/misc_debug.test b/mysql-test/suite/innodb_fts/t/misc_debug.test index cf3651e14a2..5e59ae6aba1 100644 --- a/mysql-test/suite/innodb_fts/t/misc_debug.test +++ b/mysql-test/suite/innodb_fts/t/misc_debug.test @@ -7,6 +7,7 @@ --source include/have_debug.inc --source include/have_debug_sync.inc --source include/count_sessions.inc +--source include/maybe_versioning.inc # Following test is for Bug 14668777 - ASSERT ON IB_VECTOR_SIZE( # TABLE->FTS->INDEXES, ALTER TABLE diff --git a/mysql-test/suite/innodb_fts/t/stopword.inc b/mysql-test/suite/innodb_fts/t/stopword.inc new file mode 100644 index 00000000000..774501ade85 --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/stopword.inc @@ -0,0 +1,55 @@ +if ($stopword_stage == create_table) +{ +call mtr.add_suppression("\\[ERROR\\] InnoDB: user stopword table not_defined does not exist."); +call mtr.add_suppression("\\[ERROR\\] InnoDB: user stopword table test/user_stopword_session does not exist."); + +select * from information_schema.innodb_ft_default_stopword; + +# Create FTS table +eval CREATE TABLE $stopword_table ( + id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, + title VARCHAR(200), + body TEXT, + FULLTEXT (title,body) + )$create_options ENGINE=InnoDB; + +# Insert six rows +eval INSERT INTO $stopword_table (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 ...'); + +# "the" is in the default stopword, it would not be selected +eval SELECT * FROM $stopword_table WHERE MATCH (title,body) + AGAINST ('the' IN NATURAL LANGUAGE MODE); + +# Provide user defined stopword table, if not (correctly) defined, +# it will be rejected +--error ER_WRONG_VALUE_FOR_VAR +set global innodb_ft_server_stopword_table = "not_defined"; +set global innodb_ft_server_stopword_table = NULL; + +# Define a correct formatted user stopword table +eval create table user_stopword(value varchar(30))$create_options engine = innodb; + +# The set operation should be successful +set global innodb_ft_server_stopword_table = "test/user_stopword"; + +eval drop index title on $stopword_table; + +eval create fulltext index idx on $stopword_table(title, body); +} + +if ($stopword_stage == select_1) +{ +--error 0, ER_INDEX_CORRUPT +eval SELECT * FROM $stopword_table WHERE MATCH (title,body) + AGAINST ('the' IN NATURAL LANGUAGE MODE); +--error 0, ER_INDEX_CORRUPT +eval SELECT * FROM $stopword_table WHERE MATCH (title,body) + AGAINST ('this' IN NATURAL LANGUAGE MODE); + +} diff --git a/mysql-test/suite/innodb_fts/t/stopword.test b/mysql-test/suite/innodb_fts/t/stopword.test index ca01da80734..9f8bd89b816 100644 --- a/mysql-test/suite/innodb_fts/t/stopword.test +++ b/mysql-test/suite/innodb_fts/t/stopword.test @@ -1,52 +1,16 @@ # This is the basic function tests for innodb FTS -- source include/have_innodb.inc - -call mtr.add_suppression("\\[ERROR\\] InnoDB: user stopword table not_defined does not exist."); -call mtr.add_suppression("\\[ERROR\\] InnoDB: user stopword table test/user_stopword_session does not exist."); - -select * from information_schema.innodb_ft_default_stopword; - -# 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 ...'); - -# "the" is in the default stopword, it would not be selected -SELECT * FROM articles WHERE MATCH (title,body) - AGAINST ('the' IN NATURAL LANGUAGE MODE); +-- let $modify_create_table= 1 +-- source include/maybe_versioning.inc SET @innodb_ft_server_stopword_table_orig=@@innodb_ft_server_stopword_table; SET @innodb_ft_enable_stopword_orig=@@innodb_ft_enable_stopword; SET @innodb_ft_user_stopword_table_orig=@@innodb_ft_user_stopword_table; -# Provide user defined stopword table, if not (correctly) defined, -# it will be rejected ---error ER_WRONG_VALUE_FOR_VAR -set global innodb_ft_server_stopword_table = "not_defined"; -set global innodb_ft_server_stopword_table = NULL; - -# Define a correct formatted user stopword table -create table user_stopword(value varchar(30)) engine = innodb; - -# The set operation should be successful -set global innodb_ft_server_stopword_table = "test/user_stopword"; - -drop index title on articles; - -create fulltext index idx on articles(title, body); +let $stopword_table= articles; +let $stopword_stage= create_table; +--source stopword.inc # Now we should be able to find "the" SELECT * FROM articles WHERE MATCH (title,body) @@ -55,12 +19,12 @@ SELECT * FROM articles WHERE MATCH (title,body) # Nothing inserted into the default stopword, so essentially # nothing get screened. The new stopword could only be # effective for table created thereafter -CREATE TABLE articles_2 ( +eval CREATE TABLE articles_2 ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title VARCHAR(200), body TEXT, FULLTEXT (title,body) - ) ENGINE=InnoDB; + )$create_options ENGINE=InnoDB; INSERT INTO articles_2 (title, body) VALUES ('test for stopwords','this is it...'); @@ -71,15 +35,17 @@ SELECT * FROM articles_2 WHERE MATCH (title,body) # Ok, let's instantiate some value into user supplied stop word # table +insert into user_stopword values("the"); +delete from user_stopword; insert into user_stopword values("this"); # Ok, let's repeat with the new table again. -CREATE TABLE articles_3 ( +eval CREATE TABLE articles_3 ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title VARCHAR(200), body TEXT, FULLTEXT (title,body) - ) ENGINE=InnoDB; + )$create_options ENGINE=InnoDB; INSERT INTO articles_3 (title, body) VALUES ('test for stopwords','this is it...'); @@ -89,18 +55,20 @@ SELECT * FROM articles_3 WHERE MATCH (title,body) AGAINST ('this' IN NATURAL LANGUAGE MODE); # Test session level stopword control "innodb_user_stopword_table" -create table user_stopword_session(value varchar(30)) engine = innodb; +eval create table user_stopword_session(value varchar(30))$create_options engine = innodb; +insert into user_stopword values("this"); +delete from user_stopword; insert into user_stopword_session values("session"); set session innodb_ft_user_stopword_table="test/user_stopword_session"; -CREATE TABLE articles_4 ( +eval CREATE TABLE articles_4 ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title VARCHAR(200), body TEXT, FULLTEXT (title,body) - ) ENGINE=InnoDB; + )$create_options ENGINE=InnoDB; INSERT INTO articles_4 (title, body) VALUES ('test for session stopwords','this should also be excluded...'); @@ -114,12 +82,12 @@ SELECT * FROM articles_4 WHERE MATCH (title,body) AGAINST ('this' IN NATURAL LANGUAGE MODE); --connect (con1,localhost,root,,) -CREATE TABLE articles_5 ( +eval CREATE TABLE articles_5 ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title VARCHAR(200), body TEXT, FULLTEXT (title,body) - ) ENGINE=InnoDB; + )$create_options ENGINE=InnoDB; INSERT INTO articles_5 (title, body) VALUES ('test for session stopwords','this should also be excluded...'); @@ -153,12 +121,12 @@ SET GLOBAL innodb_ft_server_stopword_table=default; # the settings. # Create FTS table -CREATE TABLE articles ( +eval CREATE TABLE articles ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title VARCHAR(200), body TEXT, FULLTEXT `idx` (title,body) - ) ENGINE=InnoDB; + )$create_options ENGINE=InnoDB; SHOW CREATE TABLE articles; @@ -292,12 +260,12 @@ SET GLOBAL innodb_ft_user_stopword_table=@innodb_ft_user_stopword_table_orig; SET SESSION innodb_ft_user_stopword_table=default; # Create FTS table -CREATE TABLE articles ( +eval CREATE TABLE articles ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title VARCHAR(200), body TEXT, FULLTEXT `idx` (title,body) - ) ENGINE=InnoDB; + )$create_options ENGINE=InnoDB; # Insert six rows INSERT INTO articles (title,body) VALUES @@ -312,14 +280,16 @@ INSERT INTO articles (title,body) VALUES SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE); SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will'); # Define a correct formatted user stopword table -create table user_stopword(value varchar(30)) engine = innodb; +eval create table user_stopword(value varchar(30))$create_options engine = innodb; # The set operation should be successful set session innodb_ft_user_stopword_table = "test/user_stopword"; # Define a correct formatted server stopword table -create table server_stopword(value varchar(30)) engine = innodb; +eval create table server_stopword(value varchar(30))$create_options engine = innodb; # The set operation should be successful set global innodb_ft_server_stopword_table = "test/server_stopword"; # Add values into user supplied stop word table +insert into user_stopword values("when"),("where"); +delete from user_stopword; insert into user_stopword values("this"),("will"),("the"); # Drop existing index and create the FTS index Using Alter Table. @@ -390,12 +360,12 @@ SET SESSION innodb_ft_user_stopword_table=default; #--------------------------------------------------------------------------------------- # Create FTS table -CREATE TABLE articles ( +eval CREATE TABLE articles ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title VARCHAR(200), body TEXT, FULLTEXT `idx` (title,body) - ) ENGINE=InnoDB; + )$create_options ENGINE=InnoDB; SHOW CREATE TABLE articles; @@ -412,7 +382,7 @@ INSERT INTO articles (title,body) VALUES SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE); SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will'); # Define a correct formatted user stopword table -create table user_stopword(value varchar(30)) engine = innodb; +eval create table user_stopword(value varchar(30))$create_options engine = innodb; # The set operation should be successful set session innodb_ft_user_stopword_table = "test/user_stopword"; insert into user_stopword values("mysqld"),("DBMS"); @@ -434,7 +404,7 @@ SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('mysqld'); # set user stopword list empty set session innodb_ft_user_stopword_table = default; # Define a correct formatted user stopword table -create table server_stopword(value varchar(30)) engine = innodb; +eval create table server_stopword(value varchar(30))$create_options engine = innodb; # The set operation should be successful set global innodb_ft_server_stopword_table = "test/server_stopword"; insert into server_stopword values("root"),("properly"); @@ -487,12 +457,12 @@ SET SESSION innodb_ft_user_stopword_table=default; # FTS stopword list test - check varaibles across sessions # Create FTS table -CREATE TABLE articles ( +eval CREATE TABLE articles ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title VARCHAR(200), body TEXT, FULLTEXT `idx` (title,body) - ) ENGINE=InnoDB; + )$create_options ENGINE=InnoDB; SHOW CREATE TABLE articles; @@ -573,7 +543,7 @@ SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"the will"@11' IN BOOL --connection con1 SET SESSION innodb_ft_enable_stopword = 1; # Define a correct formatted user stopword table -create table user_stopword(value varchar(30)) engine = innodb; +eval create table user_stopword(value varchar(30))$create_options engine = innodb; # The set operation should be successful set session innodb_ft_user_stopword_table = "test/user_stopword"; # Add values into user supplied stop word table @@ -593,7 +563,7 @@ SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will'); select @@innodb_ft_user_stopword_table; # Define a correct formatted user stopword table -create table user_stopword_1(value varchar(30)) engine = innodb; +eval create table user_stopword_1(value varchar(30))$create_options engine = innodb; # The set operation should be successful set session innodb_ft_user_stopword_table = "test/user_stopword_1"; insert into user_stopword_1 values("when"); @@ -615,7 +585,7 @@ SET SESSION innodb_ft_user_stopword_table=default; select @@innodb_ft_user_stopword_table; select @@innodb_ft_server_stopword_table; # Define a correct formatted server stopword table -create table server_stopword(value varchar(30)) engine = innodb; +eval create table server_stopword(value varchar(30))$create_options engine = innodb; # The set operation should be successful SET GLOBAL innodb_ft_server_stopword_table = "test/server_stopword"; select @@innodb_ft_server_stopword_table; diff --git a/mysql-test/suite/innodb_fts/t/sync.test b/mysql-test/suite/innodb_fts/t/sync.test index 6929dce31b8..3bd5b56a21b 100644 --- a/mysql-test/suite/innodb_fts/t/sync.test +++ b/mysql-test/suite/innodb_fts/t/sync.test @@ -7,6 +7,7 @@ --source include/not_valgrind.inc --source include/not_embedded.inc --source include/not_crashrep.inc +--source include/maybe_versioning.inc connect (con1,localhost,root,,); connection default; diff --git a/mysql-test/suite/innodb_fts/t/sync_block.test b/mysql-test/suite/innodb_fts/t/sync_block.test index 895d2ba8a59..593c8fd9176 100644 --- a/mysql-test/suite/innodb_fts/t/sync_block.test +++ b/mysql-test/suite/innodb_fts/t/sync_block.test @@ -7,6 +7,7 @@ --source include/have_debug_sync.inc --source include/have_log_bin.inc --source include/count_sessions.inc +--source include/maybe_versioning.inc SET @old_log_output = @@global.log_output; SET @old_slow_query_log = @@global.slow_query_log; diff --git a/mysql-test/suite/innodb_fts/t/sync_ddl.test b/mysql-test/suite/innodb_fts/t/sync_ddl.test index 2950297d5bb..f3919ba1c94 100644 --- a/mysql-test/suite/innodb_fts/t/sync_ddl.test +++ b/mysql-test/suite/innodb_fts/t/sync_ddl.test @@ -4,6 +4,7 @@ --source include/have_innodb.inc --source include/have_debug.inc +--source include/maybe_versioning.inc #-------------------------------------- # Check FTS_sync vs TRUNCATE (1) diff --git a/mysql-test/suite/innodb_fts/t/versioning.combinations b/mysql-test/suite/innodb_fts/t/versioning.combinations new file mode 100644 index 00000000000..42842ba51a6 --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/versioning.combinations @@ -0,0 +1,2 @@ +[prepare] +[upgrade] diff --git a/mysql-test/suite/innodb_fts/t/versioning.opt b/mysql-test/suite/innodb_fts/t/versioning.opt new file mode 100644 index 00000000000..df323743314 --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/versioning.opt @@ -0,0 +1,2 @@ +--innodb-file-per-table=0 +--innodb-doublewrite=0 diff --git a/mysql-test/suite/innodb_fts/t/versioning.test b/mysql-test/suite/innodb_fts/t/versioning.test new file mode 100644 index 00000000000..b492f9c9d98 --- /dev/null +++ b/mysql-test/suite/innodb_fts/t/versioning.test @@ -0,0 +1,126 @@ +--source include/have_innodb.inc +--source include/have_gzip.inc +--source include/not_embedded.inc + +# Combinations +# +# upgrade: test upgrade on prepared databases from std_data. +# prepare: requires $OLD_BINDIR, test upgrade and downgrade with old-version +# server. Also prepare std_data files during the run in the source +# directory (you just have to commit or reject them). +# +# Examples +# +# export OLD_BINDIR="/home/midenok/src/mariadb/10.3b/build" +# mtr innodb_fts.versioning,orig_stopword,prepare +# + +if ($MTR_COMBINATION_PREPARE) +{ + if (!$OLD_BINDIR) + { + --skip Requires OLD_BINDIR parameter (see test comment) + } +} + +--let $server_id= `select @@server_id` +--let $datadir= `select @@datadir` +--let $std_dir= $MYSQL_TEST_DIR/std_data/versioning +--let $restart_noprint= 3 + +--echo # Upgrade test +let $stopword_table= articles2; + +if ($MTR_COMBINATION_PREPARE) +{ + let $restart_bindir= $OLD_BINDIR; + --source include/restart_mysqld.inc + + let $create_options= with system versioning; + let $basic_stage= create_table; + --source basic.inc + let $basic_stage= insert_1; + --source basic.inc + let $basic_stage= insert_2; + --source basic.inc + let $basic_stage= insert_3; + --source basic.inc + let $stopword_stage= create_table; + --source stopword.inc + eval insert into $stopword_table (title, body) + values ('test for stopwords','this is it...'); + insert into user_stopword values("the"); + delete from user_stopword; + insert into user_stopword values("this"); + --source include/shutdown_mysqld.inc + + --exec mkdir -p $std_dir + --exec cp -af $datadir/ibdata1 $datadir/test/*.frm $std_dir + --exec gzip -9f $std_dir/ibdata1 $std_dir/*.frm +} + +if ($MTR_COMBINATION_UPGRADE) +{ + --source include/shutdown_mysqld.inc + --exec rm -f $datadir/test/*.ibd $datadir/ib* + --exec cp -af $std_dir/ibdata1.gz $datadir + --exec cp -af $std_dir/*.frm.gz $datadir/test + --exec gzip -df $datadir/ibdata1.gz $datadir/test/*.frm.gz +} +let $restart_bindir=; +--source include/start_mysqld.inc + +--error ER_INDEX_CORRUPT +SELECT * FROM articles WHERE MATCH (title,body) +AGAINST ('Database' IN NATURAL LANGUAGE MODE); + +call mtr.add_suppression("test/articles.? contains 3 indexes inside InnoDB"); +alter table articles force; +flush tables; +show create table articles; + +let $basic_stage= select_1; +source basic.inc; +let $basic_stage= select_2; +source basic.inc; +let $basic_stage= select_3; +source basic.inc; + +set global innodb_ft_server_stopword_table= "test/user_stopword"; +let $stopword_stage= select_1; +--source stopword.inc +eval drop index idx on $stopword_table; +eval create fulltext index idx on $stopword_table(title, body); +--source stopword.inc + +if ($MTR_COMBINATION_PREPARE) +{ + --echo # Downgrade test + let $restart_bindir= $OLD_BINDIR; + --source include/restart_mysqld.inc + + alter table articles force; + flush tables; + show create table articles; + let $basic_stage= select_1; + source basic.inc; + let $basic_stage= select_2; + source basic.inc; + let $basic_stage= select_3; + source basic.inc; + + set global innodb_ft_server_stopword_table= "test/user_stopword"; + let $stopword_stage= select_1; + # Downgrade faults with assertion "dict_index_get_n_unique(index) == 1" + # until we rebuilt the index: + eval drop index idx on $stopword_table; + eval create fulltext index idx on $stopword_table(title, body); + source stopword.inc; + + let $restart_bindir=; + --source include/restart_mysqld.inc +} + +--echo # Cleanup +eval drop tables articles, $stopword_table, user_stopword; +set global innodb_ft_server_stopword_table= default; diff --git a/mysql-test/suite/versioning/r/alter.result b/mysql-test/suite/versioning/r/alter.result index 9242f713de3..61ea06368a5 100644 --- a/mysql-test/suite/versioning/r/alter.result +++ b/mysql-test/suite/versioning/r/alter.result @@ -375,6 +375,11 @@ a b 2 NULL 3 1 4 2 +alter table t add c int, drop system versioning; +select * from t; +a b c +3 1 NULL +4 2 NULL create or replace table t (a int) with system versioning; insert into t values (1), (2), (3); delete from t where a<3; diff --git a/mysql-test/suite/versioning/r/debug.result b/mysql-test/suite/versioning/r/debug.result index 3f1367cf3cb..27ba8ee0e12 100644 --- a/mysql-test/suite/versioning/r/debug.result +++ b/mysql-test/suite/versioning/r/debug.result @@ -19,7 +19,7 @@ show create table tt2; Table Create Table tt2 CREATE TEMPORARY TABLE `tt2` ( `a` int(11) DEFAULT NULL -) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING connect con1, localhost, root; create table t3 (a int); show create table t3; @@ -32,7 +32,7 @@ show create table tt3; Table Create Table tt3 CREATE TEMPORARY TABLE `tt3` ( `a` int(11) DEFAULT NULL -) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING disconnect con1; connection default; set debug_dbug='+d,sysvers_show'; diff --git a/mysql-test/suite/versioning/r/delete.result b/mysql-test/suite/versioning/r/delete.result index 0f9e2c22130..6f8c8921790 100644 --- a/mysql-test/suite/versioning/r/delete.result +++ b/mysql-test/suite/versioning/r/delete.result @@ -146,6 +146,5 @@ delete from t1; select f1, f3, check_row_ts(row_start, row_end) from t1 for system_time all; f1 f3 check_row_ts(row_start, row_end) 1 1 HISTORICAL ROW -1 NULL ERROR: row_end == row_start 1 1 HISTORICAL ROW drop table t1; diff --git a/mysql-test/suite/versioning/r/delete_history.result b/mysql-test/suite/versioning/r/delete_history.result index 065b1f00876..64a05ff6867 100644 --- a/mysql-test/suite/versioning/r/delete_history.result +++ b/mysql-test/suite/versioning/r/delete_history.result @@ -1,3 +1,5 @@ +set @saved_frequency= @@global.innodb_purge_rseg_truncate_frequency; +set global innodb_purge_rseg_truncate_frequency= 1; create table t (a int); delete history from t before system_time now(); ERROR HY000: Table `t` is not system-versioned @@ -165,3 +167,23 @@ x 1 drop prepare stmt; drop table t1; +# +# MDEV-25004 Missing row in FTS_DOC_ID_INDEX during DELETE HISTORY +# +create table t1 (a integer, c0 varchar(255), fulltext key (c0)) +with system versioning engine innodb; +set system_versioning_alter_history= keep; +alter table t1 drop system versioning; +alter table t1 add system versioning; +insert into t1 values (1, 'politician'); +update t1 set c0= 'criminal'; +InnoDB 0 transactions not purged +delete history from t1; +drop table t1; +create table t1 (id int primary key, ftx varchar(255)) +with system versioning engine innodb; +insert into t1 values (1, 'c'); +delete from t1; +alter table t1 add fulltext key(ftx); +drop table t1; +set global innodb_purge_rseg_truncate_frequency= @saved_frequency; diff --git a/mysql-test/suite/versioning/r/foreign.result b/mysql-test/suite/versioning/r/foreign.result index d157916c60c..3eb968f1a33 100644 --- a/mysql-test/suite/versioning/r/foreign.result +++ b/mysql-test/suite/versioning/r/foreign.result @@ -443,6 +443,43 @@ pk f1 f2 left(f3, 4) check_row_ts(row_start, row_end) 1 8 8 SHOR HISTORICAL ROW 2 8 8 LONG HISTORICAL ROW drop table t1; +# Shorter case for clustered index (MDEV-25004) +create table t1 ( +y int primary key, r int, f int, key (r), +foreign key (f) references t1 (r) on delete set null) +with system versioning engine innodb; +insert into t1 values (1, 6, 6), (2, 6, 6); +delete from t1; +select *, check_row_ts(row_start, row_end) from t1 for system_time all; +y r f check_row_ts(row_start, row_end) +1 6 6 HISTORICAL ROW +2 6 6 HISTORICAL ROW +drop tables t1; +# Secondary unique index +create table t1 ( +y int unique null, r int, f int, key (r), +foreign key (f) references t1 (r) on delete set null) +with system versioning engine innodb; +insert into t1 values (1, 6, 6), (2, 6, 6); +delete from t1; +select *, check_row_ts(row_start, row_end) from t1 for system_time all; +y r f check_row_ts(row_start, row_end) +1 6 6 HISTORICAL ROW +2 6 6 HISTORICAL ROW +drop tables t1; +# Non-unique index cannot be fixed because it does not trigger duplicate error +create table t1 ( +y int, r int, f int, key (y), key (r), +foreign key (f) references t1 (r) on delete set null) +with system versioning engine innodb; +insert into t1 values (1, 6, 6), (2, 6, 6); +delete from t1; +select *, check_row_ts(row_start, row_end) from t1 for system_time all; +y r f check_row_ts(row_start, row_end) +1 6 6 HISTORICAL ROW +2 6 NULL ERROR: row_end == row_start +2 6 6 HISTORICAL ROW +drop tables t1; # # MDEV-21555 Assertion secondary index is out of sync on delete from versioned table # diff --git a/mysql-test/suite/versioning/t/alter.test b/mysql-test/suite/versioning/t/alter.test index 0900e424bd0..b6562818880 100644 --- a/mysql-test/suite/versioning/t/alter.test +++ b/mysql-test/suite/versioning/t/alter.test @@ -264,6 +264,8 @@ select * from t; select * from t for system_time all; insert into t values (4, 0); select * from t for system_time all; +alter table t add c int, drop system versioning; +select * from t; create or replace table t (a int) with system versioning; insert into t values (1), (2), (3); diff --git a/mysql-test/suite/versioning/t/delete_history.test b/mysql-test/suite/versioning/t/delete_history.test index dae7ff2db9b..f636b5a22fe 100644 --- a/mysql-test/suite/versioning/t/delete_history.test +++ b/mysql-test/suite/versioning/t/delete_history.test @@ -2,6 +2,9 @@ --source include/have_partition.inc --source suite/versioning/engines.inc +set @saved_frequency= @@global.innodb_purge_rseg_truncate_frequency; +set global innodb_purge_rseg_truncate_frequency= 1; + create table t (a int); --error ER_VERS_NOT_VERSIONED delete history from t before system_time now(); @@ -164,4 +167,26 @@ select * from t1; drop prepare stmt; drop table t1; +--echo # +--echo # MDEV-25004 Missing row in FTS_DOC_ID_INDEX during DELETE HISTORY +--echo # +create table t1 (a integer, c0 varchar(255), fulltext key (c0)) +with system versioning engine innodb; +set system_versioning_alter_history= keep; +alter table t1 drop system versioning; +alter table t1 add system versioning; +insert into t1 values (1, 'politician'); +update t1 set c0= 'criminal'; +--source suite/innodb/include/wait_all_purged.inc +delete history from t1; +drop table t1; + +create table t1 (id int primary key, ftx varchar(255)) +with system versioning engine innodb; +insert into t1 values (1, 'c'); +delete from t1; +alter table t1 add fulltext key(ftx); +drop table t1; + +set global innodb_purge_rseg_truncate_frequency= @saved_frequency; --source suite/versioning/common_finish.inc diff --git a/mysql-test/suite/versioning/t/foreign.test b/mysql-test/suite/versioning/t/foreign.test index 1c834719e0f..f4e4fa7a354 100644 --- a/mysql-test/suite/versioning/t/foreign.test +++ b/mysql-test/suite/versioning/t/foreign.test @@ -476,6 +476,39 @@ select pk, f1, f2, left(f3, 4), check_row_ts(row_start, row_end) from t1 for sys # cleanup drop table t1; +--echo # Shorter case for clustered index (MDEV-25004) +create table t1 ( + y int primary key, r int, f int, key (r), + foreign key (f) references t1 (r) on delete set null) +with system versioning engine innodb; + +insert into t1 values (1, 6, 6), (2, 6, 6); +delete from t1; +select *, check_row_ts(row_start, row_end) from t1 for system_time all; +drop tables t1; + +--echo # Secondary unique index +create table t1 ( + y int unique null, r int, f int, key (r), + foreign key (f) references t1 (r) on delete set null) +with system versioning engine innodb; + +insert into t1 values (1, 6, 6), (2, 6, 6); +delete from t1; +select *, check_row_ts(row_start, row_end) from t1 for system_time all; +drop tables t1; + +--echo # Non-unique index cannot be fixed because it does not trigger duplicate error +create table t1 ( + y int, r int, f int, key (y), key (r), + foreign key (f) references t1 (r) on delete set null) +with system versioning engine innodb; + +insert into t1 values (1, 6, 6), (2, 6, 6); +delete from t1; +select *, check_row_ts(row_start, row_end) from t1 for system_time all; +drop tables t1; + --echo # --echo # MDEV-21555 Assertion secondary index is out of sync on delete from versioned table --echo # diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 17437e683f4..7b0967b4461 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2477,7 +2477,7 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet, add_table_options(thd, table, create_info_arg, table_list->schema_table != 0, 0, packet); - if (table->versioned()) + if (DBUG_EVALUATE_IF("sysvers_hide", 0, table->versioned())) packet->append(STRING_WITH_LEN(" WITH SYSTEM VERSIONING")); #ifdef WITH_PARTITION_STORAGE_ENGINE diff --git a/storage/innobase/dict/dict0mem.cc b/storage/innobase/dict/dict0mem.cc index 265642ef210..6366efd2248 100644 --- a/storage/innobase/dict/dict0mem.cc +++ b/storage/innobase/dict/dict0mem.cc @@ -1531,6 +1531,20 @@ dict_index_t::vers_history_row( { ut_ad(!is_primary()); + /* + Get row_end from clustered index + + TODO (optimization): row_end can be taken from unique secondary index + as well. For that dict_index_t::vers_end member should be added and + updated at index init (dict_index_build_internal_non_clust()). + + Test case: + + create or replace table t1 (x int unique, y int unique, + foreign key r (y) references t1 (x)) + with system versioning engine innodb; + insert into t1 values (1, 1); + */ bool error = false; mem_heap_t* heap = NULL; dict_index_t* clust_index = NULL; diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index dc8d529d79c..6a44b8882a7 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -398,8 +398,10 @@ fts_read_stopword( fts_string_t str; mem_heap_t* heap; ib_rbt_bound_t parent; + dict_table_t* table; sel_node = static_cast(row); + table = sel_node->table_list->table; stopword_info = static_cast(user_arg); stop_words = stopword_info->cached_stopword; @@ -414,6 +416,27 @@ fts_read_stopword( str.f_n_char = 0; str.f_str = static_cast(dfield_get_data(dfield)); str.f_len = dfield_get_len(dfield); + exp = que_node_get_next(exp); + ut_ad(exp); + + if (table->versioned()) { + dfield = que_node_get_val(exp); + ut_ad(dfield_get_type(dfield)->vers_sys_end()); + void* data = dfield_get_data(dfield); + ulint len = dfield_get_len(dfield); + if (table->versioned_by_id()) { + ut_ad(len == sizeof trx_id_max_bytes); + if (0 != memcmp(data, trx_id_max_bytes, len)) { + return true; + } + } else { + ut_ad(len == sizeof timestamp_max_bytes); + if (0 != memcmp(data, timestamp_max_bytes, len)) { + return true; + } + } + } + ut_ad(!que_node_get_next(exp)); /* Only create new node if it is a value not already existed */ if (str.f_len != UNIV_SQL_NULL @@ -457,7 +480,9 @@ fts_load_user_stopword( /* Validate the user table existence in the right format */ bool ret= false; - stopword_info->charset = fts_valid_stopword_table(stopword_table_name); + const char* row_end; + stopword_info->charset = fts_valid_stopword_table(stopword_table_name, + &row_end); if (!stopword_info->charset) { cleanup: if (!fts->dict_locked) { @@ -482,6 +507,7 @@ cleanup: pars_info_t* info = pars_info_create(); pars_info_bind_id(info, "table_stopword", stopword_table_name); + pars_info_bind_id(info, "row_end", row_end); pars_info_bind_function(info, "my_func", fts_read_stopword, stopword_info); @@ -490,7 +516,7 @@ cleanup: info, "DECLARE FUNCTION my_func;\n" "DECLARE CURSOR c IS" - " SELECT value" + " SELECT value, $row_end" " FROM $table_stopword;\n" "BEGIN\n" "\n" @@ -1925,9 +1951,16 @@ fts_create_common_tables( goto func_exit; } - index = dict_mem_index_create(table, FTS_DOC_ID_INDEX_NAME, - DICT_UNIQUE, 1); - dict_mem_index_add_field(index, FTS_DOC_ID_COL_NAME, 0); + if (table->versioned()) { + index = dict_mem_index_create(table, FTS_DOC_ID_INDEX_NAME, + DICT_UNIQUE, 2); + dict_mem_index_add_field(index, FTS_DOC_ID_COL_NAME, 0); + dict_mem_index_add_field(index, table->cols[table->vers_end].name(*table), 0); + } else { + index = dict_mem_index_create(table, FTS_DOC_ID_INDEX_NAME, + DICT_UNIQUE, 1); + dict_mem_index_add_field(index, FTS_DOC_ID_COL_NAME, 0); + } op = trx_get_dict_operation(trx); @@ -3427,7 +3460,8 @@ fts_add_doc_by_id( /* Search based on Doc ID. Here, we'll need to consider the case when there is no primary index on Doc ID */ - tuple = dtuple_create(heap, 1); + const ulint n_uniq = table->fts_n_uniq(); + tuple = dtuple_create(heap, n_uniq); dfield = dtuple_get_nth_field(tuple, 0); dfield->type.mtype = DATA_INT; dfield->type.prtype = DATA_NOT_NULL | DATA_UNSIGNED | DATA_BINARY_TYPE; @@ -3435,12 +3469,27 @@ fts_add_doc_by_id( mach_write_to_8((byte*) &temp_doc_id, doc_id); dfield_set_data(dfield, &temp_doc_id, sizeof(temp_doc_id)); + if (n_uniq == 2) { + ut_ad(table->versioned()); + ut_ad(fts_id_index->fields[1].col->vers_sys_end()); + dfield = dtuple_get_nth_field(tuple, 1); + dfield->type.mtype = fts_id_index->fields[1].col->mtype; + dfield->type.prtype = fts_id_index->fields[1].col->prtype; + if (table->versioned_by_id()) { + dfield_set_data(dfield, trx_id_max_bytes, + sizeof(trx_id_max_bytes)); + } else { + dfield_set_data(dfield, timestamp_max_bytes, + sizeof(timestamp_max_bytes)); + } + } + btr_pcur_open_with_no_init( fts_id_index, tuple, PAGE_CUR_LE, BTR_SEARCH_LEAF, &pcur, &mtr); /* If we have a match, add the data to doc structure */ - if (btr_pcur_get_low_match(&pcur) == 1) { + if (btr_pcur_get_low_match(&pcur) == n_uniq) { const rec_t* rec; btr_pcur_t* doc_pcur; const rec_t* clust_rec; @@ -3637,20 +3686,34 @@ fts_get_max_doc_id( if (!page_is_empty(btr_pcur_get_page(&pcur))) { const rec_t* rec = NULL; - rec_offs offsets_[REC_OFFS_NORMAL_SIZE]; - rec_offs* offsets = offsets_; - mem_heap_t* heap = NULL; - ulint len; - const void* data; - - rec_offs_init(offsets_); + const ulint doc_id_len= 8; do { rec = btr_pcur_get_rec(&pcur); - if (page_rec_is_user_rec(rec)) { + if (!page_rec_is_user_rec(rec)) { + continue; + } + + if (index->n_uniq == 1) { break; } + + ut_ad(table->versioned()); + ut_ad(index->n_uniq == 2); + + const byte *data = rec + doc_id_len; + if (table->versioned_by_id()) { + if (0 == memcmp(data, trx_id_max_bytes, + sizeof trx_id_max_bytes)) { + break; + } + } else { + if (0 == memcmp(data, timestamp_max_bytes, + sizeof timestamp_max_bytes)) { + break; + } + } } while (btr_pcur_move_to_prev(&pcur, &mtr)); if (!rec) { @@ -3658,14 +3721,8 @@ fts_get_max_doc_id( } ut_ad(!rec_is_metadata(rec, index)); - offsets = rec_get_offsets( - rec, index, offsets, index->n_core_fields, - ULINT_UNDEFINED, &heap); - data = rec_get_nth_field(rec, offsets, 0, &len); - - doc_id = static_cast(fts_read_doc_id( - static_cast(data))); + doc_id = fts_read_doc_id(rec); } func_exit: @@ -5967,12 +6024,16 @@ void fts_drop_orphaned_tables() /**********************************************************************//** Check whether user supplied stopword table is of the right format. Caller is responsible to hold dictionary locks. -@return the stopword column charset if qualifies */ +@param stopword_table_name table name +@param row_end name of the system-versioning end column, or "value" +@return the stopword column charset +@retval NULL if the table does not exist or qualify */ CHARSET_INFO* fts_valid_stopword_table( /*=====================*/ - const char* stopword_table_name) /*!< in: Stopword table + const char* stopword_table_name, /*!< in: Stopword table name */ + const char** row_end) /* row_end value of system-versioned table */ { dict_table_t* table; dict_col_t* col = NULL; @@ -6014,6 +6075,13 @@ fts_valid_stopword_table( } ut_ad(col); + ut_ad(!table->versioned() || col->ind != table->vers_end); + + if (row_end) { + *row_end = table->versioned() + ? dict_table_get_col_name(table, table->vers_end) + : "value"; /* for fts_load_user_stopword() */ + } return(fts_get_charset(col->prtype)); } @@ -6149,18 +6217,20 @@ cleanup: /**********************************************************************//** Callback function when we initialize the FTS at the start up time. It recovers the maximum Doc IDs presented in the current table. +Tested by innodb_fts.crash_recovery @return: always returns TRUE */ static ibool fts_init_get_doc_id( /*================*/ void* row, /*!< in: sel_node_t* */ - void* user_arg) /*!< in: fts cache */ + void* user_arg) /*!< in: table with fts */ { doc_id_t doc_id = FTS_NULL_DOC_ID; sel_node_t* node = static_cast(row); que_node_t* exp = node->select_list; - fts_cache_t* cache = static_cast(user_arg); + dict_table_t* table = static_cast(user_arg); + fts_cache_t* cache = table->fts->cache; ut_ad(ib_vector_is_empty(cache->get_docs)); @@ -6175,6 +6245,29 @@ fts_init_get_doc_id( doc_id = static_cast(mach_read_from_8( static_cast(data))); + exp = que_node_get_next(que_node_get_next(exp)); + if (exp) { + ut_ad(table->versioned()); + dfield = que_node_get_val(exp); + type = dfield_get_type(dfield); + ut_ad(type->vers_sys_end()); + data = dfield_get_data(dfield); + ulint len = dfield_get_len(dfield); + if (table->versioned_by_id()) { + ut_ad(len == sizeof trx_id_max_bytes); + if (0 != memcmp(data, trx_id_max_bytes, len)) { + return true; + } + } else { + ut_ad(len == sizeof timestamp_max_bytes); + if (0 != memcmp(data, timestamp_max_bytes, len)) { + return true; + } + } + ut_ad(!(exp = que_node_get_next(exp))); + } + ut_ad(!exp); + if (doc_id >= cache->next_doc_id) { cache->next_doc_id = doc_id + 1; } @@ -6340,7 +6433,7 @@ fts_init_index( fts_doc_fetch_by_doc_id(NULL, start_doc, index, FTS_FETCH_DOC_BY_ID_LARGE, - fts_init_get_doc_id, cache); + fts_init_get_doc_id, table); } else { if (table->fts->cache->stopword_info.status & STOPWORD_NOT_INIT) { diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index a1f58091a90..58b2068b56f 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -8967,6 +8967,9 @@ ha_innobase::update_row( innobase_srv_conc_enter_innodb(m_prebuilt); + if (m_prebuilt->upd_node->is_delete) { + trx->fts_next_doc_id = 0; + } error = row_update_for_mysql(m_prebuilt); if (error == DB_SUCCESS && vers_ins_row @@ -9084,6 +9087,7 @@ ha_innobase::delete_row( && trx->id != table->vers_start_id() ? VERSIONED_DELETE : PLAIN_DELETE; + trx->fts_next_doc_id = 0; innobase_srv_conc_enter_innodb(m_prebuilt); @@ -10079,9 +10083,12 @@ ha_innobase::ft_init_ext( /*****************************************************************//** Set up search tuple for a query through FTS_DOC_ID_INDEX on supplied Doc ID. This is used by MySQL to retrieve the documents -once the search result (Doc IDs) is available */ +once the search result (Doc IDs) is available + +@return DB_SUCCESS or DB_INDEX_CORRUPT +*/ static -void +dberr_t innobase_fts_create_doc_id_key( /*===========================*/ dtuple_t* tuple, /* in/out: m_prebuilt->search_tuple */ @@ -10093,8 +10100,10 @@ innobase_fts_create_doc_id_key( { doc_id_t temp_doc_id; dfield_t* dfield = dtuple_get_nth_field(tuple, 0); + const ulint n_uniq = index->table->fts_n_uniq(); - ut_a(dict_index_get_n_unique(index) == 1); + if (dict_index_get_n_unique(index) != n_uniq) + return DB_INDEX_CORRUPT; dtuple_set_n_fields(tuple, index->n_fields); dict_index_copy_types(tuple, index, index->n_fields); @@ -10112,12 +10121,25 @@ innobase_fts_create_doc_id_key( *doc_id = temp_doc_id; dfield_set_data(dfield, doc_id, sizeof(*doc_id)); - dtuple_set_n_fields_cmp(tuple, 1); + if (n_uniq == 2) { + ut_ad(index->table->versioned()); + dfield = dtuple_get_nth_field(tuple, 1); + if (index->table->versioned_by_id()) { + dfield_set_data(dfield, trx_id_max_bytes, + sizeof(trx_id_max_bytes)); + } else { + dfield_set_data(dfield, timestamp_max_bytes, + sizeof(timestamp_max_bytes)); + } + } - for (ulint i = 1; i < index->n_fields; i++) { + dtuple_set_n_fields_cmp(tuple, n_uniq); + + for (ulint i = n_uniq; i < index->n_fields; i++) { dfield = dtuple_get_nth_field(tuple, i); dfield_set_null(dfield); } + return DB_SUCCESS; } /**********************************************************************//** @@ -10199,14 +10221,18 @@ next_record: /* We pass a pointer of search_doc_id because it will be converted to storage byte order used in the search tuple. */ - innobase_fts_create_doc_id_key(tuple, index, &search_doc_id); + dberr_t ret = innobase_fts_create_doc_id_key( + tuple, index, &search_doc_id); - innobase_srv_conc_enter_innodb(m_prebuilt); + if (ret == DB_SUCCESS) { + innobase_srv_conc_enter_innodb(m_prebuilt); - dberr_t ret = row_search_for_mysql( - (byte*) buf, PAGE_CUR_GE, m_prebuilt, ROW_SEL_EXACT, 0); + ret = row_search_for_mysql( + (byte*) buf, PAGE_CUR_GE, m_prebuilt, + ROW_SEL_EXACT, 0); - innobase_srv_conc_exit_innodb(m_prebuilt); + innobase_srv_conc_exit_innodb(m_prebuilt); + } int error; @@ -17537,7 +17563,7 @@ innodb_stopword_table_validate( /* Validate the stopword table's (if supplied) existence and of the right format */ int ret = stopword_table_name && !fts_valid_stopword_table( - stopword_table_name); + stopword_table_name, NULL); row_mysql_unlock_data_dictionary(trx); diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 19c90fed74c..fdfc347f8db 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -1341,6 +1341,11 @@ ha_innobase::check_if_supported_inplace_alter( < dict_table_get_n_user_cols(m_prebuilt->table))); if (fulltext_indexes && m_prebuilt->table->fts) { + /* FTS index of versioned table has row_end, need rebuild */ + if (table->versioned() != altered_table->versioned()) { + need_rebuild= true; + } + /* FULLTEXT indexes are supposed to remain. */ /* Disallow DROP INDEX FTS_DOC_ID_INDEX */ @@ -2762,6 +2767,8 @@ innobase_fts_check_doc_id_index( /* Check if a unique index with the name of FTS_DOC_ID_INDEX_NAME is being created. */ + const ulint fts_n_uniq= altered_table->versioned() ? 2 : 1; + for (uint i = 0; i < altered_table->s->keys; i++) { const KEY& key = altered_table->key_info[i]; @@ -2771,7 +2778,7 @@ innobase_fts_check_doc_id_index( } if ((key.flags & HA_NOSAME) - && key.user_defined_key_parts == 1 + && key.user_defined_key_parts == fts_n_uniq && !strcmp(key.name.str, FTS_DOC_ID_INDEX_NAME) && !strcmp(key.key_part[0].field->field_name.str, FTS_DOC_ID_COL_NAME)) { @@ -2801,7 +2808,7 @@ innobase_fts_check_doc_id_index( } if (!dict_index_is_unique(index) - || dict_index_get_n_unique(index) > 1 + || dict_index_get_n_unique(index) != table->fts_n_uniq() || strcmp(index->name, FTS_DOC_ID_INDEX_NAME)) { return(FTS_INCORRECT_DOC_ID_INDEX); } @@ -2842,6 +2849,7 @@ innobase_fts_check_doc_id_index_in_def( { /* Check whether there is a "FTS_DOC_ID_INDEX" in the to be built index list */ + const uint fts_n_uniq= key_info->table->versioned() ? 2 : 1; for (ulint j = 0; j < n_key; j++) { const KEY* key = &key_info[j]; @@ -2852,7 +2860,7 @@ innobase_fts_check_doc_id_index_in_def( /* Do a check on FTS DOC ID_INDEX, it must be unique, named as "FTS_DOC_ID_INDEX" and on column "FTS_DOC_ID" */ if (!(key->flags & HA_NOSAME) - || key->user_defined_key_parts != 1 + || key->user_defined_key_parts != fts_n_uniq || strcmp(key->name.str, FTS_DOC_ID_INDEX_NAME) || strcmp(key->key_part[0].field->field_name.str, FTS_DOC_ID_COL_NAME)) { @@ -3050,13 +3058,21 @@ created_clustered: if (add_fts_doc_idx) { index_def_t* index = indexdef++; + uint nfields = 1; + if (altered_table->versioned()) + ++nfields; index->fields = static_cast( - mem_heap_alloc(heap, sizeof *index->fields)); - index->n_fields = 1; - index->fields->col_no = fts_doc_id_col; - index->fields->prefix_len = 0; - index->fields->is_v_col = false; + mem_heap_alloc(heap, sizeof(*index->fields) * nfields)); + index->n_fields = nfields; + index->fields[0].col_no = fts_doc_id_col; + index->fields[0].prefix_len = 0; + index->fields[0].is_v_col = false; + if (nfields == 2) { + index->fields[1].col_no = altered_table->s->row_end_field; + index->fields[1].prefix_len = 0; + index->fields[1].is_v_col = false; + } index->ind_type = DICT_UNIQUE; ut_ad(!rebuild || !add_fts_doc_id diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index bf7d9931bed..82d0b70b17c 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -2120,6 +2120,9 @@ public: or mysql/innodb_index_stats. @return true if the table name is same as stats table */ bool is_stats_table() const; + + /** @return number of unique columns in FTS_DOC_ID index */ + unsigned fts_n_uniq() const { return versioned() ? 2 : 1; } }; inline void dict_index_t::set_modified(mtr_t& mtr) const diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h index 326734c84c9..2c75fdf66e7 100644 --- a/storage/innobase/include/fts0fts.h +++ b/storage/innobase/include/fts0fts.h @@ -832,15 +832,14 @@ fts_get_max_doc_id( /*===============*/ dict_table_t* table); /*!< in: user table */ -/******************************************************************//** -Check whether user supplied stopword table exists and is of -the right format. -@return the stopword column charset if qualifies */ -CHARSET_INFO* -fts_valid_stopword_table( -/*=====================*/ - const char* stopword_table_name); /*!< in: Stopword table - name */ +/** Check whether a stopword table is in the right format. +@param stopword_table_name table name +@param row_end name of the system-versioning end column, or "value" +@return the stopword column charset +@retval NULL if the table does not exist or qualify */ +CHARSET_INFO *fts_valid_stopword_table(const char *stopword_table_name, + const char **row_end= NULL); + /****************************************************************//** This function loads specified stopword into FTS cache @return true if success */ diff --git a/storage/innobase/include/row0ins.h b/storage/innobase/include/row0ins.h index 9a16394a052..34427dc6dc7 100644 --- a/storage/innobase/include/row0ins.h +++ b/storage/innobase/include/row0ins.h @@ -206,7 +206,6 @@ struct ins_node_t if this is NULL, entry list should be created and buffers for sys fields in row allocated */ void vers_update_end(row_prebuilt_t *prebuilt, bool history_row); - bool vers_history_row() const; /* true if 'row' is historical */ }; /** Create an insert object. diff --git a/storage/innobase/include/row0upd.h b/storage/innobase/include/row0upd.h index 9721e975a0a..8fa93467490 100644 --- a/storage/innobase/include/row0upd.h +++ b/storage/innobase/include/row0upd.h @@ -617,17 +617,13 @@ public: void vers_make_update(const trx_t *trx) { vers_update_fields(trx, table->vers_start); - } + } - /** Only set row_end = CURRENT_TIMESTAMP/trx->id. - Do not touch other fields at all. - @param[in] trx transaction */ - void vers_make_delete(const trx_t *trx) - { - update->n_fields = 0; - is_delete = VERSIONED_DELETE; - vers_update_fields(trx, table->vers_end); - } + /** Prepare update vector for versioned delete. + Set row_end to CURRENT_TIMESTAMP or trx->id. + Initialize fts_next_doc_id for versioned delete. + @param[in] trx transaction */ + void vers_make_delete(trx_t *trx); }; #define UPD_NODE_MAGIC_N 1579975 diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 2683ad8251f..f4302a1eca3 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -2059,6 +2059,65 @@ row_ins_dupl_error_with_rec( return(!rec_get_deleted_flag(rec, rec_offs_comp(offsets))); } +/** @return true if history row was inserted by this transaction + (row TRX_ID is the same as current TRX_ID). */ +static +dberr_t vers_row_same_trx(dict_index_t* index, const rec_t* rec, + que_thr_t* thr, bool *same_trx) +{ + mtr_t mtr; + dberr_t ret= DB_SUCCESS; + ulint trx_id_len; + const byte *trx_id_bytes; + trx_id_t trx_id; + dict_index_t *clust_index= dict_table_get_first_index(index->table); + ut_ad(index != clust_index); + + mtr.start(); + + rec_t *clust_rec= + row_get_clust_rec(BTR_SEARCH_LEAF, rec, index, &clust_index, &mtr); + rec_offs offsets_[REC_OFFS_NORMAL_SIZE]; + rec_offs *clust_offs= offsets_; + rec_offs_init(offsets_); + mem_heap_t *heap= NULL; + + if (clust_rec) + { + clust_offs= + rec_get_offsets(clust_rec, clust_index, clust_offs, + clust_index->n_core_fields, ULINT_UNDEFINED, &heap); + if (!clust_index->vers_history_row(clust_rec, clust_offs)) + { + *same_trx= false; + goto end; + } + } + else + { + ib::error() << "foreign constraints: secondary index " << index->name << + " of table " << index->table->name << " is out of sync"; + ut_ad("secondary index is out of sync" == 0); + ret= DB_TABLE_CORRUPT; + goto end; + } + + trx_id_bytes= rec_get_nth_field(clust_rec, clust_offs, + clust_index->n_uniq, &trx_id_len); + ut_ad(trx_id_len == DATA_TRX_ID_LEN); + + trx_id= trx_read_trx_id(trx_id_bytes); + + if (UNIV_LIKELY_NULL(heap)) + mem_heap_free(heap); + + *same_trx= thr_get_trx(thr)->id == trx_id; + +end: + mtr.commit(); + return ret; +} + /***************************************************************//** Scans a unique non-clustered index at a given index entry to determine whether a uniqueness violation has occurred for the key value of the entry. @@ -2082,6 +2141,8 @@ row_ins_scan_sec_index_for_duplicate( ulint n_fields_cmp; btr_pcur_t pcur; dberr_t err = DB_SUCCESS; + dberr_t err2; + bool same_trx; ulint allow_duplicates; rec_offs offsets_[REC_OFFS_SEC_INDEX_SIZE]; rec_offs* offsets = offsets_; @@ -2175,10 +2236,25 @@ row_ins_scan_sec_index_for_duplicate( if (cmp == 0) { if (row_ins_dupl_error_with_rec(rec, entry, index, offsets)) { + err = DB_DUPLICATE_KEY; thr_get_trx(thr)->error_info = index; + if (index->table->versioned()) { + err2 = vers_row_same_trx(index, rec, + thr, &same_trx); + if (err2 != DB_SUCCESS) { + err = err2; + goto end_scan; + } + + if (same_trx) { + err = DB_FOREIGN_DUPLICATE_KEY; + goto end_scan; + } + } + /* If the duplicate is on hidden FTS_DOC_ID, state so in the error log */ if (index == index->table->fts_doc_id_index @@ -3580,16 +3656,6 @@ row_ins_get_row_from_select( } } -inline -bool ins_node_t::vers_history_row() const -{ - if (!table->versioned()) - return false; - dfield_t* row_end = dtuple_get_nth_field(row, table->vers_end); - return row_end->vers_history_row(); -} - - /***********************************************************//** Inserts a row to a table. @return DB_SUCCESS if operation successfully completed, else error @@ -3628,31 +3694,12 @@ row_ins( ut_ad(node->state == INS_NODE_INSERT_ENTRIES); while (node->index != NULL) { - dict_index_t *index = node->index; - /* - We do not insert history rows into FTS_DOC_ID_INDEX because - it is unique by FTS_DOC_ID only and we do not want to add - row_end to unique key. Fulltext field works the way new - FTS_DOC_ID is created on every fulltext UPDATE, so holding only - FTS_DOC_ID for history is enough. - */ - const unsigned type = index->type; - if (index->type & DICT_FTS) { - } else if (!(type & DICT_UNIQUE) || index->n_uniq > 1 - || !node->vers_history_row()) { - + if (!(node->index->type & DICT_FTS)) { dberr_t err = row_ins_index_entry_step(node, thr); if (err != DB_SUCCESS) { DBUG_RETURN(err); } - } else { - /* Unique indexes with system versioning must contain - the version end column. The only exception is a hidden - FTS_DOC_ID_INDEX that InnoDB may create on a hidden or - user-created FTS_DOC_ID column. */ - ut_ad(!strcmp(index->name, FTS_DOC_ID_INDEX_NAME)); - ut_ad(!strcmp(index->fields[0].name, FTS_DOC_ID_COL_NAME)); } node->index = dict_table_get_next_index(node->index); diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 7bd15177dad..415c93a9f6f 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -455,6 +455,7 @@ row_merge_buf_redundant_convert( @param[in] new_table new table @param[in,out] psort_info parallel sort info @param[in,out] row table row +@param[in] history_row row is historical in a system-versioned table @param[in] ext cache of externally stored column prefixes, or NULL @param[in,out] doc_id Doc ID if we are creating @@ -477,6 +478,7 @@ row_merge_buf_add( const dict_table_t* new_table, fts_psort_t* psort_info, dtuple_t* row, + const bool history_row, const row_ext_t* ext, doc_id_t* doc_id, mem_heap_t* conv_heap, @@ -540,7 +542,7 @@ error: : NULL; /* Process the Doc ID column */ - if (!v_col && *doc_id + if (!v_col && index->table->fts && (*doc_id || history_row) && col->ind == index->table->fts->doc_col) { fts_write_doc_id((byte*) &write_doc_id, *doc_id); @@ -592,7 +594,7 @@ error: /* Tokenize and process data for FTS */ - if (index->type & DICT_FTS) { + if (!history_row && (index->type & DICT_FTS)) { fts_doc_item_t* doc_item; byte* value; void* ptr; @@ -1705,6 +1707,7 @@ row_merge_read_clustered_index( char new_sys_trx_end[8]; byte any_autoinc_data[8] = {0}; bool vers_update_trt = false; + bool history_row = false; DBUG_ENTER("row_merge_read_clustered_index"); @@ -2132,6 +2135,12 @@ end_of_index: row_heap); ut_ad(row); + if (new_table->versioned()) { + const dfield_t* dfield = dtuple_get_nth_field( + row, new_table->vers_end); + history_row = dfield->vers_history_row(); + } + for (ulint i = 0; i < n_nonnull; i++) { dfield_t* field = &row->fields[nonnull[i]]; @@ -2161,7 +2170,7 @@ end_of_index: } /* Get the next Doc ID */ - if (add_doc_id) { + if (add_doc_id && !history_row) { doc_id++; } else { doc_id = 0; @@ -2197,13 +2206,6 @@ end_of_index: ut_ad(add_autoinc < dict_table_get_n_user_cols(new_table)); - bool history_row = false; - if (new_table->versioned()) { - const dfield_t* dfield = dtuple_get_nth_field( - row, new_table->vers_end); - history_row = dfield->vers_history_row(); - } - dfield_t* dfield = dtuple_get_nth_field(row, add_autoinc); @@ -2327,8 +2329,8 @@ write_buffers: if (UNIV_LIKELY (row && (rows_added = row_merge_buf_add( buf, fts_index, old_table, new_table, - psort_info, row, ext, &doc_id, - conv_heap, &err, + psort_info, row, history_row, ext, + &doc_id, conv_heap, &err, &v_heap, eval_table, trx)))) { /* Set the page flush observer for the @@ -2660,9 +2662,10 @@ write_buffers: if (UNIV_UNLIKELY (!(rows_added = row_merge_buf_add( buf, fts_index, old_table, - new_table, psort_info, row, ext, - &doc_id, conv_heap, - &err, &v_heap, eval_table, trx)))) { + new_table, psort_info, row, + history_row, ext, &doc_id, + conv_heap, &err, &v_heap, + eval_table, trx)))) { /* An empty buffer should have enough room for at least one record. */ ut_ad(err == DB_COMPUTE_VALUE_FAILED diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 8eeaa62b29e..dfc5393a8b3 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -1449,7 +1449,10 @@ error_exit: return(err); } - if (dict_table_has_fts_index(table)) { + if (dict_table_has_fts_index(table) + && (!table->versioned() + || !node->row->fields[table->vers_end].vers_history_row())) { + doc_id_t doc_id; /* Extract the doc id from the hidden FTS column */ @@ -1663,7 +1666,7 @@ row_fts_update_or_delete( ut_a(dict_table_has_fts_index(prebuilt->table)); /* Deletes are simple; get them out of the way first. */ - if (node->is_delete == PLAIN_DELETE) { + if (node->is_delete) { /* A delete affects all FTS indexes, so we pass NULL */ fts_trx_add_op(trx, table, old_doc_id, FTS_DELETE, NULL); } else { @@ -2228,7 +2231,7 @@ row_update_cascade_for_mysql( return(DB_FOREIGN_EXCEED_MAX_CASCADE); } - const trx_t* trx = thr_get_trx(thr); + trx_t* trx = thr_get_trx(thr); if (table->versioned()) { if (node->is_delete == PLAIN_DELETE) { diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc index 599aece23f5..ef780e7ccb0 100644 --- a/storage/innobase/row/row0upd.cc +++ b/storage/innobase/row/row0upd.cc @@ -3545,3 +3545,16 @@ skip_append: } } } + + +/** Prepare update vector for versioned delete. +Set row_end to CURRENT_TIMESTAMP or trx->id. +Initialize fts_next_doc_id for versioned delete. +@param[in] trx transaction */ +void upd_node_t::vers_make_delete(trx_t* trx) +{ + update->n_fields= 0; + is_delete= VERSIONED_DELETE; + vers_update_fields(trx, table->vers_end); + trx->fts_next_doc_id= table->fts ? UINT64_UNDEFINED : 0; +}