OLD | NEW |
(Empty) | |
| 1 # 2015 Apr 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 # |
| 12 # The tests in this file focus on testing the fts5vocab module. |
| 13 # |
| 14 |
| 15 source [file join [file dirname [info script]] fts5_common.tcl] |
| 16 set testprefix fts5vocab |
| 17 |
| 18 # If SQLITE_ENABLE_FTS5 is defined, omit this file. |
| 19 ifcapable !fts5 { |
| 20 finish_test |
| 21 return |
| 22 } |
| 23 |
| 24 |
| 25 do_execsql_test 1.1.1 { |
| 26 CREATE VIRTUAL TABLE t1 USING fts5(one, prefix=1); |
| 27 CREATE VIRTUAL TABLE v1 USING fts5vocab(t1, 'row'); |
| 28 PRAGMA table_info = v1; |
| 29 } { |
| 30 0 term {} 0 {} 0 |
| 31 1 doc {} 0 {} 0 |
| 32 2 cnt {} 0 {} 0 |
| 33 } |
| 34 |
| 35 do_execsql_test 1.1.2 { |
| 36 CREATE VIRTUAL TABLE v2 USING fts5vocab(t1, 'col'); |
| 37 PRAGMA table_info = v2; |
| 38 } { |
| 39 0 term {} 0 {} 0 |
| 40 1 col {} 0 {} 0 |
| 41 2 doc {} 0 {} 0 |
| 42 3 cnt {} 0 {} 0 |
| 43 } |
| 44 |
| 45 do_execsql_test 1.2.1 { SELECT * FROM v1 } { } |
| 46 do_execsql_test 1.2.2 { SELECT * FROM v2 } { } |
| 47 |
| 48 do_execsql_test 1.3 { |
| 49 INSERT INTO t1 VALUES('x y z'); |
| 50 INSERT INTO t1 VALUES('x x x'); |
| 51 } |
| 52 |
| 53 do_execsql_test 1.4.1 { |
| 54 SELECT * FROM v1; |
| 55 } {x 2 4 y 1 1 z 1 1} |
| 56 |
| 57 do_execsql_test 1.4.2 { |
| 58 SELECT * FROM v2; |
| 59 } {x one 2 4 y one 1 1 z one 1 1} |
| 60 |
| 61 do_execsql_test 1.5.1 { |
| 62 BEGIN; |
| 63 INSERT INTO t1 VALUES('a b c'); |
| 64 SELECT * FROM v1 WHERE term<'d'; |
| 65 } {a 1 1 b 1 1 c 1 1} |
| 66 |
| 67 do_execsql_test 1.5.2 { |
| 68 SELECT * FROM v2 WHERE term<'d'; |
| 69 COMMIT; |
| 70 } {a one 1 1 b one 1 1 c one 1 1} |
| 71 |
| 72 do_execsql_test 1.6 { |
| 73 DELETE FROM t1 WHERE one = 'a b c'; |
| 74 SELECT * FROM v1; |
| 75 } {x 2 4 y 1 1 z 1 1} |
| 76 |
| 77 #------------------------------------------------------------------------- |
| 78 # |
| 79 do_execsql_test 2.0 { |
| 80 CREATE VIRTUAL TABLE tt USING fts5(a, b); |
| 81 INSERT INTO tt VALUES('d g b f d f', 'f c e c d a'); |
| 82 INSERT INTO tt VALUES('f a e a a b', 'e d c f d d'); |
| 83 INSERT INTO tt VALUES('b c a a a b', 'f f c c b c'); |
| 84 INSERT INTO tt VALUES('f d c a c e', 'd g d e g d'); |
| 85 INSERT INTO tt VALUES('g d e f a g x', 'f f d a a b'); |
| 86 INSERT INTO tt VALUES('g c f b c g', 'a g f d c b'); |
| 87 INSERT INTO tt VALUES('c e c f g b', 'f e d b g a'); |
| 88 INSERT INTO tt VALUES('g d e f d e', 'a c d b a g'); |
| 89 INSERT INTO tt VALUES('e f a c c b', 'b f e a f d y'); |
| 90 INSERT INTO tt VALUES('c c a a c f', 'd g a e b g'); |
| 91 } |
| 92 |
| 93 set res_col { |
| 94 a a 6 11 a b 7 9 |
| 95 b a 6 7 b b 7 7 |
| 96 c a 6 12 c b 5 8 |
| 97 d a 4 6 d b 9 13 |
| 98 e a 6 7 e b 6 6 |
| 99 f a 9 10 f b 7 10 |
| 100 g a 5 7 g b 5 7 |
| 101 x a 1 1 y b 1 1 |
| 102 } |
| 103 set res_row { |
| 104 a 10 20 b 9 14 c 9 20 d 9 19 |
| 105 e 8 13 f 10 20 g 7 14 x 1 1 |
| 106 y 1 1 |
| 107 } |
| 108 |
| 109 foreach {tn tbl resname} { |
| 110 1 "fts5vocab(tt, 'col')" res_col |
| 111 2 "fts5vocab(tt, 'row')" res_row |
| 112 3 "fts5vocab(tt, \"row\")" res_row |
| 113 4 "fts5vocab(tt, [row])" res_row |
| 114 5 "fts5vocab(tt, `row`)" res_row |
| 115 |
| 116 6 "fts5vocab('tt', 'row')" res_row |
| 117 7 "fts5vocab(\"tt\", \"row\")" res_row |
| 118 8 "fts5vocab([tt], [row])" res_row |
| 119 9 "fts5vocab(`tt`, `row`)" res_row |
| 120 } { |
| 121 do_execsql_test 2.$tn " |
| 122 DROP TABLE IF EXISTS tv; |
| 123 CREATE VIRTUAL TABLE tv USING $tbl; |
| 124 SELECT * FROM tv; |
| 125 " [set $resname] |
| 126 } |
| 127 |
| 128 #------------------------------------------------------------------------- |
| 129 # Test errors in the CREATE VIRTUAL TABLE statement. |
| 130 # |
| 131 foreach {tn sql} { |
| 132 1 { CREATE VIRTUAL TABLE aa USING fts5vocab() } |
| 133 2 { CREATE VIRTUAL TABLE aa USING fts5vocab(x) } |
| 134 3 { CREATE VIRTUAL TABLE aa USING fts5vocab(x,y,z) } |
| 135 4 { CREATE VIRTUAL TABLE temp.aa USING fts5vocab(x,y,z,y) } |
| 136 } { |
| 137 do_catchsql_test 3.$tn $sql {1 {wrong number of vtable arguments}} |
| 138 } |
| 139 |
| 140 do_catchsql_test 4.0 { |
| 141 CREATE VIRTUAL TABLE cc USING fts5vocab(tbl, unknown); |
| 142 } {1 {fts5vocab: unknown table type: 'unknown'}} |
| 143 |
| 144 do_catchsql_test 4.1 { |
| 145 ATTACH 'test.db' AS aux; |
| 146 CREATE VIRTUAL TABLE aux.cc USING fts5vocab(main, tbl, row); |
| 147 } {1 {wrong number of vtable arguments}} |
| 148 |
| 149 #------------------------------------------------------------------------- |
| 150 # Test fts5vocab tables created in the temp schema. |
| 151 # |
| 152 reset_db |
| 153 forcedelete test.db2 |
| 154 do_execsql_test 5.0 { |
| 155 ATTACH 'test.db2' AS aux; |
| 156 CREATE VIRTUAL TABLE t1 USING fts5(x); |
| 157 CREATE VIRTUAL TABLE temp.t1 USING fts5(x); |
| 158 CREATE VIRTUAL TABLE aux.t1 USING fts5(x); |
| 159 |
| 160 INSERT INTO main.t1 VALUES('a b c'); |
| 161 INSERT INTO main.t1 VALUES('d e f'); |
| 162 INSERT INTO main.t1 VALUES('a e c'); |
| 163 |
| 164 INSERT INTO temp.t1 VALUES('1 2 3'); |
| 165 INSERT INTO temp.t1 VALUES('4 5 6'); |
| 166 INSERT INTO temp.t1 VALUES('1 5 3'); |
| 167 |
| 168 INSERT INTO aux.t1 VALUES('x y z'); |
| 169 INSERT INTO aux.t1 VALUES('m n o'); |
| 170 INSERT INTO aux.t1 VALUES('x n z'); |
| 171 } |
| 172 |
| 173 breakpoint |
| 174 do_execsql_test 5.1 { |
| 175 CREATE VIRTUAL TABLE temp.vm USING fts5vocab(main, t1, row); |
| 176 CREATE VIRTUAL TABLE temp.vt1 USING fts5vocab(t1, row); |
| 177 CREATE VIRTUAL TABLE temp.vt2 USING fts5vocab(temp, t1, row); |
| 178 CREATE VIRTUAL TABLE temp.va USING fts5vocab(aux, t1, row); |
| 179 } |
| 180 |
| 181 do_execsql_test 5.2 { SELECT * FROM vm } { |
| 182 a 2 2 b 1 1 c 2 2 d 1 1 e 2 2 f 1 1 |
| 183 } |
| 184 do_execsql_test 5.3 { SELECT * FROM vt1 } { |
| 185 1 2 2 2 1 1 3 2 2 4 1 1 5 2 2 6 1 1 |
| 186 } |
| 187 do_execsql_test 5.4 { SELECT * FROM vt2 } { |
| 188 1 2 2 2 1 1 3 2 2 4 1 1 5 2 2 6 1 1 |
| 189 } |
| 190 do_execsql_test 5.5 { SELECT * FROM va } { |
| 191 m 1 1 n 2 2 o 1 1 x 2 2 y 1 1 z 2 2 |
| 192 } |
| 193 |
| 194 #------------------------------------------------------------------------- |
| 195 # |
| 196 do_execsql_test 6.0 { |
| 197 CREATE TABLE iii(iii); |
| 198 CREATE TABLE jjj(x); |
| 199 } |
| 200 |
| 201 do_catchsql_test 6.1 { |
| 202 CREATE VIRTUAL TABLE vocab1 USING fts5vocab(iii, row); |
| 203 SELECT * FROM vocab1; |
| 204 } {1 {no such fts5 table: main.iii}} |
| 205 |
| 206 do_catchsql_test 6.2 { |
| 207 CREATE VIRTUAL TABLE vocab2 USING fts5vocab(jjj, row); |
| 208 SELECT * FROM vocab2; |
| 209 } {1 {no such fts5 table: main.jjj}} |
| 210 |
| 211 do_catchsql_test 6.2 { |
| 212 CREATE VIRTUAL TABLE vocab3 USING fts5vocab(lll, row); |
| 213 SELECT * FROM vocab3; |
| 214 } {1 {no such fts5 table: main.lll}} |
| 215 |
| 216 #------------------------------------------------------------------------- |
| 217 # Test single term queries on fts5vocab tables (i.e. those with term=? |
| 218 # constraints in the WHERE clause). |
| 219 # |
| 220 do_execsql_test 7.0 { |
| 221 CREATE VIRTUAL TABLE tx USING fts5(one, two); |
| 222 INSERT INTO tx VALUES('g a ggg g a b eee', 'cc d aa ff g ee'); |
| 223 INSERT INTO tx VALUES('dd fff i a i jjj', 'f fff hh jj e f'); |
| 224 INSERT INTO tx VALUES('ggg a f f fff dd aa', 'd ggg f f j gg ddd'); |
| 225 INSERT INTO tx VALUES('e bb h jjj ii gg', 'e aa e f c fff'); |
| 226 INSERT INTO tx VALUES('j ff aa a h', 'h a j bbb bb'); |
| 227 INSERT INTO tx VALUES('cc i ff c d f', 'dd ii fff f c cc d'); |
| 228 INSERT INTO tx VALUES('jjj g i bb cc eee', 'hhh iii aaa b bbb aaa'); |
| 229 INSERT INTO tx VALUES('hhh hhh hhh bb fff f', 'fff gg aa ii h a'); |
| 230 INSERT INTO tx VALUES('b c cc aaa iii ggg f', 'iii ff ee a ff c cc'); |
| 231 INSERT INTO tx VALUES('hhh b hhh aaa j i i', 'dd ee ee aa bbb iii'); |
| 232 INSERT INTO tx VALUES('hh dd h b g ff i', 'ccc bb cc ccc f a d'); |
| 233 INSERT INTO tx VALUES('g d b ggg jj', 'fff jj ff jj g gg ee'); |
| 234 INSERT INTO tx VALUES('g ee ggg ggg cc bb eee', 'aa j jjj bbb dd eee ff'); |
| 235 INSERT INTO tx VALUES('c jjj hh ddd dd h', 'e aaa h jjj gg'); |
| 236 |
| 237 CREATE VIRTUAL TABLE txr USING fts5vocab(tx, row); |
| 238 CREATE VIRTUAL TABLE txc USING fts5vocab(tx, col); |
| 239 } |
| 240 |
| 241 proc cont {L elem} { |
| 242 set n 0 |
| 243 foreach e $L { if {$elem==$e} {incr n} } |
| 244 set n |
| 245 } |
| 246 db func cont cont |
| 247 |
| 248 foreach {term} { |
| 249 a aa aaa |
| 250 b bb bbb |
| 251 c cc ccc |
| 252 d dd ddd |
| 253 e ee eee |
| 254 f ff fff |
| 255 g gg ggg |
| 256 h hh hhh |
| 257 i ii iii |
| 258 j jj jjj |
| 259 } { |
| 260 set resr [db eval { |
| 261 SELECT $term, |
| 262 sum(cont(one || ' ' || two, $term) > 0), |
| 263 sum(cont(one || ' ' || two, $term)) |
| 264 FROM tx |
| 265 }] |
| 266 if {[lindex $resr 1]==0} {set resr [list]} |
| 267 |
| 268 set r1 [db eval { |
| 269 SELECT $term, 'one', sum(cont(one, $term)>0), sum(cont(one, $term)) FROM tx |
| 270 }] |
| 271 if {[lindex $r1 2]==0} {set r1 [list]} |
| 272 |
| 273 set r2 [db eval { |
| 274 SELECT $term, 'two', sum(cont(two, $term)>0), sum(cont(two, $term)) FROM tx |
| 275 }] |
| 276 if {[lindex $r2 2]==0} {set r2 [list]} |
| 277 |
| 278 set resc [concat $r1 $r2] |
| 279 do_execsql_test 7.$term.1 {SELECT * FROM txc WHERE term=$term} $resc |
| 280 do_execsql_test 7.$term.2 {SELECT * FROM txr WHERE term=$term} $resr |
| 281 } |
| 282 |
| 283 do_execsql_test 7.1 { |
| 284 CREATE TABLE txr_c AS SELECT * FROM txr; |
| 285 CREATE TABLE txc_c AS SELECT * FROM txc; |
| 286 } |
| 287 |
| 288 # Test range queries on the fts5vocab tables created above. |
| 289 # |
| 290 foreach {tn a b} { |
| 291 1 a jjj |
| 292 2 bb j |
| 293 3 ccc ddd |
| 294 4 dd xyz |
| 295 5 xzy dd |
| 296 6 h hh |
| 297 } { |
| 298 do_execsql_test 7.2.$tn.1 { |
| 299 SELECT * FROM txr WHERE term>=$a |
| 300 } [db eval {SELECT * FROM txr_c WHERE term>=$a}] |
| 301 do_execsql_test 7.2.$tn.2 { |
| 302 SELECT * FROM txr WHERE term<=$b |
| 303 } [db eval {SELECT * FROM txr_c WHERE term <=$b}] |
| 304 do_execsql_test 7.2.$tn.3 { |
| 305 SELECT * FROM txr WHERE term>=$a AND term<=$b |
| 306 } [db eval {SELECT * FROM txr_c WHERE term>=$a AND term <=$b}] |
| 307 |
| 308 do_execsql_test 7.2.$tn.4 { |
| 309 SELECT * FROM txc WHERE term>=$a |
| 310 } [db eval {SELECT * FROM txc_c WHERE term>=$a}] |
| 311 do_execsql_test 7.2.$tn.5 { |
| 312 SELECT * FROM txc WHERE term<=$b |
| 313 } [db eval {SELECT * FROM txc_c WHERE term <=$b}] |
| 314 do_execsql_test 7.2.$tn.6 { |
| 315 SELECT * FROM txc WHERE term>=$a AND term<=$b |
| 316 } [db eval {SELECT * FROM txc_c WHERE term>=$a AND term <=$b}] |
| 317 |
| 318 do_execsql_test 7.2.$tn.7 { |
| 319 SELECT * FROM txr WHERE term>$a |
| 320 } [db eval {SELECT * FROM txr_c WHERE term>$a}] |
| 321 do_execsql_test 7.2.$tn.8 { |
| 322 SELECT * FROM txr WHERE term<$b |
| 323 } [db eval {SELECT * FROM txr_c WHERE term<$b}] |
| 324 do_execsql_test 7.2.$tn.9 { |
| 325 SELECT * FROM txr WHERE term>$a AND term<$b |
| 326 } [db eval {SELECT * FROM txr_c WHERE term>$a AND term <$b}] |
| 327 |
| 328 do_execsql_test 7.2.$tn.10 { |
| 329 SELECT * FROM txc WHERE term>$a |
| 330 } [db eval {SELECT * FROM txc_c WHERE term>$a}] |
| 331 do_execsql_test 7.2.$tn.11 { |
| 332 SELECT * FROM txc WHERE term<$b |
| 333 } [db eval {SELECT * FROM txc_c WHERE term<$b}] |
| 334 do_execsql_test 7.2.$tn.12 { |
| 335 SELECT * FROM txc WHERE term>$a AND term<$b |
| 336 } [db eval {SELECT * FROM txc_c WHERE term>$a AND term <$b}] |
| 337 } |
| 338 |
| 339 do_execsql_test 7.3.1 { |
| 340 SELECT count(*) FROM txr, txr_c WHERE txr.term = txr_c.term; |
| 341 } {30} |
| 342 |
| 343 do_execsql_test 7.3.2 { |
| 344 SELECT count(*) FROM txc, txc_c |
| 345 WHERE txc.term = txc_c.term AND txc.col=txc_c.col; |
| 346 } {57} |
| 347 |
| 348 finish_test |
| 349 |
OLD | NEW |