163da0893Sdrh# 2010 March 10 263da0893Sdrh# 363da0893Sdrh# The author disclaims copyright to this source code. In place of 463da0893Sdrh# a legal notice, here is a blessing: 563da0893Sdrh# 663da0893Sdrh# May you do good and not evil. 763da0893Sdrh# May you find forgiveness for yourself and forgive others. 863da0893Sdrh# May you share freely, never taking more than you give. 963da0893Sdrh# 1063da0893Sdrh#*********************************************************************** 1163da0893Sdrh# 1263da0893Sdrh# Tests for the sqlite3_db_status() function 1363da0893Sdrh# 1463da0893Sdrh 1563da0893Sdrhset testdir [file dirname $argv0] 1663da0893Sdrhsource $testdir/tester.tcl 17272989b4Sdanset testprefix dbstatus 1863da0893Sdrh 192f56da3fSdanifcapable !compound { 202f56da3fSdan finish_test 212f56da3fSdan return 222f56da3fSdan} 232f56da3fSdan 24887f8d39Sdrh# Memory statistics must be enabled for this test. 25887f8d39Sdrhdb close 26887f8d39Sdrhsqlite3_shutdown 27887f8d39Sdrhsqlite3_config_memstatus 1 28272989b4Sdansqlite3_config_uri 1 29887f8d39Sdrhsqlite3_initialize 30887f8d39Sdrhsqlite3 db test.db 31887f8d39Sdrh 3263da0893Sdrh 3363da0893Sdrh# Make sure sqlite3_db_config() and sqlite3_db_status are working. 3463da0893Sdrh# 3563da0893Sdrhunset -nocomplain PAGESZ 3663da0893Sdrhunset -nocomplain BASESZ 3763da0893Sdrhdo_test dbstatus-1.1 { 3863da0893Sdrh db close 3963da0893Sdrh sqlite3 db :memory: 4063da0893Sdrh db eval { 4163da0893Sdrh CREATE TABLE t1(x); 4263da0893Sdrh } 4363da0893Sdrh set sz1 [lindex [sqlite3_db_status db SQLITE_DBSTATUS_CACHE_USED 0] 1] 4463da0893Sdrh db eval { 4563da0893Sdrh CREATE TABLE t2(y); 4663da0893Sdrh } 4763da0893Sdrh set sz2 [lindex [sqlite3_db_status db SQLITE_DBSTATUS_CACHE_USED 0] 1] 4863da0893Sdrh set ::PAGESZ [expr {$sz2-$sz1}] 4963da0893Sdrh set ::BASESZ [expr {$sz1-$::PAGESZ}] 5060a31178Sdrh expr {$::PAGESZ>1024 && $::PAGESZ<1300} 5163da0893Sdrh} {1} 5263da0893Sdrhdo_test dbstatus-1.2 { 5363da0893Sdrh db eval { 5463da0893Sdrh INSERT INTO t1 VALUES(zeroblob(9000)); 5563da0893Sdrh } 5663da0893Sdrh lindex [sqlite3_db_status db SQLITE_DBSTATUS_CACHE_USED 0] 1 5763da0893Sdrh} [expr {$BASESZ + 10*$PAGESZ}] 5863da0893Sdrh 59d46def77Sdan 60d46def77Sdanproc lookaside {db} { 61d46def77Sdan expr { $::lookaside_buffer_size * 62d46def77Sdan [lindex [sqlite3_db_status $db SQLITE_DBSTATUS_LOOKASIDE_USED 0] 1] 63d46def77Sdan } 64d46def77Sdan} 65d46def77Sdan 66*175b8f06Sdrhifcapable stat4 { 674e50c5ecSdrh set STAT3 1 684e50c5ecSdrh} else { 694e50c5ecSdrh set STAT3 0 704e50c5ecSdrh} 714e50c5ecSdrh 72d46def77Sdan#--------------------------------------------------------------------------- 73643f35e4Sdrh# Run the dbstatus-2 and dbstatus-3 tests with several of different 74d46def77Sdan# lookaside buffer sizes. 75d46def77Sdan# 76d46def77Sdanforeach ::lookaside_buffer_size {0 64 120} { 77e39cd91aSdrh ifcapable malloc_usable_size break 78d46def77Sdan 794f7b8d62Sdan # Do not run any of these tests if there is SQL configured to run 804f7b8d62Sdan # as part of the [sqlite3] command. This prevents the script from 814f7b8d62Sdan # configuring the size of the lookaside buffer after [sqlite3] has 824f7b8d62Sdan # returned. 834f7b8d62Sdan if {[presql] != ""} break 844f7b8d62Sdan 85d46def77Sdan #------------------------------------------------------------------------- 86d46def77Sdan # Tests for SQLITE_DBSTATUS_SCHEMA_USED. 87d46def77Sdan # 88d46def77Sdan # Each test in the following block works as follows. Each test uses a 89d46def77Sdan # different database schema. 90d46def77Sdan # 91d46def77Sdan # 1. Open a connection to an empty database. Disable statement caching. 92d46def77Sdan # 93d46def77Sdan # 2. Execute the SQL to create the database schema. Measure the total 94d46def77Sdan # heap and lookaside memory allocated by SQLite, and the memory 95d46def77Sdan # allocated for the database schema according to sqlite3_db_status(). 96d46def77Sdan # 97d46def77Sdan # 3. Drop all tables in the database schema. Measure the total memory 98d46def77Sdan # and the schema memory again. 99d46def77Sdan # 100d46def77Sdan # 4. Repeat step 2. 101d46def77Sdan # 102d46def77Sdan # 5. Repeat step 3. 103d46def77Sdan # 104d46def77Sdan # Then test that: 105d46def77Sdan # 106d46def77Sdan # a) The difference in schema memory quantities in steps 2 and 3 is the 107d46def77Sdan # same as the difference in total memory in steps 2 and 3. 108d46def77Sdan # 109d46def77Sdan # b) Step 4 reports the same amount of schema and total memory used as 110d46def77Sdan # in step 2. 111d46def77Sdan # 112d46def77Sdan # c) Step 5 reports the same amount of schema and total memory used as 113d46def77Sdan # in step 3. 114d46def77Sdan # 115d46def77Sdan foreach {tn schema} { 116d46def77Sdan 1 { CREATE TABLE t1(a, b) } 117d46def77Sdan 2 { CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1, c UNIQUE) } 118d46def77Sdan 3 { 119d46def77Sdan CREATE TABLE t1(a, b); 120d46def77Sdan CREATE INDEX i1 ON t1(a, b); 121d46def77Sdan } 122d46def77Sdan 4 { 123d46def77Sdan CREATE TABLE t1(a, b); 124d46def77Sdan CREATE TABLE t2(c, d); 125d46def77Sdan CREATE TRIGGER AFTER INSERT ON t1 BEGIN 126d46def77Sdan INSERT INTO t2 VALUES(new.a, new.b); 127d46def77Sdan SELECT * FROM t1, t2 WHERE a=c AND b=d GROUP BY b HAVING a>5 ORDER BY a; 128d46def77Sdan END; 129d46def77Sdan } 130d46def77Sdan 5 { 131d46def77Sdan CREATE TABLE t1(a, b); 132d46def77Sdan CREATE TABLE t2(c, d); 133d46def77Sdan CREATE VIEW v1 AS SELECT * FROM t1 UNION SELECT * FROM t2; 134d46def77Sdan } 135d55bccd7Smistachkin 6k { 136d46def77Sdan CREATE TABLE t1(a, b); 137d46def77Sdan CREATE INDEX i1 ON t1(a); 138d46def77Sdan CREATE INDEX i2 ON t1(a,b); 139d46def77Sdan CREATE INDEX i3 ON t1(b,b); 140d46def77Sdan INSERT INTO t1 VALUES(randomblob(20), randomblob(25)); 141d46def77Sdan INSERT INTO t1 SELECT randomblob(20), randomblob(25) FROM t1; 142d46def77Sdan INSERT INTO t1 SELECT randomblob(20), randomblob(25) FROM t1; 143d46def77Sdan INSERT INTO t1 SELECT randomblob(20), randomblob(25) FROM t1; 144d46def77Sdan ANALYZE; 145d46def77Sdan } 146d46def77Sdan 7 { 147d46def77Sdan CREATE TABLE t1(a, b); 148d46def77Sdan CREATE TABLE t2(c, d); 149d46def77Sdan CREATE VIEW v1 AS 150d46def77Sdan SELECT * FROM t1 151d46def77Sdan UNION 152d46def77Sdan SELECT * FROM t2 153d46def77Sdan UNION ALL 154d46def77Sdan SELECT c||b, d||a FROM t2 LEFT OUTER JOIN t1 GROUP BY c, d 155d46def77Sdan ORDER BY 1, 2 156d46def77Sdan ; 157d46def77Sdan CREATE TRIGGER tr1 INSTEAD OF INSERT ON v1 BEGIN 158d46def77Sdan SELECT * FROM v1; 159d46def77Sdan UPDATE t1 SET a=5, b=(SELECT c FROM t2); 160d46def77Sdan END; 161d46def77Sdan SELECT * FROM v1; 162d46def77Sdan } 163ccd4ad3eSdan 8x { 164ccd4ad3eSdan CREATE TABLE t1(a, b, UNIQUE(a, b)); 165ccd4ad3eSdan CREATE VIRTUAL TABLE t2 USING echo(t1); 166ccd4ad3eSdan } 167d46def77Sdan } { 168d46def77Sdan set tn "$::lookaside_buffer_size-$tn" 169d46def77Sdan 170d46def77Sdan # Step 1. 171d46def77Sdan db close 172fda06befSmistachkin forcedelete test.db 173d46def77Sdan sqlite3 db test.db 174d46def77Sdan sqlite3_db_config_lookaside db 0 $::lookaside_buffer_size 500 175d46def77Sdan db cache size 0 176d46def77Sdan 177ccd4ad3eSdan catch { register_echo_module db } 178ccd4ad3eSdan ifcapable !vtab { if {[string match *x $tn]} continue } 179ccd4ad3eSdan 180d46def77Sdan # Step 2. 181d46def77Sdan execsql $schema 182d46def77Sdan set nAlloc1 [lindex [sqlite3_status SQLITE_STATUS_MEMORY_USED 0] 1] 183d46def77Sdan incr nAlloc1 [lookaside db] 184d46def77Sdan set nSchema1 [lindex [sqlite3_db_status db SQLITE_DBSTATUS_SCHEMA_USED 0] 1] 185d46def77Sdan 186d46def77Sdan # Step 3. 187d46def77Sdan drop_all_tables 188d46def77Sdan set nAlloc2 [lindex [sqlite3_status SQLITE_STATUS_MEMORY_USED 0] 1] 189d46def77Sdan incr nAlloc2 [lookaside db] 190d46def77Sdan set nSchema2 [lindex [sqlite3_db_status db SQLITE_DBSTATUS_SCHEMA_USED 0] 1] 191d46def77Sdan 192d46def77Sdan # Step 4. 193d46def77Sdan execsql $schema 194d46def77Sdan set nAlloc3 [lindex [sqlite3_status SQLITE_STATUS_MEMORY_USED 0] 1] 195d46def77Sdan incr nAlloc3 [lookaside db] 196d46def77Sdan set nSchema3 [lindex [sqlite3_db_status db SQLITE_DBSTATUS_SCHEMA_USED 0] 1] 197d46def77Sdan 198d46def77Sdan # Step 5. 199d46def77Sdan drop_all_tables 200d46def77Sdan set nAlloc4 [lindex [sqlite3_status SQLITE_STATUS_MEMORY_USED 0] 1] 201d46def77Sdan incr nAlloc4 [lookaside db] 202d46def77Sdan set nSchema4 [lindex [sqlite3_db_status db SQLITE_DBSTATUS_SCHEMA_USED 0] 1] 203d46def77Sdan set nFree [expr {$nAlloc1-$nAlloc2}] 204ccd4ad3eSdan 205d55bccd7Smistachkin # Tests for which the test name ends in an "k" report slightly less 206d55bccd7Smistachkin # memory than is actually freed when all schema items are finalized. 207d55bccd7Smistachkin # This is because memory allocated by KeyInfo objects is no longer 208d55bccd7Smistachkin # counted as "schema memory". 209d55bccd7Smistachkin # 210ccd4ad3eSdan # Tests for which the test name ends in an "x" report slightly less 211d47f0d78Sdan # memory than is actually freed when all schema items are finalized. 212d47f0d78Sdan # This is because memory allocated by virtual table implementations 213d47f0d78Sdan # for any reason is not counted as "schema memory". 214ccd4ad3eSdan # 215d47f0d78Sdan # Additionally, in auto-vacuum mode, dropping tables and indexes causes 216d47f0d78Sdan # the page-cache to shrink. So the amount of memory freed is always 217d47f0d78Sdan # much greater than just that reported by DBSTATUS_SCHEMA_USED in this 218d47f0d78Sdan # case. 219d47f0d78Sdan # 220f52bb8d3Sdan # Some of the memory used for sqlite_stat4 is unaccounted for by 2214e50c5ecSdrh # dbstatus. 2224e50c5ecSdrh # 2234373bb88Sdan # Finally, on osx the estimate of memory used by the schema may be 2244373bb88Sdan # slightly low. 2254373bb88Sdan # 226d55bccd7Smistachkin if {[string match *k $tn] 227d55bccd7Smistachkin || [string match *x $tn] || $AUTOVACUUM 2284373bb88Sdan || ([string match *y $tn] && $STAT3) 2294373bb88Sdan || ($::tcl_platform(os) == "Darwin") 2304373bb88Sdan } { 231ccd4ad3eSdan do_test dbstatus-2.$tn.ax { expr {($nSchema1-$nSchema2)<=$nFree} } 1 232ccd4ad3eSdan } else { 233d46def77Sdan do_test dbstatus-2.$tn.a { expr {$nSchema1-$nSchema2} } $nFree 234ccd4ad3eSdan } 235ccd4ad3eSdan 236d46def77Sdan do_test dbstatus-2.$tn.b { list $nAlloc1 $nSchema1 } "$nAlloc3 $nSchema3" 237d46def77Sdan do_test dbstatus-2.$tn.c { list $nAlloc2 $nSchema2 } "$nAlloc4 $nSchema4" 238d46def77Sdan } 239d46def77Sdan 240d46def77Sdan #------------------------------------------------------------------------- 241d46def77Sdan # Tests for SQLITE_DBSTATUS_STMT_USED. 242d46def77Sdan # 243d46def77Sdan # Each test in the following block works as follows. Each test uses a 244d46def77Sdan # different database schema. 245d46def77Sdan # 246d46def77Sdan # 1. Open a connection to an empty database. Initialized the database 247d46def77Sdan # schema. 248d46def77Sdan # 249d46def77Sdan # 2. Prepare a bunch of SQL statements. Measure the total heap and 250d46def77Sdan # lookaside memory allocated by SQLite, and the memory allocated 251d46def77Sdan # for the prepared statements according to sqlite3_db_status(). 252d46def77Sdan # 253d55bccd7Smistachkin # 3. Finalize all prepared statements. Measure the total memory 254d46def77Sdan # and the prepared statement memory again. 255d46def77Sdan # 256d46def77Sdan # 4. Repeat step 2. 257d46def77Sdan # 258d46def77Sdan # 5. Repeat step 3. 259d46def77Sdan # 260d46def77Sdan # Then test that: 261d46def77Sdan # 262d46def77Sdan # a) The difference in schema memory quantities in steps 2 and 3 is the 263d46def77Sdan # same as the difference in total memory in steps 2 and 3. 264d46def77Sdan # 265d46def77Sdan # b) Step 4 reports the same amount of schema and total memory used as 266d46def77Sdan # in step 2. 267d46def77Sdan # 268d46def77Sdan # c) Step 5 reports the same amount of schema and total memory used as 269d46def77Sdan # in step 3. 270d46def77Sdan # 271d46def77Sdan foreach {tn schema statements} { 272d46def77Sdan 1 { CREATE TABLE t1(a, b) } { 273d46def77Sdan SELECT * FROM t1; 274d46def77Sdan INSERT INTO t1 VALUES(1, 2); 275d46def77Sdan INSERT INTO t1 SELECT * FROM t1; 276d46def77Sdan UPDATE t1 SET a=5; 277d46def77Sdan DELETE FROM t1; 278d46def77Sdan } 279d46def77Sdan 2 { 280d46def77Sdan PRAGMA recursive_triggers = 1; 281d46def77Sdan CREATE TABLE t1(a, b); 282d46def77Sdan CREATE TRIGGER tr1 AFTER INSERT ON t1 WHEN (new.a>0) BEGIN 283d46def77Sdan INSERT INTO t1 VALUES(new.a-1, new.b); 284d46def77Sdan END; 285d46def77Sdan } { 286d46def77Sdan INSERT INTO t1 VALUES(5, 'x'); 287d46def77Sdan } 288d46def77Sdan 3 { 289d46def77Sdan PRAGMA recursive_triggers = 1; 290d46def77Sdan CREATE TABLE t1(a, b); 291d46def77Sdan CREATE TABLE t2(a, b); 292d46def77Sdan CREATE TRIGGER tr1 AFTER INSERT ON t1 WHEN (new.a>0) BEGIN 293d46def77Sdan INSERT INTO t2 VALUES(new.a-1, new.b); 294d46def77Sdan END; 295d46def77Sdan CREATE TRIGGER tr2 AFTER INSERT ON t1 WHEN (new.a>0) BEGIN 296d46def77Sdan INSERT INTO t1 VALUES(new.a-1, new.b); 297d46def77Sdan END; 298d46def77Sdan } { 299d46def77Sdan INSERT INTO t1 VALUES(10, 'x'); 300d46def77Sdan } 301d46def77Sdan 4 { 302d46def77Sdan CREATE TABLE t1(a, b); 303d46def77Sdan } { 304d46def77Sdan SELECT count(*) FROM t1 WHERE upper(a)='ABC'; 305d46def77Sdan } 306ccd4ad3eSdan 5x { 307ccd4ad3eSdan CREATE TABLE t1(a, b UNIQUE); 308ccd4ad3eSdan CREATE VIRTUAL TABLE t2 USING echo(t1); 309ccd4ad3eSdan } { 310ccd4ad3eSdan SELECT count(*) FROM t2; 311ccd4ad3eSdan SELECT * FROM t2 WHERE b>5; 312ccd4ad3eSdan SELECT * FROM t2 WHERE b='abcdefg'; 313ccd4ad3eSdan } 314d46def77Sdan } { 315d46def77Sdan set tn "$::lookaside_buffer_size-$tn" 316d46def77Sdan 317d46def77Sdan # Step 1. 318d46def77Sdan db close 319fda06befSmistachkin forcedelete test.db 320d46def77Sdan sqlite3 db test.db 321d46def77Sdan sqlite3_db_config_lookaside db 0 $::lookaside_buffer_size 500 322d46def77Sdan db cache size 1000 323d46def77Sdan 324ccd4ad3eSdan catch { register_echo_module db } 325ccd4ad3eSdan ifcapable !vtab { if {[string match *x $tn]} continue } 326ccd4ad3eSdan 327d46def77Sdan execsql $schema 328d46def77Sdan db cache flush 329d46def77Sdan 330d46def77Sdan # Step 2. 331d46def77Sdan execsql $statements 332d46def77Sdan set nAlloc1 [lindex [sqlite3_status SQLITE_STATUS_MEMORY_USED 0] 1] 333d46def77Sdan incr nAlloc1 [lookaside db] 334d46def77Sdan set nStmt1 [lindex [sqlite3_db_status db SQLITE_DBSTATUS_STMT_USED 0] 1] 335d46def77Sdan execsql $statements 336d46def77Sdan 337d46def77Sdan # Step 3. 338d46def77Sdan db cache flush 339d46def77Sdan set nAlloc2 [lindex [sqlite3_status SQLITE_STATUS_MEMORY_USED 0] 1] 340111becfbSdan incr nAlloc2 [lookaside db] 341d46def77Sdan set nStmt2 [lindex [sqlite3_db_status db SQLITE_DBSTATUS_STMT_USED 0] 1] 342d46def77Sdan 343d46def77Sdan # Step 3. 344d46def77Sdan execsql $statements 345d46def77Sdan set nAlloc3 [lindex [sqlite3_status SQLITE_STATUS_MEMORY_USED 0] 1] 346d46def77Sdan incr nAlloc3 [lookaside db] 347d46def77Sdan set nStmt3 [lindex [sqlite3_db_status db SQLITE_DBSTATUS_STMT_USED 0] 1] 348d46def77Sdan execsql $statements 349d46def77Sdan 350d46def77Sdan # Step 4. 351d46def77Sdan db cache flush 352d46def77Sdan set nAlloc4 [lindex [sqlite3_status SQLITE_STATUS_MEMORY_USED 0] 1] 353d46def77Sdan incr nAlloc4 [lookaside db] 354d46def77Sdan set nStmt4 [lindex [sqlite3_db_status db SQLITE_DBSTATUS_STMT_USED 0] 1] 355d46def77Sdan 356d46def77Sdan set nFree [expr {$nAlloc1-$nAlloc2}] 357ccd4ad3eSdan 358ccd4ad3eSdan do_test dbstatus-3.$tn.a { expr $nStmt2 } {0} 359ccd4ad3eSdan 360ccd4ad3eSdan # Tests for which the test name ends in an "x" report slightly less 361ccd4ad3eSdan # memory than is actually freed when all statements are finalized. 362ccd4ad3eSdan # This is because a small amount of memory allocated by a virtual table 363ccd4ad3eSdan # implementation using sqlite3_mprintf() is technically considered 364ccd4ad3eSdan # external and so is not counted as "statement memory". 365ccd4ad3eSdan # 366d47f0d78Sdan#puts "$nStmt1 $nFree" 367ccd4ad3eSdan if {[string match *x $tn]} { 368ccd4ad3eSdan do_test dbstatus-3.$tn.bx { expr $nStmt1<=$nFree } {1} 369ccd4ad3eSdan } else { 370ccd4ad3eSdan do_test dbstatus-3.$tn.b { expr $nStmt1==$nFree } {1} 371ccd4ad3eSdan } 372ccd4ad3eSdan 373d46def77Sdan do_test dbstatus-3.$tn.c { list $nAlloc1 $nStmt1 } [list $nAlloc3 $nStmt3] 374d46def77Sdan do_test dbstatus-3.$tn.d { list $nAlloc2 $nStmt2 } [list $nAlloc4 $nStmt4] 375d46def77Sdan } 376d46def77Sdan} 377d46def77Sdan 378272989b4Sdan#------------------------------------------------------------------------- 3799c10608aSdan# The following tests focus on DBSTATUS_CACHE_USED_SHARED 380272989b4Sdan# 381272989b4Sdanifcapable shared_cache { 382bafad061Sdrh if {([permutation]=="memsys3" 3832aed9795Sdrh || [permutation]=="memsys5" 384bafad061Sdrh || $::tcl_platform(os)=="Linux") && ![sqlite3 -has-codec]} { 385272989b4Sdan proc do_cacheused_test {tn db res} { 386272989b4Sdan set cu [sqlite3_db_status $db SQLITE_DBSTATUS_CACHE_USED 0] 3879c10608aSdan set pcu [sqlite3_db_status $db SQLITE_DBSTATUS_CACHE_USED_SHARED 0] 388272989b4Sdan set cu [lindex $cu 1] 389272989b4Sdan set pcu [lindex $pcu 1] 390e39cd91aSdrh uplevel [list do_test $tn [list list $cu $pcu] "#/$res/"] 391272989b4Sdan } 392272989b4Sdan reset_db 393272989b4Sdan sqlite3 db file:test.db?cache=shared 394272989b4Sdan 395272989b4Sdan do_execsql_test 4.0 { 39649dcd79eSdrh PRAGMA auto_vacuum=NONE; 397272989b4Sdan CREATE TABLE t1(a, b, c); 398272989b4Sdan INSERT INTO t1 VALUES(1, 2, 3); 399272989b4Sdan } 400272989b4Sdan do_cacheused_test 4.0.1 db { 4568 4568 } 401272989b4Sdan do_execsql_test 4.1 { 402272989b4Sdan CREATE TEMP TABLE tt(a, b, c); 403272989b4Sdan INSERT INTO tt VALUES(1, 2, 3); 404272989b4Sdan } 405272989b4Sdan do_cacheused_test 4.1.1 db { 9000 9000 } 406272989b4Sdan 407272989b4Sdan sqlite3 db2 file:test.db?cache=shared 408272989b4Sdan do_cacheused_test 4.2.1 db2 { 4568 2284 } 409272989b4Sdan do_cacheused_test 4.2.2 db { 9000 6716 } 410272989b4Sdan db close 411272989b4Sdan do_cacheused_test 4.2.3 db2 { 4568 4568 } 412272989b4Sdan sqlite3 db file:test.db?cache=shared 413272989b4Sdan do_cacheused_test 4.2.4 db2 { 4568 2284 } 414272989b4Sdan db2 close 415272989b4Sdan } 4162aed9795Sdrh} 417272989b4Sdan 41868cf69edSdan#------------------------------------------------------------------------- 41968cf69edSdan# Test that passing an out-of-range value to sqlite3_stmt_status does 42068cf69edSdan# not cause a crash. 42168cf69edSdanreset_db 42268cf69edSdando_execsql_test 5.0 { 42368cf69edSdan CREATE TABLE t1(x, y); 42468cf69edSdan INSERT INTO t1 VALUES(1, 2); 42568cf69edSdan INSERT INTO t1 VALUES(3, 4); 42668cf69edSdan} 42768cf69edSdan 42868cf69edSdando_test 5.1 { 42968cf69edSdan set ::stmt [sqlite3_prepare db "SELECT * FROM t1" -1 dummy] 43068cf69edSdan sqlite3_step $::stmt 43168cf69edSdan sqlite3_step $::stmt 43268cf69edSdan sqlite3_step $::stmt 43368cf69edSdan sqlite3_reset $::stmt 43468cf69edSdan} {SQLITE_OK} 43568cf69edSdan 43615ca9e3eSdrhifcapable api_armor { 43768cf69edSdan do_test 5.2 { sqlite3_stmt_status $::stmt -1 0 } 0 43815ca9e3eSdrh} 43915ca9e3eSdrhdo_test 5.3 { sqlite3_stmt_status $::stmt 0 0 } 0 44068cf69edSdando_test 5.4 { 44168cf69edSdan expr [sqlite3_stmt_status $::stmt 99 0]>0 44268cf69edSdan} 1 44368cf69edSdanforeach {tn id res} { 44468cf69edSdan 1 SQLITE_STMTSTATUS_MEMUSED 1 44568cf69edSdan 2 SQLITE_STMTSTATUS_FULLSCAN_STEP 1 44668cf69edSdan 3 SQLITE_STMTSTATUS_SORT 0 44768cf69edSdan 4 SQLITE_STMTSTATUS_AUTOINDEX 0 44868cf69edSdan 5 SQLITE_STMTSTATUS_VM_STEP 1 44968cf69edSdan 6 SQLITE_STMTSTATUS_REPREPARE 0 45068cf69edSdan 7 SQLITE_STMTSTATUS_RUN 1 45168cf69edSdan} { 45268cf69edSdanif {$tn==2} breakpoint 45368cf69edSdan do_test 5.5.$tn { expr [sqlite3_stmt_status $::stmt $id 0]>0 } $res 45468cf69edSdan} 45568cf69edSdan 45668cf69edSdansqlite3_finalize $::stmt 45763da0893Sdrhfinish_test 458