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:
@@ -3335,8 +3335,11 @@ int sqlite3Fts1Init(sqlite3 *db){
|
||||
}
|
||||
|
||||
#if !SQLITE_CORE
|
||||
int sqlite3_extension_init(sqlite3 *db, char **pzErrMsg,
|
||||
const sqlite3_api_routines *pApi){
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
int sqlite3_fts1_init(sqlite3 *db, char **pzErrMsg,
|
||||
const sqlite3_api_routines *pApi){
|
||||
SQLITE_EXTENSION_INIT2(pApi)
|
||||
return sqlite3Fts1Init(db);
|
||||
}
|
||||
|
@@ -852,8 +852,14 @@ static void fulltext_vtab_destroy(fulltext_vtab *v){
|
||||
** argv[3] - tokenizer name (optional, a sensible default is provided)
|
||||
** argv[4..] - passed to tokenizer (optional based on tokenizer)
|
||||
**/
|
||||
static int fulltextConnect(sqlite3 *db, void *pAux, int argc, char **argv,
|
||||
sqlite3_vtab **ppVTab){
|
||||
static int fulltextConnect(
|
||||
sqlite3 *db,
|
||||
void *pAux,
|
||||
int argc,
|
||||
const char * const *argv,
|
||||
sqlite3_vtab **ppVTab,
|
||||
char **pzErr
|
||||
){
|
||||
int rc;
|
||||
fulltext_vtab *v;
|
||||
sqlite3_tokenizer_module *m = NULL;
|
||||
@@ -898,8 +904,14 @@ static int fulltextConnect(sqlite3 *db, void *pAux, int argc, char **argv,
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
static int fulltextCreate(sqlite3 *db, void *pAux, int argc, char **argv,
|
||||
sqlite3_vtab **ppVTab){
|
||||
static int fulltextCreate(
|
||||
sqlite3 *db,
|
||||
void *pAux,
|
||||
int argc,
|
||||
const char * const *argv,
|
||||
sqlite3_vtab **ppVTab,
|
||||
char **pzErr
|
||||
){
|
||||
int rc;
|
||||
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)");
|
||||
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.
|
||||
@@ -1488,8 +1500,11 @@ int fulltext_init(sqlite3 *db){
|
||||
}
|
||||
|
||||
#if !SQLITE_CORE
|
||||
int sqlite3_extension_init(sqlite3 *db, char **pzErrMsg,
|
||||
const sqlite3_api_routines *pApi){
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
int sqlite3_fulltext_init(sqlite3 *db, char **pzErrMsg,
|
||||
const sqlite3_api_routines *pApi){
|
||||
SQLITE_EXTENSION_INIT2(pApi)
|
||||
return fulltext_init(db);
|
||||
}
|
||||
|
@@ -6844,7 +6844,10 @@ int sqlite3Fts2Init(sqlite3 *db){
|
||||
}
|
||||
|
||||
#if !SQLITE_CORE
|
||||
int sqlite3_extension_init(
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
int sqlite3_fts2_init(
|
||||
sqlite3 *db,
|
||||
char **pzErrMsg,
|
||||
const sqlite3_api_routines *pApi
|
||||
|
@@ -30,6 +30,8 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "sqlite3.h"
|
||||
#include "sqlite3ext.h"
|
||||
SQLITE_EXTENSION_INIT3
|
||||
#include "fts2_hash.h"
|
||||
|
||||
/*
|
||||
|
@@ -30,6 +30,9 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "sqlite3.h"
|
||||
#include "sqlite3ext.h"
|
||||
SQLITE_EXTENSION_INIT3
|
||||
#include "fts2_tokenizer.h"
|
||||
|
||||
/*
|
||||
|
@@ -28,7 +28,7 @@
|
||||
|
||||
#include "sqlite3.h"
|
||||
#include "sqlite3ext.h"
|
||||
SQLITE_EXTENSION_INIT1
|
||||
SQLITE_EXTENSION_INIT3
|
||||
|
||||
#include "fts2_hash.h"
|
||||
#include "fts2_tokenizer.h"
|
||||
|
@@ -30,6 +30,9 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "sqlite3.h"
|
||||
#include "sqlite3ext.h"
|
||||
SQLITE_EXTENSION_INIT3
|
||||
#include "fts2_tokenizer.h"
|
||||
|
||||
typedef struct simple_tokenizer {
|
||||
|
@@ -1095,7 +1095,7 @@ static int fts3InitVtab(
|
||||
nByte = sizeof(const char *) * (argc-2);
|
||||
aCol = (const char **)sqlite3_malloc(nByte);
|
||||
if( aCol ){
|
||||
memset(aCol, 0, nByte);
|
||||
memset((void*)aCol, 0, nByte);
|
||||
azNotindexed = (char **)sqlite3_malloc(nByte);
|
||||
}
|
||||
if( azNotindexed ){
|
||||
@@ -1346,7 +1346,7 @@ static int fts3InitVtab(
|
||||
|
||||
/* Fill in the abNotindexed array */
|
||||
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++){
|
||||
char *zNot = azNotindexed[i];
|
||||
if( zNot && 0==sqlite3_strnicmp(p->azColumn[iCol], zNot, n) ){
|
||||
@@ -5376,7 +5376,10 @@ int sqlite3Fts3Corrupt(){
|
||||
/*
|
||||
** Initialize API pointer table, if required.
|
||||
*/
|
||||
int sqlite3_extension_init(
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
int sqlite3_fts3_init(
|
||||
sqlite3 *db,
|
||||
char **pzErrMsg,
|
||||
const sqlite3_api_routines *pApi
|
||||
|
@@ -32,7 +32,7 @@
|
||||
/* If not building as part of the core, include sqlite3ext.h. */
|
||||
#ifndef SQLITE_CORE
|
||||
# include "sqlite3ext.h"
|
||||
extern const sqlite3_api_routines *sqlite3_api;
|
||||
SQLITE_EXTENSION_INIT3
|
||||
#endif
|
||||
|
||||
#include "sqlite3.h"
|
||||
|
@@ -488,7 +488,10 @@ int sqlite3IcuInit(sqlite3 *db){
|
||||
}
|
||||
|
||||
#if !SQLITE_CORE
|
||||
int sqlite3_extension_init(
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
int sqlite3_icu_init(
|
||||
sqlite3 *db,
|
||||
char **pzErrMsg,
|
||||
const sqlite3_api_routines *pApi
|
||||
|
@@ -18,11 +18,11 @@
|
||||
**
|
||||
** 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
|
||||
** 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
|
||||
** 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:
|
||||
**
|
||||
|
@@ -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
|
||||
** string A given the vocabulary in T.F. The T.F field should be indexed.
|
||||
** If the W value exists and is a non-empty string, then it is an SQL
|
||||
** expression that limits the entries in T.F that will be considered.
|
||||
** The next_char(A,T,F,W,C) function finds all valid "next" characters for
|
||||
** string A given the vocabulary in T.F. If the W value exists and is a
|
||||
** non-empty string, then it is an SQL expression that limits the entries
|
||||
** 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:
|
||||
**
|
||||
@@ -184,6 +194,9 @@ static void nextCharFunc(
|
||||
const unsigned char *zTable = sqlite3_value_text(argv[1]);
|
||||
const unsigned char *zField = sqlite3_value_text(argv[2]);
|
||||
const unsigned char *zWhere;
|
||||
const unsigned char *zCollName;
|
||||
char *zWhereClause = 0;
|
||||
char *zColl = 0;
|
||||
char *zSql;
|
||||
int rc;
|
||||
|
||||
@@ -192,25 +205,41 @@ static void nextCharFunc(
|
||||
c.zPrefix = sqlite3_value_text(argv[0]);
|
||||
c.nPrefix = sqlite3_value_bytes(argv[0]);
|
||||
if( zTable==0 || zField==0 || c.zPrefix==0 ) return;
|
||||
if( argc<4
|
||||
|| (zWhere = sqlite3_value_text(argv[3]))==0
|
||||
|| zWhere[0]==0
|
||||
if( argc>=4
|
||||
&& (zWhere = sqlite3_value_text(argv[3]))!=0
|
||||
&& zWhere[0]!=0
|
||||
){
|
||||
zSql = sqlite3_mprintf(
|
||||
"SELECT \"%w\" FROM \"%w\""
|
||||
" WHERE \"%w\">=(?1 || ?2)"
|
||||
" AND \"%w\"<=(?1 || char(1114111))" /* 1114111 == 0x10ffff */
|
||||
" ORDER BY 1 ASC LIMIT 1",
|
||||
zField, zTable, zField, zField);
|
||||
zWhereClause = sqlite3_mprintf("AND (%s)", zWhere);
|
||||
if( zWhereClause==0 ){
|
||||
sqlite3_result_error_nomem(context);
|
||||
return;
|
||||
}
|
||||
}else{
|
||||
zSql = sqlite3_mprintf(
|
||||
"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);
|
||||
zWhereClause = "";
|
||||
}
|
||||
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 ){
|
||||
sqlite3_result_error_nomem(context);
|
||||
return;
|
||||
@@ -261,5 +290,9 @@ int sqlite3_nextchar_init(
|
||||
rc = sqlite3_create_function(db, "next_char", 4, SQLITE_UTF8, 0,
|
||||
nextCharFunc, 0, 0);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3_create_function(db, "next_char", 5, SQLITE_UTF8, 0,
|
||||
nextCharFunc, 0, 0);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
@@ -190,7 +190,7 @@ static void percentFinal(sqlite3_context *pCtx){
|
||||
if( p->nUsed ){
|
||||
qsort(p->a, p->nUsed, sizeof(double), doubleCmp);
|
||||
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;
|
||||
v1 = p->a[i1];
|
||||
v2 = p->a[i2];
|
||||
|
547
ext/misc/vtshim.c
Normal file
547
ext/misc/vtshim.c
Normal 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;
|
||||
}
|
@@ -3350,7 +3350,10 @@ int sqlite3_rtree_geometry_callback(
|
||||
}
|
||||
|
||||
#if !SQLITE_CORE
|
||||
int sqlite3_extension_init(
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
int sqlite3_rtree_init(
|
||||
sqlite3 *db,
|
||||
char **pzErrMsg,
|
||||
const sqlite3_api_routines *pApi
|
||||
|
118
manifest
118
manifest
@@ -1,5 +1,5 @@
|
||||
C Fix\sa\sbug\spreventing\ssome\sFK\sconstraint\schecking\sfrom\sbeing\sdeferred\suntil\sthe\send\sof\schangeset\sapplication.
|
||||
D 2013-07-04T15:22:53.953
|
||||
C Pull\sin\sall\sthe\slatest\schanges\sfrom\strunk.
|
||||
D 2013-07-09T13:05:49.248
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in aff38bc64c582dd147f18739532198372587b0f0
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@@ -51,36 +51,36 @@ F ext/async/sqlite3async.h f489b080af7e72aec0e1ee6f1d98ab6cf2e4dcef
|
||||
F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e
|
||||
F ext/fts1/ft_hash.c 3927bd880e65329bdc6f506555b228b28924921b
|
||||
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_hash.c 3196cee866edbebb1c0521e21672e6d599965114
|
||||
F ext/fts1/fts1_hash.h e7f0d761353996a8175eda351104acfde23afcb0
|
||||
F ext/fts1/fts1_porter.c b1c7304b8988ba3f764a147cdd32043b4913ea7b
|
||||
F ext/fts1/fts1_tokenizer.h fdea722c38a9f82ed921642981234f666e47919c
|
||||
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/simple_tokenizer.c 1844d72f7194c3fd3d7e4173053911bf0661b70d
|
||||
F ext/fts1/tokenizer.h 0c53421b832366d20d720d21ea3e1f6e66a36ef9
|
||||
F ext/fts2/README.tokenizers 21e3684ea5a095b55d70f6878b4ce6af5932dfb7
|
||||
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_hash.c 2689e42e1107ea67207f725cf69cf8972d00cf93
|
||||
F ext/fts2/fts2_hash.c 011a1d32de45bb1b519a1fd0048e857d6a843558
|
||||
F ext/fts2/fts2_hash.h 1824b99dfd8d0225facbdb26a2c87289b2e7dcf8
|
||||
F ext/fts2/fts2_icu.c 51c5cd3c04954badd329fa738c95fcdb717b5188
|
||||
F ext/fts2/fts2_porter.c 747056987951f743e955c8479f1df21a565720fe
|
||||
F ext/fts2/fts2_tokenizer.c a86d08c9634fabfa237c8f379008de2e11248d36
|
||||
F ext/fts2/fts2_porter.c 2cd4a507bf3c3085fe66f59b0f2a325f65aaacf5
|
||||
F ext/fts2/fts2_tokenizer.c 3dbe8058e97afb55fff3ea844120ce3208b114cc
|
||||
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/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51
|
||||
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
|
||||
F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314
|
||||
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/fts3Int.h a50cd231e906da818f00f0a81845bbf7bbeba002
|
||||
F ext/fts3/fts3Int.h c7a451661c2d9b2440b2008c3f63ce06f13181d6
|
||||
F ext/fts3/fts3_aux.c b02632f6dd0e375ce97870206d914ea6d8df5ccd
|
||||
F ext/fts3/fts3_expr.c f8eb1046063ba342c7114eba175cabb31c4a64e7
|
||||
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/mkunicode.tcl dc6f268eb526710e2c6e496c372471d773d0c368
|
||||
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/misc/amatch.c eae8454cd9dcb287b2a3ec2e65a865a4ac5f0d06
|
||||
F ext/misc/closure.c 997c20ddf35f85ab399f4a02a557a9baa822ec32
|
||||
F ext/misc/fuzzer.c 136533c53cfce0957f0b48fa11dba27e21c5c01d
|
||||
F ext/misc/ieee754.c 2565ce373d842977efe0922dc50b8a41b3289556
|
||||
F ext/misc/nextchar.c 1131e2b36116ffc6fe6b2e3464bfdace27978b1e
|
||||
F ext/misc/percentile.c 4fb5e46c4312b0be74e8e497ac18f805f0e3e6c5
|
||||
F ext/misc/ieee754.c b0362167289170627659e84173f5d2e8fee8566e
|
||||
F ext/misc/nextchar.c 80ba262d23238efcfcb3d72d71aa4513098e26a6
|
||||
F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63
|
||||
F ext/misc/regexp.c c25c65fe775f5d9801fb8573e36ebe73f2c0c2e0
|
||||
F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a
|
||||
F ext/misc/spellfix.c 6d7ce6105a4b7729f6c44ccdf1ab7e80d9707c02
|
||||
F ext/misc/vtshim.c 5fb6be7fe37659a8cbd1e16982d74cceacbc4543
|
||||
F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212
|
||||
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/rtree1.test cf679265ecafff494a768ac9c2f43a70915a6290
|
||||
F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba
|
||||
@@ -154,7 +155,7 @@ F magic.txt f2b23a6bde8f1c6e86b957e4d94eab0add520b0d
|
||||
F main.mk f045701c66fec66208bc35d79de372340916e81e
|
||||
F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a
|
||||
F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f
|
||||
F mkextw.sh 4123480947681d9b434a5e7b1ee08135abe409ac
|
||||
F mkextw.sh d2a981497b404d6498f5ff3e3b1f3816bdfcb338
|
||||
F mkopcodec.awk f6fccee29e68493bfd90a2e0466ede5fa94dd2fc
|
||||
F mkopcodeh.awk 29b84656502eee5f444c3147f331ee686956ab0e
|
||||
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
|
||||
@@ -175,7 +176,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
|
||||
F src/backup.c 43b348822db3e4cef48b2ae5a445fbeb6c73a165
|
||||
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
|
||||
F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
|
||||
F src/btree.c 7fba377c29573adfc6091832e27ee1fcbefb51d0
|
||||
F src/btree.c 3f7bbfd72efb1cbf6a49515c376a031767ec930a
|
||||
F src/btree.h 6fa8a3ff2483d0bb64a9f0105a8cedeac9e00cca
|
||||
F src/btreeInt.h eecc84f02375b2bb7a44abbcbbe3747dde73edb2
|
||||
F src/build.c 42239cfd95533e4aacf4d58b4724c8f858de5ced
|
||||
@@ -197,7 +198,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
|
||||
F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12
|
||||
F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
|
||||
F src/loadext.c c48f7f3f170e502fe0cc20748e03c6e0b5a016c2
|
||||
F src/main.c 893986530b7ea4607643675babf08888cb63e48e
|
||||
F src/main.c a27560235a8e0e3f1a94aaca30189431bf61e776
|
||||
F src/malloc.c fe085aa851b666b7c375c1ff957643dc20a04bf6
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c 437c7c4af964895d4650f29881df63535caaa1fa
|
||||
@@ -216,7 +217,7 @@ F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f
|
||||
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
|
||||
F src/os_unix.c 9eafa5458cf2ff684ddccff82c9bb113c7cad847
|
||||
F src/os_win.c 074cb2b9bca6a1c2bd72acf04666cdc554bfaa9b
|
||||
F src/pager.c 79df56da9dd49aceaa4cac207484a9a82cba40ae
|
||||
F src/pager.c 5d2f7475260a8588f9c441bb309d2b7eaa7ded3b
|
||||
F src/pager.h 5cb78b8e1adfd5451e600be7719f5a99d87ac3b1
|
||||
F src/parse.y 9acfcc83ddbf0cf82f0ed9582ccf0ad6c366ff37
|
||||
F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
|
||||
@@ -224,21 +225,21 @@ F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
|
||||
F src/pcache1.c d23d07716de96c7c0c2503ec5051a4384c3fb938
|
||||
F src/pragma.c 057f5b1343c9a79e3e6c0c542a3a08b85849ee61
|
||||
F src/prepare.c 2306be166bbeddf454e18bf8b21dba8388d05328
|
||||
F src/printf.c bff529ed47657098c55c9910b9c69b1b3b1a1353
|
||||
F src/printf.c 41c49dac366a3a411190001a8ab495fa8887974e
|
||||
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
|
||||
F src/resolve.c 89f9003e8316ee3a172795459efc2a0274e1d5a8
|
||||
F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
|
||||
F src/select.c 91b62654caf8dfe292fb8882715e575d34ad3874
|
||||
F src/shell.c a02544af6697c5782d29ec3204616f35ed9e8458
|
||||
F src/sqlite.h.in 0693f95792b64cca4d1780c082d7b96fd32aa1c3
|
||||
F src/shell.c c8cd06e6b66250a3ea0149c4edec30de14f57b6f
|
||||
F src/sqlite.h.in fb8adf7852fb92e410de422b5569923327bf8a2c
|
||||
F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0
|
||||
F src/sqlite3ext.h d936f797812c28b81b26ed18345baf8db28a21a5
|
||||
F src/sqliteInt.h 5a005fde923b3755fa3184e60028c582a8efe01d
|
||||
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
|
||||
F src/sqliteInt.h a83b0cef30022c46a19e6ace1f668b7833935eed
|
||||
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
||||
F src/status.c bedc37ec1a6bb9399944024d63f4c769971955a9
|
||||
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
||||
F src/tclsqlite.c e0eaf3a78eca2ef650abb67b6571cc86abcb5f87
|
||||
F src/test1.c 06bd01f7795bbef4aaf59d3b9fe5b3131a6ef642
|
||||
F src/test1.c 870fc648a48cb6d6808393174f7ebe82b8c840fa
|
||||
F src/test2.c 7355101c085304b90024f2261e056cdff13c6c35
|
||||
F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c
|
||||
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.h 8761e463b25e75ebc078bd67d70e39b9c817a0cb
|
||||
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_sqllog.c c1c1bbedbcaf82b93d83e4f9dd990e62476a680e
|
||||
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_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa
|
||||
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_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||
F src/tokenize.c 1e86210d3976717a19238ea7b047fac481fe8c12
|
||||
F src/tokenize.c e0e8fd3cb90a88451f6b6425726c84747b6b20d7
|
||||
F src/trigger.c 5c0ea9b8755e7c5e1a700f3e27ac4f8d92dd221e
|
||||
F src/update.c 19daebf6a0a67af5524913e93498d08388792128
|
||||
F src/utf.c 8d819e2e5104a430fc2005f018db14347c95a38f
|
||||
F src/util.c f566b5138099a2df8533b190d0dcc74b7dfbe0c9
|
||||
F src/vacuum.c ddf21cc9577c4cb459d08bee9863a78ec000c5bb
|
||||
F src/vdbe.c e1782e46404dd5aeb26d49e2180be6efcb6a2334
|
||||
F src/vacuum.c d9c5759f4c5a438bb43c2086f72c5d2edabc36c8
|
||||
F src/vdbe.c 7e1654d4ac01f017aad8088a1225e514b2aef5cf
|
||||
F src/vdbe.h 1223e2548e0970cf96f573ff6b99f804a36ad683
|
||||
F src/vdbeInt.h 1ca0f9ae9e9c28823647749edb767ea9ef2176d1
|
||||
F src/vdbeapi.c c45805f7acd2a07444b3d3b63853eb96545ec5f0
|
||||
F src/vdbeaux.c 2e82e249a0b72e9c2b63d16ec7801a966ff6a182
|
||||
F src/vdbeInt.h 11feb11eb49d8b312741011d30d91c9c50b59de0
|
||||
F src/vdbeapi.c bb28ee14bae43579b33d88e0d916a1657255a866
|
||||
F src/vdbeaux.c 84f5fb7cb2f62fd8b8a37b96ac929221cc77d317
|
||||
F src/vdbeblob.c 1268e0bcb8e21fa32520b0fc376e1bcdfaa0c642
|
||||
F src/vdbemem.c 833005f1cbbf447289f1973dba2a0c2228c7b8ab
|
||||
F src/vdbesort.c 3937e06b2a0e354500e17dc206ef4c35770a5017
|
||||
F src/vdbetrace.c 18cc59cb475e6115129bfde224367d13a35a7d13
|
||||
F src/vdbetrace.c e7ec40e1999ff3c6414424365d5941178966dcbc
|
||||
F src/vtab.c b05e5f1f4902461ba9f5fc49bb7eb7c3a0741a83
|
||||
F src/wal.c 436bfceb141b9423c45119e68e444358ee0ed35d
|
||||
F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4
|
||||
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
||||
F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73
|
||||
F src/where.c 9bcfcb4ec6a14dd0111bf287bee02be88d5709f9
|
||||
F src/where.c f5201334501cd23a39315cab479c0dcce0990701
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
|
||||
@@ -335,7 +336,7 @@ F test/auth.test 4a4c3b034fff7750513520defa910f376c96ab49
|
||||
F test/auth2.test a2a371aa6df15f8b0c8109b33d3d7f0f73e4c9aa
|
||||
F test/auth3.test a4755e6a2a2fea547ffe63c874eb569e60a28eb5
|
||||
F test/autoinc.test bd30d372d00045252f6c2e41b5f41455e1975acf
|
||||
F test/autoindex1.test 314f12f87667861ac965c41587f9df82c42fff65
|
||||
F test/autoindex1.test d4dfe14001dfcb74cfbd7107f45a79fc1ab6183e
|
||||
F test/autovacuum.test 9f22a7733f39c56ef6a5665d10145ac25d8cb574
|
||||
F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4
|
||||
F test/avtrans.test 0252654f4295ddda3b2cce0e894812259e655a85
|
||||
@@ -360,7 +361,7 @@ F test/boundary1.tcl 6421b2d920d8b09539503a8673339d32f7609eb1
|
||||
F test/boundary1.test 66d7f4706ccdb42d58eafdb081de07b0eb42d77b
|
||||
F test/boundary2.tcl e34ef4e930cf1083150d4d2c603e146bd3b76bcb
|
||||
F test/boundary2.test 9ae758d7dab7e882c8b6cc4a6a10278385bff8fa
|
||||
F test/boundary3.tcl 8901d6a503d0bf64251dd81cc74e5ad3add4b119
|
||||
F test/boundary3.tcl 23361e108a125dca9c4080c2feb884fe54d69243
|
||||
F test/boundary3.test 56ef82096b4329aca2be74fa1e2b0f762ea0eb45
|
||||
F test/boundary4.tcl 0bb4b1a94f4fc5ae59b79b9a2b7a140c405e2983
|
||||
F test/boundary4.test 89e02fa66397b8a325d5eb102b5806f961f8ec4b
|
||||
@@ -371,7 +372,7 @@ F test/capi2.test e8b18cc61090b6e5e388f54d6b125d711d1b265a
|
||||
F test/capi3.test 56ab450125ead38846cbae7e5b6a216686c3cffa
|
||||
F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4
|
||||
F test/capi3c.test 93d24621c9ff84da9da060f30431e0453db1cdb0
|
||||
F test/capi3d.test 17b57ca28be3e37e14c2ba8f787d292d84b724a1
|
||||
F test/capi3d.test 6d0fc0a86d73f42dd19a7d8b7761ab9bc02277d0
|
||||
F test/capi3e.test ad90088b18b0367125ff2d4b5400153fd2f99aab
|
||||
F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3
|
||||
F test/check.test 2eb93611139a7dfaed3be80067c7dc5ceb5fb287
|
||||
@@ -438,7 +439,7 @@ F test/e_createtable.test ddf3b2e4506e0813f46b69ccf55757c5570cc181
|
||||
F test/e_delete.test 89aa84d3d1bd284a0689ede04bce10226a5aeaa5
|
||||
F test/e_droptrigger.test afd5c4d27dec607f5997a66bf7e2498a082cb235
|
||||
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_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459
|
||||
F test/e_insert.test d5331cc95e101af2508159fc98b6801631659ffe
|
||||
@@ -675,7 +676,7 @@ F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e
|
||||
F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f
|
||||
F test/memdb.test db5260330676de007be8530d6ecc7c9ab2b06ad3
|
||||
F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2
|
||||
F test/memsubsys1.test a8f9e37567453a5d1d9d37ec102d4d88ab6be33f
|
||||
F test/memsubsys1.test f97cfd0b30e85c2f1ed16d642e7ac58006be84b2
|
||||
F test/memsubsys2.test 3a1c1a9de48e5726faa85108b02459fae8cb9ee9
|
||||
F test/minmax.test 42fbad0e81afaa6e0de41c960329f2b2c3526efd
|
||||
F test/minmax2.test b44bae787fc7b227597b01b0ca5575c7cb54d3bc
|
||||
@@ -691,7 +692,8 @@ F test/misc7.test 50c02c35ef7924c246eb3d8d71dfbf90ba352f8f
|
||||
F test/misuse.test ba4fb5d1a6101d1c171ea38b3c613d0661c83054
|
||||
F test/mmap1.test 93d167b328255cbe6679fe1e1a23be1b1197d07b
|
||||
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/multiplex2.test 580ca5817c7edbe4cc68fa150609c9473393003a
|
||||
F test/multiplex3.test d228f59eac91839a977eac19f21d053f03e4d101
|
||||
@@ -719,9 +721,9 @@ F test/pagerfault2.test caf4c7facb914fd3b03a17b31ae2b180c8d6ca1f
|
||||
F test/pagerfault3.test 1003fcda009bf48a8e22a516e193b6ef0dd1bbd8
|
||||
F test/pageropt.test 6b8f6a123a5572c195ad4ae40f2987007923bbd6
|
||||
F test/pagesize.test 1dd51367e752e742f58e861e65ed7390603827a0
|
||||
F test/pcache.test 065aa286e722ab24f2e51792c1f093bf60656b16
|
||||
F test/pcache.test b09104b03160aca0d968d99e8cd2c5b1921a993d
|
||||
F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
|
||||
F test/percentile.test 4614301e38398df7fdd5f28f4ed8f272b328251b
|
||||
F test/percentile.test b98fc868d71eb5619d42a1702e9ab91718cbed54
|
||||
F test/permutations.test 742b8005bb3c782797a20beccdbe213ef52531fb
|
||||
F test/pragma.test 5e7de6c32a5d764f09437d2025f07e4917b9e178
|
||||
F test/pragma2.test 3a55f82b954242c642f8342b17dffc8b47472947
|
||||
@@ -767,7 +769,7 @@ F test/select5.test e758b8ef94f69b111df4cb819008856655dcd535
|
||||
F test/select6.test e76bd10a56988f15726c097a5d5a7966fe82d3b2
|
||||
F test/select7.test dad6f00f0d49728a879d6eb6451d4752db0b0abe
|
||||
F test/select8.test 391de11bdd52339c30580dabbbbe97e3e9a3c79d
|
||||
F test/select9.test c0ca3cd87a8ebb04de2cb1402c77df55d911a0ea
|
||||
F test/select9.test aebc2bb0c3bc44606125033cbcaac2c8d1f33a95
|
||||
F test/selectA.test 99cf21df033b93033ea4f34aba14a500f48f04fe
|
||||
F test/selectB.test 954e4e49cf1f896d61794e440669e03a27ceea25
|
||||
F test/selectC.test 871fb55d884d3de5943c4057ebd22c2459e71977
|
||||
@@ -786,11 +788,11 @@ F test/shared9.test 5f2a8f79b4d6c7d107a01ffa1ed05ae7e6333e21
|
||||
F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5
|
||||
F test/shared_err.test 0079c05c97d88cfa03989b7c20a8b266983087aa
|
||||
F test/sharedlock.test 927a4b6da11978c82b857dbdb20a932aad732123
|
||||
F test/shell1.test 4a2f57952719972c6f862134463f8712e953c038
|
||||
F test/shell1.test 928547277d385038c696428e9d791cbbad098974
|
||||
F test/shell2.test 037d6ad16e873354195d30bb2dc4b5321788154a
|
||||
F test/shell3.test 9196c42772d575685e722c92b4b39053c6ebba59
|
||||
F test/shell4.test aa4eef8118b412d1a01477a53426ece169ea86a9
|
||||
F test/shell5.test fa2188bbb13fe2d183fd04a5f7b512650c35ef5d
|
||||
F test/shell5.test 946e620a41b64f90d45dcf91c36e8d408d435cfd
|
||||
F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
|
||||
F test/shrink.test 8c70f62b6e8eb4d54533de6d65bd06b1b9a17868
|
||||
F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329
|
||||
@@ -805,7 +807,7 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523
|
||||
F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715
|
||||
F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
|
||||
F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
|
||||
F test/spellfix.test bea537caf587df30d430c2c6a8fe9f64b8712834
|
||||
F test/spellfix.test 38246facf7d9d7eeb8a57d7497cf7ce73ce5785d
|
||||
F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298
|
||||
F test/stat.test be8d477306006ec696bc86757cfb34bec79447ce
|
||||
F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9
|
||||
@@ -861,6 +863,7 @@ F test/tkt-7bbfb7d442.test 7b2cd79c7a17ae6750e75ec1a7846712a69c9d18
|
||||
F test/tkt-80ba201079.test 105a721e6aad0ae3c5946d7615d1e4d03f6145b8
|
||||
F test/tkt-80e031a00f.test 9a154173461a4dbe2de49cda73963e04842d52f7
|
||||
F test/tkt-8454a207b9.test c583a9f814a82a2b5ba95207f55001c9f0cd816c
|
||||
F test/tkt-868145d012.test a5f941107ece6a64410ca4755c6329b7eb57a356
|
||||
F test/tkt-91e2e8ba6f.test 08c4f94ae07696b05c9b822da0b4e5337a2f54c5
|
||||
F test/tkt-94c04eaadb.test fa9c71192f7e2ea2d51bf078bc34e8da6088bf71
|
||||
F test/tkt-9d68c883.test 458f7d82a523d7644b54b497c986378a7d8c8b67
|
||||
@@ -971,7 +974,7 @@ F test/trace2.test e7a988fdd982cdec62f1f1f34b0360e6476d01a0
|
||||
F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6
|
||||
F test/trans2.test d5337e61de45e66b1fcbf9db833fa8c82e624b22
|
||||
F test/trans3.test 373ac5183cc56be69f48ae44090e7f672939f732
|
||||
F test/transitive1.test d04aa9023e425d6f2d4aa61dd81ee9e102f89062
|
||||
F test/transitive1.test 0ee69546d6fa20e577a4a706d7daa01c7eba9239
|
||||
F test/trigger1.test dc47573ac79ffe0ee3eecaa517d70d8dacbccd03
|
||||
F test/trigger2.test 834187beafd1db383af0c659cfa49b0576832816
|
||||
F test/trigger3.test aa640bb2bbb03edd5ff69c055117ea088f121945
|
||||
@@ -1025,7 +1028,7 @@ F test/wal2.test d4b470f13c87f6d8268b004380afa04c3c67cb90
|
||||
F test/wal3.test b22eb662bcbc148c5f6d956eaf94b047f7afe9c0
|
||||
F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c
|
||||
F test/wal5.test 8f888b50f66b78821e61ed0e233ded5de378224b
|
||||
F test/wal6.test 2e3bc767d9c2ce35c47106148d43fcbd072a93b3
|
||||
F test/wal6.test 527581f5527bf9c24394991e2be83000aace5f9e
|
||||
F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd
|
||||
F test/wal8.test 75c42e1bc4545c277fed212f8fc9b7723cd02216
|
||||
F test/wal9.test 378e76a9ad09cd9bee06c172ad3547b0129a6750
|
||||
@@ -1046,8 +1049,8 @@ F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417
|
||||
F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a
|
||||
F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e
|
||||
F test/where.test da54153a4c1571ea1b95659e5bec8119edf786aa
|
||||
F test/where2.test dcf0ffafe0de55051c1373835a5a57aee6b50094
|
||||
F test/where3.test 157071521ceabc06bfd4d37106e4270a8956364d
|
||||
F test/where2.test d712de0ea9a2c3de7b34b0b1e75172556fef5b24
|
||||
F test/where3.test a0682ba3dc8c8f46ffcc95a3d9f58c4327fc129f
|
||||
F test/where4.test e9b9e2f2f98f00379e6031db6a6fca29bae782a2
|
||||
F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2
|
||||
F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b
|
||||
@@ -1062,6 +1065,7 @@ F test/whereD.test 6c2feb79ef1f68381b07f39017fe5f9b96da8d62
|
||||
F test/whereE.test b3a055eef928c992b0a33198a7b8dc10eea5ad2f
|
||||
F test/whereF.test 136a7301512d72a08a272806c8767066311b7bc1
|
||||
F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31
|
||||
F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c
|
||||
F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361
|
||||
F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688
|
||||
F test/zerodamage.test 209d7ed441f44cc5299e4ebffbef06fd5aabfefd
|
||||
@@ -1111,7 +1115,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
|
||||
F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae
|
||||
F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
|
||||
P 1d44e5d3c2b1dc958442f9114a960b256e002ed3
|
||||
R 28f75ac347bd281672cb0a8d27d3f6b3
|
||||
U dan
|
||||
Z 01296a7a6fdc241a613ea24758428ad2
|
||||
P 1452defb8cfcc489230314dd1e0425feba46c49d 1e39f85077f1f2b96c3a656c5b6334bafb005908
|
||||
R 996effd12b4e262519df6f6e538dae74
|
||||
U drh
|
||||
Z 08707dac307041af534ddfd35863fca1
|
||||
|
@@ -1 +1 @@
|
||||
1452defb8cfcc489230314dd1e0425feba46c49d
|
||||
af3ca4c6e557e6bc92584586b5a97d9be41b0b82
|
@@ -11,7 +11,7 @@ CMD="$CC -c fts2amal.c"
|
||||
echo $CMD
|
||||
$CMD
|
||||
echo 'EXPORTS' >fts2.def
|
||||
echo 'sqlite3_extension_init' >>fts2.def
|
||||
echo 'sqlite3_fts2_init' >>fts2.def
|
||||
i386-mingw32msvc-dllwrap \
|
||||
--def fts2.def -v --export-all \
|
||||
--driver-name i386-mingw32msvc-gcc \
|
||||
|
@@ -3273,12 +3273,13 @@ int sqlite3BtreeCommitPhaseOne(Btree *p, const char *zMaster){
|
||||
*/
|
||||
static void btreeEndTransaction(Btree *p){
|
||||
BtShared *pBt = p->pBt;
|
||||
sqlite3 *db = p->db;
|
||||
assert( sqlite3BtreeHoldsMutex(p) );
|
||||
|
||||
#ifndef SQLITE_OMIT_AUTOVACUUM
|
||||
pBt->bDoTruncate = 0;
|
||||
#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
|
||||
** handle, downgrade to a read-only transaction. The other statements
|
||||
** may still be reading from the database. */
|
||||
|
11
src/main.c
11
src/main.c
@@ -1065,6 +1065,7 @@ const char *sqlite3ErrName(int rc){
|
||||
case SQLITE_ABORT_ROLLBACK: zName = "SQLITE_ABORT_ROLLBACK"; break;
|
||||
case SQLITE_BUSY: zName = "SQLITE_BUSY"; 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_SHAREDCACHE: zName = "SQLITE_LOCKED_SHAREDCACHE";break;
|
||||
case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break;
|
||||
@@ -1138,6 +1139,7 @@ const char *sqlite3ErrName(int rc){
|
||||
case SQLITE_NOTICE_RECOVER_ROLLBACK:
|
||||
zName = "SQLITE_NOTICE_RECOVER_ROLLBACK"; break;
|
||||
case SQLITE_WARNING: zName = "SQLITE_WARNING"; break;
|
||||
case SQLITE_WARNING_AUTOINDEX: zName = "SQLITE_WARNING_AUTOINDEX"; break;
|
||||
case SQLITE_DONE: zName = "SQLITE_DONE"; break;
|
||||
}
|
||||
}
|
||||
@@ -1396,7 +1398,7 @@ int sqlite3CreateFunc(
|
||||
*/
|
||||
p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 0);
|
||||
if( p && p->iPrefEnc==enc && p->nArg==nArg ){
|
||||
if( db->activeVdbeCnt ){
|
||||
if( db->nVdbeActive ){
|
||||
sqlite3Error(db, SQLITE_BUSY,
|
||||
"unable to delete/modify user-function due to active statements");
|
||||
assert( !db->mallocFailed );
|
||||
@@ -1998,7 +2000,7 @@ static int createCollation(
|
||||
*/
|
||||
pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 0);
|
||||
if( pColl && pColl->xCmp ){
|
||||
if( db->activeVdbeCnt ){
|
||||
if( db->nVdbeActive ){
|
||||
sqlite3Error(db, SQLITE_BUSY,
|
||||
"unable to delete/modify collation sequence due to active statements");
|
||||
return SQLITE_BUSY;
|
||||
@@ -2473,7 +2475,10 @@ static int openDatabase(
|
||||
db->nextAutovac = -1;
|
||||
db->szMmap = sqlite3GlobalConfig.szMmap;
|
||||
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
|
||||
| SQLITE_LegacyFileFmt
|
||||
#endif
|
||||
|
@@ -1812,6 +1812,7 @@ static void pager_unlock(Pager *pPager){
|
||||
pPager->changeCountDone = pPager->tempFile;
|
||||
pPager->eState = PAGER_OPEN;
|
||||
pPager->errCode = SQLITE_OK;
|
||||
if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0);
|
||||
}
|
||||
|
||||
pPager->journalOff = 0;
|
||||
@@ -3378,10 +3379,10 @@ void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){
|
||||
static void pagerFixMaplimit(Pager *pPager){
|
||||
#if SQLITE_MAX_MMAP_SIZE>0
|
||||
sqlite3_file *fd = pPager->fd;
|
||||
if( isOpen(fd) ){
|
||||
if( isOpen(fd) && fd->pMethods->iVersion>=3 ){
|
||||
sqlite3_int64 sz;
|
||||
pPager->bUseFetch = (fd->pMethods->iVersion>=3) && pPager->szMmap>0;
|
||||
sz = pPager->szMmap;
|
||||
pPager->bUseFetch = (sz>0);
|
||||
sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_SIZE, &sz);
|
||||
}
|
||||
#endif
|
||||
|
@@ -468,8 +468,8 @@ void sqlite3VXPrintf(
|
||||
}else{
|
||||
e2 = exp;
|
||||
}
|
||||
if( e2+precision+width > etBUFSIZE - 15 ){
|
||||
bufpt = zExtra = sqlite3Malloc( e2+precision+width+15 );
|
||||
if( MAX(e2,0)+precision+width > etBUFSIZE - 15 ){
|
||||
bufpt = zExtra = sqlite3Malloc( MAX(e2,0)+precision+width+15 );
|
||||
if( bufpt==0 ){
|
||||
pAccum->mallocFailed = 1;
|
||||
return;
|
||||
|
279
src/shell.c
279
src/shell.c
@@ -67,7 +67,7 @@
|
||||
#undef popen
|
||||
#define popen(a,b) _popen((a),(b))
|
||||
#undef pclose
|
||||
#define pclose(x) _pclose(x)
|
||||
#define pclose _pclose
|
||||
#else
|
||||
/* Make sure isatty() has a prototype.
|
||||
*/
|
||||
@@ -1492,6 +1492,7 @@ static void open_db(struct callback_data *p){
|
||||
** \t -> tab
|
||||
** \n -> newline
|
||||
** \r -> carriage return
|
||||
** \" -> "
|
||||
** \NNN -> ascii character NNN in octal
|
||||
** \\ -> backslash
|
||||
*/
|
||||
@@ -1507,6 +1508,8 @@ static void resolve_backslashes(char *z){
|
||||
c = '\t';
|
||||
}else if( c=='r' ){
|
||||
c = '\r';
|
||||
}else if( c=='\\' ){
|
||||
c = '\\';
|
||||
}else if( c>='0' && c<='7' ){
|
||||
c -= '0';
|
||||
if( z[i+1]>='0' && z[i+1]<='7' ){
|
||||
@@ -1650,6 +1653,107 @@ static void test_breakpoint(void){
|
||||
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
|
||||
** process that line.
|
||||
@@ -1671,7 +1775,10 @@ static int do_meta_command(char *zLine, struct callback_data *p){
|
||||
if( zLine[i]=='\'' || zLine[i]=='"' ){
|
||||
int delim = 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 ){
|
||||
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 ){
|
||||
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 */
|
||||
int nCol; /* Number of columns in the table */
|
||||
int nByte; /* Number of bytes in an SQL string */
|
||||
int i, j; /* Loop counters */
|
||||
int nSep; /* Number of bytes in p->separator[] */
|
||||
char *zSql; /* An SQL statement */
|
||||
char *zLine; /* A single line of input from the file */
|
||||
char **azCol; /* zLine[] broken up into columns */
|
||||
char *zCommit; /* How to commit changes */
|
||||
FILE *in; /* The input file */
|
||||
int lineno = 0; /* Line number of input file */
|
||||
CSVReader sCsv; /* Reader context */
|
||||
int (*xCloser)(FILE*); /* Procedure to close th3 connection */
|
||||
|
||||
seenInterrupt = 0;
|
||||
memset(&sCsv, 0, sizeof(sCsv));
|
||||
open_db(p);
|
||||
nSep = strlen30(p->separator);
|
||||
if( nSep==0 ){
|
||||
fprintf(stderr, "Error: non-null separator required for import\n");
|
||||
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);
|
||||
if( zSql==0 ){
|
||||
fprintf(stderr, "Error: out of memory\n");
|
||||
xCloser(sCsv.in);
|
||||
return 1;
|
||||
}
|
||||
nByte = strlen30(zSql);
|
||||
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);
|
||||
if( rc ){
|
||||
if (pStmt) sqlite3_finalize(pStmt);
|
||||
fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
|
||||
xCloser(sCsv.in);
|
||||
return 1;
|
||||
}
|
||||
nCol = sqlite3_column_count(pStmt);
|
||||
sqlite3_finalize(pStmt);
|
||||
pStmt = 0;
|
||||
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 ){
|
||||
fprintf(stderr, "Error: out of memory\n");
|
||||
xCloser(sCsv.in);
|
||||
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);
|
||||
for(i=1; i<nCol; i++){
|
||||
zSql[j++] = ',';
|
||||
@@ -1938,79 +2094,50 @@ static int do_meta_command(char *zLine, struct callback_data *p){
|
||||
zSql[j++] = ')';
|
||||
zSql[j] = 0;
|
||||
rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
|
||||
free(zSql);
|
||||
sqlite3_free(zSql);
|
||||
if( rc ){
|
||||
fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
|
||||
if (pStmt) sqlite3_finalize(pStmt);
|
||||
xCloser(sCsv.in);
|
||||
return 1;
|
||||
}
|
||||
in = fopen(zFile, "rb");
|
||||
if( in==0 ){
|
||||
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 */
|
||||
}
|
||||
do{
|
||||
int startLine = sCsv.nLine;
|
||||
for(i=0; i<nCol; i++){
|
||||
if( azCol[i][0]=='"' ){
|
||||
int k;
|
||||
for(z=azCol[i], j=1, k=0; z[j]; j++){
|
||||
if( z[j]=='"' ){ j++; if( z[j]==0 ) break; }
|
||||
z[k++] = z[j];
|
||||
}
|
||||
z[k] = 0;
|
||||
char *z = csv_read_one_field(&sCsv);
|
||||
if( z==0 && i==0 ) break;
|
||||
sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
|
||||
if( i<nCol-1 && sCsv.cTerm!=sCsv.cSeparator ){
|
||||
fprintf(stderr, "%s:%d: expected %d columns but found %d - "
|
||||
"filling the rest with NULL\n",
|
||||
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);
|
||||
rc = sqlite3_reset(pStmt);
|
||||
free(zLine);
|
||||
if( rc!=SQLITE_OK ){
|
||||
fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
|
||||
zCommit = "ROLLBACK";
|
||||
rc = 1;
|
||||
break; /* from while */
|
||||
if( sCsv.cTerm==sCsv.cSeparator ){
|
||||
do{
|
||||
csv_read_one_field(&sCsv);
|
||||
i++;
|
||||
}while( sCsv.cTerm==sCsv.cSeparator );
|
||||
fprintf(stderr, "%s:%d: expected %d columns but found %d - "
|
||||
"extras ignored\n",
|
||||
sCsv.zFile, startLine, nCol, i);
|
||||
}
|
||||
} /* end while */
|
||||
free(azCol);
|
||||
fclose(in);
|
||||
if( i>=nCol ){
|
||||
sqlite3_step(pStmt);
|
||||
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_exec(p->db, zCommit, 0, 0, 0);
|
||||
sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
|
||||
}else
|
||||
|
||||
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
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
/* Undocumented commands for internal testing. Subject to change
|
||||
** without notice. */
|
||||
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 ){
|
||||
int i; sqlite3_int64 v;
|
||||
for(i=1; i<nArg; i++){
|
||||
char zBuf[200];
|
||||
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
|
||||
#endif
|
||||
|
||||
if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
|
||||
sqlite3_snprintf(sizeof(p->separator), p->separator,
|
||||
|
@@ -475,6 +475,7 @@ int sqlite3_exec(
|
||||
#define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8))
|
||||
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (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_ISDIR (SQLITE_CANTOPEN | (2<<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_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8))
|
||||
#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
|
||||
#define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8))
|
||||
|
||||
/*
|
||||
** CAPI3REF: Flags For File Open Operations
|
||||
|
@@ -474,11 +474,14 @@ struct sqlite3_api_routines {
|
||||
** extension */
|
||||
# define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0;
|
||||
# define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v;
|
||||
# define SQLITE_EXTENSION_INIT3 \
|
||||
extern const sqlite3_api_routines *sqlite3_api;
|
||||
#else
|
||||
/* This case when the file is being statically linked into the
|
||||
** application */
|
||||
# define SQLITE_EXTENSION_INIT1 /*no-op*/
|
||||
# define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */
|
||||
# define SQLITE_EXTENSION_INIT3 /*no-op*/
|
||||
#endif
|
||||
|
||||
#endif /* _SQLITE3EXT_H_ */
|
||||
|
@@ -898,9 +898,10 @@ struct sqlite3 {
|
||||
u8 busy; /* TRUE if currently initializing */
|
||||
u8 orphanTrigger; /* Last statement is orphaned TEMP trigger */
|
||||
} init;
|
||||
int activeVdbeCnt; /* Number of VDBEs currently executing */
|
||||
int writeVdbeCnt; /* Number of active VDBEs that are writing */
|
||||
int vdbeExecCnt; /* Number of nested calls to VdbeExec() */
|
||||
int nVdbeActive; /* Number of VDBEs currently running */
|
||||
int nVdbeRead; /* Number of active VDBEs that read or write */
|
||||
int nVdbeWrite; /* Number of active VDBEs that read and write */
|
||||
int nVdbeExec; /* Number of nested calls to VdbeExec() */
|
||||
int nExtension; /* Number of loaded extensions */
|
||||
void **aExtension; /* Array of shared library handles */
|
||||
void (*xTrace)(void*,const char*); /* Trace function */
|
||||
@@ -1035,6 +1036,7 @@ struct sqlite3 {
|
||||
#define SQLITE_SubqCoroutine 0x0100 /* Evaluate subqueries as coroutines */
|
||||
#define SQLITE_Transitive 0x0200 /* Transitive constraints */
|
||||
#define SQLITE_OmitNoopJoin 0x0400 /* Omit unused tables in joins */
|
||||
#define SQLITE_Stat3 0x0800 /* Use the SQLITE_STAT3 table */
|
||||
#define SQLITE_AllOpts 0xffff /* All optimizations */
|
||||
|
||||
/*
|
||||
|
25
src/test1.c
25
src/test1.c
@@ -5959,15 +5959,20 @@ static int optimization_control(
|
||||
const char *zOptName;
|
||||
int mask;
|
||||
} aOpt[] = {
|
||||
{ "all", SQLITE_AllOpts },
|
||||
{ "query-flattener", SQLITE_QueryFlattener },
|
||||
{ "column-cache", SQLITE_ColumnCache },
|
||||
{ "groupby-order", SQLITE_GroupByOrder },
|
||||
{ "factor-constants", SQLITE_FactorOutConst },
|
||||
{ "real-as-int", SQLITE_IdxRealAsInt },
|
||||
{ "distinct-opt", SQLITE_DistinctOpt },
|
||||
{ "cover-idx-scan", SQLITE_CoverIdxScan },
|
||||
{ "order-by-idx-join",SQLITE_OrderByIdxJoin },
|
||||
{ "all", SQLITE_AllOpts },
|
||||
{ "none", 0 },
|
||||
{ "query-flattener", SQLITE_QueryFlattener },
|
||||
{ "column-cache", SQLITE_ColumnCache },
|
||||
{ "groupby-order", SQLITE_GroupByOrder },
|
||||
{ "factor-constants", SQLITE_FactorOutConst },
|
||||
{ "real-as-int", SQLITE_IdxRealAsInt },
|
||||
{ "distinct-opt", SQLITE_DistinctOpt },
|
||||
{ "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 ){
|
||||
@@ -5988,7 +5993,7 @@ static int optimization_control(
|
||||
Tcl_AppendResult(interp, "unknown optimization - should be one of:",
|
||||
(char*)0);
|
||||
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;
|
||||
}
|
||||
|
@@ -344,7 +344,10 @@ int Sqlitetestschema_Init(Tcl_Interp *interp){
|
||||
/*
|
||||
** Extension load function.
|
||||
*/
|
||||
int sqlite3_extension_init(
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
int sqlite3_schema_init(
|
||||
sqlite3 *db,
|
||||
char **pzErrMsg,
|
||||
const sqlite3_api_routines *pApi
|
||||
|
@@ -190,8 +190,11 @@ static int tvfsShmMap(sqlite3_file*,int,int,int, void volatile **);
|
||||
static void tvfsShmBarrier(sqlite3_file*);
|
||||
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 = {
|
||||
2, /* iVersion */
|
||||
3, /* iVersion */
|
||||
tvfsClose, /* xClose */
|
||||
tvfsRead, /* xRead */
|
||||
tvfsWrite, /* xWrite */
|
||||
@@ -207,7 +210,9 @@ static sqlite3_io_methods tvfs_io_methods = {
|
||||
tvfsShmMap, /* xShmMap */
|
||||
tvfsShmLock, /* xShmLock */
|
||||
tvfsShmBarrier, /* xShmBarrier */
|
||||
tvfsShmUnmap /* xShmUnmap */
|
||||
tvfsShmUnmap, /* xShmUnmap */
|
||||
tvfsFetch,
|
||||
tvfsUnfetch
|
||||
};
|
||||
|
||||
static int tvfsResultCode(Testvfs *p, int *pRc){
|
||||
@@ -618,7 +623,10 @@ static int tvfsOpen(
|
||||
|
||||
pMethods = (sqlite3_io_methods *)ckalloc(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 ){
|
||||
pMethods->xShmUnmap = 0;
|
||||
pMethods->xShmLock = 0;
|
||||
@@ -993,6 +1001,21 @@ static int tvfsShmUnmap(
|
||||
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(
|
||||
ClientData cd,
|
||||
Tcl_Interp *interp,
|
||||
@@ -1343,7 +1366,7 @@ static int testvfs_cmd(
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
static sqlite3_vfs tvfs_vfs = {
|
||||
2, /* iVersion */
|
||||
3, /* iVersion */
|
||||
0, /* szOsFile */
|
||||
0, /* mxPathname */
|
||||
0, /* pNext */
|
||||
@@ -1369,6 +1392,9 @@ static int testvfs_cmd(
|
||||
tvfsCurrentTime, /* xCurrentTime */
|
||||
0, /* xGetLastError */
|
||||
0, /* xCurrentTimeInt64 */
|
||||
0, /* xSetSystemCall */
|
||||
0, /* xGetSystemCall */
|
||||
0, /* xNextSystemCall */
|
||||
};
|
||||
|
||||
Testvfs *p; /* New object */
|
||||
@@ -1382,7 +1408,7 @@ static int testvfs_cmd(
|
||||
int isDefault = 0; /* True if -default is passed */
|
||||
int szOsFile = 0; /* Value passed to -szosfile */
|
||||
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;
|
||||
for(i=2; i<objc; i += 2){
|
||||
|
@@ -396,7 +396,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
|
||||
|
||||
|
||||
mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
|
||||
if( db->activeVdbeCnt==0 ){
|
||||
if( db->nVdbeActive==0 ){
|
||||
db->u1.isInterrupted = 0;
|
||||
}
|
||||
pParse->rc = SQLITE_OK;
|
||||
|
@@ -111,7 +111,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
|
||||
sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction");
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
if( db->activeVdbeCnt>1 ){
|
||||
if( db->nVdbeActive>1 ){
|
||||
sqlite3SetString(pzErrMsg, db,"cannot VACUUM - SQL statements in progress");
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
|
43
src/vdbe.c
43
src/vdbe.c
@@ -589,6 +589,7 @@ int sqlite3VdbeExec(
|
||||
goto no_mem;
|
||||
}
|
||||
assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY );
|
||||
assert( p->bIsReader || p->readOnly!=0 );
|
||||
p->rc = SQLITE_OK;
|
||||
assert( p->explain==0 );
|
||||
p->pResultSet = 0;
|
||||
@@ -2695,9 +2696,10 @@ case OP_Savepoint: {
|
||||
assert( p1==SAVEPOINT_BEGIN||p1==SAVEPOINT_RELEASE||p1==SAVEPOINT_ROLLBACK );
|
||||
assert( db->pSavepoint || db->isTransactionSavepoint==0 );
|
||||
assert( checkSavepointCount(db) );
|
||||
assert( p->bIsReader );
|
||||
|
||||
if( p1==SAVEPOINT_BEGIN ){
|
||||
if( db->writeVdbeCnt>0 ){
|
||||
if( db->nVdbeWrite>0 ){
|
||||
/* A new savepoint cannot be created if there are active write
|
||||
** statements (i.e. open read/write incremental blob handles).
|
||||
*/
|
||||
@@ -2755,7 +2757,7 @@ case OP_Savepoint: {
|
||||
if( !pSavepoint ){
|
||||
sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", zName);
|
||||
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
|
||||
** active write statements.
|
||||
*/
|
||||
@@ -2857,10 +2859,11 @@ case OP_AutoCommit: {
|
||||
turnOnAC = desiredAutoCommit && !db->autoCommit;
|
||||
assert( desiredAutoCommit==1 || desiredAutoCommit==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( turnOnAC && iRollback && db->activeVdbeCnt>1 ){
|
||||
if( turnOnAC && iRollback && db->nVdbeActive>1 ){
|
||||
/* If this instruction implements a ROLLBACK and other VMs are
|
||||
** still running, and a transaction is active, return an error indicating
|
||||
** that the other VMs must complete first.
|
||||
@@ -2870,7 +2873,7 @@ case OP_AutoCommit: {
|
||||
rc = SQLITE_BUSY;
|
||||
}else
|
||||
#endif
|
||||
if( turnOnAC && !iRollback && db->writeVdbeCnt>0 ){
|
||||
if( turnOnAC && !iRollback && db->nVdbeWrite>0 ){
|
||||
/* If this instruction implements a COMMIT and other VMs are writing
|
||||
** return an error indicating that the other VMs must complete first.
|
||||
*/
|
||||
@@ -2946,6 +2949,8 @@ case OP_AutoCommit: {
|
||||
case OP_Transaction: {
|
||||
Btree *pBt;
|
||||
|
||||
assert( p->bIsReader );
|
||||
assert( p->readOnly==0 || pOp->p2==0 );
|
||||
assert( pOp->p1>=0 && pOp->p1<db->nDb );
|
||||
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
|
||||
pBt = db->aDb[pOp->p1].pBt;
|
||||
@@ -2962,7 +2967,7 @@ case OP_Transaction: {
|
||||
}
|
||||
|
||||
if( pOp->p2 && p->usesStmtJournal
|
||||
&& (db->autoCommit==0 || db->activeVdbeCnt>1)
|
||||
&& (db->autoCommit==0 || db->nVdbeRead>1)
|
||||
){
|
||||
assert( sqlite3BtreeIsInTrans(pBt) );
|
||||
if( p->iStatement==0 ){
|
||||
@@ -3003,6 +3008,7 @@ case OP_ReadCookie: { /* out2-prerelease */
|
||||
int iDb;
|
||||
int iCookie;
|
||||
|
||||
assert( p->bIsReader );
|
||||
iDb = pOp->p1;
|
||||
iCookie = pOp->p3;
|
||||
assert( pOp->p3<SQLITE_N_BTREE_META );
|
||||
@@ -3030,6 +3036,7 @@ case OP_SetCookie: { /* in3 */
|
||||
assert( pOp->p2<SQLITE_N_BTREE_META );
|
||||
assert( pOp->p1>=0 && pOp->p1<db->nDb );
|
||||
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
|
||||
assert( p->readOnly==0 );
|
||||
pDb = &db->aDb[pOp->p1];
|
||||
assert( pDb->pBt!=0 );
|
||||
assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) );
|
||||
@@ -3080,6 +3087,7 @@ case OP_VerifyCookie: {
|
||||
assert( pOp->p1>=0 && pOp->p1<db->nDb );
|
||||
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
|
||||
assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) );
|
||||
assert( p->bIsReader );
|
||||
pBt = db->aDb[pOp->p1].pBt;
|
||||
if( pBt ){
|
||||
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->opcode==OP_OpenWrite || pOp->p5==0 );
|
||||
assert( p->bIsReader );
|
||||
assert( pOp->opcode==OP_OpenRead || p->readOnly==0 );
|
||||
|
||||
if( p->expired ){
|
||||
rc = SQLITE_ABORT;
|
||||
@@ -4787,15 +4797,18 @@ case OP_Destroy: { /* out2-prerelease */
|
||||
Vdbe *pVdbe;
|
||||
int iDb;
|
||||
|
||||
assert( p->readOnly==0 );
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
iCnt = 0;
|
||||
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++;
|
||||
}
|
||||
}
|
||||
#else
|
||||
iCnt = db->activeVdbeCnt;
|
||||
iCnt = db->nVdbeRead;
|
||||
#endif
|
||||
pOut->flags = MEM_Null;
|
||||
if( iCnt>1 ){
|
||||
@@ -4842,6 +4855,7 @@ case OP_Clear: {
|
||||
int nChange;
|
||||
|
||||
nChange = 0;
|
||||
assert( p->readOnly==0 );
|
||||
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p2))!=0 );
|
||||
rc = sqlite3BtreeClearTable(
|
||||
db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &nChange : 0)
|
||||
@@ -4888,6 +4902,7 @@ case OP_CreateTable: { /* out2-prerelease */
|
||||
pgno = 0;
|
||||
assert( pOp->p1>=0 && pOp->p1<db->nDb );
|
||||
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
|
||||
assert( p->readOnly==0 );
|
||||
pDb = &db->aDb[pOp->p1];
|
||||
assert( pDb->pBt!=0 );
|
||||
if( pOp->opcode==OP_CreateTable ){
|
||||
@@ -5035,7 +5050,8 @@ case OP_IntegrityCk: {
|
||||
int nErr; /* Number of errors reported */
|
||||
char *z; /* Text of the error report */
|
||||
Mem *pnErr; /* Register keeping track of errors remaining */
|
||||
|
||||
|
||||
assert( p->bIsReader );
|
||||
nRoot = pOp->p2;
|
||||
assert( nRoot>0 );
|
||||
aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(nRoot+1) );
|
||||
@@ -5543,6 +5559,7 @@ case OP_Checkpoint: {
|
||||
int aRes[3]; /* Results */
|
||||
Mem *pMem; /* Write results here */
|
||||
|
||||
assert( p->readOnly==0 );
|
||||
aRes[0] = 0;
|
||||
aRes[1] = aRes[2] = -1;
|
||||
assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE
|
||||
@@ -5592,6 +5609,7 @@ case OP_JournalMode: { /* out2-prerelease */
|
||||
|| eNew==PAGER_JOURNALMODE_QUERY
|
||||
);
|
||||
assert( pOp->p1>=0 && pOp->p1<db->nDb );
|
||||
assert( p->readOnly==0 );
|
||||
|
||||
pBt = db->aDb[pOp->p1].pBt;
|
||||
pPager = sqlite3BtreePager(pBt);
|
||||
@@ -5615,7 +5633,7 @@ case OP_JournalMode: { /* out2-prerelease */
|
||||
if( (eNew!=eOld)
|
||||
&& (eOld==PAGER_JOURNALMODE_WAL || eNew==PAGER_JOURNALMODE_WAL)
|
||||
){
|
||||
if( !db->autoCommit || db->activeVdbeCnt>1 ){
|
||||
if( !db->autoCommit || db->nVdbeRead>1 ){
|
||||
rc = SQLITE_ERROR;
|
||||
sqlite3SetString(&p->zErrMsg, db,
|
||||
"cannot change %s wal mode from within a transaction",
|
||||
@@ -5674,6 +5692,7 @@ case OP_JournalMode: { /* out2-prerelease */
|
||||
** a transaction.
|
||||
*/
|
||||
case OP_Vacuum: {
|
||||
assert( p->readOnly==0 );
|
||||
rc = sqlite3RunVacuum(&p->zErrMsg, db);
|
||||
break;
|
||||
}
|
||||
@@ -5691,6 +5710,7 @@ case OP_IncrVacuum: { /* jump */
|
||||
|
||||
assert( pOp->p1>=0 && pOp->p1<db->nDb );
|
||||
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
|
||||
assert( p->readOnly==0 );
|
||||
pBt = db->aDb[pOp->p1].pBt;
|
||||
rc = sqlite3BtreeIncrVacuum(pBt);
|
||||
if( rc==SQLITE_DONE ){
|
||||
@@ -5809,6 +5829,7 @@ case OP_VOpen: {
|
||||
sqlite3_vtab *pVtab;
|
||||
sqlite3_module *pModule;
|
||||
|
||||
assert( p->bIsReader );
|
||||
pCur = 0;
|
||||
pVtabCursor = 0;
|
||||
pVtab = pOp->p4.pVtab->pVtab;
|
||||
@@ -6025,6 +6046,7 @@ case OP_VRename: {
|
||||
pName = &aMem[pOp->p1];
|
||||
assert( pVtab->pModule->xRename );
|
||||
assert( memIsValid(pName) );
|
||||
assert( p->readOnly==0 );
|
||||
REGISTER_TRACE(pOp->p1, pName);
|
||||
assert( pName->flags & MEM_Str );
|
||||
testcase( pName->enc==SQLITE_UTF8 );
|
||||
@@ -6076,6 +6098,7 @@ case OP_VUpdate: {
|
||||
assert( pOp->p2==1 || pOp->p5==OE_Fail || pOp->p5==OE_Rollback
|
||||
|| pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace
|
||||
);
|
||||
assert( p->readOnly==0 );
|
||||
pVtab = pOp->p4.pVtab->pVtab;
|
||||
pModule = (sqlite3_module *)pVtab->pModule;
|
||||
nArg = pOp->p2;
|
||||
|
@@ -337,7 +337,8 @@ struct Vdbe {
|
||||
bft expired:1; /* True if the VM needs to be recompiled */
|
||||
bft runOnlyOnce:1; /* Automatically expire on reset */
|
||||
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 doingRerun:1; /* True if rerunning after an auto-reprepare */
|
||||
int nChange; /* Number of db changes made since last reset */
|
||||
|
@@ -382,11 +382,11 @@ static int sqlite3Step(Vdbe *p){
|
||||
** reset the interrupt flag. This prevents a call to sqlite3_interrupt
|
||||
** from interrupting a statement that has not yet started.
|
||||
*/
|
||||
if( db->activeVdbeCnt==0 ){
|
||||
if( db->nVdbeActive==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)
|
||||
);
|
||||
|
||||
@@ -396,8 +396,9 @@ static int sqlite3Step(Vdbe *p){
|
||||
}
|
||||
#endif
|
||||
|
||||
db->activeVdbeCnt++;
|
||||
if( p->readOnly==0 ) db->writeVdbeCnt++;
|
||||
db->nVdbeActive++;
|
||||
if( p->readOnly==0 ) db->nVdbeWrite++;
|
||||
if( p->bIsReader ) db->nVdbeRead++;
|
||||
p->pc = 0;
|
||||
}
|
||||
#ifndef SQLITE_OMIT_EXPLAIN
|
||||
@@ -406,9 +407,9 @@ static int sqlite3Step(Vdbe *p){
|
||||
}else
|
||||
#endif /* SQLITE_OMIT_EXPLAIN */
|
||||
{
|
||||
db->vdbeExecCnt++;
|
||||
db->nVdbeExec++;
|
||||
rc = sqlite3VdbeExec(p);
|
||||
db->vdbeExecCnt--;
|
||||
db->nVdbeExec--;
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_TRACE
|
||||
|
@@ -404,14 +404,26 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
|
||||
Op *pOp;
|
||||
int *aLabel = p->aLabel;
|
||||
p->readOnly = 1;
|
||||
p->bIsReader = 0;
|
||||
for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
|
||||
u8 opcode = pOp->opcode;
|
||||
|
||||
pOp->opflags = sqlite3OpcodeProperty[opcode];
|
||||
if( opcode==OP_Function || opcode==OP_AggStep ){
|
||||
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->bIsReader = 1;
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
}else if( opcode==OP_VUpdate ){
|
||||
if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
|
||||
@@ -437,8 +449,8 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
|
||||
}
|
||||
sqlite3DbFree(p->db, p->aLabel);
|
||||
p->aLabel = 0;
|
||||
|
||||
*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
|
||||
** 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
|
||||
@@ -1977,16 +1989,19 @@ static void checkActiveVdbeCnt(sqlite3 *db){
|
||||
Vdbe *p;
|
||||
int cnt = 0;
|
||||
int nWrite = 0;
|
||||
int nRead = 0;
|
||||
p = db->pVdbe;
|
||||
while( p ){
|
||||
if( p->magic==VDBE_MAGIC_RUN && p->pc>=0 ){
|
||||
cnt++;
|
||||
if( p->readOnly==0 ) nWrite++;
|
||||
if( p->bIsReader ) nRead++;
|
||||
}
|
||||
p = p->pNext;
|
||||
}
|
||||
assert( cnt==db->activeVdbeCnt );
|
||||
assert( nWrite==db->writeVdbeCnt );
|
||||
assert( cnt==db->nVdbeActive );
|
||||
assert( nWrite==db->nVdbeWrite );
|
||||
assert( nRead==db->nVdbeRead );
|
||||
}
|
||||
#else
|
||||
#define checkActiveVdbeCnt(x)
|
||||
@@ -2125,8 +2140,9 @@ int sqlite3VdbeHalt(Vdbe *p){
|
||||
}
|
||||
checkActiveVdbeCnt(db);
|
||||
|
||||
/* No commit or rollback needed if the program never started */
|
||||
if( p->pc>=0 ){
|
||||
/* No commit or rollback needed if the program never started or if the
|
||||
** 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 eStatementOp = 0;
|
||||
int isSpecialError; /* Set to true if a 'special' error */
|
||||
@@ -2179,7 +2195,7 @@ int sqlite3VdbeHalt(Vdbe *p){
|
||||
*/
|
||||
if( !sqlite3VtabInSync(db)
|
||||
&& db->autoCommit
|
||||
&& db->writeVdbeCnt==(p->readOnly==0)
|
||||
&& db->nVdbeWrite==(p->readOnly==0)
|
||||
){
|
||||
if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){
|
||||
rc = sqlite3VdbeCheckFk(p, 1);
|
||||
@@ -2262,11 +2278,12 @@ int sqlite3VdbeHalt(Vdbe *p){
|
||||
|
||||
/* We have successfully halted and closed the VM. Record this fact. */
|
||||
if( p->pc>=0 ){
|
||||
db->activeVdbeCnt--;
|
||||
if( !p->readOnly ){
|
||||
db->writeVdbeCnt--;
|
||||
}
|
||||
assert( db->activeVdbeCnt>=db->writeVdbeCnt );
|
||||
db->nVdbeActive--;
|
||||
if( !p->readOnly ) db->nVdbeWrite--;
|
||||
if( p->bIsReader ) db->nVdbeRead--;
|
||||
assert( db->nVdbeActive>=db->nVdbeRead );
|
||||
assert( db->nVdbeRead>=db->nVdbeWrite );
|
||||
assert( db->nVdbeWrite>=0 );
|
||||
}
|
||||
p->magic = VDBE_MAGIC_HALT;
|
||||
checkActiveVdbeCnt(db);
|
||||
@@ -2282,7 +2299,7 @@ int sqlite3VdbeHalt(Vdbe *p){
|
||||
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);
|
||||
}
|
||||
|
||||
|
@@ -47,9 +47,9 @@ static int findNextHostParameter(const char *zSql, int *pnToken){
|
||||
|
||||
/*
|
||||
** 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
|
||||
** 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
|
||||
** to each line of text.
|
||||
**
|
||||
@@ -87,7 +87,7 @@ char *sqlite3VdbeExpandSql(
|
||||
sqlite3StrAccumInit(&out, zBase, sizeof(zBase),
|
||||
db->aLimit[SQLITE_LIMIT_LENGTH]);
|
||||
out.db = db;
|
||||
if( db->vdbeExecCnt>1 ){
|
||||
if( db->nVdbeExec>1 ){
|
||||
while( *zRawSql ){
|
||||
const char *zStart = zRawSql;
|
||||
while( *(zRawSql++)!='\n' && *zRawSql );
|
||||
|
@@ -2463,7 +2463,7 @@ int sqlite3WalBeginWriteTransaction(Wal *pWal){
|
||||
if( memcmp(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr))!=0 ){
|
||||
walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
|
||||
pWal->writeLock = 0;
|
||||
rc = SQLITE_BUSY;
|
||||
rc = SQLITE_BUSY_SNAPSHOT;
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
104
src/where.c
104
src/where.c
@@ -159,7 +159,7 @@ static int whereLoopResize(sqlite3*, WhereLoop*, int);
|
||||
** Each instance of this object holds a sequence of WhereLoop objects
|
||||
** 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
|
||||
** not a completely accurate description because WhereLoop costs are a
|
||||
** 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
|
||||
** 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_IN 0x00000004 /* x IN (...) */
|
||||
#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_ONEROW 0x00001000 /* Selects no more than one row */
|
||||
#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.
|
||||
@@ -822,7 +822,7 @@ static u16 operatorMask(int op){
|
||||
** established when the pScan object was initialized by whereScanInit().
|
||||
** 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 iColumn; /* The column on the LHS of the term. -1 for IPK */
|
||||
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
|
||||
** index pIdx.
|
||||
*/
|
||||
WhereTerm *whereScanInit(
|
||||
static WhereTerm *whereScanInit(
|
||||
WhereScan *pScan, /* The WhereScan object being initialized */
|
||||
WhereClause *pWC, /* The WHERE clause to be scanned */
|
||||
int iCur, /* Cursor to scan for */
|
||||
@@ -1738,6 +1738,7 @@ static void exprAnalyze(
|
||||
if( pExpr->op==TK_NOTNULL
|
||||
&& pExpr->pLeft->op==TK_COLUMN
|
||||
&& pExpr->pLeft->iColumn>=0
|
||||
&& OptimizationEnabled(db, SQLITE_Stat3)
|
||||
){
|
||||
Expr *pNewExpr;
|
||||
Expr *pLeft = pExpr->pLeft;
|
||||
@@ -2041,6 +2042,7 @@ static void constructAutomaticIndex(
|
||||
WhereLoop *pLoop; /* The Loop object */
|
||||
Bitmask idxCols; /* Bitmap of columns used for indexing */
|
||||
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
|
||||
** 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);
|
||||
testcase( iCol==BMS );
|
||||
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( whereLoopResize(pParse->db, pLoop, nColumn+1) ) return;
|
||||
pLoop->aLTerm[nColumn++] = pTerm;
|
||||
@@ -2071,7 +2079,7 @@ static void constructAutomaticIndex(
|
||||
assert( nColumn>0 );
|
||||
pLoop->u.btree.nEq = pLoop->nLTerm = nColumn;
|
||||
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
|
||||
** covering index. A "covering index" is an index that contains all
|
||||
@@ -2571,7 +2579,7 @@ static int whereRangeScanEst(
|
||||
|
||||
#ifdef SQLITE_ENABLE_STAT3
|
||||
|
||||
if( nEq==0 && p->nSample ){
|
||||
if( nEq==0 && p->nSample && OptimizationEnabled(pParse->db, SQLITE_Stat3) ){
|
||||
sqlite3_value *pRangeVal;
|
||||
tRowcnt iLower = 0;
|
||||
tRowcnt iUpper = p->aiRowEst[0];
|
||||
@@ -3117,13 +3125,12 @@ static void explainOneScan(
|
||||
&& ALWAYS(pLoop->u.btree.pIndex!=0)
|
||||
){
|
||||
char *zWhere = explainIndexRange(db, pLoop, pItem->pTab);
|
||||
zMsg = sqlite3MAppendf(db, zMsg, "%s USING %s%sINDEX%s%s%s", zMsg,
|
||||
((flags & WHERE_TEMP_INDEX)?"AUTOMATIC ":""),
|
||||
((flags & WHERE_IDX_ONLY)?"COVERING ":""),
|
||||
((flags & WHERE_TEMP_INDEX)?"":" "),
|
||||
((flags & WHERE_TEMP_INDEX)?"": pLoop->u.btree.pIndex->zName),
|
||||
zWhere
|
||||
);
|
||||
zMsg = sqlite3MAppendf(db, zMsg,
|
||||
((flags & WHERE_AUTO_INDEX) ?
|
||||
"%s USING AUTOMATIC %sINDEX%.0s%s" :
|
||||
"%s USING %sINDEX %s%s"),
|
||||
zMsg, ((flags & WHERE_IDX_ONLY) ? "COVERING " : ""),
|
||||
pLoop->u.btree.pIndex->zName, zWhere);
|
||||
sqlite3DbFree(db, zWhere);
|
||||
}else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){
|
||||
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_GE==TK_GT+3 ); /* ... is correcct. */
|
||||
|
||||
assert( (pStart->wtFlags & TERM_VNULL)==0 );
|
||||
testcase( pStart->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
|
||||
pX = pStart->pExpr;
|
||||
assert( pX!=0 );
|
||||
assert( pStart->leftCursor==iCur );
|
||||
testcase( pStart->leftCursor!=iCur ); /* transitive constraints */
|
||||
r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp);
|
||||
sqlite3VdbeAddOp3(v, aMoveOp[pX->op-TK_GT], iCur, addrBrk, r1);
|
||||
VdbeComment((v, "pk"));
|
||||
@@ -3345,7 +3353,8 @@ static Bitmask codeOneLoopStart(
|
||||
Expr *pX;
|
||||
pX = pEnd->pExpr;
|
||||
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 */
|
||||
memEndValue = ++pParse->nMem;
|
||||
sqlite3ExprCode(pParse, pX->pRight, memEndValue);
|
||||
@@ -3794,7 +3803,7 @@ static Bitmask codeOneLoopStart(
|
||||
** be available.
|
||||
*/
|
||||
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
|
||||
&& (ii==0 || pSubLoop->u.btree.pIndex==pCov)
|
||||
){
|
||||
@@ -3880,6 +3889,7 @@ static Bitmask codeOneLoopStart(
|
||||
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
|
||||
if( pTerm->eOperator!=(WO_EQUIV|WO_EQ) ) continue;
|
||||
if( pTerm->leftCursor!=iCur ) continue;
|
||||
if( pLevel->iLeftJoin ) continue;
|
||||
pE = pTerm->pExpr;
|
||||
assert( !ExprHasProperty(pE, EP_FromJoin) );
|
||||
assert( (pTerm->prereqRight & newNotReady)!=0 );
|
||||
@@ -3976,12 +3986,12 @@ static void whereLoopInit(WhereLoop *p){
|
||||
** Clear the WhereLoop.u union. Leave WhereLoop.pLTerm intact.
|
||||
*/
|
||||
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 ){
|
||||
sqlite3_free(p->u.vtab.idxStr);
|
||||
p->u.vtab.needFree = 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);
|
||||
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]));
|
||||
if( pFrom->wsFlags & WHERE_VIRTUALTABLE ){
|
||||
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;
|
||||
}
|
||||
return SQLITE_OK;
|
||||
@@ -4274,6 +4284,11 @@ static int whereLoopAddBtreeIndex(
|
||||
for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){
|
||||
int nIn = 0;
|
||||
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->u.btree.nEq = saved_nEq;
|
||||
pNew->nLTerm = saved_nLTerm;
|
||||
@@ -4336,7 +4351,8 @@ static int whereLoopAddBtreeIndex(
|
||||
pNew->nOut = saved_nOut>rDiv+10 ? saved_nOut - rDiv : 10;
|
||||
}
|
||||
#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;
|
||||
if( (pTerm->eOperator & (WO_EQ|WO_ISNULL))!=0 ){
|
||||
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
|
||||
** a b-tree table, not a virtual table.
|
||||
*/
|
||||
@@ -4496,13 +4512,16 @@ static int whereLoopAddBtree(
|
||||
pNew->nLTerm = 1;
|
||||
pNew->aLTerm[0] = pTerm;
|
||||
/* 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. */
|
||||
pNew->rSetup = rLogSize + rSize + 26; assert( 26==whereCost(6) );
|
||||
/* TUNING: Each index lookup yields 10 rows in the table */
|
||||
pNew->nOut = 33; assert( 33==whereCost(10) );
|
||||
pNew->rSetup = rLogSize + rSize + 28; assert( 28==whereCost(7) );
|
||||
/* TUNING: Each index lookup yields 20 rows in the table. This
|
||||
** 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->wsFlags = WHERE_TEMP_INDEX;
|
||||
pNew->wsFlags = WHERE_AUTO_INDEX;
|
||||
pNew->prereq = mExtra | pTerm->prereqRight;
|
||||
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
|
||||
** 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
|
||||
** 1: ORDER BY is satisfied. Omit sorting
|
||||
** -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(
|
||||
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
|
||||
** 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
|
||||
**
|
||||
** 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
|
||||
** is called from an UPDATE or DELETE statement, then pOrderBy is NULL.
|
||||
*/
|
||||
@@ -5643,6 +5670,7 @@ WhereInfo *sqlite3WhereBegin(
|
||||
whereClauseInit(&pWInfo->sWC, pWInfo);
|
||||
sqlite3ExprCodeConstants(pParse, pWhere);
|
||||
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
|
||||
** expression and either jump over all of the code or fall thru.
|
||||
@@ -5796,6 +5824,7 @@ WhereInfo *sqlite3WhereBegin(
|
||||
Bitmask tabUsed = exprListTableUsage(pMaskSet, pResultSet);
|
||||
if( pOrderBy ) tabUsed |= exprListTableUsage(pMaskSet, pOrderBy);
|
||||
while( pWInfo->nLevel>=2 ){
|
||||
WhereTerm *pTerm, *pEnd;
|
||||
pLoop = pWInfo->a[pWInfo->nLevel-1].pWLoop;
|
||||
if( (pWInfo->pTabList->a[pLoop->iTab].jointype & JT_LEFT)==0 ) break;
|
||||
if( (wctrlFlags & WHERE_WANT_DISTINCT)==0
|
||||
@@ -5804,6 +5833,15 @@ WhereInfo *sqlite3WhereBegin(
|
||||
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));
|
||||
pWInfo->nLevel--;
|
||||
nTabList--;
|
||||
@@ -5827,13 +5865,11 @@ WhereInfo *sqlite3WhereBegin(
|
||||
/* Open all tables in the pTabList and any indices selected for
|
||||
** searching those tables.
|
||||
*/
|
||||
sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
|
||||
notReady = ~(Bitmask)0;
|
||||
for(ii=0, pLevel=pWInfo->a; ii<nTabList; ii++, pLevel++){
|
||||
Table *pTab; /* Table to open */
|
||||
int iDb; /* Index of database containing table/index */
|
||||
struct SrcList_item *pTabItem;
|
||||
WhereLoop *pLoop;
|
||||
|
||||
pTabItem = &pTabList->a[pLevel->iFrom];
|
||||
pTab = pTabItem->pTab;
|
||||
@@ -5869,7 +5905,7 @@ WhereInfo *sqlite3WhereBegin(
|
||||
sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
|
||||
}
|
||||
#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);
|
||||
}else
|
||||
#endif
|
||||
@@ -5992,7 +6028,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
|
||||
if( !pWInfo->okOnePass && (ws & WHERE_IDX_ONLY)==0 ){
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@@ -23,6 +23,14 @@ ifcapable {!autoindex} {
|
||||
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
|
||||
do_test autoindex1-100 {
|
||||
db eval {
|
||||
@@ -60,6 +68,15 @@ do_test autoindex1-111 {
|
||||
do_test autoindex1-112 {
|
||||
db status autoindex
|
||||
} {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
|
||||
# than a join.
|
||||
@@ -94,9 +111,15 @@ do_test autoindex1-212 {
|
||||
|
||||
# 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 {
|
||||
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
|
||||
db eval {UPDATE t2 SET d=d+1}
|
||||
}
|
||||
|
@@ -13,7 +13,6 @@ puts {# 2008 December 11
|
||||
# This file is automatically generated from a separate TCL script.
|
||||
# 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]
|
||||
source $testdir/tester.tcl
|
||||
@@ -40,16 +39,16 @@ foreach x {
|
||||
} {
|
||||
set x [expr {wide($x)}]
|
||||
set boundarynum($x) 1
|
||||
set boundarynum([expr {$x+1}]) 1
|
||||
set boundarynum([expr {-($x+1)}]) 1
|
||||
set boundarynum([expr {-($x+2)}]) 1
|
||||
set boundarynum([expr {$x+$x+1}]) 1
|
||||
set boundarynum([expr {$x+$x+2}]) 1
|
||||
set boundarynum([expr {wide($x+1)}]) 1
|
||||
set boundarynum([expr {wide(-($x+1))}]) 1
|
||||
set boundarynum([expr {wide(-($x+2))}]) 1
|
||||
set boundarynum([expr {wide($x+$x+1)}]) 1
|
||||
set boundarynum([expr {wide($x+$x+2)}]) 1
|
||||
}
|
||||
set x [expr {wide(127)}]
|
||||
for {set i 1} {$i<=9} {incr i} {
|
||||
set boundarynum($x) 1
|
||||
set boundarynum([expr {$x+1}]) 1
|
||||
set boundarynum([expr {wide($x+1)}]) 1
|
||||
set x [expr {wide($x*128 + 127)}]
|
||||
}
|
||||
|
||||
@@ -116,7 +115,7 @@ foreach r $nums1 {
|
||||
incr a
|
||||
set t1ra($r) $a
|
||||
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 t1xr($x) $r
|
||||
puts " INSERT INTO t1(oid,a,x) VALUES($r,$a,'$x');"
|
||||
@@ -158,7 +157,7 @@ foreach r $nums3 {
|
||||
|
||||
set r5 $r.5
|
||||
set r0 $r.0
|
||||
if {abs($r)<9.22337203685477580800e+18} {
|
||||
if {abs($r)<0x7FFFFFFFFFFFFFFF || $r==-9223372036854775808} {
|
||||
set x $t1rx($r)
|
||||
set a $t1ra($r)
|
||||
puts "do_test $tname-2.$i.1 \173"
|
||||
|
@@ -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.4 {UPDATE t1 SET x=x+1 WHERE x<0} 0
|
||||
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 {
|
||||
sqlite3_stmt_readonly 0
|
||||
} 1
|
||||
|
@@ -1294,7 +1294,7 @@ proc rev {str} {
|
||||
set ret
|
||||
}
|
||||
proc reverse {lhs rhs} {
|
||||
string compare [rev $lhs] [ref $rhs]
|
||||
string compare [rev $lhs] [rev $rhs]
|
||||
}
|
||||
db collate reverse reverse
|
||||
do_execsql_test e_expr-23.1.1 {
|
||||
@@ -1317,7 +1317,7 @@ do_execsql_test e_expr-23.1.4 {
|
||||
} {B}
|
||||
do_execsql_test e_expr-23.1.5 {
|
||||
SELECT CASE b WHEN a THEN 'A' ELSE 'B' END FROM t1
|
||||
} {A}
|
||||
} {B}
|
||||
do_execsql_test e_expr-23.1.6 {
|
||||
SELECT CASE 55 WHEN '55' THEN 'A' ELSE 'B' END
|
||||
} {B}
|
||||
|
@@ -94,7 +94,7 @@ sqlite3_shutdown
|
||||
sqlite3_config_pagecache [expr 1024+$xtra_size] 20
|
||||
sqlite3_initialize
|
||||
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
|
||||
set MEMORY_MANAGEMENT $sqlite_options(memorymanage)
|
||||
ifcapable !malloc_usable_size {
|
||||
|
@@ -12,7 +12,7 @@
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
ifcapable !mmap {
|
||||
ifcapable !mmap||!vtab {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
77
test/mmapfault.test
Normal file
77
test/mmapfault.test
Normal 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
|
@@ -44,6 +44,7 @@ do_test pcache-1.2 {
|
||||
execsql {
|
||||
PRAGMA cache_size=12;
|
||||
PRAGMA auto_vacuum=0;
|
||||
PRAGMA mmap_size=0;
|
||||
}
|
||||
pcache_stats
|
||||
} {current 1 max 12 min 10 recyclable 1}
|
||||
|
@@ -180,28 +180,30 @@ do_test percentile-1.21 {
|
||||
|
||||
# Million-row Inputs
|
||||
#
|
||||
do_test percentile-2.0 {
|
||||
load_static_extension db wholenumber
|
||||
execsql {
|
||||
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 {
|
||||
ifcapable vtab {
|
||||
do_test percentile-2.0 {
|
||||
load_static_extension db wholenumber
|
||||
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
|
||||
|
@@ -450,5 +450,23 @@ do_test select9-5.3 {
|
||||
}
|
||||
} {/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
|
||||
|
@@ -397,9 +397,9 @@ do_test shell1-3.11.1 {
|
||||
do_test shell1-3.11.2 {
|
||||
catchcmd "test.db" ".import FOO"
|
||||
} {1 {Error: unknown command or invalid arguments: "import". Enter ".help" for help}}
|
||||
do_test shell1-3.11.2 {
|
||||
catchcmd "test.db" ".import FOO BAR"
|
||||
} {1 {Error: no such table: BAR}}
|
||||
#do_test shell1-3.11.2 {
|
||||
# catchcmd "test.db" ".import FOO BAR"
|
||||
#} {1 {Error: no such table: BAR}}
|
||||
do_test shell1-3.11.3 {
|
||||
# too many arguments
|
||||
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"
|
||||
} {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
|
||||
#
|
||||
do_test shell1-4.1 {
|
||||
|
@@ -45,9 +45,9 @@ do_test shell5-1.1.1 {
|
||||
do_test shell5-1.1.2 {
|
||||
catchcmd "test.db" ".import FOO"
|
||||
} {1 {Error: unknown command or invalid arguments: "import". Enter ".help" for help}}
|
||||
do_test shell5-1.1.2 {
|
||||
catchcmd "test.db" ".import FOO BAR"
|
||||
} {1 {Error: no such table: BAR}}
|
||||
#do_test shell5-1.1.2 {
|
||||
# catchcmd "test.db" ".import FOO BAR"
|
||||
#} {1 {Error: no such table: BAR}}
|
||||
do_test shell5-1.1.3 {
|
||||
# too many arguments
|
||||
catchcmd "test.db" ".import FOO BAR BAD"
|
||||
@@ -101,7 +101,7 @@ do_test shell5-1.4.3 {
|
||||
puts $in "1"
|
||||
close $in
|
||||
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)
|
||||
do_test shell5-1.4.4 {
|
||||
@@ -109,14 +109,15 @@ do_test shell5-1.4.4 {
|
||||
puts $in "1|2|3"
|
||||
close $in
|
||||
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
|
||||
do_test shell5-1.4.5 {
|
||||
set in [open shell5.csv w]
|
||||
puts $in "1|2"
|
||||
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;}]
|
||||
} {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.
|
||||
set cols 999
|
||||
do_test shell5-1.6.1 {
|
||||
set sql {CREATE TABLE t2(}
|
||||
set data {}
|
||||
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 sql "c$cols);"
|
||||
append data "$cols"
|
||||
catchcmd "test.db" $sql
|
||||
set in [open shell5.csv w]
|
||||
puts $in $data
|
||||
close $in
|
||||
@@ -214,16 +215,31 @@ SELECT COUNT(*) FROM t2;}]
|
||||
} {0 1}
|
||||
|
||||
# try importing a large number of rows
|
||||
set rows 999999
|
||||
set rows 9999
|
||||
do_test shell5-1.7.1 {
|
||||
set in [open shell5.csv w]
|
||||
puts $in a
|
||||
for {set i 1} {$i<=$rows} {incr i} {
|
||||
puts $in $i
|
||||
}
|
||||
close $in
|
||||
set res [catchcmd "test.db" {CREATE TABLE t3(a);
|
||||
set res [catchcmd "test.db" {.mode csv
|
||||
.import shell5.csv t3
|
||||
SELECT COUNT(*) FROM t3;}]
|
||||
} [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
|
||||
|
@@ -105,6 +105,22 @@ do_test 1.14 {
|
||||
catchsql {SELECT next_char('','xyzzy','a')}
|
||||
} {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 {
|
||||
CREATE VIRTUAL TABLE t2 USING spellfix1;
|
||||
INSERT INTO t2 (word, soundslike) VALUES('school', 'skuul');
|
||||
|
64
test/tkt-868145d012.test
Normal file
64
test/tkt-868145d012.test
Normal 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
|
@@ -47,4 +47,59 @@ do_execsql_test transitive1-220 {
|
||||
SELECT * FROM t2 WHERE a=b AND c=b AND c<=20 ORDER BY +a;
|
||||
} {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
|
||||
|
166
test/wal6.test
166
test/wal6.test
@@ -14,6 +14,7 @@
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
set testprefix wal6
|
||||
source $testdir/tester.tcl
|
||||
source $testdir/lock_common.tcl
|
||||
source $testdir/wal_common.tcl
|
||||
@@ -29,18 +30,18 @@ forcedelete test.db
|
||||
set all_journal_modes {delete persist truncate memory off}
|
||||
foreach jmode $all_journal_modes {
|
||||
|
||||
do_test wal6-1.0.$jmode {
|
||||
do_test wal6-1.0.$jmode {
|
||||
sqlite3 db test.db
|
||||
execsql "PRAGMA journal_mode = $jmode;"
|
||||
} $jmode
|
||||
} $jmode
|
||||
|
||||
do_test wal6-1.1.$jmode {
|
||||
execsql {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
|
||||
INSERT INTO t1 VALUES(1,2);
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {1 2}
|
||||
do_test wal6-1.1.$jmode {
|
||||
execsql {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
|
||||
INSERT INTO t1 VALUES(1,2);
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {1 2}
|
||||
|
||||
# Under Windows, you'll get an error trying to delete
|
||||
# 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 {
|
||||
sqlite3 db2 test.db
|
||||
execsql {
|
||||
PRAGMA journal_mode=WAL;
|
||||
INSERT INTO t1 VALUES(3,4);
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
} db2
|
||||
} {wal 1 2 3 4}
|
||||
do_test wal6-1.2.$jmode {
|
||||
sqlite3 db2 test.db
|
||||
execsql {
|
||||
PRAGMA journal_mode=WAL;
|
||||
INSERT INTO t1 VALUES(3,4);
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
} db2
|
||||
} {wal 1 2 3 4}
|
||||
|
||||
if {$tcl_platform(platform)=="windows"} {
|
||||
if {$jmode=="persist" || $jmode=="truncate"} {
|
||||
sqlite3 db test.db
|
||||
sqlite3 db test.db
|
||||
}
|
||||
}
|
||||
|
||||
do_test wal6-1.3.$jmode {
|
||||
execsql {
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
}
|
||||
} {1 2 3 4}
|
||||
do_test wal6-1.3.$jmode {
|
||||
execsql {
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
}
|
||||
} {1 2 3 4}
|
||||
|
||||
db close
|
||||
db2 close
|
||||
db close
|
||||
db2 close
|
||||
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
|
||||
|
||||
|
@@ -307,6 +307,8 @@ do_test where2-6.6 {
|
||||
}
|
||||
} [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
|
||||
# comparisons between columns of different affinities are needed.
|
||||
#
|
||||
@@ -474,6 +476,8 @@ do_test where2-7.4 {
|
||||
}
|
||||
} {1 2 3 2 3 nosort}
|
||||
|
||||
} ;# if {[permutation] != "no_optimization"}
|
||||
|
||||
# Ticket #1807. Using IN constrains on multiple columns of
|
||||
# a multi-column index.
|
||||
#
|
||||
|
@@ -436,5 +436,48 @@ foreach predicate {
|
||||
} {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
|
||||
|
311
test/wild001.test
Normal file
311
test/wild001.test
Normal 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
|
Reference in New Issue
Block a user