1a713f2c3Sdanielk1977# 2006 September 4 2a713f2c3Sdanielk1977# 3a713f2c3Sdanielk1977# The author disclaims copyright to this source code. In place of 4a713f2c3Sdanielk1977# a legal notice, here is a blessing: 5a713f2c3Sdanielk1977# 6a713f2c3Sdanielk1977# May you do good and not evil. 7a713f2c3Sdanielk1977# May you find forgiveness for yourself and forgive others. 8a713f2c3Sdanielk1977# May you share freely, never taking more than you give. 9a713f2c3Sdanielk1977# 10a713f2c3Sdanielk1977#*********************************************************************** 11a713f2c3Sdanielk1977# This file implements regression tests for SQLite library. 12a713f2c3Sdanielk1977# 13e64ca7baSdrh# $Id: misc7.test,v 1.29 2009/07/16 18:21:18 drh Exp $ 14a713f2c3Sdanielk1977 15a713f2c3Sdanielk1977set testdir [file dirname $argv0] 16a713f2c3Sdanielk1977source $testdir/tester.tcl 17a688ca5eSdanset testprefix misc7 18a713f2c3Sdanielk1977 19afcf9bd8Sdanif {[clang_sanitize_address]==0} { 2001495b99Sdrh do_test misc7-1-misuse { 2101495b99Sdrh c_misuse_test 2201495b99Sdrh } {} 23afcf9bd8Sdan} 24a713f2c3Sdanielk1977 25a713f2c3Sdanielk1977do_test misc7-2 { 26a713f2c3Sdanielk1977 c_realloc_test 27a713f2c3Sdanielk1977} {} 28a713f2c3Sdanielk1977 29a713f2c3Sdanielk1977do_test misc7-3 { 30a713f2c3Sdanielk1977 c_collation_test 31a713f2c3Sdanielk1977} {} 32a713f2c3Sdanielk1977 3369b637b5Sdanielk1977# Try to open a directory: 3469b637b5Sdanielk1977# 3569b637b5Sdanielk1977do_test misc7-4 { 36fda06befSmistachkin delete_file mydir 3769b637b5Sdanielk1977 file mkdir mydir 3869b637b5Sdanielk1977 set rc [catch { 3969b637b5Sdanielk1977 sqlite3 db2 ./mydir 4069b637b5Sdanielk1977 } msg] 4169b637b5Sdanielk1977 list $rc $msg 4269b637b5Sdanielk1977} {1 {unable to open database file}} 4369b637b5Sdanielk1977 4485b623f2Sdrh# Try to open a file with a directory where its journal file should be. 4569b637b5Sdanielk1977# 46b8fff29cSdanif {[atomic_batch_write test.db]==0} { 4769b637b5Sdanielk1977 do_test misc7-5 { 48fda06befSmistachkin delete_file mydir 4969b637b5Sdanielk1977 file mkdir mydir-journal 5069b637b5Sdanielk1977 sqlite3 db2 ./mydir 5169b637b5Sdanielk1977 catchsql { 5269b637b5Sdanielk1977 CREATE TABLE abc(a, b, c); 5369b637b5Sdanielk1977 } db2 5469b637b5Sdanielk1977 } {1 {unable to open database file}} 5569b637b5Sdanielk1977 db2 close 56b8fff29cSdan} 5769b637b5Sdanielk1977 5869b637b5Sdanielk1977#-------------------------------------------------------------------- 5969b637b5Sdanielk1977# The following tests, misc7-6.* test the libraries behaviour when 6069b637b5Sdanielk1977# it cannot open a file. To force this condition, we use up all the 6169b637b5Sdanielk1977# file-descriptors before running sqlite. This probably only works 6269b637b5Sdanielk1977# on unix. 6369b637b5Sdanielk1977# 6469b637b5Sdanielk1977 6569b637b5Sdanielk1977proc use_up_files {} { 6669b637b5Sdanielk1977 set ret [list] 6769b637b5Sdanielk1977 catch { 6869b637b5Sdanielk1977 while 1 { lappend ret [open test.db] } 6969b637b5Sdanielk1977 } 7069b637b5Sdanielk1977 return $ret 7169b637b5Sdanielk1977} 7269b637b5Sdanielk1977 7395b289b6Sdanielk1977proc do_fileopen_test {prefix sql} { 7469b637b5Sdanielk1977 set fd_list [use_up_files] 7569b637b5Sdanielk1977 set ::go 1 7669b637b5Sdanielk1977 set ::n 1 7795b289b6Sdanielk1977 set ::sql $sql 7869b637b5Sdanielk1977 while {$::go} { 7969b637b5Sdanielk1977 catch {db close} 8095b289b6Sdanielk1977 do_test ${prefix}.${::n} { 8169b637b5Sdanielk1977 set rc [catch { 8269b637b5Sdanielk1977 sqlite db test.db 8395b289b6Sdanielk1977 db eval $::sql 8469b637b5Sdanielk1977 } msg] 8569b637b5Sdanielk1977 if {$rc == 0} {set ::go 0} 8669b637b5Sdanielk1977 8795b289b6Sdanielk1977 expr {$rc == 0 || ($rc == 1 && [string first unable $msg]==0)} 8869b637b5Sdanielk1977 } 1 8969b637b5Sdanielk1977 9069b637b5Sdanielk1977 close [lindex $fd_list 0] 9169b637b5Sdanielk1977 set fd_list [lrange $fd_list 1 end] 9269b637b5Sdanielk1977 incr ::n 9369b637b5Sdanielk1977 } 9469b637b5Sdanielk1977 foreach fd $fd_list { 9569b637b5Sdanielk1977 close $fd 9669b637b5Sdanielk1977 } 97b5584c0cSdanielk1977 db close 9895b289b6Sdanielk1977} 9995b289b6Sdanielk1977 10095b289b6Sdanielk1977execsql { CREATE TABLE abc(a PRIMARY KEY, b, c); } 10195b289b6Sdanielk1977db close 10295b289b6Sdanielk1977 1030b3d55d4Sdrhif {$tcl_platform(platform)!="windows"} { 10495b289b6Sdanielk1977 do_fileopen_test misc7-6.1 { 10595b289b6Sdanielk1977 BEGIN; 10695b289b6Sdanielk1977 INSERT INTO abc VALUES(1, 2, 3); 10795b289b6Sdanielk1977 INSERT INTO abc VALUES(2, 3, 4); 10895b289b6Sdanielk1977 INSERT INTO abc SELECT a+2, b, c FROM abc; 10995b289b6Sdanielk1977 COMMIT; 11095b289b6Sdanielk1977 } 11195b289b6Sdanielk1977 11295b289b6Sdanielk1977 do_fileopen_test misc7-6.2 { 11395b289b6Sdanielk1977 PRAGMA temp.cache_size = 1000; 11495b289b6Sdanielk1977 } 1150b3d55d4Sdrh} 11695b289b6Sdanielk1977 117b5584c0cSdanielk1977# 118b5584c0cSdanielk1977# End of tests for out-of-file-descriptors condition. 119b5584c0cSdanielk1977#-------------------------------------------------------------------- 120b5584c0cSdanielk1977 121073d3efaSdrhsqlite3 db test.db 1220b3d55d4Sdrhexecsql { 1230b3d55d4Sdrh DELETE FROM abc; 1240b3d55d4Sdrh INSERT INTO abc VALUES(1, 2, 3); 1250b3d55d4Sdrh INSERT INTO abc VALUES(2, 3, 4); 1260b3d55d4Sdrh INSERT INTO abc SELECT a+2, b, c FROM abc; 1270b3d55d4Sdrh} 1280b3d55d4Sdrh 1290b3d55d4Sdrh 130b5584c0cSdanielk1977#-------------------------------------------------------------------- 131b5584c0cSdanielk1977# Test that the sqlite3_busy_timeout call seems to delay approximately 132b5584c0cSdanielk1977# the right amount of time. 133b5584c0cSdanielk1977# 13495b289b6Sdanielk1977do_test misc7-7.0 { 135b5584c0cSdanielk1977 sqlite3 db2 test.db 136b5584c0cSdanielk1977 sqlite3_busy_timeout [sqlite3_connection_pointer db] 2000 137b5584c0cSdanielk1977 execsql { 138b5584c0cSdanielk1977 BEGIN EXCLUSIVE; 139b5584c0cSdanielk1977 } db2 140b5584c0cSdanielk1977 141b5584c0cSdanielk1977 # Now db2 has an exclusive lock on the database file, and db has 142b5584c0cSdanielk1977 # a busy-timeout of 2000 milliseconds. So check that trying to 143b5584c0cSdanielk1977 # access the database using connection db delays for at least 1500 ms. 144b5584c0cSdanielk1977 # 145073d3efaSdrh set tm [time { 146073d3efaSdrh set result [catchsql { 147b5584c0cSdanielk1977 SELECT * FROM sqlite_master; 148073d3efaSdrh } db] 149073d3efaSdrh }] 150073d3efaSdrh set delay [lindex $tm 0] ;# In microseconds 1510b3d55d4Sdrh lappend result [expr {$delay>1500000 && $delay<4000000}] 152073d3efaSdrh} {1 {database is locked} 1} 153b5584c0cSdanielk1977db2 close 154b5584c0cSdanielk1977 155b5584c0cSdanielk1977#-------------------------------------------------------------------- 156b5584c0cSdanielk1977# Test that nothing goes horribly wrong when attaching a database 157b5584c0cSdanielk1977# after the omit_readlock pragma has been exercised. 158b5584c0cSdanielk1977# 15933f111dcSdrh# Note: The PRAGMA omit_readlock was an early hack to disable the 16033f111dcSdrh# fcntl() calls for read-only databases so that read-only databases could 16133f111dcSdrh# be read on broken NFS systems. That pragma has now been removed. 16233f111dcSdrh# (Use the unix-none VFS as a replacement, if needed.) But these tests 16333f111dcSdrh# do not really depend on omit_readlock, so we left them in place. 16433f111dcSdrh# 165935ed5eaSdanielk1977do_test misc7-7.1 { 166fda06befSmistachkin forcedelete test2.db 167fda06befSmistachkin forcedelete test2.db-journal 168b5584c0cSdanielk1977 execsql { 169b5584c0cSdanielk1977 PRAGMA omit_readlock = 1; 170b5584c0cSdanielk1977 ATTACH 'test2.db' AS aux; 171b5584c0cSdanielk1977 CREATE TABLE aux.hello(world); 172b5584c0cSdanielk1977 SELECT name FROM aux.sqlite_master; 173b5584c0cSdanielk1977 } 174b5584c0cSdanielk1977} {hello} 175935ed5eaSdanielk1977do_test misc7-7.2 { 176935ed5eaSdanielk1977 execsql { 177935ed5eaSdanielk1977 DETACH aux; 178935ed5eaSdanielk1977 } 179935ed5eaSdanielk1977} {} 1800371f1b2Sdanielk1977do_test misc7-7.3 { 1810371f1b2Sdanielk1977 db close 1820371f1b2Sdanielk1977 sqlite3 db test.db -readonly 1 1830371f1b2Sdanielk1977 execsql { 1840371f1b2Sdanielk1977 PRAGMA omit_readlock = 1; 1850371f1b2Sdanielk1977 ATTACH 'test2.db' AS aux; 1860371f1b2Sdanielk1977 SELECT name FROM aux.sqlite_master; 1870371f1b2Sdanielk1977 SELECT name FROM aux.sqlite_master; 1880371f1b2Sdanielk1977 } 1890371f1b2Sdanielk1977} {hello hello} 1900371f1b2Sdanielk1977do_test misc7-7.3 { 1910371f1b2Sdanielk1977 db close 1920371f1b2Sdanielk1977 sqlite3 db test.db 1930371f1b2Sdanielk1977 set ::DB [sqlite3_connection_pointer db] 1940371f1b2Sdanielk1977 list 1950371f1b2Sdanielk1977} {} 196b5584c0cSdanielk1977 19724168728Sdanielk1977# Test the UTF-16 version of the "out of memory" message (used when 19824168728Sdanielk1977# malloc fails during sqlite3_open() ). 199b5584c0cSdanielk1977# 200b5584c0cSdanielk1977ifcapable utf16 { 201b5584c0cSdanielk1977 do_test misc7-8 { 202b5584c0cSdanielk1977 encoding convertfrom unicode [sqlite3_errmsg16 0x00000000] 203b5584c0cSdanielk1977 } {out of memory} 204b5584c0cSdanielk1977} 205b5584c0cSdanielk1977 206935ed5eaSdanielk1977do_test misc7-9 { 207935ed5eaSdanielk1977 execsql { 208935ed5eaSdanielk1977 SELECT * 209935ed5eaSdanielk1977 FROM (SELECT name+1 AS one FROM sqlite_master LIMIT 1 OFFSET 1) 210935ed5eaSdanielk1977 WHERE one LIKE 'hello%'; 211935ed5eaSdanielk1977 } 212935ed5eaSdanielk1977} {} 213b5584c0cSdanielk1977 214935ed5eaSdanielk1977#-------------------------------------------------------------------- 215780b1d94Sdanielk1977# Improve coverage for vtab code. 216935ed5eaSdanielk1977# 217935ed5eaSdanielk1977ifcapable vtab { 218780b1d94Sdanielk1977 # Run some debug code to improve reported coverage 219780b1d94Sdanielk1977 # 220780b1d94Sdanielk1977 221780b1d94Sdanielk1977 # set sqlite_where_trace 1 222935ed5eaSdanielk1977 do_test misc7-10 { 223935ed5eaSdanielk1977 register_echo_module [sqlite3_connection_pointer db] 224935ed5eaSdanielk1977 execsql { 225935ed5eaSdanielk1977 CREATE VIRTUAL TABLE t1 USING echo(abc); 226935ed5eaSdanielk1977 SELECT a FROM t1 WHERE a = 1 ORDER BY b; 227935ed5eaSdanielk1977 } 228935ed5eaSdanielk1977 } {1} 229780b1d94Sdanielk1977 set sqlite_where_trace 0 230b042d921Sdrh do_catchsql_test misc7-10.1 { 231b042d921Sdrh INSERT INTO t1(a,b,c) VALUES(12345,2,3) ON CONFLICT(a) DO NOTHING; 232b042d921Sdrh } {1 {UPSERT not implemented for virtual table "t1"}} 233780b1d94Sdanielk1977 234780b1d94Sdanielk1977 # Specify an ORDER BY clause that cannot be indexed. 235780b1d94Sdanielk1977 do_test misc7-11 { 236780b1d94Sdanielk1977 execsql { 237780b1d94Sdanielk1977 SELECT t1.a, t2.a FROM t1, t1 AS t2 ORDER BY 2 LIMIT 1; 238935ed5eaSdanielk1977 } 239780b1d94Sdanielk1977 } {1 1} 240780b1d94Sdanielk1977 241780b1d94Sdanielk1977 # The whole point of this is to test an error code other than 242780b1d94Sdanielk1977 # SQLITE_NOMEM from the vtab xBestIndex callback. 243780b1d94Sdanielk1977 # 244780b1d94Sdanielk1977 do_ioerr_test misc7-12 -tclprep { 245780b1d94Sdanielk1977 sqlite3 db2 test.db 246780b1d94Sdanielk1977 register_echo_module [sqlite3_connection_pointer db2] 247780b1d94Sdanielk1977 db2 eval { 248780b1d94Sdanielk1977 CREATE TABLE abc(a PRIMARY KEY, b, c); 249780b1d94Sdanielk1977 INSERT INTO abc VALUES(1, 2, 3); 250780b1d94Sdanielk1977 CREATE VIRTUAL TABLE t1 USING echo(abc); 251780b1d94Sdanielk1977 } 252780b1d94Sdanielk1977 db2 close 253780b1d94Sdanielk1977 } -tclbody { 254780b1d94Sdanielk1977 register_echo_module [sqlite3_connection_pointer db] 255780b1d94Sdanielk1977 execsql {SELECT * FROM t1 WHERE a = 1;} 256780b1d94Sdanielk1977 } 257780b1d94Sdanielk1977 258780b1d94Sdanielk1977 # The case where the virtual table module returns a very large number 259780b1d94Sdanielk1977 # as the cost of a scan (greater than SQLITE_BIG_DOUBLE in the code). 260780b1d94Sdanielk1977 # 261780b1d94Sdanielk1977 do_test misc7-13 { 262780b1d94Sdanielk1977 sqlite3 db test.db 263780b1d94Sdanielk1977 register_echo_module [sqlite3_connection_pointer db] 264780b1d94Sdanielk1977 set ::echo_module_cost 2.0e+99 265780b1d94Sdanielk1977 execsql {SELECT * FROM t1 WHERE a = 1;} 266780b1d94Sdanielk1977 } {1 2 3} 267780b1d94Sdanielk1977 unset ::echo_module_cost 268780b1d94Sdanielk1977} 269780b1d94Sdanielk1977 27095b289b6Sdanielk1977db close 271fda06befSmistachkinforcedelete test.db 272fda06befSmistachkinforcedelete test.db-journal 27395b289b6Sdanielk1977sqlite3 db test.db 27495b289b6Sdanielk1977 27595b289b6Sdanielk1977ifcapable explain { 276d3e17ffbSdan do_execsql_test misc7-14.0 { 27795b289b6Sdanielk1977 CREATE TABLE abc(a PRIMARY KEY, b, c); 278d3e17ffbSdan } 279d3e17ffbSdan do_eqp_test misc7-14.1 { 280d3e17ffbSdan SELECT * FROM abc AS t2 WHERE rowid = 1; 281659816e9Sdan } { 282d3e17ffbSdan QUERY PLAN 283*0227d930Sdrh `--SEARCH t2 USING INTEGER PRIMARY KEY (rowid=?) 28495b289b6Sdanielk1977} 285d3e17ffbSdan do_eqp_test misc7-14.2 { 286d3e17ffbSdan SELECT * FROM abc AS t2 WHERE a = 1; 287d3e17ffbSdan} { 288d3e17ffbSdan QUERY PLAN 289*0227d930Sdrh `--SEARCH t2 USING INDEX sqlite_autoindex_abc_1 (a=?) 29095b289b6Sdanielk1977} 291d3e17ffbSdan do_eqp_test misc7-14.3 { 292d3e17ffbSdan SELECT * FROM abc AS t2 ORDER BY a; 293d3e17ffbSdan } { 294d3e17ffbSdan QUERY PLAN 295*0227d930Sdrh `--SCAN t2 USING INDEX sqlite_autoindex_abc_1 296701bb3b4Sdrh} 29795b289b6Sdanielk1977} 29869b637b5Sdanielk1977 2993546947dSdanielk1977db close 300fda06befSmistachkinforcedelete test.db 301fda06befSmistachkinforcedelete test.db-journal 3023546947dSdanielk1977sqlite3 db test.db 3033546947dSdanielk1977 3043546947dSdanielk1977#-------------------------------------------------------------------- 3053546947dSdanielk1977# This is all to force the pager_remove_from_stmt_list() function 3063546947dSdanielk1977# (inside pager.c) to remove a pager from the middle of the 3073546947dSdanielk1977# statement-list. 3083546947dSdanielk1977# 3093546947dSdanielk1977do_test misc7-15.1 { 3103546947dSdanielk1977 execsql { 3113546947dSdanielk1977 PRAGMA cache_size = 10; 3123546947dSdanielk1977 BEGIN; 3133546947dSdanielk1977 CREATE TABLE abc(a PRIMARY KEY, b, c); 3143546947dSdanielk1977 INSERT INTO abc 3153546947dSdanielk1977 VALUES(randstr(100,100), randstr(100,100), randstr(100,100)); 3163546947dSdanielk1977 INSERT INTO abc SELECT 3173546947dSdanielk1977 randstr(100,100), randstr(100,100), randstr(100,100) FROM abc; 3183546947dSdanielk1977 INSERT INTO abc SELECT 3193546947dSdanielk1977 randstr(100,100), randstr(100,100), randstr(100,100) FROM abc; 3203546947dSdanielk1977 INSERT INTO abc SELECT 3213546947dSdanielk1977 randstr(100,100), randstr(100,100), randstr(100,100) FROM abc; 3223546947dSdanielk1977 INSERT INTO abc SELECT 3233546947dSdanielk1977 randstr(100,100), randstr(100,100), randstr(100,100) FROM abc; 3243546947dSdanielk1977 INSERT INTO abc SELECT 3253546947dSdanielk1977 randstr(100,100), randstr(100,100), randstr(100,100) FROM abc; 3263546947dSdanielk1977 INSERT INTO abc SELECT 3273546947dSdanielk1977 randstr(100,100), randstr(100,100), randstr(100,100) FROM abc; 3283546947dSdanielk1977 INSERT INTO abc SELECT 3293546947dSdanielk1977 randstr(100,100), randstr(100,100), randstr(100,100) FROM abc; 3303546947dSdanielk1977 INSERT INTO abc SELECT 3313546947dSdanielk1977 randstr(100,100), randstr(100,100), randstr(100,100) FROM abc; 3323546947dSdanielk1977 COMMIT; 3333546947dSdanielk1977 } 3343546947dSdanielk1977 expr {[file size test.db]>10240} 3353546947dSdanielk1977} {1} 3363546947dSdanielk1977do_test misc7-15.2 { 3373546947dSdanielk1977 execsql { 3383546947dSdanielk1977 DELETE FROM abc WHERE rowid > 12; 3393546947dSdanielk1977 INSERT INTO abc SELECT 3403546947dSdanielk1977 randstr(100,100), randstr(100,100), randstr(100,100) FROM abc; 3413546947dSdanielk1977 } 3423546947dSdanielk1977} {} 3433546947dSdanielk1977 344393f0689Sdanielk1977db close 345fda06befSmistachkinforcedelete test.db 346fda06befSmistachkinforcedelete test.db-journal 347393f0689Sdanielk1977sqlite3 db test.db 348393f0689Sdanielk1977 349393f0689Sdanielk1977do_ioerr_test misc7-16 -sqlprep { 350393f0689Sdanielk1977 PRAGMA cache_size = 10; 351393f0689Sdanielk1977 PRAGMA default_cache_size = 10; 352393f0689Sdanielk1977 CREATE TABLE t3(a, b, UNIQUE(a, b)); 353393f0689Sdanielk1977 INSERT INTO t3 VALUES( randstr(100, 100), randstr(100, 100) ); 354393f0689Sdanielk1977 INSERT INTO t3 SELECT randstr(100, 100), randstr(100, 100) FROM t3; 355393f0689Sdanielk1977 INSERT INTO t3 SELECT randstr(100, 100), randstr(100, 100) FROM t3; 356393f0689Sdanielk1977 INSERT INTO t3 SELECT randstr(100, 100), randstr(100, 100) FROM t3; 357393f0689Sdanielk1977 INSERT INTO t3 SELECT randstr(100, 100), randstr(100, 100) FROM t3; 358393f0689Sdanielk1977 INSERT INTO t3 SELECT randstr(100, 100), randstr(100, 100) FROM t3; 359393f0689Sdanielk1977 UPDATE t3 360393f0689Sdanielk1977 SET b = 'hello world' 361393f0689Sdanielk1977 WHERE rowid >= (SELECT max(rowid)-1 FROM t3); 362393f0689Sdanielk1977} -tclbody { 363393f0689Sdanielk1977 set rc [catch {db eval { 364393f0689Sdanielk1977 BEGIN; 365393f0689Sdanielk1977 PRAGMA cache_size = 10; 366393f0689Sdanielk1977 INSERT INTO t3 VALUES( randstr(100, 100), randstr(100, 100) ); 367393f0689Sdanielk1977 UPDATE t3 SET a = b; 368393f0689Sdanielk1977 COMMIT; 369393f0689Sdanielk1977 }} msg] 370393f0689Sdanielk1977 37114386751Sdrh if {!$rc || ($rc && [string first "UNIQUE" $msg]==0)} { 372393f0689Sdanielk1977 set msg 373393f0689Sdanielk1977 } else { 374393f0689Sdanielk1977 error $msg 375393f0689Sdanielk1977 } 376393f0689Sdanielk1977} 377393f0689Sdanielk1977 37824168728Sdanielk1977sqlite3 db test.db 37908d31a2aSdanielk1977 38008d31a2aSdanielk1977do_test misc7-16.X { 38108d31a2aSdanielk1977 execsql { 38208d31a2aSdanielk1977 SELECT count(*) FROM t3; 38308d31a2aSdanielk1977 } 38408d31a2aSdanielk1977} {32} 38508d31a2aSdanielk1977 38608d31a2aSdanielk1977#---------------------------------------------------------------------- 38708d31a2aSdanielk1977# Test the situation where a hot-journal is discovered but write-access 38808d31a2aSdanielk1977# to it is denied. This should return SQLITE_BUSY. 38908d31a2aSdanielk1977# 3900b3d55d4Sdrh# These tests do not work on windows due to restrictions in the 3910b3d55d4Sdrh# windows file system. 3920b3d55d4Sdrh# 393f1c6bc5cSmistachkinif {$tcl_platform(platform)!="windows"} { 39417fe6c1dSdrh 39517fe6c1dSdrh # Some network filesystems (ex: AFP) do not support setting read-only 39617fe6c1dSdrh # permissions. Only run these tests if full unix permission setting 39717fe6c1dSdrh # capabilities are supported. 39817fe6c1dSdrh # 39917fe6c1dSdrh file attributes test.db -permissions rw-r--r-- 40017fe6c1dSdrh if {[file attributes test.db -permissions]==0644} { 40117fe6c1dSdrh 40208d31a2aSdanielk1977 do_test misc7-17.1 { 40308d31a2aSdanielk1977 execsql { 40408d31a2aSdanielk1977 BEGIN; 40508d31a2aSdanielk1977 DELETE FROM t3 WHERE (oid%3)==0; 40608d31a2aSdanielk1977 } 407fda06befSmistachkin forcecopy test.db bak.db 408fda06befSmistachkin forcecopy test.db-journal bak.db-journal 40908d31a2aSdanielk1977 execsql { 41008d31a2aSdanielk1977 COMMIT; 41108d31a2aSdanielk1977 } 41208d31a2aSdanielk1977 413ead8e3f4Sdanielk1977 db close 414fda06befSmistachkin forcecopy bak.db test.db 415fda06befSmistachkin forcecopy bak.db-journal test.db-journal 416ead8e3f4Sdanielk1977 sqlite3 db test.db 41708d31a2aSdanielk1977 4180b3d55d4Sdrh catch {file attributes test.db-journal -permissions r--------} 4190b3d55d4Sdrh catch {file attributes test.db-journal -readonly 1} 42008d31a2aSdanielk1977 catchsql { 42108d31a2aSdanielk1977 SELECT count(*) FROM t3; 42208d31a2aSdanielk1977 } 42399dfe5ebSdrh } {1 {unable to open database file}} 42408d31a2aSdanielk1977 do_test misc7-17.2 { 425382e28faSdanielk1977 # Note that the -readonly flag must be cleared before the -permissions 426382e28faSdanielk1977 # are set. Otherwise, when using tcl 8.5 on mac, the fact that the 427382e28faSdanielk1977 # -readonly flag is set causes the attempt to set the permissions 428382e28faSdanielk1977 # to fail. 4290b3d55d4Sdrh catch {file attributes test.db-journal -readonly 0} 430382e28faSdanielk1977 catch {file attributes test.db-journal -permissions rw-------} 43108d31a2aSdanielk1977 catchsql { 43208d31a2aSdanielk1977 SELECT count(*) FROM t3; 43308d31a2aSdanielk1977 } 434ead8e3f4Sdanielk1977 } {0 32} 435ead8e3f4Sdanielk1977 4368e3e881aSdanielk1977 # sqlite3_test_control_pending_page [expr ($::sqlite_pending_byte / 1024) + 1] 4378e3e881aSdanielk1977 set ::pending_byte_page [expr ($::sqlite_pending_byte / 1024) + 1] 4388e3e881aSdanielk1977 sqlite3_test_control_pending_byte $::sqlite_pending_byte 439ead8e3f4Sdanielk1977 do_test misc7-17.3 { 440b7c2cf0aSdrh sqlite3_db_config db DEFENSIVE 0 441ead8e3f4Sdanielk1977 db eval { 442ead8e3f4Sdanielk1977 pragma writable_schema = true; 443ead8e3f4Sdanielk1977 UPDATE sqlite_master 444ead8e3f4Sdanielk1977 SET rootpage = $pending_byte_page 445ead8e3f4Sdanielk1977 WHERE type = 'table' AND name = 't3'; 446ead8e3f4Sdanielk1977 } 447ead8e3f4Sdanielk1977 execsql { 448ead8e3f4Sdanielk1977 SELECT rootpage FROM sqlite_master WHERE type = 'table' AND name = 't3'; 449ead8e3f4Sdanielk1977 } 450ead8e3f4Sdanielk1977 } $::pending_byte_page 451ead8e3f4Sdanielk1977 452ead8e3f4Sdanielk1977 do_test misc7-17.4 { 453ead8e3f4Sdanielk1977 db close 454ead8e3f4Sdanielk1977 sqlite3 db test.db 455ead8e3f4Sdanielk1977 catchsql { 456ead8e3f4Sdanielk1977 SELECT count(*) FROM t3; 457ead8e3f4Sdanielk1977 } 45880aff084Sdan } {1 {malformed database schema (t3) - invalid rootpage}} 4590b3d55d4Sdrh } 46017fe6c1dSdrh} 461ead8e3f4Sdanielk1977 4626bd00bfdSdrh# Ticket #2470 4636bd00bfdSdrh# 46480aff084Sdanreset_db 4656bd00bfdSdrhdo_test misc7-18.1 { 4666bd00bfdSdrh execsql { 4676bd00bfdSdrh CREATE TABLE table_1 (col_10); 4686bd00bfdSdrh CREATE TABLE table_2 ( 4696bd00bfdSdrh col_1, col_2, col_3, col_4, col_5, 4706bd00bfdSdrh col_6, col_7, col_8, col_9, col_10 4716bd00bfdSdrh ); 4728278ce79Sdrh SELECT a.col_10 4736bd00bfdSdrh FROM 4748278ce79Sdrh (SELECT table_1.col_10 AS col_10 FROM table_1) a, 4756bd00bfdSdrh (SELECT table_1.col_10, table_2.col_9 AS qcol_9 4766bd00bfdSdrh FROM table_1, table_2 4776bd00bfdSdrh GROUP BY table_1.col_10, qcol_9); 4786bd00bfdSdrh } 4796bd00bfdSdrh} {} 4806bd00bfdSdrh 481af005fbcSdrh# Testing boundary conditions on sqlite3_status() 482af005fbcSdrh# 483af005fbcSdrhdo_test misc7-19.1 { 484af005fbcSdrh sqlite3_status -1 0 485af005fbcSdrh} {21 0 0} 486af005fbcSdrhdo_test misc7-19.2 { 487af005fbcSdrh sqlite3_status 1000 0 488af005fbcSdrh} {21 0 0} 489af005fbcSdrh 490af005fbcSdrh 491e2a7c6e0Sdrh# sqlite3_global_recover() is a no-op. But we might as well test it 492e2a7c6e0Sdrh# if only to get the test coverage. 493e2a7c6e0Sdrh# 494e2a7c6e0Sdrhdo_test misc7-20.1 { 495e2a7c6e0Sdrh sqlite3_global_recover 496e2a7c6e0Sdrh} {SQLITE_OK} 497e2a7c6e0Sdrh 4980371f1b2Sdanielk1977# Try to open a really long file name. 4990371f1b2Sdanielk1977# 5000371f1b2Sdanielk1977do_test misc7-21.1 { 501f8a78464Smistachkin set zFile [file join [get_pwd] "[string repeat abcde 104].db"] 5020371f1b2Sdanielk1977 set rc [catch {sqlite3 db2 $zFile} msg] 5030371f1b2Sdanielk1977 list $rc $msg 5040371f1b2Sdanielk1977} {1 {unable to open database file}} 5050371f1b2Sdanielk1977 506e3664fb0Sdan# Try to do hot-journal rollback with a read-only connection. The 507e3664fb0Sdan# error code should be SQLITE_READONLY_ROLLBACK. 508e3664fb0Sdan# 509e3664fb0Sdando_test misc7-22.1 { 510e3664fb0Sdan db close 511e3664fb0Sdan forcedelete test.db copy.db-journal 512e3664fb0Sdan sqlite3 db test.db 513e3664fb0Sdan execsql { 514e3664fb0Sdan CREATE TABLE t1(a, b); 515e3664fb0Sdan INSERT INTO t1 VALUES(1, 2); 516e3664fb0Sdan INSERT INTO t1 VALUES(3, 4); 517e3664fb0Sdan } 518e3664fb0Sdan db close 519e3664fb0Sdan sqlite3 db test.db -readonly 1 520e3664fb0Sdan catchsql { 521e3664fb0Sdan INSERT INTO t1 VALUES(5, 6); 522e3664fb0Sdan } 523e3664fb0Sdan} {1 {attempt to write a readonly database}} 524e3664fb0Sdando_test misc7-22.2 { execsql { SELECT * FROM t1 } } {1 2 3 4} 525e3664fb0Sdando_test misc7-22.3 { 526e3664fb0Sdan set fd [open test.db-journal w] 527e3664fb0Sdan puts $fd [string repeat abc 1000] 528e3664fb0Sdan close $fd 529e3664fb0Sdan catchsql { SELECT * FROM t1 } 530e3664fb0Sdan} {1 {attempt to write a readonly database}} 531e3664fb0Sdando_test misc7-22.4 { 532e3664fb0Sdan sqlite3_extended_errcode db 533e3664fb0Sdan} SQLITE_READONLY_ROLLBACK 534a688ca5eSdancatch { db close } 535fda06befSmistachkinforcedelete test.db 53608d31a2aSdanielk1977 537b8fff29cSdanif {$::tcl_platform(platform)=="unix" 538b8fff29cSdan && [atomic_batch_write test.db]==0 539b8fff29cSdan} { 540a688ca5eSdan reset_db 541a688ca5eSdan do_execsql_test 23.0 { 542a688ca5eSdan CREATE TABLE t1(x, y); 543a688ca5eSdan INSERT INTO t1 VALUES(1, 2); 544a688ca5eSdan } 545a688ca5eSdan 546a688ca5eSdan do_test 23.1 { 547a688ca5eSdan db close 548a688ca5eSdan forcedelete tst 549a688ca5eSdan file mkdir tst 550a688ca5eSdan forcecopy test.db tst/test.db 551a688ca5eSdan file attributes tst -permissions r-xr-xr-x 552a688ca5eSdan } {} 553a688ca5eSdan 554a688ca5eSdan sqlite3 db tst/test.db 555a688ca5eSdan do_execsql_test 23.2 { 556a688ca5eSdan SELECT * FROM t1; 557a688ca5eSdan } {1 2} 558a688ca5eSdan 559a688ca5eSdan do_catchsql_test 23.3 { 560a688ca5eSdan INSERT INTO t1 VALUES(3, 4); 561a688ca5eSdan } {1 {attempt to write a readonly database}} 562a688ca5eSdan 563a688ca5eSdan do_test 23.4 { 564a688ca5eSdan sqlite3_extended_errcode db 565a688ca5eSdan } {SQLITE_READONLY_DIRECTORY} 566a688ca5eSdan 567a688ca5eSdan do_test 23.5 { 568a688ca5eSdan db close 569a688ca5eSdan forcedelete tst 570a688ca5eSdan } {} 571a688ca5eSdan} 572a688ca5eSdan 573a713f2c3Sdanielk1977finish_test 574