diff options
Diffstat (limited to 'ext/sqlite/libsqlite/src')
| -rw-r--r-- | ext/sqlite/libsqlite/src/btree_rb.c | 33 | ||||
| -rw-r--r-- | ext/sqlite/libsqlite/src/build.c | 4 | ||||
| -rw-r--r-- | ext/sqlite/libsqlite/src/date.c | 14 | ||||
| -rw-r--r-- | ext/sqlite/libsqlite/src/expr.c | 7 | ||||
| -rw-r--r-- | ext/sqlite/libsqlite/src/func.c | 36 | ||||
| -rw-r--r-- | ext/sqlite/libsqlite/src/main.c | 124 | ||||
| -rw-r--r-- | ext/sqlite/libsqlite/src/os.c | 6 | ||||
| -rw-r--r-- | ext/sqlite/libsqlite/src/printf.c | 9 | ||||
| -rw-r--r-- | ext/sqlite/libsqlite/src/select.c | 76 | ||||
| -rw-r--r-- | ext/sqlite/libsqlite/src/sqlite.h.in | 22 | ||||
| -rw-r--r-- | ext/sqlite/libsqlite/src/sqlite.w32.h | 2 | ||||
| -rw-r--r-- | ext/sqlite/libsqlite/src/sqliteInt.h | 8 | ||||
| -rw-r--r-- | ext/sqlite/libsqlite/src/util.c | 4 | ||||
| -rw-r--r-- | ext/sqlite/libsqlite/src/vacuum.c | 44 | ||||
| -rw-r--r-- | ext/sqlite/libsqlite/src/vdbe.c | 9 | ||||
| -rw-r--r-- | ext/sqlite/libsqlite/src/where.c | 59 | 
16 files changed, 269 insertions, 188 deletions
| diff --git a/ext/sqlite/libsqlite/src/btree_rb.c b/ext/sqlite/libsqlite/src/btree_rb.c index 49009be830..d932ab4a97 100644 --- a/ext/sqlite/libsqlite/src/btree_rb.c +++ b/ext/sqlite/libsqlite/src/btree_rb.c @@ -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  }; diff --git a/ext/sqlite/libsqlite/src/build.c b/ext/sqlite/libsqlite/src/build.c index 4b5ed56139..a089bfe625 100644 --- a/ext/sqlite/libsqlite/src/build.c +++ b/ext/sqlite/libsqlite/src/build.c @@ -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. diff --git a/ext/sqlite/libsqlite/src/date.c b/ext/sqlite/libsqlite/src/date.c index d7382aefae..c7489ec078 100644 --- a/ext/sqlite/libsqlite/src/date.c +++ b/ext/sqlite/libsqlite/src/date.c @@ -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  } diff --git a/ext/sqlite/libsqlite/src/expr.c b/ext/sqlite/libsqlite/src/expr.c index 44c0f6967a..86346fa5d9 100644 --- a/ext/sqlite/libsqlite/src/expr.c +++ b/ext/sqlite/libsqlite/src/expr.c @@ -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); diff --git a/ext/sqlite/libsqlite/src/func.c b/ext/sqlite/libsqlite/src/func.c index d54f341472..8d6012eff7 100644 --- a/ext/sqlite/libsqlite/src/func.c +++ b/ext/sqlite/libsqlite/src/func.c @@ -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); diff --git a/ext/sqlite/libsqlite/src/main.c b/ext/sqlite/libsqlite/src/main.c index e6cc80f450..c16300558a 100644 --- a/ext/sqlite/libsqlite/src/main.c +++ b/ext/sqlite/libsqlite/src/main.c @@ -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; diff --git a/ext/sqlite/libsqlite/src/os.c b/ext/sqlite/libsqlite/src/os.c index 0e2930c0ca..930d62440e 100644 --- a/ext/sqlite/libsqlite/src/os.c +++ b/ext/sqlite/libsqlite/src/os.c @@ -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.  ** diff --git a/ext/sqlite/libsqlite/src/printf.c b/ext/sqlite/libsqlite/src/printf.c index 620578d76e..f867d62af6 100644 --- a/ext/sqlite/libsqlite/src/printf.c +++ b/ext/sqlite/libsqlite/src/printf.c @@ -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;    }  } diff --git a/ext/sqlite/libsqlite/src/select.c b/ext/sqlite/libsqlite/src/select.c index 871f2e2c71..c19c2bac86 100644 --- a/ext/sqlite/libsqlite/src/select.c +++ b/ext/sqlite/libsqlite/src/select.c @@ -365,6 +365,30 @@ void sqliteAddKeyType(Vdbe *v, ExprList *pEList){  }  /* +** 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); diff --git a/ext/sqlite/libsqlite/src/sqlite.h.in b/ext/sqlite/libsqlite/src/sqlite.h.in index 11edb43489..a823f5b2e6 100644 --- a/ext/sqlite/libsqlite/src/sqlite.h.in +++ b/ext/sqlite/libsqlite/src/sqlite.h.in @@ -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,10 +483,24 @@ 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  ** routines is a copy of the first argument to xFunc() or xFinialize(). diff --git a/ext/sqlite/libsqlite/src/sqlite.w32.h b/ext/sqlite/libsqlite/src/sqlite.w32.h index 996eab0633..0239fcd657 100644 --- a/ext/sqlite/libsqlite/src/sqlite.w32.h +++ b/ext/sqlite/libsqlite/src/sqlite.w32.h @@ -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 diff --git a/ext/sqlite/libsqlite/src/sqliteInt.h b/ext/sqlite/libsqlite/src/sqliteInt.h index 57e3ab6e36..02236c2dc9 100644 --- a/ext/sqlite/libsqlite/src/sqliteInt.h +++ b/ext/sqlite/libsqlite/src/sqliteInt.h @@ -102,6 +102,9 @@  #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 @@ -117,6 +120,7 @@  #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 */ diff --git a/ext/sqlite/libsqlite/src/util.c b/ext/sqlite/libsqlite/src/util.c index 21d7b15057..ed399fde21 100644 --- a/ext/sqlite/libsqlite/src/util.c +++ b/ext/sqlite/libsqlite/src/util.c @@ -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];  }  /* diff --git a/ext/sqlite/libsqlite/src/vacuum.c b/ext/sqlite/libsqlite/src/vacuum.c index 06cc6b0a4c..a3fb196124 100644 --- a/ext/sqlite/libsqlite/src/vacuum.c +++ b/ext/sqlite/libsqlite/src/vacuum.c @@ -164,24 +164,6 @@ static int vacuumCallback1(void *pArg, int argc, char **argv, char **NotUsed){  }  /* -** 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.  */  static void randomName(unsigned char *zBuf){ @@ -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 " @@ -300,6 +267,17 @@ int sqliteRunVacuum(char **pzErrMsg, sqlite *db){        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);      sqliteResetInternalSchema(db, 0); diff --git a/ext/sqlite/libsqlite/src/vdbe.c b/ext/sqlite/libsqlite/src/vdbe.c index 09332560df..7ea05c9acd 100644 --- a/ext/sqlite/libsqlite/src/vdbe.c +++ b/ext/sqlite/libsqlite/src/vdbe.c @@ -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{ diff --git a/ext/sqlite/libsqlite/src/where.c b/ext/sqlite/libsqlite/src/where.c index a3a31a2e84..cffeccbed7 100644 --- a/ext/sqlite/libsqlite/src/where.c +++ b/ext/sqlite/libsqlite/src/where.c @@ -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); @@ -270,6 +272,35 @@ static Index *findSortingIndex(  }  /* +** 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  ** information needed to terminate the loop.  Later, the calling routine @@ -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;            }          } | 
