]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix two problems that could cause fts3 auxiliary functions to occasionally misbehave...
authordan <dan@noemail.net>
Wed, 8 Jul 2015 17:59:08 +0000 (17:59 +0000)
committerdan <dan@noemail.net>
Wed, 8 Jul 2015 17:59:08 +0000 (17:59 +0000)
FossilOrigin-Name: 372c1db2475f367d54270d5801aff0503745bff4

ext/fts3/fts3.c
manifest
manifest.uuid
test/fts3fault.test
test/fts3offsets.test [new file with mode: 0644]

index ac492ff1afa68deb4edff9739ebd289278338593..903d7d84fd3e423eaa846cdacce02c8619bab809 100644 (file)
@@ -4351,6 +4351,7 @@ void sqlite3Fts3DoclistNext(
     p += sqlite3Fts3GetVarint(p, piDocid);
   }else{
     fts3PoslistCopy(0, &p);
+    while( p<&aDoclist[nDoclist] && *p==0 ) p++; 
     if( p>=&aDoclist[nDoclist] ){
       *pbEof = 1;
     }else{
@@ -5757,10 +5758,10 @@ int sqlite3Fts3EvalPhrasePoslist(
     int rc = SQLITE_OK;
     int bDescDoclist = pTab->bDescIdx;      /* For DOCID_CMP macro */
     int bOr = 0;
-    u8 bEof = 0;
     u8 bTreeEof = 0;
     Fts3Expr *p;                  /* Used to iterate from pExpr to root */
     Fts3Expr *pNear;              /* Most senior NEAR ancestor (or pExpr) */
+    int bMatch;
 
     /* Check if this phrase descends from an OR expression node. If not, 
     ** return NULL. Otherwise, the entry that corresponds to docid 
@@ -5794,31 +5795,47 @@ int sqlite3Fts3EvalPhrasePoslist(
     }
     if( rc!=SQLITE_OK ) return rc;
 
-    pIter = pPhrase->pOrPoslist;
-    iDocid = pPhrase->iOrDocid;
-    if( pCsr->bDesc==bDescDoclist ){
-      bEof = !pPhrase->doclist.nAll ||
-                 (pIter >= (pPhrase->doclist.aAll + pPhrase->doclist.nAll));
-      while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){
-        sqlite3Fts3DoclistNext(
-            bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll, 
-            &pIter, &iDocid, &bEof
-        );
-      }
-    }else{
-      bEof = !pPhrase->doclist.nAll || (pIter && pIter<=pPhrase->doclist.aAll);
-      while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)>0 ) && bEof==0 ){
-        int dummy;
-        sqlite3Fts3DoclistPrev(
-            bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll, 
-            &pIter, &iDocid, &dummy, &bEof
-        );
+    bMatch = 1;
+    for(p=pNear; p; p=p->pLeft){
+      u8 bEof = 0;
+      Fts3Expr *pTest = p;
+      Fts3Phrase *pPh;
+      assert( pTest->eType==FTSQUERY_NEAR || pTest->eType==FTSQUERY_PHRASE );
+      if( pTest->eType==FTSQUERY_NEAR ) pTest = pTest->pRight;
+      assert( pTest->eType==FTSQUERY_PHRASE );
+      pPh = pTest->pPhrase;
+
+      pIter = pPh->pOrPoslist;
+      iDocid = pPh->iOrDocid;
+      if( pCsr->bDesc==bDescDoclist ){
+        bEof = !pPh->doclist.nAll ||
+          (pIter >= (pPh->doclist.aAll + pPh->doclist.nAll));
+        while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){
+          sqlite3Fts3DoclistNext(
+              bDescDoclist, pPh->doclist.aAll, pPh->doclist.nAll, 
+              &pIter, &iDocid, &bEof
+          );
+        }
+      }else{
+        bEof = !pPh->doclist.nAll || (pIter && pIter<=pPh->doclist.aAll);
+        while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)>0 ) && bEof==0 ){
+          int dummy;
+          sqlite3Fts3DoclistPrev(
+              bDescDoclist, pPh->doclist.aAll, pPh->doclist.nAll, 
+              &pIter, &iDocid, &dummy, &bEof
+              );
+        }
       }
+      pPh->pOrPoslist = pIter;
+      pPh->iOrDocid = iDocid;
+      if( bEof || iDocid!=pCsr->iPrevId ) bMatch = 0;
     }
-    pPhrase->pOrPoslist = pIter;
-    pPhrase->iOrDocid = iDocid;
 
-    if( bEof || iDocid!=pCsr->iPrevId ) pIter = 0;
+    if( bMatch ){
+      pIter = pPhrase->pOrPoslist;
+    }else{
+      pIter = 0;
+    }
   }
   if( pIter==0 ) return SQLITE_OK;
 
index 8742d04df9ada7b08af04ebdb7e8976ee23304fe..cd16d59a373257d748c72b6de8e287cba7f92061 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Enhance\sthe\spcache1\spage\scache\sso\sthat\sit\stries\sto\sallocate\sa\sblock\sof\nSQLITE_DEFAULT_PCACHE_INITSZ\spages\sfrom\smalloc()\son\sstartup,\sand\suses\sthose\npreallocated\spages\swhen\spossible\srather\sthan\sgoing\sto\smalloc()\sfor\seach\nindividual\spage.\s\sAbout\sa\s5%\sperformance\sincrease\sfor\ssome\sworkloads.
-D 2015-07-08T16:22:42.453
+C Fix\stwo\sproblems\sthat\scould\scause\sfts3\sauxiliary\sfunctions\sto\soccasionally\smisbehave\sif\sused\swith\smatch\sexpressions\sthat\scontain\sboth\sOR\sand\sNEAR.
+D 2015-07-08T17:59:08.894
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 017bf0511d1b2dd1db5e16488fbf75a17b526cbc
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -78,7 +78,7 @@ F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51
 F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
 F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314
 F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
-F ext/fts3/fts3.c a95de5190cf52f4fa9d5952890399cab63e632b9
+F ext/fts3/fts3.c d2f7981f4d7dfeb76aac82a15c7f37f425329c0f
 F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
 F ext/fts3/fts3Int.h 601743955ac43a0e82e6828a931c07bb3b0c95ff
 F ext/fts3/fts3_aux.c 9edc3655fcb287f0467d0a4b886a01c6185fe9f1
@@ -691,13 +691,14 @@ F test/fts3expr2.test 18da930352e5693eaa163a3eacf96233b7290d1a
 F test/fts3expr3.test 9e91b8edbcb197bf2e92161aa7696446d96dce5f
 F test/fts3expr4.test e1be1248566f43c252d4404d52914f1fc4bfa065
 F test/fts3expr5.test f9abfffbf5e53d48a33e12a1e8f8ba2c551c9b49
-F test/fts3fault.test cb72dccb0a3b9f730f16c5240f3fcb9303eb1660
+F test/fts3fault.test da49627b280b210ebc6657f76344c7851f10ce66
 F test/fts3fault2.test f953bb3cf903988172270a9a0aafd5a890b0f98f
 F test/fts3first.test dbdedd20914c8d539aa3206c9b34a23775644641
 F test/fts3join.test 53e66a0c21eb568580674a43b21c059acb26f499
 F test/fts3malloc.test b0e4c133b8d61d4f6d112d8110f8320e9e453ef6
 F test/fts3matchinfo.test 07009313ad6c082f94d8c9c3228eb8940c93ac71
 F test/fts3near.test 7e3354d46f155a822b59c0e957fd2a70c1d7e905
+F test/fts3offsets.test 5b8ec5be27dd2070af3538b23c67f1ca8c822853
 F test/fts3prefix.test fa794eaab0bdae466494947b0b153d7844478ab2
 F test/fts3prefix2.test e1f0a822ca661dced7f12ce392e14eaf65609dce
 F test/fts3query.test f33eb71a1fe1084ea585eeb7ee76b390729f5170
@@ -1364,8 +1365,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P b27a47fef995f0ab2516e6ca779711cab1f50fb9 c1e2ed0ef4d3436d19d3203c5fb553caac53659e
-R 0716d0744f0e72c8cdadbca41133bc14
-T +closed c1e2ed0ef4d3436d19d3203c5fb553caac53659e
-U drh
-Z eea1350426d30f63377f69d37a46ee1a
+P 5348ffc3fda5168c1e9e14aa88b0c6aedbda7c94
+R bb6c5e63b90e2eefb82b18295e953873
+U dan
+Z bead1c8f07e0e547f66cbd142b1cf6b7
index a2762d1d63c1e874d1b829ca2740090d33a2f207..7344ce86e2be806fe680073d102a787e96fb57fb 100644 (file)
@@ -1 +1 @@
-5348ffc3fda5168c1e9e14aa88b0c6aedbda7c94
\ No newline at end of file
+372c1db2475f367d54270d5801aff0503745bff4
\ No newline at end of file
index ab82daa935622f3038416e8accbdda56cb6b8aef..7d9433205958301a7313062d0f945e5d72a0ea18 100644 (file)
@@ -18,6 +18,8 @@ set ::testprefix fts3fault
 # If SQLITE_ENABLE_FTS3 is not defined, omit this file.
 ifcapable !fts3 { finish_test ; return }
 
+if 0 {
+
 # Test error handling in the sqlite3Fts3Init() function. This is the 
 # function that registers the FTS3 module and various support functions
 # with SQLite.
@@ -157,6 +159,9 @@ do_faultsim_test 7.3 -prep {
                        {1 {SQL logic error or missing database}}
 }
 
+
+}
+
 proc mit {blob} {
   set scan(littleEndian) i*
   set scan(bigEndian) I*
@@ -176,7 +181,7 @@ do_test 8.0 {
   faultsim_save_and_close
 } {}
 
-do_faultsim_test 8.1 -prep { 
+do_faultsim_test 8.1 -faults oom-t* -prep { 
   faultsim_restore_and_reopen
   db func mit mit
 } -body {
@@ -184,6 +189,7 @@ do_faultsim_test 8.1 -prep {
 } -test {
   faultsim_test_result {0 {{1 1 1 1 4 2 1 5 5}}}
 }
+
 do_faultsim_test 8.2 -faults oom-t* -prep { 
   faultsim_restore_and_reopen
   db func mit mit
diff --git a/test/fts3offsets.test b/test/fts3offsets.test
new file mode 100644 (file)
index 0000000..184321a
--- /dev/null
@@ -0,0 +1,124 @@
+# 2010 November 02
+#
+# The author disclaims copyright to this source code.  In place of
+# a legal notice, here is a blessing:
+#
+#    May you do good and not evil.
+#    May you find forgiveness for yourself and forgive others.
+#    May you share freely, never taking more than you give.
+#
+#***********************************************************************
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+# If SQLITE_ENABLE_FTS3 is not defined, omit this file.
+ifcapable !fts3 { finish_test ; return }
+
+set testprefix fts3offsets
+set sqlite_fts3_enable_parentheses 1
+
+proc extract {offsets text} {
+  set res ""
+
+  set off [list]
+  foreach {t i s n} $offsets {
+    lappend off [list $s $n]
+  }
+  set off [lsort -integer -index 0 $off]
+
+  set iOff 0
+  foreach e $off {
+    foreach {s n} $e {}
+    append res [string range $text $iOff $s-1]
+    append res "("
+    append res [string range $text $s [expr $s+$n-1]]
+    append res ")"
+    set iOff [expr $s+$n]
+  }
+  append res [string range $text $iOff end]
+  
+  set res
+}
+db func extract extract
+
+
+do_execsql_test 1.1.0 {
+  CREATE VIRTUAL TABLE xx USING fts3(x);
+  INSERT INTO xx VALUES('A x x x B C x x');
+  INSERT INTO xx VALUES('A B C x B x x C');
+  INSERT INTO xx VALUES('A x x B C x x x');
+}
+do_execsql_test 1.1.1 {
+  SELECT oid,extract(offsets(xx), x) FROM xx WHERE xx MATCH 'a OR (b NEAR/1 c)';
+} {
+  1 {(A) x x x (B) (C) x x} 
+  2 {(A) (B) (C) x (B) x x C} 
+  3 {(A) x x (B) (C) x x x}
+}
+
+do_execsql_test 1.2 {
+  DELETE FROM xx;
+  INSERT INTO xx VALUES('A x x x B C x x');
+  INSERT INTO xx VALUES('A x x C x x x C');
+  INSERT INTO xx VALUES('A x x B C x x x');
+}
+do_execsql_test 1.2.1 {
+  SELECT oid,extract(offsets(xx), x) FROM xx WHERE xx MATCH 'a OR (b NEAR/1 c)';
+} {
+  1 {(A) x x x (B) (C) x x}
+  2 {(A) x x C x x x C} 
+  3 {(A) x x (B) (C) x x x}
+}
+
+do_execsql_test 1.3 {
+  DELETE FROM xx;
+  INSERT INTO xx(rowid, x) VALUES(1, 'A B C');
+  INSERT INTO xx(rowid, x) VALUES(2, 'A x');
+  INSERT INTO xx(rowid, x) VALUES(3, 'A B C');
+  INSERT INTO xx(rowid, x) VALUES(4, 'A B C x x x x x x x B');
+  INSERT INTO xx(rowid, x) VALUES(5, 'A x x x x x x x x x C');
+  INSERT INTO xx(rowid, x) VALUES(6, 'A x x x x x x x x x x x B');
+  INSERT INTO xx(rowid, x) VALUES(7, 'A B C');
+}
+do_execsql_test 1.3.1 {
+  SELECT oid,extract(offsets(xx), x) FROM xx WHERE xx MATCH 'a OR (b NEAR/1 c)';
+} {
+  1 {(A) (B) (C)}
+  2 {(A) x}
+  3 {(A) (B) (C)}
+  4 {(A) (B) (C) x x x x x x x B}
+  5 {(A) x x x x x x x x x C}
+  6 {(A) x x x x x x x x x x x B} 
+  7 {(A) (B) (C)}
+}
+
+
+do_execsql_test 1.4 {
+  DELETE FROM xx;
+  INSERT INTO xx(rowid, x) VALUES(7, 'A B C');
+  INSERT INTO xx(rowid, x) VALUES(6, 'A x');
+  INSERT INTO xx(rowid, x) VALUES(5, 'A B C');
+  INSERT INTO xx(rowid, x) VALUES(4, 'A B C x x x x x x x B');
+  INSERT INTO xx(rowid, x) VALUES(3, 'A x x x x x x x x x C');
+  INSERT INTO xx(rowid, x) VALUES(2, 'A x x x x x x x x x x x B');
+  INSERT INTO xx(rowid, x) VALUES(1, 'A B C');
+}
+do_execsql_test 1.4.1 {
+  SELECT oid,extract(offsets(xx), x) FROM xx WHERE xx MATCH 'a OR (b NEAR/1 c)'
+  ORDER BY docid DESC;
+} {
+  7 {(A) (B) (C)}
+  6 {(A) x}
+  5 {(A) (B) (C)}
+  4 {(A) (B) (C) x x x x x x x B}
+  3 {(A) x x x x x x x x x C}
+  2 {(A) x x x x x x x x x x x B} 
+  1 {(A) (B) (C)}
+}
+
+
+set sqlite_fts3_enable_parentheses 0
+finish_test
+