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