Compare commits

..

65 Commits

Author SHA1 Message Date
drh 9336a521e8 Prototype for an sqlite3_db_log() interface.
FossilOrigin-Name: 658e20f55467a90bcebe5e01cf9f252dbe8bd690
2015-04-22 14:41:19 +00:00
drh 0ba51089c8 Improved filtering of input for fuzzershell for modes other than generic.
FossilOrigin-Name: 025e8370dde2918b66683f8d7fa9c7d23d03c9b4
2015-04-22 13:16:46 +00:00
drh 3fb2cc1173 Change the printf, strftime, and glob modes of fuzzershell so that they
reject all inputs that do not start with a string literal followed by a
comma.  This helps the fuzzer focus in on the kinds of behavior those modes
are intended to test.

FossilOrigin-Name: 1cceefa7c6585bca786fe9f7118f7beb829ad709
2015-04-22 11:16:34 +00:00
mistachkin 318d38cf7e When compiling for UAP, link against the new minimal MSVC runtime.
FossilOrigin-Name: 2cb945116e7a5b78741b19839899826b539d5868
2015-04-22 01:33:53 +00:00
drh 1cb50c880e Alternative fix for the double-initialization of type and collating sequence
problem that leaves the estimated table size intact.

FossilOrigin-Name: 623ddbdbf48d26dac58c593bcb9e7b184334ddfc
2015-04-21 17:17:47 +00:00
drh dfb5e1cbc6 Make sure the datatype and collating sequence of transients tables are
not initialized more than once.  Otherwise a memory leak results.

FossilOrigin-Name: 9e6beda2c8d879e438ee933e658f860d6eb42a20
2015-04-21 17:07:01 +00:00
dan 464083544e Ensure that tables names are dequoted exactly once by the trigger logic.
FossilOrigin-Name: 9d887b92f8086961e045f8acb9ee7a443796d411
2015-04-21 16:38:49 +00:00
drh be360e1ed1 Fix a memory leak in the SELECT code generator tracing logic (code that is
omitted in non-debugging builds).

FossilOrigin-Name: b623ebd859dcb1d99398aa9953f6b113bad26304
2015-04-21 16:09:07 +00:00
dan 4b79bde7a2 Fix an obscure problem with "INSERT INTO tbl(cols) SELECT" statements where the SELECT is a compound with an ORDER BY and "cols" is a strict subset of tbl's columns.
FossilOrigin-Name: 718d5d0eab045a874107e078a857226a80ab912d
2015-04-21 15:49:04 +00:00
drh 7c052da54d Change an assert() in the aggregate query code generator into a testcase().
FossilOrigin-Name: d1e6bc918b0c8e0701f5e15afb91b84a9004231b
2015-04-21 15:16:48 +00:00
dan 3c9a073723 Fix an fts4 problem to do with the handling of phrases that contain zero tokens.
FossilOrigin-Name: caba5be0b2bdaf4eb4af9af267c0c22dfbd3dba5
2015-04-21 12:06:53 +00:00
drh b6b676ea7c Fix some identifier name de-quoting issues in the foreign key and trigger logic.
FossilOrigin-Name: 59e92bd9521f1e8315a9a7e7fd3d63b0c75eaf0e
2015-04-21 03:13:47 +00:00
drh 60f4e0918d Test case for the previous check-in.
FossilOrigin-Name: a526f58bc96c0fdead51b6bd9aafea7b48bf398e
2015-04-21 02:17:30 +00:00
drh 0f517ea8d4 Make sure the whereSplit() routine in the query planner is not confused
by the likely() operator.

FossilOrigin-Name: 588db14ffb4b0e8e76d511b7b1541db3ec78836a
2015-04-21 02:12:13 +00:00
mistachkin 76f6a130a9 Enable compilation and VSIX package creation with the Visual Studio 2015 CTP.
FossilOrigin-Name: 03b725a768290e3c7b31f1ba3310532fd7dc05cd
2015-04-21 00:23:38 +00:00
drh 9985dabbac Add the --mode option to fuzzershell.
FossilOrigin-Name: b940b0fa6cf68fef58344d269ad5d39468ffe72f
2015-04-20 22:36:49 +00:00
drh 4a74d076e3 Many new configuration options for fuzzershell.
FossilOrigin-Name: 41c954391690833bf2ece4ea14457ee4bdd74e90
2015-04-20 18:58:38 +00:00
dan 4eed05347c Fix a memory leak caused by duplicate entries in the sqlite_stat1 table.
FossilOrigin-Name: 2f58c8c9722fffc486610f9e6b08178d53a56b64
2015-04-20 15:13:08 +00:00
drh cef2584335 Fix an obscure memory leak in sqlite3Stat4ProbeFree()
FossilOrigin-Name: c72abbe2c1735f3d563c6672616b2918b6209922
2015-04-20 13:59:18 +00:00
drh f34e9aabd8 Enhance fuzzershell to support multiple blocks of SQL, each run in its own
private in-memory database.

FossilOrigin-Name: ab0a96ca73cfe92d5a837c71c148e8361f42acc3
2015-04-20 12:50:13 +00:00
drh b496a8f547 Add an ALWAYS() around a new branch that was made unreachable by an even
newer change.

FossilOrigin-Name: 592c010478fba7410424f011a62e019c826f1ac3
2015-04-20 01:13:33 +00:00
mistachkin 19b887e4ec Fix another harmless compiler warning.
FossilOrigin-Name: 5ae853aaebaee76c9265061984185f74c10c4c8b
2015-04-19 23:48:10 +00:00
mistachkin 0311b622c4 Merge updates from trunk.
FossilOrigin-Name: 59d1a3bb6050a812c4eb0d25ac53327081b9efed
2015-04-19 23:40:55 +00:00
mistachkin f659cf48e8 Modify the 'mkvsix' tool itself to support the Visual Studio 2015 CTP.
FossilOrigin-Name: e0b7a191f3c22d9eacf645c58be59e0fdcb8860d
2015-04-19 23:39:05 +00:00
drh 542a176d5e Fix an off-by-one assert() in the virtual table argument tokenizer.
FossilOrigin-Name: c83052e48bbae0f45db2a44155b4e5482ee4a901
2015-04-19 23:11:10 +00:00
drh 992590be1c Fix a broken assert() and comparison for INSERT INTO ... SELECT when the
SELECT uses an unknown collating sequence.

FossilOrigin-Name: e73ac0cbac257d2d2b28e51423e30d7449b6c7b5
2015-04-19 22:41:22 +00:00
drh 7520996965 Silently ignore parser stack overflow when parsing a malformed schema in
PRAGMA writable_schema mode.

FossilOrigin-Name: 2cb37b959c66b5ae3535ab81ba14a4ebf9732df7
2015-04-19 22:31:45 +00:00
drh 5f1d2fa4d2 Fix another assert() that is not true if the database schema is corrupt.
FossilOrigin-Name: bc97cec6338b16a4e9b1a9457d01bb7fe462934d
2015-04-19 21:59:19 +00:00
mistachkin 8e18922f12 Fix harmless compiler warnings seen with MSVC 2015.
FossilOrigin-Name: d05becd873a03a366843a34e7f4c732dd8f88c86
2015-04-19 21:43:16 +00:00
drh 33c59ecafb Fix a faulty assert in the schema parsing logic.
FossilOrigin-Name: b1ed949584a2526c04952b98c3aa283427f45e10
2015-04-19 20:39:17 +00:00
mistachkin 1c89a7710e Document the NMAKE_ARGS environment variable as well.
FossilOrigin-Name: 977fd39c1509edec2e28cc8bac64e0994699f398
2015-04-19 19:53:43 +00:00
drh d0c7305313 Fix a potential NULL pointer deference on a corrupt database schema.
FossilOrigin-Name: dc61b292d8eaf422ca8a2b18f1caccef1a5389fd
2015-04-19 19:21:19 +00:00
mistachkin 88eb7fa328 Improve documentation and comments in the MSVC batch build tool.
FossilOrigin-Name: ca64ef079811006f3e0526919871ffd286c3e714
2015-04-19 18:58:29 +00:00
drh a21f78b93f Bring comments on the INSERT code generator up-to-date. Fix the INSERT code
generator so that it correctly handles inserts from a SELECT into a virtual
table with non-terminal hidden columns.

FossilOrigin-Name: 4ac81fac6c6302c042be3df493a41630b733fff0
2015-04-19 18:32:43 +00:00
mistachkin 6bbe3dfaf2 Work in progress on making VSIX packages for the Visual Studio 2015 CTP.
FossilOrigin-Name: 8469d651a0442a2bc572a869a0457a6ea8c06bc7
2015-04-19 06:18:10 +00:00
drh 816070cf5c The sqlite3_trace() callback does not try to expand parameters in statements
that have no parameter.

FossilOrigin-Name: 917e3c36293a1bf052a16116c93e5037ed712f96
2015-04-18 19:20:14 +00:00
drh 7088d50109 Fix an incorrect assert() statement in the CREATE INDEX code generator.
FossilOrigin-Name: 2eed41fda068f2cbac55e63d7c1875ddaa331508
2015-04-18 17:43:29 +00:00
dan ea8562edce Ensure that if a "ROLLBACK TO" statement is used to rollback (but not close) theoutermost transaction, the xRollbackTo() method of any virtual tables involved in the transaction is invoked.
FossilOrigin-Name: e98d481d84ef31b6ed154f14deae9b261f722616
2015-04-18 16:25:54 +00:00
drh 935f2e7074 Disregard leading zeros when converting strings to 32-bit integers.
FossilOrigin-Name: 691cc201e135a01c4cc4057be7e5d99285ab392d
2015-04-18 04:45:00 +00:00
drh c982844097 Fix an incorrect assert() in the sqlite3_trace() logic.
FossilOrigin-Name: eabde33997b5b2ffc0067930305d6fed5951a234
2015-04-18 00:22:17 +00:00
dan 1586699cfc Fix a problem affecting some fts3 UPDATE and DELETE statements on order=DESC tables.
FossilOrigin-Name: 284c1623f81704ef80edb9324954525cb2b72172
2015-04-17 20:51:55 +00:00
drh 7693c42f1a In the expression-tree comparison routine, do not compiler Expr.iColumn
and Expr.iTable for TK_STRING expressions.

FossilOrigin-Name: b67bb16c72c3e015ea82665ada9b5d3289ef6fb2
2015-04-17 19:41:37 +00:00
drh 7b4da150da Always resolve symbols in all ORDER BY clauses of a compound-SELECT, even
illegal ORDER BY clauses.

FossilOrigin-Name: 6c39ef73d5899eabdb46db50c2b00c2d8381a41a
2015-04-17 18:52:37 +00:00
drh 97ab32bcd3 Remove unnecessary parser error count increments. Let the sqlite3ErrorMsg()
take care of doing that.

FossilOrigin-Name: 3f3b0f683af2fbee83811536f6bef770ff919385
2015-04-17 18:22:53 +00:00
drh c50c8f4043 Remove an ALWAYS() that turns out to be false when there is a semantic
error on a compound SELECT.

FossilOrigin-Name: ad67a67c03078a2bc65d28f2b880b29bf02067c1
2015-04-17 16:12:03 +00:00
drh d99d28361e Ensure that semantic SQL errors are always reported back up to the syntax
parser.  Also:  Improve the defense against invalid PRAGMA synchronous settings.

FossilOrigin-Name: 7aeade9a07f29bf26e50394042ea18d0121fe7a3
2015-04-17 15:58:33 +00:00
drh b8289a8b00 Fix a faulty assert() in sqlite3SelectNew().
FossilOrigin-Name: 620d19c3b462f5c4763ebd26513321431f21dd72
2015-04-17 15:16:58 +00:00
drh 268e72f936 Add the tool/fuzzershell.c utility program.
FossilOrigin-Name: db8d9af4d04ee862995ffa13ae6dcd9a1fc72855
2015-04-17 14:30:49 +00:00
drh 50be9c4b28 Fix the header comment on the sqldiff utility program. No code changes.
FossilOrigin-Name: b355ca3a3f617cd6d4c45c8e27ecd75d9e68b792
2015-04-17 12:16:09 +00:00
drh e318a7f84c Restrict the scope of a local-use function in the parser.
FossilOrigin-Name: cd6598f47480a6189df3e4283231833fd246d7fb
2015-04-16 23:04:17 +00:00
drh a33b68364b Use a heap rather than a bitmap for cell coverage and overlap testing on
btree pages in PRAGMA integrity_check.

FossilOrigin-Name: e94b2ef2242d716379a35dba3d2df1ac512c8d30
2015-04-16 21:57:37 +00:00
drh f3151f0a0d Fix a couple of unreachable branches.
FossilOrigin-Name: 8f391dffcfe068d48f854784648610d8a86f6bc8
2015-04-16 20:27:09 +00:00
drh a4bb7764fe Fix a boundry-value condition in the phrase poslist extractor of FTS3/4.
FossilOrigin-Name: 55d10baf0bffdb1a34bf5627ed8f25e4a4efd942
2015-04-16 20:10:17 +00:00
drh ab4e7f3337 Make sure all cursors are closed when returning from a VDBE subprogram that
implements a foreign-key construct.

FossilOrigin-Name: d04d354d8e423961c3091b6ebcfbbbf10d3ecb04
2015-04-16 18:11:50 +00:00
drh 6dc4148547 Fix the VDBE so that it always uses the original opcode for profiling and
debugging even after the pOp pointer has been updated due to a jump.

FossilOrigin-Name: 647495cf12b656f6a2f028dc1fb459d667153cf2
2015-04-16 17:31:02 +00:00
drh a276e3fd4d Fix a faulty assert() in the compound-SELECT code generator.
FossilOrigin-Name: 10715b05f2201a63dca317f99ce39d3ce182e182
2015-04-16 16:22:27 +00:00
drh 59ac655d02 Silently ignore requests to change the PRAGMA synchronous setting to an
illegal integer value, rather than raising an assertion.

FossilOrigin-Name: e0a88176fcfbed7b554a036948261a332c920053
2015-04-16 16:04:39 +00:00
drh e06874eaa1 Make sure errors in coding triggers are propagated back up to the parser.
FossilOrigin-Name: 928f973ca9adc7933015b2fb6b6fcb8e3154cb9c
2015-04-16 15:47:06 +00:00
drh 9569f60e18 Add the --backslash option to the command-line shell for testing purposes.
FossilOrigin-Name: dd96211e8022365637286b146120cc5db44a9923
2015-04-16 15:05:04 +00:00
drh 6736618a8f Fix a faulty assert() in the compound select code generator.
FossilOrigin-Name: 9d336be1b16aa9bd5c9e4132bb645874993c7d96
2015-04-16 14:33:35 +00:00
drh 772460fd4c Improvements to the way VALUES clauses are parsed.
FossilOrigin-Name: ec5a493ad27593ca78899b3001630c1898b940ff
2015-04-16 14:13:12 +00:00
drh b073771cdf Fix the corruptC.test module due to a change in error message text.
FossilOrigin-Name: 7c0deed25762a954c78d98412d8f4a265a437d06
2015-04-16 12:12:07 +00:00
drh 67731a97a2 Use a heap instead of a bitmap for cell overlap and coverage testing of
btree pages in PRAGMA integrity_check.

FossilOrigin-Name: 5619c959bf7babb19fd8ba8b228be7f090fe0ce3
2015-04-16 11:56:03 +00:00
dan 0d2e2f2b10 Fix a problem in test file e_reindex.test.
FossilOrigin-Name: 5b3de9390f2ffc4c530fd47c71c70e87972cf74b
2015-04-16 08:54:01 +00:00
dan 5b1c07e7fb Ensure the sqlite3Select() routine always returns non-zero if an error has occurred.
FossilOrigin-Name: b51028ed2f57f4245a7ebd9bdb99d1bcfaf1a01b
2015-04-16 07:19:23 +00:00
74 changed files with 1885 additions and 466 deletions
+3
View File
@@ -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)"
+30 -11
View File
@@ -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,13 +148,6 @@ 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:
@@ -295,6 +296,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
@@ -488,9 +494,9 @@ TCC = $(TCC) -DSQLITE_DEBUG
RCC = $(RCC) -DSQLITE_DEBUG
!ENDIF
!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
!IF $(DEBUG)>4
TCC = $(TCC) -DSQLITE_DEBUG_OS_TRACE=1
RCC = $(RCC) -DSQLITE_DEBUG_OS_TRACE=1
!ENDIF
!IF $(DEBUG)>5
@@ -715,7 +721,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
@@ -759,6 +765,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
@@ -1166,6 +1182,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)
+29 -6
View File
@@ -3459,11 +3459,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 +4617,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 +5787,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,
+3 -3
View File
@@ -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;
}
+1 -1
View File
@@ -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) ){
+4
View File
@@ -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)
+81 -75
View File
@@ -1,9 +1,9 @@
C Revise\swhen\sthe\ssqlite3ErrName()\sfunction\sis\sdefined.
D 2015-04-28T23:34:10.625
C Prototype\sfor\san\ssqlite3_db_log()\sinterface.
D 2015-04-22T14:41:19.758
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 5f78b1ab81b64e7c57a75d170832443e66c0880a
F Makefile.in faaf75b89840659d74501bea269c7e33414761c1
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F Makefile.msc 29e11e91c4abf13c522b983552fac18422519321
F Makefile.msc 32d8fe89ac5c130f9f14293fb4a59b120895c943
F Makefile.vxworks e1b65dea203f054e71653415bd8f96dcaed47858
F README.md d58e3bebc0a4145e0f2a87994015fdb575a8e866
F VERSION 2e244662b71e6e68a5c29b014ebc5b7564f4cc5a
@@ -78,7 +78,7 @@ 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 1b198ddb76cd706722dacbbaeb17a2fde6fca2cc
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
F ext/fts3/fts3Int.h 3626655d6ba903a3919bb44e1c38e5f0f9d6be82
F ext/fts3/fts3_aux.c 5c211e17a64885faeb16b9ba7772f9d5445c2365
@@ -91,7 +91,7 @@ F ext/fts3/fts3_snippet.c 52c2dcf410b1f9af5a44d81a2cf8c68ed1cb5283
F ext/fts3/fts3_term.c a521f75132f9a495bdca1bdd45949b3191c52763
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_tokenizer.c 9afd223b07740b14dd589edd3116acacf951fd78
F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3
F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004
F ext/fts3/fts3_unicode.c a93f5edc0aff44ef8b06d7cb55b52026541ca145
@@ -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
@@ -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 60aba7d38b9bd73e249693344dd8405aa24ac02a
F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea
F mkopcodeh.awk d5e22023b5238985bb54a72d33e0ac71fe4f8a32
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
@@ -167,35 +167,35 @@ 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/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/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
F src/btree.c c6e32d84442f79d5b96965265d65b3baa231dffc
F src/btree.c 127aceb71ba93f59bc9c6ba810e992a04299e98a
F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1
F src/btreeInt.h 973a22a6fd61350b454ad614832b1f0a5e25a1e4
F src/build.c 01b969b20a44a3d9620e597d9af8242348123540
F src/build.c e246c2cea69c8f6fc825a156ea2de9dd4a17f18b
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 5555f768c05d7d4a7840c6c2e72ad7aecbe0fe54
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c 3343d551a8d810782257244fb33f2ce191493c39
F src/func.c 1414c24c873c48796ad45942257a179a423ba42f
F src/fkey.c c9b63a217d86582c22121699a47f22f524608869
F src/func.c e6b4680d0b6c901365e1ea5a6e75710e9479b70d
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 6dc030204d80be177578210a90c912e1d9597126
F src/main.c 453ae1a35c044cb5baa6b11697d722766d3f1569
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 abdb9a191a367793268fe553d25bab894e986a0e
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
F src/os_unix.c cf45d7b1cd27341ba8699e62c4902062b6297039
F src/os_win.c c2f0b0b3541906e310588b9e95080df4df75b674
F src/os_unix.c 5ed7e2e453c2980909a6b2c80dc55764b50819a8
F src/os_win.c 03d27be3a20048ef52a648d5f0a15f5edda9f2a3
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
F src/pager.c 4120a49ecd37697e28f5ed807f470b9c0b88410c
F src/pager.c 5283581c8ce8950ff483a0b3a3cab9cb4d25a21e
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 18df0da8c343dc4380f27a803858f2a4b81f1824
F src/printf.c 9753790eed39d7863a3e33567199f382d980fc28
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
F src/resolve.c 66cfe49a9c3b449ef13b89a8c47036a4ed167eab
F src/resolve.c 53486a98c17b7ae09b8c2b398013e973ce4c1aae
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 35433ea8894ac42594ddc31eb0165a6d6401cfe5
F src/shell.c 78eabce4c16c45e36fea2368f95118116399ba8a
F src/sqlite.h.in 3fb08b501d0155b4ba3ae8ef99c6f08491135dcb
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
F src/sqliteInt.h 5a4e0ae0ce02acb1cadb783abd70af800f538cba
F src/sqliteInt.h 823549bbcb0131e09c4a324080309d049a80e258
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179
F src/table.c e7a09215315a978057fb42c640f890160dbcc45e
F src/tclsqlite.c fa72a7c5278662357c105ba7925c1d0972506ff9
F src/test1.c 90fbedce75330d48d99eadb7d5f4223e86969585
F src/tclsqlite.c 14f1992dd6100bfeb1a3dec7e7f449e1c814b8ee
F src/test1.c 94efc685eb2e3dda4eb476670eeffaeaf05bead9
F src/test2.c 577961fe48961b2f2e5c8b56ee50c3f459d3359d
F src/test3.c 64d2afdd68feac1bb5e2ffb8226c8c639f798622
F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e
@@ -265,12 +265,12 @@ F src/test_intarray.c 6c610a21ab8edde85a3a2c7f2b069244ecf4d834
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 4dfb159e5c280c0ebdbf8b5ab9d95bf2765061f9
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
@@ -283,31 +283,31 @@ 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 8fa8a62632f6f3916bfb6f7b10e1ffbd36de71f0
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 4f4af7239261189393ca2752a3bf9977c14cb024
F src/vdbe.h 7e538ecf47dccb307ea2d087c3ddc2dd8d70e79d
F src/vdbeInt.h 9cbaa84f53ddd2d09a0cf61a94337a3a035d08a0
F src/vdbeapi.c 583d56b129dd27f12bed518270de9ebe521e6a75
F src/vdbeaux.c a20504ae52392459fa08402fda3f195f19d7c79d
F src/vdbeapi.c d4c9945b2a53b0b71d2a16843bb8d054ce513276
F src/vdbeaux.c aa9b179cc9e6e3e75f8f28e366bb0aafab9d710e
F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90
F src/vdbemem.c c0dc81285b7571b0a31c40f17846fe2397ec1cd9
F src/vdbemem.c b5256445b318b0f2b3bc429028469cfbb08f19a5
F src/vdbesort.c 2e7f683464fd5db3be4beaa1ff2d39e24fcb64b8
F src/vdbetrace.c 7e4222955e07dd707a2f360c0eb73452be1cb010
F src/vtab.c 9ca557215e8591ceb66e0b7c0a579c6df1e54b2d
F src/vdbetrace.c f95c2dff9041fcf07f871789c22ebb0648ea0b7c
F src/vtab.c 5f81f8a59c1f5ddb94c918f25ed5d83578fcc633
F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
F src/wal.c 753995db83247f20361a8e8a874990b21a75abd9
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804
F src/where.c 8ba8ff31dc9bf1b69fe771d35d8764d5a1efd310
F src/where.c ba0839e75f989dba622809716daabeb9c7fbd3c5
F src/whereInt.h cbe4aa57326998d89e7698ca65bb7c28541d483c
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
@@ -321,7 +321,7 @@ 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
@@ -493,19 +493,20 @@ F test/enc2.test 83437a79ba1545a55fb549309175c683fb334473
F test/enc3.test 90683ad0e6ea587b9d5542ca93568af9a9858c40
F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020
F test/eqp.test 85873fa5816c48915c82c4e74cb5c35a5b48160f
F test/errlog01.test 112ea4cd0f2974a63d60fe96d322af0f383045d4
F test/errmsg.test f31592a594b44ee121371d25ddd5d63497bb3401
F test/eval.test a64c9105d6ff163df7cf09d6ac29cdad5922078c
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 +552,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 +588,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
@@ -659,14 +661,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
@@ -743,11 +745,11 @@ 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
@@ -794,7 +796,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
@@ -836,10 +838,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
@@ -900,7 +902,7 @@ F test/spellfix.test 24f676831acddd2f4056a598fd731a72c6311f49
F test/sqllimits1.test e05786eaed7950ff6a2d00031d001d8a26131e68
F test/stat.test 76fd746b85459e812a0193410fb599f0531f22de
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 +910,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
@@ -1087,7 +1089,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 +1115,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 +1124,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 +1198,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 bcdca60b54654c8fc25fd215953d9b6bb55fd7d4
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 +1221,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 +1242,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 393b0f5b17ef29341664563a90d40ee63a0a18f7
F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43
F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d
F tool/symbols.sh fec58532668296d7c7dc48be9c87f75ccdb5814f
@@ -1250,7 +1253,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 c37f4d492f98ac5c07c08705a3826a3e86107306
R f96d406cf134e6be926fdb343dc33ea3
U mistachkin
Z 0af972753cfc85d551aad5ddaa27fa03
P 025e8370dde2918b66683f8d7fa9c7d23d03c9b4
R 065b478bd5e153421f77ec0bbb390aae
T *branch * sqlite3_db_log
T *sym-sqlite3_db_log *
T -sym-trunk *
U drh
Z cb2dffa7a83d63dde4f8c28d3e4ea48d
+1 -1
View File
@@ -1 +1 @@
9e593fb3dbc58e86f499ba4399530e3e760eb84d
658e20f55467a90bcebe5e01cf9f252dbe8bd690
+9 -6
View File
@@ -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);
-1
View File
@@ -332,7 +332,6 @@ static void codeAttach(
SQLITE_OK!=(rc = resolveAttachExpr(&sName, pDbname)) ||
SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey))
){
pParse->nErr++;
goto attach_end;
}
+72 -15
View File
@@ -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 current 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 move 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:
+9 -8
View File
@@ -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) ){
+4 -3
View File
@@ -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;
}
@@ -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
View File
@@ -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);
+5 -3
View File
@@ -886,8 +886,8 @@ static void sourceidFunc(
/*
** Implementation of the sqlite_log() function. This is a wrapper around
** sqlite3_log(). The return value is NULL. The function exists purely for
** its side-effects.
** sqlite3_db_log(). The return value is NULL. The function exists purely
** for its side-effects.
*/
static void errlogFunc(
sqlite3_context *context,
@@ -896,7 +896,9 @@ static void errlogFunc(
){
UNUSED_PARAMETER(argc);
UNUSED_PARAMETER(context);
sqlite3_log(sqlite3_value_int(argv[0]), "%s", sqlite3_value_text(argv[1]));
sqlite3_db_log(sqlite3_context_db_handle(context),
sqlite3_value_int(argv[0]),
"%s", sqlite3_value_text(argv[1]));
}
/*
+20 -17
View File
@@ -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 );
+9 -13
View File
@@ -55,18 +55,6 @@ 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
@@ -747,6 +735,14 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){
rc = setupLookaside(db, pBuf, sz, cnt);
break;
}
case SQLITE_DBCONFIG_LOG: {
/* MSVC is picky about pulling func ptrs from va lists.
** http://support.microsoft.com/kb/47961 */
typedef void(*LOGFUNC_t)(void*,int,const char*);
db->xLog = va_arg(ap, LOGFUNC_t);
db->pLogArg = va_arg(ap, void*);
break;
}
default: {
static const struct {
int op; /* The opcode */
@@ -1206,7 +1202,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_NEED_ERR_NAME)
#if (defined(SQLITE_DEBUG) && SQLITE_OS_WIN) || defined(SQLITE_TEST)
const char *sqlite3ErrName(int rc){
const char *zName = 0;
int i, origRc = rc;
+10
View File
@@ -29,6 +29,16 @@
# 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.
+1 -1
View File
@@ -641,7 +641,7 @@ static int unixMutexHeld(void) {
#endif
#ifdef SQLITE_HAVE_OS_TRACE
#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
/*
** Helper function for printing out trace information from debugging
** binaries. This returns the string representation of the supplied
+4 -4
View File
@@ -2757,7 +2757,7 @@ static int winSync(sqlite3_file *id, int flags){
BOOL rc;
#endif
#if !defined(NDEBUG) || !defined(SQLITE_NO_SYNC) || \
defined(SQLITE_HAVE_OS_TRACE)
(defined(SQLITE_TEST) && defined(SQLITE_DEBUG))
/*
** 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 */
#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
#ifdef SQLITE_DEBUG
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 */
#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
#ifdef SQLITE_DEBUG
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;
#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
#ifdef SQLITE_DEBUG
p->id = pShmNode->nextShmId++;
#endif
pShmNode->nRef++;
-4
View File
@@ -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);
}
+28 -16
View File
@@ -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
View File
@@ -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);
}
}
+24 -5
View File
@@ -1036,15 +1036,20 @@ char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
** allocate memory because it might be called while the memory allocator
** mutex is held.
*/
static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){
static void renderLogMsg(
void (*xLog)(void*,int,const char*), /* Logging function */
void *pArg, /* First argument to xLog */
int iErrCode, /* Error code */
const char *zFormat, /* Format string for error message */
va_list ap /* Arguments to format string */
){
StrAccum acc; /* String accumulator */
char zMsg[SQLITE_PRINT_BUF_SIZE*3]; /* Complete log message */
sqlite3StrAccumInit(&acc, zMsg, sizeof(zMsg), 0);
acc.useMalloc = 0;
sqlite3VXPrintf(&acc, 0, zFormat, ap);
sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode,
sqlite3StrAccumFinish(&acc));
xLog(pArg, iErrCode, sqlite3StrAccumFinish(&acc));
}
/*
@@ -1054,12 +1059,26 @@ void sqlite3_log(int iErrCode, const char *zFormat, ...){
va_list ap; /* Vararg list */
if( sqlite3GlobalConfig.xLog ){
va_start(ap, zFormat);
renderLogMsg(iErrCode, zFormat, ap);
renderLogMsg(sqlite3GlobalConfig.xLog, sqlite3GlobalConfig.pLogArg,
iErrCode, zFormat, ap);
va_end(ap);
}
}
void sqlite3_db_log(sqlite3 *db, int iErrCode, const char *zFormat, ...){
va_list ap; /* Vararg list */
if( db && db->xLog ){
va_start(ap, zFormat);
renderLogMsg(db->xLog, db->pLogArg, iErrCode, zFormat, ap);
va_end(ap);
}else if( sqlite3GlobalConfig.xLog ){
va_start(ap, zFormat);
renderLogMsg(sqlite3GlobalConfig.xLog, sqlite3GlobalConfig.pLogArg,
iErrCode, zFormat, ap);
va_end(ap);
}
}
#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
#if defined(SQLITE_DEBUG)
/*
** A version of printf() that understands %lld. Used for debugging.
** The printf() built into some versions of windows does not understand %lld
+8 -2
View File
@@ -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 -18
View File
@@ -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.
@@ -5538,6 +5540,7 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
StrAccum x;
char zLine[100];
sqlite3StrAccumInit(&x, zLine, sizeof(zLine), 0);
x.useMalloc = 0;
sqlite3XPrintf(&x, 0, "{%d,*}", pItem->iCursor);
if( pItem->zDatabase ){
sqlite3XPrintf(&x, 0, " %s.%s", pItem->zDatabase, pItem->zName);
+60 -51
View File
@@ -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
@@ -1908,23 +1909,23 @@ 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,
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);
}
}
@@ -2585,7 +2586,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 +2594,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 +2987,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 +3007,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 +3017,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;
}
@@ -3041,13 +3042,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 +3087,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 +3095,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
@@ -3648,13 +3649,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_realloc(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 +3708,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 +3737,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 +3751,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 +3762,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 +3776,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 +3789,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 +3800,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 +4112,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 +4579,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 ){
+36 -1
View File
@@ -1869,11 +1869,36 @@ struct sqlite3_mem_methods {
** following this call. The second parameter may be a NULL pointer, in
** which case the trigger setting is not reported back. </dd>
**
** [[SQLITE_DBCONFIG_LOG]] <dt>SQLITE_DBCONFIG_LOG</dt>
** <dd> The SQLITE_DBCONFIG_LOG option is used to configure the SQLite
** [error log] for a specific database connection. See also the
** [SQLITE_CONFIG_LOG] option to [sqlite3_config()] for the global log
** callback.
** (^The SQLITE_DBCONFIG_LOG option takes two arguments: a pointer to a
** function with a call signature of void(*)(void*,int,const char*),
** and a pointer to void. ^If the function pointer is not NULL, it is
** invoked by [sqlite3_db_log()] to process each logging event. ^If the
** function pointer is NULL, then calls to [sqlite3_db_log()] interface try
** to use the [SQLITE_CONFIG_LOG|global error log]. If both the connection
** and global error log callbacks are NULL then [sqlite3_db_log()] is a
** harmless no-op.
** ^The void pointer that is the second argument to SQLITE_DBCONFIG_LOG is
** passed through as the first parameter to the application-defined logger
** function whenever that function is invoked. ^The second parameter to
** the logger function is a copy of the second parameter to the corresponding
** [sqlite3_db_log()] call and is intended to be a [result code] or an
** [extended result code]. ^The third parameter passed to the logger is
** log message after formatting via [sqlite3_snprintf()].
** The SQLite logging interface is not reentrant; the logger function
** supplied by the application must not invoke any SQLite interface.
** </dd>
**
** </dl>
*/
#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
#define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */
#define SQLITE_DBCONFIG_LOG 1004 /* xFunc, void* */
/*
@@ -7285,10 +7310,19 @@ int sqlite3_strglob(const char *zGlob, const char *zStr);
**
** ^The [sqlite3_log()] interface writes a message into the [error log]
** established by the [SQLITE_CONFIG_LOG] option to [sqlite3_config()].
** ^The [sqlite3_db_log()] interface writes a message into the [error log]
** established by the [SQLITE_DBCONFIG_LOG] option to [sqlite3_db_config()].
** ^If logging is enabled, the zFormat string and subsequent arguments are
** used with [sqlite3_snprintf()] to generate the final output string.
**
** The sqlite3_log() interface is intended for use by extensions such as
** ^The [sqlite3_db_log()] interface writes error and warning information
** to the callback identified by the [SQLITE_DBCONFIG_LOG] option if that
** callback is not NULL, falling back to the [SQLITE_CONFIG_LOG] callback
** if the first parameter to [sqlite3_db_log()] is NULL or if the
** [SQLITE_DBCONFIG_LOG] callback is NULL.
**
** The sqlite3_log() and sqlite3_db_log() interfaces are intended for
** use by extensions such as
** virtual tables, collating functions, and SQL functions. While there is
** nothing to prevent an application from calling sqlite3_log(), doing so
** is considered bad form.
@@ -7302,6 +7336,7 @@ int sqlite3_strglob(const char *zGlob, const char *zStr);
** buffer.
*/
void sqlite3_log(int iErrCode, const char *zFormat, ...);
void sqlite3_db_log(sqlite3*, int iErrCode, const char *zFormat, ...);
/*
** CAPI3REF: Write-Ahead Log Commit Hook
+17 -34
View File
@@ -362,32 +362,6 @@
# 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()
@@ -1164,6 +1138,8 @@ struct sqlite3 {
double notUsed1; /* Spacer */
} u1;
Lookaside lookaside; /* Lookaside malloc configuration */
void (*xLog)(void*,int,const char*); /* Function for logging */
void *pLogArg; /* First argument to xLog() */
#ifndef SQLITE_OMIT_AUTHORIZATION
sqlite3_xauth xAuth; /* Access authorization function */
void *pAuthArg; /* 1st argument to the access auth function */
@@ -1648,6 +1624,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 */
@@ -1655,6 +1637,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 */
/*
@@ -2411,7 +2394,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 */
@@ -2795,7 +2778,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 ...
@@ -2803,12 +2786,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
@@ -2820,8 +2803,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 */
@@ -3172,7 +3155,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_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
void sqlite3DebugPrintf(const char*, ...);
#endif
#if defined(SQLITE_TEST)
@@ -3519,7 +3502,7 @@ void *sqlite3HexToBlob(sqlite3*, const char *z, int n);
u8 sqlite3HexToInt(int h);
int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
#if defined(SQLITE_NEED_ERR_NAME)
#if defined(SQLITE_TEST)
const char *sqlite3ErrName(int);
#endif
+5 -5
View File
@@ -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;
}
+28 -1
View File
@@ -5797,7 +5797,7 @@ static int test_sqlite3_log(
logcallback.pInterp = 0;
sqlite3_config(SQLITE_CONFIG_LOG, 0, 0);
}
if( objc>1 ){
if( objc==2 ){
logcallback.pObj = objv[1];
Tcl_IncrRefCount(logcallback.pObj);
logcallback.pInterp = interp;
@@ -5805,6 +5805,32 @@ static int test_sqlite3_log(
}
return TCL_OK;
}
static int test_sqlite3_db_log(
ClientData clientData,
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
int objc, /* Number of arguments */
Tcl_Obj *CONST objv[] /* Command arguments */
){
sqlite3 *db;
if( objc<1 || objc>3 ){
Tcl_WrongNumArgs(interp, 1, objv, "DB SCRIPT");
return TCL_ERROR;
}
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
if( logcallback.pObj ){
Tcl_DecrRefCount(logcallback.pObj);
logcallback.pObj = 0;
logcallback.pInterp = 0;
sqlite3_db_config(db, SQLITE_DBCONFIG_LOG, 0, 0);
}
if( objc==3 ){
logcallback.pObj = objv[2];
Tcl_IncrRefCount(logcallback.pObj);
logcallback.pInterp = interp;
sqlite3_db_config(db, SQLITE_DBCONFIG_LOG, xLogcallback, 0);
}
return TCL_OK;
}
/*
** tcl_objproc COMMANDNAME ARGS...
@@ -6906,6 +6932,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "sqlite3_wal_checkpoint_v2",test_wal_checkpoint_v2, 0 },
{ "sqlite3_wal_autocheckpoint",test_wal_autocheckpoint, 0 },
{ "test_sqlite3_log", test_sqlite3_log, 0 },
{ "test_sqlite3_db_log", test_sqlite3_db_log, 0 },
#ifndef SQLITE_OMIT_EXPLAIN
{ "print_explain_query_plan", test_print_eqp, 0 },
#endif
+5 -5
View File
@@ -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);
+7 -7
View File
@@ -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;
}
}
+3 -3
View File
@@ -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;
}
-3
View File
@@ -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;
+1 -2
View File
@@ -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");
+2 -4
View File
@@ -475,7 +475,7 @@ abort_parse:
assert( pzErrMsg!=0 );
if( pParse->zErrMsg ){
*pzErrMsg = pParse->zErrMsg;
sqlite3_log(pParse->rc, "%s", *pzErrMsg);
sqlite3_db_log(db, pParse->rc, "%s", *pzErrMsg);
pParse->zErrMsg = 0;
nErr++;
}
@@ -516,8 +516,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
View File
@@ -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);
}
+1
View File
@@ -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;
}
+16 -10
View File
@@ -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 ){
@@ -968,7 +974,7 @@ case OP_Halt: {
}else{
sqlite3SetString(&p->zErrMsg, db, "%s constraint failed", zType);
}
sqlite3_log(pOp->p1, zLogFmt, pcx, p->zSql, p->zErrMsg);
sqlite3_db_log(db, pOp->p1, zLogFmt, pcx, p->zSql, p->zErrMsg);
}
rc = sqlite3VdbeHalt(p);
assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR );
@@ -2919,7 +2925,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;
}
@@ -6489,8 +6495,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 +6506,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 */
@@ -6523,7 +6529,7 @@ vdbe_error_halt:
assert( rc );
p->rc = rc;
testcase( sqlite3GlobalConfig.xLog!=0 );
sqlite3_log(rc, "statement aborts at %d: [%s] %s",
sqlite3_db_log(db, rc, "statement aborts at %d: [%s] %s",
(int)(pOp - aOp), p->zSql, p->zErrMsg);
sqlite3VdbeHalt(p);
if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1;
+2 -2
View File
@@ -1145,9 +1145,9 @@ static int vdbeUnbind(Vdbe *p, int i){
sqlite3_mutex_enter(p->db->mutex);
if( p->magic!=VDBE_MAGIC_RUN || p->pc>=0 ){
sqlite3Error(p->db, SQLITE_MISUSE);
sqlite3_mutex_leave(p->db->mutex);
sqlite3_log(SQLITE_MISUSE,
sqlite3_db_log(p->db, SQLITE_MISUSE,
"bind on a busy prepared statement: [%s]", p->zSql);
sqlite3_mutex_leave(p->db->mutex);
return SQLITE_MISUSE_BKPT;
}
if( i<1 || i>p->nVar ){
+20 -13
View File
@@ -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);
}
@@ -2046,11 +2053,11 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
u32 iRandom;
if( retryCount ){
if( retryCount>100 ){
sqlite3_log(SQLITE_FULL, "MJ delete: %s", zMaster);
sqlite3_db_log(db, SQLITE_FULL, "MJ delete: %s", zMaster);
sqlite3OsDelete(pVfs, zMaster, 0);
break;
}else if( retryCount==1 ){
sqlite3_log(SQLITE_FULL, "MJ collide: %s", zMaster);
sqlite3_db_log(db, SQLITE_FULL, "MJ collide: %s", zMaster);
}
}
retryCount++;
+1 -1
View File
@@ -1647,7 +1647,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);
+5 -1
View File
@@ -95,6 +95,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 +113,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 );
}
+10 -3
View File
@@ -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++){
+6 -6
View File
@@ -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);
}
}
@@ -1749,7 +1750,7 @@ static void constructAutomaticIndex(
testcase( iCol==BMS );
testcase( iCol==BMS-1 );
if( !sentWarning ){
sqlite3_log(SQLITE_WARNING_AUTOINDEX,
sqlite3_db_log(pParse->db, SQLITE_WARNING_AUTOINDEX,
"automatic index on %s(%s)", pTable->zName,
pTable->aCol[iCol].zName);
sentWarning = 1;
@@ -6646,7 +6647,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);
+30
View File
@@ -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
View File
@@ -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.
+5
View File
@@ -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
View File
@@ -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
+37
View File
@@ -0,0 +1,37 @@
# 2015-04-22
#
# 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.
#
#*************************************************************************
# Test cases for the sqlite3_log() and sqlite3_db_log() interfaces.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
unset -nocomplain log
set log {}
do_test errlog01-1.0 {
test_sqlite3_db_log db [list lappend ::log]
db eval {SELECT sqlite_log(7,'simulated error')}
} {{}}
do_test errlog01-1.1 {
set ::log
} {SQLITE_NOMEM {simulated error}}
do_test errlog01-1.2 {
sqlite3 db2 :memory:
set ::log {}
db2 eval {SELECT sqlite_log(7,'simulated error')}
} {{}}
do_test errlog01-1.3 {
set ::log
} {}
finish_test
+8
View File
@@ -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
+30
View File
@@ -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
+19
View File
@@ -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
+22
View File
@@ -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
+48
View File
@@ -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
+4
View File
@@ -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
+20
View File
@@ -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
+5
View File
@@ -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
+40
View File
@@ -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
+18
View File
@@ -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 {
+18
View File
@@ -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.
+8
View File
@@ -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
View File
@@ -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
+10
View File
@@ -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
+19
View File
@@ -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 {
+49
View File
@@ -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
+37
View File
@@ -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
View File
@@ -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
View File
@@ -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
+567
View File
@@ -0,0 +1,567 @@
/*
** 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.
**
** 2015-04-20: The input text can be divided into separate SQL chunks using
** lines of the form:
**
** |****<...>****|
**
** where the "..." is arbitrary text, except the "|" should really be "/".
** ("|" is used here to avoid compiler warnings about nested comments.)
** Each such SQL comment is printed as it is encountered. A separate
** in-memory SQLite database is created to run each chunk of SQL. 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 >out.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.
*/
#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 */
} g;
/*
** 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;
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;
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);
}
/*
** 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");
}
}
return 0;
}
/*
** 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);
}
/***************************************************************************
** 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]\n", g.zArgv0);
printf(
"Read SQL text from standard input and evaluate it.\n"
"Options:\n"
" --autovacuum Enable AUTOVACUUM mode\n"
" -f FILE Read SQL text from FILE instead of standard input\n"
" --heap SZ MIN Memory allocator uses SZ bytes & min allocation MIN\n"
" --help Show this help text\n"
" --initdb DBFILE Initialize the in-memory database using template DBFILE\n"
" --lookaside N SZ Configure lookaside for N slots of SZ bytes each\n"
" --pagesize N Set the page size to N\n"
" --pcache N SZ Configure N pages of pagecache each of size SZ bytes\n"
" --scratch N SZ Configure scratch memory for N slots of SZ bytes each\n"
" --utf16be Set text encoding to UTF-16BE\n"
" --utf16le Set text encoding to UTF-16LE\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);
}
/*
** Various operating modes
*/
#define FZMODE_Generic 1
#define FZMODE_Strftime 2
#define FZMODE_Printf 3
#define FZMODE_Glob 4
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 */
FILE *in = stdin; /* Where to read SQL text from */
int rc = SQLITE_OK; /* Result codes from API functions */
int i; /* Loop counter */
int iNext; /* Next block of SQL */
sqlite3 *db; /* Open database */
sqlite3 *dbInit = 0; /* On-disk database used to initialize the in-memory db */
const char *zInitDb = 0;/* Name of the initialization database file */
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 iMode = FZMODE_Generic; /* Operating mode */
const char *zCkGlob = 0; /* Inputs must match this glob */
g.zArgv0 = argv[0];
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 ){
if( in!=stdin ) abendError("only one -f allowed");
in = fopen(argv[++i],"rb");
if( in==0 ) abendError("cannot open input file \"%s\"", argv[i]);
}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, "initdb")==0 && i+1<argc ){
if( zInitDb!=0 ) abendError("only one --initdb allowed");
zInitDb = argv[++i];
}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,"mode")==0 ){
if( i>=argc-1 ) abendError("missing argument on %s", argv[i]);
z = argv[++i];
if( strcmp(z,"generic")==0 ){
iMode = FZMODE_Printf;
zCkGlob = 0;
}else if( strcmp(z, "glob")==0 ){
iMode = FZMODE_Glob;
zCkGlob = "'*','*'";
}else if( strcmp(z, "printf")==0 ){
iMode = FZMODE_Printf;
zCkGlob = "'*',*";
}else if( strcmp(z, "strftime")==0 ){
iMode = FZMODE_Strftime;
zCkGlob = "'*',*";
}else{
abendError("unknown --mode: %s", z);
}
}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,"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,"utf16le")==0 ){
zEncoding = "utf16le";
}else
if( strcmp(z,"utf16be")==0 ){
zEncoding = "utf16be";
}else
{
abendError("unknown option: %s", argv[i]);
}
}else{
abendError("unknown argument: %s", argv[i]);
}
}
sqlite3_config(SQLITE_CONFIG_LOG, shellLog, 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( 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);
}
while( !feof(in) ){
nAlloc += nAlloc+1000;
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;
}
if( zInitDb ){
rc = sqlite3_open_v2(zInitDb, &dbInit, SQLITE_OPEN_READONLY, 0);
if( rc!=SQLITE_OK ){
abendError("unable to open initialization database \"%s\"", zInitDb);
}
}
for(i=0; i<nIn; i=iNext){
char cSaved;
if( strncmp(&zIn[i], "/****<",6)==0 ){
char *z = strstr(&zIn[i], ">****/");
if( z ){
z += 6;
printf("%.*s\n", (int)(z-&zIn[i]), &zIn[i]);
i += (int)(z-&zIn[i]);
}
}
for(iNext=i; iNext<nIn && strncmp(&zIn[iNext],"/****<",6)!=0; iNext++){}
cSaved = zIn[iNext];
zIn[iNext] = 0;
if( zCkGlob && sqlite3_strglob(zCkGlob,&zIn[i])!=0 ){
zIn[iNext] = cSaved;
continue;
}
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);
}
if( zInitDb ){
sqlite3_backup *pBackup;
pBackup = sqlite3_backup_init(db, "main", dbInit, "main");
rc = sqlite3_backup_step(pBackup, -1);
if( rc!=SQLITE_DONE ){
abendError("attempt to initialize the in-memory database failed (rc=%d)",
rc);
}
sqlite3_backup_finish(pBackup);
}
sqlite3_trace(db, traceCallback, 0);
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");
printf("INPUT (offset: %d, size: %d): [%s]\n",
i, (int)strlen(&zIn[i]), &zIn[i]);
zSql = &zIn[i];
switch( iMode ){
case FZMODE_Glob:
zSql = zToFree = sqlite3_mprintf("SELECT glob(%s);", zSql);
break;
case FZMODE_Printf:
zSql = zToFree = sqlite3_mprintf("SELECT printf(%s);", zSql);
break;
case FZMODE_Strftime:
zSql = zToFree = sqlite3_mprintf("SELECT strftime(%s);", zSql);
break;
}
rc = sqlite3_exec(db, zSql, execCallback, 0, &zErrMsg);
if( zToFree ){
sqlite3_free(zToFree);
zToFree = 0;
}
zIn[iNext] = cSaved;
printf("RESULT-CODE: %d\n", rc);
if( zErrMsg ){
printf("ERROR-MSG: [%s]\n", zErrMsg);
sqlite3_free(zErrMsg);
}
rc = sqlite3_close(db);
if( rc ){
abendError("sqlite3_close() failed with rc=%d", rc);
}
if( sqlite3_memory_used()>0 ){
abendError("memory in use after close: %lld bytes", sqlite3_memory_used());
}
}
free(zIn);
free(pHeap);
free(pLook);
free(pScratch);
free(pPCache);
return 0;
}
+35 -37
View File
@@ -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
View File
@@ -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]]
}
###############################################################################
+6 -1
View File
@@ -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>