1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-29 08:01:23 +03:00

Fix a couple of memory leaks in r-tree that can occur following an OOM condition.

FossilOrigin-Name: 1975a27cdec09e1dad4ca8281a87dd7754c02c3e
This commit is contained in:
dan
2010-08-26 14:15:37 +00:00
parent c23454023e
commit 897230eb7a
14 changed files with 89 additions and 82 deletions

View File

@ -2097,6 +2097,7 @@ static int deleteCell(Rtree *, RtreeNode *, int, int);
static int removeNode(Rtree *pRtree, RtreeNode *pNode, int iHeight){
int rc;
int rc2;
RtreeNode *pParent;
int iCell;
@ -2106,9 +2107,12 @@ static int removeNode(Rtree *pRtree, RtreeNode *pNode, int iHeight){
iCell = nodeParentIndex(pRtree, pNode);
pParent = pNode->pParent;
pNode->pParent = 0;
if( SQLITE_OK!=(rc = deleteCell(pRtree, pParent, iCell, iHeight+1))
|| SQLITE_OK!=(rc = nodeRelease(pRtree, pParent))
){
rc = deleteCell(pRtree, pParent, iCell, iHeight+1);
rc2 = nodeRelease(pRtree, pParent);
if( rc==SQLITE_OK ){
rc = rc2;
}
if( rc!=SQLITE_OK ){
return rc;
}
@ -2448,12 +2452,15 @@ static int rtreeUpdate(
** in this scenario).
*/
if( rc==SQLITE_OK && pRtree->iDepth>0 && NCELL(pRoot)==1 ){
int rc2;
RtreeNode *pChild;
i64 iChild = nodeGetRowid(pRtree, pRoot, 0);
rc = nodeAcquire(pRtree, iChild, pRoot, &pChild);
if( rc==SQLITE_OK ){
rc = removeNode(pRtree, pChild, pRtree->iDepth-1);
}
rc2 = nodeRelease(pRtree, pChild);
if( rc==SQLITE_OK ) rc = rc2;
if( rc==SQLITE_OK ){
pRtree->iDepth--;
writeInt16(pRoot->zData, pRtree->iDepth);

View File

@ -13,7 +13,7 @@
#
if {![info exists testdir]} {
set testdir [file join [file dirname $argv0] .. .. test]
set testdir [file join [file dirname [info script]] .. .. test]
}
source [file join [file dirname [info script]] rtree_util.tcl]
source $testdir/tester.tcl

View File

@ -13,7 +13,7 @@
#
if {![info exists testdir]} {
set testdir [file join [file dirname $argv0] .. .. test]
set testdir [file join [file dirname [info script]] .. .. test]
}
source [file join [file dirname [info script]] rtree_util.tcl]
source $testdir/tester.tcl

View File

@ -14,26 +14,39 @@
#
if {![info exists testdir]} {
set testdir [file join [file dirname $argv0] .. .. test]
set testdir [file join [file dirname [info script]] .. .. test]
}
source $testdir/tester.tcl
source $testdir/malloc_common.tcl
ifcapable !rtree {
finish_test
return
}
# Only run these tests if memory debugging is turned on.
# Test summary:
#
# rtree3-1: Test OOM in simple CREATE TABLE, INSERT, DELETE and SELECT
# commands on an almost empty table.
#
# rtree3-2: Test OOM in a DROP TABLE command.
#
# rtree3-3a: Test OOM during a transaction to insert 100 pseudo-random rows.
#
# rtree3-3b: Test OOM during a transaction deleting all entries in the
# database constructed in [rtree3-3a] in pseudo-random order.
#
# rtree3-4a: OOM during "SELECT count(*) FROM ..." on a big table.
#
# rtree3-4b: OOM while deleting rows from a big table.
#
# rtree3-5: Test OOM while inserting rows into a big table.
#
# rtree3-6: Test OOM while deleting all rows of a table, one at a time.
#
# rtree3-7: OOM during an ALTER TABLE RENAME TABLE command.
#
# rtree3-8: Test OOM while registering the r-tree module with sqlite.
#
source $testdir/malloc_common.tcl
if {!$MEMDEBUG} {
puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..."
finish_test
return
}
if 1 {
do_faultsim_test rtree3-1 -faults oom* -prep {
faultsim_delete_and_reopen
@ -96,8 +109,6 @@ do_faultsim_test rtree3-3b -faults oom* -prep {
db eval COMMIT
}
}
do_test rtree3-4.prep {
faultsim_delete_and_reopen
execsql {
@ -120,7 +131,7 @@ do_faultsim_test rtree3-4a -faults oom-* -prep {
faultsim_test_result {0 1500}
}
do_faultsim_test rtree3-4b -faults oom-* -prep {
do_faultsim_test rtree3-4b -faults oom-transient -prep {
faultsim_restore_and_reopen
} -body {
db eval { DELETE FROM rt WHERE ii BETWEEN 1 AND 100 }

View File

@ -13,7 +13,7 @@
#
if {![info exists testdir]} {
set testdir [file join [file dirname $argv0] .. .. test]
set testdir [file join [file dirname [info script]] .. .. test]
}
source $testdir/tester.tcl
@ -93,7 +93,7 @@ for {set nDim 1} {$nDim<=5} {incr nDim} {
for {set i 1} {$i<$::NROW} {incr i} {
# Do a random insert
#
do_test rtree-$nDim.2.$i.1 {
do_test rtree4-$nDim.2.$i.1 {
set vlist {}
for {set j 0} {$j<$nDim} {incr j} {
set mn [rand 10000]
@ -113,7 +113,7 @@ for {set nDim 1} {$nDim<=5} {incr nDim} {
lappend where mn$j>=$mn mx$j<=$mx
}
set where "WHERE [join $where { AND }]"
do_test rtree-$nDim.2.$i.2 {
do_test rtree4-$nDim.2.$i.2 {
list $where [db eval "SELECT id FROM rx $where ORDER BY id"]
} [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]]
@ -126,7 +126,7 @@ for {set nDim 1} {$nDim<=5} {incr nDim} {
lappend where mx$j>=$mn mn$j<=$mx
}
set where "WHERE [join $where { AND }]"
do_test rtree-$nDim.2.$i.3 {
do_test rtree4-$nDim.2.$i.3 {
list $where [db eval "SELECT id FROM rx $where ORDER BY id"]
} [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]]
@ -143,7 +143,7 @@ for {set nDim 1} {$nDim<=5} {incr nDim} {
lappend where mn$j>=$mn mx$j<=$mx
}
set where "WHERE [join $where { AND }]"
do_test rtree-$nDim.2.$i.3 {
do_test rtree4-$nDim.2.$i.3 {
list $where [db eval "SELECT id FROM rx $where ORDER BY id"]
} [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]]
@ -160,7 +160,7 @@ for {set nDim 1} {$nDim<=5} {incr nDim} {
lappend where mx$j>$mn mn$j<$mx
}
set where "WHERE [join $where { AND }]"
do_test rtree-$nDim.2.$i.4 {
do_test rtree4-$nDim.2.$i.4 {
list $where [db eval "SELECT id FROM rx $where ORDER BY id"]
} [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]]
@ -176,7 +176,7 @@ for {set nDim 1} {$nDim<=5} {incr nDim} {
lappend where mn$j>=-10000 mx$j<10000
}
set where "WHERE [join $where { AND }]"
do_test rtree-$nDim.2.$i.5 {
do_test rtree4-$nDim.2.$i.5 {
list $where [db eval "SELECT id FROM rx $where ORDER BY id"]
} [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]]
@ -192,7 +192,7 @@ for {set nDim 1} {$nDim<=5} {incr nDim} {
lappend where mx$j>-10000 mn$j<=10000
}
set where "WHERE [join $where { AND }]"
do_test rtree-$nDim.2.$i.6 {
do_test rtree4-$nDim.2.$i.6 {
list $where [db eval "SELECT id FROM rx $where ORDER BY id"]
} [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]]
@ -208,7 +208,7 @@ for {set nDim 1} {$nDim<=5} {incr nDim} {
lappend where mn$j>=$mn1 mn$j>$mn2 mx$j<$mx1 mx$j<=$mx2
}
set where "WHERE [join [scramble $where] { AND }]"
do_test rtree-$nDim.2.$i.7 {
do_test rtree4-$nDim.2.$i.7 {
list $where [db eval "SELECT id FROM rx $where ORDER BY id"]
} [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]]
@ -224,7 +224,7 @@ for {set nDim 1} {$nDim<=5} {incr nDim} {
lappend where mx$j>=$mn1 mx$j>$mn2 mn$j<$mx1 mn$j<=$mx2
}
set where "WHERE [join [scramble $where] { AND }]"
do_test rtree-$nDim.2.$i.8 {
do_test rtree4-$nDim.2.$i.8 {
list $where [db eval "SELECT id FROM rx $where ORDER BY id"]
} [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]]
}

View File

@ -14,7 +14,7 @@
#
if {![info exists testdir]} {
set testdir [file join [file dirname $argv0] .. .. test]
set testdir [file join [file dirname [info script]] .. .. test]
}
source $testdir/tester.tcl

View File

@ -12,7 +12,7 @@
#
if {![info exists testdir]} {
set testdir [file join [file dirname $argv0] .. .. test]
set testdir [file join [file dirname [info script]] .. .. test]
}
source $testdir/tester.tcl

View File

@ -15,7 +15,7 @@
#
if {![info exists testdir]} {
set testdir [file join [file dirname $argv0] .. .. test]
set testdir [file join [file dirname [info script]] .. .. test]
}
source $testdir/tester.tcl

View File

@ -12,7 +12,7 @@
#
if {![info exists testdir]} {
set testdir [file join [file dirname $argv0] .. .. test]
set testdir [file join [file dirname [info script]] .. .. test]
}
source $testdir/tester.tcl
ifcapable !rtree { finish_test ; return }

View File

@ -13,7 +13,7 @@
#
if {![info exists testdir]} {
set testdir [file join [file dirname $argv0] .. .. test]
set testdir [file join [file dirname [info script]] .. .. test]
}
source [file join [file dirname [info script]] rtree_util.tcl]
source $testdir/tester.tcl