diff options
Diffstat (limited to 'ext/pdo_sqlite/sqlite/src/build.c')
-rw-r--r-- | ext/pdo_sqlite/sqlite/src/build.c | 187 |
1 files changed, 105 insertions, 82 deletions
diff --git a/ext/pdo_sqlite/sqlite/src/build.c b/ext/pdo_sqlite/sqlite/src/build.c index 450316e5a4..67e83e970b 100644 --- a/ext/pdo_sqlite/sqlite/src/build.c +++ b/ext/pdo_sqlite/sqlite/src/build.c @@ -200,9 +200,6 @@ Table *sqlite3LocateTable(Parse *pParse, const char *zName, const char *zDbase){ 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 +255,7 @@ static void sqliteDeleteIndex(sqlite3 *db, Index *p){ 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 +529,7 @@ void sqlite3OpenMasterTable(Vdbe *v, int iDb){ ** 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 +577,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++; @@ -745,7 +739,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 +896,11 @@ void sqlite3AddNotNull(Parse *pParse, int onError){ ** 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 +932,18 @@ static char sqlite3AffinityType(const char *zType, int nType){ ** 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); + pCol->zType = sqlite3NameFromToken(pType); + pCol->affinity = sqlite3AffinityType(pType); } /* @@ -977,14 +959,15 @@ void sqlite3AddColumnType(Parse *pParse, Token *pFirst, Token *pLast){ 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); } @@ -1317,13 +1300,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 +1516,13 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ ** 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 +1957,6 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ 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 +1985,21 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ 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 +2067,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); @@ -2177,11 +2167,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 = &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 +2208,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 +2376,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){ + int *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. */ @@ -2473,6 +2496,32 @@ IdList *sqlite3IdListAppend(IdList *pList, Token *pToken){ } /* +** 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 +2606,6 @@ void sqlite3SrcListAddAlias(SrcList *pList, Token *pToken){ } /* -** 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 +2807,7 @@ static int collationMatch(CollSeq *pColl, Index *pIndex){ ** 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 +2825,7 @@ void reindexTable(Parse *pParse, Table *pTab, CollSeq *pColl){ ** 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 +2834,7 @@ void reindexDatabases(Parse *pParse, CollSeq *pColl){ 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); } |