aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2019-02-08 14:55:30 +0000
committerdrh <drh@noemail.net>2019-02-08 14:55:30 +0000
commit1cf197583de15d352dc169437f619d2e4631cf4b (patch)
treefdb5c38ef260c5263604a91f905fe51394d0148b /src
parent8851e10017893cfaf88acf80e223149fea1a1a37 (diff)
downloadsqlite-1cf197583de15d352dc169437f619d2e4631cf4b.tar.gz
sqlite-1cf197583de15d352dc169437f619d2e4631cf4b.zip
Give the sqlite3 object a pointer to the current Parse so that if an OOM
occurs, it can automatically set the Parse.rc value to SQLITE_NOMEM. This avoids a frequent extra test of db.mallocFailed in the innermost parser loop. FossilOrigin-Name: 5c6638040b3017c6be016441422d965a3ca00dd6ae1f78cadc0b54562978f64e
Diffstat (limited to 'src')
-rw-r--r--src/malloc.c3
-rw-r--r--src/sqliteInt.h2
-rw-r--r--src/tokenize.c8
3 files changed, 12 insertions, 1 deletions
diff --git a/src/malloc.c b/src/malloc.c
index d7f9df5ef..559e7259c 100644
--- a/src/malloc.c
+++ b/src/malloc.c
@@ -661,6 +661,9 @@ void sqlite3OomFault(sqlite3 *db){
db->u1.isInterrupted = 1;
}
db->lookaside.bDisable++;
+ if( db->pParse ){
+ db->pParse->rc = SQLITE_NOMEM_BKPT;
+ }
}
}
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 774d3e501..e56867775 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -1431,6 +1431,7 @@ struct sqlite3 {
void (*xRollbackCallback)(void*); /* Invoked at every commit. */
void *pUpdateArg;
void (*xUpdateCallback)(void*,int, const char*,const char*,sqlite_int64);
+ Parse *pParse; /* Current parse */
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
void *pPreUpdateArg; /* First argument to xPreUpdateCallback */
void (*xPreUpdateCallback)( /* Registered using sqlite3_preupdate_hook() */
@@ -3094,6 +3095,7 @@ struct Parse {
AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */
Parse *pToplevel; /* Parse structure for main program (or NULL) */
Table *pTriggerTab; /* Table triggers are being coded for */
+ Parse *pParentParse; /* Parent parser if this parser is nested */
int addrCrTab; /* Address of OP_CreateBtree opcode on CREATE TABLE */
u32 nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */
u32 oldmask; /* Mask of old.* columns referenced */
diff --git a/src/tokenize.c b/src/tokenize.c
index 2d7b23d4e..d22b46371 100644
--- a/src/tokenize.c
+++ b/src/tokenize.c
@@ -560,6 +560,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
int lastTokenParsed = -1; /* type of the previous token */
sqlite3 *db = pParse->db; /* The database connection */
int mxSqlLen; /* Max length of an SQL string */
+ VVA_ONLY( u8 startedWithOom = db->mallocFailed );
#ifdef sqlite3Parser_ENGINEALWAYSONSTACK
yyParser sEngine; /* Space to hold the Lemon-generated Parser object */
#endif
@@ -594,6 +595,8 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
assert( pParse->pNewTrigger==0 );
assert( pParse->nVar==0 );
assert( pParse->pVList==0 );
+ pParse->pParentParse = db->pParse;
+ db->pParse = pParse;
while( 1 ){
n = sqlite3GetToken((u8*)zSql, &tokenType);
mxSqlLen -= n;
@@ -650,7 +653,8 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
sqlite3Parser(pEngine, tokenType, pParse->sLastToken);
lastTokenParsed = tokenType;
zSql += n;
- if( pParse->rc!=SQLITE_OK || db->mallocFailed ) break;
+ assert( db->mallocFailed==0 || pParse->rc!=SQLITE_OK || startedWithOom );
+ if( pParse->rc!=SQLITE_OK ) break;
}
assert( nErr==0 );
#ifdef YYTRACKMAXSTACKDEPTH
@@ -718,6 +722,8 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
pParse->pZombieTab = p->pNextZombie;
sqlite3DeleteTable(db, p);
}
+ db->pParse = pParse->pParentParse;
+ pParse->pParentParse = 0;
assert( nErr==0 || pParse->rc!=SQLITE_OK );
return nErr;
}