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