summaryrefslogtreecommitdiffstats
path: root/ext/fts5/test/fts5dlidx.test
diff options
context:
space:
mode:
Diffstat (limited to 'ext/fts5/test/fts5dlidx.test')
-rw-r--r--ext/fts5/test/fts5dlidx.test197
1 files changed, 197 insertions, 0 deletions
diff --git a/ext/fts5/test/fts5dlidx.test b/ext/fts5/test/fts5dlidx.test
new file mode 100644
index 0000000..1fb95a9
--- /dev/null
+++ b/ext/fts5/test/fts5dlidx.test
@@ -0,0 +1,197 @@
+# 2015 April 21
+#
+# The author disclaims copyright to this source code. In place of
+# a legal notice, here is a blessing:
+#
+# May you do good and not evil.
+# May you find forgiveness for yourself and forgive others.
+# May you share freely, never taking more than you give.
+#
+#***********************************************************************
+#
+# This test is focused on uses of doclist-index records.
+#
+
+source [file join [file dirname [info script]] fts5_common.tcl]
+set testprefix fts5dlidx
+
+# If SQLITE_ENABLE_FTS5 is defined, omit this file.
+ifcapable !fts5 {
+ finish_test
+ return
+}
+
+if { $tcl_platform(wordSize)<8 } {
+ finish_test
+ return
+}
+
+foreach_detail_mode $testprefix {
+
+proc do_fb_test {tn sql res} {
+ set res2 [lsort -integer -decr $res]
+ uplevel [list do_execsql_test $tn.1 $sql $res]
+ uplevel [list do_execsql_test $tn.2 "$sql ORDER BY rowid DESC" $res2]
+}
+
+# This test populates the FTS5 table with $nEntry entries. Rows are
+# numbered from 0 to ($nEntry-1). The rowid for row $i is:
+#
+# ($iFirst + $i*$nStep)
+#
+# Each document is of the form "a b c a b c a b c...". If the row number ($i)
+# is an integer multiple of $spc1, then an "x" token is appended to the
+# document. If it is *also* a multiple of $spc2, a "y" token is also appended.
+#
+proc do_dlidx_test1 {tn spc1 spc2 nEntry iFirst nStep} {
+
+ do_execsql_test $tn.0 { DELETE FROM t1 }
+
+ set xdoc [list]
+ set ydoc [list]
+
+ execsql BEGIN
+ for {set i 0} {$i < $nEntry} {incr i} {
+ set rowid [expr $i * $nStep]
+ set doc [string trim [string repeat "a b c " 100]]
+ if {($i % $spc1)==0} {
+ lappend xdoc $rowid
+ append doc " x"
+ if {($i % $spc2)==0} {
+ lappend ydoc $rowid
+ append doc " y"
+ }
+ }
+ execsql { INSERT INTO t1(rowid, x) VALUES($rowid, $doc) }
+ }
+ execsql COMMIT
+
+ do_test $tn.1 {
+ execsql { INSERT INTO t1(t1) VALUES('integrity-check') }
+ } {}
+
+ do_fb_test $tn.3.1 { SELECT rowid FROM t1 WHERE t1 MATCH 'a AND x' } $xdoc
+ do_fb_test $tn.3.2 { SELECT rowid FROM t1 WHERE t1 MATCH 'x AND a' } $xdoc
+
+ do_fb_test $tn.4.1 { SELECT rowid FROM t1 WHERE t1 MATCH 'a AND y' } $ydoc
+ do_fb_test $tn.4.2 { SELECT rowid FROM t1 WHERE t1 MATCH 'y AND a' } $ydoc
+
+ if {[detail_is_full]} {
+ do_fb_test $tn.5.1 {
+ SELECT rowid FROM t1 WHERE t1 MATCH 'a + b + c + x' } $xdoc
+ do_fb_test $tn.5.2 {
+ SELECT rowid FROM t1 WHERE t1 MATCH 'b + c + x + y' } $ydoc
+ }
+}
+
+
+foreach {tn pgsz} {
+ 1 32
+ 2 200
+} {
+ do_execsql_test $tn.0 {
+ DROP TABLE IF EXISTS t1;
+ CREATE VIRTUAL TABLE t1 USING fts5(x, detail=%DETAIL%);
+ INSERT INTO t1(t1, rank) VALUES('pgsz', $pgsz);
+ }
+
+ do_dlidx_test1 1.$tn.1 10 100 10000 0 1000
+ do_dlidx_test1 1.$tn.2 10 10 10000 0 128
+ do_dlidx_test1 1.$tn.3 10 10 66 0 36028797018963970
+ do_dlidx_test1 1.$tn.4 10 10 50 0 150000000000000000
+ do_dlidx_test1 1.$tn.5 10 10 200 0 [expr 1<<55]
+ do_dlidx_test1 1.$tn.6 10 10 30 0 [expr 1<<58]
+}
+
+proc do_dlidx_test2 {tn nEntry iFirst nStep} {
+ set str [string repeat "a " 500]
+ execsql {
+ BEGIN;
+ DROP TABLE IF EXISTS t1;
+ CREATE VIRTUAL TABLE t1 USING fts5(x, detail=%DETAIL%);
+ INSERT INTO t1(t1, rank) VALUES('pgsz', 64);
+ INSERT INTO t1 VALUES('b a');
+
+ WITH iii(ii, i) AS (
+ SELECT 1, $iFirst UNION ALL
+ SELECT ii+1, i+$nStep FROM iii WHERE ii<$nEntry
+ )
+ INSERT INTO t1(rowid,x) SELECT i, $str FROM iii;
+ COMMIT;
+ }
+
+ do_execsql_test $tn.1 {
+ SELECT rowid FROM t1 WHERE t1 MATCH 'b AND a'
+ } {1}
+ do_execsql_test $tn.2 {
+ SELECT rowid FROM t1 WHERE t1 MATCH 'b AND a' ORDER BY rowid DESC
+ } {1}
+}
+
+do_dlidx_test2 2.1 [expr 20] [expr 1<<57] [expr (1<<57) + 128]
+
+#--------------------------------------------------------------------
+#
+reset_db
+
+set ::vocab [list \
+ IteratorpItercurrentlypointstothefirstrowidofadoclist \
+ Thereisadoclistindexassociatedwiththefinaltermonthecurrent \
+ pageIfthecurrenttermisthelasttermonthepageloadthe \
+ doclistindexfromdiskandinitializeaniteratoratpIterpDlidx \
+ IteratorpItercurrentlypointstothefirstrowidofadoclist \
+ Thereisadoclistindexassociatedwiththefinaltermonthecurrent \
+ pageIfthecurrenttermisthelasttermonthepageloadthe \
+ doclistindexfromdiskandinitializeaniteratoratpIterpDlidx \
+]
+proc rnddoc {} {
+ global vocab
+ set nVocab [llength $vocab]
+ set ret [list]
+ for {set i 0} {$i < 64} {incr i} {
+ lappend ret [lindex $vocab [expr $i % $nVocab]]
+ }
+ set ret
+}
+db func rnddoc rnddoc
+
+do_execsql_test 3.1 {
+ CREATE VIRTUAL TABLE abc USING fts5(a, detail=%DETAIL%);
+ INSERT INTO abc(abc, rank) VALUES('pgsz', 32);
+
+ INSERT INTO abc VALUES ( rnddoc() );
+ INSERT INTO abc VALUES ( rnddoc() );
+ INSERT INTO abc VALUES ( rnddoc() );
+ INSERT INTO abc VALUES ( rnddoc() );
+
+ INSERT INTO abc SELECT rnddoc() FROM abc;
+ INSERT INTO abc SELECT rnddoc() FROM abc;
+}
+
+
+
+do_execsql_test 3.2 {
+ SELECT rowid FROM abc WHERE abc
+ MATCH 'IteratorpItercurrentlypointstothefirstrowidofadoclist'
+ ORDER BY rowid DESC;
+} {16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1}
+
+do_execsql_test 3.3 {
+ INSERT INTO abc(abc) VALUES('integrity-check');
+ INSERT INTO abc(abc) VALUES('optimize');
+ INSERT INTO abc(abc) VALUES('integrity-check');
+}
+
+set v [lindex $vocab 0]
+set i 0
+foreach v $vocab {
+ do_execsql_test 3.4.[incr i] {
+ SELECT rowid FROM abc WHERE abc MATCH $v
+ } {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16}
+}
+
+} ;# foreach_detail_mode
+
+
+
+finish_test