| 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;
|
|
|