** Implementation of the xIntegrity() method on the FTS3/FTS4 virtual
** table.
*/
-static int fts3Integrity(
+static int fts3IntegrityMethod(
sqlite3_vtab *pVtab, /* The virtual table to be checked */
const char *zSchema, /* Name of schema in which pVtab lives */
const char *zTabname, /* Name of the pVTab table */
char **pzErr /* Write error message here */
){
Fts3Table *p = (Fts3Table*)pVtab;
- char *zSql;
int rc;
- char *zErr = 0;
-
- assert( pzErr!=0 );
- assert( *pzErr==0 );
- UNUSED_PARAMETER(isQuick);
- zSql = sqlite3_mprintf(
- "INSERT INTO \"%w\".\"%w\"(\"%w\") VALUES('integrity-check');",
- zSchema, zTabname, zTabname);
- if( zSql==0 ){
- return SQLITE_NOMEM;
- }
- rc = sqlite3_exec(p->db, zSql, 0, 0, &zErr);
- sqlite3_free(zSql);
- if( (rc&0xff)==SQLITE_CORRUPT ){
- *pzErr = sqlite3_mprintf("malformed inverted index for FTS%d table %s.%s",
- p->bFts4 ? 4 : 3, zSchema, zTabname);
- }else if( rc!=SQLITE_OK ){
+ int bOk = 0;
+
+ rc = sqlite3Fts3IntegrityCheck(p, &bOk);
+ assert( rc!=SQLITE_CORRUPT_VTAB || bOk==0 );
+ if( rc!=SQLITE_OK && rc!=SQLITE_CORRUPT_VTAB ){
*pzErr = sqlite3_mprintf("unable to validate the inverted index for"
" FTS%d table %s.%s: %s",
- p->bFts4 ? 4 : 3, zSchema, zTabname, zErr);
+ p->bFts4 ? 4 : 3, zSchema, zTabname, sqlite3_errstr(rc));
+ }else if( bOk==0 ){
+ *pzErr = sqlite3_mprintf("malformed inverted index for FTS%d table %s.%s",
+ p->bFts4 ? 4 : 3, zSchema, zTabname);
}
- sqlite3_free(zErr);
+ sqlite3Fts3SegmentsClose(p);
return SQLITE_OK;
}
/* xRelease */ fts3ReleaseMethod,
/* xRollbackTo */ fts3RollbackToMethod,
/* xShadowName */ fts3ShadowName,
- /* xIntegrity */ fts3Integrity,
+ /* xIntegrity */ fts3IntegrityMethod,
};
/*
int sqlite3Fts3ExprIterate(Fts3Expr*, int (*x)(Fts3Expr*,int,void*), void*);
+int sqlite3Fts3IntegrityCheck(Fts3Table *p, int *pbOk);
+
#endif /* !SQLITE_CORE || SQLITE_ENABLE_FTS3 */
#endif /* _FTSINT_H */
** If an error occurs (e.g. an OOM or IO error), return an SQLite error
** code. The final value of *pbOk is undefined in this case.
*/
-static int fts3IntegrityCheck(Fts3Table *p, int *pbOk){
+int sqlite3Fts3IntegrityCheck(Fts3Table *p, int *pbOk){
int rc = SQLITE_OK; /* Return code */
u64 cksum1 = 0; /* Checksum based on FTS index contents */
u64 cksum2 = 0; /* Checksum based on %_content contents */
sqlite3_finalize(pStmt);
}
- *pbOk = (cksum1==cksum2);
+ *pbOk = (rc==SQLITE_OK && cksum1==cksum2);
return rc;
}
){
int rc;
int bOk = 0;
- rc = fts3IntegrityCheck(p, &bOk);
+ rc = sqlite3Fts3IntegrityCheck(p, &bOk);
if( rc==SQLITE_OK && bOk==0 ) rc = FTS_CORRUPT_VTAB;
return rc;
}
char **pzErr /* Write error message here */
){
Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
- Fts5Config *pConfig = pTab->p.pConfig;
- char *zSql;
- char *zErr = 0;
int rc;
+
assert( pzErr!=0 && *pzErr==0 );
UNUSED_PARAM(isQuick);
- zSql = sqlite3_mprintf(
- "INSERT INTO \"%w\".\"%w\"(\"%w\") VALUES('integrity-check');",
- zSchema, zTabname, pConfig->zName);
- if( zSql==0 ) return SQLITE_NOMEM;
- rc = sqlite3_exec(pConfig->db, zSql, 0, 0, &zErr);
- sqlite3_free(zSql);
+ rc = sqlite3Fts5StorageIntegrity(pTab->pStorage, 0);
if( (rc&0xff)==SQLITE_CORRUPT ){
*pzErr = sqlite3_mprintf("malformed inverted index for FTS5 table %s.%s",
zSchema, zTabname);
}else if( rc!=SQLITE_OK ){
*pzErr = sqlite3_mprintf("unable to validate the inverted index for"
" FTS5 table %s.%s: %s",
- zSchema, zTabname, zErr);
+ zSchema, zTabname, sqlite3_errstr(rc));
}
- sqlite3_free(zErr);
+ sqlite3Fts5IndexCloseReader(pTab->p.pIndex);
+
return SQLITE_OK;
}
PRAGMA integrity_check(t2);
} {ok}
+#-------------------------------------------------------------------
+reset_db
+
+do_execsql_test 12.1 {
+ CREATE VIRTUAL TABLE x1 USING fts5(a, b);
+ INSERT INTO x1 VALUES('one', 'two');
+ INSERT INTO x1 VALUES('three', 'four');
+ INSERT INTO x1 VALUES('five', 'six');
+}
+
+do_execsql_test 12.2 {
+ PRAGMA integrity_check
+} {ok}
+
+db close
+sqlite3 db test.db -readonly 1
+
+explain_i {
+ PRAGMA integrity_check
+ }
+do_execsql_test 12.3 {
+ PRAGMA integrity_check
+} {ok}
+
+
+
finish_test
-C When\sbacking\sout\sa\scharacter\sin\sa\sconstructed\sstring\sin\sJSON,\sfirst\smake\ssure\nthe\sstring\shas\snot\sbeen\sreset\sby\son\sOOM.
-D 2024-01-20T12:19:16.518
+C Ensure\sthat\sthe\sxIntegrity\smethods\sof\sfts3\sand\sfts5\swork\son\sread-only\sdatabases.
+D 2024-01-23T10:47:04.969
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
F ext/fts3/README.tokenizers b92bdeb8b46503f0dd301d364efc5ef59ef9fa8e2758b8e742f39fa93a2e422d
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
-F ext/fts3/fts3.c d01dfb641fc04efeeadcb94d7a8342eb07d71c1a3a3852ec8ab5e64c1fcdfff9
+F ext/fts3/fts3.c 16366d9e422be6022255fcb6bb2838387a0fe0a6afb12d14e21fe8f74386ab6a
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
-F ext/fts3/fts3Int.h be688580701d41340de73384e3acc8c55be12a438583207444bd5e20f9ef426c
+F ext/fts3/fts3Int.h 968f7d7cae541a6926146e9fd3fb2b2ccbd3845b7890a8ed03de0c06ac776682
F ext/fts3/fts3_aux.c 7eab82a9cf0830f6551ba3abfdbe73ed39e322a4d3940ee82fbf723674ecd9f3
F ext/fts3/fts3_expr.c 903bfb9433109fffb10e910d7066c49cbf8eeae316adc93f0499c4da7dfc932a
F ext/fts3/fts3_hash.c 8b6e31bfb0844c27dc6092c2620bdb1fca17ed613072db057d96952c6bdb48b7
F ext/fts3/fts3_tokenizer1.c c1de4ae28356ad98ccb8b2e3388a7fdcce7607b5523738c9afb6275dab765154
F ext/fts3/fts3_unicode.c de426ff05c1c2e7bce161cf6b706638419c3a1d9c2667de9cb9dc0458c18e226
F ext/fts3/fts3_unicode2.c 416eb7e1e81142703520d284b768ca2751d40e31fa912cae24ba74860532bf0f
-F ext/fts3/fts3_write.c 5bb4721330ca589f906e72bb824dd4080b313c6d4c4231fa541e9db32dc67982
+F ext/fts3/fts3_write.c c2d7a8dfb6e7a00c6c88ce626785cf4c50ed18eba34b5fbd53cacd60af96d0f2
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
F ext/fts3/tool/fts3cov.sh c331d006359456cf6f8f953e37f2b9c7d568f3863f00bb5f7eb87fea4ac01b73
F ext/fts3/tool/fts3view.c 413c346399159df81f86c4928b7c4a455caab73bfbc8cd68f950f632e5751674
F ext/fts5/fts5_expr.c e91156ebdcc08d837f4f324168f69f3c0d7fdef0e521fd561efb48ef3297b696
F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a0ec91b1
F ext/fts5/fts5_index.c bb1965c3965f6fe5f64160bf1c0694a9684a790a783f293a76da1d38d319b258
-F ext/fts5/fts5_main.c 94a03dd431022d706290bb81b7f2180a0bb7c98f1397b5fbc90e18d3ed8d366c
+F ext/fts5/fts5_main.c cd56ed9619e9bc55ae603ecafd5965c3684bb4c1de7dd00893c307ddf98afe88
F ext/fts5/fts5_storage.c f9e31b0d155e9b2c92d5d3a09ad7a56b937fbf1c7f962e10f4ca6281349f3934
F ext/fts5/fts5_tcl.c cf0fd0dbe64ec272491b749e0d594f563cda03336aeb60900129e6d18b0aefb8
F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee
F ext/fts5/test/fts5full.test e1701a112354e0ff9a1fdffb0c940c576530c33732ee20ac5e8361777070d717
F ext/fts5/test/fts5fuzz1.test 238d8c45f3b81342aa384de3e581ff2fa330bf922a7b69e484bbc06051a1080e
F ext/fts5/test/fts5hash.test dc7bc7e0cdeb42cfce31294ad2f8fcf43192bfd0145bb7f3ecc5465d8c72696f
-F ext/fts5/test/fts5integrity.test 0d249d351163e17e2227aa9850e68193f88a7813d16cc7d51287e554bf915b3d
+F ext/fts5/test/fts5integrity.test f1723fe9fb9381b26c946ab4d7505041434df2c449d1cd53f45c7bf8c098dfa2
F ext/fts5/test/fts5interrupt.test 09613247b273a99889808ef852898177e671406fe71fdde7ea00e78ea283d227
F ext/fts5/test/fts5lastrowid.test be98fe3e03235296585b72daad7aed5717ba0062bae5e5c18dd6e04e194c6b28
F ext/fts5/test/fts5leftjoin.test c0b4cafb9661379e576dc4405c0891d8fcc2782680740513c4d1fc114b43d4ad
F test/fts4growth.test 289833c34ad45a5e6e6133b53b6a71647231fb89d36ddcb8d9c87211b6721d7f
F test/fts4growth2.test 13ad4e76451af6e6906c95cdc725d01b00044269
F test/fts4incr.test 4e353a0bd886ea984e56fce9e77724fc923b8d0d
-F test/fts4intck1.test 43774c641fdf6607c6ee90c3db8af065a37434d55d6eaf13bafe515e8b0c5729
+F test/fts4intck1.test 54e7f28e34b72fb0c614d414bb1f568154d463c5a00b20944e893df858372ed4
F test/fts4langid.test 4be912f42454998e239a2e877600263e0394afbaba03e06cedcc5a08693a345a
F test/fts4lastrowid.test 185835895948d5325c7710649824042373b2203149abe8024a9319d25234dfd7
F test/fts4merge.test 57d093660a5093ae6e9fbd2d17592a88b45bbd66db2703c4b640b28828dbe38b
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 90dd51153fd0a6197e2ee49b5492ad120f0bfc324b60651f3d4f47c286887b46
-Q +666690eb433fe38fa527ccbbb8e2c00041a33939da4f6b8bfb737d664f28f0d8
-R b92c7203f755b0af81ba067b0b4d09c9
-U drh
-Z 339bfa943d20e7905e6df807d394df8f
+P 950bf9fe7829864e0abe6d71ca0495f346feb5d7943d76c95e55a6b86ea855da
+Q +b855886c4ccce0745af6957943e77be18949722f09821688725d546d3d79b4fb
+R 542e8b3387a0404a78fe04600e4c511f
+U dan
+Z f4b03554379000a3d3fd150f7e515fb8
# Remove this line to create a well-formed Fossil manifest.
-950bf9fe7829864e0abe6d71ca0495f346feb5d7943d76c95e55a6b86ea855da
\ No newline at end of file
+e79b97369fa740f62f695057d4a2cf8dae48a683982ec879f04a19039c9cb418
\ No newline at end of file
PRAGMA integrity_check(t2);
} {{malformed inverted index for FTS4 table main.t2}}
+#-------------------------------------------------------------------------
+# Test that integrity-check works on a read-only database.
+#
+reset_db
+do_execsql_test 3.0 {
+ CREATE VIRTUAL TABLE x1 USING fts4(a, b);
+ INSERT INTO x1 VALUES('one', 'two');
+ INSERT INTO x1 VALUES('three', 'four');
+}
+db close
+sqlite3 db test.db -readonly 1
+
+do_execsql_test 3.1 {
+ PRAGMA integrity_check;
+} {ok}
+
+
finish_test