]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix a problem causing the "number-of-documents" field maintained by FTS4 to be set...
authordan <dan@noemail.net>
Tue, 27 Nov 2012 15:56:38 +0000 (15:56 +0000)
committerdan <dan@noemail.net>
Tue, 27 Nov 2012 15:56:38 +0000 (15:56 +0000)
FossilOrigin-Name: e38fb02d5ea5daa6992df4dfbbeec92bf7b525f6

ext/fts3/fts3_write.c
manifest
manifest.uuid
test/fts3conf.test

index 7869e638c5d999686f87802becbbe4611ebde0da..2cfdd2a66cb03d13c6827bfbf903a639945fdafd 100644 (file)
@@ -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;
 }
index 42664c084e92e65ca8ef13ddd30026049f6fbcb1..85a64b7abf44a9b0a8f23bf6e91afbb4fc971f57 100644 (file)
--- a/manifest
+++ b/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
index 6a072bfe5932dc3d14ea8ed6f0c0383683aceb5d..8a978c3936197d9b4ae5eef13c3e745986d154c9 100644 (file)
@@ -1 +1 @@
-d4c36d4991b048133efb21b251ab57fa66764d9d
\ No newline at end of file
+e38fb02d5ea5daa6992df4dfbbeec92bf7b525f6
\ No newline at end of file
index ce410277cac4fe6a9183667abc4a65f5a2533021..e91efbefbef9d5646b18c2b897646b386dd74112 100644 (file)
@@ -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