1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

Pull in all the latest changes from trunk.

FossilOrigin-Name: af3ca4c6e557e6bc92584586b5a97d9be41b0b82
This commit is contained in:
drh
2013-07-09 13:05:49 +00:00
57 changed files with 1986 additions and 346 deletions

View File

@@ -3335,8 +3335,11 @@ int sqlite3Fts1Init(sqlite3 *db){
} }
#if !SQLITE_CORE #if !SQLITE_CORE
int sqlite3_extension_init(sqlite3 *db, char **pzErrMsg, #ifdef _WIN32
const sqlite3_api_routines *pApi){ __declspec(dllexport)
#endif
int sqlite3_fts1_init(sqlite3 *db, char **pzErrMsg,
const sqlite3_api_routines *pApi){
SQLITE_EXTENSION_INIT2(pApi) SQLITE_EXTENSION_INIT2(pApi)
return sqlite3Fts1Init(db); return sqlite3Fts1Init(db);
} }

View File

@@ -852,8 +852,14 @@ static void fulltext_vtab_destroy(fulltext_vtab *v){
** argv[3] - tokenizer name (optional, a sensible default is provided) ** argv[3] - tokenizer name (optional, a sensible default is provided)
** argv[4..] - passed to tokenizer (optional based on tokenizer) ** argv[4..] - passed to tokenizer (optional based on tokenizer)
**/ **/
static int fulltextConnect(sqlite3 *db, void *pAux, int argc, char **argv, static int fulltextConnect(
sqlite3_vtab **ppVTab){ sqlite3 *db,
void *pAux,
int argc,
const char * const *argv,
sqlite3_vtab **ppVTab,
char **pzErr
){
int rc; int rc;
fulltext_vtab *v; fulltext_vtab *v;
sqlite3_tokenizer_module *m = NULL; sqlite3_tokenizer_module *m = NULL;
@@ -898,8 +904,14 @@ static int fulltextConnect(sqlite3 *db, void *pAux, int argc, char **argv,
return SQLITE_OK; return SQLITE_OK;
} }
static int fulltextCreate(sqlite3 *db, void *pAux, int argc, char **argv, static int fulltextCreate(
sqlite3_vtab **ppVTab){ sqlite3 *db,
void *pAux,
int argc,
const char * const *argv,
sqlite3_vtab **ppVTab,
char **pzErr
){
int rc; int rc;
assert( argc>=3 ); assert( argc>=3 );
@@ -934,7 +946,7 @@ static int fulltextCreate(sqlite3 *db, void *pAux, int argc, char **argv,
"create index %_index on %_term(term, first)"); "create index %_index on %_term(term, first)");
if( rc!=SQLITE_OK ) return rc; if( rc!=SQLITE_OK ) return rc;
return fulltextConnect(db, pAux, argc, argv, ppVTab); return fulltextConnect(db, pAux, argc, argv, ppVTab, pzErr);
} }
/* Decide how to handle an SQL query. /* Decide how to handle an SQL query.
@@ -1488,8 +1500,11 @@ int fulltext_init(sqlite3 *db){
} }
#if !SQLITE_CORE #if !SQLITE_CORE
int sqlite3_extension_init(sqlite3 *db, char **pzErrMsg, #ifdef _WIN32
const sqlite3_api_routines *pApi){ __declspec(dllexport)
#endif
int sqlite3_fulltext_init(sqlite3 *db, char **pzErrMsg,
const sqlite3_api_routines *pApi){
SQLITE_EXTENSION_INIT2(pApi) SQLITE_EXTENSION_INIT2(pApi)
return fulltext_init(db); return fulltext_init(db);
} }

View File

@@ -6844,7 +6844,10 @@ int sqlite3Fts2Init(sqlite3 *db){
} }
#if !SQLITE_CORE #if !SQLITE_CORE
int sqlite3_extension_init( #ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_fts2_init(
sqlite3 *db, sqlite3 *db,
char **pzErrMsg, char **pzErrMsg,
const sqlite3_api_routines *pApi const sqlite3_api_routines *pApi

View File

@@ -30,6 +30,8 @@
#include <string.h> #include <string.h>
#include "sqlite3.h" #include "sqlite3.h"
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT3
#include "fts2_hash.h" #include "fts2_hash.h"
/* /*

View File

@@ -30,6 +30,9 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "sqlite3.h"
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT3
#include "fts2_tokenizer.h" #include "fts2_tokenizer.h"
/* /*

View File

@@ -28,7 +28,7 @@
#include "sqlite3.h" #include "sqlite3.h"
#include "sqlite3ext.h" #include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1 SQLITE_EXTENSION_INIT3
#include "fts2_hash.h" #include "fts2_hash.h"
#include "fts2_tokenizer.h" #include "fts2_tokenizer.h"

View File

@@ -30,6 +30,9 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "sqlite3.h"
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT3
#include "fts2_tokenizer.h" #include "fts2_tokenizer.h"
typedef struct simple_tokenizer { typedef struct simple_tokenizer {

View File

@@ -1095,7 +1095,7 @@ static int fts3InitVtab(
nByte = sizeof(const char *) * (argc-2); nByte = sizeof(const char *) * (argc-2);
aCol = (const char **)sqlite3_malloc(nByte); aCol = (const char **)sqlite3_malloc(nByte);
if( aCol ){ if( aCol ){
memset(aCol, 0, nByte); memset((void*)aCol, 0, nByte);
azNotindexed = (char **)sqlite3_malloc(nByte); azNotindexed = (char **)sqlite3_malloc(nByte);
} }
if( azNotindexed ){ if( azNotindexed ){
@@ -1346,7 +1346,7 @@ static int fts3InitVtab(
/* Fill in the abNotindexed array */ /* Fill in the abNotindexed array */
for(iCol=0; iCol<nCol; iCol++){ for(iCol=0; iCol<nCol; iCol++){
int n = strlen(p->azColumn[iCol]); int n = (int)strlen(p->azColumn[iCol]);
for(i=0; i<nNotindexed; i++){ for(i=0; i<nNotindexed; i++){
char *zNot = azNotindexed[i]; char *zNot = azNotindexed[i];
if( zNot && 0==sqlite3_strnicmp(p->azColumn[iCol], zNot, n) ){ if( zNot && 0==sqlite3_strnicmp(p->azColumn[iCol], zNot, n) ){
@@ -5376,7 +5376,10 @@ int sqlite3Fts3Corrupt(){
/* /*
** Initialize API pointer table, if required. ** Initialize API pointer table, if required.
*/ */
int sqlite3_extension_init( #ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_fts3_init(
sqlite3 *db, sqlite3 *db,
char **pzErrMsg, char **pzErrMsg,
const sqlite3_api_routines *pApi const sqlite3_api_routines *pApi

View File

@@ -32,7 +32,7 @@
/* If not building as part of the core, include sqlite3ext.h. */ /* If not building as part of the core, include sqlite3ext.h. */
#ifndef SQLITE_CORE #ifndef SQLITE_CORE
# include "sqlite3ext.h" # include "sqlite3ext.h"
extern const sqlite3_api_routines *sqlite3_api; SQLITE_EXTENSION_INIT3
#endif #endif
#include "sqlite3.h" #include "sqlite3.h"

View File

@@ -488,7 +488,10 @@ int sqlite3IcuInit(sqlite3 *db){
} }
#if !SQLITE_CORE #if !SQLITE_CORE
int sqlite3_extension_init( #ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_icu_init(
sqlite3 *db, sqlite3 *db,
char **pzErrMsg, char **pzErrMsg,
const sqlite3_api_routines *pApi const sqlite3_api_routines *pApi

View File

@@ -18,11 +18,11 @@
** **
** In the first form, the value X should be a floating-point number. ** In the first form, the value X should be a floating-point number.
** The function will return a string of the form 'ieee754(Y,Z)' where ** The function will return a string of the form 'ieee754(Y,Z)' where
** Y and Z are integers such that X==Y*pow(w.0,Z). ** Y and Z are integers such that X==Y*pow(2,Z).
** **
** In the second form, Y and Z are integers which are the mantissa and ** In the second form, Y and Z are integers which are the mantissa and
** base-2 exponent of a new floating point number. The function returns ** base-2 exponent of a new floating point number. The function returns
** a floating-point value equal to Y*pow(2.0,Z). ** a floating-point value equal to Y*pow(2,Z).
** **
** Examples: ** Examples:
** **

View File

@@ -10,12 +10,22 @@
** **
****************************************************************************** ******************************************************************************
** **
** This file contains code to implement the next_char(A,T,F,W) SQL function. ** This file contains code to implement the next_char(A,T,F,W,C) SQL function.
** **
** The next_char(A,T,F,H) function finds all valid "next" characters for ** The next_char(A,T,F,W,C) function finds all valid "next" characters for
** string A given the vocabulary in T.F. The T.F field should be indexed. ** string A given the vocabulary in T.F. If the W value exists and is a
** If the W value exists and is a non-empty string, then it is an SQL ** non-empty string, then it is an SQL expression that limits the entries
** expression that limits the entries in T.F that will be considered. ** in T.F that will be considered. If C exists and is a non-empty string,
** then it is the name of the collating sequence to use for comparison. If
**
** Only the first three arguments are required. If the C parameter is
** omitted or is NULL or is an empty string, then the default collating
** sequence of T.F is used for comparision. If the W parameter is omitted
** or is NULL or is an empty string, then no filtering of the output is
** done.
**
** The T.F column should be indexed using collation C or else this routine
** will be quite slow.
** **
** For example, suppose an application has a dictionary like this: ** For example, suppose an application has a dictionary like this:
** **
@@ -184,6 +194,9 @@ static void nextCharFunc(
const unsigned char *zTable = sqlite3_value_text(argv[1]); const unsigned char *zTable = sqlite3_value_text(argv[1]);
const unsigned char *zField = sqlite3_value_text(argv[2]); const unsigned char *zField = sqlite3_value_text(argv[2]);
const unsigned char *zWhere; const unsigned char *zWhere;
const unsigned char *zCollName;
char *zWhereClause = 0;
char *zColl = 0;
char *zSql; char *zSql;
int rc; int rc;
@@ -192,25 +205,41 @@ static void nextCharFunc(
c.zPrefix = sqlite3_value_text(argv[0]); c.zPrefix = sqlite3_value_text(argv[0]);
c.nPrefix = sqlite3_value_bytes(argv[0]); c.nPrefix = sqlite3_value_bytes(argv[0]);
if( zTable==0 || zField==0 || c.zPrefix==0 ) return; if( zTable==0 || zField==0 || c.zPrefix==0 ) return;
if( argc<4 if( argc>=4
|| (zWhere = sqlite3_value_text(argv[3]))==0 && (zWhere = sqlite3_value_text(argv[3]))!=0
|| zWhere[0]==0 && zWhere[0]!=0
){ ){
zSql = sqlite3_mprintf( zWhereClause = sqlite3_mprintf("AND (%s)", zWhere);
"SELECT \"%w\" FROM \"%w\"" if( zWhereClause==0 ){
" WHERE \"%w\">=(?1 || ?2)" sqlite3_result_error_nomem(context);
" AND \"%w\"<=(?1 || char(1114111))" /* 1114111 == 0x10ffff */ return;
" ORDER BY 1 ASC LIMIT 1", }
zField, zTable, zField, zField);
}else{ }else{
zSql = sqlite3_mprintf( zWhereClause = "";
"SELECT \"%w\" FROM \"%w\""
" WHERE \"%w\">=(?1 || ?2)"
" AND \"%w\"<=(?1 || char(1114111))" /* 1114111 == 0x10ffff */
" AND (%s)"
" ORDER BY 1 ASC LIMIT 1",
zField, zTable, zField, zField, zWhere);
} }
if( argc>=5
&& (zCollName = sqlite3_value_text(argv[4]))!=0
&& zCollName[0]!=0
){
zColl = sqlite3_mprintf("collate \"%w\"", zCollName);
if( zColl==0 ){
sqlite3_result_error_nomem(context);
if( zWhereClause[0] ) sqlite3_free(zWhereClause);
return;
}
}else{
zColl = "";
}
zSql = sqlite3_mprintf(
"SELECT \"%w\" FROM \"%w\""
" WHERE \"%w\">=(?1 || ?2) %s"
" AND \"%w\"<=(?1 || char(1114111)) %s" /* 1114111 == 0x10ffff */
" %s"
" ORDER BY 1 %s ASC LIMIT 1",
zField, zTable, zField, zColl, zField, zColl, zWhereClause, zColl
);
if( zWhereClause[0] ) sqlite3_free(zWhereClause);
if( zColl[0] ) sqlite3_free(zColl);
if( zSql==0 ){ if( zSql==0 ){
sqlite3_result_error_nomem(context); sqlite3_result_error_nomem(context);
return; return;
@@ -261,5 +290,9 @@ int sqlite3_nextchar_init(
rc = sqlite3_create_function(db, "next_char", 4, SQLITE_UTF8, 0, rc = sqlite3_create_function(db, "next_char", 4, SQLITE_UTF8, 0,
nextCharFunc, 0, 0); nextCharFunc, 0, 0);
} }
if( rc==SQLITE_OK ){
rc = sqlite3_create_function(db, "next_char", 5, SQLITE_UTF8, 0,
nextCharFunc, 0, 0);
}
return rc; return rc;
} }

View File

@@ -190,7 +190,7 @@ static void percentFinal(sqlite3_context *pCtx){
if( p->nUsed ){ if( p->nUsed ){
qsort(p->a, p->nUsed, sizeof(double), doubleCmp); qsort(p->a, p->nUsed, sizeof(double), doubleCmp);
ix = (p->rPct-1.0)*(p->nUsed-1)*0.01; ix = (p->rPct-1.0)*(p->nUsed-1)*0.01;
i1 = ix; i1 = (unsigned)ix;
i2 = ix==(double)i1 || i1==p->nUsed-1 ? i1 : i1+1; i2 = ix==(double)i1 || i1==p->nUsed-1 ? i1 : i1+1;
v1 = p->a[i1]; v1 = p->a[i1];
v2 = p->a[i2]; v2 = p->a[i2];

547
ext/misc/vtshim.c Normal file
View File

@@ -0,0 +1,547 @@
/*
** 2013-06-12
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
**
** A shim that sits between the SQLite virtual table interface and
** runtimes with garbage collector based memory management.
*/
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
#include <assert.h>
#include <string.h>
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Forward references */
typedef struct vtshim_aux vtshim_aux;
typedef struct vtshim_vtab vtshim_vtab;
typedef struct vtshim_cursor vtshim_cursor;
/* The vtshim_aux argument is the auxiliary parameter that is passed
** into sqlite3_create_module_v2().
*/
struct vtshim_aux {
void *pChildAux; /* pAux for child virtual tables */
void (*xChildDestroy)(void*); /* Destructor for pChildAux */
sqlite3_module *pMod; /* Methods for child virtual tables */
sqlite3 *db; /* The database to which we are attached */
char *zName; /* Name of the module */
int bDisposed; /* True if disposed */
vtshim_vtab *pAllVtab; /* List of all vtshim_vtab objects */
sqlite3_module sSelf; /* Methods used by this shim */
};
/* A vtshim virtual table object */
struct vtshim_vtab {
sqlite3_vtab base; /* Base class - must be first */
sqlite3_vtab *pChild; /* Child virtual table */
vtshim_aux *pAux; /* Pointer to vtshim_aux object */
vtshim_cursor *pAllCur; /* List of all cursors */
vtshim_vtab **ppPrev; /* Previous on list */
vtshim_vtab *pNext; /* Next on list */
};
/* A vtshim cursor object */
struct vtshim_cursor {
sqlite3_vtab_cursor base; /* Base class - must be first */
sqlite3_vtab_cursor *pChild; /* Cursor generated by the managed subclass */
vtshim_cursor **ppPrev; /* Previous on list of all cursors */
vtshim_cursor *pNext; /* Next on list of all cursors */
};
/* Macro used to copy the child vtable error message to outer vtable */
#define VTSHIM_COPY_ERRMSG() \
do { \
sqlite3_free(pVtab->base.zErrMsg); \
pVtab->base.zErrMsg = sqlite3_mprintf("%s", pVtab->pChild->zErrMsg); \
} while (0)
/* Methods for the vtshim module */
static int vtshimCreate(
sqlite3 *db,
void *ppAux,
int argc,
const char *const*argv,
sqlite3_vtab **ppVtab,
char **pzErr
){
vtshim_aux *pAux = (vtshim_aux*)ppAux;
vtshim_vtab *pNew;
int rc;
assert( db==pAux->db );
if( pAux->bDisposed ){
if( pzErr ){
*pzErr = sqlite3_mprintf("virtual table was disposed: \"%s\"",
pAux->zName);
}
return SQLITE_ERROR;
}
pNew = sqlite3_malloc( sizeof(*pNew) );
*ppVtab = (sqlite3_vtab*)pNew;
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(*pNew));
rc = pAux->pMod->xCreate(db, pAux->pChildAux, argc, argv,
&pNew->pChild, pzErr);
if( rc ){
sqlite3_free(pNew);
*ppVtab = 0;
}
pNew->pAux = pAux;
pNew->ppPrev = &pAux->pAllVtab;
pNew->pNext = pAux->pAllVtab;
if( pAux->pAllVtab ) pAux->pAllVtab->ppPrev = &pNew->pNext;
pAux->pAllVtab = pNew;
return rc;
}
static int vtshimConnect(
sqlite3 *db,
void *ppAux,
int argc,
const char *const*argv,
sqlite3_vtab **ppVtab,
char **pzErr
){
vtshim_aux *pAux = (vtshim_aux*)ppAux;
vtshim_vtab *pNew;
int rc;
assert( db==pAux->db );
if( pAux->bDisposed ){
if( pzErr ){
*pzErr = sqlite3_mprintf("virtual table was disposed: \"%s\"",
pAux->zName);
}
return SQLITE_ERROR;
}
pNew = sqlite3_malloc( sizeof(*pNew) );
*ppVtab = (sqlite3_vtab*)pNew;
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(*pNew));
rc = pAux->pMod->xConnect(db, pAux->pChildAux, argc, argv,
&pNew->pChild, pzErr);
if( rc ){
sqlite3_free(pNew);
*ppVtab = 0;
}
pNew->pAux = pAux;
pNew->ppPrev = &pAux->pAllVtab;
pNew->pNext = pAux->pAllVtab;
if( pAux->pAllVtab ) pAux->pAllVtab->ppPrev = &pNew->pNext;
pAux->pAllVtab = pNew;
return rc;
}
static int vtshimBestIndex(
sqlite3_vtab *pBase,
sqlite3_index_info *pIdxInfo
){
vtshim_vtab *pVtab = (vtshim_vtab*)pBase;
vtshim_aux *pAux = pVtab->pAux;
int rc;
if( pAux->bDisposed ) return SQLITE_ERROR;
rc = pAux->pMod->xBestIndex(pVtab->pChild, pIdxInfo);
if( rc!=SQLITE_OK ){
VTSHIM_COPY_ERRMSG();
}
return rc;
}
static int vtshimDisconnect(sqlite3_vtab *pBase){
vtshim_vtab *pVtab = (vtshim_vtab*)pBase;
vtshim_aux *pAux = pVtab->pAux;
int rc = SQLITE_OK;
if( !pAux->bDisposed ){
rc = pAux->pMod->xDisconnect(pVtab->pChild);
}
if( pVtab->pNext ) pVtab->pNext->ppPrev = pVtab->ppPrev;
*pVtab->ppPrev = pVtab->pNext;
sqlite3_free(pVtab);
return rc;
}
static int vtshimDestroy(sqlite3_vtab *pBase){
vtshim_vtab *pVtab = (vtshim_vtab*)pBase;
vtshim_aux *pAux = pVtab->pAux;
int rc = SQLITE_OK;
if( !pAux->bDisposed ){
rc = pAux->pMod->xDestroy(pVtab->pChild);
}
if( pVtab->pNext ) pVtab->pNext->ppPrev = pVtab->ppPrev;
*pVtab->ppPrev = pVtab->pNext;
sqlite3_free(pVtab);
return rc;
}
static int vtshimOpen(sqlite3_vtab *pBase, sqlite3_vtab_cursor **ppCursor){
vtshim_vtab *pVtab = (vtshim_vtab*)pBase;
vtshim_aux *pAux = pVtab->pAux;
vtshim_cursor *pCur;
int rc;
*ppCursor = 0;
if( pAux->bDisposed ) return SQLITE_ERROR;
pCur = sqlite3_malloc( sizeof(*pCur) );
if( pCur==0 ) return SQLITE_NOMEM;
memset(pCur, 0, sizeof(*pCur));
rc = pAux->pMod->xOpen(pVtab->pChild, &pCur->pChild);
if( rc ){
sqlite3_free(pCur);
VTSHIM_COPY_ERRMSG();
return rc;
}
pCur->pChild->pVtab = pVtab->pChild;
*ppCursor = &pCur->base;
pCur->ppPrev = &pVtab->pAllCur;
if( pVtab->pAllCur ) pVtab->pAllCur->ppPrev = &pCur->pNext;
pCur->pNext = pVtab->pAllCur;
pVtab->pAllCur = pCur;
return SQLITE_OK;
}
static int vtshimClose(sqlite3_vtab_cursor *pX){
vtshim_cursor *pCur = (vtshim_cursor*)pX;
vtshim_vtab *pVtab = (vtshim_vtab*)pCur->base.pVtab;
vtshim_aux *pAux = pVtab->pAux;
int rc = SQLITE_OK;
if( !pAux->bDisposed ){
rc = pAux->pMod->xClose(pCur->pChild);
if( rc!=SQLITE_OK ){
VTSHIM_COPY_ERRMSG();
}
}
if( pCur->pNext ) pCur->pNext->ppPrev = pCur->ppPrev;
*pCur->ppPrev = pCur->pNext;
sqlite3_free(pCur);
return rc;
}
static int vtshimFilter(
sqlite3_vtab_cursor *pX,
int idxNum,
const char *idxStr,
int argc,
sqlite3_value **argv
){
vtshim_cursor *pCur = (vtshim_cursor*)pX;
vtshim_vtab *pVtab = (vtshim_vtab*)pCur->base.pVtab;
vtshim_aux *pAux = pVtab->pAux;
int rc;
if( pAux->bDisposed ) return SQLITE_ERROR;
rc = pAux->pMod->xFilter(pCur->pChild, idxNum, idxStr, argc, argv);
if( rc!=SQLITE_OK ){
VTSHIM_COPY_ERRMSG();
}
return rc;
}
static int vtshimNext(sqlite3_vtab_cursor *pX){
vtshim_cursor *pCur = (vtshim_cursor*)pX;
vtshim_vtab *pVtab = (vtshim_vtab*)pCur->base.pVtab;
vtshim_aux *pAux = pVtab->pAux;
int rc;
if( pAux->bDisposed ) return SQLITE_ERROR;
rc = pAux->pMod->xNext(pCur->pChild);
if( rc!=SQLITE_OK ){
VTSHIM_COPY_ERRMSG();
}
return rc;
}
static int vtshimEof(sqlite3_vtab_cursor *pX){
vtshim_cursor *pCur = (vtshim_cursor*)pX;
vtshim_vtab *pVtab = (vtshim_vtab*)pCur->base.pVtab;
vtshim_aux *pAux = pVtab->pAux;
int rc;
if( pAux->bDisposed ) return 1;
rc = pAux->pMod->xEof(pCur->pChild);
VTSHIM_COPY_ERRMSG();
return rc;
}
static int vtshimColumn(sqlite3_vtab_cursor *pX, sqlite3_context *ctx, int i){
vtshim_cursor *pCur = (vtshim_cursor*)pX;
vtshim_vtab *pVtab = (vtshim_vtab*)pCur->base.pVtab;
vtshim_aux *pAux = pVtab->pAux;
int rc;
if( pAux->bDisposed ) return SQLITE_ERROR;
rc = pAux->pMod->xColumn(pCur->pChild, ctx, i);
if( rc!=SQLITE_OK ){
VTSHIM_COPY_ERRMSG();
}
return rc;
}
static int vtshimRowid(sqlite3_vtab_cursor *pX, sqlite3_int64 *pRowid){
vtshim_cursor *pCur = (vtshim_cursor*)pX;
vtshim_vtab *pVtab = (vtshim_vtab*)pCur->base.pVtab;
vtshim_aux *pAux = pVtab->pAux;
int rc;
if( pAux->bDisposed ) return SQLITE_ERROR;
rc = pAux->pMod->xRowid(pCur->pChild, pRowid);
if( rc!=SQLITE_OK ){
VTSHIM_COPY_ERRMSG();
}
return rc;
}
static int vtshimUpdate(
sqlite3_vtab *pBase,
int argc,
sqlite3_value **argv,
sqlite3_int64 *pRowid
){
vtshim_vtab *pVtab = (vtshim_vtab*)pBase;
vtshim_aux *pAux = pVtab->pAux;
int rc;
if( pAux->bDisposed ) return SQLITE_ERROR;
rc = pAux->pMod->xUpdate(pVtab->pChild, argc, argv, pRowid);
if( rc!=SQLITE_OK ){
VTSHIM_COPY_ERRMSG();
}
return rc;
}
static int vtshimBegin(sqlite3_vtab *pBase){
vtshim_vtab *pVtab = (vtshim_vtab*)pBase;
vtshim_aux *pAux = pVtab->pAux;
int rc;
if( pAux->bDisposed ) return SQLITE_ERROR;
rc = pAux->pMod->xBegin(pVtab->pChild);
if( rc!=SQLITE_OK ){
VTSHIM_COPY_ERRMSG();
}
return rc;
}
static int vtshimSync(sqlite3_vtab *pBase){
vtshim_vtab *pVtab = (vtshim_vtab*)pBase;
vtshim_aux *pAux = pVtab->pAux;
int rc;
if( pAux->bDisposed ) return SQLITE_ERROR;
rc = pAux->pMod->xSync(pVtab->pChild);
if( rc!=SQLITE_OK ){
VTSHIM_COPY_ERRMSG();
}
return rc;
}
static int vtshimCommit(sqlite3_vtab *pBase){
vtshim_vtab *pVtab = (vtshim_vtab*)pBase;
vtshim_aux *pAux = pVtab->pAux;
int rc;
if( pAux->bDisposed ) return SQLITE_ERROR;
rc = pAux->pMod->xCommit(pVtab->pChild);
if( rc!=SQLITE_OK ){
VTSHIM_COPY_ERRMSG();
}
return rc;
}
static int vtshimRollback(sqlite3_vtab *pBase){
vtshim_vtab *pVtab = (vtshim_vtab*)pBase;
vtshim_aux *pAux = pVtab->pAux;
int rc;
if( pAux->bDisposed ) return SQLITE_ERROR;
rc = pAux->pMod->xRollback(pVtab->pChild);
if( rc!=SQLITE_OK ){
VTSHIM_COPY_ERRMSG();
}
return rc;
}
static int vtshimFindFunction(
sqlite3_vtab *pBase,
int nArg,
const char *zName,
void (**pxFunc)(sqlite3_context*,int,sqlite3_value**),
void **ppArg
){
vtshim_vtab *pVtab = (vtshim_vtab*)pBase;
vtshim_aux *pAux = pVtab->pAux;
int rc;
if( pAux->bDisposed ) return 0;
rc = pAux->pMod->xFindFunction(pVtab->pChild, nArg, zName, pxFunc, ppArg);
VTSHIM_COPY_ERRMSG();
return rc;
}
static int vtshimRename(sqlite3_vtab *pBase, const char *zNewName){
vtshim_vtab *pVtab = (vtshim_vtab*)pBase;
vtshim_aux *pAux = pVtab->pAux;
int rc;
if( pAux->bDisposed ) return SQLITE_ERROR;
rc = pAux->pMod->xRename(pVtab->pChild, zNewName);
if( rc!=SQLITE_OK ){
VTSHIM_COPY_ERRMSG();
}
return rc;
}
static int vtshimSavepoint(sqlite3_vtab *pBase, int n){
vtshim_vtab *pVtab = (vtshim_vtab*)pBase;
vtshim_aux *pAux = pVtab->pAux;
int rc;
if( pAux->bDisposed ) return SQLITE_ERROR;
rc = pAux->pMod->xSavepoint(pVtab->pChild, n);
if( rc!=SQLITE_OK ){
VTSHIM_COPY_ERRMSG();
}
return rc;
}
static int vtshimRelease(sqlite3_vtab *pBase, int n){
vtshim_vtab *pVtab = (vtshim_vtab*)pBase;
vtshim_aux *pAux = pVtab->pAux;
int rc;
if( pAux->bDisposed ) return SQLITE_ERROR;
rc = pAux->pMod->xRelease(pVtab->pChild, n);
if( rc!=SQLITE_OK ){
VTSHIM_COPY_ERRMSG();
}
return rc;
}
static int vtshimRollbackTo(sqlite3_vtab *pBase, int n){
vtshim_vtab *pVtab = (vtshim_vtab*)pBase;
vtshim_aux *pAux = pVtab->pAux;
int rc;
if( pAux->bDisposed ) return SQLITE_ERROR;
rc = pAux->pMod->xRollbackTo(pVtab->pChild, n);
if( rc!=SQLITE_OK ){
VTSHIM_COPY_ERRMSG();
}
return rc;
}
/* The destructor function for a disposible module */
static void vtshimAuxDestructor(void *pXAux){
vtshim_aux *pAux = (vtshim_aux*)pXAux;
assert( pAux->pAllVtab==0 );
if( !pAux->bDisposed && pAux->xChildDestroy ){
pAux->xChildDestroy(pAux->pChildAux);
}
sqlite3_free(pAux->zName);
sqlite3_free(pAux->pMod);
sqlite3_free(pAux);
}
static int vtshimCopyModule(
const sqlite3_module *pMod, /* Source module to be copied */
sqlite3_module **ppMod /* Destination for copied module */
){
sqlite3_module *p;
if( !pMod || !ppMod ) return SQLITE_ERROR;
p = sqlite3_malloc( sizeof(*p) );
if( p==0 ) return SQLITE_NOMEM;
memcpy(p, pMod, sizeof(*p));
*ppMod = p;
return SQLITE_OK;
}
#ifdef _WIN32
__declspec(dllexport)
#endif
void *sqlite3_create_disposable_module(
sqlite3 *db, /* SQLite connection to register module with */
const char *zName, /* Name of the module */
const sqlite3_module *p, /* Methods for the module */
void *pClientData, /* Client data for xCreate/xConnect */
void(*xDestroy)(void*) /* Module destructor function */
){
vtshim_aux *pAux;
sqlite3_module *pMod;
int rc;
pAux = sqlite3_malloc( sizeof(*pAux) );
if( pAux==0 ){
if( xDestroy ) xDestroy(pClientData);
return 0;
}
rc = vtshimCopyModule(p, &pMod);
if( rc!=SQLITE_OK ){
sqlite3_free(pAux);
return 0;
}
pAux->pChildAux = pClientData;
pAux->xChildDestroy = xDestroy;
pAux->pMod = pMod;
pAux->db = db;
pAux->zName = sqlite3_mprintf("%s", zName);
pAux->bDisposed = 0;
pAux->pAllVtab = 0;
pAux->sSelf.iVersion = p->iVersion<=2 ? p->iVersion : 2;
pAux->sSelf.xCreate = p->xCreate ? vtshimCreate : 0;
pAux->sSelf.xConnect = p->xConnect ? vtshimConnect : 0;
pAux->sSelf.xBestIndex = p->xBestIndex ? vtshimBestIndex : 0;
pAux->sSelf.xDisconnect = p->xDisconnect ? vtshimDisconnect : 0;
pAux->sSelf.xDestroy = p->xDestroy ? vtshimDestroy : 0;
pAux->sSelf.xOpen = p->xOpen ? vtshimOpen : 0;
pAux->sSelf.xClose = p->xClose ? vtshimClose : 0;
pAux->sSelf.xFilter = p->xFilter ? vtshimFilter : 0;
pAux->sSelf.xNext = p->xNext ? vtshimNext : 0;
pAux->sSelf.xEof = p->xEof ? vtshimEof : 0;
pAux->sSelf.xColumn = p->xColumn ? vtshimColumn : 0;
pAux->sSelf.xRowid = p->xRowid ? vtshimRowid : 0;
pAux->sSelf.xUpdate = p->xUpdate ? vtshimUpdate : 0;
pAux->sSelf.xBegin = p->xBegin ? vtshimBegin : 0;
pAux->sSelf.xSync = p->xSync ? vtshimSync : 0;
pAux->sSelf.xCommit = p->xCommit ? vtshimCommit : 0;
pAux->sSelf.xRollback = p->xRollback ? vtshimRollback : 0;
pAux->sSelf.xFindFunction = p->xFindFunction ? vtshimFindFunction : 0;
pAux->sSelf.xRename = p->xRename ? vtshimRename : 0;
if( p->iVersion>=2 ){
pAux->sSelf.xSavepoint = p->xSavepoint ? vtshimSavepoint : 0;
pAux->sSelf.xRelease = p->xRelease ? vtshimRelease : 0;
pAux->sSelf.xRollbackTo = p->xRollbackTo ? vtshimRollbackTo : 0;
}else{
pAux->sSelf.xSavepoint = 0;
pAux->sSelf.xRelease = 0;
pAux->sSelf.xRollbackTo = 0;
}
rc = sqlite3_create_module_v2(db, zName, &pAux->sSelf,
pAux, vtshimAuxDestructor);
return rc==SQLITE_OK ? (void*)pAux : 0;
}
#ifdef _WIN32
__declspec(dllexport)
#endif
void sqlite3_dispose_module(void *pX){
vtshim_aux *pAux = (vtshim_aux*)pX;
if( !pAux->bDisposed ){
vtshim_vtab *pVtab;
vtshim_cursor *pCur;
for(pVtab=pAux->pAllVtab; pVtab; pVtab=pVtab->pNext){
for(pCur=pVtab->pAllCur; pCur; pCur=pCur->pNext){
pAux->pMod->xClose(pCur->pChild);
}
pAux->pMod->xDisconnect(pVtab->pChild);
}
pAux->bDisposed = 1;
if( pAux->xChildDestroy ) pAux->xChildDestroy(pAux->pChildAux);
}
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_vtshim_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
SQLITE_EXTENSION_INIT2(pApi);
return SQLITE_OK;
}

View File

@@ -3350,7 +3350,10 @@ int sqlite3_rtree_geometry_callback(
} }
#if !SQLITE_CORE #if !SQLITE_CORE
int sqlite3_extension_init( #ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_rtree_init(
sqlite3 *db, sqlite3 *db,
char **pzErrMsg, char **pzErrMsg,
const sqlite3_api_routines *pApi const sqlite3_api_routines *pApi

118
manifest
View File

@@ -1,5 +1,5 @@
C Fix\sa\sbug\spreventing\ssome\sFK\sconstraint\schecking\sfrom\sbeing\sdeferred\suntil\sthe\send\sof\schangeset\sapplication. C Pull\sin\sall\sthe\slatest\schanges\sfrom\strunk.
D 2013-07-04T15:22:53.953 D 2013-07-09T13:05:49.248
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in aff38bc64c582dd147f18739532198372587b0f0 F Makefile.in aff38bc64c582dd147f18739532198372587b0f0
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -51,36 +51,36 @@ F ext/async/sqlite3async.h f489b080af7e72aec0e1ee6f1d98ab6cf2e4dcef
F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e
F ext/fts1/ft_hash.c 3927bd880e65329bdc6f506555b228b28924921b F ext/fts1/ft_hash.c 3927bd880e65329bdc6f506555b228b28924921b
F ext/fts1/ft_hash.h 06df7bba40dadd19597aa400a875dbc2fed705ea F ext/fts1/ft_hash.h 06df7bba40dadd19597aa400a875dbc2fed705ea
F ext/fts1/fts1.c 3e7b253e61aab0bb1fea808c7a0ce36c19432acc F ext/fts1/fts1.c f7739dc37500a613cc0dab8fc04d1b5577d02998
F ext/fts1/fts1.h 6060b8f62c1d925ea8356cb1a6598073eb9159a6 F ext/fts1/fts1.h 6060b8f62c1d925ea8356cb1a6598073eb9159a6
F ext/fts1/fts1_hash.c 3196cee866edbebb1c0521e21672e6d599965114 F ext/fts1/fts1_hash.c 3196cee866edbebb1c0521e21672e6d599965114
F ext/fts1/fts1_hash.h e7f0d761353996a8175eda351104acfde23afcb0 F ext/fts1/fts1_hash.h e7f0d761353996a8175eda351104acfde23afcb0
F ext/fts1/fts1_porter.c b1c7304b8988ba3f764a147cdd32043b4913ea7b F ext/fts1/fts1_porter.c b1c7304b8988ba3f764a147cdd32043b4913ea7b
F ext/fts1/fts1_tokenizer.h fdea722c38a9f82ed921642981234f666e47919c F ext/fts1/fts1_tokenizer.h fdea722c38a9f82ed921642981234f666e47919c
F ext/fts1/fts1_tokenizer1.c fd00d1fe4dc30dfc5c64cba695ce34f4af20d2fa F ext/fts1/fts1_tokenizer1.c fd00d1fe4dc30dfc5c64cba695ce34f4af20d2fa
F ext/fts1/fulltext.c d935e600d87bc86b7d64f55c7520ea41d6034c5c F ext/fts1/fulltext.c 37698e1909584f6d8ea67d1485e3ad39dbf42d19
F ext/fts1/fulltext.h 08525a47852d1d62a0be81d3fc3fe2d23b094efd F ext/fts1/fulltext.h 08525a47852d1d62a0be81d3fc3fe2d23b094efd
F ext/fts1/simple_tokenizer.c 1844d72f7194c3fd3d7e4173053911bf0661b70d F ext/fts1/simple_tokenizer.c 1844d72f7194c3fd3d7e4173053911bf0661b70d
F ext/fts1/tokenizer.h 0c53421b832366d20d720d21ea3e1f6e66a36ef9 F ext/fts1/tokenizer.h 0c53421b832366d20d720d21ea3e1f6e66a36ef9
F ext/fts2/README.tokenizers 21e3684ea5a095b55d70f6878b4ce6af5932dfb7 F ext/fts2/README.tokenizers 21e3684ea5a095b55d70f6878b4ce6af5932dfb7
F ext/fts2/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d F ext/fts2/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
F ext/fts2/fts2.c b48cc0bb657c0a421f4067b79aa0354bd16a046d F ext/fts2/fts2.c 72c816a9ae448049fbbe8f18a85698765fc7956c
F ext/fts2/fts2.h da5f76c65163301d1068a971fd32f4119e3c95fa F ext/fts2/fts2.h da5f76c65163301d1068a971fd32f4119e3c95fa
F ext/fts2/fts2_hash.c 2689e42e1107ea67207f725cf69cf8972d00cf93 F ext/fts2/fts2_hash.c 011a1d32de45bb1b519a1fd0048e857d6a843558
F ext/fts2/fts2_hash.h 1824b99dfd8d0225facbdb26a2c87289b2e7dcf8 F ext/fts2/fts2_hash.h 1824b99dfd8d0225facbdb26a2c87289b2e7dcf8
F ext/fts2/fts2_icu.c 51c5cd3c04954badd329fa738c95fcdb717b5188 F ext/fts2/fts2_icu.c 51c5cd3c04954badd329fa738c95fcdb717b5188
F ext/fts2/fts2_porter.c 747056987951f743e955c8479f1df21a565720fe F ext/fts2/fts2_porter.c 2cd4a507bf3c3085fe66f59b0f2a325f65aaacf5
F ext/fts2/fts2_tokenizer.c a86d08c9634fabfa237c8f379008de2e11248d36 F ext/fts2/fts2_tokenizer.c 3dbe8058e97afb55fff3ea844120ce3208b114cc
F ext/fts2/fts2_tokenizer.h 27a1a99ca2d615cf7e142839b8d79e8751b4529e F ext/fts2/fts2_tokenizer.h 27a1a99ca2d615cf7e142839b8d79e8751b4529e
F ext/fts2/fts2_tokenizer1.c 0123d21078e053bd98fd6186c5c6dc6d67969f2e F ext/fts2/fts2_tokenizer1.c 07e223eecb483d448313b5f1553a4f299a7fb7a1
F ext/fts2/mkfts2amal.tcl 974d5d438cb3f7c4a652639262f82418c1e4cff0 F ext/fts2/mkfts2amal.tcl 974d5d438cb3f7c4a652639262f82418c1e4cff0
F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51 F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314 F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
F ext/fts3/fts3.c 6dbb5c424144465782d5bf0d23be89907c972454 F ext/fts3/fts3.c 0d6311cd433ea30c9e941b93bfeac2f9e6937980
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
F ext/fts3/fts3Int.h a50cd231e906da818f00f0a81845bbf7bbeba002 F ext/fts3/fts3Int.h c7a451661c2d9b2440b2008c3f63ce06f13181d6
F ext/fts3/fts3_aux.c b02632f6dd0e375ce97870206d914ea6d8df5ccd F ext/fts3/fts3_aux.c b02632f6dd0e375ce97870206d914ea6d8df5ccd
F ext/fts3/fts3_expr.c f8eb1046063ba342c7114eba175cabb31c4a64e7 F ext/fts3/fts3_expr.c f8eb1046063ba342c7114eba175cabb31c4a64e7
F ext/fts3/fts3_hash.c 8dd2d06b66c72c628c2732555a32bc0943114914 F ext/fts3/fts3_hash.c 8dd2d06b66c72c628c2732555a32bc0943114914
@@ -104,20 +104,21 @@ F ext/fts3/unicode/CaseFolding.txt 8c678ca52ecc95e16bc7afc2dbf6fc9ffa05db8c
F ext/fts3/unicode/UnicodeData.txt cd07314edb62d49fde34debdaf92fa2aa69011e7 F ext/fts3/unicode/UnicodeData.txt cd07314edb62d49fde34debdaf92fa2aa69011e7
F ext/fts3/unicode/mkunicode.tcl dc6f268eb526710e2c6e496c372471d773d0c368 F ext/fts3/unicode/mkunicode.tcl dc6f268eb526710e2c6e496c372471d773d0c368
F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43 F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43
F ext/icu/icu.c 7538f98eab2854cf17fa5f7797bffa6c76e3863b F ext/icu/icu.c d415ccf984defeb9df2c0e1afcfaa2f6dc05eacb
F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37
F ext/misc/amatch.c eae8454cd9dcb287b2a3ec2e65a865a4ac5f0d06 F ext/misc/amatch.c eae8454cd9dcb287b2a3ec2e65a865a4ac5f0d06
F ext/misc/closure.c 997c20ddf35f85ab399f4a02a557a9baa822ec32 F ext/misc/closure.c 997c20ddf35f85ab399f4a02a557a9baa822ec32
F ext/misc/fuzzer.c 136533c53cfce0957f0b48fa11dba27e21c5c01d F ext/misc/fuzzer.c 136533c53cfce0957f0b48fa11dba27e21c5c01d
F ext/misc/ieee754.c 2565ce373d842977efe0922dc50b8a41b3289556 F ext/misc/ieee754.c b0362167289170627659e84173f5d2e8fee8566e
F ext/misc/nextchar.c 1131e2b36116ffc6fe6b2e3464bfdace27978b1e F ext/misc/nextchar.c 80ba262d23238efcfcb3d72d71aa4513098e26a6
F ext/misc/percentile.c 4fb5e46c4312b0be74e8e497ac18f805f0e3e6c5 F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63
F ext/misc/regexp.c c25c65fe775f5d9801fb8573e36ebe73f2c0c2e0 F ext/misc/regexp.c c25c65fe775f5d9801fb8573e36ebe73f2c0c2e0
F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a
F ext/misc/spellfix.c 6d7ce6105a4b7729f6c44ccdf1ab7e80d9707c02 F ext/misc/spellfix.c 6d7ce6105a4b7729f6c44ccdf1ab7e80d9707c02
F ext/misc/vtshim.c 5fb6be7fe37659a8cbd1e16982d74cceacbc4543
F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212 F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
F ext/rtree/rtree.c 757abea591d4ff67c0ff4e8f9776aeda86b18c14 F ext/rtree/rtree.c db516d7e59a14c92df10b552789509f2b632df3a
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
F ext/rtree/rtree1.test cf679265ecafff494a768ac9c2f43a70915a6290 F ext/rtree/rtree1.test cf679265ecafff494a768ac9c2f43a70915a6290
F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba
@@ -154,7 +155,7 @@ F magic.txt f2b23a6bde8f1c6e86b957e4d94eab0add520b0d
F main.mk f045701c66fec66208bc35d79de372340916e81e F main.mk f045701c66fec66208bc35d79de372340916e81e
F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a
F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f
F mkextw.sh 4123480947681d9b434a5e7b1ee08135abe409ac F mkextw.sh d2a981497b404d6498f5ff3e3b1f3816bdfcb338
F mkopcodec.awk f6fccee29e68493bfd90a2e0466ede5fa94dd2fc F mkopcodec.awk f6fccee29e68493bfd90a2e0466ede5fa94dd2fc
F mkopcodeh.awk 29b84656502eee5f444c3147f331ee686956ab0e F mkopcodeh.awk 29b84656502eee5f444c3147f331ee686956ab0e
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
@@ -175,7 +176,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
F src/backup.c 43b348822db3e4cef48b2ae5a445fbeb6c73a165 F src/backup.c 43b348822db3e4cef48b2ae5a445fbeb6c73a165
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
F src/btree.c 7fba377c29573adfc6091832e27ee1fcbefb51d0 F src/btree.c 3f7bbfd72efb1cbf6a49515c376a031767ec930a
F src/btree.h 6fa8a3ff2483d0bb64a9f0105a8cedeac9e00cca F src/btree.h 6fa8a3ff2483d0bb64a9f0105a8cedeac9e00cca
F src/btreeInt.h eecc84f02375b2bb7a44abbcbbe3747dde73edb2 F src/btreeInt.h eecc84f02375b2bb7a44abbcbbe3747dde73edb2
F src/build.c 42239cfd95533e4aacf4d58b4724c8f858de5ced F src/build.c 42239cfd95533e4aacf4d58b4724c8f858de5ced
@@ -197,7 +198,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12
F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
F src/loadext.c c48f7f3f170e502fe0cc20748e03c6e0b5a016c2 F src/loadext.c c48f7f3f170e502fe0cc20748e03c6e0b5a016c2
F src/main.c 893986530b7ea4607643675babf08888cb63e48e F src/main.c a27560235a8e0e3f1a94aaca30189431bf61e776
F src/malloc.c fe085aa851b666b7c375c1ff957643dc20a04bf6 F src/malloc.c fe085aa851b666b7c375c1ff957643dc20a04bf6
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c 437c7c4af964895d4650f29881df63535caaa1fa F src/mem1.c 437c7c4af964895d4650f29881df63535caaa1fa
@@ -216,7 +217,7 @@ F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
F src/os_unix.c 9eafa5458cf2ff684ddccff82c9bb113c7cad847 F src/os_unix.c 9eafa5458cf2ff684ddccff82c9bb113c7cad847
F src/os_win.c 074cb2b9bca6a1c2bd72acf04666cdc554bfaa9b F src/os_win.c 074cb2b9bca6a1c2bd72acf04666cdc554bfaa9b
F src/pager.c 79df56da9dd49aceaa4cac207484a9a82cba40ae F src/pager.c 5d2f7475260a8588f9c441bb309d2b7eaa7ded3b
F src/pager.h 5cb78b8e1adfd5451e600be7719f5a99d87ac3b1 F src/pager.h 5cb78b8e1adfd5451e600be7719f5a99d87ac3b1
F src/parse.y 9acfcc83ddbf0cf82f0ed9582ccf0ad6c366ff37 F src/parse.y 9acfcc83ddbf0cf82f0ed9582ccf0ad6c366ff37
F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
@@ -224,21 +225,21 @@ F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
F src/pcache1.c d23d07716de96c7c0c2503ec5051a4384c3fb938 F src/pcache1.c d23d07716de96c7c0c2503ec5051a4384c3fb938
F src/pragma.c 057f5b1343c9a79e3e6c0c542a3a08b85849ee61 F src/pragma.c 057f5b1343c9a79e3e6c0c542a3a08b85849ee61
F src/prepare.c 2306be166bbeddf454e18bf8b21dba8388d05328 F src/prepare.c 2306be166bbeddf454e18bf8b21dba8388d05328
F src/printf.c bff529ed47657098c55c9910b9c69b1b3b1a1353 F src/printf.c 41c49dac366a3a411190001a8ab495fa8887974e
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
F src/resolve.c 89f9003e8316ee3a172795459efc2a0274e1d5a8 F src/resolve.c 89f9003e8316ee3a172795459efc2a0274e1d5a8
F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
F src/select.c 91b62654caf8dfe292fb8882715e575d34ad3874 F src/select.c 91b62654caf8dfe292fb8882715e575d34ad3874
F src/shell.c a02544af6697c5782d29ec3204616f35ed9e8458 F src/shell.c c8cd06e6b66250a3ea0149c4edec30de14f57b6f
F src/sqlite.h.in 0693f95792b64cca4d1780c082d7b96fd32aa1c3 F src/sqlite.h.in fb8adf7852fb92e410de422b5569923327bf8a2c
F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0
F src/sqlite3ext.h d936f797812c28b81b26ed18345baf8db28a21a5 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
F src/sqliteInt.h 5a005fde923b3755fa3184e60028c582a8efe01d F src/sqliteInt.h a83b0cef30022c46a19e6ace1f668b7833935eed
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c bedc37ec1a6bb9399944024d63f4c769971955a9 F src/status.c bedc37ec1a6bb9399944024d63f4c769971955a9
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
F src/tclsqlite.c e0eaf3a78eca2ef650abb67b6571cc86abcb5f87 F src/tclsqlite.c e0eaf3a78eca2ef650abb67b6571cc86abcb5f87
F src/test1.c 06bd01f7795bbef4aaf59d3b9fe5b3131a6ef642 F src/test1.c 870fc648a48cb6d6808393174f7ebe82b8c840fa
F src/test2.c 7355101c085304b90024f2261e056cdff13c6c35 F src/test2.c 7355101c085304b90024f2261e056cdff13c6c35
F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c
F src/test4.c 9b32d22f5f150abe23c1830e2057c4037c45b3df F src/test4.c 9b32d22f5f150abe23c1830e2057c4037c45b3df
@@ -272,7 +273,7 @@ F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00
F src/test_quota.c 30c64f0ef84734f2231a686df41ed882b0c59bc0 F src/test_quota.c 30c64f0ef84734f2231a686df41ed882b0c59bc0
F src/test_quota.h 8761e463b25e75ebc078bd67d70e39b9c817a0cb F src/test_quota.h 8761e463b25e75ebc078bd67d70e39b9c817a0cb
F src/test_rtree.c 1d764c352b5348bb2869ff5f54aff8eadcb96041 F src/test_rtree.c 1d764c352b5348bb2869ff5f54aff8eadcb96041
F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0 F src/test_schema.c cd12a2223c3a394f4d07bb93bdf6d344c5c121b6
F src/test_server.c 2f99eb2837dfa06a4aacf24af24c6affdf66a84f F src/test_server.c 2f99eb2837dfa06a4aacf24af24c6affdf66a84f
F src/test_sqllog.c c1c1bbedbcaf82b93d83e4f9dd990e62476a680e F src/test_sqllog.c c1c1bbedbcaf82b93d83e4f9dd990e62476a680e
F src/test_stat.c d1569c7a4839f13e80187e2c26b2ab4da2d03935 F src/test_stat.c d1569c7a4839f13e80187e2c26b2ab4da2d03935
@@ -280,29 +281,29 @@ F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd
F src/test_syscall.c 16dbe79fb320fadb5acd7a0a59f49e52ab2d2091 F src/test_syscall.c 16dbe79fb320fadb5acd7a0a59f49e52ab2d2091
F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa
F src/test_thread.c 1e133a40b50e9c035b00174035b846e7eef481cb F src/test_thread.c 1e133a40b50e9c035b00174035b846e7eef481cb
F src/test_vfs.c 8e6087a8b3dcc260282074b0efba14b76311120c F src/test_vfs.c 12d9931f65acde64961523b6f420ba7cd057fbd7
F src/test_vfstrace.c 34b544e80ba7fb77be15395a609c669df2e660a2 F src/test_vfstrace.c 34b544e80ba7fb77be15395a609c669df2e660a2
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/tokenize.c 1e86210d3976717a19238ea7b047fac481fe8c12 F src/tokenize.c e0e8fd3cb90a88451f6b6425726c84747b6b20d7
F src/trigger.c 5c0ea9b8755e7c5e1a700f3e27ac4f8d92dd221e F src/trigger.c 5c0ea9b8755e7c5e1a700f3e27ac4f8d92dd221e
F src/update.c 19daebf6a0a67af5524913e93498d08388792128 F src/update.c 19daebf6a0a67af5524913e93498d08388792128
F src/utf.c 8d819e2e5104a430fc2005f018db14347c95a38f F src/utf.c 8d819e2e5104a430fc2005f018db14347c95a38f
F src/util.c f566b5138099a2df8533b190d0dcc74b7dfbe0c9 F src/util.c f566b5138099a2df8533b190d0dcc74b7dfbe0c9
F src/vacuum.c ddf21cc9577c4cb459d08bee9863a78ec000c5bb F src/vacuum.c d9c5759f4c5a438bb43c2086f72c5d2edabc36c8
F src/vdbe.c e1782e46404dd5aeb26d49e2180be6efcb6a2334 F src/vdbe.c 7e1654d4ac01f017aad8088a1225e514b2aef5cf
F src/vdbe.h 1223e2548e0970cf96f573ff6b99f804a36ad683 F src/vdbe.h 1223e2548e0970cf96f573ff6b99f804a36ad683
F src/vdbeInt.h 1ca0f9ae9e9c28823647749edb767ea9ef2176d1 F src/vdbeInt.h 11feb11eb49d8b312741011d30d91c9c50b59de0
F src/vdbeapi.c c45805f7acd2a07444b3d3b63853eb96545ec5f0 F src/vdbeapi.c bb28ee14bae43579b33d88e0d916a1657255a866
F src/vdbeaux.c 2e82e249a0b72e9c2b63d16ec7801a966ff6a182 F src/vdbeaux.c 84f5fb7cb2f62fd8b8a37b96ac929221cc77d317
F src/vdbeblob.c 1268e0bcb8e21fa32520b0fc376e1bcdfaa0c642 F src/vdbeblob.c 1268e0bcb8e21fa32520b0fc376e1bcdfaa0c642
F src/vdbemem.c 833005f1cbbf447289f1973dba2a0c2228c7b8ab F src/vdbemem.c 833005f1cbbf447289f1973dba2a0c2228c7b8ab
F src/vdbesort.c 3937e06b2a0e354500e17dc206ef4c35770a5017 F src/vdbesort.c 3937e06b2a0e354500e17dc206ef4c35770a5017
F src/vdbetrace.c 18cc59cb475e6115129bfde224367d13a35a7d13 F src/vdbetrace.c e7ec40e1999ff3c6414424365d5941178966dcbc
F src/vtab.c b05e5f1f4902461ba9f5fc49bb7eb7c3a0741a83 F src/vtab.c b05e5f1f4902461ba9f5fc49bb7eb7c3a0741a83
F src/wal.c 436bfceb141b9423c45119e68e444358ee0ed35d F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73 F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73
F src/where.c 9bcfcb4ec6a14dd0111bf287bee02be88d5709f9 F src/where.c f5201334501cd23a39315cab479c0dcce0990701
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
@@ -335,7 +336,7 @@ F test/auth.test 4a4c3b034fff7750513520defa910f376c96ab49
F test/auth2.test a2a371aa6df15f8b0c8109b33d3d7f0f73e4c9aa F test/auth2.test a2a371aa6df15f8b0c8109b33d3d7f0f73e4c9aa
F test/auth3.test a4755e6a2a2fea547ffe63c874eb569e60a28eb5 F test/auth3.test a4755e6a2a2fea547ffe63c874eb569e60a28eb5
F test/autoinc.test bd30d372d00045252f6c2e41b5f41455e1975acf F test/autoinc.test bd30d372d00045252f6c2e41b5f41455e1975acf
F test/autoindex1.test 314f12f87667861ac965c41587f9df82c42fff65 F test/autoindex1.test d4dfe14001dfcb74cfbd7107f45a79fc1ab6183e
F test/autovacuum.test 9f22a7733f39c56ef6a5665d10145ac25d8cb574 F test/autovacuum.test 9f22a7733f39c56ef6a5665d10145ac25d8cb574
F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4 F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4
F test/avtrans.test 0252654f4295ddda3b2cce0e894812259e655a85 F test/avtrans.test 0252654f4295ddda3b2cce0e894812259e655a85
@@ -360,7 +361,7 @@ F test/boundary1.tcl 6421b2d920d8b09539503a8673339d32f7609eb1
F test/boundary1.test 66d7f4706ccdb42d58eafdb081de07b0eb42d77b F test/boundary1.test 66d7f4706ccdb42d58eafdb081de07b0eb42d77b
F test/boundary2.tcl e34ef4e930cf1083150d4d2c603e146bd3b76bcb F test/boundary2.tcl e34ef4e930cf1083150d4d2c603e146bd3b76bcb
F test/boundary2.test 9ae758d7dab7e882c8b6cc4a6a10278385bff8fa F test/boundary2.test 9ae758d7dab7e882c8b6cc4a6a10278385bff8fa
F test/boundary3.tcl 8901d6a503d0bf64251dd81cc74e5ad3add4b119 F test/boundary3.tcl 23361e108a125dca9c4080c2feb884fe54d69243
F test/boundary3.test 56ef82096b4329aca2be74fa1e2b0f762ea0eb45 F test/boundary3.test 56ef82096b4329aca2be74fa1e2b0f762ea0eb45
F test/boundary4.tcl 0bb4b1a94f4fc5ae59b79b9a2b7a140c405e2983 F test/boundary4.tcl 0bb4b1a94f4fc5ae59b79b9a2b7a140c405e2983
F test/boundary4.test 89e02fa66397b8a325d5eb102b5806f961f8ec4b F test/boundary4.test 89e02fa66397b8a325d5eb102b5806f961f8ec4b
@@ -371,7 +372,7 @@ F test/capi2.test e8b18cc61090b6e5e388f54d6b125d711d1b265a
F test/capi3.test 56ab450125ead38846cbae7e5b6a216686c3cffa F test/capi3.test 56ab450125ead38846cbae7e5b6a216686c3cffa
F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4 F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4
F test/capi3c.test 93d24621c9ff84da9da060f30431e0453db1cdb0 F test/capi3c.test 93d24621c9ff84da9da060f30431e0453db1cdb0
F test/capi3d.test 17b57ca28be3e37e14c2ba8f787d292d84b724a1 F test/capi3d.test 6d0fc0a86d73f42dd19a7d8b7761ab9bc02277d0
F test/capi3e.test ad90088b18b0367125ff2d4b5400153fd2f99aab F test/capi3e.test ad90088b18b0367125ff2d4b5400153fd2f99aab
F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3 F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3
F test/check.test 2eb93611139a7dfaed3be80067c7dc5ceb5fb287 F test/check.test 2eb93611139a7dfaed3be80067c7dc5ceb5fb287
@@ -438,7 +439,7 @@ F test/e_createtable.test ddf3b2e4506e0813f46b69ccf55757c5570cc181
F test/e_delete.test 89aa84d3d1bd284a0689ede04bce10226a5aeaa5 F test/e_delete.test 89aa84d3d1bd284a0689ede04bce10226a5aeaa5
F test/e_droptrigger.test afd5c4d27dec607f5997a66bf7e2498a082cb235 F test/e_droptrigger.test afd5c4d27dec607f5997a66bf7e2498a082cb235
F test/e_dropview.test 583411e470458c5d76148542cfb5a5fa84c8f93e F test/e_dropview.test 583411e470458c5d76148542cfb5a5fa84c8f93e
F test/e_expr.test 5489424d3d9a452ac3701cdf4b680ae31a157894 F test/e_expr.test 2a599f40f37ee9e853c4396c28ff13c2c50f6628
F test/e_fkey.test 17cfb40002d165299681f39aac0cb5890c359935 F test/e_fkey.test 17cfb40002d165299681f39aac0cb5890c359935
F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459 F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459
F test/e_insert.test d5331cc95e101af2508159fc98b6801631659ffe F test/e_insert.test d5331cc95e101af2508159fc98b6801631659ffe
@@ -675,7 +676,7 @@ F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e
F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f
F test/memdb.test db5260330676de007be8530d6ecc7c9ab2b06ad3 F test/memdb.test db5260330676de007be8530d6ecc7c9ab2b06ad3
F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2 F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2
F test/memsubsys1.test a8f9e37567453a5d1d9d37ec102d4d88ab6be33f F test/memsubsys1.test f97cfd0b30e85c2f1ed16d642e7ac58006be84b2
F test/memsubsys2.test 3a1c1a9de48e5726faa85108b02459fae8cb9ee9 F test/memsubsys2.test 3a1c1a9de48e5726faa85108b02459fae8cb9ee9
F test/minmax.test 42fbad0e81afaa6e0de41c960329f2b2c3526efd F test/minmax.test 42fbad0e81afaa6e0de41c960329f2b2c3526efd
F test/minmax2.test b44bae787fc7b227597b01b0ca5575c7cb54d3bc F test/minmax2.test b44bae787fc7b227597b01b0ca5575c7cb54d3bc
@@ -691,7 +692,8 @@ F test/misc7.test 50c02c35ef7924c246eb3d8d71dfbf90ba352f8f
F test/misuse.test ba4fb5d1a6101d1c171ea38b3c613d0661c83054 F test/misuse.test ba4fb5d1a6101d1c171ea38b3c613d0661c83054
F test/mmap1.test 93d167b328255cbe6679fe1e1a23be1b1197d07b F test/mmap1.test 93d167b328255cbe6679fe1e1a23be1b1197d07b
F test/mmap2.test 9d6dd9ddb4ad2379f29cc78f38ce1e63ed418022 F test/mmap2.test 9d6dd9ddb4ad2379f29cc78f38ce1e63ed418022
F test/mmap3.test 01728252af6f9bcf708169d7b794b7597c69ac44 F test/mmap3.test c92273e16eb8d23c1d55c9815b446bb72ef0512e
F test/mmapfault.test 97507ee06172df99057dbf1c40294eabd82cbb13
F test/multiplex.test e08cc7177bd6d85990ee1d71100bb6c684c02256 F test/multiplex.test e08cc7177bd6d85990ee1d71100bb6c684c02256
F test/multiplex2.test 580ca5817c7edbe4cc68fa150609c9473393003a F test/multiplex2.test 580ca5817c7edbe4cc68fa150609c9473393003a
F test/multiplex3.test d228f59eac91839a977eac19f21d053f03e4d101 F test/multiplex3.test d228f59eac91839a977eac19f21d053f03e4d101
@@ -719,9 +721,9 @@ F test/pagerfault2.test caf4c7facb914fd3b03a17b31ae2b180c8d6ca1f
F test/pagerfault3.test 1003fcda009bf48a8e22a516e193b6ef0dd1bbd8 F test/pagerfault3.test 1003fcda009bf48a8e22a516e193b6ef0dd1bbd8
F test/pageropt.test 6b8f6a123a5572c195ad4ae40f2987007923bbd6 F test/pageropt.test 6b8f6a123a5572c195ad4ae40f2987007923bbd6
F test/pagesize.test 1dd51367e752e742f58e861e65ed7390603827a0 F test/pagesize.test 1dd51367e752e742f58e861e65ed7390603827a0
F test/pcache.test 065aa286e722ab24f2e51792c1f093bf60656b16 F test/pcache.test b09104b03160aca0d968d99e8cd2c5b1921a993d
F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025 F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
F test/percentile.test 4614301e38398df7fdd5f28f4ed8f272b328251b F test/percentile.test b98fc868d71eb5619d42a1702e9ab91718cbed54
F test/permutations.test 742b8005bb3c782797a20beccdbe213ef52531fb F test/permutations.test 742b8005bb3c782797a20beccdbe213ef52531fb
F test/pragma.test 5e7de6c32a5d764f09437d2025f07e4917b9e178 F test/pragma.test 5e7de6c32a5d764f09437d2025f07e4917b9e178
F test/pragma2.test 3a55f82b954242c642f8342b17dffc8b47472947 F test/pragma2.test 3a55f82b954242c642f8342b17dffc8b47472947
@@ -767,7 +769,7 @@ F test/select5.test e758b8ef94f69b111df4cb819008856655dcd535
F test/select6.test e76bd10a56988f15726c097a5d5a7966fe82d3b2 F test/select6.test e76bd10a56988f15726c097a5d5a7966fe82d3b2
F test/select7.test dad6f00f0d49728a879d6eb6451d4752db0b0abe F test/select7.test dad6f00f0d49728a879d6eb6451d4752db0b0abe
F test/select8.test 391de11bdd52339c30580dabbbbe97e3e9a3c79d F test/select8.test 391de11bdd52339c30580dabbbbe97e3e9a3c79d
F test/select9.test c0ca3cd87a8ebb04de2cb1402c77df55d911a0ea F test/select9.test aebc2bb0c3bc44606125033cbcaac2c8d1f33a95
F test/selectA.test 99cf21df033b93033ea4f34aba14a500f48f04fe F test/selectA.test 99cf21df033b93033ea4f34aba14a500f48f04fe
F test/selectB.test 954e4e49cf1f896d61794e440669e03a27ceea25 F test/selectB.test 954e4e49cf1f896d61794e440669e03a27ceea25
F test/selectC.test 871fb55d884d3de5943c4057ebd22c2459e71977 F test/selectC.test 871fb55d884d3de5943c4057ebd22c2459e71977
@@ -786,11 +788,11 @@ F test/shared9.test 5f2a8f79b4d6c7d107a01ffa1ed05ae7e6333e21
F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5 F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5
F test/shared_err.test 0079c05c97d88cfa03989b7c20a8b266983087aa F test/shared_err.test 0079c05c97d88cfa03989b7c20a8b266983087aa
F test/sharedlock.test 927a4b6da11978c82b857dbdb20a932aad732123 F test/sharedlock.test 927a4b6da11978c82b857dbdb20a932aad732123
F test/shell1.test 4a2f57952719972c6f862134463f8712e953c038 F test/shell1.test 928547277d385038c696428e9d791cbbad098974
F test/shell2.test 037d6ad16e873354195d30bb2dc4b5321788154a F test/shell2.test 037d6ad16e873354195d30bb2dc4b5321788154a
F test/shell3.test 9196c42772d575685e722c92b4b39053c6ebba59 F test/shell3.test 9196c42772d575685e722c92b4b39053c6ebba59
F test/shell4.test aa4eef8118b412d1a01477a53426ece169ea86a9 F test/shell4.test aa4eef8118b412d1a01477a53426ece169ea86a9
F test/shell5.test fa2188bbb13fe2d183fd04a5f7b512650c35ef5d F test/shell5.test 946e620a41b64f90d45dcf91c36e8d408d435cfd
F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3 F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
F test/shrink.test 8c70f62b6e8eb4d54533de6d65bd06b1b9a17868 F test/shrink.test 8c70f62b6e8eb4d54533de6d65bd06b1b9a17868
F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329 F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329
@@ -805,7 +807,7 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523
F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715
F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
F test/spellfix.test bea537caf587df30d430c2c6a8fe9f64b8712834 F test/spellfix.test 38246facf7d9d7eeb8a57d7497cf7ce73ce5785d
F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298 F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298
F test/stat.test be8d477306006ec696bc86757cfb34bec79447ce F test/stat.test be8d477306006ec696bc86757cfb34bec79447ce
F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9 F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9
@@ -861,6 +863,7 @@ F test/tkt-7bbfb7d442.test 7b2cd79c7a17ae6750e75ec1a7846712a69c9d18
F test/tkt-80ba201079.test 105a721e6aad0ae3c5946d7615d1e4d03f6145b8 F test/tkt-80ba201079.test 105a721e6aad0ae3c5946d7615d1e4d03f6145b8
F test/tkt-80e031a00f.test 9a154173461a4dbe2de49cda73963e04842d52f7 F test/tkt-80e031a00f.test 9a154173461a4dbe2de49cda73963e04842d52f7
F test/tkt-8454a207b9.test c583a9f814a82a2b5ba95207f55001c9f0cd816c F test/tkt-8454a207b9.test c583a9f814a82a2b5ba95207f55001c9f0cd816c
F test/tkt-868145d012.test a5f941107ece6a64410ca4755c6329b7eb57a356
F test/tkt-91e2e8ba6f.test 08c4f94ae07696b05c9b822da0b4e5337a2f54c5 F test/tkt-91e2e8ba6f.test 08c4f94ae07696b05c9b822da0b4e5337a2f54c5
F test/tkt-94c04eaadb.test fa9c71192f7e2ea2d51bf078bc34e8da6088bf71 F test/tkt-94c04eaadb.test fa9c71192f7e2ea2d51bf078bc34e8da6088bf71
F test/tkt-9d68c883.test 458f7d82a523d7644b54b497c986378a7d8c8b67 F test/tkt-9d68c883.test 458f7d82a523d7644b54b497c986378a7d8c8b67
@@ -971,7 +974,7 @@ F test/trace2.test e7a988fdd982cdec62f1f1f34b0360e6476d01a0
F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6 F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6
F test/trans2.test d5337e61de45e66b1fcbf9db833fa8c82e624b22 F test/trans2.test d5337e61de45e66b1fcbf9db833fa8c82e624b22
F test/trans3.test 373ac5183cc56be69f48ae44090e7f672939f732 F test/trans3.test 373ac5183cc56be69f48ae44090e7f672939f732
F test/transitive1.test d04aa9023e425d6f2d4aa61dd81ee9e102f89062 F test/transitive1.test 0ee69546d6fa20e577a4a706d7daa01c7eba9239
F test/trigger1.test dc47573ac79ffe0ee3eecaa517d70d8dacbccd03 F test/trigger1.test dc47573ac79ffe0ee3eecaa517d70d8dacbccd03
F test/trigger2.test 834187beafd1db383af0c659cfa49b0576832816 F test/trigger2.test 834187beafd1db383af0c659cfa49b0576832816
F test/trigger3.test aa640bb2bbb03edd5ff69c055117ea088f121945 F test/trigger3.test aa640bb2bbb03edd5ff69c055117ea088f121945
@@ -1025,7 +1028,7 @@ F test/wal2.test d4b470f13c87f6d8268b004380afa04c3c67cb90
F test/wal3.test b22eb662bcbc148c5f6d956eaf94b047f7afe9c0 F test/wal3.test b22eb662bcbc148c5f6d956eaf94b047f7afe9c0
F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c
F test/wal5.test 8f888b50f66b78821e61ed0e233ded5de378224b F test/wal5.test 8f888b50f66b78821e61ed0e233ded5de378224b
F test/wal6.test 2e3bc767d9c2ce35c47106148d43fcbd072a93b3 F test/wal6.test 527581f5527bf9c24394991e2be83000aace5f9e
F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd
F test/wal8.test 75c42e1bc4545c277fed212f8fc9b7723cd02216 F test/wal8.test 75c42e1bc4545c277fed212f8fc9b7723cd02216
F test/wal9.test 378e76a9ad09cd9bee06c172ad3547b0129a6750 F test/wal9.test 378e76a9ad09cd9bee06c172ad3547b0129a6750
@@ -1046,8 +1049,8 @@ F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417
F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a
F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e
F test/where.test da54153a4c1571ea1b95659e5bec8119edf786aa F test/where.test da54153a4c1571ea1b95659e5bec8119edf786aa
F test/where2.test dcf0ffafe0de55051c1373835a5a57aee6b50094 F test/where2.test d712de0ea9a2c3de7b34b0b1e75172556fef5b24
F test/where3.test 157071521ceabc06bfd4d37106e4270a8956364d F test/where3.test a0682ba3dc8c8f46ffcc95a3d9f58c4327fc129f
F test/where4.test e9b9e2f2f98f00379e6031db6a6fca29bae782a2 F test/where4.test e9b9e2f2f98f00379e6031db6a6fca29bae782a2
F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2 F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2
F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b
@@ -1062,6 +1065,7 @@ F test/whereD.test 6c2feb79ef1f68381b07f39017fe5f9b96da8d62
F test/whereE.test b3a055eef928c992b0a33198a7b8dc10eea5ad2f F test/whereE.test b3a055eef928c992b0a33198a7b8dc10eea5ad2f
F test/whereF.test 136a7301512d72a08a272806c8767066311b7bc1 F test/whereF.test 136a7301512d72a08a272806c8767066311b7bc1
F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31 F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31
F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c
F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361 F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361
F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688 F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688
F test/zerodamage.test 209d7ed441f44cc5299e4ebffbef06fd5aabfefd F test/zerodamage.test 209d7ed441f44cc5299e4ebffbef06fd5aabfefd
@@ -1111,7 +1115,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae
F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
P 1d44e5d3c2b1dc958442f9114a960b256e002ed3 P 1452defb8cfcc489230314dd1e0425feba46c49d 1e39f85077f1f2b96c3a656c5b6334bafb005908
R 28f75ac347bd281672cb0a8d27d3f6b3 R 996effd12b4e262519df6f6e538dae74
U dan U drh
Z 01296a7a6fdc241a613ea24758428ad2 Z 08707dac307041af534ddfd35863fca1

View File

@@ -1 +1 @@
1452defb8cfcc489230314dd1e0425feba46c49d af3ca4c6e557e6bc92584586b5a97d9be41b0b82

View File

@@ -11,7 +11,7 @@ CMD="$CC -c fts2amal.c"
echo $CMD echo $CMD
$CMD $CMD
echo 'EXPORTS' >fts2.def echo 'EXPORTS' >fts2.def
echo 'sqlite3_extension_init' >>fts2.def echo 'sqlite3_fts2_init' >>fts2.def
i386-mingw32msvc-dllwrap \ i386-mingw32msvc-dllwrap \
--def fts2.def -v --export-all \ --def fts2.def -v --export-all \
--driver-name i386-mingw32msvc-gcc \ --driver-name i386-mingw32msvc-gcc \

View File

@@ -3273,12 +3273,13 @@ int sqlite3BtreeCommitPhaseOne(Btree *p, const char *zMaster){
*/ */
static void btreeEndTransaction(Btree *p){ static void btreeEndTransaction(Btree *p){
BtShared *pBt = p->pBt; BtShared *pBt = p->pBt;
sqlite3 *db = p->db;
assert( sqlite3BtreeHoldsMutex(p) ); assert( sqlite3BtreeHoldsMutex(p) );
#ifndef SQLITE_OMIT_AUTOVACUUM #ifndef SQLITE_OMIT_AUTOVACUUM
pBt->bDoTruncate = 0; pBt->bDoTruncate = 0;
#endif #endif
if( p->inTrans>TRANS_NONE && p->db->activeVdbeCnt>1 ){ if( p->inTrans>TRANS_NONE && db->nVdbeRead>1 ){
/* If there are other active statements that belong to this database /* If there are other active statements that belong to this database
** handle, downgrade to a read-only transaction. The other statements ** handle, downgrade to a read-only transaction. The other statements
** may still be reading from the database. */ ** may still be reading from the database. */

View File

@@ -1065,6 +1065,7 @@ const char *sqlite3ErrName(int rc){
case SQLITE_ABORT_ROLLBACK: zName = "SQLITE_ABORT_ROLLBACK"; break; case SQLITE_ABORT_ROLLBACK: zName = "SQLITE_ABORT_ROLLBACK"; break;
case SQLITE_BUSY: zName = "SQLITE_BUSY"; break; case SQLITE_BUSY: zName = "SQLITE_BUSY"; break;
case SQLITE_BUSY_RECOVERY: zName = "SQLITE_BUSY_RECOVERY"; break; case SQLITE_BUSY_RECOVERY: zName = "SQLITE_BUSY_RECOVERY"; break;
case SQLITE_BUSY_SNAPSHOT: zName = "SQLITE_BUSY_SNAPSHOT"; break;
case SQLITE_LOCKED: zName = "SQLITE_LOCKED"; break; case SQLITE_LOCKED: zName = "SQLITE_LOCKED"; break;
case SQLITE_LOCKED_SHAREDCACHE: zName = "SQLITE_LOCKED_SHAREDCACHE";break; case SQLITE_LOCKED_SHAREDCACHE: zName = "SQLITE_LOCKED_SHAREDCACHE";break;
case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break; case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break;
@@ -1138,6 +1139,7 @@ const char *sqlite3ErrName(int rc){
case SQLITE_NOTICE_RECOVER_ROLLBACK: case SQLITE_NOTICE_RECOVER_ROLLBACK:
zName = "SQLITE_NOTICE_RECOVER_ROLLBACK"; break; zName = "SQLITE_NOTICE_RECOVER_ROLLBACK"; break;
case SQLITE_WARNING: zName = "SQLITE_WARNING"; break; case SQLITE_WARNING: zName = "SQLITE_WARNING"; break;
case SQLITE_WARNING_AUTOINDEX: zName = "SQLITE_WARNING_AUTOINDEX"; break;
case SQLITE_DONE: zName = "SQLITE_DONE"; break; case SQLITE_DONE: zName = "SQLITE_DONE"; break;
} }
} }
@@ -1396,7 +1398,7 @@ int sqlite3CreateFunc(
*/ */
p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 0); p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 0);
if( p && p->iPrefEnc==enc && p->nArg==nArg ){ if( p && p->iPrefEnc==enc && p->nArg==nArg ){
if( db->activeVdbeCnt ){ if( db->nVdbeActive ){
sqlite3Error(db, SQLITE_BUSY, sqlite3Error(db, SQLITE_BUSY,
"unable to delete/modify user-function due to active statements"); "unable to delete/modify user-function due to active statements");
assert( !db->mallocFailed ); assert( !db->mallocFailed );
@@ -1998,7 +2000,7 @@ static int createCollation(
*/ */
pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 0); pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 0);
if( pColl && pColl->xCmp ){ if( pColl && pColl->xCmp ){
if( db->activeVdbeCnt ){ if( db->nVdbeActive ){
sqlite3Error(db, SQLITE_BUSY, sqlite3Error(db, SQLITE_BUSY,
"unable to delete/modify collation sequence due to active statements"); "unable to delete/modify collation sequence due to active statements");
return SQLITE_BUSY; return SQLITE_BUSY;
@@ -2473,7 +2475,10 @@ static int openDatabase(
db->nextAutovac = -1; db->nextAutovac = -1;
db->szMmap = sqlite3GlobalConfig.szMmap; db->szMmap = sqlite3GlobalConfig.szMmap;
db->nextPagesize = 0; db->nextPagesize = 0;
db->flags |= SQLITE_ShortColNames | SQLITE_AutoIndex | SQLITE_EnableTrigger db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger
#if !defined(SQLITE_DEAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX
| SQLITE_AutoIndex
#endif
#if SQLITE_DEFAULT_FILE_FORMAT<4 #if SQLITE_DEFAULT_FILE_FORMAT<4
| SQLITE_LegacyFileFmt | SQLITE_LegacyFileFmt
#endif #endif

View File

@@ -1812,6 +1812,7 @@ static void pager_unlock(Pager *pPager){
pPager->changeCountDone = pPager->tempFile; pPager->changeCountDone = pPager->tempFile;
pPager->eState = PAGER_OPEN; pPager->eState = PAGER_OPEN;
pPager->errCode = SQLITE_OK; pPager->errCode = SQLITE_OK;
if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0);
} }
pPager->journalOff = 0; pPager->journalOff = 0;
@@ -3378,10 +3379,10 @@ void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){
static void pagerFixMaplimit(Pager *pPager){ static void pagerFixMaplimit(Pager *pPager){
#if SQLITE_MAX_MMAP_SIZE>0 #if SQLITE_MAX_MMAP_SIZE>0
sqlite3_file *fd = pPager->fd; sqlite3_file *fd = pPager->fd;
if( isOpen(fd) ){ if( isOpen(fd) && fd->pMethods->iVersion>=3 ){
sqlite3_int64 sz; sqlite3_int64 sz;
pPager->bUseFetch = (fd->pMethods->iVersion>=3) && pPager->szMmap>0;
sz = pPager->szMmap; sz = pPager->szMmap;
pPager->bUseFetch = (sz>0);
sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_SIZE, &sz); sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_SIZE, &sz);
} }
#endif #endif

View File

@@ -468,8 +468,8 @@ void sqlite3VXPrintf(
}else{ }else{
e2 = exp; e2 = exp;
} }
if( e2+precision+width > etBUFSIZE - 15 ){ if( MAX(e2,0)+precision+width > etBUFSIZE - 15 ){
bufpt = zExtra = sqlite3Malloc( e2+precision+width+15 ); bufpt = zExtra = sqlite3Malloc( MAX(e2,0)+precision+width+15 );
if( bufpt==0 ){ if( bufpt==0 ){
pAccum->mallocFailed = 1; pAccum->mallocFailed = 1;
return; return;

View File

@@ -67,7 +67,7 @@
#undef popen #undef popen
#define popen(a,b) _popen((a),(b)) #define popen(a,b) _popen((a),(b))
#undef pclose #undef pclose
#define pclose(x) _pclose(x) #define pclose _pclose
#else #else
/* Make sure isatty() has a prototype. /* Make sure isatty() has a prototype.
*/ */
@@ -1492,6 +1492,7 @@ static void open_db(struct callback_data *p){
** \t -> tab ** \t -> tab
** \n -> newline ** \n -> newline
** \r -> carriage return ** \r -> carriage return
** \" -> "
** \NNN -> ascii character NNN in octal ** \NNN -> ascii character NNN in octal
** \\ -> backslash ** \\ -> backslash
*/ */
@@ -1507,6 +1508,8 @@ static void resolve_backslashes(char *z){
c = '\t'; c = '\t';
}else if( c=='r' ){ }else if( c=='r' ){
c = '\r'; c = '\r';
}else if( c=='\\' ){
c = '\\';
}else if( c>='0' && c<='7' ){ }else if( c>='0' && c<='7' ){
c -= '0'; c -= '0';
if( z[i+1]>='0' && z[i+1]<='7' ){ if( z[i+1]>='0' && z[i+1]<='7' ){
@@ -1650,6 +1653,107 @@ static void test_breakpoint(void){
nCall++; nCall++;
} }
/*
** An object used to read a CSV file
*/
typedef struct CSVReader CSVReader;
struct CSVReader {
const char *zFile; /* Name of the input file */
FILE *in; /* Read the CSV text from this input stream */
char *z; /* Accumulated text for a field */
int n; /* Number of bytes in z */
int nAlloc; /* Space allocated for z[] */
int nLine; /* Current line number */
int cTerm; /* Character that terminated the most recent field */
int cSeparator; /* The separator character. (Usually ",") */
};
/* Append a single byte to z[] */
static void csv_append_char(CSVReader *p, int c){
if( p->n+1>=p->nAlloc ){
p->nAlloc += p->nAlloc + 100;
p->z = sqlite3_realloc(p->z, p->nAlloc);
if( p->z==0 ){
fprintf(stderr, "out of memory\n");
exit(1);
}
}
p->z[p->n++] = (char)c;
}
/* Read a single field of CSV text. Compatible with rfc4180 and extended
** with the option of having a separator other than ",".
**
** + Input comes from p->in.
** + Store results in p->z of length p->n. Space to hold p->z comes
** from sqlite3_malloc().
** + Use p->cSep as the separator. The default is ",".
** + Keep track of the line number in p->nLine.
** + Store the character that terminates the field in p->cTerm. Store
** EOF on end-of-file.
** + Report syntax errors on stderr
*/
static char *csv_read_one_field(CSVReader *p){
int c, pc;
int cSep = p->cSeparator;
p->n = 0;
c = fgetc(p->in);
if( c==EOF || seenInterrupt ){
p->cTerm = EOF;
return 0;
}
if( c=='"' ){
int startLine = p->nLine;
int cQuote = c;
pc = 0;
while( 1 ){
c = fgetc(p->in);
if( c=='\n' ) p->nLine++;
if( c==cQuote ){
if( pc==cQuote ){
pc = 0;
continue;
}
}
if( (c==cSep && pc==cQuote)
|| (c=='\n' && pc==cQuote)
|| (c=='\n' && pc=='\r' && p->n>2 && p->z[p->n-2]==cQuote)
|| (c==EOF && pc==cQuote)
){
do{ p->n--; }while( p->z[p->n]!=cQuote );
p->z[p->n] = 0;
p->cTerm = c;
break;
}
if( pc==cQuote && c!='\r' ){
fprintf(stderr, "%s:%d: unescaped %c character\n",
p->zFile, p->nLine, cQuote);
}
if( c==EOF ){
fprintf(stderr, "%s:%d: unterminated %c-quoted field\n",
p->zFile, startLine, cQuote);
p->z[p->n] = 0;
p->cTerm = EOF;
break;
}
csv_append_char(p, c);
pc = c;
}
}else{
while( c!=EOF && c!=cSep && c!='\n' ){
csv_append_char(p, c);
c = fgetc(p->in);
}
if( c=='\n' ){
p->nLine++;
if( p->n>1 && p->z[p->n-1]=='\r' ) p->n--;
}
p->z[p->n] = 0;
p->cTerm = c;
}
return p->z;
}
/* /*
** If an input line begins with "." then invoke this routine to ** If an input line begins with "." then invoke this routine to
** process that line. ** process that line.
@@ -1671,7 +1775,10 @@ static int do_meta_command(char *zLine, struct callback_data *p){
if( zLine[i]=='\'' || zLine[i]=='"' ){ if( zLine[i]=='\'' || zLine[i]=='"' ){
int delim = zLine[i++]; int delim = zLine[i++];
azArg[nArg++] = &zLine[i]; azArg[nArg++] = &zLine[i];
while( zLine[i] && zLine[i]!=delim ){ i++; } while( zLine[i] && zLine[i]!=delim ){
if( zLine[i]=='\\' && delim=='"' && zLine[i+1]!=0 ) i++;
i++;
}
if( zLine[i]==delim ){ if( zLine[i]==delim ){
zLine[i++] = 0; zLine[i++] = 0;
} }
@@ -1888,48 +1995,97 @@ static int do_meta_command(char *zLine, struct callback_data *p){
if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){ if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){
char *zTable = azArg[2]; /* Insert data into this table */ char *zTable = azArg[2]; /* Insert data into this table */
char *zFile = azArg[1]; /* The file from which to extract data */ char *zFile = azArg[1]; /* Name of file to extra content from */
sqlite3_stmt *pStmt = NULL; /* A statement */ sqlite3_stmt *pStmt = NULL; /* A statement */
int nCol; /* Number of columns in the table */ int nCol; /* Number of columns in the table */
int nByte; /* Number of bytes in an SQL string */ int nByte; /* Number of bytes in an SQL string */
int i, j; /* Loop counters */ int i, j; /* Loop counters */
int nSep; /* Number of bytes in p->separator[] */ int nSep; /* Number of bytes in p->separator[] */
char *zSql; /* An SQL statement */ char *zSql; /* An SQL statement */
char *zLine; /* A single line of input from the file */ CSVReader sCsv; /* Reader context */
char **azCol; /* zLine[] broken up into columns */ int (*xCloser)(FILE*); /* Procedure to close th3 connection */
char *zCommit; /* How to commit changes */
FILE *in; /* The input file */
int lineno = 0; /* Line number of input file */
seenInterrupt = 0;
memset(&sCsv, 0, sizeof(sCsv));
open_db(p); open_db(p);
nSep = strlen30(p->separator); nSep = strlen30(p->separator);
if( nSep==0 ){ if( nSep==0 ){
fprintf(stderr, "Error: non-null separator required for import\n"); fprintf(stderr, "Error: non-null separator required for import\n");
return 1; return 1;
} }
if( nSep>1 ){
fprintf(stderr, "Error: multi-character separators not allowed"
" for import\n");
return 1;
}
sCsv.zFile = zFile;
sCsv.nLine = 1;
if( sCsv.zFile[0]=='|' ){
sCsv.in = popen(sCsv.zFile+1, "r");
sCsv.zFile = "<pipe>";
xCloser = pclose;
}else{
sCsv.in = fopen(sCsv.zFile, "rb");
xCloser = fclose;
}
if( sCsv.in==0 ){
fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
return 1;
}
sCsv.cSeparator = p->separator[0];
zSql = sqlite3_mprintf("SELECT * FROM %s", zTable); zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
if( zSql==0 ){ if( zSql==0 ){
fprintf(stderr, "Error: out of memory\n"); fprintf(stderr, "Error: out of memory\n");
xCloser(sCsv.in);
return 1; return 1;
} }
nByte = strlen30(zSql); nByte = strlen30(zSql);
rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0); rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){
char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
char cSep = '(';
while( csv_read_one_field(&sCsv) ){
zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCsv.z);
cSep = ',';
if( sCsv.cTerm!=sCsv.cSeparator ) break;
}
if( cSep=='(' ){
sqlite3_free(zCreate);
sqlite3_free(sCsv.z);
xCloser(sCsv.in);
fprintf(stderr,"%s: empty file\n", sCsv.zFile);
return 1;
}
zCreate = sqlite3_mprintf("%z\n)", zCreate);
rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
sqlite3_free(zCreate);
if( rc ){
fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
sqlite3_errmsg(db));
sqlite3_free(sCsv.z);
xCloser(sCsv.in);
return 1;
}
rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
}
sqlite3_free(zSql); sqlite3_free(zSql);
if( rc ){ if( rc ){
if (pStmt) sqlite3_finalize(pStmt); if (pStmt) sqlite3_finalize(pStmt);
fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db)); fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
xCloser(sCsv.in);
return 1; return 1;
} }
nCol = sqlite3_column_count(pStmt); nCol = sqlite3_column_count(pStmt);
sqlite3_finalize(pStmt); sqlite3_finalize(pStmt);
pStmt = 0; pStmt = 0;
if( nCol==0 ) return 0; /* no columns, no error */ if( nCol==0 ) return 0; /* no columns, no error */
zSql = malloc( nByte + 20 + nCol*2 ); zSql = sqlite3_malloc( nByte*2 + 20 + nCol*2 );
if( zSql==0 ){ if( zSql==0 ){
fprintf(stderr, "Error: out of memory\n"); fprintf(stderr, "Error: out of memory\n");
xCloser(sCsv.in);
return 1; return 1;
} }
sqlite3_snprintf(nByte+20, zSql, "INSERT INTO %s VALUES(?", zTable); sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
j = strlen30(zSql); j = strlen30(zSql);
for(i=1; i<nCol; i++){ for(i=1; i<nCol; i++){
zSql[j++] = ','; zSql[j++] = ',';
@@ -1938,79 +2094,50 @@ static int do_meta_command(char *zLine, struct callback_data *p){
zSql[j++] = ')'; zSql[j++] = ')';
zSql[j] = 0; zSql[j] = 0;
rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0); rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
free(zSql); sqlite3_free(zSql);
if( rc ){ if( rc ){
fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db)); fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
if (pStmt) sqlite3_finalize(pStmt); if (pStmt) sqlite3_finalize(pStmt);
xCloser(sCsv.in);
return 1; return 1;
} }
in = fopen(zFile, "rb"); do{
if( in==0 ){ int startLine = sCsv.nLine;
fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
sqlite3_finalize(pStmt);
return 1;
}
azCol = malloc( sizeof(azCol[0])*(nCol+1) );
if( azCol==0 ){
fprintf(stderr, "Error: out of memory\n");
fclose(in);
sqlite3_finalize(pStmt);
return 1;
}
sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
zCommit = "COMMIT";
while( (zLine = local_getline(0, in, 1))!=0 ){
char *z, c;
int inQuote = 0;
lineno++;
azCol[0] = zLine;
for(i=0, z=zLine; (c = *z)!=0; z++){
if( c=='"' ) inQuote = !inQuote;
if( c=='\n' ) lineno++;
if( !inQuote && c==p->separator[0] && strncmp(z,p->separator,nSep)==0 ){
*z = 0;
i++;
if( i<nCol ){
azCol[i] = &z[nSep];
z += nSep-1;
}
}
} /* end for */
*z = 0;
if( i+1!=nCol ){
fprintf(stderr,
"Error: %s line %d: expected %d columns of data but found %d\n",
zFile, lineno, nCol, i+1);
zCommit = "ROLLBACK";
free(zLine);
rc = 1;
break; /* from while */
}
for(i=0; i<nCol; i++){ for(i=0; i<nCol; i++){
if( azCol[i][0]=='"' ){ char *z = csv_read_one_field(&sCsv);
int k; if( z==0 && i==0 ) break;
for(z=azCol[i], j=1, k=0; z[j]; j++){ sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
if( z[j]=='"' ){ j++; if( z[j]==0 ) break; } if( i<nCol-1 && sCsv.cTerm!=sCsv.cSeparator ){
z[k++] = z[j]; fprintf(stderr, "%s:%d: expected %d columns but found %d - "
} "filling the rest with NULL\n",
z[k] = 0; sCsv.zFile, startLine, nCol, i+1);
i++;
while( i<nCol ){ sqlite3_bind_null(pStmt, i); i++; }
} }
sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
} }
sqlite3_step(pStmt); if( sCsv.cTerm==sCsv.cSeparator ){
rc = sqlite3_reset(pStmt); do{
free(zLine); csv_read_one_field(&sCsv);
if( rc!=SQLITE_OK ){ i++;
fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db)); }while( sCsv.cTerm==sCsv.cSeparator );
zCommit = "ROLLBACK"; fprintf(stderr, "%s:%d: expected %d columns but found %d - "
rc = 1; "extras ignored\n",
break; /* from while */ sCsv.zFile, startLine, nCol, i);
} }
} /* end while */ if( i>=nCol ){
free(azCol); sqlite3_step(pStmt);
fclose(in); rc = sqlite3_reset(pStmt);
if( rc!=SQLITE_OK ){
fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCsv.zFile, startLine,
sqlite3_errmsg(db));
}
}
}while( sCsv.cTerm!=EOF );
xCloser(sCsv.in);
sqlite3_free(sCsv.z);
sqlite3_finalize(pStmt); sqlite3_finalize(pStmt);
sqlite3_exec(p->db, zCommit, 0, 0, 0); sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
}else }else
if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){ if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){
@@ -2332,6 +2459,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
} }
}else }else
#ifdef SQLITE_DEBUG
/* Undocumented commands for internal testing. Subject to change /* Undocumented commands for internal testing. Subject to change
** without notice. */ ** without notice. */
if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){ if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
@@ -2345,11 +2473,14 @@ static int do_meta_command(char *zLine, struct callback_data *p){
if( strncmp(azArg[0]+9, "integer", n-9)==0 ){ if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
int i; sqlite3_int64 v; int i; sqlite3_int64 v;
for(i=1; i<nArg; i++){ for(i=1; i<nArg; i++){
char zBuf[200];
v = integerValue(azArg[i]); v = integerValue(azArg[i]);
fprintf(p->out, "%s: %lld 0x%llx\n", azArg[i], v, v); sqlite3_snprintf(sizeof(zBuf), zBuf, "%s: %lld 0x%llx\n", azArg[i], v, v);
fprintf(p->out, "%s", zBuf);
} }
} }
}else }else
#endif
if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){ if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
sqlite3_snprintf(sizeof(p->separator), p->separator, sqlite3_snprintf(sizeof(p->separator), p->separator,

View File

@@ -475,6 +475,7 @@ int sqlite3_exec(
#define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8)) #define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8))
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8))
#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
@@ -494,6 +495,7 @@ int sqlite3_exec(
#define SQLITE_CONSTRAINT_VTAB (SQLITE_CONSTRAINT | (9<<8)) #define SQLITE_CONSTRAINT_VTAB (SQLITE_CONSTRAINT | (9<<8))
#define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8)) #define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8))
#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8)) #define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
#define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8))
/* /*
** CAPI3REF: Flags For File Open Operations ** CAPI3REF: Flags For File Open Operations

View File

@@ -474,11 +474,14 @@ struct sqlite3_api_routines {
** extension */ ** extension */
# define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0; # define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0;
# define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v; # define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v;
# define SQLITE_EXTENSION_INIT3 \
extern const sqlite3_api_routines *sqlite3_api;
#else #else
/* This case when the file is being statically linked into the /* This case when the file is being statically linked into the
** application */ ** application */
# define SQLITE_EXTENSION_INIT1 /*no-op*/ # define SQLITE_EXTENSION_INIT1 /*no-op*/
# define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */ # define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */
# define SQLITE_EXTENSION_INIT3 /*no-op*/
#endif #endif
#endif /* _SQLITE3EXT_H_ */ #endif /* _SQLITE3EXT_H_ */

View File

@@ -898,9 +898,10 @@ struct sqlite3 {
u8 busy; /* TRUE if currently initializing */ u8 busy; /* TRUE if currently initializing */
u8 orphanTrigger; /* Last statement is orphaned TEMP trigger */ u8 orphanTrigger; /* Last statement is orphaned TEMP trigger */
} init; } init;
int activeVdbeCnt; /* Number of VDBEs currently executing */ int nVdbeActive; /* Number of VDBEs currently running */
int writeVdbeCnt; /* Number of active VDBEs that are writing */ int nVdbeRead; /* Number of active VDBEs that read or write */
int vdbeExecCnt; /* Number of nested calls to VdbeExec() */ int nVdbeWrite; /* Number of active VDBEs that read and write */
int nVdbeExec; /* Number of nested calls to VdbeExec() */
int nExtension; /* Number of loaded extensions */ int nExtension; /* Number of loaded extensions */
void **aExtension; /* Array of shared library handles */ void **aExtension; /* Array of shared library handles */
void (*xTrace)(void*,const char*); /* Trace function */ void (*xTrace)(void*,const char*); /* Trace function */
@@ -1035,6 +1036,7 @@ struct sqlite3 {
#define SQLITE_SubqCoroutine 0x0100 /* Evaluate subqueries as coroutines */ #define SQLITE_SubqCoroutine 0x0100 /* Evaluate subqueries as coroutines */
#define SQLITE_Transitive 0x0200 /* Transitive constraints */ #define SQLITE_Transitive 0x0200 /* Transitive constraints */
#define SQLITE_OmitNoopJoin 0x0400 /* Omit unused tables in joins */ #define SQLITE_OmitNoopJoin 0x0400 /* Omit unused tables in joins */
#define SQLITE_Stat3 0x0800 /* Use the SQLITE_STAT3 table */
#define SQLITE_AllOpts 0xffff /* All optimizations */ #define SQLITE_AllOpts 0xffff /* All optimizations */
/* /*

View File

@@ -5959,15 +5959,20 @@ static int optimization_control(
const char *zOptName; const char *zOptName;
int mask; int mask;
} aOpt[] = { } aOpt[] = {
{ "all", SQLITE_AllOpts }, { "all", SQLITE_AllOpts },
{ "query-flattener", SQLITE_QueryFlattener }, { "none", 0 },
{ "column-cache", SQLITE_ColumnCache }, { "query-flattener", SQLITE_QueryFlattener },
{ "groupby-order", SQLITE_GroupByOrder }, { "column-cache", SQLITE_ColumnCache },
{ "factor-constants", SQLITE_FactorOutConst }, { "groupby-order", SQLITE_GroupByOrder },
{ "real-as-int", SQLITE_IdxRealAsInt }, { "factor-constants", SQLITE_FactorOutConst },
{ "distinct-opt", SQLITE_DistinctOpt }, { "real-as-int", SQLITE_IdxRealAsInt },
{ "cover-idx-scan", SQLITE_CoverIdxScan }, { "distinct-opt", SQLITE_DistinctOpt },
{ "order-by-idx-join",SQLITE_OrderByIdxJoin }, { "cover-idx-scan", SQLITE_CoverIdxScan },
{ "order-by-idx-join", SQLITE_OrderByIdxJoin },
{ "transitive", SQLITE_Transitive },
{ "subquery-coroutine", SQLITE_SubqCoroutine },
{ "omit-noop-join", SQLITE_OmitNoopJoin },
{ "stat3", SQLITE_Stat3 },
}; };
if( objc!=4 ){ if( objc!=4 ){
@@ -5988,7 +5993,7 @@ static int optimization_control(
Tcl_AppendResult(interp, "unknown optimization - should be one of:", Tcl_AppendResult(interp, "unknown optimization - should be one of:",
(char*)0); (char*)0);
for(i=0; i<sizeof(aOpt)/sizeof(aOpt[0]); i++){ for(i=0; i<sizeof(aOpt)/sizeof(aOpt[0]); i++){
Tcl_AppendResult(interp, " ", aOpt[i].zOptName); Tcl_AppendResult(interp, " ", aOpt[i].zOptName, (char*)0);
} }
return TCL_ERROR; return TCL_ERROR;
} }

View File

@@ -344,7 +344,10 @@ int Sqlitetestschema_Init(Tcl_Interp *interp){
/* /*
** Extension load function. ** Extension load function.
*/ */
int sqlite3_extension_init( #ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_schema_init(
sqlite3 *db, sqlite3 *db,
char **pzErrMsg, char **pzErrMsg,
const sqlite3_api_routines *pApi const sqlite3_api_routines *pApi

View File

@@ -190,8 +190,11 @@ static int tvfsShmMap(sqlite3_file*,int,int,int, void volatile **);
static void tvfsShmBarrier(sqlite3_file*); static void tvfsShmBarrier(sqlite3_file*);
static int tvfsShmUnmap(sqlite3_file*, int); static int tvfsShmUnmap(sqlite3_file*, int);
static int tvfsFetch(sqlite3_file*, sqlite3_int64, int, void**);
static int tvfsUnfetch(sqlite3_file*, sqlite3_int64, void*);
static sqlite3_io_methods tvfs_io_methods = { static sqlite3_io_methods tvfs_io_methods = {
2, /* iVersion */ 3, /* iVersion */
tvfsClose, /* xClose */ tvfsClose, /* xClose */
tvfsRead, /* xRead */ tvfsRead, /* xRead */
tvfsWrite, /* xWrite */ tvfsWrite, /* xWrite */
@@ -207,7 +210,9 @@ static sqlite3_io_methods tvfs_io_methods = {
tvfsShmMap, /* xShmMap */ tvfsShmMap, /* xShmMap */
tvfsShmLock, /* xShmLock */ tvfsShmLock, /* xShmLock */
tvfsShmBarrier, /* xShmBarrier */ tvfsShmBarrier, /* xShmBarrier */
tvfsShmUnmap /* xShmUnmap */ tvfsShmUnmap, /* xShmUnmap */
tvfsFetch,
tvfsUnfetch
}; };
static int tvfsResultCode(Testvfs *p, int *pRc){ static int tvfsResultCode(Testvfs *p, int *pRc){
@@ -618,7 +623,10 @@ static int tvfsOpen(
pMethods = (sqlite3_io_methods *)ckalloc(nByte); pMethods = (sqlite3_io_methods *)ckalloc(nByte);
memcpy(pMethods, &tvfs_io_methods, nByte); memcpy(pMethods, &tvfs_io_methods, nByte);
pMethods->iVersion = pVfs->iVersion; pMethods->iVersion = pFd->pReal->pMethods->iVersion;
if( pMethods->iVersion>pVfs->iVersion ){
pMethods->iVersion = pVfs->iVersion;
}
if( pVfs->iVersion>1 && ((Testvfs *)pVfs->pAppData)->isNoshm ){ if( pVfs->iVersion>1 && ((Testvfs *)pVfs->pAppData)->isNoshm ){
pMethods->xShmUnmap = 0; pMethods->xShmUnmap = 0;
pMethods->xShmLock = 0; pMethods->xShmLock = 0;
@@ -993,6 +1001,21 @@ static int tvfsShmUnmap(
return rc; return rc;
} }
static int tvfsFetch(
sqlite3_file *pFile,
sqlite3_int64 iOfst,
int iAmt,
void **pp
){
TestvfsFd *pFd = tvfsGetFd(pFile);
return sqlite3OsFetch(pFd->pReal, iOfst, iAmt, pp);
}
static int tvfsUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *p){
TestvfsFd *pFd = tvfsGetFd(pFile);
return sqlite3OsUnfetch(pFd->pReal, iOfst, p);
}
static int testvfs_obj_cmd( static int testvfs_obj_cmd(
ClientData cd, ClientData cd,
Tcl_Interp *interp, Tcl_Interp *interp,
@@ -1343,7 +1366,7 @@ static int testvfs_cmd(
Tcl_Obj *CONST objv[] Tcl_Obj *CONST objv[]
){ ){
static sqlite3_vfs tvfs_vfs = { static sqlite3_vfs tvfs_vfs = {
2, /* iVersion */ 3, /* iVersion */
0, /* szOsFile */ 0, /* szOsFile */
0, /* mxPathname */ 0, /* mxPathname */
0, /* pNext */ 0, /* pNext */
@@ -1369,6 +1392,9 @@ static int testvfs_cmd(
tvfsCurrentTime, /* xCurrentTime */ tvfsCurrentTime, /* xCurrentTime */
0, /* xGetLastError */ 0, /* xGetLastError */
0, /* xCurrentTimeInt64 */ 0, /* xCurrentTimeInt64 */
0, /* xSetSystemCall */
0, /* xGetSystemCall */
0, /* xNextSystemCall */
}; };
Testvfs *p; /* New object */ Testvfs *p; /* New object */
@@ -1382,7 +1408,7 @@ static int testvfs_cmd(
int isDefault = 0; /* True if -default is passed */ int isDefault = 0; /* True if -default is passed */
int szOsFile = 0; /* Value passed to -szosfile */ int szOsFile = 0; /* Value passed to -szosfile */
int mxPathname = -1; /* Value passed to -mxpathname */ int mxPathname = -1; /* Value passed to -mxpathname */
int iVersion = 2; /* Value passed to -iversion */ int iVersion = 3; /* Value passed to -iversion */
if( objc<2 || 0!=(objc%2) ) goto bad_args; if( objc<2 || 0!=(objc%2) ) goto bad_args;
for(i=2; i<objc; i += 2){ for(i=2; i<objc; i += 2){

View File

@@ -396,7 +396,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH]; mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
if( db->activeVdbeCnt==0 ){ if( db->nVdbeActive==0 ){
db->u1.isInterrupted = 0; db->u1.isInterrupted = 0;
} }
pParse->rc = SQLITE_OK; pParse->rc = SQLITE_OK;

View File

@@ -111,7 +111,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction"); sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction");
return SQLITE_ERROR; return SQLITE_ERROR;
} }
if( db->activeVdbeCnt>1 ){ if( db->nVdbeActive>1 ){
sqlite3SetString(pzErrMsg, db,"cannot VACUUM - SQL statements in progress"); sqlite3SetString(pzErrMsg, db,"cannot VACUUM - SQL statements in progress");
return SQLITE_ERROR; return SQLITE_ERROR;
} }

View File

@@ -589,6 +589,7 @@ int sqlite3VdbeExec(
goto no_mem; goto no_mem;
} }
assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY ); assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY );
assert( p->bIsReader || p->readOnly!=0 );
p->rc = SQLITE_OK; p->rc = SQLITE_OK;
assert( p->explain==0 ); assert( p->explain==0 );
p->pResultSet = 0; p->pResultSet = 0;
@@ -2695,9 +2696,10 @@ case OP_Savepoint: {
assert( p1==SAVEPOINT_BEGIN||p1==SAVEPOINT_RELEASE||p1==SAVEPOINT_ROLLBACK ); assert( p1==SAVEPOINT_BEGIN||p1==SAVEPOINT_RELEASE||p1==SAVEPOINT_ROLLBACK );
assert( db->pSavepoint || db->isTransactionSavepoint==0 ); assert( db->pSavepoint || db->isTransactionSavepoint==0 );
assert( checkSavepointCount(db) ); assert( checkSavepointCount(db) );
assert( p->bIsReader );
if( p1==SAVEPOINT_BEGIN ){ if( p1==SAVEPOINT_BEGIN ){
if( db->writeVdbeCnt>0 ){ if( db->nVdbeWrite>0 ){
/* A new savepoint cannot be created if there are active write /* A new savepoint cannot be created if there are active write
** statements (i.e. open read/write incremental blob handles). ** statements (i.e. open read/write incremental blob handles).
*/ */
@@ -2755,7 +2757,7 @@ case OP_Savepoint: {
if( !pSavepoint ){ if( !pSavepoint ){
sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", zName); sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", zName);
rc = SQLITE_ERROR; rc = SQLITE_ERROR;
}else if( db->writeVdbeCnt>0 && p1==SAVEPOINT_RELEASE ){ }else if( db->nVdbeWrite>0 && p1==SAVEPOINT_RELEASE ){
/* It is not possible to release (commit) a savepoint if there are /* It is not possible to release (commit) a savepoint if there are
** active write statements. ** active write statements.
*/ */
@@ -2857,10 +2859,11 @@ case OP_AutoCommit: {
turnOnAC = desiredAutoCommit && !db->autoCommit; turnOnAC = desiredAutoCommit && !db->autoCommit;
assert( desiredAutoCommit==1 || desiredAutoCommit==0 ); assert( desiredAutoCommit==1 || desiredAutoCommit==0 );
assert( desiredAutoCommit==1 || iRollback==0 ); assert( desiredAutoCommit==1 || iRollback==0 );
assert( db->activeVdbeCnt>0 ); /* At least this one VM is active */ assert( db->nVdbeActive>0 ); /* At least this one VM is active */
assert( p->bIsReader );
#if 0 #if 0
if( turnOnAC && iRollback && db->activeVdbeCnt>1 ){ if( turnOnAC && iRollback && db->nVdbeActive>1 ){
/* If this instruction implements a ROLLBACK and other VMs are /* If this instruction implements a ROLLBACK and other VMs are
** still running, and a transaction is active, return an error indicating ** still running, and a transaction is active, return an error indicating
** that the other VMs must complete first. ** that the other VMs must complete first.
@@ -2870,7 +2873,7 @@ case OP_AutoCommit: {
rc = SQLITE_BUSY; rc = SQLITE_BUSY;
}else }else
#endif #endif
if( turnOnAC && !iRollback && db->writeVdbeCnt>0 ){ if( turnOnAC && !iRollback && db->nVdbeWrite>0 ){
/* If this instruction implements a COMMIT and other VMs are writing /* If this instruction implements a COMMIT and other VMs are writing
** return an error indicating that the other VMs must complete first. ** return an error indicating that the other VMs must complete first.
*/ */
@@ -2946,6 +2949,8 @@ case OP_AutoCommit: {
case OP_Transaction: { case OP_Transaction: {
Btree *pBt; Btree *pBt;
assert( p->bIsReader );
assert( p->readOnly==0 || pOp->p2==0 );
assert( pOp->p1>=0 && pOp->p1<db->nDb ); assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
pBt = db->aDb[pOp->p1].pBt; pBt = db->aDb[pOp->p1].pBt;
@@ -2962,7 +2967,7 @@ case OP_Transaction: {
} }
if( pOp->p2 && p->usesStmtJournal if( pOp->p2 && p->usesStmtJournal
&& (db->autoCommit==0 || db->activeVdbeCnt>1) && (db->autoCommit==0 || db->nVdbeRead>1)
){ ){
assert( sqlite3BtreeIsInTrans(pBt) ); assert( sqlite3BtreeIsInTrans(pBt) );
if( p->iStatement==0 ){ if( p->iStatement==0 ){
@@ -3003,6 +3008,7 @@ case OP_ReadCookie: { /* out2-prerelease */
int iDb; int iDb;
int iCookie; int iCookie;
assert( p->bIsReader );
iDb = pOp->p1; iDb = pOp->p1;
iCookie = pOp->p3; iCookie = pOp->p3;
assert( pOp->p3<SQLITE_N_BTREE_META ); assert( pOp->p3<SQLITE_N_BTREE_META );
@@ -3030,6 +3036,7 @@ case OP_SetCookie: { /* in3 */
assert( pOp->p2<SQLITE_N_BTREE_META ); assert( pOp->p2<SQLITE_N_BTREE_META );
assert( pOp->p1>=0 && pOp->p1<db->nDb ); assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
assert( p->readOnly==0 );
pDb = &db->aDb[pOp->p1]; pDb = &db->aDb[pOp->p1];
assert( pDb->pBt!=0 ); assert( pDb->pBt!=0 );
assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) ); assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) );
@@ -3080,6 +3087,7 @@ case OP_VerifyCookie: {
assert( pOp->p1>=0 && pOp->p1<db->nDb ); assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) ); assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) );
assert( p->bIsReader );
pBt = db->aDb[pOp->p1].pBt; pBt = db->aDb[pOp->p1].pBt;
if( pBt ){ if( pBt ){
sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta); sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta);
@@ -3175,6 +3183,8 @@ case OP_OpenWrite: {
assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR))==pOp->p5 ); assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR))==pOp->p5 );
assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 ); assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 );
assert( p->bIsReader );
assert( pOp->opcode==OP_OpenRead || p->readOnly==0 );
if( p->expired ){ if( p->expired ){
rc = SQLITE_ABORT; rc = SQLITE_ABORT;
@@ -4787,15 +4797,18 @@ case OP_Destroy: { /* out2-prerelease */
Vdbe *pVdbe; Vdbe *pVdbe;
int iDb; int iDb;
assert( p->readOnly==0 );
#ifndef SQLITE_OMIT_VIRTUALTABLE #ifndef SQLITE_OMIT_VIRTUALTABLE
iCnt = 0; iCnt = 0;
for(pVdbe=db->pVdbe; pVdbe; pVdbe = pVdbe->pNext){ for(pVdbe=db->pVdbe; pVdbe; pVdbe = pVdbe->pNext){
if( pVdbe->magic==VDBE_MAGIC_RUN && pVdbe->inVtabMethod<2 && pVdbe->pc>=0 ){ if( pVdbe->magic==VDBE_MAGIC_RUN && pVdbe->bIsReader
&& pVdbe->inVtabMethod<2 && pVdbe->pc>=0
){
iCnt++; iCnt++;
} }
} }
#else #else
iCnt = db->activeVdbeCnt; iCnt = db->nVdbeRead;
#endif #endif
pOut->flags = MEM_Null; pOut->flags = MEM_Null;
if( iCnt>1 ){ if( iCnt>1 ){
@@ -4842,6 +4855,7 @@ case OP_Clear: {
int nChange; int nChange;
nChange = 0; nChange = 0;
assert( p->readOnly==0 );
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p2))!=0 ); assert( (p->btreeMask & (((yDbMask)1)<<pOp->p2))!=0 );
rc = sqlite3BtreeClearTable( rc = sqlite3BtreeClearTable(
db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &nChange : 0) db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &nChange : 0)
@@ -4888,6 +4902,7 @@ case OP_CreateTable: { /* out2-prerelease */
pgno = 0; pgno = 0;
assert( pOp->p1>=0 && pOp->p1<db->nDb ); assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
assert( p->readOnly==0 );
pDb = &db->aDb[pOp->p1]; pDb = &db->aDb[pOp->p1];
assert( pDb->pBt!=0 ); assert( pDb->pBt!=0 );
if( pOp->opcode==OP_CreateTable ){ if( pOp->opcode==OP_CreateTable ){
@@ -5035,7 +5050,8 @@ case OP_IntegrityCk: {
int nErr; /* Number of errors reported */ int nErr; /* Number of errors reported */
char *z; /* Text of the error report */ char *z; /* Text of the error report */
Mem *pnErr; /* Register keeping track of errors remaining */ Mem *pnErr; /* Register keeping track of errors remaining */
assert( p->bIsReader );
nRoot = pOp->p2; nRoot = pOp->p2;
assert( nRoot>0 ); assert( nRoot>0 );
aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(nRoot+1) ); aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(nRoot+1) );
@@ -5543,6 +5559,7 @@ case OP_Checkpoint: {
int aRes[3]; /* Results */ int aRes[3]; /* Results */
Mem *pMem; /* Write results here */ Mem *pMem; /* Write results here */
assert( p->readOnly==0 );
aRes[0] = 0; aRes[0] = 0;
aRes[1] = aRes[2] = -1; aRes[1] = aRes[2] = -1;
assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE
@@ -5592,6 +5609,7 @@ case OP_JournalMode: { /* out2-prerelease */
|| eNew==PAGER_JOURNALMODE_QUERY || eNew==PAGER_JOURNALMODE_QUERY
); );
assert( pOp->p1>=0 && pOp->p1<db->nDb ); assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( p->readOnly==0 );
pBt = db->aDb[pOp->p1].pBt; pBt = db->aDb[pOp->p1].pBt;
pPager = sqlite3BtreePager(pBt); pPager = sqlite3BtreePager(pBt);
@@ -5615,7 +5633,7 @@ case OP_JournalMode: { /* out2-prerelease */
if( (eNew!=eOld) if( (eNew!=eOld)
&& (eOld==PAGER_JOURNALMODE_WAL || eNew==PAGER_JOURNALMODE_WAL) && (eOld==PAGER_JOURNALMODE_WAL || eNew==PAGER_JOURNALMODE_WAL)
){ ){
if( !db->autoCommit || db->activeVdbeCnt>1 ){ if( !db->autoCommit || db->nVdbeRead>1 ){
rc = SQLITE_ERROR; rc = SQLITE_ERROR;
sqlite3SetString(&p->zErrMsg, db, sqlite3SetString(&p->zErrMsg, db,
"cannot change %s wal mode from within a transaction", "cannot change %s wal mode from within a transaction",
@@ -5674,6 +5692,7 @@ case OP_JournalMode: { /* out2-prerelease */
** a transaction. ** a transaction.
*/ */
case OP_Vacuum: { case OP_Vacuum: {
assert( p->readOnly==0 );
rc = sqlite3RunVacuum(&p->zErrMsg, db); rc = sqlite3RunVacuum(&p->zErrMsg, db);
break; break;
} }
@@ -5691,6 +5710,7 @@ case OP_IncrVacuum: { /* jump */
assert( pOp->p1>=0 && pOp->p1<db->nDb ); assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
assert( p->readOnly==0 );
pBt = db->aDb[pOp->p1].pBt; pBt = db->aDb[pOp->p1].pBt;
rc = sqlite3BtreeIncrVacuum(pBt); rc = sqlite3BtreeIncrVacuum(pBt);
if( rc==SQLITE_DONE ){ if( rc==SQLITE_DONE ){
@@ -5809,6 +5829,7 @@ case OP_VOpen: {
sqlite3_vtab *pVtab; sqlite3_vtab *pVtab;
sqlite3_module *pModule; sqlite3_module *pModule;
assert( p->bIsReader );
pCur = 0; pCur = 0;
pVtabCursor = 0; pVtabCursor = 0;
pVtab = pOp->p4.pVtab->pVtab; pVtab = pOp->p4.pVtab->pVtab;
@@ -6025,6 +6046,7 @@ case OP_VRename: {
pName = &aMem[pOp->p1]; pName = &aMem[pOp->p1];
assert( pVtab->pModule->xRename ); assert( pVtab->pModule->xRename );
assert( memIsValid(pName) ); assert( memIsValid(pName) );
assert( p->readOnly==0 );
REGISTER_TRACE(pOp->p1, pName); REGISTER_TRACE(pOp->p1, pName);
assert( pName->flags & MEM_Str ); assert( pName->flags & MEM_Str );
testcase( pName->enc==SQLITE_UTF8 ); testcase( pName->enc==SQLITE_UTF8 );
@@ -6076,6 +6098,7 @@ case OP_VUpdate: {
assert( pOp->p2==1 || pOp->p5==OE_Fail || pOp->p5==OE_Rollback assert( pOp->p2==1 || pOp->p5==OE_Fail || pOp->p5==OE_Rollback
|| pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace || pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace
); );
assert( p->readOnly==0 );
pVtab = pOp->p4.pVtab->pVtab; pVtab = pOp->p4.pVtab->pVtab;
pModule = (sqlite3_module *)pVtab->pModule; pModule = (sqlite3_module *)pVtab->pModule;
nArg = pOp->p2; nArg = pOp->p2;

View File

@@ -337,7 +337,8 @@ struct Vdbe {
bft expired:1; /* True if the VM needs to be recompiled */ bft expired:1; /* True if the VM needs to be recompiled */
bft runOnlyOnce:1; /* Automatically expire on reset */ bft runOnlyOnce:1; /* Automatically expire on reset */
bft usesStmtJournal:1; /* True if uses a statement journal */ bft usesStmtJournal:1; /* True if uses a statement journal */
bft readOnly:1; /* True for read-only statements */ bft readOnly:1; /* True for statements that do not write */
bft bIsReader:1; /* True for statements that read */
bft isPrepareV2:1; /* True if prepared with prepare_v2() */ bft isPrepareV2:1; /* True if prepared with prepare_v2() */
bft doingRerun:1; /* True if rerunning after an auto-reprepare */ bft doingRerun:1; /* True if rerunning after an auto-reprepare */
int nChange; /* Number of db changes made since last reset */ int nChange; /* Number of db changes made since last reset */

View File

@@ -382,11 +382,11 @@ static int sqlite3Step(Vdbe *p){
** reset the interrupt flag. This prevents a call to sqlite3_interrupt ** reset the interrupt flag. This prevents a call to sqlite3_interrupt
** from interrupting a statement that has not yet started. ** from interrupting a statement that has not yet started.
*/ */
if( db->activeVdbeCnt==0 ){ if( db->nVdbeActive==0 ){
db->u1.isInterrupted = 0; db->u1.isInterrupted = 0;
} }
assert( db->writeVdbeCnt>0 || db->autoCommit==0 assert( db->nVdbeWrite>0 || db->autoCommit==0
|| (db->nDeferredCons==0 && db->nDeferredImmCons==0) || (db->nDeferredCons==0 && db->nDeferredImmCons==0)
); );
@@ -396,8 +396,9 @@ static int sqlite3Step(Vdbe *p){
} }
#endif #endif
db->activeVdbeCnt++; db->nVdbeActive++;
if( p->readOnly==0 ) db->writeVdbeCnt++; if( p->readOnly==0 ) db->nVdbeWrite++;
if( p->bIsReader ) db->nVdbeRead++;
p->pc = 0; p->pc = 0;
} }
#ifndef SQLITE_OMIT_EXPLAIN #ifndef SQLITE_OMIT_EXPLAIN
@@ -406,9 +407,9 @@ static int sqlite3Step(Vdbe *p){
}else }else
#endif /* SQLITE_OMIT_EXPLAIN */ #endif /* SQLITE_OMIT_EXPLAIN */
{ {
db->vdbeExecCnt++; db->nVdbeExec++;
rc = sqlite3VdbeExec(p); rc = sqlite3VdbeExec(p);
db->vdbeExecCnt--; db->nVdbeExec--;
} }
#ifndef SQLITE_OMIT_TRACE #ifndef SQLITE_OMIT_TRACE

View File

@@ -404,14 +404,26 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
Op *pOp; Op *pOp;
int *aLabel = p->aLabel; int *aLabel = p->aLabel;
p->readOnly = 1; p->readOnly = 1;
p->bIsReader = 0;
for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){ for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
u8 opcode = pOp->opcode; u8 opcode = pOp->opcode;
pOp->opflags = sqlite3OpcodeProperty[opcode]; pOp->opflags = sqlite3OpcodeProperty[opcode];
if( opcode==OP_Function || opcode==OP_AggStep ){ if( opcode==OP_Function || opcode==OP_AggStep ){
if( pOp->p5>nMaxArgs ) nMaxArgs = pOp->p5; if( pOp->p5>nMaxArgs ) nMaxArgs = pOp->p5;
}else if( (opcode==OP_Transaction && pOp->p2!=0) || opcode==OP_Vacuum ){ }else if( opcode==OP_Transaction ){
if( pOp->p2!=0 ) p->readOnly = 0;
p->bIsReader = 1;
}else if( opcode==OP_AutoCommit || opcode==OP_Savepoint ){
p->bIsReader = 1;
}else if( opcode==OP_Vacuum
|| opcode==OP_JournalMode
#ifndef SQLITE_OMIT_WAL
|| opcode==OP_Checkpoint
#endif
){
p->readOnly = 0; p->readOnly = 0;
p->bIsReader = 1;
#ifndef SQLITE_OMIT_VIRTUALTABLE #ifndef SQLITE_OMIT_VIRTUALTABLE
}else if( opcode==OP_VUpdate ){ }else if( opcode==OP_VUpdate ){
if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2; if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
@@ -437,8 +449,8 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
} }
sqlite3DbFree(p->db, p->aLabel); sqlite3DbFree(p->db, p->aLabel);
p->aLabel = 0; p->aLabel = 0;
*pMaxFuncArgs = nMaxArgs; *pMaxFuncArgs = nMaxArgs;
assert( p->bIsReader!=0 || p->btreeMask==0 );
} }
/* /*
@@ -1964,7 +1976,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
} }
/* /*
** This routine checks that the sqlite3.activeVdbeCnt count variable ** This routine checks that the sqlite3.nVdbeActive count variable
** matches the number of vdbe's in the list sqlite3.pVdbe that are ** matches the number of vdbe's in the list sqlite3.pVdbe that are
** currently active. An assertion fails if the two counts do not match. ** currently active. An assertion fails if the two counts do not match.
** This is an internal self-check only - it is not an essential processing ** This is an internal self-check only - it is not an essential processing
@@ -1977,16 +1989,19 @@ static void checkActiveVdbeCnt(sqlite3 *db){
Vdbe *p; Vdbe *p;
int cnt = 0; int cnt = 0;
int nWrite = 0; int nWrite = 0;
int nRead = 0;
p = db->pVdbe; p = db->pVdbe;
while( p ){ while( p ){
if( p->magic==VDBE_MAGIC_RUN && p->pc>=0 ){ if( p->magic==VDBE_MAGIC_RUN && p->pc>=0 ){
cnt++; cnt++;
if( p->readOnly==0 ) nWrite++; if( p->readOnly==0 ) nWrite++;
if( p->bIsReader ) nRead++;
} }
p = p->pNext; p = p->pNext;
} }
assert( cnt==db->activeVdbeCnt ); assert( cnt==db->nVdbeActive );
assert( nWrite==db->writeVdbeCnt ); assert( nWrite==db->nVdbeWrite );
assert( nRead==db->nVdbeRead );
} }
#else #else
#define checkActiveVdbeCnt(x) #define checkActiveVdbeCnt(x)
@@ -2125,8 +2140,9 @@ int sqlite3VdbeHalt(Vdbe *p){
} }
checkActiveVdbeCnt(db); checkActiveVdbeCnt(db);
/* No commit or rollback needed if the program never started */ /* No commit or rollback needed if the program never started or if the
if( p->pc>=0 ){ ** SQL statement does not read or write a database file. */
if( p->pc>=0 && p->bIsReader ){
int mrc; /* Primary error code from p->rc */ int mrc; /* Primary error code from p->rc */
int eStatementOp = 0; int eStatementOp = 0;
int isSpecialError; /* Set to true if a 'special' error */ int isSpecialError; /* Set to true if a 'special' error */
@@ -2179,7 +2195,7 @@ int sqlite3VdbeHalt(Vdbe *p){
*/ */
if( !sqlite3VtabInSync(db) if( !sqlite3VtabInSync(db)
&& db->autoCommit && db->autoCommit
&& db->writeVdbeCnt==(p->readOnly==0) && db->nVdbeWrite==(p->readOnly==0)
){ ){
if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){ if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){
rc = sqlite3VdbeCheckFk(p, 1); rc = sqlite3VdbeCheckFk(p, 1);
@@ -2262,11 +2278,12 @@ int sqlite3VdbeHalt(Vdbe *p){
/* We have successfully halted and closed the VM. Record this fact. */ /* We have successfully halted and closed the VM. Record this fact. */
if( p->pc>=0 ){ if( p->pc>=0 ){
db->activeVdbeCnt--; db->nVdbeActive--;
if( !p->readOnly ){ if( !p->readOnly ) db->nVdbeWrite--;
db->writeVdbeCnt--; if( p->bIsReader ) db->nVdbeRead--;
} assert( db->nVdbeActive>=db->nVdbeRead );
assert( db->activeVdbeCnt>=db->writeVdbeCnt ); assert( db->nVdbeRead>=db->nVdbeWrite );
assert( db->nVdbeWrite>=0 );
} }
p->magic = VDBE_MAGIC_HALT; p->magic = VDBE_MAGIC_HALT;
checkActiveVdbeCnt(db); checkActiveVdbeCnt(db);
@@ -2282,7 +2299,7 @@ int sqlite3VdbeHalt(Vdbe *p){
sqlite3ConnectionUnlocked(db); sqlite3ConnectionUnlocked(db);
} }
assert( db->activeVdbeCnt>0 || db->autoCommit==0 || db->nStatement==0 ); assert( db->nVdbeActive>0 || db->autoCommit==0 || db->nStatement==0 );
return (p->rc==SQLITE_BUSY ? SQLITE_BUSY : SQLITE_OK); return (p->rc==SQLITE_BUSY ? SQLITE_BUSY : SQLITE_OK);
} }

View File

@@ -47,9 +47,9 @@ static int findNextHostParameter(const char *zSql, int *pnToken){
/* /*
** This function returns a pointer to a nul-terminated string in memory ** This function returns a pointer to a nul-terminated string in memory
** obtained from sqlite3DbMalloc(). If sqlite3.vdbeExecCnt is 1, then the ** obtained from sqlite3DbMalloc(). If sqlite3.nVdbeExec is 1, then the
** string contains a copy of zRawSql but with host parameters expanded to ** string contains a copy of zRawSql but with host parameters expanded to
** their current bindings. Or, if sqlite3.vdbeExecCnt is greater than 1, ** their current bindings. Or, if sqlite3.nVdbeExec is greater than 1,
** then the returned string holds a copy of zRawSql with "-- " prepended ** then the returned string holds a copy of zRawSql with "-- " prepended
** to each line of text. ** to each line of text.
** **
@@ -87,7 +87,7 @@ char *sqlite3VdbeExpandSql(
sqlite3StrAccumInit(&out, zBase, sizeof(zBase), sqlite3StrAccumInit(&out, zBase, sizeof(zBase),
db->aLimit[SQLITE_LIMIT_LENGTH]); db->aLimit[SQLITE_LIMIT_LENGTH]);
out.db = db; out.db = db;
if( db->vdbeExecCnt>1 ){ if( db->nVdbeExec>1 ){
while( *zRawSql ){ while( *zRawSql ){
const char *zStart = zRawSql; const char *zStart = zRawSql;
while( *(zRawSql++)!='\n' && *zRawSql ); while( *(zRawSql++)!='\n' && *zRawSql );

View File

@@ -2463,7 +2463,7 @@ int sqlite3WalBeginWriteTransaction(Wal *pWal){
if( memcmp(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr))!=0 ){ if( memcmp(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr))!=0 ){
walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
pWal->writeLock = 0; pWal->writeLock = 0;
rc = SQLITE_BUSY; rc = SQLITE_BUSY_SNAPSHOT;
} }
return rc; return rc;

View File

@@ -159,7 +159,7 @@ static int whereLoopResize(sqlite3*, WhereLoop*, int);
** Each instance of this object holds a sequence of WhereLoop objects ** Each instance of this object holds a sequence of WhereLoop objects
** that implement some or all of a query plan. ** that implement some or all of a query plan.
** **
** Think of each WhereLoop objects as a node in a graph, which arcs ** Think of each WhereLoop object as a node in a graph with arcs
** showing dependences and costs for travelling between nodes. (That is ** showing dependences and costs for travelling between nodes. (That is
** not a completely accurate description because WhereLoop costs are a ** not a completely accurate description because WhereLoop costs are a
** vector, not a scalar, and because dependences are many-to-one, not ** vector, not a scalar, and because dependences are many-to-one, not
@@ -429,7 +429,7 @@ struct WhereInfo {
** The particular combination of bits in each WhereLoop help to ** The particular combination of bits in each WhereLoop help to
** determine the algorithm that WhereLoop represents. ** determine the algorithm that WhereLoop represents.
*/ */
#define WHERE_COLUMN_EQ 0x00000001 /* x=EXPR or x IN (...) or x IS NULL */ #define WHERE_COLUMN_EQ 0x00000001 /* x=EXPR */
#define WHERE_COLUMN_RANGE 0x00000002 /* x<EXPR and/or x>EXPR */ #define WHERE_COLUMN_RANGE 0x00000002 /* x<EXPR and/or x>EXPR */
#define WHERE_COLUMN_IN 0x00000004 /* x IN (...) */ #define WHERE_COLUMN_IN 0x00000004 /* x IN (...) */
#define WHERE_COLUMN_NULL 0x00000008 /* x IS NULL */ #define WHERE_COLUMN_NULL 0x00000008 /* x IS NULL */
@@ -444,7 +444,7 @@ struct WhereInfo {
#define WHERE_IN_ABLE 0x00000800 /* Able to support an IN operator */ #define WHERE_IN_ABLE 0x00000800 /* Able to support an IN operator */
#define WHERE_ONEROW 0x00001000 /* Selects no more than one row */ #define WHERE_ONEROW 0x00001000 /* Selects no more than one row */
#define WHERE_MULTI_OR 0x00002000 /* OR using multiple indices */ #define WHERE_MULTI_OR 0x00002000 /* OR using multiple indices */
#define WHERE_TEMP_INDEX 0x00004000 /* Uses an ephemeral index */ #define WHERE_AUTO_INDEX 0x00004000 /* Uses an ephemeral index */
/* Convert a WhereCost value (10 times log2(X)) into its integer value X. /* Convert a WhereCost value (10 times log2(X)) into its integer value X.
@@ -822,7 +822,7 @@ static u16 operatorMask(int op){
** established when the pScan object was initialized by whereScanInit(). ** established when the pScan object was initialized by whereScanInit().
** Return NULL if there are no more matching WhereTerms. ** Return NULL if there are no more matching WhereTerms.
*/ */
WhereTerm *whereScanNext(WhereScan *pScan){ static WhereTerm *whereScanNext(WhereScan *pScan){
int iCur; /* The cursor on the LHS of the term */ int iCur; /* The cursor on the LHS of the term */
int iColumn; /* The column on the LHS of the term. -1 for IPK */ int iColumn; /* The column on the LHS of the term. -1 for IPK */
Expr *pX; /* An expression being tested */ Expr *pX; /* An expression being tested */
@@ -909,7 +909,7 @@ WhereTerm *whereScanNext(WhereScan *pScan){
** If X is not the INTEGER PRIMARY KEY then X must be compatible with ** If X is not the INTEGER PRIMARY KEY then X must be compatible with
** index pIdx. ** index pIdx.
*/ */
WhereTerm *whereScanInit( static WhereTerm *whereScanInit(
WhereScan *pScan, /* The WhereScan object being initialized */ WhereScan *pScan, /* The WhereScan object being initialized */
WhereClause *pWC, /* The WHERE clause to be scanned */ WhereClause *pWC, /* The WHERE clause to be scanned */
int iCur, /* Cursor to scan for */ int iCur, /* Cursor to scan for */
@@ -1738,6 +1738,7 @@ static void exprAnalyze(
if( pExpr->op==TK_NOTNULL if( pExpr->op==TK_NOTNULL
&& pExpr->pLeft->op==TK_COLUMN && pExpr->pLeft->op==TK_COLUMN
&& pExpr->pLeft->iColumn>=0 && pExpr->pLeft->iColumn>=0
&& OptimizationEnabled(db, SQLITE_Stat3)
){ ){
Expr *pNewExpr; Expr *pNewExpr;
Expr *pLeft = pExpr->pLeft; Expr *pLeft = pExpr->pLeft;
@@ -2041,6 +2042,7 @@ static void constructAutomaticIndex(
WhereLoop *pLoop; /* The Loop object */ WhereLoop *pLoop; /* The Loop object */
Bitmask idxCols; /* Bitmap of columns used for indexing */ Bitmask idxCols; /* Bitmap of columns used for indexing */
Bitmask extraCols; /* Bitmap of additional columns */ Bitmask extraCols; /* Bitmap of additional columns */
u8 sentWarning = 0; /* True if a warnning has been issued */
/* Generate code to skip over the creation and initialization of the /* Generate code to skip over the creation and initialization of the
** transient index on 2nd and subsequent iterations of the loop. */ ** transient index on 2nd and subsequent iterations of the loop. */
@@ -2061,6 +2063,12 @@ static void constructAutomaticIndex(
Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol); Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
testcase( iCol==BMS ); testcase( iCol==BMS );
testcase( iCol==BMS-1 ); testcase( iCol==BMS-1 );
if( !sentWarning ){
sqlite3_log(SQLITE_WARNING_AUTOINDEX,
"automatic index on %s(%s)", pTable->zName,
pTable->aCol[iCol].zName);
sentWarning = 1;
}
if( (idxCols & cMask)==0 ){ if( (idxCols & cMask)==0 ){
if( whereLoopResize(pParse->db, pLoop, nColumn+1) ) return; if( whereLoopResize(pParse->db, pLoop, nColumn+1) ) return;
pLoop->aLTerm[nColumn++] = pTerm; pLoop->aLTerm[nColumn++] = pTerm;
@@ -2071,7 +2079,7 @@ static void constructAutomaticIndex(
assert( nColumn>0 ); assert( nColumn>0 );
pLoop->u.btree.nEq = pLoop->nLTerm = nColumn; pLoop->u.btree.nEq = pLoop->nLTerm = nColumn;
pLoop->wsFlags = WHERE_COLUMN_EQ | WHERE_IDX_ONLY | WHERE_INDEXED pLoop->wsFlags = WHERE_COLUMN_EQ | WHERE_IDX_ONLY | WHERE_INDEXED
| WHERE_TEMP_INDEX; | WHERE_AUTO_INDEX;
/* Count the number of additional columns needed to create a /* Count the number of additional columns needed to create a
** covering index. A "covering index" is an index that contains all ** covering index. A "covering index" is an index that contains all
@@ -2571,7 +2579,7 @@ static int whereRangeScanEst(
#ifdef SQLITE_ENABLE_STAT3 #ifdef SQLITE_ENABLE_STAT3
if( nEq==0 && p->nSample ){ if( nEq==0 && p->nSample && OptimizationEnabled(pParse->db, SQLITE_Stat3) ){
sqlite3_value *pRangeVal; sqlite3_value *pRangeVal;
tRowcnt iLower = 0; tRowcnt iLower = 0;
tRowcnt iUpper = p->aiRowEst[0]; tRowcnt iUpper = p->aiRowEst[0];
@@ -3117,13 +3125,12 @@ static void explainOneScan(
&& ALWAYS(pLoop->u.btree.pIndex!=0) && ALWAYS(pLoop->u.btree.pIndex!=0)
){ ){
char *zWhere = explainIndexRange(db, pLoop, pItem->pTab); char *zWhere = explainIndexRange(db, pLoop, pItem->pTab);
zMsg = sqlite3MAppendf(db, zMsg, "%s USING %s%sINDEX%s%s%s", zMsg, zMsg = sqlite3MAppendf(db, zMsg,
((flags & WHERE_TEMP_INDEX)?"AUTOMATIC ":""), ((flags & WHERE_AUTO_INDEX) ?
((flags & WHERE_IDX_ONLY)?"COVERING ":""), "%s USING AUTOMATIC %sINDEX%.0s%s" :
((flags & WHERE_TEMP_INDEX)?"":" "), "%s USING %sINDEX %s%s"),
((flags & WHERE_TEMP_INDEX)?"": pLoop->u.btree.pIndex->zName), zMsg, ((flags & WHERE_IDX_ONLY) ? "COVERING " : ""),
zWhere pLoop->u.btree.pIndex->zName, zWhere);
);
sqlite3DbFree(db, zWhere); sqlite3DbFree(db, zWhere);
}else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){ }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){
zMsg = sqlite3MAppendf(db, zMsg, "%s USING INTEGER PRIMARY KEY", zMsg); zMsg = sqlite3MAppendf(db, zMsg, "%s USING INTEGER PRIMARY KEY", zMsg);
@@ -3328,10 +3335,11 @@ static Bitmask codeOneLoopStart(
assert( TK_LT==TK_GT+2 ); /* ... of the TK_xx values... */ assert( TK_LT==TK_GT+2 ); /* ... of the TK_xx values... */
assert( TK_GE==TK_GT+3 ); /* ... is correcct. */ assert( TK_GE==TK_GT+3 ); /* ... is correcct. */
assert( (pStart->wtFlags & TERM_VNULL)==0 );
testcase( pStart->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */ testcase( pStart->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
pX = pStart->pExpr; pX = pStart->pExpr;
assert( pX!=0 ); assert( pX!=0 );
assert( pStart->leftCursor==iCur ); testcase( pStart->leftCursor!=iCur ); /* transitive constraints */
r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp); r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp);
sqlite3VdbeAddOp3(v, aMoveOp[pX->op-TK_GT], iCur, addrBrk, r1); sqlite3VdbeAddOp3(v, aMoveOp[pX->op-TK_GT], iCur, addrBrk, r1);
VdbeComment((v, "pk")); VdbeComment((v, "pk"));
@@ -3345,7 +3353,8 @@ static Bitmask codeOneLoopStart(
Expr *pX; Expr *pX;
pX = pEnd->pExpr; pX = pEnd->pExpr;
assert( pX!=0 ); assert( pX!=0 );
assert( pEnd->leftCursor==iCur ); assert( (pEnd->wtFlags & TERM_VNULL)==0 );
testcase( pEnd->leftCursor!=iCur ); /* Transitive constraints */
testcase( pEnd->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */ testcase( pEnd->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
memEndValue = ++pParse->nMem; memEndValue = ++pParse->nMem;
sqlite3ExprCode(pParse, pX->pRight, memEndValue); sqlite3ExprCode(pParse, pX->pRight, memEndValue);
@@ -3794,7 +3803,7 @@ static Bitmask codeOneLoopStart(
** be available. ** be available.
*/ */
pSubLoop = pSubWInfo->a[0].pWLoop; pSubLoop = pSubWInfo->a[0].pWLoop;
assert( (pSubLoop->wsFlags & WHERE_TEMP_INDEX)==0 ); assert( (pSubLoop->wsFlags & WHERE_AUTO_INDEX)==0 );
if( (pSubLoop->wsFlags & WHERE_INDEXED)!=0 if( (pSubLoop->wsFlags & WHERE_INDEXED)!=0
&& (ii==0 || pSubLoop->u.btree.pIndex==pCov) && (ii==0 || pSubLoop->u.btree.pIndex==pCov)
){ ){
@@ -3880,6 +3889,7 @@ static Bitmask codeOneLoopStart(
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
if( pTerm->eOperator!=(WO_EQUIV|WO_EQ) ) continue; if( pTerm->eOperator!=(WO_EQUIV|WO_EQ) ) continue;
if( pTerm->leftCursor!=iCur ) continue; if( pTerm->leftCursor!=iCur ) continue;
if( pLevel->iLeftJoin ) continue;
pE = pTerm->pExpr; pE = pTerm->pExpr;
assert( !ExprHasProperty(pE, EP_FromJoin) ); assert( !ExprHasProperty(pE, EP_FromJoin) );
assert( (pTerm->prereqRight & newNotReady)!=0 ); assert( (pTerm->prereqRight & newNotReady)!=0 );
@@ -3976,12 +3986,12 @@ static void whereLoopInit(WhereLoop *p){
** Clear the WhereLoop.u union. Leave WhereLoop.pLTerm intact. ** Clear the WhereLoop.u union. Leave WhereLoop.pLTerm intact.
*/ */
static void whereLoopClearUnion(sqlite3 *db, WhereLoop *p){ static void whereLoopClearUnion(sqlite3 *db, WhereLoop *p){
if( p->wsFlags & (WHERE_VIRTUALTABLE|WHERE_TEMP_INDEX) ){ if( p->wsFlags & (WHERE_VIRTUALTABLE|WHERE_AUTO_INDEX) ){
if( (p->wsFlags & WHERE_VIRTUALTABLE)!=0 && p->u.vtab.needFree ){ if( (p->wsFlags & WHERE_VIRTUALTABLE)!=0 && p->u.vtab.needFree ){
sqlite3_free(p->u.vtab.idxStr); sqlite3_free(p->u.vtab.idxStr);
p->u.vtab.needFree = 0; p->u.vtab.needFree = 0;
p->u.vtab.idxStr = 0; p->u.vtab.idxStr = 0;
}else if( (p->wsFlags & WHERE_TEMP_INDEX)!=0 && p->u.btree.pIndex!=0 ){ }else if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 && p->u.btree.pIndex!=0 ){
sqlite3DbFree(db, p->u.btree.pIndex->zColAff); sqlite3DbFree(db, p->u.btree.pIndex->zColAff);
sqlite3DbFree(db, p->u.btree.pIndex); sqlite3DbFree(db, p->u.btree.pIndex);
p->u.btree.pIndex = 0; p->u.btree.pIndex = 0;
@@ -4024,7 +4034,7 @@ static int whereLoopXfer(sqlite3 *db, WhereLoop *pTo, WhereLoop *pFrom){
memcpy(pTo->aLTerm, pFrom->aLTerm, pTo->nLTerm*sizeof(pTo->aLTerm[0])); memcpy(pTo->aLTerm, pFrom->aLTerm, pTo->nLTerm*sizeof(pTo->aLTerm[0]));
if( pFrom->wsFlags & WHERE_VIRTUALTABLE ){ if( pFrom->wsFlags & WHERE_VIRTUALTABLE ){
pFrom->u.vtab.needFree = 0; pFrom->u.vtab.needFree = 0;
}else if( (pFrom->wsFlags & WHERE_TEMP_INDEX)!=0 ){ }else if( (pFrom->wsFlags & WHERE_AUTO_INDEX)!=0 ){
pFrom->u.btree.pIndex = 0; pFrom->u.btree.pIndex = 0;
} }
return SQLITE_OK; return SQLITE_OK;
@@ -4274,6 +4284,11 @@ static int whereLoopAddBtreeIndex(
for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){ for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){
int nIn = 0; int nIn = 0;
if( pTerm->prereqRight & pNew->maskSelf ) continue; if( pTerm->prereqRight & pNew->maskSelf ) continue;
#ifdef SQLITE_ENABLE_STAT3
if( (pTerm->wtFlags & TERM_VNULL)!=0 && pSrc->pTab->aCol[iCol].notNull ){
continue; /* skip IS NOT NULL constraints on a NOT NULL column */
}
#endif
pNew->wsFlags = saved_wsFlags; pNew->wsFlags = saved_wsFlags;
pNew->u.btree.nEq = saved_nEq; pNew->u.btree.nEq = saved_nEq;
pNew->nLTerm = saved_nLTerm; pNew->nLTerm = saved_nLTerm;
@@ -4336,7 +4351,8 @@ static int whereLoopAddBtreeIndex(
pNew->nOut = saved_nOut>rDiv+10 ? saved_nOut - rDiv : 10; pNew->nOut = saved_nOut>rDiv+10 ? saved_nOut - rDiv : 10;
} }
#ifdef SQLITE_ENABLE_STAT3 #ifdef SQLITE_ENABLE_STAT3
if( pNew->u.btree.nEq==1 && pProbe->nSample ){ if( pNew->u.btree.nEq==1 && pProbe->nSample
&& OptimizationEnabled(db, SQLITE_Stat3) ){
tRowcnt nOut = 0; tRowcnt nOut = 0;
if( (pTerm->eOperator & (WO_EQ|WO_ISNULL))!=0 ){ if( (pTerm->eOperator & (WO_EQ|WO_ISNULL))!=0 ){
testcase( pTerm->eOperator & WO_EQ ); testcase( pTerm->eOperator & WO_EQ );
@@ -4420,7 +4436,7 @@ static Bitmask columnsInIndex(Index *pIdx){
/* /*
** Add all WhereLoop objects a single table of the join were the table ** Add all WhereLoop objects for a single table of the join where the table
** is idenfied by pBuilder->pNew->iTab. That table is guaranteed to be ** is idenfied by pBuilder->pNew->iTab. That table is guaranteed to be
** a b-tree table, not a virtual table. ** a b-tree table, not a virtual table.
*/ */
@@ -4496,13 +4512,16 @@ static int whereLoopAddBtree(
pNew->nLTerm = 1; pNew->nLTerm = 1;
pNew->aLTerm[0] = pTerm; pNew->aLTerm[0] = pTerm;
/* TUNING: One-time cost for computing the automatic index is /* TUNING: One-time cost for computing the automatic index is
** approximately 6*N*log2(N) where N is the number of rows in ** approximately 7*N*log2(N) where N is the number of rows in
** the table being indexed. */ ** the table being indexed. */
pNew->rSetup = rLogSize + rSize + 26; assert( 26==whereCost(6) ); pNew->rSetup = rLogSize + rSize + 28; assert( 28==whereCost(7) );
/* TUNING: Each index lookup yields 10 rows in the table */ /* TUNING: Each index lookup yields 20 rows in the table. This
pNew->nOut = 33; assert( 33==whereCost(10) ); ** is more than the usual guess of 10 rows, since we have no way
** of knowning how selective the index will ultimately be. It would
** not be unreasonable to make this value much larger. */
pNew->nOut = 43; assert( 43==whereCost(20) );
pNew->rRun = whereCostAdd(rLogSize,pNew->nOut); pNew->rRun = whereCostAdd(rLogSize,pNew->nOut);
pNew->wsFlags = WHERE_TEMP_INDEX; pNew->wsFlags = WHERE_AUTO_INDEX;
pNew->prereq = mExtra | pTerm->prereqRight; pNew->prereq = mExtra | pTerm->prereqRight;
rc = whereLoopInsert(pBuilder, pNew); rc = whereLoopInsert(pBuilder, pNew);
} }
@@ -4881,12 +4900,19 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
/* /*
** Examine a WherePath (with the addition of the extra WhereLoop of the 5th ** Examine a WherePath (with the addition of the extra WhereLoop of the 5th
** parameters) to see if it outputs rows in the requested ORDER BY ** parameters) to see if it outputs rows in the requested ORDER BY
** (or GROUP BY) without requiring a separate source operation. Return: ** (or GROUP BY) without requiring a separate sort operation. Return:
** **
** 0: ORDER BY is not satisfied. Sorting required ** 0: ORDER BY is not satisfied. Sorting required
** 1: ORDER BY is satisfied. Omit sorting ** 1: ORDER BY is satisfied. Omit sorting
** -1: Unknown at this time ** -1: Unknown at this time
** **
** Note that processing for WHERE_GROUPBY and WHERE_DISTINCTBY is not as
** strict. With GROUP BY and DISTINCT the only requirement is that
** equivalent rows appear immediately adjacent to one another. GROUP BY
** and DISTINT do not require rows to appear in any particular order as long
** as equivelent rows are grouped together. Thus for GROUP BY and DISTINCT
** the pOrderBy terms can be matched in any order. With ORDER BY, the
** pOrderBy terms must be matched in strict left-to-right order.
*/ */
static int wherePathSatisfiesOrderBy( static int wherePathSatisfiesOrderBy(
WhereInfo *pWInfo, /* The WHERE clause */ WhereInfo *pWInfo, /* The WHERE clause */
@@ -5134,7 +5160,7 @@ static const char *wherePathName(WherePath *pPath, int nLoop, WhereLoop *pLast){
/* /*
** Given the list of WhereLoop objects on pWInfo->pLoops, this routine ** Given the list of WhereLoop objects at pWInfo->pLoops, this routine
** attempts to find the lowest cost path that visits each WhereLoop ** attempts to find the lowest cost path that visits each WhereLoop
** once. This path is then loaded into the pWInfo->a[].pWLoop fields. ** once. This path is then loaded into the pWInfo->a[].pWLoop fields.
** **
@@ -5551,7 +5577,8 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){
** **
** ORDER BY CLAUSE PROCESSING ** ORDER BY CLAUSE PROCESSING
** **
** pOrderBy is a pointer to the ORDER BY clause of a SELECT statement, ** pOrderBy is a pointer to the ORDER BY clause (or the GROUP BY clause
** if the WHERE_GROUPBY flag is set in wctrlFlags) of a SELECT statement
** if there is one. If there is no ORDER BY clause or if this routine ** if there is one. If there is no ORDER BY clause or if this routine
** is called from an UPDATE or DELETE statement, then pOrderBy is NULL. ** is called from an UPDATE or DELETE statement, then pOrderBy is NULL.
*/ */
@@ -5643,6 +5670,7 @@ WhereInfo *sqlite3WhereBegin(
whereClauseInit(&pWInfo->sWC, pWInfo); whereClauseInit(&pWInfo->sWC, pWInfo);
sqlite3ExprCodeConstants(pParse, pWhere); sqlite3ExprCodeConstants(pParse, pWhere);
whereSplit(&pWInfo->sWC, pWhere, TK_AND); /* IMP: R-15842-53296 */ whereSplit(&pWInfo->sWC, pWhere, TK_AND); /* IMP: R-15842-53296 */
sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
/* Special case: a WHERE clause that is constant. Evaluate the /* Special case: a WHERE clause that is constant. Evaluate the
** expression and either jump over all of the code or fall thru. ** expression and either jump over all of the code or fall thru.
@@ -5796,6 +5824,7 @@ WhereInfo *sqlite3WhereBegin(
Bitmask tabUsed = exprListTableUsage(pMaskSet, pResultSet); Bitmask tabUsed = exprListTableUsage(pMaskSet, pResultSet);
if( pOrderBy ) tabUsed |= exprListTableUsage(pMaskSet, pOrderBy); if( pOrderBy ) tabUsed |= exprListTableUsage(pMaskSet, pOrderBy);
while( pWInfo->nLevel>=2 ){ while( pWInfo->nLevel>=2 ){
WhereTerm *pTerm, *pEnd;
pLoop = pWInfo->a[pWInfo->nLevel-1].pWLoop; pLoop = pWInfo->a[pWInfo->nLevel-1].pWLoop;
if( (pWInfo->pTabList->a[pLoop->iTab].jointype & JT_LEFT)==0 ) break; if( (pWInfo->pTabList->a[pLoop->iTab].jointype & JT_LEFT)==0 ) break;
if( (wctrlFlags & WHERE_WANT_DISTINCT)==0 if( (wctrlFlags & WHERE_WANT_DISTINCT)==0
@@ -5804,6 +5833,15 @@ WhereInfo *sqlite3WhereBegin(
break; break;
} }
if( (tabUsed & pLoop->maskSelf)!=0 ) break; if( (tabUsed & pLoop->maskSelf)!=0 ) break;
pEnd = sWLB.pWC->a + sWLB.pWC->nTerm;
for(pTerm=sWLB.pWC->a; pTerm<pEnd; pTerm++){
if( (pTerm->prereqAll & pLoop->maskSelf)!=0
&& !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
){
break;
}
}
if( pTerm<pEnd ) break;
WHERETRACE(0xffff, ("-> drop loop %c not used\n", pLoop->cId)); WHERETRACE(0xffff, ("-> drop loop %c not used\n", pLoop->cId));
pWInfo->nLevel--; pWInfo->nLevel--;
nTabList--; nTabList--;
@@ -5827,13 +5865,11 @@ WhereInfo *sqlite3WhereBegin(
/* Open all tables in the pTabList and any indices selected for /* Open all tables in the pTabList and any indices selected for
** searching those tables. ** searching those tables.
*/ */
sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
notReady = ~(Bitmask)0; notReady = ~(Bitmask)0;
for(ii=0, pLevel=pWInfo->a; ii<nTabList; ii++, pLevel++){ for(ii=0, pLevel=pWInfo->a; ii<nTabList; ii++, pLevel++){
Table *pTab; /* Table to open */ Table *pTab; /* Table to open */
int iDb; /* Index of database containing table/index */ int iDb; /* Index of database containing table/index */
struct SrcList_item *pTabItem; struct SrcList_item *pTabItem;
WhereLoop *pLoop;
pTabItem = &pTabList->a[pLevel->iFrom]; pTabItem = &pTabList->a[pLevel->iFrom];
pTab = pTabItem->pTab; pTab = pTabItem->pTab;
@@ -5869,7 +5905,7 @@ WhereInfo *sqlite3WhereBegin(
sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
} }
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX #ifndef SQLITE_OMIT_AUTOMATIC_INDEX
if( (pLoop->wsFlags & WHERE_TEMP_INDEX)!=0 ){ if( (pLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){
constructAutomaticIndex(pParse, &pWInfo->sWC, pTabItem, notReady, pLevel); constructAutomaticIndex(pParse, &pWInfo->sWC, pTabItem, notReady, pLevel);
}else }else
#endif #endif
@@ -5992,7 +6028,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
if( !pWInfo->okOnePass && (ws & WHERE_IDX_ONLY)==0 ){ if( !pWInfo->okOnePass && (ws & WHERE_IDX_ONLY)==0 ){
sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor); sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor);
} }
if( (ws & WHERE_INDEXED)!=0 && (ws & (WHERE_IPK|WHERE_TEMP_INDEX))==0 ){ if( (ws & WHERE_INDEXED)!=0 && (ws & (WHERE_IPK|WHERE_AUTO_INDEX))==0 ){
sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur); sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur);
} }
} }

View File

@@ -23,6 +23,14 @@ ifcapable {!autoindex} {
return return
} }
# Setup for logging
db close
sqlite3_shutdown
test_sqlite3_log [list lappend ::log]
set ::log [list]
sqlite3 db test.db
# With automatic index turned off, we do a full scan of the T2 table # With automatic index turned off, we do a full scan of the T2 table
do_test autoindex1-100 { do_test autoindex1-100 {
db eval { db eval {
@@ -60,6 +68,15 @@ do_test autoindex1-111 {
do_test autoindex1-112 { do_test autoindex1-112 {
db status autoindex db status autoindex
} {7} } {7}
do_test autoindex1-113 {
set ::log
} {SQLITE_WARNING_AUTOINDEX {automatic index on t2(c)}}
db close
sqlite3_shutdown
test_sqlite3_log
sqlite3_initialize
sqlite3 db test.db
# The same test as above, but this time the T2 query is a subquery rather # The same test as above, but this time the T2 query is a subquery rather
# than a join. # than a join.
@@ -94,9 +111,15 @@ do_test autoindex1-212 {
# Modify the second table of the join while the join is in progress # Modify the second table of the join while the join is in progress
# #
do_execsql_test autoindex1-299 {
UPDATE sqlite_stat1 SET stat='10000' WHERE tbl='t2';
ANALYZE sqlite_master;
EXPLAIN QUERY PLAN
SELECT b, d FROM t1 CROSS JOIN t2 ON (c=a);
} {/AUTOMATIC COVERING INDEX/}
do_test autoindex1-300 { do_test autoindex1-300 {
set r {} set r {}
db eval {SELECT b, d FROM t1 JOIN t2 ON (c=a)} { db eval {SELECT b, d FROM t1 CROSS JOIN t2 ON (c=a)} {
lappend r $b $d lappend r $b $d
db eval {UPDATE t2 SET d=d+1} db eval {UPDATE t2 SET d=d+1}
} }

View File

@@ -13,7 +13,6 @@ puts {# 2008 December 11
# This file is automatically generated from a separate TCL script. # This file is automatically generated from a separate TCL script.
# This file seeks to exercise integer boundary values. # This file seeks to exercise integer boundary values.
# #
# $Id: boundary3.tcl,v 1.3 2009/01/02 15:45:48 shane Exp $
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
@@ -40,16 +39,16 @@ foreach x {
} { } {
set x [expr {wide($x)}] set x [expr {wide($x)}]
set boundarynum($x) 1 set boundarynum($x) 1
set boundarynum([expr {$x+1}]) 1 set boundarynum([expr {wide($x+1)}]) 1
set boundarynum([expr {-($x+1)}]) 1 set boundarynum([expr {wide(-($x+1))}]) 1
set boundarynum([expr {-($x+2)}]) 1 set boundarynum([expr {wide(-($x+2))}]) 1
set boundarynum([expr {$x+$x+1}]) 1 set boundarynum([expr {wide($x+$x+1)}]) 1
set boundarynum([expr {$x+$x+2}]) 1 set boundarynum([expr {wide($x+$x+2)}]) 1
} }
set x [expr {wide(127)}] set x [expr {wide(127)}]
for {set i 1} {$i<=9} {incr i} { for {set i 1} {$i<=9} {incr i} {
set boundarynum($x) 1 set boundarynum($x) 1
set boundarynum([expr {$x+1}]) 1 set boundarynum([expr {wide($x+1)}]) 1
set x [expr {wide($x*128 + 127)}] set x [expr {wide($x*128 + 127)}]
} }
@@ -116,7 +115,7 @@ foreach r $nums1 {
incr a incr a
set t1ra($r) $a set t1ra($r) $a
set t1ar($a) $r set t1ar($a) $r
set x [format %08x%08x [expr {wide($r)>>32}] $r] set x [format %016x [expr {wide($r)}]]
set t1rx($r) $x set t1rx($r) $x
set t1xr($x) $r set t1xr($x) $r
puts " INSERT INTO t1(oid,a,x) VALUES($r,$a,'$x');" puts " INSERT INTO t1(oid,a,x) VALUES($r,$a,'$x');"
@@ -158,7 +157,7 @@ foreach r $nums3 {
set r5 $r.5 set r5 $r.5
set r0 $r.0 set r0 $r.0
if {abs($r)<9.22337203685477580800e+18} { if {abs($r)<0x7FFFFFFFFFFFFFFF || $r==-9223372036854775808} {
set x $t1rx($r) set x $t1rx($r)
set a $t1ra($r) set a $t1ra($r)
puts "do_test $tname-2.$i.1 \173" puts "do_test $tname-2.$i.1 \173"

View File

@@ -108,6 +108,13 @@ db eval {CREATE TABLE t1(x)}
test_is_readonly capi3d-2.3 {INSERT INTO t1 VALUES(5)} 0 test_is_readonly capi3d-2.3 {INSERT INTO t1 VALUES(5)} 0
test_is_readonly capi3d-2.4 {UPDATE t1 SET x=x+1 WHERE x<0} 0 test_is_readonly capi3d-2.4 {UPDATE t1 SET x=x+1 WHERE x<0} 0
test_is_readonly capi3d-2.5 {SELECT * FROM t1} 1 test_is_readonly capi3d-2.5 {SELECT * FROM t1} 1
ifcapable wal {
test_is_readonly capi3d-2.6 {PRAGMA journal_mode=WAL} 0
test_is_readonly capi3d-2.7 {PRAGMA wal_checkpoint} 0
}
test_is_readonly capi3d-2.8 {PRAGMA application_id=1234} 0
test_is_readonly capi3d-2.9 {VACUUM} 0
test_is_readonly capi3d-2.10 {PRAGMA integrity_check} 1
do_test capi3-2.99 { do_test capi3-2.99 {
sqlite3_stmt_readonly 0 sqlite3_stmt_readonly 0
} 1 } 1

View File

@@ -1294,7 +1294,7 @@ proc rev {str} {
set ret set ret
} }
proc reverse {lhs rhs} { proc reverse {lhs rhs} {
string compare [rev $lhs] [ref $rhs] string compare [rev $lhs] [rev $rhs]
} }
db collate reverse reverse db collate reverse reverse
do_execsql_test e_expr-23.1.1 { do_execsql_test e_expr-23.1.1 {
@@ -1317,7 +1317,7 @@ do_execsql_test e_expr-23.1.4 {
} {B} } {B}
do_execsql_test e_expr-23.1.5 { do_execsql_test e_expr-23.1.5 {
SELECT CASE b WHEN a THEN 'A' ELSE 'B' END FROM t1 SELECT CASE b WHEN a THEN 'A' ELSE 'B' END FROM t1
} {A} } {B}
do_execsql_test e_expr-23.1.6 { do_execsql_test e_expr-23.1.6 {
SELECT CASE 55 WHEN '55' THEN 'A' ELSE 'B' END SELECT CASE 55 WHEN '55' THEN 'A' ELSE 'B' END
} {B} } {B}

View File

@@ -94,7 +94,7 @@ sqlite3_shutdown
sqlite3_config_pagecache [expr 1024+$xtra_size] 20 sqlite3_config_pagecache [expr 1024+$xtra_size] 20
sqlite3_initialize sqlite3_initialize
reset_highwater_marks reset_highwater_marks
build_test_db memsubsys1-2 {PRAGMA page_size=1024} build_test_db memsubsys1-2 {PRAGMA page_size=1024; PRAGMA mmap_size=0}
#show_memstats #show_memstats
set MEMORY_MANAGEMENT $sqlite_options(memorymanage) set MEMORY_MANAGEMENT $sqlite_options(memorymanage)
ifcapable !malloc_usable_size { ifcapable !malloc_usable_size {

View File

@@ -12,7 +12,7 @@
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
ifcapable !mmap { ifcapable !mmap||!vtab {
finish_test finish_test
return return
} }

77
test/mmapfault.test Normal file
View File

@@ -0,0 +1,77 @@
# 2013-05-23
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/malloc_common.tcl
ifcapable !mmap {
finish_test
return
}
set testprefix mmapfault
set a_string_counter 1
proc a_string {n} {
global a_string_counter
incr a_string_counter
string range [string repeat "${a_string_counter}." $n] 1 $n
}
db func a_string a_string
do_test 1-pre {
execsql {
CREATE TABLE t1(a UNIQUE, b UNIQUE);
INSERT INTO t1 VALUES(a_string(200), a_string(300));
INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;
INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;
}
faultsim_save_and_close
} {}
do_faultsim_test 1 -prep {
faultsim_restore_and_reopen
db func a_string a_string
breakpoint
execsql {
PRAGMA mmap_size = 1000000;
PRAGMA cache_size = 5;
BEGIN;
INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;
INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;
INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;
INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;
}
} -body {
execsql { INSERT INTO t1 VALUES(a_string(200), a_string(300)) }
} -test {
faultsim_test_result {0 {}}
if {[sqlite3_get_autocommit db]} {
sqlite3 db2 test.db
set nRow [db2 one {SELECT count(*) FROM t1}]
if {$nRow!=4} { error "Database content appears incorrect (1)" }
db2 close
}
execsql { INSERT INTO t1 VALUES(a_string(201), a_string(301)) }
set nRow [db one {SELECT count(*) FROM t1}]
if {$nRow!=5 && $nRow!=66 && $nRow!=65} {
error "Database content appears incorrect (2) ($nRow)"
}
catch { execsql COMMIT }
}
finish_test

View File

@@ -44,6 +44,7 @@ do_test pcache-1.2 {
execsql { execsql {
PRAGMA cache_size=12; PRAGMA cache_size=12;
PRAGMA auto_vacuum=0; PRAGMA auto_vacuum=0;
PRAGMA mmap_size=0;
} }
pcache_stats pcache_stats
} {current 1 max 12 min 10 recyclable 1} } {current 1 max 12 min 10 recyclable 1}

View File

@@ -180,28 +180,30 @@ do_test percentile-1.21 {
# Million-row Inputs # Million-row Inputs
# #
do_test percentile-2.0 { ifcapable vtab {
load_static_extension db wholenumber do_test percentile-2.0 {
execsql { load_static_extension db wholenumber
CREATE VIRTUAL TABLE nums USING wholenumber;
CREATE TABLE t3(x);
INSERT INTO t3 SELECT value-1 FROM nums WHERE value BETWEEN 1 AND 500000;
INSERT INTO t3 SELECT value*10 FROM nums
WHERE value BETWEEN 500000 AND 999999;
SELECT count(*) FROM t3;
}
} {1000000}
foreach {in out} {
0 0.0
100 9999990.0
50 2749999.5
10 99999.9
} {
do_test percentile-2.1.$in {
execsql { execsql {
SELECT percentile(x, $in) from t3; CREATE VIRTUAL TABLE nums USING wholenumber;
CREATE TABLE t3(x);
INSERT INTO t3 SELECT value-1 FROM nums WHERE value BETWEEN 1 AND 500000;
INSERT INTO t3 SELECT value*10 FROM nums
WHERE value BETWEEN 500000 AND 999999;
SELECT count(*) FROM t3;
} }
} $out } {1000000}
foreach {in out} {
0 0.0
100 9999990.0
50 2749999.5
10 99999.9
} {
do_test percentile-2.1.$in {
execsql {
SELECT percentile(x, $in) from t3;
}
} $out
}
} }
finish_test finish_test

View File

@@ -450,5 +450,23 @@ do_test select9-5.3 {
} }
} {/SCAN TABLE/} ;# Full table scan if the "+x" prevents index usage. } {/SCAN TABLE/} ;# Full table scan if the "+x" prevents index usage.
# 2013-07-09: Ticket [490a4b7235624298]:
# "WHERE 0" on the first element of a UNION causes an assertion fault
#
do_execsql_test select9-6.1 {
CREATE TABLE t61(a);
CREATE TABLE t62(b);
INSERT INTO t61 VALUES(111);
INSERT INTO t62 VALUES(222);
SELECT a FROM t61 WHERE 0 UNION SELECT b FROM t62;
} {222}
do_execsql_test select9-6.2 {
SELECT a FROM t61 WHERE 0 UNION ALL SELECT b FROM t62;
} {222}
do_execsql_test select9-6.3 {
SELECT a FROM t61 UNION SELECT b FROM t62 WHERE 0;
} {111}
finish_test finish_test

View File

@@ -397,9 +397,9 @@ do_test shell1-3.11.1 {
do_test shell1-3.11.2 { do_test shell1-3.11.2 {
catchcmd "test.db" ".import FOO" catchcmd "test.db" ".import FOO"
} {1 {Error: unknown command or invalid arguments: "import". Enter ".help" for help}} } {1 {Error: unknown command or invalid arguments: "import". Enter ".help" for help}}
do_test shell1-3.11.2 { #do_test shell1-3.11.2 {
catchcmd "test.db" ".import FOO BAR" # catchcmd "test.db" ".import FOO BAR"
} {1 {Error: no such table: BAR}} #} {1 {Error: no such table: BAR}}
do_test shell1-3.11.3 { do_test shell1-3.11.3 {
# too many arguments # too many arguments
catchcmd "test.db" ".import FOO BAR BAD" catchcmd "test.db" ".import FOO BAR BAD"
@@ -710,6 +710,15 @@ do_test shell1-3-29.1 {
catchcmd "test.db" ".print this is a test" catchcmd "test.db" ".print this is a test"
} {0 {this is a test}} } {0 {this is a test}}
# dot-command argument quoting
do_test shell1-3-30.1 {
catchcmd {test.db} {.print "this\"is'a\055test" 'this\"is\\a\055test'}
} {0 {this"is'a-test this\"is\\a\055test}}
do_test shell1-3-31.1 {
catchcmd {test.db} {.print "this\nis\ta\\test" 'this\nis\ta\\test'}
} [list 0 "this\nis\ta\\test this\\nis\\ta\\\\test"]
# Test the output of the ".dump" command # Test the output of the ".dump" command
# #
do_test shell1-4.1 { do_test shell1-4.1 {

View File

@@ -45,9 +45,9 @@ do_test shell5-1.1.1 {
do_test shell5-1.1.2 { do_test shell5-1.1.2 {
catchcmd "test.db" ".import FOO" catchcmd "test.db" ".import FOO"
} {1 {Error: unknown command or invalid arguments: "import". Enter ".help" for help}} } {1 {Error: unknown command or invalid arguments: "import". Enter ".help" for help}}
do_test shell5-1.1.2 { #do_test shell5-1.1.2 {
catchcmd "test.db" ".import FOO BAR" # catchcmd "test.db" ".import FOO BAR"
} {1 {Error: no such table: BAR}} #} {1 {Error: no such table: BAR}}
do_test shell5-1.1.3 { do_test shell5-1.1.3 {
# too many arguments # too many arguments
catchcmd "test.db" ".import FOO BAR BAD" catchcmd "test.db" ".import FOO BAR BAD"
@@ -101,7 +101,7 @@ do_test shell5-1.4.3 {
puts $in "1" puts $in "1"
close $in close $in
set res [catchcmd "test.db" {.import shell5.csv t1}] set res [catchcmd "test.db" {.import shell5.csv t1}]
} {1 {Error: shell5.csv line 1: expected 2 columns of data but found 1}} } {1 {shell5.csv:1: expected 2 columns but found 1 - filling the rest with NULL}}
# import file with 1 row, 3 columns (expecting 2 cols) # import file with 1 row, 3 columns (expecting 2 cols)
do_test shell5-1.4.4 { do_test shell5-1.4.4 {
@@ -109,14 +109,15 @@ do_test shell5-1.4.4 {
puts $in "1|2|3" puts $in "1|2|3"
close $in close $in
set res [catchcmd "test.db" {.import shell5.csv t1}] set res [catchcmd "test.db" {.import shell5.csv t1}]
} {1 {Error: shell5.csv line 1: expected 2 columns of data but found 3}} } {1 {shell5.csv:1: expected 2 columns but found 3 - extras ignored}}
# import file with 1 row, 2 columns # import file with 1 row, 2 columns
do_test shell5-1.4.5 { do_test shell5-1.4.5 {
set in [open shell5.csv w] set in [open shell5.csv w]
puts $in "1|2" puts $in "1|2"
close $in close $in
set res [catchcmd "test.db" {.import shell5.csv t1 set res [catchcmd "test.db" {DELETE FROM t1;
.import shell5.csv t1
SELECT COUNT(*) FROM t1;}] SELECT COUNT(*) FROM t1;}]
} {0 1} } {0 1}
@@ -197,15 +198,15 @@ SELECT length(b) FROM t1 WHERE a='8';}]
# This is limited by SQLITE_MAX_VARIABLE_NUMBER, which defaults to 999. # This is limited by SQLITE_MAX_VARIABLE_NUMBER, which defaults to 999.
set cols 999 set cols 999
do_test shell5-1.6.1 { do_test shell5-1.6.1 {
set sql {CREATE TABLE t2(}
set data {} set data {}
for {set i 1} {$i<$cols} {incr i} { for {set i 1} {$i<$cols} {incr i} {
append sql "c$i," append data "c$i|"
}
append data "c$cols\n";
for {set i 1} {$i<$cols} {incr i} {
append data "$i|" append data "$i|"
} }
append sql "c$cols);"
append data "$cols" append data "$cols"
catchcmd "test.db" $sql
set in [open shell5.csv w] set in [open shell5.csv w]
puts $in $data puts $in $data
close $in close $in
@@ -214,16 +215,31 @@ SELECT COUNT(*) FROM t2;}]
} {0 1} } {0 1}
# try importing a large number of rows # try importing a large number of rows
set rows 999999 set rows 9999
do_test shell5-1.7.1 { do_test shell5-1.7.1 {
set in [open shell5.csv w] set in [open shell5.csv w]
puts $in a
for {set i 1} {$i<=$rows} {incr i} { for {set i 1} {$i<=$rows} {incr i} {
puts $in $i puts $in $i
} }
close $in close $in
set res [catchcmd "test.db" {CREATE TABLE t3(a); set res [catchcmd "test.db" {.mode csv
.import shell5.csv t3 .import shell5.csv t3
SELECT COUNT(*) FROM t3;}] SELECT COUNT(*) FROM t3;}]
} [list 0 $rows] } [list 0 $rows]
# Inport from a pipe. (Unix only, as it requires "awk")
if {$tcl_platform(platform)=="unix"} {
do_test shell5-1.8 {
file delete -force test.db
catchcmd test.db {.mode csv
.import "|awk 'END{print \"x,y\";for(i=1;i<=5;i++){print i \",this is \" i}}'" t1
SELECT * FROM t1;}
} {0 {1,"this is 1"
2,"this is 2"
3,"this is 3"
4,"this is 4"
5,"this is 5"}}
}
finish_test finish_test

View File

@@ -105,6 +105,22 @@ do_test 1.14 {
catchsql {SELECT next_char('','xyzzy','a')} catchsql {SELECT next_char('','xyzzy','a')}
} {1 {no such table: xyzzy}} } {1 {no such table: xyzzy}}
do_execsql_test 1.20 {
CREATE TABLE vocab2(w TEXT);
CREATE INDEX vocab2w ON vocab2(w COLLATE nocase);
INSERT INTO vocab2 VALUES('abc'), ('ABD'), ('aBe'), ('AbF');
SELECT next_char('ab', 'vocab2', 'w', null, 'nocase');
} {cDeF}
do_execsql_test 1.21 {
SELECT next_char('ab','vocab2','w',null,null);
} {c}
do_execsql_test 1.22 {
SELECT next_char('AB','vocab2','w',null,'NOCASE');
} {cDeF}
do_execsql_test 1.23 {
SELECT next_char('ab','vocab2','w',null,'binary');
} {c}
do_execsql_test 2.1 { do_execsql_test 2.1 {
CREATE VIRTUAL TABLE t2 USING spellfix1; CREATE VIRTUAL TABLE t2 USING spellfix1;
INSERT INTO t2 (word, soundslike) VALUES('school', 'skuul'); INSERT INTO t2 (word, soundslike) VALUES('school', 'skuul');

64
test/tkt-868145d012.test Normal file
View File

@@ -0,0 +1,64 @@
# 2013 March 05
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library. Specifically,
# it tests that ticket [868145d012a1] is fixed.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
do_execsql_test tkt-868145d012.100 {
CREATE TABLE p (
id INTEGER PRIMARY KEY,
uid VARCHAR(36),
t INTEGER
);
CREATE TABLE pa (
id INTEGER PRIMARY KEY,
a_uid VARCHAR(36)
);
CREATE TABLE a (
id INTEGER PRIMARY KEY,
uid VARCHAR(36),
t INTEGER
);
INSERT INTO pa VALUES(1,'1234');
INSERT INTO pa VALUES(2,'2345');
INSERT INTO p VALUES(3,'1234',97);
INSERT INTO p VALUES(4,'1234',98);
INSERT INTO a VALUES(5,'1234',98);
INSERT INTO a VALUES(6,'1234',99);
} {}
do_execsql_test tkt-868145d012.110 {
SELECT DISTINCT pa.id, p.id, a.id
FROM
pa
LEFT JOIN p ON p.uid='1234'
LEFT JOIN a ON a.uid=pa.a_uid
WHERE
a.t=p.t
;
} {1 4 5}
do_execsql_test tkt-868145d012.120 {
SELECT DISTINCT pa.id, p.id, a.id
FROM
pa
LEFT JOIN p ON p.uid='1234'
LEFT JOIN a ON a.uid=pa.a_uid AND a.t=p.t
ORDER BY 1, 2, 3
;
} {1 3 {} 1 4 5 2 3 {} 2 4 {}}
finish_test

View File

@@ -47,4 +47,59 @@ do_execsql_test transitive1-220 {
SELECT * FROM t2 WHERE a=b AND c=b AND c<=20 ORDER BY +a; SELECT * FROM t2 WHERE a=b AND c=b AND c<=20 ORDER BY +a;
} {20 20 20 100 100 100} } {20 20 20 100 100 100}
# Test cases for ticket [[d805526eae253103] 2013-07-08
# "Incorrect join result or assertion fault due to transitive constraints"
#
do_execsql_test transitive1-300 {
CREATE TABLE t301(w INTEGER PRIMARY KEY, x);
CREATE TABLE t302(y INTEGER UNIQUE, z);
INSERT INTO t301 VALUES(1,2),(3,4),(5,6);
INSERT INTO t302 VALUES(1,3),(3,6),(5,7);
SELECT *
FROM t301 CROSS JOIN t302
WHERE w=y AND y IS NOT NULL
ORDER BY +w;
} {1 2 1 3 3 4 3 6 5 6 5 7}
do_execsql_test transitive1-301 {
SELECT *
FROM t301 CROSS JOIN t302
WHERE w=y AND y IS NOT NULL
ORDER BY w;
} {1 2 1 3 3 4 3 6 5 6 5 7}
do_execsql_test transitive1-310 {
SELECT *
FROM t301 CROSS JOIN t302 ON w=y
WHERE y>1
ORDER BY +w
} {3 4 3 6 5 6 5 7}
do_execsql_test transitive1-311 {
SELECT *
FROM t301 CROSS JOIN t302 ON w=y
WHERE y>1
ORDER BY w
} {3 4 3 6 5 6 5 7}
do_execsql_test transitive1-312 {
SELECT *
FROM t301 CROSS JOIN t302 ON w=y
WHERE y>1
ORDER BY w DESC
} {5 6 5 7 3 4 3 6}
do_execsql_test transitive1-320 {
SELECT *
FROM t301 CROSS JOIN t302 ON w=y
WHERE y BETWEEN 2 AND 4;
} {3 4 3 6}
do_execsql_test transitive1-331 {
SELECT *
FROM t301 CROSS JOIN t302 ON w=y
WHERE y BETWEEN 1 AND 4
ORDER BY w;
} {1 2 1 3 3 4 3 6}
do_execsql_test transitive1-332 {
SELECT *
FROM t301 CROSS JOIN t302 ON w=y
WHERE y BETWEEN 1 AND 4
ORDER BY w DESC;
} {3 4 3 6 1 2 1 3}
finish_test finish_test

View File

@@ -14,6 +14,7 @@
# #
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
set testprefix wal6
source $testdir/tester.tcl source $testdir/tester.tcl
source $testdir/lock_common.tcl source $testdir/lock_common.tcl
source $testdir/wal_common.tcl source $testdir/wal_common.tcl
@@ -29,18 +30,18 @@ forcedelete test.db
set all_journal_modes {delete persist truncate memory off} set all_journal_modes {delete persist truncate memory off}
foreach jmode $all_journal_modes { foreach jmode $all_journal_modes {
do_test wal6-1.0.$jmode { do_test wal6-1.0.$jmode {
sqlite3 db test.db sqlite3 db test.db
execsql "PRAGMA journal_mode = $jmode;" execsql "PRAGMA journal_mode = $jmode;"
} $jmode } $jmode
do_test wal6-1.1.$jmode { do_test wal6-1.1.$jmode {
execsql { execsql {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b); CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
INSERT INTO t1 VALUES(1,2); INSERT INTO t1 VALUES(1,2);
SELECT * FROM t1; SELECT * FROM t1;
} }
} {1 2} } {1 2}
# Under Windows, you'll get an error trying to delete # Under Windows, you'll get an error trying to delete
# a file this is already opened. Close the first connection # a file this is already opened. Close the first connection
@@ -51,31 +52,146 @@ if {$tcl_platform(platform)=="windows"} {
} }
} }
do_test wal6-1.2.$jmode { do_test wal6-1.2.$jmode {
sqlite3 db2 test.db sqlite3 db2 test.db
execsql { execsql {
PRAGMA journal_mode=WAL; PRAGMA journal_mode=WAL;
INSERT INTO t1 VALUES(3,4); INSERT INTO t1 VALUES(3,4);
SELECT * FROM t1 ORDER BY a; SELECT * FROM t1 ORDER BY a;
} db2 } db2
} {wal 1 2 3 4} } {wal 1 2 3 4}
if {$tcl_platform(platform)=="windows"} { if {$tcl_platform(platform)=="windows"} {
if {$jmode=="persist" || $jmode=="truncate"} { if {$jmode=="persist" || $jmode=="truncate"} {
sqlite3 db test.db sqlite3 db test.db
} }
} }
do_test wal6-1.3.$jmode { do_test wal6-1.3.$jmode {
execsql { execsql {
SELECT * FROM t1 ORDER BY a; SELECT * FROM t1 ORDER BY a;
} }
} {1 2 3 4} } {1 2 3 4}
db close db close
db2 close db2 close
forcedelete test.db forcedelete test.db
} }
#-------------------------------------------------------------------------
# Test that SQLITE_BUSY_SNAPSHOT is returned as expected.
#
reset_db
sqlite3 db2 test.db
do_execsql_test 2.1 {
PRAGMA journal_mode = WAL;
CREATE TABLE t1(a PRIMARY KEY, b TEXT);
INSERT INTO t1 VALUES(1, 'one');
INSERT INTO t1 VALUES(2, 'two');
BEGIN;
SELECT * FROM t1;
} {wal 1 one 2 two}
do_test 2.2 {
execsql {
SELECT * FROM t1;
INSERT INTO t1 VALUES(3, 'three');
} db2
} {1 one 2 two}
do_catchsql_test 2.3 {
INSERT INTO t1 VALUES('x', 'x')
} {1 {database is locked}}
do_test 2.4 {
list [sqlite3_errcode db] [sqlite3_extended_errcode db]
} {SQLITE_BUSY SQLITE_BUSY_SNAPSHOT}
do_execsql_test 2.5 {
SELECT * FROM t1;
COMMIT;
INSERT INTO t1 VALUES('x', 'x')
} {1 one 2 two}
proc test3 {prefix} {
do_test $prefix.1 {
execsql { SELECT count(*) FROM t1 }
} {0}
do_test $prefix.2 {
execsql { INSERT INTO t1 VALUES('x', 'x') } db2
} {}
do_test $prefix.3 {
execsql { INSERT INTO t1 VALUES('y', 'y') }
} {}
do_test $prefix.4 {
execsql { SELECT count(*) FROM t1 }
} {2}
}
do_execsql_test 2.6.1 { DELETE FROM t1 }
test3 2.6.2
db func test3 test3
do_execsql_test 2.6.3 { DELETE FROM t1 }
db eval {SELECT test3('2.6.4')}
do_test 2.x {
db2 close
} {}
#-------------------------------------------------------------------------
# Check that if BEGIN IMMEDIATE fails, it does not leave the user with
# an open read-transaction (unless one was already open before the BEGIN
# IMMEDIATE). Even if there are other active VMs.
#
proc test4 {prefix} {
do_test $prefix.1 {
catchsql { BEGIN IMMEDIATE }
} {1 {database is locked}}
do_test $prefix.2 {
execsql { COMMIT } db2
} {}
do_test $prefix.3 {
execsql { BEGIN IMMEDIATE }
} {}
do_test $prefix.4 {
execsql { COMMIT }
} {}
}
reset_db
sqlite3 db2 test.db
do_execsql_test 3.1 {
PRAGMA journal_mode = WAL;
CREATE TABLE ab(a PRIMARY KEY, b);
} {wal}
do_test 3.2.1 {
execsql {
BEGIN;
INSERT INTO ab VALUES(1, 2);
} db2
} {}
test4 3.2.2
db func test4 test4
do_test 3.3.1 {
execsql {
BEGIN;
INSERT INTO ab VALUES(3, 4);
} db2
} {}
db eval {SELECT test4('3.3.2')}
do_test 3.x {
db2 close
} {}
finish_test finish_test

View File

@@ -307,6 +307,8 @@ do_test where2-6.6 {
} }
} [list 1 0 4 4 2 1 9 10 sort a i1w b $::idx] } [list 1 0 4 4 2 1 9 10 sort a i1w b $::idx]
if {[permutation] != "no_optimization"} {
# Ticket #2249. Make sure the OR optimization is not attempted if # Ticket #2249. Make sure the OR optimization is not attempted if
# comparisons between columns of different affinities are needed. # comparisons between columns of different affinities are needed.
# #
@@ -474,6 +476,8 @@ do_test where2-7.4 {
} }
} {1 2 3 2 3 nosort} } {1 2 3 2 3 nosort}
} ;# if {[permutation] != "no_optimization"}
# Ticket #1807. Using IN constrains on multiple columns of # Ticket #1807. Using IN constrains on multiple columns of
# a multi-column index. # a multi-column index.
# #

View File

@@ -436,5 +436,48 @@ foreach predicate {
} {1 w-one x-one y-one z-one 9 w-nine x-nine y-nine z-nine} } {1 w-one x-one y-one z-one 9 w-nine x-nine y-nine z-nine}
} }
do_execsql_test where3-7-setup {
CREATE TABLE t71(x1 INTEGER PRIMARY KEY, y1);
CREATE TABLE t72(x2 INTEGER PRIMARY KEY, y2);
CREATE TABLE t73(x3, y3);
CREATE TABLE t74(x4, y4);
INSERT INTO t71 VALUES(123,234);
INSERT INTO t72 VALUES(234,345);
INSERT INTO t73 VALUES(123,234);
INSERT INTO t74 VALUES(234,345);
INSERT INTO t74 VALUES(234,678);
} {}
foreach disabled_opt {none omit-noop-join all} {
optimization_control db all 1
optimization_control db $disabled_opt 0
do_execsql_test where3-7.$disabled_opt.1 {
SELECT x1 FROM t71 LEFT JOIN t72 ON x2=y1;
} {123}
do_execsql_test where3-7.$disabled_opt.2 {
SELECT x1 FROM t71 LEFT JOIN t72 ON x2=y1 WHERE y2 IS NULL;
} {}
do_execsql_test where3-7.$disabled_opt.3 {
SELECT x1 FROM t71 LEFT JOIN t72 ON x2=y1 WHERE y2 IS NOT NULL;
} {123}
do_execsql_test where3-7.$disabled_opt.4 {
SELECT x1 FROM t71 LEFT JOIN t72 ON x2=y1 AND y2 IS NULL;
} {123}
do_execsql_test where3-7.$disabled_opt.5 {
SELECT x1 FROM t71 LEFT JOIN t72 ON x2=y1 AND y2 IS NOT NULL;
} {123}
do_execsql_test where3-7.$disabled_opt.6 {
SELECT x3 FROM t73 LEFT JOIN t72 ON x2=y3;
} {123}
do_execsql_test where3-7.$disabled_opt.7 {
SELECT DISTINCT x3 FROM t73 LEFT JOIN t72 ON x2=y3;
} {123}
do_execsql_test where3-7.$disabled_opt.8 {
SELECT x3 FROM t73 LEFT JOIN t74 ON x4=y3;
} {123 123}
do_execsql_test where3-7.$disabled_opt.9 {
SELECT DISTINCT x3 FROM t73 LEFT JOIN t74 ON x4=y3;
} {123}
}
finish_test finish_test

311
test/wild001.test Normal file
View File

@@ -0,0 +1,311 @@
# 2013-07-01
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This is a test case from content taken "from the wild". In this
# particular instance, the query was provided with permission by
# Elan Feingold on 2013-06-27. His message on the SQLite mailing list
# on that date reads:
#
#------------------------------------------------------------------------------
# > Can you send (1) the schema (2) the query that is giving problems, and (3)
# > the content of the sqlite_stat1 table after you have run ANALYZE? If you
# > can combine all of the above into a script, that would be great!
# >
# > If you send (1..3) above and you give us written permission to include the
# > query in our test suite, that would be off-the-chain terrific.
#
# Please find items 1..3 in this file: http://www.plexapp.com/elan/sqlite_bug.txt
#
# You have our permission to include the query in your test suite.
#
# Thanks for an amazing product.
#-----------------------------------------------------------------------------
#
# This test case merely creates the schema and populates SQLITE_STAT1 and
# SQLITE_STAT3 then runs an EXPLAIN QUERY PLAN to ensure that the right plan
# is discovered. This test case may need to be adjusted for future revisions
# of the query planner manage to select a better query plan. The query plan
# shown here is known to be very fast with the original data.
#
# This test should work the same with and without SQLITE_ENABLE_STAT3
#
###############################################################################
set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable !stat3 {
finish_test
return
}
do_execsql_test wild001.01 {
CREATE TABLE "items" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "secid" integer, "parent_id" integer, "metadata_type" integer, "guid" varchar(255), "media_item_count" integer, "title" varchar(255), "title_sort" varchar(255) COLLATE NOCASE, "original_title" varchar(255), "studio" varchar(255), "rating" float, "rating_count" integer, "tagline" varchar(255), "summary" text, "trivia" text, "quotes" text, "content_rating" varchar(255), "content_rating_age" integer, "index" integer, "absolute_index" integer, "duration" integer, "user_thumb_url" varchar(255), "user_art_url" varchar(255), "user_banner_url" varchar(255), "user_music_url" varchar(255), "user_fields" varchar(255), "tags_genre" varchar(255), "tags_collection" varchar(255), "tags_director" varchar(255), "tags_writer" varchar(255), "tags_star" varchar(255), "originally_available_at" datetime, "available_at" datetime, "expires_at" datetime, "refreshed_at" datetime, "year" integer, "added_at" datetime, "created_at" datetime, "updated_at" datetime, "deleted_at" datetime, "tags_country" varchar(255), "extra_data" varchar(255), "hash" varchar(255));
CREATE INDEX "i_secid" ON "items" ("secid" );
CREATE INDEX "i_parent_id" ON "items" ("parent_id" );
CREATE INDEX "i_created_at" ON "items" ("created_at" );
CREATE INDEX "i_index" ON "items" ("index" );
CREATE INDEX "i_title" ON "items" ("title" );
CREATE INDEX "i_title_sort" ON "items" ("title_sort" );
CREATE INDEX "i_guid" ON "items" ("guid" );
CREATE INDEX "i_metadata_type" ON "items" ("metadata_type" );
CREATE INDEX "i_deleted_at" ON "items" ("deleted_at" );
CREATE INDEX "i_secid_ex1" ON "items" ("secid", "metadata_type", "added_at" );
CREATE INDEX "i_hash" ON "items" ("hash" );
CREATE TABLE "settings" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "account_id" integer, "guid" varchar(255), "rating" float, "view_offset" integer, "view_count" integer, "last_viewed_at" datetime, "created_at" datetime, "updated_at" datetime);
CREATE INDEX "s_account_id" ON "settings" ("account_id" );
CREATE INDEX "s_guid" ON "settings" ("guid" );
ANALYZE;
INSERT INTO sqlite_stat1 VALUES('settings','s_guid','4740 1');
INSERT INTO sqlite_stat1 VALUES('settings','s_account_id','4740 4740');
INSERT INTO sqlite_stat1 VALUES('items','i_hash','27316 2');
INSERT INTO sqlite_stat1 VALUES('items','i_secid_ex1','27316 6829 4553 3');
INSERT INTO sqlite_stat1 VALUES('items','i_deleted_at','27316 27316');
INSERT INTO sqlite_stat1 VALUES('items','i_metadata_type','27316 6829');
INSERT INTO sqlite_stat1 VALUES('items','i_guid','27316 2');
INSERT INTO sqlite_stat1 VALUES('items','i_title_sort','27316 2');
INSERT INTO sqlite_stat1 VALUES('items','i_title','27316 2');
INSERT INTO sqlite_stat1 VALUES('items','i_index','27316 144');
INSERT INTO sqlite_stat1 VALUES('items','i_created_at','27316 2');
INSERT INTO sqlite_stat1 VALUES('items','i_parent_id','27316 15');
INSERT INTO sqlite_stat1 VALUES('items','i_secid','27316 6829');
INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,150,150,'com.plexapp.agents.thetvdb://153021/2/9?lang=en');
INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,198,198,'com.plexapp.agents.thetvdb://194031/1/10?lang=en');
INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,526,526,'com.plexapp.agents.thetvdb://71256/12/92?lang=en');
INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,923,923,'com.plexapp.agents.thetvdb://71256/15/16?lang=en');
INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,1008,1008,'com.plexapp.agents.thetvdb://71256/15/93?lang=en');
INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,1053,1053,'com.plexapp.agents.thetvdb://71256/16/21?lang=en');
INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,1068,1068,'com.plexapp.agents.thetvdb://71256/16/35?lang=en');
INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,1235,1235,'com.plexapp.agents.thetvdb://71256/17/44?lang=en');
INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,1255,1255,'com.plexapp.agents.thetvdb://71256/17/62?lang=en');
INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,1573,1573,'com.plexapp.agents.thetvdb://71663/20/9?lang=en');
INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,1580,1580,'com.plexapp.agents.thetvdb://71663/21/16?lang=en');
INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,2000,2000,'com.plexapp.agents.thetvdb://73141/9/8?lang=en');
INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,2107,2107,'com.plexapp.agents.thetvdb://73244/6/17?lang=en');
INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,2256,2256,'com.plexapp.agents.thetvdb://74845/4/7?lang=en');
INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,2408,2408,'com.plexapp.agents.thetvdb://75978/2/21?lang=en');
INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,2634,2634,'com.plexapp.agents.thetvdb://79126/1/1?lang=en');
INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,2962,2962,'com.plexapp.agents.thetvdb://79274/3/94?lang=en');
INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,3160,3160,'com.plexapp.agents.thetvdb://79274/5/129?lang=en');
INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,3161,3161,'com.plexapp.agents.thetvdb://79274/5/12?lang=en');
INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,3688,3688,'com.plexapp.agents.thetvdb://79274/8/62?lang=en');
INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,3714,3714,'com.plexapp.agents.thetvdb://79274/8/86?lang=en');
INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,4002,4002,'com.plexapp.agents.thetvdb://79590/13/17?lang=en');
INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,4215,4215,'com.plexapp.agents.thetvdb://80727/3/6?lang=en');
INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,4381,4381,'com.plexapp.agents.thetvdb://83462/3/24?lang=en');
INSERT INTO sqlite_stat3 VALUES('settings','s_account_id',4740,0,0,1);
INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,1879,1879,'1113f632ccd52ec8b8d7ca3d6d56da4701e48018');
INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,2721,2721,'1936154b97bb5567163edaebc2806830ae419ccf');
INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,3035,3035,'1c122331d4b7bfa0dc2c003ab5fb4f7152b9987a');
INSERT INTO sqlite_stat3 VALUES('items','i_hash',2,3393,3393,'1f81bdbc9acc3321dc592b1a109ca075731b549a');
INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,6071,6070,'393cf7713efb4519c7a3d1d5403f0d945d15a16a');
INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,7462,7461,'4677dd37011f8bd9ae7fbbdd3af6dcd8a5b4ab2d');
INSERT INTO sqlite_stat3 VALUES('items','i_hash',2,8435,8434,'4ffa339485334e81a5e12e03a63b6508d76401cf');
INSERT INTO sqlite_stat3 VALUES('items','i_hash',2,8716,8714,'52a093852e6599dd5004857b7ff5b5b82c7cdb25');
INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,9107,9104,'561183e39f866d97ec728e9ff16ac4ad01466111');
INSERT INTO sqlite_stat3 VALUES('items','i_hash',2,10942,10939,'66e99b72e29610f49499ae09ee04a376210d1f08');
INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,12143,12139,'71f0602427e173dc2c551535f73fdb6885fe4302');
INSERT INTO sqlite_stat3 VALUES('items','i_hash',2,14962,14958,'8ca8e4dfba696019830c19ab8a32c7ece9d8534b');
INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,15179,15174,'8ebf1a5cf33f8ada1fc5853ac06ac4d7e074f825');
INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,15375,15370,'908bc211bebdf21c79d2d2b54ebaa442ac1f5cae');
INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,18215,18210,'ab29e4e18ec5a14fef95aa713d69e31c045a22c1');
INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,18615,18610,'ae84c008cc0c338bf4f28d798a88575746452f6d');
INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,18649,18644,'aec7c901353e115aa5307e94018ba7507bec3a45');
INSERT INTO sqlite_stat3 VALUES('items','i_hash',2,19517,19512,'b75025fbf2e9c504e3c1197ff1b69250402a31f8');
INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,21251,21245,'c7d32f0e3a8f3a0a3dbd00833833d2ccee62f0fd');
INSERT INTO sqlite_stat3 VALUES('items','i_hash',2,23616,23610,'dd5ff61479a9bd4100de802515d9dcf72d46f07a');
INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,24287,24280,'e3db00034301b7555419d4ef6f64769298d5845e');
INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,24949,24942,'ea336abd197ecd7013854a25a4f4eb9dea7927c6');
INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,25574,25567,'f018ea5182ec3f32768ca1c3cefbf3ad160ec20b');
INSERT INTO sqlite_stat3 VALUES('items','i_hash',2,26139,26132,'f53709a8d81c12cb0f4f8d58004a25dd063de67c');
INSERT INTO sqlite_stat3 VALUES('items','i_secid_ex1',25167,0,0,2);
INSERT INTO sqlite_stat3 VALUES('items','i_secid_ex1',736,25167,1,3);
INSERT INTO sqlite_stat3 VALUES('items','i_secid_ex1',15,25903,2,4);
INSERT INTO sqlite_stat3 VALUES('items','i_secid_ex1',1398,25918,3,5);
INSERT INTO sqlite_stat3 VALUES('items','i_deleted_at',27316,0,0,NULL);
INSERT INTO sqlite_stat3 VALUES('items','i_metadata_type',2149,0,0,1);
INSERT INTO sqlite_stat3 VALUES('items','i_metadata_type',411,2149,1,2);
INSERT INTO sqlite_stat3 VALUES('items','i_metadata_type',1440,2560,2,3);
INSERT INTO sqlite_stat3 VALUES('items','i_metadata_type',23316,4000,3,4);
INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,215,215,'com.plexapp.agents.imdb://tt0065702?lang=en');
INSERT INTO sqlite_stat3 VALUES('items','i_guid',2,711,711,'com.plexapp.agents.imdb://tt0198781?lang=en');
INSERT INTO sqlite_stat3 VALUES('items','i_guid',2,987,986,'com.plexapp.agents.imdb://tt0454876?lang=en');
INSERT INTO sqlite_stat3 VALUES('items','i_guid',2,1004,1002,'com.plexapp.agents.imdb://tt0464154?lang=en');
INSERT INTO sqlite_stat3 VALUES('items','i_guid',2,1056,1053,'com.plexapp.agents.imdb://tt0499549?lang=en');
INSERT INTO sqlite_stat3 VALUES('items','i_guid',2,1120,1116,'com.plexapp.agents.imdb://tt0903624?lang=en');
INSERT INTO sqlite_stat3 VALUES('items','i_guid',2,1250,1245,'com.plexapp.agents.imdb://tt1268799?lang=en');
INSERT INTO sqlite_stat3 VALUES('items','i_guid',2,1270,1264,'com.plexapp.agents.imdb://tt1320261?lang=en');
INSERT INTO sqlite_stat3 VALUES('items','i_guid',2,1376,1369,'com.plexapp.agents.imdb://tt1772341?lang=en');
INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,3035,3027,'com.plexapp.agents.thetvdb://153021/3/14?lang=en');
INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,6071,6063,'com.plexapp.agents.thetvdb://71173/1/18?lang=en');
INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,6342,6334,'com.plexapp.agents.thetvdb://71256/13/4?lang=en');
INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,9107,9099,'com.plexapp.agents.thetvdb://72389/2/19?lang=en');
INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,11740,11732,'com.plexapp.agents.thetvdb://73893/2/13?lang=en');
INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,12143,12135,'com.plexapp.agents.thetvdb://73976/4/23?lang=en');
INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,15179,15171,'com.plexapp.agents.thetvdb://75897/16/12?lang=en');
INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,17408,17400,'com.plexapp.agents.thetvdb://76808/2/16?lang=en');
INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,17984,17976,'com.plexapp.agents.thetvdb://77068/1/16?lang=en');
INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,18215,18207,'com.plexapp.agents.thetvdb://77259/1/1?lang=en');
INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,21251,21243,'com.plexapp.agents.thetvdb://78957/8/2?lang=en');
INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,24287,24279,'com.plexapp.agents.thetvdb://80337/5/8?lang=en');
INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,25513,25505,'com.plexapp.agents.thetvdb://82226/6?lang=en');
INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,25548,25540,'com.plexapp.agents.thetvdb://82339/2/10?lang=en');
INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,26770,26762,'com.plexapp.agents.thetvdb://86901/1/3?lang=en');
INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',1524,0,0,'');
INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',2,3034,1391,'Attack of the Giant Squid');
INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',51,4742,2895,'Brad Sherwood');
INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',11,4912,2996,'Brian Williams');
INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',39,5847,3857,'Chip Esten');
INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',1,6071,4015,'Chuck Versus the DeLorean');
INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',12,7625,5436,'Denny Siegel');
INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',30,8924,6618,'Episode 1');
INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',29,9015,6629,'Episode 2');
INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',32,9082,6643,'Episode 3');
INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',28,9135,6654,'Episode 4');
INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',26,9183,6665,'Episode 5');
INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',27,9229,6677,'Episode 6');
INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',22,9266,6688,'Episode 7');
INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',20,9298,6699,'Episode 8');
INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',55,11750,8817,'Greg Proops');
INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',1,12143,9120,'Hardware Jungle');
INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',33,14712,11435,'Kathy Greenwood');
INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',3,15179,11840,'Last Call');
INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',1,18215,14601,'Nature or Nurture?');
INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',12,18241,14623,'Neil DeGrasse Tyson');
INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',68,19918,16144,'Pilot');
INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',7,21251,17298,'Reza Aslan');
INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',1,24287,20035,'Technoviking');
INSERT INTO sqlite_stat3 VALUES('items','i_title',1524,0,0,'');
INSERT INTO sqlite_stat3 VALUES('items','i_title',1,3035,1429,'Anderson Can''t Dance');
INSERT INTO sqlite_stat3 VALUES('items','i_title',51,4782,2991,'Brad Sherwood');
INSERT INTO sqlite_stat3 VALUES('items','i_title',11,4936,3079,'Brian Williams');
INSERT INTO sqlite_stat3 VALUES('items','i_title',39,5694,3783,'Chip Esten');
INSERT INTO sqlite_stat3 VALUES('items','i_title',1,6071,4100,'Clive Warren');
INSERT INTO sqlite_stat3 VALUES('items','i_title',12,7144,5078,'Denny Siegel');
INSERT INTO sqlite_stat3 VALUES('items','i_title',30,8249,6097,'Episode 1');
INSERT INTO sqlite_stat3 VALUES('items','i_title',29,8340,6108,'Episode 2');
INSERT INTO sqlite_stat3 VALUES('items','i_title',32,8407,6122,'Episode 3');
INSERT INTO sqlite_stat3 VALUES('items','i_title',28,8460,6133,'Episode 4');
INSERT INTO sqlite_stat3 VALUES('items','i_title',26,8508,6144,'Episode 5');
INSERT INTO sqlite_stat3 VALUES('items','i_title',27,8554,6156,'Episode 6');
INSERT INTO sqlite_stat3 VALUES('items','i_title',22,8591,6167,'Episode 7');
INSERT INTO sqlite_stat3 VALUES('items','i_title',20,8623,6178,'Episode 8');
INSERT INTO sqlite_stat3 VALUES('items','i_title',1,9107,6537,'Fat Albert and the Cosby Kids');
INSERT INTO sqlite_stat3 VALUES('items','i_title',55,10539,7843,'Greg Proops');
INSERT INTO sqlite_stat3 VALUES('items','i_title',1,12143,9276,'Iron Age Remains');
INSERT INTO sqlite_stat3 VALUES('items','i_title',33,13118,10143,'Kathy Greenwood');
INSERT INTO sqlite_stat3 VALUES('items','i_title',1,15179,11972,'Mink');
INSERT INTO sqlite_stat3 VALUES('items','i_title',68,17411,14035,'Pilot');
INSERT INTO sqlite_stat3 VALUES('items','i_title',2,18214,14727,'Reflections');
INSERT INTO sqlite_stat3 VALUES('items','i_title',4,21250,17481,'The Apartment');
INSERT INTO sqlite_stat3 VALUES('items','i_title',1,24287,20283,'The Simpsons Already Did It');
INSERT INTO sqlite_stat3 VALUES('items','i_index',4315,95,2,1);
INSERT INTO sqlite_stat3 VALUES('items','i_index',1553,4410,3,2);
INSERT INTO sqlite_stat3 VALUES('items','i_index',1485,5963,4,3);
INSERT INTO sqlite_stat3 VALUES('items','i_index',1414,7448,5,4);
INSERT INTO sqlite_stat3 VALUES('items','i_index',1367,8862,6,5);
INSERT INTO sqlite_stat3 VALUES('items','i_index',1328,10229,7,6);
INSERT INTO sqlite_stat3 VALUES('items','i_index',1161,11557,8,7);
INSERT INTO sqlite_stat3 VALUES('items','i_index',1108,12718,9,8);
INSERT INTO sqlite_stat3 VALUES('items','i_index',1033,13826,10,9);
INSERT INTO sqlite_stat3 VALUES('items','i_index',1014,14859,11,10);
INSERT INTO sqlite_stat3 VALUES('items','i_index',929,15873,12,11);
INSERT INTO sqlite_stat3 VALUES('items','i_index',906,16802,13,12);
INSERT INTO sqlite_stat3 VALUES('items','i_index',844,17708,14,13);
INSERT INTO sqlite_stat3 VALUES('items','i_index',690,18552,15,14);
INSERT INTO sqlite_stat3 VALUES('items','i_index',655,19242,16,15);
INSERT INTO sqlite_stat3 VALUES('items','i_index',625,19897,17,16);
INSERT INTO sqlite_stat3 VALUES('items','i_index',579,20522,18,17);
INSERT INTO sqlite_stat3 VALUES('items','i_index',555,21101,19,18);
INSERT INTO sqlite_stat3 VALUES('items','i_index',526,21656,20,19);
INSERT INTO sqlite_stat3 VALUES('items','i_index',501,22182,21,20);
INSERT INTO sqlite_stat3 VALUES('items','i_index',459,22683,22,21);
INSERT INTO sqlite_stat3 VALUES('items','i_index',439,23142,23,22);
INSERT INTO sqlite_stat3 VALUES('items','i_index',315,23581,24,23);
INSERT INTO sqlite_stat3 VALUES('items','i_index',192,24177,26,25);
INSERT INTO sqlite_stat3 VALUES('items','i_created_at',1851,0,0,NULL);
INSERT INTO sqlite_stat3 VALUES('items','i_created_at',373,1857,2,'2011-10-22 14:54:39');
INSERT INTO sqlite_stat3 VALUES('items','i_created_at',595,2230,3,'2011-10-22 14:54:41');
INSERT INTO sqlite_stat3 VALUES('items','i_created_at',337,2825,4,'2011-10-22 14:54:43');
INSERT INTO sqlite_stat3 VALUES('items','i_created_at',361,3378,8,'2011-10-22 14:54:54');
INSERT INTO sqlite_stat3 VALUES('items','i_created_at',160,3739,9,'2011-10-22 14:54:56');
INSERT INTO sqlite_stat3 VALUES('items','i_created_at',315,4000,11,'2011-10-22 14:54:59');
INSERT INTO sqlite_stat3 VALUES('items','i_created_at',321,4334,13,'2011-10-22 14:55:02');
INSERT INTO sqlite_stat3 VALUES('items','i_created_at',1292,4723,16,'2011-10-22 14:55:06');
INSERT INTO sqlite_stat3 VALUES('items','i_created_at',161,6015,17,'2011-10-22 14:55:07');
INSERT INTO sqlite_stat3 VALUES('items','i_created_at',1,9107,2677,'2012-09-04 18:07:50');
INSERT INTO sqlite_stat3 VALUES('items','i_created_at',313,9717,3270,'2012-10-18 16:50:21');
INSERT INTO sqlite_stat3 VALUES('items','i_created_at',450,10030,3271,'2012-10-18 16:50:22');
INSERT INTO sqlite_stat3 VALUES('items','i_created_at',389,10668,3275,'2012-10-18 16:50:26');
INSERT INTO sqlite_stat3 VALUES('items','i_created_at',796,11057,3276,'2012-10-18 16:51:06');
INSERT INTO sqlite_stat3 VALUES('items','i_created_at',161,12041,3280,'2012-10-19 19:52:37');
INSERT INTO sqlite_stat3 VALUES('items','i_created_at',135,13281,4186,'2013-02-19 00:56:10');
INSERT INTO sqlite_stat3 VALUES('items','i_created_at',1063,13416,4187,'2013-02-19 00:56:11');
INSERT INTO sqlite_stat3 VALUES('items','i_created_at',797,14479,4188,'2013-02-19 00:56:13');
INSERT INTO sqlite_stat3 VALUES('items','i_created_at',147,15276,4189,'2013-02-19 00:56:15');
INSERT INTO sqlite_stat3 VALUES('items','i_created_at',346,15423,4190,'2013-02-19 00:56:16');
INSERT INTO sqlite_stat3 VALUES('items','i_created_at',1,18215,6436,'2013-05-05 14:09:54');
INSERT INTO sqlite_stat3 VALUES('items','i_created_at',2,21251,8122,'2013-05-24 15:25:45');
INSERT INTO sqlite_stat3 VALUES('items','i_created_at',1,24287,11116,'2013-05-26 14:17:39');
INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',2560,0,0,NULL);
INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',18,3022,31,2350);
INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',10,6068,285,8150);
INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',158,6346,315,8949);
INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',34,9094,562,18831);
INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',20,12139,794,22838);
INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',134,14033,886,24739);
INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',159,14167,887,24740);
INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',161,14326,888,24741);
INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',161,14487,889,24742);
INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',124,14648,890,24743);
INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',157,14772,891,24744);
INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',126,15043,894,24747);
INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',40,15169,895,24748);
INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',161,15243,898,24753);
INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',138,15404,899,24754);
INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',160,15542,900,24755);
INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',161,15702,901,24756);
INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',161,15863,902,24757);
INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',124,16024,903,24758);
INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',155,16148,904,24759);
INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',26,18208,1043,29704);
INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',2,21251,1282,32952);
INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',13,24279,1583,36068);
INSERT INTO sqlite_stat3 VALUES('items','i_secid',25167,0,0,2);
INSERT INTO sqlite_stat3 VALUES('items','i_secid',736,25167,1,3);
INSERT INTO sqlite_stat3 VALUES('items','i_secid',15,25903,2,4);
INSERT INTO sqlite_stat3 VALUES('items','i_secid',1398,25918,3,5);
ANALYZE sqlite_master;
explain query plan
select items.title
from items
join items as child on child.parent_id=items.id
join items as grandchild on grandchild.parent_id=child.id
join settings
on settings.guid=grandchild.guid
and settings.account_id=1
where items.metadata_type=2
and items.secid=2
and settings.last_viewed_at is not null
group by items.id
order by settings.last_viewed_at desc
limit 10;
} [list \
0 0 3 {SEARCH TABLE settings USING INDEX s_account_id (account_id=?)} \
0 1 2 {SEARCH TABLE items AS grandchild USING INDEX i_guid (guid=?)} \
0 2 1 {SEARCH TABLE items AS child USING INTEGER PRIMARY KEY (rowid=?)} \
0 3 0 {SEARCH TABLE items USING INTEGER PRIMARY KEY (rowid=?)} \
0 0 0 {USE TEMP B-TREE FOR GROUP BY} \
0 0 0 {USE TEMP B-TREE FOR ORDER BY}]
finish_test