Snapshot of upstream SQLite 3.7.15.2
This commit is contained in:
parent
801e036cd8
commit
7d88842525
|
@ -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
|
||||
|
|
85
Makefile.msc
85
Makefile.msc
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 ){
|
||||
|
|
8
main.mk
8
main.mk
|
@ -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
299
manifest
|
@ -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
|
||||
|
|
|
@ -1 +1 @@
|
|||
091570e46d04e84b67228e0bdbcd6e1fb60c6bdb
|
||||
c0e09560d26f0a6456be9dd3447f5311eb4f238f
|
||||
|
|
138
publish.sh
138
publish.sh
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
19
src/backup.c
19
src/backup.c
|
@ -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
|
||||
));
|
||||
|
|
36
src/btree.c
36
src/btree.c
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
72
src/build.c
72
src/build.c
|
@ -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 */
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
236
src/expr.c
236
src/expr.c
|
@ -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().
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
120
src/func.c
120
src/func.c
|
@ -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 ),
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
144
src/insert.c
144
src/insert.c
|
@ -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 */
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
52
src/main.c
52
src/main.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
149
src/os_unix.c
149
src/os_unix.c
|
@ -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 ){
|
||||
|
|
336
src/os_win.c
336
src/os_win.c
|
@ -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;
|
||||
}
|
||||
|
|
49
src/pager.c
49
src/pager.c
|
@ -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 */
|
||||
|
|
14
src/pager.h
14
src/pager.h
|
@ -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);
|
||||
|
|
14
src/parse.y
14
src/parse.y
|
@ -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");
|
||||
|
|
25
src/pragma.c
25
src/pragma.c
|
@ -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 ){
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
266
src/select.c
266
src/select.c
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
150
src/shell.c
150
src/shell.c
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
243
src/sqliteInt.h
243
src/sqliteInt.h
|
@ -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 *);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 ){
|
||||
|
|
47
src/test1.c
47
src/test1.c
|
@ -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 },
|
||||
|
||||
|
|
23
src/test6.c
23
src/test6.c
|
@ -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;
|
||||
|
|
|
@ -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 ){
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
16
src/utf.c
16
src/utf.c
|
@ -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;
|
||||
|
|
|
@ -85,6 +85,7 @@ void sqlite3Vacuum(Parse *pParse){
|
|||
Vdbe *v = sqlite3GetVdbe(pParse);
|
||||
if( v ){
|
||||
sqlite3VdbeAddOp2(v, OP_Vacuum, 0, 0);
|
||||
sqlite3VdbeUsesBtree(v, 0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
112
src/vdbe.c
112
src/vdbe.c
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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) ){
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
12
src/vtab.c
12
src/vtab.c
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
1281
src/where.c
1281
src/where.c
File diff suppressed because it is too large
Load Diff
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
} {}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 #/
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -1864,5 +1864,3 @@ do_execsql_test 10.3 {
|
|||
} {1 21 41 61 81}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue