123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364 |
- # 2005 July 22
- #
- # 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 regression tests for SQLite library.
- # This file implements tests for the ANALYZE command.
- #
- # $Id: analyze.test,v 1.9 2008/08/11 18:44:58 drh Exp $
- set testdir [file dirname $argv0]
- source $testdir/tester.tcl
- # There is nothing to test if ANALYZE is disable for this build.
- #
- ifcapable {!analyze} {
- finish_test
- return
- }
- # Basic sanity checks.
- #
- do_test analyze-1.1 {
- catchsql {
- ANALYZE no_such_table
- }
- } {1 {no such table: no_such_table}}
- do_test analyze-1.2 {
- execsql {
- SELECT count(*) FROM sqlite_master WHERE name='sqlite_stat1'
- }
- } {0}
- do_test analyze-1.3 {
- catchsql {
- ANALYZE no_such_db.no_such_table
- }
- } {1 {unknown database no_such_db}}
- do_test analyze-1.4 {
- execsql {
- SELECT count(*) FROM sqlite_master WHERE name='sqlite_stat1'
- }
- } {0}
- do_test analyze-1.5.1 {
- catchsql {
- ANALYZE
- }
- } {0 {}}
- do_test analyze-1.5.2 {
- catchsql {
- PRAGMA empty_result_callbacks=1;
- ANALYZE
- }
- } {0 {}}
- do_test analyze-1.6 {
- execsql {
- SELECT count(*) FROM sqlite_master WHERE name='sqlite_stat1'
- }
- } {1}
- do_test analyze-1.6.2 {
- catchsql {
- CREATE INDEX stat1idx ON sqlite_stat1(idx);
- }
- } {1 {table sqlite_stat1 may not be indexed}}
- do_test analyze-1.6.3 {
- catchsql {
- CREATE INDEX main.stat1idx ON SQLite_stat1(idx);
- }
- } {1 {table sqlite_stat1 may not be indexed}}
- do_test analyze-1.7 {
- execsql {
- SELECT * FROM sqlite_stat1 WHERE idx NOT NULL
- }
- } {}
- do_test analyze-1.8 {
- catchsql {
- ANALYZE main
- }
- } {0 {}}
- do_test analyze-1.9 {
- execsql {
- SELECT * FROM sqlite_stat1 WHERE idx NOT NULL
- }
- } {}
- do_test analyze-1.10 {
- catchsql {
- CREATE TABLE t1(a,b);
- ANALYZE main.t1;
- }
- } {0 {}}
- do_test analyze-1.11 {
- execsql {
- SELECT * FROM sqlite_stat1
- }
- } {}
- do_test analyze-1.12 {
- catchsql {
- ANALYZE t1;
- }
- } {0 {}}
- do_test analyze-1.13 {
- execsql {
- SELECT * FROM sqlite_stat1
- }
- } {}
- # Create some indices that can be analyzed. But do not yet add
- # data. Without data in the tables, no analysis is done.
- #
- do_test analyze-2.1 {
- execsql {
- CREATE INDEX t1i1 ON t1(a);
- ANALYZE main.t1;
- SELECT * FROM sqlite_stat1 ORDER BY idx;
- }
- } {}
- do_test analyze-2.2 {
- execsql {
- CREATE INDEX t1i2 ON t1(b);
- ANALYZE t1;
- SELECT * FROM sqlite_stat1 ORDER BY idx;
- }
- } {}
- do_test analyze-2.3 {
- execsql {
- CREATE INDEX t1i3 ON t1(a,b);
- ANALYZE main;
- SELECT * FROM sqlite_stat1 ORDER BY idx;
- }
- } {}
- # Start adding data to the table. Verify that the analysis
- # is done correctly.
- #
- do_test analyze-3.1 {
- execsql {
- INSERT INTO t1 VALUES(1,2);
- INSERT INTO t1 VALUES(1,3);
- ANALYZE main.t1;
- SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
- }
- } {t1i1 {2 2} t1i2 {2 1} t1i3 {2 2 1}}
- do_test analyze-3.2 {
- execsql {
- INSERT INTO t1 VALUES(1,4);
- INSERT INTO t1 VALUES(1,5);
- ANALYZE t1;
- SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
- }
- } {t1i1 {4 4} t1i2 {4 1} t1i3 {4 4 1}}
- do_test analyze-3.3 {
- execsql {
- INSERT INTO t1 VALUES(2,5);
- ANALYZE main;
- SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
- }
- } {t1i1 {5 3} t1i2 {5 2} t1i3 {5 3 1}}
- do_test analyze-3.4 {
- execsql {
- CREATE TABLE t2 AS SELECT * FROM t1;
- CREATE INDEX t2i1 ON t2(a);
- CREATE INDEX t2i2 ON t2(b);
- CREATE INDEX t2i3 ON t2(a,b);
- ANALYZE;
- SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
- }
- } {t1i1 {5 3} t1i2 {5 2} t1i3 {5 3 1} t2i1 {5 3} t2i2 {5 2} t2i3 {5 3 1}}
- do_test analyze-3.5 {
- execsql {
- DROP INDEX t2i3;
- ANALYZE t1;
- SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
- }
- } {t1i1 {5 3} t1i2 {5 2} t1i3 {5 3 1} t2i1 {5 3} t2i2 {5 2}}
- do_test analyze-3.6 {
- execsql {
- ANALYZE t2;
- SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
- }
- } {t1i1 {5 3} t1i2 {5 2} t1i3 {5 3 1} t2i1 {5 3} t2i2 {5 2}}
- do_test analyze-3.7 {
- execsql {
- DROP INDEX t2i2;
- ANALYZE t2;
- SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
- }
- } {t1i1 {5 3} t1i2 {5 2} t1i3 {5 3 1} t2i1 {5 3}}
- do_test analyze-3.8 {
- execsql {
- CREATE TABLE t3 AS SELECT a, b, rowid AS c, 'hi' AS d FROM t1;
- CREATE INDEX t3i1 ON t3(a);
- CREATE INDEX t3i2 ON t3(a,b,c,d);
- CREATE INDEX t3i3 ON t3(d,b,c,a);
- DROP TABLE t1;
- DROP TABLE t2;
- SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
- }
- } {}
- do_test analyze-3.9 {
- execsql {
- ANALYZE;
- SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
- }
- } {t3i1 {5 3} t3i2 {5 3 1 1 1} t3i3 {5 5 2 1 1}}
- do_test analyze-3.10 {
- execsql {
- CREATE TABLE [silly " name](a, b, c);
- CREATE INDEX 'foolish '' name' ON [silly " name](a, b);
- CREATE INDEX 'another foolish '' name' ON [silly " name](c);
- INSERT INTO [silly " name] VALUES(1, 2, 3);
- INSERT INTO [silly " name] VALUES(4, 5, 6);
- ANALYZE;
- SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
- }
- } {{another foolish ' name} {2 1} {foolish ' name} {2 1 1} t3i1 {5 3} t3i2 {5 3 1 1 1} t3i3 {5 5 2 1 1}}
- do_test analyze-3.11 {
- execsql {
- DROP INDEX "foolish ' name";
- SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
- }
- } {{another foolish ' name} {2 1} t3i1 {5 3} t3i2 {5 3 1 1 1} t3i3 {5 5 2 1 1}}
- do_test analyze-3.11 {
- execsql {
- DROP TABLE "silly "" name";
- SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
- }
- } {t3i1 {5 3} t3i2 {5 3 1 1 1} t3i3 {5 5 2 1 1}}
- # Try corrupting the sqlite_stat1 table and make sure the
- # database is still able to function.
- #
- do_test analyze-4.0 {
- sqlite3 db2 test.db
- db2 eval {
- CREATE TABLE t4(x,y,z);
- CREATE INDEX t4i1 ON t4(x);
- CREATE INDEX t4i2 ON t4(y);
- INSERT INTO t4 SELECT a,b,c FROM t3;
- }
- db2 close
- db close
- sqlite3 db test.db
- execsql {
- ANALYZE;
- SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
- }
- } {t3i1 {5 3} t3i2 {5 3 1 1 1} t3i3 {5 5 2 1 1} t4i1 {5 3} t4i2 {5 2}}
- do_test analyze-4.1 {
- execsql {
- PRAGMA writable_schema=on;
- INSERT INTO sqlite_stat1 VALUES(null,null,null);
- PRAGMA writable_schema=off;
- }
- db close
- sqlite3 db test.db
- execsql {
- SELECT * FROM t4 WHERE x=1234;
- }
- } {}
- do_test analyze-4.2 {
- execsql {
- PRAGMA writable_schema=on;
- DELETE FROM sqlite_stat1;
- INSERT INTO sqlite_stat1 VALUES('t4','t4i1','nonsense');
- INSERT INTO sqlite_stat1 VALUES('t4','t4i2','120897349817238741092873198273409187234918720394817209384710928374109827172901827349871928741910');
- PRAGMA writable_schema=off;
- }
- db close
- sqlite3 db test.db
- execsql {
- SELECT * FROM t4 WHERE x=1234;
- }
- } {}
- do_test analyze-4.3 {
- execsql {
- INSERT INTO sqlite_stat1 VALUES('t4','xyzzy','0 1 2 3');
- }
- db close
- sqlite3 db test.db
- execsql {
- SELECT * FROM t4 WHERE x=1234;
- }
- } {}
- # Verify that DROP TABLE and DROP INDEX remove entries from the
- # sqlite_stat1, sqlite_stat3 and sqlite_stat4 tables.
- #
- do_test analyze-5.0 {
- execsql {
- DELETE FROM t3;
- DELETE FROM t4;
- INSERT INTO t3 VALUES(1,2,3,4);
- INSERT INTO t3 VALUES(5,6,7,8);
- INSERT INTO t3 SELECT a+8, b+8, c+8, d+8 FROM t3;
- INSERT INTO t3 SELECT a+16, b+16, c+16, d+16 FROM t3;
- INSERT INTO t3 SELECT a+32, b+32, c+32, d+32 FROM t3;
- INSERT INTO t3 SELECT a+64, b+64, c+64, d+64 FROM t3;
- INSERT INTO t4 SELECT a, b, c FROM t3;
- ANALYZE;
- SELECT DISTINCT idx FROM sqlite_stat1 ORDER BY 1;
- SELECT DISTINCT tbl FROM sqlite_stat1 ORDER BY 1;
- }
- } {t3i1 t3i2 t3i3 t4i1 t4i2 t3 t4}
- ifcapable stat4||stat3 {
- ifcapable stat4 {set stat sqlite_stat4} else {set stat sqlite_stat3}
- do_test analyze-5.1 {
- execsql "
- SELECT DISTINCT idx FROM $stat ORDER BY 1;
- SELECT DISTINCT tbl FROM $stat ORDER BY 1;
- "
- } {t3i1 t3i2 t3i3 t4i1 t4i2 t3 t4}
- }
- do_test analyze-5.2 {
- execsql {
- DROP INDEX t3i2;
- SELECT DISTINCT idx FROM sqlite_stat1 ORDER BY 1;
- SELECT DISTINCT tbl FROM sqlite_stat1 ORDER BY 1;
- }
- } {t3i1 t3i3 t4i1 t4i2 t3 t4}
- ifcapable stat4||stat3 {
- do_test analyze-5.3 {
- execsql "
- SELECT DISTINCT idx FROM $stat ORDER BY 1;
- SELECT DISTINCT tbl FROM $stat ORDER BY 1;
- "
- } {t3i1 t3i3 t4i1 t4i2 t3 t4}
- }
- do_test analyze-5.4 {
- execsql {
- DROP TABLE t3;
- SELECT DISTINCT idx FROM sqlite_stat1 ORDER BY 1;
- SELECT DISTINCT tbl FROM sqlite_stat1 ORDER BY 1;
- }
- } {t4i1 t4i2 t4}
- ifcapable stat4||stat3 {
- do_test analyze-5.5 {
- execsql "
- SELECT DISTINCT idx FROM $stat ORDER BY 1;
- SELECT DISTINCT tbl FROM $stat ORDER BY 1;
- "
- } {t4i1 t4i2 t4}
- }
- # This test corrupts the database file so it must be the last test
- # in the series.
- #
- do_test analyze-99.1 {
- execsql {
- PRAGMA writable_schema=on;
- UPDATE sqlite_master SET sql='nonsense' WHERE name='sqlite_stat1';
- }
- db close
- catch { sqlite3 db test.db }
- catchsql {
- ANALYZE
- }
- } {1 {malformed database schema (sqlite_stat1) - near "nonsense": syntax error}}
- finish_test
|