1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-30 19:03:16 +03:00

Add some tests for OR, AND and NOT operations to fts3rnd.test. Add tests to check that errors are returned when bad arguments are passed to fts3 functions snippet, offsets and optimize. Minor fix for the same

FossilOrigin-Name: 5811df3f0412598d189d46b58de4deff24573651
This commit is contained in:
dan
2009-12-07 12:34:51 +00:00
parent 00ce39458d
commit ff32e39c8e
5 changed files with 153 additions and 61 deletions

View File

@ -646,7 +646,7 @@ int fts3InitVtab(
int nName; int nName;
#ifdef SQLITE_TEST #ifdef SQLITE_TEST
char *zTestParam = 0; const char *zTestParam = 0;
if( strncmp(argv[argc-1], "test:", 5)==0 ){ if( strncmp(argv[argc-1], "test:", 5)==0 ){
zTestParam = argv[argc-1]; zTestParam = argv[argc-1];
argc--; argc--;
@ -1470,8 +1470,7 @@ static int fts3DoclistMerge(
break; break;
} }
case MERGE_POS_NEAR: default: assert( mergetype==MERGE_POS_NEAR || mergetype==MERGE_NEAR ); {
case MERGE_NEAR: {
char *aTmp = 0; char *aTmp = 0;
char **ppPos = 0; char **ppPos = 0;
if( mergetype==MERGE_POS_NEAR ){ if( mergetype==MERGE_POS_NEAR ){
@ -1506,9 +1505,6 @@ static int fts3DoclistMerge(
sqlite3_free(aTmp); sqlite3_free(aTmp);
break; break;
} }
default:
assert(!"Invalid mergetype value passed to fts3DoclistMerge()");
} }
*pnBuffer = (int)(p-aBuffer); *pnBuffer = (int)(p-aBuffer);
@ -2085,7 +2081,7 @@ static int fts3FunctionArg(
){ ){
Fts3Cursor *pRet; Fts3Cursor *pRet;
if( sqlite3_value_type(pVal)!=SQLITE_BLOB if( sqlite3_value_type(pVal)!=SQLITE_BLOB
&& sqlite3_value_bytes(pVal)!=sizeof(Fts3Cursor *) || sqlite3_value_bytes(pVal)!=sizeof(Fts3Cursor *)
){ ){
char *zErr = sqlite3_mprintf("illegal first argument to %s", zFunc); char *zErr = sqlite3_mprintf("illegal first argument to %s", zFunc);
sqlite3_result_error(pContext, zErr, -1); sqlite3_result_error(pContext, zErr, -1);
@ -2101,22 +2097,31 @@ static int fts3FunctionArg(
** Implementation of the snippet() function for FTS3 ** Implementation of the snippet() function for FTS3
*/ */
static void fts3SnippetFunc( static void fts3SnippetFunc(
sqlite3_context *pContext, sqlite3_context *pContext, /* SQLite function call context */
int argc, int nVal, /* Size of apVal[] array */
sqlite3_value **argv sqlite3_value **apVal /* Array of arguments */
){ ){
Fts3Cursor *pCsr; /* Cursor handle passed through apVal[0] */ Fts3Cursor *pCsr; /* Cursor handle passed through apVal[0] */
const char *zStart = "<b>"; const char *zStart = "<b>";
const char *zEnd = "</b>"; const char *zEnd = "</b>";
const char *zEllipsis = "<b>...</b>"; const char *zEllipsis = "<b>...</b>";
if( argc<1 || argc>4 ) return; /* There must be at least one argument passed to this function (otherwise
if( fts3FunctionArg(pContext, "snippet", argv[0], &pCsr) ) return; ** the non-overloaded version would have been called instead of this one).
*/
assert( nVal>=1 );
switch( argc ){ if( nVal>4 ){
case 4: zEllipsis = (const char*)sqlite3_value_text(argv[3]); sqlite3_result_error(pContext,
case 3: zEnd = (const char*)sqlite3_value_text(argv[2]); "wrong number of arguments to function snippet()", -1);
case 2: zStart = (const char*)sqlite3_value_text(argv[1]); return;
}
if( fts3FunctionArg(pContext, "snippet", apVal[0], &pCsr) ) return;
switch( nVal ){
case 4: zEllipsis = (const char*)sqlite3_value_text(apVal[3]);
case 3: zEnd = (const char*)sqlite3_value_text(apVal[2]);
case 2: zStart = (const char*)sqlite3_value_text(apVal[1]);
} }
sqlite3Fts3Snippet(pContext, pCsr, zStart, zEnd, zEllipsis); sqlite3Fts3Snippet(pContext, pCsr, zStart, zEnd, zEllipsis);

View File

@ -1,8 +1,5 @@
-----BEGIN PGP SIGNED MESSAGE----- C Add\ssome\stests\sfor\sOR,\sAND\sand\sNOT\soperations\sto\sfts3rnd.test.\sAdd\stests\sto\scheck\sthat\serrors\sare\sreturned\swhen\sbad\sarguments\sare\spassed\sto\sfts3\sfunctions\ssnippet,\soffsets\sand\soptimize.\sMinor\sfix\sfor\sthe\ssame
Hash: SHA1 D 2009-12-07T12:34:52
C Enhanced\sdetection\sof\sdatabase\scorruption\sin\sbtree.c:allocateSpace().
D 2009-12-06T03:35:51
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in c5827ead754ab32b9585487177c93bb00b9497b3 F Makefile.in c5827ead754ab32b9585487177c93bb00b9497b3
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@ -59,7 +56,7 @@ F ext/fts2/mkfts2amal.tcl 974d5d438cb3f7c4a652639262f82418c1e4cff0
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
F ext/fts3/README.tokenizers 998756696647400de63d5ba60e9655036cb966e9 F ext/fts3/README.tokenizers 998756696647400de63d5ba60e9655036cb966e9
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
F ext/fts3/fts3.c f4152f277722781048c9bba19aa605dbb831ad9a F ext/fts3/fts3.c 43d8cfd021d06d594ec74eb01d35c0a5731055ae
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
F ext/fts3/fts3Int.h cc716c74afa7da8e0f8ef39404f33ea62a823eb3 F ext/fts3/fts3Int.h cc716c74afa7da8e0f8ef39404f33ea62a823eb3
F ext/fts3/fts3_expr.c c18794a62c257d3456d3314c5a18e348ae0d84bd F ext/fts3/fts3_expr.c c18794a62c257d3456d3314c5a18e348ae0d84bd
@ -329,7 +326,7 @@ F test/descidx3.test 3394ad4d089335cac743c36a14129d6d931c316f
F test/diskfull.test 0cede7ef9d8f415d9d3944005c76be7589bb5ebb F test/diskfull.test 0cede7ef9d8f415d9d3944005c76be7589bb5ebb
F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376 F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376
F test/e_fkey.test fd1fcf89badd5f2773d7ac04775b5ff3488eda17 F test/e_fkey.test fd1fcf89badd5f2773d7ac04775b5ff3488eda17
F test/e_fts3.test ad278add0deca99d2d8ec3d8b06ffed965d5abc2 F test/e_fts3.test 8907e25b2c7d6bda9f7077356f64bc5e26c251a7
F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea
F test/enc2.test 6d91a5286f59add0cfcbb2d0da913b76f2242398 F test/enc2.test 6d91a5286f59add0cfcbb2d0da913b76f2242398
F test/enc3.test 5c550d59ff31dccdba5d1a02ae11c7047d77c041 F test/enc3.test 5c550d59ff31dccdba5d1a02ae11c7047d77c041
@ -405,7 +402,7 @@ F test/fts3expr.test 05dab77387801e4900009917bb18f556037d82da
F test/fts3expr2.test 18da930352e5693eaa163a3eacf96233b7290d1a F test/fts3expr2.test 18da930352e5693eaa163a3eacf96233b7290d1a
F test/fts3malloc.test d02ee86b21edd2b43044e0d6dfdcd26cb6efddcb F test/fts3malloc.test d02ee86b21edd2b43044e0d6dfdcd26cb6efddcb
F test/fts3near.test dc196dd17b4606f440c580d45b3d23aa975fd077 F test/fts3near.test dc196dd17b4606f440c580d45b3d23aa975fd077
F test/fts3rnd.test 351197c4459c9d0a20e6413e5bc541a0dbfc4765 F test/fts3rnd.test ec82795eb358b7a4d6ce79e764d8d55556197584
F test/func.test af106ed834001738246d276659406823e35cde7b F test/func.test af106ed834001738246d276659406823e35cde7b
F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f
F test/fuzz.test a4174c3009a3e2c2e14b31b364ebf7ddb49de2c9 F test/fuzz.test a4174c3009a3e2c2e14b31b364ebf7ddb49de2c9
@ -779,14 +776,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
P 7a9a35327c55452e858335933ce11669fc888aeb P 5a511f98877f0f7f12d336b7831f3da901856b02
R 0f3ea22a321de0315884a4805815ec31 R 2006ff195b109f8cae8438329e516c90
U drh U dan
Z 107d016b4cea97422dcf94676d1dec5c Z 55cd6fd2906fc3343a73a0ae677b4c81
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
iD8DBQFLGyaaoxKgR168RlERAqRoAJ9BqTXTTVZfQIaYlvy+t0KsL1+C7ACfZ/dm
hnb7PcWLb+b0XHgfDg673P4=
=+6jS
-----END PGP SIGNATURE-----

View File

@ -1 +1 @@
5a511f98877f0f7f12d336b7831f3da901856b02 5811df3f0412598d189d46b58de4deff24573651

View File

@ -32,6 +32,9 @@ proc write_test {tn tbl sql} {
proc read_test {tn sql result} { proc read_test {tn sql result} {
uplevel [list do_select_test e_fts3-$tn $sql $result] uplevel [list do_select_test e_fts3-$tn $sql $result]
} }
proc error_test {tn sql result} {
uplevel [list do_error_test e_fts3-$tn $sql $result]
}
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@ -43,7 +46,7 @@ proc read_test {tn sql result} {
# DO_MALLOC_TEST=1: Run tests with transient OOM errors. # DO_MALLOC_TEST=1: Run tests with transient OOM errors.
# DO_MALLOC_TEST=2: Run tests with persistent OOM errors. # DO_MALLOC_TEST=2: Run tests with persistent OOM errors.
# #
foreach DO_MALLOC_TEST {0 1 2} { foreach DO_MALLOC_TEST [lrange {0 1 2} 0 end] {
# Reset the database and database connection. If this iteration of the # Reset the database and database connection. If this iteration of the
# [foreach] loop is testing with OOM errors, disable the lookaside buffer. # [foreach] loop is testing with OOM errors, disable the lookaside buffer.
@ -435,5 +438,32 @@ read_test 1.8.2.4 {
# End of tests of example code in fts3.html # End of tests of example code in fts3.html
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
#-------------------------------------------------------------------------
# Test that errors in the arguments passed to the snippet and offsets
# functions are handled correctly.
#
set DO_MALLOC_TEST 0
ddl_test 2.1.1 { CREATE VIRTUAL TABLE t1 USING fts3(a, b) }
write_test 2.1.2 t1_content {
INSERT INTO t1 VALUES('one two three', x'A1B2C3D4E5F6');
}
error_test 2.1.3 {
SELECT offsets(a) FROM t1 WHERE a MATCH 'one'
} {illegal first argument to offsets}
error_test 2.1.4 {
SELECT offsets(b) FROM t1 WHERE a MATCH 'one'
} {illegal first argument to offsets}
error_test 2.1.5 {
SELECT optimize(a) FROM t1 LIMIT 1
} {illegal first argument to optimize}
error_test 2.1.6 {
SELECT snippet(a) FROM t1 WHERE a MATCH 'one'
} {illegal first argument to snippet}
error_test 2.1.7 {
SELECT snippet() FROM t1 WHERE a MATCH 'one'
} {unable to use function snippet in the requested context}
error_test 2.1.8 {
SELECT snippet(a, b, 'A', 'B', 'C') FROM t1 WHERE a MATCH 'one'
} {wrong number of arguments to function snippet()}
finish_test finish_test

View File

@ -69,27 +69,14 @@ proc update_row {rowid} {
execsql "UPDATE t1 SET [lindex $cols $iCol] = \$doc WHERE rowid = \$rowid" execsql "UPDATE t1 SET [lindex $cols $iCol] = \$doc WHERE rowid = \$rowid"
} }
# Primitives to query the in-memory table. proc simple_phrase {zPrefix} {
#
proc simple_term {zTerm} {
set ret [list] set ret [list]
foreach {key value} [array get ::t1] { set pattern "*[string map {* \[a-z\]} $zPrefix]*"
if {[string first $zTerm $value]>=0} { lappend ret $key }
}
lsort -integer $ret
}
proc simple_prefix {zPrefix} {
set ret [list]
set pattern [format "*%s%s*" $zPrefix [
string repeat {[a-z]} [expr {3-[string length $zPrefix]}]
]]
foreach {key value} [array get ::t1] { foreach {key value} [array get ::t1] {
if {[string match $pattern $value]} { lappend ret $key } if {[string match $pattern $value]} { lappend ret $key }
} }
lsort -integer $ret lsort -integer $ret
} }
proc simple_near {termlist nNear} { proc simple_near {termlist nNear} {
set ret [list] set ret [list]
@ -121,6 +108,35 @@ proc simple_near {termlist nNear} {
lsort -unique -integer $ret lsort -unique -integer $ret
} }
# The following three procs:
#
# setup_not A B
# setup_or A B
# setup_and A B
#
# each take two arguments. Both arguments must be lists of integer values
# sorted by value. The return value is the list produced by evaluating
# the equivalent of "A op B", where op is the FTS3 operator NOT, OR or
# AND.
#
proc setop_not {A B} {
foreach b $B { set n($b) {} }
set ret [list]
foreach a $A { if {![info exists n($a)]} {lappend ret $a} }
return $ret
}
proc setop_or {A B} {
lsort -integer -uniq [concat $A $B]
}
proc setop_and {A B} {
foreach b $B { set n($b) {} }
set ret [list]
foreach a $A { if {[info exists n($a)]} {lappend ret $a} }
return $ret
}
set sqlite_fts3_enable_parentheses 1
foreach nodesize {50 500 1000 2000} { foreach nodesize {50 500 1000 2000} {
catch { array unset ::t1 } catch { array unset ::t1 }
@ -162,7 +178,7 @@ foreach nodesize {50 500 1000 2000} {
set term [random_term] set term [random_term]
do_test fts3rnd-1.$nodesize.$iTest.1.$i { do_test fts3rnd-1.$nodesize.$iTest.1.$i {
execsql { SELECT docid FROM t1 WHERE t1 MATCH $term } execsql { SELECT docid FROM t1 WHERE t1 MATCH $term }
} [simple_term $term] } [simple_phrase $term]
} }
# This time, use the first two characters of each term as a term prefix # This time, use the first two characters of each term as a term prefix
@ -174,7 +190,7 @@ foreach nodesize {50 500 1000 2000} {
set match "${prefix}*" set match "${prefix}*"
do_test fts3rnd-1.$nodesize.$iTest.2.$i { do_test fts3rnd-1.$nodesize.$iTest.2.$i {
execsql { SELECT docid FROM t1 WHERE t1 MATCH $match } execsql { SELECT docid FROM t1 WHERE t1 MATCH $match }
} [simple_prefix $prefix] } [simple_phrase $match]
} }
# Similar to the above, except for phrase queries. # Similar to the above, except for phrase queries.
@ -184,9 +200,9 @@ foreach nodesize {50 500 1000 2000} {
set match "\"$term\"" set match "\"$term\""
do_test fts3rnd-1.$nodesize.$iTest.3.$i { do_test fts3rnd-1.$nodesize.$iTest.3.$i {
execsql { SELECT docid FROM t1 WHERE t1 MATCH $match } execsql { SELECT docid FROM t1 WHERE t1 MATCH $match }
} [simple_term $term] } [simple_phrase $term]
} }
# Three word phrases. # Three word phrases.
# #
for {set i 0} {$i < 10} {incr i} { for {set i 0} {$i < 10} {incr i} {
@ -194,7 +210,20 @@ foreach nodesize {50 500 1000 2000} {
set match "\"$term\"" set match "\"$term\""
do_test fts3rnd-1.$nodesize.$iTest.4.$i { do_test fts3rnd-1.$nodesize.$iTest.4.$i {
execsql { SELECT docid FROM t1 WHERE t1 MATCH $match } execsql { SELECT docid FROM t1 WHERE t1 MATCH $match }
} [simple_term $term] } [simple_phrase $term]
}
# Three word phrases made up of term-prefixes.
#
for {set i 0} {$i < 10} {incr i} {
set query "[string range [random_term] 0 1]* "
append query "[string range [random_term] 0 1]* "
append query "[string range [random_term] 0 1]*"
set match "\"$query\""
do_test fts3rnd-1.$nodesize.$iTest.5.$i {
execsql { SELECT docid FROM t1 WHERE t1 MATCH $match }
} [simple_phrase $query]
} }
# A NEAR query with terms as the arguments. # A NEAR query with terms as the arguments.
@ -202,11 +231,11 @@ foreach nodesize {50 500 1000 2000} {
for {set i 0} {$i < 10} {incr i} { for {set i 0} {$i < 10} {incr i} {
set terms [list [random_term] [random_term]] set terms [list [random_term] [random_term]]
set match [join $terms " NEAR "] set match [join $terms " NEAR "]
do_test fts3rnd-1.$nodesize.$iTest.5.$i.$match { do_test fts3rnd-1.$nodesize.$iTest.6.$i {
execsql { SELECT docid FROM t1 WHERE t1 MATCH $match } execsql { SELECT docid FROM t1 WHERE t1 MATCH $match }
} [simple_near $terms 10] } [simple_near $terms 10]
} }
# A 3-way NEAR query with terms as the arguments. # A 3-way NEAR query with terms as the arguments.
# #
for {set i 0} {$i < 10} {incr i} { for {set i 0} {$i < 10} {incr i} {
@ -214,11 +243,49 @@ foreach nodesize {50 500 1000 2000} {
set nNear 11 set nNear 11
set match [join $terms " NEAR/$nNear "] set match [join $terms " NEAR/$nNear "]
set fts3 [execsql { SELECT docid FROM t1 WHERE t1 MATCH $match }] set fts3 [execsql { SELECT docid FROM t1 WHERE t1 MATCH $match }]
set tcl [simple_near $terms $nNear] do_test fts3rnd-1.$nodesize.$iTest.7.$i {
do_test fts3rnd-1.$nodesize.$iTest.5.$i.$match {
execsql { SELECT docid FROM t1 WHERE t1 MATCH $match } execsql { SELECT docid FROM t1 WHERE t1 MATCH $match }
} [simple_near $terms $nNear] } [simple_near $terms $nNear]
} }
# Set operations on simple term queries.
#
foreach {tn op proc} {
8 OR setop_or
9 NOT setop_not
10 AND setop_and
} {
for {set i 0} {$i < 10} {incr i} {
set term1 [random_term]
set term2 [random_term]
set match "$term1 $op $term2"
do_test fts3rnd-1.$nodesize.$iTest.$tn.$i {
execsql { SELECT docid FROM t1 WHERE t1 MATCH $match }
} [$proc [simple_phrase $term1] [simple_phrase $term2]]
}
}
# Set operations on NEAR queries.
#
foreach {tn op proc} {
8 OR setop_or
9 NOT setop_not
10 AND setop_and
} {
for {set i 0} {$i < 10} {incr i} {
set term1 [random_term]
set term2 [random_term]
set term3 [random_term]
set term4 [random_term]
set match "$term1 NEAR $term2 $op $term3 NEAR $term4"
do_test fts3rnd-1.$nodesize.$iTest.$tn.$i {
execsql { SELECT docid FROM t1 WHERE t1 MATCH $match }
} [$proc \
[simple_near [list $term1 $term2] 10] \
[simple_near [list $term3 $term4] 10]
]
}
}
} }
} }