Fix a problem causing the "number-of-documents" field maintained by FTS4 to be set incorrectly.
FossilOrigin-Name: e38fb02d5ea5daa6992df4dfbbeec92bf7b525f6
This commit is contained in:
parent
6d405c2cb7
commit
bba44d0d1b
@ -776,7 +776,7 @@ static int fts3PendingTermsAdd(
|
||||
int iLangid, /* Language id to use */
|
||||
const char *zText, /* Text of document to be inserted */
|
||||
int iCol, /* Column into which text is being inserted */
|
||||
u32 *pnWord /* OUT: Number of tokens inserted */
|
||||
u32 *pnWord /* IN/OUT: Incr. by number tokens inserted */
|
||||
){
|
||||
int rc;
|
||||
int iStart = 0;
|
||||
@ -840,7 +840,7 @@ static int fts3PendingTermsAdd(
|
||||
}
|
||||
|
||||
pModule->xClose(pCsr);
|
||||
*pnWord = nWord;
|
||||
*pnWord += nWord;
|
||||
return (rc==SQLITE_DONE ? SQLITE_OK : rc);
|
||||
}
|
||||
|
||||
@ -1044,11 +1044,13 @@ static void fts3DeleteTerms(
|
||||
int *pRC, /* Result code */
|
||||
Fts3Table *p, /* The FTS table to delete from */
|
||||
sqlite3_value *pRowid, /* The docid to be deleted */
|
||||
u32 *aSz /* Sizes of deleted document written here */
|
||||
u32 *aSz, /* Sizes of deleted document written here */
|
||||
int *pbFound /* OUT: Set to true if row really does exist */
|
||||
){
|
||||
int rc;
|
||||
sqlite3_stmt *pSelect;
|
||||
|
||||
assert( *pbFound==0 );
|
||||
if( *pRC ) return;
|
||||
rc = fts3SqlStmt(p, SQL_SELECT_CONTENT_BY_ROWID, &pSelect, &pRowid);
|
||||
if( rc==SQLITE_OK ){
|
||||
@ -1066,6 +1068,7 @@ static void fts3DeleteTerms(
|
||||
*pRC = rc;
|
||||
return;
|
||||
}
|
||||
*pbFound = 1;
|
||||
}
|
||||
rc = sqlite3_reset(pSelect);
|
||||
}else{
|
||||
@ -3290,7 +3293,7 @@ static int fts3DoRebuild(Fts3Table *p){
|
||||
int iCol;
|
||||
int iLangid = langidFromSelect(p, pStmt);
|
||||
rc = fts3PendingTermsDocid(p, iLangid, sqlite3_column_int64(pStmt, 0));
|
||||
aSz[p->nColumn] = 0;
|
||||
memset(aSz, 0, sizeof(aSz[0]) * (p->nColumn+1));
|
||||
for(iCol=0; rc==SQLITE_OK && iCol<p->nColumn; iCol++){
|
||||
const char *z = (const char *) sqlite3_column_text(pStmt, iCol+1);
|
||||
rc = fts3PendingTermsAdd(p, iLangid, z, iCol, &aSz[iCol]);
|
||||
@ -5194,28 +5197,32 @@ int sqlite3Fts3DeferToken(
|
||||
static int fts3DeleteByRowid(
|
||||
Fts3Table *p,
|
||||
sqlite3_value *pRowid,
|
||||
int *pnDoc,
|
||||
int *pnChng, /* IN/OUT: Decrement if row is deleted */
|
||||
u32 *aSzDel
|
||||
){
|
||||
int isEmpty = 0;
|
||||
int rc = fts3IsEmpty(p, pRowid, &isEmpty);
|
||||
if( rc==SQLITE_OK ){
|
||||
if( isEmpty ){
|
||||
/* Deleting this row means the whole table is empty. In this case
|
||||
** delete the contents of all three tables and throw away any
|
||||
** data in the pendingTerms hash table. */
|
||||
rc = fts3DeleteAll(p, 1);
|
||||
*pnDoc = *pnDoc - 1;
|
||||
}else{
|
||||
fts3DeleteTerms(&rc, p, pRowid, aSzDel);
|
||||
if( p->zContentTbl==0 ){
|
||||
fts3SqlExec(&rc, p, SQL_DELETE_CONTENT, &pRowid);
|
||||
if( sqlite3_changes(p->db) ) *pnDoc = *pnDoc - 1;
|
||||
int rc = SQLITE_OK; /* Return code */
|
||||
int bFound = 0; /* True if *pRowid really is in the table */
|
||||
|
||||
fts3DeleteTerms(&rc, p, pRowid, aSzDel, &bFound);
|
||||
if( bFound && rc==SQLITE_OK ){
|
||||
int isEmpty = 0; /* Deleting *pRowid leaves the table empty */
|
||||
rc = fts3IsEmpty(p, pRowid, &isEmpty);
|
||||
if( rc==SQLITE_OK ){
|
||||
if( isEmpty ){
|
||||
/* Deleting this row means the whole table is empty. In this case
|
||||
** delete the contents of all three tables and throw away any
|
||||
** data in the pendingTerms hash table. */
|
||||
rc = fts3DeleteAll(p, 1);
|
||||
*pnChng = 0;
|
||||
memset(aSzDel, 0, sizeof(u32) * (p->nColumn+1) * 2);
|
||||
}else{
|
||||
*pnDoc = *pnDoc - 1;
|
||||
}
|
||||
if( p->bHasDocsize ){
|
||||
fts3SqlExec(&rc, p, SQL_DELETE_DOCSIZE, &pRowid);
|
||||
*pnChng = *pnChng - 1;
|
||||
if( p->zContentTbl==0 ){
|
||||
fts3SqlExec(&rc, p, SQL_DELETE_CONTENT, &pRowid);
|
||||
}
|
||||
if( p->bHasDocsize ){
|
||||
fts3SqlExec(&rc, p, SQL_DELETE_DOCSIZE, &pRowid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5274,13 +5281,13 @@ int sqlite3Fts3UpdateMethod(
|
||||
}
|
||||
|
||||
/* Allocate space to hold the change in document sizes */
|
||||
aSzIns = sqlite3_malloc( sizeof(aSzIns[0])*(p->nColumn+1)*2 );
|
||||
if( aSzIns==0 ){
|
||||
aSzDel = sqlite3_malloc( sizeof(aSzDel[0])*(p->nColumn+1)*2 );
|
||||
if( aSzDel==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
goto update_out;
|
||||
}
|
||||
aSzDel = &aSzIns[p->nColumn+1];
|
||||
memset(aSzIns, 0, sizeof(aSzIns[0])*(p->nColumn+1)*2);
|
||||
aSzIns = &aSzDel[p->nColumn+1];
|
||||
memset(aSzDel, 0, sizeof(aSzDel[0])*(p->nColumn+1)*2);
|
||||
|
||||
/* If this is an INSERT operation, or an UPDATE that modifies the rowid
|
||||
** value, then this operation requires constraint handling.
|
||||
@ -5365,7 +5372,7 @@ int sqlite3Fts3UpdateMethod(
|
||||
}
|
||||
|
||||
update_out:
|
||||
sqlite3_free(aSzIns);
|
||||
sqlite3_free(aSzDel);
|
||||
sqlite3Fts3SegmentsClose(p);
|
||||
return rc;
|
||||
}
|
||||
|
16
manifest
16
manifest
@ -1,5 +1,5 @@
|
||||
C Have\sthe\swindows\simplementation\sof\sxDelete\sreturn\sSQLITE_IOERR_DELETE_NOENT\nif\sthe\sfile\sto\sbe\sdeleted\sdoes\snot\sexist.\s\sThe\sunix\simplementation\swas\npreviously\smodified\sto\sbehave\sthis\sway.\s\sThe\scurrent\schanges\ssimply\sbrings\nthe\stwo\simplementations\sinto\salignment.
|
||||
D 2012-11-20T15:06:57.977
|
||||
C Fix\sa\sproblem\scausing\sthe\s"number-of-documents"\sfield\smaintained\sby\sFTS4\sto\sbe\sset\sincorrectly.
|
||||
D 2012-11-27T15:56:38.822
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in 82c41c0ed4cc94dd3cc7d498575b84c57c2c2384
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@ -72,7 +72,7 @@ F ext/fts3/fts3_tokenizer.h 66dec98e365854b6cd2d54f1a96bb6d428fc5a68
|
||||
F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004
|
||||
F ext/fts3/fts3_unicode.c 49e36e6ba59f79e6bd6a8bfe434570fe48d20559
|
||||
F ext/fts3/fts3_unicode2.c a863f05f758af36777dffc2facc898bc73fec896
|
||||
F ext/fts3/fts3_write.c ba0bb0a91ca792fba5101bd82fa14d8a00a96365
|
||||
F ext/fts3/fts3_write.c a432433a706bd065e8bb0f8b3b33ce7cf9d7f21d
|
||||
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
|
||||
F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
|
||||
F ext/fts3/tool/fts3view.c 6cfc5b67a5f0e09c0d698f9fd012c784bfaa9197
|
||||
@ -471,7 +471,7 @@ F test/fts3aux1.test 0b02743955d56fc0d4d66236a26177bd1b726de0
|
||||
F test/fts3b.test e93bbb653e52afde110ad53bbd793f14fe7a8984
|
||||
F test/fts3c.test fc723a9cf10b397fdfc2b32e73c53c8b1ec02958
|
||||
F test/fts3comp1.test a0f5b16a2df44dd0b15751787130af2183167c0c
|
||||
F test/fts3conf.test 8e65ea56f88ced6cdd2252bdddb1a8327ae5af7e
|
||||
F test/fts3conf.test ee8500c86dd58ec075e8831a1e216a79989436de
|
||||
F test/fts3corrupt.test 7b0f91780ca36118d73324ec803187208ad33b32
|
||||
F test/fts3corrupt2.test 6d96efae2f8a6af3eeaf283aba437e6d0e5447ba
|
||||
F test/fts3cov.test e0fb00d8b715ddae4a94c305992dfc3ef70353d7
|
||||
@ -1024,7 +1024,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
|
||||
F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
|
||||
P 29980b08ec591f695386b715df72d4afb6ffc3fb
|
||||
R b34ddf6d9c41f9627ecb66c931c8da70
|
||||
U drh
|
||||
Z d5d273e9e92a86e1ab421c06a18a3cfd
|
||||
P d4c36d4991b048133efb21b251ab57fa66764d9d
|
||||
R 2a6f06cab2a0521f17074582d293668f
|
||||
U dan
|
||||
Z e9d30bbbbbbe7245e672e07e58ec0924
|
||||
|
@ -1 +1 @@
|
||||
d4c36d4991b048133efb21b251ab57fa66764d9d
|
||||
e38fb02d5ea5daa6992df4dfbbeec92bf7b525f6
|
@ -136,4 +136,46 @@ do_execsql_test 2.2.2 { COMMIT }
|
||||
do_execsql_test 2.2.3 { SELECT * FROM t1 } {{a b c} {a b c}}
|
||||
fts3_integrity 2.2.4 db t1
|
||||
|
||||
do_execsql_test 3.1 {
|
||||
CREATE VIRTUAL TABLE t3 USING fts4;
|
||||
REPLACE INTO t3(docid, content) VALUES (1, 'one two');
|
||||
SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'one'
|
||||
} {X'0100000002000000'}
|
||||
|
||||
do_execsql_test 3.2 {
|
||||
REPLACE INTO t3(docid, content) VALUES (2, 'one two three four');
|
||||
SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'four'
|
||||
} {X'0200000003000000'}
|
||||
|
||||
do_execsql_test 3.3 {
|
||||
REPLACE INTO t3(docid, content) VALUES (1, 'one two three four five six');
|
||||
SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'six'
|
||||
} {X'0200000005000000'}
|
||||
|
||||
do_execsql_test 3.4 {
|
||||
UPDATE OR REPLACE t3 SET docid = 2 WHERE docid=1;
|
||||
SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'six'
|
||||
} {X'0100000006000000'}
|
||||
|
||||
do_execsql_test 3.5 {
|
||||
UPDATE OR REPLACE t3 SET docid = 3 WHERE docid=2;
|
||||
SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'six'
|
||||
} {X'0100000006000000'}
|
||||
|
||||
do_execsql_test 3.6 {
|
||||
REPLACE INTO t3(docid, content) VALUES (3, 'one two');
|
||||
SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'one'
|
||||
} {X'0100000002000000'}
|
||||
|
||||
do_execsql_test 3.7 {
|
||||
REPLACE INTO t3(docid, content) VALUES (NULL, 'one two three four');
|
||||
REPLACE INTO t3(docid, content) VALUES (NULL, 'one two three four five six');
|
||||
SELECT docid FROM t3;
|
||||
} {3 4 5}
|
||||
|
||||
do_execsql_test 3.8 {
|
||||
UPDATE OR REPLACE t3 SET docid = 5, content='three four' WHERE docid = 4;
|
||||
SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'one'
|
||||
} {X'0200000002000000'}
|
||||
|
||||
finish_test
|
||||
|
Loading…
x
Reference in New Issue
Block a user