blob: 622e48fcfa061267d5628235518d5e12c42fbe15 [file] [log] [blame]
drhc2b23e72013-11-13 15:32:15 +00001# 2013-11-13
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#
12# This file implements tests of the "skip-scan" query strategy.
13#
14
15set testdir [file dirname $argv0]
16source $testdir/tester.tcl
17
18do_execsql_test skipscan1-1.1 {
19 CREATE TABLE t1(a TEXT, b INT, c INT, d INT);
20 CREATE INDEX t1abc ON t1(a,b,c);
21 INSERT INTO t1 VALUES('abc',123,4,5);
22 INSERT INTO t1 VALUES('abc',234,5,6);
23 INSERT INTO t1 VALUES('abc',234,6,7);
24 INSERT INTO t1 VALUES('abc',345,7,8);
25 INSERT INTO t1 VALUES('def',567,8,9);
26 INSERT INTO t1 VALUES('def',345,9,10);
27 INSERT INTO t1 VALUES('bcd',100,6,11);
28
29 /* Fake the sqlite_stat1 table so that the query planner believes
30 ** the table contains thousands of rows and that the first few
31 ** columns are not selective. */
32 ANALYZE;
33 DELETE FROM sqlite_stat1;
34 INSERT INTO sqlite_stat1 VALUES('t1','t1abc','10000 5000 2000 10');
35 ANALYZE sqlite_master;
36} {}
37
38# Simple queries that leave the first one or two columns of the
39# index unconstrainted.
40#
41do_execsql_test skipscan1-1.2 {
42 SELECT a,b,c,d,'|' FROM t1 WHERE b=345 ORDER BY a;
43} {abc 345 7 8 | def 345 9 10 |}
44do_execsql_test skipscan1-1.2eqp {
45 EXPLAIN QUERY PLAN
46 SELECT a,b,c,d,'|' FROM t1 WHERE b=345 ORDER BY a;
47} {/* USING INDEX t1abc (ANY(a) AND b=?)*/}
48do_execsql_test skipscan1-1.2sort {
49 EXPLAIN QUERY PLAN
50 SELECT a,b,c,d,'|' FROM t1 WHERE b=345 ORDER BY a;
51} {~/*ORDER BY*/}
52
53do_execsql_test skipscan1-1.3 {
54 SELECT a,b,c,d,'|' FROM t1 WHERE b=345 ORDER BY a DESC;
55} {def 345 9 10 | abc 345 7 8 |}
56do_execsql_test skipscan1-1.3eqp {
57 EXPLAIN QUERY PLAN
58 SELECT a,b,c,d,'|' FROM t1 WHERE b=345 ORDER BY a;
59} {/* USING INDEX t1abc (ANY(a) AND b=?)*/}
60do_execsql_test skipscan1-1.3sort {
61 EXPLAIN QUERY PLAN
62 SELECT a,b,c,d,'|' FROM t1 WHERE b=345 ORDER BY a;
63} {~/*ORDER BY*/}
64
65do_execsql_test skipscan1-1.4 {
66 SELECT a,b,c,d,'|' FROM t1 WHERE c=6 ORDER BY a, b, c;
67} {abc 234 6 7 | bcd 100 6 11 |}
68do_execsql_test skipscan1-1.4eqp {
69 EXPLAIN QUERY PLAN
70 SELECT a,b,c,d,'|' FROM t1 WHERE c=6 ORDER BY a, b, c;
71} {/* USING INDEX t1abc (ANY(a) AND ANY(b) AND c=?)*/}
72do_execsql_test skipscan1-1.4sort {
73 EXPLAIN QUERY PLAN
74 SELECT a,b,c,d,'|' FROM t1 WHERE c=6 ORDER BY a, b, c;
75} {~/*ORDER BY*/}
76
drh2e5ef4e2013-11-13 16:58:54 +000077do_execsql_test skipscan1-1.5 {
78 SELECT a,b,c,d,'|' FROM t1 WHERE c IN (6,7) ORDER BY a, b, c;
79} {abc 234 6 7 | abc 345 7 8 | bcd 100 6 11 |}
80do_execsql_test skipscan1-1.5eqp {
81 EXPLAIN QUERY PLAN
82 SELECT a,b,c,d,'|' FROM t1 WHERE c IN (6,7) ORDER BY a, b, c;
83} {/* USING INDEX t1abc (ANY(a) AND ANY(b) AND c=?)*/}
84do_execsql_test skipscan1-1.5sort {
85 EXPLAIN QUERY PLAN
86 SELECT a,b,c,d,'|' FROM t1 WHERE c IN (6,7) ORDER BY a, b, c;
87} {~/*ORDER BY*/}
88
89do_execsql_test skipscan1-1.6 {
90 SELECT a,b,c,d,'|' FROM t1 WHERE c BETWEEN 6 AND 7 ORDER BY a, b, c;
91} {abc 234 6 7 | abc 345 7 8 | bcd 100 6 11 |}
92do_execsql_test skipscan1-1.6eqp {
93 EXPLAIN QUERY PLAN
94 SELECT a,b,c,d,'|' FROM t1 WHERE c BETWEEN 6 AND 7 ORDER BY a, b, c;
95} {/* USING INDEX t1abc (ANY(a) AND ANY(b) AND c>? AND c<?)*/}
96do_execsql_test skipscan1-1.6sort {
97 EXPLAIN QUERY PLAN
98 SELECT a,b,c,d,'|' FROM t1 WHERE c BETWEEN 6 AND 7 ORDER BY a, b, c;
99} {~/*ORDER BY*/}
100
drhd2447442013-11-13 19:01:41 +0000101do_execsql_test skipscan1-1.7 {
102 SELECT a,b,c,d,'|' FROM t1 WHERE b IN (234, 345) AND c BETWEEN 6 AND 7
103 ORDER BY a, b;
104} {abc 234 6 7 | abc 345 7 8 |}
105do_execsql_test skipscan1-1.7eqp {
106 EXPLAIN QUERY PLAN
107 SELECT a,b,c,d,'|' FROM t1 WHERE b IN (234, 345) AND c BETWEEN 6 AND 7
108 ORDER BY a, b;
109} {/* USING INDEX t1abc (ANY(a) AND b=? AND c>? AND c<?)*/}
110do_execsql_test skipscan1-1.7sort {
111 EXPLAIN QUERY PLAN
112 SELECT a,b,c,d,'|' FROM t1 WHERE b IN (234, 345) AND c BETWEEN 6 AND 7
113 ORDER BY a, b;
114} {~/*ORDER BY*/}
115
drh2e5ef4e2013-11-13 16:58:54 +0000116
drhc2b23e72013-11-13 15:32:15 +0000117# Joins
118#
drh2e5ef4e2013-11-13 16:58:54 +0000119do_execsql_test skipscan1-1.51 {
drhc2b23e72013-11-13 15:32:15 +0000120 CREATE TABLE t1j(x TEXT, y INTEGER);
121 INSERT INTO t1j VALUES('one',1),('six',6),('ninty-nine',99);
drh2e5ef4e2013-11-13 16:58:54 +0000122 INSERT INTO sqlite_stat1 VALUES('t1j',null,'3');
123 ANALYZE sqlite_master;
drhc2b23e72013-11-13 15:32:15 +0000124 SELECT x, a, b, c, d, '|' FROM t1j, t1 WHERE c=y ORDER BY +a;
125} {six abc 234 6 7 | six bcd 100 6 11 |}
drh2e5ef4e2013-11-13 16:58:54 +0000126do_execsql_test skipscan1-1.51eqp {
drhc2b23e72013-11-13 15:32:15 +0000127 EXPLAIN QUERY PLAN
128 SELECT x, a, b, c, d, '|' FROM t1j, t1 WHERE c=y ORDER BY +a;
129} {/* INDEX t1abc (ANY(a) AND ANY(b) AND c=?)*/}
130
drh2e5ef4e2013-11-13 16:58:54 +0000131do_execsql_test skipscan1-1.52 {
drhc2b23e72013-11-13 15:32:15 +0000132 SELECT x, a, b, c, d, '|' FROM t1j LEFT JOIN t1 ON c=y ORDER BY +y, +a;
133} {one {} {} {} {} | six abc 234 6 7 | six bcd 100 6 11 | ninty-nine {} {} {} {} |}
drh2e5ef4e2013-11-13 16:58:54 +0000134do_execsql_test skipscan1-1.52eqp {
drhc2b23e72013-11-13 15:32:15 +0000135 EXPLAIN QUERY PLAN
136 SELECT x, a, b, c, d, '|' FROM t1j LEFT JOIN t1 ON c=y ORDER BY +y, +a;
137} {/* INDEX t1abc (ANY(a) AND ANY(b) AND c=?)*/}
138
139do_execsql_test skipscan1-2.1 {
140 CREATE TABLE t2(a TEXT, b INT, c INT, d INT,
141 PRIMARY KEY(a,b,c));
142 INSERT INTO t2 SELECT * FROM t1;
143
144 /* Fake the sqlite_stat1 table so that the query planner believes
145 ** the table contains thousands of rows and that the first few
146 ** columns are not selective. */
147 ANALYZE;
148 UPDATE sqlite_stat1 SET stat='10000 5000 2000 10' WHERE idx NOT NULL;
149 ANALYZE sqlite_master;
150} {}
151
152do_execsql_test skipscan1-2.2 {
153 SELECT a,b,c,d,'|' FROM t2 WHERE b=345 ORDER BY a;
154} {abc 345 7 8 | def 345 9 10 |}
155do_execsql_test skipscan1-2.2eqp {
156 EXPLAIN QUERY PLAN
157 SELECT a,b,c,d,'|' FROM t2 WHERE b=345 ORDER BY a;
158} {/* USING INDEX sqlite_autoindex_t2_1 (ANY(a) AND b=?)*/}
159do_execsql_test skipscan1-2.2sort {
160 EXPLAIN QUERY PLAN
161 SELECT a,b,c,d,'|' FROM t2 WHERE b=345 ORDER BY a;
162} {~/*ORDER BY*/}
163
164
165do_execsql_test skipscan1-3.1 {
166 CREATE TABLE t3(a TEXT, b INT, c INT, d INT,
167 PRIMARY KEY(a,b,c)) WITHOUT ROWID;
168 INSERT INTO t3 SELECT * FROM t1;
169
170 /* Fake the sqlite_stat1 table so that the query planner believes
171 ** the table contains thousands of rows and that the first few
172 ** columns are not selective. */
173 ANALYZE;
174 UPDATE sqlite_stat1 SET stat='10000 5000 2000 10' WHERE idx NOT NULL;
175 ANALYZE sqlite_master;
176} {}
177
178do_execsql_test skipscan1-3.2 {
179 SELECT a,b,c,d,'|' FROM t3 WHERE b=345 ORDER BY a;
180} {abc 345 7 8 | def 345 9 10 |}
181do_execsql_test skipscan1-3.2eqp {
182 EXPLAIN QUERY PLAN
183 SELECT a,b,c,d,'|' FROM t3 WHERE b=345 ORDER BY a;
184} {/* INDEX sqlite_autoindex_t3_1 (ANY(a) AND b=?)*/}
185do_execsql_test skipscan1-3.2sort {
186 EXPLAIN QUERY PLAN
187 SELECT a,b,c,d,'|' FROM t3 WHERE b=345 ORDER BY a;
188} {~/*ORDER BY*/}
189
190finish_test