1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-02 05:54:29 +03:00

Make sure all cursors are closed when returning from a VDBE subprogram that

implements a foreign-key construct.

FossilOrigin-Name: d04d354d8e423961c3091b6ebcfbbbf10d3ecb04
This commit is contained in:
drh
2015-04-16 18:11:50 +00:00
parent 6dc4148547
commit ab4e7f3337
4 changed files with 31 additions and 19 deletions

View File

@@ -1789,6 +1789,22 @@ void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){
#endif
}
/*
** Close all cursors in the current frame.
*/
static void closeCursorsInFrame(Vdbe *p){
if( p->apCsr ){
int i;
for(i=0; i<p->nCursor; i++){
VdbeCursor *pC = p->apCsr[i];
if( pC ){
sqlite3VdbeFreeCursor(p, pC);
p->apCsr[i] = 0;
}
}
}
}
/*
** Copy the values stored in the VdbeFrame structure to its Vdbe. This
** is used, for example, when a trigger sub-program is halted to restore
@@ -1796,6 +1812,7 @@ void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){
*/
int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){
Vdbe *v = pFrame->v;
closeCursorsInFrame(v);
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
v->anExec = pFrame->anExec;
#endif
@@ -1830,17 +1847,7 @@ static void closeAllCursors(Vdbe *p){
p->nFrame = 0;
}
assert( p->nFrame==0 );
if( p->apCsr ){
int i;
for(i=0; i<p->nCursor; i++){
VdbeCursor *pC = p->apCsr[i];
if( pC ){
sqlite3VdbeFreeCursor(p, pC);
p->apCsr[i] = 0;
}
}
}
closeCursorsInFrame(p);
if( p->aMem ){
releaseMemArray(&p->aMem[1], p->nMem);
}