Annotation of embedaddon/sqlite3/test/indexedby.test, revision 1.1.1.1

1.1       misho       1: # 2008 October 4
                      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: # $Id: indexedby.test,v 1.5 2009/03/22 20:36:19 drh Exp $
                     13: 
                     14: set testdir [file dirname $argv0]
                     15: source $testdir/tester.tcl
                     16: 
                     17: # Create a schema with some indexes.
                     18: #
                     19: do_test indexedby-1.1 {
                     20:   execsql {
                     21:     CREATE TABLE t1(a, b);
                     22:     CREATE INDEX i1 ON t1(a);
                     23:     CREATE INDEX i2 ON t1(b);
                     24: 
                     25:     CREATE TABLE t2(c, d);
                     26:     CREATE INDEX i3 ON t2(c);
                     27:     CREATE INDEX i4 ON t2(d);
                     28: 
                     29:     CREATE TABLE t3(e PRIMARY KEY, f);
                     30: 
                     31:     CREATE VIEW v1 AS SELECT * FROM t1;
                     32:   }
                     33: } {}
                     34: 
                     35: # Explain Query Plan
                     36: #
                     37: proc EQP {sql} {
                     38:   uplevel "execsql {EXPLAIN QUERY PLAN $sql}"
                     39: }
                     40: 
                     41: # These tests are to check that "EXPLAIN QUERY PLAN" is working as expected.
                     42: #
                     43: do_execsql_test indexedby-1.2 {
                     44:   EXPLAIN QUERY PLAN select * from t1 WHERE a = 10; 
                     45: } {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?) (~10 rows)}}
                     46: do_execsql_test indexedby-1.3 {
                     47:   EXPLAIN QUERY PLAN select * from t1 ; 
                     48: } {0 0 0 {SCAN TABLE t1 (~1000000 rows)}}
                     49: do_execsql_test indexedby-1.4 {
                     50:   EXPLAIN QUERY PLAN select * from t1, t2 WHERE c = 10; 
                     51: } {
                     52:   0 0 1 {SEARCH TABLE t2 USING INDEX i3 (c=?) (~10 rows)} 
                     53:   0 1 0 {SCAN TABLE t1 (~1000000 rows)}
                     54: }
                     55: 
                     56: # Parser tests. Test that an INDEXED BY or NOT INDEX clause can be 
                     57: # attached to a table in the FROM clause, but not to a sub-select or
                     58: # SQL view. Also test that specifying an index that does not exist or
                     59: # is attached to a different table is detected as an error.
                     60: # 
                     61: do_test indexedby-2.1 {
                     62:   execsql { SELECT * FROM t1 NOT INDEXED WHERE a = 'one' AND b = 'two'}
                     63: } {}
                     64: do_test indexedby-2.2 {
                     65:   execsql { SELECT * FROM t1 INDEXED BY i1 WHERE a = 'one' AND b = 'two'}
                     66: } {}
                     67: do_test indexedby-2.3 {
                     68:   execsql { SELECT * FROM t1 INDEXED BY i2 WHERE a = 'one' AND b = 'two'}
                     69: } {}
                     70: 
                     71: do_test indexedby-2.4 {
                     72:   catchsql { SELECT * FROM t1 INDEXED BY i3 WHERE a = 'one' AND b = 'two'}
                     73: } {1 {no such index: i3}}
                     74: do_test indexedby-2.5 {
                     75:   catchsql { SELECT * FROM t1 INDEXED BY i5 WHERE a = 'one' AND b = 'two'}
                     76: } {1 {no such index: i5}}
                     77: do_test indexedby-2.6 {
                     78:   catchsql { SELECT * FROM t1 INDEXED BY WHERE a = 'one' AND b = 'two'}
                     79: } {1 {near "WHERE": syntax error}}
                     80: do_test indexedby-2.7 {
                     81:   catchsql { SELECT * FROM v1 INDEXED BY i1 WHERE a = 'one' }
                     82: } {1 {no such index: i1}}
                     83: 
                     84: # Tests for single table cases.
                     85: #
                     86: do_execsql_test indexedby-3.1 {
                     87:   EXPLAIN QUERY PLAN SELECT * FROM t1 NOT INDEXED WHERE a = 'one' AND b = 'two'
                     88: } {0 0 0 {SCAN TABLE t1 (~10000 rows)}}
                     89: do_execsql_test indexedby-3.2 {
                     90:   EXPLAIN QUERY PLAN 
                     91:   SELECT * FROM t1 INDEXED BY i1 WHERE a = 'one' AND b = 'two'
                     92: } {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?) (~2 rows)}}
                     93: do_execsql_test indexedby-3.3 {
                     94:   EXPLAIN QUERY PLAN 
                     95:   SELECT * FROM t1 INDEXED BY i2 WHERE a = 'one' AND b = 'two'
                     96: } {0 0 0 {SEARCH TABLE t1 USING INDEX i2 (b=?) (~2 rows)}}
                     97: do_test indexedby-3.4 {
                     98:   catchsql { SELECT * FROM t1 INDEXED BY i2 WHERE a = 'one' }
                     99: } {1 {cannot use index: i2}}
                    100: do_test indexedby-3.5 {
                    101:   catchsql { SELECT * FROM t1 INDEXED BY i2 ORDER BY a }
                    102: } {1 {cannot use index: i2}}
                    103: do_test indexedby-3.6 {
                    104:   catchsql { SELECT * FROM t1 INDEXED BY i1 WHERE a = 'one' }
                    105: } {0 {}}
                    106: do_test indexedby-3.7 {
                    107:   catchsql { SELECT * FROM t1 INDEXED BY i1 ORDER BY a }
                    108: } {0 {}}
                    109: 
                    110: do_execsql_test indexedby-3.8 {
                    111:   EXPLAIN QUERY PLAN 
                    112:   SELECT * FROM t3 INDEXED BY sqlite_autoindex_t3_1 ORDER BY e 
                    113: } {0 0 0 {SCAN TABLE t3 USING INDEX sqlite_autoindex_t3_1 (~1000000 rows)}}
                    114: do_execsql_test indexedby-3.9 {
                    115:   EXPLAIN QUERY PLAN 
                    116:   SELECT * FROM t3 INDEXED BY sqlite_autoindex_t3_1 WHERE e = 10 
                    117: } {0 0 0 {SEARCH TABLE t3 USING INDEX sqlite_autoindex_t3_1 (e=?) (~1 rows)}}
                    118: do_test indexedby-3.10 {
                    119:   catchsql { SELECT * FROM t3 INDEXED BY sqlite_autoindex_t3_1 WHERE f = 10 }
                    120: } {1 {cannot use index: sqlite_autoindex_t3_1}}
                    121: do_test indexedby-3.11 {
                    122:   catchsql { SELECT * FROM t3 INDEXED BY sqlite_autoindex_t3_2 WHERE f = 10 }
                    123: } {1 {no such index: sqlite_autoindex_t3_2}}
                    124: 
                    125: # Tests for multiple table cases.
                    126: #
                    127: do_execsql_test indexedby-4.1 {
                    128:   EXPLAIN QUERY PLAN SELECT * FROM t1, t2 WHERE a = c 
                    129: } {
                    130:   0 0 0 {SCAN TABLE t1 (~1000000 rows)} 
                    131:   0 1 1 {SEARCH TABLE t2 USING INDEX i3 (c=?) (~10 rows)}
                    132: }
                    133: do_execsql_test indexedby-4.2 {
                    134:   EXPLAIN QUERY PLAN SELECT * FROM t1 INDEXED BY i1, t2 WHERE a = c 
                    135: } {
                    136:   0 0 1 {SCAN TABLE t2 (~1000000 rows)} 
                    137:   0 1 0 {SEARCH TABLE t1 USING INDEX i1 (a=?) (~10 rows)}
                    138: }
                    139: do_test indexedby-4.3 {
                    140:   catchsql {
                    141:     SELECT * FROM t1 INDEXED BY i1, t2 INDEXED BY i3 WHERE a=c
                    142:   }
                    143: } {1 {cannot use index: i1}}
                    144: do_test indexedby-4.4 {
                    145:   catchsql {
                    146:     SELECT * FROM t2 INDEXED BY i3, t1 INDEXED BY i1 WHERE a=c
                    147:   }
                    148: } {1 {cannot use index: i3}}
                    149: 
                    150: # Test embedding an INDEXED BY in a CREATE VIEW statement. This block
                    151: # also tests that nothing bad happens if an index refered to by
                    152: # a CREATE VIEW statement is dropped and recreated.
                    153: #
                    154: do_execsql_test indexedby-5.1 {
                    155:   CREATE VIEW v2 AS SELECT * FROM t1 INDEXED BY i1 WHERE a > 5;
                    156:   EXPLAIN QUERY PLAN SELECT * FROM v2 
                    157: } {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a>?) (~250000 rows)}}
                    158: do_execsql_test indexedby-5.2 {
                    159:   EXPLAIN QUERY PLAN SELECT * FROM v2 WHERE b = 10 
                    160: } {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a>?) (~25000 rows)}}
                    161: do_test indexedby-5.3 {
                    162:   execsql { DROP INDEX i1 }
                    163:   catchsql { SELECT * FROM v2 }
                    164: } {1 {no such index: i1}}
                    165: do_test indexedby-5.4 {
                    166:   # Recreate index i1 in such a way as it cannot be used by the view query.
                    167:   execsql { CREATE INDEX i1 ON t1(b) }
                    168:   catchsql { SELECT * FROM v2 }
                    169: } {1 {cannot use index: i1}}
                    170: do_test indexedby-5.5 {
                    171:   # Drop and recreate index i1 again. This time, create it so that it can
                    172:   # be used by the query.
                    173:   execsql { DROP INDEX i1 ; CREATE INDEX i1 ON t1(a) }
                    174:   catchsql { SELECT * FROM v2 }
                    175: } {0 {}}
                    176: 
                    177: # Test that "NOT INDEXED" may use the rowid index, but not others.
                    178: # 
                    179: do_execsql_test indexedby-6.1 {
                    180:   EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b = 10 ORDER BY rowid 
                    181: } {0 0 0 {SEARCH TABLE t1 USING INDEX i2 (b=?) (~10 rows)}}
                    182: do_execsql_test indexedby-6.2 {
                    183:   EXPLAIN QUERY PLAN SELECT * FROM t1 NOT INDEXED WHERE b = 10 ORDER BY rowid 
                    184: } {0 0 0 {SCAN TABLE t1 USING INTEGER PRIMARY KEY (~100000 rows)}}
                    185: 
                    186: # Test that "INDEXED BY" can be used in a DELETE statement.
                    187: # 
                    188: do_execsql_test indexedby-7.1 {
                    189:   EXPLAIN QUERY PLAN DELETE FROM t1 WHERE a = 5 
                    190: } {0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i1 (a=?) (~10 rows)}}
                    191: do_execsql_test indexedby-7.2 {
                    192:   EXPLAIN QUERY PLAN DELETE FROM t1 NOT INDEXED WHERE a = 5 
                    193: } {0 0 0 {SCAN TABLE t1 (~100000 rows)}}
                    194: do_execsql_test indexedby-7.3 {
                    195:   EXPLAIN QUERY PLAN DELETE FROM t1 INDEXED BY i1 WHERE a = 5 
                    196: } {0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i1 (a=?) (~10 rows)}}
                    197: do_execsql_test indexedby-7.4 {
                    198:   EXPLAIN QUERY PLAN DELETE FROM t1 INDEXED BY i1 WHERE a = 5 AND b = 10
                    199: } {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?) (~2 rows)}}
                    200: do_execsql_test indexedby-7.5 {
                    201:   EXPLAIN QUERY PLAN DELETE FROM t1 INDEXED BY i2 WHERE a = 5 AND b = 10
                    202: } {0 0 0 {SEARCH TABLE t1 USING INDEX i2 (b=?) (~2 rows)}}
                    203: do_test indexedby-7.6 {
                    204:   catchsql { DELETE FROM t1 INDEXED BY i2 WHERE a = 5}
                    205: } {1 {cannot use index: i2}}
                    206: 
                    207: # Test that "INDEXED BY" can be used in an UPDATE statement.
                    208: # 
                    209: do_execsql_test indexedby-8.1 {
                    210:   EXPLAIN QUERY PLAN UPDATE t1 SET rowid=rowid+1 WHERE a = 5 
                    211: } {0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i1 (a=?) (~10 rows)}}
                    212: do_execsql_test indexedby-8.2 {
                    213:   EXPLAIN QUERY PLAN UPDATE t1 NOT INDEXED SET rowid=rowid+1 WHERE a = 5 
                    214: } {0 0 0 {SCAN TABLE t1 (~100000 rows)}}
                    215: do_execsql_test indexedby-8.3 {
                    216:   EXPLAIN QUERY PLAN UPDATE t1 INDEXED BY i1 SET rowid=rowid+1 WHERE a = 5 
                    217: } {0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i1 (a=?) (~10 rows)}}
                    218: do_execsql_test indexedby-8.4 {
                    219:   EXPLAIN QUERY PLAN 
                    220:   UPDATE t1 INDEXED BY i1 SET rowid=rowid+1 WHERE a = 5 AND b = 10
                    221: } {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?) (~2 rows)}}
                    222: do_execsql_test indexedby-8.5 {
                    223:   EXPLAIN QUERY PLAN 
                    224:   UPDATE t1 INDEXED BY i2 SET rowid=rowid+1 WHERE a = 5 AND b = 10
                    225: } {0 0 0 {SEARCH TABLE t1 USING INDEX i2 (b=?) (~2 rows)}}
                    226: do_test indexedby-8.6 {
                    227:   catchsql { UPDATE t1 INDEXED BY i2 SET rowid=rowid+1 WHERE a = 5}
                    228: } {1 {cannot use index: i2}}
                    229: 
                    230: # Test that bug #3560 is fixed.
                    231: #
                    232: do_test indexedby-9.1 {
                    233:   execsql {
                    234:     CREATE TABLE maintable( id integer);
                    235:     CREATE TABLE joinme(id_int integer, id_text text);
                    236:     CREATE INDEX joinme_id_text_idx on joinme(id_text);
                    237:     CREATE INDEX joinme_id_int_idx on joinme(id_int);
                    238:   }
                    239: } {}
                    240: do_test indexedby-9.2 {
                    241:   catchsql {
                    242:     select * from maintable as m inner join
                    243:     joinme as j indexed by joinme_id_text_idx
                    244:     on ( m.id  = j.id_int)
                    245:   }
                    246: } {1 {cannot use index: joinme_id_text_idx}}
                    247: do_test indexedby-9.3 {
                    248:   catchsql { select * from maintable, joinme INDEXED by joinme_id_text_idx }
                    249: } {1 {cannot use index: joinme_id_text_idx}}
                    250: 
                    251: # Make sure we can still create tables, indices, and columns whose name
                    252: # is "indexed".
                    253: #
                    254: do_test indexedby-10.1 {
                    255:   execsql {
                    256:     CREATE TABLE indexed(x,y);
                    257:     INSERT INTO indexed VALUES(1,2);
                    258:     SELECT * FROM indexed;
                    259:   }
                    260: } {1 2}
                    261: do_test indexedby-10.2 {
                    262:   execsql {
                    263:     CREATE INDEX i10 ON indexed(x);
                    264:     SELECT * FROM indexed indexed by i10 where x>0;
                    265:   }
                    266: } {1 2}
                    267: do_test indexedby-10.3 {
                    268:   execsql {
                    269:     DROP TABLE indexed;
                    270:     CREATE TABLE t10(indexed INTEGER);
                    271:     INSERT INTO t10 VALUES(1);
                    272:     CREATE INDEX indexed ON t10(indexed);
                    273:     SELECT * FROM t10 indexed by indexed WHERE indexed>0
                    274:   }
                    275: } {1}
                    276: 
                    277: finish_test

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>