OLD | NEW |
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 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 ** * Omit T when followed by CH | 179 ** * Omit T when followed by CH |
180 ** * Omit W when followed by R | 180 ** * Omit W when followed by R |
181 ** * Omit D when followed by J or G | 181 ** * Omit D when followed by J or G |
182 ** * Omit K in KN or G in GN at the beginning of a word | 182 ** * Omit K in KN or G in GN at the beginning of a word |
183 ** | 183 ** |
184 ** Space to hold the result is obtained from sqlite3_malloc() | 184 ** Space to hold the result is obtained from sqlite3_malloc() |
185 ** | 185 ** |
186 ** Return NULL if memory allocation fails. | 186 ** Return NULL if memory allocation fails. |
187 */ | 187 */ |
188 static unsigned char *phoneticHash(const unsigned char *zIn, int nIn){ | 188 static unsigned char *phoneticHash(const unsigned char *zIn, int nIn){ |
189 unsigned char *zOut = sqlite3_malloc( nIn + 1 ); | 189 unsigned char *zOut = sqlite3_malloc64( nIn + 1 ); |
190 int i; | 190 int i; |
191 int nOut = 0; | 191 int nOut = 0; |
192 char cPrev = 0x77; | 192 char cPrev = 0x77; |
193 char cPrevX = 0x77; | 193 char cPrevX = 0x77; |
194 const unsigned char *aClass = initClass; | 194 const unsigned char *aClass = initClass; |
195 | 195 |
196 if( zOut==0 ) return 0; | 196 if( zOut==0 ) return 0; |
197 if( nIn>2 ){ | 197 if( nIn>2 ){ |
198 switch( zIn[0] ){ | 198 switch( zIn[0] ){ |
199 case 'g': | 199 case 'g': |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 int xA, xB; /* Loop counters for zA[] and zB[] */ | 358 int xA, xB; /* Loop counters for zA[] and zB[] */ |
359 char cA = 0, 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 nMatch = 0; |
368 int mStack[60+15]; /* Stack space to use if not too much is needed */ | 369 int mStack[60+15]; /* Stack space to use if not too much is needed */ |
369 int nMatch = 0; | |
370 | 370 |
371 /* Early out if either input is NULL */ | 371 /* Early out if either input is NULL */ |
372 if( zA==0 || zB==0 ) return -1; | 372 if( zA==0 || zB==0 ) return -1; |
373 | 373 |
374 /* Skip any common prefix */ | 374 /* Skip any common prefix */ |
375 while( zA[0] && zA[0]==zB[0] ){ dc = zA[0]; zA++; zB++; nMatch++; } | 375 while( zA[0] && zA[0]==zB[0] ){ dc = zA[0]; zA++; zB++; nMatch++; } |
376 if( pnMatch ) *pnMatch = nMatch; | 376 if( pnMatch ) *pnMatch = nMatch; |
377 if( zA[0]==0 && zB[0]==0 ) return 0; | 377 if( zA[0]==0 && zB[0]==0 ) return 0; |
378 | 378 |
379 #if 0 | 379 #if 0 |
380 printf("A=\"%s\" B=\"%s\" dc=%c\n", zA, zB, dc?dc:' '); | 380 printf("A=\"%s\" B=\"%s\" dc=%c\n", zA, zB, dc?dc:' '); |
381 #endif | 381 #endif |
382 | 382 |
383 /* Verify input strings and measure their lengths */ | 383 /* Verify input strings and measure their lengths */ |
384 for(nA=0; zA[nA]; nA++){ | 384 for(nA=0; zA[nA]; nA++){ |
385 if( zA[nA]&0x80 ) return -2; | 385 if( zA[nA]&0x80 ) return -2; |
386 } | 386 } |
387 for(nB=0; zB[nB]; nB++){ | 387 for(nB=0; zB[nB]; nB++){ |
388 if( zB[nB]&0x80 ) return -2; | 388 if( zB[nB]&0x80 ) return -2; |
389 } | 389 } |
390 | 390 |
391 /* Special processing if either string is empty */ | 391 /* Special processing if either string is empty */ |
392 if( nA==0 ){ | 392 if( nA==0 ){ |
393 cBprev = dc; | 393 cBprev = (char)dc; |
394 for(xB=res=0; (cB = zB[xB])!=0; xB++){ | 394 for(xB=res=0; (cB = zB[xB])!=0; xB++){ |
395 res += insertOrDeleteCost(cBprev, cB, zB[xB+1])/FINAL_INS_COST_DIV; | 395 res += insertOrDeleteCost(cBprev, cB, zB[xB+1])/FINAL_INS_COST_DIV; |
396 cBprev = cB; | 396 cBprev = cB; |
397 } | 397 } |
398 return res; | 398 return res; |
399 } | 399 } |
400 if( nB==0 ){ | 400 if( nB==0 ){ |
401 cAprev = dc; | 401 cAprev = (char)dc; |
402 for(xA=res=0; (cA = zA[xA])!=0; xA++){ | 402 for(xA=res=0; (cA = zA[xA])!=0; xA++){ |
403 res += insertOrDeleteCost(cAprev, cA, zA[xA+1]); | 403 res += insertOrDeleteCost(cAprev, cA, zA[xA+1]); |
404 cAprev = cA; | 404 cAprev = cA; |
405 } | 405 } |
406 return res; | 406 return res; |
407 } | 407 } |
408 | 408 |
409 /* A is a prefix of B */ | 409 /* A is a prefix of B */ |
410 if( zA[0]=='*' && zA[1]==0 ) return 0; | 410 if( zA[0]=='*' && zA[1]==0 ) return 0; |
411 | 411 |
412 /* Allocate and initialize the Wagner matrix */ | 412 /* Allocate and initialize the Wagner matrix */ |
413 if( nB<(sizeof(mStack)*4)/(sizeof(mStack[0])*5) ){ | 413 if( nB<(sizeof(mStack)*4)/(sizeof(mStack[0])*5) ){ |
414 m = mStack; | 414 m = mStack; |
415 }else{ | 415 }else{ |
416 m = toFree = sqlite3_malloc( (nB+1)*5*sizeof(m[0])/4 ); | 416 m = toFree = sqlite3_malloc64( (nB+1)*5*sizeof(m[0])/4 ); |
417 if( m==0 ) return -3; | 417 if( m==0 ) return -3; |
418 } | 418 } |
419 cx = (char*)&m[nB+1]; | 419 cx = (char*)&m[nB+1]; |
420 | 420 |
421 /* Compute the Wagner edit distance */ | 421 /* Compute the Wagner edit distance */ |
422 m[0] = 0; | 422 m[0] = 0; |
423 cx[0] = dc; | 423 cx[0] = (char)dc; |
424 cBprev = dc; | 424 cBprev = (char)dc; |
425 for(xB=1; xB<=nB; xB++){ | 425 for(xB=1; xB<=nB; xB++){ |
426 cBnext = zB[xB]; | 426 cBnext = zB[xB]; |
427 cB = zB[xB-1]; | 427 cB = zB[xB-1]; |
428 cx[xB] = cB; | 428 cx[xB] = cB; |
429 m[xB] = m[xB-1] + insertOrDeleteCost(cBprev, cB, cBnext); | 429 m[xB] = m[xB-1] + insertOrDeleteCost(cBprev, cB, cBnext); |
430 cBprev = cB; | 430 cBprev = cB; |
431 } | 431 } |
432 cAprev = dc; | 432 cAprev = (char)dc; |
433 for(xA=1; xA<=nA; xA++){ | 433 for(xA=1; xA<=nA; xA++){ |
434 int lastA = (xA==nA); | 434 int lastA = (xA==nA); |
435 cA = zA[xA-1]; | 435 cA = zA[xA-1]; |
436 cAnext = zA[xA]; | 436 cAnext = zA[xA]; |
437 if( cA=='*' && lastA ) break; | 437 if( cA=='*' && lastA ) break; |
438 d = m[0]; | 438 d = m[0]; |
439 dc = cx[0]; | 439 dc = cx[0]; |
440 m[0] = d + insertOrDeleteCost(cAprev, cA, cAnext); | 440 m[0] = d + insertOrDeleteCost(cAprev, cA, cAnext); |
441 cBprev = 0; | 441 cBprev = 0; |
442 for(xB=1; xB<=nB; xB++){ | 442 for(xB=1; xB<=nB; xB++){ |
(...skipping 26 matching lines...) Expand all Loading... |
469 printf("%d,%d d=%4d u=%4d r=%4d dc=%c cA=%c cB=%c" | 469 printf("%d,%d d=%4d u=%4d r=%4d dc=%c cA=%c cB=%c" |
470 " ins=%4d del=%4d sub=%4d t=%4d ncx=%c\n", | 470 " ins=%4d del=%4d sub=%4d t=%4d ncx=%c\n", |
471 xA, xB, d, m[xB], m[xB-1], dc?dc:' ', cA, cB, | 471 xA, xB, d, m[xB], m[xB-1], dc?dc:' ', cA, cB, |
472 insCost, delCost, subCost, totalCost, ncx?ncx:' '); | 472 insCost, delCost, subCost, totalCost, ncx?ncx:' '); |
473 #endif | 473 #endif |
474 | 474 |
475 /* Update the matrix */ | 475 /* Update the matrix */ |
476 d = m[xB]; | 476 d = m[xB]; |
477 dc = cx[xB]; | 477 dc = cx[xB]; |
478 m[xB] = totalCost; | 478 m[xB] = totalCost; |
479 cx[xB] = ncx; | 479 cx[xB] = (char)ncx; |
480 cBprev = cB; | 480 cBprev = cB; |
481 } | 481 } |
482 cAprev = cA; | 482 cAprev = cA; |
483 } | 483 } |
484 | 484 |
485 /* Free the wagner matrix and return the result */ | 485 /* Free the wagner matrix and return the result */ |
486 if( cA=='*' ){ | 486 if( cA=='*' ){ |
487 res = m[1]; | 487 res = m[1]; |
488 for(xB=1; xB<=nB; xB++){ | 488 for(xB=1; xB<=nB; xB++){ |
489 if( m[xB]<res ){ | 489 if( m[xB]<res ){ |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
680 const char *zTo = (const char*)sqlite3_column_text(pStmt, 2); | 680 const char *zTo = (const char*)sqlite3_column_text(pStmt, 2); |
681 int nTo = zTo ? sqlite3_column_bytes(pStmt, 2) : 0; | 681 int nTo = zTo ? sqlite3_column_bytes(pStmt, 2) : 0; |
682 int iCost = sqlite3_column_int(pStmt, 3); | 682 int iCost = sqlite3_column_int(pStmt, 3); |
683 | 683 |
684 assert( zFrom!=0 || nFrom==0 ); | 684 assert( zFrom!=0 || nFrom==0 ); |
685 assert( zTo!=0 || nTo==0 ); | 685 assert( zTo!=0 || nTo==0 ); |
686 if( nFrom>100 || nTo>100 ) continue; | 686 if( nFrom>100 || nTo>100 ) continue; |
687 if( iCost<0 ) continue; | 687 if( iCost<0 ) continue; |
688 if( pLang==0 || iLang!=iLangPrev ){ | 688 if( pLang==0 || iLang!=iLangPrev ){ |
689 EditDist3Lang *pNew; | 689 EditDist3Lang *pNew; |
690 pNew = sqlite3_realloc(p->a, (p->nLang+1)*sizeof(p->a[0])); | 690 pNew = sqlite3_realloc64(p->a, (p->nLang+1)*sizeof(p->a[0])); |
691 if( pNew==0 ){ rc = SQLITE_NOMEM; break; } | 691 if( pNew==0 ){ rc = SQLITE_NOMEM; break; } |
692 p->a = pNew; | 692 p->a = pNew; |
693 pLang = &p->a[p->nLang]; | 693 pLang = &p->a[p->nLang]; |
694 p->nLang++; | 694 p->nLang++; |
695 pLang->iLang = iLang; | 695 pLang->iLang = iLang; |
696 pLang->iInsCost = 100; | 696 pLang->iInsCost = 100; |
697 pLang->iDelCost = 100; | 697 pLang->iDelCost = 100; |
698 pLang->iSubCost = 150; | 698 pLang->iSubCost = 150; |
699 pLang->pCost = 0; | 699 pLang->pCost = 0; |
700 iLangPrev = iLang; | 700 iLangPrev = iLang; |
701 } | 701 } |
702 if( nFrom==1 && zFrom[0]=='?' && nTo==0 ){ | 702 if( nFrom==1 && zFrom[0]=='?' && nTo==0 ){ |
703 pLang->iDelCost = iCost; | 703 pLang->iDelCost = iCost; |
704 }else if( nFrom==0 && nTo==1 && zTo[0]=='?' ){ | 704 }else if( nFrom==0 && nTo==1 && zTo[0]=='?' ){ |
705 pLang->iInsCost = iCost; | 705 pLang->iInsCost = iCost; |
706 }else if( nFrom==1 && nTo==1 && zFrom[0]=='?' && zTo[0]=='?' ){ | 706 }else if( nFrom==1 && nTo==1 && zFrom[0]=='?' && zTo[0]=='?' ){ |
707 pLang->iSubCost = iCost; | 707 pLang->iSubCost = iCost; |
708 }else{ | 708 }else{ |
709 EditDist3Cost *pCost; | 709 EditDist3Cost *pCost; |
710 int nExtra = nFrom + nTo - 4; | 710 int nExtra = nFrom + nTo - 4; |
711 if( nExtra<0 ) nExtra = 0; | 711 if( nExtra<0 ) nExtra = 0; |
712 pCost = sqlite3_malloc( sizeof(*pCost) + nExtra ); | 712 pCost = sqlite3_malloc64( sizeof(*pCost) + nExtra ); |
713 if( pCost==0 ){ rc = SQLITE_NOMEM; break; } | 713 if( pCost==0 ){ rc = SQLITE_NOMEM; break; } |
714 pCost->nFrom = nFrom; | 714 pCost->nFrom = (u8)nFrom; |
715 pCost->nTo = nTo; | 715 pCost->nTo = (u8)nTo; |
716 pCost->iCost = iCost; | 716 pCost->iCost = (u16)iCost; |
717 memcpy(pCost->a, zFrom, nFrom); | 717 memcpy(pCost->a, zFrom, nFrom); |
718 memcpy(pCost->a + nFrom, zTo, nTo); | 718 memcpy(pCost->a + nFrom, zTo, nTo); |
719 pCost->pNext = pLang->pCost; | 719 pCost->pNext = pLang->pCost; |
720 pLang->pCost = pCost; | 720 pLang->pCost = pCost; |
721 } | 721 } |
722 } | 722 } |
723 rc2 = sqlite3_finalize(pStmt); | 723 rc2 = sqlite3_finalize(pStmt); |
724 if( rc==SQLITE_OK ) rc = rc2; | 724 if( rc==SQLITE_OK ) rc = rc2; |
725 return rc; | 725 return rc; |
726 } | 726 } |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
801 const EditDist3Lang *pLang, | 801 const EditDist3Lang *pLang, |
802 const char *z, | 802 const char *z, |
803 int n | 803 int n |
804 ){ | 804 ){ |
805 EditDist3FromString *pStr; | 805 EditDist3FromString *pStr; |
806 EditDist3Cost *p; | 806 EditDist3Cost *p; |
807 int i; | 807 int i; |
808 | 808 |
809 if( z==0 ) return 0; | 809 if( z==0 ) return 0; |
810 if( n<0 ) n = (int)strlen(z); | 810 if( n<0 ) n = (int)strlen(z); |
811 pStr = sqlite3_malloc( sizeof(*pStr) + sizeof(pStr->a[0])*n + n + 1 ); | 811 pStr = sqlite3_malloc64( sizeof(*pStr) + sizeof(pStr->a[0])*n + n + 1 ); |
812 if( pStr==0 ) return 0; | 812 if( pStr==0 ) return 0; |
813 pStr->a = (EditDist3From*)&pStr[1]; | 813 pStr->a = (EditDist3From*)&pStr[1]; |
814 memset(pStr->a, 0, sizeof(pStr->a[0])*n); | 814 memset(pStr->a, 0, sizeof(pStr->a[0])*n); |
815 pStr->n = n; | 815 pStr->n = n; |
816 pStr->z = (char*)&pStr->a[n]; | 816 pStr->z = (char*)&pStr->a[n]; |
817 memcpy(pStr->z, z, n+1); | 817 memcpy(pStr->z, z, n+1); |
818 if( n && z[n-1]=='*' ){ | 818 if( n && z[n-1]=='*' ){ |
819 pStr->isPrefix = 1; | 819 pStr->isPrefix = 1; |
820 n--; | 820 n--; |
821 pStr->n--; | 821 pStr->n--; |
822 pStr->z[n] = 0; | 822 pStr->z[n] = 0; |
823 }else{ | 823 }else{ |
824 pStr->isPrefix = 0; | 824 pStr->isPrefix = 0; |
825 } | 825 } |
826 | 826 |
827 for(i=0; i<n; i++){ | 827 for(i=0; i<n; i++){ |
828 EditDist3From *pFrom = &pStr->a[i]; | 828 EditDist3From *pFrom = &pStr->a[i]; |
829 memset(pFrom, 0, sizeof(*pFrom)); | 829 memset(pFrom, 0, sizeof(*pFrom)); |
830 pFrom->nByte = utf8Len((unsigned char)z[i], n-i); | 830 pFrom->nByte = utf8Len((unsigned char)z[i], n-i); |
831 for(p=pLang->pCost; p; p=p->pNext){ | 831 for(p=pLang->pCost; p; p=p->pNext){ |
832 EditDist3Cost **apNew; | 832 EditDist3Cost **apNew; |
833 if( i+p->nFrom>n ) continue; | 833 if( i+p->nFrom>n ) continue; |
834 if( matchFrom(p, z+i, n-i)==0 ) continue; | 834 if( matchFrom(p, z+i, n-i)==0 ) continue; |
835 if( p->nTo==0 ){ | 835 if( p->nTo==0 ){ |
836 apNew = sqlite3_realloc(pFrom->apDel, | 836 apNew = sqlite3_realloc64(pFrom->apDel, |
837 sizeof(*apNew)*(pFrom->nDel+1)); | 837 sizeof(*apNew)*(pFrom->nDel+1)); |
838 if( apNew==0 ) break; | 838 if( apNew==0 ) break; |
839 pFrom->apDel = apNew; | 839 pFrom->apDel = apNew; |
840 apNew[pFrom->nDel++] = p; | 840 apNew[pFrom->nDel++] = p; |
841 }else{ | 841 }else{ |
842 apNew = sqlite3_realloc(pFrom->apSubst, | 842 apNew = sqlite3_realloc64(pFrom->apSubst, |
843 sizeof(*apNew)*(pFrom->nSubst+1)); | 843 sizeof(*apNew)*(pFrom->nSubst+1)); |
844 if( apNew==0 ) break; | 844 if( apNew==0 ) break; |
845 pFrom->apSubst = apNew; | 845 pFrom->apSubst = apNew; |
846 apNew[pFrom->nSubst++] = p; | 846 apNew[pFrom->nSubst++] = p; |
847 } | 847 } |
848 } | 848 } |
849 if( p ){ | 849 if( p ){ |
850 editDist3FromStringDelete(pStr); | 850 editDist3FromStringDelete(pStr); |
851 pStr = 0; | 851 pStr = 0; |
852 break; | 852 break; |
(...skipping 15 matching lines...) Expand all Loading... |
868 int j, | 868 int j, |
869 int iCost | 869 int iCost |
870 ){ | 870 ){ |
871 assert( iCost>=0 ); | 871 assert( iCost>=0 ); |
872 if( iCost<10000 ){ | 872 if( iCost<10000 ){ |
873 unsigned int b = m[j] + iCost; | 873 unsigned int b = m[j] + iCost; |
874 if( b<m[i] ) m[i] = b; | 874 if( b<m[i] ) m[i] = b; |
875 } | 875 } |
876 } | 876 } |
877 | 877 |
| 878 /* |
| 879 ** How much stack space (int bytes) to use for Wagner matrix in |
| 880 ** editDist3Core(). If more space than this is required, the entire |
| 881 ** matrix is taken from the heap. To reduce the load on the memory |
| 882 ** allocator, make this value as large as practical for the |
| 883 ** architecture in use. |
| 884 */ |
| 885 #ifndef SQLITE_SPELLFIX_STACKALLOC_SZ |
| 886 # define SQLITE_SPELLFIX_STACKALLOC_SZ (1024) |
| 887 #endif |
| 888 |
878 /* Compute the edit distance between two strings. | 889 /* Compute the edit distance between two strings. |
879 ** | 890 ** |
880 ** If an error occurs, return a negative number which is the error code. | 891 ** If an error occurs, return a negative number which is the error code. |
881 ** | 892 ** |
882 ** If pnMatch is not NULL, then *pnMatch is set to the number of characters | 893 ** If pnMatch is not NULL, then *pnMatch is set to the number of characters |
883 ** (not bytes) in z2 that matched the search pattern in *pFrom. If pFrom does | 894 ** (not bytes) in z2 that matched the search pattern in *pFrom. If pFrom does |
884 ** not contain the pattern for a prefix-search, then this is always the number | 895 ** not contain the pattern for a prefix-search, then this is always the number |
885 ** of characters in z2. If pFrom does contain a prefix search pattern, then | 896 ** of characters in z2. If pFrom does contain a prefix search pattern, then |
886 ** it is the number of characters in the prefix of z2 that was deemed to | 897 ** it is the number of characters in the prefix of z2 that was deemed to |
887 ** match pFrom. | 898 ** match pFrom. |
888 */ | 899 */ |
889 static int editDist3Core( | 900 static int editDist3Core( |
890 EditDist3FromString *pFrom, /* The FROM string */ | 901 EditDist3FromString *pFrom, /* The FROM string */ |
891 const char *z2, /* The TO string */ | 902 const char *z2, /* The TO string */ |
892 int n2, /* Length of the TO string */ | 903 int n2, /* Length of the TO string */ |
893 const EditDist3Lang *pLang, /* Edit weights for a particular language ID */ | 904 const EditDist3Lang *pLang, /* Edit weights for a particular language ID */ |
894 int *pnMatch /* OUT: Characters in matched prefix */ | 905 int *pnMatch /* OUT: Characters in matched prefix */ |
895 ){ | 906 ){ |
896 int k, n; | 907 int k, n; |
897 int i1, b1; | 908 int i1, b1; |
898 int i2, b2; | 909 int i2, b2; |
899 EditDist3FromString f = *pFrom; | 910 EditDist3FromString f = *pFrom; |
900 EditDist3To *a2; | 911 EditDist3To *a2; |
901 unsigned int *m; | 912 unsigned int *m; |
| 913 unsigned int *pToFree; |
902 int szRow; | 914 int szRow; |
903 EditDist3Cost *p; | 915 EditDist3Cost *p; |
904 int res; | 916 int res; |
| 917 sqlite3_uint64 nByte; |
| 918 unsigned int stackSpace[SQLITE_SPELLFIX_STACKALLOC_SZ/sizeof(unsigned int)]; |
905 | 919 |
906 /* allocate the Wagner matrix and the aTo[] array for the TO string */ | 920 /* allocate the Wagner matrix and the aTo[] array for the TO string */ |
907 n = (f.n+1)*(n2+1); | 921 n = (f.n+1)*(n2+1); |
908 n = (n+1)&~1; | 922 n = (n+1)&~1; |
909 m = sqlite3_malloc( n*sizeof(m[0]) + sizeof(a2[0])*n2 ); | 923 nByte = n*sizeof(m[0]) + sizeof(a2[0])*n2; |
910 if( m==0 ) return -1; /* Out of memory */ | 924 if( nByte<=sizeof(stackSpace) ){ |
| 925 m = stackSpace; |
| 926 pToFree = 0; |
| 927 }else{ |
| 928 m = pToFree = sqlite3_malloc64( nByte ); |
| 929 if( m==0 ) return -1; /* Out of memory */ |
| 930 } |
911 a2 = (EditDist3To*)&m[n]; | 931 a2 = (EditDist3To*)&m[n]; |
912 memset(a2, 0, sizeof(a2[0])*n2); | 932 memset(a2, 0, sizeof(a2[0])*n2); |
913 | 933 |
914 /* Fill in the a1[] matrix for all characters of the TO string */ | 934 /* Fill in the a1[] matrix for all characters of the TO string */ |
915 for(i2=0; i2<n2; i2++){ | 935 for(i2=0; i2<n2; i2++){ |
916 a2[i2].nByte = utf8Len((unsigned char)z2[i2], n2-i2); | 936 a2[i2].nByte = utf8Len((unsigned char)z2[i2], n2-i2); |
917 for(p=pLang->pCost; p; p=p->pNext){ | 937 for(p=pLang->pCost; p; p=p->pNext){ |
918 EditDist3Cost **apNew; | 938 EditDist3Cost **apNew; |
919 if( p->nFrom>0 ) continue; | 939 if( p->nFrom>0 ) continue; |
920 if( i2+p->nTo>n2 ) continue; | 940 if( i2+p->nTo>n2 ) continue; |
921 if( matchTo(p, z2+i2, n2-i2)==0 ) continue; | 941 if( matchTo(p, z2+i2, n2-i2)==0 ) continue; |
922 a2[i2].nIns++; | 942 a2[i2].nIns++; |
923 apNew = sqlite3_realloc(a2[i2].apIns, sizeof(*apNew)*a2[i2].nIns); | 943 apNew = sqlite3_realloc64(a2[i2].apIns, sizeof(*apNew)*a2[i2].nIns); |
924 if( apNew==0 ){ | 944 if( apNew==0 ){ |
925 res = -1; /* Out of memory */ | 945 res = -1; /* Out of memory */ |
926 goto editDist3Abort; | 946 goto editDist3Abort; |
927 } | 947 } |
928 a2[i2].apIns = apNew; | 948 a2[i2].apIns = apNew; |
929 a2[i2].apIns[a2[i2].nIns-1] = p; | 949 a2[i2].apIns[a2[i2].nIns-1] = p; |
930 } | 950 } |
931 } | 951 } |
932 | 952 |
933 /* Prepare to compute the minimum edit distance */ | 953 /* Prepare to compute the minimum edit distance */ |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1022 if( pnMatch ){ | 1042 if( pnMatch ){ |
1023 int nExtra = 0; | 1043 int nExtra = 0; |
1024 for(k=0; k<n; k++){ | 1044 for(k=0; k<n; k++){ |
1025 if( (z2[k] & 0xc0)==0x80 ) nExtra++; | 1045 if( (z2[k] & 0xc0)==0x80 ) nExtra++; |
1026 } | 1046 } |
1027 *pnMatch = n - nExtra; | 1047 *pnMatch = n - nExtra; |
1028 } | 1048 } |
1029 | 1049 |
1030 editDist3Abort: | 1050 editDist3Abort: |
1031 for(i2=0; i2<n2; i2++) sqlite3_free(a2[i2].apIns); | 1051 for(i2=0; i2<n2; i2++) sqlite3_free(a2[i2].apIns); |
1032 sqlite3_free(m); | 1052 sqlite3_free(pToFree); |
1033 return res; | 1053 return res; |
1034 } | 1054 } |
1035 | 1055 |
1036 /* | 1056 /* |
1037 ** Get an appropriate EditDist3Lang object. | 1057 ** Get an appropriate EditDist3Lang object. |
1038 */ | 1058 */ |
1039 static const EditDist3Lang *editDist3FindLang( | 1059 static const EditDist3Lang *editDist3FindLang( |
1040 EditDist3Config *pConfig, | 1060 EditDist3Config *pConfig, |
1041 int iLang | 1061 int iLang |
1042 ){ | 1062 ){ |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1091 sqlite3_result_int(context, dist); | 1111 sqlite3_result_int(context, dist); |
1092 } | 1112 } |
1093 } | 1113 } |
1094 } | 1114 } |
1095 | 1115 |
1096 /* | 1116 /* |
1097 ** Register the editDist3 function with SQLite | 1117 ** Register the editDist3 function with SQLite |
1098 */ | 1118 */ |
1099 static int editDist3Install(sqlite3 *db){ | 1119 static int editDist3Install(sqlite3 *db){ |
1100 int rc; | 1120 int rc; |
1101 EditDist3Config *pConfig = sqlite3_malloc( sizeof(*pConfig) ); | 1121 EditDist3Config *pConfig = sqlite3_malloc64( sizeof(*pConfig) ); |
1102 if( pConfig==0 ) return SQLITE_NOMEM; | 1122 if( pConfig==0 ) return SQLITE_NOMEM; |
1103 memset(pConfig, 0, sizeof(*pConfig)); | 1123 memset(pConfig, 0, sizeof(*pConfig)); |
1104 rc = sqlite3_create_function_v2(db, "editdist3", | 1124 rc = sqlite3_create_function_v2(db, "editdist3", |
1105 2, SQLITE_UTF8, pConfig, editDist3SqlFunc, 0, 0, 0); | 1125 2, SQLITE_UTF8, pConfig, editDist3SqlFunc, 0, 0, 0); |
1106 if( rc==SQLITE_OK ){ | 1126 if( rc==SQLITE_OK ){ |
1107 rc = sqlite3_create_function_v2(db, "editdist3", | 1127 rc = sqlite3_create_function_v2(db, "editdist3", |
1108 3, SQLITE_UTF8, pConfig, editDist3SqlFunc, 0, 0, 0); | 1128 3, SQLITE_UTF8, pConfig, editDist3SqlFunc, 0, 0, 0); |
1109 } | 1129 } |
1110 if( rc==SQLITE_OK ){ | 1130 if( rc==SQLITE_OK ){ |
1111 rc = sqlite3_create_function_v2(db, "editdist3", | 1131 rc = sqlite3_create_function_v2(db, "editdist3", |
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1580 ** Convert the input string from UTF-8 into pure ASCII by converting | 1600 ** Convert the input string from UTF-8 into pure ASCII by converting |
1581 ** all non-ASCII characters to some combination of characters in the | 1601 ** all non-ASCII characters to some combination of characters in the |
1582 ** ASCII subset. | 1602 ** ASCII subset. |
1583 ** | 1603 ** |
1584 ** The returned string might contain more characters than the input. | 1604 ** The returned string might contain more characters than the input. |
1585 ** | 1605 ** |
1586 ** Space to hold the returned string comes from sqlite3_malloc() and | 1606 ** Space to hold the returned string comes from sqlite3_malloc() and |
1587 ** should be freed by the caller. | 1607 ** should be freed by the caller. |
1588 */ | 1608 */ |
1589 static unsigned char *transliterate(const unsigned char *zIn, int nIn){ | 1609 static unsigned char *transliterate(const unsigned char *zIn, int nIn){ |
1590 unsigned char *zOut = sqlite3_malloc( nIn*4 + 1 ); | 1610 unsigned char *zOut = sqlite3_malloc64( nIn*4 + 1 ); |
1591 int c, sz, nOut; | 1611 int c, sz, nOut; |
1592 if( zOut==0 ) return 0; | 1612 if( zOut==0 ) return 0; |
1593 nOut = 0; | 1613 nOut = 0; |
1594 while( nIn>0 ){ | 1614 while( nIn>0 ){ |
1595 c = utf8Read(zIn, nIn, &sz); | 1615 c = utf8Read(zIn, nIn, &sz); |
1596 zIn += sz; | 1616 zIn += sz; |
1597 nIn -= sz; | 1617 nIn -= sz; |
1598 if( c<=127 ){ | 1618 if( c<=127 ){ |
1599 zOut[nOut++] = c; | 1619 zOut[nOut++] = (unsigned char)c; |
1600 }else{ | 1620 }else{ |
1601 int xTop, xBtm, x; | 1621 int xTop, xBtm, x; |
1602 xTop = sizeof(translit)/sizeof(translit[0]) - 1; | 1622 xTop = sizeof(translit)/sizeof(translit[0]) - 1; |
1603 xBtm = 0; | 1623 xBtm = 0; |
1604 while( xTop>=xBtm ){ | 1624 while( xTop>=xBtm ){ |
1605 x = (xTop + xBtm)/2; | 1625 x = (xTop + xBtm)/2; |
1606 if( translit[x].cFrom==c ){ | 1626 if( translit[x].cFrom==c ){ |
1607 zOut[nOut++] = translit[x].cTo0; | 1627 zOut[nOut++] = translit[x].cTo0; |
1608 if( translit[x].cTo1 ){ | 1628 if( translit[x].cTo1 ){ |
1609 zOut[nOut++] = translit[x].cTo1; | 1629 zOut[nOut++] = translit[x].cTo1; |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1707 static void scriptCodeSqlFunc( | 1727 static void scriptCodeSqlFunc( |
1708 sqlite3_context *context, | 1728 sqlite3_context *context, |
1709 int argc, | 1729 int argc, |
1710 sqlite3_value **argv | 1730 sqlite3_value **argv |
1711 ){ | 1731 ){ |
1712 const unsigned char *zIn = sqlite3_value_text(argv[0]); | 1732 const unsigned char *zIn = sqlite3_value_text(argv[0]); |
1713 int nIn = sqlite3_value_bytes(argv[0]); | 1733 int nIn = sqlite3_value_bytes(argv[0]); |
1714 int c, sz; | 1734 int c, sz; |
1715 int scriptMask = 0; | 1735 int scriptMask = 0; |
1716 int res; | 1736 int res; |
| 1737 int seenDigit = 0; |
1717 # define SCRIPT_LATIN 0x0001 | 1738 # define SCRIPT_LATIN 0x0001 |
1718 # define SCRIPT_CYRILLIC 0x0002 | 1739 # define SCRIPT_CYRILLIC 0x0002 |
1719 # define SCRIPT_GREEK 0x0004 | 1740 # define SCRIPT_GREEK 0x0004 |
1720 # define SCRIPT_HEBREW 0x0008 | 1741 # define SCRIPT_HEBREW 0x0008 |
1721 # define SCRIPT_ARABIC 0x0010 | 1742 # define SCRIPT_ARABIC 0x0010 |
1722 | 1743 |
1723 while( nIn>0 ){ | 1744 while( nIn>0 ){ |
1724 c = utf8Read(zIn, nIn, &sz); | 1745 c = utf8Read(zIn, nIn, &sz); |
1725 zIn += sz; | 1746 zIn += sz; |
1726 nIn -= sz; | 1747 nIn -= sz; |
1727 if( c<0x02af && (c>=0x80 || midClass[c&0x7f]<CCLASS_DIGIT) ){ | 1748 if( c<0x02af ){ |
1728 scriptMask |= SCRIPT_LATIN; | 1749 if( c>=0x80 || midClass[c&0x7f]<CCLASS_DIGIT ){ |
| 1750 scriptMask |= SCRIPT_LATIN; |
| 1751 }else if( c>='0' && c<='9' ){ |
| 1752 seenDigit = 1; |
| 1753 } |
1729 }else if( c>=0x0400 && c<=0x04ff ){ | 1754 }else if( c>=0x0400 && c<=0x04ff ){ |
1730 scriptMask |= SCRIPT_CYRILLIC; | 1755 scriptMask |= SCRIPT_CYRILLIC; |
1731 }else if( c>=0x0386 && c<=0x03ce ){ | 1756 }else if( c>=0x0386 && c<=0x03ce ){ |
1732 scriptMask |= SCRIPT_GREEK; | 1757 scriptMask |= SCRIPT_GREEK; |
1733 }else if( c>=0x0590 && c<=0x05ff ){ | 1758 }else if( c>=0x0590 && c<=0x05ff ){ |
1734 scriptMask |= SCRIPT_HEBREW; | 1759 scriptMask |= SCRIPT_HEBREW; |
1735 }else if( c>=0x0600 && c<=0x06ff ){ | 1760 }else if( c>=0x0600 && c<=0x06ff ){ |
1736 scriptMask |= SCRIPT_ARABIC; | 1761 scriptMask |= SCRIPT_ARABIC; |
1737 } | 1762 } |
1738 } | 1763 } |
| 1764 if( scriptMask==0 && seenDigit ) scriptMask = SCRIPT_LATIN; |
1739 switch( scriptMask ){ | 1765 switch( scriptMask ){ |
1740 case 0: res = 999; break; | 1766 case 0: res = 999; break; |
1741 case SCRIPT_LATIN: res = 215; break; | 1767 case SCRIPT_LATIN: res = 215; break; |
1742 case SCRIPT_CYRILLIC: res = 220; break; | 1768 case SCRIPT_CYRILLIC: res = 220; break; |
1743 case SCRIPT_GREEK: res = 200; break; | 1769 case SCRIPT_GREEK: res = 200; break; |
1744 case SCRIPT_HEBREW: res = 125; break; | 1770 case SCRIPT_HEBREW: res = 125; break; |
1745 case SCRIPT_ARABIC: res = 160; break; | 1771 case SCRIPT_ARABIC: res = 160; break; |
1746 default: res = 998; break; | 1772 default: res = 998; break; |
1747 } | 1773 } |
1748 sqlite3_result_int(context, res); | 1774 sqlite3_result_int(context, res); |
1749 } | 1775 } |
1750 | 1776 |
1751 /* End transliterate | 1777 /* End transliterate |
1752 ****************************************************************************** | 1778 ****************************************************************************** |
1753 ****************************************************************************** | 1779 ****************************************************************************** |
1754 ** Begin spellfix1 virtual table. | 1780 ** Begin spellfix1 virtual table. |
1755 */ | 1781 */ |
1756 | 1782 |
1757 /* Maximum length of a phonehash used for querying the shadow table */ | 1783 /* Maximum length of a phonehash used for querying the shadow table */ |
1758 #define SPELLFIX_MX_HASH 8 | 1784 #define SPELLFIX_MX_HASH 32 |
1759 | 1785 |
1760 /* Maximum number of hash strings to examine per query */ | 1786 /* Maximum number of hash strings to examine per query */ |
1761 #define SPELLFIX_MX_RUN 1 | 1787 #define SPELLFIX_MX_RUN 1 |
1762 | 1788 |
1763 typedef struct spellfix1_vtab spellfix1_vtab; | 1789 typedef struct spellfix1_vtab spellfix1_vtab; |
1764 typedef struct spellfix1_cursor spellfix1_cursor; | 1790 typedef struct spellfix1_cursor spellfix1_cursor; |
1765 | 1791 |
1766 /* Fuzzy-search virtual table object */ | 1792 /* Fuzzy-search virtual table object */ |
1767 struct spellfix1_vtab { | 1793 struct spellfix1_vtab { |
1768 sqlite3_vtab base; /* Base class - must be first */ | 1794 sqlite3_vtab base; /* Base class - must be first */ |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1903 ){ | 1929 ){ |
1904 spellfix1_vtab *pNew = 0; | 1930 spellfix1_vtab *pNew = 0; |
1905 /* const char *zModule = argv[0]; // not used */ | 1931 /* const char *zModule = argv[0]; // not used */ |
1906 const char *zDbName = argv[1]; | 1932 const char *zDbName = argv[1]; |
1907 const char *zTableName = argv[2]; | 1933 const char *zTableName = argv[2]; |
1908 int nDbName; | 1934 int nDbName; |
1909 int rc = SQLITE_OK; | 1935 int rc = SQLITE_OK; |
1910 int i; | 1936 int i; |
1911 | 1937 |
1912 nDbName = (int)strlen(zDbName); | 1938 nDbName = (int)strlen(zDbName); |
1913 pNew = sqlite3_malloc( sizeof(*pNew) + nDbName + 1); | 1939 pNew = sqlite3_malloc64( sizeof(*pNew) + nDbName + 1); |
1914 if( pNew==0 ){ | 1940 if( pNew==0 ){ |
1915 rc = SQLITE_NOMEM; | 1941 rc = SQLITE_NOMEM; |
1916 }else{ | 1942 }else{ |
1917 memset(pNew, 0, sizeof(*pNew)); | 1943 memset(pNew, 0, sizeof(*pNew)); |
1918 pNew->zDbName = (char*)&pNew[1]; | 1944 pNew->zDbName = (char*)&pNew[1]; |
1919 memcpy(pNew->zDbName, zDbName, nDbName+1); | 1945 memcpy(pNew->zDbName, zDbName, nDbName+1); |
1920 pNew->zTableName = sqlite3_mprintf("%s", zTableName); | 1946 pNew->zTableName = sqlite3_mprintf("%s", zTableName); |
1921 pNew->db = db; | 1947 pNew->db = db; |
1922 if( pNew->zTableName==0 ){ | 1948 if( pNew->zTableName==0 ){ |
1923 rc = SQLITE_NOMEM; | 1949 rc = SQLITE_NOMEM; |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2017 pCur->pFullScan = 0; | 2043 pCur->pFullScan = 0; |
2018 } | 2044 } |
2019 } | 2045 } |
2020 | 2046 |
2021 /* | 2047 /* |
2022 ** Resize the cursor to hold up to N rows of content | 2048 ** Resize the cursor to hold up to N rows of content |
2023 */ | 2049 */ |
2024 static void spellfix1ResizeCursor(spellfix1_cursor *pCur, int N){ | 2050 static void spellfix1ResizeCursor(spellfix1_cursor *pCur, int N){ |
2025 struct spellfix1_row *aNew; | 2051 struct spellfix1_row *aNew; |
2026 assert( N>=pCur->nRow ); | 2052 assert( N>=pCur->nRow ); |
2027 aNew = sqlite3_realloc(pCur->a, sizeof(pCur->a[0])*N); | 2053 aNew = sqlite3_realloc64(pCur->a, sizeof(pCur->a[0])*N); |
2028 if( aNew==0 && N>0 ){ | 2054 if( aNew==0 && N>0 ){ |
2029 spellfix1ResetCursor(pCur); | 2055 spellfix1ResetCursor(pCur); |
2030 sqlite3_free(pCur->a); | 2056 sqlite3_free(pCur->a); |
2031 pCur->nAlloc = 0; | 2057 pCur->nAlloc = 0; |
2032 pCur->a = 0; | 2058 pCur->a = 0; |
2033 }else{ | 2059 }else{ |
2034 pCur->nAlloc = N; | 2060 pCur->nAlloc = N; |
2035 pCur->a = aNew; | 2061 pCur->a = aNew; |
2036 } | 2062 } |
2037 } | 2063 } |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2176 } | 2202 } |
2177 return SQLITE_OK; | 2203 return SQLITE_OK; |
2178 } | 2204 } |
2179 | 2205 |
2180 /* | 2206 /* |
2181 ** Open a new fuzzy-search cursor. | 2207 ** Open a new fuzzy-search cursor. |
2182 */ | 2208 */ |
2183 static int spellfix1Open(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ | 2209 static int spellfix1Open(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ |
2184 spellfix1_vtab *p = (spellfix1_vtab*)pVTab; | 2210 spellfix1_vtab *p = (spellfix1_vtab*)pVTab; |
2185 spellfix1_cursor *pCur; | 2211 spellfix1_cursor *pCur; |
2186 pCur = sqlite3_malloc( sizeof(*pCur) ); | 2212 pCur = sqlite3_malloc64( sizeof(*pCur) ); |
2187 if( pCur==0 ) return SQLITE_NOMEM; | 2213 if( pCur==0 ) return SQLITE_NOMEM; |
2188 memset(pCur, 0, sizeof(*pCur)); | 2214 memset(pCur, 0, sizeof(*pCur)); |
2189 pCur->pVTab = p; | 2215 pCur->pVTab = p; |
2190 *ppCursor = &pCur->base; | 2216 *ppCursor = &pCur->base; |
2191 return SQLITE_OK; | 2217 return SQLITE_OK; |
2192 } | 2218 } |
2193 | 2219 |
2194 /* | 2220 /* |
2195 ** Adjust a distance measurement by the words rank in order to show | 2221 ** Adjust a distance measurement by the words rank in order to show |
2196 ** preference to common words. | 2222 ** preference to common words. |
2197 */ | 2223 */ |
2198 static int spellfix1Score(int iDistance, int iRank){ | 2224 static int spellfix1Score(int iDistance, int iRank){ |
2199 int iLog2; | 2225 int iLog2; |
2200 for(iLog2=0; iRank>0; iLog2++, iRank>>=1){} | 2226 for(iLog2=0; iRank>0; iLog2++, iRank>>=1){} |
2201 return iDistance + 32 - iLog2; | 2227 return iDistance + 32 - iLog2; |
2202 } | 2228 } |
2203 | 2229 |
2204 /* | 2230 /* |
2205 ** Compare two spellfix1_row objects for sorting purposes in qsort() such | 2231 ** Compare two spellfix1_row objects for sorting purposes in qsort() such |
2206 ** that they sort in order of increasing distance. | 2232 ** that they sort in order of increasing distance. |
2207 */ | 2233 */ |
2208 static int spellfix1RowCompare(const void *A, const void *B){ | 2234 static int SQLITE_CDECL spellfix1RowCompare(const void *A, const void *B){ |
2209 const struct spellfix1_row *a = (const struct spellfix1_row*)A; | 2235 const struct spellfix1_row *a = (const struct spellfix1_row*)A; |
2210 const struct spellfix1_row *b = (const struct spellfix1_row*)B; | 2236 const struct spellfix1_row *b = (const struct spellfix1_row*)B; |
2211 return a->iScore - b->iScore; | 2237 return a->iScore - b->iScore; |
2212 } | 2238 } |
2213 | 2239 |
2214 /* | 2240 /* |
2215 ** A structure used to pass information from spellfix1FilterForMatch() | 2241 ** A structure used to pass information from spellfix1FilterForMatch() |
2216 ** into spellfix1RunQuery(). | 2242 ** into spellfix1RunQuery(). |
2217 */ | 2243 */ |
2218 typedef struct MatchQuery { | 2244 typedef struct MatchQuery { |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2390 int iLang = 0; /* Language code */ | 2416 int iLang = 0; /* Language code */ |
2391 char *zSql; /* SQL of shadow table query */ | 2417 char *zSql; /* SQL of shadow table query */ |
2392 sqlite3_stmt *pStmt = 0; /* Shadow table query */ | 2418 sqlite3_stmt *pStmt = 0; /* Shadow table query */ |
2393 int rc; /* Result code */ | 2419 int rc; /* Result code */ |
2394 int idx = 1; /* Next available filter parameter */ | 2420 int idx = 1; /* Next available filter parameter */ |
2395 spellfix1_vtab *p = pCur->pVTab; /* The virtual table that owns pCur */ | 2421 spellfix1_vtab *p = pCur->pVTab; /* The virtual table that owns pCur */ |
2396 MatchQuery x; /* For passing info to RunQuery() */ | 2422 MatchQuery x; /* For passing info to RunQuery() */ |
2397 | 2423 |
2398 /* Load the cost table if we have not already done so */ | 2424 /* Load the cost table if we have not already done so */ |
2399 if( p->zCostTable!=0 && p->pConfig3==0 ){ | 2425 if( p->zCostTable!=0 && p->pConfig3==0 ){ |
2400 p->pConfig3 = sqlite3_malloc( sizeof(p->pConfig3[0]) ); | 2426 p->pConfig3 = sqlite3_malloc64( sizeof(p->pConfig3[0]) ); |
2401 if( p->pConfig3==0 ) return SQLITE_NOMEM; | 2427 if( p->pConfig3==0 ) return SQLITE_NOMEM; |
2402 memset(p->pConfig3, 0, sizeof(p->pConfig3[0])); | 2428 memset(p->pConfig3, 0, sizeof(p->pConfig3[0])); |
2403 rc = editDist3ConfigLoad(p->pConfig3, p->db, p->zCostTable); | 2429 rc = editDist3ConfigLoad(p->pConfig3, p->db, p->zCostTable); |
2404 if( rc ) return rc; | 2430 if( rc ) return rc; |
2405 } | 2431 } |
2406 memset(&x, 0, sizeof(x)); | 2432 memset(&x, 0, sizeof(x)); |
2407 x.iScope = 3; /* Default scope if none specified by "WHERE scope=N" */ | 2433 x.iScope = 3; /* Default scope if none specified by "WHERE scope=N" */ |
2408 x.iMaxDist = -1; /* Maximum allowed edit distance */ | 2434 x.iMaxDist = -1; /* Maximum allowed edit distance */ |
2409 | 2435 |
2410 if( idxNum&2 ){ | 2436 if( idxNum&2 ){ |
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2910 sqlite3 *db, | 2936 sqlite3 *db, |
2911 char **pzErrMsg, | 2937 char **pzErrMsg, |
2912 const sqlite3_api_routines *pApi | 2938 const sqlite3_api_routines *pApi |
2913 ){ | 2939 ){ |
2914 SQLITE_EXTENSION_INIT2(pApi); | 2940 SQLITE_EXTENSION_INIT2(pApi); |
2915 #ifndef SQLITE_OMIT_VIRTUALTABLE | 2941 #ifndef SQLITE_OMIT_VIRTUALTABLE |
2916 return spellfix1Register(db); | 2942 return spellfix1Register(db); |
2917 #endif | 2943 #endif |
2918 return SQLITE_OK; | 2944 return SQLITE_OK; |
2919 } | 2945 } |
OLD | NEW |