modernc.org/cc@v1.0.1/v2/testdata/_sqlite/ext/fts5/test/fts5dlidx.test (about)

     1  # 2015 April 21
     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  #
    12  # This test is focused on uses of doclist-index records.
    13  #
    14  
    15  source [file join [file dirname [info script]] fts5_common.tcl]
    16  set testprefix fts5dlidx
    17  
    18  # If SQLITE_ENABLE_FTS5 is defined, omit this file.
    19  ifcapable !fts5 {
    20    finish_test
    21    return
    22  }
    23  
    24  if { $tcl_platform(wordSize)<8 } {
    25    finish_test
    26    return
    27  }
    28  
    29  foreach_detail_mode $testprefix {
    30  
    31  proc do_fb_test {tn sql res} {
    32    set res2 [lsort -integer -decr $res]
    33    uplevel [list do_execsql_test $tn.1 $sql $res]
    34    uplevel [list do_execsql_test $tn.2 "$sql ORDER BY rowid DESC" $res2]
    35  }
    36  
    37  # This test populates the FTS5 table with $nEntry entries. Rows are 
    38  # numbered from 0 to ($nEntry-1). The rowid for row $i is:
    39  #
    40  #   ($iFirst + $i*$nStep)
    41  #
    42  # Each document is of the form "a b c a b c a b c...". If the row number ($i)
    43  # is an integer multiple of $spc1, then an "x" token is appended to the
    44  # document. If it is *also* a multiple of $spc2, a "y" token is also appended.
    45  #
    46  proc do_dlidx_test1 {tn spc1 spc2 nEntry iFirst nStep} {
    47  
    48    do_execsql_test $tn.0 { DELETE FROM t1 }
    49  
    50    set xdoc [list]
    51    set ydoc [list]
    52  
    53    execsql BEGIN
    54    for {set i 0} {$i < $nEntry} {incr i} {
    55      set rowid [expr $i * $nStep]
    56      set doc [string trim [string repeat "a b c " 100]]
    57      if {($i % $spc1)==0} {
    58        lappend xdoc $rowid
    59        append doc " x" 
    60        if {($i % $spc2)==0} { 
    61          lappend ydoc $rowid
    62          append doc " y" 
    63        }
    64      }
    65      execsql { INSERT INTO t1(rowid, x) VALUES($rowid, $doc) }
    66    }
    67    execsql COMMIT
    68  
    69    do_test $tn.1 {
    70      execsql { INSERT INTO t1(t1) VALUES('integrity-check') }
    71    } {}
    72    
    73    do_fb_test $tn.3.1 { SELECT rowid FROM t1 WHERE t1 MATCH 'a AND x' } $xdoc
    74    do_fb_test $tn.3.2 { SELECT rowid FROM t1 WHERE t1 MATCH 'x AND a' } $xdoc
    75    
    76    do_fb_test $tn.4.1 { SELECT rowid FROM t1 WHERE t1 MATCH 'a AND y' } $ydoc
    77    do_fb_test $tn.4.2 { SELECT rowid FROM t1 WHERE t1 MATCH 'y AND a' } $ydoc
    78    
    79    if {[detail_is_full]} {
    80      do_fb_test $tn.5.1 { 
    81        SELECT rowid FROM t1 WHERE t1 MATCH 'a + b + c + x' } $xdoc
    82      do_fb_test $tn.5.2 { 
    83        SELECT rowid FROM t1 WHERE t1 MATCH 'b + c + x + y' } $ydoc
    84    }
    85  }
    86  
    87  
    88  foreach {tn pgsz} {
    89    1 32
    90    2 200
    91  } {
    92    do_execsql_test $tn.0 { 
    93      DROP TABLE IF EXISTS t1;
    94      CREATE VIRTUAL TABLE t1 USING fts5(x, detail=%DETAIL%);
    95      INSERT INTO t1(t1, rank) VALUES('pgsz', $pgsz);
    96    }
    97  
    98    do_dlidx_test1 1.$tn.1     10 100 10000 0 1000
    99    do_dlidx_test1 1.$tn.2     10 10  10000 0 128
   100    do_dlidx_test1 1.$tn.3     10 10  66    0 36028797018963970
   101    do_dlidx_test1 1.$tn.4     10 10  50    0 150000000000000000
   102    do_dlidx_test1 1.$tn.5     10 10  200   0 [expr 1<<55]
   103    do_dlidx_test1 1.$tn.6      10 10  30    0 [expr 1<<58]
   104  }
   105  
   106  proc do_dlidx_test2 {tn nEntry iFirst nStep} {
   107    set str [string repeat "a " 500]
   108    execsql {
   109      BEGIN;
   110      DROP TABLE IF EXISTS t1;
   111      CREATE VIRTUAL TABLE t1 USING fts5(x, detail=%DETAIL%);
   112      INSERT INTO t1(t1, rank) VALUES('pgsz', 64);
   113      INSERT INTO t1 VALUES('b a');
   114  
   115      WITH iii(ii, i) AS (
   116        SELECT 1,     $iFirst UNION ALL 
   117        SELECT ii+1, i+$nStep FROM iii WHERE ii<$nEntry
   118      )
   119      INSERT INTO t1(rowid,x) SELECT i, $str FROM iii;
   120      COMMIT;
   121    }
   122  
   123    do_execsql_test $tn.1 {
   124      SELECT rowid FROM t1 WHERE t1 MATCH 'b AND a'
   125    } {1}
   126    do_execsql_test $tn.2 {
   127      SELECT rowid FROM t1 WHERE t1 MATCH 'b AND a' ORDER BY rowid DESC
   128    } {1}
   129  }
   130  
   131  do_dlidx_test2 2.1 [expr 20] [expr 1<<57] [expr (1<<57) + 128]
   132  
   133  #--------------------------------------------------------------------
   134  #
   135  reset_db
   136  
   137  set ::vocab [list \
   138    IteratorpItercurrentlypointstothefirstrowidofadoclist \
   139    Thereisadoclistindexassociatedwiththefinaltermonthecurrent \
   140    pageIfthecurrenttermisthelasttermonthepageloadthe \
   141    doclistindexfromdiskandinitializeaniteratoratpIterpDlidx \
   142    IteratorpItercurrentlypointstothefirstrowidofadoclist \
   143    Thereisadoclistindexassociatedwiththefinaltermonthecurrent \
   144    pageIfthecurrenttermisthelasttermonthepageloadthe \
   145    doclistindexfromdiskandinitializeaniteratoratpIterpDlidx \
   146  ]
   147  proc rnddoc {} {
   148    global vocab
   149    set nVocab [llength $vocab]
   150    set ret [list]
   151    for {set i 0} {$i < 64} {incr i} {
   152      lappend ret [lindex $vocab [expr $i % $nVocab]]
   153    }
   154    set ret
   155  }
   156  db func rnddoc rnddoc
   157  
   158  do_execsql_test 3.1 {
   159    CREATE VIRTUAL TABLE abc USING fts5(a, detail=%DETAIL%);
   160    INSERT INTO abc(abc, rank) VALUES('pgsz', 32);
   161  
   162    INSERT INTO abc VALUES ( rnddoc() );
   163    INSERT INTO abc VALUES ( rnddoc() );
   164    INSERT INTO abc VALUES ( rnddoc() );
   165    INSERT INTO abc VALUES ( rnddoc() );
   166  
   167    INSERT INTO abc SELECT rnddoc() FROM abc;
   168    INSERT INTO abc SELECT rnddoc() FROM abc;
   169  }
   170  
   171  
   172  
   173  do_execsql_test 3.2 {
   174    SELECT rowid FROM abc WHERE abc 
   175    MATCH 'IteratorpItercurrentlypointstothefirstrowidofadoclist' 
   176    ORDER BY rowid DESC;
   177  } {16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1}
   178  
   179  do_execsql_test 3.3 {
   180    INSERT INTO abc(abc) VALUES('integrity-check');
   181    INSERT INTO abc(abc) VALUES('optimize');
   182    INSERT INTO abc(abc) VALUES('integrity-check');
   183  }
   184  
   185  set v [lindex $vocab 0]
   186  set i 0
   187  foreach v $vocab {
   188    do_execsql_test 3.4.[incr i] {
   189      SELECT rowid FROM abc WHERE abc MATCH $v
   190    } {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16}
   191  }
   192  
   193  } ;# foreach_detail_mode
   194  
   195  
   196  
   197  finish_test