Skip to content

Commit

Permalink
MDEV-19869 Port innodb_fts.fulltext2 from mysql to mariadb.
Browse files Browse the repository at this point in the history
- Ported mysql Bug#20597981 test case to mariadb-10.2
- InnoDB never used fts_doc_id_in_read_set. Basically it tells
innodb to read the fts_doc_id from the index record itself.
  • Loading branch information
Thirunarayanan committed Jul 1, 2019
1 parent 723a4b1 commit ed6da51
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 19 deletions.
30 changes: 30 additions & 0 deletions mysql-test/suite/innodb_fts/r/fulltext2.result
Original file line number Diff line number Diff line change
Expand Up @@ -242,3 +242,33 @@ a
„MySQL“
DROP TABLE t1;
SET NAMES latin1;
CREATE TABLE t1 (
FTS_DOC_ID BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
id int(10) not null ,
first_name varchar(50) NOT NULL,
last_name varchar(50) NOT NULL,
PRIMARY KEY (FTS_DOC_ID),
UNIQUE KEY idx_1 (first_name, last_name),
FULLTEXT KEY `idx_2` (first_name)
) ENGINE=InnoDB;
INSERT INTO t1 (id, first_name, last_name) VALUES
(10, 'Bart', 'Simpson'),
(11, 'Homer', 'Simpson'),
(12, 'Marge', 'Simpson'),
(13, 'Lisa', 'Simpson'),
(14, 'Maggie', 'Simpson'),
(15, 'Ned', 'Flanders'),
(16, 'Nelson', 'Muntz');
analyze table t1;
Table Op Msg_type Msg_text
test.t1 analyze status OK
SELECT fts_doc_id, first_name, last_name, MATCH(first_name) AGAINST('Homer' IN BOOLEAN MODE) AS score FROM t1;
fts_doc_id first_name last_name score
1 Bart Simpson 0
2 Homer Simpson 0.7141907215118408
4 Lisa Simpson 0
5 Maggie Simpson 0
3 Marge Simpson 0
6 Ned Flanders 0
7 Nelson Muntz 0
DROP TABLE t1;
31 changes: 26 additions & 5 deletions mysql-test/suite/innodb_fts/t/fulltext2.test
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,6 @@
DROP TABLE IF EXISTS t1;
--enable_warnings

if (`select plugin_auth_version <= "5.6.10" from information_schema.plugins where plugin_name='innodb'`)
{
--skip Not fixed in InnoDB 5.6.10 or earlier
}

CREATE TABLE t1 (
i int(10) unsigned not null auto_increment primary key,
a varchar(255) not null,
Expand Down Expand Up @@ -239,3 +234,29 @@ INSERT INTO t1 VALUES('„MySQL“');
SELECT a FROM t1 WHERE MATCH a AGAINST('“MySQL„' IN BOOLEAN MODE);
DROP TABLE t1;
SET NAMES latin1;

#
# Bug #20597981 - WRONG RELEVANCE RANKING FOR FULL TEXT SEARCHES
# WHEN FTS_DOC_ID IS PRIMARY KEY
CREATE TABLE t1 (
FTS_DOC_ID BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
id int(10) not null ,
first_name varchar(50) NOT NULL,
last_name varchar(50) NOT NULL,
PRIMARY KEY (FTS_DOC_ID),
UNIQUE KEY idx_1 (first_name, last_name),
FULLTEXT KEY `idx_2` (first_name)
) ENGINE=InnoDB;

INSERT INTO t1 (id, first_name, last_name) VALUES
(10, 'Bart', 'Simpson'),
(11, 'Homer', 'Simpson'),
(12, 'Marge', 'Simpson'),
(13, 'Lisa', 'Simpson'),
(14, 'Maggie', 'Simpson'),
(15, 'Ned', 'Flanders'),
(16, 'Nelson', 'Muntz');

analyze table t1;
SELECT fts_doc_id, first_name, last_name, MATCH(first_name) AGAINST('Homer' IN BOOLEAN MODE) AS score FROM t1;
DROP TABLE t1;
29 changes: 15 additions & 14 deletions storage/innobase/handler/ha_innodb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9688,14 +9688,16 @@ ha_innobase::change_active_index(
since FT search returns rank only. In addition engine should
be able to retrieve FTS_DOC_ID column value if necessary. */
if ((m_prebuilt->index->type & DICT_FTS)) {
#ifdef MYSQL_STORE_FTS_DOC_ID
if (table->fts_doc_id_field
&& bitmap_is_set(table->read_set,
table->fts_doc_id_field->field_index
&& m_prebuilt->read_just_key)) {
m_prebuilt->fts_doc_id_in_read_set = 1;

for (ulint i = 0; i < table->s->fields; i++) {
if (m_prebuilt->read_just_key
&& bitmap_get_next_set(table->read_set, i)
&& !strcmp(table->s->field[i]->field_name,
FTS_DOC_ID_COL_NAME)){
m_prebuilt->fts_doc_id_in_read_set = true;
break;
}
}
#endif
} else {
dtuple_set_n_fields(m_prebuilt->search_tuple,
m_prebuilt->index->n_fields);
Expand All @@ -9706,13 +9708,12 @@ ha_innobase::change_active_index(

/* If it's FTS query and FTS_DOC_ID exists FTS_DOC_ID field is
always added to read_set. */

#ifdef MYSQL_STORE_FTS_DOC_ID
m_prebuilt->fts_doc_id_in_read_set =
(m_prebuilt->read_just_key && table->fts_doc_id_field
&& m_prebuilt->in_fts_query);
#endif

m_prebuilt->fts_doc_id_in_read_set = m_prebuilt->in_fts_query
&& m_prebuilt->read_just_key
&& dict_index_contains_col_or_prefix(
m_prebuilt->index,
m_prebuilt->table->fts->doc_col,
false);
}

/* MySQL changes the active index for a handle also during some
Expand Down

0 comments on commit ed6da51

Please sign in to comment.