mirror of https://github.com/sqlite/sqlite
Back out changes allowing writes to tables that have open cursors. (CVS 2134)
FossilOrigin-Name: af635cab8a1d761c469e35208dda08a29f0964a1
This commit is contained in:
parent
299b187d76
commit
12b13002ce
22
manifest
22
manifest
|
@ -1,5 +1,5 @@
|
|||
C Back\sout\schanges\sallowing\swrites\sto\stables\sthat\shave\sopen\scursors.\s(CVS\s2133)
|
||||
D 2004-11-22T10:02:10
|
||||
C Back\sout\schanges\sallowing\swrites\sto\stables\sthat\shave\sopen\scursors.\s(CVS\s2134)
|
||||
D 2004-11-22T10:02:22
|
||||
F Makefile.in 8291610f5839939a5fbff4dbbf85adb0fe1ac37f
|
||||
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
|
||||
F README a01693e454a00cc117967e3f9fdab2d4d52e9bc1
|
||||
|
@ -101,9 +101,8 @@ F test/btree4.test 3797b4305694c7af6828675b0f4b1424b8ca30e4
|
|||
F test/btree5.test 8e5ff32c02e685d36516c6499add9375fe1377f2
|
||||
F test/btree6.test a5ede6bfbbb2ec8b27e62813612c0f28e8f3e027
|
||||
F test/btree7.test a6d3b842db22af97dd14b989e90a2fd96066b72f
|
||||
F test/btree8.test d4e5932e54ae10f934d92ebaff94b594923d9ebc
|
||||
F test/capi2.test cd5e149564094bda9a587e70ec5949863222cd23
|
||||
F test/capi3.test c53e4eea686dacad8a1239c0d584fe63e6e601dc
|
||||
F test/capi2.test 8279d1d5ca1f9b518d78fefd01fd58958c7240d6
|
||||
F test/capi3.test 3b33bf7c8836028835354c055989314e9c969c5c
|
||||
F test/capi3b.test 5b6a66f9f295f79f443b5d3f33187fa5ef6cf336
|
||||
F test/collate1.test f79736d2ebf5492167ee4d1f4ab4c09dda776b03
|
||||
F test/collate2.test 12fd658d8f5106a8a5c8a77d66919d8c89394036
|
||||
|
@ -117,7 +116,7 @@ F test/crash.test 48b481769dd0ead25b0dfc0150853bfa39a3b65c
|
|||
F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
|
||||
F test/date.test dda578ec1857837156bd8b32f8e09d81d7d7881c
|
||||
F test/delete.test fc29491f6a7ac899ce29f4549a104809e245d9a6
|
||||
F test/delete2.test 04a19e248d88156324ae964676bb4584b65b46f4
|
||||
F test/delete2.test e382b6a97787197eb8b93dd4ccd37797c3725ea3
|
||||
F test/diskfull.test e2f6cfd868713ead06dc82b84a4938e868128fc0
|
||||
F test/enc.test 7a03417a1051fe8bc6c7641cf4c8c3f7e0066d52
|
||||
F test/enc2.test 6d1a2650e9da43eab499d18ca694a0cb6ec69dee
|
||||
|
@ -140,17 +139,16 @@ F test/join4.test 8dec387d06b3a4685e1104048065cf5236b99b93
|
|||
F test/lastinsert.test b6a1db3e1ce2d3f0d6afe99d445084f543b6feaa
|
||||
F test/laststmtchanges.test 07cbdabc52407c29e40abc25050f2434f044a6b1
|
||||
F test/limit.test 4798e0196186e4c9b0f3ce90c1efd196877a1d17
|
||||
F test/lock.test ba72c211499b0874c56643b9ede1df4018bb20de
|
||||
F test/lock.test 32fe28e5030f25f23bcf6beef440675b0d848413
|
||||
F test/lock2.test 59c3dd7d9b24d1bf7ec91b2d1541c37e97939d5f
|
||||
F test/lock3.test 615111293cf32aa2ed16d01c6611737651c96fb9
|
||||
F test/lock4.test 07768b4d4e942693d6036f1e6502199a3fa22a4f
|
||||
F test/main.test 5f9deae11b93336da1ccc5f91cf8be075c91ddf1
|
||||
F test/malloc.test b4674cbb5a72b113eedaaf64fcd5c062e9957ded
|
||||
F test/memdb.test c9ccd02cd9ce9d2cdcd5a712efecf24e7b93b7fa
|
||||
F test/memleak.test f1fa233f8295dd1d955a00d5e5ee857850f27f29
|
||||
F test/minmax.test c0f92d3f7b11656221735385f2c8b1878bbbdaf6
|
||||
F test/misc1.test 744f60d1025fa978708b96cb222a07a1feb1524a
|
||||
F test/misc2.test 851e63fcc849b0c155cb02eb06537ea93b7f24b2
|
||||
F test/misc2.test d3bea4b809efaa4319299e55c50ee987b4f6470c
|
||||
F test/misc3.test 928a2f1e1189924ed14e1ae074e34f40688bdf94
|
||||
F test/misc4.test d005a75f095bb04db09a5d096144405ae566b622
|
||||
F test/misuse.test 2d7c46160f7c214f761fc5d030684a37ae8832a6
|
||||
|
@ -261,7 +259,7 @@ F www/tclsqlite.tcl 560ecd6a916b320e59f2917317398f3d59b7cc25
|
|||
F www/vdbe.tcl 095f106d93875c94b47367384ebc870517431618
|
||||
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
|
||||
F www/whentouse.tcl fdacb0ba2d39831e8a6240d05a490026ad4c4e4c
|
||||
P 711e8d7695dfc74b3f1ee00591dcdda2cd7fc7d5
|
||||
R 435be4c4df18ad02a5220daa06c920af
|
||||
P 91acd87e52509a8f78894d0f4b625b54376cac21
|
||||
R 3f35736f01d9cae236fc378ee100c137
|
||||
U danielk1977
|
||||
Z 690d6154f35eb3573c00acd3211a6213
|
||||
Z 78e9f3a6a9971c738e9a8b2edd14f6b6
|
||||
|
|
|
@ -1 +1 @@
|
|||
91acd87e52509a8f78894d0f4b625b54376cac21
|
||||
af635cab8a1d761c469e35208dda08a29f0964a1
|
413
test/btree8.test
413
test/btree8.test
|
@ -1,413 +0,0 @@
|
|||
# 2004 Jun 4
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this script is btree database backend. Specifically,
|
||||
# this file tests that existing cursors are correctly repositioned
|
||||
# when entries are inserted into or deleted from btrees.
|
||||
#
|
||||
# $Id: btree8.test,v 1.4 2004/11/17 10:22:04 danielk1977 Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
# Test organization:
|
||||
#
|
||||
# btree-8.1.*: Test cursor persistence when inserting records into tables.
|
||||
# btree-8.2.*: Test cursor persistence when deleting records from tables.
|
||||
# btree-8.3.*: Test cursor persistence when inserting records into indices.
|
||||
# btree-8.4.*: Test cursor persistence when deleting records from indices.
|
||||
#
|
||||
|
||||
# Transform the number $num into a string of length $len by repeating the
|
||||
# string representation of the number as many times as necessary. Repeats
|
||||
# are seperated by a '.' character. Eg:
|
||||
#
|
||||
# [num_to_string 456 10] -> "456.456.45"
|
||||
#
|
||||
proc num_to_string {num len} {
|
||||
set num [format %.4d $num]
|
||||
return [string range [string repeat "$num." $len] 0 [expr $len-1]]
|
||||
}
|
||||
|
||||
# Proc lshuffle takes a list as an argument and returns a copy of that
|
||||
# list in randomized order. It uses the K-combinator for speed.
|
||||
#
|
||||
proc K {x y} {set x}
|
||||
proc lshuffle { list } {
|
||||
set n [llength $list]
|
||||
while {$n>0} {
|
||||
set j [expr {int(rand()*$n)}]
|
||||
lappend slist [lindex $list $j]
|
||||
set list [lreplace [K $list [set list {}]] $j $j]
|
||||
incr n -1
|
||||
}
|
||||
return $slist
|
||||
}
|
||||
|
||||
# Proc lremove takes two arguments, a list (the first argument) and a key
|
||||
# (the second argument). A copy of the list is returned with all elements
|
||||
# equal to $key removed.
|
||||
#
|
||||
proc lremove {list key} {
|
||||
while { [set i [lsearch $list $key]] != -1 } {
|
||||
set list [concat \
|
||||
[lrange $list 0 [expr $i-1]] \
|
||||
[lrange $list [expr $i+1] end]
|
||||
]
|
||||
}
|
||||
return $list
|
||||
}
|
||||
|
||||
|
||||
# Use the SQL interface to create a couple of btree tables, one using
|
||||
# the flags for an SQL table, the other an SQL index.
|
||||
#
|
||||
do_test btree8-0.0 {
|
||||
execsql {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
|
||||
CREATE INDEX i1 ON t1(b);
|
||||
}
|
||||
} {}
|
||||
set tnum [execsql {SELECT rootpage FROM sqlite_master where type = 'table'}]
|
||||
set inum [execsql {SELECT rootpage FROM sqlite_master where type = 'index'}]
|
||||
db close
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Tests btree8-1.* insert a handful of records (~10) into the type of
|
||||
# b-tree created for an SQL table. The records have integer keys in the
|
||||
# range 1..5000. A cursor is left pointing to each of these records.
|
||||
# Then, a record is inserted for each key value between 1 and 5000,
|
||||
# including the values for which a record already exists (overwriting
|
||||
# the original). After each record is inserted, the existing cursors
|
||||
# are checked to ensure they still point at the same key-value.
|
||||
#
|
||||
|
||||
# Open the database at the btree level and begin a transaction
|
||||
do_test btree8-1.0 {
|
||||
set ::bt [btree_open test.db 100 0]
|
||||
expr 0
|
||||
} {0}
|
||||
|
||||
do_test btree8-1.1 {
|
||||
btree_begin_transaction $::bt
|
||||
expr 0
|
||||
} {0}
|
||||
|
||||
# For each element in the list $keys, insert an entry into the SQL table
|
||||
# with the corresponding key value. Check that the cursor used to insert
|
||||
# the key is left pointing to it after the insert. Then save this cursor
|
||||
# in the list $csr_list.
|
||||
#
|
||||
set keys [list 3178 4886 719 1690 443 4113 1618 310 1320 2028]
|
||||
set csr_list [list]
|
||||
set testnum 2
|
||||
foreach key $keys {
|
||||
do_test btree-8-1.$testnum {
|
||||
set csr [btree_cursor $::bt $::tnum 1]
|
||||
btree_insert $csr $key [string repeat a 10]
|
||||
lappend csr_list $csr
|
||||
btree_key $csr
|
||||
} $key
|
||||
incr testnum
|
||||
}
|
||||
btree_commit $::bt
|
||||
|
||||
# Now write more entries to the table (and overwriting the ones that exist).
|
||||
# After each write, check that the cursors created above still point to the
|
||||
# same entries.
|
||||
btree_begin_transaction $::bt
|
||||
set ::write_csr [btree_cursor $::bt $::tnum 1]
|
||||
set first_entry $testnum
|
||||
for {set i $testnum} {$i < 5000 && $nErr==0 } {incr i} {
|
||||
set datalen [expr int(rand()*20.0)]
|
||||
|
||||
do_test btree8-1.$i.1 {
|
||||
btree_insert $::write_csr $i [string repeat x $datalen]
|
||||
} {}
|
||||
|
||||
set testnum 1
|
||||
foreach csr $csr_list key $keys {
|
||||
incr testnum
|
||||
do_test btree8-1.$i.$testnum {
|
||||
btree_key $::csr
|
||||
} $key
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Tests btree8-2.* loop through the tree created by tests btree8-1.*,
|
||||
# deleting records in sequential order. After each record is deleted,
|
||||
# each of the open cursors is checked to ensure that it still points
|
||||
# to the same key-value or, if that key value has been deleted, returns
|
||||
# 0 as the integer key value.
|
||||
#
|
||||
|
||||
# Now delete entries from the table.
|
||||
btree_first $::write_csr
|
||||
for {set i $first_entry} {$i < 5000 && $nErr==0 } {incr i} {
|
||||
|
||||
do_test btree8-2.$i.1 {
|
||||
btree_key $::write_csr
|
||||
} $i
|
||||
do_test btree8-2.$i.2 {
|
||||
btree_delete $::write_csr
|
||||
btree_next $::write_csr
|
||||
expr 0
|
||||
} {0}
|
||||
set testnum 2
|
||||
foreach csr $csr_list key $keys {
|
||||
incr testnum
|
||||
if {$key <= $i } {
|
||||
set key 0
|
||||
}
|
||||
do_test btree8-2.$i.$testnum {
|
||||
btree_key $::csr
|
||||
} $key
|
||||
}
|
||||
}
|
||||
|
||||
# Close all existing cursors and conclude the open transaction.
|
||||
btree_close_cursor $::write_csr
|
||||
btree_commit $::bt
|
||||
if {$::nErr>0} { puts $::csr_list ; exit }
|
||||
foreach csr $csr_list {
|
||||
btree_close_cursor $csr
|
||||
}
|
||||
set csr_list [list]
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Tests btree8-3.* are analogous to btree8-1.*, but use the type of btree
|
||||
# created for an SQL index, not an SQL table. Instead of integers, key
|
||||
# values are strings 20 bytes long created by transforming integers
|
||||
# into string using the [num_to_string] proc (see above).
|
||||
#
|
||||
|
||||
foreach key $keys {
|
||||
lappend skeys [num_to_string $key 20]
|
||||
}
|
||||
|
||||
# For each element in the list $skeys, insert an entry into the SQL index
|
||||
# with the corresponding key value. Check that the cursor used to insert
|
||||
# the key is left pointing to it after the insert. Then save this cursor
|
||||
# in the list $csr_list.
|
||||
#
|
||||
btree_begin_transaction $::bt
|
||||
set testnum 0
|
||||
foreach key $skeys {
|
||||
incr testnum
|
||||
do_test btree-8-3.$testnum {
|
||||
set csr [btree_cursor $::bt $::inum 1]
|
||||
btree_insert $csr $key ""
|
||||
lappend csr_list $csr
|
||||
btree_key $csr
|
||||
} $key
|
||||
}
|
||||
btree_commit $::bt
|
||||
|
||||
# Now write more entries to the index (and overwrite the ones that exist).
|
||||
# After each write, check that the cursors created above still point to the
|
||||
# same entries.
|
||||
btree_begin_transaction $::bt
|
||||
set ::write_csr [btree_cursor $::bt $::inum 1]
|
||||
set first_entry $testnum
|
||||
for {set i $testnum} {$i < 5000 && $nErr==0 } {incr i} {
|
||||
set skey [num_to_string $i 20]
|
||||
|
||||
do_test btree-8-3.$i.1 {
|
||||
btree_insert $::write_csr $skey ""
|
||||
} {}
|
||||
|
||||
set testnum 1
|
||||
foreach csr $csr_list key $skeys {
|
||||
incr testnum
|
||||
do_test btree-8-3.$i.$testnum {
|
||||
btree_key $::csr
|
||||
} $key
|
||||
}
|
||||
}
|
||||
btree_commit $::bt
|
||||
btree_begin_transaction $::bt
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Tests btree8-4.* are analogous to btree8-2.*, but use the type of btree
|
||||
# created for an SQL index, not an SQL table. Instead of integers, key
|
||||
# values are strings 20 bytes long created by transforming integers
|
||||
# into string using the [num_to_string] proc (see above). Also, keys
|
||||
# are deleted in random order, calculated by the [lshuffle] proc (see above).
|
||||
#
|
||||
|
||||
# Now delete entries from the index. Do this in a random order, to try to
|
||||
# ensure that internal and external nodes are deleted.
|
||||
for {set i $first_entry} {$i < 5000} {incr i} {
|
||||
lappend delete_order $i
|
||||
}
|
||||
set delete_order [lshuffle $delete_order]
|
||||
|
||||
btree_first $::write_csr
|
||||
foreach i $delete_order {
|
||||
do_test btree8-4.$i.1 {
|
||||
btree_move_to $::write_csr [num_to_string $i 20]
|
||||
btree_key $::write_csr
|
||||
} [num_to_string $i 20]
|
||||
do_test btree8-4.$i.2 {
|
||||
btree_delete $::write_csr
|
||||
} {}
|
||||
set delete_order [lremove $delete_order $i]
|
||||
set testnum 2
|
||||
foreach csr $csr_list key $keys {
|
||||
incr testnum
|
||||
if { [lsearch $delete_order $key]==-1 } {
|
||||
set skey ""
|
||||
} else {
|
||||
set skey [num_to_string $key 20]
|
||||
}
|
||||
do_test btree8-4.$i.$testnum {
|
||||
btree_key $::csr
|
||||
} $skey
|
||||
}
|
||||
}
|
||||
|
||||
btree_close_cursor $::write_csr
|
||||
btree_commit $::bt
|
||||
if {$::nErr>0} { puts $::csr_list }
|
||||
foreach csr $csr_list {
|
||||
btree_close_cursor $csr
|
||||
}
|
||||
set csr_list [list]
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# Tests btree8.5.* also test the types of trees used for SQL indices.
|
||||
# This time, 300 entries of 150 bytes each are inserted into the btree (this
|
||||
# produces a tree of height 3 - root page is the grandparent of the leaves).
|
||||
# A cursor points at each entry. We check that all cursors retain there
|
||||
# validity when:
|
||||
#
|
||||
# * Each entry is deleted (test cases btree-8.5.1.*)
|
||||
# * An entry is inserted just after/before each existing key (test
|
||||
# cases btree-8.5.2.*).
|
||||
#
|
||||
|
||||
# Open a cursor on each entry in the tree in B-tree $bt, root-page $tnum.
|
||||
# Return a list of the cursors.
|
||||
#
|
||||
proc open_cursors {bt tnum} {
|
||||
set c [btree_cursor $bt $tnum 0]
|
||||
set csr_list [list]
|
||||
for {btree_first $c} {![btree_eof $c]} {btree_next $c} {
|
||||
set c2 [btree_cursor $bt $tnum 0]
|
||||
btree_move_to $c2 [btree_key $c]
|
||||
lappend csr_list $c2
|
||||
}
|
||||
btree_close_cursor $c
|
||||
return $csr_list
|
||||
}
|
||||
|
||||
# Close all cursors in the list $csr_list.
|
||||
#
|
||||
proc close_cursors {csr_list} {
|
||||
foreach c $csr_list {
|
||||
btree_close_cursor $c
|
||||
}
|
||||
}
|
||||
|
||||
# Check that the key for each cursor in csr_list matches the corresponding
|
||||
# entry in key_list. If not, raise an exception.
|
||||
#
|
||||
proc check_cursors {key_list csr_list} {
|
||||
foreach k $key_list c $csr_list {
|
||||
if {[string compare $k [btree_key $c]]} {
|
||||
error "Csr key '[btree_key $c]' - should be '$k'"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Set up the table used for the btree-8.5.* tests
|
||||
do_test btree-8.5.0 {
|
||||
btree_begin_transaction $::bt
|
||||
set c [btree_cursor $::bt $::inum 1]
|
||||
for {set i 2} {$i<=600} {incr i 2} {
|
||||
set key [num_to_string $i 150]
|
||||
lappend key_list $key
|
||||
btree_insert $c $key ""
|
||||
}
|
||||
btree_close_cursor $c
|
||||
btree_commit $::bt
|
||||
} {}
|
||||
|
||||
# Test cases btree-8.5.1.* - Check that cursors survive DELETE operations.
|
||||
set testnum 0
|
||||
foreach key [lrange $::key_list 0 0] {
|
||||
incr testnum
|
||||
|
||||
btree_begin_transaction $::bt
|
||||
|
||||
# Open the 300 cursors.
|
||||
do_test btree-8.5.1.$testnum.1 {
|
||||
set ::csr_list [open_cursors $::bt $::inum]
|
||||
llength $::csr_list
|
||||
} {300}
|
||||
|
||||
# Delete an entry.
|
||||
do_test btree-8.5.1.$testnum.2 {
|
||||
set c [btree_cursor $::bt $::inum 1]
|
||||
btree_move_to $c $::key
|
||||
btree_delete $c
|
||||
btree_close_cursor $c
|
||||
} {}
|
||||
|
||||
# Check that all 300 cursors are Ok.
|
||||
do_test btree-8.5.1.$testnum.3 {
|
||||
catch {
|
||||
set e [lsearch $::key_list $::key]
|
||||
check_cursors [lreplace $::key_list $e $e ""] $::csr_list
|
||||
} msg
|
||||
set msg
|
||||
} {}
|
||||
|
||||
close_cursors $::csr_list
|
||||
btree_rollback $::bt
|
||||
}
|
||||
|
||||
# Test cases btree-8.5.2.* - Check that cursors survive INSERT operations.
|
||||
set testnum 0
|
||||
foreach key $::key_list {
|
||||
incr testnum
|
||||
|
||||
btree_begin_transaction $::bt
|
||||
|
||||
# Open the 300 cursors.
|
||||
do_test btree-8.5.2.$testnum.1 {
|
||||
set ::csr_list [open_cursors $::bt $::inum]
|
||||
llength $::csr_list
|
||||
} {300}
|
||||
|
||||
# Insert new entries, one before the key, and one after.
|
||||
do_test btree-8.5.2.$testnum.2 {
|
||||
set c [btree_cursor $::bt $::inum 1]
|
||||
btree_insert $c "$::key$::key" ""
|
||||
btree_insert $c [string range $::key 0 end-1] ""
|
||||
btree_close_cursor $c
|
||||
} {}
|
||||
|
||||
# Check that all 300 cursors are Ok.
|
||||
do_test btree-8.5.2.$testnum.3 {
|
||||
catch {
|
||||
check_cursors $::key_list $::csr_list
|
||||
} msg
|
||||
set msg
|
||||
} {}
|
||||
|
||||
close_cursors $::csr_list
|
||||
btree_rollback $::bt
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this script testing the callback-free C/C++ API.
|
||||
#
|
||||
# $Id: capi2.test,v 1.21 2004/11/16 15:50:21 danielk1977 Exp $
|
||||
# $Id: capi2.test,v 1.22 2004/11/22 10:02:22 danielk1977 Exp $
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
|
@ -451,21 +451,15 @@ do_test capi2-6.12 {
|
|||
[get_column_names $VM1]
|
||||
} {SQLITE_ROW 1 5 {x counter}}
|
||||
|
||||
# The next test used to report that the database was locked.
|
||||
# As of 3.1 this is no longer the case, the UPDATE works
|
||||
# even though there is a SELECT active on the table. Rows
|
||||
# scanned by subsequent calls to sqlite3_step report the
|
||||
# updated values.
|
||||
#
|
||||
do_test capi2-6.13 {
|
||||
catchsql {UPDATE t3 SET x=x+1}
|
||||
} {0 {}}
|
||||
} {1 {database table is locked}}
|
||||
do_test capi2-6.14 {
|
||||
list [sqlite3_step $VM1] \
|
||||
[sqlite3_column_count $VM1] \
|
||||
[get_row_values $VM1] \
|
||||
[get_column_names $VM1]
|
||||
} {SQLITE_ROW 1 7 {x counter}}
|
||||
} {SQLITE_ROW 1 6 {x counter}}
|
||||
do_test capi2-6.15 {
|
||||
execsql {SELECT * FROM t1}
|
||||
} {1 2 3}
|
||||
|
@ -474,7 +468,7 @@ do_test capi2-6.16 {
|
|||
[sqlite3_column_count $VM1] \
|
||||
[get_row_values $VM1] \
|
||||
[get_column_names $VM1]
|
||||
} {SQLITE_ROW 1 8 {x counter}}
|
||||
} {SQLITE_ROW 1 7 {x counter}}
|
||||
do_test capi2-6.17 {
|
||||
catchsql {UPDATE t1 SET b=b+1}
|
||||
} {0 {}}
|
||||
|
@ -483,7 +477,7 @@ do_test capi2-6.18 {
|
|||
[sqlite3_column_count $VM1] \
|
||||
[get_row_values $VM1] \
|
||||
[get_column_names $VM1]
|
||||
} {SQLITE_ROW 1 9 {x counter}}
|
||||
} {SQLITE_ROW 1 8 {x counter}}
|
||||
do_test capi2-6.19 {
|
||||
execsql {SELECT * FROM t1}
|
||||
} {1 3 3}
|
||||
|
@ -492,7 +486,7 @@ do_test capi2-6.20 {
|
|||
[sqlite3_column_count $VM1] \
|
||||
[get_row_values $VM1] \
|
||||
[get_column_names $VM1]
|
||||
} {SQLITE_ROW 1 10 {x counter}}
|
||||
} {SQLITE_ROW 1 9 {x counter}}
|
||||
#do_test capi2-6.21 {
|
||||
# execsql {ROLLBACK; SELECT * FROM t1}
|
||||
#} {1 2 3}
|
||||
|
@ -501,7 +495,7 @@ do_test capi2-6.22 {
|
|||
[sqlite3_column_count $VM1] \
|
||||
[get_row_values $VM1] \
|
||||
[get_column_names $VM1]
|
||||
} {SQLITE_ROW 1 11 {x counter}}
|
||||
} {SQLITE_ROW 1 10 {x counter}}
|
||||
#do_test capi2-6.23 {
|
||||
# execsql {BEGIN TRANSACTION;}
|
||||
#} {}
|
||||
|
@ -510,7 +504,7 @@ do_test capi2-6.24 {
|
|||
[sqlite3_column_count $VM1] \
|
||||
[get_row_values $VM1] \
|
||||
[get_column_names $VM1]
|
||||
} {SQLITE_ROW 1 12 {x counter}}
|
||||
} {SQLITE_ROW 1 11 {x counter}}
|
||||
do_test capi2-6.25 {
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES(2,3,4);
|
||||
|
@ -522,7 +516,7 @@ do_test capi2-6.26 {
|
|||
[sqlite3_column_count $VM1] \
|
||||
[get_row_values $VM1] \
|
||||
[get_column_names $VM1]
|
||||
} {SQLITE_ROW 1 13 {x counter}}
|
||||
} {SQLITE_ROW 1 12 {x counter}}
|
||||
do_test capi2-6.27 {
|
||||
catchsql {
|
||||
INSERT INTO t1 VALUES(2,4,5);
|
||||
|
@ -534,7 +528,7 @@ do_test capi2-6.28 {
|
|||
[sqlite3_column_count $VM1] \
|
||||
[get_row_values $VM1] \
|
||||
[get_column_names $VM1]
|
||||
} {SQLITE_ROW 1 14 {x counter}}
|
||||
} {SQLITE_ROW 1 13 {x counter}}
|
||||
do_test capi2-6.99 {
|
||||
sqlite3_finalize $VM1
|
||||
} {SQLITE_OK}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this script testing the callback-free C/C++ API.
|
||||
#
|
||||
# $Id: capi3.test,v 1.25 2004/11/20 20:18:55 drh Exp $
|
||||
# $Id: capi3.test,v 1.26 2004/11/22 10:02:22 danielk1977 Exp $
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
|
@ -760,15 +760,11 @@ do_test capi3-12.2 {
|
|||
}
|
||||
} {0 {}}
|
||||
|
||||
# The following test used to report "database is locked". As of 3.10
|
||||
# this is no longer the case, the INSERT is legal. The inserted row
|
||||
# will be returned after all others (because the scan is being done
|
||||
# in rowid order).
|
||||
do_test capi3-12.3 {
|
||||
catchsql {
|
||||
INSERT INTO t2 VALUES(4);
|
||||
}
|
||||
} {0 {}}
|
||||
} {1 {database table is locked}}
|
||||
do_test capi3-12.4 {
|
||||
catchsql {
|
||||
BEGIN;
|
||||
|
@ -780,14 +776,11 @@ do_test capi3-12.5 {
|
|||
} {SQLITE_ROW}
|
||||
do_test capi3-12.6 {
|
||||
sqlite3_step $STMT
|
||||
} {SQLITE_ROW}
|
||||
do_test capi3-12.7 {
|
||||
sqlite3_step $STMT
|
||||
} {SQLITE_DONE}
|
||||
do_test capi3-12.8 {
|
||||
do_test capi3-12.7 {
|
||||
sqlite3_finalize $STMT
|
||||
} {SQLITE_OK}
|
||||
do_test capi3-12.9 {
|
||||
do_test capi3-12.8 {
|
||||
execsql {
|
||||
COMMIT;
|
||||
SELECT a FROM t1;
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
# The solution to the problem was to detect that the table is locked
|
||||
# before the index entry is deleted.
|
||||
#
|
||||
# $Id: delete2.test,v 1.3 2004/11/16 15:50:21 danielk1977 Exp $
|
||||
# $Id: delete2.test,v 1.4 2004/11/22 10:02:23 danielk1977 Exp $
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
|
@ -66,26 +66,27 @@ do_test delete2-1.4 {
|
|||
} SQLITE_ROW
|
||||
integrity_check delete2-1.5
|
||||
|
||||
# Try to delete a row from the table. Before version 3.10 the DELETE
|
||||
# would fail because of the SELECT active on the table. In 3.10 the
|
||||
# DELETE is legal.
|
||||
# Try to delete a row from the table. The delete should fail.
|
||||
#
|
||||
do_test delete2-1.6 {
|
||||
catchsql {
|
||||
DELETE FROM q WHERE rowid=1
|
||||
}
|
||||
} {0 {}}
|
||||
} {1 {database table is locked}}
|
||||
integrity_check delete2-1.7
|
||||
do_test delete2-1.8 {
|
||||
execsql {
|
||||
SELECT * FROM q;
|
||||
}
|
||||
} {goodbye id.2 again id.3}
|
||||
} {hello id.1 goodbye id.2 again id.3}
|
||||
|
||||
# Finalize the query, thus clearing the lock on the table. Then
|
||||
# retry the delete. The delete should work this time.
|
||||
#
|
||||
do_test delete2-1.9 {
|
||||
sqlite3_finalize $STMT
|
||||
catchsql {
|
||||
DELETE FROM q WHERE rowid=2
|
||||
DELETE FROM q WHERE rowid=1
|
||||
}
|
||||
} {0 {}}
|
||||
integrity_check delete2-1.10
|
||||
|
@ -93,6 +94,6 @@ do_test delete2-1.11 {
|
|||
execsql {
|
||||
SELECT * FROM q;
|
||||
}
|
||||
} {again id.3}
|
||||
} {goodbye id.2 again id.3}
|
||||
|
||||
finish_test
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this script is database locks.
|
||||
#
|
||||
# $Id: lock.test,v 1.28 2004/11/16 15:50:21 danielk1977 Exp $
|
||||
# $Id: lock.test,v 1.29 2004/11/22 10:02:23 danielk1977 Exp $
|
||||
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
|
@ -98,17 +98,15 @@ do_test lock-1.17 {
|
|||
set x
|
||||
} {8 9}
|
||||
|
||||
# Previously, this test ensured that you cannot UPDATE a table from within the
|
||||
# callback of a SELECT on that same table because the SELECT has the table
|
||||
# locked. But as of 3.10 you can do this, so the test is removed.
|
||||
#
|
||||
#do_test lock-1.18 {
|
||||
# db eval {SELECT * FROM t1} qv {
|
||||
# set r [catch {db eval {UPDATE t1 SET a=b, b=a}} msg]
|
||||
# lappend r $msg
|
||||
# }
|
||||
# set r
|
||||
#} {1 {database table is locked}}
|
||||
# You cannot UPDATE a table from within the callback of a SELECT
|
||||
# on that same table because the SELECT has the table locked.
|
||||
do_test lock-1.18 {
|
||||
db eval {SELECT * FROM t1} qv {
|
||||
set r [catch {db eval {UPDATE t1 SET a=b, b=a}} msg]
|
||||
lappend r $msg
|
||||
}
|
||||
set r
|
||||
} {1 {database table is locked}}
|
||||
|
||||
# But you can UPDATE a different table from the one that is used in
|
||||
# the SELECT.
|
||||
|
|
117
test/lock4.test
117
test/lock4.test
|
@ -1,117 +0,0 @@
|
|||
# 2001 September 15
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
# This file implements regression tests for SQLite library. The focus
|
||||
# of this file is modifications made to tables while SELECT queries are
|
||||
# active on the tables. Using this capability in a program is tricky
|
||||
# because results can be difficult to predict, but can be useful.
|
||||
#
|
||||
# $Id: lock4.test,v 1.1 2004/11/17 16:41:29 danielk1977 Exp $
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
do_test lock4-1.0 {
|
||||
execsql {
|
||||
CREATE TABLE t1(a, b);
|
||||
INSERT INTO t1 VALUES(1, 2);
|
||||
}
|
||||
} {}
|
||||
|
||||
# Check that we can INSERT into a table while doing a SELECT on it.
|
||||
do_test lock4-1.1 {
|
||||
db eval {SELECT * FROM t1} {
|
||||
if {$a<5} {
|
||||
execsql "INSERT INTO t1 VALUES($a+1, ($a+1)*2)"
|
||||
}
|
||||
}
|
||||
} {}
|
||||
do_test lock4-1.2 {
|
||||
execsql {
|
||||
SELECT * FROM t1
|
||||
}
|
||||
} {1 2 2 4 3 6 4 8 5 10}
|
||||
|
||||
# Check that we can UPDATE a table while doing a SELECT on it.
|
||||
do_test lock4-1.3 {
|
||||
db eval {SELECT * FROM t1 WHERE (a%2)=0} {
|
||||
execsql "UPDATE t1 SET b = b/2 WHERE a = $a"
|
||||
}
|
||||
} {}
|
||||
do_test lock4-1.4 {
|
||||
execsql {
|
||||
SELECT * FROM t1
|
||||
}
|
||||
} {1 2 2 2 3 6 4 4 5 10}
|
||||
|
||||
# Check that we can DELETE from a table while doing a SELECT on it.
|
||||
do_test lock4-1.5 {
|
||||
db eval {SELECT * FROM t1 WHERE (a%2)=0} {
|
||||
execsql "DELETE FROM t1 WHERE a = $a"
|
||||
}
|
||||
} {}
|
||||
do_test lock4-1.6 {
|
||||
execsql {
|
||||
SELECT * FROM t1
|
||||
}
|
||||
} {1 2 3 6 5 10}
|
||||
|
||||
# Check what happens when a row is deleted while a cursor is still using
|
||||
# the row (because of a SELECT that does a join).
|
||||
do_test lock4-2.0 {
|
||||
execsql {
|
||||
CREATE TABLE t2(c);
|
||||
INSERT INTO t2 VALUES('one');
|
||||
INSERT INTO t2 VALUES('two');
|
||||
}
|
||||
} {}
|
||||
do_test lock4-2.1 {
|
||||
set res [list]
|
||||
db eval {SELECT a, b, c FROM t1, t2} {
|
||||
lappend res $a $b $c
|
||||
if {0==[string compare $c one]} {
|
||||
execsql "DELETE FROM t1 WHERE a = $a"
|
||||
}
|
||||
}
|
||||
set res
|
||||
} {1 2 one 1 2 two 3 6 one 3 6 two 5 10 one 5 10 two}
|
||||
do_test lock4-2.2 {
|
||||
execsql {
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {}
|
||||
|
||||
# do_test lock4-2.3 {
|
||||
# execsql "
|
||||
# INSERT INTO t1 VALUES('[string repeat 1 750]', '[string repeat 2 750]')
|
||||
# "
|
||||
# } {}
|
||||
# do_test lock4-2.4 {
|
||||
# set res [list]
|
||||
# db eval {SELECT a, b, c FROM t1, t2} {
|
||||
# lappend res $a $b $c
|
||||
# if {0==[string compare $c one]} {
|
||||
# execsql "DELETE FROM t1 WHERE a = '$a'"
|
||||
# }
|
||||
# }
|
||||
# set res
|
||||
# } [list \
|
||||
# [string repeat 1 750] [string repeat 2 750] one \
|
||||
# [string repeat 1 750] [string repeat 2 750] two
|
||||
# ]
|
||||
# do_test lock4-2.5 {
|
||||
# execsql {
|
||||
# SELECT * FROM t1;
|
||||
# }
|
||||
# } {}
|
||||
|
||||
finish_test
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
# This file implements tests for miscellanous features that were
|
||||
# left out of other test files.
|
||||
#
|
||||
# $Id: misc2.test,v 1.15 2004/11/22 08:43:32 danielk1977 Exp $
|
||||
# $Id: misc2.test,v 1.16 2004/11/22 10:02:23 danielk1977 Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
@ -135,6 +135,57 @@ do_test misc2-6.1 {
|
|||
}
|
||||
} {1 2}
|
||||
|
||||
# Make sure we get an error message (not a segfault) on an attempt to
|
||||
# update a table from within the callback of a select on that same
|
||||
# table.
|
||||
#
|
||||
do_test misc2-7.1 {
|
||||
db close
|
||||
file delete -force test.db
|
||||
sqlite3 db test.db
|
||||
execsql {
|
||||
CREATE TABLE t1(x);
|
||||
INSERT INTO t1 VALUES(1);
|
||||
}
|
||||
set rc [catch {
|
||||
db eval {SELECT rowid FROM t1} {} {
|
||||
db eval "DELETE FROM t1 WHERE rowid=$rowid"
|
||||
}
|
||||
} msg]
|
||||
lappend rc $msg
|
||||
} {1 {database table is locked}}
|
||||
do_test misc2-7.2 {
|
||||
set rc [catch {
|
||||
db eval {SELECT rowid FROM t1} {} {
|
||||
db eval "INSERT INTO t1 VALUES(3)"
|
||||
}
|
||||
} msg]
|
||||
lappend rc $msg
|
||||
} {1 {database table is locked}}
|
||||
do_test misc2-7.3 {
|
||||
db close
|
||||
file delete -force test.db
|
||||
sqlite3 db :memory:
|
||||
execsql {
|
||||
CREATE TABLE t1(x);
|
||||
INSERT INTO t1 VALUES(1);
|
||||
}
|
||||
set rc [catch {
|
||||
db eval {SELECT rowid FROM t1} {} {
|
||||
db eval "DELETE FROM t1 WHERE rowid=$rowid"
|
||||
}
|
||||
} msg]
|
||||
lappend rc $msg
|
||||
} {1 {database table is locked}}
|
||||
do_test misc2-7.4 {
|
||||
set rc [catch {
|
||||
db eval {SELECT rowid FROM t1} {} {
|
||||
db eval "INSERT INTO t1 VALUES(3)"
|
||||
}
|
||||
} msg]
|
||||
lappend rc $msg
|
||||
} {1 {database table is locked}}
|
||||
|
||||
# Ticket #453. If the SQL ended with "-", the tokenizer was calling that
|
||||
# an incomplete token, which caused problem. The solution was to just call
|
||||
# it a minus sign.
|
||||
|
|
Loading…
Reference in New Issue