From 27aac274b981a65f60410080e1d7d2218a8bec15 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 18 May 2015 17:50:17 +0000 Subject: [PATCH] Improve test coverage of fts5_config.c. FossilOrigin-Name: 47dbfadb994814c9349d4c9c113b862c2e97c01a --- ext/fts5/fts5.h | 5 +- ext/fts5/fts5Int.h | 3 + ext/fts5/fts5_buffer.c | 26 +++++ ext/fts5/fts5_config.c | 176 ++++++++++++++--------------- ext/fts5/fts5_expr.c | 8 +- ext/fts5/fts5_index.c | 14 --- ext/fts5/fts5_vocab.c | 2 + ext/fts5/test/fts5aa.test | 23 ++++ ext/fts5/test/fts5config.test | 202 ++++++++++++++++++++++++++++++++++ ext/fts5/test/fts5ea.test | 2 +- ext/fts5/test/fts5fault2.test | 19 ++++ ext/fts5/test/fts5fault4.test | 14 +++ ext/fts5/test/fts5merge.test | 2 +- ext/fts5/test/fts5near.test | 2 +- ext/fts5/test/fts5vocab.test | 31 ++++-- manifest | 39 +++---- manifest.uuid | 2 +- 17 files changed, 423 insertions(+), 147 deletions(-) create mode 100644 ext/fts5/test/fts5config.test diff --git a/ext/fts5/fts5.h b/ext/fts5/fts5.h index 28be0de676..7782bf697c 100644 --- a/ext/fts5/fts5.h +++ b/ext/fts5/fts5.h @@ -203,8 +203,9 @@ struct Fts5ExtensionApi { ** ** Applications may also register custom tokenizer types. A tokenizer ** is registered by providing fts5 with a populated instance of the -** following structure. The structure methods are expected to function -** as follows: +** following structure. All structure methods must be defined, setting +** any member of the fts5_tokenizer struct to NULL leads to undefined +** behaviour. The structure methods are expected to function as follows: ** ** xCreate: ** This function is used to allocate and inititalize a tokenizer instance. diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h index 3c84c9ed2a..2a66fd8b18 100644 --- a/ext/fts5/fts5Int.h +++ b/ext/fts5/fts5Int.h @@ -226,6 +226,9 @@ int sqlite3Fts5PoslistNext64( void *sqlite3Fts5MallocZero(int *pRc, int nByte); char *sqlite3Fts5Strndup(int *pRc, const char *pIn, int nIn); +/* Character set tests (like isspace(), isalpha() etc.) */ +int sqlite3Fts5IsBareword(char t); + /* ** End of interface to code in fts5_buffer.c. **************************************************************************/ diff --git a/ext/fts5/fts5_buffer.c b/ext/fts5/fts5_buffer.c index dbe51fafc4..24e7d8f65f 100644 --- a/ext/fts5/fts5_buffer.c +++ b/ext/fts5/fts5_buffer.c @@ -264,5 +264,31 @@ char *sqlite3Fts5Strndup(int *pRc, const char *pIn, int nIn){ } return zRet; } + + +/* +** Return true if character 't' may be part of an FTS5 bareword, or false +** otherwise. Characters that may be part of barewords: +** +** * All non-ASCII characters, +** * The 52 upper and lower case ASCII characters, and +** * The 10 integer ASCII characters. +** * The underscore character "_" (0x5F). +*/ +int sqlite3Fts5IsBareword(char t){ + u8 aBareword[128] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 .. 0x0F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 .. 0x1F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 .. 0x2F */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x30 .. 0x3F */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 .. 0x4F */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x50 .. 0x5F */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60 .. 0x6F */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 /* 0x70 .. 0x7F */ + }; + + return (t & 0x80) || aBareword[(int)t]; +} + #endif /* SQLITE_ENABLE_FTS5 */ diff --git a/ext/fts5/fts5_config.c b/ext/fts5/fts5_config.c index 90d7b7318f..4b35ac8b2c 100644 --- a/ext/fts5/fts5_config.c +++ b/ext/fts5/fts5_config.c @@ -53,12 +53,7 @@ static const char *fts5ConfigSkipWhitespace(const char *pIn){ */ static const char *fts5ConfigSkipBareword(const char *pIn){ const char *p = pIn; - while( *p && *p!=' ' && *p!=':' && *p!='!' && *p!='@' - && *p!='#' && *p!='$' && *p!='%' && *p!='^' && *p!='&' - && *p!='*' && *p!='(' && *p!=')' && *p!='=' - ){ - p++; - } + while ( sqlite3Fts5IsBareword(*p) ) p++; if( p==pIn ) p = 0; return p; } @@ -71,64 +66,62 @@ static int fts5_isdigit(char a){ static const char *fts5ConfigSkipLiteral(const char *pIn){ const char *p = pIn; - if( p ){ - switch( *p ){ - case 'n': case 'N': - if( sqlite3_strnicmp("null", p, 4)==0 ){ - p = &p[4]; + switch( *p ){ + case 'n': case 'N': + if( sqlite3_strnicmp("null", p, 4)==0 ){ + p = &p[4]; + }else{ + p = 0; + } + break; + + case 'x': case 'X': + p++; + if( *p=='\'' ){ + p++; + while( (*p>='a' && *p<='f') + || (*p>='A' && *p<='F') + || (*p>='0' && *p<='9') + ){ + p++; + } + if( *p=='\'' && 0==((p-pIn)%2) ){ + p++; }else{ p = 0; } - break; - - case 'x': case 'X': - p++; + }else{ + p = 0; + } + break; + + case '\'': + p++; + while( p ){ if( *p=='\'' ){ p++; - while( (*p>='a' && *p<='f') - || (*p>='A' && *p<='F') - || (*p>='0' && *p<='9') - ){ - p++; - } - if( *p=='\'' && 0==((p-pIn)%2) ){ - p++; - }else{ - p = 0; - } - }else{ - p = 0; + if( *p!='\'' ) break; } - break; - - case '\'': p++; - while( p ){ - if( *p=='\'' ){ - p++; - if( *p!='\'' ) break; - } - p++; - if( *p==0 ) p = 0; - } - break; + if( *p==0 ) p = 0; + } + break; - default: - /* maybe a number */ - if( *p=='+' || *p=='-' ) p++; + default: + /* maybe a number */ + if( *p=='+' || *p=='-' ) p++; + while( fts5_isdigit(*p) ) p++; + + /* At this point, if the literal was an integer, the parse is + ** finished. Or, if it is a floating point value, it may continue + ** with either a decimal point or an 'E' character. */ + if( *p=='.' && fts5_isdigit(p[1]) ){ + p += 2; while( fts5_isdigit(*p) ) p++; + } + if( p==pIn ) p = 0; - /* At this point, if the literal was an integer, the parse is - ** finished. Or, if it is a floating point value, it may continue - ** with either a decimal point or an 'E' character. */ - if( *p=='.' && fts5_isdigit(p[1]) ){ - p += 2; - while( fts5_isdigit(*p) ) p++; - } - if( p==pIn ) p = 0; - - break; - } + break; } return p; @@ -157,12 +150,12 @@ static int fts5Dequote(char *z){ assert( q=='[' || q=='\'' || q=='"' || q=='`' ); if( q=='[' ) q = ']'; - while( z[iIn] ){ + while( ALWAYS(z[iIn]) ){ if( z[iIn]==q ){ if( z[iIn+1]!=q ){ /* Character iIn was the close quote. */ - z[iOut] = '\0'; - return iIn+1; + iIn++; + break; }else{ /* Character iIn and iIn+1 form an escaped quote character. Skip ** the input cursor past both and copy a single quote character @@ -175,9 +168,8 @@ static int fts5Dequote(char *z){ } } - /* Did not find the close-quote character. Return -1. */ z[iOut] = '\0'; - return -1; + return iIn; } /* @@ -270,7 +262,7 @@ static int fts5ConfigParseSpecial( }else{ for(nArg=0; p && *p; nArg++){ const char *p2 = fts5ConfigSkipWhitespace(p); - if( p2 && *p2=='\'' ){ + if( *p2=='\'' ){ p = fts5ConfigSkipLiteral(p2); }else{ p = fts5ConfigSkipBareword(p2); @@ -369,32 +361,32 @@ static const char *fts5ConfigGobbleWord( int *pbQuoted /* OUT: Set to true if dequoting required */ ){ const char *zRet = 0; + + int nIn = strlen(zIn); + char *zOut = sqlite3_malloc(nIn+1); + + assert( *pRc==SQLITE_OK ); *pbQuoted = 0; *pzOut = 0; - if( *pRc==SQLITE_OK ){ - int nIn = strlen(zIn); - char *zOut = sqlite3_malloc(nIn+1); - - if( zOut==0 ){ - *pRc = SQLITE_NOMEM; + if( zOut==0 ){ + *pRc = SQLITE_NOMEM; + }else{ + memcpy(zOut, zIn, nIn+1); + if( fts5_isopenquote(zOut[0]) ){ + int ii = fts5Dequote(zOut); + zRet = &zIn[ii]; + *pbQuoted = 1; }else{ - memcpy(zOut, zIn, nIn+1); - if( fts5_isopenquote(zOut[0]) ){ - int ii = fts5Dequote(zOut); - if( ii>0 ) zRet = &zIn[ii]; - *pbQuoted = 1; - }else{ - zRet = fts5ConfigSkipBareword(zIn); - zOut[zRet-zIn] = '\0'; - } + zRet = fts5ConfigSkipBareword(zIn); + zOut[zRet-zIn] = '\0'; } + } - if( zRet==0 ){ - sqlite3_free(zOut); - }else{ - *pzOut = zOut; - } + if( zRet==0 ){ + sqlite3_free(zOut); + }else{ + *pzOut = zOut; } return zRet; @@ -569,7 +561,7 @@ int sqlite3Fts5ConfigParse( void sqlite3Fts5ConfigFree(Fts5Config *pConfig){ if( pConfig ){ int i; - if( pConfig->pTok && pConfig->pTokApi->xDelete ){ + if( pConfig->pTok ){ pConfig->pTokApi->xDelete(pConfig->pTok); } sqlite3_free(pConfig->zDb); @@ -727,7 +719,7 @@ int sqlite3Fts5ConfigParseRank( p = fts5ConfigSkipArgs(p); if( p==0 ){ rc = SQLITE_ERROR; - }else if( p!=pArgs ){ + }else{ zRankArgs = sqlite3Fts5MallocZero(&rc, 1 + p - pArgs); if( zRankArgs ) memcpy(zRankArgs, pArgs, p-pArgs); } @@ -751,17 +743,14 @@ int sqlite3Fts5ConfigSetValue( int *pbBadkey ){ int rc = SQLITE_OK; - if( 0==sqlite3_stricmp(zKey, "cookie") ){ - pConfig->iCookie = sqlite3_value_int(pVal); - } - else if( 0==sqlite3_stricmp(zKey, "pgsz") ){ + if( 0==sqlite3_stricmp(zKey, "pgsz") ){ int pgsz = 0; if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){ pgsz = sqlite3_value_int(pVal); } if( pgsz<=0 || pgsz>FTS5_MAX_PAGE_SIZE ){ - if( pbBadkey ) *pbBadkey = 1; + *pbBadkey = 1; }else{ pConfig->pgsz = pgsz; } @@ -773,7 +762,7 @@ int sqlite3Fts5ConfigSetValue( nAutomerge = sqlite3_value_int(pVal); } if( nAutomerge<0 || nAutomerge>64 ){ - if( pbBadkey ) *pbBadkey = 1; + *pbBadkey = 1; }else{ if( nAutomerge==1 ) nAutomerge = FTS5_DEFAULT_AUTOMERGE; pConfig->nAutomerge = nAutomerge; @@ -786,7 +775,7 @@ int sqlite3Fts5ConfigSetValue( nCrisisMerge = sqlite3_value_int(pVal); } if( nCrisisMerge<0 ){ - if( pbBadkey ) *pbBadkey = 1; + *pbBadkey = 1; }else{ if( nCrisisMerge<=1 ) nCrisisMerge = FTS5_DEFAULT_CRISISMERGE; pConfig->nCrisisMerge = nCrisisMerge; @@ -805,10 +794,10 @@ int sqlite3Fts5ConfigSetValue( pConfig->zRankArgs = zRankArgs; }else if( rc==SQLITE_ERROR ){ rc = SQLITE_OK; - if( pbBadkey ) *pbBadkey = 1; + *pbBadkey = 1; } }else{ - if( pbBadkey ) *pbBadkey = 1; + *pbBadkey = 1; } return rc; } @@ -844,10 +833,11 @@ int sqlite3Fts5ConfigLoad(Fts5Config *pConfig, int iCookie){ if( 0==sqlite3_stricmp(zK, "version") ){ iVersion = sqlite3_value_int(pVal); }else{ - sqlite3Fts5ConfigSetValue(pConfig, zK, pVal, 0); + int bDummy = 0; + sqlite3Fts5ConfigSetValue(pConfig, zK, pVal, &bDummy); } } - if( rc==SQLITE_OK ) rc = sqlite3_finalize(p); + rc = sqlite3_finalize(p); } if( rc==SQLITE_OK && iVersion!=FTS5_CURRENT_VERSION ){ diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index 3446c3e543..e0496fb8d2 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -117,12 +117,6 @@ static int fts5ExprIsspace(char t){ return t==' ' || t=='\t' || t=='\n' || t=='\r'; } -static int fts5ExprIstoken(char t){ - return fts5ExprIsspace(t)==0 && t!='\0' - && t!=':' && t!='(' && t!=')' - && t!=',' && t!='+' && t!='*'; -} - /* ** Read the first token from the nul-terminated string at *pz. */ @@ -169,7 +163,7 @@ static int fts5ExprGetToken( default: { const char *z2; tok = FTS5_STRING; - for(z2=&z[1]; fts5ExprIstoken(*z2); z2++); + for(z2=&z[1]; sqlite3Fts5IsBareword(*z2); z2++); pToken->n = (z2 - z); if( pToken->n==2 && memcmp(pToken->p, "OR", 2)==0 ) tok = FTS5_OR; if( pToken->n==3 && memcmp(pToken->p, "NOT", 3)==0 ) tok = FTS5_NOT; diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index f9317ddd66..dd0f42fa30 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -5566,20 +5566,6 @@ static void fts5RowidFunction( iRowid = FTS5_SEGMENT_ROWID(segid, height, pgno); sqlite3_result_int64(pCtx, iRowid); } -#if 0 - }else if( 0==sqlite3_stricmp(zArg, "start-of-index") ){ - i64 iRowid; - int idx; - if( nArg!=2 ){ - sqlite3_result_error(pCtx, - "should be: fts5_rowid('start-of-index', idx)", -1 - ); - }else{ - idx = sqlite3_value_int(apVal[1]); - iRowid = FTS5_SEGMENT_ROWID(idx, 1, 0, 0); - sqlite3_result_int64(pCtx, iRowid); - } -#endif }else { sqlite3_result_error(pCtx, "first arg to fts5_rowid() must be 'segment' " diff --git a/ext/fts5/fts5_vocab.c b/ext/fts5/fts5_vocab.c index ee2a316291..6d03877ad0 100644 --- a/ext/fts5/fts5_vocab.c +++ b/ext/fts5/fts5_vocab.c @@ -189,6 +189,8 @@ static int fts5VocabInitVtab( pRet->zFts5Db = &pRet->zFts5Tbl[nTab]; memcpy(pRet->zFts5Tbl, zTab, nTab); memcpy(pRet->zFts5Db, zDb, nDb); + sqlite3Fts5Dequote(pRet->zFts5Tbl); + sqlite3Fts5Dequote(pRet->zFts5Db); } } diff --git a/ext/fts5/test/fts5aa.test b/ext/fts5/test/fts5aa.test index 559a5a1256..028eece68a 100644 --- a/ext/fts5/test/fts5aa.test +++ b/ext/fts5/test/fts5aa.test @@ -285,6 +285,9 @@ do_catchsql_test 11.1 { do_catchsql_test 11.2 { CREATE VIRTUAL TABLE rank USING fts5(a, b, c); } {1 {reserved fts5 table name: rank}} +do_catchsql_test 11.3 { + CREATE VIRTUAL TABLE t2 USING fts5(a, b, c, rowid); +} {1 {reserved fts5 column name: rowid}} #------------------------------------------------------------------------- # @@ -377,6 +380,26 @@ do_catchsql_test 15.2 { INSERT INTO t1(t1) VALUES('integrity-check'); } {1 {database disk image is malformed}} +#------------------------------------------------------------------------- +# +do_execsql_test 16.1 { + CREATE VIRTUAL TABLE n1 USING fts5(a); + INSERT INTO n1 VALUES('a b c d'); +} + +proc funk {} { + set fd [db incrblob main n1_data block 10] + fconfigure $fd -encoding binary -translation binary + puts -nonewline $fd "\x44\x45" + close $fd + db eval { UPDATE n1_config SET v=50 WHERE k='version' } +} +db func funk funk + +do_catchsql_test 16.2 { + SELECT funk(), bm25(n1), funk() FROM n1 WHERE n1 MATCH 'a+b+c+d' +} {1 {SQL logic error or missing database}} + finish_test diff --git a/ext/fts5/test/fts5config.test b/ext/fts5/test/fts5config.test new file mode 100644 index 0000000000..22e7631bc0 --- /dev/null +++ b/ext/fts5/test/fts5config.test @@ -0,0 +1,202 @@ +# 2015 Jan 13 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file focuses on the code in fts5_config.c, which is largely concerned +# with parsing the various configuration and CREATE TABLE options. +# + +source [file join [file dirname [info script]] fts5_common.tcl] +set testprefix fts5config + +#------------------------------------------------------------------------- +# Try different types of quote characters. +# +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE t1 USING fts5('a', "b", [c], `d`); + PRAGMA table_info = t1; +} { + 0 a {} 0 {} 0 + 1 b {} 0 {} 0 + 2 c {} 0 {} 0 + 3 d {} 0 {} 0 +} + +#------------------------------------------------------------------------- +# Syntax errors in the prefix= option. +# +foreach {tn opt} { + 1 {prefix=x} + 2 {prefix='x'} + 3 {prefix='$'} +} { + set res [list 1 {malformed prefix=... directive}] + do_catchsql_test 2.$tn "CREATE VIRTUAL TABLE f1 USING fts5(x, $opt)" $res +} + +#------------------------------------------------------------------------- +# Syntax errors in the 'rank' option. +# +foreach {tn val} { + 1 "f1(xyz)" + 2 "f1(zyx)" + 3 "f1(nzz)" + 4 "f1(x'!!')" + 5 "f1(x':;')" + 6 "f1(x'[]')" + 7 "f1(x'{}')" + 8 "f1('abc)" +} { + do_catchsql_test 3.$tn { + INSERT INTO t1(t1, rank) VALUES('rank', $val); + } {1 {SQL logic error or missing database}} +} + +#------------------------------------------------------------------------- +# The parsing of SQL literals specified as part of 'rank' options. +# +do_execsql_test 4.0 { + CREATE VIRTUAL TABLE zzz USING fts5(one); + INSERT INTO zzz VALUES('a b c'); +} +proc first {cmd A} { return $A } +sqlite3_fts5_create_function db first first + +foreach {tn arg} { + 1 "123" + 2 "'01234567890ABCDEF'" + 3 "x'0123'" + 4 "x'ABCD'" + 5 "x'0123456789ABCDEF'" + 6 "x'0123456789abcdef'" + 7 "22.5" + 8 "-91.5" + 9 "-.5" + 10 "''''" + 11 "+.5" +} { + set func [string map {' ''} "first($arg)"] + do_execsql_test 4.1.$tn " + INSERT INTO zzz(zzz, rank) VALUES('rank', '$func'); + SELECT rank IS $arg FROM zzz WHERE zzz MATCH 'a + b + c' + " 1 +} + +do_execsql_test 4.2 { + INSERT INTO zzz(zzz, rank) VALUES('rank', 'f1()'); +} {} + +#------------------------------------------------------------------------- +# Misquoting in tokenize= and other options. +# +do_catchsql_test 5.1 { + CREATE VIRTUAL TABLE xx USING fts5(x, tokenize="porter 'ascii"); +} {1 {parse error in tokenize directive}} + +breakpoint +do_catchsql_test 5.2 { + CREATE VIRTUAL TABLE xx USING fts5(x, [y[]); +} {0 {}} + +do_catchsql_test 5.3 { + CREATE VIRTUAL TABLE yy USING fts5(x, [y]]); +} {1 {unrecognized token: "]"}} + +#------------------------------------------------------------------------- +# Errors in prefix= directives. +# +do_catchsql_test 6.1 { + CREATE VIRTUAL TABLE abc USING fts5(a, prefix=1, prefix=2); +} {1 {multiple prefix=... directives}} +do_catchsql_test 6.2 { + CREATE VIRTUAL TABLE abc USING fts5(a, prefix='1, 2, 1001'); +} {1 {prefix length out of range: 1001}} +do_catchsql_test 6.3 { + CREATE VIRTUAL TAbLE abc USING fts5(a, prefix='1, 2, 0000'); +} {1 {prefix length out of range: 0}} +do_catchsql_test 6.4 { + CREATE VIRTUAL TABLE abc USING fts5(a, prefix='1 , 1000000'); +} {1 {malformed prefix=... directive}} + +#------------------------------------------------------------------------- +# Duplicate tokenize= and other options. +# +do_catchsql_test 7.1 { + CREATE VIRTUAL TABLE abc USING fts5(a, tokenize=porter, tokenize=ascii); +} {1 {multiple tokenize=... directives}} +do_catchsql_test 7.2 { + CREATE VIRTUAL TABLE abc USING fts5(a, content=porter, content=ascii); +} {1 {multiple content=... directives}} +do_catchsql_test 7.3 { + CREATE VIRTUAL TABLE abc USING fts5(a, content_rowid=porter, content_rowid=a); +} {1 {multiple content_rowid=... directives}} + +#------------------------------------------------------------------------- +# Unrecognized option. +# +do_catchsql_test 8.0 { + CREATE VIRTUAL TABLE abc USING fts5(a, nosuchoption=123); +} {1 {unrecognized option: "nosuchoption"}} +do_catchsql_test 8.1 { + CREATE VIRTUAL TABLE abc USING fts5(a, "nosuchoption"=123); +} {1 {parse error in ""nosuchoption"=123"}} + +#------------------------------------------------------------------------- +# Errors in: +# +# 9.1.* 'pgsz' options. +# 9.2.* 'automerge' options. +# 9.3.* 'crisismerge' options. +# +do_execsql_test 9.0 { + CREATE VIRTUAL TABLE abc USING fts5(a, b); +} {} +do_catchsql_test 9.1.1 { + INSERT INTO abc(abc, rank) VALUES('pgsz', -5); +} {1 {SQL logic error or missing database}} +do_catchsql_test 9.1.2 { + INSERT INTO abc(abc, rank) VALUES('pgsz', 50000000); +} {1 {SQL logic error or missing database}} +do_catchsql_test 9.1.3 { + INSERT INTO abc(abc, rank) VALUES('pgsz', 66.67); +} {1 {SQL logic error or missing database}} + +do_catchsql_test 9.2.1 { + INSERT INTO abc(abc, rank) VALUES('automerge', -5); +} {1 {SQL logic error or missing database}} +do_catchsql_test 9.2.2 { + INSERT INTO abc(abc, rank) VALUES('automerge', 50000000); +} {1 {SQL logic error or missing database}} +do_catchsql_test 9.2.3 { + INSERT INTO abc(abc, rank) VALUES('automerge', 66.67); +} {1 {SQL logic error or missing database}} +do_execsql_test 9.2.4 { + INSERT INTO abc(abc, rank) VALUES('automerge', 1); +} {} + +do_catchsql_test 9.3.1 { + INSERT INTO abc(abc, rank) VALUES('crisismerge', -5); +} {1 {SQL logic error or missing database}} +do_catchsql_test 9.3.2 { + INSERT INTO abc(abc, rank) VALUES('crisismerge', 66.67); +} {1 {SQL logic error or missing database}} +do_execsql_test 9.3.3 { + INSERT INTO abc(abc, rank) VALUES('crisismerge', 1); +} {} +do_execsql_test 9.3.4 { + INSERT INTO abc(abc, rank) VALUES('crisismerge', 50000000); +} {} + +do_catchsql_test 9.4.1 { + INSERT INTO abc(abc, rank) VALUES('nosuchoption', 1); +} {1 {SQL logic error or missing database}} + +finish_test + diff --git a/ext/fts5/test/fts5ea.test b/ext/fts5/test/fts5ea.test index b80e767b63..3929ed9f59 100644 --- a/ext/fts5/test/fts5ea.test +++ b/ext/fts5/test/fts5ea.test @@ -74,7 +74,7 @@ foreach {tn expr err} { 11 {a AND "abc} {unterminated string} 12 {NEAR(a b, xyz)} {expected integer, got "xyz"} - 13 {NEAR(a b, // )} {expected integer, got "//"} + 13 {NEAR(a b, // )} {fts5: syntax error near "/"} } { do_catchsql_test 3.$tn {SELECT fts5_expr($expr, 'name', 'addr')} [list 1 $err] } diff --git a/ext/fts5/test/fts5fault2.test b/ext/fts5/test/fts5fault2.test index 9bf9b85e2b..ef1df8826a 100644 --- a/ext/fts5/test/fts5fault2.test +++ b/ext/fts5/test/fts5fault2.test @@ -117,5 +117,24 @@ do_faultsim_test 4.1 -faults oom-trans* -prep { faultsim_test_result {0 {}} } +#------------------------------------------------------------------------- +# OOM while parsing a tokenize=option +# +reset_db +faultsim_save_and_close +do_faultsim_test 5.0 -faults oom-* -prep { + faultsim_restore_and_reopen +} -body { + execsql { + CREATE VIRTUAL TABLE uio USING fts5(a, b, + tokenize="porter 'ascii'", + content="another table", + content_rowid="somecolumn" + ); + } +} -test { + faultsim_test_result {0 {}} +} + finish_test diff --git a/ext/fts5/test/fts5fault4.test b/ext/fts5/test/fts5fault4.test index b22407c5cb..f160a84ba3 100644 --- a/ext/fts5/test/fts5fault4.test +++ b/ext/fts5/test/fts5fault4.test @@ -326,6 +326,20 @@ do_faultsim_test 10.3 -faults oom-t* -body { faultsim_test_result {0 {x : "a"}} } +#------------------------------------------------------------------------- +# OOM while configuring 'rank' option. +# +reset_db +do_execsql_test 11.0 { + CREATE VIRTUAL TABLE ft USING fts5(x); +} +do_faultsim_test 11.1 -faults oom-* -body { + db eval { + INSERT INTO ft(ft, rank) VALUES('rank', 'bm25(10.0, 5.0)'); + } +} -test { + faultsim_test_result {0 {}} +} finish_test diff --git a/ext/fts5/test/fts5merge.test b/ext/fts5/test/fts5merge.test index d869c6cedb..023a2f7fe8 100644 --- a/ext/fts5/test/fts5merge.test +++ b/ext/fts5/test/fts5merge.test @@ -181,7 +181,7 @@ foreach {tn pgsz} { } $expect break } - db eval {SELECT fts5_decode(rowid, block) AS r FROM x8_data} { puts $r } +# db eval {SELECT fts5_decode(rowid, block) AS r FROM x8_data} { puts $r } } finish_test diff --git a/ext/fts5/test/fts5near.test b/ext/fts5/test/fts5near.test index f545447e6f..dffce29431 100644 --- a/ext/fts5/test/fts5near.test +++ b/ext/fts5/test/fts5near.test @@ -24,7 +24,7 @@ proc do_near_test {tn doc near res} { } execsql { - CREATE VIRTUAL TABLE t1 USING fts5(x, tokenize = 'ascii tokenchars .') + CREATE VIRTUAL TABLE t1 USING fts5(x, tokenize = "ascii tokenchars '.'") } do_near_test 1.1 ". . a . . . b . ." { NEAR(a b, 5) } 1 diff --git a/ext/fts5/test/fts5vocab.test b/ext/fts5/test/fts5vocab.test index b61db67d7b..fcef2b793d 100644 --- a/ext/fts5/test/fts5vocab.test +++ b/ext/fts5/test/fts5vocab.test @@ -82,9 +82,9 @@ do_execsql_test 2.0 { INSERT INTO tt VALUES('g d e f d e', 'a c d b a g'); INSERT INTO tt VALUES('e f a c c b', 'b f e a f d y'); INSERT INTO tt VALUES('c c a a c f', 'd g a e b g'); - CREATE VIRTUAL TABLE tv USING fts5vocab(tt, 'col'); - SELECT * FROM tv; -} { +} + +set res_col { a 0 6 11 a 1 7 9 b 0 6 7 b 1 7 7 c 0 6 12 c 1 5 8 @@ -94,16 +94,31 @@ do_execsql_test 2.0 { g 0 5 7 g 1 5 7 x 0 1 1 y 1 1 1 } - -do_execsql_test 2.1 { - CREATE VIRTUAL TABLE temp.tv2 USING fts5vocab(main, tt, 'row'); - SELECT * FROM tv2; -} { +set res_row { a 10 20 b 9 14 c 9 20 d 9 19 e 8 13 f 10 20 g 7 14 x 1 1 y 1 1 } +foreach {tn tbl resname} { + 1 "fts5vocab(tt, 'col')" res_col + 2 "fts5vocab(tt, 'row')" res_row + 3 "fts5vocab(tt, \"row\")" res_row + 4 "fts5vocab(tt, [row])" res_row + 5 "fts5vocab(tt, `row`)" res_row + + 6 "fts5vocab('tt', 'row')" res_row + 7 "fts5vocab(\"tt\", \"row\")" res_row + 8 "fts5vocab([tt], [row])" res_row + 9 "fts5vocab(`tt`, `row`)" res_row +} { + do_execsql_test 2.$tn " + DROP TABLE IF EXISTS tv; + CREATE VIRTUAL TABLE tv USING $tbl; + SELECT * FROM tv; + " [set $resname] +} + #------------------------------------------------------------------------- # foreach {tn sql} { diff --git a/manifest b/manifest index a0e7897b83..4488ddf4f5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\stest\scoverage\simprovements\sfor\sfts5. -D 2015-05-16T20:04:43.177 +C Improve\stest\scoverage\sof\sfts5_config.c. +D 2015-05-18T17:50:17.248 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in edfc69769e613a6359c42c06ea1d42c3bece1736 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -105,23 +105,23 @@ F ext/fts3/unicode/UnicodeData.txt cd07314edb62d49fde34debdaf92fa2aa69011e7 F ext/fts3/unicode/mkunicode.tcl 159c1194da0bc72f51b3c2eb71022568006dc5ad F ext/fts5/extract_api_docs.tcl 55a6d648d516f35d9a1e580ac00de27154e1904a F ext/fts5/fts5.c 74d18b4dc7518c7cd85609f1541e83bc564619a2 -F ext/fts5/fts5.h 24a2cc35b5e76eec57b37ba48c12d9d2cb522b3a -F ext/fts5/fts5Int.h e01aec94c0d927924134c30afd9803425cd88812 +F ext/fts5/fts5.h 4266c6231094005b051dbfc8dd85d2bc57243d34 +F ext/fts5/fts5Int.h 9e581dc077d4c6758eaeb0d6a85dc875f53918dc F ext/fts5/fts5_aux.c d53f00f31ad615ca4f139dd8751f9041afa00971 -F ext/fts5/fts5_buffer.c 70b971e13503566f1e257941c60817ba0920a16b -F ext/fts5/fts5_config.c 05811f0bd80c396afcf3ceea68da16149a9a3258 -F ext/fts5/fts5_expr.c a88af159ce5dcc44d7262ea80865ffc8e4ab2143 +F ext/fts5/fts5_buffer.c 861599a0abe2383f0cd0352c57001140a26b0930 +F ext/fts5/fts5_config.c 11f969ed711a0a8b611d47431d74c372ad78c713 +F ext/fts5/fts5_expr.c 0c4b50bb48740c76b8e8b89d5d40a55f8dbffd07 F ext/fts5/fts5_hash.c 54dd25348a46ea62ea96322c572e08cd1fb37304 -F ext/fts5/fts5_index.c 6e0ac5835ab33a2cf97efd591acd4fc130490e0f +F ext/fts5/fts5_index.c 2c4500c35072b049d1391bbb4e64e4c0e3d3dd43 F ext/fts5/fts5_storage.c cb8b585bfb7870a36101f1a8fa0b0777f4d1b68d F ext/fts5/fts5_tcl.c f18eeb125d733f4e815a11679b971fa61cd7ec77 F ext/fts5/fts5_tokenize.c 830eae0d35a5a5a90af34df65da3427f46d942fc F ext/fts5/fts5_unicode2.c f74f53316377068812a1fa5a37819e6b8124631d -F ext/fts5/fts5_vocab.c e532f38a62d27fa662138a6cf33890b314225506 +F ext/fts5/fts5_vocab.c b54301e376f59f08f662b5dde1cfaf26e86e4db6 F ext/fts5/fts5parse.y 777da8e5819f75c217982c79c29d014c293acac9 F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba F ext/fts5/test/fts5_common.tcl d9ea79fdbc9ecbb3541bf89d13ee0e03a8dc3d32 -F ext/fts5/test/fts5aa.test 5f221b82487abfb915e1b040eb4e305cf79a2ef5 +F ext/fts5/test/fts5aa.test 29409f14dec2ee67bd82ebf15111d6167b1003df F ext/fts5/test/fts5ab.test 6fe3a56731d15978afbb74ae51b355fc9310f2ad F ext/fts5/test/fts5ac.test 05008e00bd2761cc45df838a0988ecf318cbe1fd F ext/fts5/test/fts5ad.test 2141b0360dc4397bfed30f0b0d700fa64b44835d @@ -136,24 +136,25 @@ F ext/fts5/test/fts5al.test fc60ebeac9d8e366e71309d4c31fa72199d711d7 F ext/fts5/test/fts5aux.test d9cd26ee45ad5f628b4899f1ac5b757ce7a77bdf F ext/fts5/test/fts5auxdata.test c69b86092bf1a157172de5f9169731af3403179b F ext/fts5/test/fts5bigpl.test b1cfd00561350ab04994ba7dd9d48468e5e0ec3b +F ext/fts5/test/fts5config.test c9cc535f3b36cde1e5a32bf579f3f5962a9e82b2 F ext/fts5/test/fts5content.test 532e15b541254410adc7bfb51f94631cfe82de8f F ext/fts5/test/fts5corrupt.test 35bfdbbb3cdcea46ae7385f6432e9b5c574e70a1 F ext/fts5/test/fts5corrupt2.test 7000030df189f1f3ca58b555b459bcbf9b8f8f77 F ext/fts5/test/fts5corrupt3.test fe42c0ce0b58b7ad487a469049f91419d22c7459 F ext/fts5/test/fts5dlidx.test 070531bd45685e545e3e6021deb543f730a4011b F ext/fts5/test/fts5doclist.test 635b80ac785627841a59c583bac702b55d49fdc5 -F ext/fts5/test/fts5ea.test ed163ed820fd503354bd7dcf9d3b0e3801ade962 +F ext/fts5/test/fts5ea.test c2f33a33d307b2d38e29f66323a67b7af0b082ea F ext/fts5/test/fts5eb.test 728a1f23f263548f5c29b29dfb851b5f2dbe723e F ext/fts5/test/fts5fault1.test b42d3296be8a75f557cf2cbce0d8b483fc9db45b -F ext/fts5/test/fts5fault2.test 26c3d70648f691e2cc9391e14bbc11a973656383 +F ext/fts5/test/fts5fault2.test 28c36c843bb39ae855ba79827417ecc37f114341 F ext/fts5/test/fts5fault3.test d6e9577d4312e331a913c72931bf131704efc8f3 -F ext/fts5/test/fts5fault4.test 6e5b1609a0e7d51e7598fa675db581b3b1bfbf7e +F ext/fts5/test/fts5fault4.test 7301602e916261f0b277ed93f447fd871d5d7064 F ext/fts5/test/fts5fault5.test 98e7e77bc1d8bb47c955e7d6dc870ab5736536e3 F ext/fts5/test/fts5full.test 0924bdca5416a242103239ace79c6f5aa34bab8d F ext/fts5/test/fts5hash.test bdba7b591d503005d5a81871ba00a359daa1e969 F ext/fts5/test/fts5integrity.test 98801bd0fb7c53a40bc770280134865d61724f3a -F ext/fts5/test/fts5merge.test b985b6891e093a4b4c3c9683fe3cba7498fed690 -F ext/fts5/test/fts5near.test 3f9f64e16cac82725d03d4e04c661090f0b3b947 +F ext/fts5/test/fts5merge.test 8077454f2975a63f35761f4b8a718b3a808b7c9c +F ext/fts5/test/fts5near.test d2e3343e62d438f2efd96ebcd83a0d30a16ea6dc F ext/fts5/test/fts5optimize.test 0028c90a7817d3e576d1148fc8dff17d89054e54 F ext/fts5/test/fts5plan.test 89783f70dab89ff936ed6f21d88959b49c853a47 F ext/fts5/test/fts5porter.test 50322599823cb8080a99f0ec0c39f7d0c12bcb5e @@ -167,7 +168,7 @@ F ext/fts5/test/fts5unicode.test 79b3e34eb29ce4929628aa514a40cb467fdabe4d F ext/fts5/test/fts5unicode2.test 64a5267fd6082fcb46439892ebd0cbaa5c38acee F ext/fts5/test/fts5unindexed.test f388605341a476b6ab622b4c267cd168f59a5944 F ext/fts5/test/fts5version.test dc34a735af6625a1a7a4a916a38d122071343887 -F ext/fts5/test/fts5vocab.test 2d1bddfb6e1effd9e1d2f5d1d25bf05e9ab33e64 +F ext/fts5/test/fts5vocab.test 80fb22850dd3b2c92a3896e6021605e08c0872aa F ext/fts5/tool/loadfts5.tcl add4d349ae5463c5f60b26e821c24e60ed8054d3 F ext/fts5/tool/showfts5.tcl 921f33b30c3189deefd2b2cc81f951638544aaf1 F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43 @@ -1326,7 +1327,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 7aea8c6d99737c6c72078e0b4b9c5f8186021aa0 -R 5014cf90f97a250385093a02a58cfb68 +P 927d9a64e13c6b768f0a15475713192fcfaaf9e7 +R 820e0577a96c7901c9b911f2b08f8e07 U dan -Z e8178e8c15c67776f9bff619db326cbd +Z b644c576eadef53c3df6a681b5fdaf76 diff --git a/manifest.uuid b/manifest.uuid index 5f3b901b63..c5cb986583 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -927d9a64e13c6b768f0a15475713192fcfaaf9e7 \ No newline at end of file +47dbfadb994814c9349d4c9c113b862c2e97c01a \ No newline at end of file