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 {SEARCH 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 {SEARCH 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 {SEARCH 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 {SEARCH 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 {SEARCH 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 {SEARCH 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 {SEARCH 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 {SEARCH 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 {SEARCH 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 {SEARCH 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 {SEARCH 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 {SEARCH 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 555