fts5rowid.test 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. # 2014 Dec 20
  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. # Tests of the scalar fts5_rowid() and fts5_decode() functions.
  13. #
  14. source [file join [file dirname [info script]] fts5_common.tcl]
  15. set testprefix fts5rowid
  16. # If SQLITE_ENABLE_FTS5 is not defined, omit this file.
  17. ifcapable !fts5 {
  18. finish_test
  19. return
  20. }
  21. do_catchsql_test 1.1 {
  22. SELECT fts5_rowid()
  23. } {1 {should be: fts5_rowid(subject, ....)}}
  24. do_catchsql_test 1.2 {
  25. SELECT fts5_rowid('segment')
  26. } {1 {should be: fts5_rowid('segment', segid, pgno))}}
  27. do_execsql_test 1.3 {
  28. SELECT fts5_rowid('segment', 1, 1)
  29. } {137438953473}
  30. do_catchsql_test 1.4 {
  31. SELECT fts5_rowid('nosucharg');
  32. } {1 {first arg to fts5_rowid() must be 'segment'}}
  33. #-------------------------------------------------------------------------
  34. # Tests of the fts5_decode() function.
  35. #
  36. reset_db
  37. do_execsql_test 2.1 {
  38. CREATE VIRTUAL TABLE x1 USING fts5(a, b);
  39. INSERT INTO x1(x1, rank) VALUES('pgsz', 32);
  40. } {}
  41. proc rnddoc {n} {
  42. set map [list 0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j]
  43. set doc [list]
  44. for {set i 0} {$i < $n} {incr i} {
  45. lappend doc [string map $map [format %.3d [expr int(rand()*100)]]]
  46. }
  47. set doc
  48. }
  49. db func rnddoc rnddoc
  50. do_execsql_test 2.2 {
  51. WITH r(a, b) AS (
  52. SELECT rnddoc(6), rnddoc(6) UNION ALL
  53. SELECT rnddoc(6), rnddoc(6) FROM r
  54. )
  55. INSERT INTO x1 SELECT * FROM r LIMIT 10000;
  56. DELETE FROM x1 WHERE (rowid%2);
  57. }
  58. set res [db one {SELECT count(*) FROM x1_data}]
  59. do_execsql_test 2.3 {
  60. SELECT count(fts5_decode(rowid, block)) FROM x1_data;
  61. } $res
  62. sqlite3_db_config db DEFENSIVE 0
  63. do_execsql_test 2.4 {
  64. UPDATE x1_data SET block = X'';
  65. SELECT count(fts5_decode(rowid, block)) FROM x1_data;
  66. } $res
  67. do_execsql_test 2.5 {
  68. INSERT INTO x1(x1, rank) VALUES('pgsz', 1024);
  69. INSERT INTO x1(x1) VALUES('rebuild');
  70. }
  71. set res [db one {SELECT count(*) FROM x1_data}]
  72. do_execsql_test 2.6 {
  73. SELECT count(fts5_decode(rowid, block)) FROM x1_data;
  74. } $res
  75. # This is really a corruption test...
  76. #do_execsql_test 2.7 {
  77. # UPDATE x1_data SET block = X'';
  78. # SELECT count(fts5_decode(rowid, block)) FROM x1_data;
  79. #} $res
  80. do_execsql_test 2.8 {
  81. SELECT fts5_decode(fts5_rowid('segment', 1000, 1), X'AB')
  82. } {corrupt}
  83. #-------------------------------------------------------------------------
  84. # Tests with very large tokens.
  85. #
  86. set strlist [list \
  87. "[string repeat x 400]" \
  88. "[string repeat x 300][string repeat w 100]" \
  89. "[string repeat x 300][string repeat y 100]" \
  90. "[string repeat x 300][string repeat z 600]" \
  91. ]
  92. do_test 3.0 {
  93. execsql {
  94. BEGIN;
  95. CREATE VIRTUAL TABLE x2 USING fts5(a);
  96. }
  97. foreach str $strlist { execsql { INSERT INTO x2 VALUES($str) } }
  98. execsql COMMIT
  99. } {}
  100. for {set tn 0} {$tn<[llength $strlist]} {incr tn} {
  101. set str [lindex $strlist $tn]
  102. do_execsql_test 3.1.$tn {
  103. SELECT rowid FROM x2 WHERE x2 MATCH $str
  104. } [expr $tn+1]
  105. }
  106. set res [db one {SELECT count(*) FROM x2_data}]
  107. do_execsql_test 3.2 {
  108. SELECT count(fts5_decode(rowid, block)) FROM x2_data;
  109. } $res
  110. #-------------------------------------------------------------------------
  111. # Leaf pages with no terms or rowids at all.
  112. #
  113. set strlist [list \
  114. "[string repeat {w } 400]" \
  115. "[string repeat {x } 400]" \
  116. "[string repeat {y } 400]" \
  117. "[string repeat {z } 400]" \
  118. ]
  119. do_test 4.0 {
  120. execsql {
  121. BEGIN;
  122. CREATE VIRTUAL TABLE x3 USING fts5(a);
  123. INSERT INTO x3(x3, rank) VALUES('pgsz', 32);
  124. }
  125. foreach str $strlist { execsql { INSERT INTO x3 VALUES($str) } }
  126. execsql COMMIT
  127. } {}
  128. for {set tn 0} {$tn<[llength $strlist]} {incr tn} {
  129. set str [lindex $strlist $tn]
  130. do_execsql_test 4.1.$tn {
  131. SELECT rowid FROM x3 WHERE x3 MATCH $str
  132. } [expr $tn+1]
  133. }
  134. set res [db one {SELECT count(*) FROM x3_data}]
  135. do_execsql_test 4.2 {
  136. SELECT count(fts5_decode(rowid, block)) FROM x3_data;
  137. } $res
  138. #-------------------------------------------------------------------------
  139. # Position lists with large values.
  140. #
  141. set strlist [list \
  142. "[string repeat {w } 400]a" \
  143. "[string repeat {x } 400]a" \
  144. "[string repeat {y } 400]a" \
  145. "[string repeat {z } 400]a" \
  146. ]
  147. do_test 5.0 {
  148. execsql {
  149. BEGIN;
  150. CREATE VIRTUAL TABLE x4 USING fts5(a);
  151. INSERT INTO x4(x4, rank) VALUES('pgsz', 32);
  152. }
  153. foreach str $strlist { execsql { INSERT INTO x4 VALUES($str) } }
  154. execsql COMMIT
  155. } {}
  156. do_execsql_test 5.1 {
  157. SELECT rowid FROM x4 WHERE x4 MATCH 'a'
  158. } {1 2 3 4}
  159. set res [db one {SELECT count(*) FROM x4_data}]
  160. do_execsql_test 5.2 {
  161. SELECT count(fts5_decode(rowid, block)) FROM x4_data;
  162. } $res
  163. #-------------------------------------------------------------------------
  164. #
  165. do_execsql_test 6.0 {
  166. CREATE VIRTUAL TABLE x5 USING fts5(x, detail=none);
  167. INSERT INTO x5(x5, rank) VALUES('pgsz', 32);
  168. INSERT INTO x5 VALUES('a b c d e f');
  169. INSERT INTO x5 VALUES('a b c d e f');
  170. INSERT INTO x5 VALUES('a b c d e f');
  171. BEGIN;
  172. WITH s(i) AS (
  173. SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100
  174. ) INSERT INTO x5 SELECT 'a b c d e f' FROM s;
  175. COMMIT;
  176. SELECT count(fts5_decode_none(rowid, block)) FROM x5_data;
  177. } {32}
  178. do_execsql_test 6.1 {
  179. DELETE FROM x5 WHERE rowid <= 2;
  180. SELECT count(fts5_decode_none(rowid, block)) FROM x5_data;
  181. } {34}
  182. do_execsql_test 6.2 {
  183. UPDATE x5 SET x='a b c d e f' WHERE rowid=3;
  184. SELECT count(fts5_decode_none(rowid, block)) FROM x5_data;
  185. } {36}
  186. #db eval {SELECT rowid, fts5_decode_none(rowid, block) aS r FROM x5_data} {puts $r}
  187. finish_test