Bug #120539 Duplicate FULLTEXT index on a column returns wrong MATCH...AGAINST results when combined with a STORED generated column
Description:
When a table has a FULLTEXT index on a VARCHAR column, adding a STORED generated column (via ALTER TABLE) and a functional index, then creating a SECOND FULLTEXT index on the same column, corrupts the fulltext search state. After the second FULLTEXT index is created, MATCH(c5) AGAINST (... IN BOOLEAN MODE) queries return 0 rows instead of the correct non-zero count. The underlying data is intact -- a LIKE query on the same column and same pattern returns the correct result.
Specifically, the following sequence triggers the bug:
1. Create a table with an INT column (c0), an INT column (c4), and a
VARCHAR(255) column (c5).
2. Insert one row where c5 = '1828091703'.
3. Create a first FULLTEXT index on c5 -- queries work correctly at
this point.
4. ALTER TABLE to add a STORED generated column defined as
IFNULL(c0, 0) + 1.
5. Create a functional index on the expression (c4 + 1).
6. Create a SECOND FULLTEXT index on c5 -- this corrupts fulltext
search.
After step 6, the query:
SELECT COUNT(*) FROM idx_t0
WHERE MATCH(c5) AGAINST('1828091703*' IN BOOLEAN MODE);
returns 0 instead of 1. The control query using LIKE still returns 1:
SELECT COUNT(*) FROM idx_t0 WHERE c5 LIKE '1828091703%';
The bug requires all three preconditions to be present simultaneously:
(a) an existing FULLTEXT index on the column,
(b) a STORED generated column on the table, and
(c) a functional index on the table.
Removing any one of these conditions prevents the bug from manifesting.
How to repeat:
DROP DATABASE IF EXISTS test_ft_min;
CREATE DATABASE test_ft_min;
USE test_ft_min;
-- Step 1: Create table with 1 row
CREATE TABLE idx_t0 (
c0 INT NOT NULL,
c4 INT NOT NULL,
c5 VARCHAR(255) NOT NULL
);
INSERT INTO idx_t0 VALUES (286586734, 1717882338, '1828091703');
-- Step 2: Create FIRST fulltext index (works correctly)
CREATE FULLTEXT INDEX ft_0_c5 ON idx_t0 (c5);
-- Step 3: Add STORED generated column (triggers bug condition 1)
ALTER TABLE idx_t0 ADD COLUMN gen_col BIGINT GENERATED ALWAYS AS (IFNULL(c0, 0) + 1) STORED;
-- Step 4: Create functional index (triggers bug condition 2)
CREATE INDEX func_idx ON idx_t0 ((c4 + 1));
-- Step 5: Create SECOND fulltext index on same column (triggers the bug!)
CREATE FULLTEXT INDEX ft_idx_3122 ON idx_t0 (c5);
-- Verify: both queries should return 1
SELECT 'FT BUG (should be 1)' AS test, COUNT(*) AS result
FROM idx_t0 WHERE MATCH(c5) AGAINST('1828091703*' IN BOOLEAN MODE);
SELECT 'LIKE ctrl (should be 1)' AS test, COUNT(*) AS result
FROM idx_t0 WHERE c5 LIKE '1828091703%';
SHOW INDEX FROM idx_t0 WHERE Index_type = 'FULLTEXT';
FULLTEXT result:
+----------------------+--------+
| test | result |
+----------------------+--------+
| FT BUG (should be 1) | 0 | <- WRONG! Missing 1 row!
+----------------------+--------+
1 row in set (0.001 sec)
LIKE control result:
+-------------------------+--------+
| test | result |
+-------------------------+--------+
| LIKE ctrl (should be 1) | 1 | <- CORRECT
+-------------------------+--------+
1 row in set (0.001 sec)
Expected output for the MATCH query: COUNT(*) = 1
Actual output: COUNT(*) = 0
Suggested fix:
The second CREATE FULLTEXT INDEX statement appears to corrupt the
internal fulltext index state (possibly the FT index cache or token
mapping) when the table contains both a STORED generated column and
a functional index. The InnoDB fulltext index creation/rebuild logic
should be reviewed for the code path that handles tables with generated
columns and functional indexes.
Portions of this website are copyright © 2001, 2002 The PHP Group
Page generated in 0.038 sec. using MySQL 8.4.7-u6-cloud
Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the
respective copyright holders.
It is not reviewed in advance
by Oracle and does not necessarily represent the opinion of
Oracle or any other party.
Description: When a table has a FULLTEXT index on a VARCHAR column, adding a STORED generated column (via ALTER TABLE) and a functional index, then creating a SECOND FULLTEXT index on the same column, corrupts the fulltext search state. After the second FULLTEXT index is created, MATCH(c5) AGAINST (... IN BOOLEAN MODE) queries return 0 rows instead of the correct non-zero count. The underlying data is intact -- a LIKE query on the same column and same pattern returns the correct result. Specifically, the following sequence triggers the bug: 1. Create a table with an INT column (c0), an INT column (c4), and a VARCHAR(255) column (c5). 2. Insert one row where c5 = '1828091703'. 3. Create a first FULLTEXT index on c5 -- queries work correctly at this point. 4. ALTER TABLE to add a STORED generated column defined as IFNULL(c0, 0) + 1. 5. Create a functional index on the expression (c4 + 1). 6. Create a SECOND FULLTEXT index on c5 -- this corrupts fulltext search. After step 6, the query: SELECT COUNT(*) FROM idx_t0 WHERE MATCH(c5) AGAINST('1828091703*' IN BOOLEAN MODE); returns 0 instead of 1. The control query using LIKE still returns 1: SELECT COUNT(*) FROM idx_t0 WHERE c5 LIKE '1828091703%'; The bug requires all three preconditions to be present simultaneously: (a) an existing FULLTEXT index on the column, (b) a STORED generated column on the table, and (c) a functional index on the table. Removing any one of these conditions prevents the bug from manifesting. How to repeat: DROP DATABASE IF EXISTS test_ft_min; CREATE DATABASE test_ft_min; USE test_ft_min; -- Step 1: Create table with 1 row CREATE TABLE idx_t0 ( c0 INT NOT NULL, c4 INT NOT NULL, c5 VARCHAR(255) NOT NULL ); INSERT INTO idx_t0 VALUES (286586734, 1717882338, '1828091703'); -- Step 2: Create FIRST fulltext index (works correctly) CREATE FULLTEXT INDEX ft_0_c5 ON idx_t0 (c5); -- Step 3: Add STORED generated column (triggers bug condition 1) ALTER TABLE idx_t0 ADD COLUMN gen_col BIGINT GENERATED ALWAYS AS (IFNULL(c0, 0) + 1) STORED; -- Step 4: Create functional index (triggers bug condition 2) CREATE INDEX func_idx ON idx_t0 ((c4 + 1)); -- Step 5: Create SECOND fulltext index on same column (triggers the bug!) CREATE FULLTEXT INDEX ft_idx_3122 ON idx_t0 (c5); -- Verify: both queries should return 1 SELECT 'FT BUG (should be 1)' AS test, COUNT(*) AS result FROM idx_t0 WHERE MATCH(c5) AGAINST('1828091703*' IN BOOLEAN MODE); SELECT 'LIKE ctrl (should be 1)' AS test, COUNT(*) AS result FROM idx_t0 WHERE c5 LIKE '1828091703%'; SHOW INDEX FROM idx_t0 WHERE Index_type = 'FULLTEXT'; FULLTEXT result: +----------------------+--------+ | test | result | +----------------------+--------+ | FT BUG (should be 1) | 0 | <- WRONG! Missing 1 row! +----------------------+--------+ 1 row in set (0.001 sec) LIKE control result: +-------------------------+--------+ | test | result | +-------------------------+--------+ | LIKE ctrl (should be 1) | 1 | <- CORRECT +-------------------------+--------+ 1 row in set (0.001 sec) Expected output for the MATCH query: COUNT(*) = 1 Actual output: COUNT(*) = 0 Suggested fix: The second CREATE FULLTEXT INDEX statement appears to corrupt the internal fulltext index state (possibly the FT index cache or token mapping) when the table contains both a STORED generated column and a functional index. The InnoDB fulltext index creation/rebuild logic should be reviewed for the code path that handles tables with generated columns and functional indexes.