18e93b10aSdrh# 2011 January 04 28e93b10aSdrh# 38e93b10aSdrh# The author disclaims copyright to this source code. In place of 48e93b10aSdrh# a legal notice, here is a blessing: 58e93b10aSdrh# 68e93b10aSdrh# May you do good and not evil. 78e93b10aSdrh# May you find forgiveness for yourself and forgive others. 88e93b10aSdrh# May you share freely, never taking more than you give. 98e93b10aSdrh# 108e93b10aSdrh#*********************************************************************** 118e93b10aSdrh# 128e93b10aSdrh# This file implements regression tests for SQLite library. This file 138e93b10aSdrh# implements tests for ANALYZE to verify that multiple rows containing 148e93b10aSdrh# a NULL value count as distinct rows for the purposes of analyze 158e93b10aSdrh# statistics. 168e93b10aSdrh# 174856698fSdrh# Also include test cases for collating sequences on indices. 184856698fSdrh# 198e93b10aSdrh 208e93b10aSdrhset testdir [file dirname $argv0] 218e93b10aSdrhsource $testdir/tester.tcl 228e93b10aSdrh 23*37f3ac8fSdan# If SQLITE_OMIT_ALTERTABLE is defined, omit this file. 24*37f3ac8fSdanifcapable !altertable { 25*37f3ac8fSdan finish_test 26*37f3ac8fSdan return 27*37f3ac8fSdan} 28*37f3ac8fSdan 298e93b10aSdrhdo_test analyze4-1.0 { 308e93b10aSdrh db eval { 318e93b10aSdrh CREATE TABLE t1(a,b); 328e93b10aSdrh CREATE INDEX t1a ON t1(a); 338e93b10aSdrh CREATE INDEX t1b ON t1(b); 348e93b10aSdrh INSERT INTO t1 VALUES(1,NULL); 358e93b10aSdrh INSERT INTO t1 SELECT a+1, b FROM t1; 368e93b10aSdrh INSERT INTO t1 SELECT a+2, b FROM t1; 378e93b10aSdrh INSERT INTO t1 SELECT a+4, b FROM t1; 388e93b10aSdrh INSERT INTO t1 SELECT a+8, b FROM t1; 398e93b10aSdrh INSERT INTO t1 SELECT a+16, b FROM t1; 408e93b10aSdrh INSERT INTO t1 SELECT a+32, b FROM t1; 418e93b10aSdrh INSERT INTO t1 SELECT a+64, b FROM t1; 428e93b10aSdrh ANALYZE; 438e93b10aSdrh } 448e93b10aSdrh 458e93b10aSdrh # Should choose the t1a index since it is more specific than t1b. 468e93b10aSdrh db eval {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=5 AND b IS NULL} 478210233cSdrh} {/*SEARCH t1 USING INDEX t1a (a=?)*/} 488e93b10aSdrh 498e93b10aSdrh# Verify that the t1b index shows that it does not narrow down the 508e93b10aSdrh# search any at all. 518e93b10aSdrh# 528e93b10aSdrhdo_test analyze4-1.1 { 538e93b10aSdrh db eval { 548e93b10aSdrh SELECT idx, stat FROM sqlite_stat1 WHERE tbl='t1' ORDER BY idx; 558e93b10aSdrh } 568e93b10aSdrh} {t1a {128 1} t1b {128 128}} 578e93b10aSdrh 588e93b10aSdrh# Change half of the b values from NULL to a constant. Verify 598e93b10aSdrh# that the number of rows selected in stat1 is half the total 608e93b10aSdrh# number of rows. 618e93b10aSdrh# 628e93b10aSdrhdo_test analyze4-1.2 { 638e93b10aSdrh db eval { 648e93b10aSdrh UPDATE t1 SET b='x' WHERE a%2; 658e93b10aSdrh ANALYZE; 668e93b10aSdrh SELECT idx, stat FROM sqlite_stat1 WHERE tbl='t1' ORDER BY idx; 678e93b10aSdrh } 688e93b10aSdrh} {t1a {128 1} t1b {128 64}} 698e93b10aSdrh 708e93b10aSdrh# Change the t1.b values all back to NULL. Add columns t1.c and t1.d. 718e93b10aSdrh# Create a multi-column indices using t1.b and verify that ANALYZE 728e93b10aSdrh# processes them correctly. 738e93b10aSdrh# 748e93b10aSdrhdo_test analyze4-1.3 { 758e93b10aSdrh db eval { 768e93b10aSdrh UPDATE t1 SET b=NULL; 778e93b10aSdrh ALTER TABLE t1 ADD COLUMN c; 788e93b10aSdrh ALTER TABLE t1 ADD COLUMN d; 798e93b10aSdrh UPDATE t1 SET c=a/4, d=a/2; 808e93b10aSdrh CREATE INDEX t1bcd ON t1(b,c,d); 818e93b10aSdrh CREATE INDEX t1cdb ON t1(c,d,b); 828e93b10aSdrh CREATE INDEX t1cbd ON t1(c,b,d); 838e93b10aSdrh ANALYZE; 848e93b10aSdrh SELECT idx, stat FROM sqlite_stat1 WHERE tbl='t1' ORDER BY idx; 858e93b10aSdrh } 868e93b10aSdrh} {t1a {128 1} t1b {128 128} t1bcd {128 128 4 2} t1cbd {128 4 4 2} t1cdb {128 4 2 2}} 878e93b10aSdrh 884856698fSdrh# Verify that collating sequences are taken into account when computing 894856698fSdrh# ANALYZE statistics. 904856698fSdrh# 914856698fSdrhdo_test analyze4-2.0 { 924856698fSdrh db eval { 934856698fSdrh CREATE TABLE t2( 944856698fSdrh x INTEGER PRIMARY KEY, 954856698fSdrh a TEXT COLLATE nocase, 964856698fSdrh b TEXT COLLATE rtrim, 974856698fSdrh c TEXT COLLATE binary 984856698fSdrh ); 994856698fSdrh CREATE INDEX t2a ON t2(a); 1004856698fSdrh CREATE INDEX t2b ON t2(b); 1014856698fSdrh CREATE INDEX t2c ON t2(c); 1024856698fSdrh CREATE INDEX t2c2 ON t2(c COLLATE nocase); 1034856698fSdrh CREATE INDEX t2c3 ON t2(c COLLATE rtrim); 1044856698fSdrh INSERT INTO t2 VALUES(1, 'abc', 'abc', 'abc'); 1054856698fSdrh INSERT INTO t2 VALUES(2, 'abC', 'abC', 'abC'); 1064856698fSdrh INSERT INTO t2 VALUES(3, 'abc ', 'abc ', 'abc '); 1074856698fSdrh INSERT INTO t2 VALUES(4, 'abC ', 'abC ', 'abC '); 1084856698fSdrh INSERT INTO t2 VALUES(5, 'aBc', 'aBc', 'aBc'); 1094856698fSdrh INSERT INTO t2 VALUES(6, 'aBC', 'aBC', 'aBC'); 1104856698fSdrh INSERT INTO t2 VALUES(7, 'aBc ', 'aBc ', 'aBc '); 1114856698fSdrh INSERT INTO t2 VALUES(8, 'aBC ', 'aBC ', 'aBC '); 1124856698fSdrh ANALYZE; 1134856698fSdrh SELECT idx, stat FROM sqlite_stat1 WHERE tbl='t2' ORDER BY idx; 1144856698fSdrh } 1154856698fSdrh} {t2a {8 4} t2b {8 2} t2c {8 1} t2c2 {8 4} t2c3 {8 2}} 1164856698fSdrh 1178e93b10aSdrhfinish_test 118