github.com/jdgcs/sqlite3@v1.12.1-0.20210908114423-bc5f96e4dd51/testdata/tcl/fts2p.test (about)

     1  # 2008 June 26
     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 exercises some new testing functions in the FTS2 module,
    12  # and then uses them to do some basic tests that FTS2 is internally
    13  # working as expected.
    14  #
    15  # $Id: fts2p.test,v 1.1 2008/07/22 23:32:28 shess Exp $
    16  #
    17  
    18  set testdir [file dirname $argv0]
    19  source $testdir/tester.tcl
    20  
    21  # If SQLITE_ENABLE_FTS2 is not defined, omit this file.
    22  ifcapable !fts2 {
    23    finish_test
    24    return
    25  }
    26  
    27  #*************************************************************************
    28  # Probe to see if support for these functions is compiled in.
    29  # TODO(shess): Change main.mk to do the right thing and remove this test.
    30  db eval {
    31    DROP TABLE IF EXISTS t1;
    32    CREATE VIRTUAL TABLE t1 USING fts2(c);
    33    INSERT INTO t1 (rowid, c) VALUES (1, 'x');
    34  }
    35  
    36  set s {SELECT dump_terms(t1, 1) FROM t1 LIMIT 1}
    37  set r {1 {unable to use function dump_terms in the requested context}}
    38  if {[catchsql $s]==$r} {
    39    finish_test
    40    return
    41  }
    42  
    43  #*************************************************************************
    44  # Test that the new functions give appropriate errors.
    45  do_test fts2p-0.0 {
    46    catchsql {
    47      SELECT dump_terms(t1, 1) FROM t1 LIMIT 1;
    48    }
    49  } {1 {dump_terms: incorrect arguments}}
    50  
    51  do_test fts2p-0.1 {
    52    catchsql {
    53      SELECT dump_terms(t1, 0, 0, 0) FROM t1 LIMIT 1;
    54    }
    55  } {1 {dump_terms: incorrect arguments}}
    56  
    57  do_test fts2p-0.2 {
    58    catchsql {
    59      SELECT dump_terms(1, t1) FROM t1 LIMIT 1;
    60    }
    61  } {1 {unable to use function dump_terms in the requested context}}
    62  
    63  do_test fts2p-0.3 {
    64    catchsql {
    65      SELECT dump_terms(t1, 16, 16) FROM t1 LIMIT 1;
    66    }
    67  } {1 {dump_terms: segment not found}}
    68  
    69  do_test fts2p-0.4 {
    70    catchsql {
    71      SELECT dump_doclist(t1) FROM t1 LIMIT 1;
    72    }
    73  } {1 {dump_doclist: incorrect arguments}}
    74  
    75  do_test fts2p-0.5 {
    76    catchsql {
    77      SELECT dump_doclist(t1, NULL) FROM t1 LIMIT 1;
    78    }
    79  } {1 {dump_doclist: empty second argument}}
    80  
    81  do_test fts2p-0.6 {
    82    catchsql {
    83      SELECT dump_doclist(t1, '') FROM t1 LIMIT 1;
    84    }
    85  } {1 {dump_doclist: empty second argument}}
    86  
    87  do_test fts2p-0.7 {
    88    catchsql {
    89      SELECT dump_doclist(t1, 'a', 0) FROM t1 LIMIT 1;
    90    }
    91  } {1 {dump_doclist: incorrect arguments}}
    92  
    93  do_test fts2p-0.8 {
    94    catchsql {
    95      SELECT dump_doclist(t1, 'a', 0, 0, 0) FROM t1 LIMIT 1;
    96    }
    97  } {1 {dump_doclist: incorrect arguments}}
    98  
    99  do_test fts2p-0.9 {
   100    catchsql {
   101      SELECT dump_doclist(t1, 'a', 16, 16) FROM t1 LIMIT 1;
   102    }
   103  } {1 {dump_doclist: segment not found}}
   104  
   105  #*************************************************************************
   106  # Utility function to check for the expected terms in the segment
   107  # level/index.  _all version does same but for entire index.
   108  proc check_terms {test level index terms} {
   109    # TODO(shess): Figure out why uplevel in do_test can't catch
   110    # $level and $index directly.
   111    set ::level $level
   112    set ::index $index
   113    do_test $test.terms {
   114      execsql {
   115        SELECT dump_terms(t1, $::level, $::index) FROM t1 LIMIT 1;
   116      }
   117    } [list $terms]
   118  }
   119  proc check_terms_all {test terms} {
   120    do_test $test.terms {
   121      execsql {
   122        SELECT dump_terms(t1) FROM t1 LIMIT 1;
   123      }
   124    } [list $terms]
   125  }
   126  
   127  # Utility function to check for the expected doclist for the term in
   128  # segment level/index.  _all version does same for entire index.
   129  proc check_doclist {test level index term doclist} {
   130    # TODO(shess): Again, why can't the non-:: versions work?
   131    set ::term $term
   132    set ::level $level
   133    set ::index $index
   134    do_test $test {
   135      execsql {
   136        SELECT dump_doclist(t1, $::term, $::level, $::index) FROM t1 LIMIT 1;
   137      }
   138    } [list $doclist]
   139  }
   140  proc check_doclist_all {test term doclist} {
   141    set ::term $term
   142    do_test $test {
   143      execsql {
   144        SELECT dump_doclist(t1, $::term) FROM t1 LIMIT 1;
   145      }
   146    } [list $doclist]
   147  }
   148  
   149  #*************************************************************************
   150  # Test the segments resulting from straight-forward inserts.
   151  db eval {
   152    DROP TABLE IF EXISTS t1;
   153    CREATE VIRTUAL TABLE t1 USING fts2(c);
   154    INSERT INTO t1 (rowid, c) VALUES (1, 'This is a test');
   155    INSERT INTO t1 (rowid, c) VALUES (2, 'That was a test');
   156    INSERT INTO t1 (rowid, c) VALUES (3, 'This is a test');
   157  }
   158  
   159  # Check for expected segments and expected matches.
   160  do_test fts2p-1.0.segments {
   161    execsql {
   162      SELECT level, idx FROM t1_segdir ORDER BY level, idx;
   163    }
   164  } {0 0 0 1 0 2}
   165  do_test fts2p-1.0.matches {
   166    execsql {
   167      SELECT OFFSETS(t1) FROM t1
   168       WHERE t1 MATCH 'this OR that OR was OR a OR is OR test' ORDER BY rowid;
   169    }
   170  } [list {0 0 0 4 0 4 5 2 0 3 8 1 0 5 10 4} \
   171          {0 1 0 4 0 2 5 3 0 3 9 1 0 5 11 4} \
   172          {0 0 0 4 0 4 5 2 0 3 8 1 0 5 10 4}]
   173  
   174  # Check the specifics of the segments constructed.
   175  # Logical view of entire index.
   176  check_terms_all   fts2p-1.0.1   {a is test that this was}
   177  check_doclist_all fts2p-1.0.1.1 a {[1 0[2]] [2 0[2]] [3 0[2]]}
   178  check_doclist_all fts2p-1.0.1.2 is {[1 0[1]] [3 0[1]]}
   179  check_doclist_all fts2p-1.0.1.3 test {[1 0[3]] [2 0[3]] [3 0[3]]}
   180  check_doclist_all fts2p-1.0.1.4 that {[2 0[0]]}
   181  check_doclist_all fts2p-1.0.1.5 this {[1 0[0]] [3 0[0]]}
   182  check_doclist_all fts2p-1.0.1.6 was {[2 0[1]]}
   183  
   184  # Segment 0,0
   185  check_terms   fts2p-1.0.2   0 0 {a is test this}
   186  check_doclist fts2p-1.0.2.1 0 0 a {[1 0[2]]}
   187  check_doclist fts2p-1.0.2.2 0 0 is {[1 0[1]]}
   188  check_doclist fts2p-1.0.2.3 0 0 test {[1 0[3]]}
   189  check_doclist fts2p-1.0.2.4 0 0 this {[1 0[0]]}
   190  
   191  # Segment 0,1
   192  check_terms   fts2p-1.0.3   0 1 {a test that was}
   193  check_doclist fts2p-1.0.3.1 0 1 a {[2 0[2]]}
   194  check_doclist fts2p-1.0.3.2 0 1 test {[2 0[3]]}
   195  check_doclist fts2p-1.0.3.3 0 1 that {[2 0[0]]}
   196  check_doclist fts2p-1.0.3.4 0 1 was {[2 0[1]]}
   197  
   198  # Segment 0,2
   199  check_terms   fts2p-1.0.4   0 2 {a is test this}
   200  check_doclist fts2p-1.0.4.1 0 2 a {[3 0[2]]}
   201  check_doclist fts2p-1.0.4.2 0 2 is {[3 0[1]]}
   202  check_doclist fts2p-1.0.4.3 0 2 test {[3 0[3]]}
   203  check_doclist fts2p-1.0.4.4 0 2 this {[3 0[0]]}
   204  
   205  #*************************************************************************
   206  # Test the segments resulting from inserts followed by a delete.
   207  db eval {
   208    DROP TABLE IF EXISTS t1;
   209    CREATE VIRTUAL TABLE t1 USING fts2(c);
   210    INSERT INTO t1 (rowid, c) VALUES (1, 'This is a test');
   211    INSERT INTO t1 (rowid, c) VALUES (2, 'That was a test');
   212    INSERT INTO t1 (rowid, c) VALUES (3, 'This is a test');
   213    DELETE FROM t1 WHERE rowid = 1;
   214  }
   215  
   216  do_test fts2p-1.1.segments {
   217    execsql {
   218      SELECT level, idx FROM t1_segdir ORDER BY level, idx;
   219    }
   220  } {0 0 0 1 0 2 0 3}
   221  do_test fts2p-1.1.matches {
   222    execsql {
   223      SELECT OFFSETS(t1) FROM t1
   224       WHERE t1 MATCH 'this OR that OR was OR a OR is OR test' ORDER BY rowid;
   225    }
   226  } {{0 1 0 4 0 2 5 3 0 3 9 1 0 5 11 4} {0 0 0 4 0 4 5 2 0 3 8 1 0 5 10 4}}
   227  
   228  check_terms_all fts2p-1.1.1 {a is test that this was}
   229  check_doclist_all fts2p-1.1.1.1 a {[2 0[2]] [3 0[2]]}
   230  check_doclist_all fts2p-1.1.1.2 is {[3 0[1]]}
   231  check_doclist_all fts2p-1.1.1.3 test {[2 0[3]] [3 0[3]]}
   232  check_doclist_all fts2p-1.1.1.4 that {[2 0[0]]}
   233  check_doclist_all fts2p-1.1.1.5 this {[3 0[0]]}
   234  check_doclist_all fts2p-1.1.1.6 was {[2 0[1]]}
   235  
   236  check_terms fts2p-1.1.2 0 0 {a is test this}
   237  check_doclist fts2p-1.1.2.1 0 0 a {[1 0[2]]}
   238  check_doclist fts2p-1.1.2.2 0 0 is {[1 0[1]]}
   239  check_doclist fts2p-1.1.2.3 0 0 test {[1 0[3]]}
   240  check_doclist fts2p-1.1.2.4 0 0 this {[1 0[0]]}
   241  
   242  check_terms fts2p-1.1.3 0 1 {a test that was}
   243  check_doclist fts2p-1.1.3.1 0 1 a {[2 0[2]]}
   244  check_doclist fts2p-1.1.3.2 0 1 test {[2 0[3]]}
   245  check_doclist fts2p-1.1.3.3 0 1 that {[2 0[0]]}
   246  check_doclist fts2p-1.1.3.4 0 1 was {[2 0[1]]}
   247  
   248  check_terms fts2p-1.1.4 0 2 {a is test this}
   249  check_doclist fts2p-1.1.4.1 0 2 a {[3 0[2]]}
   250  check_doclist fts2p-1.1.4.2 0 2 is {[3 0[1]]}
   251  check_doclist fts2p-1.1.4.3 0 2 test {[3 0[3]]}
   252  check_doclist fts2p-1.1.4.4 0 2 this {[3 0[0]]}
   253  
   254  check_terms fts2p-1.1.5 0 3 {a is test this}
   255  check_doclist fts2p-1.1.5.1 0 3 a {[1]}
   256  check_doclist fts2p-1.1.5.2 0 3 is {[1]}
   257  check_doclist fts2p-1.1.5.3 0 3 test {[1]}
   258  check_doclist fts2p-1.1.5.4 0 3 this {[1]}
   259  
   260  #*************************************************************************
   261  # Test results when all references to certain tokens are deleted.
   262  db eval {
   263    DROP TABLE IF EXISTS t1;
   264    CREATE VIRTUAL TABLE t1 USING fts2(c);
   265    INSERT INTO t1 (rowid, c) VALUES (1, 'This is a test');
   266    INSERT INTO t1 (rowid, c) VALUES (2, 'That was a test');
   267    INSERT INTO t1 (rowid, c) VALUES (3, 'This is a test');
   268    DELETE FROM t1 WHERE rowid IN (1,3);
   269  }
   270  
   271  # Still 4 segments because 0,3 will contain deletes for rowid 1 and 3.
   272  do_test fts2p-1.2.segments {
   273    execsql {
   274      SELECT level, idx FROM t1_segdir ORDER BY level, idx;
   275    }
   276  } {0 0 0 1 0 2 0 3}
   277  do_test fts2p-1.2.matches {
   278    execsql {
   279      SELECT OFFSETS(t1) FROM t1
   280       WHERE t1 MATCH 'this OR that OR was OR a OR is OR test' ORDER BY rowid;
   281    }
   282  } {{0 1 0 4 0 2 5 3 0 3 9 1 0 5 11 4}}
   283  
   284  check_terms_all fts2p-1.2.1 {a is test that this was}
   285  check_doclist_all fts2p-1.2.1.1 a {[2 0[2]]}
   286  check_doclist_all fts2p-1.2.1.2 is {}
   287  check_doclist_all fts2p-1.2.1.3 test {[2 0[3]]}
   288  check_doclist_all fts2p-1.2.1.4 that {[2 0[0]]}
   289  check_doclist_all fts2p-1.2.1.5 this {}
   290  check_doclist_all fts2p-1.2.1.6 was {[2 0[1]]}
   291  
   292  check_terms fts2p-1.2.2 0 0 {a is test this}
   293  check_doclist fts2p-1.2.2.1 0 0 a {[1 0[2]]}
   294  check_doclist fts2p-1.2.2.2 0 0 is {[1 0[1]]}
   295  check_doclist fts2p-1.2.2.3 0 0 test {[1 0[3]]}
   296  check_doclist fts2p-1.2.2.4 0 0 this {[1 0[0]]}
   297  
   298  check_terms fts2p-1.2.3 0 1 {a test that was}
   299  check_doclist fts2p-1.2.3.1 0 1 a {[2 0[2]]}
   300  check_doclist fts2p-1.2.3.2 0 1 test {[2 0[3]]}
   301  check_doclist fts2p-1.2.3.3 0 1 that {[2 0[0]]}
   302  check_doclist fts2p-1.2.3.4 0 1 was {[2 0[1]]}
   303  
   304  check_terms fts2p-1.2.4 0 2 {a is test this}
   305  check_doclist fts2p-1.2.4.1 0 2 a {[3 0[2]]}
   306  check_doclist fts2p-1.2.4.2 0 2 is {[3 0[1]]}
   307  check_doclist fts2p-1.2.4.3 0 2 test {[3 0[3]]}
   308  check_doclist fts2p-1.2.4.4 0 2 this {[3 0[0]]}
   309  
   310  check_terms fts2p-1.2.5 0 3 {a is test this}
   311  check_doclist fts2p-1.2.5.1 0 3 a {[1] [3]}
   312  check_doclist fts2p-1.2.5.2 0 3 is {[1] [3]}
   313  check_doclist fts2p-1.2.5.3 0 3 test {[1] [3]}
   314  check_doclist fts2p-1.2.5.4 0 3 this {[1] [3]}
   315  
   316  #*************************************************************************
   317  # Test results when everything is optimized manually.
   318  db eval {
   319    DROP TABLE IF EXISTS t1;
   320    CREATE VIRTUAL TABLE t1 USING fts2(c);
   321    INSERT INTO t1 (rowid, c) VALUES (1, 'This is a test');
   322    INSERT INTO t1 (rowid, c) VALUES (2, 'That was a test');
   323    INSERT INTO t1 (rowid, c) VALUES (3, 'This is a test');
   324    DELETE FROM t1 WHERE rowid IN (1,3);
   325    DROP TABLE IF EXISTS t1old;
   326    ALTER TABLE t1 RENAME TO t1old;
   327    CREATE VIRTUAL TABLE t1 USING fts2(c);
   328    INSERT INTO t1 (rowid, c) SELECT rowid, c FROM t1old;
   329    DROP TABLE t1old;
   330  }
   331  
   332  # Should be a single optimal segment with the same logical results.
   333  do_test fts2p-1.3.segments {
   334    execsql {
   335      SELECT level, idx FROM t1_segdir ORDER BY level, idx;
   336    }
   337  } {0 0}
   338  do_test fts2p-1.3.matches {
   339    execsql {
   340      SELECT OFFSETS(t1) FROM t1
   341       WHERE t1 MATCH 'this OR that OR was OR a OR is OR test' ORDER BY rowid;
   342    }
   343  } {{0 1 0 4 0 2 5 3 0 3 9 1 0 5 11 4}}
   344  
   345  check_terms_all fts2p-1.3.1 {a test that was}
   346  check_doclist_all fts2p-1.3.1.1 a {[2 0[2]]}
   347  check_doclist_all fts2p-1.3.1.2 test {[2 0[3]]}
   348  check_doclist_all fts2p-1.3.1.3 that {[2 0[0]]}
   349  check_doclist_all fts2p-1.3.1.4 was {[2 0[1]]}
   350  
   351  check_terms fts2p-1.3.2 0 0 {a test that was}
   352  check_doclist fts2p-1.3.2.1 0 0 a {[2 0[2]]}
   353  check_doclist fts2p-1.3.2.2 0 0 test {[2 0[3]]}
   354  check_doclist fts2p-1.3.2.3 0 0 that {[2 0[0]]}
   355  check_doclist fts2p-1.3.2.4 0 0 was {[2 0[1]]}
   356  
   357  finish_test