Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(257)

Side by Side Diff: third_party/sqlite/src/ext/misc/spellfix.c

Issue 1610963002: Import SQLite 3.10.2. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/sqlite/src/ext/misc/series.c ('k') | third_party/sqlite/src/ext/rbu/rbu.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 ** 2012 April 10 2 ** 2012 April 10
3 ** 3 **
4 ** The author disclaims copyright to this source code. In place of 4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing: 5 ** a legal notice, here is a blessing:
6 ** 6 **
7 ** May you do good and not evil. 7 ** May you do good and not evil.
8 ** May you find forgiveness for yourself and forgive others. 8 ** May you find forgiveness for yourself and forgive others.
9 ** May you share freely, never taking more than you give. 9 ** May you share freely, never taking more than you give.
10 ** 10 **
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 ** 349 **
350 ** If pnMatch is not NULL, then *pnMatch is set to the number of bytes 350 ** If pnMatch is not NULL, then *pnMatch is set to the number of bytes
351 ** of zB that matched the pattern in zA. If zA does not end with a '*', 351 ** of zB that matched the pattern in zA. If zA does not end with a '*',
352 ** then this value is always the number of bytes in zB (i.e. strlen(zB)). 352 ** then this value is always the number of bytes in zB (i.e. strlen(zB)).
353 ** If zA does end in a '*', then it is the number of bytes in the prefix 353 ** If zA does end in a '*', then it is the number of bytes in the prefix
354 ** of zB that was deemed to match zA. 354 ** of zB that was deemed to match zA.
355 */ 355 */
356 static int editdist1(const char *zA, const char *zB, int *pnMatch){ 356 static int editdist1(const char *zA, const char *zB, int *pnMatch){
357 int nA, nB; /* Number of characters in zA[] and zB[] */ 357 int nA, nB; /* Number of characters in zA[] and zB[] */
358 int xA, xB; /* Loop counters for zA[] and zB[] */ 358 int xA, xB; /* Loop counters for zA[] and zB[] */
359 char cA, cB; /* Current character of zA and zB */ 359 char cA = 0, cB; /* Current character of zA and zB */
360 char cAprev, cBprev; /* Previous character of zA and zB */ 360 char cAprev, cBprev; /* Previous character of zA and zB */
361 char cAnext, cBnext; /* Next character in zA and zB */ 361 char cAnext, cBnext; /* Next character in zA and zB */
362 int d; /* North-west cost value */ 362 int d; /* North-west cost value */
363 int dc = 0; /* North-west character value */ 363 int dc = 0; /* North-west character value */
364 int res; /* Final result */ 364 int res; /* Final result */
365 int *m; /* The cost matrix */ 365 int *m; /* The cost matrix */
366 char *cx; /* Corresponding character values */ 366 char *cx; /* Corresponding character values */
367 int *toFree = 0; /* Malloced space */ 367 int *toFree = 0; /* Malloced space */
368 int mStack[60+15]; /* Stack space to use if not too much is needed */ 368 int mStack[60+15]; /* Stack space to use if not too much is needed */
369 int nMatch = 0; 369 int nMatch = 0;
(...skipping 1340 matching lines...) Expand 10 before | Expand all | Expand 10 after
1710 sqlite3_value **argv 1710 sqlite3_value **argv
1711 ){ 1711 ){
1712 const unsigned char *zIn = sqlite3_value_text(argv[0]); 1712 const unsigned char *zIn = sqlite3_value_text(argv[0]);
1713 int nIn = sqlite3_value_bytes(argv[0]); 1713 int nIn = sqlite3_value_bytes(argv[0]);
1714 int c, sz; 1714 int c, sz;
1715 int scriptMask = 0; 1715 int scriptMask = 0;
1716 int res; 1716 int res;
1717 # define SCRIPT_LATIN 0x0001 1717 # define SCRIPT_LATIN 0x0001
1718 # define SCRIPT_CYRILLIC 0x0002 1718 # define SCRIPT_CYRILLIC 0x0002
1719 # define SCRIPT_GREEK 0x0004 1719 # define SCRIPT_GREEK 0x0004
1720 # define SCRIPT_HEBREW 0x0008
1721 # define SCRIPT_ARABIC 0x0010
1720 1722
1721 while( nIn>0 ){ 1723 while( nIn>0 ){
1722 c = utf8Read(zIn, nIn, &sz); 1724 c = utf8Read(zIn, nIn, &sz);
1723 zIn += sz; 1725 zIn += sz;
1724 nIn -= sz; 1726 nIn -= sz;
1725 if( c<0x02af ){ 1727 if( c<0x02af && (c>=0x80 || midClass[c&0x7f]<CCLASS_DIGIT) ){
1726 scriptMask |= SCRIPT_LATIN; 1728 scriptMask |= SCRIPT_LATIN;
1727 }else if( c>=0x0400 && c<=0x04ff ){ 1729 }else if( c>=0x0400 && c<=0x04ff ){
1728 scriptMask |= SCRIPT_CYRILLIC; 1730 scriptMask |= SCRIPT_CYRILLIC;
1729 }else if( c>=0x0386 && c<=0x03ce ){ 1731 }else if( c>=0x0386 && c<=0x03ce ){
1730 scriptMask |= SCRIPT_GREEK; 1732 scriptMask |= SCRIPT_GREEK;
1733 }else if( c>=0x0590 && c<=0x05ff ){
1734 scriptMask |= SCRIPT_HEBREW;
1735 }else if( c>=0x0600 && c<=0x06ff ){
1736 scriptMask |= SCRIPT_ARABIC;
1731 } 1737 }
1732 } 1738 }
1733 switch( scriptMask ){ 1739 switch( scriptMask ){
1734 case 0: res = 999; break; 1740 case 0: res = 999; break;
1735 case SCRIPT_LATIN: res = 215; break; 1741 case SCRIPT_LATIN: res = 215; break;
1736 case SCRIPT_CYRILLIC: res = 220; break; 1742 case SCRIPT_CYRILLIC: res = 220; break;
1737 case SCRIPT_GREEK: res = 200; break; 1743 case SCRIPT_GREEK: res = 200; break;
1744 case SCRIPT_HEBREW: res = 125; break;
1745 case SCRIPT_ARABIC: res = 160; break;
1738 default: res = 998; break; 1746 default: res = 998; break;
1739 } 1747 }
1740 sqlite3_result_int(context, res); 1748 sqlite3_result_int(context, res);
1741 } 1749 }
1742 1750
1743 /* End transliterate 1751 /* End transliterate
1744 ****************************************************************************** 1752 ******************************************************************************
1745 ****************************************************************************** 1753 ******************************************************************************
1746 ** Begin spellfix1 virtual table. 1754 ** Begin spellfix1 virtual table.
1747 */ 1755 */
(...skipping 15 matching lines...) Expand all
1763 char *zTableName; /* Name of the virtual table */ 1771 char *zTableName; /* Name of the virtual table */
1764 char *zCostTable; /* Table holding edit-distance cost numbers */ 1772 char *zCostTable; /* Table holding edit-distance cost numbers */
1765 EditDist3Config *pConfig3; /* Parsed edit distance costs */ 1773 EditDist3Config *pConfig3; /* Parsed edit distance costs */
1766 }; 1774 };
1767 1775
1768 /* Fuzzy-search cursor object */ 1776 /* Fuzzy-search cursor object */
1769 struct spellfix1_cursor { 1777 struct spellfix1_cursor {
1770 sqlite3_vtab_cursor base; /* Base class - must be first */ 1778 sqlite3_vtab_cursor base; /* Base class - must be first */
1771 spellfix1_vtab *pVTab; /* The table to which this cursor belongs */ 1779 spellfix1_vtab *pVTab; /* The table to which this cursor belongs */
1772 char *zPattern; /* rhs of MATCH clause */ 1780 char *zPattern; /* rhs of MATCH clause */
1781 int idxNum; /* idxNum value passed to xFilter() */
1773 int nRow; /* Number of rows of content */ 1782 int nRow; /* Number of rows of content */
1774 int nAlloc; /* Number of allocated rows */ 1783 int nAlloc; /* Number of allocated rows */
1775 int iRow; /* Current row of content */ 1784 int iRow; /* Current row of content */
1776 int iLang; /* Value of the langid= constraint */ 1785 int iLang; /* Value of the langid= constraint */
1777 int iTop; /* Value of the top= constraint */ 1786 int iTop; /* Value of the top= constraint */
1778 int iScope; /* Value of the scope= constraint */ 1787 int iScope; /* Value of the scope= constraint */
1779 int nSearch; /* Number of vocabulary items checked */ 1788 int nSearch; /* Number of vocabulary items checked */
1780 sqlite3_stmt *pFullScan; /* Shadow query for a full table scan */ 1789 sqlite3_stmt *pFullScan; /* Shadow query for a full table scan */
1781 struct spellfix1_row { /* For each row of content */ 1790 struct spellfix1_row { /* For each row of content */
1782 sqlite3_int64 iRowid; /* Rowid for this row */ 1791 sqlite3_int64 iRowid; /* Rowid for this row */
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1843 } 1852 }
1844 1853
1845 /* 1854 /*
1846 ** Make a copy of a string. Remove leading and trailing whitespace 1855 ** Make a copy of a string. Remove leading and trailing whitespace
1847 ** and dequote it. 1856 ** and dequote it.
1848 */ 1857 */
1849 static char *spellfix1Dequote(const char *zIn){ 1858 static char *spellfix1Dequote(const char *zIn){
1850 char *zOut; 1859 char *zOut;
1851 int i, j; 1860 int i, j;
1852 char c; 1861 char c;
1853 while( isspace(zIn[0]) ) zIn++; 1862 while( isspace((unsigned char)zIn[0]) ) zIn++;
1854 zOut = sqlite3_mprintf("%s", zIn); 1863 zOut = sqlite3_mprintf("%s", zIn);
1855 if( zOut==0 ) return 0; 1864 if( zOut==0 ) return 0;
1856 i = (int)strlen(zOut); 1865 i = (int)strlen(zOut);
1857 #if 0 /* The parser will never leave spaces at the end */ 1866 #if 0 /* The parser will never leave spaces at the end */
1858 while( i>0 && isspace(zOut[i-1]) ){ i--; } 1867 while( i>0 && isspace(zOut[i-1]) ){ i--; }
1859 #endif 1868 #endif
1860 zOut[i] = 0; 1869 zOut[i] = 0;
1861 c = zOut[0]; 1870 c = zOut[0];
1862 if( c=='\'' || c=='"' ){ 1871 if( c=='\'' || c=='"' ){
1863 for(i=1, j=0; ALWAYS(zOut[i]); i++){ 1872 for(i=1, j=0; ALWAYS(zOut[i]); i++){
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
2033 */ 2042 */
2034 static int spellfix1Close(sqlite3_vtab_cursor *cur){ 2043 static int spellfix1Close(sqlite3_vtab_cursor *cur){
2035 spellfix1_cursor *pCur = (spellfix1_cursor *)cur; 2044 spellfix1_cursor *pCur = (spellfix1_cursor *)cur;
2036 spellfix1ResetCursor(pCur); 2045 spellfix1ResetCursor(pCur);
2037 spellfix1ResizeCursor(pCur, 0); 2046 spellfix1ResizeCursor(pCur, 0);
2038 sqlite3_free(pCur->zPattern); 2047 sqlite3_free(pCur->zPattern);
2039 sqlite3_free(pCur); 2048 sqlite3_free(pCur);
2040 return SQLITE_OK; 2049 return SQLITE_OK;
2041 } 2050 }
2042 2051
2052 #define SPELLFIX_IDXNUM_MATCH 0x01 /* word MATCH $str */
2053 #define SPELLFIX_IDXNUM_LANGID 0x02 /* langid == $langid */
2054 #define SPELLFIX_IDXNUM_TOP 0x04 /* top = $top */
2055 #define SPELLFIX_IDXNUM_SCOPE 0x08 /* scope = $scope */
2056 #define SPELLFIX_IDXNUM_DISTLT 0x10 /* distance < $distance */
2057 #define SPELLFIX_IDXNUM_DISTLE 0x20 /* distance <= $distance */
2058 #define SPELLFIX_IDXNUM_ROWID 0x40 /* rowid = $rowid */
2059 #define SPELLFIX_IDXNUM_DIST (0x10|0x20) /* DISTLT and DISTLE */
2060
2043 /* 2061 /*
2044 ** Search for terms of these forms:
2045 ** 2062 **
2046 ** (A) word MATCH $str 2063 ** The plan number is a bitmask of the SPELLFIX_IDXNUM_* values defined
2047 ** (B) langid == $langid 2064 ** above.
2048 ** (C) top = $top
2049 ** (D) scope = $scope
2050 ** (E) distance < $distance
2051 ** (F) distance <= $distance
2052 ** (G) rowid = $rowid
2053 **
2054 ** The plan number is a bit mask formed with these bits:
2055 **
2056 ** 0x01 (A) is found
2057 ** 0x02 (B) is found
2058 ** 0x04 (C) is found
2059 ** 0x08 (D) is found
2060 ** 0x10 (E) is found
2061 ** 0x20 (F) is found
2062 ** 0x40 (G) is found
2063 ** 2065 **
2064 ** filter.argv[*] values contains $str, $langid, $top, $scope and $rowid 2066 ** filter.argv[*] values contains $str, $langid, $top, $scope and $rowid
2065 ** if specified and in that order. 2067 ** if specified and in that order.
2066 */ 2068 */
2067 static int spellfix1BestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ 2069 static int spellfix1BestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
2068 int iPlan = 0; 2070 int iPlan = 0;
2069 int iLangTerm = -1; 2071 int iLangTerm = -1;
2070 int iTopTerm = -1; 2072 int iTopTerm = -1;
2071 int iScopeTerm = -1; 2073 int iScopeTerm = -1;
2072 int iDistTerm = -1; 2074 int iDistTerm = -1;
2073 int iRowidTerm = -1; 2075 int iRowidTerm = -1;
2074 int i; 2076 int i;
2075 const struct sqlite3_index_constraint *pConstraint; 2077 const struct sqlite3_index_constraint *pConstraint;
2076 pConstraint = pIdxInfo->aConstraint; 2078 pConstraint = pIdxInfo->aConstraint;
2077 for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){ 2079 for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
2078 if( pConstraint->usable==0 ) continue; 2080 if( pConstraint->usable==0 ) continue;
2079 2081
2080 /* Terms of the form: word MATCH $str */ 2082 /* Terms of the form: word MATCH $str */
2081 if( (iPlan & 1)==0 2083 if( (iPlan & SPELLFIX_IDXNUM_MATCH)==0
2082 && pConstraint->iColumn==SPELLFIX_COL_WORD 2084 && pConstraint->iColumn==SPELLFIX_COL_WORD
2083 && pConstraint->op==SQLITE_INDEX_CONSTRAINT_MATCH 2085 && pConstraint->op==SQLITE_INDEX_CONSTRAINT_MATCH
2084 ){ 2086 ){
2085 iPlan |= 1; 2087 iPlan |= SPELLFIX_IDXNUM_MATCH;
2086 pIdxInfo->aConstraintUsage[i].argvIndex = 1; 2088 pIdxInfo->aConstraintUsage[i].argvIndex = 1;
2087 pIdxInfo->aConstraintUsage[i].omit = 1; 2089 pIdxInfo->aConstraintUsage[i].omit = 1;
2088 } 2090 }
2089 2091
2090 /* Terms of the form: langid = $langid */ 2092 /* Terms of the form: langid = $langid */
2091 if( (iPlan & 2)==0 2093 if( (iPlan & SPELLFIX_IDXNUM_LANGID)==0
2092 && pConstraint->iColumn==SPELLFIX_COL_LANGID 2094 && pConstraint->iColumn==SPELLFIX_COL_LANGID
2093 && pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ 2095 && pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ
2094 ){ 2096 ){
2095 iPlan |= 2; 2097 iPlan |= SPELLFIX_IDXNUM_LANGID;
2096 iLangTerm = i; 2098 iLangTerm = i;
2097 } 2099 }
2098 2100
2099 /* Terms of the form: top = $top */ 2101 /* Terms of the form: top = $top */
2100 if( (iPlan & 4)==0 2102 if( (iPlan & SPELLFIX_IDXNUM_TOP)==0
2101 && pConstraint->iColumn==SPELLFIX_COL_TOP 2103 && pConstraint->iColumn==SPELLFIX_COL_TOP
2102 && pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ 2104 && pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ
2103 ){ 2105 ){
2104 iPlan |= 4; 2106 iPlan |= SPELLFIX_IDXNUM_TOP;
2105 iTopTerm = i; 2107 iTopTerm = i;
2106 } 2108 }
2107 2109
2108 /* Terms of the form: scope = $scope */ 2110 /* Terms of the form: scope = $scope */
2109 if( (iPlan & 8)==0 2111 if( (iPlan & SPELLFIX_IDXNUM_SCOPE)==0
2110 && pConstraint->iColumn==SPELLFIX_COL_SCOPE 2112 && pConstraint->iColumn==SPELLFIX_COL_SCOPE
2111 && pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ 2113 && pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ
2112 ){ 2114 ){
2113 iPlan |= 8; 2115 iPlan |= SPELLFIX_IDXNUM_SCOPE;
2114 iScopeTerm = i; 2116 iScopeTerm = i;
2115 } 2117 }
2116 2118
2117 /* Terms of the form: distance < $dist or distance <= $dist */ 2119 /* Terms of the form: distance < $dist or distance <= $dist */
2118 if( (iPlan & (16|32))==0 2120 if( (iPlan & SPELLFIX_IDXNUM_DIST)==0
2119 && pConstraint->iColumn==SPELLFIX_COL_DISTANCE 2121 && pConstraint->iColumn==SPELLFIX_COL_DISTANCE
2120 && (pConstraint->op==SQLITE_INDEX_CONSTRAINT_LT 2122 && (pConstraint->op==SQLITE_INDEX_CONSTRAINT_LT
2121 || pConstraint->op==SQLITE_INDEX_CONSTRAINT_LE) 2123 || pConstraint->op==SQLITE_INDEX_CONSTRAINT_LE)
2122 ){ 2124 ){
2123 iPlan |= pConstraint->op==SQLITE_INDEX_CONSTRAINT_LT ? 16 : 32; 2125 if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_LT ){
2126 iPlan |= SPELLFIX_IDXNUM_DISTLT;
2127 }else{
2128 iPlan |= SPELLFIX_IDXNUM_DISTLE;
2129 }
2124 iDistTerm = i; 2130 iDistTerm = i;
2125 } 2131 }
2126 2132
2127 /* Terms of the form: distance < $dist or distance <= $dist */ 2133 /* Terms of the form: distance < $dist or distance <= $dist */
2128 if( (iPlan & 64)==0 2134 if( (iPlan & SPELLFIX_IDXNUM_ROWID)==0
2129 && pConstraint->iColumn<0 2135 && pConstraint->iColumn<0
2130 && pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ 2136 && pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ
2131 ){ 2137 ){
2132 iPlan |= 64; 2138 iPlan |= SPELLFIX_IDXNUM_ROWID;
2133 iRowidTerm = i; 2139 iRowidTerm = i;
2134 } 2140 }
2135 } 2141 }
2136 if( iPlan&1 ){ 2142 if( iPlan&SPELLFIX_IDXNUM_MATCH ){
2137 int idx = 2; 2143 int idx = 2;
2138 pIdxInfo->idxNum = iPlan; 2144 pIdxInfo->idxNum = iPlan;
2139 if( pIdxInfo->nOrderBy==1 2145 if( pIdxInfo->nOrderBy==1
2140 && pIdxInfo->aOrderBy[0].iColumn==SPELLFIX_COL_SCORE 2146 && pIdxInfo->aOrderBy[0].iColumn==SPELLFIX_COL_SCORE
2141 && pIdxInfo->aOrderBy[0].desc==0 2147 && pIdxInfo->aOrderBy[0].desc==0
2142 ){ 2148 ){
2143 pIdxInfo->orderByConsumed = 1; /* Default order by iScore */ 2149 pIdxInfo->orderByConsumed = 1; /* Default order by iScore */
2144 } 2150 }
2145 if( iPlan&2 ){ 2151 if( iPlan&SPELLFIX_IDXNUM_LANGID ){
2146 pIdxInfo->aConstraintUsage[iLangTerm].argvIndex = idx++; 2152 pIdxInfo->aConstraintUsage[iLangTerm].argvIndex = idx++;
2147 pIdxInfo->aConstraintUsage[iLangTerm].omit = 1; 2153 pIdxInfo->aConstraintUsage[iLangTerm].omit = 1;
2148 } 2154 }
2149 if( iPlan&4 ){ 2155 if( iPlan&SPELLFIX_IDXNUM_TOP ){
2150 pIdxInfo->aConstraintUsage[iTopTerm].argvIndex = idx++; 2156 pIdxInfo->aConstraintUsage[iTopTerm].argvIndex = idx++;
2151 pIdxInfo->aConstraintUsage[iTopTerm].omit = 1; 2157 pIdxInfo->aConstraintUsage[iTopTerm].omit = 1;
2152 } 2158 }
2153 if( iPlan&8 ){ 2159 if( iPlan&SPELLFIX_IDXNUM_SCOPE ){
2154 pIdxInfo->aConstraintUsage[iScopeTerm].argvIndex = idx++; 2160 pIdxInfo->aConstraintUsage[iScopeTerm].argvIndex = idx++;
2155 pIdxInfo->aConstraintUsage[iScopeTerm].omit = 1; 2161 pIdxInfo->aConstraintUsage[iScopeTerm].omit = 1;
2156 } 2162 }
2157 if( iPlan&(16|32) ){ 2163 if( iPlan&SPELLFIX_IDXNUM_DIST ){
2158 pIdxInfo->aConstraintUsage[iDistTerm].argvIndex = idx++; 2164 pIdxInfo->aConstraintUsage[iDistTerm].argvIndex = idx++;
2159 pIdxInfo->aConstraintUsage[iDistTerm].omit = 1; 2165 pIdxInfo->aConstraintUsage[iDistTerm].omit = 1;
2160 } 2166 }
2161 pIdxInfo->estimatedCost = 1e5; 2167 pIdxInfo->estimatedCost = 1e5;
2162 }else if( (iPlan & 64) ){ 2168 }else if( (iPlan & SPELLFIX_IDXNUM_ROWID) ){
2163 pIdxInfo->idxNum = 64; 2169 pIdxInfo->idxNum = SPELLFIX_IDXNUM_ROWID;
2164 pIdxInfo->aConstraintUsage[iRowidTerm].argvIndex = 1; 2170 pIdxInfo->aConstraintUsage[iRowidTerm].argvIndex = 1;
2165 pIdxInfo->aConstraintUsage[iRowidTerm].omit = 1; 2171 pIdxInfo->aConstraintUsage[iRowidTerm].omit = 1;
2166 pIdxInfo->estimatedCost = 5; 2172 pIdxInfo->estimatedCost = 5;
2167 }else{ 2173 }else{
2168 pIdxInfo->idxNum = 0; 2174 pIdxInfo->idxNum = 0;
2169 pIdxInfo->estimatedCost = 1e50; 2175 pIdxInfo->estimatedCost = 1e50;
2170 } 2176 }
2171 return SQLITE_OK; 2177 return SQLITE_OK;
2172 } 2178 }
2173 2179
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
2304 }else{ 2310 }else{
2305 zK1 = (const char*)sqlite3_column_text(pStmt, 3); 2311 zK1 = (const char*)sqlite3_column_text(pStmt, 3);
2306 if( zK1==0 ) continue; 2312 if( zK1==0 ) continue;
2307 iDist = editdist1(p->zPattern, zK1, 0); 2313 iDist = editdist1(p->zPattern, zK1, 0);
2308 } 2314 }
2309 if( iDist<0 ){ 2315 if( iDist<0 ){
2310 p->rc = SQLITE_NOMEM; 2316 p->rc = SQLITE_NOMEM;
2311 break; 2317 break;
2312 } 2318 }
2313 pCur->nSearch++; 2319 pCur->nSearch++;
2314 iScore = spellfix1Score(iDist,iRank); 2320
2321 /* If there is a "distance < $dist" or "distance <= $dist" constraint,
2322 ** check if this row meets it. If not, jump back up to the top of the
2323 ** loop to process the next row. Otherwise, if the row does match the
2324 ** distance constraint, check if the pCur->a[] array is already full.
2325 ** If it is and no explicit "top = ?" constraint was present in the
2326 ** query, grow the array to ensure there is room for the new entry. */
2327 assert( (p->iMaxDist>=0)==((pCur->idxNum & SPELLFIX_IDXNUM_DIST) ? 1 : 0) );
2315 if( p->iMaxDist>=0 ){ 2328 if( p->iMaxDist>=0 ){
2316 if( iDist>p->iMaxDist ) continue; 2329 if( iDist>p->iMaxDist ) continue;
2317 if( pCur->nRow>=pCur->nAlloc-1 ){ 2330 if( pCur->nRow>=pCur->nAlloc && (pCur->idxNum & SPELLFIX_IDXNUM_TOP)==0 ){
2318 spellfix1ResizeCursor(pCur, pCur->nAlloc*2 + 10); 2331 spellfix1ResizeCursor(pCur, pCur->nAlloc*2 + 10);
2319 if( pCur->a==0 ) break; 2332 if( pCur->a==0 ) break;
2320 } 2333 }
2321 idx = pCur->nRow; 2334 }
2322 }else if( pCur->nRow<pCur->nAlloc ){ 2335
2336 iScore = spellfix1Score(iDist,iRank);
2337 if( pCur->nRow<pCur->nAlloc ){
2323 idx = pCur->nRow; 2338 idx = pCur->nRow;
2324 }else if( iScore<iWorst ){ 2339 }else if( iScore<iWorst ){
2325 idx = idxWorst; 2340 idx = idxWorst;
2326 sqlite3_free(pCur->a[idx].zWord); 2341 sqlite3_free(pCur->a[idx].zWord);
2327 }else{ 2342 }else{
2328 continue; 2343 continue;
2329 } 2344 }
2345
2330 pCur->a[idx].zWord = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1)); 2346 pCur->a[idx].zWord = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1));
2331 if( pCur->a[idx].zWord==0 ){ 2347 if( pCur->a[idx].zWord==0 ){
2332 p->rc = SQLITE_NOMEM; 2348 p->rc = SQLITE_NOMEM;
2333 break; 2349 break;
2334 } 2350 }
2335 pCur->a[idx].iRowid = sqlite3_column_int64(pStmt, 0); 2351 pCur->a[idx].iRowid = sqlite3_column_int64(pStmt, 0);
2336 pCur->a[idx].iRank = iRank; 2352 pCur->a[idx].iRank = iRank;
2337 pCur->a[idx].iDistance = iDist; 2353 pCur->a[idx].iDistance = iDist;
2338 pCur->a[idx].iScore = iScore; 2354 pCur->a[idx].iScore = iScore;
2339 pCur->a[idx].iMatchlen = iMatchlen; 2355 pCur->a[idx].iMatchlen = iMatchlen;
(...skipping 14 matching lines...) Expand all
2354 rc = sqlite3_reset(pStmt); 2370 rc = sqlite3_reset(pStmt);
2355 if( rc ) p->rc = rc; 2371 if( rc ) p->rc = rc;
2356 } 2372 }
2357 2373
2358 /* 2374 /*
2359 ** This version of the xFilter method work if the MATCH term is present 2375 ** This version of the xFilter method work if the MATCH term is present
2360 ** and we are doing a scan. 2376 ** and we are doing a scan.
2361 */ 2377 */
2362 static int spellfix1FilterForMatch( 2378 static int spellfix1FilterForMatch(
2363 spellfix1_cursor *pCur, 2379 spellfix1_cursor *pCur,
2364 int idxNum,
2365 int argc, 2380 int argc,
2366 sqlite3_value **argv 2381 sqlite3_value **argv
2367 ){ 2382 ){
2383 int idxNum = pCur->idxNum;
2368 const unsigned char *zMatchThis; /* RHS of the MATCH operator */ 2384 const unsigned char *zMatchThis; /* RHS of the MATCH operator */
2369 EditDist3FromString *pMatchStr3 = 0; /* zMatchThis as an editdist string */ 2385 EditDist3FromString *pMatchStr3 = 0; /* zMatchThis as an editdist string */
2370 char *zPattern; /* Transliteration of zMatchThis */ 2386 char *zPattern; /* Transliteration of zMatchThis */
2371 int nPattern; /* Length of zPattern */ 2387 int nPattern; /* Length of zPattern */
2372 int iLimit = 20; /* Max number of rows of output */ 2388 int iLimit = 20; /* Max number of rows of output */
2373 int iScope = 3; /* Use this many characters of zClass */ 2389 int iScope = 3; /* Use this many characters of zClass */
2374 int iLang = 0; /* Language code */ 2390 int iLang = 0; /* Language code */
2375 char *zSql; /* SQL of shadow table query */ 2391 char *zSql; /* SQL of shadow table query */
2376 sqlite3_stmt *pStmt = 0; /* Shadow table query */ 2392 sqlite3_stmt *pStmt = 0; /* Shadow table query */
2377 int rc; /* Result code */ 2393 int rc; /* Result code */
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
2469 sqlite3_finalize(pStmt); 2485 sqlite3_finalize(pStmt);
2470 editDist3FromStringDelete(pMatchStr3); 2486 editDist3FromStringDelete(pMatchStr3);
2471 return x.rc; 2487 return x.rc;
2472 } 2488 }
2473 2489
2474 /* 2490 /*
2475 ** This version of xFilter handles a full-table scan case 2491 ** This version of xFilter handles a full-table scan case
2476 */ 2492 */
2477 static int spellfix1FilterForFullScan( 2493 static int spellfix1FilterForFullScan(
2478 spellfix1_cursor *pCur, 2494 spellfix1_cursor *pCur,
2479 int idxNum,
2480 int argc, 2495 int argc,
2481 sqlite3_value **argv 2496 sqlite3_value **argv
2482 ){ 2497 ){
2483 int rc = SQLITE_OK; 2498 int rc = SQLITE_OK;
2499 int idxNum = pCur->idxNum;
2484 char *zSql; 2500 char *zSql;
2485 spellfix1_vtab *pVTab = pCur->pVTab; 2501 spellfix1_vtab *pVTab = pCur->pVTab;
2486 spellfix1ResetCursor(pCur); 2502 spellfix1ResetCursor(pCur);
2487 assert( idxNum==0 || idxNum==64 ); 2503 assert( idxNum==0 || idxNum==64 );
2488 zSql = sqlite3_mprintf( 2504 zSql = sqlite3_mprintf(
2489 "SELECT word, rank, NULL, langid, id FROM \"%w\".\"%w_vocab\"%s", 2505 "SELECT word, rank, NULL, langid, id FROM \"%w\".\"%w_vocab\"%s",
2490 pVTab->zDbName, pVTab->zTableName, 2506 pVTab->zDbName, pVTab->zTableName,
2491 ((idxNum & 64) ? " WHERE rowid=?" : "") 2507 ((idxNum & 64) ? " WHERE rowid=?" : "")
2492 ); 2508 );
2493 if( zSql==0 ) return SQLITE_NOMEM; 2509 if( zSql==0 ) return SQLITE_NOMEM;
(...skipping 20 matching lines...) Expand all
2514 ** it starts its output over again. Always called at least once 2530 ** it starts its output over again. Always called at least once
2515 ** prior to any spellfix1Column, spellfix1Rowid, or spellfix1Eof call. 2531 ** prior to any spellfix1Column, spellfix1Rowid, or spellfix1Eof call.
2516 */ 2532 */
2517 static int spellfix1Filter( 2533 static int spellfix1Filter(
2518 sqlite3_vtab_cursor *cur, 2534 sqlite3_vtab_cursor *cur,
2519 int idxNum, const char *idxStr, 2535 int idxNum, const char *idxStr,
2520 int argc, sqlite3_value **argv 2536 int argc, sqlite3_value **argv
2521 ){ 2537 ){
2522 spellfix1_cursor *pCur = (spellfix1_cursor *)cur; 2538 spellfix1_cursor *pCur = (spellfix1_cursor *)cur;
2523 int rc; 2539 int rc;
2540 pCur->idxNum = idxNum;
2524 if( idxNum & 1 ){ 2541 if( idxNum & 1 ){
2525 rc = spellfix1FilterForMatch(pCur, idxNum, argc, argv); 2542 rc = spellfix1FilterForMatch(pCur, argc, argv);
2526 }else{ 2543 }else{
2527 rc = spellfix1FilterForFullScan(pCur, idxNum, argc, argv); 2544 rc = spellfix1FilterForFullScan(pCur, argc, argv);
2528 } 2545 }
2529 return rc; 2546 return rc;
2530 } 2547 }
2531 2548
2532 2549
2533 /* 2550 /*
2534 ** Advance a cursor to its next row of output 2551 ** Advance a cursor to its next row of output
2535 */ 2552 */
2536 static int spellfix1Next(sqlite3_vtab_cursor *cur){ 2553 static int spellfix1Next(sqlite3_vtab_cursor *cur){
2537 spellfix1_cursor *pCur = (spellfix1_cursor *)cur; 2554 spellfix1_cursor *pCur = (spellfix1_cursor *)cur;
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
2649 spellfix1_cursor *pCur = (spellfix1_cursor*)cur; 2666 spellfix1_cursor *pCur = (spellfix1_cursor*)cur;
2650 if( pCur->pFullScan ){ 2667 if( pCur->pFullScan ){
2651 *pRowid = sqlite3_column_int64(pCur->pFullScan, 4); 2668 *pRowid = sqlite3_column_int64(pCur->pFullScan, 4);
2652 }else{ 2669 }else{
2653 *pRowid = pCur->a[pCur->iRow].iRowid; 2670 *pRowid = pCur->a[pCur->iRow].iRowid;
2654 } 2671 }
2655 return SQLITE_OK; 2672 return SQLITE_OK;
2656 } 2673 }
2657 2674
2658 /* 2675 /*
2676 ** This function is called by the xUpdate() method. It returns a string
2677 ** containing the conflict mode that xUpdate() should use for the current
2678 ** operation. One of: "ROLLBACK", "IGNORE", "ABORT" or "REPLACE".
2679 */
2680 static const char *spellfix1GetConflict(sqlite3 *db){
2681 static const char *azConflict[] = {
2682 /* Note: Instead of "FAIL" - "ABORT". */
2683 "ROLLBACK", "IGNORE", "ABORT", "ABORT", "REPLACE"
2684 };
2685 int eConflict = sqlite3_vtab_on_conflict(db);
2686
2687 assert( eConflict==SQLITE_ROLLBACK || eConflict==SQLITE_IGNORE
2688 || eConflict==SQLITE_FAIL || eConflict==SQLITE_ABORT
2689 || eConflict==SQLITE_REPLACE
2690 );
2691 assert( SQLITE_ROLLBACK==1 );
2692 assert( SQLITE_IGNORE==2 );
2693 assert( SQLITE_FAIL==3 );
2694 assert( SQLITE_ABORT==4 );
2695 assert( SQLITE_REPLACE==5 );
2696
2697 return azConflict[eConflict-1];
2698 }
2699
2700 /*
2659 ** The xUpdate() method. 2701 ** The xUpdate() method.
2660 */ 2702 */
2661 static int spellfix1Update( 2703 static int spellfix1Update(
2662 sqlite3_vtab *pVTab, 2704 sqlite3_vtab *pVTab,
2663 int argc, 2705 int argc,
2664 sqlite3_value **argv, 2706 sqlite3_value **argv,
2665 sqlite_int64 *pRowid 2707 sqlite_int64 *pRowid
2666 ){ 2708 ){
2667 int rc = SQLITE_OK; 2709 int rc = SQLITE_OK;
2668 sqlite3_int64 rowid, newRowid; 2710 sqlite3_int64 rowid, newRowid;
(...skipping 10 matching lines...) Expand all
2679 const unsigned char *zWord = sqlite3_value_text(argv[SPELLFIX_COL_WORD+2]); 2721 const unsigned char *zWord = sqlite3_value_text(argv[SPELLFIX_COL_WORD+2]);
2680 int nWord = sqlite3_value_bytes(argv[SPELLFIX_COL_WORD+2]); 2722 int nWord = sqlite3_value_bytes(argv[SPELLFIX_COL_WORD+2]);
2681 int iLang = sqlite3_value_int(argv[SPELLFIX_COL_LANGID+2]); 2723 int iLang = sqlite3_value_int(argv[SPELLFIX_COL_LANGID+2]);
2682 int iRank = sqlite3_value_int(argv[SPELLFIX_COL_RANK+2]); 2724 int iRank = sqlite3_value_int(argv[SPELLFIX_COL_RANK+2]);
2683 const unsigned char *zSoundslike = 2725 const unsigned char *zSoundslike =
2684 sqlite3_value_text(argv[SPELLFIX_COL_SOUNDSLIKE+2]); 2726 sqlite3_value_text(argv[SPELLFIX_COL_SOUNDSLIKE+2]);
2685 int nSoundslike = sqlite3_value_bytes(argv[SPELLFIX_COL_SOUNDSLIKE+2]); 2727 int nSoundslike = sqlite3_value_bytes(argv[SPELLFIX_COL_SOUNDSLIKE+2]);
2686 char *zK1, *zK2; 2728 char *zK1, *zK2;
2687 int i; 2729 int i;
2688 char c; 2730 char c;
2731 const char *zConflict = spellfix1GetConflict(db);
2689 2732
2690 if( zWord==0 ){ 2733 if( zWord==0 ){
2691 /* Inserts of the form: INSERT INTO table(command) VALUES('xyzzy'); 2734 /* Inserts of the form: INSERT INTO table(command) VALUES('xyzzy');
2692 ** cause zWord to be NULL, so we look at the "command" column to see 2735 ** cause zWord to be NULL, so we look at the "command" column to see
2693 ** what special actions to take */ 2736 ** what special actions to take */
2694 const char *zCmd = 2737 const char *zCmd =
2695 (const char*)sqlite3_value_text(argv[SPELLFIX_COL_COMMAND+2]); 2738 (const char*)sqlite3_value_text(argv[SPELLFIX_COL_COMMAND+2]);
2696 if( zCmd==0 ){ 2739 if( zCmd==0 ){
2697 pVTab->zErrMsg = sqlite3_mprintf("NOT NULL constraint failed: %s.word", 2740 pVTab->zErrMsg = sqlite3_mprintf("NOT NULL constraint failed: %s.word",
2698 p->zTableName); 2741 p->zTableName);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2739 if( sqlite3_value_type(argv[1])==SQLITE_NULL ){ 2782 if( sqlite3_value_type(argv[1])==SQLITE_NULL ){
2740 spellfix1DbExec(&rc, db, 2783 spellfix1DbExec(&rc, db,
2741 "INSERT INTO \"%w\".\"%w_vocab\"(rank,langid,word,k1,k2) " 2784 "INSERT INTO \"%w\".\"%w_vocab\"(rank,langid,word,k1,k2) "
2742 "VALUES(%d,%d,%Q,%Q,%Q)", 2785 "VALUES(%d,%d,%Q,%Q,%Q)",
2743 p->zDbName, p->zTableName, 2786 p->zDbName, p->zTableName,
2744 iRank, iLang, zWord, zK1, zK2 2787 iRank, iLang, zWord, zK1, zK2
2745 ); 2788 );
2746 }else{ 2789 }else{
2747 newRowid = sqlite3_value_int64(argv[1]); 2790 newRowid = sqlite3_value_int64(argv[1]);
2748 spellfix1DbExec(&rc, db, 2791 spellfix1DbExec(&rc, db,
2749 "INSERT INTO \"%w\".\"%w_vocab\"(id,rank,langid,word,k1,k2) " 2792 "INSERT OR %s INTO \"%w\".\"%w_vocab\"(id,rank,langid,word,k1,k2) "
2750 "VALUES(%lld,%d,%d,%Q,%Q,%Q)", 2793 "VALUES(%lld,%d,%d,%Q,%Q,%Q)",
2751 p->zDbName, p->zTableName, 2794 zConflict, p->zDbName, p->zTableName,
2752 newRowid, iRank, iLang, zWord, zK1, zK2 2795 newRowid, iRank, iLang, zWord, zK1, zK2
2753 ); 2796 );
2754 } 2797 }
2755 *pRowid = sqlite3_last_insert_rowid(db); 2798 *pRowid = sqlite3_last_insert_rowid(db);
2756 }else{ 2799 }else{
2757 rowid = sqlite3_value_int64(argv[0]); 2800 rowid = sqlite3_value_int64(argv[0]);
2758 newRowid = *pRowid = sqlite3_value_int64(argv[1]); 2801 newRowid = *pRowid = sqlite3_value_int64(argv[1]);
2759 spellfix1DbExec(&rc, db, 2802 spellfix1DbExec(&rc, db,
2760 "UPDATE \"%w\".\"%w_vocab\" SET id=%lld, rank=%d, langid=%d," 2803 "UPDATE OR %s \"%w\".\"%w_vocab\" SET id=%lld, rank=%d, langid=%d,"
2761 " word=%Q, k1=%Q, k2=%Q WHERE id=%lld", 2804 " word=%Q, k1=%Q, k2=%Q WHERE id=%lld",
2762 p->zDbName, p->zTableName, newRowid, iRank, iLang, 2805 zConflict, p->zDbName, p->zTableName, newRowid, iRank, iLang,
2763 zWord, zK1, zK2, rowid 2806 zWord, zK1, zK2, rowid
2764 ); 2807 );
2765 } 2808 }
2766 sqlite3_free(zK1); 2809 sqlite3_free(zK1);
2767 sqlite3_free(zK2); 2810 sqlite3_free(zK2);
2768 } 2811 }
2769 return rc; 2812 return rc;
2770 } 2813 }
2771 2814
2772 /* 2815 /*
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
2867 sqlite3 *db, 2910 sqlite3 *db,
2868 char **pzErrMsg, 2911 char **pzErrMsg,
2869 const sqlite3_api_routines *pApi 2912 const sqlite3_api_routines *pApi
2870 ){ 2913 ){
2871 SQLITE_EXTENSION_INIT2(pApi); 2914 SQLITE_EXTENSION_INIT2(pApi);
2872 #ifndef SQLITE_OMIT_VIRTUALTABLE 2915 #ifndef SQLITE_OMIT_VIRTUALTABLE
2873 return spellfix1Register(db); 2916 return spellfix1Register(db);
2874 #endif 2917 #endif
2875 return SQLITE_OK; 2918 return SQLITE_OK;
2876 } 2919 }
OLDNEW
« no previous file with comments | « third_party/sqlite/src/ext/misc/series.c ('k') | third_party/sqlite/src/ext/rbu/rbu.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698