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++;
- while( p[0]>='0' && p[0]<='9' && nPre<1000 ){
- nPre = nPre*10 + (p[0] - '0');
+ if( bFirst==0 && p[0]==',' ){
p++;
+ while( p[0]==' ' ) p++;
+ }else if( p[0]=='\0' ){
+ break;
}
- while( p[0]==' ' ) p++;
- if( p[0]==',' ){
- p++;
- }else if( p[0] ){
+ 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;
}
- if( rc==SQLITE_OK && (nPre==0 || nPre>=1000) ){
- *pzErr = sqlite3_mprintf("prefix length out of range: %d", nPre);
+
+ while( p[0]>='0' && p[0]<='9' && nPre<1000 ){
+ nPre = nPre*10 + (p[0] - '0');
+ p++;
+ }
+
+ 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;
}
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
#-------------------------------------------------------------------------
# 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.
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
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
-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
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
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
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
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
-a6bfd4692c3f8b107546fbcaeb985d2c1817b3c1
\ No newline at end of file
+11eb8e877e2ba859ef6b44318f286597186dfaf2
\ No newline at end of file