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