3 # The author disclaims copyright to this source code. In place of
4 # a legal notice, here is a blessing:
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.
10 #***********************************************************************
12 # This test is focused on uses of doclist-index records.
15 source [file join [file dirname [info script]] fts5_common.tcl]
16 set testprefix fts5dlidx
18 # If SQLITE_ENABLE_FTS5 is defined, omit this file.
24 if { $tcl_platform(wordSize)<8 } {
29 foreach_detail_mode $testprefix {
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]
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:
40 # ($iFirst + $i*$nStep)
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.
46 proc do_dlidx_test1 {tn spc1 spc2 nEntry iFirst nStep} {
48 do_execsql_test $tn.0 { DELETE FROM t1 }
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} {
60 if {($i % $spc2)==0} {
65 execsql { INSERT INTO t1(rowid, x) VALUES($rowid, $doc) }
70 execsql { INSERT INTO t1(t1) VALUES('integrity-check') }
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
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
79 if {[detail_is_full]} {
81 SELECT rowid FROM t1 WHERE t1 MATCH 'a + b + c + x' } $xdoc
83 SELECT rowid FROM t1 WHERE t1 MATCH 'b + c + x + y' } $ydoc
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);
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]
106 proc do_dlidx_test2 {tn nEntry iFirst nStep} {
107 set str [string repeat "a " 500]
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');
116 SELECT 1, $iFirst UNION ALL
117 SELECT ii+1, i+$nStep FROM iii WHERE ii<$nEntry
119 INSERT INTO t1(rowid,x) SELECT i, $str FROM iii;
123 do_execsql_test $tn.1 {
124 SELECT rowid FROM t1 WHERE t1 MATCH 'b AND a'
126 do_execsql_test $tn.2 {
127 SELECT rowid FROM t1 WHERE t1 MATCH 'b AND a' ORDER BY rowid DESC
131 do_dlidx_test2 2.1 [expr 20] [expr 1<<57] [expr (1<<57) + 128]
133 #--------------------------------------------------------------------
138 IteratorpItercurrentlypointstothefirstrowidofadoclist \
139 Thereisadoclistindexassociatedwiththefinaltermonthecurrent \
140 pageIfthecurrenttermisthelasttermonthepageloadthe \
141 doclistindexfromdiskandinitializeaniteratoratpIterpDlidx \
142 IteratorpItercurrentlypointstothefirstrowidofadoclist \
143 Thereisadoclistindexassociatedwiththefinaltermonthecurrent \
144 pageIfthecurrenttermisthelasttermonthepageloadthe \
145 doclistindexfromdiskandinitializeaniteratoratpIterpDlidx \
149 set nVocab [llength $vocab]
151 for {set i 0} {$i < 64} {incr i} {
152 lappend ret [lindex $vocab [expr $i % $nVocab]]
156 db func rnddoc rnddoc
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);
162 INSERT INTO abc VALUES ( rnddoc() );
163 INSERT INTO abc VALUES ( rnddoc() );
164 INSERT INTO abc VALUES ( rnddoc() );
165 INSERT INTO abc VALUES ( rnddoc() );
167 INSERT INTO abc SELECT rnddoc() FROM abc;
168 INSERT INTO abc SELECT rnddoc() FROM abc;
173 do_execsql_test 3.2 {
174 SELECT rowid FROM abc WHERE abc
175 MATCH 'IteratorpItercurrentlypointstothefirstrowidofadoclist'
177 } {16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1}
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');
185 set v [lindex $vocab 0]
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}
193 } ;# foreach_detail_mode