# 2011 January 19 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # # This file implements tests for SQLite library. The focus of the tests # in this file is the use of the sqlite_stat2 histogram data on tables # with many repeated values and only a few distinct values. # set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !stat2 { finish_test return } set testprefix analyze5 proc eqp {sql {db db}} { uplevel execsql [list "EXPLAIN QUERY PLAN $sql"] $db } do_test analyze5-1.0 { execsql { CREATE TABLE t1(x INTEGER PRIMARY KEY, y, z) } for {set i 0} {$i < 1000} {incr i} { set j [expr {$i>=25 && $i<=50}] set k [expr {($i>=400) + ($i>=700) + ($i>=875)}] execsql { INSERT INTO t1 VALUES($i,$j,$k) } } execsql { CREATE INDEX t1y ON t1(y); CREATE INDEX t1z ON t1(z); ANALYZE; SELECT * FROM sqlite_stat2 ORDER BY 1, 2, 3; } } [list t1 t1y 0 0 \ t1 t1y 1 0 \ t1 t1y 2 0 \ t1 t1y 3 0 \ t1 t1y 4 0 \ t1 t1y 5 0 \ t1 t1y 6 0 \ t1 t1y 7 0 \ t1 t1y 8 0 \ t1 t1y 9 0 \ t1 t1z 0 0 \ t1 t1z 1 0 \ t1 t1z 2 0 \ t1 t1z 3 0 \ t1 t1z 4 1 \ t1 t1z 5 1 \ t1 t1z 6 1 \ t1 t1z 7 2 \ t1 t1z 8 2 \ t1 t1z 9 3] # Verify that range queries generate the correct row count estimates # foreach {testid where rows} { 1 {z>=0 AND z<=0} 400 2 {z>=1 AND z<=1} 300 3 {z>=2 AND z<=2} 200 4 {z>=3 AND z<=3} 100 5 {z>=4 AND z<=4} 50 6 {z>=-1 AND z<=-1} 50 7 {z>1 AND z<3} 200 8 {z>0 AND z<100} 600 9 {z>=1 AND z<100} 600 10 {z>1 AND z<100} 300 11 {z>=2 AND z<100} 300 12 {z>2 AND z<100} 100 13 {z>=3 AND z<100} 100 14 {z>3 AND z<100} 50 15 {z>=4 AND z<100} 50 16 {z>=-100 AND z<=-1} 50 17 {z>=-100 AND z<=0} 400 18 {z>=-100 AND z<0} 50 19 {z>=-100 AND z<=1} 700 20 {z>=-100 AND z<2} 700 21 {z>=-100 AND z<=2} 900 22 {z>=-100 AND z<3} 900 31 {z>=0.0 AND z<=0.0} 400 32 {z>=1.0 AND z<=1.0} 300 33 {z>=2.0 AND z<=2.0} 200 34 {z>=3.0 AND z<=3.0} 100 35 {z>=4.0 AND z<=4.0} 50 36 {z>=-1.0 AND z<=-1.0} 50 37 {z>1.5 AND z<3.0} 200 38 {z>0.5 AND z<100} 600 39 {z>=1.0 AND z<100} 600 40 {z>1.5 AND z<100} 300 41 {z>=2.0 AND z<100} 300 42 {z>2.1 AND z<100} 100 43 {z>=3.0 AND z<100} 100 44 {z>3.2 AND z<100} 50 45 {z>=4.0 AND z<100} 50 46 {z>=-100 AND z<=-1.0} 50 47 {z>=-100 AND z<=0.0} 400 48 {z>=-100 AND z<0.0} 50 49 {z>=-100 AND z<=1.0} 700 50 {z>=-100 AND z<2.0} 700 51 {z>=-100 AND z<=2.0} 900 52 {z>=-100 AND z<3.0} 900 } { do_test analyze5-1.$testid { eqp "SELECT * FROM t1 WHERE $where" } [format {0 0 0 {SEARCH TABLE t1 USING INDEX t1z (z>? AND z=0 AND z<=0} 400 2 {z>=1 AND z<=1} 300 3 {z>=2 AND z<=2} 200 4 {z>=3 AND z<=3} 100 5 {z>=4 AND z<=4} 50 6 {z>=-1 AND z<=-1} 50 7 {z>1 AND z<3} 200 8 {z>0 AND z<100} 600 9 {z>=1 AND z<100} 600 10 {z>1 AND z<100} 300 11 {z>=2 AND z<100} 300 12 {z>2 AND z<100} 100 13 {z>=3 AND z<100} 100 14 {z>3 AND z<100} 50 15 {z>=4 AND z<100} 50 16 {z>=-100 AND z<=-1} 50 17 {z>=-100 AND z<=0} 400 18 {z>=-100 AND z<0} 50 19 {z>=-100 AND z<=1} 700 20 {z>=-100 AND z<2} 700 21 {z>=-100 AND z<=2} 900 22 {z>=-100 AND z<3} 900 31 {z>=0.0 AND z<=0.0} 400 32 {z>=1.0 AND z<=1.0} 300 33 {z>=2.0 AND z<=2.0} 200 34 {z>=3.0 AND z<=3.0} 100 35 {z>=4.0 AND z<=4.0} 50 36 {z>=-1.0 AND z<=-1.0} 50 37 {z>1.5 AND z<3.0} 200 38 {z>0.5 AND z<100} 600 39 {z>=1.0 AND z<100} 600 40 {z>1.5 AND z<100} 300 41 {z>=2.0 AND z<100} 300 42 {z>2.1 AND z<100} 100 43 {z>=3.0 AND z<100} 100 44 {z>3.2 AND z<100} 50 45 {z>=4.0 AND z<100} 50 46 {z>=-100 AND z<=-1.0} 50 47 {z>=-100 AND z<=0.0} 400 48 {z>=-100 AND z<0.0} 50 49 {z>=-100 AND z<=1.0} 700 50 {z>=-100 AND z<2.0} 700 51 {z>=-100 AND z<=2.0} 900 52 {z>=-100 AND z<3.0} 900 } { do_test analyze5-2.$testid { eqp "SELECT * FROM t1 WHERE $where" } [format {0 0 0 {SEARCH TABLE t1 USING INDEX t1z (z>? AND z='alpha' AND y<='alpha'} 400 2 {y>='bravo' AND y<='bravo'} 300 3 {y>='charlie' AND y<='charlie'} 200 4 {y>='delta' AND y<='delta'} 100 5 {y>='echo' AND y<='echo'} 50 6 {y>='' AND y<=''} 50 7 {y>'bravo' AND y<'delta'} 200 8 {y>'alpha' AND y<'zzz'} 600 9 {y>='bravo' AND y<'zzz'} 600 10 {y>'bravo' AND y<'zzz'} 300 11 {y>='charlie' AND y<'zzz'} 300 12 {y>'charlie' AND y<'zzz'} 100 13 {y>='delta' AND y<'zzz'} 100 14 {y>'delta' AND y<'zzz'} 50 15 {y>='echo' AND y<'zzz'} 50 16 {y>=0 AND y<=''} 50 17 {y>=0 AND y<='alpha'} 400 18 {y>=0 AND y<'alpha'} 50 19 {y>=0 AND y<='bravo'} 700 20 {y>=0 AND y<'charlie'} 700 21 {y>=0 AND y<='charlie'} 900 22 {y>=0 AND y<'delta'} 900 23 {y>'alpha' AND y='bravo' AND y'bravo' AND y='charlie' AND y'charlie' AND y='delta' AND y'delta' AND y='echo' AND y? AND y