aboutsummaryrefslogtreecommitdiff
path: root/src/btree.c
diff options
context:
space:
mode:
authordrh <>2021-03-18 16:47:24 +0000
committerdrh <>2021-03-18 16:47:24 +0000
commit8d81aac13ffb7fa9991eefbb36d8fc31ecdb98a5 (patch)
tree4e8af92966061459d59e9e5f10c0c481f79d0d6a /src/btree.c
parent8df014979e9c0a113bc38145d84ca986b2e30934 (diff)
parent76f7b16f1ee50a7677989ad93e1652bd31c131b7 (diff)
downloadsqlite-8d81aac13ffb7fa9991eefbb36d8fc31ecdb98a5.tar.gz
sqlite-8d81aac13ffb7fa9991eefbb36d8fc31ecdb98a5.zip
Fix the OP_OpenDup opcode so that it is able to duplicate a cursor that
was itself opened by OP_OpenDup. Add additional verification of ephemeral tables. Fix for ticket [bb8a9fd4a9b7fce5]. FossilOrigin-Name: bcbe5308f3a3b94f965b0f5627cb29cce2e09343b86d757e2de889f7773576e7
Diffstat (limited to 'src/btree.c')
-rw-r--r--src/btree.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/src/btree.c b/src/btree.c
index 500421ac0..1623e0172 100644
--- a/src/btree.c
+++ b/src/btree.c
@@ -2737,19 +2737,23 @@ static void freeTempSpace(BtShared *pBt){
*/
int sqlite3BtreeClose(Btree *p){
BtShared *pBt = p->pBt;
- BtCursor *pCur;
/* Close all cursors opened via this handle. */
assert( sqlite3_mutex_held(p->db->mutex) );
sqlite3BtreeEnter(p);
- pCur = pBt->pCursor;
- while( pCur ){
- BtCursor *pTmp = pCur;
- pCur = pCur->pNext;
- if( pTmp->pBtree==p ){
- sqlite3BtreeCloseCursor(pTmp);
+
+ /* Verify that no other cursors have this Btree open */
+#ifdef SQLITE_DEBUG
+ {
+ BtCursor *pCur = pBt->pCursor;
+ while( pCur ){
+ BtCursor *pTmp = pCur;
+ pCur = pCur->pNext;
+ assert( pTmp->pBtree!=p );
+
}
}
+#endif
/* Rollback any active transaction and free the handle structure.
** The call to sqlite3BtreeRollback() drops any table-locks held by
@@ -4541,7 +4545,14 @@ int sqlite3BtreeCloseCursor(BtCursor *pCur){
unlockBtreeIfUnused(pBt);
sqlite3_free(pCur->aOverflow);
sqlite3_free(pCur->pKey);
- sqlite3BtreeLeave(pBtree);
+ if( (pBt->openFlags & BTREE_SINGLE) && pBt->pCursor==0 ){
+ /* Since the BtShared is not sharable, there is no need to
+ ** worry about the missing sqlite3BtreeLeave() call here. */
+ assert( pBtree->sharable==0 );
+ sqlite3BtreeClose(pBtree);
+ }else{
+ sqlite3BtreeLeave(pBtree);
+ }
pCur->pBtree = 0;
}
return SQLITE_OK;