Annotation of embedaddon/sqlite3/test/eqp.test, revision 1.1
1.1 ! misho 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
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>