summaryrefslogtreecommitdiffstats
path: root/lib/libsqlite3/ext/misc/spellfix.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libsqlite3/ext/misc/spellfix.c')
-rw-r--r--lib/libsqlite3/ext/misc/spellfix.c99
1 files changed, 54 insertions, 45 deletions
diff --git a/lib/libsqlite3/ext/misc/spellfix.c b/lib/libsqlite3/ext/misc/spellfix.c
index b9514427cf9..336203433ec 100644
--- a/lib/libsqlite3/ext/misc/spellfix.c
+++ b/lib/libsqlite3/ext/misc/spellfix.c
@@ -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;
}