1# 2006 September 4 2# 3# The author disclaims copyright to this source code. In place of 4# a legal notice, here is a blessing: 5# 6# May you do good and not evil. 7# May you find forgiveness for yourself and forgive others. 8# May you share freely, never taking more than you give. 9# 10#*********************************************************************** 11# This file implements regression tests for SQLite library. 12# 13# $Id: misc7.test,v 1.29 2009/07/16 18:21:18 drh Exp $ 14 15set testdir [file dirname $argv0] 16source $testdir/tester.tcl 17set testprefix misc7 18 19if {[clang_sanitize_address]==0} { 20 do_test misc7-1-misuse { 21 c_misuse_test 22 } {} 23} 24 25do_test misc7-2 { 26 c_realloc_test 27} {} 28 29do_test misc7-3 { 30 c_collation_test 31} {} 32 33# Try to open a directory: 34# 35do_test misc7-4 { 36 delete_file mydir 37 file mkdir mydir 38 set rc [catch { 39 sqlite3 db2 ./mydir 40 } msg] 41 list $rc $msg 42} {1 {unable to open database file}} 43 44# Try to open a file with a directory where its journal file should be. 45# 46do_test misc7-5 { 47 delete_file mydir 48 file mkdir mydir-journal 49 sqlite3 db2 ./mydir 50 catchsql { 51 CREATE TABLE abc(a, b, c); 52 } db2 53} {1 {unable to open database file}} 54db2 close 55 56#-------------------------------------------------------------------- 57# The following tests, misc7-6.* test the libraries behaviour when 58# it cannot open a file. To force this condition, we use up all the 59# file-descriptors before running sqlite. This probably only works 60# on unix. 61# 62 63proc use_up_files {} { 64 set ret [list] 65 catch { 66 while 1 { lappend ret [open test.db] } 67 } 68 return $ret 69} 70 71proc do_fileopen_test {prefix sql} { 72 set fd_list [use_up_files] 73 set ::go 1 74 set ::n 1 75 set ::sql $sql 76 while {$::go} { 77 catch {db close} 78 do_test ${prefix}.${::n} { 79 set rc [catch { 80 sqlite db test.db 81 db eval $::sql 82 } msg] 83 if {$rc == 0} {set ::go 0} 84 85 expr {$rc == 0 || ($rc == 1 && [string first unable $msg]==0)} 86 } 1 87 88 close [lindex $fd_list 0] 89 set fd_list [lrange $fd_list 1 end] 90 incr ::n 91 } 92 foreach fd $fd_list { 93 close $fd 94 } 95 db close 96} 97 98execsql { CREATE TABLE abc(a PRIMARY KEY, b, c); } 99db close 100 101if {$tcl_platform(platform)!="windows"} { 102 do_fileopen_test misc7-6.1 { 103 BEGIN; 104 INSERT INTO abc VALUES(1, 2, 3); 105 INSERT INTO abc VALUES(2, 3, 4); 106 INSERT INTO abc SELECT a+2, b, c FROM abc; 107 COMMIT; 108 } 109 110 do_fileopen_test misc7-6.2 { 111 PRAGMA temp.cache_size = 1000; 112 } 113} 114 115# 116# End of tests for out-of-file-descriptors condition. 117#-------------------------------------------------------------------- 118 119sqlite3 db test.db 120execsql { 121 DELETE FROM abc; 122 INSERT INTO abc VALUES(1, 2, 3); 123 INSERT INTO abc VALUES(2, 3, 4); 124 INSERT INTO abc SELECT a+2, b, c FROM abc; 125} 126 127 128#-------------------------------------------------------------------- 129# Test that the sqlite3_busy_timeout call seems to delay approximately 130# the right amount of time. 131# 132do_test misc7-7.0 { 133 sqlite3 db2 test.db 134 sqlite3_busy_timeout [sqlite3_connection_pointer db] 2000 135 execsql { 136 BEGIN EXCLUSIVE; 137 } db2 138 139 # Now db2 has an exclusive lock on the database file, and db has 140 # a busy-timeout of 2000 milliseconds. So check that trying to 141 # access the database using connection db delays for at least 1500 ms. 142 # 143 set tm [time { 144 set result [catchsql { 145 SELECT * FROM sqlite_master; 146 } db] 147 }] 148 set delay [lindex $tm 0] ;# In microseconds 149 lappend result [expr {$delay>1500000 && $delay<4000000}] 150} {1 {database is locked} 1} 151db2 close 152 153#-------------------------------------------------------------------- 154# Test that nothing goes horribly wrong when attaching a database 155# after the omit_readlock pragma has been exercised. 156# 157# Note: The PRAGMA omit_readlock was an early hack to disable the 158# fcntl() calls for read-only databases so that read-only databases could 159# be read on broken NFS systems. That pragma has now been removed. 160# (Use the unix-none VFS as a replacement, if needed.) But these tests 161# do not really depend on omit_readlock, so we left them in place. 162# 163do_test misc7-7.1 { 164 forcedelete test2.db 165 forcedelete test2.db-journal 166 execsql { 167 PRAGMA omit_readlock = 1; 168 ATTACH 'test2.db' AS aux; 169 CREATE TABLE aux.hello(world); 170 SELECT name FROM aux.sqlite_master; 171 } 172} {hello} 173do_test misc7-7.2 { 174 execsql { 175 DETACH aux; 176 } 177} {} 178do_test misc7-7.3 { 179 db close 180 sqlite3 db test.db -readonly 1 181 execsql { 182 PRAGMA omit_readlock = 1; 183 ATTACH 'test2.db' AS aux; 184 SELECT name FROM aux.sqlite_master; 185 SELECT name FROM aux.sqlite_master; 186 } 187} {hello hello} 188do_test misc7-7.3 { 189 db close 190 sqlite3 db test.db 191 set ::DB [sqlite3_connection_pointer db] 192 list 193} {} 194 195# Test the UTF-16 version of the "out of memory" message (used when 196# malloc fails during sqlite3_open() ). 197# 198ifcapable utf16 { 199 do_test misc7-8 { 200 encoding convertfrom unicode [sqlite3_errmsg16 0x00000000] 201 } {out of memory} 202} 203 204do_test misc7-9 { 205 execsql { 206 SELECT * 207 FROM (SELECT name+1 AS one FROM sqlite_master LIMIT 1 OFFSET 1) 208 WHERE one LIKE 'hello%'; 209 } 210} {} 211 212#-------------------------------------------------------------------- 213# Improve coverage for vtab code. 214# 215ifcapable vtab { 216 # Run some debug code to improve reported coverage 217 # 218 219 # set sqlite_where_trace 1 220 do_test misc7-10 { 221 register_echo_module [sqlite3_connection_pointer db] 222 execsql { 223 CREATE VIRTUAL TABLE t1 USING echo(abc); 224 SELECT a FROM t1 WHERE a = 1 ORDER BY b; 225 } 226 } {1} 227 set sqlite_where_trace 0 228 229 # Specify an ORDER BY clause that cannot be indexed. 230 do_test misc7-11 { 231 execsql { 232 SELECT t1.a, t2.a FROM t1, t1 AS t2 ORDER BY 2 LIMIT 1; 233 } 234 } {1 1} 235 236 # The whole point of this is to test an error code other than 237 # SQLITE_NOMEM from the vtab xBestIndex callback. 238 # 239 do_ioerr_test misc7-12 -tclprep { 240 sqlite3 db2 test.db 241 register_echo_module [sqlite3_connection_pointer db2] 242 db2 eval { 243 CREATE TABLE abc(a PRIMARY KEY, b, c); 244 INSERT INTO abc VALUES(1, 2, 3); 245 CREATE VIRTUAL TABLE t1 USING echo(abc); 246 } 247 db2 close 248 } -tclbody { 249 register_echo_module [sqlite3_connection_pointer db] 250 execsql {SELECT * FROM t1 WHERE a = 1;} 251 } 252 253 # The case where the virtual table module returns a very large number 254 # as the cost of a scan (greater than SQLITE_BIG_DOUBLE in the code). 255 # 256 do_test misc7-13 { 257 sqlite3 db test.db 258 register_echo_module [sqlite3_connection_pointer db] 259 set ::echo_module_cost 2.0e+99 260 execsql {SELECT * FROM t1 WHERE a = 1;} 261 } {1 2 3} 262 unset ::echo_module_cost 263} 264 265db close 266forcedelete test.db 267forcedelete test.db-journal 268sqlite3 db test.db 269 270ifcapable explain { 271 do_execsql_test misc7-14.1 { 272 CREATE TABLE abc(a PRIMARY KEY, b, c); 273 EXPLAIN QUERY PLAN SELECT * FROM abc AS t2 WHERE rowid = 1; 274 } { 275 0 0 0 {SEARCH TABLE abc AS t2 USING INTEGER PRIMARY KEY (rowid=?)} 276 } 277 do_execsql_test misc7-14.2 { 278 EXPLAIN QUERY PLAN SELECT * FROM abc AS t2 WHERE a = 1; 279 } {0 0 0 280 {SEARCH TABLE abc AS t2 USING INDEX sqlite_autoindex_abc_1 (a=?)} 281 } 282 do_execsql_test misc7-14.3 { 283 EXPLAIN QUERY PLAN SELECT * FROM abc AS t2 ORDER BY a; 284 } {0 0 0 285 {SCAN TABLE abc AS t2 USING INDEX sqlite_autoindex_abc_1} 286 } 287} 288 289db close 290forcedelete test.db 291forcedelete test.db-journal 292sqlite3 db test.db 293 294#-------------------------------------------------------------------- 295# This is all to force the pager_remove_from_stmt_list() function 296# (inside pager.c) to remove a pager from the middle of the 297# statement-list. 298# 299do_test misc7-15.1 { 300 execsql { 301 PRAGMA cache_size = 10; 302 BEGIN; 303 CREATE TABLE abc(a PRIMARY KEY, b, c); 304 INSERT INTO abc 305 VALUES(randstr(100,100), randstr(100,100), randstr(100,100)); 306 INSERT INTO abc SELECT 307 randstr(100,100), randstr(100,100), randstr(100,100) FROM abc; 308 INSERT INTO abc SELECT 309 randstr(100,100), randstr(100,100), randstr(100,100) FROM abc; 310 INSERT INTO abc SELECT 311 randstr(100,100), randstr(100,100), randstr(100,100) FROM abc; 312 INSERT INTO abc SELECT 313 randstr(100,100), randstr(100,100), randstr(100,100) FROM abc; 314 INSERT INTO abc SELECT 315 randstr(100,100), randstr(100,100), randstr(100,100) FROM abc; 316 INSERT INTO abc SELECT 317 randstr(100,100), randstr(100,100), randstr(100,100) FROM abc; 318 INSERT INTO abc SELECT 319 randstr(100,100), randstr(100,100), randstr(100,100) FROM abc; 320 INSERT INTO abc SELECT 321 randstr(100,100), randstr(100,100), randstr(100,100) FROM abc; 322 COMMIT; 323 } 324 expr {[file size test.db]>10240} 325} {1} 326do_test misc7-15.2 { 327 execsql { 328 DELETE FROM abc WHERE rowid > 12; 329 INSERT INTO abc SELECT 330 randstr(100,100), randstr(100,100), randstr(100,100) FROM abc; 331 } 332} {} 333 334db close 335forcedelete test.db 336forcedelete test.db-journal 337sqlite3 db test.db 338 339do_ioerr_test misc7-16 -sqlprep { 340 PRAGMA cache_size = 10; 341 PRAGMA default_cache_size = 10; 342 CREATE TABLE t3(a, b, UNIQUE(a, b)); 343 INSERT INTO t3 VALUES( randstr(100, 100), randstr(100, 100) ); 344 INSERT INTO t3 SELECT randstr(100, 100), randstr(100, 100) FROM t3; 345 INSERT INTO t3 SELECT randstr(100, 100), randstr(100, 100) FROM t3; 346 INSERT INTO t3 SELECT randstr(100, 100), randstr(100, 100) FROM t3; 347 INSERT INTO t3 SELECT randstr(100, 100), randstr(100, 100) FROM t3; 348 INSERT INTO t3 SELECT randstr(100, 100), randstr(100, 100) FROM t3; 349 UPDATE t3 350 SET b = 'hello world' 351 WHERE rowid >= (SELECT max(rowid)-1 FROM t3); 352} -tclbody { 353 set rc [catch {db eval { 354 BEGIN; 355 PRAGMA cache_size = 10; 356 INSERT INTO t3 VALUES( randstr(100, 100), randstr(100, 100) ); 357 UPDATE t3 SET a = b; 358 COMMIT; 359 }} msg] 360 361 if {!$rc || ($rc && [string first "UNIQUE" $msg]==0)} { 362 set msg 363 } else { 364 error $msg 365 } 366} 367 368sqlite3 db test.db 369 370do_test misc7-16.X { 371 execsql { 372 SELECT count(*) FROM t3; 373 } 374} {32} 375 376#---------------------------------------------------------------------- 377# Test the situation where a hot-journal is discovered but write-access 378# to it is denied. This should return SQLITE_BUSY. 379# 380# These tests do not work on windows due to restrictions in the 381# windows file system. 382# 383if {$tcl_platform(platform)!="windows"} { 384 385 # Some network filesystems (ex: AFP) do not support setting read-only 386 # permissions. Only run these tests if full unix permission setting 387 # capabilities are supported. 388 # 389 file attributes test.db -permissions rw-r--r-- 390 if {[file attributes test.db -permissions]==0644} { 391 392 do_test misc7-17.1 { 393 execsql { 394 BEGIN; 395 DELETE FROM t3 WHERE (oid%3)==0; 396 } 397 forcecopy test.db bak.db 398 forcecopy test.db-journal bak.db-journal 399 execsql { 400 COMMIT; 401 } 402 403 db close 404 forcecopy bak.db test.db 405 forcecopy bak.db-journal test.db-journal 406 sqlite3 db test.db 407 408 catch {file attributes test.db-journal -permissions r--------} 409 catch {file attributes test.db-journal -readonly 1} 410 catchsql { 411 SELECT count(*) FROM t3; 412 } 413 } {1 {unable to open database file}} 414 do_test misc7-17.2 { 415 # Note that the -readonly flag must be cleared before the -permissions 416 # are set. Otherwise, when using tcl 8.5 on mac, the fact that the 417 # -readonly flag is set causes the attempt to set the permissions 418 # to fail. 419 catch {file attributes test.db-journal -readonly 0} 420 catch {file attributes test.db-journal -permissions rw-------} 421 catchsql { 422 SELECT count(*) FROM t3; 423 } 424 } {0 32} 425 426 # sqlite3_test_control_pending_page [expr ($::sqlite_pending_byte / 1024) + 1] 427 set ::pending_byte_page [expr ($::sqlite_pending_byte / 1024) + 1] 428 sqlite3_test_control_pending_byte $::sqlite_pending_byte 429 do_test misc7-17.3 { 430 db eval { 431 pragma writable_schema = true; 432 UPDATE sqlite_master 433 SET rootpage = $pending_byte_page 434 WHERE type = 'table' AND name = 't3'; 435 } 436 execsql { 437 SELECT rootpage FROM sqlite_master WHERE type = 'table' AND name = 't3'; 438 } 439 } $::pending_byte_page 440 441 do_test misc7-17.4 { 442 db close 443 sqlite3 db test.db 444 catchsql { 445 SELECT count(*) FROM t3; 446 } 447 } {1 {database disk image is malformed}} 448 } 449} 450 451# Ticket #2470 452# 453do_test misc7-18.1 { 454 execsql { 455 CREATE TABLE table_1 (col_10); 456 CREATE TABLE table_2 ( 457 col_1, col_2, col_3, col_4, col_5, 458 col_6, col_7, col_8, col_9, col_10 459 ); 460 SELECT a.col_10 461 FROM 462 (SELECT table_1.col_10 AS col_10 FROM table_1) a, 463 (SELECT table_1.col_10, table_2.col_9 AS qcol_9 464 FROM table_1, table_2 465 GROUP BY table_1.col_10, qcol_9); 466 } 467} {} 468 469# Testing boundary conditions on sqlite3_status() 470# 471do_test misc7-19.1 { 472 sqlite3_status -1 0 473} {21 0 0} 474do_test misc7-19.2 { 475 sqlite3_status 1000 0 476} {21 0 0} 477 478 479# sqlite3_global_recover() is a no-op. But we might as well test it 480# if only to get the test coverage. 481# 482do_test misc7-20.1 { 483 sqlite3_global_recover 484} {SQLITE_OK} 485 486# Try to open a really long file name. 487# 488do_test misc7-21.1 { 489 set zFile [file join [get_pwd] "[string repeat abcde 104].db"] 490 set rc [catch {sqlite3 db2 $zFile} msg] 491 list $rc $msg 492} {1 {unable to open database file}} 493 494# Try to do hot-journal rollback with a read-only connection. The 495# error code should be SQLITE_READONLY_ROLLBACK. 496# 497do_test misc7-22.1 { 498 db close 499 forcedelete test.db copy.db-journal 500 sqlite3 db test.db 501 execsql { 502 CREATE TABLE t1(a, b); 503 INSERT INTO t1 VALUES(1, 2); 504 INSERT INTO t1 VALUES(3, 4); 505 } 506 db close 507 sqlite3 db test.db -readonly 1 508 catchsql { 509 INSERT INTO t1 VALUES(5, 6); 510 } 511} {1 {attempt to write a readonly database}} 512do_test misc7-22.2 { execsql { SELECT * FROM t1 } } {1 2 3 4} 513do_test misc7-22.3 { 514 set fd [open test.db-journal w] 515 puts $fd [string repeat abc 1000] 516 close $fd 517 catchsql { SELECT * FROM t1 } 518} {1 {attempt to write a readonly database}} 519do_test misc7-22.4 { 520 sqlite3_extended_errcode db 521} SQLITE_READONLY_ROLLBACK 522catch { db close } 523forcedelete test.db 524 525if {$::tcl_platform(platform)=="unix"} { 526 reset_db 527 do_execsql_test 23.0 { 528 CREATE TABLE t1(x, y); 529 INSERT INTO t1 VALUES(1, 2); 530 } 531 532 do_test 23.1 { 533 db close 534 forcedelete tst 535 file mkdir tst 536 forcecopy test.db tst/test.db 537 file attributes tst -permissions r-xr-xr-x 538 } {} 539 540 sqlite3 db tst/test.db 541 do_execsql_test 23.2 { 542 SELECT * FROM t1; 543 } {1 2} 544 545 do_catchsql_test 23.3 { 546 INSERT INTO t1 VALUES(3, 4); 547 } {1 {attempt to write a readonly database}} 548 549 do_test 23.4 { 550 sqlite3_extended_errcode db 551 } {SQLITE_READONLY_DIRECTORY} 552 553 do_test 23.5 { 554 db close 555 forcedelete tst 556 } {} 557} 558 559finish_test 560