Skip to content

Commit 8ce8c26

Browse files
Thirunarayanandr-m
authored andcommitted
MDEV-19522 InnoDB commit fails when FTS_DOC_ID value is greater than 4294967295
InnoDB commit fails when consecutive FTS_DOC_ID value is greater than 4294967295. Fix is that InnoDB should remove the delta FTS_DOC_ID value limitations and fts should encode 8 byte value, remove FTS_DOC_ID_MAX_STEP variable. Replaced the fts0vlc.ic file with fts0vlc.h fts_encode_int(): Should be able to encode 10 bytes value fts_get_encoded_len(): Should get the length of the value which has 10 bytes fts_decode_vlc(): Add debug assertion to verify the maximum length allowed is 10. mach_read_uint64_little_endian(): Reads 64 bit stored in little endian format Added a unit test case which check for minimum and maximum value to do the fts encoding
1 parent 6b4fad9 commit 8ce8c26

File tree

18 files changed

+286
-235
lines changed

18 files changed

+286
-235
lines changed

mysql-test/suite/innodb_fts/r/basic.result

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -313,9 +313,7 @@ FTS_DOC_ID
313313
65536
314314
131071
315315
drop table t1;
316-
call mtr.add_suppression("\\[ERROR\\] InnoDB: Doc ID 20030101000000 is too big. Its difference with largest used Doc ID 0 cannot exceed or equal to 65535");
317316
CREATE TABLE t1 (FTS_DOC_ID BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
318317
title VARCHAR(200), FULLTEXT(title)) ENGINE=InnoDB;
319318
INSERT INTO t1 VALUES (NULL, NULL), (20030101000000, 20030102000000);
320-
ERROR HY000: Invalid InnoDB FTS Doc ID
321319
DROP TABLE t1;

mysql-test/suite/innodb_fts/r/innodb_fts_misc_1.result

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -972,3 +972,24 @@ SELECT * FROM information_schema.innodb_ft_deleted;
972972
DOC_ID
973973
DROP TABLE t1;
974974
SET GLOBAL innodb_ft_aux_table=DEFAULT;
975+
#
976+
# MDEV-19522 InnoDB commit fails when FTS_DOC_ID value
977+
# is greater than 4294967295
978+
#
979+
CREATE TABLE t1(
980+
FTS_DOC_ID BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
981+
f1 TEXT, f2 TEXT, PRIMARY KEY (FTS_DOC_ID),
982+
FULLTEXT KEY (f1)) ENGINE=InnoDB;
983+
INSERT INTO t1 VALUES (1,'txt','bbb');
984+
UPDATE t1 SET FTS_DOC_ID = 4294967298;
985+
SELECT * FROM t1 WHERE match(f1) against("txt");
986+
FTS_DOC_ID f1 f2
987+
4294967298 txt bbb
988+
SET @@session.insert_id = 100000000000;
989+
INSERT INTO t1(f1, f2) VALUES ('aaa', 'bbb');
990+
CREATE FULLTEXT INDEX i ON t1 (f2);
991+
SELECT * FROM t1 WHERE match(f2) against("bbb");
992+
FTS_DOC_ID f1 f2
993+
4294967298 txt bbb
994+
100000000000 aaa bbb
995+
DROP TABLE t1;

mysql-test/suite/innodb_fts/t/basic.test

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,9 +277,7 @@ insert into t1(f1, f2) values(3, "This is the third record");
277277
select FTS_DOC_ID from t1;
278278
drop table t1;
279279

280-
call mtr.add_suppression("\\[ERROR\\] InnoDB: Doc ID 20030101000000 is too big. Its difference with largest used Doc ID 0 cannot exceed or equal to 65535");
281280
CREATE TABLE t1 (FTS_DOC_ID BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
282281
title VARCHAR(200), FULLTEXT(title)) ENGINE=InnoDB;
283-
--error 182
284282
INSERT INTO t1 VALUES (NULL, NULL), (20030101000000, 20030102000000);
285283
DROP TABLE t1;

mysql-test/suite/innodb_fts/t/innodb_fts_misc_1.test

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -942,3 +942,21 @@ SET GLOBAL innodb_ft_aux_table='test/t1';
942942
SELECT * FROM information_schema.innodb_ft_deleted;
943943
DROP TABLE t1;
944944
SET GLOBAL innodb_ft_aux_table=DEFAULT;
945+
946+
--echo #
947+
--echo # MDEV-19522 InnoDB commit fails when FTS_DOC_ID value
948+
--echo # is greater than 4294967295
949+
--echo #
950+
CREATE TABLE t1(
951+
FTS_DOC_ID BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
952+
f1 TEXT, f2 TEXT, PRIMARY KEY (FTS_DOC_ID),
953+
FULLTEXT KEY (f1)) ENGINE=InnoDB;
954+
INSERT INTO t1 VALUES (1,'txt','bbb');
955+
UPDATE t1 SET FTS_DOC_ID = 4294967298;
956+
SELECT * FROM t1 WHERE match(f1) against("txt");
957+
SET @@session.insert_id = 100000000000;
958+
INSERT INTO t1(f1, f2) VALUES ('aaa', 'bbb');
959+
CREATE FULLTEXT INDEX i ON t1 (f2);
960+
SELECT * FROM t1 WHERE match(f2) against("bbb");
961+
# Cleanup
962+
DROP TABLE t1;

storage/innobase/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,3 +188,7 @@ IF(MSVC)
188188
ENDIF()
189189

190190
ADD_SUBDIRECTORY(${CMAKE_SOURCE_DIR}/extra/mariabackup ${CMAKE_BINARY_DIR}/extra/mariabackup)
191+
192+
IF(WITH_UNIT_TESTS)
193+
ADD_SUBDIRECTORY(unittest)
194+
ENDIF()

storage/innobase/fts/fts0fts.cc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ Full Text Search interface
3232
#include "fts0priv.h"
3333
#include "fts0types.h"
3434
#include "fts0types.ic"
35-
#include "fts0vlc.ic"
35+
#include "fts0vlc.h"
3636
#include "fts0plugin.h"
3737
#include "dict0priv.h"
3838
#include "dict0stats.h"
@@ -1247,7 +1247,7 @@ fts_cache_node_add_positions(
12471247
ulint enc_len;
12481248
ulint last_pos;
12491249
byte* ptr_start;
1250-
ulint doc_id_delta;
1250+
doc_id_t doc_id_delta;
12511251

12521252
#ifdef UNIV_DEBUG
12531253
if (cache) {
@@ -1258,7 +1258,7 @@ fts_cache_node_add_positions(
12581258
ut_ad(doc_id >= node->last_doc_id);
12591259

12601260
/* Calculate the space required to store the ilist. */
1261-
doc_id_delta = (ulint)(doc_id - node->last_doc_id);
1261+
doc_id_delta = doc_id - node->last_doc_id;
12621262
enc_len = fts_get_encoded_len(doc_id_delta);
12631263

12641264
last_pos = 0;
@@ -1307,14 +1307,14 @@ fts_cache_node_add_positions(
13071307
ptr_start = ptr;
13081308

13091309
/* Encode the new fragment. */
1310-
ptr += fts_encode_int(doc_id_delta, ptr);
1310+
ptr = fts_encode_int(doc_id_delta, ptr);
13111311

13121312
last_pos = 0;
13131313
for (i = 0; i < ib_vector_size(positions); i++) {
13141314
ulint pos = *(static_cast<ulint*>(
13151315
ib_vector_get(positions, i)));
13161316

1317-
ptr += fts_encode_int(pos - last_pos, ptr);
1317+
ptr = fts_encode_int(pos - last_pos, ptr);
13181318
last_pos = pos;
13191319
}
13201320

storage/innobase/fts/fts0opt.cc

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ Completed 2011/7/10 Sunny and Jimmy Yang
3636
#include "ut0list.h"
3737
#include "zlib.h"
3838
#include "fts0opt.h"
39+
#include "fts0vlc.h"
3940

4041
/** The FTS optimize thread's work queue. */
4142
ib_wqueue_t* fts_optimize_wq;
@@ -1116,7 +1117,7 @@ fts_optimize_encode_node(
11161117
ulint pos_enc_len;
11171118
doc_id_t doc_id_delta;
11181119
dberr_t error = DB_SUCCESS;
1119-
byte* src = enc->src_ilist_ptr;
1120+
const byte* src = enc->src_ilist_ptr;
11201121

11211122
if (node->first_doc_id == 0) {
11221123
ut_a(node->last_doc_id == 0);
@@ -1173,7 +1174,7 @@ fts_optimize_encode_node(
11731174

11741175
/* Encode the doc id. Cast to ulint, the delta should be small and
11751176
therefore no loss of precision. */
1176-
dst += fts_encode_int((ulint) doc_id_delta, dst);
1177+
dst = fts_encode_int(doc_id_delta, dst);
11771178

11781179
/* Copy the encoded pos array. */
11791180
memcpy(dst, src, pos_enc_len);
@@ -1220,7 +1221,8 @@ fts_optimize_node(
12201221
doc_id_t delta;
12211222
doc_id_t del_doc_id = FTS_NULL_DOC_ID;
12221223

1223-
delta = fts_decode_vlc(&enc->src_ilist_ptr);
1224+
delta = fts_decode_vlc(
1225+
(const byte**)&enc->src_ilist_ptr);
12241226

12251227
test_again:
12261228
/* Check whether the doc id is in the delete list, if
@@ -1248,7 +1250,7 @@ fts_optimize_node(
12481250

12491251
/* Skip the entries for this document. */
12501252
while (*enc->src_ilist_ptr) {
1251-
fts_decode_vlc(&enc->src_ilist_ptr);
1253+
fts_decode_vlc((const byte**)&enc->src_ilist_ptr);
12521254
}
12531255

12541256
/* Skip the end of word position marker. */

storage/innobase/fts/fts0que.cc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ Completed 2011/7/10 Sunny and Jimmy Yang
3434
#include "fts0pars.h"
3535
#include "fts0types.h"
3636
#include "fts0plugin.h"
37+
#include "fts0vlc.h"
3738

3839
#include <iomanip>
3940
#include <vector>
@@ -3224,7 +3225,7 @@ fts_query_filter_doc_ids(
32243225
ulint len, /*!< in: doc id ilist size */
32253226
ibool calc_doc_count) /*!< in: whether to remember doc count */
32263227
{
3227-
byte* ptr = static_cast<byte*>(data);
3228+
const byte* ptr = static_cast<byte*>(data);
32283229
doc_id_t doc_id = 0;
32293230
ulint decoded = 0;
32303231
ib_rbt_t* doc_freqs = word_freq->doc_freqs;
@@ -3234,8 +3235,8 @@ fts_query_filter_doc_ids(
32343235
ulint freq = 0;
32353236
fts_doc_freq_t* doc_freq;
32363237
fts_match_t* match = NULL;
3237-
ulint last_pos = 0;
3238-
ulint pos = fts_decode_vlc(&ptr);
3238+
doc_id_t last_pos = 0;
3239+
doc_id_t pos = fts_decode_vlc(&ptr);
32393240

32403241
/* Some sanity checks. */
32413242
if (doc_id == 0) {

storage/innobase/handler/ha_innodb.cc

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8543,8 +8543,7 @@ calc_row_difference(
85438543
&& prebuilt->table->fts
85448544
&& innobase_strcasecmp(
85458545
field->field_name, FTS_DOC_ID_COL_NAME) == 0) {
8546-
doc_id = (doc_id_t) mach_read_from_n_little_endian(
8547-
n_ptr, 8);
8546+
doc_id = mach_read_uint64_little_endian(n_ptr);
85488547
if (doc_id == 0) {
85498548
return(DB_FTS_INVALID_DOCID);
85508549
}
@@ -8787,16 +8786,6 @@ calc_row_difference(
87878786
<< innodb_table->name;
87888787

87898788
return(DB_FTS_INVALID_DOCID);
8790-
} else if ((doc_id
8791-
- prebuilt->table->fts->cache->next_doc_id)
8792-
>= FTS_DOC_ID_MAX_STEP) {
8793-
8794-
ib::warn() << "Doc ID " << doc_id << " is too"
8795-
" big. Its difference with largest"
8796-
" Doc ID used " << prebuilt->table->fts
8797-
->cache->next_doc_id - 1
8798-
<< " cannot exceed or equal to "
8799-
<< FTS_DOC_ID_MAX_STEP;
88008789
}
88018790

88028791

storage/innobase/handler/i_s.cc

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ Modified Dec 29, 2014 Jan Lindström (Added sys_semaphore_waits)
5858
#include "fil0fil.h"
5959
#include "fil0crypt.h"
6060
#include "dict0crea.h"
61+
#include "fts0vlc.h"
6162

6263
/** The latest successfully looked up innodb_fts_aux_table */
6364
UNIV_INTERN table_id_t innodb_ft_aux_table_id;
@@ -2775,7 +2776,7 @@ i_s_fts_index_cache_fill_one_index(
27752776
/* Decrypt the ilist, and display Dod ID and word position */
27762777
for (ulint i = 0; i < ib_vector_size(word->nodes); i++) {
27772778
fts_node_t* node;
2778-
byte* ptr;
2779+
const byte* ptr;
27792780
ulint decoded = 0;
27802781
doc_id_t doc_id = 0;
27812782

@@ -2785,13 +2786,11 @@ i_s_fts_index_cache_fill_one_index(
27852786
ptr = node->ilist;
27862787

27872788
while (decoded < node->ilist_size) {
2788-
ulint pos = fts_decode_vlc(&ptr);
27892789

2790-
doc_id += pos;
2790+
doc_id += fts_decode_vlc(&ptr);
27912791

27922792
/* Get position info */
27932793
while (*ptr) {
2794-
pos = fts_decode_vlc(&ptr);
27952794

27962795
OK(field_store_string(
27972796
fields[I_S_FTS_WORD],
@@ -2812,7 +2811,7 @@ i_s_fts_index_cache_fill_one_index(
28122811
doc_id, true));
28132812

28142813
OK(fields[I_S_FTS_ILIST_DOC_POS]->store(
2815-
pos, true));
2814+
fts_decode_vlc(&ptr), true));
28162815

28172816
OK(schema_table_store_record(
28182817
thd, table));
@@ -3146,7 +3145,7 @@ i_s_fts_index_table_fill_one_fetch(
31463145
/* Decrypt the ilist, and display Dod ID and word position */
31473146
for (ulint i = 0; i < ib_vector_size(word->nodes); i++) {
31483147
fts_node_t* node;
3149-
byte* ptr;
3148+
const byte* ptr;
31503149
ulint decoded = 0;
31513150
doc_id_t doc_id = 0;
31523151

@@ -3156,13 +3155,10 @@ i_s_fts_index_table_fill_one_fetch(
31563155
ptr = node->ilist;
31573156

31583157
while (decoded < node->ilist_size) {
3159-
ulint pos = fts_decode_vlc(&ptr);
3160-
3161-
doc_id += pos;
3158+
doc_id += fts_decode_vlc(&ptr);
31623159

31633160
/* Get position info */
31643161
while (*ptr) {
3165-
pos = fts_decode_vlc(&ptr);
31663162

31673163
OK(field_store_string(
31683164
fields[I_S_FTS_WORD],
@@ -3181,7 +3177,7 @@ i_s_fts_index_table_fill_one_fetch(
31813177
longlong(doc_id), true));
31823178

31833179
OK(fields[I_S_FTS_ILIST_DOC_POS]->store(
3184-
pos, true));
3180+
fts_decode_vlc(&ptr), true));
31853181

31863182
OK(schema_table_store_record(
31873183
thd, table));

0 commit comments

Comments
 (0)