OLD | NEW |
| (Empty) |
1 # 2009 August 06 | |
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 implements regression tests for SQLite library. This file | |
13 # implements tests for the extra functionality provided by the ANALYZE | |
14 # command when the library is compiled with SQLITE_ENABLE_STAT2 defined. | |
15 # | |
16 | |
17 set testdir [file dirname $argv0] | |
18 source $testdir/tester.tcl | |
19 | |
20 ifcapable !stat2 { | |
21 finish_test | |
22 return | |
23 } | |
24 | |
25 set testprefix analyze2 | |
26 | |
27 # Do not use a codec for tests in this file, as the database file is | |
28 # manipulated directly using tcl scripts (using the [hexio_write] command). | |
29 # | |
30 do_not_use_codec | |
31 | |
32 #-------------------------------------------------------------------- | |
33 # Test organization: | |
34 # | |
35 # analyze2-1.*: Tests to verify that ANALYZE creates and populates the | |
36 # sqlite_stat2 table as expected. | |
37 # | |
38 # analyze2-2.*: Test that when a table has two indexes on it and either | |
39 # index may be used for the scan, the index suggested by | |
40 # the contents of sqlite_stat2 table is prefered. | |
41 # | |
42 # analyze2-3.*: Similar to the previous block of tests, but using tables | |
43 # that contain a mixture of NULL, numeric, text and blob | |
44 # values. | |
45 # | |
46 # analyze2-4.*: Check that when an indexed column uses a collation other | |
47 # than BINARY, the collation is taken into account when | |
48 # using the contents of sqlite_stat2 to estimate the cost | |
49 # of a range scan. | |
50 # | |
51 # analyze2-5.*: Check that collation sequences are used as described above | |
52 # even when the only available version of the collation | |
53 # function require UTF-16 encoded arguments. | |
54 # | |
55 # analyze2-6.*: Check that the library behaves correctly when one of the | |
56 # sqlite_stat2 or sqlite_stat1 tables are missing. | |
57 # | |
58 # analyze2-7.*: Check that in a shared-schema situation, nothing goes | |
59 # wrong if sqlite_stat2 data is read by one connection, | |
60 # and freed by another. | |
61 # | |
62 | |
63 proc eqp {sql {db db}} { | |
64 uplevel execsql [list "EXPLAIN QUERY PLAN $sql"] $db | |
65 } | |
66 | |
67 do_test analyze2-1.1 { | |
68 execsql { CREATE TABLE t1(x PRIMARY KEY) } | |
69 for {set i 0} {$i < 1000} {incr i} { | |
70 execsql { INSERT INTO t1 VALUES($i) } | |
71 } | |
72 execsql { | |
73 ANALYZE; | |
74 SELECT * FROM sqlite_stat2; | |
75 } | |
76 } [list t1 sqlite_autoindex_t1_1 0 50 \ | |
77 t1 sqlite_autoindex_t1_1 1 149 \ | |
78 t1 sqlite_autoindex_t1_1 2 249 \ | |
79 t1 sqlite_autoindex_t1_1 3 349 \ | |
80 t1 sqlite_autoindex_t1_1 4 449 \ | |
81 t1 sqlite_autoindex_t1_1 5 549 \ | |
82 t1 sqlite_autoindex_t1_1 6 649 \ | |
83 t1 sqlite_autoindex_t1_1 7 749 \ | |
84 t1 sqlite_autoindex_t1_1 8 849 \ | |
85 t1 sqlite_autoindex_t1_1 9 949 \ | |
86 ] | |
87 | |
88 do_test analyze2-1.2 { | |
89 execsql { | |
90 DELETE FROM t1 WHERe x>9; | |
91 ANALYZE; | |
92 SELECT tbl, idx, group_concat(sample, ' ') FROM sqlite_stat2; | |
93 } | |
94 } {t1 sqlite_autoindex_t1_1 {0 1 2 3 4 5 6 7 8 9}} | |
95 do_test analyze2-1.3 { | |
96 execsql { | |
97 DELETE FROM t1 WHERE x>8; | |
98 ANALYZE; | |
99 SELECT * FROM sqlite_stat2; | |
100 } | |
101 } {} | |
102 do_test analyze2-1.4 { | |
103 execsql { | |
104 DELETE FROM t1; | |
105 ANALYZE; | |
106 SELECT * FROM sqlite_stat2; | |
107 } | |
108 } {} | |
109 | |
110 do_test analyze2-2.1 { | |
111 execsql { | |
112 BEGIN; | |
113 DROP TABLE t1; | |
114 CREATE TABLE t1(x, y); | |
115 CREATE INDEX t1_x ON t1(x); | |
116 CREATE INDEX t1_y ON t1(y); | |
117 } | |
118 for {set i 0} {$i < 1000} {incr i} { | |
119 execsql { INSERT INTO t1 VALUES($i, $i) } | |
120 } | |
121 execsql COMMIT | |
122 execsql ANALYZE | |
123 } {} | |
124 do_eqp_test 2.2 { | |
125 SELECT * FROM t1 WHERE x>500 AND y>700 | |
126 } { | |
127 0 0 0 {SEARCH TABLE t1 USING INDEX t1_y (y>?) (~100 rows)} | |
128 } | |
129 do_eqp_test 2.3 { | |
130 SELECT * FROM t1 WHERE x>700 AND y>500 | |
131 } { | |
132 0 0 0 {SEARCH TABLE t1 USING INDEX t1_x (x>?) (~100 rows)} | |
133 } | |
134 do_eqp_test 2.3 { | |
135 SELECT * FROM t1 WHERE y>700 AND x>500 | |
136 } { | |
137 0 0 0 {SEARCH TABLE t1 USING INDEX t1_y (y>?) (~100 rows)} | |
138 } | |
139 do_eqp_test 2.4 { | |
140 SELECT * FROM t1 WHERE y>500 AND x>700 | |
141 } { | |
142 0 0 0 {SEARCH TABLE t1 USING INDEX t1_x (x>?) (~100 rows)} | |
143 } | |
144 do_eqp_test 2.5 { | |
145 SELECT * FROM t1 WHERE x BETWEEN 100 AND 200 AND y BETWEEN 400 AND 700 | |
146 } { | |
147 0 0 0 {SEARCH TABLE t1 USING INDEX t1_x (x>? AND x<?) (~25 rows)} | |
148 } | |
149 do_eqp_test 2.6 { | |
150 SELECT * FROM t1 WHERE x BETWEEN 100 AND 500 AND y BETWEEN 400 AND 700 | |
151 } { | |
152 0 0 0 {SEARCH TABLE t1 USING INDEX t1_y (y>? AND y<?) (~75 rows)} | |
153 } | |
154 do_eqp_test 2.7 { | |
155 SELECT * FROM t1 WHERE x BETWEEN -400 AND -300 AND y BETWEEN 100 AND 300 | |
156 } { | |
157 0 0 0 {SEARCH TABLE t1 USING INDEX t1_x (x>? AND x<?) (~12 rows)} | |
158 } | |
159 do_eqp_test 2.8 { | |
160 SELECT * FROM t1 WHERE x BETWEEN 100 AND 300 AND y BETWEEN -400 AND -300 | |
161 } { | |
162 0 0 0 {SEARCH TABLE t1 USING INDEX t1_y (y>? AND y<?) (~12 rows)} | |
163 } | |
164 do_eqp_test 2.9 { | |
165 SELECT * FROM t1 WHERE x BETWEEN 500 AND 100 AND y BETWEEN 100 AND 300 | |
166 } { | |
167 0 0 0 {SEARCH TABLE t1 USING INDEX t1_x (x>? AND x<?) (~12 rows)} | |
168 } | |
169 do_eqp_test 2.10 { | |
170 SELECT * FROM t1 WHERE x BETWEEN 100 AND 300 AND y BETWEEN 500 AND 100 | |
171 } { | |
172 0 0 0 {SEARCH TABLE t1 USING INDEX t1_y (y>? AND y<?) (~12 rows)} | |
173 } | |
174 | |
175 do_test analyze2-3.1 { | |
176 set alphabet [list a b c d e f g h i j] | |
177 execsql BEGIN | |
178 for {set i 0} {$i < 1000} {incr i} { | |
179 set str [lindex $alphabet [expr ($i/100)%10]] | |
180 append str [lindex $alphabet [expr ($i/ 10)%10]] | |
181 append str [lindex $alphabet [expr ($i/ 1)%10]] | |
182 execsql { INSERT INTO t1 VALUES($str, $str) } | |
183 } | |
184 execsql COMMIT | |
185 execsql ANALYZE | |
186 execsql { | |
187 SELECT tbl,idx,group_concat(sample,' ') | |
188 FROM sqlite_stat2 | |
189 WHERE idx = 't1_x' | |
190 GROUP BY tbl,idx | |
191 } | |
192 } {t1 t1_x {100 299 499 699 899 ajj cjj ejj gjj ijj}} | |
193 do_test analyze2-3.2 { | |
194 execsql { | |
195 SELECT tbl,idx,group_concat(sample,' ') | |
196 FROM sqlite_stat2 | |
197 WHERE idx = 't1_y' | |
198 GROUP BY tbl,idx | |
199 } | |
200 } {t1 t1_y {100 299 499 699 899 ajj cjj ejj gjj ijj}} | |
201 | |
202 do_eqp_test 3.3 { | |
203 SELECT * FROM t1 WHERE x BETWEEN 100 AND 500 AND y BETWEEN 'a' AND 'b' | |
204 } { | |
205 0 0 0 {SEARCH TABLE t1 USING INDEX t1_y (y>? AND y<?) (~50 rows)} | |
206 } | |
207 do_eqp_test 3.4 { | |
208 SELECT * FROM t1 WHERE x BETWEEN 100 AND 400 AND y BETWEEN 'a' AND 'h' | |
209 } { | |
210 0 0 0 {SEARCH TABLE t1 USING INDEX t1_x (x>? AND x<?) (~100 rows)} | |
211 } | |
212 do_eqp_test 3.5 { | |
213 SELECT * FROM t1 WHERE x<'a' AND y>'h' | |
214 } { | |
215 0 0 0 {SEARCH TABLE t1 USING INDEX t1_y (y>?) (~66 rows)} | |
216 } | |
217 do_eqp_test 3.6 { | |
218 SELECT * FROM t1 WHERE x<444 AND y>'h' | |
219 } { | |
220 0 0 0 {SEARCH TABLE t1 USING INDEX t1_y (y>?) (~66 rows)} | |
221 } | |
222 do_eqp_test 3.7 { | |
223 SELECT * FROM t1 WHERE x<221 AND y>'g' | |
224 } { | |
225 0 0 0 {SEARCH TABLE t1 USING INDEX t1_x (x<?) (~66 rows)} | |
226 } | |
227 | |
228 do_test analyze2-4.1 { | |
229 execsql { CREATE TABLE t3(a COLLATE nocase, b) } | |
230 execsql { CREATE INDEX t3a ON t3(a) } | |
231 execsql { CREATE INDEX t3b ON t3(b) } | |
232 set alphabet [list A b C d E f G h I j] | |
233 execsql BEGIN | |
234 for {set i 0} {$i < 1000} {incr i} { | |
235 set str [lindex $alphabet [expr ($i/100)%10]] | |
236 append str [lindex $alphabet [expr ($i/ 10)%10]] | |
237 append str [lindex $alphabet [expr ($i/ 1)%10]] | |
238 execsql { INSERT INTO t3 VALUES($str, $str) } | |
239 } | |
240 execsql COMMIT | |
241 execsql ANALYZE | |
242 } {} | |
243 do_test analyze2-4.2 { | |
244 execsql { | |
245 PRAGMA automatic_index=OFF; | |
246 SELECT tbl,idx,group_concat(sample,' ') | |
247 FROM sqlite_stat2 | |
248 WHERE idx = 't3a' | |
249 GROUP BY tbl,idx; | |
250 PRAGMA automatic_index=ON; | |
251 } | |
252 } {t3 t3a {AfA bEj CEj dEj EEj fEj GEj hEj IEj jEj}} | |
253 do_test analyze2-4.3 { | |
254 execsql { | |
255 SELECT tbl,idx,group_concat(sample,' ') | |
256 FROM sqlite_stat2 | |
257 WHERE idx = 't3b' | |
258 GROUP BY tbl,idx | |
259 } | |
260 } {t3 t3b {AbA CIj EIj GIj IIj bIj dIj fIj hIj jIj}} | |
261 | |
262 do_eqp_test 4.4 { | |
263 SELECT * FROM t3 WHERE a > 'A' AND a < 'C' AND b > 'A' AND b < 'C' | |
264 } { | |
265 0 0 0 {SEARCH TABLE t3 USING INDEX t3b (b>? AND b<?) (~11 rows)} | |
266 } | |
267 do_eqp_test 4.5 { | |
268 SELECT * FROM t3 WHERE a > 'A' AND a < 'c' AND b > 'A' AND b < 'c' | |
269 } { | |
270 0 0 0 {SEARCH TABLE t3 USING INDEX t3a (a>? AND a<?) (~22 rows)} | |
271 } | |
272 | |
273 ifcapable utf16 { | |
274 proc test_collate {enc lhs rhs} { | |
275 # puts $enc | |
276 return [string compare $lhs $rhs] | |
277 } | |
278 do_test analyze2-5.1 { | |
279 add_test_collate db 0 0 1 | |
280 execsql { CREATE TABLE t4(x COLLATE test_collate) } | |
281 execsql { CREATE INDEX t4x ON t4(x) } | |
282 set alphabet [list a b c d e f g h i j] | |
283 execsql BEGIN | |
284 for {set i 0} {$i < 1000} {incr i} { | |
285 set str [lindex $alphabet [expr ($i/100)%10]] | |
286 append str [lindex $alphabet [expr ($i/ 10)%10]] | |
287 append str [lindex $alphabet [expr ($i/ 1)%10]] | |
288 execsql { INSERT INTO t4 VALUES($str) } | |
289 } | |
290 execsql COMMIT | |
291 execsql ANALYZE | |
292 } {} | |
293 do_test analyze2-5.2 { | |
294 execsql { | |
295 SELECT tbl,idx,group_concat(sample,' ') | |
296 FROM sqlite_stat2 | |
297 WHERE tbl = 't4' | |
298 GROUP BY tbl,idx | |
299 } | |
300 } {t4 t4x {afa bej cej dej eej fej gej hej iej jej}} | |
301 do_eqp_test 5.3 { | |
302 SELECT * FROM t4 WHERE x>'ccc' | |
303 } {0 0 0 {SEARCH TABLE t4 USING COVERING INDEX t4x (x>?) (~800 rows)}} | |
304 do_eqp_test 5.4 { | |
305 SELECT * FROM t4 AS t41, t4 AS t42 WHERE t41.x>'ccc' AND t42.x>'ggg' | |
306 } { | |
307 0 0 1 {SEARCH TABLE t4 AS t42 USING COVERING INDEX t4x (x>?) (~300 rows)} | |
308 0 1 0 {SEARCH TABLE t4 AS t41 USING COVERING INDEX t4x (x>?) (~800 rows)} | |
309 } | |
310 do_eqp_test 5.5 { | |
311 SELECT * FROM t4 AS t41, t4 AS t42 WHERE t41.x>'ddd' AND t42.x>'ccc' | |
312 } { | |
313 0 0 0 {SEARCH TABLE t4 AS t41 USING COVERING INDEX t4x (x>?) (~700 rows)} | |
314 0 1 1 {SEARCH TABLE t4 AS t42 USING COVERING INDEX t4x (x>?) (~800 rows)} | |
315 } | |
316 } | |
317 | |
318 #-------------------------------------------------------------------- | |
319 # These tests, analyze2-6.*, verify that the library behaves correctly | |
320 # when one of the sqlite_stat1 and sqlite_stat2 tables is missing. | |
321 # | |
322 # If the sqlite_stat1 table is not present, then the sqlite_stat2 | |
323 # table is not read. However, if it is the sqlite_stat2 table that | |
324 # is missing, the data in the sqlite_stat1 table is still used. | |
325 # | |
326 # Tests analyze2-6.1.* test the libary when the sqlite_stat2 table | |
327 # is missing. Tests analyze2-6.2.* test the library when sqlite_stat1 | |
328 # is not present. | |
329 # | |
330 do_test analyze2-6.0 { | |
331 execsql { | |
332 DROP TABLE IF EXISTS t4; | |
333 CREATE TABLE t5(a, b); CREATE INDEX t5i ON t5(a, b); | |
334 CREATE TABLE t6(a, b); CREATE INDEX t6i ON t6(a, b); | |
335 } | |
336 for {set ii 0} {$ii < 20} {incr ii} { | |
337 execsql { | |
338 INSERT INTO t5 VALUES($ii, $ii); | |
339 INSERT INTO t6 VALUES($ii/10, $ii/10); | |
340 } | |
341 } | |
342 execsql { | |
343 CREATE TABLE master AS | |
344 SELECT * FROM sqlite_master WHERE name LIKE 'sqlite_stat%' | |
345 } | |
346 } {} | |
347 | |
348 do_test analyze2-6.1.1 { | |
349 eqp {SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND | |
350 t5.a = 1 AND | |
351 t6.a = 1 AND t6.b = 1 | |
352 } | |
353 } {0 0 1 {SEARCH TABLE t6 USING COVERING INDEX t6i (a=? AND b=?) (~9 rows)} 0 1
0 {SEARCH TABLE t5 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}} | |
354 do_test analyze2-6.1.2 { | |
355 db cache flush | |
356 execsql ANALYZE | |
357 eqp {SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND | |
358 t5.a = 1 AND | |
359 t6.a = 1 AND t6.b = 1 | |
360 } | |
361 } {0 0 0 {SEARCH TABLE t5 USING COVERING INDEX t5i (a=?) (~1 rows)} 0 1 1 {SEARC
H TABLE t6 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}} | |
362 do_test analyze2-6.1.3 { | |
363 sqlite3 db test.db | |
364 eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND | |
365 t5.a = 1 AND | |
366 t6.a = 1 AND t6.b = 1 | |
367 } | |
368 } {0 0 0 {SEARCH TABLE t5 USING COVERING INDEX t5i (a=?) (~1 rows)} 0 1 1 {SEARC
H TABLE t6 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}} | |
369 do_test analyze2-6.1.4 { | |
370 execsql { | |
371 PRAGMA writable_schema = 1; | |
372 DELETE FROM sqlite_master WHERE tbl_name = 'sqlite_stat2'; | |
373 } | |
374 sqlite3 db test.db | |
375 eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND | |
376 t5.a = 1 AND | |
377 t6.a = 1 AND t6.b = 1 | |
378 } | |
379 } {0 0 0 {SEARCH TABLE t5 USING COVERING INDEX t5i (a=?) (~1 rows)} 0 1 1 {SEARC
H TABLE t6 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}} | |
380 do_test analyze2-6.1.5 { | |
381 execsql { | |
382 PRAGMA writable_schema = 1; | |
383 DELETE FROM sqlite_master WHERE tbl_name = 'sqlite_stat1'; | |
384 } | |
385 sqlite3 db test.db | |
386 eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND | |
387 t5.a = 1 AND | |
388 t6.a = 1 AND t6.b = 1 | |
389 } | |
390 } {0 0 1 {SEARCH TABLE t6 USING COVERING INDEX t6i (a=? AND b=?) (~9 rows)} 0 1
0 {SEARCH TABLE t5 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}} | |
391 do_test analyze2-6.1.6 { | |
392 execsql { | |
393 PRAGMA writable_schema = 1; | |
394 INSERT INTO sqlite_master SELECT * FROM master; | |
395 } | |
396 sqlite3 db test.db | |
397 eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND | |
398 t5.a = 1 AND | |
399 t6.a = 1 AND t6.b = 1 | |
400 } | |
401 } {0 0 0 {SEARCH TABLE t5 USING COVERING INDEX t5i (a=?) (~1 rows)} 0 1 1 {SEARC
H TABLE t6 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}} | |
402 | |
403 do_test analyze2-6.2.1 { | |
404 execsql { | |
405 DELETE FROM sqlite_stat1; | |
406 DELETE FROM sqlite_stat2; | |
407 } | |
408 sqlite3 db test.db | |
409 eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND | |
410 t5.a>1 AND t5.a<15 AND | |
411 t6.a>1 | |
412 } | |
413 } {0 0 0 {SEARCH TABLE t5 USING COVERING INDEX t5i (a>? AND a<?) (~60000 rows)}
0 1 1 {SEARCH TABLE t6 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}} | |
414 do_test analyze2-6.2.2 { | |
415 db cache flush | |
416 execsql ANALYZE | |
417 eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND | |
418 t5.a>1 AND t5.a<15 AND | |
419 t6.a>1 | |
420 } | |
421 } {0 0 1 {SEARCH TABLE t6 USING COVERING INDEX t6i (a>?) (~1 rows)} 0 1 0 {SEARC
H TABLE t5 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}} | |
422 do_test analyze2-6.2.3 { | |
423 sqlite3 db test.db | |
424 eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND | |
425 t5.a>1 AND t5.a<15 AND | |
426 t6.a>1 | |
427 } | |
428 } {0 0 1 {SEARCH TABLE t6 USING COVERING INDEX t6i (a>?) (~1 rows)} 0 1 0 {SEARC
H TABLE t5 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}} | |
429 do_test analyze2-6.2.4 { | |
430 execsql { | |
431 PRAGMA writable_schema = 1; | |
432 DELETE FROM sqlite_master WHERE tbl_name = 'sqlite_stat1'; | |
433 } | |
434 sqlite3 db test.db | |
435 eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND | |
436 t5.a>1 AND t5.a<15 AND | |
437 t6.a>1 | |
438 } | |
439 } {0 0 0 {SEARCH TABLE t5 USING COVERING INDEX t5i (a>? AND a<?) (~60000 rows)}
0 1 1 {SEARCH TABLE t6 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}} | |
440 do_test analyze2-6.2.5 { | |
441 execsql { | |
442 PRAGMA writable_schema = 1; | |
443 DELETE FROM sqlite_master WHERE tbl_name = 'sqlite_stat2'; | |
444 } | |
445 sqlite3 db test.db | |
446 eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND | |
447 t5.a>1 AND t5.a<15 AND | |
448 t6.a>1 | |
449 } | |
450 } {0 0 0 {SEARCH TABLE t5 USING COVERING INDEX t5i (a>? AND a<?) (~60000 rows)}
0 1 1 {SEARCH TABLE t6 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}} | |
451 do_test analyze2-6.2.6 { | |
452 execsql { | |
453 PRAGMA writable_schema = 1; | |
454 INSERT INTO sqlite_master SELECT * FROM master; | |
455 } | |
456 sqlite3 db test.db | |
457 execsql ANALYZE | |
458 eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND | |
459 t5.a>1 AND t5.a<15 AND | |
460 t6.a>1 | |
461 } | |
462 } {0 0 1 {SEARCH TABLE t6 USING COVERING INDEX t6i (a>?) (~1 rows)} 0 1 0 {SEARC
H TABLE t5 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}} | |
463 | |
464 #-------------------------------------------------------------------- | |
465 # These tests, analyze2-7.*, test that the sqlite_stat2 functionality | |
466 # works in shared-cache mode. Note that these tests reuse the database | |
467 # created for the analyze2-6.* tests. | |
468 # | |
469 ifcapable shared_cache { | |
470 db close | |
471 set ::enable_shared_cache [sqlite3_enable_shared_cache 1] | |
472 | |
473 proc incr_schema_cookie {zDb} { | |
474 foreach iOffset {24 40} { | |
475 set cookie [hexio_get_int [hexio_read $zDb $iOffset 4]] | |
476 incr cookie | |
477 hexio_write $zDb $iOffset [hexio_render_int32 $cookie] | |
478 } | |
479 } | |
480 | |
481 do_test analyze2-7.1 { | |
482 sqlite3 db1 test.db | |
483 sqlite3 db2 test.db | |
484 db1 cache size 0 | |
485 db2 cache size 0 | |
486 execsql { SELECT count(*) FROM t5 } db1 | |
487 } {20} | |
488 do_test analyze2-7.2 { | |
489 incr_schema_cookie test.db | |
490 execsql { SELECT count(*) FROM t5 } db2 | |
491 } {20} | |
492 do_test analyze2-7.3 { | |
493 incr_schema_cookie test.db | |
494 execsql { SELECT count(*) FROM t5 } db1 | |
495 } {20} | |
496 do_test analyze2-7.4 { | |
497 incr_schema_cookie test.db | |
498 execsql { SELECT count(*) FROM t5 } db2 | |
499 } {20} | |
500 | |
501 do_test analyze2-7.5 { | |
502 eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND | |
503 t5.a>1 AND t5.a<15 AND | |
504 t6.a>1 | |
505 } db1 | |
506 } {0 0 1 {SEARCH TABLE t6 USING COVERING INDEX t6i (a>?) (~1 rows)} 0 1 0 {SEA
RCH TABLE t5 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}} | |
507 do_test analyze2-7.6 { | |
508 incr_schema_cookie test.db | |
509 execsql { SELECT * FROM sqlite_master } db2 | |
510 eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND | |
511 t5.a>1 AND t5.a<15 AND | |
512 t6.a>1 | |
513 } db2 | |
514 } {0 0 1 {SEARCH TABLE t6 USING COVERING INDEX t6i (a>?) (~1 rows)} 0 1 0 {SEA
RCH TABLE t5 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}} | |
515 do_test analyze2-7.7 { | |
516 incr_schema_cookie test.db | |
517 execsql { SELECT * FROM sqlite_master } db1 | |
518 eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND | |
519 t5.a>1 AND t5.a<15 AND | |
520 t6.a>1 | |
521 } db1 | |
522 } {0 0 1 {SEARCH TABLE t6 USING COVERING INDEX t6i (a>?) (~1 rows)} 0 1 0 {SEA
RCH TABLE t5 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}} | |
523 | |
524 do_test analyze2-7.8 { | |
525 execsql { DELETE FROM sqlite_stat2 } db2 | |
526 execsql { SELECT * FROM sqlite_master } db1 | |
527 eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND | |
528 t5.a>1 AND t5.a<15 AND | |
529 t6.a>1 | |
530 } db1 | |
531 } {0 0 1 {SEARCH TABLE t6 USING COVERING INDEX t6i (a>?) (~1 rows)} 0 1 0 {SEA
RCH TABLE t5 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}} | |
532 do_test analyze2-7.9 { | |
533 execsql { SELECT * FROM sqlite_master } db2 | |
534 eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND | |
535 t5.a>1 AND t5.a<15 AND | |
536 t6.a>1 | |
537 } db2 | |
538 } {0 0 1 {SEARCH TABLE t6 USING COVERING INDEX t6i (a>?) (~1 rows)} 0 1 0 {SEA
RCH TABLE t5 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}} | |
539 | |
540 do_test analyze2-7.10 { | |
541 incr_schema_cookie test.db | |
542 execsql { SELECT * FROM sqlite_master } db1 | |
543 eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND | |
544 t5.a>1 AND t5.a<15 AND | |
545 t6.a>1 | |
546 } db1 | |
547 } {0 0 0 {SEARCH TABLE t5 USING COVERING INDEX t5i (a>? AND a<?) (~1 rows)} 0
1 1 {SEARCH TABLE t6 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}} | |
548 | |
549 db1 close | |
550 db2 close | |
551 sqlite3_enable_shared_cache $::enable_shared_cache | |
552 } | |
553 | |
554 finish_test | |
OLD | NEW |