| Index: third_party/sqlite/src/src/build.c
|
| diff --git a/third_party/sqlite/src/src/build.c b/third_party/sqlite/src/src/build.c
|
| index 63e30046578470c705fe0cc3eed84f865c821e71..cd9c81be8215127d4e0396fdc5f23e658f32340d 100644
|
| --- a/third_party/sqlite/src/src/build.c
|
| +++ b/third_party/sqlite/src/src/build.c
|
| @@ -24,25 +24,16 @@
|
| */
|
| #include "sqliteInt.h"
|
|
|
| -/*
|
| -** This routine is called when a new SQL statement is beginning to
|
| -** be parsed. Initialize the pParse structure as needed.
|
| -*/
|
| -void sqlite3BeginParse(Parse *pParse, int explainFlag){
|
| - pParse->explain = (u8)explainFlag;
|
| - pParse->nVar = 0;
|
| -}
|
| -
|
| #ifndef SQLITE_OMIT_SHARED_CACHE
|
| /*
|
| ** The TableLock structure is only used by the sqlite3TableLock() and
|
| ** codeTableLocks() functions.
|
| */
|
| struct TableLock {
|
| - int iDb; /* The database containing the table to be locked */
|
| - int iTab; /* The root page of the table to be locked */
|
| - u8 isWriteLock; /* True for write lock. False for a read lock */
|
| - const char *zName; /* Name of the table */
|
| + int iDb; /* The database containing the table to be locked */
|
| + int iTab; /* The root page of the table to be locked */
|
| + u8 isWriteLock; /* True for write lock. False for a read lock */
|
| + const char *zLockName; /* Name of the table */
|
| };
|
|
|
| /*
|
| @@ -68,6 +59,8 @@ void sqlite3TableLock(
|
| TableLock *p;
|
| assert( iDb>=0 );
|
|
|
| + if( iDb==1 ) return;
|
| + if( !sqlite3BtreeSharable(pParse->db->aDb[iDb].pBt) ) return;
|
| for(i=0; i<pToplevel->nTableLock; i++){
|
| p = &pToplevel->aTableLock[i];
|
| if( p->iDb==iDb && p->iTab==iTab ){
|
| @@ -84,10 +77,10 @@ void sqlite3TableLock(
|
| p->iDb = iDb;
|
| p->iTab = iTab;
|
| p->isWriteLock = isWriteLock;
|
| - p->zName = zName;
|
| + p->zLockName = zName;
|
| }else{
|
| pToplevel->nTableLock = 0;
|
| - pToplevel->db->mallocFailed = 1;
|
| + sqlite3OomFault(pToplevel->db);
|
| }
|
| }
|
|
|
| @@ -106,7 +99,7 @@ static void codeTableLocks(Parse *pParse){
|
| TableLock *p = &pParse->aTableLock[i];
|
| int p1 = p->iDb;
|
| sqlite3VdbeAddOp4(pVdbe, OP_TableLock, p1, p->iTab, p->isWriteLock,
|
| - p->zName, P4_STATIC);
|
| + p->zLockName, P4_STATIC);
|
| }
|
| }
|
| #else
|
| @@ -155,15 +148,14 @@ void sqlite3FinishCoding(Parse *pParse){
|
| assert( !pParse->isMultiWrite
|
| || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort));
|
| if( v ){
|
| - while( sqlite3VdbeDeletePriorOpcode(v, OP_Close) ){}
|
| sqlite3VdbeAddOp0(v, OP_Halt);
|
|
|
| #if SQLITE_USER_AUTHENTICATION
|
| if( pParse->nTableLock>0 && db->init.busy==0 ){
|
| sqlite3UserAuthInit(db);
|
| if( db->auth.authLevel<UAUTH_User ){
|
| - pParse->rc = SQLITE_AUTH_USER;
|
| sqlite3ErrorMsg(pParse, "user not authenticated");
|
| + pParse->rc = SQLITE_AUTH_USER;
|
| return;
|
| }
|
| }
|
| @@ -182,14 +174,16 @@ void sqlite3FinishCoding(Parse *pParse){
|
| assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init );
|
| sqlite3VdbeJumpHere(v, 0);
|
| for(iDb=0; iDb<db->nDb; iDb++){
|
| + Schema *pSchema;
|
| if( DbMaskTest(pParse->cookieMask, iDb)==0 ) continue;
|
| sqlite3VdbeUsesBtree(v, iDb);
|
| + pSchema = db->aDb[iDb].pSchema;
|
| sqlite3VdbeAddOp4Int(v,
|
| OP_Transaction, /* Opcode */
|
| iDb, /* P1 */
|
| DbMaskTest(pParse->writeMask,iDb), /* P2 */
|
| - pParse->cookieValue[iDb], /* P3 */
|
| - db->aDb[iDb].pSchema->iGeneration /* P4 */
|
| + pSchema->schema_cookie, /* P3 */
|
| + pSchema->iGeneration /* P4 */
|
| );
|
| if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1);
|
| VdbeComment((v,
|
| @@ -237,15 +231,9 @@ void sqlite3FinishCoding(Parse *pParse){
|
| if( pParse->pAinc!=0 && pParse->nTab==0 ) pParse->nTab = 1;
|
| sqlite3VdbeMakeReady(v, pParse);
|
| pParse->rc = SQLITE_DONE;
|
| - pParse->colNamesSet = 0;
|
| }else{
|
| pParse->rc = SQLITE_ERROR;
|
| }
|
| - pParse->nTab = 0;
|
| - pParse->nMem = 0;
|
| - pParse->nSet = 0;
|
| - pParse->nVar = 0;
|
| - DbMaskZero(pParse->cookieMask);
|
| }
|
|
|
| /*
|
| @@ -265,8 +253,7 @@ void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
|
| char *zSql;
|
| char *zErrMsg = 0;
|
| sqlite3 *db = pParse->db;
|
| -# define SAVE_SZ (sizeof(Parse) - offsetof(Parse,nVar))
|
| - char saveBuf[SAVE_SZ];
|
| + char saveBuf[PARSE_TAIL_SZ];
|
|
|
| if( pParse->nErr ) return;
|
| assert( pParse->nested<10 ); /* Nesting should only be of limited depth */
|
| @@ -277,12 +264,12 @@ void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
|
| return; /* A malloc must have failed */
|
| }
|
| pParse->nested++;
|
| - memcpy(saveBuf, &pParse->nVar, SAVE_SZ);
|
| - memset(&pParse->nVar, 0, SAVE_SZ);
|
| + memcpy(saveBuf, PARSE_TAIL(pParse), PARSE_TAIL_SZ);
|
| + memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ);
|
| sqlite3RunParser(pParse, zSql, &zErrMsg);
|
| sqlite3DbFree(db, zErrMsg);
|
| sqlite3DbFree(db, zSql);
|
| - memcpy(&pParse->nVar, saveBuf, SAVE_SZ);
|
| + memcpy(PARSE_TAIL(pParse), saveBuf, PARSE_TAIL_SZ);
|
| pParse->nested--;
|
| }
|
|
|
| @@ -321,14 +308,22 @@ Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){
|
| return 0;
|
| }
|
| #endif
|
| - for(i=OMIT_TEMPDB; i<db->nDb; i++){
|
| - int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
|
| - if( zDatabase!=0 && sqlite3StrICmp(zDatabase, db->aDb[j].zName) ) continue;
|
| - assert( sqlite3SchemaMutexHeld(db, j, 0) );
|
| - p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName);
|
| - if( p ) break;
|
| + while(1){
|
| + for(i=OMIT_TEMPDB; i<db->nDb; i++){
|
| + int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
|
| + if( zDatabase==0 || sqlite3StrICmp(zDatabase, db->aDb[j].zDbSName)==0 ){
|
| + assert( sqlite3SchemaMutexHeld(db, j, 0) );
|
| + p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName);
|
| + if( p ) return p;
|
| + }
|
| + }
|
| + /* Not found. If the name we were looking for was temp.sqlite_master
|
| + ** then change the name to sqlite_temp_master and try again. */
|
| + if( sqlite3StrICmp(zName, MASTER_NAME)!=0 ) break;
|
| + if( sqlite3_stricmp(zDatabase, db->aDb[1].zDbSName)!=0 ) break;
|
| + zName = TEMP_MASTER_NAME;
|
| }
|
| - return p;
|
| + return 0;
|
| }
|
|
|
| /*
|
| @@ -343,7 +338,7 @@ Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){
|
| */
|
| Table *sqlite3LocateTable(
|
| Parse *pParse, /* context in which to report errors */
|
| - int isView, /* True if looking for a VIEW rather than a TABLE */
|
| + u32 flags, /* LOCATE_VIEW or LOCATE_NOERR */
|
| const char *zName, /* Name of the table we are looking for */
|
| const char *zDbase /* Name of the database. Might be NULL */
|
| ){
|
| @@ -357,24 +352,29 @@ Table *sqlite3LocateTable(
|
|
|
| p = sqlite3FindTable(pParse->db, zName, zDbase);
|
| if( p==0 ){
|
| - const char *zMsg = isView ? "no such view" : "no such table";
|
| + const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table";
|
| #ifndef SQLITE_OMIT_VIRTUALTABLE
|
| if( sqlite3FindDbName(pParse->db, zDbase)<1 ){
|
| /* If zName is the not the name of a table in the schema created using
|
| ** CREATE, then check to see if it is the name of an virtual table that
|
| ** can be an eponymous virtual table. */
|
| Module *pMod = (Module*)sqlite3HashFind(&pParse->db->aModule, zName);
|
| + if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
|
| + pMod = sqlite3PragmaVtabRegister(pParse->db, zName);
|
| + }
|
| if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
|
| return pMod->pEpoTab;
|
| }
|
| }
|
| #endif
|
| - if( zDbase ){
|
| - sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName);
|
| - }else{
|
| - sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName);
|
| + if( (flags & LOCATE_NOERR)==0 ){
|
| + if( zDbase ){
|
| + sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName);
|
| + }else{
|
| + sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName);
|
| + }
|
| + pParse->checkSchema = 1;
|
| }
|
| - pParse->checkSchema = 1;
|
| }
|
|
|
| return p;
|
| @@ -391,18 +391,18 @@ Table *sqlite3LocateTable(
|
| */
|
| Table *sqlite3LocateTableItem(
|
| Parse *pParse,
|
| - int isView,
|
| + u32 flags,
|
| struct SrcList_item *p
|
| ){
|
| const char *zDb;
|
| assert( p->pSchema==0 || p->zDatabase==0 );
|
| if( p->pSchema ){
|
| int iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema);
|
| - zDb = pParse->db->aDb[iDb].zName;
|
| + zDb = pParse->db->aDb[iDb].zDbSName;
|
| }else{
|
| zDb = p->zDatabase;
|
| }
|
| - return sqlite3LocateTable(pParse, isView, p->zName, zDb);
|
| + return sqlite3LocateTable(pParse, flags, p->zName, zDb);
|
| }
|
|
|
| /*
|
| @@ -426,7 +426,7 @@ Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){
|
| int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
|
| Schema *pSchema = db->aDb[j].pSchema;
|
| assert( pSchema );
|
| - if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zName) ) continue;
|
| + if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zDbSName) ) continue;
|
| assert( sqlite3SchemaMutexHeld(db, j, 0) );
|
| p = sqlite3HashFind(&pSchema->idxHash, zName);
|
| if( p ) break;
|
| @@ -495,8 +495,8 @@ void sqlite3CollapseDatabaseArray(sqlite3 *db){
|
| for(i=j=2; i<db->nDb; i++){
|
| struct Db *pDb = &db->aDb[i];
|
| if( pDb->pBt==0 ){
|
| - sqlite3DbFree(db, pDb->zName);
|
| - pDb->zName = 0;
|
| + sqlite3DbFree(db, pDb->zDbSName);
|
| + pDb->zDbSName = 0;
|
| continue;
|
| }
|
| if( j<i ){
|
| @@ -504,7 +504,6 @@ void sqlite3CollapseDatabaseArray(sqlite3 *db){
|
| }
|
| j++;
|
| }
|
| - memset(&db->aDb[j], 0, (db->nDb-j)*sizeof(db->aDb[j]));
|
| db->nDb = j;
|
| if( db->nDb<=2 && db->aDb!=db->aDbStatic ){
|
| memcpy(db->aDbStatic, db->aDb, 2*sizeof(db->aDb[0]));
|
| @@ -577,8 +576,6 @@ void sqlite3DeleteColumnNames(sqlite3 *db, Table *pTable){
|
| for(i=0; i<pTable->nCol; i++, pCol++){
|
| sqlite3DbFree(db, pCol->zName);
|
| sqlite3ExprDelete(db, pCol->pDflt);
|
| - sqlite3DbFree(db, pCol->zDflt);
|
| - sqlite3DbFree(db, pCol->zType);
|
| sqlite3DbFree(db, pCol->zColl);
|
| }
|
| sqlite3DbFree(db, pTable->aCol);
|
| @@ -600,16 +597,10 @@ void sqlite3DeleteColumnNames(sqlite3 *db, Table *pTable){
|
| ** db parameter can be used with db->pnBytesFreed to measure the memory
|
| ** used by the Table object.
|
| */
|
| -void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
|
| +static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){
|
| Index *pIndex, *pNext;
|
| TESTONLY( int nLookaside; ) /* Used to verify lookaside not used for schema */
|
|
|
| - assert( !pTable || pTable->nRef>0 );
|
| -
|
| - /* Do not delete the table until the reference count reaches zero. */
|
| - if( !pTable ) return;
|
| - if( ((!db || db->pnBytesFreed==0) && (--pTable->nRef)>0) ) return;
|
| -
|
| /* Record the number of outstanding lookaside allocations in schema Tables
|
| ** prior to doing any free() operations. Since schema Tables do not use
|
| ** lookaside, this number should not change. */
|
| @@ -619,8 +610,9 @@ void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
|
| /* Delete all indices associated with this table. */
|
| for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){
|
| pNext = pIndex->pNext;
|
| - assert( pIndex->pSchema==pTable->pSchema );
|
| - if( !db || db->pnBytesFreed==0 ){
|
| + assert( pIndex->pSchema==pTable->pSchema
|
| + || (IsVirtual(pTable) && pIndex->idxType!=SQLITE_IDXTYPE_APPDEF) );
|
| + if( (db==0 || db->pnBytesFreed==0) && !IsVirtual(pTable) ){
|
| char *zName = pIndex->zName;
|
| TESTONLY ( Index *pOld = ) sqlite3HashInsert(
|
| &pIndex->pSchema->idxHash, zName, 0
|
| @@ -649,6 +641,13 @@ void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
|
| /* Verify that no lookaside memory was used by schema tables */
|
| assert( nLookaside==0 || nLookaside==db->lookaside.nOut );
|
| }
|
| +void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
|
| + /* Do not delete the table until the reference count reaches zero. */
|
| + if( !pTable ) return;
|
| + if( ((!db || db->pnBytesFreed==0) && (--pTable->nTabRef)>0) ) return;
|
| + deleteTable(db, pTable);
|
| +}
|
| +
|
|
|
| /*
|
| ** Unlink the given table from the hash tables and the delete the
|
| @@ -699,7 +698,7 @@ char *sqlite3NameFromToken(sqlite3 *db, Token *pName){
|
| */
|
| void sqlite3OpenMasterTable(Parse *p, int iDb){
|
| Vdbe *v = sqlite3GetVdbe(p);
|
| - sqlite3TableLock(p, iDb, MASTER_ROOT, 1, SCHEMA_TABLE(iDb));
|
| + sqlite3TableLock(p, iDb, MASTER_ROOT, 1, MASTER_NAME);
|
| sqlite3VdbeAddOp4Int(v, OP_OpenWrite, 0, MASTER_ROOT, iDb, 5);
|
| if( p->nTab==0 ){
|
| p->nTab = 1;
|
| @@ -716,12 +715,11 @@ int sqlite3FindDbName(sqlite3 *db, const char *zName){
|
| int i = -1; /* Database number */
|
| if( zName ){
|
| Db *pDb;
|
| - int n = sqlite3Strlen30(zName);
|
| for(i=(db->nDb-1), pDb=&db->aDb[i]; i>=0; i--, pDb--){
|
| - if( (!OMIT_TEMPDB || i!=1 ) && n==sqlite3Strlen30(pDb->zName) &&
|
| - 0==sqlite3StrICmp(pDb->zName, zName) ){
|
| - break;
|
| - }
|
| + if( 0==sqlite3_stricmp(pDb->zDbSName, zName) ) break;
|
| + /* "main" is always an acceptable alias for the primary database
|
| + ** even if it has been renamed using SQLITE_DBCONFIG_MAINDBNAME. */
|
| + if( i==0 && 0==sqlite3_stricmp("main", zName) ) break;
|
| }
|
| }
|
| return i;
|
| @@ -767,7 +765,8 @@ int sqlite3TwoPartName(
|
| int iDb; /* Database holding the object */
|
| sqlite3 *db = pParse->db;
|
|
|
| - if( ALWAYS(pName2!=0) && pName2->n>0 ){
|
| + assert( pName2!=0 );
|
| + if( pName2->n>0 ){
|
| if( db->init.busy ) {
|
| sqlite3ErrorMsg(pParse, "corrupt database");
|
| return -1;
|
| @@ -779,7 +778,7 @@ int sqlite3TwoPartName(
|
| return -1;
|
| }
|
| }else{
|
| - assert( db->init.iDb==0 || db->init.busy );
|
| + assert( db->init.iDb==0 || db->init.busy || (db->flags & SQLITE_Vacuum)!=0);
|
| iDb = db->init.iDb;
|
| *pUnqual = pName1;
|
| }
|
| @@ -856,62 +855,46 @@ void sqlite3StartTable(
|
| int iDb; /* Database number to create the table in */
|
| Token *pName; /* Unqualified name of the table to create */
|
|
|
| - /* The table or view name to create is passed to this routine via tokens
|
| - ** pName1 and pName2. If the table name was fully qualified, for example:
|
| - **
|
| - ** CREATE TABLE xxx.yyy (...);
|
| - **
|
| - ** Then pName1 is set to "xxx" and pName2 "yyy". On the other hand if
|
| - ** the table name is not fully qualified, i.e.:
|
| - **
|
| - ** CREATE TABLE yyy(...);
|
| - **
|
| - ** Then pName1 is set to "yyy" and pName2 is "".
|
| - **
|
| - ** The call below sets the pName pointer to point at the token (pName1 or
|
| - ** pName2) that stores the unqualified table name. The variable iDb is
|
| - ** set to the index of the database that the table or view is to be
|
| - ** created in.
|
| - */
|
| - iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
|
| - if( iDb<0 ) return;
|
| - if( !OMIT_TEMPDB && isTemp && pName2->n>0 && iDb!=1 ){
|
| - /* If creating a temp table, the name may not be qualified. Unless
|
| - ** the database name is "temp" anyway. */
|
| - sqlite3ErrorMsg(pParse, "temporary table name must be unqualified");
|
| - return;
|
| + if( db->init.busy && db->init.newTnum==1 ){
|
| + /* Special case: Parsing the sqlite_master or sqlite_temp_master schema */
|
| + iDb = db->init.iDb;
|
| + zName = sqlite3DbStrDup(db, SCHEMA_TABLE(iDb));
|
| + pName = pName1;
|
| + }else{
|
| + /* The common case */
|
| + iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
|
| + if( iDb<0 ) return;
|
| + if( !OMIT_TEMPDB && isTemp && pName2->n>0 && iDb!=1 ){
|
| + /* If creating a temp table, the name may not be qualified. Unless
|
| + ** the database name is "temp" anyway. */
|
| + sqlite3ErrorMsg(pParse, "temporary table name must be unqualified");
|
| + return;
|
| + }
|
| + if( !OMIT_TEMPDB && isTemp ) iDb = 1;
|
| + zName = sqlite3NameFromToken(db, pName);
|
| }
|
| - if( !OMIT_TEMPDB && isTemp ) iDb = 1;
|
| -
|
| pParse->sNameToken = *pName;
|
| - zName = sqlite3NameFromToken(db, pName);
|
| if( zName==0 ) return;
|
| if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
|
| goto begin_table_error;
|
| }
|
| if( db->init.iDb==1 ) isTemp = 1;
|
| #ifndef SQLITE_OMIT_AUTHORIZATION
|
| - assert( (isTemp & 1)==isTemp );
|
| + assert( isTemp==0 || isTemp==1 );
|
| + assert( isView==0 || isView==1 );
|
| {
|
| - int code;
|
| - char *zDb = db->aDb[iDb].zName;
|
| + static const u8 aCode[] = {
|
| + SQLITE_CREATE_TABLE,
|
| + SQLITE_CREATE_TEMP_TABLE,
|
| + SQLITE_CREATE_VIEW,
|
| + SQLITE_CREATE_TEMP_VIEW
|
| + };
|
| + char *zDb = db->aDb[iDb].zDbSName;
|
| if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){
|
| goto begin_table_error;
|
| }
|
| - if( isView ){
|
| - if( !OMIT_TEMPDB && isTemp ){
|
| - code = SQLITE_CREATE_TEMP_VIEW;
|
| - }else{
|
| - code = SQLITE_CREATE_VIEW;
|
| - }
|
| - }else{
|
| - if( !OMIT_TEMPDB && isTemp ){
|
| - code = SQLITE_CREATE_TEMP_TABLE;
|
| - }else{
|
| - code = SQLITE_CREATE_TABLE;
|
| - }
|
| - }
|
| - if( !isVirtual && sqlite3AuthCheck(pParse, code, zName, 0, zDb) ){
|
| + if( !isVirtual && sqlite3AuthCheck(pParse, (int)aCode[isTemp+2*isView],
|
| + zName, 0, zDb) ){
|
| goto begin_table_error;
|
| }
|
| }
|
| @@ -925,7 +908,7 @@ void sqlite3StartTable(
|
| ** collisions.
|
| */
|
| if( !IN_DECLARE_VTAB ){
|
| - char *zDb = db->aDb[iDb].zName;
|
| + char *zDb = db->aDb[iDb].zDbSName;
|
| if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
|
| goto begin_table_error;
|
| }
|
| @@ -947,15 +930,15 @@ void sqlite3StartTable(
|
|
|
| pTable = sqlite3DbMallocZero(db, sizeof(Table));
|
| if( pTable==0 ){
|
| - db->mallocFailed = 1;
|
| - pParse->rc = SQLITE_NOMEM;
|
| + assert( db->mallocFailed );
|
| + pParse->rc = SQLITE_NOMEM_BKPT;
|
| pParse->nErr++;
|
| goto begin_table_error;
|
| }
|
| pTable->zName = zName;
|
| pTable->iPKey = -1;
|
| pTable->pSchema = db->aDb[iDb].pSchema;
|
| - pTable->nRef = 1;
|
| + pTable->nTabRef = 1;
|
| pTable->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
|
| assert( pParse->pNewTable==0 );
|
| pParse->pNewTable = pTable;
|
| @@ -1004,10 +987,8 @@ void sqlite3StartTable(
|
| addr1 = sqlite3VdbeAddOp1(v, OP_If, reg3); VdbeCoverage(v);
|
| fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ?
|
| 1 : SQLITE_MAX_FILE_FORMAT;
|
| - sqlite3VdbeAddOp2(v, OP_Integer, fileFormat, reg3);
|
| - sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, reg3);
|
| - sqlite3VdbeAddOp2(v, OP_Integer, ENC(db), reg3);
|
| - sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_TEXT_ENCODING, reg3);
|
| + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, fileFormat);
|
| + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_TEXT_ENCODING, ENC(db));
|
| sqlite3VdbeJumpHere(v, addr1);
|
|
|
| /* This just creates a place-holder record in the sqlite_master table.
|
| @@ -1066,10 +1047,11 @@ void sqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol){
|
| ** first to get things going. Then this routine is called for each
|
| ** column.
|
| */
|
| -void sqlite3AddColumn(Parse *pParse, Token *pName){
|
| +void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){
|
| Table *p;
|
| int i;
|
| char *z;
|
| + char *zType;
|
| Column *pCol;
|
| sqlite3 *db = pParse->db;
|
| if( (p = pParse->pNewTable)==0 ) return;
|
| @@ -1079,8 +1061,11 @@ void sqlite3AddColumn(Parse *pParse, Token *pName){
|
| return;
|
| }
|
| #endif
|
| - z = sqlite3NameFromToken(db, pName);
|
| + z = sqlite3DbMallocRaw(db, pName->n + pType->n + 2);
|
| if( z==0 ) return;
|
| + memcpy(z, pName->z, pName->n);
|
| + z[pName->n] = 0;
|
| + sqlite3Dequote(z);
|
| for(i=0; i<p->nCol; i++){
|
| if( sqlite3_stricmp(z, p->aCol[i].zName)==0 ){
|
| sqlite3ErrorMsg(pParse, "duplicate column name: %s", z);
|
| @@ -1102,13 +1087,21 @@ void sqlite3AddColumn(Parse *pParse, Token *pName){
|
| pCol->zName = z;
|
| sqlite3ColumnPropertiesFromName(p, pCol);
|
|
|
| - /* If there is no type specified, columns have the default affinity
|
| - ** 'BLOB'. If there is a type specified, then sqlite3AddColumnType() will
|
| - ** be called next to set pCol->affinity correctly.
|
| - */
|
| - pCol->affinity = SQLITE_AFF_BLOB;
|
| - pCol->szEst = 1;
|
| + if( pType->n==0 ){
|
| + /* If there is no type specified, columns have the default affinity
|
| + ** 'BLOB'. */
|
| + pCol->affinity = SQLITE_AFF_BLOB;
|
| + pCol->szEst = 1;
|
| + }else{
|
| + zType = z + sqlite3Strlen30(z) + 1;
|
| + memcpy(zType, pType->z, pType->n);
|
| + zType[pType->n] = 0;
|
| + sqlite3Dequote(zType);
|
| + pCol->affinity = sqlite3AffinityType(zType, &pCol->szEst);
|
| + pCol->colFlags |= COLFLAG_HASTYPE;
|
| + }
|
| p->nCol++;
|
| + pParse->constraintName.n = 0;
|
| }
|
|
|
| /*
|
| @@ -1154,7 +1147,7 @@ char sqlite3AffinityType(const char *zIn, u8 *pszEst){
|
| char aff = SQLITE_AFF_NUMERIC;
|
| const char *zChar = 0;
|
|
|
| - if( zIn==0 ) return aff;
|
| + assert( zIn!=0 );
|
| while( zIn[0] ){
|
| h = (h<<8) + sqlite3UpperToLower[(*zIn)&0xff];
|
| zIn++;
|
| @@ -1212,28 +1205,6 @@ char sqlite3AffinityType(const char *zIn, u8 *pszEst){
|
| }
|
|
|
| /*
|
| -** This routine is called by the parser while in the middle of
|
| -** parsing a CREATE TABLE statement. The pFirst token is the first
|
| -** token in the sequence of tokens that describe the type of the
|
| -** column currently under construction. pLast is the last token
|
| -** in the sequence. Use this information to construct a string
|
| -** that contains the typename of the column and store that string
|
| -** in zType.
|
| -*/
|
| -void sqlite3AddColumnType(Parse *pParse, Token *pType){
|
| - Table *p;
|
| - Column *pCol;
|
| -
|
| - p = pParse->pNewTable;
|
| - if( p==0 || NEVER(p->nCol<1) ) return;
|
| - pCol = &p->aCol[p->nCol-1];
|
| - assert( pCol->zType==0 || CORRUPT_DB );
|
| - sqlite3DbFree(pParse->db, pCol->zType);
|
| - pCol->zType = sqlite3NameFromToken(pParse->db, pType);
|
| - pCol->affinity = sqlite3AffinityType(pCol->zType, &pCol->szEst);
|
| -}
|
| -
|
| -/*
|
| ** The expression is the default value for the most recently added column
|
| ** of the table currently under construction.
|
| **
|
| @@ -1258,11 +1229,16 @@ void sqlite3AddDefaultValue(Parse *pParse, ExprSpan *pSpan){
|
| ** tokens that point to volatile memory. The 'span' of the expression
|
| ** is required by pragma table_info.
|
| */
|
| + Expr x;
|
| sqlite3ExprDelete(db, pCol->pDflt);
|
| - pCol->pDflt = sqlite3ExprDup(db, pSpan->pExpr, EXPRDUP_REDUCE);
|
| - sqlite3DbFree(db, pCol->zDflt);
|
| - pCol->zDflt = sqlite3DbStrNDup(db, (char*)pSpan->zStart,
|
| - (int)(pSpan->zEnd - pSpan->zStart));
|
| + memset(&x, 0, sizeof(x));
|
| + x.op = TK_SPAN;
|
| + x.u.zToken = sqlite3DbStrNDup(db, (char*)pSpan->zStart,
|
| + (int)(pSpan->zEnd - pSpan->zStart));
|
| + x.pLeft = pSpan->pExpr;
|
| + x.flags = EP_Skip;
|
| + pCol->pDflt = sqlite3ExprDup(db, &x, EXPRDUP_REDUCE);
|
| + sqlite3DbFree(db, x.u.zToken);
|
| }
|
| }
|
| sqlite3ExprDelete(db, pSpan->pExpr);
|
| @@ -1318,10 +1294,10 @@ void sqlite3AddPrimaryKey(
|
| int sortOrder /* SQLITE_SO_ASC or SQLITE_SO_DESC */
|
| ){
|
| Table *pTab = pParse->pNewTable;
|
| - char *zType = 0;
|
| + Column *pCol = 0;
|
| int iCol = -1, i;
|
| int nTerm;
|
| - if( pTab==0 || IN_DECLARE_VTAB ) goto primary_key_exit;
|
| + if( pTab==0 ) goto primary_key_exit;
|
| if( pTab->tabFlags & TF_HasPrimaryKey ){
|
| sqlite3ErrorMsg(pParse,
|
| "table \"%s\" has more than one primary key", pTab->zName);
|
| @@ -1330,8 +1306,8 @@ void sqlite3AddPrimaryKey(
|
| pTab->tabFlags |= TF_HasPrimaryKey;
|
| if( pList==0 ){
|
| iCol = pTab->nCol - 1;
|
| - pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY;
|
| - zType = pTab->aCol[iCol].zType;
|
| + pCol = &pTab->aCol[iCol];
|
| + pCol->colFlags |= COLFLAG_PRIMKEY;
|
| nTerm = 1;
|
| }else{
|
| nTerm = pList->nExpr;
|
| @@ -1343,8 +1319,8 @@ void sqlite3AddPrimaryKey(
|
| const char *zCName = pCExpr->u.zToken;
|
| for(iCol=0; iCol<pTab->nCol; iCol++){
|
| if( sqlite3StrICmp(zCName, pTab->aCol[iCol].zName)==0 ){
|
| - pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY;
|
| - zType = pTab->aCol[iCol].zType;
|
| + pCol = &pTab->aCol[iCol];
|
| + pCol->colFlags |= COLFLAG_PRIMKEY;
|
| break;
|
| }
|
| }
|
| @@ -1352,7 +1328,8 @@ void sqlite3AddPrimaryKey(
|
| }
|
| }
|
| if( nTerm==1
|
| - && zType && sqlite3StrICmp(zType, "INTEGER")==0
|
| + && pCol
|
| + && sqlite3StrICmp(sqlite3ColumnType(pCol,""), "INTEGER")==0
|
| && sortOrder!=SQLITE_SO_DESC
|
| ){
|
| pTab->iPKey = iCol;
|
| @@ -1366,12 +1343,8 @@ void sqlite3AddPrimaryKey(
|
| "INTEGER PRIMARY KEY");
|
| #endif
|
| }else{
|
| - Index *p;
|
| - p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0,
|
| - 0, sortOrder, 0);
|
| - if( p ){
|
| - p->idxType = SQLITE_IDXTYPE_PRIMARYKEY;
|
| - }
|
| + sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0,
|
| + 0, sortOrder, 0, SQLITE_IDXTYPE_PRIMARYKEY);
|
| pList = 0;
|
| }
|
|
|
| @@ -1490,15 +1463,16 @@ CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName){
|
| ** set back to prior value. But schema changes are infrequent
|
| ** and the probability of hitting the same cookie value is only
|
| ** 1 chance in 2^32. So we're safe enough.
|
| +**
|
| +** IMPLEMENTATION-OF: R-34230-56049 SQLite automatically increments
|
| +** the schema-version whenever the schema changes.
|
| */
|
| void sqlite3ChangeCookie(Parse *pParse, int iDb){
|
| - int r1 = sqlite3GetTempReg(pParse);
|
| sqlite3 *db = pParse->db;
|
| Vdbe *v = pParse->pVdbe;
|
| assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
|
| - sqlite3VdbeAddOp2(v, OP_Integer, db->aDb[iDb].pSchema->schema_cookie+1, r1);
|
| - sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_SCHEMA_VERSION, r1);
|
| - sqlite3ReleaseTempReg(pParse, r1);
|
| + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_SCHEMA_VERSION,
|
| + db->aDb[iDb].pSchema->schema_cookie+1);
|
| }
|
|
|
| /*
|
| @@ -1580,7 +1554,7 @@ static char *createTableStmt(sqlite3 *db, Table *p){
|
| n += 35 + 6*p->nCol;
|
| zStmt = sqlite3DbMallocRaw(0, n);
|
| if( zStmt==0 ){
|
| - db->mallocFailed = 1;
|
| + sqlite3OomFault(db);
|
| return 0;
|
| }
|
| sqlite3_snprintf(n, zStmt, "CREATE TABLE ");
|
| @@ -1633,7 +1607,7 @@ static int resizeIndexObject(sqlite3 *db, Index *pIdx, int N){
|
| assert( pIdx->isResized==0 );
|
| nByte = (sizeof(char*) + sizeof(i16) + 1)*N;
|
| zExtra = sqlite3DbMallocZero(db, nByte);
|
| - if( zExtra==0 ) return SQLITE_NOMEM;
|
| + if( zExtra==0 ) return SQLITE_NOMEM_BKPT;
|
| memcpy(zExtra, pIdx->azColl, sizeof(char*)*pIdx->nColumn);
|
| pIdx->azColl = (const char**)zExtra;
|
| zExtra += sizeof(char*)*N;
|
| @@ -1690,21 +1664,23 @@ static int hasColumn(const i16 *aiCol, int nCol, int x){
|
| ** are appropriate for a WITHOUT ROWID table instead of a rowid table.
|
| ** Changes include:
|
| **
|
| -** (1) Convert the OP_CreateTable into an OP_CreateIndex. There is
|
| +** (1) Set all columns of the PRIMARY KEY schema object to be NOT NULL.
|
| +** (2) Convert the OP_CreateTable into an OP_CreateIndex. There is
|
| ** no rowid btree for a WITHOUT ROWID. Instead, the canonical
|
| ** data storage is a covering index btree.
|
| -** (2) Bypass the creation of the sqlite_master table entry
|
| +** (3) Bypass the creation of the sqlite_master table entry
|
| ** for the PRIMARY KEY as the primary key index is now
|
| ** identified by the sqlite_master table entry of the table itself.
|
| -** (3) Set the Index.tnum of the PRIMARY KEY Index object in the
|
| +** (4) Set the Index.tnum of the PRIMARY KEY Index object in the
|
| ** schema to the rootpage from the main table.
|
| -** (4) Set all columns of the PRIMARY KEY schema object to be NOT NULL.
|
| ** (5) Add all table columns to the PRIMARY KEY Index object
|
| ** so that the PRIMARY KEY is a covering index. The surplus
|
| ** columns are part of KeyInfo.nXField and are not used for
|
| ** sorting or lookup or uniqueness checks.
|
| ** (6) Replace the rowid tail on all automatically generated UNIQUE
|
| ** indices with the PRIMARY KEY columns.
|
| +**
|
| +** For virtual tables, only (1) is performed.
|
| */
|
| static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
|
| Index *pIdx;
|
| @@ -1714,6 +1690,20 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
|
| sqlite3 *db = pParse->db;
|
| Vdbe *v = pParse->pVdbe;
|
|
|
| + /* Mark every PRIMARY KEY column as NOT NULL (except for imposter tables)
|
| + */
|
| + if( !db->init.imposterTable ){
|
| + for(i=0; i<pTab->nCol; i++){
|
| + if( (pTab->aCol[i].colFlags & COLFLAG_PRIMKEY)!=0 ){
|
| + pTab->aCol[i].notNull = OE_Abort;
|
| + }
|
| + }
|
| + }
|
| +
|
| + /* The remaining transformations only apply to b-tree tables, not to
|
| + ** virtual tables */
|
| + if( IN_DECLARE_VTAB ) return;
|
| +
|
| /* Convert the OP_CreateTable opcode that would normally create the
|
| ** root-page for the table into an OP_CreateIndex opcode. The index
|
| ** created will become the PRIMARY KEY index.
|
| @@ -1729,16 +1719,16 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
|
| if( pTab->iPKey>=0 ){
|
| ExprList *pList;
|
| Token ipkToken;
|
| - ipkToken.z = pTab->aCol[pTab->iPKey].zName;
|
| - ipkToken.n = sqlite3Strlen30(ipkToken.z);
|
| + sqlite3TokenInit(&ipkToken, pTab->aCol[pTab->iPKey].zName);
|
| pList = sqlite3ExprListAppend(pParse, 0,
|
| sqlite3ExprAlloc(db, TK_ID, &ipkToken, 0));
|
| if( pList==0 ) return;
|
| pList->a[0].sortOrder = pParse->iPkSortOrder;
|
| assert( pParse->pNewTable==pTab );
|
| - pPk = sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0);
|
| - if( pPk==0 ) return;
|
| - pPk->idxType = SQLITE_IDXTYPE_PRIMARYKEY;
|
| + sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0,
|
| + SQLITE_IDXTYPE_PRIMARYKEY);
|
| + if( db->mallocFailed ) return;
|
| + pPk = sqlite3PrimaryKeyIndex(pTab);
|
| pTab->iPKey = -1;
|
| }else{
|
| pPk = sqlite3PrimaryKeyIndex(pTab);
|
| @@ -1766,19 +1756,11 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
|
| }
|
| pPk->nKeyCol = j;
|
| }
|
| - pPk->isCovering = 1;
|
| assert( pPk!=0 );
|
| + pPk->isCovering = 1;
|
| + if( !db->init.imposterTable ) pPk->uniqNotNull = 1;
|
| nPk = pPk->nKeyCol;
|
|
|
| - /* Make sure every column of the PRIMARY KEY is NOT NULL. (Except,
|
| - ** do not enforce this for imposter tables.) */
|
| - if( !db->init.imposterTable ){
|
| - for(i=0; i<nPk; i++){
|
| - pTab->aCol[pPk->aiColumn[i]].notNull = OE_Abort;
|
| - }
|
| - pPk->uniqNotNull = 1;
|
| - }
|
| -
|
| /* The root page of the PRIMARY KEY is the table root page */
|
| pPk->tnum = pTab->tnum;
|
|
|
| @@ -1873,9 +1855,13 @@ void sqlite3EndTable(
|
| ** So do not write to the disk again. Extract the root page number
|
| ** for the table from the db->init.newTnum field. (The page number
|
| ** should have been put there by the sqliteOpenCb routine.)
|
| + **
|
| + ** If the root page number is 1, that means this is the sqlite_master
|
| + ** table itself. So mark it read-only.
|
| */
|
| if( db->init.busy ){
|
| p->tnum = db->init.newTnum;
|
| + if( p->tnum==1 ) p->tabFlags |= TF_Readonly;
|
| }
|
|
|
| /* Special processing for WITHOUT ROWID Tables */
|
| @@ -1976,7 +1962,7 @@ void sqlite3EndTable(
|
| sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop);
|
| sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield);
|
| sqlite3Select(pParse, pSelect, &dest);
|
| - sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield);
|
| + sqlite3VdbeEndCoroutine(v, regYield);
|
| sqlite3VdbeJumpHere(v, addrTop - 1);
|
| if( pParse->nErr ) return;
|
| pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect);
|
| @@ -2018,7 +2004,7 @@ void sqlite3EndTable(
|
| "UPDATE %Q.%s "
|
| "SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q "
|
| "WHERE rowid=#%d",
|
| - db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
|
| + db->aDb[iDb].zDbSName, MASTER_NAME,
|
| zType,
|
| p->zName,
|
| p->zName,
|
| @@ -2033,13 +2019,13 @@ void sqlite3EndTable(
|
| /* Check to see if we need to create an sqlite_sequence table for
|
| ** keeping track of autoincrement keys.
|
| */
|
| - if( p->tabFlags & TF_Autoincrement ){
|
| + if( (p->tabFlags & TF_Autoincrement)!=0 ){
|
| Db *pDb = &db->aDb[iDb];
|
| assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
|
| if( pDb->pSchema->pSeqTab==0 ){
|
| sqlite3NestedParse(pParse,
|
| "CREATE TABLE %Q.sqlite_sequence(name,seq)",
|
| - pDb->zName
|
| + pDb->zDbSName
|
| );
|
| }
|
| }
|
| @@ -2060,7 +2046,7 @@ void sqlite3EndTable(
|
| pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName, p);
|
| if( pOld ){
|
| assert( p==pOld ); /* Malloc must have failed inside HashInsert() */
|
| - db->mallocFailed = 1;
|
| + sqlite3OomFault(db);
|
| return;
|
| }
|
| pParse->pNewTable = 0;
|
| @@ -2163,8 +2149,9 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
|
| int nErr = 0; /* Number of errors encountered */
|
| int n; /* Temporarily holds the number of cursors assigned */
|
| sqlite3 *db = pParse->db; /* Database connection for malloc errors */
|
| +#ifndef SQLITE_OMIT_AUTHORIZATION
|
| sqlite3_xauth xAuth; /* Saved xAuth pointer */
|
| - u8 bEnabledLA; /* Saved db->lookaside.bEnabled state */
|
| +#endif
|
|
|
| assert( pTable );
|
|
|
| @@ -2210,45 +2197,56 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
|
| ** statement that defines the view.
|
| */
|
| assert( pTable->pSelect );
|
| - bEnabledLA = db->lookaside.bEnabled;
|
| - if( pTable->pCheck ){
|
| - db->lookaside.bEnabled = 0;
|
| - sqlite3ColumnsFromExprList(pParse, pTable->pCheck,
|
| - &pTable->nCol, &pTable->aCol);
|
| - }else{
|
| - pSel = sqlite3SelectDup(db, pTable->pSelect, 0);
|
| - if( pSel ){
|
| - n = pParse->nTab;
|
| - sqlite3SrcListAssignCursors(pParse, pSel->pSrc);
|
| - pTable->nCol = -1;
|
| - db->lookaside.bEnabled = 0;
|
| + pSel = sqlite3SelectDup(db, pTable->pSelect, 0);
|
| + if( pSel ){
|
| + n = pParse->nTab;
|
| + sqlite3SrcListAssignCursors(pParse, pSel->pSrc);
|
| + pTable->nCol = -1;
|
| + db->lookaside.bDisable++;
|
| #ifndef SQLITE_OMIT_AUTHORIZATION
|
| - xAuth = db->xAuth;
|
| - db->xAuth = 0;
|
| - pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
|
| - db->xAuth = xAuth;
|
| + xAuth = db->xAuth;
|
| + db->xAuth = 0;
|
| + pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
|
| + db->xAuth = xAuth;
|
| #else
|
| - pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
|
| + pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
|
| #endif
|
| - pParse->nTab = n;
|
| - if( pSelTab ){
|
| - assert( pTable->aCol==0 );
|
| - pTable->nCol = pSelTab->nCol;
|
| - pTable->aCol = pSelTab->aCol;
|
| - pSelTab->nCol = 0;
|
| - pSelTab->aCol = 0;
|
| - sqlite3DeleteTable(db, pSelTab);
|
| - assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) );
|
| - }else{
|
| - pTable->nCol = 0;
|
| - nErr++;
|
| + pParse->nTab = n;
|
| + if( pTable->pCheck ){
|
| + /* CREATE VIEW name(arglist) AS ...
|
| + ** The names of the columns in the table are taken from
|
| + ** arglist which is stored in pTable->pCheck. The pCheck field
|
| + ** normally holds CHECK constraints on an ordinary table, but for
|
| + ** a VIEW it holds the list of column names.
|
| + */
|
| + sqlite3ColumnsFromExprList(pParse, pTable->pCheck,
|
| + &pTable->nCol, &pTable->aCol);
|
| + if( db->mallocFailed==0
|
| + && pParse->nErr==0
|
| + && pTable->nCol==pSel->pEList->nExpr
|
| + ){
|
| + sqlite3SelectAddColumnTypeAndCollation(pParse, pTable, pSel);
|
| }
|
| - sqlite3SelectDelete(db, pSel);
|
| - } else {
|
| + }else if( pSelTab ){
|
| + /* CREATE VIEW name AS... without an argument list. Construct
|
| + ** the column names from the SELECT statement that defines the view.
|
| + */
|
| + assert( pTable->aCol==0 );
|
| + pTable->nCol = pSelTab->nCol;
|
| + pTable->aCol = pSelTab->aCol;
|
| + pSelTab->nCol = 0;
|
| + pSelTab->aCol = 0;
|
| + assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) );
|
| + }else{
|
| + pTable->nCol = 0;
|
| nErr++;
|
| }
|
| + sqlite3DeleteTable(db, pSelTab);
|
| + sqlite3SelectDelete(db, pSel);
|
| + db->lookaside.bDisable--;
|
| + } else {
|
| + nErr++;
|
| }
|
| - db->lookaside.bEnabled = bEnabledLA;
|
| pTable->pSchema->schemaFlags |= DB_UnresetViews;
|
| #endif /* SQLITE_OMIT_VIEW */
|
| return nErr;
|
| @@ -2328,6 +2326,7 @@ void sqlite3RootPageMoved(sqlite3 *db, int iDb, int iFrom, int iTo){
|
| static void destroyRootPage(Parse *pParse, int iTable, int iDb){
|
| Vdbe *v = sqlite3GetVdbe(pParse);
|
| int r1 = sqlite3GetTempReg(pParse);
|
| + assert( iTable>1 );
|
| sqlite3VdbeAddOp3(v, OP_Destroy, iTable, r1, iDb);
|
| sqlite3MayAbort(pParse);
|
| #ifndef SQLITE_OMIT_AUTOVACUUM
|
| @@ -2342,7 +2341,7 @@ static void destroyRootPage(Parse *pParse, int iTable, int iDb){
|
| */
|
| sqlite3NestedParse(pParse,
|
| "UPDATE %Q.%s SET rootpage=%d WHERE #%d AND rootpage=#%d",
|
| - pParse->db->aDb[iDb].zName, SCHEMA_TABLE(iDb), iTable, r1, r1);
|
| + pParse->db->aDb[iDb].zDbSName, MASTER_NAME, iTable, r1, r1);
|
| #endif
|
| sqlite3ReleaseTempReg(pParse, r1);
|
| }
|
| @@ -2418,7 +2417,7 @@ static void sqlite3ClearStatTables(
|
| const char *zName /* Name of index or table */
|
| ){
|
| int i;
|
| - const char *zDbName = pParse->db->aDb[iDb].zName;
|
| + const char *zDbName = pParse->db->aDb[iDb].zDbSName;
|
| for(i=1; i<=4; i++){
|
| char zTab[24];
|
| sqlite3_snprintf(sizeof(zTab),zTab,"sqlite_stat%d",i);
|
| @@ -2471,7 +2470,7 @@ void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, int isView){
|
| if( pTab->tabFlags & TF_Autoincrement ){
|
| sqlite3NestedParse(pParse,
|
| "DELETE FROM %Q.sqlite_sequence WHERE name=%Q",
|
| - pDb->zName, pTab->zName
|
| + pDb->zDbSName, pTab->zName
|
| );
|
| }
|
| #endif
|
| @@ -2485,7 +2484,7 @@ void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, int isView){
|
| */
|
| sqlite3NestedParse(pParse,
|
| "DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'",
|
| - pDb->zName, SCHEMA_TABLE(iDb), pTab->zName);
|
| + pDb->zDbSName, MASTER_NAME, pTab->zName);
|
| if( !isView && !IsVirtual(pTab) ){
|
| destroyTable(pParse, pTab);
|
| }
|
| @@ -2518,6 +2517,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
|
| assert( pName->nSrc==1 );
|
| if( sqlite3ReadSchema(pParse) ) goto exit_drop_table;
|
| if( noErr ) db->suppressErr++;
|
| + assert( isView==0 || isView==LOCATE_VIEW );
|
| pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]);
|
| if( noErr ) db->suppressErr--;
|
|
|
| @@ -2538,7 +2538,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
|
| {
|
| int code;
|
| const char *zTab = SCHEMA_TABLE(iDb);
|
| - const char *zDb = db->aDb[iDb].zName;
|
| + const char *zDb = db->aDb[iDb].zDbSName;
|
| const char *zArg2 = 0;
|
| if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb)){
|
| goto exit_drop_table;
|
| @@ -2713,7 +2713,7 @@ void sqlite3CreateForeignKey(
|
| pFKey->zTo, (void *)pFKey
|
| );
|
| if( pNextTo==pFKey ){
|
| - db->mallocFailed = 1;
|
| + sqlite3OomFault(db);
|
| goto fk_end;
|
| }
|
| if( pNextTo ){
|
| @@ -2779,7 +2779,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
|
|
|
| #ifndef SQLITE_OMIT_AUTHORIZATION
|
| if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0,
|
| - db->aDb[iDb].zName ) ){
|
| + db->aDb[iDb].zDbSName ) ){
|
| return;
|
| }
|
| #endif
|
| @@ -2795,6 +2795,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
|
| tnum = pIndex->tnum;
|
| }
|
| pKey = sqlite3KeyInfoOfIndex(pParse, pIndex);
|
| + assert( pKey!=0 || db->mallocFailed || pParse->nErr );
|
|
|
| /* Open the sorter cursor if we are to use one. */
|
| iSorter = pParse->nTab++;
|
| @@ -2818,8 +2819,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
|
| sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0));
|
|
|
| addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); VdbeCoverage(v);
|
| - assert( pKey!=0 || db->mallocFailed || pParse->nErr );
|
| - if( IsUniqueIndex(pIndex) && pKey!=0 ){
|
| + if( IsUniqueIndex(pIndex) ){
|
| int j2 = sqlite3VdbeCurrentAddr(v) + 3;
|
| sqlite3VdbeGoto(v, j2);
|
| addr2 = sqlite3VdbeCurrentAddr(v);
|
| @@ -2831,7 +2831,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
|
| }
|
| sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx);
|
| sqlite3VdbeAddOp3(v, OP_Last, iIdx, 0, -1);
|
| - sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 0);
|
| + sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdx, regRecord);
|
| sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
|
| sqlite3ReleaseTempReg(pParse, regRecord);
|
| sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v);
|
| @@ -2888,12 +2888,8 @@ Index *sqlite3AllocateIndexObject(
|
| ** pList is a list of columns to be indexed. pList will be NULL if this
|
| ** is a primary key or unique-constraint on the most recent column added
|
| ** to the table currently under construction.
|
| -**
|
| -** If the index is created successfully, return a pointer to the new Index
|
| -** structure. This is used by sqlite3AddPrimaryKey() to mark the index
|
| -** as the tables primary key (Index.idxType==SQLITE_IDXTYPE_PRIMARYKEY)
|
| */
|
| -Index *sqlite3CreateIndex(
|
| +void sqlite3CreateIndex(
|
| Parse *pParse, /* All information about this parse */
|
| Token *pName1, /* First part of index name. May be NULL */
|
| Token *pName2, /* Second part of index name. May be NULL */
|
| @@ -2903,9 +2899,9 @@ Index *sqlite3CreateIndex(
|
| Token *pStart, /* The CREATE token that begins this statement */
|
| Expr *pPIWhere, /* WHERE clause for partial indices */
|
| int sortOrder, /* Sort order of primary key when pList==NULL */
|
| - int ifNotExist /* Omit error if index already exists */
|
| + int ifNotExist, /* Omit error if index already exists */
|
| + u8 idxType /* The index type */
|
| ){
|
| - Index *pRet = 0; /* Pointer to return */
|
| Table *pTab = 0; /* Table to be indexed */
|
| Index *pIndex = 0; /* The index to be created */
|
| char *zName = 0; /* Name of the index */
|
| @@ -2923,7 +2919,10 @@ Index *sqlite3CreateIndex(
|
| char *zExtra = 0; /* Extra space after the Index object */
|
| Index *pPk = 0; /* PRIMARY KEY index for WITHOUT ROWID tables */
|
|
|
| - if( db->mallocFailed || IN_DECLARE_VTAB || pParse->nErr>0 ){
|
| + if( db->mallocFailed || pParse->nErr>0 ){
|
| + goto exit_create_index;
|
| + }
|
| + if( IN_DECLARE_VTAB && idxType!=SQLITE_IDXTYPE_PRIMARYKEY ){
|
| goto exit_create_index;
|
| }
|
| if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
|
| @@ -3032,7 +3031,7 @@ Index *sqlite3CreateIndex(
|
| goto exit_create_index;
|
| }
|
| }
|
| - if( sqlite3FindIndex(db, zName, pDb->zName)!=0 ){
|
| + if( sqlite3FindIndex(db, zName, pDb->zDbSName)!=0 ){
|
| if( !ifNotExist ){
|
| sqlite3ErrorMsg(pParse, "index %s already exists", zName);
|
| }else{
|
| @@ -3049,13 +3048,20 @@ Index *sqlite3CreateIndex(
|
| if( zName==0 ){
|
| goto exit_create_index;
|
| }
|
| +
|
| + /* Automatic index names generated from within sqlite3_declare_vtab()
|
| + ** must have names that are distinct from normal automatic index names.
|
| + ** The following statement converts "sqlite3_autoindex..." into
|
| + ** "sqlite3_butoindex..." in order to make the names distinct.
|
| + ** The "vtab_err.test" test demonstrates the need of this statement. */
|
| + if( IN_DECLARE_VTAB ) zName[7]++;
|
| }
|
|
|
| /* Check for authorization to create an index.
|
| */
|
| #ifndef SQLITE_OMIT_AUTHORIZATION
|
| {
|
| - const char *zDb = pDb->zName;
|
| + const char *zDb = pDb->zDbSName;
|
| if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iDb), 0, zDb) ){
|
| goto exit_create_index;
|
| }
|
| @@ -3073,8 +3079,7 @@ Index *sqlite3CreateIndex(
|
| */
|
| if( pList==0 ){
|
| Token prevCol;
|
| - prevCol.z = pTab->aCol[pTab->nCol-1].zName;
|
| - prevCol.n = sqlite3Strlen30(prevCol.z);
|
| + sqlite3TokenInit(&prevCol, pTab->aCol[pTab->nCol-1].zName);
|
| pList = sqlite3ExprListAppend(pParse, 0,
|
| sqlite3ExprAlloc(db, TK_ID, &prevCol, 0));
|
| if( pList==0 ) goto exit_create_index;
|
| @@ -3113,7 +3118,7 @@ Index *sqlite3CreateIndex(
|
| pIndex->pTable = pTab;
|
| pIndex->onError = (u8)onError;
|
| pIndex->uniqNotNull = onError!=OE_None;
|
| - pIndex->idxType = pName ? SQLITE_IDXTYPE_APPDEF : SQLITE_IDXTYPE_UNIQUE;
|
| + pIndex->idxType = idxType;
|
| pIndex->pSchema = db->aDb[iDb].pSchema;
|
| pIndex->nKeyCol = pList->nExpr;
|
| if( pPIWhere ){
|
| @@ -3223,6 +3228,20 @@ Index *sqlite3CreateIndex(
|
| sqlite3DefaultRowEst(pIndex);
|
| if( pParse->pNewTable==0 ) estimateIndexWidth(pIndex);
|
|
|
| + /* If this index contains every column of its table, then mark
|
| + ** it as a covering index */
|
| + assert( HasRowid(pTab)
|
| + || pTab->iPKey<0 || sqlite3ColumnOfIndex(pIndex, pTab->iPKey)>=0 );
|
| + if( pTblName!=0 && pIndex->nColumn>=pTab->nCol ){
|
| + pIndex->isCovering = 1;
|
| + for(j=0; j<pTab->nCol; j++){
|
| + if( j==pTab->iPKey ) continue;
|
| + if( sqlite3ColumnOfIndex(pIndex,j)>=0 ) continue;
|
| + pIndex->isCovering = 0;
|
| + break;
|
| + }
|
| + }
|
| +
|
| if( pTab==pParse->pNewTable ){
|
| /* This routine has been called to create an automatic index as a
|
| ** result of a PRIMARY KEY or UNIQUE clause on a column definition, or
|
| @@ -3260,7 +3279,7 @@ Index *sqlite3CreateIndex(
|
| if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break;
|
| z1 = pIdx->azColl[k];
|
| z2 = pIndex->azColl[k];
|
| - if( z1!=z2 && sqlite3StrICmp(z1, z2) ) break;
|
| + if( sqlite3StrICmp(z1, z2) ) break;
|
| }
|
| if( k==pIdx->nKeyCol ){
|
| if( pIdx->onError!=pIndex->onError ){
|
| @@ -3279,7 +3298,7 @@ Index *sqlite3CreateIndex(
|
| pIdx->onError = pIndex->onError;
|
| }
|
| }
|
| - pRet = pIdx;
|
| + if( idxType==SQLITE_IDXTYPE_PRIMARYKEY ) pIdx->idxType = idxType;
|
| goto exit_create_index;
|
| }
|
| }
|
| @@ -3291,12 +3310,13 @@ Index *sqlite3CreateIndex(
|
| assert( pParse->nErr==0 );
|
| if( db->init.busy ){
|
| Index *p;
|
| + assert( !IN_DECLARE_VTAB );
|
| assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) );
|
| p = sqlite3HashInsert(&pIndex->pSchema->idxHash,
|
| pIndex->zName, pIndex);
|
| if( p ){
|
| assert( p==pIndex ); /* Malloc must have failed */
|
| - db->mallocFailed = 1;
|
| + sqlite3OomFault(db);
|
| goto exit_create_index;
|
| }
|
| db->flags |= SQLITE_InternChanges;
|
| @@ -3356,7 +3376,7 @@ Index *sqlite3CreateIndex(
|
| */
|
| sqlite3NestedParse(pParse,
|
| "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#%d,%Q);",
|
| - db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
|
| + db->aDb[iDb].zDbSName, MASTER_NAME,
|
| pIndex->zName,
|
| pTab->zName,
|
| iMem,
|
| @@ -3372,7 +3392,7 @@ Index *sqlite3CreateIndex(
|
| sqlite3ChangeCookie(pParse, iDb);
|
| sqlite3VdbeAddParseSchemaOp(v, iDb,
|
| sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName));
|
| - sqlite3VdbeAddOp1(v, OP_Expire, 0);
|
| + sqlite3VdbeAddOp0(v, OP_Expire);
|
| }
|
|
|
| sqlite3VdbeJumpHere(v, pIndex->tnum);
|
| @@ -3397,7 +3417,6 @@ Index *sqlite3CreateIndex(
|
| pIndex->pNext = pOther->pNext;
|
| pOther->pNext = pIndex;
|
| }
|
| - pRet = pIndex;
|
| pIndex = 0;
|
| }
|
|
|
| @@ -3408,7 +3427,6 @@ exit_create_index:
|
| sqlite3ExprListDelete(db, pList);
|
| sqlite3SrcListDelete(db, pTblName);
|
| sqlite3DbFree(db, zName);
|
| - return pRet;
|
| }
|
|
|
| /*
|
| @@ -3437,10 +3455,11 @@ void sqlite3DefaultRowEst(Index *pIdx){
|
| int i;
|
|
|
| /* Set the first entry (number of rows in the index) to the estimated
|
| - ** number of rows in the table. Or 10, if the estimated number of rows
|
| - ** in the table is less than that. */
|
| + ** number of rows in the table, or half the number of rows in the table
|
| + ** for a partial index. But do not let the estimate drop below 10. */
|
| a[0] = pIdx->pTable->nRowLogEst;
|
| - if( a[0]<33 ) a[0] = 33; assert( 33==sqlite3LogEst(10) );
|
| + if( pIdx->pPartIdxWhere!=0 ) a[0] -= 10; assert( 10==sqlite3LogEst(2) );
|
| + if( a[0]<33 ) a[0] = 33; assert( 33==sqlite3LogEst(10) );
|
|
|
| /* Estimate that a[1] is 10, a[2] is 9, a[3] is 8, a[4] is 7, a[5] is
|
| ** 6 and each subsequent value (if any) is 5. */
|
| @@ -3491,7 +3510,7 @@ void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){
|
| {
|
| int code = SQLITE_DROP_INDEX;
|
| Table *pTab = pIndex->pTable;
|
| - const char *zDb = db->aDb[iDb].zName;
|
| + const char *zDb = db->aDb[iDb].zDbSName;
|
| const char *zTab = SCHEMA_TABLE(iDb);
|
| if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
|
| goto exit_drop_index;
|
| @@ -3509,7 +3528,7 @@ void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){
|
| sqlite3BeginWriteOperation(pParse, 1, iDb);
|
| sqlite3NestedParse(pParse,
|
| "DELETE FROM %Q.%s WHERE name=%Q AND type='index'",
|
| - db->aDb[iDb].zName, SCHEMA_TABLE(iDb), pIndex->zName
|
| + db->aDb[iDb].zDbSName, MASTER_NAME, pIndex->zName
|
| );
|
| sqlite3ClearStatTables(pParse, iDb, "idx", pIndex->zName);
|
| sqlite3ChangeCookie(pParse, iDb);
|
| @@ -3652,7 +3671,7 @@ SrcList *sqlite3SrcListEnlarge(
|
| /* Allocate additional space if needed */
|
| if( (u32)pSrc->nSrc+nExtra>pSrc->nAlloc ){
|
| SrcList *pNew;
|
| - int nAlloc = pSrc->nSrc+nExtra;
|
| + int nAlloc = pSrc->nSrc*2+nExtra;
|
| int nGot;
|
| pNew = sqlite3DbRealloc(db, pSrc,
|
| sizeof(*pSrc) + (nAlloc-1)*sizeof(pSrc->a[0]) );
|
| @@ -3725,12 +3744,17 @@ SrcList *sqlite3SrcListAppend(
|
| ){
|
| struct SrcList_item *pItem;
|
| assert( pDatabase==0 || pTable!=0 ); /* Cannot have C without B */
|
| + assert( db!=0 );
|
| if( pList==0 ){
|
| - pList = sqlite3DbMallocZero(db, sizeof(SrcList) );
|
| + pList = sqlite3DbMallocRawNN(db, sizeof(SrcList) );
|
| if( pList==0 ) return 0;
|
| pList->nAlloc = 1;
|
| + pList->nSrc = 1;
|
| + memset(&pList->a[0], 0, sizeof(pList->a[0]));
|
| + pList->a[0].iCursor = -1;
|
| + }else{
|
| + pList = sqlite3SrcListEnlarge(db, pList, 1, pList->nSrc);
|
| }
|
| - pList = sqlite3SrcListEnlarge(db, pList, 1, pList->nSrc);
|
| if( db->mallocFailed ){
|
| sqlite3SrcListDelete(db, pList);
|
| return 0;
|
| @@ -3909,7 +3933,7 @@ void sqlite3SrcListShiftJoinType(SrcList *p){
|
| }
|
|
|
| /*
|
| -** Begin a transaction
|
| +** Generate VDBE code for a BEGIN statement.
|
| */
|
| void sqlite3BeginTransaction(Parse *pParse, int type){
|
| sqlite3 *db;
|
| @@ -3919,7 +3943,6 @@ void sqlite3BeginTransaction(Parse *pParse, int type){
|
| assert( pParse!=0 );
|
| db = pParse->db;
|
| assert( db!=0 );
|
| -/* if( db->aDb[0].pBt==0 ) return; */
|
| if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ){
|
| return;
|
| }
|
| @@ -3931,11 +3954,11 @@ void sqlite3BeginTransaction(Parse *pParse, int type){
|
| sqlite3VdbeUsesBtree(v, i);
|
| }
|
| }
|
| - sqlite3VdbeAddOp2(v, OP_AutoCommit, 0, 0);
|
| + sqlite3VdbeAddOp0(v, OP_AutoCommit);
|
| }
|
|
|
| /*
|
| -** Commit a transaction
|
| +** Generate VDBE code for a COMMIT statement.
|
| */
|
| void sqlite3CommitTransaction(Parse *pParse){
|
| Vdbe *v;
|
| @@ -3947,12 +3970,12 @@ void sqlite3CommitTransaction(Parse *pParse){
|
| }
|
| v = sqlite3GetVdbe(pParse);
|
| if( v ){
|
| - sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, 0);
|
| + sqlite3VdbeAddOp1(v, OP_AutoCommit, 1);
|
| }
|
| }
|
|
|
| /*
|
| -** Rollback a transaction
|
| +** Generate VDBE code for a ROLLBACK statement.
|
| */
|
| void sqlite3RollbackTransaction(Parse *pParse){
|
| Vdbe *v;
|
| @@ -4014,7 +4037,7 @@ int sqlite3OpenTempDatabase(Parse *pParse){
|
| db->aDb[1].pBt = pBt;
|
| assert( db->aDb[1].pSchema );
|
| if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, -1, 0) ){
|
| - db->mallocFailed = 1;
|
| + sqlite3OomFault(db);
|
| return 1;
|
| }
|
| }
|
| @@ -4029,15 +4052,13 @@ int sqlite3OpenTempDatabase(Parse *pParse){
|
| */
|
| void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
|
| Parse *pToplevel = sqlite3ParseToplevel(pParse);
|
| - sqlite3 *db = pToplevel->db;
|
|
|
| - assert( iDb>=0 && iDb<db->nDb );
|
| - assert( db->aDb[iDb].pBt!=0 || iDb==1 );
|
| + assert( iDb>=0 && iDb<pParse->db->nDb );
|
| + assert( pParse->db->aDb[iDb].pBt!=0 || iDb==1 );
|
| assert( iDb<SQLITE_MAX_ATTACHED+2 );
|
| - assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
|
| + assert( sqlite3SchemaMutexHeld(pParse->db, iDb, 0) );
|
| if( DbMaskTest(pToplevel->cookieMask, iDb)==0 ){
|
| DbMaskSet(pToplevel->cookieMask, iDb);
|
| - pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie;
|
| if( !OMIT_TEMPDB && iDb==1 ){
|
| sqlite3OpenTempDatabase(pToplevel);
|
| }
|
| @@ -4053,7 +4074,7 @@ void sqlite3CodeVerifyNamedSchema(Parse *pParse, const char *zDb){
|
| int i;
|
| for(i=0; i<db->nDb; i++){
|
| Db *pDb = &db->aDb[i];
|
| - if( pDb->pBt && (!zDb || 0==sqlite3StrICmp(zDb, pDb->zName)) ){
|
| + if( pDb->pBt && (!zDb || 0==sqlite3StrICmp(zDb, pDb->zDbSName)) ){
|
| sqlite3CodeVerifySchema(pParse, i);
|
| }
|
| }
|
| @@ -4131,7 +4152,7 @@ void sqlite3HaltConstraint(
|
| sqlite3MayAbort(pParse);
|
| }
|
| sqlite3VdbeAddOp4(v, OP_Halt, errCode, onError, 0, p4, p4type);
|
| - if( p5Errmsg ) sqlite3VdbeChangeP5(v, p5Errmsg);
|
| + sqlite3VdbeChangeP5(v, p5Errmsg);
|
| }
|
|
|
| /*
|
| @@ -4149,14 +4170,14 @@ void sqlite3UniqueConstraint(
|
|
|
| sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 200);
|
| if( pIdx->aColExpr ){
|
| - sqlite3XPrintf(&errMsg, 0, "index '%q'", pIdx->zName);
|
| + sqlite3XPrintf(&errMsg, "index '%q'", pIdx->zName);
|
| }else{
|
| for(j=0; j<pIdx->nKeyCol; j++){
|
| char *zCol;
|
| assert( pIdx->aiColumn[j]>=0 );
|
| zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
|
| if( j ) sqlite3StrAccumAppend(&errMsg, ", ", 2);
|
| - sqlite3XPrintf(&errMsg, 0, "%s.%s", pTab->zName, zCol);
|
| + sqlite3XPrintf(&errMsg, "%s.%s", pTab->zName, zCol);
|
| }
|
| }
|
| zErr = sqlite3StrAccumFinish(&errMsg);
|
| @@ -4300,7 +4321,7 @@ void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){
|
| if( iDb<0 ) return;
|
| z = sqlite3NameFromToken(db, pObjName);
|
| if( z==0 ) return;
|
| - zDb = db->aDb[iDb].zName;
|
| + zDb = db->aDb[iDb].zDbSName;
|
| pTab = sqlite3FindTable(db, z, zDb);
|
| if( pTab ){
|
| reindexTable(pParse, pTab, 0);
|
| @@ -4321,10 +4342,6 @@ void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){
|
| /*
|
| ** Return a KeyInfo structure that is appropriate for the given Index.
|
| **
|
| -** The KeyInfo structure for an index is cached in the Index object.
|
| -** So there might be multiple references to the returned pointer. The
|
| -** caller should not try to modify the KeyInfo object.
|
| -**
|
| ** The caller should invoke sqlite3KeyInfoUnref() on the returned object
|
| ** when it has finished using it.
|
| */
|
| @@ -4389,10 +4406,9 @@ With *sqlite3WithAdd(
|
| }else{
|
| pNew = sqlite3DbMallocZero(db, sizeof(*pWith));
|
| }
|
| - assert( zName!=0 || pNew==0 );
|
| - assert( db->mallocFailed==0 || pNew==0 );
|
| + assert( (pNew!=0 && zName!=0) || db->mallocFailed );
|
|
|
| - if( pNew==0 ){
|
| + if( db->mallocFailed ){
|
| sqlite3ExprListDelete(db, pArglist);
|
| sqlite3SelectDelete(db, pQuery);
|
| sqlite3DbFree(db, zName);
|
|
|