Index: ext/rtree/rtree.c ================================================================== --- ext/rtree/rtree.c +++ ext/rtree/rtree.c @@ -1996,12 +1996,16 @@ rc = AssignCells(pRtree, aCell, nCell, pLeft, pRight, &leftbbox, &rightbbox); if( rc!=SQLITE_OK ){ goto splitnode_out; } - /* Ensure both child nodes have node numbers assigned to them. */ - if( (0==pRight->iNode && SQLITE_OK!=(rc = nodeWrite(pRtree, pRight))) + /* Ensure both child nodes have node numbers assigned to them by calling + ** nodeWrite(). Node pRight always needs a node number, as it was created + ** by nodeNew() above. But node pLeft sometimes already has a node number. + ** In this case avoid the all to nodeWrite(). + */ + if( SQLITE_OK!=(rc = nodeWrite(pRtree, pRight)) || (0==pLeft->iNode && SQLITE_OK!=(rc = nodeWrite(pRtree, pLeft))) ){ goto splitnode_out; } @@ -2062,18 +2066,23 @@ } static int fixLeafParent(Rtree *pRtree, RtreeNode *pLeaf){ int rc = SQLITE_OK; if( pLeaf->iNode!=1 && pLeaf->pParent==0 ){ + int rc2; /* sqlite3_reset() return code */ sqlite3_bind_int64(pRtree->pReadParent, 1, pLeaf->iNode); - if( sqlite3_step(pRtree->pReadParent)==SQLITE_ROW ){ + rc = sqlite3_step(pRtree->pReadParent); + if( rc==SQLITE_ROW ){ i64 iNode = sqlite3_column_int64(pRtree->pReadParent, 0); rc = nodeAcquire(pRtree, iNode, 0, &pLeaf->pParent); - }else{ - rc = SQLITE_ERROR; + }else if( rc==SQLITE_DONE ){ + rc = SQLITE_CORRUPT; } - sqlite3_reset(pRtree->pReadParent); + rc2 = sqlite3_reset(pRtree->pReadParent); + if( rc==SQLITE_OK ){ + rc = rc2; + } if( rc==SQLITE_OK ){ rc = fixLeafParent(pRtree, pLeaf->pParent); } } return rc; @@ -2879,16 +2888,14 @@ ** Register the r-tree module with database handle db. This creates the ** virtual table module "rtree" and the debugging/analysis scalar ** function "rtreenode". */ int sqlite3RtreeInit(sqlite3 *db){ - int rc = SQLITE_OK; + const int utf8 = SQLITE_UTF8; + int rc; - if( rc==SQLITE_OK ){ - int utf8 = SQLITE_UTF8; - rc = sqlite3_create_function(db, "rtreenode", 2, utf8, 0, rtreenode, 0, 0); - } + rc = sqlite3_create_function(db, "rtreenode", 2, utf8, 0, rtreenode, 0, 0); if( rc==SQLITE_OK ){ int utf8 = SQLITE_UTF8; rc = sqlite3_create_function(db, "rtreedepth", 1, utf8, 0,rtreedepth, 0, 0); } if( rc==SQLITE_OK ){ Index: ext/rtree/rtree3.test ================================================================== --- ext/rtree/rtree3.test +++ ext/rtree/rtree3.test @@ -31,12 +31,10 @@ 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 } -body { execsql { BEGIN TRANSACTION; @@ -94,12 +92,10 @@ db eval { DELETE FROM rt WHERE x1<($f*10.0) AND x1>($f*10.5) } } db eval COMMIT } -} - do_test rtree3-4.prep { faultsim_delete_and_reopen execsql { BEGIN; PRAGMA page_size = 512; @@ -110,14 +106,21 @@ } execsql { COMMIT } faultsim_save_and_close } {} -do_faultsim_test rtree3-4 -faults oom-transient -prep { +do_faultsim_test rtree3-4a -faults oom-transient -prep { faultsim_restore_and_reopen } -body { db eval { SELECT count(*) FROM rt } } -test { faultsim_test_result {0 1500} +} +do_faultsim_test rtree3-4b -faults oom-transient -prep { + faultsim_restore_and_reopen +} -body { + db eval { DELETE FROM rt WHERE ii BETWEEN 880 AND 920 } +} -test { + faultsim_test_result {0 {}} } finish_test Index: ext/rtree/rtree8.test ================================================================== --- ext/rtree/rtree8.test +++ ext/rtree/rtree8.test @@ -102,25 +102,36 @@ do_catchsql_test rtree8-2.1.5 { DELETE FROM t1 } {1 {database disk image is malformed}} do_execsql_test rtree8-2.1.6 { - DELETE FROM t1_node; - DELETE FROM t1_parent; - DELETE FROM t1_rowid; + DROP TABLE t1; + CREATE VIRTUAL TABLE t1 USING rtree_i32(id, x1, x2); +} {} + + +populate_t1 50 +do_execsql_test rtree8-2.2.1 { + DELETE FROM t1_parent +} {} +do_catchsql_test rtree8-2.2.2 { + DELETE FROM t1 WHERE id=25 +} {1 {database disk image is malformed}} +do_execsql_test rtree8-2.2.3 { DROP TABLE t1; CREATE VIRTUAL TABLE t1 USING rtree_i32(id, x1, x2); } {} + #------------------------------------------------------------------------- # Test that trying to use the MATCH operator with the r-tree module does # not confuse it. # breakpoint populate_t1 10 do_catchsql_test rtree8-3.1 { SELECT * FROM t1 WHERE x1 MATCH '1234' -} {1 {}} +} {1 {unable to use function MATCH in the requested context}} finish_test