blob: eda95776f26fa28592e87e59913623f89ee28317 [file] [log] [blame]
dan2ce22452010-11-08 19:01:16 +00001# 2010 November 6
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
13set testdir [file dirname $argv0]
14source $testdir/tester.tcl
15
dan2f56da32012-02-13 10:00:35 +000016ifcapable !compound {
17 finish_test
18 return
19}
20
dan2ce22452010-11-08 19:01:16 +000021set testprefix eqp
22
23#-------------------------------------------------------------------------
24#
25# eqp-1.*: Assorted tests.
26# eqp-2.*: Tests for single select statements.
27# eqp-3.*: Select statements that execute sub-selects.
28# eqp-4.*: Compound select statements.
danef7075d2011-02-21 17:49:49 +000029# ...
30# eqp-7.*: "SELECT count(*) FROM tbl" statements (VDBE code OP_Count).
dan2ce22452010-11-08 19:01:16 +000031#
32
dan4a07e3d2010-11-09 14:48:59 +000033proc det {args} { uplevel do_eqp_test $args }
dan2ce22452010-11-08 19:01:16 +000034
35do_execsql_test 1.1 {
drhd9e3cad2013-10-04 02:36:19 +000036 CREATE TABLE t1(a INT, b INT, ex TEXT);
dan2ce22452010-11-08 19:01:16 +000037 CREATE INDEX i1 ON t1(a);
38 CREATE INDEX i2 ON t1(b);
drhd9e3cad2013-10-04 02:36:19 +000039 CREATE TABLE t2(a INT, b INT, ex TEXT);
40 CREATE TABLE t3(a INT, b INT, ex TEXT);
dan2ce22452010-11-08 19:01:16 +000041}
42
43do_eqp_test 1.2 {
44 SELECT * FROM t2, t1 WHERE t1.a=1 OR t1.b=2;
45} {
drh03c39052018-05-02 14:24:34 +000046 QUERY PLAN
drh5d72d922018-05-04 00:39:43 +000047 |--MULTI-INDEX OR
drhbd462bc2018-12-24 20:21:06 +000048 | |--INDEX 1
drh82102332021-03-20 15:11:29 +000049 | | `--SEARCH t1 USING INDEX i1 (a=?)
drhbd462bc2018-12-24 20:21:06 +000050 | `--INDEX 2
drh82102332021-03-20 15:11:29 +000051 | `--SEARCH t1 USING INDEX i2 (b=?)
52 `--SCAN t2
dan2ce22452010-11-08 19:01:16 +000053}
54do_eqp_test 1.3 {
55 SELECT * FROM t2 CROSS JOIN t1 WHERE t1.a=1 OR t1.b=2;
56} {
drh03c39052018-05-02 14:24:34 +000057 QUERY PLAN
drh82102332021-03-20 15:11:29 +000058 |--SCAN t2
drh5d72d922018-05-04 00:39:43 +000059 `--MULTI-INDEX OR
drhbd462bc2018-12-24 20:21:06 +000060 |--INDEX 1
drh82102332021-03-20 15:11:29 +000061 | `--SEARCH t1 USING INDEX i1 (a=?)
drhbd462bc2018-12-24 20:21:06 +000062 `--INDEX 2
drh82102332021-03-20 15:11:29 +000063 `--SEARCH t1 USING INDEX i2 (b=?)
dan2ce22452010-11-08 19:01:16 +000064}
65do_eqp_test 1.3 {
66 SELECT a FROM t1 ORDER BY a
67} {
drh03c39052018-05-02 14:24:34 +000068 QUERY PLAN
drh82102332021-03-20 15:11:29 +000069 `--SCAN t1 USING COVERING INDEX i1
dan2ce22452010-11-08 19:01:16 +000070}
71do_eqp_test 1.4 {
72 SELECT a FROM t1 ORDER BY +a
73} {
drh03c39052018-05-02 14:24:34 +000074 QUERY PLAN
drh82102332021-03-20 15:11:29 +000075 |--SCAN t1 USING COVERING INDEX i1
drh03c39052018-05-02 14:24:34 +000076 `--USE TEMP B-TREE FOR ORDER BY
dan2ce22452010-11-08 19:01:16 +000077}
78do_eqp_test 1.5 {
79 SELECT a FROM t1 WHERE a=4
80} {
drh03c39052018-05-02 14:24:34 +000081 QUERY PLAN
drh82102332021-03-20 15:11:29 +000082 `--SEARCH t1 USING COVERING INDEX i1 (a=?)
dan2ce22452010-11-08 19:01:16 +000083}
84do_eqp_test 1.6 {
85 SELECT DISTINCT count(*) FROM t3 GROUP BY a;
86} {
drh03c39052018-05-02 14:24:34 +000087 QUERY PLAN
drh82102332021-03-20 15:11:29 +000088 |--SCAN t3
drh03c39052018-05-02 14:24:34 +000089 |--USE TEMP B-TREE FOR GROUP BY
90 `--USE TEMP B-TREE FOR DISTINCT
dan2ce22452010-11-08 19:01:16 +000091}
92
drh82102332021-03-20 15:11:29 +000093do_eqp_test 1.7.1 {
drh95aa47b2010-11-16 02:49:15 +000094 SELECT * FROM t3 JOIN (SELECT 1)
95} {
drh03c39052018-05-02 14:24:34 +000096 QUERY PLAN
drhda653b82022-04-22 17:36:10 +000097 |--MATERIALIZE (subquery-xxxxxx)
drhfa16f5d2018-05-03 01:37:13 +000098 | `--SCAN CONSTANT ROW
drhda653b82022-04-22 17:36:10 +000099 |--SCAN (subquery-xxxxxx)
drh82102332021-03-20 15:11:29 +0000100 `--SCAN t3
drh95aa47b2010-11-16 02:49:15 +0000101}
drh82102332021-03-20 15:11:29 +0000102do_eqp_test 1.7.2 {
103 SELECT * FROM t3 JOIN (SELECT 1) AS v1
104} {
105 QUERY PLAN
106 |--MATERIALIZE v1
107 | `--SCAN CONSTANT ROW
108 |--SCAN v1
109 `--SCAN t3
110}
111do_eqp_test 1.7.3 {
112 SELECT * FROM t3 AS xx JOIN (SELECT 1) AS yy
113} {
114 QUERY PLAN
115 |--MATERIALIZE yy
116 | `--SCAN CONSTANT ROW
117 |--SCAN yy
118 `--SCAN xx
119}
120
121
drh95aa47b2010-11-16 02:49:15 +0000122do_eqp_test 1.8 {
123 SELECT * FROM t3 JOIN (SELECT 1 UNION SELECT 2)
124} {
drh03c39052018-05-02 14:24:34 +0000125 QUERY PLAN
drhda653b82022-04-22 17:36:10 +0000126 |--MATERIALIZE (subquery-xxxxxx)
drh03c39052018-05-02 14:24:34 +0000127 | `--COMPOUND QUERY
128 | |--LEFT-MOST SUBQUERY
drhfa16f5d2018-05-03 01:37:13 +0000129 | | `--SCAN CONSTANT ROW
drh03c39052018-05-02 14:24:34 +0000130 | `--UNION USING TEMP B-TREE
drhfa16f5d2018-05-03 01:37:13 +0000131 | `--SCAN CONSTANT ROW
drhda653b82022-04-22 17:36:10 +0000132 |--SCAN (subquery-xxxxxx)
drh82102332021-03-20 15:11:29 +0000133 `--SCAN t3
drh95aa47b2010-11-16 02:49:15 +0000134}
135do_eqp_test 1.9 {
drh82102332021-03-20 15:11:29 +0000136 SELECT * FROM t3 JOIN (SELECT 1 EXCEPT SELECT a FROM t3 LIMIT 17) AS abc
drh95aa47b2010-11-16 02:49:15 +0000137} {
drh03c39052018-05-02 14:24:34 +0000138 QUERY PLAN
drh82102332021-03-20 15:11:29 +0000139 |--MATERIALIZE abc
drh03c39052018-05-02 14:24:34 +0000140 | `--COMPOUND QUERY
141 | |--LEFT-MOST SUBQUERY
drhfa16f5d2018-05-03 01:37:13 +0000142 | | `--SCAN CONSTANT ROW
drh03c39052018-05-02 14:24:34 +0000143 | `--EXCEPT USING TEMP B-TREE
drh82102332021-03-20 15:11:29 +0000144 | `--SCAN t3
145 |--SCAN abc
146 `--SCAN t3
drh95aa47b2010-11-16 02:49:15 +0000147}
148do_eqp_test 1.10 {
drh82102332021-03-20 15:11:29 +0000149 SELECT * FROM t3 JOIN (SELECT 1 INTERSECT SELECT a FROM t3 LIMIT 17) AS abc
drh95aa47b2010-11-16 02:49:15 +0000150} {
drh03c39052018-05-02 14:24:34 +0000151 QUERY PLAN
drh82102332021-03-20 15:11:29 +0000152 |--MATERIALIZE abc
drh03c39052018-05-02 14:24:34 +0000153 | `--COMPOUND QUERY
154 | |--LEFT-MOST SUBQUERY
drhfa16f5d2018-05-03 01:37:13 +0000155 | | `--SCAN CONSTANT ROW
drh03c39052018-05-02 14:24:34 +0000156 | `--INTERSECT USING TEMP B-TREE
drh82102332021-03-20 15:11:29 +0000157 | `--SCAN t3
158 |--SCAN abc
159 `--SCAN t3
drh95aa47b2010-11-16 02:49:15 +0000160}
161
162do_eqp_test 1.11 {
drh82102332021-03-20 15:11:29 +0000163 SELECT * FROM t3 JOIN (SELECT 1 UNION ALL SELECT a FROM t3 LIMIT 17) abc
drh95aa47b2010-11-16 02:49:15 +0000164} {
drh03c39052018-05-02 14:24:34 +0000165 QUERY PLAN
drh82102332021-03-20 15:11:29 +0000166 |--MATERIALIZE abc
drh03c39052018-05-02 14:24:34 +0000167 | `--COMPOUND QUERY
168 | |--LEFT-MOST SUBQUERY
drhfa16f5d2018-05-03 01:37:13 +0000169 | | `--SCAN CONSTANT ROW
drh03c39052018-05-02 14:24:34 +0000170 | `--UNION ALL
drh82102332021-03-20 15:11:29 +0000171 | `--SCAN t3
172 |--SCAN abc
173 `--SCAN t3
drh95aa47b2010-11-16 02:49:15 +0000174}
175
dan2ce22452010-11-08 19:01:16 +0000176#-------------------------------------------------------------------------
177# Test cases eqp-2.* - tests for single select statements.
178#
179drop_all_tables
180do_execsql_test 2.1 {
drhd9e3cad2013-10-04 02:36:19 +0000181 CREATE TABLE t1(x INT, y INT, ex TEXT);
dan2ce22452010-11-08 19:01:16 +0000182
drhd9e3cad2013-10-04 02:36:19 +0000183 CREATE TABLE t2(x INT, y INT, ex TEXT);
dan2ce22452010-11-08 19:01:16 +0000184 CREATE INDEX t2i1 ON t2(x);
185}
186
dan4a07e3d2010-11-09 14:48:59 +0000187det 2.2.1 "SELECT DISTINCT min(x), max(x) FROM t1 GROUP BY x ORDER BY 1" {
drh03c39052018-05-02 14:24:34 +0000188 QUERY PLAN
drh82102332021-03-20 15:11:29 +0000189 |--SCAN t1
drh03c39052018-05-02 14:24:34 +0000190 |--USE TEMP B-TREE FOR GROUP BY
191 |--USE TEMP B-TREE FOR DISTINCT
192 `--USE TEMP B-TREE FOR ORDER BY
dan2ce22452010-11-08 19:01:16 +0000193}
dan4a07e3d2010-11-09 14:48:59 +0000194det 2.2.2 "SELECT DISTINCT min(x), max(x) FROM t2 GROUP BY x ORDER BY 1" {
drh03c39052018-05-02 14:24:34 +0000195 QUERY PLAN
drh82102332021-03-20 15:11:29 +0000196 |--SCAN t2 USING COVERING INDEX t2i1
drh03c39052018-05-02 14:24:34 +0000197 |--USE TEMP B-TREE FOR DISTINCT
198 `--USE TEMP B-TREE FOR ORDER BY
dan2ce22452010-11-08 19:01:16 +0000199}
dan4a07e3d2010-11-09 14:48:59 +0000200det 2.2.3 "SELECT DISTINCT * FROM t1" {
drh03c39052018-05-02 14:24:34 +0000201 QUERY PLAN
drh82102332021-03-20 15:11:29 +0000202 |--SCAN t1
drh03c39052018-05-02 14:24:34 +0000203 `--USE TEMP B-TREE FOR DISTINCT
dan4a07e3d2010-11-09 14:48:59 +0000204}
205det 2.2.4 "SELECT DISTINCT * FROM t1, t2" {
drh03c39052018-05-02 14:24:34 +0000206 QUERY PLAN
drh82102332021-03-20 15:11:29 +0000207 |--SCAN t1
208 |--SCAN t2
drh03c39052018-05-02 14:24:34 +0000209 `--USE TEMP B-TREE FOR DISTINCT
dan4a07e3d2010-11-09 14:48:59 +0000210}
211det 2.2.5 "SELECT DISTINCT * FROM t1, t2 ORDER BY t1.x" {
drh03c39052018-05-02 14:24:34 +0000212 QUERY PLAN
drh82102332021-03-20 15:11:29 +0000213 |--SCAN t1
214 |--SCAN t2
drh03c39052018-05-02 14:24:34 +0000215 |--USE TEMP B-TREE FOR DISTINCT
216 `--USE TEMP B-TREE FOR ORDER BY
dan4a07e3d2010-11-09 14:48:59 +0000217}
218det 2.2.6 "SELECT DISTINCT t2.x FROM t1, t2 ORDER BY t2.x" {
drh03c39052018-05-02 14:24:34 +0000219 QUERY PLAN
drh82102332021-03-20 15:11:29 +0000220 |--SCAN t2 USING COVERING INDEX t2i1
221 `--SCAN t1
dan4a07e3d2010-11-09 14:48:59 +0000222}
223
224det 2.3.1 "SELECT max(x) FROM t2" {
drh03c39052018-05-02 14:24:34 +0000225 QUERY PLAN
drh82102332021-03-20 15:11:29 +0000226 `--SEARCH t2 USING COVERING INDEX t2i1
dan4a07e3d2010-11-09 14:48:59 +0000227}
228det 2.3.2 "SELECT min(x) FROM t2" {
drh03c39052018-05-02 14:24:34 +0000229 QUERY PLAN
drh82102332021-03-20 15:11:29 +0000230 `--SEARCH t2 USING COVERING INDEX t2i1
dan4a07e3d2010-11-09 14:48:59 +0000231}
232det 2.3.3 "SELECT min(x), max(x) FROM t2" {
drh03c39052018-05-02 14:24:34 +0000233 QUERY PLAN
drh82102332021-03-20 15:11:29 +0000234 `--SCAN t2 USING COVERING INDEX t2i1
dan4a07e3d2010-11-09 14:48:59 +0000235}
236
237det 2.4.1 "SELECT * FROM t1 WHERE rowid=?" {
drh03c39052018-05-02 14:24:34 +0000238 QUERY PLAN
drh82102332021-03-20 15:11:29 +0000239 `--SEARCH t1 USING INTEGER PRIMARY KEY (rowid=?)
dan4a07e3d2010-11-09 14:48:59 +0000240}
241
242
dan2ce22452010-11-08 19:01:16 +0000243
244#-------------------------------------------------------------------------
245# Test cases eqp-3.* - tests for select statements that use sub-selects.
246#
247do_eqp_test 3.1.1 {
248 SELECT (SELECT x FROM t1 AS sub) FROM t1;
249} {
drh03c39052018-05-02 14:24:34 +0000250 QUERY PLAN
drh82102332021-03-20 15:11:29 +0000251 |--SCAN t1
drhbd462bc2018-12-24 20:21:06 +0000252 `--SCALAR SUBQUERY xxxxxx
drh82102332021-03-20 15:11:29 +0000253 `--SCAN sub
dan4a07e3d2010-11-09 14:48:59 +0000254}
255do_eqp_test 3.1.2 {
256 SELECT * FROM t1 WHERE (SELECT x FROM t1 AS sub);
257} {
drh03c39052018-05-02 14:24:34 +0000258 QUERY PLAN
drh82102332021-03-20 15:11:29 +0000259 |--SCAN t1
drhbd462bc2018-12-24 20:21:06 +0000260 `--SCALAR SUBQUERY xxxxxx
drh82102332021-03-20 15:11:29 +0000261 `--SCAN sub
dan4a07e3d2010-11-09 14:48:59 +0000262}
263do_eqp_test 3.1.3 {
264 SELECT * FROM t1 WHERE (SELECT x FROM t1 AS sub ORDER BY y);
265} {
drh03c39052018-05-02 14:24:34 +0000266 QUERY PLAN
drh82102332021-03-20 15:11:29 +0000267 |--SCAN t1
drhbd462bc2018-12-24 20:21:06 +0000268 `--SCALAR SUBQUERY xxxxxx
drh82102332021-03-20 15:11:29 +0000269 |--SCAN sub
drh03c39052018-05-02 14:24:34 +0000270 `--USE TEMP B-TREE FOR ORDER BY
dan4a07e3d2010-11-09 14:48:59 +0000271}
272do_eqp_test 3.1.4 {
273 SELECT * FROM t1 WHERE (SELECT x FROM t2 ORDER BY x);
274} {
drh03c39052018-05-02 14:24:34 +0000275 QUERY PLAN
drh82102332021-03-20 15:11:29 +0000276 |--SCAN t1
drhbd462bc2018-12-24 20:21:06 +0000277 `--SCALAR SUBQUERY xxxxxx
drh82102332021-03-20 15:11:29 +0000278 `--SCAN t2 USING COVERING INDEX t2i1
dan4a07e3d2010-11-09 14:48:59 +0000279}
280
281det 3.2.1 {
282 SELECT * FROM (SELECT * FROM t1 ORDER BY x LIMIT 10) ORDER BY y LIMIT 5
283} {
drh03c39052018-05-02 14:24:34 +0000284 QUERY PLAN
drhda653b82022-04-22 17:36:10 +0000285 |--CO-ROUTINE (subquery-xxxxxx)
drh82102332021-03-20 15:11:29 +0000286 | |--SCAN t1
drh03c39052018-05-02 14:24:34 +0000287 | `--USE TEMP B-TREE FOR ORDER BY
drhda653b82022-04-22 17:36:10 +0000288 |--SCAN (subquery-xxxxxx)
drh03c39052018-05-02 14:24:34 +0000289 `--USE TEMP B-TREE FOR ORDER BY
dan4a07e3d2010-11-09 14:48:59 +0000290}
291det 3.2.2 {
292 SELECT * FROM
293 (SELECT * FROM t1 ORDER BY x LIMIT 10) AS x1,
294 (SELECT * FROM t2 ORDER BY x LIMIT 10) AS x2
295 ORDER BY x2.y LIMIT 5
296} {
drh03c39052018-05-02 14:24:34 +0000297 QUERY PLAN
drh82102332021-03-20 15:11:29 +0000298 |--MATERIALIZE x1
299 | |--SCAN t1
drh03c39052018-05-02 14:24:34 +0000300 | `--USE TEMP B-TREE FOR ORDER BY
drh82102332021-03-20 15:11:29 +0000301 |--MATERIALIZE x2
302 | `--SCAN t2 USING INDEX t2i1
303 |--SCAN x1
304 |--SCAN x2
drh03c39052018-05-02 14:24:34 +0000305 `--USE TEMP B-TREE FOR ORDER BY
dan2ce22452010-11-08 19:01:16 +0000306}
307
dan47eb16d2010-11-11 10:36:25 +0000308det 3.3.1 {
309 SELECT * FROM t1 WHERE y IN (SELECT y FROM t2)
310} {
drh03c39052018-05-02 14:24:34 +0000311 QUERY PLAN
drh82102332021-03-20 15:11:29 +0000312 |--SCAN t1
drh5198ff52018-12-24 12:09:47 +0000313 `--LIST SUBQUERY xxxxxx
drh82102332021-03-20 15:11:29 +0000314 `--SCAN t2
dan47eb16d2010-11-11 10:36:25 +0000315}
316det 3.3.2 {
317 SELECT * FROM t1 WHERE y IN (SELECT y FROM t2 WHERE t1.x!=t2.x)
318} {
drh03c39052018-05-02 14:24:34 +0000319 QUERY PLAN
drh82102332021-03-20 15:11:29 +0000320 |--SCAN t1
drh5198ff52018-12-24 12:09:47 +0000321 `--CORRELATED LIST SUBQUERY xxxxxx
drh82102332021-03-20 15:11:29 +0000322 `--SCAN t2
dan47eb16d2010-11-11 10:36:25 +0000323}
324det 3.3.3 {
325 SELECT * FROM t1 WHERE EXISTS (SELECT y FROM t2 WHERE t1.x!=t2.x)
326} {
drh03c39052018-05-02 14:24:34 +0000327 QUERY PLAN
drh82102332021-03-20 15:11:29 +0000328 |--SCAN t1
drhbd462bc2018-12-24 20:21:06 +0000329 `--CORRELATED SCALAR SUBQUERY xxxxxx
drh82102332021-03-20 15:11:29 +0000330 `--SCAN t2
dan47eb16d2010-11-11 10:36:25 +0000331}
332
dan2ce22452010-11-08 19:01:16 +0000333#-------------------------------------------------------------------------
dan4a07e3d2010-11-09 14:48:59 +0000334# Test cases eqp-4.* - tests for composite select statements.
dan2ce22452010-11-08 19:01:16 +0000335#
336do_eqp_test 4.1.1 {
337 SELECT * FROM t1 UNION ALL SELECT * FROM t2
338} {
drh03c39052018-05-02 14:24:34 +0000339 QUERY PLAN
340 `--COMPOUND QUERY
341 |--LEFT-MOST SUBQUERY
drh82102332021-03-20 15:11:29 +0000342 | `--SCAN t1
drh03c39052018-05-02 14:24:34 +0000343 `--UNION ALL
drh82102332021-03-20 15:11:29 +0000344 `--SCAN t2
dan2ce22452010-11-08 19:01:16 +0000345}
346do_eqp_test 4.1.2 {
347 SELECT * FROM t1 UNION ALL SELECT * FROM t2 ORDER BY 2
348} {
drh03c39052018-05-02 14:24:34 +0000349 QUERY PLAN
350 `--MERGE (UNION ALL)
351 |--LEFT
drh82102332021-03-20 15:11:29 +0000352 | |--SCAN t1
drh03c39052018-05-02 14:24:34 +0000353 | `--USE TEMP B-TREE FOR ORDER BY
354 `--RIGHT
drh82102332021-03-20 15:11:29 +0000355 |--SCAN t2
drh03c39052018-05-02 14:24:34 +0000356 `--USE TEMP B-TREE FOR ORDER BY
dan2ce22452010-11-08 19:01:16 +0000357}
358do_eqp_test 4.1.3 {
359 SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY 2
360} {
drh03c39052018-05-02 14:24:34 +0000361 QUERY PLAN
362 `--MERGE (UNION)
363 |--LEFT
drh82102332021-03-20 15:11:29 +0000364 | |--SCAN t1
drh03c39052018-05-02 14:24:34 +0000365 | `--USE TEMP B-TREE FOR ORDER BY
366 `--RIGHT
drh82102332021-03-20 15:11:29 +0000367 |--SCAN t2
drh03c39052018-05-02 14:24:34 +0000368 `--USE TEMP B-TREE FOR ORDER BY
dan2ce22452010-11-08 19:01:16 +0000369}
370do_eqp_test 4.1.4 {
371 SELECT * FROM t1 INTERSECT SELECT * FROM t2 ORDER BY 2
372} {
drh03c39052018-05-02 14:24:34 +0000373 QUERY PLAN
374 `--MERGE (INTERSECT)
375 |--LEFT
drh82102332021-03-20 15:11:29 +0000376 | |--SCAN t1
drh03c39052018-05-02 14:24:34 +0000377 | `--USE TEMP B-TREE FOR ORDER BY
378 `--RIGHT
drh82102332021-03-20 15:11:29 +0000379 |--SCAN t2
drh03c39052018-05-02 14:24:34 +0000380 `--USE TEMP B-TREE FOR ORDER BY
dan2ce22452010-11-08 19:01:16 +0000381}
382do_eqp_test 4.1.5 {
383 SELECT * FROM t1 EXCEPT SELECT * FROM t2 ORDER BY 2
384} {
drh03c39052018-05-02 14:24:34 +0000385 QUERY PLAN
386 `--MERGE (EXCEPT)
387 |--LEFT
drh82102332021-03-20 15:11:29 +0000388 | |--SCAN t1
drh03c39052018-05-02 14:24:34 +0000389 | `--USE TEMP B-TREE FOR ORDER BY
390 `--RIGHT
drh82102332021-03-20 15:11:29 +0000391 |--SCAN t2
drh03c39052018-05-02 14:24:34 +0000392 `--USE TEMP B-TREE FOR ORDER BY
dan2ce22452010-11-08 19:01:16 +0000393}
394
395do_eqp_test 4.2.2 {
396 SELECT * FROM t1 UNION ALL SELECT * FROM t2 ORDER BY 1
397} {
drh03c39052018-05-02 14:24:34 +0000398 QUERY PLAN
399 `--MERGE (UNION ALL)
400 |--LEFT
drh82102332021-03-20 15:11:29 +0000401 | |--SCAN t1
drh03c39052018-05-02 14:24:34 +0000402 | `--USE TEMP B-TREE FOR ORDER BY
403 `--RIGHT
drh82102332021-03-20 15:11:29 +0000404 `--SCAN t2 USING INDEX t2i1
dan2ce22452010-11-08 19:01:16 +0000405}
dan2ce22452010-11-08 19:01:16 +0000406do_eqp_test 4.2.3 {
407 SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY 1
408} {
drh03c39052018-05-02 14:24:34 +0000409 QUERY PLAN
410 `--MERGE (UNION)
411 |--LEFT
drh82102332021-03-20 15:11:29 +0000412 | |--SCAN t1
drh03c39052018-05-02 14:24:34 +0000413 | `--USE TEMP B-TREE FOR ORDER BY
414 `--RIGHT
drh82102332021-03-20 15:11:29 +0000415 |--SCAN t2 USING INDEX t2i1
drh03c39052018-05-02 14:24:34 +0000416 `--USE TEMP B-TREE FOR RIGHT PART OF ORDER BY
dan2ce22452010-11-08 19:01:16 +0000417}
418do_eqp_test 4.2.4 {
419 SELECT * FROM t1 INTERSECT SELECT * FROM t2 ORDER BY 1
420} {
drh03c39052018-05-02 14:24:34 +0000421 QUERY PLAN
422 `--MERGE (INTERSECT)
423 |--LEFT
drh82102332021-03-20 15:11:29 +0000424 | |--SCAN t1
drh03c39052018-05-02 14:24:34 +0000425 | `--USE TEMP B-TREE FOR ORDER BY
426 `--RIGHT
drh82102332021-03-20 15:11:29 +0000427 |--SCAN t2 USING INDEX t2i1
drh03c39052018-05-02 14:24:34 +0000428 `--USE TEMP B-TREE FOR RIGHT PART OF ORDER BY
dan2ce22452010-11-08 19:01:16 +0000429}
430do_eqp_test 4.2.5 {
431 SELECT * FROM t1 EXCEPT SELECT * FROM t2 ORDER BY 1
432} {
drh03c39052018-05-02 14:24:34 +0000433 QUERY PLAN
434 `--MERGE (EXCEPT)
435 |--LEFT
drh82102332021-03-20 15:11:29 +0000436 | |--SCAN t1
drh03c39052018-05-02 14:24:34 +0000437 | `--USE TEMP B-TREE FOR ORDER BY
438 `--RIGHT
drh82102332021-03-20 15:11:29 +0000439 |--SCAN t2 USING INDEX t2i1
drh03c39052018-05-02 14:24:34 +0000440 `--USE TEMP B-TREE FOR RIGHT PART OF ORDER BY
dan2ce22452010-11-08 19:01:16 +0000441}
442
dan4a07e3d2010-11-09 14:48:59 +0000443do_eqp_test 4.3.1 {
444 SELECT x FROM t1 UNION SELECT x FROM t2
445} {
drh03c39052018-05-02 14:24:34 +0000446 QUERY PLAN
447 `--COMPOUND QUERY
448 |--LEFT-MOST SUBQUERY
drh82102332021-03-20 15:11:29 +0000449 | `--SCAN t1
drh03c39052018-05-02 14:24:34 +0000450 `--UNION USING TEMP B-TREE
drh82102332021-03-20 15:11:29 +0000451 `--SCAN t2 USING COVERING INDEX t2i1
dan7f61e922010-11-11 16:46:40 +0000452}
453
454do_eqp_test 4.3.2 {
455 SELECT x FROM t1 UNION SELECT x FROM t2 UNION SELECT x FROM t1
456} {
drh03c39052018-05-02 14:24:34 +0000457 QUERY PLAN
458 `--COMPOUND QUERY
459 |--LEFT-MOST SUBQUERY
drh82102332021-03-20 15:11:29 +0000460 | `--SCAN t1
drh03c39052018-05-02 14:24:34 +0000461 |--UNION USING TEMP B-TREE
drh82102332021-03-20 15:11:29 +0000462 | `--SCAN t2 USING COVERING INDEX t2i1
drh03c39052018-05-02 14:24:34 +0000463 `--UNION USING TEMP B-TREE
drh82102332021-03-20 15:11:29 +0000464 `--SCAN t1
dan7f61e922010-11-11 16:46:40 +0000465}
466do_eqp_test 4.3.3 {
467 SELECT x FROM t1 UNION SELECT x FROM t2 UNION SELECT x FROM t1 ORDER BY 1
468} {
drh03c39052018-05-02 14:24:34 +0000469 QUERY PLAN
470 `--MERGE (UNION)
471 |--LEFT
472 | `--MERGE (UNION)
473 | |--LEFT
drh82102332021-03-20 15:11:29 +0000474 | | |--SCAN t1
drh03c39052018-05-02 14:24:34 +0000475 | | `--USE TEMP B-TREE FOR ORDER BY
476 | `--RIGHT
drh82102332021-03-20 15:11:29 +0000477 | `--SCAN t2 USING COVERING INDEX t2i1
drh03c39052018-05-02 14:24:34 +0000478 `--RIGHT
drh82102332021-03-20 15:11:29 +0000479 |--SCAN t1
drh03c39052018-05-02 14:24:34 +0000480 `--USE TEMP B-TREE FOR ORDER BY
dan4a07e3d2010-11-09 14:48:59 +0000481}
dan2ce22452010-11-08 19:01:16 +0000482
drh03c39052018-05-02 14:24:34 +0000483if 0 {
danfa00aa22010-11-12 17:41:37 +0000484#-------------------------------------------------------------------------
485# This next block of tests verifies that the examples on the
486# lang_explain.html page are correct.
487#
488drop_all_tables
489
drh03c39052018-05-02 14:24:34 +0000490# XVIDENCE-OF: R-47779-47605 sqlite> EXPLAIN QUERY PLAN SELECT a, b
drh39759742013-08-02 23:40:45 +0000491# FROM t1 WHERE a=1;
drh82102332021-03-20 15:11:29 +0000492# 0|0|0|SCAN t1
drh39759742013-08-02 23:40:45 +0000493#
drhd9e3cad2013-10-04 02:36:19 +0000494do_execsql_test 5.1.0 { CREATE TABLE t1(a INT, b INT, ex TEXT) }
danfa00aa22010-11-12 17:41:37 +0000495det 5.1.1 "SELECT a, b FROM t1 WHERE a=1" {
drh82102332021-03-20 15:11:29 +0000496 0 0 0 {SCAN t1}
danfa00aa22010-11-12 17:41:37 +0000497}
498
drh03c39052018-05-02 14:24:34 +0000499# XVIDENCE-OF: R-55852-17599 sqlite> CREATE INDEX i1 ON t1(a);
danfa00aa22010-11-12 17:41:37 +0000500# sqlite> EXPLAIN QUERY PLAN SELECT a, b FROM t1 WHERE a=1;
drh82102332021-03-20 15:11:29 +0000501# 0|0|0|SEARCH t1 USING INDEX i1
drh39759742013-08-02 23:40:45 +0000502#
danfa00aa22010-11-12 17:41:37 +0000503do_execsql_test 5.2.0 { CREATE INDEX i1 ON t1(a) }
504det 5.2.1 "SELECT a, b FROM t1 WHERE a=1" {
drh82102332021-03-20 15:11:29 +0000505 0 0 0 {SEARCH t1 USING INDEX i1 (a=?)}
danfa00aa22010-11-12 17:41:37 +0000506}
507
drh03c39052018-05-02 14:24:34 +0000508# XVIDENCE-OF: R-21179-11011 sqlite> CREATE INDEX i2 ON t1(a, b);
danfa00aa22010-11-12 17:41:37 +0000509# sqlite> EXPLAIN QUERY PLAN SELECT a, b FROM t1 WHERE a=1;
drh82102332021-03-20 15:11:29 +0000510# 0|0|0|SEARCH t1 USING COVERING INDEX i2 (a=?)
drh39759742013-08-02 23:40:45 +0000511#
danfa00aa22010-11-12 17:41:37 +0000512do_execsql_test 5.3.0 { CREATE INDEX i2 ON t1(a, b) }
513det 5.3.1 "SELECT a, b FROM t1 WHERE a=1" {
drh82102332021-03-20 15:11:29 +0000514 0 0 0 {SEARCH t1 USING COVERING INDEX i2 (a=?)}
danfa00aa22010-11-12 17:41:37 +0000515}
516
drh03c39052018-05-02 14:24:34 +0000517# XVIDENCE-OF: R-09991-48941 sqlite> EXPLAIN QUERY PLAN
drh39759742013-08-02 23:40:45 +0000518# SELECT t1.*, t2.* FROM t1, t2 WHERE t1.a=1 AND t1.b>2;
drh82102332021-03-20 15:11:29 +0000519# 0|0|0|SEARCH t1 USING COVERING INDEX i2 (a=? AND b>?)
520# 0|1|1|SCAN t2
drh5822d6f2013-06-10 23:30:09 +0000521#
drhd9e3cad2013-10-04 02:36:19 +0000522do_execsql_test 5.4.0 {CREATE TABLE t2(c INT, d INT, ex TEXT)}
523det 5.4.1 "SELECT t1.a, t2.c FROM t1, t2 WHERE t1.a=1 AND t1.b>2" {
drh82102332021-03-20 15:11:29 +0000524 0 0 0 {SEARCH t1 USING COVERING INDEX i2 (a=? AND b>?)}
525 0 1 1 {SCAN t2}
danfa00aa22010-11-12 17:41:37 +0000526}
527
drh03c39052018-05-02 14:24:34 +0000528# XVIDENCE-OF: R-33626-61085 sqlite> EXPLAIN QUERY PLAN
drh39759742013-08-02 23:40:45 +0000529# SELECT t1.*, t2.* FROM t2, t1 WHERE t1.a=1 AND t1.b>2;
drh82102332021-03-20 15:11:29 +0000530# 0|0|1|SEARCH t1 USING COVERING INDEX i2 (a=? AND b>?)
531# 0|1|0|SCAN t2
drh5822d6f2013-06-10 23:30:09 +0000532#
drhd9e3cad2013-10-04 02:36:19 +0000533det 5.5 "SELECT t1.a, t2.c FROM t2, t1 WHERE t1.a=1 AND t1.b>2" {
drh82102332021-03-20 15:11:29 +0000534 0 0 1 {SEARCH t1 USING COVERING INDEX i2 (a=? AND b>?)}
535 0 1 0 {SCAN t2}
danfa00aa22010-11-12 17:41:37 +0000536}
537
drh03c39052018-05-02 14:24:34 +0000538# XVIDENCE-OF: R-04002-25654 sqlite> CREATE INDEX i3 ON t1(b);
danfa00aa22010-11-12 17:41:37 +0000539# sqlite> EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=1 OR b=2;
drh82102332021-03-20 15:11:29 +0000540# 0|0|0|SEARCH t1 USING COVERING INDEX i2 (a=?)
541# 0|0|0|SEARCH t1 USING INDEX i3 (b=?)
drh39759742013-08-02 23:40:45 +0000542#
danfa00aa22010-11-12 17:41:37 +0000543do_execsql_test 5.5.0 {CREATE INDEX i3 ON t1(b)}
drhd9e3cad2013-10-04 02:36:19 +0000544det 5.6.1 "SELECT a, b FROM t1 WHERE a=1 OR b=2" {
drh82102332021-03-20 15:11:29 +0000545 0 0 0 {SEARCH t1 USING COVERING INDEX i2 (a=?)}
546 0 0 0 {SEARCH t1 USING INDEX i3 (b=?)}
danfa00aa22010-11-12 17:41:37 +0000547}
548
drh03c39052018-05-02 14:24:34 +0000549# XVIDENCE-OF: R-24577-38891 sqlite> EXPLAIN QUERY PLAN
drh39759742013-08-02 23:40:45 +0000550# SELECT c, d FROM t2 ORDER BY c;
drh82102332021-03-20 15:11:29 +0000551# 0|0|0|SCAN t2
drh39759742013-08-02 23:40:45 +0000552# 0|0|0|USE TEMP B-TREE FOR ORDER BY
553#
danfa00aa22010-11-12 17:41:37 +0000554det 5.7 "SELECT c, d FROM t2 ORDER BY c" {
drh82102332021-03-20 15:11:29 +0000555 0 0 0 {SCAN t2}
danfa00aa22010-11-12 17:41:37 +0000556 0 0 0 {USE TEMP B-TREE FOR ORDER BY}
557}
558
drh03c39052018-05-02 14:24:34 +0000559# XVIDENCE-OF: R-58157-12355 sqlite> CREATE INDEX i4 ON t2(c);
danfa00aa22010-11-12 17:41:37 +0000560# sqlite> EXPLAIN QUERY PLAN SELECT c, d FROM t2 ORDER BY c;
drh82102332021-03-20 15:11:29 +0000561# 0|0|0|SCAN t2 USING INDEX i4
drh39759742013-08-02 23:40:45 +0000562#
danfa00aa22010-11-12 17:41:37 +0000563do_execsql_test 5.8.0 {CREATE INDEX i4 ON t2(c)}
564det 5.8.1 "SELECT c, d FROM t2 ORDER BY c" {
drh82102332021-03-20 15:11:29 +0000565 0 0 0 {SCAN t2 USING INDEX i4}
danfa00aa22010-11-12 17:41:37 +0000566}
567
drh03c39052018-05-02 14:24:34 +0000568# XVIDENCE-OF: R-13931-10421 sqlite> EXPLAIN QUERY PLAN SELECT
danfa00aa22010-11-12 17:41:37 +0000569# (SELECT b FROM t1 WHERE a=0), (SELECT a FROM t1 WHERE b=t2.c) FROM t2;
drh82102332021-03-20 15:11:29 +0000570# 0|0|0|SCAN t2
drh39759742013-08-02 23:40:45 +0000571# 0|0|0|EXECUTE SCALAR SUBQUERY 1
drh82102332021-03-20 15:11:29 +0000572# 1|0|0|SEARCH t1 USING COVERING INDEX i2 (a=?)
drh39759742013-08-02 23:40:45 +0000573# 0|0|0|EXECUTE CORRELATED SCALAR SUBQUERY 2
drh82102332021-03-20 15:11:29 +0000574# 2|0|0|SEARCH t1 USING INDEX i3 (b=?)
drh39759742013-08-02 23:40:45 +0000575#
danfa00aa22010-11-12 17:41:37 +0000576det 5.9 {
577 SELECT (SELECT b FROM t1 WHERE a=0), (SELECT a FROM t1 WHERE b=t2.c) FROM t2
578} {
drh82102332021-03-20 15:11:29 +0000579 0 0 0 {SCAN t2 USING COVERING INDEX i4}
danfa00aa22010-11-12 17:41:37 +0000580 0 0 0 {EXECUTE SCALAR SUBQUERY 1}
drh82102332021-03-20 15:11:29 +0000581 1 0 0 {SEARCH t1 USING COVERING INDEX i2 (a=?)}
danfa00aa22010-11-12 17:41:37 +0000582 0 0 0 {EXECUTE CORRELATED SCALAR SUBQUERY 2}
drh82102332021-03-20 15:11:29 +0000583 2 0 0 {SEARCH t1 USING INDEX i3 (b=?)}
danfa00aa22010-11-12 17:41:37 +0000584}
585
drh03c39052018-05-02 14:24:34 +0000586# XVIDENCE-OF: R-50892-45943 sqlite> EXPLAIN QUERY PLAN
drh39759742013-08-02 23:40:45 +0000587# SELECT count(*) FROM (SELECT max(b) AS x FROM t1 GROUP BY a) GROUP BY x;
drh82102332021-03-20 15:11:29 +0000588# 1|0|0|SCAN t1 USING COVERING INDEX i2
drh39759742013-08-02 23:40:45 +0000589# 0|0|0|SCAN SUBQUERY 1
590# 0|0|0|USE TEMP B-TREE FOR GROUP BY
591#
danfa00aa22010-11-12 17:41:37 +0000592det 5.10 {
593 SELECT count(*) FROM (SELECT max(b) AS x FROM t1 GROUP BY a) GROUP BY x
594} {
drh82102332021-03-20 15:11:29 +0000595 1 0 0 {SCAN t1 USING COVERING INDEX i2}
drh5822d6f2013-06-10 23:30:09 +0000596 0 0 0 {SCAN SUBQUERY 1}
danfa00aa22010-11-12 17:41:37 +0000597 0 0 0 {USE TEMP B-TREE FOR GROUP BY}
598}
599
drh03c39052018-05-02 14:24:34 +0000600# XVIDENCE-OF: R-46219-33846 sqlite> EXPLAIN QUERY PLAN
drh39759742013-08-02 23:40:45 +0000601# SELECT * FROM (SELECT * FROM t2 WHERE c=1), t1;
drh82102332021-03-20 15:11:29 +0000602# 0|0|0|SEARCH t2 USING INDEX i4 (c=?)
603# 0|1|1|SCAN t1
drh39759742013-08-02 23:40:45 +0000604#
drhd9e3cad2013-10-04 02:36:19 +0000605det 5.11 "SELECT a, b FROM (SELECT * FROM t2 WHERE c=1), t1" {
drh82102332021-03-20 15:11:29 +0000606 0 0 0 {SEARCH t2 USING INDEX i4 (c=?)}
607 0 1 1 {SCAN t1 USING COVERING INDEX i2}
danfa00aa22010-11-12 17:41:37 +0000608}
609
drh03c39052018-05-02 14:24:34 +0000610# XVIDENCE-OF: R-37879-39987 sqlite> EXPLAIN QUERY PLAN
drh39759742013-08-02 23:40:45 +0000611# SELECT a FROM t1 UNION SELECT c FROM t2;
drh82102332021-03-20 15:11:29 +0000612# 1|0|0|SCAN t1
613# 2|0|0|SCAN t2
drh39759742013-08-02 23:40:45 +0000614# 0|0|0|COMPOUND SUBQUERIES 1 AND 2 USING TEMP B-TREE (UNION)
615#
drh165674d2013-10-04 15:58:59 +0000616det 5.12 "SELECT a,b FROM t1 UNION SELECT c, 99 FROM t2" {
drh82102332021-03-20 15:11:29 +0000617 1 0 0 {SCAN t1 USING COVERING INDEX i2}
618 2 0 0 {SCAN t2 USING COVERING INDEX i4}
danfa00aa22010-11-12 17:41:37 +0000619 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 USING TEMP B-TREE (UNION)}
620}
621
drh03c39052018-05-02 14:24:34 +0000622# XVIDENCE-OF: R-44864-63011 sqlite> EXPLAIN QUERY PLAN
drh39759742013-08-02 23:40:45 +0000623# SELECT a FROM t1 EXCEPT SELECT d FROM t2 ORDER BY 1;
drh82102332021-03-20 15:11:29 +0000624# 1|0|0|SCAN t1 USING COVERING INDEX i2
625# 2|0|0|SCAN t2 2|0|0|USE TEMP B-TREE FOR ORDER BY
drh39759742013-08-02 23:40:45 +0000626# 0|0|0|COMPOUND SUBQUERIES 1 AND 2 (EXCEPT)
627#
danfa00aa22010-11-12 17:41:37 +0000628det 5.13 "SELECT a FROM t1 EXCEPT SELECT d FROM t2 ORDER BY 1" {
drh82102332021-03-20 15:11:29 +0000629 1 0 0 {SCAN t1 USING COVERING INDEX i1}
630 2 0 0 {SCAN t2}
danfa00aa22010-11-12 17:41:37 +0000631 2 0 0 {USE TEMP B-TREE FOR ORDER BY}
632 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (EXCEPT)}
633}
634
drhaf3906a2016-03-14 17:05:04 +0000635if {![nonzero_reserved_bytes]} {
636 #-------------------------------------------------------------------------
637 # The following tests - eqp-6.* - test that the example C code on
638 # documentation page eqp.html works. The C code is duplicated in test1.c
639 # and wrapped in Tcl command [print_explain_query_plan]
640 #
641 set boilerplate {
642 proc explain_query_plan {db sql} {
643 set stmt [sqlite3_prepare_v2 db $sql -1 DUMMY]
644 print_explain_query_plan $stmt
645 sqlite3_finalize $stmt
646 }
647 sqlite3 db test.db
648 explain_query_plan db {%SQL%}
649 db close
650 exit
dan91da6b82010-11-15 14:51:33 +0000651 }
drhaf3906a2016-03-14 17:05:04 +0000652
653 # Do a "Print Explain Query Plan" test.
654 proc do_peqp_test {tn sql res} {
655 set fd [open script.tcl w]
656 puts $fd [string map [list %SQL% $sql] $::boilerplate]
dan91da6b82010-11-15 14:51:33 +0000657 close $fd
drhaf3906a2016-03-14 17:05:04 +0000658
659 uplevel do_test $tn [list {
660 set fd [open "|[info nameofexec] script.tcl"]
661 set data [read $fd]
662 close $fd
663 set data
664 }] [list $res]
665 }
666
667 do_peqp_test 6.1 {
668 SELECT a, b FROM t1 EXCEPT SELECT d, 99 FROM t2 ORDER BY 1
669 } [string trimleft {
drh82102332021-03-20 15:11:29 +00006701 0 0 SCAN t1 USING COVERING INDEX i2
6712 0 0 SCAN t2
dan91da6b82010-11-15 14:51:33 +00006722 0 0 USE TEMP B-TREE FOR ORDER BY
6730 0 0 COMPOUND SUBQUERIES 1 AND 2 (EXCEPT)
674}]
drhaf3906a2016-03-14 17:05:04 +0000675}
drh03c39052018-05-02 14:24:34 +0000676}
dan91da6b82010-11-15 14:51:33 +0000677
danef7075d2011-02-21 17:49:49 +0000678#-------------------------------------------------------------------------
679# The following tests - eqp-7.* - test that queries that use the OP_Count
680# optimization return something sensible with EQP.
681#
682drop_all_tables
danfa00aa22010-11-12 17:41:37 +0000683
danef7075d2011-02-21 17:49:49 +0000684do_execsql_test 7.0 {
drh165674d2013-10-04 15:58:59 +0000685 CREATE TABLE t1(a INT, b INT, ex CHAR(100));
686 CREATE TABLE t2(a INT, b INT, ex CHAR(100));
danef7075d2011-02-21 17:49:49 +0000687 CREATE INDEX i1 ON t2(a);
688}
689
690det 7.1 "SELECT count(*) FROM t1" {
drh03c39052018-05-02 14:24:34 +0000691 QUERY PLAN
drh82102332021-03-20 15:11:29 +0000692 `--SCAN t1
danef7075d2011-02-21 17:49:49 +0000693}
694
695det 7.2 "SELECT count(*) FROM t2" {
drh03c39052018-05-02 14:24:34 +0000696 QUERY PLAN
drh82102332021-03-20 15:11:29 +0000697 `--SCAN t2 USING COVERING INDEX i1
danef7075d2011-02-21 17:49:49 +0000698}
699
700do_execsql_test 7.3 {
drh165674d2013-10-04 15:58:59 +0000701 INSERT INTO t1(a,b) VALUES(1, 2);
702 INSERT INTO t1(a,b) VALUES(3, 4);
danef7075d2011-02-21 17:49:49 +0000703
drh165674d2013-10-04 15:58:59 +0000704 INSERT INTO t2(a,b) VALUES(1, 2);
705 INSERT INTO t2(a,b) VALUES(3, 4);
706 INSERT INTO t2(a,b) VALUES(5, 6);
danef7075d2011-02-21 17:49:49 +0000707
708 ANALYZE;
709}
710
711db close
712sqlite3 db test.db
713
714det 7.4 "SELECT count(*) FROM t1" {
drh03c39052018-05-02 14:24:34 +0000715 QUERY PLAN
drh82102332021-03-20 15:11:29 +0000716 `--SCAN t1
danef7075d2011-02-21 17:49:49 +0000717}
718
719det 7.5 "SELECT count(*) FROM t2" {
drh03c39052018-05-02 14:24:34 +0000720 QUERY PLAN
drh82102332021-03-20 15:11:29 +0000721 `--SCAN t2 USING COVERING INDEX i1
danef7075d2011-02-21 17:49:49 +0000722}
danfa00aa22010-11-12 17:41:37 +0000723
dane96f2df2014-05-23 17:17:06 +0000724#-------------------------------------------------------------------------
725# The following tests - eqp-8.* - test that queries that use the OP_Count
726# optimization return something sensible with EQP.
727#
728drop_all_tables
729
730do_execsql_test 8.0 {
731 CREATE TABLE t1(a, b, c, PRIMARY KEY(b, c)) WITHOUT ROWID;
732 CREATE TABLE t2(a, b, c);
733}
734
735det 8.1.1 "SELECT * FROM t2" {
drh03c39052018-05-02 14:24:34 +0000736 QUERY PLAN
drh82102332021-03-20 15:11:29 +0000737 `--SCAN t2
dane96f2df2014-05-23 17:17:06 +0000738}
739
740det 8.1.2 "SELECT * FROM t2 WHERE rowid=?" {
drh03c39052018-05-02 14:24:34 +0000741 QUERY PLAN
drh82102332021-03-20 15:11:29 +0000742 `--SEARCH t2 USING INTEGER PRIMARY KEY (rowid=?)
dane96f2df2014-05-23 17:17:06 +0000743}
744
745det 8.1.3 "SELECT count(*) FROM t2" {
drh03c39052018-05-02 14:24:34 +0000746 QUERY PLAN
drh82102332021-03-20 15:11:29 +0000747 `--SCAN t2
dane96f2df2014-05-23 17:17:06 +0000748}
749
750det 8.2.1 "SELECT * FROM t1" {
drh03c39052018-05-02 14:24:34 +0000751 QUERY PLAN
drh82102332021-03-20 15:11:29 +0000752 `--SCAN t1
dane96f2df2014-05-23 17:17:06 +0000753}
754
755det 8.2.2 "SELECT * FROM t1 WHERE b=?" {
drh03c39052018-05-02 14:24:34 +0000756 QUERY PLAN
drh82102332021-03-20 15:11:29 +0000757 `--SEARCH t1 USING PRIMARY KEY (b=?)
dane96f2df2014-05-23 17:17:06 +0000758}
759
760det 8.2.3 "SELECT * FROM t1 WHERE b=? AND c=?" {
drh03c39052018-05-02 14:24:34 +0000761 QUERY PLAN
drh82102332021-03-20 15:11:29 +0000762 `--SEARCH t1 USING PRIMARY KEY (b=? AND c=?)
dane96f2df2014-05-23 17:17:06 +0000763}
764
765det 8.2.4 "SELECT count(*) FROM t1" {
drh03c39052018-05-02 14:24:34 +0000766 QUERY PLAN
drh82102332021-03-20 15:11:29 +0000767 `--SCAN t1
dane96f2df2014-05-23 17:17:06 +0000768}
769
drhd8852092018-08-16 15:29:40 +0000770# 2018-08-16: While working on Fossil I discovered that EXPLAIN QUERY PLAN
771# did not describe IN operators implemented using a ROWID lookup. These
772# test cases ensure that problem as been fixed.
773#
774do_execsql_test 9.0 {
775 -- Schema from Fossil 2018-08-16
776 CREATE TABLE forumpost(
777 fpid INTEGER PRIMARY KEY,
778 froot INT,
779 fprev INT,
780 firt INT,
781 fmtime REAL
782 );
783 CREATE INDEX forumthread ON forumpost(froot,fmtime);
784 CREATE TABLE blob(
785 rid INTEGER PRIMARY KEY,
786 rcvid INTEGER,
787 size INTEGER,
788 uuid TEXT UNIQUE NOT NULL,
789 content BLOB,
790 CHECK( length(uuid)>=40 AND rid>0 )
791 );
792 CREATE TABLE event(
793 type TEXT,
794 mtime DATETIME,
795 objid INTEGER PRIMARY KEY,
796 tagid INTEGER,
797 uid INTEGER REFERENCES user,
798 bgcolor TEXT,
799 euser TEXT,
800 user TEXT,
801 ecomment TEXT,
802 comment TEXT,
803 brief TEXT,
804 omtime DATETIME
805 );
806 CREATE INDEX event_i1 ON event(mtime);
807 CREATE TABLE private(rid INTEGER PRIMARY KEY);
808}
809do_eqp_test 9.1 {
810 WITH thread(age,duration,cnt,root,last) AS (
811 SELECT
812 julianday('now') - max(fmtime) AS age,
813 max(fmtime) - min(fmtime) AS duration,
814 sum(fprev IS NULL) AS msg_count,
815 froot,
816 (SELECT fpid FROM forumpost
817 WHERE froot=x.froot
818 AND fpid NOT IN private
819 ORDER BY fmtime DESC LIMIT 1)
820 FROM forumpost AS x
821 WHERE fpid NOT IN private --- Ensure this table mentioned in EQP output!
822 GROUP BY froot
823 ORDER BY 1 LIMIT 26 OFFSET 5
824 )
825 SELECT
826 thread.age,
827 thread.duration,
828 thread.cnt,
829 blob.uuid,
830 substr(event.comment,instr(event.comment,':')+1)
831 FROM thread, blob, event
832 WHERE blob.rid=thread.last
833 AND event.objid=thread.last
834 ORDER BY 1;
835} {
836 QUERY PLAN
drh82102332021-03-20 15:11:29 +0000837 |--MATERIALIZE thread
838 | |--SCAN x USING INDEX forumthread
drhd8852092018-08-16 15:29:40 +0000839 | |--USING ROWID SEARCH ON TABLE private FOR IN-OPERATOR
drhbd462bc2018-12-24 20:21:06 +0000840 | |--CORRELATED SCALAR SUBQUERY xxxxxx
drh82102332021-03-20 15:11:29 +0000841 | | |--SEARCH forumpost USING COVERING INDEX forumthread (froot=?)
drhd8852092018-08-16 15:29:40 +0000842 | | `--USING ROWID SEARCH ON TABLE private FOR IN-OPERATOR
843 | `--USE TEMP B-TREE FOR ORDER BY
drh82102332021-03-20 15:11:29 +0000844 |--SCAN thread
845 |--SEARCH blob USING INTEGER PRIMARY KEY (rowid=?)
846 |--SEARCH event USING INTEGER PRIMARY KEY (rowid=?)
drhd8852092018-08-16 15:29:40 +0000847 `--USE TEMP B-TREE FOR ORDER BY
848}
danfa00aa22010-11-12 17:41:37 +0000849
dan2ce22452010-11-08 19:01:16 +0000850finish_test