1*1da57d55SToomas Soome# 27c478bd9Sstevel@tonic-gate# 2001 September 15 37c478bd9Sstevel@tonic-gate# 47c478bd9Sstevel@tonic-gate# The author disclaims copyright to this source code. In place of 57c478bd9Sstevel@tonic-gate# a legal notice, here is a blessing: 67c478bd9Sstevel@tonic-gate# 77c478bd9Sstevel@tonic-gate# May you do good and not evil. 87c478bd9Sstevel@tonic-gate# May you find forgiveness for yourself and forgive others. 97c478bd9Sstevel@tonic-gate# May you share freely, never taking more than you give. 107c478bd9Sstevel@tonic-gate# 117c478bd9Sstevel@tonic-gate#*********************************************************************** 127c478bd9Sstevel@tonic-gate# This file implements regression tests for SQLite library. The 137c478bd9Sstevel@tonic-gate# focus of this script is database locks. 147c478bd9Sstevel@tonic-gate# 157c478bd9Sstevel@tonic-gate# $Id: lock.test,v 1.20 2004/02/14 16:31:04 drh Exp $ 167c478bd9Sstevel@tonic-gate 177c478bd9Sstevel@tonic-gate 187c478bd9Sstevel@tonic-gateset testdir [file dirname $argv0] 197c478bd9Sstevel@tonic-gatesource $testdir/tester.tcl 207c478bd9Sstevel@tonic-gate 217c478bd9Sstevel@tonic-gate# Create an alternative connection to the database 227c478bd9Sstevel@tonic-gate# 237c478bd9Sstevel@tonic-gatedo_test lock-1.0 { 247c478bd9Sstevel@tonic-gate sqlite db2 ./test.db 257c478bd9Sstevel@tonic-gate set dummy {} 267c478bd9Sstevel@tonic-gate} {} 277c478bd9Sstevel@tonic-gatedo_test lock-1.1 { 287c478bd9Sstevel@tonic-gate execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name} 297c478bd9Sstevel@tonic-gate} {} 307c478bd9Sstevel@tonic-gatedo_test lock-1.2 { 317c478bd9Sstevel@tonic-gate execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name} db2 327c478bd9Sstevel@tonic-gate} {} 337c478bd9Sstevel@tonic-gatedo_test lock-1.3 { 347c478bd9Sstevel@tonic-gate execsql {CREATE TABLE t1(a int, b int)} 357c478bd9Sstevel@tonic-gate execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name} 367c478bd9Sstevel@tonic-gate} {t1} 377c478bd9Sstevel@tonic-gate#do_test lock-1.4 { 387c478bd9Sstevel@tonic-gate# catchsql { 397c478bd9Sstevel@tonic-gate# SELECT name FROM sqlite_master WHERE type='table' ORDER BY name 407c478bd9Sstevel@tonic-gate# } db2 417c478bd9Sstevel@tonic-gate#} {1 {database schema has changed}} 427c478bd9Sstevel@tonic-gatedo_test lock-1.5 { 437c478bd9Sstevel@tonic-gate catchsql { 447c478bd9Sstevel@tonic-gate SELECT name FROM sqlite_master WHERE type='table' ORDER BY name 457c478bd9Sstevel@tonic-gate } db2 467c478bd9Sstevel@tonic-gate} {0 t1} 477c478bd9Sstevel@tonic-gate 487c478bd9Sstevel@tonic-gatedo_test lock-1.6 { 497c478bd9Sstevel@tonic-gate execsql {INSERT INTO t1 VALUES(1,2)} 507c478bd9Sstevel@tonic-gate execsql {SELECT * FROM t1} 517c478bd9Sstevel@tonic-gate} {1 2} 527c478bd9Sstevel@tonic-gatedo_test lock-1.7 { 537c478bd9Sstevel@tonic-gate execsql {SELECT * FROM t1} db2 547c478bd9Sstevel@tonic-gate} {1 2} 557c478bd9Sstevel@tonic-gatedo_test lock-1.8 { 567c478bd9Sstevel@tonic-gate execsql {UPDATE t1 SET a=b, b=a} db2 577c478bd9Sstevel@tonic-gate execsql {SELECT * FROM t1} db2 587c478bd9Sstevel@tonic-gate} {2 1} 597c478bd9Sstevel@tonic-gatedo_test lock-1.9 { 607c478bd9Sstevel@tonic-gate execsql {SELECT * FROM t1} 617c478bd9Sstevel@tonic-gate} {2 1} 627c478bd9Sstevel@tonic-gatedo_test lock-1.10 { 637c478bd9Sstevel@tonic-gate execsql {BEGIN TRANSACTION} 647c478bd9Sstevel@tonic-gate execsql {SELECT * FROM t1} 657c478bd9Sstevel@tonic-gate} {2 1} 667c478bd9Sstevel@tonic-gatedo_test lock-1.11 { 677c478bd9Sstevel@tonic-gate catchsql {SELECT * FROM t1} db2 687c478bd9Sstevel@tonic-gate} {1 {database is locked}} 697c478bd9Sstevel@tonic-gatedo_test lock-1.12 { 707c478bd9Sstevel@tonic-gate execsql {ROLLBACK} 717c478bd9Sstevel@tonic-gate catchsql {SELECT * FROM t1} 727c478bd9Sstevel@tonic-gate} {0 {2 1}} 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gatedo_test lock-1.13 { 757c478bd9Sstevel@tonic-gate execsql {CREATE TABLE t2(x int, y int)} 767c478bd9Sstevel@tonic-gate execsql {INSERT INTO t2 VALUES(8,9)} 777c478bd9Sstevel@tonic-gate execsql {SELECT * FROM t2} 787c478bd9Sstevel@tonic-gate} {8 9} 797c478bd9Sstevel@tonic-gatedo_test lock-1.14.1 { 807c478bd9Sstevel@tonic-gate catchsql {SELECT * FROM t2} db2 817c478bd9Sstevel@tonic-gate} {1 {no such table: t2}} 827c478bd9Sstevel@tonic-gatedo_test lock-1.14.2 { 837c478bd9Sstevel@tonic-gate catchsql {SELECT * FROM t1} db2 847c478bd9Sstevel@tonic-gate} {0 {2 1}} 857c478bd9Sstevel@tonic-gatedo_test lock-1.15 { 867c478bd9Sstevel@tonic-gate catchsql {SELECT * FROM t2} db2 877c478bd9Sstevel@tonic-gate} {0 {8 9}} 887c478bd9Sstevel@tonic-gate 897c478bd9Sstevel@tonic-gatedo_test lock-1.16 { 907c478bd9Sstevel@tonic-gate db eval {SELECT * FROM t1} qv { 917c478bd9Sstevel@tonic-gate set x [db eval {SELECT * FROM t1}] 927c478bd9Sstevel@tonic-gate } 937c478bd9Sstevel@tonic-gate set x 947c478bd9Sstevel@tonic-gate} {2 1} 957c478bd9Sstevel@tonic-gatedo_test lock-1.17 { 967c478bd9Sstevel@tonic-gate db eval {SELECT * FROM t1} qv { 977c478bd9Sstevel@tonic-gate set x [db eval {SELECT * FROM t2}] 987c478bd9Sstevel@tonic-gate } 997c478bd9Sstevel@tonic-gate set x 1007c478bd9Sstevel@tonic-gate} {8 9} 1017c478bd9Sstevel@tonic-gate 1027c478bd9Sstevel@tonic-gate# You cannot UPDATE a table from within the callback of a SELECT 1037c478bd9Sstevel@tonic-gate# on that same table because the SELECT has the table locked. 1047c478bd9Sstevel@tonic-gate# 1057c478bd9Sstevel@tonic-gatedo_test lock-1.18 { 1067c478bd9Sstevel@tonic-gate db eval {SELECT * FROM t1} qv { 1077c478bd9Sstevel@tonic-gate set r [catch {db eval {UPDATE t1 SET a=b, b=a}} msg] 1087c478bd9Sstevel@tonic-gate lappend r $msg 1097c478bd9Sstevel@tonic-gate } 1107c478bd9Sstevel@tonic-gate set r 1117c478bd9Sstevel@tonic-gate} {1 {database table is locked}} 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate# But you can UPDATE a different table from the one that is used in 1147c478bd9Sstevel@tonic-gate# the SELECT. 1157c478bd9Sstevel@tonic-gate# 1167c478bd9Sstevel@tonic-gatedo_test lock-1.19 { 1177c478bd9Sstevel@tonic-gate db eval {SELECT * FROM t1} qv { 1187c478bd9Sstevel@tonic-gate set r [catch {db eval {UPDATE t2 SET x=y, y=x}} msg] 1197c478bd9Sstevel@tonic-gate lappend r $msg 1207c478bd9Sstevel@tonic-gate } 1217c478bd9Sstevel@tonic-gate set r 1227c478bd9Sstevel@tonic-gate} {0 {}} 1237c478bd9Sstevel@tonic-gatedo_test lock-1.20 { 1247c478bd9Sstevel@tonic-gate execsql {SELECT * FROM t2} 1257c478bd9Sstevel@tonic-gate} {9 8} 1267c478bd9Sstevel@tonic-gate 1277c478bd9Sstevel@tonic-gate# It is possible to do a SELECT of the same table within the 1287c478bd9Sstevel@tonic-gate# callback of another SELECT on that same table because two 1297c478bd9Sstevel@tonic-gate# or more read-only cursors can be open at once. 1307c478bd9Sstevel@tonic-gate# 1317c478bd9Sstevel@tonic-gatedo_test lock-1.21 { 1327c478bd9Sstevel@tonic-gate db eval {SELECT * FROM t1} qv { 1337c478bd9Sstevel@tonic-gate set r [catch {db eval {SELECT a FROM t1}} msg] 1347c478bd9Sstevel@tonic-gate lappend r $msg 1357c478bd9Sstevel@tonic-gate } 1367c478bd9Sstevel@tonic-gate set r 1377c478bd9Sstevel@tonic-gate} {0 2} 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate# Under UNIX you can do two SELECTs at once with different database 1407c478bd9Sstevel@tonic-gate# connections, because UNIX supports reader/writer locks. Under windows, 1417c478bd9Sstevel@tonic-gate# this is not possible. 1427c478bd9Sstevel@tonic-gate# 1437c478bd9Sstevel@tonic-gateif {$::tcl_platform(platform)=="unix"} { 1447c478bd9Sstevel@tonic-gate do_test lock-1.22 { 1457c478bd9Sstevel@tonic-gate db eval {SELECT * FROM t1} qv { 1467c478bd9Sstevel@tonic-gate set r [catch {db2 eval {SELECT a FROM t1}} msg] 1477c478bd9Sstevel@tonic-gate lappend r $msg 1487c478bd9Sstevel@tonic-gate } 1497c478bd9Sstevel@tonic-gate set r 1507c478bd9Sstevel@tonic-gate } {0 2} 1517c478bd9Sstevel@tonic-gate} 1527c478bd9Sstevel@tonic-gateintegrity_check lock-1.23 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate# If one thread has a transaction another thread cannot start 1557c478bd9Sstevel@tonic-gate# a transaction. 1567c478bd9Sstevel@tonic-gate# 1577c478bd9Sstevel@tonic-gatedo_test lock-2.1 { 1587c478bd9Sstevel@tonic-gate execsql {BEGIN TRANSACTION} 1597c478bd9Sstevel@tonic-gate set r [catch {execsql {BEGIN TRANSACTION} db2} msg] 1607c478bd9Sstevel@tonic-gate lappend r $msg 1617c478bd9Sstevel@tonic-gate} {1 {database is locked}} 1627c478bd9Sstevel@tonic-gate 1637c478bd9Sstevel@tonic-gate# Nor can the other thread do a query. 1647c478bd9Sstevel@tonic-gate# 1657c478bd9Sstevel@tonic-gatedo_test lock-2.2 { 1667c478bd9Sstevel@tonic-gate set r [catch {execsql {SELECT * FROM t2} db2} msg] 1677c478bd9Sstevel@tonic-gate lappend r $msg 1687c478bd9Sstevel@tonic-gate} {1 {database is locked}} 1697c478bd9Sstevel@tonic-gate 1707c478bd9Sstevel@tonic-gate# If the other thread (the one that does not hold the transaction) 1717c478bd9Sstevel@tonic-gate# tries to start a transaction, we get a busy callback. 1727c478bd9Sstevel@tonic-gate# 1737c478bd9Sstevel@tonic-gatedo_test lock-2.3 { 1747c478bd9Sstevel@tonic-gate proc callback {args} { 1757c478bd9Sstevel@tonic-gate set ::callback_value $args 1767c478bd9Sstevel@tonic-gate break 1777c478bd9Sstevel@tonic-gate } 1787c478bd9Sstevel@tonic-gate set ::callback_value {} 1797c478bd9Sstevel@tonic-gate db2 busy callback 1807c478bd9Sstevel@tonic-gate set r [catch {execsql {BEGIN TRANSACTION} db2} msg] 1817c478bd9Sstevel@tonic-gate lappend r $msg 1827c478bd9Sstevel@tonic-gate lappend r $::callback_value 1837c478bd9Sstevel@tonic-gate} {1 {database is locked} {{} 1}} 1847c478bd9Sstevel@tonic-gatedo_test lock-2.4 { 1857c478bd9Sstevel@tonic-gate proc callback {file count} { 1867c478bd9Sstevel@tonic-gate lappend ::callback_value $count 1877c478bd9Sstevel@tonic-gate if {$count>4} break 1887c478bd9Sstevel@tonic-gate } 1897c478bd9Sstevel@tonic-gate set ::callback_value {} 1907c478bd9Sstevel@tonic-gate db2 busy callback 1917c478bd9Sstevel@tonic-gate set r [catch {execsql {BEGIN TRANSACTION} db2} msg] 1927c478bd9Sstevel@tonic-gate lappend r $msg 1937c478bd9Sstevel@tonic-gate lappend r $::callback_value 1947c478bd9Sstevel@tonic-gate} {1 {database is locked} {1 2 3 4 5}} 1957c478bd9Sstevel@tonic-gatedo_test lock-2.5 { 1967c478bd9Sstevel@tonic-gate proc callback {file count} { 1977c478bd9Sstevel@tonic-gate lappend ::callback_value $count 1987c478bd9Sstevel@tonic-gate if {$count>4} break 1997c478bd9Sstevel@tonic-gate } 2007c478bd9Sstevel@tonic-gate set ::callback_value {} 2017c478bd9Sstevel@tonic-gate db2 busy callback 2027c478bd9Sstevel@tonic-gate set r [catch {execsql {SELECT * FROM t1} db2} msg] 2037c478bd9Sstevel@tonic-gate lappend r $msg 2047c478bd9Sstevel@tonic-gate lappend r $::callback_value 2057c478bd9Sstevel@tonic-gate} {1 {database is locked} {1 2 3 4 5}} 2067c478bd9Sstevel@tonic-gate 2077c478bd9Sstevel@tonic-gate# In this test, the 3rd invocation of the busy callback causes 2087c478bd9Sstevel@tonic-gate# the first thread to release its transaction. That allows the 2097c478bd9Sstevel@tonic-gate# second thread to continue. 2107c478bd9Sstevel@tonic-gate# 2117c478bd9Sstevel@tonic-gatedo_test lock-2.6 { 2127c478bd9Sstevel@tonic-gate proc callback {file count} { 2137c478bd9Sstevel@tonic-gate lappend ::callback_value $count 2147c478bd9Sstevel@tonic-gate if {$count>2} { 2157c478bd9Sstevel@tonic-gate execsql {ROLLBACK} 2167c478bd9Sstevel@tonic-gate } 2177c478bd9Sstevel@tonic-gate } 2187c478bd9Sstevel@tonic-gate set ::callback_value {} 2197c478bd9Sstevel@tonic-gate db2 busy callback 2207c478bd9Sstevel@tonic-gate set r [catch {execsql {SELECT * FROM t2} db2} msg] 2217c478bd9Sstevel@tonic-gate lappend r $msg 2227c478bd9Sstevel@tonic-gate lappend r $::callback_value 2237c478bd9Sstevel@tonic-gate} {0 {9 8} {1 2 3}} 2247c478bd9Sstevel@tonic-gatedo_test lock-2.7 { 2257c478bd9Sstevel@tonic-gate execsql {BEGIN TRANSACTION} 2267c478bd9Sstevel@tonic-gate proc callback {file count} { 2277c478bd9Sstevel@tonic-gate lappend ::callback_value $count 2287c478bd9Sstevel@tonic-gate if {$count>2} { 2297c478bd9Sstevel@tonic-gate execsql {ROLLBACK} 2307c478bd9Sstevel@tonic-gate } 2317c478bd9Sstevel@tonic-gate } 2327c478bd9Sstevel@tonic-gate set ::callback_value {} 2337c478bd9Sstevel@tonic-gate db2 busy callback 2347c478bd9Sstevel@tonic-gate set r [catch {execsql {BEGIN TRANSACTION} db2} msg] 2357c478bd9Sstevel@tonic-gate execsql {ROLLBACK} db2 2367c478bd9Sstevel@tonic-gate lappend r $msg 2377c478bd9Sstevel@tonic-gate lappend r $::callback_value 2387c478bd9Sstevel@tonic-gate} {0 {} {1 2 3}} 2397c478bd9Sstevel@tonic-gate 2407c478bd9Sstevel@tonic-gate# Test the built-in busy timeout handler 2417c478bd9Sstevel@tonic-gate# 2427c478bd9Sstevel@tonic-gatedo_test lock-2.8 { 2437c478bd9Sstevel@tonic-gate db2 timeout 400 2447c478bd9Sstevel@tonic-gate execsql BEGIN 2457c478bd9Sstevel@tonic-gate catchsql BEGIN db2 2467c478bd9Sstevel@tonic-gate} {1 {database is locked}} 2477c478bd9Sstevel@tonic-gatedo_test lock-2.9 { 2487c478bd9Sstevel@tonic-gate db2 timeout 0 2497c478bd9Sstevel@tonic-gate execsql COMMIT 2507c478bd9Sstevel@tonic-gate} {} 2517c478bd9Sstevel@tonic-gateintegrity_check lock-2.10 2527c478bd9Sstevel@tonic-gate 2537c478bd9Sstevel@tonic-gate# Try to start two transactions in a row 2547c478bd9Sstevel@tonic-gate# 2557c478bd9Sstevel@tonic-gatedo_test lock-3.1 { 2567c478bd9Sstevel@tonic-gate execsql {BEGIN TRANSACTION} 2577c478bd9Sstevel@tonic-gate set r [catch {execsql {BEGIN TRANSACTION}} msg] 2587c478bd9Sstevel@tonic-gate execsql {ROLLBACK} 2597c478bd9Sstevel@tonic-gate lappend r $msg 2607c478bd9Sstevel@tonic-gate} {1 {cannot start a transaction within a transaction}} 2617c478bd9Sstevel@tonic-gateintegrity_check lock-3.2 2627c478bd9Sstevel@tonic-gate 2637c478bd9Sstevel@tonic-gate# Make sure the busy handler and error messages work when 2647c478bd9Sstevel@tonic-gate# opening a new pointer to the database while another pointer 2657c478bd9Sstevel@tonic-gate# has the database locked. 2667c478bd9Sstevel@tonic-gate# 2677c478bd9Sstevel@tonic-gatedo_test lock-4.1 { 2687c478bd9Sstevel@tonic-gate db2 close 2697c478bd9Sstevel@tonic-gate catch {db eval ROLLBACK} 2707c478bd9Sstevel@tonic-gate db eval BEGIN 2717c478bd9Sstevel@tonic-gate sqlite db2 ./test.db 2727c478bd9Sstevel@tonic-gate set rc [catch {db2 eval {SELECT * FROM t1}} msg] 2737c478bd9Sstevel@tonic-gate lappend rc $msg 2747c478bd9Sstevel@tonic-gate} {1 {database is locked}} 2757c478bd9Sstevel@tonic-gatedo_test lock-4.2 { 2767c478bd9Sstevel@tonic-gate set ::callback_value {} 2777c478bd9Sstevel@tonic-gate set rc [catch {db2 eval {SELECT * FROM t1}} msg] 2787c478bd9Sstevel@tonic-gate lappend rc $msg $::callback_value 2797c478bd9Sstevel@tonic-gate} {1 {database is locked} {}} 2807c478bd9Sstevel@tonic-gatedo_test lock-4.3 { 2817c478bd9Sstevel@tonic-gate proc callback {file count} { 2827c478bd9Sstevel@tonic-gate lappend ::callback_value $count 2837c478bd9Sstevel@tonic-gate if {$count>4} break 2847c478bd9Sstevel@tonic-gate } 2857c478bd9Sstevel@tonic-gate db2 busy callback 2867c478bd9Sstevel@tonic-gate set rc [catch {db2 eval {SELECT * FROM t1}} msg] 2877c478bd9Sstevel@tonic-gate lappend rc $msg $::callback_value 2887c478bd9Sstevel@tonic-gate} {1 {database is locked} {1 2 3 4 5}} 2897c478bd9Sstevel@tonic-gateexecsql {ROLLBACK} 2907c478bd9Sstevel@tonic-gate 2917c478bd9Sstevel@tonic-gate# When one thread is writing, other threads cannot read. Except if the 2927c478bd9Sstevel@tonic-gate# writing thread is writing to its temporary tables, the other threads 2937c478bd9Sstevel@tonic-gate# can still read. 2947c478bd9Sstevel@tonic-gate# 2957c478bd9Sstevel@tonic-gateproc tx_exec {sql} { 2967c478bd9Sstevel@tonic-gate db2 eval $sql 2977c478bd9Sstevel@tonic-gate} 2987c478bd9Sstevel@tonic-gatedo_test lock-5.1 { 2997c478bd9Sstevel@tonic-gate execsql { 3007c478bd9Sstevel@tonic-gate SELECT * FROM t1 3017c478bd9Sstevel@tonic-gate } 3027c478bd9Sstevel@tonic-gate} {2 1} 3037c478bd9Sstevel@tonic-gatedo_test lock-5.2 { 3047c478bd9Sstevel@tonic-gate db function tx_exec tx_exec 3057c478bd9Sstevel@tonic-gate catchsql { 3067c478bd9Sstevel@tonic-gate INSERT INTO t1(a,b) SELECT 3, tx_exec('SELECT y FROM t2 LIMIT 1'); 3077c478bd9Sstevel@tonic-gate } 3087c478bd9Sstevel@tonic-gate} {1 {database is locked}} 3097c478bd9Sstevel@tonic-gatedo_test lock-5.3 { 3107c478bd9Sstevel@tonic-gate execsql { 3117c478bd9Sstevel@tonic-gate CREATE TEMP TABLE t3(x); 3127c478bd9Sstevel@tonic-gate SELECT * FROM t3; 3137c478bd9Sstevel@tonic-gate } 3147c478bd9Sstevel@tonic-gate} {} 3157c478bd9Sstevel@tonic-gatedo_test lock-5.4 { 3167c478bd9Sstevel@tonic-gate catchsql { 3177c478bd9Sstevel@tonic-gate INSERT INTO t3 SELECT tx_exec('SELECT y FROM t2 LIMIT 1'); 3187c478bd9Sstevel@tonic-gate } 3197c478bd9Sstevel@tonic-gate} {0 {}} 3207c478bd9Sstevel@tonic-gatedo_test lock-5.5 { 3217c478bd9Sstevel@tonic-gate execsql { 3227c478bd9Sstevel@tonic-gate SELECT * FROM t3; 3237c478bd9Sstevel@tonic-gate } 3247c478bd9Sstevel@tonic-gate} {8} 3257c478bd9Sstevel@tonic-gatedo_test lock-5.6 { 3267c478bd9Sstevel@tonic-gate catchsql { 3277c478bd9Sstevel@tonic-gate UPDATE t1 SET a=tx_exec('SELECT x FROM t2'); 3287c478bd9Sstevel@tonic-gate } 3297c478bd9Sstevel@tonic-gate} {1 {database is locked}} 3307c478bd9Sstevel@tonic-gatedo_test lock-5.7 { 3317c478bd9Sstevel@tonic-gate execsql { 3327c478bd9Sstevel@tonic-gate SELECT * FROM t1; 3337c478bd9Sstevel@tonic-gate } 3347c478bd9Sstevel@tonic-gate} {2 1} 3357c478bd9Sstevel@tonic-gatedo_test lock-5.8 { 3367c478bd9Sstevel@tonic-gate catchsql { 3377c478bd9Sstevel@tonic-gate UPDATE t3 SET x=tx_exec('SELECT x FROM t2'); 3387c478bd9Sstevel@tonic-gate } 3397c478bd9Sstevel@tonic-gate} {0 {}} 3407c478bd9Sstevel@tonic-gatedo_test lock-5.9 { 3417c478bd9Sstevel@tonic-gate execsql { 3427c478bd9Sstevel@tonic-gate SELECT * FROM t3; 3437c478bd9Sstevel@tonic-gate } 3447c478bd9Sstevel@tonic-gate} {9} 3457c478bd9Sstevel@tonic-gate 3467c478bd9Sstevel@tonic-gatedo_test lock-999.1 { 3477c478bd9Sstevel@tonic-gate rename db2 {} 3487c478bd9Sstevel@tonic-gate} {} 3497c478bd9Sstevel@tonic-gate 3507c478bd9Sstevel@tonic-gatefinish_test 351