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