xref: /sqlite-3.40.0/test/analyzeC.test (revision 8210233c)
125df48d9Sdrh# 2014-07-22
225df48d9Sdrh#
325df48d9Sdrh# The author disclaims copyright to this source code.  In place of
425df48d9Sdrh# a legal notice, here is a blessing:
525df48d9Sdrh#
625df48d9Sdrh#    May you do good and not evil.
725df48d9Sdrh#    May you find forgiveness for yourself and forgive others.
825df48d9Sdrh#    May you share freely, never taking more than you give.
925df48d9Sdrh#
1025df48d9Sdrh#***********************************************************************
1125df48d9Sdrh#
1225df48d9Sdrh# This file contains automated tests used to verify that the text terms
1325df48d9Sdrh# at the end of sqlite_stat1.stat are processed correctly.
1425df48d9Sdrh#
1525df48d9Sdrh#  (1) "unordered" means that the index cannot be used for ORDER BY
1625df48d9Sdrh#      or for range queries
1725df48d9Sdrh#
1825df48d9Sdrh#  (2) "sz=NNN" sets the relative size of the index entries
1925df48d9Sdrh#
2025df48d9Sdrh#  (3) All other fields are silently ignored
2125df48d9Sdrh#
2225df48d9Sdrh
2325df48d9Sdrhset testdir [file dirname $argv0]
2425df48d9Sdrhsource $testdir/tester.tcl
2525df48d9Sdrhset testprefix analyzeC
2625df48d9Sdrh
2725df48d9Sdrh# Baseline case.  Range queries work OK.  Indexes can be used for
2825df48d9Sdrh# ORDER BY.
2925df48d9Sdrh#
3025df48d9Sdrhdo_execsql_test 1.0 {
3125df48d9Sdrh  CREATE TABLE t1(a,b,c);
3225df48d9Sdrh  INSERT INTO t1(a,b,c)
3325df48d9Sdrh    VALUES(1,2,3),(7,8,9),(4,5,6),(10,11,12),(4,8,12),(1,11,111);
3425df48d9Sdrh  CREATE INDEX t1a ON t1(a);
3525df48d9Sdrh  CREATE INDEX t1b ON t1(b);
3625df48d9Sdrh  ANALYZE;
3725df48d9Sdrh  DELETE FROM sqlite_stat1;
3825df48d9Sdrh  INSERT INTO sqlite_stat1(tbl,idx,stat)
3925df48d9Sdrh    VALUES('t1','t1a','12345 2'),('t1','t1b','12345 4');
4025df48d9Sdrh  ANALYZE sqlite_master;
4125df48d9Sdrh  SELECT *, '#' FROM t1 WHERE a BETWEEN 3 AND 8 ORDER BY c;
4225df48d9Sdrh} {4 5 6 # 7 8 9 # 4 8 12 #}
4325df48d9Sdrhdo_execsql_test 1.1 {
4425df48d9Sdrh  EXPLAIN QUERY PLAN
4525df48d9Sdrh  SELECT *, '#' FROM t1 WHERE a BETWEEN 3 AND 8 ORDER BY c;
4625df48d9Sdrh} {/.* USING INDEX t1a .a>. AND a<...*/}
4725df48d9Sdrhdo_execsql_test 1.2 {
4825df48d9Sdrh  SELECT c FROM t1 ORDER BY a;
4925df48d9Sdrh} {3 111 6 12 9 12}
5025df48d9Sdrhdo_execsql_test 1.3 {
5125df48d9Sdrh  EXPLAIN QUERY PLAN
5225df48d9Sdrh  SELECT c FROM t1 ORDER BY a;
53*8210233cSdrh} {/.*SCAN t1 USING INDEX t1a.*/}
5425df48d9Sdrhdo_execsql_test 1.3x {
5525df48d9Sdrh  EXPLAIN QUERY PLAN
5625df48d9Sdrh  SELECT c FROM t1 ORDER BY a;
5725df48d9Sdrh} {~/.*B-TREE FOR ORDER BY.*/}
5825df48d9Sdrh
5925df48d9Sdrh# Now mark the t1a index as "unordered".  Range queries and ORDER BY no
6025df48d9Sdrh# longer use the index, but equality queries do.
6125df48d9Sdrh#
6225df48d9Sdrhdo_execsql_test 2.0 {
6325df48d9Sdrh  UPDATE sqlite_stat1 SET stat='12345 2 unordered' WHERE idx='t1a';
6425df48d9Sdrh  ANALYZE sqlite_master;
6525df48d9Sdrh  SELECT *, '#' FROM t1 WHERE a BETWEEN 3 AND 8 ORDER BY c;
6625df48d9Sdrh} {4 5 6 # 7 8 9 # 4 8 12 #}
6725df48d9Sdrhdo_execsql_test 2.1 {
6825df48d9Sdrh  EXPLAIN QUERY PLAN
6925df48d9Sdrh  SELECT *, '#' FROM t1 WHERE a BETWEEN 3 AND 8 ORDER BY c;
7025df48d9Sdrh} {~/.*USING INDEX.*/}
7125df48d9Sdrhdo_execsql_test 2.2 {
7225df48d9Sdrh  SELECT c FROM t1 ORDER BY a;
7325df48d9Sdrh} {3 111 6 12 9 12}
7425df48d9Sdrhdo_execsql_test 2.3 {
7525df48d9Sdrh  EXPLAIN QUERY PLAN
7625df48d9Sdrh  SELECT c FROM t1 ORDER BY a;
7725df48d9Sdrh} {~/.*USING INDEX.*/}
7825df48d9Sdrhdo_execsql_test 2.3x {
7925df48d9Sdrh  EXPLAIN QUERY PLAN
8025df48d9Sdrh  SELECT c FROM t1 ORDER BY a;
8125df48d9Sdrh} {/.*B-TREE FOR ORDER BY.*/}
8225df48d9Sdrh
8325df48d9Sdrh# Ignore extraneous text parameters in the sqlite_stat1.stat field.
8425df48d9Sdrh#
8525df48d9Sdrhdo_execsql_test 3.0 {
8625df48d9Sdrh  UPDATE sqlite_stat1 SET stat='12345 2 whatever=5 unordered xyzzy=11'
8725df48d9Sdrh   WHERE idx='t1a';
8825df48d9Sdrh  ANALYZE sqlite_master;
8925df48d9Sdrh  SELECT *, '#' FROM t1 WHERE a BETWEEN 3 AND 8 ORDER BY c;
9025df48d9Sdrh} {4 5 6 # 7 8 9 # 4 8 12 #}
9125df48d9Sdrhdo_execsql_test 3.1 {
9225df48d9Sdrh  EXPLAIN QUERY PLAN
9325df48d9Sdrh  SELECT *, '#' FROM t1 WHERE a BETWEEN 3 AND 8 ORDER BY c;
9425df48d9Sdrh} {~/.*USING INDEX.*/}
9525df48d9Sdrhdo_execsql_test 3.2 {
9625df48d9Sdrh  SELECT c FROM t1 ORDER BY a;
9725df48d9Sdrh} {3 111 6 12 9 12}
9825df48d9Sdrhdo_execsql_test 3.3 {
9925df48d9Sdrh  EXPLAIN QUERY PLAN
10025df48d9Sdrh  SELECT c FROM t1 ORDER BY a;
10125df48d9Sdrh} {~/.*USING INDEX.*/}
10225df48d9Sdrhdo_execsql_test 3.3x {
10325df48d9Sdrh  EXPLAIN QUERY PLAN
10425df48d9Sdrh  SELECT c FROM t1 ORDER BY a;
10525df48d9Sdrh} {/.*B-TREE FOR ORDER BY.*/}
10625df48d9Sdrh
10725df48d9Sdrh# The sz=NNN parameter determines which index to scan
10825df48d9Sdrh#
10925df48d9Sdrhdo_execsql_test 4.0 {
11025df48d9Sdrh  DROP INDEX t1a;
11125df48d9Sdrh  CREATE INDEX t1ab ON t1(a,b);
11225df48d9Sdrh  CREATE INDEX t1ca ON t1(c,a);
11325df48d9Sdrh  DELETE FROM sqlite_stat1;
11425df48d9Sdrh  INSERT INTO sqlite_stat1(tbl,idx,stat)
11525df48d9Sdrh    VALUES('t1','t1ab','12345 3 2 sz=10'),('t1','t1ca','12345 3 2 sz=20');
11625df48d9Sdrh  ANALYZE sqlite_master;
11725df48d9Sdrh  SELECT count(a) FROM t1;
11825df48d9Sdrh} {6}
11925df48d9Sdrhdo_execsql_test 4.1 {
12025df48d9Sdrh  EXPLAIN QUERY PLAN
12125df48d9Sdrh  SELECT count(a) FROM t1;
12225df48d9Sdrh} {/.*INDEX t1ab.*/}
12325df48d9Sdrhdo_execsql_test 4.2 {
12425df48d9Sdrh  DELETE FROM sqlite_stat1;
12525df48d9Sdrh  INSERT INTO sqlite_stat1(tbl,idx,stat)
12625df48d9Sdrh    VALUES('t1','t1ab','12345 3 2 sz=20'),('t1','t1ca','12345 3 2 sz=10');
12725df48d9Sdrh  ANALYZE sqlite_master;
12825df48d9Sdrh  SELECT count(a) FROM t1;
12925df48d9Sdrh} {6}
13025df48d9Sdrhdo_execsql_test 4.3 {
13125df48d9Sdrh  EXPLAIN QUERY PLAN
13225df48d9Sdrh  SELECT count(a) FROM t1;
13325df48d9Sdrh} {/.*INDEX t1ca.*/}
13425df48d9Sdrh
135725dd724Sdrh# 2019-08-15.
136725dd724Sdrh# Ticket https://www.sqlite.org/src/tktview/e4598ecbdd18bd82945f602901
137725dd724Sdrh# The sz=N parameter in the sqlite_stat1 table needs to have a value of
138725dd724Sdrh# 2 or more to avoid a division by zero in the query planner.
139725dd724Sdrh#
140725dd724Sdrhdo_execsql_test 4.4 {
141725dd724Sdrh  DROP TABLE IF EXISTS t44;
142725dd724Sdrh  CREATE TABLE t44(a PRIMARY KEY);
143725dd724Sdrh  INSERT INTO sqlite_stat1 VALUES('t44',null,'sz=0');
144725dd724Sdrh  ANALYZE sqlite_master;
145725dd724Sdrh  SELECT 0 FROM t44 WHERE a IN(1,2,3);
146725dd724Sdrh} {}
147725dd724Sdrh
148725dd724Sdrh
14925df48d9Sdrh
15025df48d9Sdrh# The sz=NNN parameter works even if there is other extraneous text
15125df48d9Sdrh# in the sqlite_stat1.stat column.
15225df48d9Sdrh#
15325df48d9Sdrhdo_execsql_test 5.0 {
15425df48d9Sdrh  DELETE FROM sqlite_stat1;
15525df48d9Sdrh  INSERT INTO sqlite_stat1(tbl,idx,stat)
15625df48d9Sdrh    VALUES('t1','t1ab','12345 3 2 x=5 sz=10 y=10'),
15725df48d9Sdrh          ('t1','t1ca','12345 3 2 whatever sz=20 junk');
15825df48d9Sdrh  ANALYZE sqlite_master;
15925df48d9Sdrh  SELECT count(a) FROM t1;
16025df48d9Sdrh} {6}
16125df48d9Sdrhdo_execsql_test 5.1 {
16225df48d9Sdrh  EXPLAIN QUERY PLAN
16325df48d9Sdrh  SELECT count(a) FROM t1;
16425df48d9Sdrh} {/.*INDEX t1ab.*/}
16525df48d9Sdrhdo_execsql_test 5.2 {
16625df48d9Sdrh  DELETE FROM sqlite_stat1;
16725df48d9Sdrh  INSERT INTO sqlite_stat1(tbl,idx,stat)
16825df48d9Sdrh    VALUES('t1','t1ca','12345 3 2 x=5 sz=10 y=10'),
16925df48d9Sdrh          ('t1','t1ab','12345 3 2 whatever sz=20 junk');
17025df48d9Sdrh  ANALYZE sqlite_master;
17125df48d9Sdrh  SELECT count(a) FROM t1;
17225df48d9Sdrh} {6}
17325df48d9Sdrhdo_execsql_test 5.3 {
17425df48d9Sdrh  EXPLAIN QUERY PLAN
17525df48d9Sdrh  SELECT count(a) FROM t1;
17625df48d9Sdrh} {/.*INDEX t1ca.*/}
17725df48d9Sdrh
17825df48d9Sdrh
17925df48d9Sdrh
18025df48d9Sdrh
18125df48d9Sdrhfinish_test
182