]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Update the spellfix virtual table extension so that an explicit "top = ?" constraint...
authordan <dan@noemail.net>
Wed, 5 Aug 2015 15:29:32 +0000 (15:29 +0000)
committerdan <dan@noemail.net>
Wed, 5 Aug 2015 15:29:32 +0000 (15:29 +0000)
FossilOrigin-Name: 0888838371608558f31d5bcb5fed1c8861aa52c1

ext/misc/spellfix.c
manifest
manifest.uuid

index b9514427cf9eac5bbc0e6cd9cb5deca1a3784b87..336203433ecea59dab6efbd0d48343b919845b64 100644 (file)
@@ -1770,6 +1770,7 @@ struct spellfix1_cursor {
   sqlite3_vtab_cursor base;    /* Base class - must be first */
   spellfix1_vtab *pVTab;       /* The table to which this cursor belongs */
   char *zPattern;              /* rhs of MATCH clause */
+  int idxNum;                  /* idxNum value passed to xFilter() */
   int nRow;                    /* Number of rows of content */
   int nAlloc;                  /* Number of allocated rows */
   int iRow;                    /* Current row of content */
@@ -2040,26 +2041,19 @@ static int spellfix1Close(sqlite3_vtab_cursor *cur){
   return SQLITE_OK;
 }
 
+#define SPELLFIX_IDXNUM_MATCH  0x01         /* word MATCH $str */
+#define SPELLFIX_IDXNUM_LANGID 0x02         /* langid == $langid */
+#define SPELLFIX_IDXNUM_TOP    0x04         /* top = $top */
+#define SPELLFIX_IDXNUM_SCOPE  0x08         /* scope = $scope */
+#define SPELLFIX_IDXNUM_DISTLT 0x10         /* distance < $distance */
+#define SPELLFIX_IDXNUM_DISTLE 0x20         /* distance <= $distance */
+#define SPELLFIX_IDXNUM_ROWID  0x40         /* rowid = $rowid */
+#define SPELLFIX_IDXNUM_DIST   (0x10|0x20)  /* DISTLT and DISTLE */
+
 /*
-** Search for terms of these forms:
-**
-**   (A)    word MATCH $str
-**   (B)    langid == $langid
-**   (C)    top = $top
-**   (D)    scope = $scope
-**   (E)    distance < $distance
-**   (F)    distance <= $distance
-**   (G)    rowid = $rowid
-**
-** The plan number is a bit mask formed with these bits:
 **
-**   0x01   (A) is found
-**   0x02   (B) is found
-**   0x04   (C) is found
-**   0x08   (D) is found
-**   0x10   (E) is found
-**   0x20   (F) is found
-**   0x40   (G) is found
+** The plan number is a bitmask of the SPELLFIX_IDXNUM_* values defined
+** above.
 **
 ** filter.argv[*] values contains $str, $langid, $top, $scope and $rowid
 ** if specified and in that order.
@@ -2078,62 +2072,66 @@ static int spellfix1BestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
     if( pConstraint->usable==0 ) continue;
 
     /* Terms of the form:  word MATCH $str */
-    if( (iPlan & 1)==0 
+    if( (iPlan & SPELLFIX_IDXNUM_MATCH)==0 
      && pConstraint->iColumn==SPELLFIX_COL_WORD
      && pConstraint->op==SQLITE_INDEX_CONSTRAINT_MATCH
     ){
-      iPlan |= 1;
+      iPlan |= SPELLFIX_IDXNUM_MATCH;
       pIdxInfo->aConstraintUsage[i].argvIndex = 1;
       pIdxInfo->aConstraintUsage[i].omit = 1;
     }
 
     /* Terms of the form:  langid = $langid  */
-    if( (iPlan & 2)==0
+    if( (iPlan & SPELLFIX_IDXNUM_LANGID)==0
      && pConstraint->iColumn==SPELLFIX_COL_LANGID
      && pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ
     ){
-      iPlan |= 2;
+      iPlan |= SPELLFIX_IDXNUM_LANGID;
       iLangTerm = i;
     }
 
     /* Terms of the form:  top = $top */
-    if( (iPlan & 4)==0
+    if( (iPlan & SPELLFIX_IDXNUM_TOP)==0
      && pConstraint->iColumn==SPELLFIX_COL_TOP
      && pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ
     ){
-      iPlan |= 4;
+      iPlan |= SPELLFIX_IDXNUM_TOP;
       iTopTerm = i;
     }
 
     /* Terms of the form:  scope = $scope */
-    if( (iPlan & 8)==0
+    if( (iPlan & SPELLFIX_IDXNUM_SCOPE)==0
      && pConstraint->iColumn==SPELLFIX_COL_SCOPE
      && pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ
     ){
-      iPlan |= 8;
+      iPlan |= SPELLFIX_IDXNUM_SCOPE;
       iScopeTerm = i;
     }
 
     /* Terms of the form:  distance < $dist or distance <= $dist */
-    if( (iPlan & (16|32))==0
+    if( (iPlan & SPELLFIX_IDXNUM_DIST)==0
      && pConstraint->iColumn==SPELLFIX_COL_DISTANCE
      && (pConstraint->op==SQLITE_INDEX_CONSTRAINT_LT
           || pConstraint->op==SQLITE_INDEX_CONSTRAINT_LE)
     ){
-      iPlan |= pConstraint->op==SQLITE_INDEX_CONSTRAINT_LT ? 16 : 32;
+      if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_LT ){
+        iPlan |= SPELLFIX_IDXNUM_DISTLT;
+      }else{
+        iPlan |= SPELLFIX_IDXNUM_DISTLE;
+      }
       iDistTerm = i;
     }
 
     /* Terms of the form:  distance < $dist or distance <= $dist */
-    if( (iPlan & 64)==0
+    if( (iPlan & SPELLFIX_IDXNUM_ROWID)==0
      && pConstraint->iColumn<0
      && pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ
     ){
-      iPlan |= 64;
+      iPlan |= SPELLFIX_IDXNUM_ROWID;
       iRowidTerm = i;
     }
   }
-  if( iPlan&1 ){
+  if( iPlan&SPELLFIX_IDXNUM_MATCH ){
     int idx = 2;
     pIdxInfo->idxNum = iPlan;
     if( pIdxInfo->nOrderBy==1
@@ -2142,25 +2140,25 @@ static int spellfix1BestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
     ){
       pIdxInfo->orderByConsumed = 1;  /* Default order by iScore */
     }
-    if( iPlan&2 ){
+    if( iPlan&SPELLFIX_IDXNUM_LANGID ){
       pIdxInfo->aConstraintUsage[iLangTerm].argvIndex = idx++;
       pIdxInfo->aConstraintUsage[iLangTerm].omit = 1;
     }
-    if( iPlan&4 ){
+    if( iPlan&SPELLFIX_IDXNUM_TOP ){
       pIdxInfo->aConstraintUsage[iTopTerm].argvIndex = idx++;
       pIdxInfo->aConstraintUsage[iTopTerm].omit = 1;
     }
-    if( iPlan&8 ){
+    if( iPlan&SPELLFIX_IDXNUM_SCOPE ){
       pIdxInfo->aConstraintUsage[iScopeTerm].argvIndex = idx++;
       pIdxInfo->aConstraintUsage[iScopeTerm].omit = 1;
     }
-    if( iPlan&(16|32) ){
+    if( iPlan&SPELLFIX_IDXNUM_DIST ){
       pIdxInfo->aConstraintUsage[iDistTerm].argvIndex = idx++;
       pIdxInfo->aConstraintUsage[iDistTerm].omit = 1;
     }
     pIdxInfo->estimatedCost = 1e5;
-  }else if( (iPlan & 64) ){
-    pIdxInfo->idxNum = 64;
+  }else if( (iPlan & SPELLFIX_IDXNUM_ROWID) ){
+    pIdxInfo->idxNum = SPELLFIX_IDXNUM_ROWID;
     pIdxInfo->aConstraintUsage[iRowidTerm].argvIndex = 1;
     pIdxInfo->aConstraintUsage[iRowidTerm].omit = 1;
     pIdxInfo->estimatedCost = 5;
@@ -2311,15 +2309,24 @@ static void spellfix1RunQuery(MatchQuery *p, const char *zQuery, int nQuery){
       break;
     }
     pCur->nSearch++;
-    iScore = spellfix1Score(iDist,iRank);
+    
+    /* If there is a "distance < $dist" or "distance <= $dist" constraint,
+    ** check if this row meets it. If not, jump back up to the top of the
+    ** loop to process the next row. Otherwise, if the row does match the
+    ** distance constraint, check if the pCur->a[] array is already full.
+    ** If it is and no explicit "top = ?" constraint was present in the
+    ** query, grow the array to ensure there is room for the new entry. */
+    assert( (p->iMaxDist>=0)==((pCur->idxNum & SPELLFIX_IDXNUM_DIST) ? 1 : 0) );
     if( p->iMaxDist>=0 ){
       if( iDist>p->iMaxDist ) continue;
-      if( pCur->nRow>=pCur->nAlloc-1 ){
+      if( pCur->nRow>=pCur->nAlloc && (pCur->idxNum & SPELLFIX_IDXNUM_TOP)==0 ){
         spellfix1ResizeCursor(pCur, pCur->nAlloc*2 + 10);
         if( pCur->a==0 ) break;
       }
-      idx = pCur->nRow;
-    }else if( pCur->nRow<pCur->nAlloc ){
+    }
+
+    iScore = spellfix1Score(iDist,iRank);
+    if( pCur->nRow<pCur->nAlloc ){
       idx = pCur->nRow;
     }else if( iScore<iWorst ){
       idx = idxWorst;
@@ -2327,6 +2334,7 @@ static void spellfix1RunQuery(MatchQuery *p, const char *zQuery, int nQuery){
     }else{
       continue;
     }
+
     pCur->a[idx].zWord = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1));
     if( pCur->a[idx].zWord==0 ){
       p->rc = SQLITE_NOMEM;
@@ -2361,10 +2369,10 @@ static void spellfix1RunQuery(MatchQuery *p, const char *zQuery, int nQuery){
 */
 static int spellfix1FilterForMatch(
   spellfix1_cursor *pCur,
-  int idxNum,
   int argc,
   sqlite3_value **argv
 ){
+  int idxNum = pCur->idxNum;
   const unsigned char *zMatchThis;   /* RHS of the MATCH operator */
   EditDist3FromString *pMatchStr3 = 0; /* zMatchThis as an editdist string */
   char *zPattern;                    /* Transliteration of zMatchThis */
@@ -2476,11 +2484,11 @@ filter_exit:
 */
 static int spellfix1FilterForFullScan(
   spellfix1_cursor *pCur,
-  int idxNum,
   int argc,
   sqlite3_value **argv
 ){
   int rc = SQLITE_OK;
+  int idxNum = pCur->idxNum;
   char *zSql;
   spellfix1_vtab *pVTab = pCur->pVTab;
   spellfix1ResetCursor(pCur);
@@ -2521,10 +2529,11 @@ static int spellfix1Filter(
 ){
   spellfix1_cursor *pCur = (spellfix1_cursor *)cur;
   int rc;
+  pCur->idxNum = idxNum;
   if( idxNum & 1 ){
-    rc = spellfix1FilterForMatch(pCur, idxNum, argc, argv);
+    rc = spellfix1FilterForMatch(pCur, argc, argv);
   }else{
-    rc = spellfix1FilterForFullScan(pCur, idxNum, argc, argv);
+    rc = spellfix1FilterForFullScan(pCur, argc, argv);
   }
   return rc;
 }
index c1a8c650fc8d9f6387c24d03ef9127cef33c4655..12c88e845f2c634fe9e18ac3a90ddd8356c39a3a 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\ssome\sproblems\sin\stest\scode\sdetected\sby\scppcheck.
-D 2015-08-05T08:01:46.351
+C Update\sthe\sspellfix\svirtual\stable\sextension\sso\sthat\san\sexplicit\s"top\s=\s?"\sconstraint\sworks\seven\sif\sthere\sis\salso\sa\s"distance\s<\s?"\sor\s"distance\s<=\s?"\sconstraint.
+D 2015-08-05T15:29:32.743
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 2fc9ca6bf5949d415801c007ed3004a4bdb7c380
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -196,7 +196,7 @@ F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63
 F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc
 F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a
 F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52
-F ext/misc/spellfix.c de9181ec188294dd2a1087b329ca55cfaa76a29d
+F ext/misc/spellfix.c 86998fb73aefb7b5dc346ba8a58912f312da4996
 F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512
 F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95
 F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e
@@ -1369,7 +1369,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 dffd358f6cbf575d3b1045b1ce53429d15bade2a
-R 03d664fe9a880098c608c861d0111d6e
+P c9ff4ca4a0b44bbb8d6676144ddf77b04426e619
+R 180a25ce6d192ff71ad9fad98491dc51
 U dan
-Z d772c3ac7a9d41bdcded0f7d87a12476
+Z 9568c0ed64c13f8590f8982853b1718d
index 827537179d17b23419423657a0c6374f0c749ca8..2a4ecbd67868a78a8c84797165f61dfe40bd1931 100644 (file)
@@ -1 +1 @@
-c9ff4ca4a0b44bbb8d6676144ddf77b04426e619
\ No newline at end of file
+0888838371608558f31d5bcb5fed1c8861aa52c1
\ No newline at end of file