summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/suite/innodb_fts/r/fulltext.result11
-rw-r--r--mysql-test/suite/innodb_fts/t/fulltext.test9
-rw-r--r--storage/innobase/handler/ha_innodb.cc14
3 files changed, 33 insertions, 1 deletions
diff --git a/mysql-test/suite/innodb_fts/r/fulltext.result b/mysql-test/suite/innodb_fts/r/fulltext.result
index 7775a46e0d8..6a889f503b4 100644
--- a/mysql-test/suite/innodb_fts/r/fulltext.result
+++ b/mysql-test/suite/innodb_fts/r/fulltext.result
@@ -732,4 +732,15 @@ ALTER TABLE t1 DROP KEY `ftidx` ;
INSERT INTO t1 (col_int, col_text) VALUES ( 1255, NULL);
DROP TABLE t1;
SET @@global.innodb_file_per_table = @save;
+#
+# MDEV-20797 FULLTEXT search with apostrophe,
+# and mandatory words
+#
+CREATE TABLE t1(f1 TINYTEXT NOT NULL, FULLTEXT(f1))ENGINE=InnoDB;
+INSERT INTO t1 VALUES('O''Brien'), ('O Brien');
+SELECT * FROM t1 WHERE MATCH (f1) AGAINST ("+O'Brien" IN BOOLEAN MODE);
+f1
+O'Brien
+O Brien
+DROP TABLE t1;
# End of 10.3 tests
diff --git a/mysql-test/suite/innodb_fts/t/fulltext.test b/mysql-test/suite/innodb_fts/t/fulltext.test
index 4878a0bee3f..43c8de3fd5e 100644
--- a/mysql-test/suite/innodb_fts/t/fulltext.test
+++ b/mysql-test/suite/innodb_fts/t/fulltext.test
@@ -757,4 +757,13 @@ INSERT INTO t1 (col_int, col_text) VALUES ( 1255, NULL);
DROP TABLE t1;
SET @@global.innodb_file_per_table = @save;
+--echo #
+--echo # MDEV-20797 FULLTEXT search with apostrophe,
+--echo # and mandatory words
+--echo #
+CREATE TABLE t1(f1 TINYTEXT NOT NULL, FULLTEXT(f1))ENGINE=InnoDB;
+INSERT INTO t1 VALUES('O''Brien'), ('O Brien');
+SELECT * FROM t1 WHERE MATCH (f1) AGAINST ("+O'Brien" IN BOOLEAN MODE);
+DROP TABLE t1;
+
--echo # End of 10.3 tests
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 514e6fa31a2..e1b645c1cc3 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -6912,7 +6912,8 @@ innobase_mysql_fts_get_token(
ulint mwc = 0;
ulint length = 0;
-
+ bool reset_token_str = false;
+reset:
token->f_str = const_cast<byte*>(doc);
while (doc < end) {
@@ -6923,6 +6924,9 @@ innobase_mysql_fts_get_token(
cs, &ctype, (uchar*) doc, (uchar*) end);
if (true_word_char(ctype, *doc)) {
mwc = 0;
+ } else if (*doc == '\'' && length == 1) {
+ /* Could be apostrophe */
+ reset_token_str = true;
} else if (!misc_word_char(*doc) || mwc) {
break;
} else {
@@ -6932,6 +6936,14 @@ innobase_mysql_fts_get_token(
++length;
doc += mbl > 0 ? mbl : (mbl < 0 ? -mbl : 1);
+ if (reset_token_str) {
+ /* Reset the token if the single character
+ followed by apostrophe */
+ mwc = 0;
+ length = 0;
+ reset_token_str = false;
+ goto reset;
+ }
}
token->f_len = (uint) (doc - token->f_str) - mwc;