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

Side by Side Diff: third_party/sqlite/src/ext/fts3/fts3_write.c

Issue 1610963002: Import SQLite 3.10.2. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 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
OLDNEW
1 /* 1 /*
2 ** 2009 Oct 23 2 ** 2009 Oct 23
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 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 /* 18 */ "INSERT INTO %Q.'%q_content' VALUES(%s)", 319 /* 18 */ "INSERT INTO %Q.'%q_content' VALUES(%s)",
320 /* 19 */ "DELETE FROM %Q.'%q_docsize' WHERE docid = ?", 320 /* 19 */ "DELETE FROM %Q.'%q_docsize' WHERE docid = ?",
321 /* 20 */ "REPLACE INTO %Q.'%q_docsize' VALUES(?,?)", 321 /* 20 */ "REPLACE INTO %Q.'%q_docsize' VALUES(?,?)",
322 /* 21 */ "SELECT size FROM %Q.'%q_docsize' WHERE docid=?", 322 /* 21 */ "SELECT size FROM %Q.'%q_docsize' WHERE docid=?",
323 /* 22 */ "SELECT value FROM %Q.'%q_stat' WHERE id=?", 323 /* 22 */ "SELECT value FROM %Q.'%q_stat' WHERE id=?",
324 /* 23 */ "REPLACE INTO %Q.'%q_stat' VALUES(?,?)", 324 /* 23 */ "REPLACE INTO %Q.'%q_stat' VALUES(?,?)",
325 /* 24 */ "", 325 /* 24 */ "",
326 /* 25 */ "", 326 /* 25 */ "",
327 327
328 /* 26 */ "DELETE FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?", 328 /* 26 */ "DELETE FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?",
329 /* 27 */ "SELECT DISTINCT level / (1024 * ?) FROM %Q.'%q_segdir'", 329 /* 27 */ "SELECT ? UNION SELECT level / (1024 * ?) FROM %Q.'%q_segdir'",
330 330
331 /* This statement is used to determine which level to read the input from 331 /* This statement is used to determine which level to read the input from
332 ** when performing an incremental merge. It returns the absolute level number 332 ** when performing an incremental merge. It returns the absolute level number
333 ** of the oldest level in the db that contains at least ? segments. Or, 333 ** of the oldest level in the db that contains at least ? segments. Or,
334 ** if no level in the FTS index contains more than ? segments, the statement 334 ** if no level in the FTS index contains more than ? segments, the statement
335 ** returns zero rows. */ 335 ** returns zero rows. */
336 /* 28 */ "SELECT level FROM %Q.'%q_segdir' GROUP BY level HAVING count(*)>=?" 336 /* 28 */ "SELECT level FROM %Q.'%q_segdir' GROUP BY level HAVING count(*)>=?"
337 " ORDER BY (level %% 1024) ASC LIMIT 1", 337 " ORDER BY (level %% 1024) ASC LIMIT 1",
338 338
339 /* Estimate the upper limit on the number of leaf nodes in a new segment 339 /* Estimate the upper limit on the number of leaf nodes in a new segment
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 return (rc==SQLITE_DONE ? SQLITE_OK : rc); 853 return (rc==SQLITE_DONE ? SQLITE_OK : rc);
854 } 854 }
855 855
856 /* 856 /*
857 ** Calling this function indicates that subsequent calls to 857 ** Calling this function indicates that subsequent calls to
858 ** fts3PendingTermsAdd() are to add term/position-list pairs for the 858 ** fts3PendingTermsAdd() are to add term/position-list pairs for the
859 ** contents of the document with docid iDocid. 859 ** contents of the document with docid iDocid.
860 */ 860 */
861 static int fts3PendingTermsDocid( 861 static int fts3PendingTermsDocid(
862 Fts3Table *p, /* Full-text table handle */ 862 Fts3Table *p, /* Full-text table handle */
863 int bDelete, /* True if this op is a delete */
863 int iLangid, /* Language id of row being written */ 864 int iLangid, /* Language id of row being written */
864 sqlite_int64 iDocid /* Docid of row being written */ 865 sqlite_int64 iDocid /* Docid of row being written */
865 ){ 866 ){
866 assert( iLangid>=0 ); 867 assert( iLangid>=0 );
868 assert( bDelete==1 || bDelete==0 );
867 869
868 /* TODO(shess) Explore whether partially flushing the buffer on 870 /* TODO(shess) Explore whether partially flushing the buffer on
869 ** forced-flush would provide better performance. I suspect that if 871 ** forced-flush would provide better performance. I suspect that if
870 ** we ordered the doclists by size and flushed the largest until the 872 ** we ordered the doclists by size and flushed the largest until the
871 ** buffer was half empty, that would let the less frequent terms 873 ** buffer was half empty, that would let the less frequent terms
872 ** generate longer doclists. 874 ** generate longer doclists.
873 */ 875 */
874 if( iDocid<=p->iPrevDocid 876 if( iDocid<p->iPrevDocid
877 || (iDocid==p->iPrevDocid && p->bPrevDelete==0)
875 || p->iPrevLangid!=iLangid 878 || p->iPrevLangid!=iLangid
876 || p->nPendingData>p->nMaxPendingData 879 || p->nPendingData>p->nMaxPendingData
877 ){ 880 ){
878 int rc = sqlite3Fts3PendingTermsFlush(p); 881 int rc = sqlite3Fts3PendingTermsFlush(p);
879 if( rc!=SQLITE_OK ) return rc; 882 if( rc!=SQLITE_OK ) return rc;
880 } 883 }
881 p->iPrevDocid = iDocid; 884 p->iPrevDocid = iDocid;
882 p->iPrevLangid = iLangid; 885 p->iPrevLangid = iLangid;
886 p->bPrevDelete = bDelete;
883 return SQLITE_OK; 887 return SQLITE_OK;
884 } 888 }
885 889
886 /* 890 /*
887 ** Discard the contents of the pending-terms hash tables. 891 ** Discard the contents of the pending-terms hash tables.
888 */ 892 */
889 void sqlite3Fts3PendingTermsClear(Fts3Table *p){ 893 void sqlite3Fts3PendingTermsClear(Fts3Table *p){
890 int i; 894 int i;
891 for(i=0; i<p->nIndex; i++){ 895 for(i=0; i<p->nIndex; i++){
892 Fts3HashElem *pElem; 896 Fts3HashElem *pElem;
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
1062 int rc; 1066 int rc;
1063 sqlite3_stmt *pSelect; 1067 sqlite3_stmt *pSelect;
1064 1068
1065 assert( *pbFound==0 ); 1069 assert( *pbFound==0 );
1066 if( *pRC ) return; 1070 if( *pRC ) return;
1067 rc = fts3SqlStmt(p, SQL_SELECT_CONTENT_BY_ROWID, &pSelect, &pRowid); 1071 rc = fts3SqlStmt(p, SQL_SELECT_CONTENT_BY_ROWID, &pSelect, &pRowid);
1068 if( rc==SQLITE_OK ){ 1072 if( rc==SQLITE_OK ){
1069 if( SQLITE_ROW==sqlite3_step(pSelect) ){ 1073 if( SQLITE_ROW==sqlite3_step(pSelect) ){
1070 int i; 1074 int i;
1071 int iLangid = langidFromSelect(p, pSelect); 1075 int iLangid = langidFromSelect(p, pSelect);
1072 rc = fts3PendingTermsDocid(p, iLangid, sqlite3_column_int64(pSelect, 0)); 1076 i64 iDocid = sqlite3_column_int64(pSelect, 0);
1077 rc = fts3PendingTermsDocid(p, 1, iLangid, iDocid);
1073 for(i=1; rc==SQLITE_OK && i<=p->nColumn; i++){ 1078 for(i=1; rc==SQLITE_OK && i<=p->nColumn; i++){
1074 int iCol = i-1; 1079 int iCol = i-1;
1075 if( p->abNotindexed[iCol]==0 ){ 1080 if( p->abNotindexed[iCol]==0 ){
1076 const char *zText = (const char *)sqlite3_column_text(pSelect, i); 1081 const char *zText = (const char *)sqlite3_column_text(pSelect, i);
1077 rc = fts3PendingTermsAdd(p, iLangid, zText, -1, &aSz[iCol]); 1082 rc = fts3PendingTermsAdd(p, iLangid, zText, -1, &aSz[iCol]);
1078 aSz[p->nColumn] += sqlite3_column_bytes(pSelect, i); 1083 aSz[p->nColumn] += sqlite3_column_bytes(pSelect, i);
1079 } 1084 }
1080 } 1085 }
1081 if( rc!=SQLITE_OK ){ 1086 if( rc!=SQLITE_OK ){
1082 sqlite3_reset(pSelect); 1087 sqlite3_reset(pSelect);
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
1310 if( !pReader->aDoclist ){ 1315 if( !pReader->aDoclist ){
1311 pNext = pReader->aNode; 1316 pNext = pReader->aNode;
1312 }else{ 1317 }else{
1313 pNext = &pReader->aDoclist[pReader->nDoclist]; 1318 pNext = &pReader->aDoclist[pReader->nDoclist];
1314 } 1319 }
1315 1320
1316 if( !pNext || pNext>=&pReader->aNode[pReader->nNode] ){ 1321 if( !pNext || pNext>=&pReader->aNode[pReader->nNode] ){
1317 1322
1318 if( fts3SegReaderIsPending(pReader) ){ 1323 if( fts3SegReaderIsPending(pReader) ){
1319 Fts3HashElem *pElem = *(pReader->ppNextElem); 1324 Fts3HashElem *pElem = *(pReader->ppNextElem);
1320 if( pElem==0 ){ 1325 sqlite3_free(pReader->aNode);
1321 pReader->aNode = 0; 1326 pReader->aNode = 0;
1322 }else{ 1327 if( pElem ){
1328 char *aCopy;
1323 PendingList *pList = (PendingList *)fts3HashData(pElem); 1329 PendingList *pList = (PendingList *)fts3HashData(pElem);
1330 int nCopy = pList->nData+1;
1324 pReader->zTerm = (char *)fts3HashKey(pElem); 1331 pReader->zTerm = (char *)fts3HashKey(pElem);
1325 pReader->nTerm = fts3HashKeysize(pElem); 1332 pReader->nTerm = fts3HashKeysize(pElem);
1326 pReader->nNode = pReader->nDoclist = pList->nData + 1; 1333 aCopy = (char*)sqlite3_malloc(nCopy);
1327 pReader->aNode = pReader->aDoclist = pList->aData; 1334 if( !aCopy ) return SQLITE_NOMEM;
1335 memcpy(aCopy, pList->aData, nCopy);
1336 pReader->nNode = pReader->nDoclist = nCopy;
1337 pReader->aNode = pReader->aDoclist = aCopy;
1328 pReader->ppNextElem++; 1338 pReader->ppNextElem++;
1329 assert( pReader->aNode ); 1339 assert( pReader->aNode );
1330 } 1340 }
1331 return SQLITE_OK; 1341 return SQLITE_OK;
1332 } 1342 }
1333 1343
1334 fts3SegReaderSetEof(pReader); 1344 fts3SegReaderSetEof(pReader);
1335 1345
1336 /* If iCurrentBlock>=iLeafEndBlock, this is an EOF condition. All leaf 1346 /* If iCurrentBlock>=iLeafEndBlock, this is an EOF condition. All leaf
1337 ** blocks have already been traversed. */ 1347 ** blocks have already been traversed. */
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
1557 } 1567 }
1558 *pnOvfl = nOvfl; 1568 *pnOvfl = nOvfl;
1559 return rc; 1569 return rc;
1560 } 1570 }
1561 1571
1562 /* 1572 /*
1563 ** Free all allocations associated with the iterator passed as the 1573 ** Free all allocations associated with the iterator passed as the
1564 ** second argument. 1574 ** second argument.
1565 */ 1575 */
1566 void sqlite3Fts3SegReaderFree(Fts3SegReader *pReader){ 1576 void sqlite3Fts3SegReaderFree(Fts3SegReader *pReader){
1567 if( pReader && !fts3SegReaderIsPending(pReader) ){ 1577 if( pReader ){
1568 sqlite3_free(pReader->zTerm); 1578 if( !fts3SegReaderIsPending(pReader) ){
1579 sqlite3_free(pReader->zTerm);
1580 }
1569 if( !fts3SegReaderIsRootOnly(pReader) ){ 1581 if( !fts3SegReaderIsRootOnly(pReader) ){
1570 sqlite3_free(pReader->aNode); 1582 sqlite3_free(pReader->aNode);
1571 sqlite3_blob_close(pReader->pBlob);
1572 } 1583 }
1584 sqlite3_blob_close(pReader->pBlob);
1573 } 1585 }
1574 sqlite3_free(pReader); 1586 sqlite3_free(pReader);
1575 } 1587 }
1576 1588
1577 /* 1589 /*
1578 ** Allocate a new SegReader object. 1590 ** Allocate a new SegReader object.
1579 */ 1591 */
1580 int sqlite3Fts3SegReaderNew( 1592 int sqlite3Fts3SegReaderNew(
1581 int iAge, /* Segment "age". */ 1593 int iAge, /* Segment "age". */
1582 int bLookup, /* True for a lookup only */ 1594 int bLookup, /* True for a lookup only */
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1618 } 1630 }
1619 *ppReader = pReader; 1631 *ppReader = pReader;
1620 return SQLITE_OK; 1632 return SQLITE_OK;
1621 } 1633 }
1622 1634
1623 /* 1635 /*
1624 ** This is a comparison function used as a qsort() callback when sorting 1636 ** This is a comparison function used as a qsort() callback when sorting
1625 ** an array of pending terms by term. This occurs as part of flushing 1637 ** an array of pending terms by term. This occurs as part of flushing
1626 ** the contents of the pending-terms hash table to the database. 1638 ** the contents of the pending-terms hash table to the database.
1627 */ 1639 */
1628 static int fts3CompareElemByTerm(const void *lhs, const void *rhs){ 1640 static int SQLITE_CDECL fts3CompareElemByTerm(
1641 const void *lhs,
1642 const void *rhs
1643 ){
1629 char *z1 = fts3HashKey(*(Fts3HashElem **)lhs); 1644 char *z1 = fts3HashKey(*(Fts3HashElem **)lhs);
1630 char *z2 = fts3HashKey(*(Fts3HashElem **)rhs); 1645 char *z2 = fts3HashKey(*(Fts3HashElem **)rhs);
1631 int n1 = fts3HashKeysize(*(Fts3HashElem **)lhs); 1646 int n1 = fts3HashKeysize(*(Fts3HashElem **)lhs);
1632 int n2 = fts3HashKeysize(*(Fts3HashElem **)rhs); 1647 int n2 = fts3HashKeysize(*(Fts3HashElem **)rhs);
1633 1648
1634 int n = (n1<n2 ? n1 : n2); 1649 int n = (n1<n2 ? n1 : n2);
1635 int c = memcmp(z1, z2, n); 1650 int c = memcmp(z1, z2, n);
1636 if( c==0 ){ 1651 if( c==0 ){
1637 c = n1 - n2; 1652 c = n1 - n2;
1638 } 1653 }
(...skipping 1436 matching lines...) Expand 10 before | Expand all | Expand 10 after
3075 ** take place. */ 3090 ** take place. */
3076 bOk = 0; 3091 bOk = 0;
3077 break; 3092 break;
3078 } 3093 }
3079 bOk = 1; 3094 bOk = 1;
3080 } 3095 }
3081 rc = sqlite3_reset(pRange); 3096 rc = sqlite3_reset(pRange);
3082 3097
3083 if( bOk ){ 3098 if( bOk ){
3084 int iIdx = 0; 3099 int iIdx = 0;
3085 sqlite3_stmt *pUpdate1; 3100 sqlite3_stmt *pUpdate1 = 0;
3086 sqlite3_stmt *pUpdate2; 3101 sqlite3_stmt *pUpdate2 = 0;
3087 3102
3088 if( rc==SQLITE_OK ){ 3103 if( rc==SQLITE_OK ){
3089 rc = fts3SqlStmt(p, SQL_UPDATE_LEVEL_IDX, &pUpdate1, 0); 3104 rc = fts3SqlStmt(p, SQL_UPDATE_LEVEL_IDX, &pUpdate1, 0);
3090 } 3105 }
3091 if( rc==SQLITE_OK ){ 3106 if( rc==SQLITE_OK ){
3092 rc = fts3SqlStmt(p, SQL_UPDATE_LEVEL, &pUpdate2, 0); 3107 rc = fts3SqlStmt(p, SQL_UPDATE_LEVEL, &pUpdate2, 0);
3093 } 3108 }
3094 3109
3095 if( rc==SQLITE_OK ){ 3110 if( rc==SQLITE_OK ){
3096 3111
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
3434 ** iIndex/iLangid combination. 3449 ** iIndex/iLangid combination.
3435 */ 3450 */
3436 static int fts3DoOptimize(Fts3Table *p, int bReturnDone){ 3451 static int fts3DoOptimize(Fts3Table *p, int bReturnDone){
3437 int bSeenDone = 0; 3452 int bSeenDone = 0;
3438 int rc; 3453 int rc;
3439 sqlite3_stmt *pAllLangid = 0; 3454 sqlite3_stmt *pAllLangid = 0;
3440 3455
3441 rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0); 3456 rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0);
3442 if( rc==SQLITE_OK ){ 3457 if( rc==SQLITE_OK ){
3443 int rc2; 3458 int rc2;
3444 sqlite3_bind_int(pAllLangid, 1, p->nIndex); 3459 sqlite3_bind_int(pAllLangid, 1, p->iPrevLangid);
3460 sqlite3_bind_int(pAllLangid, 2, p->nIndex);
3445 while( sqlite3_step(pAllLangid)==SQLITE_ROW ){ 3461 while( sqlite3_step(pAllLangid)==SQLITE_ROW ){
3446 int i; 3462 int i;
3447 int iLangid = sqlite3_column_int(pAllLangid, 0); 3463 int iLangid = sqlite3_column_int(pAllLangid, 0);
3448 for(i=0; rc==SQLITE_OK && i<p->nIndex; i++){ 3464 for(i=0; rc==SQLITE_OK && i<p->nIndex; i++){
3449 rc = fts3SegmentMerge(p, iLangid, i, FTS3_SEGCURSOR_ALL); 3465 rc = fts3SegmentMerge(p, iLangid, i, FTS3_SEGCURSOR_ALL);
3450 if( rc==SQLITE_DONE ){ 3466 if( rc==SQLITE_DONE ){
3451 bSeenDone = 1; 3467 bSeenDone = 1;
3452 rc = SQLITE_OK; 3468 rc = SQLITE_OK;
3453 } 3469 }
3454 } 3470 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
3501 }else{ 3517 }else{
3502 memset(aSz, 0, nByte); 3518 memset(aSz, 0, nByte);
3503 aSzIns = &aSz[p->nColumn+1]; 3519 aSzIns = &aSz[p->nColumn+1];
3504 aSzDel = &aSzIns[p->nColumn+1]; 3520 aSzDel = &aSzIns[p->nColumn+1];
3505 } 3521 }
3506 } 3522 }
3507 3523
3508 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ 3524 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
3509 int iCol; 3525 int iCol;
3510 int iLangid = langidFromSelect(p, pStmt); 3526 int iLangid = langidFromSelect(p, pStmt);
3511 rc = fts3PendingTermsDocid(p, iLangid, sqlite3_column_int64(pStmt, 0)); 3527 rc = fts3PendingTermsDocid(p, 0, iLangid, sqlite3_column_int64(pStmt, 0));
3512 memset(aSz, 0, sizeof(aSz[0]) * (p->nColumn+1)); 3528 memset(aSz, 0, sizeof(aSz[0]) * (p->nColumn+1));
3513 for(iCol=0; rc==SQLITE_OK && iCol<p->nColumn; iCol++){ 3529 for(iCol=0; rc==SQLITE_OK && iCol<p->nColumn; iCol++){
3514 if( p->abNotindexed[iCol]==0 ){ 3530 if( p->abNotindexed[iCol]==0 ){
3515 const char *z = (const char *) sqlite3_column_text(pStmt, iCol+1); 3531 const char *z = (const char *) sqlite3_column_text(pStmt, iCol+1);
3516 rc = fts3PendingTermsAdd(p, iLangid, z, iCol, &aSz[iCol]); 3532 rc = fts3PendingTermsAdd(p, iLangid, z, iCol, &aSz[iCol]);
3517 aSz[p->nColumn] += sqlite3_column_bytes(pStmt, iCol+1); 3533 aSz[p->nColumn] += sqlite3_column_bytes(pStmt, iCol+1);
3518 } 3534 }
3519 } 3535 }
3520 if( p->bHasDocsize ){ 3536 if( p->bHasDocsize ){
3521 fts3InsertDocsize(&rc, p, aSz); 3537 fts3InsertDocsize(&rc, p, aSz);
(...skipping 1244 matching lines...) Expand 10 before | Expand all | Expand 10 after
4766 const int nHint = pHint->n; 4782 const int nHint = pHint->n;
4767 int i; 4783 int i;
4768 4784
4769 i = pHint->n-2; 4785 i = pHint->n-2;
4770 while( i>0 && (pHint->a[i-1] & 0x80) ) i--; 4786 while( i>0 && (pHint->a[i-1] & 0x80) ) i--;
4771 while( i>0 && (pHint->a[i-1] & 0x80) ) i--; 4787 while( i>0 && (pHint->a[i-1] & 0x80) ) i--;
4772 4788
4773 pHint->n = i; 4789 pHint->n = i;
4774 i += sqlite3Fts3GetVarint(&pHint->a[i], piAbsLevel); 4790 i += sqlite3Fts3GetVarint(&pHint->a[i], piAbsLevel);
4775 i += fts3GetVarint32(&pHint->a[i], pnInput); 4791 i += fts3GetVarint32(&pHint->a[i], pnInput);
4776 if( i!=nHint ) return SQLITE_CORRUPT_VTAB; 4792 if( i!=nHint ) return FTS_CORRUPT_VTAB;
4777 4793
4778 return SQLITE_OK; 4794 return SQLITE_OK;
4779 } 4795 }
4780 4796
4781 4797
4782 /* 4798 /*
4783 ** Attempt an incremental merge that writes nMerge leaf blocks. 4799 ** Attempt an incremental merge that writes nMerge leaf blocks.
4784 ** 4800 **
4785 ** Incremental merges happen nMin segments at a time. The segments 4801 ** Incremental merges happen nMin segments at a time. The segments
4786 ** to be merged are the nMin oldest segments (the ones with the smallest 4802 ** to be merged are the nMin oldest segments (the ones with the smallest
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
5134 static int fts3IntegrityCheck(Fts3Table *p, int *pbOk){ 5150 static int fts3IntegrityCheck(Fts3Table *p, int *pbOk){
5135 int rc = SQLITE_OK; /* Return code */ 5151 int rc = SQLITE_OK; /* Return code */
5136 u64 cksum1 = 0; /* Checksum based on FTS index contents */ 5152 u64 cksum1 = 0; /* Checksum based on FTS index contents */
5137 u64 cksum2 = 0; /* Checksum based on %_content contents */ 5153 u64 cksum2 = 0; /* Checksum based on %_content contents */
5138 sqlite3_stmt *pAllLangid = 0; /* Statement to return all language-ids */ 5154 sqlite3_stmt *pAllLangid = 0; /* Statement to return all language-ids */
5139 5155
5140 /* This block calculates the checksum according to the FTS index. */ 5156 /* This block calculates the checksum according to the FTS index. */
5141 rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0); 5157 rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0);
5142 if( rc==SQLITE_OK ){ 5158 if( rc==SQLITE_OK ){
5143 int rc2; 5159 int rc2;
5144 sqlite3_bind_int(pAllLangid, 1, p->nIndex); 5160 sqlite3_bind_int(pAllLangid, 1, p->iPrevLangid);
5161 sqlite3_bind_int(pAllLangid, 2, p->nIndex);
5145 while( rc==SQLITE_OK && sqlite3_step(pAllLangid)==SQLITE_ROW ){ 5162 while( rc==SQLITE_OK && sqlite3_step(pAllLangid)==SQLITE_ROW ){
5146 int iLangid = sqlite3_column_int(pAllLangid, 0); 5163 int iLangid = sqlite3_column_int(pAllLangid, 0);
5147 int i; 5164 int i;
5148 for(i=0; i<p->nIndex; i++){ 5165 for(i=0; i<p->nIndex; i++){
5149 cksum1 = cksum1 ^ fts3ChecksumIndex(p, iLangid, i, &rc); 5166 cksum1 = cksum1 ^ fts3ChecksumIndex(p, iLangid, i, &rc);
5150 } 5167 }
5151 } 5168 }
5152 rc2 = sqlite3_reset(pAllLangid); 5169 rc2 = sqlite3_reset(pAllLangid);
5153 if( rc==SQLITE_OK ) rc = rc2; 5170 if( rc==SQLITE_OK ) rc = rc2;
5154 } 5171 }
5155 5172
5156 /* This block calculates the checksum according to the %_content table */ 5173 /* This block calculates the checksum according to the %_content table */
5157 rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0);
5158 if( rc==SQLITE_OK ){ 5174 if( rc==SQLITE_OK ){
5159 sqlite3_tokenizer_module const *pModule = p->pTokenizer->pModule; 5175 sqlite3_tokenizer_module const *pModule = p->pTokenizer->pModule;
5160 sqlite3_stmt *pStmt = 0; 5176 sqlite3_stmt *pStmt = 0;
5161 char *zSql; 5177 char *zSql;
5162 5178
5163 zSql = sqlite3_mprintf("SELECT %s" , p->zReadExprlist); 5179 zSql = sqlite3_mprintf("SELECT %s" , p->zReadExprlist);
5164 if( !zSql ){ 5180 if( !zSql ){
5165 rc = SQLITE_NOMEM; 5181 rc = SQLITE_NOMEM;
5166 }else{ 5182 }else{
5167 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); 5183 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
5244 ** 5260 **
5245 ** If the two checksums are identical, the integrity-check is deemed to have 5261 ** If the two checksums are identical, the integrity-check is deemed to have
5246 ** passed. 5262 ** passed.
5247 */ 5263 */
5248 static int fts3DoIntegrityCheck( 5264 static int fts3DoIntegrityCheck(
5249 Fts3Table *p /* FTS3 table handle */ 5265 Fts3Table *p /* FTS3 table handle */
5250 ){ 5266 ){
5251 int rc; 5267 int rc;
5252 int bOk = 0; 5268 int bOk = 0;
5253 rc = fts3IntegrityCheck(p, &bOk); 5269 rc = fts3IntegrityCheck(p, &bOk);
5254 if( rc==SQLITE_OK && bOk==0 ) rc = SQLITE_CORRUPT_VTAB; 5270 if( rc==SQLITE_OK && bOk==0 ) rc = FTS_CORRUPT_VTAB;
5255 return rc; 5271 return rc;
5256 } 5272 }
5257 5273
5258 /* 5274 /*
5259 ** Handle a 'special' INSERT of the form: 5275 ** Handle a 'special' INSERT of the form:
5260 ** 5276 **
5261 ** "INSERT INTO tbl(tbl) VALUES(<expr>)" 5277 ** "INSERT INTO tbl(tbl) VALUES(<expr>)"
5262 ** 5278 **
5263 ** Argument pVal contains the result of <expr>. Currently the only 5279 ** Argument pVal contains the result of <expr>. Currently the only
5264 ** meaningful value to insert is the text 'optimize'. 5280 ** meaningful value to insert is the text 'optimize'.
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
5606 /* If this is an INSERT or UPDATE operation, insert the new record. */ 5622 /* If this is an INSERT or UPDATE operation, insert the new record. */
5607 if( nArg>1 && rc==SQLITE_OK ){ 5623 if( nArg>1 && rc==SQLITE_OK ){
5608 int iLangid = sqlite3_value_int(apVal[2 + p->nColumn + 2]); 5624 int iLangid = sqlite3_value_int(apVal[2 + p->nColumn + 2]);
5609 if( bInsertDone==0 ){ 5625 if( bInsertDone==0 ){
5610 rc = fts3InsertData(p, apVal, pRowid); 5626 rc = fts3InsertData(p, apVal, pRowid);
5611 if( rc==SQLITE_CONSTRAINT && p->zContentTbl==0 ){ 5627 if( rc==SQLITE_CONSTRAINT && p->zContentTbl==0 ){
5612 rc = FTS_CORRUPT_VTAB; 5628 rc = FTS_CORRUPT_VTAB;
5613 } 5629 }
5614 } 5630 }
5615 if( rc==SQLITE_OK && (!isRemove || *pRowid!=p->iPrevDocid ) ){ 5631 if( rc==SQLITE_OK && (!isRemove || *pRowid!=p->iPrevDocid ) ){
5616 rc = fts3PendingTermsDocid(p, iLangid, *pRowid); 5632 rc = fts3PendingTermsDocid(p, 0, iLangid, *pRowid);
5617 } 5633 }
5618 if( rc==SQLITE_OK ){ 5634 if( rc==SQLITE_OK ){
5619 assert( p->iPrevDocid==*pRowid ); 5635 assert( p->iPrevDocid==*pRowid );
5620 rc = fts3InsertTerms(p, iLangid, apVal, aSzIns); 5636 rc = fts3InsertTerms(p, iLangid, apVal, aSzIns);
5621 } 5637 }
5622 if( p->bHasDocsize ){ 5638 if( p->bHasDocsize ){
5623 fts3InsertDocsize(&rc, p, aSzIns); 5639 fts3InsertDocsize(&rc, p, aSzIns);
5624 } 5640 }
5625 nChng++; 5641 nChng++;
5626 } 5642 }
(...skipping 24 matching lines...) Expand all
5651 }else{ 5667 }else{
5652 sqlite3_exec(p->db, "ROLLBACK TO fts3", 0, 0, 0); 5668 sqlite3_exec(p->db, "ROLLBACK TO fts3", 0, 0, 0);
5653 sqlite3_exec(p->db, "RELEASE fts3", 0, 0, 0); 5669 sqlite3_exec(p->db, "RELEASE fts3", 0, 0, 0);
5654 } 5670 }
5655 } 5671 }
5656 sqlite3Fts3SegmentsClose(p); 5672 sqlite3Fts3SegmentsClose(p);
5657 return rc; 5673 return rc;
5658 } 5674 }
5659 5675
5660 #endif 5676 #endif
OLDNEW
« no previous file with comments | « third_party/sqlite/src/ext/fts3/fts3_tokenizer.c ('k') | third_party/sqlite/src/ext/fts3/tool/fts3view.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698