diff options
author | drh <> | 2021-03-18 16:47:24 +0000 |
---|---|---|
committer | drh <> | 2021-03-18 16:47:24 +0000 |
commit | 8d81aac13ffb7fa9991eefbb36d8fc31ecdb98a5 (patch) | |
tree | 4e8af92966061459d59e9e5f10c0c481f79d0d6a /src/btree.c | |
parent | 8df014979e9c0a113bc38145d84ca986b2e30934 (diff) | |
parent | 76f7b16f1ee50a7677989ad93e1652bd31c131b7 (diff) | |
download | sqlite-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.c | 27 |
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; |