| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 # 2009 January 1 | 
|  | 2 # | 
|  | 3 # The author disclaims copyright to this source code.  In place of | 
|  | 4 # a legal notice, here is a blessing: | 
|  | 5 # | 
|  | 6 #    May you do good and not evil. | 
|  | 7 #    May you find forgiveness for yourself and forgive others. | 
|  | 8 #    May you share freely, never taking more than you give. | 
|  | 9 # | 
|  | 10 #************************************************************************* | 
|  | 11 # This file implements regression tests for SQLite library.  The | 
|  | 12 # focus of this script is testing the FTS3 module syntax parser. | 
|  | 13 # | 
|  | 14 # $Id: fts3expr2.test,v 1.2 2009/06/05 17:09:12 drh Exp $ | 
|  | 15 # | 
|  | 16 | 
|  | 17 set testdir [file dirname $argv0] | 
|  | 18 source $testdir/tester.tcl | 
|  | 19 | 
|  | 20 # If SQLITE_ENABLE_FTS3 is defined, omit this file. | 
|  | 21 ifcapable !fts3 { | 
|  | 22   finish_test | 
|  | 23   return | 
|  | 24 } | 
|  | 25 | 
|  | 26 # Test overview: | 
|  | 27 # | 
|  | 28 #   The tests in this file are pseudo-randomly generated. They test | 
|  | 29 #   the fts3 match expression parser via the test interface | 
|  | 30 #   SQL function "fts3_exprtest" (see comments in fts3_expr.c). | 
|  | 31 # | 
|  | 32 #   Each test case works as follows: | 
|  | 33 # | 
|  | 34 #     1. A random expression tree is generated using proc [random_expr_tree]. | 
|  | 35 #     2. The expression tree is converted to the text of an equivalent | 
|  | 36 #        fts3 expression using proc [tree_to_expr]. | 
|  | 37 #     3. The test SQL function "fts3_exprtest" is used to parse the | 
|  | 38 #        expression text generated in step (2), returning a parsed expression | 
|  | 39 #        tree. | 
|  | 40 #     4. Test that the tree returned in step (3) matches that generated in | 
|  | 41 #        step (1). | 
|  | 42 # | 
|  | 43 #   In step (2), 4 different fts3 expressions are created from each | 
|  | 44 #   expression tree by varying the following boolean properties: | 
|  | 45 # | 
|  | 46 #     * Whether or not superflous parenthesis are included. i.e. if | 
|  | 47 #       "a OR b AND (c OR d)" or "a OR (b AND (c OR d))" is generated. | 
|  | 48 # | 
|  | 49 #     * Whether or not explict AND operators are used. i.e. if | 
|  | 50 #     "a OR b AND c" or "a OR b c" is generated. | 
|  | 51 # | 
|  | 52 | 
|  | 53 set sqlite_fts3_enable_parentheses 1 | 
|  | 54 | 
|  | 55 proc strip_phrase_data {L} { | 
|  | 56   if {[lindex $L 0] eq "PHRASE"} { | 
|  | 57     return [list P [lrange $L 3 end]] | 
|  | 58   } | 
|  | 59   return [list \ | 
|  | 60     [lindex $L 0] \ | 
|  | 61     [strip_phrase_data [lindex $L 1]] \ | 
|  | 62     [strip_phrase_data [lindex $L 2]] \ | 
|  | 63   ] | 
|  | 64 } | 
|  | 65 proc test_fts3expr2 {expr} { | 
|  | 66   strip_phrase_data [ | 
|  | 67     db one {SELECT fts3_exprtest('simple', $expr, 'a', 'b', 'c')} | 
|  | 68   ] | 
|  | 69 } | 
|  | 70 | 
|  | 71 proc rnd {nMax} { expr {int(rand()*$nMax)} } | 
|  | 72 | 
|  | 73 proc random_phrase {} { | 
|  | 74   set phrases [list one two three four "one two" "three four"] | 
|  | 75   list P [lindex $phrases [rnd [llength $phrases]]] | 
|  | 76 } | 
|  | 77 | 
|  | 78 # Generate and return a pseudo-random expression tree. Using the same | 
|  | 79 # format returned by the [test_fts3expr2] proc. | 
|  | 80 # | 
|  | 81 proc random_expr_tree {iHeight} { | 
|  | 82   if {$iHeight==0 || [rnd 3]==0} { | 
|  | 83     return [random_phrase] | 
|  | 84   } | 
|  | 85 | 
|  | 86   set operators [list NEAR NOT AND OR] | 
|  | 87   set op [lindex $operators [rnd 4]] | 
|  | 88 | 
|  | 89   if {$op eq "NEAR"} { | 
|  | 90     set iDistance [rnd 15] | 
|  | 91     return [list $op/$iDistance [random_phrase] [random_phrase]] | 
|  | 92   } | 
|  | 93 | 
|  | 94   set iNH [expr {$iHeight - 1}] | 
|  | 95   return [list $op [random_expr_tree $iNH] [random_expr_tree $iNH]] | 
|  | 96 } | 
|  | 97 | 
|  | 98 # Given an expression tree, generate a corresponding expression. | 
|  | 99 # | 
|  | 100 proc tree_to_expr {tree all_brackets implicit_and} { | 
|  | 101   set prec(NOT) 2 | 
|  | 102   set prec(AND) 3 | 
|  | 103   set prec()    3 | 
|  | 104   set prec(OR)  4 | 
|  | 105 | 
|  | 106   set op [lindex $tree 0] | 
|  | 107 | 
|  | 108   if {$op eq "P"} { | 
|  | 109     set phrase [lindex $tree 1] | 
|  | 110     if {[llength $phrase]>1} { | 
|  | 111       return "\"$phrase\"" | 
|  | 112     } else { | 
|  | 113       return $phrase | 
|  | 114     } | 
|  | 115   } | 
|  | 116 | 
|  | 117   if {$op eq "NEAR/10"} { | 
|  | 118     set op "NEAR" | 
|  | 119   } | 
|  | 120   if {$op eq "AND" && $implicit_and} { | 
|  | 121     set op "" | 
|  | 122   } | 
|  | 123 | 
|  | 124   set lhs [lindex $tree 1] | 
|  | 125   set rhs [lindex $tree 2] | 
|  | 126   set zLeft  [tree_to_expr $lhs $all_brackets $implicit_and] | 
|  | 127   set zRight [tree_to_expr $rhs $all_brackets $implicit_and] | 
|  | 128 | 
|  | 129   set iPrec 5 | 
|  | 130   set iLeftPrec 0 | 
|  | 131   set iRightPrec 0 | 
|  | 132 | 
|  | 133   catch {set iPrec      $prec($op)} | 
|  | 134   catch {set iLeftPrec  $prec([lindex $lhs 0])} | 
|  | 135   catch {set iRightPrec $prec([lindex $rhs 0])} | 
|  | 136 | 
|  | 137   if {$iLeftPrec > $iPrec || $all_brackets} { | 
|  | 138     set zLeft "($zLeft)" | 
|  | 139   } | 
|  | 140   if {$iRightPrec >= $iPrec || $all_brackets} { | 
|  | 141     set zRight "($zRight)" | 
|  | 142   } | 
|  | 143 | 
|  | 144   return "$zLeft $op $zRight" | 
|  | 145 } | 
|  | 146 | 
|  | 147 proc do_exprparse_test {name expr tree} { | 
|  | 148   uplevel do_test $name [list "test_fts3expr2 {$expr}"] [list $tree] | 
|  | 149 } | 
|  | 150 | 
|  | 151 for {set iTest 1} {$iTest<500} {incr iTest} { | 
|  | 152   set t [random_expr_tree 4] | 
|  | 153 | 
|  | 154   set e1 [tree_to_expr $t 0 0] | 
|  | 155   set e2 [tree_to_expr $t 0 1] | 
|  | 156   set e3 [tree_to_expr $t 1 0] | 
|  | 157   set e4 [tree_to_expr $t 1 1] | 
|  | 158 | 
|  | 159   do_exprparse_test fts3expr2-$iTest.1 $e1 $t | 
|  | 160   do_exprparse_test fts3expr2-$iTest.2 $e2 $t | 
|  | 161   do_exprparse_test fts3expr2-$iTest.3 $e3 $t | 
|  | 162   do_exprparse_test fts3expr2-$iTest.4 $e4 $t | 
|  | 163 } | 
|  | 164 | 
|  | 165 set sqlite_fts3_enable_parentheses 0 | 
|  | 166 finish_test | 
| OLD | NEW | 
|---|