/* ** Load the content of the sqlite_stat1 table into the index hash tables. */ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ analysisInfo sInfo; HashElem *i; char *zSql; int rc; assert( iDb>=0 && iDb<db->nDb ); assert( db->aDb[iDb].pBt!=0 ); assert( sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) ); /* Clear any prior statistics */ for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ Index *pIdx = sqliteHashData(i); sqlite3DefaultRowEst(pIdx); } /* Check to make sure the sqlite_stat1 table existss */ sInfo.db = db; sInfo.zDatabase = db->aDb[iDb].zName; if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)==0 ){ return SQLITE_ERROR; } /* Load new statistics out of the sqlite_stat1 table */ zSql = sqlite3MPrintf(db, "SELECT idx, stat FROM %Q.sqlite_stat1", sInfo.zDatabase); sqlite3SafetyOff(db); rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0); sqlite3SafetyOn(db); sqlite3_free(zSql); return rc; }
/* ** Load the content of the sqlite_stat1 table into the index hash tables. */ void sqlite3AnalysisLoad(sqlite3 *db, int iDb){ analysisInfo sInfo; HashElem *i; char *zSql; /* Clear any prior statistics */ for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ Index *pIdx = sqliteHashData(i); sqlite3DefaultRowEst(pIdx); } /* Check to make sure the sqlite_stat1 table existss */ sInfo.db = db; sInfo.zDatabase = db->aDb[iDb].zName; if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)==0 ){ return; } /* Load new statistics out of the sqlite_stat1 table */ zSql = sqlite3MPrintf("SELECT idx, stat FROM %Q.sqlite_stat1", sInfo.zDatabase); sqlite3SafetyOff(db); sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0); sqlite3SafetyOn(db); sqliteFree(zSql); }
/* ** Invoke the xSync method of all virtual tables in the sqlite3.aVTrans ** array. Return the error code for the first error that occurs, or ** SQLITE_OK if all xSync operations are successful. ** ** Set *pzErrmsg to point to a buffer that should be released using ** sqlite3DbFree() containing an error message, if one is available. */ int sqlite3VtabSync(sqlite3 *db, char **pzErrmsg){ int i; int rc = SQLITE_OK; int rcsafety; VTable **aVTrans = db->aVTrans; rc = sqlite3SafetyOff(db); db->aVTrans = 0; for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){ int (*x)(sqlite3_vtab *); sqlite3_vtab *pVtab = aVTrans[i]->pVtab; if( pVtab && (x = pVtab->pModule->xSync)!=0 ){ rc = x(pVtab); sqlite3DbFree(db, *pzErrmsg); *pzErrmsg = pVtab->zErrMsg; pVtab->zErrMsg = 0; } } db->aVTrans = aVTrans; rcsafety = sqlite3SafetyOn(db); if( rc==SQLITE_OK ){ rc = rcsafety; } return rc; }
/* ** If argument rc2 is not SQLITE_OK, then return it and do nothing. ** Otherwise, invoke the xSync method of all virtual tables in the ** sqlite3.aVTrans array. Return the error code for the first error ** that occurs, or SQLITE_OK if all xSync operations are successful. */ int sqlite3VtabSync(sqlite3 *db, int rc2){ int i; int rc = SQLITE_OK; int rcsafety; sqlite3_vtab **aVTrans = db->aVTrans; if( rc2!=SQLITE_OK ) return rc2; rc = sqlite3SafetyOff(db); db->aVTrans = 0; for(i=0; rc==SQLITE_OK && i<db->nVTrans && aVTrans[i]; i++){ sqlite3_vtab *pVtab = aVTrans[i]; int (*x)(sqlite3_vtab *); x = pVtab->pModule->xSync; if( x ){ rc = x(pVtab); } } db->aVTrans = aVTrans; rcsafety = sqlite3SafetyOn(db); if( rc==SQLITE_OK ){ rc = rcsafety; } return rc; }
/* ** Decrement the ref-count on a virtual table object. When the ref-count ** reaches zero, call the xDisconnect() method to delete the object. */ void sqlite3VtabUnlock(VTable *pVTab){ sqlite3 *db = pVTab->db; assert( db ); assert( pVTab->nRef>0 ); assert( sqlite3SafetyCheckOk(db) ); pVTab->nRef--; if( pVTab->nRef==0 ){ sqlite3_vtab *p = pVTab->pVtab; if( p ){ #ifdef SQLITE_DEBUG if( pVTab->db->magic==SQLITE_MAGIC_BUSY ){ (void)sqlite3SafetyOff(db); p->pModule->xDisconnect(p); (void)sqlite3SafetyOn(db); } else #endif { p->pModule->xDisconnect(p); } } sqlite3DbFree(db, pVTab); } }
/* ** Invoke a virtual table constructor (either xCreate or xConnect). The ** pointer to the function to invoke is passed as the fourth parameter ** to this procedure. */ static int vtabCallConstructor( sqlite3 *db, Table *pTab, Module *pMod, int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**), char **pzErr ){ int rc; int rc2; sqlite3_vtab *pVtab; const char *const*azArg = (const char *const*)pTab->azModuleArg; int nArg = pTab->nModuleArg; char *zErr = 0; char *zModuleName = sqlite3MPrintf("%s", pTab->zName); if( !zModuleName ){ return SQLITE_NOMEM; } assert( !db->pVTab ); assert( xConstruct ); db->pVTab = pTab; rc = sqlite3SafetyOff(db); assert( rc==SQLITE_OK ); rc = xConstruct(db, pMod->pAux, nArg, azArg, &pTab->pVtab, &zErr); rc2 = sqlite3SafetyOn(db); pVtab = pTab->pVtab; if( rc==SQLITE_OK && pVtab ){ pVtab->pModule = pMod->pModule; pVtab->nRef = 1; } if( SQLITE_OK!=rc ){ if( zErr==0 ){ *pzErr = sqlite3MPrintf("vtable constructor failed: %s", zModuleName); }else { *pzErr = sqlite3MPrintf("%s", zErr); sqlite3_free(zErr); } }else if( db->pVTab ){ const char *zFormat = "vtable constructor did not declare schema: %s"; *pzErr = sqlite3MPrintf(zFormat, pTab->zName); rc = SQLITE_ERROR; } if( rc==SQLITE_OK ){ rc = rc2; } db->pVTab = 0; sqliteFree(zModuleName); return rc; }
/* ** Unlock a virtual table. When the last lock is removed, ** disconnect the virtual table. */ void sqlite3VtabUnlock(sqlite3 *db, sqlite3_vtab *pVtab){ pVtab->nRef--; assert(db); assert(!sqlite3SafetyCheck(db)); if( pVtab->nRef==0 ){ if( db->magic==SQLITE_MAGIC_BUSY ){ sqlite3SafetyOff(db); pVtab->pModule->xDisconnect(pVtab); sqlite3SafetyOn(db); } else { pVtab->pModule->xDisconnect(pVtab); } } }
/* ** This function is invoked by the vdbe to call the xDestroy method ** of the virtual table named zTab in database iDb. This occurs ** when a DROP TABLE is mentioned. ** ** This call is a no-op if zTab is not a virtual table. */ int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab) { int rc = SQLITE_OK; Table *pTab; pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName); assert(pTab); if( pTab->pVtab ){ int (*xDestroy)(sqlite3_vtab *pVTab) = pTab->pMod->pModule->xDestroy; rc = sqlite3SafetyOff(db); assert( rc==SQLITE_OK ); if( xDestroy ){ rc = xDestroy(pTab->pVtab); } sqlite3SafetyOn(db); if( rc==SQLITE_OK ){ pTab->pVtab = 0; } } return rc; }
/* ** This function is invoked by the vdbe to call the xDestroy method ** of the virtual table named zTab in database iDb. This occurs ** when a DROP TABLE is mentioned. ** ** This call is a no-op if zTab is not a virtual table. */ int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){ int rc = SQLITE_OK; Table *pTab; pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName); if( ALWAYS(pTab!=0 && pTab->pVTable!=0) ){ VTable *p = vtabDisconnectAll(db, pTab); rc = sqlite3SafetyOff(db); assert( rc==SQLITE_OK ); rc = p->pMod->pModule->xDestroy(p->pVtab); (void)sqlite3SafetyOn(db); /* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */ if( rc==SQLITE_OK ){ assert( pTab->pVTable==p && p->pNext==0 ); p->pVtab = 0; pTab->pVTable = 0; sqlite3VtabUnlock(p); } } return rc; }
/* ** Execute the statement pStmt, either until a row of data is ready, the ** statement is completely executed or an error occurs. */ int sqlite3_step(sqlite3_stmt *pStmt){ Vdbe *p = (Vdbe*)pStmt; sqlite3 *db; int rc; if( p==0 || p->magic!=VDBE_MAGIC_RUN ){ return SQLITE_MISUSE; } if( p->aborted ){ return SQLITE_ABORT; } if( p->pc<=0 && p->expired ){ if( p->rc==SQLITE_OK ){ p->rc = SQLITE_SCHEMA; } return SQLITE_ERROR; } db = p->db; if( sqlite3SafetyOn(db) ){ p->rc = SQLITE_MISUSE; return SQLITE_MISUSE; } if( p->pc<0 ){ #ifndef SQLITE_OMIT_TRACE /* Invoke the trace callback if there is one */ if( db->xTrace && !db->init.busy ){ assert( p->nOp>0 ); assert( p->aOp[p->nOp-1].opcode==OP_Noop ); assert( p->aOp[p->nOp-1].p3!=0 ); assert( p->aOp[p->nOp-1].p3type==P3_DYNAMIC ); sqlite3SafetyOff(db); db->xTrace(db->pTraceArg, p->aOp[p->nOp-1].p3); if( sqlite3SafetyOn(db) ){ p->rc = SQLITE_MISUSE; return SQLITE_MISUSE; } } if( db->xProfile && !db->init.busy ){ double rNow; sqlite3OsCurrentTime(&rNow); p->startTime = (rNow - (int)rNow)*3600.0*24.0*1000000000.0; } #endif /* Print a copy of SQL as it is executed if the SQL_TRACE pragma is turned ** on in debugging mode. */ #ifdef SQLITE_DEBUG if( (db->flags & SQLITE_SqlTrace)!=0 ){ sqlite3DebugPrintf("SQL-trace: %s\n", p->aOp[p->nOp-1].p3); } #endif /* SQLITE_DEBUG */ db->activeVdbeCnt++; p->pc = 0; } #ifndef SQLITE_OMIT_EXPLAIN if( p->explain ){ rc = sqlite3VdbeList(p); }else #endif /* SQLITE_OMIT_EXPLAIN */ { rc = sqlite3VdbeExec(p); } if( sqlite3SafetyOff(db) ){ rc = SQLITE_MISUSE; } #ifndef SQLITE_OMIT_TRACE /* Invoke the profile callback if there is one */ if( rc!=SQLITE_ROW && db->xProfile && !db->init.busy ){ double rNow; u64 elapseTime; sqlite3OsCurrentTime(&rNow); elapseTime = (rNow - (int)rNow)*3600.0*24.0*1000000000.0 - p->startTime; assert( p->nOp>0 ); assert( p->aOp[p->nOp-1].opcode==OP_Noop ); assert( p->aOp[p->nOp-1].p3!=0 ); assert( p->aOp[p->nOp-1].p3type==P3_DYNAMIC ); db->xProfile(db->pProfileArg, p->aOp[p->nOp-1].p3, elapseTime); } #endif sqlite3Error(p->db, rc, p->zErrMsg ? "%s" : 0, p->zErrMsg); return rc; }
/* ** Execute the statement pStmt, either until a row of data is ready, the ** statement is completely executed or an error occurs. ** ** This routine implements the bulk of the logic behind the sqlite_step() ** API. The only thing omitted is the automatic recompile if a ** schema change has occurred. That detail is handled by the ** outer sqlite3_step() wrapper procedure. */ static int sqlite3Step(Vdbe *p){ sqlite3 *db; int rc; /* Assert that malloc() has not failed */ assert( !sqlite3MallocFailed() ); if( p==0 || p->magic!=VDBE_MAGIC_RUN ){ return SQLITE_MISUSE; } if( p->aborted ){ return SQLITE_ABORT; } if( p->pc<=0 && p->expired ){ if( p->rc==SQLITE_OK ){ p->rc = SQLITE_SCHEMA; } rc = SQLITE_ERROR; goto end_of_step; } db = p->db; if( sqlite3SafetyOn(db) ){ p->rc = SQLITE_MISUSE; return SQLITE_MISUSE; } if( p->pc<0 ){ /* If there are no other statements currently running, then ** reset the interrupt flag. This prevents a call to sqlite3_interrupt ** from interrupting a statement that has not yet started. */ if( db->activeVdbeCnt==0 ){ db->u1.isInterrupted = 0; } #ifndef SQLITE_OMIT_TRACE /* Invoke the trace callback if there is one */ if( db->xTrace && !db->init.busy ){ assert( p->nOp>0 ); assert( p->aOp[p->nOp-1].opcode==OP_Noop ); assert( p->aOp[p->nOp-1].p3!=0 ); assert( p->aOp[p->nOp-1].p3type==P3_DYNAMIC ); sqlite3SafetyOff(db); db->xTrace(db->pTraceArg, p->aOp[p->nOp-1].p3); if( sqlite3SafetyOn(db) ){ p->rc = SQLITE_MISUSE; return SQLITE_MISUSE; } } if( db->xProfile && !db->init.busy ){ double rNow; sqlite3OsCurrentTime(&rNow); p->startTime = (rNow - (int)rNow)*3600.0*24.0*1000000000.0; } #endif /* Print a copy of SQL as it is executed if the SQL_TRACE pragma is turned ** on in debugging mode. */ #ifdef SQLITE_DEBUG if( (db->flags & SQLITE_SqlTrace)!=0 ){ sqlite3DebugPrintf("SQL-trace: %s\n", p->aOp[p->nOp-1].p3); } #endif /* SQLITE_DEBUG */ db->activeVdbeCnt++; p->pc = 0; } #ifndef SQLITE_OMIT_EXPLAIN if( p->explain ){ rc = sqlite3VdbeList(p); }else #endif /* SQLITE_OMIT_EXPLAIN */ { rc = sqlite3VdbeExec(p); } if( sqlite3SafetyOff(db) ){ rc = SQLITE_MISUSE; } #ifndef SQLITE_OMIT_TRACE /* Invoke the profile callback if there is one */ if( rc!=SQLITE_ROW && db->xProfile && !db->init.busy ){ double rNow; u64 elapseTime; sqlite3OsCurrentTime(&rNow); elapseTime = (rNow - (int)rNow)*3600.0*24.0*1000000000.0 - p->startTime; assert( p->nOp>0 ); assert( p->aOp[p->nOp-1].opcode==OP_Noop ); assert( p->aOp[p->nOp-1].p3!=0 ); assert( p->aOp[p->nOp-1].p3type==P3_DYNAMIC ); db->xProfile(db->pProfileArg, p->aOp[p->nOp-1].p3, elapseTime); } #endif sqlite3Error(p->db, rc, 0); p->rc = sqlite3ApiExit(p->db, p->rc); end_of_step: assert( (rc&0xff)==rc ); if( p->zSql && (rc&0xff)<SQLITE_ROW ){ /* This behavior occurs if sqlite3_prepare_v2() was used to build ** the prepared statement. Return error codes directly */ return p->rc; }else{ /* This is for legacy sqlite3_prepare() builds and when the code ** is SQLITE_ROW or SQLITE_DONE */ return rc; } }
/* ** Open a blob handle. */ int sqlite3_blob_open( sqlite3* db, /* The database connection */ const char *zDb, /* The attached database containing the blob */ const char *zTable, /* The table containing the blob */ const char *zColumn, /* The column containing the blob */ sqlite_int64 iRow, /* The row containing the glob */ int flags, /* True -> read/write access, false -> read-only */ sqlite3_blob **ppBlob /* Handle for accessing the blob returned here */ ){ int nAttempt = 0; int iCol; /* Index of zColumn in row-record */ /* This VDBE program seeks a btree cursor to the identified ** db/table/row entry. The reason for using a vdbe program instead ** of writing code to use the b-tree layer directly is that the ** vdbe program will take advantage of the various transaction, ** locking and error handling infrastructure built into the vdbe. ** ** After seeking the cursor, the vdbe executes an OP_ResultRow. ** Code external to the Vdbe then "borrows" the b-tree cursor and ** uses it to implement the blob_read(), blob_write() and ** blob_bytes() functions. ** ** The sqlite3_blob_close() function finalizes the vdbe program, ** which closes the b-tree cursor and (possibly) commits the ** transaction. */ static const VdbeOpList openBlob[] = { {OP_Transaction, 0, 0, 0}, /* 0: Start a transaction */ {OP_VerifyCookie, 0, 0, 0}, /* 1: Check the schema cookie */ {OP_TableLock, 0, 0, 0}, /* 2: Acquire a read or write lock */ /* One of the following two instructions is replaced by an OP_Noop. */ {OP_OpenRead, 0, 0, 0}, /* 3: Open cursor 0 for reading */ {OP_OpenWrite, 0, 0, 0}, /* 4: Open cursor 0 for read/write */ {OP_Variable, 1, 1, 1}, /* 5: Push the rowid to the stack */ {OP_NotExists, 0, 9, 1}, /* 6: Seek the cursor */ {OP_Column, 0, 0, 1}, /* 7 */ {OP_ResultRow, 1, 0, 0}, /* 8 */ {OP_Close, 0, 0, 0}, /* 9 */ {OP_Halt, 0, 0, 0}, /* 10 */ }; Vdbe *v = 0; int rc = SQLITE_OK; char *zErr = 0; Table *pTab; Parse *pParse; *ppBlob = 0; sqlite3_mutex_enter(db->mutex); pParse = sqlite3StackAllocRaw(db, sizeof(*pParse)); if( pParse==0 ){ rc = SQLITE_NOMEM; goto blob_open_out; } do { memset(pParse, 0, sizeof(Parse)); pParse->db = db; if( sqlite3SafetyOn(db) ){ sqlite3DbFree(db, zErr); sqlite3StackFree(db, pParse); sqlite3_mutex_leave(db->mutex); return SQLITE_MISUSE; } sqlite3BtreeEnterAll(db); pTab = sqlite3LocateTable(pParse, 0, zTable, zDb); if( pTab && IsVirtual(pTab) ){ pTab = 0; sqlite3ErrorMsg(pParse, "cannot open virtual table: %s", zTable); } #ifndef SQLITE_OMIT_VIEW if( pTab && pTab->pSelect ){ pTab = 0; sqlite3ErrorMsg(pParse, "cannot open view: %s", zTable); } #endif if( !pTab ){ if( pParse->zErrMsg ){ sqlite3DbFree(db, zErr); zErr = pParse->zErrMsg; pParse->zErrMsg = 0; } rc = SQLITE_ERROR; (void)sqlite3SafetyOff(db); sqlite3BtreeLeaveAll(db); goto blob_open_out; } /* Now search pTab for the exact column. */ for(iCol=0; iCol < pTab->nCol; iCol++) { if( sqlite3StrICmp(pTab->aCol[iCol].zName, zColumn)==0 ){ break; } } if( iCol==pTab->nCol ){ sqlite3DbFree(db, zErr); zErr = sqlite3MPrintf(db, "no such column: \"%s\"", zColumn); rc = SQLITE_ERROR; (void)sqlite3SafetyOff(db); sqlite3BtreeLeaveAll(db); goto blob_open_out; } /* If the value is being opened for writing, check that the ** column is not indexed. It is against the rules to open an ** indexed column for writing. */ if( flags ){ Index *pIdx; for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ int j; for(j=0; j<pIdx->nColumn; j++){ if( pIdx->aiColumn[j]==iCol ){ sqlite3DbFree(db, zErr); zErr = sqlite3MPrintf(db, "cannot open indexed column for writing"); rc = SQLITE_ERROR; (void)sqlite3SafetyOff(db); sqlite3BtreeLeaveAll(db); goto blob_open_out; } } } } v = sqlite3VdbeCreate(db); if( v ){ int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); sqlite3VdbeAddOpList(v, sizeof(openBlob)/sizeof(VdbeOpList), openBlob); flags = !!flags; /* flags = (flags ? 1 : 0); */ /* Configure the OP_Transaction */ sqlite3VdbeChangeP1(v, 0, iDb); sqlite3VdbeChangeP2(v, 0, flags); /* Configure the OP_VerifyCookie */ sqlite3VdbeChangeP1(v, 1, iDb); sqlite3VdbeChangeP2(v, 1, pTab->pSchema->schema_cookie); /* Make sure a mutex is held on the table to be accessed */ sqlite3VdbeUsesBtree(v, iDb); /* Configure the OP_TableLock instruction */ sqlite3VdbeChangeP1(v, 2, iDb); sqlite3VdbeChangeP2(v, 2, pTab->tnum); sqlite3VdbeChangeP3(v, 2, flags); sqlite3VdbeChangeP4(v, 2, pTab->zName, P4_TRANSIENT); /* Remove either the OP_OpenWrite or OpenRead. Set the P2 ** parameter of the other to pTab->tnum. */ sqlite3VdbeChangeToNoop(v, 4 - flags, 1); sqlite3VdbeChangeP2(v, 3 + flags, pTab->tnum); sqlite3VdbeChangeP3(v, 3 + flags, iDb); /* Configure the number of columns. Configure the cursor to ** think that the table has one more column than it really ** does. An OP_Column to retrieve this imaginary column will ** always return an SQL NULL. This is useful because it means ** we can invoke OP_Column to fill in the vdbe cursors type ** and offset cache without causing any IO. */ sqlite3VdbeChangeP4(v, 3+flags, SQLITE_INT_TO_PTR(pTab->nCol+1),P4_INT32); sqlite3VdbeChangeP2(v, 7, pTab->nCol); if( !db->mallocFailed ){ sqlite3VdbeMakeReady(v, 1, 1, 1, 0); } } sqlite3BtreeLeaveAll(db); rc = sqlite3SafetyOff(db); if( NEVER(rc!=SQLITE_OK) || db->mallocFailed ){ goto blob_open_out; } sqlite3_bind_int64((sqlite3_stmt *)v, 1, iRow); rc = sqlite3_step((sqlite3_stmt *)v); if( rc!=SQLITE_ROW ){ nAttempt++; rc = sqlite3_finalize((sqlite3_stmt *)v); sqlite3DbFree(db, zErr); zErr = sqlite3MPrintf(db, sqlite3_errmsg(db)); v = 0; } } while( nAttempt<5 && rc==SQLITE_SCHEMA ); if( rc==SQLITE_ROW ){ /* The row-record has been opened successfully. Check that the ** column in question contains text or a blob. If it contains ** text, it is up to the caller to get the encoding right. */ Incrblob *pBlob; u32 type = v->apCsr[0]->aType[iCol]; if( type<12 ){ sqlite3DbFree(db, zErr); zErr = sqlite3MPrintf(db, "cannot open value of type %s", type==0?"null": type==7?"real": "integer" ); rc = SQLITE_ERROR; goto blob_open_out; } pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob)); if( db->mallocFailed ){ sqlite3DbFree(db, pBlob); goto blob_open_out; } pBlob->flags = flags; pBlob->pCsr = v->apCsr[0]->pCursor; sqlite3BtreeEnterCursor(pBlob->pCsr); sqlite3BtreeCacheOverflow(pBlob->pCsr); sqlite3BtreeLeaveCursor(pBlob->pCsr); pBlob->pStmt = (sqlite3_stmt *)v; pBlob->iOffset = v->apCsr[0]->aOffset[iCol]; pBlob->nByte = sqlite3VdbeSerialTypeLen(type); pBlob->db = db; *ppBlob = (sqlite3_blob *)pBlob; rc = SQLITE_OK; }else if( rc==SQLITE_OK ){ sqlite3DbFree(db, zErr); zErr = sqlite3MPrintf(db, "no such rowid: %lld", iRow); rc = SQLITE_ERROR; } blob_open_out: if( v && (rc!=SQLITE_OK || db->mallocFailed) ){ sqlite3VdbeFinalize(v); } sqlite3Error(db, rc, zErr); sqlite3DbFree(db, zErr); sqlite3StackFree(db, pParse); rc = sqlite3ApiExit(db, rc); sqlite3_mutex_leave(db->mutex); return rc; }
/* ** An SQL user-function registered to do the work of an ATTACH statement. The ** three arguments to the function come directly from an attach statement: ** ** ATTACH DATABASE x AS y KEY z ** ** SELECT sqlite_attach(x, y, z) ** ** If the optional "KEY z" syntax is omitted, an SQL NULL is passed as the ** third argument. */ static void attachFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ int i; int rc = 0; sqlite3 *db = sqlite3_user_data(context); const char *zName; const char *zFile; Db *aNew; char zErr[128]; char *zErrDyn = 0; zFile = (const char *)sqlite3_value_text(argv[0]); zName = (const char *)sqlite3_value_text(argv[1]); /* Check for the following errors: ** ** * Too many attached databases, ** * Transaction currently open ** * Specified database name already being used. */ if( db->nDb>=MAX_ATTACHED+2 ){ sqlite3_snprintf( 127, zErr, "too many attached databases - max %d", MAX_ATTACHED ); goto attach_error; } if( !db->autoCommit ){ strcpy(zErr, "cannot ATTACH database within transaction"); goto attach_error; } for(i=0; i<db->nDb; i++){ char *z = db->aDb[i].zName; if( z && sqlite3StrICmp(z, zName)==0 ){ sqlite3_snprintf(127, zErr, "database %s is already in use", zName); goto attach_error; } } /* Allocate the new entry in the db->aDb[] array and initialise the schema ** hash tables. */ if( db->aDb==db->aDbStatic ){ aNew = sqliteMalloc( sizeof(db->aDb[0])*3 ); if( aNew==0 ){ return; } memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2); }else{ aNew = sqliteRealloc(db->aDb, sizeof(db->aDb[0])*(db->nDb+1) ); if( aNew==0 ){ return; } } db->aDb = aNew; aNew = &db->aDb[db->nDb++]; memset(aNew, 0, sizeof(*aNew)); /* Open the database file. If the btree is successfully opened, use ** it to obtain the database schema. At this point the schema may ** or may not be initialised. */ rc = sqlite3BtreeFactory(db, zFile, 0, MAX_PAGES, &aNew->pBt); if( rc==SQLITE_OK ){ aNew->pSchema = sqlite3SchemaGet(aNew->pBt); if( !aNew->pSchema ){ rc = SQLITE_NOMEM; }else if( aNew->pSchema->file_format && aNew->pSchema->enc!=ENC(db) ){ strcpy(zErr, "attached databases must use the same text encoding as main database"); goto attach_error; } } aNew->zName = sqliteStrDup(zName); aNew->safety_level = 3; #if SQLITE_HAS_CODEC { extern int sqlite3CodecAttach(sqlite3*, int, void*, int); extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*); int nKey; char *zKey; int t = sqlite3_value_type(argv[2]); switch( t ){ case SQLITE_INTEGER: case SQLITE_FLOAT: zErrDyn = sqliteStrDup("Invalid key value"); rc = SQLITE_ERROR; break; case SQLITE_TEXT: case SQLITE_BLOB: nKey = sqlite3_value_bytes(argv[2]); zKey = (char *)sqlite3_value_blob(argv[2]); sqlite3CodecAttach(db, db->nDb-1, zKey, nKey); break; case SQLITE_NULL: /* No key specified. Use the key from the main database */ sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey); sqlite3CodecAttach(db, db->nDb-1, zKey, nKey); break; } } #endif /* If the file was opened successfully, read the schema for the new database. ** If this fails, or if opening the file failed, then close the file and ** remove the entry from the db->aDb[] array. i.e. put everything back the way ** we found it. */ if( rc==SQLITE_OK ){ sqlite3SafetyOn(db); rc = sqlite3Init(db, &zErrDyn); sqlite3SafetyOff(db); } if( rc ){ int i = db->nDb - 1; assert( i>=2 ); if( db->aDb[i].pBt ){ sqlite3BtreeClose(db->aDb[i].pBt); db->aDb[i].pBt = 0; db->aDb[i].pSchema = 0; } sqlite3ResetInternalSchema(db, 0); db->nDb = i; sqlite3_snprintf(127, zErr, "unable to open database: %s", zFile); goto attach_error; } return; attach_error: /* Return an error if we get here */ if( zErrDyn ){ sqlite3_result_error(context, zErrDyn, -1); sqliteFree(zErrDyn); }else{ zErr[sizeof(zErr)-1] = 0; sqlite3_result_error(context, zErr, -1); } }
/* ** Compile the UTF-8 encoded SQL statement zSql into a statement handle. */ static int sqlite3Prepare( sqlite3 *db, /* Database handle. */ const char *zSql, /* UTF-8 encoded SQL statement. */ int nBytes, /* Length of zSql in bytes. */ int saveSqlFlag, /* True to copy SQL text into the sqlite3_stmt */ sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ const char **pzTail /* OUT: End of parsed string */ ){ Parse sParse; char *zErrMsg = 0; int rc = SQLITE_OK; int i; assert( ppStmt ); *ppStmt = 0; if( sqlite3SafetyOn(db) ){ return SQLITE_MISUSE; } assert( !db->mallocFailed ); assert( sqlite3_mutex_held(db->mutex) ); /* Check to verify that it is possible to get a read lock on all ** database schemas. The inability to get a read lock indicates that ** some other database connection is holding a write-lock, which in ** turn means that the other connection has made uncommitted changes ** to the schema. ** ** Were we to proceed and prepare the statement against the uncommitted ** schema changes and if those schema changes are subsequently rolled ** back and different changes are made in their place, then when this ** prepared statement goes to run the schema cookie would fail to detect ** the schema change. Disaster would follow. ** ** This thread is currently holding mutexes on all Btrees (because ** of the sqlite3BtreeEnterAll() in sqlite3LockAndPrepare()) so it ** is not possible for another thread to start a new schema change ** while this routine is running. Hence, we do not need to hold ** locks on the schema, we just need to make sure nobody else is ** holding them. ** ** Note that setting READ_UNCOMMITTED overrides most lock detection, ** but it does *not* override schema lock detection, so this all still ** works even if READ_UNCOMMITTED is set. */ for(i=0; i<db->nDb; i++) { Btree *pBt = db->aDb[i].pBt; if( pBt ){ assert( sqlite3BtreeHoldsMutex(pBt) ); rc = sqlite3BtreeSchemaLocked(pBt); if( rc ){ const char *zDb = db->aDb[i].zName; sqlite3Error(db, rc, "database schema is locked: %s", zDb); (void)sqlite3SafetyOff(db); testcase( db->flags & SQLITE_ReadUncommitted ); return sqlite3ApiExit(db, rc); } } } memset(&sParse, 0, sizeof(sParse)); sParse.db = db; if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){ char *zSqlCopy; int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH]; if( nBytes>mxLen ){ sqlite3Error(db, SQLITE_TOOBIG, "statement too long"); (void)sqlite3SafetyOff(db); return sqlite3ApiExit(db, SQLITE_TOOBIG); } zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes); if( zSqlCopy ){ sqlite3RunParser(&sParse, zSqlCopy, &zErrMsg); sqlite3DbFree(db, zSqlCopy); sParse.zTail = &zSql[sParse.zTail-zSqlCopy]; }else{ sParse.zTail = &zSql[nBytes]; } }else{ sqlite3RunParser(&sParse, zSql, &zErrMsg); } if( db->mallocFailed ){ sParse.rc = SQLITE_NOMEM; } if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK; if( sParse.checkSchema && !schemaIsValid(db) ){ sParse.rc = SQLITE_SCHEMA; } if( sParse.rc==SQLITE_SCHEMA ){ sqlite3ResetInternalSchema(db, 0); } if( db->mallocFailed ){ sParse.rc = SQLITE_NOMEM; } if( pzTail ){ *pzTail = sParse.zTail; } rc = sParse.rc; #ifndef SQLITE_OMIT_EXPLAIN if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){ if( sParse.explain==2 ){ sqlite3VdbeSetNumCols(sParse.pVdbe, 3); sqlite3VdbeSetColName(sParse.pVdbe, 0, COLNAME_NAME, "order", SQLITE_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 1, COLNAME_NAME, "from", SQLITE_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 2, COLNAME_NAME, "detail", SQLITE_STATIC); }else{ sqlite3VdbeSetNumCols(sParse.pVdbe, 8); sqlite3VdbeSetColName(sParse.pVdbe, 0, COLNAME_NAME, "addr", SQLITE_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 1, COLNAME_NAME, "opcode", SQLITE_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 2, COLNAME_NAME, "p1", SQLITE_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 3, COLNAME_NAME, "p2", SQLITE_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 4, COLNAME_NAME, "p3", SQLITE_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 5, COLNAME_NAME, "p4", SQLITE_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 6, COLNAME_NAME, "p5", SQLITE_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 7, COLNAME_NAME, "comment", SQLITE_STATIC); } } #endif if( sqlite3SafetyOff(db) ){ rc = SQLITE_MISUSE; } assert( db->init.busy==0 || saveSqlFlag==0 ); if( db->init.busy==0 ){ Vdbe *pVdbe = sParse.pVdbe; sqlite3VdbeSetSql(pVdbe, zSql, (int)(sParse.zTail-zSql), saveSqlFlag); } if( sParse.pVdbe && (rc!=SQLITE_OK || db->mallocFailed) ){ sqlite3VdbeFinalize(sParse.pVdbe); assert(!(*ppStmt)); }else{ *ppStmt = (sqlite3_stmt*)sParse.pVdbe; } if( zErrMsg ){ sqlite3Error(db, rc, "%s", zErrMsg); sqlite3DbFree(db, zErrMsg); }else{ sqlite3Error(db, rc, 0); } rc = sqlite3ApiExit(db, rc); assert( (rc&db->errMask)==rc ); return rc; }
/* ** Close an existing SQLite database */ EXPORT_C int sqlite3_close(sqlite3 *db){ HashElem *i; int j; if( !db ){ return SQLITE_OK; } if( sqlite3SafetyCheck(db) ){ return SQLITE_MISUSE; } sqlite3_mutex_enter(db->mutex); #ifdef SQLITE_SSE { extern void sqlite3SseCleanup(sqlite3*); sqlite3SseCleanup(db); } #endif sqlite3ResetInternalSchema(db, 0); /* If a transaction is open, the ResetInternalSchema() call above ** will not have called the xDisconnect() method on any virtual ** tables in the db->aVTrans[] array. The following sqlite3VtabRollback() ** call will do so. We need to do this before the check for active ** SQL statements below, as the v-table implementation may be storing ** some prepared statements internally. */ sqlite3VtabRollback(db); /* If there are any outstanding VMs, return SQLITE_BUSY. */ if( db->pVdbe ){ sqlite3Error(db, SQLITE_BUSY, "Unable to close due to unfinalised statements"); sqlite3_mutex_leave(db->mutex); return SQLITE_BUSY; } assert( !sqlite3SafetyCheck(db) ); /* FIX ME: db->magic may be set to SQLITE_MAGIC_CLOSED if the database ** cannot be opened for some reason. So this routine needs to run in ** that case. But maybe there should be an extra magic value for the ** "failed to open" state. ** ** TODO: Coverage tests do not test the case where this condition is ** true. It's hard to see how to cause it without messing with threads. */ if( db->magic!=SQLITE_MAGIC_CLOSED && sqlite3SafetyOn(db) ){ /* printf("DID NOT CLOSE\n"); fflush(stdout); */ sqlite3_mutex_leave(db->mutex); return SQLITE_ERROR; } for(j=0; j<db->nDb; j++){ struct Db *pDb = &db->aDb[j]; if( pDb->pBt ){ sqlite3BtreeClose(pDb->pBt); pDb->pBt = 0; if( j!=1 ){ pDb->pSchema = 0; } } } sqlite3ResetInternalSchema(db, 0); assert( db->nDb<=2 ); assert( db->aDb==db->aDbStatic ); for(i=sqliteHashFirst(&db->aFunc); i; i=sqliteHashNext(i)){ FuncDef *pFunc, *pNext; for(pFunc = (FuncDef*)sqliteHashData(i); pFunc; pFunc=pNext){ pNext = pFunc->pNext; sqlite3_free(pFunc); } } for(i=sqliteHashFirst(&db->aCollSeq); i; i=sqliteHashNext(i)){ CollSeq *pColl = (CollSeq *)sqliteHashData(i); /* Invoke any destructors registered for collation sequence user data. */ for(j=0; j<3; j++){ if( pColl[j].xDel ){ pColl[j].xDel(pColl[j].pUser); } } sqlite3_free(pColl); } sqlite3HashClear(&db->aCollSeq); #ifndef SQLITE_OMIT_VIRTUALTABLE for(i=sqliteHashFirst(&db->aModule); i; i=sqliteHashNext(i)){ Module *pMod = (Module *)sqliteHashData(i); if( pMod->xDestroy ){ pMod->xDestroy(pMod->pAux); } sqlite3_free(pMod); } sqlite3HashClear(&db->aModule); #endif sqlite3HashClear(&db->aFunc); sqlite3Error(db, SQLITE_OK, 0); /* Deallocates any cached error strings. */ if( db->pErr ){ sqlite3ValueFree(db->pErr); } sqlite3CloseExtensions(db); db->magic = SQLITE_MAGIC_ERROR; /* The temp-database schema is allocated differently from the other schema ** objects (using sqliteMalloc() directly, instead of sqlite3BtreeSchema()). ** So it needs to be freed here. Todo: Why not roll the temp schema into ** the same sqliteMalloc() as the one that allocates the database ** structure? */ sqlite3_free(db->aDb[1].pSchema); sqlite3_mutex_leave(db->mutex); sqlite3_mutex_free(db->mutex); sqlite3_free(db); return SQLITE_OK; }
/* ** Compile the UTF-8 encoded SQL statement zSql into a statement handle. */ int sqlite3_prepare( sqlite3 *db, /* Database handle. */ const char *zSql, /* UTF-8 encoded SQL statement. */ int nBytes, /* Length of zSql in bytes. */ sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ const char** pzTail /* OUT: End of parsed string */ ){ Parse sParse; char *zErrMsg = 0; int rc = SQLITE_OK; if( sqlite3_malloc_failed ){ return SQLITE_NOMEM; } assert( ppStmt ); *ppStmt = 0; if( sqlite3SafetyOn(db) ){ return SQLITE_MISUSE; } memset(&sParse, 0, sizeof(sParse)); sParse.db = db; sqlite3RunParser(&sParse, zSql, &zErrMsg); if( sqlite3_malloc_failed ){ rc = SQLITE_NOMEM; sqlite3RollbackAll(db); sqlite3ResetInternalSchema(db, 0); db->flags &= ~SQLITE_InTrans; goto prepare_out; } if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK; if( sParse.rc!=SQLITE_OK && sParse.checkSchema && !schemaIsValid(db) ){ sParse.rc = SQLITE_SCHEMA; } if( sParse.rc==SQLITE_SCHEMA ){ sqlite3ResetInternalSchema(db, 0); } if( pzTail ) *pzTail = sParse.zTail; rc = sParse.rc; #ifndef SQLITE_OMIT_EXPLAIN if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){ sqlite3VdbeSetNumCols(sParse.pVdbe, 5); sqlite3VdbeSetColName(sParse.pVdbe, 0, "addr", P3_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 1, "opcode", P3_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 2, "p1", P3_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 3, "p2", P3_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 4, "p3", P3_STATIC); } #endif prepare_out: if( sqlite3SafetyOff(db) ){ rc = SQLITE_MISUSE; } if( rc==SQLITE_OK ){ *ppStmt = (sqlite3_stmt*)sParse.pVdbe; }else if( sParse.pVdbe ){ sqlite3_finalize((sqlite3_stmt*)sParse.pVdbe); } if( zErrMsg ){ sqlite3Error(db, rc, "%s", zErrMsg); sqliteFree(zErrMsg); }else{ sqlite3Error(db, rc, 0); } return rc; }
/* ** Invoke a virtual table constructor (either xCreate or xConnect). The ** pointer to the function to invoke is passed as the fourth parameter ** to this procedure. */ static int vtabCallConstructor( sqlite3 *db, Table *pTab, Module *pMod, int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**), char **pzErr ){ VTable *pVTable; int rc; const char *const*azArg = (const char *const*)pTab->azModuleArg; int nArg = pTab->nModuleArg; char *zErr = 0; char *zModuleName = sqlite3MPrintf(db, "%s", pTab->zName); if( !zModuleName ){ return SQLITE_NOMEM; } pVTable = sqlite3DbMallocZero(db, sizeof(VTable)); if( !pVTable ){ sqlite3DbFree(db, zModuleName); return SQLITE_NOMEM; } pVTable->db = db; pVTable->pMod = pMod; assert( !db->pVTab ); assert( xConstruct ); db->pVTab = pTab; /* Invoke the virtual table constructor */ (void)sqlite3SafetyOff(db); rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr); (void)sqlite3SafetyOn(db); if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; if( SQLITE_OK!=rc ){ if( zErr==0 ){ *pzErr = sqlite3MPrintf(db, "vtable constructor failed: %s", zModuleName); }else { *pzErr = sqlite3MPrintf(db, "%s", zErr); sqlite3DbFree(db, zErr); } sqlite3DbFree(db, pVTable); }else if( ALWAYS(pVTable->pVtab) ){ /* Justification of ALWAYS(): A correct vtab constructor must allocate ** the sqlite3_vtab object if successful. */ pVTable->pVtab->pModule = pMod->pModule; pVTable->nRef = 1; if( db->pVTab ){ const char *zFormat = "vtable constructor did not declare schema: %s"; *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName); sqlite3VtabUnlock(pVTable); rc = SQLITE_ERROR; }else{ int iCol; /* If everything went according to plan, link the new VTable structure ** into the linked list headed by pTab->pVTable. Then loop through the ** columns of the table to see if any of them contain the token "hidden". ** If so, set the Column.isHidden flag and remove the token from ** the type string. */ pVTable->pNext = pTab->pVTable; pTab->pVTable = pVTable; for(iCol=0; iCol<pTab->nCol; iCol++){ char *zType = pTab->aCol[iCol].zType; int nType; int i = 0; if( !zType ) continue; nType = sqlite3Strlen30(zType); if( sqlite3StrNICmp("hidden", zType, 6)||(zType[6] && zType[6]!=' ') ){ for(i=0; i<nType; i++){ if( (0==sqlite3StrNICmp(" hidden", &zType[i], 7)) && (zType[i+7]=='\0' || zType[i+7]==' ') ){ i++; break; } } } if( i<nType ){ int j; int nDel = 6 + (zType[i+6] ? 1 : 0); for(j=i; (j+nDel)<=nType; j++){ zType[j] = zType[j+nDel]; } if( zType[i]=='\0' && i>0 ){ assert(zType[i-1]==' '); zType[i-1] = '\0'; } pTab->aCol[iCol].isHidden = 1; } } } } sqlite3DbFree(db, zModuleName); db->pVTab = 0; return rc; }
/* ** Compile the UTF-8 encoded SQL statement zSql into a statement handle. */ int sqlite3Prepare( sqlite3 *db, /* Database handle. */ const char *zSql, /* UTF-8 encoded SQL statement. */ int nBytes, /* Length of zSql in bytes. */ int saveSqlFlag, /* True to copy SQL text into the sqlite3_stmt */ sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ const char **pzTail /* OUT: End of parsed string */ ){ Parse sParse; char *zErrMsg = 0; int rc = SQLITE_OK; int i; /* Assert that malloc() has not failed */ assert( !sqlite3MallocFailed() ); assert( ppStmt ); *ppStmt = 0; if( sqlite3SafetyOn(db) ){ return SQLITE_MISUSE; } /* If any attached database schemas are locked, do not proceed with ** compilation. Instead return SQLITE_LOCKED immediately. */ for(i=0; i<db->nDb; i++) { Btree *pBt = db->aDb[i].pBt; if( pBt && sqlite3BtreeSchemaLocked(pBt) ){ const char *zDb = db->aDb[i].zName; sqlite3Error(db, SQLITE_LOCKED, "database schema is locked: %s", zDb); sqlite3SafetyOff(db); return SQLITE_LOCKED; } } memset(&sParse, 0, sizeof(sParse)); sParse.db = db; if( nBytes>=0 && zSql[nBytes]!=0 ){ char *zSqlCopy = sqlite3StrNDup(zSql, nBytes); sqlite3RunParser(&sParse, zSqlCopy, &zErrMsg); sParse.zTail += zSql - zSqlCopy; sqliteFree(zSqlCopy); }else{ sqlite3RunParser(&sParse, zSql, &zErrMsg); } if( sqlite3MallocFailed() ){ sParse.rc = SQLITE_NOMEM; } if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK; if( sParse.checkSchema && !schemaIsValid(db) ){ sParse.rc = SQLITE_SCHEMA; } if( sParse.rc==SQLITE_SCHEMA ){ sqlite3ResetInternalSchema(db, 0); } if( sqlite3MallocFailed() ){ sParse.rc = SQLITE_NOMEM; } if( pzTail ){ *pzTail = sParse.zTail; } rc = sParse.rc; #ifndef SQLITE_OMIT_EXPLAIN if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){ if( sParse.explain==2 ){ sqlite3VdbeSetNumCols(sParse.pVdbe, 3); sqlite3VdbeSetColName(sParse.pVdbe, 0, COLNAME_NAME, "order", P3_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 1, COLNAME_NAME, "from", P3_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 2, COLNAME_NAME, "detail", P3_STATIC); }else{ sqlite3VdbeSetNumCols(sParse.pVdbe, 5); sqlite3VdbeSetColName(sParse.pVdbe, 0, COLNAME_NAME, "addr", P3_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 1, COLNAME_NAME, "opcode", P3_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 2, COLNAME_NAME, "p1", P3_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 3, COLNAME_NAME, "p2", P3_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 4, COLNAME_NAME, "p3", P3_STATIC); } } #endif if( sqlite3SafetyOff(db) ){ rc = SQLITE_MISUSE; } if( rc==SQLITE_OK ){ if( saveSqlFlag ){ sqlite3VdbeSetSql(sParse.pVdbe, zSql, sParse.zTail - zSql); } *ppStmt = (sqlite3_stmt*)sParse.pVdbe; }else if( sParse.pVdbe ){ sqlite3_finalize((sqlite3_stmt*)sParse.pVdbe); } if( zErrMsg ){ sqlite3Error(db, rc, "%s", zErrMsg); sqliteFree(zErrMsg); }else{ sqlite3Error(db, rc, 0); } rc = sqlite3ApiExit(db, rc); sqlite3ReleaseThreadData(); assert( (rc&db->errMask)==rc ); return rc; }
/* ** Close an existing SQLite database */ int sqlite3_close(sqlite3 *db){ HashElem *i; int j; if( !db ){ return SQLITE_OK; } if( sqlite3SafetyCheck(db) ){ return SQLITE_MISUSE; } #ifdef SQLITE_SSE sqlite3_finalize(db->pFetch); #endif /* If there are any outstanding VMs, return SQLITE_BUSY. */ if( db->pVdbe ){ sqlite3Error(db, SQLITE_BUSY, "Unable to close due to unfinalised statements"); return SQLITE_BUSY; } assert( !sqlite3SafetyCheck(db) ); /* FIX ME: db->magic may be set to SQLITE_MAGIC_CLOSED if the database ** cannot be opened for some reason. So this routine needs to run in ** that case. But maybe there should be an extra magic value for the ** "failed to open" state. */ if( db->magic!=SQLITE_MAGIC_CLOSED && sqlite3SafetyOn(db) ){ /* printf("DID NOT CLOSE\n"); fflush(stdout); */ return SQLITE_ERROR; } for(j=0; j<db->nDb; j++){ struct Db *pDb = &db->aDb[j]; if( pDb->pBt ){ sqlite3BtreeClose(pDb->pBt); pDb->pBt = 0; } } sqlite3ResetInternalSchema(db, 0); assert( db->nDb<=2 ); assert( db->aDb==db->aDbStatic ); for(i=sqliteHashFirst(&db->aFunc); i; i=sqliteHashNext(i)){ FuncDef *pFunc, *pNext; for(pFunc = (FuncDef*)sqliteHashData(i); pFunc; pFunc=pNext){ pNext = pFunc->pNext; sqliteFree(pFunc); } } for(i=sqliteHashFirst(&db->aCollSeq); i; i=sqliteHashNext(i)){ CollSeq *pColl = (CollSeq *)sqliteHashData(i); sqliteFree(pColl); } sqlite3HashClear(&db->aCollSeq); sqlite3HashClear(&db->aFunc); sqlite3Error(db, SQLITE_OK, 0); /* Deallocates any cached error strings. */ if( db->pValue ){ sqlite3ValueFree(db->pValue); } if( db->pErr ){ sqlite3ValueFree(db->pErr); } #ifndef SQLITE_OMIT_GLOBALRECOVER { sqlite3 *pPrev; sqlite3OsEnterMutex(); pPrev = pDbList; while( pPrev && pPrev->pNext!=db ){ pPrev = pPrev->pNext; } if( pPrev ){ pPrev->pNext = db->pNext; }else{ assert( pDbList==db ); pDbList = db->pNext; } sqlite3OsLeaveMutex(); } #endif db->magic = SQLITE_MAGIC_ERROR; sqliteFree(db); return SQLITE_OK; }
/* ** Execute the statement pStmt, either until a row of data is ready, the ** statement is completely executed or an error occurs. ** ** This routine implements the bulk of the logic behind the sqlite_step() ** API. The only thing omitted is the automatic recompile if a ** schema change has occurred. That detail is handled by the ** outer sqlite3_step() wrapper procedure. */ static int sqlite3Step(Vdbe *p){ sqlite3 *db; int rc; assert(p); if( p->magic!=VDBE_MAGIC_RUN ){ return SQLITE_MISUSE; } /* Assert that malloc() has not failed */ db = p->db; if( db->mallocFailed ){ return SQLITE_NOMEM; } if( p->pc<=0 && p->expired ){ if( p->rc==SQLITE_OK ){ p->rc = SQLITE_SCHEMA; } rc = SQLITE_ERROR; goto end_of_step; } if( sqlite3SafetyOn(db) ){ p->rc = SQLITE_MISUSE; return SQLITE_MISUSE; } if( p->pc<0 ){ /* If there are no other statements currently running, then ** reset the interrupt flag. This prevents a call to sqlite3_interrupt ** from interrupting a statement that has not yet started. */ if( db->activeVdbeCnt==0 ){ db->u1.isInterrupted = 0; } #ifndef SQLITE_OMIT_TRACE if( db->xProfile && !db->init.busy ){ double rNow; sqlite3OsCurrentTime(db->pVfs, &rNow); p->startTime = (rNow - (int)rNow)*3600.0*24.0*1000000000.0; } #endif db->activeVdbeCnt++; p->pc = 0; stmtLruRemove(p); } #ifndef SQLITE_OMIT_EXPLAIN if( p->explain ){ rc = sqlite3VdbeList(p); }else #endif /* SQLITE_OMIT_EXPLAIN */ { rc = sqlite3VdbeExec(p); } if( sqlite3SafetyOff(db) ){ rc = SQLITE_MISUSE; } #ifndef SQLITE_OMIT_TRACE /* Invoke the profile callback if there is one */ if( rc!=SQLITE_ROW && db->xProfile && !db->init.busy && p->nOp>0 && p->aOp[0].opcode==OP_Trace && p->aOp[0].p4.z!=0 ){ double rNow; u64 elapseTime; sqlite3OsCurrentTime(db->pVfs, &rNow); elapseTime = (rNow - (int)rNow)*3600.0*24.0*1000000000.0 - p->startTime; db->xProfile(db->pProfileArg, p->aOp[0].p4.z, elapseTime); } #endif db->errCode = rc; /*sqlite3Error(p->db, rc, 0);*/ p->rc = sqlite3ApiExit(p->db, p->rc); end_of_step: assert( (rc&0xff)==rc ); if( p->zSql && (rc&0xff)<SQLITE_ROW ){ /* This behavior occurs if sqlite3_prepare_v2() was used to build ** the prepared statement. Return error codes directly */ p->db->errCode = p->rc; /* sqlite3Error(p->db, p->rc, 0); */ return p->rc; }else{ /* This is for legacy sqlite3_prepare() builds and when the code ** is SQLITE_ROW or SQLITE_DONE */ return rc; } }
/* ** Close an existing SQLite database */ int sqlite3_close(sqlite3 *db){ HashElem *i; int j; if( !db ){ return SQLITE_OK; } if( sqlite3SafetyCheck(db) ){ return SQLITE_MISUSE; } #ifdef SQLITE_SSE sqlite3_finalize(db->pFetch); #endif /* If there are any outstanding VMs, return SQLITE_BUSY. */ if( db->pVdbe ){ sqlite3Error(db, SQLITE_BUSY, "Unable to close due to unfinalised statements"); return SQLITE_BUSY; } assert( !sqlite3SafetyCheck(db) ); /* FIX ME: db->magic may be set to SQLITE_MAGIC_CLOSED if the database ** cannot be opened for some reason. So this routine needs to run in ** that case. But maybe there should be an extra magic value for the ** "failed to open" state. */ if( db->magic!=SQLITE_MAGIC_CLOSED && sqlite3SafetyOn(db) ){ /* printf("DID NOT CLOSE\n"); fflush(stdout); */ return SQLITE_ERROR; } for(j=0; j<db->nDb; j++){ struct Db *pDb = &db->aDb[j]; if( pDb->pBt ){ sqlite3BtreeClose(pDb->pBt); pDb->pBt = 0; if( j!=1 ){ pDb->pSchema = 0; } } } sqlite3ResetInternalSchema(db, 0); assert( db->nDb<=2 ); assert( db->aDb==db->aDbStatic ); for(i=sqliteHashFirst(&db->aFunc); i; i=sqliteHashNext(i)){ FuncDef *pFunc, *pNext; for(pFunc = (FuncDef*)sqliteHashData(i); pFunc; pFunc=pNext){ pNext = pFunc->pNext; sqliteFree(pFunc); } } for(i=sqliteHashFirst(&db->aCollSeq); i; i=sqliteHashNext(i)){ CollSeq *pColl = (CollSeq *)sqliteHashData(i); sqliteFree(pColl); } sqlite3HashClear(&db->aCollSeq); sqlite3HashClear(&db->aFunc); sqlite3Error(db, SQLITE_OK, 0); /* Deallocates any cached error strings. */ if( db->pErr ){ sqlite3ValueFree(db->pErr); } db->magic = SQLITE_MAGIC_ERROR; /* The temp-database schema is allocated differently from the other schema ** objects (using sqliteMalloc() directly, instead of sqlite3BtreeSchema()). ** So it needs to be freed here. Todo: Why not roll the temp schema into ** the same sqliteMalloc() as the one that allocates the database ** structure? */ sqliteFree(db->aDb[1].pSchema); sqliteFree(db); sqlite3ReleaseThreadData(); return SQLITE_OK; }
int sqlite3_table_column_metadata( sqlite3 *db, /* Connection handle */ const char *zDbName, /* Database name or NULL */ const char *zTableName, /* Table name */ const char *zColumnName, /* Column name */ char const **pzDataType, /* OUTPUT: Declared data type */ char const **pzCollSeq, /* OUTPUT: Collation sequence name */ int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */ int *pPrimaryKey, /* OUTPUT: True if column part of PK */ int *pAutoinc /* OUTPUT: True if colums is auto-increment */ ){ int rc; char *zErrMsg = 0; Table *pTab = 0; Column *pCol = 0; int iCol; char const *zDataType = 0; char const *zCollSeq = 0; int notnull = 0; int primarykey = 0; int autoinc = 0; /* Ensure the database schema has been loaded */ if( sqlite3SafetyOn(db) ){ return SQLITE_MISUSE; } rc = sqlite3Init(db, &zErrMsg); if( SQLITE_OK!=rc ){ goto error_out; } /* Locate the table in question */ pTab = sqlite3FindTable(db, zTableName, zDbName); if( !pTab || pTab->pSelect ){ pTab = 0; goto error_out; } /* Find the column for which info is requested */ if( sqlite3IsRowid(zColumnName) ){ iCol = pTab->iPKey; if( iCol>=0 ){ pCol = &pTab->aCol[iCol]; } }else{ for(iCol=0; iCol<pTab->nCol; iCol++){ pCol = &pTab->aCol[iCol]; if( 0==sqlite3StrICmp(pCol->zName, zColumnName) ){ break; } } if( iCol==pTab->nCol ){ pTab = 0; goto error_out; } } /* The following block stores the meta information that will be returned ** to the caller in local variables zDataType, zCollSeq, notnull, primarykey ** and autoinc. At this point there are two possibilities: ** ** 1. The specified column name was rowid", "oid" or "_rowid_" ** and there is no explicitly declared IPK column. ** ** 2. The table is not a view and the column name identified an ** explicitly declared column. Copy meta information from *pCol. */ if( pCol ){ zDataType = pCol->zType; zCollSeq = pCol->zColl; notnull = (pCol->notNull?1:0); primarykey = (pCol->isPrimKey?1:0); autoinc = ((pTab->iPKey==iCol && pTab->autoInc)?1:0); }else{ zDataType = "INTEGER"; primarykey = 1; } if( !zCollSeq ){ zCollSeq = "BINARY"; } error_out: if( sqlite3SafetyOff(db) ){ rc = SQLITE_MISUSE; } /* Whether the function call succeeded or failed, set the output parameters ** to whatever their local counterparts contain. If an error did occur, ** this has the effect of zeroing all output parameters. */ if( pzDataType ) *pzDataType = zDataType; if( pzCollSeq ) *pzCollSeq = zCollSeq; if( pNotNull ) *pNotNull = notnull; if( pPrimaryKey ) *pPrimaryKey = primarykey; if( pAutoinc ) *pAutoinc = autoinc; if( SQLITE_OK==rc && !pTab ){ sqlite3SetString(&zErrMsg, "no such table column: ", zTableName, ".", zColumnName, 0); rc = SQLITE_ERROR; } sqlite3Error(db, rc, (zErrMsg?"%s":0), zErrMsg); sqliteFree(zErrMsg); return sqlite3ApiExit(db, rc); }
/* ** Attempt to read the database schema and initialize internal ** data structures for a single database file. The index of the ** database file is given by iDb. iDb==0 is used for the main ** database. iDb==1 should never be used. iDb>=2 is used for ** auxiliary databases. Return one of the SQLITE_ error codes to ** indicate success or failure. */ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ int rc; BtCursor *curMain; int size; Table *pTab; Db *pDb; char const *azArg[4]; int meta[10]; InitData initData; char const *zMasterSchema; char const *zMasterName = SCHEMA_TABLE(iDb); /* ** 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 ** initialised. 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; azArg[1] = "1"; azArg[2] = zMasterSchema; azArg[3] = 0; initData.db = db; initData.iDb = iDb; initData.rc = SQLITE_OK; initData.pzErrMsg = pzErrMsg; (void)sqlite3SafetyOff(db); sqlite3InitCallback(&initData, 3, (char **)azArg, 0); (void)sqlite3SafetyOn(db); if( initData.rc ){ rc = initData.rc; goto error_out; } pTab = sqlite3FindTable(db, zMasterName, db->aDb[iDb].zName); if( pTab ){ pTab->tabFlags |= TF_Readonly; } /* Create a cursor to hold the database open */ pDb = &db->aDb[iDb]; if( pDb->pBt==0 ){ if( !OMIT_TEMPDB && iDb==1 ){ DbSetProperty(db, 1, DB_SchemaLoaded); } return SQLITE_OK; } curMain = sqlite3MallocZero(sqlite3BtreeCursorSize()); if( !curMain ){ rc = SQLITE_NOMEM; goto error_out; } sqlite3BtreeEnter(pDb->pBt); rc = sqlite3BtreeCursor(pDb->pBt, MASTER_ROOT, 0, 0, curMain); if( rc!=SQLITE_OK && rc!=SQLITE_EMPTY ){ sqlite3SetString(pzErrMsg, db, "%s", sqlite3ErrStr(rc)); goto initone_error_out; } /* Get the database meta information. ** ** Meta values are as follows: ** meta[0] Schema cookie. Changes with each schema change. ** meta[1] File format of schema layer. ** meta[2] Size of the page cache. ** meta[3] Use freelist if 0. Autovacuum if greater than zero. ** meta[4] Db text encoding. 1:UTF-8 2:UTF-16LE 3:UTF-16BE ** meta[5] The user cookie. Used by the application. ** meta[6] Incremental-vacuum flag. ** meta[7] ** meta[8] ** meta[9] ** ** Note: The #defined SQLITE_UTF* symbols in sqliteInt.h correspond to ** the possible values of meta[4]. */ if( rc==SQLITE_OK ){ int i; for(i=0; i<ArraySize(meta); i++){ rc = sqlite3BtreeGetMeta(pDb->pBt, i+1, (u32 *)&meta[i]); if( rc ){ sqlite3SetString(pzErrMsg, db, "%s", sqlite3ErrStr(rc)); goto initone_error_out; } } }else{ memset(meta, 0, sizeof(meta)); } pDb->pSchema->schema_cookie = meta[0]; /* If opening a non-empty database, check the text encoding. For the ** main database, set sqlite3.enc to the encoding of the main database. ** For an attached db, it is an error if the encoding is not the same ** as sqlite3.enc. */ if( meta[4] ){ /* text encoding */ if( iDb==0 ){ /* If opening the main database, set ENC(db). */ ENC(db) = (u8)meta[4]; db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 6, 0); }else{ /* If opening an attached database, the encoding much match ENC(db) */ if( meta[4]!=ENC(db) ){ sqlite3SetString(pzErrMsg, db, "attached databases must use the same" " text encoding as main database"); rc = SQLITE_ERROR; goto initone_error_out; } } }else{ DbSetProperty(db, iDb, DB_Empty); } pDb->pSchema->enc = ENC(db); if( pDb->pSchema->cache_size==0 ){ size = meta[2]; if( size==0 ){ size = SQLITE_DEFAULT_CACHE_SIZE; } if( size<0 ) size = -size; pDb->pSchema->cache_size = size; sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); } /* ** file_format==1 Version 3.0.0. ** file_format==2 Version 3.1.3. // ALTER TABLE ADD COLUMN ** file_format==3 Version 3.1.4. // ditto but with non-NULL defaults ** file_format==4 Version 3.3.0. // DESC indices. Boolean constants */ pDb->pSchema->file_format = (u8)meta[1]; if( pDb->pSchema->file_format==0 ){ pDb->pSchema->file_format = 1; } if( pDb->pSchema->file_format>SQLITE_MAX_FILE_FORMAT ){ sqlite3SetString(pzErrMsg, db, "unsupported file format"); rc = SQLITE_ERROR; goto initone_error_out; } /* Ticket #2804: When we open a database in the newer file format, ** clear the legacy_file_format pragma flag so that a VACUUM will ** not downgrade the database and thus invalidate any descending ** indices that the user might have created. */ if( iDb==0 && meta[1]>=4 ){ db->flags &= ~SQLITE_LegacyFileFmt; } /* Read the schema information out of the schema tables */ assert( db->init.busy ); if( rc==SQLITE_EMPTY ){ /* For an empty database, there is nothing to read */ rc = SQLITE_OK; }else{ char *zSql; zSql = sqlite3MPrintf(db, "SELECT name, rootpage, sql FROM '%q'.%s", db->aDb[iDb].zName, zMasterName); (void)sqlite3SafetyOff(db); #ifndef SQLITE_OMIT_AUTHORIZATION { int (*xAuth)(void*,int,const char*,const char*,const char*,const char*); xAuth = db->xAuth; db->xAuth = 0; #endif rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); #ifndef SQLITE_OMIT_AUTHORIZATION db->xAuth = xAuth; } #endif if( rc==SQLITE_OK ) rc = initData.rc; (void)sqlite3SafetyOn(db); sqlite3DbFree(db, zSql); #ifndef SQLITE_OMIT_ANALYZE if( rc==SQLITE_OK ){ sqlite3AnalysisLoad(db, iDb); } #endif } if( db->mallocFailed ){ rc = SQLITE_NOMEM; sqlite3ResetInternalSchema(db, 0); } if( rc==SQLITE_OK || (db->flags&SQLITE_RecoveryMode)){ /* Black magic: If the SQLITE_RecoveryMode flag is set, then consider ** the schema loaded, even if errors occurred. In this situation the ** current sqlite3_prepare() operation will fail, but the following one ** will attempt to compile the supplied statement against whatever subset ** of the schema was loaded before the error occurred. The primary ** purpose of this is to allow access to the sqlite_master table ** even when its contents have been corrupted. */ DbSetProperty(db, iDb, DB_SchemaLoaded); rc = SQLITE_OK; } /* Jump here for an error that occurs after successfully allocating ** curMain and calling sqlite3BtreeEnter(). For an error that occurs ** before that point, jump to error_out. */ initone_error_out: sqlite3BtreeCloseCursor(curMain); sqlite3_free(curMain); sqlite3BtreeLeave(pDb->pBt); error_out: if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ db->mallocFailed = 1; } return rc; }
/* ** A read or write transaction may or may not be active on database handle ** db. If a transaction is active, commit it. If there is a ** write-transaction spanning more than one database file, this routine ** takes care of the master journal trickery. */ static int vdbeCommit(sqlite3 *db){ int i; int nTrans = 0; /* Number of databases with an active write-transaction */ int rc = SQLITE_OK; int needXcommit = 0; for(i=0; i<db->nDb; i++){ Btree *pBt = db->aDb[i].pBt; if( pBt && sqlite3BtreeIsInTrans(pBt) ){ needXcommit = 1; if( i!=1 ) nTrans++; } } /* If there are any write-transactions at all, invoke the commit hook */ if( needXcommit && db->xCommitCallback ){ int rc; sqlite3SafetyOff(db); rc = db->xCommitCallback(db->pCommitArg); sqlite3SafetyOn(db); if( rc ){ return SQLITE_CONSTRAINT; } } /* The simple case - no more than one database file (not counting the ** TEMP database) has a transaction active. There is no need for the ** master-journal. ** ** If the return value of sqlite3BtreeGetFilename() is a zero length ** string, it means the main database is :memory:. In that case we do ** not support atomic multi-file commits, so use the simple case then ** too. */ if( 0==strlen(sqlite3BtreeGetFilename(db->aDb[0].pBt)) || nTrans<=1 ){ for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ Btree *pBt = db->aDb[i].pBt; if( pBt ){ rc = sqlite3BtreeSync(pBt, 0); } } /* Do the commit only if all databases successfully synced */ if( rc==SQLITE_OK ){ for(i=0; i<db->nDb; i++){ Btree *pBt = db->aDb[i].pBt; if( pBt ){ sqlite3BtreeCommit(pBt); } } } } /* The complex case - There is a multi-file write-transaction active. ** This requires a master journal file to ensure the transaction is ** committed atomicly. */ else{ char *zMaster = 0; /* File-name for the master journal */ char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt); OsFile master; /* Select a master journal file name */ do { u32 random; sqliteFree(zMaster); sqlite3Randomness(sizeof(random), &random); zMaster = sqlite3MPrintf("%s-mj%08X", zMainFile, random&0x7fffffff); if( !zMaster ){ return SQLITE_NOMEM; } }while( sqlite3OsFileExists(zMaster) ); /* Open the master journal. */ memset(&master, 0, sizeof(master)); rc = sqlite3OsOpenExclusive(zMaster, &master, 0); if( rc!=SQLITE_OK ){ sqliteFree(zMaster); return rc; } /* Write the name of each database file in the transaction into the new ** master journal file. If an error occurs at this point close ** and delete the master journal file. All the individual journal files ** still have 'null' as the master journal pointer, so they will roll ** back independantly if a failure occurs. */ for(i=0; i<db->nDb; i++){ Btree *pBt = db->aDb[i].pBt; if( i==1 ) continue; /* Ignore the TEMP database */ if( pBt && sqlite3BtreeIsInTrans(pBt) ){ char const *zFile = sqlite3BtreeGetJournalname(pBt); if( zFile[0]==0 ) continue; /* Ignore :memory: databases */ rc = sqlite3OsWrite(&master, zFile, strlen(zFile)+1); if( rc!=SQLITE_OK ){ sqlite3OsClose(&master); sqlite3OsDelete(zMaster); sqliteFree(zMaster); return rc; } } } /* Sync the master journal file. Before doing this, open the directory ** the master journal file is store in so that it gets synced too. */ zMainFile = sqlite3BtreeGetDirname(db->aDb[0].pBt); rc = sqlite3OsOpenDirectory(zMainFile, &master); if( rc!=SQLITE_OK ){ sqlite3OsClose(&master); sqlite3OsDelete(zMaster); sqliteFree(zMaster); return rc; } rc = sqlite3OsSync(&master); if( rc!=SQLITE_OK ){ sqlite3OsClose(&master); sqliteFree(zMaster); return rc; } /* Sync all the db files involved in the transaction. The same call ** sets the master journal pointer in each individual journal. If ** an error occurs here, do not delete the master journal file. ** ** If the error occurs during the first call to sqlite3BtreeSync(), ** then there is a chance that the master journal file will be ** orphaned. But we cannot delete it, in case the master journal ** file name was written into the journal file before the failure ** occured. */ for(i=0; i<db->nDb; i++){ Btree *pBt = db->aDb[i].pBt; if( pBt && sqlite3BtreeIsInTrans(pBt) ){ rc = sqlite3BtreeSync(pBt, zMaster); if( rc!=SQLITE_OK ){ sqlite3OsClose(&master); sqliteFree(zMaster); return rc; } } } sqlite3OsClose(&master); /* Delete the master journal file. This commits the transaction. After ** doing this the directory is synced again before any individual ** transaction files are deleted. */ rc = sqlite3OsDelete(zMaster); assert( rc==SQLITE_OK ); sqliteFree(zMaster); zMaster = 0; rc = sqlite3OsSyncDirectory(zMainFile); if( rc!=SQLITE_OK ){ /* This is not good. The master journal file has been deleted, but ** the directory sync failed. There is no completely safe course of ** action from here. The individual journals contain the name of the ** master journal file, but there is no way of knowing if that ** master journal exists now or if it will exist after the operating ** system crash that may follow the fsync() failure. */ assert(0); sqliteFree(zMaster); return rc; } /* All files and directories have already been synced, so the following ** calls to sqlite3BtreeCommit() are only closing files and deleting ** journals. If something goes wrong while this is happening we don't ** really care. The integrity of the transaction is already guaranteed, ** but some stray 'cold' journals may be lying around. Returning an ** error code won't help matters. */ for(i=0; i<db->nDb; i++){ Btree *pBt = db->aDb[i].pBt; if( pBt ){ sqlite3BtreeCommit(pBt); } } } return rc; }
/* ** Compile the UTF-8 encoded SQL statement zSql into a statement handle. */ static int sqlite3Prepare( sqlite3 *db, /* Database handle. */ const char *zSql, /* UTF-8 encoded SQL statement. */ int nBytes, /* Length of zSql in bytes. */ int saveSqlFlag, /* True to copy SQL text into the sqlite3_stmt */ Vdbe *pReprepare, /* VM being reprepared */ 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 */ /* Allocate the parsing context */ pParse = sqlite3StackAllocZero(db, sizeof(*pParse)); if( pParse==0 ){ rc = SQLITE_NOMEM; goto end_prepare; } pParse->pReprepare = pReprepare; if( sqlite3SafetyOn(db) ){ rc = SQLITE_MISUSE; goto end_prepare; } assert( ppStmt && *ppStmt==0 ); assert( !db->mallocFailed ); assert( sqlite3_mutex_held(db->mutex) ); /* Check to verify that it is possible to get a read lock on all ** database schemas. The inability to get a read lock indicates that ** some other database connection is holding a write-lock, which in ** turn means that the other connection has made uncommitted changes ** to the schema. ** ** Were we to proceed and prepare the statement against the uncommitted ** schema changes and if those schema changes are subsequently rolled ** back and different changes are made in their place, then when this ** prepared statement goes to run the schema cookie would fail to detect ** the schema change. Disaster would follow. ** ** This thread is currently holding mutexes on all Btrees (because ** of the sqlite3BtreeEnterAll() in sqlite3LockAndPrepare()) so it ** is not possible for another thread to start a new schema change ** while this routine is running. Hence, we do not need to hold ** locks on the schema, we just need to make sure nobody else is ** holding them. ** ** Note that setting READ_UNCOMMITTED overrides most lock detection, ** but it does *not* override schema lock detection, so this all still ** works even if READ_UNCOMMITTED is set. */ for(i=0; i<db->nDb; i++) { Btree *pBt = db->aDb[i].pBt; if( pBt ){ assert( sqlite3BtreeHoldsMutex(pBt) ); rc = sqlite3BtreeSchemaLocked(pBt); if( rc ){ const char *zDb = db->aDb[i].zName; sqlite3Error(db, rc, "database schema is locked: %s", zDb); (void)sqlite3SafetyOff(db); testcase( db->flags & SQLITE_ReadUncommitted ); goto end_prepare; } } } sqlite3VtabUnlockList(db); pParse->db = db; if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){ char *zSqlCopy; int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH]; testcase( nBytes==mxLen ); testcase( nBytes==mxLen+1 ); if( nBytes>mxLen ){ sqlite3Error(db, SQLITE_TOOBIG, "statement too long"); (void)sqlite3SafetyOff(db); rc = sqlite3ApiExit(db, SQLITE_TOOBIG); goto end_prepare; } zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes); if( zSqlCopy ){ sqlite3RunParser(pParse, zSqlCopy, &zErrMsg); sqlite3DbFree(db, zSqlCopy); pParse->zTail = &zSql[pParse->zTail-zSqlCopy]; }else{ pParse->zTail = &zSql[nBytes]; } }else{ sqlite3RunParser(pParse, zSql, &zErrMsg); } if( db->mallocFailed ){ pParse->rc = SQLITE_NOMEM; } if( pParse->rc==SQLITE_DONE ) pParse->rc = SQLITE_OK; if( pParse->checkSchema ){ schemaIsValid(pParse); } if( pParse->rc==SQLITE_SCHEMA ){ sqlite3ResetInternalSchema(db, 0); } if( db->mallocFailed ){ pParse->rc = SQLITE_NOMEM; } if( pzTail ){ *pzTail = pParse->zTail; } rc = pParse->rc; #ifndef SQLITE_OMIT_EXPLAIN if( rc==SQLITE_OK && pParse->pVdbe && pParse->explain ){ static const char * const azColName[] = { "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment", "order", "from", "detail" }; int iFirst, mx; if( pParse->explain==2 ){ sqlite3VdbeSetNumCols(pParse->pVdbe, 3); iFirst = 8; mx = 11; }else{ sqlite3VdbeSetNumCols(pParse->pVdbe, 8); iFirst = 0; mx = 8; } for(i=iFirst; i<mx; i++){ sqlite3VdbeSetColName(pParse->pVdbe, i-iFirst, COLNAME_NAME, azColName[i], SQLITE_STATIC); } } #endif if( sqlite3SafetyOff(db) ){ rc = SQLITE_MISUSE; } assert( db->init.busy==0 || saveSqlFlag==0 ); if( db->init.busy==0 ){ Vdbe *pVdbe = pParse->pVdbe; sqlite3VdbeSetSql(pVdbe, zSql, (int)(pParse->zTail-zSql), saveSqlFlag); } if( pParse->pVdbe && (rc!=SQLITE_OK || db->mallocFailed) ){ sqlite3VdbeFinalize(pParse->pVdbe); assert(!(*ppStmt)); }else{ *ppStmt = (sqlite3_stmt*)pParse->pVdbe; } if( zErrMsg ){ sqlite3Error(db, rc, "%s", zErrMsg); sqlite3DbFree(db, zErrMsg); }else{ sqlite3Error(db, rc, 0); } /* Delete any TriggerPrg structures allocated while parsing this statement. */ while( pParse->pTriggerPrg ){ TriggerPrg *pT = pParse->pTriggerPrg; pParse->pTriggerPrg = pT->pNext; sqlite3VdbeProgramDelete(db, pT->pProgram, 0); sqlite3DbFree(db, pT); } end_prepare: sqlite3StackFree(db, pParse); rc = sqlite3ApiExit(db, rc); assert( (rc&db->errMask)==rc ); return rc; }
/* ** Attempt to read the database schema and initialize internal ** data structures for a single database file. The index of the ** database file is given by iDb. iDb==0 is used for the main ** database. iDb==1 should never be used. iDb>=2 is used for ** auxiliary databases. Return one of the SQLITE_ error codes to ** indicate success or failure. */ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ int rc; BtCursor *curMain; int size; Table *pTab; Db *pDb; char const *azArg[4]; int meta[10]; InitData initData; char const *zMasterSchema; char const *zMasterName = SCHEMA_TABLE(iDb); /* ** 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 ); /* zMasterSchema and zInitScript are set to point at the master schema ** and initialisation script appropriate for the database being ** initialised. 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. */ sqlite3SafetyOff(db); azArg[0] = zMasterName; azArg[1] = "1"; azArg[2] = zMasterSchema; azArg[3] = 0; initData.db = db; initData.iDb = iDb; initData.pzErrMsg = pzErrMsg; rc = sqlite3InitCallback(&initData, 3, (char **)azArg, 0); if( rc ){ sqlite3SafetyOn(db); return initData.rc; } pTab = sqlite3FindTable(db, zMasterName, db->aDb[iDb].zName); if( pTab ){ pTab->readOnly = 1; } sqlite3SafetyOn(db); /* Create a cursor to hold the database open */ pDb = &db->aDb[iDb]; if( pDb->pBt==0 ){ if( !OMIT_TEMPDB && iDb==1 ){ DbSetProperty(db, 1, DB_SchemaLoaded); } return SQLITE_OK; } rc = sqlite3BtreeCursor(pDb->pBt, MASTER_ROOT, 0, 0, 0, &curMain); if( rc!=SQLITE_OK && rc!=SQLITE_EMPTY ){ sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0); return rc; } /* Get the database meta information. ** ** Meta values are as follows: ** meta[0] Schema cookie. Changes with each schema change. ** meta[1] File format of schema layer. ** meta[2] Size of the page cache. ** meta[3] Use freelist if 0. Autovacuum if greater than zero. ** meta[4] Db text encoding. 1:UTF-8 2:UTF-16LE 3:UTF-16BE ** meta[5] The user cookie. Used by the application. ** meta[6] ** meta[7] ** meta[8] ** meta[9] ** ** Note: The #defined SQLITE_UTF* symbols in sqliteInt.h correspond to ** the possible values of meta[4]. */ if( rc==SQLITE_OK ){ int i; for(i=0; rc==SQLITE_OK && i<sizeof(meta)/sizeof(meta[0]); i++){ rc = sqlite3BtreeGetMeta(pDb->pBt, i+1, (u32 *)&meta[i]); } if( rc ){ sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0); sqlite3BtreeCloseCursor(curMain); return rc; } }else{ memset(meta, 0, sizeof(meta)); } pDb->pSchema->schema_cookie = meta[0]; /* If opening a non-empty database, check the text encoding. For the ** main database, set sqlite3.enc to the encoding of the main database. ** For an attached db, it is an error if the encoding is not the same ** as sqlite3.enc. */ if( meta[4] ){ /* text encoding */ if( iDb==0 ){ /* If opening the main database, set ENC(db). */ ENC(db) = (u8)meta[4]; db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 6, 0); }else{ /* If opening an attached database, the encoding much match ENC(db) */ if( meta[4]!=ENC(db) ){ sqlite3BtreeCloseCursor(curMain); sqlite3SetString(pzErrMsg, "attached databases must use the same" " text encoding as main database", (char*)0); return SQLITE_ERROR; } } }else{ DbSetProperty(db, iDb, DB_Empty); } pDb->pSchema->enc = ENC(db); size = meta[2]; if( size==0 ){ size = MAX_PAGES; } pDb->pSchema->cache_size = size; sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); /* ** file_format==1 Version 3.0.0. ** file_format==2 Version 3.1.3. // ALTER TABLE ADD COLUMN ** file_format==3 Version 3.1.4. // ditto but with non-NULL defaults ** file_format==4 Version 3.3.0. // DESC indices. Boolean constants */ pDb->pSchema->file_format = meta[1]; if( pDb->pSchema->file_format==0 ){ pDb->pSchema->file_format = 1; } if( pDb->pSchema->file_format>SQLITE_MAX_FILE_FORMAT ){ sqlite3BtreeCloseCursor(curMain); sqlite3SetString(pzErrMsg, "unsupported file format", (char*)0); return SQLITE_ERROR; } /* Read the schema information out of the schema tables */ assert( db->init.busy ); if( rc==SQLITE_EMPTY ){ /* For an empty database, there is nothing to read */ rc = SQLITE_OK; }else{ char *zSql; zSql = sqlite3MPrintf( "SELECT name, rootpage, sql FROM '%q'.%s", db->aDb[iDb].zName, zMasterName); sqlite3SafetyOff(db); rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); if( rc==SQLITE_ABORT ) rc = initData.rc; sqlite3SafetyOn(db); sqliteFree(zSql); #ifndef SQLITE_OMIT_ANALYZE if( rc==SQLITE_OK ){ sqlite3AnalysisLoad(db, iDb); } #endif sqlite3BtreeCloseCursor(curMain); } if( sqlite3MallocFailed() ){ /* sqlite3SetString(pzErrMsg, "out of memory", (char*)0); */ rc = SQLITE_NOMEM; sqlite3ResetInternalSchema(db, 0); } if( rc==SQLITE_OK ){ DbSetProperty(db, iDb, DB_SchemaLoaded); }else{ sqlite3ResetInternalSchema(db, iDb); } return rc; }
/* ** Invoke a virtual table constructor (either xCreate or xConnect). The ** pointer to the function to invoke is passed as the fourth parameter ** to this procedure. */ static int vtabCallConstructor( sqlite3 *db, Table *pTab, Module *pMod, int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**), char **pzErr ){ int rc; int rc2; sqlite3_vtab *pVtab = 0; const char *const*azArg = (const char *const*)pTab->azModuleArg; int nArg = pTab->nModuleArg; char *zErr = 0; char *zModuleName = sqlite3MPrintf(db, "%s", pTab->zName); if( !zModuleName ){ return SQLITE_NOMEM; } assert( !db->pVTab ); assert( xConstruct ); db->pVTab = pTab; rc = sqlite3SafetyOff(db); assert( rc==SQLITE_OK ); rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVtab, &zErr); rc2 = sqlite3SafetyOn(db); if( rc==SQLITE_OK && pVtab ){ pVtab->pModule = pMod->pModule; pVtab->nRef = 1; pTab->pVtab = pVtab; } if( SQLITE_OK!=rc ){ if( zErr==0 ){ *pzErr = sqlite3MPrintf(db, "vtable constructor failed: %s", zModuleName); }else { *pzErr = sqlite3MPrintf(db, "%s", zErr); sqlite3_free(zErr); } }else if( db->pVTab ){ const char *zFormat = "vtable constructor did not declare schema: %s"; *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName); rc = SQLITE_ERROR; } if( rc==SQLITE_OK ){ rc = rc2; } db->pVTab = 0; sqlite3_free(zModuleName); /* If everything went according to plan, loop through the columns ** of the table to see if any of them contain the token "hidden". ** If so, set the Column.isHidden flag and remove the token from ** the type string. */ if( rc==SQLITE_OK ){ int iCol; for(iCol=0; iCol<pTab->nCol; iCol++){ char *zType = pTab->aCol[iCol].zType; int nType; int i = 0; if( !zType ) continue; nType = strlen(zType); if( sqlite3StrNICmp("hidden", zType, 6) || (zType[6] && zType[6]!=' ') ){ for(i=0; i<nType; i++){ if( (0==sqlite3StrNICmp(" hidden", &zType[i], 7)) && (zType[i+7]=='\0' || zType[i+7]==' ') ){ i++; break; } } } if( i<nType ){ int j; int nDel = 6 + (zType[i+6] ? 1 : 0); for(j=i; (j+nDel)<=nType; j++){ zType[j] = zType[j+nDel]; } if( zType[i]=='\0' && i>0 ){ assert(zType[i-1]==' '); zType[i-1] = '\0'; } pTab->aCol[iCol].isHidden = 1; } } } return rc; }
/* ** An SQL user-function registered to do the work of an ATTACH statement. The ** three arguments to the function come directly from an attach statement: ** ** ATTACH DATABASE x AS y KEY z ** ** SELECT sqlite_attach(x, y, z) ** ** If the optional "KEY z" syntax is omitted, an SQL NULL is passed as the ** third argument. */ static void attachFunc( sqlite3_context *context, int NotUsed, sqlite3_value **argv ){ int i; int rc = 0; sqlite3 *db = sqlite3_context_db_handle(context); const char *zName; const char *zFile; Db *aNew; char *zErrDyn = 0; UNUSED_PARAMETER(NotUsed); zFile = (const char *)sqlite3_value_text(argv[0]); zName = (const char *)sqlite3_value_text(argv[1]); if( zFile==0 ) zFile = ""; if( zName==0 ) zName = ""; /* Check for the following errors: ** ** * Too many attached databases, ** * Transaction currently open ** * Specified database name already being used. */ if( db->nDb>=db->aLimit[SQLITE_LIMIT_ATTACHED]+2 ){ zErrDyn = sqlite3MPrintf(db, "too many attached databases - max %d", db->aLimit[SQLITE_LIMIT_ATTACHED] ); goto attach_error; } if( !db->autoCommit ){ zErrDyn = sqlite3MPrintf(db, "cannot ATTACH database within transaction"); goto attach_error; } for(i=0; i<db->nDb; i++){ char *z = db->aDb[i].zName; assert( z && zName ); if( sqlite3StrICmp(z, zName)==0 ){ zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName); goto attach_error; } } /* Allocate the new entry in the db->aDb[] array and initialise the schema ** hash tables. */ if( db->aDb==db->aDbStatic ){ aNew = sqlite3DbMallocRaw(db, sizeof(db->aDb[0])*3 ); if( aNew==0 ) return; memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2); }else{ aNew = sqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(db->nDb+1) ); if( aNew==0 ) return; } db->aDb = aNew; aNew = &db->aDb[db->nDb]; memset(aNew, 0, sizeof(*aNew)); /* Open the database file. If the btree is successfully opened, use ** it to obtain the database schema. At this point the schema may ** or may not be initialised. */ rc = sqlite3BtreeFactory(db, zFile, 0, SQLITE_DEFAULT_CACHE_SIZE, db->openFlags | SQLITE_OPEN_MAIN_DB, &aNew->pBt); db->nDb++; if( rc==SQLITE_CONSTRAINT ){ rc = SQLITE_ERROR; zErrDyn = sqlite3MPrintf(db, "database is already attached"); }else if( rc==SQLITE_OK ){ Pager *pPager; aNew->pSchema = sqlite3SchemaGet(db, aNew->pBt); if( !aNew->pSchema ){ rc = SQLITE_NOMEM; }else if( aNew->pSchema->file_format && aNew->pSchema->enc!=ENC(db) ){ zErrDyn = sqlite3MPrintf(db, "attached databases must use the same text encoding as main database"); rc = SQLITE_ERROR; } pPager = sqlite3BtreePager(aNew->pBt); sqlite3PagerLockingMode(pPager, db->dfltLockMode); sqlite3PagerJournalMode(pPager, db->dfltJournalMode); } aNew->zName = sqlite3DbStrDup(db, zName); aNew->safety_level = 3; #if SQLITE_HAS_CODEC { extern int sqlite3CodecAttach(sqlite3*, int, const void*, int); extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*); int nKey; char *zKey; int t = sqlite3_value_type(argv[2]); switch( t ){ case SQLITE_INTEGER: case SQLITE_FLOAT: zErrDyn = sqlite3DbStrDup(db, "Invalid key value"); rc = SQLITE_ERROR; break; case SQLITE_TEXT: case SQLITE_BLOB: nKey = sqlite3_value_bytes(argv[2]); zKey = (char *)sqlite3_value_blob(argv[2]); sqlite3CodecAttach(db, db->nDb-1, zKey, nKey); break; case SQLITE_NULL: /* No key specified. Use the key from the main database */ sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey); sqlite3CodecAttach(db, db->nDb-1, zKey, nKey); break; } } #endif /* If the file was opened successfully, read the schema for the new database. ** If this fails, or if opening the file failed, then close the file and ** remove the entry from the db->aDb[] array. i.e. put everything back the way ** we found it. */ if( rc==SQLITE_OK ){ (void)sqlite3SafetyOn(db); sqlite3BtreeEnterAll(db); rc = sqlite3Init(db, &zErrDyn); sqlite3BtreeLeaveAll(db); (void)sqlite3SafetyOff(db); } if( rc ){ int iDb = db->nDb - 1; assert( iDb>=2 ); if( db->aDb[iDb].pBt ){ sqlite3BtreeClose(db->aDb[iDb].pBt); db->aDb[iDb].pBt = 0; db->aDb[iDb].pSchema = 0; } sqlite3ResetInternalSchema(db, 0); db->nDb = iDb; if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ db->mallocFailed = 1; sqlite3DbFree(db, zErrDyn); zErrDyn = sqlite3MPrintf(db, "out of memory"); }else if( zErrDyn==0 ){ zErrDyn = sqlite3MPrintf(db, "unable to open database: %s", zFile); } goto attach_error; } return; attach_error: /* Return an error if we get here */ if( zErrDyn ){ sqlite3_result_error(context, zErrDyn, -1); sqlite3DbFree(db, zErrDyn); } if( rc ) sqlite3_result_error_code(context, rc); }
/* ** Attempt to read the database schema and initialize internal ** data structures for a single database file. The index of the ** database file is given by iDb. iDb==0 is used for the main ** database. iDb==1 should never be used. iDb>=2 is used for ** auxiliary databases. Return one of the SQLITE_ error codes to ** indicate success or failure. */ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ int rc; BtCursor *curMain; int size; Table *pTab; char const *azArg[5]; char zDbNum[30]; int meta[10]; InitData initData; char const *zMasterSchema; char const *zMasterName = SCHEMA_TABLE(iDb); /* ** 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 ); /* zMasterSchema and zInitScript are set to point at the master schema ** and initialisation script appropriate for the database being ** initialised. 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. */ sqlite3SafetyOff(db); azArg[0] = zMasterName; azArg[1] = "1"; azArg[2] = zMasterSchema; sprintf(zDbNum, "%d", iDb); azArg[3] = zDbNum; azArg[4] = 0; initData.db = db; initData.pzErrMsg = pzErrMsg; rc = sqlite3InitCallback(&initData, 4, (char **)azArg, 0); if( rc!=SQLITE_OK ){ sqlite3SafetyOn(db); return rc; } pTab = sqlite3FindTable(db, zMasterName, db->aDb[iDb].zName); if( pTab ){ pTab->readOnly = 1; } sqlite3SafetyOn(db); /* Create a cursor to hold the database open */ if( db->aDb[iDb].pBt==0 ){ if( !OMIT_TEMPDB && iDb==1 ) DbSetProperty(db, 1, DB_SchemaLoaded); return SQLITE_OK; } rc = sqlite3BtreeCursor(db->aDb[iDb].pBt, MASTER_ROOT, 0, 0, 0, &curMain); if( rc!=SQLITE_OK && rc!=SQLITE_EMPTY ){ sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0); return rc; } /* Get the database meta information. ** ** Meta values are as follows: ** meta[0] Schema cookie. Changes with each schema change. ** meta[1] File format of schema layer. ** meta[2] Size of the page cache. ** meta[3] Use freelist if 0. Autovacuum if greater than zero. ** meta[4] Db text encoding. 1:UTF-8 3:UTF-16 LE 4:UTF-16 BE ** meta[5] The user cookie. Used by the application. ** meta[6] ** meta[7] ** meta[8] ** meta[9] ** ** Note: The hash defined SQLITE_UTF* symbols in sqliteInt.h correspond to ** the possible values of meta[4]. */ if( rc==SQLITE_OK ){ int i; for(i=0; rc==SQLITE_OK && i<sizeof(meta)/sizeof(meta[0]); i++){ rc = sqlite3BtreeGetMeta(db->aDb[iDb].pBt, i+1, (u32 *)&meta[i]); } if( rc ){ sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0); sqlite3BtreeCloseCursor(curMain); return rc; } }else{ memset(meta, 0, sizeof(meta)); } db->aDb[iDb].schema_cookie = meta[0]; /* If opening a non-empty database, check the text encoding. For the ** main database, set sqlite3.enc to the encoding of the main database. ** For an attached db, it is an error if the encoding is not the same ** as sqlite3.enc. */ if( meta[4] ){ /* text encoding */ if( iDb==0 ){ /* If opening the main database, set db->enc. */ db->enc = (u8)meta[4]; db->pDfltColl = sqlite3FindCollSeq(db, db->enc, "BINARY", 6, 0); }else{ /* If opening an attached database, the encoding much match db->enc */ if( meta[4]!=db->enc ){ sqlite3BtreeCloseCursor(curMain); sqlite3SetString(pzErrMsg, "attached databases must use the same" " text encoding as main database", (char*)0); return SQLITE_ERROR; } } } size = meta[2]; if( size==0 ){ size = MAX_PAGES; } db->aDb[iDb].cache_size = size; if( iDb==0 ){ db->file_format = meta[1]; if( db->file_format==0 ){ /* This happens if the database was initially empty */ db->file_format = 1; } if( db->file_format==2 || db->file_format==3 ){ /* File format 2 is treated exactly as file format 1. New ** databases are created with file format 1. */ db->file_format = 1; } } /* ** file_format==1 Version 3.0.0. ** file_format==2 Version 3.1.3. ** file_format==3 Version 3.1.4. ** ** Version 3.0 can only use files with file_format==1. Version 3.1.3 ** can read and write files with file_format==1 or file_format==2. ** Version 3.1.4 can read and write file formats 1, 2 and 3. */ if( meta[1]>3 ){ sqlite3BtreeCloseCursor(curMain); sqlite3SetString(pzErrMsg, "unsupported file format", (char*)0); return SQLITE_ERROR; } sqlite3BtreeSetCacheSize(db->aDb[iDb].pBt, db->aDb[iDb].cache_size); /* Read the schema information out of the schema tables */ assert( db->init.busy ); if( rc==SQLITE_EMPTY ){ /* For an empty database, there is nothing to read */ rc = SQLITE_OK; }else{ char *zSql; zSql = sqlite3MPrintf( "SELECT name, rootpage, sql, '%s' FROM '%q'.%s", zDbNum, db->aDb[iDb].zName, zMasterName); sqlite3SafetyOff(db); rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); sqlite3SafetyOn(db); sqliteFree(zSql); sqlite3BtreeCloseCursor(curMain); } if( sqlite3_malloc_failed ){ sqlite3SetString(pzErrMsg, "out of memory", (char*)0); rc = SQLITE_NOMEM; sqlite3ResetInternalSchema(db, 0); } if( rc==SQLITE_OK ){ DbSetProperty(db, iDb, DB_SchemaLoaded); }else{ sqlite3ResetInternalSchema(db, iDb); } return rc; }