• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 2005 July 22
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# This file implements regression tests for SQLite library.
12# This file implements tests for the ANALYZE command.
13#
14# $Id: analyze.test,v 1.9 2008/08/11 18:44:58 drh Exp $
15
16set testdir [file dirname $argv0]
17source $testdir/tester.tcl
18
19# There is nothing to test if ANALYZE is disable for this build.
20#
21ifcapable {!analyze} {
22  finish_test
23  return
24}
25
26# Basic sanity checks.
27#
28do_test analyze-1.1 {
29  catchsql {
30    ANALYZE no_such_table
31  }
32} {1 {no such table: no_such_table}}
33do_test analyze-1.2 {
34  execsql {
35    SELECT count(*) FROM sqlite_master WHERE name='sqlite_stat1'
36  }
37} {0}
38do_test analyze-1.3 {
39  catchsql {
40    ANALYZE no_such_db.no_such_table
41  }
42} {1 {unknown database no_such_db}}
43do_test analyze-1.4 {
44  execsql {
45    SELECT count(*) FROM sqlite_master WHERE name='sqlite_stat1'
46  }
47} {0}
48do_test analyze-1.5.1 {
49  catchsql {
50    ANALYZE
51  }
52} {0 {}}
53do_test analyze-1.5.2 {
54  catchsql {
55    PRAGMA empty_result_callbacks=1;
56    ANALYZE
57  }
58} {0 {}}
59do_test analyze-1.6 {
60  execsql {
61    SELECT count(*) FROM sqlite_master WHERE name='sqlite_stat1'
62  }
63} {1}
64do_test analyze-1.6.2 {
65  catchsql {
66    CREATE INDEX stat1idx ON sqlite_stat1(idx);
67  }
68} {1 {table sqlite_stat1 may not be indexed}}
69do_test analyze-1.6.3 {
70  catchsql {
71    CREATE INDEX main.stat1idx ON SQLite_stat1(idx);
72  }
73} {1 {table sqlite_stat1 may not be indexed}}
74do_test analyze-1.7 {
75  execsql {
76    SELECT * FROM sqlite_stat1 WHERE idx NOT NULL
77  }
78} {}
79do_test analyze-1.8 {
80  catchsql {
81    ANALYZE main
82  }
83} {0 {}}
84do_test analyze-1.9 {
85  execsql {
86    SELECT * FROM sqlite_stat1 WHERE idx NOT NULL
87  }
88} {}
89do_test analyze-1.10 {
90  catchsql {
91    CREATE TABLE t1(a,b);
92    ANALYZE main.t1;
93  }
94} {0 {}}
95do_test analyze-1.11 {
96  execsql {
97    SELECT * FROM sqlite_stat1
98  }
99} {}
100do_test analyze-1.12 {
101  catchsql {
102    ANALYZE t1;
103  }
104} {0 {}}
105do_test analyze-1.13 {
106  execsql {
107    SELECT * FROM sqlite_stat1
108  }
109} {}
110
111# Create some indices that can be analyzed.  But do not yet add
112# data.  Without data in the tables, no analysis is done.
113#
114do_test analyze-2.1 {
115  execsql {
116    CREATE INDEX t1i1 ON t1(a);
117    ANALYZE main.t1;
118    SELECT * FROM sqlite_stat1 ORDER BY idx;
119  }
120} {}
121do_test analyze-2.2 {
122  execsql {
123    CREATE INDEX t1i2 ON t1(b);
124    ANALYZE t1;
125    SELECT * FROM sqlite_stat1 ORDER BY idx;
126  }
127} {}
128do_test analyze-2.3 {
129  execsql {
130    CREATE INDEX t1i3 ON t1(a,b);
131    ANALYZE main;
132    SELECT * FROM sqlite_stat1 ORDER BY idx;
133  }
134} {}
135
136# Start adding data to the table.  Verify that the analysis
137# is done correctly.
138#
139do_test analyze-3.1 {
140  execsql {
141    INSERT INTO t1 VALUES(1,2);
142    INSERT INTO t1 VALUES(1,3);
143    ANALYZE main.t1;
144    SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
145  }
146} {t1i1 {2 2} t1i2 {2 1} t1i3 {2 2 1}}
147do_test analyze-3.2 {
148  execsql {
149    INSERT INTO t1 VALUES(1,4);
150    INSERT INTO t1 VALUES(1,5);
151    ANALYZE t1;
152    SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
153  }
154} {t1i1 {4 4} t1i2 {4 1} t1i3 {4 4 1}}
155do_test analyze-3.3 {
156  execsql {
157    INSERT INTO t1 VALUES(2,5);
158    ANALYZE main;
159    SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
160  }
161} {t1i1 {5 3} t1i2 {5 2} t1i3 {5 3 1}}
162do_test analyze-3.4 {
163  execsql {
164    CREATE TABLE t2 AS SELECT * FROM t1;
165    CREATE INDEX t2i1 ON t2(a);
166    CREATE INDEX t2i2 ON t2(b);
167    CREATE INDEX t2i3 ON t2(a,b);
168    ANALYZE;
169    SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
170  }
171} {t1i1 {5 3} t1i2 {5 2} t1i3 {5 3 1} t2i1 {5 3} t2i2 {5 2} t2i3 {5 3 1}}
172do_test analyze-3.5 {
173  execsql {
174    DROP INDEX t2i3;
175    ANALYZE t1;
176    SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
177  }
178} {t1i1 {5 3} t1i2 {5 2} t1i3 {5 3 1} t2i1 {5 3} t2i2 {5 2}}
179do_test analyze-3.6 {
180  execsql {
181    ANALYZE t2;
182    SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
183  }
184} {t1i1 {5 3} t1i2 {5 2} t1i3 {5 3 1} t2i1 {5 3} t2i2 {5 2}}
185do_test analyze-3.7 {
186  execsql {
187    DROP INDEX t2i2;
188    ANALYZE t2;
189    SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
190  }
191} {t1i1 {5 3} t1i2 {5 2} t1i3 {5 3 1} t2i1 {5 3}}
192do_test analyze-3.8 {
193  execsql {
194    CREATE TABLE t3 AS SELECT a, b, rowid AS c, 'hi' AS d FROM t1;
195    CREATE INDEX t3i1 ON t3(a);
196    CREATE INDEX t3i2 ON t3(a,b,c,d);
197    CREATE INDEX t3i3 ON t3(d,b,c,a);
198    DROP TABLE t1;
199    DROP TABLE t2;
200    SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
201  }
202} {}
203do_test analyze-3.9 {
204  execsql {
205    ANALYZE;
206    SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
207  }
208} {t3i1 {5 3} t3i2 {5 3 1 1 1} t3i3 {5 5 2 1 1}}
209
210do_test analyze-3.10 {
211  execsql {
212    CREATE TABLE [silly " name](a, b, c);
213    CREATE INDEX 'foolish '' name' ON [silly " name](a, b);
214    CREATE INDEX 'another foolish '' name' ON [silly " name](c);
215    INSERT INTO [silly " name] VALUES(1, 2, 3);
216    INSERT INTO [silly " name] VALUES(4, 5, 6);
217    ANALYZE;
218    SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
219  }
220} {{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}}
221do_test analyze-3.11 {
222  execsql {
223    DROP INDEX "foolish ' name";
224    SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
225  }
226} {{another foolish ' name} {2 1} t3i1 {5 3} t3i2 {5 3 1 1 1} t3i3 {5 5 2 1 1}}
227do_test analyze-3.11 {
228  execsql {
229    DROP TABLE "silly "" name";
230    SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
231  }
232} {t3i1 {5 3} t3i2 {5 3 1 1 1} t3i3 {5 5 2 1 1}}
233
234# Try corrupting the sqlite_stat1 table and make sure the
235# database is still able to function.
236#
237do_test analyze-4.0 {
238  sqlite3 db2 test.db
239  db2 eval {
240    CREATE TABLE t4(x,y,z);
241    CREATE INDEX t4i1 ON t4(x);
242    CREATE INDEX t4i2 ON t4(y);
243    INSERT INTO t4 SELECT a,b,c FROM t3;
244  }
245  db2 close
246  db close
247  sqlite3 db test.db
248  execsql {
249    ANALYZE;
250    SELECT idx, stat FROM sqlite_stat1 ORDER BY idx;
251  }
252} {t3i1 {5 3} t3i2 {5 3 1 1 1} t3i3 {5 5 2 1 1} t4i1 {5 3} t4i2 {5 2}}
253do_test analyze-4.1 {
254  execsql {
255    PRAGMA writable_schema=on;
256    INSERT INTO sqlite_stat1 VALUES(null,null,null);
257    PRAGMA writable_schema=off;
258  }
259  db close
260  sqlite3 db test.db
261  execsql {
262    SELECT * FROM t4 WHERE x=1234;
263  }
264} {}
265do_test analyze-4.2 {
266  execsql {
267    PRAGMA writable_schema=on;
268    DELETE FROM sqlite_stat1;
269    INSERT INTO sqlite_stat1 VALUES('t4','t4i1','nonsense');
270    INSERT INTO sqlite_stat1 VALUES('t4','t4i2','120897349817238741092873198273409187234918720394817209384710928374109827172901827349871928741910');
271    PRAGMA writable_schema=off;
272  }
273  db close
274  sqlite3 db test.db
275  execsql {
276    SELECT * FROM t4 WHERE x=1234;
277  }
278} {}
279do_test analyze-4.3 {
280  execsql {
281    INSERT INTO sqlite_stat1 VALUES('t4','xyzzy','0 1 2 3');
282  }
283  db close
284  sqlite3 db test.db
285  execsql {
286    SELECT * FROM t4 WHERE x=1234;
287  }
288} {}
289
290# This test corrupts the database file so it must be the last test
291# in the series.
292#
293do_test analyze-99.1 {
294  execsql {
295    PRAGMA writable_schema=on;
296    UPDATE sqlite_master SET sql='nonsense' WHERE name='sqlite_stat1';
297  }
298  db close
299  catch { sqlite3 db test.db }
300  catchsql {
301    ANALYZE
302  }
303} {1 {malformed database schema (sqlite_stat1) - near "nonsense": syntax error}}
304
305
306finish_test
307