Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(149)

Side by Side Diff: third_party/sqlite/src/ext/fts5/fts5_storage.c

Issue 2751253002: [sql] Import SQLite 3.17.0. (Closed)
Patch Set: also clang on Linux i386 Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/sqlite/src/ext/fts5/fts5_main.c ('k') | third_party/sqlite/src/ext/fts5/fts5_tcl.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 ** 2014 May 31 2 ** 2014 May 31
3 ** 3 **
4 ** The author disclaims copyright to this source code. In place of 4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing: 5 ** a legal notice, here is a blessing:
6 ** 6 **
7 ** May you do good and not evil. 7 ** May you do good and not evil.
8 ** May you find forgiveness for yourself and forgive others. 8 ** May you find forgiveness for yourself and forgive others.
9 ** May you share freely, never taking more than you give. 9 ** May you share freely, never taking more than you give.
10 ** 10 **
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 }else{ 138 }else{
139 rc = sqlite3_prepare_v2(pC->db, zSql, -1, &p->aStmt[eStmt], 0); 139 rc = sqlite3_prepare_v2(pC->db, zSql, -1, &p->aStmt[eStmt], 0);
140 sqlite3_free(zSql); 140 sqlite3_free(zSql);
141 if( rc!=SQLITE_OK && pzErrMsg ){ 141 if( rc!=SQLITE_OK && pzErrMsg ){
142 *pzErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pC->db)); 142 *pzErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pC->db));
143 } 143 }
144 } 144 }
145 } 145 }
146 146
147 *ppStmt = p->aStmt[eStmt]; 147 *ppStmt = p->aStmt[eStmt];
148 sqlite3_reset(*ppStmt);
148 return rc; 149 return rc;
149 } 150 }
150 151
151 152
152 static int fts5ExecPrintf( 153 static int fts5ExecPrintf(
153 sqlite3 *db, 154 sqlite3 *db,
154 char **pzErr, 155 char **pzErr,
155 const char *zFormat, 156 const char *zFormat,
156 ... 157 ...
157 ){ 158 ){
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 Fts5Config *pConfig, /* FTS5 configuration */ 240 Fts5Config *pConfig, /* FTS5 configuration */
240 const char *zPost, /* Shadow table to create (e.g. "content") */ 241 const char *zPost, /* Shadow table to create (e.g. "content") */
241 const char *zDefn, /* Columns etc. for shadow table */ 242 const char *zDefn, /* Columns etc. for shadow table */
242 int bWithout, /* True for without rowid */ 243 int bWithout, /* True for without rowid */
243 char **pzErr /* OUT: Error message */ 244 char **pzErr /* OUT: Error message */
244 ){ 245 ){
245 int rc; 246 int rc;
246 char *zErr = 0; 247 char *zErr = 0;
247 248
248 rc = fts5ExecPrintf(pConfig->db, &zErr, "CREATE TABLE %Q.'%q_%q'(%s)%s", 249 rc = fts5ExecPrintf(pConfig->db, &zErr, "CREATE TABLE %Q.'%q_%q'(%s)%s",
249 pConfig->zDb, pConfig->zName, zPost, zDefn, bWithout?" WITHOUT ROWID":"" 250 pConfig->zDb, pConfig->zName, zPost, zDefn,
251 #ifndef SQLITE_FTS5_NO_WITHOUT_ROWID
252 bWithout?" WITHOUT ROWID":
253 #endif
254 ""
250 ); 255 );
251 if( zErr ){ 256 if( zErr ){
252 *pzErr = sqlite3_mprintf( 257 *pzErr = sqlite3_mprintf(
253 "fts5: error creating shadow table %q_%s: %s", 258 "fts5: error creating shadow table %q_%s: %s",
254 pConfig->zName, zPost, zErr 259 pConfig->zName, zPost, zErr
255 ); 260 );
256 sqlite3_free(zErr); 261 sqlite3_free(zErr);
257 } 262 }
258 263
259 return rc; 264 return rc;
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 336
332 /* 337 /*
333 ** Close a handle opened by an earlier call to sqlite3Fts5StorageOpen(). 338 ** Close a handle opened by an earlier call to sqlite3Fts5StorageOpen().
334 */ 339 */
335 int sqlite3Fts5StorageClose(Fts5Storage *p){ 340 int sqlite3Fts5StorageClose(Fts5Storage *p){
336 int rc = SQLITE_OK; 341 int rc = SQLITE_OK;
337 if( p ){ 342 if( p ){
338 int i; 343 int i;
339 344
340 /* Finalize all SQL statements */ 345 /* Finalize all SQL statements */
341 for(i=0; i<(int)ArraySize(p->aStmt); i++){ 346 for(i=0; i<ArraySize(p->aStmt); i++){
342 sqlite3_finalize(p->aStmt[i]); 347 sqlite3_finalize(p->aStmt[i]);
343 } 348 }
344 349
345 sqlite3_free(p); 350 sqlite3_free(p);
346 } 351 }
347 return rc; 352 return rc;
348 } 353 }
349 354
350 typedef struct Fts5InsertCtx Fts5InsertCtx; 355 typedef struct Fts5InsertCtx Fts5InsertCtx;
351 struct Fts5InsertCtx { 356 struct Fts5InsertCtx {
352 Fts5Storage *pStorage; 357 Fts5Storage *pStorage;
353 int iCol; 358 int iCol;
354 int szCol; /* Size of column value in tokens */ 359 int szCol; /* Size of column value in tokens */
355 }; 360 };
356 361
357 /* 362 /*
358 ** Tokenization callback used when inserting tokens into the FTS index. 363 ** Tokenization callback used when inserting tokens into the FTS index.
359 */ 364 */
360 static int fts5StorageInsertCallback( 365 static int fts5StorageInsertCallback(
361 void *pContext, /* Pointer to Fts5InsertCtx object */ 366 void *pContext, /* Pointer to Fts5InsertCtx object */
362 int tflags, 367 int tflags,
363 const char *pToken, /* Buffer containing token */ 368 const char *pToken, /* Buffer containing token */
364 int nToken, /* Size of token in bytes */ 369 int nToken, /* Size of token in bytes */
365 int iStart, /* Start offset of token */ 370 int iUnused1, /* Start offset of token */
366 int iEnd /* End offset of token */ 371 int iUnused2 /* End offset of token */
367 ){ 372 ){
368 Fts5InsertCtx *pCtx = (Fts5InsertCtx*)pContext; 373 Fts5InsertCtx *pCtx = (Fts5InsertCtx*)pContext;
369 Fts5Index *pIdx = pCtx->pStorage->pIndex; 374 Fts5Index *pIdx = pCtx->pStorage->pIndex;
375 UNUSED_PARAM2(iUnused1, iUnused2);
376 if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE;
370 if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){ 377 if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){
371 pCtx->szCol++; 378 pCtx->szCol++;
372 } 379 }
373 return sqlite3Fts5IndexWrite(pIdx, pCtx->iCol, pCtx->szCol-1, pToken, nToken); 380 return sqlite3Fts5IndexWrite(pIdx, pCtx->iCol, pCtx->szCol-1, pToken, nToken);
374 } 381 }
375 382
376 /* 383 /*
377 ** If a row with rowid iDel is present in the %_content table, add the 384 ** If a row with rowid iDel is present in the %_content table, add the
378 ** delete-markers to the FTS index necessary to delete it. Do not actually 385 ** delete-markers to the FTS index necessary to delete it. Do not actually
379 ** remove the %_content row at this time though. 386 ** remove the %_content row at this time though.
380 */ 387 */
381 static int fts5StorageDeleteFromIndex(Fts5Storage *p, i64 iDel){ 388 static int fts5StorageDeleteFromIndex(
389 Fts5Storage *p,
390 i64 iDel,
391 sqlite3_value **apVal
392 ){
382 Fts5Config *pConfig = p->pConfig; 393 Fts5Config *pConfig = p->pConfig;
383 sqlite3_stmt *pSeek; /* SELECT to read row iDel from %_data */ 394 sqlite3_stmt *pSeek = 0; /* SELECT to read row iDel from %_data */
384 int rc; /* Return code */ 395 int rc; /* Return code */
396 int rc2; /* sqlite3_reset() return code */
397 int iCol;
398 Fts5InsertCtx ctx;
385 399
386 rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP, &pSeek, 0); 400 if( apVal==0 ){
387 if( rc==SQLITE_OK ){ 401 rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP, &pSeek, 0);
388 int rc2; 402 if( rc!=SQLITE_OK ) return rc;
389 sqlite3_bind_int64(pSeek, 1, iDel); 403 sqlite3_bind_int64(pSeek, 1, iDel);
390 if( sqlite3_step(pSeek)==SQLITE_ROW ){ 404 if( sqlite3_step(pSeek)!=SQLITE_ROW ){
391 int iCol; 405 return sqlite3_reset(pSeek);
392 Fts5InsertCtx ctx;
393 ctx.pStorage = p;
394 ctx.iCol = -1;
395 rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 1, iDel);
396 for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){
397 if( pConfig->abUnindexed[iCol-1] ) continue;
398 ctx.szCol = 0;
399 rc = sqlite3Fts5Tokenize(pConfig,
400 FTS5_TOKENIZE_DOCUMENT,
401 (const char*)sqlite3_column_text(pSeek, iCol),
402 sqlite3_column_bytes(pSeek, iCol),
403 (void*)&ctx,
404 fts5StorageInsertCallback
405 );
406 p->aTotalSize[iCol-1] -= (i64)ctx.szCol;
407 }
408 p->nTotalRow--;
409 } 406 }
410 rc2 = sqlite3_reset(pSeek);
411 if( rc==SQLITE_OK ) rc = rc2;
412 } 407 }
413 408
409 ctx.pStorage = p;
410 ctx.iCol = -1;
411 rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 1, iDel);
412 for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){
413 if( pConfig->abUnindexed[iCol-1]==0 ){
414 const char *zText;
415 int nText;
416 if( pSeek ){
417 zText = (const char*)sqlite3_column_text(pSeek, iCol);
418 nText = sqlite3_column_bytes(pSeek, iCol);
419 }else{
420 zText = (const char*)sqlite3_value_text(apVal[iCol-1]);
421 nText = sqlite3_value_bytes(apVal[iCol-1]);
422 }
423 ctx.szCol = 0;
424 rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT,
425 zText, nText, (void*)&ctx, fts5StorageInsertCallback
426 );
427 p->aTotalSize[iCol-1] -= (i64)ctx.szCol;
428 }
429 }
430 p->nTotalRow--;
431
432 rc2 = sqlite3_reset(pSeek);
433 if( rc==SQLITE_OK ) rc = rc2;
414 return rc; 434 return rc;
415 } 435 }
416 436
417 437
418 /* 438 /*
419 ** Insert a record into the %_docsize table. Specifically, do: 439 ** Insert a record into the %_docsize table. Specifically, do:
420 ** 440 **
421 ** INSERT OR REPLACE INTO %_docsize(id, sz) VALUES(iRowid, pBuf); 441 ** INSERT OR REPLACE INTO %_docsize(id, sz) VALUES(iRowid, pBuf);
422 ** 442 **
423 ** If there is no %_docsize table (as happens if the columnsize=0 option 443 ** If there is no %_docsize table (as happens if the columnsize=0 option
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 rc = sqlite3Fts5IndexSetAverages(p->pIndex, buf.p, buf.n); 503 rc = sqlite3Fts5IndexSetAverages(p->pIndex, buf.p, buf.n);
484 } 504 }
485 sqlite3_free(buf.p); 505 sqlite3_free(buf.p);
486 506
487 return rc; 507 return rc;
488 } 508 }
489 509
490 /* 510 /*
491 ** Remove a row from the FTS table. 511 ** Remove a row from the FTS table.
492 */ 512 */
493 int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel){ 513 int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, sqlite3_value **apVal){
494 Fts5Config *pConfig = p->pConfig; 514 Fts5Config *pConfig = p->pConfig;
495 int rc; 515 int rc;
496 sqlite3_stmt *pDel = 0; 516 sqlite3_stmt *pDel = 0;
497 517
518 assert( pConfig->eContent!=FTS5_CONTENT_NORMAL || apVal==0 );
498 rc = fts5StorageLoadTotals(p, 1); 519 rc = fts5StorageLoadTotals(p, 1);
499 520
500 /* Delete the index records */ 521 /* Delete the index records */
501 if( rc==SQLITE_OK ){ 522 if( rc==SQLITE_OK ){
502 rc = fts5StorageDeleteFromIndex(p, iDel); 523 rc = fts5StorageDeleteFromIndex(p, iDel, apVal);
503 } 524 }
504 525
505 /* Delete the %_docsize record */ 526 /* Delete the %_docsize record */
506 if( rc==SQLITE_OK && pConfig->bColumnsize ){ 527 if( rc==SQLITE_OK && pConfig->bColumnsize ){
507 rc = fts5StorageGetStmt(p, FTS5_STMT_DELETE_DOCSIZE, &pDel, 0); 528 rc = fts5StorageGetStmt(p, FTS5_STMT_DELETE_DOCSIZE, &pDel, 0);
508 if( rc==SQLITE_OK ){ 529 if( rc==SQLITE_OK ){
509 sqlite3_bind_int64(pDel, 1, iDel); 530 sqlite3_bind_int64(pDel, 1, iDel);
510 sqlite3_step(pDel); 531 sqlite3_step(pDel);
511 rc = sqlite3_reset(pDel); 532 rc = sqlite3_reset(pDel);
512 } 533 }
(...skipping 12 matching lines...) Expand all
525 } 546 }
526 547
527 /* Write the averages record */ 548 /* Write the averages record */
528 if( rc==SQLITE_OK ){ 549 if( rc==SQLITE_OK ){
529 rc = fts5StorageSaveTotals(p); 550 rc = fts5StorageSaveTotals(p);
530 } 551 }
531 552
532 return rc; 553 return rc;
533 } 554 }
534 555
535 int sqlite3Fts5StorageSpecialDelete(
536 Fts5Storage *p,
537 i64 iDel,
538 sqlite3_value **apVal
539 ){
540 Fts5Config *pConfig = p->pConfig;
541 int rc;
542 sqlite3_stmt *pDel = 0;
543
544 assert( pConfig->eContent!=FTS5_CONTENT_NORMAL );
545 rc = fts5StorageLoadTotals(p, 1);
546
547 /* Delete the index records */
548 if( rc==SQLITE_OK ){
549 int iCol;
550 Fts5InsertCtx ctx;
551 ctx.pStorage = p;
552 ctx.iCol = -1;
553
554 rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 1, iDel);
555 for(iCol=0; rc==SQLITE_OK && iCol<pConfig->nCol; iCol++){
556 if( pConfig->abUnindexed[iCol] ) continue;
557 ctx.szCol = 0;
558 rc = sqlite3Fts5Tokenize(pConfig,
559 FTS5_TOKENIZE_DOCUMENT,
560 (const char*)sqlite3_value_text(apVal[iCol]),
561 sqlite3_value_bytes(apVal[iCol]),
562 (void*)&ctx,
563 fts5StorageInsertCallback
564 );
565 p->aTotalSize[iCol] -= (i64)ctx.szCol;
566 }
567 p->nTotalRow--;
568 }
569
570 /* Delete the %_docsize record */
571 if( pConfig->bColumnsize ){
572 if( rc==SQLITE_OK ){
573 rc = fts5StorageGetStmt(p, FTS5_STMT_DELETE_DOCSIZE, &pDel, 0);
574 }
575 if( rc==SQLITE_OK ){
576 sqlite3_bind_int64(pDel, 1, iDel);
577 sqlite3_step(pDel);
578 rc = sqlite3_reset(pDel);
579 }
580 }
581
582 /* Write the averages record */
583 if( rc==SQLITE_OK ){
584 rc = fts5StorageSaveTotals(p);
585 }
586
587 return rc;
588 }
589
590 /* 556 /*
591 ** Delete all entries in the FTS5 index. 557 ** Delete all entries in the FTS5 index.
592 */ 558 */
593 int sqlite3Fts5StorageDeleteAll(Fts5Storage *p){ 559 int sqlite3Fts5StorageDeleteAll(Fts5Storage *p){
594 Fts5Config *pConfig = p->pConfig; 560 Fts5Config *pConfig = p->pConfig;
595 int rc; 561 int rc;
596 562
597 /* Delete the contents of the %_data and %_docsize tables. */ 563 /* Delete the contents of the %_data and %_docsize tables. */
598 rc = fts5ExecPrintf(pConfig->db, 0, 564 rc = fts5ExecPrintf(pConfig->db, 0,
599 "DELETE FROM %Q.'%q_data';" 565 "DELETE FROM %Q.'%q_data';"
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 } 638 }
673 639
674 int sqlite3Fts5StorageOptimize(Fts5Storage *p){ 640 int sqlite3Fts5StorageOptimize(Fts5Storage *p){
675 return sqlite3Fts5IndexOptimize(p->pIndex); 641 return sqlite3Fts5IndexOptimize(p->pIndex);
676 } 642 }
677 643
678 int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge){ 644 int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge){
679 return sqlite3Fts5IndexMerge(p->pIndex, nMerge); 645 return sqlite3Fts5IndexMerge(p->pIndex, nMerge);
680 } 646 }
681 647
648 int sqlite3Fts5StorageReset(Fts5Storage *p){
649 return sqlite3Fts5IndexReset(p->pIndex);
650 }
651
682 /* 652 /*
683 ** Allocate a new rowid. This is used for "external content" tables when 653 ** Allocate a new rowid. This is used for "external content" tables when
684 ** a NULL value is inserted into the rowid column. The new rowid is allocated 654 ** a NULL value is inserted into the rowid column. The new rowid is allocated
685 ** by inserting a dummy row into the %_docsize table. The dummy will be 655 ** by inserting a dummy row into the %_docsize table. The dummy will be
686 ** overwritten later. 656 ** overwritten later.
687 ** 657 **
688 ** If the %_docsize table does not exist, SQLITE_MISMATCH is returned. In 658 ** If the %_docsize table does not exist, SQLITE_MISMATCH is returned. In
689 ** this case the user is required to provide a rowid explicitly. 659 ** this case the user is required to provide a rowid explicitly.
690 */ 660 */
691 static int fts5StorageNewRowid(Fts5Storage *p, i64 *piRowid){ 661 static int fts5StorageNewRowid(Fts5Storage *p, i64 *piRowid){
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
818 788
819 /* 789 /*
820 ** Context object used by sqlite3Fts5StorageIntegrity(). 790 ** Context object used by sqlite3Fts5StorageIntegrity().
821 */ 791 */
822 typedef struct Fts5IntegrityCtx Fts5IntegrityCtx; 792 typedef struct Fts5IntegrityCtx Fts5IntegrityCtx;
823 struct Fts5IntegrityCtx { 793 struct Fts5IntegrityCtx {
824 i64 iRowid; 794 i64 iRowid;
825 int iCol; 795 int iCol;
826 int szCol; 796 int szCol;
827 u64 cksum; 797 u64 cksum;
798 Fts5Termset *pTermset;
828 Fts5Config *pConfig; 799 Fts5Config *pConfig;
829 }; 800 };
830 801
802
831 /* 803 /*
832 ** Tokenization callback used by integrity check. 804 ** Tokenization callback used by integrity check.
833 */ 805 */
834 static int fts5StorageIntegrityCallback( 806 static int fts5StorageIntegrityCallback(
835 void *pContext, /* Pointer to Fts5InsertCtx object */ 807 void *pContext, /* Pointer to Fts5IntegrityCtx object */
836 int tflags, 808 int tflags,
837 const char *pToken, /* Buffer containing token */ 809 const char *pToken, /* Buffer containing token */
838 int nToken, /* Size of token in bytes */ 810 int nToken, /* Size of token in bytes */
839 int iStart, /* Start offset of token */ 811 int iUnused1, /* Start offset of token */
840 int iEnd /* End offset of token */ 812 int iUnused2 /* End offset of token */
841 ){ 813 ){
842 Fts5IntegrityCtx *pCtx = (Fts5IntegrityCtx*)pContext; 814 Fts5IntegrityCtx *pCtx = (Fts5IntegrityCtx*)pContext;
815 Fts5Termset *pTermset = pCtx->pTermset;
816 int bPresent;
817 int ii;
818 int rc = SQLITE_OK;
819 int iPos;
820 int iCol;
821
822 UNUSED_PARAM2(iUnused1, iUnused2);
823 if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE;
824
843 if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){ 825 if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){
844 pCtx->szCol++; 826 pCtx->szCol++;
845 } 827 }
846 pCtx->cksum ^= sqlite3Fts5IndexCksum( 828
847 pCtx->pConfig, pCtx->iRowid, pCtx->iCol, pCtx->szCol-1, pToken, nToken 829 switch( pCtx->pConfig->eDetail ){
848 ); 830 case FTS5_DETAIL_FULL:
849 return SQLITE_OK; 831 iPos = pCtx->szCol-1;
832 iCol = pCtx->iCol;
833 break;
834
835 case FTS5_DETAIL_COLUMNS:
836 iPos = pCtx->iCol;
837 iCol = 0;
838 break;
839
840 default:
841 assert( pCtx->pConfig->eDetail==FTS5_DETAIL_NONE );
842 iPos = 0;
843 iCol = 0;
844 break;
845 }
846
847 rc = sqlite3Fts5TermsetAdd(pTermset, 0, pToken, nToken, &bPresent);
848 if( rc==SQLITE_OK && bPresent==0 ){
849 pCtx->cksum ^= sqlite3Fts5IndexEntryCksum(
850 pCtx->iRowid, iCol, iPos, 0, pToken, nToken
851 );
852 }
853
854 for(ii=0; rc==SQLITE_OK && ii<pCtx->pConfig->nPrefix; ii++){
855 const int nChar = pCtx->pConfig->aPrefix[ii];
856 int nByte = sqlite3Fts5IndexCharlenToBytelen(pToken, nToken, nChar);
857 if( nByte ){
858 rc = sqlite3Fts5TermsetAdd(pTermset, ii+1, pToken, nByte, &bPresent);
859 if( bPresent==0 ){
860 pCtx->cksum ^= sqlite3Fts5IndexEntryCksum(
861 pCtx->iRowid, iCol, iPos, ii+1, pToken, nByte
862 );
863 }
864 }
865 }
866
867 return rc;
850 } 868 }
851 869
852 /* 870 /*
853 ** Check that the contents of the FTS index match that of the %_content 871 ** Check that the contents of the FTS index match that of the %_content
854 ** table. Return SQLITE_OK if they do, or SQLITE_CORRUPT if not. Return 872 ** table. Return SQLITE_OK if they do, or SQLITE_CORRUPT if not. Return
855 ** some other SQLite error code if an error occurs while attempting to 873 ** some other SQLite error code if an error occurs while attempting to
856 ** determine this. 874 ** determine this.
857 */ 875 */
858 int sqlite3Fts5StorageIntegrity(Fts5Storage *p){ 876 int sqlite3Fts5StorageIntegrity(Fts5Storage *p){
859 Fts5Config *pConfig = p->pConfig; 877 Fts5Config *pConfig = p->pConfig;
(...skipping 15 matching lines...) Expand all
875 rc = fts5StorageGetStmt(p, FTS5_STMT_SCAN, &pScan, 0); 893 rc = fts5StorageGetStmt(p, FTS5_STMT_SCAN, &pScan, 0);
876 if( rc==SQLITE_OK ){ 894 if( rc==SQLITE_OK ){
877 int rc2; 895 int rc2;
878 while( SQLITE_ROW==sqlite3_step(pScan) ){ 896 while( SQLITE_ROW==sqlite3_step(pScan) ){
879 int i; 897 int i;
880 ctx.iRowid = sqlite3_column_int64(pScan, 0); 898 ctx.iRowid = sqlite3_column_int64(pScan, 0);
881 ctx.szCol = 0; 899 ctx.szCol = 0;
882 if( pConfig->bColumnsize ){ 900 if( pConfig->bColumnsize ){
883 rc = sqlite3Fts5StorageDocsize(p, ctx.iRowid, aColSize); 901 rc = sqlite3Fts5StorageDocsize(p, ctx.iRowid, aColSize);
884 } 902 }
903 if( rc==SQLITE_OK && pConfig->eDetail==FTS5_DETAIL_NONE ){
904 rc = sqlite3Fts5TermsetNew(&ctx.pTermset);
905 }
885 for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){ 906 for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
886 if( pConfig->abUnindexed[i] ) continue; 907 if( pConfig->abUnindexed[i] ) continue;
887 ctx.iCol = i; 908 ctx.iCol = i;
888 ctx.szCol = 0; 909 ctx.szCol = 0;
889 rc = sqlite3Fts5Tokenize(pConfig, 910 if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
890 FTS5_TOKENIZE_DOCUMENT, 911 rc = sqlite3Fts5TermsetNew(&ctx.pTermset);
891 (const char*)sqlite3_column_text(pScan, i+1), 912 }
892 sqlite3_column_bytes(pScan, i+1), 913 if( rc==SQLITE_OK ){
893 (void*)&ctx, 914 rc = sqlite3Fts5Tokenize(pConfig,
894 fts5StorageIntegrityCallback 915 FTS5_TOKENIZE_DOCUMENT,
895 ); 916 (const char*)sqlite3_column_text(pScan, i+1),
896 if( pConfig->bColumnsize && ctx.szCol!=aColSize[i] ){ 917 sqlite3_column_bytes(pScan, i+1),
918 (void*)&ctx,
919 fts5StorageIntegrityCallback
920 );
921 }
922 if( rc==SQLITE_OK && pConfig->bColumnsize && ctx.szCol!=aColSize[i] ){
897 rc = FTS5_CORRUPT; 923 rc = FTS5_CORRUPT;
898 } 924 }
899 aTotalSize[i] += ctx.szCol; 925 aTotalSize[i] += ctx.szCol;
926 if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
927 sqlite3Fts5TermsetFree(ctx.pTermset);
928 ctx.pTermset = 0;
929 }
900 } 930 }
931 sqlite3Fts5TermsetFree(ctx.pTermset);
932 ctx.pTermset = 0;
933
901 if( rc!=SQLITE_OK ) break; 934 if( rc!=SQLITE_OK ) break;
902 } 935 }
903 rc2 = sqlite3_reset(pScan); 936 rc2 = sqlite3_reset(pScan);
904 if( rc==SQLITE_OK ) rc = rc2; 937 if( rc==SQLITE_OK ) rc = rc2;
905 } 938 }
906 939
907 /* Test that the "totals" (sometimes called "averages") record looks Ok */ 940 /* Test that the "totals" (sometimes called "averages") record looks Ok */
908 if( rc==SQLITE_OK ){ 941 if( rc==SQLITE_OK ){
909 int i; 942 int i;
910 rc = fts5StorageLoadTotals(p, 0); 943 rc = fts5StorageLoadTotals(p, 0);
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
1092 } 1125 }
1093 if( rc==SQLITE_OK && pVal ){ 1126 if( rc==SQLITE_OK && pVal ){
1094 int iNew = p->pConfig->iCookie + 1; 1127 int iNew = p->pConfig->iCookie + 1;
1095 rc = sqlite3Fts5IndexSetCookie(p->pIndex, iNew); 1128 rc = sqlite3Fts5IndexSetCookie(p->pIndex, iNew);
1096 if( rc==SQLITE_OK ){ 1129 if( rc==SQLITE_OK ){
1097 p->pConfig->iCookie = iNew; 1130 p->pConfig->iCookie = iNew;
1098 } 1131 }
1099 } 1132 }
1100 return rc; 1133 return rc;
1101 } 1134 }
1102
1103
OLDNEW
« no previous file with comments | « third_party/sqlite/src/ext/fts5/fts5_main.c ('k') | third_party/sqlite/src/ext/fts5/fts5_tcl.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698