diff options
| author | Scott MacVicar <scottmac@php.net> | 2008-03-07 10:55:14 +0000 |
|---|---|---|
| committer | Scott MacVicar <scottmac@php.net> | 2008-03-07 10:55:14 +0000 |
| commit | 31dade5280849135b00fd1c5e53d057732a72776 (patch) | |
| tree | 564b9f0f9d8cf89d7df9a9c12147ba8a5da6506f /ext/pdo_sqlite/sqlite/src/build.c | |
| parent | 7abf0787ad9fd613ddde880c9bc163161d7bf4ff (diff) | |
| download | php-git-31dade5280849135b00fd1c5e53d057732a72776.tar.gz | |
MFB: Update bundled SQLite to 3.5.6
Diffstat (limited to 'ext/pdo_sqlite/sqlite/src/build.c')
| -rw-r--r-- | ext/pdo_sqlite/sqlite/src/build.c | 793 |
1 files changed, 487 insertions, 306 deletions
diff --git a/ext/pdo_sqlite/sqlite/src/build.c b/ext/pdo_sqlite/sqlite/src/build.c index 5294c1a316..6ee1cd0e07 100644 --- a/ext/pdo_sqlite/sqlite/src/build.c +++ b/ext/pdo_sqlite/sqlite/src/build.c @@ -69,7 +69,7 @@ void sqlite3TableLock( int nBytes; TableLock *p; - if( 0==sqlite3ThreadDataReadOnly()->useSharedData || iDb<0 ){ + if( iDb<0 ){ return; } @@ -82,13 +82,17 @@ void sqlite3TableLock( } nBytes = sizeof(TableLock) * (pParse->nTableLock+1); - sqliteReallocOrFree((void **)&pParse->aTableLock, nBytes); + pParse->aTableLock = + sqlite3DbReallocOrFree(pParse->db, pParse->aTableLock, nBytes); if( pParse->aTableLock ){ p = &pParse->aTableLock[pParse->nTableLock++]; p->iDb = iDb; p->iTab = iTab; p->isWriteLock = isWriteLock; p->zName = zName; + }else{ + pParse->nTableLock = 0; + pParse->db->mallocFailed = 1; } } @@ -99,7 +103,6 @@ void sqlite3TableLock( static void codeTableLocks(Parse *pParse){ int i; Vdbe *pVdbe; - assert( sqlite3ThreadDataReadOnly()->useSharedData || pParse->nTableLock==0 ); if( 0==(pVdbe = sqlite3GetVdbe(pParse)) ){ return; @@ -111,7 +114,7 @@ static void codeTableLocks(Parse *pParse){ if( p->isWriteLock ){ p1 = -1*(p1+1); } - sqlite3VdbeOp3(pVdbe, OP_TableLock, p1, p->iTab, p->zName, P3_STATIC); + sqlite3VdbeAddOp4(pVdbe, OP_TableLock, p1, p->iTab, 0, p->zName, P4_STATIC); } } #else @@ -132,8 +135,10 @@ void sqlite3FinishCoding(Parse *pParse){ sqlite3 *db; Vdbe *v; - if( sqlite3MallocFailed() ) return; + db = pParse->db; + if( db->mallocFailed ) return; if( pParse->nested ) return; + if( pParse->nErr ) return; if( !pParse->pVdbe ){ if( pParse->rc==SQLITE_OK && pParse->nErr ){ pParse->rc = SQLITE_ERROR; @@ -144,10 +149,9 @@ void sqlite3FinishCoding(Parse *pParse){ /* Begin by generating some termination code at the end of the ** vdbe program */ - db = pParse->db; v = sqlite3GetVdbe(pParse); if( v ){ - sqlite3VdbeAddOp(v, OP_Halt, 0, 0); + sqlite3VdbeAddOp0(v, OP_Halt); /* The cookie mask contains one bit for each database file open. ** (Bit 0 is for main, bit 1 is for temp, and so forth.) Bits are @@ -161,13 +165,14 @@ void sqlite3FinishCoding(Parse *pParse){ sqlite3VdbeJumpHere(v, pParse->cookieGoto-1); for(iDb=0, mask=1; iDb<db->nDb; mask<<=1, iDb++){ if( (mask & pParse->cookieMask)==0 ) continue; - sqlite3VdbeAddOp(v, OP_Transaction, iDb, (mask & pParse->writeMask)!=0); - sqlite3VdbeAddOp(v, OP_VerifyCookie, iDb, pParse->cookieValue[iDb]); + sqlite3VdbeUsesBtree(v, iDb); + sqlite3VdbeAddOp2(v,OP_Transaction, iDb, (mask & pParse->writeMask)!=0); + sqlite3VdbeAddOp2(v,OP_VerifyCookie, iDb, pParse->cookieValue[iDb]); } #ifndef SQLITE_OMIT_VIRTUALTABLE if( pParse->pVirtualLock ){ char *vtab = (char *)pParse->pVirtualLock->pVtab; - sqlite3VdbeOp3(v, OP_VBegin, 0, 0, vtab, P3_VTAB); + sqlite3VdbeAddOp4(v, OP_VBegin, 0, 0, 0, vtab, P4_VTAB); } #endif @@ -176,26 +181,30 @@ void sqlite3FinishCoding(Parse *pParse){ ** shared-cache feature is enabled. */ codeTableLocks(pParse); - sqlite3VdbeAddOp(v, OP_Goto, 0, pParse->cookieGoto); + sqlite3VdbeAddOp2(v, OP_Goto, 0, pParse->cookieGoto); } #ifndef SQLITE_OMIT_TRACE - /* Add a No-op that contains the complete text of the compiled SQL - ** statement as its P3 argument. This does not change the functionality - ** of the program. - ** - ** This is used to implement sqlite3_trace(). - */ - sqlite3VdbeOp3(v, OP_Noop, 0, 0, pParse->zSql, pParse->zTail-pParse->zSql); + if( !db->init.busy ){ + /* Change the P4 argument of the first opcode (which will always be + ** an OP_Trace) to be the complete text of the current SQL statement. + */ + VdbeOp *pOp = sqlite3VdbeGetOp(v, 0); + if( pOp && pOp->opcode==OP_Trace ){ + sqlite3VdbeChangeP4(v, 0, pParse->zSql, pParse->zTail-pParse->zSql); + } + } #endif /* SQLITE_OMIT_TRACE */ } /* Get the VDBE program ready for execution */ - if( v && pParse->nErr==0 && !sqlite3MallocFailed() ){ + if( v && pParse->nErr==0 && !db->mallocFailed ){ +#ifdef SQLITE_DEBUG FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0; sqlite3VdbeTrace(v, trace); +#endif sqlite3VdbeMakeReady(v, pParse->nVar, pParse->nMem+3, pParse->nTab+3, pParse->explain); pParse->rc = SQLITE_DONE; @@ -232,16 +241,17 @@ void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){ if( pParse->nErr ) return; assert( pParse->nested<10 ); /* Nesting should only be of limited depth */ va_start(ap, zFormat); - zSql = sqlite3VMPrintf(zFormat, ap); + zSql = sqlite3VMPrintf(pParse->db, zFormat, ap); va_end(ap); if( zSql==0 ){ + pParse->db->mallocFailed = 1; return; /* A malloc must have failed */ } pParse->nested++; memcpy(saveBuf, &pParse->nVar, SAVE_SZ); memset(&pParse->nVar, 0, SAVE_SZ); sqlite3RunParser(pParse, zSql, 0); - sqliteFree(zSql); + sqlite3_free(zSql); memcpy(&pParse->nVar, saveBuf, SAVE_SZ); pParse->nested--; } @@ -281,7 +291,12 @@ Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){ ** routine leaves an error message in pParse->zErrMsg where ** sqlite3FindTable() does not. */ -Table *sqlite3LocateTable(Parse *pParse, const char *zName, const char *zDbase){ +Table *sqlite3LocateTable( + Parse *pParse, /* context in which to report errors */ + int isView, /* True if looking for a VIEW rather than a TABLE */ + const char *zName, /* Name of the table we are looking for */ + const char *zDbase /* Name of the database. Might be NULL */ +){ Table *p; /* Read the database schema. If an error occurs, leave an error message @@ -292,10 +307,11 @@ Table *sqlite3LocateTable(Parse *pParse, const char *zName, const char *zDbase){ p = sqlite3FindTable(pParse->db, zName, zDbase); if( p==0 ){ + const char *zMsg = isView ? "no such view" : "no such table"; if( zDbase ){ - sqlite3ErrorMsg(pParse, "no such table: %s.%s", zDbase, zName); + sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName); }else{ - sqlite3ErrorMsg(pParse, "no such table: %s", zName); + sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName); } pParse->checkSchema = 1; } @@ -334,8 +350,8 @@ Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){ ** Reclaim the memory used by an index */ static void freeIndex(Index *p){ - sqliteFree(p->zColAff); - sqliteFree(p); + sqlite3_free(p->zColAff); + sqlite3_free(p); } /* @@ -396,17 +412,22 @@ void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char *zIdxName){ */ void sqlite3ResetInternalSchema(sqlite3 *db, int iDb){ int i, j; - assert( iDb>=0 && iDb<db->nDb ); + + if( iDb==0 ){ + sqlite3BtreeEnterAll(db); + } for(i=iDb; i<db->nDb; i++){ Db *pDb = &db->aDb[i]; if( pDb->pSchema ){ + assert(i==1 || (pDb->pBt && sqlite3BtreeHoldsMutex(pDb->pBt))); sqlite3SchemaFree(pDb->pSchema); } if( iDb>0 ) return; } assert( iDb==0 ); db->flags &= ~SQLITE_InternChanges; + sqlite3BtreeLeaveAll(db); /* If one or more of the auxiliary database files has been closed, ** then remove them from the auxiliary database list. We take the @@ -424,7 +445,7 @@ void sqlite3ResetInternalSchema(sqlite3 *db, int iDb){ for(i=j=2; i<db->nDb; i++){ struct Db *pDb = &db->aDb[i]; if( pDb->pBt==0 ){ - sqliteFree(pDb->zName); + sqlite3_free(pDb->zName); pDb->zName = 0; continue; } @@ -437,23 +458,12 @@ void sqlite3ResetInternalSchema(sqlite3 *db, int iDb){ db->nDb = j; if( db->nDb<=2 && db->aDb!=db->aDbStatic ){ memcpy(db->aDbStatic, db->aDb, 2*sizeof(db->aDb[0])); - sqliteFree(db->aDb); + sqlite3_free(db->aDb); db->aDb = db->aDbStatic; } } /* -** This routine is called whenever a rollback occurs. If there were -** schema changes during the transaction, then we have to reset the -** internal hash tables and reload them from disk. -*/ -void sqlite3RollbackInternalChanges(sqlite3 *db){ - if( db->flags & SQLITE_InternChanges ){ - sqlite3ResetInternalSchema(db, 0); - } -} - -/* ** This routine is called when a commit occurs. */ void sqlite3CommitInternalChanges(sqlite3 *db){ @@ -469,12 +479,12 @@ static void sqliteResetColumnNames(Table *pTable){ assert( pTable!=0 ); if( (pCol = pTable->aCol)!=0 ){ for(i=0; i<pTable->nCol; i++, pCol++){ - sqliteFree(pCol->zName); + sqlite3_free(pCol->zName); sqlite3ExprDelete(pCol->pDflt); - sqliteFree(pCol->zType); - sqliteFree(pCol->zColl); + sqlite3_free(pCol->zType); + sqlite3_free(pCol->zColl); } - sqliteFree(pTable->aCol); + sqlite3_free(pTable->aCol); } pTable->aCol = 0; pTable->nCol = 0; @@ -489,18 +499,11 @@ static void sqliteResetColumnNames(Table *pTable){ ** foreign keys from the sqlite.aFKey hash table. But it does destroy ** memory structures of the indices and foreign keys associated with ** the table. -** -** Indices associated with the table are unlinked from the "db" -** data structure if db!=NULL. If db==NULL, indices attached to -** the table are deleted, but it is assumed they have already been -** unlinked. */ -void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ +void sqlite3DeleteTable(Table *pTable){ Index *pIndex, *pNext; FKey *pFKey, *pNextFKey; - db = 0; - if( pTable==0 ) return; /* Do not delete the table until the reference count reaches zero. */ @@ -520,27 +523,27 @@ void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ #ifndef SQLITE_OMIT_FOREIGN_KEY /* Delete all foreign keys associated with this table. The keys - ** should have already been unlinked from the db->aFKey hash table + ** should have already been unlinked from the pSchema->aFKey hash table */ for(pFKey=pTable->pFKey; pFKey; pFKey=pNextFKey){ pNextFKey = pFKey->pNextFrom; assert( sqlite3HashFind(&pTable->pSchema->aFKey, pFKey->zTo, strlen(pFKey->zTo)+1)!=pFKey ); - sqliteFree(pFKey); + sqlite3_free(pFKey); } #endif /* Delete the Table structure itself. */ sqliteResetColumnNames(pTable); - sqliteFree(pTable->zName); - sqliteFree(pTable->zColAff); + sqlite3_free(pTable->zName); + sqlite3_free(pTable->zColAff); sqlite3SelectDelete(pTable->pSelect); #ifndef SQLITE_OMIT_CHECK sqlite3ExprDelete(pTable->pCheck); #endif sqlite3VtabClear(pTable); - sqliteFree(pTable); + sqlite3_free(pTable); } /* @@ -572,7 +575,7 @@ void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char *zTabName){ } } #endif - sqlite3DeleteTable(db, p); + sqlite3DeleteTable(p); } db->flags |= SQLITE_InternChanges; } @@ -587,10 +590,10 @@ void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char *zTabName){ ** are not \000 terminated and are not persistent. The returned string ** is \000 terminated and is persistent. */ -char *sqlite3NameFromToken(Token *pName){ +char *sqlite3NameFromToken(sqlite3 *db, Token *pName){ char *zName; if( pName ){ - zName = sqliteStrNDup((char*)pName->z, pName->n); + zName = sqlite3DbStrNDup(db, (char*)pName->z, pName->n); sqlite3Dequote(zName); }else{ zName = 0; @@ -605,9 +608,8 @@ char *sqlite3NameFromToken(Token *pName){ void sqlite3OpenMasterTable(Parse *p, int iDb){ Vdbe *v = sqlite3GetVdbe(p); sqlite3TableLock(p, iDb, MASTER_ROOT, 1, SCHEMA_TABLE(iDb)); - sqlite3VdbeAddOp(v, OP_Integer, iDb, 0); - sqlite3VdbeAddOp(v, OP_OpenWrite, 0, MASTER_ROOT); - sqlite3VdbeAddOp(v, OP_SetNumColumns, 0, 5); /* sqlite_master has 5 columns */ + sqlite3VdbeAddOp3(v, OP_OpenWrite, 0, MASTER_ROOT, iDb); + sqlite3VdbeAddOp2(v, OP_SetNumColumns, 0, 5); /* sqlite_master has 5 columns */ } /* @@ -622,7 +624,7 @@ int sqlite3FindDb(sqlite3 *db, Token *pName){ Db *pDb; /* A database whose name space is being searched */ char *zName; /* Name we are searching for */ - zName = sqlite3NameFromToken(pName); + zName = sqlite3NameFromToken(db, pName); if( zName ){ n = strlen(zName); for(i=(db->nDb-1), pDb=&db->aDb[i]; i>=0; i--, pDb--){ @@ -631,7 +633,7 @@ int sqlite3FindDb(sqlite3 *db, Token *pName){ break; } } - sqliteFree(zName); + sqlite3_free(zName); } return i; } @@ -754,7 +756,7 @@ void sqlite3StartTable( if( !OMIT_TEMPDB && isTemp ) iDb = 1; pParse->sNameToken = *pName; - zName = sqlite3NameFromToken(pName); + zName = sqlite3NameFromToken(db, pName); if( zName==0 ) return; if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ goto begin_table_error; @@ -811,8 +813,9 @@ void sqlite3StartTable( } } - pTable = sqliteMalloc( sizeof(Table) ); + pTable = sqlite3DbMallocZero(db, sizeof(Table)); if( pTable==0 ){ + db->mallocFailed = 1; pParse->rc = SQLITE_NOMEM; pParse->nErr++; goto begin_table_error; @@ -821,7 +824,7 @@ void sqlite3StartTable( pTable->iPKey = -1; pTable->pSchema = db->aDb[iDb].pSchema; pTable->nRef = 1; - if( pParse->pNewTable ) sqlite3DeleteTable(db, pParse->pNewTable); + if( pParse->pNewTable ) sqlite3DeleteTable(pParse->pNewTable); pParse->pNewTable = pTable; /* If this is the magic sqlite_sequence table used by autoincrement, @@ -843,29 +846,33 @@ void sqlite3StartTable( ** now. */ if( !db->init.busy && (v = sqlite3GetVdbe(pParse))!=0 ){ - int lbl; + int j1; int fileFormat; + int reg1, reg2, reg3; sqlite3BeginWriteOperation(pParse, 0, iDb); #ifndef SQLITE_OMIT_VIRTUALTABLE if( isVirtual ){ - sqlite3VdbeAddOp(v, OP_VBegin, 0, 0); + sqlite3VdbeAddOp0(v, OP_VBegin); } #endif /* If the file format and encoding in the database have not been set, ** set them now. */ - sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 1); /* file_format */ - lbl = sqlite3VdbeMakeLabel(v); - sqlite3VdbeAddOp(v, OP_If, 0, lbl); + reg1 = pParse->regRowid = ++pParse->nMem; + reg2 = pParse->regRoot = ++pParse->nMem; + reg3 = ++pParse->nMem; + sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, reg3, 1); /* file_format */ + sqlite3VdbeUsesBtree(v, iDb); + j1 = sqlite3VdbeAddOp1(v, OP_If, reg3); fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ? 1 : SQLITE_MAX_FILE_FORMAT; - sqlite3VdbeAddOp(v, OP_Integer, fileFormat, 0); - sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 1); - sqlite3VdbeAddOp(v, OP_Integer, ENC(db), 0); - sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 4); - sqlite3VdbeResolveLabel(v, lbl); + sqlite3VdbeAddOp2(v, OP_Integer, fileFormat, reg3); + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, 1, reg3); + sqlite3VdbeAddOp2(v, OP_Integer, ENC(db), reg3); + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, 4, reg3); + sqlite3VdbeJumpHere(v, j1); /* This just creates a place-holder record in the sqlite_master table. ** The record created does not contain anything yet. It will be replaced @@ -877,19 +884,18 @@ void sqlite3StartTable( */ #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) if( isView || isVirtual ){ - sqlite3VdbeAddOp(v, OP_Integer, 0, 0); + sqlite3VdbeAddOp2(v, OP_Integer, 0, reg2); }else #endif { - sqlite3VdbeAddOp(v, OP_CreateTable, iDb, 0); + sqlite3VdbeAddOp2(v, OP_CreateTable, iDb, reg2); } sqlite3OpenMasterTable(pParse, iDb); - sqlite3VdbeAddOp(v, OP_NewRowid, 0, 0); - sqlite3VdbeAddOp(v, OP_Dup, 0, 0); - sqlite3VdbeAddOp(v, OP_Null, 0, 0); - sqlite3VdbeAddOp(v, OP_Insert, 0, 0); - sqlite3VdbeAddOp(v, OP_Close, 0, 0); - sqlite3VdbeAddOp(v, OP_Pull, 1, 0); + sqlite3VdbeAddOp2(v, OP_NewRowid, 0, reg1); + sqlite3VdbeAddOp2(v, OP_Null, 0, reg3); + sqlite3VdbeAddOp3(v, OP_Insert, 0, reg3, reg1); + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); + sqlite3VdbeAddOp0(v, OP_Close); } /* Normal (non-error) return. */ @@ -897,7 +903,7 @@ void sqlite3StartTable( /* If an error occurs, we jump here */ begin_table_error: - sqliteFree(zName); + sqlite3_free(zName); return; } @@ -928,20 +934,24 @@ void sqlite3AddColumn(Parse *pParse, Token *pName){ char *z; Column *pCol; if( (p = pParse->pNewTable)==0 ) return; - z = sqlite3NameFromToken(pName); + if( p->nCol+1>SQLITE_MAX_COLUMN ){ + sqlite3ErrorMsg(pParse, "too many columns on %s", p->zName); + return; + } + z = sqlite3NameFromToken(pParse->db, pName); if( z==0 ) return; for(i=0; i<p->nCol; i++){ if( STRICMP(z, p->aCol[i].zName) ){ sqlite3ErrorMsg(pParse, "duplicate column name: %s", z); - sqliteFree(z); + sqlite3_free(z); return; } } if( (p->nCol & 0x7)==0 ){ Column *aNew; - aNew = sqliteRealloc( p->aCol, (p->nCol+8)*sizeof(p->aCol[0])); + aNew = sqlite3DbRealloc(pParse->db,p->aCol,(p->nCol+8)*sizeof(p->aCol[0])); if( aNew==0 ){ - sqliteFree(z); + sqlite3_free(z); return; } p->aCol = aNew; @@ -1053,8 +1063,8 @@ void sqlite3AddColumnType(Parse *pParse, Token *pType){ i = p->nCol-1; if( i<0 ) return; pCol = &p->aCol[i]; - sqliteFree(pCol->zType); - pCol->zType = sqlite3NameFromToken(pType); + sqlite3_free(pCol->zType); + pCol->zType = sqlite3NameFromToken(pParse->db, pType); pCol->affinity = sqlite3AffinityType(pType); } @@ -1077,8 +1087,13 @@ void sqlite3AddDefaultValue(Parse *pParse, Expr *pExpr){ sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant", pCol->zName); }else{ + Expr *pCopy; + sqlite3 *db = pParse->db; sqlite3ExprDelete(pCol->pDflt); - pCol->pDflt = sqlite3ExprDup(pExpr); + pCol->pDflt = pCopy = sqlite3ExprDup(db, pExpr); + if( pCopy ){ + sqlite3TokenCopy(db, &pCopy->span, &pExpr->span); + } } } sqlite3ExprDelete(pExpr); @@ -1167,11 +1182,13 @@ void sqlite3AddCheckConstraint( ){ #ifndef SQLITE_OMIT_CHECK Table *pTab = pParse->pNewTable; + sqlite3 *db = pParse->db; if( pTab && !IN_DECLARE_VTAB ){ /* The CHECK expression must be duplicated so that tokens refer ** to malloced space and not the (ephemeral) text of the CREATE TABLE ** statement */ - pTab->pCheck = sqlite3ExprAnd(pTab->pCheck, sqlite3ExprDup(pCheckExpr)); + pTab->pCheck = sqlite3ExprAnd(db, pTab->pCheck, + sqlite3ExprDup(db, pCheckExpr)); } #endif sqlite3ExprDelete(pCheckExpr); @@ -1181,16 +1198,20 @@ void sqlite3AddCheckConstraint( ** Set the collation function of the most recently parsed table column ** to the CollSeq given. */ -void sqlite3AddCollateType(Parse *pParse, const char *zType, int nType){ +void sqlite3AddCollateType(Parse *pParse, Token *pToken){ Table *p; int i; + char *zColl; /* Dequoted name of collation sequence */ if( (p = pParse->pNewTable)==0 ) return; i = p->nCol-1; - if( sqlite3LocateCollSeq(pParse, zType, nType) ){ + zColl = sqlite3NameFromToken(pParse->db, pToken); + if( !zColl ) return; + + if( sqlite3LocateCollSeq(pParse, zColl, -1) ){ Index *pIdx; - p->aCol[i].zColl = sqliteStrNDup(zType, nType); + p->aCol[i].zColl = zColl; /* If the column is declared as "<name> PRIMARY KEY COLLATE <type>", ** then an index may have been created on this column before the @@ -1202,6 +1223,8 @@ void sqlite3AddCollateType(Parse *pParse, const char *zType, int nType){ pIdx->azColl[0] = p->aCol[i].zColl; } } + }else{ + sqlite3_free(zColl); } } @@ -1218,6 +1241,10 @@ void sqlite3AddCollateType(Parse *pParse, const char *zType, int nType){ ** If no versions of the requested collations sequence are available, or ** another error occurs, NULL is returned and an error message written into ** pParse. +** +** This routine is a wrapper around sqlite3FindCollSeq(). This routine +** invokes the collation factory if the named collation cannot be found +** and generates an error message. */ CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName){ sqlite3 *db = pParse->db; @@ -1257,9 +1284,13 @@ CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName){ ** and the probability of hitting the same cookie value is only ** 1 chance in 2^32. So we're safe enough. */ -void sqlite3ChangeCookie(sqlite3 *db, Vdbe *v, int iDb){ - sqlite3VdbeAddOp(v, OP_Integer, db->aDb[iDb].pSchema->schema_cookie+1, 0); - sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 0); +void sqlite3ChangeCookie(Parse *pParse, int iDb){ + int r1 = sqlite3GetTempReg(pParse); + sqlite3 *db = pParse->db; + Vdbe *v = pParse->pVdbe; + sqlite3VdbeAddOp2(v, OP_Integer, db->aDb[iDb].pSchema->schema_cookie+1, r1); + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, 0, r1); + sqlite3ReleaseTempReg(pParse, r1); } /* @@ -1306,7 +1337,7 @@ static void identPut(char *z, int *pIdx, char *zSignedIdent){ ** table. Memory to hold the text of the statement is obtained ** from sqliteMalloc() and must be freed by the calling function. */ -static char *createTableStmt(Table *p, int isTemp){ +static char *createTableStmt(sqlite3 *db, Table *p, int isTemp){ int i, k, n; char *zStmt; char *zSep, *zSep2, *zEnd, *z; @@ -1330,24 +1361,29 @@ static char *createTableStmt(Table *p, int isTemp){ zEnd = "\n)"; } n += 35 + 6*p->nCol; - zStmt = sqliteMallocRaw( n ); - if( zStmt==0 ) return 0; - strcpy(zStmt, !OMIT_TEMPDB&&isTemp ? "CREATE TEMP TABLE ":"CREATE TABLE "); + zStmt = sqlite3_malloc( n ); + if( zStmt==0 ){ + db->mallocFailed = 1; + return 0; + } + sqlite3_snprintf(n, zStmt, + !OMIT_TEMPDB&&isTemp ? "CREATE TEMP TABLE ":"CREATE TABLE "); k = strlen(zStmt); identPut(zStmt, &k, p->zName); zStmt[k++] = '('; for(pCol=p->aCol, i=0; i<p->nCol; i++, pCol++){ - strcpy(&zStmt[k], zSep); + sqlite3_snprintf(n-k, &zStmt[k], zSep); k += strlen(&zStmt[k]); zSep = zSep2; identPut(zStmt, &k, pCol->zName); if( (z = pCol->zType)!=0 ){ zStmt[k++] = ' '; - strcpy(&zStmt[k], z); + assert( strlen(z)+k+1<=n ); + sqlite3_snprintf(n-k, &zStmt[k], "%s", z); k += strlen(z); } } - strcpy(&zStmt[k], zEnd); + sqlite3_snprintf(n-k, &zStmt[k], "%s", zEnd); return zStmt; } @@ -1381,7 +1417,7 @@ void sqlite3EndTable( sqlite3 *db = pParse->db; int iDb; - if( (pEnd==0 && pSelect==0) || pParse->nErr || sqlite3MallocFailed() ) { + if( (pEnd==0 && pSelect==0) || pParse->nErr || db->mallocFailed ) { return; } p = pParse->pNewTable; @@ -1440,7 +1476,7 @@ void sqlite3EndTable( v = sqlite3GetVdbe(pParse); if( v==0 ) return; - sqlite3VdbeAddOp(v, OP_Close, 0, 0); + sqlite3VdbeAddOp1(v, OP_Close, 0); /* Create the rootpage for the new table and push it onto the stack. ** A view has no rootpage, so just push a zero onto the stack for @@ -1472,13 +1508,15 @@ void sqlite3EndTable( ** be redundant. */ if( pSelect ){ + SelectDest dest; Table *pSelTab; - sqlite3VdbeAddOp(v, OP_Dup, 0, 0); - sqlite3VdbeAddOp(v, OP_Integer, iDb, 0); - sqlite3VdbeAddOp(v, OP_OpenWrite, 1, 0); + + sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb); + sqlite3VdbeChangeP5(v, 1); pParse->nTab = 2; - sqlite3Select(pParse, pSelect, SRT_Table, 1, 0, 0, 0, 0); - sqlite3VdbeAddOp(v, OP_Close, 1, 0); + sqlite3SelectDestInit(&dest, SRT_Table, 1); + sqlite3Select(pParse, pSelect, &dest, 0, 0, 0, 0); + sqlite3VdbeAddOp1(v, OP_Close, 1); if( pParse->nErr==0 ){ pSelTab = sqlite3ResultSetOfSelect(pParse, 0, pSelect); if( pSelTab==0 ) return; @@ -1487,16 +1525,18 @@ void sqlite3EndTable( p->aCol = pSelTab->aCol; pSelTab->nCol = 0; pSelTab->aCol = 0; - sqlite3DeleteTable(0, pSelTab); + sqlite3DeleteTable(pSelTab); } } /* Compute the complete text of the CREATE statement */ if( pSelect ){ - zStmt = createTableStmt(p, p->pSchema==pParse->db->aDb[1].pSchema); + zStmt = createTableStmt(db, p, p->pSchema==db->aDb[1].pSchema); }else{ n = pEnd->z - pParse->sNameToken.z + 1; - zStmt = sqlite3MPrintf("CREATE %s %.*s", zType2, n, pParse->sNameToken.z); + zStmt = sqlite3MPrintf(db, + "CREATE %s %.*s", zType2, n, pParse->sNameToken.z + ); } /* A slot for the record has already been allocated in the @@ -1507,16 +1547,18 @@ void sqlite3EndTable( */ sqlite3NestedParse(pParse, "UPDATE %Q.%s " - "SET type='%s', name=%Q, tbl_name=%Q, rootpage=#0, sql=%Q " - "WHERE rowid=#1", + "SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q " + "WHERE rowid=#%d", db->aDb[iDb].zName, SCHEMA_TABLE(iDb), zType, p->zName, p->zName, - zStmt + pParse->regRoot, + zStmt, + pParse->regRowid ); - sqliteFree(zStmt); - sqlite3ChangeCookie(db, v, iDb); + sqlite3_free(zStmt); + sqlite3ChangeCookie(pParse, iDb); #ifndef SQLITE_OMIT_AUTOINCREMENT /* Check to see if we need to create an sqlite_sequence table for @@ -1534,8 +1576,8 @@ void sqlite3EndTable( #endif /* Reparse everything to update our internal data structures */ - sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0, - sqlite3MPrintf("tbl_name='%q'",p->zName), P3_DYNAMIC); + sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 0, 0, + sqlite3MPrintf(db, "tbl_name='%q'",p->zName), P4_DYNAMIC); } @@ -1548,13 +1590,18 @@ void sqlite3EndTable( pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName, strlen(p->zName)+1,p); if( pOld ){ assert( p==pOld ); /* Malloc must have failed inside HashInsert() */ + db->mallocFailed = 1; return; } #ifndef SQLITE_OMIT_FOREIGN_KEY for(pFKey=p->pFKey; pFKey; pFKey=pFKey->pNextFrom){ + void *data; int nTo = strlen(pFKey->zTo) + 1; pFKey->pNextTo = sqlite3HashFind(&pSchema->aFKey, pFKey->zTo, nTo); - sqlite3HashInsert(&pSchema->aFKey, pFKey->zTo, nTo, pFKey); + data = sqlite3HashInsert(&pSchema->aFKey, pFKey->zTo, nTo, pFKey); + if( data==(void *)pFKey ){ + db->mallocFailed = 1; + } } #endif pParse->pNewTable = 0; @@ -1570,7 +1617,7 @@ void sqlite3EndTable( pCons = pEnd; } nName = (const char *)pCons->z - zName; - p->addColOffset = 13 + sqlite3utf8CharLen(zName, nName); + p->addColOffset = 13 + sqlite3Utf8CharLen(zName, nName); } #endif } @@ -1586,7 +1633,8 @@ void sqlite3CreateView( Token *pName1, /* The token that holds the name of the view */ Token *pName2, /* The token that holds the name of the view */ Select *pSelect, /* A SELECT statement that will become the new view */ - int isTemp /* TRUE for a TEMPORARY view */ + int isTemp, /* TRUE for a TEMPORARY view */ + int noErr /* Suppress error messages if VIEW already exists */ ){ Table *p; int n; @@ -1595,20 +1643,21 @@ void sqlite3CreateView( DbFixer sFix; Token *pName; int iDb; + sqlite3 *db = pParse->db; if( pParse->nVar>0 ){ sqlite3ErrorMsg(pParse, "parameters are not allowed in views"); sqlite3SelectDelete(pSelect); return; } - sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, 0); + sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, noErr); p = pParse->pNewTable; if( p==0 || pParse->nErr ){ sqlite3SelectDelete(pSelect); return; } sqlite3TwoPartName(pParse, pName1, pName2, &pName); - iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema); + iDb = sqlite3SchemaToIndex(db, p->pSchema); if( sqlite3FixInit(&sFix, pParse, iDb, "view", pName) && sqlite3FixSelect(&sFix, pSelect) ){ @@ -1621,12 +1670,12 @@ void sqlite3CreateView( ** allocated rather than point to the input string - which means that ** they will persist after the current sqlite3_exec() call returns. */ - p->pSelect = sqlite3SelectDup(pSelect); + p->pSelect = sqlite3SelectDup(db, pSelect); sqlite3SelectDelete(pSelect); - if( sqlite3MallocFailed() ){ + if( db->mallocFailed ){ return; } - if( !pParse->db->init.busy ){ + if( !db->init.busy ){ sqlite3ViewGetColumnNames(pParse, p); } @@ -1661,6 +1710,8 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ Select *pSel; /* Copy of the SELECT that implements the view */ 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 */ + int (*xAuth)(void*,int,const char*,const char*,const char*,const char*); assert( pTable ); @@ -1701,12 +1752,19 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ ** statement that defines the view. */ assert( pTable->pSelect ); - pSel = sqlite3SelectDup(pTable->pSelect); + pSel = sqlite3SelectDup(db, pTable->pSelect); if( pSel ){ n = pParse->nTab; sqlite3SrcListAssignCursors(pParse, pSel->pSrc); pTable->nCol = -1; +#ifndef SQLITE_OMIT_AUTHORIZATION + xAuth = db->xAuth; + db->xAuth = 0; pSelTab = sqlite3ResultSetOfSelect(pParse, 0, pSel); + db->xAuth = xAuth; +#else + pSelTab = sqlite3ResultSetOfSelect(pParse, 0, pSel); +#endif pParse->nTab = n; if( pSelTab ){ assert( pTable->aCol==0 ); @@ -1714,7 +1772,7 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ pTable->aCol = pSelTab->aCol; pSelTab->nCol = 0; pSelTab->aCol = 0; - sqlite3DeleteTable(0, pSelTab); + sqlite3DeleteTable(pSelTab); pTable->pSchema->flags |= DB_UnresetViews; }else{ pTable->nCol = 0; @@ -1795,20 +1853,22 @@ void sqlite3RootPageMoved(Db *pDb, int iFrom, int iTo){ */ static void destroyRootPage(Parse *pParse, int iTable, int iDb){ Vdbe *v = sqlite3GetVdbe(pParse); - sqlite3VdbeAddOp(v, OP_Destroy, iTable, iDb); + int r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_Destroy, iTable, r1, iDb); #ifndef SQLITE_OMIT_AUTOVACUUM - /* OP_Destroy pushes an integer onto the stack. If this integer + /* OP_Destroy stores an in integer r1. If this integer ** is non-zero, then it is the root page number of a table moved to ** location iTable. The following code modifies the sqlite_master table to ** reflect this. ** - ** The "#0" in the SQL is a special constant that means whatever value + ** The "#%d" in the SQL is a special constant that means whatever value ** is on the top of the stack. See sqlite3RegisterExpr(). */ sqlite3NestedParse(pParse, - "UPDATE %Q.%s SET rootpage=%d WHERE #0 AND rootpage=#0", - pParse->db->aDb[iDb].zName, SCHEMA_TABLE(iDb), iTable); + "UPDATE %Q.%s SET rootpage=%d WHERE #%d AND rootpage=#%d", + pParse->db->aDb[iDb].zName, SCHEMA_TABLE(iDb), iTable, r1, r1); #endif + sqlite3ReleaseTempReg(pParse, r1); } /* @@ -1880,11 +1940,12 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ sqlite3 *db = pParse->db; int iDb; - if( pParse->nErr || sqlite3MallocFailed() ){ + if( pParse->nErr || db->mallocFailed ){ goto exit_drop_table; } assert( pName->nSrc==1 ); - pTab = sqlite3LocateTable(pParse, pName->a[0].zName, pName->a[0].zDatabase); + pTab = sqlite3LocateTable(pParse, isView, + pName->a[0].zName, pName->a[0].zDatabase); if( pTab==0 ){ if( noErr ){ @@ -1894,6 +1955,13 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ } iDb = sqlite3SchemaToIndex(db, pTab->pSchema); assert( iDb>=0 && iDb<db->nDb ); + + /* If pTab is a virtual table, call ViewGetColumnNames() to ensure + ** it is initialized. + */ + if( IsVirtual(pTab) && sqlite3ViewGetColumnNames(pParse, pTab) ){ + goto exit_drop_table; + } #ifndef SQLITE_OMIT_AUTHORIZATION { int code; @@ -1911,9 +1979,6 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ } #ifndef SQLITE_OMIT_VIRTUALTABLE }else if( IsVirtual(pTab) ){ - if( sqlite3ViewGetColumnNames(pParse, pTab) ){ - goto exit_drop_table; - } code = SQLITE_DROP_VTABLE; zArg2 = pTab->pMod->zName; #endif @@ -1958,13 +2023,13 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ if( v ){ Trigger *pTrigger; Db *pDb = &db->aDb[iDb]; - sqlite3BeginWriteOperation(pParse, 0, iDb); + sqlite3BeginWriteOperation(pParse, 1, iDb); #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pTab) ){ Vdbe *v = sqlite3GetVdbe(pParse); if( v ){ - sqlite3VdbeAddOp(v, OP_VBegin, 0, 0); + sqlite3VdbeAddOp0(v, OP_VBegin); } } #endif @@ -2013,10 +2078,10 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ ** the schema cookie. */ if( IsVirtual(pTab) ){ - sqlite3VdbeOp3(v, OP_VDestroy, iDb, 0, pTab->zName, 0); + sqlite3VdbeAddOp4(v, OP_VDestroy, iDb, 0, 0, pTab->zName, 0); } - sqlite3VdbeOp3(v, OP_DropTable, iDb, 0, pTab->zName, 0); - sqlite3ChangeCookie(db, v, iDb); + sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0); + sqlite3ChangeCookie(pParse, iDb); } sqliteViewResetAll(db, iDb); @@ -2083,8 +2148,10 @@ void sqlite3CreateForeignKey( nByte += strlen(pToCol->a[i].zName) + 1; } } - pFKey = sqliteMalloc( nByte ); - if( pFKey==0 ) goto fk_end; + pFKey = sqlite3DbMallocZero(pParse->db, nByte ); + if( pFKey==0 ){ + goto fk_end; + } pFKey->pFrom = p; pFKey->pNextFrom = p->pFKey; z = (char*)&pFKey[1]; @@ -2135,7 +2202,7 @@ void sqlite3CreateForeignKey( pFKey = 0; fk_end: - sqliteFree(pFKey); + sqlite3_free(pFKey); #endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ sqlite3ExprListDelete(pFromCol); sqlite3ExprListDelete(pToCol); @@ -2163,7 +2230,7 @@ void sqlite3DeferForeignKey(Parse *pParse, int isDeferred){ ** content of an index in response to a REINDEX command. ** ** if memRootPage is not negative, it means that the index is newly -** created. The memory cell specified by memRootPage contains the +** created. The register specified by memRootPage contains the ** root page number of the index. If memRootPage is negative, then ** the index already exists and must be cleared before being refilled and ** the root page number of the index is taken from pIndex->tnum. @@ -2176,11 +2243,14 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ int tnum; /* Root page of index */ Vdbe *v; /* Generate code into this virtual machine */ KeyInfo *pKey; /* KeyInfo for index */ - int iDb = sqlite3SchemaToIndex(pParse->db, pIndex->pSchema); + int regIdxKey; /* Registers containing the index key */ + int regRecord; /* Register holding assemblied index record */ + sqlite3 *db = pParse->db; /* The database connection */ + int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema); #ifndef SQLITE_OMIT_AUTHORIZATION if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0, - pParse->db->aDb[iDb].zName ) ){ + db->aDb[iDb].zName ) ){ return; } #endif @@ -2191,34 +2261,40 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ v = sqlite3GetVdbe(pParse); if( v==0 ) return; if( memRootPage>=0 ){ - sqlite3VdbeAddOp(v, OP_MemLoad, memRootPage, 0); - tnum = 0; + tnum = memRootPage; }else{ tnum = pIndex->tnum; - sqlite3VdbeAddOp(v, OP_Clear, tnum, iDb); + sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb); } - sqlite3VdbeAddOp(v, OP_Integer, iDb, 0); pKey = sqlite3IndexKeyinfo(pParse, pIndex); - sqlite3VdbeOp3(v, OP_OpenWrite, iIdx, tnum, (char *)pKey, P3_KEYINFO_HANDOFF); + sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb, + (char *)pKey, P4_KEYINFO_HANDOFF); + if( memRootPage>=0 ){ + sqlite3VdbeChangeP5(v, 1); + } sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); - addr1 = sqlite3VdbeAddOp(v, OP_Rewind, iTab, 0); - sqlite3GenerateIndexKey(v, pIndex, iTab); + addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); + regRecord = sqlite3GetTempReg(pParse); + regIdxKey = sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord); if( pIndex->onError!=OE_None ){ - int curaddr = sqlite3VdbeCurrentAddr(v); - int addr2 = curaddr+4; - sqlite3VdbeChangeP2(v, curaddr-1, addr2); - sqlite3VdbeAddOp(v, OP_Rowid, iTab, 0); - sqlite3VdbeAddOp(v, OP_AddImm, 1, 0); - sqlite3VdbeAddOp(v, OP_IsUnique, iIdx, addr2); - sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, OE_Abort, - "indexed columns are not unique", P3_STATIC); - assert( addr2==sqlite3VdbeCurrentAddr(v) ); - } - sqlite3VdbeAddOp(v, OP_IdxInsert, iIdx, 0); - sqlite3VdbeAddOp(v, OP_Next, iTab, addr1+1); + int j1, j2; + int regRowid; + + regRowid = regIdxKey + pIndex->nColumn; + j1 = sqlite3VdbeAddOp3(v, OP_IsNull, regIdxKey, 0, pIndex->nColumn); + j2 = sqlite3VdbeAddOp4(v, OP_IsUnique, iIdx, + 0, regRowid, (char*)regRecord, P4_INT32); + sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, OE_Abort, 0, + "indexed columns are not unique", P4_STATIC); + sqlite3VdbeJumpHere(v, j1); + sqlite3VdbeJumpHere(v, j2); + } + sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdx, regRecord); + sqlite3ReleaseTempReg(pParse, regRecord); + sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1); sqlite3VdbeJumpHere(v, addr1); - sqlite3VdbeAddOp(v, OP_Close, iTab, 0); - sqlite3VdbeAddOp(v, OP_Close, iIdx, 0); + sqlite3VdbeAddOp1(v, OP_Close, iTab); + sqlite3VdbeAddOp1(v, OP_Close, iIdx); } /* @@ -2240,7 +2316,7 @@ void sqlite3CreateIndex( SrcList *pTblName, /* Table to index. Use pParse->pNewTable if 0 */ ExprList *pList, /* A list of columns to be indexed */ int onError, /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ - Token *pStart, /* The CREATE token that begins a CREATE TABLE statement */ + Token *pStart, /* The CREATE token that begins this statement */ Token *pEnd, /* The ")" that closes the CREATE INDEX statement */ int sortOrder, /* Sort order of primary key when pList==NULL */ int ifNotExist /* Omit error if index already exists */ @@ -2262,7 +2338,7 @@ void sqlite3CreateIndex( int nExtra = 0; char *zExtra; - if( pParse->nErr || sqlite3MallocFailed() || IN_DECLARE_VTAB ){ + if( pParse->nErr || db->mallocFailed || IN_DECLARE_VTAB ){ goto exit_create_index; } @@ -2281,11 +2357,14 @@ void sqlite3CreateIndex( #ifndef SQLITE_OMIT_TEMPDB /* If the index name was unqualified, check if the the table - ** is a temp table. If so, set the database to 1. + ** is a temp table. If so, set the database to 1. Do not do this + ** if initialising a database schema. */ - pTab = sqlite3SrcListLookup(pParse, pTblName); - if( pName2 && pName2->n==0 && pTab && pTab->pSchema==db->aDb[1].pSchema ){ - iDb = 1; + if( !db->init.busy ){ + pTab = sqlite3SrcListLookup(pParse, pTblName); + if( pName2 && pName2->n==0 && pTab && pTab->pSchema==db->aDb[1].pSchema ){ + iDb = 1; + } } #endif @@ -2296,7 +2375,7 @@ void sqlite3CreateIndex( ** sqlite3FixSrcList can never fail. */ assert(0); } - pTab = sqlite3LocateTable(pParse, pTblName->a[0].zName, + pTab = sqlite3LocateTable(pParse, 0, pTblName->a[0].zName, pTblName->a[0].zDatabase); if( !pTab ) goto exit_create_index; assert( db->aDb[iDb].pSchema==pTab->pSchema ); @@ -2340,7 +2419,7 @@ void sqlite3CreateIndex( ** own name. */ if( pName ){ - zName = sqlite3NameFromToken(pName); + zName = sqlite3NameFromToken(db, pName); if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto exit_create_index; if( zName==0 ) goto exit_create_index; if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ @@ -2348,26 +2427,29 @@ void sqlite3CreateIndex( } if( !db->init.busy ){ if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto exit_create_index; - if( sqlite3FindIndex(db, zName, pDb->zName)!=0 ){ - if( !ifNotExist ){ - sqlite3ErrorMsg(pParse, "index %s already exists", zName); - } - goto exit_create_index; - } if( sqlite3FindTable(db, zName, 0)!=0 ){ sqlite3ErrorMsg(pParse, "there is already a table named %s", zName); goto exit_create_index; } } + if( sqlite3FindIndex(db, zName, pDb->zName)!=0 ){ + if( !ifNotExist ){ + sqlite3ErrorMsg(pParse, "index %s already exists", zName); + } + goto exit_create_index; + } }else{ char zBuf[30]; int n; Index *pLoop; for(pLoop=pTab->pIndex, n=1; pLoop; pLoop=pLoop->pNext, n++){} - sprintf(zBuf,"_%d",n); + sqlite3_snprintf(sizeof(zBuf),zBuf,"_%d",n); zName = 0; sqlite3SetString(&zName, "sqlite_autoindex_", pTab->zName, zBuf, (char*)0); - if( zName==0 ) goto exit_create_index; + if( zName==0 ){ + db->mallocFailed = 1; + goto exit_create_index; + } } /* Check for authorization to create an index. @@ -2393,7 +2475,7 @@ void sqlite3CreateIndex( if( pList==0 ){ nullId.z = (u8*)pTab->aCol[pTab->nCol-1].zName; nullId.n = strlen((char*)nullId.z); - pList = sqlite3ExprListAppend(0, 0, &nullId); + pList = sqlite3ExprListAppend(pParse, 0, 0, &nullId); if( pList==0 ) goto exit_create_index; pList->a[0].sortOrder = sortOrder; } @@ -2413,7 +2495,7 @@ void sqlite3CreateIndex( */ nName = strlen(zName); nCol = pList->nExpr; - pIndex = sqliteMalloc( + pIndex = sqlite3DbMallocZero(db, sizeof(Index) + /* Index structure */ sizeof(int)*nCol + /* Index.aiColumn */ sizeof(int)*(nCol+1) + /* Index.aiRowEst */ @@ -2422,14 +2504,16 @@ void sqlite3CreateIndex( nName + 1 + /* Index.zName */ nExtra /* Collation sequence names */ ); - if( sqlite3MallocFailed() ) goto exit_create_index; + if( db->mallocFailed ){ + goto exit_create_index; + } pIndex->azColl = (char**)(&pIndex[1]); pIndex->aiColumn = (int *)(&pIndex->azColl[nCol]); pIndex->aiRowEst = (unsigned *)(&pIndex->aiColumn[nCol]); pIndex->aSortOrder = (u8 *)(&pIndex->aiRowEst[nCol+1]); pIndex->zName = (char *)(&pIndex->aSortOrder[nCol]); zExtra = (char *)(&pIndex->zName[nName+1]); - strcpy(pIndex->zName, zName); + memcpy(pIndex->zName, zName, nName+1); pIndex->pTable = pTab; pIndex->nColumn = pList->nExpr; pIndex->onError = onError; @@ -2452,7 +2536,7 @@ void sqlite3CreateIndex( const char *zColName = pListItem->zName; Column *pTabCol; int requestedSortOrder; - char *zColl; /* Collation sequence */ + char *zColl; /* Collation sequence name */ for(j=0, pTabCol=pTab->aCol; j<pTab->nCol; j++, pTabCol++){ if( sqlite3StrICmp(zColName, pTabCol->zName)==0 ) break; @@ -2462,11 +2546,17 @@ void sqlite3CreateIndex( pTab->zName, zColName); goto exit_create_index; } + /* TODO: Add a test to make sure that the same column is not named + ** more than once within the same index. Only the first instance of + ** the column will ever be used by the optimizer. Note that using the + ** same column more than once cannot be an error because that would + ** break backwards compatibility - it needs to be a warning. + */ pIndex->aiColumn[i] = j; if( pListItem->pExpr ){ assert( pListItem->pExpr->pColl ); zColl = zExtra; - strcpy(zExtra, pListItem->pExpr->pColl->zName); + sqlite3_snprintf(nExtra, zExtra, "%s", pListItem->pExpr->pColl->zName); zExtra += (strlen(zColl) + 1); }else{ zColl = pTab->aCol[j].zColl; @@ -2543,6 +2633,7 @@ void sqlite3CreateIndex( pIndex->zName, strlen(pIndex->zName)+1, pIndex); if( p ){ assert( p==pIndex ); /* Malloc must have failed */ + db->mallocFailed = 1; goto exit_create_index; } db->flags |= SQLITE_InternChanges; @@ -2569,7 +2660,7 @@ void sqlite3CreateIndex( else if( db->init.busy==0 ){ Vdbe *v; char *zStmt; - int iMem = pParse->nMem++; + int iMem = ++pParse->nMem; v = sqlite3GetVdbe(pParse); if( v==0 ) goto exit_create_index; @@ -2578,15 +2669,14 @@ void sqlite3CreateIndex( /* Create the rootpage for the index */ sqlite3BeginWriteOperation(pParse, 1, iDb); - sqlite3VdbeAddOp(v, OP_CreateIndex, iDb, 0); - sqlite3VdbeAddOp(v, OP_MemStore, iMem, 0); + sqlite3VdbeAddOp2(v, OP_CreateIndex, iDb, iMem); /* Gather the complete text of the CREATE INDEX statement into ** the zStmt variable */ if( pStart && pEnd ){ /* A named index with an explicit CREATE INDEX statement */ - zStmt = sqlite3MPrintf("CREATE%s INDEX %.*s", + zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s", onError==OE_None ? "" : " UNIQUE", pEnd->z - pName->z + 1, pName->z); @@ -2599,24 +2689,24 @@ void sqlite3CreateIndex( /* Add an entry in sqlite_master for this index */ sqlite3NestedParse(pParse, - "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#0,%Q);", + "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#%d,%Q);", db->aDb[iDb].zName, SCHEMA_TABLE(iDb), pIndex->zName, pTab->zName, + iMem, zStmt ); - sqlite3VdbeAddOp(v, OP_Pop, 1, 0); - sqliteFree(zStmt); + sqlite3_free(zStmt); /* Fill the index with data and reparse the schema. Code an OP_Expire ** to invalidate all pre-compiled statements. */ if( pTblName ){ sqlite3RefillIndex(pParse, pIndex, iMem); - sqlite3ChangeCookie(db, v, iDb); - sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0, - sqlite3MPrintf("name='%q'", pIndex->zName), P3_DYNAMIC); - sqlite3VdbeAddOp(v, OP_Expire, 0, 0); + sqlite3ChangeCookie(pParse, iDb); + sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 0, 0, + sqlite3MPrintf(db, "name='%q'", pIndex->zName), P4_DYNAMIC); + sqlite3VdbeAddOp1(v, OP_Expire, 0); } } @@ -2648,7 +2738,7 @@ exit_create_index: } sqlite3ExprListDelete(pList); sqlite3SrcListDelete(pTblName); - sqliteFree(zName); + sqlite3_free(zName); return; } @@ -2660,11 +2750,17 @@ void sqlite3MinimumFileFormat(Parse *pParse, int iDb, int minFormat){ Vdbe *v; v = sqlite3GetVdbe(pParse); if( v ){ - sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 1); - sqlite3VdbeAddOp(v, OP_Integer, minFormat, 0); - sqlite3VdbeAddOp(v, OP_Ge, 0, sqlite3VdbeCurrentAddr(v)+3); - sqlite3VdbeAddOp(v, OP_Integer, minFormat, 0); - sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 1); + int r1 = sqlite3GetTempReg(pParse); + int r2 = sqlite3GetTempReg(pParse); + int j1; + sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, 1); + sqlite3VdbeUsesBtree(v, iDb); + sqlite3VdbeAddOp2(v, OP_Integer, minFormat, r2); + j1 = sqlite3VdbeAddOp3(v, OP_Ge, r2, 0, r1); + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, 1, r2); + sqlite3VdbeJumpHere(v, j1); + sqlite3ReleaseTempReg(pParse, r1); + sqlite3ReleaseTempReg(pParse, r2); } } @@ -2713,7 +2809,7 @@ void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){ sqlite3 *db = pParse->db; int iDb; - if( pParse->nErr || sqlite3MallocFailed() ){ + if( pParse->nErr || db->mallocFailed ){ goto exit_drop_index; } assert( pName->nSrc==1 ); @@ -2753,14 +2849,15 @@ void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){ /* Generate code to remove the index and from the master table */ v = sqlite3GetVdbe(pParse); if( v ){ + sqlite3BeginWriteOperation(pParse, 1, iDb); sqlite3NestedParse(pParse, "DELETE FROM %Q.%s WHERE name=%Q", db->aDb[iDb].zName, SCHEMA_TABLE(iDb), pIndex->zName ); - sqlite3ChangeCookie(db, v, iDb); + sqlite3ChangeCookie(pParse, iDb); destroyRootPage(pParse, pIndex->tnum, iDb); - sqlite3VdbeOp3(v, OP_DropIndex, iDb, 0, pIndex->zName, 0); + sqlite3VdbeAddOp4(v, OP_DropIndex, iDb, 0, 0, pIndex->zName, 0); } exit_drop_index: @@ -2768,44 +2865,47 @@ exit_drop_index: } /* -** ppArray points into a structure where there is an array pointer -** followed by two integers. The first integer is the -** number of elements in the structure array. The second integer -** is the number of allocated slots in the array. -** -** In other words, the structure looks something like this: +** pArray is a pointer to an array of objects. Each object in the +** array is szEntry bytes in size. This routine allocates a new +** object on the end of the array. ** -** struct Example1 { -** struct subElem *aEntry; -** int nEntry; -** int nAlloc; -** } +** *pnEntry is the number of entries already in use. *pnAlloc is +** the previously allocated size of the array. initSize is the +** suggested initial array size allocation. ** -** The pnEntry parameter points to the equivalent of Example1.nEntry. +** The index of the new entry is returned in *pIdx. ** -** This routine allocates a new slot in the array, zeros it out, -** and returns its index. If malloc fails a negative number is returned. -** -** szEntry is the sizeof of a single array entry. initSize is the -** number of array entries allocated on the initial allocation. +** This routine returns a pointer to the array of objects. This +** might be the same as the pArray parameter or it might be a different +** pointer if the array was resized. */ -int sqlite3ArrayAllocate(void **ppArray, int szEntry, int initSize){ - char *p; - int *an = (int*)&ppArray[1]; - if( an[0]>=an[1] ){ +void *sqlite3ArrayAllocate( + sqlite3 *db, /* Connection to notify of malloc failures */ + void *pArray, /* Array of objects. Might be reallocated */ + int szEntry, /* Size of each object in the array */ + int initSize, /* Suggested initial allocation, in elements */ + int *pnEntry, /* Number of objects currently in use */ + int *pnAlloc, /* Current size of the allocation, in elements */ + int *pIdx /* Write the index of a new slot here */ +){ + char *z; + if( *pnEntry >= *pnAlloc ){ void *pNew; int newSize; - newSize = an[1]*2 + initSize; - pNew = sqliteRealloc(*ppArray, newSize*szEntry); + newSize = (*pnAlloc)*2 + initSize; + pNew = sqlite3DbRealloc(db, pArray, newSize*szEntry); if( pNew==0 ){ - return -1; + *pIdx = -1; + return pArray; } - an[1] = newSize; - *ppArray = pNew; + *pnAlloc = newSize; + pArray = pNew; } - p = *ppArray; - memset(&p[an[0]*szEntry], 0, szEntry); - return an[0]++; + z = (char*)pArray; + memset(&z[*pnEntry * szEntry], 0, szEntry); + *pIdx = *pnEntry; + ++*pnEntry; + return pArray; } /* @@ -2814,19 +2914,27 @@ int sqlite3ArrayAllocate(void **ppArray, int szEntry, int initSize){ ** ** A new IdList is returned, or NULL if malloc() fails. */ -IdList *sqlite3IdListAppend(IdList *pList, Token *pToken){ +IdList *sqlite3IdListAppend(sqlite3 *db, IdList *pList, Token *pToken){ int i; if( pList==0 ){ - pList = sqliteMalloc( sizeof(IdList) ); + pList = sqlite3DbMallocZero(db, sizeof(IdList) ); if( pList==0 ) return 0; pList->nAlloc = 0; } - i = sqlite3ArrayAllocate((void**)&pList->a, sizeof(pList->a[0]), 5); + pList->a = sqlite3ArrayAllocate( + db, + pList->a, + sizeof(pList->a[0]), + 5, + &pList->nId, + &pList->nAlloc, + &i + ); if( i<0 ){ sqlite3IdListDelete(pList); return 0; } - pList->a[i].zName = sqlite3NameFromToken(pToken); + pList->a[i].zName = sqlite3NameFromToken(db, pToken); return pList; } @@ -2837,10 +2945,10 @@ void sqlite3IdListDelete(IdList *pList){ int i; if( pList==0 ) return; for(i=0; i<pList->nId; i++){ - sqliteFree(pList->a[i].zName); + sqlite3_free(pList->a[i].zName); } - sqliteFree(pList->a); - sqliteFree(pList); + sqlite3_free(pList->a); + sqlite3_free(pList); } /* @@ -2872,26 +2980,31 @@ int sqlite3IdListIndex(IdList *pList, const char *zName){ ** ** In other words, if call like this: ** -** sqlite3SrcListAppend(A,B,0); +** sqlite3SrcListAppend(D,A,B,0); ** ** Then B is a table name and the database name is unspecified. If called ** like this: ** -** sqlite3SrcListAppend(A,B,C); +** sqlite3SrcListAppend(D,A,B,C); ** ** Then C is the table name and B is the database name. */ -SrcList *sqlite3SrcListAppend(SrcList *pList, Token *pTable, Token *pDatabase){ +SrcList *sqlite3SrcListAppend( + sqlite3 *db, /* Connection to notify of malloc failures */ + SrcList *pList, /* Append to this SrcList. NULL creates a new SrcList */ + Token *pTable, /* Table to append */ + Token *pDatabase /* Database of the table */ +){ struct SrcList_item *pItem; if( pList==0 ){ - pList = sqliteMalloc( sizeof(SrcList) ); + pList = sqlite3DbMallocZero(db, sizeof(SrcList) ); if( pList==0 ) return 0; pList->nAlloc = 1; } if( pList->nSrc>=pList->nAlloc ){ SrcList *pNew; pList->nAlloc *= 2; - pNew = sqliteRealloc(pList, + pNew = sqlite3DbRealloc(db, pList, sizeof(*pList) + (pList->nAlloc-1)*sizeof(pList->a[0]) ); if( pNew==0 ){ sqlite3SrcListDelete(pList); @@ -2909,8 +3022,8 @@ SrcList *sqlite3SrcListAppend(SrcList *pList, Token *pTable, Token *pDatabase){ pDatabase = pTable; pTable = pTemp; } - pItem->zName = sqlite3NameFromToken(pTable); - pItem->zDatabase = sqlite3NameFromToken(pDatabase); + pItem->zName = sqlite3NameFromToken(db, pTable); + pItem->zDatabase = sqlite3NameFromToken(db, pDatabase); pItem->iCursor = -1; pItem->isPopulated = 0; pList->nSrc++; @@ -2923,7 +3036,7 @@ SrcList *sqlite3SrcListAppend(SrcList *pList, Token *pTable, Token *pDatabase){ void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){ int i; struct SrcList_item *pItem; - assert(pList || sqlite3MallocFailed() ); + assert(pList || pParse->db->mallocFailed ); if( pList ){ for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){ if( pItem->iCursor>=0 ) break; @@ -2936,15 +3049,6 @@ void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){ } /* -** Add an alias to the last identifier on the given identifier list. -*/ -void sqlite3SrcListAddAlias(SrcList *pList, Token *pToken){ - if( pList && pList->nSrc>0 ){ - pList->a[pList->nSrc-1].zAlias = sqlite3NameFromToken(pToken); - } -} - -/* ** Delete an entire SrcList including all its substructure. */ void sqlite3SrcListDelete(SrcList *pList){ @@ -2952,15 +3056,85 @@ void sqlite3SrcListDelete(SrcList *pList){ struct SrcList_item *pItem; if( pList==0 ) return; for(pItem=pList->a, i=0; i<pList->nSrc; i++, pItem++){ - sqliteFree(pItem->zDatabase); - sqliteFree(pItem->zName); - sqliteFree(pItem->zAlias); - sqlite3DeleteTable(0, pItem->pTab); + sqlite3_free(pItem->zDatabase); + sqlite3_free(pItem->zName); + sqlite3_free(pItem->zAlias); + sqlite3DeleteTable(pItem->pTab); sqlite3SelectDelete(pItem->pSelect); sqlite3ExprDelete(pItem->pOn); sqlite3IdListDelete(pItem->pUsing); } - sqliteFree(pList); + sqlite3_free(pList); +} + +/* +** This routine is called by the parser to add a new term to the +** end of a growing FROM clause. The "p" parameter is the part of +** the FROM clause that has already been constructed. "p" is NULL +** if this is the first term of the FROM clause. pTable and pDatabase +** are the name of the table and database named in the FROM clause term. +** pDatabase is NULL if the database name qualifier is missing - the +** usual case. If the term has a alias, then pAlias points to the +** alias token. If the term is a subquery, then pSubquery is the +** SELECT statement that the subquery encodes. The pTable and +** pDatabase parameters are NULL for subqueries. The pOn and pUsing +** parameters are the content of the ON and USING clauses. +** +** Return a new SrcList which encodes is the FROM with the new +** term added. +*/ +SrcList *sqlite3SrcListAppendFromTerm( + Parse *pParse, /* Parsing context */ + SrcList *p, /* The left part of the FROM clause already seen */ + Token *pTable, /* Name of the table to add to the FROM clause */ + Token *pDatabase, /* Name of the database containing pTable */ + Token *pAlias, /* The right-hand side of the AS subexpression */ + Select *pSubquery, /* A subquery used in place of a table name */ + Expr *pOn, /* The ON clause of a join */ + IdList *pUsing /* The USING clause of a join */ +){ + struct SrcList_item *pItem; + sqlite3 *db = pParse->db; + p = sqlite3SrcListAppend(db, p, pTable, pDatabase); + if( p==0 || p->nSrc==0 ){ + sqlite3ExprDelete(pOn); + sqlite3IdListDelete(pUsing); + sqlite3SelectDelete(pSubquery); + return p; + } + pItem = &p->a[p->nSrc-1]; + if( pAlias && pAlias->n ){ + pItem->zAlias = sqlite3NameFromToken(db, pAlias); + } + pItem->pSelect = pSubquery; + pItem->pOn = pOn; + pItem->pUsing = pUsing; + return p; +} + +/* +** When building up a FROM clause in the parser, the join operator +** is initially attached to the left operand. But the code generator +** expects the join operator to be on the right operand. This routine +** Shifts all join operators from left to right for an entire FROM +** clause. +** +** Example: Suppose the join is like this: +** +** A natural cross join B +** +** The operator is "natural cross join". The A and B operands are stored +** in p->a[0] and p->a[1], respectively. The parser initially stores the +** operator with A. This routine shifts that operator over to B. +*/ +void sqlite3SrcListShiftJoinType(SrcList *p){ + if( p && p->a ){ + int i; + for(i=p->nSrc-1; i>0; i--){ + p->a[i].jointype = p->a[i-1].jointype; + } + p->a[0].jointype = 0; + } } /* @@ -2972,17 +3146,18 @@ void sqlite3BeginTransaction(Parse *pParse, int type){ int i; if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return; - if( pParse->nErr || sqlite3MallocFailed() ) return; + if( pParse->nErr || db->mallocFailed ) return; if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ) return; v = sqlite3GetVdbe(pParse); if( !v ) return; if( type!=TK_DEFERRED ){ for(i=0; i<db->nDb; i++){ - sqlite3VdbeAddOp(v, OP_Transaction, i, (type==TK_EXCLUSIVE)+1); + sqlite3VdbeAddOp2(v, OP_Transaction, i, (type==TK_EXCLUSIVE)+1); + sqlite3VdbeUsesBtree(v, i); } } - sqlite3VdbeAddOp(v, OP_AutoCommit, 0, 0); + sqlite3VdbeAddOp2(v, OP_AutoCommit, 0, 0); } /* @@ -2993,12 +3168,12 @@ void sqlite3CommitTransaction(Parse *pParse){ Vdbe *v; if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return; - if( pParse->nErr || sqlite3MallocFailed() ) return; + if( pParse->nErr || db->mallocFailed ) return; if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ) return; v = sqlite3GetVdbe(pParse); if( v ){ - sqlite3VdbeAddOp(v, OP_AutoCommit, 1, 0); + sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, 0); } } @@ -3010,12 +3185,12 @@ void sqlite3RollbackTransaction(Parse *pParse){ Vdbe *v; if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return; - if( pParse->nErr || sqlite3MallocFailed() ) return; + if( pParse->nErr || db->mallocFailed ) return; if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ) return; v = sqlite3GetVdbe(pParse); if( v ){ - sqlite3VdbeAddOp(v, OP_AutoCommit, 1, 1); + sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, 1); } } @@ -3026,22 +3201,23 @@ void sqlite3RollbackTransaction(Parse *pParse){ int sqlite3OpenTempDatabase(Parse *pParse){ sqlite3 *db = pParse->db; if( db->aDb[1].pBt==0 && !pParse->explain ){ - int rc = sqlite3BtreeFactory(db, 0, 0, MAX_PAGES, &db->aDb[1].pBt); + int rc; + static const int flags = + SQLITE_OPEN_READWRITE | + SQLITE_OPEN_CREATE | + SQLITE_OPEN_EXCLUSIVE | + SQLITE_OPEN_DELETEONCLOSE | + SQLITE_OPEN_TEMP_DB; + + rc = sqlite3BtreeFactory(db, 0, 0, SQLITE_DEFAULT_CACHE_SIZE, flags, + &db->aDb[1].pBt); if( rc!=SQLITE_OK ){ sqlite3ErrorMsg(pParse, "unable to open a temporary database " "file for storing temporary tables"); pParse->rc = rc; return 1; } - if( db->flags & !db->autoCommit ){ - rc = sqlite3BtreeBeginTrans(db->aDb[1].pBt, 1); - if( rc!=SQLITE_OK ){ - sqlite3ErrorMsg(pParse, "unable to get a write lock on " - "the temporary database file"); - pParse->rc = rc; - return 1; - } - } + assert( (db->flags & SQLITE_InTrans)==0 || db->autoCommit ); assert( db->aDb[1].pSchema ); } return 0; @@ -3078,12 +3254,12 @@ void sqlite3CodeVerifySchema(Parse *pParse, int iDb){ if( v==0 ) return; /* This only happens if there was a prior error */ db = pParse->db; if( pParse->cookieGoto==0 ){ - pParse->cookieGoto = sqlite3VdbeAddOp(v, OP_Goto, 0, 0)+1; + pParse->cookieGoto = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0)+1; } if( iDb>=0 ){ assert( iDb<db->nDb ); assert( db->aDb[iDb].pBt!=0 || iDb==1 ); - assert( iDb<MAX_ATTACHED+2 ); + assert( iDb<SQLITE_MAX_ATTACHED+2 ); mask = 1<<iDb; if( (pParse->cookieMask & mask)==0 ){ pParse->cookieMask |= mask; @@ -3119,7 +3295,7 @@ void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){ sqlite3CodeVerifySchema(pParse, iDb); pParse->writeMask |= 1<<iDb; if( setStatement && pParse->nested==0 ){ - sqlite3VdbeAddOp(v, OP_Statement, iDb, 0); + sqlite3VdbeAddOp1(v, OP_Statement, iDb); } if( (OMIT_TEMPDB || iDb!=1) && pParse->db->aDb[1].pBt!=0 ){ sqlite3BeginWriteOperation(pParse, setStatement, 1); @@ -3218,29 +3394,33 @@ void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){ reindexDatabases(pParse, 0); return; }else if( pName2==0 || pName2->z==0 ){ + char *zColl; assert( pName1->z ); - pColl = sqlite3FindCollSeq(db, ENC(db), (char*)pName1->z, pName1->n, 0); + zColl = sqlite3NameFromToken(pParse->db, pName1); + if( !zColl ) return; + pColl = sqlite3FindCollSeq(db, ENC(db), zColl, -1, 0); if( pColl ){ - char *zColl = sqliteStrNDup((const char *)pName1->z, pName1->n); if( zColl ){ reindexDatabases(pParse, zColl); - sqliteFree(zColl); + sqlite3_free(zColl); } return; } + sqlite3_free(zColl); } iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pObjName); if( iDb<0 ) return; - z = sqlite3NameFromToken(pObjName); + z = sqlite3NameFromToken(db, pObjName); + if( z==0 ) return; zDb = db->aDb[iDb].zName; pTab = sqlite3FindTable(db, z, zDb); if( pTab ){ reindexTable(pParse, pTab, 0); - sqliteFree(z); + sqlite3_free(z); return; } pIndex = sqlite3FindIndex(db, z, zDb); - sqliteFree(z); + sqlite3_free(z); if( pIndex ){ sqlite3BeginWriteOperation(pParse, 0, iDb); sqlite3RefillIndex(pParse, pIndex, -1); @@ -3255,7 +3435,7 @@ void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){ ** with OP_OpenRead or OP_OpenWrite to access database index pIdx. ** ** If successful, a pointer to the new structure is returned. In this case -** the caller is responsible for calling sqliteFree() on the returned +** the caller is responsible for calling sqlite3_free() on the returned ** pointer. If an error occurs (out of memory or missing collation ** sequence), NULL is returned and the state of pParse updated to reflect ** the error. @@ -3264,9 +3444,10 @@ KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){ int i; int nCol = pIdx->nColumn; int nBytes = sizeof(KeyInfo) + (nCol-1)*sizeof(CollSeq*) + nCol; - KeyInfo *pKey = (KeyInfo *)sqliteMalloc(nBytes); + KeyInfo *pKey = (KeyInfo *)sqlite3DbMallocZero(pParse->db, nBytes); if( pKey ){ + pKey->db = pParse->db; pKey->aSortOrder = (u8 *)&(pKey->aColl[nCol]); assert( &pKey->aSortOrder[nCol]==&(((u8 *)pKey)[nBytes]) ); for(i=0; i<nCol; i++){ @@ -3279,7 +3460,7 @@ KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){ } if( pParse->nErr ){ - sqliteFree(pKey); + sqlite3_free(pKey); pKey = 0; } return pKey; |
