OLD | NEW |
(Empty) | |
| 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 |
OLD | NEW |