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 13 set testdir [file dirname $argv0] 14 source $testdir/tester.tcl 15 16 set 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 28 proc det {args} { uplevel do_eqp_test $args } 29 30 do_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 38 do_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 } 45 do_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 } 52 do_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 } 57 do_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 } 63 do_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 } 68 do_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 76 do_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 } 82 do_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 } 89 do_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 } 97 do_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 106 do_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 # 118 drop_all_tables 119 do_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 126 det 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 } 132 det 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 } 137 det 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 } 141 det 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 } 146 det 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 } 152 det 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 157 det 2.3.1 "SELECT max(x) FROM t2" { 158 0 0 0 {SEARCH TABLE t2 USING COVERING INDEX t2i1 (~1 rows)} 159 } 160 det 2.3.2 "SELECT min(x) FROM t2" { 161 0 0 0 {SEARCH TABLE t2 USING COVERING INDEX t2i1 (~1 rows)} 162 } 163 det 2.3.3 "SELECT min(x), max(x) FROM t2" { 164 0 0 0 {SCAN TABLE t2 (~1000000 rows)} 165 } 166 167 det 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 # 176 do_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 } 183 do_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 } 190 do_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 } 198 do_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 206 det 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 } 214 det 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 228 det 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 } 235 det 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 } 242 det 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 # 253 do_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 } 260 do_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 } 269 do_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 } 278 do_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 } 287 do_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 297 do_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 } 305 do_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 } 314 do_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 } 323 do_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 333 do_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 341 do_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 } 350 do_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 # 366 drop_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) 370 do_execsql_test 5.1.0 { CREATE TABLE t1(a, b) } 371 det 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) 378 do_execsql_test 5.2.0 { CREATE INDEX i1 ON t1(a) } 379 det 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) 386 do_execsql_test 5.3.0 { CREATE INDEX i2 ON t1(a, b) } 387 det 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) 395 do_execsql_test 5.4.0 {CREATE TABLE t2(c, d)} 396 det 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) 405 det 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) 414 do_execsql_test 5.5.0 {CREATE INDEX i3 ON t1(b)} 415 det 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 423 det 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) 431 do_execsql_test 5.8.0 {CREATE INDEX i4 ON t2(c)} 432 det 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) 442 det 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 456 det 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) 467 det 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) 476 det 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) 487 det 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 # 500 set 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. 513 proc 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 526 do_peqp_test 6.1 { 527 SELECT a FROM t1 EXCEPT SELECT d FROM t2 ORDER BY 1 528 } [string trimleft { 529 1 0 0 SCAN TABLE t1 USING COVERING INDEX i2 (~1000000 rows) 530 2 0 0 SCAN TABLE t2 (~1000000 rows) 531 2 0 0 USE TEMP B-TREE FOR ORDER BY 532 0 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 # 539 drop_all_tables 540 541 do_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 547 det 7.1 "SELECT count(*) FROM t1" { 548 0 0 0 {SCAN TABLE t1 (~1000000 rows)} 549 } 550 551 det 7.2 "SELECT count(*) FROM t2" { 552 0 0 0 {SCAN TABLE t2 USING COVERING INDEX i1(~1000000 rows)} 553 } 554 555 do_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 566 db close 567 sqlite3 db test.db 568 569 det 7.4 "SELECT count(*) FROM t1" { 570 0 0 0 {SCAN TABLE t1 (~2 rows)} 571 } 572 573 det 7.5 "SELECT count(*) FROM t2" { 574 0 0 0 {SCAN TABLE t2 USING COVERING INDEX i1(~3 rows)} 575 } 576 577 578 finish_test 579