Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Changes to FTS to ensure that it does not access the database from within the xConnect method. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
c67a52c356416cc200f51f9168d942e7 |
User & Date: | dan 2014-03-12 19:20:36 |
Context
2014-03-12
| ||
19:38 | Fix an obscure bug causing sqlite3_close() to fail if there are virtual tables on the disconnect list when it is called. check-in: 6504aa47a8 user: dan tags: trunk | |
19:20 | Changes to FTS to ensure that it does not access the database from within the xConnect method. check-in: c67a52c356 user: dan tags: trunk | |
12:44 | Prevent the rtree module from reading sqlite_stat1 data from the wrong database. check-in: 7ce03c1b55 user: dan tags: trunk | |
Changes
Changes to ext/fts3/fts3.c.
1406 1406 rc = fts3CreateTables(p); 1407 1407 } 1408 1408 1409 1409 /* Check to see if a legacy fts3 table has been "upgraded" by the 1410 1410 ** addition of a %_stat table so that it can use incremental merge. 1411 1411 */ 1412 1412 if( !isFts4 && !isCreate ){ 1413 - int rc2 = SQLITE_OK; 1414 - fts3DbExec(&rc2, db, "SELECT 1 FROM %Q.'%q_stat' WHERE id=2", 1415 - p->zDb, p->zName); 1416 - if( rc2==SQLITE_OK ) p->bHasStat = 1; 1413 + p->bHasStat = 2; 1417 1414 } 1418 1415 1419 1416 /* Figure out the page-size for the database. This is required in order to 1420 1417 ** estimate the cost of loading large doclists from the database. */ 1421 1418 fts3DatabasePageSize(&rc, p); 1422 1419 p->nNodeSize = p->nPgsz-35; 1423 1420 ................................................................................ 3316 3313 if( A>(int)nMinMerge ) rc = sqlite3Fts3Incrmerge(p, A, 8); 3317 3314 } 3318 3315 sqlite3Fts3SegmentsClose(p); 3319 3316 return rc; 3320 3317 } 3321 3318 3322 3319 /* 3323 -** Implementation of xBegin() method. This is a no-op. 3320 +** If it is currently unknown whether or not the FTS table has an %_stat 3321 +** table (if p->bHasStat==2), attempt to determine this (set p->bHasStat 3322 +** to 0 or 1). Return SQLITE_OK if successful, or an SQLite error code 3323 +** if an error occurs. 3324 +*/ 3325 +static int fts3SetHasStat(Fts3Table *p){ 3326 + int rc = SQLITE_OK; 3327 + if( p->bHasStat==2 ){ 3328 + const char *zFmt ="SELECT 1 FROM %Q.sqlite_master WHERE tbl_name='%q_stat'"; 3329 + char *zSql = sqlite3_mprintf(zFmt, p->zDb, p->zName); 3330 + if( zSql ){ 3331 + sqlite3_stmt *pStmt = 0; 3332 + rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); 3333 + if( rc==SQLITE_OK ){ 3334 + int bHasStat = (sqlite3_step(pStmt)==SQLITE_ROW); 3335 + rc = sqlite3_finalize(pStmt); 3336 + if( rc==SQLITE_OK ) p->bHasStat = bHasStat; 3337 + } 3338 + sqlite3_free(zSql); 3339 + }else{ 3340 + rc = SQLITE_NOMEM; 3341 + } 3342 + } 3343 + return rc; 3344 +} 3345 + 3346 +/* 3347 +** Implementation of xBegin() method. 3324 3348 */ 3325 3349 static int fts3BeginMethod(sqlite3_vtab *pVtab){ 3326 3350 Fts3Table *p = (Fts3Table*)pVtab; 3327 3351 UNUSED_PARAMETER(pVtab); 3328 3352 assert( p->pSegments==0 ); 3329 3353 assert( p->nPendingData==0 ); 3330 3354 assert( p->inTransaction!=1 ); 3331 3355 TESTONLY( p->inTransaction = 1 ); 3332 3356 TESTONLY( p->mxSavepoint = -1; ); 3333 3357 p->nLeafAdd = 0; 3334 - return SQLITE_OK; 3358 + return fts3SetHasStat(p); 3335 3359 } 3336 3360 3337 3361 /* 3338 3362 ** Implementation of xCommit() method. This is a no-op. The contents of 3339 3363 ** the pending-terms hash-table have already been flushed into the database 3340 3364 ** by fts3SyncMethod(). 3341 3365 */ ................................................................................ 3576 3600 sqlite3_vtab *pVtab, /* Virtual table handle */ 3577 3601 const char *zName /* New name of table */ 3578 3602 ){ 3579 3603 Fts3Table *p = (Fts3Table *)pVtab; 3580 3604 sqlite3 *db = p->db; /* Database connection */ 3581 3605 int rc; /* Return Code */ 3582 3606 3607 + /* At this point it must be known if the %_stat table exists or not. 3608 + ** So bHasStat may not be 2. */ 3609 + rc = fts3SetHasStat(p); 3610 + 3583 3611 /* As it happens, the pending terms table is always empty here. This is 3584 3612 ** because an "ALTER TABLE RENAME TABLE" statement inside a transaction 3585 3613 ** always opens a savepoint transaction. And the xSavepoint() method 3586 3614 ** flushes the pending terms table. But leave the (no-op) call to 3587 3615 ** PendingTermsFlush() in in case that changes. 3588 3616 */ 3589 3617 assert( p->nPendingData==0 ); 3590 - rc = sqlite3Fts3PendingTermsFlush(p); 3618 + if( rc==SQLITE_OK ){ 3619 + rc = sqlite3Fts3PendingTermsFlush(p); 3620 + } 3591 3621 3592 3622 if( p->zContentTbl==0 ){ 3593 3623 fts3DbExec(&rc, db, 3594 3624 "ALTER TABLE %Q.'%q_content' RENAME TO '%q_content';", 3595 3625 p->zDb, p->zName, zName 3596 3626 ); 3597 3627 }
Changes to ext/fts3/fts3Int.h.
219 219 sqlite3_stmt *aStmt[37]; 220 220 221 221 char *zReadExprlist; 222 222 char *zWriteExprlist; 223 223 224 224 int nNodeSize; /* Soft limit for node size */ 225 225 u8 bFts4; /* True for FTS4, false for FTS3 */ 226 - u8 bHasStat; /* True if %_stat table exists */ 226 + u8 bHasStat; /* True if %_stat table exists (2==unknown) */ 227 227 u8 bHasDocsize; /* True if %_docsize table exists */ 228 228 u8 bDescIdx; /* True if doclists are in reverse order */ 229 229 u8 bIgnoreSavepoint; /* True to ignore xSavepoint invocations */ 230 230 int nPgsz; /* Page size for host database */ 231 231 char *zSegmentsTbl; /* Name of %_segments table */ 232 232 sqlite3_blob *pSegments; /* Blob handle open on %_segments table */ 233 233
Changes to ext/fts3/fts3_write.c.
5266 5266 Fts3Table *p = (Fts3Table *)pVtab; 5267 5267 int rc = SQLITE_OK; /* Return Code */ 5268 5268 int isRemove = 0; /* True for an UPDATE or DELETE */ 5269 5269 u32 *aSzIns = 0; /* Sizes of inserted documents */ 5270 5270 u32 *aSzDel = 0; /* Sizes of deleted documents */ 5271 5271 int nChng = 0; /* Net change in number of documents */ 5272 5272 int bInsertDone = 0; 5273 + 5274 + /* At this point it must be known if the %_stat table exists or not. 5275 + ** So bHasStat may not be 2. */ 5276 + assert( p->bHasStat==0 || p->bHasStat==1 ); 5273 5277 5274 5278 assert( p->pSegments==0 ); 5275 5279 assert( 5276 5280 nArg==1 /* DELETE operations */ 5277 5281 || nArg==(2 + p->nColumn + 3) /* INSERT or UPDATE operations */ 5278 5282 ); 5279 5283
Changes to test/fts3d.test.
350 350 } {fts_content fts_segdir fts_segments} 351 351 do_test fts3d-6.5 { 352 352 db eval { 353 353 ALTER TABLE fts RENAME TO xyz; 354 354 SELECT name FROM sqlite_master WHERE name GLOB '???_*' ORDER BY 1; 355 355 } 356 356 } {xyz_content xyz_segdir xyz_segments} 357 + 358 +# ALTER TABLE RENAME on an FTS3 table following an incr-merge op. 359 +# 360 +do_test fts3d-6.6 { 361 + execsql { INSERT INTO xyz(xyz) VALUES('merge=2,2') } 362 + sqlite3 db test.db 363 + execsql { 364 + ALTER TABLE xyz RENAME TO ott; 365 + SELECT name FROM sqlite_master WHERE name GLOB '???_*' ORDER BY 1; 366 + } 367 +} {ott_content ott_segdir ott_segments ott_stat} 357 368 358 369 359 370 finish_test