fts5dlidx.test 5.3 KB

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