]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add some tests for OR, AND and NOT operations to fts3rnd.test. Add tests to check...
authordan <dan@noemail.net>
Mon, 7 Dec 2009 12:34:51 +0000 (12:34 +0000)
committerdan <dan@noemail.net>
Mon, 7 Dec 2009 12:34:51 +0000 (12:34 +0000)
FossilOrigin-Name: 5811df3f0412598d189d46b58de4deff24573651

ext/fts3/fts3.c
manifest
manifest.uuid
test/e_fts3.test
test/fts3rnd.test

index ee3981cfb99626a7c0172e48b223ffcc1dc9f4b7..818e130db35eca34bb48957b366efa92eb622138 100644 (file)
@@ -646,7 +646,7 @@ int fts3InitVtab(
   int nName;
 
 #ifdef SQLITE_TEST
-  char *zTestParam = 0;
+  const char *zTestParam = 0;
   if( strncmp(argv[argc-1], "test:", 5)==0 ){
     zTestParam = argv[argc-1];
     argc--;
@@ -1470,8 +1470,7 @@ static int fts3DoclistMerge(
       break;
     }
 
-    case MERGE_POS_NEAR:
-    case MERGE_NEAR: {
+    default: assert( mergetype==MERGE_POS_NEAR || mergetype==MERGE_NEAR ); {
       char *aTmp = 0;
       char **ppPos = 0;
       if( mergetype==MERGE_POS_NEAR ){
@@ -1506,9 +1505,6 @@ static int fts3DoclistMerge(
       sqlite3_free(aTmp);
       break;
     }
-
-    default:
-      assert(!"Invalid mergetype value passed to fts3DoclistMerge()");
   }
 
   *pnBuffer = (int)(p-aBuffer);
@@ -2085,7 +2081,7 @@ static int fts3FunctionArg(
 ){
   Fts3Cursor *pRet;
   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);
     sqlite3_result_error(pContext, zErr, -1);
@@ -2101,22 +2097,31 @@ static int fts3FunctionArg(
 ** Implementation of the snippet() function for FTS3
 */
 static void fts3SnippetFunc(
-  sqlite3_context *pContext,
-  int argc,
-  sqlite3_value **argv
+  sqlite3_context *pContext,      /* SQLite function call context */
+  int nVal,                       /* Size of apVal[] array */
+  sqlite3_value **apVal           /* Array of arguments */
 ){
   Fts3Cursor *pCsr;               /* Cursor handle passed through apVal[0] */
   const char *zStart = "<b>";
   const char *zEnd = "</b>";
   const char *zEllipsis = "<b>...</b>";
 
-  if( argc<1 || argc>4 ) return;
-  if( fts3FunctionArg(pContext, "snippet", argv[0], &pCsr) ) return;
+  /* There must be at least one argument passed to this function (otherwise
+  ** the non-overloaded version would have been called instead of this one).
+  */
+  assert( nVal>=1 );
+
+  if( nVal>4 ){
+    sqlite3_result_error(pContext, 
+        "wrong number of arguments to function snippet()", -1);
+    return;
+  }
+  if( fts3FunctionArg(pContext, "snippet", apVal[0], &pCsr) ) return;
 
-  switch( argc ){
-    case 4: zEllipsis = (const char*)sqlite3_value_text(argv[3]);
-    case 3: zEnd = (const char*)sqlite3_value_text(argv[2]);
-    case 2: zStart = (const char*)sqlite3_value_text(argv[1]);
+  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);
index ab1ae10f57d9fb350637c6891303b2662ed2c311..af701c58d6020dee8f97a594f93df07aafffedbe 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,8 +1,5 @@
------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA1
-
-C Enhanced\sdetection\sof\sdatabase\scorruption\sin\sbtree.c:allocateSpace().
-D 2009-12-06T03:35:51
+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
+D 2009-12-07T12:34:52
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in c5827ead754ab32b9585487177c93bb00b9497b3
 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.tokenizers 998756696647400de63d5ba60e9655036cb966e9
 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/fts3Int.h cc716c74afa7da8e0f8ef39404f33ea62a823eb3
 F ext/fts3/fts3_expr.c c18794a62c257d3456d3314c5a18e348ae0d84bd
@@ -329,7 +326,7 @@ F test/descidx3.test 3394ad4d089335cac743c36a14129d6d931c316f
 F test/diskfull.test 0cede7ef9d8f415d9d3944005c76be7589bb5ebb
 F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376
 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/enc2.test 6d91a5286f59add0cfcbb2d0da913b76f2242398
 F test/enc3.test 5c550d59ff31dccdba5d1a02ae11c7047d77c041
@@ -405,7 +402,7 @@ F test/fts3expr.test 05dab77387801e4900009917bb18f556037d82da
 F test/fts3expr2.test 18da930352e5693eaa163a3eacf96233b7290d1a
 F test/fts3malloc.test d02ee86b21edd2b43044e0d6dfdcd26cb6efddcb
 F test/fts3near.test dc196dd17b4606f440c580d45b3d23aa975fd077
-F test/fts3rnd.test 351197c4459c9d0a20e6413e5bc541a0dbfc4765
+F test/fts3rnd.test ec82795eb358b7a4d6ce79e764d8d55556197584
 F test/func.test af106ed834001738246d276659406823e35cde7b
 F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f
 F test/fuzz.test a4174c3009a3e2c2e14b31b364ebf7ddb49de2c9
@@ -779,14 +776,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 7a9a35327c55452e858335933ce11669fc888aeb
-R 0f3ea22a321de0315884a4805815ec31
-U drh
-Z 107d016b4cea97422dcf94676d1dec5c
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v1.4.6 (GNU/Linux)
-
-iD8DBQFLGyaaoxKgR168RlERAqRoAJ9BqTXTTVZfQIaYlvy+t0KsL1+C7ACfZ/dm
-hnb7PcWLb+b0XHgfDg673P4=
-=+6jS
------END PGP SIGNATURE-----
+P 5a511f98877f0f7f12d336b7831f3da901856b02
+R 2006ff195b109f8cae8438329e516c90
+U dan
+Z 55cd6fd2906fc3343a73a0ae677b4c81
index 89f0f2bfcb386c5a53b208a3db6d049dc9fb7348..ed71393961b1479a6a5591d6e7af0864781edb5c 100644 (file)
@@ -1 +1 @@
-5a511f98877f0f7f12d336b7831f3da901856b02
\ No newline at end of file
+5811df3f0412598d189d46b58de4deff24573651
\ No newline at end of file
index 319f7f67c25456b46ee4b362806a3053426e29d1..1c7afc2625dad720fc74b027ae6e00783129508d 100644 (file)
@@ -32,6 +32,9 @@ proc write_test {tn tbl sql} {
 proc read_test {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=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 
 # [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
 #-------------------------------------------------------------------------
 
+#-------------------------------------------------------------------------
+# 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
index 5acac485ff7535bc817f44c690abb8814096d0e6..0fb1512289bbdf1a00b76405126e7dd5eabde358 100644 (file)
@@ -69,27 +69,14 @@ proc update_row {rowid} {
   execsql "UPDATE t1 SET [lindex $cols $iCol] = \$doc WHERE rowid = \$rowid"
 }
 
-# Primitives to query the in-memory table.
-#
-proc simple_term {zTerm} {
+proc simple_phrase {zPrefix} {
   set ret [list]
-  foreach {key value} [array get ::t1] {
-    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]}]
-  ]]
+  set pattern "*[string map {* \[a-z\]} $zPrefix]*"
   foreach {key value} [array get ::t1] {
     if {[string match $pattern $value]} { lappend ret $key }
   }
   lsort -integer $ret
 }
-
 proc simple_near {termlist nNear} {
   set ret [list]
 
@@ -121,6 +108,35 @@ proc simple_near {termlist nNear} {
   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} {
   catch { array unset ::t1 }
 
@@ -162,7 +178,7 @@ foreach nodesize {50 500 1000 2000} {
       set term [random_term]
       do_test fts3rnd-1.$nodesize.$iTest.1.$i {
         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
@@ -174,7 +190,7 @@ foreach nodesize {50 500 1000 2000} {
       set match "${prefix}*"
       do_test fts3rnd-1.$nodesize.$iTest.2.$i {
         execsql { SELECT docid FROM t1 WHERE t1 MATCH $match }
-      } [simple_prefix $prefix]
+      } [simple_phrase $match]
     }
 
     # Similar to the above, except for phrase queries.
@@ -184,9 +200,9 @@ foreach nodesize {50 500 1000 2000} {
       set match "\"$term\""
       do_test fts3rnd-1.$nodesize.$iTest.3.$i {
         execsql { SELECT docid FROM t1 WHERE t1 MATCH $match }
-      } [simple_term $term]
+      } [simple_phrase $term]
     }
-    
+
     # Three word phrases.
     #
     for {set i 0} {$i < 10} {incr i} {
@@ -194,7 +210,20 @@ foreach nodesize {50 500 1000 2000} {
       set match "\"$term\""
       do_test fts3rnd-1.$nodesize.$iTest.4.$i {
         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.
@@ -202,11 +231,11 @@ foreach nodesize {50 500 1000 2000} {
     for {set i 0} {$i < 10} {incr i} {
       set terms [list [random_term] [random_term]]
       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 }
       } [simple_near $terms 10]
     }
+
     # A 3-way NEAR query with terms as the arguments.
     #
     for {set i 0} {$i < 10} {incr i} {
@@ -214,11 +243,49 @@ foreach nodesize {50 500 1000 2000} {
       set nNear 11
       set match [join $terms " NEAR/$nNear "]
       set fts3 [execsql { SELECT docid FROM t1 WHERE t1 MATCH $match }]
-      set tcl [simple_near $terms $nNear]
-      do_test fts3rnd-1.$nodesize.$iTest.5.$i.$match {
+      do_test fts3rnd-1.$nodesize.$iTest.7.$i {
         execsql { SELECT docid FROM t1 WHERE t1 MATCH $match }
       } [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]
+          ]
+      }
+    }
   }
 }