OLD | NEW |
| (Empty) |
1 # 2014 November 24 | |
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 implements regression tests for SQLite library. The | |
12 # focus of this script is testing the FTS5 module. | |
13 # | |
14 # Specifically, this function tests the %_config table. | |
15 # | |
16 | |
17 source [file join [file dirname [info script]] fts5_common.tcl] | |
18 set testprefix fts5al | |
19 | |
20 # If SQLITE_ENABLE_FTS5 is defined, omit this file. | |
21 ifcapable !fts5 { | |
22 finish_test | |
23 return | |
24 } | |
25 | |
26 do_execsql_test 1.1 { | |
27 CREATE VIRTUAL TABLE ft1 USING fts5(x); | |
28 SELECT * FROM ft1_config; | |
29 } {version 4} | |
30 | |
31 do_execsql_test 1.2 { | |
32 INSERT INTO ft1(ft1, rank) VALUES('pgsz', 32); | |
33 SELECT * FROM ft1_config; | |
34 } {pgsz 32 version 4} | |
35 | |
36 do_execsql_test 1.3 { | |
37 INSERT INTO ft1(ft1, rank) VALUES('pgsz', 64); | |
38 SELECT * FROM ft1_config; | |
39 } {pgsz 64 version 4} | |
40 | |
41 #-------------------------------------------------------------------------- | |
42 # Test the logic for parsing the rank() function definition. | |
43 # | |
44 foreach {tn defn} { | |
45 1 "fname()" | |
46 2 "fname(1)" | |
47 3 "fname(1,2)" | |
48 4 "fname(null,NULL,nUlL)" | |
49 5 " fname ( null , NULL , nUlL ) " | |
50 6 "fname('abc')" | |
51 7 "fname('a''bc')" | |
52 8 "fname('''abc')" | |
53 9 "fname('abc''')" | |
54 | |
55 7 "fname( 'a''bc' )" | |
56 8 "fname('''abc' )" | |
57 9 "fname( 'abc''' )" | |
58 | |
59 10 "fname(X'1234ab')" | |
60 | |
61 11 "myfunc(1.2)" | |
62 12 "myfunc(-1.0)" | |
63 13 "myfunc(.01,'abc')" | |
64 } { | |
65 do_execsql_test 2.1.$tn { | |
66 INSERT INTO ft1(ft1, rank) VALUES('rank', $defn); | |
67 } | |
68 } | |
69 | |
70 foreach {tn defn} { | |
71 1 "" | |
72 2 "fname" | |
73 3 "fname(X'234ab')" | |
74 4 "myfunc(-1.,'abc')" | |
75 } { | |
76 do_test 2.2.$tn { | |
77 catchsql { INSERT INTO ft1(ft1, rank) VALUES('rank', $defn) } | |
78 } {1 {SQL logic error or missing database}} | |
79 } | |
80 | |
81 #------------------------------------------------------------------------- | |
82 # Assorted tests of the tcl interface for creating extension functions. | |
83 # | |
84 | |
85 do_execsql_test 3.1 { | |
86 CREATE VIRTUAL TABLE t1 USING fts5(x); | |
87 INSERT INTO t1 VALUES('q w e r t y'); | |
88 INSERT INTO t1 VALUES('y t r e w q'); | |
89 } | |
90 | |
91 proc argtest {cmd args} { return $args } | |
92 sqlite3_fts5_create_function db argtest argtest | |
93 | |
94 do_execsql_test 3.2.1 { | |
95 SELECT argtest(t1, 123) FROM t1 WHERE t1 MATCH 'q' | |
96 } {123 123} | |
97 | |
98 do_execsql_test 3.2.2 { | |
99 SELECT argtest(t1, 123, 456) FROM t1 WHERE t1 MATCH 'q' | |
100 } {{123 456} {123 456}} | |
101 | |
102 proc rowidtest {cmd} { $cmd xRowid } | |
103 sqlite3_fts5_create_function db rowidtest rowidtest | |
104 | |
105 do_execsql_test 3.3.1 { | |
106 SELECT rowidtest(t1) FROM t1 WHERE t1 MATCH 'q' | |
107 } {1 2} | |
108 | |
109 proc insttest {cmd} { | |
110 set res [list] | |
111 for {set i 0} {$i < [$cmd xInstCount]} {incr i} { | |
112 lappend res [$cmd xInst $i] | |
113 } | |
114 set res | |
115 } | |
116 sqlite3_fts5_create_function db insttest insttest | |
117 | |
118 do_execsql_test 3.4.1 { | |
119 SELECT insttest(t1) FROM t1 WHERE t1 MATCH 'q' | |
120 } { | |
121 {{0 0 0}} | |
122 {{0 0 5}} | |
123 } | |
124 | |
125 do_execsql_test 3.4.2 { | |
126 SELECT insttest(t1) FROM t1 WHERE t1 MATCH 'r+e OR w' | |
127 } { | |
128 {{1 0 1}} | |
129 {{0 0 2} {1 0 4}} | |
130 } | |
131 | |
132 proc coltest {cmd} { | |
133 list [$cmd xColumnSize 0] [$cmd xColumnText 0] | |
134 } | |
135 sqlite3_fts5_create_function db coltest coltest | |
136 | |
137 do_execsql_test 3.5.1 { | |
138 SELECT coltest(t1) FROM t1 WHERE t1 MATCH 'q' | |
139 } { | |
140 {6 {q w e r t y}} | |
141 {6 {y t r e w q}} | |
142 } | |
143 | |
144 #------------------------------------------------------------------------- | |
145 # Tests for remapping the "rank" column. | |
146 # | |
147 # 4.1.*: Mapped to a function with no arguments. | |
148 # 4.2.*: Mapped to a function with one or more arguments. | |
149 # | |
150 | |
151 do_execsql_test 4.0 { | |
152 CREATE VIRTUAL TABLE t2 USING fts5(a, b); | |
153 INSERT INTO t2 VALUES('a s h g s b j m r h', 's b p a d b b a o e'); | |
154 INSERT INTO t2 VALUES('r h n t a g r d d i', 'l d n j r c f t o q'); | |
155 INSERT INTO t2 VALUES('q k n i k c a a e m', 'c h n j p g s c i t'); | |
156 INSERT INTO t2 VALUES('h j g t r e l s g s', 'k q k c i i c k n s'); | |
157 INSERT INTO t2 VALUES('b l k h d n n n m i', 'p t i a r b t q o l'); | |
158 INSERT INTO t2 VALUES('k r i l j b g i p a', 't q c h a i m g n l'); | |
159 INSERT INTO t2 VALUES('a e c q n m o m d g', 'l c t g i s q g q e'); | |
160 INSERT INTO t2 VALUES('b o j h f o g b p e', 'r t l h s b g i c p'); | |
161 INSERT INTO t2 VALUES('s q k f q b j g h f', 'n m a o p e i e k t'); | |
162 INSERT INTO t2 VALUES('o q g g q c o k a b', 'r t k p t f t h p c'); | |
163 } | |
164 | |
165 proc firstinst {cmd} { | |
166 foreach {p c o} [$cmd xInst 0] {} | |
167 expr $c*100 + $o | |
168 } | |
169 sqlite3_fts5_create_function db firstinst firstinst | |
170 | |
171 do_execsql_test 4.1.1 { | |
172 SELECT rowid, firstinst(t2) FROM t2 WHERE t2 MATCH 'a' ORDER BY rowid ASC | |
173 } { | |
174 1 0 2 4 3 6 5 103 | |
175 6 9 7 0 9 102 10 8 | |
176 } | |
177 | |
178 do_execsql_test 4.1.2 { | |
179 SELECT rowid, rank FROM t2 | |
180 WHERE t2 MATCH 'a' AND rank MATCH 'firstinst()' | |
181 ORDER BY rowid ASC | |
182 } { | |
183 1 0 2 4 3 6 5 103 | |
184 6 9 7 0 9 102 10 8 | |
185 } | |
186 | |
187 do_execsql_test 4.1.3 { | |
188 SELECT rowid, rank FROM t2 | |
189 WHERE t2 MATCH 'a' AND rank MATCH 'firstinst()' | |
190 ORDER BY rank DESC | |
191 } { | |
192 5 103 9 102 6 9 10 8 3 6 2 4 1 0 7 0 | |
193 } | |
194 | |
195 do_execsql_test 4.1.4 { | |
196 INSERT INTO t2(t2, rank) VALUES('rank', 'firstinst()'); | |
197 SELECT rowid, rank FROM t2 WHERE t2 MATCH 'a' ORDER BY rowid ASC | |
198 } { | |
199 1 0 2 4 3 6 5 103 | |
200 6 9 7 0 9 102 10 8 | |
201 } | |
202 | |
203 do_execsql_test 4.1.5 { | |
204 SELECT rowid, rank FROM t2 WHERE t2 MATCH 'a' ORDER BY rank DESC | |
205 } { | |
206 5 103 9 102 6 9 10 8 3 6 2 4 1 0 7 0 | |
207 } | |
208 | |
209 do_execsql_test 4.1.6 { | |
210 INSERT INTO t2(t2, rank) VALUES('rank', 'firstinst ( ) '); | |
211 SELECT rowid, rank FROM t2 WHERE t2 MATCH 'a' ORDER BY rank DESC | |
212 } { | |
213 5 103 9 102 6 9 10 8 3 6 2 4 1 0 7 0 | |
214 } | |
215 | |
216 proc rowidplus {cmd ival} { | |
217 expr [$cmd xRowid] + $ival | |
218 } | |
219 sqlite3_fts5_create_function db rowidplus rowidplus | |
220 | |
221 do_execsql_test 4.2.1 { | |
222 INSERT INTO t2(t2, rank) VALUES('rank', 'rowidplus(100) '); | |
223 SELECT rowid, rank FROM t2 WHERE t2 MATCH 'o + q + g' | |
224 } { | |
225 10 110 | |
226 } | |
227 do_execsql_test 4.2.2 { | |
228 INSERT INTO t2(t2, rank) VALUES('rank', 'rowidplus(111) '); | |
229 SELECT rowid, rank FROM t2 WHERE t2 MATCH 'o + q + g' | |
230 } { | |
231 10 121 | |
232 } | |
233 | |
234 do_execsql_test 4.2.3 { | |
235 SELECT rowid, rank FROM t2 | |
236 WHERE t2 MATCH 'o + q + g' AND rank MATCH 'rowidplus(112)' | |
237 } { | |
238 10 122 | |
239 } | |
240 | |
241 proc rowidmod {cmd imod} { | |
242 expr [$cmd xRowid] % $imod | |
243 } | |
244 sqlite3_fts5_create_function db rowidmod rowidmod | |
245 do_execsql_test 4.3.1 { | |
246 CREATE VIRTUAL TABLE t3 USING fts5(x); | |
247 INSERT INTO t3 VALUES('a one'); | |
248 INSERT INTO t3 VALUES('a two'); | |
249 INSERT INTO t3 VALUES('a three'); | |
250 INSERT INTO t3 VALUES('a four'); | |
251 INSERT INTO t3 VALUES('a five'); | |
252 INSERT INTO t3(t3, rank) VALUES('rank', 'bm25()'); | |
253 } | |
254 | |
255 do_execsql_test 4.3.2 { | |
256 SELECT * FROM t3 | |
257 WHERE t3 MATCH 'a' AND rank MATCH 'rowidmod(4)' | |
258 ORDER BY rank ASC | |
259 } { | |
260 {a four} {a one} {a five} {a two} {a three} | |
261 } | |
262 | |
263 do_execsql_test 4.3.3 { | |
264 SELECT *, rank FROM t3 | |
265 WHERE t3 MATCH 'a' AND rank MATCH 'rowidmod(3)' | |
266 ORDER BY rank ASC | |
267 } { | |
268 {a three} 0 {a one} 1 {a four} 1 {a two} 2 {a five} 2 | |
269 } | |
270 | |
271 do_execsql_test 4.3.4 { | |
272 SELECT * FROM t3('a', 'rowidmod(4)') ORDER BY rank ASC; | |
273 } { | |
274 {a four} {a one} {a five} {a two} {a three} | |
275 } | |
276 | |
277 do_execsql_test 4.3.5 { | |
278 SELECT *, rank FROM t3('a', 'rowidmod(3)') ORDER BY rank ASC | |
279 } { | |
280 {a three} 0 {a one} 1 {a four} 1 {a two} 2 {a five} 2 | |
281 } | |
282 | |
283 do_catchsql_test 4.4.3 { | |
284 SELECT *, rank FROM t3 WHERE t3 MATCH 'a' AND rank MATCH 'xyz(3)' | |
285 } {1 {no such function: xyz}} | |
286 do_catchsql_test 4.4.4 { | |
287 SELECT *, rank FROM t3 WHERE t3 MATCH 'a' AND rank MATCH NULL | |
288 } {1 {parse error in rank function: }} | |
289 | |
290 | |
291 | |
292 finish_test | |
293 | |
OLD | NEW |