Compare commits
167 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d49a37a8ef | |||
| 86732babe3 | |||
| 228a52d973 | |||
| 6117a17323 | |||
| d1c472dab6 | |||
| b008e4d744 | |||
| 367b8d7aa7 | |||
| 9a50f4c72a | |||
| f0578823dd | |||
| 23d3f5d661 | |||
| e2b7a7693e | |||
| cfee884e73 | |||
| 5e81e9fdae | |||
| 905d4729d3 | |||
| 018dbb17a8 | |||
| 5c0666d9e3 | |||
| 5f419b3bba | |||
| e4079e1fc5 | |||
| ebc6408484 | |||
| 818a3b5486 | |||
| 7971b7fe92 | |||
| 91f34eab2d | |||
| 9d30c8ff8f | |||
| ec39707fe6 | |||
| d79cd92b23 | |||
| a51ddb1ed7 | |||
| b19131a8c6 | |||
| 2829df082c | |||
| e7579a53fb | |||
| edf8a7bf57 | |||
| 1116b1785c | |||
| c5b35ae567 | |||
| 37d296a717 | |||
| 5776ee5cf5 | |||
| 7ca1347f59 | |||
| b7fc7c8556 | |||
| e39f388eb1 | |||
| 8c9bcb2328 | |||
| e47d5ca737 | |||
| af9b58b335 | |||
| ed09dddece | |||
| 14e3e22773 | |||
| 6d2566dfc2 | |||
| 572b0dddee | |||
| aa16c603ab | |||
| 4b48c72721 | |||
| 9d70284022 | |||
| ec722c1088 | |||
| e691dcb506 | |||
| 97b0250599 | |||
| 70738712de | |||
| 91f473b5cc | |||
| 130dbc3d96 | |||
| 2ad35d980b | |||
| b42eb3571c | |||
| 8cce6b8310 | |||
| d44c617ad4 | |||
| fab5b07395 | |||
| 51a75aaa76 | |||
| e087a7c35b | |||
| cd9cb85a41 | |||
| 477f1f12e2 | |||
| 01a3b6b1b2 | |||
| 945a3527d5 | |||
| 3f3f2c7357 | |||
| fbb9a5b1e3 | |||
| 685b2ee0c3 | |||
| acf6e08d20 | |||
| c204d81a6c | |||
| fa50834914 | |||
| d5deb6b3c4 | |||
| e08663946e | |||
| e2ba6df9f0 | |||
| 1a97c413f8 | |||
| 7dc3547eeb | |||
| c7d12f4ad4 | |||
| 4fc836546e | |||
| 229ae1ae72 | |||
| dd668c26b5 | |||
| 0167ef202b | |||
| bffdd63633 | |||
| cc80db69e9 | |||
| 35a38e0836 | |||
| 81d25cf53d | |||
| 80f6bfc064 | |||
| f66bfcb740 | |||
| 6a19865ff2 | |||
| 7314495ff8 | |||
| a7ce167e5b | |||
| efb5f9a173 | |||
| 9889ede28d | |||
| db3a32ed1c | |||
| 1cac1766df | |||
| ac6627327c | |||
| 8b47f52082 | |||
| ae144a1c9f | |||
| 7a231b4973 | |||
| 38cefc83c8 | |||
| f4d9c9822d | |||
| bd717a4d2e | |||
| 9d23ea74d4 | |||
| db586e4843 | |||
| f76ccb7d54 | |||
| b6a9121bb3 | |||
| 1cd382e350 | |||
| 50b3ea2daf | |||
| 0b79824ec5 | |||
| 6ee3fa87fd | |||
| 010bdb4c79 | |||
| 2e51716b15 | |||
| 8085d53d3c | |||
| e893759cac | |||
| 7ec796d002 | |||
| 790b37a240 | |||
| 6397a78b2b | |||
| 512e46a74c | |||
| d790c9a161 | |||
| 554a9dc78a | |||
| d86fe44ab5 | |||
| e2754c1fba | |||
| 666a42ffb3 | |||
| 298680d15a | |||
| ee37f8b0a3 | |||
| ee6c5e5ae7 | |||
| a31d3554c5 | |||
| 5f6a4ea2e2 | |||
| 0086e07865 | |||
| ec3dda5b11 | |||
| 74e1b861ad | |||
| 505ae9def8 | |||
| a677eecad3 | |||
| 0d950af311 | |||
| af8664020a | |||
| 3e36480232 | |||
| f236b21f4b | |||
| 37874d7dcc | |||
| 2ebb550824 | |||
| f7c92e82d2 | |||
| 6fcb9f3ad9 | |||
| 546738f855 | |||
| 35fb866ea3 | |||
| 2a0c16f276 | |||
| 4fcb9caa60 | |||
| 4780b9ad46 | |||
| 95da9d5d46 | |||
| b6ce71bd26 | |||
| 3722b3abf1 | |||
| b6e0286c49 | |||
| 8c754a3613 | |||
| ae8e45cb0c | |||
| 9105fd5189 | |||
| dac7e69dc2 | |||
| 5976b2c805 | |||
| 5df8428069 | |||
| 87ca8067af | |||
| c324d44690 | |||
| 8328369740 | |||
| cc491f4b1b | |||
| 9e9a67adb0 | |||
| 5b32bdff80 | |||
| cc3f3d1f05 | |||
| 217ca657d8 | |||
| cc5979dbd3 | |||
| 15750a26fa | |||
| 4043cfef75 | |||
| 11d88e68ab | |||
| 6e11892db8 |
@@ -609,7 +609,6 @@ SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
|
||||
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
|
||||
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
|
||||
SHELL_OPT += -DSQLITE_ENABLE_DESERIALIZE
|
||||
SHELL_OPT += -DSQLITE_INTROSPECTION_PRAGMAS
|
||||
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
|
||||
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ
|
||||
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
|
||||
|
||||
+9
-17
@@ -19,7 +19,7 @@ TOP = ../sqlite
|
||||
#### C Compiler and options for use in building executables that
|
||||
# will run on the platform that is doing the build.
|
||||
#
|
||||
BCC = gcc -g -O2
|
||||
BCC = gcc -g -O0
|
||||
#BCC = /opt/ancic/bin/c89 -0
|
||||
|
||||
#### If the target operating system supports the "usleep()" system
|
||||
@@ -38,8 +38,8 @@ THREADSAFE = -DTHREADSAFE=0
|
||||
#### Specify any extra linker options needed to make the library
|
||||
# thread safe
|
||||
#
|
||||
#THREADLIB = -lpthread
|
||||
THREADLIB =
|
||||
THREADLIB = -lpthread -lm -ldl
|
||||
#THREADLIB =
|
||||
|
||||
#### Specify any extra libraries needed to access required functions.
|
||||
#
|
||||
@@ -54,11 +54,9 @@ TLIBS =
|
||||
# You can make the library go almost twice as fast if you compile
|
||||
# with -DNDEBUG=1
|
||||
#
|
||||
#OPTS = -DSQLITE_DEBUG=2
|
||||
#OPTS = -DSQLITE_DEBUG=1
|
||||
#OPTS =
|
||||
OPTS = -DNDEBUG=1
|
||||
OPTS += -DHAVE_FDATASYNC=1
|
||||
OPTS += -DSQLITE_DEBUG=1
|
||||
OPTS += -DSQLITE_ENABLE_WHERETRACE
|
||||
OPTS += -DSQLITE_ENABLE_SELECTTRACE
|
||||
|
||||
#### The suffix to add to executable files. ".exe" for windows.
|
||||
# Nothing for unix.
|
||||
@@ -70,7 +68,7 @@ EXE =
|
||||
# will run on the target platform. This is usually the same
|
||||
# as BCC, unless you are cross-compiling.
|
||||
#
|
||||
TCC = gcc -O6
|
||||
TCC = gcc -O0
|
||||
#TCC = gcc -g -O0 -Wall
|
||||
#TCC = gcc -g -O0 -Wall -fprofile-arcs -ftest-coverage
|
||||
#TCC = /opt/mingw/bin/i386-mingw32-gcc -O6
|
||||
@@ -91,18 +89,12 @@ SHPREFIX = lib
|
||||
|
||||
#### Extra compiler options needed for programs that use the TCL library.
|
||||
#
|
||||
#TCL_FLAGS =
|
||||
#TCL_FLAGS = -DSTATIC_BUILD=1
|
||||
TCL_FLAGS = -I/home/drh/tcltk/8.5linux
|
||||
#TCL_FLAGS = -I/home/drh/tcltk/8.5win -DSTATIC_BUILD=1
|
||||
#TCL_FLAGS = -I/home/drh/tcltk/8.3hpux
|
||||
TCL_FLAGS = -I/home/drh/tcl/include/tcl8.6
|
||||
|
||||
#### Linker options needed to link against the TCL library.
|
||||
#
|
||||
#LIBTCL = -ltcl -lm -ldl
|
||||
LIBTCL = /home/drh/tcltk/8.5linux/libtcl8.5g.a -lm -ldl
|
||||
#LIBTCL = /home/drh/tcltk/8.5win/libtcl85s.a -lmsvcrt
|
||||
#LIBTCL = /home/drh/tcltk/8.3hpux/libtcl8.3.a -ldld -lm -lc
|
||||
LIBTCL = /home/drh/tcl/lib/libtcl8.6.a -lm -lpthread -ldl -lz
|
||||
|
||||
#### Additional objects for SQLite library when TCL support is enabled.
|
||||
#TCLOBJ =
|
||||
|
||||
@@ -351,7 +351,6 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_JSON1=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBSTAT_VTAB=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_INTROSPECTION_PRAGMAS=1
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DESERIALIZE=1
|
||||
!ENDIF
|
||||
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
|
||||
|
||||
@@ -134,6 +134,7 @@ do_setup_rec_test $tn.5 {
|
||||
SEARCH TABLE t1 USING COVERING INDEX t1_idx_000123a7 (a=?)
|
||||
}
|
||||
|
||||
if 0 {
|
||||
do_setup_rec_test $tn.6 {
|
||||
CREATE TABLE t1(a, b, c);
|
||||
} {
|
||||
@@ -142,6 +143,7 @@ do_setup_rec_test $tn.6 {
|
||||
CREATE INDEX t1_idx_00000061 ON t1(a);
|
||||
SEARCH TABLE t1 USING COVERING INDEX t1_idx_00000061
|
||||
}
|
||||
}
|
||||
|
||||
do_setup_rec_test $tn.7 {
|
||||
CREATE TABLE t1(a, b, c);
|
||||
|
||||
+22
-18
@@ -308,6 +308,18 @@
|
||||
SQLITE_EXTENSION_INIT1
|
||||
#endif
|
||||
|
||||
/*
|
||||
** The following are copied from sqliteInt.h.
|
||||
**
|
||||
** Constants for the largest and smallest possible 64-bit signed integers.
|
||||
** These macros are designed to work correctly on both 32-bit and 64-bit
|
||||
** compilers.
|
||||
*/
|
||||
#ifndef SQLITE_AMALGAMATION
|
||||
# define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32))
|
||||
# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64)
|
||||
#endif
|
||||
|
||||
static int fts3EvalNext(Fts3Cursor *pCsr);
|
||||
static int fts3EvalStart(Fts3Cursor *pCsr);
|
||||
static int fts3TermSegReaderCursor(
|
||||
@@ -2086,10 +2098,11 @@ static void fts3ColumnlistCopy(char **pp, char **ppPoslist){
|
||||
}
|
||||
|
||||
/*
|
||||
** Value used to signify the end of an position-list. This is safe because
|
||||
** it is not possible to have a document with 2^31 terms.
|
||||
** Value used to signify the end of an position-list. This must be
|
||||
** as large or larger than any value that might appear on the
|
||||
** position-list, even a position list that has been corrupted.
|
||||
*/
|
||||
#define POSITION_LIST_END 0x7fffffff
|
||||
#define POSITION_LIST_END LARGEST_INT64
|
||||
|
||||
/*
|
||||
** This function is used to help parse position-lists. When this function is
|
||||
@@ -2165,14 +2178,14 @@ static int fts3PoslistMerge(
|
||||
fts3GetVarint32(&p1[1], &iCol1);
|
||||
if( iCol1==0 ) return FTS_CORRUPT_VTAB;
|
||||
}
|
||||
else if( *p1==POS_END ) iCol1 = POSITION_LIST_END;
|
||||
else if( *p1==POS_END ) iCol1 = 0x7fffffff;
|
||||
else iCol1 = 0;
|
||||
|
||||
if( *p2==POS_COLUMN ){
|
||||
fts3GetVarint32(&p2[1], &iCol2);
|
||||
if( iCol2==0 ) return FTS_CORRUPT_VTAB;
|
||||
}
|
||||
else if( *p2==POS_END ) iCol2 = POSITION_LIST_END;
|
||||
else if( *p2==POS_END ) iCol2 = 0x7fffffff;
|
||||
else iCol2 = 0;
|
||||
|
||||
if( iCol1==iCol2 ){
|
||||
@@ -2474,7 +2487,8 @@ static void fts3PutDeltaVarint3(
|
||||
iWrite = *piPrev - iVal;
|
||||
}
|
||||
assert( *pbFirst || *piPrev==0 );
|
||||
assert( *pbFirst==0 || iWrite>0 );
|
||||
assert_fts3_nc( *pbFirst==0 || iWrite>0 );
|
||||
assert( *pbFirst==0 || iWrite>=0 );
|
||||
*pp += sqlite3Fts3PutVarint(*pp, iWrite);
|
||||
*piPrev = iVal;
|
||||
*pbFirst = 1;
|
||||
@@ -2580,6 +2594,8 @@ static int fts3DoclistOrMerge(
|
||||
fts3PoslistCopy(&p, &p2);
|
||||
fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2);
|
||||
}
|
||||
|
||||
assert( (p-aOut)<=((p1?(p1-a1):n1)+(p2?(p2-a2):n2)+FTS3_VARINT_MAX-1) );
|
||||
}
|
||||
|
||||
if( rc!=SQLITE_OK ){
|
||||
@@ -3179,18 +3195,6 @@ static int fts3NextMethod(sqlite3_vtab_cursor *pCursor){
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** The following are copied from sqliteInt.h.
|
||||
**
|
||||
** Constants for the largest and smallest possible 64-bit signed integers.
|
||||
** These macros are designed to work correctly on both 32-bit and 64-bit
|
||||
** compilers.
|
||||
*/
|
||||
#ifndef SQLITE_AMALGAMATION
|
||||
# define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32))
|
||||
# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** If the numeric type of argument pVal is "integer", then return it
|
||||
** converted to a 64-bit signed integer. Otherwise, return a copy of
|
||||
|
||||
@@ -433,10 +433,10 @@ static void fts3SnippetDetails(
|
||||
|
||||
while( iCsr<(iStart+pIter->nSnippet) && iCsr>=iStart ){
|
||||
int j;
|
||||
u64 mPhrase = (u64)1 << i;
|
||||
u64 mPhrase = (u64)1 << (i%64);
|
||||
u64 mPos = (u64)1 << (iCsr - iStart);
|
||||
assert( iCsr>=iStart && (iCsr - iStart)<=64 );
|
||||
assert( i>=0 && i<=64 );
|
||||
assert( i>=0 );
|
||||
if( (mCover|mCovered)&mPhrase ){
|
||||
iScore++;
|
||||
}else{
|
||||
|
||||
@@ -3797,14 +3797,14 @@ static int nodeReaderInit(NodeReader *p, const char *aNode, int nNode){
|
||||
p->nNode = nNode;
|
||||
|
||||
/* Figure out if this is a leaf or an internal node. */
|
||||
if( p->aNode[0] ){
|
||||
if( aNode && aNode[0] ){
|
||||
/* An internal node. */
|
||||
p->iOff = 1 + sqlite3Fts3GetVarint(&p->aNode[1], &p->iChild);
|
||||
}else{
|
||||
p->iOff = 1;
|
||||
}
|
||||
|
||||
return nodeReaderNext(p);
|
||||
return aNode ? nodeReaderNext(p) : SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4296,8 +4296,8 @@ static int fts3IncrmergeLoad(
|
||||
NodeReader reader;
|
||||
pNode = &pWriter->aNodeWriter[i];
|
||||
|
||||
rc = nodeReaderInit(&reader, pNode->block.a, pNode->block.n);
|
||||
if( reader.aNode ){
|
||||
if( pNode->block.a){
|
||||
rc = nodeReaderInit(&reader, pNode->block.a, pNode->block.n);
|
||||
while( reader.aNode && rc==SQLITE_OK ) rc = nodeReaderNext(&reader);
|
||||
blobGrowBuffer(&pNode->key, reader.term.n, &rc);
|
||||
if( rc==SQLITE_OK ){
|
||||
|
||||
@@ -695,6 +695,7 @@ int sqlite3Fts5ExprEof(Fts5Expr*);
|
||||
i64 sqlite3Fts5ExprRowid(Fts5Expr*);
|
||||
|
||||
void sqlite3Fts5ExprFree(Fts5Expr*);
|
||||
int sqlite3Fts5ExprAnd(Fts5Expr **pp1, Fts5Expr *p2);
|
||||
|
||||
/* Called during startup to register a UDF with SQLite */
|
||||
int sqlite3Fts5ExprInit(Fts5Global*, sqlite3*);
|
||||
|
||||
@@ -683,7 +683,7 @@ int sqlite3Fts5ConfigDeclareVtab(Fts5Config *pConfig){
|
||||
rc = sqlite3_declare_vtab(pConfig->db, zSql);
|
||||
sqlite3_free(zSql);
|
||||
}
|
||||
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@@ -309,6 +309,42 @@ void sqlite3Fts5ExprFree(Fts5Expr *p){
|
||||
}
|
||||
}
|
||||
|
||||
int sqlite3Fts5ExprAnd(Fts5Expr **pp1, Fts5Expr *p2){
|
||||
Fts5Parse sParse;
|
||||
memset(&sParse, 0, sizeof(sParse));
|
||||
|
||||
if( *pp1 ){
|
||||
Fts5Expr *p1 = *pp1;
|
||||
int nPhrase = p1->nPhrase + p2->nPhrase;
|
||||
|
||||
p1->pRoot = sqlite3Fts5ParseNode(&sParse, FTS5_AND, p1->pRoot, p2->pRoot,0);
|
||||
p2->pRoot = 0;
|
||||
|
||||
if( sParse.rc==SQLITE_OK ){
|
||||
Fts5ExprPhrase **ap = (Fts5ExprPhrase**)sqlite3_realloc(
|
||||
p1->apExprPhrase, nPhrase * sizeof(Fts5ExprPhrase*)
|
||||
);
|
||||
if( ap==0 ){
|
||||
sParse.rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
int i;
|
||||
memmove(&ap[p2->nPhrase], ap, p1->nPhrase*sizeof(Fts5ExprPhrase*));
|
||||
for(i=0; i<p2->nPhrase; i++){
|
||||
ap[i] = p2->apExprPhrase[i];
|
||||
}
|
||||
p1->nPhrase = nPhrase;
|
||||
p1->apExprPhrase = ap;
|
||||
}
|
||||
}
|
||||
sqlite3_free(p2->apExprPhrase);
|
||||
sqlite3_free(p2);
|
||||
}else{
|
||||
*pp1 = p2;
|
||||
}
|
||||
|
||||
return sParse.rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Argument pTerm must be a synonym iterator. Return the current rowid
|
||||
** that it points to.
|
||||
|
||||
+11
-2
@@ -713,7 +713,7 @@ static void fts5DataRelease(Fts5Data *pData){
|
||||
static Fts5Data *fts5LeafRead(Fts5Index *p, i64 iRowid){
|
||||
Fts5Data *pRet = fts5DataRead(p, iRowid);
|
||||
if( pRet ){
|
||||
if( pRet->szLeaf>pRet->nn ){
|
||||
if( pRet->nn<4 || pRet->szLeaf>pRet->nn ){
|
||||
p->rc = FTS5_CORRUPT;
|
||||
fts5DataRelease(pRet);
|
||||
pRet = 0;
|
||||
@@ -4997,9 +4997,12 @@ static void fts5MergePrefixLists(
|
||||
Fts5PoslistWriter writer;
|
||||
memset(&writer, 0, sizeof(writer));
|
||||
|
||||
/* See the earlier comment in this function for an explanation of why
|
||||
** corrupt input position lists might cause the output to consume
|
||||
** at most 20 bytes of unexpected space. */
|
||||
fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid);
|
||||
fts5BufferZero(&tmp);
|
||||
sqlite3Fts5BufferSize(&p->rc, &tmp, i1.nPoslist + i2.nPoslist);
|
||||
sqlite3Fts5BufferSize(&p->rc, &tmp, i1.nPoslist + i2.nPoslist + 10 + 10);
|
||||
if( p->rc ) break;
|
||||
|
||||
sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1);
|
||||
@@ -5047,6 +5050,12 @@ static void fts5MergePrefixLists(
|
||||
}
|
||||
|
||||
/* WRITEPOSLISTSIZE */
|
||||
assert_nc( tmp.n<=i1.nPoslist+i2.nPoslist );
|
||||
assert( tmp.n<=i1.nPoslist+i2.nPoslist+10+10 );
|
||||
if( tmp.n>i1.nPoslist+i2.nPoslist ){
|
||||
if( p->rc==SQLITE_OK ) p->rc = FTS5_CORRUPT;
|
||||
break;
|
||||
}
|
||||
fts5BufferSafeAppendVarint(&out, tmp.n * 2);
|
||||
fts5BufferSafeAppendBlob(&out, tmp.p, tmp.n);
|
||||
fts5DoclistIterNext(&i1);
|
||||
|
||||
+166
-108
@@ -465,17 +465,39 @@ static void fts5SetUniqueFlag(sqlite3_index_info *pIdxInfo){
|
||||
** Implementation of the xBestIndex method for FTS5 tables. Within the
|
||||
** WHERE constraint, it searches for the following:
|
||||
**
|
||||
** 1. A MATCH constraint against the special column.
|
||||
** 1. A MATCH constraint against the table column.
|
||||
** 2. A MATCH constraint against the "rank" column.
|
||||
** 3. An == constraint against the rowid column.
|
||||
** 4. A < or <= constraint against the rowid column.
|
||||
** 5. A > or >= constraint against the rowid column.
|
||||
** 3. A MATCH constraint against some other column.
|
||||
** 4. An == constraint against the rowid column.
|
||||
** 5. A < or <= constraint against the rowid column.
|
||||
** 6. A > or >= constraint against the rowid column.
|
||||
**
|
||||
** Within the ORDER BY, either:
|
||||
** Within the ORDER BY, the following are supported:
|
||||
**
|
||||
** 5. ORDER BY rank [ASC|DESC]
|
||||
** 6. ORDER BY rowid [ASC|DESC]
|
||||
**
|
||||
** Information for the xFilter call is passed via both the idxNum and
|
||||
** idxStr variables. Specifically, idxNum is a bitmask of the following
|
||||
** flags used to encode the ORDER BY clause:
|
||||
**
|
||||
** FTS5_BI_ORDER_RANK
|
||||
** FTS5_BI_ORDER_ROWID
|
||||
** FTS5_BI_ORDER_DESC
|
||||
**
|
||||
** idxStr is used to encode data from the WHERE clause. For each argument
|
||||
** passed to the xFilter method, the following is appended to idxStr:
|
||||
**
|
||||
** Match against table column: "m"
|
||||
** Match against rank column: "r"
|
||||
** Match against other column: "<column-number>"
|
||||
** Equality constraint against the rowid: "="
|
||||
** A < or <= against the rowid: "<"
|
||||
** A > or >= against the rowid: ">"
|
||||
**
|
||||
** This function ensures that there is at most one "r" or "=". And that if
|
||||
** there exists an "=" then there is no "<" or ">".
|
||||
**
|
||||
** Costs are assigned as follows:
|
||||
**
|
||||
** a) If an unusable MATCH operator is present in the WHERE clause, the
|
||||
@@ -503,32 +525,18 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
|
||||
Fts5Config *pConfig = pTab->pConfig;
|
||||
const int nCol = pConfig->nCol;
|
||||
int idxFlags = 0; /* Parameter passed through to xFilter() */
|
||||
int bHasMatch;
|
||||
int iNext;
|
||||
int i;
|
||||
|
||||
struct Constraint {
|
||||
int op; /* Mask against sqlite3_index_constraint.op */
|
||||
int fts5op; /* FTS5 mask for idxFlags */
|
||||
int iCol; /* 0==rowid, 1==tbl, 2==rank */
|
||||
int omit; /* True to omit this if found */
|
||||
int iConsIndex; /* Index in pInfo->aConstraint[] */
|
||||
} aConstraint[] = {
|
||||
{SQLITE_INDEX_CONSTRAINT_MATCH|SQLITE_INDEX_CONSTRAINT_EQ,
|
||||
FTS5_BI_MATCH, 1, 1, -1},
|
||||
{SQLITE_INDEX_CONSTRAINT_MATCH|SQLITE_INDEX_CONSTRAINT_EQ,
|
||||
FTS5_BI_RANK, 2, 1, -1},
|
||||
{SQLITE_INDEX_CONSTRAINT_EQ, FTS5_BI_ROWID_EQ, 0, 0, -1},
|
||||
{SQLITE_INDEX_CONSTRAINT_LT|SQLITE_INDEX_CONSTRAINT_LE,
|
||||
FTS5_BI_ROWID_LE, 0, 0, -1},
|
||||
{SQLITE_INDEX_CONSTRAINT_GT|SQLITE_INDEX_CONSTRAINT_GE,
|
||||
FTS5_BI_ROWID_GE, 0, 0, -1},
|
||||
};
|
||||
char *idxStr;
|
||||
int iIdxStr = 0;
|
||||
int iCons = 0;
|
||||
|
||||
int bSeenEq = 0;
|
||||
int bSeenGt = 0;
|
||||
int bSeenLt = 0;
|
||||
int bSeenMatch = 0;
|
||||
int bSeenRank = 0;
|
||||
|
||||
int aColMap[3];
|
||||
aColMap[0] = -1;
|
||||
aColMap[1] = nCol;
|
||||
aColMap[2] = nCol+1;
|
||||
|
||||
assert( SQLITE_INDEX_CONSTRAINT_EQ<SQLITE_INDEX_CONSTRAINT_MATCH );
|
||||
assert( SQLITE_INDEX_CONSTRAINT_GT<SQLITE_INDEX_CONSTRAINT_MATCH );
|
||||
@@ -543,40 +551,78 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
|
||||
/* Set idxFlags flags for all WHERE clause terms that will be used. */
|
||||
idxStr = (char*)sqlite3_malloc(pInfo->nConstraint * 6 + 1);
|
||||
if( idxStr==0 ) return SQLITE_NOMEM;
|
||||
pInfo->idxStr = idxStr;
|
||||
pInfo->needToFreeIdxStr = 1;
|
||||
|
||||
for(i=0; i<pInfo->nConstraint; i++){
|
||||
struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
|
||||
int iCol = p->iColumn;
|
||||
|
||||
if( (p->op==SQLITE_INDEX_CONSTRAINT_MATCH && iCol>=0 && iCol<=nCol)
|
||||
|| (p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol==nCol)
|
||||
if( p->op==SQLITE_INDEX_CONSTRAINT_MATCH
|
||||
|| (p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol>=nCol)
|
||||
){
|
||||
/* A MATCH operator or equivalent */
|
||||
if( p->usable ){
|
||||
idxFlags = (idxFlags & 0xFFFF) | FTS5_BI_MATCH | (iCol << 16);
|
||||
aConstraint[0].iConsIndex = i;
|
||||
}else{
|
||||
if( p->usable==0 || iCol<0 ){
|
||||
/* As there exists an unusable MATCH constraint this is an
|
||||
** unusable plan. Set a prohibitively high cost. */
|
||||
pInfo->estimatedCost = 1e50;
|
||||
assert( iIdxStr < pInfo->nConstraint*6 + 1 );
|
||||
idxStr[iIdxStr] = 0;
|
||||
return SQLITE_OK;
|
||||
}else{
|
||||
if( iCol==nCol+1 ){
|
||||
if( bSeenRank ) continue;
|
||||
idxStr[iIdxStr++] = 'r';
|
||||
bSeenRank = 1;
|
||||
}else{
|
||||
bSeenMatch = 1;
|
||||
idxStr[iIdxStr++] = 'm';
|
||||
if( iCol<nCol ){
|
||||
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->op<=SQLITE_INDEX_CONSTRAINT_MATCH ){
|
||||
int j;
|
||||
for(j=1; j<ArraySize(aConstraint); j++){
|
||||
struct Constraint *pC = &aConstraint[j];
|
||||
if( iCol==aColMap[pC->iCol] && (p->op & pC->op) && p->usable ){
|
||||
pC->iConsIndex = i;
|
||||
idxFlags |= pC->fts5op;
|
||||
}
|
||||
else if( p->usable && bSeenEq==0
|
||||
&& p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol<0
|
||||
){
|
||||
idxStr[iIdxStr++] = '=';
|
||||
bSeenEq = 1;
|
||||
pInfo->aConstraintUsage[i].argvIndex = ++iCons;
|
||||
}
|
||||
}
|
||||
|
||||
if( bSeenEq==0 ){
|
||||
for(i=0; i<pInfo->nConstraint; i++){
|
||||
struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
|
||||
if( p->iColumn<0 && p->usable ){
|
||||
int op = p->op;
|
||||
if( op==SQLITE_INDEX_CONSTRAINT_LT || op==SQLITE_INDEX_CONSTRAINT_LE ){
|
||||
if( bSeenLt ) continue;
|
||||
idxStr[iIdxStr++] = '<';
|
||||
pInfo->aConstraintUsage[i].argvIndex = ++iCons;
|
||||
bSeenLt = 1;
|
||||
}else
|
||||
if( op==SQLITE_INDEX_CONSTRAINT_GT || op==SQLITE_INDEX_CONSTRAINT_GE ){
|
||||
if( bSeenGt ) continue;
|
||||
idxStr[iIdxStr++] = '>';
|
||||
pInfo->aConstraintUsage[i].argvIndex = ++iCons;
|
||||
bSeenGt = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
idxStr[iIdxStr] = '\0';
|
||||
|
||||
/* Set idxFlags flags for the ORDER BY clause */
|
||||
if( pInfo->nOrderBy==1 ){
|
||||
int iSort = pInfo->aOrderBy[0].iColumn;
|
||||
if( iSort==(pConfig->nCol+1) && BitFlagTest(idxFlags, FTS5_BI_MATCH) ){
|
||||
if( iSort==(pConfig->nCol+1) && bSeenMatch ){
|
||||
idxFlags |= FTS5_BI_ORDER_RANK;
|
||||
}else if( iSort==-1 ){
|
||||
idxFlags |= FTS5_BI_ORDER_ROWID;
|
||||
@@ -590,26 +636,15 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
|
||||
}
|
||||
|
||||
/* Calculate the estimated cost based on the flags set in idxFlags. */
|
||||
bHasMatch = BitFlagTest(idxFlags, FTS5_BI_MATCH);
|
||||
if( BitFlagTest(idxFlags, FTS5_BI_ROWID_EQ) ){
|
||||
pInfo->estimatedCost = bHasMatch ? 100.0 : 10.0;
|
||||
if( bHasMatch==0 ) fts5SetUniqueFlag(pInfo);
|
||||
}else if( BitFlagAllTest(idxFlags, FTS5_BI_ROWID_LE|FTS5_BI_ROWID_GE) ){
|
||||
pInfo->estimatedCost = bHasMatch ? 500.0 : 250000.0;
|
||||
}else if( BitFlagTest(idxFlags, FTS5_BI_ROWID_LE|FTS5_BI_ROWID_GE) ){
|
||||
pInfo->estimatedCost = bHasMatch ? 750.0 : 750000.0;
|
||||
if( bSeenEq ){
|
||||
pInfo->estimatedCost = bSeenMatch ? 100.0 : 10.0;
|
||||
if( bSeenMatch==0 ) fts5SetUniqueFlag(pInfo);
|
||||
}else if( bSeenLt && bSeenGt ){
|
||||
pInfo->estimatedCost = bSeenMatch ? 500.0 : 250000.0;
|
||||
}else if( bSeenLt || bSeenGt ){
|
||||
pInfo->estimatedCost = bSeenMatch ? 750.0 : 750000.0;
|
||||
}else{
|
||||
pInfo->estimatedCost = bHasMatch ? 1000.0 : 1000000.0;
|
||||
}
|
||||
|
||||
/* Assign argvIndex values to each constraint in use. */
|
||||
iNext = 1;
|
||||
for(i=0; i<ArraySize(aConstraint); i++){
|
||||
struct Constraint *pC = &aConstraint[i];
|
||||
if( pC->iConsIndex>=0 ){
|
||||
pInfo->aConstraintUsage[pC->iConsIndex].argvIndex = iNext++;
|
||||
pInfo->aConstraintUsage[pC->iConsIndex].omit = (unsigned char)pC->omit;
|
||||
}
|
||||
pInfo->estimatedCost = bSeenMatch ? 1000.0 : 1000000.0;
|
||||
}
|
||||
|
||||
pInfo->idxNum = idxFlags;
|
||||
@@ -932,7 +967,7 @@ static int fts5CursorFirstSorted(
|
||||
**
|
||||
** If SQLite a built-in statement cache, this wouldn't be a problem. */
|
||||
rc = fts5PrepareStatement(&pSorter->pStmt, pConfig,
|
||||
"SELECT rowid, rank FROM %Q.%Q ORDER BY %s(%s%s%s) %s",
|
||||
"SELECT rowid, rank FROM %Q.%Q ORDER BY %s(\"%w\"%s%s) %s",
|
||||
pConfig->zDb, pConfig->zName, zRank, pConfig->zName,
|
||||
(zRankArgs ? ", " : ""),
|
||||
(zRankArgs ? zRankArgs : ""),
|
||||
@@ -988,10 +1023,10 @@ static int fts5SpecialMatch(
|
||||
assert( pTab->p.base.zErrMsg==0 );
|
||||
pCsr->ePlan = FTS5_PLAN_SPECIAL;
|
||||
|
||||
if( 0==sqlite3_strnicmp("reads", z, n) ){
|
||||
if( n==5 && 0==sqlite3_strnicmp("reads", z, n) ){
|
||||
pCsr->iSpecial = sqlite3Fts5IndexReads(pTab->p.pIndex);
|
||||
}
|
||||
else if( 0==sqlite3_strnicmp("id", z, n) ){
|
||||
else if( n==2 && 0==sqlite3_strnicmp("id", z, n) ){
|
||||
pCsr->iSpecial = pCsr->iCsrId;
|
||||
}
|
||||
else{
|
||||
@@ -1132,7 +1167,7 @@ static i64 fts5GetRowidLimit(sqlite3_value *pVal, i64 iDefault){
|
||||
static int fts5FilterMethod(
|
||||
sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */
|
||||
int idxNum, /* Strategy index */
|
||||
const char *zUnused, /* Unused */
|
||||
const char *idxStr, /* Unused */
|
||||
int nVal, /* Number of elements in apVal */
|
||||
sqlite3_value **apVal /* Arguments for the indexing scheme */
|
||||
){
|
||||
@@ -1140,19 +1175,17 @@ static int fts5FilterMethod(
|
||||
Fts5Config *pConfig = pTab->p.pConfig;
|
||||
Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
|
||||
int rc = SQLITE_OK; /* Error code */
|
||||
int iVal = 0; /* Counter for apVal[] */
|
||||
int bDesc; /* True if ORDER BY [rank|rowid] DESC */
|
||||
int bOrderByRank; /* True if ORDER BY rank */
|
||||
sqlite3_value *pMatch = 0; /* <tbl> MATCH ? expression (or NULL) */
|
||||
sqlite3_value *pRank = 0; /* rank MATCH ? expression (or NULL) */
|
||||
sqlite3_value *pRowidEq = 0; /* rowid = ? expression (or NULL) */
|
||||
sqlite3_value *pRowidLe = 0; /* rowid <= ? expression (or NULL) */
|
||||
sqlite3_value *pRowidGe = 0; /* rowid >= ? expression (or NULL) */
|
||||
int iCol; /* Column on LHS of MATCH operator */
|
||||
char **pzErrmsg = pConfig->pzErrmsg;
|
||||
|
||||
UNUSED_PARAM(zUnused);
|
||||
UNUSED_PARAM(nVal);
|
||||
int i;
|
||||
int iIdxStr = 0;
|
||||
Fts5Expr *pExpr = 0;
|
||||
|
||||
if( pCsr->ePlan ){
|
||||
fts5FreeCursorComponents(pCsr);
|
||||
@@ -1165,23 +1198,60 @@ static int fts5FilterMethod(
|
||||
assert( pCsr->pRank==0 );
|
||||
assert( pCsr->zRank==0 );
|
||||
assert( pCsr->zRankArgs==0 );
|
||||
assert( pTab->pSortCsr==0 || nVal==0 );
|
||||
|
||||
assert( pzErrmsg==0 || pzErrmsg==&pTab->p.base.zErrMsg );
|
||||
pConfig->pzErrmsg = &pTab->p.base.zErrMsg;
|
||||
|
||||
/* Decode the arguments passed through to this function.
|
||||
**
|
||||
** Note: The following set of if(...) statements must be in the same
|
||||
** order as the corresponding entries in the struct at the top of
|
||||
** fts5BestIndexMethod(). */
|
||||
if( BitFlagTest(idxNum, FTS5_BI_MATCH) ) pMatch = apVal[iVal++];
|
||||
if( BitFlagTest(idxNum, FTS5_BI_RANK) ) pRank = apVal[iVal++];
|
||||
if( BitFlagTest(idxNum, FTS5_BI_ROWID_EQ) ) pRowidEq = apVal[iVal++];
|
||||
if( BitFlagTest(idxNum, FTS5_BI_ROWID_LE) ) pRowidLe = apVal[iVal++];
|
||||
if( BitFlagTest(idxNum, FTS5_BI_ROWID_GE) ) pRowidGe = apVal[iVal++];
|
||||
iCol = (idxNum>>16);
|
||||
assert( iCol>=0 && iCol<=pConfig->nCol );
|
||||
assert( iVal==nVal );
|
||||
/* Decode the arguments passed through to this function. */
|
||||
for(i=0; i<nVal; i++){
|
||||
switch( idxStr[iIdxStr++] ){
|
||||
case 'r':
|
||||
pRank = apVal[i];
|
||||
break;
|
||||
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;
|
||||
}
|
||||
|
||||
if( zText[0]=='*' ){
|
||||
/* The user has issued a query of the form "MATCH '*...'". This
|
||||
** indicates that the MATCH expression is not a full text query,
|
||||
** but a request for an internal parameter. */
|
||||
rc = fts5SpecialMatch(pTab, pCsr, &zText[1]);
|
||||
goto filter_out;
|
||||
}else{
|
||||
char **pzErr = &pTab->p.base.zErrMsg;
|
||||
rc = sqlite3Fts5ExprNew(pConfig, iCol, zText, &pExpr, pzErr);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3Fts5ExprAnd(&pCsr->pExpr, pExpr);
|
||||
pExpr = 0;
|
||||
}
|
||||
if( rc!=SQLITE_OK ) goto filter_out;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case '=':
|
||||
pRowidEq = apVal[i];
|
||||
break;
|
||||
case '<':
|
||||
pRowidLe = apVal[i];
|
||||
break;
|
||||
default: assert( idxStr[iIdxStr-1]=='>' );
|
||||
pRowidGe = apVal[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
bOrderByRank = ((idxNum & FTS5_BI_ORDER_RANK) ? 1 : 0);
|
||||
pCsr->bDesc = bDesc = ((idxNum & FTS5_BI_ORDER_DESC) ? 1 : 0);
|
||||
|
||||
@@ -1208,7 +1278,7 @@ static int fts5FilterMethod(
|
||||
** (pCursor) is used to execute the query issued by function
|
||||
** fts5CursorFirstSorted() above. */
|
||||
assert( pRowidEq==0 && pRowidLe==0 && pRowidGe==0 && pRank==0 );
|
||||
assert( nVal==0 && pMatch==0 && bOrderByRank==0 && bDesc==0 );
|
||||
assert( nVal==0 && bOrderByRank==0 && bDesc==0 );
|
||||
assert( pCsr->iLastRowid==LARGEST_INT64 );
|
||||
assert( pCsr->iFirstRowid==SMALLEST_INT64 );
|
||||
if( pTab->pSortCsr->bDesc ){
|
||||
@@ -1221,29 +1291,15 @@ static int fts5FilterMethod(
|
||||
pCsr->ePlan = FTS5_PLAN_SOURCE;
|
||||
pCsr->pExpr = pTab->pSortCsr->pExpr;
|
||||
rc = fts5CursorFirst(pTab, pCsr, bDesc);
|
||||
}else if( pMatch ){
|
||||
const char *zExpr = (const char*)sqlite3_value_text(apVal[0]);
|
||||
if( zExpr==0 ) zExpr = "";
|
||||
|
||||
}else if( pCsr->pExpr ){
|
||||
rc = fts5CursorParseRank(pConfig, pCsr, pRank);
|
||||
if( rc==SQLITE_OK ){
|
||||
if( zExpr[0]=='*' ){
|
||||
/* The user has issued a query of the form "MATCH '*...'". This
|
||||
** indicates that the MATCH expression is not a full text query,
|
||||
** but a request for an internal parameter. */
|
||||
rc = fts5SpecialMatch(pTab, pCsr, &zExpr[1]);
|
||||
if( bOrderByRank ){
|
||||
pCsr->ePlan = FTS5_PLAN_SORTED_MATCH;
|
||||
rc = fts5CursorFirstSorted(pTab, pCsr, bDesc);
|
||||
}else{
|
||||
char **pzErr = &pTab->p.base.zErrMsg;
|
||||
rc = sqlite3Fts5ExprNew(pConfig, iCol, zExpr, &pCsr->pExpr, pzErr);
|
||||
if( rc==SQLITE_OK ){
|
||||
if( bOrderByRank ){
|
||||
pCsr->ePlan = FTS5_PLAN_SORTED_MATCH;
|
||||
rc = fts5CursorFirstSorted(pTab, pCsr, bDesc);
|
||||
}else{
|
||||
pCsr->ePlan = FTS5_PLAN_MATCH;
|
||||
rc = fts5CursorFirst(pTab, pCsr, bDesc);
|
||||
}
|
||||
}
|
||||
pCsr->ePlan = FTS5_PLAN_MATCH;
|
||||
rc = fts5CursorFirst(pTab, pCsr, bDesc);
|
||||
}
|
||||
}
|
||||
}else if( pConfig->zContent==0 ){
|
||||
@@ -1260,7 +1316,7 @@ static int fts5FilterMethod(
|
||||
);
|
||||
if( rc==SQLITE_OK ){
|
||||
if( pCsr->ePlan==FTS5_PLAN_ROWID ){
|
||||
sqlite3_bind_value(pCsr->pStmt, 1, apVal[0]);
|
||||
sqlite3_bind_value(pCsr->pStmt, 1, pRowidEq);
|
||||
}else{
|
||||
sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iFirstRowid);
|
||||
sqlite3_bind_int64(pCsr->pStmt, 2, pCsr->iLastRowid);
|
||||
@@ -1269,6 +1325,8 @@ static int fts5FilterMethod(
|
||||
}
|
||||
}
|
||||
|
||||
filter_out:
|
||||
sqlite3Fts5ExprFree(pExpr);
|
||||
pConfig->pzErrmsg = pzErrmsg;
|
||||
return rc;
|
||||
}
|
||||
@@ -2239,7 +2297,7 @@ static void fts5ApiCallback(
|
||||
iCsrId = sqlite3_value_int64(argv[0]);
|
||||
|
||||
pCsr = fts5CursorFromCsrid(pAux->pGlobal, iCsrId);
|
||||
if( pCsr==0 ){
|
||||
if( pCsr==0 || pCsr->ePlan==0 ){
|
||||
char *zErr = sqlite3_mprintf("no such cursor: %lld", iCsrId);
|
||||
sqlite3_result_error(context, zErr, -1);
|
||||
sqlite3_free(zErr);
|
||||
|
||||
+447
-39
@@ -767,7 +767,7 @@ SELECT * FROM t1 WHERE t1 MATCH 'abandon';
|
||||
|
||||
do_catchsql_test 13.1 {
|
||||
SELECT * FROM t1 WHERE t1 MATCH 'abandon';
|
||||
} {1 {vtable constructor failed: t1}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
@@ -958,7 +958,7 @@ do_test 15.0 {
|
||||
|
||||
do_catchsql_test 15.1 {
|
||||
INSERT INTO t1(t1) VALUES('integrity-check');
|
||||
} {1 {database disk image is malformed}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
#
|
||||
@@ -3903,19 +3903,19 @@ do_test 33.0 {
|
||||
| end crash-fed6e90021ba5d.db
|
||||
}]} {}
|
||||
|
||||
do_execsql_test 33.1 {
|
||||
do_catchsql_test 33.1 {
|
||||
CREATE VIRTUAL TABLE t2 USING fts5vocab('t1','row');
|
||||
CREATE VIRTUAL TABLE t3 USING fts5vocab('t1','col');
|
||||
CREATE VIRTUAL TABLE t4 USING fts5vocab('t1','instance');
|
||||
}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
do_catchsql_test 33.2 {
|
||||
SELECT * FROM t2;
|
||||
} {1 {database disk image is malformed}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
do_catchsql_test 33.3 {
|
||||
SELECT * FROM t2, t3, t4 WHERE t2.term=t3.term AND t3.term=t4.term;
|
||||
} {1 {database disk image is malformed}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
@@ -4637,17 +4637,17 @@ do_test 37.0 {
|
||||
|
||||
do_catchsql_test 37.1 {
|
||||
SELECT * FROM t3;
|
||||
} {1 {database disk image is malformed}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 37.0 {
|
||||
do_execsql_test 37a.0 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(b, c);
|
||||
INSERT INTO t1 VALUES('a', 'b');
|
||||
SELECT quote(block) FROM t1_data WHERE rowid=10;
|
||||
} {X'000000000101010001010101'}
|
||||
|
||||
do_execsql_test 37.1 {
|
||||
do_execsql_test 37a.1 {
|
||||
UPDATE t1_data SET block = X'FFFFFFFF0101010001010101' WHERE rowid = 10;
|
||||
SELECT rowid FROM t1('a');
|
||||
} {1}
|
||||
@@ -4894,7 +4894,7 @@ do_test 38.0 {
|
||||
|
||||
do_catchsql_test 38.1 {
|
||||
UPDATE t1 SET b=quote(zeroblob(200)) WHERE t1 MATCH 'thread*';
|
||||
} {0 {}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
@@ -5326,16 +5326,16 @@ do_test 40.0 {
|
||||
| end crash2.txt.db
|
||||
}]} {}
|
||||
|
||||
do_execsql_test 40.1 {
|
||||
do_catchsql_test 40.1 {
|
||||
BEGIN;
|
||||
INSERT INTO t1(b) VALUES(X'819192e578de3fa24af3733ca8769291a0fee3669f9fddefc5cba913e4225d4b6ce2b04f26b87fad3ee6f9b7d90a1ea62a169bf41e5d32707a6ca5c3d05e4bde05c9d89eaaa8c50e74333d2e9fcd7dfe95528a3a016aac1102d825c5cd70cf99d8a88e0ea7f798d4334386518b7ad359beb168b93aba059a2a3bd93112d65b44c12b9904ea786b204d80531cdf0504bf9b203dbe927061974caf7b9f30cbc3397b61f802e732012a6663d41c3607d6f1c0dbcfd489adac05ca500c0b04439d894cd93a840159225ef73b627e178b9f84b3ffe66cf22a963a8368813ff7961fc47f573211ccec95e0220dcbb3bf429f4a50ba54d7a53784ac51bf');
|
||||
INSERT INTO t1(b) VALUES(X'c8ae0d0e7c3175946e62ba2b449511d4eb504079984a20f77969f62206c9f3d7ea25358ab705e6978627290b6d48db9032f815a06a79a4f4b809841a0942eed12954ed166f666111812a508abc3bec87958846edaec0a6fe14564bc0a4b78f1c35ebcacca6bae29cc37ae9b59d8a2d7593af1e47dda0ece2268a98d20febafad037964f139851f9a57f48b3706b01721769071991412044cd6006f1d72eb6eb4aa5ad77e378176db8c15575fbeee47165e38a7c6c5a557ac2dfe11813976eaf6741cf593a9e457053a3c34cddfbe605a6e25419f993de8374fafcd3636509d8416a51dc7bcc14cfca322ae343078f47e23522431c17d0da0c033');
|
||||
INSERT INTO t1(b) VALUES(X'dc29a94e873a45a4243fce9b912aaefbadf1d0423e0345793874b356eeb500b92fb05284c1601fe9bad3143f72162f10242cec27c44ebf764c8fc9fb0824e32c4161472a4f914f579e0e8274f08ca1a02e59b9d8eec1f31061f9ccb9ed97a6f06534e991f7992c761489e6a7724f6e9c2b581e77487ded3a986d53c4419bbd3e9747cee300e670dd7294874c77e2ed48da68eaa6c3ec954a09ac410493d98e34d6686e54fbbe80696705f10e040c66093efb40746b33600685c94c664c7942835a9e954866121d5dcfb2cb12e92521ea3df175ee17072502dad9b9c1565f801b2179799011eb7418bfa00323e3157589e648ff7378be233c79b7');
|
||||
}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
do_catchsql_test 40.2 {
|
||||
INSERT INTO t1(a,b) VALUES(1,11),(2,22),(3, true ),(4,44);
|
||||
} {1 {database disk image is malformed}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
@@ -5789,7 +5789,7 @@ do_test 43.0 {
|
||||
|
||||
do_catchsql_test 43.1 {
|
||||
INSERT INTO t1(t1) VALUES('optimize');
|
||||
} {1 {database disk image is malformed}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
@@ -6047,7 +6047,7 @@ do_catchsql_test 45.2 {
|
||||
INSERT INTO t1(t1, rank) VALUES('merge', 5);
|
||||
INSERT INTO t1(t1, rank) VALUES('merge', 5);
|
||||
INSERT INTO t1(t1, rank) VALUES('merge', 5);
|
||||
} {0 {}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
reset_db
|
||||
@@ -6265,7 +6265,7 @@ do_test 46.0 {
|
||||
|
||||
do_catchsql_test 46.1 {
|
||||
SELECT snippet(t1,'[','', '--',-1,10) FROM t1('*');
|
||||
} {0 {{}}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
reset_db
|
||||
@@ -6418,7 +6418,7 @@ do_test 47.0 {
|
||||
|
||||
do_catchsql_test 47.1 {
|
||||
INSERT INTO t1(t1) VALUES('integrity-check');
|
||||
} {1 {database disk image is malformed}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
do_catchsql_test 47.2 {
|
||||
SELECT count(*) FROM (
|
||||
@@ -6426,7 +6426,7 @@ do_catchsql_test 47.2 {
|
||||
highlight(t1, 2, '[', ']') FROM t1('g h')
|
||||
WHERE rank MATCH 'bm25(1.0, 1.0)' ORDER BY rank
|
||||
)
|
||||
} {0 3}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
reset_db
|
||||
@@ -6908,7 +6908,7 @@ do_catchsql_test 50.1 {
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 51.1 {
|
||||
do_execsql_test 51.0 {
|
||||
BEGIN TRANSACTION;
|
||||
PRAGMA writable_schema=ON;
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(a,b,c);
|
||||
@@ -6976,7 +6976,7 @@ COMMIT;
|
||||
|
||||
do_catchsql_test 51.1 {
|
||||
SELECT max(rowid)==0 FROM t1('e*');
|
||||
} {0 0}
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
reset_db
|
||||
@@ -7130,7 +7130,7 @@ do_test 52.0 {
|
||||
|
||||
do_catchsql_test 52.1 {
|
||||
SELECT fts5_decode(id, block) FROM t1_data;
|
||||
} {1 {database disk image is malformed}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
@@ -7346,7 +7346,7 @@ do_test 53.0 {
|
||||
do_catchsql_test 53.1 {
|
||||
WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x<>1 FROM c WHERE x<10)
|
||||
INSERT INTO t1(a) SELECT randomblob(3000) FROM c;
|
||||
} {1 {database disk image is malformed}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
@@ -7562,7 +7562,7 @@ do_test 54.0 {
|
||||
|
||||
do_catchsql_test 54.1 {
|
||||
SELECT rowid==-1 FROM t1('t*');
|
||||
} {0 {0 0 0}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
@@ -7777,10 +7777,10 @@ do_test 55.0 {
|
||||
| end crash-b366b5ac0d3887.db
|
||||
}]} {}
|
||||
|
||||
do_execsql_test 55.1 {
|
||||
do_catchsql_test 55.1 {
|
||||
SAVEPOINT one;
|
||||
DELETE FROM t1 WHERE a MATCH 'ts';
|
||||
}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
do_execsql_test 55.2 {
|
||||
ROLLBACK TO one;
|
||||
@@ -8013,7 +8013,7 @@ do_test 56.1 {
|
||||
set res "1 {database disk image is malformed}"
|
||||
}
|
||||
set res
|
||||
} {1 {database disk image is malformed}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
@@ -8131,7 +8131,7 @@ do_test 57.0 {
|
||||
|
||||
do_catchsql_test 57.1 {
|
||||
INSERT INTO t1(t1) VALUES('optimize')
|
||||
} {1 {database disk image is malformed}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
@@ -8339,9 +8339,9 @@ do_test 58.0 {
|
||||
| end crash-5a5acd0ab42d31.db
|
||||
}]} {}
|
||||
|
||||
do_execsql_test 58.1 {
|
||||
do_catchsql_test 58.1 {
|
||||
SELECT * FROM t1('t*');
|
||||
} {{} {} {} {} {} {}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
do_test 59.0 {
|
||||
@@ -8544,7 +8544,7 @@ do_test 59.0 {
|
||||
|
||||
do_catchsql_test 59.1 {
|
||||
SELECT (matchinfo(591,t1)) FROM t1 WHERE t1 MATCH 'e*e'
|
||||
} {0 {}}
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
do_test 60.0 {
|
||||
@@ -8750,7 +8750,7 @@ do_test 60.0 {
|
||||
|
||||
do_catchsql_test 60.2 {
|
||||
SELECT (matchinfo(t1,591)) FROM t1 WHERE t1 MATCH 'e*e'
|
||||
} {0 {}}
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
do_test 61.0 {
|
||||
@@ -8948,13 +8948,13 @@ do_test 61.0 {
|
||||
| end crash-e5fa281edabddf.db
|
||||
}]} {}
|
||||
|
||||
do_execsql_test 61.1 {
|
||||
do_catchsql_test 61.1 {
|
||||
CREATE VIRTUAL TABLE t3 USING fts5vocab('t1'(),'col' );
|
||||
}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
do_catchsql_test 61.2 {
|
||||
SELECT * FROM t3 ORDER BY rowid;
|
||||
} {1 {database disk image is malformed}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
breakpoint
|
||||
#-------------------------------------------------------------------------
|
||||
@@ -9159,7 +9159,7 @@ do_test 62.0 {
|
||||
do_catchsql_test 62.1 {
|
||||
WITH c(x) AS (VALUES(false) UNION ALL SELECT x+1 FROM c WHERE x<72)
|
||||
INSERT INTO t1(a) SELECT randomblob(2829) FROM c;
|
||||
} {0 {}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
do_test 63.0 {
|
||||
@@ -9357,16 +9357,424 @@ do_test 63.0 {
|
||||
|
||||
do_catchsql_test 63.1 {
|
||||
SELECT * FROM t1 WHERE b MATCH 'thead*thead*theSt*';
|
||||
} {1 {database disk image is malformed}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
do_catchsql_test 63.2 {
|
||||
INSERT INTO t1(t1) VALUES('optimize');
|
||||
} {0 {}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
breakpoint
|
||||
do_catchsql_test 63.3 {
|
||||
SELECT * FROM t1 WHERE b MATCH 'thead*thead*theSt*';
|
||||
} {0 {}}
|
||||
} {/*malformed database schema*/}
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
do_test 64.0 {
|
||||
sqlite3 db {}
|
||||
db deserialize [decode_hexdb {
|
||||
.open --hexdb
|
||||
| size 28672 pagesize 4096 filename crash-4470f0b94422f7.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 06 .....@ ........
|
||||
| 32: 00 00 00 00 00 00 00 00 00 00 00 06 00 00 00 04 ................
|
||||
| 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 01 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 05 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 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 INTEGER PRIMARY
|
||||
| 3728: 4b 45 59 2c 20 73 7a 20 42 4c 4f 42 29 5d 04 07 KEY, sz BLOB)]..
|
||||
| 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 44 00 05 0e 81 00 0f 1a 0e 81 0f af 0f 58 ..D............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 04 03 03 08 03 03 08 03 03 ................
|
||||
| 3792: 07 f3 03 02 01 65 03 1e 03 05 05 04 05 05 01 00 .....e..........
|
||||
| 3808: 03 06 04 04 06 04 03 01 36 03 05 05 04 06 05 04 ........6.......
|
||||
| 3824: 06 05 04 05 05 01 01 03 06 04 04 06 04 04 06 04 ................
|
||||
| 3840: 04 06 04 03 03 01 65 03 14 04 05 06 f5 05 01 01 ......e.........
|
||||
| 3856: 02 08 09 01 20 04 05 07 05 07 05 07 05 05 01 00 .... ...........
|
||||
| 3872: 02 08 0a 0a 0a 04 01 65 03 02 0a 01 06 0a 0a 0a .......e........
|
||||
| 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 02 30 65 02 1a 02 05 05 07 ..$...G.0e......
|
||||
| 3952: 05 01 01 04 03 03 08 03 03 02 01 65 02 1e 03 05 ...........e....
|
||||
| 3968: 05 04 05 05 01 01 03 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 65 01 12 03 ............e...
|
||||
| 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 00 00 00 03 0f ec 00 0f 00 00 00 00 00 00 00 ................
|
||||
| 4064: 00 00 00 00 00 00 00 00 00 00 00 00 06 04 01 0c ................
|
||||
| 4080: 01 03 02 06 04 01 0c 01 02 02 05 04 09 0c 01 02 ................
|
||||
| page 4 offset 12288
|
||||
| 0: 0d 00 00 00 04 0e 1a 00 0f c7 0f 5b 0e ef 0e 1a ...........[....
|
||||
| 3600: 00 00 00 00 00 00 00 00 00 00 81 52 04 06 00 81 ...........R....
|
||||
| 3616: 5d 81 55 65 20 65 65 20 65 65 65 20 65 20 65 65 ].Ue ee eee e ee
|
||||
| 3632: 20 65 65 65 20 65 20 65 65 20 65 65 65 66 20 65 eee e ee eeef e
|
||||
| 3648: 65 20 65 65 65 20 65 20 65 65 20 65 65 65 20 65 e eee e ee eee e
|
||||
| 3664: 20 65 65 20 65 65 65 65 20 65 65 20 65 65 65 20 ee eeee ee eee
|
||||
| 3680: 65 20 65 65 20 65 65 65 20 65 20 65 65 20 65 65 e ee eee e ee ee
|
||||
| 3696: 65 65 20 65 65 20 65 65 65 20 65 20 65 65 20 65 ee ee eee e ee e
|
||||
| 3712: 65 65 20 65 20 65 65 20 65 65 65 65 65 65 20 65 ee e ee eeeeee e
|
||||
| 3728: 65 20 65 20 65 20 65 20 65 65 20 65 65 65 20 65 e e e e ee eee e
|
||||
| 3744: 65 20 65 65 65 65 65 20 65 65 20 65 20 65 1f 65 e eeeee ee e e.e
|
||||
| 3760: 20 65 65 20 65 65 65 20 65 65 20 65 65 65 65 65 ee eee ee eeeee
|
||||
| 3776: 20 65 65 20 65 20 65 20 65 20 65 65 20 65 65 65 ee e e e ee eee
|
||||
| 3792: 20 65 65 20 65 65 65 65 65 20 65 65 20 65 20 65 ee eeeee ee e e
|
||||
| 3808: 20 65 20 65 65 20 65 65 65 20 65 65 20 65 65 6a e ee eee ee eej
|
||||
| 3824: 03 03 ff 75 71 65 20 65 65 1f 65 65 65 20 65 20 ...uqe ee.eee e
|
||||
| 3840: 65 65 20 65 65 65 20 65 20 65 65 20 65 65 65 65 ee eee e ee eeee
|
||||
| 3856: 20 65 65 20 65 65 65 20 65 20 65 65 20 65 65 65 ee eee e ee eee
|
||||
| 3872: 20 65 20 65 65 20 65 65 65 65 65 65 20 65 65 20 e ee eeeeee ee
|
||||
| 3888: 65 20 65 20 65 20 65 65 20 65 65 65 20 65 65 20 e e e ee eee ee
|
||||
| 3904: 65 65 65 65 65 20 65 65 20 65 20 65 20 65 20 65 eeeee ee e e e e
|
||||
| 3920: 65 20 65 65 65 20 65 65 20 65 65 6a 02 04 00 75 e eee ee eej...u
|
||||
| 3936: 40 65 20 65 65 20 65 65 65 20 65 20 65 65 20 65 @e ee eee e ee e
|
||||
| 3952: 65 65 20 65 20 65 65 20 65 65 65 65 20 65 65 20 ee e ee eeee ee
|
||||
| 3968: 65 65 65 20 65 20 65 65 20 65 65 65 20 65 20 65 eee e ee eee e e
|
||||
| 3984: 65 20 65 65 65 65 65 65 20 65 65 20 65 20 65 20 e eeeeee ee e e
|
||||
| 4000: 65 20 65 65 20 65 65 65 20 65 65 20 65 65 65 65 e ee eee ee eeee
|
||||
| 4016: 65 20 65 65 20 65 20 65 20 65 20 65 65 20 65 65 e ee e e e ee ee
|
||||
| 4032: 65 20 65 65 20 65 65 37 01 04 00 41 3f 65 20 65 e ee ee7...A?e e
|
||||
| 4048: 65 20 65 65 65 20 65 20 65 65 20 65 65 65 20 65 e eee e ee eee e
|
||||
| 4064: 20 65 65 20 65 65 65 65 65 65 20 65 65 20 65 20 ee eeeeee ee e
|
||||
| 4080: 65 20 65 20 65 65 20 65 65 65 20 65 65 20 65 65 e e ee eee ee ee
|
||||
| page 5 offset 16384
|
||||
| 0: 0d 00 00 00 04 0f e4 00 0f f9 0f f2 0f eb 0f e4 ................
|
||||
| 4064: 00 00 00 00 05 04 03 00 10 21 21 05 03 03 00 10 .........!!.....
|
||||
| 4080: 11 11 05 02 03 00 10 11 11 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 crash-4470f0b94422f7.db
|
||||
}]} {}
|
||||
|
||||
do_catchsql_test 64.1 {
|
||||
SELECT * FROM ttt('e*');
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
do_test 65.0 {
|
||||
sqlite3 db {}
|
||||
db deserialize [decode_hexdb {
|
||||
.open --hexdb
|
||||
| size 28672 pagesize 4096 filename crash-3aef66940ace0c.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 0f c7 00 07 0d 92 00 0f 8d 0f 36 ...............6
|
||||
| 112: 0e cb 0e 6b 0e 0e 0d b6 0d 92 00 00 00 00 00 00 ...k............
|
||||
| 3472: 00 00 22 08 06 17 11 11 01 31 74 61 62 6c 65 74 .........1tablet
|
||||
| 3488: 32 74 32 08 43 52 45 41 54 45 20 54 41 42 4c 45 2t2.CREATE TABLE
|
||||
| 3504: 20 74 32 28 78 29 56 07 06 17 1f 1f 01 7d 74 61 t2(x)V.......ta
|
||||
| 3520: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 blet1_configt1_c
|
||||
| 3536: 6f 6e 66 69 67 07 43 52 45 41 54 45 20 54 41 42 onfig.CREATE TAB
|
||||
| 3552: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b LE 't1_config'(k
|
||||
| 3568: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 PRIMARY KEY, v)
|
||||
| 3584: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 06 WITHOUT ROWID[.
|
||||
| 3600: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64 ..!!...tablet1_d
|
||||
| 3616: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 ocsizet1_docsize
|
||||
| 3632: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 .CREATE TABLE 't
|
||||
| 3648: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 1_docsize'(id IN
|
||||
| 3664: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 TEGER PRIMARY KE
|
||||
| 3680: 59 2c 20 73 7a 20 42 4c 4f 42 29 5e 05 07 17 21 Y, sz BLOB)^...!
|
||||
| 3696: 21 01 81 07 74 61 62 6c 65 74 31 5f 63 6f 6e 74 !...tablet1_cont
|
||||
| 3712: 65 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 05 43 52 entt1_content.CR
|
||||
| 3728: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 EATE TABLE 't1_c
|
||||
| 3744: 6f 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 ontent'(id INTEG
|
||||
| 3760: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY,
|
||||
| 3776: 63 30 2c 20 63 31 2c d6 63 32 29 69 04 07 17 19 c0, c1,.c2)i....
|
||||
| 3792: 19 01 81 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 ...-tablet1_idxt
|
||||
| 3808: 31 5f 69 64 78 04 43 52 45 41 54 45 20 54 41 42 1_idx.CREATE TAB
|
||||
| 3824: 4c 45 20 27 74 31 5f 69 64 78 27 28 73 65 67 69 LE 't1_idx'(segi
|
||||
| 3840: 64 2c 20 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 d, term, pgno, P
|
||||
| 3856: 52 49 4d 41 52 59 20 4b 45 59 28 73 65 67 69 64 RIMARY KEY(segid
|
||||
| 3872: 2c 20 74 65 72 6d 29 29 20 57 49 54 48 4f 55 54 , term)) WITHOUT
|
||||
| 3888: 20 52 4f 57 49 44 55 03 07 17 1b 1b 01 81 01 74 ROWIDU........t
|
||||
| 3904: 61 62 6c 65 74 31 5f 64 61 74 61 74 31 5f 64 61 ablet1_datat1_da
|
||||
| 3920: 74 61 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 ta.CREATE TABLE
|
||||
| 3936: 27 74 31 5f 64 61 74 61 27 28 69 64 20 49 4e 54 't1_data'(id INT
|
||||
| 3952: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 EGER PRIMARY KEY
|
||||
| 3968: 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42 29 38 02 06 , block BLOB)8..
|
||||
| 3984: 17 11 11 08 5f 74 61 62 6c 65 74 31 74 31 43 52 ...._tablet1t1CR
|
||||
| 4000: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 EATE VIRTUAL TAB
|
||||
| 4016: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 LE t1 USING fts5
|
||||
| 4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00 (a,b,c).........
|
||||
| page 3 offset 8192
|
||||
| 0: 0d 00 00 00 03 0c 93 ff 0f e6 0f ef 0c 94 00 00 ................
|
||||
| 3216: 00 00 00 00 86 4a 84 80 80 80 80 01 04 00 8d 18 .....J..........
|
||||
| 3232: 00 00 03 2b 02 30 30 01 02 06 01 02 06 01 02 06 ...+.00.........
|
||||
| 3248: 1f 02 03 01 02 03 01 02 03 01 08 32 31 31 36 30 ...........21160
|
||||
| 3264: 36 30 39 01 02 07 01 02 07 01 02 07 01 01 33 f1 609...........3.
|
||||
| 3280: 02 05 01 02 05 01 02 05 01 01 35 01 02 03 01 02 ..........5.....
|
||||
| 3296: 04 01 02 04 02 07 30 30 30 30 30 30 30 1c 02 3d ......0000000..=
|
||||
| 3312: 01 02 04 01 02 04 01 06 62 69 6e 61 72 79 03 06 ........binary..
|
||||
| 3328: 01 02 02 03 06 01 01 f2 03 06 4e 02 02 03 06 01 ..........N.....
|
||||
| 3344: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
|
||||
| 3360: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
|
||||
| 3376: 03 06 01 02 02 03 06 01 02 02 01 08 63 6f 6d 70 ............comp
|
||||
| 3392: 69 6c 65 72 01 02 02 01 02 02 01 02 02 01 06 64 iler...........d
|
||||
| 3408: 62 73 74 61 74 07 02 03 01 02 13 01 02 03 02 04 bstat...........
|
||||
| 3424: 65 62 75 67 04 02 02 01 02 02 01 02 02 01 07 65 ebug...........e
|
||||
| 3440: 6e 61 62 6c 65 07 02 02 01 02 02 01 02 02 01 02 nable...........
|
||||
| 3456: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................
|
||||
| 3472: 01 02 02 01 02 01 f1 02 02 01 02 02 01 02 02 01 ................
|
||||
| 3488: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
|
||||
| 3504: 02 01 02 02 02 08 76 b4 65 6e 73 69 6f 6e 1f 02 ......v.ension..
|
||||
| 3520: 04 01 02 04 01 02 04 01 04 66 74 73 34 0a 02 03 .........fts4...
|
||||
| 3536: 01 02 03 01 02 03 04 01 25 0d 02 03 01 02 03 01 ........%.......
|
||||
| 3552: 02 03 01 03 67 63 63 01 02 03 01 02 03 01 02 03 ....gcc.........
|
||||
| 3568: 02 06 65 6f 70 6f 6c 79 0f f2 03 01 02 03 01 02 ..eopoly........
|
||||
| 3584: 03 01 05 6a 73 6f 6e 31 13 02 03 01 02 03 01 02 ...json1........
|
||||
| 3600: 03 01 04 6c 6f 61 64 1f 02 03 01 02 03 01 02 03 ...load.........
|
||||
| 3616: 00 03 6d 61 78 1c 02 0c 01 02 02 01 02 02 02 05 ..max...........
|
||||
| 3632: 65 6d 6f 72 79 1c 02 03 01 02 03 01 02 03 04 04 emory...........
|
||||
| 3648: 73 79 73 35 16 02 03 01 02 03 01 02 03 01 06 6e sys5...........n
|
||||
| 3664: 6f 63 61 73 65 02 06 01 02 02 13 06 00 f2 02 03 ocase...........
|
||||
| 3680: 06 01 12 02 13 06 01 02 02 03 06 01 02 02 03 06 ................
|
||||
| 3696: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
|
||||
| 3712: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
|
||||
| 3728: 02 01 04 6f 6d 69 74 1f 02 02 01 02 02 01 02 02 ...omit.........
|
||||
| 3744: 01 05 72 74 72 65 65 19 02 03 01 02 03 01 02 03 ..rtree.........
|
||||
| 3760: 04 02 69 6d 01 06 01 02 02 03 06 01 02 02 03 06 ..im............
|
||||
| 3776: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
|
||||
| 3792: 02 02 03 06 01 02 02 03 06 01 02 02 8e 06 01 02 ................
|
||||
| 3808: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
|
||||
| 3824: 01 0a 74 68 72 65 61 64 73 61 66 65 22 02 02 01 ..threadsafe....
|
||||
| 3840: 02 02 01 02 02 01 04 76 74 61 62 07 02 04 01 02 .......vtab.....
|
||||
| 3856: 04 01 02 04 01 01 78 01 06 01 01 02 01 06 01 01 ......x.........
|
||||
| 3872: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................
|
||||
| 3888: 01 06 01 11 02 01 06 01 01 02 01 06 01 01 02 01 ................
|
||||
| 3904: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
|
||||
| 3920: 01 01 02 01 06 01 01 01 01 06 01 01 02 01 06 01 ................
|
||||
| 3936: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
|
||||
| 3952: 02 01 06 01 01 01 f1 06 01 01 02 ad 06 01 01 02 ................
|
||||
| 3968: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
|
||||
| 3984: 06 01 01 01 01 06 01 01 02 01 06 01 01 02 01 06 ................
|
||||
| 4000: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
|
||||
| 4016: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
|
||||
| 4032: 02 01 06 01 01 02 01 06 01 01 02 04 15 13 0c 0c ................
|
||||
| 4048: 12 44 13 11 0f 47 13 0e fc 0e 11 10 0f 0e 10 0f .D...G..........
|
||||
| 4064: 44 0f 10 40 15 0f 07 01 03 00 14 24 5a 24 24 0f D..@.......$Z$$.
|
||||
| 4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01 ...$............
|
||||
| page 4 offset 12288
|
||||
| 0: 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||
| 4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02 ................
|
||||
| page 5 offset 16384
|
||||
| 0: 0d 00 00 00 24 0c 0a 00 00 00 00 00 00 00 00 00 ....$...........
|
||||
| 3072: 00 00 00 00 00 00 00 00 00 00 18 24 05 00 25 0f ...........$..%.
|
||||
| 3088: 19 54 48 52 45 41 44 53 41 46 45 3d 30 58 42 49 .THREADSAFE=0XBI
|
||||
| 3104: 4e 41 52 59 18 23 05 00 25 0f 19 54 48 52 45 41 NARY.#..%..THREA
|
||||
| 3120: 44 53 41 46 45 3d 30 58 4e 4f 43 41 53 45 17 8f DSAFE=0XNOCASE..
|
||||
| 3136: 05 00 25 0f 17 54 48 52 45 41 44 43 41 46 45 3d ..%..THREADCAFE=
|
||||
| 3152: 30 58 52 54 52 49 4d 1f 21 05 00 33 0f 19 4f 4d 0XRTRIM.!..3..OM
|
||||
| 3168: 49 54 20 4b 4f 41 44 21 45 58 54 45 4e 53 49 4f IT KOAD!EXTENSIO
|
||||
| 3184: 4e 58 42 49 4e 41 52 59 1f 20 05 00 33 0f 19 4f NXBINARY. ..3..O
|
||||
| 3200: 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 MIT LOAD EXTENSI
|
||||
| 3216: 4f 4e 58 4e 4f 43 41 53 45 1e 1f 05 00 33 0f 17 ONXNOCASE....3..
|
||||
| 3232: 4f 4d 59 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 OMYT LOAD EXTENS
|
||||
| 3248: 49 4f 4e 58 52 54 56 a9 4d 1f 1e 05 00 33 0f 19 IONXRTV.M....3..
|
||||
| 3264: 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 30 MAX MEMORY=50000
|
||||
| 3280: 30 30 30 57 42 49 4e 31 52 59 1f 1d 05 00 33 0f 000WBIN1RY....3.
|
||||
| 3296: 19 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 .MAX MEMORY=5000
|
||||
| 3312: 30 30 30 30 58 4e 4f 43 41 53 45 1e 1c 05 00 32 0000XNOCASE....2
|
||||
| 3328: 0f 17 4e 41 58 20 4d 45 4d 4f 52 59 2d 35 30 30 ..NAX MEMORY-500
|
||||
| 3344: 30 30 30 30 30 58 52 54 52 49 4d 18 1b 05 00 25 00000XRTRIM....%
|
||||
| 3360: 0f 19 45 4e 41 42 4c 45 20 52 54 52 45 45 58 42 ..ENABLE RTREEXB
|
||||
| 3376: 49 4e 41 52 59 18 1a 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB
|
||||
| 3392: 4c 45 20 52 54 52 45 45 59 4e 4f 43 41 53 45 17 LE RTREEYNOCASE.
|
||||
| 3408: 19 66 00 25 0f 17 45 4e 41 42 4c 45 20 52 54 52 .f.%..ENABLE RTR
|
||||
| 3424: 45 45 58 52 54 52 49 4d 1a 18 05 00 29 0f 19 45 EEXRTRIM....)..E
|
||||
| 3440: 4e 41 42 4c 45 20 4d 45 4d 53 59 53 35 58 42 49 NABLE MEMSYS5XBI
|
||||
| 3456: 4e 41 52 59 1a 17 05 00 29 0f 19 45 4e 41 42 4c NARY....)..ENABL
|
||||
| 3472: 45 20 4d 45 4d 53 59 53 35 58 4e 4f 43 41 53 45 E MEMSYS5XNOCASE
|
||||
| 3488: 19 16 05 00 29 0f 17 45 4e 41 42 4c 45 20 4d 45 ....)..ENABLE ME
|
||||
| 3504: 4d 53 59 53 35 58 52 54 52 49 4d 18 15 05 10 25 MSYS5XRTRIM....%
|
||||
| 3520: 0f 19 45 4e 40 42 4c 45 20 4a 53 4f 4e 31 58 42 ..EN@BLE JSON1XB
|
||||
| 3536: 49 4e 41 52 59 18 14 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB
|
||||
| 3552: 4c 45 20 4a 53 4f 4e 32 58 4e 4f 43 41 53 45 17 LE JSON2XNOCASE.
|
||||
| 3568: 13 05 00 25 0f 17 45 4d 41 42 4c 45 20 4a 53 4f ...%..EMABLE JSO
|
||||
| 3584: 4e 31 58 52 54 52 49 4d 1a 12 05 00 29 0f 19 45 N1XRTRIM....)..E
|
||||
| 3600: 4e 41 42 4c 45 20 47 45 4f 50 4f 4c 59 58 42 49 NABLE GEOPOLYXBI
|
||||
| 3616: 4e 41 52 59 1a 11 05 00 29 0f 19 45 4f 81 42 4c NARY....)..EO.BL
|
||||
| 3632: 45 20 47 45 4f 50 4f 4c 59 58 4e 4f 43 51 53 45 E GEOPOLYXNOCQSE
|
||||
| 3648: 19 10 05 00 29 0f 17 45 4e 41 42 4c 45 20 47 45 ....)..ENABLE GE
|
||||
| 3664: 4f 50 4f 4c 59 58 52 54 52 49 4d 17 0f 05 00 23 OPOLYXRTRIM....#
|
||||
| 3680: 0f 1a 45 4e 41 42 4c 45 20 46 54 53 35 58 42 49 ..ENABLE FTS5XBI
|
||||
| 3696: 4e 41 52 59 17 0e 05 00 23 0f 19 45 4e 41 42 4c NARY....#..ENABL
|
||||
| 3712: 45 20 46 54 53 35 48 4e 4f 43 41 53 45 16 1d 05 E FTS5HNOCASE...
|
||||
| 3728: 00 23 0f a4 45 4e 41 42 4c 45 20 46 54 53 35 58 .#..ENABLE FTS5X
|
||||
| 3744: 52 54 52 49 4d 17 0c 05 00 23 0f 19 45 4e 41 42 RTRIM....#..ENAB
|
||||
| 3760: 4c 45 20 46 55 53 34 58 42 49 4e 41 52 59 17 0b LE FUS4XBINARY..
|
||||
| 3776: 05 00 23 0f 19 45 4e 41 42 4c 45 20 46 54 53 34 ..#..ENABLE FTS4
|
||||
| 3792: 57 4e 4f 43 41 53 45 16 0a 05 00 23 0f 17 45 4e WNOCASE....#..EN
|
||||
| 3808: 41 42 4c 45 20 46 54 53 34 05 52 54 52 49 4d 1e ABLE FTS4.RTRIM.
|
||||
| 3824: 09 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
|
||||
| 3840: 54 41 54 20 56 54 41 42 58 42 49 4e 41 52 59 1e TAT VTABXBINARY.
|
||||
| 3856: 08 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
|
||||
| 3872: 54 41 54 20 56 54 41 42 58 4e 4f 43 41 53 45 1d TAT VTABXNOCASE.
|
||||
| 3888: 07 05 00 31 0f 17 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
|
||||
| 3904: 54 41 54 20 56 54 41 42 58 52 54 52 49 4d 11 06 TAT VTABXRTRIM..
|
||||
| 3920: 05 00 17 0f 19 44 45 42 55 47 58 42 8a 4e 41 52 .....DEBUGXB.NAR
|
||||
| 3936: 59 11 05 05 00 17 0f 19 44 45 42 55 47 58 4e 4f Y.......DEBUGXNO
|
||||
| 3952: 43 41 53 45 10 04 05 00 17 0f 17 44 45 42 55 47 CASE.......DEBUG
|
||||
| 3968: 58 52 54 52 49 4d 27 03 05 00 43 0f 19 43 4f 4d XRTRIM'...C..COM
|
||||
| 3984: 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e 30 20 PILER=gcc-5.4.0
|
||||
| 4000: 32 30 31 36 30 36 30 39 58 42 49 4e 41 52 59 27 20160609XBINARY'
|
||||
| 4016: 02 05 00 43 0f 19 43 4f 4d 50 49 4c 45 52 3f 87 ...C..COMPILER?.
|
||||
| 4032: 63 63 2d 35 2e 34 2e 30 20 32 30 31 36 30 36 30 cc-5.4.0 2016060
|
||||
| 4048: 39 58 4e 4f 43 41 53 45 26 01 05 00 43 0f 17 43 9XNOCASE&...C..C
|
||||
| 4064: 45 0d 60 59 4c 45 52 3d 67 63 63 2d 35 2e 34 2d E.`YLER=gcc-5.4-
|
||||
| 4080: 30 20 32 30 31 36 30 36 30 39 00 00 00 00 00 00 0 20160609......
|
||||
| page 6 offset 20480
|
||||
| 3808: 06 24 03 00 12 02 01 01 06 23 03 00 12 02 01 01 .$.......#......
|
||||
| 3824: 06 22 03 01 12 02 01 01 06 21 03 00 12 03 01 01 .........!......
|
||||
| 3840: 06 20 03 00 12 03 01 01 06 1f 03 00 12 03 02 01 . ..............
|
||||
| 3856: 06 1e 03 00 12 03 01 01 06 1d 03 00 12 03 01 01 ................
|
||||
| 3872: 06 1c 03 00 12 03 01 01 06 1b 03 00 12 02 01 01 ................
|
||||
| 3888: 06 1a 03 00 12 02 01 01 06 19 03 00 12 02 01 01 ................
|
||||
| 3904: 06 18 03 00 12 02 01 01 06 17 03 00 12 02 01 01 ................
|
||||
| 3920: 06 16 03 00 12 02 01 01 06 15 03 00 12 02 01 01 ................
|
||||
| 3936: 06 14 03 00 12 02 01 01 06 13 03 00 12 02 01 01 ................
|
||||
| 3952: 06 12 03 00 12 02 01 01 06 11 03 00 12 02 01 01 ................
|
||||
| 3968: 06 00 03 00 12 02 01 01 06 0f 03 00 12 02 01 01 ................
|
||||
| 3984: 06 0e 03 00 12 02 01 01 06 0d 03 00 12 02 01 01 ................
|
||||
| 4000: 06 0c 03 00 12 02 01 01 06 0b 03 00 12 02 01 01 ................
|
||||
| 4016: 06 0a 03 00 12 02 01 01 06 09 03 00 12 03 01 01 ................
|
||||
| 4032: 06 08 03 00 12 03 01 01 06 07 03 00 12 03 01 01 ................
|
||||
| 4048: 06 06 03 00 12 01 01 01 06 05 03 00 12 01 01 01 ................
|
||||
| 4064: 06 04 03 00 12 01 01 01 06 03 03 00 12 06 01 01 ................
|
||||
| 4080: 06 02 03 00 12 06 01 01 06 01 03 00 12 06 01 01 ................
|
||||
| page 7 offset 24576
|
||||
| 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 crash-3aef66940ace0c.db
|
||||
}]} {}
|
||||
|
||||
do_catchsql_test 65.1 {
|
||||
SELECT ( MATCH (t1,591)) FROM t1 WHERE t1 MATCH 'e*eŸ'
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
reset_db
|
||||
do_test 66.0 {
|
||||
sqlite3 db {}
|
||||
db deserialize [decode_hexdb {
|
||||
.open --hexdb
|
||||
| size 28672 pagesize 4096 filename crash-37cecb4e784e9f.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 07 .....@ ........
|
||||
| 96: 00 00 00 00 0d 00 00 00 07 0d d2 00 0f c4 0f 6d ...............m
|
||||
| 112: 0f 02 0e ab 0e 4e 0d f6 0d d2 00 00 00 00 00 00 .....N..........
|
||||
| 3536: 00 00 22 07 06 17 11 11 01 31 74 61 62 6c 65 74 .........1tablet
|
||||
| 3552: 32 74 32 07 43 52 45 41 54 45 20 54 41 42 4c 45 2t2.CREATE TABLE
|
||||
| 3568: 20 74 32 28 78 29 56 06 06 17 1f 1f 01 7d 74 61 t2(x)V.......ta
|
||||
| 3584: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 blet1_configt1_c
|
||||
| 3600: 6f 6e 66 69 67 06 43 52 45 41 54 45 20 54 41 42 onfig.CREATE TAB
|
||||
| 3616: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b LE 't1_config'(k
|
||||
| 3632: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 PRIMARY KEY, v)
|
||||
| 3648: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 05 WITHOUT ROWID[.
|
||||
| 3664: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64 ..!!...tablet1_d
|
||||
| 3680: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 ocsizet1_docsize
|
||||
| 3696: 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 .CREATE TABLE 't
|
||||
| 3712: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 1_docsize'(id IN
|
||||
| 3728: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 TEGER PRIMARY KE
|
||||
| 3744: 59 2c 20 73 7a 20 42 4c 4f 42 29 55 04 06 17 21 Y, sz BLOB)U...!
|
||||
| 3760: 21 01 77 74 61 62 6c 65 74 31 5f 63 6f 6e 74 65 !.wtablet1_conte
|
||||
| 3776: 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 04 43 52 45 ntt1_content.CRE
|
||||
| 3792: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 6f ATE TABLE 't1_co
|
||||
| 3808: 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 45 ntent'(id INTEGE
|
||||
| 3824: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 63 R PRIMARY KEY, c
|
||||
| 3840: 30 29 69 03 07 17 19 19 01 81 2d 74 61 62 6c 65 0)i.......-table
|
||||
| 3856: 74 31 5f 69 64 78 74 31 5f 69 64 78 03 43 52 45 t1_idxt1_idx.CRE
|
||||
| 3872: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 69 64 ATE TABLE 't1_id
|
||||
| 3888: 78 27 28 73 65 67 69 64 2c 20 74 65 72 6d 2c 20 x'(segid, term,
|
||||
| 3904: 70 67 6e 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45 pgno, PRIMARY KE
|
||||
| 3920: 59 28 73 65 67 69 64 2c 20 74 65 72 6d 29 29 20 Y(segid, term))
|
||||
| 3936: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 55 02 07 WITHOUT ROWIDU..
|
||||
| 3952: 17 1b 1b 01 81 01 74 61 62 6c 65 74 31 5f 64 61 ......tablet1_da
|
||||
| 3968: 74 61 74 31 5f 64 61 74 61 02 43 52 45 41 54 45 tat1_data.CREATE
|
||||
| 3984: 20 54 41 42 4c 45 20 27 74 31 5f 64 61 74 61 27 TABLE 't1_data'
|
||||
| 4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d (id INTEGER PRIM
|
||||
| 4016: 41 52 49 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 ARI KEY, block B
|
||||
| 4032: 4c 4f 42 29 3a 01 06 17 11 11 08 63 74 61 62 6c LOB):......ctabl
|
||||
| 4048: 65 74 31 74 31 43 52 45 41 54 45 20 56 49 52 54 et1t1CREATE VIRT
|
||||
| 4064: 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53 49 UAL TABLE t1 USI
|
||||
| 4080: 4e 47 20 66 74 73 35 28 63 6f 6e 74 65 6e 74 29 NG fts5(content)
|
||||
| page 2 offset 4096
|
||||
| 0: 0d 00 00 00 03 0f bd 00 0f e8 0f ef 0f bd 00 01 ................
|
||||
| 4016: 00 00 00 00 00 00 00 00 00 00 00 00 00 24 84 80 .............$..
|
||||
| 4032: 80 80 80 01 03 00 4e 00 00 00 1e 06 30 61 62 61 ......N.....0aba
|
||||
| 4048: 63 6b 01 02 02 04 02 66 74 02 02 02 04 04 6e 64 ck.....ft.....nd
|
||||
| 4064: 6f 6e 03 02 02 04 0a 07 05 01 03 00 10 03 03 0f on..............
|
||||
| 4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 00 01 01 ...$............
|
||||
| page 3 offset 8192
|
||||
| 0: 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||
| 4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02 ................
|
||||
| page 4 offset 12288
|
||||
| 0: 0d 00 00 00 03 0f e0 00 0f f6 0f ec 0f e0 00 00 ................
|
||||
| 4064: 0a 03 03 00 1b 61 62 61 6e 64 6f 6e 08 02 03 00 .....abandon....
|
||||
| 4080: 17 61 62 61 66 74 08 01 03 00 17 61 62 61 63 6b .abaft.....aback
|
||||
| page 5 offset 16384
|
||||
| 0: 0d 00 00 00 03 0f ee 00 0f fa 0f f4 0f ee 00 00 ................
|
||||
| 4064: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 03 ................
|
||||
| 4080: 03 00 0e 01 04 02 03 00 0e 01 04 01 03 00 0e 01 ................
|
||||
| page 6 offset 20480
|
||||
| 0: 0a 00 00 01 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.
|
||||
| page 7 offset 24576
|
||||
| 0: 0d 00 00 00 03 0f d6 00 0f f4 0f e1 0f d6 00 00 ................
|
||||
| 4048: 00 00 00 00 00 00 09 01 52 1b 72 65 62 75 69 6c ........R.rebuil
|
||||
| 4064: 64 11 02 02 2b 69 6e 74 65 67 72 69 74 79 2d 63 d...+integrity-c
|
||||
| 4080: 68 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65 heck....optimize
|
||||
| end crash-37cecb4e784e9f.db
|
||||
}]} {}
|
||||
|
||||
do_catchsql_test 66.1 {
|
||||
INSERT INTO t1(t1) VALUES('integrity-check');
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
|
||||
|
||||
sqlite3_fts5_may_be_corrupt 0
|
||||
finish_test
|
||||
|
||||
@@ -147,5 +147,27 @@ do_faultsim_test 5.1 -faults oom* -body {
|
||||
faultsim_test_result {0 {1 4}}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test OOM injection in a query with two MATCH expressions
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 6.0 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(a);
|
||||
INSERT INTO t1 VALUES('a b c d'); -- 1
|
||||
INSERT INTO t1 VALUES('d a b c'); -- 2
|
||||
INSERT INTO t1 VALUES('c d a b'); -- 3
|
||||
INSERT INTO t1 VALUES('b c d a'); -- 4
|
||||
}
|
||||
do_faultsim_test 6.1 -faults oom* -body {
|
||||
execsql { SELECT rowid FROM t1 WHERE t1 MATCH 'a' AND t1 MATCH 'b' }
|
||||
} -test {
|
||||
faultsim_test_result {0 {1 2 3 4}}
|
||||
}
|
||||
do_faultsim_test 6.2 -faults oom* -body {
|
||||
execsql { SELECT rowid FROM t1 WHERE t1 MATCH 'a OR b' AND t1 MATCH 'c OR d' }
|
||||
} -test {
|
||||
faultsim_test_result {0 {1 2 3 4}}
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
# 2019 September 02
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#*************************************************************************
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this script is testing the FTS5 module.
|
||||
#
|
||||
|
||||
source [file join [file dirname [info script]] fts5_common.tcl]
|
||||
set testprefix fts5misc
|
||||
|
||||
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
|
||||
ifcapable !fts5 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(a);
|
||||
}
|
||||
|
||||
do_catchsql_test 1.1.1 {
|
||||
SELECT highlight(t1, 4, '<b>', '</b>') FROM t1('*');
|
||||
} {1 {unknown special query: }}
|
||||
do_catchsql_test 1.1.2 {
|
||||
SELECT a FROM t1
|
||||
WHERE rank = (SELECT highlight(t1, 4, '<b>', '</b>') FROM t1('*'));
|
||||
} {1 {unknown special query: }}
|
||||
|
||||
do_catchsql_test 1.2.1 {
|
||||
SELECT highlight(t1, 4, '<b>', '</b>') FROM t1('*id');
|
||||
} {0 {{}}}
|
||||
|
||||
do_catchsql_test 1.2.2 {
|
||||
SELECT a FROM t1
|
||||
WHERE rank = (SELECT highlight(t1, 4, '<b>', '</b>') FROM t1('*id'));
|
||||
} {0 {}}
|
||||
|
||||
do_catchsql_test 1.3.1 {
|
||||
SELECT highlight(t1, 4, '<b>', '</b>') FROM t1('*reads');
|
||||
} {1 {no such cursor: 1}}
|
||||
|
||||
do_catchsql_test 1.3.2 {
|
||||
SELECT a FROM t1
|
||||
WHERE rank = (SELECT highlight(t1, 4, '<b>', '</b>') FROM t1('*reads'));
|
||||
} {1 {no such cursor: 1}}
|
||||
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
|
||||
do_catchsql_test 1.3.3 {
|
||||
SELECT a FROM t1
|
||||
WHERE rank = (SELECT highlight(t1, 4, '<b>', '</b>') FROM t1('*reads'));
|
||||
} {1 {no such cursor: 1}}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
# 2014 September 13
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#*************************************************************************
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this script is testing the FTS5 module.
|
||||
#
|
||||
|
||||
source [file join [file dirname [info script]] fts5_common.tcl]
|
||||
set testprefix fts5multi
|
||||
|
||||
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
|
||||
ifcapable !fts5 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
fts5_aux_test_functions db
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(a, b, c);
|
||||
INSERT INTO t1 VALUES('gg bb bb' ,'gg ff gg' ,'ii ii');
|
||||
INSERT INTO t1 VALUES('dd dd hh kk','jj' ,'aa');
|
||||
INSERT INTO t1 VALUES('kk gg ee' ,'hh cc' ,'hh jj aa cc');
|
||||
INSERT INTO t1 VALUES('hh' ,'bb jj cc' ,'kk ii');
|
||||
INSERT INTO t1 VALUES('kk dd kk ii','aa ee aa' ,'ee');
|
||||
INSERT INTO t1 VALUES('ee' ,'ff gg kk aa','ee ff ee');
|
||||
INSERT INTO t1 VALUES('ff jj' ,'gg ee' ,'kk ee gg kk');
|
||||
INSERT INTO t1 VALUES('ff ee dd hh','kk ee' ,'gg dd');
|
||||
INSERT INTO t1 VALUES('bb' ,'aa' ,'bb aa');
|
||||
INSERT INTO t1 VALUES('hh cc bb' ,'ff bb' ,'cc');
|
||||
INSERT INTO t1 VALUES('jj' ,'ff dd bb aa','dd dd ff ff');
|
||||
INSERT INTO t1 VALUES('ff dd gg dd','gg aa bb ff','cc');
|
||||
INSERT INTO t1 VALUES('ff aa cc jj','kk' ,'ii dd');
|
||||
INSERT INTO t1 VALUES('jj dd' ,'cc' ,'ii hh ee aa');
|
||||
INSERT INTO t1 VALUES('ff ii hh' ,'dd' ,'gg');
|
||||
INSERT INTO t1 VALUES('ff dd gg hh','hh' ,'ff dd');
|
||||
INSERT INTO t1 VALUES('cc cc' ,'ff dd ff' ,'bb');
|
||||
INSERT INTO t1 VALUES('ii' ,'bb ii' ,'jj kk');
|
||||
INSERT INTO t1 VALUES('ff hh' ,'hh bb' ,'bb dd ee');
|
||||
INSERT INTO t1 VALUES('jj kk' ,'jj' ,'gg ff cc');
|
||||
INSERT INTO t1 VALUES('dd kk' ,'ii gg' ,'dd');
|
||||
INSERT INTO t1 VALUES('cc' ,'aa ff' ,'ii');
|
||||
INSERT INTO t1 VALUES('bb ff bb ii','bb kk bb aa','hh ff ii dd');
|
||||
INSERT INTO t1 VALUES('aa' ,'ee bb jj jj','dd');
|
||||
INSERT INTO t1 VALUES('kk dd cc' ,'aa jj' ,'ee aa ff');
|
||||
INSERT INTO t1 VALUES('aa gg aa' ,'jj' ,'ii kk hh gg');
|
||||
INSERT INTO t1 VALUES('ff hh aa' ,'jj ii' ,'hh dd bb jj');
|
||||
INSERT INTO t1 VALUES('hh' ,'aa gg kk' ,'bb ee');
|
||||
INSERT INTO t1 VALUES('bb' ,'ee' ,'gg');
|
||||
INSERT INTO t1 VALUES('dd kk' ,'kk bb aa' ,'ee');
|
||||
}
|
||||
|
||||
foreach {tn c1 e1 c2 e2} {
|
||||
1 t1 aa t1 bb
|
||||
2 a aa b bb
|
||||
3 a "aa OR bb OR cc" b "jj OR ii OR hh"
|
||||
4 t1 "aa AND bb" t1 "cc"
|
||||
5 c "kk" b "aa OR bb OR cc OR dd OR ee"
|
||||
} {
|
||||
if {$c1=="t1"} {
|
||||
set lhs "( $e1 )"
|
||||
} else {
|
||||
set lhs "$c1 : ( $e1 )"
|
||||
}
|
||||
if {$c2=="t1"} {
|
||||
set rhs "( $e2 )"
|
||||
} else {
|
||||
set rhs "$c2 : ( $e2 )"
|
||||
}
|
||||
|
||||
set q1 "t1 MATCH '($lhs) AND ($rhs)'"
|
||||
set q2 "$c1 MATCH '$e1' AND $c2 MATCH '$e2'"
|
||||
|
||||
set ret [execsql "SELECT rowid FROM t1 WHERE $q1"]
|
||||
set N [llength $ret]
|
||||
do_execsql_test 1.$tn.1.($N) "SELECT rowid FROM t1 WHERE $q2" $ret
|
||||
|
||||
set ret [execsql "SELECT fts5_test_poslist(t1) FROM t1 WHERE $q1"]
|
||||
do_execsql_test 1.$tn.2.($N) "
|
||||
SELECT fts5_test_poslist(t1) FROM t1 WHERE $q2
|
||||
" $ret
|
||||
}
|
||||
|
||||
do_catchsql_test 2.1.1 {
|
||||
SELECT rowid FROM t1 WHERE t1 MATCH '(NOT' AND t1 MATCH 'aa bb';
|
||||
} {1 {fts5: syntax error near "NOT"}}
|
||||
do_catchsql_test 2.1.2 {
|
||||
SELECT rowid FROM t1 WHERE t1 MATCH 'aa bb' AND t1 MATCH '(NOT';
|
||||
} {1 {fts5: syntax error near "NOT"}}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -31,7 +31,7 @@ do_eqp_test 1.1 {
|
||||
} {
|
||||
QUERY PLAN
|
||||
|--SCAN TABLE t1
|
||||
`--SCAN TABLE f1 VIRTUAL TABLE INDEX 65537:
|
||||
`--SCAN TABLE f1 VIRTUAL TABLE INDEX 0:m
|
||||
}
|
||||
|
||||
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 65537:
|
||||
|--SCAN TABLE f1 VIRTUAL TABLE INDEX 0:m
|
||||
`--USE TEMP B-TREE FOR ORDER BY
|
||||
}
|
||||
|
||||
@@ -60,6 +60,6 @@ do_eqp_test 1.4 {
|
||||
|
||||
do_eqp_test 1.5 {
|
||||
SELECT * FROM f1 WHERE rank MATCH ?
|
||||
} {SCAN TABLE f1 VIRTUAL TABLE INDEX 2:}
|
||||
} {SCAN TABLE f1 VIRTUAL TABLE INDEX 0:r}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -162,4 +162,22 @@ do_execsql_test 5.1 {
|
||||
SELECT rowid FROM ttt('word') WHERE rowid BETWEEN 30 AND 40 ORDER BY rank;
|
||||
} {30 31 32 33 34 35 36 37 38 39 40}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 6.0 {
|
||||
CREATE VIRTUAL TABLE "My.Table" USING fts5(Text);
|
||||
|
||||
INSERT INTO "My.Table" VALUES ('hello this is a test');
|
||||
INSERT INTO "My.Table" VALUES ('of trying to order by');
|
||||
INSERT INTO "My.Table" VALUES ('rank on an fts5 table');
|
||||
INSERT INTO "My.Table" VALUES ('that have periods in');
|
||||
INSERT INTO "My.Table" VALUES ('the table names.');
|
||||
INSERT INTO "My.Table" VALUES ('table table table');
|
||||
}
|
||||
do_execsql_test 6.1 {
|
||||
SELECT * FROM "My.Table" WHERE Text MATCH 'table' ORDER BY rank;
|
||||
} {
|
||||
{table table table} {the table names.} {rank on an fts5 table}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -467,4 +467,17 @@ do_execsql_test 21.3 {
|
||||
SELECT rowid FROM x1($doc);
|
||||
} {11112}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 22.0 {
|
||||
CREATE VIRTUAL TABLE x1 USING fts5(x);
|
||||
INSERT INTO x1(x) VALUES('a b c');
|
||||
INSERT INTO x1(x) VALUES('x y z');
|
||||
INSERT INTO x1(x) VALUES('c b a');
|
||||
INSERT INTO x1(x) VALUES('z y x');
|
||||
}
|
||||
|
||||
do_catchsql_test 22.1 {SELECT * FROM x1('')} {1 {fts5: syntax error near ""}}
|
||||
do_catchsql_test 22.2 {SELECT * FROM x1(NULL)} {1 {fts5: syntax error near ""}}
|
||||
|
||||
finish_test
|
||||
|
||||
+2
-2
@@ -43,10 +43,10 @@ LSMTESTSRC = $(LSMDIR)/lsm-test/lsmtest1.c $(LSMDIR)/lsm-test/lsmtest2.c \
|
||||
|
||||
# all: lsm.so
|
||||
|
||||
LSMOPTS += -DLSM_MUTEX_PTHREADS=1 -I$(LSMDIR) -DHAVE_ZLIB
|
||||
LSMOPTS += -fPIC -DLSM_MUTEX_PTHREADS=1 -I$(LSMDIR) -DHAVE_ZLIB
|
||||
|
||||
lsm.so: $(LSMOBJ)
|
||||
$(TCCX) -shared -o lsm.so $(LSMOBJ)
|
||||
$(TCCX) -shared -fPIC -o lsm.so $(LSMOBJ)
|
||||
|
||||
%.o: $(LSMDIR)/%.c $(LSMHDR) sqlite3.h
|
||||
$(TCCX) $(LSMOPTS) -c $<
|
||||
|
||||
+1
-1
@@ -842,7 +842,7 @@ static int lsm1BestIndex(
|
||||
|
||||
const struct sqlite3_index_constraint *pConstraint;
|
||||
pConstraint = pIdxInfo->aConstraint;
|
||||
for(i=0; i<pIdxInfo->nConstraint && idxNum<16; i++, pConstraint++){
|
||||
for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
|
||||
if( pConstraint->usable==0 ) continue;
|
||||
if( pConstraint->iColumn!=0 ) continue;
|
||||
switch( pConstraint->op ){
|
||||
|
||||
@@ -88,6 +88,65 @@ do_execsql_test 210 {
|
||||
do_execsql_test 211 {
|
||||
SELECT quote(a), quote(lsm1_key), quote(lsm1_value), '|' FROM x1;
|
||||
} {'12' X'3132' X'05320000000000000A401FFB42ABE9DB' | '15' X'3135' X'4284C6' | '8' X'38' X'2162616E6A6F1633323105' |}
|
||||
do_execsql_test 212 {
|
||||
SELECT quote(a), quote(lsm1_key), quote(lsm1_value) FROM x1 WHERE a='12';
|
||||
} {'12' X'3132' X'05320000000000000A401FFB42ABE9DB'}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
forcedelete testlsm.db
|
||||
load_lsm1_vtab db
|
||||
do_execsql_test 300 {
|
||||
CREATE VIRTUAL TABLE x1 USING lsm1(testlsm.db,a,TEXT,b,c,d);
|
||||
}
|
||||
do_eqp_test 310 {
|
||||
SELECT * FROM x1 WHERE a=?
|
||||
} {SCAN TABLE x1 VIRTUAL TABLE INDEX 0:}
|
||||
|
||||
do_eqp_test 320 {
|
||||
SELECT * FROM x1 WHERE a>?
|
||||
} {SCAN TABLE x1 VIRTUAL TABLE INDEX 2:}
|
||||
|
||||
do_eqp_test 330 {
|
||||
SELECT * FROM x1 WHERE a<?
|
||||
} {SCAN TABLE x1 VIRTUAL TABLE INDEX 3:}
|
||||
do_eqp_test 340 {
|
||||
SELECT * FROM x1 WHERE a BETWEEN ? AND ?
|
||||
} {SCAN TABLE x1 VIRTUAL TABLE INDEX 1:}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
forcedelete testlsm.db
|
||||
load_lsm1_vtab db
|
||||
do_execsql_test 400 {
|
||||
CREATE VIRTUAL TABLE x1 USING lsm1(testlsm.db,a,TEXT,b);
|
||||
INSERT INTO x1 VALUES('one', 1);
|
||||
INSERT INTO x1 VALUES('two', 2);
|
||||
INSERT INTO x1 VALUES('three', 3);
|
||||
INSERT INTO x1 VALUES('four', 4);
|
||||
INSERT INTO x1 VALUES('five', 5);
|
||||
}
|
||||
do_execsql_test 410 {
|
||||
SELECT b FROM x1 WHERE a = 'two'
|
||||
} {2}
|
||||
do_execsql_test 411 {
|
||||
SELECT b FROM x1 WHERE a = 'one'
|
||||
} {1}
|
||||
do_execsql_test 412 {
|
||||
SELECT b FROM x1 WHERE a = 'five'
|
||||
} {5}
|
||||
|
||||
do_execsql_test 420 {
|
||||
SELECT b FROM x1 WHERE a BETWEEN 'one' AND 'three';
|
||||
} {1 3}
|
||||
do_execsql_test 421 {
|
||||
SELECT b FROM x1 WHERE a BETWEEN 'five' AND 'two';
|
||||
} {5 4 1 3 2}
|
||||
do_execsql_test 421 {
|
||||
SELECT b FROM x1 WHERE a > 'five';
|
||||
} {4 1 3 2}
|
||||
do_execsql_test 421 {
|
||||
SELECT b FROM x1 WHERE a <= 'three';
|
||||
} {3 1 4 5}
|
||||
|
||||
finish_test
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@
|
||||
**
|
||||
** static int aX[] = { 53, 9, 17, 2231, 4, 99 };
|
||||
** int i = sqlite3_bind_parameter_index(pStmt, "$ptr");
|
||||
** sqlite3_bind_value(pStmt, i, aX, "carray", 0);
|
||||
** sqlite3_bind_pointer(pStmt, i, aX, "carray", 0);
|
||||
**
|
||||
** There is an optional third parameter to determine the datatype of
|
||||
** the C-language array. Allowed values of the third parameter are
|
||||
|
||||
+17
-9
@@ -1820,7 +1820,7 @@ static void jsonArrayStep(
|
||||
if( pStr->zBuf==0 ){
|
||||
jsonInit(pStr, ctx);
|
||||
jsonAppendChar(pStr, '[');
|
||||
}else{
|
||||
}else if( pStr->nUsed>1 ){
|
||||
jsonAppendChar(pStr, ',');
|
||||
pStr->pCtx = ctx;
|
||||
}
|
||||
@@ -1868,9 +1868,11 @@ static void jsonGroupInverse(
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
int i;
|
||||
unsigned int i;
|
||||
int inStr = 0;
|
||||
int nNest = 0;
|
||||
char *z;
|
||||
char c;
|
||||
JsonString *pStr;
|
||||
UNUSED_PARAM(argc);
|
||||
UNUSED_PARAM(argv);
|
||||
@@ -1881,12 +1883,18 @@ static void jsonGroupInverse(
|
||||
if( NEVER(!pStr) ) return;
|
||||
#endif
|
||||
z = pStr->zBuf;
|
||||
for(i=1; z[i]!=',' || inStr; i++){
|
||||
assert( i<pStr->nUsed );
|
||||
if( z[i]=='"' ){
|
||||
for(i=1; (c = z[i])!=',' || inStr || nNest; i++){
|
||||
if( i>=pStr->nUsed ){
|
||||
pStr->nUsed = 1;
|
||||
return;
|
||||
}
|
||||
if( c=='"' ){
|
||||
inStr = !inStr;
|
||||
}else if( z[i]=='\\' ){
|
||||
}else if( c=='\\' ){
|
||||
i++;
|
||||
}else if( !inStr ){
|
||||
if( c=='{' || c=='[' ) nNest++;
|
||||
if( c=='}' || c==']' ) nNest--;
|
||||
}
|
||||
}
|
||||
pStr->nUsed -= i;
|
||||
@@ -1916,7 +1924,7 @@ static void jsonObjectStep(
|
||||
if( pStr->zBuf==0 ){
|
||||
jsonInit(pStr, ctx);
|
||||
jsonAppendChar(pStr, '{');
|
||||
}else{
|
||||
}else if( pStr->nUsed>1 ){
|
||||
jsonAppendChar(pStr, ',');
|
||||
pStr->pCtx = ctx;
|
||||
}
|
||||
@@ -2504,14 +2512,14 @@ int sqlite3Json1Init(sqlite3 *db){
|
||||
#endif
|
||||
for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
|
||||
rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg,
|
||||
SQLITE_UTF8 | SQLITE_DETERMINISTIC,
|
||||
SQLITE_UTF8 | SQLITE_DETERMINISTIC,
|
||||
(void*)&aFunc[i].flag,
|
||||
aFunc[i].xFunc, 0, 0);
|
||||
}
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
for(i=0; i<sizeof(aAgg)/sizeof(aAgg[0]) && rc==SQLITE_OK; i++){
|
||||
rc = sqlite3_create_window_function(db, aAgg[i].zName, aAgg[i].nArg,
|
||||
SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
|
||||
SQLITE_SUBTYPE | SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
|
||||
aAgg[i].xStep, aAgg[i].xFinal,
|
||||
aAgg[i].xValue, jsonGroupInverse, 0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
# 2014 August 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.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
|
||||
source [file join [file dirname [info script]] rbu_common.tcl]
|
||||
set ::testprefix rbu1
|
||||
|
||||
forcedelete test.db2
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(a INTEGER, b, c, PRIMARY KEY(a));
|
||||
CREATE INDEX t1b ON t1(b); -- root=3
|
||||
CREATE INDEX t1c ON t1(c); -- root=4
|
||||
|
||||
ATTACH 'test.db2' AS 'rbu';
|
||||
CREATE TABLE rbu.data_t1(a, b, c, rbu_control);
|
||||
INSERT INTO data_t1 VALUES(1, 1, 1, 0);
|
||||
INSERT INTO data_t1 VALUES(2, 2, 2, 0);
|
||||
INSERT INTO data_t1 VALUES(3, 3, 3, 0);
|
||||
}
|
||||
|
||||
do_test 1.1 {
|
||||
sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 1 3
|
||||
execsql {
|
||||
CREATE TABLE imp1(b, id, PRIMARY KEY(b, id)) WITHOUT ROWID;
|
||||
INSERT INTO imp1 VALUES(2, 2);
|
||||
}
|
||||
sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 0 3
|
||||
} {}
|
||||
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
|
||||
do_test 1.2 {
|
||||
sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 1 4
|
||||
execsql {
|
||||
CREATE TABLE imp1(b, id, PRIMARY KEY(b, id)) WITHOUT ROWID;
|
||||
INSERT INTO imp1 VALUES(3, 3);
|
||||
}
|
||||
sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 0 4
|
||||
} {}
|
||||
db close
|
||||
db_save
|
||||
|
||||
sqlite3 db test.db
|
||||
do_catchsql_test 1.3 { PRAGMA integrity_check } {0 {{wrong # of entries in index t1c} {wrong # of entries in index t1b}}}
|
||||
db close
|
||||
|
||||
do_test 1.4 {
|
||||
sqlite3rbu rbu test.db test.db2
|
||||
while 1 {
|
||||
set rc [rbu step]
|
||||
if {$rc!="SQLITE_OK"} break
|
||||
}
|
||||
list [catch { rbu close } msg] $msg
|
||||
} {1 {SQLITE_CONSTRAINT - UNIQUE constraint failed: t1.b, t1.a}}
|
||||
|
||||
db_restore
|
||||
sqlite3 db test.db2
|
||||
do_execsql_test 1.5 {
|
||||
PRAGMA writable_schema = 1;
|
||||
CREATE TABLE sqlite_rbu_replace_hack('v');
|
||||
}
|
||||
db close
|
||||
|
||||
do_test 1.6 {
|
||||
sqlite3rbu rbu test.db test.db2
|
||||
while 1 {
|
||||
set rc [rbu step]
|
||||
if {$rc!="SQLITE_OK"} break
|
||||
}
|
||||
list [catch { rbu close } msg] $msg
|
||||
} {0 SQLITE_DONE}
|
||||
|
||||
sqlite3 db test.db
|
||||
do_execsql_test 1.7 {
|
||||
PRAGMA integrity_check;
|
||||
SELECT count(*) FROM t1;
|
||||
} {ok 3}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
reset_db
|
||||
forcedelete test.db2
|
||||
do_execsql_test 2.0 {
|
||||
CREATE TABLE t1(a, b, c, PRIMARY KEY(a, b));
|
||||
CREATE INDEX t1c ON t1(c); -- root=4
|
||||
|
||||
ATTACH 'test.db2' AS 'rbu';
|
||||
CREATE TABLE rbu.data_t1(a, b, c, rbu_control);
|
||||
INSERT INTO data_t1 VALUES(1, 1, 1, 0);
|
||||
INSERT INTO data_t1 VALUES(2, 2, 2, 0);
|
||||
INSERT INTO data_t1 VALUES(3, 3, 3, 0);
|
||||
}
|
||||
|
||||
do_test 2.1 {
|
||||
sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 1 3
|
||||
execsql {
|
||||
CREATE TABLE imp1(a, b, id, PRIMARY KEY(b, id)) WITHOUT ROWID;
|
||||
INSERT INTO imp1 VALUES(2, 2, 2);
|
||||
}
|
||||
sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 0 3
|
||||
} {}
|
||||
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
|
||||
do_test 2.2 {
|
||||
sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 1 4
|
||||
execsql {
|
||||
CREATE TABLE imp1(c, id, PRIMARY KEY(c, id)) WITHOUT ROWID;
|
||||
INSERT INTO imp1 VALUES(3, 3);
|
||||
}
|
||||
sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 0 4
|
||||
} {}
|
||||
db close
|
||||
db_save
|
||||
|
||||
sqlite3 db test.db
|
||||
do_catchsql_test 2.3 { PRAGMA integrity_check } {0 {{wrong # of entries in index t1c} {wrong # of entries in index sqlite_autoindex_t1_1}}}
|
||||
db close
|
||||
|
||||
do_test 2.4 {
|
||||
sqlite3rbu rbu test.db test.db2
|
||||
while 1 {
|
||||
set rc [rbu step]
|
||||
if {$rc!="SQLITE_OK"} break
|
||||
}
|
||||
list [catch { rbu close } msg] $msg
|
||||
} {1 {SQLITE_CONSTRAINT - UNIQUE constraint failed: t1.a, t1.b}}
|
||||
|
||||
db_restore
|
||||
sqlite3 db test.db2
|
||||
do_execsql_test 2.5 {
|
||||
PRAGMA writable_schema = 1;
|
||||
CREATE TABLE sqlite_rbu_replace_hack('v');
|
||||
}
|
||||
db close
|
||||
|
||||
do_test 2.6 {
|
||||
sqlite3rbu rbu test.db test.db2
|
||||
while 1 {
|
||||
set rc [rbu step]
|
||||
if {$rc!="SQLITE_OK"} break
|
||||
}
|
||||
list [catch { rbu close } msg] $msg
|
||||
} {0 SQLITE_DONE}
|
||||
|
||||
sqlite3 db test.db
|
||||
do_execsql_test 2.7 {
|
||||
PRAGMA integrity_check;
|
||||
SELECT count(*) FROM t1;
|
||||
} {ok 3}
|
||||
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
+28
-3
@@ -103,6 +103,8 @@
|
||||
# define RBU_ENABLE_DELTA_CKSUM 0
|
||||
#endif
|
||||
|
||||
#define RBU_REPLACE_HACK_TABLE "sqlite_rbu_replace_hack"
|
||||
|
||||
/*
|
||||
** Swap two objects of type TYPE.
|
||||
*/
|
||||
@@ -376,6 +378,7 @@ struct sqlite3rbu {
|
||||
char *zRbu; /* Path to rbu db */
|
||||
char *zState; /* Path to state db (or NULL if zRbu) */
|
||||
char zStateDb[5]; /* Db name for state ("stat" or "main") */
|
||||
int bRbuReplaceHack; /* Do the REPLACE hack */
|
||||
int rc; /* Value returned by last rbu_step() call */
|
||||
char *zErrmsg; /* Error message if rc!=SQLITE_OK */
|
||||
int nStep; /* Rows processed for current object */
|
||||
@@ -2350,7 +2353,10 @@ static int rbuObjIterPrepareAll(
|
||||
if( p->rc==SQLITE_OK ){
|
||||
p->rc = prepareFreeAndCollectError(
|
||||
p->dbMain, &pIter->pInsert, &p->zErrmsg,
|
||||
sqlite3_mprintf("INSERT INTO \"rbu_imp_%w\" VALUES(%s)", zTbl, zBind)
|
||||
sqlite3_mprintf("%s INTO \"rbu_imp_%w\" VALUES(%s)",
|
||||
p->bRbuReplaceHack ? "REPLACE" : "INSERT",
|
||||
zTbl, zBind
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2442,7 +2448,8 @@ static int rbuObjIterPrepareAll(
|
||||
if( p->rc==SQLITE_OK ){
|
||||
p->rc = prepareFreeAndCollectError(p->dbMain, &pIter->pInsert, pz,
|
||||
sqlite3_mprintf(
|
||||
"INSERT INTO \"%s%w\"(%s%s) VALUES(%s)",
|
||||
"%s INTO \"%s%w\"(%s%s) VALUES(%s)",
|
||||
p->bRbuReplaceHack ? "REPLACE" : "INSERT",
|
||||
zWrite, zTbl, zCollist, (bRbuRowid ? ", _rowid_" : ""), zBindings
|
||||
)
|
||||
);
|
||||
@@ -2725,7 +2732,7 @@ static RbuState *rbuLoadState(sqlite3rbu *p){
|
||||
break;
|
||||
|
||||
case RBU_STATE_OALSZ:
|
||||
pRet->iOalSz = (u32)sqlite3_column_int64(pStmt, 1);
|
||||
pRet->iOalSz = sqlite3_column_int64(pStmt, 1);
|
||||
break;
|
||||
|
||||
case RBU_STATE_PHASEONESTEP:
|
||||
@@ -2744,6 +2751,24 @@ static RbuState *rbuLoadState(sqlite3rbu *p){
|
||||
rc2 = sqlite3_finalize(pStmt);
|
||||
if( rc==SQLITE_OK ) rc = rc2;
|
||||
|
||||
/* If this is not a vacuum operation, search for the special table
|
||||
** "sqlite_rbu_replace_hack". Set the flag if it is found.
|
||||
*/
|
||||
if( rc==SQLITE_OK && !rbuIsVacuum(p) ){
|
||||
sqlite3_stmt *pQuery = 0;
|
||||
rc = prepareFreeAndCollectError(p->dbRbu, &pQuery, &p->zErrmsg,
|
||||
sqlite3_mprintf("SELECT 1 FROM main.sqlite_master WHERE name='%s'",
|
||||
RBU_REPLACE_HACK_TABLE
|
||||
)
|
||||
);
|
||||
if( rc==SQLITE_OK ){
|
||||
if( sqlite3_step(pQuery)==SQLITE_ROW ){
|
||||
p->bRbuReplaceHack = 1;
|
||||
}
|
||||
rc = sqlite3_finalize(pQuery);
|
||||
}
|
||||
}
|
||||
|
||||
p->rc = rc;
|
||||
return pRet;
|
||||
}
|
||||
|
||||
@@ -527,7 +527,6 @@ SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
|
||||
SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
|
||||
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
|
||||
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
|
||||
SHELL_OPT += -DSQLITE_INTROSPECTION_PRAGMAS
|
||||
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
|
||||
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
|
||||
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
C Provide\sthe\sSQLITE_DIRECTONLY\sflag\sfor\sapp-defined\sfunctions\sthat\sprohibits\nthe\suse\sof\sthose\sfunctions\swithin\striggers\sor\sviews.
|
||||
D 2019-08-15T20:04:09.316
|
||||
C Fix\san\sRBU\sproblem\swith\srestarting\san\supdate\safter\sthe\s*-oal\sfile\sis\salready\slarger\sthan\s4GiB.
|
||||
D 2021-08-11T18:56:49.597
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
F Makefile.in 4640daf826b80947a924ac44275c451ffc13007c7c866a5730c8ce5cf9e1dc74
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc 1ce5a2f754201baf709132fe5b45027c73343fba2607107821f759d78cf136c0
|
||||
F Makefile.in 578f123620087ea459aa08fa872810a25ca7c0aaf16331de985bfcddb5f1e747
|
||||
F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241
|
||||
F Makefile.msc a463dca3c50d8a36094fe5c8c39077907f530b54edfc5388c66c85e2cfc8dc04
|
||||
F README.md 1514a365ffca3c138e00c5cc839906108a01011a6b082bad19b09781e3aa498a
|
||||
F VERSION 4c516d84c2a5f26c477ed34c09ac4136630f71c68139631f2eb591b22eea7cf1
|
||||
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
||||
@@ -47,7 +47,7 @@ F ext/async/sqlite3async.c 0f3070cc3f5ede78f2b9361fb3b629ce200d7d74
|
||||
F ext/async/sqlite3async.h f489b080af7e72aec0e1ee6f1d98ab6cf2e4dcef
|
||||
F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3
|
||||
F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4
|
||||
F ext/expert/expert1.test 358e416877a5693fb99d5514f5d88452b5239dc2196b74e0e926718502faef6d
|
||||
F ext/expert/expert1.test e2afc53a27610e8251e44c7f961806607a5490ff204b3db342740d558e052662
|
||||
F ext/expert/sqlite3expert.c 3da865f2286433588260f41e796422c611bceaca3a0bbf9139a619cf7d062c19
|
||||
F ext/expert/sqlite3expert.h af6354f8ee5c9e025024e63fec3bd640a802afcc3099a44d804752cf0791d811
|
||||
F ext/expert/test_expert.c d56c194b769bdc90cf829a14c9ecbc1edca9c850b837a4d0b13be14095c32a72
|
||||
@@ -81,7 +81,7 @@ F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51
|
||||
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
|
||||
F ext/fts3/README.tokenizers b92bdeb8b46503f0dd301d364efc5ef59ef9fa8e2758b8e742f39fa93a2e422d
|
||||
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
|
||||
F ext/fts3/fts3.c 33958a8c05a6c22bf559fedb1176ad1f313a7b42ccf5f0c0bcc8a88609e58d60
|
||||
F ext/fts3/fts3.c a01da95e840a6ddb14d0a14b35c9017a8b034b08511ca97af716f00df102fb3f
|
||||
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
|
||||
F ext/fts3/fts3Int.h 74384e28b778a057f1467529715668b98f3f12f52eeb564fd6ae1e894125c00c
|
||||
F ext/fts3/fts3_aux.c 96708c8b3a7d9b8ca1b68ea2b7e503e283f20e95f145becadedfad096dbd0f34
|
||||
@@ -90,7 +90,7 @@ F ext/fts3/fts3_hash.c 8b6e31bfb0844c27dc6092c2620bdb1fca17ed613072db057d96952c6
|
||||
F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf
|
||||
F ext/fts3/fts3_icu.c 305ce7fb6036484085b5556a9c8e62acdc7763f0f4cdf5fd538212a9f3720116
|
||||
F ext/fts3/fts3_porter.c 3565faf04b626cddf85f03825e86056a4562c009
|
||||
F ext/fts3/fts3_snippet.c 2f3a78b990f1c8658225618c8a0fa06ab60046688d6fb627a548e8ada9011150
|
||||
F ext/fts3/fts3_snippet.c 7963dd25ec81013c31f3c61697d0a1f3d06be21af3565774645c08d3dedf1fa7
|
||||
F ext/fts3/fts3_term.c f45a1e7c6ef464abb1231245d123dae12266b69e05cc56e14045b76591ae92d1
|
||||
F ext/fts3/fts3_test.c 73b16e229e517c1b1f0fb8e1046182a4e5dbc8dbe6eea8a5d4353fcce7dbbf39
|
||||
F ext/fts3/fts3_tokenize_vtab.c 1de9a61acfa2a0445ed989310c31839c57f6b6086dd9d5c97177ae734a17fd8b
|
||||
@@ -99,7 +99,7 @@ F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3
|
||||
F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004
|
||||
F ext/fts3/fts3_unicode.c 4b9af6151c29b35ed09574937083cece7c31e911f69615e168a39677569b684d
|
||||
F ext/fts3/fts3_unicode2.c 416eb7e1e81142703520d284b768ca2751d40e31fa912cae24ba74860532bf0f
|
||||
F ext/fts3/fts3_write.c 6efc4cd7dc554df06c35bfd3335503838645806a78fc33137a55eb97a8b2f3b2
|
||||
F ext/fts3/fts3_write.c 13582783abedf905e6946ce95edff7103c07810fb03a9c3b40212d21a3efa09c
|
||||
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
|
||||
F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
|
||||
F ext/fts3/tool/fts3cov.sh c331d006359456cf6f8f953e37f2b9c7d568f3863f00bb5f7eb87fea4ac01b73
|
||||
@@ -110,14 +110,14 @@ 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 7c9da96f2b9dcfa4dd94081fb2d87ec418d8cdb35b25df56756c334b6b558fd7
|
||||
F ext/fts5/fts5Int.h d87fb17d12296613cdec2d1f4213ecd8840d3deb34837b6d3889b830d06baac4
|
||||
F ext/fts5/fts5Int.h 0ec19a906a54c0e53f8a380c0ff70f11a866aa259490bc13aa39f8d2491800fd
|
||||
F ext/fts5/fts5_aux.c dcc627d8b6e3fc773db528ff67b39955dab7b51628f9dba8e15849e5bedfd7fa
|
||||
F ext/fts5/fts5_buffer.c 5a5fe0159752c0fb0a5a93c722e9db2662822709490769d482b76a6dc8aaca70
|
||||
F ext/fts5/fts5_config.c d7523cba5e66da077233c023aecbc3e6a37978ff75a18131c5ab5b1229d5bac7
|
||||
F ext/fts5/fts5_expr.c 840c88d55e78083a5e61a35968df877712ae28791b347eced1e98e3b337d2d3c
|
||||
F ext/fts5/fts5_config.c 606a29f2962a8f4508923e6ad833974b32a3ab4093f63fd6de0fb33a87eed54c
|
||||
F ext/fts5/fts5_expr.c 5661fe64f4f5a499710df9561075de84b743f01e808af46df4130a9ec343a0fd
|
||||
F ext/fts5/fts5_hash.c 1cc0095646f5f3b46721aa112fb4f9bf29ae175cb5338f89dcec66ed97acfe75
|
||||
F ext/fts5/fts5_index.c cd363c2fa3e626c04a9b7c705ff50222b4cab052704938f6a24881602ed3ed0d
|
||||
F ext/fts5/fts5_main.c 346a1ec08caa66f1187f1e0bf12e39e4d24682323b839e8a76ef653b8db8a91d
|
||||
F ext/fts5/fts5_index.c 6601d085d8e8cf4750ee49e2e1d18907582cc0aab78233d3b21bc240ba76a199
|
||||
F ext/fts5/fts5_main.c bf637030722badf06667d28f7159e4c209dbafd7aa76c33f387104b78ad147e1
|
||||
F ext/fts5/fts5_storage.c 801b4e3cd33786a60a07b6b01f86d0fbdf7e68325054e08d17176293a8081e99
|
||||
F ext/fts5/fts5_tcl.c 39bcbae507f594aad778172fa914cad0f585bf92fd3b078c686e249282db0d95
|
||||
F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee
|
||||
@@ -157,7 +157,7 @@ F ext/fts5/test/fts5connect.test 08030168fc96fc278fa81f28654fb7e90566f33aff269c0
|
||||
F ext/fts5/test/fts5content.test 9517cc527a8e8a33949652d5c7b5e251f8c3d5ae3f23f01d4320e30f29a0336b
|
||||
F ext/fts5/test/fts5corrupt.test 77ae6f41a7eba10620efb921cf7dbe218b0ef232b04519deb43581cb17a57ebe
|
||||
F ext/fts5/test/fts5corrupt2.test 7453752ba12ce91690c469a6449d412561cc604b1dec994e16ab132952e7805f
|
||||
F ext/fts5/test/fts5corrupt3.test 1f36c04fdd717f7d44a0addcdad0f5e54a5a403eab8a25426b069757830682ee
|
||||
F ext/fts5/test/fts5corrupt3.test e188a43cecb3ff53b6236f862f82b2ec36962b9e39f20cb620dfa07aed70afa4
|
||||
F ext/fts5/test/fts5corrupt4.test ea805c4d7c68b5f185b9db5d2060a7ae5875339738dd48203c92162f41e7ca91
|
||||
F ext/fts5/test/fts5delete.test cbf87e3b8867c4d5cfcaed975c7475fd3f99d072bce2075fcedf43d1f82af775
|
||||
F ext/fts5/test/fts5detail.test 31b240dbf6d44ac3507e2f8b65f29fdc12465ffd531212378c7ce1066766f54e
|
||||
@@ -176,7 +176,7 @@ F ext/fts5/test/fts5fault7.test 0acbec416edb24b8881f154e99c31e9ccf73f539cfcd1640
|
||||
F ext/fts5/test/fts5fault8.test 318238659d35f82ad215ecb57ca4c87486ea85d45dbeedaee42f148ff5105ee2
|
||||
F ext/fts5/test/fts5fault9.test 098e6b894bbdf9b2192f994a30f4043673fb3f338b6b8ab1624c704422f39119
|
||||
F ext/fts5/test/fts5faultA.test be4487576bff8c22cee6597d1893b312f306504a8c6ccd3c53ca85af12290c8c
|
||||
F ext/fts5/test/fts5faultB.test e6d04f9ea7b21be1d89abb8df2cb4baf65b0453b744d5a805fcd3ef45ff86a7e
|
||||
F ext/fts5/test/fts5faultB.test d606bdb8e81aaeb6f41de3fc9fc7ae315733f0903fbff05cf54f5b045b729ab5
|
||||
F ext/fts5/test/fts5faultD.test cc5d1225556e356615e719c612e845d41bff7d5a
|
||||
F ext/fts5/test/fts5first.test 3fcf2365c00a15fc9704233674789a3b95131d12de18a9b996159f6909dc8079
|
||||
F ext/fts5/test/fts5full.test 49b565da02918c06e58f51f0b953b0302b96f155aa68baba24782b81570685e2
|
||||
@@ -189,21 +189,23 @@ F ext/fts5/test/fts5leftjoin.test c0b4cafb9661379e576dc4405c0891d8fcc27826807405
|
||||
F ext/fts5/test/fts5matchinfo.test 79129ff6c9a2d86943b287a5a8caa7ee639f6dcf004d8975d15c279374e82e35
|
||||
F ext/fts5/test/fts5merge.test e92a8db28b45931e7a9c7b1bbd36101692759d00274df74d83fd29d25d53b3a6
|
||||
F ext/fts5/test/fts5merge2.test 3ebad1a59d6ad3fb66eff6523a09e95dc6367cbefb3cd73196801dea0425c8e2
|
||||
F ext/fts5/test/fts5misc.test 5becd134b66f7370042968a2b127b92ea7748e249f16cb6a996f450812e89eec
|
||||
F ext/fts5/test/fts5multi.test a15bc91cdb717492e6e1b66fec1c356cb57386b980c7ba5af1915f97fe878581
|
||||
F ext/fts5/test/fts5multiclient.test 5ff811c028d6108045ffef737f1e9f05028af2458e456c0937c1d1b8dea56d45
|
||||
F ext/fts5/test/fts5near.test 211477940142d733ac04fad97cb24095513ab2507073a99c2765c3ddd2ef58bd
|
||||
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 00dc4c974938b509db7cb3680407f068ee6e9cc824f492f68cb741a7b679fe41
|
||||
F ext/fts5/test/fts5plan.test 771b999d161e24fd803ce0290adb7c6e7c9b9cc2c6a0adb344813fb89473aa32
|
||||
F ext/fts5/test/fts5porter.test 8d08010c28527db66bc3feebd2b8767504aaeb9b101a986342fa7833d49d0d15
|
||||
F ext/fts5/test/fts5porter2.test 0d251a673f02fa13ca7f011654873b3add20745f7402f108600a23e52d8c7457
|
||||
F ext/fts5/test/fts5prefix.test a0fa67b06650f2deaa7bf27745899d94e0fb547ad9ecbd08bfad98c04912c056
|
||||
F ext/fts5/test/fts5query.test ac363b17a442620bb0780e93c24f16a5f963dfe2f23dc85647b869efcfada728
|
||||
F ext/fts5/test/fts5rank.test ca5000241924ecc2882db33c60f4f3a62b1ee6b16b5a9c8c6ddd9b6b2138489c
|
||||
F ext/fts5/test/fts5rank.test c9fd4a1e36b4fa92d572ec13d846469b97da249d1c2f7fd3ee7e017ce46f2416
|
||||
F ext/fts5/test/fts5rebuild.test 55d6f17715cddbf825680dd6551efbc72ed916d8cf1cde40a46fc5d785b451e7
|
||||
F ext/fts5/test/fts5restart.test 835ecc8f449e3919f72509ab58056d0cedca40d1fe04108ccf8ac4c2ba41f415
|
||||
F ext/fts5/test/fts5rowid.test b8790ec170a8dc1942a15aef3db926a5f3061b1ff171013003d8297203a20ad6
|
||||
F ext/fts5/test/fts5simple.test 313ad28ef38ebe25f0a1673dd18f2fac446e25feb15bbb0c223a65ea00594f72
|
||||
F ext/fts5/test/fts5simple.test a298670508c1458b88ce6030440f26a30673931884eb5f4094ac1773b3ba217b
|
||||
F ext/fts5/test/fts5simple2.test 258a1b0c590409bfa5271e872c79572b319d2a56554d0585f68f146a0da603f0
|
||||
F ext/fts5/test/fts5simple3.test d5c74a9d3ca71bd5dd5cacb7c55b86ea12cdddfc8b1910e3de2995206898380f
|
||||
F ext/fts5/test/fts5synonym.test 1651815b8008de170e8e600dcacc17521d765482ea8f074ae82cfa870d8bb7fb
|
||||
@@ -229,7 +231,7 @@ F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c
|
||||
F ext/icu/README.txt a295e91db742b153e8dce8f7efd31d28ad1eea4df31ef4daa3eedc85be2f5138
|
||||
F ext/icu/icu.c c2c7592574c08cd1270d909b8fb8797f6ea1f49e931e71dbcc25506b9b224580
|
||||
F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37
|
||||
F ext/lsm1/Makefile 98b0a24b45e248283d6bea4b6cb3e58d7b394edd8e96a0ac28c5fa5104813bad
|
||||
F ext/lsm1/Makefile a553b728bba6c11201b795188c5708915cc4290f02b7df6ba7e8c4c943fd5cd9
|
||||
F ext/lsm1/Makefile.msc f8c878b467232226de288da320e1ac71c131f5ec91e08b21f502303347260013
|
||||
F ext/lsm1/lsm-test/README 87ea529d2abe615e856d4714bfe8bb185e6c2771b8612aa6298588b7b43e6f86
|
||||
F ext/lsm1/lsm-test/lsmtest.h cf58528ffe0cfe535e91b44584e2ec5fb1caacdabecef0d8dcf83bf83168bf28
|
||||
@@ -269,10 +271,10 @@ F ext/lsm1/lsm_str.c 65e361b488c87b10bf3e5c0070b14ffc602cf84f094880bece77bbf6678
|
||||
F ext/lsm1/lsm_tree.c 682679d7ef2b8b6f2fe77aeb532c8d29695bca671c220b0abac77069de5fb9fb
|
||||
F ext/lsm1/lsm_unix.c 57361bcf5b1a1a028f5d66571ee490e9064d2cfb145a2cc9e5ddade467bb551b
|
||||
F ext/lsm1/lsm_varint.c 43f954af668a66c7928b81597c14d6ad4be9fedbc276bbd80f52fa28a02fdb62
|
||||
F ext/lsm1/lsm_vtab.c 529255dc704289001b225d97e57e0cfa14b29c3f281c7349cfa8fdb655de79ae
|
||||
F ext/lsm1/lsm_vtab.c 169bfe7ef8e6c9de9c77e17c4c50c9ae55fb0167d80be3d1be82c991184b6f35
|
||||
F ext/lsm1/lsm_win32.c 0a4acbd7e8d136dd3a5753f0a9e7a9802263a9d96cef3278cf120bcaa724db7c
|
||||
F ext/lsm1/test/lsm1_common.tcl 5ed4bab07c93be2e4f300ebe46007ecf4b3e20bc5fbe1dedaf04a8774a6d8d82
|
||||
F ext/lsm1/test/lsm1_simple.test ca949efefa102f4644231dcd9291d8cda7699a4ce1006b26e0e3fcb72233f422
|
||||
F ext/lsm1/test/lsm1_simple.test a04d08e8661ae6fc53786c67f0bd102c6692f003e859dde03ed9ac3f12e066e5
|
||||
F ext/lsm1/tool/mklsm1c.tcl f31561bbee5349f0a554d1ad7236ac1991fc09176626f529f6078e07335398b0
|
||||
F ext/misc/README.md d6dd0fe1d8af77040216798a6a2b0c46c73054d2f0ea544fbbcdccf6f238c240
|
||||
F ext/misc/amatch.c 50a9ef2d38dabfa371f8c1904097d493271e63d58ccb0e9b79a4fa4a94e66660
|
||||
@@ -280,7 +282,7 @@ F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a2
|
||||
F ext/misc/appendvfs.c 3777f22ec1057dc4e5fd89f2fbddcc7a29fbeef1ad038c736c54411bb1967af7
|
||||
F ext/misc/blobio.c a867c4c4617f6ec223a307ebfe0eabb45e0992f74dd47722b96f3e631c0edb2a
|
||||
F ext/misc/btreeinfo.c 4f0ebf278f46e68e6306c667917766cebc5550fd35d5de17847988e22892d4d2
|
||||
F ext/misc/carray.c ed96c218ea940b85c9a274c4d9c59fe9491c299147a38a8bba537687bd6c6005
|
||||
F ext/misc/carray.c 91e9a7f512fda934894bed30464552fffa7d3073b5be04189ae0bd0c59f26bfd
|
||||
F ext/misc/closure.c dbfd8543b2a017ae6b1a5843986b22ddf99ff126ec9634a2f4047cd14c85c243
|
||||
F ext/misc/completion.c cec672d40604075bb341a7f11ac48393efdcd90a979269b8fe7977ea62d0547f
|
||||
F ext/misc/compress.c dd4f8a6d0baccff3c694757db5b430f3bbd821d8686d1fc24df55cf9f035b189
|
||||
@@ -293,7 +295,7 @@ F ext/misc/fileio.c 288e7230e0fe464d71b0694e2d8bdd3a353118ac2e31da3964b95f460f09
|
||||
F ext/misc/fossildelta.c 7708651072eb5620ab21bbfb518d184f27b2c29c0131b09b9a2d8852a8016430
|
||||
F ext/misc/fuzzer.c c4e27daf41433a64cad5265cd27dbcb891147e9994d0422200ce81ce9a54b625
|
||||
F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c
|
||||
F ext/misc/json1.c 71ce4e39793b743fc7e4790bc3bab15598e95cab57ad8da4326fa640ae5e5310
|
||||
F ext/misc/json1.c 66ccdfa63283adb2c015019b431eeee1f5af40a78d9aad10afd22c2c6db0e3b0
|
||||
F ext/misc/memstat.c 3017a0832c645c0f8c773435620d663855f04690172316bd127270d1a7523d4d
|
||||
F ext/misc/memtrace.c 7c0d115d2ef716ad0ba632c91e05bd119cb16c1aedf3bec9f06196ead2d5537b
|
||||
F ext/misc/memvfs.c ab36f49e02ebcdf85a1e08dc4d8599ea8f343e073ac9e0bca18a98b7e1ec9567
|
||||
@@ -351,6 +353,7 @@ F ext/rbu/rbufault2.test c81327a3ac2c385b9b954db3644d4e0df93eeebfc3de9f1f29975a1
|
||||
F ext/rbu/rbufault3.test b2fcc9db5c982b869f67d1d4688d8cb515d5b92f58011fff95665f2e62cec179
|
||||
F ext/rbu/rbufault4.test 03d2849c3df7d7bd14a622e789ff049e5080edd34a79cd432e01204db2a5930a
|
||||
F ext/rbu/rbufts.test 0ae8d1da191c75bd776b86e24456db0fb6e97b7c944259fae5407ea55d23c31d
|
||||
F ext/rbu/rbuhack.test 95e7b35e58d5b2a8d182dde1a404949edf077c07485e6c2bce8a7f582941e729
|
||||
F ext/rbu/rbumisc.test 329986cf5dd51890c4eb906c2f960ebb773a79a64bed90f506b7c417825b37eb
|
||||
F ext/rbu/rbumulti.test 5fb139058f37ddc5a113c5b93238de915b769b7792de41b44c983bc7c18cf5b9
|
||||
F ext/rbu/rbupartial.test f25df014b8dbe3c5345851fba6e66f79ab237f57dc201b2d5f0dbae658ae5a4c
|
||||
@@ -363,7 +366,7 @@ F ext/rbu/rbuvacuum.test 55e101e90168c2b31df6c9638fe73dc7f7cc666b6142266d1563697
|
||||
F ext/rbu/rbuvacuum2.test b8e5b51dc8b2c0153373d024c0936be3f66f9234acbd6d0baab0869d56b14e6b
|
||||
F ext/rbu/rbuvacuum3.test 8addd82e4b83b4c93fa47428eae4fd0dbf410f8512c186f38e348feb49ba03dc
|
||||
F ext/rbu/rbuvacuum4.test a78898e438a44803eb2bc897ba3323373c9f277418e2d6d76e90f2f1dbccfd10
|
||||
F ext/rbu/sqlite3rbu.c f3a3e09f575157052813be667d6ab3b54f47fb02e6e1c9f767ad7bb8f1fb90b3
|
||||
F ext/rbu/sqlite3rbu.c d175cbd98baba39cdea85df1de376277ab207ef1e4af8071aa1c208bb4fccc84
|
||||
F ext/rbu/sqlite3rbu.h 1dc88ab7bd32d0f15890ea08d23476c4198d3da3056985403991f8c9cd389812
|
||||
F ext/rbu/test_rbu.c 03f6f177096a5f822d68d8e4069ad8907fe572c62ff2d19b141f59742821828a
|
||||
F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15
|
||||
@@ -445,7 +448,7 @@ F ext/userauth/userauth.c f81aa5a3ecacf406f170c62a144405858f6f6de51dbdc0920134e6
|
||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
|
||||
F main.mk 125adda36bb32c99dc3a11340bd029ef373b9523eac2b2af76087bfe82d4fdf8
|
||||
F main.mk 09716d345766a55b25ed157b14786526cf67c761c61d99c53e117196fb3b391a
|
||||
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
|
||||
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
|
||||
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
|
||||
@@ -459,15 +462,15 @@ F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
|
||||
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
|
||||
F src/alter.c 5c3031e45e80f79d7d54c2d32dd3c44926544d4f6a478858bfe4ee3191570190
|
||||
F src/analyze.c a3f4ea45cdb4e9df78d4ea7beb87ec8a7a46f494173b641cd28512a40a97bff2
|
||||
F src/attach.c a6f108eb7922fad920e8aba0cda56fb56d89d136d519be5177cd3bd3559f2566
|
||||
F src/attach.c 3ca19504849c2d9be10fc5899d6811f9d6e848665d1a41ffb53df0cd6e7c13ed
|
||||
F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06
|
||||
F src/backup.c f70077d40c08b7787bfe934e4d1da8030cb0cc57d46b345fba2294b7d1be23ab
|
||||
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
|
||||
F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
|
||||
F src/btree.c 5cf994516c1b74928b9d15971573a8bc8595e1afec129184099976da603402de
|
||||
F src/btree.c fdc4389b271bca30138db27dc2dfb9f52c2a7baaa44845aaf31a3c54663d837f
|
||||
F src/btree.h c11446f07ec0e9dc85af8041cb0855c52f5359c8b2a43e47e02a685282504d89
|
||||
F src/btreeInt.h 6111c15868b90669f79081039d19e7ea8674013f907710baa3c814dc3f8bfd3f
|
||||
F src/build.c 7fb6ad35d162517d6bfa196f4fb2a1d7c3a362531e84c59f3a0479e0de511556
|
||||
F src/build.c 4814d55abb5553ac82763f6df9e185503d913f912cc0abea00965bb02912cc2d
|
||||
F src/callback.c 25dda5e1c2334a367b94a64077b1d06b2553369f616261ca6783c48bcb6bda73
|
||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||
F src/ctime.c 1b0724e66f95f33b160b1af85caaf9cceb325d22abf39bd24df4f54a73982251
|
||||
@@ -475,19 +478,19 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041
|
||||
F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7
|
||||
F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319
|
||||
F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf
|
||||
F src/expr.c 1b4f5a53a5f48ba3f718413586e0f9715cf90c684fba9038186a62728e2ebe72
|
||||
F src/expr.c 1e9a6da29e3e13c14783891e867e19a54e2731c6a9b58d011cc4f3b4742a59e4
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c 6b79f4c2447691aa9ac86e2a6a774b65f3b3dd053d4220a4893051a0de20f82e
|
||||
F src/func.c 4ee36219698d50d672a28eca4adb0fd6b92e607a1883d318315e0d2fd5044467
|
||||
F src/global.c d7a7a45a78ffe01302d61c271ed50474ef1b9d2d23bf17a46a58c8a1926424ee
|
||||
F src/func.c ed33e38cd642058182a31a3f518f2e34f4bbe53aa483335705c153c4d3e50b12
|
||||
F src/global.c a1a8d698762ddd9a1543aac26c1e0029b20fcc3fcb56bfa41ec8cea2368f2798
|
||||
F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19
|
||||
F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38
|
||||
F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da
|
||||
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
|
||||
F src/insert.c c2194dd2886337b870226fcb31c13e7df8c4b5e0ea85140e510a6f1daf1ad65b
|
||||
F src/insert.c 40557ebd69f4115e7a273f9304a8ab637a47ce44f3c6923396928f023967b5e8
|
||||
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
|
||||
F src/loadext.c 22afc33c3a61b4fd80a60a54f1882688371e6bc64685df2696b008fce65a999c
|
||||
F src/main.c ff418603f9435914e8bd2febd1d5dbfcbf2ece3a4e853481a81a50fc27b321ab
|
||||
F src/loadext.c 4ddc65ae13c0d93db0ceedc8b14a28c8c260513448b0eb8c5a2ac375e3b6a85d
|
||||
F src/main.c 3851950717170ade4f6d718c18c6c7400ef5994c2a654679af2cff2ffd0fb2b9
|
||||
F src/malloc.c 0f9da2a66b230a5785af94b9672126845099b57b70a32c987d04ac28c69da990
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
|
||||
@@ -498,7 +501,7 @@ F src/memdb.c 02a5fcec19b9d40dd449ca802dc1b2e8f93f255fbf2a886277a3c3800d8d35db
|
||||
F src/memjournal.c 7561c01c90958f3ba9bc6cb2d857123d932bdfa5539ea34427a0957b2e35154d
|
||||
F src/msvc.h 3a15918220367a8876be3fa4f2abe423a861491e84b864fb2b7426bf022a28f8
|
||||
F src/mutex.c bae36f8af32c22ad80bbf0ccebec63c252b6a2b86e4d3e42672ff287ebf4a604
|
||||
F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85
|
||||
F src/mutex.h a7b2293c48db5f27007c3bdb21d438873637d12658f5a0bf8ad025bb96803c4a
|
||||
F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4
|
||||
F src/mutex_unix.c aaf9ebc3f89df28483c52208497a99a02cc3650011422fc9d4c57e4392f7fe58
|
||||
F src/mutex_w32.c 7670d770c94bbfe8289bec9d7f1394c5a00a57c37f892aab6b6612d085255235
|
||||
@@ -507,33 +510,33 @@ F src/os.c 20f7b32c1e8839999fa7e79756a6cdc3041b44d7fc635c25a1b9399180d1fbd9
|
||||
F src/os.h 48388821692e87da174ea198bf96b1b2d9d83be5dfc908f673ee21fafbe0d432
|
||||
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
|
||||
F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
|
||||
F src/os_unix.c 4ec5b1305ced509ca52c4c0cb3aeabed2ed3972147b4090cf94eb31d48caeb53
|
||||
F src/os_unix.c a76a75f179cb233d54e505c3e0c84832224cfe5dfb3ee470bdcaf1ed29da57ab
|
||||
F src/os_win.c 035a813cbd17f355bdcad7ab894af214a9c13a1db8aeac902365350b98cd45a7
|
||||
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
||||
F src/pager.c 422fd8cfa59fb9173eff36a95878904a0eeb0dcc62ba49350acc8b1e51c4dc7b
|
||||
F src/pager.h 217921e81eb5fe455caa5cda96061959706bcdd29ddb57166198645ef7822ac3
|
||||
F src/parse.y 6d03a24bc0dcd15b93c480ea8a87f7ccd25313fe826485726d9ef13b82f2378d
|
||||
F src/parse.y 50bfcb34be7320dd0cb875021a93ae6451c8f0b083f21b71934a1a3a9108015a
|
||||
F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177
|
||||
F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
|
||||
F src/pcache1.c 62714cbd1b7299a6e6a27a587b66b4fd3a836a84e1181e7f96f5c34a50917848
|
||||
F src/pragma.c a42d4c6040893a59b69a0c987e5ed0402730c444ee451fde9bbe6203e7f73b1d
|
||||
F src/pragma.h 4a9fabff14db4487a734dfeeb4be984ce662bfdccfae16145b9c732327735e13
|
||||
F src/pragma.c b47bc7db02ab13d04c680aee424466b4e34f4ef5aa7b2e464876ec005806f98f
|
||||
F src/pragma.h 40962d65b645bb3f08c1f4c456effd01c6e7f073f68ea25177e0c95e181cff75
|
||||
F src/prepare.c 132484635a30f873ee7eccd47f93ed1932503863b93b28423b42332d81adffaf
|
||||
F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4
|
||||
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
|
||||
F src/resolve.c b2733d39a22f5023ab489b8535ca6854b51ff8667ca975815d004bb7388b0e41
|
||||
F src/resolve.c e021be0c1c4a2125fa38aabcd8dbb764bf5b2c889a948c30d3708430ec6ccd00
|
||||
F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93
|
||||
F src/select.c 11087458ec2af5c4b377559ea0462c2ab842e02badd35b21a8d67257c4e0b117
|
||||
F src/shell.c.in 66cd8289adbcd159ca67872c242990ca6bed29fe80be7ebf9c6a1c068249a41e
|
||||
F src/sqlite.h.in dfbb64c0b8e4b3de2958d8372208437509acdc523aed8ae90a164f3a5d9a5739
|
||||
F src/select.c f509982c96bb24ccf57a0155fbe1e6184e0b8fb8866a04397dc41baa400e5240
|
||||
F src/shell.c.in d70bcf630c4073eaa994fa74be98886c781918e794cb8b562be8df10f018e274
|
||||
F src/sqlite.h.in 5725a6b20190a1e8d662077a1c1c8ea889ad7be90dd803f914c2de226f5fe6ab
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5
|
||||
F src/sqliteInt.h 12e8af40a561a3006b6996938c88cce1e24efe690955e193824571d20c3ef352
|
||||
F src/sqlite3ext.h cef696ce3293242c67b2339763608427bf72ee66f1f3a05389ac2a7b46001c31
|
||||
F src/sqliteInt.h 246740eab76d3ac87f856f8d979567089e8749104c12932143a6ba570e38e415
|
||||
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
|
||||
F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
|
||||
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
|
||||
F src/tclsqlite.c a65eb317f8b83f7ae546f88db56600f9a39550688d70501b8eb0cc3a4b4960c9
|
||||
F src/test1.c 87059457fb90b73a74044b379fe2cb0aefbb53c010c646ecaff23179a423638c
|
||||
F src/tclsqlite.c 50c93be3e1c03b4e6cf6756e5197afcfe7f5cd0497d83a7ac317cde09e19b290
|
||||
F src/test1.c 17e1395cbddeb9226b756d723a7566b45b43b99a5f9f55afb4ff70888de6ad6f
|
||||
F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
|
||||
F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644
|
||||
F src/test4.c 405834f6a93ec395cc4c9bb8ecebf7c3d8079e7ca16ae65e82d01afd229694bb
|
||||
@@ -554,7 +557,7 @@ F src/test_demovfs.c 86142ba864d4297d54c5b2e972e74f3141ae4b30f05b3a95824184ed2d3
|
||||
F src/test_devsym.c 6109b45c3db3ef7b002320947ed448c027356ab8b885156ff535fd8684d4a571
|
||||
F src/test_fs.c ba1e1dc18fd3159fdba0b9c4256f14032159785320dfbd6776eb9973cb75d480
|
||||
F src/test_func.c 181f992e5495644434c4f0e3cc72362a78c295eb2cf3ff4d02498b8bde7aa276
|
||||
F src/test_hexio.c 1d4469ca61ab202a1fcec6543f584d2407205e8d
|
||||
F src/test_hexio.c d170d0e1a6431afdeac086a250d2595078288c2257615d37949355361399bcaa
|
||||
F src/test_init.c 4413c211a94b62157ca4c145b3f27c497f03c664
|
||||
F src/test_intarray.c 39b4181662a0f33a427748d87218e7578d913e683dc27eab7098bb41617cac71
|
||||
F src/test_intarray.h d57ae92f420cda25e22790dac474d60961bd0c500cbaa3338a05152d4a669ef7
|
||||
@@ -588,37 +591,37 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394
|
||||
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
|
||||
F src/tokenize.c d3615f0cbe4db5949503bf5916f3cd4fa5de855d5b4ef560f3b6dd5629423a1e
|
||||
F src/treeview.c fc8c6c0a8a26afb3a97e3f844d65403dd27cf1450baf4415034fa4ccf00c4d7e
|
||||
F src/trigger.c 2305271878e95addc1c01361e5e8e342e87cba5efefdd7d3032687e5d67e05d1
|
||||
F src/update.c 3cb9150d2cf661d938e2f1b1749945f3faa767f88febdb739ab1793bbf895ff2
|
||||
F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4
|
||||
F src/treeview.c fddeb413159c3eeeaea3f496172f121cf3695606c461dc4e6dcee51417952df5
|
||||
F src/trigger.c 845ccc08f60716c58aa28fe6470385c18ef8c4e1d88c93dcf449bc13d464eb2e
|
||||
F src/update.c 7f05fad5e145248a00048aeb0bac78b8fdb4ed17216e14a6eb24c55596e87ee7
|
||||
F src/upsert.c 710c91bb13e3c3fed5b6fe17cb13e09560bdd003ad8b8c51e6b16c80cfc48b10
|
||||
F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507
|
||||
F src/util.c fffdfa627be74d69ef425f92db124e7148af449bb8a3286e79577c42bca84061
|
||||
F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf
|
||||
F src/vdbe.c 1041610254502572bcc79ce6f61d9364fb93c154a4935fbaeaa7fd2e158e5205
|
||||
F src/vdbe.c 7f43ed8e055a4290535d2e4520d33f0ac6cc00ef76a0c099e4c6bd85be74a6b9
|
||||
F src/vdbe.h 3f2b571e702e77e6bf031f0236e554aedfae643e991f69000320f481408455cf
|
||||
F src/vdbeInt.h e95de5129124d77f01439e6635012adfaf23c0017bff47296126143cf18bd0c6
|
||||
F src/vdbeapi.c 95001d0f84ee3cda344fed98ca0d7961deb4fc836b83495630d0af1f7cc4789e
|
||||
F src/vdbeaux.c 8eeb9799d80bc6b37f2bcb23b3519234b596c530046c2cd0261f9ef1a1ba6c37
|
||||
F src/vdbeaux.c 7ccf418141df1c7f87b0d69510523ae522abbe47c769d1b2c15120e88fac3eb9
|
||||
F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b1
|
||||
F src/vdbemem.c 920285c3b7f5c64369e02da437dab71e9e91862df9c486541c14633739f91d75
|
||||
F src/vdbesort.c 3531ae3a431ad6b98b67bd891fb42ec9d66867157188a2b1a9e58c55da6151b2
|
||||
F src/vdbemem.c d8e10d1773806105e62094c4ede0a4684f46caaf07667a45e6d461e94306b530
|
||||
F src/vdbesort.c da75f505aba230060ce6472605a4aa6494f73eeb1071e1cc2643c3d4035e671b
|
||||
F src/vdbetrace.c fa3bf238002f0bbbdfb66cc8afb0cea284ff9f148d6439bc1f6f2b4c3b7143f0
|
||||
F src/vtab.c 1fa256c6ddad7a81e2a4dc080d015d4b0a7135767717d311298e47f6fca64bb3
|
||||
F src/vtab.c 5a0b7193d586991b3db30e343d6b59959906bfe8658a6a0a85709b20ca50bb49
|
||||
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c bbd6838bd79c0a32144d482fb0b6a9d2d1a252fb3b16d5005ec30f2f80413b0d
|
||||
F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a
|
||||
F src/walker.c d5a94907dcac990e31976be9dc769d17f6a806782593d6aec9d760ee01ec22cd
|
||||
F src/where.c 2fac51d2420f05ab6f644f1813d4f73f6214304836fd9b22345738d943faad9b
|
||||
F src/whereInt.h 2082fc2bd1eb66cb236a1a3c4b250e33d2bad9e43a0486a2cf9e4e211c58f3eb
|
||||
F src/wherecode.c cf885ea2d439af9827c5cbab7d4c12be5c079439b7bd12e97151ccfe088c13c0
|
||||
F src/whereexpr.c 5cce1fd11876086890a27c05e0cb75ca97ba64ba6984f72154039f1cfd2e69cc
|
||||
F src/window.c 07e1c15081a735750218185c6b17053c87ecb764d06ab2c0a1ce568a2b4688e5
|
||||
F src/where.c 9f3f23efc45934e7b7ea6c0c1042420b73053e7c3264feef6faf9ce6fbd5df61
|
||||
F src/whereInt.h 2c6bae136a7c0be6ff75dc36950d1968c67d005c8e51d7a9d77cb996bb4843d9
|
||||
F src/wherecode.c 535c8e228478fd971b9a5b6cb6773995b0fbf7020d5989508a5094ce5b8cd95b
|
||||
F src/whereexpr.c 05c283d26aa9c3f5d1bf13a5f6a573b43295b9db280eff18e26f97d7d7f119b4
|
||||
F src/window.c 064f251451c8e2a1c76b6269229d911a651e119c6a5f522b6eaebf8dc8714041
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
|
||||
F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627
|
||||
F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
F test/aggnested.test 18b00de006597e960a6b27ccec51474ac66cf1070a87c1933e5694dc02190ef1
|
||||
F test/aggnested.test 12106f0748e8e9bfc1a8e6840e203e051eae06a26ed13fc9fd5db108a8d6db54
|
||||
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
|
||||
F test/all.test 2ecb8bbd52416642e41c9081182a8df05d42c75637afd4488aace78cc4b69e13
|
||||
F test/alter.test 16ed8d2470193f34bc711e51506ff1211ebfab8025ca3b9510ff2aef139874cb
|
||||
@@ -724,7 +727,7 @@ F test/capi3d.test aba917805573a03deed961a21f07a5a84505ad0a616f7e3fc1508844a15bc
|
||||
F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe
|
||||
F test/cast.test 3619f0c58c2e4b2a94aa86e75607e497d34ef40ab74418e71aef7b4ca5155895
|
||||
F test/cffault.test 9d6b20606afe712374952eec4f8fd74b1a8097ef
|
||||
F test/check.test e6527bed2b5557ffdbf5680765c4ae6fe61e9b68b7ee69a7f776787a4527b5da
|
||||
F test/check.test 4b57ecbbb300336382ca21ef983dfa70b291a70ae430690494d13f1629f45a38
|
||||
F test/checkfault.test da6cb3d50247169efcb20bdf57863a3ccfa1d27d9e55cd324f0680096970f014
|
||||
F test/chunksize.test 427d87791743486cbf0c3b8c625002f3255cb3a89c6eba655a98923b1387b760
|
||||
F test/close.test eccbad8ecd611d974cbf47278c3d4e5874faf02d811338d5d348af42d56d647c
|
||||
@@ -745,7 +748,7 @@ F test/colmeta.test 2c765ea61ee37bc43bbe6d6047f89004e6508eb1
|
||||
F test/colname.test 87ad5458bb8709312dac0d6755fd30e8e4ca83298d0a9ef6e5c24277a3c3390e
|
||||
F test/conflict.test c7cc007e2af151516ddf38f7412fe10d473a694f55e3df437e2c7b31c2590e8d
|
||||
F test/conflict2.test bb0b94cf7196c64a3cbd815c66d3ee98c2fecd9c
|
||||
F test/conflict3.test a83db76a6c3503b2fa057c7bfb08c318d8a422202d8bc5b86226e078e5b49ff9
|
||||
F test/conflict3.test 56d18aedfa521a7ebffadb8254cfff10caf4e49cd8659cb54da39513aed478ba
|
||||
F test/contrib01.test 2a1cbc0f2f48955d7d073f725765da6fbceda6b4
|
||||
F test/corrupt.test d7cb0300e4a297147b6a05e92a1684bc8973635c3bcaa3d66e983c9cbdbf47a3
|
||||
F test/corrupt2.test bb50042cf9a1f1023d73af325d47eb02a6bb11e3c52f8812644b220c5d4bca35
|
||||
@@ -767,8 +770,8 @@ F test/corruptH.test 79801d97ec5c2f9f3c87739aa1ec2eb786f96454
|
||||
F test/corruptI.test a17bbf54fdde78d43cf3cc34b0057719fd4a173a3d824285b67dc5257c064c7b
|
||||
F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4
|
||||
F test/corruptK.test 5b4212fe346699831c5ad559a62c54e11c0611bdde1ea8423a091f9c01aa32af
|
||||
F test/corruptL.test 865cb75ed971b72b5ee9ad9017befee6bd38794011cae69f00676d82c5a5dd69
|
||||
F test/corruptM.test 04a4061b1979283851953217e411187be79e50f5e5e3ef340c3f8e564173aae1
|
||||
F test/corruptL.test dfad96373bf9264d73039315ea6013994b90bf6776847adc7ec06b6fad3c04b2
|
||||
F test/corruptM.test 7d574320e08c1b36caa3e47262061f186367d593a7e305d35f15289cc2c3e067
|
||||
F test/cost.test 51f4fcaae6e78ad5a57096831259ed6c760e2ac6876836e91c00030fad385b34
|
||||
F test/count.test cb2e0f934c6eb33670044520748d2ecccd46259c
|
||||
F test/countofview.test e17d6e6688cf74f22783c9ec6e788c0790ee4fbbaee713affd00b1ac0bb39b86
|
||||
@@ -811,7 +814,7 @@ F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d
|
||||
F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2
|
||||
F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e
|
||||
F test/distinct.test a1783b960ad8c15a77cd9f207be072898db1026c
|
||||
F test/distinct2.test 1a01038083535fa9431f4a22587ae58d52d0a794910c36bd2bec07ba1e0e7367
|
||||
F test/distinct2.test b854b442111bf362328981f55d39d0df13140383b112057f6e046e311f14e5c3
|
||||
F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376
|
||||
F test/e_blobbytes.test 439a945953b35cb6948a552edaec4dc31fd70a05
|
||||
F test/e_blobclose.test 4b3c8c60c2171164d472059c73e9f3c1844bb66d
|
||||
@@ -857,7 +860,7 @@ F test/extraquick.test cb254400bd42bfb777ff675356aabf3287978f79
|
||||
F test/fallocate.test 37a62e396a68eeede8f8d2ecf23573a80faceb630788d314d0a073d862616717
|
||||
F test/filectrl.test 6e871c2d35dead1d9a88e176e8d2ca094fec6bb3
|
||||
F test/filefmt.test f393e80c4b8d493b7a7f8f3809a8425bbf4292af1f5140f01cb1427798a2bbd4
|
||||
F test/filter1.test 94a6d26588db0e4e7305e1f0985a99405e98dd034dc393dd6264603eed6645d4
|
||||
F test/filter1.test c2f34e58ee82a60c3ee9b5b4c4f2004ec2f529dff2f473706eeffa684cbb6719
|
||||
F test/filter2.tcl 44e525497ce07382915f01bd29ffd0fa49dab3adb87253b5e5103ba8f93393e8
|
||||
F test/filter2.test 485cf95d1f6d6ceee5632201ca52a71868599836f430cdee42e5f7f14666e30a
|
||||
F test/filterfault.test c08fb491d698e8df6c122c98f7db1c65ffcfcad2c1ab0e07fa8a5be1b34eaa8b
|
||||
@@ -935,7 +938,7 @@ F test/fts3conf.test c84bbaec81281c1788aa545ac6e78a6bd6cde2bdbbce2da261690e3659f
|
||||
F test/fts3corrupt.test 46b9ddda7f6588fd5a5b1f4bb4fc0618dc45010e7dddb8a3a188baf3197177ae
|
||||
F test/fts3corrupt2.test bf55c3fa0b0dc8ea1c0fe5543623bd27714585da6a129038fd6999fe3b0d25f3
|
||||
F test/fts3corrupt3.test 0d5b69a0998b4adf868cc301fc78f3d0707745f1d984ce044c205cdb764b491f
|
||||
F test/fts3corrupt4.test d5389e14950e57333bfc972f262c90b5ba0e864a958df9e437e3aacd3a5570a7
|
||||
F test/fts3corrupt4.test 545c50e70d1fe922b6efef12019a92829832f52993c5421086489ce72bde2251
|
||||
F test/fts3corrupt5.test 0549f85ec4bd22e992f645f13c59b99d652f2f5e643dac75568bfd23a6db7ed5
|
||||
F test/fts3cov.test cb932743da52a1c79a1ab8983e26c8121cf02263d6ff16e1f642e6f9b8348338
|
||||
F test/fts3d.test 2bd8c97bcb9975f2334147173b4872505b6a41359a4f9068960a36afe07a679f
|
||||
@@ -965,7 +968,7 @@ F test/fts3query.test ca033ff2ebcc22c69d89032fb0bc1850997d31e7e60ecd26440796ba16
|
||||
F test/fts3rank.test cd99bc83a3c923c8d52afd90d86979cf05fc41849f892faeac3988055ef37b99
|
||||
F test/fts3rnd.test 1320d8826a845e38a96e769562bf83d7a92a15d0
|
||||
F test/fts3shared.test 57e26a801f21027b7530da77db54286a6fe4997e
|
||||
F test/fts3snippet.test dace744104d1a44dc12dc9dd10b8d7542342df503d96942b7c4a55034e761789
|
||||
F test/fts3snippet.test 430bb5ace2b31ccd99de4d71775d956da832c114c4b3e39589748f114458647c
|
||||
F test/fts3sort.test ed34c716a11cc2009a35210e84ad5f9c102362ca
|
||||
F test/fts3tok1.test a663f4cac22a9505400bc22aacb818d7055240409c28729669ea7d4cc2120d15
|
||||
F test/fts3tok_err.test 52273cd193b9036282f7bacb43da78c6be87418d
|
||||
@@ -983,9 +986,11 @@ F test/fts4merge.test 1096e30b58ad616bd502141bfe5bfe4c3a518df89e958d41a5ed1ce322
|
||||
F test/fts4merge2.test 5faa558d1b672f82b847d2a337465fa745e46891
|
||||
F test/fts4merge3.test 8d9ccb4a3d41c4c617a149d6c4b13ad02de797d0
|
||||
F test/fts4merge4.test d895b1057a7798b67e03455d0fa50e9ea836c47b
|
||||
F test/fts4merge5.test 69932d85cda8a1c4dcfb742865900ed8fbda51724b8cf9a45bbe226dfd06c596
|
||||
F test/fts4noti.test 5553d7bb2e20bf4a06b23e849352efc022ce6309
|
||||
F test/fts4onepass.test d69ddc4ee3415e40b0c5d1d0408488a87614d4f63ba9c44f3e52db541d6b7cc7
|
||||
F test/fts4opt.test 0fd0cc84000743ff2a883b9b84b4a5be07249f0ba790c8848a757164cdd46b2a
|
||||
F test/fts4record.test a48508f69a84c9287c8019d3a1ae712f5730d8335ffaf8e2101e691d078950bb
|
||||
F test/fts4rename.test 15fd9985c2bce6dea20da2245b22029ec89bd4710ed317c4c53abbe3cfd0c880
|
||||
F test/fts4umlaut.test fcaca4471de7e78c9d1f7e8976e3e8704d7d8ad979d57a739d00f3f757380429
|
||||
F test/fts4unicode.test ceca76422abc251818cb25dabe33d3c3970da5f7c90e1540f190824e6b3a7c95
|
||||
@@ -1011,7 +1016,7 @@ F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e4
|
||||
F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5
|
||||
F test/fuzzdata6.db 92a80e4afc172c24f662a10a612d188fb272de4a9bd19e017927c95f737de6d7
|
||||
F test/fuzzdata7.db e7a86fd83dda151d160445d542e32e5c6019c541b3a74c2a525b6ac640639711
|
||||
F test/fuzzdata8.db dc52be9b732f5bc1cdc0db0ff5b8e69b87bc8989b13a94eb8acaef63897a007c
|
||||
F test/fuzzdata8.db c75b0fd1d28c262f9c3a9428393ff9c420ea5bdbe0b33c557a971915a94bab71
|
||||
F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8
|
||||
F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14
|
||||
F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536
|
||||
@@ -1025,11 +1030,11 @@ F test/hook2.test b9ff3b8c6519fb67f33192f1afe86e7782ee4ac8
|
||||
F test/icu.test 41aa8847745a879b897a7febea0f8f9efc8e67fe8bf680589b6e07c7b0a1569a
|
||||
F test/ieee754.test 806fc0ce7f305f57e3331eaceeddcfec9339e607
|
||||
F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8
|
||||
F test/in.test 63e642e97bc22c8fd970752fb4f0b3992a957003ea87524fe69e5a700500c500
|
||||
F test/in.test 3e9bd58597a444123a40a9ac94cae0fec8897e17e9f519b02fc370bcf5ba5175
|
||||
F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75
|
||||
F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0
|
||||
F test/in4.test d2b38cba404bc4320f4fe1b595b3d163f212c068
|
||||
F test/in5.test 7ae37fcd4a5e198291c6ab5f31a5bb3d15397efe8b75a6736d7a95a7b8dd9e08
|
||||
F test/in4.test 0f77b0ff371549e6a119d0356be10bdba72258162e9701e83527a560482f5e98
|
||||
F test/in5.test b32ce7f4a93f44c5dee94af16886d922cc16ebe33c8e1765c73d4049d0f4b40f
|
||||
F test/in6.test 62d943a02f722948f4410ee0b53c3cb39acd7c41afb083df8d7004238fe90a20
|
||||
F test/incrblob.test c9b96afc292aeff43d6687bcb09b0280aa599822
|
||||
F test/incrblob2.test a494c9e848560039a23974b9119cfc2cf3ad3bd15cc2694ee6367ae537ef8f1f
|
||||
@@ -1047,13 +1052,13 @@ F test/index2.test f835d5e13ca163bd78c4459ca15fd2e4ed487407
|
||||
F test/index3.test 51685f39345462b84fcf77eb8537af847fdf438cc96b05c45d6aaca4e473ade0
|
||||
F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6
|
||||
F test/index5.test 8621491915800ec274609e42e02a97d67e9b13e7
|
||||
F test/index6.test 7883c35749e3f38282572194ffdbe7d025b1e2938c1e67da2d408ff3c27d9a46
|
||||
F test/index6.test 4d1dd3cab97fba2ddf30bb70afc82eab35bd6e61788b3ac941e55263f81ef7e9
|
||||
F test/index7.test 1d764c0cca45f5a76150b08e127ccc8d52492cfa788b5fafed4be784a351b020
|
||||
F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7
|
||||
F test/index9.test 0aa3e509dddf81f93380396e40e9bb386904c1054924ba8fa9bcdfe85a8e7721
|
||||
F test/indexedby.test a52c8c6abfae4fbfb51d99440de4ca1840dbacc606b05e29328a2a8ba7cd914e
|
||||
F test/indexexpr1.test 0f293369ed6f56764cfc3db05685d45469d9e685ba87e3698527049ba359ae24
|
||||
F test/indexexpr2.test d319e7d1b1043403f39a20c892d512e02b5549c6004806b977030f2430c60208
|
||||
F test/indexexpr1.test c26c8b352311c1deb30642cd0379e5cb94e416c7e9e0885e92d9e01554df2db9
|
||||
F test/indexexpr2.test b580f378423bca443ffab47ada677203cfcf8a60f48a8aa20065f27c8f7739b5
|
||||
F test/indexfault.test 98d78a8ff1f5335628b62f886a1cb7c7dac1ef6d48fa39c51ec871c87dce9811
|
||||
F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
|
||||
F test/insert.test 72004f6a900a25bd3f1ce9a72e73d02749644666a8ce6d6d2dba061137e5aa63
|
||||
@@ -1062,9 +1067,9 @@ F test/insert3.test 1b7db95a03ad9c5013fdf7d6722b6cd66ee55e30
|
||||
F test/insert4.test 7802ada6ba8738661b9f6c0e26858d3375b40cc7180289fd350644cd7a08fec9
|
||||
F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6
|
||||
F test/insertfault.test ac63d14ea3b49c573673a572f4014b9117383a03e497c58f308b5c776e4a7f74
|
||||
F test/instr.test 9a8802f28437d8ade53fedfc47b2ca599b4e48ba
|
||||
F test/instr.test 107df2b9b74a4b59315916b575590a08f2a714de0754abe541f10a0971d0a2a4
|
||||
F test/instrfault.test 0f870b218ea17cd477bb19ed330eecdb460dd53a
|
||||
F test/intarray.test 8319986182af37c8eb4879c6bfe9cf0074e9d43b193a4c728a0efa3417c53fb7
|
||||
F test/intarray.test bb976b0b3df0ebb6a2eddfb61768280440e672beba5460ed49679ea984ccf440
|
||||
F test/interrupt.test 16ea879ec728cb76414c148c5f24afd5d1f91054
|
||||
F test/interrupt2.test e4408ca770a6feafbadb0801e54a0dcd1a8d108d
|
||||
F test/intpkey.test ac71107a49a06492b69b82aafaf225400598d3c8
|
||||
@@ -1077,7 +1082,7 @@ F test/ioerr4.test f130fe9e71008577b342b8874d52984bd04ede2c
|
||||
F test/ioerr5.test 2edfa4fb0f896f733071303b42224df8bedd9da4
|
||||
F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b
|
||||
F test/istrue.test 75327829744e65cc8700e69340b8e6c192e10e39dfae7ccb0e970d3c4f49090a
|
||||
F test/join.test d53a3662762eff50b65da8775201e609878a27dd0885a1ae7bcde9bb46cecbc5
|
||||
F test/join.test 6ce8296a08e78632c322cde0add78a7ce05466c3d9ec7d5130b38b5b489e7c27
|
||||
F test/join2.test 10f7047e723ebd68b2f47189be8eed20451a6f665d8bf46f1774c640d1062417
|
||||
F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0
|
||||
F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
|
||||
@@ -1100,7 +1105,7 @@ F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
|
||||
F test/lemon-test01.y 58b764610fd934e189ffbb0bbfa33d171b9cb06019b55bdc04d090d6767e11d7
|
||||
F test/like.test 3d702d79bf871fa32985b1ce334294c587e3948d3ab972001e811a58577e8b3c
|
||||
F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da
|
||||
F test/like3.test 62bf82ac674b7d4126e73532e1ad96cdcd8e1752a4ed90b28a6f98305f5a66aa
|
||||
F test/like3.test 4f940ad275c006319950054a7a65661f476772171b82b6fdf795e4dda36f246f
|
||||
F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e
|
||||
F test/limit2.test 9409b033284642a859fafc95f29a5a6a557bd57c1f0d7c3f554bd64ed69df77e
|
||||
F test/loadext.test faa4f6eed07a5aac35d57fdd7bc07f8fc82464cfd327567c10cf0ba3c86cde04
|
||||
@@ -1150,7 +1155,7 @@ F test/memsubsys2.test 3e4a8d0c05fd3e5fa92017c64666730a520c7e08
|
||||
F test/minmax.test 6751e87b409fe11b02e70a306d846fa544e25a41
|
||||
F test/minmax2.test dae92964ac87c1d2ef978c582e81a95e11c00f1cbef68980bfb2abaf10315063
|
||||
F test/minmax3.test cc1e8b010136db0d01a6f2a29ba5a9f321034354
|
||||
F test/minmax4.test 838fe32b812dc50778be3799767cefb5ff59bb04cff81d4f12c0708642f65151
|
||||
F test/minmax4.test 272ca395257f05937dc96441c9dde4bc9fbf116a8d4fa02baeb0d13d50e36c87
|
||||
F test/misc1.test 7ce84b25df9872e7d7878613a96815d2ba5bc974ac4e15a50118dde8f3917599
|
||||
F test/misc2.test 00d7de54eda90e237fc9a38b9e5ccc769ebf6d4d
|
||||
F test/misc3.test cf3dda47d5dda3e53fc5804a100d3c82be736c9d
|
||||
@@ -1182,6 +1187,7 @@ F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161
|
||||
F test/notify3.test 10ff25cde502e72a92053a2f215d64bece4ef934
|
||||
F test/notnull.test a37b663d5bb728d66fc182016613fb8e4a0a4bbf3d75b8876a7527f7d4ed3f18
|
||||
F test/null.test 0dcce4f04284ec66108c503327ad6d224c0752b3
|
||||
F test/nulls1.test 725fb4d99db2ddcce59ca6bf847cd92db8f1af861785918892f84ac3bcd4223d
|
||||
F test/numcast.test 5d126f7f581432e86a90d1e35cac625164aec4a1
|
||||
F test/numindex1.test 20a5450d4b056e48cd5db30e659f13347a099823
|
||||
F test/offset1.test f06b83657bcf26f9ce805e67450e189e282143b2
|
||||
@@ -1198,6 +1204,7 @@ F test/orderby6.test 8b38138ab0972588240b3fca0985d2e400432859
|
||||
F test/orderby7.test 3d1383d52ade5b9eb3a173b3147fdd296f0202da
|
||||
F test/orderby8.test 23ef1a5d72bd3adcc2f65561c654295d1b8047bd
|
||||
F test/orderby9.test 87fb9548debcc2cd141c5299002dd94672fa76a3
|
||||
F test/orderbyA.test df608e59efc2ef50c1eddf1a773b272de3252e9401bfec86d04b52fd973866d5
|
||||
F test/oserror.test 1fc9746b83d778e70d115049747ba19c7fba154afce7cc165b09feb6ca6abbc5
|
||||
F test/ossfuzz.c 18af635fa73d12a109b305faca727a734c1fa28a421b161d9d15c5a84a4998a2
|
||||
F test/ossshell.c f125c5bd16e537a2549aa579b328dd1c59905e7ab1338dfc210e755bb7b69f17
|
||||
@@ -1215,13 +1222,13 @@ F test/parser1.test 6ccdf5e459a5dc4673d3273dc311a7e9742ca952dd0551a6a6320d27035c
|
||||
F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
|
||||
F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
|
||||
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
|
||||
F test/permutations.test 4282fb00e5ac0f8c2cd1be62652f6da4ac03ce3c58b7d785fa17f4684492a0e0
|
||||
F test/pg_common.tcl 4740dc35190d6acdab14c097783331361301ab504a94d948f6afbb56ce0a51e8
|
||||
F test/pragma.test cf066fe0f7f5d49f4758de4986407b8676c61aaa7871599340d64f42a8edc352
|
||||
F test/permutations.test 8587800fe1a0eb01456a3f4500b821e54e3347e78acf11dbf05f4990530f6cee
|
||||
F test/pg_common.tcl 222a1bad1c41c308fa366313cd7b51b3be7e9b21c8736a421b974ac941693b54
|
||||
F test/pragma.test 59becdfd720b80d463ab750f69f7118fde10dfd556aa5d554f3bf6b7e5ea7533
|
||||
F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f
|
||||
F test/pragma3.test 8300aa9c63cff1027006ca34bf413a148abbd6dcd471fa9a1ded322fe18c0df9
|
||||
F test/pragma4.test 1cb4b32f1a304ed9e291d7c4d49c91c2c8dc1b9450e6d2c1198b2cc895d40d77
|
||||
F test/pragma5.test 824ce6ced5d6b7ec71abe37fc6005ff836fe39d638273dc5192b39864b9ee983
|
||||
F test/pragma5.test 2be6a44c91e8585ccb4c71c5f221ccebe0692a49557215a912916ed391188959
|
||||
F test/pragmafault.test 275edaf3161771d37de60e5c2b412627ac94cef11739236bec12ed1258b240f8
|
||||
F test/prefixes.test b524a1c44bffec225b9aec98bd728480352aa8532ac4c15771fb85e8beef65d9
|
||||
F test/printf.test 0300699733e53101b2ce48800518427249edd4053bb50fa0621c6607482f0fdb
|
||||
@@ -1243,8 +1250,8 @@ F test/recover.test ccb8c2623902a92ebb76770edd075cb4f75a4760bb7afde38026572c6e79
|
||||
F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8
|
||||
F test/regexp2.test 40e894223b3d6672655481493f1be12012f2b33c
|
||||
F test/reindex.test cd9d6021729910ece82267b4f5e1b5ac2911a7566c43b43c176a6a4732e2118d
|
||||
F test/releasetest.tcl 968fc1e8fd23e113fb8a04379747f3a9f2c12d207b2de85aeff5a825962e1cd7 x
|
||||
F test/releasetest_data.tcl 4f55292d7e3e7995754373612a16b71f41be22dfded3a0375ccaf65c465d3765
|
||||
F test/releasetest.tcl fb76d8fcc95ac29d6356cd9e52b726ab9e43a24082897618dfbcb7c2b0049153 x
|
||||
F test/releasetest_data.tcl 9919fc6ac5bc92f8878fecfd1840db15999f660a6c9f609240b41aa62b885c88
|
||||
F test/resetdb.test 8062cf10a09d8c048f8de7711e94571c38b38168db0e5877ba7561789e5eeb2b
|
||||
F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb
|
||||
F test/rollback.test 06680159bc6746d0f26276e339e3ae2f951c64812468308838e0a3362d911eaa
|
||||
@@ -1260,7 +1267,7 @@ F test/rowvalue3.test 3068f508753af69884b12125995f023da0dbb256
|
||||
F test/rowvalue4.test 02e35f7762371c2f57ebd856aa056eac56cb27ef7715a0bb31eac1895a745356
|
||||
F test/rowvalue5.test c81c7d8cf36711ab37675ad7376084ae2a359cb6
|
||||
F test/rowvalue6.test d19b54feb604d5601f8614b15e214e0774c01087
|
||||
F test/rowvalue7.test 5d06ff19d9e6969e574a2e662a531dd0c67801a8
|
||||
F test/rowvalue7.test c1cbdbf407029db01f87764097c6ac02a1c5a37efd2776eff32a9cdfdf6f2dba
|
||||
F test/rowvalue8.test 5900eddad9e2c3c2e26f1a95f74aafc1232ee5e0
|
||||
F test/rowvalue9.test d8dd2c6ecac432dadaa79e41dc2434f007be1b6b
|
||||
F test/rowvaluefault.test 7cd9ccc6c2fbdd881672984087aad0491bb75504
|
||||
@@ -1388,7 +1395,7 @@ F test/tabfunc01.test 20e98ffe55f35d8d33fd834ca8bf9d4b637e560af8fcd00464b4154d90
|
||||
F test/table.test eb3463b7add9f16a5bb836badf118cf391b809d09fdccd1f79684600d07ec132
|
||||
F test/tableapi.test ecbcc29c4ab62c1912c3717c48ea5c5e59f7d64e4a91034e6148bd2b82f177f4
|
||||
F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
|
||||
F test/tclsqlite.test 6c7368554f15ea6df3852173c0f1d6353f824afb1896f6fc17fb21b057c0685a
|
||||
F test/tclsqlite.test f9acb83122be0a7c4997ab7f17742507874dced95144c20217c2428553f110bb
|
||||
F test/tempdb.test 4cdaa23ddd8acb4d79cbb1b68ccdfd09b0537aaba909ca69a876157c2a2cbd08
|
||||
F test/tempdb2.test 353864e96fd3ae2f70773d0ffbf8b1fe48589b02c2ec05013b540879410c3440
|
||||
F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900
|
||||
@@ -1411,6 +1418,7 @@ F test/threadtest3.c 38a612ea62854349ed66372f330a40d73c5cf956
|
||||
F test/threadtest4.c c1e67136ceb6c7ec8184e56ac61db28f96bd2925
|
||||
F test/time-wordcount.sh 8e0b0f8109367827ad5d58f5cc849705731e4b90
|
||||
F test/tkt-02a8e81d44.test 6c80d9c7514e2a42d4918bf87bf6bc54f379110c
|
||||
F test/tkt-18458b1a.test c543c4b8e8c7c2200579a635e72c15bc374a92d44eddb1d588d4fdeca9cca532
|
||||
F test/tkt-26ff0c2d1e.test c15bec890c4d226c0da2f35ff30f9e84c169cfef90e73a8cb5cec11d723dfa96
|
||||
F test/tkt-2a5629202f.test 0521bd25658428baa26665aa53ffed9367d33af2
|
||||
F test/tkt-2d1a5c67d.test be1326f3061caec85085f4c9ee4490561ca037c0
|
||||
@@ -1420,7 +1428,7 @@ F test/tkt-313723c356.test 4b306ad45c736cedf2f5221f6155b92143244b6d
|
||||
F test/tkt-385a5b56b9.test 5204a7cba0e28c99df0acbf95af5e1af4d32965a7a14de6eccebf949607618b1
|
||||
F test/tkt-38cb5df375.test f3cc8671f1eb604d4ae9cf886ed4366bec656678
|
||||
F test/tkt-3998683a16.test 6d1d04d551ed1704eb3396ca87bb9ccc8c5c1eb7
|
||||
F test/tkt-3a77c9714e.test b08bca26de1140bdf004a37716582a43d7bd8be8
|
||||
F test/tkt-3a77c9714e.test 90e3e8455ee945a4076d4c44062b8845708af24a880355328fe7008f2047c9f0
|
||||
F test/tkt-3fe897352e.test 27e26eb0f1811aeba4d65aba43a4c52e99da5e70
|
||||
F test/tkt-4a03edc4c8.test 91c0e135888cdc3d4eea82406a44b05c8c1648d0
|
||||
F test/tkt-4c86b126f2.test cbcc611becd0396890169ab23102dd70048bbc9a
|
||||
@@ -1446,11 +1454,12 @@ F test/tkt-9a8b09f8e6.test b2ef151d0984b2ebf237760dbeaa50724e5a0667
|
||||
F test/tkt-9d68c883.test 16f7cb96781ba579bc2e19bb14b4ad609d9774b6
|
||||
F test/tkt-9f2eb3abac.test cb6123ac695a08b4454c3792fbe85108f67fabf8
|
||||
F test/tkt-a7b7803e.test 159ef554234fa1f9fb318c751b284bd1cf858da4
|
||||
F test/tkt-a7debbe0.test 65a647034e3416d068f81e7d86fffc07edfae371c70b8761714edb56ec1c7521
|
||||
F test/tkt-a8a0d2996a.test 002e1cde8fc30c39611b52cf981c88200b858765748556822da72e0d32fac73e
|
||||
F test/tkt-b1d3a2e531.test 8f7576e41ca179289ee1a8fee28386fd8e4b0550
|
||||
F test/tkt-b351d95f9.test d14a503c414c5c58fdde3e80f9a3cfef986498c0
|
||||
F test/tkt-b72787b1.test a95e8cdad0b98af1853ac7f0afd4ab27b77bf5f3
|
||||
F test/tkt-b75a9ca6b0.test 1bc0381538fd21f96a10dbabc10ffc51b5b2e5f412d34bae571273ca784003d7
|
||||
F test/tkt-b75a9ca6b0.test ade89229d853a67a21bbd5e6e1e787a8f9d21f19908d1b7fca6bf3d4d5aa0767
|
||||
F test/tkt-ba7cbfaedc.test b4c0deccc12aeb55cfdb57935b16b5d67c5a9877
|
||||
F test/tkt-bd484a090c.test 60460bf946f79a79712b71f202eda501ca99b898
|
||||
F test/tkt-bdc6bbbb38.test fc38bb09bdd440e3513a1f5f98fc60a075182d7d
|
||||
@@ -1560,7 +1569,7 @@ F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6
|
||||
F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76
|
||||
F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94
|
||||
F test/transitive1.test 293300f46916569f08875cdb2fe2134be2c27677
|
||||
F test/trigger1.test 17e4b43e656c4b354df2357634a6ba887990f510c43629f4feca30e3338d2a61
|
||||
F test/trigger1.test 6be279c9d48b25320eab68c30fd5268ab787955679f4c584128f71800247fb50
|
||||
F test/trigger2.test 5cd7d69a7ba1143ee045e4ae2963ff32ae4c87a6
|
||||
F test/trigger3.test aa640bb2bbb03edd5ff69c055117ea088f121945
|
||||
F test/trigger4.test 74700b76ebf3947b2f7a92405141eb2cf2a5d359
|
||||
@@ -1592,7 +1601,7 @@ F test/unixexcl.test d936ba2b06794018e136418addd59a2354eeae97
|
||||
F test/unordered.test ffeea7747d5ba962a8009a20b7e53d68cbae05b063604c68702c5998eb50c981
|
||||
F test/update.test 1148de8d913e9817717990603aadeca07aab9ddbb10a30f167cbfd8d3a3ccb60
|
||||
F test/update2.test 67455bc61fcbcf96923c45b3bc4f87bc72be7d67575ad35f134906148c7b06d3
|
||||
F test/upsert1.test 994bde41800bb77dbe32fcd2e1f6c4b49cc9f2c6cd345731c774dff02b51c110
|
||||
F test/upsert1.test 9b115320149e6d72db64511a373c522746c2a2156efdbdb52add33504f66c989
|
||||
F test/upsert2.test 9c3cdbb1a890227f6504ce4b0e3de68f4cdfa16bb21d8641208a9239896c5a09
|
||||
F test/upsert3.test 88d7d590a1948a9cb6eac1b54b0642f67a9f35a1fc0f19b200e97d5d39e3179c
|
||||
F test/upsert4.test 25d2a1da92f149331ae0c51ca6e3eee78189577585eab92de149900d62994fa5
|
||||
@@ -1610,8 +1619,8 @@ F test/vacuum5.test 263b144d537e92ad8e9ca8a73cc6e1583f41cfd0dda9432b87f7806174a2
|
||||
F test/vacuummem.test 7b42abb3208bd82dd23a7536588396f295a314f2
|
||||
F test/varint.test bbce22cda8fc4d135bcc2b589574be8410614e62
|
||||
F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
|
||||
F test/view.test c1e64ff5a860fdbb7b52add0996af2ee1af563ddf2e86b964d15d04d81a001be
|
||||
F test/vtab1.test efb4c4a45146193d6d55fb85f7162febd6423f29c72ede09bb96383f49e3abc1
|
||||
F test/view.test 10ea54300a097d7c0337fd104abffe4a4786d1598b94017a37efe0e0d3e04dd5
|
||||
F test/vtab1.test c5d9e90ed02bcacd776dcbb7360199d290f7f53c26b484ddece543060c54319f
|
||||
F test/vtab2.test 14d4ab26cee13ba6cf5c5601b158e4f57552d3b055cdd9406cf7f711e9c84082
|
||||
F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e
|
||||
F test/vtab4.test 8e73ed268f3d596bc3590f45fc948fb40f28e9c3
|
||||
@@ -1669,8 +1678,8 @@ F test/walslow.test c05c68d4dc2700a982f89133ce103a1a84cc285f
|
||||
F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2af51747
|
||||
F test/walvfs.test f1accd66c876e3a0f6b4bef5b18d13411062d0ff0a0016e32bb41570474e99fc
|
||||
F test/wapp.tcl b440cd8cf57953d3a49e7ee81e6a18f18efdaf113b69f7d8482b0710a64566ec
|
||||
F test/wapptest.tcl 3090239c59379d41e1a0644feb6683082fdb86edfab0c668973f8003f22c0e5d x
|
||||
F test/where.test d640c16d33ae671c7583fd575d1a64fd55194dcc4393b877b3028db9ddba5a3b
|
||||
F test/wapptest.tcl 3cca775aede0591756a1fc0da55bbb3715d8c363873fd2cfdd4d555b0a4af57d x
|
||||
F test/where.test 19c709c9f0f6ed12c23f909f6592aa55fba34269d5a2898537aa27a22b9ce650
|
||||
F test/where2.test 478d2170637b9211f593120648858593bf2445a1
|
||||
F test/where3.test 2341a294e17193a6b1699ea7f192124a5286ca6acfcc3f4b06d16c931fbcda2c
|
||||
F test/where4.test 4a371bfcc607f41d233701bdec33ac2972908ba8
|
||||
@@ -1685,7 +1694,7 @@ F test/whereC.test cae295158703cb3fc23bf1a108a9ab730efff0f6
|
||||
F test/whereD.test 711d4df58d6d4fb9b3f5ce040b818564198be002
|
||||
F test/whereE.test b3a055eef928c992b0a33198a7b8dc10eea5ad2f
|
||||
F test/whereF.test 3d9412b1199d3e2bed34fcb76b4c48d0bf4df95d27e3f8dd27b6f8b4716d0d89
|
||||
F test/whereG.test 0158783235a6dd82fc0e37652b8522b186b9510594ac0a4bff0c4101b4396a52
|
||||
F test/whereG.test 4cda56de49f0c7d9a4f2590a3ddc5f79a7f2a03d2229d0f5bb5d3981ce57f293
|
||||
F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2
|
||||
F test/whereI.test a2874062140ed4aba9ffae76e6190a3df6fc73d1373fdfa8fd632945082a5364
|
||||
F test/whereJ.test 88287550f6ee604422403b053455b1ad894eeaa5c35d348532dfa1439286cb9a
|
||||
@@ -1700,8 +1709,8 @@ F test/win32lock.test fbf107c91d8f5512be5a5b87c4c42ab9fdd54972
|
||||
F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d
|
||||
F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc
|
||||
F test/window1.test 376a7c9c5b9df9868d92a6d9d455262e1b769f4410b19006f5f8c5507c2a7ed7
|
||||
F test/window2.tcl a44834af6267be6e14882311ef8790bf5047f1b9bc25685ee1762d48dc24f1e7
|
||||
F test/window2.test 2f3ae63e171dce7f2ac29a41020f4da413b1d7bdaba48ee124fd336b152e34c5
|
||||
F test/window2.tcl 66db96fd9fd202bc31ee7f8ce7904cb469564864cff3f74e009bfef8102333f4
|
||||
F test/window2.test af2a001ded703bb8f2474fb0edfef170d5aba00f5c1f2aa9f65935b5da13df90
|
||||
F test/window3.tcl acea6e86a4324a210fd608d06741010ca83ded9fde438341cb978c49928faf03
|
||||
F test/window3.test e9959a993c8a71e96433be8daaa1827d78b8921e4f12debd7bdbeb3c856ef3cb
|
||||
F test/window4.tcl d732df0e81beedc0ba8a563ade68611d322d27303ad0c0c8e4444107c39e84ec
|
||||
@@ -1709,25 +1718,27 @@ F test/window4.test 807f3e6b15f9338e5b9742b87c5c7ca825b42b9657fde6096e8901193708
|
||||
F test/window5.test d328dd18221217c49c144181975eea17339eaeaf0e9aa558cee3afb84652821e
|
||||
F test/window6.test f8d674254b23289cc17c84d79dec7eda7caa1dfb7836c43122cfdf3640d1df32
|
||||
F test/window7.tcl 6a1210f05d40ec89c22960213a22cd3f98d4e2f2eb20646c83c8c30d4d76108f
|
||||
F test/window7.test ce7f865241fdd1c5c4db869cd7bb2986c3be836bc2e73649a6846dd920f63e0f
|
||||
F test/window8.tcl 9e9a82ae9eea90a4a83481d641a812b974980c38f9247f3b89a6e3c8bed45518
|
||||
F test/window8.test df187dc19921f7be0ab709d531d681bd80ccaac96a913a89ecee8b272b91d43f
|
||||
F test/window9.test 20a6b590be718b6bc98a5356d4396d6cdf19329c547da084fa225b92d68e1693
|
||||
F test/window7.test 1d31276961ae7801edc72173edaf7593e3cbc79c06d1f1f09e20d8418af403cd
|
||||
F test/window8.tcl f2711aa3571e4e6b0dad98db8d95fd6cb8d9db0c92bbdf535f153b07606a1ce2
|
||||
F test/window8.test c4331b27a6f66d69fa8f8bab10cc731db1a81d293ae108a68f7c3487fa94e65b
|
||||
F test/window9.test ae8be07be05a5a4c8ead1818ac5d45f278b8dd456e589d67f24270b0070c35a0
|
||||
F test/windowA.test 6d63dc1260daa17141a55007600581778523a8b420629f1282d2acfc36af23be
|
||||
F test/windowB.test 7a983ea1cc1cf72be7f378e4b32f6cb2d73014c5cd8b25aaee825164cd4269e5
|
||||
F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387019e0
|
||||
F test/windowerr.test a8b752402109c15aa1c5efe1b93ccb0ce1ef84fa964ae1cd6684dd0b3cc1819b
|
||||
F test/windowfault.test 403693d7d951c5473f052f7ecddb61ed15ac9d212f238b8904ea270ba90f83e5
|
||||
F test/windowfault.test a90b397837209f15e54afa62e8be39b2759a0101fae04e05a08bcc50e243a452
|
||||
F test/with1.test d32792084dcb5f6c047d77bb8a032822ef9fe050ade07d0aeffa37753a05e3c9
|
||||
F test/with2.test e0030e2f0267a910d6c0e4f46f2dfe941c1cc0d4f659ba69b3597728e7e8f1ab
|
||||
F test/with3.test b5f1372097690c6ef84db2f13fc7e64a88c7263c3f88493605f90597e8a68d45
|
||||
F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f198205
|
||||
F test/withM.test 693b61765f2b387b5e3e24a4536e2e82de15ff64
|
||||
F test/without_rowid1.test f40c2757272ce171b88e4227f14450db2c4d42800d447baa7656a65562d2f8d9
|
||||
F test/without_rowid1.test 0abe18762b74714580c1d4d00a8e540e58966d3e46aae41ddb1a1d2c88c9277d
|
||||
F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99
|
||||
F test/without_rowid3.test ea4b59dd1b0d7f5f5e4b7cca978cdb905752a9d7c57dc4344a591dba765a3691
|
||||
F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a
|
||||
F test/without_rowid5.test 89b1c587bd92a0590e440da33e7666bf4891572a
|
||||
F test/without_rowid6.test 3c1bbf0eb81c672115933158b62b009e67cf1a7f8c2c612bbce63a7385efa18e
|
||||
F test/without_rowid7.test 0e0d7be00f05f54898e20e07bcc947cd97b42d7106021fa0d2897324bc6d330e
|
||||
F test/without_rowid6.test 8463b20098e9f75a501a9f17dfb42fffc79068eac0b2775fe56ef2281d2df45e
|
||||
F test/without_rowid7.test d7c59a93d726b55812d620f8f284e01904a5b85f9ee9eea8f2f68571a5e8c40e
|
||||
F test/wordcount.c d721a4b6fae93e6e33449700bce1686bc23257c27425bc3ef1599dc912adec66
|
||||
F test/writecrash.test f1da7f7adfe8d7f09ea79b42e5ca6dcc41102f27f8e334ad71539501ddd910cc
|
||||
F test/zeroblob.test 07a5b11ab591d1f26c626945fb7f228f68b993533b2ada77273edf6ee29db174
|
||||
@@ -1755,8 +1766,8 @@ F tool/genfkey.test b6afd7b825d797a1e1274f519ab5695373552ecad5cd373530c63533638a
|
||||
F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
|
||||
F tool/index_usage.c 9ec344d29cbeb03fdc0fce668eedfb7495792170de933adf95cf8d6904a166ad
|
||||
F tool/kvtest-speed.sh 4761a9c4b3530907562314d7757995787f7aef8f
|
||||
F tool/lemon.c cc43148d2793ab93668e74a6a6319bb71c2e65c1ffcd6deeaa59e12be9362a43
|
||||
F tool/lempar.c 4b868d0a5eb9a67cd1b546274227c0d449dad073c663b331b686fa2253e1c86f
|
||||
F tool/lemon.c 61d5f0af1eff8f754b75ddca668c9897fd30759e389bfffb42ce9e4d38fd4746
|
||||
F tool/lempar.c eb2841e2a7fd484cf44b1f526b06e7ab0f216d2f41818bf9485e8f38e3d1db19
|
||||
F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9
|
||||
F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862
|
||||
F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca
|
||||
@@ -1764,12 +1775,12 @@ F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439
|
||||
F tool/mkautoconfamal.sh 422fc365358a2e92876ffc62971a0ff28ed472fc8bcf9de0df921c736fdeca5e
|
||||
F tool/mkccode.tcl 86463e68ce9c15d3041610fedd285ce32a5cf7a58fc88b3202b8b76837650dbe x
|
||||
F tool/mkctimec.tcl dd183b73ae1c28249669741c250525f0407e579a70482371668fd5f130d9feb3
|
||||
F tool/mkkeywordhash.c 537b1a11ec1829b51b633da3ba2cc889b4a3f7356b06a07423b6d4cce92c2350
|
||||
F tool/mkkeywordhash.c bc5bcc92ebcaf15345346be7cf2204b83ed649b5208234adb5e543c061209bbf
|
||||
F tool/mkmsvcmin.tcl cad0c7b54d7dd92bc87d59f36d4cc4f070eb2e625f14159dc2f5c4204e6a13ea
|
||||
F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c
|
||||
F tool/mkopcodeh.tcl 352a4319c0ad869eb26442bf7c3b015aa15594c21f1cce5a6420dbe999367c21
|
||||
F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa
|
||||
F tool/mkpragmatab.tcl 8250ef3df54aee09f6c6ed36cad390bb6dd20bbe71927d8bff069ed9fe0bbf98
|
||||
F tool/mkpragmatab.tcl f115d63ada8171f9da28dc8e34e043a1a159692d46b89f66b6e681140bc4683d
|
||||
F tool/mkshellc.tcl 70a9978e363b0f3280ca9ce1c46d72563ff479c1930a12a7375e3881b7325712
|
||||
F tool/mksourceid.c d458f9004c837bee87a6382228ac20d3eae3c49ea3b0a5aace936f8b60748d3b
|
||||
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
|
||||
@@ -1794,7 +1805,7 @@ F tool/showstat4.c 0682ebea7abf4d3657f53c4a243f2e7eab48eab344ed36a94bb75dcd19a5c
|
||||
F tool/showwal.c ad9d768f96ca6199ad3a8c9562d679680bd032dd01204ea3e5ea6fb931d81847
|
||||
F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe
|
||||
F tool/spaceanal.tcl 4bfd19aad7eb3ce0372ef0255f58035e0bba4ff5e9acfd763a10c6fb365c8dec
|
||||
F tool/speed-check.sh 27c7fe178d5b2f7c90a04a127907acda0bfe637fa85b13c43e03e5ed39b008b6
|
||||
F tool/speed-check.sh 2b042d703a9472f08c3b13be27afac658426f8e4fc87cd2d575953fda86f08d1
|
||||
F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355
|
||||
F tool/speedtest16.c ecb6542862151c3e6509bbc00509b234562ae81e
|
||||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||
@@ -1836,10 +1847,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 98357d8c1263920b33a3648ef9214a63c99728bafa7a8d3dd6a1241b2303fd42
|
||||
R ad310bbebd66791c892628fc8eec172c
|
||||
T *branch * directonly
|
||||
T *sym-directonly *
|
||||
T -sym-trunk *
|
||||
U drh
|
||||
Z 950f463a47bf34120eda446765855ee2
|
||||
P 4b73e151cdb4b89bdd2f1bab5c0378500234ce6c479cc1d8cd4e006be79d1162
|
||||
Q +087b8b41c6ed76b55c11315e7e95679d67590be20ae21108b593d00bb7d1c57a
|
||||
R f1bc15780a98eb9fb1abdadc164e3b34
|
||||
U dan
|
||||
Z 02ec0c40b41079c9dff32d6e22ece993
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
fc745845d8d76adc165575e2192f4176e3c28e614c72571d56f4011560499fe1
|
||||
56869f54f31186231a4467f10208bcc08d9edae23c6e21831d6d3dff47da51de
|
||||
@@ -299,6 +299,7 @@ static void detachFunc(
|
||||
sqlite3 *db = sqlite3_context_db_handle(context);
|
||||
int i;
|
||||
Db *pDb = 0;
|
||||
HashElem *pEntry;
|
||||
char zErr[128];
|
||||
|
||||
UNUSED_PARAMETER(NotUsed);
|
||||
@@ -323,6 +324,18 @@ static void detachFunc(
|
||||
goto detach_error;
|
||||
}
|
||||
|
||||
/* If any TEMP triggers reference the schema being detached, move those
|
||||
** triggers to reference the TEMP schema itself. */
|
||||
assert( db->aDb[1].pSchema );
|
||||
pEntry = sqliteHashFirst(&db->aDb[1].pSchema->trigHash);
|
||||
while( pEntry ){
|
||||
Trigger *pTrig = (Trigger*)sqliteHashData(pEntry);
|
||||
if( pTrig->pTabSchema==pDb->pSchema ){
|
||||
pTrig->pTabSchema = pTrig->pSchema;
|
||||
}
|
||||
pEntry = sqliteHashNext(pEntry);
|
||||
}
|
||||
|
||||
sqlite3BtreeClose(pDb->pBt);
|
||||
pDb->pBt = 0;
|
||||
pDb->pSchema = 0;
|
||||
|
||||
+3
-1
@@ -6992,7 +6992,8 @@ static int pageInsertArray(
|
||||
while( 1 /*Exit by break*/ ){
|
||||
int sz, rc;
|
||||
u8 *pSlot;
|
||||
sz = cachedCellSize(pCArray, i);
|
||||
assert( pCArray->szCell[i]!=0 );
|
||||
sz = pCArray->szCell[i];
|
||||
if( (aData[1]==0 && aData[2]==0) || (pSlot = pageFindSlot(pPg,sz,&rc))==0 ){
|
||||
if( (pData - pBegin)<sz ) return 1;
|
||||
pData -= sz;
|
||||
@@ -7153,6 +7154,7 @@ static int editPage(
|
||||
memmove(&pCellptr[2], pCellptr, (nCell - iCell) * 2);
|
||||
}
|
||||
nCell++;
|
||||
cachedCellSize(pCArray, iCell+iNew);
|
||||
if( pageInsertArray(
|
||||
pPg, pBegin, &pData, pCellptr,
|
||||
iCell+iNew, 1, pCArray
|
||||
|
||||
+32
-6
@@ -1443,7 +1443,7 @@ void sqlite3AddPrimaryKey(
|
||||
pTab->keyConf = (u8)onError;
|
||||
assert( autoInc==0 || autoInc==1 );
|
||||
pTab->tabFlags |= autoInc*TF_Autoincrement;
|
||||
if( pList ) pParse->iPkSortOrder = pList->a[0].sortOrder;
|
||||
if( pList ) pParse->iPkSortOrder = pList->a[0].sortFlags;
|
||||
}else if( autoInc ){
|
||||
#ifndef SQLITE_OMIT_AUTOINCREMENT
|
||||
sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
|
||||
@@ -1894,7 +1894,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
|
||||
if( IN_RENAME_OBJECT ){
|
||||
sqlite3RenameTokenRemap(pParse, pList->a[0].pExpr, &pTab->iPKey);
|
||||
}
|
||||
pList->a[0].sortOrder = pParse->iPkSortOrder;
|
||||
pList->a[0].sortFlags = pParse->iPkSortOrder;
|
||||
assert( pParse->pNewTable==pTab );
|
||||
pTab->iPKey = -1;
|
||||
sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0,
|
||||
@@ -2816,7 +2816,8 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
|
||||
}
|
||||
#endif
|
||||
if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0
|
||||
&& sqlite3StrNICmp(pTab->zName, "sqlite_stat", 11)!=0 ){
|
||||
&& sqlite3StrNICmp(pTab->zName+7, "stat", 4)!=0
|
||||
&& sqlite3StrNICmp(pTab->zName+7, "parameters", 10)!=0 ){
|
||||
sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName);
|
||||
goto exit_drop_table;
|
||||
}
|
||||
@@ -3153,6 +3154,27 @@ Index *sqlite3AllocateIndexObject(
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
** If expression list pList contains an expression that was parsed with
|
||||
** an explicit "NULLS FIRST" or "NULLS LAST" clause, leave an error in
|
||||
** pParse and return non-zero. Otherwise, return zero.
|
||||
*/
|
||||
int sqlite3HasExplicitNulls(Parse *pParse, ExprList *pList){
|
||||
if( pList ){
|
||||
int i;
|
||||
for(i=0; i<pList->nExpr; i++){
|
||||
if( pList->a[i].bNulls ){
|
||||
u8 sf = pList->a[i].sortFlags;
|
||||
sqlite3ErrorMsg(pParse, "unsupported use of NULLS %s",
|
||||
(sf==0 || sf==3) ? "FIRST" : "LAST"
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Create a new index for an SQL table. pName1.pName2 is the name of the index
|
||||
** and pTblList is the name of the table that is to be indexed. Both will
|
||||
@@ -3204,6 +3226,9 @@ void sqlite3CreateIndex(
|
||||
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
|
||||
goto exit_create_index;
|
||||
}
|
||||
if( sqlite3HasExplicitNulls(pParse, pList) ){
|
||||
goto exit_create_index;
|
||||
}
|
||||
|
||||
/*
|
||||
** Find the table that is to be indexed. Return early if not found.
|
||||
@@ -3368,7 +3393,7 @@ void sqlite3CreateIndex(
|
||||
sqlite3ExprAlloc(db, TK_ID, &prevCol, 0));
|
||||
if( pList==0 ) goto exit_create_index;
|
||||
assert( pList->nExpr==1 );
|
||||
sqlite3ExprListSetSortOrder(pList, sortOrder);
|
||||
sqlite3ExprListSetSortOrder(pList, sortOrder, SQLITE_SO_UNDEFINED);
|
||||
}else{
|
||||
sqlite3ExprListCheckLength(pParse, pList, "index");
|
||||
if( pParse->nErr ) goto exit_create_index;
|
||||
@@ -3486,7 +3511,7 @@ void sqlite3CreateIndex(
|
||||
goto exit_create_index;
|
||||
}
|
||||
pIndex->azColl[i] = zColl;
|
||||
requestedSortOrder = pListItem->sortOrder & sortOrderMask;
|
||||
requestedSortOrder = pListItem->sortFlags & sortOrderMask;
|
||||
pIndex->aSortOrder[i] = (u8)requestedSortOrder;
|
||||
}
|
||||
|
||||
@@ -4704,7 +4729,8 @@ KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){
|
||||
const char *zColl = pIdx->azColl[i];
|
||||
pKey->aColl[i] = zColl==sqlite3StrBINARY ? 0 :
|
||||
sqlite3LocateCollSeq(pParse, zColl);
|
||||
pKey->aSortOrder[i] = pIdx->aSortOrder[i];
|
||||
pKey->aSortFlags[i] = pIdx->aSortOrder[i];
|
||||
assert( 0==(pKey->aSortFlags[i] & KEYINFO_ORDER_BIGNULL) );
|
||||
}
|
||||
if( pParse->nErr ){
|
||||
assert( pParse->rc==SQLITE_ERROR_MISSING_COLLSEQ );
|
||||
|
||||
+163
-55
@@ -44,7 +44,6 @@ char sqlite3TableColumnAffinity(Table *pTab, int iCol){
|
||||
*/
|
||||
char sqlite3ExprAffinity(Expr *pExpr){
|
||||
int op;
|
||||
if( pExpr->flags & EP_Generic ) return 0;
|
||||
while( ExprHasProperty(pExpr, EP_Skip) ){
|
||||
assert( pExpr->op==TK_COLLATE );
|
||||
pExpr = pExpr->pLeft;
|
||||
@@ -106,10 +105,22 @@ Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){
|
||||
}
|
||||
|
||||
/*
|
||||
** Skip over any TK_COLLATE operators and any unlikely()
|
||||
** or likelihood() function at the root of an expression.
|
||||
** Skip over any TK_COLLATE operators.
|
||||
*/
|
||||
Expr *sqlite3ExprSkipCollate(Expr *pExpr){
|
||||
while( pExpr && ExprHasProperty(pExpr, EP_Skip) ){
|
||||
assert( pExpr->op==TK_COLLATE );
|
||||
pExpr = pExpr->pLeft;
|
||||
}
|
||||
return pExpr;
|
||||
}
|
||||
|
||||
/*
|
||||
** Skip over any TK_COLLATE operators and/or any unlikely()
|
||||
** or likelihood() or likely() functions at the root of an
|
||||
** expression.
|
||||
*/
|
||||
Expr *sqlite3ExprSkipCollateAndLikely(Expr *pExpr){
|
||||
while( pExpr && ExprHasProperty(pExpr, EP_Skip|EP_Unlikely) ){
|
||||
if( ExprHasProperty(pExpr, EP_Unlikely) ){
|
||||
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
|
||||
@@ -144,7 +155,6 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
|
||||
Expr *p = pExpr;
|
||||
while( p ){
|
||||
int op = p->op;
|
||||
if( p->flags & EP_Generic ) break;
|
||||
if( op==TK_REGISTER ) op = p->op2;
|
||||
if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_TRIGGER)
|
||||
&& p->y.pTab!=0
|
||||
@@ -895,7 +905,7 @@ Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){
|
||||
}else if( ExprAlwaysFalse(pLeft) || ExprAlwaysFalse(pRight) ){
|
||||
sqlite3ExprUnmapAndDelete(pParse, pLeft);
|
||||
sqlite3ExprUnmapAndDelete(pParse, pRight);
|
||||
return sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0);
|
||||
return sqlite3Expr(db, TK_INTEGER, "0");
|
||||
}else{
|
||||
return sqlite3PExpr(pParse, TK_AND, pLeft, pRight);
|
||||
}
|
||||
@@ -1399,8 +1409,9 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){
|
||||
}
|
||||
pItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
|
||||
pItem->zSpan = sqlite3DbStrDup(db, pOldItem->zSpan);
|
||||
pItem->sortOrder = pOldItem->sortOrder;
|
||||
pItem->sortFlags = pOldItem->sortFlags;
|
||||
pItem->done = 0;
|
||||
pItem->bNulls = pOldItem->bNulls;
|
||||
pItem->bSpanIsTab = pOldItem->bSpanIsTab;
|
||||
pItem->bSorterRef = pOldItem->bSorterRef;
|
||||
pItem->u = pOldItem->u;
|
||||
@@ -1511,7 +1522,7 @@ Select *sqlite3SelectDup(sqlite3 *db, Select *pDup, int flags){
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
pNew->pWin = 0;
|
||||
pNew->pWinDefn = sqlite3WindowListDup(db, p->pWinDefn);
|
||||
if( p->pWin ) gatherSelectWindows(pNew);
|
||||
if( p->pWin && db->mallocFailed==0 ) gatherSelectWindows(pNew);
|
||||
#endif
|
||||
pNew->selId = p->selId;
|
||||
*pp = pNew;
|
||||
@@ -1620,6 +1631,10 @@ ExprList *sqlite3ExprListAppendVector(
|
||||
|
||||
for(i=0; i<pColumns->nId; i++){
|
||||
Expr *pSubExpr = sqlite3ExprForVectorField(pParse, pExpr, i);
|
||||
assert( pSubExpr!=0 || db->mallocFailed );
|
||||
assert( pSubExpr==0 || pSubExpr->iTable==0 );
|
||||
if( pSubExpr==0 ) continue;
|
||||
pSubExpr->iTable = pColumns->nId;
|
||||
pList = sqlite3ExprListAppend(pParse, pList, pSubExpr);
|
||||
if( pList ){
|
||||
assert( pList->nExpr==iFirst+i+1 );
|
||||
@@ -1652,15 +1667,34 @@ vector_append_error:
|
||||
/*
|
||||
** Set the sort order for the last element on the given ExprList.
|
||||
*/
|
||||
void sqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder){
|
||||
void sqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder, int eNulls){
|
||||
struct ExprList_item *pItem;
|
||||
if( p==0 ) return;
|
||||
assert( SQLITE_SO_UNDEFINED<0 && SQLITE_SO_ASC>=0 && SQLITE_SO_DESC>0 );
|
||||
assert( p->nExpr>0 );
|
||||
if( iSortOrder<0 ){
|
||||
assert( p->a[p->nExpr-1].sortOrder==SQLITE_SO_ASC );
|
||||
return;
|
||||
|
||||
assert( SQLITE_SO_UNDEFINED<0 && SQLITE_SO_ASC==0 && SQLITE_SO_DESC>0 );
|
||||
assert( iSortOrder==SQLITE_SO_UNDEFINED
|
||||
|| iSortOrder==SQLITE_SO_ASC
|
||||
|| iSortOrder==SQLITE_SO_DESC
|
||||
);
|
||||
assert( eNulls==SQLITE_SO_UNDEFINED
|
||||
|| eNulls==SQLITE_SO_ASC
|
||||
|| eNulls==SQLITE_SO_DESC
|
||||
);
|
||||
|
||||
pItem = &p->a[p->nExpr-1];
|
||||
assert( pItem->bNulls==0 );
|
||||
if( iSortOrder==SQLITE_SO_UNDEFINED ){
|
||||
iSortOrder = SQLITE_SO_ASC;
|
||||
}
|
||||
pItem->sortFlags = (u8)iSortOrder;
|
||||
|
||||
if( eNulls!=SQLITE_SO_UNDEFINED ){
|
||||
pItem->bNulls = 1;
|
||||
if( iSortOrder!=eNulls ){
|
||||
pItem->sortFlags |= KEYINFO_ORDER_BIGNULL;
|
||||
}
|
||||
}
|
||||
p->a[p->nExpr-1].sortOrder = (u8)iSortOrder;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2159,27 +2193,30 @@ int sqlite3ExprCanBeNull(const Expr *p){
|
||||
*/
|
||||
int sqlite3ExprNeedsNoAffinityChange(const Expr *p, char aff){
|
||||
u8 op;
|
||||
int unaryMinus = 0;
|
||||
if( aff==SQLITE_AFF_BLOB ) return 1;
|
||||
while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ p = p->pLeft; }
|
||||
while( p->op==TK_UPLUS || p->op==TK_UMINUS ){
|
||||
if( p->op==TK_UMINUS ) unaryMinus = 1;
|
||||
p = p->pLeft;
|
||||
}
|
||||
op = p->op;
|
||||
if( op==TK_REGISTER ) op = p->op2;
|
||||
switch( op ){
|
||||
case TK_INTEGER: {
|
||||
return aff==SQLITE_AFF_INTEGER || aff==SQLITE_AFF_NUMERIC;
|
||||
return aff>=SQLITE_AFF_NUMERIC;
|
||||
}
|
||||
case TK_FLOAT: {
|
||||
return aff==SQLITE_AFF_REAL || aff==SQLITE_AFF_NUMERIC;
|
||||
return aff>=SQLITE_AFF_NUMERIC;
|
||||
}
|
||||
case TK_STRING: {
|
||||
return aff==SQLITE_AFF_TEXT;
|
||||
return !unaryMinus && aff==SQLITE_AFF_TEXT;
|
||||
}
|
||||
case TK_BLOB: {
|
||||
return 1;
|
||||
return !unaryMinus;
|
||||
}
|
||||
case TK_COLUMN: {
|
||||
assert( p->iTable>=0 ); /* p cannot be part of a CHECK constraint */
|
||||
return p->iColumn<0
|
||||
&& (aff==SQLITE_AFF_INTEGER || aff==SQLITE_AFF_NUMERIC);
|
||||
return aff>=SQLITE_AFF_NUMERIC && p->iColumn<0;
|
||||
}
|
||||
default: {
|
||||
return 0;
|
||||
@@ -2362,7 +2399,7 @@ static int sqlite3InRhsIsConstant(Expr *pIn){
|
||||
#ifndef SQLITE_OMIT_SUBQUERY
|
||||
int sqlite3FindInIndex(
|
||||
Parse *pParse, /* Parsing context */
|
||||
Expr *pX, /* The right-hand side (RHS) of the IN operator */
|
||||
Expr *pX, /* The IN expression */
|
||||
u32 inFlags, /* IN_INDEX_LOOP, _MEMBERSHIP, and/or _NOOP_OK */
|
||||
int *prRhsHasNull, /* Register holding NULL status. See notes */
|
||||
int *aiMap, /* Mapping from Index fields to RHS fields */
|
||||
@@ -2787,7 +2824,7 @@ void sqlite3CodeRhsOfIN(
|
||||
int i;
|
||||
ExprList *pList = pExpr->x.pList;
|
||||
struct ExprList_item *pItem;
|
||||
int r1, r2, r3;
|
||||
int r1, r2;
|
||||
affinity = sqlite3ExprAffinity(pLeft);
|
||||
if( affinity<=SQLITE_AFF_NONE ){
|
||||
affinity = SQLITE_AFF_BLOB;
|
||||
@@ -2815,9 +2852,9 @@ void sqlite3CodeRhsOfIN(
|
||||
}
|
||||
|
||||
/* Evaluate the expression and insert it into the temp table */
|
||||
r3 = sqlite3ExprCodeTarget(pParse, pE2, r1);
|
||||
sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
|
||||
sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r2, r3, 1);
|
||||
sqlite3ExprCode(pParse, pE2, r1);
|
||||
sqlite3VdbeAddOp4(v, OP_MakeRecord, r1, 1, r2, &affinity, 1);
|
||||
sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r2, r1, 1);
|
||||
}
|
||||
sqlite3ReleaseTempReg(pParse, r1);
|
||||
sqlite3ReleaseTempReg(pParse, r2);
|
||||
@@ -2830,6 +2867,7 @@ void sqlite3CodeRhsOfIN(
|
||||
/* Subroutine return */
|
||||
sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
|
||||
sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
|
||||
sqlite3ClearTempRegCache(pParse);
|
||||
}
|
||||
}
|
||||
#endif /* SQLITE_OMIT_SUBQUERY */
|
||||
@@ -2843,7 +2881,7 @@ void sqlite3CodeRhsOfIN(
|
||||
**
|
||||
** The pExpr parameter is the SELECT or EXISTS operator to be coded.
|
||||
**
|
||||
** The register that holds the result. For a multi-column SELECT,
|
||||
** Return the register that holds the result. For a multi-column SELECT,
|
||||
** the result is stored in a contiguous array of registers and the
|
||||
** return value is the register of the left-most result column.
|
||||
** Return 0 if an error occurs.
|
||||
@@ -2921,11 +2959,21 @@ int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
|
||||
VdbeComment((v, "Init EXISTS result"));
|
||||
}
|
||||
pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[1], 0);
|
||||
if( pSel->pLimit ){
|
||||
sqlite3ExprDelete(pParse->db, pSel->pLimit->pLeft);
|
||||
/* The subquery already has a limit. If the pre-existing limit is X
|
||||
** then make the new limit X<>0 so that the new limit is either 1 or 0 */
|
||||
sqlite3 *db = pParse->db;
|
||||
pLimit = sqlite3Expr(db, TK_INTEGER, "0");
|
||||
if( pLimit ){
|
||||
pLimit->affExpr = SQLITE_AFF_NUMERIC;
|
||||
pLimit = sqlite3PExpr(pParse, TK_NE,
|
||||
sqlite3ExprDup(db, pSel->pLimit->pLeft, 0), pLimit);
|
||||
}
|
||||
sqlite3ExprDelete(db, pSel->pLimit->pLeft);
|
||||
pSel->pLimit->pLeft = pLimit;
|
||||
}else{
|
||||
/* If there is no pre-existing limit add a limit of 1 */
|
||||
pLimit = sqlite3Expr(pParse->db, TK_INTEGER, "1");
|
||||
pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0);
|
||||
}
|
||||
pSel->iLimit = 0;
|
||||
@@ -2940,6 +2988,7 @@ int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
|
||||
/* Subroutine return */
|
||||
sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
|
||||
sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
|
||||
sqlite3ClearTempRegCache(pParse);
|
||||
}
|
||||
|
||||
return rReg;
|
||||
@@ -3087,13 +3136,21 @@ static void sqlite3ExprCodeIN(
|
||||
int r2, regToFree;
|
||||
int regCkNull = 0;
|
||||
int ii;
|
||||
int bLhsReal; /* True if the LHS of the IN has REAL affinity */
|
||||
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
|
||||
if( destIfNull!=destIfFalse ){
|
||||
regCkNull = sqlite3GetTempReg(pParse);
|
||||
sqlite3VdbeAddOp3(v, OP_BitAnd, rLhs, rLhs, regCkNull);
|
||||
}
|
||||
bLhsReal = sqlite3ExprAffinity(pExpr->pLeft)==SQLITE_AFF_REAL;
|
||||
for(ii=0; ii<pList->nExpr; ii++){
|
||||
r2 = sqlite3ExprCodeTemp(pParse, pList->a[ii].pExpr, ®ToFree);
|
||||
if( bLhsReal ){
|
||||
r2 = regToFree = sqlite3GetTempReg(pParse);
|
||||
sqlite3ExprCode(pParse, pList->a[ii].pExpr, r2);
|
||||
sqlite3VdbeAddOp4(v, OP_Affinity, r2, 1, 0, "E", P4_STATIC);
|
||||
}else{
|
||||
r2 = sqlite3ExprCodeTemp(pParse, pList->a[ii].pExpr, ®ToFree);
|
||||
}
|
||||
if( regCkNull && sqlite3ExprCanBeNull(pList->a[ii].pExpr) ){
|
||||
sqlite3VdbeAddOp3(v, OP_BitAnd, regCkNull, r2, regCkNull);
|
||||
}
|
||||
@@ -3378,7 +3435,7 @@ void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){
|
||||
** the correct value for the expression.
|
||||
*/
|
||||
static void exprToRegister(Expr *pExpr, int iReg){
|
||||
Expr *p = sqlite3ExprSkipCollate(pExpr);
|
||||
Expr *p = sqlite3ExprSkipCollateAndLikely(pExpr);
|
||||
p->op2 = p->op;
|
||||
p->op = TK_REGISTER;
|
||||
p->iTable = iReg;
|
||||
@@ -3495,7 +3552,19 @@ expr_code_doover:
|
||||
if( iTab<0 ){
|
||||
if( pParse->iSelfTab<0 ){
|
||||
/* Generating CHECK constraints or inserting into partial index */
|
||||
return pExpr->iColumn - pParse->iSelfTab;
|
||||
assert( pExpr->y.pTab!=0 );
|
||||
assert( pExpr->iColumn>=XN_ROWID );
|
||||
assert( pExpr->iColumn<pExpr->y.pTab->nCol );
|
||||
if( pExpr->iColumn>=0
|
||||
&& pExpr->y.pTab->aCol[pExpr->iColumn].affinity==SQLITE_AFF_REAL
|
||||
){
|
||||
sqlite3VdbeAddOp2(v, OP_SCopy, pExpr->iColumn - pParse->iSelfTab,
|
||||
target);
|
||||
sqlite3VdbeAddOp1(v, OP_RealAffinity, target);
|
||||
return target;
|
||||
}else{
|
||||
return pExpr->iColumn - pParse->iSelfTab;
|
||||
}
|
||||
}else{
|
||||
/* Coding an expression that is part of an index where column names
|
||||
** in the index refer to the table to which the index belongs */
|
||||
@@ -3890,8 +3959,8 @@ expr_code_doover:
|
||||
pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft);
|
||||
}
|
||||
assert( pExpr->iTable==0 || pExpr->pLeft->op==TK_SELECT );
|
||||
if( pExpr->iTable
|
||||
&& pExpr->iTable!=(n = sqlite3ExprVectorSize(pExpr->pLeft))
|
||||
if( pExpr->iTable!=0
|
||||
&& pExpr->iTable!=(n = sqlite3ExprVectorSize(pExpr->pLeft))
|
||||
){
|
||||
sqlite3ErrorMsg(pParse, "%d columns assigned %d values",
|
||||
pExpr->iTable, n);
|
||||
@@ -3994,10 +4063,23 @@ expr_code_doover:
|
||||
break;
|
||||
}
|
||||
|
||||
/* TK_IF_NULL_ROW Expr nodes are inserted ahead of expressions
|
||||
** that derive from the right-hand table of a LEFT JOIN. The
|
||||
** Expr.iTable value is the table number for the right-hand table.
|
||||
** The expression is only evaluated if that table is not currently
|
||||
** on a LEFT JOIN NULL row.
|
||||
*/
|
||||
case TK_IF_NULL_ROW: {
|
||||
int addrINR;
|
||||
u8 okConstFactor = pParse->okConstFactor;
|
||||
addrINR = sqlite3VdbeAddOp1(v, OP_IfNullRow, pExpr->iTable);
|
||||
/* Temporarily disable factoring of constant expressions, since
|
||||
** even though expressions may appear to be constant, they are not
|
||||
** really constant because they originate from the right-hand side
|
||||
** of a LEFT JOIN. */
|
||||
pParse->okConstFactor = 0;
|
||||
inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
|
||||
pParse->okConstFactor = okConstFactor;
|
||||
sqlite3VdbeJumpHere(v, addrINR);
|
||||
sqlite3VdbeChangeP3(v, addrINR, inReg);
|
||||
break;
|
||||
@@ -4173,7 +4255,7 @@ int sqlite3ExprCodeAtInit(
|
||||
*/
|
||||
int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){
|
||||
int r2;
|
||||
pExpr = sqlite3ExprSkipCollate(pExpr);
|
||||
pExpr = sqlite3ExprSkipCollateAndLikely(pExpr);
|
||||
if( ConstFactorOk(pParse)
|
||||
&& pExpr->op!=TK_REGISTER
|
||||
&& sqlite3ExprIsConstantNotJoin(pExpr)
|
||||
@@ -4874,7 +4956,8 @@ int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTab){
|
||||
){
|
||||
if( pA->iColumn!=pB->iColumn ) return 2;
|
||||
if( pA->op2!=pB->op2 ) return 2;
|
||||
if( pA->iTable!=pB->iTable
|
||||
if( pA->op!=TK_IN
|
||||
&& pA->iTable!=pB->iTable
|
||||
&& (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
|
||||
}
|
||||
}
|
||||
@@ -4904,7 +4987,7 @@ int sqlite3ExprListCompare(ExprList *pA, ExprList *pB, int iTab){
|
||||
for(i=0; i<pA->nExpr; i++){
|
||||
Expr *pExprA = pA->a[i].pExpr;
|
||||
Expr *pExprB = pB->a[i].pExpr;
|
||||
if( pA->a[i].sortOrder!=pB->a[i].sortOrder ) return 1;
|
||||
if( pA->a[i].sortFlags!=pB->a[i].sortFlags ) return 1;
|
||||
if( sqlite3ExprCompare(0, pExprA, pExprB, iTab) ) return 1;
|
||||
}
|
||||
return 0;
|
||||
@@ -4916,20 +4999,23 @@ int sqlite3ExprListCompare(ExprList *pA, ExprList *pB, int iTab){
|
||||
*/
|
||||
int sqlite3ExprCompareSkip(Expr *pA, Expr *pB, int iTab){
|
||||
return sqlite3ExprCompare(0,
|
||||
sqlite3ExprSkipCollate(pA),
|
||||
sqlite3ExprSkipCollate(pB),
|
||||
sqlite3ExprSkipCollateAndLikely(pA),
|
||||
sqlite3ExprSkipCollateAndLikely(pB),
|
||||
iTab);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return non-zero if Expr p can only be true if pNN is not NULL.
|
||||
**
|
||||
** Or if seenNot is true, return non-zero if Expr p can only be
|
||||
** non-NULL if pNN is not NULL
|
||||
*/
|
||||
static int exprImpliesNotNull(
|
||||
Parse *pParse, /* Parsing context */
|
||||
Expr *p, /* The expression to be checked */
|
||||
Expr *pNN, /* The expression that is NOT NULL */
|
||||
int iTab, /* Table being evaluated */
|
||||
int seenNot /* True if p is an operand of NOT */
|
||||
int seenNot /* Return true only if p can be any non-NULL value */
|
||||
){
|
||||
assert( p );
|
||||
assert( pNN );
|
||||
@@ -4941,19 +5027,19 @@ static int exprImpliesNotNull(
|
||||
if( seenNot && ExprHasProperty(p, EP_xIsSelect) ) return 0;
|
||||
assert( ExprHasProperty(p,EP_xIsSelect)
|
||||
|| (p->x.pList!=0 && p->x.pList->nExpr>0) );
|
||||
return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot);
|
||||
return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1);
|
||||
}
|
||||
case TK_BETWEEN: {
|
||||
ExprList *pList = p->x.pList;
|
||||
assert( pList!=0 );
|
||||
assert( pList->nExpr==2 );
|
||||
if( seenNot ) return 0;
|
||||
if( exprImpliesNotNull(pParse, pList->a[0].pExpr, pNN, iTab, seenNot)
|
||||
|| exprImpliesNotNull(pParse, pList->a[1].pExpr, pNN, iTab, seenNot)
|
||||
if( exprImpliesNotNull(pParse, pList->a[0].pExpr, pNN, iTab, 1)
|
||||
|| exprImpliesNotNull(pParse, pList->a[1].pExpr, pNN, iTab, 1)
|
||||
){
|
||||
return 1;
|
||||
}
|
||||
return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot);
|
||||
return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1);
|
||||
}
|
||||
case TK_EQ:
|
||||
case TK_NE:
|
||||
@@ -4963,20 +5049,21 @@ static int exprImpliesNotNull(
|
||||
case TK_GE:
|
||||
case TK_PLUS:
|
||||
case TK_MINUS:
|
||||
case TK_BITOR:
|
||||
case TK_LSHIFT:
|
||||
case TK_RSHIFT:
|
||||
case TK_CONCAT:
|
||||
seenNot = 1;
|
||||
/* Fall thru */
|
||||
case TK_STAR:
|
||||
case TK_REM:
|
||||
case TK_BITAND:
|
||||
case TK_BITOR:
|
||||
case TK_SLASH:
|
||||
case TK_LSHIFT:
|
||||
case TK_RSHIFT:
|
||||
case TK_CONCAT: {
|
||||
case TK_SLASH: {
|
||||
if( exprImpliesNotNull(pParse, p->pRight, pNN, iTab, seenNot) ) return 1;
|
||||
/* Fall thru into the next case */
|
||||
}
|
||||
case TK_SPAN:
|
||||
case TK_COLLATE:
|
||||
case TK_BITNOT:
|
||||
case TK_UPLUS:
|
||||
case TK_UMINUS: {
|
||||
return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot);
|
||||
@@ -4984,8 +5071,9 @@ static int exprImpliesNotNull(
|
||||
case TK_TRUTH: {
|
||||
if( seenNot ) return 0;
|
||||
if( p->op2!=TK_IS ) return 0;
|
||||
return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot);
|
||||
return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1);
|
||||
}
|
||||
case TK_BITNOT:
|
||||
case TK_NOT: {
|
||||
return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1);
|
||||
}
|
||||
@@ -5051,7 +5139,6 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
|
||||
if( ExprHasProperty(pExpr, EP_FromJoin) ) return WRC_Prune;
|
||||
switch( pExpr->op ){
|
||||
case TK_ISNOT:
|
||||
case TK_NOT:
|
||||
case TK_ISNULL:
|
||||
case TK_NOTNULL:
|
||||
case TK_IS:
|
||||
@@ -5060,7 +5147,6 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
|
||||
case TK_IN:
|
||||
case TK_FUNCTION:
|
||||
testcase( pExpr->op==TK_ISNOT );
|
||||
testcase( pExpr->op==TK_NOT );
|
||||
testcase( pExpr->op==TK_ISNULL );
|
||||
testcase( pExpr->op==TK_NOTNULL );
|
||||
testcase( pExpr->op==TK_IS );
|
||||
@@ -5076,6 +5162,18 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
|
||||
}
|
||||
return WRC_Prune;
|
||||
|
||||
case TK_AND:
|
||||
if( sqlite3ExprImpliesNonNullRow(pExpr->pLeft, pWalker->u.iCur)
|
||||
&& sqlite3ExprImpliesNonNullRow(pExpr->pRight, pWalker->u.iCur)
|
||||
){
|
||||
pWalker->eCode = 1;
|
||||
}
|
||||
return WRC_Prune;
|
||||
|
||||
case TK_BETWEEN:
|
||||
sqlite3WalkExpr(pWalker, pExpr->pLeft);
|
||||
return WRC_Prune;
|
||||
|
||||
/* Virtual tables are allowed to use constraints like x=NULL. So
|
||||
** a term of the form x=y does not prove that y is not null if x
|
||||
** is the column of a virtual table */
|
||||
@@ -5096,6 +5194,7 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
|
||||
){
|
||||
return WRC_Prune;
|
||||
}
|
||||
|
||||
default:
|
||||
return WRC_Continue;
|
||||
}
|
||||
@@ -5125,7 +5224,7 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
|
||||
*/
|
||||
int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab){
|
||||
Walker w;
|
||||
p = sqlite3ExprSkipCollate(p);
|
||||
p = sqlite3ExprSkipCollateAndLikely(p);
|
||||
while( p ){
|
||||
if( p->op==TK_NOTNULL ){
|
||||
p = p->pLeft;
|
||||
@@ -5231,7 +5330,10 @@ static int exprSrcCount(Walker *pWalker, Expr *pExpr){
|
||||
}
|
||||
if( i<nSrc ){
|
||||
p->nThis++;
|
||||
}else{
|
||||
}else if( nSrc==0 || pExpr->iTable<pSrc->a[0].iCursor ){
|
||||
/* In a well-formed parse tree (no name resolution errors),
|
||||
** TK_COLUMN nodes with smaller Expr.iTable values are in an
|
||||
** outer context. Those are the only ones to count as "other" */
|
||||
p->nOther++;
|
||||
}
|
||||
}
|
||||
@@ -5248,8 +5350,9 @@ int sqlite3FunctionUsesThisSrc(Expr *pExpr, SrcList *pSrcList){
|
||||
Walker w;
|
||||
struct SrcCount cnt;
|
||||
assert( pExpr->op==TK_AGG_FUNCTION );
|
||||
memset(&w, 0, sizeof(w));
|
||||
w.xExprCallback = exprSrcCount;
|
||||
w.xSelectCallback = 0;
|
||||
w.xSelectCallback = sqlite3SelectWalkNoop;
|
||||
w.u.pSrcCount = &cnt;
|
||||
cnt.pSrc = pSrcList;
|
||||
cnt.nThis = 0;
|
||||
@@ -5518,6 +5621,11 @@ void sqlite3ReleaseTempRange(Parse *pParse, int iReg, int nReg){
|
||||
|
||||
/*
|
||||
** Mark all temporary registers as being unavailable for reuse.
|
||||
**
|
||||
** Always invoke this procedure after coding a subroutine or co-routine
|
||||
** that might be invoked from other parts of the code, to ensure that
|
||||
** the sub/co-routine does not use registers in common with the code that
|
||||
** invokes the sub/co-routine.
|
||||
*/
|
||||
void sqlite3ClearTempRegCache(Parse *pParse){
|
||||
pParse->nTempReg = 0;
|
||||
|
||||
+21
-2
@@ -203,6 +203,8 @@ static void instrFunc(
|
||||
int N = 1;
|
||||
int isText;
|
||||
unsigned char firstChar;
|
||||
sqlite3_value *pC1 = 0;
|
||||
sqlite3_value *pC2 = 0;
|
||||
|
||||
UNUSED_PARAMETER(argc);
|
||||
typeHaystack = sqlite3_value_type(argv[0]);
|
||||
@@ -215,12 +217,22 @@ static void instrFunc(
|
||||
zHaystack = sqlite3_value_blob(argv[0]);
|
||||
zNeedle = sqlite3_value_blob(argv[1]);
|
||||
isText = 0;
|
||||
}else{
|
||||
}else if( typeHaystack!=SQLITE_BLOB && typeNeedle!=SQLITE_BLOB ){
|
||||
zHaystack = sqlite3_value_text(argv[0]);
|
||||
zNeedle = sqlite3_value_text(argv[1]);
|
||||
isText = 1;
|
||||
}else{
|
||||
pC1 = sqlite3_value_dup(argv[0]);
|
||||
zHaystack = sqlite3_value_text(pC1);
|
||||
if( zHaystack==0 ) goto endInstrOOM;
|
||||
nHaystack = sqlite3_value_bytes(pC1);
|
||||
pC2 = sqlite3_value_dup(argv[1]);
|
||||
zNeedle = sqlite3_value_text(pC2);
|
||||
if( zNeedle==0 ) goto endInstrOOM;
|
||||
nNeedle = sqlite3_value_bytes(pC2);
|
||||
isText = 1;
|
||||
}
|
||||
if( zNeedle==0 || (nHaystack && zHaystack==0) ) return;
|
||||
if( zNeedle==0 || (nHaystack && zHaystack==0) ) goto endInstrOOM;
|
||||
firstChar = zNeedle[0];
|
||||
while( nNeedle<=nHaystack
|
||||
&& (zHaystack[0]!=firstChar || memcmp(zHaystack, zNeedle, nNeedle)!=0)
|
||||
@@ -234,6 +246,13 @@ static void instrFunc(
|
||||
if( nNeedle>nHaystack ) N = 0;
|
||||
}
|
||||
sqlite3_result_int(context, N);
|
||||
endInstr:
|
||||
sqlite3_value_free(pC1);
|
||||
sqlite3_value_free(pC2);
|
||||
return;
|
||||
endInstrOOM:
|
||||
sqlite3_result_error_nomem(context);
|
||||
goto endInstr;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -271,14 +271,6 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = {
|
||||
*/
|
||||
FuncDefHash sqlite3BuiltinFunctions;
|
||||
|
||||
/*
|
||||
** Constant tokens for values 0 and 1.
|
||||
*/
|
||||
const Token sqlite3IntTokens[] = {
|
||||
{ "0", 1 },
|
||||
{ "1", 1 }
|
||||
};
|
||||
|
||||
#ifdef VDBE_PROFILE
|
||||
/*
|
||||
** The following performance counter can be used in place of
|
||||
|
||||
@@ -99,6 +99,7 @@ const char *sqlite3IndexAffinityStr(sqlite3 *db, Index *pIdx){
|
||||
aff = sqlite3ExprAffinity(pIdx->aColExpr->a[n].pExpr);
|
||||
}
|
||||
if( aff<SQLITE_AFF_BLOB ) aff = SQLITE_AFF_BLOB;
|
||||
if( aff>SQLITE_AFF_NUMERIC) aff = SQLITE_AFF_NUMERIC;
|
||||
pIdx->zColAff[n] = aff;
|
||||
}
|
||||
pIdx->zColAff[n] = 0;
|
||||
@@ -833,6 +834,9 @@ void sqlite3Insert(
|
||||
pTab->zName);
|
||||
goto insert_cleanup;
|
||||
}
|
||||
if( sqlite3HasExplicitNulls(pParse, pUpsert->pUpsertTarget) ){
|
||||
goto insert_cleanup;
|
||||
}
|
||||
pTabList->a[0].iCursor = iDataCur;
|
||||
pUpsert->pUpsertSrc = pTabList;
|
||||
pUpsert->regData = regData;
|
||||
|
||||
+7
-1
@@ -461,7 +461,13 @@ static const sqlite3_api_routines sqlite3Apis = {
|
||||
#endif
|
||||
/* Version 3.28.0 and later */
|
||||
sqlite3_stmt_isexplain,
|
||||
sqlite3_value_frombind
|
||||
sqlite3_value_frombind,
|
||||
/* Version 3.30.0 and later */
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
sqlite3_drop_modules,
|
||||
#else
|
||||
0,
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
+4
-5
@@ -836,6 +836,7 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){
|
||||
} aFlagOp[] = {
|
||||
{ SQLITE_DBCONFIG_ENABLE_FKEY, SQLITE_ForeignKeys },
|
||||
{ SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger },
|
||||
{ SQLITE_DBCONFIG_ENABLE_VIEW, SQLITE_EnableView },
|
||||
{ SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, SQLITE_Fts3Tokenizer },
|
||||
{ SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension },
|
||||
{ SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, SQLITE_NoCkptOnClose },
|
||||
@@ -1235,11 +1236,8 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
for(i=sqliteHashFirst(&db->aModule); i; i=sqliteHashNext(i)){
|
||||
Module *pMod = (Module *)sqliteHashData(i);
|
||||
if( pMod->xDestroy ){
|
||||
pMod->xDestroy(pMod->pAux);
|
||||
}
|
||||
sqlite3VtabEponymousTableClear(db, pMod);
|
||||
sqlite3DbFree(db, pMod);
|
||||
sqlite3VtabModuleUnref(db, pMod);
|
||||
}
|
||||
sqlite3HashClear(&db->aModule);
|
||||
#endif
|
||||
@@ -1721,7 +1719,7 @@ int sqlite3CreateFunc(
|
||||
|
||||
assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC );
|
||||
assert( SQLITE_FUNC_DIRECT==SQLITE_DIRECTONLY );
|
||||
extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY);
|
||||
extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY|SQLITE_SUBTYPE);
|
||||
enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY);
|
||||
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
@@ -3077,6 +3075,7 @@ static int openDatabase(
|
||||
db->nMaxSorterMmap = 0x7FFFFFFF;
|
||||
db->flags |= SQLITE_ShortColNames
|
||||
| SQLITE_EnableTrigger
|
||||
| SQLITE_EnableView
|
||||
| SQLITE_CacheSpill
|
||||
|
||||
/* The SQLITE_DQS compile-time option determines the default settings
|
||||
|
||||
@@ -67,4 +67,5 @@
|
||||
#define MUTEX_LOGIC(X)
|
||||
#else
|
||||
#define MUTEX_LOGIC(X) X
|
||||
int sqlite3_mutex_held(sqlite3_mutex*);
|
||||
#endif /* defined(SQLITE_MUTEX_OMIT) */
|
||||
|
||||
+38
-14
@@ -105,13 +105,29 @@
|
||||
# include <sys/param.h>
|
||||
#endif /* SQLITE_ENABLE_LOCKING_STYLE */
|
||||
|
||||
#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))
|
||||
# define HAVE_GETHOSTUUID 1
|
||||
# else
|
||||
# warning "gethostuuid() is disabled."
|
||||
/*
|
||||
** Try to determine if gethostuuid() is available based on standard
|
||||
** macros. This might sometimes compute the wrong value for some
|
||||
** obscure platforms. For those cases, simply compile with one of
|
||||
** the following:
|
||||
**
|
||||
** -DHAVE_GETHOSTUUID=0
|
||||
** -DHAVE_GETHOSTUUID=1
|
||||
**
|
||||
** None if this matters except when building on Apple products with
|
||||
** -DSQLITE_ENABLE_LOCKING_STYLE.
|
||||
*/
|
||||
#ifndef HAVE_GETHOSTUUID
|
||||
# define HAVE_GETHOSTUUID 0
|
||||
# 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))
|
||||
# undef HAVE_GETHOSTUUID
|
||||
# define HAVE_GETHOSTUUID 1
|
||||
# else
|
||||
# warning "gethostuuid() is disabled."
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@@ -5824,7 +5840,7 @@ static int getFileMode(
|
||||
** If the SQLITE_ENABLE_8_3_NAMES option is enabled, then the
|
||||
** original filename is unavailable. But 8_3_NAMES is only used for
|
||||
** FAT filesystems and permissions do not matter there, so just use
|
||||
** the default permissions.
|
||||
** the default permissions. In 8_3_NAMES mode, leave *pMode set to zero.
|
||||
*/
|
||||
static int findCreateFileMode(
|
||||
const char *zPath, /* Path of file (possibly) being created */
|
||||
@@ -6059,11 +6075,19 @@ static int unixOpen(
|
||||
goto open_finished;
|
||||
}
|
||||
|
||||
/* If this process is running as root and if creating a new rollback
|
||||
** journal or WAL file, set the ownership of the journal or WAL to be
|
||||
** the same as the original database.
|
||||
/* The owner of the rollback journal or WAL file should always be the
|
||||
** same as the owner of the database file. Try to ensure that this is
|
||||
** the case. The chown() system call will be a no-op if the current
|
||||
** process lacks root privileges, be we should at least try. Without
|
||||
** this step, if a root process opens a database file, it can leave
|
||||
** behinds a journal/WAL that is owned by root and hence make the
|
||||
** database inaccessible to unprivileged processes.
|
||||
**
|
||||
** If openMode==0, then that means uid and gid are not set correctly
|
||||
** (probably because SQLite is configured to use 8+3 filename mode) and
|
||||
** in that case we do not want to attempt the chown().
|
||||
*/
|
||||
if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){
|
||||
if( openMode && (flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL))!=0 ){
|
||||
robustFchown(fd, uid, gid);
|
||||
}
|
||||
}
|
||||
@@ -6921,7 +6945,7 @@ int sqlite3_hostid_num = 0;
|
||||
|
||||
#define PROXY_HOSTIDLEN 16 /* conch file host id length */
|
||||
|
||||
#ifdef HAVE_GETHOSTUUID
|
||||
#if HAVE_GETHOSTUUID
|
||||
/* Not always defined in the headers as it ought to be */
|
||||
extern int gethostuuid(uuid_t id, const struct timespec *wait);
|
||||
#endif
|
||||
@@ -6932,7 +6956,7 @@ extern int gethostuuid(uuid_t id, const struct timespec *wait);
|
||||
static int proxyGetHostID(unsigned char *pHostID, int *pError){
|
||||
assert(PROXY_HOSTIDLEN == sizeof(uuid_t));
|
||||
memset(pHostID, 0, PROXY_HOSTIDLEN);
|
||||
#ifdef HAVE_GETHOSTUUID
|
||||
#if HAVE_GETHOSTUUID
|
||||
{
|
||||
struct timespec timeout = {1, 0}; /* 1 sec timeout */
|
||||
if( gethostuuid(pHostID, &timeout) ){
|
||||
|
||||
+14
-35
@@ -211,6 +211,7 @@ columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,&A,&Y);}
|
||||
IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH NO PLAN
|
||||
QUERY KEY OF OFFSET PRAGMA RAISE RECURSIVE RELEASE REPLACE RESTRICT ROW ROWS
|
||||
ROLLBACK SAVEPOINT TEMP TRIGGER VACUUM VIEW VIRTUAL WITH WITHOUT
|
||||
NULLS FIRST LAST
|
||||
%ifdef SQLITE_OMIT_COMPOUND_SELECT
|
||||
EXCEPT INTERSECT UNION
|
||||
%endif SQLITE_OMIT_COMPOUND_SELECT
|
||||
@@ -781,13 +782,13 @@ using_opt(U) ::= . {U = 0;}
|
||||
|
||||
orderby_opt(A) ::= . {A = 0;}
|
||||
orderby_opt(A) ::= ORDER BY sortlist(X). {A = X;}
|
||||
sortlist(A) ::= sortlist(A) COMMA expr(Y) sortorder(Z). {
|
||||
sortlist(A) ::= sortlist(A) COMMA expr(Y) sortorder(Z) nulls(X). {
|
||||
A = sqlite3ExprListAppend(pParse,A,Y);
|
||||
sqlite3ExprListSetSortOrder(A,Z);
|
||||
sqlite3ExprListSetSortOrder(A,Z,X);
|
||||
}
|
||||
sortlist(A) ::= expr(Y) sortorder(Z). {
|
||||
sortlist(A) ::= expr(Y) sortorder(Z) nulls(X). {
|
||||
A = sqlite3ExprListAppend(pParse,0,Y); /*A-overwrites-Y*/
|
||||
sqlite3ExprListSetSortOrder(A,Z);
|
||||
sqlite3ExprListSetSortOrder(A,Z,X);
|
||||
}
|
||||
|
||||
%type sortorder {int}
|
||||
@@ -796,6 +797,11 @@ sortorder(A) ::= ASC. {A = SQLITE_SO_ASC;}
|
||||
sortorder(A) ::= DESC. {A = SQLITE_SO_DESC;}
|
||||
sortorder(A) ::= . {A = SQLITE_SO_UNDEFINED;}
|
||||
|
||||
%type nulls {int}
|
||||
nulls(A) ::= NULLS FIRST. {A = SQLITE_SO_ASC;}
|
||||
nulls(A) ::= NULLS LAST. {A = SQLITE_SO_DESC;}
|
||||
nulls(A) ::= . {A = SQLITE_SO_UNDEFINED;}
|
||||
|
||||
%type groupby_opt {ExprList*}
|
||||
%destructor groupby_opt {sqlite3ExprListDelete(pParse->db, $$);}
|
||||
groupby_opt(A) ::= . {A = 0;}
|
||||
@@ -1175,34 +1181,7 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
||||
** regardless of the value of expr1.
|
||||
*/
|
||||
sqlite3ExprUnmapAndDelete(pParse, A);
|
||||
A = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[N],1);
|
||||
}else if( Y->nExpr==1 ){
|
||||
/* Expressions of the form:
|
||||
**
|
||||
** expr1 IN (?1)
|
||||
** expr1 NOT IN (?2)
|
||||
**
|
||||
** with exactly one value on the RHS can be simplified to something
|
||||
** like this:
|
||||
**
|
||||
** expr1 == ?1
|
||||
** expr1 <> ?2
|
||||
**
|
||||
** But, the RHS of the == or <> is marked with the EP_Generic flag
|
||||
** so that it may not contribute to the computation of comparison
|
||||
** affinity or the collating sequence to use for comparison. Otherwise,
|
||||
** the semantics would be subtly different from IN or NOT IN.
|
||||
*/
|
||||
Expr *pRHS = Y->a[0].pExpr;
|
||||
Y->a[0].pExpr = 0;
|
||||
sqlite3ExprListDelete(pParse->db, Y);
|
||||
/* pRHS cannot be NULL because a malloc error would have been detected
|
||||
** before now and control would have never reached this point */
|
||||
if( ALWAYS(pRHS) ){
|
||||
pRHS->flags &= ~EP_Collate;
|
||||
pRHS->flags |= EP_Generic;
|
||||
}
|
||||
A = sqlite3PExpr(pParse, N ? TK_NE : TK_EQ, A, pRHS);
|
||||
A = sqlite3Expr(pParse->db, TK_INTEGER, N ? "1" : "0");
|
||||
}else{
|
||||
A = sqlite3PExpr(pParse, TK_IN, A, 0);
|
||||
if( A ){
|
||||
@@ -1767,12 +1746,12 @@ filter_clause(A) ::= FILTER LP WHERE expr(X) RP. { A = X; }
|
||||
** are synthesized and do not actually appear in the grammar:
|
||||
*/
|
||||
%token
|
||||
TRUEFALSE /* True or false keyword */
|
||||
ISNOT /* Combination of IS and NOT */
|
||||
FUNCTION /* A function invocation */
|
||||
COLUMN /* Reference to a table column */
|
||||
AGG_FUNCTION /* An aggregate function */
|
||||
AGG_COLUMN /* An aggregated column */
|
||||
TRUEFALSE /* True or false keyword */
|
||||
ISNOT /* Combination of IS and NOT */
|
||||
FUNCTION /* A function invocation */
|
||||
UMINUS /* Unary minus */
|
||||
UPLUS /* Unary plus */
|
||||
TRUTH /* IS TRUE or IS FALSE or IS NOT TRUE or IS NOT FALSE */
|
||||
|
||||
+1
-1
@@ -1245,7 +1245,7 @@ void sqlite3Pragma(
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef SQLITE_INTROSPECTION_PRAGMAS
|
||||
#ifndef SQLITE_OMIT_INTROSPECTION_PRAGMAS
|
||||
case PragTyp_FUNCTION_LIST: {
|
||||
int i;
|
||||
HashElem *j;
|
||||
|
||||
+4
-4
@@ -311,7 +311,7 @@ static const PragmaName aPragmaName[] = {
|
||||
/* iArg: */ SQLITE_FullFSync },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
#if defined(SQLITE_INTROSPECTION_PRAGMAS)
|
||||
#if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS)
|
||||
{/* zName: */ "function_list",
|
||||
/* ePragTyp: */ PragTyp_FUNCTION_LIST,
|
||||
/* ePragFlg: */ PragFlg_Result0,
|
||||
@@ -435,7 +435,7 @@ static const PragmaName aPragmaName[] = {
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
#if !defined(SQLITE_OMIT_VIRTUALTABLE)
|
||||
#if defined(SQLITE_INTROSPECTION_PRAGMAS)
|
||||
#if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS)
|
||||
{/* zName: */ "module_list",
|
||||
/* ePragTyp: */ PragTyp_MODULE_LIST,
|
||||
/* ePragFlg: */ PragFlg_Result0,
|
||||
@@ -470,7 +470,7 @@ static const PragmaName aPragmaName[] = {
|
||||
/* iArg: */ SQLITE_ParserTrace },
|
||||
#endif
|
||||
#endif
|
||||
#if defined(SQLITE_INTROSPECTION_PRAGMAS)
|
||||
#if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS)
|
||||
{/* zName: */ "pragma_list",
|
||||
/* ePragTyp: */ PragTyp_PRAGMA_LIST,
|
||||
/* ePragFlg: */ PragFlg_Result0,
|
||||
@@ -668,4 +668,4 @@ static const PragmaName aPragmaName[] = {
|
||||
/* iArg: */ SQLITE_WriteSchema|SQLITE_NoSchemaError },
|
||||
#endif
|
||||
};
|
||||
/* Number of pragmas: 62 on by default, 81 total. */
|
||||
/* Number of pragmas: 65 on by default, 81 total. */
|
||||
|
||||
+10
-3
@@ -96,6 +96,13 @@ static void resolveAlias(
|
||||
pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken);
|
||||
pExpr->flags |= EP_MemToken;
|
||||
}
|
||||
if( ExprHasProperty(pExpr, EP_WinFunc) ){
|
||||
if( pExpr->y.pWin!=0 ){
|
||||
pExpr->y.pWin->pOwner = pExpr;
|
||||
}else{
|
||||
assert( db->mallocFailed );
|
||||
}
|
||||
}
|
||||
sqlite3DbFree(db, pDup);
|
||||
}
|
||||
ExprSetProperty(pExpr, EP_Alias);
|
||||
@@ -973,7 +980,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
}
|
||||
case TK_IS:
|
||||
case TK_ISNOT: {
|
||||
Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight);
|
||||
Expr *pRight = sqlite3ExprSkipCollateAndLikely(pExpr->pRight);
|
||||
assert( !ExprHasProperty(pExpr, EP_Reduced) );
|
||||
/* Handle special cases of "x IS TRUE", "x IS FALSE", "x IS NOT TRUE",
|
||||
** and "x IS NOT FALSE". */
|
||||
@@ -1184,7 +1191,7 @@ static int resolveCompoundOrderBy(
|
||||
int iCol = -1;
|
||||
Expr *pE, *pDup;
|
||||
if( pItem->done ) continue;
|
||||
pE = sqlite3ExprSkipCollate(pItem->pExpr);
|
||||
pE = sqlite3ExprSkipCollateAndLikely(pItem->pExpr);
|
||||
if( sqlite3ExprIsInteger(pE, &iCol) ){
|
||||
if( iCol<=0 || iCol>pEList->nExpr ){
|
||||
resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr);
|
||||
@@ -1363,7 +1370,7 @@ static int resolveOrderGroupBy(
|
||||
pParse = pNC->pParse;
|
||||
for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
|
||||
Expr *pE = pItem->pExpr;
|
||||
Expr *pE2 = sqlite3ExprSkipCollate(pE);
|
||||
Expr *pE2 = sqlite3ExprSkipCollateAndLikely(pE);
|
||||
if( zType[0]!='G' ){
|
||||
iCol = resolveAsName(pParse, pSelect->pEList, pE2);
|
||||
if( iCol>0 ){
|
||||
|
||||
+75
-31
@@ -664,7 +664,7 @@ static void pushOntoSorter(
|
||||
if( pParse->db->mallocFailed ) return;
|
||||
pOp->p2 = nKey + nData;
|
||||
pKI = pOp->p4.pKeyInfo;
|
||||
memset(pKI->aSortOrder, 0, pKI->nKeyField); /* Makes OP_Jump testable */
|
||||
memset(pKI->aSortFlags, 0, pKI->nKeyField); /* Makes OP_Jump testable */
|
||||
sqlite3VdbeChangeP4(v, -1, (char*)pKI, P4_KEYINFO);
|
||||
testcase( pKI->nAllField > pKI->nKeyField+2 );
|
||||
pOp->p4.pKeyInfo = sqlite3KeyInfoFromExprList(pParse,pSort->pOrderBy,nOBSat,
|
||||
@@ -1275,7 +1275,7 @@ KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){
|
||||
int nExtra = (N+X)*(sizeof(CollSeq*)+1) - sizeof(CollSeq*);
|
||||
KeyInfo *p = sqlite3DbMallocRawNN(db, sizeof(KeyInfo) + nExtra);
|
||||
if( p ){
|
||||
p->aSortOrder = (u8*)&p->aColl[N+X];
|
||||
p->aSortFlags = (u8*)&p->aColl[N+X];
|
||||
p->nKeyField = (u16)N;
|
||||
p->nAllField = (u16)(N+X);
|
||||
p->enc = ENC(db);
|
||||
@@ -1352,7 +1352,7 @@ KeyInfo *sqlite3KeyInfoFromExprList(
|
||||
assert( sqlite3KeyInfoIsWriteable(pInfo) );
|
||||
for(i=iStart, pItem=pList->a+iStart; i<nExpr; i++, pItem++){
|
||||
pInfo->aColl[i-iStart] = sqlite3ExprNNCollSeq(pParse, pItem->pExpr);
|
||||
pInfo->aSortOrder[i-iStart] = pItem->sortOrder;
|
||||
pInfo->aSortFlags[i-iStart] = pItem->sortFlags;
|
||||
}
|
||||
}
|
||||
return pInfo;
|
||||
@@ -1960,7 +1960,7 @@ int sqlite3ColumnsFromExprList(
|
||||
if( (zName = pEList->a[i].zName)!=0 ){
|
||||
/* If the column contains an "AS <name>" phrase, use <name> as the name */
|
||||
}else{
|
||||
Expr *pColExpr = sqlite3ExprSkipCollate(pEList->a[i].pExpr);
|
||||
Expr *pColExpr = sqlite3ExprSkipCollateAndLikely(pEList->a[i].pExpr);
|
||||
while( pColExpr->op==TK_DOT ){
|
||||
pColExpr = pColExpr->pRight;
|
||||
assert( pColExpr!=0 );
|
||||
@@ -2253,7 +2253,7 @@ static KeyInfo *multiSelectOrderByKeyInfo(Parse *pParse, Select *p, int nExtra){
|
||||
}
|
||||
assert( sqlite3KeyInfoIsWriteable(pRet) );
|
||||
pRet->aColl[i] = pColl;
|
||||
pRet->aSortOrder[i] = pOrderBy->a[i].sortOrder;
|
||||
pRet->aSortFlags[i] = pOrderBy->a[i].sortFlags;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3228,7 +3228,7 @@ static int multiSelectOrderBy(
|
||||
assert( sqlite3KeyInfoIsWriteable(pKeyDup) );
|
||||
for(i=0; i<nExpr; i++){
|
||||
pKeyDup->aColl[i] = multiSelectCollSeq(pParse, p, i);
|
||||
pKeyDup->aSortOrder[i] = 0;
|
||||
pKeyDup->aSortFlags[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3476,11 +3476,20 @@ static Expr *substExpr(
|
||||
pNew->iRightJoinTable = pExpr->iRightJoinTable;
|
||||
ExprSetProperty(pNew, EP_FromJoin);
|
||||
}
|
||||
if( pNew && ExprHasProperty(pExpr,EP_Generic) ){
|
||||
ExprSetProperty(pNew, EP_Generic);
|
||||
}
|
||||
sqlite3ExprDelete(db, pExpr);
|
||||
pExpr = pNew;
|
||||
|
||||
/* Ensure that the expression now has an implicit collation sequence,
|
||||
** just as it did when it was a column of a view or sub-query. */
|
||||
if( pExpr ){
|
||||
if( pExpr->op!=TK_COLUMN && pExpr->op!=TK_COLLATE ){
|
||||
CollSeq *pColl = sqlite3ExprCollSeq(pSubst->pParse, pExpr);
|
||||
pExpr = sqlite3ExprAddCollateString(pSubst->pParse, pExpr,
|
||||
(pColl ? pColl->zName : "BINARY")
|
||||
);
|
||||
}
|
||||
ExprClearProperty(pExpr, EP_Collate);
|
||||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
@@ -4405,7 +4414,7 @@ static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){
|
||||
ExprList *pEList = pFunc->x.pList; /* Arguments to agg function */
|
||||
const char *zFunc; /* Name of aggregate function pFunc */
|
||||
ExprList *pOrderBy;
|
||||
u8 sortOrder;
|
||||
u8 sortFlags;
|
||||
|
||||
assert( *ppMinMax==0 );
|
||||
assert( pFunc->op==TK_AGG_FUNCTION );
|
||||
@@ -4416,16 +4425,16 @@ static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){
|
||||
zFunc = pFunc->u.zToken;
|
||||
if( sqlite3StrICmp(zFunc, "min")==0 ){
|
||||
eRet = WHERE_ORDERBY_MIN;
|
||||
sortOrder = SQLITE_SO_ASC;
|
||||
sortFlags = KEYINFO_ORDER_BIGNULL;
|
||||
}else if( sqlite3StrICmp(zFunc, "max")==0 ){
|
||||
eRet = WHERE_ORDERBY_MAX;
|
||||
sortOrder = SQLITE_SO_DESC;
|
||||
sortFlags = KEYINFO_ORDER_DESC;
|
||||
}else{
|
||||
return eRet;
|
||||
}
|
||||
*ppMinMax = pOrderBy = sqlite3ExprListDup(db, pEList, 0);
|
||||
assert( pOrderBy!=0 || db->mallocFailed );
|
||||
if( pOrderBy ) pOrderBy->a[0].sortOrder = sortOrder;
|
||||
if( pOrderBy ) pOrderBy->a[0].sortFlags = sortFlags;
|
||||
return eRet;
|
||||
}
|
||||
|
||||
@@ -4906,6 +4915,10 @@ static int selectExpander(Walker *pWalker, Select *p){
|
||||
u8 eCodeOrig = pWalker->eCode;
|
||||
if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
|
||||
assert( pFrom->pSelect==0 );
|
||||
if( pTab->pSelect && (db->flags & SQLITE_EnableView)==0 ){
|
||||
sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited",
|
||||
pTab->zName);
|
||||
}
|
||||
pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0);
|
||||
nCol = pTab->nCol;
|
||||
pTab->nCol = -1;
|
||||
@@ -5343,6 +5356,19 @@ static void updateAccumulator(Parse *pParse, int regAcc, AggInfo *pAggInfo){
|
||||
assert( !IsWindowFunc(pF->pExpr) );
|
||||
if( ExprHasProperty(pF->pExpr, EP_WinFunc) ){
|
||||
Expr *pFilter = pF->pExpr->y.pWin->pFilter;
|
||||
if( pAggInfo->nAccumulator
|
||||
&& (pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL)
|
||||
){
|
||||
if( regHit==0 ) regHit = ++pParse->nMem;
|
||||
/* If this is the first row of the group (regAcc==0), clear the
|
||||
** "magnet" register regHit so that the accumulator registers
|
||||
** are populated if the FILTER clause jumps over the the
|
||||
** invocation of min() or max() altogether. Or, if this is not
|
||||
** the first row (regAcc==1), set the magnet register so that the
|
||||
** accumulators are not populated unless the min()/max() is invoked and
|
||||
** indicates that they should be. */
|
||||
sqlite3VdbeAddOp2(v, OP_Copy, regAcc, regHit);
|
||||
}
|
||||
addrNext = sqlite3VdbeMakeLabel(pParse);
|
||||
sqlite3ExprIfFalse(pParse, pFilter, addrNext, SQLITE_JUMPIFNULL);
|
||||
}
|
||||
@@ -5393,6 +5419,7 @@ static void updateAccumulator(Parse *pParse, int regAcc, AggInfo *pAggInfo){
|
||||
for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){
|
||||
sqlite3ExprCode(pParse, pC->pExpr, pC->iMem);
|
||||
}
|
||||
|
||||
pAggInfo->directMode = 0;
|
||||
if( addrHitTest ){
|
||||
sqlite3VdbeJumpHere(v, addrHitTest);
|
||||
@@ -5438,7 +5465,7 @@ static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){
|
||||
Select *pS = pWalker->u.pSelect;
|
||||
if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, pS->pGroupBy) ){
|
||||
sqlite3 *db = pWalker->pParse->db;
|
||||
Expr *pNew = sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[1], 0);
|
||||
Expr *pNew = sqlite3Expr(db, TK_INTEGER, "1");
|
||||
if( pNew ){
|
||||
Expr *pWhere = pS->pWhere;
|
||||
SWAP(Expr, *pNew, *pExpr);
|
||||
@@ -6196,23 +6223,35 @@ int sqlite3Select(
|
||||
}
|
||||
assert( 66==sqlite3LogEst(100) );
|
||||
if( p->nSelectRow>66 ) p->nSelectRow = 66;
|
||||
|
||||
/* If there is both a GROUP BY and an ORDER BY clause and they are
|
||||
** identical, then it may be possible to disable the ORDER BY clause
|
||||
** on the grounds that the GROUP BY will cause elements to come out
|
||||
** in the correct order. It also may not - the GROUP BY might use a
|
||||
** database index that causes rows to be grouped together as required
|
||||
** but not actually sorted. Either way, record the fact that the
|
||||
** ORDER BY and GROUP BY clauses are the same by setting the orderByGrp
|
||||
** variable. */
|
||||
if( sSort.pOrderBy && pGroupBy->nExpr==sSort.pOrderBy->nExpr ){
|
||||
int ii;
|
||||
/* The GROUP BY processing doesn't care whether rows are delivered in
|
||||
** ASC or DESC order - only that each group is returned contiguously.
|
||||
** So set the ASC/DESC flags in the GROUP BY to match those in the
|
||||
** ORDER BY to maximize the chances of rows being delivered in an
|
||||
** order that makes the ORDER BY redundant. */
|
||||
for(ii=0; ii<pGroupBy->nExpr; ii++){
|
||||
u8 sortFlags = sSort.pOrderBy->a[ii].sortFlags & KEYINFO_ORDER_DESC;
|
||||
pGroupBy->a[ii].sortFlags = sortFlags;
|
||||
}
|
||||
if( sqlite3ExprListCompare(pGroupBy, sSort.pOrderBy, -1)==0 ){
|
||||
orderByGrp = 1;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
assert( 0==sqlite3LogEst(1) );
|
||||
p->nSelectRow = 0;
|
||||
}
|
||||
|
||||
/* If there is both a GROUP BY and an ORDER BY clause and they are
|
||||
** identical, then it may be possible to disable the ORDER BY clause
|
||||
** on the grounds that the GROUP BY will cause elements to come out
|
||||
** in the correct order. It also may not - the GROUP BY might use a
|
||||
** database index that causes rows to be grouped together as required
|
||||
** but not actually sorted. Either way, record the fact that the
|
||||
** ORDER BY and GROUP BY clauses are the same by setting the orderByGrp
|
||||
** variable. */
|
||||
if( sqlite3ExprListCompare(pGroupBy, sSort.pOrderBy, -1)==0 ){
|
||||
orderByGrp = 1;
|
||||
}
|
||||
|
||||
/* Create a label to jump to when we want to abort the query */
|
||||
addrEnd = sqlite3VdbeMakeLabel(pParse);
|
||||
|
||||
@@ -6568,13 +6607,18 @@ int sqlite3Select(
|
||||
{
|
||||
int regAcc = 0; /* "populate accumulators" flag */
|
||||
|
||||
/* If there are accumulator registers but no min() or max() functions,
|
||||
** allocate register regAcc. Register regAcc will contain 0 the first
|
||||
** time the inner loop runs, and 1 thereafter. The code generated
|
||||
** by updateAccumulator() only updates the accumulator registers if
|
||||
** regAcc contains 0. */
|
||||
/* If there are accumulator registers but no min() or max() functions
|
||||
** without FILTER clauses, allocate register regAcc. Register regAcc
|
||||
** will contain 0 the first time the inner loop runs, and 1 thereafter.
|
||||
** The code generated by updateAccumulator() uses this to ensure
|
||||
** that the accumulator registers are (a) updated only once if
|
||||
** there are no min() or max functions or (b) always updated for the
|
||||
** first row visited by the aggregate, so that they are updated at
|
||||
** least once even if the FILTER clause means the min() or max()
|
||||
** function visits zero rows. */
|
||||
if( sAggInfo.nAccumulator ){
|
||||
for(i=0; i<sAggInfo.nFunc; i++){
|
||||
if( ExprHasProperty(sAggInfo.aFunc[i].pExpr, EP_WinFunc) ) continue;
|
||||
if( sAggInfo.aFunc[i].pFunc->funcFlags&SQLITE_FUNC_NEEDCOLL ) break;
|
||||
}
|
||||
if( i==sAggInfo.nFunc ){
|
||||
|
||||
+113
-68
@@ -1289,7 +1289,7 @@ static void editFunc(
|
||||
fseek(f, 0, SEEK_END);
|
||||
sz = ftell(f);
|
||||
rewind(f);
|
||||
p = sqlite3_malloc64( sz+(bBin==0) );
|
||||
p = sqlite3_malloc64( sz+1 );
|
||||
if( p==0 ){
|
||||
sqlite3_result_error_nomem(context);
|
||||
goto edit_func_end;
|
||||
@@ -1766,7 +1766,8 @@ static void eqp_render_level(ShellState *p, int iEqpId){
|
||||
for(pRow = eqp_next_row(p, iEqpId, 0); pRow; pRow = pNext){
|
||||
pNext = eqp_next_row(p, iEqpId, pRow);
|
||||
z = pRow->zText;
|
||||
utf8_printf(p->out, "%s%s%s\n", p->sGraph.zPrefix, pNext ? "|--" : "`--", z);
|
||||
utf8_printf(p->out, "%s%s%s\n", p->sGraph.zPrefix,
|
||||
pNext ? "|--" : "`--", z);
|
||||
if( n<(int)sizeof(p->sGraph.zPrefix)-7 ){
|
||||
memcpy(&p->sGraph.zPrefix[n], pNext ? "| " : " ", 4);
|
||||
eqp_render_level(p, pRow->iEqpId);
|
||||
@@ -1957,7 +1958,7 @@ static int shell_callback(
|
||||
while( j>0 && IsSpace(z[j-1]) ){ j--; }
|
||||
z[j] = 0;
|
||||
if( strlen30(z)>=79 ){
|
||||
for(i=j=0; (c = z[i])!=0; i++){ /* Copy changes from z[i] back to z[j] */
|
||||
for(i=j=0; (c = z[i])!=0; i++){ /* Copy from z[i] back to z[j] */
|
||||
if( c==cEnd ){
|
||||
cEnd = 0;
|
||||
}else if( c=='"' || c=='\'' || c=='`' ){
|
||||
@@ -2536,7 +2537,7 @@ static int display_stats(
|
||||
raw_printf(pArg->out, "Autoindex Inserts: %d\n", iCur);
|
||||
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
|
||||
raw_printf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
|
||||
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_REPREPARE, bReset);
|
||||
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_REPREPARE,bReset);
|
||||
raw_printf(pArg->out, "Reprepare operations: %d\n", iCur);
|
||||
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_RUN, bReset);
|
||||
raw_printf(pArg->out, "Number of times run: %d\n", iCur);
|
||||
@@ -3459,20 +3460,20 @@ static const char *(azHelp[]) = {
|
||||
".archive ... Manage SQL archives",
|
||||
" Each command must have exactly one of the following options:",
|
||||
" -c, --create Create a new archive",
|
||||
" -u, --update Add files or update files with changed mtime",
|
||||
" -i, --insert Like -u but always add even if mtime unchanged",
|
||||
" -u, --update Add or update files with changed mtime",
|
||||
" -i, --insert Like -u but always add even if unchanged",
|
||||
" -t, --list List contents of archive",
|
||||
" -x, --extract Extract files from archive",
|
||||
" Optional arguments:",
|
||||
" -v, --verbose Print each filename as it is processed",
|
||||
" -f FILE, --file FILE Operate on archive FILE (default is current db)",
|
||||
" -a FILE, --append FILE Operate on FILE opened using the apndvfs VFS",
|
||||
" -C DIR, --directory DIR Change to directory DIR to read/extract files",
|
||||
" -f FILE, --file FILE Use archive FILE (default is current db)",
|
||||
" -a FILE, --append FILE Open FILE using the apndvfs VFS",
|
||||
" -C DIR, --directory DIR Read/extract files from directory DIR",
|
||||
" -n, --dryrun Show the SQL that would have occurred",
|
||||
" Examples:",
|
||||
" .ar -cf archive.sar foo bar # Create archive.sar from files foo and bar",
|
||||
" .ar -tf archive.sar # List members of archive.sar",
|
||||
" .ar -xvf archive.sar # Verbosely extract files from archive.sar",
|
||||
" .ar -cf ARCHIVE foo bar # Create ARCHIVE from files foo and bar",
|
||||
" .ar -tf ARCHIVE # List members of ARCHIVE",
|
||||
" .ar -xvf ARCHIVE # Verbosely extract files from ARCHIVE",
|
||||
" See also:",
|
||||
" http://sqlite.org/cli.html#sqlar_archive_support",
|
||||
#endif
|
||||
@@ -3481,7 +3482,7 @@ static const char *(azHelp[]) = {
|
||||
#endif
|
||||
".backup ?DB? FILE Backup DB (default \"main\") to FILE",
|
||||
" --append Use the appendvfs",
|
||||
" --async Write to FILE without a journal and without fsync()",
|
||||
" --async Write to FILE without journal and fsync()",
|
||||
".bail on|off Stop after hitting an error. Default OFF",
|
||||
".binary on|off Turn binary output on or off. Default OFF",
|
||||
".cd DIRECTORY Change the working directory to DIRECTORY",
|
||||
@@ -3501,15 +3502,15 @@ static const char *(azHelp[]) = {
|
||||
" Other Modes:",
|
||||
#ifdef SQLITE_DEBUG
|
||||
" test Show raw EXPLAIN QUERY PLAN output",
|
||||
" trace Like \"full\" but also enable \"PRAGMA vdbe_trace\"",
|
||||
" trace Like \"full\" but enable \"PRAGMA vdbe_trace\"",
|
||||
#endif
|
||||
" trigger Like \"full\" but also show trigger bytecode",
|
||||
".excel Display the output of next command in a spreadsheet",
|
||||
".excel Display the output of next command in spreadsheet",
|
||||
".exit ?CODE? Exit this program with return-code CODE",
|
||||
".expert EXPERIMENTAL. Suggest indexes for specified queries",
|
||||
".expert EXPERIMENTAL. Suggest indexes for queries",
|
||||
/* Because explain mode comes on automatically now, the ".explain" mode
|
||||
** is removed from the help screen. It is still supported for legacy, however */
|
||||
/*".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic",*/
|
||||
** is removed from the help screen. It is still supported for legacy, however */
|
||||
/*".explain ?on|off|auto? Turn EXPLAIN output mode on or off",*/
|
||||
".filectrl CMD ... Run various sqlite3_file_control() operations",
|
||||
" Run \".filectrl\" with no arguments for details",
|
||||
".fullschema ?--indent? Show schema and the content of sqlite_stat tables",
|
||||
@@ -3556,7 +3557,7 @@ static const char *(azHelp[]) = {
|
||||
" --append Use appendvfs to append database to the end of FILE",
|
||||
#ifdef SQLITE_ENABLE_DESERIALIZE
|
||||
" --deserialize Load into memory useing sqlite3_deserialize()",
|
||||
" --hexdb Load the output of \"dbtotxt\" as an in-memory database",
|
||||
" --hexdb Load the output of \"dbtotxt\" as an in-memory db",
|
||||
" --maxsize N Maximum size for --hexdb or --deserialized database",
|
||||
#endif
|
||||
" --new Initialize FILE to an empty database",
|
||||
@@ -3569,7 +3570,7 @@ static const char *(azHelp[]) = {
|
||||
" init Initialize the TEMP table that holds bindings",
|
||||
" list List the current parameter bindings",
|
||||
" set PARAMETER VALUE Given SQL parameter PARAMETER a value of VALUE",
|
||||
" PARAMETER should start with '$', ':', '@', or '?'",
|
||||
" PARAMETER should start with one of: $ : @ ?",
|
||||
" unset PARAMETER Remove PARAMETER from the binding table",
|
||||
".print STRING... Print literal STRING",
|
||||
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
|
||||
@@ -3584,6 +3585,11 @@ static const char *(azHelp[]) = {
|
||||
".read FILE Read input from FILE",
|
||||
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
|
||||
".recover Recover as much data as possible from corrupt db.",
|
||||
" --freelist-corrupt Assume the freelist is corrupt",
|
||||
" --recovery-db NAME Store recovery metadata in database file NAME",
|
||||
" --lost-and-found TABLE Alternative name for the lost-and-found table",
|
||||
" --no-rowids Do not attempt to recover rowid values",
|
||||
" that are not also INTEGER PRIMARY KEYs",
|
||||
#endif
|
||||
".restore ?DB? FILE Restore content of DB (default \"main\") from FILE",
|
||||
".save FILE Write in-memory database into FILE",
|
||||
@@ -3615,7 +3621,7 @@ static const char *(azHelp[]) = {
|
||||
" Options:",
|
||||
" --schema Also hash the sqlite_master table",
|
||||
" --sha3-224 Use the sha3-224 algorithm",
|
||||
" --sha3-256 Use the sha3-256 algorithm. This is the default.",
|
||||
" --sha3-256 Use the sha3-256 algorithm (default)",
|
||||
" --sha3-384 Use the sha3-384 algorithm",
|
||||
" --sha3-512 Use the sha3-512 algorithm",
|
||||
" Any other argument is a LIKE pattern for tables to hash",
|
||||
@@ -3649,6 +3655,10 @@ static const char *(azHelp[]) = {
|
||||
" --row Trace each row (SQLITE_TRACE_ROW)",
|
||||
" --close Trace connection close (SQLITE_TRACE_CLOSE)",
|
||||
#endif /* SQLITE_OMIT_TRACE */
|
||||
#ifdef SQLITE_DEBUG
|
||||
".unmodule NAME ... Unregister virtual table modules",
|
||||
" --allexcept Unregister everything except those named",
|
||||
#endif
|
||||
".vfsinfo ?AUX? Information about the top-level VFS",
|
||||
".vfslist List all available VFSes",
|
||||
".vfsname ?AUX? Print the name of the VFS stack",
|
||||
@@ -5519,7 +5529,7 @@ void shellReset(
|
||||
#endif /* !defined SQLITE_OMIT_VIRTUALTABLE */
|
||||
|
||||
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
|
||||
/*********************************************************************************
|
||||
/******************************************************************************
|
||||
** The ".archive" or ".ar" command.
|
||||
*/
|
||||
/*
|
||||
@@ -5717,7 +5727,8 @@ static int arParseCommand(
|
||||
i = n;
|
||||
}else{
|
||||
if( iArg>=(nArg-1) ){
|
||||
return arErrorMsg(pAr, "option requires an argument: %c",z[i]);
|
||||
return arErrorMsg(pAr, "option requires an argument: %c",
|
||||
z[i]);
|
||||
}
|
||||
zArg = azArg[++iArg];
|
||||
}
|
||||
@@ -6105,10 +6116,10 @@ end_ar_transaction:
|
||||
** Implementation of ".ar" dot command.
|
||||
*/
|
||||
static int arDotCommand(
|
||||
ShellState *pState, /* Current shell tool state */
|
||||
int fromCmdLine, /* True if -A command-line option, not .ar cmd */
|
||||
char **azArg, /* Array of arguments passed to dot command */
|
||||
int nArg /* Number of entries in azArg[] */
|
||||
ShellState *pState, /* Current shell tool state */
|
||||
int fromCmdLine, /* True if -A command-line option, not .ar cmd */
|
||||
char **azArg, /* Array of arguments passed to dot command */
|
||||
int nArg /* Number of entries in azArg[] */
|
||||
){
|
||||
ArCommand cmd;
|
||||
int rc;
|
||||
@@ -6208,7 +6219,7 @@ end_ar_command:
|
||||
return rc;
|
||||
}
|
||||
/* End of the ".archive" or ".ar" command logic
|
||||
**********************************************************************************/
|
||||
*******************************************************************************/
|
||||
#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) */
|
||||
|
||||
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
|
||||
@@ -6583,6 +6594,7 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
|
||||
RecoverTable *pOrphan = 0;
|
||||
|
||||
int bFreelist = 1; /* 0 if --freelist-corrupt is specified */
|
||||
int bRowids = 1; /* 0 if --no-rowids */
|
||||
for(i=1; i<nArg; i++){
|
||||
char *z = azArg[i];
|
||||
int n;
|
||||
@@ -6598,13 +6610,13 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
|
||||
if( n<=15 && memcmp("-lost-and-found", z, n)==0 && i<(nArg-1) ){
|
||||
i++;
|
||||
zLostAndFound = azArg[i];
|
||||
}else
|
||||
if( n<=10 && memcmp("-no-rowids", z, n)==0 ){
|
||||
bRowids = 0;
|
||||
}
|
||||
else{
|
||||
raw_printf(stderr, "unexpected option: %s\n", azArg[i]);
|
||||
raw_printf(stderr, "options are:\n");
|
||||
raw_printf(stderr, " --freelist-corrupt\n");
|
||||
raw_printf(stderr, " --recovery-db DATABASE\n");
|
||||
raw_printf(stderr, " --lost-and-found TABLE-NAME\n");
|
||||
utf8_printf(stderr, "unexpected option: %s\n", azArg[i]);
|
||||
showHelp(pState->out, azArg[0]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -6706,7 +6718,7 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
|
||||
" )"
|
||||
" SELECT pgno FROM p WHERE (parent IS NULL OR pgno = orig)"
|
||||
") "
|
||||
"FROM pages WHERE maxlen > 0 AND i NOT IN freelist;"
|
||||
"FROM pages WHERE maxlen IS NOT NULL AND i NOT IN freelist;"
|
||||
"UPDATE recovery.map AS o SET intkey = ("
|
||||
" SELECT substr(data, 1, 1)==X'0D' FROM sqlite_dbpage WHERE pgno=o.pgno"
|
||||
");"
|
||||
@@ -6766,8 +6778,11 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
|
||||
shellPrepare(pState->db, &rc,
|
||||
"SELECT pgno FROM recovery.map WHERE root=?", &pPages
|
||||
);
|
||||
|
||||
shellPrepare(pState->db, &rc,
|
||||
"SELECT max(field), group_concat(shell_escape_crnl(quote(value)), ', ')"
|
||||
"SELECT max(field), group_concat(shell_escape_crnl(quote"
|
||||
"(case when (? AND field<0) then NULL else value end)"
|
||||
"), ', ')"
|
||||
", min(field) "
|
||||
"FROM sqlite_dbdata WHERE pgno = ? AND field != ?"
|
||||
"GROUP BY cell", &pCells
|
||||
@@ -6802,11 +6817,16 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
|
||||
raw_printf(pState->out, "DELETE FROM sqlite_sequence;\n");
|
||||
}
|
||||
sqlite3_bind_int(pPages, 1, iRoot);
|
||||
sqlite3_bind_int(pCells, 2, pTab->iPk);
|
||||
if( bRowids==0 && pTab->iPk<0 ){
|
||||
sqlite3_bind_int(pCells, 1, 1);
|
||||
}else{
|
||||
sqlite3_bind_int(pCells, 1, 0);
|
||||
}
|
||||
sqlite3_bind_int(pCells, 3, pTab->iPk);
|
||||
|
||||
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPages) ){
|
||||
int iPgno = sqlite3_column_int(pPages, 0);
|
||||
sqlite3_bind_int(pCells, 1, iPgno);
|
||||
sqlite3_bind_int(pCells, 2, iPgno);
|
||||
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pCells) ){
|
||||
int nField = sqlite3_column_int(pCells, 0);
|
||||
int iMin = sqlite3_column_int(pCells, 2);
|
||||
@@ -6889,7 +6909,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
int nArg = 0;
|
||||
int n, c;
|
||||
int rc = 0;
|
||||
char *azArg[50];
|
||||
char *azArg[52];
|
||||
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
if( p->expert.pExpert ){
|
||||
@@ -6899,7 +6919,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
|
||||
/* Parse the input line into tokens.
|
||||
*/
|
||||
while( zLine[h] && nArg<ArraySize(azArg) ){
|
||||
while( zLine[h] && nArg<ArraySize(azArg)-1 ){
|
||||
while( IsSpace(zLine[h]) ){ h++; }
|
||||
if( zLine[h]==0 ) break;
|
||||
if( zLine[h]=='\'' || zLine[h]=='"' ){
|
||||
@@ -6920,6 +6940,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
resolve_backslashes(azArg[nArg-1]);
|
||||
}
|
||||
}
|
||||
azArg[nArg] = 0;
|
||||
|
||||
/* Process the input line.
|
||||
*/
|
||||
@@ -7135,6 +7156,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
} aDbConfig[] = {
|
||||
{ "enable_fkey", SQLITE_DBCONFIG_ENABLE_FKEY },
|
||||
{ "enable_trigger", SQLITE_DBCONFIG_ENABLE_TRIGGER },
|
||||
{ "enable_view", SQLITE_DBCONFIG_ENABLE_VIEW },
|
||||
{ "fts3_tokenizer", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
|
||||
{ "load_extension", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION },
|
||||
{ "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE },
|
||||
@@ -8126,12 +8148,8 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
** Clear all bind parameters by dropping the TEMP table that holds them.
|
||||
*/
|
||||
if( nArg==2 && strcmp(azArg[1],"clear")==0 ){
|
||||
int wrSchema = 0;
|
||||
sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, -1, &wrSchema);
|
||||
sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, 1, 0);
|
||||
sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp.sqlite_parameters;",
|
||||
0, 0, 0);
|
||||
sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, wrSchema, 0);
|
||||
}else
|
||||
|
||||
/* .parameter list
|
||||
@@ -8457,11 +8475,12 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
appendText(&sSelect, ".sqlite_master", 0);
|
||||
}
|
||||
sqlite3_finalize(pStmt);
|
||||
#ifdef SQLITE_INTROSPECTION_PRAGMAS
|
||||
#ifndef SQLITE_OMIT_INTROSPECTION_PRAGMAS
|
||||
if( zName ){
|
||||
appendText(&sSelect,
|
||||
" UNION ALL SELECT shell_module_schema(name),"
|
||||
" 'table', name, name, name, 9e+99, 'main' FROM pragma_module_list", 0);
|
||||
" 'table', name, name, name, 9e+99, 'main' FROM pragma_module_list",
|
||||
0);
|
||||
}
|
||||
#endif
|
||||
appendText(&sSelect, ") WHERE ", 0);
|
||||
@@ -8560,7 +8579,8 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
if( pSession->p==0 ) goto session_not_open;
|
||||
out = fopen(azCmd[1], "wb");
|
||||
if( out==0 ){
|
||||
utf8_printf(stderr, "ERROR: cannot open \"%s\" for writing\n", azCmd[1]);
|
||||
utf8_printf(stderr, "ERROR: cannot open \"%s\" for writing\n",
|
||||
azCmd[1]);
|
||||
}else{
|
||||
int szChng;
|
||||
void *pChng;
|
||||
@@ -8881,8 +8901,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
{
|
||||
utf8_printf(stderr, "Unknown option \"%s\" on \"%s\"\n",
|
||||
azArg[i], azArg[0]);
|
||||
raw_printf(stderr, "Should be one of: --schema"
|
||||
" --sha3-224 --sha3-256 --sha3-384 --sha3-512\n");
|
||||
showHelp(p->out, azArg[0]);
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}
|
||||
@@ -9160,26 +9179,26 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
int ctrlCode; /* Integer code for that option */
|
||||
const char *zUsage; /* Usage notes */
|
||||
} aCtrl[] = {
|
||||
{ "always", SQLITE_TESTCTRL_ALWAYS, "BOOLEAN" },
|
||||
{ "assert", SQLITE_TESTCTRL_ASSERT, "BOOLEAN" },
|
||||
/*{ "benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, "" },*/
|
||||
/*{ "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, "" },*/
|
||||
{ "byteorder", SQLITE_TESTCTRL_BYTEORDER, "" },
|
||||
{ "extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,"BOOLEAN" },
|
||||
/*{ "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, "" }, */
|
||||
{ "imposter", SQLITE_TESTCTRL_IMPOSTER, "SCHEMA ON/OFF ROOTPAGE"},
|
||||
{ "internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, "BOOLEAN" },
|
||||
{ "localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,"BOOLEAN" },
|
||||
{ "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT, "BOOLEAN" },
|
||||
{ "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS, "DISABLE-MASK" },
|
||||
{ "always", SQLITE_TESTCTRL_ALWAYS, "BOOLEAN" },
|
||||
{ "assert", SQLITE_TESTCTRL_ASSERT, "BOOLEAN" },
|
||||
/*{ "benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, "" },*/
|
||||
/*{ "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, "" },*/
|
||||
{ "byteorder", SQLITE_TESTCTRL_BYTEORDER, "" },
|
||||
{ "extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,"BOOLEAN" },
|
||||
/*{ "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, "" },*/
|
||||
{ "imposter", SQLITE_TESTCTRL_IMPOSTER, "SCHEMA ON/OFF ROOTPAGE"},
|
||||
{ "internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, "BOOLEAN" },
|
||||
{ "localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,"BOOLEAN" },
|
||||
{ "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT, "BOOLEAN" },
|
||||
{ "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS, "DISABLE-MASK" },
|
||||
#ifdef YYCOVERAGE
|
||||
{ "parser_coverage", SQLITE_TESTCTRL_PARSER_COVERAGE, "" },
|
||||
{ "parser_coverage", SQLITE_TESTCTRL_PARSER_COVERAGE, "" },
|
||||
#endif
|
||||
{ "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE, "OFFSET " },
|
||||
{ "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE, "" },
|
||||
{ "prng_save", SQLITE_TESTCTRL_PRNG_SAVE, "" },
|
||||
{ "prng_seed", SQLITE_TESTCTRL_PRNG_SEED, "SEED ?db?" },
|
||||
{ "reserve", SQLITE_TESTCTRL_RESERVE, "BYTES-OF-RESERVE" },
|
||||
{ "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE, "OFFSET " },
|
||||
{ "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE, "" },
|
||||
{ "prng_save", SQLITE_TESTCTRL_PRNG_SAVE, "" },
|
||||
{ "prng_seed", SQLITE_TESTCTRL_PRNG_SEED, "SEED ?db?" },
|
||||
{ "reserve", SQLITE_TESTCTRL_RESERVE, "BYTES-OF-RESERVE"},
|
||||
};
|
||||
int testctrl = -1;
|
||||
int iCtrl = -1;
|
||||
@@ -9322,7 +9341,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}
|
||||
}
|
||||
if( isOk==0 && iCtrl>=0 ){
|
||||
utf8_printf(p->out, "Usage: .testctrl %s %s\n", zCmd, aCtrl[iCtrl].zUsage);
|
||||
utf8_printf(p->out, "Usage: .testctrl %s %s\n", zCmd,aCtrl[iCtrl].zUsage);
|
||||
rc = 1;
|
||||
}else if( isOk==1 ){
|
||||
raw_printf(p->out, "%d\n", rc2);
|
||||
@@ -9400,6 +9419,31 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}else
|
||||
#endif /* !defined(SQLITE_OMIT_TRACE) */
|
||||
|
||||
#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_VIRTUALTABLE)
|
||||
if( c=='u' && strncmp(azArg[0], "unmodule", n)==0 ){
|
||||
int ii;
|
||||
int lenOpt;
|
||||
char *zOpt;
|
||||
if( nArg<2 ){
|
||||
raw_printf(stderr, "Usage: .unmodule [--allexcept] NAME ...\n");
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}
|
||||
open_db(p, 0);
|
||||
zOpt = azArg[1];
|
||||
if( zOpt[0]=='-' && zOpt[1]=='-' && zOpt[2]!=0 ) zOpt++;
|
||||
lenOpt = (int)strlen(zOpt);
|
||||
if( lenOpt>=3 && strncmp(zOpt, "-allexcept",lenOpt)==0 ){
|
||||
assert( azArg[nArg]==0 );
|
||||
sqlite3_drop_modules(p->db, nArg>2 ? (const char**)(azArg+2) : 0);
|
||||
}else{
|
||||
for(ii=1; ii<nArg; ii++){
|
||||
sqlite3_create_module(p->db, azArg[ii], 0, 0);
|
||||
}
|
||||
}
|
||||
}else
|
||||
#endif
|
||||
|
||||
#if SQLITE_USER_AUTHENTICATION
|
||||
if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
|
||||
if( nArg<2 ){
|
||||
@@ -9414,7 +9458,8 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}
|
||||
rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3], strlen30(azArg[3]));
|
||||
rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
|
||||
strlen30(azArg[3]));
|
||||
if( rc ){
|
||||
utf8_printf(stderr, "Authentication failed for user %s\n", azArg[2]);
|
||||
rc = 1;
|
||||
|
||||
+55
-3
@@ -2093,6 +2093,17 @@ struct sqlite3_mem_methods {
|
||||
** following this call. The second parameter may be a NULL pointer, in
|
||||
** which case the trigger setting is not reported back. </dd>
|
||||
**
|
||||
** [[SQLITE_DBCONFIG_ENABLE_VIEW]]
|
||||
** <dt>SQLITE_DBCONFIG_ENABLE_VIEW</dt>
|
||||
** <dd> ^This option is used to enable or disable [CREATE VIEW | views].
|
||||
** There should be two additional arguments.
|
||||
** The first argument is an integer which is 0 to disable views,
|
||||
** positive to enable views or negative to leave the setting unchanged.
|
||||
** The second parameter is a pointer to an integer into which
|
||||
** is written 0 or 1 to indicate whether views are disabled or enabled
|
||||
** following this call. The second parameter may be a NULL pointer, in
|
||||
** which case the view setting is not reported back. </dd>
|
||||
**
|
||||
** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]]
|
||||
** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt>
|
||||
** <dd> ^This option is used to enable or disable the
|
||||
@@ -2265,7 +2276,8 @@ struct sqlite3_mem_methods {
|
||||
#define SQLITE_DBCONFIG_LEGACY_ALTER_TABLE 1012 /* int int* */
|
||||
#define SQLITE_DBCONFIG_DQS_DML 1013 /* int int* */
|
||||
#define SQLITE_DBCONFIG_DQS_DDL 1014 /* int int* */
|
||||
#define SQLITE_DBCONFIG_MAX 1014 /* Largest DBCONFIG */
|
||||
#define SQLITE_DBCONFIG_ENABLE_VIEW 1015 /* int int* */
|
||||
#define SQLITE_DBCONFIG_MAX 1015 /* Largest DBCONFIG */
|
||||
|
||||
/*
|
||||
** CAPI3REF: Enable Or Disable Extended Result Codes
|
||||
@@ -4848,9 +4860,12 @@ int sqlite3_reset(sqlite3_stmt *pStmt);
|
||||
** function that is not deterministic. The SQLite query planner is able to
|
||||
** perform additional optimizations on deterministic functions, so use
|
||||
** of the [SQLITE_DETERMINISTIC] flag is recommended where possible.
|
||||
**
|
||||
** ^The fourth parameter may also optionally include the [SQLITE_DIRECTONLY]
|
||||
** flag, which if present prevents the function from being invoked from
|
||||
** within VIEWs or TRIGGERs.
|
||||
** within VIEWs or TRIGGERs. For security reasons, the [SQLITE_DIRECTONLY]
|
||||
** flag is recommended for any application-defined SQL function that has
|
||||
** side-effects.
|
||||
**
|
||||
** ^(The fifth parameter is an arbitrary pointer. The implementation of the
|
||||
** function can gain access to this pointer using [sqlite3_user_data()].)^
|
||||
@@ -4974,10 +4989,24 @@ int sqlite3_create_window_function(
|
||||
** deterministic, for example, but randomblob() is not.
|
||||
**
|
||||
** The SQLITE_DIRECTONLY flag means that the function may only be invoked
|
||||
** from top-level SQL, and cannot be used in VIEWs or TRIGGERs.
|
||||
** from top-level SQL, and cannot be used in VIEWs or TRIGGERs. This is
|
||||
** a security feature which is recommended for all
|
||||
** [application-defined SQL functions] that have side-effects. This flag
|
||||
** prevents an attacker from adding triggers and views to a schema then
|
||||
** tricking a high-privilege application into causing unintended side-effects
|
||||
** while performing ordinary queries.
|
||||
**
|
||||
** The SQLITE_SUBTYPE flag indicates to SQLite that a function may call
|
||||
** [sqlite3_value_subtype()] to inspect the sub-types of its arguments.
|
||||
** Specifying this flag makes no difference for scalar or aggregate user
|
||||
** functions. However, if it is not specified for a user-defined window
|
||||
** function, then any sub-types belonging to arguments passed to the window
|
||||
** function may be discarded before the window function is called (i.e.
|
||||
** sqlite3_value_subtype() will always return 0).
|
||||
*/
|
||||
#define SQLITE_DETERMINISTIC 0x000000800
|
||||
#define SQLITE_DIRECTONLY 0x000080000
|
||||
#define SQLITE_SUBTYPE 0x000100000
|
||||
|
||||
/*
|
||||
** CAPI3REF: Deprecated Functions
|
||||
@@ -6623,6 +6652,12 @@ struct sqlite3_index_info {
|
||||
** ^The sqlite3_create_module()
|
||||
** interface is equivalent to sqlite3_create_module_v2() with a NULL
|
||||
** destructor.
|
||||
**
|
||||
** ^If the third parameter (the pointer to the sqlite3_module object) is
|
||||
** NULL then no new module is create and any existing modules with the
|
||||
** same name are dropped.
|
||||
**
|
||||
** See also: [sqlite3_drop_modules()]
|
||||
*/
|
||||
int sqlite3_create_module(
|
||||
sqlite3 *db, /* SQLite connection to register module with */
|
||||
@@ -6638,6 +6673,23 @@ int sqlite3_create_module_v2(
|
||||
void(*xDestroy)(void*) /* Module destructor function */
|
||||
);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Remove Unnecessary Virtual Table Implementations
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^The sqlite3_drop_modules(D,L) interface removes all virtual
|
||||
** table modules from database connection D except those named on list L.
|
||||
** The L parameter must be either NULL or a pointer to an array of pointers
|
||||
** to strings where the array is terminated by a single NULL pointer.
|
||||
** ^If the L parameter is NULL, then all virtual table modules are removed.
|
||||
**
|
||||
** See also: [sqlite3_create_module()]
|
||||
*/
|
||||
int sqlite3_drop_modules(
|
||||
sqlite3 *db, /* Remove modules from this connection */
|
||||
const char **azKeep /* Except, do not remove the ones named here */
|
||||
);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Virtual Table Instance Object
|
||||
** KEYWORDS: sqlite3_vtab
|
||||
|
||||
@@ -322,6 +322,8 @@ struct sqlite3_api_routines {
|
||||
/* Version 3.28.0 and later */
|
||||
int (*stmt_isexplain)(sqlite3_stmt*);
|
||||
int (*value_frombind)(sqlite3_value*);
|
||||
/* Version 3.30.0 and later */
|
||||
int (*drop_modules)(sqlite3*,const char**);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -614,6 +616,8 @@ typedef int (*sqlite3_loadext_entry)(
|
||||
/* Version 3.28.0 and later */
|
||||
#define sqlite3_stmt_isexplain sqlite3_api->isexplain
|
||||
#define sqlite3_value_frombind sqlite3_api->frombind
|
||||
/* Version 3.30.0 and later */
|
||||
#define sqlite3_drop_modules sqlite3_api->drop_modules
|
||||
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
|
||||
|
||||
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||
|
||||
+30
-13
@@ -1537,16 +1537,17 @@ struct sqlite3 {
|
||||
#define SQLITE_Defensive 0x10000000 /* Input SQL is likely hostile */
|
||||
#define SQLITE_DqsDDL 0x20000000 /* dbl-quoted strings allowed in DDL*/
|
||||
#define SQLITE_DqsDML 0x40000000 /* dbl-quoted strings allowed in DML*/
|
||||
#define SQLITE_EnableView 0x80000000 /* Enable the use of views */
|
||||
|
||||
/* Flags used only if debugging */
|
||||
#define HI(X) ((u64)(X)<<32)
|
||||
#ifdef SQLITE_DEBUG
|
||||
#define SQLITE_SqlTrace HI(0x0001) /* Debug print SQL as it executes */
|
||||
#define SQLITE_VdbeListing HI(0x0002) /* Debug listings of VDBE progs */
|
||||
#define SQLITE_VdbeTrace HI(0x0004) /* True to trace VDBE execution */
|
||||
#define SQLITE_VdbeAddopTrace HI(0x0008) /* Trace sqlite3VdbeAddOp() calls */
|
||||
#define SQLITE_VdbeEQP HI(0x0010) /* Debug EXPLAIN QUERY PLAN */
|
||||
#define SQLITE_ParserTrace HI(0x0020) /* PRAGMA parser_trace=ON */
|
||||
#define SQLITE_SqlTrace HI(0x0100000) /* Debug print SQL as it executes */
|
||||
#define SQLITE_VdbeListing HI(0x0200000) /* Debug listings of VDBE progs */
|
||||
#define SQLITE_VdbeTrace HI(0x0400000) /* True to trace VDBE execution */
|
||||
#define SQLITE_VdbeAddopTrace HI(0x0800000) /* Trace sqlite3VdbeAddOp() calls */
|
||||
#define SQLITE_VdbeEQP HI(0x1000000) /* Debug EXPLAIN QUERY PLAN */
|
||||
#define SQLITE_ParserTrace HI(0x2000000) /* PRAGMA parser_trace=ON */
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -1685,6 +1686,7 @@ struct FuncDestructor {
|
||||
#define SQLITE_FUNC_WINDOW 0x00010000 /* Built-in window-only function */
|
||||
#define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */
|
||||
#define SQLITE_FUNC_DIRECT 0x00080000 /* Not for use in TRIGGERs or VIEWs */
|
||||
#define SQLITE_FUNC_SUBTYPE 0x00100000 /* Result likely to have sub-type */
|
||||
|
||||
/*
|
||||
** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
|
||||
@@ -1798,6 +1800,7 @@ struct Savepoint {
|
||||
struct Module {
|
||||
const sqlite3_module *pModule; /* Callback pointers */
|
||||
const char *zName; /* Name passed to create_module() */
|
||||
int nRefModule; /* Number of pointers to this object */
|
||||
void *pAux; /* pAux passed to create_module() */
|
||||
void (*xDestroy)(void *); /* Module destructor function */
|
||||
Table *pEpoTab; /* Eponymous table for this module */
|
||||
@@ -2136,10 +2139,16 @@ struct KeyInfo {
|
||||
u16 nKeyField; /* Number of key columns in the index */
|
||||
u16 nAllField; /* Total columns, including key plus others */
|
||||
sqlite3 *db; /* The database connection */
|
||||
u8 *aSortOrder; /* Sort order for each column. */
|
||||
u8 *aSortFlags; /* Sort order for each column. */
|
||||
CollSeq *aColl[1]; /* Collating sequence for each term of the key */
|
||||
};
|
||||
|
||||
/*
|
||||
** Allowed bit values for entries in the KeyInfo.aSortFlags[] array.
|
||||
*/
|
||||
#define KEYINFO_ORDER_DESC 0x01 /* DESC sort order */
|
||||
#define KEYINFO_ORDER_BIGNULL 0x02 /* NULL is larger than any other value */
|
||||
|
||||
/*
|
||||
** This object holds a record which has been parsed out into individual
|
||||
** fields, for the purposes of doing a comparison.
|
||||
@@ -2468,6 +2477,8 @@ struct Expr {
|
||||
** TK_REGISTER: register number
|
||||
** TK_TRIGGER: 1 -> new, 0 -> old
|
||||
** EP_Unlikely: 134217728 times likelihood
|
||||
** TK_IN: ephemerial table holding RHS
|
||||
** TK_SELECT_COLUMN: Number of columns on the LHS
|
||||
** TK_SELECT: 1st register of result vector */
|
||||
ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid.
|
||||
** TK_VARIABLE: variable number (always >= 1).
|
||||
@@ -2505,7 +2516,7 @@ struct Expr {
|
||||
#define EP_DblQuoted 0x000040 /* token.z was originally in "..." */
|
||||
#define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */
|
||||
#define EP_Collate 0x000100 /* Tree contains a TK_COLLATE operator */
|
||||
#define EP_Generic 0x000200 /* Ignore COLLATE or affinity on this tree */
|
||||
/* 0x000200 Available for reuse */
|
||||
#define EP_IntValue 0x000400 /* Integer value contained in u.iValue */
|
||||
#define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */
|
||||
#define EP_Skip 0x001000 /* Operator does not contribute to affinity */
|
||||
@@ -2600,11 +2611,12 @@ struct ExprList {
|
||||
Expr *pExpr; /* The parse tree for this expression */
|
||||
char *zName; /* Token associated with this expression */
|
||||
char *zSpan; /* Original text of the expression */
|
||||
u8 sortOrder; /* 1 for DESC or 0 for ASC */
|
||||
u8 sortFlags; /* Mask of KEYINFO_ORDER_* flags */
|
||||
unsigned done :1; /* A flag to indicate when processing is finished */
|
||||
unsigned bSpanIsTab :1; /* zSpan holds DB.TABLE.COLUMN */
|
||||
unsigned reusable :1; /* Constant expression is reusable */
|
||||
unsigned bSorterRef :1; /* Defer evaluation until after sorting */
|
||||
unsigned bNulls: 1; /* True if explicit "NULLS FIRST/LAST" */
|
||||
union {
|
||||
struct {
|
||||
u16 iOrderByCol; /* For ORDER BY, column number in result set */
|
||||
@@ -3593,8 +3605,8 @@ struct Window {
|
||||
Expr *pFilter; /* The FILTER expression */
|
||||
FuncDef *pFunc; /* The function */
|
||||
int iEphCsr; /* Partition buffer or Peer buffer */
|
||||
int regAccum;
|
||||
int regResult;
|
||||
int regAccum; /* Accumulator */
|
||||
int regResult; /* Interim result */
|
||||
int csrApp; /* Function cursor (used by min/max) */
|
||||
int regApp; /* Function register (also used by min/max) */
|
||||
int regPart; /* Array of registers for PARTITION BY values */
|
||||
@@ -3604,6 +3616,8 @@ struct Window {
|
||||
int regOne; /* Register containing constant value 1 */
|
||||
int regStartRowid;
|
||||
int regEndRowid;
|
||||
u8 bExprArgs; /* Defer evaluation of window function arguments
|
||||
** due to the SQLITE_SUBTYPE flag */
|
||||
};
|
||||
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
@@ -3885,7 +3899,7 @@ void sqlite3ExprDelete(sqlite3*, Expr*);
|
||||
void sqlite3ExprUnmapAndDelete(Parse*, Expr*);
|
||||
ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
|
||||
ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*);
|
||||
void sqlite3ExprListSetSortOrder(ExprList*,int);
|
||||
void sqlite3ExprListSetSortOrder(ExprList*,int,int);
|
||||
void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
|
||||
void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*);
|
||||
void sqlite3ExprListDelete(sqlite3*, ExprList*);
|
||||
@@ -4272,6 +4286,7 @@ int sqlite3ExprCollSeqMatch(Parse*,Expr*,Expr*);
|
||||
Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int);
|
||||
Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
|
||||
Expr *sqlite3ExprSkipCollate(Expr*);
|
||||
Expr *sqlite3ExprSkipCollateAndLikely(Expr*);
|
||||
int sqlite3CheckCollSeq(Parse *, CollSeq *);
|
||||
int sqlite3WritableSchema(sqlite3*);
|
||||
int sqlite3CheckObjectName(Parse*, const char*,const char*,const char*);
|
||||
@@ -4307,7 +4322,6 @@ extern const unsigned char sqlite3OpcodeProperty[];
|
||||
extern const char sqlite3StrBINARY[];
|
||||
extern const unsigned char sqlite3UpperToLower[];
|
||||
extern const unsigned char sqlite3CtypeMap[];
|
||||
extern const Token sqlite3IntTokens[];
|
||||
extern SQLITE_WSD struct Sqlite3Config sqlite3Config;
|
||||
extern FuncDefHash sqlite3BuiltinFunctions;
|
||||
#ifndef SQLITE_OMIT_WSD
|
||||
@@ -4361,6 +4375,7 @@ void sqlite3KeyInfoUnref(KeyInfo*);
|
||||
KeyInfo *sqlite3KeyInfoRef(KeyInfo*);
|
||||
KeyInfo *sqlite3KeyInfoOfIndex(Parse*, Index*);
|
||||
KeyInfo *sqlite3KeyInfoFromExprList(Parse*, ExprList*, int, int);
|
||||
int sqlite3HasExplicitNulls(Parse*, ExprList*);
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
int sqlite3KeyInfoIsWriteable(KeyInfo*);
|
||||
@@ -4440,6 +4455,7 @@ void sqlite3AutoLoadExtensions(sqlite3*);
|
||||
# define sqlite3VtabInSync(db) 0
|
||||
# define sqlite3VtabLock(X)
|
||||
# define sqlite3VtabUnlock(X)
|
||||
# define sqlite3VtabModuleUnref(D,X)
|
||||
# define sqlite3VtabUnlockList(X)
|
||||
# define sqlite3VtabSavepoint(X, Y, Z) SQLITE_OK
|
||||
# define sqlite3GetVTable(X,Y) ((VTable*)0)
|
||||
@@ -4451,6 +4467,7 @@ void sqlite3AutoLoadExtensions(sqlite3*);
|
||||
int sqlite3VtabCommit(sqlite3 *db);
|
||||
void sqlite3VtabLock(VTable *);
|
||||
void sqlite3VtabUnlock(VTable *);
|
||||
void sqlite3VtabModuleUnref(sqlite3*,Module*);
|
||||
void sqlite3VtabUnlockList(sqlite3*);
|
||||
int sqlite3VtabSavepoint(sqlite3 *, int, int);
|
||||
void sqlite3VtabImportErrmsg(Vdbe*, sqlite3_vtab*);
|
||||
|
||||
+90
-22
@@ -1917,33 +1917,33 @@ static int SQLITE_TCLAPI DbObjCmd(
|
||||
"authorizer", "backup", "bind_fallback",
|
||||
"busy", "cache", "changes",
|
||||
"close", "collate", "collation_needed",
|
||||
"commit_hook", "complete", "copy",
|
||||
"deserialize", "enable_load_extension", "errorcode",
|
||||
"eval", "exists", "function",
|
||||
"incrblob", "interrupt", "last_insert_rowid",
|
||||
"nullvalue", "onecolumn", "preupdate",
|
||||
"profile", "progress", "rekey",
|
||||
"restore", "rollback_hook", "serialize",
|
||||
"status", "timeout", "total_changes",
|
||||
"trace", "trace_v2", "transaction",
|
||||
"unlock_notify", "update_hook", "version",
|
||||
"wal_hook", 0
|
||||
"commit_hook", "complete", "config",
|
||||
"copy", "deserialize", "enable_load_extension",
|
||||
"errorcode", "eval", "exists",
|
||||
"function", "incrblob", "interrupt",
|
||||
"last_insert_rowid", "nullvalue", "onecolumn",
|
||||
"preupdate", "profile", "progress",
|
||||
"rekey", "restore", "rollback_hook",
|
||||
"serialize", "status", "timeout",
|
||||
"total_changes", "trace", "trace_v2",
|
||||
"transaction", "unlock_notify", "update_hook",
|
||||
"version", "wal_hook", 0
|
||||
};
|
||||
enum DB_enum {
|
||||
DB_AUTHORIZER, DB_BACKUP, DB_BIND_FALLBACK,
|
||||
DB_BUSY, DB_CACHE, DB_CHANGES,
|
||||
DB_CLOSE, DB_COLLATE, DB_COLLATION_NEEDED,
|
||||
DB_COMMIT_HOOK, DB_COMPLETE, DB_COPY,
|
||||
DB_DESERIALIZE, DB_ENABLE_LOAD_EXTENSION,DB_ERRORCODE,
|
||||
DB_EVAL, DB_EXISTS, DB_FUNCTION,
|
||||
DB_INCRBLOB, DB_INTERRUPT, DB_LAST_INSERT_ROWID,
|
||||
DB_NULLVALUE, DB_ONECOLUMN, DB_PREUPDATE,
|
||||
DB_PROFILE, DB_PROGRESS, DB_REKEY,
|
||||
DB_RESTORE, DB_ROLLBACK_HOOK, DB_SERIALIZE,
|
||||
DB_STATUS, DB_TIMEOUT, DB_TOTAL_CHANGES,
|
||||
DB_TRACE, DB_TRACE_V2, DB_TRANSACTION,
|
||||
DB_UNLOCK_NOTIFY, DB_UPDATE_HOOK, DB_VERSION,
|
||||
DB_WAL_HOOK
|
||||
DB_COMMIT_HOOK, DB_COMPLETE, DB_CONFIG,
|
||||
DB_COPY, DB_DESERIALIZE, DB_ENABLE_LOAD_EXTENSION,
|
||||
DB_ERRORCODE, DB_EVAL, DB_EXISTS,
|
||||
DB_FUNCTION, DB_INCRBLOB, DB_INTERRUPT,
|
||||
DB_LAST_INSERT_ROWID, DB_NULLVALUE, DB_ONECOLUMN,
|
||||
DB_PREUPDATE, DB_PROFILE, DB_PROGRESS,
|
||||
DB_REKEY, DB_RESTORE, DB_ROLLBACK_HOOK,
|
||||
DB_SERIALIZE, DB_STATUS, DB_TIMEOUT,
|
||||
DB_TOTAL_CHANGES, DB_TRACE, DB_TRACE_V2,
|
||||
DB_TRANSACTION, DB_UNLOCK_NOTIFY, DB_UPDATE_HOOK,
|
||||
DB_VERSION, DB_WAL_HOOK
|
||||
};
|
||||
/* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */
|
||||
|
||||
@@ -2331,6 +2331,74 @@ static int SQLITE_TCLAPI DbObjCmd(
|
||||
break;
|
||||
}
|
||||
|
||||
/* $db config ?OPTION? ?BOOLEAN?
|
||||
**
|
||||
** Configure the database connection using the sqlite3_db_config()
|
||||
** interface.
|
||||
*/
|
||||
case DB_CONFIG: {
|
||||
static const struct DbConfigChoices {
|
||||
const char *zName;
|
||||
int op;
|
||||
} aDbConfig[] = {
|
||||
{ "enable_fkey", SQLITE_DBCONFIG_ENABLE_FKEY },
|
||||
{ "enable_trigger", SQLITE_DBCONFIG_ENABLE_TRIGGER },
|
||||
{ "enable_view", SQLITE_DBCONFIG_ENABLE_VIEW },
|
||||
{ "fts3_tokenizer", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
|
||||
{ "load_extension", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION },
|
||||
{ "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE },
|
||||
{ "enable_qpsg", SQLITE_DBCONFIG_ENABLE_QPSG },
|
||||
{ "trigger_eqp", SQLITE_DBCONFIG_TRIGGER_EQP },
|
||||
{ "reset_database", SQLITE_DBCONFIG_RESET_DATABASE },
|
||||
{ "defensive", SQLITE_DBCONFIG_DEFENSIVE },
|
||||
{ "writable_schema", SQLITE_DBCONFIG_WRITABLE_SCHEMA },
|
||||
{ "legacy_alter_table", SQLITE_DBCONFIG_LEGACY_ALTER_TABLE },
|
||||
{ "dqs_dml", SQLITE_DBCONFIG_DQS_DML },
|
||||
{ "dqs_ddl", SQLITE_DBCONFIG_DQS_DDL },
|
||||
};
|
||||
Tcl_Obj *pResult;
|
||||
int ii;
|
||||
if( objc>4 ){
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "?OPTION? ?BOOLEAN?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( objc==2 ){
|
||||
/* With no arguments, list all configuration options and with the
|
||||
** current value */
|
||||
pResult = Tcl_NewListObj(0,0);
|
||||
for(ii=0; ii<sizeof(aDbConfig)/sizeof(aDbConfig[0]); ii++){
|
||||
int v = 0;
|
||||
sqlite3_db_config(pDb->db, aDbConfig[ii].op, -1, &v);
|
||||
Tcl_ListObjAppendElement(interp, pResult,
|
||||
Tcl_NewStringObj(aDbConfig[ii].zName,-1));
|
||||
Tcl_ListObjAppendElement(interp, pResult,
|
||||
Tcl_NewIntObj(v));
|
||||
}
|
||||
}else{
|
||||
const char *zOpt = Tcl_GetString(objv[2]);
|
||||
int onoff = -1;
|
||||
int v = 0;
|
||||
if( zOpt[0]=='-' ) zOpt++;
|
||||
for(ii=0; ii<sizeof(aDbConfig)/sizeof(aDbConfig[0]); ii++){
|
||||
if( strcmp(aDbConfig[ii].zName, zOpt)==0 ) break;
|
||||
}
|
||||
if( ii>=sizeof(aDbConfig)/sizeof(aDbConfig[0]) ){
|
||||
Tcl_AppendResult(interp, "unknown config option: \"", zOpt,
|
||||
"\"", (void*)0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( objc==4 ){
|
||||
if( Tcl_GetBooleanFromObj(interp, objv[3], &onoff) ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
sqlite3_db_config(pDb->db, aDbConfig[ii].op, onoff, &v);
|
||||
pResult = Tcl_NewIntObj(v);
|
||||
}
|
||||
Tcl_SetObjResult(interp, pResult);
|
||||
break;
|
||||
}
|
||||
|
||||
/* $db copy conflict-algorithm table filename ?SEPARATOR? ?NULLINDICATOR?
|
||||
**
|
||||
** Copy data into table from filename, optionally using SEPARATOR
|
||||
|
||||
+29
@@ -1110,6 +1110,33 @@ static int SQLITE_TCLAPI test_create_function(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_drop_modules DB ?NAME ...?
|
||||
**
|
||||
** Invoke the sqlite3_drop_modules(D,L) interface on database
|
||||
** connection DB, in order to drop all modules except those named in
|
||||
** the argument.
|
||||
*/
|
||||
static int SQLITE_TCLAPI test_drop_modules(
|
||||
void *NotUsed,
|
||||
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
||||
int argc, /* Number of arguments */
|
||||
char **argv /* Text of each argument */
|
||||
){
|
||||
sqlite3 *db;
|
||||
|
||||
if( argc!=2 ){
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
|
||||
" DB\"", 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
sqlite3_drop_modules(db, argc>2 ? (const char**)(argv+2) : 0);
|
||||
#endif
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Routines to implement the x_count() aggregate function.
|
||||
**
|
||||
@@ -7175,6 +7202,7 @@ static int SQLITE_TCLAPI optimization_control(
|
||||
{ "omit-noop-join", SQLITE_OmitNoopJoin },
|
||||
{ "stat4", SQLITE_Stat4 },
|
||||
{ "skip-scan", SQLITE_SkipScan },
|
||||
{ "push-down", SQLITE_PushDown },
|
||||
};
|
||||
|
||||
if( objc!=4 ){
|
||||
@@ -7860,6 +7888,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
{ "sqlite3_close_v2", (Tcl_CmdProc*)sqlite_test_close_v2 },
|
||||
{ "sqlite3_create_function", (Tcl_CmdProc*)test_create_function },
|
||||
{ "sqlite3_create_aggregate", (Tcl_CmdProc*)test_create_aggregate },
|
||||
{ "sqlite3_drop_modules", (Tcl_CmdProc*)test_drop_modules },
|
||||
{ "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func },
|
||||
{ "sqlite_abort", (Tcl_CmdProc*)sqlite_abort },
|
||||
{ "sqlite_bind", (Tcl_CmdProc*)test_bind },
|
||||
|
||||
@@ -337,6 +337,17 @@ static int getFts3Varint(const char *p, sqlite_int64 *v){
|
||||
return (int) (q - (unsigned char *)p);
|
||||
}
|
||||
|
||||
static int putFts3Varint(char *p, sqlite_int64 v){
|
||||
unsigned char *q = (unsigned char *) p;
|
||||
sqlite_uint64 vu = v;
|
||||
do{
|
||||
*q++ = (unsigned char) ((vu & 0x7f) | 0x80);
|
||||
vu >>= 7;
|
||||
}while( vu!=0 );
|
||||
q[-1] &= 0x7f; /* turn off high bit in final byte */
|
||||
assert( q - (unsigned char *)p <= 10 );
|
||||
return (int) (q - (unsigned char *)p);
|
||||
}
|
||||
|
||||
/*
|
||||
** USAGE: read_fts3varint BLOB VARNAME
|
||||
@@ -367,6 +378,67 @@ static int SQLITE_TCLAPI read_fts3varint(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** USAGE: make_fts3record ARGLIST
|
||||
*/
|
||||
static int SQLITE_TCLAPI make_fts3record(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
Tcl_Obj **aArg = 0;
|
||||
int nArg = 0;
|
||||
unsigned char *aOut = 0;
|
||||
int nOut = 0;
|
||||
int nAlloc = 0;
|
||||
int i;
|
||||
|
||||
if( objc!=2 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "LIST");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( Tcl_ListObjGetElements(interp, objv[1], &nArg, &aArg) ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
for(i=0; i<nArg; i++){
|
||||
sqlite3_int64 iVal;
|
||||
if( TCL_OK==Tcl_GetWideIntFromObj(0, aArg[i], &iVal) ){
|
||||
if( nOut+10>nAlloc ){
|
||||
int nNew = nAlloc?nAlloc*2:128;
|
||||
unsigned char *aNew = sqlite3_realloc(aOut, nNew);
|
||||
if( aNew==0 ){
|
||||
sqlite3_free(aOut);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
aOut = aNew;
|
||||
nAlloc = nNew;
|
||||
}
|
||||
nOut += putFts3Varint((char*)&aOut[nOut], iVal);
|
||||
}else{
|
||||
int nVal = 0;
|
||||
char *zVal = Tcl_GetStringFromObj(aArg[i], &nVal);
|
||||
while( (nOut + nVal)>nAlloc ){
|
||||
int nNew = nAlloc?nAlloc*2:128;
|
||||
unsigned char *aNew = sqlite3_realloc(aOut, nNew);
|
||||
if( aNew==0 ){
|
||||
sqlite3_free(aOut);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
aOut = aNew;
|
||||
nAlloc = nNew;
|
||||
}
|
||||
memcpy(&aOut[nOut], zVal, nVal);
|
||||
nOut += nVal;
|
||||
}
|
||||
}
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(aOut, nOut));
|
||||
sqlite3_free(aOut);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Register commands with the TCL interpreter.
|
||||
@@ -383,6 +455,7 @@ int Sqlitetest_hexio_Init(Tcl_Interp *interp){
|
||||
{ "hexio_render_int32", hexio_render_int32 },
|
||||
{ "utf8_to_utf8", utf8_to_utf8 },
|
||||
{ "read_fts3varint", read_fts3varint },
|
||||
{ "make_fts3record", make_fts3record },
|
||||
};
|
||||
int i;
|
||||
for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
|
||||
|
||||
+8
-1
@@ -536,7 +536,14 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
|
||||
}
|
||||
|
||||
case TK_COLLATE: {
|
||||
sqlite3TreeViewLine(pView, "COLLATE %Q", pExpr->u.zToken);
|
||||
/* COLLATE operators without the EP_Collate flag are intended to
|
||||
** emulate collation associated with a table column. These show
|
||||
** up in the treeview output as "SOFT-COLLATE". Explicit COLLATE
|
||||
** operators that appear in the original SQL always have the
|
||||
** EP_Collate bit set and appear in treeview output as just "COLLATE" */
|
||||
sqlite3TreeViewLine(pView, "%sCOLLATE %Q%s",
|
||||
!ExprHasProperty(pExpr, EP_Collate) ? "SOFT-" : "",
|
||||
pExpr->u.zToken, zFlgs);
|
||||
sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
+10
-7
@@ -463,6 +463,9 @@ TriggerStep *sqlite3TriggerInsertStep(
|
||||
pTriggerStep->pIdList = pColumn;
|
||||
pTriggerStep->pUpsert = pUpsert;
|
||||
pTriggerStep->orconf = orconf;
|
||||
if( pUpsert ){
|
||||
sqlite3HasExplicitNulls(pParse, pUpsert->pUpsertTarget);
|
||||
}
|
||||
}else{
|
||||
testcase( pColumn );
|
||||
sqlite3IdListDelete(db, pColumn);
|
||||
@@ -618,10 +621,9 @@ void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){
|
||||
iDb = sqlite3SchemaToIndex(pParse->db, pTrigger->pSchema);
|
||||
assert( iDb>=0 && iDb<db->nDb );
|
||||
pTable = tableOfTrigger(pTrigger);
|
||||
assert( pTable );
|
||||
assert( pTable->pSchema==pTrigger->pSchema || iDb==1 );
|
||||
assert( (pTable && pTable->pSchema==pTrigger->pSchema) || iDb==1 );
|
||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||
{
|
||||
if( pTable ){
|
||||
int code = SQLITE_DROP_TRIGGER;
|
||||
const char *zDb = db->aDb[iDb].zDbSName;
|
||||
const char *zTab = SCHEMA_TABLE(iDb);
|
||||
@@ -635,7 +637,6 @@ void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){
|
||||
|
||||
/* Generate code to destroy the database record of the trigger.
|
||||
*/
|
||||
assert( pTable!=0 );
|
||||
if( (v = sqlite3GetVdbe(pParse))!=0 ){
|
||||
sqlite3NestedParse(pParse,
|
||||
"DELETE FROM %Q.%s WHERE name=%Q AND type='trigger'",
|
||||
@@ -659,9 +660,11 @@ void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const char *zName){
|
||||
if( ALWAYS(pTrigger) ){
|
||||
if( pTrigger->pSchema==pTrigger->pTabSchema ){
|
||||
Table *pTab = tableOfTrigger(pTrigger);
|
||||
Trigger **pp;
|
||||
for(pp=&pTab->pTrigger; *pp!=pTrigger; pp=&((*pp)->pNext));
|
||||
*pp = (*pp)->pNext;
|
||||
if( pTab ){
|
||||
Trigger **pp;
|
||||
for(pp=&pTab->pTrigger; *pp!=pTrigger; pp=&((*pp)->pNext));
|
||||
*pp = (*pp)->pNext;
|
||||
}
|
||||
}
|
||||
sqlite3DeleteTrigger(db, pTrigger);
|
||||
db->mDbFlags |= DBFLAG_SchemaChange;
|
||||
|
||||
+12
-13
@@ -715,28 +715,30 @@ void sqlite3Update(
|
||||
}
|
||||
|
||||
if( !isView ){
|
||||
int addr1 = 0; /* Address of jump instruction */
|
||||
|
||||
/* Do constraint checks. */
|
||||
assert( regOldRowid>0 );
|
||||
sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur,
|
||||
regNewRowid, regOldRowid, chngKey, onError, labelContinue, &bReplace,
|
||||
aXRef, 0);
|
||||
|
||||
/* If REPLACE conflict handling may have been used, or if the PK of the
|
||||
** row is changing, then the GenerateConstraintChecks() above may have
|
||||
** moved cursor iDataCur. Reseek it. */
|
||||
if( bReplace || chngKey ){
|
||||
if( pPk ){
|
||||
sqlite3VdbeAddOp4Int(v, OP_NotFound,iDataCur,labelContinue,regKey,nKey);
|
||||
}else{
|
||||
sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue,regOldRowid);
|
||||
}
|
||||
VdbeCoverageNeverTaken(v);
|
||||
}
|
||||
|
||||
/* Do FK constraint checks. */
|
||||
if( hasFK ){
|
||||
sqlite3FkCheck(pParse, pTab, regOldRowid, 0, aXRef, chngKey);
|
||||
}
|
||||
|
||||
/* Delete the index entries associated with the current record. */
|
||||
if( bReplace || chngKey ){
|
||||
if( pPk ){
|
||||
addr1 = sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, 0, regKey, nKey);
|
||||
}else{
|
||||
addr1 = sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, 0, regOldRowid);
|
||||
}
|
||||
VdbeCoverageNeverTaken(v);
|
||||
}
|
||||
sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, aRegIdx, -1);
|
||||
|
||||
/* If changing the rowid value, or if there are foreign key constraints
|
||||
@@ -766,9 +768,6 @@ void sqlite3Update(
|
||||
sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, 0);
|
||||
}
|
||||
#endif
|
||||
if( bReplace || chngKey ){
|
||||
sqlite3VdbeJumpHere(v, addr1);
|
||||
}
|
||||
|
||||
if( hasFK ){
|
||||
sqlite3FkCheck(pParse, pTab, 0, regNewRowid, aXRef, chngKey);
|
||||
|
||||
+7
-1
@@ -205,6 +205,7 @@ void sqlite3UpsertDoUpdate(
|
||||
sqlite3 *db = pParse->db;
|
||||
SrcList *pSrc; /* FROM clause for the UPDATE */
|
||||
int iDataCur;
|
||||
int i;
|
||||
|
||||
assert( v!=0 );
|
||||
assert( pUpsert!=0 );
|
||||
@@ -221,7 +222,6 @@ void sqlite3UpsertDoUpdate(
|
||||
Index *pPk = sqlite3PrimaryKeyIndex(pTab);
|
||||
int nPk = pPk->nKeyCol;
|
||||
int iPk = pParse->nMem+1;
|
||||
int i;
|
||||
pParse->nMem += nPk;
|
||||
for(i=0; i<nPk; i++){
|
||||
int k;
|
||||
@@ -242,6 +242,12 @@ void sqlite3UpsertDoUpdate(
|
||||
/* pUpsert does not own pUpsertSrc - the outer INSERT statement does. So
|
||||
** we have to make a copy before passing it down into sqlite3Update() */
|
||||
pSrc = sqlite3SrcListDup(db, pUpsert->pUpsertSrc, 0);
|
||||
/* excluded.* columns of type REAL need to be converted to a hard real */
|
||||
for(i=0; i<pTab->nCol; i++){
|
||||
if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){
|
||||
sqlite3VdbeAddOp1(v, OP_RealAffinity, pUpsert->regData+i);
|
||||
}
|
||||
}
|
||||
sqlite3Update(pParse, pSrc, pUpsert->pUpsertSet,
|
||||
pUpsert->pUpsertWhere, OE_Abort, 0, 0, pUpsert);
|
||||
pUpsert->pUpsertSet = 0; /* Will have been deleted by sqlite3Update() */
|
||||
|
||||
+27
-19
@@ -483,13 +483,15 @@ void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){
|
||||
c = 's';
|
||||
}
|
||||
*(zCsr++) = c;
|
||||
*(zCsr++) = 'x';
|
||||
sqlite3_snprintf(100, zCsr, "%d[", pMem->n);
|
||||
zCsr += sqlite3Strlen30(zCsr);
|
||||
for(i=0; i<16 && i<pMem->n; i++){
|
||||
for(i=0; i<25 && i<pMem->n; i++){
|
||||
sqlite3_snprintf(100, zCsr, "%02X", ((int)pMem->z[i] & 0xFF));
|
||||
zCsr += sqlite3Strlen30(zCsr);
|
||||
}
|
||||
for(i=0; i<16 && i<pMem->n; i++){
|
||||
*zCsr++ = '|';
|
||||
for(i=0; i<25 && i<pMem->n; i++){
|
||||
char z = pMem->z[i];
|
||||
if( z<32 || z>126 ) *zCsr++ = '.';
|
||||
else *zCsr++ = z;
|
||||
@@ -519,7 +521,7 @@ void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){
|
||||
sqlite3_snprintf(100, &zBuf[k], "%d", pMem->n);
|
||||
k += sqlite3Strlen30(&zBuf[k]);
|
||||
zBuf[k++] = '[';
|
||||
for(j=0; j<15 && j<pMem->n; j++){
|
||||
for(j=0; j<25 && j<pMem->n; j++){
|
||||
u8 c = pMem->z[j];
|
||||
if( c>=0x20 && c<0x7f ){
|
||||
zBuf[k++] = c;
|
||||
@@ -552,7 +554,7 @@ static void memTracePrint(Mem *p){
|
||||
printf(" i:%lld", p->u.i);
|
||||
#ifndef SQLITE_OMIT_FLOATING_POINT
|
||||
}else if( p->flags & MEM_Real ){
|
||||
printf(" r:%g", p->u.r);
|
||||
printf(" r:%.17g", p->u.r);
|
||||
#endif
|
||||
}else if( sqlite3VdbeMemIsRowSet(p) ){
|
||||
printf(" (rowset)");
|
||||
@@ -1141,7 +1143,6 @@ case OP_Real: { /* same as TK_FLOAT, out2 */
|
||||
case OP_String8: { /* same as TK_STRING, out2 */
|
||||
assert( pOp->p4.z!=0 );
|
||||
pOut = out2Prerelease(p, pOp);
|
||||
pOp->opcode = OP_String;
|
||||
pOp->p1 = sqlite3Strlen30(pOp->p4.z);
|
||||
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
@@ -1165,6 +1166,7 @@ case OP_String8: { /* same as TK_STRING, out2 */
|
||||
if( pOp->p1>db->aLimit[SQLITE_LIMIT_LENGTH] ){
|
||||
goto too_big;
|
||||
}
|
||||
pOp->opcode = OP_String;
|
||||
assert( rc==SQLITE_OK );
|
||||
/* Fall through to the next case, OP_String */
|
||||
}
|
||||
@@ -1832,6 +1834,7 @@ case OP_RealAffinity: { /* in1 */
|
||||
testcase( pIn1->flags & MEM_Int );
|
||||
testcase( pIn1->flags & MEM_IntReal );
|
||||
sqlite3VdbeMemRealify(pIn1);
|
||||
REGISTER_TRACE(pOp->p1, pIn1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2227,9 +2230,14 @@ case OP_Compare: {
|
||||
REGISTER_TRACE(p2+idx, &aMem[p2+idx]);
|
||||
assert( i<pKeyInfo->nKeyField );
|
||||
pColl = pKeyInfo->aColl[i];
|
||||
bRev = pKeyInfo->aSortOrder[i];
|
||||
bRev = (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_DESC);
|
||||
iCompare = sqlite3MemCompare(&aMem[p1+idx], &aMem[p2+idx], pColl);
|
||||
if( iCompare ){
|
||||
if( (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_BIGNULL)
|
||||
&& ((aMem[p1+idx].flags & MEM_Null) || (aMem[p2+idx].flags & MEM_Null))
|
||||
){
|
||||
iCompare = -iCompare;
|
||||
}
|
||||
if( bRev ) iCompare = -iCompare;
|
||||
break;
|
||||
}
|
||||
@@ -2520,11 +2528,6 @@ case OP_Offset: { /* out3 */
|
||||
** if the P4 argument is a P4_MEM use the value of the P4 argument as
|
||||
** the result.
|
||||
**
|
||||
** If the OPFLAG_CLEARCACHE bit is set on P5 and P1 is a pseudo-table cursor,
|
||||
** then the cache of the cursor is reset prior to extracting the column.
|
||||
** The first OP_Column against a pseudo-table after the value of the content
|
||||
** register has changed should have this bit set.
|
||||
**
|
||||
** If the OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG bits are set on P5 then
|
||||
** the result is guaranteed to only be used as the argument of a length()
|
||||
** or typeof() function, respectively. The loading of large blobs can be
|
||||
@@ -4127,6 +4130,7 @@ case OP_SeekGT: { /* jump, in3, group */
|
||||
pC->deferredMoveto = 0;
|
||||
pC->cacheStatus = CACHE_STALE;
|
||||
if( pC->isTable ){
|
||||
u16 flags3, newType;
|
||||
/* The BTREE_SEEK_EQ flag is only set on index cursors */
|
||||
assert( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ)==0
|
||||
|| CORRUPT_DB );
|
||||
@@ -4135,16 +4139,19 @@ case OP_SeekGT: { /* jump, in3, group */
|
||||
** blob, or NULL. But it needs to be an integer before we can do
|
||||
** the seek, so convert it. */
|
||||
pIn3 = &aMem[pOp->p3];
|
||||
if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Str))==MEM_Str ){
|
||||
flags3 = pIn3->flags;
|
||||
if( (flags3 & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Str))==MEM_Str ){
|
||||
applyNumericAffinity(pIn3, 0);
|
||||
}
|
||||
iKey = sqlite3VdbeIntValue(pIn3);
|
||||
iKey = sqlite3VdbeIntValue(pIn3); /* Get the integer key value */
|
||||
newType = pIn3->flags; /* Record the type after applying numeric affinity */
|
||||
pIn3->flags = flags3; /* But convert the type back to its original */
|
||||
|
||||
/* If the P3 value could not be converted into an integer without
|
||||
** loss of information, then special processing is required... */
|
||||
if( (pIn3->flags & (MEM_Int|MEM_IntReal))==0 ){
|
||||
if( (pIn3->flags & MEM_Real)==0 ){
|
||||
if( (pIn3->flags & MEM_Null) || oc>=OP_SeekGE ){
|
||||
if( (newType & (MEM_Int|MEM_IntReal))==0 ){
|
||||
if( (newType & MEM_Real)==0 ){
|
||||
if( (newType & MEM_Null) || oc>=OP_SeekGE ){
|
||||
VdbeBranchTaken(1,2);
|
||||
goto jump_to_p2;
|
||||
}else{
|
||||
@@ -5440,11 +5447,12 @@ case OP_Next: /* jump */
|
||||
** The Prev opcode is only used after SeekLT, SeekLE, and Last. */
|
||||
assert( pOp->opcode!=OP_Next
|
||||
|| pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE
|
||||
|| pC->seekOp==OP_Rewind || pC->seekOp==OP_Found
|
||||
|| pC->seekOp==OP_NullRow|| pC->seekOp==OP_SeekRowid);
|
||||
|| pC->seekOp==OP_Rewind || pC->seekOp==OP_Found
|
||||
|| pC->seekOp==OP_NullRow|| pC->seekOp==OP_SeekRowid
|
||||
|| pC->seekOp==OP_IfNoHope);
|
||||
assert( pOp->opcode!=OP_Prev
|
||||
|| pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE
|
||||
|| pC->seekOp==OP_Last
|
||||
|| pC->seekOp==OP_Last || pC->seekOp==OP_IfNoHope
|
||||
|| pC->seekOp==OP_NullRow);
|
||||
|
||||
rc = pOp->p4.xAdvance(pC->uc.pCursor, pOp->p3);
|
||||
|
||||
+27
-11
@@ -1493,14 +1493,16 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
|
||||
case P4_KEYINFO: {
|
||||
int j;
|
||||
KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
|
||||
assert( pKeyInfo->aSortOrder!=0 );
|
||||
assert( pKeyInfo->aSortFlags!=0 );
|
||||
sqlite3_str_appendf(&x, "k(%d", pKeyInfo->nKeyField);
|
||||
for(j=0; j<pKeyInfo->nKeyField; j++){
|
||||
CollSeq *pColl = pKeyInfo->aColl[j];
|
||||
const char *zColl = pColl ? pColl->zName : "";
|
||||
if( strcmp(zColl, "BINARY")==0 ) zColl = "B";
|
||||
sqlite3_str_appendf(&x, ",%s%s",
|
||||
pKeyInfo->aSortOrder[j] ? "-" : "", zColl);
|
||||
sqlite3_str_appendf(&x, ",%s%s%s",
|
||||
(pKeyInfo->aSortFlags[j] & KEYINFO_ORDER_DESC) ? "-" : "",
|
||||
(pKeyInfo->aSortFlags[j] & KEYINFO_ORDER_BIGNULL)? "N." : "",
|
||||
zColl);
|
||||
}
|
||||
sqlite3_str_append(&x, ")", 1);
|
||||
break;
|
||||
@@ -3813,7 +3815,7 @@ UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(
|
||||
p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte);
|
||||
if( !p ) return 0;
|
||||
p->aMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))];
|
||||
assert( pKeyInfo->aSortOrder!=0 );
|
||||
assert( pKeyInfo->aSortFlags!=0 );
|
||||
p->pKeyInfo = pKeyInfo;
|
||||
p->nField = pKeyInfo->nKeyField + 1;
|
||||
return p;
|
||||
@@ -3912,7 +3914,7 @@ static int vdbeRecordCompareDebug(
|
||||
if( szHdr1>98307 ) return SQLITE_CORRUPT;
|
||||
d1 = szHdr1;
|
||||
assert( pKeyInfo->nAllField>=pPKey2->nField || CORRUPT_DB );
|
||||
assert( pKeyInfo->aSortOrder!=0 );
|
||||
assert( pKeyInfo->aSortFlags!=0 );
|
||||
assert( pKeyInfo->nKeyField>0 );
|
||||
assert( idx1<=szHdr1 || CORRUPT_DB );
|
||||
do{
|
||||
@@ -3943,7 +3945,12 @@ static int vdbeRecordCompareDebug(
|
||||
pKeyInfo->nAllField>i ? pKeyInfo->aColl[i] : 0);
|
||||
if( rc!=0 ){
|
||||
assert( mem1.szMalloc==0 ); /* See comment below */
|
||||
if( pKeyInfo->aSortOrder[i] ){
|
||||
if( (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_BIGNULL)
|
||||
&& ((mem1.flags & MEM_Null) || (pPKey2->aMem[i].flags & MEM_Null))
|
||||
){
|
||||
rc = -rc;
|
||||
}
|
||||
if( pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_DESC ){
|
||||
rc = -rc; /* Invert the result for DESC sort order. */
|
||||
}
|
||||
goto debugCompareEnd;
|
||||
@@ -4319,7 +4326,7 @@ int sqlite3VdbeRecordCompareWithSkip(
|
||||
VVA_ONLY( mem1.szMalloc = 0; ) /* Only needed by assert() statements */
|
||||
assert( pPKey2->pKeyInfo->nAllField>=pPKey2->nField
|
||||
|| CORRUPT_DB );
|
||||
assert( pPKey2->pKeyInfo->aSortOrder!=0 );
|
||||
assert( pPKey2->pKeyInfo->aSortFlags!=0 );
|
||||
assert( pPKey2->pKeyInfo->nKeyField>0 );
|
||||
assert( idx1<=szHdr1 || CORRUPT_DB );
|
||||
do{
|
||||
@@ -4442,8 +4449,14 @@ int sqlite3VdbeRecordCompareWithSkip(
|
||||
}
|
||||
|
||||
if( rc!=0 ){
|
||||
if( pPKey2->pKeyInfo->aSortOrder[i] ){
|
||||
rc = -rc;
|
||||
int sortFlags = pPKey2->pKeyInfo->aSortFlags[i];
|
||||
if( sortFlags ){
|
||||
if( (sortFlags & KEYINFO_ORDER_BIGNULL)==0
|
||||
|| ((sortFlags & KEYINFO_ORDER_DESC)
|
||||
!=(serial_type==0 || (pRhs->flags&MEM_Null)))
|
||||
){
|
||||
rc = -rc;
|
||||
}
|
||||
}
|
||||
assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, rc) );
|
||||
assert( mem1.szMalloc==0 ); /* See comment below */
|
||||
@@ -4660,7 +4673,10 @@ RecordCompare sqlite3VdbeFindCompare(UnpackedRecord *p){
|
||||
** header size is (12*5 + 1 + 1) bytes. */
|
||||
if( p->pKeyInfo->nAllField<=13 ){
|
||||
int flags = p->aMem[0].flags;
|
||||
if( p->pKeyInfo->aSortOrder[0] ){
|
||||
if( p->pKeyInfo->aSortFlags[0] ){
|
||||
if( p->pKeyInfo->aSortFlags[0] & KEYINFO_ORDER_BIGNULL ){
|
||||
return sqlite3VdbeRecordCompare;
|
||||
}
|
||||
p->r1 = 1;
|
||||
p->r2 = -1;
|
||||
}else{
|
||||
@@ -5006,7 +5022,7 @@ void sqlite3VdbePreUpdateHook(
|
||||
preupdate.keyinfo.db = db;
|
||||
preupdate.keyinfo.enc = ENC(db);
|
||||
preupdate.keyinfo.nKeyField = pTab->nCol;
|
||||
preupdate.keyinfo.aSortOrder = (u8*)&fakeSortOrder;
|
||||
preupdate.keyinfo.aSortFlags = (u8*)&fakeSortOrder;
|
||||
preupdate.iKey1 = iKey1;
|
||||
preupdate.iKey2 = iKey2;
|
||||
preupdate.pTab = pTab;
|
||||
|
||||
+7
-1
@@ -232,7 +232,13 @@ SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){
|
||||
assert( pMem->szMalloc==0
|
||||
|| pMem->szMalloc==sqlite3DbMallocSize(pMem->db, pMem->zMalloc) );
|
||||
if( pMem->szMalloc>0 && bPreserve && pMem->z==pMem->zMalloc ){
|
||||
pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
|
||||
if( pMem->db ){
|
||||
pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
|
||||
}else{
|
||||
pMem->zMalloc = sqlite3Realloc(pMem->z, n);
|
||||
if( pMem->zMalloc==0 ) sqlite3_free(pMem->z);
|
||||
pMem->z = pMem->zMalloc;
|
||||
}
|
||||
bPreserve = 0;
|
||||
}else{
|
||||
if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc);
|
||||
|
||||
+5
-2
@@ -829,7 +829,8 @@ static int vdbeSorterCompareText(
|
||||
);
|
||||
}
|
||||
}else{
|
||||
if( pTask->pSorter->pKeyInfo->aSortOrder[0] ){
|
||||
assert( !(pTask->pSorter->pKeyInfo->aSortFlags[0]&KEYINFO_ORDER_BIGNULL) );
|
||||
if( pTask->pSorter->pKeyInfo->aSortFlags[0] ){
|
||||
res = res * -1;
|
||||
}
|
||||
}
|
||||
@@ -897,7 +898,8 @@ static int vdbeSorterCompareInt(
|
||||
pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2
|
||||
);
|
||||
}
|
||||
}else if( pTask->pSorter->pKeyInfo->aSortOrder[0] ){
|
||||
}else if( pTask->pSorter->pKeyInfo->aSortFlags[0] ){
|
||||
assert( !(pTask->pSorter->pKeyInfo->aSortFlags[0]&KEYINFO_ORDER_BIGNULL) );
|
||||
res = res * -1;
|
||||
}
|
||||
|
||||
@@ -1012,6 +1014,7 @@ int sqlite3VdbeSorterInit(
|
||||
|
||||
if( pKeyInfo->nAllField<13
|
||||
&& (pKeyInfo->aColl[0]==0 || pKeyInfo->aColl[0]==db->pDfltColl)
|
||||
&& (pKeyInfo->aSortFlags[0] & KEYINFO_ORDER_BIGNULL)==0
|
||||
){
|
||||
pSorter->typeMask = SORTER_TYPE_INTEGER | SORTER_TYPE_TEXT;
|
||||
}
|
||||
|
||||
+64
-14
@@ -32,6 +32,9 @@ struct VtabCtx {
|
||||
** Construct and install a Module object for a virtual table. When this
|
||||
** routine is called, it is guaranteed that all appropriate locks are held
|
||||
** and the module is not already part of the connection.
|
||||
**
|
||||
** If there already exists a module with zName, replace it with the new one.
|
||||
** If pModule==0, then delete the module zName if it exists.
|
||||
*/
|
||||
Module *sqlite3VtabCreateModule(
|
||||
sqlite3 *db, /* Database in which module is registered */
|
||||
@@ -41,25 +44,36 @@ Module *sqlite3VtabCreateModule(
|
||||
void (*xDestroy)(void *) /* Module destructor function */
|
||||
){
|
||||
Module *pMod;
|
||||
int nName = sqlite3Strlen30(zName);
|
||||
pMod = (Module *)sqlite3Malloc(sizeof(Module) + nName + 1);
|
||||
if( pMod==0 ){
|
||||
sqlite3OomFault(db);
|
||||
Module *pDel;
|
||||
char *zCopy;
|
||||
if( pModule==0 ){
|
||||
zCopy = (char*)zName;
|
||||
pMod = 0;
|
||||
}else{
|
||||
Module *pDel;
|
||||
char *zCopy = (char *)(&pMod[1]);
|
||||
int nName = sqlite3Strlen30(zName);
|
||||
pMod = (Module *)sqlite3Malloc(sizeof(Module) + nName + 1);
|
||||
if( pMod==0 ){
|
||||
sqlite3OomFault(db);
|
||||
return 0;
|
||||
}
|
||||
zCopy = (char *)(&pMod[1]);
|
||||
memcpy(zCopy, zName, nName+1);
|
||||
pMod->zName = zCopy;
|
||||
pMod->pModule = pModule;
|
||||
pMod->pAux = pAux;
|
||||
pMod->xDestroy = xDestroy;
|
||||
pMod->pEpoTab = 0;
|
||||
pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod);
|
||||
assert( pDel==0 || pDel==pMod );
|
||||
if( pDel ){
|
||||
pMod->nRefModule = 1;
|
||||
}
|
||||
pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod);
|
||||
if( pDel ){
|
||||
if( pDel==pMod ){
|
||||
sqlite3OomFault(db);
|
||||
sqlite3DbFree(db, pDel);
|
||||
pMod = 0;
|
||||
}else{
|
||||
sqlite3VtabEponymousTableClear(db, pDel);
|
||||
sqlite3VtabModuleUnref(db, pDel);
|
||||
}
|
||||
}
|
||||
return pMod;
|
||||
@@ -80,11 +94,7 @@ static int createModule(
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
if( sqlite3HashFind(&db->aModule, zName) ){
|
||||
rc = SQLITE_MISUSE_BKPT;
|
||||
}else{
|
||||
(void)sqlite3VtabCreateModule(db, zName, pModule, pAux, xDestroy);
|
||||
}
|
||||
(void)sqlite3VtabCreateModule(db, zName, pModule, pAux, xDestroy);
|
||||
rc = sqlite3ApiExit(db, rc);
|
||||
if( rc!=SQLITE_OK && xDestroy ) xDestroy(pAux);
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
@@ -123,6 +133,44 @@ int sqlite3_create_module_v2(
|
||||
return createModule(db, zName, pModule, pAux, xDestroy);
|
||||
}
|
||||
|
||||
/*
|
||||
** External API to drop all virtual-table modules, except those named
|
||||
** on the azNames list.
|
||||
*/
|
||||
int sqlite3_drop_modules(sqlite3 *db, const char** azNames){
|
||||
HashElem *pThis, *pNext;
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
|
||||
#endif
|
||||
for(pThis=sqliteHashFirst(&db->aModule); pThis; pThis=pNext){
|
||||
Module *pMod = (Module*)sqliteHashData(pThis);
|
||||
pNext = sqliteHashNext(pThis);
|
||||
if( azNames ){
|
||||
int ii;
|
||||
for(ii=0; azNames[ii]!=0 && strcmp(azNames[ii],pMod->zName)!=0; ii++){}
|
||||
if( azNames[ii]!=0 ) continue;
|
||||
}
|
||||
createModule(db, pMod->zName, 0, 0, 0);
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Decrement the reference count on a Module object. Destroy the
|
||||
** module when the reference count reaches zero.
|
||||
*/
|
||||
void sqlite3VtabModuleUnref(sqlite3 *db, Module *pMod){
|
||||
assert( pMod->nRefModule>0 );
|
||||
pMod->nRefModule--;
|
||||
if( pMod->nRefModule==0 ){
|
||||
if( pMod->xDestroy ){
|
||||
pMod->xDestroy(pMod->pAux);
|
||||
}
|
||||
assert( pMod->pEpoTab==0 );
|
||||
sqlite3DbFree(db, pMod);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Lock the virtual table so that it cannot be disconnected.
|
||||
** Locks nest. Every lock should have a corresponding unlock.
|
||||
@@ -162,6 +210,7 @@ void sqlite3VtabUnlock(VTable *pVTab){
|
||||
pVTab->nRef--;
|
||||
if( pVTab->nRef==0 ){
|
||||
sqlite3_vtab *p = pVTab->pVtab;
|
||||
sqlite3VtabModuleUnref(pVTab->db, pVTab->pMod);
|
||||
if( p ){
|
||||
p->pModule->xDisconnect(p);
|
||||
}
|
||||
@@ -566,6 +615,7 @@ static int vtabCallConstructor(
|
||||
** the sqlite3_vtab object if successful. */
|
||||
memset(pVTable->pVtab, 0, sizeof(pVTable->pVtab[0]));
|
||||
pVTable->pVtab->pModule = pMod->pModule;
|
||||
pMod->nRefModule++;
|
||||
pVTable->nRef = 1;
|
||||
if( sCtx.bDeclared==0 ){
|
||||
const char *zFormat = "vtable constructor did not declare schema: %s";
|
||||
|
||||
+41
-20
@@ -253,7 +253,8 @@ static WhereTerm *whereScanNext(WhereScan *pScan){
|
||||
){
|
||||
if( (pTerm->eOperator & WO_EQUIV)!=0
|
||||
&& pScan->nEquiv<ArraySize(pScan->aiCur)
|
||||
&& (pX = sqlite3ExprSkipCollate(pTerm->pExpr->pRight))->op==TK_COLUMN
|
||||
&& (pX = sqlite3ExprSkipCollateAndLikely(pTerm->pExpr->pRight))->op
|
||||
==TK_COLUMN
|
||||
){
|
||||
int j;
|
||||
for(j=0; j<pScan->nEquiv; j++){
|
||||
@@ -449,7 +450,7 @@ static int findIndexCol(
|
||||
const char *zColl = pIdx->azColl[iCol];
|
||||
|
||||
for(i=0; i<pList->nExpr; i++){
|
||||
Expr *p = sqlite3ExprSkipCollate(pList->a[i].pExpr);
|
||||
Expr *p = sqlite3ExprSkipCollateAndLikely(pList->a[i].pExpr);
|
||||
if( p->op==TK_COLUMN
|
||||
&& p->iColumn==pIdx->aiColumn[iCol]
|
||||
&& p->iTable==iBase
|
||||
@@ -513,7 +514,7 @@ static int isDistinctRedundant(
|
||||
** current SELECT is a correlated sub-query.
|
||||
*/
|
||||
for(i=0; i<pDistinct->nExpr; i++){
|
||||
Expr *p = sqlite3ExprSkipCollate(pDistinct->a[i].pExpr);
|
||||
Expr *p = sqlite3ExprSkipCollateAndLikely(pDistinct->a[i].pExpr);
|
||||
if( p->op==TK_COLUMN && p->iTable==iBase && p->iColumn<0 ) return 1;
|
||||
}
|
||||
|
||||
@@ -933,6 +934,7 @@ static sqlite3_index_info *allocateIndexInfo(
|
||||
for(i=0; i<n; i++){
|
||||
Expr *pExpr = pOrderBy->a[i].pExpr;
|
||||
if( pExpr->op!=TK_COLUMN || pExpr->iTable!=pSrc->iCursor ) break;
|
||||
if( pOrderBy->a[i].sortFlags & KEYINFO_ORDER_BIGNULL ) break;
|
||||
}
|
||||
if( i==n){
|
||||
nOrderBy = n;
|
||||
@@ -1031,7 +1033,7 @@ static sqlite3_index_info *allocateIndexInfo(
|
||||
for(i=0; i<nOrderBy; i++){
|
||||
Expr *pExpr = pOrderBy->a[i].pExpr;
|
||||
pIdxOrderBy[i].iColumn = pExpr->iColumn;
|
||||
pIdxOrderBy[i].desc = pOrderBy->a[i].sortOrder;
|
||||
pIdxOrderBy[i].desc = pOrderBy->a[i].sortFlags & KEYINFO_ORDER_DESC;
|
||||
}
|
||||
|
||||
*pmNoOmit = mNoOmit;
|
||||
@@ -2266,7 +2268,7 @@ static void whereLoopOutputAdjust(
|
||||
){
|
||||
WhereTerm *pTerm, *pX;
|
||||
Bitmask notAllowed = ~(pLoop->prereq|pLoop->maskSelf);
|
||||
int i, j, k;
|
||||
int i, j;
|
||||
LogEst iReduce = 0; /* pLoop->nOut should not exceed nRow-iReduce */
|
||||
|
||||
assert( (pLoop->wsFlags & WHERE_AUTO_INDEX)==0 );
|
||||
@@ -2292,6 +2294,7 @@ static void whereLoopOutputAdjust(
|
||||
pLoop->nOut--;
|
||||
if( pTerm->eOperator&(WO_EQ|WO_IS) ){
|
||||
Expr *pRight = pTerm->pExpr->pRight;
|
||||
int k = 0;
|
||||
testcase( pTerm->pExpr->op==TK_IS );
|
||||
if( sqlite3ExprIsInteger(pRight, &k) && k>=(-1) && k<=1 ){
|
||||
k = 10;
|
||||
@@ -2516,8 +2519,6 @@ static int whereLoopAddBtreeIndex(
|
||||
}else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){
|
||||
/* "x IN (value, value, ...)" */
|
||||
nIn = sqlite3LogEst(pExpr->x.pList->nExpr);
|
||||
assert( nIn>0 ); /* RHS always has 2 or more terms... The parser
|
||||
** changes "x IN (?)" into "x=?". */
|
||||
}
|
||||
if( pProbe->hasStat1 ){
|
||||
LogEst M, logK, safetyMargin;
|
||||
@@ -2769,7 +2770,7 @@ static int indexMightHelpWithOrderBy(
|
||||
if( pIndex->bUnordered ) return 0;
|
||||
if( (pOB = pBuilder->pWInfo->pOrderBy)==0 ) return 0;
|
||||
for(ii=0; ii<pOB->nExpr; ii++){
|
||||
Expr *pExpr = sqlite3ExprSkipCollate(pOB->a[ii].pExpr);
|
||||
Expr *pExpr = sqlite3ExprSkipCollateAndLikely(pOB->a[ii].pExpr);
|
||||
if( pExpr->op==TK_COLUMN && pExpr->iTable==iCursor ){
|
||||
if( pExpr->iColumn<0 ) return 1;
|
||||
for(jj=0; jj<pIndex->nKeyCol; jj++){
|
||||
@@ -2800,7 +2801,9 @@ static int whereUsablePartialIndex(int iTab, WhereClause *pWC, Expr *pWhere){
|
||||
}
|
||||
if( pParse->db->flags & SQLITE_EnableQPSG ) pParse = 0;
|
||||
for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
|
||||
Expr *pExpr = pTerm->pExpr;
|
||||
Expr *pExpr;
|
||||
if( pTerm->wtFlags & TERM_NOPARTIDX ) continue;
|
||||
pExpr = pTerm->pExpr;
|
||||
if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->iRightJoinTable==iTab)
|
||||
&& sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab)
|
||||
){
|
||||
@@ -3709,7 +3712,7 @@ static i8 wherePathSatisfiesOrderBy(
|
||||
*/
|
||||
for(i=0; i<nOrderBy; i++){
|
||||
if( MASKBIT(i) & obSat ) continue;
|
||||
pOBExpr = sqlite3ExprSkipCollate(pOrderBy->a[i].pExpr);
|
||||
pOBExpr = sqlite3ExprSkipCollateAndLikely(pOrderBy->a[i].pExpr);
|
||||
if( pOBExpr->op!=TK_COLUMN ) continue;
|
||||
if( pOBExpr->iTable!=iCur ) continue;
|
||||
pTerm = sqlite3WhereFindTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn,
|
||||
@@ -3765,15 +3768,21 @@ static i8 wherePathSatisfiesOrderBy(
|
||||
u16 eOp = pLoop->aLTerm[j]->eOperator;
|
||||
|
||||
/* Skip over == and IS and ISNULL terms. (Also skip IN terms when
|
||||
** doing WHERE_ORDERBY_LIMIT processing).
|
||||
** doing WHERE_ORDERBY_LIMIT processing). Except, IS and ISNULL
|
||||
** terms imply that the index is not UNIQUE NOT NULL in which case
|
||||
** the loop need to be marked as not order-distinct because it can
|
||||
** have repeated NULL rows.
|
||||
**
|
||||
** If the current term is a column of an ((?,?) IN (SELECT...))
|
||||
** expression for which the SELECT returns more than one column,
|
||||
** check that it is the only column used by this loop. Otherwise,
|
||||
** if it is one of two or more, none of the columns can be
|
||||
** considered to match an ORDER BY term. */
|
||||
** considered to match an ORDER BY term.
|
||||
*/
|
||||
if( (eOp & eqOpMask)!=0 ){
|
||||
if( eOp & WO_ISNULL ){
|
||||
if( eOp & (WO_ISNULL|WO_IS) ){
|
||||
testcase( eOp & WO_ISNULL );
|
||||
testcase( eOp & WO_IS );
|
||||
testcase( isOrderDistinct );
|
||||
isOrderDistinct = 0;
|
||||
}
|
||||
@@ -3799,7 +3808,7 @@ static i8 wherePathSatisfiesOrderBy(
|
||||
*/
|
||||
if( pIndex ){
|
||||
iColumn = pIndex->aiColumn[j];
|
||||
revIdx = pIndex->aSortOrder[j];
|
||||
revIdx = pIndex->aSortOrder[j] & KEYINFO_ORDER_DESC;
|
||||
if( iColumn==pIndex->pTable->iPKey ) iColumn = XN_ROWID;
|
||||
}else{
|
||||
iColumn = XN_ROWID;
|
||||
@@ -3823,7 +3832,7 @@ static i8 wherePathSatisfiesOrderBy(
|
||||
isMatch = 0;
|
||||
for(i=0; bOnce && i<nOrderBy; i++){
|
||||
if( MASKBIT(i) & obSat ) continue;
|
||||
pOBExpr = sqlite3ExprSkipCollate(pOrderBy->a[i].pExpr);
|
||||
pOBExpr = sqlite3ExprSkipCollateAndLikely(pOrderBy->a[i].pExpr);
|
||||
testcase( wctrlFlags & WHERE_GROUPBY );
|
||||
testcase( wctrlFlags & WHERE_DISTINCTBY );
|
||||
if( (wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY))==0 ) bOnce = 0;
|
||||
@@ -3851,22 +3860,28 @@ static i8 wherePathSatisfiesOrderBy(
|
||||
/* Make sure the sort order is compatible in an ORDER BY clause.
|
||||
** Sort order is irrelevant for a GROUP BY clause. */
|
||||
if( revSet ){
|
||||
if( (rev ^ revIdx)!=pOrderBy->a[i].sortOrder ) isMatch = 0;
|
||||
if( (rev ^ revIdx)!=(pOrderBy->a[i].sortFlags&KEYINFO_ORDER_DESC) ){
|
||||
isMatch = 0;
|
||||
}
|
||||
}else{
|
||||
rev = revIdx ^ pOrderBy->a[i].sortOrder;
|
||||
rev = revIdx ^ (pOrderBy->a[i].sortFlags & KEYINFO_ORDER_DESC);
|
||||
if( rev ) *pRevMask |= MASKBIT(iLoop);
|
||||
revSet = 1;
|
||||
}
|
||||
}
|
||||
if( isMatch && (pOrderBy->a[i].sortFlags & KEYINFO_ORDER_BIGNULL) ){
|
||||
if( j==pLoop->u.btree.nEq ){
|
||||
pLoop->wsFlags |= WHERE_BIGNULL_SORT;
|
||||
}else{
|
||||
isMatch = 0;
|
||||
}
|
||||
}
|
||||
if( isMatch ){
|
||||
if( iColumn==XN_ROWID ){
|
||||
testcase( distinctColumns==0 );
|
||||
distinctColumns = 1;
|
||||
}
|
||||
obSat |= MASKBIT(i);
|
||||
if( (wctrlFlags & WHERE_ORDERBY_MIN) && j==pLoop->u.btree.nEq ){
|
||||
pLoop->wsFlags |= WHERE_MIN_ORDERED;
|
||||
}
|
||||
}else{
|
||||
/* No match found */
|
||||
if( j==0 || j<nKeyCol ){
|
||||
@@ -5060,6 +5075,7 @@ WhereInfo *sqlite3WhereBegin(
|
||||
sqlite3VdbeSetP4KeyInfo(pParse, pIx);
|
||||
if( (pLoop->wsFlags & WHERE_CONSTRAINT)!=0
|
||||
&& (pLoop->wsFlags & (WHERE_COLUMN_RANGE|WHERE_SKIPSCAN))==0
|
||||
&& (pLoop->wsFlags & WHERE_BIGNULL_SORT)==0
|
||||
&& (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0
|
||||
&& pWInfo->eDistinct!=WHERE_DISTINCT_ORDERED
|
||||
){
|
||||
@@ -5201,6 +5217,11 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
|
||||
VdbeCoverageIf(v, pLevel->op==OP_Next);
|
||||
VdbeCoverageIf(v, pLevel->op==OP_Prev);
|
||||
VdbeCoverageIf(v, pLevel->op==OP_VNext);
|
||||
if( pLevel->regBignull ){
|
||||
sqlite3VdbeResolveLabel(v, pLevel->addrBignull);
|
||||
sqlite3VdbeAddOp2(v, OP_DecrJumpZero, pLevel->regBignull, pLevel->p2-1);
|
||||
VdbeCoverage(v);
|
||||
}
|
||||
#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
|
||||
if( addrSeek ) sqlite3VdbeJumpHere(v, addrSeek);
|
||||
#endif
|
||||
|
||||
+5
-2
@@ -71,13 +71,15 @@ struct WhereLevel {
|
||||
int addrCont; /* Jump here to continue with the next loop cycle */
|
||||
int addrFirst; /* First instruction of interior of the loop */
|
||||
int addrBody; /* Beginning of the body of this loop */
|
||||
int regBignull; /* big-null flag reg. True if a NULL-scan is needed */
|
||||
int addrBignull; /* Jump here for next part of big-null scan */
|
||||
#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
|
||||
u32 iLikeRepCntr; /* LIKE range processing counter register (times 2) */
|
||||
int addrLikeRep; /* LIKE range processing address */
|
||||
#endif
|
||||
u8 iFrom; /* Which entry in the FROM clause */
|
||||
u8 op, p3, p5; /* Opcode, P3 & P5 of the opcode that ends the loop */
|
||||
int p1, p2; /* Operands of the opcode used to ends the loop */
|
||||
int p1, p2; /* Operands of the opcode used to end the loop */
|
||||
union { /* Information that depends on pWLoop->wsFlags */
|
||||
struct {
|
||||
int nIn; /* Number of entries in aInLoop[] */
|
||||
@@ -289,6 +291,7 @@ struct WhereTerm {
|
||||
#define TERM_LIKE 0x400 /* The original LIKE operator */
|
||||
#define TERM_IS 0x800 /* Term.pExpr is an IS operator */
|
||||
#define TERM_VARSELECT 0x1000 /* Term.pExpr contains a correlated sub-query */
|
||||
#define TERM_NOPARTIDX 0x2000 /* Not for use to enable a partial index */
|
||||
|
||||
/*
|
||||
** An instance of the WhereScan object is used as an iterator for locating
|
||||
@@ -586,6 +589,6 @@ void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*);
|
||||
#define WHERE_UNQ_WANTED 0x00010000 /* WHERE_ONEROW would have been helpful*/
|
||||
#define WHERE_PARTIALIDX 0x00020000 /* The automatic index is partial */
|
||||
#define WHERE_IN_EARLYOUT 0x00040000 /* Perhaps quit IN loops early */
|
||||
#define WHERE_MIN_ORDERED 0x00080000 /* Column nEq of index is min() expr */
|
||||
#define WHERE_BIGNULL_SORT 0x00080000 /* Column nEq of index is BIGNULL */
|
||||
|
||||
#endif /* !defined(SQLITE_WHEREINT_H) */
|
||||
|
||||
+71
-38
@@ -1117,6 +1117,7 @@ typedef struct IdxExprTrans {
|
||||
static int whereIndexExprTransNode(Walker *p, Expr *pExpr){
|
||||
IdxExprTrans *pX = p->u.pIdxTrans;
|
||||
if( sqlite3ExprCompare(0, pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){
|
||||
pExpr->affExpr = sqlite3ExprAffinity(pExpr);
|
||||
pExpr->op = TK_COLUMN;
|
||||
pExpr->iTable = pX->iIdxCur;
|
||||
pExpr->iColumn = pX->iIdxCol;
|
||||
@@ -1549,31 +1550,12 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
u8 bSeekPastNull = 0; /* True to seek past initial nulls */
|
||||
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 */
|
||||
|
||||
pIdx = pLoop->u.btree.pIndex;
|
||||
iIdxCur = pLevel->iIdxCur;
|
||||
assert( nEq>=pLoop->nSkip );
|
||||
|
||||
/* If this loop satisfies a sort order (pOrderBy) request that
|
||||
** was passed to this function to implement a "SELECT min(x) ..."
|
||||
** query, then the caller will only allow the loop to run for
|
||||
** a single iteration. This means that the first row returned
|
||||
** should not have a NULL value stored in 'x'. If column 'x' is
|
||||
** the first one after the nEq equality constraints in the index,
|
||||
** this requires some special handling.
|
||||
*/
|
||||
assert( (pWInfo->pOrderBy!=0 && pWInfo->pOrderBy->nExpr==1)
|
||||
|| (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0 );
|
||||
if( pLoop->wsFlags & WHERE_MIN_ORDERED ){
|
||||
assert( (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN) );
|
||||
assert( pWInfo->nOBSat );
|
||||
assert( pIdx->nColumn>nEq );
|
||||
assert( pLoop->nSkip==0 );
|
||||
bSeekPastNull = 1;
|
||||
nExtraReg = 1;
|
||||
}
|
||||
|
||||
/* Find any inequality constraint terms for the start and end
|
||||
** of the range.
|
||||
*/
|
||||
@@ -1614,6 +1596,25 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
}
|
||||
assert( pRangeEnd==0 || (pRangeEnd->wtFlags & TERM_VNULL)==0 );
|
||||
|
||||
/* If the WHERE_BIGNULL_SORT flag is set, then index column nEq uses
|
||||
** a non-default "big-null" sort (either ASC NULLS LAST or DESC NULLS
|
||||
** FIRST). In both cases separate ordered scans are made of those
|
||||
** index entries for which the column is null and for those for which
|
||||
** it is not. For an ASC sort, the non-NULL entries are scanned first.
|
||||
** For DESC, NULL entries are scanned first.
|
||||
*/
|
||||
if( (pLoop->wsFlags & (WHERE_TOP_LIMIT|WHERE_BTM_LIMIT))==0
|
||||
&& (pLoop->wsFlags & WHERE_BIGNULL_SORT)!=0
|
||||
){
|
||||
assert( bSeekPastNull==0 && nExtraReg==0 && nBtm==0 && nTop==0 );
|
||||
assert( pRangeEnd==0 && pRangeStart==0 );
|
||||
assert( pLoop->nSkip==0 );
|
||||
nExtraReg = 1;
|
||||
bSeekPastNull = 1;
|
||||
pLevel->regBignull = regBignull = ++pParse->nMem;
|
||||
pLevel->addrBignull = sqlite3VdbeMakeLabel(pParse);
|
||||
}
|
||||
|
||||
/* If we are doing a reverse order scan on an ascending index, or
|
||||
** a forward order scan on a descending index, interchange the
|
||||
** start and end terms (pRangeStart and pRangeEnd).
|
||||
@@ -1636,7 +1637,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
if( zStartAff && nTop ){
|
||||
zEndAff = sqlite3DbStrDup(db, &zStartAff[nEq]);
|
||||
}
|
||||
addrNxt = pLevel->addrNxt;
|
||||
addrNxt = (regBignull ? pLevel->addrBignull : pLevel->addrNxt);
|
||||
|
||||
testcase( pRangeStart && (pRangeStart->eOperator & WO_LE)!=0 );
|
||||
testcase( pRangeStart && (pRangeStart->eOperator & WO_GE)!=0 );
|
||||
@@ -1670,10 +1671,14 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
}
|
||||
bSeekPastNull = 0;
|
||||
}else if( bSeekPastNull ){
|
||||
sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
|
||||
nConstraint++;
|
||||
startEq = 0;
|
||||
sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
|
||||
start_constraints = 1;
|
||||
nConstraint++;
|
||||
}else if( regBignull ){
|
||||
sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
|
||||
start_constraints = 1;
|
||||
nConstraint++;
|
||||
}
|
||||
codeApplyAffinity(pParse, regBase, nConstraint - bSeekPastNull, zStartAff);
|
||||
if( pLoop->nSkip>0 && nConstraint==pLoop->nSkip ){
|
||||
@@ -1684,6 +1689,11 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
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"));
|
||||
}
|
||||
|
||||
op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev];
|
||||
assert( op!=0 );
|
||||
sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
|
||||
@@ -1695,23 +1705,21 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
VdbeCoverageIf(v, op==OP_SeekLE); testcase( op==OP_SeekLE );
|
||||
VdbeCoverageIf(v, op==OP_SeekLT); testcase( op==OP_SeekLT );
|
||||
|
||||
if( bSeekPastNull && (pLoop->wsFlags & WHERE_TOP_LIMIT)==0 ){
|
||||
/* If bSeekPastNull is set only to skip past the NULL values for
|
||||
** a query like "SELECT min(a), b FROM t1", then add code so that
|
||||
** if there are no rows with (a IS NOT NULL), then do the seek
|
||||
** without jumping past NULLs instead. This allows the code in
|
||||
** select.c to pick a value for "b" in the above query. */
|
||||
assert( startEq==0 && (op==OP_SeekGT || op==OP_SeekLT) );
|
||||
assert( (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)!=0 && pWInfo->nOBSat>0 );
|
||||
sqlite3VdbeChangeP2(v, -1, sqlite3VdbeCurrentAddr(v)+1);
|
||||
assert( bSeekPastNull==0 || bStopAtNull==0 );
|
||||
if( regBignull ){
|
||||
assert( bSeekPastNull==1 || bStopAtNull==1 );
|
||||
assert( bSeekPastNull==!bStopAtNull );
|
||||
assert( bStopAtNull==startEq );
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2);
|
||||
|
||||
op = aStartOp[(start_constraints<<2) + (1<<1) + bRev];
|
||||
assert( op==OP_SeekGE || op==OP_SeekLE );
|
||||
sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
|
||||
op = aStartOp[(nConstraint>1)*4 + 2 + bRev];
|
||||
sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase,
|
||||
nConstraint-startEq);
|
||||
VdbeCoverage(v);
|
||||
VdbeCoverageIf(v, op==OP_Rewind); testcase( op==OP_Rewind );
|
||||
VdbeCoverageIf(v, op==OP_Last); testcase( op==OP_Last );
|
||||
VdbeCoverageIf(v, op==OP_SeekGE); testcase( op==OP_SeekGE );
|
||||
VdbeCoverageIf(v, op==OP_SeekLE); testcase( op==OP_SeekLE );
|
||||
assert( op==OP_Rewind || op==OP_Last || op==OP_SeekGE || op==OP_SeekLE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1744,8 +1752,10 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
endEq = 1;
|
||||
}
|
||||
}else if( bStopAtNull ){
|
||||
sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
|
||||
endEq = 0;
|
||||
if( regBignull==0 ){
|
||||
sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
|
||||
endEq = 0;
|
||||
}
|
||||
nConstraint++;
|
||||
}
|
||||
sqlite3DbFree(db, zStartAff);
|
||||
@@ -1756,6 +1766,12 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
|
||||
/* Check if the index cursor is past the end of the range. */
|
||||
if( nConstraint ){
|
||||
if( regBignull ){
|
||||
/* Except, skip the end-of-range check while doing the NULL-scan */
|
||||
sqlite3VdbeAddOp2(v, OP_IfNot, regBignull, sqlite3VdbeCurrentAddr(v)+3);
|
||||
VdbeComment((v, "If NULL-scan 2nd pass"));
|
||||
VdbeCoverage(v);
|
||||
}
|
||||
op = aEndOp[bRev*2 + endEq];
|
||||
sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
|
||||
testcase( op==OP_IdxGT ); VdbeCoverageIf(v, op==OP_IdxGT );
|
||||
@@ -1763,6 +1779,23 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
testcase( op==OP_IdxLT ); VdbeCoverageIf(v, op==OP_IdxLT );
|
||||
testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE );
|
||||
}
|
||||
if( regBignull ){
|
||||
/* During a NULL-scan, check to see if we have reached the end of
|
||||
** the NULLs */
|
||||
assert( bSeekPastNull==!bStopAtNull );
|
||||
assert( bSeekPastNull+bStopAtNull==1 );
|
||||
assert( nConstraint+bSeekPastNull>0 );
|
||||
sqlite3VdbeAddOp2(v, OP_If, regBignull, sqlite3VdbeCurrentAddr(v)+2);
|
||||
VdbeComment((v, "If NULL-scan 1st pass"));
|
||||
VdbeCoverage(v);
|
||||
op = aEndOp[bRev*2 + bSeekPastNull];
|
||||
sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase,
|
||||
nConstraint+bSeekPastNull);
|
||||
testcase( op==OP_IdxGT ); VdbeCoverageIf(v, op==OP_IdxGT );
|
||||
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( pLoop->wsFlags & WHERE_IN_EARLYOUT ){
|
||||
sqlite3VdbeAddOp2(v, OP_SeekHit, iIdxCur, 1);
|
||||
|
||||
+21
-7
@@ -84,7 +84,7 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){
|
||||
}else{
|
||||
pTerm->truthProb = 1;
|
||||
}
|
||||
pTerm->pExpr = sqlite3ExprSkipCollate(p);
|
||||
pTerm->pExpr = sqlite3ExprSkipCollateAndLikely(p);
|
||||
pTerm->wtFlags = wtFlags;
|
||||
pTerm->pWC = pWC;
|
||||
pTerm->iParent = -1;
|
||||
@@ -117,10 +117,16 @@ static int allowedOp(int op){
|
||||
** the left hand side of a comparison overrides any collation sequence
|
||||
** attached to the right. For the same reason the EP_Collate flag
|
||||
** is not commuted.
|
||||
**
|
||||
** The return value is extra flags that are added to the WhereTerm object
|
||||
** after it is commuted. The only extra flag ever added is TERM_NOPARTIDX
|
||||
** which prevents the term from being used to enable a partial index if
|
||||
** COLLATE changes have been made.
|
||||
*/
|
||||
static void exprCommute(Parse *pParse, Expr *pExpr){
|
||||
static u16 exprCommute(Parse *pParse, Expr *pExpr){
|
||||
u16 expRight = (pExpr->pRight->flags & EP_Collate);
|
||||
u16 expLeft = (pExpr->pLeft->flags & EP_Collate);
|
||||
u16 wtFlags = 0;
|
||||
assert( allowedOp(pExpr->op) && pExpr->op!=TK_IN );
|
||||
if( expRight==expLeft ){
|
||||
/* Either X and Y both have COLLATE operator or neither do */
|
||||
@@ -128,11 +134,13 @@ static void exprCommute(Parse *pParse, Expr *pExpr){
|
||||
/* Both X and Y have COLLATE operators. Make sure X is always
|
||||
** used by clearing the EP_Collate flag from Y. */
|
||||
pExpr->pRight->flags &= ~EP_Collate;
|
||||
wtFlags |= TERM_NOPARTIDX;
|
||||
}else if( sqlite3ExprCollSeq(pParse, pExpr->pLeft)!=0 ){
|
||||
/* Neither X nor Y have COLLATE operators, but X has a non-default
|
||||
** collating sequence. So add the EP_Collate marker on X to cause
|
||||
** it to be searched first. */
|
||||
pExpr->pLeft->flags |= EP_Collate;
|
||||
wtFlags |= TERM_NOPARTIDX;
|
||||
}
|
||||
}
|
||||
SWAP(Expr*,pExpr->pRight,pExpr->pLeft);
|
||||
@@ -144,6 +152,7 @@ static void exprCommute(Parse *pParse, Expr *pExpr){
|
||||
assert( pExpr->op>=TK_GT && pExpr->op<=TK_GE );
|
||||
pExpr->op = ((pExpr->op-TK_GT)^2)+TK_GT;
|
||||
}
|
||||
return wtFlags;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -275,6 +284,7 @@ static int isLikeOrGlob(
|
||||
** 2019-05-02 https://sqlite.org/src/info/b043a54c3de54b28
|
||||
** 2019-06-10 https://sqlite.org/src/info/fd76310a5e843e07
|
||||
** 2019-06-14 https://sqlite.org/src/info/ce8717f0885af975
|
||||
** 2019-09-03 https://sqlite.org/src/info/0f0428096f17252a
|
||||
*/
|
||||
if( pLeft->op!=TK_COLUMN
|
||||
|| sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
|
||||
@@ -284,9 +294,13 @@ static int isLikeOrGlob(
|
||||
double rDummy;
|
||||
isNum = sqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8);
|
||||
if( isNum<=0 ){
|
||||
zNew[iTo-1]++;
|
||||
isNum = sqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8);
|
||||
zNew[iTo-1]--;
|
||||
if( iTo==1 && zNew[0]=='-' ){
|
||||
isNum = +1;
|
||||
}else{
|
||||
zNew[iTo-1]++;
|
||||
isNum = sqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8);
|
||||
zNew[iTo-1]--;
|
||||
}
|
||||
}
|
||||
if( isNum>0 ){
|
||||
sqlite3ExprDelete(db, pPrefix);
|
||||
@@ -1140,7 +1154,7 @@ static void exprAnalyze(
|
||||
pDup = pExpr;
|
||||
pNew = pTerm;
|
||||
}
|
||||
exprCommute(pParse, pDup);
|
||||
pNew->wtFlags |= exprCommute(pParse, pDup);
|
||||
pNew->leftCursor = aiCurCol[0];
|
||||
pNew->u.leftColumn = aiCurCol[1];
|
||||
testcase( (prereqLeft | extraRight) != prereqLeft );
|
||||
@@ -1451,7 +1465,7 @@ static void exprAnalyze(
|
||||
** all terms of the WHERE clause.
|
||||
*/
|
||||
void sqlite3WhereSplit(WhereClause *pWC, Expr *pExpr, u8 op){
|
||||
Expr *pE2 = sqlite3ExprSkipCollate(pExpr);
|
||||
Expr *pE2 = sqlite3ExprSkipCollateAndLikely(pExpr);
|
||||
pWC->op = op;
|
||||
if( pE2==0 ) return;
|
||||
if( pE2->op!=op ){
|
||||
|
||||
+279
-89
@@ -888,7 +888,7 @@ static ExprList *exprListAppendList(
|
||||
pDup->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse);
|
||||
}
|
||||
pList = sqlite3ExprListAppend(pParse, pList, pDup);
|
||||
if( pList ) pList->a[nInit+i].sortOrder = pAppend->a[i].sortOrder;
|
||||
if( pList ) pList->a[nInit+i].sortFlags = pAppend->a[i].sortFlags;
|
||||
}
|
||||
}
|
||||
return pList;
|
||||
@@ -965,8 +965,15 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
|
||||
** window function - one for the accumulator, another for interim
|
||||
** results. */
|
||||
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
|
||||
pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
|
||||
pSublist = exprListAppendList(pParse, pSublist, pWin->pOwner->x.pList, 0);
|
||||
ExprList *pArgs = pWin->pOwner->x.pList;
|
||||
if( pWin->pFunc->funcFlags & SQLITE_FUNC_SUBTYPE ){
|
||||
selectWindowRewriteEList(pParse, pMWin, pSrc, pArgs, pTab, &pSublist);
|
||||
pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
|
||||
pWin->bExprArgs = 1;
|
||||
}else{
|
||||
pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
|
||||
pSublist = exprListAppendList(pParse, pSublist, pArgs, 0);
|
||||
}
|
||||
if( pWin->pFilter ){
|
||||
Expr *pFilter = sqlite3ExprDup(db, pWin->pFilter, 0);
|
||||
pSublist = sqlite3ExprListAppend(pParse, pSublist, pFilter);
|
||||
@@ -984,7 +991,7 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
|
||||
*/
|
||||
if( pSublist==0 ){
|
||||
pSublist = sqlite3ExprListAppend(pParse, 0,
|
||||
sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0)
|
||||
sqlite3Expr(db, TK_INTEGER, "0")
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1315,8 +1322,8 @@ void sqlite3WindowCodeInit(Parse *pParse, Window *pMWin){
|
||||
pWin->regApp = pParse->nMem+1;
|
||||
pParse->nMem += 3;
|
||||
if( pKeyInfo && pWin->pFunc->zName[1]=='i' ){
|
||||
assert( pKeyInfo->aSortOrder[0]==0 );
|
||||
pKeyInfo->aSortOrder[0] = 1;
|
||||
assert( pKeyInfo->aSortFlags[0]==0 );
|
||||
pKeyInfo->aSortFlags[0] = KEYINFO_ORDER_DESC;
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pWin->csrApp, 2);
|
||||
sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO);
|
||||
@@ -1401,6 +1408,108 @@ static int windowArgCount(Window *pWin){
|
||||
return (pList ? pList->nExpr : 0);
|
||||
}
|
||||
|
||||
typedef struct WindowCodeArg WindowCodeArg;
|
||||
typedef struct WindowCsrAndReg WindowCsrAndReg;
|
||||
|
||||
/*
|
||||
** See comments above struct WindowCodeArg.
|
||||
*/
|
||||
struct WindowCsrAndReg {
|
||||
int csr; /* Cursor number */
|
||||
int reg; /* First in array of peer values */
|
||||
};
|
||||
|
||||
/*
|
||||
** A single instance of this structure is allocated on the stack by
|
||||
** sqlite3WindowCodeStep() and a pointer to it passed to the various helper
|
||||
** routines. This is to reduce the number of arguments required by each
|
||||
** helper function.
|
||||
**
|
||||
** regArg:
|
||||
** Each window function requires an accumulator register (just as an
|
||||
** ordinary aggregate function does). This variable is set to the first
|
||||
** in an array of accumulator registers - one for each window function
|
||||
** in the WindowCodeArg.pMWin list.
|
||||
**
|
||||
** eDelete:
|
||||
** The window functions implementation sometimes caches the input rows
|
||||
** that it processes in a temporary table. If it is not zero, this
|
||||
** variable indicates when rows may be removed from the temp table (in
|
||||
** order to reduce memory requirements - it would always be safe just
|
||||
** to leave them there). Possible values for eDelete are:
|
||||
**
|
||||
** WINDOW_RETURN_ROW:
|
||||
** An input row can be discarded after it is returned to the caller.
|
||||
**
|
||||
** WINDOW_AGGINVERSE:
|
||||
** An input row can be discarded after the window functions xInverse()
|
||||
** callbacks have been invoked in it.
|
||||
**
|
||||
** WINDOW_AGGSTEP:
|
||||
** An input row can be discarded after the window functions xStep()
|
||||
** callbacks have been invoked in it.
|
||||
**
|
||||
** start,current,end
|
||||
** Consider a window-frame similar to the following:
|
||||
**
|
||||
** (ORDER BY a, b GROUPS BETWEEN 2 PRECEDING AND 2 FOLLOWING)
|
||||
**
|
||||
** The windows functions implmentation caches the input rows in a temp
|
||||
** table, sorted by "a, b" (it actually populates the cache lazily, and
|
||||
** aggressively removes rows once they are no longer required, but that's
|
||||
** a mere detail). It keeps three cursors open on the temp table. One
|
||||
** (current) that points to the next row to return to the query engine
|
||||
** once its window function values have been calculated. Another (end)
|
||||
** points to the next row to call the xStep() method of each window function
|
||||
** on (so that it is 2 groups ahead of current). And a third (start) that
|
||||
** points to the next row to call the xInverse() method of each window
|
||||
** function on.
|
||||
**
|
||||
** Each cursor (start, current and end) consists of a VDBE cursor
|
||||
** (WindowCsrAndReg.csr) and an array of registers (starting at
|
||||
** WindowCodeArg.reg) that always contains a copy of the peer values
|
||||
** read from the corresponding cursor.
|
||||
**
|
||||
** Depending on the window-frame in question, all three cursors may not
|
||||
** be required. In this case both WindowCodeArg.csr and reg are set to
|
||||
** 0.
|
||||
*/
|
||||
struct WindowCodeArg {
|
||||
Parse *pParse; /* Parse context */
|
||||
Window *pMWin; /* First in list of functions being processed */
|
||||
Vdbe *pVdbe; /* VDBE object */
|
||||
int addrGosub; /* OP_Gosub to this address to return one row */
|
||||
int regGosub; /* Register used with OP_Gosub(addrGosub) */
|
||||
int regArg; /* First in array of accumulator registers */
|
||||
int eDelete; /* See above */
|
||||
|
||||
WindowCsrAndReg start;
|
||||
WindowCsrAndReg current;
|
||||
WindowCsrAndReg end;
|
||||
};
|
||||
|
||||
/*
|
||||
** Generate VM code to read the window frames peer values from cursor csr into
|
||||
** an array of registers starting at reg.
|
||||
*/
|
||||
static void windowReadPeerValues(
|
||||
WindowCodeArg *p,
|
||||
int csr,
|
||||
int reg
|
||||
){
|
||||
Window *pMWin = p->pMWin;
|
||||
ExprList *pOrderBy = pMWin->pOrderBy;
|
||||
if( pOrderBy ){
|
||||
Vdbe *v = sqlite3GetVdbe(p->pParse);
|
||||
ExprList *pPart = pMWin->pPartition;
|
||||
int iColOff = pMWin->nBufferCol + (pPart ? pPart->nExpr : 0);
|
||||
int i;
|
||||
for(i=0; i<pOrderBy->nExpr; i++){
|
||||
sqlite3VdbeAddOp3(v, OP_Column, csr, iColOff+i, reg+i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Generate VM code to invoke either xStep() (if bInverse is 0) or
|
||||
** xInverse (if bInverse is non-zero) for each window function in the
|
||||
@@ -1421,22 +1530,27 @@ static int windowArgCount(Window *pWin){
|
||||
** number of rows in the current partition.
|
||||
*/
|
||||
static void windowAggStep(
|
||||
Parse *pParse,
|
||||
WindowCodeArg *p,
|
||||
Window *pMWin, /* Linked list of window functions */
|
||||
int csr, /* Read arguments from this cursor */
|
||||
int bInverse, /* True to invoke xInverse instead of xStep */
|
||||
int reg /* Array of registers */
|
||||
){
|
||||
Parse *pParse = p->pParse;
|
||||
Vdbe *v = sqlite3GetVdbe(pParse);
|
||||
Window *pWin;
|
||||
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
|
||||
FuncDef *pFunc = pWin->pFunc;
|
||||
int regArg;
|
||||
int nArg = windowArgCount(pWin);
|
||||
int nArg = pWin->bExprArgs ? 0 : windowArgCount(pWin);
|
||||
int i;
|
||||
|
||||
assert( bInverse==0 || pWin->eStart!=TK_UNBOUNDED );
|
||||
|
||||
/* All OVER clauses in the same window function aggregate step must
|
||||
** be the same. */
|
||||
assert( pWin==pMWin || sqlite3WindowCompare(pParse,pWin,pMWin,0)==0 );
|
||||
|
||||
for(i=0; i<nArg; i++){
|
||||
if( i!=1 || pFunc->zName!=nth_valueName ){
|
||||
sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+i, reg+i);
|
||||
@@ -1474,14 +1588,30 @@ static void windowAggStep(
|
||||
int addrIf = 0;
|
||||
if( pWin->pFilter ){
|
||||
int regTmp;
|
||||
assert( nArg==0 || nArg==pWin->pOwner->x.pList->nExpr );
|
||||
assert( nArg || pWin->pOwner->x.pList==0 );
|
||||
assert( pWin->bExprArgs || !nArg ||nArg==pWin->pOwner->x.pList->nExpr );
|
||||
assert( pWin->bExprArgs || nArg ||pWin->pOwner->x.pList==0 );
|
||||
regTmp = sqlite3GetTempReg(pParse);
|
||||
sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp);
|
||||
addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1);
|
||||
VdbeCoverage(v);
|
||||
sqlite3ReleaseTempReg(pParse, regTmp);
|
||||
}
|
||||
|
||||
if( pWin->bExprArgs ){
|
||||
int iStart = sqlite3VdbeCurrentAddr(v);
|
||||
VdbeOp *pOp, *pEnd;
|
||||
|
||||
nArg = pWin->pOwner->x.pList->nExpr;
|
||||
regArg = sqlite3GetTempRange(pParse, nArg);
|
||||
sqlite3ExprCodeExprList(pParse, pWin->pOwner->x.pList, regArg, 0, 0);
|
||||
|
||||
pEnd = sqlite3VdbeGetOp(v, -1);
|
||||
for(pOp=sqlite3VdbeGetOp(v, iStart); pOp<=pEnd; pOp++){
|
||||
if( pOp->opcode==OP_Column && pOp->p1==pWin->iEphCsr ){
|
||||
pOp->p1 = csr;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
|
||||
CollSeq *pColl;
|
||||
assert( nArg>0 );
|
||||
@@ -1492,32 +1622,14 @@ static void windowAggStep(
|
||||
bInverse, regArg, pWin->regAccum);
|
||||
sqlite3VdbeAppendP4(v, pFunc, P4_FUNCDEF);
|
||||
sqlite3VdbeChangeP5(v, (u8)nArg);
|
||||
if( pWin->bExprArgs ){
|
||||
sqlite3ReleaseTempRange(pParse, regArg, nArg);
|
||||
}
|
||||
if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct WindowCodeArg WindowCodeArg;
|
||||
typedef struct WindowCsrAndReg WindowCsrAndReg;
|
||||
struct WindowCsrAndReg {
|
||||
int csr;
|
||||
int reg;
|
||||
};
|
||||
|
||||
struct WindowCodeArg {
|
||||
Parse *pParse;
|
||||
Window *pMWin;
|
||||
Vdbe *pVdbe;
|
||||
int regGosub;
|
||||
int addrGosub;
|
||||
int regArg;
|
||||
int eDelete;
|
||||
|
||||
WindowCsrAndReg start;
|
||||
WindowCsrAndReg current;
|
||||
WindowCsrAndReg end;
|
||||
};
|
||||
|
||||
/*
|
||||
** Values that may be passed as the second argument to windowCodeOp().
|
||||
*/
|
||||
@@ -1525,28 +1637,6 @@ struct WindowCodeArg {
|
||||
#define WINDOW_AGGINVERSE 2
|
||||
#define WINDOW_AGGSTEP 3
|
||||
|
||||
/*
|
||||
** Generate VM code to read the window frames peer values from cursor csr into
|
||||
** an array of registers starting at reg.
|
||||
*/
|
||||
static void windowReadPeerValues(
|
||||
WindowCodeArg *p,
|
||||
int csr,
|
||||
int reg
|
||||
){
|
||||
Window *pMWin = p->pMWin;
|
||||
ExprList *pOrderBy = pMWin->pOrderBy;
|
||||
if( pOrderBy ){
|
||||
Vdbe *v = sqlite3GetVdbe(p->pParse);
|
||||
ExprList *pPart = pMWin->pPartition;
|
||||
int iColOff = pMWin->nBufferCol + (pPart ? pPart->nExpr : 0);
|
||||
int i;
|
||||
for(i=0; i<pOrderBy->nExpr; i++){
|
||||
sqlite3VdbeAddOp3(v, OP_Column, csr, iColOff+i, reg+i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Generate VM code to invoke either xValue() (bFin==0) or xFinalize()
|
||||
** (bFin==1) for each window function in the linked list starting at
|
||||
@@ -1609,6 +1699,8 @@ static void windowFullScan(WindowCodeArg *p){
|
||||
int addrNext;
|
||||
int csr;
|
||||
|
||||
VdbeModuleComment((v, "windowFullScan begin"));
|
||||
|
||||
assert( pMWin!=0 );
|
||||
csr = pMWin->csrApp;
|
||||
nPeer = (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0);
|
||||
@@ -1665,7 +1757,7 @@ static void windowFullScan(WindowCodeArg *p){
|
||||
if( addrEq ) sqlite3VdbeJumpHere(v, addrEq);
|
||||
}
|
||||
|
||||
windowAggStep(pParse, pMWin, csr, 0, p->regArg);
|
||||
windowAggStep(p, pMWin, csr, 0, p->regArg);
|
||||
|
||||
sqlite3VdbeResolveLabel(v, lblNext);
|
||||
sqlite3VdbeAddOp2(v, OP_Next, csr, addrNext);
|
||||
@@ -1680,6 +1772,7 @@ static void windowFullScan(WindowCodeArg *p){
|
||||
}
|
||||
|
||||
windowAggFinal(p, 1);
|
||||
VdbeModuleComment((v, "windowFullScan end"));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1854,34 +1947,46 @@ static void windowIfNewPeer(
|
||||
/*
|
||||
** This function is called as part of generating VM programs for RANGE
|
||||
** offset PRECEDING/FOLLOWING frame boundaries. Assuming "ASC" order for
|
||||
** the ORDER BY term in the window, it generates code equivalent to:
|
||||
** the ORDER BY term in the window, and that argument op is OP_Ge, it generates
|
||||
** code equivalent to:
|
||||
**
|
||||
** if( csr1.peerVal + regVal >= csr2.peerVal ) goto lbl;
|
||||
**
|
||||
** A special type of arithmetic is used such that if csr.peerVal is not
|
||||
** a numeric type (real or integer), then the result of the addition is
|
||||
** a copy of csr1.peerVal.
|
||||
** The value of parameter op may also be OP_Gt or OP_Le. In these cases the
|
||||
** operator in the above pseudo-code is replaced with ">" or "<=", respectively.
|
||||
**
|
||||
** If the sort-order for the ORDER BY term in the window is DESC, then the
|
||||
** comparison is reversed. Instead of adding regVal to csr1.peerVal, it is
|
||||
** subtracted. And the comparison operator is inverted to - ">=" becomes "<=",
|
||||
** ">" becomes "<", and so on. So, with DESC sort order, if the argument op
|
||||
** is OP_Ge, the generated code is equivalent to:
|
||||
**
|
||||
** if( csr1.peerVal - regVal <= csr2.peerVal ) goto lbl;
|
||||
**
|
||||
** A special type of arithmetic is used such that if csr1.peerVal is not
|
||||
** a numeric type (real or integer), then the result of the addition addition
|
||||
** or subtraction is a a copy of csr1.peerVal.
|
||||
*/
|
||||
static void windowCodeRangeTest(
|
||||
WindowCodeArg *p,
|
||||
int op, /* OP_Ge or OP_Gt */
|
||||
int csr1,
|
||||
int regVal,
|
||||
int csr2,
|
||||
int lbl
|
||||
int op, /* OP_Ge, OP_Gt, or OP_Le */
|
||||
int csr1, /* Cursor number for cursor 1 */
|
||||
int regVal, /* Register containing non-negative number */
|
||||
int csr2, /* Cursor number for cursor 2 */
|
||||
int lbl /* Jump destination if condition is true */
|
||||
){
|
||||
Parse *pParse = p->pParse;
|
||||
Vdbe *v = sqlite3GetVdbe(pParse);
|
||||
int reg1 = sqlite3GetTempReg(pParse);
|
||||
int reg2 = sqlite3GetTempReg(pParse);
|
||||
int arith = OP_Add;
|
||||
int addrGe;
|
||||
|
||||
int regString = ++pParse->nMem;
|
||||
ExprList *pOrderBy = p->pMWin->pOrderBy; /* ORDER BY clause for window */
|
||||
int reg1 = sqlite3GetTempReg(pParse); /* Reg. for csr1.peerVal+regVal */
|
||||
int reg2 = sqlite3GetTempReg(pParse); /* Reg. for csr2.peerVal */
|
||||
int regString = ++pParse->nMem; /* Reg. for constant value '' */
|
||||
int arith = OP_Add; /* OP_Add or OP_Subtract */
|
||||
int addrGe; /* Jump destination */
|
||||
|
||||
assert( op==OP_Ge || op==OP_Gt || op==OP_Le );
|
||||
assert( p->pMWin->pOrderBy && p->pMWin->pOrderBy->nExpr==1 );
|
||||
if( p->pMWin->pOrderBy->a[0].sortOrder ){
|
||||
assert( pOrderBy && pOrderBy->nExpr==1 );
|
||||
if( pOrderBy->a[0].sortFlags & KEYINFO_ORDER_DESC ){
|
||||
switch( op ){
|
||||
case OP_Ge: op = OP_Le; break;
|
||||
case OP_Gt: op = OP_Lt; break;
|
||||
@@ -1890,27 +1995,95 @@ static void windowCodeRangeTest(
|
||||
arith = OP_Subtract;
|
||||
}
|
||||
|
||||
/* Read the peer-value from each cursor into a register */
|
||||
windowReadPeerValues(p, csr1, reg1);
|
||||
windowReadPeerValues(p, csr2, reg2);
|
||||
|
||||
/* Check if the peer value for csr1 value is a text or blob by comparing
|
||||
** it to the smallest possible string - ''. If it is, jump over the
|
||||
** OP_Add or OP_Subtract operation and proceed directly to the comparison. */
|
||||
VdbeModuleComment((v, "CodeRangeTest: if( R%d %s R%d %s R%d ) goto lbl",
|
||||
reg1, (arith==OP_Add ? "+" : "-"), regVal,
|
||||
((op==OP_Ge) ? ">=" : (op==OP_Le) ? "<=" : (op==OP_Gt) ? ">" : "<"), reg2
|
||||
));
|
||||
|
||||
/* Register reg1 currently contains csr1.peerVal (the peer-value from csr1).
|
||||
** This block adds (or subtracts for DESC) the numeric value in regVal
|
||||
** from it. Or, if reg1 is not numeric (it is a NULL, a text value or a blob),
|
||||
** then leave reg1 as it is. In pseudo-code, this is implemented as:
|
||||
**
|
||||
** if( reg1>='' ) goto addrGe;
|
||||
** reg1 = reg1 +/- regVal
|
||||
** addrGe:
|
||||
**
|
||||
** Since all strings and blobs are greater-than-or-equal-to an empty string,
|
||||
** the add/subtract is skipped for these, as required. If reg1 is a NULL,
|
||||
** then the arithmetic is performed, but since adding or subtracting from
|
||||
** NULL is always NULL anyway, this case is handled as required too. */
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, regString, 0, "", P4_STATIC);
|
||||
addrGe = sqlite3VdbeAddOp3(v, OP_Ge, regString, 0, reg1);
|
||||
VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp3(v, arith, regVal, reg1, reg1);
|
||||
sqlite3VdbeJumpHere(v, addrGe);
|
||||
|
||||
/* If the BIGNULL flag is set for the ORDER BY, then it is required to
|
||||
** consider NULL values to be larger than all other values, instead of
|
||||
** the usual smaller. The VDBE opcodes OP_Ge and so on do not handle this
|
||||
** (and adding that capability causes a performance regression), so
|
||||
** instead if the BIGNULL flag is set then cases where either reg1 or
|
||||
** reg2 are NULL are handled separately in the following block. The code
|
||||
** generated is equivalent to:
|
||||
**
|
||||
** if( reg1 IS NULL ){
|
||||
** if( op==OP_Ge ) goto lbl;
|
||||
** if( op==OP_Gt && reg2 IS NOT NULL ) goto lbl;
|
||||
** if( op==OP_Le && reg2 IS NULL ) goto lbl;
|
||||
** }else if( reg2 IS NULL ){
|
||||
** if( op==OP_Le ) goto lbl;
|
||||
** }
|
||||
**
|
||||
** Additionally, if either reg1 or reg2 are NULL but the jump to lbl is
|
||||
** not taken, control jumps over the comparison operator coded below this
|
||||
** block. */
|
||||
if( pOrderBy->a[0].sortFlags & KEYINFO_ORDER_BIGNULL ){
|
||||
/* This block runs if reg1 contains a NULL. */
|
||||
int addr = sqlite3VdbeAddOp1(v, OP_NotNull, reg1); VdbeCoverage(v);
|
||||
switch( op ){
|
||||
case OP_Ge:
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, lbl);
|
||||
break;
|
||||
case OP_Gt:
|
||||
sqlite3VdbeAddOp2(v, OP_NotNull, reg2, lbl);
|
||||
VdbeCoverage(v);
|
||||
break;
|
||||
case OP_Le:
|
||||
sqlite3VdbeAddOp2(v, OP_IsNull, reg2, lbl);
|
||||
VdbeCoverage(v);
|
||||
break;
|
||||
default: assert( op==OP_Lt ); /* no-op */ break;
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+3);
|
||||
|
||||
/* This block runs if reg1 is not NULL, but reg2 is. */
|
||||
sqlite3VdbeJumpHere(v, addr);
|
||||
sqlite3VdbeAddOp2(v, OP_IsNull, reg2, lbl); VdbeCoverage(v);
|
||||
if( op==OP_Gt || op==OP_Ge ){
|
||||
sqlite3VdbeChangeP2(v, -1, sqlite3VdbeCurrentAddr(v)+1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Compare registers reg2 and reg1, taking the jump if required. Note that
|
||||
** control skips over this test if the BIGNULL flag is set and either
|
||||
** reg1 or reg2 contain a NULL value. */
|
||||
sqlite3VdbeAddOp3(v, op, reg2, lbl, reg1); VdbeCoverage(v);
|
||||
sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
|
||||
|
||||
assert( op==OP_Ge || op==OP_Gt || op==OP_Lt || op==OP_Le );
|
||||
testcase(op==OP_Ge); VdbeCoverageIf(v, op==OP_Ge);
|
||||
testcase(op==OP_Lt); VdbeCoverageIf(v, op==OP_Lt);
|
||||
testcase(op==OP_Le); VdbeCoverageIf(v, op==OP_Le);
|
||||
testcase(op==OP_Gt); VdbeCoverageIf(v, op==OP_Gt);
|
||||
|
||||
sqlite3ReleaseTempReg(pParse, reg1);
|
||||
sqlite3ReleaseTempReg(pParse, reg2);
|
||||
|
||||
VdbeModuleComment((v, "CodeRangeTest: end"));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1930,9 +2103,7 @@ static int windowCodeOp(
|
||||
Window *pMWin = p->pMWin;
|
||||
int ret = 0;
|
||||
Vdbe *v = p->pVdbe;
|
||||
int addrIf = 0;
|
||||
int addrContinue = 0;
|
||||
int addrGoto = 0;
|
||||
int bPeer = (pMWin->eFrmType!=TK_ROWS);
|
||||
|
||||
int lblDone = sqlite3VdbeMakeLabel(pParse);
|
||||
@@ -1965,7 +2136,7 @@ static int windowCodeOp(
|
||||
);
|
||||
}
|
||||
}else{
|
||||
addrIf = sqlite3VdbeAddOp3(v, OP_IfPos, regCountdown, 0, 1);
|
||||
sqlite3VdbeAddOp3(v, OP_IfPos, regCountdown, lblDone, 1);
|
||||
VdbeCoverage(v);
|
||||
}
|
||||
}
|
||||
@@ -1974,6 +2145,25 @@ static int windowCodeOp(
|
||||
windowAggFinal(p, 0);
|
||||
}
|
||||
addrContinue = sqlite3VdbeCurrentAddr(v);
|
||||
|
||||
/* If this is a (RANGE BETWEEN a FOLLOWING AND b FOLLOWING) or
|
||||
** (RANGE BETWEEN b PRECEDING AND a PRECEDING) frame, ensure the
|
||||
** start cursor does not advance past the end cursor within the
|
||||
** temporary table. It otherwise might, if (a>b). */
|
||||
if( pMWin->eStart==pMWin->eEnd && regCountdown
|
||||
&& pMWin->eFrmType==TK_RANGE && op==WINDOW_AGGINVERSE
|
||||
){
|
||||
int regRowid1 = sqlite3GetTempReg(pParse);
|
||||
int regRowid2 = sqlite3GetTempReg(pParse);
|
||||
sqlite3VdbeAddOp2(v, OP_Rowid, p->start.csr, regRowid1);
|
||||
sqlite3VdbeAddOp2(v, OP_Rowid, p->end.csr, regRowid2);
|
||||
sqlite3VdbeAddOp3(v, OP_Ge, regRowid2, lblDone, regRowid1);
|
||||
VdbeCoverage(v);
|
||||
sqlite3ReleaseTempReg(pParse, regRowid1);
|
||||
sqlite3ReleaseTempReg(pParse, regRowid2);
|
||||
assert( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_FOLLOWING );
|
||||
}
|
||||
|
||||
switch( op ){
|
||||
case WINDOW_RETURN_ROW:
|
||||
csr = p->current.csr;
|
||||
@@ -1988,7 +2178,7 @@ static int windowCodeOp(
|
||||
assert( pMWin->regEndRowid );
|
||||
sqlite3VdbeAddOp2(v, OP_AddImm, pMWin->regStartRowid, 1);
|
||||
}else{
|
||||
windowAggStep(pParse, pMWin, csr, 1, p->regArg);
|
||||
windowAggStep(p, pMWin, csr, 1, p->regArg);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -2000,7 +2190,7 @@ static int windowCodeOp(
|
||||
assert( pMWin->regEndRowid );
|
||||
sqlite3VdbeAddOp2(v, OP_AddImm, pMWin->regEndRowid, 1);
|
||||
}else{
|
||||
windowAggStep(pParse, pMWin, csr, 0, p->regArg);
|
||||
windowAggStep(p, pMWin, csr, 0, p->regArg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2018,7 +2208,7 @@ static int windowCodeOp(
|
||||
sqlite3VdbeAddOp2(v, OP_Next, csr, sqlite3VdbeCurrentAddr(v)+1+bPeer);
|
||||
VdbeCoverage(v);
|
||||
if( bPeer ){
|
||||
addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, lblDone);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2034,8 +2224,6 @@ static int windowCodeOp(
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNextRange);
|
||||
}
|
||||
sqlite3VdbeResolveLabel(v, lblDone);
|
||||
if( addrGoto ) sqlite3VdbeJumpHere(v, addrGoto);
|
||||
if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2051,6 +2239,7 @@ Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){
|
||||
pNew = sqlite3DbMallocZero(db, sizeof(Window));
|
||||
if( pNew ){
|
||||
pNew->zName = sqlite3DbStrDup(db, p->zName);
|
||||
pNew->zBase = sqlite3DbStrDup(db, p->zBase);
|
||||
pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0);
|
||||
pNew->pFunc = p->pFunc;
|
||||
pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0);
|
||||
@@ -2063,6 +2252,7 @@ Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){
|
||||
pNew->pStart = sqlite3ExprDup(db, p->pStart, 0);
|
||||
pNew->pEnd = sqlite3ExprDup(db, p->pEnd, 0);
|
||||
pNew->pOwner = pOwner;
|
||||
pNew->bImplicitFrame = p->bImplicitFrame;
|
||||
}
|
||||
}
|
||||
return pNew;
|
||||
@@ -2386,7 +2576,7 @@ static int windowExprGtZero(Parse *pParse, Expr *pExpr){
|
||||
** regEnd = <expr2>
|
||||
** regStart = <expr1>
|
||||
** }else{
|
||||
** if( (csrEnd.key + regEnd) <= csrCurrent.key ){
|
||||
** while( (csrEnd.key + regEnd) <= csrCurrent.key ){
|
||||
** AGGSTEP
|
||||
** }
|
||||
** while( (csrStart.key + regStart) < csrCurrent.key ){
|
||||
@@ -2459,8 +2649,6 @@ void sqlite3WindowCodeStep(
|
||||
int addrGosubFlush = 0; /* Address of OP_Gosub to flush: */
|
||||
int addrInteger = 0; /* Address of OP_Integer */
|
||||
int addrEmpty; /* Address of OP_Rewind in flush: */
|
||||
int regStart = 0; /* Value of <expr> PRECEDING */
|
||||
int regEnd = 0; /* Value of <expr> FOLLOWING */
|
||||
int regNew; /* Array of registers holding new input row */
|
||||
int regRecord; /* regNew array in record form */
|
||||
int regRowid; /* Rowid for regRecord in eph table */
|
||||
@@ -2469,6 +2657,8 @@ void sqlite3WindowCodeStep(
|
||||
int regFlushPart = 0; /* Register for "Gosub flush_partition" */
|
||||
WindowCodeArg s; /* Context object for sub-routines */
|
||||
int lblWhereEnd; /* Label just before sqlite3WhereEnd() code */
|
||||
int regStart = 0; /* Value of <expr> PRECEDING */
|
||||
int regEnd = 0; /* Value of <expr> FOLLOWING */
|
||||
|
||||
assert( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_CURRENT
|
||||
|| pMWin->eStart==TK_FOLLOWING || pMWin->eStart==TK_UNBOUNDED
|
||||
@@ -2599,14 +2789,14 @@ void sqlite3WindowCodeStep(
|
||||
|
||||
if( regStart ){
|
||||
sqlite3ExprCode(pParse, pMWin->pStart, regStart);
|
||||
windowCheckValue(pParse, regStart, 0 + (pMWin->eFrmType==TK_RANGE ? 3 : 0));
|
||||
windowCheckValue(pParse, regStart, 0 + (pMWin->eFrmType==TK_RANGE?3:0));
|
||||
}
|
||||
if( regEnd ){
|
||||
sqlite3ExprCode(pParse, pMWin->pEnd, regEnd);
|
||||
windowCheckValue(pParse, regEnd, 1 + (pMWin->eFrmType==TK_RANGE ? 3 : 0));
|
||||
windowCheckValue(pParse, regEnd, 1 + (pMWin->eFrmType==TK_RANGE?3:0));
|
||||
}
|
||||
|
||||
if( pMWin->eStart==pMWin->eEnd && regStart ){
|
||||
if( pMWin->eFrmType!=TK_RANGE && pMWin->eStart==pMWin->eEnd && regStart ){
|
||||
int op = ((pMWin->eStart==TK_FOLLOWING) ? OP_Ge : OP_Le);
|
||||
int addrGe = sqlite3VdbeAddOp3(v, op, regStart, 0, regEnd);
|
||||
VdbeCoverageNeverNullIf(v, op==OP_Ge); /* NeverNull because bound <expr> */
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix affinity2
|
||||
|
||||
do_execsql_test affinity2-100 {
|
||||
CREATE TABLE t1(
|
||||
@@ -58,4 +59,78 @@ do_execsql_test affinity2-300 {
|
||||
SELECT rowid, xt==+xi, xt==xi, xt==xb FROM t1 ORDER BY rowid;
|
||||
} {1 1 1 0 2 1 1 1 3 0 1 1}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
do_execsql_test 400 {
|
||||
CREATE TABLE ttt(c0, c1);
|
||||
CREATE INDEX ii ON ttt(CAST(c0 AS NUMERIC));
|
||||
INSERT INTO ttt VALUES('abc', '-1');
|
||||
}
|
||||
do_execsql_test 410 {
|
||||
SELECT * FROM ttt WHERE CAST(c0 AS NUMERIC) > c1 GROUP BY rowid;
|
||||
} {abc -1}
|
||||
do_execsql_test 420 {
|
||||
SELECT * FROM ttt INDEXED BY ii WHERE CAST(c0 AS NUMERIC) > c1 GROUP BY rowid;
|
||||
} {abc -1}
|
||||
|
||||
do_execsql_test 430 {
|
||||
CREATE TABLE t3(a, b, c INTEGER);
|
||||
CREATE INDEX t3ac ON t3(a, c-1);
|
||||
INSERT INTO t3 VALUES(1, 1, 1);
|
||||
INSERT INTO t3 VALUES(2, 1, 0);
|
||||
INSERT INTO t3 VALUES(3, 1, 1);
|
||||
INSERT INTO t3 VALUES(4, 1, 0);
|
||||
INSERT INTO t3 VALUES(5, 1, 1);
|
||||
}
|
||||
do_execsql_test 440 {
|
||||
SELECT * FROM t3 WHERE c='0' ORDER BY a;
|
||||
} {2 1 0 4 1 0}
|
||||
|
||||
# 2019-08-22 ticket https://sqlite.org/src/info/d99f1ffe836c591ac57f
|
||||
# False positive in sqlite3ExprNeedsNoAffinityChange()
|
||||
#
|
||||
do_execsql_test 500 {
|
||||
DROP TABLE IF EXISTS t0;
|
||||
CREATE TABLE t0(c0 TEXT UNIQUE, c1);
|
||||
INSERT INTO t0(c0) VALUES (-1);
|
||||
SELECT quote(- x'ce'), quote(t0.c0), quote(- x'ce' >= t0.c0) FROM t0;
|
||||
} {0 '-1' 1}
|
||||
do_execsql_test 501 {
|
||||
SELECT * FROM t0 WHERE - x'ce' >= t0.c0;
|
||||
} {-1 {}}
|
||||
do_execsql_test 502 {
|
||||
SELECT quote(+-+x'ce'), quote(t0.c0), quote(+-+x'ce' >= t0.c0) FROM t0;
|
||||
} {0 '-1' 1}
|
||||
do_execsql_test 503 {
|
||||
SELECT * FROM t0 WHERE +-+x'ce' >= t0.c0;
|
||||
} {-1 {}}
|
||||
do_execsql_test 504 {
|
||||
SELECT quote(- 'ce'), quote(t0.c0), quote(- 'ce' >= t0.c0) FROM t0;
|
||||
} {0 '-1' 1}
|
||||
do_execsql_test 505 {
|
||||
SELECT * FROM t0 WHERE - 'ce' >= t0.c0;
|
||||
} {-1 {}}
|
||||
do_execsql_test 506 {
|
||||
SELECT quote(+-+'ce'), quote(t0.c0), quote(+-+'ce' >= t0.c0) FROM t0;
|
||||
} {0 '-1' 1}
|
||||
do_execsql_test 507 {
|
||||
SELECT * FROM t0 WHERE +-+'ce' >= t0.c0;
|
||||
} {-1 {}}
|
||||
|
||||
# 2019-08-30 ticket https://www.sqlite.org/src/info/40812aea1fde9594
|
||||
#
|
||||
# Due to some differences in floating point computations, these tests do not
|
||||
# work under valgrind.
|
||||
#
|
||||
if {![info exists ::G(valgrind)]} {
|
||||
do_execsql_test 600 {
|
||||
DROP TABLE IF EXISTS t0;
|
||||
CREATE TABLE t0(c0 REAL UNIQUE);
|
||||
INSERT INTO t0(c0) VALUES (3175546974276630385);
|
||||
SELECT 3175546974276630385 < c0 FROM t0;
|
||||
} {1}
|
||||
do_execsql_test 601 {
|
||||
SELECT 1 FROM t0 WHERE 3175546974276630385 < c0;
|
||||
} {1}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
+29
-1
@@ -1,4 +1,4 @@
|
||||
# 2012 August 23
|
||||
# 2012-08-23
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
@@ -232,6 +232,34 @@ do_test aggnested-3.16 {
|
||||
GROUP BY id1;
|
||||
}
|
||||
} {12 2 34 4}
|
||||
|
||||
# 2019-08-31
|
||||
# Problem found by dbsqlfuzz
|
||||
#
|
||||
do_execsql_test aggnested-4.1 {
|
||||
DROP TABLE IF EXISTS aa;
|
||||
DROP TABLE IF EXISTS bb;
|
||||
CREATE TABLE aa(x INT); INSERT INTO aa(x) VALUES(123);
|
||||
CREATE TABLE bb(y INT); INSERT INTO bb(y) VALUES(456);
|
||||
SELECT (SELECT sum(x+(SELECT y)) FROM bb) FROM aa;
|
||||
} {579}
|
||||
do_execsql_test aggnested-4.2 {
|
||||
SELECT (SELECT sum(x+y) FROM bb) FROM aa;
|
||||
} {579}
|
||||
do_execsql_test aggnested-4.3 {
|
||||
DROP TABLE IF EXISTS tx;
|
||||
DROP TABLE IF EXISTS ty;
|
||||
CREATE TABLE tx(x INT);
|
||||
INSERT INTO tx VALUES(1),(2),(3),(4),(5);
|
||||
CREATE TABLE ty(y INT);
|
||||
INSERT INTO ty VALUES(91),(92),(93);
|
||||
SELECT min((SELECT count(y) FROM ty)) FROM tx;
|
||||
} {3}
|
||||
do_execsql_test aggnested-4.4 {
|
||||
SELECT max((SELECT a FROM (SELECT count(*) AS a FROM ty) AS s)) FROM tx;
|
||||
} {3}
|
||||
|
||||
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -123,6 +123,11 @@ do_test check-2.1 {
|
||||
y REAL CONSTRAINT two CHECK( typeof(coalesce(y,0.1))=='real' ),
|
||||
z TEXT CONSTRAINT three CHECK( typeof(coalesce(z,''))=='text' )
|
||||
);
|
||||
CREATE TABLE t2n(
|
||||
x INTEGER CONSTRAINT one CHECK( typeof(coalesce(x,0))=="integer" ),
|
||||
y NUMERIC CONSTRAINT two CHECK( typeof(coalesce(y,0.1))=='real' ),
|
||||
z TEXT CONSTRAINT three CHECK( typeof(coalesce(z,''))=='text' )
|
||||
);
|
||||
PRAGMA writable_schema = 0;
|
||||
}
|
||||
} {}
|
||||
@@ -146,9 +151,17 @@ do_test check-2.4 {
|
||||
}
|
||||
} {1 {CHECK constraint failed: one}}
|
||||
do_test check-2.5 {
|
||||
# The 5 gets automatically promoted to 5.0 because the column type is REAL
|
||||
catchsql {
|
||||
INSERT INTO t2 VALUES(NULL, 5, NULL);
|
||||
}
|
||||
} {0 {}}
|
||||
do_test check-2.5b {
|
||||
# This time the column type is NUMERIC, so not automatic promption to REAL
|
||||
# occurs and the constraint fails.
|
||||
catchsql {
|
||||
INSERT INTO t2n VALUES(NULL, 5, NULL);
|
||||
}
|
||||
} {1 {CHECK constraint failed: two}}
|
||||
do_test check-2.6 {
|
||||
catchsql {
|
||||
@@ -195,6 +208,7 @@ do_test check-2.cleanup {
|
||||
execsql {
|
||||
DROP TABLE IF EXISTS t2b;
|
||||
DROP TABLE IF EXISTS t2c;
|
||||
DROP TABLE IF EXISTS t2n;
|
||||
}
|
||||
} {}
|
||||
|
||||
|
||||
@@ -366,5 +366,73 @@ do_execsql_test 12.3 {
|
||||
SELECT * FROM t2;
|
||||
} {111 111B 112 112}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
ifcapable trigger {
|
||||
reset_db
|
||||
do_execsql_test 13.1.0 {
|
||||
PRAGMA recursive_triggers = true;
|
||||
CREATE TABLE t0 (c0 UNIQUE, c1 UNIQUE);
|
||||
CREATE TRIGGER tr0 AFTER DELETE ON t0 BEGIN
|
||||
DELETE FROM t0;
|
||||
END;
|
||||
|
||||
INSERT INTO t0 VALUES(1, NULL);
|
||||
INSERT INTO t0 VALUES(0, NULL);
|
||||
}
|
||||
|
||||
do_execsql_test 13.1.1 {
|
||||
UPDATE OR REPLACE t0 SET c1 = 1;
|
||||
}
|
||||
|
||||
integrity_check 13.1.2
|
||||
|
||||
do_execsql_test 13.1.3 {
|
||||
SELECT * FROM t0
|
||||
} {}
|
||||
|
||||
do_execsql_test 13.2.0 {
|
||||
CREATE TABLE t2 (a PRIMARY KEY, b UNIQUE, c UNIQUE) WITHOUT ROWID;
|
||||
CREATE TRIGGER tr3 AFTER DELETE ON t2 BEGIN
|
||||
DELETE FROM t2;
|
||||
END;
|
||||
|
||||
INSERT INTO t2 VALUES(1, 1, 1);
|
||||
INSERT INTO t2 VALUES(2, 2, 2);
|
||||
}
|
||||
|
||||
do_execsql_test 13.2.1 {
|
||||
UPDATE OR REPLACE t2 SET c = 0;
|
||||
}
|
||||
|
||||
integrity_check 13.2.2
|
||||
|
||||
do_execsql_test 13.2.3 {
|
||||
SELECT * FROM t2
|
||||
} {}
|
||||
|
||||
do_execsql_test 13.3.0 {
|
||||
CREATE TABLE t1(a, b);
|
||||
CREATE TABLE log(x);
|
||||
CREATE INDEX i1 ON t1(a);
|
||||
INSERT INTO t1 VALUES(1, 2);
|
||||
|
||||
CREATE TRIGGER tb BEFORE UPDATE ON t1 BEGIN
|
||||
DELETE FROM t1;
|
||||
END;
|
||||
CREATE TRIGGER ta AFTER UPDATE ON t1 BEGIN
|
||||
INSERT INTO log VALUES('fired!');
|
||||
END;
|
||||
|
||||
UPDATE t1 SET b=3;
|
||||
}
|
||||
|
||||
do_execsql_test 13.3.1 {
|
||||
SELECT * FROM t1;
|
||||
} {}
|
||||
do_execsql_test 13.3.2 {
|
||||
SELECT * FROM log;
|
||||
} {}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
+10
-4
@@ -377,11 +377,14 @@ do_test 4.0 {
|
||||
| end crash-6b48ba69806134.db
|
||||
}]} {}
|
||||
|
||||
set res {1 {database disk image is malformed}}
|
||||
ifcapable oversize_cell_check {
|
||||
set res {1 {no such table: t3}}
|
||||
}
|
||||
do_catchsql_test 4.1 {
|
||||
PRAGMA writable_schema=ON; -- bypass improved sqlite_master consistency checking
|
||||
INSERT INTO t3 SELECT * FROM t2;
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
} $res
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
@@ -835,11 +838,14 @@ do_test 8.0 {
|
||||
| end a.db
|
||||
}]} {}
|
||||
|
||||
|
||||
set res {1 {database disk image is malformed}}
|
||||
ifcapable oversize_cell_check {
|
||||
set res {1 {no such table: t3}}
|
||||
}
|
||||
do_catchsql_test 8.1 {
|
||||
PRAGMA writable_schema=ON; -- bypass improved sqlite_master consistency checking
|
||||
INSERT INTO t3 SELECT * FROM t2;
|
||||
} {1 {database disk image is malformed}}
|
||||
} $res
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
|
||||
+36
-52
@@ -22,6 +22,16 @@ set testprefix corruptM
|
||||
#
|
||||
database_may_be_corrupt
|
||||
|
||||
proc open_db2_and_catchsql {sql} {
|
||||
set rc [catch { sqlite3 db2 test.db } msg]
|
||||
if {$rc} {
|
||||
return [list $rc $msg]
|
||||
}
|
||||
set res [catchsql $sql db2]
|
||||
db2 close
|
||||
set res
|
||||
}
|
||||
|
||||
db close
|
||||
forcedelete test.db
|
||||
sqlite3 db test.db
|
||||
@@ -38,165 +48,139 @@ do_execsql_test corruptM-101 {
|
||||
UPDATE sqlite_master SET tbl_name=NULL WHERE name='t1';
|
||||
SELECT type, name, tbl_name, '|' FROM sqlite_master;
|
||||
} {table t1 {} | index i1 t1 | view v2 v2 | trigger r1 t1 |}
|
||||
sqlite3 db2 test.db
|
||||
do_test corruptM-102 {
|
||||
catchsql {
|
||||
open_db2_and_catchsql {
|
||||
PRAGMA quick_check;
|
||||
} db2
|
||||
}
|
||||
} {1 {malformed database schema (t1)}}
|
||||
db2 close
|
||||
|
||||
do_execsql_test corruptM-110 {
|
||||
UPDATE sqlite_master SET tbl_name='tx' WHERE name='t1';
|
||||
SELECT type, name, tbl_name, '|' FROM sqlite_master;
|
||||
} {table t1 tx | index i1 t1 | view v2 v2 | trigger r1 t1 |}
|
||||
sqlite3 db2 test.db
|
||||
do_test corruptM-111 {
|
||||
catchsql {
|
||||
open_db2_and_catchsql {
|
||||
PRAGMA quick_check;
|
||||
} db2
|
||||
}
|
||||
} {1 {malformed database schema (t1)}}
|
||||
db2 close
|
||||
do_execsql_test corruptM-112 {
|
||||
UPDATE sqlite_master SET tbl_name='t1', type='tabl' WHERE name='t1';
|
||||
SELECT type, name, tbl_name, '|' FROM sqlite_master;
|
||||
} {tabl t1 t1 | index i1 t1 | view v2 v2 | trigger r1 t1 |}
|
||||
sqlite3 db2 test.db
|
||||
do_test corruptM-113 {
|
||||
catchsql {
|
||||
open_db2_and_catchsql {
|
||||
PRAGMA quick_check;
|
||||
} db2
|
||||
}
|
||||
} {1 {malformed database schema (t1)}}
|
||||
db2 close
|
||||
do_execsql_test corruptM-114 {
|
||||
UPDATE sqlite_master SET tbl_name='t9',type='table',name='t9'WHERE name='t1';
|
||||
SELECT type, name, tbl_name, '|' FROM sqlite_master;
|
||||
} {table t9 t9 | index i1 t1 | view v2 v2 | trigger r1 t1 |}
|
||||
sqlite3 db2 test.db
|
||||
do_test corruptM-114 {
|
||||
catchsql {
|
||||
open_db2_and_catchsql {
|
||||
PRAGMA quick_check;
|
||||
} db2
|
||||
}
|
||||
} {1 {malformed database schema (t9)}}
|
||||
db2 close
|
||||
|
||||
do_execsql_test corruptM-120 {
|
||||
UPDATE sqlite_master SET name='t1',tbl_name='T1' WHERE name='t9';
|
||||
SELECT type, name, tbl_name, '|' FROM sqlite_master;
|
||||
} {table t1 T1 | index i1 t1 | view v2 v2 | trigger r1 t1 |}
|
||||
sqlite3 db2 test.db
|
||||
do_test corruptM-121 {
|
||||
catchsql {
|
||||
open_db2_and_catchsql {
|
||||
PRAGMA quick_check;
|
||||
SELECT * FROM t1, v2;
|
||||
} db2
|
||||
}
|
||||
} {0 {ok 111 222 333 15 22}}
|
||||
db2 close
|
||||
|
||||
do_execsql_test corruptM-130 {
|
||||
UPDATE sqlite_master SET type='view' WHERE name='t1';
|
||||
SELECT type, name, tbl_name, '|' FROM sqlite_master;
|
||||
} {view t1 T1 | index i1 t1 | view v2 v2 | trigger r1 t1 |}
|
||||
sqlite3 db2 test.db
|
||||
do_test corruptM-131 {
|
||||
catchsql {
|
||||
open_db2_and_catchsql {
|
||||
PRAGMA quick_check;
|
||||
SELECT * FROM t1, v2;
|
||||
} db2
|
||||
}
|
||||
} {1 {malformed database schema (t1)}}
|
||||
db2 close
|
||||
|
||||
do_execsql_test corruptM-140 {
|
||||
UPDATE sqlite_master SET type='table', tbl_name='t1' WHERE name='t1';
|
||||
UPDATE sqlite_master SET tbl_name='tx' WHERE name='i1';
|
||||
SELECT type, name, tbl_name, '|' FROM sqlite_master;
|
||||
} {table t1 t1 | index i1 tx | view v2 v2 | trigger r1 t1 |}
|
||||
sqlite3 db2 test.db
|
||||
do_test corruptM-141 {
|
||||
catchsql {
|
||||
open_db2_and_catchsql {
|
||||
PRAGMA quick_check;
|
||||
SELECT * FROM t1, v2;
|
||||
} db2
|
||||
}
|
||||
} {1 {malformed database schema (i1)}}
|
||||
db2 close
|
||||
|
||||
do_execsql_test corruptM-150 {
|
||||
UPDATE sqlite_master SET type='table', tbl_name='t1' WHERE name='i1';
|
||||
SELECT type, name, tbl_name, '|' FROM sqlite_master;
|
||||
} {table t1 t1 | table i1 t1 | view v2 v2 | trigger r1 t1 |}
|
||||
sqlite3 db2 test.db
|
||||
do_test corruptM-151 {
|
||||
catchsql {
|
||||
open_db2_and_catchsql {
|
||||
PRAGMA quick_check;
|
||||
SELECT * FROM t1, v2;
|
||||
} db2
|
||||
}
|
||||
} {1 {malformed database schema (i1)}}
|
||||
db2 close
|
||||
|
||||
do_execsql_test corruptM-160 {
|
||||
UPDATE sqlite_master SET type='view', tbl_name='t1' WHERE name='i1';
|
||||
SELECT type, name, tbl_name, '|' FROM sqlite_master;
|
||||
} {table t1 t1 | view i1 t1 | view v2 v2 | trigger r1 t1 |}
|
||||
sqlite3 db2 test.db
|
||||
do_test corruptM-161 {
|
||||
catchsql {
|
||||
open_db2_and_catchsql {
|
||||
PRAGMA quick_check;
|
||||
SELECT * FROM t1, v2;
|
||||
} db2
|
||||
}
|
||||
} {1 {malformed database schema (i1)}}
|
||||
db2 close
|
||||
|
||||
do_execsql_test corruptM-170 {
|
||||
UPDATE sqlite_master SET type='index', tbl_name='t1' WHERE name='i1';
|
||||
UPDATE sqlite_master SET type='table', tbl_name='v2' WHERE name='v2';
|
||||
SELECT type, name, tbl_name, '|' FROM sqlite_master;
|
||||
} {table t1 t1 | index i1 t1 | table v2 v2 | trigger r1 t1 |}
|
||||
sqlite3 db2 test.db
|
||||
do_test corruptM-171 {
|
||||
catchsql {
|
||||
open_db2_and_catchsql {
|
||||
PRAGMA quick_check;
|
||||
SELECT * FROM t1, v2;
|
||||
} db2
|
||||
}
|
||||
} {1 {malformed database schema (v2)}}
|
||||
db2 close
|
||||
|
||||
do_execsql_test corruptM-180 {
|
||||
UPDATE sqlite_master SET type='view',name='v3',tbl_name='v3' WHERE name='v2';
|
||||
SELECT type, name, tbl_name, '|' FROM sqlite_master;
|
||||
} {table t1 t1 | index i1 t1 | view v3 v3 | trigger r1 t1 |}
|
||||
sqlite3 db2 test.db
|
||||
do_test corruptM-181 {
|
||||
catchsql {
|
||||
open_db2_and_catchsql {
|
||||
PRAGMA quick_check;
|
||||
SELECT * FROM t1, v2;
|
||||
} db2
|
||||
}
|
||||
} {1 {malformed database schema (v3)}}
|
||||
db2 close
|
||||
|
||||
do_execsql_test corruptM-190 {
|
||||
UPDATE sqlite_master SET type='view',name='v2',tbl_name='v2' WHERE name='v3';
|
||||
UPDATE sqlite_master SET type='view' WHERE name='r1';
|
||||
SELECT type, name, tbl_name, '|' FROM sqlite_master;
|
||||
} {table t1 t1 | index i1 t1 | view v2 v2 | view r1 t1 |}
|
||||
sqlite3 db2 test.db
|
||||
do_test corruptM-191 {
|
||||
catchsql {
|
||||
open_db2_and_catchsql {
|
||||
PRAGMA quick_check;
|
||||
SELECT * FROM t1, v2;
|
||||
} db2
|
||||
}
|
||||
} {1 {malformed database schema (r1)}}
|
||||
db2 close
|
||||
do_execsql_test corruptM-192 {
|
||||
UPDATE sqlite_master SET type='trigger',tbl_name='v2' WHERE name='r1';
|
||||
SELECT type, name, tbl_name, '|' FROM sqlite_master;
|
||||
} {table t1 t1 | index i1 t1 | view v2 v2 | trigger r1 v2 |}
|
||||
sqlite3 db2 test.db
|
||||
do_test corruptM-193 {
|
||||
catchsql {
|
||||
open_db2_and_catchsql {
|
||||
PRAGMA quick_check;
|
||||
SELECT * FROM t1, v2;
|
||||
} db2
|
||||
}
|
||||
} {1 {malformed database schema (r1)}}
|
||||
db2 close
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -274,6 +274,32 @@ do_execsql_test 2040 {
|
||||
two 1 1
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 3000 {
|
||||
CREATE TABLE t0 (c0, c1 NOT NULL DEFAULT 1, c2, PRIMARY KEY (c0, c1));
|
||||
INSERT INTO t0(c2) VALUES (NULL), (NULL), (NULL), (NULL), (NULL), (NULL), (NULL), (NULL), (NULL), (NULL), (NULL);
|
||||
INSERT INTO t0(c2) VALUES('a');
|
||||
}
|
||||
|
||||
do_execsql_test 3010 {
|
||||
SELECT DISTINCT * FROM t0 WHERE NULL IS t0.c0;
|
||||
} {
|
||||
{} 1 {}
|
||||
{} 1 a
|
||||
}
|
||||
|
||||
do_execsql_test 3020 {
|
||||
ANALYZE;
|
||||
}
|
||||
|
||||
do_execsql_test 3030 {
|
||||
SELECT DISTINCT * FROM t0 WHERE NULL IS c0;
|
||||
} {
|
||||
{} 1 {}
|
||||
{} 1 a
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
@@ -101,4 +101,68 @@ do_catchsql_test 2.3 {
|
||||
SELECT sum(a) FILTER (WHERE 1 - count(a)) FROM t1
|
||||
} {1 {misuse of aggregate function count()}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 3.0 {
|
||||
CREATE TABLE t1(a,b);
|
||||
INSERT INTO t1 VALUES(1, 1);
|
||||
}
|
||||
do_execsql_test 3.1 {
|
||||
SELECT b, max(a) FILTER (WHERE b='x') FROM t1;
|
||||
} {1 {}}
|
||||
|
||||
do_execsql_test 3.2 {
|
||||
CREATE TABLE t2(a, b, c);
|
||||
INSERT INTO t2 VALUES(1, 2, 3);
|
||||
INSERT INTO t2 VALUES(1, 3, 4);
|
||||
INSERT INTO t2 VALUES(2, 5, 6);
|
||||
INSERT INTO t2 VALUES(2, 7, 8);
|
||||
}
|
||||
do_execsql_test 3.3 {
|
||||
SELECT a, c, max(b) FILTER (WHERE c='x') FROM t2 GROUP BY a;
|
||||
} {1 3 {} 2 6 {}}
|
||||
|
||||
do_execsql_test 3.4 {
|
||||
DELETE FROM t2;
|
||||
INSERT INTO t2 VALUES(1, 5, 'x');
|
||||
INSERT INTO t2 VALUES(1, 2, 3);
|
||||
INSERT INTO t2 VALUES(1, 4, 'x');
|
||||
INSERT INTO t2 VALUES(2, 5, 6);
|
||||
INSERT INTO t2 VALUES(2, 7, 8);
|
||||
}
|
||||
do_execsql_test 3.5 {
|
||||
SELECT a, c, max(b) FILTER (WHERE c='x') FROM t2 GROUP BY a;
|
||||
} {1 x 5 2 6 {}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 4.0 {
|
||||
CREATE TABLE t1(a, b, c);
|
||||
INSERT INTO t1 VALUES('a', 0, 5);
|
||||
INSERT INTO t1 VALUES('a', 1, 10);
|
||||
INSERT INTO t1 VALUES('a', 0, 15);
|
||||
|
||||
INSERT INTO t1 VALUES('b', 0, 5);
|
||||
INSERT INTO t1 VALUES('b', 1, 1000);
|
||||
INSERT INTO t1 VALUES('b', 0, 5);
|
||||
|
||||
INSERT INTO t1 VALUES('c', 0, 1);
|
||||
INSERT INTO t1 VALUES('c', 1, 2);
|
||||
INSERT INTO t1 VALUES('c', 0, 3);
|
||||
}
|
||||
|
||||
do_execsql_test 4.1 {
|
||||
SELECT avg(c) FILTER (WHERE b!=1) AS h FROM t1 GROUP BY a ORDER BY h;
|
||||
} {2.0 5.0 10.0}
|
||||
do_execsql_test 4.2 {
|
||||
SELECT avg(c) FILTER (WHERE b!=1) AS h FROM t1 GROUP BY a ORDER BY (h+1.0);
|
||||
} {2.0 5.0 10.0}
|
||||
do_execsql_test 4.3 {
|
||||
SELECT a, avg(c) FILTER (WHERE b!=1) AS h FROM t1 GROUP BY a ORDER BY avg(c);
|
||||
} {c 2.0 a 10.0 b 5.0}
|
||||
do_execsql_test 4.4 {
|
||||
SELECT a, avg(c) FILTER (WHERE b!=1) FROM t1 GROUP BY a ORDER BY 2
|
||||
} {c 2.0 b 5.0 a 10.0}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
@@ -5329,4 +5329,221 @@ do_catchsql_test 29.1 {
|
||||
INSERT INTO t1(t1) SELECT x FROM t2;
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
reset_db
|
||||
do_test 30.0 {
|
||||
sqlite3 db {}
|
||||
db deserialize [decode_hexdb {
|
||||
| size 28672 pagesize 4096 filename crash-e6e3857edf9b26.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 0e b1 00 06 0d a4 00 0f 8d 0f 21 ...............!
|
||||
| 112: 0e b9 0d c8 0e 7e 0d a4 00 00 00 00 00 00 00 00 .....~..........
|
||||
| 3488: 00 00 00 00 22 07 06 17 11 11 01 31 74 61 62 6c ...........1tabl
|
||||
| 3504: 65 74 32 74 32 07 43 52 45 41 54 45 20 54 41 42 et2t2.CREATE TAB
|
||||
| 3520: 4c 45 20 74 32 28 78 29 81 33 05 07 17 1f 1f 01 LE t2(x).3......
|
||||
| 3536: 82 35 74 61 62 6c 65 74 31 5f 73 65 67 64 69 72 .5tablet1_segdir
|
||||
| 3552: 74 31 5f 73 65 67 64 69 72 05 43 52 45 41 54 45 t1_segdir.CREATE
|
||||
| 3568: 20 54 41 42 4c 45 20 27 74 31 5f 73 65 67 64 69 TABLE 't1_segdi
|
||||
| 3584: 72 27 28 6c 65 76 65 6c 20 49 4e 54 45 47 45 52 r'(level INTEGER
|
||||
| 3600: 2c 69 64 78 20 49 4e 54 45 47 45 52 2c 73 74 61 ,idx INTEGER,sta
|
||||
| 3616: 72 74 5f 62 6c 6f 63 6b 20 49 4e 54 45 47 45 52 rt_block INTEGER
|
||||
| 3632: 2c 6c 65 61 76 65 73 5f 65 6e 64 5f 62 6c 6f 63 ,leaves_end_bloc
|
||||
| 3648: 6b 20 49 4e 54 45 47 45 52 2c 65 6e 64 5f 62 6c k INTEGER,end_bl
|
||||
| 3664: 6f 63 6b 20 49 4e 54 45 47 45 62 2c 72 6f 6f 74 ock INTEGEb,root
|
||||
| 3680: 20 42 4c 4f 42 2c 50 52 49 4d 41 52 59 20 4b 45 BLOB,PRIMARY KE
|
||||
| 3696: 59 28 6c 65 76 65 6c 2c 20 69 64 78 29 29 31 06 Y(level, idx))1.
|
||||
| 3712: 06 17 45 1f 01 00 69 6e 64 65 78 73 71 6c 69 74 ..E...indexsqlit
|
||||
| 3728: 65 5f 61 75 74 6f 69 6e 64 65 78 5f 74 31 5f 73 e_autoindex_t1_s
|
||||
| 3744: 65 67 64 69 72 5f 31 74 31 5f 73 65 67 64 69 72 egdir_1t1_segdir
|
||||
| 3760: 06 0f c7 00 08 00 00 00 00 66 04 07 17 23 23 01 .........f...##.
|
||||
| 3776: 81 13 74 61 62 6c 65 74 31 5f 73 65 67 6d 65 6e ..tablet1_segmen
|
||||
| 3792: 74 73 74 31 5f 73 65 67 6d 65 6e 74 73 04 43 52 tst1_segments.CR
|
||||
| 3808: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 73 EATE TABLE 't1_s
|
||||
| 3824: 65 67 6d 65 6e 74 73 27 28 62 6c 6f 63 6b 69 64 egments'(blockid
|
||||
| 3840: 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 INTEGER PRIMARY
|
||||
| 3856: 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42 KEY, block BLOB
|
||||
| 3872: 29 6a 03 07 17 21 21 01 81 1f 74 61 62 6c 65 74 )j...!!...tablet
|
||||
| 3888: 31 5f 63 6f 6e 74 65 6e 74 74 31 5f 63 6f 6e 74 1_contentt1_cont
|
||||
| 3904: 65 6e 74 03 43 52 45 41 54 45 20 54 41 42 4c 45 ent.CREATE TABLE
|
||||
| 3920: 20 27 74 31 5f 63 6f 6e 74 65 6e 74 27 28 64 6f 't1_content'(do
|
||||
| 3936: 63 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d cid INTEGER PRIM
|
||||
| 3952: 41 52 59 20 4b 45 59 2c 20 27 63 30 61 27 2c 20 ARY KEY, 'c0a',
|
||||
| 3968: 27 63 31 62 27 2c 20 27 63 32 63 27 29 38 02 06 'c1b', 'c2c')8..
|
||||
| 3984: 17 11 11 08 5f 74 61 62 6c 65 74 31 74 31 43 52 ...._tablet1t1CR
|
||||
| 4000: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 EATE VIRTUAL TAB
|
||||
| 4016: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 33 LE t1 USING fts3
|
||||
| 4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00 (a,b,c).........
|
||||
| page 3 offset 8192
|
||||
| 0: 0d 00 00 00 25 0b 48 00 0f d8 0f af 0f 86 0f 74 ....%.H........t
|
||||
| 16: 0f 61 0f 4e 0f 2f 0f 0f 0e ef 0e d7 0e be 0e a5 .a.N./..........
|
||||
| 32: 0e 8d 0e 74 0e 5b 0e 40 0e 24 0e 08 0d ef 00 00 ...t.[.@.$......
|
||||
| 2880: 00 00 00 00 00 00 00 00 81 3f 25 06 00 82 7e f0 .........?%...~.
|
||||
| 2896: 00 43 4f 4d 50 49 4c 45 52 3d 67 63 63 2d 35 2e .COMPILER=gcc-5.
|
||||
| 2912: 34 23 00 20 32 30 31 36 30 36 30 39 20 44 45 42 4#. 20160609 DEB
|
||||
| 2928: 55 47 20 45 4e 41 42 4c 45 20 44 42 53 54 41 54 UG ENABLE DBSTAT
|
||||
| 2944: 20 56 54 41 42 20 45 4e 42 92 4c 45 20 46 54 53 VTAB ENB.LE FTS
|
||||
| 2960: 34 20 45 4e 41 42 4c 45 20 46 54 53 35 20 45 4e 4 ENABLE FTS5 EN
|
||||
| 2976: 41 42 4c 45 20 47 45 4f 50 4f 4c 59 20 45 4e 41 ABLE GEOPOLY ENA
|
||||
| 2992: 42 4c 45 1f 4a 53 4f 4e 31 20 45 4e 41 42 4c 49 BLE.JSON1 ENABLI
|
||||
| 3008: 00 4d 45 4d 53 59 53 35 20 45 4e 41 42 4c 45 20 .MEMSYS5 ENABLE
|
||||
| 3024: 52 54 52 45 45 20 4d 41 58 20 4d 45 4d 4f 52 59 RTREE MAX MEMORY
|
||||
| 3040: 3d 35 30 30 30 30 30 30 30 20 4f 4d 49 54 20 4c =50000000 OMIT L
|
||||
| 3056: 4f 41 44 20 45 58 54 45 4e 53 49 4f 4e 20 54 48 OAD EXTENSION TH
|
||||
| 3072: 52 45 41 44 53 41 46 45 3d 30 18 24 05 00 25 0f READSAFE=0.$..%.
|
||||
| 3088: 19 54 48 52 45 41 44 53 41 46 45 3d 30 58 42 49 .THREADSAFE=0XBI
|
||||
| 3104: 4e 41 52 59 18 23 05 00 25 0f 19 54 48 52 45 41 NARY.#..%..THREA
|
||||
| 3120: 44 53 41 46 45 3d 30 88 4e 4f 43 41 53 45 17 22 DSAFE=0.NOCASE..
|
||||
| 3136: 05 00 25 0f 17 54 48 52 45 41 44 53 41 46 45 3d ..%..THREADSAFE=
|
||||
| 3152: 30 58 52 54 52 49 4d 1f 21 05 00 33 0f 19 4f 4d 0XRTRIM.!..3..OM
|
||||
| 3168: 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 4f IT LOAD EXTENSIO
|
||||
| 3184: 4e 58 42 49 4e 41 52 59 1f 20 05 00 33 0f 19 4f NXBINARY. ..3..O
|
||||
| 3200: 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 MIT LOAD EXTENSI
|
||||
| 3216: 4f 4e 58 4e 4f 43 41 53 45 1e 20 05 00 33 0f 17 ONXNOCASE. ..3..
|
||||
| 3232: 4f 4d 49 54 20 4c 4f 41 54 20 45 58 54 45 4e 53 OMIT LOAT EXTENS
|
||||
| 3248: 49 4f 4e 58 52 54 52 49 4d 1f 1e 04 00 33 0f 19 IONXRTRIM....3..
|
||||
| 3264: 82 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 30 .AX MEMORY=50000
|
||||
| 3280: 30 30 30 58 42 49 4e 41 52 59 1f 1d 05 00 33 0f 000XBINARY....3.
|
||||
| 3296: 19 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 .MAX MEMORY=5000
|
||||
| 3312: 30 30 30 30 58 4e 4f 43 41 53 45 1e 1c 05 00 33 0000XNOCASE....3
|
||||
| 3328: 0f 17 4d 41 58 20 4d 45 4d fa 52 59 3d 35 30 20 ..MAX MEM.RY=50
|
||||
| 3344: 30 30 30 30 30 58 52 54 52 49 4d 18 1b 05 00 25 00000XRTRIM....%
|
||||
| 3360: 0f 19 45 4e 41 42 4c 45 20 52 53 52 45 45 58 42 ..ENABLE RSREEXB
|
||||
| 3376: 49 4e 41 52 59 18 1a 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB
|
||||
| 3392: 4c 45 20 52 54 52 45 45 58 4e 4f 53 41 53 45 17 LE RTREEXNOSASE.
|
||||
| 3408: 19 05 00 25 0f 17 45 4e 42 42 4c 45 20 52 54 52 ...%..ENBBLE RTR
|
||||
| 3424: 45 45 58 52 54 52 49 4d 1a 18 05 00 29 0f 19 45 EEXRTRIM....)..E
|
||||
| 3440: 4e 41 42 4c 45 20 4d 45 4d 53 5a 53 35 58 42 49 NABLE MEMSZS5XBI
|
||||
| 3456: 4e 41 52 59 1a 17 05 00 29 0f 19 45 4e 41 42 3c NARY....)..ENAB<
|
||||
| 3472: 45 20 4d 45 4d 53 59 53 35 58 4e 4f 43 41 53 45 E MEMSYS5XNOCASE
|
||||
| 3488: 19 16 05 00 29 0f 17 45 4e 41 42 4c 45 20 4d 45 ....)..ENABLE ME
|
||||
| 3504: 4d 53 59 53 35 58 52 54 52 49 4d 18 15 05 00 25 MSYS5XRTRIM....%
|
||||
| 3520: 0f 19 45 4e 41 42 4c 45 20 4a 53 4f 4e 31 58 42 ..ENABLE JSON1XB
|
||||
| 3536: 49 4e 41 52 59 18 14 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB
|
||||
| 3552: 4c 45 20 4a 53 4f 4e 31 58 4e 4f 43 41 53 45 17 LE JSON1XNOCASE.
|
||||
| 3568: 13 05 00 25 0f 17 45 4e 41 42 4c 45 20 4a 53 4f ...%..ENABLE JSO
|
||||
| 3584: 4e 31 58 52 54 52 49 4d 1a 12 05 00 29 0f 19 45 N1XRTRIM....)..E
|
||||
| 3600: 4e 31 42 4c 45 20 47 45 4e 50 4f 4c 59 58 42 49 N1BLE GENPOLYXBI
|
||||
| 3616: 4e 41 52 59 1a 11 05 00 29 0f 19 45 4e f2 1e 4c NARY....)..EN..L
|
||||
| 3632: 45 20 47 45 4f 50 4f 4c 59 58 4e 4f 43 41 53 45 E GEOPOLYXNOCASE
|
||||
| 3648: 19 10 05 00 29 0f 17 45 4e 41 42 4c 45 20 47 45 ....)..ENABLE GE
|
||||
| 3664: 4f 50 4f 4c 59 58 52 54 52 49 4d 17 0f 05 00 23 OPOLYXRTRIM....#
|
||||
| 3680: 0f 19 45 4e 41 42 4c 45 20 46 54 53 35 58 42 49 ..ENABLE FTS5XBI
|
||||
| 3696: 4e 41 52 59 17 0e 05 00 23 0f 19 45 4e 41 42 3c NARY....#..ENAB<
|
||||
| 3712: 45 20 46 54 53 35 58 4e 4f 43 41 53 45 16 0d 05 E FTS5XNOCASE...
|
||||
| 3728: 00 23 0f 17 45 4e 41 42 4c 45 20 46 54 53 35 58 .#..ENABLE FTS5X
|
||||
| 3744: 52 54 52 49 4d 17 0c 05 00 23 0f 19 45 4e 41 42 RTRIM....#..ENAB
|
||||
| 3760: 4c 45 20 46 54 53 34 58 42 49 4e 41 52 59 17 0b LE FTS4XBINARY..
|
||||
| 3776: 05 00 23 0f 19 45 4e 41 43 4c 45 20 46 54 53 35 ..#..ENACLE FTS5
|
||||
| 3792: 58 4e 4f 43 40 53 45 16 0a 05 00 23 0f 17 45 4e XNOC@SE....#..EN
|
||||
| 3808: 41 42 4c 45 20 46 54 53 34 58 52 54 52 49 4d 1e ABLE FTS4XRTRIM.
|
||||
| 3824: 09 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
|
||||
| 3840: 54 41 55 20 56 54 41 42 58 42 49 4e 41 52 59 1e TAU VTABXBINARY.
|
||||
| 3856: 08 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
|
||||
| 3872: 54 41 54 20 56 54 41 42 58 4e 4f 43 41 53 45 1d TAT VTABXNOCASE.
|
||||
| 3888: 07 05 00 31 0f 17 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
|
||||
| 3904: 54 41 54 20 56 54 41 42 58 52 54 62 49 4d 11 06 TAT VTABXRTbIM..
|
||||
| 3920: 05 00 17 0f 19 44 45 42 54 47 58 42 49 4e 41 52 .....DEBTGXBINAR
|
||||
| 3936: 59 11 05 05 00 17 0f 19 54 45 42 55 47 58 4e 4f Y.......TEBUGXNO
|
||||
| 3952: 43 41 53 45 10 04 05 00 17 0f 17 44 45 42 55 47 CASE.......DEBUG
|
||||
| 3968: 68 52 54 52 49 4d 27 03 05 00 43 0f 19 43 4f 4d hRTRIM'...C..COM
|
||||
| 3984: 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e 30 20 PILER=gcc-5.4.0
|
||||
| 4000: 32 30 31 36 30 36 30 39 58 42 49 4e 41 52 59 27 20160609XBINARY'
|
||||
| 4016: 02 05 00 43 0f 19 43 4f 4d 50 49 4c 45 52 3d 67 ...C..COMPILER=g
|
||||
| 4032: 63 63 2d 35 2e 34 2e 30 20 32 30 31 36 30 36 30 cc-5.4.0 2016060
|
||||
| 4048: 39 58 4f 4f 43 41 53 45 26 01 05 00 43 0f 17 43 9XOOCASE&...C..C
|
||||
| 4064: 4f 4d 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e OMPILER=gcc-5.4.
|
||||
| 4080: 30 20 32 30 31 36 30 36 30 39 58 52 54 52 49 4d 0 20160609XRTRIM
|
||||
| page 4 offset 12288
|
||||
| 0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||
| page 5 offset 16384
|
||||
| 0: 0d 00 00 00 02 0b a0 00 0c ad 0b a0 00 00 00 00 ................
|
||||
| 2976: 82 0a 02 08 08 09 08 08 17 84 06 30 20 32 35 33 ...........0 253
|
||||
| 2992: 00 01 30 04 25 06 1b 00 00 08 32 30 31 36 30 36 ..0.%.....201606
|
||||
| 3008: 30 39 03 25 07 00 00 01 34 03 25 05 00 00 01 35 09.%....4.%....5
|
||||
| 3024: 03 25 04 00 01 07 30 30 30 30 30 30 30 03 25 1a .%....0000000.%.
|
||||
| 3040: 00 00 08 63 6f 6d 70 69 6c 65 72 03 25 02 00 00 ...compiler.%...
|
||||
| 3056: 06 64 62 73 74 61 74 03 25 0a 00 01 04 65 62 75 .dbstat.%....ebu
|
||||
| 3072: 67 03 25 08 00 00 06 65 6e 61 62 6c 65 09 25 09 g.%....enable.%.
|
||||
| 3088: 05 04 04 04 04 04 00 01 08 78 74 65 6e 73 69 6f .........xtensio
|
||||
| 3104: 6e 03 25 1d 00 00 04 66 74 73 34 03 25 0d 00 03 n.%....fts4.%...
|
||||
| 3120: 01 35 03 25 0f 00 00 03 67 63 63 03 25 03 00 01 .5.%....gcc.%...
|
||||
| 3136: 06 65 6f 70 6f 6c 79 03 25 11 00 00 05 6a 73 6f .eopoly.%....jso
|
||||
| 3152: 6e 31 03 25 14 00 e8 04 6c 6f 61 64 03 25 1c 00 n1.%....load.%..
|
||||
| 3168: 00 03 6d 61 78 03 25 18 00 01 05 65 6d 6f 72 79 ..max.%....emory
|
||||
| 3184: 03 25 19 00 03 04 73 79 73 35 03 25 15 00 00 04 .%....sys5.%....
|
||||
| 3200: 6f 6d 69 74 03 25 1b 00 00 05 72 74 72 65 65 03 omit.%....rtree.
|
||||
| 3216: 25 17 00 00 0a 74 68 72 65 61 64 73 61 66 65 03 %....threadsafe.
|
||||
| 3232: 25 1e 00 00 04 76 74 61 62 03 25 0b 00 86 50 01 %....vtab.%...P.
|
||||
| 3248: 08 08 08 08 08 17 8d 12 30 20 38 33 35 00 01 30 ........0 835..0
|
||||
| 3264: 12 01 06 00 01 06 00 01 06 00 1f 03 00 01 03 00 ................
|
||||
| 3280: 01 03 00 00 08 32 30 31 36 30 36 30 39 09 01 07 .....20160609...
|
||||
| 3296: 00 01 07 00 01 07 00 00 01 34 09 01 05 00 01 05 .........4......
|
||||
| 3312: 00 01 05 00 00 01 35 09 01 04 00 01 04 00 01 04 ......5.........
|
||||
| 3328: 00 01 07 30 30 30 30 30 30 30 09 1c 04 00 01 04 ...0000000......
|
||||
| 3344: 00 01 04 00 00 06 62 69 6e 61 72 79 3c 03 01 02 ......binary<...
|
||||
| 3360: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 ................
|
||||
| 3376: 00 03 01 02 f2 00 03 01 02 02 00 03 01 02 02 00 ................
|
||||
| 3392: 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 03 ................
|
||||
| 3408: 01 02 02 00 03 01 02 02 00 00 08 63 6f 6d 70 69 ...........compi
|
||||
| 3424: 6c 65 72 09 01 02 00 01 02 00 01 02 00 00 06 64 ler............d
|
||||
| 3440: 62 73 74 61 74 09 07 03 00 01 03 00 01 03 00 01 bstat...........
|
||||
| 3456: 04 65 62 75 67 09 04 02 00 01 02 00 01 02 00 00 .ebug...........
|
||||
| 3472: 06 65 6e 60 62 6c 65 3f 07 02 00 01 02 00 01 01 .en`ble?........
|
||||
| 3488: ff f1 b1 00 00 02 3f 01 01 f0 f1 02 00 57 02 00 ......?......W..
|
||||
| 3504: 01 02 00 01 02 00 01 02 00 01 02 00 01 02 10 01 ................
|
||||
| 3520: 02 00 01 02 00 01 02 00 01 02 01 01 02 00 01 02 ................
|
||||
| 3536: 00 01 02 00 00 f2 00 01 08 78 74 65 6e 73 69 6f .........xtensio
|
||||
| 3552: 6e 09 1f 04 00 01 04 00 01 04 00 00 04 66 74 73 n............fts
|
||||
| 3568: 34 09 0a 03 00 01 03 00 01 03 00 03 01 35 09 0d 4............5..
|
||||
| 3584: 03 00 01 03 00 01 03 00 00 03 67 63 63 09 01 03 ..........gcc...
|
||||
| 3600: 00 01 03 00 01 03 00 01 06 65 6f 70 6f 6c 79 09 .........eopoly.
|
||||
| 3616: 10 03 00 01 03 00 01 03 00 00 b3 6a 73 6f 6e 31 ...........json1
|
||||
| 3632: 09 13 03 00 01 03 00 01 03 00 00 04 6c 6f 61 64 ............load
|
||||
| 3648: 09 1f 03 00 01 03 00 01 03 00 00 03 6d 61 78 09 ............max.
|
||||
| 3664: 1c 02 00 01 02 00 01 02 00 01 05 65 6d 6f 72 79 ...........emory
|
||||
| 3680: 09 1c 03 00 01 03 00 01 03 00 03 04 73 79 73 35 ............sys5
|
||||
| 3696: 09 16 03 00 01 03 00 01 03 cc 00 06 6e 6f 63 61 ............noca
|
||||
| 3712: 73 65 3c 02 01 02 02 00 03 01 02 02 00 03 01 02 se<.............
|
||||
| 3728: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 ................
|
||||
| 3744: 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 ................
|
||||
| 3760: 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 00 ................
|
||||
| 3776: 04 6f 6d 69 74 09 1f 02 00 01 02 00 01 02 00 00 .omit...........
|
||||
| 3792: 05 72 74 62 65 65 09 19 03 00 01 03 00 01 03 00 .rtbee..........
|
||||
| 3808: 03 02 69 6d 3c 01 01 02 02 00 03 01 02 02 00 03 ..im<...........
|
||||
| 3824: 01 02 02 00 03 01 02 02 00 03 01 02 02 00 03 01 ................
|
||||
| 3840: 02 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 ................
|
||||
| 3856: 02 00 03 01 02 02 00 03 01 02 01 00 03 01 02 02 ................
|
||||
| 3872: 00 00 0a 74 68 72 65 61 64 73 61 66 65 09 22 02 ...threadsafe...
|
||||
| 3888: 00 01 02 00 02 02 00 00 04 76 74 61 62 09 07 04 .........vtab...
|
||||
| 3904: 00 01 03 00 01 04 00 00 01 78 b4 01 01 01 01 02 .........x......
|
||||
| 3920: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 ................
|
||||
| 3936: 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01 ................
|
||||
| 3952: 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01 ................
|
||||
| 3968: 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01 ................
|
||||
| 3984: 02 01 01 01 01 02 00 01 01 01 02 00 01 01 01 02 ................
|
||||
| 4000: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 ................
|
||||
| 4016: 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01 ................
|
||||
| 4032: 01 01 02 00 01 01 01 da 00 01 01 01 02 00 01 01 ................
|
||||
| 4048: 01 02 00 01 01 01 01 ff ff 01 01 02 00 01 01 01 ................
|
||||
| 4064: 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 ................
|
||||
| 4080: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 ................
|
||||
| page 6 offset 20480
|
||||
| 0: 0a 00 00 00 02 0f f5 00 0f fb 0f f5 01 00 00 00 ................
|
||||
| 4080: 00 00 00 00 00 05 04 08 09 01 02 04 04 08 08 09 ................
|
||||
| page 7 offset 24576
|
||||
| 0: 01 6f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .o..............
|
||||
| end crash-e6e3857edf9b26.db
|
||||
}]} {}
|
||||
|
||||
do_execsql_test 30.1 {
|
||||
UPDATE t1 SET b=a;
|
||||
}
|
||||
|
||||
do_catchsql_test 30.2 {
|
||||
SELECT (matchinfo(null)) FROM t1 WHERE t1 MATCH 'ee*e*e*e*e*e*e*Re*e*e*e**'
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -561,7 +561,31 @@ do_test 4.3 {
|
||||
}]
|
||||
} {64}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Request a snippet from a query with more than 64 phrases.
|
||||
#
|
||||
do_execsql_test 5.0 {
|
||||
CREATE VIRTUAL TABLE t5 USING fts3(x);
|
||||
INSERT INTO t5 VALUES('a1 a2 a3');
|
||||
INSERT INTO t5 VALUES('a4 a5 a6');
|
||||
INSERT INTO t5 VALUES('a70 a71 a72');
|
||||
}
|
||||
|
||||
do_execsql_test 5.1 {
|
||||
SELECT snippet(t5, '[', ']') FROM t5 WHERE t5 MATCH
|
||||
'a1 OR a2 OR a3 OR a4 OR a5 OR a6 OR a7 OR a8 OR a9 OR a10 OR ' ||
|
||||
'a11 OR a12 OR a13 OR a14 OR a15 OR a16 OR a17 OR a18 OR a19 OR a10 OR ' ||
|
||||
'a21 OR a22 OR a23 OR a24 OR a25 OR a26 OR a27 OR a28 OR a29 OR a20 OR ' ||
|
||||
'a31 OR a32 OR a33 OR a34 OR a35 OR a36 OR a37 OR a38 OR a39 OR a30 OR ' ||
|
||||
'a41 OR a42 OR a43 OR a44 OR a45 OR a46 OR a47 OR a48 OR a49 OR a40 OR ' ||
|
||||
'a51 OR a52 OR a53 OR a54 OR a55 OR a56 OR a57 OR a58 OR a59 OR a50 OR ' ||
|
||||
'a61 OR a62 OR a63 OR a64 OR a65 OR a66 OR a67 OR a68 OR a69 OR a60 OR ' ||
|
||||
'a71 OR a72 OR a73 OR a74 OR a75 OR a76 OR a77 OR a78 OR a79 OR a70'
|
||||
} {
|
||||
{[a1] [a2] [a3]}
|
||||
{[a4] [a5] [a6]}
|
||||
{[a70] [a71] [a72]}
|
||||
}
|
||||
|
||||
set sqlite_fts3_enable_parentheses 0
|
||||
finish_test
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
# 2019 October 02
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#*************************************************************************
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this script is testing the FTS4 module.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix fts4merge5
|
||||
|
||||
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
|
||||
ifcapable !fts3 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
source $testdir/genesis.tcl
|
||||
|
||||
do_execsql_test 1.1 {
|
||||
CREATE TABLE t1(docid, words);
|
||||
}
|
||||
fts_kjv_genesis
|
||||
|
||||
do_execsql_test 1.2 {
|
||||
CREATE VIRTUAL TABLE x1 USING fts3;
|
||||
INSERT INTO x1(x1) VALUES('nodesize=64');
|
||||
INSERT INTO x1(x1) VALUES('maxpending=64');
|
||||
}
|
||||
|
||||
do_execsql_test 1.3 {
|
||||
INSERT INTO x1(docid, content) SELECT * FROM t1;
|
||||
}
|
||||
|
||||
for {set tn 1} {1} {incr tn} {
|
||||
set tc1 [db total_changes]
|
||||
do_execsql_test 1.4.$tn.1 {
|
||||
INSERT INTO x1(x1) VALUES('merge=1,2');
|
||||
}
|
||||
set tc2 [db total_changes]
|
||||
|
||||
if {($tc2 - $tc1)<2} break
|
||||
|
||||
do_execsql_test 1.4.$tn.1 {
|
||||
INSERT INTO x1(x1) VALUES('integrity-check');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
finish_test
|
||||
@@ -0,0 +1,120 @@
|
||||
# 2019 September 18
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#*************************************************************************
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this script is testing the FTS4 module.
|
||||
#
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
source $testdir/fts3_common.tcl
|
||||
set testprefix fts4record
|
||||
|
||||
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
|
||||
ifcapable !fts3 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
sqlite3_fts3_may_be_corrupt 1
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts4(x);
|
||||
INSERT INTO t1 VALUES('terma terma terma termb');
|
||||
}
|
||||
|
||||
do_execsql_test 1.1 {
|
||||
SELECT quote(root) FROM t1_segdir
|
||||
} {
|
||||
X'00057465726D6105010203030004016203010500'
|
||||
}
|
||||
|
||||
proc make_record_wrapper {args} { make_fts3record $args }
|
||||
db func record make_record_wrapper
|
||||
|
||||
do_execsql_test 1.2 {
|
||||
select quote(
|
||||
record(0, 5, 'terma', 5, 1, 2, 3, 3, 0,
|
||||
4, 1, 'b' , 3, 1, 5, 0
|
||||
) );
|
||||
} {
|
||||
X'00057465726D6105010203030004016203010500'
|
||||
}
|
||||
|
||||
do_execsql_test 1.3.1 {
|
||||
UPDATE t1_segdir SET root =
|
||||
record(0, 5, 'terma', 5, 1, 2, 3, 3, 0,
|
||||
4, 1, 'b' , 3, 1, 5,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0
|
||||
);
|
||||
}
|
||||
|
||||
do_catchsql_test 1.3.2 {
|
||||
SELECT snippet(t1) FROM t1 WHERE t1 MATCH 'term*'
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
do_execsql_test 1.4.1 {
|
||||
UPDATE t1_segdir SET root =
|
||||
record(0, 5, 'terma', 5, 1, 2, 3, 3, 0,
|
||||
4, 1, 'b' , 4, 1, 5,
|
||||
256, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0
|
||||
);
|
||||
}
|
||||
|
||||
do_catchsql_test 1.4.2 {
|
||||
SELECT snippet(t1) FROM t1 WHERE t1 MATCH 'term*'
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
do_execsql_test 1.4.3 {
|
||||
SELECT quote(root) FROM t1_segdir
|
||||
} {
|
||||
X'00057465726D610501020303000401620401058002010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100'
|
||||
}
|
||||
|
||||
do_execsql_test 1.5.1 {
|
||||
UPDATE t1_segdir SET root =
|
||||
record(0, 5, 'terma', 5, 1, 2, 3, 3, 0,
|
||||
4, 1, 'b' , 4, 1, 5,
|
||||
256, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0
|
||||
);
|
||||
}
|
||||
|
||||
do_catchsql_test 1.4.2 {
|
||||
SELECT snippet(t1) FROM t1 WHERE t1 MATCH 'term*'
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
do_execsql_test 1.4.3 {
|
||||
SELECT quote(root) FROM t1_segdir
|
||||
} {
|
||||
X'00057465726D610501020303000401620401058002010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100'
|
||||
}
|
||||
|
||||
|
||||
do_execsql_test 1.5.1 {
|
||||
UPDATE t1_segdir SET root =
|
||||
X'00057465726D61050102030300040162040105FF00010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100'
|
||||
}
|
||||
|
||||
do_catchsql_test 1.5.2 {
|
||||
SELECT snippet(t1) FROM t1 WHERE t1 MATCH 'term*'
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
do_catchsql_test 1.5.3 {
|
||||
INSERT INTO t1(t1) VALUES('integrity-check');
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
finish_test
|
||||
Binary file not shown.
@@ -750,4 +750,39 @@ do_execsql_test in-17.4 {
|
||||
SELECT 1 IN (CAST('1' AS text) COLLATE nocase);
|
||||
} 0
|
||||
|
||||
# 2019-08-27 ticket https://sqlite.org/src/info/dbaf8a6820be1ece
|
||||
#
|
||||
do_execsql_test in-18.1 {
|
||||
DROP TABLE IF EXISTS t0;
|
||||
CREATE TABLE t0(c0 INT UNIQUE);
|
||||
INSERT INTO t0(c0) VALUES (1);
|
||||
SELECT * FROM t0 WHERE '1' IN (t0.c0);
|
||||
} {}
|
||||
|
||||
# 2019-09-02 ticket https://www.sqlite.org/src/info/2841e99d104c6436
|
||||
# For the IN_INDEX_NOOP optimization, apply REAL affinity to the LHS
|
||||
# values prior to comparison if the RHS has REAL affinity.
|
||||
#
|
||||
# Also ticket https://sqlite.org/src/info/29f635e0af71234b
|
||||
#
|
||||
do_execsql_test in-19.1 {
|
||||
DROP TABLE IF EXISTS t0;
|
||||
CREATE TABLE t0(c0 REAL UNIQUE);
|
||||
INSERT INTO t0(c0) VALUES(2.07093491255203046E18);
|
||||
SELECT 1 FROM t0 WHERE c0 IN ('2070934912552030444');
|
||||
} {1}
|
||||
do_execsql_test in-19.2 {
|
||||
SELECT c0 IN ('2070934912552030444') FROM t0;
|
||||
} {1}
|
||||
do_execsql_test in-19.3 {
|
||||
SELECT c0 IN ('2070934912552030444',2,3) FROM t0;
|
||||
} {1}
|
||||
do_execsql_test in-19.4 {
|
||||
DROP TABLE t0;
|
||||
CREATE TABLE t0(c0 TEXT, c1 REAL, c2, PRIMARY KEY(c2, c0, c1));
|
||||
CREATE INDEX i0 ON t0(c1 IN (c0));
|
||||
INSERT INTO t0(c0, c2) VALUES (0, NULL) ON CONFLICT(c2, c1, c0) DO NOTHING;
|
||||
PRAGMA integrity_check;
|
||||
} {ok}
|
||||
|
||||
finish_test
|
||||
|
||||
+8
-5
@@ -226,10 +226,13 @@ do_execsql_test in4-3.42 {
|
||||
do_execsql_test in4-3.43 {
|
||||
SELECT * FROM t3 WHERE x IN (10);
|
||||
} {10 10 10}
|
||||
do_execsql_test in4-3.44 {
|
||||
EXPLAIN
|
||||
SELECT * FROM t3 WHERE x IN (10);
|
||||
} {~/OpenEphemeral/}
|
||||
|
||||
# This test would verify that the "X IN (Y)" -> "X==Y" optimization
|
||||
# was working. But we have now taken that optimization out.
|
||||
#do_execsql_test in4-3.44 {
|
||||
# EXPLAIN
|
||||
# SELECT * FROM t3 WHERE x IN (10);
|
||||
#} {~/OpenEphemeral/}
|
||||
do_execsql_test in4-3.45 {
|
||||
SELECT * FROM t3 WHERE x NOT IN (10,11,99999);
|
||||
} {1 1 1}
|
||||
@@ -326,7 +329,7 @@ do_execsql_test in4-6.1 {
|
||||
do_execsql_test in4-6.1-eqp {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t6a, t6b WHERE a=3 AND b IN (c);
|
||||
} {~/SCAN/}
|
||||
} {~/SCAN TABLE t6a/}
|
||||
do_execsql_test in4-6.2 {
|
||||
SELECT * FROM t6a, t6b WHERE a=3 AND c IN (b);
|
||||
} {3 4 4 44}
|
||||
|
||||
@@ -248,5 +248,22 @@ do_execsql_test 9.1 {
|
||||
SELECT * FROM t9 WHERE a IN (44, 45, 44, 45)
|
||||
} {44 45}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test that ticket c7a117190 is fixed.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 9.0 {
|
||||
CREATE TABLE t0(c0);
|
||||
CREATE VIEW v0(c0) AS SELECT LOWER(CAST('1e500' AS TEXT)) FROM t0;
|
||||
INSERT INTO t0(c0) VALUES (NULL);
|
||||
}
|
||||
|
||||
do_execsql_test 9.1 {
|
||||
SELECT lower('1e500') FROM t0 WHERE rowid NOT IN (0, 0, lower('1e500'));
|
||||
} {1e500}
|
||||
|
||||
do_execsql_test 9.2 {
|
||||
SELECT lower('1e500') FROM t0 WHERE rowid != lower('1e500');
|
||||
} {1e500}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -437,4 +437,48 @@ do_execsql_test index6-14.2 {
|
||||
SELECT * FROM t0 WHERE CASE c0 WHEN 0 THEN 0 ELSE 1 END;
|
||||
} {{} row}
|
||||
|
||||
# 2019-08-30
|
||||
# Ticket https://www.sqlite.org/src/info/a6408d42b9f44462
|
||||
# Ticket https://www.sqlite.org/src/info/fba33c8b1df6a915
|
||||
# https://sqlite.org/src/info/bac716244fddac1fe841
|
||||
#
|
||||
do_execsql_test index6-15.1 {
|
||||
DROP TABLE t0;
|
||||
CREATE TABLE t0(c0);
|
||||
INSERT INTO t0(c0) VALUES (NULL);
|
||||
CREATE INDEX i0 ON t0(1) WHERE c0 NOT NULL;
|
||||
SELECT 1 FROM t0 WHERE (t0.c0 IS FALSE) IS FALSE;
|
||||
} {1}
|
||||
do_execsql_test index6-15.2 {
|
||||
SELECT 1 FROM t0 WHERE (t0.c0 IS FALSE) BETWEEN FALSE AND TRUE;
|
||||
} {1}
|
||||
do_execsql_test index6-15.3 {
|
||||
SELECT 1 FROM t0 WHERE TRUE BETWEEN (t0.c0 IS FALSE) AND TRUE;
|
||||
} {1}
|
||||
do_execsql_test index6-15.4 {
|
||||
SELECT 1 FROM t0 WHERE FALSE BETWEEN FALSE AND (t0.c0 IS FALSE);
|
||||
} {1}
|
||||
do_execsql_test index6-15.5 {
|
||||
SELECT 1 FROM t0 WHERE (c0 IS FALSE) IN (FALSE);
|
||||
} {1}
|
||||
|
||||
# 2019-09-03
|
||||
# Ticket https://sqlite.org/src/info/767a8cbc6d20bd68
|
||||
do_execsql_test index6-16.1 {
|
||||
DROP TABLE t0;
|
||||
CREATE TABLE t0(c0 COLLATE NOCASE, c1);
|
||||
CREATE INDEX i0 ON t0(0) WHERE c0 >= c1;
|
||||
INSERT INTO t0 VALUES('a', 'B');
|
||||
SELECT c1 <= c0, c0 >= c1 FROM t0;
|
||||
} {1 0}
|
||||
do_execsql_test index6-16.2 {
|
||||
SELECT 2 FROM t0 WHERE c0 >= c1;
|
||||
} {}
|
||||
do_execsql_test index6-16.3 {
|
||||
SELECT 3 FROM t0 WHERE c1 <= c0;
|
||||
} {3}
|
||||
|
||||
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -457,4 +457,30 @@ do_execsql_test indexexpr-1700 {
|
||||
SELECT * FROM t0 WHERE ((NULL IS FALSE) IS FALSE);
|
||||
} {0}
|
||||
|
||||
# 2019-09-02 https://www.sqlite.org/src/tktview/57af00b6642ecd6848
|
||||
# When the expression of an an index-on-expression references a
|
||||
# table column of type REAL that is actually holding an MEM_IntReal
|
||||
# value, be sure to use the REAL value and not the INT value when
|
||||
# computing the expression.
|
||||
#
|
||||
ifcapable like_match_blobs {
|
||||
do_execsql_test indexexpr-1800 {
|
||||
DROP TABLE IF EXISTS t0;
|
||||
CREATE TABLE t0(c0 REAL, c1 TEXT);
|
||||
CREATE INDEX i0 ON t0(+c0, c0);
|
||||
INSERT INTO t0(c0) VALUES(0);
|
||||
SELECT CAST(+ t0.c0 AS BLOB) LIKE 0 FROM t0;
|
||||
} {0}
|
||||
do_execsql_test indexexpr-1810 {
|
||||
SELECT CAST(+ t0.c0 AS BLOB) LIKE '0.0' FROM t0;
|
||||
} {1}
|
||||
do_execsql_test indexexpr-1820 {
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1(x REAL);
|
||||
CREATE INDEX t1x ON t1(x, +x);
|
||||
INSERT INTO t1(x) VALUES(2);
|
||||
SELECT +x FROM t1 WHERE x=2;
|
||||
} {2.0}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -295,6 +295,82 @@ do_execsql_test 7.3 {
|
||||
REINDEX;
|
||||
} {}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 8.0 {
|
||||
CREATE TABLE t0(c0);
|
||||
CREATE INDEX i0 ON t0(c0) WHERE c0 NOT NULL;
|
||||
INSERT INTO t0(c0) VALUES (NULL);
|
||||
}
|
||||
|
||||
do_execsql_test 8.1.1 {
|
||||
SELECT * FROM t0 WHERE ~('' BETWEEN t0.c0 AND TRUE);
|
||||
} {{}}
|
||||
do_execsql_test 8.1.2 {
|
||||
SELECT ~('' BETWEEN t0.c0 AND TRUE) FROM t0;
|
||||
} {-1}
|
||||
|
||||
foreach {tn expr} {
|
||||
1 " 0 == (34 BETWEEN c0 AND 33)"
|
||||
2 " 1 != (34 BETWEEN c0 AND 33)"
|
||||
3 "-1 < (34 BETWEEN c0 AND 33)"
|
||||
4 "-1 <= (34 BETWEEN c0 AND 33)"
|
||||
5 " 1 > (34 BETWEEN c0 AND 33)"
|
||||
6 " 1 >= (34 BETWEEN c0 AND 33)"
|
||||
7 " 1 - (34 BETWEEN c0 AND 33)"
|
||||
8 "-1 + (34 BETWEEN c0 AND 33)"
|
||||
9 " 1 | (34 BETWEEN c0 AND 33)"
|
||||
10 " 1 << (34 BETWEEN c0 AND 33)"
|
||||
11 " 1 >> (34 BETWEEN c0 AND 33)"
|
||||
12 " 1 || (34 BETWEEN c0 AND 33)"
|
||||
} {
|
||||
do_execsql_test 8.3.$tn.1 "SELECT * FROM t0 WHERE $expr ORDER BY c0" { {} }
|
||||
do_execsql_test 8.3.$tn.2 "SELECT ($expr) IS TRUE FROM t0" { 1 }
|
||||
}
|
||||
|
||||
do_execsql_test 8.4 {
|
||||
CREATE TABLE t1(a, b);
|
||||
INSERT INTO t1 VALUES(1, 2), (3, 4);
|
||||
CREATE TABLE t2(x, y);
|
||||
}
|
||||
|
||||
foreach {tn expr} {
|
||||
1 " 0 == (a=0 AND y=1)"
|
||||
2 " 1 != (a=0 AND y=1)"
|
||||
3 "-1 < (a=0 AND y=1)"
|
||||
4 "-1 <= (a=0 AND y=1)"
|
||||
5 " 1 > (a=0 AND y=1)"
|
||||
6 " 1 >= (a=0 AND y=1)"
|
||||
7 " 1 - (a=0 AND y=1)"
|
||||
8 "-1 + (a=0 AND y=1)"
|
||||
9 " 1 | (a=0 AND y=1)"
|
||||
10 "1 << (a=0 AND y=1)"
|
||||
11 "1 >> (a=0 AND y=1)"
|
||||
12 "1 || (a=0 AND y=1)"
|
||||
|
||||
13 " 0 == (10 BETWEEN y AND b)"
|
||||
14 " 1 != (10 BETWEEN y AND b)"
|
||||
15 "-1 < (10 BETWEEN y AND b)"
|
||||
16 "-1 <= (10 BETWEEN y AND b)"
|
||||
17 " 1 > (10 BETWEEN y AND b)"
|
||||
18 " 1 >= (10 BETWEEN y AND b)"
|
||||
19 " 1 - (10 BETWEEN y AND b)"
|
||||
20 "-1 + (10 BETWEEN y AND b)"
|
||||
21 " 1 | (10 BETWEEN y AND b)"
|
||||
22 " 1 << (10 BETWEEN y AND b)"
|
||||
23 " 1 >> (10 BETWEEN y AND b)"
|
||||
24 " 1 || (10 BETWEEN y AND b)"
|
||||
|
||||
25 " 1 || (10 BETWEEN y AND b)"
|
||||
} {
|
||||
do_execsql_test 8.5.$tn.1 "
|
||||
SELECT * FROM t1 LEFT JOIN t2 WHERE $expr
|
||||
" {1 2 {} {} 3 4 {} {}}
|
||||
|
||||
do_execsql_test 8.5.$tn.2 "
|
||||
SELECT ($expr) IS TRUE FROM t1 LEFT JOIN t2
|
||||
" {1 1}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
@@ -257,4 +257,25 @@ do_execsql_test instr-1.64 {
|
||||
SELECT instr(a, b) FROM x1;
|
||||
} 0
|
||||
|
||||
# 2019-09-16 ticket https://www.sqlite.org/src/info/587791f92620090e
|
||||
#
|
||||
do_execsql_test instr-2.0 {
|
||||
DROP TABLE IF EXISTS t0;
|
||||
CREATE TABLE t0(c0 PRIMARY KEY, c1);
|
||||
INSERT INTO t0(c0) VALUES (x'bb'), (0);
|
||||
SELECT COUNT(*) FROM t0 WHERE INSTR(x'aabb', t0.c0) ORDER BY t0.c0, t0.c1;
|
||||
} {1}
|
||||
do_execsql_test instr-2.1 {
|
||||
SELECT quote(c0) FROM t0 WHERE INSTR(x'aabb', t0.c0) ORDER BY t0.c0, t0.c1;
|
||||
} {X'BB'}
|
||||
do_execsql_test instr-2.2 {
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1(x);
|
||||
INSERT INTO t1(x) VALUES('text'),(x'bb');
|
||||
SELECT quote(x) FROM t1 WHERE instr(x'aabb',x);
|
||||
} {X'BB'}
|
||||
do_execsql_test instr-2.3 {
|
||||
SELECT quote(x) FROM t1 WHERE x>'zzz' AND instr(x'aabb',x);
|
||||
} {X'BB'}
|
||||
|
||||
finish_test
|
||||
|
||||
+4
-4
@@ -47,12 +47,12 @@ do_test intarray-1.1 {
|
||||
}
|
||||
} {table ia1 table ia2 table ia3 table ia4}
|
||||
|
||||
# Verify the inability to DROP and recreate an intarray virtual table.
|
||||
# Verify the ability to DROP and recreate an intarray virtual table.
|
||||
do_test intarray-1.1b {
|
||||
db eval {DROP TABLE ia1}
|
||||
set rc [catch {sqlite3_intarray_create db ia1} msg]
|
||||
lappend rc $msg
|
||||
} {1 SQLITE_MISUSE}
|
||||
set rc [catch {sqlite3_intarray_create db ia1} ia1]
|
||||
lappend rc $ia1
|
||||
} {/0 [0-9A-Z]+/}
|
||||
|
||||
do_test intarray-1.2 {
|
||||
db eval {
|
||||
|
||||
+21
-1
@@ -812,11 +812,16 @@ do_execsql_test join-15.105 {
|
||||
FROM t1 LEFT JOIN t2
|
||||
WHERE a IN (1,3,x,y);
|
||||
} {1 2 {} {} x 3 4 {} {} x}
|
||||
do_execsql_test join-15.106 {
|
||||
do_execsql_test join-15.106a {
|
||||
SELECT *, 'x'
|
||||
FROM t1 LEFT JOIN t2
|
||||
WHERE NOT ( 'x'='y' AND t2.y=1 );
|
||||
} {1 2 {} {} x 3 4 {} {} x}
|
||||
do_execsql_test join-15.106b {
|
||||
SELECT *, 'x'
|
||||
FROM t1 LEFT JOIN t2
|
||||
WHERE ~ ( 'x'='y' AND t2.y=1 );
|
||||
} {1 2 {} {} x 3 4 {} {} x}
|
||||
do_execsql_test join-15.107 {
|
||||
SELECT *, 'x'
|
||||
FROM t1 LEFT JOIN t2
|
||||
@@ -864,4 +869,19 @@ do_execsql_test join-16.100 {
|
||||
WHERE (b IS NOT NULL)=0;
|
||||
} {1 {}}
|
||||
|
||||
# 2019-08-17 ticket https://sqlite.org/src/tktview/6710d2f7a13a299728ab
|
||||
# Ensure that constants that derive from the right-hand table of a LEFT JOIN
|
||||
# are never factored out, since they are not really constant.
|
||||
#
|
||||
do_execsql_test join-17.100 {
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1(x);
|
||||
INSERT INTO t1(x) VALUES(0),(1);
|
||||
SELECT * FROM t1 LEFT JOIN (SELECT abs(1) AS y FROM t1) ON x WHERE NOT(y='a');
|
||||
} {1 1 1 1}
|
||||
do_execsql_test join-17.110 {
|
||||
SELECT * FROM t1 LEFT JOIN (SELECT abs(1)+2 AS y FROM t1) ON x
|
||||
WHERE NOT(y='a');
|
||||
} {1 3 1 3}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -207,6 +207,19 @@ do_execsql_test like3-5.410 {
|
||||
SELECT * FROM t0 WHERE t0.c0 LIKE '.1%';
|
||||
} {.1%}
|
||||
|
||||
# 2019-09-03
|
||||
# Ticket https://www.sqlite.org/src/info/0f0428096f
|
||||
do_execsql_test like3-5.420 {
|
||||
DROP TABLE IF EXISTS t0;
|
||||
CREATE TABLE t0(c0 UNIQUE);
|
||||
INSERT INTO t0(c0) VALUES(-1);
|
||||
SELECT * FROM t0 WHERE t0.c0 GLOB '-*';
|
||||
} {-1}
|
||||
do_execsql_test like3-5.421 {
|
||||
SELECT t0.c0 GLOB '-*' FROM t0;
|
||||
} {1}
|
||||
|
||||
|
||||
|
||||
# 2019-02-27
|
||||
# Verify that the LIKE optimization works with an ESCAPE clause when
|
||||
|
||||
@@ -200,4 +200,37 @@ do_execsql_test 5.1 {
|
||||
SELECT MIN(a) FROM t1 WHERE a=123;
|
||||
} {123}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Tests for ticket f8a7060ece.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 6.1.0 {
|
||||
CREATE TABLE t1(a, b, c);
|
||||
INSERT INTO t1 VALUES(NULL, 1, 'x');
|
||||
CREATE INDEX i1 ON t1(a);
|
||||
}
|
||||
do_execsql_test 6.1.1 {
|
||||
SELECT min(a), b, c FROM t1 WHERE c='x';
|
||||
} {{} 1 x}
|
||||
do_execsql_test 6.1.2 {
|
||||
INSERT INTO t1 VALUES(1, 2, 'y');
|
||||
} {}
|
||||
do_execsql_test 6.1.3 {
|
||||
SELECT min(a), b, c FROM t1 WHERE c='x';
|
||||
} {{} 1 x}
|
||||
|
||||
do_execsql_test 6.2.0 {
|
||||
CREATE TABLE t0(c0 UNIQUE, c1);
|
||||
INSERT INTO t0(c1) VALUES (0);
|
||||
INSERT INTO t0(c0) VALUES (0);
|
||||
CREATE VIEW v0(c0, c1) AS
|
||||
SELECT t0.c1, t0.c0 FROM t0 WHERE CAST(t0.rowid AS INT) = 1;
|
||||
}
|
||||
do_execsql_test 6.2.1 {
|
||||
SELECT c0, c1 FROM v0;
|
||||
} {0 {}}
|
||||
do_execsql_test 6.2.2 {
|
||||
SELECT v0.c0, MIN(v0.c1) FROM v0;
|
||||
} {0 {}}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -0,0 +1,253 @@
|
||||
# 2019 August 10
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
# This file implements regression tests for SQLite library.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix nulls1
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
DROP TABLE IF EXISTS t3;
|
||||
CREATE TABLE t3(a INTEGER);
|
||||
INSERT INTO t3 VALUES(NULL), (10), (30), (20), (NULL);
|
||||
} {}
|
||||
|
||||
for {set a 0} {$a < 3} {incr a} {
|
||||
foreach {tn limit} {
|
||||
1 ""
|
||||
2 "LIMIT 10"
|
||||
} {
|
||||
do_execsql_test 1.$a.$tn.1 "
|
||||
SELECT a FROM t3 ORDER BY a nULLS FIRST $limit
|
||||
" {{} {} 10 20 30}
|
||||
|
||||
do_execsql_test 1.$a.$tn.2 "
|
||||
SELECT a FROM t3 ORDER BY a nULLS LAST $limit
|
||||
" {10 20 30 {} {}}
|
||||
|
||||
do_execsql_test 1.$a.$tn.3 "
|
||||
SELECT a FROM t3 ORDER BY a DESC nULLS FIRST $limit
|
||||
" {{} {} 30 20 10}
|
||||
|
||||
do_execsql_test 1.$a.$tn.4 "
|
||||
SELECT a FROM t3 ORDER BY a DESC nULLS LAST $limit
|
||||
" {30 20 10 {} {}}
|
||||
}
|
||||
|
||||
switch $a {
|
||||
0 {
|
||||
execsql { CREATE INDEX i1 ON t3(a) }
|
||||
}
|
||||
1 {
|
||||
execsql { DROP INDEX i1 ; CREATE INDEX i1 ON t3(a DESC) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 2.0 {
|
||||
CREATE TABLE t2(a, b, c);
|
||||
CREATE INDEX i2 ON t2(a, b);
|
||||
INSERT INTO t2 VALUES(1, 1, 1);
|
||||
INSERT INTO t2 VALUES(1, NULL, 2);
|
||||
INSERT INTO t2 VALUES(1, NULL, 3);
|
||||
INSERT INTO t2 VALUES(1, 4, 4);
|
||||
}
|
||||
|
||||
do_execsql_test 2.1 {
|
||||
SELECT * FROM t2 WHERE a=1 ORDER BY b NULLS LAST
|
||||
} {
|
||||
1 1 1 1 4 4 1 {} 2 1 {} 3
|
||||
}
|
||||
|
||||
do_execsql_test 2.2 {
|
||||
SELECT * FROM t2 WHERE a=1 ORDER BY b DESC NULLS FIRST
|
||||
} {
|
||||
1 {} 3
|
||||
1 {} 2
|
||||
1 4 4
|
||||
1 1 1
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 3.0 {
|
||||
CREATE TABLE t1(a, b, c, d, UNIQUE (b));
|
||||
}
|
||||
foreach {tn sql err} {
|
||||
1 { CREATE INDEX i1 ON t1(a ASC NULLS LAST) } LAST
|
||||
2 { CREATE INDEX i1 ON t1(a ASC NULLS FIRST) } FIRST
|
||||
3 { CREATE INDEX i1 ON t1(a, b ASC NULLS LAST) } LAST
|
||||
4 { CREATE INDEX i1 ON t1(a, b ASC NULLS FIRST) } FIRST
|
||||
5 { CREATE INDEX i1 ON t1(a DESC NULLS LAST) } LAST
|
||||
6 { CREATE INDEX i1 ON t1(a DESC NULLS FIRST) } FIRST
|
||||
7 { CREATE INDEX i1 ON t1(a, b DESC NULLS LAST) } LAST
|
||||
8 { CREATE INDEX i1 ON t1(a, b DESC NULLS FIRST) } FIRST
|
||||
9 { CREATE TABLE t2(a, b, PRIMARY KEY(a DESC, b NULLS FIRST)) } FIRST
|
||||
10 { CREATE TABLE t2(a, b, UNIQUE(a DESC NULLS FIRST, b)) } FIRST
|
||||
11 { INSERT INTO t1 VALUES(1, 2, 3, 4)
|
||||
ON CONFLICT (b DESC NULLS LAST) DO UPDATE SET a = a+1 } LAST
|
||||
12 {
|
||||
CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN
|
||||
INSERT INTO t1 VALUES(1, 2, 3, 4)
|
||||
ON CONFLICT (b DESC NULLS FIRST) DO UPDATE SET a = a+1;
|
||||
END
|
||||
} FIRST
|
||||
} {
|
||||
do_catchsql_test 3.1.$tn $sql "1 {unsupported use of NULLS $err}"
|
||||
}
|
||||
|
||||
do_execsql_test 3.2 {
|
||||
CREATE TABLE first(nulls, last);
|
||||
INSERT INTO first(last, nulls) VALUES(100,200), (300,400), (200,300);
|
||||
SELECT * FROM first ORDER BY nulls;
|
||||
} {
|
||||
200 100
|
||||
300 200
|
||||
400 300
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
ifcapable vtab {
|
||||
register_echo_module db
|
||||
do_execsql_test 4.0 {
|
||||
CREATE TABLE tx(a INTEGER PRIMARY KEY, b, c);
|
||||
CREATE INDEX i1 ON tx(b);
|
||||
INSERT INTO tx VALUES(1, 1, 1);
|
||||
INSERT INTO tx VALUES(2, NULL, 2);
|
||||
INSERT INTO tx VALUES(3, 3, 3);
|
||||
INSERT INTO tx VALUES(4, NULL, 4);
|
||||
INSERT INTO tx VALUES(5, 5, 5);
|
||||
CREATE VIRTUAL TABLE te USING echo(tx);
|
||||
}
|
||||
|
||||
do_execsql_test 4.1 {
|
||||
SELECT * FROM tx ORDER BY b NULLS FIRST;
|
||||
} {2 {} 2 4 {} 4 1 1 1 3 3 3 5 5 5}
|
||||
do_execsql_test 4.2 {
|
||||
SELECT * FROM te ORDER BY b NULLS FIRST;
|
||||
} {2 {} 2 4 {} 4 1 1 1 3 3 3 5 5 5}
|
||||
|
||||
do_execsql_test 4.3 {
|
||||
SELECT * FROM tx ORDER BY b NULLS LAST;
|
||||
} {1 1 1 3 3 3 5 5 5 2 {} 2 4 {} 4}
|
||||
do_execsql_test 4.4 {
|
||||
SELECT * FROM te ORDER BY b NULLS LAST;
|
||||
} {1 1 1 3 3 3 5 5 5 2 {} 2 4 {} 4}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
do_execsql_test 5.0 {
|
||||
CREATE TABLE t4(a, b, c);
|
||||
INSERT INTO t4 VALUES(1, 1, 11);
|
||||
INSERT INTO t4 VALUES(1, 2, 12);
|
||||
INSERT INTO t4 VALUES(1, NULL, 1);
|
||||
|
||||
INSERT INTO t4 VALUES(2, NULL, 1);
|
||||
INSERT INTO t4 VALUES(2, 2, 12);
|
||||
INSERT INTO t4 VALUES(2, 1, 11);
|
||||
|
||||
INSERT INTO t4 VALUES(3, NULL, 1);
|
||||
INSERT INTO t4 VALUES(3, 2, 12);
|
||||
INSERT INTO t4 VALUES(3, NULL, 3);
|
||||
}
|
||||
|
||||
do_execsql_test 5.1 {
|
||||
SELECT * FROM t4 WHERE a IN (1, 2, 3) ORDER BY a, b NULLS LAST
|
||||
} {
|
||||
1 1 11 1 2 12 1 {} 1
|
||||
2 1 11 2 2 12 2 {} 1
|
||||
3 2 12 3 {} 1 3 {} 3
|
||||
}
|
||||
do_execsql_test 5.2 {
|
||||
CREATE INDEX t4ab ON t4(a, b);
|
||||
SELECT * FROM t4 WHERE a IN (1, 2, 3) ORDER BY a, b NULLS LAST
|
||||
} {
|
||||
1 1 11 1 2 12 1 {} 1
|
||||
2 1 11 2 2 12 2 {} 1
|
||||
3 2 12 3 {} 1 3 {} 3
|
||||
}
|
||||
do_eqp_test 5.3 {
|
||||
SELECT * FROM t4 WHERE a IN (1, 2, 3) ORDER BY a, b NULLS LAST
|
||||
} {
|
||||
QUERY PLAN
|
||||
`--SEARCH TABLE t4 USING INDEX t4ab (a=?)
|
||||
}
|
||||
|
||||
do_execsql_test 5.4 {
|
||||
SELECT * FROM t4 WHERE a IN (1, 2, 3) ORDER BY a DESC, b DESC NULLS FIRST
|
||||
} {
|
||||
3 {} 3 3 {} 1 3 2 12
|
||||
2 {} 1 2 2 12 2 1 11
|
||||
1 {} 1 1 2 12 1 1 11
|
||||
}
|
||||
do_eqp_test 5.5 {
|
||||
SELECT * FROM t4 WHERE a IN (1, 2, 3) ORDER BY a DESC, b DESC NULLS FIRST
|
||||
} {
|
||||
QUERY PLAN
|
||||
`--SEARCH TABLE t4 USING INDEX t4ab (a=?)
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
do_execsql_test 6.0 {
|
||||
CREATE TABLE t5(a, b, c);
|
||||
WITH s(i) AS (
|
||||
VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<200
|
||||
)
|
||||
INSERT INTO t5 SELECT i%2, CASE WHEN (i%10)==0 THEN NULL ELSE i END, i FROM s;
|
||||
}
|
||||
|
||||
set res1 [db eval { SELECT a,b FROM t5 WHERE a=1 ORDER BY b NULLS LAST, c }]
|
||||
set res2 [db eval {
|
||||
SELECT a,b FROM t5 WHERE a=1 ORDER BY b DESC NULLS FIRST, c DESC
|
||||
}]
|
||||
|
||||
do_execsql_test 6.1.1 {
|
||||
CREATE INDEX t5ab ON t5(a, b, c);
|
||||
SELECT a,b FROM t5 WHERE a=1 ORDER BY b NULLS LAST, c;
|
||||
} $res1
|
||||
do_eqp_test 6.1.2 {
|
||||
SELECT a,b FROM t5 WHERE a=1 ORDER BY b NULLS LAST, c;
|
||||
} {
|
||||
QUERY PLAN
|
||||
`--SEARCH TABLE t5 USING COVERING INDEX t5ab (a=?)
|
||||
}
|
||||
do_execsql_test 6.2.1 {
|
||||
SELECT a,b FROM t5 WHERE a=1 ORDER BY b DESC NULLS FIRST, c DESC
|
||||
} $res2
|
||||
do_eqp_test 6.2.2 {
|
||||
SELECT a,b FROM t5 WHERE a=1 ORDER BY b DESC NULLS FIRST, c DESC
|
||||
} {
|
||||
QUERY PLAN
|
||||
`--SEARCH TABLE t5 USING COVERING INDEX t5ab (a=?)
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
do_execsql_test 7.0 {
|
||||
CREATE TABLE t71(a, b, c);
|
||||
CREATE INDEX t71abc ON t71(a, b, c);
|
||||
|
||||
SELECT * FROM t71 WHERE a=1 AND b=2 ORDER BY c NULLS LAST;
|
||||
SELECT * FROM t71 WHERE a=1 AND b=2 ORDER BY c DESC NULLS FIRST;
|
||||
|
||||
SELECT * FROM t71 ORDER BY a NULLS LAST;
|
||||
SELECT * FROM t71 ORDER BY a DESC NULLS FIRST;
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
# 2019-09-21
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
# This file implements regression tests for SQLite library.
|
||||
#
|
||||
# Specifically, it tests cases where the expressions in a GROUP BY
|
||||
# clause are the same as those in the ORDER BY clause.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set ::testprefix orderbyA
|
||||
|
||||
proc do_sortcount_test {tn sql cnt res} {
|
||||
set eqp [execsql "EXPLAIN QUERY PLAN $sql"]
|
||||
set rcnt [regexp -all {USE TEMP} $eqp]
|
||||
uplevel [list do_test $tn.1 [list set {} $rcnt] $cnt]
|
||||
uplevel [list do_execsql_test $tn.2 $sql $res]
|
||||
}
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(a, b, c);
|
||||
INSERT INTO t1 VALUES('one', 1, 11);
|
||||
INSERT INTO t1 VALUES('three', 7, 11);
|
||||
INSERT INTO t1 VALUES('one', 2, 11);
|
||||
INSERT INTO t1 VALUES('one', 3, 11);
|
||||
INSERT INTO t1 VALUES('two', 4, 11);
|
||||
INSERT INTO t1 VALUES('two', 6, 11);
|
||||
INSERT INTO t1 VALUES('three', 8, 11);
|
||||
INSERT INTO t1 VALUES('two', 5, 11);
|
||||
INSERT INTO t1 VALUES('three', 9, 11);
|
||||
}
|
||||
|
||||
foreach {tn idx} {
|
||||
1 {}
|
||||
2 {CREATE INDEX i1 ON t1(a)}
|
||||
3 {CREATE INDEX i1 ON t1(a DESC)}
|
||||
} {
|
||||
execsql { DROP INDEX IF EXISTS i1 }
|
||||
execsql $idx
|
||||
|
||||
# $match is the number of temp-table sorts we expect if the GROUP BY
|
||||
# can use the same sort order as the ORDER BY. $nomatch is the number
|
||||
# of expected sorts if the GROUP BY and ORDER BY are not compatible.
|
||||
set match 1
|
||||
set nomatch 2
|
||||
if {$tn>=2} {
|
||||
set match 0
|
||||
set nomatch 1
|
||||
}
|
||||
|
||||
do_sortcount_test 1.$tn.1.1 {
|
||||
SELECT a, sum(b) FROM t1 GROUP BY a ORDER BY a
|
||||
} $match {one 6 three 24 two 15}
|
||||
do_sortcount_test 1.$tn.1.2 {
|
||||
SELECT a, sum(b) FROM t1 GROUP BY a ORDER BY a DESC
|
||||
} $match {two 15 three 24 one 6}
|
||||
|
||||
do_sortcount_test 1.$tn.2.1 {
|
||||
SELECT a, sum(b) FROM t1 GROUP BY a ORDER BY a||''
|
||||
} $nomatch {one 6 three 24 two 15}
|
||||
do_sortcount_test 1.$tn.2.2 {
|
||||
SELECT a, sum(b) FROM t1 GROUP BY a ORDER BY a||'' DESC
|
||||
} $nomatch {two 15 three 24 one 6}
|
||||
|
||||
do_sortcount_test 1.$tn.3.1 {
|
||||
SELECT a, sum(b) FROM t1 GROUP BY a ORDER BY a NULLS LAST
|
||||
} $nomatch {one 6 three 24 two 15}
|
||||
do_sortcount_test 1.$tn.3.2 {
|
||||
SELECT a, sum(b) FROM t1 GROUP BY a ORDER BY a DESC NULLS FIRST
|
||||
} $nomatch {two 15 three 24 one 6}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
do_execsql_test 2.0 {
|
||||
CREATE TABLE t2(a, b, c);
|
||||
INSERT INTO t2 VALUES(1, 'one', 1);
|
||||
INSERT INTO t2 VALUES(1, 'two', 2);
|
||||
INSERT INTO t2 VALUES(1, 'one', 3);
|
||||
INSERT INTO t2 VALUES(1, 'two', 4);
|
||||
INSERT INTO t2 VALUES(1, 'one', 5);
|
||||
INSERT INTO t2 VALUES(1, 'two', 6);
|
||||
|
||||
INSERT INTO t2 VALUES(2, 'one', 7);
|
||||
INSERT INTO t2 VALUES(2, 'two', 8);
|
||||
INSERT INTO t2 VALUES(2, 'one', 9);
|
||||
INSERT INTO t2 VALUES(2, 'two', 10);
|
||||
INSERT INTO t2 VALUES(2, 'one', 11);
|
||||
INSERT INTO t2 VALUES(2, 'two', 12);
|
||||
|
||||
INSERT INTO t2 VALUES(NULL, 'one', 13);
|
||||
INSERT INTO t2 VALUES(NULL, 'two', 14);
|
||||
INSERT INTO t2 VALUES(NULL, 'one', 15);
|
||||
INSERT INTO t2 VALUES(NULL, 'two', 16);
|
||||
INSERT INTO t2 VALUES(NULL, 'one', 17);
|
||||
INSERT INTO t2 VALUES(NULL, 'two', 18);
|
||||
}
|
||||
|
||||
foreach {tn idx} {
|
||||
1 {}
|
||||
|
||||
2 { CREATE INDEX i2 ON t2(a, b) }
|
||||
3 { CREATE INDEX i2 ON t2(a DESC, b DESC) }
|
||||
|
||||
4 { CREATE INDEX i2 ON t2(a, b DESC) }
|
||||
5 { CREATE INDEX i2 ON t2(a DESC, b) }
|
||||
} {
|
||||
execsql { DROP INDEX IF EXISTS i2 }
|
||||
execsql $idx
|
||||
|
||||
|
||||
set nSort [expr ($tn==2 || $tn==3) ? 0 : 1]
|
||||
do_sortcount_test 2.$tn.1.1 {
|
||||
SELECT a, b, sum(c) FROM t2 GROUP BY a, b ORDER BY a, b;
|
||||
} $nSort {{} one 45 {} two 48 1 one 9 1 two 12 2 one 27 2 two 30}
|
||||
do_sortcount_test 2.$tn.1.2 {
|
||||
SELECT a, b, sum(c) FROM t2 GROUP BY a, b ORDER BY a DESC, b DESC;
|
||||
} $nSort {2 two 30 2 one 27 1 two 12 1 one 9 {} two 48 {} one 45}
|
||||
|
||||
set nSort [expr ($tn==4 || $tn==5) ? 0 : 1]
|
||||
do_sortcount_test 2.$tn.2.1 {
|
||||
SELECT a, b, sum(c) FROM t2 GROUP BY a, b ORDER BY a, b DESC;
|
||||
} $nSort { {} two 48 {} one 45 1 two 12 1 one 9 2 two 30 2 one 27 }
|
||||
do_sortcount_test 2.$tn.2.2 {
|
||||
SELECT a, b, sum(c) FROM t2 GROUP BY a, b ORDER BY a DESC, b;
|
||||
} $nSort { 2 one 27 2 two 30 1 one 9 1 two 12 {} one 45 {} two 48 }
|
||||
|
||||
# ORDER BY can never piggyback on the GROUP BY sort if it uses
|
||||
# non-standard NULLS behaviour.
|
||||
set nSort [expr $tn==1 ? 2 : 1]
|
||||
do_sortcount_test 2.$tn.3.1 {
|
||||
SELECT a, b, sum(c) FROM t2 GROUP BY a, b ORDER BY a, b DESC NULLS FIRST;
|
||||
} $nSort { {} two 48 {} one 45 1 two 12 1 one 9 2 two 30 2 one 27 }
|
||||
do_sortcount_test 2.$tn.3.2 {
|
||||
SELECT a, b, sum(c) FROM t2 GROUP BY a, b ORDER BY a DESC, b NULLS LAST;
|
||||
} $nSort { 2 one 27 2 two 30 1 one 9 1 two 12 {} one 45 {} two 48 }
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
@@ -126,6 +126,7 @@ set allquicktests [test_set $alltests -exclude {
|
||||
walcrash2.test e_fkey.test backup.test
|
||||
|
||||
fts4merge.test fts4merge2.test fts4merge4.test fts4check.test
|
||||
fts4merge5.test
|
||||
fts3cov.test fts3snippet.test fts3corrupt2.test fts3an.test
|
||||
fts3defer.test fts4langid.test fts3sort.test fts5unicode.test
|
||||
|
||||
@@ -455,8 +456,8 @@ test_suite "coverage-analyze" -description {
|
||||
Coverage tests for file analyze.c.
|
||||
} -files {
|
||||
analyze3.test analyze4.test analyze5.test analyze6.test
|
||||
analyze7.test analyze8.test analyze9.test analyzeA.test
|
||||
analyze.test analyzeB.test mallocA.test
|
||||
analyze7.test analyze8.test analyze9.test
|
||||
analyze.test mallocA.test
|
||||
}
|
||||
|
||||
test_suite "coverage-sorter" -description {
|
||||
@@ -624,7 +625,7 @@ test_suite "utf16" -description {
|
||||
} -files {
|
||||
alter.test alter3.test
|
||||
analyze.test analyze3.test analyze4.test analyze5.test analyze6.test
|
||||
analyze7.test analyze8.test analyze9.test analyzeA.test analyzeB.test
|
||||
analyze7.test analyze8.test analyze9.test
|
||||
auth.test bind.test blob.test capi2.test capi3.test collate1.test
|
||||
collate2.test collate3.test collate4.test collate5.test collate6.test
|
||||
conflict.test date.test delete.test expr.test fkey1.test func.test
|
||||
|
||||
+2
-2
@@ -70,8 +70,8 @@ proc execsql {sql} {
|
||||
proc execsql_test {tn sql} {
|
||||
set res [execsql $sql]
|
||||
set sql [string map {string_agg group_concat} $sql]
|
||||
set sql [string map [list {NULLS FIRST} {}] $sql]
|
||||
set sql [string map [list {NULLS LAST} {}] $sql]
|
||||
# set sql [string map [list {NULLS FIRST} {}] $sql]
|
||||
# set sql [string map [list {NULLS LAST} {}] $sql]
|
||||
puts $::fd "do_execsql_test $tn {"
|
||||
puts $::fd " [string trim $sql]"
|
||||
puts $::fd "} {$res}"
|
||||
|
||||
+11
-5
@@ -1859,10 +1859,11 @@ do_test 23.1 {
|
||||
CREATE INDEX i1 ON t1(b,c);
|
||||
CREATE INDEX i2 ON t1(c,d);
|
||||
CREATE INDEX i2x ON t1(d COLLATE nocase, c DESC);
|
||||
CREATE INDEX i3 ON t1(d,b+c,c);
|
||||
CREATE TABLE t2(x INTEGER REFERENCES t1);
|
||||
}
|
||||
db2 eval {SELECT name FROM sqlite_master}
|
||||
} {t1 i1 i2 i2x t2}
|
||||
} {t1 i1 i2 i2x i3 t2}
|
||||
do_test 23.2a {
|
||||
db eval {
|
||||
DROP INDEX i2;
|
||||
@@ -1889,13 +1890,14 @@ do_test 23.2b {
|
||||
# means left-most. Key columns come before auxiliary columns.)
|
||||
#
|
||||
# (The second column of output from PRAGMA index_xinfo is...)
|
||||
# EVIDENCE-OF: R-40889-06838 The rank of the column within the table
|
||||
# EVIDENCE-OF: R-06603-49335 The rank of the column within the table
|
||||
# being indexed, or -1 if the index-column is the rowid of the table
|
||||
# being indexed.
|
||||
# being indexed and -2 if the index is on an expression.
|
||||
#
|
||||
# (The third column of output from PRAGMA index_xinfo is...)
|
||||
# EVIDENCE-OF: R-22751-28901 The name of the column being indexed, or
|
||||
# NULL if the index-column is the rowid of the table being indexed.
|
||||
# EVIDENCE-OF: R-40641-22898 The name of the column being indexed, or
|
||||
# NULL if the index-column is the rowid of the table being indexed or an
|
||||
# expression.
|
||||
#
|
||||
# (The fourth column of output from PRAGMA index_xinfo is...)
|
||||
# EVIDENCE-OF: R-11847-09179 1 if the index-column is sorted in reverse
|
||||
@@ -1915,6 +1917,9 @@ do_test 23.2c {
|
||||
do_test 23.2d {
|
||||
db2 eval {PRAGMA index_xinfo(i2x)}
|
||||
} {0 3 d 0 nocase 1 1 2 c 1 BINARY 1 2 -1 {} 0 BINARY 0}
|
||||
do_test 23.2e {
|
||||
db2 eval {PRAGMA index_xinfo(i3)}
|
||||
} {0 3 d 0 BINARY 1 1 -2 {} 0 BINARY 1 2 2 c 0 BINARY 1 3 -1 {} 0 BINARY 0}
|
||||
|
||||
# EVIDENCE-OF: R-64103-17776 PRAGMA schema.index_list(table-name); This
|
||||
# pragma returns one row for each index associated with the given table.
|
||||
@@ -1936,6 +1941,7 @@ do_test 23.2d {
|
||||
#
|
||||
do_test 23.3 {
|
||||
db eval {
|
||||
DROP INDEX IF EXISTS i3;
|
||||
CREATE INDEX i3 ON t1(d,b,c);
|
||||
}
|
||||
capture_pragma db2 out {PRAGMA index_list(t1)}
|
||||
|
||||
+2
-2
@@ -11,9 +11,9 @@
|
||||
# This file implements regression tests for SQLite library.
|
||||
#
|
||||
# This file implements tests for the PRAGMA command. Specifically,
|
||||
# those pragmas enabled at build time by setting:
|
||||
# those pragmas that are not disabled at build time by setting:
|
||||
#
|
||||
# -DSQLITE_INTROSPECTION_PRAGMAS
|
||||
# -DSQLITE_OMIT_INTROSPECTION_PRAGMAS
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
|
||||
@@ -412,6 +412,8 @@ proc count_tests_and_errors {logfile rcVar errmsgVar} {
|
||||
# skip over "value is outside range" errors
|
||||
if {[regexp {value .* is outside the range of representable} $line]} {
|
||||
# noop
|
||||
} elseif {[regexp {overflow: .* cannot be represented} $line]} {
|
||||
# noop
|
||||
} else {
|
||||
incr ::NERRCASE
|
||||
if {$rc==0} {
|
||||
|
||||
@@ -578,10 +578,14 @@ proc main_tests {args} {
|
||||
puts "$config \"$target\""
|
||||
if {$bNodebug==0 && $bNosynthetic==0} {
|
||||
set iHas [string first SQLITE_DEBUG $::Configs($config)]
|
||||
set dtarget test
|
||||
if {$target=="tcltest"} {
|
||||
set dtarget tcltest
|
||||
}
|
||||
if {$iHas>=0} {
|
||||
puts "$config-ndebug \"test\""
|
||||
puts "$config-ndebug \"$dtarget\""
|
||||
} else {
|
||||
puts "$config-debug \"test\""
|
||||
puts "$config-debug \"$dtarget\""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,4 +55,14 @@ do_catchsql_test 2.2 {
|
||||
UPDATE t1 SET (b,c,d) = (SELECT x,y FROM t2 WHERE w=a);
|
||||
} {1 {3 columns assigned 2 values}}
|
||||
|
||||
# 2019-08-26
|
||||
# ticket https://www.sqlite.org/src/info/78acc9d40f0786e8
|
||||
#
|
||||
do_catchsql_test 3.0 {
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1(a,b);
|
||||
INSERT INTO t1 VALUES(1,2);
|
||||
UPDATE t1 SET (a,a,a,b)=(SELECT 99,100);
|
||||
} {1 {4 columns assigned 2 values}}
|
||||
|
||||
finish_test
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@ do_test tcl-1.1.1 {
|
||||
do_test tcl-1.2 {
|
||||
set v [catch {db bogus} msg]
|
||||
lappend v $msg
|
||||
} {1 {bad option "bogus": must be authorizer, backup, bind_fallback, busy, cache, changes, close, collate, collation_needed, commit_hook, complete, copy, deserialize, enable_load_extension, errorcode, eval, exists, function, incrblob, interrupt, last_insert_rowid, nullvalue, onecolumn, preupdate, profile, progress, rekey, restore, rollback_hook, serialize, status, timeout, total_changes, trace, trace_v2, transaction, unlock_notify, update_hook, version, or wal_hook}}
|
||||
} {1 {bad option "bogus": must be authorizer, backup, bind_fallback, busy, cache, changes, close, collate, collation_needed, commit_hook, complete, config, copy, deserialize, enable_load_extension, errorcode, eval, exists, function, incrblob, interrupt, last_insert_rowid, nullvalue, onecolumn, preupdate, profile, progress, rekey, restore, rollback_hook, serialize, status, timeout, total_changes, trace, trace_v2, transaction, unlock_notify, update_hook, version, or wal_hook}}
|
||||
do_test tcl-1.2.1 {
|
||||
set v [catch {db cache bogus} msg]
|
||||
lappend v $msg
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user