OLD | NEW |
| (Empty) |
1 # 2008 June 26 | |
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 exercises some new testing functions in the FTS2 module, | |
12 # and then uses them to do some basic tests that FTS2 is internally | |
13 # working as expected. | |
14 # | |
15 # $Id: fts2p.test,v 1.1 2008/07/22 23:32:28 shess Exp $ | |
16 # | |
17 | |
18 set testdir [file dirname $argv0] | |
19 source $testdir/tester.tcl | |
20 | |
21 # If SQLITE_ENABLE_FTS2 is not defined, omit this file. | |
22 ifcapable !fts2 { | |
23 finish_test | |
24 return | |
25 } | |
26 | |
27 #************************************************************************* | |
28 # Probe to see if support for these functions is compiled in. | |
29 # TODO(shess): Change main.mk to do the right thing and remove this test. | |
30 db eval { | |
31 DROP TABLE IF EXISTS t1; | |
32 CREATE VIRTUAL TABLE t1 USING fts2(c); | |
33 INSERT INTO t1 (rowid, c) VALUES (1, 'x'); | |
34 } | |
35 | |
36 set s {SELECT dump_terms(t1, 1) FROM t1 LIMIT 1} | |
37 set r {1 {unable to use function dump_terms in the requested context}} | |
38 if {[catchsql $s]==$r} { | |
39 finish_test | |
40 return | |
41 } | |
42 | |
43 #************************************************************************* | |
44 # Test that the new functions give appropriate errors. | |
45 do_test fts2p-0.0 { | |
46 catchsql { | |
47 SELECT dump_terms(t1, 1) FROM t1 LIMIT 1; | |
48 } | |
49 } {1 {dump_terms: incorrect arguments}} | |
50 | |
51 do_test fts2p-0.1 { | |
52 catchsql { | |
53 SELECT dump_terms(t1, 0, 0, 0) FROM t1 LIMIT 1; | |
54 } | |
55 } {1 {dump_terms: incorrect arguments}} | |
56 | |
57 do_test fts2p-0.2 { | |
58 catchsql { | |
59 SELECT dump_terms(1, t1) FROM t1 LIMIT 1; | |
60 } | |
61 } {1 {unable to use function dump_terms in the requested context}} | |
62 | |
63 do_test fts2p-0.3 { | |
64 catchsql { | |
65 SELECT dump_terms(t1, 16, 16) FROM t1 LIMIT 1; | |
66 } | |
67 } {1 {dump_terms: segment not found}} | |
68 | |
69 do_test fts2p-0.4 { | |
70 catchsql { | |
71 SELECT dump_doclist(t1) FROM t1 LIMIT 1; | |
72 } | |
73 } {1 {dump_doclist: incorrect arguments}} | |
74 | |
75 do_test fts2p-0.5 { | |
76 catchsql { | |
77 SELECT dump_doclist(t1, NULL) FROM t1 LIMIT 1; | |
78 } | |
79 } {1 {dump_doclist: empty second argument}} | |
80 | |
81 do_test fts2p-0.6 { | |
82 catchsql { | |
83 SELECT dump_doclist(t1, '') FROM t1 LIMIT 1; | |
84 } | |
85 } {1 {dump_doclist: empty second argument}} | |
86 | |
87 do_test fts2p-0.7 { | |
88 catchsql { | |
89 SELECT dump_doclist(t1, 'a', 0) FROM t1 LIMIT 1; | |
90 } | |
91 } {1 {dump_doclist: incorrect arguments}} | |
92 | |
93 do_test fts2p-0.8 { | |
94 catchsql { | |
95 SELECT dump_doclist(t1, 'a', 0, 0, 0) FROM t1 LIMIT 1; | |
96 } | |
97 } {1 {dump_doclist: incorrect arguments}} | |
98 | |
99 do_test fts2p-0.9 { | |
100 catchsql { | |
101 SELECT dump_doclist(t1, 'a', 16, 16) FROM t1 LIMIT 1; | |
102 } | |
103 } {1 {dump_doclist: segment not found}} | |
104 | |
105 #************************************************************************* | |
106 # Utility function to check for the expected terms in the segment | |
107 # level/index. _all version does same but for entire index. | |
108 proc check_terms {test level index terms} { | |
109 # TODO(shess): Figure out why uplevel in do_test can't catch | |
110 # $level and $index directly. | |
111 set ::level $level | |
112 set ::index $index | |
113 do_test $test.terms { | |
114 execsql { | |
115 SELECT dump_terms(t1, $::level, $::index) FROM t1 LIMIT 1; | |
116 } | |
117 } [list $terms] | |
118 } | |
119 proc check_terms_all {test terms} { | |
120 do_test $test.terms { | |
121 execsql { | |
122 SELECT dump_terms(t1) FROM t1 LIMIT 1; | |
123 } | |
124 } [list $terms] | |
125 } | |
126 | |
127 # Utility function to check for the expected doclist for the term in | |
128 # segment level/index. _all version does same for entire index. | |
129 proc check_doclist {test level index term doclist} { | |
130 # TODO(shess): Again, why can't the non-:: versions work? | |
131 set ::term $term | |
132 set ::level $level | |
133 set ::index $index | |
134 do_test $test { | |
135 execsql { | |
136 SELECT dump_doclist(t1, $::term, $::level, $::index) FROM t1 LIMIT 1; | |
137 } | |
138 } [list $doclist] | |
139 } | |
140 proc check_doclist_all {test term doclist} { | |
141 set ::term $term | |
142 do_test $test { | |
143 execsql { | |
144 SELECT dump_doclist(t1, $::term) FROM t1 LIMIT 1; | |
145 } | |
146 } [list $doclist] | |
147 } | |
148 | |
149 #************************************************************************* | |
150 # Test the segments resulting from straight-forward inserts. | |
151 db eval { | |
152 DROP TABLE IF EXISTS t1; | |
153 CREATE VIRTUAL TABLE t1 USING fts2(c); | |
154 INSERT INTO t1 (rowid, c) VALUES (1, 'This is a test'); | |
155 INSERT INTO t1 (rowid, c) VALUES (2, 'That was a test'); | |
156 INSERT INTO t1 (rowid, c) VALUES (3, 'This is a test'); | |
157 } | |
158 | |
159 # Check for expected segments and expected matches. | |
160 do_test fts2p-1.0.segments { | |
161 execsql { | |
162 SELECT level, idx FROM t1_segdir ORDER BY level, idx; | |
163 } | |
164 } {0 0 0 1 0 2} | |
165 do_test fts2p-1.0.matches { | |
166 execsql { | |
167 SELECT OFFSETS(t1) FROM t1 | |
168 WHERE t1 MATCH 'this OR that OR was OR a OR is OR test' ORDER BY rowid; | |
169 } | |
170 } [list {0 0 0 4 0 4 5 2 0 3 8 1 0 5 10 4} \ | |
171 {0 1 0 4 0 2 5 3 0 3 9 1 0 5 11 4} \ | |
172 {0 0 0 4 0 4 5 2 0 3 8 1 0 5 10 4}] | |
173 | |
174 # Check the specifics of the segments constructed. | |
175 # Logical view of entire index. | |
176 check_terms_all fts2p-1.0.1 {a is test that this was} | |
177 check_doclist_all fts2p-1.0.1.1 a {[1 0[2]] [2 0[2]] [3 0[2]]} | |
178 check_doclist_all fts2p-1.0.1.2 is {[1 0[1]] [3 0[1]]} | |
179 check_doclist_all fts2p-1.0.1.3 test {[1 0[3]] [2 0[3]] [3 0[3]]} | |
180 check_doclist_all fts2p-1.0.1.4 that {[2 0[0]]} | |
181 check_doclist_all fts2p-1.0.1.5 this {[1 0[0]] [3 0[0]]} | |
182 check_doclist_all fts2p-1.0.1.6 was {[2 0[1]]} | |
183 | |
184 # Segment 0,0 | |
185 check_terms fts2p-1.0.2 0 0 {a is test this} | |
186 check_doclist fts2p-1.0.2.1 0 0 a {[1 0[2]]} | |
187 check_doclist fts2p-1.0.2.2 0 0 is {[1 0[1]]} | |
188 check_doclist fts2p-1.0.2.3 0 0 test {[1 0[3]]} | |
189 check_doclist fts2p-1.0.2.4 0 0 this {[1 0[0]]} | |
190 | |
191 # Segment 0,1 | |
192 check_terms fts2p-1.0.3 0 1 {a test that was} | |
193 check_doclist fts2p-1.0.3.1 0 1 a {[2 0[2]]} | |
194 check_doclist fts2p-1.0.3.2 0 1 test {[2 0[3]]} | |
195 check_doclist fts2p-1.0.3.3 0 1 that {[2 0[0]]} | |
196 check_doclist fts2p-1.0.3.4 0 1 was {[2 0[1]]} | |
197 | |
198 # Segment 0,2 | |
199 check_terms fts2p-1.0.4 0 2 {a is test this} | |
200 check_doclist fts2p-1.0.4.1 0 2 a {[3 0[2]]} | |
201 check_doclist fts2p-1.0.4.2 0 2 is {[3 0[1]]} | |
202 check_doclist fts2p-1.0.4.3 0 2 test {[3 0[3]]} | |
203 check_doclist fts2p-1.0.4.4 0 2 this {[3 0[0]]} | |
204 | |
205 #************************************************************************* | |
206 # Test the segments resulting from inserts followed by a delete. | |
207 db eval { | |
208 DROP TABLE IF EXISTS t1; | |
209 CREATE VIRTUAL TABLE t1 USING fts2(c); | |
210 INSERT INTO t1 (rowid, c) VALUES (1, 'This is a test'); | |
211 INSERT INTO t1 (rowid, c) VALUES (2, 'That was a test'); | |
212 INSERT INTO t1 (rowid, c) VALUES (3, 'This is a test'); | |
213 DELETE FROM t1 WHERE rowid = 1; | |
214 } | |
215 | |
216 do_test fts2p-1.1.segments { | |
217 execsql { | |
218 SELECT level, idx FROM t1_segdir ORDER BY level, idx; | |
219 } | |
220 } {0 0 0 1 0 2 0 3} | |
221 do_test fts2p-1.1.matches { | |
222 execsql { | |
223 SELECT OFFSETS(t1) FROM t1 | |
224 WHERE t1 MATCH 'this OR that OR was OR a OR is OR test' ORDER BY rowid; | |
225 } | |
226 } {{0 1 0 4 0 2 5 3 0 3 9 1 0 5 11 4} {0 0 0 4 0 4 5 2 0 3 8 1 0 5 10 4}} | |
227 | |
228 check_terms_all fts2p-1.1.1 {a is test that this was} | |
229 check_doclist_all fts2p-1.1.1.1 a {[2 0[2]] [3 0[2]]} | |
230 check_doclist_all fts2p-1.1.1.2 is {[3 0[1]]} | |
231 check_doclist_all fts2p-1.1.1.3 test {[2 0[3]] [3 0[3]]} | |
232 check_doclist_all fts2p-1.1.1.4 that {[2 0[0]]} | |
233 check_doclist_all fts2p-1.1.1.5 this {[3 0[0]]} | |
234 check_doclist_all fts2p-1.1.1.6 was {[2 0[1]]} | |
235 | |
236 check_terms fts2p-1.1.2 0 0 {a is test this} | |
237 check_doclist fts2p-1.1.2.1 0 0 a {[1 0[2]]} | |
238 check_doclist fts2p-1.1.2.2 0 0 is {[1 0[1]]} | |
239 check_doclist fts2p-1.1.2.3 0 0 test {[1 0[3]]} | |
240 check_doclist fts2p-1.1.2.4 0 0 this {[1 0[0]]} | |
241 | |
242 check_terms fts2p-1.1.3 0 1 {a test that was} | |
243 check_doclist fts2p-1.1.3.1 0 1 a {[2 0[2]]} | |
244 check_doclist fts2p-1.1.3.2 0 1 test {[2 0[3]]} | |
245 check_doclist fts2p-1.1.3.3 0 1 that {[2 0[0]]} | |
246 check_doclist fts2p-1.1.3.4 0 1 was {[2 0[1]]} | |
247 | |
248 check_terms fts2p-1.1.4 0 2 {a is test this} | |
249 check_doclist fts2p-1.1.4.1 0 2 a {[3 0[2]]} | |
250 check_doclist fts2p-1.1.4.2 0 2 is {[3 0[1]]} | |
251 check_doclist fts2p-1.1.4.3 0 2 test {[3 0[3]]} | |
252 check_doclist fts2p-1.1.4.4 0 2 this {[3 0[0]]} | |
253 | |
254 check_terms fts2p-1.1.5 0 3 {a is test this} | |
255 check_doclist fts2p-1.1.5.1 0 3 a {[1]} | |
256 check_doclist fts2p-1.1.5.2 0 3 is {[1]} | |
257 check_doclist fts2p-1.1.5.3 0 3 test {[1]} | |
258 check_doclist fts2p-1.1.5.4 0 3 this {[1]} | |
259 | |
260 #************************************************************************* | |
261 # Test results when all references to certain tokens are deleted. | |
262 db eval { | |
263 DROP TABLE IF EXISTS t1; | |
264 CREATE VIRTUAL TABLE t1 USING fts2(c); | |
265 INSERT INTO t1 (rowid, c) VALUES (1, 'This is a test'); | |
266 INSERT INTO t1 (rowid, c) VALUES (2, 'That was a test'); | |
267 INSERT INTO t1 (rowid, c) VALUES (3, 'This is a test'); | |
268 DELETE FROM t1 WHERE rowid IN (1,3); | |
269 } | |
270 | |
271 # Still 4 segments because 0,3 will contain deletes for rowid 1 and 3. | |
272 do_test fts2p-1.2.segments { | |
273 execsql { | |
274 SELECT level, idx FROM t1_segdir ORDER BY level, idx; | |
275 } | |
276 } {0 0 0 1 0 2 0 3} | |
277 do_test fts2p-1.2.matches { | |
278 execsql { | |
279 SELECT OFFSETS(t1) FROM t1 | |
280 WHERE t1 MATCH 'this OR that OR was OR a OR is OR test' ORDER BY rowid; | |
281 } | |
282 } {{0 1 0 4 0 2 5 3 0 3 9 1 0 5 11 4}} | |
283 | |
284 check_terms_all fts2p-1.2.1 {a is test that this was} | |
285 check_doclist_all fts2p-1.2.1.1 a {[2 0[2]]} | |
286 check_doclist_all fts2p-1.2.1.2 is {} | |
287 check_doclist_all fts2p-1.2.1.3 test {[2 0[3]]} | |
288 check_doclist_all fts2p-1.2.1.4 that {[2 0[0]]} | |
289 check_doclist_all fts2p-1.2.1.5 this {} | |
290 check_doclist_all fts2p-1.2.1.6 was {[2 0[1]]} | |
291 | |
292 check_terms fts2p-1.2.2 0 0 {a is test this} | |
293 check_doclist fts2p-1.2.2.1 0 0 a {[1 0[2]]} | |
294 check_doclist fts2p-1.2.2.2 0 0 is {[1 0[1]]} | |
295 check_doclist fts2p-1.2.2.3 0 0 test {[1 0[3]]} | |
296 check_doclist fts2p-1.2.2.4 0 0 this {[1 0[0]]} | |
297 | |
298 check_terms fts2p-1.2.3 0 1 {a test that was} | |
299 check_doclist fts2p-1.2.3.1 0 1 a {[2 0[2]]} | |
300 check_doclist fts2p-1.2.3.2 0 1 test {[2 0[3]]} | |
301 check_doclist fts2p-1.2.3.3 0 1 that {[2 0[0]]} | |
302 check_doclist fts2p-1.2.3.4 0 1 was {[2 0[1]]} | |
303 | |
304 check_terms fts2p-1.2.4 0 2 {a is test this} | |
305 check_doclist fts2p-1.2.4.1 0 2 a {[3 0[2]]} | |
306 check_doclist fts2p-1.2.4.2 0 2 is {[3 0[1]]} | |
307 check_doclist fts2p-1.2.4.3 0 2 test {[3 0[3]]} | |
308 check_doclist fts2p-1.2.4.4 0 2 this {[3 0[0]]} | |
309 | |
310 check_terms fts2p-1.2.5 0 3 {a is test this} | |
311 check_doclist fts2p-1.2.5.1 0 3 a {[1] [3]} | |
312 check_doclist fts2p-1.2.5.2 0 3 is {[1] [3]} | |
313 check_doclist fts2p-1.2.5.3 0 3 test {[1] [3]} | |
314 check_doclist fts2p-1.2.5.4 0 3 this {[1] [3]} | |
315 | |
316 #************************************************************************* | |
317 # Test results when everything is optimized manually. | |
318 db eval { | |
319 DROP TABLE IF EXISTS t1; | |
320 CREATE VIRTUAL TABLE t1 USING fts2(c); | |
321 INSERT INTO t1 (rowid, c) VALUES (1, 'This is a test'); | |
322 INSERT INTO t1 (rowid, c) VALUES (2, 'That was a test'); | |
323 INSERT INTO t1 (rowid, c) VALUES (3, 'This is a test'); | |
324 DELETE FROM t1 WHERE rowid IN (1,3); | |
325 DROP TABLE IF EXISTS t1old; | |
326 ALTER TABLE t1 RENAME TO t1old; | |
327 CREATE VIRTUAL TABLE t1 USING fts2(c); | |
328 INSERT INTO t1 (rowid, c) SELECT rowid, c FROM t1old; | |
329 DROP TABLE t1old; | |
330 } | |
331 | |
332 # Should be a single optimal segment with the same logical results. | |
333 do_test fts2p-1.3.segments { | |
334 execsql { | |
335 SELECT level, idx FROM t1_segdir ORDER BY level, idx; | |
336 } | |
337 } {0 0} | |
338 do_test fts2p-1.3.matches { | |
339 execsql { | |
340 SELECT OFFSETS(t1) FROM t1 | |
341 WHERE t1 MATCH 'this OR that OR was OR a OR is OR test' ORDER BY rowid; | |
342 } | |
343 } {{0 1 0 4 0 2 5 3 0 3 9 1 0 5 11 4}} | |
344 | |
345 check_terms_all fts2p-1.3.1 {a test that was} | |
346 check_doclist_all fts2p-1.3.1.1 a {[2 0[2]]} | |
347 check_doclist_all fts2p-1.3.1.2 test {[2 0[3]]} | |
348 check_doclist_all fts2p-1.3.1.3 that {[2 0[0]]} | |
349 check_doclist_all fts2p-1.3.1.4 was {[2 0[1]]} | |
350 | |
351 check_terms fts2p-1.3.2 0 0 {a test that was} | |
352 check_doclist fts2p-1.3.2.1 0 0 a {[2 0[2]]} | |
353 check_doclist fts2p-1.3.2.2 0 0 test {[2 0[3]]} | |
354 check_doclist fts2p-1.3.2.3 0 0 that {[2 0[0]]} | |
355 check_doclist fts2p-1.3.2.4 0 0 was {[2 0[1]]} | |
356 | |
357 finish_test | |
OLD | NEW |