Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Tests and minor fixes to improve coverage of FTS5 code. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
f4de6d450e143cb1dd5447800d4b178e |
User & Date: | dan 2015-10-14 21:08:48.055 |
Context
2015-10-14
| ||
22:46 | In the MSVC makefile, make sure LDFLAGS is used for the tool executables as well. (check-in: 0a17ee49c6 user: mistachkin tags: trunk) | |
21:08 | Tests and minor fixes to improve coverage of FTS5 code. (check-in: f4de6d450e user: dan tags: trunk) | |
20:34 | Fix harmless compiler warnings. (check-in: 1c46c194a2 user: mistachkin tags: trunk) | |
Changes
Changes to ext/fts5/fts5_index.c.
︙ | ︙ | |||
1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 | } pIter->iLeafOffset = iOff; }else if( pIter->pSeg==0 ){ const u8 *pList = 0; const char *zTerm = 0; int nList = 0; if( 0==(pIter->flags & FTS5_SEGITER_ONETERM) ){ sqlite3Fts5HashScanNext(p->pHash); sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &pList, &nList); } if( pList==0 ){ fts5DataRelease(pIter->pLeaf); pIter->pLeaf = 0; }else{ pIter->pLeaf->p = (u8*)pList; pIter->pLeaf->nn = nList; pIter->pLeaf->szLeaf = nList; pIter->iEndofDoclist = nList+1; sqlite3Fts5BufferSet(&p->rc, &pIter->term, (int)strlen(zTerm), (u8*)zTerm); pIter->iLeafOffset = fts5GetVarint(pList, (u64*)&pIter->iRowid); | > | | 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 | } pIter->iLeafOffset = iOff; }else if( pIter->pSeg==0 ){ const u8 *pList = 0; const char *zTerm = 0; int nList = 0; assert( (pIter->flags & FTS5_SEGITER_ONETERM) || pbNewTerm ); if( 0==(pIter->flags & FTS5_SEGITER_ONETERM) ){ sqlite3Fts5HashScanNext(p->pHash); sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &pList, &nList); } if( pList==0 ){ fts5DataRelease(pIter->pLeaf); pIter->pLeaf = 0; }else{ pIter->pLeaf->p = (u8*)pList; pIter->pLeaf->nn = nList; pIter->pLeaf->szLeaf = nList; pIter->iEndofDoclist = nList+1; sqlite3Fts5BufferSet(&p->rc, &pIter->term, (int)strlen(zTerm), (u8*)zTerm); pIter->iLeafOffset = fts5GetVarint(pList, (u64*)&pIter->iRowid); *pbNewTerm = 1; } }else{ iOff = 0; /* Next entry is not on the current page */ while( iOff==0 ){ fts5SegIterNextPage(p, pIter); pLeaf = pIter->pLeaf; |
︙ | ︙ | |||
4031 4032 4033 4034 4035 4036 4037 | if( 0==fts5BufferGrow(&p->rc, pBuf, pSeg->nPos) ){ if( pColset==0 ){ fts5ChunkIterate(p, pSeg, (void*)pBuf, fts5PoslistCallback); }else{ PoslistCallbackCtx sCtx; sCtx.pBuf = pBuf; sCtx.pColset = pColset; | | | 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 | if( 0==fts5BufferGrow(&p->rc, pBuf, pSeg->nPos) ){ if( pColset==0 ){ fts5ChunkIterate(p, pSeg, (void*)pBuf, fts5PoslistCallback); }else{ PoslistCallbackCtx sCtx; sCtx.pBuf = pBuf; sCtx.pColset = pColset; sCtx.eState = fts5IndexColsetTest(pColset, 0); assert( sCtx.eState==0 || sCtx.eState==1 ); fts5ChunkIterate(p, pSeg, (void*)&sCtx, fts5PoslistFilterCallback); } } } /* |
︙ | ︙ | |||
5192 5193 5194 5195 5196 5197 5198 | if( res<0 ) p->rc = FTS5_CORRUPT; } fts5IntegrityCheckPgidx(p, pLeaf); } fts5DataRelease(pLeaf); if( p->rc ) break; | < | 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 | if( res<0 ) p->rc = FTS5_CORRUPT; } fts5IntegrityCheckPgidx(p, pLeaf); } fts5DataRelease(pLeaf); if( p->rc ) break; /* Now check that the iter.nEmpty leaves following the current leaf ** (a) exist and (b) contain no terms. */ fts5IndexIntegrityCheckEmpty( p, pSeg, iIdxPrevLeaf+1, iDlidxPrevLeaf+1, iIdxLeaf-1 ); if( p->rc ) break; |
︙ | ︙ |
Changes to ext/fts5/fts5_main.c.
︙ | ︙ | |||
443 444 445 446 447 448 449 | /* ** Set the SQLITE_INDEX_SCAN_UNIQUE flag in pIdxInfo->flags. Unless this ** extension is currently being used by a version of SQLite too old to ** support index-info flags. In that case this function is a no-op. */ static void fts5SetUniqueFlag(sqlite3_index_info *pIdxInfo){ #if SQLITE_VERSION_NUMBER>=3008012 | > | > > | 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 | /* ** Set the SQLITE_INDEX_SCAN_UNIQUE flag in pIdxInfo->flags. Unless this ** extension is currently being used by a version of SQLite too old to ** support index-info flags. In that case this function is a no-op. */ static void fts5SetUniqueFlag(sqlite3_index_info *pIdxInfo){ #if SQLITE_VERSION_NUMBER>=3008012 #ifndef SQLITE_CORE if( sqlite3_libversion_number()>=3008012 ) #endif { pIdxInfo->idxFlags |= SQLITE_INDEX_SCAN_UNIQUE; } #endif } /* ** Implementation of the xBestIndex method for FTS5 tables. Within the |
︙ | ︙ |
Changes to ext/fts5/fts5_storage.c.
︙ | ︙ | |||
721 722 723 724 725 726 727 | *piRowid = sqlite3_value_int64(apVal[1]); }else{ rc = fts5StorageNewRowid(p, piRowid); } }else{ sqlite3_stmt *pInsert = 0; /* Statement to write %_content table */ int i; /* Counter variable */ | < < < < < < < < < | < | 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 | *piRowid = sqlite3_value_int64(apVal[1]); }else{ rc = fts5StorageNewRowid(p, piRowid); } }else{ sqlite3_stmt *pInsert = 0; /* Statement to write %_content table */ int i; /* Counter variable */ rc = fts5StorageGetStmt(p, FTS5_STMT_INSERT_CONTENT, &pInsert, 0); for(i=1; rc==SQLITE_OK && i<=pConfig->nCol+1; i++){ rc = sqlite3_bind_value(pInsert, i, apVal[i]); } if( rc==SQLITE_OK ){ sqlite3_step(pInsert); rc = sqlite3_reset(pInsert); } |
︙ | ︙ |
Changes to ext/fts5/test/fts5aa.test.
︙ | ︙ | |||
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | } do_execsql_test 6.3 { REPLACE INTO t1(rowid, x, y) VALUES('22', 'l l l', 'l l l'); } do_execsql_test 6.4 { INSERT INTO t1(t1) VALUES('integrity-check') } #------------------------------------------------------------------------- # reset_db expr srand(0) do_execsql_test 7.0 { CREATE VIRTUAL TABLE t1 USING fts5(x,y,z); | > > > > > > > > > > > | 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 | } do_execsql_test 6.3 { REPLACE INTO t1(rowid, x, y) VALUES('22', 'l l l', 'l l l'); } do_execsql_test 6.4 { REPLACE INTO t1(x, y) VALUES('x y z', 'x y z'); } do_execsql_test 6.5 { INSERT INTO t1(t1) VALUES('integrity-check') } do_execsql_test 6.6 { SELECT rowid, * FROM t1; } { 22 {l l l} {l l l} 23 {x y z} {x y z} } #------------------------------------------------------------------------- # reset_db expr srand(0) do_execsql_test 7.0 { CREATE VIRTUAL TABLE t1 USING fts5(x,y,z); |
︙ | ︙ |
Changes to ext/fts5/test/fts5corrupt3.test.
︙ | ︙ | |||
246 247 248 249 250 251 252 | } set {} {} } {} catch { db eval ROLLBACK } } } | < < | 246 247 248 249 250 251 252 253 254 255 256 257 258 259 | } set {} {} } {} catch { db eval ROLLBACK } } } #------------------------------------------------------------------------ # reset_db do_execsql_test 6.1.0 { CREATE VIRTUAL TABLE t1 USING fts5(a); INSERT INTO t1 VALUES('bbbbb ccccc'); SELECT quote(block) FROM t1_data WHERE rowid>100; |
︙ | ︙ | |||
331 332 333 334 335 336 337 338 339 340 | ----------^^----------------------------------------------------- WHERE id>100; } do_catchsql_test 6.3.5 { INSERT INTO t1(t1) VALUES('integrity-check'); } {1 {database disk image is malformed}} sqlite3_fts5_may_be_corrupt 0 finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 | ----------^^----------------------------------------------------- WHERE id>100; } do_catchsql_test 6.3.5 { INSERT INTO t1(t1) VALUES('integrity-check'); } {1 {database disk image is malformed}} } #------------------------------------------------------------------------ # reset_db reset_db proc rnddoc {n} { set map [list a b c d] set doc [list] for {set i 0} {$i < $n} {incr i} { lappend doc "x[lindex $map [expr int(rand()*4)]]" } set doc } db func rnddoc rnddoc do_test 7.0 { execsql { CREATE VIRTUAL TABLE t5 USING fts5(x); INSERT INTO t5 VALUES( rnddoc(10000) ); INSERT INTO t5 VALUES( rnddoc(10000) ); INSERT INTO t5 VALUES( rnddoc(10000) ); INSERT INTO t5 VALUES( rnddoc(10000) ); INSERT INTO t5(t5) VALUES('optimize'); } } {} do_test 7.1 { foreach i [db eval { SELECT rowid FROM t5_data WHERE rowid>100 }] { db eval BEGIN db eval {DELETE FROM t5_data WHERE rowid = $i} set r [catchsql { INSERT INTO t5(t5) VALUES('integrity-check')} ] if {$r != "1 {database disk image is malformed}"} { error $r } db eval ROLLBACK } } {} sqlite3_fts5_may_be_corrupt 0 finish_test |
Changes to ext/fts5/test/fts5fault7.test.
︙ | ︙ | |||
82 83 84 85 86 87 88 89 90 91 | INSERT INTO t2 VALUES('e a d a e d'); } } -body { db eval COMMIT } -test { faultsim_test_result {0 {}} } finish_test | > > > > > > > > > > > > > > > > > > > > > | 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | INSERT INTO t2 VALUES('e a d a e d'); } } -body { db eval COMMIT } -test { faultsim_test_result {0 {}} } #------------------------------------------------------------------------- # Test fault-injection when a segment is promoted. # reset_db do_execsql_test 2.0 { CREATE VIRTUAL TABLE xy USING fts5(x); INSERT INTO xy(rowid, x) VALUES(1, '1 2 3'); INSERT INTO xy(rowid, x) VALUES(2, '2 3 4'); INSERT INTO xy(rowid, x) VALUES(3, '3 4 5'); } faultsim_save_and_close do_faultsim_test 2 -faults oom-* -prep { faultsim_restore_and_reopen } -body { db eval { UPDATE OR REPLACE xy SET rowid=3 WHERE rowid = 2 } } -test { faultsim_test_result {0 {}} } finish_test |
Changes to ext/fts5/test/fts5hash.test.
︙ | ︙ | |||
80 81 82 83 84 85 86 | set hash [sqlite3_fts5_token_hash 1024 xyz] set vocab [build_vocab1 -prefix xyz -hash $hash] lappend vocab xyz do_execsql_test 1.1 { CREATE VIRTUAL TABLE vocab USING fts5vocab(eee, 'row'); BEGIN; | < > > > | < | > | | 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | set hash [sqlite3_fts5_token_hash 1024 xyz] set vocab [build_vocab1 -prefix xyz -hash $hash] lappend vocab xyz do_execsql_test 1.1 { CREATE VIRTUAL TABLE vocab USING fts5vocab(eee, 'row'); BEGIN; } do_test 1.2 { for {set i 1} {$i <= 100} {incr i} { execsql { INSERT INTO eee VALUES( r($vocab, 5), r($vocab, 7) ) } } } {} do_test 1.2 { db eval { SELECT term, doc FROM vocab } { set nRow [db one {SELECT count(*) FROM eee WHERE eee MATCH $term}] if {$nRow != $doc} { error "term=$term fts5vocab=$doc cnt=$nRow" } } |
︙ | ︙ |
Changes to ext/fts5/test/fts5prefix.test.
︙ | ︙ | |||
191 192 193 194 195 196 197 198 199 200 201 | } $res } } execsql { INSERT INTO t3(t3) VALUES('optimize') } execsql { INSERT INTO t3(t3) VALUES('integrity-check') } } finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 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 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 | } $res } } execsql { INSERT INTO t3(t3) VALUES('optimize') } execsql { INSERT INTO t3(t3) VALUES('integrity-check') } } #------------------------------------------------------------------------- # reset_db do_execsql_test 4.0 { CREATE VIRTUAL TABLE t2 USING fts5(c1, c2); INSERT INTO t2 VALUES('xa xb', 'xb xa'); INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 2 INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 4 INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 8 INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 16 INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 32 INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 64 INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 128 INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 256 INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 512 INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 1024 INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 2048 INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 4096 SELECT count(*) FROM t2('x*'); } {4096} do_execsql_test 4.1 { UPDATE t2 SET c2 = 'ya yb'; SELECT count(*) FROM t2('c1:x*'); SELECT count(*) FROM t2('c2:x*'); } {4096 0} do_execsql_test 4.2 { UPDATE t2 SET c2 = 'xa'; SELECT count(*) FROM t2('c1:x*'); SELECT count(*) FROM t2('c2:x*'); } {4096 4096} #------------------------------------------------------------------------- # reset_db proc rnddoc {n} { set map [list a b c d] set doc [list] for {set i 0} {$i < $n} {incr i} { lappend doc "x[lindex $map [expr int(rand()*4)]]" } set doc } set cols [list] for {set i 1} {$i<250} {incr i} { lappend cols "c$i" lappend vals "'[rnddoc 10]'" } do_test 5.0 { execsql "CREATE VIRTUAL TABLE t4 USING fts5([join $cols ,])" execsql {INSERT INTO t4(t4, rank) VALUES('pgsz', 32)} execsql "INSERT INTO t4 VALUES([join $vals ,])" execsql "INSERT INTO t4 VALUES([join $vals ,])" execsql "INSERT INTO t4 VALUES([join $vals ,])" execsql "INSERT INTO t4 VALUES([join $vals ,])" } {} proc gmatch {col pattern} { expr {[lsearch -glob $col $pattern]>=0} } db func gmatch gmatch foreach {tn col pattern} { 1 c100 {xa*} 2 c200 {xb*} } { set res [db eval "SELECT rowid FROM t4 WHERE gmatch($col, \$pattern)"] set query "$col : $pattern" do_execsql_test 5.$tn { SELECT rowid FROM t4($query) } $res } reset_db db func fts5_rnddoc fts5_rnddoc do_test 6.0 { execsql { CREATE VIRTUAL TABLE t5 USING fts5(x, y); INSERT INTO t5 VALUES( fts5_rnddoc(10000), fts5_rnddoc(10000) ); INSERT INTO t5 VALUES( fts5_rnddoc(10000), fts5_rnddoc(10000) ); INSERT INTO t5 VALUES( fts5_rnddoc(10000), fts5_rnddoc(10000) ); INSERT INTO t5 VALUES( fts5_rnddoc(10000), fts5_rnddoc(10000) ); } } {} proc gmatch {col pattern} { expr {[lsearch -glob $col $pattern]>=0} } db func gmatch gmatch foreach {tn col pattern} { 1 y {xa*} 2 y {xb*} 3 y {xc*} 4 x {xa*} 5 x {xb*} 6 x {xc*} } { set res [db eval "SELECT rowid FROM t5 WHERE gmatch($col, \$pattern)"] set query "$col : $pattern" do_execsql_test 6.$tn { SELECT rowid FROM t5($query) } $res } finish_test |
Changes to ext/fts5/test/fts5simple.test.
︙ | ︙ | |||
295 296 297 298 299 300 301 302 303 304 | } } {} do_execsql_test 12.2 { SELECT rowid FROM xx('x:a'); COMMIT; } {} finish_test | > > > > > > > > > > > > > > > > > > > > > > | 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 | } } {} do_execsql_test 12.2 { SELECT rowid FROM xx('x:a'); COMMIT; } {} #------------------------------------------------------------------------- # Try an UPDATE OR REPLACE query. # do_execsql_test 13.1 { CREATE VIRTUAL TABLE xy USING fts5(x); INSERT INTO xy(rowid, x) VALUES(1, '1 2 3'); INSERT INTO xy(rowid, x) VALUES(2, '2 3 4'); INSERT INTO xy(rowid, x) VALUES(3, '3 4 5'); } do_execsql_test 13.2 { UPDATE OR REPLACE xy SET rowid=3 WHERE rowid = 2; SELECT rowid, x FROM xy; } { 1 {1 2 3} 3 {2 3 4} } do_execsql_test 13.3 { INSERT INTO xy(xy) VALUES('integrity-check'); } finish_test |