fts5detail.test 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. # 2015 December 18
  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. # This file implements regression tests for SQLite library. The
  12. # focus of this script is testing the FTS5 module.
  13. #
  14. source [file join [file dirname [info script]] fts5_common.tcl]
  15. set testprefix fts5detail
  16. # If SQLITE_ENABLE_FTS5 is not defined, omit this file.
  17. ifcapable !fts5 {
  18. finish_test
  19. return
  20. }
  21. fts5_aux_test_functions db
  22. #--------------------------------------------------------------------------
  23. # Simple tests.
  24. #
  25. do_execsql_test 1.0 {
  26. CREATE VIRTUAL TABLE t1 USING fts5(a, b, c, detail=col);
  27. INSERT INTO t1 VALUES('h d g', 'j b b g b', 'i e i d h g g'); -- 1
  28. INSERT INTO t1 VALUES('h j d', 'j h d a h', 'f d d g g f b'); -- 2
  29. INSERT INTO t1 VALUES('j c i', 'f f h e f', 'c j i j c h f'); -- 3
  30. INSERT INTO t1 VALUES('e g g', 'g e d h i', 'e d b e g d c'); -- 4
  31. INSERT INTO t1 VALUES('b c c', 'd i h a f', 'd i j f a b c'); -- 5
  32. INSERT INTO t1 VALUES('e d e', 'b c j g d', 'a i f d h b d'); -- 6
  33. INSERT INTO t1 VALUES('g h e', 'b c d i d', 'e f c i f i c'); -- 7
  34. INSERT INTO t1 VALUES('c f j', 'j j i e a', 'h a c f d h e'); -- 8
  35. INSERT INTO t1 VALUES('a h i', 'c i a f a', 'c f d h g d g'); -- 9
  36. INSERT INTO t1 VALUES('j g g', 'e f e f f', 'h j b i c g e'); -- 10
  37. }
  38. do_execsql_test 1.1 {
  39. INSERT INTO t1(t1) VALUES('integrity-check');
  40. }
  41. foreach {tn match res} {
  42. 1 "a:a" {9}
  43. 2 "b:g" {1 4 6}
  44. 3 "c:h" {1 3 6 8 9 10}
  45. } {
  46. do_execsql_test 1.2.$tn.1 {
  47. SELECT rowid FROM t1($match);
  48. } $res
  49. do_execsql_test 1.2.$tn.2 {
  50. SELECT rowid FROM t1($match || '*');
  51. } $res
  52. }
  53. do_catchsql_test 1.3.1 {
  54. SELECT rowid FROM t1('h + d');
  55. } {1 {fts5: phrase queries are not supported (detail!=full)}}
  56. do_catchsql_test 1.3.2 {
  57. SELECT rowid FROM t1('NEAR(h d)');
  58. } {1 {fts5: NEAR queries are not supported (detail!=full)}}
  59. #-------------------------------------------------------------------------
  60. # integrity-check with both detail= and prefix= options.
  61. #
  62. do_execsql_test 2.0 {
  63. CREATE VIRTUAL TABLE t2 USING fts5(a, detail=col, prefix="1");
  64. INSERT INTO t2(a) VALUES('aa ab');
  65. }
  66. #db eval {SELECT rowid, fts5_decode(rowid, block) aS r FROM t2_data} {puts $r}
  67. do_execsql_test 2.1 {
  68. INSERT INTO t2(t2) VALUES('integrity-check');
  69. }
  70. do_execsql_test 2.2 {
  71. SELECT fts5_test_poslist(t2) FROM t2('aa');
  72. } {0.0.0}
  73. do_execsql_test 2.3 {
  74. SELECT fts5_test_collist(t2) FROM t2('aa');
  75. } {0.0}
  76. set ::pc 0
  77. #puts [nearset {{ax bx cx}} -pc ::pc -near 10 -- b*]
  78. #exit
  79. #-------------------------------------------------------------------------
  80. # Check that the xInstCount, xInst, xPhraseFirst and xPhraseNext APIs
  81. # work with detail=col tables.
  82. #
  83. set data {
  84. 1 {abb aca aca} {aba bab aab aac caa} {abc cbc ccb bcc bab ccb aca}
  85. 2 {bca aca acb} {ccb bcc bca aab bcc} {bab aaa aac cbb bba aca abc}
  86. 3 {cca abc cab} {aab aba bcc cac baa} {bab cbb acb aba aab ccc cca}
  87. 4 {ccb bcb aba} {aba bbb bcc cac bbb} {cbb aaa bca bcc aab cac aca}
  88. 5 {bca bbc cac} {aba cbb cac cca aca} {cab acb cbc ccb cac bbb bcb}
  89. 6 {acc bba cba} {bab bbc bbb bcb aca} {bca ccc cbb aca bac ccc ccb}
  90. 7 {aba bab aaa} {abb bca aac bcb bcc} {bcb bbc aba aaa cba abc acc}
  91. 8 {cab aba aaa} {ccb aca caa bbc bcc} {aaa abc ccb bbb cac cca abb}
  92. 9 {bcb bab bac} {bcb cba cac bbb abc} {aba aca cbb acb abb ccc ccb}
  93. 10 {aba aab ccc} {abc ccc bcc cab bbb} {aab bcc cbb ccc aaa bac baa}
  94. 11 {bab acb cba} {aac cab cab bca cbc} {aab cbc aac baa ccb acc cac}
  95. 12 {ccc cbb cbc} {aaa aab bcc aac bbc} {cbc cbc bac bac ccc bbc acc}
  96. 13 {cab bbc abc} {bbb bab bba aca bab} {baa bbb aab bbb ccb bbb ccc}
  97. 14 {bbc cab caa} {acb aac abb cba acc} {cba bba bba acb abc abb baa}
  98. 15 {aba cca bcc} {aaa acb abc aab ccb} {cca bcb acc aaa caa cca cbc}
  99. 16 {bcb bba aba} {cbc acb cab caa ccb} {aac aaa bbc cab cca cba abc}
  100. 17 {caa cbb acc} {ccb bcb bca aaa bcc} {bbb aca bcb bca cbc cbc cca}
  101. 18 {cbb bbc aac} {ccc bbc aaa aab baa} {cab cab cac cca bbc abc bbc}
  102. 19 {ccc acc aaa} {aab cbb bca cca caa} {bcb aca aca cab acc bac bcc}
  103. 20 {aab ccc bcb} {bbc cbb bbc aaa bcc} {cbc aab ccc aaa bcb bac cbc}
  104. 21 {aba cab ccc} {bbc cbc cba acc bbb} {acc aab aac acb aca bca acb}
  105. 22 {bcb bca baa} {cca bbc aca ccb cbb} {aab abc bbc aaa cab bcc bcc}
  106. 23 {cac cbb caa} {bbc aba bbb bcc ccb} {bbc bbb cab bbc cac abb acc}
  107. 24 {ccb acb caa} {cab bba cac bbc aac} {aac bca abc cab bca cab bcb}
  108. 25 {bbb aca bca} {bcb acc ccc cac aca} {ccc acb acc cac cac bba bbc}
  109. 26 {bab acc caa} {caa cab cac bac aca} {aba cac caa acc bac ccc aaa}
  110. 27 {bca bca aaa} {ccb aca bca aaa baa} {bab acc aaa cca cba cca bac}
  111. 28 {ccb cac cac} {bca abb bba bbc baa} {aca ccb aac cab ccc cab caa}
  112. 29 {abc bca cab} {cac cbc cbb ccc bcc} {bcc aaa aaa acc aac cac aac}
  113. 30 {aca acc acb} {aab aac cbb caa acb} {acb bbc bbc acc cbb bbc aac}
  114. 31 {aba aca baa} {aca bcc cab bab acb} {bcc acb baa bcb bbc acc aba}
  115. 32 {abb cbc caa} {cba abb bbb cbb aca} {bac aca caa cac caa ccb bbc}
  116. 33 {bcc bcb bcb} {cca cab cbc abb bab} {caa bbc aac bbb cab cba aaa}
  117. 34 {caa cab acc} {ccc ccc bcc acb bcc} {bac bba aca bcb bba bcb cac}
  118. 35 {bac bcb cba} {bcc acb bbc cba bab} {abb cbb abc abc bac acc cbb}
  119. 36 {cab bab ccb} {bca bba bab cca acc} {acc aab bcc bac acb cbb caa}
  120. 37 {aca cbc cab} {bba aac aca aac aaa} {baa cbb cba aba cab bca bcb}
  121. 38 {acb aab baa} {baa bab bca bbc bbb} {abc baa acc aba cab baa cac}
  122. 39 {bcb aac cba} {bcb baa caa cac bbc} {cbc ccc bab ccb bbb caa aba}
  123. 40 {cba ccb abc} {cbb caa cba aac bab} {cbb bbb bca bbb bac cac bca}
  124. }
  125. set data {
  126. 1 {abb aca aca} {aba bab aab aac caa} {abc cbc ccb bcc bab ccb aca}
  127. }
  128. proc matchdata {expr {bAsc 1}} {
  129. set tclexpr [db one {
  130. SELECT fts5_expr_tcl($expr, 'nearset $cols -pc ::pc', 'x', 'y', 'z')
  131. }]
  132. set res [list]
  133. #puts "$expr -> $tclexpr"
  134. foreach {id x y z} $::data {
  135. set cols [list $x $y $z]
  136. set ::pc 0
  137. #set hits [lsort -command instcompare [eval $tclexpr]]
  138. set hits [eval $tclexpr]
  139. if {[llength $hits]>0} {
  140. lappend res [list $id $hits]
  141. }
  142. }
  143. if {$bAsc} {
  144. set res [lsort -integer -increasing -index 0 $res]
  145. } else {
  146. set res [lsort -integer -decreasing -index 0 $res]
  147. }
  148. return [concat {*}$res]
  149. }
  150. foreach {tn tbl} {
  151. 1 { CREATE VIRTUAL TABLE t3 USING fts5(x, y, z, detail=col) }
  152. 2 { CREATE VIRTUAL TABLE t3 USING fts5(x, y, z, detail=none) }
  153. } {
  154. reset_db
  155. fts5_aux_test_functions db
  156. execsql $tbl
  157. foreach {id x y z} $data {
  158. execsql { INSERT INTO t3(rowid, x, y, z) VALUES($id, $x, $y, $z) }
  159. }
  160. foreach {tn2 expr} {
  161. 1 aaa 2 ccc 3 bab 4 aac
  162. 5 aa* 6 cc* 7 ba* 8 aa*
  163. 9 a* 10 b* 11 c*
  164. } {
  165. set res [matchdata $expr]
  166. do_execsql_test 3.$tn.$tn2.1 {
  167. SELECT rowid, fts5_test_poslist(t3) FROM t3($expr)
  168. } $res
  169. do_execsql_test 3.$tn.$tn2.2 {
  170. SELECT rowid, fts5_test_poslist2(t3) FROM t3($expr)
  171. } $res
  172. }
  173. }
  174. #-------------------------------------------------------------------------
  175. # Simple tests for detail=none tables.
  176. #
  177. do_execsql_test 4.0 {
  178. CREATE VIRTUAL TABLE t4 USING fts5(a, b, c, detail=none);
  179. INSERT INTO t4 VALUES('a b c', 'b c d', 'e f g');
  180. INSERT INTO t4 VALUES('1 2 3', '4 5 6', '7 8 9');
  181. }
  182. do_catchsql_test 4.1 {
  183. SELECT * FROM t4('a:a')
  184. } {1 {fts5: column queries are not supported (detail=none)}}
  185. do_catchsql_test 4.2 {
  186. SELECT * FROM t4('a:a &')
  187. } {1 {fts5: syntax error near "&"}}
  188. #-------------------------------------------------------------------------
  189. # Test that for the same content detail=none uses less space than
  190. # detail=col, and that detail=col uses less space than detail=full
  191. #
  192. reset_db
  193. do_test 5.1 {
  194. foreach {tbl detail} {t1 none t2 col t3 full} {
  195. execsql "CREATE VIRTUAL TABLE $tbl USING fts5(x, y, z, detail=$detail)"
  196. foreach {rowid x y z} $::data {
  197. execsql "INSERT INTO $tbl (rowid, x, y, z) VALUES(\$rowid, \$x, \$y, \$z)"
  198. }
  199. }
  200. } {}
  201. do_execsql_test 5.2 {
  202. SELECT
  203. (SELECT sum(length(block)) from t1_data) <
  204. (SELECT sum(length(block)) from t2_data)
  205. } {1}
  206. do_execsql_test 5.3 {
  207. SELECT
  208. (SELECT sum(length(block)) from t2_data) <
  209. (SELECT sum(length(block)) from t3_data)
  210. } {1}
  211. finish_test