fts5fault6.test 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. # 2014 June 17
  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 is focused on OOM errors.
  13. #
  14. source [file join [file dirname [info script]] fts5_common.tcl]
  15. source $testdir/malloc_common.tcl
  16. set testprefix fts5fault6
  17. # If SQLITE_ENABLE_FTS5 is not defined, omit this file.
  18. ifcapable !fts5 {
  19. finish_test
  20. return
  21. }
  22. #-------------------------------------------------------------------------
  23. # OOM while rebuilding an FTS5 table.
  24. #
  25. do_execsql_test 1.0 {
  26. CREATE VIRTUAL TABLE tt USING fts5(a, b);
  27. INSERT INTO tt VALUES('c d c g g f', 'a a a d g a');
  28. INSERT INTO tt VALUES('c d g b f d', 'b g e c g c');
  29. INSERT INTO tt VALUES('c c f d e d', 'c e g d b c');
  30. INSERT INTO tt VALUES('e a f c e f', 'g b a c d g');
  31. INSERT INTO tt VALUES('c g f b b d', 'g c d c f g');
  32. INSERT INTO tt VALUES('d a g a b b', 'g c g g c e');
  33. INSERT INTO tt VALUES('e f a b c e', 'f d c d c c');
  34. INSERT INTO tt VALUES('e c a g c d', 'b b g f f b');
  35. INSERT INTO tt VALUES('g b d d e b', 'f f b d a c');
  36. INSERT INTO tt VALUES('e a d a e d', 'c e a e f g');
  37. }
  38. faultsim_save_and_close
  39. do_faultsim_test 1.1 -faults oom-t* -prep {
  40. faultsim_restore_and_reopen
  41. } -body {
  42. db eval { INSERT INTO tt(tt) VALUES('rebuild') }
  43. } -test {
  44. faultsim_test_result {0 {}}
  45. }
  46. do_faultsim_test 1.2 -faults oom-t* -prep {
  47. faultsim_restore_and_reopen
  48. } -body {
  49. db eval { REPLACE INTO tt(rowid, a, b) VALUES(6, 'x y z', 'l l l'); }
  50. } -test {
  51. faultsim_test_result {0 {}}
  52. }
  53. #-------------------------------------------------------------------------
  54. # OOM within a special delete.
  55. #
  56. reset_db
  57. do_execsql_test 2.0 {
  58. CREATE VIRTUAL TABLE tt USING fts5(a, content="");
  59. INSERT INTO tt VALUES('c d c g g f');
  60. INSERT INTO tt VALUES('c d g b f d');
  61. INSERT INTO tt VALUES('c c f d e d');
  62. INSERT INTO tt VALUES('e a f c e f');
  63. INSERT INTO tt VALUES('c g f b b d');
  64. INSERT INTO tt VALUES('d a g a b b');
  65. INSERT INTO tt VALUES('e f a b c e');
  66. INSERT INTO tt VALUES('e c a g c d');
  67. INSERT INTO tt VALUES('g b d d e b');
  68. INSERT INTO tt VALUES('e a d a e d');
  69. }
  70. faultsim_save_and_close
  71. do_faultsim_test 2.1 -faults oom-t* -prep {
  72. faultsim_restore_and_reopen
  73. } -body {
  74. db eval { INSERT INTO tt(tt, rowid, a) VALUES('delete', 3, 'c d g b f d'); }
  75. } -test {
  76. faultsim_test_result {0 {}}
  77. }
  78. do_faultsim_test 2.2 -faults oom-t* -prep {
  79. faultsim_restore_and_reopen
  80. } -body {
  81. db eval { INSERT INTO tt(tt) VALUES('delete-all') }
  82. } -test {
  83. faultsim_test_result {0 {}}
  84. }
  85. do_faultsim_test 2.3 -faults oom-t* -prep {
  86. faultsim_restore_and_reopen
  87. } -body {
  88. db eval { INSERT INTO tt VALUES('x y z') }
  89. } -test {
  90. faultsim_test_result {0 {}}
  91. }
  92. #-------------------------------------------------------------------------
  93. # OOM in the ASCII tokenizer with very large tokens.
  94. #
  95. # Also the unicode tokenizer.
  96. #
  97. set t1 [string repeat wxyz 20]
  98. set t2 [string repeat wxyz 200]
  99. set t3 [string repeat wxyz 2000]
  100. set doc "$t1 $t2 $t3"
  101. do_execsql_test 3.0 {
  102. CREATE VIRTUAL TABLE xyz USING fts5(c, tokenize=ascii, content="");
  103. CREATE VIRTUAL TABLE xyz2 USING fts5(c, content="");
  104. }
  105. faultsim_save_and_close
  106. do_faultsim_test 3.1 -faults oom-t* -prep {
  107. faultsim_restore_and_reopen
  108. db eval { SELECT * FROM xyz }
  109. } -body {
  110. db eval { INSERT INTO xyz VALUES($::doc) }
  111. } -test {
  112. faultsim_test_result {0 {}}
  113. }
  114. do_faultsim_test 3.2 -faults oom-t* -prep {
  115. faultsim_restore_and_reopen
  116. db eval { SELECT * FROM xyz2 }
  117. } -body {
  118. db eval { INSERT INTO xyz2 VALUES($::doc) }
  119. } -test {
  120. faultsim_test_result {0 {}}
  121. }
  122. #-------------------------------------------------------------------------
  123. # OOM while initializing a unicode61 tokenizer.
  124. #
  125. reset_db
  126. faultsim_save_and_close
  127. do_faultsim_test 4.1 -faults oom-t* -prep {
  128. faultsim_restore_and_reopen
  129. } -body {
  130. db eval {
  131. CREATE VIRTUAL TABLE yu USING fts5(x, tokenize="unicode61 separators abc");
  132. }
  133. } -test {
  134. faultsim_test_result {0 {}}
  135. }
  136. #-------------------------------------------------------------------------
  137. #
  138. # 5.2.* OOM while running a query that includes synonyms and matchinfo().
  139. #
  140. # 5.3.* OOM while running a query that returns a row containing instances
  141. # of more than 4 synonyms for a single term.
  142. #
  143. proc mit {blob} {
  144. set scan(littleEndian) i*
  145. set scan(bigEndian) I*
  146. binary scan $blob $scan($::tcl_platform(byteOrder)) r
  147. return $r
  148. }
  149. proc tcl_tokenize {tflags text} {
  150. foreach {w iStart iEnd} [fts5_tokenize_split $text] {
  151. sqlite3_fts5_token $w $iStart $iEnd
  152. if {$tflags=="query" && [string length $w]==1} {
  153. for {set i 2} {$i < 7} {incr i} {
  154. sqlite3_fts5_token -colo [string repeat $w $i] $iStart $iEnd
  155. }
  156. }
  157. }
  158. }
  159. proc tcl_create {args} { return "tcl_tokenize" }
  160. reset_db
  161. sqlite3_fts5_create_tokenizer db tcl tcl_create
  162. db func mit mit
  163. sqlite3_fts5_register_matchinfo db
  164. do_test 5.0 {
  165. execsql { CREATE VIRTUAL TABLE t1 USING fts5(a, tokenize=tcl) }
  166. execsql { INSERT INTO t1(t1, rank) VALUES('pgsz', 32) }
  167. foreach {rowid text} {
  168. 1 {aaaa cc b aaaaa cc aa}
  169. 2 {aa aa bb a bbb}
  170. 3 {bb aaaaa aaaaa b aaaa aaaaa}
  171. 4 {aa a b aaaa aa}
  172. 5 {aa b ccc aaaaa cc}
  173. 6 {aa aaaaa bbbb cc aaa}
  174. 7 {aaaaa aa aa ccccc bb}
  175. 8 {ccc bbbbb ccccc bbb c}
  176. 9 {cccccc bbbb a aaa cccc c}
  177. 20 {ddd f ddd eeeee fff ffff eeee ddd fff eeeee dddddd eeee}
  178. 21 {fffff eee dddd fffff dd ee ee eeeee eee eeeeee ee dd e}
  179. 22 {fffff d eeee dddd fffff dddddd ffff ddddd eeeee ee eee dddd ddddd}
  180. 23 {ddddd fff ddd eeeee ffff eeee ddd ff ff ffffff eeeeee dddd ffffff}
  181. 24 {eee dd ee dddd dddd eeeeee e eee fff ffff}
  182. 25 {ddddd ffffff dddddd fff ddd ddddd ddd f eeee fff dddd f}
  183. 26 {f ffff fff fff eeeeee dddd d dddddd ddddd eee ff eeeee}
  184. 27 {eee fff dddddd eeeee eeeee dddd ddddd ffff f eeeee eee dddddd ddddd d}
  185. 28 {dd ddddd d ddd d fff d dddd ee dddd ee ddd dddddd dddddd}
  186. 29 {eeee dddd ee dddd eeee dddd dd fffff f ddd eeeee ddd ee}
  187. 30 {ff ffffff eeeeee eeeee eee ffffff ff ffff f fffff eeeee}
  188. 31 {fffff eeeeee dddd eeee eeee eeeeee eee fffff d ddddd ffffff ffff dddddd}
  189. 32 {dddddd fffff ee eeeeee eeee ee fff dddd fff eeee ffffff eeeeee ffffff}
  190. 33 {ddddd eeee dd ffff dddddd fff eeee ddddd ffff eeee ddd}
  191. 34 {ee dddd ddddd dddddd eeee eeeeee f dd ee dddddd ffffff}
  192. 35 {ee dddd dd eeeeee ddddd eee d eeeeee dddddd eee dddd fffff}
  193. 36 {eee ffffff ffffff e fffff eeeee ff dddddd dddddd fff}
  194. 37 {eeeee fffff dddddd dddd ffffff fff f dd ee dd dd eeeee}
  195. 38 {eeeeee ee d ff eeeeee eeeeee eee eeeee ee ffffff dddd eeee dddddd ee}
  196. 39 {eeeeee ddd fffff e dddd ee eee eee ffffff ee f d dddd}
  197. 40 {ffffff dddddd eee ee ffffff eee eeee ddddd ee eeeeee f}
  198. 41 {ddd ddd fff fffff ee fffff f fff ddddd fffff}
  199. 42 {dddd ee ff d f ffffff fff ffffff ff dd dddddd f eeee}
  200. 43 {d dd fff fffff d f fff e dddd ee ee}
  201. 44 {ff ffff eee ddd d dd ffff dddd d eeee d eeeeee}
  202. 45 {eeee f eeeee ee e ffff f ddd e fff}
  203. 46 {ffff d ffff eeee ffff eeeee f ffff ddddd eee}
  204. 47 {dd dd dddddd ddddd fffff dddddd ddd ddddd eeeeee ffff eeee eee ee}
  205. 48 {ffff ffff e dddd ffffff dd dd dddd f fffff}
  206. 49 {ffffff d dddddd ffff eeeee f ffff ffff d dd fffff eeeee}
  207. 50 {x e}
  208. } {
  209. execsql { INSERT INTO t1(rowid, a) VALUES($rowid, $text) }
  210. }
  211. } {}
  212. set res [list {*}{
  213. 1 {3 24 8 2 12 6}
  214. 5 {2 24 8 2 12 6}
  215. 6 {3 24 8 1 12 6}
  216. 7 {3 24 8 1 12 6}
  217. 9 {2 24 8 3 12 6}
  218. }]
  219. do_execsql_test 5.1.1 {
  220. SELECT rowid, mit(matchinfo(t1, 'x')) FROM t1 WHERE t1 MATCH 'a AND c'
  221. } $res
  222. do_execsql_test 5.1.2 {
  223. SELECT count(*) FROM t1 WHERE t1 MATCH 'd e f'
  224. } 29
  225. faultsim_save_and_close
  226. do_faultsim_test 5.2 -faults oom* -prep {
  227. faultsim_restore_and_reopen
  228. sqlite3_fts5_create_tokenizer db tcl tcl_create
  229. sqlite3_fts5_register_matchinfo db
  230. db func mit mit
  231. } -body {
  232. db eval {
  233. SELECT rowid, mit(matchinfo(t1, 'x')) FROM t1 WHERE t1 MATCH 'a AND c'
  234. }
  235. } -test {
  236. faultsim_test_result [list 0 $::res] {1 {SQL logic error}}
  237. }
  238. do_faultsim_test 5.3 -faults oom* -prep {
  239. faultsim_restore_and_reopen
  240. sqlite3_fts5_create_tokenizer db tcl tcl_create
  241. } -body {
  242. db eval {
  243. SELECT count(*) FROM t1 WHERE t1 MATCH 'd AND e AND f'
  244. }
  245. } -test {
  246. faultsim_test_result {0 29} {1 {SQL logic error}}
  247. }
  248. do_faultsim_test 5.4 -faults oom* -prep {
  249. faultsim_restore_and_reopen
  250. sqlite3_fts5_create_tokenizer db tcl tcl_create
  251. } -body {
  252. db eval {
  253. SELECT count(*) FROM t1 WHERE t1 MATCH 'x + e'
  254. }
  255. } -test {
  256. faultsim_test_result {0 1} {1 {SQL logic error}}
  257. }
  258. #-------------------------------------------------------------------------
  259. catch { db close }
  260. do_faultsim_test 6 -faults oom* -prep {
  261. sqlite_orig db test.db
  262. sqlite3_db_config_lookaside db 0 0 0
  263. } -test {
  264. faultsim_test_result {0 {}} {1 {initialization of fts5 failed: }}
  265. if {$testrc==0} {
  266. db eval { CREATE VIRTUAL TABLE temp.t1 USING fts5(x) }
  267. }
  268. db close
  269. }
  270. finish_test