16d3eb82bSdan# 2010 July 09 26d3eb82bSdan# 36d3eb82bSdan# The author disclaims copyright to this source code. In place of 46d3eb82bSdan# a legal notice, here is a blessing: 56d3eb82bSdan# 66d3eb82bSdan# May you do good and not evil. 76d3eb82bSdan# May you find forgiveness for yourself and forgive others. 86d3eb82bSdan# May you share freely, never taking more than you give. 96d3eb82bSdan# 106d3eb82bSdan#*********************************************************************** 116d3eb82bSdan# This file implements regression tests for SQLite library. The 126d3eb82bSdan# focus of this file is testing the SELECT statement. 136d3eb82bSdan# 146d3eb82bSdan 156d3eb82bSdanset testdir [file dirname $argv0] 166d3eb82bSdansource $testdir/tester.tcl 17b5c557b8Sdanset testprefix stat 186d3eb82bSdan 192f56da3fSdanifcapable !vtab||!compound { 206d3eb82bSdan finish_test 216d3eb82bSdan return 226d3eb82bSdan} 236d3eb82bSdan 247da56b4fSdrh# This module uses hard-coded results that depend on exact measurements of 257da56b4fSdrh# pages sizes at the byte level, and hence will not work if the reserved_bytes 267da56b4fSdrh# value is nonzero. 277da56b4fSdrhif {[nonzero_reserved_bytes]} {finish_test; return;} 286d3eb82bSdan 296d3eb82bSdanset ::asc 1 306d3eb82bSdanproc a_string {n} { string range [string repeat [incr ::asc]. $n] 1 $n } 316d3eb82bSdandb func a_string a_string 326d3eb82bSdan 336d3eb82bSdanregister_dbstat_vtab db 346d3eb82bSdando_execsql_test stat-0.0 { 354d249e61Sdrh PRAGMA table_info(dbstat); 366c0e41b9Sdrh} {/0 name TEXT .* 1 path TEXT .* 9 pgsize INTEGER/} 375360b55cSdrh 385360b55cSdrh# Attempts to drop an eponymous virtual table are a no-op. 3935c7312fSdando_catchsql_test stat-0.1a { 405360b55cSdrh DROP TABLE dbstat; 4135c7312fSdan} {1 {table dbstat may not be dropped}} 4235c7312fSdando_execsql_test stat-0.1b { 435360b55cSdrh PRAGMA table_info=dbstat; 445360b55cSdrh} {/0 name TEXT .* 1 path TEXT .* 9 pgsize INTEGER/} 455360b55cSdrh 465360b55cSdrhdb close 475360b55cSdrhforcedelete test.db 485360b55cSdrhsqlite3 db test.db 495360b55cSdrhdb func a_string a_string 505360b55cSdrhregister_dbstat_vtab db 515360b55cSdrhdo_execsql_test stat-0.2 { 521fab01acSdan PRAGMA auto_vacuum = OFF; 536d3eb82bSdan CREATE VIRTUAL TABLE temp.stat USING dbstat; 546d3eb82bSdan SELECT * FROM stat; 556d3eb82bSdan} {} 569091f775Sshaneh 575360b55cSdrh 5805accd22Sdanif {[wal_is_capable]} { 596d3eb82bSdan do_execsql_test stat-0.1 { 606d3eb82bSdan PRAGMA journal_mode = WAL; 616d3eb82bSdan PRAGMA journal_mode = delete; 624c9f129dSdrh SELECT name, path, pageno, pagetype, ncell, payload, unused, mx_payload 634c9f129dSdrh FROM stat; 641e32bed3Sdrh } {wal delete sqlite_schema / 1 leaf 0 0 916 0} 659091f775Sshaneh} 666d3eb82bSdan 676d3eb82bSdando_test stat-1.0 { 686d3eb82bSdan execsql { 696d3eb82bSdan CREATE TABLE t1(a, b); 706d3eb82bSdan CREATE INDEX i1 ON t1(b); 712d07f260Sdan INSERT INTO t1(rowid, a, b) VALUES(2, 2, 3); 722d07f260Sdan INSERT INTO t1(rowid, a, b) VALUES(3, 4, 5); 736d3eb82bSdan } 746d3eb82bSdan} {} 756d3eb82bSdando_test stat-1.1 { 766d3eb82bSdan execsql { 774c9f129dSdrh SELECT name, path, pageno, pagetype, ncell, payload, unused, mx_payload 784c9f129dSdrh FROM stat WHERE name = 't1'; 796d3eb82bSdan } 806d3eb82bSdan} {t1 / 2 leaf 2 10 998 5} 816d3eb82bSdando_test stat-1.2 { 826d3eb82bSdan execsql { 834c9f129dSdrh SELECT name, path, pageno, pagetype, ncell, payload, unused, mx_payload 844c9f129dSdrh FROM stat WHERE name = 'i1'; 856d3eb82bSdan } 866d3eb82bSdan} {i1 / 3 leaf 2 10 1000 5} 876d3eb82bSdando_test stat-1.3 { 886d3eb82bSdan execsql { 894c9f129dSdrh SELECT name, path, pageno, pagetype, ncell, payload, unused, mx_payload 901e32bed3Sdrh FROM stat WHERE name = 'sqlite_schema'; 916d3eb82bSdan } 921e32bed3Sdrh} {sqlite_schema / 1 leaf 2 77 831 40} 936d3eb82bSdando_test stat-1.4 { 946d3eb82bSdan execsql { 956d3eb82bSdan DROP TABLE t1; 966d3eb82bSdan } 976d3eb82bSdan} {} 986d3eb82bSdan 996d3eb82bSdando_execsql_test stat-2.1 { 1006d3eb82bSdan CREATE TABLE t3(a PRIMARY KEY, b); 1012d07f260Sdan INSERT INTO t3(rowid, a, b) VALUES(2, a_string(111), a_string(222)); 1023f4d1d1bSdrh INSERT INTO t3 SELECT a_string(110+rowid), a_string(221+rowid) FROM t3 1033f4d1d1bSdrh ORDER BY rowid; 1043f4d1d1bSdrh INSERT INTO t3 SELECT a_string(110+rowid), a_string(221+rowid) FROM t3 1053f4d1d1bSdrh ORDER BY rowid; 1063f4d1d1bSdrh INSERT INTO t3 SELECT a_string(110+rowid), a_string(221+rowid) FROM t3 1073f4d1d1bSdrh ORDER BY rowid; 1083f4d1d1bSdrh INSERT INTO t3 SELECT a_string(110+rowid), a_string(221+rowid) FROM t3 1093f4d1d1bSdrh ORDER BY rowid; 1103f4d1d1bSdrh INSERT INTO t3 SELECT a_string(110+rowid), a_string(221+rowid) FROM t3 1113f4d1d1bSdrh ORDER BY rowid; 1124c9f129dSdrh SELECT name, path, pageno, pagetype, ncell, payload, unused, mx_payload 1131e32bed3Sdrh FROM stat WHERE name != 'sqlite_schema' ORDER BY name; 1146d3eb82bSdan} [list \ 1156d3eb82bSdan sqlite_autoindex_t3_1 / 3 internal 3 368 623 125 \ 1166d3eb82bSdan sqlite_autoindex_t3_1 /000/ 8 leaf 8 946 46 123 \ 1176d3eb82bSdan sqlite_autoindex_t3_1 /001/ 9 leaf 8 988 2 131 \ 1186d3eb82bSdan sqlite_autoindex_t3_1 /002/ 15 leaf 7 857 137 132 \ 1196d3eb82bSdan sqlite_autoindex_t3_1 /003/ 20 leaf 6 739 257 129 \ 1206d3eb82bSdan t3 / 2 internal 15 0 907 0 \ 1216d3eb82bSdan t3 /000/ 4 leaf 2 678 328 340 \ 1226d3eb82bSdan t3 /001/ 5 leaf 2 682 324 342 \ 1236d3eb82bSdan t3 /002/ 6 leaf 2 682 324 342 \ 1246d3eb82bSdan t3 /003/ 7 leaf 2 690 316 346 \ 1256d3eb82bSdan t3 /004/ 10 leaf 2 682 324 342 \ 1266d3eb82bSdan t3 /005/ 11 leaf 2 690 316 346 \ 1276d3eb82bSdan t3 /006/ 12 leaf 2 698 308 350 \ 1286d3eb82bSdan t3 /007/ 13 leaf 2 706 300 354 \ 1296d3eb82bSdan t3 /008/ 14 leaf 2 682 324 342 \ 1306d3eb82bSdan t3 /009/ 16 leaf 2 690 316 346 \ 1316d3eb82bSdan t3 /00a/ 17 leaf 2 698 308 350 \ 1326d3eb82bSdan t3 /00b/ 18 leaf 2 706 300 354 \ 1336d3eb82bSdan t3 /00c/ 19 leaf 2 714 292 358 \ 1346d3eb82bSdan t3 /00d/ 21 leaf 2 722 284 362 \ 1356d3eb82bSdan t3 /00e/ 22 leaf 2 730 276 366 \ 1366d3eb82bSdan t3 /00f/ 23 leaf 2 738 268 370 \ 1376d3eb82bSdan] 138a4641715Sdrh 139012b15e2Sdrhdo_execsql_test stat-2.1agg { 140012b15e2Sdrh SELECT * FROM dbstat WHERE aggregate=TRUE ORDER BY name; 141012b15e2Sdrh} [list \ 142012b15e2Sdrh sqlite_autoindex_t3_1 {} 5 {} 32 3898 1065 132 {} 5120 \ 1431e32bed3Sdrh sqlite_schema {} 1 {} 2 84 824 49 {} 1024 \ 144012b15e2Sdrh t3 {} 17 {} 47 11188 5815 370 {} 17408 \ 145012b15e2Sdrh] 146012b15e2Sdrh 147a4641715Sdrh# With every index entry overflowing, make sure no pages are missed 148a4641715Sdrh# (other than the locking page which is 64 in this test build.) 149a4641715Sdrh# 150a4641715Sdrhdo_execsql_test stat-2.2 { 151a4641715Sdrh UPDATE t3 SET a=a||hex(randomblob(700)); 152a4641715Sdrh VACUUM; 153a4641715Sdrh SELECT pageno FROM stat EXCEPT SELECT pageno-1 FROM stat; 154a4641715Sdrh} {64 136} 155a4641715Sdrh 156a4641715Sdrhdo_execsql_test stat-2.3 { DROP TABLE t3; VACUUM; } {} 1576d3eb82bSdan 1586d3eb82bSdando_execsql_test stat-3.1 { 1596d3eb82bSdan CREATE TABLE t4(x); 1606d3eb82bSdan CREATE INDEX i4 ON t4(x); 1612d07f260Sdan INSERT INTO t4(rowid, x) VALUES(2, a_string(7777)); 1624c9f129dSdrh SELECT name, path, pageno, pagetype, ncell, payload, unused, mx_payload 1631e32bed3Sdrh FROM stat WHERE name != 'sqlite_schema' ORDER BY name; 1646d3eb82bSdan} [list \ 1656d3eb82bSdan i4 / 3 leaf 1 103 905 7782 \ 166a4641715Sdrh i4 /000+000000 4 overflow 0 1020 0 0 \ 167a4641715Sdrh i4 /000+000001 5 overflow 0 1020 0 0 \ 168a4641715Sdrh i4 /000+000002 6 overflow 0 1020 0 0 \ 169a4641715Sdrh i4 /000+000003 7 overflow 0 1020 0 0 \ 170a4641715Sdrh i4 /000+000004 8 overflow 0 1020 0 0 \ 171a4641715Sdrh i4 /000+000005 9 overflow 0 1020 0 0 \ 172a4641715Sdrh i4 /000+000006 10 overflow 0 1020 0 0 \ 173a4641715Sdrh i4 /000+000007 11 overflow 0 539 481 0 \ 1746d3eb82bSdan t4 / 2 leaf 1 640 367 7780 \ 175a4641715Sdrh t4 /000+000000 12 overflow 0 1020 0 0 \ 176a4641715Sdrh t4 /000+000001 13 overflow 0 1020 0 0 \ 177a4641715Sdrh t4 /000+000002 14 overflow 0 1020 0 0 \ 178a4641715Sdrh t4 /000+000003 15 overflow 0 1020 0 0 \ 179a4641715Sdrh t4 /000+000004 16 overflow 0 1020 0 0 \ 180a4641715Sdrh t4 /000+000005 17 overflow 0 1020 0 0 \ 181a4641715Sdrh t4 /000+000006 18 overflow 0 1020 0 0 \ 1826d3eb82bSdan] 1836d3eb82bSdan 184012b15e2Sdrhdo_execsql_test stat-3.2 { 185012b15e2Sdrh SELECT *, '|' FROM dbstat WHERE aggregate=TRUE ORDER BY name; 186012b15e2Sdrh} [list \ 187012b15e2Sdrh i4 {} 9 {} 1 7782 1386 7782 {} 9216 | \ 1881e32bed3Sdrh sqlite_schema {} 1 {} 2 74 834 40 {} 1024 | \ 189012b15e2Sdrh t4 {} 8 {} 1 7780 367 7780 {} 8192 | \ 190012b15e2Sdrh] 191012b15e2Sdrh 192012b15e2Sdrh 1936d3eb82bSdando_execsql_test stat-4.1 { 1946d3eb82bSdan CREATE TABLE t5(x); 1956d3eb82bSdan CREATE INDEX i5 ON t5(x); 1964c9f129dSdrh SELECT name, path, pageno, pagetype, ncell, payload, unused, mx_payload 1974c9f129dSdrh FROM stat WHERE name = 't5' OR name = 'i5'; 1986d3eb82bSdan} [list \ 199a4641715Sdrh i5 / 20 leaf 0 0 1016 0 \ 200a4641715Sdrh t5 / 19 leaf 0 0 1016 0 \ 2016d3eb82bSdan] 2026d3eb82bSdan 2036d3eb82bSdandb close 204fda06befSmistachkinforcedelete test.db 2056d3eb82bSdansqlite3 db test.db 2066d3eb82bSdanregister_dbstat_vtab db 2076d3eb82bSdando_execsql_test stat-5.1 { 2081fab01acSdan PRAGMA auto_vacuum = OFF; 209857df26bSdrh CREATE TABLE tx(y); 210857df26bSdrh ATTACH ':memory:' AS aux1; 211857df26bSdrh CREATE VIRTUAL TABLE temp.stat USING dbstat(aux1); 212857df26bSdrh CREATE TABLE aux1.t1(x); 2136d3eb82bSdan INSERT INTO t1 VALUES(zeroblob(1513)); 2146d3eb82bSdan INSERT INTO t1 VALUES(zeroblob(1514)); 2154c9f129dSdrh SELECT name, path, pageno, pagetype, ncell, payload, unused, mx_payload 2164c9f129dSdrh FROM stat WHERE name = 't1'; 2176d3eb82bSdan} [list \ 2186d3eb82bSdan t1 / 2 leaf 2 993 5 1517 \ 2196d3eb82bSdan t1 /000+000000 3 overflow 0 1020 0 0 \ 2206d3eb82bSdan t1 /001+000000 4 overflow 0 1020 0 0 \ 2216d3eb82bSdan] 2226d3eb82bSdan 223012b15e2Sdrhdo_execsql_test stat-5.20 { 224012b15e2Sdrh SELECT name, quote(path), pageno, quote(pagetype), ncell, payload, 225012b15e2Sdrh unused, mx_payload, '|' FROM dbstat('main',1); 2261e32bed3Sdrh} {sqlite_schema NULL 1 NULL 1 34 878 34 | tx NULL 1 NULL 0 0 1016 0 |} 227012b15e2Sdrhdo_execsql_test stat-5.21 { 228012b15e2Sdrh SELECT name, quote(path), pageno, quote(pagetype), ncell, payload, 229012b15e2Sdrh unused, mx_payload, '|' FROM dbstat('aux1',1); 2301e32bed3Sdrh} {sqlite_schema NULL 1 NULL 1 34 878 34 | t1 NULL 3 NULL 2 3033 5 1517 |} 231012b15e2Sdrh 232012b15e2Sdrh 233857df26bSdrhdo_catchsql_test stat-6.1 { 234857df26bSdrh CREATE VIRTUAL TABLE temp.s2 USING dbstat(mainx); 235857df26bSdrh} {1 {no such database: mainx}} 236857df26bSdrh 237b5c557b8Sdan#------------------------------------------------------------------------- 238b5c557b8Sdan# Test that the argument passed to the dbstat constructor is dequoted 239b5c557b8Sdan# before it is matched against the names of attached databases. 240b5c557b8Sdan# 241b5c557b8Sdanforcedelete test.db2 242b5c557b8Sdando_execsql_test 7.1 { 243b5c557b8Sdan ATTACH 'test.db2' AS '123'; 244482721abSdan PRAGMA "123".auto_vacuum = OFF; 245b5c557b8Sdan CREATE TABLE "123".x1(a, b); 246b5c557b8Sdan INSERT INTO x1 VALUES(1, 2); 247b5c557b8Sdan} 248b5c557b8Sdan 249b5c557b8Sdando_execsql_test 7.1.1 { 250b5c557b8Sdan SELECT * FROM dbstat('123'); 251b5c557b8Sdan} { 2521e32bed3Sdrh sqlite_schema / 1 leaf 1 37 875 37 0 1024 253b5c557b8Sdan x1 / 2 leaf 1 4 1008 4 1024 1024 254b5c557b8Sdan} 255b5c557b8Sdando_execsql_test 7.1.2 { 256b5c557b8Sdan SELECT * FROM dbstat(123); 257b5c557b8Sdan} { 2581e32bed3Sdrh sqlite_schema / 1 leaf 1 37 875 37 0 1024 259b5c557b8Sdan x1 / 2 leaf 1 4 1008 4 1024 1024 260b5c557b8Sdan} 261b5c557b8Sdando_execsql_test 7.1.3 { 262b5c557b8Sdan CREATE VIRTUAL TABLE x2 USING dbstat('123'); 263b5c557b8Sdan SELECT * FROM x2; 264b5c557b8Sdan} { 2651e32bed3Sdrh sqlite_schema / 1 leaf 1 37 875 37 0 1024 266b5c557b8Sdan x1 / 2 leaf 1 4 1008 4 1024 1024 267b5c557b8Sdan} 268b5c557b8Sdando_execsql_test 7.1.4 { 269b5c557b8Sdan CREATE VIRTUAL TABLE x3 USING dbstat(123); 270b5c557b8Sdan SELECT * FROM x3; 271b5c557b8Sdan} { 2721e32bed3Sdrh sqlite_schema / 1 leaf 1 37 875 37 0 1024 273b5c557b8Sdan x1 / 2 leaf 1 4 1008 4 1024 1024 274b5c557b8Sdan} 275b5c557b8Sdan 276b5c557b8Sdando_execsql_test 7.2 { 277b5c557b8Sdan DETACH 123; 278b5c557b8Sdan DROP TABLE x2; 279b5c557b8Sdan DROP TABLE x3; 280b5c557b8Sdan ATTACH 'test.db2' AS '123corp'; 281b5c557b8Sdan} 282b5c557b8Sdando_execsql_test 7.2.1 { 283b5c557b8Sdan SELECT * FROM dbstat('123corp'); 284b5c557b8Sdan} { 2851e32bed3Sdrh sqlite_schema / 1 leaf 1 37 875 37 0 1024 286b5c557b8Sdan x1 / 2 leaf 1 4 1008 4 1024 1024 287b5c557b8Sdan} 288b5c557b8Sdando_catchsql_test 7.2.2 { 289b5c557b8Sdan SELECT * FROM dbstat(123corp); 290b5c557b8Sdan} {1 {unrecognized token: "123corp"}} 291b5c557b8Sdando_execsql_test 7.2.3 { 292b5c557b8Sdan CREATE VIRTUAL TABLE x2 USING dbstat('123corp'); 293b5c557b8Sdan SELECT * FROM x2; 294b5c557b8Sdan} { 2951e32bed3Sdrh sqlite_schema / 1 leaf 1 37 875 37 0 1024 296b5c557b8Sdan x1 / 2 leaf 1 4 1008 4 1024 1024 297b5c557b8Sdan} 298b5c557b8Sdando_catchsql_test 7.2.4 { 299b5c557b8Sdan CREATE VIRTUAL TABLE x3 USING dbstat(123corp); 300b5c557b8Sdan SELECT * FROM x3; 301b5c557b8Sdan} {1 {unrecognized token: "123corp"}} 302b5c557b8Sdan 303664d80bbSdan 3046fe63b4eSdando_execsql_test 8.1 { 3056fe63b4eSdan CREATE VIRTUAL TABLE st4 USING dbstat; 3066fe63b4eSdan} 3076fe63b4eSdando_execsql_test 8.2 { 3082e5beddbSdrh SELECT * FROM st4 WHERE st4.aggregate = NULL; 3096fe63b4eSdan} 3106fe63b4eSdando_execsql_test 8.3 { 3116fe63b4eSdan SELECT aggregate=1 FROM st4 WHERE aggregate = 5 3126fe63b4eSdan} 313664d80bbSdando_execsql_test 8.4 { 314664d80bbSdan SELECT * FROM st4 WHERE name = NULL; 3152e5beddbSdrh} {} 3162e5beddbSdrhdo_execsql_test 8.5 { 317664d80bbSdan SELECT * FROM st4 WHERE schema = NULL; 3182e5beddbSdrh} {} 3196fe63b4eSdan 32035c7312fSdan#------------------------------------------------------------------------- 32135c7312fSdanreset_db 32235c7312fSdanbreakpoint 32335c7312fSdando_catchsql_test 9.1 { 32435c7312fSdan CREATE TABLE dbstat(x, y); 32535c7312fSdan DROP TABLE nosuchdb.dbstat; 326*b670fd55Sdrh} {/1 {(no such table: nosuchdb.dbstat|table dbstat may not be dropped)}/} 32735c7312fSdan 3286d3eb82bSdanfinish_test 329