Home | History | Annotate | Download | only in test
      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