OLD | NEW |
1 # 2015 August 05 | 1 # 2015 August 05 |
2 # | 2 # |
3 # The author disclaims copyright to this source code. In place of | 3 # The author disclaims copyright to this source code. In place of |
4 # a legal notice, here is a blessing: | 4 # a legal notice, here is a blessing: |
5 # | 5 # |
6 # May you do good and not evil. | 6 # May you do good and not evil. |
7 # May you find forgiveness for yourself and forgive others. | 7 # May you find forgiveness for yourself and forgive others. |
8 # May you share freely, never taking more than you give. | 8 # May you share freely, never taking more than you give. |
9 # | 9 # |
10 #*********************************************************************** | 10 #*********************************************************************** |
11 # | 11 # |
12 | 12 |
13 source [file join [file dirname [info script]] fts5_common.tcl] | 13 source [file join [file dirname [info script]] fts5_common.tcl] |
14 set testprefix fts5matchinfo | 14 set testprefix fts5matchinfo |
15 | 15 |
16 # If SQLITE_ENABLE_FTS5 is not defined, omit this file. | 16 # If SQLITE_ENABLE_FTS5 is not defined, omit this file. |
17 ifcapable !fts5 { finish_test ; return } | 17 ifcapable !fts5 { finish_test ; return } |
18 | 18 |
| 19 foreach_detail_mode $testprefix { |
| 20 |
19 proc mit {blob} { | 21 proc mit {blob} { |
20 set scan(littleEndian) i* | 22 set scan(littleEndian) i* |
21 set scan(bigEndian) I* | 23 set scan(bigEndian) I* |
22 binary scan $blob $scan($::tcl_platform(byteOrder)) r | 24 binary scan $blob $scan($::tcl_platform(byteOrder)) r |
23 return $r | 25 return $r |
24 } | 26 } |
25 db func mit mit | 27 db func mit mit |
26 | 28 |
27 sqlite3_fts5_register_matchinfo db | 29 sqlite3_fts5_register_matchinfo db |
28 | 30 |
29 do_execsql_test 1.0 { | 31 do_execsql_test 1.0 { |
30 CREATE VIRTUAL TABLE t1 USING fts5(content); | 32 CREATE VIRTUAL TABLE t1 USING fts5(content, detail=%DETAIL%); |
31 } | 33 } |
32 | 34 |
33 do_execsql_test 1.1 { | 35 do_execsql_test 1.1 { |
34 INSERT INTO t1(content) VALUES('I wandered lonely as a cloud'); | 36 INSERT INTO t1(content) VALUES('I wandered lonely as a cloud'); |
35 INSERT INTO t1(content) VALUES('That floats on high o''er vales and hills,'); | 37 INSERT INTO t1(content) VALUES('That floats on high o''er vales and hills,'); |
36 INSERT INTO t1(content) VALUES('When all at once I saw a crowd,'); | 38 INSERT INTO t1(content) VALUES('When all at once I saw a crowd,'); |
37 INSERT INTO t1(content) VALUES('A host, of golden daffodils,'); | 39 INSERT INTO t1(content) VALUES('A host, of golden daffodils,'); |
38 SELECT mit(matchinfo(t1)) FROM t1 WHERE t1 MATCH 'I'; | 40 SELECT mit(matchinfo(t1)) FROM t1 WHERE t1 MATCH 'I'; |
39 } {{1 1 1 2 2} {1 1 1 2 2}} | 41 } {{1 1 1 2 2} {1 1 1 2 2}} |
40 | 42 |
41 # Now create an FTS4 table that does not specify matchinfo=fts3. | 43 # Now create an FTS4 table that does not specify matchinfo=fts3. |
42 # | 44 # |
43 do_execsql_test 1.2 { | 45 do_execsql_test 1.2 { |
44 CREATE VIRTUAL TABLE t2 USING fts5(content); | 46 CREATE VIRTUAL TABLE t2 USING fts5(content, detail=%DETAIL%); |
45 INSERT INTO t2 SELECT * FROM t1; | 47 INSERT INTO t2 SELECT * FROM t1; |
46 SELECT mit(matchinfo(t2)) FROM t2 WHERE t2 MATCH 'I'; | 48 SELECT mit(matchinfo(t2)) FROM t2 WHERE t2 MATCH 'I'; |
47 } {{1 1 1 2 2} {1 1 1 2 2}} | 49 } {{1 1 1 2 2} {1 1 1 2 2}} |
48 | 50 |
49 | 51 |
50 #-------------------------------------------------------------------------- | 52 #-------------------------------------------------------------------------- |
51 # Proc [do_matchinfo_test] is used to test the FTSX matchinfo() function. | 53 # Proc [do_matchinfo_test] is used to test the FTSX matchinfo() function. |
52 # | 54 # |
53 # The first argument - $tn - is a test identifier. This may be either a | 55 # The first argument - $tn - is a test identifier. This may be either a |
54 # full identifier (i.e. "fts3matchinfo-1.1") or, if global var $testprefix | 56 # full identifier (i.e. "fts3matchinfo-1.1") or, if global var $testprefix |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 do_execsql_test $tn.multi $sql [normalize2 $allres] | 144 do_execsql_test $tn.multi $sql [normalize2 $allres] |
143 } | 145 } |
144 proc normalize2 {list_of_lists} { | 146 proc normalize2 {list_of_lists} { |
145 set res [list] | 147 set res [list] |
146 foreach elem $list_of_lists { | 148 foreach elem $list_of_lists { |
147 lappend res [list {*}$elem] | 149 lappend res [list {*}$elem] |
148 } | 150 } |
149 return $res | 151 return $res |
150 } | 152 } |
151 | 153 |
| 154 # Similar to [do_matchinfo_test], except that this is a no-op if the FTS5 |
| 155 # mode is not detail=full. |
| 156 # |
| 157 proc do_matchinfo_p_test {tn tbl expr results} { |
| 158 if {[detail_is_full]} { |
| 159 uplevel [list do_matchinfo_test $tn $tbl $expr $results] |
| 160 } |
| 161 } |
152 | 162 |
153 do_execsql_test 4.1.0 { | 163 do_execsql_test 4.1.0 { |
154 CREATE VIRTUAL TABLE t4 USING fts5(x, y); | 164 CREATE VIRTUAL TABLE t4 USING fts5(x, y, detail=%DETAIL%); |
155 INSERT INTO t4 VALUES('a b c d e', 'f g h i j'); | 165 INSERT INTO t4 VALUES('a b c d e', 'f g h i j'); |
156 INSERT INTO t4 VALUES('f g h i j', 'a b c d e'); | 166 INSERT INTO t4 VALUES('f g h i j', 'a b c d e'); |
157 } | 167 } |
158 | 168 |
159 do_matchinfo_test 4.1.1 t4 {t4 MATCH 'a b c'} { | 169 do_matchinfo_test 4.1.1 t4 {t4 MATCH 'a b c'} { |
160 s {{3 0} {0 3}} | 170 s {{3 0} {0 3}} |
161 } | 171 } |
162 | 172 |
163 do_matchinfo_test 4.1.1 t4 {t4 MATCH 'a b c'} { | 173 do_matchinfo_test 4.1.1 t4 {t4 MATCH 'a b c'} { |
164 p {3 3} | 174 p {3 3} |
(...skipping 13 matching lines...) Expand all Loading... |
178 n {2 2} | 188 n {2 2} |
179 l {{5 5} {5 5}} | 189 l {{5 5} {5 5}} |
180 a {{5 5} {5 5}} | 190 a {{5 5} {5 5}} |
181 | 191 |
182 s {{3 0} {0 3}} | 192 s {{3 0} {0 3}} |
183 | 193 |
184 xxxxxxxxxxxxxxxxxx - pcx - xpc - ccc - pppxpcpcx - laxnpc - | 194 xxxxxxxxxxxxxxxxxx - pcx - xpc - ccc - pppxpcpcx - laxnpc - |
185 xpxsscplax - | 195 xpxsscplax - |
186 } | 196 } |
187 | 197 |
188 do_matchinfo_test 4.1.2 t4 {t4 MATCH '"g h i"'} { | 198 do_matchinfo_p_test 4.1.2 t4 {t4 MATCH '"g h i"'} { |
189 p {1 1} | 199 p {1 1} |
190 c {2 2} | 200 c {2 2} |
191 x { | 201 x { |
192 {0 1 1 1 1 1} | 202 {0 1 1 1 1 1} |
193 {1 1 1 0 1 1} | 203 {1 1 1 0 1 1} |
194 } | 204 } |
195 n {2 2} | 205 n {2 2} |
196 l {{5 5} {5 5}} | 206 l {{5 5} {5 5}} |
197 a {{5 5} {5 5}} | 207 a {{5 5} {5 5}} |
198 | 208 |
199 s {{0 1} {1 0}} | 209 s {{0 1} {1 0}} |
200 | 210 |
201 xxxxxxxxxxxxxxxxxx - pcx - xpc - ccc - pppxpcpcx - laxnpc - | 211 xxxxxxxxxxxxxxxxxx - pcx - xpc - ccc - pppxpcpcx - laxnpc - |
202 sxsxs - | 212 sxsxs - |
203 } | 213 } |
204 | 214 |
205 do_matchinfo_test 4.1.3 t4 {t4 MATCH 'a b'} { s {{2 0} {0 2}} } | 215 do_matchinfo_test 4.1.3 t4 {t4 MATCH 'a b'} { s {{2 0} {0 2}} } |
206 do_matchinfo_test 4.1.4 t4 {t4 MATCH '"a b" c'} { s {{2 0} {0 2}} } | 216 do_matchinfo_p_test 4.1.4 t4 {t4 MATCH '"a b" c'} { s {{2 0} {0 2}} } |
207 do_matchinfo_test 4.1.5 t4 {t4 MATCH 'a "b c"'} { s {{2 0} {0 2}} } | 217 do_matchinfo_p_test 4.1.5 t4 {t4 MATCH 'a "b c"'} { s {{2 0} {0 2}} } |
208 do_matchinfo_test 4.1.6 t4 {t4 MATCH 'd d'} { s {{1 0} {0 1}} } | 218 do_matchinfo_test 4.1.6 t4 {t4 MATCH 'd d'} { s {{1 0} {0 1}} } |
209 do_matchinfo_test 4.1.7 t4 {t4 MATCH 'f OR abcd'} { | 219 do_matchinfo_test 4.1.7 t4 {t4 MATCH 'f OR abcd'} { |
210 x { | 220 x { |
211 {0 1 1 1 1 1 0 0 0 0 0 0} | 221 {0 1 1 1 1 1 0 0 0 0 0 0} |
212 {1 1 1 0 1 1 0 0 0 0 0 0} | 222 {1 1 1 0 1 1 0 0 0 0 0 0} |
213 } | 223 } |
214 } | 224 } |
215 do_matchinfo_test 4.1.8 t4 {t4 MATCH 'f NOT abcd'} { | 225 do_matchinfo_test 4.1.8 t4 {t4 MATCH 'f NOT abcd'} { |
216 x { | 226 x { |
217 {0 1 1 1 1 1 0 0 0 0 0 0} | 227 {0 1 1 1 1 1 0 0 0 0 0 0} |
218 {1 1 1 0 1 1 0 0 0 0 0 0} | 228 {1 1 1 0 1 1 0 0 0 0 0 0} |
219 } | 229 } |
220 } | 230 } |
221 | 231 |
222 do_execsql_test 4.2.0 { | 232 do_execsql_test 4.2.0 { |
223 CREATE VIRTUAL TABLE t5 USING fts5(content); | 233 CREATE VIRTUAL TABLE t5 USING fts5(content, detail=%DETAIL%); |
224 INSERT INTO t5 VALUES('a a a a a'); | 234 INSERT INTO t5 VALUES('a a a a a'); |
225 INSERT INTO t5 VALUES('a b a b a'); | 235 INSERT INTO t5 VALUES('a b a b a'); |
226 INSERT INTO t5 VALUES('c b c b c'); | 236 INSERT INTO t5 VALUES('c b c b c'); |
227 INSERT INTO t5 VALUES('x x x x x'); | 237 INSERT INTO t5 VALUES('x x x x x'); |
228 } | 238 } |
229 do_matchinfo_test 4.2.1 t5 {t5 MATCH 'a a'} { | 239 do_matchinfo_test 4.2.1 t5 {t5 MATCH 'a a'} { |
230 x {{5 8 2 5 8 2} {3 8 2 3 8 2}} | 240 x {{5 8 2 5 8 2} {3 8 2 3 8 2}} |
231 s {2 1} | 241 s {2 1} |
232 } | 242 } |
233 do_matchinfo_test 4.2.2 t5 {t5 MATCH 'a b'} { s {2} } | 243 do_matchinfo_test 4.2.2 t5 {t5 MATCH 'a b'} { s {2} } |
234 do_matchinfo_test 4.2.3 t5 {t5 MATCH 'a b a'} { s {3} } | 244 do_matchinfo_test 4.2.3 t5 {t5 MATCH 'a b a'} { s {3} } |
235 do_matchinfo_test 4.2.4 t5 {t5 MATCH 'a a a'} { s {3 1} } | 245 do_matchinfo_test 4.2.4 t5 {t5 MATCH 'a a a'} { s {3 1} } |
236 do_matchinfo_test 4.2.5 t5 {t5 MATCH '"a b" "a b"'} { s {2} } | 246 do_matchinfo_p_test 4.2.5 t5 {t5 MATCH '"a b" "a b"'} { s {2} } |
237 do_matchinfo_test 4.2.6 t5 {t5 MATCH 'a OR b'} { s {1 2 1} } | 247 do_matchinfo_test 4.2.6 t5 {t5 MATCH 'a OR b'} { s {1 2 1} } |
238 | 248 |
239 do_execsql_test 4.3.0 "INSERT INTO t5 VALUES('x y [string repeat {b } 50000]')"; | 249 do_execsql_test 4.3.0 "INSERT INTO t5 VALUES('x y [string repeat {b } 50000]')"; |
240 | 250 |
241 # It used to be that the second 'a' token would be deferred. That doesn't | 251 # It used to be that the second 'a' token would be deferred. That doesn't |
242 # work any longer. | 252 # work any longer. |
243 if 0 { | 253 if 0 { |
244 do_matchinfo_test 4.3.1 t5 {t5 MATCH 'a a'} { | 254 do_matchinfo_test 4.3.1 t5 {t5 MATCH 'a a'} { |
245 x {{5 8 2 5 5 5} {3 8 2 3 5 5}} | 255 x {{5 8 2 5 5 5} {3 8 2 3 5 5}} |
246 s {2 1} | 256 s {2 1} |
247 } | 257 } |
248 } | 258 } |
249 | 259 |
250 do_matchinfo_test 4.3.2 t5 {t5 MATCH 'a b'} { s {2} } | 260 do_matchinfo_test 4.3.2 t5 {t5 MATCH 'a b'} { s {2} } |
251 do_matchinfo_test 4.3.3 t5 {t5 MATCH 'a b a'} { s {3} } | 261 do_matchinfo_test 4.3.3 t5 {t5 MATCH 'a b a'} { s {3} } |
252 do_matchinfo_test 4.3.4 t5 {t5 MATCH 'a a a'} { s {3 1} } | 262 do_matchinfo_test 4.3.4 t5 {t5 MATCH 'a a a'} { s {3 1} } |
253 do_matchinfo_test 4.3.5 t5 {t5 MATCH '"a b" "a b"'} { s {2} } | 263 do_matchinfo_p_test 4.3.5 t5 {t5 MATCH '"a b" "a b"'} { s {2} } |
254 do_matchinfo_test 4.3.6 t5 {t5 MATCH 'a OR b'} { s {1 2 1 1} } | 264 do_matchinfo_test 4.3.6 t5 {t5 MATCH 'a OR b'} { s {1 2 1 1} } |
255 | 265 |
256 do_execsql_test 4.4.0.1 { INSERT INTO t5(t5) VALUES('optimize') } | 266 do_execsql_test 4.4.0.1 { INSERT INTO t5(t5) VALUES('optimize') } |
257 | 267 |
258 do_matchinfo_test 4.4.2 t5 {t5 MATCH 'a b'} { s {2} } | 268 do_matchinfo_test 4.4.2 t5 {t5 MATCH 'a b'} { s {2} } |
259 do_matchinfo_test 4.4.1 t5 {t5 MATCH 'a a'} { s {2 1} } | 269 do_matchinfo_test 4.4.1 t5 {t5 MATCH 'a a'} { s {2 1} } |
260 do_matchinfo_test 4.4.2 t5 {t5 MATCH 'a b'} { s {2} } | 270 do_matchinfo_test 4.4.2 t5 {t5 MATCH 'a b'} { s {2} } |
261 do_matchinfo_test 4.4.3 t5 {t5 MATCH 'a b a'} { s {3} } | 271 do_matchinfo_test 4.4.3 t5 {t5 MATCH 'a b a'} { s {3} } |
262 do_matchinfo_test 4.4.4 t5 {t5 MATCH 'a a a'} { s {3 1} } | 272 do_matchinfo_test 4.4.4 t5 {t5 MATCH 'a a a'} { s {3 1} } |
263 do_matchinfo_test 4.4.5 t5 {t5 MATCH '"a b" "a b"'} { s {2} } | 273 do_matchinfo_p_test 4.4.5 t5 {t5 MATCH '"a b" "a b"'} { s {2} } |
264 | 274 |
265 do_execsql_test 4.5.0 { | 275 do_execsql_test 4.5.0 { |
266 CREATE VIRTUAL TABLE t6 USING fts5(a, b, c); | 276 CREATE VIRTUAL TABLE t6 USING fts5(a, b, c, detail=%DETAIL%); |
267 INSERT INTO t6 VALUES('a', 'b', 'c'); | 277 INSERT INTO t6 VALUES('a', 'b', 'c'); |
268 } | 278 } |
269 do_matchinfo_test 4.5.1 t6 {t6 MATCH 'a b c'} { s {{1 1 1}} } | 279 do_matchinfo_test 4.5.1 t6 {t6 MATCH 'a b c'} { s {{1 1 1}} } |
270 | 280 |
271 | 281 |
272 #------------------------------------------------------------------------- | 282 #------------------------------------------------------------------------- |
273 # Test the outcome of matchinfo() when used within a query that does not | 283 # Test the outcome of matchinfo() when used within a query that does not |
274 # use the full-text index (i.e. lookup by rowid or full-table scan). | 284 # use the full-text index (i.e. lookup by rowid or full-table scan). |
275 # | 285 # |
276 do_execsql_test 7.1 { | 286 do_execsql_test 7.1 { |
277 CREATE VIRTUAL TABLE t10 USING fts5(content); | 287 CREATE VIRTUAL TABLE t10 USING fts5(content, detail=%DETAIL%); |
278 INSERT INTO t10 VALUES('first record'); | 288 INSERT INTO t10 VALUES('first record'); |
279 INSERT INTO t10 VALUES('second record'); | 289 INSERT INTO t10 VALUES('second record'); |
280 } | 290 } |
281 do_execsql_test 7.2 { | 291 do_execsql_test 7.2 { |
282 SELECT typeof(matchinfo(t10)), length(matchinfo(t10)) FROM t10; | 292 SELECT typeof(matchinfo(t10)), length(matchinfo(t10)) FROM t10; |
283 } {blob 8 blob 8} | 293 } {blob 8 blob 8} |
284 do_execsql_test 7.3 { | 294 do_execsql_test 7.3 { |
285 SELECT typeof(matchinfo(t10)), length(matchinfo(t10)) FROM t10 WHERE rowid=1; | 295 SELECT typeof(matchinfo(t10)), length(matchinfo(t10)) FROM t10 WHERE rowid=1; |
286 } {blob 8} | 296 } {blob 8} |
287 do_execsql_test 7.4 { | 297 do_execsql_test 7.4 { |
288 SELECT typeof(matchinfo(t10)), length(matchinfo(t10)) | 298 SELECT typeof(matchinfo(t10)), length(matchinfo(t10)) |
289 FROM t10 WHERE t10 MATCH 'record' | 299 FROM t10 WHERE t10 MATCH 'record' |
290 } {blob 20 blob 20} | 300 } {blob 20 blob 20} |
291 | 301 |
292 #------------------------------------------------------------------------- | 302 #------------------------------------------------------------------------- |
293 # Test a special case - matchinfo('nxa') with many zero length documents. | 303 # Test a special case - matchinfo('nxa') with many zero length documents. |
294 # Special because "x" internally uses a statement used by both "n" and "a". | 304 # Special because "x" internally uses a statement used by both "n" and "a". |
295 # This was causing a problem at one point in the obscure case where the | 305 # This was causing a problem at one point in the obscure case where the |
296 # total number of bytes of data stored in an fts3 table was greater than | 306 # total number of bytes of data stored in an fts3 table was greater than |
297 # the number of rows. i.e. when the following query returns true: | 307 # the number of rows. i.e. when the following query returns true: |
298 # | 308 # |
299 # SELECT sum(length(content)) < count(*) FROM fts4table; | 309 # SELECT sum(length(content)) < count(*) FROM fts4table; |
300 # | 310 # |
301 do_execsql_test 8.1 { | 311 do_execsql_test 8.1 { |
302 CREATE VIRTUAL TABLE t11 USING fts5(content); | 312 CREATE VIRTUAL TABLE t11 USING fts5(content, detail=%DETAIL%); |
303 INSERT INTO t11(t11, rank) VALUES('pgsz', 32); | 313 INSERT INTO t11(t11, rank) VALUES('pgsz', 32); |
304 INSERT INTO t11 VALUES('quitealongstringoftext'); | 314 INSERT INTO t11 VALUES('quitealongstringoftext'); |
305 INSERT INTO t11 VALUES('anotherquitealongstringoftext'); | 315 INSERT INTO t11 VALUES('anotherquitealongstringoftext'); |
306 INSERT INTO t11 VALUES('athirdlongstringoftext'); | 316 INSERT INTO t11 VALUES('athirdlongstringoftext'); |
307 INSERT INTO t11 VALUES('andonemoreforgoodluck'); | 317 INSERT INTO t11 VALUES('andonemoreforgoodluck'); |
308 } | 318 } |
309 do_test 8.2 { | 319 do_test 8.2 { |
310 for {set i 0} {$i < 200} {incr i} { | 320 for {set i 0} {$i < 200} {incr i} { |
311 execsql { INSERT INTO t11 VALUES('') } | 321 execsql { INSERT INTO t11 VALUES('') } |
312 } | 322 } |
313 execsql { INSERT INTO t11(t11) VALUES('optimize') } | 323 execsql { INSERT INTO t11(t11) VALUES('optimize') } |
314 } {} | 324 } {} |
315 do_execsql_test 8.3 { | 325 do_execsql_test 8.3 { |
316 SELECT mit(matchinfo(t11, 'nxa')) FROM t11 WHERE t11 MATCH 'a*' | 326 SELECT mit(matchinfo(t11, 'nxa')) FROM t11 WHERE t11 MATCH 'a*' |
317 } {{204 1 3 3 0} {204 1 3 3 0} {204 1 3 3 0}} | 327 } {{204 1 3 3 0} {204 1 3 3 0} {204 1 3 3 0}} |
318 | 328 |
319 #------------------------------------------------------------------------- | 329 #------------------------------------------------------------------------- |
320 | 330 |
321 do_execsql_test 9.1 { | 331 if {[detail_is_full]} { |
322 CREATE VIRTUAL TABLE t12 USING fts5(content); | 332 do_execsql_test 9.1 { |
323 INSERT INTO t12 VALUES('a b c d'); | 333 CREATE VIRTUAL TABLE t12 USING fts5(content, detail=%DETAIL%); |
324 SELECT mit(matchinfo(t12, 'x')) FROM t12 WHERE t12 MATCH 'NEAR(a d, 1) OR a'; | 334 INSERT INTO t12 VALUES('a b c d'); |
325 } {{0 1 1 0 1 1 1 1 1}} | 335 SELECT mit(matchinfo(t12,'x')) FROM t12 WHERE t12 MATCH 'NEAR(a d, 1) OR a'; |
326 do_execsql_test 9.2 { | 336 } {{0 1 1 0 1 1 1 1 1}} |
327 INSERT INTO t12 VALUES('a d c d'); | 337 do_execsql_test 9.2 { |
328 SELECT mit(matchinfo(t12, 'x')) FROM t12 WHERE t12 MATCH 'NEAR(a d, 1) OR a'; | 338 INSERT INTO t12 VALUES('a d c d'); |
329 } { | 339 SELECT mit(matchinfo(t12,'x')) FROM t12 WHERE t12 MATCH 'NEAR(a d, 1) OR a'; |
330 {0 2 2 0 3 2 1 2 2} {1 2 2 1 3 2 1 2 2} | 340 } { |
331 } | 341 {0 2 2 0 3 2 1 2 2} {1 2 2 1 3 2 1 2 2} |
332 do_execsql_test 9.3 { | 342 } |
333 INSERT INTO t12 VALUES('a d d a'); | 343 do_execsql_test 9.3 { |
334 SELECT mit(matchinfo(t12, 'x')) FROM t12 WHERE t12 MATCH 'NEAR(a d, 1) OR a'; | 344 INSERT INTO t12 VALUES('a d d a'); |
335 } { | 345 SELECT mit(matchinfo(t12,'x')) FROM t12 WHERE t12 MATCH 'NEAR(a d, 1) OR a'; |
336 {0 4 3 0 5 3 1 4 3} {1 4 3 1 5 3 1 4 3} {2 4 3 2 5 3 2 4 3} | 346 } { |
| 347 {0 4 3 0 5 3 1 4 3} {1 4 3 1 5 3 1 4 3} {2 4 3 2 5 3 2 4 3} |
| 348 } |
337 } | 349 } |
338 | 350 |
339 #--------------------------------------------------------------------------- | 351 #--------------------------------------------------------------------------- |
340 # Test for a memory leak | 352 # Test for a memory leak |
341 # | 353 # |
342 do_execsql_test 10.1 { | 354 do_execsql_test 10.1 { |
343 DROP TABLE t10; | 355 DROP TABLE t10; |
344 CREATE VIRTUAL TABLE t10 USING fts5(idx, value); | 356 CREATE VIRTUAL TABLE t10 USING fts5(idx, value, detail=%DETAIL%); |
345 INSERT INTO t10 values (1, 'one'),(2, 'two'),(3, 'three'); | 357 INSERT INTO t10 values (1, 'one'),(2, 'two'),(3, 'three'); |
346 SELECT t10.rowid, t10.* | 358 SELECT t10.rowid, t10.* |
347 FROM t10 | 359 FROM t10 |
348 JOIN (SELECT 1 AS idx UNION SELECT 2 UNION SELECT 3) AS x | 360 JOIN (SELECT 1 AS idx UNION SELECT 2 UNION SELECT 3) AS x |
349 WHERE t10 MATCH x.idx | 361 WHERE t10 MATCH x.idx |
350 AND matchinfo(t10) not null | 362 AND matchinfo(t10) not null |
351 GROUP BY t10.rowid | 363 GROUP BY t10.rowid |
352 ORDER BY 1; | 364 ORDER BY 1; |
353 } {1 1 one 2 2 two 3 3 three} | 365 } {1 1 one 2 2 two 3 3 three} |
354 | 366 |
355 #--------------------------------------------------------------------------- | 367 #--------------------------------------------------------------------------- |
356 # Test the 'y' matchinfo flag | 368 # Test the 'y' matchinfo flag |
357 # | 369 # |
358 reset_db | 370 reset_db |
359 sqlite3_fts5_register_matchinfo db | 371 sqlite3_fts5_register_matchinfo db |
360 do_execsql_test 11.0 { | 372 do_execsql_test 11.0 { |
361 CREATE VIRTUAL TABLE tt USING fts5(x, y); | 373 CREATE VIRTUAL TABLE tt USING fts5(x, y, detail=%DETAIL%); |
362 INSERT INTO tt VALUES('c d a c d d', 'e a g b d a'); -- 1 | 374 INSERT INTO tt VALUES('c d a c d d', 'e a g b d a'); -- 1 |
363 INSERT INTO tt VALUES('c c g a e b', 'c g d g e c'); -- 2 | 375 INSERT INTO tt VALUES('c c g a e b', 'c g d g e c'); -- 2 |
364 INSERT INTO tt VALUES('b e f d e g', 'b a c b c g'); -- 3 | 376 INSERT INTO tt VALUES('b e f d e g', 'b a c b c g'); -- 3 |
365 INSERT INTO tt VALUES('a c f f g d', 'd b f d e g'); -- 4 | 377 INSERT INTO tt VALUES('a c f f g d', 'd b f d e g'); -- 4 |
366 INSERT INTO tt VALUES('g a c f c f', 'd g g b c c'); -- 5 | 378 INSERT INTO tt VALUES('g a c f c f', 'd g g b c c'); -- 5 |
367 INSERT INTO tt VALUES('g a c e b b', 'd b f b g g'); -- 6 | 379 INSERT INTO tt VALUES('g a c e b b', 'd b f b g g'); -- 6 |
368 INSERT INTO tt VALUES('f d a a f c', 'e e a d c f'); -- 7 | 380 INSERT INTO tt VALUES('f d a a f c', 'e e a d c f'); -- 7 |
369 INSERT INTO tt VALUES('a c b b g f', 'a b a e d f'); -- 8 | 381 INSERT INTO tt VALUES('a c b b g f', 'a b a e d f'); -- 8 |
370 INSERT INTO tt VALUES('b a f e c c', 'f d b b a b'); -- 9 | 382 INSERT INTO tt VALUES('b a f e c c', 'f d b b a b'); -- 9 |
371 INSERT INTO tt VALUES('f d c e a c', 'f a f a a f'); -- 10 | 383 INSERT INTO tt VALUES('f d c e a c', 'f a f a a f'); -- 10 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
403 6 {1 0 2 2} 8 {1 2 2 1} 9 {1 1 1 3} | 415 6 {1 0 2 2} 8 {1 2 2 1} 9 {1 1 1 3} |
404 } | 416 } |
405 | 417 |
406 7 "a OR (a AND b)" { | 418 7 "a OR (a AND b)" { |
407 1 {1 2 1 2 0 1} 2 {1 0 1 0 1 0} 3 {0 1 0 1 1 2} 4 {1 0 1 0 0 1} | 419 1 {1 2 1 2 0 1} 2 {1 0 1 0 1 0} 3 {0 1 0 1 1 2} 4 {1 0 1 0 0 1} |
408 5 {1 0 1 0 0 1} 6 {1 0 1 0 2 2} 7 {2 1 0 0 0 0} 8 {1 2 1 2 2 1} | 420 5 {1 0 1 0 0 1} 6 {1 0 1 0 2 2} 7 {2 1 0 0 0 0} 8 {1 2 1 2 2 1} |
409 9 {1 1 1 1 1 3} 10 {1 3 0 0 0 0} | 421 9 {1 1 1 1 1 3} 10 {1 3 0 0 0 0} |
410 } | 422 } |
411 | 423 |
412 } { | 424 } { |
| 425 |
| 426 if {[string match *:* $expr] && [detail_is_none]} continue |
413 do_execsql_test 11.1.$tn.1 { | 427 do_execsql_test 11.1.$tn.1 { |
414 SELECT rowid, mit(matchinfo(tt, 'y')) FROM tt WHERE tt MATCH $expr | 428 SELECT rowid, mit(matchinfo(tt, 'y')) FROM tt WHERE tt MATCH $expr |
415 } $res | 429 } $res |
416 | 430 |
417 set r2 [list] | 431 set r2 [list] |
418 foreach {rowid L} $res { | 432 foreach {rowid L} $res { |
419 lappend r2 $rowid | 433 lappend r2 $rowid |
420 set M [list] | 434 set M [list] |
421 foreach {a b} $L { | 435 foreach {a b} $L { |
422 lappend M [expr ($a ? 1 : 0) + ($b ? 2 : 0)] | 436 lappend M [expr ($a ? 1 : 0) + ($b ? 2 : 0)] |
(...skipping 13 matching lines...) Expand all Loading... |
436 #--------------------------------------------------------------------------- | 450 #--------------------------------------------------------------------------- |
437 # Test the 'b' matchinfo flag | 451 # Test the 'b' matchinfo flag |
438 # | 452 # |
439 reset_db | 453 reset_db |
440 sqlite3_fts5_register_matchinfo db | 454 sqlite3_fts5_register_matchinfo db |
441 db func mit mit | 455 db func mit mit |
442 | 456 |
443 do_test 12.0 { | 457 do_test 12.0 { |
444 set cols [list] | 458 set cols [list] |
445 for {set i 0} {$i < 50} {incr i} { lappend cols "c$i" } | 459 for {set i 0} {$i < 50} {incr i} { lappend cols "c$i" } |
446 execsql "CREATE VIRTUAL TABLE tt USING fts5([join $cols ,])" | 460 execsql "CREATE VIRTUAL TABLE tt USING fts5([join $cols ,], detail=%DETAIL%)" |
447 } {} | 461 } {} |
448 | 462 |
449 do_execsql_test 12.1 { | 463 do_execsql_test 12.1 { |
450 INSERT INTO tt (rowid, c4, c45) VALUES(1, 'abc', 'abc'); | 464 INSERT INTO tt (rowid, c4, c45) VALUES(1, 'abc', 'abc'); |
451 SELECT mit(matchinfo(tt, 'b')) FROM tt WHERE tt MATCH 'abc'; | 465 SELECT mit(matchinfo(tt, 'b')) FROM tt WHERE tt MATCH 'abc'; |
452 } [list [list [expr 1<<4] [expr 1<<(45-32)]]] | 466 } [list [list [expr 1<<4] [expr 1<<(45-32)]]] |
453 | 467 |
| 468 } ;# foreach_detail_mode |
| 469 |
| 470 #------------------------------------------------------------------------- |
| 471 # Test that a bad fts5() return is detected |
| 472 # |
| 473 reset_db |
| 474 proc xyz {} {} |
| 475 db func fts5 -argcount 0 xyz |
| 476 do_test 13.1 { |
| 477 list [catch { sqlite3_fts5_register_matchinfo db } msg] $msg |
| 478 } {1 SQLITE_ERROR} |
| 479 |
| 480 #------------------------------------------------------------------------- |
| 481 # Test that an invalid matchinfo() flag is detected |
| 482 # |
| 483 reset_db |
| 484 sqlite3_fts5_register_matchinfo db |
| 485 do_execsql_test 14.1 { |
| 486 CREATE VIRTUAL TABLE x1 USING fts5(z); |
| 487 INSERT INTO x1 VALUES('a b c a b c a b c'); |
| 488 } {} |
| 489 |
| 490 do_catchsql_test 14.2 { |
| 491 SELECT matchinfo(x1, 'd') FROM x1('a b c'); |
| 492 } {1 {unrecognized matchinfo flag: d}} |
| 493 |
454 finish_test | 494 finish_test |
455 | 495 |
OLD | NEW |