Index: Makefile.msc
==================================================================
--- Makefile.msc
+++ Makefile.msc
@@ -74,11 +74,11 @@
# cross-compiling, it is suggested that this macro be modified via the command
# line (since nmake itself does not provide a built-in method to guess it).
# For example, to use the x86 compiler when cross-compiling for x64, a command
# line similar to the following could be used (all on one line):
#
-# nmake /f Makefile.msc
+# nmake /f Makefile.msc sqlite3.dll
# "NCC=""%VCINSTALLDIR%\bin\cl.exe"""
# USE_NATIVE_LIBPATHS=1
#
!IFDEF NCC
NCC = $(NCC:\\=\)
Index: ext/fts3/fts3.c
==================================================================
--- ext/fts3/fts3.c
+++ ext/fts3/fts3.c
@@ -4434,10 +4434,11 @@
/* Allocate a MultiSegReader for each token in the expression. */
fts3EvalAllocateReaders(pCsr, pCsr->pExpr, &nToken, &nOr, &rc);
/* Determine which, if any, tokens in the expression should be deferred. */
+#ifndef SQLITE_DISABLE_FTS4_DEFERRED
if( rc==SQLITE_OK && nToken>1 && pTab->bFts4 ){
Fts3TokenAndCost *aTC;
Fts3Expr **apOr;
aTC = (Fts3TokenAndCost *)sqlite3_malloc(
sizeof(Fts3TokenAndCost) * nToken
@@ -4464,10 +4465,11 @@
}
sqlite3_free(aTC);
}
}
+#endif
fts3EvalStartReaders(pCsr, pCsr->pExpr, 1, &rc);
return rc;
}
@@ -4847,10 +4849,11 @@
&& !fts3EvalTestExpr(pCsr, pExpr->pRight, pRc)
);
break;
default: {
+#ifndef SQLITE_DISABLE_FTS4_DEFERRED
if( pCsr->pDeferred
&& (pExpr->iDocid==pCsr->iPrevId || pExpr->bDeferred)
){
Fts3Phrase *pPhrase = pExpr->pPhrase;
assert( pExpr->bDeferred || pPhrase->doclist.bFreeList==0 );
@@ -4858,11 +4861,13 @@
fts3EvalInvalidatePoslist(pPhrase);
}
*pRc = fts3EvalDeferredPhrase(pCsr, pPhrase);
bHit = (pPhrase->doclist.pList!=0);
pExpr->iDocid = pCsr->iPrevId;
- }else{
+ }else
+#endif
+ {
bHit = (pExpr->bEof==0 && pExpr->iDocid==pCsr->iPrevId);
}
break;
}
}
Index: ext/fts3/fts3Int.h
==================================================================
--- ext/fts3/fts3Int.h
+++ ext/fts3/fts3Int.h
@@ -425,14 +425,24 @@
int sqlite3Fts3ReadBlock(Fts3Table*, sqlite3_int64, char **, int*, int*);
int sqlite3Fts3SelectDoctotal(Fts3Table *, sqlite3_stmt **);
int sqlite3Fts3SelectDocsize(Fts3Table *, sqlite3_int64, sqlite3_stmt **);
+#ifndef SQLITE_DISABLE_FTS4_DEFERRED
void sqlite3Fts3FreeDeferredTokens(Fts3Cursor *);
int sqlite3Fts3DeferToken(Fts3Cursor *, Fts3PhraseToken *, int);
int sqlite3Fts3CacheDeferredDoclists(Fts3Cursor *);
void sqlite3Fts3FreeDeferredDoclists(Fts3Cursor *);
+int sqlite3Fts3DeferredTokenList(Fts3DeferredToken *, char **, int *);
+#else
+# define sqlite3Fts3FreeDeferredTokens(x)
+# define sqlite3Fts3DeferToken(x,y,z) SQLITE_OK
+# define sqlite3Fts3CacheDeferredDoclists(x) SQLITE_OK
+# define sqlite3Fts3FreeDeferredDoclists(x)
+# define sqlite3Fts3DeferredTokenList(x,y,z) SQLITE_OK
+#endif
+
void sqlite3Fts3SegmentsClose(Fts3Table *);
int sqlite3Fts3MaxLevel(Fts3Table *, int *);
/* Special values interpreted by sqlite3SegReaderCursor() */
#define FTS3_SEGCURSOR_PENDING -1
@@ -537,16 +547,14 @@
Fts3Table *, Fts3MultiSegReader *, sqlite3_int64 *, char **, int *);
int sqlite3Fts3EvalPhrasePoslist(Fts3Cursor *, Fts3Expr *, int iCol, char **);
int sqlite3Fts3MsrOvfl(Fts3Cursor *, Fts3MultiSegReader *, int *);
int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr);
-int sqlite3Fts3DeferredTokenList(Fts3DeferredToken *, char **, int *);
-
/* fts3_unicode2.c (functions generated by parsing unicode text files) */
#ifdef SQLITE_ENABLE_FTS4_UNICODE61
int sqlite3FtsUnicodeFold(int, int);
int sqlite3FtsUnicodeIsalnum(int);
int sqlite3FtsUnicodeIsdiacritic(int);
#endif
#endif /* !SQLITE_CORE || SQLITE_ENABLE_FTS3 */
#endif /* _FTSINT_H */
Index: ext/fts3/fts3_write.c
==================================================================
--- ext/fts3/fts3_write.c
+++ ext/fts3/fts3_write.c
@@ -5044,10 +5044,11 @@
}
return rc;
}
+#ifndef SQLITE_DISABLE_FTS4_DEFERRED
/*
** Delete all cached deferred doclists. Deferred doclists are cached
** (allocated) by the sqlite3Fts3CacheDeferredDoclists() function.
*/
void sqlite3Fts3FreeDeferredDoclists(Fts3Cursor *pCsr){
@@ -5181,10 +5182,11 @@
assert( pToken->pDeferred==0 );
pToken->pDeferred = pDeferred;
return SQLITE_OK;
}
+#endif
/*
** SQLite value pRowid contains the rowid of a row that may or may not be
** present in the FTS3 table. If it is, delete it and adjust the contents
** of subsiduary data structures accordingly.
Index: src/btree.c
==================================================================
--- src/btree.c
+++ src/btree.c
@@ -1459,11 +1459,11 @@
}
next = get2byte(&data[pc]);
size = get2byte(&data[pc+2]);
if( (next>0 && next<=pc+size+3) || pc+size>usableSize ){
/* Free blocks must be in ascending order. And the last byte of
- ** the free-block must lie on the database page. */
+ ** the free-block must lie on the database page. */
return SQLITE_CORRUPT_BKPT;
}
nFree = nFree + size;
pc = next;
}
@@ -2633,11 +2633,11 @@
if( rc==SQLITE_OK ){
if( p->inTrans==TRANS_NONE ){
pBt->nTransaction++;
#ifndef SQLITE_OMIT_SHARED_CACHE
if( p->sharable ){
- assert( p->lock.pBtree==p && p->lock.iTable==1 );
+ assert( p->lock.pBtree==p && p->lock.iTable==1 );
p->lock.eLock = READ_LOCK;
p->lock.pNext = pBt->pLock;
pBt->pLock = &p->lock;
}
#endif
Index: src/build.c
==================================================================
--- src/build.c
+++ src/build.c
@@ -532,11 +532,11 @@
pNext = pIndex->pNext;
assert( pIndex->pSchema==pTable->pSchema );
if( !db || db->pnBytesFreed==0 ){
char *zName = pIndex->zName;
TESTONLY ( Index *pOld = ) sqlite3HashInsert(
- &pIndex->pSchema->idxHash, zName, sqlite3Strlen30(zName), 0
+ &pIndex->pSchema->idxHash, zName, sqlite3Strlen30(zName), 0
);
assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) );
assert( pOld==pIndex || pOld==0 );
}
freeIndex(db, pIndex);
Index: src/mem1.c
==================================================================
--- src/mem1.c
+++ src/mem1.c
@@ -229,18 +229,18 @@
/* defer MT decisions to system malloc */
_sqliteZone_ = malloc_default_zone();
}else{
/* only 1 core, use our own zone to contention over global locks,
** e.g. we have our own dedicated locks */
- bool success;
+ bool success;
malloc_zone_t* newzone = malloc_create_zone(4096, 0);
malloc_set_zone_name(newzone, "Sqlite_Heap");
do{
success = OSAtomicCompareAndSwapPtrBarrier(NULL, newzone,
(void * volatile *)&_sqliteZone_);
}while(!_sqliteZone_);
- if( !success ){
+ if( !success ){
/* somebody registered a zone first */
malloc_destroy_zone(newzone);
}
}
#endif
Index: src/os_unix.c
==================================================================
--- src/os_unix.c
+++ src/os_unix.c
@@ -713,13 +713,13 @@
return SQLITE_BUSY;
case EACCES:
/* EACCES is like EAGAIN during locking operations, but not any other time*/
if( (sqliteIOErr == SQLITE_IOERR_LOCK) ||
- (sqliteIOErr == SQLITE_IOERR_UNLOCK) ||
- (sqliteIOErr == SQLITE_IOERR_RDLOCK) ||
- (sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) ){
+ (sqliteIOErr == SQLITE_IOERR_UNLOCK) ||
+ (sqliteIOErr == SQLITE_IOERR_RDLOCK) ||
+ (sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) ){
return SQLITE_BUSY;
}
/* else fall through */
case EPERM:
return SQLITE_PERM;
@@ -1762,11 +1762,11 @@
lock.l_start = lock.l_len = 0L;
if( unixFileLock(pFile, &lock)==0 ){
pInode->eFileLock = NO_LOCK;
}else{
rc = SQLITE_IOERR_UNLOCK;
- pFile->lastErrno = errno;
+ pFile->lastErrno = errno;
pInode->eFileLock = NO_LOCK;
pFile->eFileLock = NO_LOCK;
}
}
@@ -1778,11 +1778,11 @@
assert( pInode->nLock>=0 );
if( pInode->nLock==0 ){
closePendingFds(pFile);
}
}
-
+
end_unlock:
unixLeaveMutex();
if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock;
return rc;
}
@@ -2045,11 +2045,11 @@
char *zLockFile = (char *)pFile->lockingContext;
int rc;
assert( pFile );
OSTRACE(("UNLOCK %d %d was %d pid=%d (dotlock)\n", pFile->h, eFileLock,
- pFile->eFileLock, getpid()));
+ pFile->eFileLock, getpid()));
assert( eFileLock<=SHARED_LOCK );
/* no-op if possible */
if( pFile->eFileLock==eFileLock ){
return SQLITE_OK;
@@ -2432,11 +2432,11 @@
sem_t *pSem = pFile->pInode->pSem;
assert( pFile );
assert( pSem );
OSTRACE(("UNLOCK %d %d was %d pid=%d (sem)\n", pFile->h, eFileLock,
- pFile->eFileLock, getpid()));
+ pFile->eFileLock, getpid()));
assert( eFileLock<=SHARED_LOCK );
/* no-op if possible */
if( pFile->eFileLock==eFileLock ){
return SQLITE_OK;
@@ -3022,11 +3022,11 @@
SimulateIOError( newOffset-- );
if( newOffset!=offset ){
if( newOffset == -1 ){
((unixFile*)id)->lastErrno = errno;
}else{
- ((unixFile*)id)->lastErrno = 0;
+ ((unixFile*)id)->lastErrno = 0;
}
return -1;
}
got = osRead(id->h, pBuf, cnt);
#endif
@@ -3110,11 +3110,11 @@
SimulateIOError( newOffset-- );
if( newOffset!=offset ){
if( newOffset == -1 ){
((unixFile*)id)->lastErrno = errno;
}else{
- ((unixFile*)id)->lastErrno = 0;
+ ((unixFile*)id)->lastErrno = 0;
}
return -1;
}
got = osWrite(id->h, pBuf, cnt);
}while( got<0 && errno==EINTR );
@@ -5624,11 +5624,11 @@
** with _IOWR('z', 23, struct ByteRangeLockPB2) to track the same 5 states.
** To simulate a F_RDLCK on the shared range, on AFP a randomly selected
** address in the shared range is taken for a SHARED lock, the entire
** shared range is taken for an EXCLUSIVE lock):
**
-** PENDING_BYTE 0x40000000
+** PENDING_BYTE 0x40000000
** RESERVED_BYTE 0x40000001
** SHARED_RANGE 0x40000002 -> 0x40000200
**
** This works well on the local file system, but shows a nearly 100x
** slowdown in read performance on AFP because the AFP client disables
Index: src/os_win.c
==================================================================
--- src/os_win.c
+++ src/os_win.c
@@ -44,13 +44,15 @@
#ifndef FILE_ATTRIBUTE_MASK
# define FILE_ATTRIBUTE_MASK (0x0003FFF7)
#endif
+#ifndef SQLITE_OMIT_WAL
/* Forward references */
typedef struct winShm winShm; /* A connection to shared-memory */
typedef struct winShmNode winShmNode; /* A region of shared-memory */
+#endif
/*
** WinCE lacks native support for file locking so we have to fake it
** with some code of our own.
*/
@@ -74,11 +76,13 @@
HANDLE h; /* Handle for accessing the file */
u8 locktype; /* Type of lock currently held on this file */
short sharedLockByte; /* Randomly chosen byte used as a shared lock */
u8 ctrlFlags; /* Flags. See WINFILE_* below */
DWORD lastErrno; /* The Windows errno from the last I/O error */
+#ifndef SQLITE_OMIT_WAL
winShm *pShm; /* Instance of shared memory on this file */
+#endif
const char *zPath; /* Full pathname of this file */
int szChunk; /* Chunk size configured by FCNTL_CHUNK_SIZE */
#if SQLITE_OS_WINCE
LPWSTR zDeleteOnClose; /* Name of file to delete when closing */
HANDLE hMutex; /* Mutex used to control access to shared lock */
@@ -1935,11 +1939,13 @@
static int winClose(sqlite3_file *id){
int rc, cnt = 0;
winFile *pFile = (winFile*)id;
assert( id!=0 );
+#ifndef SQLITE_OMIT_WAL
assert( pFile->pShm==0 );
+#endif
OSTRACE(("CLOSE %d\n", pFile->h));
do{
rc = osCloseHandle(pFile->h);
/* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */
}while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (sqlite3_win32_sleep(100), 1) );
@@ -3685,11 +3691,13 @@
memset(pFile, 0, sizeof(*pFile));
pFile->pMethod = &winIoMethod;
pFile->h = h;
pFile->lastErrno = NO_ERROR;
pFile->pVfs = pVfs;
+#ifndef SQLITE_OMIT_WAL
pFile->pShm = 0;
+#endif
pFile->zPath = zName;
if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){
pFile->ctrlFlags |= WINFILE_PSOW;
}
Index: src/sqlite.h.in
==================================================================
--- src/sqlite.h.in
+++ src/sqlite.h.in
@@ -3152,12 +3152,15 @@
** ^The third argument is the value to bind to the parameter.
**
** ^(In those routines that have a fourth argument, its value is the
** number of bytes in the parameter. To be clear: the value is the
** number of bytes in the value, not the number of characters.)^
-** ^If the fourth parameter is negative, the length of the string is
+** ^If the fourth parameter to sqlite3_bind_text() or sqlite3_bind_text16()
+** is negative, then the length of the string is
** the number of bytes up to the first zero terminator.
+** If the fourth parameter to sqlite3_bind_blob() is negative, then
+** the behavior is undefined.
** If a non-negative fourth parameter is provided to sqlite3_bind_text()
** or sqlite3_bind_text16() then that parameter must be the byte offset
** where the NUL terminator would occur assuming the string were NUL
** terminated. If any NUL characters occur at byte offsets less than
** the value of the fourth parameter then the resulting string value will
Index: src/test1.c
==================================================================
--- src/test1.c
+++ src/test1.c
@@ -5926,11 +5926,11 @@
){
int i;
sqlite3 *db;
const char *zOpt;
int onoff;
- int mask;
+ int mask = 0;
static const struct {
const char *zOptName;
int mask;
} aOpt[] = {
{ "all", SQLITE_OptMask },
Index: src/test_config.c
==================================================================
--- src/test_config.c
+++ src/test_config.c
@@ -316,10 +316,16 @@
#if defined(SQLITE_ENABLE_FTS3) && defined(SQLITE_ENABLE_FTS4_UNICODE61)
Tcl_SetVar2(interp, "sqlite_options", "fts3_unicode", "1", TCL_GLOBAL_ONLY);
#else
Tcl_SetVar2(interp, "sqlite_options", "fts3_unicode", "0", TCL_GLOBAL_ONLY);
#endif
+
+#ifdef SQLITE_DISABLE_FTS4_DEFERRED
+ Tcl_SetVar2(interp, "sqlite_options", "fts4_deferred", "0", TCL_GLOBAL_ONLY);
+#else
+ Tcl_SetVar2(interp, "sqlite_options", "fts4_deferred", "1", TCL_GLOBAL_ONLY);
+#endif
#ifdef SQLITE_OMIT_GET_TABLE
Tcl_SetVar2(interp, "sqlite_options", "gettable", "0", TCL_GLOBAL_ONLY);
#else
Tcl_SetVar2(interp, "sqlite_options", "gettable", "1", TCL_GLOBAL_ONLY);
Index: src/test_multiplex.c
==================================================================
--- src/test_multiplex.c
+++ src/test_multiplex.c
@@ -500,15 +500,15 @@
int flags, /* Flags to control the opening */
int *pOutFlags /* Flags showing results of opening */
){
int rc = SQLITE_OK; /* Result code */
multiplexConn *pMultiplexOpen; /* The new multiplex file descriptor */
- multiplexGroup *pGroup; /* Corresponding multiplexGroup object */
+ multiplexGroup *pGroup = 0; /* Corresponding multiplexGroup object */
sqlite3_file *pSubOpen = 0; /* Real file descriptor */
sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs; /* Real VFS */
- int nName;
- int sz;
+ int nName = 0;
+ int sz = 0;
char *zToFree = 0;
UNUSED_PARAMETER(pVfs);
memset(pConn, 0, pVfs->szOsFile);
assert( zName || (flags & SQLITE_OPEN_DELETEONCLOSE) );
Index: src/test_spellfix.c
==================================================================
--- src/test_spellfix.c
+++ src/test_spellfix.c
@@ -657,11 +657,11 @@
){
sqlite3_stmt *pStmt;
int rc, rc2;
char *zSql;
int iLangPrev = -9999;
- EditDist3Lang *pLang;
+ EditDist3Lang *pLang = 0;
zSql = sqlite3_mprintf("SELECT iLang, cFrom, cTo, iCost"
" FROM \"%w\" WHERE iLang>=0 ORDER BY iLang", zTable);
if( zSql==0 ) return SQLITE_NOMEM;
rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
@@ -678,11 +678,11 @@
assert( zFrom!=0 || nFrom==0 );
assert( zTo!=0 || nTo==0 );
if( nFrom>100 || nTo>100 ) continue;
if( iCost<0 ) continue;
- if( iLang!=iLangPrev ){
+ if( pLang==0 || iLang!=iLangPrev ){
EditDist3Lang *pNew;
pNew = sqlite3_realloc(p->a, (p->nLang+1)*sizeof(p->a[0]));
if( pNew==0 ){ rc = SQLITE_NOMEM; break; }
p->a = pNew;
pLang = &p->a[p->nLang];
@@ -861,13 +861,13 @@
unsigned int *m,
int i,
int j,
int iCost
){
- int b;
+ assert( iCost>=0 );
if( iCost<10000 ){
- b = m[j] + iCost;
+ unsigned int b = m[j] + iCost;
if( biRow < pCur->nRow ){
if( pCur->pFullScan ){
- int rc = sqlite3_step(pCur->pFullScan);
+ rc = sqlite3_step(pCur->pFullScan);
if( rc!=SQLITE_ROW ) pCur->iRow = pCur->nRow;
+ if( rc==SQLITE_ROW || rc==SQLITE_DONE ) rc = SQLITE_OK;
}else{
pCur->iRow++;
}
}
- return SQLITE_OK;
+ return rc;
}
/*
** Return TRUE if we are at the end-of-file
*/
@@ -2771,29 +2773,39 @@
/*
** Register the various functions and the virtual table.
*/
static int spellfix1Register(sqlite3 *db){
- int nErr = 0;
+ int rc = SQLITE_OK;
int i;
- nErr += sqlite3_create_function(db, "spellfix1_translit", 1, SQLITE_UTF8, 0,
+ rc = sqlite3_create_function(db, "spellfix1_translit", 1, SQLITE_UTF8, 0,
transliterateSqlFunc, 0, 0);
- nErr += sqlite3_create_function(db, "spellfix1_editdist", 2, SQLITE_UTF8, 0,
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_create_function(db, "spellfix1_editdist", 2, SQLITE_UTF8, 0,
editdistSqlFunc, 0, 0);
- nErr += sqlite3_create_function(db, "spellfix1_phonehash", 1, SQLITE_UTF8, 0,
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_create_function(db, "spellfix1_phonehash", 1, SQLITE_UTF8, 0,
phoneticHashSqlFunc, 0, 0);
- nErr += sqlite3_create_function(db, "spellfix1_scriptcode", 1, SQLITE_UTF8, 0,
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_create_function(db, "spellfix1_scriptcode", 1, SQLITE_UTF8, 0,
scriptCodeSqlFunc, 0, 0);
- nErr += sqlite3_create_module(db, "spellfix1", &spellfix1Module, 0);
- nErr += editDist3Install(db);
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_create_module(db, "spellfix1", &spellfix1Module, 0);
+ }
+ if( rc==SQLITE_OK ){
+ rc = editDist3Install(db);
+ }
/* Verify sanity of the translit[] table */
for(i=0; i0}
+ ifcapable fts4_deferred {
+ expr {[fts3_zero_long_segments t1 $limit]>0}
+ } else {
+ expr 1
+ }
} {1}
do_fts3query_test 4.$tn.3.1 -deferred five t1 {one AND five}
do_fts3query_test 4.$tn.3.2 -deferred five t1 {one NEAR five}
do_fts3query_test 4.$tn.3.3 -deferred five t1 {one NEAR/1 five}
Index: test/fts3defer.test
==================================================================
--- test/fts3defer.test
+++ test/fts3defer.test
@@ -11,11 +11,11 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/malloc_common.tcl
-ifcapable !fts3 {
+ifcapable !fts3||!fts4_deferred {
finish_test
return
}
set sqlite_fts3_enable_parentheses 1
Index: test/fts3defer2.test
==================================================================
--- test/fts3defer2.test
+++ test/fts3defer2.test
@@ -11,11 +11,14 @@
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/malloc_common.tcl
-ifcapable !fts3 { finish_test ; return }
+ifcapable !fts3||!fts4_deferred {
+ finish_test
+ return
+}
set testprefix fts3defer2
proc mit {blob} {
set scan(littleEndian) i*
Index: test/fts3matchinfo.test
==================================================================
--- test/fts3matchinfo.test
+++ test/fts3matchinfo.test
@@ -273,15 +273,18 @@
do_matchinfo_test 4.3.3 t5 {t5 MATCH 'a b a'} { s {3} }
do_matchinfo_test 4.3.4 t5 {t5 MATCH 'a a a'} { s {3 1} }
do_matchinfo_test 4.3.5 t5 {t5 MATCH '"a b" "a b"'} { s {2} }
do_matchinfo_test 4.3.6 t5 {t5 MATCH 'a OR b'} { s {1 2 1 1} }
-do_execsql_test 4.4.0 {
- INSERT INTO t5(t5) VALUES('optimize');
- UPDATE t5_segments
- SET block = zeroblob(length(block))
- WHERE length(block)>10000;
+do_execsql_test 4.4.0.1 { INSERT INTO t5(t5) VALUES('optimize') }
+
+ifcapable fts4_deferred {
+ do_execsql_test 4.4.0.2 {
+ UPDATE t5_segments
+ SET block = zeroblob(length(block))
+ WHERE length(block)>10000;
+ }
}
do_matchinfo_test 4.4.2 t5 {t5 MATCH 'a b'} { s {2} }
do_matchinfo_test 4.4.1 t5 {t5 MATCH 'a a'} { s {2 1} }
do_matchinfo_test 4.4.2 t5 {t5 MATCH 'a b'} { s {2} }
Index: test/fts4aa.test
==================================================================
--- test/fts4aa.test
+++ test/fts4aa.test
@@ -1653,18 +1653,20 @@
do_test fts4aa-1.8 {
db eval {
SELECT docid FROM t1_docsize EXCEPT SELECT docid FROM t1
}
} {}
-do_test fts4aa-1.9 {
- # Note: Token 'in' is being deferred in the following query.
- db eval {
- SELECT docid, mit(matchinfo(t1, 'pcxnal')) FROM t1
- WHERE t1 MATCH 'joseph died in egypt'
- ORDER BY docid;
- }
-} {1050026 {4 1 1 1 1 1 1 1 2 1 1 1 1 1 1 23 23}}
+ifcapable fts4_deferred {
+ do_test fts4aa-1.9 {
+ # Note: Token 'in' is being deferred in the following query.
+ db eval {
+ SELECT docid, mit(matchinfo(t1, 'pcxnal')) FROM t1
+ WHERE t1 MATCH 'joseph died in egypt'
+ ORDER BY docid;
+ }
+ } {1050026 {4 1 1 1 1 1 1 1 2 1 1 1 1 1 1 23 23}}
+}
# Should get the same search results from FTS3
#
do_test fts4aa-2.0 {
db eval {
Index: test/releasetest.tcl
==================================================================
--- test/releasetest.tcl
+++ test/releasetest.tcl
@@ -149,10 +149,19 @@
}
"Extra-Robustness" {
-DSQLITE_ENABLE_OVERSIZE_CELL_CHECK=1
-DSQLITE_MAX_ATTACHED=62
}
+ "Devkit" {
+ -DSQLITE_DEFAULT_FILE_FORMAT=4
+ -DSQLITE_MAX_ATTACHED=30
+ -DSQLITE_ENABLE_COLUMN_METADATA
+ -DSQLITE_ENABLE_FTS4
+ -DSQLITE_ENABLE_FTS4_PARENTHESIS
+ -DSQLITE_DISABLE_FTS4_DEFERRED
+ -DSQLITE_ENABLE_RTREE
+ }
}
array set ::Platforms {
Linux-x86_64 {
"Debug-One" "checksymbols test"
@@ -164,10 +173,11 @@
"Ftrapv" test
"Default" "threadtest test"
"Device-One" fulltest
}
Linux-i686 {
+ "Devkit" test
"Unlock-Notify" "QUICKTEST_INCLUDE=notify2.test test"
"Device-One" test
"Device-Two" test
"Default" "threadtest fulltest"
}
ADDED tool/checkSpacing.c
Index: tool/checkSpacing.c
==================================================================
--- /dev/null
+++ tool/checkSpacing.c
@@ -0,0 +1,84 @@
+/*
+** This program checks for formatting problems in source code:
+**
+** * Any use of tab characters
+** * White space at the end of a line
+** * Blank lines at the end of a file
+**
+** Any violations are reported.
+*/
+#include
+#include
+#include
+
+#define CR_OK 0x001
+#define WSEOL_OK 0x002
+
+static void checkSpacing(const char *zFile, unsigned flags){
+ FILE *in = fopen(zFile, "rb");
+ int i;
+ int seenSpace;
+ int seenTab;
+ int ln = 0;
+ int lastNonspace = 0;
+ char zLine[2000];
+ if( in==0 ){
+ printf("cannot open %s\n", zFile);
+ return;
+ }
+ while( fgets(zLine, sizeof(zLine), in) ){
+ seenSpace = 0;
+ seenTab = 0;
+ ln++;
+ for(i=0; zLine[i]; i++){
+ if( zLine[i]=='\t' && seenTab==0 ){
+ printf("%s:%d: tab (\\t) character\n", zFile, ln);
+ seenTab = 1;
+ }else if( zLine[i]=='\r' ){
+ if( (flags & CR_OK)==0 ){
+ printf("%s:%d: carriage-return (\\r) character\n", zFile, ln);
+ }
+ }else if( zLine[i]==' ' ){
+ seenSpace = 1;
+ }else if( zLine[i]!='\n' ){
+ lastNonspace = ln;
+ seenSpace = 0;
+ }
+ }
+ if( seenSpace && (flags & WSEOL_OK)==0 ){
+ printf("%s:%d: whitespace at end-of-line\n", zFile, ln);
+ }
+ }
+ fclose(in);
+ if( lastNonspace
#include
#ifndef __WIN32__
# if defined(_WIN32) || defined(WIN32)
-# define __WIN32__
+# define __WIN32__
# endif
#endif
#ifdef __WIN32__
#ifdef __cplusplus
@@ -651,11 +651,11 @@
break;
}
}
}else if( sp->prec>=0 ){
rp->precsym = rp->rhs[i];
- }
+ }
}
}
}
return;
}
@@ -709,16 +709,16 @@
}else if( s2->type==MULTITERMINAL ){
for(j=0; jnsubsym; j++){
progress += SetAdd(s1->firstset,s2->subsym[j]->index);
}
break;
- }else if( s1==s2 ){
+ }else if( s1==s2 ){
if( s1->lambda==LEMON_FALSE ) break;
- }else{
+ }else{
progress += SetUnion(s1->firstset,s2->firstset);
if( s2->lambda==LEMON_FALSE ) break;
- }
+ }
}
}
}while( progress );
return;
}
@@ -957,12 +957,12 @@
for(plp=cfp->fplp; plp; plp=plp->next){
change = SetUnion(plp->cfp->fws,cfp->fws);
if( change ){
plp->cfp->status = INCOMPLETE;
progress = 1;
- }
- }
+ }
+ }
cfp->status = COMPLETE;
}
}
}while( progress );
}
@@ -991,11 +991,11 @@
if( SetFind(cfp->fws,j) ){
/* Add a reduce action to the state "stp" which will reduce by the
** rule "cfp->rp" if the lookahead symbol is "lemp->symbols[j]" */
Action_add(&stp->ap,REDUCE,lemp->symbols[j],(char *)cfp->rp);
}
- }
+ }
}
}
}
/* Add the accepting token */
@@ -1260,15 +1260,15 @@
int k;
for(k=0; knsubsym; k++){
SetAdd(newcfp->fws, xsp->subsym[k]->index);
}
break;
- }else{
+ }else{
SetUnion(newcfp->fws,xsp->firstset);
if( xsp->lambda==LEMON_FALSE ) break;
- }
- }
+ }
+ }
if( i==rp->nrhs ) Plink_add(&cfp->fplp,newcfp);
}
}
}
return;
@@ -1994,19 +1994,19 @@
if( psp->prevrule==0 ){
ErrorMsg(psp->filename,psp->tokenlineno,
"There is no prior rule upon which to attach the code \
fragment which begins on this line.");
psp->errorcnt++;
- }else if( psp->prevrule->code!=0 ){
+ }else if( psp->prevrule->code!=0 ){
ErrorMsg(psp->filename,psp->tokenlineno,
"Code fragment beginning on this line is not the first \
to follow the previous rule.");
psp->errorcnt++;
}else{
psp->prevrule->line = psp->tokenlineno;
psp->prevrule->code = &x[1];
- }
+ }
}else if( x[0]=='[' ){
psp->state = PRECEDENCE_MARK_1;
}else{
ErrorMsg(psp->filename,psp->tokenlineno,
"Token \"%s\" should be either \"%%\" or a nonterminal name.",
@@ -2095,19 +2095,19 @@
if( rp==0 ){
ErrorMsg(psp->filename,psp->tokenlineno,
"Can't allocate enough memory for this rule.");
psp->errorcnt++;
psp->prevrule = 0;
- }else{
+ }else{
int i;
rp->ruleline = psp->tokenlineno;
rp->rhs = (struct symbol**)&rp[1];
rp->rhsalias = (const char**)&(rp->rhs[psp->nrhs]);
for(i=0; inrhs; i++){
rp->rhs[i] = psp->rhs[i];
rp->rhsalias[i] = psp->alias[i];
- }
+ }
rp->lhs = psp->lhs;
rp->lhsalias = psp->lhsalias;
rp->nrhs = psp->nrhs;
rp->code = 0;
rp->precsym = 0;
@@ -2115,29 +2115,29 @@
rp->nextlhs = rp->lhs->rule;
rp->lhs->rule = rp;
rp->next = 0;
if( psp->firstrule==0 ){
psp->firstrule = psp->lastrule = rp;
- }else{
+ }else{
psp->lastrule->next = rp;
psp->lastrule = rp;
- }
+ }
psp->prevrule = rp;
- }
+ }
psp->state = WAITING_FOR_DECL_OR_RULE;
}else if( isalpha(x[0]) ){
if( psp->nrhs>=MAXRHS ){
ErrorMsg(psp->filename,psp->tokenlineno,
"Too many symbols on RHS of rule beginning at \"%s\".",
x);
psp->errorcnt++;
psp->state = RESYNC_AFTER_RULE_ERROR;
- }else{
+ }else{
psp->rhs[psp->nrhs] = Symbol_new(x);
psp->alias[psp->nrhs] = 0;
psp->nrhs++;
- }
+ }
}else if( (x[0]=='|' || x[0]=='/') && psp->nrhs>0 ){
struct symbol *msp = psp->rhs[psp->nrhs-1];
if( msp->type!=MULTITERMINAL ){
struct symbol *origsp = msp;
msp = (struct symbol *) calloc(1,sizeof(*msp));
@@ -2197,28 +2197,28 @@
psp->insertLineMacro = 1;
psp->state = WAITING_FOR_DECL_ARG;
if( strcmp(x,"name")==0 ){
psp->declargslot = &(psp->gp->name);
psp->insertLineMacro = 0;
- }else if( strcmp(x,"include")==0 ){
+ }else if( strcmp(x,"include")==0 ){
psp->declargslot = &(psp->gp->include);
- }else if( strcmp(x,"code")==0 ){
+ }else if( strcmp(x,"code")==0 ){
psp->declargslot = &(psp->gp->extracode);
- }else if( strcmp(x,"token_destructor")==0 ){
+ }else if( strcmp(x,"token_destructor")==0 ){
psp->declargslot = &psp->gp->tokendest;
- }else if( strcmp(x,"default_destructor")==0 ){
+ }else if( strcmp(x,"default_destructor")==0 ){
psp->declargslot = &psp->gp->vardest;
- }else if( strcmp(x,"token_prefix")==0 ){
+ }else if( strcmp(x,"token_prefix")==0 ){
psp->declargslot = &psp->gp->tokenprefix;
psp->insertLineMacro = 0;
- }else if( strcmp(x,"syntax_error")==0 ){
+ }else if( strcmp(x,"syntax_error")==0 ){
psp->declargslot = &(psp->gp->error);
- }else if( strcmp(x,"parse_accept")==0 ){
+ }else if( strcmp(x,"parse_accept")==0 ){
psp->declargslot = &(psp->gp->accept);
- }else if( strcmp(x,"parse_failure")==0 ){
+ }else if( strcmp(x,"parse_failure")==0 ){
psp->declargslot = &(psp->gp->failure);
- }else if( strcmp(x,"stack_overflow")==0 ){
+ }else if( strcmp(x,"stack_overflow")==0 ){
psp->declargslot = &(psp->gp->overflow);
}else if( strcmp(x,"extra_argument")==0 ){
psp->declargslot = &(psp->gp->arg);
psp->insertLineMacro = 0;
}else if( strcmp(x,"token_type")==0 ){
@@ -2243,13 +2243,13 @@
psp->state = WAITING_FOR_PRECEDENCE_SYMBOL;
}else if( strcmp(x,"nonassoc")==0 ){
psp->preccounter++;
psp->declassoc = NONE;
psp->state = WAITING_FOR_PRECEDENCE_SYMBOL;
- }else if( strcmp(x,"destructor")==0 ){
+ }else if( strcmp(x,"destructor")==0 ){
psp->state = WAITING_FOR_DESTRUCTOR_SYMBOL;
- }else if( strcmp(x,"type")==0 ){
+ }else if( strcmp(x,"type")==0 ){
psp->state = WAITING_FOR_DATATYPE_SYMBOL;
}else if( strcmp(x,"fallback")==0 ){
psp->fallback = 0;
psp->state = WAITING_FOR_FALLBACK_ID;
}else if( strcmp(x,"wildcard")==0 ){
@@ -2257,11 +2257,11 @@
}else{
ErrorMsg(psp->filename,psp->tokenlineno,
"Unknown declaration keyword: \"%%%s\".",x);
psp->errorcnt++;
psp->state = RESYNC_AFTER_DECL_ERROR;
- }
+ }
}else{
ErrorMsg(psp->filename,psp->tokenlineno,
"Illegal declaration keyword: \"%s\".",x);
psp->errorcnt++;
psp->state = RESYNC_AFTER_DECL_ERROR;
@@ -2312,14 +2312,14 @@
sp = Symbol_new(x);
if( sp->prec>=0 ){
ErrorMsg(psp->filename,psp->tokenlineno,
"Symbol \"%s\" has already be given a precedence.",x);
psp->errorcnt++;
- }else{
+ }else{
sp->prec = psp->preccounter;
sp->assoc = psp->declassoc;
- }
+ }
}else{
ErrorMsg(psp->filename,psp->tokenlineno,
"Can't assign a precedence to \"%s\".",x);
psp->errorcnt++;
}
@@ -2585,25 +2585,25 @@
prevc = 0;
while( (c= *cp)!=0 && (c!='/' || prevc!='*') ){
if( c=='\n' ) lineno++;
prevc = c;
cp++;
- }
- }else if( c=='/' && cp[1]=='/' ){ /* Skip C++ style comments too */
+ }
+ }else if( c=='/' && cp[1]=='/' ){ /* Skip C++ style comments too */
cp = &cp[2];
while( (c= *cp)!=0 && c!='\n' ) cp++;
if( c ) lineno++;
- }else if( c=='\'' || c=='\"' ){ /* String a character literals */
+ }else if( c=='\'' || c=='\"' ){ /* String a character literals */
int startchar, prevc;
startchar = c;
prevc = 0;
for(cp++; (c= *cp)!=0 && (c!=startchar || prevc=='\\'); cp++){
if( c=='\n' ) lineno++;
if( prevc=='\\' ) prevc = 0;
else prevc = c;
- }
- }
+ }
+ }
}
if( c==0 ){
ErrorMsg(ps.filename,ps.tokenlineno,
"C code starting on this line is not terminated before the end of the file.");
ps.errorcnt++;