mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Thoroughly reset the rtree cursor at the start of each VFilter operation,
including clearing its cache. This prevents left over pages in the cache which can cause problems on shutdown after a LEFT JOIN. Ticket [5eadca17c4dde90c] FossilOrigin-Name: 4c50afafce8416369f89477ba7fe7d9b047399a5ee5754c73d0e67bbea8d877c
This commit is contained in:
@ -1065,9 +1065,12 @@ static int rtreeOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
|
||||
|
||||
|
||||
/*
|
||||
** Free the RtreeCursor.aConstraint[] array and its contents.
|
||||
** Reset a cursor back to its initial state.
|
||||
*/
|
||||
static void freeCursorConstraints(RtreeCursor *pCsr){
|
||||
static void resetCursor(RtreeCursor *pCsr){
|
||||
Rtree *pRtree = (Rtree *)(pCsr->base.pVtab);
|
||||
int ii;
|
||||
sqlite3_stmt *pStmt;
|
||||
if( pCsr->aConstraint ){
|
||||
int i; /* Used to iterate through constraint array */
|
||||
for(i=0; i<pCsr->nConstraint; i++){
|
||||
@ -1080,6 +1083,13 @@ static void freeCursorConstraints(RtreeCursor *pCsr){
|
||||
sqlite3_free(pCsr->aConstraint);
|
||||
pCsr->aConstraint = 0;
|
||||
}
|
||||
for(ii=0; ii<RTREE_CACHE_SZ; ii++) nodeRelease(pRtree, pCsr->aNode[ii]);
|
||||
sqlite3_free(pCsr->aPoint);
|
||||
pStmt = pCsr->pReadAux;
|
||||
memset(pCsr, 0, sizeof(RtreeCursor));
|
||||
pCsr->base.pVtab = (sqlite3_vtab*)pRtree;
|
||||
pCsr->pReadAux = pStmt;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1087,13 +1097,10 @@ static void freeCursorConstraints(RtreeCursor *pCsr){
|
||||
*/
|
||||
static int rtreeClose(sqlite3_vtab_cursor *cur){
|
||||
Rtree *pRtree = (Rtree *)(cur->pVtab);
|
||||
int ii;
|
||||
RtreeCursor *pCsr = (RtreeCursor *)cur;
|
||||
assert( pRtree->nCursor>0 );
|
||||
freeCursorConstraints(pCsr);
|
||||
resetCursor(pCsr);
|
||||
sqlite3_finalize(pCsr->pReadAux);
|
||||
sqlite3_free(pCsr->aPoint);
|
||||
for(ii=0; ii<RTREE_CACHE_SZ; ii++) nodeRelease(pRtree, pCsr->aNode[ii]);
|
||||
sqlite3_free(pCsr);
|
||||
pRtree->nCursor--;
|
||||
nodeBlobReset(pRtree);
|
||||
@ -1799,17 +1806,11 @@ static int rtreeFilter(
|
||||
int ii;
|
||||
int rc = SQLITE_OK;
|
||||
int iCell = 0;
|
||||
sqlite3_stmt *pStmt;
|
||||
|
||||
rtreeReference(pRtree);
|
||||
|
||||
/* Reset the cursor to the same state as rtreeOpen() leaves it in. */
|
||||
freeCursorConstraints(pCsr);
|
||||
sqlite3_free(pCsr->aPoint);
|
||||
pStmt = pCsr->pReadAux;
|
||||
memset(pCsr, 0, sizeof(RtreeCursor));
|
||||
pCsr->base.pVtab = (sqlite3_vtab*)pRtree;
|
||||
pCsr->pReadAux = pStmt;
|
||||
resetCursor(pCsr);
|
||||
|
||||
pCsr->iStrategy = idxNum;
|
||||
if( idxNum==1 ){
|
||||
|
Reference in New Issue
Block a user