Avoid leaving view-definitions with an incomplete set of column names/types in
[sqlite.git] / test / cost.test
blob5d23e0ed7bcfb357f763301ca422a30bcf44e5df
1 # 2014-04-26
3 # The author disclaims copyright to this source code.  In place of
4 # a legal notice, here is a blessing:
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.
10 #***********************************************************************
11
13 set testdir [file dirname $argv0]
14 source $testdir/tester.tcl
15 set testprefix cost
18 do_execsql_test 1.1 {
19   CREATE TABLE t3(id INTEGER PRIMARY KEY, b NOT NULL);
20   CREATE TABLE t4(c, d, e);
21   CREATE UNIQUE INDEX i3 ON t3(b);
22   CREATE UNIQUE INDEX i4 ON t4(c, d);
24 do_eqp_test 1.2 {
25   SELECT e FROM t3, t4 WHERE b=c ORDER BY b, d;
26 } {
27   QUERY PLAN
28   |--SCAN TABLE t3 USING COVERING INDEX i3
29   `--SEARCH TABLE t4 USING INDEX i4 (c=?)
33 do_execsql_test 2.1 {
34   CREATE TABLE t1(a, b);
35   CREATE INDEX i1 ON t1(a);
38 # It is better to use an index for ORDER BY than sort externally, even 
39 # if the index is a non-covering index.
40 do_eqp_test 2.2 {
41   SELECT * FROM t1 ORDER BY a;
42 } {SCAN TABLE t1 USING INDEX i1}
44 do_execsql_test 3.1 {
45   CREATE TABLE t5(a INTEGER PRIMARY KEY,b,c,d,e,f,g);
46   CREATE INDEX t5b ON t5(b);
47   CREATE INDEX t5c ON t5(c);
48   CREATE INDEX t5d ON t5(d);
49   CREATE INDEX t5e ON t5(e);
50   CREATE INDEX t5f ON t5(f);
51   CREATE INDEX t5g ON t5(g);
54 do_eqp_test 3.2 {
55   SELECT a FROM t5 
56   WHERE b IS NULL OR c IS NULL OR d IS NULL 
57   ORDER BY a;
58 } {
59   QUERY PLAN
60   |--MULTI-INDEX OR
61   |  |--SEARCH TABLE t5 USING INDEX t5b (b=?)
62   |  |--SEARCH TABLE t5 USING INDEX t5c (c=?)
63   |  `--SEARCH TABLE t5 USING INDEX t5d (d=?)
64   `--USE TEMP B-TREE FOR ORDER BY
67 #-------------------------------------------------------------------------
68 # If there is no likelihood() or stat3 data, SQLite assumes that a closed
69 # range scan (e.g. one constrained by "col BETWEEN ? AND ?" constraint)
70 # visits 1/64 of the rows in a table.
72 # Note: 1/63 =~ 0.016
73 # Note: 1/65 =~ 0.015
75 reset_db
76 do_execsql_test 4.1 {
77   CREATE TABLE t1(a, b);
78   CREATE INDEX i1 ON t1(a);
79   CREATE INDEX i2 ON t1(b);
81 do_eqp_test 4.2 {
82   SELECT * FROM t1 WHERE likelihood(a=?, 0.014) AND b BETWEEN ? AND ?;
83 } {SEARCH TABLE t1 USING INDEX i1 (a=?)}
85 do_eqp_test 4.3 {
86   SELECT * FROM t1 WHERE likelihood(a=?, 0.016) AND b BETWEEN ? AND ?;
87 } {SEARCH TABLE t1 USING INDEX i2 (b>? AND b<?)}
90 #-------------------------------------------------------------------------
92 reset_db
93 do_execsql_test 5.1 {
94   CREATE TABLE t2(x, y);
95   CREATE INDEX t2i1 ON t2(x);
98 do_eqp_test 5.2 {
99   SELECT * FROM t2 ORDER BY x, y;
100 } {
101   QUERY PLAN
102   |--SCAN TABLE t2 USING INDEX t2i1
103   `--USE TEMP B-TREE FOR RIGHT PART OF ORDER BY
106 do_eqp_test 5.3 {
107   SELECT * FROM t2 WHERE x BETWEEN ? AND ? ORDER BY rowid;
108 } {
109   QUERY PLAN
110   |--SEARCH TABLE t2 USING INDEX t2i1 (x>? AND x<?)
111   `--USE TEMP B-TREE FOR ORDER BY
114 # where7.test, where8.test:
116 do_execsql_test 6.1 {
117   CREATE TABLE t3(a INTEGER PRIMARY KEY, b, c);
118   CREATE INDEX t3i1 ON t3(b);
119   CREATE INDEX t3i2 ON t3(c);
122 do_eqp_test 6.2 {
123   SELECT a FROM t3 WHERE (b BETWEEN 2 AND 4) OR c=100 ORDER BY a
124 } {
125   QUERY PLAN
126   |--MULTI-INDEX OR
127   |  |--SEARCH TABLE t3 USING INDEX t3i1 (b>? AND b<?)
128   |  `--SEARCH TABLE t3 USING INDEX t3i2 (c=?)
129   `--USE TEMP B-TREE FOR ORDER BY
132 #-------------------------------------------------------------------------
134 reset_db
135 do_execsql_test 7.1 {
136   CREATE TABLE t1(a INTEGER PRIMARY KEY,b,c,d,e,f,g);
137   CREATE INDEX t1b ON t1(b);
138   CREATE INDEX t1c ON t1(c);
139   CREATE INDEX t1d ON t1(d);
140   CREATE INDEX t1e ON t1(e);
141   CREATE INDEX t1f ON t1(f);
142   CREATE INDEX t1g ON t1(g);
145 do_eqp_test 7.2 {
146   SELECT a FROM t1
147      WHERE (b>=950 AND b<=1010) OR (b IS NULL AND c NOT NULL)
148   ORDER BY a
149 } {
150   QUERY PLAN
151   |--MULTI-INDEX OR
152   |  |--SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)
153   |  `--SEARCH TABLE t1 USING INDEX t1b (b=?)
154   `--USE TEMP B-TREE FOR ORDER BY
157 do_eqp_test 7.3 {
158   SELECT rowid FROM t1
159   WHERE (+b IS NULL AND c NOT NULL AND d NOT NULL)
160         OR (b NOT NULL AND c IS NULL AND d NOT NULL)
161         OR (b NOT NULL AND c NOT NULL AND d IS NULL)
162 } {SCAN TABLE t1}
164 do_eqp_test 7.4 {
165   SELECT rowid FROM t1 WHERE (+b IS NULL AND c NOT NULL) OR c IS NULL
166 } {SCAN TABLE t1}
168 #-------------------------------------------------------------------------
170 reset_db
171 do_execsql_test 8.1 {
172   CREATE TABLE composer(
173     cid INTEGER PRIMARY KEY,
174     cname TEXT
175   );
176   CREATE TABLE album(
177     aid INTEGER PRIMARY KEY,
178     aname TEXT
179   );
180   CREATE TABLE track(
181     tid INTEGER PRIMARY KEY,
182     cid INTEGER REFERENCES composer,
183     aid INTEGER REFERENCES album,
184     title TEXT
185   );
186   CREATE INDEX track_i1 ON track(cid);
187   CREATE INDEX track_i2 ON track(aid);
190 do_eqp_test 8.2 {
191   SELECT DISTINCT aname
192     FROM album, composer, track
193    WHERE cname LIKE '%bach%'
194      AND unlikely(composer.cid=track.cid)
195      AND unlikely(album.aid=track.aid);
196 } {
197   QUERY PLAN
198   |--SCAN TABLE track
199   |--SEARCH TABLE album USING INTEGER PRIMARY KEY (rowid=?)
200   |--SEARCH TABLE composer USING INTEGER PRIMARY KEY (rowid=?)
201   `--USE TEMP B-TREE FOR DISTINCT
204 #-------------------------------------------------------------------------
206 do_execsql_test 9.1 {
207   CREATE TABLE t1(
208     a,b,c,d,e, f,g,h,i,j,
209     k,l,m,n,o, p,q,r,s,t
210   );
211   CREATE INDEX i1 ON t1(k,l,m,n,o,p,q,r,s,t);
213 do_test 9.2 {
214   for {set i 0} {$i < 100} {incr i} {
215     execsql { INSERT INTO t1 DEFAULT VALUES }
216   }
217   execsql {
218     ANALYZE;
219     CREATE INDEX i2 ON t1(a,b,c,d,e,f,g,h,i,j);
220   }
221 } {}
223 set L [list a=? b=? c=? d=? e=? f=? g=? h=? i=? j=?]
224 foreach {tn nTerm nRow} {
225   1   1 10
226   2   2  9
227   3   3  8
228   4   4  7
229   5   5  6
230   6   6  5
231   7   7  5
232   8   8  5
233   9   9  5
234   10 10  5
235 } {
236   set w [join [lrange $L 0 [expr $nTerm-1]] " AND "]
237   set p1 [expr ($nRow-1) / 100.0]
238   set p2 [expr ($nRow+1) / 100.0]
240   set sql1 "SELECT * FROM t1 WHERE likelihood(k=?, $p1) AND $w"
241   set sql2 "SELECT * FROM t1 WHERE likelihood(k=?, $p2) AND $w"
243   do_eqp_test 9.3.$tn.1 $sql1 {/INDEX i1/}
244   do_eqp_test 9.3.$tn.2 $sql2 {/INDEX i2/}
248 #-------------------------------------------------------------------------
251 ifcapable stat4 {
252   do_execsql_test 10.1 {
253     CREATE TABLE t6(a, b, c);
254     CREATE INDEX t6i1 ON t6(a, b);
255     CREATE INDEX t6i2 ON t6(c);
256   }
257   
258   do_test 10.2 {
259     for {set i 0} {$i < 16} {incr i} {
260       execsql { INSERT INTO t6 VALUES($i%4, 'xyz', $i%8) }
261     }
262     execsql ANALYZE
263   } {}
265   do_eqp_test 10.3 {
266     SELECT rowid FROM t6 WHERE a=0 AND c=0
267   } {SEARCH TABLE t6 USING INDEX t6i2 (c=?)}
269   do_eqp_test 10.4 {
270     SELECT rowid FROM t6 WHERE a=0 AND b='xyz' AND c=0
271   } {SEARCH TABLE t6 USING INDEX t6i2 (c=?)}
273   do_eqp_test 10.5 {
274     SELECT rowid FROM t6 WHERE likelihood(a=0, 0.1) AND c=0
275   } {SEARCH TABLE t6 USING INDEX t6i1 (a=?)}
277   do_eqp_test 10.6 {
278     SELECT rowid FROM t6 WHERE likelihood(a=0, 0.1) AND b='xyz' AND c=0
279   } {SEARCH TABLE t6 USING INDEX t6i1 (a=? AND b=?)}
282 finish_test