1# 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 16set testprefix eqp 17 18#------------------------------------------------------------------------- 19# 20# eqp-1.*: Assorted tests. 21# eqp-2.*: Tests for single select statements. 22# eqp-3.*: Select statements that execute sub-selects. 23# eqp-4.*: Compound select statements. 24# ... 25# eqp-7.*: "SELECT count(*) FROM tbl" statements (VDBE code OP_Count). 26# 27 28proc det {args} { uplevel do_eqp_test $args } 29 30do_execsql_test 1.1 { 31 CREATE TABLE t1(a, b); 32 CREATE INDEX i1 ON t1(a); 33 CREATE INDEX i2 ON t1(b); 34 CREATE TABLE t2(a, b); 35 CREATE TABLE t3(a, b); 36} 37 38do_eqp_test 1.2 { 39 SELECT * FROM t2, t1 WHERE t1.a=1 OR t1.b=2; 40} { 41 0 0 1 {SEARCH TABLE t1 USING INDEX i1 (a=?) (~10 rows)} 42 0 0 1 {SEARCH TABLE t1 USING INDEX i2 (b=?) (~10 rows)} 43 0 1 0 {SCAN TABLE t2 (~1000000 rows)} 44} 45do_eqp_test 1.3 { 46 SELECT * FROM t2 CROSS JOIN t1 WHERE t1.a=1 OR t1.b=2; 47} { 48 0 0 0 {SCAN TABLE t2 (~1000000 rows)} 49 0 1 1 {SEARCH TABLE t1 USING INDEX i1 (a=?) (~10 rows)} 50 0 1 1 {SEARCH TABLE t1 USING INDEX i2 (b=?) (~10 rows)} 51} 52do_eqp_test 1.3 { 53 SELECT a FROM t1 ORDER BY a 54} { 55 0 0 0 {SCAN TABLE t1 USING COVERING INDEX i1 (~1000000 rows)} 56} 57do_eqp_test 1.4 { 58 SELECT a FROM t1 ORDER BY +a 59} { 60 0 0 0 {SCAN TABLE t1 (~1000000 rows)} 61 0 0 0 {USE TEMP B-TREE FOR ORDER BY} 62} 63do_eqp_test 1.5 { 64 SELECT a FROM t1 WHERE a=4 65} { 66 0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i1 (a=?) (~10 rows)} 67} 68do_eqp_test 1.6 { 69 SELECT DISTINCT count(*) FROM t3 GROUP BY a; 70} { 71 0 0 0 {SCAN TABLE t3 (~1000000 rows)} 72 0 0 0 {USE TEMP B-TREE FOR GROUP BY} 73 0 0 0 {USE TEMP B-TREE FOR DISTINCT} 74} 75 76do_eqp_test 1.7 { 77 SELECT * FROM t3 JOIN (SELECT 1) 78} { 79 0 0 1 {SCAN SUBQUERY 1 (~1 rows)} 80 0 1 0 {SCAN TABLE t3 (~1000000 rows)} 81} 82do_eqp_test 1.8 { 83 SELECT * FROM t3 JOIN (SELECT 1 UNION SELECT 2) 84} { 85 1 0 0 {COMPOUND SUBQUERIES 2 AND 3 USING TEMP B-TREE (UNION)} 86 0 0 1 {SCAN SUBQUERY 1 (~2 rows)} 87 0 1 0 {SCAN TABLE t3 (~1000000 rows)} 88} 89do_eqp_test 1.9 { 90 SELECT * FROM t3 JOIN (SELECT 1 EXCEPT SELECT a FROM t3 LIMIT 17) 91} { 92 3 0 0 {SCAN TABLE t3 (~1000000 rows)} 93 1 0 0 {COMPOUND SUBQUERIES 2 AND 3 USING TEMP B-TREE (EXCEPT)} 94 0 0 1 {SCAN SUBQUERY 1 (~17 rows)} 95 0 1 0 {SCAN TABLE t3 (~1000000 rows)} 96} 97do_eqp_test 1.10 { 98 SELECT * FROM t3 JOIN (SELECT 1 INTERSECT SELECT a FROM t3 LIMIT 17) 99} { 100 3 0 0 {SCAN TABLE t3 (~1000000 rows)} 101 1 0 0 {COMPOUND SUBQUERIES 2 AND 3 USING TEMP B-TREE (INTERSECT)} 102 0 0 1 {SCAN SUBQUERY 1 (~1 rows)} 103 0 1 0 {SCAN TABLE t3 (~1000000 rows)} 104} 105 106do_eqp_test 1.11 { 107 SELECT * FROM t3 JOIN (SELECT 1 UNION ALL SELECT a FROM t3 LIMIT 17) 108} { 109 3 0 0 {SCAN TABLE t3 (~1000000 rows)} 110 1 0 0 {COMPOUND SUBQUERIES 2 AND 3 (UNION ALL)} 111 0 0 1 {SCAN SUBQUERY 1 (~17 rows)} 112 0 1 0 {SCAN TABLE t3 (~1000000 rows)} 113} 114 115#------------------------------------------------------------------------- 116# Test cases eqp-2.* - tests for single select statements. 117# 118drop_all_tables 119do_execsql_test 2.1 { 120 CREATE TABLE t1(x, y); 121 122 CREATE TABLE t2(x, y); 123 CREATE INDEX t2i1 ON t2(x); 124} 125 126det 2.2.1 "SELECT DISTINCT min(x), max(x) FROM t1 GROUP BY x ORDER BY 1" { 127 0 0 0 {SCAN TABLE t1 (~1000000 rows)} 128 0 0 0 {USE TEMP B-TREE FOR GROUP BY} 129 0 0 0 {USE TEMP B-TREE FOR DISTINCT} 130 0 0 0 {USE TEMP B-TREE FOR ORDER BY} 131} 132det 2.2.2 "SELECT DISTINCT min(x), max(x) FROM t2 GROUP BY x ORDER BY 1" { 133 0 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1 (~1000000 rows)} 134 0 0 0 {USE TEMP B-TREE FOR DISTINCT} 135 0 0 0 {USE TEMP B-TREE FOR ORDER BY} 136} 137det 2.2.3 "SELECT DISTINCT * FROM t1" { 138 0 0 0 {SCAN TABLE t1 (~1000000 rows)} 139 0 0 0 {USE TEMP B-TREE FOR DISTINCT} 140} 141det 2.2.4 "SELECT DISTINCT * FROM t1, t2" { 142 0 0 0 {SCAN TABLE t1 (~1000000 rows)} 143 0 1 1 {SCAN TABLE t2 (~1000000 rows)} 144 0 0 0 {USE TEMP B-TREE FOR DISTINCT} 145} 146det 2.2.5 "SELECT DISTINCT * FROM t1, t2 ORDER BY t1.x" { 147 0 0 0 {SCAN TABLE t1 (~1000000 rows)} 148 0 1 1 {SCAN TABLE t2 (~1000000 rows)} 149 0 0 0 {USE TEMP B-TREE FOR DISTINCT} 150 0 0 0 {USE TEMP B-TREE FOR ORDER BY} 151} 152det 2.2.6 "SELECT DISTINCT t2.x FROM t1, t2 ORDER BY t2.x" { 153 0 0 1 {SCAN TABLE t2 USING COVERING INDEX t2i1 (~1000000 rows)} 154 0 1 0 {SCAN TABLE t1 (~1000000 rows)} 155} 156 157det 2.3.1 "SELECT max(x) FROM t2" { 158 0 0 0 {SEARCH TABLE t2 USING COVERING INDEX t2i1 (~1 rows)} 159} 160det 2.3.2 "SELECT min(x) FROM t2" { 161 0 0 0 {SEARCH TABLE t2 USING COVERING INDEX t2i1 (~1 rows)} 162} 163det 2.3.3 "SELECT min(x), max(x) FROM t2" { 164 0 0 0 {SCAN TABLE t2 (~1000000 rows)} 165} 166 167det 2.4.1 "SELECT * FROM t1 WHERE rowid=?" { 168 0 0 0 {SEARCH TABLE t1 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)} 169} 170 171 172 173#------------------------------------------------------------------------- 174# Test cases eqp-3.* - tests for select statements that use sub-selects. 175# 176do_eqp_test 3.1.1 { 177 SELECT (SELECT x FROM t1 AS sub) FROM t1; 178} { 179 0 0 0 {SCAN TABLE t1 (~1000000 rows)} 180 0 0 0 {EXECUTE SCALAR SUBQUERY 1} 181 1 0 0 {SCAN TABLE t1 AS sub (~1000000 rows)} 182} 183do_eqp_test 3.1.2 { 184 SELECT * FROM t1 WHERE (SELECT x FROM t1 AS sub); 185} { 186 0 0 0 {SCAN TABLE t1 (~1000000 rows)} 187 0 0 0 {EXECUTE SCALAR SUBQUERY 1} 188 1 0 0 {SCAN TABLE t1 AS sub (~1000000 rows)} 189} 190do_eqp_test 3.1.3 { 191 SELECT * FROM t1 WHERE (SELECT x FROM t1 AS sub ORDER BY y); 192} { 193 0 0 0 {SCAN TABLE t1 (~1000000 rows)} 194 0 0 0 {EXECUTE SCALAR SUBQUERY 1} 195 1 0 0 {SCAN TABLE t1 AS sub (~1000000 rows)} 196 1 0 0 {USE TEMP B-TREE FOR ORDER BY} 197} 198do_eqp_test 3.1.4 { 199 SELECT * FROM t1 WHERE (SELECT x FROM t2 ORDER BY x); 200} { 201 0 0 0 {SCAN TABLE t1 (~1000000 rows)} 202 0 0 0 {EXECUTE SCALAR SUBQUERY 1} 203 1 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1 (~1000000 rows)} 204} 205 206det 3.2.1 { 207 SELECT * FROM (SELECT * FROM t1 ORDER BY x LIMIT 10) ORDER BY y LIMIT 5 208} { 209 1 0 0 {SCAN TABLE t1 (~1000000 rows)} 210 1 0 0 {USE TEMP B-TREE FOR ORDER BY} 211 0 0 0 {SCAN SUBQUERY 1 (~10 rows)} 212 0 0 0 {USE TEMP B-TREE FOR ORDER BY} 213} 214det 3.2.2 { 215 SELECT * FROM 216 (SELECT * FROM t1 ORDER BY x LIMIT 10) AS x1, 217 (SELECT * FROM t2 ORDER BY x LIMIT 10) AS x2 218 ORDER BY x2.y LIMIT 5 219} { 220 1 0 0 {SCAN TABLE t1 (~1000000 rows)} 221 1 0 0 {USE TEMP B-TREE FOR ORDER BY} 222 2 0 0 {SCAN TABLE t2 USING INDEX t2i1 (~1000000 rows)} 223 0 0 0 {SCAN SUBQUERY 1 AS x1 (~10 rows)} 224 0 1 1 {SCAN SUBQUERY 2 AS x2 (~10 rows)} 225 0 0 0 {USE TEMP B-TREE FOR ORDER BY} 226} 227 228det 3.3.1 { 229 SELECT * FROM t1 WHERE y IN (SELECT y FROM t2) 230} { 231 0 0 0 {SCAN TABLE t1 (~100000 rows)} 232 0 0 0 {EXECUTE LIST SUBQUERY 1} 233 1 0 0 {SCAN TABLE t2 (~1000000 rows)} 234} 235det 3.3.2 { 236 SELECT * FROM t1 WHERE y IN (SELECT y FROM t2 WHERE t1.x!=t2.x) 237} { 238 0 0 0 {SCAN TABLE t1 (~500000 rows)} 239 0 0 0 {EXECUTE CORRELATED LIST SUBQUERY 1} 240 1 0 0 {SCAN TABLE t2 (~500000 rows)} 241} 242det 3.3.3 { 243 SELECT * FROM t1 WHERE EXISTS (SELECT y FROM t2 WHERE t1.x!=t2.x) 244} { 245 0 0 0 {SCAN TABLE t1 (~500000 rows)} 246 0 0 0 {EXECUTE CORRELATED SCALAR SUBQUERY 1} 247 1 0 0 {SCAN TABLE t2 (~500000 rows)} 248} 249 250#------------------------------------------------------------------------- 251# Test cases eqp-4.* - tests for composite select statements. 252# 253do_eqp_test 4.1.1 { 254 SELECT * FROM t1 UNION ALL SELECT * FROM t2 255} { 256 1 0 0 {SCAN TABLE t1 (~1000000 rows)} 257 2 0 0 {SCAN TABLE t2 (~1000000 rows)} 258 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (UNION ALL)} 259} 260do_eqp_test 4.1.2 { 261 SELECT * FROM t1 UNION ALL SELECT * FROM t2 ORDER BY 2 262} { 263 1 0 0 {SCAN TABLE t1 (~1000000 rows)} 264 1 0 0 {USE TEMP B-TREE FOR ORDER BY} 265 2 0 0 {SCAN TABLE t2 (~1000000 rows)} 266 2 0 0 {USE TEMP B-TREE FOR ORDER BY} 267 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (UNION ALL)} 268} 269do_eqp_test 4.1.3 { 270 SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY 2 271} { 272 1 0 0 {SCAN TABLE t1 (~1000000 rows)} 273 1 0 0 {USE TEMP B-TREE FOR ORDER BY} 274 2 0 0 {SCAN TABLE t2 (~1000000 rows)} 275 2 0 0 {USE TEMP B-TREE FOR ORDER BY} 276 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (UNION)} 277} 278do_eqp_test 4.1.4 { 279 SELECT * FROM t1 INTERSECT SELECT * FROM t2 ORDER BY 2 280} { 281 1 0 0 {SCAN TABLE t1 (~1000000 rows)} 282 1 0 0 {USE TEMP B-TREE FOR ORDER BY} 283 2 0 0 {SCAN TABLE t2 (~1000000 rows)} 284 2 0 0 {USE TEMP B-TREE FOR ORDER BY} 285 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (INTERSECT)} 286} 287do_eqp_test 4.1.5 { 288 SELECT * FROM t1 EXCEPT SELECT * FROM t2 ORDER BY 2 289} { 290 1 0 0 {SCAN TABLE t1 (~1000000 rows)} 291 1 0 0 {USE TEMP B-TREE FOR ORDER BY} 292 2 0 0 {SCAN TABLE t2 (~1000000 rows)} 293 2 0 0 {USE TEMP B-TREE FOR ORDER BY} 294 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (EXCEPT)} 295} 296 297do_eqp_test 4.2.2 { 298 SELECT * FROM t1 UNION ALL SELECT * FROM t2 ORDER BY 1 299} { 300 1 0 0 {SCAN TABLE t1 (~1000000 rows)} 301 1 0 0 {USE TEMP B-TREE FOR ORDER BY} 302 2 0 0 {SCAN TABLE t2 USING INDEX t2i1 (~1000000 rows)} 303 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (UNION ALL)} 304} 305do_eqp_test 4.2.3 { 306 SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY 1 307} { 308 1 0 0 {SCAN TABLE t1 (~1000000 rows)} 309 1 0 0 {USE TEMP B-TREE FOR ORDER BY} 310 2 0 0 {SCAN TABLE t2 (~1000000 rows)} 311 2 0 0 {USE TEMP B-TREE FOR ORDER BY} 312 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (UNION)} 313} 314do_eqp_test 4.2.4 { 315 SELECT * FROM t1 INTERSECT SELECT * FROM t2 ORDER BY 1 316} { 317 1 0 0 {SCAN TABLE t1 (~1000000 rows)} 318 1 0 0 {USE TEMP B-TREE FOR ORDER BY} 319 2 0 0 {SCAN TABLE t2 (~1000000 rows)} 320 2 0 0 {USE TEMP B-TREE FOR ORDER BY} 321 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (INTERSECT)} 322} 323do_eqp_test 4.2.5 { 324 SELECT * FROM t1 EXCEPT SELECT * FROM t2 ORDER BY 1 325} { 326 1 0 0 {SCAN TABLE t1 (~1000000 rows)} 327 1 0 0 {USE TEMP B-TREE FOR ORDER BY} 328 2 0 0 {SCAN TABLE t2 (~1000000 rows)} 329 2 0 0 {USE TEMP B-TREE FOR ORDER BY} 330 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (EXCEPT)} 331} 332 333do_eqp_test 4.3.1 { 334 SELECT x FROM t1 UNION SELECT x FROM t2 335} { 336 1 0 0 {SCAN TABLE t1 (~1000000 rows)} 337 2 0 0 {SCAN TABLE t2 (~1000000 rows)} 338 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 USING TEMP B-TREE (UNION)} 339} 340 341do_eqp_test 4.3.2 { 342 SELECT x FROM t1 UNION SELECT x FROM t2 UNION SELECT x FROM t1 343} { 344 2 0 0 {SCAN TABLE t1 (~1000000 rows)} 345 3 0 0 {SCAN TABLE t2 (~1000000 rows)} 346 1 0 0 {COMPOUND SUBQUERIES 2 AND 3 USING TEMP B-TREE (UNION)} 347 4 0 0 {SCAN TABLE t1 (~1000000 rows)} 348 0 0 0 {COMPOUND SUBQUERIES 1 AND 4 USING TEMP B-TREE (UNION)} 349} 350do_eqp_test 4.3.3 { 351 SELECT x FROM t1 UNION SELECT x FROM t2 UNION SELECT x FROM t1 ORDER BY 1 352} { 353 2 0 0 {SCAN TABLE t1 (~1000000 rows)} 354 2 0 0 {USE TEMP B-TREE FOR ORDER BY} 355 3 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1 (~1000000 rows)} 356 1 0 0 {COMPOUND SUBQUERIES 2 AND 3 (UNION)} 357 4 0 0 {SCAN TABLE t1 (~1000000 rows)} 358 4 0 0 {USE TEMP B-TREE FOR ORDER BY} 359 0 0 0 {COMPOUND SUBQUERIES 1 AND 4 (UNION)} 360} 361 362#------------------------------------------------------------------------- 363# This next block of tests verifies that the examples on the 364# lang_explain.html page are correct. 365# 366drop_all_tables 367 368# EVIDENCE-OF: R-64208-08323 sqlite> EXPLAIN QUERY PLAN SELECT a, b 369# FROM t1 WHERE a=1; 0|0|0|SCAN TABLE t1 (~100000 rows) 370do_execsql_test 5.1.0 { CREATE TABLE t1(a, b) } 371det 5.1.1 "SELECT a, b FROM t1 WHERE a=1" { 372 0 0 0 {SCAN TABLE t1 (~100000 rows)} 373} 374 375# EVIDENCE-OF: R-09022-44606 sqlite> CREATE INDEX i1 ON t1(a); 376# sqlite> EXPLAIN QUERY PLAN SELECT a, b FROM t1 WHERE a=1; 377# 0|0|0|SEARCH TABLE t1 USING INDEX i1 (a=?) (~10 rows) 378do_execsql_test 5.2.0 { CREATE INDEX i1 ON t1(a) } 379det 5.2.1 "SELECT a, b FROM t1 WHERE a=1" { 380 0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?) (~10 rows)} 381} 382 383# EVIDENCE-OF: R-62228-34103 sqlite> CREATE INDEX i2 ON t1(a, b); 384# sqlite> EXPLAIN QUERY PLAN SELECT a, b FROM t1 WHERE a=1; 385# 0|0|0|SEARCH TABLE t1 USING COVERING INDEX i2 (a=?) (~10 rows) 386do_execsql_test 5.3.0 { CREATE INDEX i2 ON t1(a, b) } 387det 5.3.1 "SELECT a, b FROM t1 WHERE a=1" { 388 0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i2 (a=?) (~10 rows)} 389} 390 391# EVIDENCE-OF: R-22253-05302 sqlite> EXPLAIN QUERY PLAN SELECT t1.*, 392# t2.* FROM t1, t2 WHERE t1.a=1 AND t1.b>2; 0|0|0|SEARCH TABLE t1 393# USING COVERING INDEX i2 (a=? AND b>?) (~3 rows) 0|1|1|SCAN TABLE t2 394# (~1000000 rows) 395do_execsql_test 5.4.0 {CREATE TABLE t2(c, d)} 396det 5.4.1 "SELECT t1.*, t2.* FROM t1, t2 WHERE t1.a=1 AND t1.b>2" { 397 0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i2 (a=? AND b>?) (~2 rows)} 398 0 1 1 {SCAN TABLE t2 (~1000000 rows)} 399} 400 401# EVIDENCE-OF: R-21040-07025 sqlite> EXPLAIN QUERY PLAN SELECT t1.*, 402# t2.* FROM t2, t1 WHERE t1.a=1 AND t1.b>2; 0|0|1|SEARCH TABLE t1 403# USING COVERING INDEX i2 (a=? AND b>?) (~3 rows) 0|1|0|SCAN TABLE t2 404# (~1000000 rows) 405det 5.5 "SELECT t1.*, t2.* FROM t2, t1 WHERE t1.a=1 AND t1.b>2" { 406 0 0 1 {SEARCH TABLE t1 USING COVERING INDEX i2 (a=? AND b>?) (~2 rows)} 407 0 1 0 {SCAN TABLE t2 (~1000000 rows)} 408} 409 410# EVIDENCE-OF: R-39007-61103 sqlite> CREATE INDEX i3 ON t1(b); 411# sqlite> EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=1 OR b=2; 412# 0|0|0|SEARCH TABLE t1 USING COVERING INDEX i2 (a=?) (~10 rows) 413# 0|0|0|SEARCH TABLE t1 USING INDEX i3 (b=?) (~10 rows) 414do_execsql_test 5.5.0 {CREATE INDEX i3 ON t1(b)} 415det 5.6.1 "SELECT * FROM t1 WHERE a=1 OR b=2" { 416 0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i2 (a=?) (~10 rows)} 417 0 0 0 {SEARCH TABLE t1 USING INDEX i3 (b=?) (~10 rows)} 418} 419 420# EVIDENCE-OF: R-33025-54904 sqlite> EXPLAIN QUERY PLAN SELECT c, d 421# FROM t2 ORDER BY c; 0|0|0|SCAN TABLE t2 (~1000000 rows) 0|0|0|USE TEMP 422# B-TREE FOR ORDER BY 423det 5.7 "SELECT c, d FROM t2 ORDER BY c" { 424 0 0 0 {SCAN TABLE t2 (~1000000 rows)} 425 0 0 0 {USE TEMP B-TREE FOR ORDER BY} 426} 427 428# EVIDENCE-OF: R-38854-22809 sqlite> CREATE INDEX i4 ON t2(c); 429# sqlite> EXPLAIN QUERY PLAN SELECT c, d FROM t2 ORDER BY c; 430# 0|0|0|SCAN TABLE t2 USING INDEX i4 (~1000000 rows) 431do_execsql_test 5.8.0 {CREATE INDEX i4 ON t2(c)} 432det 5.8.1 "SELECT c, d FROM t2 ORDER BY c" { 433 0 0 0 {SCAN TABLE t2 USING INDEX i4 (~1000000 rows)} 434} 435 436# EVIDENCE-OF: R-29884-43993 sqlite> EXPLAIN QUERY PLAN SELECT 437# (SELECT b FROM t1 WHERE a=0), (SELECT a FROM t1 WHERE b=t2.c) FROM t2; 438# 0|0|0|SCAN TABLE t2 (~1000000 rows) 0|0|0|EXECUTE SCALAR SUBQUERY 1 439# 1|0|0|SEARCH TABLE t1 USING COVERING INDEX i2 (a=?) (~10 rows) 440# 0|0|0|EXECUTE CORRELATED SCALAR SUBQUERY 2 2|0|0|SEARCH TABLE t1 USING 441# INDEX i3 (b=?) (~10 rows) 442det 5.9 { 443 SELECT (SELECT b FROM t1 WHERE a=0), (SELECT a FROM t1 WHERE b=t2.c) FROM t2 444} { 445 0 0 0 {SCAN TABLE t2 (~1000000 rows)} 446 0 0 0 {EXECUTE SCALAR SUBQUERY 1} 447 1 0 0 {SEARCH TABLE t1 USING COVERING INDEX i2 (a=?) (~10 rows)} 448 0 0 0 {EXECUTE CORRELATED SCALAR SUBQUERY 2} 449 2 0 0 {SEARCH TABLE t1 USING INDEX i3 (b=?) (~10 rows)} 450} 451 452# EVIDENCE-OF: R-17911-16445 sqlite> EXPLAIN QUERY PLAN SELECT 453# count(*) FROM (SELECT max(b) AS x FROM t1 GROUP BY a) GROUP BY x; 454# 1|0|0|SCAN TABLE t1 USING COVERING INDEX i2 (~1000000 rows) 0|0|0|SCAN 455# SUBQUERY 1 (~1000000 rows) 0|0|0|USE TEMP B-TREE FOR GROUP BY 456det 5.10 { 457 SELECT count(*) FROM (SELECT max(b) AS x FROM t1 GROUP BY a) GROUP BY x 458} { 459 1 0 0 {SCAN TABLE t1 USING COVERING INDEX i2 (~1000000 rows)} 460 0 0 0 {SCAN SUBQUERY 1 (~100 rows)} 461 0 0 0 {USE TEMP B-TREE FOR GROUP BY} 462} 463 464# EVIDENCE-OF: R-18544-33103 sqlite> EXPLAIN QUERY PLAN SELECT * FROM 465# (SELECT * FROM t2 WHERE c=1), t1; 0|0|0|SEARCH TABLE t2 USING INDEX i4 466# (c=?) (~10 rows) 0|1|1|SCAN TABLE t1 (~1000000 rows) 467det 5.11 "SELECT * FROM (SELECT * FROM t2 WHERE c=1), t1" { 468 0 0 0 {SEARCH TABLE t2 USING INDEX i4 (c=?) (~10 rows)} 469 0 1 1 {SCAN TABLE t1 (~1000000 rows)} 470} 471 472# EVIDENCE-OF: R-40701-42164 sqlite> EXPLAIN QUERY PLAN SELECT a FROM 473# t1 UNION SELECT c FROM t2; 1|0|0|SCAN TABLE t1 (~1000000 rows) 474# 2|0|0|SCAN TABLE t2 (~1000000 rows) 0|0|0|COMPOUND SUBQUERIES 1 AND 2 475# USING TEMP B-TREE (UNION) 476det 5.12 "SELECT a FROM t1 UNION SELECT c FROM t2" { 477 1 0 0 {SCAN TABLE t1 (~1000000 rows)} 478 2 0 0 {SCAN TABLE t2 (~1000000 rows)} 479 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 USING TEMP B-TREE (UNION)} 480} 481 482# EVIDENCE-OF: R-61538-24748 sqlite> EXPLAIN QUERY PLAN SELECT a FROM 483# t1 EXCEPT SELECT d FROM t2 ORDER BY 1; 1|0|0|SCAN TABLE t1 USING 484# COVERING INDEX i2 (~1000000 rows) 2|0|0|SCAN TABLE t2 (~1000000 rows) 485# 2|0|0|USE TEMP B-TREE FOR ORDER BY 0|0|0|COMPOUND SUBQUERIES 1 AND 2 486# (EXCEPT) 487det 5.13 "SELECT a FROM t1 EXCEPT SELECT d FROM t2 ORDER BY 1" { 488 1 0 0 {SCAN TABLE t1 USING COVERING INDEX i2 (~1000000 rows)} 489 2 0 0 {SCAN TABLE t2 (~1000000 rows)} 490 2 0 0 {USE TEMP B-TREE FOR ORDER BY} 491 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (EXCEPT)} 492} 493 494 495#------------------------------------------------------------------------- 496# The following tests - eqp-6.* - test that the example C code on 497# documentation page eqp.html works. The C code is duplicated in test1.c 498# and wrapped in Tcl command [print_explain_query_plan] 499# 500set boilerplate { 501 proc explain_query_plan {db sql} { 502 set stmt [sqlite3_prepare_v2 db $sql -1 DUMMY] 503 print_explain_query_plan $stmt 504 sqlite3_finalize $stmt 505 } 506 sqlite3 db test.db 507 explain_query_plan db {%SQL%} 508 db close 509 exit 510} 511 512# Do a "Print Explain Query Plan" test. 513proc do_peqp_test {tn sql res} { 514 set fd [open script.tcl w] 515 puts $fd [string map [list %SQL% $sql] $::boilerplate] 516 close $fd 517 518 uplevel do_test $tn [list { 519 set fd [open "|[info nameofexec] script.tcl"] 520 set data [read $fd] 521 close $fd 522 set data 523 }] [list $res] 524} 525 526do_peqp_test 6.1 { 527 SELECT a FROM t1 EXCEPT SELECT d FROM t2 ORDER BY 1 528} [string trimleft { 5291 0 0 SCAN TABLE t1 USING COVERING INDEX i2 (~1000000 rows) 5302 0 0 SCAN TABLE t2 (~1000000 rows) 5312 0 0 USE TEMP B-TREE FOR ORDER BY 5320 0 0 COMPOUND SUBQUERIES 1 AND 2 (EXCEPT) 533}] 534 535#------------------------------------------------------------------------- 536# The following tests - eqp-7.* - test that queries that use the OP_Count 537# optimization return something sensible with EQP. 538# 539drop_all_tables 540 541do_execsql_test 7.0 { 542 CREATE TABLE t1(a, b); 543 CREATE TABLE t2(a, b); 544 CREATE INDEX i1 ON t2(a); 545} 546 547det 7.1 "SELECT count(*) FROM t1" { 548 0 0 0 {SCAN TABLE t1 (~1000000 rows)} 549} 550 551det 7.2 "SELECT count(*) FROM t2" { 552 0 0 0 {SCAN TABLE t2 USING COVERING INDEX i1(~1000000 rows)} 553} 554 555do_execsql_test 7.3 { 556 INSERT INTO t1 VALUES(1, 2); 557 INSERT INTO t1 VALUES(3, 4); 558 559 INSERT INTO t2 VALUES(1, 2); 560 INSERT INTO t2 VALUES(3, 4); 561 INSERT INTO t2 VALUES(5, 6); 562 563 ANALYZE; 564} 565 566db close 567sqlite3 db test.db 568 569det 7.4 "SELECT count(*) FROM t1" { 570 0 0 0 {SCAN TABLE t1 (~2 rows)} 571} 572 573det 7.5 "SELECT count(*) FROM t2" { 574 0 0 0 {SCAN TABLE t2 USING COVERING INDEX i1(~3 rows)} 575} 576 577 578finish_test 579