Index: third_party/sqlite/src/ext/fts3/fts3_tokenizer.c |
diff --git a/third_party/sqlite/src/ext/fts3/fts3_tokenizer.c b/third_party/sqlite/src/ext/fts3/fts3_tokenizer.c |
index e5de9c935f91c83dcb6b21b8d91e0d1f456d30de..aa28933439cea86d5a722f2537d08226f608a11b 100644 |
--- a/third_party/sqlite/src/ext/fts3/fts3_tokenizer.c |
+++ b/third_party/sqlite/src/ext/fts3/fts3_tokenizer.c |
@@ -30,10 +30,9 @@ |
SQLITE_EXTENSION_INIT1 |
#endif |
-#include "fts3_hash.h" |
-#include "fts3_tokenizer.h" |
+#include "fts3Int.h" |
#include <assert.h> |
-#include <stddef.h> |
+#include <string.h> |
/* |
** Implementation of the SQL scalar function for accessing the underlying |
@@ -60,14 +59,14 @@ static void scalarFunc( |
int argc, |
sqlite3_value **argv |
){ |
- fts3Hash *pHash; |
+ Fts3Hash *pHash; |
void *pPtr = 0; |
const unsigned char *zName; |
int nName; |
assert( argc==1 || argc==2 ); |
- pHash = (fts3Hash *)sqlite3_user_data(context); |
+ pHash = (Fts3Hash *)sqlite3_user_data(context); |
zName = sqlite3_value_text(argv[0]); |
nName = sqlite3_value_bytes(argv[0])+1; |
@@ -98,6 +97,115 @@ static void scalarFunc( |
sqlite3_result_blob(context, (void *)&pPtr, sizeof(pPtr), SQLITE_TRANSIENT); |
} |
+int sqlite3Fts3IsIdChar(char c){ |
+ static const char isFtsIdChar[] = { |
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x */ |
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1x */ |
+ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2x */ |
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 3x */ |
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4x */ |
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 5x */ |
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6x */ |
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 7x */ |
+ }; |
+ return (c&0x80 || isFtsIdChar[(int)(c)]); |
+} |
+ |
+const char *sqlite3Fts3NextToken(const char *zStr, int *pn){ |
+ const char *z1; |
+ const char *z2 = 0; |
+ |
+ /* Find the start of the next token. */ |
+ z1 = zStr; |
+ while( z2==0 ){ |
+ char c = *z1; |
+ switch( c ){ |
+ case '\0': return 0; /* No more tokens here */ |
+ case '\'': |
+ case '"': |
+ case '`': { |
+ z2 = z1; |
+ while( *++z2 && (*z2!=c || *++z2==c) ); |
+ break; |
+ } |
+ case '[': |
+ z2 = &z1[1]; |
+ while( *z2 && z2[0]!=']' ) z2++; |
+ if( *z2 ) z2++; |
+ break; |
+ |
+ default: |
+ if( sqlite3Fts3IsIdChar(*z1) ){ |
+ z2 = &z1[1]; |
+ while( sqlite3Fts3IsIdChar(*z2) ) z2++; |
+ }else{ |
+ z1++; |
+ } |
+ } |
+ } |
+ |
+ *pn = (int)(z2-z1); |
+ return z1; |
+} |
+ |
+int sqlite3Fts3InitTokenizer( |
+ Fts3Hash *pHash, /* Tokenizer hash table */ |
+ const char *zArg, /* Tokenizer name */ |
+ sqlite3_tokenizer **ppTok, /* OUT: Tokenizer (if applicable) */ |
+ char **pzErr /* OUT: Set to malloced error message */ |
+){ |
+ int rc; |
+ char *z = (char *)zArg; |
+ int n; |
+ char *zCopy; |
+ char *zEnd; /* Pointer to nul-term of zCopy */ |
+ sqlite3_tokenizer_module *m; |
+ |
+ zCopy = sqlite3_mprintf("%s", zArg); |
+ if( !zCopy ) return SQLITE_NOMEM; |
+ zEnd = &zCopy[strlen(zCopy)]; |
+ |
+ z = (char *)sqlite3Fts3NextToken(zCopy, &n); |
+ z[n] = '\0'; |
+ sqlite3Fts3Dequote(z); |
+ |
+ m = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash,z,(int)strlen(z)+1); |
+ if( !m ){ |
+ *pzErr = sqlite3_mprintf("unknown tokenizer: %s", z); |
+ rc = SQLITE_ERROR; |
+ }else{ |
+ char const **aArg = 0; |
+ int iArg = 0; |
+ z = &z[n+1]; |
+ while( z<zEnd && (NULL!=(z = (char *)sqlite3Fts3NextToken(z, &n))) ){ |
+ int nNew = sizeof(char *)*(iArg+1); |
+ char const **aNew = (const char **)sqlite3_realloc((void *)aArg, nNew); |
+ if( !aNew ){ |
+ sqlite3_free(zCopy); |
+ sqlite3_free((void *)aArg); |
+ return SQLITE_NOMEM; |
+ } |
+ aArg = aNew; |
+ aArg[iArg++] = z; |
+ z[n] = '\0'; |
+ sqlite3Fts3Dequote(z); |
+ z = &z[n+1]; |
+ } |
+ rc = m->xCreate(iArg, aArg, ppTok); |
+ assert( rc!=SQLITE_OK || *ppTok ); |
+ if( rc!=SQLITE_OK ){ |
+ *pzErr = sqlite3_mprintf("unknown tokenizer"); |
+ }else{ |
+ (*ppTok)->pModule = m; |
+ } |
+ sqlite3_free((void *)aArg); |
+ } |
+ |
+ sqlite3_free(zCopy); |
+ return rc; |
+} |
+ |
+ |
#ifdef SQLITE_TEST |
#include <tcl.h> |
@@ -134,7 +242,7 @@ static void testFunc( |
int argc, |
sqlite3_value **argv |
){ |
- fts3Hash *pHash; |
+ Fts3Hash *pHash; |
sqlite3_tokenizer_module *p; |
sqlite3_tokenizer *pTokenizer = 0; |
sqlite3_tokenizer_cursor *pCsr = 0; |
@@ -167,7 +275,7 @@ static void testFunc( |
zArg = (const char *)sqlite3_value_text(argv[1]); |
} |
- pHash = (fts3Hash *)sqlite3_user_data(context); |
+ pHash = (Fts3Hash *)sqlite3_user_data(context); |
p = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zName, nName+1); |
if( !p ){ |
@@ -258,7 +366,7 @@ int queryTokenizer( |
sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC); |
if( SQLITE_ROW==sqlite3_step(pStmt) ){ |
if( sqlite3_column_type(pStmt, 0)==SQLITE_BLOB ){ |
- memcpy(pp, sqlite3_column_blob(pStmt, 0), sizeof(*pp)); |
+ memcpy((void *)pp, sqlite3_column_blob(pStmt, 0), sizeof(*pp)); |
} |
} |
@@ -295,6 +403,9 @@ static void intTestFunc( |
const sqlite3_tokenizer_module *p2; |
sqlite3 *db = (sqlite3 *)sqlite3_user_data(context); |
+ UNUSED_PARAMETER(argc); |
+ UNUSED_PARAMETER(argv); |
+ |
/* Test the query function */ |
sqlite3Fts3SimpleTokenizerModule(&p1); |
rc = queryTokenizer(db, "simple", &p2); |
@@ -336,16 +447,16 @@ static void intTestFunc( |
*/ |
int sqlite3Fts3InitHashTable( |
sqlite3 *db, |
- fts3Hash *pHash, |
+ Fts3Hash *pHash, |
const char *zName |
){ |
int rc = SQLITE_OK; |
void *p = (void *)pHash; |
const int any = SQLITE_ANY; |
- char *zTest = 0; |
- char *zTest2 = 0; |
#ifdef SQLITE_TEST |
+ char *zTest = 0; |
+ char *zTest2 = 0; |
void *pdb = (void *)db; |
zTest = sqlite3_mprintf("%s_test", zName); |
zTest2 = sqlite3_mprintf("%s_internal_test", zName); |
@@ -354,18 +465,29 @@ int sqlite3Fts3InitHashTable( |
} |
#endif |
- if( rc!=SQLITE_OK |
- || (rc = sqlite3_create_function(db, zName, 1, any, p, scalarFunc, 0, 0)) |
- || (rc = sqlite3_create_function(db, zName, 2, any, p, scalarFunc, 0, 0)) |
+ if( SQLITE_OK==rc ){ |
+ rc = sqlite3_create_function(db, zName, 1, any, p, scalarFunc, 0, 0); |
+ } |
+ if( SQLITE_OK==rc ){ |
+ rc = sqlite3_create_function(db, zName, 2, any, p, scalarFunc, 0, 0); |
+ } |
#ifdef SQLITE_TEST |
- || (rc = sqlite3_create_function(db, zTest, 2, any, p, testFunc, 0, 0)) |
- || (rc = sqlite3_create_function(db, zTest, 3, any, p, testFunc, 0, 0)) |
- || (rc = sqlite3_create_function(db, zTest2, 0, any, pdb, intTestFunc, 0, 0)) |
+ if( SQLITE_OK==rc ){ |
+ rc = sqlite3_create_function(db, zTest, 2, any, p, testFunc, 0, 0); |
+ } |
+ if( SQLITE_OK==rc ){ |
+ rc = sqlite3_create_function(db, zTest, 3, any, p, testFunc, 0, 0); |
+ } |
+ if( SQLITE_OK==rc ){ |
+ rc = sqlite3_create_function(db, zTest2, 0, any, pdb, intTestFunc, 0, 0); |
+ } |
#endif |
- ); |
+#ifdef SQLITE_TEST |
sqlite3_free(zTest); |
sqlite3_free(zTest2); |
+#endif |
+ |
return rc; |
} |