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>