Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add tests to check that modifying the schema of an FTS content table does not cause a crash in the FTS module. Also disable the deferred token optimization for content=xxx FTS tables. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | fts4-content |
Files: | files | file ages | folders |
SHA1: |
be86c7061b68f403730bf63ea1f7dc0d |
User & Date: | dan 2011-10-04 16:37:35.422 |
Context
2011-10-04
| ||
19:41 | Improve test coverage of fts3.c. (check-in: 0f439944ab user: dan tags: fts4-content) | |
16:37 | Add tests to check that modifying the schema of an FTS content table does not cause a crash in the FTS module. Also disable the deferred token optimization for content=xxx FTS tables. (check-in: be86c7061b user: dan tags: fts4-content) | |
11:22 | Add experimental 'content' option to FTS4. (check-in: 1d27ea741f user: dan tags: fts4-content) | |
Changes
Changes to ext/fts3/fts3.c.
︙ | ︙ | |||
4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 | int rc = SQLITE_OK; /* Return code */ int ii; /* Iterator variable for various purposes */ int nOvfl = 0; /* Total overflow pages used by doclists */ int nToken = 0; /* Total number of tokens in cluster */ int nMinEst = 0; /* The minimum count for any phrase so far. */ int nLoad4 = 1; /* (Phrases that will be loaded)^4. */ /* Count the tokens in this AND/NEAR cluster. If none of the doclists ** associated with the tokens spill onto overflow pages, or if there is ** only 1 token, exit early. No tokens to defer in this case. */ for(ii=0; ii<nTC; ii++){ if( aTC[ii].pRoot==pRoot ){ nOvfl += aTC[ii].nOvfl; | > > > > > > > > > | 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 | int rc = SQLITE_OK; /* Return code */ int ii; /* Iterator variable for various purposes */ int nOvfl = 0; /* Total overflow pages used by doclists */ int nToken = 0; /* Total number of tokens in cluster */ int nMinEst = 0; /* The minimum count for any phrase so far. */ int nLoad4 = 1; /* (Phrases that will be loaded)^4. */ /* Tokens are never deferred for FTS tables created using the content=xxx ** option. The reason being that it is not guaranteed that the content ** table actually contains the same data as the index. To prevent this from ** causing any problems, the deferred token optimization is completely ** disabled for content=xxx tables. */ if( pTab->zContentTbl ){ return SQLITE_OK; } /* Count the tokens in this AND/NEAR cluster. If none of the doclists ** associated with the tokens spill onto overflow pages, or if there is ** only 1 token, exit early. No tokens to defer in this case. */ for(ii=0; ii<nTC; ii++){ if( aTC[ii].pRoot==pRoot ){ nOvfl += aTC[ii].nOvfl; |
︙ | ︙ |
Changes to ext/fts3/fts3Int.h.
︙ | ︙ | |||
221 222 223 224 225 226 227 | int nPrefix; /* Prefix length (0 for main terms index) */ Fts3Hash hPending; /* Pending terms table for this index */ } *aIndex; int nMaxPendingData; /* Max pending data before flush to disk */ int nPendingData; /* Current bytes of pending data */ sqlite_int64 iPrevDocid; /* Docid of most recently inserted document */ | | < | 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 | int nPrefix; /* Prefix length (0 for main terms index) */ Fts3Hash hPending; /* Pending terms table for this index */ } *aIndex; int nMaxPendingData; /* Max pending data before flush to disk */ int nPendingData; /* Current bytes of pending data */ sqlite_int64 iPrevDocid; /* Docid of most recently inserted document */ #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) /* State variables used for validating that the transaction control ** methods of the virtual table are called at appropriate times. These ** values do not contribution to the FTS computation; they are used for ** verifying the SQLite core. */ int inTransaction; /* True after xBegin but before xCommit/xRollback */ int mxSavepoint; /* Largest valid xSavepoint integer */ #endif }; /* ** When the core wants to read from the virtual table, it creates a ** virtual table cursor (an instance of the following structure) using ** the xOpen method. Cursors are destroyed using the xClose method. */ struct Fts3Cursor { sqlite3_vtab_cursor base; /* Base class used by SQLite core */ i16 eSearch; /* Search strategy (see below) */ u8 isEof; /* True if at End Of Results */ u8 isRequireSeek; /* True if must seek pStmt to %_content row */ sqlite3_stmt *pStmt; /* Prepared statement in use by the cursor */ Fts3Expr *pExpr; /* Parsed MATCH query string */ int nPhrase; /* Number of matchable phrases in query */ Fts3DeferredToken *pDeferred; /* Deferred search tokens, if any */ sqlite3_int64 iPrevId; /* Previous id read from aDoclist */ char *pNextId; /* Pointer into the body of aDoclist */ char *aDoclist; /* List of docids for full-text queries */ |
︙ | ︙ |
Changes to test/fts4content.test.
︙ | ︙ | |||
17 18 19 20 21 22 23 24 25 26 27 28 29 30 | set ::testprefix fts4content # If SQLITE_ENABLE_FTS3 is defined, omit this file. ifcapable !fts3 { finish_test return } do_execsql_test 1.1 { CREATE TABLE t1(a, b, c); INSERT INTO t1 VALUES('w x', 'x y', 'y z'); CREATE VIRTUAL TABLE ft1 USING fts4(content=t1); } | > > > > > > > > > > > > > > > > > > | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | set ::testprefix fts4content # If SQLITE_ENABLE_FTS3 is defined, omit this file. ifcapable !fts3 { finish_test return } #------------------------------------------------------------------------- # Test organization: # # 1.* - Warm-body tests. # # 2.* - Querying a content=xxx FTS table. # # 3.* - Writing to a content=xxx FTS table. # # 4.* - The "INSERT INTO fts(fts) VALUES('rebuild')" command. # # 5.* - Check that CREATE TABLE, DROP TABLE and ALTER TABLE correctly # ignore any %_content table when used with the content=xxx option. # # 6.* - Test the effects of messing with the schema of table xxx after # creating a content=xxx FTS index. # do_execsql_test 1.1 { CREATE TABLE t1(a, b, c); INSERT INTO t1 VALUES('w x', 'x y', 'y z'); CREATE VIRTUAL TABLE ft1 USING fts4(content=t1); } |
︙ | ︙ | |||
358 359 360 361 362 363 364 365 366 | CREATE VIRTUAL TABLE ft5 USING fts4(content=t5); CREATE TABLE t5_content(a, b); DROP TABLE ft5; SELECT name FROM sqlite_master WHERE name LIKE '%t5%'; } { t5 t5_content } finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 | CREATE VIRTUAL TABLE ft5 USING fts4(content=t5); CREATE TABLE t5_content(a, b); DROP TABLE ft5; SELECT name FROM sqlite_master WHERE name LIKE '%t5%'; } { t5 t5_content } #------------------------------------------------------------------------- # Test cases 6.* test # do_catchsql_test 6.1.1 { CREATE VIRTUAL TABLE ft7 USING fts4(content=t7); } {1 {vtable constructor failed: ft7}} do_execsql_test 6.2.1 { CREATE TABLE t7(one, two); CREATE VIRTUAL TABLE ft7 USING fts4(content=t7); INSERT INTO t7 VALUES('A B', 'B A'); INSERT INTO t7 VALUES('C D', 'A A'); SELECT * FROM ft7; } { {A B} {B A} {C D} {A A} } do_catchsql_test 6.2.2 { DROP TABLE t7; SELECT * FROM ft7; } {1 {SQL logic error or missing database}} db close sqlite3 db test.db do_execsql_test 6.2.3 { SELECT name FROM sqlite_master WHERE name LIKE '%t7%' } { ft7 ft7_segments ft7_segdir sqlite_autoindex_ft7_segdir_1 ft7_docsize ft7_stat } do_catchsql_test 6.2.4 { SELECT * FROM ft7; } {1 {vtable constructor failed: ft7}} do_execsql_test 6.2.5 { CREATE TABLE t7(x, y); INSERT INTO t7 VALUES('A B', 'B A'); INSERT INTO t7 VALUES('C D', 'A A'); SELECT * FROM ft7; } { {A B} {B A} {C D} {A A} } do_execsql_test 6.2.6 { INSERT INTO ft7(ft7) VALUES('rebuild'); SELECT rowid FROM ft7 WHERE ft7 MATCH '"A A"'; } {2} do_execsql_test 6.2.7 { DROP TABLE t7; CREATE TABLE t7(x); } do_catchsql_test 6.2.8 { SELECT rowid FROM ft7 WHERE ft7 MATCH '"A A"'; } {1 {SQL logic error or missing database}} do_catchsql_test 6.2.9 { SELECT rowid FROM ft7 WHERE ft7 MATCH '"A A"'; } {1 {SQL logic error or missing database}} db close sqlite3 db test.db do_catchsql_test 6.2.10 { SELECT rowid FROM ft7 WHERE ft7 MATCH '"A A"'; } {0 2} do_catchsql_test 6.2.11 { SELECT rowid, * FROM ft7 WHERE ft7 MATCH '"A A"'; } {0 {2 {}}} finish_test |
Changes to test/permutations.test.
︙ | ︙ | |||
179 180 181 182 183 184 185 186 187 188 189 190 191 192 | fts3atoken.test fts3b.test fts3c.test fts3cov.test fts3d.test fts3defer.test fts3defer2.test fts3e.test fts3expr.test fts3expr2.test fts3near.test fts3query.test fts3shared.test fts3snippet.test fts3sort.test fts3fault.test fts3malloc.test fts3matchinfo.test fts3aux1.test fts3comp1.test fts3auto.test fts4aa.test fts4content.test } lappend ::testsuitelist xxx #------------------------------------------------------------------------- # Define the coverage related test suites: # | > > | 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | fts3atoken.test fts3b.test fts3c.test fts3cov.test fts3d.test fts3defer.test fts3defer2.test fts3e.test fts3expr.test fts3expr2.test fts3near.test fts3query.test fts3shared.test fts3snippet.test fts3sort.test fts3fault.test fts3malloc.test fts3matchinfo.test fts3aux1.test fts3comp1.test fts3auto.test fts4aa.test fts4content.test fts3conf.test fts3prefix.test fts3fault2.test fts3corrupt.test fts3corrupt2.test } lappend ::testsuitelist xxx #------------------------------------------------------------------------- # Define the coverage related test suites: # |
︙ | ︙ |