Snapshot of upstream SQLite 3.7.15.2

This commit is contained in:
Nick Parker 2013-01-15 16:38:05 -06:00
parent 801e036cd8
commit 7d88842525
139 changed files with 8590 additions and 4361 deletions

View File

@ -45,7 +45,7 @@ TCC += @TCL_INCLUDE_SPEC@
# The library that programs using TCL must link against.
#
LIBTCL = @TCL_LIB_SPEC@ @TCL_LIBS@
LIBTCL = @TCL_LIB_SPEC@
# Compiler options needed for programs that use the readline() library.
#
@ -889,6 +889,9 @@ fulltest: testfixture$(TEXE) sqlite3$(TEXE)
soaktest: testfixture$(TEXE) sqlite3$(TEXE)
./testfixture$(TEXE) $(TOP)/test/all.test -soak=1
fulltestonly: testfixture$(TEXE) sqlite3$(TEXE)
./testfixture$(TEXE) $(TOP)/test/full.test
test: testfixture$(TEXE) sqlite3$(TEXE)
./testfixture$(TEXE) $(TOP)/test/veryquick.test
@ -932,7 +935,6 @@ clean:
rm -rf .libs .deps
rm -f lemon$(BEXE) lempar.c parse.* sqlite*.tar.gz
rm -f mkkeywordhash$(BEXE) keywordhash.h
rm -f $(PUBLISH)
rm -f *.da *.bb *.bbg gmon.out
rm -rf quota2a quota2b quota2c
rm -rf tsrc .target_source
@ -941,7 +943,7 @@ clean:
rm -f sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def
rm -f sqlite3.c
rm -f sqlite3_analyzer$(TEXE) sqlite3_analyzer.c
rm -f sqlite-output.vsix
rm -f sqlite-*-output.vsix
distclean: clean
rm -f config.log config.status libtool Makefile sqlite3.pc

View File

@ -9,49 +9,75 @@ TOP = .
# Set this non-0 to create and use the SQLite amalgamation file.
#
!IFNDEF USE_AMALGAMATION
USE_AMALGAMATION = 1
!ENDIF
# Set this non-0 to use the International Components for Unicode (ICU).
#
!IFNDEF USE_ICU
USE_ICU = 0
!ENDIF
# Set this non-0 to dynamically link to the MSVC runtime library.
#
!IFNDEF USE_CRT_DLL
USE_CRT_DLL = 0
!ENDIF
# Set this non-0 to attempt setting the native compiler automatically
# for cross-compiling the command line tools needed during the compilation
# process.
#
!IFNDEF XCOMPILE
XCOMPILE = 0
!ENDIF
# Set this non-0 to use the native libraries paths for cross-compiling
# the command line tools needed during the compilation process.
#
!IFNDEF USE_NATIVE_LIBPATHS
USE_NATIVE_LIBPATHS = 0
!ENDIF
# Set this 0 to skip the compiling and embedding of version resources.
#
!IFNDEF USE_RC
USE_RC = 1
!ENDIF
# Set this non-0 to compile binaries suitable for the WinRT environment.
# This setting does not apply to any binaries that require Tcl to operate
# properly (i.e. the text fixture, etc).
#
!IFNDEF FOR_WINRT
FOR_WINRT = 0
!ENDIF
# Set this non-0 to skip attempting to look for and/or link with the Tcl
# runtime library.
#
!IFNDEF NO_TCL
NO_TCL = 0
!ENDIF
# Set this to non-0 to create and use PDBs.
#
!IFNDEF SYMBOLS
SYMBOLS = 1
!ENDIF
# Set this to non-0 to use the SQLite debugging heap subsystem.
#
!IFNDEF MEMDEBUG
MEMDEBUG = 0
!ENDIF
# Set this to non-0 to use the Win32 native heap subsystem.
#
!IFNDEF WIN32HEAP
WIN32HEAP = 0
!ENDIF
# Set this to one of the following values to enable various debugging
# features. Each level includes the debugging options from the previous
@ -64,7 +90,9 @@ WIN32HEAP = 0
# 4 == SQLITE_DEBUG_OS_TRACE: Enables output from the OSTRACE() macros.
# 5 == SQLITE_ENABLE_IOTRACE: Enables output from the IOTRACE() macros.
#
!IFNDEF DEBUG
DEBUG = 0
!ENDIF
# Check for the predefined command macro CC. This should point to the compiler
# binary for the target platform. If it is not defined, simply define it to
@ -157,8 +185,8 @@ NLTLIBPATHS = "/LIBPATH:$(NCRTLIBPATH)" "/LIBPATH:$(NSDKLIBPATH)"
# will run on the target platform. (BCC and TCC are usually the
# same unless your are cross-compiling.)
#
TCC = $(CC) -W3 -DSQLITE_OS_WIN=1 -I. -I$(TOP)\src -fp:precise
RCC = $(RC) -DSQLITE_OS_WIN=1 -I. -I$(TOP)\src
TCC = $(CC) -W3 -DSQLITE_OS_WIN=1 -I$(TOP) -I$(TOP)\src -fp:precise
RCC = $(RC) -DSQLITE_OS_WIN=1 -I$(TOP) -I$(TOP)\src
# When compiling the library for use in the WinRT environment,
# the following compile-time options must be used as well to
@ -168,8 +196,8 @@ RCC = $(RC) -DSQLITE_OS_WIN=1 -I. -I$(TOP)\src
!IF $(FOR_WINRT)!=0
TCC = $(TCC) -DSQLITE_OS_WINRT=1
RCC = $(RCC) -DSQLITE_OS_WINRT=1
TCC = $(TCC) -DWINAPI_FAMILY=WINAPI_PARTITION_APP
RCC = $(RCC) -DWINAPI_FAMILY=WINAPI_PARTITION_APP
TCC = $(TCC) -DWINAPI_FAMILY=WINAPI_FAMILY_APP
RCC = $(RCC) -DWINAPI_FAMILY=WINAPI_FAMILY_APP
!ENDIF
# Also, we need to dynamically link to the correct MSVC runtime
@ -180,14 +208,18 @@ RCC = $(RCC) -DWINAPI_FAMILY=WINAPI_PARTITION_APP
!IF $(FOR_WINRT)!=0 || $(USE_CRT_DLL)!=0
!IF $(DEBUG)>0
TCC = $(TCC) -MDd
BCC = $(BCC) -MDd
!ELSE
TCC = $(TCC) -MD
BCC = $(BCC) -MD
!ENDIF
!ELSE
!IF $(DEBUG)>0
TCC = $(TCC) -MTd
BCC = $(BCC) -MTd
!ELSE
TCC = $(TCC) -MT
BCC = $(BCC) -MT
!ENDIF
!ENDIF
@ -472,6 +504,14 @@ LIBOBJ = $(LIBOBJS0)
LIBOBJ = $(LIBOBJS1)
!ENDIF
# Determine if embedded resource compilation and usage are enabled.
#
!IF $(USE_RC)!=0
LIBRESOBJS = sqlite3res.lo
!ELSE
LIBRESOBJS =
!ENDIF
# All of the source code files.
#
SRC = \
@ -766,10 +806,10 @@ libsqlite3.lib: $(LIBOBJ)
libtclsqlite3.lib: tclsqlite.lo libsqlite3.lib
$(LTLIB) $(LTLIBOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite.lo libsqlite3.lib $(LIBTCL:tcl=tclstub) $(TLIBS)
sqlite3.exe: $(TOP)\src\shell.c libsqlite3.lib sqlite3res.lo sqlite3.h
sqlite3.exe: $(TOP)\src\shell.c libsqlite3.lib $(LIBRESOBJS) sqlite3.h
$(LTLINK) $(READLINE_FLAGS) \
$(TOP)\src\shell.c \
/link $(LTLINKOPTS) $(LTLIBPATHS) libsqlite3.lib sqlite3res.lo $(LIBREADLINE) $(LTLIBS) $(TLIBS)
/link $(LTLINKOPTS) $(LTLIBPATHS) libsqlite3.lib $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
# This target creates a directory named "tsrc" and fills it with
# copies of all of the C source code and header files needed to
@ -789,8 +829,8 @@ sqlite3.exe: $(TOP)\src\shell.c libsqlite3.lib sqlite3res.lo sqlite3.h
sqlite3.c: .target_source $(TOP)\tool\mksqlite3c.tcl
$(TCLSH_CMD) $(TOP)\tool\mksqlite3c.tcl
sqlite3-all.c: sqlite3.c $(TOP)/tool/split-sqlite3c.tcl
$(TCLSH_CMD) $(TOP)/tool/split-sqlite3c.tcl
sqlite3-all.c: sqlite3.c $(TOP)\tool\split-sqlite3c.tcl
$(TCLSH_CMD) $(TOP)\tool\split-sqlite3c.tcl
# Rule to build the amalgamation
#
@ -819,14 +859,16 @@ opcodes.lo: opcodes.c
# Rule to build the Win32 resources object file.
#
sqlite3res.lo: $(TOP)\src\sqlite3.rc $(HDR)
!IF $(USE_RC)!=0
$(LIBRESOBJS): $(TOP)\src\sqlite3.rc $(HDR)
echo #ifndef SQLITE_RESOURCE_VERSION > sqlite3rc.h
for /F %%V in ('type VERSION') do ( \
for /F %%V in ('type "$(TOP)\VERSION"') do ( \
echo #define SQLITE_RESOURCE_VERSION %%V \
| $(NAWK) "/.*/ { gsub(/[.]/,\",\");print }" >> sqlite3rc.h \
)
echo #endif >> sqlite3rc.h
$(LTRCOMPILE) -fo sqlite3res.lo $(TOP)\src\sqlite3.rc
$(LTRCOMPILE) -fo $(LIBRESOBJS) $(TOP)\src\sqlite3.rc
!ENDIF
# Rules to build individual *.lo files from files in the src directory.
#
@ -1043,8 +1085,8 @@ tclsqlite.lo: $(TOP)\src\tclsqlite.c $(HDR)
tclsqlite-shell.lo: $(TOP)\src\tclsqlite.c $(HDR)
$(LTCOMPILE) -DTCLSH=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c
tclsqlite3.exe: tclsqlite-shell.lo libsqlite3.lib sqlite3res.lo
$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /OUT:$@ libsqlite3.lib tclsqlite-shell.lo sqlite3res.lo $(LTLIBS) $(TLIBS)
tclsqlite3.exe: tclsqlite-shell.lo libsqlite3.lib $(LIBRESOBJS)
$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /OUT:$@ libsqlite3.lib tclsqlite-shell.lo $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
# Rules to build opcodes.c and opcodes.h
#
@ -1157,11 +1199,11 @@ TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC0)
TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC1)
!ENDIF
testfixture.exe: $(TESTFIXTURE_SRC) sqlite3res.lo $(HDR)
testfixture.exe: $(TESTFIXTURE_SRC) $(LIBRESOBJS) $(HDR)
$(LTLINK) -DSQLITE_NO_SYNC=1 $(TESTFIXTURE_FLAGS) \
-DBUILD_sqlite -I$(TCLINCDIR) \
$(TESTFIXTURE_SRC) \
/link $(LTLINKOPTS) $(LTLIBPATHS) sqlite3res.lo $(LTLIBS) $(TLIBS)
/link $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
fulltest: testfixture.exe sqlite3.exe
.\testfixture.exe $(TOP)\test\all.test
@ -1169,6 +1211,9 @@ fulltest: testfixture.exe sqlite3.exe
soaktest: testfixture.exe sqlite3.exe
.\testfixture.exe $(TOP)\test\all.test -soak=1
fulltestonly: testfixture.exe sqlite3.exe
.\testfixture.exe $(TOP)\test\full.test
test: testfixture.exe sqlite3.exe
.\testfixture.exe $(TOP)\test\veryquick.test
@ -1179,9 +1224,9 @@ sqlite3_analyzer.c: sqlite3.c $(TOP)\src\test_stat.c $(TOP)\src\tclsqlite.c $(TO
$(NAWK) -f $(TOP)\tool\tostr.awk $(TOP)\tool\spaceanal.tcl >> $@
echo ; return zMainloop; } >> $@
sqlite3_analyzer.exe: sqlite3_analyzer.c sqlite3res.lo
sqlite3_analyzer.exe: sqlite3_analyzer.c $(LIBRESOBJS)
$(LTLINK) -DBUILD_sqlite -DTCLSH=2 -I$(TCLINCDIR) sqlite3_analyzer.c \
/link $(LTLINKOPTS) $(LTLIBPATHS) sqlite3res.lo $(LTLIBS) $(TLIBS)
/link $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
clean:
del /Q *.lo *.ilk *.lib *.obj *.pdb sqlite3.exe libsqlite3.lib
@ -1202,7 +1247,7 @@ clean:
del /Q sqlite3.c
del /Q sqlite3rc.h
del /Q sqlite3_analyzer.exe sqlite3_analyzer.exp sqlite3_analyzer.c
del /Q sqlite-output.vsix
del /Q sqlite-*-output.vsix
# Dynamic link library section.
#
@ -1214,5 +1259,5 @@ sqlite3.def: libsqlite3.lib
| $(NAWK) "/ 1 _?sqlite3_/ { sub(/^.* _?/,\"\");print }" \
| sort >> sqlite3.def
sqlite3.dll: $(LIBOBJ) sqlite3res.lo sqlite3.def
$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /DEF:sqlite3.def /OUT:$@ $(LIBOBJ) sqlite3res.lo $(LTLIBS) $(TLIBS)
sqlite3.dll: $(LIBOBJ) $(LIBRESOBJS) sqlite3.def
$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /DEF:sqlite3.def /OUT:$@ $(LIBOBJ) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)

View File

@ -625,6 +625,9 @@ fulltest: testfixture$(EXE) sqlite3$(EXE)
soaktest: testfixture$(EXE) sqlite3$(EXE)
./testfixture$(EXE) $(TOP)/test/all.test -soak=1
fulltestonly: testfixture$(EXE) sqlite3$(EXE)
./testfixture$(EXE) $(TOP)/test/full.test
test: testfixture$(EXE) sqlite3$(EXE)
./testfixture$(EXE) $(TOP)/test/veryquick.test

View File

@ -1 +1 @@
3.7.14.1
3.7.15.2

6513
configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -501,7 +501,6 @@ if test "${use_tcl}" = "yes" ; then
AC_SUBST(TCL_VERSION)
AC_SUBST(TCL_BIN_DIR)
AC_SUBST(TCL_SRC_DIR)
AC_SUBST(TCL_LIBS)
AC_SUBST(TCL_INCLUDE_SPEC)
AC_SUBST(TCL_LIB_FILE)

View File

@ -1,3 +1,10 @@
NOTE (2012-11-29):
The functionality implemented by this extension has been superseded
by WAL-mode. This module is no longer supported or maintained. The
code is retained for historical reference only.
------------------------------------------------------------------------------
Normally, when SQLite writes to a database file, it waits until the write
operation is finished before returning control to the calling application.
@ -161,4 +168,3 @@ the database, eliminating the bottleneck.
The functionality required of each of the above functions is described
in comments in sqlite3async.c.

View File

@ -1510,6 +1510,7 @@ static void asyncWriterThread(void){
case ASYNC_DELETE:
ASYNC_TRACE(("DELETE %s\n", p->zBuf));
rc = pVfs->xDelete(pVfs, p->zBuf, (int)p->iOffset);
if( rc==SQLITE_IOERR_DELETE_NOENT ) rc = SQLITE_OK;
break;
case ASYNC_OPENEXCLUSIVE: {

View File

@ -75,7 +75,7 @@ int sqlite3async_initialize(const char *zParent, int isDefault);
** On win32 platforms, this function also releases the small number of
** critical section and event objects created by sqlite3async_initialize().
*/
void sqlite3async_shutdown();
void sqlite3async_shutdown(void);
/*
** This function may only be called when the asynchronous IO VFS is
@ -94,7 +94,7 @@ void sqlite3async_shutdown();
** If multiple simultaneous calls are made to sqlite3async_run() from two
** or more threads, then the calls are serialized internally.
*/
void sqlite3async_run();
void sqlite3async_run(void);
/*
** This function may only be called when the asynchronous IO VFS is

View File

@ -118,7 +118,7 @@ static int icuOpen(
nChar = nInput+1;
pCsr = (IcuCursor *)sqlite3_malloc(
sizeof(IcuCursor) + /* IcuCursor */
nChar * sizeof(UChar) + /* IcuCursor.aChar[] */
((nChar+3)&~3) * sizeof(UChar) + /* IcuCursor.aChar[] */
(nChar+1) * sizeof(int) /* IcuCursor.aOffset[] */
);
if( !pCsr ){
@ -126,7 +126,7 @@ static int icuOpen(
}
memset(pCsr, 0, sizeof(IcuCursor));
pCsr->aChar = (UChar *)&pCsr[1];
pCsr->aOffset = (int *)&pCsr->aChar[nChar];
pCsr->aOffset = (int *)&pCsr->aChar[(nChar+3)&~3];
pCsr->aOffset[iOut] = iInput;
U8_NEXT(zInput, iInput, nInput, c);

View File

@ -4743,35 +4743,39 @@ static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){
nTmp += p->pRight->pPhrase->doclist.nList;
}
nTmp += p->pPhrase->doclist.nList;
aTmp = sqlite3_malloc(nTmp*2);
if( !aTmp ){
*pRc = SQLITE_NOMEM;
if( nTmp==0 ){
res = 0;
}else{
char *aPoslist = p->pPhrase->doclist.pList;
int nToken = p->pPhrase->nToken;
aTmp = sqlite3_malloc(nTmp*2);
if( !aTmp ){
*pRc = SQLITE_NOMEM;
res = 0;
}else{
char *aPoslist = p->pPhrase->doclist.pList;
int nToken = p->pPhrase->nToken;
for(p=p->pParent;res && p && p->eType==FTSQUERY_NEAR; p=p->pParent){
Fts3Phrase *pPhrase = p->pRight->pPhrase;
int nNear = p->nNear;
res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
}
aPoslist = pExpr->pRight->pPhrase->doclist.pList;
nToken = pExpr->pRight->pPhrase->nToken;
for(p=pExpr->pLeft; p && res; p=p->pLeft){
int nNear;
Fts3Phrase *pPhrase;
assert( p->pParent && p->pParent->pLeft==p );
nNear = p->pParent->nNear;
pPhrase = (
p->eType==FTSQUERY_NEAR ? p->pRight->pPhrase : p->pPhrase
);
res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
for(p=p->pParent;res && p && p->eType==FTSQUERY_NEAR; p=p->pParent){
Fts3Phrase *pPhrase = p->pRight->pPhrase;
int nNear = p->nNear;
res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
}
aPoslist = pExpr->pRight->pPhrase->doclist.pList;
nToken = pExpr->pRight->pPhrase->nToken;
for(p=pExpr->pLeft; p && res; p=p->pLeft){
int nNear;
Fts3Phrase *pPhrase;
assert( p->pParent && p->pParent->pLeft==p );
nNear = p->pParent->nNear;
pPhrase = (
p->eType==FTSQUERY_NEAR ? p->pRight->pPhrase : p->pPhrase
);
res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
}
}
sqlite3_free(aTmp);
}
sqlite3_free(aTmp);
}
return res;

View File

@ -185,7 +185,7 @@ static int getNextToken(
rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, n, &pCursor);
if( rc==SQLITE_OK ){
const char *zToken;
int nToken, iStart, iEnd, iPosition;
int nToken = 0, iStart = 0, iEnd = 0, iPosition = 0;
int nByte; /* total space to allocate */
rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition);
@ -300,7 +300,7 @@ static int getNextString(
int ii;
for(ii=0; rc==SQLITE_OK; ii++){
const char *zByte;
int nByte, iBegin, iEnd, iPos;
int nByte = 0, iBegin = 0, iEnd = 0, iPos = 0;
rc = pModule->xNext(pCursor, &zByte, &nByte, &iBegin, &iEnd, &iPos);
if( rc==SQLITE_OK ){
Fts3PhraseToken *pToken;

View File

@ -119,7 +119,7 @@ static int icuOpen(
nChar = nInput+1;
pCsr = (IcuCursor *)sqlite3_malloc(
sizeof(IcuCursor) + /* IcuCursor */
nChar * sizeof(UChar) + /* IcuCursor.aChar[] */
((nChar+3)&~3) * sizeof(UChar) + /* IcuCursor.aChar[] */
(nChar+1) * sizeof(int) /* IcuCursor.aOffset[] */
);
if( !pCsr ){
@ -127,7 +127,7 @@ static int icuOpen(
}
memset(pCsr, 0, sizeof(IcuCursor));
pCsr->aChar = (UChar *)&pCsr[1];
pCsr->aOffset = (int *)&pCsr->aChar[nChar];
pCsr->aOffset = (int *)&pCsr->aChar[(nChar+3)&~3];
pCsr->aOffset[iOut] = iInput;
U8_NEXT(zInput, iInput, nInput, c);

View File

@ -576,7 +576,7 @@ static int fts3SnippetShift(
return rc;
}
while( rc==SQLITE_OK && iCurrent<(nSnippet+nDesired) ){
const char *ZDUMMY; int DUMMY1, DUMMY2, DUMMY3;
const char *ZDUMMY; int DUMMY1 = 0, DUMMY2 = 0, DUMMY3 = 0;
rc = pMod->xNext(pC, &ZDUMMY, &DUMMY1, &DUMMY2, &DUMMY3, &iCurrent);
}
pMod->xClose(pC);
@ -620,8 +620,6 @@ static int fts3SnippetText(
int iCol = pFragment->iCol+1; /* Query column to extract text from */
sqlite3_tokenizer_module *pMod; /* Tokenizer module methods object */
sqlite3_tokenizer_cursor *pC; /* Tokenizer cursor open on zDoc/nDoc */
const char *ZDUMMY; /* Dummy argument used with tokenizer */
int DUMMY1; /* Dummy argument used with tokenizer */
zDoc = (const char *)sqlite3_column_text(pCsr->pStmt, iCol);
if( zDoc==0 ){
@ -640,10 +638,23 @@ static int fts3SnippetText(
}
while( rc==SQLITE_OK ){
int iBegin; /* Offset in zDoc of start of token */
int iFin; /* Offset in zDoc of end of token */
int isHighlight; /* True for highlighted terms */
const char *ZDUMMY; /* Dummy argument used with tokenizer */
int DUMMY1 = -1; /* Dummy argument used with tokenizer */
int iBegin = 0; /* Offset in zDoc of start of token */
int iFin = 0; /* Offset in zDoc of end of token */
int isHighlight = 0; /* True for highlighted terms */
/* Variable DUMMY1 is initialized to a negative value above. Elsewhere
** in the FTS code the variable that the third argument to xNext points to
** is initialized to zero before the first (*but not necessarily
** subsequent*) call to xNext(). This is done for a particular application
** that needs to know whether or not the tokenizer is being used for
** snippet generation or for some other purpose.
**
** Extreme care is required when writing code to depend on this
** initialization. It is not a documented part of the tokenizer interface.
** If a tokenizer is used directly by any code outside of FTS, this
** convention might not be respected. */
rc = pMod->xNext(pC, &ZDUMMY, &DUMMY1, &iBegin, &iFin, &iCurrent);
if( rc!=SQLITE_OK ){
if( rc==SQLITE_DONE ){
@ -1333,8 +1344,6 @@ void sqlite3Fts3Offsets(
){
Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
sqlite3_tokenizer_module const *pMod = pTab->pTokenizer->pModule;
const char *ZDUMMY; /* Dummy argument used with xNext() */
int NDUMMY; /* Dummy argument used with xNext() */
int rc; /* Return Code */
int nToken; /* Number of tokens in query */
int iCol; /* Column currently being processed */
@ -1367,9 +1376,11 @@ void sqlite3Fts3Offsets(
*/
for(iCol=0; iCol<pTab->nColumn; iCol++){
sqlite3_tokenizer_cursor *pC; /* Tokenizer cursor */
int iStart;
int iEnd;
int iCurrent;
const char *ZDUMMY; /* Dummy argument used with xNext() */
int NDUMMY = 0; /* Dummy argument used with xNext() */
int iStart = 0;
int iEnd = 0;
int iCurrent = 0;
const char *zDoc;
int nDoc;

View File

@ -251,10 +251,10 @@ static void testFunc(
const char *azArg[64];
const char *zToken;
int nToken;
int iStart;
int iEnd;
int iPos;
int nToken = 0;
int iStart = 0;
int iEnd = 0;
int iPos = 0;
int i;
Tcl_Obj *pRet;

View File

@ -776,16 +776,16 @@ static int fts3PendingTermsAdd(
int iLangid, /* Language id to use */
const char *zText, /* Text of document to be inserted */
int iCol, /* Column into which text is being inserted */
u32 *pnWord /* OUT: Number of tokens inserted */
u32 *pnWord /* IN/OUT: Incr. by number tokens inserted */
){
int rc;
int iStart;
int iEnd;
int iPos;
int iStart = 0;
int iEnd = 0;
int iPos = 0;
int nWord = 0;
char const *zToken;
int nToken;
int nToken = 0;
sqlite3_tokenizer *pTokenizer = p->pTokenizer;
sqlite3_tokenizer_module const *pModule = pTokenizer->pModule;
@ -840,7 +840,7 @@ static int fts3PendingTermsAdd(
}
pModule->xClose(pCsr);
*pnWord = nWord;
*pnWord += nWord;
return (rc==SQLITE_DONE ? SQLITE_OK : rc);
}
@ -1044,11 +1044,13 @@ static void fts3DeleteTerms(
int *pRC, /* Result code */
Fts3Table *p, /* The FTS table to delete from */
sqlite3_value *pRowid, /* The docid to be deleted */
u32 *aSz /* Sizes of deleted document written here */
u32 *aSz, /* Sizes of deleted document written here */
int *pbFound /* OUT: Set to true if row really does exist */
){
int rc;
sqlite3_stmt *pSelect;
assert( *pbFound==0 );
if( *pRC ) return;
rc = fts3SqlStmt(p, SQL_SELECT_CONTENT_BY_ROWID, &pSelect, &pRowid);
if( rc==SQLITE_OK ){
@ -1066,6 +1068,7 @@ static void fts3DeleteTerms(
*pRC = rc;
return;
}
*pbFound = 1;
}
rc = sqlite3_reset(pSelect);
}else{
@ -3290,7 +3293,7 @@ static int fts3DoRebuild(Fts3Table *p){
int iCol;
int iLangid = langidFromSelect(p, pStmt);
rc = fts3PendingTermsDocid(p, iLangid, sqlite3_column_int64(pStmt, 0));
aSz[p->nColumn] = 0;
memset(aSz, 0, sizeof(aSz[0]) * (p->nColumn+1));
for(iCol=0; rc==SQLITE_OK && iCol<p->nColumn; iCol++){
const char *z = (const char *) sqlite3_column_text(pStmt, iCol+1);
rc = fts3PendingTermsAdd(p, iLangid, z, iCol, &aSz[iCol]);
@ -4934,9 +4937,9 @@ static int fts3IntegrityCheck(Fts3Table *p, int *pbOk){
rc = sqlite3Fts3OpenTokenizer(p->pTokenizer, iLang, zText, nText, &pT);
while( rc==SQLITE_OK ){
char const *zToken; /* Buffer containing token */
int nToken; /* Number of bytes in token */
int iDum1, iDum2; /* Dummy variables */
int iPos; /* Position of token in zText */
int nToken = 0; /* Number of bytes in token */
int iDum1 = 0, iDum2 = 0; /* Dummy variables */
int iPos = 0; /* Position of token in zText */
rc = pModule->xNext(pT, &zToken, &nToken, &iDum1, &iDum2, &iPos);
if( rc==SQLITE_OK ){
@ -5103,9 +5106,9 @@ int sqlite3Fts3CacheDeferredDoclists(Fts3Cursor *pCsr){
rc = sqlite3Fts3OpenTokenizer(pT, pCsr->iLangid, zText, -1, &pTC);
while( rc==SQLITE_OK ){
char const *zToken; /* Buffer containing token */
int nToken; /* Number of bytes in token */
int iDum1, iDum2; /* Dummy variables */
int iPos; /* Position of token in zText */
int nToken = 0; /* Number of bytes in token */
int iDum1 = 0, iDum2 = 0; /* Dummy variables */
int iPos = 0; /* Position of token in zText */
rc = pModule->xNext(pTC, &zToken, &nToken, &iDum1, &iDum2, &iPos);
for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){
@ -5194,28 +5197,32 @@ int sqlite3Fts3DeferToken(
static int fts3DeleteByRowid(
Fts3Table *p,
sqlite3_value *pRowid,
int *pnDoc,
int *pnChng, /* IN/OUT: Decrement if row is deleted */
u32 *aSzDel
){
int isEmpty = 0;
int rc = fts3IsEmpty(p, pRowid, &isEmpty);
if( rc==SQLITE_OK ){
if( isEmpty ){
/* Deleting this row means the whole table is empty. In this case
** delete the contents of all three tables and throw away any
** data in the pendingTerms hash table. */
rc = fts3DeleteAll(p, 1);
*pnDoc = *pnDoc - 1;
}else{
fts3DeleteTerms(&rc, p, pRowid, aSzDel);
if( p->zContentTbl==0 ){
fts3SqlExec(&rc, p, SQL_DELETE_CONTENT, &pRowid);
if( sqlite3_changes(p->db) ) *pnDoc = *pnDoc - 1;
int rc = SQLITE_OK; /* Return code */
int bFound = 0; /* True if *pRowid really is in the table */
fts3DeleteTerms(&rc, p, pRowid, aSzDel, &bFound);
if( bFound && rc==SQLITE_OK ){
int isEmpty = 0; /* Deleting *pRowid leaves the table empty */
rc = fts3IsEmpty(p, pRowid, &isEmpty);
if( rc==SQLITE_OK ){
if( isEmpty ){
/* Deleting this row means the whole table is empty. In this case
** delete the contents of all three tables and throw away any
** data in the pendingTerms hash table. */
rc = fts3DeleteAll(p, 1);
*pnChng = 0;
memset(aSzDel, 0, sizeof(u32) * (p->nColumn+1) * 2);
}else{
*pnDoc = *pnDoc - 1;
}
if( p->bHasDocsize ){
fts3SqlExec(&rc, p, SQL_DELETE_DOCSIZE, &pRowid);
*pnChng = *pnChng - 1;
if( p->zContentTbl==0 ){
fts3SqlExec(&rc, p, SQL_DELETE_CONTENT, &pRowid);
}
if( p->bHasDocsize ){
fts3SqlExec(&rc, p, SQL_DELETE_DOCSIZE, &pRowid);
}
}
}
}
@ -5246,7 +5253,7 @@ int sqlite3Fts3UpdateMethod(
int rc = SQLITE_OK; /* Return Code */
int isRemove = 0; /* True for an UPDATE or DELETE */
u32 *aSzIns = 0; /* Sizes of inserted documents */
u32 *aSzDel; /* Sizes of deleted documents */
u32 *aSzDel = 0; /* Sizes of deleted documents */
int nChng = 0; /* Net change in number of documents */
int bInsertDone = 0;
@ -5274,13 +5281,13 @@ int sqlite3Fts3UpdateMethod(
}
/* Allocate space to hold the change in document sizes */
aSzIns = sqlite3_malloc( sizeof(aSzIns[0])*(p->nColumn+1)*2 );
if( aSzIns==0 ){
aSzDel = sqlite3_malloc( sizeof(aSzDel[0])*(p->nColumn+1)*2 );
if( aSzDel==0 ){
rc = SQLITE_NOMEM;
goto update_out;
}
aSzDel = &aSzIns[p->nColumn+1];
memset(aSzIns, 0, sizeof(aSzIns[0])*(p->nColumn+1)*2);
aSzIns = &aSzDel[p->nColumn+1];
memset(aSzDel, 0, sizeof(aSzDel[0])*(p->nColumn+1)*2);
/* If this is an INSERT operation, or an UPDATE that modifies the rowid
** value, then this operation requires constraint handling.
@ -5365,7 +5372,7 @@ int sqlite3Fts3UpdateMethod(
}
update_out:
sqlite3_free(aSzIns);
sqlite3_free(aSzDel);
sqlite3Fts3SegmentsClose(p);
return rc;
}

View File

@ -2660,7 +2660,7 @@ static int newRowid(Rtree *pRtree, i64 *piRowid){
*/
static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){
int rc; /* Return code */
RtreeNode *pLeaf; /* Leaf node containing record iDelete */
RtreeNode *pLeaf = 0; /* Leaf node containing record iDelete */
int iCell; /* Index of iDelete cell in pLeaf */
RtreeNode *pRoot; /* Root node of rtree structure */
@ -2863,7 +2863,7 @@ static int rtreeUpdate(
*/
if( rc==SQLITE_OK && nData>1 ){
/* Insert the new record into the r-tree */
RtreeNode *pLeaf;
RtreeNode *pLeaf = 0;
/* Figure out the rowid of the new row. */
if( bHaveRowid==0 ){

View File

@ -257,6 +257,7 @@ TESTSRC = \
$(TOP)/src/test_schema.c \
$(TOP)/src/test_server.c \
$(TOP)/src/test_stat.c \
$(TOP)/src/test_sqllog.c \
$(TOP)/src/test_superlock.c \
$(TOP)/src/test_syscall.c \
$(TOP)/src/test_tclvar.c \
@ -546,7 +547,7 @@ TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE
testfixture$(EXE): $(TESTSRC2) libsqlite3.a $(TESTSRC) $(TOP)/src/tclsqlite.c
$(TCCX) $(TCL_FLAGS) -DTCLSH=1 $(TESTFIXTURE_FLAGS) \
$(TESTSRC) $(TESTSRC2) $(TOP)/src/tclsqlite.c \
-o testfixture$(EXE) $(LIBTCL) $(THREADLIB) libsqlite3.a
-o testfixture$(EXE) $(LIBTCL) libsqlite3.a $(THREADLIB)
amalgamation-testfixture$(EXE): sqlite3.c $(TESTSRC) $(TOP)/src/tclsqlite.c
$(TCCX) $(TCL_FLAGS) -DTCLSH=1 $(TESTFIXTURE_FLAGS) \
@ -565,6 +566,9 @@ fulltest: testfixture$(EXE) sqlite3$(EXE)
soaktest: testfixture$(EXE) sqlite3$(EXE)
./testfixture$(EXE) $(TOP)/test/all.test -soak=1
fulltestonly: testfixture$(EXE) sqlite3$(EXE)
./testfixture$(EXE) $(TOP)/test/full.test
test: testfixture$(EXE) sqlite3$(EXE)
./testfixture$(EXE) $(TOP)/test/veryquick.test
@ -616,4 +620,4 @@ clean:
rm -f threadtest3 threadtest3.exe
rm -f sqlite3.c fts?amal.c tclsqlite3.c
rm -f sqlite3_analyzer sqlite3_analyzer.exe sqlite3_analyzer.c
rm -f sqlite-output.vsix
rm -f sqlite-*-output.vsix

299
manifest
View File

@ -1,12 +1,12 @@
C Version\s3.7.14.1
D 2012-10-04T19:37:12.994
C Version\s3.7.15.2\srelease\scandidate
D 2013-01-09T11:53:05.549
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in abd5c10d21d1395f140d9e50ea999df8fa4d6376
F Makefile.in 690d441a758cbffd13e814dc2724a721a6ebd400
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F Makefile.msc 2d696f01c228995e98b3b953a08b7bba1d48c130
F Makefile.vxworks 879f034a64062a364b21000266bbd5bc6e0c19b9
F Makefile.msc 5a3b6f34d263b01f8b798c291fac1529fd650308
F Makefile.vxworks b18ad88e9a8c6a001f5cf4a389116a4f1a7ab45f
F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6
F VERSION 9694dff497fc7e53037a5890f30ab069c26e8ab7
F VERSION b5fc9136ddbcdd63702e99fea1b4e83960f52006
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
F addopcodes.awk 17dc593f791f874d2c23a0f9360850ded0286531
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
@ -15,16 +15,16 @@ F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
F config.h.in 0921066a13130082764ab4ab6456f7b5bebe56de
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
F configure e2c3b28dec7f5d1f72dd7465c87bb37f6af1931f x
F configure.ac 6e909664785b8184db2179013cd9d574f96ca3a3
F configure a417189892a5a3c54a73ac96583e3671bddc8db7 x
F configure.ac 81c43d151d0b0e406be056394cc9ff4cb3fd0444
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
F doc/lemon.html 334dbf6621b8fb8790297ec1abf3cfa4621709d1
F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710
F doc/vfs-shm.txt e101f27ea02a8387ce46a05be2b1a902a021d37a
F ext/README.txt 913a7bd3f4837ab14d7e063304181787658b14e1
F ext/async/README.txt 0c541f418b14b415212264cbaaf51c924ec62e5b
F ext/async/sqlite3async.c 733a9f21b1066f44ff07b9c0da973b1e483d1e0c
F ext/async/sqlite3async.h a21e1252deb14a2c211f0e165c4b9122a8f1f344
F ext/async/README.txt e12275968f6fde133a80e04387d0e839b0c51f91
F ext/async/sqlite3async.c b5a3e30f538a9ffe81538b3063b4d5963f9bb422
F ext/async/sqlite3async.h f489b080af7e72aec0e1ee6f1d98ab6cf2e4dcef
F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e
F ext/fts1/ft_hash.c 3927bd880e65329bdc6f506555b228b28924921b
F ext/fts1/ft_hash.h 1a35e654a235c2c662d3ca0dfc3138ad60b8b7d5
@ -45,7 +45,7 @@ F ext/fts2/fts2.c 4ef7d7ecf590da0dd416ac54612c53a7d4175790
F ext/fts2/fts2.h da5f76c65163301d1068a971fd32f4119e3c95fa
F ext/fts2/fts2_hash.c 2689e42e1107ea67207f725cf69cf8972d00cf93
F ext/fts2/fts2_hash.h 9a5b1be94664139f93217a0770d7144425cffb3a
F ext/fts2/fts2_icu.c 1ea9993a39c9783c2e2d7446d055e9d64411dda0
F ext/fts2/fts2_icu.c 51c5cd3c04954badd329fa738c95fcdb717b5188
F ext/fts2/fts2_porter.c 747056987951f743e955c8479f1df21a565720fe
F ext/fts2/fts2_tokenizer.c 26e993a00b2bd5b6e73c155597361710b12ffe25
F ext/fts2/fts2_tokenizer.h a7e46462d935a314b2682287f12f27530a3ee08e
@ -55,24 +55,24 @@ F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
F ext/fts3/fts3.c ab90126ee0163539d21d0618d22afa2eb645f7e2
F ext/fts3/fts3.c a867cafae0235324df64c5775cbf352a3f712cb9
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
F ext/fts3/fts3Int.h 1e58825246b56259267382d2f9902774c049460a
F ext/fts3/fts3_aux.c 5205182bd8f372782597888156404766edf5781e
F ext/fts3/fts3_expr.c dbc7ba4c3a6061adde0f38ed8e9b349568299551
F ext/fts3/fts3_expr.c ceefcaf91344abbf6ceb3cadf404eef5be6924e6
F ext/fts3/fts3_hash.c 8dd2d06b66c72c628c2732555a32bc0943114914
F ext/fts3/fts3_hash.h 8331fb2206c609f9fc4c4735b9ab5ad6137c88ec
F ext/fts3/fts3_icu.c b85eca4a52e5ec11b94392de5167974c11906d4a
F ext/fts3/fts3_icu.c e319e108661147bcca8dd511cd562f33a1ba81b5
F ext/fts3/fts3_porter.c a465b49fcb8249a755792f87516eff182efa42b3
F ext/fts3/fts3_snippet.c bf67520ae9d2352a65368ed101729ff701c08808
F ext/fts3/fts3_snippet.c f6ebb3536069ceaa27e9f178f4a59379db44ac10
F ext/fts3/fts3_term.c a521f75132f9a495bdca1bdd45949b3191c52763
F ext/fts3/fts3_test.c 348f7d08cae05285794e23dc4fe8b8fdf66e264a
F ext/fts3/fts3_tokenizer.c e94a8b901066031437ccfe4769fc76370257cede
F ext/fts3/fts3_tokenizer.c 3664bb8836ab7633cf9da786c9d6fd366be5ae2c
F ext/fts3/fts3_tokenizer.h 66dec98e365854b6cd2d54f1a96bb6d428fc5a68
F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004
F ext/fts3/fts3_unicode.c 49e36e6ba59f79e6bd6a8bfe434570fe48d20559
F ext/fts3/fts3_unicode2.c a863f05f758af36777dffc2facc898bc73fec896
F ext/fts3/fts3_write.c c30c49f3debb9497a07f15cc4c042815e35474ef
F ext/fts3/fts3_write.c c2166f7148a4ad8bcdad99a99d647b1091744e6b
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
F ext/fts3/tool/fts3view.c 6cfc5b67a5f0e09c0d698f9fd012c784bfaa9197
@ -83,7 +83,7 @@ F ext/icu/README.txt bf8461d8cdc6b8f514c080e4e10dc3b2bbdfefa9
F ext/icu/icu.c eb9ae1d79046bd7871aa97ee6da51eb770134b5a
F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
F ext/rtree/rtree.c d17aecb7a92762efa7b1f5d5fd7c88fd77d70827
F ext/rtree/rtree.c 47064ee2995a396bfb626337d2b43f12cc0af687
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
F ext/rtree/rtree1.test e474a2b5eff231496dbd073fe67e5fbaf7f444c9
F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba
@ -103,49 +103,47 @@ F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F main.mk 72026405046ed5b1f0368943b89c0aa29ad558b6
F main.mk a0d170ae1a8a8683688e281194e09d47a68eaa3f
F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a
F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f
F mkextw.sh 4123480947681d9b434a5e7b1ee08135abe409ac
F mkopcodec.awk f6fccee29e68493bfd90a2e0466ede5fa94dd2fc
F mkopcodeh.awk 29b84656502eee5f444c3147f331ee686956ab0e
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
F publish.sh 313c5b2425f2cf5e547db7549a9796acc4508f22
F publish_osx.sh 2ad2ee7d50632dff99949edc9c162dbb052f7534
F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad
F src/alter.c 149cc80d9257971b0bff34e58fb2263e01998289
F src/alter.c f8db986c03eb0bfb221523fc9bbb9d0b70de3168
F src/analyze.c 7553068d21e32a57fc33ab6b2393fc8c1ba41410
F src/attach.c 577bf5675b0c50495fc28549f2fcbdb1bac71143
F src/attach.c ea5247f240e2c08afd608e9beb380814b86655e1
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
F src/backup.c 5b31b24d6814b11de763debf342c8cd0a15a4910
F src/backup.c cab40f2c1fe79d6eb93d3b4086c78c41ad2fa5d0
F src/bitvec.c 26675fe8e431dc555e6f2d0e11e651d172234aa1
F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
F src/btree.c 97edf88abd2b66f31886ba977d2b3b2a21d81d4c
F src/btree.h 4aee02e879211bfcfd3f551769578d2e940ab6c2
F src/btree.c eccee944cb2221e919d7a855e5928d8643194b14
F src/btree.h 3ad7964d6c5b1c7bff569aab6adfa075f8bf06cd
F src/btreeInt.h 4e5c2bd0f9b36b2a815a6d84f771a61a65830621
F src/build.c a3b700afd475e6387da59be6f2e86161e80d6d87
F src/callback.c 0cb4228cdcd827dcc5def98fb099edcc9142dbcd
F src/build.c f4f86c07002c6f3ee96c1e34e0e993a962ef2c73
F src/callback.c d7e46f40c3cf53c43550b7da7a1d0479910b62cc
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
F src/ctime.c 500d019da966631ad957c37705642be87524463b
F src/ctime.c 72a70dcfda75d3a1f81041ce4573e7afddcd8e4e
F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4
F src/delete.c 335f36750dc6ac88d580aa36a6487459be9889de
F src/expr.c 217840a107dcc1e5dbb57cea311daad04bedbb9a
F src/delete.c 9b8d308979114991e5dc7cee958316e07186941d
F src/expr.c 0e41d66d868b37dbc0e041c342e0036fad27e705
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c 9c77d842dc9961d92a06a65abb80c64ef1750296
F src/func.c 18dfedfb857e100b05755a1b12e88b389f957879
F src/global.c 4cfdca5cb0edd33c4d021baec4ede958cb2c793b
F src/hash.c a4031441741932da9e7a65bee2b36b5d0e81c073
F src/fkey.c dcb7c37a4bf526ded7b24a01a60fe071bcd160a2
F src/func.c 8147799b048065a1590805be464d05b4913e652c
F src/global.c e59ecd2c553ad0d4bfbc84ca71231336f8993a7a
F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4
F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
F src/insert.c b090d0a9fb9ff2dbdeaf66aedccf98cd13b1af60
F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e
F src/insert.c dc197aa9293a26d300eb5378880e701f7b20fefa
F src/journal.c eb7b9f5e783266521bcd9b2b93d419a219411f71
F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f
F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416
F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d
F src/main.c 02255cf1da50956c5427c469abddb15bccc4ba09
F src/main.c 448564ee3795b13c373bbc5c8590df8fbfe1d64c
F src/malloc.c fe085aa851b666b7c375c1ff957643dc20a04bf6
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c 437c7c4af964895d4650f29881df63535caaa1fa
@ -162,36 +160,36 @@ F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30
F src/os.c e1acdc09ff3ac2412945cca9766e2dcf4675f31c
F src/os.h 027491c77d2404c0a678bb3fb06286f331eb9b57
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
F src/os_unix.c 69b2fe66316524eebf5f1ce85c1fdfe2952307e9
F src/os_win.c 5dec8fe85ee547152075c020db72aec4382f0d0a
F src/pager.c 5665fa9ecec51f11dabdfd8eefefa89391856007
F src/pager.h 8b8c9bc065a3c66769df8724dfdf492ee1aab3c5
F src/parse.y f29df90bd3adc64b33114ab1de9fb7768fcf2099
F src/os_unix.c ad459bb62eb6f3f6aae26d97b1a28fbac7bf0260
F src/os_win.c ce1f5db8a7bb4d6f2092b1b2cb9631bec54a6320
F src/pager.c 4092c907222cfd451c74fe6bd2fd64b342f7190f
F src/pager.h 1109a06578ec5574dc2c74cf8d9f69daf36fe3e0
F src/parse.y c2b4a6454ad77299b1443e2c483a560a9f16e724
F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
F src/pcache.h 1b5dcc3dc8103d03e625b177023ee67764fa6b7c
F src/pcache1.c 9fd22671c270b35131ef480bbc00392b8b5f8ab9
F src/pragma.c 97f9357f0e7e5fb46a2519f14539550aa07db49f
F src/prepare.c 33291b83cca285718048d219c67b8298501fa3a5
F src/pragma.c 015723c48072781d2740e310ab04dc92956b76d1
F src/prepare.c 931ad0d852a0df48f79adcba6ce79ca5f475625c
F src/printf.c 4a9f882f1c1787a8b494a2987765acf9d97ac21f
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
F src/resolve.c 9e28280ec98035f31900fdd1db01f86f68ca6c32
F src/resolve.c cdd546d62da7763119ea1fa455a898959e03457f
F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
F src/select.c f843c872a97baa1594c2cc3d4c003409a7bd03af
F src/shell.c 87953c5d9c73d9494db97d1607e2e2280418f261
F src/sqlite.h.in c447d35212736c4c77d86bc2d00f6cf4d4c12131
F src/select.c e6daa524bbdfa98f4abdb8cb281498f0047d3161
F src/shell.c e392dd1ccbb77cc1d75a8367a89b473c24bea019
F src/sqlite.h.in 39cc33bb08897c748fe3383c29ccf56585704177
F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0
F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477
F src/sqliteInt.h 053e03a532beb909ead2df0721db67cdb4c48ae8
F src/sqliteInt.h d1f0866c69d94fe018a32f78c31a043e3fc0d0de
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 35939e7e03abf1b7577ce311f48f682c40de3208
F src/status.c bedc37ec1a6bb9399944024d63f4c769971955a9
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
F src/tclsqlite.c d20022c647aa7a871d7b4038c4ec971cafe39744
F src/test1.c 3d70f7c5987f186884cfebbfa7151a7d3d67d86e
F src/tclsqlite.c 515abd8e33e82aa330eeb54675185a7e1e5b6778
F src/test1.c f62769c989146149590662ab02de4a813813a9c5
F src/test2.c 4178056dd1e7d70f954ad8a1e3edb71a2a784daf
F src/test3.c 3c3c2407fa6ec7a19e24ae23f7cb439d0275a60d
F src/test4.c bf9fa9bece01de08e6f5e02314e4af5c13590dfa
F src/test5.c a6d1ac55ac054d0b2b8f37b5e655b6c92645a013
F src/test6.c 417e1e214734393c24a8ee80b41485a9c4169123
F src/test6.c 938794c970ed6810036c8d28450ca28166524bf7
F src/test7.c 2e0781754905c8adc3268d8f0967e7633af58843
F src/test8.c 8bcce65e5ee027fbfd7da41d28371aabbfd369ff
F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60
@ -206,55 +204,56 @@ F src/test_func.c 3a8dd37c08ab43b76d38eea2836e34a3897bf170
F src/test_fuzzer.c 1d26aa965120420bc14807da29d4d4541bfa6148
F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd
F src/test_init.c 3cbad7ce525aec925f8fda2192d576d47f0d478a
F src/test_intarray.c d879bbf8e4ce085ab966d1f3c896a7c8b4f5fc99
F src/test_intarray.h 489edb9068bb926583445cb02589344961054207
F src/test_intarray.c 07ddcebe4097d400ffca362770f1d883c112387a
F src/test_intarray.h b999bb18d090b8d9d9c49d36ec37ef8f341fe169
F src/test_journal.c f5c0a05b7b3d5930db769b5ee6c3766dc2221a64
F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e
F src/test_malloc.c 3f5903a1528fd32fe4c472a3bd0259128d8faaef
F src/test_malloc.c 6982a357a6a6c24f281b91c89303a5c31075c392
F src/test_multiplex.c ac0fbc1748e5b86a41a1d7a84654fae0d53a881d
F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d
F src/test_multiplex.h 9b63b95f07acedee425fdfe49a47197c9bf5f9d8
F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e
F src/test_onefile.c 0396f220561f3b4eedc450cef26d40c593c69a25
F src/test_osinst.c 90a845c8183013d80eccb1f29e8805608516edba
F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00
F src/test_quota.c 8ab295092c70903ca6f3209fa4c75f5cb6c1bf8e
F src/test_quota.c 0e0e2e3bf6766b101ecccd8c042b66e44e9be8f5
F src/test_quota.h 8761e463b25e75ebc078bd67d70e39b9c817a0cb
F src/test_rtree.c aba603c949766c4193f1068b91c787f57274e0d9
F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0
F src/test_server.c 2f99eb2837dfa06a4aacf24af24c6affdf66a84f
F src/test_spellfix.c 76dd8d3111d2f5354c374f71fa23b752bd0b029c
F src/test_sqllog.c 8acb843ddb9928dea8962e31bb09f421a72ffccb
F src/test_stat.c d1569c7a4839f13e80187e2c26b2ab4da2d03935
F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd
F src/test_syscall.c a992d8c80ea91fbf21fb2dd570db40e77dd7e6ae
F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa
F src/test_thread.c e286f2173563f2a1747c24bcda6b9d030bf4f4e4
F src/test_vfs.c c6260ef238c1142c8f8bd402db02216afd182ae3
F src/test_vfstrace.c f60e12754e65c05386aab59db8d2ae086314138d
F src/test_vfstrace.c 34b544e80ba7fb77be15395a609c669df2e660a2
F src/test_wholenumber.c 3d2b9ed1505c40ad5c5ca2ad16ae7a289d6cc251
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/tokenize.c 1e86210d3976717a19238ea7b047fac481fe8c12
F src/trigger.c 3f258307040173aff383eb23fb74c44fe829078c
F src/trigger.c cd95ac64efa60e39faf9b5597443192ff27a22fa
F src/update.c 28d2d098b43a2c70dae399896ea8a02f622410ef
F src/utf.c 890c67dcfcc7a74623c95baac7535aadfe265e84
F src/utf.c 8d819e2e5104a430fc2005f018db14347c95a38f
F src/util.c 0af2e515dc0dabacec931bca39525f6c3f1c5455
F src/vacuum.c 587a52bb8833d7ac15af8916f25437e2575028bd
F src/vdbe.c 9c524bded348fd0a53adc19f2d7cad76ba3442b2
F src/vdbe.h 18f581cac1f4339ec3299f3e0cc6e11aec654cdb
F src/vdbeInt.h 986b6b11a13c517337355009e5438703ba5b0a40
F src/vdbeapi.c 88ea823bbcb4320f5a6607f39cd7c2d3cc4c26b1
F src/vdbeaux.c 9c293fd3040211687e83d5d27bef2382933146c2
F src/vacuum.c 2727bdd08847fcb6b2d2da6d14f018910e8645d3
F src/vdbe.c f51eb3207594703d24e91335cb16906e894b48aa
F src/vdbe.h b52887278cb173e66188da84dfab216bea61119d
F src/vdbeInt.h 79abf9b31be406d35ca77d6999cb2d42aaf91e78
F src/vdbeapi.c 4c2418161cf45392ba76a7ca92f9a5f06b96f89c
F src/vdbeaux.c 7658c5d9db838db5780f6a1c4d1280d0646e3569
F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb
F src/vdbemem.c cb55e84b8e2c15704968ee05f0fae25883299b74
F src/vdbesort.c 0dc1b274dcb4d4c8e71b0b2b15261f286caba39b
F src/vdbesort.c c61ca318681c0e7267da8be3abfca8469652a7e9
F src/vdbetrace.c 8bd5da325fc90f28464335e4cc4ad1407fe30835
F src/vtab.c d2c54fd22aa83eb34fc6f7cd9b097f2fc2b1e9de
F src/wal.c 5acb3e7bbd31f10ba39acad9ce6b399055337a9d
F src/vtab.c b05e5f1f4902461ba9f5fc49bb7eb7c3a0741a83
F src/wal.c f5c7b5027d0ed0e9bc9afeb4a3a8dfea762ec7d2
F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6
F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b
F src/where.c e74f9ed463b0153e7f2a0e5f291c2be16ae76b35
F src/where.c 613a89f1c9cf965b66e9d90f7f3e7a870596ac80
F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/aggnested.test 0be144b453e0622a085fae8665c32f5676708e00
F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
F test/all.test 52fc8dee494092031a556911d404ca30a749a30b
F test/alter.test 57d96ec9b320bd07af77567034488dcb6642c748
@ -266,7 +265,7 @@ F test/analyze.test f8ab7d15858b4093b06caf5e57e2a5ff7104bdae
F test/analyze3.test c3c7f6c3951900c188cf94b2d5ee3246d6b3ff89
F test/analyze4.test 757b37875cf9bb528d46f74497bc789c88365045
F test/analyze5.test 713354664c5ff1853ab2cbcb740f0cf5cb7c802e
F test/analyze6.test bd3625806a5ee6f7bef72d06295bd319f0290af2
F test/analyze6.test aa8dae5066bbed35c5f45a507fb87f2d342f2c99
F test/analyze7.test d3587aa5af75c9048d031b94fceca2534fa75d1d
F test/analyze8.test 4ca170de2ba30ccb1af2c0406803db72262f9691
F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b
@ -285,20 +284,21 @@ F test/auth2.test 270baddc8b9c273682760cffba6739d907bd2882
F test/auth3.test a4755e6a2a2fea547ffe63c874eb569e60a28eb5
F test/autoinc.test bd30d372d00045252f6c2e41b5f41455e1975acf
F test/autoindex1.test 058d0b331ae6840a61bbee910d8cbae27bfd5991
F test/autovacuum.test fcaf4616ae5bb18098db1cb36262565e5c841c3c
F test/autovacuum.test 9f22a7733f39c56ef6a5665d10145ac25d8cb574
F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4
F test/avtrans.test 0252654f4295ddda3b2cce0e894812259e655a85
F test/backcompat.test bccbc64769d9c755ad65ee7c2f7336b86e3cc0c8
F test/backcompat.test ecd841f3a3bfb81518721879cc56a760670e3198
F test/backup.test c9cdd23a495864b9edf75a9fa66f5cb7e10fcf62
F test/backup2.test 34986ef926ea522911a51dfdb2f8e99b7b75ebcf
F test/backup4.test 4d90389daeb781fe718816a4fc836ad1b06791d8
F test/backup_ioerr.test 40d208bc9224b666ee3ed423f49bc9062a36a9d0
F test/backup_malloc.test 7162d604ec2b4683c4b3799a48657fb8b5e2d450
F test/badutf.test d5360fc31f643d37a973ab0d8b4fb85799c3169f
F test/badutf2.test f5bc7f2d280670ecd79b9cf4f0f1760c607fe51f
F test/bc_common.tcl 5c8689cc6d2fb44b7c0968ae4f85eb26d50022fa
F test/between.test 16b1776c6323faadb097a52d673e8e3d8be7d070
F test/bigfile.test 8f88b5ef065e31c615c49d725ede94155fbe9609
F test/bigfile2.test 8a3c242c3c3481e7cde5a6ef2a66fdc367a095f7
F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59
F test/bigfile2.test 7c79f1ef0c6c2c2bc1e7bd895596fab32bfb4796
F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747
F test/bind.test 3c7b320969000c441a70952b0b15938fbb66237c
F test/bindxfer.test efecd12c580c14df5f4ad3b3e83c667744a4f7e0
@ -323,11 +323,11 @@ F test/capi3e.test f7408dda65c92b9056199fdc180f893015f83dde
F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3
F test/check.test 193f47ed43a8d29aca12b30cd30ceb105fbe710d
F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91
F test/collate1.test e3eaa48c21e150814be1a7b852d2a8af24458d04
F test/collate1.test fd02c4d8afc71879c4bb952586389961a21fb0ce
F test/collate2.test 04cebe4a033be319d6ddbb3bbc69464e01700b49
F test/collate3.test d28d2cfab2c3a3d4628ae4b2b7afc9965daa3b4c
F test/collate4.test 3d3f123f83fd8ccda6f48d617e44e661b9870c7d
F test/collate5.test 67f1d3e848e230ff4802815a79acb0a8b5e69bd7
F test/collate4.test d37682293d3c32223dec2e6afdeaf9de18415248
F test/collate5.test 65d928034d30d2d263a80f6359f7549ee1598ec6
F test/collate6.test 8be65a182abaac8011a622131486dafb8076e907
F test/collate7.test 8ec29d98f3ee4ccebce6e16ce3863fb6b8c7b868
F test/collate8.test df26649cfcbddf109c04122b340301616d3a88f6
@ -348,17 +348,18 @@ F test/corrupt9.test 959179e68dc0b7b99f424cf3e0381c86dcdd0112
F test/corruptA.test fafa652aa585753be4f6b62ff0bb250266eaf7ce
F test/corruptB.test 20d4a20cbed23958888c3e8995b424a47223d647
F test/corruptC.test 62a767fe64acb1975f58cc6171192839c783edbb
F test/corruptD.test 99b1999dbfa7cc04aaeac9d695a2445d4e7c7458
F test/corruptE.test 1b9eb20a8711251ce57b44a257e241085b39b52d
F test/corruptD.test 3b09903a2e2fe07ecafe775fea94177f8a4bb34f
F test/corruptE.test d3a3d7e864a95978195741744dda4abfd8286018
F test/corruptF.test 984b1706c9c0e4248141b056c21124612628d12e
F test/count.test 454e1ce985c94d13efeac405ce54439f49336163
F test/coveridxscan.test cdb47d01acc4a634a34fd25abe85189e0d0f1e62
F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f
F test/crash2.test 5b14d4eb58b880e231361d3b609b216acda86651
F test/crash3.test 8f5de9d32ab9ab95475a9efe7f47a940aa889418
F test/crash4.test fe2821baf37168dc59dd733dcf7dba2a401487bc
F test/crash5.test 13b9ca94e048194bca070e26160ce76b406c56be
F test/crash6.test 4c56f1e40d0291e1110790a99807aa875b1647ba
F test/crash7.test 6c6a369af266af2ef50ab34df8f94d719065e2c1
F test/crash7.test 1a194c4900a255258cf94b7fcbfd29536db572df
F test/crash8.test 38767cb504bbe491de6be4a7006b154973a2309f
F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8
@ -366,7 +367,7 @@ F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c
F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47
F test/date.test f3228180c87bbe5d39c9397bf001c0095c3821b9
F test/dbstatus.test 207e5b63fcb7b9c3bb8e1fdf38ebd4654ad0e54b
F test/dbstatus2.test b1de8250fde1f3474d6b86f0e89de38d84794f56
F test/dbstatus2.test bf7396af964b89e39435babbcdf296ae8fc5f10a
F test/default.test 6faf23ccb300114924353007795aa9a8ec0aa9dc
F test/delete.test a065b05d2ebf60fd16639c579a4adfb7c381c701
F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa
@ -375,28 +376,28 @@ F test/descidx1.test 533dcbda614b0463b0ea029527fd27e5a9ab2d66
F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d
F test/descidx3.test fe720e8b37d59f4cef808b0bf4e1b391c2e56b6f
F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e
F test/distinct.test da36612d05b9ed17e0425d4bfd7ab978d28a7e46
F test/distinct.test 84da1414b2e6887fffd5ed571311b344c5b082ce
F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376
F test/e_createtable.test 48598b15e8fe6554d301e7b65a10c9851f177e84
F test/e_createtable.test 0a2465736199cb5e084645a8714ee04299b81721
F test/e_delete.test 89aa84d3d1bd284a0689ede04bce10226a5aeaa5
F test/e_droptrigger.test afd5c4d27dec607f5997a66bf7e2498a082cb235
F test/e_dropview.test 583411e470458c5d76148542cfb5a5fa84c8f93e
F test/e_expr.test 5489424d3d9a452ac3701cdf4b680ae31a157894
F test/e_fkey.test 057eed81a41a2b21b1790032f4e8aaba0b2b0e17
F test/e_fkey.test a79ab1d3213c7ac64621eec28f8e8bb219775445
F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459
F test/e_insert.test c6ac239a97cb16dfbd0c16496f8cd871b4068c0c
F test/e_insert.test d5331cc95e101af2508159fc98b6801631659ffe
F test/e_reindex.test dfedfc32c5a282b0596c6537cbcd4217fbb1a216
F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6
F test/e_select.test f5d4b81205701deacfae42051ae200969c41d2c0
F test/e_select.test 07e8d81268ba1ffcaf1dc4bec48956af150c42f9
F test/e_select2.test 5c3d3da19c7b3e90ae444579db2b70098599ab92
F test/e_update.test 161d5dc6a3ed9dd08f5264d13e20735d7a89f00c
F test/e_uri.test 9e190ca799d9190eec6e43f2aadf1d10c06a57a3
F test/e_uri.test bc240fbc6cbbbdff832ee05858432a25961ab36a
F test/e_vacuum.test 331da289ae186656cf5f2eb27f577a89c0c221af
F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea
F test/enc2.test 796c59832e2b9a52842f382ffda8f3e989db03ad
F test/enc3.test 90683ad0e6ea587b9d5542ca93568af9a9858c40
F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020
F test/eqp.test 6a389bba6ea113fd5179515001be788a38d53ec7
F test/eqp.test 46aa946dd55c90635327898275d3e533d23a9845
F test/errmsg.test 3bb606db9d040cc6854459f8f5e5a2bcd9b7fd2a
F test/eval.test bc269c365ba877554948441e91ad5373f9f91be3
F test/exclusive.test a1b324cb21834a490cd052d409d34789cfef57cb
@ -405,7 +406,7 @@ F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
F test/exists.test 8f7b27b61c2fbe5822f0a1f899c715d14e416e30
F test/expr.test 67c9fd6f8f829e239dc8b0f4a08a73c08b09196d
F test/fallocate.test b5d34437bd7ab01d41b1464b8117aefd4d32160e
F test/filectrl.test f0327bd804d9c7bd048fa7a151c5eab8e27df42b
F test/filectrl.test 14fa712e42c4cb791e09dfd58a6a03efb47ef13a
F test/filefmt.test ffa17b5aebc3eb4b1e3be1ccb5ee906ffbd97f6e
F test/fkey1.test 01c7de578e11747e720c2d9aeef27f239853c4da
F test/fkey2.test 080969fe219b3b082b0e097ac18c6af2e5b0631f
@ -471,7 +472,7 @@ F test/fts3aux1.test 0b02743955d56fc0d4d66236a26177bd1b726de0
F test/fts3b.test e93bbb653e52afde110ad53bbd793f14fe7a8984
F test/fts3c.test fc723a9cf10b397fdfc2b32e73c53c8b1ec02958
F test/fts3comp1.test a0f5b16a2df44dd0b15751787130af2183167c0c
F test/fts3conf.test 8e65ea56f88ced6cdd2252bdddb1a8327ae5af7e
F test/fts3conf.test ee8500c86dd58ec075e8831a1e216a79989436de
F test/fts3corrupt.test 7b0f91780ca36118d73324ec803187208ad33b32
F test/fts3corrupt2.test 6d96efae2f8a6af3eeaf283aba437e6d0e5447ba
F test/fts3cov.test e0fb00d8b715ddae4a94c305992dfc3ef70353d7
@ -486,7 +487,7 @@ F test/fts3fault.test cb72dccb0a3b9f730f16c5240f3fcb9303eb1660
F test/fts3fault2.test 3198eef2804deea7cac8403e771d9cbcb752d887
F test/fts3first.test dbdedd20914c8d539aa3206c9b34a23775644641
F test/fts3malloc.test b86ea33db9e8c58c0c2f8027a9fcadaf6a1568be
F test/fts3matchinfo.test 15edde2c4d373d60449658176af7164d622a62f0
F test/fts3matchinfo.test ecb08f586d027eb03941bcfcded6cb9d8ccb3a66
F test/fts3near.test 2e318ee434d32babd27c167142e2b94ddbab4844
F test/fts3prefix.test b36d4f00b128a51e7b386cc013a874246d9d7dc1
F test/fts3prefix2.test 477ca96e67f60745b7ac931cfa6e9b080c562da5
@ -503,6 +504,7 @@ F test/fts4merge.test c424309743fdd203f8e56a1f1cd7872cd66cc0ee
F test/fts4merge2.test 5faa558d1b672f82b847d2a337465fa745e46891
F test/fts4merge3.test aab02a09f50fe6baaddc2e159c3eabc116d45fc7
F test/fts4unicode.test aad033abdcfa0f87ce5f56468f59fdf2a0acbcef
F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d
F test/func.test 0d89043dab9a8853358d14c68e028ee0093bf066
F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f
F test/func3.test 001021e5b88bd02a3b365a5c5fd8f6f49d39744a
@ -512,7 +514,7 @@ F test/fuzz2.test 207d0f9d06db3eaf47a6b7bfc835b8e2fc397167
F test/fuzz3.test aec64345184d1662bd30e6a17851ff659d596dc5
F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b
F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26
F test/fuzzer1.test 69cf1036b92fd3b8e1fd65bef4d7ee3f085c28fb
F test/fuzzer1.test a2e93bb1e19513dd6bf9c63d3d7c4673c983ca19
F test/fuzzerfault.test ff2282c81797b6a355f0748d8b54c7287c5d2b25
F test/hook.test 5f3749de6462a6b87b4209b74adf7df5ac2df639
F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4
@ -520,7 +522,8 @@ F test/in.test 5941096407d8c133b9eff15bd3e666624b6cbde3
F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75
F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0
F test/in4.test 64f3cc1acde1b9161ccdd8e5bde3daefdb5b2617
F test/incrblob.test 26fde912a1e0aff158b3a84ef3b265f046aad3be
F test/in5.test 99f9a40af01711b06d2d614ecfe96129f334fba3
F test/incrblob.test 34765fa6fb5d8e0f256fc7d6497c04b205398849
F test/incrblob2.test edc3a96e557bd61fb39acc8d2edd43371fbbaa19
F test/incrblob3.test aedbb35ea1b6450c33b98f2b6ed98e5020be8dc7
F test/incrblob4.test 09be37d3dd996a31ea6993bba7837ece549414a8
@ -542,9 +545,10 @@ F test/insert2.test 4f3a04d168c728ed5ec2c88842e772606c7ce435
F test/insert3.test 1b7db95a03ad9c5013fdf7d6722b6cd66ee55e30
F test/insert4.test 87f6798f31d60c4e177622fcc3663367e6ecbd90
F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6
F test/instr.test a34e1d46a9eefb098a7167ef0e730a4a3d82fba0
F test/intarray.test 066b7d7ac38d25bf96f87f1b017bfc687551cdd4
F test/interrupt.test 42e7cf98646fd9cb4a3b131a93ed3c50b9e149f1
F test/intpkey.test 537669fd535f62632ca64828e435b9e54e8d677f
F test/interrupt.test dfe9a67a94b0b2d8f70545ba1a6cca10780d71cc
F test/intpkey.test 7af30f6ae852d8d1c2b70e4bf1551946742e92d8
F test/io.test 36d251507d72e92b965fb2f0801c2f0b56335bcf
F test/ioerr.test 40bb2cfcab63fb6aa7424cd97812a84bc16b5fb8
F test/ioerr2.test 9d71166f8466eda510f1af6137bdabaa82b5408d
@ -566,12 +570,12 @@ F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
F test/keyword1.test a2400977a2e4fde43bf33754c2929fda34dbca05
F test/lastinsert.test 474d519c68cb79d07ecae56a763aa7f322c72f51
F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
F test/like.test 7b4aaa4a8192fdec90e0a905984c92a688c51e48
F test/like.test 0e5412f4dac4a849f613e1ef8b529d56a6e31d08
F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da
F test/limit.test 2db7b3b34fb925b8e847d583d2eb67531d0ce67e
F test/loadext.test 2b5e249c51c986a5aff1f0950cf7ba30976c8f22
F test/loadext2.test 0bcaeb4d81cd5b6e883fdfea3c1bdbe1f173cbca
F test/lock.test db74fdf5a73bad29ab3d862ea78bf1068972cc1d
F test/lock.test 87af515b0c4cf928576d0f89946d67d7c265dfb4
F test/lock2.test 5242d8ac4e2d59c403aebff606af449b455aceff
F test/lock3.test f271375930711ae044080f4fe6d6eda930870d00
F test/lock4.test e175ae13865bc87680607563bafba21f31a26f12
@ -583,7 +587,7 @@ F test/lookaside.test 93f07bac140c5bb1d49f3892d2684decafdc7af2
F test/main.test 39c4bb8a157f57298ed1659d6df89d9f35aaf2c8
F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9
F test/malloc.test bc745155ff4252d4f35ec8316625b0dfe2abc659
F test/malloc3.test de8eca0c3e748878845fdca3663ec4b642073caf
F test/malloc3.test 3e9eb921c4314acf4fb64230868fdb2e1ce60eea
F test/malloc4.test 957337613002b7058a85116493a262f679f3a261
F test/malloc5.test a577cbbcc1594c7763b9b3515b3633555751c7f0
F test/malloc6.test 2f039d9821927eacae43e1831f815e157659a151
@ -609,8 +613,8 @@ F test/memdb.test 708a028d6d373e5b3842e4bdc8ba80998c9a4da6
F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2
F test/memsubsys1.test a8f9e37567453a5d1d9d37ec102d4d88ab6be33f
F test/memsubsys2.test 3a1c1a9de48e5726faa85108b02459fae8cb9ee9
F test/minmax.test 722d80816f7e096bf2c04f4111f1a6c1ba65453d
F test/minmax2.test 33504c01a03bd99226144e4b03f7631a274d66e0
F test/minmax.test c61518429e66e228efc79661fbd2dc3e4924ec44
F test/minmax2.test b44bae787fc7b227597b01b0ca5575c7cb54d3bc
F test/minmax3.test cc1e8b010136db0d01a6f2a29ba5a9f321034354
F test/minmax4.test 536a3360470633a177e42fbc19660d146b51daef
F test/misc1.test 889b40722442380a2f6575f30831b32b2372d70e
@ -633,8 +637,10 @@ F test/notify3.test a86259abbfb923aa27d30f0fc038c88e5251488a
F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347
F test/null.test a8b09b8ed87852742343b33441a9240022108993
F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394
F test/orderby1.test f33968647da5c546528fe4d2bf86c6a6a2e5a7ae
F test/orderby2.test bc11009f7cd99d96b1b11e57b199b00633eb5b04
F test/oserror.test 50417780d0e0d7cd23cf12a8277bb44024765df3
F test/pager1.test 2163c6ef119f497a71a84137c957c63763e640ab
F test/pager1.test f4c57e14583da2183fe31555c67fb32feda96092
F test/pager2.test 745b911dde3d1f24ae0870bd433dfa83d7c658c1
F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f
F test/pagerfault.test 452f2cc23e3bfcfa935f4442aec1da4fe1dc0442
@ -644,7 +650,7 @@ F test/pageropt.test 9191867ed19a2b3db6c42d1b36b6fbc657cd1ab0
F test/pagesize.test 1dd51367e752e742f58e861e65ed7390603827a0
F test/pcache.test 065aa286e722ab24f2e51792c1f093bf60656b16
F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
F test/permutations.test 1a8ac849b659445a0b3883caf42fa2c2a289f4a1
F test/permutations.test 360b92859c0af814b3fe10b68746936389606501
F test/pragma.test a62f73293b0f0d79b0c87f8dd32d46fe53b0bd17
F test/pragma2.test 3a55f82b954242c642f8342b17dffc8b47472947
F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552
@ -660,7 +666,7 @@ F test/randexpr1.test eda062a97e60f9c38ae8d806b03b0ddf23d796df
F test/rdonly.test c267d050a1d9a6a321de502b737daf28821a518d
F test/reindex.test 44edd3966b474468b823d481eafef0c305022254
F test/releasetest.mk 2eced2f9ae701fd0a29e714a241760503ccba25a
F test/releasetest.tcl e48fd8e0e8abad89f30e08620790533ae4e02010
F test/releasetest.tcl 06d289d8255794073a58d2850742f627924545ce
F test/rollback.test a1b4784b864331eae8b2a98c189efa2a8b11ff07
F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81
F test/rowid.test f777404492adb0e00868fd706a3721328fd3af48
@ -699,9 +705,10 @@ F test/shared4.test 72d90821e8d2fc918a08f16d32880868d8ee8e9d
F test/shared6.test 866bb4982c45ce216c61ded5e8fde4e7e2f3ffa9
F test/shared7.test 960760bc8d03e1419e70dea69cf41db62853616e
F test/shared8.test b27befbefbe7f4517f1d6b7ff8f64a41ec74165d
F test/shared_err.test 91e26ec4f3fbe07951967955585137e2f18993de
F test/shared9.test 5f2a8f79b4d6c7d107a01ffa1ed05ae7e6333e21
F test/shared_err.test 0079c05c97d88cfa03989b7c20a8b266983087aa
F test/sharedlock.test ffa0a3c4ac192145b310f1254f8afca4d553eabf
F test/shell1.test 9895ee3013742a02e5afd8d77793729967ffd195
F test/shell1.test b7896eb84028f3bc8300caf1fc796a73728aad0b
F test/shell2.test 037d6ad16e873354195d30bb2dc4b5321788154a
F test/shell3.test 9196c42772d575685e722c92b4b39053c6ebba59
F test/shell4.test aa4eef8118b412d1a01477a53426ece169ea86a9
@ -722,10 +729,10 @@ F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
F test/spellfix.test 2953e9da0e46dab5f83059ef6bfdebca66e13418
F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298
F test/stat.test 08e8185b3fd5b010c90d7ad82b9dd4ea1cbf14b0
F test/stat.test be8d477306006ec696bc86757cfb34bec79447ce
F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9
F test/subquery.test d4aea23ac267463d4aa604bf937c3992347b20f7
F test/subquery2.test edcad5c118f0531c2e21bf16a09bbb105252d4cd
F test/subquery2.test 91e1e364072aeff431d1f9689b15147e421d88c7
F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4
F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a
F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2
@ -734,12 +741,12 @@ F test/syscall.test bea9bf329bff733c791310244617c2a76974e64a
F test/sysfault.test c79441d88d23696fbec7b147dba98d42a04f523f
F test/table.test a59d985ca366e39b17b175f387f9d5db5a18d4e2
F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
F test/tclsqlite.test 952b772830bd380c9b5f58c03fb374189be53828
F test/tclsqlite.test 37a61c2da7e3bfe3b8c1a2867199f6b860df5d43
F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c
F test/temptable.test 51edd31c65ed1560dd600b1796e8325df96318e2
F test/temptrigger.test 26670ed7a39cf2296a7f0a9e0a1d7bdb7abe936d
F test/tester.tcl 2665f64c9ce71944b4d41269114e658fb81bda05
F test/thread001.test 7cc2ce08f9cde95964736d11e91f9ab610f82f91
F test/tester.tcl 2f383e811010b05a83c0f00fc168cae1dd63a6d9
F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5
F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
F test/thread004.test f51dfc3936184aaf73ee85f315224baad272a87f
@ -755,34 +762,35 @@ F test/tkt-26ff0c2d1e.test 888324e751512972c6e0d1a09df740d8f5aaf660
F test/tkt-2a5629202f.test 1ab32e084e9fc3d36be6dee2617530846a0eb0b6
F test/tkt-2d1a5c67d.test b028a811049eb472cb2d3a43fc8ce4f6894eebda
F test/tkt-2ea2425d34.test 1cf13e6f75d149b3209a0cb32927a82d3d79fb28
F test/tkt-31338dca7e.test 1f714c14b6682c5db715e0bda347926a3456f7a9
F test/tkt-31338dca7e.test 6fb8807851964da0d24e942f2e19c7c705b9fb58
F test/tkt-313723c356.test c47f8a9330523e6f35698bf4489bcb29609b53ac
F test/tkt-385a5b56b9.test 8eb87c4bbcc3fd4f33d73719de7e9d64973fa196
F test/tkt-385a5b56b9.test 7782a382912a51f09f1d1a1442bca1e75f9c549b
F test/tkt-38cb5df375.test f3cc8671f1eb604d4ae9cf886ed4366bec656678
F test/tkt-3998683a16.test 6d1d04d551ed1704eb3396ca87bb9ccc8c5c1eb7
F test/tkt-3a77c9714e.test 32bb28afa8c63fc76e972e996193139b63551ed9
F test/tkt-3fe897352e.test 10de1a67bd5c66b238a4c96abe55531b37bb4f00
F test/tkt-4a03edc4c8.test 2865e4edbc075b954daa82f8da7cc973033ec76e
F test/tkt-54844eea3f.test a12b851128f46a695e4e378cca67409b9b8f5894
F test/tkt-5d863f876e.test 884072c2de496ddbb90c387c9ebc0d4f44a91b8e
F test/tkt-5d863f876e.test c9f36ca503fa154a3655f92a69d2c30da1747bfa
F test/tkt-5e10420e8d.test 904d1687b3c06d43e5b3555bbcf6802e7c0ffd84
F test/tkt-5ee23731f.test 9db6e1d7209dc0794948b260d6f82b2b1de83a9f
F test/tkt-752e1646fc.test ea78d88d14fe9866bdd991c634483334639e13bf
F test/tkt-78e04e52ea.test ab52f0c1e2de6e46c910f4cc16b086bba05952b7
F test/tkt-78e04e52ea.test 703e0bfb23d543edf0426a97e3bbd0ca346508ec
F test/tkt-7bbfb7d442.test dfa5c8097a8c353ae40705d6cddeb1f99c18b81a
F test/tkt-80ba201079.test 9eb040d81c404f56838a6af93593f42790def63f
F test/tkt-80ba201079.test 105a721e6aad0ae3c5946d7615d1e4d03f6145b8
F test/tkt-80e031a00f.test 9a154173461a4dbe2de49cda73963e04842d52f7
F test/tkt-8454a207b9.test c583a9f814a82a2b5ba95207f55001c9f0cd816c
F test/tkt-91e2e8ba6f.test 08c4f94ae07696b05c9b822da0b4e5337a2f54c5
F test/tkt-94c04eaadb.test fa9c71192f7e2ea2d51bf078bc34e8da6088bf71
F test/tkt-9d68c883.test 458f7d82a523d7644b54b497c986378a7d8c8b67
F test/tkt-a7b7803e.test 159ef554234fa1f9fb318c751b284bd1cf858da4
F test/tkt-b1d3a2e531.test 610ef582413171b379652663111b1f996d9f8f78
F test/tkt-b351d95f9.test d14a503c414c5c58fdde3e80f9a3cfef986498c0
F test/tkt-b72787b1.test a95e8cdad0b98af1853ac7f0afd4ab27b77bf5f3
F test/tkt-bd484a090c.test 60460bf946f79a79712b71f202eda501ca99b898
F test/tkt-bdc6bbbb38.test fc38bb09bdd440e3513a1f5f98fc60a075182d7d
F test/tkt-c48d99d690.test bed446e3513ae10eec1b86fdd186ef750226c408
F test/tkt-cbd054fa6b.test bd9fb546f63bc0c79d1776978d059fa51c5b1c63
F test/tkt-cbd054fa6b.test 9c27ed07b333eed458e5d4543f91ecdcf05aeb19
F test/tkt-d11f09d36e.test fb44f7961aa6d4b632fb7b9768239832210b5fc7
F test/tkt-d635236375.test 9d37e988b47d87505bc9445be0ca447002df5d09
F test/tkt-d82e3f3721.test bcc0dfba658d15bab30fd4a9320c9e35d214ce30
@ -823,7 +831,7 @@ F test/tkt2686.test 6ee01c9b9e9c48f6d3a1fdd553b1cc4258f903d6
F test/tkt2767.test 569000d842678f9cf2db7e0d1b27cbc9011381b0
F test/tkt2817.test f31839e01f4243cff7399ef654d3af3558cb8d8d
F test/tkt2820.test 39940276b3436d125deb7d8ebeee053e4cf13213
F test/tkt2822.test a2b27a58df62d1b2e712f91dbe42ad3b7e0e77cc
F test/tkt2822.test f391776423a7c0d0949edfce375708bfb0f3141e
F test/tkt2832.test a9b0b74a02dca166a04d9e37739c414b10929caa
F test/tkt2854.test e432965db29e27e16f539b2ba7f502eb2ccc49af
F test/tkt2920.test a8737380e4ae6424e00c0273dc12775704efbebf
@ -846,7 +854,7 @@ F test/tkt3461.test 228ea328a5a21e8663f80ee3d212a6ad92549a19
F test/tkt3493.test 1686cbde85f8721fc1bdc0ee72f2ef2f63139218
F test/tkt3508.test d75704db9501625c7f7deec119fcaf1696aefb7d
F test/tkt3522.test 22ce2ebbcb04a6be56c0977d405c207967318fd6
F test/tkt3527.test 9e8f28a706c772d5a7cd1020c946fab6c74e3ae0
F test/tkt3527.test 1a6a48441b560bdc53aec581a868eb576234874d
F test/tkt3541.test 5dc257bde9bc833ab9cc6844bf170b998dbb950a
F test/tkt3554.test f599967f279077bace39220cbe76085c7b423725
F test/tkt3581.test 1966b7193f1e3f14951cce8c66907ae69454e9a3
@ -881,7 +889,7 @@ F test/trace2.test c1dc104a8d11a347c870cfea6235e3fc6f6cb06d
F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6
F test/trans2.test d5337e61de45e66b1fcbf9db833fa8c82e624b22
F test/trans3.test 373ac5183cc56be69f48ae44090e7f672939f732
F test/trigger1.test de42feb7cd442787d38185ae74f5a1d7afa400cb
F test/trigger1.test 30f343f91586765874a28ad539c06f5a5f049931
F test/trigger2.test 834187beafd1db383af0c659cfa49b0576832816
F test/trigger3.test d2c60d8be271c355d61727411e753181e877230a
F test/trigger4.test 74700b76ebf3947b2f7a92405141eb2cf2a5d359
@ -892,7 +900,7 @@ F test/trigger8.test 30cb0530bd7c4728055420e3f739aa00412eafa4
F test/trigger9.test 5b0789f1c5c4600961f8e68511b825b87be53e31
F test/triggerA.test e0aaba16d3547193d36bbd82a1b0ed75e9c88d40
F test/triggerB.test 56780c031b454abac2340dbb3b71ac5c56c3d7fe
F test/triggerC.test 4d4bdaf0230c206b50d350330107ef9802bc2d4f
F test/triggerC.test a7b4367392c755bc5fd5fff88011753e6b6afe90
F test/triggerD.test 8e7f3921a92a5797d472732108109e44575fa650
F test/tt3_checkpoint.c 415eccce672d681b297485fc20f44cdf0eac93af
F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff
@ -900,7 +908,7 @@ F test/types2.test 3555aacf8ed8dc883356e59efc314707e6247a84
F test/types3.test 99e009491a54f4dc02c06bdbc0c5eea56ae3e25a
F test/unique.test 083c7fff74695bcc27a71d75699deba3595bc9c2
F test/unixexcl.test a9870e46cc6f8390a494513d4f2bf55b5a8b3e46
F test/unordered.test f53095cee37851bf30130fa1bf299a8845e837bb
F test/unordered.test 93dce7b6c97a817a4fe26980c484605a4511f614
F test/update.test 8bc86fd7ef1a00014f76dc6a6a7c974df4aef172
F test/uri.test 63e03df051620a18f794b4f4adcdefb3c23b6751
F test/utf16align.test 54cd35a27c005a9b6e7815d887718780b6a462ae
@ -911,7 +919,7 @@ F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
F test/veryquick.test 7701bb609fe8bf6535514e8b849a309e8f00573b
F test/view.test b182a67ec43f490b156b5a710827a341be83dd17
F test/vtab1.test 10fb9e656fe4b318cd82ff1616a340acc01aac4b
F test/vtab1.test 36c9935e4be3b6350b31b6b697561b6fc3ab349a
F test/vtab2.test 7bcffc050da5c68f4f312e49e443063e2d391c0d
F test/vtab3.test baad99fd27217f5d6db10660522e0b7192446de1
F test/vtab4.test 942f8b8280b3ea8a41dae20e7822d065ca1cb275
@ -936,7 +944,8 @@ F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c
F test/wal5.test f58ed4b8b542f71c7441da12fbd769d99b362437
F test/wal6.test 2e3bc767d9c2ce35c47106148d43fcbd072a93b3
F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd
F test/wal8.test 5ab217d21f7e5e86af2933a4ffd0d8357cc2c0bd
F test/wal8.test b3ee739fe8f7586aaebdc2367f477ebcf3e3b034
F test/wal9.test 378e76a9ad09cd9bee06c172ad3547b0129a6750
F test/wal_common.tcl a98f17fba96206122eff624db0ab13ec377be4fe
F test/walbak.test b9f68e39646375c2b877be906babcc15d38b4877
F test/walbig.test f437473a16cfb314867c6b5d1dbcd519e73e3434
@ -953,7 +962,7 @@ F test/walro.test a31deb621033442a76c3a61e44929250d06f81b1
F test/walshared.test 6dda2293880c300baf5d791c307f653094585761
F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a
F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e
F test/where.test 4c9f69987ed2aa0173fa930f2b41ab9879478cd8
F test/where.test 9714e6f292d70c22e78e1cecb3d896457186b9b7
F test/where2.test 43d4becaf5a5df854e6c21d624a1cb84c6904554
F test/where3.test 667e75642102c97a00bf9b23d3cb267db321d006
F test/where4.test e9b9e2f2f98f00379e6031db6a6fca29bae782a2
@ -962,16 +971,18 @@ F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b
F test/where7.test 5c566388f0cc318b0032ce860f4ac5548e3c265a
F test/where8.test a6c740fd286d7883e274e17b6230a9d672a7ab1f
F test/where8m.test da346596e19d54f0aba35ebade032a7c47d79739
F test/where9.test ae98dc22ef9b6f2bc81e9f164e41b38faa9bda06
F test/where9.test bcab47eff78f1412a6aec1d6b8a3939d4a9db098
F test/whereA.test 24c234263c8fe358f079d5e57d884fb569d2da0a
F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5
F test/whereC.test 13ff5ec0dba407c0e0c075980c75b3275a6774e5
F test/whereD.test 11945e79899a97958d87d1e5ac6ae5abd827356b
F test/whereD.test 3f3ee93825c94804f1fc91eef2de0d365981759a
F test/whereE.test 7bd34945797efef15819368479bacc34215e4e1d
F test/whereF.test a0e296643cabe5278379bc1a0aa158cf3c54a1c9
F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31
F test/win32lock.test b2a539e85ae6b2d78475e016a9636b4451dc7fb9
F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688
F test/zerodamage.test 0de750389990b1078bab203c712dc3fefd1d8b82
F tool/build-all-msvc.bat 1a18aa39983ae7354d834bc55a850a54fc007576 x
F test/zerodamage.test e7f77fded01dfcdf92ac2c5400f1e35d7a21463c
F tool/build-all-msvc.bat 74fb6e5cca66ebdb6c9bbafb2f8b802f08146d38 x
F tool/build-shell.sh b64a481901fc9ffe5ca8812a2a9255b6cfb77381
F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2
F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b
@ -989,35 +1000,33 @@ F tool/mksqlite3c-noext.tcl 8bce31074e4cbe631bb7676526a048335f4c9f02
F tool/mksqlite3c.tcl 589c7f44e990be1b8443cfe4808dce392b0327fa
F tool/mksqlite3h.tcl 78013ad79a5e492e5f764f3c7a8ef834255061f8
F tool/mksqlite3internalh.tcl 3dca7bb5374cee003379b8cbac73714f610ef795
F tool/mkvsix.tcl 19b2ab9ea16445953a76568a5bbe4cb864f92dfe
F tool/mkvsix.tcl 0be7f7a591f1e83f9199cb82911b66668ca484c9
F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091
F tool/omittest.tcl 4665982e95a6e5c1bd806cf7bc3dea95be422d77
F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a
F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5
F tool/showdb.c 2e28d8e499b016485672e9a7ac65dacc0d28ff69
F tool/showdb.c aca2644aa4de7c0cad5821e50bbd55397e0974b8
F tool/showjournal.c b62cecaab86a4053d944c276bb5232e4d17ece02
F tool/showwal.c f09e5a80a293919290ec85a6a37c85a5ddcf37d9
F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe
F tool/space_used.tcl f714c41a59e326b8b9042f415b628b561bafa06b
F tool/spaceanal.tcl e42273000686a4afbf6a5e5d7fb12be65e92afb1
F tool/spaceanal.tcl 76f583a246a0b027f423252339e711f13198932e
F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355
F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c
F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43
F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d
F tool/symbols.sh fec58532668296d7c7dc48be9c87f75ccdb5814f
F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9
P 81fd941da62956e32d1c4ffcdb39abecba7a6f3b
R a82bf185a73888ab1f23d02429bade9e
T +bgcolor * #d0c0ff
T +sym-release *
T +sym-version-3.7.14.1 *
F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
P 3d0609c958040d049b86f69d750ffcef764417df
R 9f4348d1a37f598f7d9d8be10eff6aea
U drh
Z 002ec98f7f5b76deaac3a726393245f3
Z 2c8e31332e45b7b8f7af42318006a1b7

View File

@ -1 +1 @@
091570e46d04e84b67228e0bdbcd6e1fb60c6bdb
c0e09560d26f0a6456be9dd3447f5311eb4f238f

View File

@ -1,138 +0,0 @@
#!/bin/sh
#
# This script is used to compile SQLite and package everything up
# so that it is ready to move to the SQLite website.
#
# Set srcdir to the name of the directory that contains the publish.sh
# script.
#
srcdir=`echo "$0" | sed 's%\(^.*\)/[^/][^/]*$%\1%'`
# Get the makefile.
#
cp $srcdir/Makefile.linux-gcc ./Makefile
chmod +x $srcdir/install-sh
# Get the current version number - needed to help build filenames
#
VERS=`cat $srcdir/VERSION`
VERSW=`sed 's/\./_/g' $srcdir/VERSION`
echo "VERSIONS: $VERS $VERSW"
# Start by building an sqlite shell for linux.
#
make clean
make sqlite3.c
CFLAGS="-Os -DSQLITE_ENABLE_FTS3=0 -DSQLITE_ENABLE_RTREE=0"
CFLAGS="$CFLAGS -DSQLITE_THREADSAFE=0"
echo '***** '"COMPILING sqlite3-$VERS.bin..."
gcc $CFLAGS -Itsrc sqlite3.c tsrc/shell.c -o sqlite3 -ldl
strip sqlite3
mv sqlite3 sqlite3-$VERS.bin
gzip sqlite3-$VERS.bin
chmod 644 sqlite3-$VERS.bin.gz
mv sqlite3-$VERS.bin.gz doc
# Build the sqlite.so and tclsqlite.so shared libraries
# under Linux
#
TCLDIR=/home/drh/tcltk/846/linux/846linux
TCLSTUBLIB=$TCLDIR/libtclstub8.4g.a
CFLAGS="-Os -DSQLITE_ENABLE_FTS3=3 -DSQLITE_ENABLE_RTREE=1"
CFLAGS="$CFLAGS -DHAVE_LOCALTIME_R=1 -DHAVE_GMTIME_R=1"
CFLAGS="$CFLAGS -DSQLITE_ENABLE_COLUMN_METADATA=1"
echo '***** BUILDING shared libraries for linux'
gcc $CFLAGS -shared tclsqlite3.c $TCLSTUBLIB -o tclsqlite3.so -lpthread
strip tclsqlite3.so
chmod 644 tclsqlite3.so
mv tclsqlite3.so tclsqlite-$VERS.so
gzip tclsqlite-$VERS.so
mv tclsqlite-$VERS.so.gz doc
gcc $CFLAGS -shared sqlite3.c -o sqlite3.so -lpthread
strip sqlite3.so
chmod 644 sqlite3.so
mv sqlite3.so sqlite-$VERS.so
gzip sqlite-$VERS.so
mv sqlite-$VERS.so.gz doc
# Build the tclsqlite3.dll and sqlite3.dll shared libraries.
#
. $srcdir/mkdll.sh
echo '***** PACKAGING shared libraries for windows'
echo zip doc/tclsqlite-$VERSW.zip tclsqlite3.dll
zip doc/tclsqlite-$VERSW.zip tclsqlite3.dll
echo zip doc/sqlitedll-$VERSW.zip sqlite3.dll sqlite3.def
zip doc/sqlitedll-$VERSW.zip sqlite3.dll sqlite3.def
# Build the sqlite.exe executable for windows.
#
OPTS='-DSTATIC_BUILD=1 -DNDEBUG=1 -DSQLITE_THREADSAFE=0'
OPTS="$OPTS -DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_RTREE=1"
i386-mingw32msvc-gcc -Os $OPTS -Itsrc -I$TCLDIR sqlite3.c tsrc/shell.c \
-o sqlite3.exe
zip doc/sqlite-$VERSW.zip sqlite3.exe
# Build a source archive useful for windows.
#
make target_source
cd tsrc
echo '***** BUILDING preprocessed source archives'
rm fts[12]* icu*
rm -f ../doc/sqlite-source-$VERSW.zip
zip ../doc/sqlite-source-$VERSW.zip *
cd ..
cp tsrc/sqlite3.h tsrc/sqlite3ext.h .
cp tsrc/shell.c .
pwd
zip doc/sqlite-amalgamation-$VERSW.zip sqlite3.c sqlite3.h sqlite3ext.h shell.c sqlite3.def
# Construct a tarball of the source tree
#
echo '***** BUILDING source archive'
ORIGIN=`pwd`
cd $srcdir
chmod +x configure
cd ..
mv sqlite sqlite-$VERS
EXCLUDE=`find sqlite-$VERS -print | egrep '(www/|art/|doc/|contrib/|_FOSSIL_)' | sed 's,^, --exclude ,'`
echo "tar czf $ORIGIN/doc/sqlite-$VERS.tar.gz $EXCLUDE sqlite-$VERS"
tar czf $ORIGIN/doc/sqlite-$VERS.tar.gz $EXCLUDE sqlite-$VERS
mv sqlite-$VERS sqlite
cd $ORIGIN
#
# Build RPMS (binary) and Source RPM
#
# Make sure we are properly setup to build RPMs
#
echo "%HOME %{expand:%%(cd; pwd)}" > $HOME/.rpmmacros
echo "%_topdir %{HOME}/rpm" >> $HOME/.rpmmacros
mkdir $HOME/rpm
mkdir $HOME/rpm/BUILD
mkdir $HOME/rpm/SOURCES
mkdir $HOME/rpm/RPMS
mkdir $HOME/rpm/SRPMS
mkdir $HOME/rpm/SPECS
# create the spec file from the template
sed s/SQLITE_VERSION/$VERS/g $srcdir/spec.template > $HOME/rpm/SPECS/sqlite.spec
# copy the source tarball to the rpm directory
cp doc/sqlite-$VERS.tar.gz $HOME/rpm/SOURCES/.
# build all the rpms
rpm -ba $HOME/rpm/SPECS/sqlite.spec >& rpm-$vers.log
# copy the RPMs into the build directory.
mv $HOME/rpm/RPMS/i386/sqlite*-$vers*.rpm doc
mv $HOME/rpm/SRPMS/sqlite-$vers*.rpm doc
# Build the website
#
#cp $srcdir/../historical/* doc
#make doc
#cd doc
#chmod 644 *.gz

View File

@ -1,35 +0,0 @@
#!/bin/sh
#
# This script is used to compile SQLite and package everything up
# so that it is ready to move to the SQLite website.
#
# Set srcdir to the name of the directory that contains the publish.sh
# script.
#
srcdir=`echo "$0" | sed 's%\(^.*\)/[^/][^/]*$%\1%'`
# Get the makefile.
#
cp $srcdir/Makefile.linux-gcc ./Makefile
chmod +x $srcdir/install-sh
# Get the current version number - needed to help build filenames
#
VERS=`cat $srcdir/VERSION`
VERSW=`sed 's/\./_/g' $srcdir/VERSION`
echo "VERSIONS: $VERS $VERSW"
# Start by building an sqlite shell for linux.
#
make clean
make sqlite3.c
CFLAGS="-Os -DSQLITE_ENABLE_FTS3=1 -DSQLITE_THREADSAFE=0"
NAME=sqlite3-$VERS-osx-x86.bin
echo '***** '"COMPILING $NAME..."
gcc $CFLAGS -Itsrc sqlite3.c tsrc/shell.c -o $NAME -ldl
strip $NAME
chmod 644 $NAME
gzip $NAME
mkdir -p doc
mv $NAME.gz doc

View File

@ -414,7 +414,7 @@ void sqlite3AlterRenameTable(
assert( pSrc->nSrc==1 );
assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
pTab = sqlite3LocateTable(pParse, 0, pSrc->a[0].zName, pSrc->a[0].zDatabase);
pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);
if( !pTab ) goto exit_rename_table;
iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
zDb = db->aDb[iDb].zName;
@ -664,7 +664,7 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
** If there is a NOT NULL constraint, then the default value for the
** column must not be NULL.
*/
if( pCol->isPrimKey ){
if( pCol->colFlags & COLFLAG_PRIMKEY ){
sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column");
return;
}
@ -757,7 +757,7 @@ void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
assert( pParse->pNewTable==0 );
assert( sqlite3BtreeHoldsAllMutexes(db) );
if( db->mallocFailed ) goto exit_begin_add_column;
pTab = sqlite3LocateTable(pParse, 0, pSrc->a[0].zName, pSrc->a[0].zDatabase);
pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);
if( !pTab ) goto exit_begin_add_column;
#ifndef SQLITE_OMIT_VIRTUALTABLE

View File

@ -434,6 +434,7 @@ int sqlite3FixInit(
assert( db->nDb>iDb );
pFix->pParse = pParse;
pFix->zDb = db->aDb[iDb].zName;
pFix->pSchema = db->aDb[iDb].pSchema;
pFix->zType = zType;
pFix->pName = pName;
return 1;
@ -464,14 +465,15 @@ int sqlite3FixSrcList(
if( NEVER(pList==0) ) return 0;
zDb = pFix->zDb;
for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
if( pItem->zDatabase==0 ){
pItem->zDatabase = sqlite3DbStrDup(pFix->pParse->db, zDb);
}else if( sqlite3StrICmp(pItem->zDatabase,zDb)!=0 ){
if( pItem->zDatabase && sqlite3StrICmp(pItem->zDatabase, zDb) ){
sqlite3ErrorMsg(pFix->pParse,
"%s %T cannot reference objects in database %s",
pFix->zType, pFix->pName, pItem->zDatabase);
return 1;
}
sqlite3DbFree(pFix->pParse->db, pItem->zDatabase);
pItem->zDatabase = 0;
pItem->pSchema = pFix->pSchema;
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1;
if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1;

View File

@ -219,13 +219,16 @@ static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){
const int nCopy = MIN(nSrcPgsz, nDestPgsz);
const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz;
#ifdef SQLITE_HAS_CODEC
int nSrcReserve = sqlite3BtreeGetReserve(p->pSrc);
/* Use BtreeGetReserveNoMutex() for the source b-tree, as although it is
** guaranteed that the shared-mutex is held by this thread, handle
** p->pSrc may not actually be the owner. */
int nSrcReserve = sqlite3BtreeGetReserveNoMutex(p->pSrc);
int nDestReserve = sqlite3BtreeGetReserve(p->pDest);
#endif
int rc = SQLITE_OK;
i64 iOff;
assert( sqlite3BtreeGetReserveNoMutex(p->pSrc)>=0 );
assert( p->bDestLocked );
assert( !isFatalError(p->rc) );
assert( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) );
@ -410,7 +413,13 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
** same schema version.
*/
if( rc==SQLITE_DONE ){
rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1);
if( nSrcPage==0 ){
rc = sqlite3BtreeNewDb(p->pDest);
nSrcPage = 1;
}
if( rc==SQLITE_OK || rc==SQLITE_DONE ){
rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1);
}
if( rc==SQLITE_OK ){
if( p->pDestDb ){
sqlite3ResetAllSchemasOfConnection(p->pDestDb);
@ -444,6 +453,7 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
}else{
nDestTruncate = nSrcPage * (pgszSrc/pgszDest);
}
assert( nDestTruncate>0 );
sqlite3PagerTruncateImage(pDestPager, nDestTruncate);
if( pgszSrc<pgszDest ){
@ -462,7 +472,8 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
i64 iEnd;
assert( pFile );
assert( (i64)nDestTruncate*(i64)pgszDest >= iSize || (
assert( nDestTruncate==0
|| (i64)nDestTruncate*(i64)pgszDest >= iSize || (
nDestTruncate==(int)(PENDING_BYTE_PAGE(p->pDest->pBt)-1)
&& iSize>=PENDING_BYTE && iSize<=PENDING_BYTE+pgszDest
));

View File

@ -2200,6 +2200,24 @@ int sqlite3BtreeGetPageSize(Btree *p){
return p->pBt->pageSize;
}
#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_DEBUG)
/*
** This function is similar to sqlite3BtreeGetReserve(), except that it
** may only be called if it is guaranteed that the b-tree mutex is already
** held.
**
** This is useful in one special case in the backup API code where it is
** known that the shared b-tree mutex is held, but the mutex on the
** database handle that owns *p is not. In this case if sqlite3BtreeEnter()
** were to be called, it might collide with some other operation on the
** database handle that owns *p, causing undefined behaviour.
*/
int sqlite3BtreeGetReserveNoMutex(Btree *p){
assert( sqlite3_mutex_held(p->pBt->mutex) );
return p->pBt->pageSize - p->pBt->usableSize;
}
#endif /* SQLITE_HAS_CODEC || SQLITE_DEBUG */
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM)
/*
** Return the number of bytes of space at the end of every page that
@ -2513,6 +2531,20 @@ static int newDatabase(BtShared *pBt){
return SQLITE_OK;
}
/*
** Initialize the first page of the database file (creating a database
** consisting of a single page and no schema objects). Return SQLITE_OK
** if successful, or an SQLite error code otherwise.
*/
int sqlite3BtreeNewDb(Btree *p){
int rc;
sqlite3BtreeEnter(p);
p->pBt->nPage = 0;
rc = newDatabase(p->pBt);
sqlite3BtreeLeave(p);
return rc;
}
/*
** Attempt to start a new transaction. A write-transaction
** is started if the second argument is nonzero, otherwise a read-
@ -5256,7 +5288,7 @@ static int clearCell(MemPage *pPage, unsigned char *pCell){
return SQLITE_OK; /* No overflow pages. Return without doing anything */
}
if( pCell+info.iOverflow+3 > pPage->aData+pPage->maskPage ){
return SQLITE_CORRUPT; /* Cell extends past end of page */
return SQLITE_CORRUPT_BKPT; /* Cell extends past end of page */
}
ovflPgno = get4byte(&pCell[info.iOverflow]);
assert( pBt->usableSize > 4 );
@ -5712,7 +5744,7 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){
assert( pPage->nOverflow==1 );
/* This error condition is now caught prior to reaching this function */
if( pPage->nCell<=0 ) return SQLITE_CORRUPT_BKPT;
if( pPage->nCell==0 ) return SQLITE_CORRUPT_BKPT;
/* Allocate a new page. This page will become the right-sibling of
** pPage. Make the parent page writable, so that the new divider cell

View File

@ -71,6 +71,9 @@ int sqlite3BtreeMaxPageCount(Btree*,int);
u32 sqlite3BtreeLastPage(Btree*);
int sqlite3BtreeSecureDelete(Btree*,int);
int sqlite3BtreeGetReserve(Btree*);
#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_DEBUG)
int sqlite3BtreeGetReserveNoMutex(Btree *p);
#endif
int sqlite3BtreeSetAutoVacuum(Btree *, int);
int sqlite3BtreeGetAutoVacuum(Btree *);
int sqlite3BtreeBeginTrans(Btree*,int);
@ -114,6 +117,8 @@ void sqlite3BtreeTripAllCursors(Btree*, int);
void sqlite3BtreeGetMeta(Btree *pBtree, int idx, u32 *pValue);
int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value);
int sqlite3BtreeNewDb(Btree *p);
/*
** The second parameter to sqlite3BtreeGetMeta or sqlite3BtreeUpdateMeta
** should be one of the following values. The integer values are assigned

View File

@ -127,6 +127,7 @@ void sqlite3FinishCoding(Parse *pParse){
sqlite3 *db;
Vdbe *v;
assert( pParse->pToplevel==0 );
db = pParse->db;
if( db->mallocFailed ) return;
if( pParse->nested ) return;
@ -319,6 +320,31 @@ Table *sqlite3LocateTable(
return p;
}
/*
** Locate the table identified by *p.
**
** This is a wrapper around sqlite3LocateTable(). The difference between
** sqlite3LocateTable() and this function is that this function restricts
** the search to schema (p->pSchema) if it is not NULL. p->pSchema may be
** non-NULL if it is part of a view or trigger program definition. See
** sqlite3FixSrcList() for details.
*/
Table *sqlite3LocateTableItem(
Parse *pParse,
int isView,
struct SrcList_item *p
){
const char *zDb;
assert( p->pSchema==0 || p->zDatabase==0 );
if( p->pSchema ){
int iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema);
zDb = pParse->db->aDb[iDb].zName;
}else{
zDb = p->zDatabase;
}
return sqlite3LocateTable(pParse, isView, p->zName, zDb);
}
/*
** Locate the in-memory structure that describes
** a particular index given the name of that index
@ -1169,7 +1195,7 @@ void sqlite3AddPrimaryKey(
pTab->tabFlags |= TF_HasPrimaryKey;
if( pList==0 ){
iCol = pTab->nCol - 1;
pTab->aCol[iCol].isPrimKey = 1;
pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY;
}else{
for(i=0; i<pList->nExpr; i++){
for(iCol=0; iCol<pTab->nCol; iCol++){
@ -1178,7 +1204,7 @@ void sqlite3AddPrimaryKey(
}
}
if( iCol<pTab->nCol ){
pTab->aCol[iCol].isPrimKey = 1;
pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY;
}
}
if( pList->nExpr>1 ) iCol = -1;
@ -1295,10 +1321,7 @@ CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName){
pColl = sqlite3FindCollSeq(db, enc, zName, initbusy);
if( !initbusy && (!pColl || !pColl->xCmp) ){
pColl = sqlite3GetCollSeq(db, enc, pColl, zName);
if( !pColl ){
sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
}
pColl = sqlite3GetCollSeq(pParse, enc, pColl, zName);
}
return pColl;
@ -1997,6 +2020,7 @@ static void destroyTable(Parse *pParse, Table *pTab){
return;
}else{
int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
assert( iDb>=0 && iDb<pParse->db->nDb );
destroyRootPage(pParse, iLargest, iDb);
iDestroyed = iLargest;
}
@ -2114,8 +2138,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
assert( pParse->nErr==0 );
assert( pName->nSrc==1 );
if( noErr ) db->suppressErr++;
pTab = sqlite3LocateTable(pParse, isView,
pName->a[0].zName, pName->a[0].zDatabase);
pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]);
if( noErr ) db->suppressErr--;
if( pTab==0 ){
@ -2555,9 +2578,9 @@ Index *sqlite3CreateIndex(
** sqlite3FixSrcList can never fail. */
assert(0);
}
pTab = sqlite3LocateTable(pParse, 0, pTblName->a[0].zName,
pTblName->a[0].zDatabase);
if( !pTab || db->mallocFailed ) goto exit_create_index;
pTab = sqlite3LocateTableItem(pParse, 0, &pTblName->a[0]);
assert( db->mallocFailed==0 || pTab==0 );
if( pTab==0 ) goto exit_create_index;
assert( db->aDb[iDb].pSchema==pTab->pSchema );
}else{
assert( pName==0 );
@ -2668,10 +2691,8 @@ Index *sqlite3CreateIndex(
for(i=0; i<pList->nExpr; i++){
Expr *pExpr = pList->a[i].pExpr;
if( pExpr ){
CollSeq *pColl = pExpr->pColl;
/* Either pColl!=0 or there was an OOM failure. But if an OOM
** failure we have quit before reaching this point. */
if( ALWAYS(pColl) ){
CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr);
if( pColl ){
nExtra += (1 + sqlite3Strlen30(pColl->zName));
}
}
@ -2734,6 +2755,7 @@ Index *sqlite3CreateIndex(
const char *zColName = pListItem->zName;
Column *pTabCol;
int requestedSortOrder;
CollSeq *pColl; /* Collating sequence */
char *zColl; /* Collation sequence name */
for(j=0, pTabCol=pTab->aCol; j<pTab->nCol; j++, pTabCol++){
@ -2746,14 +2768,11 @@ Index *sqlite3CreateIndex(
goto exit_create_index;
}
pIndex->aiColumn[i] = j;
/* Justification of the ALWAYS(pListItem->pExpr->pColl): Because of
** the way the "idxlist" non-terminal is constructed by the parser,
** if pListItem->pExpr is not null then either pListItem->pExpr->pColl
** must exist or else there must have been an OOM error. But if there
** was an OOM error, we would never reach this point. */
if( pListItem->pExpr && ALWAYS(pListItem->pExpr->pColl) ){
if( pListItem->pExpr
&& (pColl = sqlite3ExprCollSeq(pParse, pListItem->pExpr))!=0
){
int nColl;
zColl = pListItem->pExpr->pColl->zName;
zColl = pColl->zName;
nColl = sqlite3Strlen30(zColl) + 1;
assert( nExtra>=nColl );
memcpy(zExtra, zColl, nColl);
@ -3567,6 +3586,15 @@ int sqlite3OpenTempDatabase(Parse *pParse){
void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
Parse *pToplevel = sqlite3ParseToplevel(pParse);
#ifndef SQLITE_OMIT_TRIGGER
if( pToplevel!=pParse ){
/* This branch is taken if a trigger is currently being coded. In this
** case, set cookieGoto to a non-zero value to show that this function
** has been called. This is used by the sqlite3ExprCodeConstants()
** function. */
pParse->cookieGoto = -1;
}
#endif
if( pToplevel->cookieGoto==0 ){
Vdbe *v = sqlite3GetVdbe(pToplevel);
if( v==0 ) return; /* This only happens if there was a prior error */

View File

@ -75,17 +75,18 @@ static int synthCollSeq(sqlite3 *db, CollSeq *pColl){
**
** The return value is either the collation sequence to be used in database
** db for collation type name zName, length nName, or NULL, if no collation
** sequence can be found.
** sequence can be found. If no collation is found, leave an error message.
**
** See also: sqlite3LocateCollSeq(), sqlite3FindCollSeq()
*/
CollSeq *sqlite3GetCollSeq(
sqlite3* db, /* The database connection */
Parse *pParse, /* Parsing context */
u8 enc, /* The desired encoding for the collating sequence */
CollSeq *pColl, /* Collating sequence with native encoding, or NULL */
const char *zName /* Collating sequence name */
){
CollSeq *p;
sqlite3 *db = pParse->db;
p = pColl;
if( !p ){
@ -102,6 +103,9 @@ CollSeq *sqlite3GetCollSeq(
p = 0;
}
assert( !p || p->xCmp );
if( p==0 ){
sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
}
return p;
}
@ -120,10 +124,8 @@ int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){
if( pColl ){
const char *zName = pColl->zName;
sqlite3 *db = pParse->db;
CollSeq *p = sqlite3GetCollSeq(db, ENC(db), pColl, zName);
CollSeq *p = sqlite3GetCollSeq(pParse, ENC(db), pColl, zName);
if( !p ){
sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
pParse->nErr++;
return SQLITE_ERROR;
}
assert( p==pColl );

View File

@ -338,6 +338,9 @@ static const char * const azCompileOpt[] = {
#ifdef SQLITE_PROXY_DEBUG
"PROXY_DEBUG",
#endif
#ifdef SQLITE_RTREE_INT_ONLY
"RTREE_INT_ONLY",
#endif
#ifdef SQLITE_SECURE_DELETE
"SECURE_DELETE",
#endif

View File

@ -32,7 +32,7 @@ Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
struct SrcList_item *pItem = pSrc->a;
Table *pTab;
assert( pItem && pSrc->nSrc==1 );
pTab = sqlite3LocateTable(pParse, 0, pItem->zName, pItem->zDatabase);
pTab = sqlite3LocateTableItem(pParse, 0, pItem);
sqlite3DeleteTable(pParse->db, pItem->pTab);
pItem->pTab = pTab;
if( pTab ){
@ -112,6 +112,7 @@ void sqlite3MaterializeView(
sqlite3SelectDelete(db, pDup);
}
pDup = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0, 0, 0, 0);
if( pDup ) pDup->selFlags |= SF_Materialize;
}
sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur);
sqlite3Select(pParse, pDup, &dest);
@ -638,7 +639,9 @@ int sqlite3GenerateIndexKey(
}
if( doMakeRec ){
const char *zAff;
if( pTab->pSelect || (pParse->db->flags & SQLITE_IdxRealAsInt)!=0 ){
if( pTab->pSelect
|| OptimizationDisabled(pParse->db, SQLITE_IdxRealAsInt)
){
zAff = 0;
}else{
zAff = sqlite3IndexAffinityStr(v, pIdx);

View File

@ -31,7 +31,9 @@
** SELECT * FROM t1 WHERE (select a from t1);
*/
char sqlite3ExprAffinity(Expr *pExpr){
int op = pExpr->op;
int op;
pExpr = sqlite3ExprSkipCollate(pExpr);
op = pExpr->op;
if( op==TK_SELECT ){
assert( pExpr->flags&EP_xIsSelect );
return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
@ -56,66 +58,94 @@ char sqlite3ExprAffinity(Expr *pExpr){
}
/*
** Set the explicit collating sequence for an expression to the
** collating sequence supplied in the second argument.
** Set the collating sequence for expression pExpr to be the collating
** sequence named by pToken. Return a pointer to a new Expr node that
** implements the COLLATE operator.
**
** If a memory allocation error occurs, that fact is recorded in pParse->db
** and the pExpr parameter is returned unchanged.
*/
Expr *sqlite3ExprSetColl(Expr *pExpr, CollSeq *pColl){
if( pExpr && pColl ){
pExpr->pColl = pColl;
pExpr->flags |= EP_ExpCollate;
Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr *pExpr, Token *pCollName){
if( pCollName->n>0 ){
Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, 1);
if( pNew ){
pNew->pLeft = pExpr;
pNew->flags |= EP_Collate;
pExpr = pNew;
}
}
return pExpr;
}
Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){
Token s;
assert( zC!=0 );
s.z = zC;
s.n = sqlite3Strlen30(s.z);
return sqlite3ExprAddCollateToken(pParse, pExpr, &s);
}
/*
** Skip over any TK_COLLATE and/or TK_AS operators at the root of
** an expression.
*/
Expr *sqlite3ExprSkipCollate(Expr *pExpr){
while( pExpr && (pExpr->op==TK_COLLATE || pExpr->op==TK_AS) ){
pExpr = pExpr->pLeft;
}
return pExpr;
}
/*
** Set the collating sequence for expression pExpr to be the collating
** sequence named by pToken. Return a pointer to the revised expression.
** The collating sequence is marked as "explicit" using the EP_ExpCollate
** flag. An explicit collating sequence will override implicit
** collating sequences.
*/
Expr *sqlite3ExprSetCollByToken(Parse *pParse, Expr *pExpr, Token *pCollName){
char *zColl = 0; /* Dequoted name of collation sequence */
CollSeq *pColl;
sqlite3 *db = pParse->db;
zColl = sqlite3NameFromToken(db, pCollName);
pColl = sqlite3LocateCollSeq(pParse, zColl);
sqlite3ExprSetColl(pExpr, pColl);
sqlite3DbFree(db, zColl);
return pExpr;
}
/*
** Return the default collation sequence for the expression pExpr. If
** there is no default collation type, return 0.
** Return the collation sequence for the expression pExpr. If
** there is no defined collating sequence, return NULL.
**
** The collating sequence might be determined by a COLLATE operator
** or by the presence of a column with a defined collating sequence.
** COLLATE operators take first precedence. Left operands take
** precedence over right operands.
*/
CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
sqlite3 *db = pParse->db;
CollSeq *pColl = 0;
Expr *p = pExpr;
while( p ){
int op;
pColl = p->pColl;
if( pColl ) break;
op = p->op;
if( p->pTab!=0 && (
op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER || op==TK_TRIGGER
)){
/* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally
** a TK_COLUMN but was previously evaluated and cached in a register */
const char *zColl;
int j = p->iColumn;
if( j>=0 ){
sqlite3 *db = pParse->db;
zColl = p->pTab->aCol[j].zColl;
pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
pExpr->pColl = pColl;
int op = p->op;
if( op==TK_CAST || op==TK_UPLUS ){
p = p->pLeft;
continue;
}
assert( op!=TK_REGISTER || p->op2!=TK_COLLATE );
if( op==TK_COLLATE ){
if( db->init.busy ){
/* Do not report errors when parsing while the schema */
pColl = sqlite3FindCollSeq(db, ENC(db), p->u.zToken, 0);
}else{
pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
}
break;
}
if( op!=TK_CAST && op!=TK_UPLUS ){
if( p->pTab!=0
&& (op==TK_AGG_COLUMN || op==TK_COLUMN
|| op==TK_REGISTER || op==TK_TRIGGER)
){
/* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally
** a TK_COLUMN but was previously evaluated and cached in a register */
int j = p->iColumn;
if( j>=0 ){
const char *zColl = p->pTab->aCol[j].zColl;
pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
}
break;
}
if( p->flags & EP_Collate ){
if( ALWAYS(p->pLeft) && (p->pLeft->flags & EP_Collate)!=0 ){
p = p->pLeft;
}else{
p = p->pRight;
}
}else{
break;
}
p = p->pLeft;
}
if( sqlite3CheckCollSeq(pParse, pColl) ){
pColl = 0;
@ -219,12 +249,10 @@ CollSeq *sqlite3BinaryCompareCollSeq(
){
CollSeq *pColl;
assert( pLeft );
if( pLeft->flags & EP_ExpCollate ){
assert( pLeft->pColl );
pColl = pLeft->pColl;
}else if( pRight && pRight->flags & EP_ExpCollate ){
assert( pRight->pColl );
pColl = pRight->pColl;
if( pLeft->flags & EP_Collate ){
pColl = sqlite3ExprCollSeq(pParse, pLeft);
}else if( pRight && (pRight->flags & EP_Collate)!=0 ){
pColl = sqlite3ExprCollSeq(pParse, pRight);
}else{
pColl = sqlite3ExprCollSeq(pParse, pLeft);
if( !pColl ){
@ -454,17 +482,11 @@ void sqlite3ExprAttachSubtrees(
}else{
if( pRight ){
pRoot->pRight = pRight;
if( pRight->flags & EP_ExpCollate ){
pRoot->flags |= EP_ExpCollate;
pRoot->pColl = pRight->pColl;
}
pRoot->flags |= EP_Collate & pRight->flags;
}
if( pLeft ){
pRoot->pLeft = pLeft;
if( pLeft->flags & EP_ExpCollate ){
pRoot->flags |= EP_ExpCollate;
pRoot->pColl = pLeft->pColl;
}
pRoot->flags |= EP_Collate & pLeft->flags;
}
exprSetHeight(pRoot);
}
@ -722,7 +744,7 @@ static int dupedExprStructSize(Expr *p, int flags){
assert( !ExprHasProperty(p, EP_FromJoin) );
assert( (p->flags2 & EP2_MallocedToken)==0 );
assert( (p->flags2 & EP2_Irreducible)==0 );
if( p->pLeft || p->pRight || p->pColl || p->x.pList ){
if( p->pLeft || p->pRight || p->x.pList ){
nSize = EXPR_REDUCEDSIZE | EP_Reduced;
}else{
nSize = EXPR_TOKENONLYSIZE | EP_TokenOnly;
@ -930,6 +952,7 @@ SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){
struct SrcList_item *pNewItem = &pNew->a[i];
struct SrcList_item *pOldItem = &p->a[i];
Table *pTab;
pNewItem->pSchema = pOldItem->pSchema;
pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase);
pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias);
@ -938,6 +961,7 @@ SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){
pNewItem->addrFillSub = pOldItem->addrFillSub;
pNewItem->regReturn = pOldItem->regReturn;
pNewItem->isCorrelated = pOldItem->isCorrelated;
pNewItem->viaCoroutine = pOldItem->viaCoroutine;
pNewItem->zIndex = sqlite3DbStrDup(db, pOldItem->zIndex);
pNewItem->notIndexed = pOldItem->notIndexed;
pNewItem->pIndex = pOldItem->pIndex;
@ -1420,12 +1444,16 @@ int sqlite3CodeOnce(Parse *pParse){
/*
** This function is used by the implementation of the IN (...) operator.
** It's job is to find or create a b-tree structure that may be used
** either to test for membership of the (...) set or to iterate through
** its members, skipping duplicates.
** The pX parameter is the expression on the RHS of the IN operator, which
** might be either a list of expressions or a subquery.
**
** The job of this routine is to find or create a b-tree object that can
** be used either to test for membership in the RHS set or to iterate through
** all members of the RHS set, skipping duplicates.
**
** A cursor is opened on the b-tree object that the RHS of the IN operator
** and pX->iTable is set to the index of that cursor.
**
** The index of the cursor opened on the b-tree (database table, database index
** or ephermal table) is stored in pX->iTable before this function returns.
** The returned value of this function indicates the b-tree type, as follows:
**
** IN_INDEX_ROWID - The cursor was opened on a database table.
@ -1433,11 +1461,16 @@ int sqlite3CodeOnce(Parse *pParse){
** IN_INDEX_EPH - The cursor was opened on a specially created and
** populated epheremal table.
**
** An existing b-tree may only be used if the SELECT is of the simple
** form:
** An existing b-tree might be used if the RHS expression pX is a simple
** subquery such as:
**
** SELECT <column> FROM <table>
**
** If the RHS of the IN operator is a list or a more complex subquery, then
** an ephemeral table might need to be generated from the RHS and then
** pX->iTable made to point to the ephermeral table instead of an
** existing table.
**
** If the prNotFound parameter is 0, then the b-tree will be used to iterate
** through the set members, skipping any duplicates. In this case an
** epheremal table must be used unless the selected <column> is guaranteed
@ -1533,8 +1566,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
** comparison is the same as the affinity of the column. If
** it is not, it is not possible to use any index.
*/
char aff = comparisonAffinity(pX);
int affinity_ok = (pTab->aCol[iCol].affinity==aff||aff==SQLITE_AFF_NONE);
int affinity_ok = sqlite3IndexAffinityOk(pX, pTab->aCol[iCol].affinity);
for(pIdx=pTab->pIndex; pIdx && eType==0 && affinity_ok; pIdx=pIdx->pNext){
if( (pIdx->aiColumn[0]==iCol)
@ -1662,6 +1694,7 @@ int sqlite3CodeSubselect(
case TK_IN: {
char affinity; /* Affinity of the LHS of the IN */
KeyInfo keyInfo; /* Keyinfo for the generated table */
static u8 sortOrder = 0; /* Fake aSortOrder for keyInfo */
int addr; /* Address of OP_OpenEphemeral instruction */
Expr *pLeft = pExpr->pLeft; /* the LHS of the IN operator */
@ -1689,6 +1722,7 @@ int sqlite3CodeSubselect(
if( rMayHaveNull==0 ) sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
memset(&keyInfo, 0, sizeof(keyInfo));
keyInfo.nField = 1;
keyInfo.aSortOrder = &sortOrder;
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
/* Case 1: expr IN (SELECT ...)
@ -1729,6 +1763,7 @@ int sqlite3CodeSubselect(
affinity = SQLITE_AFF_NONE;
}
keyInfo.aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
keyInfo.aSortOrder = &sortOrder;
/* Loop through each expression in <exprlist>. */
r1 = sqlite3GetTempReg(pParse);
@ -2055,7 +2090,7 @@ void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){
** for testing only - to verify that SQLite always gets the same answer
** with and without the column cache.
*/
if( pParse->db->flags & SQLITE_ColumnCache ) return;
if( OptimizationDisabled(pParse->db, SQLITE_ColumnCache) ) return;
/* First replace any existing entry.
**
@ -2252,8 +2287,8 @@ void sqlite3ExprCacheAffinityChange(Parse *pParse, int iStart, int iCount){
void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){
int i;
struct yColCache *p;
if( NEVER(iFrom==iTo) ) return;
sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg);
assert( iFrom>=iTo+nReg || iFrom+nReg<=iTo );
sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg-1);
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
int x = p->iReg;
if( x>=iFrom && x<iFrom+nReg ){
@ -2262,18 +2297,6 @@ void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){
}
}
/*
** Generate code to copy content from registers iFrom...iFrom+nReg-1
** over to iTo..iTo+nReg-1.
*/
void sqlite3ExprCodeCopy(Parse *pParse, int iFrom, int iTo, int nReg){
int i;
if( NEVER(iFrom==iTo) ) return;
for(i=0; i<nReg; i++){
sqlite3VdbeAddOp2(pParse->pVdbe, OP_Copy, iFrom+i, iTo+i);
}
}
#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
/*
** Return true if any register in the range iFrom..iTo (inclusive)
@ -2745,6 +2768,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
sqlite3ReleaseTempReg(pParse, r4);
break;
}
case TK_COLLATE:
case TK_UPLUS: {
inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
break;
@ -3114,6 +3138,12 @@ void sqlite3ExplainExpr(Vdbe *pOut, Expr *pExpr){
case TK_ISNULL: zUniOp = "ISNULL"; break;
case TK_NOTNULL: zUniOp = "NOTNULL"; break;
case TK_COLLATE: {
sqlite3ExplainExpr(pOut, pExpr->pLeft);
sqlite3ExplainPrintf(pOut,".COLLATE(%s)",pExpr->u.zToken);
break;
}
case TK_AGG_FUNCTION:
case TK_CONST_FUNC:
case TK_FUNCTION: {
@ -3332,6 +3362,9 @@ static int evalConstExpr(Walker *pWalker, Expr *pExpr){
case TK_REGISTER: {
return WRC_Prune;
}
case TK_COLLATE: {
return WRC_Continue;
}
case TK_FUNCTION:
case TK_AGG_FUNCTION:
case TK_CONST_FUNC: {
@ -3353,9 +3386,11 @@ static int evalConstExpr(Walker *pWalker, Expr *pExpr){
}
if( isAppropriateForFactoring(pExpr) ){
int r1 = ++pParse->nMem;
int r2;
r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
if( NEVER(r1!=r2) ) sqlite3ReleaseTempReg(pParse, r1);
int r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
/* If r2!=r1, it means that register r1 is never used. That is harmless
** but suboptimal, so we want to know about the situation to fix it.
** Hence the following assert: */
assert( r2==r1 );
pExpr->op2 = pExpr->op;
pExpr->op = TK_REGISTER;
pExpr->iTable = r2;
@ -3383,7 +3418,7 @@ static int evalConstExpr(Walker *pWalker, Expr *pExpr){
void sqlite3ExprCodeConstants(Parse *pParse, Expr *pExpr){
Walker w;
if( pParse->cookieGoto ) return;
if( (pParse->db->flags & SQLITE_FactorOutConst)!=0 ) return;
if( OptimizationDisabled(pParse->db, SQLITE_FactorOutConst) ) return;
w.xExprCallback = evalConstExpr;
w.xSelectCallback = 0;
w.pParse = pParse;
@ -3772,7 +3807,15 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB){
return 2;
}
if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
if( pA->op!=pB->op ) return 2;
if( pA->op!=pB->op ){
if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB)<2 ){
return 1;
}
if( pB->op==TK_COLLATE && sqlite3ExprCompare(pA, pB->pLeft)<2 ){
return 1;
}
return 2;
}
if( sqlite3ExprCompare(pA->pLeft, pB->pLeft) ) return 2;
if( sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 2;
if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList) ) return 2;
@ -3784,11 +3827,9 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB){
}else if( pA->op!=TK_COLUMN && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken){
if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 2;
if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
return 2;
return pA->op==TK_COLLATE ? 1 : 2;
}
}
if( (pA->flags & EP_ExpCollate)!=(pB->flags & EP_ExpCollate) ) return 1;
if( (pA->flags & EP_ExpCollate)!=0 && pA->pColl!=pB->pColl ) return 2;
return 0;
}
@ -4029,8 +4070,10 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
ExprSetIrreducible(pExpr);
pExpr->iAgg = (i16)i;
pExpr->pAggInfo = pAggInfo;
return WRC_Prune;
}else{
return WRC_Continue;
}
return WRC_Prune;
}
}
return WRC_Continue;
@ -4042,9 +4085,10 @@ static int analyzeAggregatesInSelect(Walker *pWalker, Select *pSelect){
}
/*
** Analyze the given expression looking for aggregate functions and
** for variables that need to be added to the pParse->aAgg[] array.
** Make additional entries to the pParse->aAgg[] array as necessary.
** Analyze the pExpr expression looking for aggregate functions and
** for variables that need to be added to AggInfo object that pNC->pAggInfo
** points to. Additional entries are made on the AggInfo object as
** necessary.
**
** This routine should only be called after the expression has been
** analyzed by sqlite3ResolveExprNames().

View File

@ -511,12 +511,15 @@ static void fkScanChildren(
** expression to the parent key column defaults. */
if( pIdx ){
Column *pCol;
const char *zColl;
iCol = pIdx->aiColumn[i];
pCol = &pTab->aCol[iCol];
if( pTab->iPKey==iCol ) iCol = -1;
pLeft->iTable = regData+iCol+1;
pLeft->affinity = pCol->affinity;
pLeft->pColl = sqlite3LocateCollSeq(pParse, pCol->zColl);
zColl = pCol->zColl;
if( zColl==0 ) zColl = db->pDfltColl->zName;
pLeft = sqlite3ExprAddCollateString(pParse, pLeft, zColl);
}else{
pLeft->iTable = regData;
pLeft->affinity = SQLITE_AFF_INTEGER;
@ -925,7 +928,8 @@ int sqlite3FkRequired(
int iKey;
for(iKey=0; iKey<pTab->nCol; iKey++){
Column *pCol = &pTab->aCol[iKey];
if( (zKey ? !sqlite3StrICmp(pCol->zName, zKey) : pCol->isPrimKey) ){
if( (zKey ? !sqlite3StrICmp(pCol->zName, zKey)
: (pCol->colFlags & COLFLAG_PRIMKEY)!=0) ){
if( aChange[iKey]>=0 ) return 1;
if( iKey==pTab->iPKey && chngRowid ) return 1;
}

View File

@ -168,6 +168,56 @@ static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
}
}
/*
** Implementation of the instr() function.
**
** instr(haystack,needle) finds the first occurrence of needle
** in haystack and returns the number of previous characters plus 1,
** or 0 if needle does not occur within haystack.
**
** If both haystack and needle are BLOBs, then the result is one more than
** the number of bytes in haystack prior to the first occurrence of needle,
** or 0 if needle never occurs in haystack.
*/
static void instrFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
const unsigned char *zHaystack;
const unsigned char *zNeedle;
int nHaystack;
int nNeedle;
int typeHaystack, typeNeedle;
int N = 1;
int isText;
UNUSED_PARAMETER(argc);
typeHaystack = sqlite3_value_type(argv[0]);
typeNeedle = sqlite3_value_type(argv[1]);
if( typeHaystack==SQLITE_NULL || typeNeedle==SQLITE_NULL ) return;
nHaystack = sqlite3_value_bytes(argv[0]);
nNeedle = sqlite3_value_bytes(argv[1]);
if( typeHaystack==SQLITE_BLOB && typeNeedle==SQLITE_BLOB ){
zHaystack = sqlite3_value_blob(argv[0]);
zNeedle = sqlite3_value_blob(argv[1]);
isText = 0;
}else{
zHaystack = sqlite3_value_text(argv[0]);
zNeedle = sqlite3_value_text(argv[1]);
isText = 1;
}
while( nNeedle<=nHaystack && memcmp(zHaystack, zNeedle, nNeedle)!=0 ){
N++;
do{
nHaystack--;
zHaystack++;
}while( isText && (zHaystack[0]&0xc0)==0x80 );
}
if( nNeedle>nHaystack ) N = 0;
sqlite3_result_int(context, N);
}
/*
** Implementation of the substr() function.
**
@ -367,33 +417,14 @@ static void lowerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
}
}
#if 0 /* This function is never used. */
/*
** The COALESCE() and IFNULL() functions used to be implemented as shown
** here. But now they are implemented as VDBE code so that unused arguments
** do not have to be computed. This legacy implementation is retained as
** comment.
** The COALESCE() and IFNULL() functions are implemented as VDBE code so
** that unused argument values do not have to be computed. However, we
** still need some kind of function implementation for this routines in
** the function table. That function implementation will never be called
** so it doesn't matter what the implementation is. We might as well use
** the "version()" function as a substitute.
*/
/*
** Implementation of the IFNULL(), NVL(), and COALESCE() functions.
** All three do the same thing. They return the first non-NULL
** argument.
*/
static void ifnullFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
int i;
for(i=0; i<argc; i++){
if( SQLITE_NULL!=sqlite3_value_type(argv[i]) ){
sqlite3_result_value(context, argv[i]);
break;
}
}
}
#endif /* NOT USED */
#define ifnullFunc versionFunc /* Substitute function - never called */
/*
@ -512,7 +543,7 @@ struct compareInfo {
** whereas only characters less than 0x80 do in ASCII.
*/
#if defined(SQLITE_EBCDIC)
# define sqlite3Utf8Read(A,C) (*(A++))
# define sqlite3Utf8Read(A) (*((*A)++))
# define GlogUpperToLower(A) A = sqlite3UpperToLower[A]
#else
# define GlogUpperToLower(A) if( !((A)&~0x7f) ){ A = sqlite3UpperToLower[A]; }
@ -569,18 +600,18 @@ static int patternCompare(
u8 noCase = pInfo->noCase;
int prevEscape = 0; /* True if the previous character was 'escape' */
while( (c = sqlite3Utf8Read(zPattern,&zPattern))!=0 ){
if( !prevEscape && c==matchAll ){
while( (c=sqlite3Utf8Read(zPattern,&zPattern)) == matchAll
while( (c = sqlite3Utf8Read(&zPattern))!=0 ){
if( c==matchAll && !prevEscape ){
while( (c=sqlite3Utf8Read(&zPattern)) == matchAll
|| c == matchOne ){
if( c==matchOne && sqlite3Utf8Read(zString, &zString)==0 ){
if( c==matchOne && sqlite3Utf8Read(&zString)==0 ){
return 0;
}
}
if( c==0 ){
return 1;
}else if( c==esc ){
c = sqlite3Utf8Read(zPattern, &zPattern);
c = sqlite3Utf8Read(&zPattern);
if( c==0 ){
return 0;
}
@ -592,25 +623,25 @@ static int patternCompare(
}
return *zString!=0;
}
while( (c2 = sqlite3Utf8Read(zString,&zString))!=0 ){
while( (c2 = sqlite3Utf8Read(&zString))!=0 ){
if( noCase ){
GlogUpperToLower(c2);
GlogUpperToLower(c);
while( c2 != 0 && c2 != c ){
c2 = sqlite3Utf8Read(zString, &zString);
c2 = sqlite3Utf8Read(&zString);
GlogUpperToLower(c2);
}
}else{
while( c2 != 0 && c2 != c ){
c2 = sqlite3Utf8Read(zString, &zString);
c2 = sqlite3Utf8Read(&zString);
}
}
if( c2==0 ) return 0;
if( patternCompare(zPattern,zString,pInfo,esc) ) return 1;
}
return 0;
}else if( !prevEscape && c==matchOne ){
if( sqlite3Utf8Read(zString, &zString)==0 ){
}else if( c==matchOne && !prevEscape ){
if( sqlite3Utf8Read(&zString)==0 ){
return 0;
}
}else if( c==matchSet ){
@ -618,20 +649,20 @@ static int patternCompare(
assert( esc==0 ); /* This only occurs for GLOB, not LIKE */
seen = 0;
invert = 0;
c = sqlite3Utf8Read(zString, &zString);
c = sqlite3Utf8Read(&zString);
if( c==0 ) return 0;
c2 = sqlite3Utf8Read(zPattern, &zPattern);
c2 = sqlite3Utf8Read(&zPattern);
if( c2=='^' ){
invert = 1;
c2 = sqlite3Utf8Read(zPattern, &zPattern);
c2 = sqlite3Utf8Read(&zPattern);
}
if( c2==']' ){
if( c==']' ) seen = 1;
c2 = sqlite3Utf8Read(zPattern, &zPattern);
c2 = sqlite3Utf8Read(&zPattern);
}
while( c2 && c2!=']' ){
if( c2=='-' && zPattern[0]!=']' && zPattern[0]!=0 && prior_c>0 ){
c2 = sqlite3Utf8Read(zPattern, &zPattern);
c2 = sqlite3Utf8Read(&zPattern);
if( c>=prior_c && c<=c2 ) seen = 1;
prior_c = 0;
}else{
@ -640,7 +671,7 @@ static int patternCompare(
}
prior_c = c2;
}
c2 = sqlite3Utf8Read(zPattern, &zPattern);
c2 = sqlite3Utf8Read(&zPattern);
}
if( c2==0 || (seen ^ invert)==0 ){
return 0;
@ -648,7 +679,7 @@ static int patternCompare(
}else if( esc==c && !prevEscape ){
prevEscape = 1;
}else{
c2 = sqlite3Utf8Read(zString, &zString);
c2 = sqlite3Utf8Read(&zString);
if( noCase ){
GlogUpperToLower(c);
GlogUpperToLower(c2);
@ -720,7 +751,7 @@ static void likeFunc(
"ESCAPE expression must be a single character", -1);
return;
}
escape = sqlite3Utf8Read(zEsc, &zEsc);
escape = sqlite3Utf8Read(&zEsc);
}
if( zA && zB ){
struct compareInfo *pInfo = sqlite3_user_data(context);
@ -1555,6 +1586,7 @@ void sqlite3RegisterGlobalFunctions(void){
AGGREGATE(max, 1, 1, 1, minmaxStep, minMaxFinalize ),
FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF),
FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH),
FUNCTION(instr, 2, 0, 0, instrFunc ),
FUNCTION(substr, 2, 0, 0, substrFunc ),
FUNCTION(substr, 3, 0, 0, substrFunc ),
FUNCTION(abs, 1, 0, 0, absFunc ),

View File

@ -133,6 +133,10 @@ const unsigned char sqlite3CtypeMap[256] = {
# define SQLITE_USE_URI 0
#endif
#ifndef SQLITE_ALLOW_COVERING_INDEX_SCAN
# define SQLITE_ALLOW_COVERING_INDEX_SCAN 1
#endif
/*
** The following singleton contains the global configuration for
** the SQLite library.
@ -142,6 +146,7 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = {
1, /* bCoreMutex */
SQLITE_THREADSAFE==1, /* bFullMutex */
SQLITE_USE_URI, /* bOpenUri */
SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */
0x7ffffffe, /* mxStrlen */
128, /* szLookaside */
500, /* nLookaside */
@ -170,6 +175,10 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = {
0, /* xLog */
0, /* pLogArg */
0, /* bLocaltimeFault */
#ifdef SQLITE_ENABLE_SQLLOG
0, /* xSqllog */
0 /* pSqllogArg */
#endif
};

View File

@ -193,7 +193,7 @@ static void removeElementGivenHash(
}
sqlite3_free( elem );
pH->count--;
if( pH->count<=0 ){
if( pH->count==0 ){
assert( pH->first==0 );
assert( pH->count==0 );
sqlite3HashClear(pH);

View File

@ -25,7 +25,7 @@ void sqlite3OpenTable(
int opcode /* OP_OpenRead or OP_OpenWrite */
){
Vdbe *v;
if( IsVirtual(pTab) ) return;
assert( !IsVirtual(pTab) );
v = sqlite3GetVdbe(p);
assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );
sqlite3TableLock(p, iDb, pTab->tnum, (opcode==OP_OpenWrite)?1:0, pTab->zName);
@ -320,6 +320,97 @@ void sqlite3AutoincrementEnd(Parse *pParse){
#endif /* SQLITE_OMIT_AUTOINCREMENT */
/*
** Generate code for a co-routine that will evaluate a subquery one
** row at a time.
**
** The pSelect parameter is the subquery that the co-routine will evaluation.
** Information about the location of co-routine and the registers it will use
** is returned by filling in the pDest object.
**
** Registers are allocated as follows:
**
** pDest->iSDParm The register holding the next entry-point of the
** co-routine. Run the co-routine to its next breakpoint
** by calling "OP_Yield $X" where $X is pDest->iSDParm.
**
** pDest->iSDParm+1 The register holding the "completed" flag for the
** co-routine. This register is 0 if the previous Yield
** generated a new result row, or 1 if the subquery
** has completed. If the Yield is called again
** after this register becomes 1, then the VDBE will
** halt with an SQLITE_INTERNAL error.
**
** pDest->iSdst First result register.
**
** pDest->nSdst Number of result registers.
**
** This routine handles all of the register allocation and fills in the
** pDest structure appropriately.
**
** Here is a schematic of the generated code assuming that X is the
** co-routine entry-point register reg[pDest->iSDParm], that EOF is the
** completed flag reg[pDest->iSDParm+1], and R and S are the range of
** registers that hold the result set, reg[pDest->iSdst] through
** reg[pDest->iSdst+pDest->nSdst-1]:
**
** X <- A
** EOF <- 0
** goto B
** A: setup for the SELECT
** loop rows in the SELECT
** load results into registers R..S
** yield X
** end loop
** cleanup after the SELECT
** EOF <- 1
** yield X
** halt-error
** B:
**
** To use this subroutine, the caller generates code as follows:
**
** [ Co-routine generated by this subroutine, shown above ]
** S: yield X
** if EOF goto E
** if skip this row, goto C
** if terminate loop, goto E
** deal with this row
** C: goto S
** E:
*/
int sqlite3CodeCoroutine(Parse *pParse, Select *pSelect, SelectDest *pDest){
int regYield; /* Register holding co-routine entry-point */
int regEof; /* Register holding co-routine completion flag */
int addrTop; /* Top of the co-routine */
int j1; /* Jump instruction */
int rc; /* Result code */
Vdbe *v; /* VDBE under construction */
regYield = ++pParse->nMem;
regEof = ++pParse->nMem;
v = sqlite3GetVdbe(pParse);
addrTop = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp2(v, OP_Integer, addrTop+2, regYield); /* X <- A */
VdbeComment((v, "Co-routine entry point"));
sqlite3VdbeAddOp2(v, OP_Integer, 0, regEof); /* EOF <- 0 */
VdbeComment((v, "Co-routine completion flag"));
sqlite3SelectDestInit(pDest, SRT_Coroutine, regYield);
j1 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
rc = sqlite3Select(pParse, pSelect, pDest);
assert( pParse->nErr==0 || rc );
if( pParse->db->mallocFailed && rc==SQLITE_OK ) rc = SQLITE_NOMEM;
if( rc ) return rc;
sqlite3VdbeAddOp2(v, OP_Integer, 1, regEof); /* EOF <- 1 */
sqlite3VdbeAddOp1(v, OP_Yield, regYield); /* yield X */
sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_INTERNAL, OE_Abort);
VdbeComment((v, "End of coroutine"));
sqlite3VdbeJumpHere(v, j1); /* label B: */
return rc;
}
/* Forward declaration */
static int xferOptimization(
Parse *pParse, /* Parser context */
@ -568,51 +659,12 @@ void sqlite3Insert(
** co-routine is the common header to the 3rd and 4th templates.
*/
if( pSelect ){
/* Data is coming from a SELECT. Generate code to implement that SELECT
** as a co-routine. The code is common to both the 3rd and 4th
** templates:
**
** EOF <- 0
** X <- A
** goto B
** A: setup for the SELECT
** loop over the tables in the SELECT
** load value into register R..R+n
** yield X
** end loop
** cleanup after the SELECT
** EOF <- 1
** yield X
** halt-error
**
** On each invocation of the co-routine, it puts a single row of the
** SELECT result into registers dest.iMem...dest.iMem+dest.nMem-1.
** (These output registers are allocated by sqlite3Select().) When
** the SELECT completes, it sets the EOF flag stored in regEof.
*/
int rc, j1;
regEof = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_Integer, 0, regEof); /* EOF <- 0 */
VdbeComment((v, "SELECT eof flag"));
sqlite3SelectDestInit(&dest, SRT_Coroutine, ++pParse->nMem);
addrSelect = sqlite3VdbeCurrentAddr(v)+2;
sqlite3VdbeAddOp2(v, OP_Integer, addrSelect-1, dest.iSDParm);
j1 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
VdbeComment((v, "Jump over SELECT coroutine"));
/* Resolve the expressions in the SELECT statement and execute it. */
rc = sqlite3Select(pParse, pSelect, &dest);
assert( pParse->nErr==0 || rc );
if( rc || NEVER(pParse->nErr) || db->mallocFailed ){
goto insert_cleanup;
}
sqlite3VdbeAddOp2(v, OP_Integer, 1, regEof); /* EOF <- 1 */
sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); /* yield X */
sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_INTERNAL, OE_Abort);
VdbeComment((v, "End of SELECT coroutine"));
sqlite3VdbeJumpHere(v, j1); /* label B: */
/* Data is coming from a SELECT. Generate a co-routine to run that
** SELECT. */
int rc = sqlite3CodeCoroutine(pParse, pSelect, &dest);
if( rc ) goto insert_cleanup;
regEof = dest.iSDParm + 1;
regFromSelect = dest.iSdst;
assert( pSelect->pEList );
nColumn = pSelect->pEList->nExpr;
@ -1691,7 +1743,7 @@ static int xferOptimization(
** we have to check the semantics.
*/
pItem = pSelect->pSrc->a;
pSrc = sqlite3LocateTable(pParse, 0, pItem->zName, pItem->zDatabase);
pSrc = sqlite3LocateTableItem(pParse, 0, pItem);
if( pSrc==0 ){
return 0; /* FROM clause does not contain a real table */
}

View File

@ -228,6 +228,16 @@ int sqlite3JournalCreate(sqlite3_file *p){
return createFile((JournalFile *)p);
}
/*
** The file-handle passed as the only argument is guaranteed to be an open
** file. It may or may not be of class JournalFile. If the file is a
** JournalFile, and the underlying file on disk has not yet been opened,
** return 0. Otherwise, return 1.
*/
int sqlite3JournalExists(sqlite3_file *p){
return (p->pMethods!=&JournalFileMethods || ((JournalFile *)p)->pReal!=0);
}
/*
** Return the number of bytes required to store a JournalFile that uses vfs
** pVfs to create the underlying on-disk files.

View File

@ -608,6 +608,7 @@ static void yy_reduce(
*/
%%
};
assert( yyruleno>=0 && yyruleno<sizeof(yyRuleInfo)/sizeof(yyRuleInfo[0]) );
yygoto = yyRuleInfo[yyruleno].lhs;
yysize = yyRuleInfo[yyruleno].nrhs;
yypParser->yyidx -= yysize;

View File

@ -132,6 +132,13 @@ int sqlite3_initialize(void){
*/
if( sqlite3GlobalConfig.isInit ) return SQLITE_OK;
#ifdef SQLITE_ENABLE_SQLLOG
{
extern void sqlite3_init_sqllog(void);
sqlite3_init_sqllog();
}
#endif
/* Make sure the mutex subsystem is initialized. If unable to
** initialize the mutex subsystem, return early with the error.
** If the system is so sick that we are unable to allocate a mutex,
@ -475,6 +482,20 @@ int sqlite3_config(int op, ...){
break;
}
case SQLITE_CONFIG_COVERING_INDEX_SCAN: {
sqlite3GlobalConfig.bUseCis = va_arg(ap, int);
break;
}
#ifdef SQLITE_ENABLE_SQLLOG
case SQLITE_CONFIG_SQLLOG: {
typedef void(*SQLLOGFUNC_t)(void*, sqlite3*, const char*, int);
sqlite3GlobalConfig.xSqllog = va_arg(ap, SQLLOGFUNC_t);
sqlite3GlobalConfig.pSqllogArg = va_arg(ap, void *);
break;
}
#endif
default: {
rc = SQLITE_ERROR;
break;
@ -814,6 +835,13 @@ static int sqlite3Close(sqlite3 *db, int forceZombie){
return SQLITE_BUSY;
}
#ifdef SQLITE_ENABLE_SQLLOG
if( sqlite3GlobalConfig.xSqllog ){
/* Closing the handle. Fourth parameter is passed the value 2. */
sqlite3GlobalConfig.xSqllog(sqlite3GlobalConfig.pSqllogArg, db, 0, 2);
}
#endif
/* Convert the connection into a zombie and then close it.
*/
db->magic = SQLITE_MAGIC_ZOMBIE;
@ -1116,6 +1144,7 @@ int sqlite3_busy_handler(
db->busyHandler.xFunc = xBusy;
db->busyHandler.pArg = pArg;
db->busyHandler.nBusy = 0;
db->busyTimeout = 0;
sqlite3_mutex_leave(db->mutex);
return SQLITE_OK;
}
@ -1153,8 +1182,8 @@ void sqlite3_progress_handler(
*/
int sqlite3_busy_timeout(sqlite3 *db, int ms){
if( ms>0 ){
db->busyTimeout = ms;
sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db);
db->busyTimeout = ms;
}else{
sqlite3_busy_handler(db, 0, 0);
}
@ -1767,6 +1796,15 @@ int sqlite3_extended_errcode(sqlite3 *db){
return db->errCode;
}
/*
** Return a string that describes the kind of error specified in the
** argument. For now, this simply calls the internal sqlite3ErrStr()
** function.
*/
const char *sqlite3_errstr(int rc){
return sqlite3ErrStr(rc);
}
/*
** Create a new collating function for database "db". The name is zName
** and the encoding is enc.
@ -2436,6 +2474,13 @@ opendb_out:
db->magic = SQLITE_MAGIC_SICK;
}
*ppDb = db;
#ifdef SQLITE_ENABLE_SQLLOG
if( sqlite3GlobalConfig.xSqllog ){
/* Opening a db handle. Fourth parameter is passed 0. */
void *pArg = sqlite3GlobalConfig.pSqllogArg;
sqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0);
}
#endif
return sqlite3ApiExit(0, rc);
}
@ -2741,7 +2786,7 @@ int sqlite3_table_column_metadata(
zDataType = pCol->zType;
zCollSeq = pCol->zColl;
notnull = pCol->notNull!=0;
primarykey = pCol->isPrimKey!=0;
primarykey = (pCol->colFlags & COLFLAG_PRIMKEY)!=0;
autoinc = pTab->iPKey==iCol && (pTab->tabFlags & TF_Autoincrement)!=0;
}else{
zDataType = "INTEGER";
@ -3004,8 +3049,7 @@ int sqlite3_test_control(int op, ...){
*/
case SQLITE_TESTCTRL_OPTIMIZATIONS: {
sqlite3 *db = va_arg(ap, sqlite3*);
int x = va_arg(ap,int);
db->flags = (x & SQLITE_OptMask) | (db->flags & ~SQLITE_OptMask);
db->dbOptFlags = (u16)(va_arg(ap, int) & 0xffff);
break;
}

View File

@ -46,6 +46,13 @@
#include "sqliteInt.h"
#if SQLITE_OS_UNIX /* This file is used on unix only */
/* Use posix_fallocate() if it is available
*/
#if !defined(HAVE_POSIX_FALLOCATE) \
&& (_XOPEN_SOURCE >= 600 || _POSIX_C_SOURCE >= 200112L)
# define HAVE_POSIX_FALLOCATE 1
#endif
/*
** There are various methods for file locking used for concurrency
** control:
@ -218,6 +225,10 @@ struct unixFile {
const char *zPath; /* Name of the file */
unixShm *pShm; /* Shared memory segment information */
int szChunk; /* Configured by FCNTL_CHUNK_SIZE */
#ifdef __QNXNTO__
int sectorSize; /* Device sector size */
int deviceCharacteristics; /* Precomputed device characteristics */
#endif
#if SQLITE_ENABLE_LOCKING_STYLE
int openFlags; /* The flags specified at open() */
#endif
@ -2086,13 +2097,13 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) {
** Close a file. Make sure the lock has been released before closing.
*/
static int dotlockClose(sqlite3_file *id) {
int rc;
int rc = SQLITE_OK;
if( id ){
unixFile *pFile = (unixFile*)id;
dotlockUnlock(id, NO_LOCK);
sqlite3_free(pFile->lockingContext);
rc = closeUnixFile(id);
}
rc = closeUnixFile(id);
return rc;
}
/****************** End of the dot-file lock implementation *******************
@ -2296,10 +2307,12 @@ static int flockUnlock(sqlite3_file *id, int eFileLock) {
** Close a file.
*/
static int flockClose(sqlite3_file *id) {
int rc = SQLITE_OK;
if( id ){
flockUnlock(id, NO_LOCK);
rc = closeUnixFile(id);
}
return closeUnixFile(id);
return rc;
}
#endif /* SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORK */
@ -3010,6 +3023,8 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
i64 newOffset;
#endif
TIMER_START;
assert( cnt==(cnt&0x1ffff) );
cnt &= 0x1ffff;
do{
#if defined(USE_PREAD)
got = osPread(id->h, pBuf, cnt, offset);
@ -3099,6 +3114,8 @@ static int seekAndWrite(unixFile *id, i64 offset, const void *pBuf, int cnt){
#if (!defined(USE_PREAD) && !defined(USE_PREAD64))
i64 newOffset;
#endif
assert( cnt==(cnt&0x1ffff) );
cnt &= 0x1ffff;
TIMER_START;
#if defined(USE_PREAD)
do{ got = osPwrite(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR );
@ -3564,6 +3581,9 @@ static void unixModeBit(unixFile *pFile, unsigned char mask, int *pArg){
}
}
/* Forward declaration */
static int unixGetTempname(int nBuf, char *zBuf);
/*
** Information and control of an open file handle.
*/
@ -3601,6 +3621,14 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
*(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName);
return SQLITE_OK;
}
case SQLITE_FCNTL_TEMPFILENAME: {
char *zTFile = sqlite3_malloc( pFile->pVfs->mxPathname );
if( zTFile ){
unixGetTempname(pFile->pVfs->mxPathname, zTFile);
*(char**)pArg = zTFile;
}
return SQLITE_OK;
}
#ifdef SQLITE_DEBUG
/* The pager calls this method to signal that it has done
** a rollback and that the database is therefore unchanged and
@ -3632,10 +3660,92 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
** a database and its journal file) that the sector size will be the
** same for both.
*/
static int unixSectorSize(sqlite3_file *pFile){
(void)pFile;
#ifndef __QNXNTO__
static int unixSectorSize(sqlite3_file *NotUsed){
UNUSED_PARAMETER(NotUsed);
return SQLITE_DEFAULT_SECTOR_SIZE;
}
#endif
/*
** The following version of unixSectorSize() is optimized for QNX.
*/
#ifdef __QNXNTO__
#include <sys/dcmd_blk.h>
#include <sys/statvfs.h>
static int unixSectorSize(sqlite3_file *id){
unixFile *pFile = (unixFile*)id;
if( pFile->sectorSize == 0 ){
struct statvfs fsInfo;
/* Set defaults for non-supported filesystems */
pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE;
pFile->deviceCharacteristics = 0;
if( fstatvfs(pFile->h, &fsInfo) == -1 ) {
return pFile->sectorSize;
}
if( !strcmp(fsInfo.f_basetype, "tmp") ) {
pFile->sectorSize = fsInfo.f_bsize;
pFile->deviceCharacteristics =
SQLITE_IOCAP_ATOMIC4K | /* All ram filesystem writes are atomic */
SQLITE_IOCAP_SAFE_APPEND | /* growing the file does not occur until
** the write succeeds */
SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind
** so it is ordered */
0;
}else if( strstr(fsInfo.f_basetype, "etfs") ){
pFile->sectorSize = fsInfo.f_bsize;
pFile->deviceCharacteristics =
/* etfs cluster size writes are atomic */
(pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) |
SQLITE_IOCAP_SAFE_APPEND | /* growing the file does not occur until
** the write succeeds */
SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind
** so it is ordered */
0;
}else if( !strcmp(fsInfo.f_basetype, "qnx6") ){
pFile->sectorSize = fsInfo.f_bsize;
pFile->deviceCharacteristics =
SQLITE_IOCAP_ATOMIC | /* All filesystem writes are atomic */
SQLITE_IOCAP_SAFE_APPEND | /* growing the file does not occur until
** the write succeeds */
SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind
** so it is ordered */
0;
}else if( !strcmp(fsInfo.f_basetype, "qnx4") ){
pFile->sectorSize = fsInfo.f_bsize;
pFile->deviceCharacteristics =
/* full bitset of atomics from max sector size and smaller */
((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 |
SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind
** so it is ordered */
0;
}else if( strstr(fsInfo.f_basetype, "dos") ){
pFile->sectorSize = fsInfo.f_bsize;
pFile->deviceCharacteristics =
/* full bitset of atomics from max sector size and smaller */
((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 |
SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind
** so it is ordered */
0;
}else{
pFile->deviceCharacteristics =
SQLITE_IOCAP_ATOMIC512 | /* blocks are atomic */
SQLITE_IOCAP_SAFE_APPEND | /* growing the file does not occur until
** the write succeeds */
0;
}
}
/* Last chance verification. If the sector size isn't a multiple of 512
** then it isn't valid.*/
if( pFile->sectorSize % 512 != 0 ){
pFile->deviceCharacteristics = 0;
pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE;
}
return pFile->sectorSize;
}
#endif /* __QNXNTO__ */
/*
** Return the device characteristics for the file.
@ -3652,11 +3762,15 @@ static int unixSectorSize(sqlite3_file *pFile){
*/
static int unixDeviceCharacteristics(sqlite3_file *id){
unixFile *p = (unixFile*)id;
int rc = 0;
#ifdef __QNXNTO__
if( p->sectorSize==0 ) unixSectorSize(id);
rc = p->deviceCharacteristics;
#endif
if( p->ctrlFlags & UNIXFILE_PSOW ){
return SQLITE_IOCAP_POWERSAFE_OVERWRITE;
}else{
return 0;
rc |= SQLITE_IOCAP_POWERSAFE_OVERWRITE;
}
return rc;
}
#ifndef SQLITE_OMIT_WAL
@ -4072,11 +4186,19 @@ static int unixShmMap(
** the requested memory region.
*/
if( !bExtend ) goto shmpage_out;
#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
if( osFallocate(pShmNode->h, sStat.st_size, nByte)!=0 ){
rc = unixLogError(SQLITE_IOERR_SHMSIZE, "fallocate",
pShmNode->zFilename);
goto shmpage_out;
}
#else
if( robust_ftruncate(pShmNode->h, nByte) ){
rc = unixLogError(SQLITE_IOERR_SHMSIZE, "ftruncate",
pShmNode->zFilename);
goto shmpage_out;
}
#endif
}
}
@ -4094,7 +4216,7 @@ static int unixShmMap(
if( pShmNode->h>=0 ){
pMem = mmap(0, szRegion,
pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE,
MAP_SHARED, pShmNode->h, pShmNode->nRegion*szRegion
MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion
);
if( pMem==MAP_FAILED ){
rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename);
@ -5278,8 +5400,13 @@ static int unixDelete(
int rc = SQLITE_OK;
UNUSED_PARAMETER(NotUsed);
SimulateIOError(return SQLITE_IOERR_DELETE);
if( osUnlink(zPath)==(-1) && errno!=ENOENT ){
return unixLogError(SQLITE_IOERR_DELETE, "unlink", zPath);
if( osUnlink(zPath)==(-1) ){
if( errno==ENOENT ){
rc = SQLITE_IOERR_DELETE_NOENT;
}else{
rc = unixLogError(SQLITE_IOERR_DELETE, "unlink", zPath);
}
return rc;
}
#ifndef SQLITE_DISABLE_DIRSYNC
if( (dirSync & 1)!=0 ){

View File

@ -24,6 +24,66 @@
*/
#include "os_common.h"
/*
** Compiling and using WAL mode requires several APIs that are only
** available in Windows platforms based on the NT kernel.
*/
#if !SQLITE_OS_WINNT && !defined(SQLITE_OMIT_WAL)
# error "WAL mode requires support from the Windows NT kernel, compile\
with SQLITE_OMIT_WAL."
#endif
/*
** Are most of the Win32 ANSI APIs available (i.e. with certain exceptions
** based on the sub-platform)?
*/
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
# define SQLITE_WIN32_HAS_ANSI
#endif
/*
** Are most of the Win32 Unicode APIs available (i.e. with certain exceptions
** based on the sub-platform)?
*/
#if SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT
# define SQLITE_WIN32_HAS_WIDE
#endif
/*
** Do we need to manually define the Win32 file mapping APIs for use with WAL
** mode (e.g. these APIs are available in the Windows CE SDK; however, they
** are not present in the header file)?
*/
#if SQLITE_WIN32_FILEMAPPING_API && !defined(SQLITE_OMIT_WAL)
/*
** Two of the file mapping APIs are different under WinRT. Figure out which
** set we need.
*/
#if SQLITE_OS_WINRT
WINBASEAPI HANDLE WINAPI CreateFileMappingFromApp(HANDLE, \
LPSECURITY_ATTRIBUTES, ULONG, ULONG64, LPCWSTR);
WINBASEAPI LPVOID WINAPI MapViewOfFileFromApp(HANDLE, ULONG, ULONG64, SIZE_T);
#else
#if defined(SQLITE_WIN32_HAS_ANSI)
WINBASEAPI HANDLE WINAPI CreateFileMappingA(HANDLE, LPSECURITY_ATTRIBUTES, \
DWORD, DWORD, DWORD, LPCSTR);
#endif /* defined(SQLITE_WIN32_HAS_ANSI) */
#if defined(SQLITE_WIN32_HAS_WIDE)
WINBASEAPI HANDLE WINAPI CreateFileMappingW(HANDLE, LPSECURITY_ATTRIBUTES, \
DWORD, DWORD, DWORD, LPCWSTR);
#endif /* defined(SQLITE_WIN32_HAS_WIDE) */
WINBASEAPI LPVOID WINAPI MapViewOfFile(HANDLE, DWORD, DWORD, DWORD, SIZE_T);
#endif /* SQLITE_OS_WINRT */
/*
** This file mapping API is common to both Win32 and WinRT.
*/
WINBASEAPI BOOL WINAPI UnmapViewOfFile(LPCVOID);
#endif /* SQLITE_WIN32_FILEMAPPING_API && !defined(SQLITE_OMIT_WAL) */
/*
** Macro to find the minimum of two numeric values.
*/
@ -229,14 +289,6 @@ int sqlite3_os_type = 0;
static int sqlite3_os_type = 0;
#endif
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
# define SQLITE_WIN32_HAS_ANSI
#endif
#if SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT
# define SQLITE_WIN32_HAS_WIDE
#endif
#ifndef SYSCALL
# define SYSCALL sqlite3_syscall_ptr
#endif
@ -308,6 +360,16 @@ static struct win_syscall {
#define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \
LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent)
#if (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_ANSI) && \
!defined(SQLITE_OMIT_WAL))
{ "CreateFileMappingA", (SYSCALL)CreateFileMappingA, 0 },
#else
{ "CreateFileMappingA", (SYSCALL)0, 0 },
#endif
#define osCreateFileMappingA ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \
DWORD,DWORD,DWORD,LPCSTR))aSyscall[6].pCurrent)
#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
!defined(SQLITE_OMIT_WAL))
{ "CreateFileMappingW", (SYSCALL)CreateFileMappingW, 0 },
@ -316,7 +378,7 @@ static struct win_syscall {
#endif
#define osCreateFileMappingW ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \
DWORD,DWORD,DWORD,LPCWSTR))aSyscall[6].pCurrent)
DWORD,DWORD,DWORD,LPCWSTR))aSyscall[7].pCurrent)
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
{ "CreateMutexW", (SYSCALL)CreateMutexW, 0 },
@ -325,7 +387,7 @@ static struct win_syscall {
#endif
#define osCreateMutexW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,BOOL, \
LPCWSTR))aSyscall[7].pCurrent)
LPCWSTR))aSyscall[8].pCurrent)
#if defined(SQLITE_WIN32_HAS_ANSI)
{ "DeleteFileA", (SYSCALL)DeleteFileA, 0 },
@ -333,7 +395,7 @@ static struct win_syscall {
{ "DeleteFileA", (SYSCALL)0, 0 },
#endif
#define osDeleteFileA ((BOOL(WINAPI*)(LPCSTR))aSyscall[8].pCurrent)
#define osDeleteFileA ((BOOL(WINAPI*)(LPCSTR))aSyscall[9].pCurrent)
#if defined(SQLITE_WIN32_HAS_WIDE)
{ "DeleteFileW", (SYSCALL)DeleteFileW, 0 },
@ -341,7 +403,7 @@ static struct win_syscall {
{ "DeleteFileW", (SYSCALL)0, 0 },
#endif
#define osDeleteFileW ((BOOL(WINAPI*)(LPCWSTR))aSyscall[9].pCurrent)
#define osDeleteFileW ((BOOL(WINAPI*)(LPCWSTR))aSyscall[10].pCurrent)
#if SQLITE_OS_WINCE
{ "FileTimeToLocalFileTime", (SYSCALL)FileTimeToLocalFileTime, 0 },
@ -350,7 +412,7 @@ static struct win_syscall {
#endif
#define osFileTimeToLocalFileTime ((BOOL(WINAPI*)(CONST FILETIME*, \
LPFILETIME))aSyscall[10].pCurrent)
LPFILETIME))aSyscall[11].pCurrent)
#if SQLITE_OS_WINCE
{ "FileTimeToSystemTime", (SYSCALL)FileTimeToSystemTime, 0 },
@ -359,11 +421,11 @@ static struct win_syscall {
#endif
#define osFileTimeToSystemTime ((BOOL(WINAPI*)(CONST FILETIME*, \
LPSYSTEMTIME))aSyscall[11].pCurrent)
LPSYSTEMTIME))aSyscall[12].pCurrent)
{ "FlushFileBuffers", (SYSCALL)FlushFileBuffers, 0 },
#define osFlushFileBuffers ((BOOL(WINAPI*)(HANDLE))aSyscall[12].pCurrent)
#define osFlushFileBuffers ((BOOL(WINAPI*)(HANDLE))aSyscall[13].pCurrent)
#if defined(SQLITE_WIN32_HAS_ANSI)
{ "FormatMessageA", (SYSCALL)FormatMessageA, 0 },
@ -372,7 +434,7 @@ static struct win_syscall {
#endif
#define osFormatMessageA ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPSTR, \
DWORD,va_list*))aSyscall[13].pCurrent)
DWORD,va_list*))aSyscall[14].pCurrent)
#if defined(SQLITE_WIN32_HAS_WIDE)
{ "FormatMessageW", (SYSCALL)FormatMessageW, 0 },
@ -381,15 +443,19 @@ static struct win_syscall {
#endif
#define osFormatMessageW ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPWSTR, \
DWORD,va_list*))aSyscall[14].pCurrent)
DWORD,va_list*))aSyscall[15].pCurrent)
#if !defined(SQLITE_OMIT_LOAD_EXTENSION)
{ "FreeLibrary", (SYSCALL)FreeLibrary, 0 },
#else
{ "FreeLibrary", (SYSCALL)0, 0 },
#endif
#define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[15].pCurrent)
#define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[16].pCurrent)
{ "GetCurrentProcessId", (SYSCALL)GetCurrentProcessId, 0 },
#define osGetCurrentProcessId ((DWORD(WINAPI*)(VOID))aSyscall[16].pCurrent)
#define osGetCurrentProcessId ((DWORD(WINAPI*)(VOID))aSyscall[17].pCurrent)
#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI)
{ "GetDiskFreeSpaceA", (SYSCALL)GetDiskFreeSpaceA, 0 },
@ -398,7 +464,7 @@ static struct win_syscall {
#endif
#define osGetDiskFreeSpaceA ((BOOL(WINAPI*)(LPCSTR,LPDWORD,LPDWORD,LPDWORD, \
LPDWORD))aSyscall[17].pCurrent)
LPDWORD))aSyscall[18].pCurrent)
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
{ "GetDiskFreeSpaceW", (SYSCALL)GetDiskFreeSpaceW, 0 },
@ -407,7 +473,7 @@ static struct win_syscall {
#endif
#define osGetDiskFreeSpaceW ((BOOL(WINAPI*)(LPCWSTR,LPDWORD,LPDWORD,LPDWORD, \
LPDWORD))aSyscall[18].pCurrent)
LPDWORD))aSyscall[19].pCurrent)
#if defined(SQLITE_WIN32_HAS_ANSI)
{ "GetFileAttributesA", (SYSCALL)GetFileAttributesA, 0 },
@ -415,7 +481,7 @@ static struct win_syscall {
{ "GetFileAttributesA", (SYSCALL)0, 0 },
#endif
#define osGetFileAttributesA ((DWORD(WINAPI*)(LPCSTR))aSyscall[19].pCurrent)
#define osGetFileAttributesA ((DWORD(WINAPI*)(LPCSTR))aSyscall[20].pCurrent)
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
{ "GetFileAttributesW", (SYSCALL)GetFileAttributesW, 0 },
@ -423,7 +489,7 @@ static struct win_syscall {
{ "GetFileAttributesW", (SYSCALL)0, 0 },
#endif
#define osGetFileAttributesW ((DWORD(WINAPI*)(LPCWSTR))aSyscall[20].pCurrent)
#define osGetFileAttributesW ((DWORD(WINAPI*)(LPCWSTR))aSyscall[21].pCurrent)
#if defined(SQLITE_WIN32_HAS_WIDE)
{ "GetFileAttributesExW", (SYSCALL)GetFileAttributesExW, 0 },
@ -432,7 +498,7 @@ static struct win_syscall {
#endif
#define osGetFileAttributesExW ((BOOL(WINAPI*)(LPCWSTR,GET_FILEEX_INFO_LEVELS, \
LPVOID))aSyscall[21].pCurrent)
LPVOID))aSyscall[22].pCurrent)
#if !SQLITE_OS_WINRT
{ "GetFileSize", (SYSCALL)GetFileSize, 0 },
@ -440,7 +506,7 @@ static struct win_syscall {
{ "GetFileSize", (SYSCALL)0, 0 },
#endif
#define osGetFileSize ((DWORD(WINAPI*)(HANDLE,LPDWORD))aSyscall[22].pCurrent)
#define osGetFileSize ((DWORD(WINAPI*)(HANDLE,LPDWORD))aSyscall[23].pCurrent)
#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI)
{ "GetFullPathNameA", (SYSCALL)GetFullPathNameA, 0 },
@ -449,7 +515,7 @@ static struct win_syscall {
#endif
#define osGetFullPathNameA ((DWORD(WINAPI*)(LPCSTR,DWORD,LPSTR, \
LPSTR*))aSyscall[23].pCurrent)
LPSTR*))aSyscall[24].pCurrent)
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
{ "GetFullPathNameW", (SYSCALL)GetFullPathNameW, 0 },
@ -458,12 +524,13 @@ static struct win_syscall {
#endif
#define osGetFullPathNameW ((DWORD(WINAPI*)(LPCWSTR,DWORD,LPWSTR, \
LPWSTR*))aSyscall[24].pCurrent)
LPWSTR*))aSyscall[25].pCurrent)
{ "GetLastError", (SYSCALL)GetLastError, 0 },
#define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[25].pCurrent)
#define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[26].pCurrent)
#if !defined(SQLITE_OMIT_LOAD_EXTENSION)
#if SQLITE_OS_WINCE
/* The GetProcAddressA() routine is only available on Windows CE. */
{ "GetProcAddressA", (SYSCALL)GetProcAddressA, 0 },
@ -472,9 +539,12 @@ static struct win_syscall {
** an ANSI string regardless of the _UNICODE setting */
{ "GetProcAddressA", (SYSCALL)GetProcAddress, 0 },
#endif
#else
{ "GetProcAddressA", (SYSCALL)0, 0 },
#endif
#define osGetProcAddressA ((FARPROC(WINAPI*)(HMODULE, \
LPCSTR))aSyscall[26].pCurrent)
LPCSTR))aSyscall[27].pCurrent)
#if !SQLITE_OS_WINRT
{ "GetSystemInfo", (SYSCALL)GetSystemInfo, 0 },
@ -482,11 +552,11 @@ static struct win_syscall {
{ "GetSystemInfo", (SYSCALL)0, 0 },
#endif
#define osGetSystemInfo ((VOID(WINAPI*)(LPSYSTEM_INFO))aSyscall[27].pCurrent)
#define osGetSystemInfo ((VOID(WINAPI*)(LPSYSTEM_INFO))aSyscall[28].pCurrent)
{ "GetSystemTime", (SYSCALL)GetSystemTime, 0 },
#define osGetSystemTime ((VOID(WINAPI*)(LPSYSTEMTIME))aSyscall[28].pCurrent)
#define osGetSystemTime ((VOID(WINAPI*)(LPSYSTEMTIME))aSyscall[29].pCurrent)
#if !SQLITE_OS_WINCE
{ "GetSystemTimeAsFileTime", (SYSCALL)GetSystemTimeAsFileTime, 0 },
@ -495,7 +565,7 @@ static struct win_syscall {
#endif
#define osGetSystemTimeAsFileTime ((VOID(WINAPI*)( \
LPFILETIME))aSyscall[29].pCurrent)
LPFILETIME))aSyscall[30].pCurrent)
#if defined(SQLITE_WIN32_HAS_ANSI)
{ "GetTempPathA", (SYSCALL)GetTempPathA, 0 },
@ -503,7 +573,7 @@ static struct win_syscall {
{ "GetTempPathA", (SYSCALL)0, 0 },
#endif
#define osGetTempPathA ((DWORD(WINAPI*)(DWORD,LPSTR))aSyscall[30].pCurrent)
#define osGetTempPathA ((DWORD(WINAPI*)(DWORD,LPSTR))aSyscall[31].pCurrent)
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
{ "GetTempPathW", (SYSCALL)GetTempPathW, 0 },
@ -511,7 +581,7 @@ static struct win_syscall {
{ "GetTempPathW", (SYSCALL)0, 0 },
#endif
#define osGetTempPathW ((DWORD(WINAPI*)(DWORD,LPWSTR))aSyscall[31].pCurrent)
#define osGetTempPathW ((DWORD(WINAPI*)(DWORD,LPWSTR))aSyscall[32].pCurrent)
#if !SQLITE_OS_WINRT
{ "GetTickCount", (SYSCALL)GetTickCount, 0 },
@ -519,7 +589,7 @@ static struct win_syscall {
{ "GetTickCount", (SYSCALL)0, 0 },
#endif
#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[32].pCurrent)
#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent)
#if defined(SQLITE_WIN32_HAS_ANSI)
{ "GetVersionExA", (SYSCALL)GetVersionExA, 0 },
@ -528,12 +598,12 @@ static struct win_syscall {
#endif
#define osGetVersionExA ((BOOL(WINAPI*)( \
LPOSVERSIONINFOA))aSyscall[33].pCurrent)
LPOSVERSIONINFOA))aSyscall[34].pCurrent)
{ "HeapAlloc", (SYSCALL)HeapAlloc, 0 },
#define osHeapAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD, \
SIZE_T))aSyscall[34].pCurrent)
SIZE_T))aSyscall[35].pCurrent)
#if !SQLITE_OS_WINRT
{ "HeapCreate", (SYSCALL)HeapCreate, 0 },
@ -542,7 +612,7 @@ static struct win_syscall {
#endif
#define osHeapCreate ((HANDLE(WINAPI*)(DWORD,SIZE_T, \
SIZE_T))aSyscall[35].pCurrent)
SIZE_T))aSyscall[36].pCurrent)
#if !SQLITE_OS_WINRT
{ "HeapDestroy", (SYSCALL)HeapDestroy, 0 },
@ -550,21 +620,21 @@ static struct win_syscall {
{ "HeapDestroy", (SYSCALL)0, 0 },
#endif
#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[36].pCurrent)
#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[37].pCurrent)
{ "HeapFree", (SYSCALL)HeapFree, 0 },
#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[37].pCurrent)
#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[38].pCurrent)
{ "HeapReAlloc", (SYSCALL)HeapReAlloc, 0 },
#define osHeapReAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD,LPVOID, \
SIZE_T))aSyscall[38].pCurrent)
SIZE_T))aSyscall[39].pCurrent)
{ "HeapSize", (SYSCALL)HeapSize, 0 },
#define osHeapSize ((SIZE_T(WINAPI*)(HANDLE,DWORD, \
LPCVOID))aSyscall[39].pCurrent)
LPCVOID))aSyscall[40].pCurrent)
#if !SQLITE_OS_WINRT
{ "HeapValidate", (SYSCALL)HeapValidate, 0 },
@ -573,23 +643,24 @@ static struct win_syscall {
#endif
#define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \
LPCVOID))aSyscall[40].pCurrent)
LPCVOID))aSyscall[41].pCurrent)
#if defined(SQLITE_WIN32_HAS_ANSI)
#if defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
{ "LoadLibraryA", (SYSCALL)LoadLibraryA, 0 },
#else
{ "LoadLibraryA", (SYSCALL)0, 0 },
#endif
#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[41].pCurrent)
#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[42].pCurrent)
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
!defined(SQLITE_OMIT_LOAD_EXTENSION)
{ "LoadLibraryW", (SYSCALL)LoadLibraryW, 0 },
#else
{ "LoadLibraryW", (SYSCALL)0, 0 },
#endif
#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[42].pCurrent)
#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[43].pCurrent)
#if !SQLITE_OS_WINRT
{ "LocalFree", (SYSCALL)LocalFree, 0 },
@ -597,7 +668,7 @@ static struct win_syscall {
{ "LocalFree", (SYSCALL)0, 0 },
#endif
#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[43].pCurrent)
#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[44].pCurrent)
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
{ "LockFile", (SYSCALL)LockFile, 0 },
@ -607,7 +678,7 @@ static struct win_syscall {
#ifndef osLockFile
#define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
DWORD))aSyscall[44].pCurrent)
DWORD))aSyscall[45].pCurrent)
#endif
#if !SQLITE_OS_WINCE
@ -618,7 +689,7 @@ static struct win_syscall {
#ifndef osLockFileEx
#define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \
LPOVERLAPPED))aSyscall[45].pCurrent)
LPOVERLAPPED))aSyscall[46].pCurrent)
#endif
#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL))
@ -628,26 +699,26 @@ static struct win_syscall {
#endif
#define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
SIZE_T))aSyscall[46].pCurrent)
SIZE_T))aSyscall[47].pCurrent)
{ "MultiByteToWideChar", (SYSCALL)MultiByteToWideChar, 0 },
#define osMultiByteToWideChar ((int(WINAPI*)(UINT,DWORD,LPCSTR,int,LPWSTR, \
int))aSyscall[47].pCurrent)
int))aSyscall[48].pCurrent)
{ "QueryPerformanceCounter", (SYSCALL)QueryPerformanceCounter, 0 },
#define osQueryPerformanceCounter ((BOOL(WINAPI*)( \
LARGE_INTEGER*))aSyscall[48].pCurrent)
LARGE_INTEGER*))aSyscall[49].pCurrent)
{ "ReadFile", (SYSCALL)ReadFile, 0 },
#define osReadFile ((BOOL(WINAPI*)(HANDLE,LPVOID,DWORD,LPDWORD, \
LPOVERLAPPED))aSyscall[49].pCurrent)
LPOVERLAPPED))aSyscall[50].pCurrent)
{ "SetEndOfFile", (SYSCALL)SetEndOfFile, 0 },
#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[50].pCurrent)
#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[51].pCurrent)
#if !SQLITE_OS_WINRT
{ "SetFilePointer", (SYSCALL)SetFilePointer, 0 },
@ -656,7 +727,7 @@ static struct win_syscall {
#endif
#define osSetFilePointer ((DWORD(WINAPI*)(HANDLE,LONG,PLONG, \
DWORD))aSyscall[51].pCurrent)
DWORD))aSyscall[52].pCurrent)
#if !SQLITE_OS_WINRT
{ "Sleep", (SYSCALL)Sleep, 0 },
@ -664,12 +735,12 @@ static struct win_syscall {
{ "Sleep", (SYSCALL)0, 0 },
#endif
#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[52].pCurrent)
#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[53].pCurrent)
{ "SystemTimeToFileTime", (SYSCALL)SystemTimeToFileTime, 0 },
#define osSystemTimeToFileTime ((BOOL(WINAPI*)(CONST SYSTEMTIME*, \
LPFILETIME))aSyscall[53].pCurrent)
LPFILETIME))aSyscall[54].pCurrent)
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
{ "UnlockFile", (SYSCALL)UnlockFile, 0 },
@ -679,7 +750,7 @@ static struct win_syscall {
#ifndef osUnlockFile
#define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
DWORD))aSyscall[54].pCurrent)
DWORD))aSyscall[55].pCurrent)
#endif
#if !SQLITE_OS_WINCE
@ -689,7 +760,7 @@ static struct win_syscall {
#endif
#define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
LPOVERLAPPED))aSyscall[55].pCurrent)
LPOVERLAPPED))aSyscall[56].pCurrent)
#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL)
{ "UnmapViewOfFile", (SYSCALL)UnmapViewOfFile, 0 },
@ -697,17 +768,17 @@ static struct win_syscall {
{ "UnmapViewOfFile", (SYSCALL)0, 0 },
#endif
#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[56].pCurrent)
#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[57].pCurrent)
{ "WideCharToMultiByte", (SYSCALL)WideCharToMultiByte, 0 },
#define osWideCharToMultiByte ((int(WINAPI*)(UINT,DWORD,LPCWSTR,int,LPSTR,int, \
LPCSTR,LPBOOL))aSyscall[57].pCurrent)
LPCSTR,LPBOOL))aSyscall[58].pCurrent)
{ "WriteFile", (SYSCALL)WriteFile, 0 },
#define osWriteFile ((BOOL(WINAPI*)(HANDLE,LPCVOID,DWORD,LPDWORD, \
LPOVERLAPPED))aSyscall[58].pCurrent)
LPOVERLAPPED))aSyscall[59].pCurrent)
#if SQLITE_OS_WINRT
{ "CreateEventExW", (SYSCALL)CreateEventExW, 0 },
@ -716,7 +787,7 @@ static struct win_syscall {
#endif
#define osCreateEventExW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,LPCWSTR, \
DWORD,DWORD))aSyscall[59].pCurrent)
DWORD,DWORD))aSyscall[60].pCurrent)
#if !SQLITE_OS_WINRT
{ "WaitForSingleObject", (SYSCALL)WaitForSingleObject, 0 },
@ -725,7 +796,7 @@ static struct win_syscall {
#endif
#define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \
DWORD))aSyscall[60].pCurrent)
DWORD))aSyscall[61].pCurrent)
#if SQLITE_OS_WINRT
{ "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 },
@ -734,7 +805,7 @@ static struct win_syscall {
#endif
#define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \
BOOL))aSyscall[61].pCurrent)
BOOL))aSyscall[62].pCurrent)
#if SQLITE_OS_WINRT
{ "SetFilePointerEx", (SYSCALL)SetFilePointerEx, 0 },
@ -743,7 +814,7 @@ static struct win_syscall {
#endif
#define osSetFilePointerEx ((BOOL(WINAPI*)(HANDLE,LARGE_INTEGER, \
PLARGE_INTEGER,DWORD))aSyscall[62].pCurrent)
PLARGE_INTEGER,DWORD))aSyscall[63].pCurrent)
#if SQLITE_OS_WINRT
{ "GetFileInformationByHandleEx", (SYSCALL)GetFileInformationByHandleEx, 0 },
@ -752,7 +823,7 @@ static struct win_syscall {
#endif
#define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \
FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[63].pCurrent)
FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[64].pCurrent)
#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
{ "MapViewOfFileFromApp", (SYSCALL)MapViewOfFileFromApp, 0 },
@ -761,7 +832,7 @@ static struct win_syscall {
#endif
#define osMapViewOfFileFromApp ((LPVOID(WINAPI*)(HANDLE,ULONG,ULONG64, \
SIZE_T))aSyscall[64].pCurrent)
SIZE_T))aSyscall[65].pCurrent)
#if SQLITE_OS_WINRT
{ "CreateFile2", (SYSCALL)CreateFile2, 0 },
@ -770,16 +841,16 @@ static struct win_syscall {
#endif
#define osCreateFile2 ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD,DWORD, \
LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[65].pCurrent)
LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[66].pCurrent)
#if SQLITE_OS_WINRT
#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_LOAD_EXTENSION)
{ "LoadPackagedLibrary", (SYSCALL)LoadPackagedLibrary, 0 },
#else
{ "LoadPackagedLibrary", (SYSCALL)0, 0 },
#endif
#define osLoadPackagedLibrary ((HMODULE(WINAPI*)(LPCWSTR, \
DWORD))aSyscall[66].pCurrent)
DWORD))aSyscall[67].pCurrent)
#if SQLITE_OS_WINRT
{ "GetTickCount64", (SYSCALL)GetTickCount64, 0 },
@ -787,7 +858,7 @@ static struct win_syscall {
{ "GetTickCount64", (SYSCALL)0, 0 },
#endif
#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[67].pCurrent)
#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[68].pCurrent)
#if SQLITE_OS_WINRT
{ "GetNativeSystemInfo", (SYSCALL)GetNativeSystemInfo, 0 },
@ -796,7 +867,7 @@ static struct win_syscall {
#endif
#define osGetNativeSystemInfo ((VOID(WINAPI*)( \
LPSYSTEM_INFO))aSyscall[68].pCurrent)
LPSYSTEM_INFO))aSyscall[69].pCurrent)
#if defined(SQLITE_WIN32_HAS_ANSI)
{ "OutputDebugStringA", (SYSCALL)OutputDebugStringA, 0 },
@ -804,7 +875,7 @@ static struct win_syscall {
{ "OutputDebugStringA", (SYSCALL)0, 0 },
#endif
#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[69].pCurrent)
#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[70].pCurrent)
#if defined(SQLITE_WIN32_HAS_WIDE)
{ "OutputDebugStringW", (SYSCALL)OutputDebugStringW, 0 },
@ -812,11 +883,11 @@ static struct win_syscall {
{ "OutputDebugStringW", (SYSCALL)0, 0 },
#endif
#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[70].pCurrent)
#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[71].pCurrent)
{ "GetProcessHeap", (SYSCALL)GetProcessHeap, 0 },
#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[71].pCurrent)
#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[72].pCurrent)
#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
{ "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 },
@ -825,7 +896,7 @@ static struct win_syscall {
#endif
#define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \
LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[72].pCurrent)
LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[73].pCurrent)
}; /* End of the overrideable system calls */
@ -983,6 +1054,8 @@ void sqlite3_win32_sleep(DWORD milliseconds){
*/
#if SQLITE_OS_WINCE || SQLITE_OS_WINRT
# define isNT() (1)
#elif !defined(SQLITE_WIN32_HAS_WIDE)
# define isNT() (0)
#else
static int isNT(void){
if( sqlite3_os_type==0 ){
@ -993,7 +1066,7 @@ void sqlite3_win32_sleep(DWORD milliseconds){
}
return sqlite3_os_type==2;
}
#endif /* SQLITE_OS_WINCE */
#endif
#ifdef SQLITE_WIN32_MALLOC
/*
@ -1203,7 +1276,7 @@ static LPWSTR utf8ToUnicode(const char *zFilename){
if( nChar==0 ){
return 0;
}
zWideFilename = sqlite3_malloc( nChar*sizeof(zWideFilename[0]) );
zWideFilename = sqlite3MallocZero( nChar*sizeof(zWideFilename[0]) );
if( zWideFilename==0 ){
return 0;
}
@ -1228,7 +1301,7 @@ static char *unicodeToUtf8(LPCWSTR zWideFilename){
if( nByte == 0 ){
return 0;
}
zFilename = sqlite3_malloc( nByte );
zFilename = sqlite3MallocZero( nByte );
if( zFilename==0 ){
return 0;
}
@ -1258,7 +1331,7 @@ static LPWSTR mbcsToUnicode(const char *zFilename){
if( nByte==0 ){
return 0;
}
zMbcsFilename = sqlite3_malloc( nByte*sizeof(zMbcsFilename[0]) );
zMbcsFilename = sqlite3MallocZero( nByte*sizeof(zMbcsFilename[0]) );
if( zMbcsFilename==0 ){
return 0;
}
@ -1287,7 +1360,7 @@ static char *unicodeToMbcs(LPCWSTR zWideFilename){
if( nByte == 0 ){
return 0;
}
zFilename = sqlite3_malloc( nByte );
zFilename = sqlite3MallocZero( nByte );
if( zFilename==0 ){
return 0;
}
@ -2119,7 +2192,8 @@ static int winWrite(
if( retryIoerr(&nRetry, &lastErrno) ) continue;
break;
}
if( nWrite<=0 ){
assert( nWrite==0 || nWrite<=(DWORD)nRem );
if( nWrite==0 || nWrite>(DWORD)nRem ){
lastErrno = osGetLastError();
break;
}
@ -2617,6 +2691,9 @@ static void winModeBit(winFile *pFile, unsigned char mask, int *pArg){
}
}
/* Forward declaration */
static int getTempname(int nBuf, char *zBuf);
/*
** Control and query of the open file handle.
*/
@ -2677,6 +2754,14 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){
}
return SQLITE_OK;
}
case SQLITE_FCNTL_TEMPFILENAME: {
char *zTFile = sqlite3_malloc( pFile->pVfs->mxPathname );
if( zTFile ){
getTempname(pFile->pVfs->mxPathname, zTFile);
*(char**)pArg = zTFile;
}
return SQLITE_OK;
}
}
return SQLITE_NOTFOUND;
}
@ -2934,16 +3019,14 @@ static int winOpenSharedMemory(winFile *pDbFd){
/* Allocate space for the new sqlite3_shm object. Also speculatively
** allocate space for a new winShmNode and filename.
*/
p = sqlite3_malloc( sizeof(*p) );
p = sqlite3MallocZero( sizeof(*p) );
if( p==0 ) return SQLITE_IOERR_NOMEM;
memset(p, 0, sizeof(*p));
nName = sqlite3Strlen30(pDbFd->zPath);
pNew = sqlite3_malloc( sizeof(*pShmNode) + nName + 17 );
pNew = sqlite3MallocZero( sizeof(*pShmNode) + nName + 17 );
if( pNew==0 ){
sqlite3_free(p);
return SQLITE_IOERR_NOMEM;
}
memset(pNew, 0, sizeof(*pNew) + nName + 17);
pNew->zFilename = (char*)&pNew[1];
sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath);
sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename);
@ -3280,17 +3363,21 @@ static int winShmMap(
pShmNode->aRegion = apNew;
while( pShmNode->nRegion<=iRegion ){
HANDLE hMap; /* file-mapping handle */
HANDLE hMap = NULL; /* file-mapping handle */
void *pMap = 0; /* Mapped memory region */
#if SQLITE_OS_WINRT
hMap = osCreateFileMappingFromApp(pShmNode->hFile.h,
NULL, PAGE_READWRITE, nByte, NULL
);
#else
#elif defined(SQLITE_WIN32_HAS_WIDE)
hMap = osCreateFileMappingW(pShmNode->hFile.h,
NULL, PAGE_READWRITE, 0, nByte, NULL
);
#elif defined(SQLITE_WIN32_HAS_ANSI)
hMap = osCreateFileMappingA(pShmNode->hFile.h,
NULL, PAGE_READWRITE, 0, nByte, NULL
);
#endif
OSTRACE(("SHM-MAP pid-%d create region=%d nbyte=%d %s\n",
(int)osGetCurrentProcessId(), pShmNode->nRegion, nByte,
@ -3812,14 +3899,24 @@ static int winDelete(
&sAttrData) ){
attr = sAttrData.dwFileAttributes;
}else{
rc = SQLITE_OK; /* Already gone? */
lastErrno = osGetLastError();
if( lastErrno==ERROR_FILE_NOT_FOUND || lastErrno==ERROR_PATH_NOT_FOUND ){
rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
}else{
rc = SQLITE_ERROR;
}
break;
}
#else
attr = osGetFileAttributesW(zConverted);
#endif
if ( attr==INVALID_FILE_ATTRIBUTES ){
rc = SQLITE_OK; /* Already gone? */
lastErrno = osGetLastError();
if( lastErrno==ERROR_FILE_NOT_FOUND || lastErrno==ERROR_PATH_NOT_FOUND ){
rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
}else{
rc = SQLITE_ERROR;
}
break;
}
if ( attr&FILE_ATTRIBUTE_DIRECTORY ){
@ -3841,7 +3938,12 @@ static int winDelete(
do {
attr = osGetFileAttributesA(zConverted);
if ( attr==INVALID_FILE_ATTRIBUTES ){
rc = SQLITE_OK; /* Already gone? */
lastErrno = osGetLastError();
if( lastErrno==ERROR_FILE_NOT_FOUND || lastErrno==ERROR_PATH_NOT_FOUND ){
rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
}else{
rc = SQLITE_ERROR;
}
break;
}
if ( attr&FILE_ATTRIBUTE_DIRECTORY ){
@ -3859,7 +3961,7 @@ static int winDelete(
} while(1);
}
#endif
if( rc ){
if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){
rc = winLogError(SQLITE_IOERR_DELETE, lastErrno,
"winDelete", zFilename);
}else{
@ -4039,7 +4141,7 @@ static int winFullPathname(
#endif
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__)
int nByte;
DWORD nByte;
void *zConverted;
char *zOut;
@ -4073,13 +4175,27 @@ static int winFullPathname(
}
if( isNT() ){
LPWSTR zTemp;
nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0) + 3;
zTemp = sqlite3_malloc( nByte*sizeof(zTemp[0]) );
nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0);
if( nByte==0 ){
winLogError(SQLITE_ERROR, osGetLastError(),
"GetFullPathNameW1", zConverted);
sqlite3_free(zConverted);
return SQLITE_CANTOPEN_FULLPATH;
}
nByte += 3;
zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
if( zTemp==0 ){
sqlite3_free(zConverted);
return SQLITE_IOERR_NOMEM;
}
osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0);
nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0);
if( nByte==0 ){
winLogError(SQLITE_ERROR, osGetLastError(),
"GetFullPathNameW2", zConverted);
sqlite3_free(zConverted);
sqlite3_free(zTemp);
return SQLITE_CANTOPEN_FULLPATH;
}
sqlite3_free(zConverted);
zOut = unicodeToUtf8(zTemp);
sqlite3_free(zTemp);
@ -4087,13 +4203,27 @@ static int winFullPathname(
#ifdef SQLITE_WIN32_HAS_ANSI
else{
char *zTemp;
nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0) + 3;
zTemp = sqlite3_malloc( nByte*sizeof(zTemp[0]) );
nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0);
if( nByte==0 ){
winLogError(SQLITE_ERROR, osGetLastError(),
"GetFullPathNameA1", zConverted);
sqlite3_free(zConverted);
return SQLITE_CANTOPEN_FULLPATH;
}
nByte += 3;
zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
if( zTemp==0 ){
sqlite3_free(zConverted);
return SQLITE_IOERR_NOMEM;
}
osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
nByte = osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
if( nByte==0 ){
winLogError(SQLITE_ERROR, osGetLastError(),
"GetFullPathNameA2", zConverted);
sqlite3_free(zConverted);
sqlite3_free(zTemp);
return SQLITE_CANTOPEN_FULLPATH;
}
sqlite3_free(zConverted);
zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
sqlite3_free(zTemp);
@ -4351,7 +4481,7 @@ int sqlite3_os_init(void){
/* Double-check that the aSyscall[] array has been constructed
** correctly. See ticket [bb3a86e890c8e96ab] */
assert( ArraySize(aSyscall)==73 );
assert( ArraySize(aSyscall)==74 );
#ifndef SQLITE_OMIT_WAL
/* get memory map allocation granularity */
@ -4370,7 +4500,7 @@ int sqlite3_os_init(void){
int sqlite3_os_end(void){
#if SQLITE_OS_WINRT
if( sleepObj != NULL ){
if( sleepObj!=NULL ){
osCloseHandle(sleepObj);
sleepObj = NULL;
}

View File

@ -1941,12 +1941,13 @@ static int pager_end_transaction(Pager *pPager, int hasMaster){
** file should be closed and deleted. If this connection writes to
** the database file, it will do so using an in-memory journal.
*/
int bDelete = (!pPager->tempFile && sqlite3JournalExists(pPager->jfd));
assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE
|| pPager->journalMode==PAGER_JOURNALMODE_MEMORY
|| pPager->journalMode==PAGER_JOURNALMODE_WAL
);
sqlite3OsClose(pPager->jfd);
if( !pPager->tempFile ){
if( bDelete ){
rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
}
}
@ -2509,6 +2510,21 @@ static int pager_truncate(Pager *pPager, Pgno nPage){
return rc;
}
/*
** Return a sanitized version of the sector-size of OS file pFile. The
** return value is guaranteed to lie between 32 and MAX_SECTOR_SIZE.
*/
int sqlite3SectorSize(sqlite3_file *pFile){
int iRet = sqlite3OsSectorSize(pFile);
if( iRet<32 ){
iRet = 512;
}else if( iRet>MAX_SECTOR_SIZE ){
assert( MAX_SECTOR_SIZE>=512 );
iRet = MAX_SECTOR_SIZE;
}
return iRet;
}
/*
** Set the value of the Pager.sectorSize variable for the given
** pager based on the value returned by the xSectorSize method
@ -2544,14 +2560,7 @@ static void setSectorSize(Pager *pPager){
** call will segfault. */
pPager->sectorSize = 512;
}else{
pPager->sectorSize = sqlite3OsSectorSize(pPager->fd);
if( pPager->sectorSize<32 ){
pPager->sectorSize = 512;
}
if( pPager->sectorSize>MAX_SECTOR_SIZE ){
assert( MAX_SECTOR_SIZE>=512 );
pPager->sectorSize = MAX_SECTOR_SIZE;
}
pPager->sectorSize = sqlite3SectorSize(pPager->fd);
}
}
@ -3151,6 +3160,7 @@ static int pagerOpenWalIfPresent(Pager *pPager){
if( rc ) return rc;
if( nPage==0 ){
rc = sqlite3OsDelete(pPager->pVfs, pPager->zWal, 0);
if( rc==SQLITE_IOERR_DELETE_NOENT ) rc = SQLITE_OK;
isWal = 0;
}else{
rc = sqlite3OsAccess(
@ -3468,9 +3478,16 @@ void sqlite3PagerSetBusyhandler(
Pager *pPager, /* Pager object */
int (*xBusyHandler)(void *), /* Pointer to busy-handler function */
void *pBusyHandlerArg /* Argument to pass to xBusyHandler */
){
){
pPager->xBusyHandler = xBusyHandler;
pPager->pBusyHandlerArg = pBusyHandlerArg;
if( isOpen(pPager->fd) ){
void **ap = (void **)&pPager->xBusyHandler;
assert( ((int(*)(void *))(ap[0]))==xBusyHandler );
assert( ap[1]==pBusyHandlerArg );
sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_BUSYHANDLER, (void *)ap);
}
}
/*
@ -4448,7 +4465,7 @@ int sqlite3PagerOpen(
memcpy(pPager->zFilename, zPathname, nPathname);
if( nUri ) memcpy(&pPager->zFilename[nPathname+1], zUri, nUri);
memcpy(pPager->zJournal, zPathname, nPathname);
memcpy(&pPager->zJournal[nPathname], "-journal\000", 8+1);
memcpy(&pPager->zJournal[nPathname], "-journal\000", 8+2);
sqlite3FileSuffix3(pPager->zFilename, pPager->zJournal);
#ifndef SQLITE_OMIT_WAL
pPager->zWal = &pPager->zJournal[nPathname+8+1];
@ -5650,7 +5667,7 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){
# define DIRECT_MODE isDirectMode
#endif
if( !pPager->changeCountDone && pPager->dbSize>0 ){
if( !pPager->changeCountDone && ALWAYS(pPager->dbSize>0) ){
PgHdr *pPgHdr; /* Reference to page 1 */
assert( !pPager->tempFile && isOpen(pPager->fd) );
@ -5870,7 +5887,7 @@ int sqlite3PagerCommitPhaseOne(
/* If this transaction has made the database smaller, then all pages
** being discarded by the truncation must be written to the journal
** file. This can only happen in auto-vacuum mode.
** file.
**
** Before reading the pages with page numbers larger than the
** current value of Pager.dbSize, set dbSize back to the value
@ -5878,7 +5895,6 @@ int sqlite3PagerCommitPhaseOne(
** calls to sqlite3PagerGet() return zeroed pages instead of
** reading data from the database file.
*/
#ifndef SQLITE_OMIT_AUTOVACUUM
if( pPager->dbSize<pPager->dbOrigSize
&& pPager->journalMode!=PAGER_JOURNALMODE_OFF
){
@ -5898,7 +5914,6 @@ int sqlite3PagerCommitPhaseOne(
}
pPager->dbSize = dbSize;
}
#endif
/* Write the master journal name into the journal file. If a master
** journal file name has already been written to the journal file,
@ -6901,6 +6916,8 @@ int sqlite3PagerCloseWal(Pager *pPager){
return rc;
}
#endif /* !SQLITE_OMIT_WAL */
#ifdef SQLITE_ENABLE_ZIPVFS
/*
** A read-lock must be held on the pager when this function is called. If
@ -6930,6 +6947,4 @@ void *sqlite3PagerCodec(PgHdr *pPg){
}
#endif /* SQLITE_HAS_CODEC */
#endif /* !SQLITE_OMIT_WAL */
#endif /* SQLITE_OMIT_DISKIO */

View File

@ -138,11 +138,14 @@ int sqlite3PagerOpenSavepoint(Pager *pPager, int n);
int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint);
int sqlite3PagerSharedLock(Pager *pPager);
int sqlite3PagerCheckpoint(Pager *pPager, int, int*, int*);
int sqlite3PagerWalSupported(Pager *pPager);
int sqlite3PagerWalCallback(Pager *pPager);
int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
int sqlite3PagerCloseWal(Pager *pPager);
#ifndef SQLITE_OMIT_WAL
int sqlite3PagerCheckpoint(Pager *pPager, int, int*, int*);
int sqlite3PagerWalSupported(Pager *pPager);
int sqlite3PagerWalCallback(Pager *pPager);
int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
int sqlite3PagerCloseWal(Pager *pPager);
#endif
#ifdef SQLITE_ENABLE_ZIPVFS
int sqlite3PagerWalFramesize(Pager *pPager);
#endif
@ -160,6 +163,7 @@ void *sqlite3PagerTempSpace(Pager*);
int sqlite3PagerIsMemdb(Pager*);
void sqlite3PagerCacheStat(Pager *, int, int, int *);
void sqlite3PagerClearCache(Pager *);
int sqlite3SectorSize(sqlite3_file *);
/* Functions used to truncate the database file. */
void sqlite3PagerTruncateImage(Pager*,Pgno);

View File

@ -815,7 +815,7 @@ expr(A) ::= VARIABLE(X). {
spanSet(&A, &X, &X);
}
expr(A) ::= expr(E) COLLATE ids(C). {
A.pExpr = sqlite3ExprSetCollByToken(pParse, E.pExpr, &C);
A.pExpr = sqlite3ExprAddCollateToken(pParse, E.pExpr, &C);
A.zStart = E.zStart;
A.zEnd = &C.z[C.n];
}
@ -1140,22 +1140,14 @@ uniqueflag(A) ::= . {A = OE_None;}
idxlist_opt(A) ::= . {A = 0;}
idxlist_opt(A) ::= LP idxlist(X) RP. {A = X;}
idxlist(A) ::= idxlist(X) COMMA nm(Y) collate(C) sortorder(Z). {
Expr *p = 0;
if( C.n>0 ){
p = sqlite3Expr(pParse->db, TK_COLUMN, 0);
sqlite3ExprSetCollByToken(pParse, p, &C);
}
Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C);
A = sqlite3ExprListAppend(pParse,X, p);
sqlite3ExprListSetName(pParse,A,&Y,1);
sqlite3ExprListCheckLength(pParse, A, "index");
if( A ) A->a[A->nExpr-1].sortOrder = (u8)Z;
}
idxlist(A) ::= nm(Y) collate(C) sortorder(Z). {
Expr *p = 0;
if( C.n>0 ){
p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
sqlite3ExprSetCollByToken(pParse, p, &C);
}
Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C);
A = sqlite3ExprListAppend(pParse,0, p);
sqlite3ExprListSetName(pParse, A, &Y, 1);
sqlite3ExprListCheckLength(pParse, A, "index");

View File

@ -357,6 +357,7 @@ void sqlite3Pragma(
aFcntl[1] = zLeft;
aFcntl[2] = zRight;
aFcntl[3] = 0;
db->busyHandler.nBusy = 0;
rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl);
if( rc==SQLITE_OK ){
if( aFcntl[0] ){
@ -974,7 +975,8 @@ void sqlite3Pragma(
}else{
sqlite3VdbeAddOp2(v, OP_Null, 0, 5);
}
sqlite3VdbeAddOp2(v, OP_Integer, pCol->isPrimKey, 6);
sqlite3VdbeAddOp2(v, OP_Integer,
(pCol->colFlags&COLFLAG_PRIMKEY)!=0, 6);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6);
}
}
@ -1233,7 +1235,7 @@ void sqlite3Pragma(
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName),
P4_DYNAMIC);
sqlite3VdbeAddOp3(v, OP_Move, 2, 4, 1);
sqlite3VdbeAddOp2(v, OP_Move, 2, 4);
sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 2);
sqlite3VdbeAddOp2(v, OP_ResultRow, 2, 1);
sqlite3VdbeJumpHere(v, addr);
@ -1536,6 +1538,22 @@ void sqlite3Pragma(
sqlite3_db_release_memory(db);
}else
/*
** PRAGMA busy_timeout
** PRAGMA busy_timeout = N
**
** Call sqlite3_busy_timeout(db, N). Return the current timeout value
** if one is set. If no busy handler or a different busy handler is set
** then 0 is returned. Setting the busy_timeout to 0 or negative
** disables the timeout.
*/
if( sqlite3StrICmp(zLeft, "busy_timeout")==0 ){
if( zRight ){
sqlite3_busy_timeout(db, sqlite3Atoi(zRight));
}
returnSingleInt(pParse, "timeout", db->busyTimeout);
}else
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
/*
** Report the current state of file logs for all databases
@ -1551,13 +1569,12 @@ void sqlite3Pragma(
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "status", SQLITE_STATIC);
for(i=0; i<db->nDb; i++){
Btree *pBt;
Pager *pPager;
const char *zState = "unknown";
int j;
if( db->aDb[i].zName==0 ) continue;
sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, db->aDb[i].zName, P4_STATIC);
pBt = db->aDb[i].pBt;
if( pBt==0 || (pPager = sqlite3BtreePager(pBt))==0 ){
if( pBt==0 || sqlite3BtreePager(pBt)==0 ){
zState = "closed";
}else if( sqlite3_file_control(db, i ? db->aDb[i].zName : 0,
SQLITE_FCNTL_LOCKSTATE, &j)==SQLITE_OK ){

View File

@ -134,7 +134,9 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){
static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
int rc;
int i;
#ifndef SQLITE_OMIT_DEPRECATED
int size;
#endif
Table *pTab;
Db *pDb;
char const *azArg[4];

View File

@ -68,6 +68,15 @@ static void incrAggFunctionDepth(Expr *pExpr, int N){
** from the result in the result-set. We might fix this someday. Or
** then again, we might not...
**
** If the reference is followed by a COLLATE operator, then make sure
** the COLLATE operator is preserved. For example:
**
** SELECT a+b, c+d FROM t1 ORDER BY 1 COLLATE nocase;
**
** Should be transformed into:
**
** SELECT a+b, c+d FROM t1 ORDER BY (a+b) COLLATE nocase;
**
** The nSubquery parameter specifies how many levels of subquery the
** alias is removed from the original expression. The usually value is
** zero but it might be more if the alias is contained within a subquery
@ -91,8 +100,9 @@ static void resolveAlias(
assert( pOrig!=0 );
assert( pOrig->flags & EP_Resolved );
db = pParse->db;
pDup = sqlite3ExprDup(db, pOrig, 0);
if( pDup==0 ) return;
if( pOrig->op!=TK_COLUMN && zType[0]!='G' ){
pDup = sqlite3ExprDup(db, pOrig, 0);
incrAggFunctionDepth(pDup, nSubquery);
pDup = sqlite3PExpr(pParse, TK_AS, pDup, 0, 0);
if( pDup==0 ) return;
@ -100,32 +110,26 @@ static void resolveAlias(
pEList->a[iCol].iAlias = (u16)(++pParse->nAlias);
}
pDup->iTable = pEList->a[iCol].iAlias;
}else if( ExprHasProperty(pOrig, EP_IntValue) || pOrig->u.zToken==0 ){
pDup = sqlite3ExprDup(db, pOrig, 0);
if( pDup==0 ) return;
}else{
char *zToken = pOrig->u.zToken;
assert( zToken!=0 );
pOrig->u.zToken = 0;
pDup = sqlite3ExprDup(db, pOrig, 0);
pOrig->u.zToken = zToken;
if( pDup==0 ) return;
assert( (pDup->flags & (EP_Reduced|EP_TokenOnly))==0 );
pDup->flags2 |= EP2_MallocedToken;
pDup->u.zToken = sqlite3DbStrDup(db, zToken);
}
if( pExpr->flags & EP_ExpCollate ){
pDup->pColl = pExpr->pColl;
pDup->flags |= EP_ExpCollate;
if( pExpr->op==TK_COLLATE ){
pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
}
/* Before calling sqlite3ExprDelete(), set the EP_Static flag. This
** prevents ExprDelete() from deleting the Expr structure itself,
** allowing it to be repopulated by the memcpy() on the following line.
** The pExpr->u.zToken might point into memory that will be freed by the
** sqlite3DbFree(db, pDup) on the last line of this block, so be sure to
** make a copy of the token before doing the sqlite3DbFree().
*/
ExprSetProperty(pExpr, EP_Static);
sqlite3ExprDelete(db, pExpr);
memcpy(pExpr, pDup, sizeof(*pExpr));
if( !ExprHasProperty(pExpr, EP_IntValue) && pExpr->u.zToken!=0 ){
assert( (pExpr->flags & (EP_Reduced|EP_TokenOnly))==0 );
pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken);
pExpr->flags2 |= EP2_MallocedToken;
}
sqlite3DbFree(db, pDup);
}
@ -195,7 +199,7 @@ static int lookupName(
assert( pNC ); /* the name context cannot be NULL. */
assert( zCol ); /* The Z in X.Y.Z cannot be NULL */
assert( ~ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
/* Initialize the node to no-match */
pExpr->iTable = -1;
@ -812,7 +816,7 @@ static int resolveCompoundOrderBy(
int iCol = -1;
Expr *pE, *pDup;
if( pItem->done ) continue;
pE = pItem->pExpr;
pE = sqlite3ExprSkipCollate(pItem->pExpr);
if( sqlite3ExprIsInteger(pE, &iCol) ){
if( iCol<=0 || iCol>pEList->nExpr ){
resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr);
@ -830,14 +834,20 @@ static int resolveCompoundOrderBy(
}
}
if( iCol>0 ){
CollSeq *pColl = pE->pColl;
int flags = pE->flags & EP_ExpCollate;
/* Convert the ORDER BY term into an integer column number iCol,
** taking care to preserve the COLLATE clause if it exists */
Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
if( pNew==0 ) return 1;
pNew->flags |= EP_IntValue;
pNew->u.iValue = iCol;
if( pItem->pExpr==pE ){
pItem->pExpr = pNew;
}else{
assert( pItem->pExpr->op==TK_COLLATE );
assert( pItem->pExpr->pLeft==pE );
pItem->pExpr->pLeft = pNew;
}
sqlite3ExprDelete(db, pE);
pItem->pExpr = pE = sqlite3Expr(db, TK_INTEGER, 0);
if( pE==0 ) return 1;
pE->pColl = pColl;
pE->flags |= EP_IntValue | flags;
pE->u.iValue = iCol;
pItem->iOrderByCol = (u16)iCol;
pItem->done = 1;
}else{
@ -942,11 +952,11 @@ static int resolveOrderGroupBy(
pItem->iOrderByCol = (u16)iCol;
continue;
}
if( sqlite3ExprIsInteger(pE, &iCol) ){
if( sqlite3ExprIsInteger(sqlite3ExprSkipCollate(pE), &iCol) ){
/* The ORDER BY term is an integer constant. Again, set the column
** number so that sqlite3ResolveOrderGroupBy() will convert the
** order-by term to a copy of the result-set expression */
if( iCol<1 ){
if( iCol<1 || iCol>0xffff ){
resolveOutOfRangeError(pParse, zType, i+1, nResult);
return 1;
}

View File

@ -525,6 +525,19 @@ static int checkForMultiColumnSelectError(
}
#endif
/*
** An instance of the following object is used to record information about
** how to process the DISTINCT keyword, to simplify passing that information
** into the selectInnerLoop() routine.
*/
typedef struct DistinctCtx DistinctCtx;
struct DistinctCtx {
u8 isTnct; /* True if the DISTINCT keyword is present */
u8 eTnctType; /* One of the WHERE_DISTINCT_* operators */
int tabTnct; /* Ephemeral table used for DISTINCT processing */
int addrTnct; /* Address of OP_OpenEphemeral opcode for tabTnct */
};
/*
** This routine generates the code for the inside of the inner loop
** of a SELECT.
@ -541,7 +554,7 @@ static void selectInnerLoop(
int srcTab, /* Pull data from this table */
int nColumn, /* Number of columns in the source table */
ExprList *pOrderBy, /* If not NULL, sort results using this key */
int distinct, /* If >=0, make sure results are distinct */
DistinctCtx *pDistinct, /* If not NULL, info on how to process DISTINCT */
SelectDest *pDest, /* How to dispose of the results */
int iContinue, /* Jump here to continue with next row */
int iBreak /* Jump here to break out of the inner loop */
@ -557,7 +570,7 @@ static void selectInnerLoop(
assert( v );
if( NEVER(v==0) ) return;
assert( pEList!=0 );
hasDistinct = distinct>=0;
hasDistinct = pDistinct ? pDistinct->eTnctType : WHERE_DISTINCT_NOOP;
if( pOrderBy==0 && !hasDistinct ){
codeOffset(v, p, iContinue);
}
@ -597,7 +610,55 @@ static void selectInnerLoop(
if( hasDistinct ){
assert( pEList!=0 );
assert( pEList->nExpr==nColumn );
codeDistinct(pParse, distinct, iContinue, nColumn, regResult);
switch( pDistinct->eTnctType ){
case WHERE_DISTINCT_ORDERED: {
VdbeOp *pOp; /* No longer required OpenEphemeral instr. */
int iJump; /* Jump destination */
int regPrev; /* Previous row content */
/* Allocate space for the previous row */
regPrev = pParse->nMem+1;
pParse->nMem += nColumn;
/* Change the OP_OpenEphemeral coded earlier to an OP_Null
** sets the MEM_Cleared bit on the first register of the
** previous value. This will cause the OP_Ne below to always
** fail on the first iteration of the loop even if the first
** row is all NULLs.
*/
sqlite3VdbeChangeToNoop(v, pDistinct->addrTnct);
pOp = sqlite3VdbeGetOp(v, pDistinct->addrTnct);
pOp->opcode = OP_Null;
pOp->p1 = 1;
pOp->p2 = regPrev;
iJump = sqlite3VdbeCurrentAddr(v) + nColumn;
for(i=0; i<nColumn; i++){
CollSeq *pColl = sqlite3ExprCollSeq(pParse, pEList->a[i].pExpr);
if( i<nColumn-1 ){
sqlite3VdbeAddOp3(v, OP_Ne, regResult+i, iJump, regPrev+i);
}else{
sqlite3VdbeAddOp3(v, OP_Eq, regResult+i, iContinue, regPrev+i);
}
sqlite3VdbeChangeP4(v, -1, (const char *)pColl, P4_COLLSEQ);
sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
}
assert( sqlite3VdbeCurrentAddr(v)==iJump );
sqlite3VdbeAddOp3(v, OP_Copy, regResult, regPrev, nColumn-1);
break;
}
case WHERE_DISTINCT_UNIQUE: {
sqlite3VdbeChangeToNoop(v, pDistinct->addrTnct);
break;
}
default: {
assert( pDistinct->eTnctType==WHERE_DISTINCT_UNORDERED );
codeDistinct(pParse, pDistinct->tabTnct, iContinue, nColumn, regResult);
break;
}
}
if( pOrderBy==0 ){
codeOffset(v, p, iContinue);
}
@ -655,7 +716,8 @@ static void selectInnerLoop(
*/
case SRT_Set: {
assert( nColumn==1 );
p->affinity = sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affSdst);
pDest->affSdst =
sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affSdst);
if( pOrderBy ){
/* At first glance you would think we could optimize out the
** ORDER BY in this case since the order of entries in the set
@ -664,7 +726,7 @@ static void selectInnerLoop(
pushOntoSorter(pParse, pOrderBy, p, regResult);
}else{
int r1 = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, 1, r1, &p->affinity, 1);
sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult,1,r1, &pDest->affSdst, 1);
sqlite3ExprCacheAffinityChange(pParse, regResult, 1);
sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1);
sqlite3ReleaseTempReg(pParse, r1);
@ -931,7 +993,8 @@ static void generateSortTail(
#ifndef SQLITE_OMIT_SUBQUERY
case SRT_Set: {
assert( nColumn==1 );
sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, 1, regRowid, &p->affinity, 1);
sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, 1, regRowid,
&pDest->affSdst, 1);
sqlite3ExprCacheAffinityChange(pParse, regRow, 1);
sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, regRowid);
break;
@ -1246,7 +1309,7 @@ static void generateColumnNames(
static int selectColumnsFromExprList(
Parse *pParse, /* Parsing context */
ExprList *pEList, /* Expr list from which to derive column names */
int *pnCol, /* Write the number of columns here */
i16 *pnCol, /* Write the number of columns here */
Column **paCol /* Write the new column list here */
){
sqlite3 *db = pParse->db; /* Database connection */
@ -1272,7 +1335,7 @@ static int selectColumnsFromExprList(
for(i=0, pCol=aCol; i<nCol; i++, pCol++){
/* Get an appropriate name for the column
*/
p = pEList->a[i].pExpr;
p = sqlite3ExprSkipCollate(pEList->a[i].pExpr);
assert( p->pRight==0 || ExprHasProperty(p->pRight, EP_IntValue)
|| p->pRight->u.zToken==0 || p->pRight->u.zToken[0]!=0 );
if( (zName = pEList->a[i].zName)!=0 ){
@ -1768,7 +1831,7 @@ static int multiSelect(
sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak);
iStart = sqlite3VdbeCurrentAddr(v);
selectInnerLoop(pParse, p, p->pEList, unionTab, p->pEList->nExpr,
0, -1, &dest, iCont, iBreak);
0, 0, &dest, iCont, iBreak);
sqlite3VdbeResolveLabel(v, iCont);
sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart);
sqlite3VdbeResolveLabel(v, iBreak);
@ -1846,7 +1909,7 @@ static int multiSelect(
sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0);
sqlite3ReleaseTempReg(pParse, r1);
selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr,
0, -1, &dest, iCont, iBreak);
0, 0, &dest, iCont, iBreak);
sqlite3VdbeResolveLabel(v, iCont);
sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart);
sqlite3VdbeResolveLabel(v, iBreak);
@ -1892,6 +1955,7 @@ static int multiSelect(
*apColl = db->pDfltColl;
}
}
pKeyInfo->aSortOrder = (u8*)apColl;
for(pLoop=p; pLoop; pLoop=pLoop->pPrior){
for(i=0; i<2; i++){
@ -1965,7 +2029,7 @@ static int generateOutputSubroutine(
(char*)pKeyInfo, p4type);
sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2);
sqlite3VdbeJumpHere(v, j1);
sqlite3ExprCodeCopy(pParse, pIn->iSdst, regPrev+1, pIn->nSdst);
sqlite3VdbeAddOp3(v, OP_Copy, pIn->iSdst, regPrev+1, pIn->nSdst-1);
sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev);
}
if( pParse->db->mallocFailed ) return 0;
@ -2000,10 +2064,10 @@ static int generateOutputSubroutine(
case SRT_Set: {
int r1;
assert( pIn->nSdst==1 );
p->affinity =
pDest->affSdst =
sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affSdst);
r1 = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, 1, r1, &p->affinity, 1);
sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, 1, r1, &pDest->affSdst,1);
sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, 1);
sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iSDParm, r1);
sqlite3ReleaseTempReg(pParse, r1);
@ -2269,12 +2333,13 @@ static int multiSelectOrderBy(
for(i=0; i<nOrderBy; i++){
CollSeq *pColl;
Expr *pTerm = pOrderBy->a[i].pExpr;
if( pTerm->flags & EP_ExpCollate ){
pColl = pTerm->pColl;
if( pTerm->flags & EP_Collate ){
pColl = sqlite3ExprCollSeq(pParse, pTerm);
}else{
pColl = multiSelectCollSeq(pParse, p, aPermute[i]);
pTerm->flags |= EP_ExpCollate;
pTerm->pColl = pColl;
if( pColl==0 ) pColl = db->pDfltColl;
pOrderBy->a[i].pExpr =
sqlite3ExprAddCollateString(pParse, pTerm, pColl->zName);
}
pKeyMerge->aColl[i] = pColl;
pKeyMerge->aSortOrder[i] = pOrderBy->a[i].sortOrder;
@ -2477,6 +2542,7 @@ static int multiSelectOrderBy(
sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY);
sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy,
(char*)pKeyMerge, P4_KEYINFO_HANDOFF);
sqlite3VdbeChangeP5(v, OPFLAG_PERMUTE);
sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB);
/* Release temporary registers
@ -2544,9 +2610,6 @@ static Expr *substExpr(
assert( pEList!=0 && pExpr->iColumn<pEList->nExpr );
assert( pExpr->pLeft==0 && pExpr->pRight==0 );
pNew = sqlite3ExprDup(db, pEList->a[pExpr->iColumn].pExpr, 0);
if( pNew && pExpr->pColl ){
pNew->pColl = pExpr->pColl;
}
sqlite3ExprDelete(db, pExpr);
pExpr = pNew;
}
@ -2745,7 +2808,7 @@ static int flattenSubquery(
*/
assert( p!=0 );
assert( p->pPrior==0 ); /* Unable to flatten compound queries */
if( db->flags & SQLITE_QueryFlattener ) return 0;
if( OptimizationDisabled(db, SQLITE_QueryFlattener) ) return 0;
pSrc = p->pSrc;
assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc );
pSubitem = &pSrc->a[iFrom];
@ -3034,10 +3097,9 @@ static int flattenSubquery(
pList = pParent->pEList;
for(i=0; i<pList->nExpr; i++){
if( pList->a[i].zName==0 ){
const char *zSpan = pList->a[i].zSpan;
if( ALWAYS(zSpan) ){
pList->a[i].zName = sqlite3DbStrDup(db, zSpan);
}
char *zName = sqlite3DbStrDup(db, pList->a[i].zSpan);
sqlite3Dequote(zName);
pList->a[i].zName = zName;
}
}
substExprList(db, pParent->pEList, iParent, pSub->pEList);
@ -3268,8 +3330,7 @@ static int selectExpander(Walker *pWalker, Select *p){
}else{
/* An ordinary table or view name in the FROM clause */
assert( pFrom->pTab==0 );
pFrom->pTab = pTab =
sqlite3LocateTable(pParse,0,pFrom->zName,pFrom->zDatabase);
pFrom->pTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom);
if( pTab==0 ) return WRC_Abort;
pTab->nRef++;
#if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE)
@ -3785,11 +3846,9 @@ int sqlite3Select(
ExprList *pOrderBy; /* The ORDER BY clause. May be NULL */
ExprList *pGroupBy; /* The GROUP BY clause. May be NULL */
Expr *pHaving; /* The HAVING clause. May be NULL */
int isDistinct; /* True if the DISTINCT keyword is present */
int distinct; /* Table to use for the distinct set */
int rc = 1; /* Value to return from this function */
int addrSortIndex; /* Address of an OP_OpenEphemeral instruction */
int addrDistinctIndex; /* Address of an OP_OpenEphemeral instruction */
DistinctCtx sDistinct; /* Info on how to code the DISTINCT keyword */
AggInfo sAggInfo; /* Information used by aggregate queries */
int iEnd; /* Address of the end of the query */
sqlite3 *db; /* The database connection */
@ -3849,8 +3908,17 @@ int sqlite3Select(
int isAggSub;
if( pSub==0 ) continue;
/* Sometimes the code for a subquery will be generated more than
** once, if the subquery is part of the WHERE clause in a LEFT JOIN,
** for example. In that case, do not regenerate the code to manifest
** a view or the co-routine to implement a view. The first instance
** is sufficient, though the subroutine to manifest the view does need
** to be invoked again. */
if( pItem->addrFillSub ){
sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub);
if( pItem->viaCoroutine==0 ){
sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub);
}
continue;
}
@ -3871,6 +3939,44 @@ int sqlite3Select(
p->selFlags |= SF_Aggregate;
}
i = -1;
}else if( pTabList->nSrc==1 && (p->selFlags & SF_Materialize)==0
&& OptimizationEnabled(db, SQLITE_SubqCoroutine)
){
/* Implement a co-routine that will return a single row of the result
** set on each invocation.
*/
int addrTop;
int addrEof;
pItem->regReturn = ++pParse->nMem;
addrEof = ++pParse->nMem;
/* Before coding the OP_Goto to jump to the start of the main routine,
** ensure that the jump to the verify-schema routine has already
** been coded. Otherwise, the verify-schema would likely be coded as
** part of the co-routine. If the main routine then accessed the
** database before invoking the co-routine for the first time (for
** example to initialize a LIMIT register from a sub-select), it would
** be doing so without having verified the schema version and obtained
** the required db locks. See ticket d6b36be38. */
sqlite3CodeVerifySchema(pParse, -1);
sqlite3VdbeAddOp0(v, OP_Goto);
addrTop = sqlite3VdbeAddOp1(v, OP_OpenPseudo, pItem->iCursor);
sqlite3VdbeChangeP5(v, 1);
VdbeComment((v, "coroutine for %s", pItem->pTab->zName));
pItem->addrFillSub = addrTop;
sqlite3VdbeAddOp2(v, OP_Integer, 0, addrEof);
sqlite3VdbeChangeP5(v, 1);
sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn);
explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
sqlite3Select(pParse, pSub, &dest);
pItem->pTab->nRowEst = (unsigned)pSub->nSelectRow;
pItem->viaCoroutine = 1;
sqlite3VdbeChangeP2(v, addrTop, dest.iSdst);
sqlite3VdbeChangeP3(v, addrTop, dest.nSdst);
sqlite3VdbeAddOp2(v, OP_Integer, 1, addrEof);
sqlite3VdbeAddOp1(v, OP_Yield, pItem->regReturn);
VdbeComment((v, "end %s", pItem->pTab->zName));
sqlite3VdbeJumpHere(v, addrTop-1);
sqlite3ClearTempRegCache(pParse);
}else{
/* Generate a subroutine that will fill an ephemeral table with
** the content of this subquery. pItem->addrFillSub will point
@ -3915,7 +4021,7 @@ int sqlite3Select(
pWhere = p->pWhere;
pGroupBy = p->pGroupBy;
pHaving = p->pHaving;
isDistinct = (p->selFlags & SF_Distinct)!=0;
sDistinct.isTnct = (p->selFlags & SF_Distinct)!=0;
#ifndef SQLITE_OMIT_COMPOUND_SELECT
/* If there is are a sequence of queries, do the earlier ones first.
@ -3950,7 +4056,7 @@ int sqlite3Select(
** to disable this optimization for testing purposes.
*/
if( sqlite3ExprListCompare(p->pGroupBy, pOrderBy)==0
&& (db->flags & SQLITE_GroupByOrder)==0 ){
&& OptimizationEnabled(db, SQLITE_GroupByOrder) ){
pOrderBy = 0;
}
@ -3976,6 +4082,10 @@ int sqlite3Select(
p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0);
pGroupBy = p->pGroupBy;
pOrderBy = 0;
/* Notice that even thought SF_Distinct has been cleared from p->selFlags,
** the sDistinct.isTnct is still set. Hence, isTnct represents the
** original setting of the SF_Distinct flag, not the current setting */
assert( sDistinct.isTnct );
}
/* If there is an ORDER BY clause, then this sorting
@ -4016,24 +4126,27 @@ int sqlite3Select(
/* Open a virtual index to use for the distinct set.
*/
if( p->selFlags & SF_Distinct ){
KeyInfo *pKeyInfo;
distinct = pParse->nTab++;
pKeyInfo = keyInfoFromExprList(pParse, p->pEList);
addrDistinctIndex = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, distinct, 0, 0,
(char*)pKeyInfo, P4_KEYINFO_HANDOFF);
sDistinct.tabTnct = pParse->nTab++;
sDistinct.addrTnct = sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
sDistinct.tabTnct, 0, 0,
(char*)keyInfoFromExprList(pParse, p->pEList),
P4_KEYINFO_HANDOFF);
sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
sDistinct.eTnctType = WHERE_DISTINCT_UNORDERED;
}else{
distinct = addrDistinctIndex = -1;
sDistinct.eTnctType = WHERE_DISTINCT_NOOP;
}
/* Aggregate and non-aggregate queries are handled differently */
if( !isAgg && pGroupBy==0 ){
ExprList *pDist = (isDistinct ? p->pEList : 0);
/* No aggregate functions and no GROUP BY clause */
ExprList *pDist = (sDistinct.isTnct ? p->pEList : 0);
/* Begin the database scan. */
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pOrderBy, pDist, 0,0);
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pOrderBy, pDist, 0,0);
if( pWInfo==0 ) goto select_end;
if( pWInfo->nRowOut < p->nSelectRow ) p->nSelectRow = pWInfo->nRowOut;
if( pWInfo->eDistinct ) sDistinct.eTnctType = pWInfo->eDistinct;
if( pOrderBy && pWInfo->nOBSat==pOrderBy->nExpr ) pOrderBy = 0;
/* If sorting index that was created by a prior OP_OpenEphemeral
** instruction ended up not being needed, then change the OP_OpenEphemeral
@ -4044,59 +4157,16 @@ int sqlite3Select(
p->addrOpenEphm[2] = -1;
}
if( pWInfo->eDistinct ){
VdbeOp *pOp; /* No longer required OpenEphemeral instr. */
assert( addrDistinctIndex>=0 );
pOp = sqlite3VdbeGetOp(v, addrDistinctIndex);
assert( isDistinct );
assert( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED
|| pWInfo->eDistinct==WHERE_DISTINCT_UNIQUE
);
distinct = -1;
if( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED ){
int iJump;
int iExpr;
int iFlag = ++pParse->nMem;
int iBase = pParse->nMem+1;
int iBase2 = iBase + pEList->nExpr;
pParse->nMem += (pEList->nExpr*2);
/* Change the OP_OpenEphemeral coded earlier to an OP_Integer. The
** OP_Integer initializes the "first row" flag. */
pOp->opcode = OP_Integer;
pOp->p1 = 1;
pOp->p2 = iFlag;
sqlite3ExprCodeExprList(pParse, pEList, iBase, 1);
iJump = sqlite3VdbeCurrentAddr(v) + 1 + pEList->nExpr + 1 + 1;
sqlite3VdbeAddOp2(v, OP_If, iFlag, iJump-1);
for(iExpr=0; iExpr<pEList->nExpr; iExpr++){
CollSeq *pColl = sqlite3ExprCollSeq(pParse, pEList->a[iExpr].pExpr);
sqlite3VdbeAddOp3(v, OP_Ne, iBase+iExpr, iJump, iBase2+iExpr);
sqlite3VdbeChangeP4(v, -1, (const char *)pColl, P4_COLLSEQ);
sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
}
sqlite3VdbeAddOp2(v, OP_Goto, 0, pWInfo->iContinue);
sqlite3VdbeAddOp2(v, OP_Integer, 0, iFlag);
assert( sqlite3VdbeCurrentAddr(v)==iJump );
sqlite3VdbeAddOp3(v, OP_Move, iBase, iBase2, pEList->nExpr);
}else{
pOp->opcode = OP_Noop;
}
}
/* Use the standard inner loop. */
selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, distinct, pDest,
selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, &sDistinct, pDest,
pWInfo->iContinue, pWInfo->iBreak);
/* End the database scan loop.
*/
sqlite3WhereEnd(pWInfo);
}else{
/* This is the processing for aggregate queries */
/* This case when there exist aggregate functions or a GROUP BY clause
** or both */
NameContext sNC; /* Name context for processing aggregate information */
int iAMem; /* First Mem address for storing current GROUP BY */
int iBMem; /* First Mem address for previous GROUP BY */
@ -4204,14 +4274,13 @@ int sqlite3Select(
** in the right order to begin with.
*/
sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pGroupBy, 0, 0, 0);
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0, 0, 0);
if( pWInfo==0 ) goto select_end;
if( pGroupBy==0 ){
if( pWInfo->nOBSat==pGroupBy->nExpr ){
/* The optimizer is able to deliver rows in group by order so
** we do not have to sort. The OP_OpenEphemeral table will be
** cancelled later because we still need to use the pKeyInfo
*/
pGroupBy = p->pGroupBy;
groupBySort = 0;
}else{
/* Rows are coming out in undetermined order. We have to push
@ -4225,7 +4294,8 @@ int sqlite3Select(
int nGroupBy;
explainTempTable(pParse,
isDistinct && !(p->selFlags&SF_Distinct)?"DISTINCT":"GROUP BY");
(sDistinct.isTnct && (p->selFlags&SF_Distinct)==0) ?
"DISTINCT" : "GROUP BY");
groupBySort = 1;
nGroupBy = pGroupBy->nExpr;
@ -4357,7 +4427,7 @@ int sqlite3Select(
finalizeAggFunctions(pParse, &sAggInfo);
sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL);
selectInnerLoop(pParse, p, p->pEList, 0, 0, pOrderBy,
distinct, pDest,
&sDistinct, pDest,
addrOutputRow+1, addrSetAbort);
sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
VdbeComment((v, "end groupby result generator"));
@ -4460,6 +4530,7 @@ int sqlite3Select(
u8 flag = minMaxQuery(p);
if( flag ){
assert( !ExprHasProperty(p->pEList->a[0].pExpr, EP_xIsSelect) );
assert( p->pEList->a[0].pExpr->x.pList->nExpr==1 );
pMinMax = sqlite3ExprListDup(db, p->pEList->a[0].pExpr->x.pList,0);
pDel = pMinMax;
if( pMinMax && !db->mallocFailed ){
@ -4473,13 +4544,14 @@ int sqlite3Select(
** of output.
*/
resetAccumulator(pParse, &sAggInfo);
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pMinMax,0,flag,0);
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMax,0,flag,0);
if( pWInfo==0 ){
sqlite3ExprListDelete(db, pDel);
goto select_end;
}
updateAccumulator(pParse, &sAggInfo);
if( !pMinMax && flag ){
assert( pMinMax==0 || pMinMax->nExpr==1 );
if( pWInfo->nOBSat>0 ){
sqlite3VdbeAddOp2(v, OP_Goto, 0, pWInfo->iBreak);
VdbeComment((v, "%s() by index",
(flag==WHERE_ORDERBY_MIN?"min":"max")));
@ -4490,7 +4562,7 @@ int sqlite3Select(
pOrderBy = 0;
sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL);
selectInnerLoop(pParse, p, p->pEList, 0, 0, 0, -1,
selectInnerLoop(pParse, p, p->pEList, 0, 0, 0, 0,
pDest, addrEnd, addrEnd);
sqlite3ExprListDelete(db, pDel);
}
@ -4498,7 +4570,7 @@ int sqlite3Select(
} /* endif aggregate query */
if( distinct>=0 ){
if( sDistinct.eTnctType==WHERE_DISTINCT_UNORDERED ){
explainTempTable(pParse, "DISTINCT");
}

View File

@ -541,6 +541,9 @@ static void output_c_string(FILE *out, const char *z){
if( c=='\\' ){
fputc(c, out);
fputc(c, out);
}else if( c=='"' ){
fputc('\\', out);
fputc('"', out);
}else if( c=='\t' ){
fputc('\\', out);
fputc('t', out);
@ -696,7 +699,7 @@ static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int
}else{
w = 0;
}
if( w<=0 ){
if( w==0 ){
w = strlen30(azCol[i] ? azCol[i] : "");
if( w<10 ) w = 10;
n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
@ -706,7 +709,11 @@ static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int
p->actualWidth[i] = w;
}
if( p->showHeader ){
fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
if( w<0 ){
fprintf(p->out,"%*.*s%s",-w,-w,azCol[i], i==nArg-1 ? "\n": " ");
}else{
fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
}
}
}
if( p->showHeader ){
@ -714,6 +721,7 @@ static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int
int w;
if( i<ArraySize(p->actualWidth) ){
w = p->actualWidth[i];
if( w<0 ) w = -w;
}else{
w = 10;
}
@ -735,8 +743,13 @@ static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int
strlen30(azArg[i])>w ){
w = strlen30(azArg[i]);
}
fprintf(p->out,"%-*.*s%s",w,w,
azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
if( w<0 ){
fprintf(p->out,"%*.*s%s",-w,-w,
azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
}else{
fprintf(p->out,"%-*.*s%s",w,w,
azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
}
}
break;
}
@ -786,14 +799,14 @@ static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int
if( p->cnt++==0 && p->showHeader ){
for(i=0; i<nArg; i++){
output_c_string(p->out,azCol[i] ? azCol[i] : "");
fprintf(p->out, "%s", p->separator);
if(i<nArg-1) fprintf(p->out, "%s", p->separator);
}
fprintf(p->out,"\n");
}
if( azArg==0 ) break;
for(i=0; i<nArg; i++){
output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
fprintf(p->out, "%s", p->separator);
if(i<nArg-1) fprintf(p->out, "%s", p->separator);
}
fprintf(p->out,"\n");
break;
@ -1416,9 +1429,10 @@ static char zHelp[] =
" list Values delimited by .separator string\n"
" tabs Tab-separated values\n"
" tcl TCL list elements\n"
".nullvalue STRING Print STRING in place of NULL values\n"
".nullvalue STRING Use STRING in place of NULL values\n"
".output FILENAME Send output to FILENAME\n"
".output stdout Send output to the screen\n"
".print STRING... Print literal STRING\n"
".prompt MAIN CONTINUE Replace the standard prompts\n"
".quit Exit this program\n"
".read FILENAME Execute SQL in FILENAME\n"
@ -2007,6 +2021,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
p->mode = MODE_Html;
}else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){
p->mode = MODE_Tcl;
sqlite3_snprintf(sizeof(p->separator), p->separator, " ");
}else if( n2==3 && strncmp(azArg[1],"csv",n2)==0 ){
p->mode = MODE_Csv;
sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
@ -2070,6 +2085,15 @@ static int do_meta_command(char *zLine, struct callback_data *p){
}
}else
if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
int i;
for(i=1; i<nArg; i++){
if( i>1 ) fprintf(p->out, " ");
fprintf(p->out, "%s", azArg[i]);
}
fprintf(p->out, "\n");
}else
if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
if( nArg >= 2) {
strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
@ -2493,6 +2517,13 @@ static int do_meta_command(char *zLine, struct callback_data *p){
}
}else
#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
extern int sqlite3WhereTrace;
sqlite3WhereTrace = atoi(azArg[1]);
}else
#endif
if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){
int j;
assert( nArg<=ArraySize(azArg) );
@ -2684,7 +2715,7 @@ static int process_input(struct callback_data *p, FILE *in){
free(zSql);
}
free(zLine);
return errCnt;
return errCnt>0;
}
/*
@ -2797,11 +2828,14 @@ static const char zOptions[] =
" -bail stop after hitting an error\n"
" -batch force batch I/O\n"
" -column set output mode to 'column'\n"
" -cmd command run \"command\" before reading stdin\n"
" -cmd COMMAND run \"COMMAND\" before reading stdin\n"
" -csv set output mode to 'csv'\n"
" -echo print commands before execution\n"
" -init filename read/process named file\n"
" -init FILENAME read/process named file\n"
" -[no]header turn headers on or off\n"
#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
" -heap SIZE Size of heap for memsys3 or memsys5\n"
#endif
" -help show this message\n"
" -html set output mode to HTML\n"
" -interactive force interactive I/O\n"
@ -2810,8 +2844,8 @@ static const char zOptions[] =
#ifdef SQLITE_ENABLE_MULTIPLEX
" -multiplex enable the multiplexor VFS\n"
#endif
" -nullvalue 'text' set text string for NULL values\n"
" -separator 'x' set output field separator (|)\n"
" -nullvalue TEXT set text string for NULL values. Default ''\n"
" -separator SEP set output field separator. Default: '|'\n"
" -stats print memory stats before each finalize\n"
" -version show SQLite version\n"
" -vfs NAME use NAME as the default VFS\n"
@ -2847,6 +2881,19 @@ static void main_init(struct callback_data *data) {
sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
}
/*
** Get the argument to an --option. Throw an error and die if no argument
** is available.
*/
static char *cmdline_option_value(int argc, char **argv, int i){
if( i==argc ){
fprintf(stderr, "%s: Error: missing argument to %s\n",
argv[0], argv[argc-1]);
exit(1);
}
return argv[i];
}
int main(int argc, char **argv){
char *zErrMsg = 0;
struct callback_data data;
@ -2876,24 +2923,35 @@ int main(int argc, char **argv){
** the size of the alternative malloc heap,
** and the first command to execute.
*/
for(i=1; i<argc-1; i++){
for(i=1; i<argc; i++){
char *z;
if( argv[i][0]!='-' ) break;
z = argv[i];
if( z[0]!='-' ){
if( data.zDbFilename==0 ){
data.zDbFilename = z;
continue;
}
if( zFirstCmd==0 ){
zFirstCmd = z;
continue;
}
fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
fprintf(stderr,"Use -help for a list of options.\n");
return 1;
}
if( z[1]=='-' ) z++;
if( strcmp(z,"-separator")==0
|| strcmp(z,"-nullvalue")==0
|| strcmp(z,"-cmd")==0
){
i++;
(void)cmdline_option_value(argc, argv, ++i);
}else if( strcmp(z,"-init")==0 ){
i++;
zInitFile = argv[i];
/* Need to check for batch mode here to so we can avoid printing
** informational messages (like from process_sqliterc) before
** we do the actual processing of arguments later in a second pass.
*/
zInitFile = cmdline_option_value(argc, argv, ++i);
}else if( strcmp(z,"-batch")==0 ){
/* Need to check for batch mode here to so we can avoid printing
** informational messages (like from process_sqliterc) before
** we do the actual processing of arguments later in a second pass.
*/
stdin_is_interactive = 0;
}else if( strcmp(z,"-heap")==0 ){
#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
@ -2901,7 +2959,7 @@ int main(int argc, char **argv){
const char *zSize;
sqlite3_int64 szHeap;
zSize = argv[++i];
zSize = cmdline_option_value(argc, argv, ++i);
szHeap = atoi(zSize);
for(j=0; (c = zSize[j])!=0; j++){
if( c=='M' ){ szHeap *= 1000000; break; }
@ -2928,7 +2986,7 @@ int main(int argc, char **argv){
sqlite3_multiplex_initialize(0, 1);
#endif
}else if( strcmp(z,"-vfs")==0 ){
sqlite3_vfs *pVfs = sqlite3_vfs_find(argv[++i]);
sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
if( pVfs ){
sqlite3_vfs_register(pVfs, 1);
}else{
@ -2937,31 +2995,15 @@ int main(int argc, char **argv){
}
}
}
if( i<argc ){
data.zDbFilename = argv[i++];
}else{
if( data.zDbFilename==0 ){
#ifndef SQLITE_OMIT_MEMORYDB
data.zDbFilename = ":memory:";
#else
data.zDbFilename = 0;
#endif
}
if( i<argc ){
zFirstCmd = argv[i++];
}
if( i<argc ){
fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
fprintf(stderr,"Use -help for a list of options.\n");
return 1;
}
data.out = stdout;
#ifdef SQLITE_OMIT_MEMORYDB
if( data.zDbFilename==0 ){
fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
return 1;
}
#endif
}
data.out = stdout;
/* Go ahead and open the database file if it already exists. If the
** file does not exist, delay opening it. This prevents empty database
@ -2986,8 +3028,9 @@ int main(int argc, char **argv){
** file is processed so that the command-line arguments will override
** settings in the initialization file.
*/
for(i=1; i<argc && argv[i][0]=='-'; i++){
for(i=1; i<argc; i++){
char *z = argv[i];
if( z[0]!='-' ) continue;
if( z[1]=='-' ){ z++; }
if( strcmp(z,"-init")==0 ){
i++;
@ -3003,25 +3046,11 @@ int main(int argc, char **argv){
data.mode = MODE_Csv;
memcpy(data.separator,",",2);
}else if( strcmp(z,"-separator")==0 ){
i++;
if(i>=argc){
fprintf(stderr,"%s: Error: missing argument for option: %s\n",
Argv0, z);
fprintf(stderr,"Use -help for a list of options.\n");
return 1;
}
sqlite3_snprintf(sizeof(data.separator), data.separator,
"%.*s",(int)sizeof(data.separator)-1,argv[i]);
"%s",cmdline_option_value(argc,argv,++i));
}else if( strcmp(z,"-nullvalue")==0 ){
i++;
if(i>=argc){
fprintf(stderr,"%s: Error: missing argument for option: %s\n",
Argv0, z);
fprintf(stderr,"Use -help for a list of options.\n");
return 1;
}
sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue,
"%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
"%s",cmdline_option_value(argc,argv,++i));
}else if( strcmp(z,"-header")==0 ){
data.showHeader = 1;
}else if( strcmp(z,"-noheader")==0 ){
@ -3055,8 +3084,7 @@ int main(int argc, char **argv){
usage(1);
}else if( strcmp(z,"-cmd")==0 ){
if( i==argc-1 ) break;
i++;
z = argv[i];
z = cmdline_option_value(argc,argv,++i);
if( z[0]=='.' ){
rc = do_meta_command(z, &data);
if( rc && bail_on_error ) return rc;

View File

@ -469,10 +469,12 @@ int sqlite3_exec(
#define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8))
#define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8))
#define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8))
#define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8))
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
@ -850,6 +852,26 @@ struct sqlite3_io_methods {
** compilation of the PRAGMA fails with an error. ^The [SQLITE_FCNTL_PRAGMA]
** file control occurs at the beginning of pragma statement analysis and so
** it is able to override built-in [PRAGMA] statements.
**
** <li>[[SQLITE_FCNTL_BUSYHANDLER]]
** ^This file-control may be invoked by SQLite on the database file handle
** shortly after it is opened in order to provide a custom VFS with access
** to the connections busy-handler callback. The argument is of type (void **)
** - an array of two (void *) values. The first (void *) actually points
** to a function of type (int (*)(void *)). In order to invoke the connections
** busy-handler, this function should be invoked with the second (void *) in
** the array as the only argument. If it returns non-zero, then the operation
** should be retried. If it returns zero, the custom VFS should abandon the
** current operation.
**
** <li>[[SQLITE_FCNTL_TEMPFILENAME]]
** ^Application can invoke this file-control to have SQLite generate a
** temporary filename using the same algorithm that is followed to generate
** temporary filenames for TEMP tables and other internal uses. The
** argument should be a char** which will be filled with the filename
** written into memory obtained from [sqlite3_malloc()]. The caller should
** invoke [sqlite3_free()] on the result to avoid a memory leak.
**
** </ul>
*/
#define SQLITE_FCNTL_LOCKSTATE 1
@ -866,6 +888,8 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_VFSNAME 12
#define SQLITE_FCNTL_POWERSAFE_OVERWRITE 13
#define SQLITE_FCNTL_PRAGMA 14
#define SQLITE_FCNTL_BUSYHANDLER 15
#define SQLITE_FCNTL_TEMPFILENAME 16
/*
** CAPI3REF: Mutex Handle
@ -1562,11 +1586,39 @@ struct sqlite3_mem_methods {
** disabled. The default value may be changed by compiling with the
** [SQLITE_USE_URI] symbol defined.
**
** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]] <dt>SQLITE_CONFIG_COVERING_INDEX_SCAN
** <dd> This option takes a single integer argument which is interpreted as
** a boolean in order to enable or disable the use of covering indices for
** full table scans in the query optimizer. The default setting is determined
** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on"
** if that compile-time option is omitted.
** The ability to disable the use of covering indices for full table scans
** is because some incorrectly coded legacy applications might malfunction
** malfunction when the optimization is enabled. Providing the ability to
** disable the optimization allows the older, buggy application code to work
** without change even with newer versions of SQLite.
**
** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]]
** <dt>SQLITE_CONFIG_PCACHE and SQLITE_CONFIG_GETPCACHE
** <dd> These options are obsolete and should not be used by new code.
** They are retained for backwards compatibility but are now no-ops.
** </dl>
**
** [[SQLITE_CONFIG_SQLLOG]]
** <dt>SQLITE_CONFIG_SQLLOG
** <dd>This option is only available if sqlite is compiled with the
** SQLITE_ENABLE_SQLLOG pre-processor macro defined. The first argument should
** be a pointer to a function of type void(*)(void*,sqlite3*,const char*, int).
** The second should be of type (void*). The callback is invoked by the library
** in three separate circumstances, identified by the value passed as the
** fourth parameter. If the fourth parameter is 0, then the database connection
** passed as the second argument has just been opened. The third argument
** points to a buffer containing the name of the main database file. If the
** fourth parameter is 1, then the SQL statement that the third parameter
** points to has just been executed. Or, if the fourth parameter is 2, then
** the connection being passed as the second parameter is being closed. The
** third parameter is passed NULL In this case.
** </dl>
*/
#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
#define SQLITE_CONFIG_MULTITHREAD 2 /* nil */
@ -1587,6 +1639,8 @@ struct sqlite3_mem_methods {
#define SQLITE_CONFIG_URI 17 /* int */
#define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */
#define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */
#define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */
#define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */
/*
** CAPI3REF: Database Connection Configuration Options
@ -2595,7 +2649,7 @@ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
** an error)^.
** ^If "ro" is specified, then the database is opened for read-only
** access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the
** third argument to sqlite3_prepare_v2(). ^If the mode option is set to
** third argument to sqlite3_open_v2(). ^If the mode option is set to
** "rw", then the database is opened for read-write (but not create)
** access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had
** been set. ^Value "rwc" is equivalent to setting both
@ -2747,6 +2801,11 @@ sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64);
** However, the error string might be overwritten or deallocated by
** subsequent calls to other SQLite interface functions.)^
**
** ^The sqlite3_errstr() interface returns the English-language text
** that describes the [result code], as UTF-8.
** ^(Memory to hold the error message string is managed internally
** and must not be freed by the application)^.
**
** When the serialized [threading mode] is in use, it might be the
** case that a second error occurs on a separate thread in between
** the time of the first error and the call to these interfaces.
@ -2765,6 +2824,7 @@ int sqlite3_errcode(sqlite3 *db);
int sqlite3_extended_errcode(sqlite3 *db);
const char *sqlite3_errmsg(sqlite3*);
const void *sqlite3_errmsg16(sqlite3*);
const char *sqlite3_errstr(int);
/*
** CAPI3REF: SQL Statement Object
@ -4727,6 +4787,9 @@ void *sqlite3_update_hook(
** future releases of SQLite. Applications that care about shared
** cache setting should set it explicitly.
**
** This interface is threadsafe on processors where writing a
** 32-bit integer is atomic.
**
** See Also: [SQLite Shared-Cache Mode]
*/
int sqlite3_enable_shared_cache(int);

View File

@ -661,6 +661,7 @@ typedef struct Parse Parse;
typedef struct RowSet RowSet;
typedef struct Savepoint Savepoint;
typedef struct Select Select;
typedef struct SelectDest SelectDest;
typedef struct SrcList SrcList;
typedef struct StrAccum StrAccum;
typedef struct Table Table;
@ -826,6 +827,7 @@ struct sqlite3 {
unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */
int errCode; /* Most recent error code (SQLITE_*) */
int errMask; /* & result codes with this before returning */
u16 dbOptFlags; /* Flags to enable/disable optimizations */
u8 autoCommit; /* The auto-commit flag. */
u8 temp_store; /* 1: file 2: memory 0: default */
u8 mallocFailed; /* True if we have seen a malloc failure */
@ -930,48 +932,59 @@ struct sqlite3 {
/*
** Possible values for the sqlite3.flags.
*/
#define SQLITE_VdbeTrace 0x00000100 /* True to trace VDBE execution */
#define SQLITE_InternChanges 0x00000200 /* Uncommitted Hash table changes */
#define SQLITE_FullColNames 0x00000400 /* Show full column names on SELECT */
#define SQLITE_ShortColNames 0x00000800 /* Show short columns names */
#define SQLITE_CountRows 0x00001000 /* Count rows changed by INSERT, */
#define SQLITE_VdbeTrace 0x00000001 /* True to trace VDBE execution */
#define SQLITE_InternChanges 0x00000002 /* Uncommitted Hash table changes */
#define SQLITE_FullColNames 0x00000004 /* Show full column names on SELECT */
#define SQLITE_ShortColNames 0x00000008 /* Show short columns names */
#define SQLITE_CountRows 0x00000010 /* Count rows changed by INSERT, */
/* DELETE, or UPDATE and return */
/* the count using a callback. */
#define SQLITE_NullCallback 0x00002000 /* Invoke the callback once if the */
#define SQLITE_NullCallback 0x00000020 /* Invoke the callback once if the */
/* result set is empty */
#define SQLITE_SqlTrace 0x00004000 /* Debug print SQL as it executes */
#define SQLITE_VdbeListing 0x00008000 /* Debug listings of VDBE programs */
#define SQLITE_WriteSchema 0x00010000 /* OK to update SQLITE_MASTER */
/* 0x00020000 Unused */
#define SQLITE_IgnoreChecks 0x00040000 /* Do not enforce check constraints */
#define SQLITE_ReadUncommitted 0x0080000 /* For shared-cache mode */
#define SQLITE_LegacyFileFmt 0x00100000 /* Create new databases in format 1 */
#define SQLITE_FullFSync 0x00200000 /* Use full fsync on the backend */
#define SQLITE_CkptFullFSync 0x00400000 /* Use full fsync for checkpoint */
#define SQLITE_RecoveryMode 0x00800000 /* Ignore schema errors */
#define SQLITE_ReverseOrder 0x01000000 /* Reverse unordered SELECTs */
#define SQLITE_RecTriggers 0x02000000 /* Enable recursive triggers */
#define SQLITE_ForeignKeys 0x04000000 /* Enforce foreign key constraints */
#define SQLITE_AutoIndex 0x08000000 /* Enable automatic indexes */
#define SQLITE_PreferBuiltin 0x10000000 /* Preference to built-in funcs */
#define SQLITE_LoadExtension 0x20000000 /* Enable load_extension */
#define SQLITE_EnableTrigger 0x40000000 /* True to enable triggers */
#define SQLITE_SqlTrace 0x00000040 /* Debug print SQL as it executes */
#define SQLITE_VdbeListing 0x00000080 /* Debug listings of VDBE programs */
#define SQLITE_WriteSchema 0x00000100 /* OK to update SQLITE_MASTER */
/* 0x00000200 Unused */
#define SQLITE_IgnoreChecks 0x00000400 /* Do not enforce check constraints */
#define SQLITE_ReadUncommitted 0x0000800 /* For shared-cache mode */
#define SQLITE_LegacyFileFmt 0x00001000 /* Create new databases in format 1 */
#define SQLITE_FullFSync 0x00002000 /* Use full fsync on the backend */
#define SQLITE_CkptFullFSync 0x00004000 /* Use full fsync for checkpoint */
#define SQLITE_RecoveryMode 0x00008000 /* Ignore schema errors */
#define SQLITE_ReverseOrder 0x00010000 /* Reverse unordered SELECTs */
#define SQLITE_RecTriggers 0x00020000 /* Enable recursive triggers */
#define SQLITE_ForeignKeys 0x00040000 /* Enforce foreign key constraints */
#define SQLITE_AutoIndex 0x00080000 /* Enable automatic indexes */
#define SQLITE_PreferBuiltin 0x00100000 /* Preference to built-in funcs */
#define SQLITE_LoadExtension 0x00200000 /* Enable load_extension */
#define SQLITE_EnableTrigger 0x00400000 /* True to enable triggers */
/*
** Bits of the sqlite3.flags field that are used by the
** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface.
** These must be the low-order bits of the flags field.
** Bits of the sqlite3.dbOptFlags field that are used by the
** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to
** selectively disable various optimizations.
*/
#define SQLITE_QueryFlattener 0x01 /* Disable query flattening */
#define SQLITE_ColumnCache 0x02 /* Disable the column cache */
#define SQLITE_IndexSort 0x04 /* Disable indexes for sorting */
#define SQLITE_IndexSearch 0x08 /* Disable indexes for searching */
#define SQLITE_IndexCover 0x10 /* Disable index covering table */
#define SQLITE_GroupByOrder 0x20 /* Disable GROUPBY cover of ORDERBY */
#define SQLITE_FactorOutConst 0x40 /* Disable factoring out constants */
#define SQLITE_IdxRealAsInt 0x80 /* Store REAL as INT in indices */
#define SQLITE_DistinctOpt 0x80 /* DISTINCT using indexes */
#define SQLITE_OptMask 0xff /* Mask of all disablable opts */
#define SQLITE_QueryFlattener 0x0001 /* Query flattening */
#define SQLITE_ColumnCache 0x0002 /* Column cache */
#define SQLITE_GroupByOrder 0x0004 /* GROUPBY cover of ORDERBY */
#define SQLITE_FactorOutConst 0x0008 /* Constant factoring */
#define SQLITE_IdxRealAsInt 0x0010 /* Store REAL as INT in indices */
#define SQLITE_DistinctOpt 0x0020 /* DISTINCT using indexes */
#define SQLITE_CoverIdxScan 0x0040 /* Covering index scans */
#define SQLITE_OrderByIdxJoin 0x0080 /* ORDER BY of joins via index */
#define SQLITE_SubqCoroutine 0x0100 /* Evaluate subqueries as coroutines */
#define SQLITE_AllOpts 0xffff /* All optimizations */
/*
** Macros for testing whether or not optimizations are enabled or disabled.
*/
#ifndef SQLITE_OMIT_BUILTIN_TEST
#define OptimizationDisabled(db, mask) (((db)->dbOptFlags&(mask))!=0)
#define OptimizationEnabled(db, mask) (((db)->dbOptFlags&(mask))==0)
#else
#define OptimizationDisabled(db, mask) 0
#define OptimizationEnabled(db, mask) 1
#endif
/*
** Possible values for the sqlite.magic field.
@ -1122,32 +1135,22 @@ struct Column {
char *zDflt; /* Original text of the default value */
char *zType; /* Data type for this column */
char *zColl; /* Collating sequence. If NULL, use the default */
u8 notNull; /* True if there is a NOT NULL constraint */
u8 isPrimKey; /* True if this column is part of the PRIMARY KEY */
u8 notNull; /* An OE_ code for handling a NOT NULL constraint */
char affinity; /* One of the SQLITE_AFF_... values */
#ifndef SQLITE_OMIT_VIRTUALTABLE
u8 isHidden; /* True if this column is 'hidden' */
#endif
u16 colFlags; /* Boolean properties. See COLFLAG_ defines below */
};
/* Allowed values for Column.colFlags:
*/
#define COLFLAG_PRIMKEY 0x0001 /* Column is part of the primary key */
#define COLFLAG_HIDDEN 0x0002 /* A hidden column in a virtual table */
/*
** A "Collating Sequence" is defined by an instance of the following
** structure. Conceptually, a collating sequence consists of a name and
** a comparison routine that defines the order of that sequence.
**
** There may two separate implementations of the collation function, one
** that processes text in UTF-8 encoding (CollSeq.xCmp) and another that
** processes text encoded in UTF-16 (CollSeq.xCmp16), using the machine
** native byte order. When a collation sequence is invoked, SQLite selects
** the version that will require the least expensive encoding
** translations, if any.
**
** The CollSeq.pUser member variable is an extra parameter that passed in
** as the first argument to the UTF-8 comparison function, xCmp.
** CollSeq.pUser16 is the equivalent for the UTF-16 comparison function,
** xCmp16.
**
** If both CollSeq.xCmp and CollSeq.xCmp16 are NULL, it means that the
** If CollSeq.xCmp is NULL, it means that the
** collating sequence is undefined. Indices built on an undefined
** collating sequence may not be read or written.
*/
@ -1285,28 +1288,28 @@ struct VTable {
*/
struct Table {
char *zName; /* Name of the table or view */
int iPKey; /* If not negative, use aCol[iPKey] as the primary key */
int nCol; /* Number of columns in this table */
Column *aCol; /* Information about each column */
Index *pIndex; /* List of SQL indexes on this table. */
int tnum; /* Root BTree node for this table (see note above) */
tRowcnt nRowEst; /* Estimated rows in table - from sqlite_stat1 table */
Select *pSelect; /* NULL for tables. Points to definition if a view. */
u16 nRef; /* Number of pointers to this Table */
u8 tabFlags; /* Mask of TF_* values */
u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */
FKey *pFKey; /* Linked list of all foreign keys in this table */
char *zColAff; /* String defining the affinity of each column */
#ifndef SQLITE_OMIT_CHECK
ExprList *pCheck; /* All CHECK constraints */
#endif
tRowcnt nRowEst; /* Estimated rows in table - from sqlite_stat1 table */
int tnum; /* Root BTree node for this table (see note above) */
i16 iPKey; /* If not negative, use aCol[iPKey] as the primary key */
i16 nCol; /* Number of columns in this table */
u16 nRef; /* Number of pointers to this Table */
u8 tabFlags; /* Mask of TF_* values */
u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */
#ifndef SQLITE_OMIT_ALTERTABLE
int addColOffset; /* Offset in CREATE TABLE stmt to add a new column */
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
VTable *pVTable; /* List of VTable objects. */
int nModuleArg; /* Number of arguments to the module */
char **azModuleArg; /* Text of all module args. [0] is module name */
VTable *pVTable; /* List of VTable objects. */
#endif
Trigger *pTrigger; /* List of triggers stored in pSchema */
Schema *pSchema; /* Schema that contains this table */
@ -1330,7 +1333,7 @@ struct Table {
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE
# define IsVirtual(X) (((X)->tabFlags & TF_Virtual)!=0)
# define IsHiddenColumn(X) ((X)->isHidden)
# define IsHiddenColumn(X) (((X)->colFlags & COLFLAG_HIDDEN)!=0)
#else
# define IsVirtual(X) 0
# define IsHiddenColumn(X) 0
@ -1675,13 +1678,15 @@ struct Expr {
ExprList *pList; /* Function arguments or in "<expr> IN (<expr-list)" */
Select *pSelect; /* Used for sub-selects and "<expr> IN (<select>)" */
} x;
CollSeq *pColl; /* The collation type of the column or 0 */
/* If the EP_Reduced flag is set in the Expr.flags mask, then no
** space is allocated for the fields below this point. An attempt to
** access them will result in a segfault or malfunction.
*********************************************************************/
#if SQLITE_MAX_EXPR_DEPTH>0
int nHeight; /* Height of the tree headed by this node */
#endif
int iTable; /* TK_COLUMN: cursor number of table holding column
** TK_REGISTER: register number
** TK_TRIGGER: 1 -> new, 0 -> old */
@ -1695,9 +1700,6 @@ struct Expr {
** TK_AGG_FUNCTION: nesting depth */
AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
Table *pTab; /* Table for TK_COLUMN expressions. */
#if SQLITE_MAX_EXPR_DEPTH>0
int nHeight; /* Height of the tree headed by this node */
#endif
};
/*
@ -1711,7 +1713,7 @@ struct Expr {
#define EP_VarSelect 0x0020 /* pSelect is correlated, not constant */
#define EP_DblQuoted 0x0040 /* token.z was originally in "..." */
#define EP_InfixFunc 0x0080 /* True for an infix function: LIKE, GLOB, etc */
#define EP_ExpCollate 0x0100 /* Collating sequence specified explicitly */
#define EP_Collate 0x0100 /* Tree contains a TK_COLLATE opeartor */
#define EP_FixedDest 0x0200 /* Result needed in a specific register */
#define EP_IntValue 0x0400 /* Integer value contained in u.iValue */
#define EP_xIsSelect 0x0800 /* x.pSelect is valid (otherwise x.pList is) */
@ -1855,6 +1857,7 @@ struct SrcList {
i16 nSrc; /* Number of tables or subqueries in the FROM clause */
i16 nAlloc; /* Number of entries allocated in a[] below */
struct SrcList_item {
Schema *pSchema; /* Schema to which this item is fixed */
char *zDatabase; /* Name of database holding this table */
char *zName; /* Name of the table */
char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */
@ -1863,8 +1866,9 @@ struct SrcList {
int addrFillSub; /* Address of subroutine to manifest a subquery */
int regReturn; /* Register holding return address of addrFillSub */
u8 jointype; /* Type of join between this able and the previous */
u8 notIndexed; /* True if there is a NOT INDEXED clause */
u8 isCorrelated; /* True if sub-query is correlated */
unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */
unsigned isCorrelated :1; /* True if sub-query is correlated */
unsigned viaCoroutine :1; /* Implemented as a co-routine */
#ifndef SQLITE_OMIT_EXPLAIN
u8 iSelectId; /* If pSelect!=0, the id of the sub-select in EQP */
#endif
@ -1905,7 +1909,8 @@ struct SrcList {
*/
struct WherePlan {
u32 wsFlags; /* WHERE_* flags that describe the strategy */
u32 nEq; /* Number of == constraints */
u16 nEq; /* Number of == constraints */
u16 nOBSat; /* Number of ORDER BY terms satisfied */
double nRow; /* Estimated number of rows (for EQP) */
union {
Index *pIdx; /* Index when WHERE_INDEXED is true */
@ -1949,6 +1954,7 @@ struct WhereLevel {
} in; /* Used when plan.wsFlags&WHERE_IN_ABLE */
Index *pCovidx; /* Possible covering index for WHERE_MULTI_OR */
} u;
double rOptCost; /* "Optimal" cost for this level */
/* The following field is really not part of the current level. But
** we need a place to cache virtual table index information for each
@ -1981,24 +1987,28 @@ struct WhereLevel {
** into the second half to give some continuity.
*/
struct WhereInfo {
Parse *pParse; /* Parsing and code generating context */
u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */
u8 okOnePass; /* Ok to use one-pass algorithm for UPDATE or DELETE */
u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */
u8 eDistinct;
SrcList *pTabList; /* List of tables in the join */
int iTop; /* The very beginning of the WHERE loop */
int iContinue; /* Jump here to continue with next record */
int iBreak; /* Jump here to break out of the loop */
int nLevel; /* Number of nested loop */
struct WhereClause *pWC; /* Decomposition of the WHERE clause */
double savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */
double nRowOut; /* Estimated number of output rows */
WhereLevel a[1]; /* Information about each nest loop in WHERE */
Parse *pParse; /* Parsing and code generating context */
SrcList *pTabList; /* List of tables in the join */
u16 nOBSat; /* Number of ORDER BY terms satisfied by indices */
u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */
u8 okOnePass; /* Ok to use one-pass algorithm for UPDATE/DELETE */
u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */
u8 eDistinct; /* One of the WHERE_DISTINCT_* values below */
int iTop; /* The very beginning of the WHERE loop */
int iContinue; /* Jump here to continue with next record */
int iBreak; /* Jump here to break out of the loop */
int nLevel; /* Number of nested loop */
struct WhereClause *pWC; /* Decomposition of the WHERE clause */
double savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */
double nRowOut; /* Estimated number of output rows */
WhereLevel a[1]; /* Information about each nest loop in WHERE */
};
#define WHERE_DISTINCT_UNIQUE 1
#define WHERE_DISTINCT_ORDERED 2
/* Allowed values for WhereInfo.eDistinct and DistinctCtx.eTnctType */
#define WHERE_DISTINCT_NOOP 0 /* DISTINCT keyword not used */
#define WHERE_DISTINCT_UNIQUE 1 /* No duplicates */
#define WHERE_DISTINCT_ORDERED 2 /* All duplicates are adjacent */
#define WHERE_DISTINCT_UNORDERED 3 /* Duplicates are scattered */
/*
** A NameContext defines a context in which to resolve table and column
@ -2057,13 +2067,12 @@ struct NameContext {
** as the OP_OpenEphm instruction is coded because not
** enough information about the compound query is known at that point.
** The KeyInfo for addrOpenTran[0] and [1] contains collating sequences
** for the result set. The KeyInfo for addrOpenTran[2] contains collating
** for the result set. The KeyInfo for addrOpenEphm[2] contains collating
** sequences for the ORDER BY clause.
*/
struct Select {
ExprList *pEList; /* The fields of the result */
u8 op; /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
char affinity; /* MakeRecord with this affinity for SRT_Set */
u16 selFlags; /* Various SF_* values */
int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */
int addrOpenEphm[3]; /* OP_OpenEphem opcodes related to this select */
@ -2084,14 +2093,15 @@ struct Select {
** Allowed values for Select.selFlags. The "SF" prefix stands for
** "Select Flag".
*/
#define SF_Distinct 0x01 /* Output should be DISTINCT */
#define SF_Resolved 0x02 /* Identifiers have been resolved */
#define SF_Aggregate 0x04 /* Contains aggregate functions */
#define SF_UsesEphemeral 0x08 /* Uses the OpenEphemeral opcode */
#define SF_Expanded 0x10 /* sqlite3SelectExpand() called on this */
#define SF_HasTypeInfo 0x20 /* FROM subqueries have Table metadata */
#define SF_UseSorter 0x40 /* Sort using a sorter */
#define SF_Values 0x80 /* Synthesized from VALUES clause */
#define SF_Distinct 0x0001 /* Output should be DISTINCT */
#define SF_Resolved 0x0002 /* Identifiers have been resolved */
#define SF_Aggregate 0x0004 /* Contains aggregate functions */
#define SF_UsesEphemeral 0x0008 /* Uses the OpenEphemeral opcode */
#define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */
#define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */
#define SF_UseSorter 0x0040 /* Sort using a sorter */
#define SF_Values 0x0080 /* Synthesized from VALUES clause */
#define SF_Materialize 0x0100 /* Force materialization of views */
/*
@ -2114,13 +2124,12 @@ struct Select {
#define SRT_Coroutine 10 /* Generate a single row of result */
/*
** A structure used to customize the behavior of sqlite3Select(). See
** comments above sqlite3Select() for details.
** An instance of this object describes where to put of the results of
** a SELECT statement.
*/
typedef struct SelectDest SelectDest;
struct SelectDest {
u8 eDest; /* How to dispose of the results */
u8 affSdst; /* Affinity used when eDest==SRT_Set */
u8 eDest; /* How to dispose of the results. On of SRT_* above. */
char affSdst; /* Affinity used when eDest==SRT_Set */
int iSDParm; /* A parameter used by the eDest disposal method */
int iSdst; /* Base register where results are written */
int nSdst; /* Number of registers allocated */
@ -2321,6 +2330,7 @@ struct AuthContext {
#define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */
#define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */
#define OPFLAG_P2ISREG 0x02 /* P2 to OP_Open** is a register number */
#define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */
/*
* Each trigger present in the database schema is stored as an instance of
@ -2420,6 +2430,7 @@ struct TriggerStep {
typedef struct DbFixer DbFixer;
struct DbFixer {
Parse *pParse; /* The parsing context. Error messages written here */
Schema *pSchema; /* Fix items to this schema */
const char *zDb; /* Make sure all objects are contained in this database */
const char *zType; /* Type of the container - used for error messages */
const Token *pName; /* Name of the container - used for error messages */
@ -2462,6 +2473,7 @@ struct Sqlite3Config {
int bCoreMutex; /* True to enable core mutexing */
int bFullMutex; /* True to enable full mutexing */
int bOpenUri; /* True to interpret filenames as URIs */
int bUseCis; /* Use covering indices for full-scans */
int mxStrlen; /* Maximum string length */
int szLookaside; /* Default lookaside buffer size */
int nLookaside; /* Default lookaside buffer count */
@ -2491,6 +2503,10 @@ struct Sqlite3Config {
void (*xLog)(void*,int,const char*); /* Function for logging */
void *pLogArg; /* First argument to xLog() */
int bLocaltimeFault; /* True to fail localtime() calls */
#ifdef SQLITE_ENABLE_SQLLOG
void(*xSqllog)(void*,sqlite3*,const char*, int);
void *pSqllogArg;
#endif
};
/*
@ -2778,6 +2794,7 @@ void sqlite3DeleteTable(sqlite3*, Table*);
# define sqlite3AutoincrementBegin(X)
# define sqlite3AutoincrementEnd(X)
#endif
int sqlite3CodeCoroutine(Parse*, Select*, SelectDest*);
void sqlite3Insert(Parse*, SrcList*, ExprList*, Select*, IdList*, int);
void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*);
IdList *sqlite3IdListAppend(sqlite3*, IdList*, Token*);
@ -2807,13 +2824,11 @@ Expr *sqlite3LimitWhere(Parse *, SrcList *, Expr *, ExprList *, Expr *, Expr *,
#endif
void sqlite3DeleteFrom(Parse*, SrcList*, Expr*);
void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int);
WhereInfo *sqlite3WhereBegin(
Parse*,SrcList*,Expr*,ExprList**,ExprList*,u16,int);
WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int);
void sqlite3WhereEnd(WhereInfo*);
int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8);
void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int);
void sqlite3ExprCodeMove(Parse*, int, int, int);
void sqlite3ExprCodeCopy(Parse*, int, int, int);
void sqlite3ExprCacheStore(Parse*, int, int, int);
void sqlite3ExprCachePush(Parse*);
void sqlite3ExprCachePop(Parse*, int);
@ -2830,6 +2845,7 @@ void sqlite3ExprIfTrue(Parse*, Expr*, int, int);
void sqlite3ExprIfFalse(Parse*, Expr*, int, int);
Table *sqlite3FindTable(sqlite3*,const char*, const char*);
Table *sqlite3LocateTable(Parse*,int isView,const char*, const char*);
Table *sqlite3LocateTableItem(Parse*,int isView,struct SrcList_item *);
Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
@ -2953,7 +2969,7 @@ int sqlite3GetInt32(const char *, int*);
int sqlite3Atoi(const char*);
int sqlite3Utf16ByteLen(const void *pData, int nChar);
int sqlite3Utf8CharLen(const char *pData, int nByte);
u32 sqlite3Utf8Read(const u8*, const u8**);
u32 sqlite3Utf8Read(const u8**);
/*
** Routines to read and write variable-length integers. These used to
@ -3006,8 +3022,9 @@ int sqlite3ReadSchema(Parse *pParse);
CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
Expr *sqlite3ExprSetColl(Expr*, CollSeq*);
Expr *sqlite3ExprSetCollByToken(Parse *pParse, Expr*, Token*);
Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, Token*);
Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
Expr *sqlite3ExprSkipCollate(Expr*);
int sqlite3CheckCollSeq(Parse *, CollSeq *);
int sqlite3CheckObjectName(Parse *, const char *);
void sqlite3VdbeSetChanges(sqlite3 *, int);
@ -3060,7 +3077,7 @@ int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
void sqlite3AlterFinishAddColumn(Parse *, Token *);
void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
CollSeq *sqlite3GetCollSeq(sqlite3*, u8, CollSeq *, const char*);
CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*);
char sqlite3AffinityType(const char*);
void sqlite3Analyze(Parse*, Token*, Token*);
int sqlite3InvokeBusyHandler(BusyHandler*);
@ -3164,8 +3181,10 @@ void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*);
CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *);
int sqlite3TempInMemory(const sqlite3*);
const char *sqlite3JournalModename(int);
int sqlite3Checkpoint(sqlite3*, int, int, int*, int*);
int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int);
#ifndef SQLITE_OMIT_WAL
int sqlite3Checkpoint(sqlite3*, int, int, int*, int*);
int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int);
#endif
/* Declarations for functions in fkey.c. All of these are replaced by
** no-op macros if OMIT_FOREIGN_KEY is defined. In this case no foreign
@ -3223,8 +3242,10 @@ int sqlite3FindInIndex(Parse *, Expr *, int*);
int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int);
int sqlite3JournalSize(sqlite3_vfs *);
int sqlite3JournalCreate(sqlite3_file *);
int sqlite3JournalExists(sqlite3_file *p);
#else
#define sqlite3JournalSize(pVfs) ((pVfs)->szOsFile)
#define sqlite3JournalExists(p) 1
#endif
void sqlite3MemJournalOpen(sqlite3_file *);

View File

@ -208,7 +208,8 @@ int sqlite3_db_status(
db->pnBytesFreed = &nByte;
for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){
sqlite3VdbeDeleteObject(db, pVdbe);
sqlite3VdbeClearObject(db, pVdbe);
sqlite3DbFree(db, pVdbe);
}
db->pnBytesFreed = 0;

View File

@ -1489,7 +1489,7 @@ static Tcl_Obj *dbEvalColumnValue(DbEvalContext *p, int iCol){
}
}
return Tcl_NewStringObj(sqlite3_column_text(pStmt, iCol), -1);
return Tcl_NewStringObj((char*)sqlite3_column_text(pStmt, iCol), -1);
}
/*
@ -2343,7 +2343,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
const char *zDb = "main";
const char *zTable;
const char *zColumn;
sqlite_int64 iRow;
Tcl_WideInt iRow;
/* Check for the -readonly option */
if( objc>3 && strcmp(Tcl_GetString(objv[2]), "-readonly")==0 ){
@ -2534,7 +2534,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
pKey = Tcl_GetByteArrayFromObj(objv[2], &nKey);
rc = sqlite3_rekey(pDb->db, pKey, nKey);
if( rc ){
Tcl_AppendResult(interp, sqlite3ErrStr(rc), 0);
Tcl_AppendResult(interp, sqlite3_errstr(rc), 0);
rc = TCL_ERROR;
}
#endif
@ -2905,6 +2905,7 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
void *pKey = 0;
int nKey = 0;
#endif
int rc;
/* In normal use, each TCL interpreter runs in a single thread. So
** by default, we can turn of mutexing on SQLite database connections.
@ -3009,12 +3010,16 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
memset(p, 0, sizeof(*p));
zFile = Tcl_GetStringFromObj(objv[2], 0);
zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename);
sqlite3_open_v2(zFile, &p->db, flags, zVfs);
rc = sqlite3_open_v2(zFile, &p->db, flags, zVfs);
Tcl_DStringFree(&translatedFilename);
if( SQLITE_OK!=sqlite3_errcode(p->db) ){
zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(p->db));
sqlite3_close(p->db);
p->db = 0;
if( p->db ){
if( SQLITE_OK!=sqlite3_errcode(p->db) ){
zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(p->db));
sqlite3_close(p->db);
p->db = 0;
}
}else{
zErrMsg = sqlite3_mprintf("%s", sqlite3_errstr(rc));
}
#ifdef SQLITE_HAS_CODEC
if( p->db ){

View File

@ -3067,7 +3067,7 @@ static int test_bind_int64(
){
sqlite3_stmt *pStmt;
int idx;
i64 value;
Tcl_WideInt value;
int rc;
if( objc!=4 ){
@ -4703,7 +4703,7 @@ static int test_soft_heap_limit(
Tcl_Obj *CONST objv[]
){
sqlite3_int64 amt;
sqlite3_int64 N = -1;
Tcl_WideInt N = -1;
if( objc!=1 && objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "?N?");
return TCL_ERROR;
@ -5096,7 +5096,7 @@ static int file_control_sizehint_test(
int objc, /* Number of arguments */
Tcl_Obj *CONST objv[] /* Command arguments */
){
sqlite3_int64 nSize; /* Hinted size */
Tcl_WideInt nSize; /* Hinted size */
char *zDb; /* Db name ("main", "temp" etc.) */
sqlite3 *db; /* Database handle */
int rc; /* file_control() return code */
@ -5321,6 +5321,38 @@ static int file_control_vfsname(
return TCL_OK;
}
/*
** tclcmd: file_control_tempfilename DB ?AUXDB?
**
** Return a string that is a temporary filename
*/
static int file_control_tempfilename(
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
int objc, /* Number of arguments */
Tcl_Obj *CONST objv[] /* Command arguments */
){
sqlite3 *db;
const char *zDbName = "main";
char *zTName = 0;
if( objc!=2 && objc!=3 ){
Tcl_AppendResult(interp, "wrong # args: should be \"",
Tcl_GetStringFromObj(objv[0], 0), " DB ?AUXDB?", 0);
return TCL_ERROR;
}
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
return TCL_ERROR;
}
if( objc==3 ){
zDbName = Tcl_GetString(objv[2]);
}
sqlite3_file_control(db, zDbName, SQLITE_FCNTL_TEMPFILENAME, (void*)&zTName);
Tcl_AppendResult(interp, zTName, (char*)0);
sqlite3_free(zTName);
return TCL_OK;
}
/*
** tclcmd: sqlite3_vfs_list
@ -5933,15 +5965,15 @@ static int optimization_control(
const char *zOptName;
int mask;
} aOpt[] = {
{ "all", SQLITE_OptMask },
{ "all", SQLITE_AllOpts },
{ "query-flattener", SQLITE_QueryFlattener },
{ "column-cache", SQLITE_ColumnCache },
{ "index-sort", SQLITE_IndexSort },
{ "index-search", SQLITE_IndexSearch },
{ "index-cover", SQLITE_IndexCover },
{ "groupby-order", SQLITE_GroupByOrder },
{ "factor-constants", SQLITE_FactorOutConst },
{ "real-as-int", SQLITE_IdxRealAsInt },
{ "distinct-opt", SQLITE_DistinctOpt },
{ "cover-idx-scan", SQLITE_CoverIdxScan },
{ "order-by-idx-join",SQLITE_OrderByIdxJoin },
};
if( objc!=4 ){
@ -6150,6 +6182,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "file_control_persist_wal", file_control_persist_wal, 0 },
{ "file_control_powersafe_overwrite",file_control_powersafe_overwrite,0},
{ "file_control_vfsname", file_control_vfsname, 0 },
{ "file_control_tempfilename", file_control_tempfilename, 0 },
{ "sqlite3_vfs_list", vfs_list, 0 },
{ "sqlite3_create_function_v2", test_create_function_v2, 0 },

View File

@ -312,8 +312,8 @@ static int writeListSync(CrashFile *pFile, int isCrash){
assert(pWrite->zBuf);
#ifdef TRACE_CRASHTEST
printf("Trashing %d sectors @ sector %d (%s)\n",
1+iLast-iFirst, iFirst, pWrite->pFile->zName
printf("Trashing %d sectors @ %lld (sector %d) (%s)\n",
1+iLast-iFirst, pWrite->iOffset, iFirst, pWrite->pFile->zName
);
#endif
@ -628,18 +628,19 @@ static int cfOpen(
** to read data from the 512-byte locking region of a file opened
** with the SQLITE_OPEN_MAIN_DB flag. This region of a database file
** never contains valid data anyhow. So avoid doing such a read here.
**
** UPDATE: It also contains an assert() verifying that each call
** to the xRead() method reads less than 128KB of data.
*/
const int isDb = (flags&SQLITE_OPEN_MAIN_DB);
i64 iChunk = pWrapper->iSize;
if( iChunk>PENDING_BYTE && isDb ){
iChunk = PENDING_BYTE;
}
i64 iOff;
memset(pWrapper->zData, 0, pWrapper->nData);
rc = sqlite3OsRead(pReal, pWrapper->zData, (int)iChunk, 0);
if( SQLITE_OK==rc && pWrapper->iSize>(PENDING_BYTE+512) && isDb ){
i64 iOff = PENDING_BYTE+512;
iChunk = pWrapper->iSize - iOff;
rc = sqlite3OsRead(pReal, &pWrapper->zData[iOff], (int)iChunk, iOff);
for(iOff=0; iOff<pWrapper->iSize; iOff += 512){
int nRead = pWrapper->iSize - (int)iOff;
if( nRead>512 ) nRead = 512;
if( isDb && iOff==PENDING_BYTE ) continue;
rc = sqlite3OsRead(pReal, &pWrapper->zData[iOff], nRead, iOff);
}
}else{
rc = SQLITE_NOMEM;

View File

@ -346,8 +346,9 @@ static int test_intarray_bind(
return TCL_ERROR;
}
for(i=0; i<n; i++){
a[i] = 0;
Tcl_GetWideIntFromObj(0, objv[i+2], &a[i]);
Tcl_WideInt x = 0;
Tcl_GetWideIntFromObj(0, objv[i+2], &x);
a[i] = x;
}
rc = sqlite3_intarray_bind(pArray, n, a, sqlite3_free);
if( rc!=SQLITE_OK ){

View File

@ -76,6 +76,13 @@
*/
#include "sqlite3.h"
/*
** Make sure we can call this stuff from C++.
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
** An sqlite3_intarray is an abstract type to stores an instance of
** an integer array.
@ -112,3 +119,7 @@ int sqlite3_intarray_bind(
sqlite3_int64 *aElements, /* Content of the intarray */
void (*xFree)(void*) /* How to dispose of the intarray when done */
);
#ifdef __cplusplus
} /* End of the 'extern "C"' block */
#endif

View File

@ -720,8 +720,8 @@ static int test_memdebug_settitle(
#ifdef SQLITE_MEMDEBUG
{
const char *zTitle;
zTitle = Tcl_GetString(objv[1]);
extern int sqlite3MemdebugSettitle(const char*);
zTitle = Tcl_GetString(objv[1]);
sqlite3MemdebugSettitle(zTitle);
}
#endif
@ -1094,9 +1094,7 @@ static int test_db_config_lookaside(
}
/*
** Usage:
**
** sqlite3_config_heap NBYTE NMINALLOC
** Usage: sqlite3_config_heap NBYTE NMINALLOC
*/
static int test_config_heap(
void * clientData,
@ -1133,7 +1131,7 @@ static int test_config_heap(
}
/*
** tclcmd: sqlite3_config_error [DB]
** Usage: sqlite3_config_error [DB]
**
** Invoke sqlite3_config() or sqlite3_db_config() with invalid
** opcodes and verify that they return errors.
@ -1171,10 +1169,10 @@ static int test_config_error(
}
/*
** tclcmd: sqlite3_config_uri BOOLEAN
** Usage: sqlite3_config_uri BOOLEAN
**
** Invoke sqlite3_config() or sqlite3_db_config() with invalid
** opcodes and verify that they return errors.
** Enables or disables interpretation of URI parameters by default using
** SQLITE_CONFIG_URI.
*/
static int test_config_uri(
void * clientData,
@ -1200,10 +1198,37 @@ static int test_config_uri(
}
/*
** Usage:
** Usage: sqlite3_config_cis BOOLEAN
**
** sqlite3_dump_memsys3 FILENAME
** sqlite3_dump_memsys5 FILENAME
** Enables or disables the use of the covering-index scan optimization.
** SQLITE_CONFIG_COVERING_INDEX_SCAN.
*/
static int test_config_cis(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
int rc;
int bUseCis;
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "BOOL");
return TCL_ERROR;
}
if( Tcl_GetBooleanFromObj(interp, objv[1], &bUseCis) ){
return TCL_ERROR;
}
rc = sqlite3_config(SQLITE_CONFIG_COVERING_INDEX_SCAN, bUseCis);
Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE);
return TCL_OK;
}
/*
** Usage: sqlite3_dump_memsys3 FILENAME
** sqlite3_dump_memsys5 FILENAME
**
** Write a summary of unfreed memsys3 allocations to FILENAME.
*/
@ -1451,6 +1476,7 @@ int Sqlitetest_malloc_Init(Tcl_Interp *interp){
{ "sqlite3_config_lookaside", test_config_lookaside ,0 },
{ "sqlite3_config_error", test_config_error ,0 },
{ "sqlite3_config_uri", test_config_uri ,0 },
{ "sqlite3_config_cis", test_config_cis ,0 },
{ "sqlite3_db_config_lookaside",test_db_config_lookaside ,0 },
{ "sqlite3_dump_memsys3", test_dump_memsys3 ,3 },
{ "sqlite3_dump_memsys5", test_dump_memsys3 ,5 },

View File

@ -46,6 +46,10 @@
#define MULTIPLEX_CTRL_SET_CHUNK_SIZE 214015
#define MULTIPLEX_CTRL_SET_MAX_CHUNKS 214016
#ifdef __cplusplus
extern "C" {
#endif
/*
** CAPI: Initialize the multiplex VFS shim - sqlite3_multiplex_initialize()
**
@ -88,4 +92,8 @@ extern int sqlite3_multiplex_initialize(const char *zOrigVfsName, int makeDefaul
*/
extern int sqlite3_multiplex_shutdown(void);
#ifdef __cplusplus
} /* End of the 'extern "C"' block */
#endif
#endif

View File

@ -1073,7 +1073,7 @@ size_t sqlite3_quota_fwrite(
/* If the write was incomplete, adjust the file size and group size
** downward */
if( rc<nmemb && pFile ){
size_t nWritten = rc>=0 ? rc : 0;
size_t nWritten = rc;
sqlite3_int64 iNewEnd = iOfst + size*nWritten;
if( iNewEnd<iEnd ) iNewEnd = iEnd;
quotaEnter();
@ -1179,7 +1179,13 @@ int sqlite3_quota_ftruncate(quota_FILE *p, sqlite3_int64 szNew){
rc = ftruncate(fileno(p->f), szNew);
#endif
#if SQLITE_OS_WIN
rc = _chsize_s(_fileno(p->f), szNew);
# if defined(__MINGW32__) && defined(SQLITE_TEST)
/* _chsize_s() is missing from MingW (as of 2012-11-06). Use
** _chsize() as a work-around for testing purposes. */
rc = _chsize(_fileno(p->f), (long)szNew);
# else
rc = _chsize_s(_fileno(p->f), szNew);
# endif
#endif
if( pFile && rc==0 ){
quotaGroup *pGroup = pFile->pGroup;
@ -1354,8 +1360,10 @@ static void tclQuotaCallback(
rc = Tcl_EvalObjEx(p->interp, pEval, TCL_EVAL_GLOBAL);
if( rc==TCL_OK ){
Tcl_WideInt x;
Tcl_Obj *pLimit = Tcl_ObjGetVar2(p->interp, pVarname, 0, 0);
rc = Tcl_GetWideIntFromObj(p->interp, pLimit, piLimit);
rc = Tcl_GetWideIntFromObj(p->interp, pLimit, &x);
*piLimit = x;
Tcl_UnsetVar(p->interp, Tcl_GetString(pVarname), 0);
}
@ -1437,7 +1445,7 @@ static int test_quota_set(
Tcl_Obj *CONST objv[]
){
const char *zPattern; /* File pattern to configure */
sqlite3_int64 iLimit; /* Initial quota in bytes */
Tcl_WideInt iLimit; /* Initial quota in bytes */
Tcl_Obj *pScript; /* Tcl script to invoke to increase quota */
int rc; /* Value returned by quota_set() */
TclQuotaCallback *p; /* Callback object */
@ -1613,7 +1621,6 @@ static int test_quota_fread(
return TCL_ERROR;
}
got = sqlite3_quota_fread(zBuf, sz, nElem, p);
if( got<0 ) got = 0;
zBuf[got*sz] = 0;
Tcl_SetResult(interp, zBuf, TCL_VOLATILE);
sqlite3_free(zBuf);

View File

@ -475,6 +475,7 @@ static int vfstraceFileControl(sqlite3_file *pFile, int op, void *pArg){
case SQLITE_FCNTL_PERSIST_WAL: zOp = "PERSIST_WAL"; break;
case SQLITE_FCNTL_OVERWRITE: zOp = "OVERWRITE"; break;
case SQLITE_FCNTL_VFSNAME: zOp = "VFSNAME"; break;
case SQLITE_FCNTL_TEMPFILENAME: zOp = "TEMPFILENAME"; break;
case 0xca093fa0: zOp = "DB_UNCHANGED"; break;
case SQLITE_FCNTL_PRAGMA: {
const char *const* a = (const char*const*)pArg;
@ -496,7 +497,8 @@ static int vfstraceFileControl(sqlite3_file *pFile, int op, void *pArg){
*(char**)pArg = sqlite3_mprintf("vfstrace.%s/%z",
pInfo->zVfsName, *(char**)pArg);
}
if( op==SQLITE_FCNTL_PRAGMA && rc==SQLITE_OK && *(char**)pArg ){
if( (op==SQLITE_FCNTL_PRAGMA || op==SQLITE_FCNTL_TEMPFILENAME)
&& rc==SQLITE_OK && *(char**)pArg ){
vfstrace_printf(pInfo, "%s.xFileControl(%s,%s) returns %s",
pInfo->zVfsName, p->zFName, zOp, *(char**)pArg);
}

View File

@ -729,6 +729,15 @@ static int codeTriggerProgram(
*/
pParse->eOrconf = (orconf==OE_Default)?pStep->orconf:(u8)orconf;
/* Clear the cookieGoto flag. When coding triggers, the cookieGoto
** variable is used as a flag to indicate to sqlite3ExprCodeConstants()
** that it is not safe to refactor constants (this happens after the
** start of the first loop in the SQL statement is coded - at that
** point code may be conditionally executed, so it is no longer safe to
** initialize constant register values). */
assert( pParse->cookieGoto==0 || pParse->cookieGoto==-1 );
pParse->cookieGoto = 0;
switch( pStep->op ){
case TK_UPDATE: {
sqlite3Update(pParse,

View File

@ -164,25 +164,23 @@ static const unsigned char sqlite3Utf8Trans1[] = {
|| (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } \
}
u32 sqlite3Utf8Read(
const unsigned char *zIn, /* First byte of UTF-8 character */
const unsigned char **pzNext /* Write first byte past UTF-8 char here */
const unsigned char **pz /* Pointer to string from which to read char */
){
unsigned int c;
/* Same as READ_UTF8() above but without the zTerm parameter.
** For this routine, we assume the UTF8 string is always zero-terminated.
*/
c = *(zIn++);
c = *((*pz)++);
if( c>=0xc0 ){
c = sqlite3Utf8Trans1[c-0xc0];
while( (*zIn & 0xc0)==0x80 ){
c = (c<<6) + (0x3f & *(zIn++));
while( (*(*pz) & 0xc0)==0x80 ){
c = (c<<6) + (0x3f & *((*pz)++));
}
if( c<0x80
|| (c&0xFFFFF800)==0xD800
|| (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; }
}
*pzNext = zIn;
return c;
}
@ -283,7 +281,6 @@ int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
if( desiredEnc==SQLITE_UTF16LE ){
/* UTF-8 -> UTF-16 Little-endian */
while( zIn<zTerm ){
/* c = sqlite3Utf8Read(zIn, zTerm, (const u8**)&zIn); */
READ_UTF8(zIn, zTerm, c);
WRITE_UTF16LE(z, c);
}
@ -291,7 +288,6 @@ int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
assert( desiredEnc==SQLITE_UTF16BE );
/* UTF-8 -> UTF-16 Big-endian */
while( zIn<zTerm ){
/* c = sqlite3Utf8Read(zIn, zTerm, (const u8**)&zIn); */
READ_UTF8(zIn, zTerm, c);
WRITE_UTF16BE(z, c);
}
@ -419,7 +415,7 @@ int sqlite3Utf8To8(unsigned char *zIn){
u32 c;
while( zIn[0] && zOut<=zIn ){
c = sqlite3Utf8Read(zIn, (const u8**)&zIn);
c = sqlite3Utf8Read((const u8**)&zIn);
if( c!=0xfffd ){
WRITE_UTF8(zOut, c);
}
@ -524,7 +520,7 @@ void sqlite3UtfSelfTest(void){
assert( n>0 && n<=4 );
z[0] = 0;
z = zBuf;
c = sqlite3Utf8Read(z, (const u8**)&z);
c = sqlite3Utf8Read((const u8**)&z);
t = i;
if( i>=0xD800 && i<=0xDFFF ) t = 0xFFFD;
if( (i&0xFFFFFFFE)==0xFFFE ) t = 0xFFFD;

View File

@ -85,6 +85,7 @@ void sqlite3Vacuum(Parse *pParse){
Vdbe *v = sqlite3GetVdbe(pParse);
if( v ){
sqlite3VdbeAddOp2(v, OP_Vacuum, 0, 0);
sqlite3VdbeUsesBtree(v, 0);
}
return;
}

View File

@ -422,7 +422,9 @@ void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){
** Print the value of a register for tracing purposes:
*/
static void memTracePrint(FILE *out, Mem *p){
if( p->flags & MEM_Null ){
if( p->flags & MEM_Invalid ){
fprintf(out, " undefined");
}else if( p->flags & MEM_Null ){
fprintf(out, " NULL");
}else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
fprintf(out, " si:%lld", p->u.i);
@ -956,23 +958,28 @@ case OP_String: { /* out2-prerelease */
break;
}
/* Opcode: Null * P2 P3 * *
/* Opcode: Null P1 P2 P3 * *
**
** Write a NULL into registers P2. If P3 greater than P2, then also write
** NULL into register P3 and ever register in between P2 and P3. If P3
** NULL into register P3 and every register in between P2 and P3. If P3
** is less than P2 (typically P3 is zero) then only register P2 is
** set to NULL
** set to NULL.
**
** If the P1 value is non-zero, then also set the MEM_Cleared flag so that
** NULL values will not compare equal even if SQLITE_NULLEQ is set on
** OP_Ne or OP_Eq.
*/
case OP_Null: { /* out2-prerelease */
int cnt;
u16 nullFlag;
cnt = pOp->p3-pOp->p2;
assert( pOp->p3<=p->nMem );
pOut->flags = MEM_Null;
pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null;
while( cnt>0 ){
pOut++;
memAboutToChange(p, pOut);
VdbeMemRelease(pOut);
pOut->flags = MEM_Null;
pOut->flags = nullFlag;
cnt--;
}
break;
@ -1015,10 +1022,10 @@ case OP_Variable: { /* out2-prerelease */
/* Opcode: Move P1 P2 P3 * *
**
** Move the values in register P1..P1+P3-1 over into
** registers P2..P2+P3-1. Registers P1..P1+P1-1 are
** Move the values in register P1..P1+P3 over into
** registers P2..P2+P3. Registers P1..P1+P3 are
** left holding a NULL. It is an error for register ranges
** P1..P1+P3-1 and P2..P2+P3-1 to overlap.
** P1..P1+P3 and P2..P2+P3 to overlap.
*/
case OP_Move: {
char *zMalloc; /* Holding variable for allocated memory */
@ -1026,7 +1033,7 @@ case OP_Move: {
int p1; /* Register to copy from */
int p2; /* Register to copy to */
n = pOp->p3;
n = pOp->p3 + 1;
p1 = pOp->p1;
p2 = pOp->p2;
assert( n>0 && p1>0 && p2>0 );
@ -1055,20 +1062,31 @@ case OP_Move: {
break;
}
/* Opcode: Copy P1 P2 * * *
/* Opcode: Copy P1 P2 P3 * *
**
** Make a copy of register P1 into register P2.
** Make a copy of registers P1..P1+P3 into registers P2..P2+P3.
**
** This instruction makes a deep copy of the value. A duplicate
** is made of any string or blob constant. See also OP_SCopy.
*/
case OP_Copy: { /* in1, out2 */
case OP_Copy: {
int n;
n = pOp->p3;
pIn1 = &aMem[pOp->p1];
pOut = &aMem[pOp->p2];
assert( pOut!=pIn1 );
sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
Deephemeralize(pOut);
REGISTER_TRACE(pOp->p2, pOut);
while( 1 ){
sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
Deephemeralize(pOut);
#ifdef SQLITE_DEBUG
pOut->pScopyFrom = 0;
#endif
REGISTER_TRACE(pOp->p2+pOp->p3-n, pOut);
if( (n--)==0 ) break;
pOut++;
pIn1++;
}
break;
}
@ -1252,6 +1270,7 @@ case OP_Subtract: /* same as TK_MINUS, in1, in2, out3 */
case OP_Multiply: /* same as TK_STAR, in1, in2, out3 */
case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */
case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
char bIntint; /* Started out as two integer operands */
int flags; /* Combined MEM_* flags from both inputs */
i64 iA; /* Integer value of left operand */
i64 iB; /* Integer value of right operand */
@ -1268,6 +1287,7 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
if( (pIn1->flags & pIn2->flags & MEM_Int)==MEM_Int ){
iA = pIn1->u.i;
iB = pIn2->u.i;
bIntint = 1;
switch( pOp->opcode ){
case OP_Add: if( sqlite3AddInt64(&iB,iA) ) goto fp_math; break;
case OP_Subtract: if( sqlite3SubInt64(&iB,iA) ) goto fp_math; break;
@ -1288,6 +1308,7 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
pOut->u.i = iB;
MemSetTypeFlag(pOut, MEM_Int);
}else{
bIntint = 0;
fp_math:
rA = sqlite3VdbeRealValue(pIn1);
rB = sqlite3VdbeRealValue(pIn2);
@ -1319,7 +1340,7 @@ fp_math:
}
pOut->r = rB;
MemSetTypeFlag(pOut, MEM_Real);
if( (flags & MEM_Real)==0 ){
if( (flags & MEM_Real)==0 && !bIntint ){
sqlite3VdbeIntegerAffinity(pOut);
}
#endif
@ -1737,6 +1758,10 @@ case OP_ToReal: { /* same as TK_TO_REAL, in1 */
**
** If the SQLITE_STOREP2 bit of P5 is set, then do not jump. Instead,
** store a boolean result (either 0, or 1, or NULL) in register P2.
**
** If the SQLITE_NULLEQ bit is set in P5, then NULL values are considered
** equal to one another, provided that they do not have their MEM_Cleared
** bit set.
*/
/* Opcode: Ne P1 P2 P3 P4 P5
**
@ -1803,7 +1828,15 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
** or not both operands are null.
*/
assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne );
res = (flags1 & flags3 & MEM_Null)==0;
assert( (flags1 & MEM_Cleared)==0 );
if( (flags1&MEM_Null)!=0
&& (flags3&MEM_Null)!=0
&& (flags3&MEM_Cleared)==0
){
res = 0; /* Results are equal */
}else{
res = 1; /* Results are not equal */
}
}else{
/* SQLITE_NULLEQ is clear and at least one operand is NULL,
** then the result is always NULL.
@ -1862,9 +1895,9 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
** Set the permutation used by the OP_Compare operator to be the array
** of integers in P4.
**
** The permutation is only valid until the next OP_Permutation, OP_Compare,
** OP_Halt, or OP_ResultRow. Typically the OP_Permutation should occur
** immediately prior to the OP_Compare.
** The permutation is only valid until the next OP_Compare that has
** the OPFLAG_PERMUTE bit set in P5. Typically the OP_Permutation should
** occur immediately prior to the OP_Compare.
*/
case OP_Permutation: {
assert( pOp->p4type==P4_INTARRAY );
@ -1873,12 +1906,17 @@ case OP_Permutation: {
break;
}
/* Opcode: Compare P1 P2 P3 P4 *
/* Opcode: Compare P1 P2 P3 P4 P5
**
** Compare two vectors of registers in reg(P1)..reg(P1+P3-1) (call this
** vector "A") and in reg(P2)..reg(P2+P3-1) ("B"). Save the result of
** the comparison for use by the next OP_Jump instruct.
**
** If P5 has the OPFLAG_PERMUTE bit set, then the order of comparison is
** determined by the most recent OP_Permutation operator. If the
** OPFLAG_PERMUTE bit is clear, then register are compared in sequential
** order.
**
** P4 is a KeyInfo structure that defines collating sequences and sort
** orders for the comparison. The permutation applies to registers
** only. The KeyInfo elements are used sequentially.
@ -1897,6 +1935,7 @@ case OP_Compare: {
CollSeq *pColl; /* Collating sequence to use on this term */
int bRev; /* True for DESCENDING sort order */
if( (pOp->p5 & OPFLAG_PERMUTE)==0 ) aPermute = 0;
n = pOp->p3;
pKeyInfo = pOp->p4.pKeyInfo;
assert( n>0 );
@ -2040,8 +2079,6 @@ case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */
**
** Check if OP_Once flag P1 is set. If so, jump to instruction P2. Otherwise,
** set the flag and fall through to the next instruction.
**
** See also: JumpOnce
*/
case OP_Once: { /* jump */
assert( pOp->p1<p->nOnceFlag );
@ -2212,6 +2249,11 @@ case OP_Column: {
}
}else if( ALWAYS(pC->pseudoTableReg>0) ){
pReg = &aMem[pC->pseudoTableReg];
if( pC->multiPseudo ){
sqlite3VdbeMemShallowCopy(pDest, pReg+p2, MEM_Ephem);
Deephemeralize(pDest);
goto op_column_out;
}
assert( pReg->flags & MEM_Blob );
assert( memIsValid(pReg) );
payloadSize = pReg->n;
@ -3270,7 +3312,7 @@ case OP_OpenEphemeral: {
break;
}
/* Opcode: OpenSorter P1 P2 * P4 *
/* Opcode: SorterOpen P1 P2 * P4 *
**
** This opcode works like OP_OpenEphemeral except that it opens
** a transient index that is specifically designed to sort large
@ -3278,6 +3320,7 @@ case OP_OpenEphemeral: {
*/
case OP_SorterOpen: {
VdbeCursor *pCx;
#ifndef SQLITE_OMIT_MERGE_SORT
pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
if( pCx==0 ) goto no_mem;
@ -3292,12 +3335,13 @@ case OP_SorterOpen: {
break;
}
/* Opcode: OpenPseudo P1 P2 P3 * *
/* Opcode: OpenPseudo P1 P2 P3 * P5
**
** Open a new cursor that points to a fake table that contains a single
** row of data. The content of that one row in the content of memory
** register P2. In other words, cursor P1 becomes an alias for the
** MEM_Blob content contained in register P2.
** register P2 when P5==0. In other words, cursor P1 becomes an alias for the
** MEM_Blob content contained in register P2. When P5==1, then the
** row is represented by P3 consecutive registers beginning with P2.
**
** A pseudo-table created by this opcode is used to hold a single
** row output from the sorter so that the row can be decomposed into
@ -3317,6 +3361,7 @@ case OP_OpenPseudo: {
pCx->pseudoTableReg = pOp->p2;
pCx->isTable = 1;
pCx->isIndex = 0;
pCx->multiPseudo = pOp->p5;
break;
}
@ -4168,6 +4213,7 @@ case OP_SorterCompare: {
*/
case OP_SorterData: {
VdbeCursor *pC;
#ifndef SQLITE_OMIT_MERGE_SORT
pOut = &aMem[pOp->p2];
pC = p->apCsr[pOp->p1];
@ -4280,7 +4326,7 @@ case OP_Rowid: { /* out2-prerelease */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
assert( pC->pseudoTableReg==0 );
assert( pC->pseudoTableReg==0 || pC->nullRow );
if( pC->nullRow ){
pOut->flags = MEM_Null;
break;
@ -4706,6 +4752,7 @@ case OP_Destroy: { /* out2-prerelease */
int iCnt;
Vdbe *pVdbe;
int iDb;
#ifndef SQLITE_OMIT_VIRTUALTABLE
iCnt = 0;
for(pVdbe=db->pVdbe; pVdbe; pVdbe = pVdbe->pNext){
@ -5495,7 +5542,9 @@ case OP_JournalMode: { /* out2-prerelease */
Pager *pPager; /* Pager associated with pBt */
int eNew; /* New journal mode */
int eOld; /* The old journal mode */
#ifndef SQLITE_OMIT_WAL
const char *zFilename; /* Name of database file for pPager */
#endif
eNew = pOp->p3;
assert( eNew==PAGER_JOURNALMODE_DELETE
@ -6075,7 +6124,10 @@ case OP_Trace: {
char *zTrace;
char *z;
if( db->xTrace && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 ){
if( db->xTrace
&& !p->doingRerun
&& (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
){
z = sqlite3VdbeExpandSql(p, zTrace);
db->xTrace(db->pTraceArg, z);
sqlite3DbFree(db, z);

View File

@ -188,7 +188,7 @@ VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
int sqlite3VdbeMakeLabel(Vdbe*);
void sqlite3VdbeRunOnlyOnce(Vdbe*);
void sqlite3VdbeDelete(Vdbe*);
void sqlite3VdbeDeleteObject(sqlite3*,Vdbe*);
void sqlite3VdbeClearObject(sqlite3*,Vdbe*);
void sqlite3VdbeMakeReady(Vdbe*,Parse*);
int sqlite3VdbeFinalize(Vdbe*);
void sqlite3VdbeResolveLabel(Vdbe*, int);

View File

@ -63,6 +63,7 @@ struct VdbeCursor {
Bool isIndex; /* True if an index containing keys only - no data */
Bool isOrdered; /* True if the underlying table is BTREE_UNORDERED */
Bool isSorter; /* True if a new-style sorter */
Bool multiPseudo; /* Multi-register pseudo-cursor */
sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */
const sqlite3_module *pModule; /* Module for cursor pVtabCursor */
i64 seqCount; /* Sequence counter */
@ -187,7 +188,9 @@ struct Mem {
#define MEM_RowSet 0x0020 /* Value is a RowSet object */
#define MEM_Frame 0x0040 /* Value is a VdbeFrame object */
#define MEM_Invalid 0x0080 /* Value is undefined */
#define MEM_TypeMask 0x00ff /* Mask of type bits */
#define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */
#define MEM_TypeMask 0x01ff /* Mask of type bits */
/* Whenever Mem contains a valid string or blob representation, one of
** the following flags must be set to determine the memory management
@ -273,6 +276,11 @@ struct Explain {
char zBase[100]; /* Initial space */
};
/* A bitfield type for use inside of structures. Always follow with :N where
** N is the number of bits.
*/
typedef unsigned bft; /* Bit Field Type */
/*
** An instance of the virtual machine. This structure contains the complete
** state of the virtual machine.
@ -314,15 +322,16 @@ struct Vdbe {
int pc; /* The program counter */
int rc; /* Value to return */
u8 errorAction; /* Recovery action to do in case of an error */
u8 explain; /* True if EXPLAIN present on SQL command */
u8 changeCntOn; /* True to update the change-counter */
u8 expired; /* True if the VM needs to be recompiled */
u8 runOnlyOnce; /* Automatically expire on reset */
u8 minWriteFileFormat; /* Minimum file format for writable database files */
u8 inVtabMethod; /* See comments above */
u8 usesStmtJournal; /* True if uses a statement journal */
u8 readOnly; /* True for read-only statements */
u8 isPrepareV2; /* True if prepared with prepare_v2() */
bft explain:2; /* True if EXPLAIN present on SQL command */
bft inVtabMethod:2; /* See comments above */
bft changeCntOn:1; /* True to update the change-counter */
bft expired:1; /* True if the VM needs to be recompiled */
bft runOnlyOnce:1; /* Automatically expire on reset */
bft usesStmtJournal:1; /* True if uses a statement journal */
bft readOnly:1; /* True for read-only statements */
bft isPrepareV2:1; /* True if prepared with prepare_v2() */
bft doingRerun:1; /* True if rerunning after an auto-reprepare */
int nChange; /* Number of db changes made since last reset */
yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */
yDbMask lockMask; /* Subset of btreeMask that requires a lock */

View File

@ -478,10 +478,12 @@ int sqlite3_step(sqlite3_stmt *pStmt){
}
db = v->db;
sqlite3_mutex_enter(db->mutex);
v->doingRerun = 0;
while( (rc = sqlite3Step(v))==SQLITE_SCHEMA
&& cnt++ < SQLITE_MAX_SCHEMA_RETRY
&& (rc2 = rc = sqlite3Reprepare(v))==SQLITE_OK ){
sqlite3_reset(pStmt);
v->doingRerun = 1;
assert( v->expired==0 );
}
if( rc2!=SQLITE_OK && ALWAYS(v->isPrepareV2) && ALWAYS(db->pErr) ){

View File

@ -53,7 +53,7 @@ Vdbe *sqlite3VdbeCreate(sqlite3 *db){
void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, int isPrepareV2){
assert( isPrepareV2==1 || isPrepareV2==0 );
if( p==0 ) return;
#ifdef SQLITE_OMIT_TRACE
#if defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_ENABLE_SQLLOG)
if( !isPrepareV2 ) return;
#endif
assert( p->zSql==0 );
@ -723,6 +723,7 @@ void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){
addr = p->nOp - 1;
}
pOp = &p->aOp[addr];
assert( pOp->p4type==P4_NOTUSED || pOp->p4type==P4_INT32 );
freeP4(db, pOp->p4type, pOp->p4.p);
pOp->p4.p = 0;
if( n==P4_INT32 ){
@ -745,10 +746,9 @@ void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){
u8 *aSortOrder;
memcpy((char*)pKeyInfo, zP4, nByte - nField);
aSortOrder = pKeyInfo->aSortOrder;
if( aSortOrder ){
pKeyInfo->aSortOrder = (unsigned char*)&pKeyInfo->aColl[nField];
memcpy(pKeyInfo->aSortOrder, aSortOrder, nField);
}
assert( aSortOrder!=0 );
pKeyInfo->aSortOrder = (unsigned char*)&pKeyInfo->aColl[nField];
memcpy(pKeyInfo->aSortOrder, aSortOrder, nField);
pOp->p4type = P4_KEYINFO;
}else{
p->db->mallocFailed = 1;
@ -861,26 +861,23 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
case P4_KEYINFO: {
int i, j;
KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
assert( pKeyInfo->aSortOrder!=0 );
sqlite3_snprintf(nTemp, zTemp, "keyinfo(%d", pKeyInfo->nField);
i = sqlite3Strlen30(zTemp);
for(j=0; j<pKeyInfo->nField; j++){
CollSeq *pColl = pKeyInfo->aColl[j];
if( pColl ){
int n = sqlite3Strlen30(pColl->zName);
if( i+n>nTemp-6 ){
memcpy(&zTemp[i],",...",4);
break;
}
zTemp[i++] = ',';
if( pKeyInfo->aSortOrder && pKeyInfo->aSortOrder[j] ){
zTemp[i++] = '-';
}
memcpy(&zTemp[i], pColl->zName,n+1);
i += n;
}else if( i+4<nTemp-6 ){
memcpy(&zTemp[i],",nil",4);
i += 4;
const char *zColl = pColl ? pColl->zName : "nil";
int n = sqlite3Strlen30(zColl);
if( i+n>nTemp-6 ){
memcpy(&zTemp[i],",...",4);
break;
}
zTemp[i++] = ',';
if( pKeyInfo->aSortOrder[j] ){
zTemp[i++] = '-';
}
memcpy(&zTemp[i], zColl, n+1);
i += n;
}
zTemp[i++] = ')';
zTemp[i] = 0;
@ -1770,7 +1767,9 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
if( sqlite3BtreeIsInTrans(pBt) ){
needXcommit = 1;
if( i!=1 ) nTrans++;
sqlite3BtreeEnter(pBt);
rc = sqlite3PagerExclusiveLock(sqlite3BtreePager(pBt));
sqlite3BtreeLeave(pBt);
}
}
if( rc!=SQLITE_OK ){
@ -2324,6 +2323,27 @@ int sqlite3VdbeTransferError(Vdbe *p){
return rc;
}
#ifdef SQLITE_ENABLE_SQLLOG
/*
** If an SQLITE_CONFIG_SQLLOG hook is registered and the VM has been run,
** invoke it.
*/
static void vdbeInvokeSqllog(Vdbe *v){
if( sqlite3GlobalConfig.xSqllog && v->rc==SQLITE_OK && v->zSql && v->pc>=0 ){
char *zExpanded = sqlite3VdbeExpandSql(v, v->zSql);
assert( v->db->init.busy==0 );
if( zExpanded ){
sqlite3GlobalConfig.xSqllog(
sqlite3GlobalConfig.pSqllogArg, v->db, zExpanded, 1
);
sqlite3DbFree(v->db, zExpanded);
}
}
}
#else
# define vdbeInvokeSqllog(x)
#endif
/*
** Clean up a VDBE after execution but do not delete the VDBE just yet.
** Write any error messages into *pzErrMsg. Return the result code.
@ -2351,6 +2371,7 @@ int sqlite3VdbeReset(Vdbe *p){
** instructions yet, leave the main database error information unchanged.
*/
if( p->pc>=0 ){
vdbeInvokeSqllog(p);
sqlite3VdbeTransferError(p);
sqlite3DbFree(db, p->zErrMsg);
p->zErrMsg = 0;
@ -2432,12 +2453,14 @@ void sqlite3VdbeDeleteAuxData(VdbeFunc *pVdbeFunc, int mask){
}
/*
** Free all memory associated with the Vdbe passed as the second argument.
** Free all memory associated with the Vdbe passed as the second argument,
** except for object itself, which is preserved.
**
** The difference between this function and sqlite3VdbeDelete() is that
** VdbeDelete() also unlinks the Vdbe from the list of VMs associated with
** the database connection.
** the database connection and frees the object itself.
*/
void sqlite3VdbeDeleteObject(sqlite3 *db, Vdbe *p){
void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
SubProgram *pSub, *pNext;
int i;
assert( p->db==0 || p->db==db );
@ -2455,10 +2478,9 @@ void sqlite3VdbeDeleteObject(sqlite3 *db, Vdbe *p){
sqlite3DbFree(db, p->zSql);
sqlite3DbFree(db, p->pFree);
#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
sqlite3DbFree(db, p->zExplain);
sqlite3_free(p->zExplain);
sqlite3DbFree(db, p->pExplain);
#endif
sqlite3DbFree(db, p);
}
/*
@ -2470,6 +2492,7 @@ void sqlite3VdbeDelete(Vdbe *p){
if( NEVER(p==0) ) return;
db = p->db;
assert( sqlite3_mutex_held(db->mutex) );
sqlite3VdbeClearObject(db, p);
if( p->pPrev ){
p->pPrev->pNext = p->pNext;
}else{
@ -2481,7 +2504,7 @@ void sqlite3VdbeDelete(Vdbe *p){
}
p->magic = VDBE_MAGIC_DEAD;
p->db = 0;
sqlite3VdbeDeleteObject(db, p);
sqlite3DbFree(db, p);
}
/*
@ -2583,9 +2606,6 @@ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){
# define MAX_6BYTE ((((i64)0x00008000)<<32)-1)
i64 i = pMem->u.i;
u64 u;
if( file_format>=4 && (i&1)==i ){
return 8+(u32)i;
}
if( i<0 ){
if( i<(-MAX_6BYTE) ) return 6;
/* Previous test prevents: u = -(-9223372036854775808) */
@ -2593,7 +2613,9 @@ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){
}else{
u = i;
}
if( u<=127 ) return 1;
if( u<=127 ){
return ((i&1)==i && file_format>=4) ? 8+(u32)u : 1;
}
if( u<=32767 ) return 2;
if( u<=8388607 ) return 3;
if( u<=2147483647 ) return 4;
@ -2878,6 +2900,7 @@ UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(
}
p->aMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))];
assert( pKeyInfo->aSortOrder!=0 );
p->pKeyInfo = pKeyInfo;
p->nField = pKeyInfo->nField + 1;
return p;
@ -2971,6 +2994,7 @@ int sqlite3VdbeRecordCompare(
idx1 = getVarint32(aKey1, szHdr1);
d1 = szHdr1;
nField = pKeyInfo->nField;
assert( pKeyInfo->aSortOrder!=0 );
while( idx1<szHdr1 && i<pPKey2->nField ){
u32 serial_type1;
@ -2990,7 +3014,7 @@ int sqlite3VdbeRecordCompare(
assert( mem1.zMalloc==0 ); /* See comment below */
/* Invert the result if we are using DESC sort order. */
if( pKeyInfo->aSortOrder && i<nField && pKeyInfo->aSortOrder[i] ){
if( i<nField && pKeyInfo->aSortOrder[i] ){
rc = -rc;
}

View File

@ -195,8 +195,11 @@ static int vdbeSorterIterRead(
int rc; /* sqlite3OsRead() return code */
/* Determine how many bytes of data to read. */
nRead = (int)(p->iEof - p->iReadOff);
if( nRead>p->nBuffer ) nRead = p->nBuffer;
if( (p->iEof - p->iReadOff) > (i64)p->nBuffer ){
nRead = p->nBuffer;
}else{
nRead = (int)(p->iEof - p->iReadOff);
}
assert( nRead>0 );
/* Read data from the file. Return early if an error occurs. */

View File

@ -264,7 +264,7 @@ void sqlite3VtabClear(sqlite3 *db, Table *p){
if( p->azModuleArg ){
int i;
for(i=0; i<p->nModuleArg; i++){
sqlite3DbFree(db, p->azModuleArg[i]);
if( i!=1 ) sqlite3DbFree(db, p->azModuleArg[i]);
}
sqlite3DbFree(db, p->azModuleArg);
}
@ -324,7 +324,7 @@ void sqlite3VtabBeginParse(
pTable->tabFlags |= TF_Virtual;
pTable->nModuleArg = 0;
addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName));
addModuleArgument(db, pTable, sqlite3DbStrDup(db, db->aDb[iDb].zName));
addModuleArgument(db, pTable, 0);
addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName));
pParse->sNameToken.n = (int)(&pModuleName->z[pModuleName->n] - pName1->z);
@ -481,6 +481,7 @@ static int vtabCallConstructor(
int nArg = pTab->nModuleArg;
char *zErr = 0;
char *zModuleName = sqlite3MPrintf(db, "%s", pTab->zName);
int iDb;
if( !zModuleName ){
return SQLITE_NOMEM;
@ -494,6 +495,9 @@ static int vtabCallConstructor(
pVTable->db = db;
pVTable->pMod = pMod;
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
pTab->azModuleArg[1] = db->aDb[iDb].zName;
/* Invoke the virtual table constructor */
assert( &db->pVtabCtx );
assert( xConstruct );
@ -528,7 +532,7 @@ static int vtabCallConstructor(
/* If everything went according to plan, link the new VTable structure
** into the linked list headed by pTab->pVTable. Then loop through the
** columns of the table to see if any of them contain the token "hidden".
** If so, set the Column.isHidden flag and remove the token from
** If so, set the Column COLFLAG_HIDDEN flag and remove the token from
** the type string. */
pVTable->pNext = pTab->pVTable;
pTab->pVTable = pVTable;
@ -559,7 +563,7 @@ static int vtabCallConstructor(
assert(zType[i-1]==' ');
zType[i-1] = '\0';
}
pTab->aCol[iCol].isHidden = 1;
pTab->aCol[iCol].colFlags |= COLFLAG_HIDDEN;
}
}
}

View File

@ -2518,7 +2518,7 @@ int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx){
assert( walFramePgno(pWal, iFrame)!=1 );
rc = xUndo(pUndoCtx, walFramePgno(pWal, iFrame));
}
walCleanupHash(pWal);
if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal);
}
assert( rc==SQLITE_OK );
return rc;
@ -2828,7 +2828,7 @@ int sqlite3WalFrames(
*/
if( isCommit && (sync_flags & WAL_SYNC_TRANSACTIONS)!=0 ){
if( pWal->padToSectorBoundary ){
int sectorSize = sqlite3OsSectorSize(pWal->pWalFd);
int sectorSize = sqlite3SectorSize(pWal->pWalFd);
w.iSyncPoint = ((iOffset+sectorSize-1)/sectorSize)*sectorSize;
while( iOffset<w.iSyncPoint ){
rc = walWriteOneFrame(&w, pLast, nTruncate, iOffset);

File diff suppressed because it is too large Load Diff

View File

@ -68,4 +68,164 @@ do_test aggnested-2.0 {
} {A,B,B 3 33 333 3333}
db2 close
##################### Test cases for ticket [bfbf38e5e9956ac69f] ############
#
# This first test case is the original problem report:
do_test aggnested-3.0 {
db eval {
CREATE TABLE AAA (
aaa_id INTEGER PRIMARY KEY AUTOINCREMENT
);
CREATE TABLE RRR (
rrr_id INTEGER PRIMARY KEY AUTOINCREMENT,
rrr_date INTEGER NOT NULL,
rrr_aaa INTEGER
);
CREATE TABLE TTT (
ttt_id INTEGER PRIMARY KEY AUTOINCREMENT,
target_aaa INTEGER NOT NULL,
source_aaa INTEGER NOT NULL
);
insert into AAA (aaa_id) values (2);
insert into TTT (ttt_id, target_aaa, source_aaa)
values (4469, 2, 2);
insert into TTT (ttt_id, target_aaa, source_aaa)
values (4476, 2, 1);
insert into RRR (rrr_id, rrr_date, rrr_aaa)
values (0, 0, NULL);
insert into RRR (rrr_id, rrr_date, rrr_aaa)
values (2, 4312, 2);
SELECT i.aaa_id,
(SELECT sum(CASE WHEN (t.source_aaa == i.aaa_id) THEN 1 ELSE 0 END)
FROM TTT t
) AS segfault
FROM
(SELECT curr.rrr_aaa as aaa_id
FROM RRR curr
-- you also can comment out the next line
-- it causes segfault to happen after one row is outputted
INNER JOIN AAA a ON (curr.rrr_aaa = aaa_id)
LEFT JOIN RRR r ON (r.rrr_id <> 0 AND r.rrr_date < curr.rrr_date)
GROUP BY curr.rrr_id
HAVING r.rrr_date IS NULL
) i;
}
} {2 1}
# Further variants of the test case, as found in the ticket
#
do_test aggnested-3.1 {
db eval {
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
CREATE TABLE t1 (
id1 INTEGER PRIMARY KEY AUTOINCREMENT,
value1 INTEGER
);
INSERT INTO t1 VALUES(4469,2),(4476,1);
CREATE TABLE t2 (
id2 INTEGER PRIMARY KEY AUTOINCREMENT,
value2 INTEGER
);
INSERT INTO t2 VALUES(0,1),(2,2);
SELECT
(SELECT sum(value2==xyz) FROM t2)
FROM
(SELECT curr.value1 as xyz
FROM t1 AS curr LEFT JOIN t1 AS other
GROUP BY curr.id1);
}
} {1 1}
do_test aggnested-3.2 {
db eval {
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
CREATE TABLE t1 (
id1 INTEGER,
value1 INTEGER,
x1 INTEGER
);
INSERT INTO t1 VALUES(4469,2,98),(4469,1,99),(4469,3,97);
CREATE TABLE t2 (
value2 INTEGER
);
INSERT INTO t2 VALUES(1);
SELECT
(SELECT sum(value2==xyz) FROM t2)
FROM
(SELECT value1 as xyz, max(x1) AS pqr
FROM t1
GROUP BY id1);
}
} {0}
do_test aggnested-3.3 {
db eval {
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
CREATE TABLE t1(id1, value1);
INSERT INTO t1 VALUES(4469,2),(4469,1);
CREATE TABLE t2 (value2);
INSERT INTO t2 VALUES(1);
SELECT (SELECT sum(value2=value1) FROM t2), max(value1)
FROM t1
GROUP BY id1;
}
} {0 2}
# A batch of queries all doing approximately the same operation involving
# two nested aggregate queries.
#
do_test aggnested-3.11 {
db eval {
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
CREATE TABLE t1(id1, value1);
INSERT INTO t1 VALUES(4469,12),(4469,11),(4470,34);
CREATE INDEX t1id1 ON t1(id1);
CREATE TABLE t2 (value2);
INSERT INTO t2 VALUES(12),(34),(34);
INSERT INTO t2 SELECT value2 FROM t2;
SELECT max(value1), (SELECT count(*) FROM t2 WHERE value2=max(value1))
FROM t1
GROUP BY id1;
}
} {12 2 34 4}
do_test aggnested-3.12 {
db eval {
SELECT max(value1), (SELECT count(*) FROM t2 WHERE value2=value1)
FROM t1
GROUP BY id1;
}
} {12 2 34 4}
do_test aggnested-3.13 {
db eval {
SELECT value1, (SELECT sum(value2=value1) FROM t2)
FROM t1;
}
} {12 2 11 0 34 4}
do_test aggnested-3.14 {
db eval {
SELECT value1, (SELECT sum(value2=value1) FROM t2)
FROM t1
WHERE value1 IN (SELECT max(value1) FROM t1 GROUP BY id1);
}
} {12 2 34 4}
do_test aggnested-3.15 {
# FIXME: If case 3.16 works, then this case really ought to work too...
catchsql {
SELECT max(value1), (SELECT sum(value2=max(value1)) FROM t2)
FROM t1
GROUP BY id1;
}
} {1 {misuse of aggregate function max()}}
do_test aggnested-3.16 {
db eval {
SELECT max(value1), (SELECT sum(value2=value1) FROM t2)
FROM t1
GROUP BY id1;
}
} {12 2 34 4}
finish_test

View File

@ -61,14 +61,14 @@ do_test analyze6-1.0 {
#
do_test analyze6-1.1 {
eqp {SELECT count(*) FROM ev, cat WHERE x=y}
} {0 0 1 {SCAN TABLE cat (~16 rows)} 0 1 0 {SEARCH TABLE ev USING COVERING INDEX evy (y=?) (~32 rows)}}
} {0 0 1 {SCAN TABLE cat USING COVERING INDEX catx (~16 rows)} 0 1 0 {SEARCH TABLE ev USING COVERING INDEX evy (y=?) (~32 rows)}}
# The same plan is chosen regardless of the order of the tables in the
# FROM clause.
#
do_test analyze6-1.2 {
eqp {SELECT count(*) FROM cat, ev WHERE x=y}
} {0 0 0 {SCAN TABLE cat (~16 rows)} 0 1 1 {SEARCH TABLE ev USING COVERING INDEX evy (y=?) (~32 rows)}}
} {0 0 0 {SCAN TABLE cat USING COVERING INDEX catx (~16 rows)} 0 1 1 {SEARCH TABLE ev USING COVERING INDEX evy (y=?) (~32 rows)}}
# Ticket [83ea97620bd3101645138b7b0e71c12c5498fe3d] 2011-03-30

View File

@ -114,7 +114,7 @@ foreach delete_order $delete_orders {
}
do_test autovacuum-1.$tn.($delete).3 {
execsql {
select a from av1
select a from av1 order by rowid
}
} $::tbl_data
}

View File

@ -213,7 +213,9 @@ unset ::incompatible
#
do_allbackcompat_test {
if {[code1 {sqlite3 -version}] >= "3.7.0"
&& [code1 {set ::sqlite_options(wal)}]
&& [code2 {sqlite3 -version}] >= "3.7.0"
&& [code2 {set ::sqlite_options(wal)}]
} {
do_test backcompat-2.1.1 { sql1 {

View File

@ -16,6 +16,7 @@
#
if {[file exists skip-big-file]} return
if {$tcl_platform(os)=="Darwin"} return
set testdir [file dirname $argv0]
source $testdir/tester.tcl

View File

@ -14,6 +14,7 @@
#
if {[file exists skip-big-file]} return
if {$tcl_platform(os)=="Darwin"} return
set testdir [file dirname $argv0]
source $testdir/tester.tcl

View File

@ -75,6 +75,7 @@ do_test collate1-1.1 {
}
} {{} 0x119 0x2D}
do_test collate1-1.2 {
breakpoint
execsql {
SELECT c2 FROM collate1t1 ORDER BY 1 COLLATE hex;
}

View File

@ -94,7 +94,7 @@ do_test collate4-1.1.5 {
cksort {SELECT b FROM collate4t1 ORDER BY b COLLATE TEXT}
} {{} A B a b nosort}
do_test collate4-1.1.6 {
cksort {SELECT b FROM collate4t1 ORDER BY b COLLATE NOCASE}
cksort {SELECT b FROM collate4t1 ORDER BY b COLLATE NOCASE, rowid}
} {{} a A b B sort}
do_test collate4-1.1.7 {
@ -171,13 +171,13 @@ do_test collate4-1.1.21 {
}
} {}
do_test collate4-1.1.22 {
cksort {SELECT a FROM collate4t4 ORDER BY a}
cksort {SELECT a FROM collate4t4 ORDER BY a, rowid}
} {{} a A b B sort}
do_test collate4-1.1.23 {
cksort {SELECT a FROM collate4t4 ORDER BY a COLLATE NOCASE}
cksort {SELECT a FROM collate4t4 ORDER BY a COLLATE NOCASE, rowid}
} {{} a A b B sort}
do_test collate4-1.1.24 {
cksort {SELECT a FROM collate4t4 ORDER BY a COLLATE TEXT}
cksort {SELECT a FROM collate4t4 ORDER BY a COLLATE TEXT, rowid}
} {{} A B a b nosort}
do_test collate4-1.1.25 {
cksort {SELECT b FROM collate4t4 ORDER BY b}
@ -222,7 +222,7 @@ do_test collate4-1.2.4 {
cksort {SELECT a FROM collate4t1 ORDER BY a, b}
} {{} A a B b nosort}
do_test collate4-1.2.5 {
cksort {SELECT a FROM collate4t1 ORDER BY a, b COLLATE nocase}
cksort {SELECT a FROM collate4t1 ORDER BY a, b COLLATE nocase, rowid}
} {{} a A b B sort}
do_test collate4-1.2.6 {
cksort {SELECT a FROM collate4t1 ORDER BY a, b COLLATE text}
@ -271,10 +271,10 @@ do_test collate4-1.2.14 {
}
} {}
do_test collate4-1.2.15 {
cksort {SELECT a FROM collate4t3 ORDER BY a}
cksort {SELECT a FROM collate4t3 ORDER BY a, rowid}
} {{} a A b B sort}
do_test collate4-1.2.16 {
cksort {SELECT a FROM collate4t3 ORDER BY a COLLATE nocase}
cksort {SELECT a FROM collate4t3 ORDER BY a COLLATE nocase, rowid}
} {{} a A b B sort}
do_test collate4-1.2.17 {
cksort {SELECT a FROM collate4t3 ORDER BY a COLLATE text}
@ -364,7 +364,8 @@ do_test collate4-2.1.4 {
CREATE INDEX collate4i1 ON collate4t1(a COLLATE TEXT);
}
count {
SELECT * FROM collate4t2, collate4t1 WHERE a = b;
SELECT * FROM collate4t2, collate4t1 WHERE a = b
ORDER BY collate4t2.rowid, collate4t1.rowid
}
} {A a A A 19}
do_test collate4-2.1.5 {
@ -375,7 +376,8 @@ do_test collate4-2.1.5 {
ifcapable subquery {
do_test collate4-2.1.6 {
count {
SELECT a FROM collate4t1 WHERE a IN (SELECT * FROM collate4t2);
SELECT a FROM collate4t1 WHERE a IN (SELECT * FROM collate4t2)
ORDER BY rowid
}
} {a A 10}
do_test collate4-2.1.7 {
@ -384,7 +386,8 @@ ifcapable subquery {
CREATE INDEX collate4i1 ON collate4t1(a);
}
count {
SELECT a FROM collate4t1 WHERE a IN (SELECT * FROM collate4t2);
SELECT a FROM collate4t1 WHERE a IN (SELECT * FROM collate4t2)
ORDER BY rowid
}
} {a A 6}
do_test collate4-2.1.8 {
@ -398,7 +401,7 @@ ifcapable subquery {
CREATE INDEX collate4i1 ON collate4t1(a COLLATE TEXT);
}
count {
SELECT a FROM collate4t1 WHERE a IN ('z', 'a');
SELECT a FROM collate4t1 WHERE a IN ('z', 'a') ORDER BY rowid;
}
} {a A 9}
}

View File

@ -221,7 +221,7 @@ do_test collate5-3.0 {
execsql {
SELECT a FROM collate5t1 UNION ALL SELECT a FROM collate5t2 ORDER BY 1;
}
} {a A a A b B b B n N}
} {/[aA] [aA] [aA] [aA] [bB] [bB] [bB] [bB] [nN] [nN]/}
do_test collate5-3.1 {
execsql {
SELECT a FROM collate5t2 UNION ALL SELECT a FROM collate5t1 ORDER BY 1;
@ -282,7 +282,7 @@ do_test collate5-4.2 {
execsql {
SELECT a, b, count(*) FROM collate5t1 GROUP BY a, b ORDER BY a, b;
}
} {A 1.0 2 b 2 1 B 3 1}
} {/[aA] 1(.0)? 2 [bB] 2 1 [bB] 3 1/}
do_test collate5-4.3 {
execsql {
DROP TABLE collate5t1;

View File

@ -107,12 +107,12 @@ proc restore_file {} {
do_test corruptD-1.1.1 {
incr_change_counter
hexio_write test.db [expr 1024+1] FFFF
catchsql { SELECT * FROM t1 }
catchsql { SELECT * FROM t1 ORDER BY rowid }
} {1 {database disk image is malformed}}
do_test corruptD-1.1.2 {
incr_change_counter
hexio_write test.db [expr 1024+1] [hexio_render_int32 1021]
catchsql { SELECT * FROM t1 }
catchsql { SELECT * FROM t1 ORDER BY rowid }
} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------

View File

@ -49,7 +49,7 @@ do_test corruptE-1.1 {
INSERT OR IGNORE INTO t1 SELECT x*17,y FROM t1;
INSERT OR IGNORE INTO t1 SELECT x*19,y FROM t1;
CREATE INDEX t1i1 ON t1(x);
CREATE TABLE t2 AS SELECT x,2 as y FROM t1 WHERE rowid%5!=0;
CREATE TABLE t2 AS SELECT x,2 as y FROM t1 WHERE rowid%5!=0 ORDER BY rowid;
COMMIT;
}
} {}

View File

@ -13,6 +13,7 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix crash7
ifcapable !crashtest {
finish_test
@ -79,4 +80,37 @@ foreach f [list test.db test.db-journal] {
}
}
db close
forcedelete test.db
sqlite3 db test.db
do_execsql_test 2.0 {
CREATE TABLE t1(a, b, UNIQUE(a, b));
INSERT INTO t1 VALUES(randomblob(100), randomblob(100));
INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1;
INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1;
INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1;
INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1;
INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1;
INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1;
INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1;
INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1;
INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1;
INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1;
INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1;
INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1;
INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1;
INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM t1;
DELETE FROM t1 WHERE rowid%2;
}
db_save_and_close
for {set i 0} {$i < 20} {incr i} {
db_restore_and_reopen
do_test 2.[expr $i+1].1 {
crashsql -file test.db -seed $i {VACUUM}
} {1 {child process exited abnormally}}
do_execsql_test 2.[expr $i+1].2 { PRAGMA integrity_check } {ok}
}
finish_test

View File

@ -85,10 +85,12 @@ do_test 2.3 { db_write db 1 } {0 4 0}
do_test 2.4 { db_write db 0 } {0 0 0}
do_test 2.5 { db_write db 1 } {0 0 0}
do_test 2.6 {
execsql { PRAGMA journal_mode = WAL }
db_write db 1
} {0 1 0}
ifcapable wal {
do_test 2.6 {
execsql { PRAGMA journal_mode = WAL }
db_write db 1
} {0 1 0}
}
do_test 2.7 {
execsql { INSERT INTO t1 VALUES(5, randomblob(600)) }
db_write db

View File

@ -168,17 +168,33 @@ foreach {tn sql temptables res} {
6 "b FROM t1" {hash} {b B}
7 "a FROM t1" {} {A a}
8 "b COLLATE nocase FROM t1" {} {b}
9 "b COLLATE nocase FROM t1 ORDER BY b COLLATE nocase" {} {B}
9 "b COLLATE nocase FROM t1 ORDER BY b COLLATE nocase" {} {b}
} {
do_execsql_test 2.$tn.1 "SELECT DISTINCT $sql" $res
do_temptables_test 2.$tn.2 "SELECT DISTINCT $sql" $temptables
}
do_execsql_test 2.A {
SELECT (SELECT DISTINCT o.a FROM t1 AS i) FROM t1 AS o;
SELECT (SELECT DISTINCT o.a FROM t1 AS i) FROM t1 AS o ORDER BY rowid;
} {a A a A}
do_test 3.0 {
db eval {
CREATE TABLE t3(a INTEGER, b INTEGER, c, UNIQUE(a,b));
INSERT INTO t3 VALUES
(null, null, 1),
(null, null, 2),
(null, 3, 4),
(null, 3, 5),
(6, null, 7),
(6, null, 8);
SELECT DISTINCT a, b FROM t3 ORDER BY +a, +b;
}
} {{} {} {} 3 6 {}}
do_test 3.1 {
regexp {OpenEphemeral} [db eval {
EXPLAIN SELECT DISTINCT a, b FROM t3 ORDER BY +a, +b;
}]
} {0}
finish_test

View File

@ -1591,7 +1591,7 @@ foreach {tn tbl res ac data} {
" $res
do_test e_createtable-4.17.$tn.3 { sqlite3_get_autocommit db } $ac
do_execsql_test 4.17.$tn.4 "SELECT * FROM $tbl" $data
do_execsql_test 4.17.$tn.4 "SELECT * FROM $tbl ORDER BY rowid" $data
}
catchsql COMMIT

View File

@ -2060,7 +2060,7 @@ do_test e_fkey-45.1 {
do_test e_fkey-45.2 {
execsql {
DELETE FROM pA WHERE rowid = 3;
SELECT quote(x) FROM pA;
SELECT quote(x) FROM pA ORDER BY rowid;
}
} {X'0000' X'9999' X'1234'}
do_test e_fkey-45.3 {
@ -2069,7 +2069,7 @@ do_test e_fkey-45.3 {
do_test e_fkey-45.4 {
execsql {
UPDATE pA SET x = X'8765' WHERE rowid = 4;
SELECT quote(x) FROM pA;
SELECT quote(x) FROM pA ORDER BY rowid;
}
} {X'0000' X'9999' X'8765'}
do_test e_fkey-45.5 {
@ -2325,7 +2325,7 @@ do_test e_fkey-51.1 {
do_test e_fkey-51.2 {
execsql {
UPDATE parent SET x = 22;
SELECT * FROM parent ; SELECT 'xxx' ; SELECT a FROM child;
SELECT * FROM parent ORDER BY rowid; SELECT 'xxx' ; SELECT a FROM child;
}
} {22 21 23 xxx 22}
do_test e_fkey-51.3 {
@ -2335,7 +2335,7 @@ do_test e_fkey-51.3 {
INSERT INTO parent VALUES(-1);
INSERT INTO child VALUES(-1);
UPDATE parent SET x = 22;
SELECT * FROM parent ; SELECT 'xxx' ; SELECT a FROM child;
SELECT * FROM parent ORDER BY rowid; SELECT 'xxx' ; SELECT a FROM child;
}
} {22 23 21 xxx 23}

View File

@ -141,8 +141,8 @@ do_insert_tests e_insert-0 {
delete_all_data
# EVIDENCE-OF: R-20288-20462 The first form (with the "VALUES" keyword)
# creates a single new row in an existing table.
# EVIDENCE-OF: R-21490-41092 The first form (with the "VALUES" keyword)
# creates one or more new rows in an existing table.
#
do_insert_tests e_insert-1.1 {
0 "SELECT count(*) FROM a2" {0}
@ -152,11 +152,14 @@ do_insert_tests e_insert-1.1 {
2a "INSERT INTO a2(a, b) VALUES(1, 2)" {}
2b "SELECT count(*) FROM a2" {2}
3a "INSERT INTO a2(a) VALUES(3),(4)" {}
3b "SELECT count(*) FROM a2" {4}
}
# EVIDENCE-OF: R-36040-20870 If no column-list is specified then the
# number of values must be the same as the number of columns in the
# table.
# EVIDENCE-OF: R-53616-44976 If no column-list is specified then the
# number of values inserted into each row must be the same as the number
# of columns in the table.
#
# A test in the block above verifies that if the VALUES list has the
# correct number of columns (for table a2, 3 columns) works. So these
@ -171,9 +174,10 @@ do_insert_tests e_insert-1.2 -error {
4 "INSERT INTO a2 VALUES(1,2,3,4,5)" {a2 3 5}
}
# EVIDENCE-OF: R-04006-57648 In this case the result of evaluating the
# left-most expression in the VALUES list is inserted into the left-most
# column of the new row, and so on.
# EVIDENCE-OF: R-34231-22576 In this case the result of evaluating the
# left-most expression in each term of the VALUES list is inserted into
# the left-most column of the each new row, and forth for each
# subsequent expression.
#
delete_all_data
do_insert_tests e_insert-1.3 {
@ -187,8 +191,9 @@ do_insert_tests e_insert-1.3 {
3b "SELECT * FROM a2 WHERE oid=last_insert_rowid()" {2 x y}
}
# EVIDENCE-OF: R-62524-00361 If a column-list is specified, then the
# number of values must match the number of specified columns.
# EVIDENCE-OF: R-44710-64652 If a column-list is specified, then the
# number of values in each term of the VALUS list must match the number
# of specified columns.
#
do_insert_tests e_insert-1.4 -error {
%d values for %d columns

View File

@ -1023,10 +1023,10 @@ do_execsql_test e_select-4.9.0 {
#
do_select_tests e_select-4.9 {
1 "SELECT group_concat(one), two FROM b1 GROUP BY two" {
4,5 f 1 o 7,6 s 3,2 t
/#,# f 1 o #,# s #,# t/
}
2 "SELECT group_concat(one), sum(one) FROM b1 GROUP BY (one>4)" {
1,4,3,2 10 5,7,6 18
1,2,3,4 10 5,6,7 18
}
3 "SELECT group_concat(one) FROM b1 GROUP BY (two>'o'), one%2" {
4 1,5 2,6 3,7
@ -1040,7 +1040,7 @@ do_select_tests e_select-4.9 {
# values are considered equal.
#
do_select_tests e_select-4.10 {
1 "SELECT group_concat(y) FROM b2 GROUP BY x" {0,1 3 2,4}
1 "SELECT group_concat(y) FROM b2 GROUP BY x" {/#,# 3 #,#/}
2 "SELECT count(*) FROM b2 GROUP BY CASE WHEN y<4 THEN NULL ELSE 0 END" {4 1}
}
@ -1745,12 +1745,12 @@ do_select_tests e_select-8.4 {
1 2 7 1 2 8 1 4 93 1 5 -1
}
8 "SELECT z, x FROM d1 ORDER BY 2" {
3 1 8 1 7 1 -20 1
93 1 -1 1 -1 2 93 2
/# 1 # 1 # 1 # 1
# 1 # 1 # 2 # 2/
}
9 "SELECT z, x FROM d1 ORDER BY 1" {
-20 1 -1 2 -1 1 3 1
7 1 8 1 93 2 93 1
/-20 1 -1 # -1 # 3 1
7 1 8 1 93 # 93 #/
}
}
@ -1766,10 +1766,10 @@ do_select_tests e_select-8.5 {
94 94 9 8 4 0 0 -19
}
3 "SELECT z AS x, x AS z FROM d1 ORDER BY z" {
3 1 8 1 7 1 -20 1 93 1 -1 1 -1 2 93 2
/# 1 # 1 # 1 # 1 # 1 # 1 # 2 # 2/
}
4 "SELECT z AS x, x AS z FROM d1 ORDER BY x" {
-20 1 -1 2 -1 1 3 1 7 1 8 1 93 2 93 1
/-20 1 -1 # -1 # 3 1 7 1 8 1 93 # 93 #/
}
}

View File

@ -261,9 +261,9 @@ foreach {tn uri error} "
}
# EVIDENCE-OF: R-09651-31805 If "ro" is specified, then the database is
# EVIDENCE-OF: R-43036-46756 If "ro" is specified, then the database is
# opened for read-only access, just as if the SQLITE_OPEN_READONLY flag
# had been set in the third argument to sqlite3_prepare_v2().
# had been set in the third argument to sqlite3_open_v2().
#
# EVIDENCE-OF: R-40137-26050 If the mode option is set to "rw", then the
# database is opened for read-write (but not create) access, as if

View File

@ -62,7 +62,7 @@ do_eqp_test 1.3 {
do_eqp_test 1.4 {
SELECT a FROM t1 ORDER BY +a
} {
0 0 0 {SCAN TABLE t1 (~1000000 rows)}
0 0 0 {SCAN TABLE t1 USING COVERING INDEX i1 (~1000000 rows)}
0 0 0 {USE TEMP B-TREE FOR ORDER BY}
}
do_eqp_test 1.5 {
@ -166,7 +166,7 @@ det 2.3.2 "SELECT min(x) FROM t2" {
0 0 0 {SEARCH TABLE t2 USING COVERING INDEX t2i1 (~1 rows)}
}
det 2.3.3 "SELECT min(x), max(x) FROM t2" {
0 0 0 {SCAN TABLE t2 (~1000000 rows)}
0 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1 (~1000000 rows)}
}
det 2.4.1 "SELECT * FROM t1 WHERE rowid=?" {
@ -339,7 +339,7 @@ do_eqp_test 4.3.1 {
SELECT x FROM t1 UNION SELECT x FROM t2
} {
1 0 0 {SCAN TABLE t1 (~1000000 rows)}
2 0 0 {SCAN TABLE t2 (~1000000 rows)}
2 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1 (~1000000 rows)}
0 0 0 {COMPOUND SUBQUERIES 1 AND 2 USING TEMP B-TREE (UNION)}
}
@ -347,7 +347,7 @@ do_eqp_test 4.3.2 {
SELECT x FROM t1 UNION SELECT x FROM t2 UNION SELECT x FROM t1
} {
2 0 0 {SCAN TABLE t1 (~1000000 rows)}
3 0 0 {SCAN TABLE t2 (~1000000 rows)}
3 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1 (~1000000 rows)}
1 0 0 {COMPOUND SUBQUERIES 2 AND 3 USING TEMP B-TREE (UNION)}
4 0 0 {SCAN TABLE t1 (~1000000 rows)}
0 0 0 {COMPOUND SUBQUERIES 1 AND 4 USING TEMP B-TREE (UNION)}
@ -447,7 +447,7 @@ det 5.8.1 "SELECT c, d FROM t2 ORDER BY c" {
det 5.9 {
SELECT (SELECT b FROM t1 WHERE a=0), (SELECT a FROM t1 WHERE b=t2.c) FROM t2
} {
0 0 0 {SCAN TABLE t2 (~1000000 rows)}
0 0 0 {SCAN TABLE t2 USING COVERING INDEX i4 (~1000000 rows)}
0 0 0 {EXECUTE SCALAR SUBQUERY 1}
1 0 0 {SEARCH TABLE t1 USING COVERING INDEX i2 (a=?) (~10 rows)}
0 0 0 {EXECUTE CORRELATED SCALAR SUBQUERY 2}
@ -471,7 +471,7 @@ det 5.10 {
# (c=?) (~10 rows) 0|1|1|SCAN TABLE t1 (~1000000 rows)
det 5.11 "SELECT * FROM (SELECT * FROM t2 WHERE c=1), t1" {
0 0 0 {SEARCH TABLE t2 USING INDEX i4 (c=?) (~10 rows)}
0 1 1 {SCAN TABLE t1 (~1000000 rows)}
0 1 1 {SCAN TABLE t1 USING COVERING INDEX i2 (~1000000 rows)}
}
# EVIDENCE-OF: R-40701-42164 sqlite> EXPLAIN QUERY PLAN SELECT a FROM
@ -479,8 +479,8 @@ det 5.11 "SELECT * FROM (SELECT * FROM t2 WHERE c=1), t1" {
# 2|0|0|SCAN TABLE t2 (~1000000 rows) 0|0|0|COMPOUND SUBQUERIES 1 AND 2
# USING TEMP B-TREE (UNION)
det 5.12 "SELECT a FROM t1 UNION SELECT c FROM t2" {
1 0 0 {SCAN TABLE t1 (~1000000 rows)}
2 0 0 {SCAN TABLE t2 (~1000000 rows)}
1 0 0 {SCAN TABLE t1 USING COVERING INDEX i1 (~1000000 rows)}
2 0 0 {SCAN TABLE t2 USING COVERING INDEX i4 (~1000000 rows)}
0 0 0 {COMPOUND SUBQUERIES 1 AND 2 USING TEMP B-TREE (UNION)}
}

View File

@ -36,6 +36,12 @@ do_test filectrl-1.5 {
sqlite3 db test_control_lockproxy.db
file_control_lockproxy_test db [get_pwd]
} {}
do_test filectrl-1.6 {
sqlite3 db test.db
set fn [file_control_tempfilename db]
puts -nonewline \[$fn\]
set fn
} {/etilqs_/}
db close
forcedelete .test_control_lockproxy.db-conch test.proxy
finish_test

View File

@ -136,4 +136,46 @@ do_execsql_test 2.2.2 { COMMIT }
do_execsql_test 2.2.3 { SELECT * FROM t1 } {{a b c} {a b c}}
fts3_integrity 2.2.4 db t1
do_execsql_test 3.1 {
CREATE VIRTUAL TABLE t3 USING fts4;
REPLACE INTO t3(docid, content) VALUES (1, 'one two');
SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'one'
} {X'0100000002000000'}
do_execsql_test 3.2 {
REPLACE INTO t3(docid, content) VALUES (2, 'one two three four');
SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'four'
} {X'0200000003000000'}
do_execsql_test 3.3 {
REPLACE INTO t3(docid, content) VALUES (1, 'one two three four five six');
SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'six'
} {X'0200000005000000'}
do_execsql_test 3.4 {
UPDATE OR REPLACE t3 SET docid = 2 WHERE docid=1;
SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'six'
} {X'0100000006000000'}
do_execsql_test 3.5 {
UPDATE OR REPLACE t3 SET docid = 3 WHERE docid=2;
SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'six'
} {X'0100000006000000'}
do_execsql_test 3.6 {
REPLACE INTO t3(docid, content) VALUES (3, 'one two');
SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'one'
} {X'0100000002000000'}
do_execsql_test 3.7 {
REPLACE INTO t3(docid, content) VALUES (NULL, 'one two three four');
REPLACE INTO t3(docid, content) VALUES (NULL, 'one two three four five six');
SELECT docid FROM t3;
} {3 4 5}
do_execsql_test 3.8 {
UPDATE OR REPLACE t3 SET docid = 5, content='three four' WHERE docid = 4;
SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'one'
} {X'0200000002000000'}
finish_test

View File

@ -407,5 +407,24 @@ do_catchsql_test 8.5.3.2 {
SELECT mit(matchinfo(t11, 'nxa')) FROM t11 WHERE t11 MATCH 'a*'
} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
do_execsql_test 8.1 {
CREATE VIRTUAL TABLE t12 USING fts4;
INSERT INTO t12 VALUES('a b c d');
SELECT mit(matchinfo(t12, 'x')) FROM t12 WHERE t12 MATCH 'a NEAR/1 d OR a';
} {{0 0 0 0 0 0 1 1 1}}
do_execsql_test 8.2 {
INSERT INTO t12 VALUES('a d c d');
SELECT mit(matchinfo(t12, 'x')) FROM t12 WHERE t12 MATCH 'a NEAR/1 d OR a';
} {
{0 1 1 0 1 1 1 2 2} {1 1 1 1 1 1 1 2 2}
}
do_execsql_test 8.3 {
INSERT INTO t12 VALUES('a d d a');
SELECT mit(matchinfo(t12, 'x')) FROM t12 WHERE t12 MATCH 'a NEAR/1 d OR a';
} {
{0 3 2 0 3 2 1 4 3} {1 3 2 1 3 2 1 4 3} {2 3 2 2 3 2 2 4 3}
}
finish_test

View File

@ -1864,5 +1864,3 @@ do_execsql_test 10.3 {
} {1 21 41 61 81}
finish_test

View File

@ -437,7 +437,7 @@ if {[permutation] != "memsubsys1"} {
} {}
do_test incrblob-6.2 {
execsql {
SELECT rowid FROM blobs
SELECT rowid FROM blobs ORDER BY rowid
}
} {1 2 3}
do_test incrblob-6.3 {

View File

@ -166,6 +166,8 @@ for {set i 1} {$i<$max_count-5} {incr i 1} {
} {1 interrupted}
}
if {0} { # This doesn't work anymore since the collation factor is
# no longer called during schema parsing.
# Interrupt during parsing
#
do_test interrupt-5.1 {
@ -179,5 +181,5 @@ do_test interrupt-5.1 {
CREATE INDEX fake ON fake1(a COLLATE fake_collation, b, c DESC);
}
} {1 interrupt}
}
finish_test

Some files were not shown because too many files have changed in this diff Show More