]> granicus.if.org Git - php/commitdiff
MFH: Upgraded SQLite 2 library in ext/sqlite to 2.8.16
authorIlia Alshanetsky <iliaa@php.net>
Wed, 7 Sep 2005 15:11:33 +0000 (15:11 +0000)
committerIlia Alshanetsky <iliaa@php.net>
Wed, 7 Sep 2005 15:11:33 +0000 (15:11 +0000)
18 files changed:
NEWS
ext/sqlite/libsqlite/VERSION
ext/sqlite/libsqlite/src/btree_rb.c
ext/sqlite/libsqlite/src/build.c
ext/sqlite/libsqlite/src/date.c
ext/sqlite/libsqlite/src/expr.c
ext/sqlite/libsqlite/src/func.c
ext/sqlite/libsqlite/src/main.c
ext/sqlite/libsqlite/src/os.c
ext/sqlite/libsqlite/src/printf.c
ext/sqlite/libsqlite/src/select.c
ext/sqlite/libsqlite/src/sqlite.h.in
ext/sqlite/libsqlite/src/sqlite.w32.h
ext/sqlite/libsqlite/src/sqliteInt.h
ext/sqlite/libsqlite/src/util.c
ext/sqlite/libsqlite/src/vacuum.c
ext/sqlite/libsqlite/src/vdbe.c
ext/sqlite/libsqlite/src/where.c

diff --git a/NEWS b/NEWS
index 549db6525246f631f4a520065adf828cdb275c2c..c8a0c5ade304af2d9afc09b656dbddcc6045e551 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,7 @@ PHP                                                                        NEWS
   classes. (Dmitry, Michael Wallner)
 - Added "new_link" parameter to mssql_connect(). Bug #34369. (Frank)
 - Upgraded bundled SQLite library for PDO:SQLite to 3.2.5 (Ilia)
+- Upgraded SQLite 2 library in ext/sqlite to 2.8.16 (Ilia)
 - Upgraded PCRE library to version 6.2. (Andrei)
 - Upgraded bundled libraries in Windows distribution. (Edin)
   . zlib 1.2.3
index 63cb62ffdbd6ce4f526cb78534c7771200ff3c88..85c0a6a965e4c81ac1f2a2a5d10a8a5a67c4e9e9 100644 (file)
@@ -1 +1 @@
-2.8.14
+2.8.16
index 49009be8304f23cd7d5d5d31a602f56fd20d3896..d932ab4a974037773b5aa35e20a3253deb3c0aa6 100644 (file)
@@ -259,17 +259,16 @@ static void rightRotate(BtRbTree *pTree, BtRbNode *pX)
  * concatenation of orig and val is returned. The original orig is deleted
  * (using sqliteFree()).
  */
-static char *append_val(char * orig, char const * val)
-{
+static char *append_val(char * orig, char const * val){
+  char *z;
   if( !orig ){
-    return sqliteStrDup( val );
+    z = sqliteStrDup( val );
   } else{
-    char * ret = 0;
-    sqliteSetString(&ret, orig, val, (char*)0);
+    z = 0;
+    sqliteSetString(&z, orig, val, (char*)0);
     sqliteFree( orig );
-    return ret;
   }
-  assert(0);
+  return z;
 }
 
 /*
@@ -723,13 +722,13 @@ static int memRbtreeCursor(
   pCur = *ppCur = sqliteMalloc(sizeof(RbtCursor));
   if( sqlite_malloc_failed ) return SQLITE_NOMEM;
   pCur->pTree  = sqliteHashFind(&tree->tblHash, 0, iTable);
+  assert( pCur->pTree );
   pCur->pRbtree = tree;
   pCur->iTree  = iTable;
   pCur->pOps = &sqliteRbtreeCursorOps;
   pCur->wrFlag = wrFlag;
   pCur->pShared = pCur->pTree->pCursors;
   pCur->pTree->pCursors = pCur;
-  
 
   assert( (*ppCur)->pTree );
   return SQLITE_OK;
@@ -1178,12 +1177,11 @@ static int memRbtreeKey(RbtCursor* pCur, int offset, int amt, char *zBuf)
   if( !pCur->pNode ) return 0;
   if( !pCur->pNode->pKey || ((amt + offset) <= pCur->pNode->nKey) ){
     memcpy(zBuf, ((char*)pCur->pNode->pKey)+offset, amt);
-    return amt;
   }else{
     memcpy(zBuf, ((char*)pCur->pNode->pKey)+offset, pCur->pNode->nKey-offset);
-    return pCur->pNode->nKey-offset;
+    amt = pCur->pNode->nKey-offset;
   }
-  assert(0);
+  return amt;
 }
 
 static int memRbtreeDataSize(RbtCursor* pCur, int *pSize)
@@ -1201,12 +1199,11 @@ static int memRbtreeData(RbtCursor *pCur, int offset, int amt, char *zBuf)
   if( !pCur->pNode ) return 0;
   if( (amt + offset) <= pCur->pNode->nData ){
     memcpy(zBuf, ((char*)pCur->pNode->pData)+offset, amt);
-    return amt;
   }else{
     memcpy(zBuf, ((char*)pCur->pNode->pData)+offset ,pCur->pNode->nData-offset);
-    return pCur->pNode->nData-offset;
+    amt = pCur->pNode->nData-offset;
   }
-  assert(0);
+  return amt;
 }
 
 static int memRbtreeCloseCursor(RbtCursor* pCur)
@@ -1421,13 +1418,12 @@ static int memRbtreeCursorDump(RbtCursor* pCur, int* aRes)
   assert(!"Cannot call sqliteRbtreeCursorDump");
   return SQLITE_OK;
 }
+#endif
 
 static struct Pager *memRbtreePager(Rbtree* tree)
 {
-  assert(!"Cannot call sqliteRbtreePager");
-  return SQLITE_OK;
+  return 0;
 }
-#endif
 
 /*
 ** Return the full pathname of the underlying database file.
@@ -1463,10 +1459,9 @@ static BtOps sqliteRbtreeOps = {
     (char*(*)(Btree*,int*,int)) memRbtreeIntegrityCheck,
     (const char*(*)(Btree*)) memRbtreeGetFilename,
     (int(*)(Btree*,Btree*)) memRbtreeCopyFile,
-
+    (struct Pager*(*)(Btree*)) memRbtreePager,
 #ifdef SQLITE_TEST
     (int(*)(Btree*,int,int)) memRbtreePageDump,
-    (struct Pager*(*)(Btree*)) memRbtreePager
 #endif
 };
 
index 4b5ed5613980acab55c85ca503636da7575d70e6..a089bfe625bee4bd8ee74fe78f86d0f4097fbda2 100644 (file)
@@ -1537,7 +1537,7 @@ void sqliteCreateIndex(
   if( pName && !db->init.busy ){
     Index *pISameName;    /* Another index with the same name */
     Table *pTSameName;    /* A table with same name as the index */
-    zName = sqliteStrNDup(pName->z, pName->n);
+    zName = sqliteTableNameFromToken(pName);
     if( zName==0 ) goto exit_create_index;
     if( (pISameName = sqliteFindIndex(db, zName, 0))!=0 ){
       sqliteErrorMsg(pParse, "index %s already exists", zName);
@@ -1557,7 +1557,7 @@ void sqliteCreateIndex(
     sqliteSetString(&zName, "(", pTab->zName, " autoindex ", zBuf, (char*)0);
     if( zName==0 ) goto exit_create_index;
   }else{
-    zName = sqliteStrNDup(pName->z, pName->n);
+    zName = sqliteTableNameFromToken(pName);
   }
 
   /* Check for authorization to create an index.
index d7382aefae4f9b657fa72c6e3bf9b22347b0f118..c7489ec078d9c5e8da0de0392699f7316d4df92e 100644 (file)
@@ -800,18 +800,20 @@ static void strftimeFunc(sqlite_func *context, int argc, const char **argv){
         case 'H':  sprintf(&z[j],"%02d",x.h); j+=2; break;
         case 'W': /* Fall thru */
         case 'j': {
-          int n;
+          int n;             /* Number of days since 1st day of year */
           DateTime y = x;
           y.validJD = 0;
           y.M = 1;
           y.D = 1;
           computeJD(&y);
-          n = x.rJD - y.rJD + 1;
+          n = x.rJD - y.rJD;
           if( zFmt[i]=='W' ){
-            sprintf(&z[j],"%02d",(n+6)/7);
+            int wd;   /* 0=Monday, 1=Tuesday, ... 6=Sunday */
+            wd = ((int)(x.rJD+0.5)) % 7;
+            sprintf(&z[j],"%02d",(n+7-wd)/7);
             j += 2;
           }else{
-            sprintf(&z[j],"%03d",n);
+            sprintf(&z[j],"%03d",n+1);
             j += 3;
           }
           break;
@@ -847,19 +849,18 @@ static void strftimeFunc(sqlite_func *context, int argc, const char **argv){
 ** external linkage.
 */
 void sqliteRegisterDateTimeFunctions(sqlite *db){
+#ifndef SQLITE_OMIT_DATETIME_FUNCS
   static struct {
      char *zName;
      int nArg;
      int dataType;
      void (*xFunc)(sqlite_func*,int,const char**);
   } aFuncs[] = {
-#ifndef SQLITE_OMIT_DATETIME_FUNCS
     { "julianday", -1, SQLITE_NUMERIC, juliandayFunc   },
     { "date",      -1, SQLITE_TEXT,    dateFunc        },
     { "time",      -1, SQLITE_TEXT,    timeFunc        },
     { "datetime",  -1, SQLITE_TEXT,    datetimeFunc    },
     { "strftime",  -1, SQLITE_TEXT,    strftimeFunc    },
-#endif
   };
   int i;
 
@@ -870,4 +871,5 @@ void sqliteRegisterDateTimeFunctions(sqlite *db){
       sqlite_function_type(db, aFuncs[i].zName, aFuncs[i].dataType);
     }
   }
+#endif
 }
index 44c0f6967a843142491ba9296f22b0b97737f3c4..86346fa5d9610bcf625a1bf269db8e4e2b1cd2df 100644 (file)
@@ -124,7 +124,7 @@ Expr *sqliteExprDup(Expr *p){
   if( pNew==0 ) return 0;
   memcpy(pNew, p, sizeof(*pNew));
   if( p->token.z!=0 ){
-    pNew->token.z = sqliteStrDup(p->token.z);
+    pNew->token.z = sqliteStrNDup(p->token.z, p->token.n);
     pNew->token.dyn = 1;
   }else{
     assert( pNew->token.z==0 );
@@ -155,7 +155,10 @@ ExprList *sqliteExprListDup(ExprList *p){
   if( pNew==0 ) return 0;
   pNew->nExpr = pNew->nAlloc = p->nExpr;
   pNew->a = pItem = sqliteMalloc( p->nExpr*sizeof(p->a[0]) );
-  if( pItem==0 ) return 0;  /* Leaks memory after a malloc failure */
+  if( pItem==0 ){
+    sqliteFree(pNew);
+    return 0;
+  }
   for(i=0; i<p->nExpr; i++, pItem++){
     Expr *pNewExpr, *pOldExpr;
     pItem->pExpr = pNewExpr = sqliteExprDup(pOldExpr = p->a[i].pExpr);
index d54f341472d65ca5e7100552e6f623c595241b98..8d6012eff7dccbbfe236a5c598be393536252007 100644 (file)
@@ -157,20 +157,20 @@ static void roundFunc(sqlite_func *context, int argc, const char **argv){
 ** Implementation of the upper() and lower() SQL functions.
 */
 static void upperFunc(sqlite_func *context, int argc, const char **argv){
-  char *z;
+  unsigned char *z;
   int i;
   if( argc<1 || argv[0]==0 ) return;
-  z = sqlite_set_result_string(context, argv[0], -1);
+  z = (unsigned char*)sqlite_set_result_string(context, argv[0], -1);
   if( z==0 ) return;
   for(i=0; z[i]; i++){
     if( islower(z[i]) ) z[i] = toupper(z[i]);
   }
 }
 static void lowerFunc(sqlite_func *context, int argc, const char **argv){
-  char *z;
+  unsigned char *z;
   int i;
   if( argc<1 || argv[0]==0 ) return;
-  z = sqlite_set_result_string(context, argv[0], -1);
+  z = (unsigned char*)sqlite_set_result_string(context, argv[0], -1);
   if( z==0 ) return;
   for(i=0; z[i]; i++){
     if( isupper(z[i]) ) z[i] = tolower(z[i]);
@@ -517,26 +517,28 @@ static void minmaxStep(sqlite_func *context, int argc, const char **argv){
   int mask;    /* 0 for min() or 0xffffffff for max() */
 
   assert( argc==2 );
+  if( argv[0]==0 ) return;  /* Ignore NULL values */
   if( argv[1][0]=='n' ){
     xCompare = sqliteCompare;
   }else{
     xCompare = strcmp;
   }
   mask = (int)sqlite_user_data(context);
+  assert( mask==0 || mask==-1 );
   p = sqlite_aggregate_context(context, sizeof(*p));
-  if( p==0 || argc<1 || argv[0]==0 ) return;
+  if( p==0 || argc<1 ) return;
   if( p->z==0 || (xCompare(argv[0],p->z)^mask)<0 ){
     int len;
-    if( !p->zBuf[0] ){
+    if( p->zBuf[0] ){
       sqliteFree(p->z);
     }
     len = strlen(argv[0]);
     if( len < sizeof(p->zBuf)-1 ){
       p->z = &p->zBuf[1];
-      p->zBuf[0] = 1;
+      p->zBuf[0] = 0;
     }else{
       p->z = sqliteMalloc( len+1 );
-      p->zBuf[0] = 0;
+      p->zBuf[0] = 1;
       if( p->z==0 ) return;
     }
     strcpy(p->z, argv[0]);
@@ -545,10 +547,10 @@ static void minmaxStep(sqlite_func *context, int argc, const char **argv){
 static void minMaxFinalize(sqlite_func *context){
   MinMaxCtx *p;
   p = sqlite_aggregate_context(context, sizeof(*p));
-  if( p && p->z ){
+  if( p && p->z && p->zBuf[0]<2 ){
     sqlite_set_result_string(context, p->z, strlen(p->z));
   }
-  if( p && !p->zBuf[0] ){
+  if( p && p->zBuf[0] ){
     sqliteFree(p->z);
   }
 }
@@ -621,7 +623,12 @@ void sqliteRegisterBuiltinFunctions(sqlite *db){
   int i;
 
   for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
-    void *pArg = aFuncs[i].argType==2 ? (void*)(-1) : db;
+    void *pArg;
+    switch( aFuncs[i].argType ){
+      case 0:  pArg = 0;           break;
+      case 1:  pArg = db;          break;
+      case 2:  pArg = (void*)(-1); break;
+    }
     sqlite_create_function(db, aFuncs[i].zName,
            aFuncs[i].nArg, aFuncs[i].xFunc, pArg);
     if( aFuncs[i].xFunc ){
@@ -629,7 +636,12 @@ void sqliteRegisterBuiltinFunctions(sqlite *db){
     }
   }
   for(i=0; i<sizeof(aAggs)/sizeof(aAggs[0]); i++){
-    void *pArg = aAggs[i].argType==2 ? (void*)(-1) : db;
+    void *pArg;
+    switch( aAggs[i].argType ){
+      case 0:  pArg = 0;           break;
+      case 1:  pArg = db;          break;
+      case 2:  pArg = (void*)(-1); break;
+    }
     sqlite_create_aggregate(db, aAggs[i].zName,
            aAggs[i].nArg, aAggs[i].xStep, aAggs[i].xFinalize, pArg);
     sqlite_function_type(db, aAggs[i].zName, aAggs[i].dataType);
index e6cc80f4507b1c1029b650bb4bc4a6cc7c2d2a29..c16300558ac644bceba4c3d830e20b7d94db4880 100644 (file)
@@ -189,10 +189,13 @@ static int sqliteInitOne(sqlite *db, int iDb, char **pzErrMsg){
   BtCursor *curMain;
   int size;
   Table *pTab;
-  char *azArg[6];
+  char const *azArg[6];
   char zDbNum[30];
   int meta[SQLITE_N_BTREE_META];
   InitData initData;
+  char const *zMasterSchema;
+  char const *zMasterName;
+  char *zSql = 0;
 
   /*
   ** The master database table has a structure like this
@@ -216,62 +219,38 @@ static int sqliteInitOne(sqlite *db, int iDb, char **pzErrMsg){
      ")"
   ;
 
-  /* The following SQL will read the schema from the master tables.
-  ** The first version works with SQLite file formats 2 or greater.
-  ** The second version is for format 1 files.
-  **
-  ** Beginning with file format 2, the rowid for new table entries
-  ** (including entries in sqlite_master) is an increasing integer.
-  ** So for file format 2 and later, we can play back sqlite_master
-  ** and all the CREATE statements will appear in the right order.
-  ** But with file format 1, table entries were random and so we
-  ** have to make sure the CREATE TABLEs occur before their corresponding
-  ** CREATE INDEXs.  (We don't have to deal with CREATE VIEW or
-  ** CREATE TRIGGER in file format 1 because those constructs did
-  ** not exist then.) 
+  assert( iDb>=0 && iDb<db->nDb );
+
+  /* zMasterSchema and zInitScript are set to point at the master schema
+  ** and initialisation script appropriate for the database being
+  ** initialised. zMasterName is the name of the master table.
   */
-  static char init_script[] = 
-     "SELECT type, name, rootpage, sql, 1 FROM sqlite_temp_master "
-     "UNION ALL "
-     "SELECT type, name, rootpage, sql, 0 FROM sqlite_master";
-  static char older_init_script[] = 
-     "SELECT type, name, rootpage, sql, 1 FROM sqlite_temp_master "
-     "UNION ALL "
-     "SELECT type, name, rootpage, sql, 0 FROM sqlite_master "
-     "WHERE type='table' "
-     "UNION ALL "
-     "SELECT type, name, rootpage, sql, 0 FROM sqlite_master "
-     "WHERE type='index'";
-
-
-  assert( iDb>=0 && iDb!=1 && iDb<db->nDb );
-
-  /* Construct the schema tables: sqlite_master and sqlite_temp_master
+  if( iDb==1 ){
+    zMasterSchema = temp_master_schema;
+    zMasterName = TEMP_MASTER_NAME;
+  }else{
+    zMasterSchema = master_schema;
+    zMasterName = MASTER_NAME;
+  }
+
+  /* Construct the schema table.
   */
   sqliteSafetyOff(db);
   azArg[0] = "table";
-  azArg[1] = MASTER_NAME;
+  azArg[1] = zMasterName;
   azArg[2] = "2";
-  azArg[3] = master_schema;
+  azArg[3] = zMasterSchema;
   sprintf(zDbNum, "%d", iDb);
   azArg[4] = zDbNum;
   azArg[5] = 0;
   initData.db = db;
   initData.pzErrMsg = pzErrMsg;
-  sqliteInitCallback(&initData, 5, azArg, 0);
-  pTab = sqliteFindTable(db, MASTER_NAME, "main");
+  sqliteInitCallback(&initData, 5, (char **)azArg, 0);
+  pTab = sqliteFindTable(db, zMasterName, db->aDb[iDb].zName);
   if( pTab ){
     pTab->readOnly = 1;
-  }
-  if( iDb==0 ){
-    azArg[1] = TEMP_MASTER_NAME;
-    azArg[3] = temp_master_schema;
-    azArg[4] = "1";
-    sqliteInitCallback(&initData, 5, azArg, 0);
-    pTab = sqliteFindTable(db, TEMP_MASTER_NAME, "temp");
-    if( pTab ){
-      pTab->readOnly = 1;
-    }
+  }else{
+    return SQLITE_NOMEM;
   }
   sqliteSafetyOn(db);
 
@@ -320,7 +299,7 @@ static int sqliteInitOne(sqlite *db, int iDb, char **pzErrMsg){
       sqliteSetString(pzErrMsg, "unsupported file format", (char*)0);
       return SQLITE_ERROR;
     }
-  }else if( db->file_format!=meta[2] || db->file_format<4 ){
+  }else if( iDb!=1 && (db->file_format!=meta[2] || db->file_format<4) ){
     assert( db->file_format>=4 );
     if( meta[2]==0 ){
       sqliteSetString(pzErrMsg, "cannot attach empty database: ",
@@ -340,18 +319,35 @@ static int sqliteInitOne(sqlite *db, int iDb, char **pzErrMsg){
   */
   assert( db->init.busy );
   sqliteSafetyOff(db);
-  if( iDb==0 ){
-    rc = sqlite_exec(db, 
-        db->file_format>=2 ? init_script : older_init_script,
-        sqliteInitCallback, &initData, 0);
+
+  /* The following SQL will read the schema from the master tables.
+  ** The first version works with SQLite file formats 2 or greater.
+  ** The second version is for format 1 files.
+  **
+  ** Beginning with file format 2, the rowid for new table entries
+  ** (including entries in sqlite_master) is an increasing integer.
+  ** So for file format 2 and later, we can play back sqlite_master
+  ** and all the CREATE statements will appear in the right order.
+  ** But with file format 1, table entries were random and so we
+  ** have to make sure the CREATE TABLEs occur before their corresponding
+  ** CREATE INDEXs.  (We don't have to deal with CREATE VIEW or
+  ** CREATE TRIGGER in file format 1 because those constructs did
+  ** not exist then.) 
+  */
+  if( db->file_format>=2 ){
+    sqliteSetString(&zSql, 
+        "SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"",
+       db->aDb[iDb].zName, "\".", zMasterName, (char*)0);
   }else{
-    char *zSql = 0;
     sqliteSetString(&zSql, 
-       "SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"",
-       db->aDb[iDb].zName, "\".sqlite_master", (char*)0);
-    rc = sqlite_exec(db, zSql, sqliteInitCallback, &initData, 0);
-    sqliteFree(zSql);
+        "SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"",
+       db->aDb[iDb].zName, "\".", zMasterName, 
+       " WHERE type IN ('table', 'index')"
+       " ORDER BY CASE type WHEN 'table' THEN 0 ELSE 1 END", (char*)0);
   }
+  rc = sqlite_exec(db, zSql, sqliteInitCallback, &initData, 0);
+
+  sqliteFree(zSql);
   sqliteSafetyOn(db);
   sqliteBtreeCloseCursor(curMain);
   if( sqlite_malloc_failed ){
@@ -361,9 +357,6 @@ static int sqliteInitOne(sqlite *db, int iDb, char **pzErrMsg){
   }
   if( rc==SQLITE_OK ){
     DbSetProperty(db, iDb, DB_SchemaLoaded);
-    if( iDb==0 ){
-      DbSetProperty(db, 1, DB_SchemaLoaded);
-    }
   }else{
     sqliteResetInternalSchema(db, iDb);
   }
@@ -391,13 +384,24 @@ int sqliteInit(sqlite *db, char **pzErrMsg){
   rc = SQLITE_OK;
   db->init.busy = 1;
   for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
-    if( DbHasProperty(db, i, DB_SchemaLoaded) ) continue;
-    assert( i!=1 );  /* Should have been initialized together with 0 */
+    if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue;
     rc = sqliteInitOne(db, i, pzErrMsg);
     if( rc ){
       sqliteResetInternalSchema(db, i);
     }
   }
+
+  /* Once all the other databases have been initialised, load the schema
+  ** for the TEMP database. This is loaded last, as the TEMP database
+  ** schema may contain references to objects in other databases.
+  */
+  if( rc==SQLITE_OK && db->nDb>1 && !DbHasProperty(db, 1, DB_SchemaLoaded) ){
+    rc = sqliteInitOne(db, 1, pzErrMsg);
+    if( rc ){
+      sqliteResetInternalSchema(db, 1);
+    }
+  }
+
   db->init.busy = 0;
   if( rc==SQLITE_OK ){
     db->flags |= SQLITE_Initialized;
index 0e2930c0ca84cf99c450d13ff2e4954f3b968bae..930d62440e7cccc776932d7cc5e00fc7cb2d07aa 100644 (file)
@@ -830,7 +830,7 @@ int sqliteOsTempFileName(char *zBuf){
     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
     "0123456789";
   int i, j;
-  char *zDir;
+  const char *zDir;
   char zTempPath[SQLITE_TEMPNAME_SIZE];
   if( sqlite_temp_directory==0 ){
     GetTempPath(SQLITE_TEMPNAME_SIZE-30, zTempPath);
@@ -1116,6 +1116,10 @@ int sqliteOsSeek(OsFile *id, off_t offset){
 #endif
 }
 
+#ifdef SQLITE_NOSYNC
+# define fsync(X) 0
+#endif
+
 /*
 ** Make sure all writes to a particular file are committed to disk.
 **
index 620578d76ee356a2a584c94d73f1ccf9bd1e65b7..f867d62af61a581f351e3b372019a18be19db351 100644 (file)
@@ -227,6 +227,7 @@ static int vxprintf(
   int nsd;                   /* Number of significant digits returned */
 #endif
 
+  func(arg,"",0);
   count = length = 0;
   bufpt = 0;
   for(; (c=(*fmt))!=0; ++fmt){
@@ -673,9 +674,11 @@ static void mout(void *arg, const char *zNewText, int nNewChar){
       }
     }
   }
-  if( pM->zText && nNewChar>0 ){
-    memcpy(&pM->zText[pM->nChar], zNewText, nNewChar);
-    pM->nChar += nNewChar;
+  if( pM->zText ){
+    if( nNewChar>0 ){
+      memcpy(&pM->zText[pM->nChar], zNewText, nNewChar);
+      pM->nChar += nNewChar;
+    }
     pM->zText[pM->nChar] = 0;
   }
 }
index 871f2e2c714c9904cc3b7394e8c78cfac657e439..c19c2bac86471c630b8ec733e5949f0efe3530d1 100644 (file)
@@ -364,6 +364,30 @@ void sqliteAddKeyType(Vdbe *v, ExprList *pEList){
   sqliteVdbeChangeP3(v, -1, zType, P3_DYNAMIC);
 }
 
+/*
+** Add code to implement the OFFSET and LIMIT
+*/
+static void codeLimiter(
+  Vdbe *v,          /* Generate code into this VM */
+  Select *p,        /* The SELECT statement being coded */
+  int iContinue,    /* Jump here to skip the current record */
+  int iBreak,       /* Jump here to end the loop */
+  int nPop          /* Number of times to pop stack when jumping */
+){
+  if( p->iOffset>=0 ){
+    int addr = sqliteVdbeCurrentAddr(v) + 2;
+    if( nPop>0 ) addr++;
+    sqliteVdbeAddOp(v, OP_MemIncr, p->iOffset, addr);
+    if( nPop>0 ){
+      sqliteVdbeAddOp(v, OP_Pop, nPop, 0);
+    }
+    sqliteVdbeAddOp(v, OP_Goto, 0, iContinue);
+  }
+  if( p->iLimit>=0 ){
+    sqliteVdbeAddOp(v, OP_MemIncr, p->iLimit, iBreak);
+  }
+}
+
 /*
 ** This routine generates the code for the inside of the inner loop
 ** of a SELECT.
@@ -388,6 +412,7 @@ static int selectInnerLoop(
 ){
   Vdbe *v = pParse->pVdbe;
   int i;
+  int hasDistinct;        /* True if the DISTINCT keyword is present */
 
   if( v==0 ) return 0;
   assert( pEList!=0 );
@@ -395,15 +420,9 @@ static int selectInnerLoop(
   /* If there was a LIMIT clause on the SELECT statement, then do the check
   ** to see if this row should be output.
   */
-  if( pOrderBy==0 ){
-    if( p->iOffset>=0 ){
-      int addr = sqliteVdbeCurrentAddr(v);
-      sqliteVdbeAddOp(v, OP_MemIncr, p->iOffset, addr+2);
-      sqliteVdbeAddOp(v, OP_Goto, 0, iContinue);
-    }
-    if( p->iLimit>=0 ){
-      sqliteVdbeAddOp(v, OP_MemIncr, p->iLimit, iBreak);
-    }
+  hasDistinct = distinct>=0 && pEList && pEList->nExpr>0;
+  if( pOrderBy==0 && !hasDistinct ){
+    codeLimiter(v, p, iContinue, iBreak, 0);
   }
 
   /* Pull the requested columns.
@@ -423,7 +442,7 @@ static int selectInnerLoop(
   ** and this row has been seen before, then do not make this row
   ** part of the result.
   */
-  if( distinct>=0 && pEList && pEList->nExpr>0 ){
+  if( hasDistinct ){
 #if NULL_ALWAYS_DISTINCT
     sqliteVdbeAddOp(v, OP_IsNull, -pEList->nExpr, sqliteVdbeCurrentAddr(v)+7);
 #endif
@@ -434,6 +453,9 @@ static int selectInnerLoop(
     sqliteVdbeAddOp(v, OP_Goto, 0, iContinue);
     sqliteVdbeAddOp(v, OP_String, 0, 0);
     sqliteVdbeAddOp(v, OP_PutStrKey, distinct, 0);
+    if( pOrderBy==0 ){
+      codeLimiter(v, p, iContinue, iBreak, nColumn);
+    }
   }
 
   switch( eDest ){
@@ -570,14 +592,7 @@ static void generateSortTail(
   if( eDest==SRT_Sorter ) return;
   sqliteVdbeAddOp(v, OP_Sort, 0, 0);
   addr = sqliteVdbeAddOp(v, OP_SortNext, 0, end1);
-  if( p->iOffset>=0 ){
-    sqliteVdbeAddOp(v, OP_MemIncr, p->iOffset, addr+4);
-    sqliteVdbeAddOp(v, OP_Pop, 1, 0);
-    sqliteVdbeAddOp(v, OP_Goto, 0, addr);
-  }
-  if( p->iLimit>=0 ){
-    sqliteVdbeAddOp(v, OP_MemIncr, p->iLimit, end2);
-  }
+  codeLimiter(v, p, addr, end2, 1);
   switch( eDest ){
     case SRT_Callback: {
       sqliteVdbeAddOp(v, OP_SortCallback, nColumn, 0);
@@ -810,8 +825,9 @@ Table *sqliteResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){
     }else{
       char zBuf[30];
       sprintf(zBuf, "column%d", i+1);
-      pTab->aCol[i].zName = sqliteStrDup(zBuf);
+      aCol[i].zName = sqliteStrDup(zBuf);
     }
+    sqliteDequote(aCol[i].zName);
   }
   pTab->iPKey = -1;
   return pTab;
@@ -943,11 +959,11 @@ static int fillInColumnList(Parse *pParse, Select *p){
         /* This expression is a "*" or a "TABLE.*" and needs to be
         ** expanded. */
         int tableSeen = 0;      /* Set to 1 when TABLE matches */
-        Token *pName;           /* text of name of TABLE */
+        char *zTName;           /* text of name of TABLE */
         if( pE->op==TK_DOT && pE->pLeft ){
-          pName = &pE->pLeft->token;
+          zTName = sqliteTableNameFromToken(&pE->pLeft->token);
         }else{
-          pName = 0;
+          zTName = 0;
         }
         for(i=0; i<pTabList->nSrc; i++){
           Table *pTab = pTabList->a[i].pTab;
@@ -955,9 +971,8 @@ static int fillInColumnList(Parse *pParse, Select *p){
           if( zTabName==0 || zTabName[0]==0 ){ 
             zTabName = pTab->zName;
           }
-          if( pName && (zTabName==0 || zTabName[0]==0 || 
-                 sqliteStrNICmp(pName->z, zTabName, pName->n)!=0 ||
-                 zTabName[pName->n]!=0) ){
+          if( zTName && (zTabName==0 || zTabName[0]==0 || 
+                 sqliteStrICmp(zTName, zTabName)!=0) ){
             continue;
           }
           tableSeen = 1;
@@ -1002,13 +1017,14 @@ static int fillInColumnList(Parse *pParse, Select *p){
           }
         }
         if( !tableSeen ){
-          if( pName ){
-            sqliteErrorMsg(pParse, "no such table: %T", pName);
+          if( zTName ){
+            sqliteErrorMsg(pParse, "no such table: %s", zTName);
           }else{
             sqliteErrorMsg(pParse, "no tables specified");
           }
           rc = 1;
         }
+        sqliteFree(zTName);
       }
     }
     sqliteExprListDelete(pEList);
@@ -1916,6 +1932,12 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){
   }else{
     sqliteVdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
     sqliteVdbeOp3(v, OP_OpenRead, base+1, pIdx->tnum, pIdx->zName, P3_STATIC);
+    if( seekOp==OP_Rewind ){
+      sqliteVdbeAddOp(v, OP_String, 0, 0);
+      sqliteVdbeAddOp(v, OP_MakeKey, 1, 0);
+      sqliteVdbeAddOp(v, OP_IncrKey, 0, 0);
+      seekOp = OP_MoveTo;
+    }
     sqliteVdbeAddOp(v, seekOp, base+1, 0);
     sqliteVdbeAddOp(v, OP_IdxRecno, base+1, 0);
     sqliteVdbeAddOp(v, OP_Close, base+1, 0);
index 11edb434890257da02f0768879a9516579710e69..a823f5b2e6fc190111407619b77f19c99047b3cf 100644 (file)
@@ -28,7 +28,11 @@ extern "C" {
 /*
 ** The version of the SQLite library.
 */
-#define SQLITE_VERSION         "--VERS--"
+#ifdef SQLITE_VERSION
+# undef SQLITE_VERSION
+#else
+# define SQLITE_VERSION         "--VERS--"
+#endif
 
 /*
 ** The version string is also compiled into the library so that a program
@@ -479,9 +483,23 @@ int sqlite_function_type(
   int datatype              /* The datatype for this function */
 );
 #define SQLITE_NUMERIC     (-1)
-#define SQLITE_TEXT        (-2)
+/* #define SQLITE_TEXT     (-2)  // See below */
 #define SQLITE_ARGS        (-3)
 
+/*
+** SQLite version 3 defines SQLITE_TEXT differently.  To allow both
+** version 2 and version 3 to be included, undefine them both if a
+** conflict is seen.  Define SQLITE2_TEXT to be the version 2 value.
+*/
+#ifdef SQLITE_TEXT
+# undef SQLITE_TEXT
+#else
+# define SQLITE_TEXT     (-2)
+#endif
+#define SQLITE2_TEXT     (-2)
+
+
+
 /*
 ** The user function implementations call one of the following four routines
 ** in order to return their results.  The first parameter to each of these
index 996eab06335e5e13a7e2a12b44ff6b87bb90984e..0239fcd657761fdfa8876d004a5bc9cadda6412e 100644 (file)
@@ -28,7 +28,7 @@ extern "C" {
 /*
 ** The version of the SQLite library.
 */
-#define SQLITE_VERSION         "2.8.11"
+#define SQLITE_VERSION         "2.8.16"
 
 /*
 ** The version string is also compiled into the library so that a program
index 57e3ab6e36aeac147578acfdcd3cdb63bfb0be12..02236c2dc985aa11eea7703b9ffcfb5a78cf20db 100644 (file)
 #ifndef UINT16_TYPE
 # define UINT16_TYPE unsigned short int
 #endif
+#ifndef INT16_TYPE
+# define INT16_TYPE short int
+#endif
 #ifndef UINT8_TYPE
 # define UINT8_TYPE unsigned char
 #endif
 #endif
 typedef UINT32_TYPE u32;           /* 4-byte unsigned integer */
 typedef UINT16_TYPE u16;           /* 2-byte unsigned integer */
+typedef INT16_TYPE i16;            /* 2-byte signed integer */
 typedef UINT8_TYPE u8;             /* 1-byte unsigned integer */
 typedef UINT8_TYPE i8;             /* 1-byte signed integer */
 typedef INTPTR_TYPE ptr;           /* Big enough to hold a pointer */
@@ -762,8 +766,8 @@ struct IdList {
 ** now be identified by a database name, a dot, then the table name: ID.ID.
 */
 struct SrcList {
-  u16 nSrc;        /* Number of tables or subqueries in the FROM clause */
-  u16 nAlloc;      /* Number of entries allocated in a[] below */
+  i16 nSrc;        /* Number of tables or subqueries in the FROM clause */
+  i16 nAlloc;      /* Number of entries allocated in a[] below */
   struct SrcList_item {
     char *zDatabase;  /* Name of database holding this table */
     char *zName;      /* Name of the table */
index 21d7b15057ae43fefcd73c3e7a678d17834ac66f..ed399fde21d6e819eaee3550a699de258764469f 100644 (file)
@@ -504,14 +504,14 @@ int sqliteStrICmp(const char *zLeft, const char *zRight){
   a = (unsigned char *)zLeft;
   b = (unsigned char *)zRight;
   while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
-  return *a - *b;
+  return UpperToLower[*a] - UpperToLower[*b];
 }
 int sqliteStrNICmp(const char *zLeft, const char *zRight, int N){
   register unsigned char *a, *b;
   a = (unsigned char *)zLeft;
   b = (unsigned char *)zRight;
   while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
-  return N<0 ? 0 : *a - *b;
+  return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b];
 }
 
 /*
index 06cc6b0a4cb5a0a1c680330992b29fb2878e8a61..a3fb196124c762d6e98ae6ea89a7c01d3fd88000 100644 (file)
@@ -163,24 +163,6 @@ static int vacuumCallback1(void *pArg, int argc, char **argv, char **NotUsed){
   return rc;
 }
 
-/*
-** This callback is used to transfer PRAGMA settings from one database
-** to the other.  The value in argv[0] should be passed to a pragma
-** identified by ((vacuumStruct*)pArg)->zPragma.
-*/
-static int vacuumCallback3(void *pArg, int argc, char **argv, char **NotUsed){
-  vacuumStruct *p = (vacuumStruct*)pArg;
-  char zBuf[200];
-  assert( argc==1 );
-  if( argv==0 ) return 0;
-  assert( argv[0]!=0 );
-  assert( strlen(p->zPragma)<100 );
-  assert( strlen(argv[0])<30 );
-  sprintf(zBuf,"PRAGMA %s=%s;", p->zPragma, argv[0]);
-  p->rc = execsql(p->pzErrMsg, p->dbNew, zBuf);
-  return p->rc;
-}
-
 /*
 ** Generate a random name of 20 character in length.
 */
@@ -226,14 +208,6 @@ int sqliteRunVacuum(char **pzErrMsg, sqlite *db){
   char *zErrMsg;          /* Error message */
   vacuumStruct sVac;      /* Information passed to callbacks */
 
-  /* These are all of the pragmas that need to be transferred over
-  ** to the new database */
-  static const char *zPragma[] = {
-     "default_synchronous",
-     "default_cache_size",
-     /* "default_temp_store", */
-  };
-
   if( db->flags & SQLITE_InTrans ){
     sqliteSetString(pzErrMsg, "cannot VACUUM from within a transaction", 
        (char*)0);
@@ -283,13 +257,6 @@ int sqliteRunVacuum(char **pzErrMsg, sqlite *db){
   sVac.dbOld = db;
   sVac.dbNew = dbNew;
   sVac.pzErrMsg = pzErrMsg;
-  for(i=0; rc==SQLITE_OK && i<sizeof(zPragma)/sizeof(zPragma[0]); i++){
-    char zBuf[200];
-    assert( strlen(zPragma[i])<100 );
-    sprintf(zBuf, "PRAGMA %s;", zPragma[i]);
-    sVac.zPragma = zPragma[i];
-    rc = sqlite_exec(db, zBuf, vacuumCallback3, &sVac, &zErrMsg);
-  }
   if( rc==SQLITE_OK ){
     rc = sqlite_exec(db, 
       "SELECT type, name, sql FROM sqlite_master "
@@ -299,6 +266,17 @@ int sqliteRunVacuum(char **pzErrMsg, sqlite *db){
       "WHERE sql NOT NULL AND type=='view'",
       vacuumCallback1, &sVac, &zErrMsg);
   }
+  if( rc==SQLITE_OK ){
+    int meta1[SQLITE_N_BTREE_META];
+    int meta2[SQLITE_N_BTREE_META];
+    sqliteBtreeGetMeta(db->aDb[0].pBt, meta1);
+    sqliteBtreeGetMeta(dbNew->aDb[0].pBt, meta2);
+    meta2[1] = meta1[1]+1;
+    meta2[3] = meta1[3];
+    meta2[4] = meta1[4];
+    meta2[6] = meta1[6];
+    rc = sqliteBtreeUpdateMeta(dbNew->aDb[0].pBt, meta2);
+  }
   if( rc==SQLITE_OK ){
     rc = sqliteBtreeCopyFile(db->aDb[0].pBt, dbNew->aDb[0].pBt);
     sqlite_exec(db, "COMMIT", 0, 0, 0);
index 09332560df2b6d7244b6fec5b35c5972afc6aeef..7ea05c9acd2d28ab9cdbf08e26e28ee6c0d47b0f 100644 (file)
@@ -4545,6 +4545,10 @@ case OP_AggGet: {
     pTos->flags &= ~(MEM_Dyn|MEM_Static|MEM_Short);
     pTos->flags |= MEM_Ephem;
   }
+  if( pTos->flags & MEM_AggCtx ){
+    Release(pTos);
+    pTos->flags = MEM_Null;
+  }
   break;
 }
 
@@ -4695,8 +4699,9 @@ case OP_SetNext: {
       break;
     }
   }else{
-    assert( pSet->prev );
-    pSet->prev = sqliteHashNext(pSet->prev);
+    if( pSet->prev ){
+      pSet->prev = sqliteHashNext(pSet->prev);
+    }
     if( pSet->prev==0 ){
       break;
     }else{
index a3a31a2e84189bd099abaf78de4a9ce4eb502a0a..cffeccbed7736b4be210796a15cb35c176117bf7 100644 (file)
@@ -46,7 +46,7 @@ struct ExprInfo {
 typedef struct ExprMaskSet ExprMaskSet;
 struct ExprMaskSet {
   int n;          /* Number of assigned cursor values */
-  int ix[32];     /* Cursor assigned to each bit */
+  int ix[31];     /* Cursor assigned to each bit */
 };
 
 /*
@@ -123,7 +123,9 @@ static int exprTableUsage(ExprMaskSet *pMaskSet, Expr *p){
   unsigned int mask = 0;
   if( p==0 ) return 0;
   if( p->op==TK_COLUMN ){
-    return getMask(pMaskSet, p->iTable);
+    mask = getMask(pMaskSet, p->iTable);
+    if( mask==0 ) mask = -1;
+    return mask;
   }
   if( p->pRight ){
     mask = exprTableUsage(pMaskSet, p->pRight);
@@ -269,6 +271,35 @@ static Index *findSortingIndex(
   return pMatch;
 }
 
+/*
+** Disable a term in the WHERE clause.  Except, do not disable the term
+** if it controls a LEFT OUTER JOIN and it did not originate in the ON
+** or USING clause of that join.
+**
+** Consider the term t2.z='ok' in the following queries:
+**
+**   (1)  SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x WHERE t2.z='ok'
+**   (2)  SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x AND t2.z='ok'
+**   (3)  SELECT * FROM t1, t2 WHERE t1.a=t2.x AND t2.z='ok'
+**
+** The t2.z='ok' is disabled in the in (2) because it did not originate
+** in the ON clause.  The term is disabled in (3) because it is not part
+** of a LEFT OUTER JOIN.  In (1), the term is not disabled.
+**
+** Disabling a term causes that term to not be tested in the inner loop
+** of the join.  Disabling is an optimization.  We would get the correct
+** results if nothing were ever disabled, but joins might run a little
+** slower.  The trick is to disable as much as we can without disabling
+** too much.  If we disabled in (1), we'd get the wrong answer.
+** See ticket #813.
+*/
+static void disableTerm(WhereLevel *pLevel, Expr **ppExpr){
+  Expr *pExpr = *ppExpr;
+  if( pLevel->iLeftJoin==0 || ExprHasProperty(pExpr, EP_FromJoin) ){
+    *ppExpr = 0;
+  }
+}
+
 /*
 ** Generate the beginning of the loop used for WHERE clause processing.
 ** The return value is a pointer to an (opaque) structure that contains
@@ -736,7 +767,7 @@ WhereInfo *sqliteWhereBegin(
       }else{
         sqliteExprCode(pParse, aExpr[k].p->pLeft);
       }
-      aExpr[k].p = 0;
+      disableTerm(pLevel, &aExpr[k].p);
       cont = pLevel->cont = sqliteVdbeMakeLabel(v);
       sqliteVdbeAddOp(v, OP_MustBeInt, 1, brk);
       haveKey = 0;
@@ -760,7 +791,7 @@ WhereInfo *sqliteWhereBegin(
           ){
             if( pX->op==TK_EQ ){
               sqliteExprCode(pParse, pX->pRight);
-              aExpr[k].p = 0;
+              disableTerm(pLevel, &aExpr[k].p);
               break;
             }
             if( pX->op==TK_IN && nColumn==1 ){
@@ -777,7 +808,7 @@ WhereInfo *sqliteWhereBegin(
                 pLevel->inOp = OP_Next;
                 pLevel->inP1 = pX->iTable;
               }
-              aExpr[k].p = 0;
+              disableTerm(pLevel, &aExpr[k].p);
               break;
             }
           }
@@ -787,7 +818,7 @@ WhereInfo *sqliteWhereBegin(
              && aExpr[k].p->pRight->iColumn==pIdx->aiColumn[j]
           ){
             sqliteExprCode(pParse, aExpr[k].p->pLeft);
-            aExpr[k].p = 0;
+            disableTerm(pLevel, &aExpr[k].p);
             break;
           }
         }
@@ -854,7 +885,7 @@ WhereInfo *sqliteWhereBegin(
         sqliteVdbeAddOp(v, OP_ForceInt,
           aExpr[k].p->op==TK_LT || aExpr[k].p->op==TK_GT, brk);
         sqliteVdbeAddOp(v, OP_MoveTo, iCur, brk);
-        aExpr[k].p = 0;
+        disableTerm(pLevel, &aExpr[k].p);
       }else{
         sqliteVdbeAddOp(v, OP_Rewind, iCur, brk);
       }
@@ -876,7 +907,7 @@ WhereInfo *sqliteWhereBegin(
         }else{
           testOp = OP_Gt;
         }
-        aExpr[k].p = 0;
+        disableTerm(pLevel, &aExpr[k].p);
       }
       start = sqliteVdbeCurrentAddr(v);
       pLevel->op = OP_Next;
@@ -931,7 +962,7 @@ WhereInfo *sqliteWhereBegin(
              && aExpr[k].p->pLeft->iColumn==pIdx->aiColumn[j]
           ){
             sqliteExprCode(pParse, aExpr[k].p->pRight);
-            aExpr[k].p = 0;
+            disableTerm(pLevel, &aExpr[k].p);
             break;
           }
           if( aExpr[k].idxRight==iCur
@@ -940,7 +971,7 @@ WhereInfo *sqliteWhereBegin(
              && aExpr[k].p->pRight->iColumn==pIdx->aiColumn[j]
           ){
             sqliteExprCode(pParse, aExpr[k].p->pLeft);
-            aExpr[k].p = 0;
+            disableTerm(pLevel, &aExpr[k].p);
             break;
           }
         }
@@ -977,7 +1008,7 @@ WhereInfo *sqliteWhereBegin(
           ){
             sqliteExprCode(pParse, pExpr->pRight);
             leFlag = pExpr->op==TK_LE;
-            aExpr[k].p = 0;
+            disableTerm(pLevel, &aExpr[k].p);
             break;
           }
           if( aExpr[k].idxRight==iCur
@@ -987,7 +1018,7 @@ WhereInfo *sqliteWhereBegin(
           ){
             sqliteExprCode(pParse, pExpr->pLeft);
             leFlag = pExpr->op==TK_GE;
-            aExpr[k].p = 0;
+            disableTerm(pLevel, &aExpr[k].p);
             break;
           }
         }
@@ -1036,7 +1067,7 @@ WhereInfo *sqliteWhereBegin(
           ){
             sqliteExprCode(pParse, pExpr->pRight);
             geFlag = pExpr->op==TK_GE;
-            aExpr[k].p = 0;
+            disableTerm(pLevel, &aExpr[k].p);
             break;
           }
           if( aExpr[k].idxRight==iCur
@@ -1046,7 +1077,7 @@ WhereInfo *sqliteWhereBegin(
           ){
             sqliteExprCode(pParse, pExpr->pLeft);
             geFlag = pExpr->op==TK_LE;
-            aExpr[k].p = 0;
+            disableTerm(pLevel, &aExpr[k].p);
             break;
           }
         }