Compare commits
138 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4598bf806c | |||
| 608e2f0919 | |||
| f311315ffd | |||
| ed7974dee5 | |||
| 19f7bd3b07 | |||
| d1d43efa4f | |||
| beb22d086b | |||
| 461ff3594b | |||
| 403869680b | |||
| 672f07c642 | |||
| 1a56fce614 | |||
| 94d6f3f836 | |||
| 787f6d418d | |||
| 07d7a8dca9 | |||
| 340558540e | |||
| a00a016740 | |||
| ff01ee34c9 | |||
| e93986a93b | |||
| 71cb422055 | |||
| f8c4c3a09f | |||
| d5157e01b8 | |||
| 05881886a6 | |||
| 7207be402d | |||
| f6b0464e36 | |||
| c6712647c6 | |||
| c196219dd4 | |||
| 936a30598e | |||
| bbb29ecfb4 | |||
| 4d906f1b5a | |||
| 1ca037f41e | |||
| 0897c3c056 | |||
| a41cc5c6f0 | |||
| f46be6a1b9 | |||
| a344ad47f3 | |||
| 12a6a1eaf9 | |||
| 95dca8d0cf | |||
| 7093a3be03 | |||
| 7d14ffe4e1 | |||
| 64208b50ce | |||
| 9bb612f2c8 | |||
| 04e70ce07d | |||
| 4ad1a1c74c | |||
| d7d406e81c | |||
| a22c1c84cc | |||
| ccf578d435 | |||
| deaa61072d | |||
| 644f43c0f7 | |||
| 67306cb3b4 | |||
| 33a99fad08 | |||
| fad4dd0fd1 | |||
| 4f65b3bbfb | |||
| 395a60dad4 | |||
| af3711536b | |||
| 1e6c58dee2 | |||
| a957e22fa4 | |||
| f287d00108 | |||
| a54e1b1fc8 | |||
| 0b2949c36e | |||
| dfbaae7572 | |||
| c40076a8cf | |||
| 46f0f4e56d | |||
| f761d937c2 | |||
| 68cf0ace3d | |||
| 75fa266341 | |||
| f573b4fb94 | |||
| f36cbefe81 | |||
| 399b740986 | |||
| 3a8847a5fc | |||
| fc1070bfc4 | |||
| 9e3b8ae1e0 | |||
| 9a28680095 | |||
| abd2779560 | |||
| 153fa608bf | |||
| b4e313a5b0 | |||
| 273ee15121 | |||
| 7548ab20e6 | |||
| 9ca41fbfa9 | |||
| 79d9af960b | |||
| 68cffa65fb | |||
| 39c7125a97 | |||
| f2e151aeab | |||
| acc225a7a1 | |||
| 3acd3fb9d8 | |||
| f2fa084cf1 | |||
| bc2e95140b | |||
| f1ea425560 | |||
| d96e3821e4 | |||
| 18ef40e563 | |||
| b5a69238b4 | |||
| ddcfe92105 | |||
| 86f477edaa | |||
| 94acc2ef42 | |||
| 4fb8452875 | |||
| 786142a994 | |||
| ebd2ecdda7 | |||
| 8ab0809473 | |||
| 2b75d3beb0 | |||
| 78f04753ae | |||
| 2b06b0769e | |||
| 52cfe0312a | |||
| 512aa78ca2 | |||
| 60c71b02ca | |||
| fa17e134b2 | |||
| d321b6f4ad | |||
| 37ccfcfeb9 | |||
| c51ceeb049 | |||
| acd3c8a995 | |||
| d49c0c83ef | |||
| 6acdee6765 | |||
| 8337da6678 | |||
| 72c38d87bf | |||
| 7b8524168e | |||
| e2678b93af | |||
| 832aa023c6 | |||
| 04cd60e18c | |||
| 92e21ef079 | |||
| 359941bd33 | |||
| ca3ee7e18a | |||
| 60081a0382 | |||
| 30497f4169 | |||
| 99744fa4ab | |||
| 58d6f633ba | |||
| 599456f0ab | |||
| 6c3b4b07d1 | |||
| 7b14b990d0 | |||
| 14f38b3d0a | |||
| 46fe138d98 | |||
| 1d42e619ac | |||
| fce445b8fa | |||
| 9191c702fc | |||
| 1d8f892a31 | |||
| 45d827cb6a | |||
| 289a0c849b | |||
| f0b41745c5 | |||
| 398221e2ad | |||
| 861889e4f8 | |||
| a3d6d6a93f | |||
| e0404386f2 |
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for sqlite 3.33.0.
|
||||
# Generated by GNU Autoconf 2.69 for sqlite 3.34.0.
|
||||
#
|
||||
#
|
||||
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
|
||||
@@ -726,8 +726,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='sqlite'
|
||||
PACKAGE_TARNAME='sqlite'
|
||||
PACKAGE_VERSION='3.33.0'
|
||||
PACKAGE_STRING='sqlite 3.33.0'
|
||||
PACKAGE_VERSION='3.34.0'
|
||||
PACKAGE_STRING='sqlite 3.34.0'
|
||||
PACKAGE_BUGREPORT=''
|
||||
PACKAGE_URL=''
|
||||
|
||||
@@ -1467,7 +1467,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures sqlite 3.33.0 to adapt to many kinds of systems.
|
||||
\`configure' configures sqlite 3.34.0 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@@ -1532,7 +1532,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of sqlite 3.33.0:";;
|
||||
short | recursive ) echo "Configuration of sqlite 3.34.0:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1659,7 +1659,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
sqlite configure 3.33.0
|
||||
sqlite configure 3.34.0
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
@@ -2078,7 +2078,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by sqlite $as_me 3.33.0, which was
|
||||
It was created by sqlite $as_me 3.34.0, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@@ -12243,7 +12243,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by sqlite $as_me 3.33.0, which was
|
||||
This file was extended by sqlite $as_me 3.34.0, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -12309,7 +12309,7 @@ _ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
sqlite config.status 3.33.0
|
||||
sqlite config.status 3.34.0
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
||||
+329
-170
File diff suppressed because it is too large
Load Diff
@@ -326,6 +326,47 @@ do_setup_rec_test $tn.16 {
|
||||
SCAN TABLE t1
|
||||
}
|
||||
|
||||
do_setup_rec_test $tn.17.1 {
|
||||
CREATE TABLE example (A INTEGER, B INTEGER, C INTEGER, PRIMARY KEY (A,B));
|
||||
} {
|
||||
SELECT * FROM example WHERE a=?
|
||||
} {
|
||||
(no new indexes)
|
||||
SEARCH TABLE example USING INDEX sqlite_autoindex_example_1 (A=?)
|
||||
}
|
||||
do_setup_rec_test $tn.17.2 {
|
||||
CREATE TABLE example (A INTEGER, B INTEGER, C INTEGER, PRIMARY KEY (A,B));
|
||||
} {
|
||||
SELECT * FROM example WHERE b=?
|
||||
} {
|
||||
CREATE INDEX example_idx_00000042 ON example(B);
|
||||
SEARCH TABLE example USING INDEX example_idx_00000042 (B=?)
|
||||
}
|
||||
do_setup_rec_test $tn.17.3 {
|
||||
CREATE TABLE example (A INTEGER, B INTEGER, C INTEGER, PRIMARY KEY (A,B));
|
||||
} {
|
||||
SELECT * FROM example WHERE a=? AND b=?
|
||||
} {
|
||||
(no new indexes)
|
||||
SEARCH TABLE example USING INDEX sqlite_autoindex_example_1 (A=? AND B=?)
|
||||
}
|
||||
do_setup_rec_test $tn.17.4 {
|
||||
CREATE TABLE example (A INTEGER, B INTEGER, C INTEGER, PRIMARY KEY (A,B));
|
||||
} {
|
||||
SELECT * FROM example WHERE a=? AND b>?
|
||||
} {
|
||||
(no new indexes)
|
||||
SEARCH TABLE example USING INDEX sqlite_autoindex_example_1 (A=? AND B>?)
|
||||
}
|
||||
do_setup_rec_test $tn.17.5 {
|
||||
CREATE TABLE example (A INTEGER, B INTEGER, C INTEGER, PRIMARY KEY (A,B));
|
||||
} {
|
||||
SELECT * FROM example WHERE a>? AND b=?
|
||||
} {
|
||||
CREATE INDEX example_idx_0000cb3f ON example(B, A);
|
||||
SEARCH TABLE example USING INDEX example_idx_0000cb3f (B=? AND A>?)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
proc do_candidates_test {tn sql res} {
|
||||
|
||||
@@ -685,6 +685,7 @@ static int idxGetTableInfo(
|
||||
IdxTable *pNew = 0;
|
||||
int rc, rc2;
|
||||
char *pCsr = 0;
|
||||
int nPk = 0;
|
||||
|
||||
rc = idxPrintfPrepareStmt(db, &p1, pzErrmsg, "PRAGMA table_info=%Q", zTab);
|
||||
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){
|
||||
@@ -695,6 +696,7 @@ static int idxGetTableInfo(
|
||||
);
|
||||
nByte += 1 + STRLEN(zCol);
|
||||
nCol++;
|
||||
nPk += (sqlite3_column_int(p1, 5)>0);
|
||||
}
|
||||
rc2 = sqlite3_reset(p1);
|
||||
if( rc==SQLITE_OK ) rc = rc2;
|
||||
@@ -714,7 +716,7 @@ static int idxGetTableInfo(
|
||||
const char *zCol = (const char*)sqlite3_column_text(p1, 1);
|
||||
int nCopy = STRLEN(zCol) + 1;
|
||||
pNew->aCol[nCol].zName = pCsr;
|
||||
pNew->aCol[nCol].iPk = sqlite3_column_int(p1, 5);
|
||||
pNew->aCol[nCol].iPk = (sqlite3_column_int(p1, 5)==1 && nPk==1);
|
||||
memcpy(pCsr, zCol, nCopy);
|
||||
pCsr += nCopy;
|
||||
|
||||
|
||||
+23
-9
@@ -184,6 +184,7 @@ struct Fts5Config {
|
||||
Fts5Tokenizer *pTok;
|
||||
fts5_tokenizer *pTokApi;
|
||||
int bLock; /* True when table is preparing statement */
|
||||
int ePattern; /* FTS_PATTERN_XXX constant */
|
||||
|
||||
/* Values loaded from the %_config table */
|
||||
int iCookie; /* Incremented when %_config is modified */
|
||||
@@ -204,17 +205,19 @@ struct Fts5Config {
|
||||
};
|
||||
|
||||
/* Current expected value of %_config table 'version' field */
|
||||
#define FTS5_CURRENT_VERSION 4
|
||||
#define FTS5_CURRENT_VERSION 4
|
||||
|
||||
#define FTS5_CONTENT_NORMAL 0
|
||||
#define FTS5_CONTENT_NONE 1
|
||||
#define FTS5_CONTENT_EXTERNAL 2
|
||||
|
||||
#define FTS5_DETAIL_FULL 0
|
||||
#define FTS5_DETAIL_NONE 1
|
||||
#define FTS5_DETAIL_COLUMNS 2
|
||||
|
||||
#define FTS5_DETAIL_FULL 0
|
||||
#define FTS5_DETAIL_NONE 1
|
||||
#define FTS5_DETAIL_COLUMNS 2
|
||||
|
||||
#define FTS5_PATTERN_NONE 0
|
||||
#define FTS5_PATTERN_LIKE 65 /* matches SQLITE_INDEX_CONSTRAINT_LIKE */
|
||||
#define FTS5_PATTERN_GLOB 66 /* matches SQLITE_INDEX_CONSTRAINT_GLOB */
|
||||
|
||||
int sqlite3Fts5ConfigParse(
|
||||
Fts5Global*, sqlite3*, int, const char **, Fts5Config**, char**
|
||||
@@ -484,7 +487,7 @@ int sqlite3Fts5IndexSetAverages(Fts5Index *p, const u8*, int);
|
||||
/*
|
||||
** Functions called by the storage module as part of integrity-check.
|
||||
*/
|
||||
int sqlite3Fts5IndexIntegrityCheck(Fts5Index*, u64 cksum);
|
||||
int sqlite3Fts5IndexIntegrityCheck(Fts5Index*, u64 cksum, int bUseCksum);
|
||||
|
||||
/*
|
||||
** Called during virtual module initialization to register UDF
|
||||
@@ -554,8 +557,7 @@ int sqlite3Fts5GetTokenizer(
|
||||
Fts5Global*,
|
||||
const char **azArg,
|
||||
int nArg,
|
||||
Fts5Tokenizer**,
|
||||
fts5_tokenizer**,
|
||||
Fts5Config*,
|
||||
char **pzErr
|
||||
);
|
||||
|
||||
@@ -639,7 +641,7 @@ int sqlite3Fts5StorageDelete(Fts5Storage *p, i64, sqlite3_value**);
|
||||
int sqlite3Fts5StorageContentInsert(Fts5Storage *p, sqlite3_value**, i64*);
|
||||
int sqlite3Fts5StorageIndexInsert(Fts5Storage *p, sqlite3_value**, i64);
|
||||
|
||||
int sqlite3Fts5StorageIntegrity(Fts5Storage *p);
|
||||
int sqlite3Fts5StorageIntegrity(Fts5Storage *p, int iArg);
|
||||
|
||||
int sqlite3Fts5StorageStmt(Fts5Storage *p, int eStmt, sqlite3_stmt**, char**);
|
||||
void sqlite3Fts5StorageStmtRelease(Fts5Storage *p, int eStmt, sqlite3_stmt*);
|
||||
@@ -684,11 +686,19 @@ struct Fts5Token {
|
||||
/* Parse a MATCH expression. */
|
||||
int sqlite3Fts5ExprNew(
|
||||
Fts5Config *pConfig,
|
||||
int bPhraseToAnd,
|
||||
int iCol, /* Column on LHS of MATCH operator */
|
||||
const char *zExpr,
|
||||
Fts5Expr **ppNew,
|
||||
char **pzErr
|
||||
);
|
||||
int sqlite3Fts5ExprPattern(
|
||||
Fts5Config *pConfig,
|
||||
int bGlob,
|
||||
int iCol,
|
||||
const char *zText,
|
||||
Fts5Expr **pp
|
||||
);
|
||||
|
||||
/*
|
||||
** for(rc = sqlite3Fts5ExprFirst(pExpr, pIdx, bDesc);
|
||||
@@ -797,6 +807,10 @@ int sqlite3Fts5AuxInit(fts5_api*);
|
||||
*/
|
||||
|
||||
int sqlite3Fts5TokenizerInit(fts5_api*);
|
||||
int sqlite3Fts5TokenizerPattern(
|
||||
int (*xCreate)(void*, const char**, int, Fts5Tokenizer**),
|
||||
Fts5Tokenizer *pTok
|
||||
);
|
||||
/*
|
||||
** End of interface to code in fts5_tokenizer.c.
|
||||
**************************************************************************/
|
||||
|
||||
@@ -325,7 +325,7 @@ static int fts5ConfigParseSpecial(
|
||||
rc = SQLITE_ERROR;
|
||||
}else{
|
||||
rc = sqlite3Fts5GetTokenizer(pGlobal,
|
||||
(const char**)azArg, (int)nArg, &pConfig->pTok, &pConfig->pTokApi,
|
||||
(const char**)azArg, (int)nArg, pConfig,
|
||||
pzErr
|
||||
);
|
||||
}
|
||||
@@ -397,9 +397,7 @@ static int fts5ConfigParseSpecial(
|
||||
*/
|
||||
static int fts5ConfigDefaultTokenizer(Fts5Global *pGlobal, Fts5Config *pConfig){
|
||||
assert( pConfig->pTok==0 && pConfig->pTokApi==0 );
|
||||
return sqlite3Fts5GetTokenizer(
|
||||
pGlobal, 0, 0, &pConfig->pTok, &pConfig->pTokApi, 0
|
||||
);
|
||||
return sqlite3Fts5GetTokenizer(pGlobal, 0, 0, pConfig, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+215
-52
@@ -128,6 +128,7 @@ struct Fts5Parse {
|
||||
int nPhrase; /* Size of apPhrase array */
|
||||
Fts5ExprPhrase **apPhrase; /* Array of all phrases */
|
||||
Fts5ExprNode *pExpr; /* Result of a successful parse */
|
||||
int bPhraseToAnd; /* Convert "a+b" to "a AND b" */
|
||||
};
|
||||
|
||||
void sqlite3Fts5ParseError(Fts5Parse *pParse, const char *zFmt, ...){
|
||||
@@ -216,6 +217,7 @@ static void fts5ParseFree(void *p){ sqlite3_free(p); }
|
||||
|
||||
int sqlite3Fts5ExprNew(
|
||||
Fts5Config *pConfig, /* FTS5 Configuration */
|
||||
int bPhraseToAnd,
|
||||
int iCol,
|
||||
const char *zExpr, /* Expression text */
|
||||
Fts5Expr **ppNew,
|
||||
@@ -231,6 +233,7 @@ int sqlite3Fts5ExprNew(
|
||||
*ppNew = 0;
|
||||
*pzErr = 0;
|
||||
memset(&sParse, 0, sizeof(sParse));
|
||||
sParse.bPhraseToAnd = bPhraseToAnd;
|
||||
pEngine = sqlite3Fts5ParserAlloc(fts5ParseAlloc);
|
||||
if( pEngine==0 ){ return SQLITE_NOMEM; }
|
||||
sParse.pConfig = pConfig;
|
||||
@@ -273,6 +276,7 @@ int sqlite3Fts5ExprNew(
|
||||
pNew->pConfig = pConfig;
|
||||
pNew->apExprPhrase = sParse.apPhrase;
|
||||
pNew->nPhrase = sParse.nPhrase;
|
||||
pNew->bDesc = 0;
|
||||
sParse.apPhrase = 0;
|
||||
}
|
||||
}else{
|
||||
@@ -284,6 +288,81 @@ int sqlite3Fts5ExprNew(
|
||||
return sParse.rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** This function is only called when using the special 'trigram' tokenizer.
|
||||
** Argument zText contains the text of a LIKE or GLOB pattern matched
|
||||
** against column iCol. This function creates and compiles an FTS5 MATCH
|
||||
** expression that will match a superset of the rows matched by the LIKE or
|
||||
** GLOB. If successful, SQLITE_OK is returned. Otherwise, an SQLite error
|
||||
** code.
|
||||
*/
|
||||
int sqlite3Fts5ExprPattern(
|
||||
Fts5Config *pConfig, int bGlob, int iCol, const char *zText, Fts5Expr **pp
|
||||
){
|
||||
i64 nText = strlen(zText);
|
||||
char *zExpr = (char*)sqlite3_malloc64(nText*4 + 1);
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
if( zExpr==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
char aSpec[3];
|
||||
int iOut = 0;
|
||||
int i = 0;
|
||||
int iFirst = 0;
|
||||
|
||||
if( bGlob==0 ){
|
||||
aSpec[0] = '_';
|
||||
aSpec[1] = '%';
|
||||
aSpec[2] = 0;
|
||||
}else{
|
||||
aSpec[0] = '*';
|
||||
aSpec[1] = '?';
|
||||
aSpec[2] = '[';
|
||||
}
|
||||
|
||||
while( i<=nText ){
|
||||
if( i==nText
|
||||
|| zText[i]==aSpec[0] || zText[i]==aSpec[1] || zText[i]==aSpec[2]
|
||||
){
|
||||
if( i-iFirst>=3 ){
|
||||
int jj;
|
||||
zExpr[iOut++] = '"';
|
||||
for(jj=iFirst; jj<i; jj++){
|
||||
zExpr[iOut++] = zText[jj];
|
||||
if( zText[jj]=='"' ) zExpr[iOut++] = '"';
|
||||
}
|
||||
zExpr[iOut++] = '"';
|
||||
zExpr[iOut++] = ' ';
|
||||
}
|
||||
if( zText[i]==aSpec[2] ){
|
||||
i += 2;
|
||||
if( zText[i-1]=='^' ) i++;
|
||||
while( i<nText && zText[i]!=']' ) i++;
|
||||
}
|
||||
iFirst = i+1;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if( iOut>0 ){
|
||||
int bAnd = 0;
|
||||
if( pConfig->eDetail!=FTS5_DETAIL_FULL ){
|
||||
bAnd = 1;
|
||||
if( pConfig->eDetail==FTS5_DETAIL_NONE ){
|
||||
iCol = pConfig->nCol;
|
||||
}
|
||||
}
|
||||
zExpr[iOut] = '\0';
|
||||
rc = sqlite3Fts5ExprNew(pConfig, bAnd, iCol, zExpr, pp,pConfig->pzErrmsg);
|
||||
}else{
|
||||
*pp = 0;
|
||||
}
|
||||
sqlite3_free(zExpr);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Free the expression node object passed as the only argument.
|
||||
*/
|
||||
@@ -1661,6 +1740,20 @@ void sqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p){
|
||||
pParse->pExpr = p;
|
||||
}
|
||||
|
||||
static int parseGrowPhraseArray(Fts5Parse *pParse){
|
||||
if( (pParse->nPhrase % 8)==0 ){
|
||||
sqlite3_int64 nByte = sizeof(Fts5ExprPhrase*) * (pParse->nPhrase + 8);
|
||||
Fts5ExprPhrase **apNew;
|
||||
apNew = (Fts5ExprPhrase**)sqlite3_realloc64(pParse->apPhrase, nByte);
|
||||
if( apNew==0 ){
|
||||
pParse->rc = SQLITE_NOMEM;
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
pParse->apPhrase = apNew;
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** This function is called by the parser to process a string token. The
|
||||
** string may or may not be quoted. In any case it is tokenized and a
|
||||
@@ -1696,16 +1789,9 @@ Fts5ExprPhrase *sqlite3Fts5ParseTerm(
|
||||
}else{
|
||||
|
||||
if( pAppend==0 ){
|
||||
if( (pParse->nPhrase % 8)==0 ){
|
||||
sqlite3_int64 nByte = sizeof(Fts5ExprPhrase*) * (pParse->nPhrase + 8);
|
||||
Fts5ExprPhrase **apNew;
|
||||
apNew = (Fts5ExprPhrase**)sqlite3_realloc64(pParse->apPhrase, nByte);
|
||||
if( apNew==0 ){
|
||||
pParse->rc = SQLITE_NOMEM;
|
||||
fts5ExprPhraseFree(sCtx.pPhrase);
|
||||
return 0;
|
||||
}
|
||||
pParse->apPhrase = apNew;
|
||||
if( parseGrowPhraseArray(pParse) ){
|
||||
fts5ExprPhraseFree(sCtx.pPhrase);
|
||||
return 0;
|
||||
}
|
||||
pParse->nPhrase++;
|
||||
}
|
||||
@@ -2112,6 +2198,67 @@ static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** This function is used when parsing LIKE or GLOB patterns against
|
||||
** trigram indexes that specify either detail=column or detail=none.
|
||||
** It converts a phrase:
|
||||
**
|
||||
** abc + def + ghi
|
||||
**
|
||||
** into an AND tree:
|
||||
**
|
||||
** abc AND def AND ghi
|
||||
*/
|
||||
static Fts5ExprNode *fts5ParsePhraseToAnd(
|
||||
Fts5Parse *pParse,
|
||||
Fts5ExprNearset *pNear
|
||||
){
|
||||
int nTerm = pNear->apPhrase[0]->nTerm;
|
||||
int ii;
|
||||
int nByte;
|
||||
Fts5ExprNode *pRet;
|
||||
|
||||
assert( pNear->nPhrase==1 );
|
||||
assert( pParse->bPhraseToAnd );
|
||||
|
||||
nByte = sizeof(Fts5ExprNode) + nTerm*sizeof(Fts5ExprNode*);
|
||||
pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte);
|
||||
if( pRet ){
|
||||
pRet->eType = FTS5_AND;
|
||||
pRet->nChild = nTerm;
|
||||
fts5ExprAssignXNext(pRet);
|
||||
pParse->nPhrase--;
|
||||
for(ii=0; ii<nTerm; ii++){
|
||||
Fts5ExprPhrase *pPhrase = (Fts5ExprPhrase*)sqlite3Fts5MallocZero(
|
||||
&pParse->rc, sizeof(Fts5ExprPhrase)
|
||||
);
|
||||
if( pPhrase ){
|
||||
if( parseGrowPhraseArray(pParse) ){
|
||||
fts5ExprPhraseFree(pPhrase);
|
||||
}else{
|
||||
pParse->apPhrase[pParse->nPhrase++] = pPhrase;
|
||||
pPhrase->nTerm = 1;
|
||||
pPhrase->aTerm[0].zTerm = sqlite3Fts5Strndup(
|
||||
&pParse->rc, pNear->apPhrase[0]->aTerm[ii].zTerm, -1
|
||||
);
|
||||
pRet->apChild[ii] = sqlite3Fts5ParseNode(pParse, FTS5_STRING,
|
||||
0, 0, sqlite3Fts5ParseNearset(pParse, 0, pPhrase)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( pParse->rc ){
|
||||
sqlite3Fts5ParseNodeFree(pRet);
|
||||
pRet = 0;
|
||||
}else{
|
||||
sqlite3Fts5ParseNearsetFree(pNear);
|
||||
}
|
||||
}
|
||||
|
||||
return pRet;
|
||||
}
|
||||
|
||||
/*
|
||||
** Allocate and return a new expression object. If anything goes wrong (i.e.
|
||||
** OOM error), leave an error code in pParse and return NULL.
|
||||
@@ -2136,51 +2283,58 @@ Fts5ExprNode *sqlite3Fts5ParseNode(
|
||||
if( eType!=FTS5_STRING && pLeft==0 ) return pRight;
|
||||
if( eType!=FTS5_STRING && pRight==0 ) return pLeft;
|
||||
|
||||
if( eType==FTS5_NOT ){
|
||||
nChild = 2;
|
||||
}else if( eType==FTS5_AND || eType==FTS5_OR ){
|
||||
nChild = 2;
|
||||
if( pLeft->eType==eType ) nChild += pLeft->nChild-1;
|
||||
if( pRight->eType==eType ) nChild += pRight->nChild-1;
|
||||
}
|
||||
if( eType==FTS5_STRING
|
||||
&& pParse->bPhraseToAnd
|
||||
&& pNear->apPhrase[0]->nTerm>1
|
||||
){
|
||||
pRet = fts5ParsePhraseToAnd(pParse, pNear);
|
||||
}else{
|
||||
if( eType==FTS5_NOT ){
|
||||
nChild = 2;
|
||||
}else if( eType==FTS5_AND || eType==FTS5_OR ){
|
||||
nChild = 2;
|
||||
if( pLeft->eType==eType ) nChild += pLeft->nChild-1;
|
||||
if( pRight->eType==eType ) nChild += pRight->nChild-1;
|
||||
}
|
||||
|
||||
nByte = sizeof(Fts5ExprNode) + sizeof(Fts5ExprNode*)*(nChild-1);
|
||||
pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte);
|
||||
nByte = sizeof(Fts5ExprNode) + sizeof(Fts5ExprNode*)*(nChild-1);
|
||||
pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte);
|
||||
|
||||
if( pRet ){
|
||||
pRet->eType = eType;
|
||||
pRet->pNear = pNear;
|
||||
fts5ExprAssignXNext(pRet);
|
||||
if( eType==FTS5_STRING ){
|
||||
int iPhrase;
|
||||
for(iPhrase=0; iPhrase<pNear->nPhrase; iPhrase++){
|
||||
pNear->apPhrase[iPhrase]->pNode = pRet;
|
||||
if( pNear->apPhrase[iPhrase]->nTerm==0 ){
|
||||
pRet->xNext = 0;
|
||||
pRet->eType = FTS5_EOF;
|
||||
if( pRet ){
|
||||
pRet->eType = eType;
|
||||
pRet->pNear = pNear;
|
||||
fts5ExprAssignXNext(pRet);
|
||||
if( eType==FTS5_STRING ){
|
||||
int iPhrase;
|
||||
for(iPhrase=0; iPhrase<pNear->nPhrase; iPhrase++){
|
||||
pNear->apPhrase[iPhrase]->pNode = pRet;
|
||||
if( pNear->apPhrase[iPhrase]->nTerm==0 ){
|
||||
pRet->xNext = 0;
|
||||
pRet->eType = FTS5_EOF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( pParse->pConfig->eDetail!=FTS5_DETAIL_FULL ){
|
||||
Fts5ExprPhrase *pPhrase = pNear->apPhrase[0];
|
||||
if( pNear->nPhrase!=1
|
||||
|| pPhrase->nTerm>1
|
||||
|| (pPhrase->nTerm>0 && pPhrase->aTerm[0].bFirst)
|
||||
){
|
||||
assert( pParse->rc==SQLITE_OK );
|
||||
pParse->rc = SQLITE_ERROR;
|
||||
assert( pParse->zErr==0 );
|
||||
pParse->zErr = sqlite3_mprintf(
|
||||
"fts5: %s queries are not supported (detail!=full)",
|
||||
pNear->nPhrase==1 ? "phrase": "NEAR"
|
||||
);
|
||||
sqlite3_free(pRet);
|
||||
pRet = 0;
|
||||
if( pParse->pConfig->eDetail!=FTS5_DETAIL_FULL ){
|
||||
Fts5ExprPhrase *pPhrase = pNear->apPhrase[0];
|
||||
if( pNear->nPhrase!=1
|
||||
|| pPhrase->nTerm>1
|
||||
|| (pPhrase->nTerm>0 && pPhrase->aTerm[0].bFirst)
|
||||
){
|
||||
assert( pParse->rc==SQLITE_OK );
|
||||
pParse->rc = SQLITE_ERROR;
|
||||
assert( pParse->zErr==0 );
|
||||
pParse->zErr = sqlite3_mprintf(
|
||||
"fts5: %s queries are not supported (detail!=full)",
|
||||
pNear->nPhrase==1 ? "phrase": "NEAR"
|
||||
);
|
||||
sqlite3_free(pRet);
|
||||
pRet = 0;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
fts5ExprAddChildren(pRet, pLeft);
|
||||
fts5ExprAddChildren(pRet, pRight);
|
||||
}
|
||||
}else{
|
||||
fts5ExprAddChildren(pRet, pLeft);
|
||||
fts5ExprAddChildren(pRet, pRight);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2401,8 +2555,17 @@ static char *fts5ExprPrint(Fts5Config *pConfig, Fts5ExprNode *pExpr){
|
||||
int iTerm;
|
||||
|
||||
if( pNear->pColset ){
|
||||
int iCol = pNear->pColset->aiCol[0];
|
||||
zRet = fts5PrintfAppend(zRet, "%s : ", pConfig->azCol[iCol]);
|
||||
int ii;
|
||||
Fts5Colset *pColset = pNear->pColset;
|
||||
if( pColset->nCol>1 ) zRet = fts5PrintfAppend(zRet, "{");
|
||||
for(ii=0; ii<pColset->nCol; ii++){
|
||||
zRet = fts5PrintfAppend(zRet, "%s%s",
|
||||
pConfig->azCol[pColset->aiCol[ii]], ii==pColset->nCol-1 ? "" : " "
|
||||
);
|
||||
}
|
||||
if( zRet ){
|
||||
zRet = fts5PrintfAppend(zRet, "%s : ", pColset->nCol>1 ? "}" : "");
|
||||
}
|
||||
if( zRet==0 ) return 0;
|
||||
}
|
||||
|
||||
@@ -2525,7 +2688,7 @@ static void fts5ExprFunction(
|
||||
|
||||
rc = sqlite3Fts5ConfigParse(pGlobal, db, nConfig, azConfig, &pConfig, &zErr);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3Fts5ExprNew(pConfig, pConfig->nCol, zExpr, &pExpr, &zErr);
|
||||
rc = sqlite3Fts5ExprNew(pConfig, 0, pConfig->nCol, zExpr, &pExpr, &zErr);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
char *zText;
|
||||
|
||||
@@ -306,7 +306,6 @@ int sqlite3Fts5HashWrite(
|
||||
p->iCol = (pHash->eDetail==FTS5_DETAIL_FULL ? 0 : -1);
|
||||
}
|
||||
|
||||
nIncr += p->nData;
|
||||
}else{
|
||||
|
||||
/* Appending to an existing hash-entry. Check that there is enough
|
||||
@@ -339,8 +338,9 @@ int sqlite3Fts5HashWrite(
|
||||
/* If this is a new rowid, append the 4-byte size field for the previous
|
||||
** entry, and the new rowid for this entry. */
|
||||
if( iRowid!=p->iRowid ){
|
||||
u64 iDiff = (u64)iRowid - (u64)p->iRowid;
|
||||
fts5HashAddPoslistSize(pHash, p, 0);
|
||||
p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iRowid - p->iRowid);
|
||||
p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iDiff);
|
||||
p->iRowid = iRowid;
|
||||
bNew = 1;
|
||||
p->iSzPoslist = p->nData;
|
||||
|
||||
+12
-9
@@ -1754,7 +1754,7 @@ static void fts5SegIterReverseInitPage(Fts5Index *p, Fts5SegIter *pIter){
|
||||
|
||||
ASSERT_SZLEAF_OK(pIter->pLeaf);
|
||||
while( 1 ){
|
||||
i64 iDelta = 0;
|
||||
u64 iDelta = 0;
|
||||
|
||||
if( eDetail==FTS5_DETAIL_NONE ){
|
||||
/* todo */
|
||||
@@ -1769,7 +1769,7 @@ static void fts5SegIterReverseInitPage(Fts5Index *p, Fts5SegIter *pIter){
|
||||
i += nPos;
|
||||
}
|
||||
if( i>=n ) break;
|
||||
i += fts5GetVarint(&a[i], (u64*)&iDelta);
|
||||
i += fts5GetVarint(&a[i], &iDelta);
|
||||
pIter->iRowid += iDelta;
|
||||
|
||||
/* If necessary, grow the pIter->aRowidOffset[] array. */
|
||||
@@ -1868,7 +1868,7 @@ static void fts5SegIterNext_Reverse(
|
||||
if( pIter->iRowidOffset>0 ){
|
||||
u8 *a = pIter->pLeaf->p;
|
||||
int iOff;
|
||||
i64 iDelta;
|
||||
u64 iDelta;
|
||||
|
||||
pIter->iRowidOffset--;
|
||||
pIter->iLeafOffset = pIter->aRowidOffset[pIter->iRowidOffset];
|
||||
@@ -1877,7 +1877,7 @@ static void fts5SegIterNext_Reverse(
|
||||
if( p->pConfig->eDetail!=FTS5_DETAIL_NONE ){
|
||||
iOff += pIter->nPos;
|
||||
}
|
||||
fts5GetVarint(&a[iOff], (u64*)&iDelta);
|
||||
fts5GetVarint(&a[iOff], &iDelta);
|
||||
pIter->iRowid -= iDelta;
|
||||
}else{
|
||||
fts5SegIterReverseNewPage(p, pIter);
|
||||
@@ -4997,7 +4997,9 @@ static void fts5MergePrefixLists(
|
||||
** at most 20 bytes of unexpected space. */
|
||||
fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid);
|
||||
fts5BufferZero(&tmp);
|
||||
sqlite3Fts5BufferSize(&p->rc, &tmp, i1.nPoslist + i2.nPoslist + 10 + 10);
|
||||
sqlite3Fts5BufferSize(&p->rc, &tmp,
|
||||
i1.nPoslist + i2.nPoslist + 10 + 10 + FTS5_DATA_ZERO_PADDING
|
||||
);
|
||||
if( p->rc ) break;
|
||||
|
||||
sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1);
|
||||
@@ -5071,9 +5073,10 @@ static void fts5MergePrefixLists(
|
||||
}
|
||||
assert_nc( out.n<=(p1->n+p2->n+9) );
|
||||
|
||||
fts5BufferSet(&p->rc, p1, out.n, out.p);
|
||||
fts5BufferFree(p1);
|
||||
fts5BufferFree(&tmp);
|
||||
fts5BufferFree(&out);
|
||||
memset(&out.p[out.n], 0, FTS5_DATA_ZERO_PADDING);
|
||||
*p1 = out;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6059,7 +6062,7 @@ static void fts5IndexIntegrityCheckSegment(
|
||||
** error, or some other SQLite error code if another error (e.g. OOM)
|
||||
** occurs.
|
||||
*/
|
||||
int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum){
|
||||
int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum, int bUseCksum){
|
||||
int eDetail = p->pConfig->eDetail;
|
||||
u64 cksum2 = 0; /* Checksum based on contents of indexes */
|
||||
Fts5Buffer poslist = {0,0,0}; /* Buffer used to hold a poslist */
|
||||
@@ -6130,7 +6133,7 @@ int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum){
|
||||
fts5TestTerm(p, &term, 0, 0, cksum2, &cksum3);
|
||||
|
||||
fts5MultiIterFree(pIter);
|
||||
if( p->rc==SQLITE_OK && cksum!=cksum2 ) p->rc = FTS5_CORRUPT;
|
||||
if( p->rc==SQLITE_OK && bUseCksum && cksum!=cksum2 ) p->rc = FTS5_CORRUPT;
|
||||
|
||||
fts5StructureRelease(pStruct);
|
||||
#ifdef SQLITE_DEBUG
|
||||
|
||||
+80
-37
@@ -464,6 +464,23 @@ static void fts5SetUniqueFlag(sqlite3_index_info *pIdxInfo){
|
||||
#endif
|
||||
}
|
||||
|
||||
static int fts5UsePatternMatch(
|
||||
Fts5Config *pConfig,
|
||||
struct sqlite3_index_constraint *p
|
||||
){
|
||||
assert( FTS5_PATTERN_GLOB==SQLITE_INDEX_CONSTRAINT_GLOB );
|
||||
assert( FTS5_PATTERN_LIKE==SQLITE_INDEX_CONSTRAINT_LIKE );
|
||||
if( pConfig->ePattern==FTS5_PATTERN_GLOB && p->op==FTS5_PATTERN_GLOB ){
|
||||
return 1;
|
||||
}
|
||||
if( pConfig->ePattern==FTS5_PATTERN_LIKE
|
||||
&& (p->op==FTS5_PATTERN_LIKE || p->op==FTS5_PATTERN_GLOB)
|
||||
){
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Implementation of the xBestIndex method for FTS5 tables. Within the
|
||||
** WHERE constraint, it searches for the following:
|
||||
@@ -493,7 +510,9 @@ static void fts5SetUniqueFlag(sqlite3_index_info *pIdxInfo){
|
||||
**
|
||||
** Match against table column: "m"
|
||||
** Match against rank column: "r"
|
||||
** Match against other column: "<column-number>"
|
||||
** Match against other column: "M<column-number>"
|
||||
** LIKE against other column: "L<column-number>"
|
||||
** GLOB against other column: "G<column-number>"
|
||||
** Equality constraint against the rowid: "="
|
||||
** A < or <= against the rowid: "<"
|
||||
** A > or >= against the rowid: ">"
|
||||
@@ -554,7 +573,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
|
||||
idxStr = (char*)sqlite3_malloc(pInfo->nConstraint * 6 + 1);
|
||||
idxStr = (char*)sqlite3_malloc(pInfo->nConstraint * 8 + 1);
|
||||
if( idxStr==0 ) return SQLITE_NOMEM;
|
||||
pInfo->idxStr = idxStr;
|
||||
pInfo->needToFreeIdxStr = 1;
|
||||
@@ -578,25 +597,29 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
|
||||
if( bSeenRank ) continue;
|
||||
idxStr[iIdxStr++] = 'r';
|
||||
bSeenRank = 1;
|
||||
}else{
|
||||
}else if( iCol>=0 ){
|
||||
bSeenMatch = 1;
|
||||
idxStr[iIdxStr++] = 'm';
|
||||
if( iCol<nCol ){
|
||||
sqlite3_snprintf(6, &idxStr[iIdxStr], "%d", iCol);
|
||||
idxStr += strlen(&idxStr[iIdxStr]);
|
||||
assert( idxStr[iIdxStr]=='\0' );
|
||||
}
|
||||
idxStr[iIdxStr++] = 'M';
|
||||
sqlite3_snprintf(6, &idxStr[iIdxStr], "%d", iCol);
|
||||
idxStr += strlen(&idxStr[iIdxStr]);
|
||||
assert( idxStr[iIdxStr]=='\0' );
|
||||
}
|
||||
pInfo->aConstraintUsage[i].argvIndex = ++iCons;
|
||||
pInfo->aConstraintUsage[i].omit = 1;
|
||||
}
|
||||
}
|
||||
else if( p->usable && bSeenEq==0
|
||||
&& p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol<0
|
||||
){
|
||||
idxStr[iIdxStr++] = '=';
|
||||
bSeenEq = 1;
|
||||
pInfo->aConstraintUsage[i].argvIndex = ++iCons;
|
||||
}else if( p->usable ){
|
||||
if( iCol>=0 && iCol<nCol && fts5UsePatternMatch(pConfig, p) ){
|
||||
assert( p->op==FTS5_PATTERN_LIKE || p->op==FTS5_PATTERN_GLOB );
|
||||
idxStr[iIdxStr++] = p->op==FTS5_PATTERN_LIKE ? 'L' : 'G';
|
||||
sqlite3_snprintf(6, &idxStr[iIdxStr], "%d", iCol);
|
||||
idxStr += strlen(&idxStr[iIdxStr]);
|
||||
pInfo->aConstraintUsage[i].argvIndex = ++iCons;
|
||||
assert( idxStr[iIdxStr]=='\0' );
|
||||
}else if( bSeenEq==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol<0 ){
|
||||
idxStr[iIdxStr++] = '=';
|
||||
bSeenEq = 1;
|
||||
pInfo->aConstraintUsage[i].argvIndex = ++iCons;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1229,19 +1252,14 @@ static int fts5FilterMethod(
|
||||
case 'r':
|
||||
pRank = apVal[i];
|
||||
break;
|
||||
case 'm': {
|
||||
case 'M': {
|
||||
const char *zText = (const char*)sqlite3_value_text(apVal[i]);
|
||||
if( zText==0 ) zText = "";
|
||||
|
||||
if( idxStr[iIdxStr]>='0' && idxStr[iIdxStr]<='9' ){
|
||||
iCol = 0;
|
||||
do{
|
||||
iCol = iCol*10 + (idxStr[iIdxStr]-'0');
|
||||
iIdxStr++;
|
||||
}while( idxStr[iIdxStr]>='0' && idxStr[iIdxStr]<='9' );
|
||||
}else{
|
||||
iCol = pConfig->nCol;
|
||||
}
|
||||
iCol = 0;
|
||||
do{
|
||||
iCol = iCol*10 + (idxStr[iIdxStr]-'0');
|
||||
iIdxStr++;
|
||||
}while( idxStr[iIdxStr]>='0' && idxStr[iIdxStr]<='9' );
|
||||
|
||||
if( zText[0]=='*' ){
|
||||
/* The user has issued a query of the form "MATCH '*...'". This
|
||||
@@ -1251,7 +1269,7 @@ static int fts5FilterMethod(
|
||||
goto filter_out;
|
||||
}else{
|
||||
char **pzErr = &pTab->p.base.zErrMsg;
|
||||
rc = sqlite3Fts5ExprNew(pConfig, iCol, zText, &pExpr, pzErr);
|
||||
rc = sqlite3Fts5ExprNew(pConfig, 0, iCol, zText, &pExpr, pzErr);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3Fts5ExprAnd(&pCsr->pExpr, pExpr);
|
||||
pExpr = 0;
|
||||
@@ -1261,6 +1279,25 @@ static int fts5FilterMethod(
|
||||
|
||||
break;
|
||||
}
|
||||
case 'L':
|
||||
case 'G': {
|
||||
int bGlob = (idxStr[iIdxStr-1]=='G');
|
||||
const char *zText = (const char*)sqlite3_value_text(apVal[i]);
|
||||
iCol = 0;
|
||||
do{
|
||||
iCol = iCol*10 + (idxStr[iIdxStr]-'0');
|
||||
iIdxStr++;
|
||||
}while( idxStr[iIdxStr]>='0' && idxStr[iIdxStr]<='9' );
|
||||
if( zText ){
|
||||
rc = sqlite3Fts5ExprPattern(pConfig, bGlob, iCol, zText, &pExpr);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3Fts5ExprAnd(&pCsr->pExpr, pExpr);
|
||||
pExpr = 0;
|
||||
}
|
||||
if( rc!=SQLITE_OK ) goto filter_out;
|
||||
break;
|
||||
}
|
||||
case '=':
|
||||
pRowidEq = apVal[i];
|
||||
break;
|
||||
@@ -1508,7 +1545,8 @@ static int fts5SpecialInsert(
|
||||
int nMerge = sqlite3_value_int(pVal);
|
||||
rc = sqlite3Fts5StorageMerge(pTab->pStorage, nMerge);
|
||||
}else if( 0==sqlite3_stricmp("integrity-check", zCmd) ){
|
||||
rc = sqlite3Fts5StorageIntegrity(pTab->pStorage);
|
||||
int iArg = sqlite3_value_int(pVal);
|
||||
rc = sqlite3Fts5StorageIntegrity(pTab->pStorage, iArg);
|
||||
#ifdef SQLITE_DEBUG
|
||||
}else if( 0==sqlite3_stricmp("prefix-index", zCmd) ){
|
||||
pConfig->bPrefixIndex = sqlite3_value_int(pVal);
|
||||
@@ -2671,8 +2709,7 @@ int sqlite3Fts5GetTokenizer(
|
||||
Fts5Global *pGlobal,
|
||||
const char **azArg,
|
||||
int nArg,
|
||||
Fts5Tokenizer **ppTok,
|
||||
fts5_tokenizer **ppTokApi,
|
||||
Fts5Config *pConfig,
|
||||
char **pzErr
|
||||
){
|
||||
Fts5TokenizerModule *pMod;
|
||||
@@ -2684,16 +2721,22 @@ int sqlite3Fts5GetTokenizer(
|
||||
rc = SQLITE_ERROR;
|
||||
*pzErr = sqlite3_mprintf("no such tokenizer: %s", azArg[0]);
|
||||
}else{
|
||||
rc = pMod->x.xCreate(pMod->pUserData, &azArg[1], (nArg?nArg-1:0), ppTok);
|
||||
*ppTokApi = &pMod->x;
|
||||
if( rc!=SQLITE_OK && pzErr ){
|
||||
*pzErr = sqlite3_mprintf("error in tokenizer constructor");
|
||||
rc = pMod->x.xCreate(
|
||||
pMod->pUserData, &azArg[1], (nArg?nArg-1:0), &pConfig->pTok
|
||||
);
|
||||
pConfig->pTokApi = &pMod->x;
|
||||
if( rc!=SQLITE_OK ){
|
||||
if( pzErr ) *pzErr = sqlite3_mprintf("error in tokenizer constructor");
|
||||
}else{
|
||||
pConfig->ePattern = sqlite3Fts5TokenizerPattern(
|
||||
pMod->x.xCreate, pConfig->pTok
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if( rc!=SQLITE_OK ){
|
||||
*ppTokApi = 0;
|
||||
*ppTok = 0;
|
||||
pConfig->pTokApi = 0;
|
||||
pConfig->pTok = 0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
||||
+78
-65
@@ -429,9 +429,16 @@ static int fts5StorageDeleteFromIndex(
|
||||
zText, nText, (void*)&ctx, fts5StorageInsertCallback
|
||||
);
|
||||
p->aTotalSize[iCol-1] -= (i64)ctx.szCol;
|
||||
if( p->aTotalSize[iCol-1]<0 ){
|
||||
rc = FTS5_CORRUPT;
|
||||
}
|
||||
}
|
||||
}
|
||||
p->nTotalRow--;
|
||||
if( rc==SQLITE_OK && p->nTotalRow<1 ){
|
||||
rc = FTS5_CORRUPT;
|
||||
}else{
|
||||
p->nTotalRow--;
|
||||
}
|
||||
|
||||
rc2 = sqlite3_reset(pSeek);
|
||||
if( rc==SQLITE_OK ) rc = rc2;
|
||||
@@ -874,13 +881,14 @@ static int fts5StorageIntegrityCallback(
|
||||
** some other SQLite error code if an error occurs while attempting to
|
||||
** determine this.
|
||||
*/
|
||||
int sqlite3Fts5StorageIntegrity(Fts5Storage *p){
|
||||
int sqlite3Fts5StorageIntegrity(Fts5Storage *p, int iArg){
|
||||
Fts5Config *pConfig = p->pConfig;
|
||||
int rc; /* Return code */
|
||||
int rc = SQLITE_OK; /* Return code */
|
||||
int *aColSize; /* Array of size pConfig->nCol */
|
||||
i64 *aTotalSize; /* Array of size pConfig->nCol */
|
||||
Fts5IntegrityCtx ctx;
|
||||
sqlite3_stmt *pScan;
|
||||
int bUseCksum;
|
||||
|
||||
memset(&ctx, 0, sizeof(Fts5IntegrityCtx));
|
||||
ctx.pConfig = p->pConfig;
|
||||
@@ -889,83 +897,88 @@ int sqlite3Fts5StorageIntegrity(Fts5Storage *p){
|
||||
aColSize = (int*)&aTotalSize[pConfig->nCol];
|
||||
memset(aTotalSize, 0, sizeof(i64) * pConfig->nCol);
|
||||
|
||||
/* Generate the expected index checksum based on the contents of the
|
||||
** %_content table. This block stores the checksum in ctx.cksum. */
|
||||
rc = fts5StorageGetStmt(p, FTS5_STMT_SCAN, &pScan, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
int rc2;
|
||||
while( SQLITE_ROW==sqlite3_step(pScan) ){
|
||||
int i;
|
||||
ctx.iRowid = sqlite3_column_int64(pScan, 0);
|
||||
ctx.szCol = 0;
|
||||
if( pConfig->bColumnsize ){
|
||||
rc = sqlite3Fts5StorageDocsize(p, ctx.iRowid, aColSize);
|
||||
}
|
||||
if( rc==SQLITE_OK && pConfig->eDetail==FTS5_DETAIL_NONE ){
|
||||
rc = sqlite3Fts5TermsetNew(&ctx.pTermset);
|
||||
}
|
||||
for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
|
||||
if( pConfig->abUnindexed[i] ) continue;
|
||||
ctx.iCol = i;
|
||||
bUseCksum = (pConfig->eContent==FTS5_CONTENT_NORMAL
|
||||
|| (pConfig->eContent==FTS5_CONTENT_EXTERNAL && iArg)
|
||||
);
|
||||
if( bUseCksum ){
|
||||
/* Generate the expected index checksum based on the contents of the
|
||||
** %_content table. This block stores the checksum in ctx.cksum. */
|
||||
rc = fts5StorageGetStmt(p, FTS5_STMT_SCAN, &pScan, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
int rc2;
|
||||
while( SQLITE_ROW==sqlite3_step(pScan) ){
|
||||
int i;
|
||||
ctx.iRowid = sqlite3_column_int64(pScan, 0);
|
||||
ctx.szCol = 0;
|
||||
if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
|
||||
if( pConfig->bColumnsize ){
|
||||
rc = sqlite3Fts5StorageDocsize(p, ctx.iRowid, aColSize);
|
||||
}
|
||||
if( rc==SQLITE_OK && pConfig->eDetail==FTS5_DETAIL_NONE ){
|
||||
rc = sqlite3Fts5TermsetNew(&ctx.pTermset);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
const char *zText = (const char*)sqlite3_column_text(pScan, i+1);
|
||||
int nText = sqlite3_column_bytes(pScan, i+1);
|
||||
rc = sqlite3Fts5Tokenize(pConfig,
|
||||
FTS5_TOKENIZE_DOCUMENT,
|
||||
zText, nText,
|
||||
(void*)&ctx,
|
||||
fts5StorageIntegrityCallback
|
||||
);
|
||||
}
|
||||
if( rc==SQLITE_OK && pConfig->bColumnsize && ctx.szCol!=aColSize[i] ){
|
||||
rc = FTS5_CORRUPT;
|
||||
}
|
||||
aTotalSize[i] += ctx.szCol;
|
||||
if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
|
||||
sqlite3Fts5TermsetFree(ctx.pTermset);
|
||||
ctx.pTermset = 0;
|
||||
for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
|
||||
if( pConfig->abUnindexed[i] ) continue;
|
||||
ctx.iCol = i;
|
||||
ctx.szCol = 0;
|
||||
if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
|
||||
rc = sqlite3Fts5TermsetNew(&ctx.pTermset);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
const char *zText = (const char*)sqlite3_column_text(pScan, i+1);
|
||||
int nText = sqlite3_column_bytes(pScan, i+1);
|
||||
rc = sqlite3Fts5Tokenize(pConfig,
|
||||
FTS5_TOKENIZE_DOCUMENT,
|
||||
zText, nText,
|
||||
(void*)&ctx,
|
||||
fts5StorageIntegrityCallback
|
||||
);
|
||||
}
|
||||
if( rc==SQLITE_OK && pConfig->bColumnsize && ctx.szCol!=aColSize[i] ){
|
||||
rc = FTS5_CORRUPT;
|
||||
}
|
||||
aTotalSize[i] += ctx.szCol;
|
||||
if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
|
||||
sqlite3Fts5TermsetFree(ctx.pTermset);
|
||||
ctx.pTermset = 0;
|
||||
}
|
||||
}
|
||||
sqlite3Fts5TermsetFree(ctx.pTermset);
|
||||
ctx.pTermset = 0;
|
||||
|
||||
if( rc!=SQLITE_OK ) break;
|
||||
}
|
||||
sqlite3Fts5TermsetFree(ctx.pTermset);
|
||||
ctx.pTermset = 0;
|
||||
|
||||
if( rc!=SQLITE_OK ) break;
|
||||
rc2 = sqlite3_reset(pScan);
|
||||
if( rc==SQLITE_OK ) rc = rc2;
|
||||
}
|
||||
rc2 = sqlite3_reset(pScan);
|
||||
if( rc==SQLITE_OK ) rc = rc2;
|
||||
}
|
||||
|
||||
/* Test that the "totals" (sometimes called "averages") record looks Ok */
|
||||
if( rc==SQLITE_OK ){
|
||||
int i;
|
||||
rc = fts5StorageLoadTotals(p, 0);
|
||||
for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
|
||||
if( p->aTotalSize[i]!=aTotalSize[i] ) rc = FTS5_CORRUPT;
|
||||
/* Test that the "totals" (sometimes called "averages") record looks Ok */
|
||||
if( rc==SQLITE_OK ){
|
||||
int i;
|
||||
rc = fts5StorageLoadTotals(p, 0);
|
||||
for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
|
||||
if( p->aTotalSize[i]!=aTotalSize[i] ) rc = FTS5_CORRUPT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check that the %_docsize and %_content tables contain the expected
|
||||
** number of rows. */
|
||||
if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){
|
||||
i64 nRow = 0;
|
||||
rc = fts5StorageCount(p, "content", &nRow);
|
||||
if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT;
|
||||
}
|
||||
if( rc==SQLITE_OK && pConfig->bColumnsize ){
|
||||
i64 nRow = 0;
|
||||
rc = fts5StorageCount(p, "docsize", &nRow);
|
||||
if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT;
|
||||
/* Check that the %_docsize and %_content tables contain the expected
|
||||
** number of rows. */
|
||||
if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){
|
||||
i64 nRow = 0;
|
||||
rc = fts5StorageCount(p, "content", &nRow);
|
||||
if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT;
|
||||
}
|
||||
if( rc==SQLITE_OK && pConfig->bColumnsize ){
|
||||
i64 nRow = 0;
|
||||
rc = fts5StorageCount(p, "docsize", &nRow);
|
||||
if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Pass the expected checksum down to the FTS index module. It will
|
||||
** verify, amongst other things, that it matches the checksum generated by
|
||||
** inspecting the index itself. */
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3Fts5IndexIntegrityCheck(p->pIndex, ctx.cksum);
|
||||
rc = sqlite3Fts5IndexIntegrityCheck(p->pIndex, ctx.cksum, bUseCksum);
|
||||
}
|
||||
|
||||
sqlite3_free(aTotalSize);
|
||||
|
||||
@@ -1258,6 +1258,131 @@ static int fts5PorterTokenize(
|
||||
);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
** Start of trigram implementation.
|
||||
*/
|
||||
typedef struct TrigramTokenizer TrigramTokenizer;
|
||||
struct TrigramTokenizer {
|
||||
int bFold; /* True to fold to lower-case */
|
||||
};
|
||||
|
||||
/*
|
||||
** Free a trigram tokenizer.
|
||||
*/
|
||||
static void fts5TriDelete(Fts5Tokenizer *p){
|
||||
sqlite3_free(p);
|
||||
}
|
||||
|
||||
/*
|
||||
** Allocate a trigram tokenizer.
|
||||
*/
|
||||
static int fts5TriCreate(
|
||||
void *pCtx,
|
||||
const char **azArg,
|
||||
int nArg,
|
||||
Fts5Tokenizer **ppOut
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
TrigramTokenizer *pNew = (TrigramTokenizer*)sqlite3_malloc(sizeof(*pNew));
|
||||
if( pNew==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
int i;
|
||||
pNew->bFold = 1;
|
||||
for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
|
||||
const char *zArg = azArg[i+1];
|
||||
if( 0==sqlite3_stricmp(azArg[i], "case_sensitive") ){
|
||||
if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1] ){
|
||||
rc = SQLITE_ERROR;
|
||||
}else{
|
||||
pNew->bFold = (zArg[0]=='0');
|
||||
}
|
||||
}else{
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
}
|
||||
if( rc!=SQLITE_OK ){
|
||||
fts5TriDelete((Fts5Tokenizer*)pNew);
|
||||
pNew = 0;
|
||||
}
|
||||
}
|
||||
*ppOut = (Fts5Tokenizer*)pNew;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Trigram tokenizer tokenize routine.
|
||||
*/
|
||||
static int fts5TriTokenize(
|
||||
Fts5Tokenizer *pTok,
|
||||
void *pCtx,
|
||||
int flags,
|
||||
const char *pText, int nText,
|
||||
int (*xToken)(void*, int, const char*, int, int, int)
|
||||
){
|
||||
TrigramTokenizer *p = (TrigramTokenizer*)pTok;
|
||||
int rc = SQLITE_OK;
|
||||
char aBuf[32];
|
||||
const unsigned char *zIn = (const unsigned char*)pText;
|
||||
const unsigned char *zEof = &zIn[nText];
|
||||
u32 iCode;
|
||||
|
||||
while( 1 ){
|
||||
char *zOut = aBuf;
|
||||
int iStart = zIn - (const unsigned char*)pText;
|
||||
const unsigned char *zNext;
|
||||
|
||||
READ_UTF8(zIn, zEof, iCode);
|
||||
if( iCode==0 ) break;
|
||||
zNext = zIn;
|
||||
if( zIn<zEof ){
|
||||
if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0);
|
||||
WRITE_UTF8(zOut, iCode);
|
||||
READ_UTF8(zIn, zEof, iCode);
|
||||
if( iCode==0 ) break;
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
if( zIn<zEof ){
|
||||
if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0);
|
||||
WRITE_UTF8(zOut, iCode);
|
||||
READ_UTF8(zIn, zEof, iCode);
|
||||
if( iCode==0 ) break;
|
||||
if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0);
|
||||
WRITE_UTF8(zOut, iCode);
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
rc = xToken(pCtx, 0, aBuf, zOut-aBuf, iStart, iStart + zOut-aBuf);
|
||||
if( rc!=SQLITE_OK ) break;
|
||||
zIn = zNext;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Argument xCreate is a pointer to a constructor function for a tokenizer.
|
||||
** pTok is a tokenizer previously created using the same method. This function
|
||||
** returns one of FTS5_PATTERN_NONE, FTS5_PATTERN_LIKE or FTS5_PATTERN_GLOB
|
||||
** indicating the style of pattern matching that the tokenizer can support.
|
||||
** In practice, this is:
|
||||
**
|
||||
** "trigram" tokenizer, case_sensitive=1 - FTS5_PATTERN_GLOB
|
||||
** "trigram" tokenizer, case_sensitive=0 (the default) - FTS5_PATTERN_LIKE
|
||||
** all other tokenizers - FTS5_PATTERN_NONE
|
||||
*/
|
||||
int sqlite3Fts5TokenizerPattern(
|
||||
int (*xCreate)(void*, const char**, int, Fts5Tokenizer**),
|
||||
Fts5Tokenizer *pTok
|
||||
){
|
||||
if( xCreate==fts5TriCreate ){
|
||||
TrigramTokenizer *p = (TrigramTokenizer*)pTok;
|
||||
return p->bFold ? FTS5_PATTERN_LIKE : FTS5_PATTERN_GLOB;
|
||||
}
|
||||
return FTS5_PATTERN_NONE;
|
||||
}
|
||||
|
||||
/*
|
||||
** Register all built-in tokenizers with FTS5.
|
||||
*/
|
||||
@@ -1269,6 +1394,7 @@ int sqlite3Fts5TokenizerInit(fts5_api *pApi){
|
||||
{ "unicode61", {fts5UnicodeCreate, fts5UnicodeDelete, fts5UnicodeTokenize}},
|
||||
{ "ascii", {fts5AsciiCreate, fts5AsciiDelete, fts5AsciiTokenize }},
|
||||
{ "porter", {fts5PorterCreate, fts5PorterDelete, fts5PorterTokenize }},
|
||||
{ "trigram", {fts5TriCreate, fts5TriDelete, fts5TriTokenize}},
|
||||
};
|
||||
|
||||
int rc = SQLITE_OK; /* Return code */
|
||||
|
||||
@@ -773,4 +773,5 @@ void sqlite3Fts5UnicodeAscii(u8 *aArray, u8 *aAscii){
|
||||
}
|
||||
iTbl++;
|
||||
}
|
||||
aAscii[0] = 0; /* 0x00 is never a token character */
|
||||
}
|
||||
|
||||
@@ -82,5 +82,24 @@ foreach_detail_mode $::testprefix {
|
||||
} {1 {unable to use function MATCH in the requested context}}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Confirm that the expression parser creates the same expression tree
|
||||
# for:
|
||||
#
|
||||
# {a b} : (abc AND def)
|
||||
# -{c d} : (abc AND def)
|
||||
#
|
||||
# Assuming that the table columns are (a, b, c, d).
|
||||
#
|
||||
do_execsql_test 5.1 {
|
||||
SELECT fts5_expr('abcd AND cdef');
|
||||
} {{"abcd" AND "cdef"}}
|
||||
do_execsql_test 5.2 {
|
||||
SELECT fts5_expr('{a b} : (abcd AND cdef)', 'a', 'b', 'c', 'd');
|
||||
} {{{a b} : "abcd" AND {a b} : "cdef"}}
|
||||
do_execsql_test 5.3 {
|
||||
SELECT fts5_expr('-{c d} : (abcd AND cdef)', 'a', 'b', 'c', 'd');
|
||||
} {{{a b} : "abcd" AND {a b} : "cdef"}}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -9691,7 +9691,7 @@ do_test 65.0 {
|
||||
|
||||
do_catchsql_test 65.1 {
|
||||
SELECT ( MATCH (t1,591)) FROM t1 WHERE t1 MATCH 'e*eŸ'
|
||||
} {1 {database disk image is malformed}}
|
||||
} {1 {malformed database schema (t2) - invalid rootpage}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@@ -10324,6 +10324,109 @@ do_catchsql_test 69.2 {
|
||||
SELECT * FROM t1 WHERE a MATCH 'fx*'
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_test 70.0 {
|
||||
sqlite3 db {}
|
||||
db deserialize [decode_hexdb {
|
||||
.open --hexdb
|
||||
| size 24576 pagesize 4096 filename sql022250.txt.db
|
||||
| page 1 offset 0
|
||||
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
|
||||
| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........
|
||||
| 96: 00 00 00 00 0d 00 00 00 06 0d e2 00 0f c4 0f 6a ...............j
|
||||
| 112: 0e fc 0e 9d 0e 3d 0d e2 00 00 00 00 00 00 00 00 .....=..........
|
||||
| 3552: 00 00 59 06 06 17 21 21 01 7f 74 61 62 6c 65 74 ..Y...!!..tablet
|
||||
| 3568: 74 74 5f 63 6f 6e 66 69 67 74 74 74 5f 63 6f 6e tt_configttt_con
|
||||
| 3584: 66 69 67 06 43 52 45 41 54 45 20 54 41 42 4c 45 fig.CREATE TABLE
|
||||
| 3600: 20 27 74 74 74 5f 63 6f 6e 66 69 67 27 28 6b 20 'ttt_config'(k
|
||||
| 3616: 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 20 PRIMARY KEY, v)
|
||||
| 3632: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5e 15 07 WITHOUT ROWID^..
|
||||
| 3648: 17 23 23 01 81 03 74 61 62 6c 65 74 74 74 5f 64 .##...tablettt_d
|
||||
| 3664: 6f 63 73 69 7a 65 74 74 74 5f 64 6f 63 73 69 7a ocsizettt_docsiz
|
||||
| 3680: 65 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 e.CREATE TABLE '
|
||||
| 3696: 74 74 74 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 ttt_docsize'(id
|
||||
| 3712: 49 4d 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 IMTEGER PRIMARY
|
||||
| 3728: 4b 45 59 2c 20 73 7a 20 42 4c 4f 20 29 5d 04 07 KEY, sz BLO )]..
|
||||
| 3744: 17 23 23 01 81 01 74 61 62 6c 65 74 74 74 5f 63 .##...tablettt_c
|
||||
| 3760: 6f 6e 74 65 6e 74 74 74 74 5f 63 6f 6e 74 65 6e ontentttt_conten
|
||||
| 3776: 74 04 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 t.CREATE TABLE '
|
||||
| 3792: 74 74 74 5f 63 6f 6e 74 65 6e 74 27 28 69 64 20 ttt_content'(id
|
||||
| 3808: 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 INTEGER PRIMARY
|
||||
| 3824: 4b 45 59 2c 20 63 30 2c 20 63 31 29 6c 03 07 17 KEY, c0, c1)l...
|
||||
| 3840: 1b 1b 01 81 2f 74 61 62 6c 65 74 74 74 5f 69 64 ..../tablettt_id
|
||||
| 3856: 78 74 74 74 5f 69 64 78 03 43 52 45 41 54 45 20 xttt_idx.CREATE
|
||||
| 3872: 54 41 42 4c 45 20 27 74 74 74 5f 69 64 78 27 28 TABLE 'ttt_idx'(
|
||||
| 3888: 73 65 67 69 64 2c 20 74 65 72 6d 2c 20 70 67 6e segid, term, pgn
|
||||
| 3904: 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45 59 28 73 o, PRIMARY KEY(s
|
||||
| 3920: 65 67 69 64 2c 20 74 65 72 6d 29 29 20 57 49 54 egid, term)) WIT
|
||||
| 3936: 48 4f 55 54 20 52 4f 57 49 44 58 02 07 17 1d 1d HOUT ROWIDX.....
|
||||
| 3952: 01 81 03 74 61 62 6c 65 74 74 74 5f 64 61 74 61 ...tablettt_data
|
||||
| 3968: 74 74 74 5f 64 61 74 61 02 43 52 45 41 54 45 20 ttt_data.CREATE
|
||||
| 3984: 54 41 42 4c 45 20 27 74 74 74 5f 64 61 74 61 27 TABLE 'ttt_data'
|
||||
| 4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d (id INTEGER PRIM
|
||||
| 4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 ARY KEY, block B
|
||||
| 4032: 4c 4f 42 29 3a 01 06 17 13 13 08 5f 74 61 62 6c LOB):......_tabl
|
||||
| 4048: 65 74 74 74 74 74 74 43 52 45 41 54 45 20 56 49 ettttttCREATE VI
|
||||
| 4064: 52 54 55 41 4c 20 54 41 42 4c 45 20 74 74 74 20 RTUAL TABLE ttt
|
||||
| 4080: 55 53 49 4e 47 20 66 74 73 35 28 61 2c 20 62 29 USING fts5(a, b)
|
||||
| page 2 offset 4096
|
||||
| 0: 0d 0f 54 00 05 0e 81 00 0f e7 0e 81 0f af 0f 58 ..T............X
|
||||
| 16: 0e 98 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||
| 3712: 00 15 0a 03 00 30 00 00 00 00 01 03 03 00 03 01 .....0..........
|
||||
| 3728: 01 01 02 01 01 03 01 01 81 24 8c 80 80 80 80 01 .........$......
|
||||
| 3744: 04 00 82 4c 00 00 00 9b 02 30 65 03 1a 02 05 05 ...L.....0e.....
|
||||
| 3760: 07 05 01 01 04 03 03 08 03 03 01 2e 02 05 05 07 ................
|
||||
| 3776: 05 07 05 07 05 01 01 14 03 03 08 03 03 08 03 bf ................
|
||||
| 3792: 07 f2 f3 02 01 65 03 1e 03 05 05 04 05 05 01 01 .....e..........
|
||||
| 3808: 03 06 04 04 06 04 03 01 36 03 05 05 04 05 05 04 ........6.......
|
||||
| 3824: 05 15 04 05 05 01 01 03 06 04 04 06 04 04 a1 04 ................
|
||||
| 3840: 04 06 04 03 03 01 65 03 14 04 05 07 05 05 01 01 ......e.........
|
||||
| 3856: 02 09 0a 01 20 04 05 07 05 07 05 07 05 05 01 01 .... ...........
|
||||
| 3872: 02 0f da 0a 0a 04 01 64 f3 02 0a 01 06 0a 0a 0a .......d........
|
||||
| 3888: 05 01 65 03 06 01 01 0a 01 0a 01 01 0a 0a 0a 04 ..e.............
|
||||
| 3904: 2b 31 21 0b 0f ef 00 14 2a 00 00 00 00 01 02 02 +1!.....*.......
|
||||
| 3920: 00 02 01 01 01 02 01 01 50 88 80 80 80 80 01 04 ........P.......
|
||||
| 3936: 00 81 24 00 00 00 47 01 30 65 02 1a 02 05 05 07 ..$...G.0e......
|
||||
| 3952: 05 01 01 04 03 03 08 03 03 02 01 65 02 1d f3 05 ...........e....
|
||||
| 3968: 05 04 05 05 01 01 04 06 04 04 06 04 03 03 01 65 ...............e
|
||||
| 3984: 02 14 04 05 07 05 05 01 01 02 08 0a 04 01 65 02 ..............e.
|
||||
| 4000: 02 0a 05 01 65 02 06 01 01 0a 04 12 14 0f 06 31 ....e..........1
|
||||
| 4016: 84 80 80 80 80 01 03 00 68 00 00 00 2b 02 30 65 ........h...+.0e
|
||||
| 4032: 01 10 02 05 05 01 01 04 03 03 02 01 66 01 12 03 ............f...
|
||||
| 4048: 05 05 01 01 03 06 04 03 03 01 65 01 0e 04 05 05 ..........e.....
|
||||
| 4064: 01 01 02 08 04 0d 0e 06 01 03 00 12 04 4c 4c 00 .............LL.
|
||||
| 4080: 00 00 11 24 00 00 00 00 01 01 01 00 01 01 01 01 ...$............
|
||||
| page 3 offset 8192
|
||||
| 0: 0a 2f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ./..............
|
||||
| page 4 offset 12288
|
||||
| 3344: 00 00 00 00 00 00 00 00 00 00 81 52 04 06 10 81 ...........R....
|
||||
| 3360: 5d 81 55 65 20 65 65 20 65 65 65 20 65 20 65 65 ].Ue ee eee e ee
|
||||
| 3376: 20 65 65 65 20 65 20 65 65 20 65 65 65 65 20 65 eee e ee eeee e
|
||||
| 3392: 65 20 65 65 65 24 a5 20 65 65 20 65 65 65 20 65 e eee$. ee eee e
|
||||
| 3408: 24 05 65 20 65 65 65 65 20 65 65 20 65 65 65 20 $.e eeee ee eee
|
||||
| 3424: 65 20 65 65 20 65 65 65 20 65 20 65 65 20 65 65 e ee eee e ee ee
|
||||
| 3440: 65 65 20 65 65 20 65 65 65 20 65 20 65 65 10 65 ee ee eee e ee.e
|
||||
| 3456: 65 65 20 65 20 65 65 20 65 65 65 65 65 65 20 65 ee e ee eeeeee e
|
||||
| 3472: 65 20 65 20 65 20 65 20 65 65 20 65 65 65 20 65 e e e e ee eee e
|
||||
| 3488: 1f 20 65 65 66 65 65 20 65 65 20 65 20 65 20 2d . eefee ee e e -
|
||||
| page 5 offset 16384
|
||||
| 4064: 00 00 00 00 05 04 d0 00 10 21 21 05 03 03 00 10 .........!!.....
|
||||
| 4080: 11 11 05 02 03 00 10 11 10 05 01 03 00 10 09 09 ................
|
||||
| page 6 offset 20480
|
||||
| 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................
|
||||
| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version.
|
||||
| end sql022250.txt.db
|
||||
}]} {}
|
||||
|
||||
do_catchsql_test 70.1 {
|
||||
SELECT snippet(ttt, -1, '', '','','>')FROM ttt('e* NOT ee*e* NOT ee*');
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
do_catchsql_test 70.2 {
|
||||
SELECT snippet(ttt, -1, '', '','',13)FROM ttt('e* NOT ee*e* NOT ee*')
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
sqlite3_fts5_may_be_corrupt 0
|
||||
finish_test
|
||||
|
||||
|
||||
@@ -50,4 +50,47 @@ do_test 1.2 {
|
||||
}
|
||||
} {}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 2.0 {
|
||||
CREATE TABLE test (
|
||||
id INTEGER PRIMARY KEY,
|
||||
name TEXT,
|
||||
value TEXT
|
||||
);
|
||||
CREATE VIRTUAL TABLE test_idx USING fts5(
|
||||
name, content=test, content_rowid=id
|
||||
);
|
||||
}
|
||||
|
||||
do_catchsql_test 2.1 {
|
||||
INSERT INTO test_idx (test_idx, rowid, name) VALUES('delete', 1, 'quick');
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
do_catchsql_test 2.2 {
|
||||
INSERT INTO test_idx(rowid, name) VALUES(123, 'one one one');
|
||||
INSERT INTO test_idx (test_idx, rowid, name) VALUES('delete', 123, 'one');
|
||||
INSERT INTO test_idx (test_idx, rowid, name) VALUES('delete', 123, 'one');
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
do_execsql_test 2.3 {
|
||||
DROP TABLE test_idx;
|
||||
CREATE VIRTUAL TABLE test_idx USING fts5(
|
||||
name, content=test, content_rowid=id
|
||||
);
|
||||
|
||||
INSERT INTO test_idx(rowid, name) VALUES(123, 'one one one');
|
||||
INSERT INTO test_idx(rowid, name) VALUES(124, 'two two two');
|
||||
INSERT INTO test_idx(rowid, name) VALUES(125, 'two two two');
|
||||
INSERT INTO test_idx (test_idx, rowid, name) VALUES('delete', 123, 'one');
|
||||
INSERT INTO test_idx (test_idx, rowid, name) VALUES('delete', 123, 'one');
|
||||
INSERT INTO test_idx (test_idx, rowid, name) VALUES('delete', 123, 'one');
|
||||
}
|
||||
|
||||
do_catchsql_test 2.4 {
|
||||
SELECT rowid FROM test_idx WHERE test_idx MATCH 'two' ORDER BY rank;
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
source [file join [file dirname [info script]] fts5_common.tcl]
|
||||
source $testdir/malloc_common.tcl
|
||||
set testprefix fts5faultA
|
||||
set testprefix fts5faultD
|
||||
|
||||
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
|
||||
ifcapable !fts5 {
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
# 2016 February 2
|
||||
#
|
||||
# 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 is focused on OOM errors.
|
||||
#
|
||||
|
||||
source [file join [file dirname [info script]] fts5_common.tcl]
|
||||
source $testdir/malloc_common.tcl
|
||||
set testprefix fts5faultE
|
||||
|
||||
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
|
||||
ifcapable !fts5 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
faultsim_save_and_close
|
||||
do_faultsim_test 1 -prep {
|
||||
faultsim_restore_and_reopen
|
||||
} -body {
|
||||
execsql { CREATE VIRTUAL TABLE t1 USING fts5(x, y, tokenize=trigram) }
|
||||
} -test {
|
||||
faultsim_test_result {0 {}} {1 {vtable constructor failed: t1}}
|
||||
}
|
||||
|
||||
reset_db
|
||||
do_execsql_test 2.0 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(x, y, tokenize=trigram);
|
||||
}
|
||||
|
||||
faultsim_save_and_close
|
||||
do_faultsim_test 2 -prep {
|
||||
faultsim_restore_and_reopen
|
||||
} -body {
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES('abcdefghijklmnopqrstuvwxyz', NULL);
|
||||
SELECT count(*) FROM t1 WHERE x LIKE '%mnop%' AND t1 MATCH 'jkl';
|
||||
}
|
||||
} -test {
|
||||
faultsim_test_result {0 1} {1 {vtable constructor failed: t1}}
|
||||
}
|
||||
|
||||
reset_db
|
||||
do_execsql_test 3.0 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(x, y, tokenize=trigram, detail=none);
|
||||
INSERT INTO t1 VALUES('abcdefghijklmnopqrstuvwxyz', NULL);
|
||||
}
|
||||
|
||||
faultsim_save_and_close
|
||||
do_faultsim_test 3 -prep {
|
||||
faultsim_restore_and_reopen
|
||||
} -body {
|
||||
execsql {
|
||||
SELECT count(*) FROM t1 WHERE x LIKE '%mnopqrs%' AND t1 MATCH 'abc'
|
||||
}
|
||||
} -test {
|
||||
faultsim_test_result {0 1} {1 {vtable constructor failed: t1}}
|
||||
}
|
||||
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -112,7 +112,7 @@ foreach_detail_mode $testprefix {
|
||||
# Add a small and very large token with the same hash value to an
|
||||
# empty table. At one point this would provoke an asan error.
|
||||
#
|
||||
do_test 2.0 {
|
||||
do_test 1.5 {
|
||||
set big [string repeat 12345 40]
|
||||
set hash [sqlite3_fts5_token_hash 1024 $big]
|
||||
while {1} {
|
||||
@@ -128,4 +128,41 @@ foreach_detail_mode $testprefix {
|
||||
|
||||
} ;# foreach_detail_mode
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 2.1 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(x);
|
||||
INSERT INTO t1(t1, rank) VALUES('hashsize', 1024);
|
||||
INSERT INTO t1(t1, rank) VALUES('automerge', 0);
|
||||
INSERT INTO t1(t1, rank) VALUES('crisismerge', 1000);
|
||||
}
|
||||
|
||||
do_execsql_test 2.2 {
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES('abc def ghi');
|
||||
SELECT count(*) FROM t1_data;
|
||||
} {2}
|
||||
|
||||
do_execsql_test 2.3 {
|
||||
WITH s(i) AS (
|
||||
SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<1024
|
||||
)
|
||||
INSERT INTO t1 SELECT 'abc def ghi' FROM s;
|
||||
SELECT (SELECT count(*) FROM t1_data) > 10;
|
||||
} {1}
|
||||
|
||||
do_execsql_test 2.4 {
|
||||
COMMIT;
|
||||
DROP TABLE t1;
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(x);
|
||||
INSERT INTO t1(t1, rank) VALUES('hashsize', 1024);
|
||||
INSERT INTO t1(t1, rank) VALUES('automerge', 0);
|
||||
INSERT INTO t1(t1, rank) VALUES('crisismerge', 1000);
|
||||
WITH s(i) AS (
|
||||
SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<1024
|
||||
)
|
||||
INSERT INTO t1 SELECT 'abc' || i || ' def' || i || ' ghi' || i FROM s;
|
||||
SELECT (SELECT count(*) FROM t1_data) > 100;
|
||||
} {1}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -273,7 +273,6 @@ do_execsql_test 9.1.2 {
|
||||
SELECT quote(x'37');
|
||||
} {X'37'}
|
||||
|
||||
breakpoint
|
||||
do_execsql_test 9.2 {
|
||||
INSERT INTO vt0 VALUES (SUBSTR(x'37', 0));
|
||||
-- INSERT INTO vt0 VALUES (x'37');
|
||||
@@ -282,4 +281,40 @@ do_execsql_test 9.3 {
|
||||
INSERT INTO vt0(vt0) VALUES('integrity-check');
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 10.0 {
|
||||
CREATE TABLE t1(i INTEGER PRIMARY KEY, a, b);
|
||||
CREATE VIRTUAL TABLE vt0 USING fts5(a, b, content=t1);
|
||||
INSERT INTO vt0(rowid, a, b) VALUES(1, 'abc', 'def');
|
||||
}
|
||||
do_catchsql_test 10.1 {
|
||||
INSERT INTO vt0(vt0) VALUES('integrity-check');
|
||||
} {0 {}}
|
||||
do_catchsql_test 10.2 {
|
||||
INSERT INTO vt0(vt0, rank) VALUES('integrity-check', 0);
|
||||
} {0 {}}
|
||||
do_catchsql_test 10.3 {
|
||||
INSERT INTO vt0(vt0, rank) VALUES('integrity-check', 1);
|
||||
} {1 {database disk image is malformed}}
|
||||
do_catchsql_test 10.3 {
|
||||
INSERT INTO t1 VALUES(1, 'abc', 'def');
|
||||
INSERT INTO vt0(vt0, rank) VALUES('integrity-check', 1);
|
||||
} {0 {}}
|
||||
|
||||
do_execsql_test 10.4 {
|
||||
CREATE VIRTUAL TABLE vt1 USING fts5(a, b, content=);
|
||||
INSERT INTO vt1(rowid, a, b) VALUES(1, 'abc', 'def');
|
||||
}
|
||||
|
||||
do_catchsql_test 10.5.1 {
|
||||
INSERT INTO vt0(vt0, rank) VALUES('integrity-check', 0);
|
||||
} {0 {}}
|
||||
do_catchsql_test 10.5.2 {
|
||||
INSERT INTO vt0(vt0, rank) VALUES('integrity-check', 1);
|
||||
} {0 {}}
|
||||
do_catchsql_test 10.5.3 {
|
||||
INSERT INTO vt0(vt0) VALUES('integrity-check');
|
||||
} {0 {}}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -31,7 +31,7 @@ do_eqp_test 1.1 {
|
||||
} {
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1
|
||||
`--SCAN TABLE f1 VIRTUAL TABLE INDEX 0:m
|
||||
`--SCAN TABLE f1 VIRTUAL TABLE INDEX 0:M1
|
||||
}
|
||||
|
||||
do_eqp_test 1.2 {
|
||||
@@ -46,7 +46,7 @@ do_eqp_test 1.3 {
|
||||
SELECT * FROM f1 WHERE f1 MATCH ? ORDER BY ff
|
||||
} {
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE f1 VIRTUAL TABLE INDEX 0:m
|
||||
|--SCAN TABLE f1 VIRTUAL TABLE INDEX 0:M1
|
||||
`--USE TEMP B-TREE FOR ORDER BY
|
||||
}
|
||||
|
||||
|
||||
@@ -111,5 +111,40 @@ do_catchsql_test 2.1 {
|
||||
SELECT * FROM t4;
|
||||
} {1 {SQL logic error}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Embedded 0x00 characters.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 3.1.0 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(z);
|
||||
CREATE VIRTUAL TABLE tt USING fts5vocab(t1, 'instance');
|
||||
INSERT INTO t1 VALUES('abc' || char(0) || 'def');
|
||||
SELECT * FROM tt;
|
||||
} { abc 1 z 0 def 1 z 1 }
|
||||
do_execsql_test 3.1.1 {
|
||||
SELECT hex(z) FROM t1;
|
||||
} {61626300646566}
|
||||
do_execsql_test 3.1.2 {
|
||||
INSERT INTO t1(t1) VALUES('integrity-check');
|
||||
} {}
|
||||
|
||||
do_execsql_test 3.2.0 {
|
||||
CREATE VIRTUAL TABLE t2 USING fts5(z,
|
||||
tokenize="unicode61 categories 'L* N* Co Cc'"
|
||||
);
|
||||
CREATE VIRTUAL TABLE tu USING fts5vocab(t2, 'instance');
|
||||
|
||||
INSERT INTO t2 VALUES('abc' || char(0) || 'def');
|
||||
SELECT * FROM tu;
|
||||
} { abc 1 z 0 def 1 z 1 }
|
||||
|
||||
do_execsql_test 3.2.1 {
|
||||
SELECT hex(z) FROM t1;
|
||||
} {61626300646566}
|
||||
|
||||
do_execsql_test 3.2.2 {
|
||||
INSERT INTO t1(t1) VALUES('integrity-check');
|
||||
} {}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
# 2020 September 30
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#*************************************************************************
|
||||
#
|
||||
# Tests for the fts5 "trigram" tokenizer.
|
||||
#
|
||||
|
||||
source [file join [file dirname [info script]] fts5_common.tcl]
|
||||
ifcapable !fts5 { finish_test ; return }
|
||||
set ::testprefix fts5trigram
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(y, tokenize=trigram);
|
||||
INSERT INTO t1 VALUES('abcdefghijklm');
|
||||
INSERT INTO t1 VALUES('กรุงเทพมหานคร');
|
||||
}
|
||||
|
||||
foreach {tn s res} {
|
||||
1 abc "(abc)defghijklm"
|
||||
2 defgh "abc(defgh)ijklm"
|
||||
3 abcdefghijklm "(abcdefghijklm)"
|
||||
4 กรุ "(กรุ)งเทพมหานคร"
|
||||
5 งเทพมห "กรุ(งเทพมห)านคร"
|
||||
6 กรุงเทพมหานคร "(กรุงเทพมหานคร)"
|
||||
7 Abc "(abc)defghijklm"
|
||||
8 deFgh "abc(defgh)ijklm"
|
||||
9 aBcdefGhijKlm "(abcdefghijklm)"
|
||||
} {
|
||||
do_execsql_test 1.1.$tn {
|
||||
SELECT highlight(t1, 0, '(', ')') FROM t1($s)
|
||||
} $res
|
||||
}
|
||||
|
||||
do_execsql_test 1.2.0 {
|
||||
SELECT fts5_expr('ABCD', 'tokenize=trigram')
|
||||
} {{"abc" + "bcd"}}
|
||||
|
||||
do_execsql_test 1.2.1 {
|
||||
SELECT * FROM t1 WHERE y LIKE ? ESCAPE 'a'
|
||||
}
|
||||
|
||||
foreach {tn like res} {
|
||||
1 {%cDef%} 1
|
||||
2 {cDef%} {}
|
||||
3 {%f%} 1
|
||||
4 {%f_h%} 1
|
||||
5 {%f_g%} {}
|
||||
6 {abc%klm} 1
|
||||
7 {ABCDEFG%} 1
|
||||
8 {%รุงเ%} 2
|
||||
} {
|
||||
do_execsql_test 1.3.$tn {
|
||||
SELECT rowid FROM t1 WHERE y LIKE $like
|
||||
} $res
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 2.0 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(y, tokenize="trigram case_sensitive 1");
|
||||
INSERT INTO t1 VALUES('abcdefghijklm');
|
||||
INSERT INTO t1 VALUES('กรุงเทพมหานคร');
|
||||
}
|
||||
|
||||
foreach {tn s res} {
|
||||
1 abc "(abc)defghijklm"
|
||||
2 defgh "abc(defgh)ijklm"
|
||||
3 abcdefghijklm "(abcdefghijklm)"
|
||||
4 กรุ "(กรุ)งเทพมหานคร"
|
||||
5 งเทพมห "กรุ(งเทพมห)านคร"
|
||||
6 กรุงเทพมหานคร "(กรุงเทพมหานคร)"
|
||||
7 Abc ""
|
||||
8 deFgh ""
|
||||
9 aBcdefGhijKlm ""
|
||||
} {
|
||||
do_execsql_test 2.1.$tn {
|
||||
SELECT highlight(t1, 0, '(', ')') FROM t1($s)
|
||||
} $res
|
||||
}
|
||||
foreach {tn like res} {
|
||||
1 {%cDef%} 1
|
||||
2 {cDef%} {}
|
||||
3 {%f%} 1
|
||||
4 {%f_h%} 1
|
||||
5 {%f_g%} {}
|
||||
6 {abc%klm} 1
|
||||
7 {ABCDEFG%} 1
|
||||
8 {%รุงเ%} 2
|
||||
} {
|
||||
do_execsql_test 2.2.$tn {
|
||||
SELECT rowid FROM t1 WHERE y LIKE $like
|
||||
} $res
|
||||
}
|
||||
foreach {tn like res} {
|
||||
1 {*cdef*} 1
|
||||
2 {cdef*} {}
|
||||
3 {*f*} 1
|
||||
4 {*f?h*} 1
|
||||
5 {*f?g*} {}
|
||||
6 {abc*klm} 1
|
||||
7 {abcdefg*} 1
|
||||
8 {*รุงเ*} 2
|
||||
9 {abc[d]efg*} 1
|
||||
10 {abc[]d]efg*} 1
|
||||
11 {abc[^]d]efg*} {}
|
||||
12 {abc[^]XYZ]efg*} 1
|
||||
} {
|
||||
do_execsql_test 2.3.$tn {
|
||||
SELECT rowid FROM t1 WHERE y GLOB $like
|
||||
} $res
|
||||
}
|
||||
|
||||
do_execsql_test 2.3.null.1 {
|
||||
SELECT rowid FROM t1 WHERE y LIKE NULL
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_catchsql_test 3.1 {
|
||||
CREATE VIRTUAL TABLE ttt USING fts5(c, tokenize="trigram case_sensitive 2");
|
||||
} {1 {error in tokenizer constructor}}
|
||||
do_catchsql_test 3.2 {
|
||||
CREATE VIRTUAL TABLE ttt USING fts5(c, tokenize="trigram case_sensitive 11");
|
||||
} {1 {error in tokenizer constructor}}
|
||||
do_catchsql_test 3.3 {
|
||||
CREATE VIRTUAL TABLE ttt USING fts5(c, "tokenize=trigram case_sensitive 1");
|
||||
} {0 {}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 4.0 {
|
||||
CREATE VIRTUAL TABLE t0 USING fts5(b, tokenize = "trigram");
|
||||
}
|
||||
do_execsql_test 4.1 {
|
||||
INSERT INTO t0 VALUES (x'000b01');
|
||||
}
|
||||
do_execsql_test 4.2 {
|
||||
INSERT INTO t0(t0) VALUES('integrity-check');
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
foreach_detail_mode $::testprefix {
|
||||
foreach {ci} {0 1} {
|
||||
reset_db
|
||||
do_execsql_test 5.cs=$ci.0.1 "
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(
|
||||
y, tokenize=\"trigram case_sensitive $ci\", detail=%DETAIL%
|
||||
);
|
||||
"
|
||||
do_execsql_test 5.cs=$ci.0.2 {
|
||||
INSERT INTO t1 VALUES('abcdefghijklm');
|
||||
INSERT INTO t1 VALUES('กรุงเทพมหานคร');
|
||||
}
|
||||
|
||||
foreach {tn like res} {
|
||||
1 {%cDef%} 1
|
||||
2 {cDef%} {}
|
||||
3 {%f%} 1
|
||||
4 {%f_h%} 1
|
||||
5 {%f_g%} {}
|
||||
6 {abc%klm} 1
|
||||
7 {ABCDEFG%} 1
|
||||
8 {%รุงเ%} 2
|
||||
} {
|
||||
do_execsql_test 5.cs=$ci.1.$tn {
|
||||
SELECT rowid FROM t1 WHERE y LIKE $like
|
||||
} $res
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
do_execsql_test 6.0 {
|
||||
CREATE VIRTUAL TABLE ci0 USING fts5(x, tokenize="trigram");
|
||||
CREATE VIRTUAL TABLE ci1 USING fts5(x, tokenize="trigram case_sensitive 1");
|
||||
}
|
||||
|
||||
# LIKE and GLOB both work with case-insensitive tokenizers. Only GLOB works
|
||||
# with case-sensitive.
|
||||
do_eqp_test 6.1 {
|
||||
SELECT * FROM ci0 WHERE x LIKE ?
|
||||
} {VIRTUAL TABLE INDEX 0:L0}
|
||||
do_eqp_test 6.2 {
|
||||
SELECT * FROM ci0 WHERE x GLOB ?
|
||||
} {VIRTUAL TABLE INDEX 0:G0}
|
||||
do_eqp_test 6.3 {
|
||||
SELECT * FROM ci1 WHERE x LIKE ?
|
||||
} {{SCAN TABLE ci1 VIRTUAL TABLE INDEX 0:}}
|
||||
do_eqp_test 6.4 {
|
||||
SELECT * FROM ci1 WHERE x GLOB ?
|
||||
} {VIRTUAL TABLE INDEX 0:G0}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -12,6 +12,7 @@ proc process_cmdline {} {
|
||||
cmdline::process ::A $::argv {
|
||||
{fts5 "use fts5 (this is the default)"}
|
||||
{fts4 "use fts4"}
|
||||
{trigram "Use tokenize=trigram"}
|
||||
{colsize "10 10 10" "list of column sizes"}
|
||||
{tblname "t1" "table name to create"}
|
||||
{detail "full" "Fts5 detail mode to use"}
|
||||
@@ -175,6 +176,7 @@ proc create_table {} {
|
||||
set sql "CREATE VIRTUAL TABLE IF NOT EXISTS $A(tblname) USING $A(fts) ("
|
||||
append sql [join $cols ,]
|
||||
if {$A(fts)=="fts5"} { append sql ",detail=$A(detail)" }
|
||||
if {$A(trigram)} { append sql ",tokenize=trigram" }
|
||||
append sql ", prefix='$A(prefix)');"
|
||||
|
||||
db eval $sql
|
||||
|
||||
+3
-3
@@ -54,11 +54,11 @@
|
||||
** statically linked against the application, initialize it using
|
||||
** a single API call as follows:
|
||||
**
|
||||
** sqlite3_cksumvfs_init();
|
||||
** sqlite3_register_cksumvfs();
|
||||
**
|
||||
** Cksumvfs is a VFS Shim. When loaded, "cksmvfs" becomes the new
|
||||
** default VFS and it uses the prior default VFS as the next VFS
|
||||
** down in the stack. This is normally what you want. However, it
|
||||
** down in the stack. This is normally what you want. However, in
|
||||
** complex situations where multiple VFS shims are being loaded,
|
||||
** it might be important to ensure that cksumvfs is loaded in the
|
||||
** correct order so that it sequences itself into the default VFS
|
||||
@@ -79,7 +79,7 @@
|
||||
** the reserve-bytes value to 8 by runing:
|
||||
**
|
||||
** int n = 8;
|
||||
** sqlite3_file_control(db, 0, SQLITE_FCNTL_RESERVED_BYTES, &n);
|
||||
** sqlite3_file_control(db, 0, SQLITE_FCNTL_RESERVE_BYTES, &n);
|
||||
**
|
||||
** If you do this immediately after creating a new database file,
|
||||
** before anything else has been written into the file, then that
|
||||
|
||||
+1
-1
@@ -776,7 +776,7 @@ static int csvtabColumn(
|
||||
CsvCursor *pCur = (CsvCursor*)cur;
|
||||
CsvTable *pTab = (CsvTable*)cur->pVtab;
|
||||
if( i>=0 && i<pTab->nCol && pCur->azVal[i]!=0 ){
|
||||
sqlite3_result_text(ctx, pCur->azVal[i], -1, SQLITE_STATIC);
|
||||
sqlite3_result_text(ctx, pCur->azVal[i], -1, SQLITE_TRANSIENT);
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
+9
-7
@@ -523,14 +523,16 @@ static int zipfileAppendData(
|
||||
const u8 *aWrite,
|
||||
int nWrite
|
||||
){
|
||||
size_t n;
|
||||
fseek(pTab->pWriteFd, (long)pTab->szCurrent, SEEK_SET);
|
||||
n = fwrite(aWrite, 1, nWrite, pTab->pWriteFd);
|
||||
if( (int)n!=nWrite ){
|
||||
pTab->base.zErrMsg = sqlite3_mprintf("error in fwrite()");
|
||||
return SQLITE_ERROR;
|
||||
if( nWrite>0 ){
|
||||
size_t n = nWrite;
|
||||
fseek(pTab->pWriteFd, (long)pTab->szCurrent, SEEK_SET);
|
||||
n = fwrite(aWrite, 1, nWrite, pTab->pWriteFd);
|
||||
if( (int)n!=nWrite ){
|
||||
pTab->base.zErrMsg = sqlite3_mprintf("error in fwrite()");
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
pTab->szCurrent += nWrite;
|
||||
}
|
||||
pTab->szCurrent += nWrite;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -759,7 +759,7 @@ static int nodeAcquire(
|
||||
** are the leaves, and so on. If the depth as specified on the root node
|
||||
** is greater than RTREE_MAX_DEPTH, the r-tree structure must be corrupt.
|
||||
*/
|
||||
if( pNode && iNode==1 ){
|
||||
if( pNode && rc==SQLITE_OK && iNode==1 ){
|
||||
pRtree->iDepth = readInt16(pNode->zData);
|
||||
if( pRtree->iDepth>RTREE_MAX_DEPTH ){
|
||||
rc = SQLITE_CORRUPT_VTAB;
|
||||
|
||||
@@ -227,7 +227,7 @@ static int SQLITE_TCLAPI test_session_cmd(
|
||||
){
|
||||
TestSession *p = (TestSession*)clientData;
|
||||
sqlite3_session *pSession = p->pSession;
|
||||
struct SessionSubcmd {
|
||||
static struct SessionSubcmd {
|
||||
const char *zSub;
|
||||
int nArg;
|
||||
const char *zMsg;
|
||||
@@ -1131,7 +1131,7 @@ static int SQLITE_TCLAPI test_rebaser_cmd(
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
struct RebaseSubcmd {
|
||||
static struct RebaseSubcmd {
|
||||
const char *zSub;
|
||||
int nArg;
|
||||
const char *zMsg;
|
||||
@@ -1248,7 +1248,7 @@ static int SQLITE_TCLAPI test_sqlite3session_config(
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
struct ConfigOpt {
|
||||
static struct ConfigOpt {
|
||||
const char *zSub;
|
||||
int op;
|
||||
} aSub[] = {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
C Optimizations\sto\sthe\slogic\sthat\sconverts\smain\stable\saccesses\sinto\sequivalent\nindex\saccesses.\s\sCode\sis\snow\sslightly\ssmaller\sand\sfaster\sthan\strunk.
|
||||
D 2020-08-14T21:32:16.882
|
||||
C Prettify\sbtree.h\sheadings.\sClose\sbranch.
|
||||
D 2020-10-27T11:58:37.756
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@@ -7,7 +7,7 @@ F Makefile.in 19374a5db06c3199ec1bab71ab74a103d8abf21053c05e9389255dc58083f806
|
||||
F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241
|
||||
F Makefile.msc 48f5a3fc32672c09ad73795749f6253e406a31526935fbbffd8f021108d54574
|
||||
F README.md 1514a365ffca3c138e00c5cc839906108a01011a6b082bad19b09781e3aa498a
|
||||
F VERSION 5db2ee2cfcc790af73775fa485c13b2e8ccaa5936c6e1f47aedeba7056041ca5
|
||||
F VERSION 4027b9aea92d64385570778ebd14388c0b23e92aafda15e7b89c45886c9b920a
|
||||
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
||||
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
|
||||
F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
|
||||
@@ -34,11 +34,11 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
|
||||
F config.guess 883205ddf25b46f10c181818bf42c09da9888884af96f79e1719264345053bd6
|
||||
F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc
|
||||
F config.sub c2d0260f17f3e4bc0b6808fccf1b291cb5e9126c14fc5890efc77b9fd0175559
|
||||
F configure a97f98dfff699495aef66ae3d9c424345778a663f583e0d6e7522670518f87c1 x
|
||||
F configure 63af83d31b9fdf304f2dbb1e1638530d4ceff31702d1e19550d1fbf3bdf9471e x
|
||||
F configure.ac 40d01e89cb325c28b33f5957e61fede0bd17da2b5e37d9b223a90c8a318e88d4
|
||||
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
||||
F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd
|
||||
F doc/lemon.html 1edc0f916e771212792d4d077aedc05168bf13fd65d64d41b2c13e46ac0063a8
|
||||
F doc/lemon.html c5d8ba85ac1daef7be8c2d389899480eb62451ff5c09b0c28ff8157bb8770746
|
||||
F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710
|
||||
F doc/trusted-schema.md 33625008620e879c7bcfbbfa079587612c434fa094d338b08242288d358c3e8a
|
||||
F doc/vfs-shm.txt e101f27ea02a8387ce46a05be2b1a902a021d37a
|
||||
@@ -49,8 +49,8 @@ F ext/async/sqlite3async.c 6f247666b495c477628dd19364d279c78ea48cd90c72d9f9b98ad
|
||||
F ext/async/sqlite3async.h 46b47c79357b97ad85d20d2795942c0020dc20c532114a49808287f04aa5309a
|
||||
F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3
|
||||
F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4
|
||||
F ext/expert/expert1.test 2e10ff875c31c9e6fc5e324767624181273859771fe34c5daeeadf3f2974a4f7
|
||||
F ext/expert/sqlite3expert.c b5eae75862d34a204d16c45dcb813888b5f86bdc156c6136b0f79094c0da4f79
|
||||
F ext/expert/expert1.test dba6e752cc701621771f925f3872b183fa688f7b4a9f4822631fc02bdbffc45a
|
||||
F ext/expert/sqlite3expert.c 2778d9f06b3a8bfa859cb6b75b82f004477bf5dd78edd17d954319750ca963f3
|
||||
F ext/expert/sqlite3expert.h ca81efc2679a92373a13a3e76a6138d0310e32be53d6c3bfaedabd158ea8969b
|
||||
F ext/expert/test_expert.c d56c194b769bdc90cf829a14c9ecbc1edca9c850b837a4d0b13be14095c32a72
|
||||
F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e
|
||||
@@ -112,20 +112,20 @@ F ext/fts3/unicode/mkunicode.tcl bf7fcaa6d68e6d38223467983785d054f1cff4d9e3905dd
|
||||
F ext/fts3/unicode/parseunicode.tcl a981bd6466d12dd17967515801c3ff23f74a281be1a03cf1e6f52a6959fc77eb
|
||||
F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0
|
||||
F ext/fts5/fts5.h c132a9323f22a972c4c93a8d5a3d901113a6e612faf30ca8e695788438c5ca2a
|
||||
F ext/fts5/fts5Int.h d7cbc214ee167496f70905667e18f73ea0402f7ef09236ce305e117e0efc866a
|
||||
F ext/fts5/fts5Int.h 26c74dd5776f798436fbf604a0bf0e8de263b35b5060b05c15f9085845d9fda2
|
||||
F ext/fts5/fts5_aux.c dcc627d8b6e3fc773db528ff67b39955dab7b51628f9dba8e15849e5bedfd7fa
|
||||
F ext/fts5/fts5_buffer.c 5a5fe0159752c0fb0a5a93c722e9db2662822709490769d482b76a6dc8aaca70
|
||||
F ext/fts5/fts5_config.c b447948f35ad3354e8fe5e242e0a7e7b5b941555400b9404259944e3aa570037
|
||||
F ext/fts5/fts5_expr.c 2be456484786333d559dc2987a00f2750981fab91d52db8452a8046278c5f22e
|
||||
F ext/fts5/fts5_hash.c 1cc0095646f5f3b46721aa112fb4f9bf29ae175cb5338f89dcec66ed97acfe75
|
||||
F ext/fts5/fts5_index.c de14c9a30f45e2b847ff9284b14776d9d07961e545e8f1546a6aa3f915af721f
|
||||
F ext/fts5/fts5_main.c e881a2ea0bf01b3a3ff0bc1b31373c58fd54b6c9f3c43ea3d431bea4e5d4025e
|
||||
F ext/fts5/fts5_storage.c 3ecda8edadc1f62a355d6789776be0da609f8658c50d72e422674093ab7e1528
|
||||
F ext/fts5/fts5_config.c be54f44fca491e96c6923a4b9a736f2da2b13811600eb6e38d1bcc91c4ea2e61
|
||||
F ext/fts5/fts5_expr.c e527e3a7410393075598cec544e3831798a8c88b3e8878e2cfb7cb147113e925
|
||||
F ext/fts5/fts5_hash.c 1aa93c9b5f461afba66701ee226297dc78402b3bdde81e90a10de5fe3df14959
|
||||
F ext/fts5/fts5_index.c fb8ed13cb8f2ddeb80ea6ade6e35d59b0bc01b9bd741f7e60a1c58a92877d5d7
|
||||
F ext/fts5/fts5_main.c b4e4931c7fcc9acfa0c3b8b5e5e80b5b424b8d9207aae3a22b674bd35ccf149d
|
||||
F ext/fts5/fts5_storage.c 58ba71e6cd3d43a5735815e7956ee167babb4d2cbfe206905174792af4d09d75
|
||||
F ext/fts5/fts5_tcl.c 39bcbae507f594aad778172fa914cad0f585bf92fd3b078c686e249282db0d95
|
||||
F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee
|
||||
F ext/fts5/fts5_test_tok.c f96c6e193c466711d6d7828d5f190407fe7ab897062d371426dd3036f01258e7
|
||||
F ext/fts5/fts5_tokenize.c 2e508c6a3bd8ee56c48e98a38052e1a650e49b32a484cce9b189984114bc3b88
|
||||
F ext/fts5/fts5_unicode2.c 8bd0cd07396b74c1a05590e4070d635bccfc849812c305619f109e6c0485e250
|
||||
F ext/fts5/fts5_tokenize.c 6f47244681c670ec3c1364f19b2ec0cca191249ff3543755a65e1fc1df348061
|
||||
F ext/fts5/fts5_unicode2.c 85f64663cbd8ddd09d3a1e8823759b07085018b4a53158632e264cd785f88763
|
||||
F ext/fts5/fts5_varint.c e64d2113f6e1bfee0032972cffc1207b77af63319746951bf1d09885d1dadf80
|
||||
F ext/fts5/fts5_vocab.c 7a071833064dc8bca236c3c323e56aac36f583aa2c46ce916d52e31ce87462c9
|
||||
F ext/fts5/fts5parse.y eb526940f892ade5693f22ffd6c4f2702543a9059942772526eac1fde256bb05
|
||||
@@ -151,7 +151,7 @@ F ext/fts5/test/fts5bigpl.test 6466c89b38439f0aba26ac09e232a6b963f29b1cbe1304f6a
|
||||
F ext/fts5/test/fts5bigtok.test 541119e616c637caea925a8c028c37c2c29e94383e00aa2f9198d530724b6e36
|
||||
F ext/fts5/test/fts5cat.test daba0b80659460b0cb60bd1f40b402478a761fe7ea414c3c94c2be25568cc33a
|
||||
F ext/fts5/test/fts5circref.test f880dfd0d99f6fb73b88ccacb0927d18e833672fd906cc47d6b4e529419eaa62
|
||||
F ext/fts5/test/fts5colset.test a30473451321bbf0b6218af62e96b4ae5fa99931cfdb210b5ecc804623b30f75
|
||||
F ext/fts5/test/fts5colset.test 7031ce84fb4d312df5a99fc4e7b324e660ccb513c97eccdef469bfd52d3d0f8f
|
||||
F ext/fts5/test/fts5columnsize.test 45459ce4dd9fd853b6044cdc9674921bff89e3d840f348ca8c1630f9edbf5482
|
||||
F ext/fts5/test/fts5config.test 60094712debc59286c59aef0e6cf511c37d866802776a825ce437d26afe0817f
|
||||
F ext/fts5/test/fts5conflict.test 655925678e630d3cdf145d18725a558971806416f453ac8410ca8c04d934238d
|
||||
@@ -159,9 +159,9 @@ F ext/fts5/test/fts5connect.test 08030168fc96fc278fa81f28654fb7e90566f33aff269c0
|
||||
F ext/fts5/test/fts5content.test 213506436fb2c87567b8e31f6d43ab30aab99354cec74ed679f22aad0cdbf283
|
||||
F ext/fts5/test/fts5corrupt.test 77ae6f41a7eba10620efb921cf7dbe218b0ef232b04519deb43581cb17a57ebe
|
||||
F ext/fts5/test/fts5corrupt2.test 7453752ba12ce91690c469a6449d412561cc604b1dec994e16ab132952e7805f
|
||||
F ext/fts5/test/fts5corrupt3.test 7afe0fea5b2160798fdc3306395048768c6fc13acefc0e7129d4075b6e1bb224
|
||||
F ext/fts5/test/fts5corrupt3.test b8d4d6f167b8189999dac7162ddec614ab9dca4fe5e9dcfd315e383a5e15444b
|
||||
F ext/fts5/test/fts5corrupt4.test ea805c4d7c68b5f185b9db5d2060a7ae5875339738dd48203c92162f41e7ca91
|
||||
F ext/fts5/test/fts5delete.test cbf87e3b8867c4d5cfcaed975c7475fd3f99d072bce2075fcedf43d1f82af775
|
||||
F ext/fts5/test/fts5delete.test 4a15fb03b6c7eac62ac807a3a32b7f0dc74f0d479c410e3e3568ae96b9469290
|
||||
F ext/fts5/test/fts5detail.test 31b240dbf6d44ac3507e2f8b65f29fdc12465ffd531212378c7ce1066766f54e
|
||||
F ext/fts5/test/fts5determin.test 1b77879b2ae818b5b71c859e534ee334dac088b7cf3ff3bf76a2c82b1c788d11
|
||||
F ext/fts5/test/fts5dlidx.test b90852c55881b29dbac6380b274de27beae623ac4b6d567c6c8fb9cdc315a86e
|
||||
@@ -179,12 +179,13 @@ F ext/fts5/test/fts5fault8.test 318238659d35f82ad215ecb57ca4c87486ea85d45dbeedae
|
||||
F ext/fts5/test/fts5fault9.test 098e6b894bbdf9b2192f994a30f4043673fb3f338b6b8ab1624c704422f39119
|
||||
F ext/fts5/test/fts5faultA.test be4487576bff8c22cee6597d1893b312f306504a8c6ccd3c53ca85af12290c8c
|
||||
F ext/fts5/test/fts5faultB.test d606bdb8e81aaeb6f41de3fc9fc7ae315733f0903fbff05cf54f5b045b729ab5
|
||||
F ext/fts5/test/fts5faultD.test cc5d1225556e356615e719c612e845d41bff7d5a
|
||||
F ext/fts5/test/fts5faultD.test e7ed7895abfe6bc98a5e853826f6b74956e7ba7f594f1860bbf9e504b9647996
|
||||
F ext/fts5/test/fts5faultE.test 844586ce71dab4be85bb86880e87b624d089f851654cd22e4710c77eb8ce7075
|
||||
F ext/fts5/test/fts5first.test 3fcf2365c00a15fc9704233674789a3b95131d12de18a9b996159f6909dc8079
|
||||
F ext/fts5/test/fts5full.test e1701a112354e0ff9a1fdffb0c940c576530c33732ee20ac5e8361777070d717
|
||||
F ext/fts5/test/fts5fuzz1.test 238d8c45f3b81342aa384de3e581ff2fa330bf922a7b69e484bbc06051a1080e
|
||||
F ext/fts5/test/fts5hash.test a4cf51acad99bfc43c16fb74f9d22495dc221ae0701fc5e908ca963a9b26a02b
|
||||
F ext/fts5/test/fts5integrity.test 8ffabcd91b058d812aba3e3e0a06f76ce165ba402a18cca20e34204a7feec92e
|
||||
F ext/fts5/test/fts5hash.test dc7bc7e0cdeb42cfce31294ad2f8fcf43192bfd0145bb7f3ecc5465d8c72696f
|
||||
F ext/fts5/test/fts5integrity.test e387b2bd1c83e50f4a12f58a5fd399111bbab36be2f1c9fd5bb974be08a32de6
|
||||
F ext/fts5/test/fts5interrupt.test 09613247b273a99889808ef852898177e671406fe71fdde7ea00e78ea283d227
|
||||
F ext/fts5/test/fts5lastrowid.test be98fe3e03235296585b72daad7aed5717ba0062bae5e5c18dd6e04e194c6b28
|
||||
F ext/fts5/test/fts5leftjoin.test c0b4cafb9661379e576dc4405c0891d8fcc2782680740513c4d1fc114b43d4ad
|
||||
@@ -198,7 +199,7 @@ F ext/fts5/test/fts5near.test 211477940142d733ac04fad97cb24095513ab2507073a99c27
|
||||
F ext/fts5/test/fts5onepass.test f9b7d9b2c334900c6542a869760290e2ab5382af8fbd618834bf1fcc3e7b84da
|
||||
F ext/fts5/test/fts5optimize.test 36a752d24c818792032e4ff502936fc9cc5ef938721696396fdc79214b2717f1
|
||||
F ext/fts5/test/fts5phrase.test 13e5d8e9083077b3d9c74315b3c92ec723cc6eb37c8155e0bfe1bba00559f07b
|
||||
F ext/fts5/test/fts5plan.test 771b999d161e24fd803ce0290adb7c6e7c9b9cc2c6a0adb344813fb89473aa32
|
||||
F ext/fts5/test/fts5plan.test 79d35b5e83bbdcba48d946a7f008df161f6b0ede1a966892d0aa6c8dd0b6e773
|
||||
F ext/fts5/test/fts5porter.test 8d08010c28527db66bc3feebd2b8767504aaeb9b101a986342fa7833d49d0d15
|
||||
F ext/fts5/test/fts5porter2.test 0d251a673f02fa13ca7f011654873b3add20745f7402f108600a23e52d8c7457
|
||||
F ext/fts5/test/fts5prefix.test a0fa67b06650f2deaa7bf27745899d94e0fb547ad9ecbd08bfad98c04912c056
|
||||
@@ -213,9 +214,10 @@ F ext/fts5/test/fts5simple2.test 258a1b0c590409bfa5271e872c79572b319d2a56554d058
|
||||
F ext/fts5/test/fts5simple3.test d5c74a9d3ca71bd5dd5cacb7c55b86ea12cdddfc8b1910e3de2995206898380f
|
||||
F ext/fts5/test/fts5synonym.test 1651815b8008de170e8e600dcacc17521d765482ea8f074ae82cfa870d8bb7fb
|
||||
F ext/fts5/test/fts5synonym2.test b54cce5c34ec08ed616f646635538ae82e34a0e28f947ec60b6fadbc4b3fb17a
|
||||
F ext/fts5/test/fts5tok1.test ce6551e41ff56f30b69963577324624733bed0d1753589f06120d664d9cd45c9
|
||||
F ext/fts5/test/fts5tok1.test 1f7817499f5971450d8c4a652114b3d833393c8134e32422d0af27884ffe9cef
|
||||
F ext/fts5/test/fts5tok2.test dcacb32d4a2a3f0dd3215d4a3987f78ae4be21a2
|
||||
F ext/fts5/test/fts5tokenizer.test ac3c9112b263a639fb0508ae73a3ee886bf4866d2153771a8e8a20c721305a43
|
||||
F ext/fts5/test/fts5trigram.test e2ce256fd0ccd6707e740aa3596206aedb0d5834b100c0cb49e344dcd1d8463c
|
||||
F ext/fts5/test/fts5umlaut.test a42fe2fe6387c40c49ab27ccbd070e1ae38e07f38d05926482cc0bccac9ad602
|
||||
F ext/fts5/test/fts5unicode.test 17056f4efe6b0a5d4f41fdf7a7dc9af2873004562eaa899d40633b93dc95f5a9
|
||||
F ext/fts5/test/fts5unicode2.test 9b3df486de05fb4bde4aa7ee8de2e6dae1df6eb90e3f2e242c9383b95d314e3e
|
||||
@@ -227,7 +229,7 @@ F ext/fts5/test/fts5version.test c8f2cc105f0abf0224965f93e584633dee3e06c91478bc6
|
||||
F ext/fts5/test/fts5vocab.test 7ed80d9af1ddaaa1637da05e406327b5aac250848bc604c1c1cc667908b87760
|
||||
F ext/fts5/test/fts5vocab2.test e0fdc3a3095f6eda68ac9bf9a443ff929a124d46f00af19933604085712e9d47
|
||||
F ext/fts5/tool/fts5speed.tcl b0056f91a55b2d1a3684ec05729de92b042e2f85
|
||||
F ext/fts5/tool/fts5txt2db.tcl 526a9979c963f1c54fd50976a05a502e533a4c59
|
||||
F ext/fts5/tool/fts5txt2db.tcl c0d43c8590656f8240e622b00957b3a0facc49482411a9fdc2870b45c0c82f9f
|
||||
F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093
|
||||
F ext/fts5/tool/mkfts5c.tcl d1c2a9ab8e0ec690a52316f33dd9b1d379942f45
|
||||
F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c
|
||||
@@ -286,11 +288,11 @@ F ext/misc/appendvfs.c 55121d311d408ba9c62c3cfa367408887638f02f9522dd9859891d0ee
|
||||
F ext/misc/blobio.c a867c4c4617f6ec223a307ebfe0eabb45e0992f74dd47722b96f3e631c0edb2a
|
||||
F ext/misc/btreeinfo.c d28ce349b40054eaa9473e835837bad7a71deec33ba13e39f963d50933bfa0f9
|
||||
F ext/misc/carray.c 91e9a7f512fda934894bed30464552fffa7d3073b5be04189ae0bd0c59f26bfd
|
||||
F ext/misc/cksumvfs.c 0f022867786b615d7f68fb3ab3a16627fe6a730442abf804735e18a73f835a83
|
||||
F ext/misc/cksumvfs.c 910848f3d9739908cf77cad66a76dd45001546f46ff5ef4ca5c20c5476e77e98
|
||||
F ext/misc/closure.c dbfd8543b2a017ae6b1a5843986b22ddf99ff126ec9634a2f4047cd14c85c243
|
||||
F ext/misc/completion.c 6dafd7f4348eecc7be9e920d4b419d1fb2af75d938cd9c59a20cfe8beb2f22b9
|
||||
F ext/misc/compress.c 3354c77a7c8e86e07d849916000cdac451ed96500bfb5bd83b20eb61eee012c9
|
||||
F ext/misc/csv.c 3ed979c1eb35e35a98b30ef545a2facf62994594217681d9138b4b75faf6b0d7
|
||||
F ext/misc/csv.c 53b3338d4fa812eda51a2637df30233a4dae16b964ee5666e2051b9672ed8bb4
|
||||
F ext/misc/dbdata.c e316fba936571584e55abd5b974a32a191727a6b746053a0c9d439bd2cf93940
|
||||
F ext/misc/dbdump.c b8592f6f2da292c62991a13864a60d6c573c47a9cc58362131b9e6a64f823e01
|
||||
F ext/misc/decimal.c 3ddbf8162015be4d5ec2395dee4538f1e638bb517174bb148274b132df6e1d08
|
||||
@@ -332,7 +334,7 @@ F ext/misc/vfsstat.c 389ea13983d3af926504c314f06a83cc858d5adc24b40af74aaed1fece0
|
||||
F ext/misc/vtablog.c 5538acd0c8ddaae372331bee11608d76973436b77d6a91e8635cfc9432fba5ae
|
||||
F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd
|
||||
F ext/misc/wholenumber.c 520f34c3099e5b7d546f13708607dc2fa173c46b68952eecf0d19cd675fec85e
|
||||
F ext/misc/zipfile.c d1be54ea83ac9ad71b8b6ffc4b60db8946ce2ceacdf6bff063fcd9489f41bb49
|
||||
F ext/misc/zipfile.c e35e035bc2765b1ccdcb15f9815c2112843fcbc8f36aa071f0e5935df7072228
|
||||
F ext/misc/zorder.c b0ff58fa643afa1d846786d51ea8d5c4b6b35aa0254ab5a82617db92f3adda64
|
||||
F ext/rbu/rbu.c 8681f6157db6adc82c34af24b14ea8a3be0146ad2a3b6c1d5da6cb8a5796c8ce
|
||||
F ext/rbu/rbu1.test 221d9c18a5e600ac9ac6b1810d99d9f99163a7909ba61597876ab6e4d4beb3d6
|
||||
@@ -388,7 +390,7 @@ F ext/repair/test/checkindex01.test b530f141413b587c9eb78ff734de6bb79bc3515c3350
|
||||
F ext/repair/test/test.tcl 686d76d888dffd021f64260abf29a55c57b2cedfa7fc69150b42b1d6119aac3c
|
||||
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
|
||||
F ext/rtree/geopoly.c f15cc6845d64a629035627d863cbe3eadc9cb30f9ca77bd823b0ca8a5a3f8b00
|
||||
F ext/rtree/rtree.c f87ffcc91f49272862119cfdd256b02514351893786a710d88f85933790608d4
|
||||
F ext/rtree/rtree.c 60f6f1675134201974be4189dbd219494c13e1ed30e80bd92ae0dcc86df1b035
|
||||
F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412
|
||||
F ext/rtree/rtree1.test 00792b030a4e188ff1b22e8530e8aa0452bb5dd81c2b18cb004afc7dc63e040e
|
||||
F ext/rtree/rtree2.test 9d9deddbb16fd0c30c36e6b4fdc3ee3132d765567f0f9432ee71e1303d32603d
|
||||
@@ -450,7 +452,7 @@ F ext/session/sessionstat1.test 218d351cf9fcd6648f125a26b607b140310160184723c266
|
||||
F ext/session/sessionwor.test 67b5ab91d4f93ce65ff1f58240ac5ddf73f8670facc1ffa49cef56293d52818d
|
||||
F ext/session/sqlite3session.c 2c76b8c3a5d6dab736686f8a48833b8bdac0871ecc6f447f9839d28bd4a63d6c
|
||||
F ext/session/sqlite3session.h a2db5b72b938d12c727b4b4ec632254ca493670a9c0de597af3271a7f774fc57
|
||||
F ext/session/test_session.c 98797aba475a799376c9a42214f2d1debf2d0c3cb657d9c8bbf4f70bf3fb4aec
|
||||
F ext/session/test_session.c 24286d958dc6f4ca4d7e710f09bc0fa9d50956a40dd99fd8223e7488024c71fe
|
||||
F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
|
||||
F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04
|
||||
F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb
|
||||
@@ -470,24 +472,24 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
|
||||
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
|
||||
F src/alter.c 805de23ddca536181f8f0439df989fdd4a2f76c40bc305ec9fe2f211f68c89e8
|
||||
F src/analyze.c 5cffff3d355858cd22bfc6e20ac7203510d2e1cc935086eb06f4abb2f579f628
|
||||
F src/attach.c 0b11e00c166b622c84ec176773b1d691c61ad07d247809e3e1635d4e99e71d30
|
||||
F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c
|
||||
F src/attach.c 0f497c15c4cfe3bdcb214f0dbdbbb6c5ed7e8a9308ac445c7959f5e5780437a9
|
||||
F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06
|
||||
F src/backup.c b1c90cd4110248c8e1273ff4578d3a84c0c34725e1b96dacd4a6294a908702de
|
||||
F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d
|
||||
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
|
||||
F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
|
||||
F src/btree.c 1439fd9b45d4d1883c53752daef42af489adaa1a1508fa39dedbc9c80ea21a2f
|
||||
F src/btree.h 7af72bbb4863c331c8f6753277ab40ee67d2a2125a63256d5c25489722ec162b
|
||||
F src/btreeInt.h 83166f6daeb91062b6ae9ee6247b3ad07e40eba58f3c05ba9e8dedad4ab1ea38
|
||||
F src/build.c dbdaee54ffef924a070eb6202017e10d6be56baab953ef0a8e714a6def683198
|
||||
F src/btree.c ad0a38e4d4a0b6b3e003b5478556dbe890c0d58c7a95362e02d1fa539631af19
|
||||
F src/btree.h c16c855f7e2ef5bfe8fb119a20339fb8e24a3efe6edce17be4df66bce4e20241
|
||||
F src/btreeInt.h ffd66480520d9d70222171b3a026d78b80833b5cea49c89867949f3e023d5f43
|
||||
F src/build.c f6449d4e85e998e14d3f537e8ea898dca2fcb83c277db3e60945af9b9177db81
|
||||
F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c
|
||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||
F src/ctime.c e98518d2d3d4029a13c805e07313fb60c877be56db76e90dd5f3af73085d0ce6
|
||||
F src/date.c dace306a10d9b02ee553d454c8e1cf8d3c9b932e137738a6b15b90253a9bfc10
|
||||
F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a
|
||||
F src/dbstat.c 3aa79fc3aed7ce906e4ea6c10e85d657299e304f6049861fe300053ac57de36c
|
||||
F src/delete.c a2a603ab07cced8560065b0e2c4c9c842f2c5a2fd43d87355f95eb53bae7fe21
|
||||
F src/expr.c 58c06940d964c2cf455b979cf66a648499d294a5ee6dadcaeaed447257c1dc75
|
||||
F src/delete.c 927cf8f900583e79aca8f1a321979e0a8f053babd9a690b44b38f79de2cc09fe
|
||||
F src/expr.c 2cfe739c81e9751123b900dee54f6d34f8ec4b747515a51f1771de8e2840650d
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c 83372403298e6a7dd989a47aaacdbaa5b4307b5199dbd56e07d4896066b3de72
|
||||
F src/func.c 2333eb4277f55a5efdc12ef754e7d7ec9105d257b2fd00301d23ce1e8fa67dc0
|
||||
@@ -496,17 +498,17 @@ F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19
|
||||
F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38
|
||||
F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144
|
||||
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
|
||||
F src/insert.c 957254a2d0542597455d0d4c640e4e3f3eea8c6d78f04582df03dfc626f07925
|
||||
F src/insert.c 7e081d33aab4a9d761c39dccf3c3872c35501565d2ed9db66301918d23bc7901
|
||||
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
|
||||
F src/loadext.c 436af4968c6954d304fce9efa12719367bd8f37b19b93b71d6ad607e85adbb47
|
||||
F src/main.c 09580279145f27f3db206ef44dcb3a8875a42644230f79c7e54aff35e71668f0
|
||||
F src/malloc.c 22d5bdd9fe88ae4fad1b91a1b9735104b82853ffef868f1f05517d60dc1875f5
|
||||
F src/main.c 54d61d1e94f225636053c862c930d7dd7b29162b93d3f3ecb00439910ccba02a
|
||||
F src/malloc.c 413b0ffea2b45c37c6cf2ed5509f6d6b508b0a033caa9b4bf90bed4ee044a2ff
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
|
||||
F src/mem2.c b93b8762ab999a29ae7751532dadf0a1ac78040308a5fb1d17fcc365171d67eb
|
||||
F src/mem3.c 30301196cace2a085cbedee1326a49f4b26deff0af68774ca82c1f7c06fda4f6
|
||||
F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944
|
||||
F src/memdb.c d58e398e315e88f95f8d07d17e80ab11259ebd6d1a10397434329eeabd1985e3
|
||||
F src/memdb.c ab0632d42407e866d2b616bd19d4211ac0ad1b430f04c4e187d60005b8700b98
|
||||
F src/memjournal.c 90b2ca7e2f465d57c16b69d15a9f3e3294af61088eb4938f2f7664d5ac50f813
|
||||
F src/msvc.h 3a15918220367a8876be3fa4f2abe423a861491e84b864fb2b7426bf022a28f8
|
||||
F src/mutex.c 5e3409715552348732e97b9194abe92fdfcd934cfb681df4ba0ab87ac6c18d25
|
||||
@@ -519,38 +521,38 @@ F src/os.c 80e4cf3e5da06be03ca641661e331ce60eeeeabf0d7354dbb1c0e166d0eedbbe
|
||||
F src/os.h 48388821692e87da174ea198bf96b1b2d9d83be5dfc908f673ee21fafbe0d432
|
||||
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
|
||||
F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
|
||||
F src/os_unix.c 9b1b860163fd2d4d7679b5260d384d1a9f88ef917a90f28963eca8acd472d8c8
|
||||
F src/os_win.c a2149ff0a85c1c3f9cc102a46c673ce87e992396ba3411bfb53db66813b32f1d
|
||||
F src/os_unix.c b16ae8f19de9fb91836164b8ff122c069d0b177179df7bb632cf41bf61308d89
|
||||
F src/os_win.c 77d39873836f1831a9b0b91894fec45ab0e9ca8e067dc8c549e1d1eca1566fe9
|
||||
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
||||
F src/pager.c 3700a1c55427a3d4168ad1f1b8a8b0cb9ace1d107e4506e30a8f1e66d8a1195e
|
||||
F src/pager.h 4bf9b3213a4b2bebbced5eaa8b219cf25d4a82f385d093cd64b7e93e5285f66f
|
||||
F src/parse.y 5bdb760a29c0b25caf7e80e82210b81cd2ea3066d5199ca29e6eac40b34bc184
|
||||
F src/parse.y 9ce4dfb772608ed5bd3c32f33e943e021e3b06cfd2c01932d4280888fdd2ebed
|
||||
F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177
|
||||
F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
|
||||
F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a
|
||||
F src/pragma.c bdb600be936f66b9fe69d26dfbba4528beaaf4f95c479c85b328a92484e0bf71
|
||||
F src/pragma.c 6daaaecc26a4b09481d21722525b079ce756751a43a79cc1d8f122d686806193
|
||||
F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf
|
||||
F src/prepare.c 3d5a761d026052bc888d1b803a06dd2bfe245e8e836d4689f927003549148b0f
|
||||
F src/printf.c 9efcd4e984f22bcccb1ded37a1178cac98f6e3a0534e1e0629f64899971f8838
|
||||
F src/prepare.c 270170a239c0f66bd3c228f373afe24447c2614a6829ae22080babc64f241931
|
||||
F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed
|
||||
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
|
||||
F src/resolve.c d74715aceed2a8f493ba244d535646fa93132042a4400a29dfd26ec841514048
|
||||
F src/resolve.c 97b91fb25d86881ff20c9ad2ad98412c6c1bb5f7d6c9bb044db250cbc9cfcd4b
|
||||
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
|
||||
F src/select.c 510fdf819f218be3dac2683d3eaaf64e5080f548061a4dd12205590beda976bb
|
||||
F src/shell.c.in b9b819feede7b85585ab0826490a352e04e2ee46e8132c92597d29972b2be1d7
|
||||
F src/sqlite.h.in d2c03414a8ee5d4a6855c04dd7cd5998e45139b0fe66b65bae86d4223edd091f
|
||||
F src/select.c 645aa47fb8ce95e95290d4852d44cf5997c89c3e754a74c91e010459a8db7a72
|
||||
F src/shell.c.in b317d851046496c92e28529eb96f9d2ec1ad480590b1676e0362865f5466f886
|
||||
F src/sqlite.h.in ff32663b457306eb88c3039868280aa39da31162ed69c4e71fa8e028684e7277
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 2d1af80082edffd71c6f96f70ad1ce6a4fb46615ad10291fc77fe0dea9ff0197
|
||||
F src/sqliteInt.h 86ad0f9164cbadb2ba9598cc6cf5b32bdb47b343c0da5ca62f3d73b60be55b65
|
||||
F src/sqliteLimit.h 95cb8479ca459496d9c1c6a9f76b38aee12203a56ce1092fe13e50ae2454c032
|
||||
F src/sqliteInt.h c6c4c310b699364eff6457f05beb47fd30943687d511bf99b6f722af236377fb
|
||||
F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
|
||||
F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1
|
||||
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
|
||||
F src/tclsqlite.c 986b6391f02cd9b53c1d688be55899f6ffddeb8e8014cd83c1b73ff912579a71
|
||||
F src/test1.c 24b9cd0863ecc4d3920f4999c40e876c2bd92f3cc5879c48b99abe02c546ed18
|
||||
F src/test1.c 9e52fb797bf74fa327295df38881aa3ade0824bfb0c14abd0719e555b169fd55
|
||||
F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
|
||||
F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644
|
||||
F src/test4.c 7c4420e01c577b5c4add2cb03119743b1a357543d347773b9e717195ea967159
|
||||
F src/test5.c 328aae2c010c57a9829d255dc099d6899311672d
|
||||
F src/test6.c e8d839fbc552ce044bec8234561a2d5b8819b48e29548ad0ba400471697946a8
|
||||
F src/test6.c ae73a3a42bbc982fb9e301b84d30bda65a307be48c6dff20aba1461e17a9b0ce
|
||||
F src/test7.c 5612e9aecf934d6df7bba6ce861fdf5ba5456010
|
||||
F src/test8.c 7fb971777c2c79c734bb52757191d68d4af659b8de9b4a071be3f527a9d19a02
|
||||
F src/test9.c 12e5ba554d2d1cbe0158f6ab3f7ffcd7a86ee4e5
|
||||
@@ -563,10 +565,10 @@ F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274
|
||||
F src/test_config.c 5ea19bf0972a9d91728518b4d30e91477acce80496003ecbef3a7fb18d0bd081
|
||||
F src/test_delete.c e2fe07646dff6300b48d49b2fee2fe192ed389e834dd635e3b3bac0ce0bf9f8f
|
||||
F src/test_demovfs.c 86142ba864d4297d54c5b2e972e74f3141ae4b30f05b3a95824184ed2d3d7f91
|
||||
F src/test_devsym.c 6109b45c3db3ef7b002320947ed448c027356ab8b885156ff535fd8684d4a571
|
||||
F src/test_devsym.c aff2255ea290d7718da08af30cdf18e470ff7325a5eff63e0057b1496ed66593
|
||||
F src/test_fs.c ba1e1dc18fd3159fdba0b9c4256f14032159785320dfbd6776eb9973cb75d480
|
||||
F src/test_func.c 181f992e5495644434c4f0e3cc72362a78c295eb2cf3ff4d02498b8bde7aa276
|
||||
F src/test_hexio.c d170d0e1a6431afdeac086a250d2595078288c2257615d37949355361399bcaa
|
||||
F src/test_hexio.c 9478e56a0f08e07841a014a93b20e4ba2709ab56d039d1ca8020e26846aa19bd
|
||||
F src/test_init.c 4413c211a94b62157ca4c145b3f27c497f03c664
|
||||
F src/test_intarray.c 39b4181662a0f33a427748d87218e7578d913e683dc27eab7098bb41617cac71
|
||||
F src/test_intarray.h d57ae92f420cda25e22790dac474d60961bd0c500cbaa3338a05152d4a669ef7
|
||||
@@ -592,7 +594,7 @@ F src/test_tclsh.c eeafce33ad2136d57e5dec10f1e9a4347447eb72ffd504a1c7b9c6bfe2e71
|
||||
F src/test_tclvar.c 33ff42149494a39c5fbb0df3d25d6fafb2f668888e41c0688d07273dcb268dfc
|
||||
F src/test_thread.c 269ea9e1fa5828dba550eb26f619aa18aedbc29fd92f8a5f6b93521fbb74a61c
|
||||
F src/test_vdbecov.c f60c6f135ec42c0de013a1d5136777aa328a776d33277f92abac648930453d43
|
||||
F src/test_vfs.c 36822d696789535bdd0260f07d2c9a46546082fea8bb1d0a7354c7f9366e37ea
|
||||
F src/test_vfs.c 2cc38a79892017702d13da79ad5152c196eec19bbd67fbde4d88065aac894a84
|
||||
F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698
|
||||
F src/test_windirent.c a895e2c068a06644eef91a7f0a32182445a893b9a0f33d0cdb4283dca2486ac1
|
||||
F src/test_windirent.h 90dfbe95442c9762357fe128dc7ae3dc199d006de93eb33ba3972e0a90484215
|
||||
@@ -602,19 +604,19 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
|
||||
F src/tokenize.c 4dc01b267593537e2a0d0efe9f80dabe24c5b6f7627bc6971c487fa6a1dacbbf
|
||||
F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda
|
||||
F src/trigger.c ef67bde309a831515dc3c2173d792574309f2f42d45f8c078743fae9f7f98c75
|
||||
F src/update.c 55a6203008d033fc1a9c125d7a0a61efdb79bbb2e6db427b917d1d427b4639be
|
||||
F src/update.c 1f6167d4acff9f2ae800f7dade84877afbd595c155cdeb7d56f08165d75570c4
|
||||
F src/upsert.c 2920de71b20f04fe25eb00b655d086f0ba60ea133c59d7fa3325c49838818e78
|
||||
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
|
||||
F src/util.c c8bf30c4356b091bcc3b624d0e24b2b4d11b8be4d6c90d8e0705971e15cc819b
|
||||
F src/vacuum.c 1c4f8e2f39d950037f4cf946b6858c993d3a54c3101f78e05c76460a073afcf0
|
||||
F src/vdbe.c e9f7f818f128c8600058c0eabb6b3975974c95153a104d340f419adabbc15b9f
|
||||
F src/util.c c0c7977de7ef9b8cb10f6c85f2d0557889a658f817b0455909a49179ba4c8002
|
||||
F src/vacuum.c 492422c1463c076473bae1858799c7a0a5fe87a133d1223239447c422cd26286
|
||||
F src/vdbe.c 6f3fb4f058c478b38c5280ccfc939745076c6a693999e49846c99fdc761c9c90
|
||||
F src/vdbe.h 83603854bfa5851af601fc0947671eb260f4363e62e960e8a994fb9bbcd2aaa1
|
||||
F src/vdbeInt.h 762abffb7709f19c2cb74af1bba73a900f762e64f80d69c31c9ae89ed1066b60
|
||||
F src/vdbeInt.h 3ca5e9fd6e095a8b6cf6bc3587a46fc93499503b2fe48951e1034ba9e2ce2f6e
|
||||
F src/vdbeapi.c c5e7cb2ab89a24d7f723e87b508f21bfb1359a04db5277d8a99fd1e015c12eb9
|
||||
F src/vdbeaux.c 73854da7a9a4f12db72a855758214173c82f46a14be6cb19e63677ba02c97cae
|
||||
F src/vdbeaux.c c4c0389aed3ac31f835904c3d1f730d6818742633f9474140d8ce174c10f2267
|
||||
F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b1
|
||||
F src/vdbemem.c 947f2a65910edb4014dc981d33e414a68c51f169f9df8c4c493a0ba840b6eb1f
|
||||
F src/vdbesort.c 2be76d26998ce2b3324cdcc9f6443728e54b6c7677c553ad909c7d7cfab587df
|
||||
F src/vdbesort.c f5b5e473a7cee44e47a94817b042fd7172cf3aa2c0a7928a8339d612bcfdec5a
|
||||
F src/vdbetrace.c fa3bf238002f0bbbdfb66cc8afb0cea284ff9f148d6439bc1f6f2b4c3b7143f0
|
||||
F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c
|
||||
F src/vtab.c 5f5fc793092f53bbdfde296c50f563fb7bda58cf48e9cf6a8bdfbc5abd409845
|
||||
@@ -622,14 +624,14 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c 69e770e96fd56cc21608992bf2c6f1f3dc5cf2572d0495c6a643b06c3a679f14
|
||||
F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a
|
||||
F src/walker.c 3df26a33dc4f54e8771600fb7fdebe1ece0896c2ad68c30ab40b017aa4395049
|
||||
F src/where.c 396ba2c62defd56283ef54a4b221f698f4733fe8fbfca4aa8b1cc4f8c58d12ee
|
||||
F src/whereInt.h eb8c2847fb464728533777efec1682b3c074224293b2da73513c61a609efbeab
|
||||
F src/wherecode.c cb9bc7cef99578c99baceafeea9c9bcc738d5be37f56dbfe3a1c61ea52483fd0
|
||||
F src/whereexpr.c 264d58971eaf8256eb5b0917bcd7fc7a1f1109fdda183a8382308a1b18a2dce7
|
||||
F src/where.c 03d35ea488e694849923e28ccdce1ef377a5c3738405b5323ff97eb9aa7569c1
|
||||
F src/whereInt.h 59077fbd0b3d01bc8715e746c86a99ebf4c85bde8a57077ec04d2a23e59666ec
|
||||
F src/wherecode.c a3a1aff30fe99a818d8e7c607980f033f40c68d890e03ed25838b9dbb7908bee
|
||||
F src/whereexpr.c 2a05552e808047a93845278c98c6ca64a265fa8e9ffd087c161bb11bfe339866
|
||||
F src/window.c edd6f5e25a1e8f2b6f5305b7f5f7da7bb35f07f0d432b255b1d4c2fcab4205aa
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627
|
||||
F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
|
||||
F test/affinity3.test eecb0dabee4b7765a8465439d5e99429279ffba23ca74a7eae270a452799f9e7
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
F test/aggnested.test 2f65ec8132e0ca896de550b9908094d49ad65a99116a9d79deeb6017604ad4f6
|
||||
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
|
||||
@@ -644,12 +646,12 @@ F test/altercol.test 1d6a6fe698b81e626baea4881f5717f9bc53d7d07f1cd23ee7ad1b931f1
|
||||
F test/alterlegacy.test 82022721ce0de29cedc9a7af63bc9fcc078b0ee000f8283b4b6ea9c3eab2f44b
|
||||
F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74a3fb80c9
|
||||
F test/altermalloc2.test fa7b1c1139ea39b8dec407cf1feb032ca8e0076bd429574969b619175ad0174b
|
||||
F test/altertab.test b8b2104212e8ea87c75c3cbe3cb78ed7236a6c828ee2e59ed09d3dbe9812d002
|
||||
F test/altertab.test 6d7bbac2c4a6ef71b775094a3298fa3a92274d95034ee23157ffba92768e47e6
|
||||
F test/altertab2.test b0d62f323ca5dab42b0bc028c52e310ebdd13e655e8fac070fe622bad7852c2b
|
||||
F test/altertab3.test d0d51e652aaa11e37de1f1215181d88334fefcb185f3b9bd91e06e98260c4694
|
||||
F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
|
||||
F test/analyze.test 547bb700f903107b38611b014ca645d6b5bb819f5210d7bf39c40802aafeb7d7
|
||||
F test/analyze3.test 01f0b122e3e54ad2544f14f7cc7dcb4c2cb8753cad5e88c6b8d49615b3fd6a2b
|
||||
F test/analyze3.test fca2a9de0017becfdcc201647f03b1cfd5ba0e7b5b5c852936e4ec62780cde49
|
||||
F test/analyze4.test cdf88f3f72b0f0643a1ff6c730fc5af1e42464d47478d9fbac84c333f72c014e
|
||||
F test/analyze5.test fa5131952303ac4146aba101b116b9c8cb89e2637531c334a6df7f7d19dddc0d
|
||||
F test/analyze6.test 6c3f7df2996cb6872f355a6ac1eb6d5de00a5a9288214bad7ef25c97d9cc72dc
|
||||
@@ -667,7 +669,7 @@ F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b
|
||||
F test/async3.test d73a062002376d7edc1fe3edff493edbec1fc2f7
|
||||
F test/async4.test 1787e3952128aa10238bf39945126de7ca23685a
|
||||
F test/async5.test 383ab533fdb9f7ad228cc99ee66e1acb34cc0dc0
|
||||
F test/atof1.test 1ccfc96a6888566597b83d882c81b3c04258dc39317e8c1cec89ba481eaa2fba
|
||||
F test/atof1.test 10049623e77006691c4c2978c1dc8a3f75276377a53417811aa85bda7493f963
|
||||
F test/atomic.test 065a453dde33c77ff586d91ccaa6ed419829d492dbb1a5694b8a09f3f9d7d061
|
||||
F test/atomic2.test b6863b4aa552543874f80b42fb3063f1c8c2e3d8e56b6562f00a3cc347b5c1da
|
||||
F test/atrc.c c388fac43dbba05c804432a7135ae688b32e8f25818e9994ffba4b64cf60c27c
|
||||
@@ -709,7 +711,7 @@ F test/bestindex7.test f36ada201973d3022cf7afffffe08de9e58341996020e7a2df9a1d2f2
|
||||
F test/between.test 68137a6e941c221417c15b6fe2d55f27bb1b6ab48bdf9e2aa51efdd85bc53802
|
||||
F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59
|
||||
F test/bigfile2.test 1b489a3a39ae90c7f027b79110d6b4e1dbc71bfc
|
||||
F test/bigmmap.test 31dad31573638bd32de866cdefd11843f75685be4ba6aec1a47918f098f1899b
|
||||
F test/bigmmap.test e906cf9729d7c362270ffe9fa6471f4c39c28ba83f0f77fb795e1b4d38a22ba0
|
||||
F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747
|
||||
F test/bigsort.test 8299fa9298f4f1e02fc7d2712e8b77d6cd60e5a2
|
||||
F test/bind.test 1e136709b306f7ed3192d349c2930d89df6ab621654ad6f1a72381d3fe76f483
|
||||
@@ -728,7 +730,7 @@ F test/btree01.test e08b3613540145b353f20c81cb18ead54ff12e0f
|
||||
F test/btree02.test 7555a5440453d900410160a52554fe6478af4faf53098f7235f1f443d5a1d6cc
|
||||
F test/btreefault.test c2bcb542685eea44621275cfedbd8a13f65201e3
|
||||
F test/busy.test 510dc6daaad18bcbbc085bcc6217d6dc418def5e73f72ce1475eea0cb7834727
|
||||
F test/busy2.test 2499cb62c9e58e18335892602c158cb35639c411803adca6423401b31e46c503
|
||||
F test/busy2.test 26ae3b8b74235c851f27326807de94292af4d359476c629f80dc106f35c8293e
|
||||
F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de
|
||||
F test/cacheflush.test af25bb1509df04c1da10e38d8f322d66eceedf61
|
||||
F test/cachespill.test 895997f84a25b323b166aecb69baab2d6380ea98f9e0bcc688c4493c535cfab9
|
||||
@@ -738,9 +740,9 @@ F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4
|
||||
F test/capi3c.test 54e2dc0c8fd7c34ad1590d1be6864397da2438c95a9f5aee2f8fbc60c112e44b
|
||||
F test/capi3d.test aba917805573a03deed961a21f07a5a84505ad0a616f7e3fc1508844a15bccc4
|
||||
F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe
|
||||
F test/cast.test 2906ccab6a3ebd147ffa63304b635be903ce58264110d0a0eb4fd9939422bb53
|
||||
F test/cast.test 336fa21989b5170ebcaf90c24266be22dd97b3e23d1fad5ecf6ad4efb04c4423
|
||||
F test/cffault.test 9d6b20606afe712374952eec4f8fd74b1a8097ef
|
||||
F test/check.test 9776af795bb5d0f197b7f8fe248052e3ca2ed35304d863efcdbf8b1316e11f65
|
||||
F test/check.test 4a2a91ed67eee84a6be16057c48d5198b6fb24849cd6da6cd855981de3fbb416
|
||||
F test/checkfault.test da6cb3d50247169efcb20bdf57863a3ccfa1d27d9e55cd324f0680096970f014
|
||||
F test/chunksize.test 427d87791743486cbf0c3b8c625002f3255cb3a89c6eba655a98923b1387b760
|
||||
F test/close.test eccbad8ecd611d974cbf47278c3d4e5874faf02d811338d5d348af42d56d647c
|
||||
@@ -759,8 +761,8 @@ F test/collateA.test b8218ab90d1fa5c59dcf156efabb1b2599c580d6
|
||||
F test/collateB.test 1e68906951b846570f29f20102ed91d29e634854ee47454d725f2151ecac0b95
|
||||
F test/colmeta.test 2c765ea61ee37bc43bbe6d6047f89004e6508eb1
|
||||
F test/colname.test 87ad5458bb8709312dac0d6755fd30e8e4ca83298d0a9ef6e5c24277a3c3390e
|
||||
F test/conflict.test 58857e2533fb9f2e0358ea7cb191215657846be1dd9da3b3d6df3e750c02ae03
|
||||
F test/conflict2.test bb0b94cf7196c64a3cbd815c66d3ee98c2fecd9c
|
||||
F test/conflict.test ac0667090f66130ac77d5fb764655558ca6600dd6d88f670ca9123b61c448337
|
||||
F test/conflict2.test 5557909ce683b1073982f5d1b61dfb1d41e369533bfdaf003180c5bc87282dd1
|
||||
F test/conflict3.test 81865d9599609aca394fb3b9cd5f561d4729ea5b176bece3644f6ecb540f88ac
|
||||
F test/contrib01.test 2a1cbc0f2f48955d7d073f725765da6fbceda6b4
|
||||
F test/corrupt.test d7cb0300e4a297147b6a05e92a1684bc8973635c3bcaa3d66e983c9cbdbf47a3
|
||||
@@ -807,7 +809,7 @@ F test/cursorhint.test 0175e4404181ace3ceca8b114eb0a98eae600d565aa4e2705abbe6614
|
||||
F test/cursorhint2.test 6f3aa9cb19e7418967a10ec6905209bcbb5968054da855fc36c8beee9ae9c42f
|
||||
F test/dataversion1.test 6e5e86ac681f0782e766ebcb56c019ae001522d114e0e111e5ebf68ccf2a7bb8
|
||||
F test/date.test 9b73bbeb1b82d9c1f44dec5cf563bf7da58d2373
|
||||
F test/date2.test 5ef8265c71460cda6b1698bf18f4bb0ffb40ac08c5092f6afe84d398c2feb5be
|
||||
F test/date2.test 520a1708e4e14c682cf514560f3e9f2e5affa9d66560fbc2a6941ae291260daf
|
||||
F test/dbdata.test 042f49acff3438f940eeba5868d3af080ae64ddf26ae78f80c92bec3ca7d8603
|
||||
F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e
|
||||
F test/dbfuzz001.test 55e1a3504f8dea84155e09912fe3b1c3ad77e0b1a938ec42ca03b8e51b321e30
|
||||
@@ -828,14 +830,14 @@ F test/descidx2.test a0ba347037ff3b811f4c6ceca5fd0f9d5d72e74e59f2d9de346a9d2f6ad
|
||||
F test/descidx3.test 953c831df7ea219c73826dfbf2f6ee02d95040725aa88ccb4fa43d1a1999b926
|
||||
F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e
|
||||
F test/distinct.test e7d0cf371944dd0cbedff86420744e2f1ea2b528156451c97eb6ff41a99b9236
|
||||
F test/distinct2.test 11b0594c932098e969d084ba45ab81d5040f4d4e766db65d49146705a305ed98
|
||||
F test/distinct2.test cd1d15a4a2abf579298f7161e821ed50c0119136fe0424db85c52cf0adc230d1
|
||||
F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376
|
||||
F test/e_blobbytes.test 439a945953b35cb6948a552edaec4dc31fd70a05
|
||||
F test/e_blobclose.test 4b3c8c60c2171164d472059c73e9f3c1844bb66d
|
||||
F test/e_blobopen.test e95e1d40f995056f6f322cd5e1a1b83a27e1a145
|
||||
F test/e_blobwrite.test f87ff598b67af5b3ec002a8d83e804dc8d23808e88cf0080c176612fc9ffce14
|
||||
F test/e_changes.test fd66105385153dbf21fdb35eb8ef6c3e1eade579
|
||||
F test/e_createtable.test ea27082d6f84df61e1d9e383f3fd79220418856a4a8afc41af75d458b8e7ac33
|
||||
F test/e_createtable.test 7107f5deda2324ea12dbf105044dc9265195401e9dbb3eead6a2c1a3da4bb5b7
|
||||
F test/e_delete.test ab39084f26ae1f033c940b70ebdbbd523dc4962e
|
||||
F test/e_droptrigger.test 235c610f8bf8ec44513e222b9085c7e49fad65ad0c1975ac2577109dd06fd8fa
|
||||
F test/e_dropview.test 74e405df7fa0f762e0c9445b166fe03955856532e2bb234c372f7c51228d75e7
|
||||
@@ -879,7 +881,7 @@ F test/filter2.tcl 44e525497ce07382915f01bd29ffd0fa49dab3adb87253b5e5103ba8f9339
|
||||
F test/filter2.test 485cf95d1f6d6ceee5632201ca52a71868599836f430cdee42e5f7f14666e30a
|
||||
F test/filterfault.test c08fb491d698e8df6c122c98f7db1c65ffcfcad2c1ab0e07fa8a5be1b34eaa8b
|
||||
F test/fkey1.test d11dbb8a93ead9b5c46ae5d02da016d61245d47662fb2d844c99214f6163f768
|
||||
F test/fkey2.test b1b6a8c5556dc0ccf31291b1fed8aa57e404b38f3236110e19ab4dc6aa93edf2
|
||||
F test/fkey2.test 1063d65e5923c054cfb8f0555a92a3ae0fa8c067275a33ee1715bd856cdb304c
|
||||
F test/fkey3.test 76d475c80b84ee7a5d062e56ccb6ea68882e2b49
|
||||
F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d
|
||||
F test/fkey5.test 6727452e163a427147e84e739da18713da553d79f9783559b04fdcd36d5c7421
|
||||
@@ -1017,7 +1019,7 @@ F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d
|
||||
F test/func.test f673822636fb8ed618dd2b80230d16e495d19c8f2e2e7d6c22e93e2b3de097ad
|
||||
F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f
|
||||
F test/func3.test 2bb0f31ab7baaed690b962a88544d7be6b34fa389364bc36a44e441ed3e3f1e6
|
||||
F test/func4.test a94858a8c1f10a408b0b3db439c990b59dbb2349411d503de011ac4e2b5f27a6
|
||||
F test/func4.test 2285fb5792d593fef442358763f0fd9de806eda47dbc7a5934df57ffdc484c31
|
||||
F test/func5.test 863e6d1bd0013d09c17236f8a13ea34008dd857d87d85a13a673960e4c25d82a
|
||||
F test/func6.test 90e42b64c4f9fb6f04f44cb8a1da586c8542502e926b19c76504fe74ff2a9b7c
|
||||
F test/fuzz-oss1.test e58330d01cbbd8215ee636b17a03fe220b37dbfa
|
||||
@@ -1027,7 +1029,7 @@ F test/fuzz3.test 9c813e6613b837cb7a277b0383cd66bfa07042b4cf0317157c35852f30043c
|
||||
F test/fuzz4.test c229bcdb45518a89e1d208a21343e061503460ac69fae1539320a89f572eb634
|
||||
F test/fuzz_common.tcl b7197de6ed1ee8250a4f82d67876f4561b42ee8cbbfc6160dcb66331bad3f830
|
||||
F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2
|
||||
F test/fuzzcheck.c 656ee850f331872a784e7d6a10649efe2af123bdaacb728b5a03e4faee8b959c
|
||||
F test/fuzzcheck.c 5f81f2cc65f13068620245f2e2c6059657d3b26be476df379ae2da539f17676d
|
||||
F test/fuzzdata1.db d36e88741b4f23bcbaaf55b006290669d03c6c891cf13c7b3a53bc1b097b693f
|
||||
F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f
|
||||
F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
|
||||
@@ -1035,7 +1037,7 @@ F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e4
|
||||
F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5
|
||||
F test/fuzzdata6.db 92a80e4afc172c24f662a10a612d188fb272de4a9bd19e017927c95f737de6d7
|
||||
F test/fuzzdata7.db 0166b56fd7a6b9636a1d60ef0a060f86ddaecf99400a666bb6e5bbd7199ad1f2
|
||||
F test/fuzzdata8.db 99f99201280962430f3287e879e050ba88fe458d05cbf28e37ecab369ffe2e86
|
||||
F test/fuzzdata8.db f8451a1fd38efbea8c1a7cdf5d02259c4702446a9fabf566becd306b64a50236
|
||||
F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8
|
||||
F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14
|
||||
F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536
|
||||
@@ -1050,7 +1052,7 @@ F test/hook2.test b9ff3b8c6519fb67f33192f1afe86e7782ee4ac8
|
||||
F test/icu.test 716a6b89fbabe5cc63e0cd4c260befb08fd7b9d761f04d43669233292f0753b1
|
||||
F test/ieee754.test b0945d12be7d255f3dfa18e2511b17ca37e0edd2b803231c52d05b86c04ab26e
|
||||
F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8
|
||||
F test/in.test ae4ba0fe3232fdd84ef1090a68c5cd6ccd93f1f8774d5c967dd0c1b301492eed
|
||||
F test/in.test 688ed2011d922d83141a45af431601738674a4c0bdde34b6351f688b82a169b3
|
||||
F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75
|
||||
F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0
|
||||
F test/in4.test 65460600d48933adba4283c6ebd089aae173d16136ab9d01f74c89089090c5a5
|
||||
@@ -1084,7 +1086,7 @@ F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
|
||||
F test/insert.test 4e3f0de67aac3c5be1f4aaedbcea11638f1b5cdc9a3115be14d19aa9db7623c6
|
||||
F test/insert2.test 4d14b8f1b810a41995f6286b64a6943215d52208
|
||||
F test/insert3.test 1b7db95a03ad9c5013fdf7d6722b6cd66ee55e30
|
||||
F test/insert4.test fb9e0f752c75f453555990250b449f6d123ae6a3ebf054d14e4470de4498dce3
|
||||
F test/insert4.test 59cb99521be01a5aefc9be8e8b5a51ee7f3944781d4d7f6201b9f774fcd51662
|
||||
F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6
|
||||
F test/insertfault.test ac63d14ea3b49c573673a572f4014b9117383a03e497c58f308b5c776e4a7f74
|
||||
F test/instr.test 107df2b9b74a4b59315916b575590a08f2a714de0754abe541f10a0971d0a2a4
|
||||
@@ -1101,13 +1103,13 @@ F test/ioerr3.test d3cec5e1a11ad6d27527d0d38573fbff14c71bdd
|
||||
F test/ioerr4.test f130fe9e71008577b342b8874d52984bd04ede2c
|
||||
F test/ioerr5.test 2edfa4fb0f896f733071303b42224df8bedd9da4
|
||||
F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b
|
||||
F test/istrue.test 06f92ea38750fa74df7dbbe6920205251c2310861fbbe23a3adfa918a2e2ba74
|
||||
F test/join.test bca044589e94bb466e4c1e91fb6fecdc3f3326ca6b3f590f555f1958156eb321
|
||||
F test/join2.test 7d24d095ab88d3910228d53a3b548b7baf2e0e7d8aac6731a273e300e1b34b61
|
||||
F test/istrue.test 9619a2d77580f676048aaff7a16a0bcfea2b96c6c660dfaded2e53c873418899
|
||||
F test/join.test 25da4f53523a4aa17c893134b47fba6aa4799bb33350517b157785878290e238
|
||||
F test/join2.test 21fc30e54ab35ed66bf51b89cec18729205497f5cc43c83bc042f96a73721593
|
||||
F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0
|
||||
F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
|
||||
F test/join5.test 3a96dc62f0b45402d7207e22d1993fe0c2fce1c57644a11439891dd62b990eb7
|
||||
F test/join6.test cfe6503791ceb0cbb509966740286ec423cbf10b
|
||||
F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c
|
||||
F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497
|
||||
F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4
|
||||
F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e
|
||||
@@ -1207,7 +1209,7 @@ F test/notify1.test 669b2b743618efdc18ca4b02f45423d5d2304abf
|
||||
F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161
|
||||
F test/notify3.test 10ff25cde502e72a92053a2f215d64bece4ef934
|
||||
F test/notnull.test a37b663d5bb728d66fc182016613fb8e4a0a4bbf3d75b8876a7527f7d4ed3f18
|
||||
F test/null.test 0dcce4f04284ec66108c503327ad6d224c0752b3
|
||||
F test/null.test b7ff206a1c60fe01aa2abd33ef9ea83c93727d993ca8a613de86e925c9f2bc6f
|
||||
F test/nulls1.test 82c5bc33148405f21205865abf13c786084438d573a4ac4e87e11b6091cde526
|
||||
F test/numcast.test 5d126f7f581432e86a90d1e35cac625164aec4a1
|
||||
F test/numindex1.test 20a5450d4b056e48cd5db30e659f13347a099823
|
||||
@@ -1230,7 +1232,7 @@ F test/oserror.test 1fc9746b83d778e70d115049747ba19c7fba154afce7cc165b09feb6ca6a
|
||||
F test/ossfuzz.c 9636dad2092a05a32110df0ca06713038dd0c43dd89a77dabe4b8b0d71096715
|
||||
F test/ossshell.c f125c5bd16e537a2549aa579b328dd1c59905e7ab1338dfc210e755bb7b69f17
|
||||
F test/ovfl.test 199c482696defceacee8c8e0e0ef36da62726b2f
|
||||
F test/pager1.test 4fba160bf450cea19f6bf1d6483ef467545bac6405570e176c83c2c4b5d6d0d5
|
||||
F test/pager1.test 293c7ad1f19a07e548179b97534c6588249d4e40058b378ea26e75cc84d936f5
|
||||
F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71
|
||||
F test/pager3.test 4e9a83d6ca0838d7c602c9eb93d1357562d9059c1e02ffb138a8271020838370
|
||||
F test/pager4.test a122e9e6925d5b23b31e3dfef8c6a44bbf19590e
|
||||
@@ -1262,7 +1264,7 @@ F test/quick.test 1681febc928d686362d50057c642f77a02c62e57
|
||||
F test/quota-glob.test 32901e9eed6705d68ca3faee2a06b73b57cb3c26
|
||||
F test/quota.test bfb269ce81ea52f593f9648316cd5013d766dd2a
|
||||
F test/quota2.test 7dc12e08b11cbc4c16c9ba2aa2e040ea8d8ab4b8
|
||||
F test/quote.test 626149eda89ee64d81a3790de370f9f0211921b11568a49c28c861f394330508
|
||||
F test/quote.test 3f9238ab0e1db70dea89af9afa5859dbd759b0ce0a63da67d547553e2c316475
|
||||
F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459
|
||||
F test/randexpr1.test eda062a97e60f9c38ae8d806b03b0ddf23d796df
|
||||
F test/rbu.test 168573d353cd0fd10196b87b0caa322c144ef736
|
||||
@@ -1272,7 +1274,7 @@ F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8
|
||||
F test/regexp2.test 40e894223b3d6672655481493f1be12012f2b33c
|
||||
F test/reindex.test cd9d6021729910ece82267b4f5e1b5ac2911a7566c43b43c176a6a4732e2118d
|
||||
F test/releasetest.tcl fb76d8fcc95ac29d6356cd9e52b726ab9e43a24082897618dfbcb7c2b0049153 x
|
||||
F test/releasetest_data.tcl 9919fc6ac5bc92f8878fecfd1840db15999f660a6c9f609240b41aa62b885c88
|
||||
F test/releasetest_data.tcl b9cb30360759b80d92d4ea86b84ebfd8035b97f9078a482deb3cf9d0b2442655
|
||||
F test/resetdb.test 8062cf10a09d8c048f8de7711e94571c38b38168db0e5877ba7561789e5eeb2b
|
||||
F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb
|
||||
F test/rollback.test 06680159bc6746d0f26276e339e3ae2f951c64812468308838e0a3362d911eaa
|
||||
@@ -1312,7 +1314,7 @@ F test/schema6.test e4bd1f23d368695eb9e7b51ef6e02ca0642ea2ab4a52579959826b5e7dce
|
||||
F test/schemafault.test 1936bceca55ac82c5efbcc9fc91a1933e45c8d1e1d106b9a7e56c972a5a2a51e
|
||||
F test/securedel.test 2f70b2449186a1921bd01ec9da407fbfa98c3a7a5521854c300c194b2ff09384
|
||||
F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5
|
||||
F test/select1.test 009a6d8eacd9684d046302b8d13b50846a87e39d6f08e92178aa13e95ea29a2d
|
||||
F test/select1.test 0ed936740777f52858b6607f39ffac4b2b63b8fc7edf3ab2ebad3c3553ceecee
|
||||
F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56
|
||||
F test/select3.test c49fbb758903f3718e2de5aa4655eda4838131cbea24a86db908f8b6889aa68c
|
||||
F test/select4.test e8a2502e3623f3058871030599a48abb35789d2244d5b380ecf3696873fdd4a4
|
||||
@@ -1344,7 +1346,7 @@ F test/sharedA.test 49d87ec54ab640fbbc3786ee3c01de94aaa482a3a9f834ad3fe92770eb69
|
||||
F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e
|
||||
F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939
|
||||
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
|
||||
F test/shell1.test 1305efc92f132a1fcf97c00ac02b1b192865b4d33d44cab499e0bdcff71ce045
|
||||
F test/shell1.test 161353b1d52cfdc7772ebf03f34cc11384f7d8621ae3013394adcddc5357bace
|
||||
F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b
|
||||
F test/shell3.test ac8c2b744014c3e9a0e26bfd829ab65f00923dc1a91ffd044863e9423cc91494
|
||||
F test/shell4.test 1c6aef11daaa2d6830acaba3ac9cbec93fbc1c3d5530743a637f39b3987d08ce
|
||||
@@ -1360,7 +1362,7 @@ F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329
|
||||
F test/skipscan1.test ed524bc86f27646b3a297f45d6557b55db338977b6838f8064b196b35848b31b
|
||||
F test/skipscan2.test 3eb703ce794f139e7b83567911046298bcde29606116727f9b700ce34f559d2d
|
||||
F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5
|
||||
F test/skipscan5.test 67817a4b6857c47e0e33ba3e506da6f23ef68de2
|
||||
F test/skipscan5.test 980875ad45d8aacfe7bdec7c288343520cd1d14e84befdcfe50c785f9e6c8709
|
||||
F test/skipscan6.test 0b4cd1b4ac9f84d91454df513c99a4932fa07e8f27b8049bea605068b3e34ac7
|
||||
F test/snapshot.test a504f2e7009f512ef66c719f0ea1c55a556bdaf1e1312c80a04d46fc1a3e9632
|
||||
F test/snapshot2.test 8d6ff5dd9cc503f6e12d408a30409c3f9c653507b24408d9cd7195931c89bc54
|
||||
@@ -1385,7 +1387,7 @@ F test/speed3.test 694affeb9100526007436334cf7d08f3d74b85ef
|
||||
F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715
|
||||
F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
|
||||
F test/speed4p.test 377a0c48e5a92e0b11c1c5ebb1bc9d83a7312c922bc0cb05970ef5d6a96d1f0c
|
||||
F test/speedtest1.c ac0e6ebadb97b54b7ac45288d1beea633a219d5fb98aa3395cb8364c31c985cb
|
||||
F test/speedtest1.c 6f74bbfd6b78c8cf3aa9fc4d2cd3e261322bb140f42fee34df909c76b50fff53
|
||||
F test/spellfix.test 951a6405d49d1a23d6b78027d3877b4a33eeb8221dcab5704b499755bb4f552e
|
||||
F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3
|
||||
F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33
|
||||
@@ -1437,7 +1439,7 @@ F test/thread2.test f35d2106452b77523b3a2b7d1dcde2e5ee8f9e46
|
||||
F test/thread_common.tcl 334639cadcb9f912bf82aa73f49efd5282e6cadd
|
||||
F test/threadtest1.c 6029d9c5567db28e6dc908a0c63099c3ba6c383b
|
||||
F test/threadtest2.c a70a8e94bef23339d34226eb9521015ef99f4df8
|
||||
F test/threadtest3.c 38a612ea62854349ed66372f330a40d73c5cf956
|
||||
F test/threadtest3.c e63013af10cf236c7610eb06d33bde08c861806dc64be811940ff4d9ddd34a4f
|
||||
F test/threadtest4.c c1e67136ceb6c7ec8184e56ac61db28f96bd2925
|
||||
F test/time-wordcount.sh 8e0b0f8109367827ad5d58f5cc849705731e4b90
|
||||
F test/tkt-02a8e81d44.test 6c80d9c7514e2a42d4918bf87bf6bc54f379110c
|
||||
@@ -1588,7 +1590,7 @@ F test/tpch01.test 7c4eb8cdd79c568f46d344b3e789c9fdb8a766d112871352704861f3fca32
|
||||
F test/trace.test a659a9862957f4789e37a92b3bf6d2caf5c86b02cdeefc41e850ae53acf6992a
|
||||
F test/trace2.test f5cb67ad3bc09e0c58e8cca78dfd0b5639259983
|
||||
F test/trace3.test 1dff966888773ff1bfea01c080caf15417892b3f998408fe920c4791f7337144
|
||||
F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6
|
||||
F test/trans.test 45f6f9ab6f66a7b5744f1caac06b558f95da62501916906cf55586a896f9f439
|
||||
F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76
|
||||
F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94
|
||||
F test/transitive1.test 293300f46916569f08875cdb2fe2134be2c27677
|
||||
@@ -1613,6 +1615,7 @@ F test/trustschema1.test 4e970aef0bfe0cee139703cc7209d0e0f07725d999b180ba50770f4
|
||||
F test/tt3_checkpoint.c 9e75cf7c1c364f52e1c47fd0f14c4340a9db0fe1
|
||||
F test/tt3_index.c 39eec10a35f57672225be4d182862152896dee4a
|
||||
F test/tt3_lookaside1.c 0377e202c3c2a50d688cb65ba203afeda6fafeb9
|
||||
F test/tt3_shared.c b37d22defc944a2ac4c91c927fd06c1d48cd51e2ce9d004fe868625bd2399f93
|
||||
F test/tt3_stress.c f9a769ca8b026ecc76ee93ca8c9700a5619f8e51c581107c4053ba6ac97f616f
|
||||
F test/tt3_vacuum.c 1753f45917699c9c1f66b64c717a717c9379f776
|
||||
F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff
|
||||
@@ -1649,7 +1652,7 @@ F test/vacuum5.test 263b144d537e92ad8e9ca8a73cc6e1583f41cfd0dda9432b87f7806174a2
|
||||
F test/vacuummem.test 7b42abb3208bd82dd23a7536588396f295a314f2
|
||||
F test/varint.test bbce22cda8fc4d135bcc2b589574be8410614e62
|
||||
F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
|
||||
F test/view.test 10ea54300a097d7c0337fd104abffe4a4786d1598b94017a37efe0e0d3e04dd5
|
||||
F test/view.test fd48eddb32a35a98c3de70062ebac66ebf4a2bbfc75a1cc1109159ef8bfc47a9
|
||||
F test/vtab1.test c5d9e90ed02bcacd776dcbb7360199d290f7f53c26b484ddece543060c54319f
|
||||
F test/vtab2.test 14d4ab26cee13ba6cf5c5601b158e4f57552d3b055cdd9406cf7f711e9c84082
|
||||
F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e
|
||||
@@ -1667,7 +1670,7 @@ F test/vtabE.test 2a143fe75a11275781d1fd1988d86b66a3f69cb98f4add62e3da8fd0f637b4
|
||||
F test/vtabF.test 1918844c7c902f6a16c8dacf1ec8f84886d6e78b
|
||||
F test/vtabH.test 2efb5a24b0bb50796b21eca23032cfb77abfa4b0c03938e38ce5897abac404ca
|
||||
F test/vtabI.test 751b07636700dbdea328e4265b6077ccd6811a3f
|
||||
F test/vtabJ.test d7b73675708cf63cfcb9d443bb451fc01a028347275b7311e51f9fdf3ca6757f
|
||||
F test/vtabJ.test a6aef49d558af90fae10565b29501f82a95781cb4f797f2d13e2d19f9b6bc77b
|
||||
F test/vtab_alter.test 736e66fb5ec7b4fee58229aa3ada2f27ec58bc58c00edae4836890c3784c6783
|
||||
F test/vtab_err.test dcc8b7b9cb67522b3fe7a272c73856829dae4ab7fdb30399aea1b6981bda2b65
|
||||
F test/vtab_shared.test 5253bff2355a9a3f014c15337da7e177ab0ef8ad
|
||||
@@ -1710,7 +1713,7 @@ F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2a
|
||||
F test/walvfs.test a2913001a83b19c1d20220e556cee14d87d47ecb6949b5e0a2e9e2590abecf1e
|
||||
F test/wapp.tcl b440cd8cf57953d3a49e7ee81e6a18f18efdaf113b69f7d8482b0710a64566ec
|
||||
F test/wapptest.tcl 899594e25684861d5b0c0880fb012364def50ef8097041b8ddf74be5ba7fa270 x
|
||||
F test/where.test f5e62453537e5b335b69f3b09f8a02ce3328289fad5d866e25371284b837d78d
|
||||
F test/where.test e713c0c64e3e6b062235e39a2f7e5508c517df16b63d69fd786e26bc7330b1c6
|
||||
F test/where2.test 478d2170637b9211f593120648858593bf2445a1
|
||||
F test/where3.test 2341a294e17193a6b1699ea7f192124a5286ca6acfcc3f4b06d16c931fbcda2c
|
||||
F test/where4.test 4a371bfcc607f41d233701bdec33ac2972908ba8
|
||||
@@ -1719,13 +1722,13 @@ F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b
|
||||
F test/where7.test 75722434c486ac9e74718caa6cce234f45ba34c0b6c0f9555b29eb8bb5f6ade1
|
||||
F test/where8.test 461ca40265ed996a6305da99bb024b0e41602bb586acf544c08f95922358e49f
|
||||
F test/where9.test 8e3e0ff42cc17156f52361a1c012281550d0d632912fec92d1d6df74db7a8e6d
|
||||
F test/whereA.test 6c6a420ca7d313242f9b1bd471dc80e4d0f8323700ba9c78df0bb843d4daa3b4
|
||||
F test/whereA.test 9d1077b117f1b68d5f739d94f36956c36cf995eb87bb19b77b2e81af020edd20
|
||||
F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5
|
||||
F test/whereC.test cae295158703cb3fc23bf1a108a9ab730efff0f6
|
||||
F test/whereD.test c1c335e914e28b122e000e9310f02d2be83e1c9dbca2e29f46bd732703944d1b
|
||||
F test/whereE.test b3a055eef928c992b0a33198a7b8dc10eea5ad2f
|
||||
F test/whereF.test 3d9412b1199d3e2bed34fcb76b4c48d0bf4df95d27e3f8dd27b6f8b4716d0d89
|
||||
F test/whereG.test 9363b2a97d914cb1b81aff5069ef0cf2a071a67e2b604eac6fe9c0114017d9aa
|
||||
F test/whereG.test 77127a4d214bb21da3b5c695cf4106cd9e418c60d9c24471ba55d3772067cd35
|
||||
F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2
|
||||
F test/whereI.test a2874062140ed4aba9ffae76e6190a3df6fc73d1373fdfa8fd632945082a5364
|
||||
F test/whereJ.test 88287550f6ee604422403b053455b1ad894eeaa5c35d348532dfa1439286cb9a
|
||||
@@ -1758,14 +1761,15 @@ F test/windowB.test 7a983ea1cc1cf72be7f378e4b32f6cb2d73014c5cd8b25aaee825164cd42
|
||||
F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387019e0
|
||||
F test/windowerr.test a8b752402109c15aa1c5efe1b93ccb0ce1ef84fa964ae1cd6684dd0b3cc1819b
|
||||
F test/windowfault.test 72375ae71031eabf96bc88d0af128c8628a091ddc99b5a394e848b3df5fc17ad
|
||||
F test/with1.test 584580a5ae79868a91873863f8cb2d00040006dc1e4c332ef1d8642f2815dc6e
|
||||
F test/with1.test 780be387f01e290e768bdfd1827280f9e37ba37223eb4736aba386864fac5a94
|
||||
F test/with2.test e0030e2f0267a910d6c0e4f46f2dfe941c1cc0d4f659ba69b3597728e7e8f1ab
|
||||
F test/with3.test 13b3336739da648a9e4dfa11bb04e73a920c97620041007c5f75d5d14084c346
|
||||
F test/with3.test a261f0ea225c4af0ce6447f1157bb603959b2a665f14a03951c2883d2ef1c0f0
|
||||
F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f198205
|
||||
F test/with5.test 6248213c41fab36290b5b73aa3f937309dfba337004d9d8434c3fabc8c7d4be8
|
||||
F test/withM.test 693b61765f2b387b5e3e24a4536e2e82de15ff64
|
||||
F test/without_rowid1.test 9cfb83705c506e3849fa7efc88a3c9a15f9a50bf9b1516b41757a7cef9bba8c3
|
||||
F test/without_rowid1.test e4034c0849ccc2e8bb749c69f15bd69bb9fcf8fe77e8d17ce02369604242fe83
|
||||
F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99
|
||||
F test/without_rowid3.test 96426a6c9a2a5cf62bbe55ea1ad038eaaf4bf743f40a1ad517233b8e5a3d4339
|
||||
F test/without_rowid3.test 39ab0dd773eaa62e59b17093f875327630f54c4145458f6d2b053d68d4b2f67b
|
||||
F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a
|
||||
F test/without_rowid5.test 89b1c587bd92a0590e440da33e7666bf4891572a
|
||||
F test/without_rowid6.test 8463b20098e9f75a501a9f17dfb42fffc79068eac0b2775fe56ef2281d2df45e
|
||||
@@ -1778,7 +1782,7 @@ F test/zipfile.test 429cb81c518487fa1b644b6b04b6e9af704a4fa767bd1a110204c5f03b2e
|
||||
F test/zipfile2.test 9903388a602a3834189857a985106ff95c3bba6a3969e0134127df991889db5d
|
||||
F test/zipfilefault.test 44d4d7a7f7cca7521d569d7f71026b241d65a6b1757aa409c1a168827edbbc2c
|
||||
F tool/GetFile.cs 47852aa0d806fe47ed1ac5138bdce7f000fe87aaa7f28107d0cb1e26682aeb44
|
||||
F tool/GetTclKit.bat 8995df40c4209808b31f24de0b58f90930239a234f7591e3675d45bfbb990c5d
|
||||
F tool/GetTclKit.bat e95747c0f7a9fe279a9979178b71f6431a21f945b390fc3120244897ff3f5135
|
||||
F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91
|
||||
F tool/build-all-msvc.bat c12328d06c45fec8baada5949e3d5af54bf8c887 x
|
||||
F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367
|
||||
@@ -1798,8 +1802,8 @@ F tool/genfkey.test b6afd7b825d797a1e1274f519ab5695373552ecad5cd373530c63533638a
|
||||
F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
|
||||
F tool/index_usage.c f62a0c701b2c7ff2f3e21d206f093c123f222dbf07136a10ffd1ca15a5c706c5
|
||||
F tool/kvtest-speed.sh 4761a9c4b3530907562314d7757995787f7aef8f
|
||||
F tool/lemon.c 600a58b9d1b8ec5419373982428e927ca208826edacb91ca42ab94514d006039
|
||||
F tool/lempar.c e8899b28488f060d0ff931539ea6311b16b22dce068c086c788a06d5e8d01ab7
|
||||
F tool/lemon.c 70eedc31614a58fe31a71025c17ebd1502a6ce9cfef0ed5e33acb0b5b737b291
|
||||
F tool/lempar.c 0e1d5eeb9736108d3dba782a9dd56f4e7cb69006b6ee181308b7ebfb15313a12
|
||||
F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9
|
||||
F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862
|
||||
F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca
|
||||
@@ -1817,7 +1821,7 @@ F tool/mkshellc.tcl 70a9978e363b0f3280ca9ce1c46d72563ff479c1930a12a7375e3881b732
|
||||
F tool/mksourceid.c 36aa8020014aed0836fd13c51d6dc9219b0df1761d6b5f58ff5b616211b079b9
|
||||
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
|
||||
F tool/mksqlite3c-noext.tcl 4f7cfef5152b0c91920355cbfc1d608a4ad242cb819f1aea07f6d0274f584a7f
|
||||
F tool/mksqlite3c.tcl f4ef476510eca4124c874a72029f1e01bc54a896b1724e8f9eef0d8bfae0e84c
|
||||
F tool/mksqlite3c.tcl 00c4c0382eb000153182da2bee2547ca05554eeeed10177efe5894c54e4e6d4d
|
||||
F tool/mksqlite3h.tcl 1f5e4a1dbbbc43c83cc6e74fe32c6c620502240b66c7c0f33a51378e78fc4edf
|
||||
F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b
|
||||
F tool/mkvsix.tcl b9e0777a213c23156b6542842c238479e496ebf5
|
||||
@@ -1844,7 +1848,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||
F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd
|
||||
F tool/split-sqlite3c.tcl 3efcd4240b738f6bb2b5af0aea7e1e0ef9bc1c61654f645076cec883030b710c
|
||||
F tool/sqldiff.c 5046b8e227213ad016b336eb5a933e252e1f0fd1e07060c5755e259a30891287
|
||||
F tool/sqldiff.c a3362140091b6d8a0771a589aaff147c114b13eb915927390587f0fa78c2040d
|
||||
F tool/sqlite3_analyzer.c.in 7eeaae8b0d7577662acaabbb11107af0659d1b41bc1dfdd4d91422de27127968
|
||||
F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaaef898
|
||||
F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848
|
||||
@@ -1879,7 +1883,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P a495f60d315e34b1a1bc5fb1336e05047add52c8fb2710b577c97b10a5e734f6
|
||||
R 54b8b0b6f00b6cfab28e2e5a52014ff6
|
||||
U drh
|
||||
Z a854ac35ef1e1fa9d5bc731176f5cbf6
|
||||
P eb6e5fc1891be52acf378269405a99bab92b9bf501b7eba04eae07c851ed3027
|
||||
R 4d578fe854f29eb4522630d2ff1014ab
|
||||
T +closed *
|
||||
U shearer
|
||||
Z 451aeadec2dd7d0cf13fe0ace3038992
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
611b640442025e57b8e161f8ddac1f19bd3be9a3d5266f4cef287595c3ed9257
|
||||
ee9689ad2fadb3b9c11235312bfc32a1db294485b4503a07692bbdbce71e021d
|
||||
@@ -1772,6 +1772,7 @@ static int loadStatTbl(
|
||||
}
|
||||
pSpace = (tRowcnt*)&pIdx->aSample[nSample];
|
||||
pIdx->aAvgEq = pSpace; pSpace += nIdxCol;
|
||||
pIdx->pTable->tabFlags |= TF_HasStat4;
|
||||
for(i=0; i<nSample; i++){
|
||||
pIdx->aSample[i].anEq = pSpace; pSpace += nIdxCol;
|
||||
pIdx->aSample[i].anLt = pSpace; pSpace += nIdxCol;
|
||||
|
||||
+3
-1
@@ -293,7 +293,9 @@ static void detachFunc(
|
||||
sqlite3_snprintf(sizeof(zErr),zErr, "cannot detach database %s", zName);
|
||||
goto detach_error;
|
||||
}
|
||||
if( sqlite3BtreeIsInReadTrans(pDb->pBt) || sqlite3BtreeIsInBackup(pDb->pBt) ){
|
||||
if( sqlite3BtreeTxnState(pDb->pBt)!=SQLITE_TXN_NONE
|
||||
|| sqlite3BtreeIsInBackup(pDb->pBt)
|
||||
){
|
||||
sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName);
|
||||
goto detach_error;
|
||||
}
|
||||
|
||||
+4
-4
@@ -123,7 +123,7 @@ static int setDestPgsz(sqlite3_backup *p){
|
||||
** message in database handle db.
|
||||
*/
|
||||
static int checkReadTransaction(sqlite3 *db, Btree *p){
|
||||
if( sqlite3BtreeIsInReadTrans(p) ){
|
||||
if( sqlite3BtreeTxnState(p)!=SQLITE_TXN_NONE ){
|
||||
sqlite3ErrorWithMsg(db, SQLITE_ERROR, "destination database is in use");
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
@@ -354,7 +354,7 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
|
||||
** one now. If a transaction is opened here, then it will be closed
|
||||
** before this function exits.
|
||||
*/
|
||||
if( rc==SQLITE_OK && 0==sqlite3BtreeIsInReadTrans(p->pSrc) ){
|
||||
if( rc==SQLITE_OK && SQLITE_TXN_NONE==sqlite3BtreeTxnState(p->pSrc) ){
|
||||
rc = sqlite3BtreeBeginTrans(p->pSrc, 0, 0);
|
||||
bCloseTrans = 1;
|
||||
}
|
||||
@@ -726,7 +726,7 @@ int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){
|
||||
sqlite3BtreeEnter(pTo);
|
||||
sqlite3BtreeEnter(pFrom);
|
||||
|
||||
assert( sqlite3BtreeIsInTrans(pTo) );
|
||||
assert( sqlite3BtreeTxnState(pTo)==SQLITE_TXN_WRITE );
|
||||
pFd = sqlite3PagerFile(sqlite3BtreePager(pTo));
|
||||
if( pFd->pMethods ){
|
||||
i64 nByte = sqlite3BtreeGetPageSize(pFrom)*(i64)sqlite3BtreeLastPage(pFrom);
|
||||
@@ -762,7 +762,7 @@ int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){
|
||||
sqlite3PagerClearCache(sqlite3BtreePager(b.pDest));
|
||||
}
|
||||
|
||||
assert( sqlite3BtreeIsInTrans(pTo)==0 );
|
||||
assert( sqlite3BtreeTxnState(pTo)!=SQLITE_TXN_WRITE );
|
||||
copy_finished:
|
||||
sqlite3BtreeLeave(pFrom);
|
||||
sqlite3BtreeLeave(pTo);
|
||||
|
||||
+23
-13
@@ -112,6 +112,17 @@ int sqlite3_enable_shared_cache(int enable){
|
||||
#define hasReadConflicts(a, b) 0
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
/*
|
||||
** Return an reset the seek counter for a Btree object.
|
||||
*/
|
||||
sqlite3_uint64 sqlite3BtreeSeekCount(Btree *pBt){
|
||||
u64 n = pBt->nSeek;
|
||||
pBt->nSeek = 0;
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Implementation of the SQLITE_CORRUPT_PAGE() macro. Takes a single
|
||||
** (MemPage*) as an argument. The (MemPage*) must not be NULL.
|
||||
@@ -2605,7 +2616,7 @@ btree_open_out:
|
||||
** do not change the pager-cache size.
|
||||
*/
|
||||
if( sqlite3BtreeSchema(p, 0, 0)==0 ){
|
||||
sqlite3PagerSetCachesize(p->pBt->pPager, SQLITE_DEFAULT_CACHE_SIZE);
|
||||
sqlite3BtreeSetCacheSize(p, SQLITE_DEFAULT_CACHE_SIZE);
|
||||
}
|
||||
|
||||
pFile = sqlite3PagerFile(pBt->pPager);
|
||||
@@ -5459,6 +5470,10 @@ int sqlite3BtreeMovetoUnpacked(
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
pCur->pBtree->nSeek++; /* Performance measurement during testing */
|
||||
#endif
|
||||
|
||||
if( pIdxKey ){
|
||||
xRecordCompare = sqlite3VdbeFindCompare(pIdxKey);
|
||||
pIdxKey->errCode = 0;
|
||||
@@ -5735,7 +5750,7 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){
|
||||
|
||||
pPage = pCur->pPage;
|
||||
idx = ++pCur->ix;
|
||||
if( !pPage->isInit ){
|
||||
if( !pPage->isInit || sqlite3FaultSim(412) ){
|
||||
/* The only known way for this to happen is for there to be a
|
||||
** recursive SQL function that does a DELETE operation as part of a
|
||||
** SELECT which deletes content out from under an active cursor
|
||||
@@ -10310,11 +10325,12 @@ const char *sqlite3BtreeGetJournalname(Btree *p){
|
||||
}
|
||||
|
||||
/*
|
||||
** Return non-zero if a transaction is active.
|
||||
** Return one of SQLITE_TXN_NONE, SQLITE_TXN_READ, or SQLITE_TXN_WRITE
|
||||
** to describe the current transaction state of Btree p.
|
||||
*/
|
||||
int sqlite3BtreeIsInTrans(Btree *p){
|
||||
int sqlite3BtreeTxnState(Btree *p){
|
||||
assert( p==0 || sqlite3_mutex_held(p->db->mutex) );
|
||||
return (p && (p->inTrans==TRANS_WRITE));
|
||||
return p ? p->inTrans : 0;
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_WAL
|
||||
@@ -10343,14 +10359,8 @@ int sqlite3BtreeCheckpoint(Btree *p, int eMode, int *pnLog, int *pnCkpt){
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Return non-zero if a read (or write) transaction is active.
|
||||
** Return true if there is currently a backup running on Btree p.
|
||||
*/
|
||||
int sqlite3BtreeIsInReadTrans(Btree *p){
|
||||
assert( p );
|
||||
assert( sqlite3_mutex_held(p->db->mutex) );
|
||||
return p->inTrans!=TRANS_NONE;
|
||||
}
|
||||
|
||||
int sqlite3BtreeIsInBackup(Btree *p){
|
||||
assert( p );
|
||||
assert( sqlite3_mutex_held(p->db->mutex) );
|
||||
@@ -10532,7 +10542,7 @@ int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){
|
||||
|
||||
/*
|
||||
** Return true if the cursor has a hint specified. This routine is
|
||||
** only used from within assert() statements
|
||||
** only used from within or around assert() statements
|
||||
*/
|
||||
int sqlite3BtreeCursorHasHint(BtCursor *pCsr, unsigned int mask){
|
||||
return (pCsr->hints & mask)!=0;
|
||||
|
||||
+348
-168
@@ -9,17 +9,99 @@
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This header file defines the interface that the sqlite B-Tree file
|
||||
** subsystem. See comments in the source code for a detailed description
|
||||
** of what each interface routine does.
|
||||
** This header file defines the interface to the sqlite B-Tree storage
|
||||
** subsystem. All SQLite database operations become calls to the B-Tree
|
||||
** storage layer. The B-Tree layer requires a key-value store underneath
|
||||
** that is capable of MVCC - that is, transaction commit and rollback,
|
||||
** locking and concurrent access. See comments in btree.c for a detailed
|
||||
** description of each interface routine.
|
||||
**
|
||||
** The btree module organises an SQL database of tables and rows into
|
||||
** multiple key-value pair stores, which in turn are represented as
|
||||
** fixed-size pages in the memory-based page cache. The BTree functions
|
||||
** operate on pages in the page cache. A separate B-tree is used for each
|
||||
** table and each index in the database. Databases are stored in an on-disk
|
||||
** Database Image, which the B-Tree module knows nothing about except for
|
||||
** opening and closing.
|
||||
**
|
||||
** The architecture is described at https://www.sqlite.org/arch.html .
|
||||
**
|
||||
** A Btree record is also called a payload in SQLite source. A Btree
|
||||
** record for table data contains only two fields: the unique key value
|
||||
** ROWID, and the table row data. A Btree record for an index btree or
|
||||
** a WITHOUT ROWID table contain an arbitary key and no (uninitialised) data.
|
||||
** Btree pages are a fixed size. There will usually be multiple payloads
|
||||
** per page, but large payloads (eg BLOB data) may spill over to multiple
|
||||
** pages.
|
||||
**
|
||||
** Functions in this header file are grouped according to their logical task:
|
||||
**
|
||||
** Opening and Closing Database Connections
|
||||
**
|
||||
** Database Image Configuration and Querying
|
||||
**
|
||||
** Btree Connection Configuration and Querying
|
||||
**
|
||||
** Mutex Function Wrappers
|
||||
**
|
||||
** Transaction and Savepoint Functions
|
||||
**
|
||||
** Cursors and Cursor Functions
|
||||
**
|
||||
** Record and Payload Handling Functions
|
||||
**
|
||||
** Table Functions
|
||||
**
|
||||
** Reading and Writing Metadata
|
||||
**
|
||||
*/
|
||||
|
||||
#ifndef SQLITE_BTREE_H
|
||||
#define SQLITE_BTREE_H
|
||||
|
||||
/* TODO: This definition is just included so other modules compile. It
|
||||
** needs to be revisited.
|
||||
/*
|
||||
** Forward declarations of structure
|
||||
*/
|
||||
typedef struct Btree Btree;
|
||||
typedef struct BtCursor BtCursor;
|
||||
typedef struct BtShared BtShared;
|
||||
typedef struct BtreePayload BtreePayload;
|
||||
|
||||
/*
|
||||
********************************************
|
||||
* Opening and Closing Database Connections
|
||||
********************************************
|
||||
*/
|
||||
|
||||
int sqlite3BtreeOpen(
|
||||
sqlite3_vfs *pVfs, /* VFS to use with this b-tree */
|
||||
const char *zFilename, /* Name of database file to open */
|
||||
sqlite3 *db, /* Associated database connection */
|
||||
Btree **ppBtree, /* Return open Btree* here */
|
||||
int flags, /* Flags */
|
||||
int vfsFlags /* Flags passed through to VFS open */
|
||||
);
|
||||
|
||||
/* The flags parameter to sqlite3BtreeOpen can be the bitwise OR of the
|
||||
** following values.
|
||||
**
|
||||
** NOTE: These values must match the corresponding PAGER_ values in
|
||||
** pager.h.
|
||||
*/
|
||||
|
||||
#define BTREE_OMIT_JOURNAL 1 /* No create/use journal in temp databases */
|
||||
#define BTREE_MEMORY 2 /* This is an in-memory DB */
|
||||
#define BTREE_SINGLE 4 /* The file contains at most 1 b-tree */
|
||||
#define BTREE_UNORDERED 8 /* Use of a hash implementation is OK */
|
||||
/* Only a BTREE_SINGLE can be BTREE_UNORDERED */
|
||||
|
||||
int sqlite3BtreeClose(Btree*);
|
||||
|
||||
/*
|
||||
**********************************************
|
||||
** Database Image Configuration and Querying
|
||||
**********************************************
|
||||
*/
|
||||
#define SQLITE_N_BTREE_META 16
|
||||
|
||||
/*
|
||||
** If defined as non-zero, auto-vacuum is enabled by default. Otherwise
|
||||
@@ -33,124 +115,148 @@
|
||||
#define BTREE_AUTOVACUUM_FULL 1 /* Do full auto-vacuum */
|
||||
#define BTREE_AUTOVACUUM_INCR 2 /* Incremental vacuum */
|
||||
|
||||
/*
|
||||
** Forward declarations of structure
|
||||
*/
|
||||
typedef struct Btree Btree;
|
||||
typedef struct BtCursor BtCursor;
|
||||
typedef struct BtShared BtShared;
|
||||
typedef struct BtreePayload BtreePayload;
|
||||
int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix);
|
||||
int sqlite3BtreeGetPageSize(Btree*);
|
||||
|
||||
int sqlite3BtreeSetAutoVacuum(Btree *, int);
|
||||
int sqlite3BtreeGetAutoVacuum(Btree *);
|
||||
|
||||
int sqlite3BtreeOpen(
|
||||
sqlite3_vfs *pVfs, /* VFS to use with this b-tree */
|
||||
const char *zFilename, /* Name of database file to open */
|
||||
sqlite3 *db, /* Associated database connection */
|
||||
Btree **ppBtree, /* Return open Btree* here */
|
||||
int flags, /* Flags */
|
||||
int vfsFlags /* Flags passed through to VFS open */
|
||||
);
|
||||
|
||||
/* The flags parameter to sqlite3BtreeOpen can be the bitwise or of the
|
||||
** following values.
|
||||
**
|
||||
** NOTE: These values must match the corresponding PAGER_ values in
|
||||
** pager.h.
|
||||
*/
|
||||
#define BTREE_OMIT_JOURNAL 1 /* Do not create or use a rollback journal */
|
||||
#define BTREE_MEMORY 2 /* This is an in-memory DB */
|
||||
#define BTREE_SINGLE 4 /* The file contains at most 1 b-tree */
|
||||
#define BTREE_UNORDERED 8 /* Use of a hash implementation is OK */
|
||||
|
||||
int sqlite3BtreeClose(Btree*);
|
||||
int sqlite3BtreeSetCacheSize(Btree*,int);
|
||||
int sqlite3BtreeSetSpillSize(Btree*,int);
|
||||
#if SQLITE_MAX_MMAP_SIZE>0
|
||||
int sqlite3BtreeSetMmapLimit(Btree*,sqlite3_int64);
|
||||
#endif
|
||||
int sqlite3BtreeSetPagerFlags(Btree*,unsigned);
|
||||
int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix);
|
||||
int sqlite3BtreeGetPageSize(Btree*);
|
||||
Pgno sqlite3BtreeMaxPageCount(Btree*,Pgno);
|
||||
Pgno sqlite3BtreeLastPage(Btree*);
|
||||
int sqlite3BtreeSecureDelete(Btree*,int);
|
||||
int sqlite3BtreeGetRequestedReserve(Btree*);
|
||||
int sqlite3BtreeGetReserveNoMutex(Btree *p);
|
||||
int sqlite3BtreeSetAutoVacuum(Btree *, int);
|
||||
int sqlite3BtreeGetAutoVacuum(Btree *);
|
||||
|
||||
/* Implements PRAGMA integrity_check on a Btree and its associated file.
|
||||
* Only called from vdbe.c/OP_IntegrityCk */
|
||||
char *sqlite3BtreeIntegrityCheck(sqlite3*,Btree*,Pgno*aRoot,int nRoot,int,int*);
|
||||
|
||||
/* A single step of an incremental vacuum. For PRAGMA incremental_vacuum(N) */
|
||||
/* Neither autovacuum mode nor the VACUUM SQLite command use this function. */
|
||||
int sqlite3BtreeIncrVacuum(Btree *);
|
||||
|
||||
/* Copy a complete Btree into another Btree, ie from one file into another */
|
||||
/* Used only in the case of a backup and vacuum operations */
|
||||
int sqlite3BtreeCopyFile(Btree *, Btree *);
|
||||
|
||||
|
||||
/*
|
||||
************************************************
|
||||
** Btree Connection Configuration and Querying
|
||||
************************************************
|
||||
*/
|
||||
|
||||
|
||||
int sqlite3BtreeSetCacheSize(Btree*,int);
|
||||
Pgno sqlite3BtreeMaxPageCount(Btree*,Pgno);
|
||||
Pgno sqlite3BtreeLastPage(Btree*);
|
||||
const char *sqlite3BtreeGetFilename(Btree *);
|
||||
const char *sqlite3BtreeGetJournalname(Btree *);
|
||||
|
||||
int sqlite3BtreeIsReadonly(Btree *pBt);
|
||||
|
||||
/* Estimate number of rows in table
|
||||
* called only by OP IsSmaller, from PRAGMA optimize
|
||||
*/
|
||||
i64 sqlite3BtreeRowCountEst(BtCursor*);
|
||||
|
||||
/* Return the pager associated with a BTree */
|
||||
struct Pager *sqlite3BtreePager(Btree*);
|
||||
|
||||
|
||||
/*
|
||||
****************************
|
||||
** Mutex Function Wrappers
|
||||
****************************
|
||||
**
|
||||
** Every lock applies to an entire BTree. These functions are
|
||||
** wrappers for the sqlite3_mutex* functions, which are called
|
||||
** outside btree.c
|
||||
*/
|
||||
|
||||
/*
|
||||
** If we are not using shared cache, then there is no need to
|
||||
** use mutexes to access the BtShared structures. So make the
|
||||
** Enter and Leave procedures no-ops.
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_SHARED_CACHE
|
||||
void sqlite3BtreeEnter(Btree*);
|
||||
void sqlite3BtreeEnterAll(sqlite3*);
|
||||
int sqlite3BtreeSharable(Btree*);
|
||||
void sqlite3BtreeEnterCursor(BtCursor*);
|
||||
int sqlite3BtreeConnectionCount(Btree*);
|
||||
#else
|
||||
# define sqlite3BtreeEnter(X)
|
||||
# define sqlite3BtreeEnterAll(X)
|
||||
# define sqlite3BtreeSharable(X) 0
|
||||
# define sqlite3BtreeEnterCursor(X)
|
||||
# define sqlite3BtreeConnectionCount(X) 1
|
||||
#endif
|
||||
|
||||
#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE
|
||||
void sqlite3BtreeLeave(Btree*);
|
||||
void sqlite3BtreeLeaveCursor(BtCursor*);
|
||||
void sqlite3BtreeLeaveAll(sqlite3*);
|
||||
#ifndef NDEBUG
|
||||
/* These routines are used inside assert() statements only. */
|
||||
int sqlite3BtreeHoldsMutex(Btree*);
|
||||
int sqlite3BtreeHoldsAllMutexes(sqlite3*);
|
||||
int sqlite3SchemaMutexHeld(sqlite3*,int,Schema*);
|
||||
#endif
|
||||
#else
|
||||
|
||||
# define sqlite3BtreeLeave(X)
|
||||
# define sqlite3BtreeLeaveCursor(X)
|
||||
# define sqlite3BtreeLeaveAll(X)
|
||||
|
||||
# define sqlite3BtreeHoldsMutex(X) 1
|
||||
# define sqlite3BtreeHoldsAllMutexes(X) 1
|
||||
# define sqlite3SchemaMutexHeld(X,Y,Z) 1
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
****************************************
|
||||
** Transaction and SavePoint Functions
|
||||
****************************************
|
||||
*/
|
||||
|
||||
int sqlite3BtreeBeginTrans(Btree*,int,int*);
|
||||
int sqlite3BtreeCommitPhaseOne(Btree*, const char*);
|
||||
int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster);
|
||||
int sqlite3BtreeCommitPhaseTwo(Btree*, int);
|
||||
int sqlite3BtreeCommit(Btree*);
|
||||
int sqlite3BtreeRollback(Btree*,int,int);
|
||||
int sqlite3BtreeBeginStmt(Btree*,int);
|
||||
int sqlite3BtreeCreateTable(Btree*, Pgno*, int flags);
|
||||
int sqlite3BtreeIsInTrans(Btree*);
|
||||
int sqlite3BtreeIsInReadTrans(Btree*);
|
||||
int sqlite3BtreeTxnState(Btree*);
|
||||
int sqlite3BtreeIsInBackup(Btree*);
|
||||
void *sqlite3BtreeSchema(Btree *, int, void(*)(void *));
|
||||
int sqlite3BtreeSchemaLocked(Btree *pBtree);
|
||||
#ifndef SQLITE_OMIT_SHARED_CACHE
|
||||
int sqlite3BtreeLockTable(Btree *pBtree, int iTab, u8 isWriteLock);
|
||||
#endif
|
||||
|
||||
/* Savepoints are named, nestable SQL transactions mostly implemented */
|
||||
/* in vdbe.c and pager.c See https://sqlite.org/lang_savepoint.html */
|
||||
int sqlite3BtreeSavepoint(Btree *, int, int);
|
||||
|
||||
const char *sqlite3BtreeGetFilename(Btree *);
|
||||
const char *sqlite3BtreeGetJournalname(Btree *);
|
||||
int sqlite3BtreeCopyFile(Btree *, Btree *);
|
||||
/* A statement sub-transaction is an internal-only transaction used */
|
||||
/* only by OP_Transaction, see comments in vdbe.c. A statement */
|
||||
/* sub-transaction is implemented as an anonymous savepoint. */
|
||||
int sqlite3BtreeBeginStmt(Btree*,int);
|
||||
|
||||
int sqlite3BtreeIncrVacuum(Btree *);
|
||||
/* A checkpoint refers to only to WAL. See https://sqlite.org/wal.html#ckpt */
|
||||
#ifndef SQLITE_OMIT_WAL
|
||||
int sqlite3BtreeCheckpoint(Btree*, int, int *, int *);
|
||||
#endif
|
||||
|
||||
/* The flags parameter to sqlite3BtreeCreateTable can be the bitwise OR
|
||||
** of the flags shown below.
|
||||
**
|
||||
** Every SQLite table must have either BTREE_INTKEY or BTREE_BLOBKEY set.
|
||||
** With BTREE_INTKEY, the table key is a 64-bit integer and arbitrary data
|
||||
** is stored in the leaves. (BTREE_INTKEY is used for SQL tables.) With
|
||||
** BTREE_BLOBKEY, the key is an arbitrary BLOB and no content is stored
|
||||
** anywhere - the key is the content. (BTREE_BLOBKEY is used for SQL
|
||||
** indices.)
|
||||
*/
|
||||
#define BTREE_INTKEY 1 /* Table has only 64-bit signed integer keys */
|
||||
#define BTREE_BLOBKEY 2 /* Table has keys only - no data */
|
||||
|
||||
int sqlite3BtreeDropTable(Btree*, int, int*);
|
||||
int sqlite3BtreeClearTable(Btree*, int, int*);
|
||||
int sqlite3BtreeClearTableOfCursor(BtCursor*);
|
||||
/* Set all relevant cursors to error state on transaction rollback */
|
||||
int sqlite3BtreeTripAllCursors(Btree*, int, int);
|
||||
|
||||
void sqlite3BtreeGetMeta(Btree *pBtree, int idx, u32 *pValue);
|
||||
int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value);
|
||||
|
||||
int sqlite3BtreeNewDb(Btree *p);
|
||||
|
||||
/*
|
||||
** The second parameter to sqlite3BtreeGetMeta or sqlite3BtreeUpdateMeta
|
||||
** should be one of the following values. The integer values are assigned
|
||||
** to constants so that the offset of the corresponding field in an
|
||||
** SQLite database header may be found using the following formula:
|
||||
*********************************
|
||||
** Cursors and Cursor functions
|
||||
*********************************
|
||||
**
|
||||
** offset = 36 + (idx * 4)
|
||||
**
|
||||
** For example, the free-page-count field is located at byte offset 36 of
|
||||
** the database file header. The incr-vacuum-flag field is located at
|
||||
** byte offset 64 (== 36+4*7).
|
||||
**
|
||||
** The BTREE_DATA_VERSION value is not really a value stored in the header.
|
||||
** It is a read-only number computed by the pager. But we merge it with
|
||||
** the header value access routines since its access pattern is the same.
|
||||
** Call it a "virtual meta value".
|
||||
*/
|
||||
#define BTREE_FREE_PAGE_COUNT 0
|
||||
#define BTREE_SCHEMA_VERSION 1
|
||||
#define BTREE_FILE_FORMAT 2
|
||||
#define BTREE_DEFAULT_CACHE_SIZE 3
|
||||
#define BTREE_LARGEST_ROOT_PAGE 4
|
||||
#define BTREE_TEXT_ENCODING 5
|
||||
#define BTREE_USER_VERSION 6
|
||||
#define BTREE_INCR_VACUUM 7
|
||||
#define BTREE_APPLICATION_ID 8
|
||||
#define BTREE_DATA_VERSION 15 /* A virtual meta-value */
|
||||
|
||||
/*
|
||||
** Kinds of hints that can be passed into the sqlite3BtreeCursorHint()
|
||||
@@ -225,12 +331,28 @@ int sqlite3BtreeNewDb(Btree *p);
|
||||
|
||||
int sqlite3BtreeCursor(
|
||||
Btree*, /* BTree containing table to open */
|
||||
Pgno iTable, /* Index of root page */
|
||||
Pgno iTable, /* Index of root page */
|
||||
int wrFlag, /* 1 for writing. 0 for read-only */
|
||||
struct KeyInfo*, /* First argument to compare function */
|
||||
BtCursor *pCursor /* Space to write cursor structure */
|
||||
);
|
||||
|
||||
/* True if hint specified, used in or around assert statements only */
|
||||
int sqlite3BtreeCursorHasHint(BtCursor*, unsigned int mask);
|
||||
|
||||
BtCursor *sqlite3BtreeFakeValidCursor(void);
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
sqlite3_uint64 sqlite3BtreeSeekCount(Btree*);
|
||||
#else
|
||||
# define sqlite3BtreeSeekCount(X) 0
|
||||
#endif
|
||||
|
||||
#ifndef NDEBUG
|
||||
int sqlite3BtreeCursorIsValid(BtCursor*);
|
||||
#endif
|
||||
int sqlite3BtreeCursorIsValidNN(BtCursor*);
|
||||
|
||||
int sqlite3BtreeCursorSize(void);
|
||||
void sqlite3BtreeCursorZero(BtCursor*);
|
||||
void sqlite3BtreeCursorHintFlags(BtCursor*, unsigned);
|
||||
@@ -238,7 +360,10 @@ void sqlite3BtreeCursorHintFlags(BtCursor*, unsigned);
|
||||
void sqlite3BtreeCursorHint(BtCursor*, int, ...);
|
||||
#endif
|
||||
|
||||
void sqlite3BtreeClearCursor(BtCursor *);
|
||||
int sqlite3BtreeCloseCursor(BtCursor*);
|
||||
|
||||
/* Cursor seek to a specified rowid in the Btree */
|
||||
int sqlite3BtreeMovetoUnpacked(
|
||||
BtCursor*,
|
||||
UnpackedRecord *pUnKey,
|
||||
@@ -246,9 +371,42 @@ int sqlite3BtreeMovetoUnpacked(
|
||||
int bias,
|
||||
int *pRes
|
||||
);
|
||||
int sqlite3BtreeCursorHasMoved(BtCursor*);
|
||||
int sqlite3BtreeCursorRestore(BtCursor*, int*);
|
||||
int sqlite3BtreeDelete(BtCursor*, u8 flags);
|
||||
|
||||
int sqlite3BtreeFirst(BtCursor*, int *pRes);
|
||||
int sqlite3BtreeLast(BtCursor*, int *pRes);
|
||||
int sqlite3BtreeNext(BtCursor*, int flags);
|
||||
int sqlite3BtreeEof(BtCursor*);
|
||||
int sqlite3BtreePrevious(BtCursor*, int flags);
|
||||
i64 sqlite3BtreeIntegerKey(BtCursor*);
|
||||
|
||||
int sqlite3BtreeCount(sqlite3*, BtCursor*, i64*);
|
||||
|
||||
|
||||
void *sqlite3BtreeSchema(Btree *, int, void(*)(void *));
|
||||
int sqlite3BtreeSchemaLocked(Btree *pBtree);
|
||||
#ifndef SQLITE_OMIT_SHARED_CACHE
|
||||
int sqlite3BtreeLockTable(Btree *pBtree, int iTab, u8 isWriteLock);
|
||||
#endif
|
||||
void sqlite3BtreeCursorPin(BtCursor*);
|
||||
void sqlite3BtreeCursorUnpin(BtCursor*);
|
||||
|
||||
int sqlite3BtreeCursorHasMoved(BtCursor*);
|
||||
int sqlite3BtreeCursorRestore(BtCursor*, int*);
|
||||
|
||||
#ifdef SQLITE_TEST
|
||||
int sqlite3BtreeCursorInfo(BtCursor*, int*, int);
|
||||
void sqlite3BtreeCursorList(Btree*);
|
||||
#endif
|
||||
|
||||
/*
|
||||
******************************************
|
||||
** Record and Payload handling functions
|
||||
******************************************
|
||||
**
|
||||
** A Btree record is a key-value pair consisting of a rowid key, and arbitary
|
||||
** data value. The record is also called a payload.
|
||||
**
|
||||
*/
|
||||
|
||||
/* Allowed flags for sqlite3BtreeDelete() and sqlite3BtreeInsert() */
|
||||
#define BTREE_SAVEPOSITION 0x02 /* Leave cursor pointing at NEXT or PREV */
|
||||
@@ -300,92 +458,114 @@ struct BtreePayload {
|
||||
|
||||
int sqlite3BtreeInsert(BtCursor*, const BtreePayload *pPayload,
|
||||
int flags, int seekResult);
|
||||
int sqlite3BtreeFirst(BtCursor*, int *pRes);
|
||||
int sqlite3BtreeLast(BtCursor*, int *pRes);
|
||||
int sqlite3BtreeNext(BtCursor*, int flags);
|
||||
int sqlite3BtreeEof(BtCursor*);
|
||||
int sqlite3BtreePrevious(BtCursor*, int flags);
|
||||
i64 sqlite3BtreeIntegerKey(BtCursor*);
|
||||
void sqlite3BtreeCursorPin(BtCursor*);
|
||||
void sqlite3BtreeCursorUnpin(BtCursor*);
|
||||
|
||||
int sqlite3BtreeDelete(BtCursor*, u8 flags);
|
||||
|
||||
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
|
||||
i64 sqlite3BtreeOffset(BtCursor*);
|
||||
#endif
|
||||
int sqlite3BtreePayload(BtCursor*, u32 offset, u32 amt, void*);
|
||||
const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt);
|
||||
u32 sqlite3BtreePayloadSize(BtCursor*);
|
||||
sqlite3_int64 sqlite3BtreeMaxRecordSize(BtCursor*);
|
||||
|
||||
char *sqlite3BtreeIntegrityCheck(sqlite3*,Btree*,Pgno*aRoot,int nRoot,int,int*);
|
||||
struct Pager *sqlite3BtreePager(Btree*);
|
||||
i64 sqlite3BtreeRowCountEst(BtCursor*);
|
||||
|
||||
/* These functions deal with arbitary-sized binary blobs in a Btree */
|
||||
#ifndef SQLITE_OMIT_INCRBLOB
|
||||
int sqlite3BtreePayloadChecked(BtCursor*, u32 offset, u32 amt, void*);
|
||||
int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*);
|
||||
void sqlite3BtreeIncrblobCursor(BtCursor *);
|
||||
#endif
|
||||
void sqlite3BtreeClearCursor(BtCursor *);
|
||||
int sqlite3BtreeSetVersion(Btree *pBt, int iVersion);
|
||||
int sqlite3BtreeCursorHasHint(BtCursor*, unsigned int mask);
|
||||
int sqlite3BtreeIsReadonly(Btree *pBt);
|
||||
int sqlite3HeaderSizeBtree(void);
|
||||
|
||||
#ifndef NDEBUG
|
||||
int sqlite3BtreeCursorIsValid(BtCursor*);
|
||||
#endif
|
||||
int sqlite3BtreeCursorIsValidNN(BtCursor*);
|
||||
|
||||
int sqlite3BtreeCount(sqlite3*, BtCursor*, i64*);
|
||||
|
||||
#ifdef SQLITE_TEST
|
||||
int sqlite3BtreeCursorInfo(BtCursor*, int*, int);
|
||||
void sqlite3BtreeCursorList(Btree*);
|
||||
#endif
|
||||
|
||||
#ifndef SQLITE_OMIT_WAL
|
||||
int sqlite3BtreeCheckpoint(Btree*, int, int *, int *);
|
||||
#endif
|
||||
|
||||
/*
|
||||
** If we are not using shared cache, then there is no need to
|
||||
** use mutexes to access the BtShared structures. So make the
|
||||
** Enter and Leave procedures no-ops.
|
||||
********************
|
||||
** Table functions
|
||||
********************
|
||||
**
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_SHARED_CACHE
|
||||
void sqlite3BtreeEnter(Btree*);
|
||||
void sqlite3BtreeEnterAll(sqlite3*);
|
||||
int sqlite3BtreeSharable(Btree*);
|
||||
void sqlite3BtreeEnterCursor(BtCursor*);
|
||||
int sqlite3BtreeConnectionCount(Btree*);
|
||||
#else
|
||||
# define sqlite3BtreeEnter(X)
|
||||
# define sqlite3BtreeEnterAll(X)
|
||||
# define sqlite3BtreeSharable(X) 0
|
||||
# define sqlite3BtreeEnterCursor(X)
|
||||
# define sqlite3BtreeConnectionCount(X) 1
|
||||
#endif
|
||||
|
||||
#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE
|
||||
void sqlite3BtreeLeave(Btree*);
|
||||
void sqlite3BtreeLeaveCursor(BtCursor*);
|
||||
void sqlite3BtreeLeaveAll(sqlite3*);
|
||||
#ifndef NDEBUG
|
||||
/* These routines are used inside assert() statements only. */
|
||||
int sqlite3BtreeHoldsMutex(Btree*);
|
||||
int sqlite3BtreeHoldsAllMutexes(sqlite3*);
|
||||
int sqlite3SchemaMutexHeld(sqlite3*,int,Schema*);
|
||||
#endif
|
||||
#else
|
||||
/* The flags parameter to sqlite3BtreeCreateTable can be the bitwise OR
|
||||
** of the flags shown below.
|
||||
**
|
||||
** Every SQLite table must have either BTREE_INTKEY or BTREE_BLOBKEY set.
|
||||
** With BTREE_INTKEY, the table key is a 64-bit integer and arbitrary data
|
||||
** is stored in the leaves. (BTREE_INTKEY is used for SQL tables.) With
|
||||
** BTREE_BLOBKEY, the key is an arbitrary BLOB and no content is stored
|
||||
** anywhere - the key is the content. (BTREE_BLOBKEY is used for SQL
|
||||
** indices.)
|
||||
*/
|
||||
|
||||
# define sqlite3BtreeLeave(X)
|
||||
# define sqlite3BtreeLeaveCursor(X)
|
||||
# define sqlite3BtreeLeaveAll(X)
|
||||
#define BTREE_INTKEY 1 /* Table has only 64-bit signed integer keys */
|
||||
#define BTREE_BLOBKEY 2 /* Table has keys only - no data */
|
||||
|
||||
# define sqlite3BtreeHoldsMutex(X) 1
|
||||
# define sqlite3BtreeHoldsAllMutexes(X) 1
|
||||
# define sqlite3SchemaMutexHeld(X,Y,Z) 1
|
||||
#endif
|
||||
int sqlite3BtreeDropTable(Btree*, int, int*);
|
||||
int sqlite3BtreeClearTable(Btree*, int, int*);
|
||||
int sqlite3BtreeClearTableOfCursor(BtCursor*);
|
||||
|
||||
|
||||
/*
|
||||
*********************************
|
||||
** Reading and Writing Metadata
|
||||
*********************************
|
||||
**
|
||||
** Note there is metadata which is not in the first database page
|
||||
** including (as below) some visible via the os.h API
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
** The second parameter to sqlite3BtreeGetMeta or sqlite3BtreeUpdateMeta
|
||||
** should be one of the following values. The integer values are assigned
|
||||
** to constants so that the offset of the corresponding field in an
|
||||
** SQLite database header may be found using the following formula:
|
||||
**
|
||||
** offset = 36 + (idx * 4)
|
||||
**
|
||||
** For example, the free-page-count field is located at byte offset 36 of
|
||||
** the database file header. The incr-vacuum-flag field is located at
|
||||
** byte offset 64 (== 36+4*7).
|
||||
**
|
||||
** The BTREE_DATA_VERSION value is not really a value stored in the header.
|
||||
** It is a read-only number computed by the pager. But we merge it with
|
||||
** the header value access routines since its access pattern is the same.
|
||||
** Call it a "virtual meta value".
|
||||
*/
|
||||
#define BTREE_FREE_PAGE_COUNT 0
|
||||
#define BTREE_SCHEMA_VERSION 1
|
||||
#define BTREE_FILE_FORMAT 2
|
||||
#define BTREE_DEFAULT_CACHE_SIZE 3
|
||||
#define BTREE_LARGEST_ROOT_PAGE 4
|
||||
#define BTREE_TEXT_ENCODING 5
|
||||
#define BTREE_USER_VERSION 6
|
||||
#define BTREE_INCR_VACUUM 7
|
||||
#define BTREE_APPLICATION_ID 8
|
||||
#define BTREE_DATA_VERSION 15 /* A virtual meta-value */
|
||||
|
||||
|
||||
/* Refers to the size of the per-page header, not per-database header */
|
||||
/* Used for configuring the size of the pages in the page cache */
|
||||
int sqlite3HeaderSizeBtree(void);
|
||||
|
||||
/* TODO: This definition is only used in asserts to determine whether
|
||||
* the metadata index (second parameter of Get/UpdateMeta functions)
|
||||
* is out of range. It is only included here so other modules compile. It
|
||||
* ** needs to be revisited.
|
||||
* */
|
||||
#define SQLITE_N_BTREE_META 16
|
||||
|
||||
void sqlite3BtreeGetMeta(Btree *pBtree, int idx, u32 *pValue);
|
||||
int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value);
|
||||
|
||||
/* This returns the size of the current database file, ie the same */
|
||||
/* result as sqlite3OsFileSize in os.h . */
|
||||
sqlite3_int64 sqlite3BtreeMaxRecordSize(BtCursor*);
|
||||
|
||||
/* Version number of the file format must be either 1 or 2 */
|
||||
/* 1=legacy, 2=WAL . Read and write versions set to same value */
|
||||
int sqlite3BtreeSetVersion(Btree *pBt, int iVersion);
|
||||
|
||||
/* Initialize the first page of the database file and return */
|
||||
int sqlite3BtreeNewDb(Btree *p);
|
||||
|
||||
|
||||
#endif /* SQLITE_BTREE_H */
|
||||
|
||||
@@ -353,6 +353,9 @@ struct Btree {
|
||||
u32 iDataVersion; /* Combines with pBt->pPager->iDataVersion */
|
||||
Btree *pNext; /* List of other sharable Btrees from the same db */
|
||||
Btree *pPrev; /* Back pointer of the same list */
|
||||
#ifdef SQLITE_DEBUG
|
||||
u64 nSeek; /* Calls to sqlite3BtreeMovetoUnpacked() */
|
||||
#endif
|
||||
#ifndef SQLITE_OMIT_SHARED_CACHE
|
||||
BtLock lock; /* Object used to lock page 1 */
|
||||
#endif
|
||||
@@ -364,11 +367,25 @@ struct Btree {
|
||||
** If the shared-data extension is enabled, there may be multiple users
|
||||
** of the Btree structure. At most one of these may open a write transaction,
|
||||
** but any number may have active read transactions.
|
||||
**
|
||||
** These values must match SQLITE_TXN_NONE, SQLITE_TXN_READ, and
|
||||
** SQLITE_TXN_WRITE
|
||||
*/
|
||||
#define TRANS_NONE 0
|
||||
#define TRANS_READ 1
|
||||
#define TRANS_WRITE 2
|
||||
|
||||
#if TRANS_NONE!=SQLITE_TXN_NONE
|
||||
# error wrong numeric code for no-transaction
|
||||
#endif
|
||||
#if TRANS_READ!=SQLITE_TXN_READ
|
||||
# error wrong numeric code for read-transaction
|
||||
#endif
|
||||
#if TRANS_WRITE!=SQLITE_TXN_WRITE
|
||||
# error wrong numeric code for write-transaction
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** An instance of this object represents a single database file.
|
||||
**
|
||||
|
||||
+48
-24
@@ -53,7 +53,7 @@ void sqlite3TableLock(
|
||||
u8 isWriteLock, /* True for a write lock */
|
||||
const char *zName /* Name of the table to be locked */
|
||||
){
|
||||
Parse *pToplevel = sqlite3ParseToplevel(pParse);
|
||||
Parse *pToplevel;
|
||||
int i;
|
||||
int nBytes;
|
||||
TableLock *p;
|
||||
@@ -61,6 +61,7 @@ void sqlite3TableLock(
|
||||
|
||||
if( iDb==1 ) return;
|
||||
if( !sqlite3BtreeSharable(pParse->db->aDb[iDb].pBt) ) return;
|
||||
pToplevel = sqlite3ParseToplevel(pParse);
|
||||
for(i=0; i<pToplevel->nTableLock; i++){
|
||||
p = &pToplevel->aTableLock[i];
|
||||
if( p->iDb==iDb && p->iTab==iTab ){
|
||||
@@ -90,10 +91,8 @@ void sqlite3TableLock(
|
||||
*/
|
||||
static void codeTableLocks(Parse *pParse){
|
||||
int i;
|
||||
Vdbe *pVdbe;
|
||||
|
||||
pVdbe = sqlite3GetVdbe(pParse);
|
||||
assert( pVdbe!=0 ); /* sqlite3GetVdbe cannot fail: VDBE already allocated */
|
||||
Vdbe *pVdbe = pParse->pVdbe;
|
||||
assert( pVdbe!=0 );
|
||||
|
||||
for(i=0; i<pParse->nTableLock; i++){
|
||||
TableLock *p = &pParse->aTableLock[i];
|
||||
@@ -1618,8 +1617,10 @@ primary_key_exit:
|
||||
** Add a new CHECK constraint to the table currently under construction.
|
||||
*/
|
||||
void sqlite3AddCheckConstraint(
|
||||
Parse *pParse, /* Parsing context */
|
||||
Expr *pCheckExpr /* The check expression */
|
||||
Parse *pParse, /* Parsing context */
|
||||
Expr *pCheckExpr, /* The check expression */
|
||||
const char *zStart, /* Opening "(" */
|
||||
const char *zEnd /* Closing ")" */
|
||||
){
|
||||
#ifndef SQLITE_OMIT_CHECK
|
||||
Table *pTab = pParse->pNewTable;
|
||||
@@ -1630,6 +1631,13 @@ void sqlite3AddCheckConstraint(
|
||||
pTab->pCheck = sqlite3ExprListAppend(pParse, pTab->pCheck, pCheckExpr);
|
||||
if( pParse->constraintName.n ){
|
||||
sqlite3ExprListSetName(pParse, pTab->pCheck, &pParse->constraintName, 1);
|
||||
}else{
|
||||
Token t;
|
||||
for(zStart++; sqlite3Isspace(zStart[0]); zStart++){}
|
||||
while( sqlite3Isspace(zEnd[-1]) ){ zEnd--; }
|
||||
t.z = zStart;
|
||||
t.n = (int)(zEnd - t.z);
|
||||
sqlite3ExprListSetName(pParse, pTab->pCheck, &t, 1);
|
||||
}
|
||||
}else
|
||||
#endif
|
||||
@@ -1648,7 +1656,7 @@ void sqlite3AddCollateType(Parse *pParse, Token *pToken){
|
||||
char *zColl; /* Dequoted name of collation sequence */
|
||||
sqlite3 *db;
|
||||
|
||||
if( (p = pParse->pNewTable)==0 ) return;
|
||||
if( (p = pParse->pNewTable)==0 || IN_RENAME_OBJECT ) return;
|
||||
i = p->nCol-1;
|
||||
db = pParse->db;
|
||||
zColl = sqlite3NameFromToken(db, pToken);
|
||||
@@ -1883,12 +1891,15 @@ static int resizeIndexObject(sqlite3 *db, Index *pIdx, int N){
|
||||
int nByte;
|
||||
if( pIdx->nColumn>=N ) return SQLITE_OK;
|
||||
assert( pIdx->isResized==0 );
|
||||
nByte = (sizeof(char*) + sizeof(i16) + 1)*N;
|
||||
nByte = (sizeof(char*) + sizeof(LogEst) + sizeof(i16) + 1)*N;
|
||||
zExtra = sqlite3DbMallocZero(db, nByte);
|
||||
if( zExtra==0 ) return SQLITE_NOMEM_BKPT;
|
||||
memcpy(zExtra, pIdx->azColl, sizeof(char*)*pIdx->nColumn);
|
||||
pIdx->azColl = (const char**)zExtra;
|
||||
zExtra += sizeof(char*)*N;
|
||||
memcpy(zExtra, pIdx->aiRowLogEst, sizeof(LogEst)*(pIdx->nKeyCol+1));
|
||||
pIdx->aiRowLogEst = (LogEst*)zExtra;
|
||||
zExtra += sizeof(LogEst)*N;
|
||||
memcpy(zExtra, pIdx->aiColumn, sizeof(i16)*pIdx->nColumn);
|
||||
pIdx->aiColumn = (i16*)zExtra;
|
||||
zExtra += sizeof(i16)*N;
|
||||
@@ -4449,7 +4460,7 @@ void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){
|
||||
assert(pList || pParse->db->mallocFailed );
|
||||
if( pList ){
|
||||
for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
|
||||
if( pItem->iCursor>=0 ) break;
|
||||
if( pItem->iCursor>=0 ) continue;
|
||||
pItem->iCursor = pParse->nTab++;
|
||||
if( pItem->pSelect ){
|
||||
sqlite3SrcListAssignCursors(pParse, pItem->pSelect->pSrc);
|
||||
@@ -4466,15 +4477,15 @@ void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){
|
||||
struct SrcList_item *pItem;
|
||||
if( pList==0 ) return;
|
||||
for(pItem=pList->a, i=0; i<pList->nSrc; i++, pItem++){
|
||||
sqlite3DbFree(db, pItem->zDatabase);
|
||||
if( pItem->zDatabase ) sqlite3DbFreeNN(db, pItem->zDatabase);
|
||||
sqlite3DbFree(db, pItem->zName);
|
||||
sqlite3DbFree(db, pItem->zAlias);
|
||||
if( pItem->zAlias ) sqlite3DbFreeNN(db, pItem->zAlias);
|
||||
if( pItem->fg.isIndexedBy ) sqlite3DbFree(db, pItem->u1.zIndexedBy);
|
||||
if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg);
|
||||
sqlite3DeleteTable(db, pItem->pTab);
|
||||
sqlite3SelectDelete(db, pItem->pSelect);
|
||||
sqlite3ExprDelete(db, pItem->pOn);
|
||||
sqlite3IdListDelete(db, pItem->pUsing);
|
||||
if( pItem->pSelect ) sqlite3SelectDelete(db, pItem->pSelect);
|
||||
if( pItem->pOn ) sqlite3ExprDelete(db, pItem->pOn);
|
||||
if( pItem->pUsing ) sqlite3IdListDelete(db, pItem->pUsing);
|
||||
}
|
||||
sqlite3DbFreeNN(db, pList);
|
||||
}
|
||||
@@ -4646,7 +4657,16 @@ void sqlite3BeginTransaction(Parse *pParse, int type){
|
||||
if( !v ) return;
|
||||
if( type!=TK_DEFERRED ){
|
||||
for(i=0; i<db->nDb; i++){
|
||||
sqlite3VdbeAddOp2(v, OP_Transaction, i, (type==TK_EXCLUSIVE)+1);
|
||||
int eTxnType;
|
||||
Btree *pBt = db->aDb[i].pBt;
|
||||
if( pBt && sqlite3BtreeIsReadonly(pBt) ){
|
||||
eTxnType = 0; /* Read txn */
|
||||
}else if( type==TK_EXCLUSIVE ){
|
||||
eTxnType = 2; /* Exclusive txn */
|
||||
}else{
|
||||
eTxnType = 1; /* Write txn */
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, OP_Transaction, i, eTxnType);
|
||||
sqlite3VdbeUsesBtree(v, i);
|
||||
}
|
||||
}
|
||||
@@ -4735,13 +4755,11 @@ int sqlite3OpenTempDatabase(Parse *pParse){
|
||||
** will occur at the end of the top-level VDBE and will be generated
|
||||
** later, by sqlite3FinishCoding().
|
||||
*/
|
||||
void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
|
||||
Parse *pToplevel = sqlite3ParseToplevel(pParse);
|
||||
|
||||
assert( iDb>=0 && iDb<pParse->db->nDb );
|
||||
assert( pParse->db->aDb[iDb].pBt!=0 || iDb==1 );
|
||||
static void sqlite3CodeVerifySchemaAtToplevel(Parse *pToplevel, int iDb){
|
||||
assert( iDb>=0 && iDb<pToplevel->db->nDb );
|
||||
assert( pToplevel->db->aDb[iDb].pBt!=0 || iDb==1 );
|
||||
assert( iDb<SQLITE_MAX_ATTACHED+2 );
|
||||
assert( sqlite3SchemaMutexHeld(pParse->db, iDb, 0) );
|
||||
assert( sqlite3SchemaMutexHeld(pToplevel->db, iDb, 0) );
|
||||
if( DbMaskTest(pToplevel->cookieMask, iDb)==0 ){
|
||||
DbMaskSet(pToplevel->cookieMask, iDb);
|
||||
if( !OMIT_TEMPDB && iDb==1 ){
|
||||
@@ -4749,6 +4767,10 @@ void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
|
||||
}
|
||||
}
|
||||
}
|
||||
void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
|
||||
sqlite3CodeVerifySchemaAtToplevel(sqlite3ParseToplevel(pParse), iDb);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** If argument zDb is NULL, then call sqlite3CodeVerifySchema() for each
|
||||
@@ -4780,7 +4802,7 @@ void sqlite3CodeVerifyNamedSchema(Parse *pParse, const char *zDb){
|
||||
*/
|
||||
void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){
|
||||
Parse *pToplevel = sqlite3ParseToplevel(pParse);
|
||||
sqlite3CodeVerifySchema(pParse, iDb);
|
||||
sqlite3CodeVerifySchemaAtToplevel(pToplevel, iDb);
|
||||
DbMaskSet(pToplevel->writeMask, iDb);
|
||||
pToplevel->isMultiWrite |= setStatement;
|
||||
}
|
||||
@@ -4831,7 +4853,9 @@ void sqlite3HaltConstraint(
|
||||
i8 p4type, /* P4_STATIC or P4_TRANSIENT */
|
||||
u8 p5Errmsg /* P5_ErrMsg type */
|
||||
){
|
||||
Vdbe *v = sqlite3GetVdbe(pParse);
|
||||
Vdbe *v;
|
||||
assert( pParse->pVdbe!=0 );
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
assert( (errCode&0xff)==SQLITE_CONSTRAINT || pParse->nested );
|
||||
if( onError==OE_Abort ){
|
||||
sqlite3MayAbort(pParse);
|
||||
|
||||
@@ -942,10 +942,6 @@ int sqlite3GenerateIndexKey(
|
||||
}
|
||||
if( regOut ){
|
||||
sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regOut);
|
||||
if( pIdx->pTable->pSelect ){
|
||||
const char *zAff = sqlite3IndexAffinityStr(pParse->db, pIdx);
|
||||
sqlite3VdbeChangeP4(v, -1, zAff, P4_TRANSIENT);
|
||||
}
|
||||
}
|
||||
sqlite3ReleaseTempRange(pParse, regBase, nCol);
|
||||
return regBase;
|
||||
|
||||
+7
-4
@@ -44,8 +44,10 @@ char sqlite3TableColumnAffinity(Table *pTab, int iCol){
|
||||
*/
|
||||
char sqlite3ExprAffinity(const Expr *pExpr){
|
||||
int op;
|
||||
while( ExprHasProperty(pExpr, EP_Skip) ){
|
||||
assert( pExpr->op==TK_COLLATE || pExpr->op==TK_IF_NULL_ROW );
|
||||
while( ExprHasProperty(pExpr, EP_Skip|EP_IfNullRow) ){
|
||||
assert( pExpr->op==TK_COLLATE
|
||||
|| pExpr->op==TK_IF_NULL_ROW
|
||||
|| (pExpr->op==TK_REGISTER && pExpr->op2==TK_IF_NULL_ROW) );
|
||||
pExpr = pExpr->pLeft;
|
||||
assert( pExpr!=0 );
|
||||
}
|
||||
@@ -115,7 +117,7 @@ Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){
|
||||
*/
|
||||
Expr *sqlite3ExprSkipCollate(Expr *pExpr){
|
||||
while( pExpr && ExprHasProperty(pExpr, EP_Skip) ){
|
||||
assert( pExpr->op==TK_COLLATE || pExpr->op==TK_IF_NULL_ROW );
|
||||
assert( pExpr->op==TK_COLLATE );
|
||||
pExpr = pExpr->pLeft;
|
||||
}
|
||||
return pExpr;
|
||||
@@ -134,7 +136,7 @@ Expr *sqlite3ExprSkipCollateAndLikely(Expr *pExpr){
|
||||
assert( pExpr->op==TK_FUNCTION );
|
||||
pExpr = pExpr->x.pList->a[0].pExpr;
|
||||
}else{
|
||||
assert( pExpr->op==TK_COLLATE || pExpr->op==TK_IF_NULL_ROW );
|
||||
assert( pExpr->op==TK_COLLATE );
|
||||
pExpr = pExpr->pLeft;
|
||||
}
|
||||
}
|
||||
@@ -768,6 +770,7 @@ int sqlite3SelectExprHeight(Select *p){
|
||||
** Expr.flags.
|
||||
*/
|
||||
void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){
|
||||
if( pParse->nErr ) return;
|
||||
if( p && p->x.pList && !ExprHasProperty(p, EP_xIsSelect) ){
|
||||
p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList);
|
||||
}
|
||||
|
||||
+6
-5
@@ -32,7 +32,8 @@ void sqlite3OpenTable(
|
||||
){
|
||||
Vdbe *v;
|
||||
assert( !IsVirtual(pTab) );
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
assert( pParse->pVdbe!=0 );
|
||||
v = pParse->pVdbe;
|
||||
assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );
|
||||
sqlite3TableLock(pParse, iDb, pTab->tnum,
|
||||
(opcode==OP_OpenWrite)?1:0, pTab->zName);
|
||||
@@ -1531,7 +1532,7 @@ void sqlite3GenerateConstraintChecks(
|
||||
|
||||
isUpdate = regOldData!=0;
|
||||
db = pParse->db;
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
v = pParse->pVdbe;
|
||||
assert( v!=0 );
|
||||
assert( pTab->pSelect==0 ); /* This table is not a VIEW */
|
||||
nCol = pTab->nCol;
|
||||
@@ -1685,7 +1686,7 @@ void sqlite3GenerateConstraintChecks(
|
||||
sqlite3VdbeGoto(v, ignoreDest);
|
||||
}else{
|
||||
char *zName = pCheck->a[i].zEName;
|
||||
if( zName==0 ) zName = pTab->zName;
|
||||
assert( zName!=0 || pParse->db->mallocFailed );
|
||||
if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-26383-51744 */
|
||||
sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_CHECK,
|
||||
onError, zName, P4_TRANSIENT,
|
||||
@@ -2304,7 +2305,7 @@ void sqlite3CompleteInsertion(
|
||||
|| update_flags==(OPFLAG_ISUPDATE|OPFLAG_SAVEPOSITION)
|
||||
);
|
||||
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
v = pParse->pVdbe;
|
||||
assert( v!=0 );
|
||||
assert( pTab->pSelect==0 ); /* This table is not a VIEW */
|
||||
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
|
||||
@@ -2405,7 +2406,7 @@ int sqlite3OpenTableAndIndices(
|
||||
return 0;
|
||||
}
|
||||
iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
v = pParse->pVdbe;
|
||||
assert( v!=0 );
|
||||
if( iBase<0 ) iBase = pParse->nTab;
|
||||
iDataCur = iBase++;
|
||||
|
||||
+57
-6
@@ -897,7 +897,7 @@ int sqlite3_db_cacheflush(sqlite3 *db){
|
||||
sqlite3BtreeEnterAll(db);
|
||||
for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
|
||||
Btree *pBt = db->aDb[i].pBt;
|
||||
if( pBt && sqlite3BtreeIsInTrans(pBt) ){
|
||||
if( pBt && sqlite3BtreeTxnState(pBt)==SQLITE_TXN_WRITE ){
|
||||
Pager *pPager = sqlite3BtreePager(pBt);
|
||||
rc = sqlite3PagerFlush(pPager);
|
||||
if( rc==SQLITE_BUSY ){
|
||||
@@ -1241,6 +1241,36 @@ static int sqlite3Close(sqlite3 *db, int forceZombie){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the transaction state for a single databse, or the maximum
|
||||
** transaction state over all attached databases if zSchema is null.
|
||||
*/
|
||||
int sqlite3_txn_state(sqlite3 *db, const char *zSchema){
|
||||
int iDb, nDb;
|
||||
int iTxn = -1;
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !sqlite3SafetyCheckOk(db) ){
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
if( zSchema ){
|
||||
nDb = iDb = sqlite3FindDbName(db, zSchema);
|
||||
if( iDb<0 ) nDb--;
|
||||
}else{
|
||||
iDb = 0;
|
||||
nDb = db->nDb-1;
|
||||
}
|
||||
for(; iDb<=nDb; iDb++){
|
||||
Btree *pBt = db->aDb[iDb].pBt;
|
||||
int x = pBt!=0 ? sqlite3BtreeTxnState(pBt) : SQLITE_TXN_NONE;
|
||||
if( x>iTxn ) iTxn = x;
|
||||
}
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return iTxn;
|
||||
}
|
||||
|
||||
/*
|
||||
** Two variations on the public interface for closing a database
|
||||
** connection. The sqlite3_close() version returns SQLITE_BUSY and
|
||||
@@ -1401,7 +1431,7 @@ void sqlite3RollbackAll(sqlite3 *db, int tripCode){
|
||||
for(i=0; i<db->nDb; i++){
|
||||
Btree *p = db->aDb[i].pBt;
|
||||
if( p ){
|
||||
if( sqlite3BtreeIsInTrans(p) ){
|
||||
if( sqlite3BtreeTxnState(p)==SQLITE_TXN_WRITE ){
|
||||
inTrans = 1;
|
||||
}
|
||||
sqlite3BtreeRollback(p, tripCode, !schemaChange);
|
||||
@@ -3822,7 +3852,9 @@ int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){
|
||||
}
|
||||
rc = SQLITE_OK;
|
||||
}else{
|
||||
int nSave = db->busyHandler.nBusy;
|
||||
rc = sqlite3OsFileControl(fd, op, pArg);
|
||||
db->busyHandler.nBusy = nSave;
|
||||
}
|
||||
sqlite3BtreeLeave(pBtree);
|
||||
}
|
||||
@@ -4205,6 +4237,25 @@ int sqlite3_test_control(int op, ...){
|
||||
sqlite3ResultIntReal(pCtx);
|
||||
break;
|
||||
}
|
||||
|
||||
/* sqlite3_test_control(SQLITE_TESTCTRL_SEEK_COUNT,
|
||||
** sqlite3 *db, // Database connection
|
||||
** u64 *pnSeek // Write seek count here
|
||||
** );
|
||||
**
|
||||
** This test-control queries the seek-counter on the "main" database
|
||||
** file. The seek-counter is written into *pnSeek and is then reset.
|
||||
** The seek-count is only available if compiled with SQLITE_DEBUG.
|
||||
*/
|
||||
case SQLITE_TESTCTRL_SEEK_COUNT: {
|
||||
sqlite3 *db = va_arg(ap, sqlite3*);
|
||||
u64 *pn = va_arg(ap, sqlite3_uint64*);
|
||||
*pn = sqlite3BtreeSeekCount(db->aDb->pBt);
|
||||
(void)db; /* Silence harmless unused variable warning */
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
va_end(ap);
|
||||
#endif /* SQLITE_UNTESTABLE */
|
||||
@@ -4440,7 +4491,7 @@ int sqlite3_snapshot_get(
|
||||
int iDb = sqlite3FindDbName(db, zDb);
|
||||
if( iDb==0 || iDb>1 ){
|
||||
Btree *pBt = db->aDb[iDb].pBt;
|
||||
if( 0==sqlite3BtreeIsInTrans(pBt) ){
|
||||
if( SQLITE_TXN_WRITE!=sqlite3BtreeTxnState(pBt) ){
|
||||
rc = sqlite3BtreeBeginTrans(pBt, 0, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3PagerSnapshotGet(sqlite3BtreePager(pBt), ppSnapshot);
|
||||
@@ -4476,10 +4527,10 @@ int sqlite3_snapshot_open(
|
||||
iDb = sqlite3FindDbName(db, zDb);
|
||||
if( iDb==0 || iDb>1 ){
|
||||
Btree *pBt = db->aDb[iDb].pBt;
|
||||
if( sqlite3BtreeIsInTrans(pBt)==0 ){
|
||||
if( sqlite3BtreeTxnState(pBt)!=SQLITE_TXN_WRITE ){
|
||||
Pager *pPager = sqlite3BtreePager(pBt);
|
||||
int bUnlock = 0;
|
||||
if( sqlite3BtreeIsInReadTrans(pBt) ){
|
||||
if( sqlite3BtreeTxnState(pBt)!=SQLITE_TXN_NONE ){
|
||||
if( db->nVdbeActive==0 ){
|
||||
rc = sqlite3PagerSnapshotCheck(pPager, pSnapshot);
|
||||
if( rc==SQLITE_OK ){
|
||||
@@ -4528,7 +4579,7 @@ int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb){
|
||||
iDb = sqlite3FindDbName(db, zDb);
|
||||
if( iDb==0 || iDb>1 ){
|
||||
Btree *pBt = db->aDb[iDb].pBt;
|
||||
if( 0==sqlite3BtreeIsInReadTrans(pBt) ){
|
||||
if( SQLITE_TXN_NONE==sqlite3BtreeTxnState(pBt) ){
|
||||
rc = sqlite3BtreeBeginTrans(pBt, 0, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3PagerSnapshotRecover(sqlite3BtreePager(pBt));
|
||||
|
||||
+6
-1
@@ -474,12 +474,17 @@ void *sqlite3Realloc(void *pOld, u64 nBytes){
|
||||
if( nOld==nNew ){
|
||||
pNew = pOld;
|
||||
}else if( sqlite3GlobalConfig.bMemstat ){
|
||||
sqlite3_int64 nUsed;
|
||||
sqlite3_mutex_enter(mem0.mutex);
|
||||
sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, (int)nBytes);
|
||||
nDiff = nNew - nOld;
|
||||
if( nDiff>0 && sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >=
|
||||
if( nDiff>0 && (nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)) >=
|
||||
mem0.alarmThreshold-nDiff ){
|
||||
sqlite3MallocAlarm(nDiff);
|
||||
if( mem0.hardLimit>0 && nUsed >= mem0.hardLimit - nDiff ){
|
||||
sqlite3_mutex_leave(mem0.mutex);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
|
||||
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
|
||||
|
||||
+15
-4
@@ -126,11 +126,14 @@ static const sqlite3_io_methods memdb_io_methods = {
|
||||
** Close an memdb-file.
|
||||
**
|
||||
** The pData pointer is owned by the application, so there is nothing
|
||||
** to free.
|
||||
** to free. Unless the SQLITE_DESERIALIZE_FREEONCLOSE flag is set,
|
||||
** in which case we own the pData pointer and need to free it.
|
||||
*/
|
||||
static int memdbClose(sqlite3_file *pFile){
|
||||
MemFile *p = (MemFile *)pFile;
|
||||
if( p->mFlags & SQLITE_DESERIALIZE_FREEONCLOSE ) sqlite3_free(p->aData);
|
||||
if( p->mFlags & SQLITE_DESERIALIZE_FREEONCLOSE ){
|
||||
sqlite3_free(p->aData);
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
@@ -573,8 +576,12 @@ int sqlite3_deserialize(
|
||||
goto end_deserialize;
|
||||
}
|
||||
zSql = sqlite3_mprintf("ATTACH x AS %Q", zSchema);
|
||||
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
|
||||
sqlite3_free(zSql);
|
||||
if( zSql==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
|
||||
sqlite3_free(zSql);
|
||||
}
|
||||
if( rc ) goto end_deserialize;
|
||||
db->init.iDb = (u8)iDb;
|
||||
db->init.reopenMemdb = 1;
|
||||
@@ -589,6 +596,7 @@ int sqlite3_deserialize(
|
||||
rc = SQLITE_ERROR;
|
||||
}else{
|
||||
p->aData = pData;
|
||||
pData = 0;
|
||||
p->sz = szDb;
|
||||
p->szAlloc = szBuf;
|
||||
p->szMax = szBuf;
|
||||
@@ -601,6 +609,9 @@ int sqlite3_deserialize(
|
||||
|
||||
end_deserialize:
|
||||
sqlite3_finalize(pStmt);
|
||||
if( pData && (mFlags & SQLITE_DESERIALIZE_FREEONCLOSE)!=0 ){
|
||||
sqlite3_free(pData);
|
||||
}
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
+92
-55
@@ -122,7 +122,8 @@
|
||||
# if defined(__APPLE__) && ((__MAC_OS_X_VERSION_MIN_REQUIRED > 1050) || \
|
||||
(__IPHONE_OS_VERSION_MIN_REQUIRED > 2000))
|
||||
# if (!defined(TARGET_OS_EMBEDDED) || (TARGET_OS_EMBEDDED==0)) \
|
||||
&& (!defined(TARGET_IPHONE_SIMULATOR) || (TARGET_IPHONE_SIMULATOR==0))
|
||||
&& (!defined(TARGET_IPHONE_SIMULATOR) || (TARGET_IPHONE_SIMULATOR==0))\
|
||||
&& (!defined(TARGET_OS_MACCATALYST) || (TARGET_OS_MACCATALYST==0))
|
||||
# undef HAVE_GETHOSTUUID
|
||||
# define HAVE_GETHOSTUUID 1
|
||||
# else
|
||||
@@ -1544,6 +1545,9 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Forward declaration*/
|
||||
static int unixSleep(sqlite3_vfs*,int);
|
||||
|
||||
/*
|
||||
** Set a posix-advisory-lock.
|
||||
**
|
||||
@@ -1573,7 +1577,7 @@ static int osSetPosixAdvisoryLock(
|
||||
** generic posix, however, there is no such API. So we simply try the
|
||||
** lock once every millisecond until either the timeout expires, or until
|
||||
** the lock is obtained. */
|
||||
usleep(1000);
|
||||
unixSleep(0,1000);
|
||||
rc = osFcntl(h,F_SETLK,pLock);
|
||||
tm--;
|
||||
}
|
||||
@@ -2144,6 +2148,7 @@ static int unixClose(sqlite3_file *id){
|
||||
}
|
||||
sqlite3_mutex_leave(pInode->pLockMutex);
|
||||
releaseInodeInfo(pFile);
|
||||
assert( pFile->pShm==0 );
|
||||
rc = closeUnixFile(id);
|
||||
unixLeaveMutex();
|
||||
return rc;
|
||||
@@ -4254,6 +4259,7 @@ struct unixShmNode {
|
||||
char **apRegion; /* Array of mapped shared-memory regions */
|
||||
int nRef; /* Number of unixShm objects pointing to this */
|
||||
unixShm *pFirst; /* All unixShm objects pointing to this */
|
||||
int aLock[SQLITE_SHM_NLOCK]; /* # shared locks on slot, -1==excl lock */
|
||||
#ifdef SQLITE_DEBUG
|
||||
u8 exclMask; /* Mask of exclusive locks held */
|
||||
u8 sharedMask; /* Mask of shared locks held */
|
||||
@@ -4794,6 +4800,38 @@ shmpage_out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Check that the pShmNode->aLock[] array comports with the locking bitmasks
|
||||
** held by each client. Return true if it does, or false otherwise. This
|
||||
** is to be used in an assert(). e.g.
|
||||
**
|
||||
** assert( assertLockingArrayOk(pShmNode) );
|
||||
*/
|
||||
#ifdef SQLITE_DEBUG
|
||||
static int assertLockingArrayOk(unixShmNode *pShmNode){
|
||||
unixShm *pX;
|
||||
int aLock[SQLITE_SHM_NLOCK];
|
||||
assert( sqlite3_mutex_held(pShmNode->pShmMutex) );
|
||||
|
||||
memset(aLock, 0, sizeof(aLock));
|
||||
for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
|
||||
int i;
|
||||
for(i=0; i<SQLITE_SHM_NLOCK; i++){
|
||||
if( pX->exclMask & (1<<i) ){
|
||||
assert( aLock[i]==0 );
|
||||
aLock[i] = -1;
|
||||
}else if( pX->sharedMask & (1<<i) ){
|
||||
assert( aLock[i]>=0 );
|
||||
aLock[i]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert( 0==memcmp(pShmNode->aLock, aLock, sizeof(aLock)) );
|
||||
return (memcmp(pShmNode->aLock, aLock, sizeof(aLock))==0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Change the lock state for a shared-memory segment.
|
||||
**
|
||||
@@ -4810,10 +4848,10 @@ static int unixShmLock(
|
||||
){
|
||||
unixFile *pDbFd = (unixFile*)fd; /* Connection holding shared memory */
|
||||
unixShm *p = pDbFd->pShm; /* The shared memory being locked */
|
||||
unixShm *pX; /* For looping over all siblings */
|
||||
unixShmNode *pShmNode = p->pShmNode; /* The underlying file iNode */
|
||||
int rc = SQLITE_OK; /* Result code */
|
||||
u16 mask; /* Mask of locks to take or release */
|
||||
int *aLock = pShmNode->aLock;
|
||||
|
||||
assert( pShmNode==pDbFd->pInode->pShmNode );
|
||||
assert( pShmNode->pInode==pDbFd->pInode );
|
||||
@@ -4852,78 +4890,76 @@ static int unixShmLock(
|
||||
mask = (1<<(ofst+n)) - (1<<ofst);
|
||||
assert( n>1 || mask==(1<<ofst) );
|
||||
sqlite3_mutex_enter(pShmNode->pShmMutex);
|
||||
assert( assertLockingArrayOk(pShmNode) );
|
||||
if( flags & SQLITE_SHM_UNLOCK ){
|
||||
u16 allMask = 0; /* Mask of locks held by siblings */
|
||||
if( (p->exclMask|p->sharedMask) & mask ){
|
||||
int ii;
|
||||
int bUnlock = 1;
|
||||
|
||||
/* See if any siblings hold this same lock */
|
||||
for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
|
||||
if( pX==p ) continue;
|
||||
assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 );
|
||||
allMask |= pX->sharedMask;
|
||||
for(ii=ofst; ii<ofst+n; ii++){
|
||||
if( aLock[ii]>((p->sharedMask & (1<<ii)) ? 1 : 0) ){
|
||||
bUnlock = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if( bUnlock ){
|
||||
rc = unixShmSystemLock(pDbFd, F_UNLCK, ofst+UNIX_SHM_BASE, n);
|
||||
if( rc==SQLITE_OK ){
|
||||
memset(&aLock[ofst], 0, sizeof(int)*n);
|
||||
}
|
||||
}else if( p->sharedMask & (1<<ofst) ){
|
||||
assert( n==1 && aLock[ofst]>1 );
|
||||
aLock[ofst]--;
|
||||
}
|
||||
|
||||
/* Undo the local locks */
|
||||
if( rc==SQLITE_OK ){
|
||||
p->exclMask &= ~mask;
|
||||
p->sharedMask &= ~mask;
|
||||
}
|
||||
}
|
||||
|
||||
/* Unlock the system-level locks */
|
||||
if( (mask & allMask)==0 ){
|
||||
rc = unixShmSystemLock(pDbFd, F_UNLCK, ofst+UNIX_SHM_BASE, n);
|
||||
}else{
|
||||
rc = SQLITE_OK;
|
||||
}
|
||||
|
||||
/* Undo the local locks */
|
||||
if( rc==SQLITE_OK ){
|
||||
p->exclMask &= ~mask;
|
||||
p->sharedMask &= ~mask;
|
||||
}
|
||||
}else if( flags & SQLITE_SHM_SHARED ){
|
||||
u16 allShared = 0; /* Union of locks held by connections other than "p" */
|
||||
|
||||
/* Find out which shared locks are already held by sibling connections.
|
||||
** If any sibling already holds an exclusive lock, go ahead and return
|
||||
** SQLITE_BUSY.
|
||||
*/
|
||||
for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
|
||||
if( (pX->exclMask & mask)!=0 ){
|
||||
assert( n==1 );
|
||||
assert( (p->exclMask & (1<<ofst))==0 );
|
||||
if( (p->sharedMask & mask)==0 ){
|
||||
if( aLock[ofst]<0 ){
|
||||
rc = SQLITE_BUSY;
|
||||
break;
|
||||
}
|
||||
allShared |= pX->sharedMask;
|
||||
}
|
||||
|
||||
/* Get shared locks at the system level, if necessary */
|
||||
if( rc==SQLITE_OK ){
|
||||
if( (allShared & mask)==0 ){
|
||||
}else if( aLock[ofst]==0 ){
|
||||
rc = unixShmSystemLock(pDbFd, F_RDLCK, ofst+UNIX_SHM_BASE, n);
|
||||
}else{
|
||||
rc = SQLITE_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the local shared locks */
|
||||
if( rc==SQLITE_OK ){
|
||||
p->sharedMask |= mask;
|
||||
/* Get the local shared locks */
|
||||
if( rc==SQLITE_OK ){
|
||||
p->sharedMask |= mask;
|
||||
aLock[ofst]++;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
/* Make sure no sibling connections hold locks that will block this
|
||||
** lock. If any do, return SQLITE_BUSY right away.
|
||||
*/
|
||||
for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
|
||||
if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){
|
||||
** lock. If any do, return SQLITE_BUSY right away. */
|
||||
int ii;
|
||||
for(ii=ofst; ii<ofst+n; ii++){
|
||||
assert( (p->sharedMask & mask)==0 );
|
||||
if( (p->exclMask & (1<<ii))==0 && aLock[ii] ){
|
||||
rc = SQLITE_BUSY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the exclusive locks at the system level. Then if successful
|
||||
** also mark the local connection as being locked.
|
||||
*/
|
||||
|
||||
/* Get the exclusive locks at the system level. Then if successful
|
||||
** also update the in-memory values. */
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = unixShmSystemLock(pDbFd, F_WRLCK, ofst+UNIX_SHM_BASE, n);
|
||||
if( rc==SQLITE_OK ){
|
||||
assert( (p->sharedMask & mask)==0 );
|
||||
p->exclMask |= mask;
|
||||
for(ii=ofst; ii<ofst+n; ii++){
|
||||
aLock[ii] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
assert( assertLockingArrayOk(pShmNode) );
|
||||
sqlite3_mutex_leave(pShmNode->pShmMutex);
|
||||
OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n",
|
||||
p->id, osGetpid(0), p->sharedMask, p->exclMask));
|
||||
@@ -6543,7 +6579,8 @@ static int unixSleep(sqlite3_vfs *NotUsed, int microseconds){
|
||||
UNUSED_PARAMETER(NotUsed);
|
||||
return microseconds;
|
||||
#elif defined(HAVE_USLEEP) && HAVE_USLEEP
|
||||
usleep(microseconds);
|
||||
if( microseconds>=1000000 ) sleep(microseconds/1000000);
|
||||
if( microseconds%1000000 ) usleep(microseconds%1000000);
|
||||
UNUSED_PARAMETER(NotUsed);
|
||||
return microseconds;
|
||||
#else
|
||||
@@ -7116,7 +7153,7 @@ static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){
|
||||
|
||||
if( nTries==1 ){
|
||||
conchModTime = buf.st_mtimespec;
|
||||
usleep(500000); /* wait 0.5 sec and try the lock again*/
|
||||
unixSleep(0,500000); /* wait 0.5 sec and try the lock again*/
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -7142,7 +7179,7 @@ static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){
|
||||
/* don't break the lock on short read or a version mismatch */
|
||||
return SQLITE_BUSY;
|
||||
}
|
||||
usleep(10000000); /* wait 10 sec and try the lock again */
|
||||
unixSleep(0,10000000); /* wait 10 sec and try the lock again */
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
+5
-1
@@ -5126,7 +5126,11 @@ static int winOpen(
|
||||
dwCreationDisposition = OPEN_EXISTING;
|
||||
}
|
||||
|
||||
dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
|
||||
if( 0==sqlite3_uri_boolean(zName, "exclusive", 0) ){
|
||||
dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
|
||||
}else{
|
||||
dwShareMode = 0;
|
||||
}
|
||||
|
||||
if( isDelete ){
|
||||
#if SQLITE_OS_WINCE
|
||||
|
||||
+14
-8
@@ -1,5 +1,6 @@
|
||||
%include {
|
||||
/*
|
||||
** 2001 September 15
|
||||
** 2001-09-15
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
@@ -9,11 +10,16 @@
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** This file contains SQLite's grammar for SQL. Process this file
|
||||
** using the lemon parser generator to generate C code that runs
|
||||
** the parser. Lemon will also generate a header file containing
|
||||
** numeric codes for all of the tokens.
|
||||
** This file contains SQLite's SQL parser.
|
||||
**
|
||||
** The canonical source code to this file ("parse.y") is a Lemon grammar
|
||||
** file that specifies the input grammar and actions to take while parsing.
|
||||
** That input file is processed by Lemon to generate a C-language
|
||||
** implementation of a parser for the given grammer. You might be reading
|
||||
** this comment as part of the translated C-code. Edits should be made
|
||||
** to the original parse.y sources.
|
||||
*/
|
||||
}
|
||||
|
||||
// All token codes are small integers with #defines that begin with "TK_"
|
||||
%token_prefix TK_
|
||||
@@ -366,7 +372,7 @@ ccons ::= PRIMARY KEY sortorder(Z) onconf(R) autoinc(I).
|
||||
{sqlite3AddPrimaryKey(pParse,0,R,I,Z);}
|
||||
ccons ::= UNIQUE onconf(R). {sqlite3CreateIndex(pParse,0,0,0,0,R,0,0,0,0,
|
||||
SQLITE_IDXTYPE_UNIQUE);}
|
||||
ccons ::= CHECK LP expr(X) RP. {sqlite3AddCheckConstraint(pParse,X);}
|
||||
ccons ::= CHECK LP(A) expr(X) RP(B). {sqlite3AddCheckConstraint(pParse,X,A.z,B.z);}
|
||||
ccons ::= REFERENCES nm(T) eidlist_opt(TA) refargs(R).
|
||||
{sqlite3CreateForeignKey(pParse,0,&T,TA,R);}
|
||||
ccons ::= defer_subclause(D). {sqlite3DeferForeignKey(pParse,D);}
|
||||
@@ -420,8 +426,8 @@ tcons ::= PRIMARY KEY LP sortlist(X) autoinc(I) RP onconf(R).
|
||||
tcons ::= UNIQUE LP sortlist(X) RP onconf(R).
|
||||
{sqlite3CreateIndex(pParse,0,0,0,X,R,0,0,0,0,
|
||||
SQLITE_IDXTYPE_UNIQUE);}
|
||||
tcons ::= CHECK LP expr(E) RP onconf.
|
||||
{sqlite3AddCheckConstraint(pParse,E);}
|
||||
tcons ::= CHECK LP(A) expr(E) RP(B) onconf.
|
||||
{sqlite3AddCheckConstraint(pParse,E,A.z,B.z);}
|
||||
tcons ::= FOREIGN KEY LP eidlist(FA) RP
|
||||
REFERENCES nm(T) eidlist_opt(TA) refargs(R) defer_subclause_opt(D). {
|
||||
sqlite3CreateForeignKey(pParse, FA, &T, TA, R);
|
||||
|
||||
+5
-3
@@ -131,7 +131,9 @@ static int getTempStore(const char *z){
|
||||
static int invalidateTempStorage(Parse *pParse){
|
||||
sqlite3 *db = pParse->db;
|
||||
if( db->aDb[1].pBt!=0 ){
|
||||
if( !db->autoCommit || sqlite3BtreeIsInReadTrans(db->aDb[1].pBt) ){
|
||||
if( !db->autoCommit
|
||||
|| sqlite3BtreeTxnState(db->aDb[1].pBt)!=SQLITE_TXN_NONE
|
||||
){
|
||||
sqlite3ErrorMsg(pParse, "temporary storage cannot be changed "
|
||||
"from within a transaction");
|
||||
return SQLITE_ERROR;
|
||||
@@ -1451,7 +1453,7 @@ void sqlite3Pragma(
|
||||
aiCols = 0;
|
||||
if( pParent ){
|
||||
x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols);
|
||||
assert( x==0 );
|
||||
assert( x==0 || db->mallocFailed );
|
||||
}
|
||||
addrOk = sqlite3VdbeMakeLabel(pParse);
|
||||
|
||||
@@ -1476,7 +1478,7 @@ void sqlite3Pragma(
|
||||
int jmp = sqlite3VdbeCurrentAddr(v)+2;
|
||||
sqlite3VdbeAddOp3(v, OP_SeekRowid, i, jmp, regRow); VdbeCoverage(v);
|
||||
sqlite3VdbeGoto(v, addrOk);
|
||||
assert( pFK->nCol==1 );
|
||||
assert( pFK->nCol==1 || db->mallocFailed );
|
||||
}
|
||||
|
||||
/* Generate code to report an FK violation to the caller. */
|
||||
|
||||
+3
-2
@@ -240,7 +240,7 @@ int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){
|
||||
** on the b-tree database, open one now. If a transaction is opened, it
|
||||
** will be closed before this function returns. */
|
||||
sqlite3BtreeEnter(pDb->pBt);
|
||||
if( !sqlite3BtreeIsInReadTrans(pDb->pBt) ){
|
||||
if( sqlite3BtreeTxnState(pDb->pBt)==SQLITE_TXN_NONE ){
|
||||
rc = sqlite3BtreeBeginTrans(pDb->pBt, 0, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
sqlite3SetString(pzErrMsg, db, sqlite3ErrStr(rc));
|
||||
@@ -483,7 +483,7 @@ static void schemaIsValid(Parse *pParse){
|
||||
/* If there is not already a read-only (or read-write) transaction opened
|
||||
** on the b-tree database, open one now. If a transaction is opened, it
|
||||
** will be closed immediately after reading the meta-value. */
|
||||
if( !sqlite3BtreeIsInReadTrans(pBt) ){
|
||||
if( sqlite3BtreeTxnState(pBt)==SQLITE_TXN_NONE ){
|
||||
rc = sqlite3BtreeBeginTrans(pBt, 0, 0);
|
||||
if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
|
||||
sqlite3OomFault(db);
|
||||
@@ -746,6 +746,7 @@ static int sqlite3LockAndPrepare(
|
||||
sqlite3BtreeLeaveAll(db);
|
||||
rc = sqlite3ApiExit(db, rc);
|
||||
assert( (rc&db->errMask)==rc );
|
||||
db->busyHandler.nBusy = 0;
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
+4
-5
@@ -427,11 +427,10 @@ void sqlite3_str_vappendf(
|
||||
v = va_arg(ap,int);
|
||||
}
|
||||
if( v<0 ){
|
||||
if( v==SMALLEST_INT64 ){
|
||||
longvalue = ((u64)1)<<63;
|
||||
}else{
|
||||
longvalue = -v;
|
||||
}
|
||||
testcase( v==SMALLEST_INT64 );
|
||||
testcase( v==(-1) );
|
||||
longvalue = ~v;
|
||||
longvalue++;
|
||||
prefix = '-';
|
||||
}else{
|
||||
longvalue = v;
|
||||
|
||||
+1
-1
@@ -1075,7 +1075,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
assert( !ExprHasProperty(pExpr, EP_Reduced) );
|
||||
/* Handle special cases of "x IS TRUE", "x IS FALSE", "x IS NOT TRUE",
|
||||
** and "x IS NOT FALSE". */
|
||||
if( pRight && pRight->op==TK_ID ){
|
||||
if( pRight && (pRight->op==TK_ID || pRight->op==TK_TRUEFALSE) ){
|
||||
int rc = resolveExprStep(pWalker, pRight);
|
||||
if( rc==WRC_Abort ) return WRC_Abort;
|
||||
if( pRight->op==TK_TRUEFALSE ){
|
||||
|
||||
+71
-42
@@ -2340,6 +2340,7 @@ static void generateWithRecursiveQuery(
|
||||
int nCol = p->pEList->nExpr; /* Number of columns in the recursive table */
|
||||
Vdbe *v = pParse->pVdbe; /* The prepared statement under construction */
|
||||
Select *pSetup = p->pPrior; /* The setup query */
|
||||
Select *pFirstRec; /* Left-most recursive term */
|
||||
int addrTop; /* Top of the loop */
|
||||
int addrCont, addrBreak; /* CONTINUE and BREAK addresses */
|
||||
int iCurrent = 0; /* The Current table */
|
||||
@@ -2415,7 +2416,25 @@ static void generateWithRecursiveQuery(
|
||||
/* Detach the ORDER BY clause from the compound SELECT */
|
||||
p->pOrderBy = 0;
|
||||
|
||||
/* Figure out how many elements of the compound SELECT are part of the
|
||||
** recursive query. Make sure no recursive elements use aggregate
|
||||
** functions. Mark the recursive elements as UNION ALL even if they
|
||||
** are really UNION because the distinctness will be enforced by the
|
||||
** iDistinct table. pFirstRec is left pointing to the left-most
|
||||
** recursive term of the CTE.
|
||||
*/
|
||||
pFirstRec = p;
|
||||
for(pFirstRec=p; ALWAYS(pFirstRec!=0); pFirstRec=pFirstRec->pPrior){
|
||||
if( pFirstRec->selFlags & SF_Aggregate ){
|
||||
sqlite3ErrorMsg(pParse, "recursive aggregate queries not supported");
|
||||
goto end_of_recursive_query;
|
||||
}
|
||||
pFirstRec->op = TK_ALL;
|
||||
if( (pFirstRec->pPrior->selFlags & SF_Recursive)==0 ) break;
|
||||
}
|
||||
|
||||
/* Store the results of the setup-query in Queue. */
|
||||
pSetup = pFirstRec->pPrior;
|
||||
pSetup->pNext = 0;
|
||||
ExplainQueryPlan((pParse, 1, "SETUP"));
|
||||
rc = sqlite3Select(pParse, pSetup, &destQueue);
|
||||
@@ -2448,15 +2467,11 @@ static void generateWithRecursiveQuery(
|
||||
/* Execute the recursive SELECT taking the single row in Current as
|
||||
** the value for the recursive-table. Store the results in the Queue.
|
||||
*/
|
||||
if( p->selFlags & SF_Aggregate ){
|
||||
sqlite3ErrorMsg(pParse, "recursive aggregate queries not supported");
|
||||
}else{
|
||||
p->pPrior = 0;
|
||||
ExplainQueryPlan((pParse, 1, "RECURSIVE STEP"));
|
||||
sqlite3Select(pParse, p, &destQueue);
|
||||
assert( p->pPrior==0 );
|
||||
p->pPrior = pSetup;
|
||||
}
|
||||
pFirstRec->pPrior = 0;
|
||||
ExplainQueryPlan((pParse, 1, "RECURSIVE STEP"));
|
||||
sqlite3Select(pParse, p, &destQueue);
|
||||
assert( pFirstRec->pPrior==0 );
|
||||
pFirstRec->pPrior = pSetup;
|
||||
|
||||
/* Keep running the loop until the Queue is empty */
|
||||
sqlite3VdbeGoto(v, addrTop);
|
||||
@@ -2525,6 +2540,16 @@ static int multiSelectValues(
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return true if the SELECT statement which is known to be the recursive
|
||||
** part of a recursive CTE still has its anchor terms attached. If the
|
||||
** anchor terms have already been removed, then return false.
|
||||
*/
|
||||
static int hasAnchor(Select *p){
|
||||
while( p && (p->selFlags & SF_Recursive)!=0 ){ p = p->pPrior; }
|
||||
return p!=0;
|
||||
}
|
||||
|
||||
/*
|
||||
** This routine is called to process a compound query form from
|
||||
** two or more separate queries using UNION, UNION ALL, EXCEPT, or
|
||||
@@ -2610,7 +2635,7 @@ static int multiSelect(
|
||||
assert( p->pEList->nExpr==pPrior->pEList->nExpr );
|
||||
|
||||
#ifndef SQLITE_OMIT_CTE
|
||||
if( p->selFlags & SF_Recursive ){
|
||||
if( (p->selFlags & SF_Recursive)!=0 && hasAnchor(p) ){
|
||||
generateWithRecursiveQuery(pParse, p, &dest);
|
||||
}else
|
||||
#endif
|
||||
@@ -2701,6 +2726,7 @@ static int multiSelect(
|
||||
findRightmost(p)->selFlags |= SF_UsesEphemeral;
|
||||
assert( p->pEList );
|
||||
}
|
||||
|
||||
|
||||
/* Code the SELECT statements to our left
|
||||
*/
|
||||
@@ -3506,7 +3532,7 @@ static Expr *substExpr(
|
||||
ifNullRow.op = TK_IF_NULL_ROW;
|
||||
ifNullRow.pLeft = pCopy;
|
||||
ifNullRow.iTable = pSubst->iNewTable;
|
||||
ifNullRow.flags = EP_Skip;
|
||||
ifNullRow.flags = EP_IfNullRow;
|
||||
pCopy = &ifNullRow;
|
||||
}
|
||||
testcase( ExprHasProperty(pCopy, EP_Subquery) );
|
||||
@@ -3515,8 +3541,7 @@ static Expr *substExpr(
|
||||
ExprSetProperty(pNew, EP_CanBeNull);
|
||||
}
|
||||
if( pNew && ExprHasProperty(pExpr,EP_FromJoin) ){
|
||||
pNew->iRightJoinTable = pExpr->iRightJoinTable;
|
||||
ExprSetProperty(pNew, EP_FromJoin);
|
||||
sqlite3SetJoinExpr(pNew, pExpr->iRightJoinTable);
|
||||
}
|
||||
sqlite3ExprDelete(db, pExpr);
|
||||
pExpr = pNew;
|
||||
@@ -4795,8 +4820,10 @@ static int withExpand(
|
||||
ExprList *pEList;
|
||||
Select *pSel;
|
||||
Select *pLeft; /* Left-most SELECT statement */
|
||||
Select *pRecTerm; /* Left-most recursive term */
|
||||
int bMayRecursive; /* True if compound joined by UNION [ALL] */
|
||||
With *pSavedWith; /* Initial value of pParse->pWith */
|
||||
int iRecTab = -1; /* Cursor for recursive table */
|
||||
|
||||
/* If pCte->zCteErr is non-NULL at this point, then this is an illegal
|
||||
** recursive reference to CTE pCte. Leave an error in pParse and return
|
||||
@@ -4821,44 +4848,48 @@ static int withExpand(
|
||||
assert( pFrom->pSelect );
|
||||
|
||||
/* Check if this is a recursive CTE. */
|
||||
pSel = pFrom->pSelect;
|
||||
pRecTerm = pSel = pFrom->pSelect;
|
||||
bMayRecursive = ( pSel->op==TK_ALL || pSel->op==TK_UNION );
|
||||
if( bMayRecursive ){
|
||||
while( bMayRecursive && pRecTerm->op==pSel->op ){
|
||||
int i;
|
||||
SrcList *pSrc = pFrom->pSelect->pSrc;
|
||||
SrcList *pSrc = pRecTerm->pSrc;
|
||||
assert( pRecTerm->pPrior!=0 );
|
||||
for(i=0; i<pSrc->nSrc; i++){
|
||||
struct SrcList_item *pItem = &pSrc->a[i];
|
||||
if( pItem->zDatabase==0
|
||||
&& pItem->zName!=0
|
||||
&& 0==sqlite3StrICmp(pItem->zName, pCte->zName)
|
||||
){
|
||||
){
|
||||
pItem->pTab = pTab;
|
||||
pItem->fg.isRecursive = 1;
|
||||
pTab->nTabRef++;
|
||||
pSel->selFlags |= SF_Recursive;
|
||||
pItem->fg.isRecursive = 1;
|
||||
if( pRecTerm->selFlags & SF_Recursive ){
|
||||
sqlite3ErrorMsg(pParse,
|
||||
"multiple references to recursive table: %s", pCte->zName
|
||||
);
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
pRecTerm->selFlags |= SF_Recursive;
|
||||
if( iRecTab<0 ) iRecTab = pParse->nTab++;
|
||||
pItem->iCursor = iRecTab;
|
||||
}
|
||||
}
|
||||
if( (pRecTerm->selFlags & SF_Recursive)==0 ) break;
|
||||
pRecTerm = pRecTerm->pPrior;
|
||||
}
|
||||
|
||||
/* Only one recursive reference is permitted. */
|
||||
if( pTab->nTabRef>2 ){
|
||||
sqlite3ErrorMsg(
|
||||
pParse, "multiple references to recursive table: %s", pCte->zName
|
||||
);
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
assert( pTab->nTabRef==1 ||
|
||||
((pSel->selFlags&SF_Recursive) && pTab->nTabRef==2 ));
|
||||
|
||||
pCte->zCteErr = "circular reference: %s";
|
||||
pSavedWith = pParse->pWith;
|
||||
pParse->pWith = pWith;
|
||||
if( bMayRecursive ){
|
||||
Select *pPrior = pSel->pPrior;
|
||||
assert( pPrior->pWith==0 );
|
||||
pPrior->pWith = pSel->pWith;
|
||||
sqlite3WalkSelect(pWalker, pPrior);
|
||||
pPrior->pWith = 0;
|
||||
if( pSel->selFlags & SF_Recursive ){
|
||||
assert( pRecTerm!=0 );
|
||||
assert( (pRecTerm->selFlags & SF_Recursive)==0 );
|
||||
assert( pRecTerm->pNext!=0 );
|
||||
assert( (pRecTerm->pNext->selFlags & SF_Recursive)!=0 );
|
||||
assert( pRecTerm->pWith==0 );
|
||||
pRecTerm->pWith = pSel->pWith;
|
||||
sqlite3WalkSelect(pWalker, pRecTerm);
|
||||
pRecTerm->pWith = 0;
|
||||
}else{
|
||||
sqlite3WalkSelect(pWalker, pSel);
|
||||
}
|
||||
@@ -5808,13 +5839,11 @@ int sqlite3Select(
|
||||
assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo );
|
||||
assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue );
|
||||
assert( p->pOrderBy==0 || pDest->eDest!=SRT_Queue );
|
||||
if( IgnorableOrderby(pDest) ){
|
||||
assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union ||
|
||||
pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard ||
|
||||
pDest->eDest==SRT_Queue || pDest->eDest==SRT_DistFifo ||
|
||||
pDest->eDest==SRT_DistQueue || pDest->eDest==SRT_Fifo);
|
||||
/* If ORDER BY makes no difference in the output then neither does
|
||||
** DISTINCT so it can be removed too. */
|
||||
if( IgnorableDistinct(pDest) ){
|
||||
assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union ||
|
||||
pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard ||
|
||||
pDest->eDest==SRT_DistQueue || pDest->eDest==SRT_DistFifo );
|
||||
/* All of these destinations are also able to ignore the ORDER BY clause */
|
||||
sqlite3ExprListDelete(db, p->pOrderBy);
|
||||
p->pOrderBy = 0;
|
||||
p->selFlags &= ~SF_Distinct;
|
||||
|
||||
+138
-48
@@ -553,8 +553,6 @@ static void utf8_width_print(FILE *pOut, int w, const char *zUtf){
|
||||
int i;
|
||||
int n;
|
||||
int aw = w<0 ? -w : w;
|
||||
char zBuf[1000];
|
||||
if( aw>(int)sizeof(zBuf)/3 ) aw = (int)sizeof(zBuf)/3;
|
||||
for(i=n=0; zUtf[i]; i++){
|
||||
if( (zUtf[i]&0xc0)!=0x80 ){
|
||||
n++;
|
||||
@@ -1028,6 +1026,7 @@ INCLUDE ../ext/misc/memtrace.c
|
||||
INCLUDE ../ext/misc/uint.c
|
||||
INCLUDE ../ext/misc/decimal.c
|
||||
INCLUDE ../ext/misc/ieee754.c
|
||||
INCLUDE ../ext/misc/series.c
|
||||
#ifdef SQLITE_HAVE_ZLIB
|
||||
INCLUDE ../ext/misc/zipfile.c
|
||||
INCLUDE ../ext/misc/sqlar.c
|
||||
@@ -1185,6 +1184,8 @@ struct ShellState {
|
||||
#define SHFLG_CountChanges 0x00000020 /* .changes setting */
|
||||
#define SHFLG_Echo 0x00000040 /* .echo or --echo setting */
|
||||
#define SHFLG_HeaderSet 0x00000080 /* .header has been used */
|
||||
#define SHFLG_DumpDataOnly 0x00000100 /* .dump show data only */
|
||||
#define SHFLG_DumpNoSys 0x00000200 /* .dump omits system tables */
|
||||
|
||||
/*
|
||||
** Macros for testing and setting shellFlgs
|
||||
@@ -3705,19 +3706,25 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azNotUsed){
|
||||
const char *zType;
|
||||
const char *zSql;
|
||||
ShellState *p = (ShellState *)pArg;
|
||||
int dataOnly;
|
||||
int noSys;
|
||||
|
||||
UNUSED_PARAMETER(azNotUsed);
|
||||
if( nArg!=3 || azArg==0 ) return 0;
|
||||
zTable = azArg[0];
|
||||
zType = azArg[1];
|
||||
zSql = azArg[2];
|
||||
dataOnly = (p->shellFlgs & SHFLG_DumpDataOnly)!=0;
|
||||
noSys = (p->shellFlgs & SHFLG_DumpNoSys)!=0;
|
||||
|
||||
if( strcmp(zTable, "sqlite_sequence")==0 ){
|
||||
raw_printf(p->out, "DELETE FROM sqlite_sequence;\n");
|
||||
}else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
|
||||
raw_printf(p->out, "ANALYZE sqlite_schema;\n");
|
||||
if( strcmp(zTable, "sqlite_sequence")==0 && !noSys ){
|
||||
if( !dataOnly ) raw_printf(p->out, "DELETE FROM sqlite_sequence;\n");
|
||||
}else if( sqlite3_strglob("sqlite_stat?", zTable)==0 && !noSys ){
|
||||
if( !dataOnly ) raw_printf(p->out, "ANALYZE sqlite_schema;\n");
|
||||
}else if( strncmp(zTable, "sqlite_", 7)==0 ){
|
||||
return 0;
|
||||
}else if( dataOnly ){
|
||||
/* no-op */
|
||||
}else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
|
||||
char *zIns;
|
||||
if( !p->writableSchema ){
|
||||
@@ -3890,8 +3897,10 @@ static const char *(azHelp[]) = {
|
||||
".dbinfo ?DB? Show status information about the database",
|
||||
".dump ?TABLE? Render database content as SQL",
|
||||
" Options:",
|
||||
" --preserve-rowids Include ROWID values in the output",
|
||||
" --data-only Output only INSERT statements",
|
||||
" --newlines Allow unescaped newline characters in output",
|
||||
" --nosys Omit system tables (ex: \"sqlite_stat1\")",
|
||||
" --preserve-rowids Include ROWID values in the output",
|
||||
" TABLE is a LIKE pattern for the tables to dump",
|
||||
" Additional LIKE patterns can be given in subsequent arguments",
|
||||
".echo on|off Turn command echo on or off",
|
||||
@@ -4016,8 +4025,9 @@ static const char *(azHelp[]) = {
|
||||
".save FILE Write in-memory database into FILE",
|
||||
".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off",
|
||||
".schema ?PATTERN? Show the CREATE statements matching PATTERN",
|
||||
" Options:",
|
||||
" --indent Try to pretty-print the schema",
|
||||
" Options:",
|
||||
" --indent Try to pretty-print the schema",
|
||||
" --nosys Omit objects whose names start with \"sqlite_\"",
|
||||
".selftest ?OPTIONS? Run tests defined in the SELFTEST table",
|
||||
" Options:",
|
||||
" --init Create a new SELFTEST table",
|
||||
@@ -4426,6 +4436,19 @@ static void shellIdQuote(
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Scalar function "usleep(X)" invokes sqlite3_sleep(X) and returns X.
|
||||
*/
|
||||
static void shellUSleepFunc(
|
||||
sqlite3_context *context,
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
int sleep = sqlite3_value_int(argv[0]);
|
||||
sqlite3_sleep(sleep/1000);
|
||||
sqlite3_result_int(context, sleep);
|
||||
}
|
||||
|
||||
/*
|
||||
** Scalar function "shell_escape_crnl" used by the .recover command.
|
||||
** The argument passed to this function is the output of built-in
|
||||
@@ -4590,6 +4613,7 @@ static void open_db(ShellState *p, int openFlags){
|
||||
sqlite3_uint_init(p->db, 0, 0);
|
||||
sqlite3_decimal_init(p->db, 0, 0);
|
||||
sqlite3_ieee_init(p->db, 0, 0);
|
||||
sqlite3_series_init(p->db, 0, 0);
|
||||
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
|
||||
sqlite3_dbdata_init(p->db, 0, 0);
|
||||
#endif
|
||||
@@ -4609,6 +4633,8 @@ static void open_db(ShellState *p, int openFlags){
|
||||
shellInt32, 0, 0);
|
||||
sqlite3_create_function(p->db, "shell_idquote", 1, SQLITE_UTF8, 0,
|
||||
shellIdQuote, 0, 0);
|
||||
sqlite3_create_function(p->db, "usleep",1,SQLITE_UTF8,0,
|
||||
shellUSleepFunc, 0, 0);
|
||||
#ifndef SQLITE_NOHAVE_SYSTEM
|
||||
sqlite3_create_function(p->db, "edit", 1, SQLITE_UTF8, 0,
|
||||
editFunc, 0, 0);
|
||||
@@ -7583,21 +7609,41 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}else
|
||||
|
||||
if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
|
||||
ShellState data;
|
||||
char *zErrMsg = 0;
|
||||
char **azName = 0;
|
||||
int nName = 0;
|
||||
sqlite3_stmt *pStmt;
|
||||
int i;
|
||||
open_db(p, 0);
|
||||
memcpy(&data, p, sizeof(data));
|
||||
data.showHeader = 0;
|
||||
data.cMode = data.mode = MODE_List;
|
||||
sqlite3_snprintf(sizeof(data.colSeparator),data.colSeparator,": ");
|
||||
data.cnt = 0;
|
||||
sqlite3_exec(p->db, "SELECT name, file FROM pragma_database_list",
|
||||
callback, &data, &zErrMsg);
|
||||
if( zErrMsg ){
|
||||
utf8_printf(stderr,"Error: %s\n", zErrMsg);
|
||||
sqlite3_free(zErrMsg);
|
||||
rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
|
||||
if( rc ){
|
||||
utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
|
||||
rc = 1;
|
||||
}else{
|
||||
while( sqlite3_step(pStmt)==SQLITE_ROW ){
|
||||
const char *zSchema = (const char *)sqlite3_column_text(pStmt,1);
|
||||
const char *zFile = (const char*)sqlite3_column_text(pStmt,2);
|
||||
azName = sqlite3_realloc(azName, (nName+1)*2*sizeof(char*));
|
||||
if( azName==0 ){ shell_out_of_memory(); /* Does not return */ }
|
||||
azName[nName*2] = strdup(zSchema);
|
||||
azName[nName*2+1] = strdup(zFile);
|
||||
nName++;
|
||||
}
|
||||
}
|
||||
sqlite3_finalize(pStmt);
|
||||
for(i=0; i<nName; i++){
|
||||
int eTxn = sqlite3_txn_state(p->db, azName[i*2]);
|
||||
int bRdonly = sqlite3_db_readonly(p->db, azName[i*2]);
|
||||
const char *z = azName[i*2+1];
|
||||
utf8_printf(p->out, "%s: %s %s%s\n",
|
||||
azName[i*2],
|
||||
z && z[0] ? z : "\"\"",
|
||||
bRdonly ? "r/o" : "r/w",
|
||||
eTxn==SQLITE_TXN_NONE ? "" :
|
||||
eTxn==SQLITE_TXN_READ ? " read-txn" : " write-txn");
|
||||
free(azName[i*2]);
|
||||
free(azName[i*2+1]);
|
||||
}
|
||||
sqlite3_free(azName);
|
||||
}else
|
||||
|
||||
if( c=='d' && n>=3 && strncmp(azArg[0], "dbconfig", n)==0 ){
|
||||
@@ -7656,7 +7702,9 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
int i;
|
||||
int savedShowHeader = p->showHeader;
|
||||
int savedShellFlags = p->shellFlgs;
|
||||
ShellClearFlag(p, SHFLG_PreserveRowid|SHFLG_Newlines|SHFLG_Echo);
|
||||
ShellClearFlag(p,
|
||||
SHFLG_PreserveRowid|SHFLG_Newlines|SHFLG_Echo
|
||||
|SHFLG_DumpDataOnly|SHFLG_DumpNoSys);
|
||||
for(i=1; i<nArg; i++){
|
||||
if( azArg[i][0]=='-' ){
|
||||
const char *z = azArg[i]+1;
|
||||
@@ -7675,6 +7723,12 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
if( strcmp(z,"newlines")==0 ){
|
||||
ShellSetFlag(p, SHFLG_Newlines);
|
||||
}else
|
||||
if( strcmp(z,"data-only")==0 ){
|
||||
ShellSetFlag(p, SHFLG_DumpDataOnly);
|
||||
}else
|
||||
if( strcmp(z,"nosys")==0 ){
|
||||
ShellSetFlag(p, SHFLG_DumpNoSys);
|
||||
}else
|
||||
{
|
||||
raw_printf(stderr, "Unknown option \"%s\" on \".dump\"\n", azArg[i]);
|
||||
rc = 1;
|
||||
@@ -7691,11 +7745,13 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
|
||||
open_db(p, 0);
|
||||
|
||||
/* When playing back a "dump", the content might appear in an order
|
||||
** which causes immediate foreign key constraints to be violated.
|
||||
** So disable foreign-key constraint enforcement to prevent problems. */
|
||||
raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n");
|
||||
raw_printf(p->out, "BEGIN TRANSACTION;\n");
|
||||
if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){
|
||||
/* When playing back a "dump", the content might appear in an order
|
||||
** which causes immediate foreign key constraints to be violated.
|
||||
** So disable foreign-key constraint enforcement to prevent problems. */
|
||||
raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n");
|
||||
raw_printf(p->out, "BEGIN TRANSACTION;\n");
|
||||
}
|
||||
p->writableSchema = 0;
|
||||
p->showHeader = 0;
|
||||
/* Set writable_schema=ON since doing so forces SQLite to initialize
|
||||
@@ -7713,14 +7769,16 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
);
|
||||
run_schema_dump_query(p,zSql);
|
||||
sqlite3_free(zSql);
|
||||
zSql = sqlite3_mprintf(
|
||||
"SELECT sql FROM sqlite_schema "
|
||||
"WHERE (%s) AND sql NOT NULL"
|
||||
" AND type IN ('index','trigger','view')",
|
||||
zLike
|
||||
);
|
||||
run_table_dump_query(p, zSql);
|
||||
sqlite3_free(zSql);
|
||||
if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){
|
||||
zSql = sqlite3_mprintf(
|
||||
"SELECT sql FROM sqlite_schema "
|
||||
"WHERE (%s) AND sql NOT NULL"
|
||||
" AND type IN ('index','trigger','view')",
|
||||
zLike
|
||||
);
|
||||
run_table_dump_query(p, zSql);
|
||||
sqlite3_free(zSql);
|
||||
}
|
||||
sqlite3_free(zLike);
|
||||
if( p->writableSchema ){
|
||||
raw_printf(p->out, "PRAGMA writable_schema=OFF;\n");
|
||||
@@ -7728,7 +7786,9 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}
|
||||
sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
|
||||
sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
|
||||
raw_printf(p->out, p->nErr?"ROLLBACK; -- due to errors\n":"COMMIT;\n");
|
||||
if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){
|
||||
raw_printf(p->out, p->nErr?"ROLLBACK; -- due to errors\n":"COMMIT;\n");
|
||||
}
|
||||
p->showHeader = savedShowHeader;
|
||||
p->shellFlgs = savedShellFlags;
|
||||
}else
|
||||
@@ -8167,7 +8227,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
while( (nSkip--)>0 ){
|
||||
while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){}
|
||||
}
|
||||
zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
|
||||
zSql = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
|
||||
if( zSql==0 ){
|
||||
import_cleanup(&sCtx);
|
||||
shell_out_of_memory();
|
||||
@@ -8176,7 +8236,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
|
||||
import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
|
||||
if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
|
||||
char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
|
||||
char *zCreate = sqlite3_mprintf("CREATE TABLE \"%w\"", zTable);
|
||||
char cSep = '(';
|
||||
while( xRead(&sCtx) ){
|
||||
zCreate = sqlite3_mprintf("%z%c\n \"%w\" TEXT", zCreate, cSep, sCtx.z);
|
||||
@@ -8197,7 +8257,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
|
||||
sqlite3_free(zCreate);
|
||||
if( rc ){
|
||||
utf8_printf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
|
||||
utf8_printf(stderr, "CREATE TABLE \"%s\"(...) failed: %s\n", zTable,
|
||||
sqlite3_errmsg(p->db));
|
||||
import_cleanup(&sCtx);
|
||||
rc = 1;
|
||||
@@ -8962,9 +9022,16 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}
|
||||
if( notNormalFile(azArg[1])
|
||||
|| (p->in = fopen(azArg[1], "rb"))==0
|
||||
){
|
||||
if( azArg[1][0]=='|' ){
|
||||
p->in = popen(azArg[1]+1, "r");
|
||||
if( p->in==0 ){
|
||||
utf8_printf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
|
||||
rc = 1;
|
||||
}else{
|
||||
rc = process_input(p);
|
||||
pclose(p->in);
|
||||
}
|
||||
}else if( notNormalFile(azArg[1]) || (p->in = fopen(azArg[1], "rb"))==0 ){
|
||||
utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
|
||||
rc = 1;
|
||||
}else{
|
||||
@@ -9046,6 +9113,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
const char *zName = 0;
|
||||
int iSchema = 0;
|
||||
int bDebug = 0;
|
||||
int bNoSystemTabs = 0;
|
||||
int ii;
|
||||
|
||||
open_db(p, 0);
|
||||
@@ -9058,10 +9126,16 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
data.cMode = data.mode = MODE_Pretty;
|
||||
}else if( optionMatch(azArg[ii],"debug") ){
|
||||
bDebug = 1;
|
||||
}else if( optionMatch(azArg[ii],"nosys") ){
|
||||
bNoSystemTabs = 1;
|
||||
}else if( azArg[ii][0]=='-' ){
|
||||
utf8_printf(stderr, "Unknown option: \"%s\"\n", azArg[ii]);
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}else if( zName==0 ){
|
||||
zName = azArg[ii];
|
||||
}else{
|
||||
raw_printf(stderr, "Usage: .schema ?--indent? ?LIKE-PATTERN?\n");
|
||||
raw_printf(stderr, "Usage: .schema ?--indent? ?--nosys? ?LIKE-PATTERN?\n");
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}
|
||||
@@ -9147,7 +9221,10 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
appendText(&sSelect, " AND ", 0);
|
||||
sqlite3_free(zQarg);
|
||||
}
|
||||
appendText(&sSelect, "type!='meta' AND sql IS NOT NULL"
|
||||
if( bNoSystemTabs ){
|
||||
appendText(&sSelect, "name NOT LIKE 'sqlite_%%' AND ", 0);
|
||||
}
|
||||
appendText(&sSelect, "sql IS NOT NULL"
|
||||
" ORDER BY snum, rowid", 0);
|
||||
if( bDebug ){
|
||||
utf8_printf(p->out, "SQL: %s;\n", sSelect.z);
|
||||
@@ -9844,6 +9921,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
{ "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE, "" },
|
||||
{ "prng_save", SQLITE_TESTCTRL_PRNG_SAVE, "" },
|
||||
{ "prng_seed", SQLITE_TESTCTRL_PRNG_SEED, "SEED ?db?" },
|
||||
{ "seek_count", SQLITE_TESTCTRL_SEEK_COUNT, "" },
|
||||
};
|
||||
int testctrl = -1;
|
||||
int iCtrl = -1;
|
||||
@@ -9906,7 +9984,6 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
/* sqlite3_test_control(int) */
|
||||
case SQLITE_TESTCTRL_PRNG_SAVE:
|
||||
case SQLITE_TESTCTRL_PRNG_RESTORE:
|
||||
case SQLITE_TESTCTRL_PRNG_RESET:
|
||||
case SQLITE_TESTCTRL_BYTEORDER:
|
||||
if( nArg==2 ){
|
||||
rc2 = sqlite3_test_control(testctrl);
|
||||
@@ -9980,6 +10057,14 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}
|
||||
break;
|
||||
|
||||
case SQLITE_TESTCTRL_SEEK_COUNT: {
|
||||
u64 x = 0;
|
||||
rc2 = sqlite3_test_control(testctrl, p->db, &x);
|
||||
utf8_printf(p->out, "%llu\n", x);
|
||||
isOk = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef YYCOVERAGE
|
||||
case SQLITE_TESTCTRL_PARSER_COVERAGE:
|
||||
if( nArg==2 ){
|
||||
@@ -10875,11 +10960,14 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
|
||||
(void)cmdline_option_value(argc, argv, ++i);
|
||||
#endif
|
||||
}else if( strcmp(z,"-pagecache")==0 ){
|
||||
int n, sz;
|
||||
sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
|
||||
sqlite3_int64 n, sz;
|
||||
sz = integerValue(cmdline_option_value(argc,argv,++i));
|
||||
if( sz>70000 ) sz = 70000;
|
||||
if( sz<0 ) sz = 0;
|
||||
n = (int)integerValue(cmdline_option_value(argc,argv,++i));
|
||||
n = integerValue(cmdline_option_value(argc,argv,++i));
|
||||
if( sz>0 && n>0 && 0xffffffffffffLL/sz<n ){
|
||||
n = 0xffffffffffffLL/sz;
|
||||
}
|
||||
sqlite3_config(SQLITE_CONFIG_PAGECACHE,
|
||||
(n>0 && sz>0) ? malloc(n*sz) : 0, sz, n);
|
||||
data.shellFlgs |= SHFLG_Pagecache;
|
||||
@@ -11015,6 +11103,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
|
||||
data.mode = MODE_List;
|
||||
}else if( strcmp(z,"-quote")==0 ){
|
||||
data.mode = MODE_Quote;
|
||||
sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, SEP_Comma);
|
||||
sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, SEP_Row);
|
||||
}else if( strcmp(z,"-line")==0 ){
|
||||
data.mode = MODE_Line;
|
||||
}else if( strcmp(z,"-column")==0 ){
|
||||
|
||||
+66
-4
@@ -6186,6 +6186,57 @@ const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName);
|
||||
*/
|
||||
int sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Determine the transaction state of a database
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^The sqlite3_txn_state(D,S) interface returns the current
|
||||
** [transaction state] of schema S in database connection D. ^If S is NULL,
|
||||
** then the highest transaction state of any schema on databse connection D
|
||||
** is returned. Transaction states are (in order of lowest to highest):
|
||||
** <ol>
|
||||
** <li value="0"> SQLITE_TXN_NONE
|
||||
** <li value="1"> SQLITE_TXN_READ
|
||||
** <li value="2"> SQLITE_TXN_WRITE
|
||||
** </ol>
|
||||
** ^If the S argument to sqlite3_txn_state(D,S) is not the name of
|
||||
** a valid schema, then -1 is returned.
|
||||
*/
|
||||
int sqlite3_txn_state(sqlite3*,const char *zSchema);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Allowed return values from [sqlite3_txn_state()]
|
||||
** KEYWORDS: {transaction state}
|
||||
**
|
||||
** These constants define the current transaction state of a database file.
|
||||
** ^The [sqlite3_txn_state(D,S)] interface returns one of these
|
||||
** constants in order to describe the transaction state of schema S
|
||||
** in [database connection] D.
|
||||
**
|
||||
** <dl>
|
||||
** [[SQLITE_TXN_NONE]] <dt>SQLITE_TXN_NONE</dt>
|
||||
** <dd>The SQLITE_TXN_NONE state means that no transaction is currently
|
||||
** pending.</dd>
|
||||
**
|
||||
** [[SQLITE_TXN_READ]] <dt>SQLITE_TXN_READ</dt>
|
||||
** <dd>The SQLITE_TXN_READ state means that the database is currently
|
||||
** in a read transaction. Content has been read from the database file
|
||||
** but nothing in the database file has changed. The transaction state
|
||||
** will advanced to SQLITE_TXN_WRITE if any changes occur and there are
|
||||
** no other conflicting concurrent write transactions. The transaction
|
||||
** state will revert to SQLITE_TXN_NONE following a [ROLLBACK] or
|
||||
** [COMMIT].</dd>
|
||||
**
|
||||
** [[SQLITE_TXN_WRITE]] <dt>SQLITE_TXN_WRITE</dt>
|
||||
** <dd>The SQLITE_TXN_WRITE state means that the database is currently
|
||||
** in a write transaction. Content has been written to the database file
|
||||
** but has not yet committed. The transaction state will change to
|
||||
** to SQLITE_TXN_NONE at the next [ROLLBACK] or [COMMIT].</dd>
|
||||
*/
|
||||
#define SQLITE_TXN_NONE 0
|
||||
#define SQLITE_TXN_READ 1
|
||||
#define SQLITE_TXN_WRITE 2
|
||||
|
||||
/*
|
||||
** CAPI3REF: Find the next prepared statement
|
||||
** METHOD: sqlite3
|
||||
@@ -7688,6 +7739,7 @@ int sqlite3_test_control(int op, ...);
|
||||
#define SQLITE_TESTCTRL_PRNG_SAVE 5
|
||||
#define SQLITE_TESTCTRL_PRNG_RESTORE 6
|
||||
#define SQLITE_TESTCTRL_PRNG_RESET 7 /* NOT USED */
|
||||
#define SQLITE_TESTCTRL_SEEK_COUNT 7
|
||||
#define SQLITE_TESTCTRL_BITVEC_TEST 8
|
||||
#define SQLITE_TESTCTRL_FAULT_INSTALL 9
|
||||
#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10
|
||||
@@ -9192,10 +9244,11 @@ int sqlite3_vtab_on_conflict(sqlite3 *);
|
||||
** CAPI3REF: Determine If Virtual Table Column Access Is For UPDATE
|
||||
**
|
||||
** If the sqlite3_vtab_nochange(X) routine is called within the [xColumn]
|
||||
** method of a [virtual table], then it returns true if and only if the
|
||||
** method of a [virtual table], then it might return true if the
|
||||
** column is being fetched as part of an UPDATE operation during which the
|
||||
** column value will not change. Applications might use this to substitute
|
||||
** a return value that is less expensive to compute and that the corresponding
|
||||
** column value will not change. The virtual table implementation can use
|
||||
** this hint as permission to substitute a return value that is less
|
||||
** expensive to compute and that the corresponding
|
||||
** [xUpdate] method understands as a "no-change" value.
|
||||
**
|
||||
** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that
|
||||
@@ -9204,6 +9257,12 @@ int sqlite3_vtab_on_conflict(sqlite3 *);
|
||||
** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces].
|
||||
** In that case, [sqlite3_value_nochange(X)] will return true for the
|
||||
** same column in the [xUpdate] method.
|
||||
**
|
||||
** The sqlite3_vtab_nochange() routine is an optimization. Virtual table
|
||||
** implementations should continue to give a correct answer even if the
|
||||
** sqlite3_vtab_nochange() interface were to always return false. In the
|
||||
** current implementation, the sqlite3_vtab_nochange() interface does always
|
||||
** returns false for the enhanced [UPDATE FROM] statement.
|
||||
*/
|
||||
int sqlite3_vtab_nochange(sqlite3_context*);
|
||||
|
||||
@@ -9345,6 +9404,7 @@ void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Flush caches to disk mid-transaction
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^If a write-transaction is open on [database connection] D when the
|
||||
** [sqlite3_db_cacheflush(D)] interface invoked, any dirty
|
||||
@@ -9377,6 +9437,7 @@ int sqlite3_db_cacheflush(sqlite3*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: The pre-update hook.
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^These interfaces are only available if SQLite is compiled using the
|
||||
** [SQLITE_ENABLE_PREUPDATE_HOOK] compile-time option.
|
||||
@@ -9417,7 +9478,7 @@ int sqlite3_db_cacheflush(sqlite3*);
|
||||
** seventh parameter is the final rowid value of the row being inserted
|
||||
** or updated. The value of the seventh parameter passed to the callback
|
||||
** function is not defined for operations on WITHOUT ROWID tables, or for
|
||||
** INSERT operations on rowid tables.
|
||||
** DELETE operations on rowid tables.
|
||||
**
|
||||
** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()],
|
||||
** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces
|
||||
@@ -9479,6 +9540,7 @@ int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Low-level system error code
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^Attempt to return the underlying operating system error code or error
|
||||
** number that caused the most recent I/O error or failure to open a file.
|
||||
|
||||
+21
-13
@@ -17,15 +17,16 @@
|
||||
|
||||
/* Special Comments:
|
||||
**
|
||||
** Some comments have special meaning to the tools that measure test
|
||||
** coverage:
|
||||
** Some comments have special meaning to the external tools that measure test
|
||||
** coverage of conditional brances (MC/DC testing, described in
|
||||
** https://en.wikipedia.org/wiki/Modified_condition/decision_coverage ).
|
||||
**
|
||||
** NO_TEST - The branches on this line are not
|
||||
** measured by branch coverage. This is
|
||||
** used on lines of code that actually
|
||||
** implement parts of coverage testing.
|
||||
**
|
||||
** OPTIMIZATION-IF-TRUE - This branch is allowed to alway be false
|
||||
** OPTIMIZATION-IF-TRUE - This branch is allowed to always be false
|
||||
** and the correct answer is still obtained,
|
||||
** though perhaps more slowly.
|
||||
**
|
||||
@@ -35,7 +36,11 @@
|
||||
**
|
||||
** PREVENTS-HARMLESS-OVERREAD - This branch prevents a buffer overread
|
||||
** that would be harmless and undetectable
|
||||
** if it did occur.
|
||||
** if it did occur.
|
||||
**
|
||||
** The OPTIMIZATION-* comments above are for mutation testing as described in
|
||||
** https://en.wikipedia.org/wiki/Mutation_testing and
|
||||
** https://www.sqlite.org/testing.html#mutationtests .
|
||||
**
|
||||
** In all cases, the special comment must be enclosed in the usual
|
||||
** slash-asterisk...asterisk-slash comment marks, with no spaces between the
|
||||
@@ -2187,6 +2192,7 @@ struct Table {
|
||||
#define TF_OOOHidden 0x0400 /* Out-of-Order hidden columns */
|
||||
#define TF_HasNotNull 0x0800 /* Contains NOT NULL constraints */
|
||||
#define TF_Shadow 0x1000 /* True for a shadow table */
|
||||
#define TF_HasStat4 0x2000 /* STAT4 info available for this table */
|
||||
|
||||
/*
|
||||
** Test to see whether or not a table is a virtual table. This is
|
||||
@@ -2715,7 +2721,7 @@ struct Expr {
|
||||
#define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */
|
||||
#define EP_Win 0x008000 /* Contains window functions */
|
||||
#define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */
|
||||
/* 0x020000 // available for reuse */
|
||||
#define EP_IfNullRow 0x020000 /* The TK_IF_NULL_ROW opcode */
|
||||
#define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */
|
||||
#define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
|
||||
#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
|
||||
@@ -3152,9 +3158,6 @@ struct Select {
|
||||
** statements within triggers whose only purpose is
|
||||
** the side-effects of functions.
|
||||
**
|
||||
** All of the above are free to ignore their ORDER BY clause. Those that
|
||||
** follow must honor the ORDER BY clause.
|
||||
**
|
||||
** SRT_Output Generate a row of output (using the OP_ResultRow
|
||||
** opcode) for each row in the result set.
|
||||
**
|
||||
@@ -3211,13 +3214,18 @@ struct Select {
|
||||
#define SRT_Except 2 /* Remove result from a UNION index */
|
||||
#define SRT_Exists 3 /* Store 1 if the result is not empty */
|
||||
#define SRT_Discard 4 /* Do not save the results anywhere */
|
||||
#define SRT_Fifo 5 /* Store result as data with an automatic rowid */
|
||||
#define SRT_DistFifo 6 /* Like SRT_Fifo, but unique results only */
|
||||
#define SRT_DistFifo 5 /* Like SRT_Fifo, but unique results only */
|
||||
#define SRT_DistQueue 6 /* Like SRT_Queue, but unique results only */
|
||||
|
||||
/* The DISTINCT clause is ignored for all of the above. Not that
|
||||
** IgnorableDistinct() implies IgnorableOrderby() */
|
||||
#define IgnorableDistinct(X) ((X->eDest)<=SRT_DistQueue)
|
||||
|
||||
#define SRT_Queue 7 /* Store result in an queue */
|
||||
#define SRT_DistQueue 8 /* Like SRT_Queue, but unique results only */
|
||||
#define SRT_Fifo 8 /* Store result as data with an automatic rowid */
|
||||
|
||||
/* The ORDER BY clause is ignored for all of the above */
|
||||
#define IgnorableOrderby(X) ((X->eDest)<=SRT_DistQueue)
|
||||
#define IgnorableOrderby(X) ((X->eDest)<=SRT_Fifo)
|
||||
|
||||
#define SRT_Output 9 /* Output each row of result */
|
||||
#define SRT_Mem 10 /* Store result in a memory cell */
|
||||
@@ -4184,7 +4192,7 @@ void sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int);
|
||||
void sqlite3AddColumn(Parse*,Token*,Token*);
|
||||
void sqlite3AddNotNull(Parse*, int);
|
||||
void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int);
|
||||
void sqlite3AddCheckConstraint(Parse*, Expr*);
|
||||
void sqlite3AddCheckConstraint(Parse*, Expr*, const char*, const char*);
|
||||
void sqlite3AddDefaultValue(Parse*,Expr*,const char*,const char*);
|
||||
void sqlite3AddCollateType(Parse*, Token*);
|
||||
void sqlite3AddGenerated(Parse*,Expr*,Token*);
|
||||
|
||||
+1
-5
@@ -60,11 +60,7 @@
|
||||
** The maximum depth of an expression tree. This is limited to
|
||||
** some extent by SQLITE_MAX_SQL_LENGTH. But sometime you might
|
||||
** want to place more severe limits on the complexity of an
|
||||
** expression.
|
||||
**
|
||||
** A value of 0 used to mean that the limit was not enforced.
|
||||
** But that is no longer true. The limit is now strictly enforced
|
||||
** at all times.
|
||||
** expression. A value of 0 means that there is no limit.
|
||||
*/
|
||||
#ifndef SQLITE_MAX_EXPR_DEPTH
|
||||
# define SQLITE_MAX_EXPR_DEPTH 1000
|
||||
|
||||
+28
@@ -7749,6 +7749,33 @@ static int SQLITE_TCLAPI test_sqlite3_db_config(
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(v));
|
||||
return TCL_OK;
|
||||
}
|
||||
/*
|
||||
** tclcmd: sqlite3_txn_state DB ?SCHEMA?
|
||||
**
|
||||
** Invoke sqlite3_txn_state(DB,SCHEMA) and return the
|
||||
** numeric value that results. Use NULL for SCHEMA if the 3 argument
|
||||
** is omitted.
|
||||
*/
|
||||
static int SQLITE_TCLAPI test_sqlite3_txn_state(
|
||||
void *clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
sqlite3 *db;
|
||||
const char *zSchema;
|
||||
int iTxn;
|
||||
|
||||
if( objc!=2 && objc!=3 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "DB ?SCHEMA?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
|
||||
zSchema = objc==3 ? Tcl_GetString(objv[2]) : 0;
|
||||
iTxn = sqlite3_txn_state(db, zSchema);
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(iTxn));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Change the name of the main database schema from "main" to "icecube".
|
||||
@@ -7985,6 +8012,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
void *clientData;
|
||||
} aObjCmd[] = {
|
||||
{ "sqlite3_db_config", test_sqlite3_db_config, 0 },
|
||||
{ "sqlite3_txn_state", test_sqlite3_txn_state, 0 },
|
||||
{ "bad_behavior", test_bad_behavior, (void*)&iZero },
|
||||
{ "register_dbstat_vtab", test_register_dbstat_vtab },
|
||||
{ "sqlite3_connection_pointer", get_sqlite_pointer, 0 },
|
||||
|
||||
+8
-4
@@ -550,13 +550,16 @@ static int cfDeviceCharacteristics(sqlite3_file *pFile){
|
||||
** Pass-throughs for WAL support.
|
||||
*/
|
||||
static int cfShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
|
||||
return sqlite3OsShmLock(((CrashFile*)pFile)->pRealFile, ofst, n, flags);
|
||||
sqlite3_file *pReal = ((CrashFile*)pFile)->pRealFile;
|
||||
return pReal->pMethods->xShmLock(pReal, ofst, n, flags);
|
||||
}
|
||||
static void cfShmBarrier(sqlite3_file *pFile){
|
||||
sqlite3OsShmBarrier(((CrashFile*)pFile)->pRealFile);
|
||||
sqlite3_file *pReal = ((CrashFile*)pFile)->pRealFile;
|
||||
pReal->pMethods->xShmBarrier(pReal);
|
||||
}
|
||||
static int cfShmUnmap(sqlite3_file *pFile, int delFlag){
|
||||
return sqlite3OsShmUnmap(((CrashFile*)pFile)->pRealFile, delFlag);
|
||||
sqlite3_file *pReal = ((CrashFile*)pFile)->pRealFile;
|
||||
return pReal->pMethods->xShmUnmap(pReal, delFlag);
|
||||
}
|
||||
static int cfShmMap(
|
||||
sqlite3_file *pFile, /* Handle open on database file */
|
||||
@@ -565,7 +568,8 @@ static int cfShmMap(
|
||||
int w, /* True to extend file if necessary */
|
||||
void volatile **pp /* OUT: Mapped memory */
|
||||
){
|
||||
return sqlite3OsShmMap(((CrashFile*)pFile)->pRealFile, iRegion, sz, w, pp);
|
||||
sqlite3_file *pReal = ((CrashFile*)pFile)->pRealFile;
|
||||
return pReal->pMethods->xShmMap(pReal, iRegion, sz, w, pp);
|
||||
}
|
||||
|
||||
static const sqlite3_io_methods CrashFileVtab = {
|
||||
|
||||
+4
-4
@@ -191,7 +191,7 @@ static int devsymDeviceCharacteristics(sqlite3_file *pFile){
|
||||
*/
|
||||
static int devsymShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
|
||||
devsym_file *p = (devsym_file *)pFile;
|
||||
return sqlite3OsShmLock(p->pReal, ofst, n, flags);
|
||||
return p->pReal->pMethods->xShmLock(p->pReal, ofst, n, flags);
|
||||
}
|
||||
static int devsymShmMap(
|
||||
sqlite3_file *pFile,
|
||||
@@ -201,15 +201,15 @@ static int devsymShmMap(
|
||||
void volatile **pp
|
||||
){
|
||||
devsym_file *p = (devsym_file *)pFile;
|
||||
return sqlite3OsShmMap(p->pReal, iRegion, szRegion, isWrite, pp);
|
||||
return p->pReal->pMethods->xShmMap(p->pReal, iRegion, szRegion, isWrite, pp);
|
||||
}
|
||||
static void devsymShmBarrier(sqlite3_file *pFile){
|
||||
devsym_file *p = (devsym_file *)pFile;
|
||||
sqlite3OsShmBarrier(p->pReal);
|
||||
p->pReal->pMethods->xShmBarrier(p->pReal);
|
||||
}
|
||||
static int devsymShmUnmap(sqlite3_file *pFile, int delFlag){
|
||||
devsym_file *p = (devsym_file *)pFile;
|
||||
return sqlite3OsShmUnmap(p->pReal, delFlag);
|
||||
return p->pReal->pMethods->xShmUnmap(p->pReal, delFlag);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+3
-3
@@ -168,7 +168,7 @@ static int SQLITE_TCLAPI hexio_write(
|
||||
if( Tcl_GetIntFromObj(interp, objv[2], &offset) ) return TCL_ERROR;
|
||||
zFile = Tcl_GetString(objv[1]);
|
||||
zIn = (const unsigned char *)Tcl_GetStringFromObj(objv[3], &nIn);
|
||||
aOut = sqlite3_malloc( nIn/2 );
|
||||
aOut = sqlite3_malloc( 1 + nIn/2 );
|
||||
if( aOut==0 ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -213,7 +213,7 @@ static int SQLITE_TCLAPI hexio_get_int(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
zIn = (const unsigned char *)Tcl_GetStringFromObj(objv[1], &nIn);
|
||||
aOut = sqlite3_malloc( nIn/2 );
|
||||
aOut = sqlite3_malloc( 1 + nIn/2 );
|
||||
if( aOut==0 ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -309,7 +309,7 @@ static int SQLITE_TCLAPI utf8_to_utf8(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
zOrig = (unsigned char *)Tcl_GetStringFromObj(objv[1], &n);
|
||||
z = sqlite3_malloc( n+3 );
|
||||
z = sqlite3_malloc( n+4 );
|
||||
n = sqlite3TestHexToBin(zOrig, n, z);
|
||||
z[n] = 0;
|
||||
nOut = sqlite3Utf8To8(z);
|
||||
|
||||
+8
-4
@@ -895,7 +895,8 @@ static int tvfsShmMap(
|
||||
Testvfs *p = (Testvfs *)(pFd->pVfs->pAppData);
|
||||
|
||||
if( p->isFullshm ){
|
||||
return sqlite3OsShmMap(pFd->pReal, iPage, pgsz, isWrite, pp);
|
||||
sqlite3_file *pReal = pFd->pReal;
|
||||
return pReal->pMethods->xShmMap(pReal, iPage, pgsz, isWrite, pp);
|
||||
}
|
||||
|
||||
if( 0==pFd->pShm ){
|
||||
@@ -945,7 +946,8 @@ static int tvfsShmLock(
|
||||
char zLock[80];
|
||||
|
||||
if( p->isFullshm ){
|
||||
return sqlite3OsShmLock(pFd->pReal, ofst, n, flags);
|
||||
sqlite3_file *pReal = pFd->pReal;
|
||||
return pReal->pMethods->xShmLock(pReal, ofst, n, flags);
|
||||
}
|
||||
|
||||
if( p->pScript && p->mask&TESTVFS_SHMLOCK_MASK ){
|
||||
@@ -1009,7 +1011,8 @@ static void tvfsShmBarrier(sqlite3_file *pFile){
|
||||
}
|
||||
|
||||
if( p->isFullshm ){
|
||||
sqlite3OsShmBarrier(pFd->pReal);
|
||||
sqlite3_file *pReal = pFd->pReal;
|
||||
pReal->pMethods->xShmBarrier(pReal);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1025,7 +1028,8 @@ static int tvfsShmUnmap(
|
||||
TestvfsFd **ppFd;
|
||||
|
||||
if( p->isFullshm ){
|
||||
return sqlite3OsShmUnmap(pFd->pReal, deleteFlag);
|
||||
sqlite3_file *pReal = pFd->pReal;
|
||||
return pReal->pMethods->xShmUnmap(pReal, deleteFlag);
|
||||
}
|
||||
|
||||
if( !pBuffer ) return SQLITE_OK;
|
||||
|
||||
+19
-5
@@ -234,7 +234,7 @@ static void updateFromSelect(
|
||||
#endif
|
||||
pList = sqlite3ExprListAppend(pParse, pList, pNew);
|
||||
}
|
||||
eDest = SRT_Upfrom;
|
||||
eDest = IsVirtual(pTab) ? SRT_Table : SRT_Upfrom;
|
||||
}else if( pTab->pSelect ){
|
||||
for(i=0; i<pTab->nCol; i++){
|
||||
pList = sqlite3ExprListAppend(pParse, pList, exprRowColumn(pParse, i));
|
||||
@@ -1187,12 +1187,26 @@ static void updateVirtualTable(
|
||||
regArg = pParse->nMem + 1;
|
||||
pParse->nMem += nArg;
|
||||
if( pSrc->nSrc>1 ){
|
||||
Index *pPk = 0;
|
||||
Expr *pRow;
|
||||
ExprList *pList;
|
||||
if( pRowid ){
|
||||
pRow = sqlite3ExprDup(db, pRowid, 0);
|
||||
if( HasRowid(pTab) ){
|
||||
if( pRowid ){
|
||||
pRow = sqlite3ExprDup(db, pRowid, 0);
|
||||
}else{
|
||||
pRow = sqlite3PExpr(pParse, TK_ROW, 0, 0);
|
||||
}
|
||||
}else{
|
||||
pRow = sqlite3PExpr(pParse, TK_ROW, 0, 0);
|
||||
i16 iPk; /* PRIMARY KEY column */
|
||||
pPk = sqlite3PrimaryKeyIndex(pTab);
|
||||
assert( pPk!=0 );
|
||||
assert( pPk->nKeyCol==1 );
|
||||
iPk = pPk->aiColumn[0];
|
||||
if( aXRef[iPk]>=0 ){
|
||||
pRow = sqlite3ExprDup(db, pChanges->a[aXRef[iPk]].pExpr, 0);
|
||||
}else{
|
||||
pRow = exprRowColumn(pParse, iPk);
|
||||
}
|
||||
}
|
||||
pList = sqlite3ExprListAppend(pParse, 0, pRow);
|
||||
|
||||
@@ -1206,7 +1220,7 @@ static void updateVirtualTable(
|
||||
}
|
||||
}
|
||||
|
||||
updateFromSelect(pParse, ephemTab, 0, pList, pSrc, pWhere, 0, 0);
|
||||
updateFromSelect(pParse, ephemTab, pPk, pList, pSrc, pWhere, 0, 0);
|
||||
sqlite3ExprListDelete(db, pList);
|
||||
eOnePass = ONEPASS_OFF;
|
||||
}else{
|
||||
|
||||
@@ -681,6 +681,7 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
|
||||
incr = 1;
|
||||
}else{
|
||||
incr = 2;
|
||||
length &= ~1;
|
||||
assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
|
||||
for(i=3-enc; i<length && zNum[i]==0; i+=2){}
|
||||
nonNum = i<length;
|
||||
|
||||
+2
-2
@@ -339,8 +339,8 @@ SQLITE_NOINLINE int sqlite3RunVacuum(
|
||||
BTREE_APPLICATION_ID, 0, /* Preserve the application id */
|
||||
};
|
||||
|
||||
assert( 1==sqlite3BtreeIsInTrans(pTemp) );
|
||||
assert( pOut!=0 || 1==sqlite3BtreeIsInTrans(pMain) );
|
||||
assert( SQLITE_TXN_WRITE==sqlite3BtreeTxnState(pTemp) );
|
||||
assert( pOut!=0 || SQLITE_TXN_WRITE==sqlite3BtreeTxnState(pMain) );
|
||||
|
||||
/* Copy Btree meta values */
|
||||
for(i=0; i<ArraySize(aCopy); i+=2){
|
||||
|
||||
+207
-28
@@ -3487,7 +3487,8 @@ case OP_AutoCommit: {
|
||||
** active.
|
||||
** If P2 is non-zero, then a write-transaction is started, or if a
|
||||
** read-transaction is already active, it is upgraded to a write-transaction.
|
||||
** If P2 is zero, then a read-transaction is started.
|
||||
** If P2 is zero, then a read-transaction is started. If P2 is 2 or more
|
||||
** then an exclusive transaction is started.
|
||||
**
|
||||
** P1 is the index of the database file on which the transaction is
|
||||
** started. Index 0 is the main database file and index 1 is the
|
||||
@@ -3521,6 +3522,7 @@ case OP_Transaction: {
|
||||
|
||||
assert( p->bIsReader );
|
||||
assert( p->readOnly==0 || pOp->p2==0 );
|
||||
assert( pOp->p2>=0 && pOp->p2<=2 );
|
||||
assert( pOp->p1>=0 && pOp->p1<db->nDb );
|
||||
assert( DbMaskTest(p->btreeMask, pOp->p1) );
|
||||
if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){
|
||||
@@ -3546,7 +3548,7 @@ case OP_Transaction: {
|
||||
&& pOp->p2
|
||||
&& (db->autoCommit==0 || db->nVdbeRead>1)
|
||||
){
|
||||
assert( sqlite3BtreeIsInTrans(pBt) );
|
||||
assert( sqlite3BtreeTxnState(pBt)==SQLITE_TXN_WRITE );
|
||||
if( p->iStatement==0 ){
|
||||
assert( db->nStatement>=0 && db->nSavepoint>=0 );
|
||||
db->nStatement++;
|
||||
@@ -4383,22 +4385,172 @@ seek_not_found:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: SeekHit P1 P2 * * *
|
||||
** Synopsis: seekHit=P2
|
||||
|
||||
/* Opcode: SeekScan P1 P2 * * *
|
||||
** Synopsis: Scan-ahead up to P1 rows
|
||||
**
|
||||
** Set the seekHit flag on cursor P1 to the value in P2.
|
||||
** The seekHit flag is used by the IfNoHope opcode.
|
||||
** This opcode is a prefix opcode to OP_SeekGE. In other words, this
|
||||
** opcode must be immediately followed by OP_SeekGE. This constraint is
|
||||
** checked by assert() statements.
|
||||
**
|
||||
** P1 must be a valid b-tree cursor. P2 must be a boolean value,
|
||||
** either 0 or 1.
|
||||
** This opcode uses the P1 through P4 operands of the subsequent
|
||||
** OP_SeekGE. In the text that follows, the operands of the subsequent
|
||||
** OP_SeekGE opcode are denoted as SeekOP.P1 through SeekOP.P4. Only
|
||||
** the P1 and P2 operands of this opcode are also used, and are called
|
||||
** This.P1 and This.P2.
|
||||
**
|
||||
** This opcode helps to optimize IN operators on a multi-column index
|
||||
** where the IN operator is on the later terms of the index by avoiding
|
||||
** unnecessary seeks on the btree, substituting steps to the next row
|
||||
** of the b-tree instead. A correct answer is obtained if this opcode
|
||||
** is omitted or is a no-op.
|
||||
**
|
||||
** The SeekGE.P3 and SeekGE.P4 operands identify an unpacked key which
|
||||
** is the desired entry that we want the cursor SeekGE.P1 to be pointing
|
||||
** to. Call this SeekGE.P4/P5 row the "target".
|
||||
**
|
||||
** If the SeekGE.P1 cursor is not currently pointing to a valid row,
|
||||
** then this opcode is a no-op and control passes through into the OP_SeekGE.
|
||||
**
|
||||
** If the SeekGE.P1 cursor is pointing to a valid row, then that row
|
||||
** might be the target row, or it might be near and slightly before the
|
||||
** target row. This opcode attempts to position the cursor on the target
|
||||
** row by, perhaps by invoking sqlite3BtreeStep() on the cursor
|
||||
** between 0 and This.P1 times.
|
||||
**
|
||||
** There are three possible outcomes from this opcode:<ol>
|
||||
**
|
||||
** <li> If after This.P1 steps, the cursor is still point to a place that
|
||||
** is earlier in the btree than the target row,
|
||||
** then fall through into the subsquence OP_SeekGE opcode.
|
||||
**
|
||||
** <li> If the cursor is successfully moved to the target row by 0 or more
|
||||
** sqlite3BtreeNext() calls, then jump to This.P2, which will land just
|
||||
** past the OP_IdxGT opcode that follows the OP_SeekGE.
|
||||
**
|
||||
** <li> If the cursor ends up past the target row (indicating the the target
|
||||
** row does not exist in the btree) then jump to SeekOP.P2.
|
||||
** </ol>
|
||||
*/
|
||||
case OP_SeekScan: {
|
||||
VdbeCursor *pC;
|
||||
int res;
|
||||
int nStep;
|
||||
UnpackedRecord r;
|
||||
|
||||
assert( pOp[1].opcode==OP_SeekGE );
|
||||
|
||||
/* pOp->p2 points to the first instruction past the OP_IdxGT that
|
||||
** follows the OP_SeekGE. */
|
||||
assert( pOp->p2>=(int)(pOp-aOp)+2 );
|
||||
assert( aOp[pOp->p2-1].opcode==OP_IdxGT );
|
||||
assert( pOp[1].p1==aOp[pOp->p2-1].p1 );
|
||||
assert( pOp[1].p2==aOp[pOp->p2-1].p2 );
|
||||
assert( pOp[1].p3==aOp[pOp->p2-1].p3 );
|
||||
|
||||
assert( pOp->p1>0 );
|
||||
pC = p->apCsr[pOp[1].p1];
|
||||
assert( pC!=0 );
|
||||
assert( pC->eCurType==CURTYPE_BTREE );
|
||||
assert( !pC->isTable );
|
||||
if( !sqlite3BtreeCursorIsValidNN(pC->uc.pCursor) ){
|
||||
#ifdef SQLITE_DEBUG
|
||||
if( db->flags&SQLITE_VdbeTrace ){
|
||||
printf("... cursor not valid - fall through\n");
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
nStep = pOp->p1;
|
||||
assert( nStep>=1 );
|
||||
r.pKeyInfo = pC->pKeyInfo;
|
||||
r.nField = (u16)pOp[1].p4.i;
|
||||
r.default_rc = 0;
|
||||
r.aMem = &aMem[pOp[1].p3];
|
||||
#ifdef SQLITE_DEBUG
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<r.nField; i++){
|
||||
assert( memIsValid(&r.aMem[i]) );
|
||||
REGISTER_TRACE(pOp[1].p3+i, &aMem[pOp[1].p3+i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
res = 0; /* Not needed. Only used to silence a warning. */
|
||||
while(1){
|
||||
rc = sqlite3VdbeIdxKeyCompare(db, pC, &r, &res);
|
||||
if( rc ) goto abort_due_to_error;
|
||||
if( res>0 ){
|
||||
seekscan_search_fail:
|
||||
#ifdef SQLITE_DEBUG
|
||||
if( db->flags&SQLITE_VdbeTrace ){
|
||||
printf("... %d steps and then skip\n", pOp->p1 - nStep);
|
||||
}
|
||||
#endif
|
||||
VdbeBranchTaken(1,3);
|
||||
pOp++;
|
||||
goto jump_to_p2;
|
||||
}
|
||||
if( res==0 ){
|
||||
#ifdef SQLITE_DEBUG
|
||||
if( db->flags&SQLITE_VdbeTrace ){
|
||||
printf("... %d steps and then success\n", pOp->p1 - nStep);
|
||||
}
|
||||
#endif
|
||||
VdbeBranchTaken(2,3);
|
||||
goto jump_to_p2;
|
||||
break;
|
||||
}
|
||||
if( nStep<=0 ){
|
||||
#ifdef SQLITE_DEBUG
|
||||
if( db->flags&SQLITE_VdbeTrace ){
|
||||
printf("... fall through after %d steps\n", pOp->p1);
|
||||
}
|
||||
#endif
|
||||
VdbeBranchTaken(0,3);
|
||||
break;
|
||||
}
|
||||
nStep--;
|
||||
rc = sqlite3BtreeNext(pC->uc.pCursor, 0);
|
||||
if( rc ){
|
||||
if( rc==SQLITE_DONE ){
|
||||
rc = SQLITE_OK;
|
||||
goto seekscan_search_fail;
|
||||
}else{
|
||||
goto abort_due_to_error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* Opcode: SeekHit P1 P2 P3 * *
|
||||
** Synopsis: set P2<=seekHit<=P3
|
||||
**
|
||||
** Increase or decrease the seekHit value for cursor P1, if necessary,
|
||||
** so that it is no less than P2 and no greater than P3.
|
||||
**
|
||||
** The seekHit integer represents the maximum of terms in an index for which
|
||||
** there is known to be at least one match. If the seekHit value is smaller
|
||||
** than the total number of equality terms in an index lookup, then the
|
||||
** OP_IfNoHope opcode might run to see if the IN loop can be abandoned
|
||||
** early, thus saving work. This is part of the IN-early-out optimization.
|
||||
**
|
||||
** P1 must be a valid b-tree cursor.
|
||||
*/
|
||||
case OP_SeekHit: {
|
||||
VdbeCursor *pC;
|
||||
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
|
||||
pC = p->apCsr[pOp->p1];
|
||||
assert( pC!=0 );
|
||||
assert( pOp->p2==0 || pOp->p2==1 );
|
||||
pC->seekHit = pOp->p2 & 1;
|
||||
assert( pOp->p3>=pOp->p2 );
|
||||
if( pC->seekHit<pOp->p2 ){
|
||||
pC->seekHit = pOp->p2;
|
||||
}else if( pC->seekHit>pOp->p3 ){
|
||||
pC->seekHit = pOp->p3;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -4456,16 +4608,20 @@ case OP_IfNotOpen: { /* jump */
|
||||
** Synopsis: key=r[P3@P4]
|
||||
**
|
||||
** Register P3 is the first of P4 registers that form an unpacked
|
||||
** record.
|
||||
** record. Cursor P1 is an index btree. P2 is a jump destination.
|
||||
** In other words, the operands to this opcode are the same as the
|
||||
** operands to OP_NotFound and OP_IdxGT.
|
||||
**
|
||||
** Cursor P1 is on an index btree. If the seekHit flag is set on P1, then
|
||||
** this opcode is a no-op. But if the seekHit flag of P1 is clear, then
|
||||
** check to see if there is any entry in P1 that matches the
|
||||
** prefix identified by P3 and P4. If no entry matches the prefix,
|
||||
** jump to P2. Otherwise fall through.
|
||||
** This opcode is an optimization attempt only. If this opcode always
|
||||
** falls through, the correct answer is still obtained, but extra works
|
||||
** is performed.
|
||||
**
|
||||
** This opcode behaves like OP_NotFound if the seekHit
|
||||
** flag is clear and it behaves like OP_Noop if the seekHit flag is set.
|
||||
** A value of N in the seekHit flag of cursor P1 means that there exists
|
||||
** a key P3:N that will match some record in the index. We want to know
|
||||
** if it is possible for a record P3:P4 to match some record in the
|
||||
** index. If it is not possible, we can skips some work. So if seekHit
|
||||
** is less than P4, attempt to find out if a match is possible by running
|
||||
** OP_NotFound.
|
||||
**
|
||||
** This opcode is used in IN clause processing for a multi-column key.
|
||||
** If an IN clause is attached to an element of the key other than the
|
||||
@@ -4507,7 +4663,7 @@ case OP_IfNoHope: { /* jump, in3 */
|
||||
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
|
||||
pC = p->apCsr[pOp->p1];
|
||||
assert( pC!=0 );
|
||||
if( pC->seekHit ) break;
|
||||
if( pC->seekHit>=pOp->p4.i ) break;
|
||||
/* Fall through into OP_NotFound */
|
||||
/* no break */ deliberate_fall_through
|
||||
}
|
||||
@@ -4589,6 +4745,7 @@ case OP_Found: { /* jump, in3 */
|
||||
}else{
|
||||
VdbeBranchTaken(takeJump||alreadyExists==0,2);
|
||||
if( takeJump || !alreadyExists ) goto jump_to_p2;
|
||||
if( pOp->opcode==OP_IfNoHope ) pC->seekHit = pOp->p4.i;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -5821,7 +5978,7 @@ case OP_FinishSeek: {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: IdxGE P1 P2 P3 P4 P5
|
||||
/* Opcode: IdxGE P1 P2 P3 P4 *
|
||||
** Synopsis: key=r[P3@P4]
|
||||
**
|
||||
** The P4 register values beginning with P3 form an unpacked index
|
||||
@@ -5832,7 +5989,7 @@ case OP_FinishSeek: {
|
||||
** If the P1 index entry is greater than or equal to the key value
|
||||
** then jump to P2. Otherwise fall through to the next instruction.
|
||||
*/
|
||||
/* Opcode: IdxGT P1 P2 P3 P4 P5
|
||||
/* Opcode: IdxGT P1 P2 P3 P4 *
|
||||
** Synopsis: key=r[P3@P4]
|
||||
**
|
||||
** The P4 register values beginning with P3 form an unpacked index
|
||||
@@ -5843,7 +6000,7 @@ case OP_FinishSeek: {
|
||||
** If the P1 index entry is greater than the key value
|
||||
** then jump to P2. Otherwise fall through to the next instruction.
|
||||
*/
|
||||
/* Opcode: IdxLT P1 P2 P3 P4 P5
|
||||
/* Opcode: IdxLT P1 P2 P3 P4 *
|
||||
** Synopsis: key=r[P3@P4]
|
||||
**
|
||||
** The P4 register values beginning with P3 form an unpacked index
|
||||
@@ -5854,7 +6011,7 @@ case OP_FinishSeek: {
|
||||
** If the P1 index entry is less than the key value then jump to P2.
|
||||
** Otherwise fall through to the next instruction.
|
||||
*/
|
||||
/* Opcode: IdxLE P1 P2 P3 P4 P5
|
||||
/* Opcode: IdxLE P1 P2 P3 P4 *
|
||||
** Synopsis: key=r[P3@P4]
|
||||
**
|
||||
** The P4 register values beginning with P3 form an unpacked index
|
||||
@@ -5880,7 +6037,6 @@ case OP_IdxGE: { /* jump */
|
||||
assert( pC->eCurType==CURTYPE_BTREE );
|
||||
assert( pC->uc.pCursor!=0);
|
||||
assert( pC->deferredMoveto==0 );
|
||||
assert( pOp->p5==0 || pOp->p5==1 );
|
||||
assert( pOp->p4type==P4_INT32 );
|
||||
r.pKeyInfo = pC->pKeyInfo;
|
||||
r.nField = (u16)pOp->p4.i;
|
||||
@@ -5901,8 +6057,31 @@ case OP_IdxGE: { /* jump */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
res = 0; /* Not needed. Only used to silence a warning. */
|
||||
rc = sqlite3VdbeIdxKeyCompare(db, pC, &r, &res);
|
||||
|
||||
/* Inlined version of sqlite3VdbeIdxKeyCompare() */
|
||||
{
|
||||
i64 nCellKey = 0;
|
||||
BtCursor *pCur;
|
||||
Mem m;
|
||||
|
||||
assert( pC->eCurType==CURTYPE_BTREE );
|
||||
pCur = pC->uc.pCursor;
|
||||
assert( sqlite3BtreeCursorIsValid(pCur) );
|
||||
nCellKey = sqlite3BtreePayloadSize(pCur);
|
||||
/* nCellKey will always be between 0 and 0xffffffff because of the way
|
||||
** that btreeParseCellPtr() and sqlite3GetVarint32() are implemented */
|
||||
if( nCellKey<=0 || nCellKey>0x7fffffff ){
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
goto abort_due_to_error;
|
||||
}
|
||||
sqlite3VdbeMemInit(&m, db, 0);
|
||||
rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m);
|
||||
if( rc ) goto abort_due_to_error;
|
||||
res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, &r, 0);
|
||||
sqlite3VdbeMemRelease(&m);
|
||||
}
|
||||
/* End of inlined sqlite3VdbeIdxKeyCompare() */
|
||||
|
||||
assert( (OP_IdxLE&1)==(OP_IdxLT&1) && (OP_IdxGE&1)==(OP_IdxGT&1) );
|
||||
if( (pOp->opcode&1)==(OP_IdxLT&1) ){
|
||||
assert( pOp->opcode==OP_IdxLE || pOp->opcode==OP_IdxLT );
|
||||
@@ -5912,7 +6091,7 @@ case OP_IdxGE: { /* jump */
|
||||
res++;
|
||||
}
|
||||
VdbeBranchTaken(res>0,2);
|
||||
if( rc ) goto abort_due_to_error;
|
||||
assert( rc==SQLITE_OK );
|
||||
if( res>0 ) goto jump_to_p2;
|
||||
break;
|
||||
}
|
||||
@@ -7038,7 +7217,7 @@ case OP_JournalMode: { /* out2 */
|
||||
/* Open a transaction on the database file. Regardless of the journal
|
||||
** mode, this transaction always uses a rollback journal.
|
||||
*/
|
||||
assert( sqlite3BtreeIsInTrans(pBt)==0 );
|
||||
assert( sqlite3BtreeTxnState(pBt)!=SQLITE_TXN_WRITE );
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3BtreeSetVersion(pBt, (eNew==PAGER_JOURNALMODE_WAL ? 2 : 1));
|
||||
}
|
||||
|
||||
+1
-1
@@ -86,7 +86,7 @@ struct VdbeCursor {
|
||||
Bool isEphemeral:1; /* True for an ephemeral table */
|
||||
Bool useRandomRowid:1; /* Generate new record numbers semi-randomly */
|
||||
Bool isOrdered:1; /* True if the table is not BTREE_UNORDERED */
|
||||
Bool seekHit:1; /* See the OP_SeekHit and OP_IfNoHope opcodes */
|
||||
u16 seekHit; /* See the OP_SeekHit and OP_IfNoHope opcodes */
|
||||
Btree *pBtx; /* Separate file holding temporary table */
|
||||
i64 seqCount; /* Sequence counter */
|
||||
u32 *aAltMap; /* Mapping from table to index column numbers */
|
||||
|
||||
+5
-4
@@ -475,6 +475,7 @@ void sqlite3VdbeAddParseSchemaOp(Vdbe *p, int iDb, char *zWhere){
|
||||
int j;
|
||||
sqlite3VdbeAddOp4(p, OP_ParseSchema, iDb, 0, 0, zWhere, P4_DYNAMIC);
|
||||
for(j=0; j<p->db->nDb; j++) sqlite3VdbeUsesBtree(p, j);
|
||||
sqlite3MayAbort(p->pParse);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -703,7 +704,7 @@ int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
|
||||
if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename
|
||||
|| opcode==OP_VDestroy
|
||||
|| opcode==OP_VCreate
|
||||
|| (opcode==OP_ParseSchema && pOp->p4.z==0)
|
||||
|| opcode==OP_ParseSchema
|
||||
|| ((opcode==OP_Halt || opcode==OP_HaltIfNull)
|
||||
&& ((pOp->p1)!=SQLITE_OK && pOp->p2==OE_Abort))
|
||||
){
|
||||
@@ -1521,7 +1522,7 @@ char *sqlite3VdbeDisplayComment(
|
||||
sqlite3_str_appendf(&x, "%d", v1);
|
||||
}else if( pCtx->argc>1 ){
|
||||
sqlite3_str_appendf(&x, "%d..%d", v1, v1+pCtx->argc-1);
|
||||
}else{
|
||||
}else if( x.accError==0 ){
|
||||
assert( x.nChar>2 );
|
||||
x.nChar -= 2;
|
||||
ii++;
|
||||
@@ -2663,7 +2664,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
|
||||
*/
|
||||
for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
|
||||
Btree *pBt = db->aDb[i].pBt;
|
||||
if( sqlite3BtreeIsInTrans(pBt) ){
|
||||
if( sqlite3BtreeTxnState(pBt)==SQLITE_TXN_WRITE ){
|
||||
/* Whether or not a database might need a super-journal depends upon
|
||||
** its journal mode (among other things). This matrix determines which
|
||||
** journal modes use a super-journal and which do not */
|
||||
@@ -2798,7 +2799,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
|
||||
*/
|
||||
for(i=0; i<db->nDb; i++){
|
||||
Btree *pBt = db->aDb[i].pBt;
|
||||
if( sqlite3BtreeIsInTrans(pBt) ){
|
||||
if( sqlite3BtreeTxnState(pBt)==SQLITE_TXN_WRITE ){
|
||||
char const *zFile = sqlite3BtreeGetJournalname(pBt);
|
||||
if( zFile==0 ){
|
||||
continue; /* Ignore TEMP and :memory: databases */
|
||||
|
||||
+4
-1
@@ -970,13 +970,16 @@ int sqlite3VdbeSorterInit(
|
||||
if( pSorter==0 ){
|
||||
rc = SQLITE_NOMEM_BKPT;
|
||||
}else{
|
||||
Btree *pBt = db->aDb[0].pBt;
|
||||
pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz);
|
||||
memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo);
|
||||
pKeyInfo->db = 0;
|
||||
if( nField && nWorker==0 ){
|
||||
pKeyInfo->nKeyField = nField;
|
||||
}
|
||||
pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt);
|
||||
sqlite3BtreeEnter(pBt);
|
||||
pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(pBt);
|
||||
sqlite3BtreeLeave(pBt);
|
||||
pSorter->nTask = nWorker + 1;
|
||||
pSorter->iPrev = (u8)(nWorker - 1);
|
||||
pSorter->bUseThreads = (pSorter->nTask>1);
|
||||
|
||||
+49
-24
@@ -257,7 +257,7 @@ static WhereTerm *whereScanNext(WhereScan *pScan){
|
||||
do{
|
||||
for(pTerm=pWC->a+k; k<pWC->nTerm; k++, pTerm++){
|
||||
if( pTerm->leftCursor==iCur
|
||||
&& pTerm->u.leftColumn==iColumn
|
||||
&& pTerm->u.x.leftColumn==iColumn
|
||||
&& (iColumn!=XN_EXPR
|
||||
|| sqlite3ExprCompareSkip(pTerm->pExpr->pLeft,
|
||||
pScan->pIdxExpr,iCur)==0)
|
||||
@@ -679,8 +679,8 @@ static int termCanDriveIndex(
|
||||
return 0;
|
||||
}
|
||||
if( (pTerm->prereqRight & notReady)!=0 ) return 0;
|
||||
if( pTerm->u.leftColumn<0 ) return 0;
|
||||
aff = pSrc->pTab->aCol[pTerm->u.leftColumn].affinity;
|
||||
if( pTerm->u.x.leftColumn<0 ) return 0;
|
||||
aff = pSrc->pTab->aCol[pTerm->u.x.leftColumn].affinity;
|
||||
if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0;
|
||||
testcase( pTerm->pExpr->op==TK_IS );
|
||||
return 1;
|
||||
@@ -751,7 +751,7 @@ static void constructAutomaticIndex(
|
||||
sqlite3ExprDup(pParse->db, pExpr, 0));
|
||||
}
|
||||
if( termCanDriveIndex(pTerm, pSrc, notReady) ){
|
||||
int iCol = pTerm->u.leftColumn;
|
||||
int iCol = pTerm->u.x.leftColumn;
|
||||
Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
|
||||
testcase( iCol==BMS );
|
||||
testcase( iCol==BMS-1 );
|
||||
@@ -804,14 +804,14 @@ static void constructAutomaticIndex(
|
||||
idxCols = 0;
|
||||
for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
|
||||
if( termCanDriveIndex(pTerm, pSrc, notReady) ){
|
||||
int iCol = pTerm->u.leftColumn;
|
||||
int iCol = pTerm->u.x.leftColumn;
|
||||
Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
|
||||
testcase( iCol==BMS-1 );
|
||||
testcase( iCol==BMS );
|
||||
if( (idxCols & cMask)==0 ){
|
||||
Expr *pX = pTerm->pExpr;
|
||||
idxCols |= cMask;
|
||||
pIdx->aiColumn[n] = pTerm->u.leftColumn;
|
||||
pIdx->aiColumn[n] = pTerm->u.x.leftColumn;
|
||||
pColl = sqlite3ExprCompareCollSeq(pParse, pX);
|
||||
assert( pColl!=0 || pParse->nErr>0 ); /* TH3 collate01.800 */
|
||||
pIdx->azColl[n] = pColl ? pColl->zName : sqlite3StrBINARY;
|
||||
@@ -932,7 +932,7 @@ static sqlite3_index_info *allocateIndexInfo(
|
||||
testcase( pTerm->eOperator & WO_ALL );
|
||||
if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue;
|
||||
if( pTerm->wtFlags & TERM_VNULL ) continue;
|
||||
assert( pTerm->u.leftColumn>=(-1) );
|
||||
assert( pTerm->u.x.leftColumn>=(-1) );
|
||||
nTerm++;
|
||||
}
|
||||
|
||||
@@ -992,8 +992,8 @@ static sqlite3_index_info *allocateIndexInfo(
|
||||
){
|
||||
continue;
|
||||
}
|
||||
assert( pTerm->u.leftColumn>=(-1) );
|
||||
pIdxCons[j].iColumn = pTerm->u.leftColumn;
|
||||
assert( pTerm->u.x.leftColumn>=(-1) );
|
||||
pIdxCons[j].iColumn = pTerm->u.x.leftColumn;
|
||||
pIdxCons[j].iTermOffset = i;
|
||||
op = pTerm->eOperator & WO_ALL;
|
||||
if( op==WO_IN ) op = WO_EQ;
|
||||
@@ -1756,9 +1756,9 @@ void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm){
|
||||
if( pTerm->wtFlags & TERM_CODED ) zType[3] = 'C';
|
||||
if( pTerm->eOperator & WO_SINGLE ){
|
||||
sqlite3_snprintf(sizeof(zLeft),zLeft,"left={%d:%d}",
|
||||
pTerm->leftCursor, pTerm->u.leftColumn);
|
||||
pTerm->leftCursor, pTerm->u.x.leftColumn);
|
||||
}else if( (pTerm->eOperator & WO_OR)!=0 && pTerm->u.pOrInfo!=0 ){
|
||||
sqlite3_snprintf(sizeof(zLeft),zLeft,"indexable=0x%lld",
|
||||
sqlite3_snprintf(sizeof(zLeft),zLeft,"indexable=0x%llx",
|
||||
pTerm->u.pOrInfo->indexable);
|
||||
}else{
|
||||
sqlite3_snprintf(sizeof(zLeft),zLeft,"left=%d", pTerm->leftCursor);
|
||||
@@ -1772,8 +1772,8 @@ void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm){
|
||||
sqlite3DebugPrintf(" prob=%-3d prereq=%llx,%llx",
|
||||
pTerm->truthProb, (u64)pTerm->prereqAll, (u64)pTerm->prereqRight);
|
||||
}
|
||||
if( pTerm->iField ){
|
||||
sqlite3DebugPrintf(" iField=%d", pTerm->iField);
|
||||
if( pTerm->u.x.iField ){
|
||||
sqlite3DebugPrintf(" iField=%d", pTerm->u.x.iField);
|
||||
}
|
||||
if( pTerm->iParent>=0 ){
|
||||
sqlite3DebugPrintf(" iParent=%d", pTerm->iParent);
|
||||
@@ -2536,7 +2536,7 @@ static int whereLoopAddBtreeIndex(
|
||||
/* "x IN (value, value, ...)" */
|
||||
nIn = sqlite3LogEst(pExpr->x.pList->nExpr);
|
||||
}
|
||||
if( pProbe->hasStat1 ){
|
||||
if( pProbe->hasStat1 && rLogSize>=10 ){
|
||||
LogEst M, logK, safetyMargin;
|
||||
/* Let:
|
||||
** N = the total number of rows in the table
|
||||
@@ -2555,7 +2555,8 @@ static int whereLoopAddBtreeIndex(
|
||||
** a safety margin of 2 (LogEst: 10) that favors using the IN operator
|
||||
** with the index, as using an index has better worst-case behavior.
|
||||
** If we do not have real sqlite_stat1 data, always prefer to use
|
||||
** the index.
|
||||
** the index. Do not bother with this optimization on very small
|
||||
** tables (less than 2 rows) as it is pointless in that case.
|
||||
*/
|
||||
M = pProbe->aiRowLogEst[saved_nEq];
|
||||
logK = estLog(nIn);
|
||||
@@ -2564,7 +2565,7 @@ static int whereLoopAddBtreeIndex(
|
||||
WHERETRACE(0x40,
|
||||
("Scan preferred over IN operator on column %d of \"%s\" (%d<%d)\n",
|
||||
saved_nEq, pProbe->zName, M+logK+10, nIn+rLogSize));
|
||||
continue;
|
||||
pNew->wsFlags |= WHERE_IN_SEEKSCAN;
|
||||
}else{
|
||||
WHERETRACE(0x40,
|
||||
("IN operator preferred on column %d of \"%s\" (%d>=%d)\n",
|
||||
@@ -3041,8 +3042,23 @@ static int whereLoopAddBtree(
|
||||
|
||||
/* Full table scan */
|
||||
pNew->iSortIdx = b ? iSortIdx : 0;
|
||||
/* TUNING: Cost of full table scan is (N*3.0). */
|
||||
/* TUNING: Cost of full table scan is 3.0*N. The 3.0 factor is an
|
||||
** extra cost designed to discourage the use of full table scans,
|
||||
** since index lookups have better worst-case performance if our
|
||||
** stat guesses are wrong. Reduce the 3.0 penalty slightly
|
||||
** (to 2.75) if we have valid STAT4 information for the table.
|
||||
** At 2.75, a full table scan is preferred over using an index on
|
||||
** a column with just two distinct values where each value has about
|
||||
** an equal number of appearances. Without STAT4 data, we still want
|
||||
** to use an index in that case, since the constraint might be for
|
||||
** the scarcer of the two values, and in that case an index lookup is
|
||||
** better.
|
||||
*/
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
pNew->rRun = rSize + 16 - 2*((pTab->tabFlags & TF_HasStat4)!=0);
|
||||
#else
|
||||
pNew->rRun = rSize + 16;
|
||||
#endif
|
||||
ApplyCostMultiplier(pNew->rRun, pTab->costMult);
|
||||
whereLoopOutputAdjust(pWC, pNew, rSize);
|
||||
rc = whereLoopInsert(pBuilder, pNew);
|
||||
@@ -4053,16 +4069,24 @@ static LogEst whereSortingCost(
|
||||
** cost = (3.0 * N * log(N)) * (Y/X)
|
||||
**
|
||||
** The (Y/X) term is implemented using stack variable rScale
|
||||
** below. */
|
||||
** below.
|
||||
*/
|
||||
LogEst rScale, rSortCost;
|
||||
assert( nOrderBy>0 && 66==sqlite3LogEst(100) );
|
||||
rScale = sqlite3LogEst((nOrderBy-nSorted)*100/nOrderBy) - 66;
|
||||
rSortCost = nRow + rScale + 16;
|
||||
|
||||
/* Multiple by log(M) where M is the number of output rows.
|
||||
** Use the LIMIT for M if it is smaller */
|
||||
** Use the LIMIT for M if it is smaller. Or if this sort is for
|
||||
** a DISTINT operator, M will be the number of distinct output
|
||||
** rows, so fudge it downwards a bit.
|
||||
*/
|
||||
if( (pWInfo->wctrlFlags & WHERE_USE_LIMIT)!=0 && pWInfo->iLimit<nRow ){
|
||||
nRow = pWInfo->iLimit;
|
||||
}else if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT) ){
|
||||
/* TUNING: In the sort for a DISTINCT operator, assume that the DISTINCT
|
||||
** reduces the number of output rows by a factor of 2 */
|
||||
if( nRow>10 ) nRow -= 10; assert( 10==sqlite3LogEst(2) );
|
||||
}
|
||||
rSortCost += estLog(nRow);
|
||||
return rSortCost;
|
||||
@@ -5189,6 +5213,7 @@ WhereInfo *sqlite3WhereBegin(
|
||||
if( (pLoop->wsFlags & WHERE_CONSTRAINT)!=0
|
||||
&& (pLoop->wsFlags & (WHERE_COLUMN_RANGE|WHERE_SKIPSCAN))==0
|
||||
&& (pLoop->wsFlags & WHERE_BIGNULL_SORT)==0
|
||||
&& (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0
|
||||
&& (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0
|
||||
&& pWInfo->eDistinct!=WHERE_DISTINCT_ORDERED
|
||||
){
|
||||
@@ -5351,7 +5376,9 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
|
||||
sqlite3VdbeJumpHere(v, pIn->addrInTop+1);
|
||||
if( pIn->eEndLoopOp!=OP_Noop ){
|
||||
if( pIn->nPrefix ){
|
||||
assert( pLoop->wsFlags & WHERE_IN_EARLYOUT );
|
||||
int bEarlyOut =
|
||||
(pLoop->wsFlags & WHERE_VIRTUALTABLE)==0
|
||||
&& (pLoop->wsFlags & WHERE_IN_EARLYOUT)!=0;
|
||||
if( pLevel->iLeftJoin ){
|
||||
/* For LEFT JOIN queries, cursor pIn->iCur may not have been
|
||||
** opened yet. This occurs for WHERE clauses such as
|
||||
@@ -5362,12 +5389,10 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
|
||||
** jump over the OP_Next or OP_Prev instruction about to
|
||||
** be coded. */
|
||||
sqlite3VdbeAddOp2(v, OP_IfNotOpen, pIn->iCur,
|
||||
sqlite3VdbeCurrentAddr(v) + 2 +
|
||||
((pLoop->wsFlags & WHERE_VIRTUALTABLE)==0)
|
||||
);
|
||||
sqlite3VdbeCurrentAddr(v) + 2 + bEarlyOut);
|
||||
VdbeCoverage(v);
|
||||
}
|
||||
if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ){
|
||||
if( bEarlyOut ){
|
||||
sqlite3VdbeAddOp4Int(v, OP_IfNoHope, pLevel->iIdxCur,
|
||||
sqlite3VdbeCurrentAddr(v)+2,
|
||||
pIn->iBase, pIn->nPrefix);
|
||||
|
||||
+5
-2
@@ -261,9 +261,11 @@ struct WhereTerm {
|
||||
u8 eMatchOp; /* Op for vtab MATCH/LIKE/GLOB/REGEXP terms */
|
||||
int iParent; /* Disable pWC->a[iParent] when this term disabled */
|
||||
int leftCursor; /* Cursor number of X in "X <op> <expr>" */
|
||||
int iField; /* Field in (?,?,?) IN (SELECT...) vector */
|
||||
union {
|
||||
int leftColumn; /* Column number of X in "X <op> <expr>" */
|
||||
struct {
|
||||
int leftColumn; /* Column number of X in "X <op> <expr>" */
|
||||
int iField; /* Field in (?,?,?) IN (SELECT...) vector */
|
||||
} x; /* Opcode other than OP_OR or OP_AND */
|
||||
WhereOrInfo *pOrInfo; /* Extra information if (eOperator & WO_OR)!=0 */
|
||||
WhereAndInfo *pAndInfo; /* Extra information if (eOperator& WO_AND)!=0 */
|
||||
} u;
|
||||
@@ -617,5 +619,6 @@ void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*);
|
||||
#define WHERE_PARTIALIDX 0x00020000 /* The automatic index is partial */
|
||||
#define WHERE_IN_EARLYOUT 0x00040000 /* Perhaps quit IN loops early */
|
||||
#define WHERE_BIGNULL_SORT 0x00080000 /* Column nEq of index is BIGNULL */
|
||||
#define WHERE_IN_SEEKSCAN 0x00100000 /* Seek-scan optimization for IN */
|
||||
|
||||
#endif /* !defined(SQLITE_WHEREINT_H) */
|
||||
|
||||
+34
-8
@@ -427,7 +427,7 @@ static Expr *removeUnindexableInClauseTerms(
|
||||
|
||||
for(i=iEq; i<pLoop->nLTerm; i++){
|
||||
if( pLoop->aLTerm[i]->pExpr==pX ){
|
||||
int iField = pLoop->aLTerm[i]->iField - 1;
|
||||
int iField = pLoop->aLTerm[i]->u.x.iField - 1;
|
||||
if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */
|
||||
pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr);
|
||||
pOrigRhs->a[iField].pExpr = 0;
|
||||
@@ -570,6 +570,9 @@ static int codeEqualityTerm(
|
||||
if( pLevel->u.in.nIn==0 ){
|
||||
pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse);
|
||||
}
|
||||
if( iEq>0 && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 ){
|
||||
pLoop->wsFlags |= WHERE_IN_EARLYOUT;
|
||||
}
|
||||
|
||||
i = pLevel->u.in.nIn;
|
||||
pLevel->u.in.nIn += nEq;
|
||||
@@ -596,7 +599,6 @@ static int codeEqualityTerm(
|
||||
if( iEq>0 ){
|
||||
pIn->iBase = iReg - i;
|
||||
pIn->nPrefix = i;
|
||||
pLoop->wsFlags |= WHERE_IN_EARLYOUT;
|
||||
}else{
|
||||
pIn->nPrefix = 0;
|
||||
}
|
||||
@@ -606,6 +608,14 @@ static int codeEqualityTerm(
|
||||
pIn++;
|
||||
}
|
||||
}
|
||||
testcase( iEq>0
|
||||
&& (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0
|
||||
&& (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 );
|
||||
if( iEq>0
|
||||
&& (pLoop->wsFlags & (WHERE_IN_SEEKSCAN|WHERE_VIRTUALTABLE))==0
|
||||
){
|
||||
sqlite3VdbeAddOp3(v, OP_SeekHit, pLevel->iIdxCur, 0, iEq);
|
||||
}
|
||||
}else{
|
||||
pLevel->u.in.nIn = 0;
|
||||
}
|
||||
@@ -1392,6 +1402,9 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
pLoop->u.vtab.needFree ? P4_DYNAMIC : P4_STATIC);
|
||||
VdbeCoverage(v);
|
||||
pLoop->u.vtab.needFree = 0;
|
||||
/* An OOM inside of AddOp4(OP_VFilter) instruction above might have freed
|
||||
** the u.vtab.idxStr. NULL it out to prevent a use-after-free */
|
||||
if( db->mallocFailed ) pLoop->u.vtab.idxStr = 0;
|
||||
pLevel->p1 = iCur;
|
||||
pLevel->op = pWInfo->eOnePass ? OP_Noop : OP_VNext;
|
||||
pLevel->p2 = sqlite3VdbeCurrentAddr(v);
|
||||
@@ -1650,6 +1663,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
u8 bStopAtNull = 0; /* Add condition to terminate at NULLs */
|
||||
int omitTable; /* True if we use the index only */
|
||||
int regBignull = 0; /* big-null flag register */
|
||||
int addrSeekScan = 0; /* Opcode of the OP_SeekScan, if any */
|
||||
|
||||
pIdx = pLoop->u.btree.pIndex;
|
||||
iIdxCur = pLevel->iIdxCur;
|
||||
@@ -1788,9 +1802,6 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
** above has already left the cursor sitting on the correct row,
|
||||
** so no further seeking is needed */
|
||||
}else{
|
||||
if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){
|
||||
sqlite3VdbeAddOp1(v, OP_SeekHit, iIdxCur);
|
||||
}
|
||||
if( regBignull ){
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 1, regBignull);
|
||||
VdbeComment((v, "NULL-scan pass ctr"));
|
||||
@@ -1798,6 +1809,20 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
|
||||
op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev];
|
||||
assert( op!=0 );
|
||||
if( (pLoop->wsFlags & WHERE_IN_SEEKSCAN)!=0 && op==OP_SeekGE ){
|
||||
assert( regBignull==0 );
|
||||
/* TUNING: The OP_SeekScan opcode seeks to reduce the number
|
||||
** of expensive seek operations by replacing a single seek with
|
||||
** 1 or more step operations. The question is, how many steps
|
||||
** should we try before giving up and going with a seek. The cost
|
||||
** of a seek is proportional to the logarithm of the of the number
|
||||
** of entries in the tree, so basing the number of steps to try
|
||||
** on the estimated number of rows in the btree seems like a good
|
||||
** guess. */
|
||||
addrSeekScan = sqlite3VdbeAddOp1(v, OP_SeekScan,
|
||||
(pIdx->aiRowLogEst[0]+9)/10);
|
||||
VdbeCoverage(v);
|
||||
}
|
||||
sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
|
||||
VdbeCoverage(v);
|
||||
VdbeCoverageIf(v, op==OP_Rewind); testcase( op==OP_Rewind );
|
||||
@@ -1880,6 +1905,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
testcase( op==OP_IdxGE ); VdbeCoverageIf(v, op==OP_IdxGE );
|
||||
testcase( op==OP_IdxLT ); VdbeCoverageIf(v, op==OP_IdxLT );
|
||||
testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE );
|
||||
if( addrSeekScan ) sqlite3VdbeJumpHere(v, addrSeekScan);
|
||||
}
|
||||
if( regBignull ){
|
||||
/* During a NULL-scan, check to see if we have reached the end of
|
||||
@@ -1899,8 +1925,8 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE );
|
||||
}
|
||||
|
||||
if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){
|
||||
sqlite3VdbeAddOp2(v, OP_SeekHit, iIdxCur, 1);
|
||||
if( (pLoop->wsFlags & WHERE_IN_EARLYOUT)!=0 ){
|
||||
sqlite3VdbeAddOp3(v, OP_SeekHit, iIdxCur, nEq, nEq);
|
||||
}
|
||||
|
||||
/* Seek the table cursor, if required */
|
||||
@@ -2407,7 +2433,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
#endif
|
||||
assert( !ExprHasProperty(pE, EP_FromJoin) );
|
||||
assert( (pTerm->prereqRight & pLevel->notReady)!=0 );
|
||||
pAlt = sqlite3WhereFindTerm(pWC, iCur, pTerm->u.leftColumn, notReady,
|
||||
pAlt = sqlite3WhereFindTerm(pWC, iCur, pTerm->u.x.leftColumn, notReady,
|
||||
WO_EQ|WO_IN|WO_IS, 0);
|
||||
if( pAlt==0 ) continue;
|
||||
if( pAlt->wtFlags & (TERM_CODED) ) continue;
|
||||
|
||||
+13
-13
@@ -798,7 +798,7 @@ static void exprAnalyzeOrTerm(
|
||||
assert( pOrTerm->wtFlags & (TERM_COPIED|TERM_VIRTUAL) );
|
||||
continue;
|
||||
}
|
||||
iColumn = pOrTerm->u.leftColumn;
|
||||
iColumn = pOrTerm->u.x.leftColumn;
|
||||
iCursor = pOrTerm->leftCursor;
|
||||
pLeft = pOrTerm->pExpr->pLeft;
|
||||
break;
|
||||
@@ -820,7 +820,7 @@ static void exprAnalyzeOrTerm(
|
||||
assert( pOrTerm->eOperator & WO_EQ );
|
||||
if( pOrTerm->leftCursor!=iCursor ){
|
||||
pOrTerm->wtFlags &= ~TERM_OR_OK;
|
||||
}else if( pOrTerm->u.leftColumn!=iColumn || (iColumn==XN_EXPR
|
||||
}else if( pOrTerm->u.x.leftColumn!=iColumn || (iColumn==XN_EXPR
|
||||
&& sqlite3ExprCompare(pParse, pOrTerm->pExpr->pLeft, pLeft, -1)
|
||||
)){
|
||||
okToChngToIN = 0;
|
||||
@@ -855,7 +855,7 @@ static void exprAnalyzeOrTerm(
|
||||
if( (pOrTerm->wtFlags & TERM_OR_OK)==0 ) continue;
|
||||
assert( pOrTerm->eOperator & WO_EQ );
|
||||
assert( pOrTerm->leftCursor==iCursor );
|
||||
assert( pOrTerm->u.leftColumn==iColumn );
|
||||
assert( pOrTerm->u.x.leftColumn==iColumn );
|
||||
pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight, 0);
|
||||
pList = sqlite3ExprListAppend(pWInfo->pParse, pList, pDup);
|
||||
pLeft = pOrTerm->pExpr->pLeft;
|
||||
@@ -1091,15 +1091,15 @@ static void exprAnalyze(
|
||||
Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight);
|
||||
u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV;
|
||||
|
||||
if( pTerm->iField>0 ){
|
||||
if( pTerm->u.x.iField>0 ){
|
||||
assert( op==TK_IN );
|
||||
assert( pLeft->op==TK_VECTOR );
|
||||
pLeft = pLeft->x.pList->a[pTerm->iField-1].pExpr;
|
||||
pLeft = pLeft->x.pList->a[pTerm->u.x.iField-1].pExpr;
|
||||
}
|
||||
|
||||
if( exprMightBeIndexed(pSrc, prereqLeft, aiCurCol, pLeft, op) ){
|
||||
pTerm->leftCursor = aiCurCol[0];
|
||||
pTerm->u.leftColumn = aiCurCol[1];
|
||||
pTerm->u.x.leftColumn = aiCurCol[1];
|
||||
pTerm->eOperator = operatorMask(op) & opMask;
|
||||
}
|
||||
if( op==TK_IS ) pTerm->wtFlags |= TERM_IS;
|
||||
@@ -1109,7 +1109,7 @@ static void exprAnalyze(
|
||||
WhereTerm *pNew;
|
||||
Expr *pDup;
|
||||
u16 eExtraOp = 0; /* Extra bits for pNew->eOperator */
|
||||
assert( pTerm->iField==0 );
|
||||
assert( pTerm->u.x.iField==0 );
|
||||
if( pTerm->leftCursor>=0 ){
|
||||
int idxNew;
|
||||
pDup = sqlite3ExprDup(db, pExpr, 0);
|
||||
@@ -1135,7 +1135,7 @@ static void exprAnalyze(
|
||||
}
|
||||
pNew->wtFlags |= exprCommute(pParse, pDup);
|
||||
pNew->leftCursor = aiCurCol[0];
|
||||
pNew->u.leftColumn = aiCurCol[1];
|
||||
pNew->u.x.leftColumn = aiCurCol[1];
|
||||
testcase( (prereqLeft | extraRight) != prereqLeft );
|
||||
pNew->prereqRight = prereqLeft | extraRight;
|
||||
pNew->prereqAll = prereqAll;
|
||||
@@ -1309,7 +1309,7 @@ static void exprAnalyze(
|
||||
pNewTerm = &pWC->a[idxNew];
|
||||
pNewTerm->prereqRight = prereqExpr;
|
||||
pNewTerm->leftCursor = pLeft->iTable;
|
||||
pNewTerm->u.leftColumn = pLeft->iColumn;
|
||||
pNewTerm->u.x.leftColumn = pLeft->iColumn;
|
||||
pNewTerm->eOperator = WO_AUX;
|
||||
pNewTerm->eMatchOp = eOp2;
|
||||
markTermAsChild(pWC, idxNew, idxTerm);
|
||||
@@ -1356,13 +1356,13 @@ static void exprAnalyze(
|
||||
/* If there is a vector IN term - e.g. "(a, b) IN (SELECT ...)" - create
|
||||
** a virtual term for each vector component. The expression object
|
||||
** used by each such virtual term is pExpr (the full vector IN(...)
|
||||
** expression). The WhereTerm.iField variable identifies the index within
|
||||
** expression). The WhereTerm.u.x.iField variable identifies the index within
|
||||
** the vector on the LHS that the virtual term represents.
|
||||
**
|
||||
** This only works if the RHS is a simple SELECT (not a compound) that does
|
||||
** not use window functions.
|
||||
*/
|
||||
if( pWC->op==TK_AND && pExpr->op==TK_IN && pTerm->iField==0
|
||||
if( pWC->op==TK_AND && pExpr->op==TK_IN && pTerm->u.x.iField==0
|
||||
&& pExpr->pLeft->op==TK_VECTOR
|
||||
&& pExpr->x.pSelect->pPrior==0
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
@@ -1373,7 +1373,7 @@ static void exprAnalyze(
|
||||
for(i=0; i<sqlite3ExprVectorSize(pExpr->pLeft); i++){
|
||||
int idxNew;
|
||||
idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL);
|
||||
pWC->a[idxNew].iField = i+1;
|
||||
pWC->a[idxNew].u.x.iField = i+1;
|
||||
exprAnalyze(pSrc, pWC, idxNew);
|
||||
markTermAsChild(pWC, idxNew, idxTerm);
|
||||
}
|
||||
@@ -1408,7 +1408,7 @@ static void exprAnalyze(
|
||||
pNewTerm = &pWC->a[idxNew];
|
||||
pNewTerm->prereqRight = 0;
|
||||
pNewTerm->leftCursor = pLeft->iTable;
|
||||
pNewTerm->u.leftColumn = pLeft->iColumn;
|
||||
pNewTerm->u.x.leftColumn = pLeft->iColumn;
|
||||
pNewTerm->eOperator = WO_GT;
|
||||
markTermAsChild(pWC, idxNew, idxTerm);
|
||||
pTerm = &pWC->a[idxTerm];
|
||||
|
||||
+4
-4
@@ -72,10 +72,10 @@ do_execsql_test affinity3-200 {
|
||||
CREATE TABLE mzed AS SELECT * FROM idmap;
|
||||
}
|
||||
|
||||
do_execsql_test affinity3-210 {
|
||||
PRAGMA automatic_index=ON;
|
||||
SELECT * FROM data JOIN idmap USING(id);
|
||||
} {1 abc a 4 xyz e}
|
||||
#do_execsql_test affinity3-210 {
|
||||
#PRAGMA automatic_index=ON;
|
||||
#SELECT * FROM data JOIN idmap USING(id);
|
||||
#} {1 abc a 4 xyz e}
|
||||
do_execsql_test affinity3-220 {
|
||||
SELECT * FROM data JOIN mzed USING(id);
|
||||
} {1 abc a 4 xyz e}
|
||||
|
||||
@@ -677,4 +677,39 @@ do_execsql_test 22.1 {
|
||||
SELECT * FROM t1;
|
||||
} {1 2 78 a b 78}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
db collate compare64 compare64
|
||||
|
||||
do_execsql_test 23.1 {
|
||||
CREATE TABLE gigo(a text);
|
||||
CREATE TABLE idx(x text COLLATE compare64);
|
||||
CREATE VIEW v1 AS SELECT * FROM idx WHERE x='abc';
|
||||
}
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
|
||||
do_execsql_test 23.2 {
|
||||
alter table gigo rename to ggiiggoo;
|
||||
alter table idx rename to idx2;
|
||||
}
|
||||
|
||||
do_execsql_test 23.3 {
|
||||
SELECT sql FROM sqlite_master;
|
||||
} {
|
||||
{CREATE TABLE "ggiiggoo"(a text)}
|
||||
{CREATE TABLE "idx2"(x text COLLATE compare64)}
|
||||
{CREATE VIEW v1 AS SELECT * FROM "idx2" WHERE x='abc'}
|
||||
}
|
||||
|
||||
do_execsql_test 23.4 {
|
||||
ALTER TABLE idx2 RENAME x TO y;
|
||||
SELECT sql FROM sqlite_master;
|
||||
} {
|
||||
{CREATE TABLE "ggiiggoo"(a text)}
|
||||
{CREATE TABLE "idx2"(y text COLLATE compare64)}
|
||||
{CREATE VIEW v1 AS SELECT * FROM "idx2" WHERE y='abc'}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
@@ -23,6 +23,16 @@ ifcapable !stat4 {
|
||||
return
|
||||
}
|
||||
|
||||
# This test cannot be run with the sqlite3_prepare() permutation, as it
|
||||
# tests that stat4 data can be used to influence the plans of queries
|
||||
# based on bound variable values. And this is not possible when using
|
||||
# sqlite3_prepare() - as queries cannot be internally re-prepared after
|
||||
# binding values are available.
|
||||
if {[permutation]=="prepare"} {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# Test Organization:
|
||||
#
|
||||
|
||||
+4
-4
@@ -75,10 +75,10 @@ do_execsql_test atof1-2.30 {
|
||||
CREATE INDEX i1 ON t1(a);
|
||||
SELECT count(*) FROM t1 WHERE substr(a,',');
|
||||
} {1}
|
||||
|
||||
|
||||
|
||||
|
||||
# 2020-08-27 OSSFuzz find related to the above.
|
||||
do_execsql_test atof1-2.40 {
|
||||
SELECT randomblob(0) - 1;
|
||||
} {-1}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
+1
-1
@@ -95,7 +95,7 @@ for {set i 0} {$i < 9} {incr i} {
|
||||
" [string map {"\n " "\n"} "
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t$t AS o USING COVERING INDEX sqlite_autoindex_t${t}_1
|
||||
`--CORRELATED SCALAR SUBQUERY
|
||||
`--CORRELATED SCALAR SUBQUERY xxxxxx
|
||||
`--SEARCH TABLE t$t AS i USING INTEGER PRIMARY KEY (rowid=?)
|
||||
"]
|
||||
}
|
||||
|
||||
@@ -131,5 +131,41 @@ do_multiclient_test tn {
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Check that even if the busy-handler fails (returns zero) within a
|
||||
# call to sqlite3_prepare() (or _v2(), or _v3()), it is still invoked
|
||||
# the next time an SQLITE_BUSY is encountered.
|
||||
#
|
||||
|
||||
do_multiclient_test tn {
|
||||
code1 {
|
||||
set ::busy_called 0
|
||||
proc busy {args} {
|
||||
if {$::busy_called} { return 1 }
|
||||
set ::busy_called 1
|
||||
return 0
|
||||
}
|
||||
db busy busy
|
||||
}
|
||||
|
||||
do_test 3.$tn.1 {
|
||||
sql2 {
|
||||
CREATE TABLE t1(x);
|
||||
BEGIN EXCLUSIVE;
|
||||
INSERT INTO t1 VALUES('x');
|
||||
}
|
||||
} {}
|
||||
|
||||
do_test 3.$tn.2 {
|
||||
set ::busy_called 0
|
||||
list [catch { sql1 { SELECT * FROM t1 } } msg] $msg $::busy_called
|
||||
} {1 {database is locked} 1}
|
||||
|
||||
do_test 3.$tn.3 {
|
||||
set ::busy_called 0
|
||||
list [catch { sql1 { SELECT * FROM t1 } } msg] $msg $::busy_called
|
||||
} {1 {database is locked} 1}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
@@ -474,5 +474,14 @@ ifcapable utf16 {
|
||||
} 1
|
||||
}
|
||||
|
||||
reset_db
|
||||
do_execsql_test cast-9.0 {
|
||||
CREATE TABLE t0(c0);
|
||||
INSERT INTO t0(c0) VALUES (0);
|
||||
CREATE VIEW v1(c0, c1) AS
|
||||
SELECT CAST(0.0 AS NUMERIC), COUNT(*) OVER () FROM t0;
|
||||
SELECT v1.c0 FROM v1, t0 WHERE v1.c0=0;
|
||||
} {0.0}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
+25
-19
@@ -40,7 +40,7 @@ do_test check-1.3 {
|
||||
catchsql {
|
||||
INSERT INTO t1 VALUES(6,7);
|
||||
}
|
||||
} {1 {CHECK constraint failed: t1}}
|
||||
} {1 {CHECK constraint failed: x<5}}
|
||||
do_test check-1.4 {
|
||||
execsql {
|
||||
SELECT * FROM t1;
|
||||
@@ -50,7 +50,7 @@ do_test check-1.5 {
|
||||
catchsql {
|
||||
INSERT INTO t1 VALUES(4,3);
|
||||
}
|
||||
} {1 {CHECK constraint failed: t1}}
|
||||
} {1 {CHECK constraint failed: y>x}}
|
||||
do_test check-1.6 {
|
||||
execsql {
|
||||
SELECT * FROM t1;
|
||||
@@ -87,7 +87,7 @@ do_test check-1.12 {
|
||||
catchsql {
|
||||
UPDATE t1 SET x=7 WHERE x==2
|
||||
}
|
||||
} {1 {CHECK constraint failed: t1}}
|
||||
} {1 {CHECK constraint failed: x<5}}
|
||||
do_test check-1.13 {
|
||||
execsql {
|
||||
SELECT * FROM t1;
|
||||
@@ -97,7 +97,7 @@ do_test check-1.14 {
|
||||
catchsql {
|
||||
UPDATE t1 SET x=5 WHERE x==2
|
||||
}
|
||||
} {1 {CHECK constraint failed: t1}}
|
||||
} {1 {CHECK constraint failed: x<5}}
|
||||
do_test check-1.15 {
|
||||
execsql {
|
||||
SELECT * FROM t1;
|
||||
@@ -186,7 +186,7 @@ do_test check-2.11 {
|
||||
catchsql {
|
||||
INSERT INTO t2b VALUES('xyzzy','hi',5);
|
||||
}
|
||||
} {1 {CHECK constraint failed: t2b}}
|
||||
} {1 {CHECK constraint failed: typeof(coalesce(x,0))=='integer'}}
|
||||
do_test check-2.12 {
|
||||
execsql {
|
||||
CREATE TABLE t2c(
|
||||
@@ -271,7 +271,7 @@ do_test check-3.9 {
|
||||
catchsql {
|
||||
INSERT INTO t3 VALUES(111,222,333);
|
||||
}
|
||||
} {1 {CHECK constraint failed: t3}}
|
||||
} {1 {CHECK constraint failed: t3.x<25}}
|
||||
|
||||
do_test check-4.1 {
|
||||
execsql {
|
||||
@@ -313,7 +313,10 @@ do_test check-4.6 {
|
||||
catchsql {
|
||||
UPDATE t4 SET x=0, y=1;
|
||||
}
|
||||
} {1 {CHECK constraint failed: t4}}
|
||||
} {1 {CHECK constraint failed: x+y==11
|
||||
OR x*y==12
|
||||
OR x/y BETWEEN 5 AND 8
|
||||
OR -x==y+10}}
|
||||
do_test check-4.7 {
|
||||
execsql {
|
||||
SELECT * FROM t4;
|
||||
@@ -335,7 +338,10 @@ do_test check-4.9 {
|
||||
catchsql {
|
||||
UPDATE t4 SET x=0, y=2;
|
||||
}
|
||||
} {1 {CHECK constraint failed: t4}}
|
||||
} {1 {CHECK constraint failed: x+y==11
|
||||
OR x*y==12
|
||||
OR x/y BETWEEN 5 AND 8
|
||||
OR -x==y+10}}
|
||||
ifcapable vacuum {
|
||||
do_test check_4.10 {
|
||||
catchsql {
|
||||
@@ -386,7 +392,7 @@ do_test check-6.5 {
|
||||
catchsql {
|
||||
UPDATE OR FAIL t1 SET x=7-x, y=y+1;
|
||||
}
|
||||
} {1 {CHECK constraint failed: t1}}
|
||||
} {1 {CHECK constraint failed: x<5}}
|
||||
do_test check-6.6 {
|
||||
execsql {
|
||||
SELECT * FROM t1;
|
||||
@@ -398,7 +404,7 @@ do_test check-6.7 {
|
||||
INSERT INTO t1 VALUES(1,30.0);
|
||||
INSERT OR ROLLBACK INTO t1 VALUES(8,40.0);
|
||||
}
|
||||
} {1 {CHECK constraint failed: t1}}
|
||||
} {1 {CHECK constraint failed: x<5}}
|
||||
do_test check-6.8 {
|
||||
catchsql {
|
||||
COMMIT;
|
||||
@@ -417,7 +423,7 @@ do_test check-6.12 {
|
||||
catchsql {
|
||||
REPLACE INTO t1 VALUES(6,7);
|
||||
}
|
||||
} {1 {CHECK constraint failed: t1}}
|
||||
} {1 {CHECK constraint failed: x<5}}
|
||||
do_test check-6.13 {
|
||||
execsql {SELECT * FROM t1}
|
||||
} {3 12.0 2 20.0}
|
||||
@@ -446,7 +452,7 @@ db func myfunc -deterministic myfunc
|
||||
do_execsql_test 7.1 { CREATE TABLE t6(a CHECK (myfunc(a))) }
|
||||
do_execsql_test 7.2 { INSERT INTO t6 VALUES(9) }
|
||||
do_catchsql_test 7.3 { INSERT INTO t6 VALUES(11) } \
|
||||
{1 {CHECK constraint failed: t6}}
|
||||
{1 {CHECK constraint failed: myfunc(a)}}
|
||||
|
||||
do_test 7.4 {
|
||||
sqlite3 db2 test.db
|
||||
@@ -469,7 +475,7 @@ do_test 7.7 {
|
||||
do_test 7.8 {
|
||||
db2 func myfunc myfunc
|
||||
catchsql { INSERT INTO t6 VALUES(12) } db2
|
||||
} {1 {CHECK constraint failed: t6}}
|
||||
} {1 {CHECK constraint failed: myfunc(a)}}
|
||||
|
||||
# 2013-08-02: Silently ignore database name qualifiers in CHECK constraints.
|
||||
#
|
||||
@@ -550,10 +556,10 @@ do_execsql_test 12.20 {
|
||||
} {}
|
||||
do_catchsql_test 12.21 {
|
||||
INSERT INTO t1(a) VALUES('xyz');
|
||||
} {1 {CHECK constraint failed: t1}}
|
||||
} {1 {CHECK constraint failed: a<>+a}}
|
||||
do_catchsql_test 12.22 {
|
||||
INSERT INTO t1(a) VALUES(123);
|
||||
} {1 {CHECK constraint failed: t1}}
|
||||
} {1 {CHECK constraint failed: a<>+a}}
|
||||
do_execsql_test 12.30 {
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1(a TEXT, CHECK(NOT(a=+a)));
|
||||
@@ -561,10 +567,10 @@ do_execsql_test 12.30 {
|
||||
} {}
|
||||
do_catchsql_test 12.31 {
|
||||
INSERT INTO t1(a) VALUES('xyz');
|
||||
} {1 {CHECK constraint failed: t1}}
|
||||
} {1 {CHECK constraint failed: NOT(a=+a)}}
|
||||
do_catchsql_test 12.32 {
|
||||
INSERT INTO t1(a) VALUES(123);
|
||||
} {1 {CHECK constraint failed: t1}}
|
||||
} {1 {CHECK constraint failed: NOT(a=+a)}}
|
||||
do_execsql_test 12.40 {
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1(a TEXT, CHECK(NOT(a<>+a)));
|
||||
@@ -585,7 +591,7 @@ do_execsql_test 12.60 {
|
||||
} {NULL}
|
||||
do_catchsql_test 12.61 {
|
||||
INSERT INTO t1(a) VALUES(456);
|
||||
} {1 {CHECK constraint failed: t1}}
|
||||
} {1 {CHECK constraint failed: a NOT BETWEEN 0 AND +a}}
|
||||
do_execsql_test 12.70 {
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1(a TEXT, CHECK(a BETWEEN +a AND 999999));
|
||||
@@ -600,6 +606,6 @@ do_execsql_test 12.80 {
|
||||
} {NULL}
|
||||
do_catchsql_test 12.81 {
|
||||
INSERT INTO t1(a) VALUES(456);
|
||||
} {1 {CHECK constraint failed: t1}}
|
||||
} {1 {CHECK constraint failed: a NOT BETWEEN +a AND 999999}}
|
||||
|
||||
finish_test
|
||||
|
||||
+1
-1
@@ -813,7 +813,7 @@ do_test conflict-13.1 {
|
||||
catchsql {
|
||||
REPLACE INTO t13 VALUES(2);
|
||||
}
|
||||
} {1 {CHECK constraint failed: t13}}
|
||||
} {1 {CHECK constraint failed: a!=2}}
|
||||
verify_ex_errcode conflict-13.1b SQLITE_CONSTRAINT_CHECK
|
||||
do_test conflict-13.2 {
|
||||
execsql {
|
||||
|
||||
+1
-1
@@ -811,7 +811,7 @@ do_test conflict2-13.1 {
|
||||
catchsql {
|
||||
REPLACE INTO t13 VALUES(2);
|
||||
}
|
||||
} {1 {CHECK constraint failed: t13}}
|
||||
} {1 {CHECK constraint failed: a!=2}}
|
||||
verify_ex_errcode conflict2-13.1b SQLITE_CONSTRAINT_CHECK
|
||||
do_test conflict2-13.2 {
|
||||
execsql {
|
||||
|
||||
+2
-2
@@ -36,7 +36,7 @@ do_execsql_test date2-120 {
|
||||
} {2017-07-20 one}
|
||||
do_catchsql_test date2-130 {
|
||||
INSERT INTO t1(x,y) VALUES('2017-08-01','two');
|
||||
} {1 {CHECK constraint failed: t1}}
|
||||
} {1 {CHECK constraint failed: date(x) BETWEEN '2017-07-01' AND '2017-07-31'}}
|
||||
|
||||
do_execsql_test date2-200 {
|
||||
CREATE TABLE t2(x,y);
|
||||
@@ -138,7 +138,7 @@ do_catchsql_test date2-601 {
|
||||
} {0 {}}
|
||||
do_catchsql_test date2-602 {
|
||||
INSERT INTO t601(a,b) VALUES(1e100, '1970-01-01');
|
||||
} {1 {CHECK constraint failed: t601}}
|
||||
} {1 {CHECK constraint failed: a<julianday(b)}}
|
||||
do_catchsql_test date2-603 {
|
||||
INSERT INTO t601(a,b) VALUES(10, 'now');
|
||||
} {1 {non-deterministic use of julianday() in a CHECK constraint}}
|
||||
|
||||
+1
-1
@@ -266,7 +266,7 @@ do_execsql_test 2030 {
|
||||
ANALYZE;
|
||||
}
|
||||
do_execsql_test 2040 {
|
||||
SELECT DISTINCT a, b, x FROM t3 CROSS JOIN t2 ORDER BY a;
|
||||
SELECT DISTINCT a, b, x FROM t3 CROSS JOIN t2 ORDER BY a, +b;
|
||||
} {
|
||||
one 0 1
|
||||
one 1 1
|
||||
|
||||
+11
-11
@@ -1433,20 +1433,20 @@ do_execsql_test 4.11 {
|
||||
}
|
||||
|
||||
do_createtable_tests 4.11 -error {CHECK constraint failed: %s} {
|
||||
1a "INSERT INTO x1 VALUES('one', 0)" {x1}
|
||||
1b "INSERT INTO t1 VALUES('one', -4.0)" {t1}
|
||||
1a "INSERT INTO x1 VALUES('one', 0)" {b>0}
|
||||
1b "INSERT INTO t1 VALUES('one', -4.0)" {b>0}
|
||||
|
||||
2a "INSERT INTO x2 VALUES('abc', 1)" {x2}
|
||||
2b "INSERT INTO t2 VALUES('abc', 1)" {t2}
|
||||
2a "INSERT INTO x2 VALUES('abc', 1)" {a||b}
|
||||
2b "INSERT INTO t2 VALUES('abc', 1)" {a||b}
|
||||
|
||||
3a "INSERT INTO x2 VALUES(0, 'abc')" {x2}
|
||||
3b "INSERT INTO t2 VALUES(0, 'abc')" {t2}
|
||||
3a "INSERT INTO x2 VALUES(0, 'abc')" {a||b}
|
||||
3b "INSERT INTO t2 VALUES(0, 'abc')" {a||b}
|
||||
|
||||
4a "UPDATE t1 SET b=-1 WHERE rowid=1" {t1}
|
||||
4b "UPDATE x1 SET b=-1 WHERE rowid=1" {x1}
|
||||
4a "UPDATE t1 SET b=-1 WHERE rowid=1" {b>0}
|
||||
4b "UPDATE x1 SET b=-1 WHERE rowid=1" {b>0}
|
||||
|
||||
4a "UPDATE x2 SET a='' WHERE rowid=1" {x2}
|
||||
4b "UPDATE t2 SET a='' WHERE rowid=1" {t2}
|
||||
4a "UPDATE x2 SET a='' WHERE rowid=1" {a||b}
|
||||
4b "UPDATE t2 SET a='' WHERE rowid=1" {a||b}
|
||||
}
|
||||
|
||||
# EVIDENCE-OF: R-34109-39108 If the CHECK expression evaluates to NULL,
|
||||
@@ -1639,7 +1639,7 @@ do_execsql_test 4.18.1 {
|
||||
do_execsql_test 4.18.2 { BEGIN; INSERT INTO t4 VALUES(5, 6) }
|
||||
do_catchsql_test 4.18.3 {
|
||||
INSERT INTO t4 SELECT a+4, b+4 FROM t4
|
||||
} {1 {CHECK constraint failed: t4}}
|
||||
} {1 {CHECK constraint failed: b!=10}}
|
||||
do_test e_createtable-4.18.4 { sqlite3_get_autocommit db } 0
|
||||
do_execsql_test 4.18.5 { SELECT * FROM t4 } {1 2 3 4 5 6}
|
||||
|
||||
|
||||
+2
-2
@@ -417,14 +417,14 @@ do_test fkey2-3.1.2 {
|
||||
} {}
|
||||
do_test fkey2-3.1.3 {
|
||||
catchsql { UPDATE ab SET a = 5 }
|
||||
} {1 {CHECK constraint failed: ef}}
|
||||
} {1 {CHECK constraint failed: e!=5}}
|
||||
do_test fkey2-3.1.4 {
|
||||
execsql { SELECT * FROM ab }
|
||||
} {1 b}
|
||||
do_test fkey2-3.1.4 {
|
||||
execsql BEGIN;
|
||||
catchsql { UPDATE ab SET a = 5 }
|
||||
} {1 {CHECK constraint failed: ef}}
|
||||
} {1 {CHECK constraint failed: e!=5}}
|
||||
do_test fkey2-3.1.5 {
|
||||
execsql COMMIT;
|
||||
execsql { SELECT * FROM ab; SELECT * FROM cd; SELECT * FROM ef }
|
||||
|
||||
+23
-23
@@ -381,32 +381,32 @@ ifcapable check {
|
||||
catchsql {
|
||||
INSERT INTO t1 (x) VALUES (NULL);
|
||||
}
|
||||
} {1 {CHECK constraint failed: t1}}
|
||||
} {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
|
||||
do_test func4-3.3 {
|
||||
catchsql {
|
||||
INSERT INTO t1 (x) VALUES (NULL);
|
||||
}
|
||||
} {1 {CHECK constraint failed: t1}}
|
||||
} {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
|
||||
do_test func4-3.4 {
|
||||
catchsql {
|
||||
INSERT INTO t1 (x) VALUES ('');
|
||||
}
|
||||
} {1 {CHECK constraint failed: t1}}
|
||||
} {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
|
||||
do_test func4-3.5 {
|
||||
catchsql {
|
||||
INSERT INTO t1 (x) VALUES ('bad');
|
||||
}
|
||||
} {1 {CHECK constraint failed: t1}}
|
||||
} {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
|
||||
do_test func4-3.6 {
|
||||
catchsql {
|
||||
INSERT INTO t1 (x) VALUES ('1234bad');
|
||||
}
|
||||
} {1 {CHECK constraint failed: t1}}
|
||||
} {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
|
||||
do_test func4-3.7 {
|
||||
catchsql {
|
||||
INSERT INTO t1 (x) VALUES ('1234.56bad');
|
||||
}
|
||||
} {1 {CHECK constraint failed: t1}}
|
||||
} {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
|
||||
do_test func4-3.8 {
|
||||
catchsql {
|
||||
INSERT INTO t1 (x) VALUES (1234);
|
||||
@@ -416,7 +416,7 @@ ifcapable check {
|
||||
catchsql {
|
||||
INSERT INTO t1 (x) VALUES (1234.56);
|
||||
}
|
||||
} {1 {CHECK constraint failed: t1}}
|
||||
} {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
|
||||
do_test func4-3.10 {
|
||||
catchsql {
|
||||
INSERT INTO t1 (x) VALUES ('1234');
|
||||
@@ -426,27 +426,27 @@ ifcapable check {
|
||||
catchsql {
|
||||
INSERT INTO t1 (x) VALUES ('1234.56');
|
||||
}
|
||||
} {1 {CHECK constraint failed: t1}}
|
||||
} {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
|
||||
do_test func4-3.12 {
|
||||
catchsql {
|
||||
INSERT INTO t1 (x) VALUES (ZEROBLOB(4));
|
||||
}
|
||||
} {1 {CHECK constraint failed: t1}}
|
||||
} {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
|
||||
do_test func4-3.13 {
|
||||
catchsql {
|
||||
INSERT INTO t1 (x) VALUES (X'');
|
||||
}
|
||||
} {1 {CHECK constraint failed: t1}}
|
||||
} {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
|
||||
do_test func4-3.14 {
|
||||
catchsql {
|
||||
INSERT INTO t1 (x) VALUES (X'1234');
|
||||
}
|
||||
} {1 {CHECK constraint failed: t1}}
|
||||
} {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
|
||||
do_test func4-3.15 {
|
||||
catchsql {
|
||||
INSERT INTO t1 (x) VALUES (X'12345678');
|
||||
}
|
||||
} {1 {CHECK constraint failed: t1}}
|
||||
} {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
|
||||
do_test func4-3.16 {
|
||||
catchsql {
|
||||
INSERT INTO t1 (x) VALUES ('1234.00');
|
||||
@@ -467,7 +467,7 @@ ifcapable check {
|
||||
catchsql {
|
||||
INSERT INTO t1 (x) VALUES (9223372036854775808);
|
||||
}
|
||||
} {1 {CHECK constraint failed: t1}}
|
||||
} {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
|
||||
}
|
||||
do_execsql_test func4-3.20 {
|
||||
SELECT x FROM t1 WHERE x>0 ORDER BY x;
|
||||
@@ -483,32 +483,32 @@ ifcapable check {
|
||||
catchsql {
|
||||
INSERT INTO t2 (x) VALUES (NULL);
|
||||
}
|
||||
} {1 {CHECK constraint failed: t2}}
|
||||
} {1 {CHECK constraint failed: toreal(x) IS NOT NULL}}
|
||||
do_test func4-4.3 {
|
||||
catchsql {
|
||||
INSERT INTO t2 (x) VALUES (NULL);
|
||||
}
|
||||
} {1 {CHECK constraint failed: t2}}
|
||||
} {1 {CHECK constraint failed: toreal(x) IS NOT NULL}}
|
||||
do_test func4-4.4 {
|
||||
catchsql {
|
||||
INSERT INTO t2 (x) VALUES ('');
|
||||
}
|
||||
} {1 {CHECK constraint failed: t2}}
|
||||
} {1 {CHECK constraint failed: toreal(x) IS NOT NULL}}
|
||||
do_test func4-4.5 {
|
||||
catchsql {
|
||||
INSERT INTO t2 (x) VALUES ('bad');
|
||||
}
|
||||
} {1 {CHECK constraint failed: t2}}
|
||||
} {1 {CHECK constraint failed: toreal(x) IS NOT NULL}}
|
||||
do_test func4-4.6 {
|
||||
catchsql {
|
||||
INSERT INTO t2 (x) VALUES ('1234bad');
|
||||
}
|
||||
} {1 {CHECK constraint failed: t2}}
|
||||
} {1 {CHECK constraint failed: toreal(x) IS NOT NULL}}
|
||||
do_test func4-4.7 {
|
||||
catchsql {
|
||||
INSERT INTO t2 (x) VALUES ('1234.56bad');
|
||||
}
|
||||
} {1 {CHECK constraint failed: t2}}
|
||||
} {1 {CHECK constraint failed: toreal(x) IS NOT NULL}}
|
||||
do_test func4-4.8 {
|
||||
catchsql {
|
||||
INSERT INTO t2 (x) VALUES (1234);
|
||||
@@ -533,22 +533,22 @@ ifcapable check {
|
||||
catchsql {
|
||||
INSERT INTO t2 (x) VALUES (ZEROBLOB(4));
|
||||
}
|
||||
} {1 {CHECK constraint failed: t2}}
|
||||
} {1 {CHECK constraint failed: toreal(x) IS NOT NULL}}
|
||||
do_test func4-4.13 {
|
||||
catchsql {
|
||||
INSERT INTO t2 (x) VALUES (X'');
|
||||
}
|
||||
} {1 {CHECK constraint failed: t2}}
|
||||
} {1 {CHECK constraint failed: toreal(x) IS NOT NULL}}
|
||||
do_test func4-4.14 {
|
||||
catchsql {
|
||||
INSERT INTO t2 (x) VALUES (X'1234');
|
||||
}
|
||||
} {1 {CHECK constraint failed: t2}}
|
||||
} {1 {CHECK constraint failed: toreal(x) IS NOT NULL}}
|
||||
do_test func4-4.15 {
|
||||
catchsql {
|
||||
INSERT INTO t2 (x) VALUES (X'12345678');
|
||||
}
|
||||
} {1 {CHECK constraint failed: t2}}
|
||||
} {1 {CHECK constraint failed: toreal(x) IS NOT NULL}}
|
||||
do_execsql_test func4-4.16 {
|
||||
SELECT x FROM t2 ORDER BY x;
|
||||
} {1234.0 1234.0 1234.56 1234.56}
|
||||
|
||||
+33
-9
@@ -627,7 +627,7 @@ static int decodeDatabase(
|
||||
unsigned char **paDecode, /* OUT: decoded database file */
|
||||
int *pnDecode /* OUT: Size of decoded database */
|
||||
){
|
||||
unsigned char *a; /* Database under construction */
|
||||
unsigned char *a, *aNew; /* Database under construction */
|
||||
int mx = 0; /* Current size of the database */
|
||||
sqlite3_uint64 nAlloc = 4096; /* Space allocated in a[] */
|
||||
unsigned int i; /* Next byte of zIn[] to read */
|
||||
@@ -673,11 +673,12 @@ static int decodeDatabase(
|
||||
}
|
||||
newSize = MX_FILE_SZ;
|
||||
}
|
||||
a = sqlite3_realloc64( a, newSize );
|
||||
if( a==0 ){
|
||||
fprintf(stderr, "Out of memory!\n");
|
||||
exit(1);
|
||||
aNew = sqlite3_realloc64( a, newSize );
|
||||
if( aNew==0 ){
|
||||
sqlite3_free(a);
|
||||
return -1;
|
||||
}
|
||||
a = aNew;
|
||||
assert( newSize > nAlloc );
|
||||
memset(a+nAlloc, 0, (size_t)(newSize - nAlloc));
|
||||
nAlloc = newSize;
|
||||
@@ -851,7 +852,8 @@ int runCombinedDbSqlInput(const uint8_t *aData, size_t nByte){
|
||||
int nAlloc = 0;
|
||||
int nNotUsed = 0;
|
||||
sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &nAlloc, &nNotUsed, 0);
|
||||
fprintf(stderr,"Memory leak in mutator: %lld bytes in %d allocations\n",
|
||||
fprintf(stderr,"memory leak prior to test start:"
|
||||
" %lld bytes in %d allocations\n",
|
||||
sqlite3_memory_used(), nAlloc);
|
||||
exit(1);
|
||||
}
|
||||
@@ -866,7 +868,10 @@ int runCombinedDbSqlInput(const uint8_t *aData, size_t nByte){
|
||||
fflush(stdout);
|
||||
}
|
||||
rc = sqlite3_open(0, &cx.db);
|
||||
if( rc ) return 1;
|
||||
if( rc ){
|
||||
sqlite3_free(aDb);
|
||||
return 1;
|
||||
}
|
||||
if( bVdbeDebug ){
|
||||
sqlite3_exec(cx.db, "PRAGMA vdbe_debug=ON", 0, 0, 0);
|
||||
}
|
||||
@@ -1410,7 +1415,8 @@ static void showHelp(void){
|
||||
" --export-sql DIR Write SQL to file(s) in DIR. Also works with --sqlid\n"
|
||||
" --help Show this help text\n"
|
||||
" --info Show information about SOURCE-DB w/o running tests\n"
|
||||
" --limit-depth N Limit expression depth to N\n"
|
||||
" --limit-depth N Limit expression depth to N. Default: 500\n"
|
||||
" --limit-heap N Limit heap memory to N. Default: 100M\n"
|
||||
" --limit-mem N Limit memory used by test SQLite instance to N bytes\n"
|
||||
" --limit-vdbe Panic if any test runs for more than 100,000 cycles\n"
|
||||
" --load-sql ARGS... Load SQL scripts fron files into SOURCE-DB\n"
|
||||
@@ -1424,6 +1430,7 @@ static void showHelp(void){
|
||||
" -q|--quiet Reduced output\n"
|
||||
" --rebuild Rebuild and vacuum the database file\n"
|
||||
" --result-trace Show the results of each SQL command\n"
|
||||
" --skip N Skip the first N test cases\n"
|
||||
" --spinner Use a spinner to show progress\n"
|
||||
" --sqlid N Use only SQL where sqlid=N\n"
|
||||
" --timeout N Abort if any single test needs more than N seconds\n"
|
||||
@@ -1451,6 +1458,7 @@ int main(int argc, char **argv){
|
||||
int rebuildFlag = 0; /* --rebuild */
|
||||
int vdbeLimitFlag = 0; /* --limit-vdbe */
|
||||
int infoFlag = 0; /* --info */
|
||||
int nSkip = 0; /* --skip */
|
||||
int bSpinner = 0; /* True for --spinner */
|
||||
int timeoutTest = 0; /* undocumented --timeout-test flag */
|
||||
int runFlags = 0; /* Flags sent to runSql() */
|
||||
@@ -1520,6 +1528,10 @@ int main(int argc, char **argv){
|
||||
if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
|
||||
depthLimit = integerValue(argv[++i]);
|
||||
}else
|
||||
if( strcmp(z,"limit-heap")==0 ){
|
||||
if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
|
||||
heapLimit = integerValue(argv[++i]);
|
||||
}else
|
||||
if( strcmp(z,"limit-mem")==0 ){
|
||||
if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
|
||||
nMem = integerValue(argv[++i]);
|
||||
@@ -1578,6 +1590,10 @@ int main(int argc, char **argv){
|
||||
if( strcmp(z,"result-trace")==0 ){
|
||||
runFlags |= SQL_OUTPUT;
|
||||
}else
|
||||
if( strcmp(z,"skip")==0 ){
|
||||
if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
|
||||
nSkip = atoi(argv[++i]);
|
||||
}else
|
||||
if( strcmp(z,"spinner")==0 ){
|
||||
bSpinner = 1;
|
||||
}else
|
||||
@@ -1898,7 +1914,11 @@ int main(int argc, char **argv){
|
||||
prevAmt = amt;
|
||||
}
|
||||
}
|
||||
runCombinedDbSqlInput(pSql->a, pSql->sz);
|
||||
if( nSkip>0 ){
|
||||
nSkip--;
|
||||
}else{
|
||||
runCombinedDbSqlInput(pSql->a, pSql->sz);
|
||||
}
|
||||
nTest++;
|
||||
g.zTestName[0] = 0;
|
||||
disableOom();
|
||||
@@ -1927,6 +1947,10 @@ int main(int argc, char **argv){
|
||||
prevAmt = amt;
|
||||
}
|
||||
}
|
||||
if( nSkip>0 ){
|
||||
nSkip--;
|
||||
continue;
|
||||
}
|
||||
createVFile("main.db", pDb->sz, pDb->a);
|
||||
sqlite3_randomness(0,0);
|
||||
if( ossFuzzThisDb ){
|
||||
|
||||
Binary file not shown.
+7
-1
@@ -332,7 +332,7 @@ do_test in-10.2 {
|
||||
catchsql {
|
||||
INSERT INTO t5 VALUES(4);
|
||||
}
|
||||
} {1 {CHECK constraint failed: t5}}
|
||||
} {1 {CHECK constraint failed: a IN (111,222,333)}}
|
||||
|
||||
# Ticket #1821
|
||||
#
|
||||
@@ -791,4 +791,10 @@ do_execsql_test in-19.40 {
|
||||
PRAGMA integrity_check;
|
||||
} {ok}
|
||||
|
||||
# Ticket f3ff1472887
|
||||
#
|
||||
do_execsql_test in-20.1 {
|
||||
SELECT (1 IN (2 IS TRUE));
|
||||
} {1}
|
||||
|
||||
finish_test
|
||||
|
||||
+5
-5
@@ -55,7 +55,7 @@ do_test insert4-1.1 {
|
||||
catchsql {
|
||||
INSERT INTO t1 SELECT * FROM t2;
|
||||
}
|
||||
} {1 {CHECK constraint failed: t1}}
|
||||
} {1 {CHECK constraint failed: b>a}}
|
||||
xferopt_test insert4-1.2 0
|
||||
do_test insert4-1.3 {
|
||||
execsql {
|
||||
@@ -102,7 +102,7 @@ do_test insert4-2.3.3 {
|
||||
INSERT INTO t1 SELECT * FROM t2 LIMIT 1;
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {1 {CHECK constraint failed: t1}}
|
||||
} {1 {CHECK constraint failed: b>a}}
|
||||
xferopt_test insert4-2.3.4 0
|
||||
|
||||
# Do not run the transfer optimization if there is a DISTINCT
|
||||
@@ -120,7 +120,7 @@ do_test insert4-2.4.3 {
|
||||
DELETE FROM t1;
|
||||
INSERT INTO t1 SELECT DISTINCT * FROM t2;
|
||||
}
|
||||
} {1 {CHECK constraint failed: t1}}
|
||||
} {1 {CHECK constraint failed: b>a}}
|
||||
xferopt_test insert4-2.4.4 0
|
||||
|
||||
# The following procedure constructs two tables then tries to transfer
|
||||
@@ -316,7 +316,7 @@ do_test insert4-6.6 {
|
||||
catchsql {
|
||||
INSERT INTO t6b SELECT * FROM t6a;
|
||||
}
|
||||
} {1 {CHECK constraint failed: t6b}}
|
||||
} {1 {CHECK constraint failed: x<>'abc' COLLATE nocase}}
|
||||
do_test insert4-6.7 {
|
||||
execsql {
|
||||
DROP TABLE t6b;
|
||||
@@ -325,7 +325,7 @@ do_test insert4-6.7 {
|
||||
catchsql {
|
||||
INSERT INTO t6b SELECT * FROM t6a;
|
||||
}
|
||||
} {1 {CHECK constraint failed: t6b}}
|
||||
} {1 {CHECK constraint failed: x COLLATE nocase <>'abc'}}
|
||||
|
||||
# Ticket [6284df89debdfa61db8073e062908af0c9b6118e]
|
||||
# Disable the xfer optimization if the destination table contains
|
||||
|
||||
+5
-5
@@ -112,16 +112,16 @@ do_execsql_test istrue-520 {
|
||||
} {1 1 0 {} {}}
|
||||
do_catchsql_test istrue-521 {
|
||||
INSERT INTO t2 VALUES(2,false,false,null,null);
|
||||
} {1 {CHECK constraint failed: t2}}
|
||||
} {1 {CHECK constraint failed: b IS TRUE}}
|
||||
do_catchsql_test istrue-522 {
|
||||
INSERT INTO t2 VALUES(2,true,true,null,null);
|
||||
} {1 {CHECK constraint failed: t2}}
|
||||
} {1 {CHECK constraint failed: c IS FALSE}}
|
||||
do_catchsql_test istrue-523 {
|
||||
INSERT INTO t2 VALUES(2,true,false,true,null);
|
||||
} {1 {CHECK constraint failed: t2}}
|
||||
} {1 {CHECK constraint failed: d IS NOT TRUE}}
|
||||
do_catchsql_test istrue-524 {
|
||||
INSERT INTO t2 VALUES(2,true,false,null,false);
|
||||
} {1 {CHECK constraint failed: t2}}
|
||||
} {1 {CHECK constraint failed: e IS NOT FALSE}}
|
||||
|
||||
foreach {tn val} [list 1 NaN 2 -NaN 3 NaN0 4 -NaN0 5 Inf 6 -Inf] {
|
||||
do_execsql_test istrue-600.$tn.1 {
|
||||
@@ -193,7 +193,7 @@ do_execsql_test istrue-840 {
|
||||
} {}
|
||||
do_catchsql_test istrue-841 {
|
||||
INSERT INTO False VALUES(5,6,7);
|
||||
} {1 {CHECK constraint failed: false}}
|
||||
} {1 {CHECK constraint failed: 5 IN (false.false)}}
|
||||
do_execsql_test istrue-850 {
|
||||
SELECT 9 IN (false.false) FROM false;
|
||||
} {0}
|
||||
|
||||
+14
-1
@@ -1025,5 +1025,18 @@ do_execsql_test join-24.2 {
|
||||
SELECT * FROM t2 LEFT JOIN t1 ON a=0 WHERE (x='x' OR x IS NULL);
|
||||
} {1 {} {}}
|
||||
|
||||
finish_test
|
||||
# 2020-09-30 ticket 66e4b0e271c47145
|
||||
# The query flattener inserts an "expr AND expr" expression as a substitution
|
||||
# for the column of a view where that view column is part of an ON expression
|
||||
# of a LEFT JOIN.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test join-25.1 {
|
||||
CREATE TABLE t0(c0 INT);
|
||||
CREATE VIEW v0 AS SELECT (NULL AND 5) as c0 FROM t0;
|
||||
INSERT INTO t0(c0) VALUES (NULL);
|
||||
SELECT count(*) FROM v0 LEFT JOIN t0 ON v0.c0;
|
||||
} {1}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
+16
-1
@@ -294,7 +294,10 @@ do_execsql_test 8.1 {
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Ticket [45f4bf4eb].
|
||||
# Ticket [45f4bf4eb] reported by Manuel Rigger (2020-04-25)
|
||||
#
|
||||
# Follow up error reported by Eric Speckman on the SQLite forum
|
||||
# https://sqlite.org/forum/info/c49496d24d35bd7c (2020-08-19)
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 9.0 {
|
||||
@@ -324,5 +327,17 @@ do_execsql_test 9.5 {
|
||||
UNION SELECT 0,0 WHERE 0;
|
||||
} {0 0}
|
||||
|
||||
do_execsql_test 9.10 {
|
||||
CREATE TABLE t1 (aaa);
|
||||
INSERT INTO t1 VALUES(23456);
|
||||
CREATE TABLE t2(bbb);
|
||||
CREATE VIEW v2(ccc) AS SELECT bbb IS 1234 FROM t2;
|
||||
SELECT ccc, ccc IS NULL AS ddd FROM t1 LEFT JOIN v2;
|
||||
} {{} 1}
|
||||
optimization_control db query-flattener 0
|
||||
do_execsql_test 9.11 {
|
||||
SELECT ccc, ccc IS NULL AS ddd FROM t1 LEFT JOIN v2;
|
||||
} {{} 1}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -147,6 +147,22 @@ ifcapable compound {
|
||||
} {1 91 92 3 93 5}
|
||||
}
|
||||
|
||||
do_execsql_test join6-5.1 {
|
||||
CREATE TABLE tx(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o PRIMARY KEY)
|
||||
WITHOUT ROWID;
|
||||
INSERT INTO tx VALUES(
|
||||
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
|
||||
);
|
||||
} {}
|
||||
do_execsql_test joint6-5.2 {
|
||||
SELECT o FROM tx NATURAL JOIN tx;
|
||||
} {15}
|
||||
|
||||
do_execsql_test join6-5.3 {
|
||||
CREATE TABLE ty(a,Ñ,x6,x7,x8,Q,I,v,x1,L,E,x2,x3,x4,x5,s,g PRIMARY KEY,b,c)
|
||||
WITHOUT ROWID;
|
||||
SELECT a FROM ty NATURAL JOIN ty;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -296,5 +296,12 @@ do_execsql_test null-9.3 {
|
||||
SELECT * FROM t5 WHERE a IS NULL AND b = 'x';
|
||||
} {{} x two {} x ii}
|
||||
|
||||
# 2020-09-30 ticket 5c4e7aa793943803
|
||||
reset_db
|
||||
do_execsql_test null-10.1 {
|
||||
CREATE TABLE t0(c0 PRIMARY KEY DESC);
|
||||
INSERT INTO t0(c0) VALUES (0);
|
||||
SELECT * FROM t0 WHERE t0.c0 > NULL;
|
||||
} {}
|
||||
|
||||
finish_test
|
||||
|
||||
+1
-1
@@ -276,7 +276,7 @@ do_execsql_test pager1-3.1.2 {
|
||||
} {3 0}
|
||||
do_catchsql_test pager1-3.1.3 {
|
||||
INSERT INTO t1 SELECT a+3, randomblob(1500) FROM t1
|
||||
} {1 {CHECK constraint failed: counter}}
|
||||
} {1 {CHECK constraint failed: i<5}}
|
||||
do_execsql_test pager1-3.4 { SELECT * FROM counter } {3 0}
|
||||
do_execsql_test pager1-3.5 { SELECT a FROM t1 } {1 2 3}
|
||||
do_execsql_test pager1-3.6 { COMMIT } {}
|
||||
|
||||
+1
-1
@@ -122,7 +122,7 @@ do_execsql_test 2.3.1 {
|
||||
}
|
||||
do_catchsql_test 2.3.2 {
|
||||
INSERT INTO xyz VALUES(1, 2, 'null');
|
||||
} {1 {CHECK constraint failed: xyz}}
|
||||
} {1 {CHECK constraint failed: c!="null"}}
|
||||
|
||||
do_execsql_test 2.4 {
|
||||
INSERT INTO t1 VALUES(1, 2, 3);
|
||||
|
||||
@@ -54,9 +54,10 @@ array set ::Configs [strip_comments {
|
||||
-DSQLITE_ENABLE_DESERIALIZE
|
||||
}
|
||||
"Sanitize" {
|
||||
CC=clang -fsanitize=undefined
|
||||
CC=clang -fsanitize=address,undefined
|
||||
-DSQLITE_ENABLE_STAT4
|
||||
--enable-session
|
||||
--enable-debug
|
||||
--enable-all
|
||||
}
|
||||
"Stdcall" {
|
||||
-DUSE_STDCALL=1
|
||||
@@ -135,6 +136,11 @@ array set ::Configs [strip_comments {
|
||||
-DSQLITE_MUTATION_TEST
|
||||
--enable-fts5 --enable-json1
|
||||
}
|
||||
"Debug-Two" {
|
||||
-DSQLITE_DEFAULT_MEMSTATUS=0
|
||||
-DSQLITE_MAX_EXPR_DEPTH=0
|
||||
--enable-debug
|
||||
}
|
||||
"Fast-One" {
|
||||
-O6
|
||||
-DSQLITE_ENABLE_FTS4=1
|
||||
@@ -142,6 +148,7 @@ array set ::Configs [strip_comments {
|
||||
-DSQLITE_ENABLE_STAT4
|
||||
-DSQLITE_ENABLE_RBU
|
||||
-DSQLITE_MAX_ATTACHED=125
|
||||
-DSQLITE_MAX_MMAP_SIZE=12884901888
|
||||
-DLONGDOUBLE_TYPE=double
|
||||
--enable-session
|
||||
}
|
||||
@@ -284,6 +291,7 @@ array set ::Platforms [strip_comments {
|
||||
"Check-Symbols*" checksymbols
|
||||
"Fast-One" "fuzztest test"
|
||||
"Debug-One" "mptest test"
|
||||
"Debug-Two" "test"
|
||||
"Have-Not" test
|
||||
"Secure-Delete" test
|
||||
"Unlock-Notify" "QUICKTEST_INCLUDE=notify2.test test"
|
||||
@@ -294,7 +302,7 @@ array set ::Platforms [strip_comments {
|
||||
"No-lookaside" test
|
||||
"Devkit" test
|
||||
"Apple" test
|
||||
"Sanitize" {QUICKTEST_OMIT=func4.test,nan.test test}
|
||||
"Sanitize" {QUICKTEST_OMIT=crash*,shell*,sqldiff*,sessionB.test test}
|
||||
"Device-One" fulltest
|
||||
"Default" "threadtest fulltest"
|
||||
"Valgrind*" valgrindtest
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user