xref: /sqlite-3.40.0/test/fts3expr2.test (revision dda70fe3)
15973e6a3Sdanielk1977# 2009 January 1
25973e6a3Sdanielk1977#
35973e6a3Sdanielk1977# The author disclaims copyright to this source code.  In place of
45973e6a3Sdanielk1977# a legal notice, here is a blessing:
55973e6a3Sdanielk1977#
65973e6a3Sdanielk1977#    May you do good and not evil.
75973e6a3Sdanielk1977#    May you find forgiveness for yourself and forgive others.
85973e6a3Sdanielk1977#    May you share freely, never taking more than you give.
95973e6a3Sdanielk1977#
105973e6a3Sdanielk1977#*************************************************************************
115973e6a3Sdanielk1977# This file implements regression tests for SQLite library.  The
125973e6a3Sdanielk1977# focus of this script is testing the FTS3 module syntax parser.
135973e6a3Sdanielk1977#
14*dda70fe3Sdrh# $Id: fts3expr2.test,v 1.2 2009/06/05 17:09:12 drh Exp $
155973e6a3Sdanielk1977#
165973e6a3Sdanielk1977
175973e6a3Sdanielk1977set testdir [file dirname $argv0]
185973e6a3Sdanielk1977source $testdir/tester.tcl
195973e6a3Sdanielk1977
205973e6a3Sdanielk1977# If SQLITE_ENABLE_FTS3 is defined, omit this file.
215973e6a3Sdanielk1977ifcapable !fts3 {
225973e6a3Sdanielk1977  finish_test
235973e6a3Sdanielk1977  return
245973e6a3Sdanielk1977}
255973e6a3Sdanielk1977
265973e6a3Sdanielk1977# Test overview:
275973e6a3Sdanielk1977#
285973e6a3Sdanielk1977#   The tests in this file are pseudo-randomly generated. They test
295973e6a3Sdanielk1977#   the fts3 match expression parser via the test interface
305973e6a3Sdanielk1977#   SQL function "fts3_exprtest" (see comments in fts3_expr.c).
315973e6a3Sdanielk1977#
325973e6a3Sdanielk1977#   Each test case works as follows:
335973e6a3Sdanielk1977#
345973e6a3Sdanielk1977#     1. A random expression tree is generated using proc [random_expr_tree].
355973e6a3Sdanielk1977#     2. The expression tree is converted to the text of an equivalent
365973e6a3Sdanielk1977#        fts3 expression using proc [tree_to_expr].
375973e6a3Sdanielk1977#     3. The test SQL function "fts3_exprtest" is used to parse the
385973e6a3Sdanielk1977#        expression text generated in step (2), returning a parsed expression
395973e6a3Sdanielk1977#        tree.
405973e6a3Sdanielk1977#     4. Test that the tree returned in step (3) matches that generated in
415973e6a3Sdanielk1977#        step (1).
425973e6a3Sdanielk1977#
435973e6a3Sdanielk1977#   In step (2), 4 different fts3 expressions are created from each
445973e6a3Sdanielk1977#   expression tree by varying the following boolean properties:
455973e6a3Sdanielk1977#
465973e6a3Sdanielk1977#     * Whether or not superflous parenthesis are included. i.e. if
475973e6a3Sdanielk1977#       "a OR b AND (c OR d)" or "a OR (b AND (c OR d))" is generated.
485973e6a3Sdanielk1977#
495973e6a3Sdanielk1977#     * Whether or not explict AND operators are used. i.e. if
505973e6a3Sdanielk1977#     "a OR b AND c" or "a OR b c" is generated.
515973e6a3Sdanielk1977#
525973e6a3Sdanielk1977
535973e6a3Sdanielk1977set sqlite_fts3_enable_parentheses 1
545973e6a3Sdanielk1977
555973e6a3Sdanielk1977proc strip_phrase_data {L} {
565973e6a3Sdanielk1977  if {[lindex $L 0] eq "PHRASE"} {
575973e6a3Sdanielk1977    return [list P [lrange $L 3 end]]
585973e6a3Sdanielk1977  }
595973e6a3Sdanielk1977  return [list \
605973e6a3Sdanielk1977    [lindex $L 0] \
615973e6a3Sdanielk1977    [strip_phrase_data [lindex $L 1]] \
625973e6a3Sdanielk1977    [strip_phrase_data [lindex $L 2]] \
635973e6a3Sdanielk1977  ]
645973e6a3Sdanielk1977}
655973e6a3Sdanielk1977proc test_fts3expr2 {expr} {
665973e6a3Sdanielk1977  strip_phrase_data [
675973e6a3Sdanielk1977    db one {SELECT fts3_exprtest('simple', $expr, 'a', 'b', 'c')}
685973e6a3Sdanielk1977  ]
695973e6a3Sdanielk1977}
705973e6a3Sdanielk1977
715973e6a3Sdanielk1977proc rnd {nMax} { expr {int(rand()*$nMax)} }
725973e6a3Sdanielk1977
735973e6a3Sdanielk1977proc random_phrase {} {
745973e6a3Sdanielk1977  set phrases [list one two three four "one two" "three four"]
755973e6a3Sdanielk1977  list P [lindex $phrases [rnd [llength $phrases]]]
765973e6a3Sdanielk1977}
775973e6a3Sdanielk1977
785973e6a3Sdanielk1977# Generate and return a pseudo-random expression tree. Using the same
795973e6a3Sdanielk1977# format returned by the [test_fts3expr2] proc.
805973e6a3Sdanielk1977#
815973e6a3Sdanielk1977proc random_expr_tree {iHeight} {
825973e6a3Sdanielk1977  if {$iHeight==0 || [rnd 3]==0} {
835973e6a3Sdanielk1977    return [random_phrase]
845973e6a3Sdanielk1977  }
855973e6a3Sdanielk1977
865973e6a3Sdanielk1977  set operators [list NEAR NOT AND OR]
875973e6a3Sdanielk1977  set op [lindex $operators [rnd 4]]
885973e6a3Sdanielk1977
895973e6a3Sdanielk1977  if {$op eq "NEAR"} {
905973e6a3Sdanielk1977    set iDistance [rnd 15]
915973e6a3Sdanielk1977    return [list $op/$iDistance [random_phrase] [random_phrase]]
925973e6a3Sdanielk1977  }
935973e6a3Sdanielk1977
945973e6a3Sdanielk1977  set iNH [expr {$iHeight - 1}]
955973e6a3Sdanielk1977  return [list $op [random_expr_tree $iNH] [random_expr_tree $iNH]]
965973e6a3Sdanielk1977}
975973e6a3Sdanielk1977
985973e6a3Sdanielk1977# Given an expression tree, generate a corresponding expression.
995973e6a3Sdanielk1977#
1005973e6a3Sdanielk1977proc tree_to_expr {tree all_brackets implicit_and} {
1015973e6a3Sdanielk1977  set prec(NOT) 2
1025973e6a3Sdanielk1977  set prec(AND) 3
1035973e6a3Sdanielk1977  set prec()    3
1045973e6a3Sdanielk1977  set prec(OR)  4
1055973e6a3Sdanielk1977
1065973e6a3Sdanielk1977  set op [lindex $tree 0]
1075973e6a3Sdanielk1977
1085973e6a3Sdanielk1977  if {$op eq "P"} {
1095973e6a3Sdanielk1977    set phrase [lindex $tree 1]
1105973e6a3Sdanielk1977    if {[llength $phrase]>1} {
1115973e6a3Sdanielk1977      return "\"$phrase\""
1125973e6a3Sdanielk1977    } else {
1135973e6a3Sdanielk1977      return $phrase
1145973e6a3Sdanielk1977    }
1155973e6a3Sdanielk1977  }
1165973e6a3Sdanielk1977
1175973e6a3Sdanielk1977  if {$op eq "NEAR/10"} {
1185973e6a3Sdanielk1977    set op "NEAR"
1195973e6a3Sdanielk1977  }
1205973e6a3Sdanielk1977  if {$op eq "AND" && $implicit_and} {
1215973e6a3Sdanielk1977    set op ""
1225973e6a3Sdanielk1977  }
1235973e6a3Sdanielk1977
1245973e6a3Sdanielk1977  set lhs [lindex $tree 1]
1255973e6a3Sdanielk1977  set rhs [lindex $tree 2]
1265973e6a3Sdanielk1977  set zLeft  [tree_to_expr $lhs $all_brackets $implicit_and]
1275973e6a3Sdanielk1977  set zRight [tree_to_expr $rhs $all_brackets $implicit_and]
1285973e6a3Sdanielk1977
1295973e6a3Sdanielk1977  set iPrec 5
1305973e6a3Sdanielk1977  set iLeftPrec 0
1315973e6a3Sdanielk1977  set iRightPrec 0
1325973e6a3Sdanielk1977
1335973e6a3Sdanielk1977  catch {set iPrec      $prec($op)}
1345973e6a3Sdanielk1977  catch {set iLeftPrec  $prec([lindex $lhs 0])}
1355973e6a3Sdanielk1977  catch {set iRightPrec $prec([lindex $rhs 0])}
1365973e6a3Sdanielk1977
1375973e6a3Sdanielk1977  if {$iLeftPrec > $iPrec || $all_brackets} {
1385973e6a3Sdanielk1977    set zLeft "($zLeft)"
1395973e6a3Sdanielk1977  }
1405973e6a3Sdanielk1977  if {$iRightPrec >= $iPrec || $all_brackets} {
1415973e6a3Sdanielk1977    set zRight "($zRight)"
1425973e6a3Sdanielk1977  }
1435973e6a3Sdanielk1977
1445973e6a3Sdanielk1977  return "$zLeft $op $zRight"
1455973e6a3Sdanielk1977}
1465973e6a3Sdanielk1977
1475973e6a3Sdanielk1977proc do_exprparse_test {name expr tree} {
1485973e6a3Sdanielk1977  uplevel do_test $name [list "test_fts3expr2 {$expr}"] [list $tree]
1495973e6a3Sdanielk1977}
1505973e6a3Sdanielk1977
1515973e6a3Sdanielk1977for {set iTest 1} {$iTest<500} {incr iTest} {
1525973e6a3Sdanielk1977  set t [random_expr_tree 4]
1535973e6a3Sdanielk1977
1545973e6a3Sdanielk1977  set e1 [tree_to_expr $t 0 0]
1555973e6a3Sdanielk1977  set e2 [tree_to_expr $t 0 1]
1565973e6a3Sdanielk1977  set e3 [tree_to_expr $t 1 0]
1575973e6a3Sdanielk1977  set e4 [tree_to_expr $t 1 1]
1585973e6a3Sdanielk1977
1595973e6a3Sdanielk1977  do_exprparse_test fts3expr2-$iTest.1 $e1 $t
1605973e6a3Sdanielk1977  do_exprparse_test fts3expr2-$iTest.2 $e2 $t
1615973e6a3Sdanielk1977  do_exprparse_test fts3expr2-$iTest.3 $e3 $t
1625973e6a3Sdanielk1977  do_exprparse_test fts3expr2-$iTest.4 $e4 $t
1635973e6a3Sdanielk1977}
1645973e6a3Sdanielk1977
1655973e6a3Sdanielk1977set sqlite_fts3_enable_parentheses 0
1665973e6a3Sdanielk1977finish_test
167