xref: /sqlite-3.40.0/test/autoanalyze1.test (revision a3928dd7)
1*a3928dd7Sdrh# 2017-02-17
2*a3928dd7Sdrh#
3*a3928dd7Sdrh# The author disclaims copyright to this source code.  In place of
4*a3928dd7Sdrh# a legal notice, here is a blessing:
5*a3928dd7Sdrh#
6*a3928dd7Sdrh#    May you do good and not evil.
7*a3928dd7Sdrh#    May you find forgiveness for yourself and forgive others.
8*a3928dd7Sdrh#    May you share freely, never taking more than you give.
9*a3928dd7Sdrh#
10*a3928dd7Sdrh#***********************************************************************
11*a3928dd7Sdrh#
12*a3928dd7Sdrh# This file implements tests for the logic used to estimate when
13*a3928dd7Sdrh# running ANALYZE would be beneficial.
14*a3928dd7Sdrh#
15*a3928dd7Sdrh# Note that this test uses some hard-coded bitmask values from sqliteInt.h.
16*a3928dd7Sdrh# If any of the following constants changes:
17*a3928dd7Sdrh#
18*a3928dd7Sdrh#    define TF_HasStat1   0x0010
19*a3928dd7Sdrh#    define TF_SizeChng   0x0100
20*a3928dd7Sdrh#    define TF_StatsUsed  0x0200
21*a3928dd7Sdrh#
22*a3928dd7Sdrh# then some of the magic numbers in test results below might need to be
23*a3928dd7Sdrh# adjusted.
24*a3928dd7Sdrh#
25*a3928dd7Sdrh
26*a3928dd7Sdrhset testdir [file dirname $argv0]
27*a3928dd7Sdrhsource $testdir/tester.tcl
28*a3928dd7Sdrh
29*a3928dd7Sdrh# There is nothing to test if ANALYZE is disable for this build.
30*a3928dd7Sdrh# These tests also use "PRAGMA stats" which are only enabled for
31*a3928dd7Sdrh# debugging builds.
32*a3928dd7Sdrh#
33*a3928dd7Sdrhifcapable {!debug || !analyze} {
34*a3928dd7Sdrh  finish_test
35*a3928dd7Sdrh  return
36*a3928dd7Sdrh}
37*a3928dd7Sdrh
38*a3928dd7Sdrhdo_execsql_test autoanalyze1-100 {
39*a3928dd7Sdrh  -- Build up a test table with some indexes
40*a3928dd7Sdrh  CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d);
41*a3928dd7Sdrh  CREATE UNIQUE INDEX t1bc ON t1(b,c);
42*a3928dd7Sdrh  CREATE INDEX t1d ON t1(d);
43*a3928dd7Sdrh  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100)
44*a3928dd7Sdrh    INSERT INTO t1(a,b,c,d) SELECT x, x, x, x FROM c;
45*a3928dd7Sdrh  -- Verify that the hasStat1 flag is clear on on indexes
46*a3928dd7Sdrh  SELECT idx, flgs FROM pragma_stats
47*a3928dd7Sdrh   WHERE idx IS NOT NULL
48*a3928dd7Sdrh   ORDER BY idx;
49*a3928dd7Sdrh  -- Verify that the TF_HasStat1 flag is clear on the table
50*a3928dd7Sdrh  SELECT tbl, (flgs & 0x10)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL;
51*a3928dd7Sdrh} {t1bc 0 t1d 0 t1 0}
52*a3928dd7Sdrh
53*a3928dd7Sdrh# No use of stat1 recorded so far
54*a3928dd7Sdrhdo_execsql_test autoanalyze1-110 {
55*a3928dd7Sdrh  SELECT (flgs & 0x0200)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL;
56*a3928dd7Sdrh} {0}
57*a3928dd7Sdrh
58*a3928dd7Sdrh# Access using a unique index does not set the TF_StatsUsed flag.
59*a3928dd7Sdrh#
60*a3928dd7Sdrhdo_execsql_test autoanalyze1-200 {
61*a3928dd7Sdrh  SELECT * FROM t1 WHERE a=55;
62*a3928dd7Sdrh} {55 55 55 55}
63*a3928dd7Sdrhdo_execsql_test autoanalyze1-201 {
64*a3928dd7Sdrh  SELECT (flgs & 0x0200)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL;
65*a3928dd7Sdrh} {0}
66*a3928dd7Sdrh
67*a3928dd7Sdrhdo_execsql_test autoanalyze1-210 {
68*a3928dd7Sdrh  SELECT * FROM t1 WHERE a IN (55,199,299);
69*a3928dd7Sdrh} {55 55 55 55}
70*a3928dd7Sdrhdo_execsql_test autoanalyze1-211 {
71*a3928dd7Sdrh  SELECT (flgs & 0x0200)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL;
72*a3928dd7Sdrh} {0}
73*a3928dd7Sdrh
74*a3928dd7Sdrhdo_execsql_test autoanalyze1-220 {
75*a3928dd7Sdrh  SELECT * FROM t1 WHERE (b,c)=(45,45);
76*a3928dd7Sdrh} {45 45 45 45}
77*a3928dd7Sdrhdo_execsql_test autoanalyze1-221 {
78*a3928dd7Sdrh  SELECT (flgs & 0x0200)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL;
79*a3928dd7Sdrh} {0}
80*a3928dd7Sdrh
81*a3928dd7Sdrh# Any use of the non-unique t1d index triggers the use of stats.
82*a3928dd7Sdrh#
83*a3928dd7Sdrhsqlite3 db test.db
84*a3928dd7Sdrhdo_execsql_test autoanalyze1-300 {
85*a3928dd7Sdrh  SELECT * FROM t1 WHERE d=45;
86*a3928dd7Sdrh} {45 45 45 45}
87*a3928dd7Sdrhdo_execsql_test autoanalyze1-301 {
88*a3928dd7Sdrh  SELECT (flgs & 0x0200)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL;
89*a3928dd7Sdrh} {1}
90*a3928dd7Sdrh
91*a3928dd7Sdrhsqlite3 db test.db
92*a3928dd7Sdrhdo_execsql_test autoanalyze1-310 {
93*a3928dd7Sdrh  SELECT * FROM t1 WHERE d=45 AND a=45;
94*a3928dd7Sdrh} {45 45 45 45}
95*a3928dd7Sdrhdo_execsql_test autoanalyze1-311 {
96*a3928dd7Sdrh  SELECT (flgs & 0x0200)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL;
97*a3928dd7Sdrh} {0}  ;# The ROWID lookup short-circuits the d=45 constraint
98*a3928dd7Sdrh
99*a3928dd7Sdrhsqlite3 db test.db
100*a3928dd7Sdrhdo_execsql_test autoanalyze1-320 {
101*a3928dd7Sdrh  SELECT * FROM t1 WHERE d=45 AND a IN (45,46);
102*a3928dd7Sdrh} {45 45 45 45}
103*a3928dd7Sdrhdo_execsql_test autoanalyze1-321 {
104*a3928dd7Sdrh  SELECT (flgs & 0x0200)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL;
105*a3928dd7Sdrh} {1}
106*a3928dd7Sdrh
107*a3928dd7Sdrh# Any use of prefix of a unique index triggers the use of stats
108*a3928dd7Sdrh#
109*a3928dd7Sdrhsqlite3 db test.db
110*a3928dd7Sdrhdo_execsql_test autoanalyze1-400 {
111*a3928dd7Sdrh  SELECT * FROM t1 WHERE b=45;
112*a3928dd7Sdrh} {45 45 45 45}
113*a3928dd7Sdrhdo_execsql_test autoanalyze1-401 {
114*a3928dd7Sdrh  SELECT (flgs & 0x0200)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL;
115*a3928dd7Sdrh} {1}
116*a3928dd7Sdrh
117*a3928dd7Sdrh# The TF_StatsUsed flag is reset when the database is reopened
118*a3928dd7Sdrh#
119*a3928dd7Sdrhsqlite3 db test.db
120*a3928dd7Sdrhdo_execsql_test autoanalyze1-500 {
121*a3928dd7Sdrh  SELECT (flgs & 0x0200)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL;
122*a3928dd7Sdrh} {0}
123*a3928dd7Sdrh
124*a3928dd7Sdrhfinish_test
125