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);
     }