diff --git a/ext/fts5/fts5_config.c b/ext/fts5/fts5_config.c index 4f6272dbe2..6b0e2b28b6 100644 --- a/ext/fts5/fts5_config.c +++ b/ext/fts5/fts5_config.c @@ -216,34 +216,53 @@ static int fts5ConfigParseSpecial( if( sqlite3_strnicmp("prefix", zCmd, nCmd)==0 ){ const int nByte = sizeof(int) * FTS5_MAX_PREFIX_INDEXES; const char *p; - if( pConfig->aPrefix ){ - *pzErr = sqlite3_mprintf("multiple prefix=... directives"); - rc = SQLITE_ERROR; - }else{ + int bFirst = 1; + if( pConfig->aPrefix==0 ){ pConfig->aPrefix = sqlite3Fts5MallocZero(&rc, nByte); + if( rc ) return rc; } + p = zArg; - while( rc==SQLITE_OK && p[0] ){ + while( 1 ){ int nPre = 0; + while( p[0]==' ' ) p++; + if( bFirst==0 && p[0]==',' ){ + p++; + while( p[0]==' ' ) p++; + }else if( p[0]=='\0' ){ + break; + } + if( p[0]<'0' || p[0]>'9' ){ + *pzErr = sqlite3_mprintf("malformed prefix=... directive"); + rc = SQLITE_ERROR; + break; + } + + if( pConfig->nPrefix==FTS5_MAX_PREFIX_INDEXES ){ + *pzErr = sqlite3_mprintf( + "too many prefix indexes (max %d)", FTS5_MAX_PREFIX_INDEXES + ); + rc = SQLITE_ERROR; + break; + } + while( p[0]>='0' && p[0]<='9' && nPre<1000 ){ nPre = nPre*10 + (p[0] - '0'); p++; } - while( p[0]==' ' ) p++; - if( p[0]==',' ){ - p++; - }else if( p[0] ){ - *pzErr = sqlite3_mprintf("malformed prefix=... directive"); - rc = SQLITE_ERROR; - } - if( rc==SQLITE_OK && (nPre==0 || nPre>=1000) ){ - *pzErr = sqlite3_mprintf("prefix length out of range: %d", nPre); + + if( rc==SQLITE_OK && (nPre<=0 || nPre>=1000) ){ + *pzErr = sqlite3_mprintf("prefix length out of range (max 999)"); rc = SQLITE_ERROR; + break; } + pConfig->aPrefix[pConfig->nPrefix] = nPre; pConfig->nPrefix++; + bFirst = 0; } + assert( pConfig->nPrefix<=FTS5_MAX_PREFIX_INDEXES ); return rc; } diff --git a/ext/fts5/test/fts5config.test b/ext/fts5/test/fts5config.test index 7c88e03d38..dcda2d42a6 100644 --- a/ext/fts5/test/fts5config.test +++ b/ext/fts5/test/fts5config.test @@ -42,6 +42,8 @@ foreach {tn opt} { 1 {prefix=x} 2 {prefix='x'} 3 {prefix='$'} + 4 {prefix='1,2,'} + 5 {prefix=',1'} } { set res [list 1 {malformed prefix=... directive}] do_catchsql_test 2.$tn "CREATE VIRTUAL TABLE f1 USING fts5(x, $opt)" $res @@ -118,18 +120,15 @@ do_catchsql_test 5.3 { #------------------------------------------------------------------------- # 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}} +} {1 {prefix length out of range (max 999)}} do_catchsql_test 6.3 { CREATE VIRTUAL TAbLE abc USING fts5(a, prefix='1, 2, 0000'); -} {1 {prefix length out of range: 0}} +} {1 {prefix length out of range (max 999)}} do_catchsql_test 6.4 { CREATE VIRTUAL TABLE abc USING fts5(a, prefix='1 , 1000000'); -} {1 {malformed prefix=... directive}} +} {1 {prefix length out of range (max 999)}} #------------------------------------------------------------------------- # Duplicate tokenize= and other options. @@ -204,5 +203,16 @@ do_catchsql_test 9.4.1 { INSERT INTO abc(abc, rank) VALUES('nosuchoption', 1); } {1 {SQL logic error or missing database}} +#------------------------------------------------------------------------- +# Too many prefix indexes. Maximum allowed is 31. +# +foreach {tn spec} { + 1 {prefix="1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32"} + 2 {prefix="1 2 3 4", prefix="5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32"} +} { + set sql "CREATE VIRTUAL TABLE xyz USING fts5(x, $spec)" + do_catchsql_test 10.$tn $sql {1 {too many prefix indexes (max 31)}} +} + finish_test diff --git a/ext/fts5/test/fts5prefix.test b/ext/fts5/test/fts5prefix.test index 70de0bc78a..8e0d5a2954 100644 --- a/ext/fts5/test/fts5prefix.test +++ b/ext/fts5/test/fts5prefix.test @@ -298,6 +298,48 @@ foreach {tn col pattern} { do_execsql_test 6.$tn { SELECT rowid FROM t5($query) } $res } +#------------------------------------------------------------------------- +# Check that the various ways of creating prefix indexes produce the +# same database on disk. +# +save_prng_state +foreach {tn create} { + 1 { CREATE VIRTUAL TABLE tt USING fts5(x, y, prefix="1,2,3") } + 2 { CREATE VIRTUAL TABLE tt USING fts5(x, y, prefix="1 2 3") } + 3 { CREATE VIRTUAL TABLE tt USING fts5(x, y, prefix=1, prefix=2, prefix=3) } + 4 { CREATE VIRTUAL TABLE tt USING fts5(x, y, prefix="1 2", prefix=3) } +} { + execsql { DROP TABLE IF EXISTS tt } + restore_prng_state + execsql $create + execsql { + INSERT INTO tt VALUES('cc b ggg ccc aa eee hh', 'aa g b hh a e'); + INSERT INTO tt VALUES('cc bb cc gg j g cc', 'ii jjj ggg jjj cc cc'); + INSERT INTO tt VALUES('h eee cc h iii', 'aaa iii dd iii dd'); + INSERT INTO tt VALUES('jjj hh eee c e b gg', 'j bbb jj ddd jj'); + INSERT INTO tt VALUES('ii hhh aaa ff c hhh iii', 'j cc hh bb e'); + INSERT INTO tt VALUES('e fff hhh i aaa', 'g b aa gg c aa dd'); + INSERT INTO tt VALUES('i aaa ccc gg hhh aa h', 'j bbb bbb d ff'); + INSERT INTO tt VALUES('g f gg ff ff jjj d', 'jjj d j fff fff ee j'); + INSERT INTO tt VALUES('a cc e ccc jjj c', 'ccc iii d bb a eee g'); + INSERT INTO tt VALUES('jj hh hh bb bbb gg', 'j c jjj bb iii f'); + INSERT INTO tt VALUES('a ggg g cc ccc aa', 'jjj j j aaa c'); + INSERT INTO tt VALUES('ddd j dd b i', 'aaa bbb iii ggg ff ccc ddd'); + INSERT INTO tt VALUES('jj ii hh c ii h gg', 'hhh bbb ddd bbb hh g ggg'); + INSERT INTO tt VALUES('aa hhh ccc h ggg ccc', 'iii d jj a ff ii'); + } + + #db eval {SELECT rowid, fts5_decode(rowid, block) aS r FROM tt_data} {puts $r} + + if {$tn==1} { + set ::checksum [execsql {SELECT md5sum(id, block) FROM tt_data}] + } else { + do_execsql_test 7.$tn { + SELECT md5sum(id, block) FROM tt_data + } [list $::checksum] + } +} + finish_test diff --git a/manifest b/manifest index 85f1621207..3b43cff7f4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhancement\sthe\svirtual\stable\sinterface\sto\ssupport\sLIKE,\sGLOB,\sand\sREGEXP\noperators.\s\sAlso\sadd\sthe\ssqlite3_strlike()\sinterface,\swhich\smight\sbe\suseful\nas\spart\sof\sthe\simplementation\sof\sLIKE\son\ssome\svirtual\stables. -D 2015-11-25T01:57:42.585 +C Fix\sthe\sfts5\s"prefix="\soption\sto\smatch\sthe\sdocumentation\s(space\sseparated\slist,\smultiple\sprefix=\soptions\ssupported).\sThe\sundocumented\scomma-separated\sformat\s(compatible\swith\sfts4)\sstill\sworks. +D 2015-11-25T11:56:24.532 F Makefile.in d828db6afa6c1fa060d01e33e4674408df1942a1 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc e928e68168df69b353300ac87c10105206653a03 @@ -106,7 +106,7 @@ F ext/fts5/fts5.h 8b9a13b309b180e9fb88ea5666c0d8d73c6102d9 F ext/fts5/fts5Int.h acf968e43d57b6b1caf7554d34ec35d6ed3b4fe8 F ext/fts5/fts5_aux.c 1f384972d606375b8fa078319f25ab4b5feb1b35 F ext/fts5/fts5_buffer.c 1e49512a535045e621246dc7f4f65f3593fa0fc2 -F ext/fts5/fts5_config.c 6fc92c0b1bda5244c28a54c9ba740736bd5513d9 +F ext/fts5/fts5_config.c 0ee66188609a62342e9f9aeefa3c3e44518a4dd6 F ext/fts5/fts5_expr.c 28b15c9ae296204bc0a2e5cf7a667d840a9d2900 F ext/fts5/fts5_hash.c a9d4c1efebc2a91d26ad7ebdfcbf2678ceac405f F ext/fts5/fts5_index.c b622a0a70f57a96469e6828da2dd70e0872aeb37 @@ -139,7 +139,7 @@ F ext/fts5/test/fts5aux.test 8c687c948cc98e9a94be014df7d518acc1b3b74f F ext/fts5/test/fts5auxdata.test 141a7cbffcceb1bd2799b4b29c183ff8780d586e F ext/fts5/test/fts5bigpl.test 04ee0d7eebbebf17c31f5a0b5c5f9494eac3a0cb F ext/fts5/test/fts5columnsize.test a8cfef21ffa1c264b9f670a7d94eeaccb5341c07 -F ext/fts5/test/fts5config.test ad2ff42ddc856aed2d05bf89dc1c578c8a39ea3b +F ext/fts5/test/fts5config.test 42c1336cc6ed33d7e9c4a05dbce81721b765e7d0 F ext/fts5/test/fts5conflict.test 26f4e46c4d31e16221794832a990dc4e30e18de5 F ext/fts5/test/fts5content.test 9a952c95518a14182dc3b59e3c8fa71cda82a4e1 F ext/fts5/test/fts5corrupt.test c2ad090192708150d50d961278df10ae7a4b8b62 @@ -168,7 +168,7 @@ F ext/fts5/test/fts5phrase.test f6d1d464da5beb25dc56277aa4f1d6102f0d9a2f F ext/fts5/test/fts5plan.test 6a55ecbac9890765b0e16f8c421c7e0888cfe436 F ext/fts5/test/fts5porter.test 7cdc07bef301d70eebbfa75dcaf45c3680e1d0e1 F ext/fts5/test/fts5porter2.test 2e65633d58a1c525d5af0f6c01e5a59155bb3487 -F ext/fts5/test/fts5prefix.test 7ccbdf180ed561a912acef520519e85af8642239 +F ext/fts5/test/fts5prefix.test efd42e00bb8e8a36383f25c838185508681c093f F ext/fts5/test/fts5query.test f5ec25f5f2fbb70033424113cdffc101b1985a40 F ext/fts5/test/fts5rank.test 7e9e64eac7245637f6f2033aec4b292aaf611aab F ext/fts5/test/fts5rebuild.test 03935f617ace91ed23a6099c7c74d905227ff29b @@ -1405,8 +1405,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 20256177072caa4f2b4114038ad1c8f6e26bc562 e70ec71d6883f2f8fc75301ff985bccb5aa06127 -R d30ed8c32e99c9a94479405580943fff -T +closed e70ec71d6883f2f8fc75301ff985bccb5aa06127 -U drh -Z 535a3252c539f51f296331cdb8ca572e +P a6bfd4692c3f8b107546fbcaeb985d2c1817b3c1 +R 1d5b11516958faf6b08e74d20f3f2fa4 +U dan +Z 6f4c4e6edf8914578c51e0efeab8cf04 diff --git a/manifest.uuid b/manifest.uuid index 453c2a5a99..70c5c2cfac 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a6bfd4692c3f8b107546fbcaeb985d2c1817b3c1 \ No newline at end of file +11eb8e877e2ba859ef6b44318f286597186dfaf2 \ No newline at end of file