Merge recent enhancements and bug fixes from trunk.

FossilOrigin-Name: 78bc42e664e9fa9ee21ad9762c369f291fcdf5db
This commit is contained in:
drh 2015-11-07 01:33:30 +00:00
commit 98a0e0083f
36 changed files with 856 additions and 287 deletions

View File

@ -1078,7 +1078,7 @@ fastfuzztest: fuzzcheck$(TEXE) $(FUZZDATA)
./fuzzcheck$(TEXE) --limit-mem 100M $(FUZZDATA)
valgrindfuzz: fuzzcheck$(TEXT) $(FUZZDATA)
valgrind ./fuzzcheck$(TEXE) --cell-size-check --limit-mem 10M $(FUZZDATA)
valgrind ./fuzzcheck$(TEXE) --cell-size-check --limit-mem 10M --timeout 600 $(FUZZDATA)
# Minimal testing that runs in less than 3 minutes
#

View File

@ -160,6 +160,7 @@ struct Fts5Config {
int pgsz; /* Approximate page size used in %_data */
int nAutomerge; /* 'automerge' setting */
int nCrisisMerge; /* Maximum allowed segments per level */
int nHashSize; /* Bytes of memory for in-memory hash */
char *zRank; /* Name of rank function */
char *zRankArgs; /* Arguments to rank function */

View File

@ -20,6 +20,7 @@
#define FTS5_DEFAULT_PAGE_SIZE 4050
#define FTS5_DEFAULT_AUTOMERGE 4
#define FTS5_DEFAULT_CRISISMERGE 16
#define FTS5_DEFAULT_HASHSIZE (1024*1024)
/* Maximum allowed page size */
#define FTS5_MAX_PAGE_SIZE (128*1024)
@ -706,33 +707,37 @@ int sqlite3Fts5ConfigParseRank(
*pzRank = 0;
*pzRankArgs = 0;
p = fts5ConfigSkipWhitespace(p);
pRank = p;
p = fts5ConfigSkipBareword(p);
if( p ){
zRank = sqlite3Fts5MallocZero(&rc, 1 + p - pRank);
if( zRank ) memcpy(zRank, pRank, p-pRank);
}else{
if( p==0 ){
rc = SQLITE_ERROR;
}
}else{
p = fts5ConfigSkipWhitespace(p);
pRank = p;
p = fts5ConfigSkipBareword(p);
if( rc==SQLITE_OK ){
p = fts5ConfigSkipWhitespace(p);
if( *p!='(' ) rc = SQLITE_ERROR;
p++;
}
if( rc==SQLITE_OK ){
const char *pArgs;
p = fts5ConfigSkipWhitespace(p);
pArgs = p;
if( *p!=')' ){
p = fts5ConfigSkipArgs(p);
if( p==0 ){
rc = SQLITE_ERROR;
}else{
zRankArgs = sqlite3Fts5MallocZero(&rc, 1 + p - pArgs);
if( zRankArgs ) memcpy(zRankArgs, pArgs, p-pArgs);
if( p ){
zRank = sqlite3Fts5MallocZero(&rc, 1 + p - pRank);
if( zRank ) memcpy(zRank, pRank, p-pRank);
}else{
rc = SQLITE_ERROR;
}
if( rc==SQLITE_OK ){
p = fts5ConfigSkipWhitespace(p);
if( *p!='(' ) rc = SQLITE_ERROR;
p++;
}
if( rc==SQLITE_OK ){
const char *pArgs;
p = fts5ConfigSkipWhitespace(p);
pArgs = p;
if( *p!=')' ){
p = fts5ConfigSkipArgs(p);
if( p==0 ){
rc = SQLITE_ERROR;
}else{
zRankArgs = sqlite3Fts5MallocZero(&rc, 1 + p - pArgs);
if( zRankArgs ) memcpy(zRankArgs, pArgs, p-pArgs);
}
}
}
}
@ -767,6 +772,18 @@ int sqlite3Fts5ConfigSetValue(
}
}
else if( 0==sqlite3_stricmp(zKey, "hashsize") ){
int nHashSize = -1;
if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
nHashSize = sqlite3_value_int(pVal);
}
if( nHashSize<=0 ){
*pbBadkey = 1;
}else{
pConfig->nHashSize = nHashSize;
}
}
else if( 0==sqlite3_stricmp(zKey, "automerge") ){
int nAutomerge = -1;
if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
@ -827,6 +844,7 @@ int sqlite3Fts5ConfigLoad(Fts5Config *pConfig, int iCookie){
pConfig->pgsz = FTS5_DEFAULT_PAGE_SIZE;
pConfig->nAutomerge = FTS5_DEFAULT_AUTOMERGE;
pConfig->nCrisisMerge = FTS5_DEFAULT_CRISISMERGE;
pConfig->nHashSize = FTS5_DEFAULT_HASHSIZE;
zSql = sqlite3Fts5Mprintf(&rc, zSelect, pConfig->zDb, pConfig->zName);
if( zSql ){

View File

@ -288,7 +288,6 @@ struct Fts5Index {
** in-memory hash tables before they are flushed to disk.
*/
Fts5Hash *pHash; /* Hash table for in-memory data */
int nMaxPendingData; /* Max pending data before flush to disk */
int nPendingData; /* Current bytes of pending data */
i64 iWriteRowid; /* Rowid for current doc being written */
int bDelete; /* Current write is a delete */
@ -4453,7 +4452,7 @@ int sqlite3Fts5IndexBeginWrite(Fts5Index *p, int bDelete, i64 iRowid){
/* Flush the hash table to disk if required */
if( iRowid<p->iWriteRowid
|| (iRowid==p->iWriteRowid && p->bDelete==0)
|| (p->nPendingData > p->nMaxPendingData)
|| (p->nPendingData > p->pConfig->nHashSize)
){
fts5IndexFlush(p);
}
@ -4519,7 +4518,6 @@ int sqlite3Fts5IndexOpen(
if( rc==SQLITE_OK ){
p->pConfig = pConfig;
p->nWorkUnit = FTS5_WORK_UNIT;
p->nMaxPendingData = 1024*1024;
p->zDataTbl = sqlite3Fts5Mprintf(&rc, "%s_data", pConfig->zName);
if( p->zDataTbl && bCreate ){
rc = sqlite3Fts5CreateTable(

View File

@ -395,6 +395,15 @@ static int fts5InitVtab(
rc = sqlite3Fts5ConfigDeclareVtab(pConfig);
}
/* Load the initial configuration */
if( rc==SQLITE_OK ){
assert( pConfig->pzErrmsg==0 );
pConfig->pzErrmsg = pzErr;
rc = sqlite3Fts5IndexLoadConfig(pTab->pIndex);
sqlite3Fts5IndexRollback(pTab->pIndex);
pConfig->pzErrmsg = 0;
}
if( rc!=SQLITE_OK ){
fts5FreeVtab(pTab);
pTab = 0;
@ -829,13 +838,42 @@ static int fts5NextMethod(sqlite3_vtab_cursor *pCursor){
return rc;
}
static sqlite3_stmt *fts5PrepareStatement(
int *pRc,
Fts5Config *pConfig,
const char *zFmt,
...
){
sqlite3_stmt *pRet = 0;
va_list ap;
va_start(ap, zFmt);
if( *pRc==SQLITE_OK ){
int rc;
char *zSql = sqlite3_vmprintf(zFmt, ap);
if( zSql==0 ){
rc = SQLITE_NOMEM;
}else{
rc = sqlite3_prepare_v2(pConfig->db, zSql, -1, &pRet, 0);
if( rc!=SQLITE_OK ){
*pConfig->pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(pConfig->db));
}
sqlite3_free(zSql);
}
*pRc = rc;
}
va_end(ap);
return pRet;
}
static int fts5CursorFirstSorted(Fts5Table *pTab, Fts5Cursor *pCsr, int bDesc){
Fts5Config *pConfig = pTab->pConfig;
Fts5Sorter *pSorter;
int nPhrase;
int nByte;
int rc = SQLITE_OK;
char *zSql;
const char *zRank = pCsr->zRank;
const char *zRankArgs = pCsr->zRankArgs;
@ -853,17 +891,13 @@ static int fts5CursorFirstSorted(Fts5Table *pTab, Fts5Cursor *pCsr, int bDesc){
** table, saving it creates a circular reference.
**
** If SQLite a built-in statement cache, this wouldn't be a problem. */
zSql = sqlite3Fts5Mprintf(&rc,
pSorter->pStmt = fts5PrepareStatement(&rc, pConfig,
"SELECT rowid, rank FROM %Q.%Q ORDER BY %s(%s%s%s) %s",
pConfig->zDb, pConfig->zName, zRank, pConfig->zName,
(zRankArgs ? ", " : ""),
(zRankArgs ? zRankArgs : ""),
bDesc ? "DESC" : "ASC"
);
if( zSql ){
rc = sqlite3_prepare_v2(pConfig->db, zSql, -1, &pSorter->pStmt, 0);
sqlite3_free(zSql);
}
pCsr->pSorter = pSorter;
if( rc==SQLITE_OK ){

View File

@ -52,7 +52,7 @@ do_faultsim_test 2 -prep {
INSERT INTO t1 VALUES('a b c', 'a bc def ghij klmno');
}
} -test {
faultsim_test_result {0 {}}
faultsim_test_result {0 {}} {1 {vtable constructor failed: t1}}
}
reset_db
@ -66,7 +66,7 @@ do_faultsim_test 3 -prep {
} -body {
execsql { DELETE FROM t1 }
} -test {
faultsim_test_result {0 {}}
faultsim_test_result {0 {}} {1 {vtable constructor failed: t1}}
}
reset_db
@ -101,7 +101,7 @@ foreach {tn expr res} {
} -body "
execsql { SELECT rowid FROM t2 WHERE t2 MATCH '$expr' }
" -test "
faultsim_test_result {[list 0 $res]}
faultsim_test_result {[list 0 $res]} {1 {vtable constructor failed: t2}}
"
}

View File

@ -107,7 +107,7 @@ set ::res [db eval {SELECT rowid, x1 FROM x1 WHERE x1 MATCH '*reads'}]
do_faultsim_test 4 -faults oom-* -body {
db eval {SELECT rowid, x, x1 FROM x1 WHERE x1 MATCH '*reads'}
} -test {
faultsim_test_result {0 {0 {} 3}}
faultsim_test_result {0 {0 {} 4}}
}
#-------------------------------------------------------------------------

View File

@ -41,5 +41,60 @@ do_execsql_test 1.3 {
WHERE xyz MATCH 'x AND y' ORDER BY rank
} [list [string map {x [x] y [y]} $doc]]
#-------------------------------------------------------------------------
# Check that the 'rank' option really is persistent.
#
do_execsql_test 2.0 {
CREATE VIRTUAL TABLE tt USING fts5(a);
INSERT INTO tt VALUES('a x x x x');
INSERT INTO tt VALUES('x x a a a');
INSERT INTO tt VALUES('x a a x x');
}
proc firstinst {cmd} {
foreach {p c o} [$cmd xInst 0] {}
return $o
}
sqlite3_fts5_create_function db firstinst firstinst
do_execsql_test 2.1 {
SELECT rowid FROM tt('a') ORDER BY rank;
} {2 3 1}
do_execsql_test 2.2 {
SELECT rowid FROM tt('a', 'firstinst()') ORDER BY rank;
} {1 3 2}
do_execsql_test 2.3 {
INSERT INTO tt(tt, rank) VALUES('rank', 'firstinst()');
SELECT rowid FROM tt('a') ORDER BY rank;
} {1 3 2}
do_test 2.4 {
sqlite3 db2 test.db
catchsql { SELECT rowid FROM tt('a') ORDER BY rank; } db2
} {1 {no such function: firstinst}}
do_test 2.5 {
db2 close
sqlite3 db2 test.db
sqlite3_fts5_create_function db2 firstinst firstinst
execsql { SELECT rowid FROM tt('a') ORDER BY rank; } db2
} {1 3 2}
do_test 2.6 {
execsql { SELECT rowid FROM tt('a') ORDER BY rank; } db2
} {1 3 2}
do_test 2.7 {
execsql { SELECT rowid FROM tt('a') ORDER BY rank; } db
} {1 3 2}
finish_test

View File

@ -18,7 +18,7 @@ ifcapable !fts5 {
finish_test
return
}
#-------------------------------------------------------------------------
#
set doc "x x [string repeat {y } 50]z z"
@ -322,5 +322,34 @@ do_execsql_test 13.3 {
INSERT INTO xy(xy) VALUES('integrity-check');
}
#-------------------------------------------------------------------------
#
do_execsql_test 14.1 {
CREATE VIRTUAL TABLE ttt USING fts5(x);
BEGIN;
INSERT INTO ttt(rowid, x) VALUES(1, 'a b c');
INSERT INTO ttt(rowid, x) VALUES(2, 'a b c');
INSERT INTO ttt(rowid, x) VALUES(3, 'a b c');
COMMIT;
}
do_test 14.2 {
fts5_level_segs ttt
} {1}
#-------------------------------------------------------------------------
db func rnddoc fts5_rnddoc
do_execsql_test 4.0 {
CREATE VIRTUAL TABLE x1 USING fts5(x);
INSERT INTO x1(x1, rank) VALUES('pgsz', 32);
WITH ii(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM ii WHERE i<10 )
INSERT INTO x1 SELECT rnddoc(5) FROM ii;
}
do_execsql_test 4.1 {
SELECT rowid, x, x1 FROM x1 WHERE x1 MATCH '*reads'
} {0 {} 4}
finish_test

View File

@ -48,6 +48,7 @@ proc usage {} {
puts stderr " -crisismerge N (set the crisismerge parameter to N)"
puts stderr " -prefix PREFIX (comma separated prefix= argument)"
puts stderr " -trans N (commit after N inserts - 0 == never)"
puts stderr " -hashsize N (set the fts5 hashsize parameter to N)"
exit 1
}
@ -59,6 +60,7 @@ set O(automerge) -1
set O(crisismerge) -1
set O(prefix) ""
set O(trans) 0
set O(hashsize) -1
if {[llength $argv]<2} usage
set nOpt [expr {[llength $argv]-2}]
@ -106,6 +108,11 @@ for {set i 0} {$i < $nOpt} {incr i} {
set O(prefix) [lindex $argv $i]
}
-hashsize {
if { [incr i]>=$nOpt } usage
set O(hashsize) [lindex $argv $i]
}
default {
usage
}
@ -126,6 +133,14 @@ db eval BEGIN
db eval "CREATE VIRTUAL TABLE t1 USING $O(vtab) (path, content$O(tok)$pref)"
db eval "INSERT INTO t1(t1, rank) VALUES('pgsz', 4050);"
}
if {$O(hashsize)>=0} {
catch {
db eval "INSERT INTO t1(t1, rank) VALUES('hashsize', $O(hashsize));"
}
}
if {$O(automerge)>=0} {
if {$O(vtab) == "fts5"} {
db eval { INSERT INTO t1(t1, rank) VALUES('automerge', $O(automerge)) }
@ -141,6 +156,7 @@ db eval BEGIN
}
load_hierachy [lindex $argv end]
db eval COMMIT
puts ""

View File

@ -94,16 +94,16 @@ static void ieee754func(
m >>= 1;
e++;
}
while( ((m>>32)&0xfff00000)==0 ){
while( m!=0 && ((m>>32)&0xfff00000)==0 ){
m <<= 1;
e--;
}
e += 1075;
if( e<0 ) e = m = 0;
if( e>0x7ff ) m = 0;
if( e>0x7ff ) e = 0x7ff;
a = m & ((((sqlite3_int64)1)<<52)-1);
a |= e<<52;
if( isNeg ) a |= ((sqlite3_int64)1)<<63;
if( isNeg ) a |= ((sqlite3_uint64)1)<<63;
memcpy(&r, &a, sizeof(r));
sqlite3_result_double(context, r);
}

View File

@ -768,7 +768,7 @@ fastfuzztest: fuzzcheck$(EXE) $(FUZZDATA)
./fuzzcheck$(EXE) --limit-mem 100M $(FUZZDATA)
valgrindfuzz: fuzzcheck$(EXE) $(FUZZDATA)
valgrind ./fuzzcheck$(EXE) --cell-size-check --limit-mem 10M $(FUZZDATA)
valgrind ./fuzzcheck$(EXE) --cell-size-check --limit-mem 10M --timeout 600 $(FUZZDATA)
# A very quick test using only testfixture and omitting all the slower
# tests. Designed to run in under 3 minutes on a workstation.

View File

@ -1,6 +1,6 @@
C Merge\sall\srecent\senhancements\sand\sfixes\sfrom\strunk.
D 2015-11-02T18:57:26.691
F Makefile.in 3229179cfbc7d1378aba248dcbdf5213fff6214a
C Merge\srecent\senhancements\sand\sbug\sfixes\sfrom\strunk.
D 2015-11-07T01:33:30.741
F Makefile.in 7037017983949da7c736ca3de2c3d29611b77d1c
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 2ed14817d36a6c26cb146e53b9c8a7318ba5bdd4
F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7
@ -103,14 +103,14 @@ F ext/fts3/unicode/mkunicode.tcl 95cf7ec186e48d4985e433ff8a1c89090a774252
F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95
F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0
F ext/fts5/fts5.h 8b9a13b309b180e9fb88ea5666c0d8d73c6102d9
F ext/fts5/fts5Int.h 06594fd3e5a3c74da6df9141e165975dc0ea6ef4
F ext/fts5/fts5Int.h acf968e43d57b6b1caf7554d34ec35d6ed3b4fe8
F ext/fts5/fts5_aux.c 1f384972d606375b8fa078319f25ab4b5feb1b35
F ext/fts5/fts5_buffer.c 1e49512a535045e621246dc7f4f65f3593fa0fc2
F ext/fts5/fts5_config.c 88a77f5d5e4dfbb2355b8f6cc9969b7f02d94685
F ext/fts5/fts5_config.c 6fc92c0b1bda5244c28a54c9ba740736bd5513d9
F ext/fts5/fts5_expr.c 28b15c9ae296204bc0a2e5cf7a667d840a9d2900
F ext/fts5/fts5_hash.c a9d4c1efebc2a91d26ad7ebdfcbf2678ceac405f
F ext/fts5/fts5_index.c 356481ce027cc2ede8e462c316b578260cda29d2
F ext/fts5/fts5_main.c 39358d3d8f0d6ea3757c40e0ddcbb6bc435604c3
F ext/fts5/fts5_index.c b622a0a70f57a96469e6828da2dd70e0872aeb37
F ext/fts5/fts5_main.c 7581280ee242785477df67402f2853c66f77d45b
F ext/fts5/fts5_storage.c 9ea3d92178743758b6c54d9fe8836bbbdcc92e3b
F ext/fts5/fts5_tcl.c 3bf445e66de32137d4693694ff7b1fd6074e32bd
F ext/fts5/fts5_test_mi.c e96be827aa8f571031e65e481251dc1981d608bf
@ -149,10 +149,10 @@ F ext/fts5/test/fts5dlidx.test ecba5e62ea8b26c33829961602069c546228046d
F ext/fts5/test/fts5doclist.test 8edb5b57e5f144030ed74ec00ef6fa4294fed79b
F ext/fts5/test/fts5ea.test b01e3a18cdfabbff8104a96a5242a06a68a998a0
F ext/fts5/test/fts5eb.test 3e5869af2008cbc4ad03a175a0b6f6e58134cd43
F ext/fts5/test/fts5fault1.test 7a562367cb4a735b57b410dbdb62dcc8d971faec
F ext/fts5/test/fts5fault1.test 4b39c47ca3544615daa8a2f733b911fa08022c77
F ext/fts5/test/fts5fault2.test 28c36c843bb39ae855ba79827417ecc37f114341
F ext/fts5/test/fts5fault3.test d6e9577d4312e331a913c72931bf131704efc8f3
F ext/fts5/test/fts5fault4.test 762991d526ee67c2b374351a17248097ea38bee7
F ext/fts5/test/fts5fault4.test 4864f2b5c2c083440dbe85aff60897bc1aa04603
F ext/fts5/test/fts5fault5.test f2b8645053d48982e8979749e93994c43011c118
F ext/fts5/test/fts5fault6.test 9682664d679643ac6736e90c225526cc84073cda
F ext/fts5/test/fts5fault7.test 01be274bfc8d9bf22451a3bf5892e9399d044f1b
@ -170,11 +170,11 @@ F ext/fts5/test/fts5porter.test 7cdc07bef301d70eebbfa75dcaf45c3680e1d0e1
F ext/fts5/test/fts5porter2.test 2e65633d58a1c525d5af0f6c01e5a59155bb3487
F ext/fts5/test/fts5prefix.test 7ccbdf180ed561a912acef520519e85af8642239
F ext/fts5/test/fts5query.test f5ec25f5f2fbb70033424113cdffc101b1985a40
F ext/fts5/test/fts5rank.test 11dcebba31d822f7e99685b4ea2c2ae3ec0b16f1
F ext/fts5/test/fts5rank.test 7e9e64eac7245637f6f2033aec4b292aaf611aab
F ext/fts5/test/fts5rebuild.test 03935f617ace91ed23a6099c7c74d905227ff29b
F ext/fts5/test/fts5restart.test c17728fdea26e7d0f617d22ad5b4b2862b994c17
F ext/fts5/test/fts5rowid.test 400384798349d658eaf06aefa1e364957d5d4821
F ext/fts5/test/fts5simple.test 41333e267c6145efc3620342af53dfe65d5676b7
F ext/fts5/test/fts5simple.test 9bded45827b4ab8933c87b7b3bcc3cd47f7378a4
F ext/fts5/test/fts5synonym.test cf88c0a56d5ea9591e3939ef1f6e294f7f2d0671
F ext/fts5/test/fts5tokenizer.test ea4df698b35cc427ebf2ba22829d0e28386d8c89
F ext/fts5/test/fts5unicode.test fbef8d8a3b4b88470536cc57604a82ca52e51841
@ -184,7 +184,7 @@ F ext/fts5/test/fts5unindexed.test e9539d5b78c677315e7ed8ea911d4fd25437c680
F ext/fts5/test/fts5version.test 978f59541d8cef7e8591f8be2115ec5ccb863e2e
F ext/fts5/test/fts5vocab.test c88a5554d0409494da95ba647bbdb4879b2624b0
F ext/fts5/tool/fts5txt2db.tcl c374c4c4797e8cdfadabdfaeeb5412dcd6686e84
F ext/fts5/tool/loadfts5.tcl 58e90407cc5c2b1770460119488fd7c0090d4dd3
F ext/fts5/tool/loadfts5.tcl 4cc2d6af43b58d4fac05bc4fdabd0e5862c3b2c1
F ext/fts5/tool/mkfts5c.tcl d1c2a9ab8e0ec690a52316f33dd9b1d379942f45
F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c
F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43
@ -196,7 +196,7 @@ F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83
F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2
F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f
F ext/misc/fuzzer.c 4c84635c71c26cfa7c2e5848cf49fe2d2cfcd767
F ext/misc/ieee754.c b0362167289170627659e84173f5d2e8fee8566e
F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c
F ext/misc/json1.c 4f45afd9dbcd6feca8c528251efbb7fc09299a09
F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342
F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63
@ -283,7 +283,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
F main.mk ace127ebc8f73fbe37ecf9021385f9efdc4d595d
F main.mk 2e67604b0dbd7670230ed626b6a2947f05a35ba5
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
@ -299,18 +299,18 @@ F src/alter.c 9d649e46c780166e416fb11dbd23f8d49aab8267
F src/analyze.c 4c308880cf53c558070cb8513bdff4ffb1a38a77
F src/attach.c e944d0052b577703b9b83aac1638452ff42a8395
F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
F src/backup.c c3a9c4209439b806c44cf30daf466955727bf46c
F src/backup.c 2869a76c03eb393ee795416e2387005553df72bc
F src/bitvec.c d1f21d7d91690747881f03940584f4cc548c9d3d
F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
F src/btree.c 77343aac89c50bb5e06cbca3ace8c057c14de57c
F src/btree.h b512723e4f27d7ba16b4b985cdecdb82c0f6d0c0
F src/btreeInt.h 8177c9ab90d772d6d2c6c517e05bed774b7c92c0
F src/btree.c 9e5d713bf54be8bfcae9b60210173dd53570f56d
F src/btree.h 1b8bf2818b5e256c25a5e09126720113b1d783da
F src/btreeInt.h 3ab435ed27adea54d040584b0bcc488ee7db1e38
F src/build.c ca574d33ffb1763cfd2979383f4d507095bfbe19
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f
F src/ctime.c 509ef9c64d1321f42448f111da86400b1799218a
F src/date.c fb1c99172017dcc8e237339132c91a21a0788584
F src/dbstat.c e637e7a7ff40ef32132a418c6fdf1cfb63aa27c7
F src/dbstat.c ffd63fc8ba7541476ced189b95e95d7f2bc63f78
F src/delete.c 9dddc4434aace0f42f1ed1c5224cdcfc2328ed67
F src/expr.c 0080c0f12806eca91e75a23a121a68918e9da357
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
@ -347,8 +347,8 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
F src/os_unix.c cf72e06e15839ebe7121e01d3eebf256c039b0ca
F src/os_win.c 1716291e5ec2dbfc5a1fe0b32182030f1f7d8acf
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
F src/pager.c 9c1eec0d88133484b165fa0b5284a411c24b964c
F src/pager.h 1c4fa826c330040c5659a384446c7cc6e8e4200c
F src/pager.c ed5cff11793b6a4146582aabb29ed8613a6cf89e
F src/pager.h 7fc069c07f3120ee466ff3d48a9d376974ebffa7
F src/parse.y 11078cd8e3af00f030505b6a86a06a4536cfdeaa
F src/pcache.c 24be750c79272e0ca7b6e007bc94999700f3e5ef
F src/pcache.h 9968603796240cdf83da7e7bef76edf90619cea9
@ -365,13 +365,13 @@ F src/shell.c 993863f82d764be0c00803056e56b9b744f86f02
F src/sqlite.h.in 45821b35edf55ac410c16a3e1de4d6d43aa7ee16
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
F src/sqlite3ext.h 4b66e3e3435da4b4c8c83696d0349f0c503b3924
F src/sqliteInt.h b2e72eaa886665d042908a736d98fadacab95ef6
F src/sqliteInt.h a02b33a3b68913394c218ec27f24b8fa33518244
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba
F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
F src/tclsqlite.c e2344bee0d192397f555a24ef3fab26f2ed93bcc
F src/test1.c 9ac5cbfe3c859ab7518edc5109a2959d6bf7b059
F src/test2.c 577961fe48961b2f2e5c8b56ee50c3f459d3359d
F src/test1.c a719afff3144f7f01c6dc3f7d118ac31d15e7527
F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b
F src/test3.c a8887dabbbee3059af338f20d290084a63ed1b0f
F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e
F src/test5.c 5a34feec76d9b3a86aab30fd4f6cc9c48cbab4c1
@ -423,11 +423,11 @@ F src/update.c c2fff3b60bfcabcb0372acbe8cf6f77c2bb515bc
F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
F src/util.c fc612367108b74573c5fd13a85d0a23027f438bd
F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
F src/vdbe.c 755ebcef6b85f4917b567401752aa39523cd06e5
F src/vdbe.c 9539aa0ccf4844b8b59466ef3c15dbffb479a390
F src/vdbe.h bfe3f80dba435377cdb64fd917f2529f0f48ab77
F src/vdbeInt.h d6ae6e64ad16e213f37306b1735ff72fb98bec69
F src/vdbeapi.c f5eda36a5c85ef578957ab4311e8d9b1f51a3552
F src/vdbeaux.c 3c67cbdee0308a0e0a942e5edea95339e021ea5c
F src/vdbeaux.c 1c5969fa8b04e162a2e893ebb283071bec81a006
F src/vdbeblob.c b400c25ac822af3c507ef84b5cd93c1583a70321
F src/vdbemem.c 25b6cfd665b5073480452426e84136edd94140c0
F src/vdbesort.c 8b23930a1289526f6d2a3a9f2e965bcc963e4a68
@ -473,7 +473,7 @@ F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b
F test/async3.test d73a062002376d7edc1fe3edff493edbec1fc2f7
F test/async4.test 1787e3952128aa10238bf39945126de7ca23685a
F test/async5.test 383ab533fdb9f7ad228cc99ee66e1acb34cc0dc0
F test/atof1.test 08a61df9365c341f334a65f4348897312d8f3db7
F test/atof1.test ff0b0156fd705b67c506e1f2bfe9e26102bea9bd
F test/attach.test 437107943f14d131cf5efc2ae5305a94d7cb1d58
F test/attach2.test 0ec5defa340363de6cd50fd595046465e9aaba2d
F test/attach3.test 359eb65d00102cdfcef6fa4e81dc1648f8f80b27
@ -500,7 +500,7 @@ F test/backup_ioerr.test 4c3c7147cee85b024ecf6e150e090c32fdbb5135
F test/backup_malloc.test 7162d604ec2b4683c4b3799a48657fb8b5e2d450
F test/badutf.test d5360fc31f643d37a973ab0d8b4fb85799c3169f
F test/badutf2.test f5bc7f2d280670ecd79b9cf4f0f1760c607fe51f
F test/bc_common.tcl 5c8689cc6d2fb44b7c0968ae4f85eb26d50022fa
F test/bc_common.tcl 3eda41ef9cda7d5f6c205462c96228b301da4191
F test/between.test 34d375fb5ce1ae283ffe82b6b233e9f38e84fc6c
F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59
F test/bigfile2.test 1b489a3a39ae90c7f027b79110d6b4e1dbc71bfc
@ -539,7 +539,7 @@ F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91
F test/collate1.test 08c18e7512a5a32c97938854263fa15362eeb846
F test/collate2.test 9aaa410a00734e48bcb27f3872617d6f69b2a621
F test/collate3.test 89defc49983ddfbf0a0555aca8c0521a676f56a5
F test/collate4.test f04d5168685f2eef637ecfa2d4ddf8ec0d600177
F test/collate4.test c953715fb498b87163e3e73dd94356bff1f317bd
F test/collate5.test 65d928034d30d2d263a80f6359f7549ee1598ec6
F test/collate6.test 8be65a182abaac8011a622131486dafb8076e907
F test/collate7.test 8ec29d98f3ee4ccebce6e16ce3863fb6b8c7b868
@ -621,7 +621,7 @@ F test/e_select.test 52692ff3849541e828ad4661fe3773a9b8711763
F test/e_select2.test aceb80ab927d46fba5ce7586ebabf23e2bb0604f
F test/e_totalchanges.test b12ee5809d3e63aeb83238dd501a7bca7fd72c10
F test/e_update.test f46c2554d915c9197548681e8d8c33a267e84528
F test/e_uri.test 5ae33760fb2039c61aa2d90886f1664664173585
F test/e_uri.test eed3eb41b22d051a1164110dacdc778899126e14
F test/e_vacuum.test 5bfbdc21b65c0abf24398d0ba31dc88d93ca77a9
F test/e_wal.test ae9a593207a77d711443ee69ffe081fda9243625
F test/e_walauto.test 280714ddf14e1a47dcbc59d515cd0b026dfd5567
@ -785,6 +785,7 @@ F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98
F test/hexlit.test 1d312fa816dfd3650a3bb488093bc09a0c927f67
F test/hook.test aa41c095d26822b8a51aa4c82904a14347961be6
F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4
F test/ieee754.test 118b665a97a8df0e8f2fbdb07d113e596f4a6b53
F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8
F test/in.test 61a24ae38d4b64ec69f06ccdf022992f68a98176
F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75
@ -922,6 +923,7 @@ F test/notify3.test 10ff25cde502e72a92053a2f215d64bece4ef934
F test/notnull.test f8fcf58669ddba79274daa2770d61dfad8274f62
F test/null.test 0dcce4f04284ec66108c503327ad6d224c0752b3
F test/numcast.test 5d126f7f581432e86a90d1e35cac625164aec4a1
F test/numindex1.test 20a5450d4b056e48cd5db30e659f13347a099823
F test/offset1.test f06b83657bcf26f9ce805e67450e189e282143b2
F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394
F test/orderby1.test 870e150450437d3980badbde3d0166b81d9e33f6
@ -948,7 +950,7 @@ F test/parser1.test 222b5cbf3e2e659fec1bf7d723488c8b9c94f1d0
F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
F test/permutations.test c57b8fa360f3b86385fc03f9b25160b5fdfbcb51
F test/permutations.test 63cb93f915b4056463cef8ad035082e9f1cb524e
F test/pragma.test a44253f911e7d50127d4a08f927f47c861a4c772
F test/pragma2.test b5e2ce4c892afceb308c6ae6163a9099b2a0d8d7
F test/pragma3.test 6f849ccffeee7e496d2f2b5e74152306c0b8757c
@ -968,7 +970,7 @@ F test/rbu.test 168573d353cd0fd10196b87b0caa322c144ef736
F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8
F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8
F test/reindex.test 44edd3966b474468b823d481eafef0c305022254
F test/releasetest.tcl 67a82199e6ddee609211488bc04ed3f9ea3aa28a
F test/releasetest.tcl 2d000ceded3115758be96abb9c10a5669fb27862
F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb
F test/rollback.test 458fe73eb3ffdfdf9f6ba3e9b7350a6220414dea
F test/rollback2.test fc14cf6d1a2b250d2735ef16124b971bce152f14
@ -1322,10 +1324,10 @@ F test/walro.test 34422d1d95aaff0388f0791ec20edb34e2a3ed57
F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417
F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a
F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e
F test/where.test 66d4c107e82dfe86c01a96277b77e7a8809aff0b
F test/where.test 9902a3d84e9bc80357a2c54ed0e76c0d6d04a867
F test/where2.test af78c55589cbc82d793449493adba0dc3d659f23
F test/where3.test 1ad55ba900bd7747f98b6082e65bd3e442c5004e
F test/where4.test 44f506bf1737cf0fa4fc795e340208250f1fcd89
F test/where4.test 4a371bfcc607f41d233701bdec33ac2972908ba8
F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2
F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b
F test/where7.test 5a4b0abc207d71da4deecd734ad8579e8dd40aa8
@ -1419,7 +1421,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 395a153ff7b3c7a72f3d02b6fe76d72383f4e480 6d5ce3ede4c7038c19a77268a5a7b9d5650933c2
R 108cce56953c38f03dac9fc0349473c4
P 0546d1cd1a3402890edade7970c269cc3f17bc98 0f5b147d1fe83c34d0fbeacc7422be94d8441bc1
R 65016c2c463ac04ecdb2d993caf6bb9d
U drh
Z a9e0c02c1ba22a50e60adc1f82d63108
Z 6ef4d8405632dbe4f4eb27a0771bc5f1

View File

@ -1 +1 @@
0546d1cd1a3402890edade7970c269cc3f17bc98
78bc42e664e9fa9ee21ad9762c369f291fcdf5db

View File

@ -293,7 +293,7 @@ static int backupOnePage(
DbPage *pDestPg = 0;
Pgno iDest = (Pgno)(iOff/nDestPgsz)+1;
if( iDest==PENDING_BYTE_PAGE(p->pDest->pBt) ) continue;
if( SQLITE_OK==(rc = sqlite3PagerGet(pDestPager, iDest, &pDestPg))
if( SQLITE_OK==(rc = sqlite3PagerGet(pDestPager, iDest, &pDestPg, 0))
&& SQLITE_OK==(rc = sqlite3PagerWrite(pDestPg))
){
const u8 *zIn = &zSrcData[iOff%nSrcPgsz];
@ -419,8 +419,7 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
const Pgno iSrcPg = p->iNext; /* Source page number */
if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){
DbPage *pSrcPg; /* Source page object */
rc = sqlite3PagerAcquire(pSrcPager, iSrcPg, &pSrcPg,
PAGER_GET_READONLY);
rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg,PAGER_GET_READONLY);
if( rc==SQLITE_OK ){
rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg), 0);
sqlite3PagerUnref(pSrcPg);
@ -520,7 +519,7 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
for(iPg=nDestTruncate; rc==SQLITE_OK && iPg<=(Pgno)nDstPage; iPg++){
if( iPg!=PENDING_BYTE_PAGE(p->pDest->pBt) ){
DbPage *pPg;
rc = sqlite3PagerGet(pDestPager, iPg, &pPg);
rc = sqlite3PagerGet(pDestPager, iPg, &pPg, 0);
if( rc==SQLITE_OK ){
rc = sqlite3PagerWrite(pPg);
sqlite3PagerUnref(pPg);
@ -540,7 +539,7 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
){
PgHdr *pSrcPg = 0;
const Pgno iSrcPg = (Pgno)((iOff/pgszSrc)+1);
rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg);
rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg, 0);
if( rc==SQLITE_OK ){
u8 *zData = sqlite3PagerGetData(pSrcPg);
rc = sqlite3OsWrite(pFile, zData, pgszSrc, iOff);

View File

@ -931,7 +931,7 @@ static void ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent, int *pRC){
return;
}
iPtrmap = PTRMAP_PAGENO(pBt, key);
rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage);
rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage, 0);
if( rc!=SQLITE_OK ){
*pRC = rc;
return;
@ -974,7 +974,7 @@ static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){
assert( sqlite3_mutex_held(pBt->mutex) );
iPtrmap = PTRMAP_PAGENO(pBt, key);
rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage);
rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage, 0);
if( rc!=0 ){
return rc;
}
@ -1901,11 +1901,14 @@ static void zeroPage(MemPage *pPage, int flags){
*/
static MemPage *btreePageFromDbPage(DbPage *pDbPage, Pgno pgno, BtShared *pBt){
MemPage *pPage = (MemPage*)sqlite3PagerGetExtra(pDbPage);
pPage->aData = sqlite3PagerGetData(pDbPage);
pPage->pDbPage = pDbPage;
pPage->pBt = pBt;
pPage->pgno = pgno;
pPage->hdrOffset = pgno==1 ? 100 : 0;
if( pgno!=pPage->pgno ){
pPage->aData = sqlite3PagerGetData(pDbPage);
pPage->pDbPage = pDbPage;
pPage->pBt = pBt;
pPage->pgno = pgno;
pPage->hdrOffset = pgno==1 ? 100 : 0;
}
assert( pPage->aData==sqlite3PagerGetData(pDbPage) );
return pPage;
}
@ -1931,7 +1934,7 @@ static int btreeGetPage(
assert( flags==0 || flags==PAGER_GET_NOCONTENT || flags==PAGER_GET_READONLY );
assert( sqlite3_mutex_held(pBt->mutex) );
rc = sqlite3PagerAcquire(pBt->pPager, pgno, (DbPage**)&pDbPage, flags);
rc = sqlite3PagerGet(pBt->pPager, pgno, (DbPage**)&pDbPage, flags);
if( rc ) return rc;
*ppPage = btreePageFromDbPage(pDbPage, pgno, pBt);
return SQLITE_OK;
@ -1996,24 +1999,25 @@ static int getAndInitPage(
rc = SQLITE_CORRUPT_BKPT;
goto getAndInitPage_error;
}
rc = sqlite3PagerAcquire(pBt->pPager, pgno, (DbPage**)&pDbPage, bReadOnly);
rc = sqlite3PagerGet(pBt->pPager, pgno, (DbPage**)&pDbPage, bReadOnly);
if( rc ){
goto getAndInitPage_error;
}
*ppPage = btreePageFromDbPage(pDbPage, pgno, pBt);
*ppPage = (MemPage*)sqlite3PagerGetExtra(pDbPage);
if( (*ppPage)->isInit==0 ){
btreePageFromDbPage(pDbPage, pgno, pBt);
rc = btreeInitPage(*ppPage);
if( rc!=SQLITE_OK ){
releasePage(*ppPage);
goto getAndInitPage_error;
}
}
assert( (*ppPage)->pgno==pgno );
assert( (*ppPage)->aData==sqlite3PagerGetData(pDbPage) );
/* If obtaining a child page for a cursor, we must verify that the page is
** compatible with the root page. */
if( pCur
&& ((*ppPage)->nCell<1 || (*ppPage)->intKey!=pCur->curIntKey)
){
if( pCur && ((*ppPage)->nCell<1 || (*ppPage)->intKey!=pCur->curIntKey) ){
rc = SQLITE_CORRUPT_BKPT;
releasePage(*ppPage);
goto getAndInitPage_error;
@ -4593,7 +4597,7 @@ static int accessPayload(
{
DbPage *pDbPage;
rc = sqlite3PagerAcquire(pBt->pPager, nextPage, &pDbPage,
rc = sqlite3PagerGet(pBt->pPager, nextPage, &pDbPage,
((eOp&0x01)==0 ? PAGER_GET_READONLY : 0)
);
if( rc==SQLITE_OK ){
@ -5037,6 +5041,8 @@ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
** *pRes>0 The cursor is left pointing at an entry that
** is larger than intKey/pIdxKey.
**
** For index tables, the pIdxKey->eqSeen field is set to 1 if there
** exists an entry in the table that exactly matches pIdxKey.
*/
int sqlite3BtreeMovetoUnpacked(
BtCursor *pCur, /* The cursor to be moved */
@ -6960,9 +6966,6 @@ static void copyNodeContent(MemPage *pFrom, MemPage *pTo, int *pRC){
** If aOvflSpace is set to a null pointer, this function returns
** SQLITE_NOMEM.
*/
#if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_M_ARM)
#pragma optimize("", off)
#endif
static int balance_nonroot(
MemPage *pParent, /* Parent page of siblings being balanced */
int iParentIdx, /* Index of "the page" in pParent */
@ -7708,9 +7711,6 @@ balance_cleanup:
return rc;
}
#if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_M_ARM)
#pragma optimize("", on)
#endif
/*
@ -8909,7 +8909,7 @@ static void checkList(
break;
}
if( checkRef(pCheck, iPage) ) break;
if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage) ){
if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage, 0) ){
checkAppendMsg(pCheck, "failed to get page %d", iPage);
break;
}
@ -9646,7 +9646,6 @@ int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){
return rc;
}
#ifdef SQLITE_DEBUG
/*
** Return true if the cursor has a hint specified. This routine is
** only used from within assert() statements
@ -9654,7 +9653,6 @@ int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){
int sqlite3BtreeCursorHasHint(BtCursor *pCsr, unsigned int mask){
return (pCsr->hints & mask)!=0;
}
#endif
/*
** Return true if the given Btree is read-only.

View File

@ -257,9 +257,7 @@ int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*);
void sqlite3BtreeIncrblobCursor(BtCursor *);
void sqlite3BtreeClearCursor(BtCursor *);
int sqlite3BtreeSetVersion(Btree *pBt, int iVersion);
#ifdef SQLITE_DEBUG
int sqlite3BtreeCursorHasHint(BtCursor*, unsigned int mask);
#endif
int sqlite3BtreeIsReadonly(Btree *pBt);
int sqlite3HeaderSizeBtree(void);

View File

@ -517,7 +517,7 @@ struct BtCursor {
int skipNext; /* Prev() is noop if negative. Next() is noop if positive.
** Error code if eState==CURSOR_FAULT */
u8 curFlags; /* zero or more BTCF_* flags defined below */
u8 curPagerFlags; /* Flags to send to sqlite3PagerAcquire() */
u8 curPagerFlags; /* Flags to send to sqlite3PagerGet() */
u8 eState; /* One of the CURSOR_XXX constants (see below) */
u8 hints; /* As configured by CursorSetHints() */
/* All fields above are zeroed when the cursor is allocated. See

View File

@ -386,7 +386,7 @@ static int statDecodePage(Btree *pBt, StatPage *p){
int rc;
u32 iPrev = pCell->aOvfl[j-1];
DbPage *pPg = 0;
rc = sqlite3PagerGet(sqlite3BtreePager(pBt), iPrev, &pPg);
rc = sqlite3PagerGet(sqlite3BtreePager(pBt), iPrev, &pPg, 0);
if( rc!=SQLITE_OK ){
assert( pPg==0 );
return rc;
@ -454,7 +454,7 @@ statNextRestart:
pCsr->isEof = 1;
return sqlite3_reset(pCsr->pStmt);
}
rc = sqlite3PagerGet(pPager, iRoot, &pCsr->aPage[0].pPg);
rc = sqlite3PagerGet(pPager, iRoot, &pCsr->aPage[0].pPg, 0);
pCsr->aPage[0].iPgno = iRoot;
pCsr->aPage[0].iCell = 0;
pCsr->aPage[0].zPath = z = sqlite3_mprintf("/");
@ -514,7 +514,7 @@ statNextRestart:
}else{
p[1].iPgno = p->aCell[p->iCell].iChildPg;
}
rc = sqlite3PagerGet(pPager, p[1].iPgno, &p[1].pPg);
rc = sqlite3PagerGet(pPager, p[1].iPgno, &p[1].pPg, 0);
p[1].iCell = 0;
p[1].zPath = z = sqlite3_mprintf("%s%.3x/", p->zPath, p->iCell);
p->iCell++;

View File

@ -2333,7 +2333,7 @@ static int pager_playback_one_page(
assert( isSavepnt );
assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)==0 );
pPager->doNotSpill |= SPILLFLAG_ROLLBACK;
rc = sqlite3PagerAcquire(pPager, pgno, &pPg, 1);
rc = sqlite3PagerGet(pPager, pgno, &pPg, 1);
assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)!=0 );
pPager->doNotSpill &= ~SPILLFLAG_ROLLBACK;
if( rc!=SQLITE_OK ) return rc;
@ -4969,7 +4969,7 @@ static int hasHotJournal(Pager *pPager, int *pExists){
/*
** This function is called to obtain a shared lock on the database file.
** It is illegal to call sqlite3PagerAcquire() until after this function
** It is illegal to call sqlite3PagerGet() until after this function
** has been successfully called. If a shared-lock is already held when
** this function is called, it is a no-op.
**
@ -5272,7 +5272,7 @@ static void pagerUnlockIfUnused(Pager *pPager){
** Since Lookup() never goes to disk, it never has to deal with locks
** or journal files.
*/
int sqlite3PagerAcquire(
int sqlite3PagerGet(
Pager *pPager, /* The pager open on the database file */
Pgno pgno, /* Page number to fetch */
DbPage **ppPage, /* Write a pointer to the page here */
@ -5858,7 +5858,7 @@ static SQLITE_NOINLINE int pagerWriteLargeSector(PgHdr *pPg){
PgHdr *pPage;
if( pg==pPg->pgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){
if( pg!=PAGER_MJ_PGNO(pPager) ){
rc = sqlite3PagerGet(pPager, pg, &pPage);
rc = sqlite3PagerGet(pPager, pg, &pPage, 0);
if( rc==SQLITE_OK ){
rc = pager_write(pPage);
if( pPage->flags&PGHDR_NEED_SYNC ){
@ -6018,7 +6018,7 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){
assert( !pPager->tempFile && isOpen(pPager->fd) );
/* Open page 1 of the file for writing. */
rc = sqlite3PagerGet(pPager, 1, &pPgHdr);
rc = sqlite3PagerGet(pPager, 1, &pPgHdr, 0);
assert( pPgHdr==0 || rc==SQLITE_OK );
/* If page one was fetched successfully, and this function is not
@ -6173,7 +6173,7 @@ int sqlite3PagerCommitPhaseOne(
if( pList==0 ){
/* Must have at least one page for the WAL commit flag.
** Ticket [2d1a5c67dfc2363e44f29d9bbd57f] 2011-05-18 */
rc = sqlite3PagerGet(pPager, 1, &pPageOne);
rc = sqlite3PagerGet(pPager, 1, &pPageOne, 0);
pList = pPageOne;
pList->pDirty = 0;
}
@ -6878,7 +6878,7 @@ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){
** the journal file twice, but that is not a problem.
*/
PgHdr *pPgHdr;
rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr);
rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr, 0);
if( rc!=SQLITE_OK ){
if( needSyncPgno<=pPager->dbOrigSize ){
assert( pPager->pTmpSpace!=0 );

View File

@ -79,7 +79,7 @@ typedef struct PgHdr DbPage;
#define PAGER_JOURNALMODE_WAL 5 /* Use write-ahead logging */
/*
** Flags that make up the mask passed to sqlite3PagerAcquire().
** Flags that make up the mask passed to sqlite3PagerGet().
*/
#define PAGER_GET_NOCONTENT 0x01 /* Do not load data from disk */
#define PAGER_GET_READONLY 0x02 /* Read-only page is acceptable */
@ -135,8 +135,7 @@ sqlite3_backup **sqlite3PagerBackupPtr(Pager*);
int sqlite3PagerFlush(Pager*);
/* Functions used to obtain and release page references. */
int sqlite3PagerAcquire(Pager *pPager, Pgno pgno, DbPage **ppPage, int clrFlag);
#define sqlite3PagerGet(A,B,C) sqlite3PagerAcquire(A,B,C,0)
int sqlite3PagerGet(Pager *pPager, Pgno pgno, DbPage **ppPage, int clrFlag);
DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno);
void sqlite3PagerRef(DbPage*);
void sqlite3PagerUnref(DbPage*);

View File

@ -1820,9 +1820,8 @@ struct KeyInfo {
};
/*
** An instance of the following structure holds information about a
** single index record that has already been parsed out into individual
** values.
** This object holds a record which has been parsed out into individual
** fields, for the purposes of doing a comparison.
**
** A record is an object that contains one or more fields of data.
** Records are used to store the content of a table row and to store
@ -1830,20 +1829,40 @@ struct KeyInfo {
** the OP_MakeRecord opcode of the VDBE and is disassembled by the
** OP_Column opcode.
**
** This structure holds a record that has already been disassembled
** into its constituent fields.
** An instance of this object serves as a "key" for doing a search on
** an index b+tree. The goal of the search is to find the entry that
** is closed to the key described by this object. This object might hold
** just a prefix of the key. The number of fields is given by
** pKeyInfo->nField.
**
** The r1 and r2 member variables are only used by the optimized comparison
** functions vdbeRecordCompareInt() and vdbeRecordCompareString().
** The r1 and r2 fields are the values to return if this key is less than
** or greater than a key in the btree, respectively. These are normally
** -1 and +1 respectively, but might be inverted to +1 and -1 if the b-tree
** is in DESC order.
**
** The key comparison functions actually return default_rc when they find
** an equals comparison. default_rc can be -1, 0, or +1. If there are
** multiple entries in the b-tree with the same key (when only looking
** at the first pKeyInfo->nFields,) then default_rc can be set to -1 to
** cause the search to find the last match, or +1 to cause the search to
** find the first match.
**
** The key comparison functions will set eqSeen to true if they ever
** get and equal results when comparing this structure to a b-tree record.
** When default_rc!=0, the search might end up on the record immediately
** before the first match or immediately after the last match. The
** eqSeen field will indicate whether or not an exact match exists in the
** b-tree.
*/
struct UnpackedRecord {
KeyInfo *pKeyInfo; /* Collation and sort-order information */
Mem *aMem; /* Values */
u16 nField; /* Number of entries in apMem[] */
i8 default_rc; /* Comparison result if keys are equal */
u8 errCode; /* Error detected by xRecordCompare (CORRUPT or NOMEM) */
Mem *aMem; /* Values */
int r1; /* Value to return if (lhs > rhs) */
int r2; /* Value to return if (rhs < lhs) */
i8 r1; /* Value to return if (lhs > rhs) */
i8 r2; /* Value to return if (rhs < lhs) */
u8 eqSeen; /* True if an equality comparison has been seen */
};

View File

@ -7039,6 +7039,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
};
static int bitmask_size = sizeof(Bitmask)*8;
static int longdouble_size = sizeof(LONGDOUBLE_TYPE);
int i;
extern int sqlite3_sync_count, sqlite3_fullsync_count;
extern int sqlite3_opentemp_count;
@ -7139,6 +7140,8 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
(char*)&sqlite3_data_directory, TCL_LINK_STRING);
Tcl_LinkVar(interp, "bitmask_size",
(char*)&bitmask_size, TCL_LINK_INT|TCL_LINK_READ_ONLY);
Tcl_LinkVar(interp, "longdouble_size",
(char*)&longdouble_size, TCL_LINK_INT|TCL_LINK_READ_ONLY);
Tcl_LinkVar(interp, "sqlite_sync_count",
(char*)&sqlite3_sync_count, TCL_LINK_INT);
Tcl_LinkVar(interp, "sqlite_fullsync_count",

View File

@ -322,7 +322,7 @@ static int page_get(
if( Tcl_GetInt(interp, argv[2], &pgno) ) return TCL_ERROR;
rc = sqlite3PagerSharedLock(pPager);
if( rc==SQLITE_OK ){
rc = sqlite3PagerGet(pPager, pgno, &pPage);
rc = sqlite3PagerGet(pPager, pgno, &pPage, 0);
}
if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);

View File

@ -3607,6 +3607,13 @@ case OP_ColumnsUsed: {
** is greater than or equal to the key value. If there are no records
** greater than or equal to the key and P2 is not zero, then jump to P2.
**
** If the cursor P1 was opened using the OPFLAG_SEEKEQ flag, then this
** opcode will always land on a record that equally equals the key, or
** else jump immediately to P2. When the cursor is OPFLAG_SEEKEQ, this
** opcode must be followed by an IdxLE opcode with the same arguments.
** The IdxLE opcode will be skipped if this opcode succeeds, but the
** IdxLE opcode will be used on subsequent loop iterations.
**
** This opcode leaves the cursor configured to move in forward order,
** from the beginning toward the end. In other words, the cursor is
** configured to use Next, not Prev.
@ -3665,18 +3672,26 @@ case OP_ColumnsUsed: {
** from the end toward the beginning. In other words, the cursor is
** configured to use Prev, not Next.
**
** If the cursor P1 was opened using the OPFLAG_SEEKEQ flag, then this
** opcode will always land on a record that equally equals the key, or
** else jump immediately to P2. When the cursor is OPFLAG_SEEKEQ, this
** opcode must be followed by an IdxGE opcode with the same arguments.
** The IdxGE opcode will be skipped if this opcode succeeds, but the
** IdxGE opcode will be used on subsequent loop iterations.
**
** See also: Found, NotFound, SeekGt, SeekGe, SeekLt
*/
case OP_SeekLT: /* jump, in3 */
case OP_SeekLE: /* jump, in3 */
case OP_SeekGE: /* jump, in3 */
case OP_SeekGT: { /* jump, in3 */
int res;
int oc;
VdbeCursor *pC;
UnpackedRecord r;
int nField;
i64 iKey; /* The rowid we are to seek to */
int res; /* Comparison result */
int oc; /* Opcode */
VdbeCursor *pC; /* The cursor to seek */
UnpackedRecord r; /* The key to seek for */
int nField; /* Number of columns or fields in the key */
i64 iKey; /* The rowid we are to seek to */
int eqOnly; /* Only interested in == results */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
assert( pOp->p2!=0 );
@ -3689,27 +3704,16 @@ case OP_SeekGT: { /* jump, in3 */
assert( pC->isOrdered );
assert( pC->pCursor!=0 );
oc = pOp->opcode;
eqOnly = 0;
pC->nullRow = 0;
#ifdef SQLITE_DEBUG
pC->seekOp = pOp->opcode;
#endif
/* For a cursor with the BTREE_SEEK_EQ hint, only the OP_SeekGE and
** OP_SeekLE opcodes are allowed, and these must be immediately followed
** by an OP_IdxGT or OP_IdxLT opcode, respectively, with the same key.
*/
#ifdef SQLITE_DEBUG
if( sqlite3BtreeCursorHasHint(pC->pCursor, BTREE_SEEK_EQ) ){
assert( pOp->opcode==OP_SeekGE || pOp->opcode==OP_SeekLE );
assert( pOp[1].opcode==OP_IdxLT || pOp[1].opcode==OP_IdxGT );
assert( pOp[1].p1==pOp[0].p1 );
assert( pOp[1].p2==pOp[0].p2 );
assert( pOp[1].p3==pOp[0].p3 );
assert( pOp[1].p4.i==pOp[0].p4.i );
}
#endif
if( pC->isTable ){
/* The BTREE_SEEK_EQ flag is only set on index cursors */
assert( sqlite3BtreeCursorHasHint(pC->pCursor, BTREE_SEEK_EQ)==0 );
/* The input value in P3 might be of any type: integer, real, string,
** blob, or NULL. But it needs to be an integer before we can do
** the seek, so convert it. */
@ -3758,6 +3762,20 @@ case OP_SeekGT: { /* jump, in3 */
goto abort_due_to_error;
}
}else{
/* For a cursor with the BTREE_SEEK_EQ hint, only the OP_SeekGE and
** OP_SeekLE opcodes are allowed, and these must be immediately followed
** by an OP_IdxGT or OP_IdxLT opcode, respectively, with the same key.
*/
if( sqlite3BtreeCursorHasHint(pC->pCursor, BTREE_SEEK_EQ) ){
eqOnly = 1;
assert( pOp->opcode==OP_SeekGE || pOp->opcode==OP_SeekLE );
assert( pOp[1].opcode==OP_IdxLT || pOp[1].opcode==OP_IdxGT );
assert( pOp[1].p1==pOp[0].p1 );
assert( pOp[1].p2==pOp[0].p2 );
assert( pOp[1].p3==pOp[0].p3 );
assert( pOp[1].p4.i==pOp[0].p4.i );
}
nField = pOp->p4.i;
assert( pOp->p4type==P4_INT32 );
assert( nField>0 );
@ -3782,10 +3800,15 @@ case OP_SeekGT: { /* jump, in3 */
{ int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); }
#endif
ExpandBlob(r.aMem);
r.eqSeen = 0;
rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, &r, 0, 0, &res);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
if( eqOnly && r.eqSeen==0 ){
assert( res!=0 );
goto seek_not_found;
}
}
pC->deferredMoveto = 0;
pC->cacheStatus = CACHE_STALE;
@ -3813,10 +3836,14 @@ case OP_SeekGT: { /* jump, in3 */
res = sqlite3BtreeEof(pC->pCursor);
}
}
seek_not_found:
assert( pOp->p2>0 );
VdbeBranchTaken(res!=0,2);
if( res ){
goto jump_to_p2;
}else if( eqOnly ){
assert( pOp[1].opcode==OP_IdxLT || pOp[1].opcode==OP_IdxGT );
pOp++; /* Skip the OP_IdxLt or OP_IdxGT that follows */
}
break;
}

View File

@ -3320,6 +3320,10 @@ u32 sqlite3VdbeSerialGet(
/* EVIDENCE-OF: R-01849-26079 Value is a big-endian 32-bit
** twos-complement integer. */
pMem->u.i = FOUR_BYTE_INT(buf);
#ifdef __HP_cc
/* Work around a sign-extension bug in the HP compiler for HP/UX */
if( buf[0]&0x80 ) pMem->u.i |= 0xffffffff80000000LL;
#endif
pMem->flags = MEM_Int;
testcase( pMem->u.i<0 );
return 4;
@ -3636,6 +3640,34 @@ static SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem *pB2){
return pB1->n - pB2->n;
}
/*
** Do a comparison between a 64-bit signed integer and a 64-bit floating-point
** number. Return negative, zero, or positive if the first (i64) is less than,
** equal to, or greater than the second (double).
*/
static int sqlite3IntFloatCompare(i64 i, double r){
if( sizeof(LONGDOUBLE_TYPE)>8 ){
LONGDOUBLE_TYPE x = (LONGDOUBLE_TYPE)i;
if( x<r ) return -1;
if( x>r ) return +1;
return 0;
}else{
i64 y;
double s;
if( r<-9223372036854775808.0 ) return +1;
if( r>9223372036854775807.0 ) return -1;
y = (i64)r;
if( i<y ) return -1;
if( i>y ){
if( y==SMALLEST_INT64 && r>0.0 ) return -1;
return +1;
}
s = (double)i;
if( s<r ) return -1;
if( s>r ) return +1;
return 0;
}
}
/*
** Compare the values contained by the two memory cells, returning
@ -3662,34 +3694,34 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
return (f2&MEM_Null) - (f1&MEM_Null);
}
/* If one value is a number and the other is not, the number is less.
** If both are numbers, compare as reals if one is a real, or as integers
** if both values are integers.
/* At least one of the two values is a number
*/
if( combined_flags&(MEM_Int|MEM_Real) ){
double r1, r2;
if( (f1 & f2 & MEM_Int)!=0 ){
if( pMem1->u.i < pMem2->u.i ) return -1;
if( pMem1->u.i > pMem2->u.i ) return 1;
if( pMem1->u.i > pMem2->u.i ) return +1;
return 0;
}
if( (f1 & f2 & MEM_Real)!=0 ){
if( pMem1->u.r < pMem2->u.r ) return -1;
if( pMem1->u.r > pMem2->u.r ) return +1;
return 0;
}
if( (f1&MEM_Int)!=0 ){
if( (f2&MEM_Real)!=0 ){
return sqlite3IntFloatCompare(pMem1->u.i, pMem2->u.r);
}else{
return -1;
}
}
if( (f1&MEM_Real)!=0 ){
r1 = pMem1->u.r;
}else if( (f1&MEM_Int)!=0 ){
r1 = (double)pMem1->u.i;
}else{
return 1;
if( (f2&MEM_Int)!=0 ){
return -sqlite3IntFloatCompare(pMem2->u.i, pMem1->u.r);
}else{
return -1;
}
}
if( (f2&MEM_Real)!=0 ){
r2 = pMem2->u.r;
}else if( (f2&MEM_Int)!=0 ){
r2 = (double)pMem2->u.i;
}else{
return -1;
}
if( r1<r2 ) return -1;
if( r1>r2 ) return 1;
return 0;
return +1;
}
/* If one value is a string and the other is a blob, the string is less.
@ -3840,13 +3872,8 @@ int sqlite3VdbeRecordCompareWithSkip(
}else if( serial_type==0 ){
rc = -1;
}else if( serial_type==7 ){
double rhs = (double)pRhs->u.i;
sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1);
if( mem1.u.r<rhs ){
rc = -1;
}else if( mem1.u.r>rhs ){
rc = +1;
}
rc = -sqlite3IntFloatCompare(pRhs->u.i, mem1.u.r);
}else{
i64 lhs = vdbeRecordDecodeInt(serial_type, &aKey1[d1]);
i64 rhs = pRhs->u.i;
@ -3870,18 +3897,15 @@ int sqlite3VdbeRecordCompareWithSkip(
}else if( serial_type==0 ){
rc = -1;
}else{
double rhs = pRhs->u.r;
double lhs;
sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1);
if( serial_type==7 ){
lhs = mem1.u.r;
if( mem1.u.r<pRhs->u.r ){
rc = -1;
}else if( mem1.u.r>pRhs->u.r ){
rc = +1;
}
}else{
lhs = (double)mem1.u.i;
}
if( lhs<rhs ){
rc = -1;
}else if( lhs>rhs ){
rc = +1;
rc = sqlite3IntFloatCompare(mem1.u.i, pRhs->u.r);
}
}
}
@ -3971,6 +3995,7 @@ int sqlite3VdbeRecordCompareWithSkip(
|| vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, pPKey2->default_rc)
|| pKeyInfo->db->mallocFailed
);
pPKey2->eqSeen = 1;
return pPKey2->default_rc;
}
int sqlite3VdbeRecordCompare(
@ -4070,6 +4095,7 @@ static int vdbeRecordCompareInt(
/* The first fields of the two keys are equal and there are no trailing
** fields. Return pPKey2->default_rc in this case. */
res = pPKey2->default_rc;
pPKey2->eqSeen = 1;
}
assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, res) );
@ -4090,6 +4116,7 @@ static int vdbeRecordCompareString(
int serial_type;
int res;
assert( pPKey2->aMem[0].flags & MEM_Str );
vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo);
getVarint32(&aKey1[1], serial_type);
if( serial_type<12 ){
@ -4116,6 +4143,7 @@ static int vdbeRecordCompareString(
res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1);
}else{
res = pPKey2->default_rc;
pPKey2->eqSeen = 1;
}
}else if( res>0 ){
res = pPKey2->r2;

View File

@ -15,7 +15,7 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
if {![info exists __GNUC__] || [regexp arm $tcl_platform(machine)]} {
if {$::longdouble_size<=8} {
finish_test
return
}

View File

@ -7,11 +7,13 @@ proc bc_find_binaries {zCaption} {
# against.
#
set binaries [list]
set pattern "[file tail [info nameofexec]]?*"
set self [file tail [info nameofexec]]
set pattern "$self?*"
if {$::tcl_platform(platform)=="windows"} {
set pattern [string map {\.exe {}} $pattern]
}
foreach file [glob -nocomplain $pattern] {
if {$file==$self} continue
if {[file executable $file] && [file isfile $file]} {lappend binaries $file}
}

View File

@ -352,7 +352,7 @@ do_test collate4-2.1.2 {
count {
SELECT * FROM collate4t2, collate4t1 WHERE a = b;
}
} {A a A A 5}
} {A a A A 4}
do_test collate4-2.1.3 {
count {
SELECT * FROM collate4t2, collate4t1 WHERE b = a;
@ -372,7 +372,7 @@ do_test collate4-2.1.5 {
count {
SELECT * FROM collate4t2, collate4t1 WHERE b = a;
}
} {A A 4}
} {A A 3}
ifcapable subquery {
do_test collate4-2.1.6 {
count {
@ -389,12 +389,12 @@ ifcapable subquery {
SELECT a FROM collate4t1 WHERE a IN (SELECT * FROM collate4t2)
ORDER BY rowid
}
} {a A 6}
} {a A 5}
do_test collate4-2.1.8 {
count {
SELECT a FROM collate4t1 WHERE a IN ('z', 'a');
}
} {a A 5}
} {a A 4}
do_test collate4-2.1.9 {
execsql {
DROP INDEX collate4i1;

View File

@ -26,7 +26,9 @@ proc parse_uri {uri} {
set DB [sqlite3_open_v2 $uri {
SQLITE_OPEN_READWRITE SQLITE_OPEN_CREATE SQLITE_OPEN_WAL
} tvfs]
set fileName [sqlite3_db_filename $DB main]
sqlite3_close $DB
forcedelete $fileName
tvfs delete
tvfs2 delete

56
test/ieee754.test Normal file
View File

@ -0,0 +1,56 @@
# 2015-11-06
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# Tests of the iee754 extension
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
load_static_extension db ieee754
foreach {id float rep} {
1 1.0 1,0
2 2.0 2,0
3 0.5 1,-1
4 1.5 3,-1
5 0.0 0,-1075
6 4.9406564584124654e-324 4503599627370497,-1075
7 2.2250738585072009e-308 9007199254740991,-1075
8 2.2250738585072014e-308 1,-1022
} {
do_test ieee754-100-$id-1 {
db eval "SELECT ieee754($float);"
} "ieee754($rep)"
do_test ieee754-100-$id-2 {
db eval "SELECT ieee754($rep)==$float;"
} {1}
if {$float!=0.0} {
do_test ieee754-100-$id-3 {
db eval "SELECT ieee754(-$float);"
} "ieee754(-$rep)"
do_test ieee754-100-$id-4 {
db eval "SELECT ieee754(-$rep)==-$float;"
} {1}
}
}
do_execsql_test ieee754-110 {
SELECT ieee754(1,1024), ieee754(4503599627370495,972);
} {Inf 1.79769313486232e+308}
do_execsql_test ieee754-111 {
SELECT ieee754(-1,1024), ieee754(-4503599627370495,972);
} {-Inf -1.79769313486232e+308}
do_execsql_test ieee754-112 {
SELECT ieee754(4503599627370495,973) is null;
} {1}
finish_test

79
test/numindex1.test Normal file
View File

@ -0,0 +1,79 @@
# 2015-11-05
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements tests for indexes on large numeric values.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# Test cases from Zsbán Ambrus:
#
do_execsql_test numindex1-1.1 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
CREATE INDEX t1b ON t1(b);
INSERT INTO t1(a,b) VALUES(100, 356282677878746339);
INSERT INTO t1(a,b) VALUES(50, 356282677878746339.0);
INSERT INTO t1(a,b) VALUES(0, 356282677878746340);
DELETE FROM t1 WHERE a=50;
PRAGMA integrity_check;
} {ok}
do_execsql_test numindex1-1.2 {
CREATE TABLE t2(a,b);
INSERT INTO t2(a,b) VALUES('b', 1<<58),
('c', (1<<58)+1e-7), ('d', (1<<58)+1);
SELECT a, b, typeof(b), '|' FROM t2 ORDER BY +a;
} {b 288230376151711744 integer | c 2.88230376151712e+17 real | d 288230376151711745 integer |}
do_execsql_test numindex1-1.3 {
SELECT x.a || CASE WHEN x.b==y.b THEN '==' ELSE '<>' END || y.a
FROM t2 AS x, t2 AS y
ORDER BY +x.a, +x.b;
} {b==b b==c b<>d c==b c==c c<>d d<>b d<>c d==d}
# New test cases
#
do_execsql_test numindex1-2.1 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(a INTEGER PRIMARY KEY,b);
CREATE INDEX t1b ON t1(b);
WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100)
INSERT INTO t1(a,b) SELECT x, 10000000000000004.0 FROM c
WHERE x NOT IN (23,37);
INSERT INTO t1(a,b) VALUES(23,10000000000000005);
INSERT INTO t1(a,b) VALUES(37,10000000000000003);
DELETE FROM t1 WHERE a NOT IN (23,37);
PRAGMA integrity_check;
} {ok}
do_execsql_test numindex1-3.1 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(a INTEGER PRIMARY KEY,b);
CREATE INDEX t1b ON t1(b);
WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<20)
INSERT INTO t1(a,b) SELECT x, 100000000000000005.0
FROM c WHERE x NOT IN (3,5,7,11,13,17,19);
INSERT INTO t1(a,b) VALUES(3,100000000000000005);
INSERT INTO t1(a,b) VALUES(5,100000000000000000);
INSERT INTO t1(a,b) VALUES(7,100000000000000008);
INSERT INTO t1(a,b) VALUES(11,100000000000000006);
INSERT INTO t1(a,b) VALUES(13,100000000000000001);
INSERT INTO t1(a,b) VALUES(17,100000000000000004);
INSERT INTO t1(a,b) VALUES(19,100000000000000003);
PRAGMA integrity_check;
} {ok}
do_execsql_test numindex1-3.2 {
SELECT a FROM t1 ORDER BY b;
} {1 2 4 5 6 8 9 10 12 14 15 16 18 20 13 19 17 3 11 7}
finish_test

View File

@ -182,7 +182,7 @@ test_suite "valgrind" -prefix "" -description {
} -files [
test_set $allquicktests -exclude *malloc* *ioerr* *fault* wal.test \
shell*.test crash8.test atof1.test selectG.test \
tkt-fc62af4523.test
tkt-fc62af4523.test numindex1.test
] -initialize {
set ::G(valgrind) 1
} -shutdown {
@ -711,7 +711,7 @@ test_suite "inmemory_journal" -description {
pragma journal_mode = 'memory'
} -files [test_set $::allquicktests -exclude {
# Exclude all tests that simulate IO errors.
autovacuum_ioerr2.test incrvacuum_ioerr.test ioerr.test
autovacuum_ioerr2.test cffault.test incrvacuum_ioerr.test ioerr.test
ioerr.test ioerr2.test ioerr3.test ioerr4.test ioerr5.test
vacuum3.test incrblob_err.test diskfull.test backup_ioerr.test
e_fts3.test fts3cov.test fts3malloc.test fts3rnd.test
@ -727,7 +727,7 @@ test_suite "inmemory_journal" -description {
corrupt5.test corruptA.test pageropt.test
# Exclude stmt.test, which expects sub-journals to use temporary files.
stmt.test
stmt.test symlink.test
zerodamage.test

View File

@ -19,6 +19,8 @@ optional) are:
--dryrun (Print what would have happened)
--info (Show diagnostic info)
--with-tcl=DIR (Use TCL build at DIR)
--jobs N (Use N processes - default 1)
--progress (Show progress messages)
The default value for --srcdir is the parent of the directory holding
this script.
@ -32,6 +34,12 @@ Every test begins with a fresh run of the configure script at the top
of the SQLite source tree.
}
# Return a timestamp of the form HH:MM:SS
#
proc now {} {
return [clock format [clock seconds] -format %H:%M:%S]
}
# Omit comments (text between # and \n) in a long multi-line string.
#
proc strip_comments {in} {
@ -120,6 +128,7 @@ array set ::Configs [strip_comments {
-DSQLITE_ENABLE_STAT4
-DSQLITE_ENABLE_RBU
-DSQLITE_MAX_ATTACHED=125
-DLONGDOUBLE_TYPE=double
}
"Device-One" {
-O2
@ -223,6 +232,7 @@ array set ::Configs [strip_comments {
array set ::Platforms [strip_comments {
Linux-x86_64 {
"Check-Symbols" checksymbols
"Fast-One" fuzztest
"Debug-One" "mptest test"
"Have-Not" test
"Secure-Delete" test
@ -233,10 +243,9 @@ array set ::Platforms [strip_comments {
"No-lookaside" test
"Devkit" test
"Sanitize" {QUICKTEST_OMIT=func4.test,nan.test test}
"Fast-One" fuzztest
"Valgrind" valgrindtest
"Default" "threadtest fulltest"
"Device-One" fulltest
"Default" "threadtest fulltest"
"Valgrind" valgrindtest
}
Linux-i686 {
"Devkit" test
@ -257,12 +266,12 @@ array set ::Platforms [strip_comments {
"OS-X" "threadtest fulltest"
}
"Windows NT-intel" {
"Default" "mptest fulltestonly"
"Have-Not" test
"Default" "mptest fulltestonly"
}
"Windows NT-amd64" {
"Default" "mptest fulltestonly"
"Have-Not" test
"Default" "mptest fulltestonly"
}
# The Failure-Detection platform runs various tests that deliberately
@ -285,6 +294,9 @@ array set ::Platforms [strip_comments {
#########################################################################
#########################################################################
# Configuration verification: Check that each entry in the list of configs
# specified for each platforms exists.
#
foreach {key value} [array get ::Platforms] {
foreach {v t} $value {
if {0==[info exists ::Configs($v)]} {
@ -372,9 +384,8 @@ proc count_tests_and_errors {logfile rcVar errmsgVar} {
}
close $fd
if {$::BUILDONLY} {
if {$rc==0} {
set errmsg "Build complete"
} else {
incr ::NTESTCASE
if {$rc!=0} {
set errmsg "Build failed"
}
} elseif {!$seen} {
@ -386,12 +397,169 @@ proc count_tests_and_errors {logfile rcVar errmsgVar} {
}
}
proc run_test_suite {name testtarget config} {
#--------------------------------------------------------------------------
# This command is invoked as the [main] routine for scripts run with the
# "--slave" option.
#
# For each test (i.e. "configure && make test" execution), the master
# process spawns a process with the --slave option. It writes two lines
# to the slaves stdin. The first contains a single boolean value - the
# value of ::TRACE to use in the slave script. The second line contains a
# list in the same format as each element of the list passed to the
# [run_all_test_suites] command in the master process.
#
# The slave then runs the "configure && make test" commands specified. It
# exits successfully if the tests passes, or with a non-zero error code
# otherwise.
#
proc run_slave_test {} {
# Read global vars configuration from stdin.
set V [gets stdin]
foreach {::TRACE ::MSVC ::DRYRUN} $V {}
# Read the test-suite configuration from stdin.
set T [gets stdin]
foreach {title dir configOpts testtarget makeOpts cflags opts} $T {}
# Create and switch to the test directory.
trace_cmd file mkdir $dir
trace_cmd cd $dir
catch {file delete core}
catch {file delete test.log}
# Run the "./configure && make" commands.
set rc 0
set rc [catch [configureCommand $configOpts]]
if {!$rc} {
if {[info exists ::env(TCLSH_CMD)]} {
set savedEnv(TCLSH_CMD) $::env(TCLSH_CMD)
} else {
unset -nocomplain savedEnv(TCLSH_CMD)
}
set ::env(TCLSH_CMD) [file nativename [info nameofexecutable]]
set rc [catch [makeCommand $testtarget $makeOpts $cflags $opts]]
if {[info exists savedEnv(TCLSH_CMD)]} {
set ::env(TCLSH_CMD) $savedEnv(TCLSH_CMD)
} else {
unset -nocomplain ::env(TCLSH_CMD)
}
}
# Exis successfully if the test passed, or with a non-zero error code
# otherwise.
exit $rc
}
# This command is invoked in the master process each time a slave
# file-descriptor is readable.
#
proc slave_fileevent {fd T tm1} {
global G
foreach {title dir configOpts testtarget makeOpts cflags opts} $T {}
if {[eof $fd]} {
fconfigure $fd -blocking 1
set rc [catch { close $fd }]
set errmsg {}
set logfile [file join $dir test.log]
if {[file exists $logfile]} {
count_tests_and_errors [file join $dir test.log] rc errmsg
} elseif {$rc==0 && !$::DRYRUN} {
set rc 1
set errmsg "no test.log file..."
}
if {!$::TRACE} {
set tm2 [clock seconds]
set hours [expr {($tm2-$tm1)/3600}]
set minutes [expr {(($tm2-$tm1)/60)%60}]
set seconds [expr {($tm2-$tm1)%60}]
set tm [format (%02d:%02d:%02d) $hours $minutes $seconds]
if {$rc} {
set status FAIL
incr ::NERR
} else {
set status Ok
}
set n [string length $title]
if {$::PROGRESS_MSGS} {
PUTS "finished: ${title}[string repeat . [expr {53-$n}]] $status $tm"
} else {
PUTS "${title}[string repeat . [expr {63-$n}]] $status $tm"
}
if {$errmsg!=""} {PUTS " $errmsg"}
flush stdout
}
incr G(nJob) -1
} else {
set line [gets $fd]
if {[string trim $line] != ""} {
puts "Trace : $title - \"$line\""
}
}
}
#--------------------------------------------------------------------------
# The only argument passed to this function is a list of test-suites to
# run. Each "test-suite" is itself a list consisting of the following
# elements:
#
# * Test title (for display).
# * The name of the directory to run the test in.
# * The argument for [configureCommand]
# * The first argument for [makeCommand]
# * The second argument for [makeCommand]
# * The third argument for [makeCommand]
#
proc run_all_test_suites {alltests} {
global G
set tests $alltests
set G(nJob) 0
while {[llength $tests]>0 || $G(nJob)>0} {
if {$G(nJob)>=$::JOBS || [llength $tests]==0} {
vwait G(nJob)
}
if {[llength $tests]>0} {
set T [lindex $tests 0]
set tests [lrange $tests 1 end]
foreach {title dir configOpts testtarget makeOpts cflags opts} $T {}
if {$::PROGRESS_MSGS && !$::TRACE} {
set n [string length $title]
PUTS "starting: ${title} at [now]"
flush stdout
}
# Run the job.
#
set tm1 [clock seconds]
incr G(nJob)
set script [file normalize [info script]]
set fd [open "|[info nameofexecutable] $script --slave" r+]
fconfigure $fd -blocking 0
fileevent $fd readable [list slave_fileevent $fd $T $tm1]
puts $fd [list $::TRACE $::MSVC $::DRYRUN]
puts $fd [list {*}$T]
flush $fd
}
}
}
proc add_test_suite {listvar name testtarget config} {
upvar $listvar alltests
# Tcl variable $opts is used to build up the value used to set the
# OPTS Makefile variable. Variable $cflags holds the value for
# CFLAGS. The makefile will pass OPTS to both gcc and lemon, but
# CFLAGS is only passed to gcc.
#
set makeOpts ""
set cflags [expr {$::MSVC ? "-Zi" : "-g"}]
set opts ""
set title ${name}($testtarget)
@ -404,67 +572,74 @@ proc run_test_suite {name testtarget config} {
} elseif {[regexp {^[A-Z]+=} $arg]} {
lappend testtarget $arg
} elseif {[regexp {^--(enable|disable)-} $arg]} {
if {$::MSVC} {
if {$arg eq "--disable-amalgamation"} {
lappend makeOpts USE_AMALGAMATION=0
continue
}
if {$arg eq "--disable-shared"} {
lappend makeOpts USE_CRT_DLL=0 DYNAMIC_SHELL=0
continue
}
if {$arg eq "--enable-fts5"} {
lappend opts -DSQLITE_ENABLE_FTS5
continue
}
if {$arg eq "--enable-json1"} {
lappend opts -DSQLITE_ENABLE_JSON1
continue
}
if {$arg eq "--enable-shared"} {
lappend makeOpts USE_CRT_DLL=1 DYNAMIC_SHELL=1
continue
}
}
lappend configOpts $arg
} else {
if {$::MSVC} {
if {$arg eq "-g"} {
lappend cflags -Zi
continue
}
if {[regexp -- {^-O(\d+)$} $arg all level]} then {
lappend makeOpts OPTIMIZATIONS=$level
continue
}
}
lappend cflags $arg
}
}
set cflags [join $cflags " "]
set opts [join $opts " "]
append opts " -DSQLITE_NO_SYNC=1"
# Disable sync to make testing faster.
#
lappend opts -DSQLITE_NO_SYNC=1
# Some configurations already set HAVE_USLEEP; in that case, skip it.
#
if {![regexp { -DHAVE_USLEEP$} $opts]
&& ![regexp { -DHAVE_USLEEP[ =]+} $opts]} {
append opts " -DHAVE_USLEEP=1"
if {[lsearch -regexp $opts {^-DHAVE_USLEEP(?:=|$)}]==-1} {
lappend opts -DHAVE_USLEEP=1
}
# Add the define for this platform.
#
if {$::tcl_platform(platform)=="windows"} {
lappend opts -DSQLITE_OS_WIN=1
} else {
lappend opts -DSQLITE_OS_UNIX=1
}
# Set the sub-directory to use.
#
set dir [string tolower [string map {- _ " " _} $name]]
if {$::tcl_platform(platform)=="windows"} {
append opts " -DSQLITE_OS_WIN=1"
} else {
append opts " -DSQLITE_OS_UNIX=1"
}
# Join option lists into strings, using space as delimiter.
#
set makeOpts [join $makeOpts " "]
set cflags [join $cflags " "]
set opts [join $opts " "]
if {!$::TRACE} {
set n [string length $title]
PUTS -nonewline "${title}[string repeat . [expr {63-$n}]]"
flush stdout
}
set rc 0
set tm1 [clock seconds]
set origdir [pwd]
trace_cmd file mkdir $dir
trace_cmd cd $dir
set errmsg {}
catch {file delete core}
set rc [catch [configureCommand $configOpts]]
if {!$rc} {
set rc [catch [makeCommand $testtarget $cflags $opts]]
count_tests_and_errors test.log rc errmsg
}
trace_cmd cd $origdir
set tm2 [clock seconds]
if {!$::TRACE} {
set hours [expr {($tm2-$tm1)/3600}]
set minutes [expr {(($tm2-$tm1)/60)%60}]
set seconds [expr {($tm2-$tm1)%60}]
set tm [format (%02d:%02d:%02d) $hours $minutes $seconds]
if {$rc} {
PUTS " FAIL $tm"
incr ::NERR
} else {
PUTS " Ok $tm"
}
if {$errmsg!=""} {PUTS " $errmsg"}
}
lappend alltests [list \
$title $dir $configOpts $testtarget $makeOpts $cflags $opts]
}
# The following procedure returns the "configure" command to be exectued for
@ -484,15 +659,19 @@ proc configureCommand {opts} {
# The following procedure returns the "make" command to be executed for the
# specified targets, compiler flags, and options.
#
proc makeCommand { targets cflags opts } {
proc makeCommand { targets makeOpts cflags opts } {
set result [list trace_cmd exec]
if {$::MSVC} {
set nmakeDir [file nativename $::SRCDIR]
set nmakeFile [file join $nmakeDir Makefile.msc]
lappend result nmake /f $nmakeFile TOP=$nmakeDir clean
set nmakeFile [file nativename [file join $nmakeDir Makefile.msc]]
lappend result nmake /f $nmakeFile TOP=$nmakeDir
} else {
lappend result make clean
lappend result make
}
foreach makeOpt $makeOpts {
lappend result $makeOpt
}
lappend result clean
foreach target $targets {
lappend result $target
}
@ -507,9 +686,11 @@ proc trace_cmd {args} {
if {$::TRACE} {
PUTS $args
}
set res ""
if {!$::DRYRUN} {
uplevel 1 $args
set res [uplevel 1 $args]
}
return $res
}
@ -520,13 +701,14 @@ proc trace_cmd {args} {
#
proc process_options {argv} {
set ::SRCDIR [file normalize [file dirname [file dirname $::argv0]]]
set ::QUICK 0
set ::MSVC 0
set ::BUILDONLY 0
set ::DRYRUN 0
set ::EXEC exec
set ::TRACE 0
set ::WITHTCL {}
set ::QUICK 0
set ::MSVC 0
set ::BUILDONLY 0
set ::DRYRUN 0
set ::TRACE 0
set ::JOBS 1
set ::PROGRESS_MSGS 0
set ::WITHTCL {}
set config {}
set platform $::tcl_platform(os)-$::tcl_platform(machine)
@ -534,6 +716,11 @@ proc process_options {argv} {
set x [lindex $argv $i]
if {[regexp {^--[a-z]} $x]} {set x [string range $x 1 end]}
switch -glob -- $x {
-slave {
run_slave_test
exit
}
-srcdir {
incr i
set ::SRCDIR [file normalize [lindex $argv $i]]
@ -544,6 +731,15 @@ proc process_options {argv} {
set platform [lindex $argv $i]
}
-jobs {
incr i
set ::JOBS [lindex $argv $i]
}
-progress {
set ::PROGRESS_MSGS 1
}
-quick {
set ::QUICK 1
}
@ -597,11 +793,7 @@ proc process_options {argv} {
}
-g {
if {$::MSVC} {
lappend ::EXTRACONFIG -Zi
} else {
lappend ::EXTRACONFIG [lindex $argv $i]
}
lappend ::EXTRACONFIG [lindex $argv $i]
}
-with-tcl=* {
@ -640,11 +832,20 @@ proc process_options {argv} {
if {[llength $config]==1} {lappend config fulltest}
set ::CONFIGLIST $config
} else {
set ::CONFIGLIST $::Platforms($platform)
if {$::JOBS>1} {
set ::CONFIGLIST {}
foreach {target zConfig} [lreverse $::Platforms($platform)] {
append ::CONFIGLIST [format " %-25s %s\n" \
[list $zConfig] [list $target]]
}
} else {
set ::CONFIGLIST $::Platforms($platform)
}
}
PUTS "Running the following test configurations for $platform:"
PUTS " [string trim $::CONFIGLIST]"
PUTS -nonewline "Flags:"
if {$::PROGRESS_MSGS} {PUTS -nonewline " --progress"}
if {$::DRYRUN} {PUTS -nonewline " --dryrun"}
if {$::BUILDONLY} {PUTS -nonewline " --buildonly"}
if {$::MSVC} {PUTS -nonewline " --msvc"}
@ -652,6 +853,7 @@ proc process_options {argv} {
1 {PUTS -nonewline " --quick"}
2 {PUTS -nonewline " --veryquick"}
}
if {$::JOBS>1} {PUTS -nonewline " --jobs $::JOBS"}
PUTS ""
}
@ -683,13 +885,15 @@ proc main {argv} {
}
if {$::BUILDONLY} {
set target testfixture
if {$::MSVC} {append target .exe}
if {$::tcl_platform(platform)=="windows"} {
append target .exe
}
}
}
set config_options [concat $::Configs($zConfig) $::EXTRACONFIG]
incr NTEST
run_test_suite $zConfig $target $config_options
add_test_suite all $zConfig $target $config_options
# If the configuration included the SQLITE_DEBUG option, then remove
# it and run veryquick.test. If it did not include the SQLITE_DEBUG option
@ -703,16 +907,18 @@ proc main {argv} {
if {$debug_idx < 0} {
incr NTEST
append config_options " -DSQLITE_DEBUG=1"
run_test_suite "${zConfig}_debug" $xtarget $config_options
add_test_suite all "${zConfig}_debug" $xtarget $config_options
} else {
incr NTEST
regsub { *-DSQLITE_MEMDEBUG[^ ]* *} $config_options { } config_options
regsub { *-DSQLITE_DEBUG[^ ]* *} $config_options { } config_options
run_test_suite "${zConfig}_ndebug" $xtarget $config_options
add_test_suite all "${zConfig}_ndebug" $xtarget $config_options
}
}
}
run_all_test_suites $all
set elapsetime [expr {[clock seconds]-$STARTTIME}]
set hr [expr {$elapsetime/3600}]
set min [expr {($elapsetime/60)%60}]

View File

@ -412,22 +412,22 @@ ifcapable subquery {
count {
SELECT * FROM t1 WHERE w IN (-1,1,2,3) order by 1;
}
} {1 0 4 2 1 9 3 1 16 13}
} {1 0 4 2 1 9 3 1 16 12}
do_test where-5.3b {
count {
SELECT * FROM t1 WHERE w IN (3,-1,1,2) order by 1;
}
} {1 0 4 2 1 9 3 1 16 13}
} {1 0 4 2 1 9 3 1 16 12}
do_test where-5.3c {
count {
SELECT * FROM t1 WHERE w IN (3,2,-1,1,2) order by 1;
}
} {1 0 4 2 1 9 3 1 16 13}
} {1 0 4 2 1 9 3 1 16 12}
do_test where-5.3d {
count {
SELECT * FROM t1 WHERE w IN (-1,1,2,3) order by 1 DESC;
}
} {3 1 16 2 1 9 1 0 4 12}
} {3 1 16 2 1 9 1 0 4 11}
do_test where-5.4 {
count {
SELECT * FROM t1 WHERE w+0 IN (-1,1,2,3) order by 1;
@ -465,7 +465,7 @@ ifcapable subquery {
count {
SELECT * FROM t1 WHERE x IN (1,7) ORDER BY 1;
}
} {2 1 9 3 1 16 7}
} {2 1 9 3 1 16 6}
do_test where-5.10 {
count {
SELECT * FROM t1 WHERE x+0 IN (1,7) ORDER BY 1;
@ -485,17 +485,17 @@ ifcapable subquery {
count {
SELECT * FROM t1 WHERE x IN (1,7) AND y NOT IN (6400,8100) ORDER BY 1;
}
} {2 1 9 3 1 16 7}
} {2 1 9 3 1 16 6}
do_test where-5.14 {
count {
SELECT * FROM t1 WHERE x IN (1,7) AND y IN (9,10) ORDER BY 1;
}
} {2 1 9 8}
} {2 1 9 5}
do_test where-5.15 {
count {
SELECT * FROM t1 WHERE x IN (1,7) AND y IN (9,16) ORDER BY 1;
}
} {2 1 9 3 1 16 11}
} {2 1 9 3 1 16 9}
do_test where-5.100 {
db eval {
SELECT w, x, y FROM t1 WHERE x IN (1,5) AND y IN (9,8,3025,1000,3969)

View File

@ -91,7 +91,7 @@ do_test where4-1.10 {
} {6 2}
do_test where4-1.11 {
count {SELECT rowid FROM t1 WHERE w=x'78' AND x IS NULL AND y=123}
} {1}
} {0}
do_test where4-1.12 {
count {SELECT rowid FROM t1 WHERE w=x'78' AND x IS NULL AND y=x'7A'}
} {6 2}