Compare commits
115 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b092b0337c | |||
| 1a51337af8 | |||
| 36b948f88a | |||
| c049057242 | |||
| c843016e36 | |||
| b3df0c675c | |||
| e9c5f97683 | |||
| 929b923388 | |||
| 5789d1a46f | |||
| abf582509d | |||
| 6296a2ab4b | |||
| f2db338926 | |||
| d154a43ed9 | |||
| 6c98415a1c | |||
| 6a412b8be9 | |||
| f3cdcdccbe | |||
| b4a91a9a88 | |||
| 5824d44bab | |||
| 0bdef92dc2 | |||
| d68d1f4863 | |||
| bd6789e761 | |||
| 5fb71254e4 | |||
| 06d83377e1 | |||
| 42c0a2b2f3 | |||
| 4d35c41f48 | |||
| 995f8b9d73 | |||
| a30c158c38 | |||
| b3f3d64b4b | |||
| 375d9b1f1c | |||
| 7c84c02ce3 | |||
| f332071b7f | |||
| f89aa47f80 | |||
| be5248f084 | |||
| 0ee751fb67 | |||
| 9a9705de5c | |||
| 9f18f7434e | |||
| 048810b63b | |||
| 61a0d6bc55 | |||
| 0ef84d0e5e | |||
| 8ea5eca183 | |||
| f1e1736fe1 | |||
| e1a71a582f | |||
| 875bafa17a | |||
| 1cbb7fa95c | |||
| 41148f83c4 | |||
| 00808deed0 | |||
| 38f2024062 | |||
| 0ba51089c8 | |||
| 3fb2cc1173 | |||
| 318d38cf7e | |||
| 1cb50c880e | |||
| dfb5e1cbc6 | |||
| 464083544e | |||
| be360e1ed1 | |||
| 4b79bde7a2 | |||
| 7c052da54d | |||
| 3c9a073723 | |||
| b6b676ea7c | |||
| 60f4e0918d | |||
| 0f517ea8d4 | |||
| 76f6a130a9 | |||
| 9985dabbac | |||
| 4a74d076e3 | |||
| 4eed05347c | |||
| cef2584335 | |||
| f34e9aabd8 | |||
| b496a8f547 | |||
| 19b887e4ec | |||
| 0311b622c4 | |||
| f659cf48e8 | |||
| 542a176d5e | |||
| 992590be1c | |||
| 7520996965 | |||
| 5f1d2fa4d2 | |||
| 8e18922f12 | |||
| 33c59ecafb | |||
| 1c89a7710e | |||
| d0c7305313 | |||
| 88eb7fa328 | |||
| a21f78b93f | |||
| 6bbe3dfaf2 | |||
| 816070cf5c | |||
| 7088d50109 | |||
| ea8562edce | |||
| 935f2e7074 | |||
| c982844097 | |||
| 1586699cfc | |||
| 7693c42f1a | |||
| 7b4da150da | |||
| 97ab32bcd3 | |||
| c50c8f4043 | |||
| d99d28361e | |||
| b8289a8b00 | |||
| 268e72f936 | |||
| 50be9c4b28 | |||
| e318a7f84c | |||
| a33b68364b | |||
| f3151f0a0d | |||
| a4bb7764fe | |||
| ab4e7f3337 | |||
| 6dc4148547 | |||
| b10f22a141 | |||
| a276e3fd4d | |||
| 59ac655d02 | |||
| e06874eaa1 | |||
| 9569f60e18 | |||
| 6736618a8f | |||
| 772460fd4c | |||
| b073771cdf | |||
| 67731a97a2 | |||
| 0d2e2f2b10 | |||
| 5b1c07e7fb | |||
| 0cbcffa75d | |||
| 02b0e267fb | |||
| fb383e9229 |
+16
-5
@@ -539,6 +539,9 @@ sqlite3$(TEXE): $(TOP)/src/shell.c libsqlite3.la sqlite3.h
|
||||
sqldiff$(EXE): $(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h
|
||||
$(LTLINK) -o $@ $(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS)
|
||||
|
||||
fuzzershell$(EXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h
|
||||
$(LTLINK) -o $@ $(TOP)/tool/fuzzershell.c sqlite3.c $(TLIBS)
|
||||
|
||||
mptester$(EXE): sqlite3.c $(TOP)/mptest/mptest.c
|
||||
$(LTLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \
|
||||
$(TLIBS) -rpath "$(libdir)"
|
||||
@@ -948,34 +951,42 @@ testfixture$(TEXE): $(TESTFIXTURE_SRC)
|
||||
-o $@ $(TESTFIXTURE_SRC) $(LIBTCL) $(TLIBS)
|
||||
|
||||
# A very detailed test running most or all test cases
|
||||
fulltest: testfixture$(TEXE) sqlite3$(TEXE)
|
||||
fulltest: testfixture$(TEXE) sqlite3$(TEXE) fuzztest
|
||||
./testfixture$(TEXE) $(TOP)/test/all.test
|
||||
|
||||
# Really really long testing
|
||||
soaktest: testfixture$(TEXE) sqlite3$(TEXE)
|
||||
soaktest: testfixture$(TEXE) sqlite3$(TEXE) fuzzoomtest
|
||||
./testfixture$(TEXE) $(TOP)/test/all.test -soak=1
|
||||
|
||||
# Do extra testing but not aeverything.
|
||||
fulltestonly: testfixture$(TEXE) sqlite3$(TEXE)
|
||||
./testfixture$(TEXE) $(TOP)/test/full.test
|
||||
|
||||
# Fuzz testing
|
||||
fuzztest: fuzzershell$(TEXE)
|
||||
./fuzzershell$(TEXE) $(TOP)/test/fuzzdata1.txt $(TOP)/test/fuzzdata2.txt
|
||||
|
||||
fuzzoomtest: fuzzershell$(TEXE)
|
||||
./fuzzershell$(TEXE) -f $(TOP)/test/fuzzdata1.txt --oom
|
||||
|
||||
# This is the common case. Run many tests but not those that take
|
||||
# a really long time.
|
||||
#
|
||||
test: testfixture$(TEXE) sqlite3$(TEXE)
|
||||
test: testfixture$(TEXE) sqlite3$(TEXE) fuzztest
|
||||
./testfixture$(TEXE) $(TOP)/test/veryquick.test
|
||||
|
||||
# Run a test using valgrind. This can take a really long time
|
||||
# because valgrind is so much slower than a native machine.
|
||||
#
|
||||
valgrindtest: testfixture$(TEXE) sqlite3$(TEXE)
|
||||
valgrindtest: testfixture$(TEXE) sqlite3$(TEXE) fuzzershell$(TEXE)
|
||||
valgrind -v ./fuzzershell$(TEXE) -f $(TOP)/test/fuzzdata1.txt
|
||||
OMIT_MISUSE=1 valgrind -v ./testfixture$(TEXE) $(TOP)/test/permutations.test valgrind
|
||||
|
||||
# A very fast test that checks basic sanity. The name comes from
|
||||
# the 60s-era electronics testing: "Turn it on and see if smoke
|
||||
# comes out."
|
||||
#
|
||||
smoketest: testfixture$(TEXE)
|
||||
smoketest: testfixture$(TEXE) fuzzershell$(TEXE)
|
||||
./testfixture$(TEXE) $(TOP)/test/main.test
|
||||
|
||||
sqlite3_analyzer.c: sqlite3.c $(TOP)/src/test_stat.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl
|
||||
|
||||
+47
-8
@@ -115,6 +115,14 @@ USE_RC = 1
|
||||
FOR_WINRT = 0
|
||||
!ENDIF
|
||||
|
||||
# Set this non-0 to compile binaries suitable for the UAP environment.
|
||||
# This setting does not apply to any binaries that require Tcl to operate
|
||||
# properly (i.e. the text fixture, etc).
|
||||
#
|
||||
!IFNDEF FOR_UAP
|
||||
FOR_UAP = 0
|
||||
!ENDIF
|
||||
|
||||
# Set this non-0 to skip attempting to look for and/or link with the Tcl
|
||||
# runtime library.
|
||||
#
|
||||
@@ -140,6 +148,13 @@ MEMDEBUG = 0
|
||||
WIN32HEAP = 0
|
||||
!ENDIF
|
||||
|
||||
# Set this to non-0 to enable OSTRACE() macros, which can be useful when
|
||||
# debugging.
|
||||
#
|
||||
!IFNDEF OSTRACE
|
||||
OSTRACE = 0
|
||||
!ENDIF
|
||||
|
||||
# Set this to one of the following values to enable various debugging
|
||||
# features. Each level includes the debugging options from the previous
|
||||
# levels. Currently, the recognized values for DEBUG are:
|
||||
@@ -288,6 +303,11 @@ BCC = $(BCC) -FAcs
|
||||
#
|
||||
!IF $(USE_NATIVE_LIBPATHS)!=0
|
||||
NLTLIBPATHS = "/LIBPATH:$(NCRTLIBPATH)" "/LIBPATH:$(NSDKLIBPATH)"
|
||||
|
||||
!IFDEF NUCRTLIBPATH
|
||||
NUCRTLIBPATH = $(NUCRTLIBPATH:\\=\)
|
||||
NLTLIBPATHS = $(NLTLIBPATHS) "/LIBPATH:$(NUCRTLIBPATH)"
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
# C compiler and options for use in building executables that
|
||||
@@ -481,9 +501,9 @@ TCC = $(TCC) -DSQLITE_DEBUG
|
||||
RCC = $(RCC) -DSQLITE_DEBUG
|
||||
!ENDIF
|
||||
|
||||
!IF $(DEBUG)>4
|
||||
TCC = $(TCC) -DSQLITE_DEBUG_OS_TRACE=1
|
||||
RCC = $(RCC) -DSQLITE_DEBUG_OS_TRACE=1
|
||||
!IF $(DEBUG)>4 || $(OSTRACE)!=0
|
||||
TCC = $(TCC) -DSQLITE_FORCE_OS_TRACE=1 -DSQLITE_DEBUG_OS_TRACE=1
|
||||
RCC = $(RCC) -DSQLITE_FORCE_OS_TRACE=1 -DSQLITE_DEBUG_OS_TRACE=1
|
||||
!ENDIF
|
||||
|
||||
!IF $(DEBUG)>5
|
||||
@@ -708,7 +728,7 @@ LTLIBOPTS = /NOLOGO
|
||||
#
|
||||
!IF $(FOR_WINRT)!=0
|
||||
LTLINKOPTS = $(LTLINKOPTS) /APPCONTAINER
|
||||
!IF "$(VISUALSTUDIOVERSION)"=="12.0"
|
||||
!IF "$(VISUALSTUDIOVERSION)"=="12.0" || "$(VISUALSTUDIOVERSION)"=="14.0"
|
||||
!IFNDEF STORELIBPATH
|
||||
!IF "$(PLATFORM)"=="x86"
|
||||
STORELIBPATH = $(CRTLIBPATH)\store
|
||||
@@ -752,6 +772,16 @@ LTLINKOPTS = $(LTLINKOPTS) WindowsPhoneCore.lib RuntimeObject.lib PhoneAppModelH
|
||||
LTLINKOPTS = $(LTLINKOPTS) /NODEFAULTLIB:kernel32.lib /NODEFAULTLIB:ole32.lib
|
||||
!ENDIF
|
||||
|
||||
# When compiling for UAP, some extra linker options are also required.
|
||||
#
|
||||
!IF $(FOR_UAP)!=0
|
||||
LTLINKOPTS = $(LTLINKOPTS) /DYNAMICBASE /NODEFAULTLIB:kernel32.lib
|
||||
LTLINKOPTS = $(LTLINKOPTS) mincore.lib
|
||||
!IFDEF PSDKLIBPATH
|
||||
LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(PSDKLIBPATH)"
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
# If either debugging or symbols are enabled, enable PDBs.
|
||||
#
|
||||
!IF $(DEBUG)>1 || $(SYMBOLS)!=0
|
||||
@@ -1159,6 +1189,9 @@ sqlite3.exe: $(TOP)\src\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) sqlite3.h
|
||||
sqldiff.exe: $(TOP)\tool\sqldiff.c sqlite3.c sqlite3.h
|
||||
$(LTLINK) $(TOP)\tool\sqldiff.c sqlite3.c
|
||||
|
||||
fuzzershell.exe: $(TOP)\tool\fuzzershell.c sqlite3.c sqlite3.h
|
||||
$(LTLINK) $(TOP)\tool\fuzzershell.c sqlite3.c
|
||||
|
||||
mptester.exe: $(TOP)\mptest\mptest.c $(SHELL_CORE_DEP) $(LIBRESOBJS) sqlite3.h
|
||||
$(LTLINK) $(SHELL_COMPILE_OPTS) $(TOP)\mptest\mptest.c \
|
||||
/link $(LTLINKOPTS) $(LTLIBPATHS) $(SHELL_LINK_OPTS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
|
||||
@@ -1598,19 +1631,25 @@ testfixture.exe: $(TESTFIXTURE_SRC) $(LIBRESOBJS) $(HDR)
|
||||
extensiontest: testfixture.exe testloadext.dll
|
||||
.\testfixture.exe $(TOP)\test\loadext.test
|
||||
|
||||
fulltest: testfixture.exe sqlite3.exe
|
||||
fulltest: testfixture.exe sqlite3.exe fuzztest
|
||||
.\testfixture.exe $(TOP)\test\all.test
|
||||
|
||||
soaktest: testfixture.exe sqlite3.exe
|
||||
soaktest: testfixture.exe sqlite3.exe fuzzoomtest
|
||||
.\testfixture.exe $(TOP)\test\all.test -soak=1
|
||||
|
||||
fulltestonly: testfixture.exe sqlite3.exe
|
||||
fulltestonly: testfixture.exe sqlite3.exe fuzztest
|
||||
.\testfixture.exe $(TOP)\test\full.test
|
||||
|
||||
queryplantest: testfixture.exe sqlite3.exe
|
||||
.\testfixture.exe $(TOP)\test\permutations.test queryplanner
|
||||
|
||||
test: testfixture.exe sqlite3.exe
|
||||
fuzztest: fuzzershell.exe
|
||||
.\fuzzershell.exe $(TOP)\test\fuzzdata1.txt $(TOP)\test\fuzzdata2.txt
|
||||
|
||||
fuzzoomtest: fuzzershell.exe
|
||||
.\fuzzershell.exe -f $(TOP)\test\fuzzdata1.txt --oom
|
||||
|
||||
test: testfixture.exe sqlite3.exe fuzztest
|
||||
.\testfixture.exe $(TOP)\test\veryquick.test
|
||||
|
||||
smoketest: testfixture.exe
|
||||
|
||||
+48
-14
@@ -508,6 +508,17 @@ static int fts3DisconnectMethod(sqlite3_vtab *pVtab){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Write an error message into *pzErr
|
||||
*/
|
||||
void sqlite3Fts3ErrMsg(char **pzErr, const char *zFormat, ...){
|
||||
va_list ap;
|
||||
sqlite3_free(*pzErr);
|
||||
va_start(ap, zFormat);
|
||||
*pzErr = sqlite3_vmprintf(zFormat, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/*
|
||||
** Construct one or more SQL statements from the format string given
|
||||
** and then evaluate those statements. The success code is written
|
||||
@@ -1039,7 +1050,7 @@ static int fts3ContentColumns(
|
||||
}else{
|
||||
rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
*pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
|
||||
sqlite3Fts3ErrMsg(pzErr, "%s", sqlite3_errmsg(db));
|
||||
}
|
||||
}
|
||||
sqlite3_free(zSql);
|
||||
@@ -1207,13 +1218,13 @@ static int fts3InitVtab(
|
||||
}
|
||||
}
|
||||
if( iOpt==SizeofArray(aFts4Opt) ){
|
||||
*pzErr = sqlite3_mprintf("unrecognized parameter: %s", z);
|
||||
sqlite3Fts3ErrMsg(pzErr, "unrecognized parameter: %s", z);
|
||||
rc = SQLITE_ERROR;
|
||||
}else{
|
||||
switch( iOpt ){
|
||||
case 0: /* MATCHINFO */
|
||||
if( strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "fts3", 4) ){
|
||||
*pzErr = sqlite3_mprintf("unrecognized matchinfo: %s", zVal);
|
||||
sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo: %s", zVal);
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
bNoDocsize = 1;
|
||||
@@ -1241,7 +1252,7 @@ static int fts3InitVtab(
|
||||
if( (strlen(zVal)!=3 || sqlite3_strnicmp(zVal, "asc", 3))
|
||||
&& (strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "desc", 4))
|
||||
){
|
||||
*pzErr = sqlite3_mprintf("unrecognized order: %s", zVal);
|
||||
sqlite3Fts3ErrMsg(pzErr, "unrecognized order: %s", zVal);
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
bDescIdx = (zVal[0]=='d' || zVal[0]=='D');
|
||||
@@ -1327,7 +1338,7 @@ static int fts3InitVtab(
|
||||
rc = fts3PrefixParameter(zPrefix, &nIndex, &aIndex);
|
||||
if( rc==SQLITE_ERROR ){
|
||||
assert( zPrefix );
|
||||
*pzErr = sqlite3_mprintf("error parsing prefix parameter: %s", zPrefix);
|
||||
sqlite3Fts3ErrMsg(pzErr, "error parsing prefix parameter: %s", zPrefix);
|
||||
}
|
||||
if( rc!=SQLITE_OK ) goto fts3_init_out;
|
||||
|
||||
@@ -1409,7 +1420,7 @@ static int fts3InitVtab(
|
||||
}
|
||||
for(i=0; i<nNotindexed; i++){
|
||||
if( azNotindexed[i] ){
|
||||
*pzErr = sqlite3_mprintf("no such column: %s", azNotindexed[i]);
|
||||
sqlite3Fts3ErrMsg(pzErr, "no such column: %s", azNotindexed[i]);
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
}
|
||||
@@ -1417,7 +1428,7 @@ static int fts3InitVtab(
|
||||
if( rc==SQLITE_OK && (zCompress==0)!=(zUncompress==0) ){
|
||||
char const *zMiss = (zCompress==0 ? "compress" : "uncompress");
|
||||
rc = SQLITE_ERROR;
|
||||
*pzErr = sqlite3_mprintf("missing %s parameter in fts4 constructor", zMiss);
|
||||
sqlite3Fts3ErrMsg(pzErr, "missing %s parameter in fts4 constructor", zMiss);
|
||||
}
|
||||
p->zReadExprlist = fts3ReadExprList(p, zUncompress, &rc);
|
||||
p->zWriteExprlist = fts3WriteExprList(p, zCompress, &rc);
|
||||
@@ -2810,7 +2821,7 @@ static int fts3SegReaderCursor(
|
||||
** calls out here. */
|
||||
if( iLevel<0 && p->aIndex ){
|
||||
Fts3SegReader *pSeg = 0;
|
||||
rc = sqlite3Fts3SegReaderPending(p, iIndex, zTerm, nTerm, isPrefix, &pSeg);
|
||||
rc = sqlite3Fts3SegReaderPending(p, iIndex, zTerm, nTerm, isPrefix||isScan, &pSeg);
|
||||
if( rc==SQLITE_OK && pSeg ){
|
||||
rc = fts3SegReaderCursorAppend(pCsr, pSeg);
|
||||
}
|
||||
@@ -3459,11 +3470,31 @@ static void fts3ReversePoslist(char *pStart, char **ppPoslist){
|
||||
char *p = &(*ppPoslist)[-2];
|
||||
char c = 0;
|
||||
|
||||
/* Skip backwards passed any trailing 0x00 bytes added by NearTrim() */
|
||||
while( p>pStart && (c=*p--)==0 );
|
||||
|
||||
/* Search backwards for a varint with value zero (the end of the previous
|
||||
** poslist). This is an 0x00 byte preceded by some byte that does not
|
||||
** have the 0x80 bit set. */
|
||||
while( p>pStart && (*p & 0x80) | c ){
|
||||
c = *p--;
|
||||
}
|
||||
if( p>pStart ){ p = &p[2]; }
|
||||
assert( p==pStart || c==0 );
|
||||
|
||||
/* At this point p points to that preceding byte without the 0x80 bit
|
||||
** set. So to find the start of the poslist, skip forward 2 bytes then
|
||||
** over a varint.
|
||||
**
|
||||
** Normally. The other case is that p==pStart and the poslist to return
|
||||
** is the first in the doclist. In this case do not skip forward 2 bytes.
|
||||
** The second part of the if condition (c==0 && *ppPoslist>&p[2])
|
||||
** is required for cases where the first byte of a doclist and the
|
||||
** doclist is empty. For example, if the first docid is 10, a doclist
|
||||
** that begins with:
|
||||
**
|
||||
** 0x0A 0x00 <next docid delta varint>
|
||||
*/
|
||||
if( p>pStart || (c==0 && *ppPoslist>&p[2]) ){ p = &p[2]; }
|
||||
while( *p++&0x80 );
|
||||
*ppPoslist = p;
|
||||
}
|
||||
@@ -4597,12 +4628,14 @@ static void fts3EvalStartReaders(
|
||||
){
|
||||
if( pExpr && SQLITE_OK==*pRc ){
|
||||
if( pExpr->eType==FTSQUERY_PHRASE ){
|
||||
int i;
|
||||
int nToken = pExpr->pPhrase->nToken;
|
||||
for(i=0; i<nToken; i++){
|
||||
if( pExpr->pPhrase->aToken[i].pDeferred==0 ) break;
|
||||
if( nToken ){
|
||||
int i;
|
||||
for(i=0; i<nToken; i++){
|
||||
if( pExpr->pPhrase->aToken[i].pDeferred==0 ) break;
|
||||
}
|
||||
pExpr->bDeferred = (i==nToken);
|
||||
}
|
||||
pExpr->bDeferred = (i==nToken);
|
||||
*pRc = fts3EvalPhraseStart(pCsr, 1, pExpr->pPhrase);
|
||||
}else{
|
||||
fts3EvalStartReaders(pCsr, pExpr->pLeft, pRc);
|
||||
@@ -5765,7 +5798,8 @@ int sqlite3Fts3EvalPhrasePoslist(
|
||||
pIter = pPhrase->pOrPoslist;
|
||||
iDocid = pPhrase->iOrDocid;
|
||||
if( pCsr->bDesc==bDescDoclist ){
|
||||
bEof = (pIter >= (pPhrase->doclist.aAll + pPhrase->doclist.nAll));
|
||||
bEof = !pPhrase->doclist.nAll ||
|
||||
(pIter >= (pPhrase->doclist.aAll + pPhrase->doclist.nAll));
|
||||
while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){
|
||||
sqlite3Fts3DoclistNext(
|
||||
bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll,
|
||||
|
||||
@@ -539,6 +539,7 @@ int sqlite3Fts3Incrmerge(Fts3Table*,int,int);
|
||||
)
|
||||
|
||||
/* fts3.c */
|
||||
void sqlite3Fts3ErrMsg(char**,const char*,...);
|
||||
int sqlite3Fts3PutVarint(char *, sqlite3_int64);
|
||||
int sqlite3Fts3GetVarint(const char *, sqlite_int64 *);
|
||||
int sqlite3Fts3GetVarint32(const char *, int *);
|
||||
|
||||
+1
-1
@@ -116,7 +116,7 @@ static int fts3auxConnectMethod(
|
||||
return SQLITE_OK;
|
||||
|
||||
bad_args:
|
||||
*pzErr = sqlite3_mprintf("invalid arguments to fts4aux constructor");
|
||||
sqlite3Fts3ErrMsg(pzErr, "invalid arguments to fts4aux constructor");
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@@ -1022,13 +1022,13 @@ int sqlite3Fts3ExprParse(
|
||||
sqlite3Fts3ExprFree(*ppExpr);
|
||||
*ppExpr = 0;
|
||||
if( rc==SQLITE_TOOBIG ){
|
||||
*pzErr = sqlite3_mprintf(
|
||||
sqlite3Fts3ErrMsg(pzErr,
|
||||
"FTS expression tree is too large (maximum depth %d)",
|
||||
SQLITE_FTS3_MAX_EXPR_DEPTH
|
||||
);
|
||||
rc = SQLITE_ERROR;
|
||||
}else if( rc==SQLITE_ERROR ){
|
||||
*pzErr = sqlite3_mprintf("malformed MATCH expression: [%s]", z);
|
||||
sqlite3Fts3ErrMsg(pzErr, "malformed MATCH expression: [%s]", z);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -824,7 +824,7 @@ static int fts3MatchinfoCheck(
|
||||
){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
*pzErr = sqlite3_mprintf("unrecognized matchinfo request: %c", cArg);
|
||||
sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo request: %c", cArg);
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ static int fts3termConnectMethod(
|
||||
|
||||
/* The user should specify a single argument - the name of an fts3 table. */
|
||||
if( argc!=4 ){
|
||||
*pzErr = sqlite3_mprintf(
|
||||
sqlite3Fts3ErrMsg(pzErr,
|
||||
"wrong number of arguments to fts4term constructor"
|
||||
);
|
||||
return SQLITE_ERROR;
|
||||
|
||||
@@ -85,7 +85,7 @@ static int fts3tokQueryTokenizer(
|
||||
|
||||
p = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zName, nName+1);
|
||||
if( !p ){
|
||||
*pzErr = sqlite3_mprintf("unknown tokenizer: %s", zName);
|
||||
sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer: %s", zName);
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@@ -172,7 +172,7 @@ int sqlite3Fts3InitTokenizer(
|
||||
|
||||
m = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash,z,(int)strlen(z)+1);
|
||||
if( !m ){
|
||||
*pzErr = sqlite3_mprintf("unknown tokenizer: %s", z);
|
||||
sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer: %s", z);
|
||||
rc = SQLITE_ERROR;
|
||||
}else{
|
||||
char const **aArg = 0;
|
||||
@@ -195,7 +195,7 @@ int sqlite3Fts3InitTokenizer(
|
||||
rc = m->xCreate(iArg, aArg, ppTok);
|
||||
assert( rc!=SQLITE_OK || *ppTok );
|
||||
if( rc!=SQLITE_OK ){
|
||||
*pzErr = sqlite3_mprintf("unknown tokenizer");
|
||||
sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer");
|
||||
}else{
|
||||
(*ppTok)->pModule = m;
|
||||
}
|
||||
@@ -279,9 +279,9 @@ static void testFunc(
|
||||
p = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zName, nName+1);
|
||||
|
||||
if( !p ){
|
||||
char *zErr = sqlite3_mprintf("unknown tokenizer: %s", zName);
|
||||
sqlite3_result_error(context, zErr, -1);
|
||||
sqlite3_free(zErr);
|
||||
char *zErr2 = sqlite3_mprintf("unknown tokenizer: %s", zName);
|
||||
sqlite3_result_error(context, zErr2, -1);
|
||||
sqlite3_free(zErr2);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -326,7 +326,7 @@ static int fts3SqlStmt(
|
||||
/* 25 */ "",
|
||||
|
||||
/* 26 */ "DELETE FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?",
|
||||
/* 27 */ "SELECT DISTINCT level / (1024 * ?) FROM %Q.'%q_segdir'",
|
||||
/* 27 */ "SELECT ? UNION SELECT level / (1024 * ?) FROM %Q.'%q_segdir'",
|
||||
|
||||
/* This statement is used to determine which level to read the input from
|
||||
** when performing an incremental merge. It returns the absolute level number
|
||||
@@ -3444,7 +3444,8 @@ static int fts3DoOptimize(Fts3Table *p, int bReturnDone){
|
||||
rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
int rc2;
|
||||
sqlite3_bind_int(pAllLangid, 1, p->nIndex);
|
||||
sqlite3_bind_int(pAllLangid, 1, p->iPrevLangid);
|
||||
sqlite3_bind_int(pAllLangid, 2, p->nIndex);
|
||||
while( sqlite3_step(pAllLangid)==SQLITE_ROW ){
|
||||
int i;
|
||||
int iLangid = sqlite3_column_int(pAllLangid, 0);
|
||||
@@ -4776,7 +4777,7 @@ static int fts3IncrmergeHintPop(Blob *pHint, i64 *piAbsLevel, int *pnInput){
|
||||
pHint->n = i;
|
||||
i += sqlite3Fts3GetVarint(&pHint->a[i], piAbsLevel);
|
||||
i += fts3GetVarint32(&pHint->a[i], pnInput);
|
||||
if( i!=nHint ) return SQLITE_CORRUPT_VTAB;
|
||||
if( i!=nHint ) return FTS_CORRUPT_VTAB;
|
||||
|
||||
return SQLITE_OK;
|
||||
}
|
||||
@@ -5144,7 +5145,8 @@ static int fts3IntegrityCheck(Fts3Table *p, int *pbOk){
|
||||
rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
int rc2;
|
||||
sqlite3_bind_int(pAllLangid, 1, p->nIndex);
|
||||
sqlite3_bind_int(pAllLangid, 1, p->iPrevLangid);
|
||||
sqlite3_bind_int(pAllLangid, 2, p->nIndex);
|
||||
while( rc==SQLITE_OK && sqlite3_step(pAllLangid)==SQLITE_ROW ){
|
||||
int iLangid = sqlite3_column_int(pAllLangid, 0);
|
||||
int i;
|
||||
@@ -5157,7 +5159,6 @@ static int fts3IntegrityCheck(Fts3Table *p, int *pbOk){
|
||||
}
|
||||
|
||||
/* This block calculates the checksum according to the %_content table */
|
||||
rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3_tokenizer_module const *pModule = p->pTokenizer->pModule;
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
@@ -5254,7 +5255,7 @@ static int fts3DoIntegrityCheck(
|
||||
int rc;
|
||||
int bOk = 0;
|
||||
rc = fts3IntegrityCheck(p, &bOk);
|
||||
if( rc==SQLITE_OK && bOk==0 ) rc = SQLITE_CORRUPT_VTAB;
|
||||
if( rc==SQLITE_OK && bOk==0 ) rc = FTS_CORRUPT_VTAB;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -876,7 +876,7 @@ static fuzzer_stem *fuzzerNewStem(
|
||||
if( pNew==0 ) return 0;
|
||||
memset(pNew, 0, sizeof(*pNew));
|
||||
pNew->zBasis = (char*)&pNew[1];
|
||||
pNew->nBasis = (int)strlen(zWord);
|
||||
pNew->nBasis = (fuzzer_len)strlen(zWord);
|
||||
memcpy(pNew->zBasis, zWord, pNew->nBasis+1);
|
||||
pRule = pCur->pVtab->pRule;
|
||||
while( fuzzerSkipRule(pRule, pNew, pCur->iRuleset) ){
|
||||
|
||||
+12
-4
@@ -2820,11 +2820,19 @@ static int rtreeUpdate(
|
||||
if( nData>1 ){
|
||||
int ii;
|
||||
|
||||
/* Populate the cell.aCoord[] array. The first coordinate is azData[3]. */
|
||||
assert( nData==(pRtree->nDim*2 + 3) );
|
||||
/* Populate the cell.aCoord[] array. The first coordinate is azData[3].
|
||||
**
|
||||
** NB: nData can only be less than nDim*2+3 if the rtree is mis-declared
|
||||
** with "column" that are interpreted as table constraints.
|
||||
** Example: CREATE VIRTUAL TABLE bad USING rtree(x,y,CHECK(y>5));
|
||||
** This problem was discovered after years of use, so we silently ignore
|
||||
** these kinds of misdeclared tables to avoid breaking any legacy.
|
||||
*/
|
||||
assert( nData<=(pRtree->nDim*2 + 3) );
|
||||
|
||||
#ifndef SQLITE_RTREE_INT_ONLY
|
||||
if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
|
||||
for(ii=0; ii<(pRtree->nDim*2); ii+=2){
|
||||
for(ii=0; ii<nData-4; ii+=2){
|
||||
cell.aCoord[ii].f = rtreeValueDown(azData[ii+3]);
|
||||
cell.aCoord[ii+1].f = rtreeValueUp(azData[ii+4]);
|
||||
if( cell.aCoord[ii].f>cell.aCoord[ii+1].f ){
|
||||
@@ -2835,7 +2843,7 @@ static int rtreeUpdate(
|
||||
}else
|
||||
#endif
|
||||
{
|
||||
for(ii=0; ii<(pRtree->nDim*2); ii+=2){
|
||||
for(ii=0; ii<nData-4; ii+=2){
|
||||
cell.aCoord[ii].i = sqlite3_value_int(azData[ii+3]);
|
||||
cell.aCoord[ii+1].i = sqlite3_value_int(azData[ii+4]);
|
||||
if( cell.aCoord[ii].i>cell.aCoord[ii+1].i ){
|
||||
|
||||
@@ -408,6 +408,10 @@ sqldiff$(EXE): $(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h
|
||||
$(TCCX) -o sqldiff$(EXE) -DSQLITE_THREADSAFE=0 \
|
||||
$(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS) $(THREADLIB)
|
||||
|
||||
fuzzershell$(EXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h
|
||||
$(TCCX) -o fuzzershell$(EXE) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION\
|
||||
$(TOP)/tool/fuzzershell.c sqlite3.c $(TLIBS) $(THREADLIB)
|
||||
|
||||
mptester$(EXE): sqlite3.c $(TOP)/mptest/mptest.c
|
||||
$(TCCX) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \
|
||||
$(TLIBS) $(THREADLIB)
|
||||
@@ -629,21 +633,34 @@ fts3-testfixture$(EXE): sqlite3.c fts3amal.c $(TESTSRC) $(TOP)/src/tclsqlite.c
|
||||
$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c fts3amal.c \
|
||||
-o testfixture$(EXE) $(LIBTCL) $(THREADLIB)
|
||||
|
||||
fulltest: testfixture$(EXE) sqlite3$(EXE)
|
||||
fulltest: testfixture$(EXE) sqlite3$(EXE) fuzztest
|
||||
./testfixture$(EXE) $(TOP)/test/all.test
|
||||
|
||||
soaktest: testfixture$(EXE) sqlite3$(EXE)
|
||||
soaktest: testfixture$(EXE) sqlite3$(EXE) fuzzoomtest
|
||||
./testfixture$(EXE) $(TOP)/test/all.test -soak=1
|
||||
|
||||
fulltestonly: testfixture$(EXE) sqlite3$(EXE)
|
||||
fulltestonly: testfixture$(EXE) sqlite3$(EXE) fuzztest
|
||||
./testfixture$(EXE) $(TOP)/test/full.test
|
||||
|
||||
queryplantest: testfixture$(EXE) sqlite3$(EXE)
|
||||
./testfixture$(EXE) $(TOP)/test/permutations.test queryplanner
|
||||
|
||||
test: testfixture$(EXE) sqlite3$(EXE)
|
||||
fuzztest: fuzzershell$(EXE)
|
||||
./fuzzershell$(EXE) $(TOP)/test/fuzzdata1.txt $(TOP)/test/fuzzdata2.txt
|
||||
|
||||
fuzzoomtest: fuzzershell$(EXE)
|
||||
./fuzzershell$(EXE) -f $(TOP)/test/fuzzdata1.txt --oom
|
||||
|
||||
test: testfixture$(EXE) sqlite3$(EXE) fuzztest
|
||||
./testfixture$(EXE) $(TOP)/test/veryquick.test
|
||||
|
||||
# Run a test using valgrind. This can take a really long time
|
||||
# because valgrind is so much slower than a native machine.
|
||||
#
|
||||
valgrindtest: testfixture$(EXE) sqlite3$(EXE) fuzzershell$(EXE)
|
||||
valgrind -v ./fuzzershell$(EXE) -f $(TOP)/test/fuzzdata1.txt
|
||||
OMIT_MISUSE=1 valgrind -v ./testfixture$(EXE) $(TOP)/test/permutations.test valgrind
|
||||
|
||||
# The next two rules are used to support the "threadtest" target. Building
|
||||
# threadtest runs a few thread-safety tests that are implemented in C. This
|
||||
# target is invoked by the releasetest.tcl script.
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
C When\sparsing\sthe\sschema,\signore\sany\sSQL\sthat\sdoes\snot\sbegin\swith\s"CREATE".
|
||||
D 2015-04-16T00:26:03.247
|
||||
C Add\sthe\sSQLITE_LIMIT_PRINTF_WIDTH\ssetting\sfor\ssqlite3_limit()\sand\sassociated\nlogic\sfor\spreventing\sDOS\sattacks\susing\sprintf()\swith\soversized\swidths\sor\nprecisions.
|
||||
D 2015-05-02T18:25:25.099
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in 5f78b1ab81b64e7c57a75d170832443e66c0880a
|
||||
F Makefile.in e628c50e237251fc7e768bef14ee7e822ad69e69
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
F Makefile.msc 11cb5361e34b80e9c5b417ed6a6deee099c5b5f3
|
||||
F Makefile.msc 4c7e6fc40c5b65134b789b18b83743abac907504
|
||||
F Makefile.vxworks e1b65dea203f054e71653415bd8f96dcaed47858
|
||||
F README.md d58e3bebc0a4145e0f2a87994015fdb575a8e866
|
||||
F VERSION 2e244662b71e6e68a5c29b014ebc5b7564f4cc5a
|
||||
@@ -78,25 +78,25 @@ 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 4bd75289875b63c04f943d6ed7c31737da99cd74
|
||||
F ext/fts3/fts3.c 2fb98467f4b670c8934cdd97d1ba3ffa7382764c
|
||||
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
|
||||
F ext/fts3/fts3Int.h 3626655d6ba903a3919bb44e1c38e5f0f9d6be82
|
||||
F ext/fts3/fts3_aux.c 5c211e17a64885faeb16b9ba7772f9d5445c2365
|
||||
F ext/fts3/fts3_expr.c 40123785eaa3ebd4c45c9b23407cc44ac0c49905
|
||||
F ext/fts3/fts3Int.h 59ecaa2d7af0da44c70b6aeaebdcfc070d14abab
|
||||
F ext/fts3/fts3_aux.c 9edc3655fcb287f0467d0a4b886a01c6185fe9f1
|
||||
F ext/fts3/fts3_expr.c 71c063da9c2a4167fb54aec089dd5ef33a58c9cb
|
||||
F ext/fts3/fts3_hash.c 29b986e43f4e9dd40110eafa377dc0d63c422c60
|
||||
F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf
|
||||
F ext/fts3/fts3_icu.c e319e108661147bcca8dd511cd562f33a1ba81b5
|
||||
F ext/fts3/fts3_porter.c 3565faf04b626cddf85f03825e86056a4562c009
|
||||
F ext/fts3/fts3_snippet.c 52c2dcf410b1f9af5a44d81a2cf8c68ed1cb5283
|
||||
F ext/fts3/fts3_term.c a521f75132f9a495bdca1bdd45949b3191c52763
|
||||
F ext/fts3/fts3_snippet.c 0ce4ee2451b9f3603a1693ef9779bb0fb662a9fe
|
||||
F ext/fts3/fts3_term.c 88c55a6fa1a51ab494e33dced0401a6c28791fd7
|
||||
F ext/fts3/fts3_test.c 8a3a78c4458b2d7c631fcf4b152a5cd656fa7038
|
||||
F ext/fts3/fts3_tokenize_vtab.c becc661223db7898b213f9e8a23d75bac02408c9
|
||||
F ext/fts3/fts3_tokenizer.c b7e586baeb8d0a061cf01a0f7081d88f3935eecf
|
||||
F ext/fts3/fts3_tokenize_vtab.c a27593ab19657166f6fa5ec073b678cc29a75860
|
||||
F ext/fts3/fts3_tokenizer.c 50e7a69a549ac5882cc1971ee43f66aaabc11395
|
||||
F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3
|
||||
F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004
|
||||
F ext/fts3/fts3_unicode.c a93f5edc0aff44ef8b06d7cb55b52026541ca145
|
||||
F ext/fts3/fts3_unicode2.c c3d01968d497bd7001e7dc774ba75b372738c057
|
||||
F ext/fts3/fts3_write.c 7104ec015474ee61a8a570349b925f35c6b0a294
|
||||
F ext/fts3/fts3_write.c 4f005f78592a1447ca96c8475ef5342ab7dbe02a
|
||||
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
|
||||
F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
|
||||
F ext/fts3/tool/fts3view.c 8e53d0190a7b3443764bbd32ad47be2bd852026d
|
||||
@@ -111,7 +111,7 @@ F ext/misc/closure.c 636024302cde41b2bf0c542f81c40c624cfb7012
|
||||
F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83
|
||||
F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2
|
||||
F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f
|
||||
F ext/misc/fuzzer.c e3e18f47252c151b5553d7e806f38e757d37c4cc
|
||||
F ext/misc/fuzzer.c 4c84635c71c26cfa7c2e5848cf49fe2d2cfcd767
|
||||
F ext/misc/ieee754.c b0362167289170627659e84173f5d2e8fee8566e
|
||||
F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342
|
||||
F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63
|
||||
@@ -124,7 +124,7 @@ F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95
|
||||
F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e
|
||||
F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212
|
||||
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
|
||||
F ext/rtree/rtree.c 14e6239434d4e3f65d3e90320713f26aa24e167f
|
||||
F ext/rtree/rtree.c 0c207fd8b814a35537d96681cbf57436e200b75e
|
||||
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
|
||||
F ext/rtree/rtree1.test 541bbcab74613907fea08b2ecdcdd5b7aa724cc9
|
||||
F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba
|
||||
@@ -152,7 +152,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e
|
||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
|
||||
F main.mk ddffac494a82d42772df9fe30d3a78acf4f7cb41
|
||||
F main.mk 1225d45e1883000a3ed6f028893a11c04522ea6a
|
||||
F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea
|
||||
F mkopcodeh.awk d5e22023b5238985bb54a72d33e0ac71fe4f8a32
|
||||
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
|
||||
@@ -166,36 +166,36 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
|
||||
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
|
||||
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
|
||||
F src/alter.c d23d6b6991f66b383934f137fd4384d93fb98c81
|
||||
F src/analyze.c 91540f835163d5369ccbae78e2e6c74d0dd53c1d
|
||||
F src/attach.c 3c1053a4cf1c3ca05c8c1d74a94cb688d763cef2
|
||||
F src/alter.c 8f6dc4a6ddc1ebc0ed5cc470c4e57ff0d1605e90
|
||||
F src/analyze.c d23790787f80ebed58df7774744b4cf96401498b
|
||||
F src/attach.c c38ac5a520a231d5d0308fd7f2ad95191c867bae
|
||||
F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
|
||||
F src/backup.c ff743689c4d6c5cb55ad42ed9d174b2b3e71f1e3
|
||||
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
|
||||
F src/bitvec.c 5eb7958c3bf65210211cbcfc44eff86d0ded7c9d
|
||||
F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
|
||||
F src/btree.c c6e32d84442f79d5b96965265d65b3baa231dffc
|
||||
F src/btree.c 9c1a6b3aafa1ce5fde83724fdc2dce2ed3144690
|
||||
F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1
|
||||
F src/btreeInt.h 973a22a6fd61350b454ad614832b1f0a5e25a1e4
|
||||
F src/build.c 01b969b20a44a3d9620e597d9af8242348123540
|
||||
F src/build.c 61b47073f79f31e80a05db9ce13c5ca81bf8f74e
|
||||
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
|
||||
F src/complete.c a5cf5b4b56390cfb7b8636e8f7ddef90258dd575
|
||||
F src/ctime.c 98f89724adc891a1a4c655bee04e33e716e05887
|
||||
F src/date.c e4d50b3283696836ec1036b695ead9a19e37a5ac
|
||||
F src/delete.c 37964e6c1d73ff49cbea9ff690c9605fb15f600e
|
||||
F src/expr.c 8800584340a9b4f4c0ca55c360de751c6da0b11a
|
||||
F src/expr.c 4c05a28eebe63b288fda1db0e8de556a82ca2ec6
|
||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||
F src/fkey.c 3343d551a8d810782257244fb33f2ce191493c39
|
||||
F src/func.c 1414c24c873c48796ad45942257a179a423ba42f
|
||||
F src/fkey.c c9b63a217d86582c22121699a47f22f524608869
|
||||
F src/func.c 6b5a0c8364399c0ea6c5dda0e3ef662c4b789f6f
|
||||
F src/global.c 4f77cadbc5427d00139ba43d0f3979804cbb700e
|
||||
F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
|
||||
F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
|
||||
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
|
||||
F src/insert.c 305dd3f9539d0affa4bf1c14cc7dffb34867e040
|
||||
F src/insert.c 8176ba5bad8fcef643558ca5708f33ed05a4035a
|
||||
F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
|
||||
F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e
|
||||
F src/lempar.c 7274c97d24bb46631e504332ccd3bd1b37841770
|
||||
F src/loadext.c 86bd4e2fccd520b748cba52492ab60c4a770f660
|
||||
F src/main.c 40e333960d53f7d50ee8ce09d40431c87ea653f2
|
||||
F src/loadext.c 29255bbe1cfb2ce9bbff2526a5ecfddcb49b9271
|
||||
F src/main.c 3fa53630047925acbba0a142c5ca11ce07e20645
|
||||
F src/malloc.c 6a370b83d54e4bbf6f94021221c2a311cff26a18
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c abe6ee469b6c5a35c7f22bfeb9c9bac664a1c987
|
||||
@@ -212,35 +212,35 @@ F src/mutex_w32.c 61660ada28d8308ad190f444c2170c4f2a590c2f
|
||||
F src/notify.c 9711a7575036f0d3040ba61bc6e217f13a9888e7
|
||||
F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8
|
||||
F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf
|
||||
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
|
||||
F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e
|
||||
F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
|
||||
F src/os_unix.c 5ed7e2e453c2980909a6b2c80dc55764b50819a8
|
||||
F src/os_win.c 03d27be3a20048ef52a648d5f0a15f5edda9f2a3
|
||||
F src/os_unix.c 23eb5f56fac54d8fe0cb204291f3b3b2d94f23fc
|
||||
F src/os_win.c 2da99cf07da7db6bcb1974013abfd89ec74749b3
|
||||
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
|
||||
F src/pager.c 4120a49ecd37697e28f5ed807f470b9c0b88410c
|
||||
F src/pager.c 97110085b1321298412f1e5c37bddb95b36d9208
|
||||
F src/pager.h c3476e7c89cdf1c6914e50a11f3714e30b4e0a77
|
||||
F src/parse.y 1299c66e7b1707322ccd8af43a359b8fb0d46d72
|
||||
F src/parse.y c4e0387bc88c8e21e5ba653e2578959a1f3cdbc7
|
||||
F src/pcache.c 10539fb959849ad6efff80050541cab3d25089d4
|
||||
F src/pcache.h b44658c9c932d203510279439d891a2a83e12ba8
|
||||
F src/pcache1.c 69d137620a305f814398bd29a0c998038c0695e9
|
||||
F src/pragma.c 3965ae4e82bed39fb97ce04c5fe18c9bc3ee6a88
|
||||
F src/pragma.c c1f4d012ea9f6b1ce52d341b2cd0ad72d560afd7
|
||||
F src/pragma.h 09c89bca58e9a44de2116cc8272b8d454657129f
|
||||
F src/prepare.c 1fffbdcd6f8a0173a8f70d71f22528f4c0e1e3d3
|
||||
F src/printf.c 08fa675c200aac29e561c6153f91f909ed17612f
|
||||
F src/printf.c c287c1cf15bffc79a2fab2a034da6f341baee869
|
||||
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
||||
F src/resolve.c 66cfe49a9c3b449ef13b89a8c47036a4ed167eab
|
||||
F src/resolve.c 13109bc3b5ab404446296efa17039640de5bc35d
|
||||
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
|
||||
F src/select.c 93260bc9e7e0e6dfe1b7cb8815b0ed4cad8be9e3
|
||||
F src/shell.c 72b61a9d41ba12b67ea06fe9267abcc012c6c5bb
|
||||
F src/sqlite.h.in ca27603a36fcacdaac5a19d8ee35aaff8ce8516f
|
||||
F src/select.c 5e83049a0be1caf88921e815d0118bce49cba827
|
||||
F src/shell.c e83273a73784f8abd344a433b65ea8b4fa133645
|
||||
F src/sqlite.h.in 08935b02c117fa3793b193324388befd77592ad3
|
||||
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
||||
F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
|
||||
F src/sqliteInt.h 90b7bfd89d7307cd0750663da419ba4bb81e7379
|
||||
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
|
||||
F src/sqliteInt.h 42f804c1a065a4e204d126883bc9731fde6714de
|
||||
F src/sqliteLimit.h c647cd30d5228f520a754b46b6204586b6818f63
|
||||
F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179
|
||||
F src/table.c e7a09215315a978057fb42c640f890160dbcc45e
|
||||
F src/tclsqlite.c fa72a7c5278662357c105ba7925c1d0972506ff9
|
||||
F src/test1.c 90fbedce75330d48d99eadb7d5f4223e86969585
|
||||
F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
|
||||
F src/tclsqlite.c 14f1992dd6100bfeb1a3dec7e7f449e1c814b8ee
|
||||
F src/test1.c 3cf9b20cc81580b61046628986db73ac1583f7ac
|
||||
F src/test2.c 577961fe48961b2f2e5c8b56ee50c3f459d3359d
|
||||
F src/test3.c 64d2afdd68feac1bb5e2ffb8226c8c639f798622
|
||||
F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e
|
||||
@@ -261,16 +261,16 @@ F src/test_fs.c ced436e3d4b8e4681328409b8081051ce614e28f
|
||||
F src/test_func.c f1ac201465472e76a73e2f3695c3553c63e7322a
|
||||
F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd
|
||||
F src/test_init.c 66b33120ffe9cd853b5a905ec850d51151337b32
|
||||
F src/test_intarray.c 6c610a21ab8edde85a3a2c7f2b069244ecf4d834
|
||||
F src/test_intarray.c 870124b95ec4c645d4eb84f15efb7133528fb1a5
|
||||
F src/test_intarray.h 9dc57417fb65bc7835cc18548852cc08cc062202
|
||||
F src/test_journal.c 5360fbe1d1e4416ca36290562fd5a2e3f70f32aa
|
||||
F src/test_loadext.c a5251f956ab6af21e138dc1f9c0399394a510cb4
|
||||
F src/test_malloc.c b9495384e74923aefde8311de974bf9b0f5ba570
|
||||
F src/test_multiplex.c 97813565daa7ee480abcc5dd1e9984ed1f71eb8c
|
||||
F src/test_malloc.c 208f09a4e21defa496bc1094fcfadea19385a112
|
||||
F src/test_multiplex.c 9fefd23f6cc3fa9bf0748a5e453167e7b9f193ce
|
||||
F src/test_multiplex.h c08e4e8f8651f0c5e0509b138ff4d5b43ed1f5d3
|
||||
F src/test_mutex.c 293042d623ebba969160f471a82aa1551626454f
|
||||
F src/test_onefile.c 0396f220561f3b4eedc450cef26d40c593c69a25
|
||||
F src/test_osinst.c 3d0340bc31a9f3d8a3547e0272373e80f78dde25
|
||||
F src/test_onefile.c 38f7cbe79d5bafe95bde683cc3a53b8ca16daf10
|
||||
F src/test_osinst.c 5423dc1d355f594371f27dd292ca54bd320b8196
|
||||
F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00
|
||||
F src/test_quota.c 180813f43683be5725458fc1ff13ac455d8e722d
|
||||
F src/test_quota.h 2a8ad1952d1d2ca9af0ce0465e56e6c023b5e15d
|
||||
@@ -278,50 +278,50 @@ F src/test_rtree.c bfe6f4386517f70054311109f3528adffec34485
|
||||
F src/test_schema.c 2bdba21b82f601da69793e1f1d11bf481a79b091
|
||||
F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe
|
||||
F src/test_sqllog.c b690c12933f50ff46491e0d56a251f84ae16e914
|
||||
F src/test_stat.c ffc8177f6e69de32a8a89fa6bca73facb6c5face
|
||||
F src/test_stat.c e6583a44b0a23207ba2a9d69be16a338a8b70aa2
|
||||
F src/test_superlock.c 06797157176eb7085027d9dd278c0d7a105e3ec9
|
||||
F src/test_syscall.c 2e21ca7f7dc54a028f1967b63f1e76155c356f9b
|
||||
F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa
|
||||
F src/test_thread.c af391ec03d23486dffbcc250b7e58e073f172af9
|
||||
F src/test_vfs.c b7e6831e6fcf04c5090accff30640ec5c9630739
|
||||
F src/test_vfs.c 3b65d42e18b262805716bd96178c81da8f2d9283
|
||||
F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698
|
||||
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||
F src/threads.c 6bbcc9fe50c917864d48287b4792d46d6e873481
|
||||
F src/tokenize.c a8234a67577308935cdf13e618cd66556f5f45d1
|
||||
F src/trigger.c 69a91bed7c94e46223e37ffccfeeb35e34b999ac
|
||||
F src/tokenize.c b15511a2396641792f386ceb440d1d922972a78e
|
||||
F src/trigger.c 322f23aad694e8f31d384dcfa386d52a48d3c52f
|
||||
F src/update.c 3c4ecc282accf12d39edb8d524cf089645e55a13
|
||||
F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
|
||||
F src/util.c 98a7627ca48ad3265b6940915a1d08355eb3fc7e
|
||||
F src/util.c a6431c92803b975b7322724a7b433e538d243539
|
||||
F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
|
||||
F src/vdbe.c 3f3afd12d4794cb51fe13dc948b1172a5eb71a94
|
||||
F src/vdbe.c ff9efff0548b6a31d095ddc999d606e7605f0cdc
|
||||
F src/vdbe.h 7e538ecf47dccb307ea2d087c3ddc2dd8d70e79d
|
||||
F src/vdbeInt.h 9cbaa84f53ddd2d09a0cf61a94337a3a035d08a0
|
||||
F src/vdbeapi.c 583d56b129dd27f12bed518270de9ebe521e6a75
|
||||
F src/vdbeaux.c a20504ae52392459fa08402fda3f195f19d7c79d
|
||||
F src/vdbeaux.c 03591cca98ec50e1493043f0ff7abbece0b9c83d
|
||||
F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90
|
||||
F src/vdbemem.c c0dc81285b7571b0a31c40f17846fe2397ec1cd9
|
||||
F src/vdbesort.c 2e7f683464fd5db3be4beaa1ff2d39e24fcb64b8
|
||||
F src/vdbetrace.c 7e4222955e07dd707a2f360c0eb73452be1cb010
|
||||
F src/vtab.c 9ca557215e8591ceb66e0b7c0a579c6df1e54b2d
|
||||
F src/vdbemem.c 7bfbeef0978a2e1a05d979641fdbf7c189b7ddf4
|
||||
F src/vdbesort.c f5009e7a35e3065635d8918b9a31f498a499976b
|
||||
F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0
|
||||
F src/vtab.c c535e80259ebe616467181a83a4263555b97c694
|
||||
F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
|
||||
F src/wal.c 753995db83247f20361a8e8a874990b21a75abd9
|
||||
F src/wal.c ce2cb2d06faab54d1bce3e739bec79e063dd9113
|
||||
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
||||
F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804
|
||||
F src/where.c 8ba8ff31dc9bf1b69fe771d35d8764d5a1efd310
|
||||
F src/where.c 85fff9c40569ccb79c3177419b339e7d7df566cb
|
||||
F src/whereInt.h cbe4aa57326998d89e7698ca65bb7c28541d483c
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
F test/aggnested.test b35b4cd69fc913f90d39a575e171e1116c3a4bb7
|
||||
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
|
||||
F test/all.test 6ff7b43c2b4b905c74dc4a813d201d0fa64c5783
|
||||
F test/alter.test 547dc2d292644301ac9a7dda22b319b74f9c08d2
|
||||
F test/alter.test 2facdddf08d0d48e75dc6cc312cd2b030f4835dd
|
||||
F test/alter2.test 7ea05c7d92ac99349a802ef7ada17294dd647060
|
||||
F test/alter3.test 49c9d9fba2b8fcdce2dedeca97bbf1f369cc548d
|
||||
F test/alter4.test c461150723ac957f3b2214aa0b11552cd72023ec
|
||||
F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc
|
||||
F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
|
||||
F test/analyze.test 3eb35a4af972f98422e5dc0586501b17d103d321
|
||||
F test/analyze3.test 75b9e42ea1e4edc919250450dc5762186965d4e6
|
||||
F test/analyze3.test 0f0ee6135b293a0e5af471a8423b80b688469d71
|
||||
F test/analyze4.test eff2df19b8dd84529966420f29ea52edc6b56213
|
||||
F test/analyze5.test 765c4e284aa69ca172772aa940946f55629bc8c4
|
||||
F test/analyze6.test f1c552ce39cca4ec922a7e4e0e5d0203d6b3281f
|
||||
@@ -426,7 +426,7 @@ F test/corrupt8.test 2399dfe40d2c0c63af86706e30f3e6302a8d0516
|
||||
F test/corrupt9.test 730a3db08d4ab9aa43392ea30d9c2b4879cbff85
|
||||
F test/corruptA.test 53e56dafd180addcdadb402244b8cb9771d2ba26
|
||||
F test/corruptB.test 73a8d6c0b9833697ecf16b63e3c5c05c945b5dec
|
||||
F test/corruptC.test 02405cf7ed0c1e989060e1aab6d02ffbc3906fbb
|
||||
F test/corruptC.test 3fcc0f73d2cf2d69befe2d96332b942426a6aae2
|
||||
F test/corruptD.test b3c205fac7952b1de645ce44bb02335cd9e3e040
|
||||
F test/corruptE.test 193b4ca4e927e77c1d5f4f56203ddc998432a7ee
|
||||
F test/corruptF.test be9fde98e4c93648f1ba52b74e5318edc8f59fe4
|
||||
@@ -435,7 +435,7 @@ F test/corruptH.test 5dd4fa98c6c1ed33b178f9e8a48c4fdd3cfc9067
|
||||
F test/corruptI.test 221ad8b7f0a9ac6b80fc577e73b5ad8cdea31243
|
||||
F test/corruptJ.test 9e29e7a81ee3b6ac50f77ea7a9e2f3fa03f32d91
|
||||
F test/cost.test 19d314526616ce4473eb4e4e450fcb94499ce318
|
||||
F test/count.test 42a251178e32f617eda33f76236a7f79825a50b5
|
||||
F test/count.test cb2e0f934c6eb33670044520748d2ecccd46259c
|
||||
F test/coveridxscan.test cdb47d01acc4a634a34fd25abe85189e0d0f1e62
|
||||
F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f
|
||||
F test/crash2.test 5b14d4eb58b880e231361d3b609b216acda86651
|
||||
@@ -476,7 +476,7 @@ F test/e_expr.test 8f5fdd7261e2d746813b0c6a1c0e34824ad3c5ad
|
||||
F test/e_fkey.test a1783fe1f759e1990e6a11adfcf0702dac4d0707
|
||||
F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459
|
||||
F test/e_insert.test 0e63edc037afe738bb81a626a676811ed7862c90
|
||||
F test/e_reindex.test 396b7b4f0a66863b4e95116a67d93b227193e589
|
||||
F test/e_reindex.test 57d439f6c644befc8274ac93cf2f5449cf2736c1
|
||||
F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6
|
||||
F test/e_select.test 52692ff3849541e828ad4661fe3773a9b8711763
|
||||
F test/e_select2.test aceb80ab927d46fba5ce7586ebabf23e2bb0604f
|
||||
@@ -499,13 +499,13 @@ F test/exclusive.test c7ebbc756eacf544c108b15eed64d7d4e5f86b75
|
||||
F test/exclusive2.test 32798111aae78a5deec980eee383213f189df308
|
||||
F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
|
||||
F test/exists.test 8f7b27b61c2fbe5822f0a1f899c715d14e416e30
|
||||
F test/expr.test c4b9bf0cc60b26862475e19999fbd2609ca8259c
|
||||
F test/expr.test 79c3e7502d9e571553b85f0ecc8ff2ac7d0e4931
|
||||
F test/extension01.test 00d13cec817f331a687a243e0e5a2d87b0e358c9
|
||||
F test/fallocate.test 3e979af17dfa7e5e9dda5eba1a696c04fa9d47f7
|
||||
F test/filectrl.test 14fa712e42c4cb791e09dfd58a6a03efb47ef13a
|
||||
F test/filefmt.test cb34663f126cbc2d358af552dcaf5c72769b0146
|
||||
F test/fkey1.test e1d1fa84cde579185ea01358436839703e415a5b
|
||||
F test/fkey2.test 223c624e7eccee21e89c98d4d127ac88d774b940
|
||||
F test/fkey1.test de5b287f6a480b36bd51e8debcf48168e26e4ed2
|
||||
F test/fkey2.test f3d27ecba480a348c328965d154214719bb158a9
|
||||
F test/fkey3.test 76d475c80b84ee7a5d062e56ccb6ea68882e2b49
|
||||
F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d
|
||||
F test/fkey5.test 56bcb5a6e8b725b17febc267fb041a6695e86853
|
||||
@@ -551,7 +551,7 @@ F test/fts2r.test b154c30b63061d8725e320fba1a39e2201cadd5e
|
||||
F test/fts2token.test d8070b241a15ff13592a9ae4a8b7c171af6f445a
|
||||
F test/fts3.test 672a040ea57036fb4b6fdc09027c18d7d24ab654
|
||||
F test/fts3_common.tcl 99cf6659b87c0f74f55963c2aea03b3a7d66ceb0
|
||||
F test/fts3aa.test edd20ddbbc5b6015ab340abf2ca278ae11ec387d
|
||||
F test/fts3aa.test 6c263a6f8845205ee02550981a94c2e8dc1e7058
|
||||
F test/fts3ab.test 7f6cf260ae80dda064023df8e8e503e9a412b91f
|
||||
F test/fts3ac.test 636ed7486043055d4f126a0e385f2d5a82ebbf63
|
||||
F test/fts3ad.test e40570cb6f74f059129ad48bcef3d7cbc20dda49
|
||||
@@ -587,6 +587,7 @@ F test/fts3expr.test 3401d47b229c4504424caf362cc4ff704cad4162
|
||||
F test/fts3expr2.test 18da930352e5693eaa163a3eacf96233b7290d1a
|
||||
F test/fts3expr3.test 9e91b8edbcb197bf2e92161aa7696446d96dce5f
|
||||
F test/fts3expr4.test e1be1248566f43c252d4404d52914f1fc4bfa065
|
||||
F test/fts3expr5.test f9abfffbf5e53d48a33e12a1e8f8ba2c551c9b49
|
||||
F test/fts3fault.test cb72dccb0a3b9f730f16c5240f3fcb9303eb1660
|
||||
F test/fts3fault2.test f953bb3cf903988172270a9a0aafd5a890b0f98f
|
||||
F test/fts3first.test dbdedd20914c8d539aa3206c9b34a23775644641
|
||||
@@ -605,7 +606,7 @@ F test/fts3tok1.test 178c050199af8c05299b1ad572514ce1c54b7827
|
||||
F test/fts3tok_err.test 52273cd193b9036282f7bacb43da78c6be87418d
|
||||
F test/fts3varint.test 752c08ed5d32c5d7dc211b056f4ed68a76b7e36e
|
||||
F test/fts4aa.test 10aac8e9d62c7357590acfabe3fad01e9a9ce1cb
|
||||
F test/fts4check.test 74d77f6cdb768ac49df5afda575cef14ae3d239a
|
||||
F test/fts4check.test 9d9e818fd6cb29c0e007cd6d00447739d4fde430
|
||||
F test/fts4content.test abb0c77bc3da3df64fec72e00844d2257a90025d
|
||||
F test/fts4docid.test e33c383cfbdff0284685604d256f347a18fdbf01
|
||||
F test/fts4growth.test df10fde9f47cf5c71861e63fd8efcd573c4f7e53
|
||||
@@ -630,6 +631,8 @@ F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1
|
||||
F test/fuzz3.test efd384b896c647b61a2c1848ba70d42aad60a7b3
|
||||
F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b
|
||||
F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26
|
||||
F test/fuzzdata1.txt 9fceb50868e0b798160e83742bd7e44e457176a0
|
||||
F test/fuzzdata2.txt ba9b4467d7ec46cc85d32c0d031540cd727ae6ad
|
||||
F test/fuzzer1.test d4c52aaf3ef923da293a2653cfab33d02f718a36
|
||||
F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536
|
||||
F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98
|
||||
@@ -659,14 +662,14 @@ F test/index3.test b6ec456cf3b81d9a32123fe7e449bde434db338b
|
||||
F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6
|
||||
F test/index5.test 25b0b451aceed4ac5f7d49f856f6de7257470b3e
|
||||
F test/index6.test 3ae54e53c53f2adcacda269237d8e52bdb05a481
|
||||
F test/index7.test 3d54dce09344c4530ea39a458aa304da044c887a
|
||||
F test/index7.test 9c6765a74fc3fcde7aebc5b3bd40d98df14a527c
|
||||
F test/indexedby.test 5f527a78bae74c61b8046ae3037f9dfb0bf0c353
|
||||
F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d
|
||||
F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
|
||||
F test/insert.test 38742b5e9601c8f8d76e9b7555f7270288c2d371
|
||||
F test/insert2.test 4f3a04d168c728ed5ec2c88842e772606c7ce435
|
||||
F test/insert2.test 4d14b8f1b810a41995f6286b64a6943215d52208
|
||||
F test/insert3.test 1b7db95a03ad9c5013fdf7d6722b6cd66ee55e30
|
||||
F test/insert4.test 4791662c50518bdd37d394cae9a7a8014e845bb3
|
||||
F test/insert4.test a20432f1c0fbbcff8f11d0e6ab4acb8c9db58023
|
||||
F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6
|
||||
F test/instr.test 737bbf80685232033f3abedc6ae92f75860b5dd2
|
||||
F test/intarray.test 066b7d7ac38d25bf96f87f1b017bfc687551cdd4
|
||||
@@ -688,7 +691,7 @@ F test/join6.test cfe6503791ceb0cbb509966740286ec423cbf10b
|
||||
F test/journal1.test 69abc726c51b4a0409189f9a85191205297c0577
|
||||
F test/journal2.test ae06f566c28552c313ded3fee79a6c69e6d049b1
|
||||
F test/journal3.test ff8af941f9e06161d3db1b46bb9f965ff0e7f307
|
||||
F test/jrnlmode.test 9ee3a78f53d52cca737db69293d15dc41c0cbd36
|
||||
F test/jrnlmode.test 6014ba5c11d66ff8bc7d87a7a2abc5c54be73b2e
|
||||
F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d
|
||||
F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
|
||||
F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
|
||||
@@ -711,7 +714,7 @@ F test/lock_common.tcl 7ffb45accf6ee91c736df9bafe0806a44358f035
|
||||
F test/lookaside.test 93f07bac140c5bb1d49f3892d2684decafdc7af2
|
||||
F test/main.test 16131264ea0c2b93b95201f0c92958e85f2ba11a
|
||||
F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9
|
||||
F test/malloc.test 96939d2d1a6f39667bbebe5bc27c6525f2ab614e
|
||||
F test/malloc.test 21c213365f2cca95ab2d7dc078dc8525f96065f8
|
||||
F test/malloc3.test e3b32c724b5a124b57cb0ed177f675249ad0c66a
|
||||
F test/malloc4.test 957337613002b7058a85116493a262f679f3a261
|
||||
F test/malloc5.test 79182b8bffd6d62f77b1a5a8ba8e6bf0e5053b8e
|
||||
@@ -743,15 +746,16 @@ F test/minmax.test 42fbad0e81afaa6e0de41c960329f2b2c3526efd
|
||||
F test/minmax2.test b44bae787fc7b227597b01b0ca5575c7cb54d3bc
|
||||
F test/minmax3.test cc1e8b010136db0d01a6f2a29ba5a9f321034354
|
||||
F test/minmax4.test 936941484ebdceb8adec7c86b6cd9b6e5e897c1f
|
||||
F test/misc1.test 9abcae9a0b8785d6fa92925dbb19c309ae9ea077
|
||||
F test/misc1.test 783ba75743b2cf71e0f646bf540a6cef57264811
|
||||
F test/misc2.test 00d7de54eda90e237fc9a38b9e5ccc769ebf6d4d
|
||||
F test/misc3.test cf3dda47d5dda3e53fc5804a100d3c82be736c9d
|
||||
F test/misc4.test 9c078510fbfff05a9869a0b6d8b86a623ad2c4f6
|
||||
F test/misc5.test 528468b26d03303b1f047146e5eefc941b9069f5
|
||||
F test/misc5.test f96428ea95b3820aafc6f1c50cf48a09e4597ee1
|
||||
F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91
|
||||
F test/misc7.test edd0b63e2ee29a256900b0514f6fff27e19e9bb2
|
||||
F test/misc8.test fc2754d38892f7dac30c22db3616c2764f117d66
|
||||
F test/misuse.test 3c34719944ba045cc6c188a4852ba04680728912
|
||||
F test/mkfuzzdata1.tcl 5f9c33fadc64b078bb4a2c04c18b6dd3da075bec
|
||||
F test/mmap1.test 1bfd611b9841eafb44f7d83c0788e146d84a33c9
|
||||
F test/mmap2.test 9d6dd9ddb4ad2379f29cc78f38ce1e63ed418022
|
||||
F test/mmap3.test c92273e16eb8d23c1d55c9815b446bb72ef0512e
|
||||
@@ -794,7 +798,7 @@ F test/pcache.test b09104b03160aca0d968d99e8cd2c5b1921a993d
|
||||
F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
|
||||
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
|
||||
F test/permutations.test f9cc1dd987986c9d4949211c7a4ed55ec9aecba1
|
||||
F test/pragma.test e6605ce89c66db930aef561e43a22281a09ffc66
|
||||
F test/pragma.test be7195f0aa72bdb8a512133e9640ac40f15b57a2
|
||||
F test/pragma2.test f624a496a95ee878e81e59961eade66d5c00c028
|
||||
F test/pragma3.test 6f849ccffeee7e496d2f2b5e74152306c0b8757c
|
||||
F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc
|
||||
@@ -812,8 +816,8 @@ F test/randexpr1.test eda062a97e60f9c38ae8d806b03b0ddf23d796df
|
||||
F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8
|
||||
F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8
|
||||
F test/reindex.test 44edd3966b474468b823d481eafef0c305022254
|
||||
F test/releasetest.tcl a37cd82092c8be438255d65804b5951d6e3ecdae
|
||||
F test/resolver01.test 33abf37ff8335e6bf98f2b45a0af3e06996ccd9a
|
||||
F test/releasetest.tcl 7ad4fd49ae50c41ec7781815bdda8a8b278781d4
|
||||
F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb
|
||||
F test/rollback.test 458fe73eb3ffdfdf9f6ba3e9b7350a6220414dea
|
||||
F test/rollback2.test fc14cf6d1a2b250d2735ef16124b971bce152f14
|
||||
F test/rollbackfault.test 6a004f71087cc399296cffbb5429ea6da655ae65
|
||||
@@ -836,10 +840,10 @@ F test/schema4.test e6a66e20cc69f0e306667c08be7fda3d11707dc5
|
||||
F test/schema5.test 29699b4421f183c8f0e88bd28ce7d75d13ea653e
|
||||
F test/securedel.test 21749c32ccc30f1ea9e4b9f33295a6521ec20fa0
|
||||
F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5
|
||||
F test/select1.test fc2a61f226a649393664ad54bc5376631801517c
|
||||
F test/select1.test be62204d2bd9a5a8a149e9974cfddce893d8f686
|
||||
F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56
|
||||
F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054
|
||||
F test/select4.test 16fa1cafb942f42294ec85cbb78954c2f2d15a44
|
||||
F test/select4.test 48e14766d98b744b2202cca6d4679bf7ef3784c8
|
||||
F test/select5.test e758b8ef94f69b111df4cb819008856655dcd535
|
||||
F test/select6.test 39eac4a5c03650b2b473c532882273283ee8b7a0
|
||||
F test/select7.test 7fd2ef598cfabb6b9ff6ac13973b91d0527df49d
|
||||
@@ -899,8 +903,9 @@ F test/speedtest1.c 2b416dca3a155fcaa849540b2e7fc1df12896c23
|
||||
F test/spellfix.test 24f676831acddd2f4056a598fd731a72c6311f49
|
||||
F test/sqllimits1.test e05786eaed7950ff6a2d00031d001d8a26131e68
|
||||
F test/stat.test 76fd746b85459e812a0193410fb599f0531f22de
|
||||
F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1
|
||||
F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9
|
||||
F test/subquery.test 666fdecceac258f5fd84bed09a64e49d9f37edd9
|
||||
F test/subquery.test d7268d193dd33d5505df965399d3a594e76ae13f
|
||||
F test/subquery2.test 438f8a7da1457277b22e4176510f7659b286995f
|
||||
F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4
|
||||
F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a
|
||||
@@ -908,7 +913,7 @@ F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2
|
||||
F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85
|
||||
F test/syscall.test d2fdaad713f103ac611fe7ef9b724c7b69f8149c
|
||||
F test/sysfault.test fa776e60bf46bdd3ae69f0b73e46ee3977a58ae6
|
||||
F test/table.test 06271d61eb13871490d38168433c1ef3dd82bb2a
|
||||
F test/table.test bd841e8df69b99172ce9c7d53587463913d711ca
|
||||
F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
|
||||
F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
|
||||
F test/tclsqlite.test 7fb866443c7deceed22b63948ccd6f76b52ad054
|
||||
@@ -1071,7 +1076,7 @@ F test/tkt4018.test 7c2c9ba4df489c676a0a7a0e809a1fb9b2185bd1
|
||||
F test/tokenize.test ce430a7aed48fc98301611429595883fdfcab5d7
|
||||
F test/tpch01.test 04adbf8d8300fa60a222f28d901abd76e7be6dd4
|
||||
F test/trace.test 73a5508100f7fccfbc3f8018d5f6963ed478eea0
|
||||
F test/trace2.test 93b47ca6996c66b47f57224cfb146f34e07df382
|
||||
F test/trace2.test f5cb67ad3bc09e0c58e8cca78dfd0b5639259983
|
||||
F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6
|
||||
F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76
|
||||
F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94
|
||||
@@ -1087,7 +1092,7 @@ F test/trigger8.test 30cb0530bd7c4728055420e3f739aa00412eafa4
|
||||
F test/trigger9.test 2226ec795a33b0460ab5cf8891e9054cc7edef41
|
||||
F test/triggerA.test fe5597f47ee21bacb4936dc827994ed94161e332
|
||||
F test/triggerB.test 56780c031b454abac2340dbb3b71ac5c56c3d7fe
|
||||
F test/triggerC.test a68980c5955d62ee24be6f97129d824f199f9a4c
|
||||
F test/triggerC.test 302d8995f5ffe63bbc15053abb3ef7a39cf5a092
|
||||
F test/triggerD.test 8e7f3921a92a5797d472732108109e44575fa650
|
||||
F test/triggerE.test 355e9c5cbaed5cd039a60baad1fb2197caeb8e52
|
||||
F test/tt3_checkpoint.c 9e75cf7c1c364f52e1c47fd0f14c4340a9db0fe1
|
||||
@@ -1113,7 +1118,7 @@ F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9
|
||||
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
|
||||
F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
|
||||
F test/view.test f311691d696a5cc27e3c1b875cec1b0866b4ccd9
|
||||
F test/vtab1.test c9dc2a73e93331d70b37ce4b246ef6dc18412fef
|
||||
F test/vtab1.test d1e5ec7a818f1d3f0402382b6a1d0c06071b770f
|
||||
F test/vtab2.test 3644649aa8d1daac57fd541f6a5f914cac59203e
|
||||
F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e
|
||||
F test/vtab4.test 942f8b8280b3ea8a41dae20e7822d065ca1cb275
|
||||
@@ -1122,7 +1127,7 @@ F test/vtab6.test 5f5380c425e52993560ab4763db4f826d2ba7b09
|
||||
F test/vtab7.test ae560ebea870ed04e9aa4177cc302f910faaabb5
|
||||
F test/vtab8.test e19fa4a538fcd1bb66c22825fa8f71618fb13583
|
||||
F test/vtab9.test ea58d2b95d61955f87226381716b2d0b1d4e4f9b
|
||||
F test/vtabA.test c86e1990b7e1e2bb34602a06fffa4c69f2b516dc
|
||||
F test/vtabA.test 1317f06a03597eee29f40a49b6c21e1aaba4285f
|
||||
F test/vtabB.test 04df5dc531b9f44d9ca65b9c1b79f12b5922a796
|
||||
F test/vtabC.test 4528f459a13136f982e75614d120aef165f17292
|
||||
F test/vtabD.test 05b3f1d77117271671089e48719524b676842e96
|
||||
@@ -1196,17 +1201,18 @@ F test/without_rowid6.test db0dbf03c49030aa3c1ba5f618620334bd2baf5f
|
||||
F test/wordcount.c 9915e06cb33d8ca8109b8700791afe80d305afda
|
||||
F test/zeroblob.test fb3c0e4ab172d386954deda24c03f500e121d80d
|
||||
F test/zerodamage.test cf6748bad89553cc1632be51a6f54e487e4039ac
|
||||
F tool/build-all-msvc.bat 72e05bc8deca39a547884485c086b915f50a91ed x
|
||||
F tool/build-all-msvc.bat 9058bd90a3c078a3d8c17d40e853aaa0f47885f4 x
|
||||
F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367
|
||||
F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2
|
||||
F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b
|
||||
F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2
|
||||
F tool/fast_vacuum.c 5ba0d6f5963a0a63bdc42840f678bad75b2ebce1
|
||||
F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439
|
||||
F tool/fuzzershell.c beafb3f10b02fedab02d364054290d93cfa42c8e
|
||||
F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4
|
||||
F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5
|
||||
F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
|
||||
F tool/lemon.c ae5f61e3b164d35955777b20d6febcbaf0950702
|
||||
F tool/lemon.c b9109f59b57e7b6f101c4fe644c8361ba6dee969
|
||||
F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc
|
||||
F tool/logest.c eef612f8adf4d0993dafed0416064cf50d5d33c6
|
||||
F tool/mkautoconfamal.sh d1a2da0e15b2ed33d60af35c7e9d483f13a8eb9f
|
||||
@@ -1218,7 +1224,7 @@ F tool/mksqlite3c-noext.tcl 69bae8ce4aa52d2ff82d4a8a856bf283ec035b2e
|
||||
F tool/mksqlite3c.tcl 52a3352f7aa15f1db851e45ac3a5e2173d6fe93c
|
||||
F tool/mksqlite3h.tcl 44730d586c9031638cdd2eb443b801c0d2dbd9f8
|
||||
F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b
|
||||
F tool/mkvsix.tcl 52a4c613707ac34ae9c226e5ccc69cb948556105
|
||||
F tool/mkvsix.tcl 3b58b9398f91c7dbf18d49eb87cefeee9efdbce1
|
||||
F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091
|
||||
F tool/omittest.tcl 34d7ac01fe4fd18e3637f64abe12c40eca0f6b97
|
||||
F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
|
||||
@@ -1239,7 +1245,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||
F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c
|
||||
F tool/sqldiff.c 5c16cf3a1f566873abbdecac0d13a6691437564f
|
||||
F tool/sqldiff.c 8999f959c2305a908b50e44bc636bdbfe04aa06c
|
||||
F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43
|
||||
F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d
|
||||
F tool/symbols.sh fec58532668296d7c7dc48be9c87f75ccdb5814f
|
||||
@@ -1250,7 +1256,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P e018f4bf1f27f7838342940ad89a12d7f1536e8e
|
||||
R 9772cd879deb52a3e48d7b6cb0b29092
|
||||
P 803cb60e75e0b09a526eefec11139cb3e8ae8c7c
|
||||
R 67f13f2b14c81a78caffdc6aae1db680
|
||||
T *branch * limit-printf-width
|
||||
T *sym-limit-printf-width *
|
||||
T -sym-trunk *
|
||||
U drh
|
||||
Z 089490261a72224f9edd48b4acf9b866
|
||||
Z 231851b453c464ec61b44da5b9128378
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
d3c00d61581c8ba6dce5618391432d3af8d324d4
|
||||
f8b159794c3855cad86d755cc7422ddc21722200
|
||||
@@ -126,6 +126,7 @@ static void renameParentFunc(
|
||||
n = sqlite3GetToken(z, &token);
|
||||
}while( token==TK_SPACE );
|
||||
|
||||
if( token==TK_ILLEGAL ) break;
|
||||
zParent = sqlite3DbStrNDup(db, (const char *)z, n);
|
||||
if( zParent==0 ) break;
|
||||
sqlite3Dequote(zParent);
|
||||
|
||||
+9
-6
@@ -1519,14 +1519,17 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
|
||||
z = argv[2];
|
||||
|
||||
if( pIndex ){
|
||||
tRowcnt *aiRowEst = 0;
|
||||
int nCol = pIndex->nKeyCol+1;
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
tRowcnt * const aiRowEst = pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(
|
||||
sizeof(tRowcnt) * nCol
|
||||
);
|
||||
if( aiRowEst==0 ) pInfo->db->mallocFailed = 1;
|
||||
#else
|
||||
tRowcnt * const aiRowEst = 0;
|
||||
/* Index.aiRowEst may already be set here if there are duplicate
|
||||
** sqlite_stat1 entries for this index. In that case just clobber
|
||||
** the old data with the new instead of allocating a new array. */
|
||||
if( pIndex->aiRowEst==0 ){
|
||||
pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(sizeof(tRowcnt) * nCol);
|
||||
if( pIndex->aiRowEst==0 ) pInfo->db->mallocFailed = 1;
|
||||
}
|
||||
aiRowEst = pIndex->aiRowEst;
|
||||
#endif
|
||||
pIndex->bUnordered = 0;
|
||||
decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex);
|
||||
|
||||
@@ -332,7 +332,6 @@ static void codeAttach(
|
||||
SQLITE_OK!=(rc = resolveAttachExpr(&sName, pDbname)) ||
|
||||
SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey))
|
||||
){
|
||||
pParse->nErr++;
|
||||
goto attach_end;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -341,7 +341,7 @@ int sqlite3BitvecBuiltinTest(int sz, int *aOp){
|
||||
** bits to act as the reference */
|
||||
pBitvec = sqlite3BitvecCreate( sz );
|
||||
pV = sqlite3MallocZero( (sz+7)/8 + 1 );
|
||||
pTmpSpace = sqlite3_malloc(BITVEC_SZ);
|
||||
pTmpSpace = sqlite3_malloc64(BITVEC_SZ);
|
||||
if( pBitvec==0 || pV==0 || pTmpSpace==0 ) goto bitvec_end;
|
||||
|
||||
/* NULL pBitvec tests */
|
||||
|
||||
+73
-17
@@ -8528,6 +8528,57 @@ static void checkList(
|
||||
}
|
||||
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
|
||||
|
||||
/*
|
||||
** An implementation of a min-heap.
|
||||
**
|
||||
** aHeap[0] is the number of elements on the heap. aHeap[1] is the
|
||||
** root element. The daughter nodes of aHeap[N] are aHeap[N*2]
|
||||
** and aHeap[N*2+1].
|
||||
**
|
||||
** The heap property is this: Every node is less than or equal to both
|
||||
** of its daughter nodes. A consequence of the heap property is that the
|
||||
** root node aHeap[1] is always the minimum value currently in the heap.
|
||||
**
|
||||
** The btreeHeapInsert() routine inserts an unsigned 32-bit number onto
|
||||
** the heap, preserving the heap property. The btreeHeapPull() routine
|
||||
** removes the root element from the heap (the minimum value in the heap)
|
||||
** and then moves other nodes around as necessary to preserve the heap
|
||||
** property.
|
||||
**
|
||||
** This heap is used for cell overlap and coverage testing. Each u32
|
||||
** entry represents the span of a cell or freeblock on a btree page.
|
||||
** The upper 16 bits are the index of the first byte of a range and the
|
||||
** lower 16 bits are the index of the last byte of that range.
|
||||
*/
|
||||
static void btreeHeapInsert(u32 *aHeap, u32 x){
|
||||
u32 j, i = ++aHeap[0];
|
||||
aHeap[i] = x;
|
||||
while( (j = i/2)>0 && aHeap[j]>aHeap[i] ){
|
||||
x = aHeap[j];
|
||||
aHeap[j] = aHeap[i];
|
||||
aHeap[i] = x;
|
||||
i = j;
|
||||
}
|
||||
}
|
||||
static int btreeHeapPull(u32 *aHeap, u32 *pOut){
|
||||
u32 j, i, x;
|
||||
if( (x = aHeap[0])==0 ) return 0;
|
||||
*pOut = aHeap[1];
|
||||
aHeap[1] = aHeap[x];
|
||||
aHeap[x] = 0xffffffff;
|
||||
aHeap[0]--;
|
||||
i = 1;
|
||||
while( (j = i*2)<=aHeap[0] ){
|
||||
if( aHeap[j]>aHeap[j+1] ) j++;
|
||||
if( aHeap[i]<aHeap[j] ) break;
|
||||
x = aHeap[i];
|
||||
aHeap[i] = aHeap[j];
|
||||
aHeap[j] = x;
|
||||
i = j;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_INTEGRITY_CHECK
|
||||
/*
|
||||
** Do various sanity checks on a single page of a tree. Return
|
||||
@@ -8560,7 +8611,8 @@ static int checkTreePage(
|
||||
u8 *data;
|
||||
BtShared *pBt;
|
||||
int usableSize;
|
||||
char *hit = 0;
|
||||
u32 *heap = 0;
|
||||
u32 x, prev = 0;
|
||||
i64 nMinKey = 0;
|
||||
i64 nMaxKey = 0;
|
||||
const char *saved_zPfx = pCheck->zPfx;
|
||||
@@ -8705,15 +8757,15 @@ static int checkTreePage(
|
||||
*/
|
||||
data = pPage->aData;
|
||||
hdr = pPage->hdrOffset;
|
||||
hit = sqlite3PageMalloc( pBt->pageSize );
|
||||
heap = (u32*)sqlite3PageMalloc( pBt->pageSize );
|
||||
pCheck->zPfx = 0;
|
||||
if( hit==0 ){
|
||||
if( heap==0 ){
|
||||
pCheck->mallocFailed = 1;
|
||||
}else{
|
||||
int contentOffset = get2byteNotZero(&data[hdr+5]);
|
||||
assert( contentOffset<=usableSize ); /* Enforced by btreeInitPage() */
|
||||
memset(hit+contentOffset, 0, usableSize-contentOffset);
|
||||
memset(hit, 1, contentOffset);
|
||||
heap[0] = 0;
|
||||
btreeHeapInsert(heap, contentOffset-1);
|
||||
/* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the
|
||||
** number of cells on the page. */
|
||||
nCell = get2byte(&data[hdr+3]);
|
||||
@@ -8725,7 +8777,6 @@ static int checkTreePage(
|
||||
for(i=0; i<nCell; i++){
|
||||
int pc = get2byte(&data[cellStart+i*2]);
|
||||
u32 size = 65536;
|
||||
int j;
|
||||
if( pc<=usableSize-4 ){
|
||||
size = cellSizePtr(pPage, &data[pc]);
|
||||
}
|
||||
@@ -8734,7 +8785,7 @@ static int checkTreePage(
|
||||
checkAppendMsg(pCheck,
|
||||
"Corruption detected in cell %d on page %d",i,iPage);
|
||||
}else{
|
||||
for(j=pc+size-1; j>=pc; j--) hit[j]++;
|
||||
btreeHeapInsert(heap, (pc<<16)|(pc+size-1));
|
||||
}
|
||||
}
|
||||
/* EVIDENCE-OF: R-20690-50594 The second field of the b-tree page header
|
||||
@@ -8746,7 +8797,7 @@ static int checkTreePage(
|
||||
assert( i<=usableSize-4 ); /* Enforced by btreeInitPage() */
|
||||
size = get2byte(&data[i+2]);
|
||||
assert( i+size<=usableSize ); /* Enforced by btreeInitPage() */
|
||||
for(j=i+size-1; j>=i; j--) hit[j]++;
|
||||
btreeHeapInsert(heap, (i<<16)|(i+size-1));
|
||||
/* EVIDENCE-OF: R-58208-19414 The first 2 bytes of a freeblock are a
|
||||
** big-endian integer which is the offset in the b-tree page of the next
|
||||
** freeblock in the chain, or zero if the freeblock is the last on the
|
||||
@@ -8758,27 +8809,33 @@ static int checkTreePage(
|
||||
assert( j<=usableSize-4 ); /* Enforced by btreeInitPage() */
|
||||
i = j;
|
||||
}
|
||||
for(i=cnt=0; i<usableSize; i++){
|
||||
if( hit[i]==0 ){
|
||||
cnt++;
|
||||
}else if( hit[i]>1 ){
|
||||
cnt = 0;
|
||||
assert( heap[0]>0 );
|
||||
assert( (heap[1]>>16)==0 );
|
||||
btreeHeapPull(heap,&prev);
|
||||
while( btreeHeapPull(heap,&x) ){
|
||||
if( (prev&0xffff)+1>(x>>16) ){
|
||||
checkAppendMsg(pCheck,
|
||||
"Multiple uses for byte %d of page %d", i, iPage);
|
||||
"Multiple uses for byte %u of page %d", x>>16, iPage);
|
||||
break;
|
||||
}else{
|
||||
cnt += (x>>16) - (prev&0xffff) - 1;
|
||||
prev = x;
|
||||
}
|
||||
}
|
||||
cnt += usableSize - (prev&0xffff) - 1;
|
||||
/* EVIDENCE-OF: R-43263-13491 The total number of bytes in all fragments
|
||||
** is stored in the fifth field of the b-tree page header.
|
||||
** EVIDENCE-OF: R-07161-27322 The one-byte integer at offset 7 gives the
|
||||
** number of fragmented free bytes within the cell content area.
|
||||
*/
|
||||
if( cnt!=data[hdr+7] ){
|
||||
if( heap[0]==0 && cnt!=data[hdr+7] ){
|
||||
checkAppendMsg(pCheck,
|
||||
"Fragmentation of %d bytes reported as %d on page %d",
|
||||
cnt, data[hdr+7], iPage);
|
||||
}
|
||||
}
|
||||
sqlite3PageFree(hit);
|
||||
sqlite3PageFree(heap);
|
||||
releasePage(pPage);
|
||||
|
||||
end_of_check:
|
||||
@@ -8842,8 +8899,7 @@ char *sqlite3BtreeIntegrityCheck(
|
||||
}
|
||||
i = PENDING_BYTE_PAGE(pBt);
|
||||
if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i);
|
||||
sqlite3StrAccumInit(&sCheck.errMsg, zErr, sizeof(zErr), SQLITE_MAX_LENGTH);
|
||||
sCheck.errMsg.useMalloc = 2;
|
||||
sqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), SQLITE_MAX_LENGTH);
|
||||
|
||||
/* Check the integrity of the freelist
|
||||
*/
|
||||
|
||||
+10
-10
@@ -142,9 +142,11 @@ void sqlite3FinishCoding(Parse *pParse){
|
||||
|
||||
assert( pParse->pToplevel==0 );
|
||||
db = pParse->db;
|
||||
if( db->mallocFailed ) return;
|
||||
if( pParse->nested ) return;
|
||||
if( pParse->nErr ) return;
|
||||
if( db->mallocFailed || pParse->nErr ){
|
||||
if( pParse->rc==SQLITE_OK ) pParse->rc = SQLITE_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Begin by generating some termination code at the end of the
|
||||
** vdbe program
|
||||
@@ -761,14 +763,12 @@ int sqlite3TwoPartName(
|
||||
if( ALWAYS(pName2!=0) && pName2->n>0 ){
|
||||
if( db->init.busy ) {
|
||||
sqlite3ErrorMsg(pParse, "corrupt database");
|
||||
pParse->nErr++;
|
||||
return -1;
|
||||
}
|
||||
*pUnqual = pName2;
|
||||
iDb = sqlite3FindDb(db, pName1);
|
||||
if( iDb<0 ){
|
||||
sqlite3ErrorMsg(pParse, "unknown database %T", pName1);
|
||||
pParse->nErr++;
|
||||
return -1;
|
||||
}
|
||||
}else{
|
||||
@@ -927,7 +927,7 @@ void sqlite3StartTable(
|
||||
if( !noErr ){
|
||||
sqlite3ErrorMsg(pParse, "table %T already exists", pName);
|
||||
}else{
|
||||
assert( !db->init.busy );
|
||||
assert( !db->init.busy || CORRUPT_DB );
|
||||
sqlite3CodeVerifySchema(pParse, iDb);
|
||||
}
|
||||
goto begin_table_error;
|
||||
@@ -1216,7 +1216,8 @@ void sqlite3AddColumnType(Parse *pParse, Token *pType){
|
||||
p = pParse->pNewTable;
|
||||
if( p==0 || NEVER(p->nCol<1) ) return;
|
||||
pCol = &p->aCol[p->nCol-1];
|
||||
assert( pCol->zType==0 );
|
||||
assert( pCol->zType==0 || CORRUPT_DB );
|
||||
sqlite3DbFree(pParse->db, pCol->zType);
|
||||
pCol->zType = sqlite3NameFromToken(pParse->db, pType);
|
||||
pCol->affinity = sqlite3AffinityType(pCol->zType, &pCol->szEst);
|
||||
}
|
||||
@@ -2450,6 +2451,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
|
||||
}
|
||||
assert( pParse->nErr==0 );
|
||||
assert( pName->nSrc==1 );
|
||||
if( sqlite3ReadSchema(pParse) ) goto exit_drop_table;
|
||||
if( noErr ) db->suppressErr++;
|
||||
pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]);
|
||||
if( noErr ) db->suppressErr--;
|
||||
@@ -2857,8 +2859,7 @@ Index *sqlite3CreateIndex(
|
||||
char *zExtra = 0; /* Extra space after the Index object */
|
||||
Index *pPk = 0; /* PRIMARY KEY index for WITHOUT ROWID tables */
|
||||
|
||||
assert( pParse->nErr==0 ); /* Never called with prior errors */
|
||||
if( db->mallocFailed || IN_DECLARE_VTAB ){
|
||||
if( db->mallocFailed || IN_DECLARE_VTAB || pParse->nErr>0 ){
|
||||
goto exit_create_index;
|
||||
}
|
||||
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
|
||||
@@ -4023,8 +4024,7 @@ void sqlite3UniqueConstraint(
|
||||
StrAccum errMsg;
|
||||
Table *pTab = pIdx->pTable;
|
||||
|
||||
sqlite3StrAccumInit(&errMsg, 0, 0, 200);
|
||||
errMsg.db = pParse->db;
|
||||
sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 200);
|
||||
for(j=0; j<pIdx->nKeyCol; j++){
|
||||
char *zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
|
||||
if( j ) sqlite3StrAccumAppend(&errMsg, ", ", 2);
|
||||
|
||||
+5
-4
@@ -1251,7 +1251,8 @@ u32 sqlite3ExprListFlags(const ExprList *pList){
|
||||
u32 m = 0;
|
||||
if( pList ){
|
||||
for(i=0; i<pList->nExpr; i++){
|
||||
m |= pList->a[i].pExpr->flags;
|
||||
Expr *pExpr = pList->a[i].pExpr;
|
||||
if( ALWAYS(pExpr) ) m |= pList->a[i].pExpr->flags;
|
||||
}
|
||||
}
|
||||
return m;
|
||||
@@ -2016,7 +2017,7 @@ int sqlite3CodeSubselect(
|
||||
pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0,
|
||||
&sqlite3IntTokens[1]);
|
||||
pSel->iLimit = 0;
|
||||
pSel->selFlags &= ~SF_AllValues;
|
||||
pSel->selFlags &= ~SF_MultiValue;
|
||||
if( sqlite3Select(pParse, pSel, &dest) ){
|
||||
return 0;
|
||||
}
|
||||
@@ -3382,7 +3383,7 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
|
||||
break;
|
||||
}
|
||||
case TK_ID: {
|
||||
sqlite3TreeViewLine(pView,"ID %Q", pExpr->u.zToken);
|
||||
sqlite3TreeViewLine(pView,"ID \"%w\"", pExpr->u.zToken);
|
||||
break;
|
||||
}
|
||||
#ifndef SQLITE_OMIT_CAST
|
||||
@@ -4017,7 +4018,7 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){
|
||||
if( sqlite3ExprCompare(pA->pLeft, pB->pLeft, iTab) ) return 2;
|
||||
if( sqlite3ExprCompare(pA->pRight, pB->pRight, iTab) ) return 2;
|
||||
if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2;
|
||||
if( ALWAYS((combinedFlags & EP_Reduced)==0) ){
|
||||
if( ALWAYS((combinedFlags & EP_Reduced)==0) && pA->op!=TK_STRING ){
|
||||
if( pA->iColumn!=pB->iColumn ) return 2;
|
||||
if( pA->iTable!=pB->iTable
|
||||
&& (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
|
||||
|
||||
+12
-13
@@ -1197,10 +1197,10 @@ static Trigger *fkActionTrigger(
|
||||
** parent table are used for the comparison. */
|
||||
pEq = sqlite3PExpr(pParse, TK_EQ,
|
||||
sqlite3PExpr(pParse, TK_DOT,
|
||||
sqlite3PExpr(pParse, TK_ID, 0, 0, &tOld),
|
||||
sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol)
|
||||
sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
|
||||
sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)
|
||||
, 0),
|
||||
sqlite3PExpr(pParse, TK_ID, 0, 0, &tFromCol)
|
||||
sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0)
|
||||
, 0);
|
||||
pWhere = sqlite3ExprAnd(db, pWhere, pEq);
|
||||
|
||||
@@ -1212,12 +1212,12 @@ static Trigger *fkActionTrigger(
|
||||
if( pChanges ){
|
||||
pEq = sqlite3PExpr(pParse, TK_IS,
|
||||
sqlite3PExpr(pParse, TK_DOT,
|
||||
sqlite3PExpr(pParse, TK_ID, 0, 0, &tOld),
|
||||
sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol),
|
||||
sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
|
||||
sqlite3ExprAlloc(db, TK_ID, &tToCol, 0),
|
||||
0),
|
||||
sqlite3PExpr(pParse, TK_DOT,
|
||||
sqlite3PExpr(pParse, TK_ID, 0, 0, &tNew),
|
||||
sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol),
|
||||
sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
|
||||
sqlite3ExprAlloc(db, TK_ID, &tToCol, 0),
|
||||
0),
|
||||
0);
|
||||
pWhen = sqlite3ExprAnd(db, pWhen, pEq);
|
||||
@@ -1227,8 +1227,8 @@ static Trigger *fkActionTrigger(
|
||||
Expr *pNew;
|
||||
if( action==OE_Cascade ){
|
||||
pNew = sqlite3PExpr(pParse, TK_DOT,
|
||||
sqlite3PExpr(pParse, TK_ID, 0, 0, &tNew),
|
||||
sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol)
|
||||
sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
|
||||
sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)
|
||||
, 0);
|
||||
}else if( action==OE_SetDflt ){
|
||||
Expr *pDflt = pFKey->pFrom->aCol[iFromCol].pDflt;
|
||||
@@ -1275,13 +1275,12 @@ static Trigger *fkActionTrigger(
|
||||
pTrigger = (Trigger *)sqlite3DbMallocZero(db,
|
||||
sizeof(Trigger) + /* struct Trigger */
|
||||
sizeof(TriggerStep) + /* Single step in trigger program */
|
||||
nFrom + 1 /* Space for pStep->target.z */
|
||||
nFrom + 1 /* Space for pStep->zTarget */
|
||||
);
|
||||
if( pTrigger ){
|
||||
pStep = pTrigger->step_list = (TriggerStep *)&pTrigger[1];
|
||||
pStep->target.z = (char *)&pStep[1];
|
||||
pStep->target.n = nFrom;
|
||||
memcpy((char *)pStep->target.z, zFrom, nFrom);
|
||||
pStep->zTarget = (char *)&pStep[1];
|
||||
memcpy((char *)pStep->zTarget, zFrom, nFrom);
|
||||
|
||||
pStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
|
||||
pStep->pExprList = sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE);
|
||||
|
||||
+14
-10
@@ -231,18 +231,23 @@ static void printfFunc(
|
||||
PrintfArguments x;
|
||||
StrAccum str;
|
||||
const char *zFormat;
|
||||
int n;
|
||||
sqlite3 *db = sqlite3_context_db_handle(context);
|
||||
|
||||
if( argc>=1 && (zFormat = (const char*)sqlite3_value_text(argv[0]))!=0 ){
|
||||
x.nArg = argc-1;
|
||||
x.nUsed = 0;
|
||||
x.apArg = argv+1;
|
||||
sqlite3StrAccumInit(&str, 0, 0, SQLITE_MAX_LENGTH);
|
||||
str.db = sqlite3_context_db_handle(context);
|
||||
sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]);
|
||||
sqlite3XPrintf(&str, SQLITE_PRINTF_SQLFUNC, zFormat, &x);
|
||||
n = str.nChar;
|
||||
sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n,
|
||||
sqlite3_result_text(context, sqlite3StrAccumFinish(&str), str.nChar,
|
||||
SQLITE_DYNAMIC);
|
||||
if( str.accError ){
|
||||
if( str.accError==STRACCUM_NOMEM ){
|
||||
sqlite3_result_error_nomem(context);
|
||||
}else{
|
||||
sqlite3_result_error_toobig(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -388,7 +393,7 @@ static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Allocate nByte bytes of space using sqlite3_malloc(). If the
|
||||
** Allocate nByte bytes of space using sqlite3Malloc(). If the
|
||||
** allocation fails, call sqlite3_result_error_nomem() to notify
|
||||
** the database handle that malloc() has failed and return NULL.
|
||||
** If nByte is larger than the maximum string or blob length, then
|
||||
@@ -1057,7 +1062,7 @@ static void charFunc(
|
||||
){
|
||||
unsigned char *z, *zOut;
|
||||
int i;
|
||||
zOut = z = sqlite3_malloc( argc*4+1 );
|
||||
zOut = z = sqlite3_malloc64( argc*4+1 );
|
||||
if( z==0 ){
|
||||
sqlite3_result_error_nomem(context);
|
||||
return;
|
||||
@@ -1205,7 +1210,7 @@ static void replaceFunc(
|
||||
return;
|
||||
}
|
||||
zOld = zOut;
|
||||
zOut = sqlite3_realloc(zOut, (int)nOut);
|
||||
zOut = sqlite3_realloc64(zOut, (int)nOut);
|
||||
if( zOut==0 ){
|
||||
sqlite3_result_error_nomem(context);
|
||||
sqlite3_free(zOld);
|
||||
@@ -1567,8 +1572,7 @@ static void groupConcatStep(
|
||||
|
||||
if( pAccum ){
|
||||
sqlite3 *db = sqlite3_context_db_handle(context);
|
||||
int firstTerm = pAccum->useMalloc==0;
|
||||
pAccum->useMalloc = 2;
|
||||
int firstTerm = pAccum->mxAlloc==0;
|
||||
pAccum->mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH];
|
||||
if( !firstTerm ){
|
||||
if( argc==2 ){
|
||||
|
||||
+20
-17
@@ -342,20 +342,23 @@ static int xferOptimization(
|
||||
/*
|
||||
** This routine is called to handle SQL of the following forms:
|
||||
**
|
||||
** insert into TABLE (IDLIST) values(EXPRLIST)
|
||||
** insert into TABLE (IDLIST) values(EXPRLIST),(EXPRLIST),...
|
||||
** insert into TABLE (IDLIST) select
|
||||
** insert into TABLE (IDLIST) default values
|
||||
**
|
||||
** The IDLIST following the table name is always optional. If omitted,
|
||||
** then a list of all columns for the table is substituted. The IDLIST
|
||||
** appears in the pColumn parameter. pColumn is NULL if IDLIST is omitted.
|
||||
** then a list of all (non-hidden) columns for the table is substituted.
|
||||
** The IDLIST appears in the pColumn parameter. pColumn is NULL if IDLIST
|
||||
** is omitted.
|
||||
**
|
||||
** The pList parameter holds EXPRLIST in the first form of the INSERT
|
||||
** statement above, and pSelect is NULL. For the second form, pList is
|
||||
** NULL and pSelect is a pointer to the select statement used to generate
|
||||
** data for the insert.
|
||||
** For the pSelect parameter holds the values to be inserted for the
|
||||
** first two forms shown above. A VALUES clause is really just short-hand
|
||||
** for a SELECT statement that omits the FROM clause and everything else
|
||||
** that follows. If the pSelect parameter is NULL, that means that the
|
||||
** DEFAULT VALUES form of the INSERT statement is intended.
|
||||
**
|
||||
** The code generated follows one of four templates. For a simple
|
||||
** insert with data coming from a VALUES clause, the code executes
|
||||
** insert with data coming from a single-row VALUES clause, the code executes
|
||||
** once straight down through. Pseudo-code follows (we call this
|
||||
** the "1st template"):
|
||||
**
|
||||
@@ -462,7 +465,7 @@ void sqlite3Insert(
|
||||
u8 useTempTable = 0; /* Store SELECT results in intermediate table */
|
||||
u8 appendFlag = 0; /* True if the insert is likely to be an append */
|
||||
u8 withoutRowid; /* 0 for normal table. 1 for WITHOUT ROWID table */
|
||||
u8 bIdListInOrder = 1; /* True if IDLIST is in table order */
|
||||
u8 bIdListInOrder; /* True if IDLIST is in table order */
|
||||
ExprList *pList = 0; /* List of VALUES() to be inserted */
|
||||
|
||||
/* Register allocations */
|
||||
@@ -487,8 +490,8 @@ void sqlite3Insert(
|
||||
}
|
||||
|
||||
/* If the Select object is really just a simple VALUES() list with a
|
||||
** single row values (the common case) then keep that one row of values
|
||||
** and go ahead and discard the Select object
|
||||
** single row (the common case) then keep that one row of values
|
||||
** and discard the other (unused) parts of the pSelect object
|
||||
*/
|
||||
if( pSelect && (pSelect->selFlags & SF_Values)!=0 && pSelect->pPrior==0 ){
|
||||
pList = pSelect->pEList;
|
||||
@@ -596,6 +599,7 @@ void sqlite3Insert(
|
||||
** is appears in the original table. (The index of the INTEGER
|
||||
** PRIMARY KEY in the original table is pTab->iPKey.)
|
||||
*/
|
||||
bIdListInOrder = (pTab->tabFlags & TF_OOOHidden)==0;
|
||||
if( pColumn ){
|
||||
for(i=0; i<pColumn->nId; i++){
|
||||
pColumn->a[i].idx = -1;
|
||||
@@ -631,7 +635,8 @@ void sqlite3Insert(
|
||||
** co-routine is the common header to the 3rd and 4th templates.
|
||||
*/
|
||||
if( pSelect ){
|
||||
/* Data is coming from a SELECT. Generate a co-routine to run the SELECT */
|
||||
/* Data is coming from a SELECT or from a multi-row VALUES clause.
|
||||
** Generate a co-routine to run the SELECT. */
|
||||
int regYield; /* Register holding co-routine entry-point */
|
||||
int addrTop; /* Top of the co-routine */
|
||||
int rc; /* Result code */
|
||||
@@ -644,8 +649,7 @@ void sqlite3Insert(
|
||||
dest.nSdst = pTab->nCol;
|
||||
rc = sqlite3Select(pParse, pSelect, &dest);
|
||||
regFromSelect = dest.iSdst;
|
||||
assert( pParse->nErr==0 || rc );
|
||||
if( rc || db->mallocFailed ) goto insert_cleanup;
|
||||
if( rc || db->mallocFailed || pParse->nErr ) goto insert_cleanup;
|
||||
sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield);
|
||||
sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */
|
||||
assert( pSelect->pEList );
|
||||
@@ -693,8 +697,8 @@ void sqlite3Insert(
|
||||
sqlite3ReleaseTempReg(pParse, regTempRowid);
|
||||
}
|
||||
}else{
|
||||
/* This is the case if the data for the INSERT is coming from a VALUES
|
||||
** clause
|
||||
/* This is the case if the data for the INSERT is coming from a
|
||||
** single-row VALUES clause
|
||||
*/
|
||||
NameContext sNC;
|
||||
memset(&sNC, 0, sizeof(sNC));
|
||||
@@ -2021,7 +2025,6 @@ static int xferOptimization(
|
||||
** might change the definition of a collation sequence and then run
|
||||
** a VACUUM command. In that case keys may not be written in strictly
|
||||
** sorted order. */
|
||||
int i;
|
||||
for(i=0; i<pSrcIdx->nColumn; i++){
|
||||
char *zColl = pSrcIdx->azColl[i];
|
||||
assert( zColl!=0 );
|
||||
|
||||
+10
-10
@@ -430,7 +430,7 @@ static int sqlite3LoadExtension(
|
||||
const char *zEntry;
|
||||
char *zAltEntry = 0;
|
||||
void **aHandle;
|
||||
int nMsg = 300 + sqlite3Strlen30(zFile);
|
||||
u64 nMsg = 300 + sqlite3Strlen30(zFile);
|
||||
int ii;
|
||||
|
||||
/* Shared library endings to try if zFile cannot be loaded as written */
|
||||
@@ -473,7 +473,7 @@ static int sqlite3LoadExtension(
|
||||
#endif
|
||||
if( handle==0 ){
|
||||
if( pzErrMsg ){
|
||||
*pzErrMsg = zErrmsg = sqlite3_malloc(nMsg);
|
||||
*pzErrMsg = zErrmsg = sqlite3_malloc64(nMsg);
|
||||
if( zErrmsg ){
|
||||
sqlite3_snprintf(nMsg, zErrmsg,
|
||||
"unable to open shared library [%s]", zFile);
|
||||
@@ -499,7 +499,7 @@ static int sqlite3LoadExtension(
|
||||
if( xInit==0 && zProc==0 ){
|
||||
int iFile, iEntry, c;
|
||||
int ncFile = sqlite3Strlen30(zFile);
|
||||
zAltEntry = sqlite3_malloc(ncFile+30);
|
||||
zAltEntry = sqlite3_malloc64(ncFile+30);
|
||||
if( zAltEntry==0 ){
|
||||
sqlite3OsDlClose(pVfs, handle);
|
||||
return SQLITE_NOMEM;
|
||||
@@ -521,7 +521,7 @@ static int sqlite3LoadExtension(
|
||||
if( xInit==0 ){
|
||||
if( pzErrMsg ){
|
||||
nMsg += sqlite3Strlen30(zEntry);
|
||||
*pzErrMsg = zErrmsg = sqlite3_malloc(nMsg);
|
||||
*pzErrMsg = zErrmsg = sqlite3_malloc64(nMsg);
|
||||
if( zErrmsg ){
|
||||
sqlite3_snprintf(nMsg, zErrmsg,
|
||||
"no entry point [%s] in shared library [%s]", zEntry, zFile);
|
||||
@@ -620,7 +620,7 @@ static const sqlite3_api_routines sqlite3Apis = { 0 };
|
||||
*/
|
||||
typedef struct sqlite3AutoExtList sqlite3AutoExtList;
|
||||
static SQLITE_WSD struct sqlite3AutoExtList {
|
||||
int nExt; /* Number of entries in aExt[] */
|
||||
u32 nExt; /* Number of entries in aExt[] */
|
||||
void (**aExt)(void); /* Pointers to the extension init functions */
|
||||
} sqlite3Autoext = { 0, 0 };
|
||||
|
||||
@@ -653,7 +653,7 @@ int sqlite3_auto_extension(void (*xInit)(void)){
|
||||
}else
|
||||
#endif
|
||||
{
|
||||
int i;
|
||||
u32 i;
|
||||
#if SQLITE_THREADSAFE
|
||||
sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
|
||||
#endif
|
||||
@@ -663,9 +663,9 @@ int sqlite3_auto_extension(void (*xInit)(void)){
|
||||
if( wsdAutoext.aExt[i]==xInit ) break;
|
||||
}
|
||||
if( i==wsdAutoext.nExt ){
|
||||
int nByte = (wsdAutoext.nExt+1)*sizeof(wsdAutoext.aExt[0]);
|
||||
u64 nByte = (wsdAutoext.nExt+1)*sizeof(wsdAutoext.aExt[0]);
|
||||
void (**aNew)(void);
|
||||
aNew = sqlite3_realloc(wsdAutoext.aExt, nByte);
|
||||
aNew = sqlite3_realloc64(wsdAutoext.aExt, nByte);
|
||||
if( aNew==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
@@ -697,7 +697,7 @@ int sqlite3_cancel_auto_extension(void (*xInit)(void)){
|
||||
int n = 0;
|
||||
wsdAutoextInit;
|
||||
sqlite3_mutex_enter(mutex);
|
||||
for(i=wsdAutoext.nExt-1; i>=0; i--){
|
||||
for(i=(int)wsdAutoext.nExt-1; i>=0; i--){
|
||||
if( wsdAutoext.aExt[i]==xInit ){
|
||||
wsdAutoext.nExt--;
|
||||
wsdAutoext.aExt[i] = wsdAutoext.aExt[wsdAutoext.nExt];
|
||||
@@ -735,7 +735,7 @@ void sqlite3_reset_auto_extension(void){
|
||||
** If anything goes wrong, set an error in the database connection.
|
||||
*/
|
||||
void sqlite3AutoLoadExtensions(sqlite3 *db){
|
||||
int i;
|
||||
u32 i;
|
||||
int go = 1;
|
||||
int rc;
|
||||
int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
|
||||
|
||||
+20
-5
@@ -55,6 +55,18 @@ int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; }
|
||||
*/
|
||||
int sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; }
|
||||
|
||||
/*
|
||||
** When compiling the test fixture or with debugging enabled (on Win32),
|
||||
** this variable being set to non-zero will cause OSTRACE macros to emit
|
||||
** extra diagnostic information.
|
||||
*/
|
||||
#ifdef SQLITE_HAVE_OS_TRACE
|
||||
# ifndef SQLITE_DEBUG_OS_TRACE
|
||||
# define SQLITE_DEBUG_OS_TRACE 0
|
||||
# endif
|
||||
int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE;
|
||||
#endif
|
||||
|
||||
#if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE)
|
||||
/*
|
||||
** If the following function pointer is not NULL and if
|
||||
@@ -1194,7 +1206,7 @@ void sqlite3RollbackAll(sqlite3 *db, int tripCode){
|
||||
** Return a static string containing the name corresponding to the error code
|
||||
** specified in the argument.
|
||||
*/
|
||||
#if (defined(SQLITE_DEBUG) && SQLITE_OS_WIN) || defined(SQLITE_TEST)
|
||||
#if defined(SQLITE_NEED_ERR_NAME)
|
||||
const char *sqlite3ErrName(int rc){
|
||||
const char *zName = 0;
|
||||
int i, origRc = rc;
|
||||
@@ -2276,6 +2288,7 @@ static const int aHardLimit[] = {
|
||||
SQLITE_MAX_VARIABLE_NUMBER, /* IMP: R-38091-32352 */
|
||||
SQLITE_MAX_TRIGGER_DEPTH,
|
||||
SQLITE_MAX_WORKER_THREADS,
|
||||
SQLITE_MAX_PRINTF_WIDTH,
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -2354,7 +2367,8 @@ int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){
|
||||
assert( aHardLimit[SQLITE_LIMIT_VARIABLE_NUMBER]==SQLITE_MAX_VARIABLE_NUMBER);
|
||||
assert( aHardLimit[SQLITE_LIMIT_TRIGGER_DEPTH]==SQLITE_MAX_TRIGGER_DEPTH );
|
||||
assert( aHardLimit[SQLITE_LIMIT_WORKER_THREADS]==SQLITE_MAX_WORKER_THREADS );
|
||||
assert( SQLITE_LIMIT_WORKER_THREADS==(SQLITE_N_LIMIT-1) );
|
||||
assert( aHardLimit[SQLITE_LIMIT_PRINTF_WIDTH]==SQLITE_MAX_PRINTF_WIDTH );
|
||||
assert( SQLITE_LIMIT_PRINTF_WIDTH==(SQLITE_N_LIMIT-1) );
|
||||
|
||||
|
||||
if( limitId<0 || limitId>=SQLITE_N_LIMIT ){
|
||||
@@ -2419,14 +2433,14 @@ int sqlite3ParseUri(
|
||||
int eState; /* Parser state when parsing URI */
|
||||
int iIn; /* Input character index */
|
||||
int iOut = 0; /* Output character index */
|
||||
int nByte = nUri+2; /* Bytes of space to allocate */
|
||||
u64 nByte = nUri+2; /* Bytes of space to allocate */
|
||||
|
||||
/* Make sure the SQLITE_OPEN_URI flag is set to indicate to the VFS xOpen
|
||||
** method that there may be extra parameters following the file-name. */
|
||||
flags |= SQLITE_OPEN_URI;
|
||||
|
||||
for(iIn=0; iIn<nUri; iIn++) nByte += (zUri[iIn]=='&');
|
||||
zFile = sqlite3_malloc(nByte);
|
||||
zFile = sqlite3_malloc64(nByte);
|
||||
if( !zFile ) return SQLITE_NOMEM;
|
||||
|
||||
iIn = 5;
|
||||
@@ -2592,7 +2606,7 @@ int sqlite3ParseUri(
|
||||
}
|
||||
|
||||
}else{
|
||||
zFile = sqlite3_malloc(nUri+2);
|
||||
zFile = sqlite3_malloc64(nUri+2);
|
||||
if( !zFile ) return SQLITE_NOMEM;
|
||||
memcpy(zFile, zUri, nUri);
|
||||
zFile[nUri] = '\0';
|
||||
@@ -2720,6 +2734,7 @@ static int openDatabase(
|
||||
assert( sizeof(db->aLimit)==sizeof(aHardLimit) );
|
||||
memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit));
|
||||
db->aLimit[SQLITE_LIMIT_WORKER_THREADS] = SQLITE_DEFAULT_WORKER_THREADS;
|
||||
db->aLimit[SQLITE_LIMIT_PRINTF_WIDTH] = 10000;
|
||||
db->autoCommit = 1;
|
||||
db->nextAutovac = -1;
|
||||
db->szMmap = sqlite3GlobalConfig.szMmap;
|
||||
|
||||
@@ -29,16 +29,6 @@
|
||||
# error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead."
|
||||
#endif
|
||||
|
||||
#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
|
||||
# ifndef SQLITE_DEBUG_OS_TRACE
|
||||
# define SQLITE_DEBUG_OS_TRACE 0
|
||||
# endif
|
||||
int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE;
|
||||
# define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X
|
||||
#else
|
||||
# define OSTRACE(X)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Macros for performance tracing. Normally turned off. Only works
|
||||
** on i486 hardware.
|
||||
|
||||
+16
-16
@@ -641,7 +641,7 @@ static int unixMutexHeld(void) {
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
|
||||
#ifdef SQLITE_HAVE_OS_TRACE
|
||||
/*
|
||||
** Helper function for printing out trace information from debugging
|
||||
** binaries. This returns the string representation of the supplied
|
||||
@@ -904,7 +904,7 @@ static struct vxworksFileId *vxworksFindFileId(const char *zAbsoluteName){
|
||||
|
||||
assert( zAbsoluteName[0]=='/' );
|
||||
n = (int)strlen(zAbsoluteName);
|
||||
pNew = sqlite3_malloc( sizeof(*pNew) + (n+1) );
|
||||
pNew = sqlite3_malloc64( sizeof(*pNew) + (n+1) );
|
||||
if( pNew==0 ) return 0;
|
||||
pNew->zCanonicalName = (char*)&pNew[1];
|
||||
memcpy(pNew->zCanonicalName, zAbsoluteName, n+1);
|
||||
@@ -1308,7 +1308,7 @@ static int findInodeInfo(
|
||||
pInode = pInode->pNext;
|
||||
}
|
||||
if( pInode==0 ){
|
||||
pInode = sqlite3_malloc( sizeof(*pInode) );
|
||||
pInode = sqlite3_malloc64( sizeof(*pInode) );
|
||||
if( pInode==0 ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
@@ -3829,7 +3829,7 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
case SQLITE_FCNTL_TEMPFILENAME: {
|
||||
char *zTFile = sqlite3_malloc( pFile->pVfs->mxPathname );
|
||||
char *zTFile = sqlite3_malloc64( pFile->pVfs->mxPathname );
|
||||
if( zTFile ){
|
||||
unixGetTempname(pFile->pVfs->mxPathname, zTFile);
|
||||
*(char**)pArg = zTFile;
|
||||
@@ -4270,7 +4270,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
|
||||
int nShmFilename; /* Size of the SHM filename in bytes */
|
||||
|
||||
/* Allocate space for the new unixShm object. */
|
||||
p = sqlite3_malloc( sizeof(*p) );
|
||||
p = sqlite3_malloc64( sizeof(*p) );
|
||||
if( p==0 ) return SQLITE_NOMEM;
|
||||
memset(p, 0, sizeof(*p));
|
||||
assert( pDbFd->pShm==0 );
|
||||
@@ -4301,7 +4301,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
|
||||
#else
|
||||
nShmFilename = 6 + (int)strlen(zBasePath);
|
||||
#endif
|
||||
pShmNode = sqlite3_malloc( sizeof(*pShmNode) + nShmFilename );
|
||||
pShmNode = sqlite3_malloc64( sizeof(*pShmNode) + nShmFilename );
|
||||
if( pShmNode==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
goto shm_open_err;
|
||||
@@ -4511,7 +4511,7 @@ static int unixShmMap(
|
||||
goto shmpage_out;
|
||||
}
|
||||
}else{
|
||||
pMem = sqlite3_malloc(szRegion);
|
||||
pMem = sqlite3_malloc64(szRegion);
|
||||
if( pMem==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
goto shmpage_out;
|
||||
@@ -5348,7 +5348,7 @@ static int fillInUnixFile(
|
||||
** the afpLockingContext.
|
||||
*/
|
||||
afpLockingContext *pCtx;
|
||||
pNew->lockingContext = pCtx = sqlite3_malloc( sizeof(*pCtx) );
|
||||
pNew->lockingContext = pCtx = sqlite3_malloc64( sizeof(*pCtx) );
|
||||
if( pCtx==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
@@ -5378,7 +5378,7 @@ static int fillInUnixFile(
|
||||
int nFilename;
|
||||
assert( zFilename!=0 );
|
||||
nFilename = (int)strlen(zFilename) + 6;
|
||||
zLockFile = (char *)sqlite3_malloc(nFilename);
|
||||
zLockFile = (char *)sqlite3_malloc64(nFilename);
|
||||
if( zLockFile==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
@@ -5755,7 +5755,7 @@ static int unixOpen(
|
||||
if( pUnused ){
|
||||
fd = pUnused->fd;
|
||||
}else{
|
||||
pUnused = sqlite3_malloc(sizeof(*pUnused));
|
||||
pUnused = sqlite3_malloc64(sizeof(*pUnused));
|
||||
if( !pUnused ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
@@ -6135,7 +6135,7 @@ static int unixRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){
|
||||
*/
|
||||
memset(zBuf, 0, nBuf);
|
||||
randomnessPid = osGetpid(0);
|
||||
#if !defined(SQLITE_TEST)
|
||||
#if !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS)
|
||||
{
|
||||
int fd, got;
|
||||
fd = robust_open("/dev/urandom", O_RDONLY, 0);
|
||||
@@ -6547,7 +6547,7 @@ static int proxyCreateUnixFile(
|
||||
if( pUnused ){
|
||||
fd = pUnused->fd;
|
||||
}else{
|
||||
pUnused = sqlite3_malloc(sizeof(*pUnused));
|
||||
pUnused = sqlite3_malloc64(sizeof(*pUnused));
|
||||
if( !pUnused ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
@@ -6580,7 +6580,7 @@ static int proxyCreateUnixFile(
|
||||
}
|
||||
}
|
||||
|
||||
pNew = (unixFile *)sqlite3_malloc(sizeof(*pNew));
|
||||
pNew = (unixFile *)sqlite3_malloc64(sizeof(*pNew));
|
||||
if( pNew==NULL ){
|
||||
rc = SQLITE_NOMEM;
|
||||
goto end_create_proxy;
|
||||
@@ -7042,7 +7042,7 @@ static int proxyReleaseConch(unixFile *pFile){
|
||||
|
||||
/*
|
||||
** Given the name of a database file, compute the name of its conch file.
|
||||
** Store the conch filename in memory obtained from sqlite3_malloc().
|
||||
** Store the conch filename in memory obtained from sqlite3_malloc64().
|
||||
** Make *pConchPath point to the new name. Return SQLITE_OK on success
|
||||
** or SQLITE_NOMEM if unable to obtain memory.
|
||||
**
|
||||
@@ -7058,7 +7058,7 @@ static int proxyCreateConchPathname(char *dbPath, char **pConchPath){
|
||||
|
||||
/* Allocate space for the conch filename and initialize the name to
|
||||
** the name of the original database file. */
|
||||
*pConchPath = conchPath = (char *)sqlite3_malloc(len + 8);
|
||||
*pConchPath = conchPath = (char *)sqlite3_malloc64(len + 8);
|
||||
if( conchPath==0 ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
@@ -7174,7 +7174,7 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) {
|
||||
OSTRACE(("TRANSPROXY %d for %s pid=%d\n", pFile->h,
|
||||
(lockPath ? lockPath : ":auto:"), osGetpid(0)));
|
||||
|
||||
pCtx = sqlite3_malloc( sizeof(*pCtx) );
|
||||
pCtx = sqlite3_malloc64( sizeof(*pCtx) );
|
||||
if( pCtx==0 ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
|
||||
+7
-7
@@ -2757,7 +2757,7 @@ static int winSync(sqlite3_file *id, int flags){
|
||||
BOOL rc;
|
||||
#endif
|
||||
#if !defined(NDEBUG) || !defined(SQLITE_NO_SYNC) || \
|
||||
(defined(SQLITE_TEST) && defined(SQLITE_DEBUG))
|
||||
defined(SQLITE_HAVE_OS_TRACE)
|
||||
/*
|
||||
** Used when SQLITE_NO_SYNC is not defined and by the assert() and/or
|
||||
** OSTRACE() macros.
|
||||
@@ -3434,7 +3434,7 @@ struct winShmNode {
|
||||
int nRef; /* Number of winShm objects pointing to this */
|
||||
winShm *pFirst; /* All winShm objects pointing to this */
|
||||
winShmNode *pNext; /* Next in list of all winShmNode objects */
|
||||
#ifdef SQLITE_DEBUG
|
||||
#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
|
||||
u8 nextShmId; /* Next available winShm.id value */
|
||||
#endif
|
||||
};
|
||||
@@ -3465,7 +3465,7 @@ struct winShm {
|
||||
u8 hasMutex; /* True if holding the winShmNode mutex */
|
||||
u16 sharedMask; /* Mask of shared locks held */
|
||||
u16 exclMask; /* Mask of exclusive locks held */
|
||||
#ifdef SQLITE_DEBUG
|
||||
#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
|
||||
u8 id; /* Id of this connection with its winShmNode */
|
||||
#endif
|
||||
};
|
||||
@@ -3656,7 +3656,7 @@ static int winOpenSharedMemory(winFile *pDbFd){
|
||||
|
||||
/* Make the new connection a child of the winShmNode */
|
||||
p->pShmNode = pShmNode;
|
||||
#ifdef SQLITE_DEBUG
|
||||
#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
|
||||
p->id = pShmNode->nextShmId++;
|
||||
#endif
|
||||
pShmNode->nRef++;
|
||||
@@ -3925,7 +3925,7 @@ static int winShmMap(
|
||||
}
|
||||
|
||||
/* Map the requested memory region into this processes address space. */
|
||||
apNew = (struct ShmRegion *)sqlite3_realloc(
|
||||
apNew = (struct ShmRegion *)sqlite3_realloc64(
|
||||
pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0])
|
||||
);
|
||||
if( !apNew ){
|
||||
@@ -5372,7 +5372,7 @@ static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
|
||||
static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
|
||||
int n = 0;
|
||||
UNUSED_PARAMETER(pVfs);
|
||||
#if defined(SQLITE_TEST)
|
||||
#if defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS)
|
||||
n = nBuf;
|
||||
memset(zBuf, 0, nBuf);
|
||||
#else
|
||||
@@ -5406,7 +5406,6 @@ static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
|
||||
memcpy(&zBuf[n], &i, sizeof(i));
|
||||
n += sizeof(i);
|
||||
}
|
||||
#endif
|
||||
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
|
||||
if( sizeof(UUID)<=nBuf-n ){
|
||||
UUID id;
|
||||
@@ -5423,6 +5422,7 @@ static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
|
||||
n += sizeof(UUID);
|
||||
}
|
||||
#endif
|
||||
#endif /* defined(SQLITE_TEST) || defined(SQLITE_ZERO_PRNG_SEED) */
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
+2
-4
@@ -3044,9 +3044,7 @@ static int pagerWalFrames(
|
||||
){
|
||||
int rc; /* Return code */
|
||||
int nList; /* Number of pages in pList */
|
||||
#if defined(SQLITE_DEBUG) || defined(SQLITE_CHECK_PAGES)
|
||||
PgHdr *p; /* For looping over pages */
|
||||
#endif
|
||||
|
||||
assert( pPager->pWal );
|
||||
assert( pList );
|
||||
@@ -3063,7 +3061,6 @@ static int pagerWalFrames(
|
||||
** any pages with page numbers greater than nTruncate into the WAL file.
|
||||
** They will never be read by any client. So remove them from the pDirty
|
||||
** list here. */
|
||||
PgHdr *p;
|
||||
PgHdr **ppNext = &pList;
|
||||
nList = 0;
|
||||
for(p=pList; (*ppNext = p)!=0; p=p->pDirty){
|
||||
@@ -3083,7 +3080,6 @@ static int pagerWalFrames(
|
||||
pPager->pageSize, pList, nTruncate, isCommit, pPager->walSyncFlags
|
||||
);
|
||||
if( rc==SQLITE_OK && pPager->pBackup ){
|
||||
PgHdr *p;
|
||||
for(p=pList; p; p=p->pDirty){
|
||||
sqlite3BackupUpdate(pPager->pBackup, p->pgno, (u8 *)p->pData);
|
||||
}
|
||||
@@ -7014,6 +7010,8 @@ int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){
|
||||
}
|
||||
assert( state==pPager->eState );
|
||||
}
|
||||
}else if( eMode==PAGER_JOURNALMODE_OFF ){
|
||||
sqlite3OsClose(pPager->jfd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+28
-16
@@ -409,28 +409,35 @@ cmd ::= select(X). {
|
||||
%type oneselect {Select*}
|
||||
%destructor oneselect {sqlite3SelectDelete(pParse->db, $$);}
|
||||
|
||||
select(A) ::= with(W) selectnowith(X). {
|
||||
Select *p = X, *pNext, *pLoop;
|
||||
if( p ){
|
||||
int cnt = 0, mxSelect;
|
||||
p->pWith = W;
|
||||
%include {
|
||||
/*
|
||||
** For a compound SELECT statement, make sure p->pPrior->pNext==p for
|
||||
** all elements in the list. And make sure list length does not exceed
|
||||
** SQLITE_LIMIT_COMPOUND_SELECT.
|
||||
*/
|
||||
static void parserDoubleLinkSelect(Parse *pParse, Select *p){
|
||||
if( p->pPrior ){
|
||||
u16 allValues = SF_Values;
|
||||
pNext = 0;
|
||||
Select *pNext = 0, *pLoop;
|
||||
int mxSelect, cnt = 0;
|
||||
for(pLoop=p; pLoop; pNext=pLoop, pLoop=pLoop->pPrior, cnt++){
|
||||
pLoop->pNext = pNext;
|
||||
pLoop->selFlags |= SF_Compound;
|
||||
allValues &= pLoop->selFlags;
|
||||
}
|
||||
if( allValues ){
|
||||
p->selFlags |= SF_AllValues;
|
||||
}else if(
|
||||
(mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0
|
||||
&& cnt>mxSelect
|
||||
if( (p->selFlags & SF_MultiValue)==0 &&
|
||||
(mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 &&
|
||||
cnt>mxSelect
|
||||
){
|
||||
sqlite3ErrorMsg(pParse, "too many terms in compound SELECT");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
select(A) ::= with(W) selectnowith(X). {
|
||||
Select *p = X;
|
||||
if( p ){
|
||||
p->pWith = W;
|
||||
parserDoubleLinkSelect(pParse, p);
|
||||
}else{
|
||||
sqlite3WithDelete(pParse->db, W);
|
||||
}
|
||||
@@ -445,12 +452,14 @@ selectnowith(A) ::= selectnowith(X) multiselect_op(Y) oneselect(Z). {
|
||||
SrcList *pFrom;
|
||||
Token x;
|
||||
x.n = 0;
|
||||
parserDoubleLinkSelect(pParse, pRhs);
|
||||
pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0,0);
|
||||
pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0,0);
|
||||
}
|
||||
if( pRhs ){
|
||||
pRhs->op = (u8)Y;
|
||||
pRhs->pPrior = X;
|
||||
pRhs->selFlags &= ~SF_MultiValue;
|
||||
if( Y!=TK_ALL ) pParse->hasCompound = 1;
|
||||
}else{
|
||||
sqlite3SelectDelete(pParse->db, X);
|
||||
@@ -498,13 +507,16 @@ values(A) ::= VALUES LP nexprlist(X) RP. {
|
||||
A = sqlite3SelectNew(pParse,X,0,0,0,0,0,SF_Values,0,0);
|
||||
}
|
||||
values(A) ::= values(X) COMMA LP exprlist(Y) RP. {
|
||||
Select *pRight = sqlite3SelectNew(pParse,Y,0,0,0,0,0,SF_Values,0,0);
|
||||
Select *pRight, *pLeft = X;
|
||||
pRight = sqlite3SelectNew(pParse,Y,0,0,0,0,0,SF_Values|SF_MultiValue,0,0);
|
||||
if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue;
|
||||
if( pRight ){
|
||||
pRight->op = TK_ALL;
|
||||
pRight->pPrior = X;
|
||||
pLeft = X;
|
||||
pRight->pPrior = pLeft;
|
||||
A = pRight;
|
||||
}else{
|
||||
A = X;
|
||||
A = pLeft;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+9
-7
@@ -164,15 +164,15 @@ static int changeTempStorage(Parse *pParse, const char *zStorageType){
|
||||
*/
|
||||
static void returnSingleInt(Parse *pParse, const char *zLabel, i64 value){
|
||||
Vdbe *v = sqlite3GetVdbe(pParse);
|
||||
int mem = ++pParse->nMem;
|
||||
int nMem = ++pParse->nMem;
|
||||
i64 *pI64 = sqlite3DbMallocRaw(pParse->db, sizeof(value));
|
||||
if( pI64 ){
|
||||
memcpy(pI64, &value, sizeof(value));
|
||||
}
|
||||
sqlite3VdbeAddOp4(v, OP_Int64, 0, mem, 0, (char*)pI64, P4_INT64);
|
||||
sqlite3VdbeAddOp4(v, OP_Int64, 0, nMem, 0, (char*)pI64, P4_INT64);
|
||||
sqlite3VdbeSetNumCols(v, 1);
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, SQLITE_STATIC);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, nMem, 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -337,11 +337,11 @@ void sqlite3Pragma(
|
||||
rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl);
|
||||
if( rc==SQLITE_OK ){
|
||||
if( aFcntl[0] ){
|
||||
int mem = ++pParse->nMem;
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, mem, 0, aFcntl[0], 0);
|
||||
int nMem = ++pParse->nMem;
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, nMem, 0, aFcntl[0], 0);
|
||||
sqlite3VdbeSetNumCols(v, 1);
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "result", SQLITE_STATIC);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, nMem, 1);
|
||||
sqlite3_free(aFcntl[0]);
|
||||
}
|
||||
goto pragma_out;
|
||||
@@ -946,7 +946,9 @@ void sqlite3Pragma(
|
||||
sqlite3ErrorMsg(pParse,
|
||||
"Safety level may not be changed inside a transaction");
|
||||
}else{
|
||||
pDb->safety_level = getSafetyLevel(zRight,0,1)+1;
|
||||
int iLevel = (getSafetyLevel(zRight,0,1)+1) & PAGER_SYNCHRONOUS_MASK;
|
||||
if( iLevel==0 ) iLevel = 1;
|
||||
pDb->safety_level = iLevel;
|
||||
setAllPagerFlags(db);
|
||||
}
|
||||
}
|
||||
|
||||
+39
-32
@@ -138,6 +138,7 @@ static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
|
||||
** Set the StrAccum object to an error mode.
|
||||
*/
|
||||
static void setStrAccumError(StrAccum *p, u8 eError){
|
||||
assert( eError==STRACCUM_NOMEM || eError==STRACCUM_TOOBIG );
|
||||
p->accError = eError;
|
||||
p->nAlloc = 0;
|
||||
}
|
||||
@@ -300,6 +301,16 @@ void sqlite3VXPrintf(
|
||||
}else{
|
||||
precision = -1;
|
||||
}
|
||||
|
||||
/* Check for over-size width or precision and error-out if found */
|
||||
if( bArgList ){
|
||||
int iLimit = pAccum->db->aLimit[SQLITE_LIMIT_PRINTF_WIDTH];
|
||||
if( width>iLimit || precision>iLimit ){
|
||||
setStrAccumError(pAccum, STRACCUM_TOOBIG);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the conversion type modifier */
|
||||
if( c=='l' ){
|
||||
flag_long = 1;
|
||||
@@ -755,7 +766,7 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
|
||||
testcase(p->accError==STRACCUM_NOMEM);
|
||||
return 0;
|
||||
}
|
||||
if( !p->useMalloc ){
|
||||
if( p->mxAlloc==0 ){
|
||||
N = p->nAlloc - p->nChar - 1;
|
||||
setStrAccumError(p, STRACCUM_TOOBIG);
|
||||
return N;
|
||||
@@ -775,10 +786,10 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
|
||||
}else{
|
||||
p->nAlloc = (int)szNew;
|
||||
}
|
||||
if( p->useMalloc==1 ){
|
||||
if( p->db ){
|
||||
zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
|
||||
}else{
|
||||
zNew = sqlite3_realloc(zOld, p->nAlloc);
|
||||
zNew = sqlite3_realloc64(zOld, p->nAlloc);
|
||||
}
|
||||
if( zNew ){
|
||||
assert( p->zText!=0 || p->nChar==0 );
|
||||
@@ -855,12 +866,8 @@ void sqlite3StrAccumAppendAll(StrAccum *p, const char *z){
|
||||
char *sqlite3StrAccumFinish(StrAccum *p){
|
||||
if( p->zText ){
|
||||
p->zText[p->nChar] = 0;
|
||||
if( p->useMalloc && p->zText==p->zBase ){
|
||||
if( p->useMalloc==1 ){
|
||||
p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
|
||||
}else{
|
||||
p->zText = sqlite3_malloc(p->nChar+1);
|
||||
}
|
||||
if( p->mxAlloc>0 && p->zText==p->zBase ){
|
||||
p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
|
||||
if( p->zText ){
|
||||
memcpy(p->zText, p->zBase, p->nChar+1);
|
||||
}else{
|
||||
@@ -876,25 +883,31 @@ char *sqlite3StrAccumFinish(StrAccum *p){
|
||||
*/
|
||||
void sqlite3StrAccumReset(StrAccum *p){
|
||||
if( p->zText!=p->zBase ){
|
||||
if( p->useMalloc==1 ){
|
||||
sqlite3DbFree(p->db, p->zText);
|
||||
}else{
|
||||
sqlite3_free(p->zText);
|
||||
}
|
||||
sqlite3DbFree(p->db, p->zText);
|
||||
}
|
||||
p->zText = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Initialize a string accumulator
|
||||
** Initialize a string accumulator.
|
||||
**
|
||||
** p: The accumulator to be initialized.
|
||||
** db: Pointer to a database connection. May be NULL. Lookaside
|
||||
** memory is used if not NULL. db->mallocFailed is set appropriately
|
||||
** when not NULL.
|
||||
** zBase: An initial buffer. May be NULL in which case the initial buffer
|
||||
** is malloced.
|
||||
** n: Size of zBase in bytes. If total space requirements never exceed
|
||||
** n then no memory allocations ever occur.
|
||||
** mx: Maximum number of bytes to accumulate. If mx==0 then no memory
|
||||
** allocations will ever occur.
|
||||
*/
|
||||
void sqlite3StrAccumInit(StrAccum *p, char *zBase, int n, int mx){
|
||||
void sqlite3StrAccumInit(StrAccum *p, sqlite3 *db, char *zBase, int n, int mx){
|
||||
p->zText = p->zBase = zBase;
|
||||
p->db = 0;
|
||||
p->db = db;
|
||||
p->nChar = 0;
|
||||
p->nAlloc = n;
|
||||
p->mxAlloc = mx;
|
||||
p->useMalloc = 1;
|
||||
p->accError = 0;
|
||||
}
|
||||
|
||||
@@ -907,9 +920,8 @@ char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){
|
||||
char zBase[SQLITE_PRINT_BUF_SIZE];
|
||||
StrAccum acc;
|
||||
assert( db!=0 );
|
||||
sqlite3StrAccumInit(&acc, zBase, sizeof(zBase),
|
||||
sqlite3StrAccumInit(&acc, db, zBase, sizeof(zBase),
|
||||
db->aLimit[SQLITE_LIMIT_LENGTH]);
|
||||
acc.db = db;
|
||||
sqlite3VXPrintf(&acc, SQLITE_PRINTF_INTERNAL, zFormat, ap);
|
||||
z = sqlite3StrAccumFinish(&acc);
|
||||
if( acc.accError==STRACCUM_NOMEM ){
|
||||
@@ -967,8 +979,7 @@ char *sqlite3_vmprintf(const char *zFormat, va_list ap){
|
||||
#ifndef SQLITE_OMIT_AUTOINIT
|
||||
if( sqlite3_initialize() ) return 0;
|
||||
#endif
|
||||
sqlite3StrAccumInit(&acc, zBase, sizeof(zBase), SQLITE_MAX_LENGTH);
|
||||
acc.useMalloc = 2;
|
||||
sqlite3StrAccumInit(&acc, 0, zBase, sizeof(zBase), SQLITE_MAX_LENGTH);
|
||||
sqlite3VXPrintf(&acc, 0, zFormat, ap);
|
||||
z = sqlite3StrAccumFinish(&acc);
|
||||
return z;
|
||||
@@ -1013,8 +1024,7 @@ char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){
|
||||
return zBuf;
|
||||
}
|
||||
#endif
|
||||
sqlite3StrAccumInit(&acc, zBuf, n, 0);
|
||||
acc.useMalloc = 0;
|
||||
sqlite3StrAccumInit(&acc, 0, zBuf, n, 0);
|
||||
sqlite3VXPrintf(&acc, 0, zFormat, ap);
|
||||
return sqlite3StrAccumFinish(&acc);
|
||||
}
|
||||
@@ -1040,8 +1050,7 @@ static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){
|
||||
StrAccum acc; /* String accumulator */
|
||||
char zMsg[SQLITE_PRINT_BUF_SIZE*3]; /* Complete log message */
|
||||
|
||||
sqlite3StrAccumInit(&acc, zMsg, sizeof(zMsg), 0);
|
||||
acc.useMalloc = 0;
|
||||
sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0);
|
||||
sqlite3VXPrintf(&acc, 0, zFormat, ap);
|
||||
sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode,
|
||||
sqlite3StrAccumFinish(&acc));
|
||||
@@ -1059,7 +1068,7 @@ void sqlite3_log(int iErrCode, const char *zFormat, ...){
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(SQLITE_DEBUG)
|
||||
#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
|
||||
/*
|
||||
** A version of printf() that understands %lld. Used for debugging.
|
||||
** The printf() built into some versions of windows does not understand %lld
|
||||
@@ -1069,8 +1078,7 @@ void sqlite3DebugPrintf(const char *zFormat, ...){
|
||||
va_list ap;
|
||||
StrAccum acc;
|
||||
char zBuf[500];
|
||||
sqlite3StrAccumInit(&acc, zBuf, sizeof(zBuf), 0);
|
||||
acc.useMalloc = 0;
|
||||
sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
|
||||
va_start(ap,zFormat);
|
||||
sqlite3VXPrintf(&acc, 0, zFormat, ap);
|
||||
va_end(ap);
|
||||
@@ -1097,7 +1105,7 @@ void sqlite3DebugPrintf(const char *zFormat, ...){
|
||||
** is not the last item in the tree. */
|
||||
TreeView *sqlite3TreeViewPush(TreeView *p, u8 moreToFollow){
|
||||
if( p==0 ){
|
||||
p = sqlite3_malloc( sizeof(*p) );
|
||||
p = sqlite3_malloc64( sizeof(*p) );
|
||||
if( p==0 ) return 0;
|
||||
memset(p, 0, sizeof(*p));
|
||||
}else{
|
||||
@@ -1120,8 +1128,7 @@ void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){
|
||||
int i;
|
||||
StrAccum acc;
|
||||
char zBuf[500];
|
||||
sqlite3StrAccumInit(&acc, zBuf, sizeof(zBuf), 0);
|
||||
acc.useMalloc = 0;
|
||||
sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
|
||||
if( p ){
|
||||
for(i=0; i<p->iLevel && i<sizeof(p->bLine)-1; i++){
|
||||
sqlite3StrAccumAppend(&acc, p->bLine[i] ? "| " : " ", 4);
|
||||
|
||||
+10
-4
@@ -79,7 +79,7 @@ static void incrAggFunctionDepth(Expr *pExpr, int N){
|
||||
** 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
|
||||
** alias is removed from the original expression. The usual value is
|
||||
** zero but it might be more if the alias is contained within a subquery
|
||||
** of the original expression. The Expr.op2 field of TK_AGG_FUNCTION
|
||||
** structures must be increased by the nSubquery amount.
|
||||
@@ -99,7 +99,7 @@ static void resolveAlias(
|
||||
assert( iCol>=0 && iCol<pEList->nExpr );
|
||||
pOrig = pEList->a[iCol].pExpr;
|
||||
assert( pOrig!=0 );
|
||||
assert( pOrig->flags & EP_Resolved );
|
||||
assert( (pOrig->flags & EP_Resolved)!=0 || zType[0]==0 );
|
||||
db = pParse->db;
|
||||
pDup = sqlite3ExprDup(db, pOrig, 0);
|
||||
if( pDup==0 ) return;
|
||||
@@ -460,7 +460,6 @@ static int lookupName(
|
||||
if( cnt==0 && zTab==0 && ExprHasProperty(pExpr,EP_DblQuoted) ){
|
||||
pExpr->op = TK_STRING;
|
||||
pExpr->pTab = 0;
|
||||
pExpr->iTable = -1;
|
||||
return WRC_Prune;
|
||||
}
|
||||
|
||||
@@ -1300,8 +1299,15 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
|
||||
** The ORDER BY clause for compounds SELECT statements is handled
|
||||
** below, after all of the result-sets for all of the elements of
|
||||
** the compound have been resolved.
|
||||
**
|
||||
** If there is an ORDER BY clause on a term of a compound-select other
|
||||
** than the right-most term, then that is a syntax error. But the error
|
||||
** is not detected until much later, and so we need to go ahead and
|
||||
** resolve those symbols on the incorrect ORDER BY for consistency.
|
||||
*/
|
||||
if( !isCompound && resolveOrderGroupBy(&sNC, p, p->pOrderBy, "ORDER") ){
|
||||
if( isCompound<=nCompound /* Defer right-most ORDER BY of a compound */
|
||||
&& resolveOrderGroupBy(&sNC, p, p->pOrderBy, "ORDER")
|
||||
){
|
||||
return WRC_Abort;
|
||||
}
|
||||
if( db->mallocFailed ){
|
||||
|
||||
+21
-19
@@ -111,7 +111,6 @@ Select *sqlite3SelectNew(
|
||||
Select standin;
|
||||
sqlite3 *db = pParse->db;
|
||||
pNew = sqlite3DbMallocZero(db, sizeof(*pNew) );
|
||||
assert( db->mallocFailed || !pOffset || pLimit ); /* OFFSET implies LIMIT */
|
||||
if( pNew==0 ){
|
||||
assert( db->mallocFailed );
|
||||
pNew = &standin;
|
||||
@@ -131,7 +130,7 @@ Select *sqlite3SelectNew(
|
||||
pNew->op = TK_SELECT;
|
||||
pNew->pLimit = pLimit;
|
||||
pNew->pOffset = pOffset;
|
||||
assert( pOffset==0 || pLimit!=0 );
|
||||
assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || db->mallocFailed!=0 );
|
||||
pNew->addrOpenEphm[0] = -1;
|
||||
pNew->addrOpenEphm[1] = -1;
|
||||
if( db->mallocFailed ) {
|
||||
@@ -1381,7 +1380,7 @@ static const char *columnTypeImpl(
|
||||
** of the SELECT statement. Return the declaration type and origin
|
||||
** data for the result-set column of the sub-select.
|
||||
*/
|
||||
if( iCol>=0 && ALWAYS(iCol<pS->pEList->nExpr) ){
|
||||
if( iCol>=0 && iCol<pS->pEList->nExpr ){
|
||||
/* If iCol is less than zero, then the expression requests the
|
||||
** rowid of the sub-select or view. This expression is legal (see
|
||||
** test case misc2.2.2) - it always evaluates to NULL.
|
||||
@@ -1701,12 +1700,14 @@ static void selectAddColumnTypeAndCollation(
|
||||
a = pSelect->pEList->a;
|
||||
for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
|
||||
p = a[i].pExpr;
|
||||
pCol->zType = sqlite3DbStrDup(db, columnType(&sNC, p,0,0,0, &pCol->szEst));
|
||||
if( pCol->zType==0 ){
|
||||
pCol->zType = sqlite3DbStrDup(db, columnType(&sNC, p,0,0,0, &pCol->szEst));
|
||||
}
|
||||
szAll += pCol->szEst;
|
||||
pCol->affinity = sqlite3ExprAffinity(p);
|
||||
if( pCol->affinity==0 ) pCol->affinity = SQLITE_AFF_NONE;
|
||||
pColl = sqlite3ExprCollSeq(pParse, p);
|
||||
if( pColl ){
|
||||
if( pColl && pCol->zColl==0 ){
|
||||
pCol->zColl = sqlite3DbStrDup(db, pColl->zName);
|
||||
}
|
||||
}
|
||||
@@ -2108,8 +2109,7 @@ static int multiSelectValues(
|
||||
int nExpr = p->pEList->nExpr;
|
||||
int nRow = 1;
|
||||
int rc = 0;
|
||||
assert( p->pNext==0 );
|
||||
assert( p->selFlags & SF_AllValues );
|
||||
assert( p->selFlags & SF_MultiValue );
|
||||
do{
|
||||
assert( p->selFlags & SF_Values );
|
||||
assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) );
|
||||
@@ -2218,7 +2218,7 @@ static int multiSelect(
|
||||
|
||||
/* Special handling for a compound-select that originates as a VALUES clause.
|
||||
*/
|
||||
if( p->selFlags & SF_AllValues ){
|
||||
if( p->selFlags & SF_MultiValue ){
|
||||
rc = multiSelectValues(pParse, p, &dest);
|
||||
goto multi_select_end;
|
||||
}
|
||||
@@ -2629,7 +2629,7 @@ static int generateOutputSubroutine(
|
||||
** of the scan loop.
|
||||
*/
|
||||
case SRT_Mem: {
|
||||
assert( pIn->nSdst==1 );
|
||||
assert( pIn->nSdst==1 || pParse->nErr>0 ); testcase( pIn->nSdst!=1 );
|
||||
sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, 1);
|
||||
/* The LIMIT clause will jump out of the loop for us */
|
||||
break;
|
||||
@@ -2644,7 +2644,7 @@ static int generateOutputSubroutine(
|
||||
pDest->iSdst = sqlite3GetTempRange(pParse, pIn->nSdst);
|
||||
pDest->nSdst = pIn->nSdst;
|
||||
}
|
||||
sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSdst, pDest->nSdst);
|
||||
sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSdst, pIn->nSdst);
|
||||
sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
|
||||
break;
|
||||
}
|
||||
@@ -2860,8 +2860,10 @@ static int multiSelectOrderBy(
|
||||
if( aPermute ){
|
||||
struct ExprList_item *pItem;
|
||||
for(i=0, pItem=pOrderBy->a; i<nOrderBy; i++, pItem++){
|
||||
assert( pItem->u.x.iOrderByCol>0
|
||||
&& pItem->u.x.iOrderByCol<=p->pEList->nExpr );
|
||||
assert( pItem->u.x.iOrderByCol>0 );
|
||||
/* assert( pItem->u.x.iOrderByCol<=p->pEList->nExpr ) is also true
|
||||
** but only for well-formed SELECT statements. */
|
||||
testcase( pItem->u.x.iOrderByCol > p->pEList->nExpr );
|
||||
aPermute[i] = pItem->u.x.iOrderByCol - 1;
|
||||
}
|
||||
pKeyMerge = multiSelectOrderByKeyInfo(pParse, p, 1);
|
||||
@@ -4422,7 +4424,7 @@ static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
|
||||
sqlite3WalkSelect(&w, pSelect);
|
||||
}
|
||||
w.xSelectCallback = selectExpander;
|
||||
if( (pSelect->selFlags & SF_AllValues)==0 ){
|
||||
if( (pSelect->selFlags & SF_MultiValue)==0 ){
|
||||
w.xSelectCallback2 = selectPopWith;
|
||||
}
|
||||
sqlite3WalkSelect(&w, pSelect);
|
||||
@@ -4608,7 +4610,8 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
|
||||
}
|
||||
if( pF->iDistinct>=0 ){
|
||||
addrNext = sqlite3VdbeMakeLabel(v);
|
||||
assert( nArg==1 );
|
||||
testcase( nArg==0 ); /* Error condition */
|
||||
testcase( nArg>1 ); /* Also an error */
|
||||
codeDistinct(pParse, pF->iDistinct, addrNext, 1, regAgg);
|
||||
}
|
||||
if( pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
|
||||
@@ -5483,10 +5486,9 @@ int sqlite3Select(
|
||||
*/
|
||||
sqlite3VdbeResolveLabel(v, iEnd);
|
||||
|
||||
/* The SELECT was successfully coded. Set the return code to 0
|
||||
** to indicate no errors.
|
||||
*/
|
||||
rc = 0;
|
||||
/* The SELECT has been coded. If there is an error in the Parse structure,
|
||||
** set the return code to 1. Otherwise 0. */
|
||||
rc = (pParse->nErr>0);
|
||||
|
||||
/* Control jumps to here if an error is encountered above, or upon
|
||||
** successful coding of the SELECT.
|
||||
@@ -5537,7 +5539,7 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
|
||||
struct SrcList_item *pItem = &p->pSrc->a[i];
|
||||
StrAccum x;
|
||||
char zLine[100];
|
||||
sqlite3StrAccumInit(&x, zLine, sizeof(zLine), 0);
|
||||
sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
|
||||
sqlite3XPrintf(&x, 0, "{%d,*}", pItem->iCursor);
|
||||
if( pItem->zDatabase ){
|
||||
sqlite3XPrintf(&x, 0, " %s.%s", pItem->zDatabase, pItem->zName);
|
||||
|
||||
+135
-61
@@ -336,7 +336,7 @@ static int stdin_is_interactive = 1;
|
||||
** to this database a static variable so that it can be accessed
|
||||
** by the SIGINT handler to interrupt database processing.
|
||||
*/
|
||||
static sqlite3 *db = 0;
|
||||
static sqlite3 *globalDb = 0;
|
||||
|
||||
/*
|
||||
** True if an interrupt (Control-C) has been received.
|
||||
@@ -527,6 +527,7 @@ struct ShellState {
|
||||
int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
|
||||
int statsOn; /* True to display memory stats before each finalize */
|
||||
int scanstatsOn; /* True to display scan stats before each finalize */
|
||||
int backslashOn; /* Resolve C-style \x escapes in SQL input text */
|
||||
int outCount; /* Revert to stdout when reaching zero */
|
||||
int cnt; /* Number of records displayed so far */
|
||||
FILE *out; /* Write results here */
|
||||
@@ -804,7 +805,7 @@ static void interrupt_handler(int NotUsed){
|
||||
UNUSED_PARAMETER(NotUsed);
|
||||
seenInterrupt++;
|
||||
if( seenInterrupt>2 ) exit(1);
|
||||
if( db ) sqlite3_interrupt(db);
|
||||
if( globalDb ) sqlite3_interrupt(globalDb);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1190,7 +1191,7 @@ static char *save_err_msg(
|
||||
sqlite3 *db /* Database to query */
|
||||
){
|
||||
int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
|
||||
char *zErrMsg = sqlite3_malloc(nErrMsg);
|
||||
char *zErrMsg = sqlite3_malloc64(nErrMsg);
|
||||
if( zErrMsg ){
|
||||
memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
|
||||
}
|
||||
@@ -1427,8 +1428,8 @@ static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
|
||||
/* Grow the p->aiIndent array as required */
|
||||
if( iOp>=nAlloc ){
|
||||
nAlloc += 100;
|
||||
p->aiIndent = (int*)sqlite3_realloc(p->aiIndent, nAlloc*sizeof(int));
|
||||
abYield = (int*)sqlite3_realloc(abYield, nAlloc*sizeof(int));
|
||||
p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int));
|
||||
abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
|
||||
}
|
||||
abYield[iOp] = str_in_array(zOp, azYield);
|
||||
p->aiIndent[iOp] = 0;
|
||||
@@ -1545,7 +1546,7 @@ static int shell_exec(
|
||||
if( xCallback ){
|
||||
/* allocate space for col name ptr, value ptr, and type */
|
||||
int nCol = sqlite3_column_count(pStmt);
|
||||
void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
|
||||
void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1);
|
||||
if( !pData ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
@@ -1792,6 +1793,7 @@ static char zHelp[] =
|
||||
#ifdef SQLITE_ENABLE_IOTRACE
|
||||
".iotrace FILE Enable I/O diagnostic logging to FILE\n"
|
||||
#endif
|
||||
".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n"
|
||||
#ifndef SQLITE_OMIT_LOAD_EXTENSION
|
||||
".load FILE ?ENTRY? Load an extension library\n"
|
||||
#endif
|
||||
@@ -1861,7 +1863,7 @@ static void readfileFunc(
|
||||
fseek(in, 0, SEEK_END);
|
||||
nIn = ftell(in);
|
||||
rewind(in);
|
||||
pBuf = sqlite3_malloc( nIn );
|
||||
pBuf = sqlite3_malloc64( nIn );
|
||||
if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
|
||||
sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
|
||||
}else{
|
||||
@@ -1908,23 +1910,29 @@ static void open_db(ShellState *p, int keepAlive){
|
||||
if( p->db==0 ){
|
||||
sqlite3_initialize();
|
||||
sqlite3_open(p->zDbFilename, &p->db);
|
||||
db = p->db;
|
||||
if( db && sqlite3_errcode(db)==SQLITE_OK ){
|
||||
sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
|
||||
#ifdef SQLITE_ENABLE_STAT_VTAB
|
||||
if( p->db ){
|
||||
int sqlite3_dbstat_register(sqlite3*);
|
||||
sqlite3_dbstat_register(p->db);
|
||||
}
|
||||
#endif
|
||||
globalDb = p->db;
|
||||
if( p->db && sqlite3_errcode(p->db)==SQLITE_OK ){
|
||||
sqlite3_create_function(p->db, "shellstatic", 0, SQLITE_UTF8, 0,
|
||||
shellstaticFunc, 0, 0);
|
||||
}
|
||||
if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
|
||||
if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
|
||||
fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
|
||||
p->zDbFilename, sqlite3_errmsg(db));
|
||||
p->zDbFilename, sqlite3_errmsg(p->db));
|
||||
if( keepAlive ) return;
|
||||
exit(1);
|
||||
}
|
||||
#ifndef SQLITE_OMIT_LOAD_EXTENSION
|
||||
sqlite3_enable_load_extension(p->db, 1);
|
||||
#endif
|
||||
sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0,
|
||||
sqlite3_create_function(p->db, "readfile", 1, SQLITE_UTF8, 0,
|
||||
readfileFunc, 0, 0);
|
||||
sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0,
|
||||
sqlite3_create_function(p->db, "writefile", 2, SQLITE_UTF8, 0,
|
||||
writefileFunc, 0, 0);
|
||||
}
|
||||
}
|
||||
@@ -2121,7 +2129,7 @@ struct ImportCtx {
|
||||
static void import_append_char(ImportCtx *p, int c){
|
||||
if( p->n+1>=p->nAlloc ){
|
||||
p->nAlloc += p->nAlloc + 100;
|
||||
p->z = sqlite3_realloc(p->z, p->nAlloc);
|
||||
p->z = sqlite3_realloc64(p->z, p->nAlloc);
|
||||
if( p->z==0 ){
|
||||
fprintf(stderr, "out of memory\n");
|
||||
exit(1);
|
||||
@@ -2135,7 +2143,7 @@ static void import_append_char(ImportCtx *p, int c){
|
||||
**
|
||||
** + Input comes from p->in.
|
||||
** + Store results in p->z of length p->n. Space to hold p->z comes
|
||||
** from sqlite3_malloc().
|
||||
** from sqlite3_malloc64().
|
||||
** + Use p->cSep as the column separator. The default is ",".
|
||||
** + Use p->rSep as the row separator. The default is "\n".
|
||||
** + Keep track of the line number in p->nLine.
|
||||
@@ -2209,7 +2217,7 @@ static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){
|
||||
**
|
||||
** + Input comes from p->in.
|
||||
** + Store results in p->z of length p->n. Space to hold p->z comes
|
||||
** from sqlite3_malloc().
|
||||
** from sqlite3_malloc64().
|
||||
** + Use p->cSep as the column separator. The default is "\x1F".
|
||||
** + Use p->rSep as the row separator. The default is "\x1E".
|
||||
** + Keep track of the row number in p->nLine.
|
||||
@@ -2269,7 +2277,7 @@ static void tryToCloneData(
|
||||
goto end_data_xfer;
|
||||
}
|
||||
n = sqlite3_column_count(pQuery);
|
||||
zInsert = sqlite3_malloc(200 + nTable + n*3);
|
||||
zInsert = sqlite3_malloc64(200 + nTable + n*3);
|
||||
if( zInsert==0 ){
|
||||
fprintf(stderr, "out of memory\n");
|
||||
goto end_data_xfer;
|
||||
@@ -2585,7 +2593,7 @@ static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
|
||||
** Return 1 on error, 2 to exit, and 0 otherwise.
|
||||
*/
|
||||
static int do_meta_command(char *zLine, ShellState *p){
|
||||
int i = 1;
|
||||
int h = 1;
|
||||
int nArg = 0;
|
||||
int n, c;
|
||||
int rc = 0;
|
||||
@@ -2593,24 +2601,24 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
|
||||
/* Parse the input line into tokens.
|
||||
*/
|
||||
while( zLine[i] && nArg<ArraySize(azArg) ){
|
||||
while( IsSpace(zLine[i]) ){ i++; }
|
||||
if( zLine[i]==0 ) break;
|
||||
if( zLine[i]=='\'' || zLine[i]=='"' ){
|
||||
int delim = zLine[i++];
|
||||
azArg[nArg++] = &zLine[i];
|
||||
while( zLine[i] && zLine[i]!=delim ){
|
||||
if( zLine[i]=='\\' && delim=='"' && zLine[i+1]!=0 ) i++;
|
||||
i++;
|
||||
while( zLine[h] && nArg<ArraySize(azArg) ){
|
||||
while( IsSpace(zLine[h]) ){ h++; }
|
||||
if( zLine[h]==0 ) break;
|
||||
if( zLine[h]=='\'' || zLine[h]=='"' ){
|
||||
int delim = zLine[h++];
|
||||
azArg[nArg++] = &zLine[h];
|
||||
while( zLine[h] && zLine[h]!=delim ){
|
||||
if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
|
||||
h++;
|
||||
}
|
||||
if( zLine[i]==delim ){
|
||||
zLine[i++] = 0;
|
||||
if( zLine[h]==delim ){
|
||||
zLine[h++] = 0;
|
||||
}
|
||||
if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
|
||||
}else{
|
||||
azArg[nArg++] = &zLine[i];
|
||||
while( zLine[i] && !IsSpace(zLine[i]) ){ i++; }
|
||||
if( zLine[i] ) zLine[i++] = 0;
|
||||
azArg[nArg++] = &zLine[h];
|
||||
while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
|
||||
if( zLine[h] ) zLine[h++] = 0;
|
||||
resolve_backslashes(azArg[nArg-1]);
|
||||
}
|
||||
}
|
||||
@@ -2986,7 +2994,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
nByte = strlen30(zSql);
|
||||
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
|
||||
import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
|
||||
if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){
|
||||
if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
|
||||
char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
|
||||
char cSep = '(';
|
||||
while( xRead(&sCtx) ){
|
||||
@@ -3006,7 +3014,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
sqlite3_free(zCreate);
|
||||
if( rc ){
|
||||
fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
|
||||
sqlite3_errmsg(db));
|
||||
sqlite3_errmsg(p->db));
|
||||
sqlite3_free(sCtx.z);
|
||||
xCloser(sCtx.in);
|
||||
return 1;
|
||||
@@ -3016,7 +3024,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
sqlite3_free(zSql);
|
||||
if( rc ){
|
||||
if (pStmt) sqlite3_finalize(pStmt);
|
||||
fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
|
||||
fprintf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
|
||||
xCloser(sCtx.in);
|
||||
return 1;
|
||||
}
|
||||
@@ -3024,7 +3032,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
sqlite3_finalize(pStmt);
|
||||
pStmt = 0;
|
||||
if( nCol==0 ) return 0; /* no columns, no error */
|
||||
zSql = sqlite3_malloc( nByte*2 + 20 + nCol*2 );
|
||||
zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
|
||||
if( zSql==0 ){
|
||||
fprintf(stderr, "Error: out of memory\n");
|
||||
xCloser(sCtx.in);
|
||||
@@ -3041,13 +3049,13 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
|
||||
sqlite3_free(zSql);
|
||||
if( rc ){
|
||||
fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
|
||||
fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
|
||||
if (pStmt) sqlite3_finalize(pStmt);
|
||||
xCloser(sCtx.in);
|
||||
return 1;
|
||||
}
|
||||
needCommit = sqlite3_get_autocommit(db);
|
||||
if( needCommit ) sqlite3_exec(db, "BEGIN", 0, 0, 0);
|
||||
needCommit = sqlite3_get_autocommit(p->db);
|
||||
if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
|
||||
do{
|
||||
int startLine = sCtx.nLine;
|
||||
for(i=0; i<nCol; i++){
|
||||
@@ -3086,7 +3094,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
rc = sqlite3_reset(pStmt);
|
||||
if( rc!=SQLITE_OK ){
|
||||
fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile, startLine,
|
||||
sqlite3_errmsg(db));
|
||||
sqlite3_errmsg(p->db));
|
||||
}
|
||||
}
|
||||
}while( sCtx.cTerm!=EOF );
|
||||
@@ -3094,7 +3102,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
xCloser(sCtx.in);
|
||||
sqlite3_free(sCtx.z);
|
||||
sqlite3_finalize(pStmt);
|
||||
if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0);
|
||||
if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
|
||||
}else
|
||||
|
||||
if( c=='i' && (strncmp(azArg[0], "indices", n)==0
|
||||
@@ -3164,6 +3172,64 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}
|
||||
}else
|
||||
#endif
|
||||
if( c=='l' && n>=5 && strncmp(azArg[0], "limits", n)==0 ){
|
||||
static const struct {
|
||||
const char *zLimitName; /* Name of a limit */
|
||||
int limitCode; /* Integer code for that limit */
|
||||
} aLimit[] = {
|
||||
{ "length", SQLITE_LIMIT_LENGTH },
|
||||
{ "sql_length", SQLITE_LIMIT_SQL_LENGTH },
|
||||
{ "column", SQLITE_LIMIT_COLUMN },
|
||||
{ "expr_depth", SQLITE_LIMIT_EXPR_DEPTH },
|
||||
{ "compound_select", SQLITE_LIMIT_COMPOUND_SELECT },
|
||||
{ "vdbe_op", SQLITE_LIMIT_VDBE_OP },
|
||||
{ "function_arg", SQLITE_LIMIT_FUNCTION_ARG },
|
||||
{ "attached", SQLITE_LIMIT_ATTACHED },
|
||||
{ "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH },
|
||||
{ "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER },
|
||||
{ "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH },
|
||||
{ "worker_threads", SQLITE_LIMIT_WORKER_THREADS },
|
||||
{ "printf_width", SQLITE_LIMIT_PRINTF_WIDTH },
|
||||
};
|
||||
int i, n2;
|
||||
open_db(p, 0);
|
||||
if( nArg==1 ){
|
||||
for(i=0; i<sizeof(aLimit)/sizeof(aLimit[0]); i++){
|
||||
printf("%20s %d\n", aLimit[i].zLimitName,
|
||||
sqlite3_limit(p->db, aLimit[i].limitCode, -1));
|
||||
}
|
||||
}else if( nArg>3 ){
|
||||
fprintf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n");
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}else{
|
||||
int iLimit = -1;
|
||||
n2 = strlen30(azArg[1]);
|
||||
for(i=0; i<sizeof(aLimit)/sizeof(aLimit[0]); i++){
|
||||
if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){
|
||||
if( iLimit<0 ){
|
||||
iLimit = i;
|
||||
}else{
|
||||
fprintf(stderr, "ambiguous limit: \"%s\"\n", azArg[1]);
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( iLimit<0 ){
|
||||
fprintf(stderr, "unknown limit: \"%s\"\n"
|
||||
"enter \".limits\" with no arguments for a list.\n",
|
||||
azArg[1]);
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}
|
||||
if( nArg==3 ){
|
||||
sqlite3_limit(p->db, aLimit[iLimit].limitCode, integerValue(azArg[2]));
|
||||
}
|
||||
printf("%20s %d\n", aLimit[iLimit].zLimitName,
|
||||
sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
|
||||
}
|
||||
}else
|
||||
|
||||
#ifndef SQLITE_OMIT_LOAD_EXTENSION
|
||||
if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
|
||||
@@ -3648,13 +3714,13 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
while( sqlite3_step(pStmt)==SQLITE_ROW ){
|
||||
if( nRow>=nAlloc ){
|
||||
char **azNew;
|
||||
int n = nAlloc*2 + 10;
|
||||
azNew = sqlite3_realloc(azResult, sizeof(azResult[0])*n);
|
||||
int n2 = nAlloc*2 + 10;
|
||||
azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2);
|
||||
if( azNew==0 ){
|
||||
fprintf(stderr, "Error: out of memory\n");
|
||||
break;
|
||||
}
|
||||
nAlloc = n;
|
||||
nAlloc = n2;
|
||||
azResult = azNew;
|
||||
}
|
||||
azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
|
||||
@@ -3707,15 +3773,15 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
{ "imposter", SQLITE_TESTCTRL_IMPOSTER },
|
||||
};
|
||||
int testctrl = -1;
|
||||
int rc = 0;
|
||||
int i, n;
|
||||
int rc2 = 0;
|
||||
int i, n2;
|
||||
open_db(p, 0);
|
||||
|
||||
/* convert testctrl text option to value. allow any unique prefix
|
||||
** of the option name, or a numerical value. */
|
||||
n = strlen30(azArg[1]);
|
||||
n2 = strlen30(azArg[1]);
|
||||
for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
|
||||
if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
|
||||
if( strncmp(azArg[1], aCtrl[i].zCtrlName, n2)==0 ){
|
||||
if( testctrl<0 ){
|
||||
testctrl = aCtrl[i].ctrlCode;
|
||||
}else{
|
||||
@@ -3736,8 +3802,8 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
case SQLITE_TESTCTRL_RESERVE:
|
||||
if( nArg==3 ){
|
||||
int opt = (int)strtol(azArg[2], 0, 0);
|
||||
rc = sqlite3_test_control(testctrl, p->db, opt);
|
||||
fprintf(p->out, "%d (0x%08x)\n", rc, rc);
|
||||
rc2 = sqlite3_test_control(testctrl, p->db, opt);
|
||||
fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
|
||||
} else {
|
||||
fprintf(stderr,"Error: testctrl %s takes a single int option\n",
|
||||
azArg[1]);
|
||||
@@ -3750,8 +3816,8 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
case SQLITE_TESTCTRL_PRNG_RESET:
|
||||
case SQLITE_TESTCTRL_BYTEORDER:
|
||||
if( nArg==2 ){
|
||||
rc = sqlite3_test_control(testctrl);
|
||||
fprintf(p->out, "%d (0x%08x)\n", rc, rc);
|
||||
rc2 = sqlite3_test_control(testctrl);
|
||||
fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
|
||||
} else {
|
||||
fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
|
||||
}
|
||||
@@ -3761,8 +3827,8 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
case SQLITE_TESTCTRL_PENDING_BYTE:
|
||||
if( nArg==3 ){
|
||||
unsigned int opt = (unsigned int)integerValue(azArg[2]);
|
||||
rc = sqlite3_test_control(testctrl, opt);
|
||||
fprintf(p->out, "%d (0x%08x)\n", rc, rc);
|
||||
rc2 = sqlite3_test_control(testctrl, opt);
|
||||
fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
|
||||
} else {
|
||||
fprintf(stderr,"Error: testctrl %s takes a single unsigned"
|
||||
" int option\n", azArg[1]);
|
||||
@@ -3775,8 +3841,8 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
case SQLITE_TESTCTRL_NEVER_CORRUPT:
|
||||
if( nArg==3 ){
|
||||
int opt = booleanValue(azArg[2]);
|
||||
rc = sqlite3_test_control(testctrl, opt);
|
||||
fprintf(p->out, "%d (0x%08x)\n", rc, rc);
|
||||
rc2 = sqlite3_test_control(testctrl, opt);
|
||||
fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
|
||||
} else {
|
||||
fprintf(stderr,"Error: testctrl %s takes a single int option\n",
|
||||
azArg[1]);
|
||||
@@ -3788,8 +3854,8 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
case SQLITE_TESTCTRL_ISKEYWORD:
|
||||
if( nArg==3 ){
|
||||
const char *opt = azArg[2];
|
||||
rc = sqlite3_test_control(testctrl, opt);
|
||||
fprintf(p->out, "%d (0x%08x)\n", rc, rc);
|
||||
rc2 = sqlite3_test_control(testctrl, opt);
|
||||
fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
|
||||
} else {
|
||||
fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
|
||||
azArg[1]);
|
||||
@@ -3799,11 +3865,11 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
|
||||
case SQLITE_TESTCTRL_IMPOSTER:
|
||||
if( nArg==5 ){
|
||||
rc = sqlite3_test_control(testctrl, p->db,
|
||||
rc2 = sqlite3_test_control(testctrl, p->db,
|
||||
azArg[2],
|
||||
integerValue(azArg[3]),
|
||||
integerValue(azArg[4]));
|
||||
fprintf(p->out, "%d (0x%08x)\n", rc, rc);
|
||||
fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
|
||||
}else{
|
||||
fprintf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n");
|
||||
}
|
||||
@@ -4111,6 +4177,7 @@ static int process_input(ShellState *p, FILE *in){
|
||||
&& sqlite3_complete(zSql) ){
|
||||
p->cnt = 0;
|
||||
open_db(p, 0);
|
||||
if( p->backslashOn ) resolve_backslashes(zSql);
|
||||
BEGIN_TIMER;
|
||||
rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
|
||||
END_TIMER;
|
||||
@@ -4577,6 +4644,13 @@ int SQLITE_CDECL main(int argc, char **argv){
|
||||
data.statsOn = 1;
|
||||
}else if( strcmp(z,"-scanstats")==0 ){
|
||||
data.scanstatsOn = 1;
|
||||
}else if( strcmp(z,"-backslash")==0 ){
|
||||
/* Undocumented command-line option: -backslash
|
||||
** Causes C-style backslash escapes to be evaluated in SQL statements
|
||||
** prior to sending the SQL into SQLite. Useful for injecting
|
||||
** crazy bytes in the middle of SQL statements for testing and debugging.
|
||||
*/
|
||||
data.backslashOn = 1;
|
||||
}else if( strcmp(z,"-bail")==0 ){
|
||||
bail_on_error = 1;
|
||||
}else if( strcmp(z,"-version")==0 ){
|
||||
|
||||
@@ -3190,6 +3190,17 @@ int sqlite3_limit(sqlite3*, int id, int newVal);
|
||||
** [[SQLITE_LIMIT_WORKER_THREADS]] ^(<dt>SQLITE_LIMIT_WORKER_THREADS</dt>
|
||||
** <dd>The maximum number of auxiliary worker threads that a single
|
||||
** [prepared statement] may start.</dd>)^
|
||||
**
|
||||
** [[SQLITE_LIMIT_PRINTF_WIDTH]] ^(<dt>SQLITE_LIMIT_PRINTF_WIDTH</dt>
|
||||
** <dd>The maximum absolute value of the width or precision of a
|
||||
** format specifier in the [printf SQL function].)^ ^Any invocation of
|
||||
** the [printf SQL function] containing a width or precision larger than
|
||||
** this limit (or smaller than the negative of this limit) causes an
|
||||
** [SQLITE_TOOBIG] exception to be thrown. <p>This limit applies
|
||||
** to the SQL function printf() only, and not to the various C-language
|
||||
** printf-style interfaces such as [sqlite3_mprintf()]. For the C-language
|
||||
** interfaces, the width and precision can be any 32-bit signed
|
||||
** integer.
|
||||
** </dl>
|
||||
*/
|
||||
#define SQLITE_LIMIT_LENGTH 0
|
||||
@@ -3204,6 +3215,7 @@ int sqlite3_limit(sqlite3*, int id, int newVal);
|
||||
#define SQLITE_LIMIT_VARIABLE_NUMBER 9
|
||||
#define SQLITE_LIMIT_TRIGGER_DEPTH 10
|
||||
#define SQLITE_LIMIT_WORKER_THREADS 11
|
||||
#define SQLITE_LIMIT_PRINTF_WIDTH 12
|
||||
|
||||
/*
|
||||
** CAPI3REF: Compiling An SQL Statement
|
||||
|
||||
+49
-43
@@ -362,6 +362,32 @@
|
||||
# define NEVER(X) (X)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Declarations used for tracing the operating system interfaces.
|
||||
*/
|
||||
#if defined(SQLITE_FORCE_OS_TRACE) || defined(SQLITE_TEST) || \
|
||||
(defined(SQLITE_DEBUG) && SQLITE_OS_WIN)
|
||||
extern int sqlite3OSTrace;
|
||||
# define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X
|
||||
# define SQLITE_HAVE_OS_TRACE
|
||||
#else
|
||||
# define OSTRACE(X)
|
||||
# undef SQLITE_HAVE_OS_TRACE
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Is the sqlite3ErrName() function needed in the build? Currently,
|
||||
** it is needed by "mutex_w32.c" (when debugging), "os_win.c" (when
|
||||
** OSTRACE is enabled), and by several "test*.c" files (which are
|
||||
** compiled using SQLITE_TEST).
|
||||
*/
|
||||
#if defined(SQLITE_HAVE_OS_TRACE) || defined(SQLITE_TEST) || \
|
||||
(defined(SQLITE_DEBUG) && SQLITE_OS_WIN)
|
||||
# define SQLITE_NEED_ERR_NAME
|
||||
#else
|
||||
# undef SQLITE_NEED_ERR_NAME
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Return true (non-zero) if the input is an integer that is too large
|
||||
** to fit in 32-bits. This macro is used inside of various testcase()
|
||||
@@ -983,7 +1009,7 @@ struct Schema {
|
||||
** The number of different kinds of things that can be limited
|
||||
** using the sqlite3_limit() interface.
|
||||
*/
|
||||
#define SQLITE_N_LIMIT (SQLITE_LIMIT_WORKER_THREADS+1)
|
||||
#define SQLITE_N_LIMIT (SQLITE_LIMIT_PRINTF_WIDTH+1)
|
||||
|
||||
/*
|
||||
** Lookaside malloc is a set of fixed-size buffers that can be used
|
||||
@@ -1557,34 +1583,8 @@ struct VTable {
|
||||
};
|
||||
|
||||
/*
|
||||
** Each SQL table is represented in memory by an instance of the
|
||||
** following structure.
|
||||
**
|
||||
** Table.zName is the name of the table. The case of the original
|
||||
** CREATE TABLE statement is stored, but case is not significant for
|
||||
** comparisons.
|
||||
**
|
||||
** Table.nCol is the number of columns in this table. Table.aCol is a
|
||||
** pointer to an array of Column structures, one for each column.
|
||||
**
|
||||
** If the table has an INTEGER PRIMARY KEY, then Table.iPKey is the index of
|
||||
** the column that is that key. Otherwise Table.iPKey is negative. Note
|
||||
** that the datatype of the PRIMARY KEY must be INTEGER for this field to
|
||||
** be set. An INTEGER PRIMARY KEY is used as the rowid for each row of
|
||||
** the table. If a table has no INTEGER PRIMARY KEY, then a random rowid
|
||||
** is generated for each row of the table. TF_HasPrimaryKey is set if
|
||||
** the table has any PRIMARY KEY, INTEGER or otherwise.
|
||||
**
|
||||
** Table.tnum is the page number for the root BTree page of the table in the
|
||||
** database file. If Table.iDb is the index of the database table backend
|
||||
** in sqlite.aDb[]. 0 is for the main database and 1 is for the file that
|
||||
** holds temporary tables and indices. If TF_Ephemeral is set
|
||||
** then the table is stored in a file that is automatically deleted
|
||||
** when the VDBE cursor to the table is closed. In this case Table.tnum
|
||||
** refers VDBE cursor number that holds the table open, not to the root
|
||||
** page number. Transient tables are used to hold the results of a
|
||||
** sub-query that appears instead of a real table name in the FROM clause
|
||||
** of a SELECT statement.
|
||||
** The schema for each SQL table and view is represented in memory
|
||||
** by an instance of the following structure.
|
||||
*/
|
||||
struct Table {
|
||||
char *zName; /* Name of the table or view */
|
||||
@@ -1596,11 +1596,11 @@ struct Table {
|
||||
#ifndef SQLITE_OMIT_CHECK
|
||||
ExprList *pCheck; /* All CHECK constraints */
|
||||
#endif
|
||||
LogEst nRowLogEst; /* 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 */
|
||||
int tnum; /* Root BTree page for this table */
|
||||
i16 iPKey; /* If not negative, use aCol[iPKey] as the rowid */
|
||||
i16 nCol; /* Number of columns in this table */
|
||||
u16 nRef; /* Number of pointers to this Table */
|
||||
LogEst nRowLogEst; /* Estimated rows in table - from sqlite_stat1 table */
|
||||
LogEst szTabRow; /* Estimated size of each table row in bytes */
|
||||
#ifdef SQLITE_ENABLE_COSTMULT
|
||||
LogEst costMult; /* Cost multiplier for using this table */
|
||||
@@ -1622,6 +1622,12 @@ struct Table {
|
||||
|
||||
/*
|
||||
** Allowed values for Table.tabFlags.
|
||||
**
|
||||
** TF_OOOHidden applies to virtual tables that have hidden columns that are
|
||||
** followed by non-hidden columns. Example: "CREATE VIRTUAL TABLE x USING
|
||||
** vtab1(a HIDDEN, b);". Since "b" is a non-hidden column but "a" is hidden,
|
||||
** the TF_OOOHidden attribute would apply in this case. Such tables require
|
||||
** special handling during INSERT processing.
|
||||
*/
|
||||
#define TF_Readonly 0x01 /* Read-only system table */
|
||||
#define TF_Ephemeral 0x02 /* An ephemeral table */
|
||||
@@ -1629,6 +1635,7 @@ struct Table {
|
||||
#define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */
|
||||
#define TF_Virtual 0x10 /* Is a virtual table */
|
||||
#define TF_WithoutRowid 0x20 /* No rowid used. PRIMARY KEY is the key */
|
||||
#define TF_OOOHidden 0x40 /* Out-of-Order hidden columns */
|
||||
|
||||
|
||||
/*
|
||||
@@ -2385,7 +2392,7 @@ struct Select {
|
||||
#define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */
|
||||
#define SF_Compound 0x0040 /* Part of a compound query */
|
||||
#define SF_Values 0x0080 /* Synthesized from VALUES clause */
|
||||
#define SF_AllValues 0x0100 /* All terms of compound are VALUES */
|
||||
#define SF_MultiValue 0x0100 /* Single VALUES term with multiple rows */
|
||||
#define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */
|
||||
#define SF_MaybeConvert 0x0400 /* Need convertCompoundSelectToSubquery() */
|
||||
#define SF_Recursive 0x0800 /* The recursive part of a recursive CTE */
|
||||
@@ -2769,7 +2776,7 @@ struct Trigger {
|
||||
* orconf -> stores the ON CONFLICT algorithm
|
||||
* pSelect -> If this is an INSERT INTO ... SELECT ... statement, then
|
||||
* this stores a pointer to the SELECT statement. Otherwise NULL.
|
||||
* target -> A token holding the quoted name of the table to insert into.
|
||||
* zTarget -> Dequoted name of the table to insert into.
|
||||
* pExprList -> If this is an INSERT INTO ... VALUES ... statement, then
|
||||
* this stores values to be inserted. Otherwise NULL.
|
||||
* pIdList -> If this is an INSERT INTO ... (<column-names>) VALUES ...
|
||||
@@ -2777,12 +2784,12 @@ struct Trigger {
|
||||
* inserted into.
|
||||
*
|
||||
* (op == TK_DELETE)
|
||||
* target -> A token holding the quoted name of the table to delete from.
|
||||
* zTarget -> Dequoted name of the table to delete from.
|
||||
* pWhere -> The WHERE clause of the DELETE statement if one is specified.
|
||||
* Otherwise NULL.
|
||||
*
|
||||
* (op == TK_UPDATE)
|
||||
* target -> A token holding the quoted name of the table to update rows of.
|
||||
* zTarget -> Dequoted name of the table to update.
|
||||
* pWhere -> The WHERE clause of the UPDATE statement if one is specified.
|
||||
* Otherwise NULL.
|
||||
* pExprList -> A list of the columns to update and the expressions to update
|
||||
@@ -2794,8 +2801,8 @@ struct TriggerStep {
|
||||
u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */
|
||||
u8 orconf; /* OE_Rollback etc. */
|
||||
Trigger *pTrig; /* The trigger that this step is a part of */
|
||||
Select *pSelect; /* SELECT statment or RHS of INSERT INTO .. SELECT ... */
|
||||
Token target; /* Target table for DELETE, UPDATE, INSERT */
|
||||
Select *pSelect; /* SELECT statement or RHS of INSERT INTO SELECT ... */
|
||||
char *zTarget; /* Target table for DELETE, UPDATE, INSERT */
|
||||
Expr *pWhere; /* The WHERE clause for DELETE or UPDATE steps */
|
||||
ExprList *pExprList; /* SET clause for UPDATE. */
|
||||
IdList *pIdList; /* Column names for INSERT */
|
||||
@@ -2828,8 +2835,7 @@ struct StrAccum {
|
||||
char *zText; /* The string collected so far */
|
||||
int nChar; /* Length of the string so far */
|
||||
int nAlloc; /* Amount of space allocated in zText */
|
||||
int mxAlloc; /* Maximum allowed string length */
|
||||
u8 useMalloc; /* 0: none, 1: sqlite3DbMalloc, 2: sqlite3_malloc */
|
||||
int mxAlloc; /* Maximum allowed allocation. 0 for no malloc usage */
|
||||
u8 accError; /* STRACCUM_NOMEM or STRACCUM_TOOBIG */
|
||||
};
|
||||
#define STRACCUM_NOMEM 1
|
||||
@@ -3146,7 +3152,7 @@ void sqlite3XPrintf(StrAccum*, u32, const char*, ...);
|
||||
char *sqlite3MPrintf(sqlite3*,const char*, ...);
|
||||
char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
|
||||
char *sqlite3MAppendf(sqlite3*,char*,const char*,...);
|
||||
#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
|
||||
#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
|
||||
void sqlite3DebugPrintf(const char*, ...);
|
||||
#endif
|
||||
#if defined(SQLITE_TEST)
|
||||
@@ -3493,7 +3499,7 @@ void *sqlite3HexToBlob(sqlite3*, const char *z, int n);
|
||||
u8 sqlite3HexToInt(int h);
|
||||
int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
|
||||
|
||||
#if defined(SQLITE_TEST)
|
||||
#if defined(SQLITE_NEED_ERR_NAME)
|
||||
const char *sqlite3ErrName(int);
|
||||
#endif
|
||||
|
||||
@@ -3587,7 +3593,7 @@ int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *,
|
||||
int sqlite3ApiExit(sqlite3 *db, int);
|
||||
int sqlite3OpenTempDatabase(Parse *);
|
||||
|
||||
void sqlite3StrAccumInit(StrAccum*, char*, int, int);
|
||||
void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int);
|
||||
void sqlite3StrAccumAppend(StrAccum*,const char*,int);
|
||||
void sqlite3StrAccumAppendAll(StrAccum*,const char*);
|
||||
void sqlite3AppendChar(StrAccum*,int,char);
|
||||
|
||||
@@ -208,3 +208,11 @@
|
||||
#ifndef SQLITE_MAX_TRIGGER_DEPTH
|
||||
# define SQLITE_MAX_TRIGGER_DEPTH 1000
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Maximum width or precision of a format specification in the SQL printf()
|
||||
** function.
|
||||
*/
|
||||
#ifndef SQLITE_MAX_PRINTF_WIDTH
|
||||
# define SQLITE_MAX_PRINTF_WIDTH 0x7fffffff
|
||||
#endif
|
||||
|
||||
+3
-3
@@ -90,7 +90,7 @@ static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
|
||||
z = 0;
|
||||
}else{
|
||||
int n = sqlite3Strlen30(argv[i])+1;
|
||||
z = sqlite3_malloc( n );
|
||||
z = sqlite3_malloc64( n );
|
||||
if( z==0 ) goto malloc_failed;
|
||||
memcpy(z, argv[i], n);
|
||||
}
|
||||
@@ -139,7 +139,7 @@ int sqlite3_get_table(
|
||||
res.nData = 1;
|
||||
res.nAlloc = 20;
|
||||
res.rc = SQLITE_OK;
|
||||
res.azResult = sqlite3_malloc(sizeof(char*)*res.nAlloc );
|
||||
res.azResult = sqlite3_malloc64(sizeof(char*)*res.nAlloc );
|
||||
if( res.azResult==0 ){
|
||||
db->errCode = SQLITE_NOMEM;
|
||||
return SQLITE_NOMEM;
|
||||
@@ -167,7 +167,7 @@ int sqlite3_get_table(
|
||||
}
|
||||
if( res.nAlloc>res.nData ){
|
||||
char **azNew;
|
||||
azNew = sqlite3_realloc( res.azResult, sizeof(char*)*res.nData );
|
||||
azNew = sqlite3_realloc64( res.azResult, sizeof(char*)*res.nData );
|
||||
if( azNew==0 ){
|
||||
sqlite3_free_table(&res.azResult[1]);
|
||||
db->errCode = SQLITE_NOMEM;
|
||||
|
||||
+5
-5
@@ -1191,7 +1191,7 @@ static int dbPrepareAndBind(
|
||||
int n;
|
||||
u8 *data;
|
||||
const char *zType = (pVar->typePtr ? pVar->typePtr->name : "");
|
||||
char c = zType[0];
|
||||
c = zType[0];
|
||||
if( zVar[0]=='@' ||
|
||||
(c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0) ){
|
||||
/* Load a BLOB type if the Tcl variable is a bytearray and
|
||||
@@ -2298,7 +2298,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
}
|
||||
Tcl_DecrRefCount(pRet);
|
||||
}else{
|
||||
ClientData cd[2];
|
||||
ClientData cd2[2];
|
||||
DbEvalContext *p;
|
||||
Tcl_Obj *pArray = 0;
|
||||
Tcl_Obj *pScript;
|
||||
@@ -2312,9 +2312,9 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
p = (DbEvalContext *)Tcl_Alloc(sizeof(DbEvalContext));
|
||||
dbEvalInit(p, pDb, objv[2], pArray);
|
||||
|
||||
cd[0] = (void *)p;
|
||||
cd[1] = (void *)pScript;
|
||||
rc = DbEvalNextCmd(cd, interp, TCL_OK);
|
||||
cd2[0] = (void *)p;
|
||||
cd2[1] = (void *)pScript;
|
||||
rc = DbEvalNextCmd(cd2, interp, TCL_OK);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
+2
-1
@@ -5451,10 +5451,11 @@ static int test_limit(
|
||||
{ "SQLITE_LIMIT_VARIABLE_NUMBER", SQLITE_LIMIT_VARIABLE_NUMBER },
|
||||
{ "SQLITE_LIMIT_TRIGGER_DEPTH", SQLITE_LIMIT_TRIGGER_DEPTH },
|
||||
{ "SQLITE_LIMIT_WORKER_THREADS", SQLITE_LIMIT_WORKER_THREADS },
|
||||
{ "SQLITE_LIMIT_PRINTF_WIDTH", SQLITE_LIMIT_PRINTF_WIDTH },
|
||||
|
||||
/* Out of range test cases */
|
||||
{ "SQLITE_LIMIT_TOOSMALL", -1, },
|
||||
{ "SQLITE_LIMIT_TOOBIG", SQLITE_LIMIT_WORKER_THREADS+1 },
|
||||
{ "SQLITE_LIMIT_TOOBIG", SQLITE_LIMIT_PRINTF_WIDTH+1 },
|
||||
};
|
||||
int i, id = 0;
|
||||
int val;
|
||||
|
||||
+4
-4
@@ -85,7 +85,7 @@ static int intarrayCreate(
|
||||
char **pzErr /* Put error message text here */
|
||||
){
|
||||
int rc = SQLITE_NOMEM;
|
||||
intarray_vtab *pVtab = sqlite3_malloc(sizeof(intarray_vtab));
|
||||
intarray_vtab *pVtab = sqlite3_malloc64(sizeof(intarray_vtab));
|
||||
|
||||
if( pVtab ){
|
||||
memset(pVtab, 0, sizeof(intarray_vtab));
|
||||
@@ -102,7 +102,7 @@ static int intarrayCreate(
|
||||
static int intarrayOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
|
||||
int rc = SQLITE_NOMEM;
|
||||
intarray_cursor *pCur;
|
||||
pCur = sqlite3_malloc(sizeof(intarray_cursor));
|
||||
pCur = sqlite3_malloc64(sizeof(intarray_cursor));
|
||||
if( pCur ){
|
||||
memset(pCur, 0, sizeof(intarray_cursor));
|
||||
*ppCursor = (sqlite3_vtab_cursor *)pCur;
|
||||
@@ -225,7 +225,7 @@ SQLITE_API int sqlite3_intarray_create(
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
sqlite3_intarray *p;
|
||||
|
||||
*ppReturn = p = sqlite3_malloc( sizeof(*p) );
|
||||
*ppReturn = p = sqlite3_malloc64( sizeof(*p) );
|
||||
if( p==0 ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
@@ -340,7 +340,7 @@ static int test_intarray_bind(
|
||||
pArray = (sqlite3_intarray*)sqlite3TestTextToPtr(Tcl_GetString(objv[1]));
|
||||
n = objc - 2;
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
a = sqlite3_malloc( sizeof(a[0])*n );
|
||||
a = sqlite3_malloc64( sizeof(a[0])*n );
|
||||
if( a==0 ){
|
||||
Tcl_AppendResult(interp, "SQLITE_NOMEM", (char*)0);
|
||||
return TCL_ERROR;
|
||||
|
||||
+5
-5
@@ -211,15 +211,15 @@ static int faultsimInstall(int install){
|
||||
faultsimBeginBenign, faultsimEndBenign
|
||||
);
|
||||
}else{
|
||||
sqlite3_mem_methods m;
|
||||
sqlite3_mem_methods m2;
|
||||
assert(memfault.m.xMalloc);
|
||||
|
||||
/* One should be able to reset the default memory allocator by storing
|
||||
** a zeroed allocator then calling GETMALLOC. */
|
||||
memset(&m, 0, sizeof(m));
|
||||
sqlite3_config(SQLITE_CONFIG_MALLOC, &m);
|
||||
sqlite3_config(SQLITE_CONFIG_GETMALLOC, &m);
|
||||
assert( memcmp(&m, &memfault.m, sizeof(m))==0 );
|
||||
memset(&m2, 0, sizeof(m2));
|
||||
sqlite3_config(SQLITE_CONFIG_MALLOC, &m2);
|
||||
sqlite3_config(SQLITE_CONFIG_GETMALLOC, &m2);
|
||||
assert( memcmp(&m2, &memfault.m, sizeof(m2))==0 );
|
||||
|
||||
rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &memfault.m);
|
||||
sqlite3_test_control(SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, 0, 0);
|
||||
|
||||
+12
-12
@@ -286,7 +286,7 @@ static void multiplexFilename(
|
||||
static int multiplexSubFilename(multiplexGroup *pGroup, int iChunk){
|
||||
if( iChunk>=pGroup->nReal ){
|
||||
struct multiplexReal *p;
|
||||
p = sqlite3_realloc(pGroup->aReal, (iChunk+1)*sizeof(*p));
|
||||
p = sqlite3_realloc64(pGroup->aReal, (iChunk+1)*sizeof(*p));
|
||||
if( p==0 ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
@@ -297,7 +297,7 @@ static int multiplexSubFilename(multiplexGroup *pGroup, int iChunk){
|
||||
if( pGroup->zName && pGroup->aReal[iChunk].z==0 ){
|
||||
char *z;
|
||||
int n = pGroup->nName;
|
||||
pGroup->aReal[iChunk].z = z = sqlite3_malloc( n+5 );
|
||||
pGroup->aReal[iChunk].z = z = sqlite3_malloc64( n+5 );
|
||||
if( z==0 ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
@@ -357,7 +357,7 @@ static sqlite3_file *multiplexSubOpen(
|
||||
}
|
||||
flags &= ~SQLITE_OPEN_CREATE;
|
||||
}
|
||||
pSubOpen = sqlite3_malloc( pOrigVfs->szOsFile );
|
||||
pSubOpen = sqlite3_malloc64( pOrigVfs->szOsFile );
|
||||
if( pSubOpen==0 ){
|
||||
*rc = SQLITE_IOERR_NOMEM;
|
||||
return 0;
|
||||
@@ -524,7 +524,7 @@ static int multiplexOpen(
|
||||
nName = zName ? multiplexStrlen30(zName) : 0;
|
||||
sz = sizeof(multiplexGroup) /* multiplexGroup */
|
||||
+ nName + 1; /* zName */
|
||||
pGroup = sqlite3_malloc( sz );
|
||||
pGroup = sqlite3_malloc64( sz );
|
||||
if( pGroup==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}
|
||||
@@ -568,15 +568,15 @@ static int multiplexOpen(
|
||||
if( pSubOpen==0 && rc==SQLITE_OK ) rc = SQLITE_CANTOPEN;
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3_int64 sz;
|
||||
sqlite3_int64 sz64;
|
||||
|
||||
rc = pSubOpen->pMethods->xFileSize(pSubOpen, &sz);
|
||||
rc = pSubOpen->pMethods->xFileSize(pSubOpen, &sz64);
|
||||
if( rc==SQLITE_OK && zName ){
|
||||
int bExists;
|
||||
if( flags & SQLITE_OPEN_MASTER_JOURNAL ){
|
||||
pGroup->bEnabled = 0;
|
||||
}else
|
||||
if( sz==0 ){
|
||||
if( sz64==0 ){
|
||||
if( flags & SQLITE_OPEN_MAIN_JOURNAL ){
|
||||
/* If opening a main journal file and the first chunk is zero
|
||||
** bytes in size, delete any subsequent chunks from the
|
||||
@@ -607,10 +607,10 @@ static int multiplexOpen(
|
||||
rc = pOrigVfs->xAccess(pOrigVfs, pGroup->aReal[1].z,
|
||||
SQLITE_ACCESS_EXISTS, &bExists);
|
||||
bExists = multiplexSubSize(pGroup, 1, &rc)>0;
|
||||
if( rc==SQLITE_OK && bExists && sz==(sz&0xffff0000) && sz>0
|
||||
&& sz!=pGroup->szChunk ){
|
||||
pGroup->szChunk = (int)sz;
|
||||
}else if( rc==SQLITE_OK && !bExists && sz>pGroup->szChunk ){
|
||||
if( rc==SQLITE_OK && bExists && sz64==(sz64&0xffff0000) && sz64>0
|
||||
&& sz64!=pGroup->szChunk ){
|
||||
pGroup->szChunk = (int)sz64;
|
||||
}else if( rc==SQLITE_OK && !bExists && sz64>pGroup->szChunk ){
|
||||
pGroup->bEnabled = 0;
|
||||
}
|
||||
}
|
||||
@@ -655,7 +655,7 @@ static int multiplexDelete(
|
||||
*/
|
||||
int nName = (int)strlen(zName);
|
||||
char *z;
|
||||
z = sqlite3_malloc(nName + 5);
|
||||
z = sqlite3_malloc64(nName + 5);
|
||||
if( z==0 ){
|
||||
rc = SQLITE_IOERR_NOMEM;
|
||||
}else{
|
||||
|
||||
+3
-3
@@ -595,9 +595,9 @@ static int fsOpen(
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
if( 0==(flags&(SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_MAIN_JOURNAL)) ){
|
||||
tmp_file *p = (tmp_file *)pFile;
|
||||
memset(p, 0, sizeof(*p));
|
||||
p->base.pMethods = &tmp_io_methods;
|
||||
tmp_file *p2 = (tmp_file *)pFile;
|
||||
memset(p2, 0, sizeof(*p2));
|
||||
p2->base.pMethods = &tmp_io_methods;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -1131,7 +1131,6 @@ static int test_vfslog(
|
||||
|
||||
switch( (enum VL_enum)iSub ){
|
||||
case VL_ANNOTATE: {
|
||||
int rc;
|
||||
char *zVfs;
|
||||
char *zMsg;
|
||||
if( objc!=4 ){
|
||||
@@ -1148,7 +1147,6 @@ static int test_vfslog(
|
||||
break;
|
||||
}
|
||||
case VL_FINALIZE: {
|
||||
int rc;
|
||||
char *zVfs;
|
||||
if( objc!=3 ){
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "VFS");
|
||||
@@ -1164,7 +1162,6 @@ static int test_vfslog(
|
||||
};
|
||||
|
||||
case VL_NEW: {
|
||||
int rc;
|
||||
char *zVfs;
|
||||
char *zParent;
|
||||
char *zLog;
|
||||
|
||||
+68
-51
@@ -140,15 +140,23 @@ static int statConnect(
|
||||
sqlite3_vtab **ppVtab,
|
||||
char **pzErr
|
||||
){
|
||||
StatTable *pTab;
|
||||
StatTable *pTab = 0;
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
pTab = (StatTable *)sqlite3_malloc(sizeof(StatTable));
|
||||
memset(pTab, 0, sizeof(StatTable));
|
||||
pTab->db = db;
|
||||
rc = sqlite3_declare_vtab(db, VTAB_SCHEMA);
|
||||
if( rc==SQLITE_OK ){
|
||||
pTab = (StatTable *)sqlite3_malloc64(sizeof(StatTable));
|
||||
if( pTab==0 ) rc = SQLITE_NOMEM;
|
||||
}
|
||||
|
||||
sqlite3_declare_vtab(db, VTAB_SCHEMA);
|
||||
*ppVtab = &pTab->base;
|
||||
return SQLITE_OK;
|
||||
assert( rc==SQLITE_OK || pTab==0 );
|
||||
if( rc==SQLITE_OK ){
|
||||
memset(pTab, 0, sizeof(StatTable));
|
||||
pTab->db = db;
|
||||
}
|
||||
|
||||
*ppVtab = (sqlite3_vtab*)pTab;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -195,33 +203,39 @@ static int statOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
|
||||
StatCursor *pCsr;
|
||||
int rc;
|
||||
|
||||
pCsr = (StatCursor *)sqlite3_malloc(sizeof(StatCursor));
|
||||
memset(pCsr, 0, sizeof(StatCursor));
|
||||
pCsr->base.pVtab = pVTab;
|
||||
pCsr = (StatCursor *)sqlite3_malloc64(sizeof(StatCursor));
|
||||
if( pCsr==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
memset(pCsr, 0, sizeof(StatCursor));
|
||||
pCsr->base.pVtab = pVTab;
|
||||
|
||||
rc = sqlite3_prepare_v2(pTab->db,
|
||||
"SELECT 'sqlite_master' AS name, 1 AS rootpage, 'table' AS type"
|
||||
" UNION ALL "
|
||||
"SELECT name, rootpage, type FROM sqlite_master WHERE rootpage!=0"
|
||||
" ORDER BY name", -1,
|
||||
&pCsr->pStmt, 0
|
||||
);
|
||||
if( rc!=SQLITE_OK ){
|
||||
sqlite3_free(pCsr);
|
||||
return rc;
|
||||
rc = sqlite3_prepare_v2(pTab->db,
|
||||
"SELECT 'sqlite_master' AS name, 1 AS rootpage, 'table' AS type"
|
||||
" UNION ALL "
|
||||
"SELECT name, rootpage, type FROM sqlite_master WHERE rootpage!=0"
|
||||
" ORDER BY name", -1,
|
||||
&pCsr->pStmt, 0
|
||||
);
|
||||
if( rc!=SQLITE_OK ){
|
||||
sqlite3_free(pCsr);
|
||||
pCsr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
*ppCursor = (sqlite3_vtab_cursor *)pCsr;
|
||||
return SQLITE_OK;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void statClearPage(StatPage *p){
|
||||
int i;
|
||||
for(i=0; i<p->nCell; i++){
|
||||
sqlite3_free(p->aCell[i].aOvfl);
|
||||
if( p->aCell ){
|
||||
for(i=0; i<p->nCell; i++){
|
||||
sqlite3_free(p->aCell[i].aOvfl);
|
||||
}
|
||||
sqlite3_free(p->aCell);
|
||||
}
|
||||
sqlite3PagerUnref(p->pPg);
|
||||
sqlite3_free(p->aCell);
|
||||
sqlite3_free(p->zPath);
|
||||
memset(p, 0, sizeof(StatPage));
|
||||
}
|
||||
@@ -306,7 +320,8 @@ static int statDecodePage(Btree *pBt, StatPage *p){
|
||||
sqlite3BtreeEnter(pBt);
|
||||
nUsable = szPage - sqlite3BtreeGetReserveNoMutex(pBt);
|
||||
sqlite3BtreeLeave(pBt);
|
||||
p->aCell = sqlite3_malloc((p->nCell+1) * sizeof(StatCell));
|
||||
p->aCell = sqlite3_malloc64((p->nCell+1) * sizeof(StatCell));
|
||||
if( p->aCell==0 ) return SQLITE_NOMEM;
|
||||
memset(p->aCell, 0, (p->nCell+1) * sizeof(StatCell));
|
||||
|
||||
for(i=0; i<p->nCell; i++){
|
||||
@@ -338,7 +353,8 @@ static int statDecodePage(Btree *pBt, StatPage *p){
|
||||
int nOvfl = ((nPayload - nLocal) + nUsable-4 - 1) / (nUsable - 4);
|
||||
pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4);
|
||||
pCell->nOvfl = nOvfl;
|
||||
pCell->aOvfl = sqlite3_malloc(sizeof(u32)*nOvfl);
|
||||
pCell->aOvfl = sqlite3_malloc64(sizeof(u32)*nOvfl);
|
||||
if( pCell->aOvfl==0 ) return SQLITE_NOMEM;
|
||||
pCell->aOvfl[0] = sqlite3Get4byte(&aData[iOff+nLocal]);
|
||||
for(j=1; j<nOvfl; j++){
|
||||
int rc;
|
||||
@@ -486,31 +502,33 @@ statNextRestart:
|
||||
pCsr->zName = (char *)sqlite3_column_text(pCsr->pStmt, 0);
|
||||
pCsr->iPageno = p->iPgno;
|
||||
|
||||
statDecodePage(pBt, p);
|
||||
statSizeAndOffset(pCsr);
|
||||
rc = statDecodePage(pBt, p);
|
||||
if( rc==SQLITE_OK ){
|
||||
statSizeAndOffset(pCsr);
|
||||
|
||||
switch( p->flags ){
|
||||
case 0x05: /* table internal */
|
||||
case 0x02: /* index internal */
|
||||
pCsr->zPagetype = "internal";
|
||||
break;
|
||||
case 0x0D: /* table leaf */
|
||||
case 0x0A: /* index leaf */
|
||||
pCsr->zPagetype = "leaf";
|
||||
break;
|
||||
default:
|
||||
pCsr->zPagetype = "corrupted";
|
||||
break;
|
||||
switch( p->flags ){
|
||||
case 0x05: /* table internal */
|
||||
case 0x02: /* index internal */
|
||||
pCsr->zPagetype = "internal";
|
||||
break;
|
||||
case 0x0D: /* table leaf */
|
||||
case 0x0A: /* index leaf */
|
||||
pCsr->zPagetype = "leaf";
|
||||
break;
|
||||
default:
|
||||
pCsr->zPagetype = "corrupted";
|
||||
break;
|
||||
}
|
||||
pCsr->nCell = p->nCell;
|
||||
pCsr->nUnused = p->nUnused;
|
||||
pCsr->nMxPayload = p->nMxPayload;
|
||||
pCsr->zPath = sqlite3_mprintf("%s", p->zPath);
|
||||
nPayload = 0;
|
||||
for(i=0; i<p->nCell; i++){
|
||||
nPayload += p->aCell[i].nLocal;
|
||||
}
|
||||
pCsr->nPayload = nPayload;
|
||||
}
|
||||
pCsr->nCell = p->nCell;
|
||||
pCsr->nUnused = p->nUnused;
|
||||
pCsr->nMxPayload = p->nMxPayload;
|
||||
pCsr->zPath = sqlite3_mprintf("%s", p->zPath);
|
||||
nPayload = 0;
|
||||
for(i=0; i<p->nCell; i++){
|
||||
nPayload += p->aCell[i].nLocal;
|
||||
}
|
||||
pCsr->nPayload = nPayload;
|
||||
}
|
||||
|
||||
return rc;
|
||||
@@ -602,8 +620,7 @@ int sqlite3_dbstat_register(sqlite3 *db){
|
||||
0, /* xFindMethod */
|
||||
0, /* xRename */
|
||||
};
|
||||
sqlite3_create_module(db, "dbstat", &dbstat_module, 0);
|
||||
return SQLITE_OK;
|
||||
return sqlite3_create_module(db, "dbstat", &dbstat_module, 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+1
-2
@@ -1080,7 +1080,7 @@ static int testvfs_obj_cmd(
|
||||
switch( aSubcmd[i].eCmd ){
|
||||
case CMD_SHM: {
|
||||
Tcl_Obj *pObj;
|
||||
int i, rc;
|
||||
int rc;
|
||||
TestvfsBuffer *pBuffer;
|
||||
char *zName;
|
||||
if( objc!=3 && objc!=4 ){
|
||||
@@ -1160,7 +1160,6 @@ static int testvfs_obj_cmd(
|
||||
};
|
||||
Tcl_Obj **apElem = 0;
|
||||
int nElem = 0;
|
||||
int i;
|
||||
int mask = 0;
|
||||
if( objc!=3 ){
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "LIST");
|
||||
|
||||
+5
-5
@@ -450,12 +450,14 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
|
||||
}
|
||||
abort_parse:
|
||||
assert( nErr==0 );
|
||||
if( zSql[i]==0 && pParse->rc==SQLITE_OK ){
|
||||
if( zSql[i]==0 && pParse->rc==SQLITE_OK && db->mallocFailed==0 ){
|
||||
if( lastTokenParsed!=TK_SEMI ){
|
||||
sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
|
||||
pParse->zTail = &zSql[i];
|
||||
}
|
||||
sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
|
||||
if( pParse->rc==SQLITE_OK && db->mallocFailed==0 ){
|
||||
sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
|
||||
}
|
||||
}
|
||||
#ifdef YYTRACKMAXSTACKDEPTH
|
||||
sqlite3_mutex_enter(sqlite3MallocMutex());
|
||||
@@ -516,8 +518,6 @@ abort_parse:
|
||||
pParse->pZombieTab = p->pNextZombie;
|
||||
sqlite3DeleteTable(db, p);
|
||||
}
|
||||
if( nErr>0 && pParse->rc==SQLITE_OK ){
|
||||
pParse->rc = SQLITE_ERROR;
|
||||
}
|
||||
assert( nErr==0 || pParse->rc!=SQLITE_OK );
|
||||
return nErr;
|
||||
}
|
||||
|
||||
+10
-9
@@ -193,7 +193,6 @@ void sqlite3BeginTrigger(
|
||||
/* Do not create a trigger on a system table */
|
||||
if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){
|
||||
sqlite3ErrorMsg(pParse, "cannot create trigger on system table");
|
||||
pParse->nErr++;
|
||||
goto trigger_cleanup;
|
||||
}
|
||||
|
||||
@@ -373,12 +372,12 @@ static TriggerStep *triggerStepAllocate(
|
||||
){
|
||||
TriggerStep *pTriggerStep;
|
||||
|
||||
pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n);
|
||||
pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1);
|
||||
if( pTriggerStep ){
|
||||
char *z = (char*)&pTriggerStep[1];
|
||||
memcpy(z, pName->z, pName->n);
|
||||
pTriggerStep->target.z = z;
|
||||
pTriggerStep->target.n = pName->n;
|
||||
sqlite3Dequote(z);
|
||||
pTriggerStep->zTarget = z;
|
||||
pTriggerStep->op = op;
|
||||
}
|
||||
return pTriggerStep;
|
||||
@@ -661,7 +660,7 @@ Trigger *sqlite3TriggersExist(
|
||||
}
|
||||
|
||||
/*
|
||||
** Convert the pStep->target token into a SrcList and return a pointer
|
||||
** Convert the pStep->zTarget string into a SrcList and return a pointer
|
||||
** to that SrcList.
|
||||
**
|
||||
** This routine adds a specific database name, if needed, to the target when
|
||||
@@ -674,16 +673,17 @@ static SrcList *targetSrcList(
|
||||
Parse *pParse, /* The parsing context */
|
||||
TriggerStep *pStep /* The trigger containing the target token */
|
||||
){
|
||||
sqlite3 *db = pParse->db;
|
||||
int iDb; /* Index of the database to use */
|
||||
SrcList *pSrc; /* SrcList to be returned */
|
||||
|
||||
pSrc = sqlite3SrcListAppend(pParse->db, 0, &pStep->target, 0);
|
||||
pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
|
||||
if( pSrc ){
|
||||
assert( pSrc->nSrc>0 );
|
||||
iDb = sqlite3SchemaToIndex(pParse->db, pStep->pTrig->pSchema);
|
||||
pSrc->a[pSrc->nSrc-1].zName = sqlite3DbStrDup(db, pStep->zTarget);
|
||||
iDb = sqlite3SchemaToIndex(db, pStep->pTrig->pSchema);
|
||||
if( iDb==0 || iDb>=2 ){
|
||||
sqlite3 *db = pParse->db;
|
||||
assert( iDb<pParse->db->nDb );
|
||||
assert( iDb<db->nDb );
|
||||
pSrc->a[pSrc->nSrc-1].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zName);
|
||||
}
|
||||
}
|
||||
@@ -795,6 +795,7 @@ static void transferParseError(Parse *pTo, Parse *pFrom){
|
||||
if( pTo->nErr==0 ){
|
||||
pTo->zErrMsg = pFrom->zErrMsg;
|
||||
pTo->nErr = pFrom->nErr;
|
||||
pTo->rc = pFrom->rc;
|
||||
}else{
|
||||
sqlite3DbFree(pFrom->db, pFrom->zErrMsg);
|
||||
}
|
||||
|
||||
@@ -655,6 +655,7 @@ int sqlite3GetInt32(const char *zNum, int *pValue){
|
||||
}
|
||||
}
|
||||
#endif
|
||||
while( zNum[0]=='0' ) zNum++;
|
||||
for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){
|
||||
v = v*10 + c;
|
||||
}
|
||||
|
||||
+20
-12
@@ -539,6 +539,9 @@ int sqlite3VdbeExec(
|
||||
){
|
||||
Op *aOp = p->aOp; /* Copy of p->aOp */
|
||||
Op *pOp = aOp; /* Current operation */
|
||||
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
|
||||
Op *pOrigOp; /* Value of pOp at the top of the loop */
|
||||
#endif
|
||||
int rc = SQLITE_OK; /* Value to return */
|
||||
sqlite3 *db = p->db; /* The database */
|
||||
u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */
|
||||
@@ -681,6 +684,9 @@ int sqlite3VdbeExec(
|
||||
memAboutToChange(p, &aMem[pOp->p3]);
|
||||
}
|
||||
#endif
|
||||
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
|
||||
pOrigOp = pOp;
|
||||
#endif
|
||||
|
||||
switch( pOp->opcode ){
|
||||
|
||||
@@ -1199,10 +1205,11 @@ case OP_Move: {
|
||||
memAboutToChange(p, pOut);
|
||||
sqlite3VdbeMemMove(pOut, pIn1);
|
||||
#ifdef SQLITE_DEBUG
|
||||
if( pOut->pScopyFrom>=&aMem[p1] && pOut->pScopyFrom<&aMem[p1+pOp->p3] ){
|
||||
pOut->pScopyFrom += p1 - pOp->p2;
|
||||
if( pOut->pScopyFrom>=&aMem[p1] && pOut->pScopyFrom<pOut ){
|
||||
pOut->pScopyFrom += pOp->p2 - p1;
|
||||
}
|
||||
#endif
|
||||
Deephemeralize(pOut);
|
||||
REGISTER_TRACE(p2++, pOut);
|
||||
pIn1++;
|
||||
pOut++;
|
||||
@@ -2471,7 +2478,7 @@ case OP_Column: {
|
||||
}
|
||||
}
|
||||
|
||||
/* If after trying to extra new entries from the header, nHdrParsed is
|
||||
/* If after trying to extract new entries from the header, nHdrParsed is
|
||||
** still not up to p2, that means that the record has fewer than p2
|
||||
** columns. So the result will be either the default value or a NULL.
|
||||
*/
|
||||
@@ -2919,7 +2926,7 @@ case OP_Savepoint: {
|
||||
db->nDeferredImmCons = pSavepoint->nDeferredImmCons;
|
||||
}
|
||||
|
||||
if( !isTransaction ){
|
||||
if( !isTransaction || p1==SAVEPOINT_ROLLBACK ){
|
||||
rc = sqlite3VtabSavepoint(db, p1, iSavepoint);
|
||||
if( rc!=SQLITE_OK ) goto abort_due_to_error;
|
||||
}
|
||||
@@ -6101,8 +6108,9 @@ case OP_VOpen: {
|
||||
pCur->pVtabCursor = pVtabCursor;
|
||||
pVtab->nRef++;
|
||||
}else{
|
||||
db->mallocFailed = 1;
|
||||
assert( db->mallocFailed );
|
||||
pModule->xClose(pVtabCursor);
|
||||
goto no_mem;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -6489,8 +6497,8 @@ default: { /* This is really OP_Noop and OP_Explain */
|
||||
#ifdef VDBE_PROFILE
|
||||
{
|
||||
u64 endTime = sqlite3Hwtime();
|
||||
if( endTime>start ) pOp->cycles += endTime - start;
|
||||
pOp->cnt++;
|
||||
if( endTime>start ) pOrigOp->cycles += endTime - start;
|
||||
pOrigOp->cnt++;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -6500,16 +6508,16 @@ default: { /* This is really OP_Noop and OP_Explain */
|
||||
** the evaluator loop. So we can leave it out when NDEBUG is defined.
|
||||
*/
|
||||
#ifndef NDEBUG
|
||||
assert( pOp>=&aOp[-1] && pOp<&aOp[p->nOp] );
|
||||
assert( pOp>=&aOp[-1] && pOp<&aOp[p->nOp-1] );
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
if( db->flags & SQLITE_VdbeTrace ){
|
||||
if( rc!=0 ) printf("rc=%d\n",rc);
|
||||
if( pOp->opflags & (OPFLG_OUT2) ){
|
||||
registerTrace(pOp->p2, &aMem[pOp->p2]);
|
||||
if( pOrigOp->opflags & (OPFLG_OUT2) ){
|
||||
registerTrace(pOrigOp->p2, &aMem[pOrigOp->p2]);
|
||||
}
|
||||
if( pOp->opflags & OPFLG_OUT3 ){
|
||||
registerTrace(pOp->p3, &aMem[pOp->p3]);
|
||||
if( pOrigOp->opflags & OPFLG_OUT3 ){
|
||||
registerTrace(pOrigOp->p3, &aMem[pOrigOp->p3]);
|
||||
}
|
||||
}
|
||||
#endif /* SQLITE_DEBUG */
|
||||
|
||||
+18
-11
@@ -1789,6 +1789,22 @@ void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
** Close all cursors in the current frame.
|
||||
*/
|
||||
static void closeCursorsInFrame(Vdbe *p){
|
||||
if( p->apCsr ){
|
||||
int i;
|
||||
for(i=0; i<p->nCursor; i++){
|
||||
VdbeCursor *pC = p->apCsr[i];
|
||||
if( pC ){
|
||||
sqlite3VdbeFreeCursor(p, pC);
|
||||
p->apCsr[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Copy the values stored in the VdbeFrame structure to its Vdbe. This
|
||||
** is used, for example, when a trigger sub-program is halted to restore
|
||||
@@ -1796,6 +1812,7 @@ void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){
|
||||
*/
|
||||
int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){
|
||||
Vdbe *v = pFrame->v;
|
||||
closeCursorsInFrame(v);
|
||||
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
|
||||
v->anExec = pFrame->anExec;
|
||||
#endif
|
||||
@@ -1830,17 +1847,7 @@ static void closeAllCursors(Vdbe *p){
|
||||
p->nFrame = 0;
|
||||
}
|
||||
assert( p->nFrame==0 );
|
||||
|
||||
if( p->apCsr ){
|
||||
int i;
|
||||
for(i=0; i<p->nCursor; i++){
|
||||
VdbeCursor *pC = p->apCsr[i];
|
||||
if( pC ){
|
||||
sqlite3VdbeFreeCursor(p, pC);
|
||||
p->apCsr[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
closeCursorsInFrame(p);
|
||||
if( p->aMem ){
|
||||
releaseMemArray(&p->aMem[1], p->nMem);
|
||||
}
|
||||
|
||||
+5
-4
@@ -200,10 +200,11 @@ int sqlite3VdbeMemMakeWriteable(Mem *pMem){
|
||||
pMem->z[pMem->n] = 0;
|
||||
pMem->z[pMem->n+1] = 0;
|
||||
pMem->flags |= MEM_Term;
|
||||
#ifdef SQLITE_DEBUG
|
||||
pMem->pScopyFrom = 0;
|
||||
#endif
|
||||
}
|
||||
pMem->flags &= ~MEM_Ephem;
|
||||
#ifdef SQLITE_DEBUG
|
||||
pMem->pScopyFrom = 0;
|
||||
#endif
|
||||
|
||||
return SQLITE_OK;
|
||||
}
|
||||
@@ -1647,7 +1648,7 @@ void sqlite3Stat4ProbeFree(UnpackedRecord *pRec){
|
||||
Mem *aMem = pRec->aMem;
|
||||
sqlite3 *db = aMem[0].db;
|
||||
for(i=0; i<nCol; i++){
|
||||
if( aMem[i].szMalloc ) sqlite3DbFree(db, aMem[i].zMalloc);
|
||||
sqlite3VdbeMemRelease(&aMem[i]);
|
||||
}
|
||||
sqlite3KeyInfoUnref(pRec->pKeyInfo);
|
||||
sqlite3DbFree(db, pRec);
|
||||
|
||||
+95
-71
@@ -2063,11 +2063,12 @@ static void vdbeMergeEngineCompare(
|
||||
#define INCRINIT_TASK 1
|
||||
#define INCRINIT_ROOT 2
|
||||
|
||||
/* Forward reference.
|
||||
** The vdbeIncrMergeInit() and vdbePmaReaderIncrMergeInit() routines call each
|
||||
** other (when building a merge tree).
|
||||
/*
|
||||
** Forward reference required as the vdbeIncrMergeInit() and
|
||||
** vdbePmaReaderIncrInit() routines are called mutually recursively when
|
||||
** building a merge tree.
|
||||
*/
|
||||
static int vdbePmaReaderIncrMergeInit(PmaReader *pReadr, int eMode);
|
||||
static int vdbePmaReaderIncrInit(PmaReader *pReadr, int eMode);
|
||||
|
||||
/*
|
||||
** Initialize the MergeEngine object passed as the second argument. Once this
|
||||
@@ -2114,7 +2115,7 @@ static int vdbeMergeEngineInit(
|
||||
** better advantage of multi-processor hardware. */
|
||||
rc = vdbePmaReaderNext(&pMerger->aReadr[nTree-i-1]);
|
||||
}else{
|
||||
rc = vdbePmaReaderIncrMergeInit(&pMerger->aReadr[i], INCRINIT_NORMAL);
|
||||
rc = vdbePmaReaderIncrInit(&pMerger->aReadr[i], INCRINIT_NORMAL);
|
||||
}
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
}
|
||||
@@ -2126,17 +2127,15 @@ static int vdbeMergeEngineInit(
|
||||
}
|
||||
|
||||
/*
|
||||
** Initialize the IncrMerge field of a PmaReader.
|
||||
**
|
||||
** If the PmaReader passed as the first argument is not an incremental-reader
|
||||
** (if pReadr->pIncr==0), then this function is a no-op. Otherwise, it serves
|
||||
** to open and/or initialize the temp file related fields of the IncrMerge
|
||||
** The PmaReader passed as the first argument is guaranteed to be an
|
||||
** incremental-reader (pReadr->pIncr!=0). This function serves to open
|
||||
** and/or initialize the temp file related fields of the IncrMerge
|
||||
** object at (pReadr->pIncr).
|
||||
**
|
||||
** If argument eMode is set to INCRINIT_NORMAL, then all PmaReaders
|
||||
** in the sub-tree headed by pReadr are also initialized. Data is then loaded
|
||||
** into the buffers belonging to pReadr and it is set to
|
||||
** point to the first key in its range.
|
||||
** in the sub-tree headed by pReadr are also initialized. Data is then
|
||||
** loaded into the buffers belonging to pReadr and it is set to point to
|
||||
** the first key in its range.
|
||||
**
|
||||
** If argument eMode is set to INCRINIT_TASK, then pReadr is guaranteed
|
||||
** to be a multi-threaded PmaReader and this function is being called in a
|
||||
@@ -2163,59 +2162,62 @@ static int vdbeMergeEngineInit(
|
||||
static int vdbePmaReaderIncrMergeInit(PmaReader *pReadr, int eMode){
|
||||
int rc = SQLITE_OK;
|
||||
IncrMerger *pIncr = pReadr->pIncr;
|
||||
SortSubtask *pTask = pIncr->pTask;
|
||||
sqlite3 *db = pTask->pSorter->db;
|
||||
|
||||
/* eMode is always INCRINIT_NORMAL in single-threaded mode */
|
||||
assert( SQLITE_MAX_WORKER_THREADS>0 || eMode==INCRINIT_NORMAL );
|
||||
|
||||
if( pIncr ){
|
||||
SortSubtask *pTask = pIncr->pTask;
|
||||
sqlite3 *db = pTask->pSorter->db;
|
||||
rc = vdbeMergeEngineInit(pTask, pIncr->pMerger, eMode);
|
||||
|
||||
rc = vdbeMergeEngineInit(pTask, pIncr->pMerger, eMode);
|
||||
|
||||
/* Set up the required files for pIncr. A multi-theaded IncrMerge object
|
||||
** requires two temp files to itself, whereas a single-threaded object
|
||||
** only requires a region of pTask->file2. */
|
||||
if( rc==SQLITE_OK ){
|
||||
int mxSz = pIncr->mxSz;
|
||||
/* Set up the required files for pIncr. A multi-theaded IncrMerge object
|
||||
** requires two temp files to itself, whereas a single-threaded object
|
||||
** only requires a region of pTask->file2. */
|
||||
if( rc==SQLITE_OK ){
|
||||
int mxSz = pIncr->mxSz;
|
||||
#if SQLITE_MAX_WORKER_THREADS>0
|
||||
if( pIncr->bUseThread ){
|
||||
rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[0].pFd);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[1].pFd);
|
||||
}
|
||||
}else
|
||||
if( pIncr->bUseThread ){
|
||||
rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[0].pFd);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[1].pFd);
|
||||
}
|
||||
}else
|
||||
#endif
|
||||
/*if( !pIncr->bUseThread )*/{
|
||||
if( pTask->file2.pFd==0 ){
|
||||
assert( pTask->file2.iEof>0 );
|
||||
rc = vdbeSorterOpenTempFile(db, pTask->file2.iEof, &pTask->file2.pFd);
|
||||
pTask->file2.iEof = 0;
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
pIncr->aFile[1].pFd = pTask->file2.pFd;
|
||||
pIncr->iStartOff = pTask->file2.iEof;
|
||||
pTask->file2.iEof += mxSz;
|
||||
}
|
||||
/*if( !pIncr->bUseThread )*/{
|
||||
if( pTask->file2.pFd==0 ){
|
||||
assert( pTask->file2.iEof>0 );
|
||||
rc = vdbeSorterOpenTempFile(db, pTask->file2.iEof, &pTask->file2.pFd);
|
||||
pTask->file2.iEof = 0;
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
pIncr->aFile[1].pFd = pTask->file2.pFd;
|
||||
pIncr->iStartOff = pTask->file2.iEof;
|
||||
pTask->file2.iEof += mxSz;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if SQLITE_MAX_WORKER_THREADS>0
|
||||
if( rc==SQLITE_OK && pIncr->bUseThread ){
|
||||
/* Use the current thread to populate aFile[1], even though this
|
||||
** PmaReader is multi-threaded. The reason being that this function
|
||||
** is already running in background thread pIncr->pTask->thread. */
|
||||
assert( eMode==INCRINIT_ROOT || eMode==INCRINIT_TASK );
|
||||
rc = vdbeIncrPopulate(pIncr);
|
||||
}
|
||||
if( rc==SQLITE_OK && pIncr->bUseThread ){
|
||||
/* Use the current thread to populate aFile[1], even though this
|
||||
** PmaReader is multi-threaded. If this is an INCRINIT_TASK object,
|
||||
** then this function is already running in background thread
|
||||
** pIncr->pTask->thread.
|
||||
**
|
||||
** If this is the INCRINIT_ROOT object, then it is running in the
|
||||
** main VDBE thread. But that is Ok, as that thread cannot return
|
||||
** control to the VDBE or proceed with anything useful until the
|
||||
** first results are ready from this merger object anyway.
|
||||
*/
|
||||
assert( eMode==INCRINIT_ROOT || eMode==INCRINIT_TASK );
|
||||
rc = vdbeIncrPopulate(pIncr);
|
||||
}
|
||||
#endif
|
||||
|
||||
if( rc==SQLITE_OK
|
||||
&& (SQLITE_MAX_WORKER_THREADS==0 || eMode!=INCRINIT_TASK)
|
||||
){
|
||||
rc = vdbePmaReaderNext(pReadr);
|
||||
}
|
||||
if( rc==SQLITE_OK && (SQLITE_MAX_WORKER_THREADS==0 || eMode!=INCRINIT_TASK) ){
|
||||
rc = vdbePmaReaderNext(pReadr);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -2224,7 +2226,7 @@ static int vdbePmaReaderIncrMergeInit(PmaReader *pReadr, int eMode){
|
||||
** The main routine for vdbePmaReaderIncrMergeInit() operations run in
|
||||
** background threads.
|
||||
*/
|
||||
static void *vdbePmaReaderBgInit(void *pCtx){
|
||||
static void *vdbePmaReaderBgIncrInit(void *pCtx){
|
||||
PmaReader *pReader = (PmaReader*)pCtx;
|
||||
void *pRet = SQLITE_INT_TO_PTR(
|
||||
vdbePmaReaderIncrMergeInit(pReader,INCRINIT_TASK)
|
||||
@@ -2232,20 +2234,36 @@ static void *vdbePmaReaderBgInit(void *pCtx){
|
||||
pReader->pIncr->pTask->bDone = 1;
|
||||
return pRet;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Use a background thread to invoke vdbePmaReaderIncrMergeInit(INCRINIT_TASK)
|
||||
** on the PmaReader object passed as the first argument.
|
||||
**
|
||||
** This call will initialize the various fields of the pReadr->pIncr
|
||||
** structure and, if it is a multi-threaded IncrMerger, launch a
|
||||
** background thread to populate aFile[1].
|
||||
** If the PmaReader passed as the first argument is not an incremental-reader
|
||||
** (if pReadr->pIncr==0), then this function is a no-op. Otherwise, it invokes
|
||||
** the vdbePmaReaderIncrMergeInit() function with the parameters passed to
|
||||
** this routine to initialize the incremental merge.
|
||||
**
|
||||
** If the IncrMerger object is multi-threaded (IncrMerger.bUseThread==1),
|
||||
** then a background thread is launched to call vdbePmaReaderIncrMergeInit().
|
||||
** Or, if the IncrMerger is single threaded, the same function is called
|
||||
** using the current thread.
|
||||
*/
|
||||
static int vdbePmaReaderBgIncrInit(PmaReader *pReadr){
|
||||
void *pCtx = (void*)pReadr;
|
||||
return vdbeSorterCreateThread(pReadr->pIncr->pTask, vdbePmaReaderBgInit, pCtx);
|
||||
}
|
||||
static int vdbePmaReaderIncrInit(PmaReader *pReadr, int eMode){
|
||||
IncrMerger *pIncr = pReadr->pIncr; /* Incremental merger */
|
||||
int rc = SQLITE_OK; /* Return code */
|
||||
if( pIncr ){
|
||||
#if SQLITE_MAX_WORKER_THREADS>0
|
||||
assert( pIncr->bUseThread==0 || eMode==INCRINIT_TASK );
|
||||
if( pIncr->bUseThread ){
|
||||
void *pCtx = (void*)pReadr;
|
||||
rc = vdbeSorterCreateThread(pIncr->pTask, vdbePmaReaderBgIncrInit, pCtx);
|
||||
}else
|
||||
#endif
|
||||
{
|
||||
rc = vdbePmaReaderIncrMergeInit(pReadr, eMode);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Allocate a new MergeEngine object to merge the contents of nPMA level-0
|
||||
@@ -2490,15 +2508,21 @@ static int vdbeSorterSetupMerge(VdbeSorter *pSorter){
|
||||
}
|
||||
}
|
||||
for(iTask=0; rc==SQLITE_OK && iTask<pSorter->nTask; iTask++){
|
||||
/* Check that:
|
||||
**
|
||||
** a) The incremental merge object is configured to use the
|
||||
** right task, and
|
||||
** b) If it is using task (nTask-1), it is configured to run
|
||||
** in single-threaded mode. This is important, as the
|
||||
** root merge (INCRINIT_ROOT) will be using the same task
|
||||
** object.
|
||||
*/
|
||||
PmaReader *p = &pMain->aReadr[iTask];
|
||||
assert( p->pIncr==0 || p->pIncr->pTask==&pSorter->aTask[iTask] );
|
||||
if( p->pIncr ){
|
||||
if( iTask==pSorter->nTask-1 ){
|
||||
rc = vdbePmaReaderIncrMergeInit(p, INCRINIT_TASK);
|
||||
}else{
|
||||
rc = vdbePmaReaderBgIncrInit(p);
|
||||
}
|
||||
}
|
||||
assert( p->pIncr==0 || (
|
||||
(p->pIncr->pTask==&pSorter->aTask[iTask]) /* a */
|
||||
&& (iTask!=pSorter->nTask-1 || p->pIncr->bUseThread==0) /* b */
|
||||
));
|
||||
rc = vdbePmaReaderIncrInit(p, INCRINIT_TASK);
|
||||
}
|
||||
}
|
||||
pMain = 0;
|
||||
|
||||
+6
-3
@@ -84,9 +84,8 @@ char *sqlite3VdbeExpandSql(
|
||||
char zBase[100]; /* Initial working space */
|
||||
|
||||
db = p->db;
|
||||
sqlite3StrAccumInit(&out, zBase, sizeof(zBase),
|
||||
sqlite3StrAccumInit(&out, db, zBase, sizeof(zBase),
|
||||
db->aLimit[SQLITE_LIMIT_LENGTH]);
|
||||
out.db = db;
|
||||
if( db->nVdbeExec>1 ){
|
||||
while( *zRawSql ){
|
||||
const char *zStart = zRawSql;
|
||||
@@ -95,6 +94,8 @@ char *sqlite3VdbeExpandSql(
|
||||
assert( (zRawSql - zStart) > 0 );
|
||||
sqlite3StrAccumAppend(&out, zStart, (int)(zRawSql-zStart));
|
||||
}
|
||||
}else if( p->nVar==0 ){
|
||||
sqlite3StrAccumAppend(&out, zRawSql, sqlite3Strlen30(zRawSql));
|
||||
}else{
|
||||
while( zRawSql[0] ){
|
||||
n = findNextHostParameter(zRawSql, &nToken);
|
||||
@@ -111,10 +112,12 @@ char *sqlite3VdbeExpandSql(
|
||||
idx = nextIndex;
|
||||
}
|
||||
}else{
|
||||
assert( zRawSql[0]==':' || zRawSql[0]=='$' || zRawSql[0]=='@' );
|
||||
assert( zRawSql[0]==':' || zRawSql[0]=='$' ||
|
||||
zRawSql[0]=='@' || zRawSql[0]=='#' );
|
||||
testcase( zRawSql[0]==':' );
|
||||
testcase( zRawSql[0]=='$' );
|
||||
testcase( zRawSql[0]=='@' );
|
||||
testcase( zRawSql[0]=='#' );
|
||||
idx = sqlite3VdbeParameterIndex(p, zRawSql, nToken);
|
||||
assert( idx>0 );
|
||||
}
|
||||
|
||||
+11
-4
@@ -472,7 +472,7 @@ void sqlite3VtabArgExtend(Parse *pParse, Token *p){
|
||||
pArg->z = p->z;
|
||||
pArg->n = p->n;
|
||||
}else{
|
||||
assert(pArg->z < p->z);
|
||||
assert(pArg->z <= p->z);
|
||||
pArg->n = (int)(&p->z[p->n] - pArg->z);
|
||||
}
|
||||
}
|
||||
@@ -559,6 +559,7 @@ static int vtabCallConstructor(
|
||||
rc = SQLITE_ERROR;
|
||||
}else{
|
||||
int iCol;
|
||||
u8 oooHidden = 0;
|
||||
/* 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".
|
||||
@@ -571,7 +572,10 @@ static int vtabCallConstructor(
|
||||
char *zType = pTab->aCol[iCol].zType;
|
||||
int nType;
|
||||
int i = 0;
|
||||
if( !zType ) continue;
|
||||
if( !zType ){
|
||||
pTab->tabFlags |= oooHidden;
|
||||
continue;
|
||||
}
|
||||
nType = sqlite3Strlen30(zType);
|
||||
if( sqlite3StrNICmp("hidden", zType, 6)||(zType[6] && zType[6]!=' ') ){
|
||||
for(i=0; i<nType; i++){
|
||||
@@ -594,6 +598,9 @@ static int vtabCallConstructor(
|
||||
zType[i-1] = '\0';
|
||||
}
|
||||
pTab->aCol[iCol].colFlags |= COLFLAG_HIDDEN;
|
||||
oooHidden = TF_OOOHidden;
|
||||
}else{
|
||||
pTab->tabFlags |= oooHidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -957,7 +964,7 @@ int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
assert( op==SAVEPOINT_RELEASE||op==SAVEPOINT_ROLLBACK||op==SAVEPOINT_BEGIN );
|
||||
assert( iSavepoint>=0 );
|
||||
assert( iSavepoint>=-1 );
|
||||
if( db->aVTrans ){
|
||||
int i;
|
||||
for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){
|
||||
@@ -1075,7 +1082,7 @@ void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){
|
||||
if( pTab==pToplevel->apVtabLock[i] ) return;
|
||||
}
|
||||
n = (pToplevel->nVtabLock+1)*sizeof(pToplevel->apVtabLock[0]);
|
||||
apVtabLock = sqlite3_realloc(pToplevel->apVtabLock, n);
|
||||
apVtabLock = sqlite3_realloc64(pToplevel->apVtabLock, n);
|
||||
if( apVtabLock ){
|
||||
pToplevel->apVtabLock = apVtabLock;
|
||||
pToplevel->apVtabLock[pToplevel->nVtabLock++] = pTab;
|
||||
|
||||
@@ -522,7 +522,7 @@ static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
|
||||
if( pWal->nWiData<=iPage ){
|
||||
int nByte = sizeof(u32*)*(iPage+1);
|
||||
volatile u32 **apNew;
|
||||
apNew = (volatile u32 **)sqlite3_realloc((void *)pWal->apWiData, nByte);
|
||||
apNew = (volatile u32 **)sqlite3_realloc64((void *)pWal->apWiData, nByte);
|
||||
if( !apNew ){
|
||||
*ppPage = 0;
|
||||
return SQLITE_NOMEM;
|
||||
@@ -1147,7 +1147,7 @@ static int walIndexRecover(Wal *pWal){
|
||||
|
||||
/* Malloc a buffer to read frames into. */
|
||||
szFrame = szPage + WAL_FRAME_HDRSIZE;
|
||||
aFrame = (u8 *)sqlite3_malloc(szFrame);
|
||||
aFrame = (u8 *)sqlite3_malloc64(szFrame);
|
||||
if( !aFrame ){
|
||||
rc = SQLITE_NOMEM;
|
||||
goto recovery_error;
|
||||
@@ -1540,7 +1540,7 @@ static int walIteratorInit(Wal *pWal, WalIterator **pp){
|
||||
nByte = sizeof(WalIterator)
|
||||
+ (nSegment-1)*sizeof(struct WalSegment)
|
||||
+ iLast*sizeof(ht_slot);
|
||||
p = (WalIterator *)sqlite3_malloc(nByte);
|
||||
p = (WalIterator *)sqlite3_malloc64(nByte);
|
||||
if( !p ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
@@ -1550,7 +1550,7 @@ static int walIteratorInit(Wal *pWal, WalIterator **pp){
|
||||
/* Allocate temporary space used by the merge-sort routine. This block
|
||||
** of memory will be freed before this function returns.
|
||||
*/
|
||||
aTmp = (ht_slot *)sqlite3_malloc(
|
||||
aTmp = (ht_slot *)sqlite3_malloc64(
|
||||
sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast)
|
||||
);
|
||||
if( !aTmp ){
|
||||
|
||||
+13
-8
@@ -255,13 +255,14 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){
|
||||
** all terms of the WHERE clause.
|
||||
*/
|
||||
static void whereSplit(WhereClause *pWC, Expr *pExpr, u8 op){
|
||||
Expr *pE2 = sqlite3ExprSkipCollate(pExpr);
|
||||
pWC->op = op;
|
||||
if( pExpr==0 ) return;
|
||||
if( pExpr->op!=op ){
|
||||
if( pE2==0 ) return;
|
||||
if( pE2->op!=op ){
|
||||
whereClauseInsert(pWC, pExpr, 0);
|
||||
}else{
|
||||
whereSplit(pWC, pExpr->pLeft, op);
|
||||
whereSplit(pWC, pExpr->pRight, op);
|
||||
whereSplit(pWC, pE2->pLeft, op);
|
||||
whereSplit(pWC, pE2->pRight, op);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3102,8 +3103,7 @@ static int explainOneScan(
|
||||
|| ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0))
|
||||
|| (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));
|
||||
|
||||
sqlite3StrAccumInit(&str, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
|
||||
str.db = db;
|
||||
sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
|
||||
sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN");
|
||||
if( pItem->pSelect ){
|
||||
sqlite3XPrintf(&str, 0, " SUBQUERY %d", pItem->iSelectId);
|
||||
@@ -4302,6 +4302,13 @@ static void whereLoopDelete(sqlite3 *db, WhereLoop *p){
|
||||
*/
|
||||
static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
|
||||
if( ALWAYS(pWInfo) ){
|
||||
int i;
|
||||
for(i=0; i<pWInfo->nLevel; i++){
|
||||
WhereLevel *pLevel = &pWInfo->a[i];
|
||||
if( pLevel->pWLoop && (pLevel->pWLoop->wsFlags & WHERE_IN_ABLE) ){
|
||||
sqlite3DbFree(db, pLevel->u.in.aInLoop);
|
||||
}
|
||||
}
|
||||
whereClauseClear(&pWInfo->sWC);
|
||||
while( pWInfo->pLoops ){
|
||||
WhereLoop *p = pWInfo->pLoops;
|
||||
@@ -6646,7 +6653,6 @@ WhereInfo *sqlite3WhereBegin(
|
||||
}
|
||||
#ifdef WHERETRACE_ENABLED /* !=0 */
|
||||
if( sqlite3WhereTrace ){
|
||||
int ii;
|
||||
sqlite3DebugPrintf("---- Solution nRow=%d", pWInfo->nRowOut);
|
||||
if( pWInfo->nOBSat>0 ){
|
||||
sqlite3DebugPrintf(" ORDERBY=%d,0x%llx", pWInfo->nOBSat, pWInfo->revMask);
|
||||
@@ -6899,7 +6905,6 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
|
||||
VdbeCoverageIf(v, pIn->eEndLoopOp==OP_NextIfOpen);
|
||||
sqlite3VdbeJumpHere(v, pIn->addrInTop-1);
|
||||
}
|
||||
sqlite3DbFree(db, pLevel->u.in.aInLoop);
|
||||
}
|
||||
sqlite3VdbeResolveLabel(v, pLevel->addrBrk);
|
||||
if( pLevel->addrSkip ){
|
||||
|
||||
@@ -912,5 +912,14 @@ do_execsql_test alter-17.9 {
|
||||
do_execsql_test alter-17.10 {
|
||||
SELECT sqlite_rename_parent(NULL,'abc','xyz');
|
||||
} {{}}
|
||||
do_execsql_test alter-17.11 {
|
||||
SELECT sqlite_rename_parent('create references ''','abc','xyz');
|
||||
} {{create references '}}
|
||||
do_execsql_test alter-17.12 {
|
||||
SELECT sqlite_rename_parent('create references "abc"123" ','abc','xyz');
|
||||
} {{create references "xyz"123" }}
|
||||
do_execsql_test alter-17.13 {
|
||||
SELECT sqlite_rename_parent("references '''",'abc','xyz');
|
||||
} {{references '''}}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix analyze3
|
||||
|
||||
ifcapable !stat4&&!stat3 {
|
||||
finish_test
|
||||
@@ -46,6 +47,9 @@ ifcapable !stat4&&!stat3 {
|
||||
#
|
||||
# analyze3-6.*: Test that the problem fixed by commit [127a5b776d] is fixed.
|
||||
#
|
||||
# analyze3-7.*: Test that some memory leaks discovered by fuzz testing
|
||||
# have been fixed.
|
||||
#
|
||||
|
||||
proc getvar {varname} { uplevel #0 set $varname }
|
||||
db function var getvar
|
||||
@@ -662,4 +666,30 @@ do_eqp_test analyze3-6-2 {
|
||||
SELECT * FROM t1 WHERE a = 5 AND b > 'w' AND c = 13;
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX i2 (c=?)}}
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# 2015-04-20.
|
||||
# Memory leak in sqlite3Stat4ProbeFree(). (Discovered while fuzzing.)
|
||||
#
|
||||
do_execsql_test analyze-7.1 {
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
|
||||
INSERT INTO t1 VALUES(1,1,'0000');
|
||||
CREATE INDEX t0b ON t1(b);
|
||||
ANALYZE;
|
||||
SELECT c FROM t1 WHERE b=3 AND a BETWEEN 30 AND hex(1);
|
||||
} {}
|
||||
|
||||
# At one point duplicate stat1 entries were causing a memory leak.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 7.2 {
|
||||
CREATE TABLE t1(a,b,c);
|
||||
CREATE INDEX t1a ON t1(a);
|
||||
ANALYZE;
|
||||
SELECT * FROM sqlite_stat1;
|
||||
INSERT INTO sqlite_stat1(tbl,idx,stat) VALUES('t1','t1a','12000');
|
||||
INSERT INTO sqlite_stat1(tbl,idx,stat) VALUES('t1','t1a','12000');
|
||||
ANALYZE sqlite_master;
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
+1
-1
@@ -292,7 +292,7 @@ do_test corruptC-2.15 {
|
||||
hexio_write test.db 986 b9
|
||||
sqlite3 db test.db
|
||||
catchsql {SELECT count(*) FROM sqlite_master;}
|
||||
} {1 {malformed database schema (t1i1) - no such table: main.t1}}
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
#
|
||||
# Now test for a series of quasi-random seeds.
|
||||
|
||||
@@ -191,4 +191,9 @@ do_execsql_test count-5.1 {
|
||||
SELECT count(*) FROM t5;
|
||||
} {1}
|
||||
|
||||
do_catchsql_test count-6.1 {
|
||||
CREATE TABLE t6(x);
|
||||
SELECT count(DISTINCT) FROM t6 GROUP BY x;
|
||||
} {1 {DISTINCT aggregates must have exactly one argument}}
|
||||
|
||||
finish_test
|
||||
|
||||
+6
-2
@@ -48,8 +48,11 @@ do_execsql_test e_reindex-1.1 {
|
||||
INSERT INTO t1 VALUES(1, 2);
|
||||
INSERT INTO t1 VALUES(3, 4);
|
||||
INSERT INTO t1 VALUES(5, 6);
|
||||
|
||||
CREATE TABLE saved(a,b,c,d,e);
|
||||
INSERT INTO saved SELECT * FROM sqlite_master WHERE type = 'index';
|
||||
PRAGMA writable_schema = 1;
|
||||
UPDATE sqlite_master SET sql = '-- ' || sql WHERE type = 'index';
|
||||
DELETE FROM sqlite_master WHERE type = 'index';
|
||||
} {}
|
||||
|
||||
db close
|
||||
@@ -59,7 +62,8 @@ do_execsql_test e_reindex-1.2 {
|
||||
INSERT INTO t1 VALUES(7, 8);
|
||||
INSERT INTO t1 VALUES(9, 10);
|
||||
PRAGMA writable_schema = 1;
|
||||
UPDATE sqlite_master SET sql = substr(sql, 4) WHERE type = 'index';
|
||||
INSERT INTO sqlite_master SELECT * FROM saved;
|
||||
DROP TABLE saved;
|
||||
} {}
|
||||
|
||||
db close
|
||||
|
||||
@@ -943,5 +943,13 @@ do_realnum_test expr-13.7 {
|
||||
}
|
||||
} {9.22337203685478e+18}
|
||||
|
||||
do_execsql_test expr-13.8 {
|
||||
SELECT "" <= '';
|
||||
} {1}
|
||||
do_execsql_test expr-13.9 {
|
||||
SELECT '' <= "";
|
||||
} {1}
|
||||
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -121,4 +121,34 @@ do_test fkey1-3.5 {
|
||||
sqlite3_db_status db DBSTATUS_DEFERRED_FKS 0
|
||||
} {0 0 0}
|
||||
|
||||
# Stress the dequoting logic. The first test is not so bad.
|
||||
do_execsql_test fkey1-4.0 {
|
||||
PRAGMA foreign_keys=ON;
|
||||
CREATE TABLE "xx1"("xx2" TEXT PRIMARY KEY, "xx3" TEXT);
|
||||
INSERT INTO "xx1"("xx2","xx3") VALUES('abc','def');
|
||||
CREATE TABLE "xx4"("xx5" TEXT REFERENCES "xx1" ON DELETE CASCADE);
|
||||
INSERT INTO "xx4"("xx5") VALUES('abc');
|
||||
INSERT INTO "xx1"("xx2","xx3") VALUES('uvw','xyz');
|
||||
SELECT 1, "xx5" FROM "xx4";
|
||||
DELETE FROM "xx1";
|
||||
SELECT 2, "xx5" FROM "xx4";
|
||||
} {1 abc}
|
||||
|
||||
# This case is identical to the previous except the "xx" in each name
|
||||
# is changed to a single escaped double-quote character.
|
||||
do_execsql_test fkey1-4.1 {
|
||||
PRAGMA foreign_keys=ON;
|
||||
CREATE TABLE """1"("""2" TEXT PRIMARY KEY, """3" TEXT);
|
||||
INSERT INTO """1"("""2","""3") VALUES('abc','def');
|
||||
CREATE TABLE """4"("""5" TEXT REFERENCES """1" ON DELETE CASCADE);
|
||||
INSERT INTO """4"("""5") VALUES('abc');
|
||||
INSERT INTO """1"("""2","""3") VALUES('uvw','xyz');
|
||||
SELECT 1, """5" FROM """4";
|
||||
DELETE FROM """1";
|
||||
SELECT 2, """5" FROM """4";
|
||||
} {1 abc}
|
||||
do_execsql_test fkey1-4.2 {
|
||||
PRAGMA table_info="""1";
|
||||
} {0 {"2} TEXT 0 {} 1 1 {"3} TEXT 0 {} 0}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -676,6 +676,11 @@ do_test fkey2-9.2.3 {
|
||||
SELECT * FROM cc;
|
||||
}
|
||||
} {{} A {} {} B {} 3 A 2 3 B 2}
|
||||
do_execsql_test fkey2-9.3.0 {
|
||||
CREATE TABLE t3(x PRIMARY KEY REFERENCES t3 ON DELETE SET NULL);
|
||||
INSERT INTO t3(x) VALUES(12345);
|
||||
DROP TABLE t3;
|
||||
} {}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# The following tests, fkey2-10.*, test "foreign key mismatch" and
|
||||
@@ -2014,4 +2019,18 @@ do_test fkey2-ce7c13.1.6 {
|
||||
}
|
||||
} {1 {FOREIGN KEY constraint failed}}
|
||||
|
||||
# 2015-04-16: Foreign key errors propagate back up to the parser.
|
||||
#
|
||||
do_test fkey2-20150416-100 {
|
||||
db close
|
||||
sqlite3 db :memory:
|
||||
catchsql {
|
||||
PRAGMA foreign_keys=1;
|
||||
CREATE TABLE t1(x PRIMARY KEY);
|
||||
CREATE TABLE t(y REFERENCES t0(x)ON DELETE SET DEFAULT);
|
||||
CREATE TABLE t0(y REFERENCES t1 ON DELETE SET NULL);
|
||||
REPLACE INTO t1 SELECT(0);CREATE TABLE t2(x);CREATE TABLE t3;
|
||||
}
|
||||
} {1 {foreign key mismatch - "t" referencing "t0"}}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix fts3aa
|
||||
|
||||
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
|
||||
ifcapable !fts3 {
|
||||
@@ -221,5 +222,26 @@ do_catchsql_test fts3aa-7.5 {
|
||||
CREATE VIRTUAL TABLE t4 USING fts4(tokenize=simple, tokenize=simple);
|
||||
} {1 {unrecognized parameter: tokenize=simple}}
|
||||
|
||||
do_execsql_test 8.0 {
|
||||
CREATE VIRTUAL TABLE t0 USING fts4(order=desc);
|
||||
BEGIN;
|
||||
INSERT INTO t0(rowid, content) VALUES(1, 'abc');
|
||||
UPDATE t0 SET docid=5 WHERE docid=1;
|
||||
INSERT INTO t0(rowid, content) VALUES(6, 'abc');
|
||||
}
|
||||
do_execsql_test 8.1 {
|
||||
SELECT docid FROM t0 WHERE t0 MATCH 'abc';
|
||||
} {6 5}
|
||||
do_execsql_test 8.2 {
|
||||
SELECT docid FROM t0 WHERE t0 MATCH '"abc abc"';
|
||||
} {}
|
||||
do_execsql_test 8.3 { COMMIT }
|
||||
do_execsql_test 8.4 {
|
||||
SELECT docid FROM t0 WHERE t0 MATCH 'abc';
|
||||
} {6 5}
|
||||
do_execsql_test 8.5 {
|
||||
SELECT docid FROM t0 WHERE t0 MATCH '"abc abc"';
|
||||
} {}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
# 2006 September 9
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#*************************************************************************
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this script is testing the FTS3 module.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix fts3expr5
|
||||
|
||||
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
|
||||
ifcapable !fts3 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Various forms of empty phrase expressions.
|
||||
#
|
||||
do_execsql_test 1.0 {
|
||||
CREATE VIRTUAL TABLE t0 USING fts3(x);
|
||||
SELECT rowid FROM t0 WHERE x MATCH '';
|
||||
} {}
|
||||
do_execsql_test 1.1 {
|
||||
SELECT rowid FROM t0 WHERE x MATCH '""';
|
||||
} {}
|
||||
do_execsql_test 1.2 {
|
||||
SELECT rowid FROM t0 WHERE x MATCH '"" ""';
|
||||
} {}
|
||||
do_execsql_test 1.3 {
|
||||
SELECT rowid FROM t0 WHERE x MATCH '"" OR ""';
|
||||
} {}
|
||||
do_execsql_test 1.4 {
|
||||
SELECT rowid FROM t0 WHERE x MATCH '"" NOT ""';
|
||||
} {}
|
||||
do_execsql_test 1.5 {
|
||||
SELECT rowid FROM t0 WHERE x MATCH '""""';
|
||||
} {}
|
||||
|
||||
finish_test
|
||||
@@ -179,5 +179,35 @@ do_test 4.2 {
|
||||
} {1 {database disk image is malformed}}
|
||||
reset_db
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Test case 5.*
|
||||
#
|
||||
# Test that the integrity-check works if there is uncommitted data.
|
||||
#
|
||||
do_execsql_test 5.0 {
|
||||
BEGIN;
|
||||
CREATE VIRTUAL TABLE t5 USING fts4(a, prefix="1,2,3");
|
||||
INSERT INTO t5 VALUES('And down by Kosiosko, where the reed-banks sweep');
|
||||
INSERT INTO t5 VALUES('and sway, and the rolling plains are wide, the');
|
||||
INSERT INTO t5 VALUES('man from snowy river is a household name today,');
|
||||
INSERT INTO t5 VALUES('and the stockmen tell the story of his ride');
|
||||
}
|
||||
|
||||
do_execsql_test 5.1 {
|
||||
INSERT INTO t5(t5) VALUES('integrity-check');
|
||||
} {}
|
||||
|
||||
do_catchsql_test 5.2 {
|
||||
INSERT INTO t5_content VALUES(5, 'his hardy mountain pony');
|
||||
INSERT INTO t5(t5) VALUES('integrity-check');
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
do_execsql_test 5.3 ROLLBACK
|
||||
|
||||
do_execsql_test 5.4 {
|
||||
CREATE VIRTUAL TABLE t5 USING fts4(a, prefix="1,2,3");
|
||||
INSERT INTO t5(t5) VALUES('integrity-check');
|
||||
} {}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -311,5 +311,9 @@ do_eqp_test index7-6.4 {
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t4 USING INDEX i4 (c=?)}
|
||||
}
|
||||
do_catchsql_test index7-6.5 {
|
||||
CREATE INDEX t5a ON t5(a) WHERE a=#1;
|
||||
} {1 {near "#1": syntax error}}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix insert2
|
||||
|
||||
# Create some tables with data that we can select against
|
||||
#
|
||||
@@ -275,4 +276,23 @@ ifcapable subquery {
|
||||
} {1 2 1 3 1 4}
|
||||
}
|
||||
|
||||
do_execsql_test 6.0 {
|
||||
CREATE TABLE t5(a, b, c DEFAULT 'c', d);
|
||||
}
|
||||
do_execsql_test 6.1 {
|
||||
INSERT INTO t5(a) SELECT 456 UNION ALL SELECT 123 ORDER BY 1;
|
||||
SELECT * FROM t5 ORDER BY rowid;
|
||||
} {123 {} c {} 456 {} c {}}
|
||||
|
||||
ifcapable fts3 {
|
||||
do_execsql_test 6.2 {
|
||||
CREATE VIRTUAL TABLE t0 USING fts4(a);
|
||||
}
|
||||
do_execsql_test 6.3 {
|
||||
INSERT INTO t0 SELECT 0 UNION SELECT 0 AS 'x' ORDER BY x;
|
||||
SELECT * FROM t0;
|
||||
} {0}
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -560,5 +560,10 @@ do_test insert4-8.25 {
|
||||
}
|
||||
} {1 3}
|
||||
|
||||
do_catchsql_test insert4-9.1 {
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1(x);
|
||||
INSERT INTO t1(x) VALUES(5 COLLATE xyzzy) UNION SELECT 0;
|
||||
} {1 {no such collation sequence: xyzzy}}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -555,4 +555,19 @@ do_execsql_test jrnlmode-8.28 { PRAGMA journal_mode=DELETE } {delete}
|
||||
do_execsql_test jrnlmode-8.29 { COMMIT } {}
|
||||
do_execsql_test jrnlmode-8.30 { PRAGMA journal_mode=DELETE } {delete}
|
||||
|
||||
# Assertion fault on 2015-05-01
|
||||
do_test jrnlmode-9.1 {
|
||||
forcedelete test2.db
|
||||
sqlite3 db2 test2.db
|
||||
breakpoint
|
||||
db2 eval {CREATE TEMP TABLE t(l); PRAGMA journal_mode=off;}
|
||||
db2 close
|
||||
} {}
|
||||
do_execsql_test jrnlmode-9.2 {
|
||||
PRAGMA locking_mode = exclusive;
|
||||
CREATE TABLE tx(a);
|
||||
PRAGMA journal_mode = off;
|
||||
} {exclusive off}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -923,6 +923,27 @@ do_faultsim_test 41.2 -faults oom* -body {
|
||||
faultsim_integrity_check
|
||||
}
|
||||
|
||||
reset_db
|
||||
do_execsql_test 42.0 {
|
||||
CREATE TABLE t1(x INTEGER PRIMARY KEY, y, z);
|
||||
CREATE TABLE t2(a, b);
|
||||
CREATE VIEW a002 AS SELECT *, sum(b) AS m FROM t2 GROUP BY a;
|
||||
}
|
||||
faultsim_save_and_close
|
||||
do_faultsim_test 42 -faults oom-tran* -prep {
|
||||
faultsim_restore_and_reopen
|
||||
execsql { SELECT * FROM sqlite_master }
|
||||
} -body {
|
||||
execsql {
|
||||
SELECT t1.z, a002.m
|
||||
FROM t1 JOIN a002 ON t1.y=a002.m
|
||||
WHERE t1.x IN (1,2,3);
|
||||
}
|
||||
} -test {
|
||||
faultsim_test_result {0 {}}
|
||||
}
|
||||
|
||||
|
||||
# Ensure that no file descriptors were leaked.
|
||||
do_test malloc-99.X {
|
||||
catch {db close}
|
||||
|
||||
@@ -644,4 +644,44 @@ do_execsql_test misc1-22.1 {
|
||||
SELECT ""+3 FROM (SELECT ""+5);
|
||||
} {3}
|
||||
|
||||
# 2015-04-19: NULL pointer dereference on a corrupt schema
|
||||
#
|
||||
db close
|
||||
sqlite3 db :memory:
|
||||
do_execsql_test misc1-23.1 {
|
||||
CREATE TABLE t1(x);
|
||||
PRAGMA writable_schema=ON;
|
||||
UPDATE sqlite_master SET sql='CREATE table t(d CHECK(T(#0)';
|
||||
BEGIN;
|
||||
CREATE TABLE t2(y);
|
||||
ROLLBACK;
|
||||
DROP TABLE IF EXISTS t3;
|
||||
} {}
|
||||
|
||||
# 2015-04-19: Faulty assert() statement
|
||||
#
|
||||
db close
|
||||
database_may_be_corrupt
|
||||
sqlite3 db :memory:
|
||||
do_catchsql_test misc1-23.2 {
|
||||
CREATE TABLE t1(x UNIQUE);
|
||||
PRAGMA writable_schema=ON;
|
||||
UPDATE sqlite_master SET sql='CREATE TABLE IF not EXISTS t(c)';
|
||||
BEGIN;
|
||||
CREATE TABLE t2(x);
|
||||
ROLLBACK;
|
||||
DROP TABLE F;
|
||||
} {1 {no such table: F}}
|
||||
db close
|
||||
sqlite3 db :memory:
|
||||
do_catchsql_test misc1-23.3 {
|
||||
CREATE TABLE t1(x UNIQUE);
|
||||
PRAGMA writable_schema=ON;
|
||||
UPDATE sqlite_master SET sql='CREATE table y(a TEXT, a TEXT)';
|
||||
BEGIN;
|
||||
CREATE TABLE t2(y);
|
||||
ROLLBACK;
|
||||
DROP TABLE IF EXISTS t;
|
||||
} {0 {}}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -583,6 +583,24 @@ do_test misc5-7.1 {
|
||||
catchsql $sql
|
||||
} {1 {parser stack overflow}}
|
||||
|
||||
# Parser stack overflow is silently ignored when it occurs while parsing the
|
||||
# schema and PRAGMA writable_schema is turned on.
|
||||
#
|
||||
do_test misc5-7.2 {
|
||||
sqlite3 db2 :memory:
|
||||
catchsql {
|
||||
CREATE TABLE t1(x UNIQUE);
|
||||
PRAGMA writable_schema=ON;
|
||||
UPDATE sqlite_master SET sql='CREATE table t(o CHECK(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((;VALUES(o)';
|
||||
BEGIN;
|
||||
CREATE TABLE t2(y);
|
||||
ROLLBACK;
|
||||
DROP TABLE IF EXISTS D;
|
||||
} db2
|
||||
} {0 {}}
|
||||
db2 close
|
||||
|
||||
|
||||
# Ticket #1911
|
||||
#
|
||||
ifcapable compound {
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
#!/usr/bin/tclsh
|
||||
#
|
||||
# Run this script in order to rebuild the fuzzdata1.txt file containing
|
||||
# fuzzer data for the fuzzershell utility that is create by afl-fuzz.
|
||||
#
|
||||
# This script gathers all of the test cases identified by afl-fuzz and
|
||||
# runs afl-cmin and afl-tmin over them all to try to generate a mimimum
|
||||
# set of tests that cover all observed behavior.
|
||||
#
|
||||
# Options:
|
||||
#
|
||||
# --afl-bin DIR1 DIR1 contains the AFL binaries
|
||||
# --fuzzershell PATH Full pathname of instrumented fuzzershell
|
||||
# --afl-data DIR3 DIR3 is the "-o" directory from afl-fuzz
|
||||
# -o FILE Write results into FILE
|
||||
#
|
||||
set AFLBIN {}
|
||||
set FUZZERSHELL {}
|
||||
set AFLDATA {}
|
||||
set OUTFILE {}
|
||||
|
||||
proc usage {} {
|
||||
puts stderr "Usage: $::argv0 --afl-bin DIR --fuzzershell PATH\
|
||||
--afl-data DIR -o FILE"
|
||||
exit 1
|
||||
}
|
||||
proc cmdlineerr {msg} {
|
||||
puts stderr $msg
|
||||
usage
|
||||
}
|
||||
|
||||
for {set i 0} {$i<[llength $argv]} {incr i} {
|
||||
set x [lindex $argv $i]
|
||||
if {[string index $x 0]!="-"} {cmdlineerr "illegal argument: $x"}
|
||||
set x [string trimleft $x -]
|
||||
incr i
|
||||
if {$i>=[llength $argv]} {cmdlineerr "no argument on --$x"}
|
||||
set a [lindex $argv $i]
|
||||
switch -- $x {
|
||||
afl-bin {set AFLBIN $a}
|
||||
afl-data {set AFLDATA $a}
|
||||
fuzzershell {set FUZZERSHELL $a}
|
||||
o {set OUTFILE $a}
|
||||
default {cmdlineerr "unknown option: --$x"}
|
||||
}
|
||||
}
|
||||
proc checkarg {varname option} {
|
||||
set val [set ::$varname]
|
||||
if {$val==""} {cmdlineerr "required option missing: --$option"}
|
||||
}
|
||||
checkarg AFLBIN afl-bin
|
||||
checkarg AFLDATA afl-data
|
||||
checkarg FUZZERSHELL fuzzershell
|
||||
checkarg OUTFILE o
|
||||
proc checkexec {x} {
|
||||
if {![file exec $x]} {cmdlineerr "cannot find $x"}
|
||||
}
|
||||
checkexec $AFLBIN/afl-cmin
|
||||
checkexec $AFLBIN/afl-tmin
|
||||
checkexec $FUZZERSHELL
|
||||
proc checkdir {x} {
|
||||
if {![file isdir $x]} {cmdlineerr "no such directory: $x"}
|
||||
}
|
||||
checkdir $AFLDATA/queue
|
||||
|
||||
proc progress {msg} {
|
||||
puts "******** $msg"
|
||||
flush stdout
|
||||
}
|
||||
progress "mkdir tmp1 tmp2"
|
||||
file mkdir tmp1 tmp2
|
||||
progress "copying test cases from $AFLDATA into tmp1..."
|
||||
set n 0
|
||||
foreach file [glob -nocomplain $AFLDATA/queue/id:*] {
|
||||
incr n
|
||||
file copy $file tmp1/$n
|
||||
}
|
||||
foreach file [glob -nocomplain $AFLDATA/crash*/id:*] {
|
||||
incr n
|
||||
file copy $file tmp1/$n
|
||||
}
|
||||
progress "total $n files copied."
|
||||
progress "running: $AFLBIN/afl-cmin -i tmp1 -o tmp2 $FUZZERSHELL"
|
||||
exec $AFLBIN/afl-cmin -i tmp1 -o tmp2 $FUZZERSHELL >&@ stdout
|
||||
progress "afl-cmin complete."
|
||||
#
|
||||
# Experiments show that running afl-tmin is too slow for this application.
|
||||
# And it doesn't really make the test cases that much smaller. So let's
|
||||
# just skip it.
|
||||
#
|
||||
# foreach file [glob tmp2/*] {
|
||||
# progress "$AFLBIN/afl-tmin -i $file -o tmp3/[file tail $file] $FUZZERSHELL"
|
||||
# exec $AFLBIN/afl-tmin -i $file -o tmp3/[file tail $file] \
|
||||
# $FUZZERSHELL >&@ stdout
|
||||
# }
|
||||
progress "generating final output into $OUTFILE"
|
||||
set out [open $OUTFILE wb]
|
||||
puts $out "# Test data for use with fuzzershell. Automatically
|
||||
# generated using $argv0. This file contains binary data
|
||||
#"
|
||||
set n 0
|
||||
foreach file [glob tmp2/*] {
|
||||
incr n
|
||||
puts -nonewline $out "/****<$n>****/"
|
||||
set in [open $file rb]
|
||||
puts -nonewline $out [read $in]
|
||||
close $in
|
||||
}
|
||||
close $out
|
||||
progress "done. $n test cases written to $OUTFILE"
|
||||
progress "clean-up..."
|
||||
file delete -force tmp1
|
||||
progress "culled test cases left in the tmp2 directory"
|
||||
@@ -219,6 +219,24 @@ do_test pragma-1.14 {
|
||||
PRAGMA synchronous;
|
||||
}
|
||||
} {2}
|
||||
do_test pragma-1.14.1 {
|
||||
execsql {
|
||||
PRAGMA synchronous=4;
|
||||
PRAGMA synchronous;
|
||||
}
|
||||
} {0}
|
||||
do_test pragma-1.14.2 {
|
||||
execsql {
|
||||
PRAGMA synchronous=3;
|
||||
PRAGMA synchronous;
|
||||
}
|
||||
} {0}
|
||||
do_test pragma-1.14.3 {
|
||||
execsql {
|
||||
PRAGMA synchronous=10;
|
||||
PRAGMA synchronous;
|
||||
}
|
||||
} {2}
|
||||
} ;# ifcapable pager_pragmas
|
||||
|
||||
# Test turning "flag" pragmas on and off.
|
||||
|
||||
+21
-2
@@ -18,6 +18,7 @@ optional) are:
|
||||
--buildonly (Just build testfixture - do not run)
|
||||
--dryrun (Print what would have happened)
|
||||
--info (Show diagnostic info)
|
||||
--with-tcl=DIR (Use TCL build at DIR)
|
||||
|
||||
The default value for --srcdir is the parent of the directory holding
|
||||
this script.
|
||||
@@ -110,6 +111,13 @@ array set ::Configs [strip_comments {
|
||||
-DSQLITE_ENABLE_STAT4
|
||||
-DSQLITE_MAX_ATTACHED=125
|
||||
}
|
||||
"Fast-One" {
|
||||
-O6
|
||||
-DSQLITE_ENABLE_FTS4=1
|
||||
-DSQLITE_ENABLE_RTREE=1
|
||||
-DSQLITE_ENABLE_STAT4
|
||||
-DSQLITE_MAX_ATTACHED=125
|
||||
}
|
||||
"Device-One" {
|
||||
-O2
|
||||
-DSQLITE_DEBUG=1
|
||||
@@ -199,6 +207,8 @@ array set ::Configs [strip_comments {
|
||||
Fail2 {-O0}
|
||||
Fail3 {-O0}
|
||||
Fail4 {-O0}
|
||||
FuzzFail1 {-O0}
|
||||
FuzzFail2 {-O0}
|
||||
}]
|
||||
|
||||
array set ::Platforms [strip_comments {
|
||||
@@ -214,6 +224,7 @@ array set ::Platforms [strip_comments {
|
||||
"No-lookaside" test
|
||||
"Devkit" test
|
||||
"Sanitize" {QUICKTEST_OMIT=func4.test,nan.test test}
|
||||
"Fast-One" fuzzoomtest
|
||||
"Valgrind" valgrindtest
|
||||
"Default" "threadtest fulltest"
|
||||
"Device-One" fulltest
|
||||
@@ -255,6 +266,8 @@ array set ::Platforms [strip_comments {
|
||||
Fail2 "TEST_FAILURE=2 valgrindtest"
|
||||
Fail3 "TEST_FAILURE=3 valgrindtest"
|
||||
Fail4 "TEST_FAILURE=4 test"
|
||||
FuzzFail1 "TEST_FAILURE=5 test"
|
||||
FuzzFail2 "TEST_FAILURE=5 valgrindtest"
|
||||
}
|
||||
}]
|
||||
|
||||
@@ -351,7 +364,7 @@ proc run_test_suite {name testtarget config} {
|
||||
set cflags [expr {$::MSVC ? "-Zi" : "-g"}]
|
||||
set opts ""
|
||||
set title ${name}($testtarget)
|
||||
set configOpts ""
|
||||
set configOpts $::WITHTCL
|
||||
|
||||
regsub -all {#[^\n]*\n} $config \n config
|
||||
foreach arg $config {
|
||||
@@ -482,6 +495,7 @@ proc process_options {argv} {
|
||||
set ::DRYRUN 0
|
||||
set ::EXEC exec
|
||||
set ::TRACE 0
|
||||
set ::WITHTCL {}
|
||||
set config {}
|
||||
set platform $::tcl_platform(os)-$::tcl_platform(machine)
|
||||
|
||||
@@ -556,6 +570,10 @@ proc process_options {argv} {
|
||||
}
|
||||
}
|
||||
|
||||
-with-tcl=* {
|
||||
set ::WITHTCL -$x
|
||||
}
|
||||
|
||||
-D* -
|
||||
-O* -
|
||||
-enable-* -
|
||||
@@ -643,10 +661,11 @@ proc main {argv} {
|
||||
# it and run veryquick.test. If it did not include the SQLITE_DEBUG option
|
||||
# add it and run veryquick.test.
|
||||
if {$target!="checksymbols" && $target!="valgrindtest"
|
||||
&& !$::BUILDONLY && $::QUICK<2} {
|
||||
&& $target!="fuzzoomtest" && !$::BUILDONLY && $::QUICK<2} {
|
||||
set debug_idx [lsearch -glob $config_options -DSQLITE_DEBUG*]
|
||||
set xtarget $target
|
||||
regsub -all {fulltest[a-z]*} $xtarget test xtarget
|
||||
regsub -all {fuzzoomtest} $xtarget fuzztest xtarget
|
||||
if {$debug_idx < 0} {
|
||||
incr NTEST
|
||||
append config_options " -DSQLITE_DEBUG=1"
|
||||
|
||||
@@ -11,10 +11,12 @@
|
||||
#
|
||||
# This file tests features of the name resolver (the component that
|
||||
# figures out what identifiers in the SQL statement refer to) that
|
||||
# were fixed by ticket [2500cdb9be]
|
||||
# were fixed by ticket [2500cdb9be].
|
||||
#
|
||||
# See also tickets [1c69be2daf] and [f617ea3125] from 2013-08-14.
|
||||
#
|
||||
# Also a fuzzer-discovered problem on 2015-04-23.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@@ -201,6 +203,12 @@ do_execsql_test resolver01-6.3 {
|
||||
GROUP BY lower(name);
|
||||
} {1 {} 1 {}}
|
||||
|
||||
do_execsql_test resolver01-7.1 {
|
||||
SELECT 2 AS x WHERE (SELECT x AS y WHERE 3>y);
|
||||
} {2}
|
||||
do_execsql_test resolver01-7.2 {
|
||||
SELECT 2 AS x WHERE (SELECT x AS y WHERE 1>y);
|
||||
} {}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -307,6 +307,9 @@ do_test select1-4.4 {
|
||||
set v [catch {execsql {SELECT f1 FROM test1 ORDER BY min(f1)}} msg]
|
||||
lappend v $msg
|
||||
} {1 {misuse of aggregate: min()}}
|
||||
do_catchsql_test select1-4.5 {
|
||||
INSERT INTO test1(f1) SELECT f1 FROM test1 ORDER BY min(f1);
|
||||
} {1 {misuse of aggregate: min()}}
|
||||
|
||||
# The restriction not allowing constants in the ORDER BY clause
|
||||
# has been removed. See ticket #1768
|
||||
@@ -1072,5 +1075,10 @@ if {[db one {PRAGMA locking_mode}]=="normal"} {
|
||||
do_test select1-16.1 {
|
||||
catchsql {SELECT 1 FROM (SELECT *)}
|
||||
} {1 {no tables specified}}
|
||||
|
||||
# 2015-04-17: assertion fix.
|
||||
do_catchsql_test select1-16.2 {
|
||||
SELECT 1 FROM sqlite_master LIMIT 1,#1;
|
||||
} {1 {near "#1": syntax error}}
|
||||
|
||||
finish_test
|
||||
|
||||
+22
-1
@@ -118,6 +118,10 @@ do_test select4-1.3 {
|
||||
}} msg]
|
||||
lappend v $msg
|
||||
} {1 {ORDER BY clause should come after UNION ALL not before}}
|
||||
do_catchsql_test select4-1.4 {
|
||||
SELECT (VALUES(0) INTERSECT SELECT(0) UNION SELECT(0) ORDER BY 1 UNION
|
||||
SELECT 0 UNION SELECT 0 ORDER BY 1);
|
||||
} {1 {ORDER BY clause should come after UNION not before}}
|
||||
|
||||
# Union operator
|
||||
#
|
||||
@@ -148,6 +152,12 @@ do_test select4-2.3 {
|
||||
}} msg]
|
||||
lappend v $msg
|
||||
} {1 {ORDER BY clause should come after UNION not before}}
|
||||
do_test select4-2.4 {
|
||||
set v [catch {execsql {
|
||||
SELECT 0 ORDER BY (SELECT 0) UNION SELECT 0;
|
||||
}} msg]
|
||||
lappend v $msg
|
||||
} {1 {ORDER BY clause should come after UNION not before}}
|
||||
|
||||
# Except operator
|
||||
#
|
||||
@@ -874,6 +884,17 @@ do_execsql_test select4-14.10 {
|
||||
do_execsql_test select4-14.11 {
|
||||
SELECT (SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4)
|
||||
} {1}
|
||||
|
||||
do_execsql_test select4-14.12 {
|
||||
VALUES(1) UNION VALUES(2);
|
||||
} {1 2}
|
||||
do_execsql_test select4-14.13 {
|
||||
VALUES(1),(2),(3) EXCEPT VALUES(2);
|
||||
} {1 3}
|
||||
do_execsql_test select4-14.14 {
|
||||
VALUES(1),(2),(3) EXCEPT VALUES(1),(3);
|
||||
} {2}
|
||||
do_execsql_test select4-14.15 {
|
||||
SELECT * FROM (SELECT 123), (SELECT 456) ON likely(0 OR 1) OR 0;
|
||||
} {123 456}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
# 2015 April 28
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
source $testdir/malloc_common.tcl
|
||||
set testprefix statfault
|
||||
|
||||
ifcapable !vtab||!compound {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
register_dbstat_vtab db
|
||||
do_execsql_test statfault-1 {
|
||||
CREATE TABLE t1(a, b UNIQUE);
|
||||
INSERT INTO t1 VALUES(1, randomblob(500));
|
||||
INSERT INTO t1 VALUES(randomblob(500), 1);
|
||||
INSERT INTO t1 VALUES(2, randomblob(250));
|
||||
INSERT INTO t1 VALUES(randomblob(250), 2);
|
||||
CREATE VIRTUAL TABLE sss USING dbstat;
|
||||
} {}
|
||||
faultsim_save_and_close
|
||||
|
||||
do_faultsim_test 1 -faults * -prep {
|
||||
faultsim_restore_and_reopen
|
||||
register_dbstat_vtab db
|
||||
execsql { SELECT 1 FROM sqlite_master LIMIT 1 }
|
||||
} -body {
|
||||
execsql { SELECT count(*) FROM sss }
|
||||
} -test {
|
||||
faultsim_test_result {0 8}
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
@@ -584,4 +584,14 @@ do_test subquery-7.11 {
|
||||
} {30303}
|
||||
} ;############# Disabled
|
||||
|
||||
# 2015-04-21.
|
||||
# Verify that a memory leak in the table column type and collation analysis
|
||||
# is plugged.
|
||||
#
|
||||
do_execsql_test subquery-8.1 {
|
||||
CREATE TABLE t8(a TEXT, b INT);
|
||||
SELECT (SELECT 0 FROM (SELECT * FROM t1)) AS x WHERE x;
|
||||
SELECT (SELECT 0 FROM (SELECT * FROM (SELECT 0))) AS x WHERE x;
|
||||
} {}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -272,6 +272,25 @@ do_test table-5.2.1 {
|
||||
}
|
||||
} {}
|
||||
|
||||
do_test table-5.2.2 {
|
||||
db close
|
||||
forcedelete test.db
|
||||
sqlite3 db test.db
|
||||
db eval {
|
||||
CREATE TABLE t0(a,b);
|
||||
CREATE INDEX t ON t0(a);
|
||||
PRAGMA writable_schema=ON;
|
||||
UPDATE sqlite_master SET sql='CREATE TABLE a.b(a UNIQUE';
|
||||
BEGIN;
|
||||
CREATE TABLE t1(x);
|
||||
ROLLBACK;
|
||||
DROP TABLE IF EXISTS t99;
|
||||
}
|
||||
} {}
|
||||
db close
|
||||
forcedelete test.db
|
||||
sqlite3 db test.db
|
||||
|
||||
# Make sure an EXPLAIN does not really create a new table
|
||||
#
|
||||
do_test table-5.3 {
|
||||
|
||||
+1
-1
@@ -143,7 +143,7 @@ ifcapable fts3 {
|
||||
INSERT INTO x1(x1) VALUES('optimize');
|
||||
} {
|
||||
"INSERT INTO x1(x1) VALUES('optimize');"
|
||||
"-- SELECT DISTINCT level / (1024 * ?) FROM 'main'.'x1_segdir'"
|
||||
"-- SELECT ? UNION SELECT level / (1024 * ?) FROM 'main'.'x1_segdir'"
|
||||
"-- SELECT idx, start_block, leaves_end_block, end_block, root FROM 'main'.'x1_segdir' WHERE level BETWEEN ? AND ?ORDER BY level DESC, idx ASC"
|
||||
"-- SELECT max(level) FROM 'main'.'x1_segdir' WHERE level BETWEEN ? AND ?"
|
||||
"-- SELECT coalesce((SELECT max(blockid) FROM 'main'.'x1_segments') + 1, 1)"
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix triggerC
|
||||
ifcapable {!trigger} {
|
||||
finish_test
|
||||
return
|
||||
@@ -993,4 +994,52 @@ reset_db
|
||||
optimization_control db factor-constants 0
|
||||
do_execsql_test triggerC-14.2 $SQL {1 2 3}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Check that table names used by trigger programs are dequoted exactly
|
||||
# once.
|
||||
#
|
||||
do_execsql_test 15.1.1 {
|
||||
PRAGMA recursive_triggers = 1;
|
||||
CREATE TABLE node(
|
||||
id int not null primary key,
|
||||
pid int not null default 0 references node,
|
||||
key varchar not null,
|
||||
path varchar default '',
|
||||
unique(pid, key)
|
||||
);
|
||||
CREATE TRIGGER node_delete_referencing AFTER DELETE ON "node"
|
||||
BEGIN
|
||||
DELETE FROM "node" WHERE pid = old."id";
|
||||
END;
|
||||
}
|
||||
do_execsql_test 15.1.2 {
|
||||
INSERT INTO node(id, pid, key) VALUES(9, 0, 'test');
|
||||
INSERT INTO node(id, pid, key) VALUES(90, 9, 'test1');
|
||||
INSERT INTO node(id, pid, key) VALUES(900, 90, 'test2');
|
||||
DELETE FROM node WHERE id=9;
|
||||
SELECT * FROM node;
|
||||
}
|
||||
|
||||
do_execsql_test 15.2.1 {
|
||||
CREATE TABLE x1 (x);
|
||||
|
||||
CREATE TABLE x2 (a, b);
|
||||
CREATE TABLE '"x2"'(a, b);
|
||||
|
||||
INSERT INTO x2 VALUES(1, 2);
|
||||
INSERT INTO x2 VALUES(3, 4);
|
||||
INSERT INTO '"x2"' SELECT * FROM x2;
|
||||
|
||||
CREATE TRIGGER x1ai AFTER INSERT ON x1 BEGIN
|
||||
INSERT INTO """x2""" VALUES('x', 'y');
|
||||
DELETE FROM """x2""" WHERE a=1;
|
||||
UPDATE """x2""" SET b = 11 WHERE a = 3;
|
||||
END;
|
||||
|
||||
INSERT INTO x1 VALUES('go!');
|
||||
}
|
||||
|
||||
do_execsql_test 15.2.2 { SELECT * FROM x2; } {1 2 3 4}
|
||||
do_execsql_test 15.2.3 { SELECT * FROM """x2"""; } {3 11 x y}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -1491,4 +1491,41 @@ do_test 23.3.1 {
|
||||
} {1 {database table is locked}}
|
||||
do_execsql_test 23.3.2 { SELECT * FROM t1e } {1 2 3 4}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# At one point SQL like this:
|
||||
#
|
||||
# SAVEPOINT xyz; -- Opens SQL transaction
|
||||
# INSERT INTO vtab -- Write to virtual table
|
||||
# ROLLBACK TO xyz;
|
||||
# RELEASE xyz;
|
||||
#
|
||||
# was not invoking the xRollbackTo() callback for the ROLLBACK TO
|
||||
# operation. Which meant that virtual tables like FTS3 would incorrectly
|
||||
# commit the results of the INSERT as part of the "RELEASE xyz" command.
|
||||
#
|
||||
# The following tests check that this has been fixed.
|
||||
#
|
||||
ifcapable fts3 {
|
||||
do_execsql_test 24.0 {
|
||||
CREATE VIRTUAL TABLE t4 USING fts3();
|
||||
SAVEPOINT a;
|
||||
INSERT INTO t4 VALUES('a b c');
|
||||
ROLLBACK TO a;
|
||||
RELEASE a;
|
||||
SELECT * FROM t4;
|
||||
} {}
|
||||
|
||||
do_execsql_test 24.1 { SELECT * FROM t4 WHERE t4 MATCH 'b' } {}
|
||||
do_execsql_test 24.2 { INSERT INTO t4(t4) VALUES('integrity-check') } {}
|
||||
|
||||
do_execsql_test 24.3 {
|
||||
SAVEPOINT a;
|
||||
CREATE VIRTUAL TABLE t5 USING fts3();
|
||||
SAVEPOINT b;
|
||||
ROLLBACK TO a;
|
||||
SAVEPOINT c;
|
||||
RELEASE a;
|
||||
}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
+17
-6
@@ -74,28 +74,39 @@ do_test vtabA-1.6 {
|
||||
SELECT * FROM t1e;
|
||||
}
|
||||
} {{value a} {value c}}
|
||||
do_execsql_test vtabA-1.7 {
|
||||
DELETE FROM t1e;
|
||||
INSERT INTO t1e SELECT 'abc','def';
|
||||
} {}
|
||||
do_execsql_test vtabA-1.8 {
|
||||
INSERT INTO t1e VALUES('ghi','jkl'),('mno','pqr'),('stu','vwx');
|
||||
} {}
|
||||
do_execsql_test vtabA-1.9 {
|
||||
SELECT a,b,c, '|' FROM t1e ORDER BY 1;
|
||||
} {abc {} def | ghi {} jkl | mno {} pqr | stu {} vwx |}
|
||||
|
||||
|
||||
# Test that the expansion of a '*' expression in the result set of
|
||||
# a SELECT does not include the hidden column.
|
||||
#
|
||||
do_test vtabA-1.7 {
|
||||
do_test vtabA-1.20 {
|
||||
execsql {
|
||||
INSERT INTO t1e SELECT * FROM t1e;
|
||||
}
|
||||
} {}
|
||||
do_test vtabA-1.8 {
|
||||
do_test vtabA-1.21 {
|
||||
execsql {
|
||||
SELECT * FROM t1e;
|
||||
SELECT * FROM t1e ORDER BY 1;
|
||||
}
|
||||
} {{value a} {value c} {value a} {value c}}
|
||||
} {abc def abc def ghi jkl ghi jkl mno pqr mno pqr stu vwx stu vwx}
|
||||
|
||||
# Test that the declaration type of the hidden column does not include
|
||||
# the token "HIDDEN".
|
||||
#
|
||||
do_test vtabA-1.9 {
|
||||
do_test vtabA-1.22 {
|
||||
get_decltype t1e b
|
||||
} {VARCHAR}
|
||||
do_test vtabA-1.10 {
|
||||
do_test vtabA-1.23 {
|
||||
get_collist t1e
|
||||
} {a c}
|
||||
|
||||
|
||||
+125
-19
@@ -28,6 +28,11 @@ REM In the example above, "C:\dev\sqlite\core" represents the root of the
|
||||
REM source tree for SQLite and "C:\Temp" represents the final destination
|
||||
REM directory for the generated output files.
|
||||
REM
|
||||
REM Please note that the SQLite build process performed by the Makefile
|
||||
REM associated with this batch script requires both Gawk ^(gawk.exe^) and Tcl
|
||||
REM 8.5 ^(tclsh85.exe^) to be present in a directory contained in the PATH
|
||||
REM environment variable unless a pre-existing amalgamation file is used.
|
||||
REM
|
||||
REM There are several environment variables that may be set to modify the
|
||||
REM behavior of this batch script and its associated Makefile. The list of
|
||||
REM platforms to build may be overriden by using the PLATFORMS environment
|
||||
@@ -37,17 +42,58 @@ REM being used. The list of configurations to build may be overridden by
|
||||
REM setting the CONFIGURATIONS environment variable, which should contain a
|
||||
REM list of configurations to build ^(e.g. Debug Retail^). Neither of these
|
||||
REM variable values may contain any double quotes, surrounding or embedded.
|
||||
REM Finally, the NCRTLIBPATH and NSDKLIBPATH environment variables may be set
|
||||
REM to specify the location of the CRT and SDK, respectively, needed to compile
|
||||
REM executables native to the architecture of the build machine during any
|
||||
REM cross-compilation that may be necessary, depending on the platforms to be
|
||||
REM built. These values in these two variables should be surrounded by double
|
||||
REM quotes if they contain spaces.
|
||||
REM
|
||||
REM Please note that the SQLite build process performed by the Makefile
|
||||
REM associated with this batch script requires both Gawk ^(gawk.exe^) and Tcl
|
||||
REM 8.5 ^(tclsh85.exe^) to be present in a directory contained in the PATH
|
||||
REM environment variable unless a pre-existing amalgamation file is used.
|
||||
REM Finally, the NCRTLIBPATH, NUCRTLIBPATH, and NSDKLIBPATH environment
|
||||
REM variables may be set to specify the location of the CRT, Universal CRT, and
|
||||
REM Windows SDK, respectively, that may be needed to compile executables native
|
||||
REM to the architecture of the build machine during any cross-compilation that
|
||||
REM may be necessary, depending on the platforms to be built. These values in
|
||||
REM these three variables should be surrounded by double quotes if they contain
|
||||
REM spaces.
|
||||
REM
|
||||
REM There are a few other environment variables that impact the build process
|
||||
REM when set ^(to anything^), they are:
|
||||
REM
|
||||
REM NOCLEAN
|
||||
REM
|
||||
REM When set, the "clean" target will not be used during each build iteration.
|
||||
REM However, the target binaries, if any, will still be deleted manually prior
|
||||
REM to being rebuilt. Setting this environment variable is only rarely needed
|
||||
REM and could cause issues in some circumstances; therefore, setting it is not
|
||||
REM recommended.
|
||||
REM
|
||||
REM NOSYMBOLS
|
||||
REM
|
||||
REM When set, copying of symbol files ^(*.pdb^) created during the build will
|
||||
REM be skipped and they will not appear in the final destination directory.
|
||||
REM Setting this environment variable is never strictly needed and could cause
|
||||
REM issues in some circumstances; therefore, setting it is not recommended.
|
||||
REM
|
||||
REM BUILD_ALL_SHELL
|
||||
REM
|
||||
REM When set, the command line shell will be built for each selected platform
|
||||
REM and configuration as well. In addition, the command line shell binaries
|
||||
REM will be copied, with their symbols, to the final destination directory.
|
||||
REM
|
||||
REM USE_WINV63_NSDKLIBPATH
|
||||
REM
|
||||
REM When set, modifies how the NSDKLIBPATH environment variable is built, based
|
||||
REM on the WindowsSdkDir environment variable. It forces this batch script to
|
||||
REM assume the Windows 8.1 SDK location should be used.
|
||||
REM
|
||||
REM USE_WINV100_NSDKLIBPATH
|
||||
REM
|
||||
REM When set, modifies how the NSDKLIBPATH environment variable is built, based
|
||||
REM on the WindowsSdkDir environment variable. It causes this batch script to
|
||||
REM assume the Windows 10.0 SDK location should be used.
|
||||
REM
|
||||
REM NMAKE_ARGS
|
||||
REM
|
||||
REM When set, the value is expanded and passed to the NMAKE command line, after
|
||||
REM its other arguments. This is used to specify additional NMAKE options, for
|
||||
REM example:
|
||||
REM
|
||||
REM SET NMAKE_ARGS=FOR_WINRT=1
|
||||
REM
|
||||
SETLOCAL
|
||||
|
||||
@@ -217,8 +263,20 @@ SET TOOLPATH=%gawk.exe_PATH%;%tclsh85.exe_PATH%
|
||||
%_VECHO% ToolPath = '%TOOLPATH%'
|
||||
|
||||
REM
|
||||
REM NOTE: Check for MSVC 2012/2013 because the Windows SDK directory handling
|
||||
REM is slightly different for those versions.
|
||||
REM NOTE: Setting the Windows SDK library path is only required for MSVC
|
||||
REM 2012, 2013, and 2015.
|
||||
REM
|
||||
CALL :fn_UnsetVariable SET_NSDKLIBPATH
|
||||
|
||||
REM
|
||||
REM NOTE: Setting the Universal CRT library path is only required for MSVC
|
||||
REM 2015.
|
||||
REM
|
||||
CALL :fn_UnsetVariable SET_NUCRTLIBPATH
|
||||
|
||||
REM
|
||||
REM NOTE: Check for MSVC 2012, 2013, and 2015 specially because the Windows
|
||||
REM SDK directory handling is slightly different for those versions.
|
||||
REM
|
||||
IF "%VisualStudioVersion%" == "11.0" (
|
||||
REM
|
||||
@@ -236,8 +294,22 @@ IF "%VisualStudioVersion%" == "11.0" (
|
||||
IF NOT DEFINED NSDKLIBPATH (
|
||||
SET SET_NSDKLIBPATH=1
|
||||
)
|
||||
) ELSE (
|
||||
CALL :fn_UnsetVariable SET_NSDKLIBPATH
|
||||
) ELSE IF "%VisualStudioVersion%" == "14.0" (
|
||||
REM
|
||||
REM NOTE: If the Windows SDK library path has already been set, do not set
|
||||
REM it to something else later on.
|
||||
REM
|
||||
IF NOT DEFINED NSDKLIBPATH (
|
||||
SET SET_NSDKLIBPATH=1
|
||||
)
|
||||
|
||||
REM
|
||||
REM NOTE: If the Universal CRT library path has already been set, do not set
|
||||
REM it to something else later on.
|
||||
REM
|
||||
IF NOT DEFINED NUCRTLIBPATH (
|
||||
SET SET_NUCRTLIBPATH=1
|
||||
)
|
||||
)
|
||||
|
||||
REM
|
||||
@@ -294,6 +366,7 @@ FOR %%P IN (%PLATFORMS%) DO (
|
||||
CALL :fn_UnsetVariable LIB
|
||||
CALL :fn_UnsetVariable LIBPATH
|
||||
CALL :fn_UnsetVariable Platform
|
||||
CALL :fn_UnsetVariable UniversalCRTSdkDir
|
||||
REM CALL :fn_UnsetVariable VCINSTALLDIR
|
||||
CALL :fn_UnsetVariable VSINSTALLDIR
|
||||
CALL :fn_UnsetVariable WindowsPhoneKitDir
|
||||
@@ -385,8 +458,8 @@ FOR %%P IN (%PLATFORMS%) DO (
|
||||
)
|
||||
|
||||
REM
|
||||
REM NOTE: When using MSVC 2012 and/or 2013, the native SDK path cannot
|
||||
REM simply use the "lib" sub-directory beneath the location
|
||||
REM NOTE: When using MSVC 2012, 2013, or 2015, the native SDK path
|
||||
REM cannot simply be the "lib" sub-directory beneath the location
|
||||
REM specified in the WindowsSdkDir environment variable because
|
||||
REM that location does not actually contain the necessary library
|
||||
REM files for x86. This must be done for each iteration because
|
||||
@@ -405,19 +478,39 @@ FOR %%P IN (%PLATFORMS%) DO (
|
||||
CALL :fn_CopyVariable WindowsSdkDir NSDKLIBPATH
|
||||
|
||||
REM
|
||||
REM NOTE: The Windows 8.1 SDK has a slightly different directory
|
||||
REM naming convention.
|
||||
REM NOTE: The Windows 8.x and Windows 10.0 SDKs have a slightly
|
||||
REM different directory naming conventions.
|
||||
REM
|
||||
IF DEFINED USE_WINV63_NSDKLIBPATH (
|
||||
IF DEFINED USE_WINV100_NSDKLIBPATH (
|
||||
CALL :fn_AppendVariable NSDKLIBPATH \..\10\lib\10.0.10030.0\um\x86
|
||||
CALL :fn_CopyVariable UniversalCRTSdkDir PSDKLIBPATH
|
||||
CALL :fn_AppendVariable PSDKLIBPATH Lib\10.0.10030.0\um\%%D
|
||||
) ELSE IF DEFINED USE_WINV63_NSDKLIBPATH (
|
||||
CALL :fn_AppendVariable NSDKLIBPATH \lib\winv6.3\um\x86
|
||||
) ELSE IF "%VisualStudioVersion%" == "12.0" (
|
||||
CALL :fn_AppendVariable NSDKLIBPATH \..\8.0\lib\win8\um\x86
|
||||
) ELSE IF "%VisualStudioVersion%" == "14.0" (
|
||||
CALL :fn_AppendVariable NSDKLIBPATH \..\8.0\lib\win8\um\x86
|
||||
) ELSE (
|
||||
CALL :fn_AppendVariable NSDKLIBPATH \lib\win8\um\x86
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
REM
|
||||
REM NOTE: When using MSVC 2015, setting the Universal CRT library path
|
||||
REM for x86 may be required as well. This must also be done for
|
||||
REM each iteration because it relies upon the UniversalCRTSdkDir
|
||||
REM environment variable being set by the batch file used to
|
||||
REM setup the MSVC environment.
|
||||
REM
|
||||
IF DEFINED SET_NUCRTLIBPATH (
|
||||
IF DEFINED UniversalCRTSdkDir (
|
||||
CALL :fn_CopyVariable UniversalCRTSdkDir NUCRTLIBPATH
|
||||
CALL :fn_AppendVariable NUCRTLIBPATH \lib\winv10.0\ucrt\x86
|
||||
)
|
||||
)
|
||||
|
||||
REM
|
||||
REM NOTE: Unless prevented from doing so, invoke NMAKE with the MSVC
|
||||
REM makefile to clean any stale build output from previous
|
||||
@@ -575,6 +668,19 @@ REM NOTE: If we get to this point, we have succeeded.
|
||||
REM
|
||||
GOTO no_errors
|
||||
|
||||
:fn_ShowVariable
|
||||
SETLOCAL
|
||||
SET __ECHO_CMD=ECHO %%%2%%
|
||||
FOR /F "delims=" %%V IN ('%__ECHO_CMD%') DO (
|
||||
IF NOT "%%V" == "" (
|
||||
IF NOT "%%V" == "%%%2%%" (
|
||||
%_VECHO% %1 = '%%V'
|
||||
)
|
||||
)
|
||||
)
|
||||
ENDLOCAL
|
||||
GOTO :EOF
|
||||
|
||||
:fn_ResetErrorLevel
|
||||
VERIFY > NUL
|
||||
GOTO :EOF
|
||||
|
||||
@@ -0,0 +1,839 @@
|
||||
/*
|
||||
** 2015-04-17
|
||||
**
|
||||
** The author disclaims copyright to this source code. In place of
|
||||
** a legal notice, here is a blessing:
|
||||
**
|
||||
** May you do good and not evil.
|
||||
** May you find forgiveness for yourself and forgive others.
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
**
|
||||
** This is a utility program designed to aid running the SQLite library
|
||||
** against an external fuzzer, such as American Fuzzy Lop (AFL)
|
||||
** (http://lcamtuf.coredump.cx/afl/). Basically, this program reads
|
||||
** SQL text from standard input and passes it through to SQLite for evaluation,
|
||||
** just like the "sqlite3" command-line shell. Differences from the
|
||||
** command-line shell:
|
||||
**
|
||||
** (1) The complex "dot-command" extensions are omitted. This
|
||||
** prevents the fuzzer from discovering that it can run things
|
||||
** like ".shell rm -rf ~"
|
||||
**
|
||||
** (2) The database is opened with the SQLITE_OPEN_MEMORY flag so that
|
||||
** no disk I/O from the database is permitted. The ATTACH command
|
||||
** with a filename still uses an in-memory database.
|
||||
**
|
||||
** (3) The main in-memory database can be initialized from a template
|
||||
** disk database so that the fuzzer starts with a database containing
|
||||
** content.
|
||||
**
|
||||
** (4) The eval() SQL function is added, allowing the fuzzer to do
|
||||
** interesting recursive operations.
|
||||
**
|
||||
** (5) An error is raised if there is a memory leak.
|
||||
**
|
||||
** The input text can be divided into separate test cases using comments
|
||||
** of the form:
|
||||
**
|
||||
** |****<...>****|
|
||||
**
|
||||
** where the "..." is arbitrary text. (Except the "|" should really be "/".
|
||||
** "|" is used here to avoid compiler errors about nested comments.)
|
||||
** A separate in-memory SQLite database is created to run each test case.
|
||||
** This feature allows the "queue" of AFL to be captured into a single big
|
||||
** file using a command like this:
|
||||
**
|
||||
** (for i in id:*; do echo '|****<'$i'>****|'; cat $i; done) >~/all-queue.txt
|
||||
**
|
||||
** (Once again, change the "|" to "/") Then all elements of the AFL queue
|
||||
** can be run in a single go (for regression testing, for example) by typing:
|
||||
**
|
||||
** fuzzershell -f ~/all-queue.txt
|
||||
**
|
||||
** After running each chunk of SQL, the database connection is closed. The
|
||||
** program aborts if the close fails or if there is any unfreed memory after
|
||||
** the close.
|
||||
**
|
||||
** New test cases can be appended to all-queue.txt at any time. If redundant
|
||||
** test cases are added, they can be eliminated by running:
|
||||
**
|
||||
** fuzzershell -f ~/all-queue.txt --unique-cases ~/unique-cases.txt
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
#include "sqlite3.h"
|
||||
|
||||
/*
|
||||
** All global variables are gathered into the "g" singleton.
|
||||
*/
|
||||
struct GlobalVars {
|
||||
const char *zArgv0; /* Name of program */
|
||||
sqlite3_mem_methods sOrigMem; /* Original memory methods */
|
||||
sqlite3_mem_methods sOomMem; /* Memory methods with OOM simulator */
|
||||
int iOomCntdown; /* Memory fails on 1 to 0 transition */
|
||||
int nOomFault; /* Increments for each OOM fault */
|
||||
int bOomOnce; /* Fail just once if true */
|
||||
int bOomEnable; /* True to enable OOM simulation */
|
||||
int nOomBrkpt; /* Number of calls to oomFault() */
|
||||
char zTestName[100]; /* Name of current test */
|
||||
} g;
|
||||
|
||||
/*
|
||||
** Maximum number of iterations for an OOM test
|
||||
*/
|
||||
#ifndef OOM_MAX
|
||||
# define OOM_MAX 625
|
||||
#endif
|
||||
|
||||
/*
|
||||
** This routine is called when a simulated OOM occurs. It exists as a
|
||||
** convenient place to set a debugger breakpoint.
|
||||
*/
|
||||
static void oomFault(void){
|
||||
g.nOomBrkpt++; /* Prevent oomFault() from being optimized out */
|
||||
}
|
||||
|
||||
|
||||
/* Versions of malloc() and realloc() that simulate OOM conditions */
|
||||
static void *oomMalloc(int nByte){
|
||||
if( nByte>0 && g.bOomEnable && g.iOomCntdown>0 ){
|
||||
g.iOomCntdown--;
|
||||
if( g.iOomCntdown==0 ){
|
||||
if( g.nOomFault==0 ) oomFault();
|
||||
g.nOomFault++;
|
||||
if( !g.bOomOnce ) g.iOomCntdown = 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return g.sOrigMem.xMalloc(nByte);
|
||||
}
|
||||
static void *oomRealloc(void *pOld, int nByte){
|
||||
if( nByte>0 && g.bOomEnable && g.iOomCntdown>0 ){
|
||||
g.iOomCntdown--;
|
||||
if( g.iOomCntdown==0 ){
|
||||
if( g.nOomFault==0 ) oomFault();
|
||||
g.nOomFault++;
|
||||
if( !g.bOomOnce ) g.iOomCntdown = 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return g.sOrigMem.xRealloc(pOld, nByte);
|
||||
}
|
||||
|
||||
/*
|
||||
** Print an error message and abort in such a way to indicate to the
|
||||
** fuzzer that this counts as a crash.
|
||||
*/
|
||||
static void abendError(const char *zFormat, ...){
|
||||
va_list ap;
|
||||
if( g.zTestName[0] ){
|
||||
fprintf(stderr, "%s (%s): ", g.zArgv0, g.zTestName);
|
||||
}else{
|
||||
fprintf(stderr, "%s: ", g.zArgv0);
|
||||
}
|
||||
va_start(ap, zFormat);
|
||||
vfprintf(stderr, zFormat, ap);
|
||||
va_end(ap);
|
||||
fprintf(stderr, "\n");
|
||||
abort();
|
||||
}
|
||||
/*
|
||||
** Print an error message and quit, but not in a way that would look
|
||||
** like a crash.
|
||||
*/
|
||||
static void fatalError(const char *zFormat, ...){
|
||||
va_list ap;
|
||||
if( g.zTestName[0] ){
|
||||
fprintf(stderr, "%s (%s): ", g.zArgv0, g.zTestName);
|
||||
}else{
|
||||
fprintf(stderr, "%s: ", g.zArgv0);
|
||||
}
|
||||
va_start(ap, zFormat);
|
||||
vfprintf(stderr, zFormat, ap);
|
||||
va_end(ap);
|
||||
fprintf(stderr, "\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
** Evaluate some SQL. Abort if unable.
|
||||
*/
|
||||
static void sqlexec(sqlite3 *db, const char *zFormat, ...){
|
||||
va_list ap;
|
||||
char *zSql;
|
||||
char *zErrMsg = 0;
|
||||
int rc;
|
||||
va_start(ap, zFormat);
|
||||
zSql = sqlite3_vmprintf(zFormat, ap);
|
||||
va_end(ap);
|
||||
rc = sqlite3_exec(db, zSql, 0, 0, &zErrMsg);
|
||||
if( rc ) abendError("failed sql [%s]: %s", zSql, zErrMsg);
|
||||
sqlite3_free(zSql);
|
||||
}
|
||||
|
||||
/*
|
||||
** This callback is invoked by sqlite3_log().
|
||||
*/
|
||||
static void shellLog(void *pNotUsed, int iErrCode, const char *zMsg){
|
||||
printf("LOG: (%d) %s\n", iErrCode, zMsg);
|
||||
fflush(stdout);
|
||||
}
|
||||
static void shellLogNoop(void *pNotUsed, int iErrCode, const char *zMsg){
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
** This callback is invoked by sqlite3_exec() to return query results.
|
||||
*/
|
||||
static int execCallback(void *NotUsed, int argc, char **argv, char **colv){
|
||||
int i;
|
||||
static unsigned cnt = 0;
|
||||
printf("ROW #%u:\n", ++cnt);
|
||||
for(i=0; i<argc; i++){
|
||||
printf(" %s=", colv[i]);
|
||||
if( argv[i] ){
|
||||
printf("[%s]\n", argv[i]);
|
||||
}else{
|
||||
printf("NULL\n");
|
||||
}
|
||||
}
|
||||
fflush(stdout);
|
||||
return 0;
|
||||
}
|
||||
static int execNoop(void *NotUsed, int argc, char **argv, char **colv){
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_TRACE
|
||||
/*
|
||||
** This callback is invoked by sqlite3_trace() as each SQL statement
|
||||
** starts.
|
||||
*/
|
||||
static void traceCallback(void *NotUsed, const char *zMsg){
|
||||
printf("TRACE: %s\n", zMsg);
|
||||
fflush(stdout);
|
||||
}
|
||||
static void traceNoop(void *NotUsed, const char *zMsg){
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************************************************************
|
||||
** eval() implementation copied from ../ext/misc/eval.c
|
||||
*/
|
||||
/*
|
||||
** Structure used to accumulate the output
|
||||
*/
|
||||
struct EvalResult {
|
||||
char *z; /* Accumulated output */
|
||||
const char *zSep; /* Separator */
|
||||
int szSep; /* Size of the separator string */
|
||||
sqlite3_int64 nAlloc; /* Number of bytes allocated for z[] */
|
||||
sqlite3_int64 nUsed; /* Number of bytes of z[] actually used */
|
||||
};
|
||||
|
||||
/*
|
||||
** Callback from sqlite_exec() for the eval() function.
|
||||
*/
|
||||
static int callback(void *pCtx, int argc, char **argv, char **colnames){
|
||||
struct EvalResult *p = (struct EvalResult*)pCtx;
|
||||
int i;
|
||||
for(i=0; i<argc; i++){
|
||||
const char *z = argv[i] ? argv[i] : "";
|
||||
size_t sz = strlen(z);
|
||||
if( (sqlite3_int64)sz+p->nUsed+p->szSep+1 > p->nAlloc ){
|
||||
char *zNew;
|
||||
p->nAlloc = p->nAlloc*2 + sz + p->szSep + 1;
|
||||
/* Using sqlite3_realloc64() would be better, but it is a recent
|
||||
** addition and will cause a segfault if loaded by an older version
|
||||
** of SQLite. */
|
||||
zNew = p->nAlloc<=0x7fffffff ? sqlite3_realloc(p->z, (int)p->nAlloc) : 0;
|
||||
if( zNew==0 ){
|
||||
sqlite3_free(p->z);
|
||||
memset(p, 0, sizeof(*p));
|
||||
return 1;
|
||||
}
|
||||
p->z = zNew;
|
||||
}
|
||||
if( p->nUsed>0 ){
|
||||
memcpy(&p->z[p->nUsed], p->zSep, p->szSep);
|
||||
p->nUsed += p->szSep;
|
||||
}
|
||||
memcpy(&p->z[p->nUsed], z, sz);
|
||||
p->nUsed += sz;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Implementation of the eval(X) and eval(X,Y) SQL functions.
|
||||
**
|
||||
** Evaluate the SQL text in X. Return the results, using string
|
||||
** Y as the separator. If Y is omitted, use a single space character.
|
||||
*/
|
||||
static void sqlEvalFunc(
|
||||
sqlite3_context *context,
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
const char *zSql;
|
||||
sqlite3 *db;
|
||||
char *zErr = 0;
|
||||
int rc;
|
||||
struct EvalResult x;
|
||||
|
||||
memset(&x, 0, sizeof(x));
|
||||
x.zSep = " ";
|
||||
zSql = (const char*)sqlite3_value_text(argv[0]);
|
||||
if( zSql==0 ) return;
|
||||
if( argc>1 ){
|
||||
x.zSep = (const char*)sqlite3_value_text(argv[1]);
|
||||
if( x.zSep==0 ) return;
|
||||
}
|
||||
x.szSep = (int)strlen(x.zSep);
|
||||
db = sqlite3_context_db_handle(context);
|
||||
rc = sqlite3_exec(db, zSql, callback, &x, &zErr);
|
||||
if( rc!=SQLITE_OK ){
|
||||
sqlite3_result_error(context, zErr, -1);
|
||||
sqlite3_free(zErr);
|
||||
}else if( x.zSep==0 ){
|
||||
sqlite3_result_error_nomem(context);
|
||||
sqlite3_free(x.z);
|
||||
}else{
|
||||
sqlite3_result_text(context, x.z, (int)x.nUsed, sqlite3_free);
|
||||
}
|
||||
}
|
||||
/* End of the eval() implementation
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
** Print sketchy documentation for this utility program
|
||||
*/
|
||||
static void showHelp(void){
|
||||
printf("Usage: %s [options] ?FILE...?\n", g.zArgv0);
|
||||
printf(
|
||||
"Read SQL text from FILE... (or from standard input if FILE... is omitted)\n"
|
||||
"and then evaluate each block of SQL contained therein.\n"
|
||||
"Options:\n"
|
||||
" --autovacuum Enable AUTOVACUUM mode\n"
|
||||
" --heap SZ MIN Memory allocator uses SZ bytes & min allocation MIN\n"
|
||||
" --help Show this help text\n"
|
||||
" --lookaside N SZ Configure lookaside for N slots of SZ bytes each\n"
|
||||
" --oom Run each test multiple times in a simulated OOM loop\n"
|
||||
" --pagesize N Set the page size to N\n"
|
||||
" --pcache N SZ Configure N pages of pagecache each of size SZ bytes\n"
|
||||
" -q Reduced output\n"
|
||||
" --quiet Reduced output\n"
|
||||
" --scratch N SZ Configure scratch memory for N slots of SZ bytes each\n"
|
||||
" --unique-cases FILE Write all unique test cases to FILE\n"
|
||||
" --utf16be Set text encoding to UTF-16BE\n"
|
||||
" --utf16le Set text encoding to UTF-16LE\n"
|
||||
" -v Increased output\n"
|
||||
" --verbose Increased output\n"
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the value of a hexadecimal digit. Return -1 if the input
|
||||
** is not a hex digit.
|
||||
*/
|
||||
static int hexDigitValue(char c){
|
||||
if( c>='0' && c<='9' ) return c - '0';
|
||||
if( c>='a' && c<='f' ) return c - 'a' + 10;
|
||||
if( c>='A' && c<='F' ) return c - 'A' + 10;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
** Interpret zArg as an integer value, possibly with suffixes.
|
||||
*/
|
||||
static int integerValue(const char *zArg){
|
||||
sqlite3_int64 v = 0;
|
||||
static const struct { char *zSuffix; int iMult; } aMult[] = {
|
||||
{ "KiB", 1024 },
|
||||
{ "MiB", 1024*1024 },
|
||||
{ "GiB", 1024*1024*1024 },
|
||||
{ "KB", 1000 },
|
||||
{ "MB", 1000000 },
|
||||
{ "GB", 1000000000 },
|
||||
{ "K", 1000 },
|
||||
{ "M", 1000000 },
|
||||
{ "G", 1000000000 },
|
||||
};
|
||||
int i;
|
||||
int isNeg = 0;
|
||||
if( zArg[0]=='-' ){
|
||||
isNeg = 1;
|
||||
zArg++;
|
||||
}else if( zArg[0]=='+' ){
|
||||
zArg++;
|
||||
}
|
||||
if( zArg[0]=='0' && zArg[1]=='x' ){
|
||||
int x;
|
||||
zArg += 2;
|
||||
while( (x = hexDigitValue(zArg[0]))>=0 ){
|
||||
v = (v<<4) + x;
|
||||
zArg++;
|
||||
}
|
||||
}else{
|
||||
while( isdigit(zArg[0]) ){
|
||||
v = v*10 + zArg[0] - '0';
|
||||
zArg++;
|
||||
}
|
||||
}
|
||||
for(i=0; i<sizeof(aMult)/sizeof(aMult[0]); i++){
|
||||
if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
|
||||
v *= aMult[i].iMult;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( v>0x7fffffff ) abendError("parameter too large - max 2147483648");
|
||||
return (int)(isNeg? -v : v);
|
||||
}
|
||||
|
||||
/* Return the current wall-clock time */
|
||||
static sqlite3_int64 timeOfDay(void){
|
||||
static sqlite3_vfs *clockVfs = 0;
|
||||
sqlite3_int64 t;
|
||||
if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
|
||||
if( clockVfs->iVersion>=1 && clockVfs->xCurrentTimeInt64!=0 ){
|
||||
clockVfs->xCurrentTimeInt64(clockVfs, &t);
|
||||
}else{
|
||||
double r;
|
||||
clockVfs->xCurrentTime(clockVfs, &r);
|
||||
t = (sqlite3_int64)(r*86400000.0);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv){
|
||||
char *zIn = 0; /* Input text */
|
||||
int nAlloc = 0; /* Number of bytes allocated for zIn[] */
|
||||
int nIn = 0; /* Number of bytes of zIn[] used */
|
||||
size_t got; /* Bytes read from input */
|
||||
int rc = SQLITE_OK; /* Result codes from API functions */
|
||||
int i; /* Loop counter */
|
||||
int iNext; /* Next block of SQL */
|
||||
sqlite3 *db; /* Open database */
|
||||
char *zErrMsg = 0; /* Error message returned from sqlite3_exec() */
|
||||
const char *zEncoding = 0; /* --utf16be or --utf16le */
|
||||
int nHeap = 0, mnHeap = 0; /* Heap size from --heap */
|
||||
int nLook = 0, szLook = 0; /* --lookaside configuration */
|
||||
int nPCache = 0, szPCache = 0;/* --pcache configuration */
|
||||
int nScratch = 0, szScratch=0;/* --scratch configuration */
|
||||
int pageSize = 0; /* Desired page size. 0 means default */
|
||||
void *pHeap = 0; /* Allocated heap space */
|
||||
void *pLook = 0; /* Allocated lookaside space */
|
||||
void *pPCache = 0; /* Allocated storage for pcache */
|
||||
void *pScratch = 0; /* Allocated storage for scratch */
|
||||
int doAutovac = 0; /* True for --autovacuum */
|
||||
char *zSql; /* SQL to run */
|
||||
char *zToFree = 0; /* Call sqlite3_free() on this afte running zSql */
|
||||
int verboseFlag = 0; /* --verbose or -v flag */
|
||||
int quietFlag = 0; /* --quiet or -q flag */
|
||||
int nTest = 0; /* Number of test cases run */
|
||||
int multiTest = 0; /* True if there will be multiple test cases */
|
||||
int lastPct = -1; /* Previous percentage done output */
|
||||
sqlite3 *dataDb = 0; /* Database holding compacted input data */
|
||||
sqlite3_stmt *pStmt = 0; /* Statement to insert testcase into dataDb */
|
||||
const char *zDataOut = 0; /* Write compacted data to this output file */
|
||||
int nHeader = 0; /* Bytes of header comment text on input file */
|
||||
int oomFlag = 0; /* --oom */
|
||||
int oomCnt = 0; /* Counter for the OOM loop */
|
||||
char zErrBuf[200]; /* Space for the error message */
|
||||
const char *zFailCode; /* Value of the TEST_FAILURE environment var */
|
||||
const char *zPrompt; /* Initial prompt when large-file fuzzing */
|
||||
int nInFile = 0; /* Number of input files to read */
|
||||
char **azInFile = 0; /* Array of input file names */
|
||||
int jj; /* Loop counter for azInFile[] */
|
||||
sqlite3_int64 iStart, iEnd; /* Start and end-times for a test case */
|
||||
|
||||
|
||||
zFailCode = getenv("TEST_FAILURE");
|
||||
g.zArgv0 = argv[0];
|
||||
zPrompt = "<stdin>";
|
||||
for(i=1; i<argc; i++){
|
||||
const char *z = argv[i];
|
||||
if( z[0]=='-' ){
|
||||
z++;
|
||||
if( z[0]=='-' ) z++;
|
||||
if( strcmp(z,"autovacuum")==0 ){
|
||||
doAutovac = 1;
|
||||
}else
|
||||
if( strcmp(z, "f")==0 && i+1<argc ){
|
||||
i++;
|
||||
goto addNewInFile;
|
||||
}else
|
||||
if( strcmp(z,"heap")==0 ){
|
||||
if( i>=argc-2 ) abendError("missing arguments on %s\n", argv[i]);
|
||||
nHeap = integerValue(argv[i+1]);
|
||||
mnHeap = integerValue(argv[i+2]);
|
||||
i += 2;
|
||||
}else
|
||||
if( strcmp(z,"help")==0 ){
|
||||
showHelp();
|
||||
return 0;
|
||||
}else
|
||||
if( strcmp(z,"lookaside")==0 ){
|
||||
if( i>=argc-2 ) abendError("missing arguments on %s", argv[i]);
|
||||
nLook = integerValue(argv[i+1]);
|
||||
szLook = integerValue(argv[i+2]);
|
||||
i += 2;
|
||||
}else
|
||||
if( strcmp(z,"oom")==0 ){
|
||||
oomFlag = 1;
|
||||
}else
|
||||
if( strcmp(z,"pagesize")==0 ){
|
||||
if( i>=argc-1 ) abendError("missing argument on %s", argv[i]);
|
||||
pageSize = integerValue(argv[++i]);
|
||||
}else
|
||||
if( strcmp(z,"pcache")==0 ){
|
||||
if( i>=argc-2 ) abendError("missing arguments on %s", argv[i]);
|
||||
nPCache = integerValue(argv[i+1]);
|
||||
szPCache = integerValue(argv[i+2]);
|
||||
i += 2;
|
||||
}else
|
||||
if( strcmp(z,"quiet")==0 || strcmp(z,"q")==0 ){
|
||||
quietFlag = 1;
|
||||
verboseFlag = 0;
|
||||
}else
|
||||
if( strcmp(z,"scratch")==0 ){
|
||||
if( i>=argc-2 ) abendError("missing arguments on %s", argv[i]);
|
||||
nScratch = integerValue(argv[i+1]);
|
||||
szScratch = integerValue(argv[i+2]);
|
||||
i += 2;
|
||||
}else
|
||||
if( strcmp(z, "unique-cases")==0 ){
|
||||
if( i>=argc-1 ) abendError("missing arguments on %s", argv[i]);
|
||||
if( zDataOut ) abendError("only one --minimize allowed");
|
||||
zDataOut = argv[++i];
|
||||
}else
|
||||
if( strcmp(z,"utf16le")==0 ){
|
||||
zEncoding = "utf16le";
|
||||
}else
|
||||
if( strcmp(z,"utf16be")==0 ){
|
||||
zEncoding = "utf16be";
|
||||
}else
|
||||
if( strcmp(z,"verbose")==0 || strcmp(z,"v")==0 ){
|
||||
quietFlag = 0;
|
||||
verboseFlag = 1;
|
||||
}else
|
||||
{
|
||||
abendError("unknown option: %s", argv[i]);
|
||||
}
|
||||
}else{
|
||||
addNewInFile:
|
||||
nInFile++;
|
||||
azInFile = realloc(azInFile, sizeof(azInFile[0])*nInFile);
|
||||
if( azInFile==0 ) abendError("out of memory");
|
||||
azInFile[nInFile-1] = argv[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Do global SQLite initialization */
|
||||
sqlite3_config(SQLITE_CONFIG_LOG, verboseFlag ? shellLog : shellLogNoop, 0);
|
||||
if( nHeap>0 ){
|
||||
pHeap = malloc( nHeap );
|
||||
if( pHeap==0 ) fatalError("cannot allocate %d-byte heap\n", nHeap);
|
||||
rc = sqlite3_config(SQLITE_CONFIG_HEAP, pHeap, nHeap, mnHeap);
|
||||
if( rc ) abendError("heap configuration failed: %d\n", rc);
|
||||
}
|
||||
if( oomFlag ){
|
||||
sqlite3_config(SQLITE_CONFIG_GETMALLOC, &g.sOrigMem);
|
||||
g.sOomMem = g.sOrigMem;
|
||||
g.sOomMem.xMalloc = oomMalloc;
|
||||
g.sOomMem.xRealloc = oomRealloc;
|
||||
sqlite3_config(SQLITE_CONFIG_MALLOC, &g.sOomMem);
|
||||
}
|
||||
if( nLook>0 ){
|
||||
sqlite3_config(SQLITE_CONFIG_LOOKASIDE, 0, 0);
|
||||
if( szLook>0 ){
|
||||
pLook = malloc( nLook*szLook );
|
||||
if( pLook==0 ) fatalError("out of memory");
|
||||
}
|
||||
}
|
||||
if( nScratch>0 && szScratch>0 ){
|
||||
pScratch = malloc( nScratch*(sqlite3_int64)szScratch );
|
||||
if( pScratch==0 ) fatalError("cannot allocate %lld-byte scratch",
|
||||
nScratch*(sqlite3_int64)szScratch);
|
||||
rc = sqlite3_config(SQLITE_CONFIG_SCRATCH, pScratch, szScratch, nScratch);
|
||||
if( rc ) abendError("scratch configuration failed: %d\n", rc);
|
||||
}
|
||||
if( nPCache>0 && szPCache>0 ){
|
||||
pPCache = malloc( nPCache*(sqlite3_int64)szPCache );
|
||||
if( pPCache==0 ) fatalError("cannot allocate %lld-byte pcache",
|
||||
nPCache*(sqlite3_int64)szPCache);
|
||||
rc = sqlite3_config(SQLITE_CONFIG_PAGECACHE, pPCache, szPCache, nPCache);
|
||||
if( rc ) abendError("pcache configuration failed: %d", rc);
|
||||
}
|
||||
|
||||
/* If the --unique-cases option was supplied, open the database that will
|
||||
** be used to gather unique test cases.
|
||||
*/
|
||||
if( zDataOut ){
|
||||
rc = sqlite3_open(":memory:", &dataDb);
|
||||
if( rc ) abendError("cannot open :memory: database");
|
||||
rc = sqlite3_exec(dataDb,
|
||||
"CREATE TABLE testcase(sql BLOB PRIMARY KEY, tm) WITHOUT ROWID;",0,0,0);
|
||||
if( rc ) abendError("%s", sqlite3_errmsg(dataDb));
|
||||
rc = sqlite3_prepare_v2(dataDb,
|
||||
"INSERT OR IGNORE INTO testcase(sql,tm)VALUES(?1,?2)",
|
||||
-1, &pStmt, 0);
|
||||
if( rc ) abendError("%s", sqlite3_errmsg(dataDb));
|
||||
}
|
||||
|
||||
/* Initialize the input buffer used to hold SQL text */
|
||||
if( nInFile==0 ) nInFile = 1;
|
||||
nAlloc = 1000;
|
||||
zIn = malloc(nAlloc);
|
||||
if( zIn==0 ) fatalError("out of memory");
|
||||
|
||||
/* Loop over all input files */
|
||||
for(jj=0; jj<nInFile; jj++){
|
||||
|
||||
/* Read the complete content of the next input file into zIn[] */
|
||||
FILE *in;
|
||||
if( azInFile ){
|
||||
int j, k;
|
||||
in = fopen(azInFile[jj],"rb");
|
||||
if( in==0 ){
|
||||
abendError("cannot open %s for reading", azInFile[jj]);
|
||||
}
|
||||
zPrompt = azInFile[jj];
|
||||
for(j=k=0; zPrompt[j]; j++) if( zPrompt[j]=='/' ) k = j+1;
|
||||
zPrompt += k;
|
||||
}else{
|
||||
in = stdin;
|
||||
zPrompt = "<stdin>";
|
||||
}
|
||||
while( !feof(in) ){
|
||||
zIn = realloc(zIn, nAlloc);
|
||||
if( zIn==0 ) fatalError("out of memory");
|
||||
got = fread(zIn+nIn, 1, nAlloc-nIn-1, in);
|
||||
nIn += (int)got;
|
||||
zIn[nIn] = 0;
|
||||
if( got==0 ) break;
|
||||
nAlloc += nAlloc+1000;
|
||||
}
|
||||
if( in!=stdin ) fclose(in);
|
||||
lastPct = -1;
|
||||
|
||||
/* Skip initial lines of the input file that begin with "#" */
|
||||
for(i=0; i<nIn; i=iNext+1){
|
||||
if( zIn[i]!='#' ) break;
|
||||
for(iNext=i+1; iNext<nIn && zIn[iNext]!='\n'; iNext++){}
|
||||
}
|
||||
nHeader = i;
|
||||
|
||||
/* Process all test cases contained within the input file.
|
||||
*/
|
||||
for(; i<nIn; i=iNext, nTest++, g.zTestName[0]=0){
|
||||
char cSaved;
|
||||
if( strncmp(&zIn[i], "/****<",6)==0 ){
|
||||
char *z = strstr(&zIn[i], ">****/");
|
||||
if( z ){
|
||||
z += 6;
|
||||
sqlite3_snprintf(sizeof(g.zTestName), g.zTestName, "%.*s",
|
||||
(int)(z-&zIn[i]) - 12, &zIn[i+6]);
|
||||
if( verboseFlag ){
|
||||
printf("%.*s\n", (int)(z-&zIn[i]), &zIn[i]);
|
||||
fflush(stdout);
|
||||
}
|
||||
i += (int)(z-&zIn[i]);
|
||||
multiTest = 1;
|
||||
}
|
||||
}
|
||||
for(iNext=i; iNext<nIn && strncmp(&zIn[iNext],"/****<",6)!=0; iNext++){}
|
||||
cSaved = zIn[iNext];
|
||||
zIn[iNext] = 0;
|
||||
|
||||
|
||||
/* Print out the SQL of the next test case is --verbose is enabled
|
||||
*/
|
||||
zSql = &zIn[i];
|
||||
if( verboseFlag ){
|
||||
printf("INPUT (offset: %d, size: %d): [%s]\n",
|
||||
i, (int)strlen(&zIn[i]), &zIn[i]);
|
||||
}else if( multiTest && !quietFlag ){
|
||||
if( oomFlag ){
|
||||
printf("%s\n", g.zTestName);
|
||||
}else{
|
||||
int pct = (10*iNext)/nIn;
|
||||
if( pct!=lastPct ){
|
||||
if( lastPct<0 ) printf("%s:", zPrompt);
|
||||
printf(" %d%%", pct*10);
|
||||
lastPct = pct;
|
||||
}
|
||||
}
|
||||
}
|
||||
fflush(stdout);
|
||||
|
||||
/* Run the next test case. Run it multiple times in --oom mode
|
||||
*/
|
||||
if( oomFlag ){
|
||||
oomCnt = g.iOomCntdown = 1;
|
||||
g.nOomFault = 0;
|
||||
g.bOomOnce = 1;
|
||||
if( verboseFlag ){
|
||||
printf("Once.%d\n", oomCnt);
|
||||
fflush(stdout);
|
||||
}
|
||||
}else{
|
||||
oomCnt = 0;
|
||||
}
|
||||
do{
|
||||
rc = sqlite3_open_v2(
|
||||
"main.db", &db,
|
||||
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY,
|
||||
0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
abendError("Unable to open the in-memory database");
|
||||
}
|
||||
if( pLook ){
|
||||
rc = sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE,pLook,szLook,nLook);
|
||||
if( rc!=SQLITE_OK ) abendError("lookaside configuration filed: %d", rc);
|
||||
}
|
||||
#ifndef SQLITE_OMIT_TRACE
|
||||
sqlite3_trace(db, verboseFlag ? traceCallback : traceNoop, 0);
|
||||
#endif
|
||||
sqlite3_create_function(db, "eval", 1, SQLITE_UTF8, 0, sqlEvalFunc, 0, 0);
|
||||
sqlite3_create_function(db, "eval", 2, SQLITE_UTF8, 0, sqlEvalFunc, 0, 0);
|
||||
sqlite3_limit(db, SQLITE_LIMIT_LENGTH, 1000000);
|
||||
if( zEncoding ) sqlexec(db, "PRAGMA encoding=%s", zEncoding);
|
||||
if( pageSize ) sqlexec(db, "PRAGMA pagesize=%d", pageSize);
|
||||
if( doAutovac ) sqlexec(db, "PRAGMA auto_vacuum=FULL");
|
||||
iStart = timeOfDay();
|
||||
g.bOomEnable = 1;
|
||||
if( verboseFlag ){
|
||||
zErrMsg = 0;
|
||||
rc = sqlite3_exec(db, zSql, execCallback, 0, &zErrMsg);
|
||||
if( zErrMsg ){
|
||||
sqlite3_snprintf(sizeof(zErrBuf),zErrBuf,"%z", zErrMsg);
|
||||
zErrMsg = 0;
|
||||
}
|
||||
}else {
|
||||
rc = sqlite3_exec(db, zSql, execNoop, 0, 0);
|
||||
}
|
||||
g.bOomEnable = 0;
|
||||
iEnd = timeOfDay();
|
||||
rc = sqlite3_close(db);
|
||||
if( rc ){
|
||||
abendError("sqlite3_close() failed with rc=%d", rc);
|
||||
}
|
||||
if( !zDataOut && sqlite3_memory_used()>0 ){
|
||||
abendError("memory in use after close: %lld bytes",sqlite3_memory_used());
|
||||
}
|
||||
if( oomFlag ){
|
||||
/* Limit the number of iterations of the OOM loop to OOM_MAX. If the
|
||||
** first pass (single failure) exceeds 2/3rds of OOM_MAX this skip the
|
||||
** second pass (continuous failure after first) completely. */
|
||||
if( g.nOomFault==0 || oomCnt>OOM_MAX ){
|
||||
if( g.bOomOnce && oomCnt<=(OOM_MAX*2/3) ){
|
||||
oomCnt = g.iOomCntdown = 1;
|
||||
g.bOomOnce = 0;
|
||||
}else{
|
||||
oomCnt = 0;
|
||||
}
|
||||
}else{
|
||||
g.iOomCntdown = ++oomCnt;
|
||||
g.nOomFault = 0;
|
||||
}
|
||||
if( oomCnt ){
|
||||
if( verboseFlag ){
|
||||
printf("%s.%d\n", g.bOomOnce ? "Once" : "Multi", oomCnt);
|
||||
fflush(stdout);
|
||||
}
|
||||
nTest++;
|
||||
}
|
||||
}
|
||||
}while( oomCnt>0 );
|
||||
|
||||
/* Store unique test cases in the in the dataDb database if the
|
||||
** --unique-cases flag is present
|
||||
*/
|
||||
if( zDataOut ){
|
||||
sqlite3_bind_blob(pStmt, 1, &zIn[i], iNext-i, SQLITE_STATIC);
|
||||
sqlite3_bind_int64(pStmt, 2, iEnd - iStart);
|
||||
rc = sqlite3_step(pStmt);
|
||||
if( rc!=SQLITE_DONE ) abendError("%s", sqlite3_errmsg(dataDb));
|
||||
sqlite3_reset(pStmt);
|
||||
}
|
||||
|
||||
/* Free the SQL from the current test case
|
||||
*/
|
||||
if( zToFree ){
|
||||
sqlite3_free(zToFree);
|
||||
zToFree = 0;
|
||||
}
|
||||
zIn[iNext] = cSaved;
|
||||
|
||||
/* Show test-case results in --verbose mode
|
||||
*/
|
||||
if( verboseFlag ){
|
||||
printf("RESULT-CODE: %d\n", rc);
|
||||
if( zErrMsg ){
|
||||
printf("ERROR-MSG: [%s]\n", zErrBuf);
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
/* Simulate an error if the TEST_FAILURE environment variable is "5".
|
||||
** This is used to verify that automated test script really do spot
|
||||
** errors that occur in this test program.
|
||||
*/
|
||||
if( zFailCode ){
|
||||
if( zFailCode[0]=='5' && zFailCode[1]==0 ){
|
||||
abendError("simulated failure");
|
||||
}else if( zFailCode[0]!=0 ){
|
||||
/* If TEST_FAILURE is something other than 5, just exit the test
|
||||
** early */
|
||||
printf("\nExit early due to TEST_FAILURE being set");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( !verboseFlag && multiTest && !quietFlag && !oomFlag ) printf("\n");
|
||||
}
|
||||
|
||||
/* Report total number of tests run
|
||||
*/
|
||||
if( nTest>1 && !quietFlag ){
|
||||
printf("%s: 0 errors out of %d tests\nSQLite %s %s\n",
|
||||
g.zArgv0, nTest, sqlite3_libversion(), sqlite3_sourceid());
|
||||
}
|
||||
|
||||
/* Write the unique test cases if the --unique-cases flag was used
|
||||
*/
|
||||
if( zDataOut ){
|
||||
int n = 0;
|
||||
FILE *out = fopen(zDataOut, "wb");
|
||||
if( out==0 ) abendError("cannot open %s for writing", zDataOut);
|
||||
if( nHeader>0 ) fwrite(zIn, nHeader, 1, out);
|
||||
sqlite3_finalize(pStmt);
|
||||
rc = sqlite3_prepare_v2(dataDb, "SELECT sql, tm FROM testcase ORDER BY tm, sql",
|
||||
-1, &pStmt, 0);
|
||||
if( rc ) abendError("%s", sqlite3_errmsg(dataDb));
|
||||
while( sqlite3_step(pStmt)==SQLITE_ROW ){
|
||||
fprintf(out,"/****<%d:%dms>****/", ++n, sqlite3_column_int(pStmt,1));
|
||||
fwrite(sqlite3_column_blob(pStmt,0),sqlite3_column_bytes(pStmt,0),1,out);
|
||||
}
|
||||
fclose(out);
|
||||
sqlite3_finalize(pStmt);
|
||||
sqlite3_close(dataDb);
|
||||
}
|
||||
|
||||
/* Clean up and exit.
|
||||
*/
|
||||
free(azInFile);
|
||||
free(zIn);
|
||||
free(pHeap);
|
||||
free(pLook);
|
||||
free(pScratch);
|
||||
free(pPCache);
|
||||
return 0;
|
||||
}
|
||||
+35
-37
@@ -1114,7 +1114,6 @@ void FindActions(struct lemon *lemp)
|
||||
/* Resolve conflicts */
|
||||
for(i=0; i<lemp->nstate; i++){
|
||||
struct action *ap, *nap;
|
||||
struct state *stp;
|
||||
stp = lemp->sorted[i];
|
||||
/* assert( stp->ap ); */
|
||||
stp->ap = Action_sort(stp->ap);
|
||||
@@ -3748,9 +3747,9 @@ void ReportTable(
|
||||
/* Generate the include code, if any */
|
||||
tplt_print(out,lemp,lemp->include,&lineno);
|
||||
if( mhflag ){
|
||||
char *name = file_makename(lemp, ".h");
|
||||
fprintf(out,"#include \"%s\"\n", name); lineno++;
|
||||
free(name);
|
||||
char *incName = file_makename(lemp, ".h");
|
||||
fprintf(out,"#include \"%s\"\n", incName); lineno++;
|
||||
free(incName);
|
||||
}
|
||||
tplt_xfer(lemp->name,in,out,&lineno);
|
||||
|
||||
@@ -3791,7 +3790,6 @@ void ReportTable(
|
||||
}
|
||||
name = lemp->name ? lemp->name : "Parse";
|
||||
if( lemp->arg && lemp->arg[0] ){
|
||||
int i;
|
||||
i = lemonStrlen(lemp->arg);
|
||||
while( i>=1 && isspace(lemp->arg[i-1]) ) i--;
|
||||
while( i>=1 && (isalnum(lemp->arg[i-1]) || lemp->arg[i-1]=='_') ) i--;
|
||||
@@ -4479,18 +4477,18 @@ int Strsafe_insert(const char *data)
|
||||
}
|
||||
if( x1a->count>=x1a->size ){
|
||||
/* Need to make the hash table bigger */
|
||||
int i,size;
|
||||
int i,arrSize;
|
||||
struct s_x1 array;
|
||||
array.size = size = x1a->size*2;
|
||||
array.size = arrSize = x1a->size*2;
|
||||
array.count = x1a->count;
|
||||
array.tbl = (x1node*)calloc(size, sizeof(x1node) + sizeof(x1node*));
|
||||
array.tbl = (x1node*)calloc(arrSize, sizeof(x1node) + sizeof(x1node*));
|
||||
if( array.tbl==0 ) return 0; /* Fail due to malloc failure */
|
||||
array.ht = (x1node**)&(array.tbl[size]);
|
||||
for(i=0; i<size; i++) array.ht[i] = 0;
|
||||
array.ht = (x1node**)&(array.tbl[arrSize]);
|
||||
for(i=0; i<arrSize; i++) array.ht[i] = 0;
|
||||
for(i=0; i<x1a->count; i++){
|
||||
x1node *oldnp, *newnp;
|
||||
oldnp = &(x1a->tbl[i]);
|
||||
h = strhash(oldnp->data) & (size-1);
|
||||
h = strhash(oldnp->data) & (arrSize-1);
|
||||
newnp = &(array.tbl[i]);
|
||||
if( array.ht[h] ) array.ht[h]->from = &(newnp->next);
|
||||
newnp->next = array.ht[h];
|
||||
@@ -4646,18 +4644,18 @@ int Symbol_insert(struct symbol *data, const char *key)
|
||||
}
|
||||
if( x2a->count>=x2a->size ){
|
||||
/* Need to make the hash table bigger */
|
||||
int i,size;
|
||||
int i,arrSize;
|
||||
struct s_x2 array;
|
||||
array.size = size = x2a->size*2;
|
||||
array.size = arrSize = x2a->size*2;
|
||||
array.count = x2a->count;
|
||||
array.tbl = (x2node*)calloc(size, sizeof(x2node) + sizeof(x2node*));
|
||||
array.tbl = (x2node*)calloc(arrSize, sizeof(x2node) + sizeof(x2node*));
|
||||
if( array.tbl==0 ) return 0; /* Fail due to malloc failure */
|
||||
array.ht = (x2node**)&(array.tbl[size]);
|
||||
for(i=0; i<size; i++) array.ht[i] = 0;
|
||||
array.ht = (x2node**)&(array.tbl[arrSize]);
|
||||
for(i=0; i<arrSize; i++) array.ht[i] = 0;
|
||||
for(i=0; i<x2a->count; i++){
|
||||
x2node *oldnp, *newnp;
|
||||
oldnp = &(x2a->tbl[i]);
|
||||
h = strhash(oldnp->key) & (size-1);
|
||||
h = strhash(oldnp->key) & (arrSize-1);
|
||||
newnp = &(array.tbl[i]);
|
||||
if( array.ht[h] ) array.ht[h]->from = &(newnp->next);
|
||||
newnp->next = array.ht[h];
|
||||
@@ -4722,12 +4720,12 @@ int Symbol_count()
|
||||
struct symbol **Symbol_arrayof()
|
||||
{
|
||||
struct symbol **array;
|
||||
int i,size;
|
||||
int i,arrSize;
|
||||
if( x2a==0 ) return 0;
|
||||
size = x2a->count;
|
||||
array = (struct symbol **)calloc(size, sizeof(struct symbol *));
|
||||
arrSize = x2a->count;
|
||||
array = (struct symbol **)calloc(arrSize, sizeof(struct symbol *));
|
||||
if( array ){
|
||||
for(i=0; i<size; i++) array[i] = x2a->tbl[i].data;
|
||||
for(i=0; i<arrSize; i++) array[i] = x2a->tbl[i].data;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
@@ -4843,18 +4841,18 @@ int State_insert(struct state *data, struct config *key)
|
||||
}
|
||||
if( x3a->count>=x3a->size ){
|
||||
/* Need to make the hash table bigger */
|
||||
int i,size;
|
||||
int i,arrSize;
|
||||
struct s_x3 array;
|
||||
array.size = size = x3a->size*2;
|
||||
array.size = arrSize = x3a->size*2;
|
||||
array.count = x3a->count;
|
||||
array.tbl = (x3node*)calloc(size, sizeof(x3node) + sizeof(x3node*));
|
||||
array.tbl = (x3node*)calloc(arrSize, sizeof(x3node) + sizeof(x3node*));
|
||||
if( array.tbl==0 ) return 0; /* Fail due to malloc failure */
|
||||
array.ht = (x3node**)&(array.tbl[size]);
|
||||
for(i=0; i<size; i++) array.ht[i] = 0;
|
||||
array.ht = (x3node**)&(array.tbl[arrSize]);
|
||||
for(i=0; i<arrSize; i++) array.ht[i] = 0;
|
||||
for(i=0; i<x3a->count; i++){
|
||||
x3node *oldnp, *newnp;
|
||||
oldnp = &(x3a->tbl[i]);
|
||||
h = statehash(oldnp->key) & (size-1);
|
||||
h = statehash(oldnp->key) & (arrSize-1);
|
||||
newnp = &(array.tbl[i]);
|
||||
if( array.ht[h] ) array.ht[h]->from = &(newnp->next);
|
||||
newnp->next = array.ht[h];
|
||||
@@ -4901,12 +4899,12 @@ struct state *State_find(struct config *key)
|
||||
struct state **State_arrayof()
|
||||
{
|
||||
struct state **array;
|
||||
int i,size;
|
||||
int i,arrSize;
|
||||
if( x3a==0 ) return 0;
|
||||
size = x3a->count;
|
||||
array = (struct state **)calloc(size, sizeof(struct state *));
|
||||
arrSize = x3a->count;
|
||||
array = (struct state **)calloc(arrSize, sizeof(struct state *));
|
||||
if( array ){
|
||||
for(i=0; i<size; i++) array[i] = x3a->tbl[i].data;
|
||||
for(i=0; i<arrSize; i++) array[i] = x3a->tbl[i].data;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
@@ -4983,18 +4981,18 @@ int Configtable_insert(struct config *data)
|
||||
}
|
||||
if( x4a->count>=x4a->size ){
|
||||
/* Need to make the hash table bigger */
|
||||
int i,size;
|
||||
int i,arrSize;
|
||||
struct s_x4 array;
|
||||
array.size = size = x4a->size*2;
|
||||
array.size = arrSize = x4a->size*2;
|
||||
array.count = x4a->count;
|
||||
array.tbl = (x4node*)calloc(size, sizeof(x4node) + sizeof(x4node*));
|
||||
array.tbl = (x4node*)calloc(arrSize, sizeof(x4node) + sizeof(x4node*));
|
||||
if( array.tbl==0 ) return 0; /* Fail due to malloc failure */
|
||||
array.ht = (x4node**)&(array.tbl[size]);
|
||||
for(i=0; i<size; i++) array.ht[i] = 0;
|
||||
array.ht = (x4node**)&(array.tbl[arrSize]);
|
||||
for(i=0; i<arrSize; i++) array.ht[i] = 0;
|
||||
for(i=0; i<x4a->count; i++){
|
||||
x4node *oldnp, *newnp;
|
||||
oldnp = &(x4a->tbl[i]);
|
||||
h = confighash(oldnp->data) & (size-1);
|
||||
h = confighash(oldnp->data) & (arrSize-1);
|
||||
newnp = &(array.tbl[i]);
|
||||
if( array.ht[h] ) array.ht[h]->from = &(newnp->next);
|
||||
newnp->next = array.ht[h];
|
||||
|
||||
+47
-5
@@ -174,6 +174,9 @@ proc writeFile { fileName data } {
|
||||
return ""
|
||||
}
|
||||
|
||||
#
|
||||
# TODO: Modify this procedure when a new version of Visual Studio is released.
|
||||
#
|
||||
proc getMinVsVersionXmlChunk { vsVersion } {
|
||||
switch -exact $vsVersion {
|
||||
2012 {
|
||||
@@ -184,17 +187,26 @@ proc getMinVsVersionXmlChunk { vsVersion } {
|
||||
return [appendArgs \
|
||||
"\r\n " {MinVSVersion="12.0"}]
|
||||
}
|
||||
2015 {
|
||||
return [appendArgs \
|
||||
"\r\n " {MinVSVersion="14.0"}]
|
||||
}
|
||||
default {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# TODO: Modify this procedure when a new version of Visual Studio is released.
|
||||
#
|
||||
proc getMaxPlatformVersionXmlChunk { packageFlavor vsVersion } {
|
||||
#
|
||||
# NOTE: Only Visual Studio 2013 supports this SDK manifest attribute.
|
||||
# NOTE: Only Visual Studio 2013 and later support this attribute within the
|
||||
# SDK manifest.
|
||||
#
|
||||
if {![string equal $vsVersion 2013]} then {
|
||||
if {![string equal $vsVersion 2013] && \
|
||||
![string equal $vsVersion 2015]} then {
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -221,6 +233,9 @@ proc getMaxPlatformVersionXmlChunk { packageFlavor vsVersion } {
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# TODO: Modify this procedure when a new version of Visual Studio is released.
|
||||
#
|
||||
proc getExtraFileListXmlChunk { packageFlavor vsVersion } {
|
||||
#
|
||||
# NOTE: Windows Phone 8.0 does not require any extra attributes in its VSIX
|
||||
@@ -245,6 +260,14 @@ proc getExtraFileListXmlChunk { packageFlavor vsVersion } {
|
||||
"\r\n " AppliesTo=\" $appliesTo \" \
|
||||
"\r\n " {DependsOn="Microsoft.VCLibs, version=12.0"}]
|
||||
}
|
||||
2015 {
|
||||
#
|
||||
# TODO: Is the ".AppLocal" suffix always needed here?
|
||||
#
|
||||
return [appendArgs \
|
||||
"\r\n " AppliesTo=\" $appliesTo \" \
|
||||
"\r\n " {DependsOn="Microsoft.VCLibs.AppLocal, version=14.0"}]
|
||||
}
|
||||
default {
|
||||
return ""
|
||||
}
|
||||
@@ -354,10 +377,11 @@ if {[string length $vsVersion] == 0} then {
|
||||
fail "invalid Visual Studio version"
|
||||
}
|
||||
|
||||
if {![string equal $vsVersion 2012] && ![string equal $vsVersion 2013]} then {
|
||||
if {![string equal $vsVersion 2012] && ![string equal $vsVersion 2013] && \
|
||||
![string equal $vsVersion 2015]} then {
|
||||
fail [appendArgs \
|
||||
"unsupported Visual Studio version, must be one of: " \
|
||||
[list 2012 2013]]
|
||||
[list 2012 2013 2015]]
|
||||
}
|
||||
|
||||
set shortNames(WinRT,2012) SQLite.WinRT
|
||||
@@ -368,6 +392,7 @@ set shortNames(WP80,2013) SQLite.WP80.2013
|
||||
set shortNames(WP81,2013) SQLite.WP81
|
||||
set shortNames(Win32,2012) SQLite.Win32
|
||||
set shortNames(Win32,2013) SQLite.Win32.2013
|
||||
set shortNames(UAP,2015) SQLite.UAP.2015
|
||||
|
||||
set displayNames(WinRT,2012) "SQLite for Windows Runtime"
|
||||
set displayNames(WinRT,2013) "SQLite for Windows Runtime"
|
||||
@@ -377,6 +402,7 @@ set displayNames(WP80,2013) "SQLite for Windows Phone"
|
||||
set displayNames(WP81,2013) "SQLite for Windows Phone 8.1"
|
||||
set displayNames(Win32,2012) "SQLite for Windows"
|
||||
set displayNames(Win32,2013) "SQLite for Windows"
|
||||
set displayNames(UAP,2015) "SQLite for Universal App Platform"
|
||||
|
||||
if {[string equal $packageFlavor WinRT]} then {
|
||||
set shortName $shortNames($packageFlavor,$vsVersion)
|
||||
@@ -432,6 +458,22 @@ if {[string equal $packageFlavor WinRT]} then {
|
||||
set extraSdkPath "\\..\\$targetPlatformIdentifier"
|
||||
set extraFileListAttributes \
|
||||
[getExtraFileListXmlChunk $packageFlavor $vsVersion]
|
||||
} elseif {[string equal $packageFlavor UAP]} then {
|
||||
if {$vsVersion ne "2015"} then {
|
||||
fail [appendArgs \
|
||||
"unsupported combination, package flavor " $packageFlavor \
|
||||
" is only supported with Visual Studio 2015"]
|
||||
}
|
||||
set shortName $shortNames($packageFlavor,$vsVersion)
|
||||
set displayName $displayNames($packageFlavor,$vsVersion)
|
||||
set targetPlatformIdentifier UAP
|
||||
set targetPlatformVersion v0.8.0.0
|
||||
set minVsVersion [getMinVsVersionXmlChunk $vsVersion]
|
||||
set maxPlatformVersion \
|
||||
[getMaxPlatformVersionXmlChunk $packageFlavor $vsVersion]
|
||||
set extraSdkPath "\\..\\$targetPlatformIdentifier"
|
||||
set extraFileListAttributes \
|
||||
[getExtraFileListXmlChunk $packageFlavor $vsVersion]
|
||||
} elseif {[string equal $packageFlavor Win32]} then {
|
||||
set shortName $shortNames($packageFlavor,$vsVersion)
|
||||
set displayName $displayNames($packageFlavor,$vsVersion)
|
||||
@@ -446,7 +488,7 @@ if {[string equal $packageFlavor WinRT]} then {
|
||||
} else {
|
||||
fail [appendArgs \
|
||||
"unsupported package flavor, must be one of: " \
|
||||
[list WinRT WinRT81 WP80 WP81 Win32]]
|
||||
[list WinRT WinRT81 WP80 WP81 UAP Win32]]
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
|
||||
+8
-3
@@ -10,8 +10,13 @@
|
||||
**
|
||||
*************************************************************************
|
||||
**
|
||||
** This is a utility problem that computes the differences in content
|
||||
** This is a utility program that computes the differences in content
|
||||
** between two SQLite databases.
|
||||
**
|
||||
** To compile, simply link against SQLite.
|
||||
**
|
||||
** See the showHelp() routine below for a brief description of how to
|
||||
** run the utility.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -492,7 +497,7 @@ static void diff_one_table(const char *zTab, FILE *out){
|
||||
char **az2 = 0; /* Columns in aux */
|
||||
int nPk; /* Primary key columns in main */
|
||||
int nPk2; /* Primary key columns in aux */
|
||||
int n; /* Number of columns in main */
|
||||
int n = 0; /* Number of columns in main */
|
||||
int n2; /* Number of columns in aux */
|
||||
int nQ; /* Number of output columns in the diff query */
|
||||
int i; /* Loop counter */
|
||||
@@ -729,7 +734,7 @@ static void summarize_one_table(const char *zTab, FILE *out){
|
||||
char **az2 = 0; /* Columns in aux */
|
||||
int nPk; /* Primary key columns in main */
|
||||
int nPk2; /* Primary key columns in aux */
|
||||
int n; /* Number of columns in main */
|
||||
int n = 0; /* Number of columns in main */
|
||||
int n2; /* Number of columns in aux */
|
||||
int i; /* Loop counter */
|
||||
const char *zSep; /* Separator string */
|
||||
|
||||
Reference in New Issue
Block a user