1 # 2005 December 30 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 # 12 # $Id: shared.test,v 1.36 2009/03/16 13:19:36 danielk1977 Exp $ 13 14 set testdir [file dirname $argv0] 15 source $testdir/tester.tcl 16 db close 17 18 # These tests cannot be run without the ATTACH command. 19 # 20 ifcapable !shared_cache||!attach { 21 finish_test 22 return 23 } 24 25 set ::enable_shared_cache [sqlite3_enable_shared_cache 1] 26 27 foreach av [list 0 1] { 28 29 # Open the database connection and execute the auto-vacuum pragma 30 file delete -force test.db 31 sqlite3 db test.db 32 33 ifcapable autovacuum { 34 do_test shared-[expr $av+1].1.0 { 35 execsql "pragma auto_vacuum=$::av" 36 execsql {pragma auto_vacuum} 37 } "$av" 38 } else { 39 if {$av} { 40 db close 41 break 42 } 43 } 44 45 # if we're using proxy locks, we use 2 filedescriptors for a db 46 # that is open but NOT yet locked, after a lock is taken we'll have 3, 47 # normally sqlite uses 1 (proxy locking adds the conch and the local lock) 48 set using_proxy 0 49 foreach {name value} [array get env SQLITE_FORCE_PROXY_LOCKING] { 50 set using_proxy $value 51 } 52 set extrafds_prelock 0 53 set extrafds_postlock 0 54 if {$using_proxy>0} { 55 set extrafds_prelock 1 56 set extrafds_postlock 2 57 } 58 59 # $av is currently 0 if this loop iteration is to test with auto-vacuum turned 60 # off, and 1 if it is turned on. Increment it so that (1 -> no auto-vacuum) 61 # and (2 -> auto-vacuum). The sole reason for this is so that it looks nicer 62 # when we use this variable as part of test-case names. 63 # 64 incr av 65 66 # Test organization: 67 # 68 # shared-1.*: Simple test to verify basic sanity of table level locking when 69 # two connections share a pager cache. 70 # shared-2.*: Test that a read transaction can co-exist with a 71 # write-transaction, including a simple test to ensure the 72 # external locking protocol is still working. 73 # shared-3.*: Simple test of read-uncommitted mode. 74 # shared-4.*: Check that the schema is locked and unlocked correctly. 75 # shared-5.*: Test that creating/dropping schema items works when databases 76 # are attached in different orders to different handles. 77 # shared-6.*: Locking, UNION ALL queries and sub-queries. 78 # shared-7.*: Autovacuum and shared-cache. 79 # shared-8.*: Tests related to the text encoding of shared-cache databases. 80 # shared-9.*: TEMP triggers and shared-cache databases. 81 # shared-10.*: Tests of sqlite3_close(). 82 # shared-11.*: Test transaction locking. 83 # 84 85 do_test shared-$av.1.1 { 86 # Open a second database on the file test.db. It should use the same pager 87 # cache and schema as the original connection. Verify that only 1 file is 88 # opened. 89 sqlite3 db2 test.db 90 set ::sqlite_open_file_count 91 expr $sqlite_open_file_count-$extrafds_postlock 92 } {1} 93 do_test shared-$av.1.2 { 94 # Add a table and a single row of data via the first connection. 95 # Ensure that the second connection can see them. 96 execsql { 97 CREATE TABLE abc(a, b, c); 98 INSERT INTO abc VALUES(1, 2, 3); 99 } db 100 execsql { 101 SELECT * FROM abc; 102 } db2 103 } {1 2 3} 104 do_test shared-$av.1.3 { 105 # Have the first connection begin a transaction and obtain a read-lock 106 # on table abc. This should not prevent the second connection from 107 # querying abc. 108 execsql { 109 BEGIN; 110 SELECT * FROM abc; 111 } 112 execsql { 113 SELECT * FROM abc; 114 } db2 115 } {1 2 3} 116 do_test shared-$av.1.4 { 117 # Try to insert a row into abc via connection 2. This should fail because 118 # of the read-lock connection 1 is holding on table abc (obtained in the 119 # previous test case). 120 catchsql { 121 INSERT INTO abc VALUES(4, 5, 6); 122 } db2 123 } {1 {database table is locked: abc}} 124 do_test shared-$av.1.5 { 125 # Using connection 2 (the one without the open transaction), try to create 126 # a new table. This should fail because of the open read transaction 127 # held by connection 1. 128 catchsql { 129 CREATE TABLE def(d, e, f); 130 } db2 131 } {1 {database table is locked: sqlite_master}} 132 do_test shared-$av.1.6 { 133 # Upgrade connection 1's transaction to a write transaction. Create 134 # a new table - def - and insert a row into it. Because the connection 1 135 # transaction modifies the schema, it should not be possible for 136 # connection 2 to access the database at all until the connection 1 137 # has finished the transaction. 138 execsql { 139 CREATE TABLE def(d, e, f); 140 INSERT INTO def VALUES('IV', 'V', 'VI'); 141 } 142 } {} 143 do_test shared-$av.1.7 { 144 # Read from the sqlite_master table with connection 1 (inside the 145 # transaction). Then test that we can not do this with connection 2. This 146 # is because of the schema-modified lock established by connection 1 147 # in the previous test case. 148 execsql { 149 SELECT * FROM sqlite_master; 150 } 151 catchsql { 152 SELECT * FROM sqlite_master; 153 } db2 154 } {1 {database schema is locked: main}} 155 do_test shared-$av.1.8 { 156 # Commit the connection 1 transaction. 157 execsql { 158 COMMIT; 159 } 160 } {} 161 162 do_test shared-$av.2.1 { 163 # Open connection db3 to the database. Use a different path to the same 164 # file so that db3 does *not* share the same pager cache as db and db2 165 # (there should be two open file handles). 166 if {$::tcl_platform(platform)=="unix"} { 167 sqlite3 db3 ./test.db 168 } else { 169 sqlite3 db3 TEST.DB 170 } 171 set ::sqlite_open_file_count 172 expr $sqlite_open_file_count-($extrafds_prelock+$extrafds_postlock) 173 } {2} 174 do_test shared-$av.2.2 { 175 # Start read transactions on db and db2 (the shared pager cache). Ensure 176 # db3 cannot write to the database. 177 execsql { 178 BEGIN; 179 SELECT * FROM abc; 180 } 181 execsql { 182 BEGIN; 183 SELECT * FROM abc; 184 } db2 185 catchsql { 186 INSERT INTO abc VALUES(1, 2, 3); 187 } db2 188 } {1 {database table is locked: abc}} 189 do_test shared-$av.2.3 { 190 # Turn db's transaction into a write-transaction. db3 should still be 191 # able to read from table def (but will not see the new row). Connection 192 # db2 should not be able to read def (because of the write-lock). 193 194 # Todo: The failed "INSERT INTO abc ..." statement in the above test 195 # has started a write-transaction on db2 (should this be so?). This 196 # would prevent connection db from starting a write-transaction. So roll the 197 # db2 transaction back and replace it with a new read transaction. 198 execsql { 199 ROLLBACK; 200 BEGIN; 201 SELECT * FROM abc; 202 } db2 203 204 execsql { 205 INSERT INTO def VALUES('VII', 'VIII', 'IX'); 206 } 207 concat [ 208 catchsql { SELECT * FROM def; } db3 209 ] [ 210 catchsql { SELECT * FROM def; } db2 211 ] 212 } {0 {IV V VI} 1 {database table is locked: def}} 213 do_test shared-$av.2.4 { 214 # Commit the open transaction on db. db2 still holds a read-transaction. 215 # This should prevent db3 from writing to the database, but not from 216 # reading. 217 execsql { 218 COMMIT; 219 } 220 concat [ 221 catchsql { SELECT * FROM def; } db3 222 ] [ 223 catchsql { INSERT INTO def VALUES('X', 'XI', 'XII'); } db3 224 ] 225 } {0 {IV V VI VII VIII IX} 1 {database is locked}} 226 227 catchsql COMMIT db2 228 229 do_test shared-$av.3.1.1 { 230 # This test case starts a linear scan of table 'seq' using a 231 # read-uncommitted connection. In the middle of the scan, rows are added 232 # to the end of the seq table (ahead of the current cursor position). 233 # The uncommitted rows should be included in the results of the scan. 234 execsql " 235 CREATE TABLE seq(i PRIMARY KEY, x); 236 INSERT INTO seq VALUES(1, '[string repeat X 500]'); 237 INSERT INTO seq VALUES(2, '[string repeat X 500]'); 238 " 239 execsql {SELECT * FROM sqlite_master} db2 240 execsql {PRAGMA read_uncommitted = 1} db2 241 242 set ret [list] 243 db2 eval {SELECT i FROM seq ORDER BY i} { 244 if {$i < 4} { 245 set max [execsql {SELECT max(i) FROM seq}] 246 db eval { 247 INSERT INTO seq SELECT i + :max, x FROM seq; 248 } 249 } 250 lappend ret $i 251 } 252 set ret 253 } {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16} 254 do_test shared-$av.3.1.2 { 255 # Another linear scan through table seq using a read-uncommitted connection. 256 # This time, delete each row as it is read. Should not affect the results of 257 # the scan, but the table should be empty after the scan is concluded 258 # (test 3.1.3 verifies this). 259 set ret [list] 260 db2 eval {SELECT i FROM seq} { 261 db eval {DELETE FROM seq WHERE i = :i} 262 lappend ret $i 263 } 264 set ret 265 } {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16} 266 do_test shared-$av.3.1.3 { 267 execsql { 268 SELECT * FROM seq; 269 } 270 } {} 271 272 catch {db close} 273 catch {db2 close} 274 catch {db3 close} 275 276 #-------------------------------------------------------------------------- 277 # Tests shared-4.* test that the schema locking rules are applied 278 # correctly. i.e.: 279 # 280 # 1. All transactions require a read-lock on the schemas of databases they 281 # access. 282 # 2. Transactions that modify a database schema require a write-lock on that 283 # schema. 284 # 3. It is not possible to compile a statement while another handle has a 285 # write-lock on the schema. 286 # 287 288 # Open two database handles db and db2. Each has a single attach database 289 # (as well as main): 290 # 291 # db.main -> ./test.db 292 # db.test2 -> ./test2.db 293 # db2.main -> ./test2.db 294 # db2.test -> ./test.db 295 # 296 file delete -force test.db 297 file delete -force test2.db 298 file delete -force test2.db-journal 299 sqlite3 db test.db 300 sqlite3 db2 test2.db 301 do_test shared-$av.4.1.1 { 302 set sqlite_open_file_count 303 expr $sqlite_open_file_count-($extrafds_prelock*2) 304 } {2} 305 do_test shared-$av.4.1.2 { 306 execsql {ATTACH 'test2.db' AS test2} 307 set sqlite_open_file_count 308 expr $sqlite_open_file_count-($extrafds_postlock*2) 309 } {2} 310 do_test shared-$av.4.1.3 { 311 execsql {ATTACH 'test.db' AS test} db2 312 set sqlite_open_file_count 313 expr $sqlite_open_file_count-($extrafds_postlock*2) 314 } {2} 315 316 # Sanity check: Create a table in ./test.db via handle db, and test that handle 317 # db2 can "see" the new table immediately. A handle using a seperate pager 318 # cache would have to reload the database schema before this were possible. 319 # 320 do_test shared-$av.4.2.1 { 321 execsql { 322 CREATE TABLE abc(a, b, c); 323 CREATE TABLE def(d, e, f); 324 INSERT INTO abc VALUES('i', 'ii', 'iii'); 325 INSERT INTO def VALUES('I', 'II', 'III'); 326 } 327 } {} 328 do_test shared-$av.4.2.2 { 329 execsql { 330 SELECT * FROM test.abc; 331 } db2 332 } {i ii iii} 333 334 # Open a read-transaction and read from table abc via handle 2. Check that 335 # handle 1 can read table abc. Check that handle 1 cannot modify table abc 336 # or the database schema. Then check that handle 1 can modify table def. 337 # 338 do_test shared-$av.4.3.1 { 339 execsql { 340 BEGIN; 341 SELECT * FROM test.abc; 342 } db2 343 } {i ii iii} 344 do_test shared-$av.4.3.2 { 345 catchsql { 346 INSERT INTO abc VALUES('iv', 'v', 'vi'); 347 } 348 } {1 {database table is locked: abc}} 349 do_test shared-$av.4.3.3 { 350 catchsql { 351 CREATE TABLE ghi(g, h, i); 352 } 353 } {1 {database table is locked: sqlite_master}} 354 do_test shared-$av.4.3.3 { 355 catchsql { 356 INSERT INTO def VALUES('IV', 'V', 'VI'); 357 } 358 } {0 {}} 359 do_test shared-$av.4.3.4 { 360 # Cleanup: commit the transaction opened by db2. 361 execsql { 362 COMMIT 363 } db2 364 } {} 365 366 # Open a write-transaction using handle 1 and modify the database schema. 367 # Then try to execute a compiled statement to read from the same 368 # database via handle 2 (fails to get the lock on sqlite_master). Also 369 # try to compile a read of the same database using handle 2 (also fails). 370 # Finally, compile a read of the other database using handle 2. This 371 # should also fail. 372 # 373 ifcapable compound { 374 do_test shared-$av.4.4.1.2 { 375 # Sanity check 1: Check that the schema is what we think it is when viewed 376 # via handle 1. 377 execsql { 378 CREATE TABLE test2.ghi(g, h, i); 379 SELECT 'test.db:'||name FROM sqlite_master 380 UNION ALL 381 SELECT 'test2.db:'||name FROM test2.sqlite_master; 382 } 383 } {test.db:abc test.db:def test2.db:ghi} 384 do_test shared-$av.4.4.1.2 { 385 # Sanity check 2: Check that the schema is what we think it is when viewed 386 # via handle 2. 387 execsql { 388 SELECT 'test2.db:'||name FROM sqlite_master 389 UNION ALL 390 SELECT 'test.db:'||name FROM test.sqlite_master; 391 } db2 392 } {test2.db:ghi test.db:abc test.db:def} 393 } 394 395 do_test shared-$av.4.4.2 { 396 set ::DB2 [sqlite3_connection_pointer db2] 397 set sql {SELECT * FROM abc} 398 set ::STMT1 [sqlite3_prepare $::DB2 $sql -1 DUMMY] 399 execsql { 400 BEGIN; 401 CREATE TABLE jkl(j, k, l); 402 } 403 sqlite3_step $::STMT1 404 } {SQLITE_ERROR} 405 do_test shared-$av.4.4.3 { 406 sqlite3_finalize $::STMT1 407 } {SQLITE_LOCKED} 408 do_test shared-$av.4.4.4 { 409 set rc [catch { 410 set ::STMT1 [sqlite3_prepare $::DB2 $sql -1 DUMMY] 411 } msg] 412 list $rc $msg 413 } {1 {(6) database schema is locked: test}} 414 do_test shared-$av.4.4.5 { 415 set rc [catch { 416 set ::STMT1 [sqlite3_prepare $::DB2 "SELECT * FROM ghi" -1 DUMMY] 417 } msg] 418 list $rc $msg 419 } {1 {(6) database schema is locked: test}} 420 421 422 catch {db2 close} 423 catch {db close} 424 425 #-------------------------------------------------------------------------- 426 # Tests shared-5.* 427 # 428 foreach db [list test.db test1.db test2.db test3.db] { 429 file delete -force $db ${db}-journal 430 } 431 do_test shared-$av.5.1.1 { 432 sqlite3 db1 test.db 433 sqlite3 db2 test.db 434 execsql { 435 ATTACH 'test1.db' AS test1; 436 ATTACH 'test2.db' AS test2; 437 ATTACH 'test3.db' AS test3; 438 } db1 439 execsql { 440 ATTACH 'test3.db' AS test3; 441 ATTACH 'test2.db' AS test2; 442 ATTACH 'test1.db' AS test1; 443 } db2 444 } {} 445 do_test shared-$av.5.1.2 { 446 execsql { 447 CREATE TABLE test1.t1(a, b); 448 CREATE INDEX test1.i1 ON t1(a, b); 449 } db1 450 } {} 451 ifcapable view { 452 do_test shared-$av.5.1.3 { 453 execsql { 454 CREATE VIEW test1.v1 AS SELECT * FROM t1; 455 } db1 456 } {} 457 } 458 ifcapable trigger { 459 do_test shared-$av.5.1.4 { 460 execsql { 461 CREATE TRIGGER test1.trig1 AFTER INSERT ON t1 BEGIN 462 INSERT INTO t1 VALUES(new.a, new.b); 463 END; 464 } db1 465 } {} 466 } 467 do_test shared-$av.5.1.5 { 468 execsql { 469 DROP INDEX i1; 470 } db2 471 } {} 472 ifcapable view { 473 do_test shared-$av.5.1.6 { 474 execsql { 475 DROP VIEW v1; 476 } db2 477 } {} 478 } 479 ifcapable trigger { 480 do_test shared-$av.5.1.7 { 481 execsql { 482 DROP TRIGGER trig1; 483 } db2 484 } {} 485 } 486 do_test shared-$av.5.1.8 { 487 execsql { 488 DROP TABLE t1; 489 } db2 490 } {} 491 ifcapable compound { 492 do_test shared-$av.5.1.9 { 493 execsql { 494 SELECT * FROM sqlite_master UNION ALL SELECT * FROM test1.sqlite_master 495 } db1 496 } {} 497 } 498 499 #-------------------------------------------------------------------------- 500 # Tests shared-6.* test that a query obtains all the read-locks it needs 501 # before starting execution of the query. This means that there is no chance 502 # some rows of data will be returned before a lock fails and SQLITE_LOCK 503 # is returned. 504 # 505 do_test shared-$av.6.1.1 { 506 execsql { 507 CREATE TABLE t1(a, b); 508 CREATE TABLE t2(a, b); 509 INSERT INTO t1 VALUES(1, 2); 510 INSERT INTO t2 VALUES(3, 4); 511 } db1 512 } {} 513 ifcapable compound { 514 do_test shared-$av.6.1.2 { 515 execsql { 516 SELECT * FROM t1 UNION ALL SELECT * FROM t2; 517 } db2 518 } {1 2 3 4} 519 } 520 do_test shared-$av.6.1.3 { 521 # Establish a write lock on table t2 via connection db2. Then make a 522 # UNION all query using connection db1 that first accesses t1, followed 523 # by t2. If the locks are grabbed at the start of the statement (as 524 # they should be), no rows are returned. If (as was previously the case) 525 # they are grabbed as the tables are accessed, the t1 rows will be 526 # returned before the query fails. 527 # 528 execsql { 529 BEGIN; 530 INSERT INTO t2 VALUES(5, 6); 531 } db2 532 set ret [list] 533 catch { 534 db1 eval {SELECT * FROM t1 UNION ALL SELECT * FROM t2} { 535 lappend ret $a $b 536 } 537 } 538 set ret 539 } {} 540 do_test shared-$av.6.1.4 { 541 execsql { 542 COMMIT; 543 BEGIN; 544 INSERT INTO t1 VALUES(7, 8); 545 } db2 546 set ret [list] 547 catch { 548 db1 eval { 549 SELECT (CASE WHEN a>4 THEN (SELECT a FROM t1) ELSE 0 END) AS d FROM t2; 550 } { 551 lappend ret $d 552 } 553 } 554 set ret 555 } {} 556 557 catch {db1 close} 558 catch {db2 close} 559 foreach f [list test.db test2.db] { 560 file delete -force $f ${f}-journal 561 } 562 563 #-------------------------------------------------------------------------- 564 # Tests shared-7.* test auto-vacuum does not invalidate cursors from 565 # other shared-cache users when it reorganizes the database on 566 # COMMIT. 567 # 568 do_test shared-$av.7.1 { 569 # This test case sets up a test database in auto-vacuum mode consisting 570 # of two tables, t1 and t2. Both have a single index. Table t1 is 571 # populated first (so consists of pages toward the start of the db file), 572 # t2 second (pages toward the end of the file). 573 sqlite3 db test.db 574 sqlite3 db2 test.db 575 execsql { 576 BEGIN; 577 CREATE TABLE t1(a PRIMARY KEY, b); 578 CREATE TABLE t2(a PRIMARY KEY, b); 579 } 580 set ::contents {} 581 for {set i 0} {$i < 100} {incr i} { 582 set a [string repeat "$i " 20] 583 set b [string repeat "$i " 20] 584 db eval { 585 INSERT INTO t1 VALUES(:a, :b); 586 } 587 lappend ::contents [list [expr $i+1] $a $b] 588 } 589 execsql { 590 INSERT INTO t2 SELECT * FROM t1; 591 COMMIT; 592 } 593 } {} 594 do_test shared-$av.7.2 { 595 # This test case deletes the contents of table t1 (the one at the start of 596 # the file) while many cursors are open on table t2 and its index. All of 597 # the non-root pages will be moved from the end to the start of the file 598 # when the DELETE is committed - this test verifies that moving the pages 599 # does not disturb the open cursors. 600 # 601 602 proc lockrow {db tbl oids body} { 603 set ret [list] 604 db eval "SELECT oid AS i, a, b FROM $tbl ORDER BY a" { 605 if {$i==[lindex $oids 0]} { 606 set noids [lrange $oids 1 end] 607 if {[llength $noids]==0} { 608 set subret [eval $body] 609 } else { 610 set subret [lockrow $db $tbl $noids $body] 611 } 612 } 613 lappend ret [list $i $a $b] 614 } 615 return [linsert $subret 0 $ret] 616 } 617 proc locktblrows {db tbl body} { 618 set oids [db eval "SELECT oid FROM $tbl"] 619 lockrow $db $tbl $oids $body 620 } 621 622 set scans [locktblrows db t2 { 623 execsql { 624 DELETE FROM t1; 625 } db2 626 }] 627 set error 0 628 629 # Test that each SELECT query returned the expected contents of t2. 630 foreach s $scans { 631 if {[lsort -integer -index 0 $s]!=$::contents} { 632 set error 1 633 } 634 } 635 set error 636 } {0} 637 638 catch {db close} 639 catch {db2 close} 640 unset -nocomplain contents 641 642 #-------------------------------------------------------------------------- 643 # The following tests try to trick the shared-cache code into assuming 644 # the wrong encoding for a database. 645 # 646 file delete -force test.db test.db-journal 647 ifcapable utf16 { 648 do_test shared-$av.8.1.1 { 649 sqlite3 db test.db 650 execsql { 651 PRAGMA encoding = 'UTF-16'; 652 SELECT * FROM sqlite_master; 653 } 654 } {} 655 do_test shared-$av.8.1.2 { 656 string range [execsql {PRAGMA encoding;}] 0 end-2 657 } {UTF-16} 658 659 do_test shared-$av.8.1.3 { 660 sqlite3 db2 test.db 661 execsql { 662 PRAGMA encoding = 'UTF-8'; 663 CREATE TABLE abc(a, b, c); 664 } db2 665 } {} 666 do_test shared-$av.8.1.4 { 667 execsql { 668 SELECT * FROM sqlite_master; 669 } 670 } "table abc abc [expr $AUTOVACUUM?3:2] {CREATE TABLE abc(a, b, c)}" 671 do_test shared-$av.8.1.5 { 672 db2 close 673 execsql { 674 PRAGMA encoding; 675 } 676 } {UTF-8} 677 678 file delete -force test2.db test2.db-journal 679 do_test shared-$av.8.2.1 { 680 execsql { 681 ATTACH 'test2.db' AS aux; 682 SELECT * FROM aux.sqlite_master; 683 } 684 } {} 685 do_test shared-$av.8.2.2 { 686 sqlite3 db2 test2.db 687 execsql { 688 PRAGMA encoding = 'UTF-16'; 689 CREATE TABLE def(d, e, f); 690 } db2 691 string range [execsql {PRAGMA encoding;} db2] 0 end-2 692 } {UTF-16} 693 694 catch {db close} 695 catch {db2 close} 696 file delete -force test.db test2.db 697 698 do_test shared-$av.8.3.2 { 699 sqlite3 db test.db 700 execsql { CREATE TABLE def(d, e, f) } 701 execsql { PRAGMA encoding } 702 } {UTF-8} 703 do_test shared-$av.8.3.3 { 704 set zDb16 "[encoding convertto unicode test.db]\x00\x00" 705 set db16 [sqlite3_open16 $zDb16 {}] 706 707 set stmt [sqlite3_prepare $db16 "SELECT sql FROM sqlite_master" -1 DUMMY] 708 sqlite3_step $stmt 709 set sql [sqlite3_column_text $stmt 0] 710 sqlite3_finalize $stmt 711 set sql 712 } {CREATE TABLE def(d, e, f)} 713 do_test shared-$av.8.3.4 { 714 set stmt [sqlite3_prepare $db16 "PRAGMA encoding" -1 DUMMY] 715 sqlite3_step $stmt 716 set enc [sqlite3_column_text $stmt 0] 717 sqlite3_finalize $stmt 718 set enc 719 } {UTF-8} 720 721 sqlite3_close $db16 722 723 # Bug #2547 is causing this to fail. 724 if 0 { 725 do_test shared-$av.8.2.3 { 726 catchsql { 727 SELECT * FROM aux.sqlite_master; 728 } 729 } {1 {attached databases must use the same text encoding as main database}} 730 } 731 } 732 733 catch {db close} 734 catch {db2 close} 735 file delete -force test.db test2.db 736 737 #--------------------------------------------------------------------------- 738 # The following tests - shared-9.* - test interactions between TEMP triggers 739 # and shared-schemas. 740 # 741 ifcapable trigger&&tempdb { 742 743 do_test shared-$av.9.1 { 744 sqlite3 db test.db 745 sqlite3 db2 test.db 746 execsql { 747 CREATE TABLE abc(a, b, c); 748 CREATE TABLE abc_mirror(a, b, c); 749 CREATE TEMP TRIGGER BEFORE INSERT ON abc BEGIN 750 INSERT INTO abc_mirror(a, b, c) VALUES(new.a, new.b, new.c); 751 END; 752 INSERT INTO abc VALUES(1, 2, 3); 753 SELECT * FROM abc_mirror; 754 } 755 } {1 2 3} 756 do_test shared-$av.9.2 { 757 execsql { 758 INSERT INTO abc VALUES(4, 5, 6); 759 SELECT * FROM abc_mirror; 760 } db2 761 } {1 2 3} 762 do_test shared-$av.9.3 { 763 db close 764 db2 close 765 } {} 766 767 } ; # End shared-9.* 768 769 #--------------------------------------------------------------------------- 770 # The following tests - shared-10.* - test that the library behaves 771 # correctly when a connection to a shared-cache is closed. 772 # 773 do_test shared-$av.10.1 { 774 # Create a small sample database with two connections to it (db and db2). 775 file delete -force test.db 776 sqlite3 db test.db 777 sqlite3 db2 test.db 778 execsql { 779 CREATE TABLE ab(a PRIMARY KEY, b); 780 CREATE TABLE de(d PRIMARY KEY, e); 781 INSERT INTO ab VALUES('Chiang Mai', 100000); 782 INSERT INTO ab VALUES('Bangkok', 8000000); 783 INSERT INTO de VALUES('Ubon', 120000); 784 INSERT INTO de VALUES('Khon Kaen', 200000); 785 } 786 } {} 787 do_test shared-$av.10.2 { 788 # Open a read-transaction with the first connection, a write-transaction 789 # with the second. 790 execsql { 791 BEGIN; 792 SELECT * FROM ab; 793 } 794 execsql { 795 BEGIN; 796 INSERT INTO de VALUES('Pataya', 30000); 797 } db2 798 } {} 799 do_test shared-$av.10.3 { 800 # An external connection should be able to read the database, but not 801 # prepare a write operation. 802 if {$::tcl_platform(platform)=="unix"} { 803 sqlite3 db3 ./test.db 804 } else { 805 sqlite3 db3 TEST.DB 806 } 807 execsql { 808 SELECT * FROM ab; 809 } db3 810 catchsql { 811 BEGIN; 812 INSERT INTO de VALUES('Pataya', 30000); 813 } db3 814 } {1 {database is locked}} 815 do_test shared-$av.10.4 { 816 # Close the connection with the write-transaction open 817 db2 close 818 } {} 819 do_test shared-$av.10.5 { 820 # Test that the db2 transaction has been automatically rolled back. 821 # If it has not the ('Pataya', 30000) entry will still be in the table. 822 execsql { 823 SELECT * FROM de; 824 } 825 } {Ubon 120000 {Khon Kaen} 200000} 826 do_test shared-$av.10.5 { 827 # Closing db2 should have dropped the shared-cache back to a read-lock. 828 # So db3 should be able to prepare a write... 829 catchsql {INSERT INTO de VALUES('Pataya', 30000);} db3 830 } {0 {}} 831 do_test shared-$av.10.6 { 832 # ... but not commit it. 833 catchsql {COMMIT} db3 834 } {1 {database is locked}} 835 do_test shared-$av.10.7 { 836 # Commit the (read-only) db transaction. Check via db3 to make sure the 837 # contents of table "de" are still as they should be. 838 execsql { 839 COMMIT; 840 } 841 execsql { 842 SELECT * FROM de; 843 } db3 844 } {Ubon 120000 {Khon Kaen} 200000 Pataya 30000} 845 do_test shared-$av.10.9 { 846 # Commit the external transaction. 847 catchsql {COMMIT} db3 848 } {0 {}} 849 integrity_check shared-$av.10.10 850 do_test shared-$av.10.11 { 851 db close 852 db3 close 853 } {} 854 855 do_test shared-$av.11.1 { 856 file delete -force test.db 857 sqlite3 db test.db 858 sqlite3 db2 test.db 859 execsql { 860 CREATE TABLE abc(a, b, c); 861 CREATE TABLE abc2(a, b, c); 862 BEGIN; 863 INSERT INTO abc VALUES(1, 2, 3); 864 } 865 } {} 866 do_test shared-$av.11.2 { 867 catchsql {BEGIN;} db2 868 catchsql {SELECT * FROM abc;} db2 869 } {1 {database table is locked: abc}} 870 do_test shared-$av.11.3 { 871 catchsql {BEGIN} db2 872 } {1 {cannot start a transaction within a transaction}} 873 do_test shared-$av.11.4 { 874 catchsql {SELECT * FROM abc2;} db2 875 } {0 {}} 876 do_test shared-$av.11.5 { 877 catchsql {INSERT INTO abc2 VALUES(1, 2, 3);} db2 878 } {1 {database table is locked}} 879 do_test shared-$av.11.6 { 880 catchsql {SELECT * FROM abc2} 881 } {0 {}} 882 do_test shared-$av.11.6 { 883 execsql { 884 ROLLBACK; 885 PRAGMA read_uncommitted = 1; 886 } db2 887 } {} 888 do_test shared-$av.11.7 { 889 execsql { 890 INSERT INTO abc2 VALUES(4, 5, 6); 891 INSERT INTO abc2 VALUES(7, 8, 9); 892 } 893 } {} 894 do_test shared-$av.11.8 { 895 set res [list] 896 db2 eval { 897 SELECT abc.a as I, abc2.a as II FROM abc, abc2; 898 } { 899 execsql { 900 DELETE FROM abc WHERE 1; 901 } 902 lappend res $I $II 903 } 904 set res 905 } {1 4 {} 7} 906 if {[llength [info command sqlite3_shared_cache_report]]==1} { 907 do_test shared-$av.11.9 { 908 string tolower [sqlite3_shared_cache_report] 909 } [string tolower [list [file nativename [file normalize test.db]] 2]] 910 } 911 912 do_test shared-$av.11.11 { 913 db close 914 db2 close 915 } {} 916 917 # This tests that if it is impossible to free any pages, SQLite will 918 # exceed the limit set by PRAGMA cache_size. 919 file delete -force test.db test.db-journal 920 sqlite3 db test.db 921 ifcapable pager_pragmas { 922 do_test shared-$av.12.1 { 923 execsql { 924 PRAGMA cache_size = 10; 925 PRAGMA cache_size; 926 } 927 } {10} 928 } 929 do_test shared-$av.12.2 { 930 set ::db_handles [list] 931 for {set i 1} {$i < 15} {incr i} { 932 lappend ::db_handles db$i 933 sqlite3 db$i test.db 934 execsql "CREATE TABLE db${i}(a, b, c)" db$i 935 execsql "INSERT INTO db${i} VALUES(1, 2, 3)" 936 } 937 } {} 938 proc nested_select {handles} { 939 [lindex $handles 0] eval "SELECT * FROM [lindex $handles 0]" { 940 lappend ::res $a $b $c 941 if {[llength $handles]>1} { 942 nested_select [lrange $handles 1 end] 943 } 944 } 945 } 946 do_test shared-$av.12.3 { 947 set ::res [list] 948 nested_select $::db_handles 949 set ::res 950 } [string range [string repeat "1 2 3 " [llength $::db_handles]] 0 end-1] 951 952 do_test shared-$av.12.X { 953 db close 954 foreach h $::db_handles { 955 $h close 956 } 957 } {} 958 959 # Internally, locks are acquired on shared B-Tree structures in the order 960 # that the structures appear in the virtual memory address space. This 961 # test case attempts to cause the order of the structures in memory 962 # to be different from the order in which they are attached to a given 963 # database handle. This covers an extra line or two. 964 # 965 do_test shared-$av.13.1 { 966 file delete -force test2.db test3.db test4.db test5.db 967 sqlite3 db :memory: 968 execsql { 969 ATTACH 'test2.db' AS aux2; 970 ATTACH 'test3.db' AS aux3; 971 ATTACH 'test4.db' AS aux4; 972 ATTACH 'test5.db' AS aux5; 973 DETACH aux2; 974 DETACH aux3; 975 DETACH aux4; 976 ATTACH 'test2.db' AS aux2; 977 ATTACH 'test3.db' AS aux3; 978 ATTACH 'test4.db' AS aux4; 979 } 980 } {} 981 do_test shared-$av.13.2 { 982 execsql { 983 CREATE TABLE t1(a, b, c); 984 CREATE TABLE aux2.t2(a, b, c); 985 CREATE TABLE aux3.t3(a, b, c); 986 CREATE TABLE aux4.t4(a, b, c); 987 CREATE TABLE aux5.t5(a, b, c); 988 SELECT count(*) FROM 989 aux2.sqlite_master, 990 aux3.sqlite_master, 991 aux4.sqlite_master, 992 aux5.sqlite_master 993 } 994 } {1} 995 do_test shared-$av.13.3 { 996 db close 997 } {} 998 999 # Test that nothing horrible happens if a connection to a shared B-Tree 1000 # structure is closed while some other connection has an open cursor. 1001 # 1002 do_test shared-$av.14.1 { 1003 sqlite3 db test.db 1004 sqlite3 db2 test.db 1005 execsql {SELECT name FROM sqlite_master} 1006 } {db1 db2 db3 db4 db5 db6 db7 db8 db9 db10 db11 db12 db13 db14} 1007 do_test shared-$av.14.2 { 1008 set res [list] 1009 db eval {SELECT name FROM sqlite_master} { 1010 if {$name eq "db7"} { 1011 db2 close 1012 } 1013 lappend res $name 1014 } 1015 set res 1016 } {db1 db2 db3 db4 db5 db6 db7 db8 db9 db10 db11 db12 db13 db14} 1017 do_test shared-$av.14.3 { 1018 db close 1019 } {} 1020 1021 # Populate a database schema using connection [db]. Then drop it using 1022 # [db2]. This is to try to find any points where shared-schema elements 1023 # are allocated using the lookaside buffer of [db]. 1024 # 1025 # Mutexes are enabled for this test as that activates a couple of useful 1026 # assert() statements in the C code. 1027 # 1028 do_test shared-$av-15.1 { 1029 file delete -force test.db 1030 sqlite3 db test.db -fullmutex 1 1031 sqlite3 db2 test.db -fullmutex 1 1032 execsql { 1033 CREATE TABLE t1(a, b, c); 1034 CREATE INDEX i1 ON t1(a, b); 1035 CREATE VIEW v1 AS SELECT * FROM t1; 1036 CREATE VIEW v2 AS SELECT * FROM t1, v1 1037 WHERE t1.c=v1.c GROUP BY t1.a ORDER BY v1.b; 1038 CREATE TRIGGER tr1 AFTER INSERT ON t1 1039 WHEN new.a!=1 1040 BEGIN 1041 DELETE FROM t1 WHERE a=5; 1042 INSERT INTO t1 VALUES(1, 2, 3); 1043 UPDATE t1 SET c=c+1; 1044 END; 1045 1046 INSERT INTO t1 VALUES(5, 6, 7); 1047 INSERT INTO t1 VALUES(8, 9, 10); 1048 INSERT INTO t1 VALUES(11, 12, 13); 1049 ANALYZE; 1050 SELECT * FROM t1; 1051 } 1052 } {1 2 6 8 9 12 1 2 5 11 12 14 1 2 4} 1053 do_test shared-$av-15.2 { 1054 execsql { DROP TABLE t1 } db2 1055 } {} 1056 db close 1057 db2 close 1058 1059 } 1060 1061 sqlite3_enable_shared_cache $::enable_shared_cache 1062 finish_test 1063