fts5contentless2.test 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. # 2023 July 19
  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 file contains tests for the content= and content_rowid= options.
  13. #
  14. source [file join [file dirname [info script]] fts5_common.tcl]
  15. set testprefix fts5contentless2
  16. # If SQLITE_ENABLE_FTS5 is not defined, omit this file.
  17. ifcapable !fts5 {
  18. finish_test
  19. return
  20. }
  21. proc vocab {} {
  22. list aaa bbb ccc ddd eee fff ggg hhh iii jjj kkk lll mmm nnn ooo ppp
  23. }
  24. proc document {nToken} {
  25. set doc [list]
  26. set vocab [vocab]
  27. for {set ii 0} {$ii < $nToken} {incr ii} {
  28. lappend doc [lindex $vocab [expr int(rand()*[llength $vocab])]]
  29. }
  30. set doc
  31. }
  32. db func document document
  33. proc contains {doc token} {
  34. expr {[lsearch $doc $token]>=0}
  35. }
  36. db func contains contains
  37. proc do_compare_tables_test {tn} {
  38. uplevel [list do_test $tn {
  39. foreach v [vocab] {
  40. set l1 [execsql { SELECT rowid FROM t1 WHERE contains(doc, $v) }]
  41. set l2 [execsql { SELECT rowid FROM t2($v) }]
  42. if {$l1!=$l2} { error "1: query mismatch ($l1) ($l2)" }
  43. set w "[string range $v 0 1]*"
  44. set l1 [execsql { SELECT rowid FROM t1 WHERE contains(doc, $w) }]
  45. set l2 [execsql { SELECT rowid FROM t2($w) }]
  46. if {$l1!=$l2} { error "2: query mismatch ($l1) ($l2)" }
  47. set w "[string range $v 0 0]*"
  48. set l1 [execsql { SELECT rowid FROM t1 WHERE contains(doc, $w) }]
  49. set l2 [execsql { SELECT rowid FROM t2($w) }]
  50. if {$l1!=$l2} { error "2: query mismatch ($l1) ($l2)" }
  51. set l1 [execsql {
  52. SELECT rowid FROM t1 WHERE contains(doc, $v) ORDER BY rowid DESC
  53. }]
  54. set l2 [execsql { SELECT rowid FROM t2($v) ORDER BY rowid DESC }]
  55. if {$l1!=$l2} { error "1: query mismatch ($l1) ($l2)" }
  56. }
  57. set {} {}
  58. } {}]
  59. }
  60. proc lshuffle {in} {
  61. set L [list]
  62. set ret [list]
  63. foreach elem $in { lappend L [list [expr rand()] $elem] }
  64. foreach pair [lsort -index 0 $L] { lappend ret [lindex $pair 1] }
  65. set ret
  66. }
  67. expr srand(0)
  68. do_execsql_test 1.0 {
  69. CREATE VIRTUAL TABLE t2 USING fts5(
  70. doc, prefix=2, content=, contentless_delete=1
  71. );
  72. CREATE TABLE t1(doc);
  73. CREATE TRIGGER tr1 AFTER DELETE ON t1 BEGIN
  74. DELETE FROM t2 WHERE rowid = old.rowid;
  75. END;
  76. }
  77. set SMALLEST64 -9223372036854775808
  78. set LARGEST64 9223372036854775807
  79. foreach {tn r1 r2} {
  80. 1 0 50
  81. 2 $SMALLEST64 $SMALLEST64+50
  82. 3 $LARGEST64-50 $LARGEST64
  83. 4 -50 -1
  84. } {
  85. set r1 [expr $r1]
  86. set r2 [expr $r2]
  87. do_test 1.1.$tn {
  88. execsql BEGIN
  89. for {set ii $r1} {$ii <= $r2} {incr ii} {
  90. execsql { INSERT INTO t1(rowid, doc) VALUES ($ii, document(8)); }
  91. }
  92. execsql COMMIT
  93. } {}
  94. }
  95. do_test 1.2 {
  96. db eval { SELECT rowid, doc FROM t1 } {
  97. execsql { INSERT INTO t2(rowid, doc) VALUES($rowid, $doc) }
  98. }
  99. } {}
  100. foreach {tn rowid} {
  101. 1 $SMALLEST64
  102. 2 0
  103. 3 -5
  104. 4 -30
  105. 5 $LARGEST64
  106. 6 $LARGEST64-1
  107. } {
  108. set rowid [expr $rowid]
  109. do_execsql_test 1.3.$tn.1 {
  110. DELETE FROM t1 WHERE rowid=$rowid
  111. }
  112. do_compare_tables_test 1.3.$tn.2
  113. }
  114. set iTest 1
  115. foreach r [lshuffle [execsql {SELECT rowid FROM t1}]] {
  116. if {($iTest % 50)==0} {
  117. execsql { INSERT INTO t2(t2) VALUES('optimize') }
  118. }
  119. if {($iTest % 5)==0} {
  120. execsql { INSERT INTO t2(t2, rank) VALUES('merge', 5) }
  121. }
  122. do_execsql_test 1.4.$iTest.1($r) {
  123. DELETE FROM t1 WHERE rowid=$r
  124. }
  125. do_compare_tables_test 1.4.$iTest.2
  126. incr iTest
  127. }
  128. do_execsql_test 1.5 {
  129. SELECT * FROM t1
  130. } {}
  131. #-------------------------------------------------------------------------
  132. reset_db
  133. db func document document
  134. do_execsql_test 2.0 {
  135. CREATE VIRTUAL TABLE t2 USING fts5(doc, content=, contentless_delete=1);
  136. WITH s(i) AS (
  137. SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<1000
  138. )
  139. INSERT INTO t2(rowid, doc) SELECT i, i || ' ' || i FROM s;
  140. }
  141. do_execsql_test 2.1 {
  142. BEGIN;
  143. DELETE FROM t2 WHERE rowid=32;
  144. DELETE FROM t2 WHERE rowid=64;
  145. DELETE FROM t2 WHERE rowid=96;
  146. DELETE FROM t2 WHERE rowid=128;
  147. DELETE FROM t2 WHERE rowid=160;
  148. DELETE FROM t2 WHERE rowid=192;
  149. COMMIT;
  150. }
  151. do_execsql_test 2.2 {
  152. SELECT * FROM t2('128');
  153. } {}
  154. #-------------------------------------------------------------------------
  155. foreach {tn step} {
  156. 1 3
  157. 2 7
  158. 3 15
  159. } {
  160. set step [expr $step]
  161. reset_db
  162. db func document document
  163. do_execsql_test 3.$tn.0 {
  164. CREATE VIRTUAL TABLE t2 USING fts5(doc, content=, contentless_delete=1);
  165. INSERT INTO t2(t2, rank) VALUES('pgsz', 100);
  166. WITH s(i) AS (
  167. SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<1000
  168. )
  169. INSERT INTO t2(rowid, doc) SELECT i, i || ' ' || i FROM s;
  170. }
  171. do_execsql_test 3.$tn.1 {
  172. DELETE FROM t2 WHERE (rowid % $step)==0
  173. }
  174. do_execsql_test 3.$tn.2 {
  175. SELECT * FROM t2( $step * 5 )
  176. } {}
  177. }
  178. finish_test