The unified diff between revisions [83b5270b..] and [5587f68e..] is displayed below. It can also be downloaded as a raw diff.
This diff has been restricted to the following files: 'sqlite/build.c'
#
#
# patch "sqlite/build.c"
# from [593d8fda0576a72e6f1fbf8f1a61db110dde9264]
# to [74653e045581bfbadb8b35a0cb38a62f4a2c850e]
#
============================================================
--- sqlite/build.c 593d8fda0576a72e6f1fbf8f1a61db110dde9264
+++ sqlite/build.c 74653e045581bfbadb8b35a0cb38a62f4a2c850e
@@ -22,7 +22,7 @@
** COMMIT
** ROLLBACK
**
-** $Id: build.c,v 1.326 2005/06/12 21:35:52 drh Exp $
+** $Id: build.c,v 1.350 2005/09/16 02:48:02 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@@ -85,6 +85,7 @@ void sqlite3FinishCoding(Parse *pParse){
sqlite3VdbeAddOp(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.
@@ -92,6 +93,7 @@ void sqlite3FinishCoding(Parse *pParse){
** This is used to implement sqlite3_trace().
*/
sqlite3VdbeOp3(v, OP_Noop, 0, 0, pParse->zSql, pParse->zTail-pParse->zSql);
+#endif /* SQLITE_OMIT_TRACE */
}
@@ -101,7 +103,7 @@ void sqlite3FinishCoding(Parse *pParse){
FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0;
sqlite3VdbeTrace(v, trace);
sqlite3VdbeMakeReady(v, pParse->nVar, pParse->nMem+3,
- pParse->nTab+3, pParse->nMaxDepth+1, pParse->explain);
+ pParse->nTab+3, pParse->explain);
pParse->rc = SQLITE_DONE;
pParse->colNamesSet = 0;
}else if( pParse->rc==SQLITE_OK ){
@@ -130,7 +132,6 @@ void sqlite3NestedParse(Parse *pParse, c
void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
va_list ap;
char *zSql;
- int rc;
# define SAVE_SZ (sizeof(Parse) - offsetof(Parse,nVar))
char saveBuf[SAVE_SZ];
@@ -145,7 +146,7 @@ void sqlite3NestedParse(Parse *pParse, c
pParse->nested++;
memcpy(saveBuf, &pParse->nVar, SAVE_SZ);
memset(&pParse->nVar, 0, SAVE_SZ);
- rc = sqlite3RunParser(pParse, zSql, 0);
+ sqlite3RunParser(pParse, zSql, 0);
sqliteFree(zSql);
memcpy(&pParse->nVar, saveBuf, SAVE_SZ);
pParse->nested--;
@@ -200,9 +201,6 @@ Table *sqlite3LocateTable(Parse *pParse,
if( p==0 ){
if( zDbase ){
sqlite3ErrorMsg(pParse, "no such table: %s.%s", zDbase, zName);
- }else if( sqlite3FindTable(pParse->db, zName, 0)!=0 ){
- sqlite3ErrorMsg(pParse, "table \"%s\" is not in database \"%s\"",
- zName, zDbase);
}else{
sqlite3ErrorMsg(pParse, "no such table: %s", zName);
}
@@ -258,10 +256,7 @@ static void sqliteDeleteIndex(sqlite3 *d
assert( db!=0 && p->zName!=0 );
pOld = sqlite3HashInsert(&db->aDb[p->iDb].idxHash, p->zName,
strlen(p->zName)+1, 0);
- if( pOld!=0 && pOld!=p ){
- sqlite3HashInsert(&db->aDb[p->iDb].idxHash, pOld->zName,
- strlen(pOld->zName)+1, pOld);
- }
+ assert( pOld==0 || pOld==p );
freeIndex(p);
}
@@ -535,7 +530,7 @@ void sqlite3OpenMasterTable(Vdbe *v, int
** index of the named database in db->aDb[], or -1 if the named db
** does not exist.
*/
-static int findDb(sqlite3 *db, Token *pName){
+int sqlite3FindDb(sqlite3 *db, Token *pName){
int i = -1; /* Database number */
int n; /* Number of characters in the name */
Db *pDb; /* A database whose name space is being searched */
@@ -583,7 +578,7 @@ int sqlite3TwoPartName(
if( pName2 && pName2->n>0 ){
assert( !db->init.busy );
*pUnqual = pName2;
- iDb = findDb(db, pName1);
+ iDb = sqlite3FindDb(db, pName1);
if( iDb<0 ){
sqlite3ErrorMsg(pParse, "unknown database %T", pName1);
pParse->nErr++;
@@ -640,7 +635,6 @@ void sqlite3StartTable(
int isView /* True if this is a VIEW */
){
Table *pTable;
- Index *pIdx;
char *zName = 0; /* The name of the new table */
sqlite3 *db = pParse->db;
Vdbe *v;
@@ -719,8 +713,7 @@ void sqlite3StartTable(
sqlite3ErrorMsg(pParse, "table %T already exists", pName);
goto begin_table_error;
}
- if( (pIdx = sqlite3FindIndex(db, zName, 0))!=0 &&
- ( iDb==0 || !db->init.busy) ){
+ if( sqlite3FindIndex(db, zName, 0)!=0 && (iDb==0 || !db->init.busy) ){
sqlite3ErrorMsg(pParse, "there is already an index named %s", zName);
goto begin_table_error;
}
@@ -745,7 +738,7 @@ void sqlite3StartTable(
** so that INSERT can find the table easily.
*/
#ifndef SQLITE_OMIT_AUTOINCREMENT
- if( strcmp(zName, "sqlite_sequence")==0 ){
+ if( !pParse->nested && strcmp(zName, "sqlite_sequence")==0 ){
db->aDb[iDb].pSeqTab = pTable;
}
#endif
@@ -902,11 +895,11 @@ void sqlite3AddNotNull(Parse *pParse, in
** If none of the substrings in the above table are found,
** SQLITE_AFF_NUMERIC is returned.
*/
-static char sqlite3AffinityType(const char *zType, int nType){
+char sqlite3AffinityType(const Token *pType){
u32 h = 0;
char aff = SQLITE_AFF_NUMERIC;
- const unsigned char *zIn = zType;
- const unsigned char *zEnd = (zIn+nType);
+ const unsigned char *zIn = pType->z;
+ const unsigned char *zEnd = &pType->z[pType->n];
while( zIn!=zEnd ){
h = (h<<8) + sqlite3UpperToLower[*zIn];
@@ -938,30 +931,18 @@ static char sqlite3AffinityType(const ch
** that contains the typename of the column and store that string
** in zType.
*/
-void sqlite3AddColumnType(Parse *pParse, Token *pFirst, Token *pLast){
+void sqlite3AddColumnType(Parse *pParse, Token *pType){
Table *p;
- int i, j;
- int n;
- char *z;
- const unsigned char *zIn;
-
+ int i;
Column *pCol;
+
if( (p = pParse->pNewTable)==0 ) return;
i = p->nCol-1;
if( i<0 ) return;
pCol = &p->aCol[i];
- zIn = pFirst->z;
- n = pLast->n + (pLast->z - zIn);
- assert( pCol->zType==0 );
- z = pCol->zType = sqliteMallocRaw(n+1);
- if( z==0 ) return;
- for(i=j=0; i<n; i++){
- int c = zIn[i];
- if( isspace(c) ) continue;
- z[j++] = c;
- }
- z[j] = 0;
- pCol->affinity = sqlite3AffinityType(z, n);
+ sqliteFree(pCol->zType);
+ pCol->zType = sqlite3NameFromToken(pType);
+ pCol->affinity = sqlite3AffinityType(pType);
}
/*
@@ -977,14 +958,15 @@ void sqlite3AddDefaultValue(Parse *pPars
void sqlite3AddDefaultValue(Parse *pParse, Expr *pExpr){
Table *p;
Column *pCol;
- if( (p = pParse->pNewTable)==0 ) return;
- pCol = &(p->aCol[p->nCol-1]);
- if( !sqlite3ExprIsConstant(pExpr) ){
- sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant",
- pCol->zName);
- }else{
- sqlite3ExprDelete(pCol->pDflt);
- pCol->pDflt = sqlite3ExprDup(pExpr);
+ if( (p = pParse->pNewTable)!=0 ){
+ pCol = &(p->aCol[p->nCol-1]);
+ if( !sqlite3ExprIsConstantOrFunction(pExpr) ){
+ sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant",
+ pCol->zName);
+ }else{
+ sqlite3ExprDelete(pCol->pDflt);
+ pCol->pDflt = sqlite3ExprDup(pExpr);
+ }
}
sqlite3ExprDelete(pExpr);
}
@@ -1033,7 +1015,9 @@ void sqlite3AddPrimaryKey(
break;
}
}
- if( iCol<pTab->nCol ) pTab->aCol[iCol].isPrimKey = 1;
+ if( iCol<pTab->nCol ){
+ pTab->aCol[iCol].isPrimKey = 1;
+ }
}
if( pList->nExpr>1 ) iCol = -1;
}
@@ -1317,13 +1301,11 @@ void sqlite3EndTable(
*/
if( p->pSelect==0 ){
/* A regular table */
- /* sqlite3VdbeAddOp(v, OP_CreateTable, p->iDb, 0); */
zType = "table";
zType2 = "TABLE";
#ifndef SQLITE_OMIT_VIEW
}else{
/* A view */
- /* sqlite3VdbeAddOp(v, OP_Integer, 0, 0); */
zType = "view";
zType2 = "VIEW";
#endif
@@ -1535,10 +1517,13 @@ int sqlite3ViewGetColumnNames(Parse *pPa
** Actually, this error is caught previously and so the following test
** should always fail. But we will leave it in place just to be safe.
*/
+#if 0
if( pTable->nCol<0 ){
sqlite3ErrorMsg(pParse, "view %s is circularly defined", pTable->zName);
return 1;
}
+#endif
+ assert( pTable->nCol>=0 );
/* If we get this far, it means we need to compute the table names.
** Note that the call to sqlite3ResultSetOfSelect() will expand any
@@ -1973,7 +1958,6 @@ static void sqlite3RefillIndex(Parse *pP
int addr1; /* Address of top of loop */
int tnum; /* Root page of index */
Vdbe *v; /* Generate code into this virtual machine */
- int isUnique; /* True for a unique index */
#ifndef SQLITE_OMIT_AUTHORIZATION
if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0,
@@ -2002,16 +1986,21 @@ static void sqlite3RefillIndex(Parse *pP
sqlite3VdbeAddOp(v, OP_Integer, pIndex->iDb, 0);
sqlite3VdbeOp3(v, OP_OpenWrite, iIdx, tnum,
(char*)&pIndex->keyInfo, P3_KEYINFO);
- sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
- sqlite3VdbeAddOp(v, OP_OpenRead, iTab, pTab->tnum);
- sqlite3VdbeAddOp(v, OP_SetNumColumns, iTab, pTab->nCol);
+ sqlite3OpenTableForReading(v, iTab, pTab);
addr1 = sqlite3VdbeAddOp(v, OP_Rewind, iTab, 0);
sqlite3GenerateIndexKey(v, pIndex, iTab);
- isUnique = pIndex->onError!=OE_None;
- sqlite3VdbeAddOp(v, OP_IdxInsert, iIdx, isUnique);
- if( isUnique ){
- sqlite3VdbeChangeP3(v, -1, "indexed columns are not unique", P3_STATIC);
+ 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);
sqlite3VdbeChangeP2(v, addr1, sqlite3VdbeCurrentAddr(v));
sqlite3VdbeAddOp(v, OP_Close, iTab, 0);
@@ -2079,7 +2068,9 @@ void sqlite3CreateIndex(
if( sqlite3FixInit(&sFix, pParse, iDb, "index", pName) &&
sqlite3FixSrcList(&sFix, pTblName)
){
- goto exit_create_index;
+ /* Because the parser constructs pTblName from a single identifier,
+ ** sqlite3FixSrcList can never fail. */
+ assert(0);
}
pTab = sqlite3LocateTable(pParse, pTblName->a[0].zName,
pTblName->a[0].zDatabase);
@@ -2124,14 +2115,12 @@ void sqlite3CreateIndex(
goto exit_create_index;
}
if( !db->init.busy ){
- Index *pISameName; /* Another index with the same name */
- Table *pTSameName; /* A table with same name as the index */
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto exit_create_index;
- if( (pISameName = sqlite3FindIndex(db, zName, db->aDb[iDb].zName))!=0 ){
+ if( sqlite3FindIndex(db, zName, db->aDb[iDb].zName)!=0 ){
sqlite3ErrorMsg(pParse, "index %s already exists", zName);
goto exit_create_index;
}
- if( (pTSameName = sqlite3FindTable(db, zName, 0))!=0 ){
+ if( sqlite3FindTable(db, zName, 0)!=0 ){
sqlite3ErrorMsg(pParse, "there is already a table named %s", zName);
goto exit_create_index;
}
@@ -2177,11 +2166,12 @@ void sqlite3CreateIndex(
/*
** Allocate the index structure.
*/
- pIndex = sqliteMalloc( sizeof(Index) + strlen(zName) + 1 +
- (sizeof(int) + sizeof(CollSeq*))*pList->nExpr );
+ pIndex = sqliteMalloc( sizeof(Index) + strlen(zName) + 1 + sizeof(int) +
+ (sizeof(int)*2 + sizeof(CollSeq*))*pList->nExpr );
if( sqlite3_malloc_failed ) goto exit_create_index;
pIndex->aiColumn = (int*)&pIndex->keyInfo.aColl[pList->nExpr];
- pIndex->zName = (char*)&pIndex->aiColumn[pList->nExpr];
+ pIndex->aiRowEst = (unsigned*)&pIndex->aiColumn[pList->nExpr];
+ pIndex->zName = (char*)&pIndex->aiRowEst[pList->nExpr+1];
strcpy(pIndex->zName, zName);
pIndex->pTable = pTab;
pIndex->nColumn = pList->nExpr;
@@ -2217,6 +2207,7 @@ void sqlite3CreateIndex(
}
}
pIndex->keyInfo.nField = pList->nExpr;
+ sqlite3DefaultRowEst(pIndex);
if( pTab==pParse->pNewTable ){
/* This routine has been called to create an automatic index as a
@@ -2384,6 +2375,37 @@ exit_create_index:
}
/*
+** Fill the Index.aiRowEst[] array with default information - information
+** to be used when we have not run the ANALYZE command.
+**
+** aiRowEst[0] is suppose to contain the number of elements in the index.
+** Since we do not know, guess 1 million. aiRowEst[1] is an estimate of the
+** number of rows in the table that match any particular value of the
+** first column of the index. aiRowEst[2] is an estimate of the number
+** of rows that match any particular combiniation of the first 2 columns
+** of the index. And so forth. It must always be the case that
+*
+** aiRowEst[N]<=aiRowEst[N-1]
+** aiRowEst[N]>=1
+**
+** Apart from that, we have little to go on besides intuition as to
+** how aiRowEst[] should be initialized. The numbers generated here
+** are based on typical values found in actual indices.
+*/
+void sqlite3DefaultRowEst(Index *pIdx){
+ unsigned *a = pIdx->aiRowEst;
+ int i;
+ assert( a!=0 );
+ a[0] = 1000000;
+ for(i=pIdx->nColumn; i>=1; i--){
+ a[i] = 10;
+ }
+ if( pIdx->onError!=OE_None ){
+ a[pIdx->nColumn] = 1;
+ }
+}
+
+/*
** This routine will drop an existing named index. This routine
** implements the DROP INDEX statement.
*/
@@ -2445,34 +2467,95 @@ 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:
+**
+** struct Example1 {
+** struct subElem *aEntry;
+** int nEntry;
+** int nAlloc;
+** }
+**
+** The pnEntry parameter points to the equivalent of Example1.nEntry.
+**
+** 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.
+*/
+int sqlite3ArrayAllocate(void **ppArray, int szEntry, int initSize){
+ char *p;
+ int *an = (int*)&ppArray[1];
+ if( an[0]>=an[1] ){
+ void *pNew;
+ int newSize;
+ newSize = an[1]*2 + initSize;
+ pNew = sqliteRealloc(*ppArray, newSize*szEntry);
+ if( pNew==0 ){
+ return -1;
+ }
+ an[1] = newSize;
+ *ppArray = pNew;
+ }
+ p = *ppArray;
+ memset(&p[an[0]*szEntry], 0, szEntry);
+ return an[0]++;
+}
+
+/*
** Append a new element to the given IdList. Create a new IdList if
** need be.
**
** A new IdList is returned, or NULL if malloc() fails.
*/
IdList *sqlite3IdListAppend(IdList *pList, Token *pToken){
+ int i;
if( pList==0 ){
pList = sqliteMalloc( sizeof(IdList) );
if( pList==0 ) return 0;
pList->nAlloc = 0;
}
- if( pList->nId>=pList->nAlloc ){
- struct IdList_item *a;
- pList->nAlloc = pList->nAlloc*2 + 5;
- a = sqliteRealloc(pList->a, pList->nAlloc*sizeof(pList->a[0]) );
- if( a==0 ){
- sqlite3IdListDelete(pList);
- return 0;
- }
- pList->a = a;
+ i = sqlite3ArrayAllocate((void**)&pList->a, sizeof(pList->a[0]), 5);
+ if( i<0 ){
+ sqlite3IdListDelete(pList);
+ return 0;
}
- memset(&pList->a[pList->nId], 0, sizeof(pList->a[0]));
- pList->a[pList->nId].zName = sqlite3NameFromToken(pToken);
- pList->nId++;
+ pList->a[i].zName = sqlite3NameFromToken(pToken);
return pList;
}
/*
+** Delete an IdList.
+*/
+void sqlite3IdListDelete(IdList *pList){
+ int i;
+ if( pList==0 ) return;
+ for(i=0; i<pList->nId; i++){
+ sqliteFree(pList->a[i].zName);
+ }
+ sqliteFree(pList->a);
+ sqliteFree(pList);
+}
+
+/*
+** Return the index in pList of the identifier named zId. Return -1
+** if not found.
+*/
+int sqlite3IdListIndex(IdList *pList, const char *zName){
+ int i;
+ if( pList==0 ) return -1;
+ for(i=0; i<pList->nId; i++){
+ if( sqlite3StrICmp(pList->a[i].zName, zName)==0 ) return i;
+ }
+ return -1;
+}
+
+/*
** Append a new table name to the given SrcList. Create a new SrcList if
** need be. A new entry is created in the SrcList even if pToken is NULL.
**
@@ -2557,32 +2640,6 @@ void sqlite3SrcListAddAlias(SrcList *pLi
}
/*
-** Delete an IdList.
-*/
-void sqlite3IdListDelete(IdList *pList){
- int i;
- if( pList==0 ) return;
- for(i=0; i<pList->nId; i++){
- sqliteFree(pList->a[i].zName);
- }
- sqliteFree(pList->a);
- sqliteFree(pList);
-}
-
-/*
-** Return the index in pList of the identifier named zId. Return -1
-** if not found.
-*/
-int sqlite3IdListIndex(IdList *pList, const char *zName){
- int i;
- if( pList==0 ) return -1;
- for(i=0; i<pList->nId; i++){
- if( sqlite3StrICmp(pList->a[i].zName, zName)==0 ) return i;
- }
- return -1;
-}
-
-/*
** Delete an entire SrcList including all its substructure.
*/
void sqlite3SrcListDelete(SrcList *pList){
@@ -2784,7 +2841,7 @@ static int collationMatch(CollSeq *pColl
** If pColl==0 then recompute all indices of pTab.
*/
#ifndef SQLITE_OMIT_REINDEX
-void reindexTable(Parse *pParse, Table *pTab, CollSeq *pColl){
+static void reindexTable(Parse *pParse, Table *pTab, CollSeq *pColl){
Index *pIndex; /* An index associated with pTab */
for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){
@@ -2802,7 +2859,7 @@ void reindexTable(Parse *pParse, Table *
** all indices everywhere.
*/
#ifndef SQLITE_OMIT_REINDEX
-void reindexDatabases(Parse *pParse, CollSeq *pColl){
+static void reindexDatabases(Parse *pParse, CollSeq *pColl){
Db *pDb; /* A single database */
int iDb; /* The database index number */
sqlite3 *db = pParse->db; /* The database connection */
@@ -2811,7 +2868,7 @@ void reindexDatabases(Parse *pParse, Col
for(iDb=0, pDb=db->aDb; iDb<db->nDb; iDb++, pDb++){
if( pDb==0 ) continue;
- for(k=sqliteHashFirst(&pDb->tblHash); k; k=sqliteHashNext(k)){
+ for(k=sqliteHashFirst(&pDb->tblHash); k; k=sqliteHashNext(k)){
pTab = (Table*)sqliteHashData(k);
reindexTable(pParse, pTab, pColl);
}