Index: third_party/sqlite/src/src/prepare.c |
diff --git a/third_party/sqlite/src/src/prepare.c b/third_party/sqlite/src/src/prepare.c |
index 5d1ae00d137867d8404238237f1cccbb21d7ce18..74127bc76b424e558709e100765c1a26cedbd6ef 100644 |
--- a/third_party/sqlite/src/src/prepare.c |
+++ b/third_party/sqlite/src/src/prepare.c |
@@ -28,13 +28,12 @@ static void corruptSchema( |
if( !db->mallocFailed && (db->flags & SQLITE_RecoveryMode)==0 ){ |
char *z; |
if( zObj==0 ) zObj = "?"; |
- z = sqlite3_mprintf("malformed database schema (%s)", zObj); |
- if( z && zExtra ) z = sqlite3_mprintf("%z - %s", z, zExtra); |
+ z = sqlite3MPrintf(db, "malformed database schema (%s)", zObj); |
+ if( zExtra ) z = sqlite3MPrintf(db, "%z - %s", z, zExtra); |
sqlite3DbFree(db, *pData->pzErrMsg); |
*pData->pzErrMsg = z; |
- if( z==0 ) db->mallocFailed = 1; |
} |
- pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT_BKPT; |
+ pData->rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_CORRUPT_BKPT; |
} |
/* |
@@ -74,6 +73,7 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ |
** structures that describe the table, index, or view. |
*/ |
int rc; |
+ u8 saved_iDb = db->init.iDb; |
sqlite3_stmt *pStmt; |
TESTONLY(int rcp); /* Return code from sqlite3_prepare() */ |
@@ -84,14 +84,15 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ |
TESTONLY(rcp = ) sqlite3_prepare(db, argv[2], -1, &pStmt, 0); |
rc = db->errCode; |
assert( (rc&0xFF)==(rcp&0xFF) ); |
- db->init.iDb = 0; |
+ db->init.iDb = saved_iDb; |
+ assert( saved_iDb==0 || (db->flags & SQLITE_Vacuum)!=0 ); |
if( SQLITE_OK!=rc ){ |
if( db->init.orphanTrigger ){ |
assert( iDb==1 ); |
}else{ |
pData->rc = rc; |
if( rc==SQLITE_NOMEM ){ |
- db->mallocFailed = 1; |
+ sqlite3OomFault(db); |
}else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){ |
corruptSchema(pData, argv[0], sqlite3_errmsg(db)); |
} |
@@ -108,7 +109,7 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ |
** to do here is record the root page number for that index. |
*/ |
Index *pIndex; |
- pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zName); |
+ pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zDbSName); |
if( pIndex==0 ){ |
/* This can occur if there exists an index on a TEMP table which |
** has the same name as another index on a permanent index. Since |
@@ -137,61 +138,27 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ |
#ifndef SQLITE_OMIT_DEPRECATED |
int size; |
#endif |
- Table *pTab; |
Db *pDb; |
char const *azArg[4]; |
int meta[5]; |
InitData initData; |
- char const *zMasterSchema; |
- char const *zMasterName; |
+ const char *zMasterName; |
int openedTransaction = 0; |
- /* |
- ** The master database table has a structure like this |
- */ |
- static const char master_schema[] = |
- "CREATE TABLE sqlite_master(\n" |
- " type text,\n" |
- " name text,\n" |
- " tbl_name text,\n" |
- " rootpage integer,\n" |
- " sql text\n" |
- ")" |
- ; |
-#ifndef SQLITE_OMIT_TEMPDB |
- static const char temp_master_schema[] = |
- "CREATE TEMP TABLE sqlite_temp_master(\n" |
- " type text,\n" |
- " name text,\n" |
- " tbl_name text,\n" |
- " rootpage integer,\n" |
- " sql text\n" |
- ")" |
- ; |
-#else |
- #define temp_master_schema 0 |
-#endif |
- |
assert( iDb>=0 && iDb<db->nDb ); |
assert( db->aDb[iDb].pSchema ); |
assert( sqlite3_mutex_held(db->mutex) ); |
assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) ); |
- /* zMasterSchema and zInitScript are set to point at the master schema |
- ** and initialisation script appropriate for the database being |
- ** initialized. zMasterName is the name of the master table. |
- */ |
- if( !OMIT_TEMPDB && iDb==1 ){ |
- zMasterSchema = temp_master_schema; |
- }else{ |
- zMasterSchema = master_schema; |
- } |
- zMasterName = SCHEMA_TABLE(iDb); |
- |
- /* Construct the schema tables. */ |
- azArg[0] = zMasterName; |
+ /* Construct the in-memory representation schema tables (sqlite_master or |
+ ** sqlite_temp_master) by invoking the parser directly. The appropriate |
+ ** table name will be inserted automatically by the parser so we can just |
+ ** use the abbreviation "x" here. The parser will also automatically tag |
+ ** the schema table as read-only. */ |
+ azArg[0] = zMasterName = SCHEMA_TABLE(iDb); |
azArg[1] = "1"; |
- azArg[2] = zMasterSchema; |
+ azArg[2] = "CREATE TABLE x(type text,name text,tbl_name text," |
+ "rootpage integer,sql text)"; |
azArg[3] = 0; |
initData.db = db; |
initData.iDb = iDb; |
@@ -202,10 +169,6 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ |
rc = initData.rc; |
goto error_out; |
} |
- pTab = sqlite3FindTable(db, zMasterName, db->aDb[iDb].zName); |
- if( ALWAYS(pTab) ){ |
- pTab->tabFlags |= TF_Readonly; |
- } |
/* Create a cursor to hold the database open |
*/ |
@@ -324,8 +287,8 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ |
{ |
char *zSql; |
zSql = sqlite3MPrintf(db, |
- "SELECT name, rootpage, sql FROM '%q'.%s ORDER BY rowid", |
- db->aDb[iDb].zName, zMasterName); |
+ "SELECT name, rootpage, sql FROM \"%w\".%s ORDER BY rowid", |
+ db->aDb[iDb].zDbSName, zMasterName); |
#ifndef SQLITE_OMIT_AUTHORIZATION |
{ |
sqlite3_xauth xAuth; |
@@ -346,7 +309,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ |
#endif |
} |
if( db->mallocFailed ){ |
- rc = SQLITE_NOMEM; |
+ rc = SQLITE_NOMEM_BKPT; |
sqlite3ResetAllSchemasOfConnection(db); |
} |
if( rc==SQLITE_OK || (db->flags&SQLITE_RecoveryMode)){ |
@@ -374,7 +337,7 @@ initone_error_out: |
error_out: |
if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ |
- db->mallocFailed = 1; |
+ sqlite3OomFault(db); |
} |
return rc; |
} |
@@ -472,7 +435,7 @@ static void schemaIsValid(Parse *pParse){ |
if( !sqlite3BtreeIsInReadTrans(pBt) ){ |
rc = sqlite3BtreeBeginTrans(pBt, 0); |
if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ |
- db->mallocFailed = 1; |
+ sqlite3OomFault(db); |
} |
if( rc!=SQLITE_OK ) return; |
openedTransaction = 1; |
@@ -535,6 +498,11 @@ void sqlite3ParserReset(Parse *pParse){ |
sqlite3 *db = pParse->db; |
sqlite3DbFree(db, pParse->aLabel); |
sqlite3ExprListDelete(db, pParse->pConstExpr); |
+ if( db ){ |
+ assert( db->lookaside.bDisable >= pParse->disableLookaside ); |
+ db->lookaside.bDisable -= pParse->disableLookaside; |
+ } |
+ pParse->disableLookaside = 0; |
} |
} |
@@ -550,20 +518,16 @@ static int sqlite3Prepare( |
sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ |
const char **pzTail /* OUT: End of parsed string */ |
){ |
- Parse *pParse; /* Parsing context */ |
char *zErrMsg = 0; /* Error message */ |
int rc = SQLITE_OK; /* Result code */ |
int i; /* Loop counter */ |
+ Parse sParse; /* Parsing context */ |
- /* Allocate the parsing context */ |
- pParse = sqlite3StackAllocZero(db, sizeof(*pParse)); |
- if( pParse==0 ){ |
- rc = SQLITE_NOMEM; |
- goto end_prepare; |
- } |
- pParse->pReprepare = pReprepare; |
+ memset(&sParse, 0, PARSE_HDR_SZ); |
+ memset(PARSE_TAIL(&sParse), 0, PARSE_TAIL_SZ); |
+ sParse.pReprepare = pReprepare; |
assert( ppStmt && *ppStmt==0 ); |
- assert( !db->mallocFailed ); |
+ /* assert( !db->mallocFailed ); // not true with SQLITE_USE_ALLOCA */ |
assert( sqlite3_mutex_held(db->mutex) ); |
/* Check to verify that it is possible to get a read lock on all |
@@ -595,7 +559,7 @@ static int sqlite3Prepare( |
assert( sqlite3BtreeHoldsMutex(pBt) ); |
rc = sqlite3BtreeSchemaLocked(pBt); |
if( rc ){ |
- const char *zDb = db->aDb[i].zName; |
+ const char *zDb = db->aDb[i].zDbSName; |
sqlite3ErrorWithMsg(db, rc, "database schema is locked: %s", zDb); |
testcase( db->flags & SQLITE_ReadUncommitted ); |
goto end_prepare; |
@@ -605,8 +569,7 @@ static int sqlite3Prepare( |
sqlite3VtabUnlockList(db); |
- pParse->db = db; |
- pParse->nQueryLoop = 0; /* Logarithmic, so 0 really means 1 */ |
+ sParse.db = db; |
if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){ |
char *zSqlCopy; |
int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH]; |
@@ -619,64 +582,61 @@ static int sqlite3Prepare( |
} |
zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes); |
if( zSqlCopy ){ |
- sqlite3RunParser(pParse, zSqlCopy, &zErrMsg); |
+ sqlite3RunParser(&sParse, zSqlCopy, &zErrMsg); |
+ sParse.zTail = &zSql[sParse.zTail-zSqlCopy]; |
sqlite3DbFree(db, zSqlCopy); |
- pParse->zTail = &zSql[pParse->zTail-zSqlCopy]; |
}else{ |
- pParse->zTail = &zSql[nBytes]; |
+ sParse.zTail = &zSql[nBytes]; |
} |
}else{ |
- sqlite3RunParser(pParse, zSql, &zErrMsg); |
+ sqlite3RunParser(&sParse, zSql, &zErrMsg); |
} |
- assert( 0==pParse->nQueryLoop ); |
+ assert( 0==sParse.nQueryLoop ); |
- if( db->mallocFailed ){ |
- pParse->rc = SQLITE_NOMEM; |
- } |
- if( pParse->rc==SQLITE_DONE ) pParse->rc = SQLITE_OK; |
- if( pParse->checkSchema ){ |
- schemaIsValid(pParse); |
+ if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK; |
+ if( sParse.checkSchema ){ |
+ schemaIsValid(&sParse); |
} |
if( db->mallocFailed ){ |
- pParse->rc = SQLITE_NOMEM; |
+ sParse.rc = SQLITE_NOMEM_BKPT; |
} |
if( pzTail ){ |
- *pzTail = pParse->zTail; |
+ *pzTail = sParse.zTail; |
} |
- rc = pParse->rc; |
+ rc = sParse.rc; |
#ifndef SQLITE_OMIT_EXPLAIN |
- if( rc==SQLITE_OK && pParse->pVdbe && pParse->explain ){ |
+ if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){ |
static const char * const azColName[] = { |
"addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment", |
"selectid", "order", "from", "detail" |
}; |
int iFirst, mx; |
- if( pParse->explain==2 ){ |
- sqlite3VdbeSetNumCols(pParse->pVdbe, 4); |
+ if( sParse.explain==2 ){ |
+ sqlite3VdbeSetNumCols(sParse.pVdbe, 4); |
iFirst = 8; |
mx = 12; |
}else{ |
- sqlite3VdbeSetNumCols(pParse->pVdbe, 8); |
+ sqlite3VdbeSetNumCols(sParse.pVdbe, 8); |
iFirst = 0; |
mx = 8; |
} |
for(i=iFirst; i<mx; i++){ |
- sqlite3VdbeSetColName(pParse->pVdbe, i-iFirst, COLNAME_NAME, |
+ sqlite3VdbeSetColName(sParse.pVdbe, i-iFirst, COLNAME_NAME, |
azColName[i], SQLITE_STATIC); |
} |
} |
#endif |
if( db->init.busy==0 ){ |
- Vdbe *pVdbe = pParse->pVdbe; |
- sqlite3VdbeSetSql(pVdbe, zSql, (int)(pParse->zTail-zSql), saveSqlFlag); |
+ Vdbe *pVdbe = sParse.pVdbe; |
+ sqlite3VdbeSetSql(pVdbe, zSql, (int)(sParse.zTail-zSql), saveSqlFlag); |
} |
- if( pParse->pVdbe && (rc!=SQLITE_OK || db->mallocFailed) ){ |
- sqlite3VdbeFinalize(pParse->pVdbe); |
+ if( sParse.pVdbe && (rc!=SQLITE_OK || db->mallocFailed) ){ |
+ sqlite3VdbeFinalize(sParse.pVdbe); |
assert(!(*ppStmt)); |
}else{ |
- *ppStmt = (sqlite3_stmt*)pParse->pVdbe; |
+ *ppStmt = (sqlite3_stmt*)sParse.pVdbe; |
} |
if( zErrMsg ){ |
@@ -687,16 +647,15 @@ static int sqlite3Prepare( |
} |
/* Delete any TriggerPrg structures allocated while parsing this statement. */ |
- while( pParse->pTriggerPrg ){ |
- TriggerPrg *pT = pParse->pTriggerPrg; |
- pParse->pTriggerPrg = pT->pNext; |
+ while( sParse.pTriggerPrg ){ |
+ TriggerPrg *pT = sParse.pTriggerPrg; |
+ sParse.pTriggerPrg = pT->pNext; |
sqlite3DbFree(db, pT); |
} |
end_prepare: |
- sqlite3ParserReset(pParse); |
- sqlite3StackFree(db, pParse); |
+ sqlite3ParserReset(&sParse); |
rc = sqlite3ApiExit(db, rc); |
assert( (rc&db->errMask)==rc ); |
return rc; |
@@ -754,7 +713,7 @@ int sqlite3Reprepare(Vdbe *p){ |
rc = sqlite3LockAndPrepare(db, zSql, -1, 0, p, &pNew, 0); |
if( rc ){ |
if( rc==SQLITE_NOMEM ){ |
- db->mallocFailed = 1; |
+ sqlite3OomFault(db); |
} |
assert( pNew==0 ); |
return rc; |