Skip to content

Commit f05bd8b

Browse files
dandan
authored andcommitted
Ensure that the xIntegrity methods of fts3 and fts5 work on read-only databases.
FossilOrigin-Name: e79b97369fa740f62f695057d4a2cf8dae48a683982ec879f04a19039c9cb418
1 parent b5c5f36 commit f05bd8b

8 files changed

Lines changed: 79 additions & 50 deletions

File tree

ext/fts3/fts3.c

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4006,38 +4006,28 @@ static int fts3ShadowName(const char *zName){
40064006
** Implementation of the xIntegrity() method on the FTS3/FTS4 virtual
40074007
** table.
40084008
*/
4009-
static int fts3Integrity(
4009+
static int fts3IntegrityMethod(
40104010
sqlite3_vtab *pVtab, /* The virtual table to be checked */
40114011
const char *zSchema, /* Name of schema in which pVtab lives */
40124012
const char *zTabname, /* Name of the pVTab table */
40134013
int isQuick, /* True if this is a quick_check */
40144014
char **pzErr /* Write error message here */
40154015
){
40164016
Fts3Table *p = (Fts3Table*)pVtab;
4017-
char *zSql;
40184017
int rc;
4019-
char *zErr = 0;
4020-
4021-
assert( pzErr!=0 );
4022-
assert( *pzErr==0 );
4023-
UNUSED_PARAMETER(isQuick);
4024-
zSql = sqlite3_mprintf(
4025-
"INSERT INTO \"%w\".\"%w\"(\"%w\") VALUES('integrity-check');",
4026-
zSchema, zTabname, zTabname);
4027-
if( zSql==0 ){
4028-
return SQLITE_NOMEM;
4029-
}
4030-
rc = sqlite3_exec(p->db, zSql, 0, 0, &zErr);
4031-
sqlite3_free(zSql);
4032-
if( (rc&0xff)==SQLITE_CORRUPT ){
4033-
*pzErr = sqlite3_mprintf("malformed inverted index for FTS%d table %s.%s",
4034-
p->bFts4 ? 4 : 3, zSchema, zTabname);
4035-
}else if( rc!=SQLITE_OK ){
4018+
int bOk = 0;
4019+
4020+
rc = sqlite3Fts3IntegrityCheck(p, &bOk);
4021+
assert( rc!=SQLITE_CORRUPT_VTAB || bOk==0 );
4022+
if( rc!=SQLITE_OK && rc!=SQLITE_CORRUPT_VTAB ){
40364023
*pzErr = sqlite3_mprintf("unable to validate the inverted index for"
40374024
" FTS%d table %s.%s: %s",
4038-
p->bFts4 ? 4 : 3, zSchema, zTabname, zErr);
4025+
p->bFts4 ? 4 : 3, zSchema, zTabname, sqlite3_errstr(rc));
4026+
}else if( bOk==0 ){
4027+
*pzErr = sqlite3_mprintf("malformed inverted index for FTS%d table %s.%s",
4028+
p->bFts4 ? 4 : 3, zSchema, zTabname);
40394029
}
4040-
sqlite3_free(zErr);
4030+
sqlite3Fts3SegmentsClose(p);
40414031
return SQLITE_OK;
40424032
}
40434033

@@ -4068,7 +4058,7 @@ static const sqlite3_module fts3Module = {
40684058
/* xRelease */ fts3ReleaseMethod,
40694059
/* xRollbackTo */ fts3RollbackToMethod,
40704060
/* xShadowName */ fts3ShadowName,
4071-
/* xIntegrity */ fts3Integrity,
4061+
/* xIntegrity */ fts3IntegrityMethod,
40724062
};
40734063

40744064
/*

ext/fts3/fts3Int.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,5 +653,7 @@ int sqlite3FtsUnicodeIsdiacritic(int);
653653

654654
int sqlite3Fts3ExprIterate(Fts3Expr*, int (*x)(Fts3Expr*,int,void*), void*);
655655

656+
int sqlite3Fts3IntegrityCheck(Fts3Table *p, int *pbOk);
657+
656658
#endif /* !SQLITE_CORE || SQLITE_ENABLE_FTS3 */
657659
#endif /* _FTSINT_H */

ext/fts3/fts3_write.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5294,7 +5294,7 @@ static u64 fts3ChecksumIndex(
52945294
** If an error occurs (e.g. an OOM or IO error), return an SQLite error
52955295
** code. The final value of *pbOk is undefined in this case.
52965296
*/
5297-
static int fts3IntegrityCheck(Fts3Table *p, int *pbOk){
5297+
int sqlite3Fts3IntegrityCheck(Fts3Table *p, int *pbOk){
52985298
int rc = SQLITE_OK; /* Return code */
52995299
u64 cksum1 = 0; /* Checksum based on FTS index contents */
53005300
u64 cksum2 = 0; /* Checksum based on %_content contents */
@@ -5372,7 +5372,7 @@ static int fts3IntegrityCheck(Fts3Table *p, int *pbOk){
53725372
sqlite3_finalize(pStmt);
53735373
}
53745374

5375-
*pbOk = (cksum1==cksum2);
5375+
*pbOk = (rc==SQLITE_OK && cksum1==cksum2);
53765376
return rc;
53775377
}
53785378

@@ -5412,7 +5412,7 @@ static int fts3DoIntegrityCheck(
54125412
){
54135413
int rc;
54145414
int bOk = 0;
5415-
rc = fts3IntegrityCheck(p, &bOk);
5415+
rc = sqlite3Fts3IntegrityCheck(p, &bOk);
54165416
if( rc==SQLITE_OK && bOk==0 ) rc = FTS_CORRUPT_VTAB;
54175417
return rc;
54185418
}

ext/fts5/fts5_main.c

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2971,27 +2971,21 @@ static int fts5IntegrityMethod(
29712971
char **pzErr /* Write error message here */
29722972
){
29732973
Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
2974-
Fts5Config *pConfig = pTab->p.pConfig;
2975-
char *zSql;
2976-
char *zErr = 0;
29772974
int rc;
2975+
29782976
assert( pzErr!=0 && *pzErr==0 );
29792977
UNUSED_PARAM(isQuick);
2980-
zSql = sqlite3_mprintf(
2981-
"INSERT INTO \"%w\".\"%w\"(\"%w\") VALUES('integrity-check');",
2982-
zSchema, zTabname, pConfig->zName);
2983-
if( zSql==0 ) return SQLITE_NOMEM;
2984-
rc = sqlite3_exec(pConfig->db, zSql, 0, 0, &zErr);
2985-
sqlite3_free(zSql);
2978+
rc = sqlite3Fts5StorageIntegrity(pTab->pStorage, 0);
29862979
if( (rc&0xff)==SQLITE_CORRUPT ){
29872980
*pzErr = sqlite3_mprintf("malformed inverted index for FTS5 table %s.%s",
29882981
zSchema, zTabname);
29892982
}else if( rc!=SQLITE_OK ){
29902983
*pzErr = sqlite3_mprintf("unable to validate the inverted index for"
29912984
" FTS5 table %s.%s: %s",
2992-
zSchema, zTabname, zErr);
2985+
zSchema, zTabname, sqlite3_errstr(rc));
29932986
}
2994-
sqlite3_free(zErr);
2987+
sqlite3Fts5IndexCloseReader(pTab->p.pIndex);
2988+
29952989
return SQLITE_OK;
29962990
}
29972991

ext/fts5/test/fts5integrity.test

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,4 +355,30 @@ do_execsql_test 11.4 {
355355
PRAGMA integrity_check(t2);
356356
} {ok}
357357

358+
#-------------------------------------------------------------------
359+
reset_db
360+
361+
do_execsql_test 12.1 {
362+
CREATE VIRTUAL TABLE x1 USING fts5(a, b);
363+
INSERT INTO x1 VALUES('one', 'two');
364+
INSERT INTO x1 VALUES('three', 'four');
365+
INSERT INTO x1 VALUES('five', 'six');
366+
}
367+
368+
do_execsql_test 12.2 {
369+
PRAGMA integrity_check
370+
} {ok}
371+
372+
db close
373+
sqlite3 db test.db -readonly 1
374+
375+
explain_i {
376+
PRAGMA integrity_check
377+
}
378+
do_execsql_test 12.3 {
379+
PRAGMA integrity_check
380+
} {ok}
381+
382+
383+
358384
finish_test

manifest

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
C When\sbacking\sout\sa\scharacter\sin\sa\sconstructed\sstring\sin\sJSON,\sfirst\smake\ssure\nthe\sstring\shas\snot\sbeen\sreset\sby\son\sOOM.
2-
D 2024-01-20T12:19:16.518
1+
C Ensure\sthat\sthe\sxIntegrity\smethods\sof\sfts3\sand\sfts5\swork\son\sread-only\sdatabases.
2+
D 2024-01-23T10:47:04.969
33
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
44
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
55
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -63,9 +63,9 @@ F ext/fts3/README.content b9078d0843a094d86af0d48dffbff13c906702b4c3558012e67b9c
6363
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
6464
F ext/fts3/README.tokenizers b92bdeb8b46503f0dd301d364efc5ef59ef9fa8e2758b8e742f39fa93a2e422d
6565
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
66-
F ext/fts3/fts3.c d01dfb641fc04efeeadcb94d7a8342eb07d71c1a3a3852ec8ab5e64c1fcdfff9
66+
F ext/fts3/fts3.c 16366d9e422be6022255fcb6bb2838387a0fe0a6afb12d14e21fe8f74386ab6a
6767
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
68-
F ext/fts3/fts3Int.h be688580701d41340de73384e3acc8c55be12a438583207444bd5e20f9ef426c
68+
F ext/fts3/fts3Int.h 968f7d7cae541a6926146e9fd3fb2b2ccbd3845b7890a8ed03de0c06ac776682
6969
F ext/fts3/fts3_aux.c 7eab82a9cf0830f6551ba3abfdbe73ed39e322a4d3940ee82fbf723674ecd9f3
7070
F ext/fts3/fts3_expr.c 903bfb9433109fffb10e910d7066c49cbf8eeae316adc93f0499c4da7dfc932a
7171
F ext/fts3/fts3_hash.c 8b6e31bfb0844c27dc6092c2620bdb1fca17ed613072db057d96952c6bdb48b7
@@ -81,7 +81,7 @@ F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3
8181
F ext/fts3/fts3_tokenizer1.c c1de4ae28356ad98ccb8b2e3388a7fdcce7607b5523738c9afb6275dab765154
8282
F ext/fts3/fts3_unicode.c de426ff05c1c2e7bce161cf6b706638419c3a1d9c2667de9cb9dc0458c18e226
8383
F ext/fts3/fts3_unicode2.c 416eb7e1e81142703520d284b768ca2751d40e31fa912cae24ba74860532bf0f
84-
F ext/fts3/fts3_write.c 5bb4721330ca589f906e72bb824dd4080b313c6d4c4231fa541e9db32dc67982
84+
F ext/fts3/fts3_write.c c2d7a8dfb6e7a00c6c88ce626785cf4c50ed18eba34b5fbd53cacd60af96d0f2
8585
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
8686
F ext/fts3/tool/fts3cov.sh c331d006359456cf6f8f953e37f2b9c7d568f3863f00bb5f7eb87fea4ac01b73
8787
F ext/fts3/tool/fts3view.c 413c346399159df81f86c4928b7c4a455caab73bfbc8cd68f950f632e5751674
@@ -98,7 +98,7 @@ F ext/fts5/fts5_config.c 8072a207034b51ae9b7694121d1b5715c794e94b275e088f70ae532
9898
F ext/fts5/fts5_expr.c e91156ebdcc08d837f4f324168f69f3c0d7fdef0e521fd561efb48ef3297b696
9999
F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a0ec91b1
100100
F ext/fts5/fts5_index.c bb1965c3965f6fe5f64160bf1c0694a9684a790a783f293a76da1d38d319b258
101-
F ext/fts5/fts5_main.c 94a03dd431022d706290bb81b7f2180a0bb7c98f1397b5fbc90e18d3ed8d366c
101+
F ext/fts5/fts5_main.c cd56ed9619e9bc55ae603ecafd5965c3684bb4c1de7dd00893c307ddf98afe88
102102
F ext/fts5/fts5_storage.c f9e31b0d155e9b2c92d5d3a09ad7a56b937fbf1c7f962e10f4ca6281349f3934
103103
F ext/fts5/fts5_tcl.c cf0fd0dbe64ec272491b749e0d594f563cda03336aeb60900129e6d18b0aefb8
104104
F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee
@@ -176,7 +176,7 @@ F ext/fts5/test/fts5first.test 3fcf2365c00a15fc9704233674789a3b95131d12de18a9b99
176176
F ext/fts5/test/fts5full.test e1701a112354e0ff9a1fdffb0c940c576530c33732ee20ac5e8361777070d717
177177
F ext/fts5/test/fts5fuzz1.test 238d8c45f3b81342aa384de3e581ff2fa330bf922a7b69e484bbc06051a1080e
178178
F ext/fts5/test/fts5hash.test dc7bc7e0cdeb42cfce31294ad2f8fcf43192bfd0145bb7f3ecc5465d8c72696f
179-
F ext/fts5/test/fts5integrity.test 0d249d351163e17e2227aa9850e68193f88a7813d16cc7d51287e554bf915b3d
179+
F ext/fts5/test/fts5integrity.test f1723fe9fb9381b26c946ab4d7505041434df2c449d1cd53f45c7bf8c098dfa2
180180
F ext/fts5/test/fts5interrupt.test 09613247b273a99889808ef852898177e671406fe71fdde7ea00e78ea283d227
181181
F ext/fts5/test/fts5lastrowid.test be98fe3e03235296585b72daad7aed5717ba0062bae5e5c18dd6e04e194c6b28
182182
F ext/fts5/test/fts5leftjoin.test c0b4cafb9661379e576dc4405c0891d8fcc2782680740513c4d1fc114b43d4ad
@@ -1197,7 +1197,7 @@ F test/fts4docid.test e33c383cfbdff0284685604d256f347a18fdbf01
11971197
F test/fts4growth.test 289833c34ad45a5e6e6133b53b6a71647231fb89d36ddcb8d9c87211b6721d7f
11981198
F test/fts4growth2.test 13ad4e76451af6e6906c95cdc725d01b00044269
11991199
F test/fts4incr.test 4e353a0bd886ea984e56fce9e77724fc923b8d0d
1200-
F test/fts4intck1.test 43774c641fdf6607c6ee90c3db8af065a37434d55d6eaf13bafe515e8b0c5729
1200+
F test/fts4intck1.test 54e7f28e34b72fb0c614d414bb1f568154d463c5a00b20944e893df858372ed4
12011201
F test/fts4langid.test 4be912f42454998e239a2e877600263e0394afbaba03e06cedcc5a08693a345a
12021202
F test/fts4lastrowid.test 185835895948d5325c7710649824042373b2203149abe8024a9319d25234dfd7
12031203
F test/fts4merge.test 57d093660a5093ae6e9fbd2d17592a88b45bbd66db2703c4b640b28828dbe38b
@@ -2157,9 +2157,9 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
21572157
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
21582158
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
21592159
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
2160-
P 90dd51153fd0a6197e2ee49b5492ad120f0bfc324b60651f3d4f47c286887b46
2161-
Q +666690eb433fe38fa527ccbbb8e2c00041a33939da4f6b8bfb737d664f28f0d8
2162-
R b92c7203f755b0af81ba067b0b4d09c9
2163-
U drh
2164-
Z 339bfa943d20e7905e6df807d394df8f
2160+
P 950bf9fe7829864e0abe6d71ca0495f346feb5d7943d76c95e55a6b86ea855da
2161+
Q +b855886c4ccce0745af6957943e77be18949722f09821688725d546d3d79b4fb
2162+
R 542e8b3387a0404a78fe04600e4c511f
2163+
U dan
2164+
Z f4b03554379000a3d3fd150f7e515fb8
21652165
# Remove this line to create a well-formed Fossil manifest.

manifest.uuid

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
950bf9fe7829864e0abe6d71ca0495f346feb5d7943d76c95e55a6b86ea855da
1+
e79b97369fa740f62f695057d4a2cf8dae48a683982ec879f04a19039c9cb418

test/fts4intck1.test

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,5 +54,22 @@ do_execsql_test 2.3 {
5454
PRAGMA integrity_check(t2);
5555
} {{malformed inverted index for FTS4 table main.t2}}
5656

57+
#-------------------------------------------------------------------------
58+
# Test that integrity-check works on a read-only database.
59+
#
60+
reset_db
61+
do_execsql_test 3.0 {
62+
CREATE VIRTUAL TABLE x1 USING fts4(a, b);
63+
INSERT INTO x1 VALUES('one', 'two');
64+
INSERT INTO x1 VALUES('three', 'four');
65+
}
66+
db close
67+
sqlite3 db test.db -readonly 1
68+
69+
do_execsql_test 3.1 {
70+
PRAGMA integrity_check;
71+
} {ok}
72+
73+
5774

5875
finish_test

0 commit comments

Comments
 (0)