xref: /sqlite-3.40.0/test/autoindex3.test (revision 8210233c)
1dabe36d9Sdrh# 2014-06-17
2dabe36d9Sdrh#
3dabe36d9Sdrh# The author disclaims copyright to this source code.  In place of
4dabe36d9Sdrh# a legal notice, here is a blessing:
5dabe36d9Sdrh#
6dabe36d9Sdrh#    May you do good and not evil.
7dabe36d9Sdrh#    May you find forgiveness for yourself and forgive others.
8dabe36d9Sdrh#    May you share freely, never taking more than you give.
9dabe36d9Sdrh#
10dabe36d9Sdrh#*************************************************************************
11dabe36d9Sdrh#
12dabe36d9Sdrh# This file implements regression tests for SQLite library.  The
13dabe36d9Sdrh# focus of this script is testing automatic index creation logic,
14dabe36d9Sdrh# and specifically that an automatic index will not be created that
15dabe36d9Sdrh# shadows a declared index.
16dabe36d9Sdrh#
17dabe36d9Sdrh
18dabe36d9Sdrhset testdir [file dirname $argv0]
19dabe36d9Sdrhsource $testdir/tester.tcl
2070273d0bSdanset testprefix autoindex3
21dabe36d9Sdrh
22dabe36d9Sdrh# The t1b and t2d indexes are not very selective.  It used to be that
23dabe36d9Sdrh# the autoindex mechanism would create automatic indexes on t1(b) or
24dabe36d9Sdrh# t2(d), make assumptions that they were reasonably selective, and use
25dabe36d9Sdrh# them instead of t1b or t2d.  But that would be cheating, because the
26dabe36d9Sdrh# automatic index cannot be any more selective than the real index.
27dabe36d9Sdrh#
28dabe36d9Sdrh# This test verifies that the cheat is no longer allowed.
29dabe36d9Sdrh#
30dabe36d9Sdrhdo_execsql_test autoindex3-100 {
31dabe36d9Sdrh  CREATE TABLE t1(a,b,x);
32dabe36d9Sdrh  CREATE TABLE t2(c,d,y);
33dabe36d9Sdrh  CREATE INDEX t1b ON t1(b);
34dabe36d9Sdrh  CREATE INDEX t2d ON t2(d);
35dabe36d9Sdrh  ANALYZE sqlite_master;
36dabe36d9Sdrh  INSERT INTO sqlite_stat1 VALUES('t1','t1b','10000 500');
37dabe36d9Sdrh  INSERT INTO sqlite_stat1 VALUES('t2','t2d','10000 500');
38dabe36d9Sdrh  ANALYZE sqlite_master;
39dabe36d9Sdrh  EXPLAIN QUERY PLAN SELECT * FROM t1, t2 WHERE d=b;
40dabe36d9Sdrh} {~/AUTO/}
41dabe36d9Sdrh
42dabe36d9Sdrh# Automatic indexes can still be used if existing indexes do not
43dabe36d9Sdrh# participate in == constraints.
44dabe36d9Sdrh#
45dabe36d9Sdrhdo_execsql_test autoindex3-110 {
46dabe36d9Sdrh  EXPLAIN QUERY PLAN SELECT * FROM t1, t2 WHERE d>b AND x=y;
47dabe36d9Sdrh} {/AUTO/}
48dabe36d9Sdrhdo_execsql_test autoindex3-120 {
49dabe36d9Sdrh  EXPLAIN QUERY PLAN SELECT * FROM t1, t2 WHERE d<b AND x=y;
50dabe36d9Sdrh} {/AUTO/}
51dabe36d9Sdrhdo_execsql_test autoindex3-130 {
52dabe36d9Sdrh  EXPLAIN QUERY PLAN SELECT * FROM t1, t2 WHERE d IS NULL AND x=y;
53dabe36d9Sdrh} {/AUTO/}
54dabe36d9Sdrhdo_execsql_test autoindex3-140 {
55dabe36d9Sdrh  EXPLAIN QUERY PLAN SELECT * FROM t1, t2 WHERE d IN (5,b) AND x=y;
56dabe36d9Sdrh} {/AUTO/}
57dabe36d9Sdrh
5870273d0bSdanreset_db
5970273d0bSdando_execsql_test 210 {
6070273d0bSdan  CREATE TABLE v(b, d, e);
6170273d0bSdan  CREATE TABLE u(a, b, c);
6270273d0bSdan  ANALYZE sqlite_master;
6370273d0bSdan  INSERT INTO "sqlite_stat1" VALUES('u','uab','40000 400 1');
6470273d0bSdan  INSERT INTO "sqlite_stat1" VALUES('v','vbde','40000 400 1 1');
6570273d0bSdan  INSERT INTO "sqlite_stat1" VALUES('v','ve','40000 21');
6670273d0bSdan
6770273d0bSdan  CREATE INDEX uab on u(a, b);
6870273d0bSdan  CREATE INDEX ve on v(e);
6970273d0bSdan  CREATE INDEX vbde on v(b,d,e);
7070273d0bSdan
7170273d0bSdan  DROP TABLE IF EXISTS sqlite_stat4;
7270273d0bSdan  ANALYZE sqlite_master;
7370273d0bSdan}
7470273d0bSdan
7570273d0bSdan# At one point, SQLite was using the inferior plan:
7670273d0bSdan#
77*8210233cSdrh#   0|0|1|SEARCH v USING INDEX ve (e>?)
78*8210233cSdrh#   0|1|0|SEARCH u USING COVERING INDEX uab (ANY(a) AND b=?)
7970273d0bSdan#
8070273d0bSdan# on the basis that the real index "uab" must be better than the automatic
8170273d0bSdan# index. This is not right - a skip-scan is not necessarily better than an
8270273d0bSdan# automatic index scan.
8370273d0bSdan#
8470273d0bSdando_eqp_test 220 {
8570273d0bSdan  select count(*) from u, v where u.b = v.b and v.e > 34;
8670273d0bSdan} {
87b3f0276bSdrh  QUERY PLAN
88*8210233cSdrh  |--SEARCH v USING INDEX ve (e>?)
89*8210233cSdrh  `--SEARCH u USING AUTOMATIC COVERING INDEX (b=?)
9070273d0bSdan}
9170273d0bSdan
92dabe36d9Sdrh
93dabe36d9Sdrhfinish_test
94