mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Have fts5 better handle OOM errors from sqlite3_blob_close().
FossilOrigin-Name: f418350f3f83147bc5817a885be6e39ff9ff5722742a88d17600729c53c65010
This commit is contained in:
@ -778,11 +778,13 @@ static int fts5LeafFirstTermOff(Fts5Data *pLeaf){
|
||||
/*
|
||||
** Close the read-only blob handle, if it is open.
|
||||
*/
|
||||
void sqlite3Fts5IndexCloseReader(Fts5Index *p){
|
||||
void fts5IndexCloseReader(Fts5Index *p){
|
||||
if( p->pReader ){
|
||||
int rc;
|
||||
sqlite3_blob *pReader = p->pReader;
|
||||
p->pReader = 0;
|
||||
sqlite3_blob_close(pReader);
|
||||
rc = sqlite3_blob_close(pReader);
|
||||
if( p->rc==SQLITE_OK ) p->rc = rc;
|
||||
}
|
||||
}
|
||||
|
||||
@ -807,7 +809,7 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){
|
||||
assert( p->pReader==0 );
|
||||
p->pReader = pBlob;
|
||||
if( rc!=SQLITE_OK ){
|
||||
sqlite3Fts5IndexCloseReader(p);
|
||||
fts5IndexCloseReader(p);
|
||||
}
|
||||
if( rc==SQLITE_ABORT ) rc = SQLITE_OK;
|
||||
}
|
||||
@ -5009,6 +5011,14 @@ static int fts5IndexReturn(Fts5Index *p){
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Close the read-only blob handle, if it is open.
|
||||
*/
|
||||
void sqlite3Fts5IndexCloseReader(Fts5Index *p){
|
||||
fts5IndexCloseReader(p);
|
||||
fts5IndexReturn(p);
|
||||
}
|
||||
|
||||
typedef struct Fts5FlushCtx Fts5FlushCtx;
|
||||
struct Fts5FlushCtx {
|
||||
Fts5Index *pIdx;
|
||||
@ -6730,7 +6740,7 @@ int sqlite3Fts5IndexBeginWrite(Fts5Index *p, int bDelete, i64 iRowid){
|
||||
int sqlite3Fts5IndexSync(Fts5Index *p){
|
||||
assert( p->rc==SQLITE_OK );
|
||||
fts5IndexFlush(p);
|
||||
sqlite3Fts5IndexCloseReader(p);
|
||||
fts5IndexCloseReader(p);
|
||||
return fts5IndexReturn(p);
|
||||
}
|
||||
|
||||
@ -6741,11 +6751,10 @@ int sqlite3Fts5IndexSync(Fts5Index *p){
|
||||
** records must be invalidated.
|
||||
*/
|
||||
int sqlite3Fts5IndexRollback(Fts5Index *p){
|
||||
sqlite3Fts5IndexCloseReader(p);
|
||||
fts5IndexCloseReader(p);
|
||||
fts5IndexDiscardData(p);
|
||||
fts5StructureInvalidate(p);
|
||||
/* assert( p->rc==SQLITE_OK ); */
|
||||
return SQLITE_OK;
|
||||
return fts5IndexReturn(p);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -6946,6 +6955,16 @@ static void fts5SegIterSetEOF(Fts5SegIter *pSeg){
|
||||
pSeg->pLeaf = 0;
|
||||
}
|
||||
|
||||
void fts5IterClose(Fts5IndexIter *pIndexIter){
|
||||
if( pIndexIter ){
|
||||
Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
|
||||
Fts5Index *pIndex = pIter->pIndex;
|
||||
fts5TokendataIterDelete(pIter->pTokenDataIter);
|
||||
fts5MultiIterFree(pIter);
|
||||
fts5IndexCloseReader(pIndex);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** This function appends iterator pAppend to Fts5TokenDataIter pIn and
|
||||
** returns the result.
|
||||
@ -6973,7 +6992,7 @@ static Fts5TokenDataIter *fts5AppendTokendataIter(
|
||||
}
|
||||
}
|
||||
if( p->rc ){
|
||||
sqlite3Fts5IterClose((Fts5IndexIter*)pAppend);
|
||||
fts5IterClose((Fts5IndexIter*)pAppend);
|
||||
}else{
|
||||
pRet->apIter[pRet->nIter++] = pAppend;
|
||||
}
|
||||
@ -7186,7 +7205,7 @@ static Fts5Iter *fts5SetupTokendataIter(
|
||||
fts5BufferSet(&p->rc, &bSeek, nToken, pToken);
|
||||
}
|
||||
if( p->rc ){
|
||||
sqlite3Fts5IterClose((Fts5IndexIter*)pNew);
|
||||
fts5IterClose((Fts5IndexIter*)pNew);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -7251,7 +7270,7 @@ static Fts5Iter *fts5SetupTokendataIter(
|
||||
** not point to any terms that match the query. So delete it and break
|
||||
** out of the loop - all required iterators have been collected. */
|
||||
if( pSmall==0 ){
|
||||
sqlite3Fts5IterClose((Fts5IndexIter*)pNew);
|
||||
fts5IterClose((Fts5IndexIter*)pNew);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -7380,9 +7399,9 @@ int sqlite3Fts5IndexQuery(
|
||||
}
|
||||
|
||||
if( p->rc ){
|
||||
sqlite3Fts5IterClose((Fts5IndexIter*)pRet);
|
||||
fts5IterClose((Fts5IndexIter*)pRet);
|
||||
pRet = 0;
|
||||
sqlite3Fts5IndexCloseReader(p);
|
||||
fts5IndexCloseReader(p);
|
||||
}
|
||||
|
||||
*ppIter = (Fts5IndexIter*)pRet;
|
||||
@ -7632,11 +7651,9 @@ int sqlite3Fts5IndexIterWriteTokendata(
|
||||
*/
|
||||
void sqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){
|
||||
if( pIndexIter ){
|
||||
Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
|
||||
Fts5Index *pIndex = pIter->pIndex;
|
||||
fts5TokendataIterDelete(pIter->pTokenDataIter);
|
||||
fts5MultiIterFree(pIter);
|
||||
sqlite3Fts5IndexCloseReader(pIndex);
|
||||
Fts5Index *pIndex = ((Fts5Iter*)pIndexIter)->pIndex;
|
||||
fts5IterClose(pIndexIter);
|
||||
fts5IndexReturn(pIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@ -8166,7 +8183,7 @@ static int fts5QueryCksum(
|
||||
rc = sqlite3Fts5IterNext(pIter);
|
||||
}
|
||||
}
|
||||
sqlite3Fts5IterClose(pIter);
|
||||
fts5IterClose(pIter);
|
||||
|
||||
*pCksum = cksum;
|
||||
return rc;
|
||||
|
@ -290,5 +290,40 @@ do_faultsim_test 11 -faults oom* -prep {
|
||||
faultsim_test_result {0 {}}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
|
||||
ifcapable foreignkey {
|
||||
do_execsql_test 12.0 {
|
||||
CREATE VIRTUAL TABLE f1 USING fts5(content);
|
||||
CREATE TABLE p1(a INTEGER PRIMARY KEY);
|
||||
CREATE TABLE c1(b REFERENCES p1 DEFERRABLE INITIALLY DEFERRED);
|
||||
}
|
||||
|
||||
faultsim_save_and_close
|
||||
|
||||
do_faultsim_test 11 -faults oom* -prep {
|
||||
faultsim_restore_and_reopen
|
||||
execsql {
|
||||
PRAGMA foreign_keys = 1;
|
||||
BEGIN;
|
||||
INSERT INTO c1 VALUES(123);
|
||||
SAVEPOINT xyz;
|
||||
}
|
||||
} -body {
|
||||
execsql {
|
||||
INSERT INTO f1 VALUES('a b c');
|
||||
ROLLBACK TO xyz;
|
||||
COMMIT;
|
||||
}
|
||||
} -test {
|
||||
execsql { SELECT 123 }
|
||||
faultsim_test_result \
|
||||
{1 {FOREIGN KEY constraint failed}} \
|
||||
{1 {out of memory}} \
|
||||
{1 {constraint failed}}
|
||||
}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
Reference in New Issue
Block a user