Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 52afa8ff09 | |||
| c5fd65d3f7 |
@@ -566,7 +566,6 @@ SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
|
||||
SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
|
||||
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
|
||||
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ
|
||||
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
|
||||
FUZZCHECK_SRC = $(TOP)/test/fuzzcheck.c $(TOP)/test/ossfuzz.c
|
||||
DBFUZZ_OPT =
|
||||
|
||||
|
||||
+14
-30
@@ -745,7 +745,6 @@ RCC = $(RCC) -DSQLITE_ENABLE_API_ARMOR=1
|
||||
|
||||
!IF $(DEBUG)>2
|
||||
TCC = $(TCC) -DSQLITE_DEBUG=1
|
||||
TCC = $(TCC) -DSQLITE_ENABLE_WHERETRACE -DSQLITE_ENABLE_SELECTTRACE
|
||||
RCC = $(RCC) -DSQLITE_DEBUG=1
|
||||
!ENDIF
|
||||
|
||||
@@ -1510,13 +1509,9 @@ SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_
|
||||
#
|
||||
MPTESTER_COMPILE_OPTS = -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS5
|
||||
FUZZERSHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1
|
||||
FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ -DSQLITE_MAX_MEMORY=50000000
|
||||
FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ
|
||||
FUZZCHECK_SRC = $(TOP)\test\fuzzcheck.c $(TOP)\test\ossfuzz.c
|
||||
OSSSHELL_SRC = $(TOP)\test\ossshell.c $(TOP)\test\ossfuzz.c
|
||||
DBFUZZ_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION
|
||||
KV_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ
|
||||
DBSELFTEST_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
|
||||
ST_COMPILE_OPTS = -DSQLITE_THREADSAFE=0
|
||||
|
||||
# Standard options to testfixture.
|
||||
#
|
||||
@@ -1559,7 +1554,7 @@ $(SQLITE3DLL): $(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP)
|
||||
sqlite3.def: libsqlite3.lib
|
||||
echo EXPORTS > sqlite3.def
|
||||
dumpbin /all libsqlite3.lib \
|
||||
| $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3(?:session|changeset)?_[^@]*)(?:@\d+)?$$" \1 \
|
||||
| $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3_[^@]*)(?:@\d+)?$$" \1 \
|
||||
| sort >> sqlite3.def
|
||||
# <</block2>>
|
||||
|
||||
@@ -1586,9 +1581,6 @@ sourcetest: srcck1.exe sqlite3.c
|
||||
fuzzershell.exe: $(TOP)\tool\fuzzershell.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) $(FUZZERSHELL_COMPILE_OPTS) $(TOP)\tool\fuzzershell.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
dbfuzz.exe: $(TOP)\test\dbfuzz.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) $(DBFUZZ_COMPILE_OPTS) $(TOP)\test\dbfuzz.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
fuzzcheck.exe: $(FUZZCHECK_SRC) $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) $(FUZZCHECK_COMPILE_OPTS) $(FUZZCHECK_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
@@ -2185,54 +2177,46 @@ testloadext.dll: testloadext.lo
|
||||
$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /OUT:$@ testloadext.lo
|
||||
|
||||
showdb.exe: $(TOP)\tool\showdb.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||
$(TOP)\tool\showdb.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
showstat4.exe: $(TOP)\tool\showstat4.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||
$(TOP)\tool\showstat4.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
showjournal.exe: $(TOP)\tool\showjournal.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||
$(TOP)\tool\showjournal.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
showwal.exe: $(TOP)\tool\showwal.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||
$(TOP)\tool\showwal.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
changeset.exe: $(TOP)\ext\session\changeset.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
-DSQLITE_ENABLE_SESSION=1 -DSQLITE_ENABLE_PREUPDATE_HOOK=1 \
|
||||
changeset.exe: $(TOP)\ext\session\changeset.c $(SQLITE3C)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||
$(TOP)\ext\session\changeset.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
fts3view.exe: $(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||
$(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
rollback-test.exe: $(TOP)\tool\rollback-test.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||
$(TOP)\tool\rollback-test.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
LogEst.exe: $(TOP)\tool\logest.c $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) $(TOP)\tool\LogEst.c /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
$(LTLINK) $(NO_WARN) -Fe$@ $(TOP)\tool\LogEst.c /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
wordcount.exe: $(TOP)\test\wordcount.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||
$(TOP)\test\wordcount.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
speedtest1.exe: $(TOP)\test\speedtest1.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) $(ST_COMPILE_OPTS) -DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||
$(TOP)\test\speedtest1.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
kvtest.exe: $(TOP)\test\kvtest.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) $(KV_COMPILE_OPTS) \
|
||||
$(TOP)\test\kvtest.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
dbselftest.exe: $(TOP)\test\dbselftest.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) $(DBSELFTEST_COMPILE_OPTS) $(TOP)\test\dbselftest.c $(SQLITE3C)
|
||||
|
||||
rbu.exe: $(TOP)\ext\rbu\rbu.c $(TOP)\ext\rbu\sqlite3rbu.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_ENABLE_RBU \
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_ENABLE_RBU -Fe$@ \
|
||||
$(TOP)\ext\rbu\rbu.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
moreclean: clean
|
||||
|
||||
@@ -950,7 +950,7 @@ Replace.exe:
|
||||
sqlite3.def: Replace.exe $(LIBOBJ)
|
||||
echo EXPORTS > sqlite3.def
|
||||
dumpbin /all $(LIBOBJ) \
|
||||
| .\Replace.exe "^\s+/EXPORT:_?(sqlite3(?:session|changeset)?_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \
|
||||
| .\Replace.exe "^\s+/EXPORT:_?(sqlite3_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \
|
||||
| sort >> sqlite3.def
|
||||
|
||||
$(SQLITE3EXE): $(TOP)\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLITE3H)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for sqlite 3.18.0.
|
||||
# Generated by GNU Autoconf 2.69 for sqlite 3.17.0.
|
||||
#
|
||||
#
|
||||
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
|
||||
@@ -726,8 +726,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='sqlite'
|
||||
PACKAGE_TARNAME='sqlite'
|
||||
PACKAGE_VERSION='3.18.0'
|
||||
PACKAGE_STRING='sqlite 3.18.0'
|
||||
PACKAGE_VERSION='3.17.0'
|
||||
PACKAGE_STRING='sqlite 3.17.0'
|
||||
PACKAGE_BUGREPORT=''
|
||||
PACKAGE_URL=''
|
||||
|
||||
@@ -1463,7 +1463,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures sqlite 3.18.0 to adapt to many kinds of systems.
|
||||
\`configure' configures sqlite 3.17.0 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@@ -1528,7 +1528,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of sqlite 3.18.0:";;
|
||||
short | recursive ) echo "Configuration of sqlite 3.17.0:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1652,7 +1652,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
sqlite configure 3.18.0
|
||||
sqlite configure 3.17.0
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
@@ -2071,7 +2071,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by sqlite $as_me 3.18.0, which was
|
||||
It was created by sqlite $as_me 3.17.0, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@@ -12151,7 +12151,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by sqlite $as_me 3.18.0, which was
|
||||
This file was extended by sqlite $as_me 3.17.0, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -12217,7 +12217,7 @@ _ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
sqlite config.status 3.18.0
|
||||
sqlite config.status 3.17.0
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
||||
+15
-40
@@ -492,7 +492,6 @@ static int fts3DisconnectMethod(sqlite3_vtab *pVtab){
|
||||
assert( p->pSegments==0 );
|
||||
|
||||
/* Free any prepared statements held */
|
||||
sqlite3_finalize(p->pSeekStmt);
|
||||
for(i=0; i<SizeofArray(p->aStmt); i++){
|
||||
sqlite3_finalize(p->aStmt[i]);
|
||||
}
|
||||
@@ -1681,26 +1680,6 @@ static int fts3OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Finalize the statement handle at pCsr->pStmt.
|
||||
**
|
||||
** Or, if that statement handle is one created by fts3CursorSeekStmt(),
|
||||
** and the Fts3Table.pSeekStmt slot is currently NULL, save the statement
|
||||
** pointer there instead of finalizing it.
|
||||
*/
|
||||
static void fts3CursorFinalizeStmt(Fts3Cursor *pCsr){
|
||||
if( pCsr->bSeekStmt ){
|
||||
Fts3Table *p = (Fts3Table *)pCsr->base.pVtab;
|
||||
if( p->pSeekStmt==0 ){
|
||||
p->pSeekStmt = pCsr->pStmt;
|
||||
sqlite3_reset(pCsr->pStmt);
|
||||
pCsr->pStmt = 0;
|
||||
}
|
||||
pCsr->bSeekStmt = 0;
|
||||
}
|
||||
sqlite3_finalize(pCsr->pStmt);
|
||||
}
|
||||
|
||||
/*
|
||||
** Close the cursor. For additional information see the documentation
|
||||
** on the xClose method of the virtual table interface.
|
||||
@@ -1708,7 +1687,7 @@ static void fts3CursorFinalizeStmt(Fts3Cursor *pCsr){
|
||||
static int fts3CloseMethod(sqlite3_vtab_cursor *pCursor){
|
||||
Fts3Cursor *pCsr = (Fts3Cursor *)pCursor;
|
||||
assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
|
||||
fts3CursorFinalizeStmt(pCsr);
|
||||
sqlite3_finalize(pCsr->pStmt);
|
||||
sqlite3Fts3ExprFree(pCsr->pExpr);
|
||||
sqlite3Fts3FreeDeferredTokens(pCsr);
|
||||
sqlite3_free(pCsr->aDoclist);
|
||||
@@ -1726,23 +1705,20 @@ static int fts3CloseMethod(sqlite3_vtab_cursor *pCursor){
|
||||
**
|
||||
** (or the equivalent for a content=xxx table) and set pCsr->pStmt to
|
||||
** it. If an error occurs, return an SQLite error code.
|
||||
**
|
||||
** Otherwise, set *ppStmt to point to pCsr->pStmt and return SQLITE_OK.
|
||||
*/
|
||||
static int fts3CursorSeekStmt(Fts3Cursor *pCsr){
|
||||
static int fts3CursorSeekStmt(Fts3Cursor *pCsr, sqlite3_stmt **ppStmt){
|
||||
int rc = SQLITE_OK;
|
||||
if( pCsr->pStmt==0 ){
|
||||
Fts3Table *p = (Fts3Table *)pCsr->base.pVtab;
|
||||
char *zSql;
|
||||
if( p->pSeekStmt ){
|
||||
pCsr->pStmt = p->pSeekStmt;
|
||||
p->pSeekStmt = 0;
|
||||
}else{
|
||||
zSql = sqlite3_mprintf("SELECT %s WHERE rowid = ?", p->zReadExprlist);
|
||||
if( !zSql ) return SQLITE_NOMEM;
|
||||
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0);
|
||||
sqlite3_free(zSql);
|
||||
}
|
||||
if( rc==SQLITE_OK ) pCsr->bSeekStmt = 1;
|
||||
zSql = sqlite3_mprintf("SELECT %s WHERE rowid = ?", p->zReadExprlist);
|
||||
if( !zSql ) return SQLITE_NOMEM;
|
||||
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0);
|
||||
sqlite3_free(zSql);
|
||||
}
|
||||
*ppStmt = pCsr->pStmt;
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -1754,7 +1730,9 @@ static int fts3CursorSeekStmt(Fts3Cursor *pCsr){
|
||||
static int fts3CursorSeek(sqlite3_context *pContext, Fts3Cursor *pCsr){
|
||||
int rc = SQLITE_OK;
|
||||
if( pCsr->isRequireSeek ){
|
||||
rc = fts3CursorSeekStmt(pCsr);
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
|
||||
rc = fts3CursorSeekStmt(pCsr, &pStmt);
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iPrevId);
|
||||
pCsr->isRequireSeek = 0;
|
||||
@@ -3212,7 +3190,7 @@ static int fts3FilterMethod(
|
||||
assert( iIdx==nVal );
|
||||
|
||||
/* In case the cursor has been used before, clear it now. */
|
||||
fts3CursorFinalizeStmt(pCsr);
|
||||
sqlite3_finalize(pCsr->pStmt);
|
||||
sqlite3_free(pCsr->aDoclist);
|
||||
sqlite3Fts3MIBufferFree(pCsr->pMIBuffer);
|
||||
sqlite3Fts3ExprFree(pCsr->pExpr);
|
||||
@@ -3280,7 +3258,7 @@ static int fts3FilterMethod(
|
||||
rc = SQLITE_NOMEM;
|
||||
}
|
||||
}else if( eSearch==FTS3_DOCID_SEARCH ){
|
||||
rc = fts3CursorSeekStmt(pCsr);
|
||||
rc = fts3CursorSeekStmt(pCsr, &pCsr->pStmt);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3_bind_value(pCsr->pStmt, 1, pCons);
|
||||
}
|
||||
@@ -3408,10 +3386,8 @@ static int fts3SyncMethod(sqlite3_vtab *pVtab){
|
||||
const u32 nMinMerge = 64; /* Minimum amount of incr-merge work to do */
|
||||
|
||||
Fts3Table *p = (Fts3Table*)pVtab;
|
||||
int rc;
|
||||
i64 iLastRowid = sqlite3_last_insert_rowid(p->db);
|
||||
int rc = sqlite3Fts3PendingTermsFlush(p);
|
||||
|
||||
rc = sqlite3Fts3PendingTermsFlush(p);
|
||||
if( rc==SQLITE_OK
|
||||
&& p->nLeafAdd>(nMinMerge/16)
|
||||
&& p->nAutoincrmerge && p->nAutoincrmerge!=0xff
|
||||
@@ -3426,7 +3402,6 @@ static int fts3SyncMethod(sqlite3_vtab *pVtab){
|
||||
if( A>(int)nMinMerge ) rc = sqlite3Fts3Incrmerge(p, A, p->nAutoincrmerge);
|
||||
}
|
||||
sqlite3Fts3SegmentsClose(p);
|
||||
sqlite3_set_last_insert_rowid(p->db, iLastRowid);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@@ -230,7 +230,6 @@ struct Fts3Table {
|
||||
** statements is run and reset within a single virtual table API call.
|
||||
*/
|
||||
sqlite3_stmt *aStmt[40];
|
||||
sqlite3_stmt *pSeekStmt; /* Cache for fts3CursorSeekStmt() */
|
||||
|
||||
char *zReadExprlist;
|
||||
char *zWriteExprlist;
|
||||
@@ -300,7 +299,6 @@ struct Fts3Cursor {
|
||||
i16 eSearch; /* Search strategy (see below) */
|
||||
u8 isEof; /* True if at End Of Results */
|
||||
u8 isRequireSeek; /* True if must seek pStmt to %_content row */
|
||||
u8 bSeekStmt; /* True if pStmt is a seek */
|
||||
sqlite3_stmt *pStmt; /* Prepared statement in use by the cursor */
|
||||
Fts3Expr *pExpr; /* Parsed MATCH query string */
|
||||
int iLangid; /* Language being queried for */
|
||||
|
||||
+1
-3
@@ -30,9 +30,7 @@ typedef short i16;
|
||||
typedef sqlite3_int64 i64;
|
||||
typedef sqlite3_uint64 u64;
|
||||
|
||||
#ifndef ArraySize
|
||||
# define ArraySize(x) ((int)(sizeof(x) / sizeof(x[0])))
|
||||
#endif
|
||||
#define ArraySize(x) ((int)(sizeof(x) / sizeof(x[0])))
|
||||
|
||||
#define testcase(x)
|
||||
#define ALWAYS(x) 1
|
||||
|
||||
+2
-13
@@ -1110,10 +1110,7 @@ static int fts5ExprNodeNext_OR(
|
||||
|| (bFromValid && fts5RowidCmp(pExpr, p1->iRowid, iFrom)<0)
|
||||
){
|
||||
int rc = fts5ExprNodeNext(pExpr, p1, bFromValid, iFrom);
|
||||
if( rc!=SQLITE_OK ){
|
||||
pNode->bNomatch = 0;
|
||||
return rc;
|
||||
}
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1144,10 +1141,7 @@ static int fts5ExprNodeTest_AND(
|
||||
if( cmp>0 ){
|
||||
/* Advance pChild until it points to iLast or laster */
|
||||
rc = fts5ExprNodeNext(pExpr, pChild, 1, iLast);
|
||||
if( rc!=SQLITE_OK ){
|
||||
pAnd->bNomatch = 0;
|
||||
return rc;
|
||||
}
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
}
|
||||
|
||||
/* If the child node is now at EOF, so is the parent AND node. Otherwise,
|
||||
@@ -1186,8 +1180,6 @@ static int fts5ExprNodeNext_AND(
|
||||
int rc = fts5ExprNodeNext(pExpr, pNode->apChild[0], bFromValid, iFrom);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = fts5ExprNodeTest_AND(pExpr, pNode);
|
||||
}else{
|
||||
pNode->bNomatch = 0;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@@ -1230,9 +1222,6 @@ static int fts5ExprNodeNext_NOT(
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = fts5ExprNodeTest_NOT(pExpr, pNode);
|
||||
}
|
||||
if( rc!=SQLITE_OK ){
|
||||
pNode->bNomatch = 0;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
+15
-10
@@ -545,6 +545,11 @@ int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, sqlite3_value **apVal){
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the averages record */
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = fts5StorageSaveTotals(p);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -748,6 +753,11 @@ int sqlite3Fts5StorageIndexInsert(
|
||||
}
|
||||
sqlite3_free(buf.p);
|
||||
|
||||
/* Write the averages record */
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = fts5StorageSaveTotals(p);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -1082,17 +1092,12 @@ int sqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow){
|
||||
** Flush any data currently held in-memory to disk.
|
||||
*/
|
||||
int sqlite3Fts5StorageSync(Fts5Storage *p, int bCommit){
|
||||
int rc = SQLITE_OK;
|
||||
i64 iLastRowid = sqlite3_last_insert_rowid(p->pConfig->db);
|
||||
if( p->bTotalsValid ){
|
||||
rc = fts5StorageSaveTotals(p);
|
||||
if( bCommit ) p->bTotalsValid = 0;
|
||||
if( bCommit && p->bTotalsValid ){
|
||||
int rc = fts5StorageSaveTotals(p);
|
||||
p->bTotalsValid = 0;
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3Fts5IndexSync(p->pIndex, bCommit);
|
||||
}
|
||||
sqlite3_set_last_insert_rowid(p->pConfig->db, iLastRowid);
|
||||
return rc;
|
||||
return sqlite3Fts5IndexSync(p->pIndex, bCommit);
|
||||
}
|
||||
|
||||
int sqlite3Fts5StorageRollback(Fts5Storage *p){
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
# 2016 February 2
|
||||
#
|
||||
# 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 is focused on OOM errors.
|
||||
#
|
||||
|
||||
source [file join [file dirname [info script]] fts5_common.tcl]
|
||||
source $testdir/malloc_common.tcl
|
||||
set testprefix fts5faultA
|
||||
|
||||
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
|
||||
ifcapable !fts5 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
foreach_detail_mode $testprefix {
|
||||
if {"%DETAIL%"=="none"} continue
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE VIRTUAL TABLE o1 USING fts5(a, b, c, detail=%DETAIL%);
|
||||
INSERT INTO o1(o1, rank) VALUES('pgsz', 32);
|
||||
|
||||
WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<60 )
|
||||
INSERT INTO o1 SELECT 'A', 'B', 'C' FROM s;
|
||||
|
||||
WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<60 )
|
||||
INSERT INTO o1 SELECT 'C', 'A', 'B' FROM s;
|
||||
|
||||
WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<60 )
|
||||
INSERT INTO o1 SELECT 'B', 'C', 'A' FROM s;
|
||||
}
|
||||
|
||||
do_faultsim_test 1 -faults int* -prep {
|
||||
sqlite3 db test.db
|
||||
} -body {
|
||||
execsql { SELECT count(*) FROM o1('a') }
|
||||
} -test {
|
||||
faultsim_test_result {0 180} {1 {vtable constructor failed: o1}}
|
||||
}
|
||||
|
||||
do_faultsim_test 2 -faults int* -prep {
|
||||
sqlite3 db test.db
|
||||
} -body {
|
||||
execsql { SELECT * FROM o1('a:a AND {b c}:b') ORDER BY rank }
|
||||
expr 1
|
||||
} -test {
|
||||
faultsim_test_result {0 1} {1 {vtable constructor failed: o1}}
|
||||
}
|
||||
|
||||
do_faultsim_test 3 -faults int* -prep {
|
||||
sqlite3 db test.db
|
||||
} -body {
|
||||
execsql { SELECT * FROM o1('{b c}:b NOT a:a') ORDER BY rank }
|
||||
expr 1
|
||||
} -test {
|
||||
faultsim_test_result {0 1} {1 {vtable constructor failed: o1}}
|
||||
}
|
||||
|
||||
do_faultsim_test 4 -faults int* -prep {
|
||||
sqlite3 db test.db
|
||||
} -body {
|
||||
execsql { SELECT * FROM o1('b:b OR a:a') }
|
||||
expr 1
|
||||
} -test {
|
||||
faultsim_test_result {0 1} {1 {vtable constructor failed: o1}}
|
||||
}
|
||||
|
||||
do_faultsim_test 5 -faults int* -prep {
|
||||
sqlite3 db test.db
|
||||
} -body {
|
||||
execsql { SELECT count(*) FROM o1('c:b') }
|
||||
expr 1
|
||||
} -test {
|
||||
faultsim_test_result {0 1} {1 {vtable constructor failed: o1}}
|
||||
}
|
||||
}
|
||||
|
||||
finish_test
|
||||
@@ -1,73 +0,0 @@
|
||||
# 2017 Feb 27
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# Tests of the last_insert_rowid functionality with fts5.
|
||||
#
|
||||
|
||||
source [file join [file dirname [info script]] fts5_common.tcl]
|
||||
set testprefix fts5lastrowid
|
||||
|
||||
# If SQLITE_ENABLE_FTS5 is defined, omit this file.
|
||||
ifcapable !fts5 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(str);
|
||||
}
|
||||
|
||||
do_execsql_test 1.1 {
|
||||
INSERT INTO t1 VALUES('one string');
|
||||
INSERT INTO t1 VALUES('two string');
|
||||
INSERT INTO t1 VALUES('three string');
|
||||
SELECT last_insert_rowid();
|
||||
} {3}
|
||||
|
||||
do_execsql_test 1.2 {
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES('one string');
|
||||
INSERT INTO t1 VALUES('two string');
|
||||
INSERT INTO t1 VALUES('three string');
|
||||
COMMIT;
|
||||
SELECT last_insert_rowid();
|
||||
} {6}
|
||||
|
||||
do_execsql_test 1.3 {
|
||||
INSERT INTO t1(rowid, str) VALUES(-22, 'some more text');
|
||||
SELECT last_insert_rowid();
|
||||
} {-22}
|
||||
|
||||
do_execsql_test 1.4 {
|
||||
BEGIN;
|
||||
INSERT INTO t1(rowid, str) VALUES(45, 'some more text');
|
||||
INSERT INTO t1(rowid, str) VALUES(46, 'some more text');
|
||||
INSERT INTO t1(rowid, str) VALUES(222, 'some more text');
|
||||
SELECT last_insert_rowid();
|
||||
COMMIT;
|
||||
SELECT last_insert_rowid();
|
||||
} {222 222}
|
||||
|
||||
do_execsql_test 1.5 {
|
||||
CREATE TABLE x1(x);
|
||||
INSERT INTO x1 VALUES('john'), ('paul'), ('george'), ('ringo');
|
||||
INSERT INTO t1 SELECT x FROM x1;
|
||||
SELECT last_insert_rowid();
|
||||
} {226}
|
||||
|
||||
do_execsql_test 1.6 {
|
||||
INSERT INTO t1(rowid, str) SELECT rowid+10, x FROM x1;
|
||||
SELECT last_insert_rowid();
|
||||
} {14}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -1,710 +0,0 @@
|
||||
/*
|
||||
** 2017-03-08
|
||||
**
|
||||
** 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 SQLite extension implements a functions that compute SHA1 hashes.
|
||||
** Two SQL functions are implemented:
|
||||
**
|
||||
** sha3(X,SIZE)
|
||||
** sha3_query(Y,SIZE)
|
||||
**
|
||||
** The sha3(X) function computes the SHA3 hash of the input X, or NULL if
|
||||
** X is NULL.
|
||||
**
|
||||
** The sha3_query(Y) function evalutes all queries in the SQL statements of Y
|
||||
** and returns a hash of their results.
|
||||
*/
|
||||
#include "sqlite3ext.h"
|
||||
SQLITE_EXTENSION_INIT1
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
typedef sqlite3_uint64 u64;
|
||||
|
||||
/******************************************************************************
|
||||
** The Hash Engine
|
||||
*/
|
||||
/*
|
||||
** Macros to determine whether the machine is big or little endian,
|
||||
** and whether or not that determination is run-time or compile-time.
|
||||
**
|
||||
** For best performance, an attempt is made to guess at the byte-order
|
||||
** using C-preprocessor macros. If that is unsuccessful, or if
|
||||
** -DSHA3_BYTEORDER=0 is set, then byte-order is determined
|
||||
** at run-time.
|
||||
*/
|
||||
#ifndef SHA3_BYTEORDER
|
||||
# if defined(i386) || defined(__i386__) || defined(_M_IX86) || \
|
||||
defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
|
||||
defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \
|
||||
defined(__arm__)
|
||||
# define SHA3_BYTEORDER 1234
|
||||
# elif defined(sparc) || defined(__ppc__)
|
||||
# define SHA3_BYTEORDER 4321
|
||||
# else
|
||||
# define SHA3_BYTEORDER 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** State structure for a SHA3 hash in progress
|
||||
*/
|
||||
typedef struct SHA3Context SHA3Context;
|
||||
struct SHA3Context {
|
||||
union {
|
||||
u64 s[25]; /* Keccak state. 5x5 lines of 64 bits each */
|
||||
unsigned char x[1600]; /* ... or 1600 bytes */
|
||||
} u;
|
||||
unsigned nRate; /* Bytes of input accepted per Keccak iteration */
|
||||
unsigned nLoaded; /* Input bytes loaded into u.x[] so far this cycle */
|
||||
unsigned ixMask; /* Insert next input into u.x[nLoaded^ixMask]. */
|
||||
};
|
||||
|
||||
/*
|
||||
** A single step of the Keccak mixing function for a 1600-bit state
|
||||
*/
|
||||
static void KeccakF1600Step(SHA3Context *p){
|
||||
int i;
|
||||
u64 B0, B1, B2, B3, B4;
|
||||
u64 C0, C1, C2, C3, C4;
|
||||
u64 D0, D1, D2, D3, D4;
|
||||
static const u64 RC[] = {
|
||||
0x0000000000000001ULL, 0x0000000000008082ULL,
|
||||
0x800000000000808aULL, 0x8000000080008000ULL,
|
||||
0x000000000000808bULL, 0x0000000080000001ULL,
|
||||
0x8000000080008081ULL, 0x8000000000008009ULL,
|
||||
0x000000000000008aULL, 0x0000000000000088ULL,
|
||||
0x0000000080008009ULL, 0x000000008000000aULL,
|
||||
0x000000008000808bULL, 0x800000000000008bULL,
|
||||
0x8000000000008089ULL, 0x8000000000008003ULL,
|
||||
0x8000000000008002ULL, 0x8000000000000080ULL,
|
||||
0x000000000000800aULL, 0x800000008000000aULL,
|
||||
0x8000000080008081ULL, 0x8000000000008080ULL,
|
||||
0x0000000080000001ULL, 0x8000000080008008ULL
|
||||
};
|
||||
# define A00 (p->u.s[0])
|
||||
# define A01 (p->u.s[1])
|
||||
# define A02 (p->u.s[2])
|
||||
# define A03 (p->u.s[3])
|
||||
# define A04 (p->u.s[4])
|
||||
# define A10 (p->u.s[5])
|
||||
# define A11 (p->u.s[6])
|
||||
# define A12 (p->u.s[7])
|
||||
# define A13 (p->u.s[8])
|
||||
# define A14 (p->u.s[9])
|
||||
# define A20 (p->u.s[10])
|
||||
# define A21 (p->u.s[11])
|
||||
# define A22 (p->u.s[12])
|
||||
# define A23 (p->u.s[13])
|
||||
# define A24 (p->u.s[14])
|
||||
# define A30 (p->u.s[15])
|
||||
# define A31 (p->u.s[16])
|
||||
# define A32 (p->u.s[17])
|
||||
# define A33 (p->u.s[18])
|
||||
# define A34 (p->u.s[19])
|
||||
# define A40 (p->u.s[20])
|
||||
# define A41 (p->u.s[21])
|
||||
# define A42 (p->u.s[22])
|
||||
# define A43 (p->u.s[23])
|
||||
# define A44 (p->u.s[24])
|
||||
# define ROL64(a,x) ((a<<x)|(a>>(64-x)))
|
||||
|
||||
for(i=0; i<24; i+=4){
|
||||
C0 = A00^A10^A20^A30^A40;
|
||||
C1 = A01^A11^A21^A31^A41;
|
||||
C2 = A02^A12^A22^A32^A42;
|
||||
C3 = A03^A13^A23^A33^A43;
|
||||
C4 = A04^A14^A24^A34^A44;
|
||||
D0 = C4^ROL64(C1, 1);
|
||||
D1 = C0^ROL64(C2, 1);
|
||||
D2 = C1^ROL64(C3, 1);
|
||||
D3 = C2^ROL64(C4, 1);
|
||||
D4 = C3^ROL64(C0, 1);
|
||||
|
||||
B0 = (A00^D0);
|
||||
B1 = ROL64((A11^D1), 44);
|
||||
B2 = ROL64((A22^D2), 43);
|
||||
B3 = ROL64((A33^D3), 21);
|
||||
B4 = ROL64((A44^D4), 14);
|
||||
A00 = B0 ^((~B1)& B2 );
|
||||
A00 ^= RC[i];
|
||||
A11 = B1 ^((~B2)& B3 );
|
||||
A22 = B2 ^((~B3)& B4 );
|
||||
A33 = B3 ^((~B4)& B0 );
|
||||
A44 = B4 ^((~B0)& B1 );
|
||||
|
||||
B2 = ROL64((A20^D0), 3);
|
||||
B3 = ROL64((A31^D1), 45);
|
||||
B4 = ROL64((A42^D2), 61);
|
||||
B0 = ROL64((A03^D3), 28);
|
||||
B1 = ROL64((A14^D4), 20);
|
||||
A20 = B0 ^((~B1)& B2 );
|
||||
A31 = B1 ^((~B2)& B3 );
|
||||
A42 = B2 ^((~B3)& B4 );
|
||||
A03 = B3 ^((~B4)& B0 );
|
||||
A14 = B4 ^((~B0)& B1 );
|
||||
|
||||
B4 = ROL64((A40^D0), 18);
|
||||
B0 = ROL64((A01^D1), 1);
|
||||
B1 = ROL64((A12^D2), 6);
|
||||
B2 = ROL64((A23^D3), 25);
|
||||
B3 = ROL64((A34^D4), 8);
|
||||
A40 = B0 ^((~B1)& B2 );
|
||||
A01 = B1 ^((~B2)& B3 );
|
||||
A12 = B2 ^((~B3)& B4 );
|
||||
A23 = B3 ^((~B4)& B0 );
|
||||
A34 = B4 ^((~B0)& B1 );
|
||||
|
||||
B1 = ROL64((A10^D0), 36);
|
||||
B2 = ROL64((A21^D1), 10);
|
||||
B3 = ROL64((A32^D2), 15);
|
||||
B4 = ROL64((A43^D3), 56);
|
||||
B0 = ROL64((A04^D4), 27);
|
||||
A10 = B0 ^((~B1)& B2 );
|
||||
A21 = B1 ^((~B2)& B3 );
|
||||
A32 = B2 ^((~B3)& B4 );
|
||||
A43 = B3 ^((~B4)& B0 );
|
||||
A04 = B4 ^((~B0)& B1 );
|
||||
|
||||
B3 = ROL64((A30^D0), 41);
|
||||
B4 = ROL64((A41^D1), 2);
|
||||
B0 = ROL64((A02^D2), 62);
|
||||
B1 = ROL64((A13^D3), 55);
|
||||
B2 = ROL64((A24^D4), 39);
|
||||
A30 = B0 ^((~B1)& B2 );
|
||||
A41 = B1 ^((~B2)& B3 );
|
||||
A02 = B2 ^((~B3)& B4 );
|
||||
A13 = B3 ^((~B4)& B0 );
|
||||
A24 = B4 ^((~B0)& B1 );
|
||||
|
||||
C0 = A00^A20^A40^A10^A30;
|
||||
C1 = A11^A31^A01^A21^A41;
|
||||
C2 = A22^A42^A12^A32^A02;
|
||||
C3 = A33^A03^A23^A43^A13;
|
||||
C4 = A44^A14^A34^A04^A24;
|
||||
D0 = C4^ROL64(C1, 1);
|
||||
D1 = C0^ROL64(C2, 1);
|
||||
D2 = C1^ROL64(C3, 1);
|
||||
D3 = C2^ROL64(C4, 1);
|
||||
D4 = C3^ROL64(C0, 1);
|
||||
|
||||
B0 = (A00^D0);
|
||||
B1 = ROL64((A31^D1), 44);
|
||||
B2 = ROL64((A12^D2), 43);
|
||||
B3 = ROL64((A43^D3), 21);
|
||||
B4 = ROL64((A24^D4), 14);
|
||||
A00 = B0 ^((~B1)& B2 );
|
||||
A00 ^= RC[i+1];
|
||||
A31 = B1 ^((~B2)& B3 );
|
||||
A12 = B2 ^((~B3)& B4 );
|
||||
A43 = B3 ^((~B4)& B0 );
|
||||
A24 = B4 ^((~B0)& B1 );
|
||||
|
||||
B2 = ROL64((A40^D0), 3);
|
||||
B3 = ROL64((A21^D1), 45);
|
||||
B4 = ROL64((A02^D2), 61);
|
||||
B0 = ROL64((A33^D3), 28);
|
||||
B1 = ROL64((A14^D4), 20);
|
||||
A40 = B0 ^((~B1)& B2 );
|
||||
A21 = B1 ^((~B2)& B3 );
|
||||
A02 = B2 ^((~B3)& B4 );
|
||||
A33 = B3 ^((~B4)& B0 );
|
||||
A14 = B4 ^((~B0)& B1 );
|
||||
|
||||
B4 = ROL64((A30^D0), 18);
|
||||
B0 = ROL64((A11^D1), 1);
|
||||
B1 = ROL64((A42^D2), 6);
|
||||
B2 = ROL64((A23^D3), 25);
|
||||
B3 = ROL64((A04^D4), 8);
|
||||
A30 = B0 ^((~B1)& B2 );
|
||||
A11 = B1 ^((~B2)& B3 );
|
||||
A42 = B2 ^((~B3)& B4 );
|
||||
A23 = B3 ^((~B4)& B0 );
|
||||
A04 = B4 ^((~B0)& B1 );
|
||||
|
||||
B1 = ROL64((A20^D0), 36);
|
||||
B2 = ROL64((A01^D1), 10);
|
||||
B3 = ROL64((A32^D2), 15);
|
||||
B4 = ROL64((A13^D3), 56);
|
||||
B0 = ROL64((A44^D4), 27);
|
||||
A20 = B0 ^((~B1)& B2 );
|
||||
A01 = B1 ^((~B2)& B3 );
|
||||
A32 = B2 ^((~B3)& B4 );
|
||||
A13 = B3 ^((~B4)& B0 );
|
||||
A44 = B4 ^((~B0)& B1 );
|
||||
|
||||
B3 = ROL64((A10^D0), 41);
|
||||
B4 = ROL64((A41^D1), 2);
|
||||
B0 = ROL64((A22^D2), 62);
|
||||
B1 = ROL64((A03^D3), 55);
|
||||
B2 = ROL64((A34^D4), 39);
|
||||
A10 = B0 ^((~B1)& B2 );
|
||||
A41 = B1 ^((~B2)& B3 );
|
||||
A22 = B2 ^((~B3)& B4 );
|
||||
A03 = B3 ^((~B4)& B0 );
|
||||
A34 = B4 ^((~B0)& B1 );
|
||||
|
||||
C0 = A00^A40^A30^A20^A10;
|
||||
C1 = A31^A21^A11^A01^A41;
|
||||
C2 = A12^A02^A42^A32^A22;
|
||||
C3 = A43^A33^A23^A13^A03;
|
||||
C4 = A24^A14^A04^A44^A34;
|
||||
D0 = C4^ROL64(C1, 1);
|
||||
D1 = C0^ROL64(C2, 1);
|
||||
D2 = C1^ROL64(C3, 1);
|
||||
D3 = C2^ROL64(C4, 1);
|
||||
D4 = C3^ROL64(C0, 1);
|
||||
|
||||
B0 = (A00^D0);
|
||||
B1 = ROL64((A21^D1), 44);
|
||||
B2 = ROL64((A42^D2), 43);
|
||||
B3 = ROL64((A13^D3), 21);
|
||||
B4 = ROL64((A34^D4), 14);
|
||||
A00 = B0 ^((~B1)& B2 );
|
||||
A00 ^= RC[i+2];
|
||||
A21 = B1 ^((~B2)& B3 );
|
||||
A42 = B2 ^((~B3)& B4 );
|
||||
A13 = B3 ^((~B4)& B0 );
|
||||
A34 = B4 ^((~B0)& B1 );
|
||||
|
||||
B2 = ROL64((A30^D0), 3);
|
||||
B3 = ROL64((A01^D1), 45);
|
||||
B4 = ROL64((A22^D2), 61);
|
||||
B0 = ROL64((A43^D3), 28);
|
||||
B1 = ROL64((A14^D4), 20);
|
||||
A30 = B0 ^((~B1)& B2 );
|
||||
A01 = B1 ^((~B2)& B3 );
|
||||
A22 = B2 ^((~B3)& B4 );
|
||||
A43 = B3 ^((~B4)& B0 );
|
||||
A14 = B4 ^((~B0)& B1 );
|
||||
|
||||
B4 = ROL64((A10^D0), 18);
|
||||
B0 = ROL64((A31^D1), 1);
|
||||
B1 = ROL64((A02^D2), 6);
|
||||
B2 = ROL64((A23^D3), 25);
|
||||
B3 = ROL64((A44^D4), 8);
|
||||
A10 = B0 ^((~B1)& B2 );
|
||||
A31 = B1 ^((~B2)& B3 );
|
||||
A02 = B2 ^((~B3)& B4 );
|
||||
A23 = B3 ^((~B4)& B0 );
|
||||
A44 = B4 ^((~B0)& B1 );
|
||||
|
||||
B1 = ROL64((A40^D0), 36);
|
||||
B2 = ROL64((A11^D1), 10);
|
||||
B3 = ROL64((A32^D2), 15);
|
||||
B4 = ROL64((A03^D3), 56);
|
||||
B0 = ROL64((A24^D4), 27);
|
||||
A40 = B0 ^((~B1)& B2 );
|
||||
A11 = B1 ^((~B2)& B3 );
|
||||
A32 = B2 ^((~B3)& B4 );
|
||||
A03 = B3 ^((~B4)& B0 );
|
||||
A24 = B4 ^((~B0)& B1 );
|
||||
|
||||
B3 = ROL64((A20^D0), 41);
|
||||
B4 = ROL64((A41^D1), 2);
|
||||
B0 = ROL64((A12^D2), 62);
|
||||
B1 = ROL64((A33^D3), 55);
|
||||
B2 = ROL64((A04^D4), 39);
|
||||
A20 = B0 ^((~B1)& B2 );
|
||||
A41 = B1 ^((~B2)& B3 );
|
||||
A12 = B2 ^((~B3)& B4 );
|
||||
A33 = B3 ^((~B4)& B0 );
|
||||
A04 = B4 ^((~B0)& B1 );
|
||||
|
||||
C0 = A00^A30^A10^A40^A20;
|
||||
C1 = A21^A01^A31^A11^A41;
|
||||
C2 = A42^A22^A02^A32^A12;
|
||||
C3 = A13^A43^A23^A03^A33;
|
||||
C4 = A34^A14^A44^A24^A04;
|
||||
D0 = C4^ROL64(C1, 1);
|
||||
D1 = C0^ROL64(C2, 1);
|
||||
D2 = C1^ROL64(C3, 1);
|
||||
D3 = C2^ROL64(C4, 1);
|
||||
D4 = C3^ROL64(C0, 1);
|
||||
|
||||
B0 = (A00^D0);
|
||||
B1 = ROL64((A01^D1), 44);
|
||||
B2 = ROL64((A02^D2), 43);
|
||||
B3 = ROL64((A03^D3), 21);
|
||||
B4 = ROL64((A04^D4), 14);
|
||||
A00 = B0 ^((~B1)& B2 );
|
||||
A00 ^= RC[i+3];
|
||||
A01 = B1 ^((~B2)& B3 );
|
||||
A02 = B2 ^((~B3)& B4 );
|
||||
A03 = B3 ^((~B4)& B0 );
|
||||
A04 = B4 ^((~B0)& B1 );
|
||||
|
||||
B2 = ROL64((A10^D0), 3);
|
||||
B3 = ROL64((A11^D1), 45);
|
||||
B4 = ROL64((A12^D2), 61);
|
||||
B0 = ROL64((A13^D3), 28);
|
||||
B1 = ROL64((A14^D4), 20);
|
||||
A10 = B0 ^((~B1)& B2 );
|
||||
A11 = B1 ^((~B2)& B3 );
|
||||
A12 = B2 ^((~B3)& B4 );
|
||||
A13 = B3 ^((~B4)& B0 );
|
||||
A14 = B4 ^((~B0)& B1 );
|
||||
|
||||
B4 = ROL64((A20^D0), 18);
|
||||
B0 = ROL64((A21^D1), 1);
|
||||
B1 = ROL64((A22^D2), 6);
|
||||
B2 = ROL64((A23^D3), 25);
|
||||
B3 = ROL64((A24^D4), 8);
|
||||
A20 = B0 ^((~B1)& B2 );
|
||||
A21 = B1 ^((~B2)& B3 );
|
||||
A22 = B2 ^((~B3)& B4 );
|
||||
A23 = B3 ^((~B4)& B0 );
|
||||
A24 = B4 ^((~B0)& B1 );
|
||||
|
||||
B1 = ROL64((A30^D0), 36);
|
||||
B2 = ROL64((A31^D1), 10);
|
||||
B3 = ROL64((A32^D2), 15);
|
||||
B4 = ROL64((A33^D3), 56);
|
||||
B0 = ROL64((A34^D4), 27);
|
||||
A30 = B0 ^((~B1)& B2 );
|
||||
A31 = B1 ^((~B2)& B3 );
|
||||
A32 = B2 ^((~B3)& B4 );
|
||||
A33 = B3 ^((~B4)& B0 );
|
||||
A34 = B4 ^((~B0)& B1 );
|
||||
|
||||
B3 = ROL64((A40^D0), 41);
|
||||
B4 = ROL64((A41^D1), 2);
|
||||
B0 = ROL64((A42^D2), 62);
|
||||
B1 = ROL64((A43^D3), 55);
|
||||
B2 = ROL64((A44^D4), 39);
|
||||
A40 = B0 ^((~B1)& B2 );
|
||||
A41 = B1 ^((~B2)& B3 );
|
||||
A42 = B2 ^((~B3)& B4 );
|
||||
A43 = B3 ^((~B4)& B0 );
|
||||
A44 = B4 ^((~B0)& B1 );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Initialize a new hash. iSize determines the size of the hash
|
||||
** in bits and should be one of 224, 256, 384, or 512. Or iSize
|
||||
** can be zero to use the default hash size of 256 bits.
|
||||
*/
|
||||
static void SHA3Init(SHA3Context *p, int iSize){
|
||||
memset(p, 0, sizeof(*p));
|
||||
if( iSize>=128 && iSize<=512 ){
|
||||
p->nRate = (1600 - ((iSize + 31)&~31)*2)/8;
|
||||
}else{
|
||||
p->nRate = (1600 - 2*256)/8;
|
||||
}
|
||||
#if SHA3_BYTEORDER==1234
|
||||
/* Known to be little-endian at compile-time. No-op */
|
||||
#elif SHA3_BYTEORDER==4321
|
||||
p->ixMask = 7; /* Big-endian */
|
||||
#else
|
||||
{
|
||||
static unsigned int one = 1;
|
||||
if( 1==*(unsigned char*)&one ){
|
||||
/* Little endian. No byte swapping. */
|
||||
p->ixMask = 0;
|
||||
}else{
|
||||
/* Big endian. Byte swap. */
|
||||
p->ixMask = 7;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
** Make consecutive calls to the SHA3Update function to add new content
|
||||
** to the hash
|
||||
*/
|
||||
static void SHA3Update(
|
||||
SHA3Context *p,
|
||||
const unsigned char *aData,
|
||||
unsigned int nData
|
||||
){
|
||||
unsigned int i = 0;
|
||||
#if SHA3_BYTEORDER==1234
|
||||
if( (p->nLoaded % 8)==0 && ((aData - (const unsigned char*)0)&7)==0 ){
|
||||
for(; i+7<nData; i+=8){
|
||||
p->u.s[p->nLoaded/8] ^= *(u64*)&aData[i];
|
||||
p->nLoaded += 8;
|
||||
if( p->nLoaded>=p->nRate ){
|
||||
KeccakF1600Step(p);
|
||||
p->nLoaded = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
for(; i<nData; i++){
|
||||
#if SHA3_BYTEORDER==1234
|
||||
p->u.x[p->nLoaded] ^= aData[i];
|
||||
#elif SHA3_BYTEORDER==4321
|
||||
p->u.x[p->nLoaded^0x07] ^= aData[i];
|
||||
#else
|
||||
p->u.x[p->nLoaded^p->ixMask] ^= aData[i];
|
||||
#endif
|
||||
p->nLoaded++;
|
||||
if( p->nLoaded==p->nRate ){
|
||||
KeccakF1600Step(p);
|
||||
p->nLoaded = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** After all content has been added, invoke SHA3Final() to compute
|
||||
** the final hash. The function returns a pointer to the binary
|
||||
** hash value.
|
||||
*/
|
||||
static unsigned char *SHA3Final(SHA3Context *p){
|
||||
unsigned int i;
|
||||
if( p->nLoaded==p->nRate-1 ){
|
||||
const unsigned char c1 = 0x86;
|
||||
SHA3Update(p, &c1, 1);
|
||||
}else{
|
||||
const unsigned char c2 = 0x06;
|
||||
const unsigned char c3 = 0x80;
|
||||
SHA3Update(p, &c2, 1);
|
||||
p->nLoaded = p->nRate - 1;
|
||||
SHA3Update(p, &c3, 1);
|
||||
}
|
||||
for(i=0; i<p->nRate; i++){
|
||||
p->u.x[i+p->nRate] = p->u.x[i^p->ixMask];
|
||||
}
|
||||
return &p->u.x[p->nRate];
|
||||
}
|
||||
/* End of the hashing logic
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
** Implementation of the sha3(X,SIZE) function.
|
||||
**
|
||||
** Return a BLOB which is the SIZE-bit SHA3 hash of X. The default
|
||||
** size is 256. If X is a BLOB, it is hashed as is.
|
||||
** For all other non-NULL types of input, X is converted into a UTF-8 string
|
||||
** and the string is hashed without the trailing 0x00 terminator. The hash
|
||||
** of a NULL value is NULL.
|
||||
*/
|
||||
static void sha3Func(
|
||||
sqlite3_context *context,
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
SHA3Context cx;
|
||||
int eType = sqlite3_value_type(argv[0]);
|
||||
int nByte = sqlite3_value_bytes(argv[0]);
|
||||
int iSize;
|
||||
if( argc==1 ){
|
||||
iSize = 256;
|
||||
}else{
|
||||
iSize = sqlite3_value_int(argv[1]);
|
||||
if( iSize!=224 && iSize!=256 && iSize!=384 && iSize!=512 ){
|
||||
sqlite3_result_error(context, "SHA3 size should be one of: 224 256 "
|
||||
"384 512", -1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if( eType==SQLITE_NULL ) return;
|
||||
SHA3Init(&cx, iSize);
|
||||
if( eType==SQLITE_BLOB ){
|
||||
SHA3Update(&cx, sqlite3_value_blob(argv[0]), nByte);
|
||||
}else{
|
||||
SHA3Update(&cx, sqlite3_value_text(argv[0]), nByte);
|
||||
}
|
||||
sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT);
|
||||
}
|
||||
|
||||
/* Compute a string using sqlite3_vsnprintf() with a maximum length
|
||||
** of 50 bytes and add it to the hash.
|
||||
*/
|
||||
static void hash_step_vformat(
|
||||
SHA3Context *p, /* Add content to this context */
|
||||
const char *zFormat,
|
||||
...
|
||||
){
|
||||
va_list ap;
|
||||
int n;
|
||||
char zBuf[50];
|
||||
va_start(ap, zFormat);
|
||||
sqlite3_vsnprintf(sizeof(zBuf),zBuf,zFormat,ap);
|
||||
va_end(ap);
|
||||
n = (int)strlen(zBuf);
|
||||
SHA3Update(p, (unsigned char*)zBuf, n);
|
||||
}
|
||||
|
||||
/*
|
||||
** Implementation of the sha3_query(SQL,SIZE) function.
|
||||
**
|
||||
** This function compiles and runs the SQL statement(s) given in the
|
||||
** argument. The results are hashed using a SIZE-bit SHA3. The default
|
||||
** size is 256.
|
||||
**
|
||||
** The format of the byte stream that is hashed is summarized as follows:
|
||||
**
|
||||
** S<n>:<sql>
|
||||
** R
|
||||
** N
|
||||
** I<int>
|
||||
** F<ieee-float>
|
||||
** B<size>:<bytes>
|
||||
** T<size>:<text>
|
||||
**
|
||||
** <sql> is the original SQL text for each statement run and <n> is
|
||||
** the size of that text. The SQL text is UTF-8. A single R character
|
||||
** occurs before the start of each row. N means a NULL value.
|
||||
** I mean an 8-byte little-endian integer <int>. F is a floating point
|
||||
** number with an 8-byte little-endian IEEE floating point value <ieee-float>.
|
||||
** B means blobs of <size> bytes. T means text rendered as <size>
|
||||
** bytes of UTF-8. The <n> and <size> values are expressed as an ASCII
|
||||
** text integers.
|
||||
**
|
||||
** For each SQL statement in the X input, there is one S segment. Each
|
||||
** S segment is followed by zero or more R segments, one for each row in the
|
||||
** result set. After each R, there are one or more N, I, F, B, or T segments,
|
||||
** one for each column in the result set. Segments are concatentated directly
|
||||
** with no delimiters of any kind.
|
||||
*/
|
||||
static void sha3QueryFunc(
|
||||
sqlite3_context *context,
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
sqlite3 *db = sqlite3_context_db_handle(context);
|
||||
const char *zSql = (const char*)sqlite3_value_text(argv[0]);
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
int nCol; /* Number of columns in the result set */
|
||||
int i; /* Loop counter */
|
||||
int rc;
|
||||
int n;
|
||||
const char *z;
|
||||
SHA3Context cx;
|
||||
int iSize;
|
||||
|
||||
if( argc==1 ){
|
||||
iSize = 256;
|
||||
}else{
|
||||
iSize = sqlite3_value_int(argv[1]);
|
||||
if( iSize!=224 && iSize!=256 && iSize!=384 && iSize!=512 ){
|
||||
sqlite3_result_error(context, "SHA3 size should be one of: 224 256 "
|
||||
"384 512", -1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if( zSql==0 ) return;
|
||||
SHA3Init(&cx, iSize);
|
||||
while( zSql[0] ){
|
||||
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql);
|
||||
if( rc ){
|
||||
char *zMsg = sqlite3_mprintf("error SQL statement [%s]: %s",
|
||||
zSql, sqlite3_errmsg(db));
|
||||
sqlite3_finalize(pStmt);
|
||||
sqlite3_result_error(context, zMsg, -1);
|
||||
sqlite3_free(zMsg);
|
||||
return;
|
||||
}
|
||||
if( !sqlite3_stmt_readonly(pStmt) ){
|
||||
char *zMsg = sqlite3_mprintf("non-query: [%s]", sqlite3_sql(pStmt));
|
||||
sqlite3_finalize(pStmt);
|
||||
sqlite3_result_error(context, zMsg, -1);
|
||||
sqlite3_free(zMsg);
|
||||
return;
|
||||
}
|
||||
nCol = sqlite3_column_count(pStmt);
|
||||
z = sqlite3_sql(pStmt);
|
||||
n = (int)strlen(z);
|
||||
hash_step_vformat(&cx,"S%d:",n);
|
||||
SHA3Update(&cx,(unsigned char*)z,n);
|
||||
|
||||
/* Compute a hash over the result of the query */
|
||||
while( SQLITE_ROW==sqlite3_step(pStmt) ){
|
||||
SHA3Update(&cx,(const unsigned char*)"R",1);
|
||||
for(i=0; i<nCol; i++){
|
||||
switch( sqlite3_column_type(pStmt,i) ){
|
||||
case SQLITE_NULL: {
|
||||
SHA3Update(&cx, (const unsigned char*)"N",1);
|
||||
break;
|
||||
}
|
||||
case SQLITE_INTEGER: {
|
||||
sqlite3_uint64 u;
|
||||
int j;
|
||||
unsigned char x[9];
|
||||
sqlite3_int64 v = sqlite3_column_int64(pStmt,i);
|
||||
memcpy(&u, &v, 8);
|
||||
for(j=8; j>=1; j--){
|
||||
x[j] = u & 0xff;
|
||||
u >>= 8;
|
||||
}
|
||||
x[0] = 'I';
|
||||
SHA3Update(&cx, x, 9);
|
||||
break;
|
||||
}
|
||||
case SQLITE_FLOAT: {
|
||||
sqlite3_uint64 u;
|
||||
int j;
|
||||
unsigned char x[9];
|
||||
double r = sqlite3_column_double(pStmt,i);
|
||||
memcpy(&u, &r, 8);
|
||||
for(j=8; j>=1; j--){
|
||||
x[j] = u & 0xff;
|
||||
u >>= 8;
|
||||
}
|
||||
x[0] = 'F';
|
||||
SHA3Update(&cx,x,9);
|
||||
break;
|
||||
}
|
||||
case SQLITE_TEXT: {
|
||||
int n2 = sqlite3_column_bytes(pStmt, i);
|
||||
const unsigned char *z2 = sqlite3_column_text(pStmt, i);
|
||||
hash_step_vformat(&cx,"T%d:",n2);
|
||||
SHA3Update(&cx, z2, n2);
|
||||
break;
|
||||
}
|
||||
case SQLITE_BLOB: {
|
||||
int n2 = sqlite3_column_bytes(pStmt, i);
|
||||
const unsigned char *z2 = sqlite3_column_blob(pStmt, i);
|
||||
hash_step_vformat(&cx,"B%d:",n2);
|
||||
SHA3Update(&cx, z2, n2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sqlite3_finalize(pStmt);
|
||||
}
|
||||
sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT);
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
int sqlite3_shathree_init(
|
||||
sqlite3 *db,
|
||||
char **pzErrMsg,
|
||||
const sqlite3_api_routines *pApi
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
SQLITE_EXTENSION_INIT2(pApi);
|
||||
(void)pzErrMsg; /* Unused parameter */
|
||||
rc = sqlite3_create_function(db, "sha3", 1, SQLITE_UTF8, 0,
|
||||
sha3Func, 0, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3_create_function(db, "sha3", 2, SQLITE_UTF8, 0,
|
||||
sha3Func, 0, 0);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3_create_function(db, "sha3_query", 1, SQLITE_UTF8, 0,
|
||||
sha3QueryFunc, 0, 0);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3_create_function(db, "sha3_query", 2, SQLITE_UTF8, 0,
|
||||
sha3QueryFunc, 0, 0);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
# 2017 March 02
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
|
||||
if {![info exists testdir]} {
|
||||
set testdir [file join [file dirname [info script]] .. .. test]
|
||||
}
|
||||
source $testdir/tester.tcl
|
||||
set ::testprefix rbucrash2
|
||||
|
||||
db close
|
||||
forcedelete test.db-oal rbu.db
|
||||
sqlite3_shutdown
|
||||
sqlite3_config_uri 1
|
||||
reset_db
|
||||
|
||||
# Set up a target database and an rbu update database. The target
|
||||
# db is the usual "test.db", the rbu db is "test.db2".
|
||||
#
|
||||
forcedelete test.db2
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(a, b, c, PRIMARY KEY(a), UNIQUE(b));
|
||||
INSERT INTO t1 VALUES(1, 2, 3);
|
||||
INSERT INTO t1 VALUES(4, 5, 6);
|
||||
INSERT INTO t1 VALUES(7, 8, 9);
|
||||
|
||||
ATTACH 'test.db2' AS rbu;
|
||||
CREATE TABLE rbu.data_t1(a, b, c, rbu_control);
|
||||
INSERT INTO data_t1 VALUES('one', randomblob(3500), NULL, 0);
|
||||
INSERT INTO data_t1 VALUES('two', randomblob(3500), NULL, 0);
|
||||
INSERT INTO data_t1 VALUES('three', randomblob(3500), NULL, 0);
|
||||
INSERT INTO data_t1 VALUES('four', randomblob(3500), NULL, 0);
|
||||
INSERT INTO data_t1 VALUES('five', randomblob(3500), NULL, 0);
|
||||
INSERT INTO data_t1 VALUES('six', randomblob(3500), NULL, 0);
|
||||
}
|
||||
db_save_and_close
|
||||
|
||||
proc do_rbu_crash_test2 {tn script} {
|
||||
|
||||
foreach {f blksz} {
|
||||
test.db 512
|
||||
test.db2 512
|
||||
test.db 4096
|
||||
test.db2 4096
|
||||
} {
|
||||
set bDone 0
|
||||
for {set iDelay 1} {$bDone==0} {incr iDelay} {
|
||||
forcedelete test.db2 test.db2-journal test.db test.db-oal test.db-wal
|
||||
db_restore
|
||||
|
||||
set res [
|
||||
crashsql -file $f -delay $iDelay -tclbody $script -dflt 1 -opendb {} \
|
||||
-blocksize $blksz {}
|
||||
]
|
||||
|
||||
set bDone 1
|
||||
if {$res == "1 {child process exited abnormally}"} {
|
||||
set bDone 0
|
||||
} elseif {$res != "0 {}"} {
|
||||
error "unexected catchsql result: $res"
|
||||
}
|
||||
|
||||
sqlite3rbu rbu test.db test.db2
|
||||
while {[rbu step]=="SQLITE_OK"} {}
|
||||
rbu close
|
||||
|
||||
sqlite3 db test.db
|
||||
do_execsql_test $tn.delay=$iDelay.f=$f.blksz=$blksz {
|
||||
PRAGMA integrity_check;
|
||||
} {ok}
|
||||
db close
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for {set x 1} {$x < 10} {incr x} {
|
||||
do_rbu_crash_test2 1.$x {
|
||||
sqlite3rbu rbu test.db test.db2
|
||||
while {[rbu step]=="SQLITE_OK"} {
|
||||
rbu savestate
|
||||
}
|
||||
rbu close
|
||||
}
|
||||
}
|
||||
|
||||
for {set x 1} {$x < 2} {incr x} {
|
||||
do_rbu_crash_test2 2.$x {
|
||||
sqlite3rbu rbu test.db test.db2
|
||||
while {[rbu step]=="SQLITE_OK"} {
|
||||
rbu close
|
||||
sqlite3rbu rbu test.db test.db2
|
||||
}
|
||||
rbu close
|
||||
}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -40,7 +40,6 @@ proc create_rbu1 {filename} {
|
||||
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
PRAGMA page_size = 4096;
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
|
||||
}
|
||||
|
||||
@@ -267,7 +266,6 @@ foreach bReopen {0 1} {
|
||||
do_test 3.$bReopen.1.0 {
|
||||
reset_db
|
||||
execsql {
|
||||
PRAGMA page_size = 4096;
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
|
||||
CREATE TABLE t2(a INTEGER PRIMARY KEY, b);
|
||||
CREATE TABLE t3(a INTEGER PRIMARY KEY, b);
|
||||
|
||||
+3
-50
@@ -356,7 +356,6 @@ struct sqlite3rbu {
|
||||
RbuObjIter objiter; /* Iterator for skipping through tbl/idx */
|
||||
const char *zVfsName; /* Name of automatically created rbu vfs */
|
||||
rbu_file *pTargetFd; /* File handle open on target db */
|
||||
int nPagePerSector; /* Pages per sector for pTargetFd */
|
||||
i64 iOalSz;
|
||||
i64 nPhaseOneStep;
|
||||
|
||||
@@ -2621,23 +2620,6 @@ static void rbuSetupCheckpoint(sqlite3rbu *p, RbuState *pState){
|
||||
if( p->nFrame==0 || (pState && pState->iWalCksum!=p->iWalCksum) ){
|
||||
p->rc = SQLITE_DONE;
|
||||
p->eStage = RBU_STAGE_DONE;
|
||||
}else{
|
||||
int nSectorSize;
|
||||
sqlite3_file *pDb = p->pTargetFd->pReal;
|
||||
sqlite3_file *pWal = p->pTargetFd->pWalFd->pReal;
|
||||
assert( p->nPagePerSector==0 );
|
||||
nSectorSize = pDb->pMethods->xSectorSize(pDb);
|
||||
if( nSectorSize>p->pgsz ){
|
||||
p->nPagePerSector = nSectorSize / p->pgsz;
|
||||
}else{
|
||||
p->nPagePerSector = 1;
|
||||
}
|
||||
|
||||
/* Call xSync() on the wal file. This causes SQLite to sync the
|
||||
** directory in which the target database and the wal file reside, in
|
||||
** case it has not been synced since the rename() call in
|
||||
** rbuMoveOalFile(). */
|
||||
p->rc = pWal->pMethods->xSync(pWal, SQLITE_SYNC_NORMAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3293,26 +3275,9 @@ int sqlite3rbu_step(sqlite3rbu *p){
|
||||
p->rc = SQLITE_DONE;
|
||||
}
|
||||
}else{
|
||||
/* At one point the following block copied a single frame from the
|
||||
** wal file to the database file. So that one call to sqlite3rbu_step()
|
||||
** checkpointed a single frame.
|
||||
**
|
||||
** However, if the sector-size is larger than the page-size, and the
|
||||
** application calls sqlite3rbu_savestate() or close() immediately
|
||||
** after this step, then rbu_step() again, then a power failure occurs,
|
||||
** then the database page written here may be damaged. Work around
|
||||
** this by checkpointing frames until the next page in the aFrame[]
|
||||
** lies on a different disk sector to the current one. */
|
||||
u32 iSector;
|
||||
do{
|
||||
RbuFrame *pFrame = &p->aFrame[p->nStep];
|
||||
iSector = (pFrame->iDbPage-1) / p->nPagePerSector;
|
||||
rbuCheckpointFrame(p, pFrame);
|
||||
p->nStep++;
|
||||
}while( p->nStep<p->nFrame
|
||||
&& iSector==((p->aFrame[p->nStep].iDbPage-1) / p->nPagePerSector)
|
||||
&& p->rc==SQLITE_OK
|
||||
);
|
||||
RbuFrame *pFrame = &p->aFrame[p->nStep];
|
||||
rbuCheckpointFrame(p, pFrame);
|
||||
p->nStep++;
|
||||
}
|
||||
p->nProgress++;
|
||||
}
|
||||
@@ -3753,12 +3718,6 @@ int sqlite3rbu_close(sqlite3rbu *p, char **pzErrmsg){
|
||||
p->rc = sqlite3_exec(p->dbMain, "COMMIT", 0, 0, &p->zErrmsg);
|
||||
}
|
||||
|
||||
/* Sync the db file if currently doing an incremental checkpoint */
|
||||
if( p->rc==SQLITE_OK && p->eStage==RBU_STAGE_CKPT ){
|
||||
sqlite3_file *pDb = p->pTargetFd->pReal;
|
||||
p->rc = pDb->pMethods->xSync(pDb, SQLITE_SYNC_NORMAL);
|
||||
}
|
||||
|
||||
rbuSaveState(p, p->eStage);
|
||||
|
||||
if( p->rc==SQLITE_OK && p->eStage==RBU_STAGE_OAL ){
|
||||
@@ -3883,12 +3842,6 @@ int sqlite3rbu_savestate(sqlite3rbu *p){
|
||||
if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbMain, "COMMIT", 0, 0, 0);
|
||||
}
|
||||
|
||||
/* Sync the db file */
|
||||
if( rc==SQLITE_OK && p->eStage==RBU_STAGE_CKPT ){
|
||||
sqlite3_file *pDb = p->pTargetFd->pReal;
|
||||
rc = pDb->pMethods->xSync(pDb, SQLITE_SYNC_NORMAL);
|
||||
}
|
||||
|
||||
p->rc = rc;
|
||||
rbuSaveState(p, p->eStage);
|
||||
rc = p->rc;
|
||||
|
||||
+59
-30
@@ -68,7 +68,6 @@
|
||||
#ifndef SQLITE_AMALGAMATION
|
||||
#include "sqlite3rtree.h"
|
||||
typedef sqlite3_int64 i64;
|
||||
typedef sqlite3_uint64 u64;
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned int u32;
|
||||
@@ -368,19 +367,25 @@ struct RtreeMatchArg {
|
||||
# define MIN(x,y) ((x) > (y) ? (y) : (x))
|
||||
#endif
|
||||
|
||||
/* What version of GCC is being used. 0 means GCC is not being used .
|
||||
** Note that the GCC_VERSION macro will also be set correctly when using
|
||||
** clang, since clang works hard to be gcc compatible. So the gcc
|
||||
** optimizations will also work when compiling with clang.
|
||||
*/
|
||||
/* What version of GCC is being used. 0 means GCC is not being used */
|
||||
#ifndef GCC_VERSION
|
||||
#if defined(__GNUC__) && !defined(SQLITE_DISABLE_INTRINSIC)
|
||||
#ifdef __GNUC__
|
||||
# define GCC_VERSION (__GNUC__*1000000+__GNUC_MINOR__*1000+__GNUC_PATCHLEVEL__)
|
||||
#else
|
||||
# define GCC_VERSION 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* What version of CLANG is being used. 0 means CLANG is not being used */
|
||||
#ifndef CLANG_VERSION
|
||||
#if defined(__clang__) && !defined(_WIN32)
|
||||
# define CLANG_VERSION \
|
||||
(__clang_major__*1000000+__clang_minor__*1000+__clang_patchlevel__)
|
||||
#else
|
||||
# define CLANG_VERSION 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* The testcase() macro should already be defined in the amalgamation. If
|
||||
** it is not, make it a no-op.
|
||||
*/
|
||||
@@ -398,22 +403,23 @@ struct RtreeMatchArg {
|
||||
** at run-time.
|
||||
*/
|
||||
#ifndef SQLITE_BYTEORDER
|
||||
#if defined(i386) || defined(__i386__) || defined(_M_IX86) || \
|
||||
defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
|
||||
defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \
|
||||
defined(__arm__)
|
||||
#if (defined(i386) || defined(__i386__) || defined(_M_IX86) || \
|
||||
defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
|
||||
defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \
|
||||
defined(__arm__)) && !defined(SQLITE_RUNTIME_BYTEORDER)
|
||||
# define SQLITE_BYTEORDER 1234
|
||||
#elif defined(sparc) || defined(__ppc__)
|
||||
# define SQLITE_BYTEORDER 4321
|
||||
#else
|
||||
# define SQLITE_BYTEORDER 0 /* 0 means "unknown at compile-time" */
|
||||
#endif
|
||||
#if (defined(sparc) || defined(__ppc__)) \
|
||||
&& !defined(SQLITE_RUNTIME_BYTEORDER)
|
||||
# define SQLITE_BYTEORDER 4321
|
||||
#endif
|
||||
# define SQLITE_BYTEORDER 0 /* 0 means "unknown at compile-time" */
|
||||
#endif
|
||||
|
||||
|
||||
/* What version of MSVC is being used. 0 means MSVC is not being used */
|
||||
#ifndef MSVC_VERSION
|
||||
#if defined(_MSC_VER) && !defined(SQLITE_DISABLE_INTRINSIC)
|
||||
#if defined(_MSC_VER)
|
||||
# define MSVC_VERSION _MSC_VER
|
||||
#else
|
||||
# define MSVC_VERSION 0
|
||||
@@ -431,8 +437,11 @@ static void readCoord(u8 *p, RtreeCoord *pCoord){
|
||||
assert( ((((char*)p) - (char*)0)&3)==0 ); /* p is always 4-byte aligned */
|
||||
#if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
|
||||
pCoord->u = _byteswap_ulong(*(u32*)p);
|
||||
#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
|
||||
#elif SQLITE_BYTEORDER==1234 && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000)
|
||||
pCoord->u = __builtin_bswap32(*(u32*)p);
|
||||
#elif SQLITE_BYTEORDER==1234
|
||||
pCoord->u = ((pCoord->u>>24)&0xff)|((pCoord->u>>8)&0xff00)|
|
||||
((pCoord->u&0xff)<<24)|((pCoord->u&0xff00)<<8);
|
||||
#elif SQLITE_BYTEORDER==4321
|
||||
pCoord->u = *(u32*)p;
|
||||
#else
|
||||
@@ -447,17 +456,21 @@ static void readCoord(u8 *p, RtreeCoord *pCoord){
|
||||
static i64 readInt64(u8 *p){
|
||||
#if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
|
||||
u64 x;
|
||||
testcase( ((((char*)p) - (char*)0)&7)!=0 ); /* not always 8-byte aligned */
|
||||
memcpy(&x, p, 8);
|
||||
return (i64)_byteswap_uint64(x);
|
||||
#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
|
||||
#elif SQLITE_BYTEORDER==1234 && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000)
|
||||
u64 x;
|
||||
testcase( ((((char*)p) - (char*)0)&7)!=0 ); /* not always 8-byte aligned */
|
||||
memcpy(&x, p, 8);
|
||||
return (i64)__builtin_bswap64(x);
|
||||
#elif SQLITE_BYTEORDER==4321
|
||||
i64 x;
|
||||
testcase( ((((char*)p) - (char*)0)&7)!=0 ); /* not always 8-byte aligned */
|
||||
memcpy(&x, p, 8);
|
||||
return x;
|
||||
#else
|
||||
testcase( ((((char*)p) - (char*)0)&7)!=0 ); /* not always 8-byte aligned */
|
||||
return (
|
||||
(((i64)p[0]) << 56) +
|
||||
(((i64)p[1]) << 48) +
|
||||
@@ -476,16 +489,17 @@ static i64 readInt64(u8 *p){
|
||||
** 64 bit integer. The value returned is the number of bytes written
|
||||
** to the argument buffer (always 2, 4 and 8 respectively).
|
||||
*/
|
||||
static void writeInt16(u8 *p, int i){
|
||||
static int writeInt16(u8 *p, int i){
|
||||
p[0] = (i>> 8)&0xFF;
|
||||
p[1] = (i>> 0)&0xFF;
|
||||
return 2;
|
||||
}
|
||||
static int writeCoord(u8 *p, RtreeCoord *pCoord){
|
||||
u32 i;
|
||||
assert( ((((char*)p) - (char*)0)&3)==0 ); /* p is always 4-byte aligned */
|
||||
assert( sizeof(RtreeCoord)==4 );
|
||||
assert( sizeof(u32)==4 );
|
||||
#if SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
|
||||
#if SQLITE_BYTEORDER==1234 && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000)
|
||||
i = __builtin_bswap32(pCoord->u);
|
||||
memcpy(p, &i, 4);
|
||||
#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
|
||||
@@ -504,7 +518,8 @@ static int writeCoord(u8 *p, RtreeCoord *pCoord){
|
||||
return 4;
|
||||
}
|
||||
static int writeInt64(u8 *p, i64 i){
|
||||
#if SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
|
||||
testcase( ((((char*)p) - (char*)0)&7)!=0 ); /* Not always 8-byte aligned */
|
||||
#if SQLITE_BYTEORDER==1234 && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000)
|
||||
i = (i64)__builtin_bswap64((u64)i);
|
||||
memcpy(p, &i, 8);
|
||||
#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
|
||||
@@ -1060,7 +1075,7 @@ static int rtreeEof(sqlite3_vtab_cursor *cur){
|
||||
c.u = _byteswap_ulong(*(u32*)a); \
|
||||
r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \
|
||||
}
|
||||
#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
|
||||
#elif SQLITE_BYTEORDER==1234 && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000)
|
||||
#define RTREE_DECODE_COORD(eInt, a, r) { \
|
||||
RtreeCoord c; /* Coordinate decoded */ \
|
||||
c.u = __builtin_bswap32(*(u32*)a); \
|
||||
@@ -1294,7 +1309,7 @@ static int rtreeSearchPointCompare(
|
||||
}
|
||||
|
||||
/*
|
||||
** Interchange two search points in a cursor.
|
||||
** Interchange to search points in a cursor.
|
||||
*/
|
||||
static void rtreeSearchPointSwap(RtreeCursor *p, int i, int j){
|
||||
RtreeSearchPoint t = p->aPoint[i];
|
||||
@@ -1601,6 +1616,7 @@ static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
|
||||
if( i==0 ){
|
||||
sqlite3_result_int64(ctx, nodeGetRowid(pRtree, pNode, p->iCell));
|
||||
}else{
|
||||
if( rc ) return rc;
|
||||
nodeGetCoord(pRtree, pNode, p->iCell, i-1, &c);
|
||||
#ifndef SQLITE_RTREE_INT_ONLY
|
||||
if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
|
||||
@@ -1795,6 +1811,19 @@ static int rtreeFilter(
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Set the pIdxInfo->estimatedRows variable to nRow. Unless this
|
||||
** extension is currently being used by a version of SQLite too old to
|
||||
** support estimatedRows. In that case this function is a no-op.
|
||||
*/
|
||||
static void setEstimatedRows(sqlite3_index_info *pIdxInfo, i64 nRow){
|
||||
#if SQLITE_VERSION_NUMBER>=3008002
|
||||
if( sqlite3_libversion_number()>=3008002 ){
|
||||
pIdxInfo->estimatedRows = nRow;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
** Rtree virtual table module xBestIndex method. There are three
|
||||
** table scan strategies to choose from (in order from most to
|
||||
@@ -1874,7 +1903,7 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
|
||||
** a single row.
|
||||
*/
|
||||
pIdxInfo->estimatedCost = 30.0;
|
||||
pIdxInfo->estimatedRows = 1;
|
||||
setEstimatedRows(pIdxInfo, 1);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
@@ -1906,7 +1935,7 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
|
||||
|
||||
nRow = pRtree->nRowEst >> (iIdx/2);
|
||||
pIdxInfo->estimatedCost = (double)6.0 * (double)nRow;
|
||||
pIdxInfo->estimatedRows = nRow;
|
||||
setEstimatedRows(pIdxInfo, nRow);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -1945,12 +1974,12 @@ static RtreeDValue cellArea(Rtree *pRtree, RtreeCell *p){
|
||||
** of the objects size in each dimension.
|
||||
*/
|
||||
static RtreeDValue cellMargin(Rtree *pRtree, RtreeCell *p){
|
||||
RtreeDValue margin = 0;
|
||||
int ii = pRtree->nDim2 - 2;
|
||||
do{
|
||||
RtreeDValue margin;
|
||||
int ii;
|
||||
margin = DCOORD(p->aCoord[1]) - DCOORD(p->aCoord[0]);
|
||||
for(ii=2; ii<pRtree->nDim2; ii+=2){
|
||||
margin += (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii]));
|
||||
ii -= 2;
|
||||
}while( ii>=0 );
|
||||
}
|
||||
return margin;
|
||||
}
|
||||
|
||||
|
||||
@@ -63,10 +63,7 @@ do_test 1.2.1 {
|
||||
INSERT INTO t1 VALUES(7, 8);
|
||||
}
|
||||
set ::log
|
||||
} {}
|
||||
do_test 1.2.2 {
|
||||
db2 eval { SELECT * FROM t1 }
|
||||
} {5 6 {} 7 8 {}}
|
||||
} {SQLITE_SCHEMA {sqlite3changeset_apply(): table t1 has 3 columns, expected 2}}
|
||||
|
||||
do_test 1.3.0 {
|
||||
execsql {
|
||||
|
||||
@@ -33,11 +33,16 @@ proc do_changeset_invert_test {tn session res} {
|
||||
|
||||
|
||||
proc do_conflict_test {tn args} {
|
||||
proc xConflict {args} {
|
||||
lappend ::xConflict $args
|
||||
return ""
|
||||
}
|
||||
proc bgerror {args} { set ::background_error $args }
|
||||
|
||||
|
||||
set O(-tables) [list]
|
||||
set O(-sql) [list]
|
||||
set O(-conflicts) [list]
|
||||
set O(-policy) "OMIT"
|
||||
|
||||
array set V $args
|
||||
foreach key [array names V] {
|
||||
@@ -45,12 +50,6 @@ proc do_conflict_test {tn args} {
|
||||
}
|
||||
array set O $args
|
||||
|
||||
proc xConflict {args} [subst -nocommands {
|
||||
lappend ::xConflict [set args]
|
||||
return $O(-policy)
|
||||
}]
|
||||
proc bgerror {args} { set ::background_error $args }
|
||||
|
||||
sqlite3session S db main
|
||||
foreach t $O(-tables) { S attach $t }
|
||||
execsql $O(-sql)
|
||||
|
||||
@@ -1,216 +0,0 @@
|
||||
# 2017 February 04
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# Tests for the sessions module. Specifically, that a changeset can
|
||||
# be applied after ALTER TABLE ADD COLUMN has been used to add
|
||||
# columns to tables.
|
||||
#
|
||||
|
||||
if {![info exists testdir]} {
|
||||
set testdir [file join [file dirname [info script]] .. .. test]
|
||||
}
|
||||
source [file join [file dirname [info script]] session_common.tcl]
|
||||
source $testdir/tester.tcl
|
||||
ifcapable !session {finish_test; return}
|
||||
|
||||
set testprefix sessionat
|
||||
|
||||
db close
|
||||
sqlite3_shutdown
|
||||
test_sqlite3_log log
|
||||
proc log {code msg} { lappend ::log $code $msg }
|
||||
|
||||
proc reset_test {} {
|
||||
catch { db close }
|
||||
catch { db2 close }
|
||||
forcedelete test.db test.db2
|
||||
sqlite3 db test.db
|
||||
sqlite3 db2 test.db2
|
||||
}
|
||||
|
||||
|
||||
# Run all tests in this file twice. Once with "WITHOUT ROWID", and once
|
||||
# with regular rowid tables.
|
||||
#
|
||||
# ?.1.*: Test that PK inconsistencies are detected if one or more of the PK
|
||||
# columns are not present in the changeset.
|
||||
#
|
||||
# ?.2.*: Test that it is not possible to apply a changeset with N columns
|
||||
# to a db with fewer than N columns.
|
||||
#
|
||||
# ?.3.*: Test some INSERT, UPDATE and DELETE operations that do not
|
||||
# require conflict handling.
|
||||
#
|
||||
# ?.4.*: Test some INSERT, UPDATE and DELETE operations that do require
|
||||
# conflict handling.
|
||||
#
|
||||
# ?.5.*: Test that attempting to concat two changesets with different
|
||||
# numbers of columns for the same table is an error.
|
||||
#
|
||||
foreach {tn trailing} {
|
||||
sessionat-ipk ""
|
||||
sessionat-wor " WITHOUT ROWID "
|
||||
} {
|
||||
eval [string map [list %WR% $trailing] {
|
||||
reset_test
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
do_execsql_test $tn.1.0 {
|
||||
CREATE TABLE t1(a, b, PRIMARY KEY(a)) %WR%;
|
||||
}
|
||||
do_execsql_test -db db2 $tn.1.1 {
|
||||
CREATE TABLE t1(a, b, c, PRIMARY KEY(a, c)) %WR%;
|
||||
}
|
||||
do_test $tn.1.2 {
|
||||
set ::log {}
|
||||
do_then_apply_sql { INSERT INTO t1 VALUES('one', 'two') }
|
||||
set ::log
|
||||
} [list \
|
||||
SQLITE_SCHEMA {sqlite3changeset_apply(): primary key mismatch for table t1}
|
||||
]
|
||||
do_execsql_test $tn.1.3 { SELECT * FROM t1 } {one two}
|
||||
do_execsql_test -db db2 $tn.1.4 { SELECT * FROM t1 } {}
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
do_execsql_test $tn.2.0 {
|
||||
CREATE TABLE t2(x, y, z, PRIMARY KEY(x)) %WR%;
|
||||
}
|
||||
do_execsql_test -db db2 $tn.2.1 {
|
||||
CREATE TABLE t2(x, y, PRIMARY KEY(x)) %WR%;
|
||||
}
|
||||
do_test $tn.2.2 {
|
||||
db cache flush
|
||||
set ::log {}
|
||||
do_then_apply_sql { INSERT INTO t2 VALUES(1, 2, 3) }
|
||||
set ::log
|
||||
} [list SQLITE_SCHEMA \
|
||||
{sqlite3changeset_apply(): table t2 has 2 columns, expected 3 or more}
|
||||
]
|
||||
do_execsql_test $tn.2.3 { SELECT * FROM t2 } {1 2 3}
|
||||
do_execsql_test -db db2 $tn.2.4 { SELECT * FROM t2 } {}
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
do_execsql_test $tn.3.0 {
|
||||
CREATE TABLE t3(a, b, PRIMARY KEY(b)) %WR%;
|
||||
}
|
||||
do_execsql_test -db db2 $tn.3.1 {
|
||||
CREATE TABLE t3(a, b, c DEFAULT 'D', PRIMARY KEY(b)) %WR%;
|
||||
}
|
||||
do_test $tn.3.2 {
|
||||
do_then_apply_sql {
|
||||
INSERT INTO t3 VALUES(1, 2);
|
||||
INSERT INTO t3 VALUES(3, 4);
|
||||
INSERT INTO t3 VALUES(5, 6);
|
||||
};
|
||||
db2 eval {SELECT * FROM t3}
|
||||
} {1 2 D 3 4 D 5 6 D}
|
||||
do_test $tn.3.3 {
|
||||
do_then_apply_sql {
|
||||
UPDATE t3 SET a=45 WHERE b=4;
|
||||
DELETE FROM t3 WHERE a=5;
|
||||
};
|
||||
db2 eval {SELECT * FROM t3}
|
||||
} {1 2 D 45 4 D}
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
# 4.1: INSERT statements
|
||||
# 4.2: DELETE statements
|
||||
# 4.3: UPDATE statements
|
||||
#
|
||||
do_execsql_test $tn.4.1.0 {
|
||||
CREATE TABLE t4(x INTEGER PRIMARY KEY, y) %WR%;
|
||||
}
|
||||
do_execsql_test -db db2 $tn.4.1.1 {
|
||||
CREATE TABLE t4(x INTEGER PRIMARY KEY, y, z) %WR%;
|
||||
INSERT INTO t4 VALUES(1, 2, 3);
|
||||
INSERT INTO t4 VALUES(4, 5, 6);
|
||||
}
|
||||
do_conflict_test $tn.4.1.2 -tables t4 -sql {
|
||||
INSERT INTO t4 VALUES(10, 20);
|
||||
INSERT INTO t4 VALUES(4, 11);
|
||||
} -conflicts {
|
||||
{INSERT t4 CONFLICT {i 4 i 11} {i 4 i 5}}
|
||||
}
|
||||
do_execsql_test -db db2 $tn.4.1.3 {
|
||||
SELECT * FROM t4 ORDER BY x
|
||||
} {1 2 3 4 5 6 10 20 {}}
|
||||
do_conflict_test $tn.4.1.4 -policy REPLACE -tables t4 -sql {
|
||||
INSERT INTO t4 VALUES(1, 11);
|
||||
} -conflicts {
|
||||
{INSERT t4 CONFLICT {i 1 i 11} {i 1 i 2}}
|
||||
}
|
||||
do_execsql_test -db db2 $tn.4.1.5 {
|
||||
SELECT * FROM t4 ORDER BY x
|
||||
} {1 11 {} 4 5 6 10 20 {}}
|
||||
|
||||
do_execsql_test $tn.4.2.0 {
|
||||
DELETE FROM t4;
|
||||
INSERT INTO t4 VALUES(1, 'A');
|
||||
INSERT INTO t4 VALUES(2, 'B');
|
||||
INSERT INTO t4 VALUES(3, 'C');
|
||||
INSERT INTO t4 VALUES(4, 'D');
|
||||
}
|
||||
do_execsql_test -db db2 $tn.4.2.1 {
|
||||
DELETE FROM t4;
|
||||
INSERT INTO t4 VALUES(1, 'A', 'a');
|
||||
INSERT INTO t4 VALUES(3, 'C', 'c');
|
||||
INSERT INTO t4 VALUES(4, 'E', 'd');
|
||||
}
|
||||
do_conflict_test $tn.4.2.2 -tables t4 -sql {
|
||||
DELETE FROM t4 WHERE x=2;
|
||||
DELETE FROM t4 WHERE x=4;
|
||||
} -conflicts {
|
||||
{DELETE t4 NOTFOUND {i 2 t B}}
|
||||
{DELETE t4 DATA {i 4 t D} {i 4 t E}}
|
||||
}
|
||||
|
||||
do_execsql_test $tn.4.3.0 {
|
||||
CREATE TABLE t5(a, b, c PRIMARY KEY) %WR%;
|
||||
INSERT INTO t5 VALUES(1,1,1), (2,2,2), (3,3,3), (4,4,4);
|
||||
}
|
||||
do_execsql_test -db db2 $tn.4.3.1 {
|
||||
CREATE TABLE t5(a, b, c PRIMARY KEY, d CHECK(b!=10)) %WR%;
|
||||
INSERT INTO t5 VALUES (2,2,2,2), (3,8,3,3), (4,4,4,4);
|
||||
}
|
||||
do_conflict_test $tn.4.3.2 -tables t5 -sql {
|
||||
UPDATE t5 SET a=4 WHERE c=1;
|
||||
UPDATE t5 SET b=9 WHERE c=3;
|
||||
UPDATE t5 SET b=10 WHERE c=2;
|
||||
} -conflicts {
|
||||
{UPDATE t5 NOTFOUND {i 1 {} {} i 1} {i 4 {} {} {} {}}}
|
||||
{UPDATE t5 DATA {{} {} i 3 i 3} {{} {} i 9 {} {}} {i 3 i 8 i 3}}
|
||||
{UPDATE t5 CONSTRAINT {{} {} i 2 i 2} {{} {} i 10 {} {}}}
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
do_execsql_test $tn.5.0 {
|
||||
CREATE TABLE t6(a, b, c, PRIMARY KEY(a, b)) %WR%;
|
||||
}
|
||||
do_execsql_test -db db2 $tn.5.1 {
|
||||
CREATE TABLE t6(a, b, c, d, e, PRIMARY KEY(a, b)) %WR%;
|
||||
}
|
||||
do_test $tn.5.2 {
|
||||
set c1 [sql_exec_changeset db {
|
||||
INSERT INTO t6 VALUES(1, 1, 1);
|
||||
INSERT INTO t6 VALUES(2, 2, 2);
|
||||
}]
|
||||
set c2 [sql_exec_changeset db2 {
|
||||
INSERT INTO t6 VALUES(3, 3, 3, 3, 3);
|
||||
INSERT INTO t6 VALUES(4, 4, 4, 4, 4);
|
||||
}]
|
||||
list [catch { sqlite3changeset_concat $c1 $c2} msg] $msg
|
||||
} {1 SQLITE_SCHEMA}
|
||||
|
||||
}]
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
@@ -3028,7 +3028,7 @@ int sqlite3changeset_conflict(
|
||||
if( !pIter->pConflict ){
|
||||
return SQLITE_MISUSE;
|
||||
}
|
||||
if( iVal<0 || iVal>=pIter->nCol ){
|
||||
if( iVal<0 || iVal>=sqlite3_column_count(pIter->pConflict) ){
|
||||
return SQLITE_RANGE;
|
||||
}
|
||||
*ppValue = sqlite3_column_value(pIter->pConflict, iVal);
|
||||
@@ -3495,13 +3495,7 @@ static int sessionInsertRow(
|
||||
|
||||
sessionAppendStr(&buf, "INSERT INTO main.", &rc);
|
||||
sessionAppendIdent(&buf, zTab, &rc);
|
||||
sessionAppendStr(&buf, "(", &rc);
|
||||
for(i=0; i<p->nCol; i++){
|
||||
if( i!=0 ) sessionAppendStr(&buf, ", ", &rc);
|
||||
sessionAppendIdent(&buf, p->azCol[i], &rc);
|
||||
}
|
||||
|
||||
sessionAppendStr(&buf, ") VALUES(?", &rc);
|
||||
sessionAppendStr(&buf, " VALUES(?", &rc);
|
||||
for(i=1; i<p->nCol; i++){
|
||||
sessionAppendStr(&buf, ", ?", &rc);
|
||||
}
|
||||
@@ -4047,17 +4041,11 @@ static int sessionChangesetApply(
|
||||
nTab = (int)strlen(zTab);
|
||||
sApply.azCol = (const char **)zTab;
|
||||
}else{
|
||||
int nMinCol = 0;
|
||||
int i;
|
||||
|
||||
sqlite3changeset_pk(pIter, &abPK, 0);
|
||||
rc = sessionTableInfo(
|
||||
db, "main", zNew, &sApply.nCol, &zTab, &sApply.azCol, &sApply.abPK
|
||||
);
|
||||
if( rc!=SQLITE_OK ) break;
|
||||
for(i=0; i<sApply.nCol; i++){
|
||||
if( sApply.abPK[i] ) nMinCol = i+1;
|
||||
}
|
||||
|
||||
if( sApply.nCol==0 ){
|
||||
schemaMismatch = 1;
|
||||
@@ -4065,29 +4053,26 @@ static int sessionChangesetApply(
|
||||
"sqlite3changeset_apply(): no such table: %s", zTab
|
||||
);
|
||||
}
|
||||
else if( sApply.nCol<nCol ){
|
||||
else if( sApply.nCol!=nCol ){
|
||||
schemaMismatch = 1;
|
||||
sqlite3_log(SQLITE_SCHEMA,
|
||||
"sqlite3changeset_apply(): table %s has %d columns, "
|
||||
"expected %d or more",
|
||||
"sqlite3changeset_apply(): table %s has %d columns, expected %d",
|
||||
zTab, sApply.nCol, nCol
|
||||
);
|
||||
}
|
||||
else if( nCol<nMinCol || memcmp(sApply.abPK, abPK, nCol)!=0 ){
|
||||
else if( memcmp(sApply.abPK, abPK, nCol)!=0 ){
|
||||
schemaMismatch = 1;
|
||||
sqlite3_log(SQLITE_SCHEMA, "sqlite3changeset_apply(): "
|
||||
"primary key mismatch for table %s", zTab
|
||||
);
|
||||
}
|
||||
else{
|
||||
sApply.nCol = nCol;
|
||||
if((rc = sessionSelectRow(db, zTab, &sApply))
|
||||
|| (rc = sessionUpdateRow(db, zTab, &sApply))
|
||||
|| (rc = sessionDeleteRow(db, zTab, &sApply))
|
||||
|| (rc = sessionInsertRow(db, zTab, &sApply))
|
||||
){
|
||||
break;
|
||||
}
|
||||
else if(
|
||||
(rc = sessionSelectRow(db, zTab, &sApply))
|
||||
|| (rc = sessionUpdateRow(db, zTab, &sApply))
|
||||
|| (rc = sessionDeleteRow(db, zTab, &sApply))
|
||||
|| (rc = sessionInsertRow(db, zTab, &sApply))
|
||||
){
|
||||
break;
|
||||
}
|
||||
nTab = sqlite3Strlen30(zTab);
|
||||
}
|
||||
|
||||
@@ -319,8 +319,7 @@ int sqlite3session_changeset(
|
||||
** the from-table, a DELETE record is added to the session object.
|
||||
**
|
||||
** <li> For each row (primary key) that exists in both tables, but features
|
||||
** different non-PK values in each, an UPDATE record is added to the
|
||||
** session.
|
||||
** different in each, an UPDATE record is added to the session.
|
||||
** </ul>
|
||||
**
|
||||
** To clarify, if this function is called and then a changeset constructed
|
||||
@@ -905,7 +904,7 @@ void sqlite3changegroup_delete(sqlite3_changegroup*);
|
||||
** <ul>
|
||||
** <li> The table has the same name as the name recorded in the
|
||||
** changeset, and
|
||||
** <li> The table has at least as many columns as recorded in the
|
||||
** <li> The table has the same number of columns as recorded in the
|
||||
** changeset, and
|
||||
** <li> The table has primary key columns in the same position as
|
||||
** recorded in the changeset.
|
||||
@@ -950,11 +949,7 @@ void sqlite3changegroup_delete(sqlite3_changegroup*);
|
||||
** If a row with matching primary key values is found, but one or more of
|
||||
** the non-primary key fields contains a value different from the original
|
||||
** row value stored in the changeset, the conflict-handler function is
|
||||
** invoked with [SQLITE_CHANGESET_DATA] as the second argument. If the
|
||||
** database table has more columns than are recorded in the changeset,
|
||||
** only the values of those non-primary key fields are compared against
|
||||
** the current database contents - any trailing database table columns
|
||||
** are ignored.
|
||||
** invoked with [SQLITE_CHANGESET_DATA] as the second argument.
|
||||
**
|
||||
** If no row with matching primary key values is found in the database,
|
||||
** the conflict-handler function is invoked with [SQLITE_CHANGESET_NOTFOUND]
|
||||
@@ -969,9 +964,7 @@ void sqlite3changegroup_delete(sqlite3_changegroup*);
|
||||
**
|
||||
** <dt>INSERT Changes<dd>
|
||||
** For each INSERT change, an attempt is made to insert the new row into
|
||||
** the database. If the changeset row contains fewer fields than the
|
||||
** database table, the trailing fields are populated with their default
|
||||
** values.
|
||||
** the database.
|
||||
**
|
||||
** If the attempt to insert the row fails because the database already
|
||||
** contains a row with the same primary key values, the conflict handler
|
||||
@@ -989,13 +982,13 @@ void sqlite3changegroup_delete(sqlite3_changegroup*);
|
||||
** For each UPDATE change, this function checks if the target database
|
||||
** contains a row with the same primary key value (or values) as the
|
||||
** original row values stored in the changeset. If it does, and the values
|
||||
** stored in all modified non-primary key columns also match the values
|
||||
** stored in the changeset the row is updated within the target database.
|
||||
** stored in all non-primary key columns also match the values stored in
|
||||
** the changeset the row is updated within the target database.
|
||||
**
|
||||
** If a row with matching primary key values is found, but one or more of
|
||||
** the modified non-primary key fields contains a value different from an
|
||||
** original row value stored in the changeset, the conflict-handler function
|
||||
** is invoked with [SQLITE_CHANGESET_DATA] as the second argument. Since
|
||||
** the non-primary key fields contains a value different from an original
|
||||
** row value stored in the changeset, the conflict-handler function is
|
||||
** invoked with [SQLITE_CHANGESET_DATA] as the second argument. Since
|
||||
** UPDATE changes only contain values for non-primary key fields that are
|
||||
** to be modified, only those fields need to match the original values to
|
||||
** avoid the SQLITE_CHANGESET_DATA conflict-handler callback.
|
||||
|
||||
@@ -21,10 +21,6 @@
|
||||
*/
|
||||
#ifdef SQLITE_USER_AUTHENTICATION
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
** If a database contains the SQLITE_USER table, then the
|
||||
** sqlite3_user_authenticate() interface must be invoked with an
|
||||
@@ -89,8 +85,4 @@ int sqlite3_user_delete(
|
||||
const char *zUsername /* Username to remove */
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end of the 'extern "C"' block */
|
||||
#endif
|
||||
|
||||
#endif /* SQLITE_USER_AUTHENTICATION */
|
||||
|
||||
@@ -477,7 +477,6 @@ SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
|
||||
SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
|
||||
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
|
||||
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
|
||||
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
|
||||
DBFUZZ_OPT =
|
||||
KV_OPT = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ
|
||||
ST_OPT = -DSQLITE_THREADSAFE=0
|
||||
@@ -899,7 +898,7 @@ speedtest1$(EXE): $(TOP)/test/speedtest1.c sqlite3.c
|
||||
$(TCCX) -I. $(ST_OPT) -o speedtest1$(EXE) $(TOP)/test/speedtest1.c sqlite3.c $(THREADLIB)
|
||||
|
||||
kvtest$(EXE): $(TOP)/test/kvtest.c sqlite3.c
|
||||
$(TCCX) -I. $(KV_OPT) -o kvtest$(EXE) $(TOP)/test/kvtest.c sqlite3.c $(THREADLIB)
|
||||
$(TCCX) -I. $(KV+OPT) -o kvtest$(EXE) $(TOP)/test/kvtest.c sqlite3.c $(THREADLIB)
|
||||
|
||||
rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.o
|
||||
$(TCC) -I. -o rbu$(EXE) $(TOP)/ext/rbu/rbu.c sqlite3.o \
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
C The\soutput\sof\sthe\s".dump"\scommand\sin\sthe\sCLI\squotes\snewline\sand\scarriage-return\ncharacters\susing\s"char(10)"\sand\s"char(13)".
|
||||
D 2017-03-11T01:56:41.692
|
||||
F Makefile.in 2dae2a56457c2885425a480e1053de8096aff924
|
||||
C Merge\sthe\slatest\strunk\schanges,\sespecially\sthe\sRTREE\senhancement\sto\suse\nsqlite3_blob\sobjects.
|
||||
D 2017-02-04T14:30:57.322
|
||||
F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc 9020fa41eb91f657ae0cc44145d0a2f3af520860
|
||||
F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964
|
||||
F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7
|
||||
F VERSION 3605fa447e4623f5ff4a6adc97b1fde9a257b8f2
|
||||
F VERSION cddd8d88dc8202afa0ebc96da61fc4acbd1e96a5
|
||||
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
||||
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
|
||||
F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
|
||||
F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
|
||||
F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903
|
||||
F autoconf/Makefile.am 1a47d071e3d5435f8f7ebff7eb6703848bbd65d4
|
||||
F autoconf/Makefile.msc 3de603bcec5c07462801a20fd7dc1b871400af99
|
||||
F autoconf/Makefile.msc 3f29e0fc2a78e113250d79a5da375c1d8d8c06b0
|
||||
F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7
|
||||
F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1
|
||||
F autoconf/configure.ac cacf2616abf6e4a569bde2ef365c143caeec40bc
|
||||
@@ -30,7 +30,7 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
|
||||
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
|
||||
F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc
|
||||
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
|
||||
F configure b15d030a8ae2e672d76c97b6667dacb98934a467 x
|
||||
F configure fcfa56d5d66668c9263dc007724f62acff06dc83 x
|
||||
F configure.ac 605173e829ab64514ed89f9b53d0da1739d7b0a0
|
||||
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
||||
F doc/lemon.html b5a3c07d33ecb8e019ce8f7660fe2dbbad9d7977
|
||||
@@ -70,9 +70,9 @@ 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 95c7041ea75d82d2d9a4cd058904ba889751f5b8
|
||||
F ext/fts3/fts3.c 5a8cafedffd101e9946f8909ecf8d34aaa383b4d
|
||||
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
|
||||
F ext/fts3/fts3Int.h eb2502000148e80913b965db3e59f29251266d0a
|
||||
F ext/fts3/fts3Int.h 89d0bd4595a0de384dac78e94b803de12586e8dd
|
||||
F ext/fts3/fts3_aux.c 9edc3655fcb287f0467d0a4b886a01c6185fe9f1
|
||||
F ext/fts3/fts3_expr.c dfd571a24412779ac01f25c01d888c6ef7b2d0ef
|
||||
F ext/fts3/fts3_hash.c 29b986e43f4e9dd40110eafa377dc0d63c422c60
|
||||
@@ -98,15 +98,15 @@ F ext/fts3/unicode/mkunicode.tcl 2debed3f582d77b3fdd0b8830880250021571fd8
|
||||
F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95
|
||||
F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0
|
||||
F ext/fts5/fts5.h 62f3e33ceeb9a428db139f9c012186b371da1cc7
|
||||
F ext/fts5/fts5Int.h c629b24d2b92b99596f3b8e82289fddca06df6e1
|
||||
F ext/fts5/fts5Int.h b2eda36e0f224365c8e23dc8f559311834f1c13f
|
||||
F ext/fts5/fts5_aux.c 67acf8d51723cf28ffc3828210ba662df4b8d267
|
||||
F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd
|
||||
F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857
|
||||
F ext/fts5/fts5_expr.c c6ecc2280162a3714d15dce2a8f2299f748b627c
|
||||
F ext/fts5/fts5_expr.c 33f0e8063ac7360bcd71c0ff0dcbacdc05fffe50
|
||||
F ext/fts5/fts5_hash.c 880998e596b60f078348d48732ca4ad9a90caad2
|
||||
F ext/fts5/fts5_index.c f67032a9a529ba52a545e6e3ab970764199c05d4
|
||||
F ext/fts5/fts5_main.c f85281445dcf8be32d18841c93a6f90fe27dbfe2
|
||||
F ext/fts5/fts5_storage.c 8f0e65cb33bde8f449e1c9b4be4600d18b4da6e9
|
||||
F ext/fts5/fts5_storage.c de0ed8a06738bde433afe11e92295ceaffbc4e58
|
||||
F ext/fts5/fts5_tcl.c 4a901f00c8553740dba63511603f5527d741c26a
|
||||
F ext/fts5/fts5_test_mi.c 783b86697ebf773c18fc109992426c0173a055bc
|
||||
F ext/fts5/fts5_test_tok.c db08af63673c3a7d39f053b36fd6e065017706be
|
||||
@@ -160,12 +160,10 @@ F ext/fts5/test/fts5fault8.test 6785af34bd1760de74e2824ea9c161965af78f85
|
||||
F ext/fts5/test/fts5fault9.test e10e395428a9ea0596ebe752ff7123d16ab78e08
|
||||
F ext/fts5/test/fts5faultA.test fa5d59c0ff62b7125cd14eee38ded1c46e15a7ea
|
||||
F ext/fts5/test/fts5faultB.test 7f3bba790fa172073ac314f9b8ed197390b61eca
|
||||
F ext/fts5/test/fts5faultD.test cc5d1225556e356615e719c612e845d41bff7d5a
|
||||
F ext/fts5/test/fts5full.test 6f6143af0c6700501d9fd597189dfab1555bb741
|
||||
F ext/fts5/test/fts5fuzz1.test bece4695fc169b61ab236ada7931c6e4942cbef9
|
||||
F ext/fts5/test/fts5hash.test 06f9309ccb4d5050a131594e9e47d0b21456837d
|
||||
F ext/fts5/test/fts5integrity.test f5e4f8d284385875068ad0f3e894ce43e9de835d
|
||||
F ext/fts5/test/fts5lastrowid.test 4fac1aba696dd6c956e03b0cf91f6f1f3aaec494
|
||||
F ext/fts5/test/fts5matchinfo.test f7dde99697bcb310ea8faa8eb2714d9f4dfc0e1b
|
||||
F ext/fts5/test/fts5merge.test 9f65f090d214ff865c56bef4f864aaa1182af6e3
|
||||
F ext/fts5/test/fts5merge2.test a6da3c16d694235938d1939f503cfa53f0943d75
|
||||
@@ -225,7 +223,6 @@ F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a
|
||||
F ext/misc/scrub.c 1c5bfb8b0cd18b602fcb55755e84abf0023ac2fb
|
||||
F ext/misc/series.c e11e534ada797d5b816d7e7a93c022306563ca35
|
||||
F ext/misc/sha1.c 0b9e9b855354910d3ca467bf39099d570e73db56
|
||||
F ext/misc/shathree.c 38aa4c3c3d3c3fc34b8ea367bed299d8d8a224b2
|
||||
F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52
|
||||
F ext/misc/spellfix.c a4723b6aff748a417b5091b68a46443265c40f0d
|
||||
F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512
|
||||
@@ -251,7 +248,6 @@ F ext/rbu/rbuB.test c25bc325b8072a766e56bb76c001866b405925c2
|
||||
F ext/rbu/rbuC.test efe47db508a0269b683cb2a1913a425ffd39a831
|
||||
F ext/rbu/rbu_common.tcl a38e8e2d4a50fd6aaf151633714c1b1d2fae3ead
|
||||
F ext/rbu/rbucrash.test 8d2ed5d4b05fef6c00c2a6b5f7ead71fa172a695
|
||||
F ext/rbu/rbucrash2.test b2ecbdd7bb72c88bd217c65bd00dafa07f7f2d4d
|
||||
F ext/rbu/rbudiff.test 3e605cf624d00d04d0fb1316a3acec4fbe3b3ac5
|
||||
F ext/rbu/rbudor.test 99b05cc0df613e962c2c8085cfb05686a09cf315
|
||||
F ext/rbu/rbufault.test cc0be8d5d392d98b0c2d6a51be377ea989250a89
|
||||
@@ -259,16 +255,16 @@ F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06
|
||||
F ext/rbu/rbufault3.test 54a399888ac4af44c68f9f58afbed23149428bca
|
||||
F ext/rbu/rbufault4.test 34e70701cbec51571ffbd9fbf9d4e0f2ec495ca7
|
||||
F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda
|
||||
F ext/rbu/rbuprogress.test 1849d4e0e50616edf5ce75ce7db86622e656b5cf
|
||||
F ext/rbu/rbuprogress.test e3e25fb7622641b8f2df7c6b7a7eb6fddfc46a4b
|
||||
F ext/rbu/rburesume.test 8acb77f4a422ff55acfcfc9cc15a5cb210b1de83
|
||||
F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48
|
||||
F ext/rbu/rbuvacuum.test 4a977447c15c2581ab668781d9ef4294382530e0
|
||||
F ext/rbu/rbuvacuum2.test 2074ab14fe66e1c7e7210c62562650dcd215bbaa
|
||||
F ext/rbu/sqlite3rbu.c 2a89efba9eeba8e6c89a498dc195e8efbdde2694
|
||||
F ext/rbu/sqlite3rbu.c bb0de6cdbdb14a7d55a097238a434b7e99caf318
|
||||
F ext/rbu/sqlite3rbu.h 6fb6294c34a9ca93b5894a33bca530c6f08decba
|
||||
F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88
|
||||
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
|
||||
F ext/rtree/rtree.c 3f3a595dba485e340246fa2c8ba330a6b9768b00
|
||||
F ext/rtree/rtree.c 0c229d23ce7b9bc69365281689065f3cbbe4561e
|
||||
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
|
||||
F ext/rtree/rtree1.test 42dadfc7b44a436cd74a1bebc0b9b689e4eaf7ec
|
||||
F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba
|
||||
@@ -294,7 +290,7 @@ F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
|
||||
F ext/session/changeset.c 4ccbaa4531944c24584bf6a61ba3a39c62b6267a
|
||||
F ext/session/session1.test c8a50e0e8581dc1a00e832aa59bb61f180404d44
|
||||
F ext/session/session2.test 284de45abae4cc1082bc52012ee81521d5ac58e0
|
||||
F ext/session/session3.test ce9ce3dfa489473987f899e9f6a0f2db9bde3479
|
||||
F ext/session/session3.test a7a9ce59b8d1e49e2cc23d81421ac485be0eea01
|
||||
F ext/session/session4.test 457b02bdc349eb01151e54de014df77abd3c08c8
|
||||
F ext/session/session5.test 716bc6fafd625ce60dfa62ae128971628c1a1169
|
||||
F ext/session/session6.test 443789bc2fca12e4f7075cf692c60b8a2bea1a26
|
||||
@@ -307,22 +303,21 @@ F ext/session/sessionD.test d4744c78334162851d2a2f285c7e603e31b49aa2
|
||||
F ext/session/sessionE.test e60a238c47f0feb3bb707e7f35e22be09c7e8f26
|
||||
F ext/session/sessionF.test c2f178d4dfd723a5fd94a730ea2ccb44c669e3ce
|
||||
F ext/session/sessionG.test 01ef705096a9d3984eebdcca79807a211dee1b60
|
||||
F ext/session/session_common.tcl 7776eda579773113b30c7abfd4545c445228cb73
|
||||
F ext/session/session_common.tcl 9b696a341cf1d3744823715ed92bb19749b6c3d4
|
||||
F ext/session/session_speed_test.c edc1f96fd5e0e4b16eb03e2a73041013d59e8723
|
||||
F ext/session/sessionat.test b25d61d663ebc795506bf74079dc4ba0092fad25
|
||||
F ext/session/sessionfault.test da273f2712b6411e85e71465a1733b8501dbf6f7
|
||||
F ext/session/sessionfault2.test 04aa0bc9aa70ea43d8de82c4f648db4de1e990b0
|
||||
F ext/session/sessionwor.test 2f3744236dc8b170a695b7d8ddc8c743c7e79fdc
|
||||
F ext/session/sqlite3session.c 13642d9c754cc18f17e141f82860d269e2adf920
|
||||
F ext/session/sqlite3session.h d4db650adfcc7a4360e9f12a09c2d117b1db6b53
|
||||
F ext/session/sqlite3session.c c61a43396368ec00dc127f7bc647e9bd6a4ee5fb
|
||||
F ext/session/sqlite3session.h 9345166bd8f80562145586cf817f707de5ecada2
|
||||
F ext/session/test_session.c eb0bd6c1ea791c1d66ee4ef94c16500dad936386
|
||||
F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
|
||||
F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220
|
||||
F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04
|
||||
F ext/userauth/userauth.c 3410be31283abba70255d71fd24734e017a4497f
|
||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
|
||||
F main.mk 0ec10b604f4668f7e85a358954babe75c94dc0d5
|
||||
F main.mk afc52937b4e5fe08678e8d5a4fe4487d44e3bc61
|
||||
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
|
||||
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
|
||||
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
|
||||
@@ -335,23 +330,23 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
|
||||
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
|
||||
F src/alter.c 3b23977620ce9662ac54443f65b87ba996e36121
|
||||
F src/analyze.c 6d8234916c29be943e6ea28b5bef67dff98d9905
|
||||
F src/analyze.c ac7a5d7e3cee07d074697904e00e4a8ab7b2b4f5
|
||||
F src/attach.c 8c476f8bd5d2afe11d925f890d30e527e5b0ce43
|
||||
F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792
|
||||
F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b
|
||||
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
|
||||
F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca
|
||||
F src/btree.c e2bae0a03f73d119910fb35c9550987564065137
|
||||
F src/btree.h bf64dfeeddeebdb775a5eba0098bbc00d073290d
|
||||
F src/btreeInt.h cd55d39d9916270837a88c12e701047cba0729b0
|
||||
F src/build.c 43f903c9082040ced2b421543cb0300c2973647d
|
||||
F src/btree.c 9fe65ab418d99e80289f024016b5e5e74c3059dd
|
||||
F src/btree.h e6d352808956ec163a17f832193a3e198b3fb0ac
|
||||
F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e
|
||||
F src/build.c 9e799f1edd910dfa8a0bc29bd390d35d310596af
|
||||
F src/callback.c 2e76147783386374bf01b227f752c81ec872d730
|
||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||
F src/ctime.c a9984df73898c042a5cfc8f9d8e7723d02bc35c9
|
||||
F src/date.c ee676e7694dfadbdd2fde1a258a71be8360ba5ae
|
||||
F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a
|
||||
F src/date.c dc3f1391d9297f8c748132813aaffcb117090d6e
|
||||
F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d
|
||||
F src/delete.c 0d9d5549d42e79ce4d82ff1db1e6c81e36d2f67c
|
||||
F src/expr.c 8a29e9b72d4b642189999c41782cd6c5bc43512f
|
||||
F src/expr.c d29114e9b709eaeaaa18553a5bbe60a19302aeef
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae
|
||||
F src/func.c c67273e1ec08abbdcc14c189892a3ff6eeece86b
|
||||
@@ -360,13 +355,13 @@ F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd
|
||||
F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4
|
||||
F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da
|
||||
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
|
||||
F src/insert.c 3ed64afc49c0a2221e397b9f65d231ffbef506fe
|
||||
F src/legacy.c e88ed13c2d531decde75d42c2e35623fb9ce3cb0
|
||||
F src/insert.c 444354c23d4d140a57d6eb46f34e376a7f8f62e8
|
||||
F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e
|
||||
F src/loadext.c a68d8d1d14cf7488bb29dc5311cb1ce9a4404258
|
||||
F src/main.c 158326243c5ddc8b98a1e983fa488650cf76d760
|
||||
F src/malloc.c 89c98e3619d362dcffa5c1c639b364b65b474751
|
||||
F src/main.c e207b81542d13b9f13d61e78ca441f9781f055b0
|
||||
F src/malloc.c fc1b9f445290f2145da48fc08730c26e6082b640
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c fd7cd6fe21d46fe0a4186367dd8dc26d87b787eb
|
||||
F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b
|
||||
F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
|
||||
F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a
|
||||
F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944
|
||||
@@ -376,44 +371,44 @@ F src/mutex.c 8e45800ee78e0cd1f1f3fe8e398853307f4a085c
|
||||
F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85
|
||||
F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4
|
||||
F src/mutex_unix.c 27bb6cc49485ee46711a6580ab7b3f1402211d23
|
||||
F src/mutex_w32.c a898fa969823b100c0f5fdc57e54c9a1e419ab4d
|
||||
F src/mutex_w32.c 5e6fe1c298fb5a8a15aaed4161d5759311431c17
|
||||
F src/notify.c 9711a7575036f0d3040ba61bc6e217f13a9888e7
|
||||
F src/os.c add02933b1dce7a39a005b00a2f5364b763e9a24
|
||||
F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343
|
||||
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
|
||||
F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
|
||||
F src/os_unix.c 30e2c43e4955db990e5b5a81e901f8aa74cc8820
|
||||
F src/os_win.c 2a6c73eef01c51a048cc4ddccd57f981afbec18a
|
||||
F src/os_win.c cf90abd4e50d9f56d2c20ce8e005aff55d7bd8e9
|
||||
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
||||
F src/pager.c ff1232b3088a39806035ecfac4fffeb22717d80b
|
||||
F src/pager.h f2a99646c5533ffe11afa43e9e0bea74054e4efa
|
||||
F src/parse.y 48b03113704ee8bd78ee6996d81de7fbee22e105
|
||||
F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870
|
||||
F src/parse.y 591704fce84f814d9a3642774c1f011d38f4149c
|
||||
F src/pcache.c 51070ec9b8251bbf9c6ea3d35fd96a458752929e
|
||||
F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490
|
||||
F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953
|
||||
F src/pragma.c b7bf4f1dd9cdcdd3f72f0bdbce3502d69d0f48ba
|
||||
F src/pragma.h c9c763958fec92b04125571472c9500b351c5f7f
|
||||
F src/pragma.c 7831956012f5d764761fbd023e59b0ffc08f5e8d
|
||||
F src/pragma.h 61aa5389118594bebb28120a6720401aee34ce1a
|
||||
F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a
|
||||
F src/printf.c 67427bbee66d891fc6f6f5aada857e9cdb368c1c
|
||||
F src/printf.c ff10a9b9902cd2afe5f655f3013c6307d969b1fd
|
||||
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
|
||||
F src/resolve.c 3e518b962d932a997fae373366880fc028c75706
|
||||
F src/resolve.c f9bc0de45a30a450da47b3766de00be89bf9be79
|
||||
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
|
||||
F src/select.c d12f3539f80db38b09015561b569e0eb1c4b6c5f
|
||||
F src/shell.c 353f3cebb938099577494326e2853010512e0625
|
||||
F src/sqlite.h.in 4d0c08f8640c586564a7032b259c5f69bf397850
|
||||
F src/shell.c a84e453c213f3e0d6935a582024da4e242f85a19
|
||||
F src/sqlite.h.in 878b0f81f3f59d1f24c002127dd18740a81ba32a
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae
|
||||
F src/sqliteInt.h df268ce1d04df042cf43b557d2309eb0b71e86c4
|
||||
F src/sqliteInt.h 3724c48e82605b471bbf7e41109b5850c6e89f31
|
||||
F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247
|
||||
F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1
|
||||
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
|
||||
F src/tclsqlite.c 6c2151b6d8d98e183a04466d40df8889c0574d79
|
||||
F src/tclsqlite.c 418f5e5e0840425a7e5b33f3600dccd378a57549
|
||||
F src/test1.c 8a98191a1da8e100f77cdb5cc716df67d405028d
|
||||
F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
|
||||
F src/test3.c d03f5b5da9a2410b7a91c64b0d3306ed28ab6fee
|
||||
F src/test4.c 18ec393bb4d0ad1de729f0b94da7267270f3d8e6
|
||||
F src/test5.c 328aae2c010c57a9829d255dc099d6899311672d
|
||||
F src/test6.c 004ad42f121f693b8cbe060d1a330678abc61620
|
||||
F src/test6.c 55aa2775c154415dcf4ed7cd1e19a193122b3a02
|
||||
F src/test7.c 5612e9aecf934d6df7bba6ce861fdf5ba5456010
|
||||
F src/test8.c 4f4904721167b32f7a4fa8c7b32a07a673d6cc86
|
||||
F src/test9.c 12e5ba554d2d1cbe0158f6ab3f7ffcd7a86ee4e5
|
||||
@@ -421,7 +416,7 @@ F src/test_async.c 195ab49da082053fdb0f949c114b806a49ca770a
|
||||
F src/test_autoext.c 915d245e736652a219a907909bb6710f0d587871
|
||||
F src/test_backup.c bf5da90c9926df0a4b941f2d92825a01bbe090a0
|
||||
F src/test_bestindex.c d23f80d334c59662af69191854c76b8d3d0c8c96
|
||||
F src/test_blob.c f65ac717da2618691cf9dad094e6da0219dcd208
|
||||
F src/test_blob.c 6a4c7920d1d9c6cc0f7aa50c89c4f80016aeda83
|
||||
F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274
|
||||
F src/test_config.c 83179ea845479b5be9a651d014649e3f2722a1fe
|
||||
F src/test_delete.c af7eab5702f853fb1c62a5f7665e2234cf1ae17b
|
||||
@@ -458,31 +453,31 @@ F src/test_windirent.c 17f91f5f2aa1bb7328abb49414c363b5d2a9d3ff
|
||||
F src/test_windirent.h 5d67483a55442e31e1bde0f4a230e6e932ad5906
|
||||
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
|
||||
F src/tokenize.c dc748c5afcb9e5beb3ef5651bc99a4622e30f6a1
|
||||
F src/tokenize.c 25ccc63ae2c4163933221f3181c9982b47cd08d2
|
||||
F src/treeview.c 4e44ade3bfe59d82005039f72e09333ce2b4162c
|
||||
F src/trigger.c c9f0810043b265724fdb1bdd466894f984dfc182
|
||||
F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58
|
||||
F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c
|
||||
F src/util.c ca8440ede81e155d15cff7c101654f60b55a9ae6
|
||||
F src/vacuum.c 1fe4555cd8c9b263afb85b5b4ee3a4a4181ad569
|
||||
F src/vdbe.c f520378e510fd36bbf289921798dbc8f2b3dc30d
|
||||
F src/util.c a88b0466fddf445ce752226d4698ca3faada620a
|
||||
F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16
|
||||
F src/vdbe.c e7b1e860140f1d1803c6f4176b1e8f3801f3a290
|
||||
F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c
|
||||
F src/vdbeInt.h 4e4b15b2e1330e1636e4e01974eab2b0b985092f
|
||||
F src/vdbeapi.c 5b08d82592bcff4470601fe78aaabebd50837860
|
||||
F src/vdbeaux.c 57361f2e761d92a254638bdbfc03fc68ae6aebc6
|
||||
F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9
|
||||
F src/vdbeapi.c 3e4a8893feeb78620f4aac4ac5b85d92255b97e1
|
||||
F src/vdbeaux.c b9a36e530e6525ca9d9a685bc7b1d01fa77b5cf8
|
||||
F src/vdbeblob.c a0e2edbfff53935c5434e2bce031801decd0e6dd
|
||||
F src/vdbemem.c 3b5a9a5b375458d3e12a50ae1aaa41eeec2175fd
|
||||
F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face
|
||||
F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834
|
||||
F src/vtab.c 007513c2ef52472fcdea6a741683d50662e82790
|
||||
F src/vtab.c c4bbe0f870f52036553f8098aee0703997f0577a
|
||||
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c 40c543f0a2195d1b0dc88ef12142bea690009344
|
||||
F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71
|
||||
F src/walker.c b71a992b413b3a022572eccf29ef4b4890223791
|
||||
F src/where.c 1a3a8adb717a20f17c186f3baa22b0b5f3a5ab13
|
||||
F src/whereInt.h 2d50c2b74a33be44cb68fdecee30b4d93552f1f4
|
||||
F src/wherecode.c 677e95413c472c0b413023b6b69a47f40fce1b04
|
||||
F src/whereexpr.c 130cdd1a43af71b19755270fb1224874cf55158c
|
||||
F src/walker.c 91a6df7435827e41cff6bb7df50ea00934ee78b0
|
||||
F src/where.c bc71775e23d23334e8f449aa31012d692dc09cb2
|
||||
F src/whereInt.h 2bcc3d176e6091cb8f50a30b65c006e88a73614d
|
||||
F src/wherecode.c 99a8ced164c75edf41b3a865a75381c9adb38b28
|
||||
F src/whereexpr.c 35ad025389a632a3987a35617c878be3b3d70dc6
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
|
||||
F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
|
||||
@@ -525,7 +520,6 @@ F test/attachmalloc.test 3a4bfca9545bfe906a8d2e622de10fbac5b711b0
|
||||
F test/auth.test c6ede04bee65637ff354b43fc1235aa560c0863e
|
||||
F test/auth2.test 9eb7fce9f34bf1f50d3f366fb3e606be5a2000a1
|
||||
F test/auth3.test 0d48b901cf111c14b4b1b5205c7d28f1a278190f
|
||||
F test/autoanalyze1.test 1ba80d5e1412d46503566b70741a5eea060da929
|
||||
F test/autoinc.test 6ae8fb69c9f656962464ae4e6667045d0dfc3b46
|
||||
F test/autoindex1.test 14b63a9f1e405fe6d5bfc8c8d00249c2ebaf13ea
|
||||
F test/autoindex2.test 12ef578928102baaa0dc23ad397601a2f4ecb0df
|
||||
@@ -580,7 +574,7 @@ F test/capi3d.test 485048dc5cd07bc68011e4917ad035ad6047ab82
|
||||
F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe
|
||||
F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3
|
||||
F test/cffault.test 9d6b20606afe712374952eec4f8fd74b1a8097ef
|
||||
F test/check.test 92b23a91fb7be12fba7ee9ce518217e2919a21da
|
||||
F test/check.test 85a84bfc4be0e83f668747211c7cd45a6721d485
|
||||
F test/close.test 83947daf3b700631f90f4850ddaab455be4af73d
|
||||
F test/closure01.test b1703ba40639cfc9b295cf478d70739415eec6a4
|
||||
F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91
|
||||
@@ -612,7 +606,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 46ec43bd90a02fd7b37ad8a7a949c55aa5717f89
|
||||
F test/corruptC.test 4ef10844eba5213bd262f4d96784d7fcda114afe
|
||||
F test/corruptD.test b3c205fac7952b1de645ce44bb02335cd9e3e040
|
||||
F test/corruptE.test 82ccf4f8f543fdbedd4aa42c709cb077f7374c62
|
||||
F test/corruptF.test be9fde98e4c93648f1ba52b74e5318edc8f59fe4
|
||||
@@ -620,7 +614,6 @@ F test/corruptG.test adf79b669cbfd19e28c8191a610d083ae53a6d51
|
||||
F test/corruptH.test 79801d97ec5c2f9f3c87739aa1ec2eb786f96454
|
||||
F test/corruptI.test 075fe1d75aa1d84e2949be56b6264376c41502e4
|
||||
F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4
|
||||
F test/corruptK.test 814a59ec699d8546b4e29005fba3d16e933ef2fe
|
||||
F test/cost.test 1eedbfd868f806f3fa08ff072b04cf270dcf61c8
|
||||
F test/count.test cb2e0f934c6eb33670044520748d2ecccd46259c
|
||||
F test/coveridxscan.test b629e896b14df2f000a99b8d170d80589c46562c
|
||||
@@ -640,8 +633,8 @@ F test/csv01.test e0ba3caaa57e4c667a0b45977689fb8082f14348
|
||||
F test/ctime.test ff6c38e822459d6ca743c34901caf57740b08b54
|
||||
F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856
|
||||
F test/cursorhint2.test 8457e93d97f665f23f97cdbc8477d16e3480331b
|
||||
F test/date.test 9b73bbeb1b82d9c1f44dec5cf563bf7da58d2373
|
||||
F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e
|
||||
F test/date.test a6a5a48b90907bca9fbcc79a30be5a715c1ab2fc
|
||||
F test/dbfuzz.c 8cc2bdb818b4483a052f9f80f96be74cbd9a6e1d
|
||||
F test/dbstatus.test 73149851b3aff14fc6db478e58f9083a66422cf5
|
||||
F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab
|
||||
F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d
|
||||
@@ -659,7 +652,7 @@ F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376
|
||||
F test/e_blobbytes.test 439a945953b35cb6948a552edaec4dc31fd70a05
|
||||
F test/e_blobclose.test 4b3c8c60c2171164d472059c73e9f3c1844bb66d
|
||||
F test/e_blobopen.test e95e1d40f995056f6f322cd5e1a1b83a27e1a145
|
||||
F test/e_blobwrite.test 650ded42ee5e0c2dbf263583ce01adf280129599
|
||||
F test/e_blobwrite.test 98c2f532be5b4e5f7b4d653f716bec06835b7957
|
||||
F test/e_changes.test fd66105385153dbf21fdb35eb8ef6c3e1eade579
|
||||
F test/e_createtable.test d4c6059d44dcd4b636de9aae322766062b471844
|
||||
F test/e_delete.test ab39084f26ae1f033c940b70ebdbbd523dc4962e
|
||||
@@ -681,7 +674,6 @@ F test/e_wal.test ae9a593207a77d711443ee69ffe081fda9243625
|
||||
F test/e_walauto.test 248af31e73c98df23476a22bdb815524c9dc3ba8
|
||||
F test/e_walckpt.test 28c371a6bb5e5fe7f31679c1df1763a19d19e8a0
|
||||
F test/e_walhook.test 4c0613a0c76e7a9d5c4c211e1b4cbcc1143914df
|
||||
F test/emptytable.test a38110becbdfa6325cd65cb588dca658cd885f62
|
||||
F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea
|
||||
F test/enc2.test 83437a79ba1545a55fb549309175c683fb334473
|
||||
F test/enc3.test 6807f7a7740a00361ca8d0ccd66bc60c8dc5f2b6
|
||||
@@ -810,7 +802,6 @@ F test/fts4growth.test e5390da74619cacc389711bac9349640b32c4f9a
|
||||
F test/fts4growth2.test 13ad4e76451af6e6906c95cdc725d01b00044269
|
||||
F test/fts4incr.test 4e353a0bd886ea984e56fce9e77724fc923b8d0d
|
||||
F test/fts4langid.test 65a7332c9bc257919e259a304aa8a38c41655b9d
|
||||
F test/fts4lastrowid.test fa5e157955a3121615ef3e16ff5196e96c9e1e64
|
||||
F test/fts4merge.test d2b39f6b1bd4a9738a13540e2d044cba11c43d47
|
||||
F test/fts4merge2.test 5faa558d1b672f82b847d2a337465fa745e46891
|
||||
F test/fts4merge3.test 8d9ccb4a3d41c4c617a149d6c4b13ad02de797d0
|
||||
@@ -856,10 +847,10 @@ F test/in4.test d2b38cba404bc4320f4fe1b595b3d163f212c068
|
||||
F test/in5.test 6c006e0bcd7351b69350ef566e65f244023489e9
|
||||
F test/incrblob.test c9b96afc292aeff43d6687bcb09b0280aa599822
|
||||
F test/incrblob2.test a5ce5ed1d0b01e2ed347245a21170372528af0a5
|
||||
F test/incrblob3.test d8d036fde015d4a159cd3cbae9d29003b37227a4
|
||||
F test/incrblob3.test f1b473c65d8bb43b5f4e2bdcc3f7fc3ac83fd19c
|
||||
F test/incrblob4.test 21a52a6843a56cdcce968c6a86b72a7066d0e6ba
|
||||
F test/incrblob_err.test 69f9247fed50278d48ea710d1a8f9cdb09e4c0b8
|
||||
F test/incrblobfault.test 74dd8ac108304cea0b4a0df6df63a1567e558758
|
||||
F test/incrblobfault.test 280474078f6da9e732cd2a215d3d854969014b6e
|
||||
F test/incrcorrupt.test 6c567fbf870aa9e91866fe52ce6f200cd548939a
|
||||
F test/incrvacuum.test d2a6ddf5e429720b5fe502766af747915ccf6c32
|
||||
F test/incrvacuum2.test 7d26cfda66c7e55898d196de54ac4ec7d86a4e3d
|
||||
@@ -874,7 +865,7 @@ F test/index6.test b4fc812290067a578b98bb2667b676db89e202a7
|
||||
F test/index7.test 7feababe16f2091b229c22aff2bcc1d4d6b9d2bb
|
||||
F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7
|
||||
F test/indexedby.test 9c4cd331224e57f79fbf411ae245e6272d415985
|
||||
F test/indexexpr1.test 038b3befa74e5a75126b6e9dd2ae5df61c1c7cf7
|
||||
F test/indexexpr1.test 7d243fac508b4a99fb900ffe34eb488312cfce84
|
||||
F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d
|
||||
F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
|
||||
F test/insert.test 38742b5e9601c8f8d76e9b7555f7270288c2d371
|
||||
@@ -911,7 +902,7 @@ F test/json101.test c0897616f32d95431f37fd291cb78742181980ac
|
||||
F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a
|
||||
F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0
|
||||
F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
|
||||
F test/kvtest.c b9a9822dda05a1aa481215a52e2fc93cd8b22ee5
|
||||
F test/kvtest.c 7a3c38ee56b9cc45dc5a5edc50fd9bc9425659a9
|
||||
F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
|
||||
F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
|
||||
F test/like.test 0603f4fa0dad50987f70032c05800cbfa8985302
|
||||
@@ -935,7 +926,7 @@ F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9
|
||||
F test/malloc.test 21c213365f2cca95ab2d7dc078dc8525f96065f8
|
||||
F test/malloc3.test e3b32c724b5a124b57cb0ed177f675249ad0c66a
|
||||
F test/malloc4.test 957337613002b7058a85116493a262f679f3a261
|
||||
F test/malloc5.test 192d0b5ee1d023a07d5164c34cf47d010da73da1
|
||||
F test/malloc5.test 02ed7c5313f0a68d95f2dfca8c8962132bd1f04b
|
||||
F test/malloc6.test 2f039d9821927eacae43e1831f815e157659a151
|
||||
F test/malloc7.test 7c68a32942858bc715284856c5507446bba88c3a
|
||||
F test/malloc8.test 9b7a3f8cb9cf0b12fff566e80a980b1767bd961d
|
||||
@@ -1006,7 +997,7 @@ F test/orderby7.test 3d1383d52ade5b9eb3a173b3147fdd296f0202da
|
||||
F test/orderby8.test 23ef1a5d72bd3adcc2f65561c654295d1b8047bd
|
||||
F test/orderby9.test 87fb9548debcc2cd141c5299002dd94672fa76a3
|
||||
F test/oserror.test b32dc34f2363ef18532e3a0a7358e3e7e321974f
|
||||
F test/ossfuzz.c f04b9f236e51d4db701bdebe8ac01318c83102a8
|
||||
F test/ossfuzz.c e469138f4be3e92df6173b79b3b216ab6e17b407
|
||||
F test/ossshell.c d9f1a6f43e7bab45d6be857a5800f5d4a1861db3
|
||||
F test/ovfl.test 199c482696defceacee8c8e0e0ef36da62726b2f
|
||||
F test/pager1.test 841868017e9dd3cb459b8d78862091a7d9cff21d
|
||||
@@ -1022,13 +1013,13 @@ F test/parser1.test 391b9bf9a229547a129c61ac345ed1a6f5eb1854
|
||||
F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
|
||||
F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
|
||||
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
|
||||
F test/permutations.test 46ad98770d3c04ce2418cab2cc527647bfe961a7
|
||||
F test/permutations.test cd0b7bc04bf5e50d3a993d24c834d591f7d4f5fe
|
||||
F test/pragma.test 1e94755164a3a3264cd39836de4bebcb7809e5f8
|
||||
F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f
|
||||
F test/pragma3.test 14c12bc5352b1e100e0b6b44f371053a81ccf8ed
|
||||
F test/pragma4.test 6e85b6eab8e61ffc9c7db59d842276674e8e3264
|
||||
F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc
|
||||
F test/printf2.test 9e6db85f81c63f2367c34a9d7db384088bd374ad
|
||||
F test/printf2.test 0b61566dd1c0f0b802f59dffa228c5dc5aa6b054
|
||||
F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb
|
||||
F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
|
||||
F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca
|
||||
@@ -1109,7 +1100,7 @@ F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5
|
||||
F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e
|
||||
F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506
|
||||
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
|
||||
F test/shell1.test bc1ca4161e1f459c9cd412d3f21f4ee635cf2322
|
||||
F test/shell1.test 52ac23a345772ab0d6d3241a21a633fdaa3ed581
|
||||
F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b
|
||||
F test/shell3.test 9b95ba643eaa228376f06a898fb410ee9b6e57c1
|
||||
F test/shell4.test 89ad573879a745974ff2df20ff97c5d6ffffbd5d
|
||||
@@ -1144,7 +1135,7 @@ F test/speed3.test 694affeb9100526007436334cf7d08f3d74b85ef
|
||||
F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715
|
||||
F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
|
||||
F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
|
||||
F test/speedtest1.c 7b1ab42b097b484c18d99e1d1c71a6a0c9c87a7a
|
||||
F test/speedtest1.c 02fe15bb784c5276a083ffe9969cc51e0bce7644
|
||||
F test/spellfix.test f9c1f431e2c096c8775fec032952320c0e4700db
|
||||
F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3
|
||||
F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33
|
||||
@@ -1176,7 +1167,7 @@ F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
|
||||
F test/temptable2.test cd396beb41117a5302fff61767c35fa4270a0d5e
|
||||
F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637
|
||||
F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc
|
||||
F test/tester.tcl 581f0185434daf7026ccede4c07e8d1479186ec5
|
||||
F test/tester.tcl 2a49c1aff731f380ea640106377e19611a1443ae
|
||||
F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5
|
||||
F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
|
||||
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
|
||||
@@ -1212,7 +1203,7 @@ F test/tkt-5e10420e8d.test 904d1687b3c06d43e5b3555bbcf6802e7c0ffd84
|
||||
F test/tkt-5ee23731f.test 9db6e1d7209dc0794948b260d6f82b2b1de83a9f
|
||||
F test/tkt-6bfb98dfc0.test 24780633627b5cfc0635a5500c2389ebfb563336
|
||||
F test/tkt-752e1646fc.test ea78d88d14fe9866bdd991c634483334639e13bf
|
||||
F test/tkt-78e04e52ea.test 1b2e6bf4f1d9887b216b6da774e5f25915ec8118
|
||||
F test/tkt-78e04e52ea.test 813779f8888f3ca226df656c4eef078f9635f3c9
|
||||
F test/tkt-7a31705a7e6.test e75a2bba4eec801b92c8040eb22096ac6d35e844
|
||||
F test/tkt-7bbfb7d442.test 7b2cd79c7a17ae6750e75ec1a7846712a69c9d18
|
||||
F test/tkt-80ba201079.test 105a721e6aad0ae3c5946d7615d1e4d03f6145b8
|
||||
@@ -1381,7 +1372,7 @@ F test/vacuummem.test 7b42abb3208bd82dd23a7536588396f295a314f2
|
||||
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
|
||||
F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
|
||||
F test/view.test 765802c7a66d37fabd5ac8e2f2dbe572b43eb9ab
|
||||
F test/vtab1.test ed4a576231d8a36e70fd18e2b79b621b31e7f22a
|
||||
F test/vtab1.test 7c4b81abd88361ada9cbe414c459efca26be6bda
|
||||
F test/vtab2.test f8cd1bb9aba7143eba97812d9617880a36d247ad
|
||||
F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e
|
||||
F test/vtab4.test 8e73ed268f3d596bc3590f45fc948fb40f28e9c3
|
||||
@@ -1396,7 +1387,7 @@ F test/vtabC.test 4528f459a13136f982e75614d120aef165f17292
|
||||
F test/vtabD.test 05b3f1d77117271671089e48719524b676842e96
|
||||
F test/vtabE.test d5024aa42754962f6bb0afd261681686488e7afe
|
||||
F test/vtabF.test 1918844c7c902f6a16c8dacf1ec8f84886d6e78b
|
||||
F test/vtabH.test 5f9253eb9e41ba9fe94f4aa3e9230191893d7764
|
||||
F test/vtabH.test a2912cd3ea3386aecc3cb74ebfdfcc4e6d4b7dd3
|
||||
F test/vtabI.test 751b07636700dbdea328e4265b6077ccd6811a3f
|
||||
F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5
|
||||
F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
|
||||
@@ -1472,10 +1463,10 @@ F test/wordcount.c 06efb84b7c48a4973c2c24ea06c93d00bce24389
|
||||
F test/zeroblob.test 3857870fe681b8185654414a9bccfde80b62a0fa
|
||||
F test/zerodamage.test e59a56443d6298ecf7435f618f0b27654f0c849e
|
||||
F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5
|
||||
F tool/GetTclKit.bat 6afa640edc7810725aec61c3076ac617c4aaf0b7
|
||||
F tool/GetTclKit.bat f94784e3bdc2f50c539266f5467cbf1f27612cb3
|
||||
F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91
|
||||
F tool/addopcodes.tcl 10c889c4a65ec6c5604e4a47306fa77ff57ae189
|
||||
F tool/build-all-msvc.bat c12328d06c45fec8baada5949e3d5af54bf8c887 x
|
||||
F tool/build-all-msvc.bat 018c1b273458a90c8ba633c6f0c5654cfcb138bf x
|
||||
F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367
|
||||
F tool/cg_anno.tcl f95b0006c52cf7f0496b506343415b6ee3cdcdd3 x
|
||||
F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2
|
||||
@@ -1493,18 +1484,17 @@ F tool/lempar.c db1bdb4821f2d8fbd76e577cf3ab18642c8d08d1
|
||||
F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9
|
||||
F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862
|
||||
F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca
|
||||
F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439
|
||||
F tool/mkautoconfamal.sh e855df211ecbcc7131dee817110ff386cfb112f7
|
||||
F tool/mkkeywordhash.c f7f3b342211ac6a14258b9726d5b97cf4f548f22
|
||||
F tool/mkmsvcmin.tcl 95b37e202cbed873aa8ffdbb493b9db45927be2b
|
||||
F tool/mkmsvcmin.tcl 2f12f7fa8858bbe61cf81820a2da96c79ed1ca8d
|
||||
F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c
|
||||
F tool/mkopcodeh.tcl a01d2c1d8a6205b03fc635adf3735b4c523befd3
|
||||
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
|
||||
F tool/mkpragmatab.tcl 2ffe6d5fdc2d3381621d6c77978ba054466e757f
|
||||
F tool/mkpragmatab.tcl ebb4bfcd2f8010e0a3934b6118db4b5f2f5edf5c
|
||||
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
|
||||
F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb
|
||||
F tool/mksqlite3c.tcl 06b2e6a0f21cc0a5d70fbbd136b3e0a96470645e
|
||||
F tool/mksqlite3h.tcl b9836752c3d08f9fab2dfc0017ca9fd5d90ac863
|
||||
F tool/mksqlite3h.tcl c006c4e5da57c649b24b689511dcd270dd7b0249
|
||||
F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b
|
||||
F tool/mkvsix.tcl b9e0777a213c23156b6542842c238479e496ebf5
|
||||
F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091
|
||||
@@ -1562,10 +1552,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 7359fcacaadc349f520536311dcd1d0b5cea7673
|
||||
R 21dd742a2e245e17ea4fce05d92294e6
|
||||
T *branch * string-quoting-dump
|
||||
T *sym-string-quoting-dump *
|
||||
T -sym-trunk *
|
||||
P 53b77838f05b4805b956b5763c75af434662fb20 97ccf3e4de11ffea46993cb7fb7ab559b9810705
|
||||
R 2f9978803a25617be0ce666b2a1de5c0
|
||||
U drh
|
||||
Z 185539d207724f873d847ed122ae7c58
|
||||
Z 44ad075deb400520ebcde6cf0102f52f
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
8b2954dd8376e2de985cf5dedeb6eec32c430505
|
||||
61bd2a885da45e7fa4f02ea1c44d6706faa6bf46
|
||||
+30
-46
@@ -290,7 +290,6 @@ struct Stat4Accum {
|
||||
Stat4Sample *aBest; /* Array of nCol best samples */
|
||||
int iMin; /* Index in a[] of entry with minimum score */
|
||||
int nSample; /* Current number of samples */
|
||||
int nMaxEqZero; /* Max leading 0 in anEq[] for any a[] entry */
|
||||
int iGet; /* Index of current sample accessed by stat_get() */
|
||||
Stat4Sample *a; /* Array of mxSample Stat4Sample objects */
|
||||
sqlite3 *db; /* Database connection, for malloc() */
|
||||
@@ -555,13 +554,6 @@ static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){
|
||||
assert( IsStat4 || nEqZero==0 );
|
||||
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
/* Stat4Accum.nMaxEqZero is set to the maximum number of leading 0
|
||||
** values in the anEq[] array of any sample in Stat4Accum.a[]. In
|
||||
** other words, if nMaxEqZero is n, then it is guaranteed that there
|
||||
** are no samples with Stat4Sample.anEq[m]==0 for (m>=n). */
|
||||
if( nEqZero>p->nMaxEqZero ){
|
||||
p->nMaxEqZero = nEqZero;
|
||||
}
|
||||
if( pNew->isPSample==0 ){
|
||||
Stat4Sample *pUpgrade = 0;
|
||||
assert( pNew->anEq[pNew->iCol]>0 );
|
||||
@@ -659,22 +651,12 @@ static void samplePushPrevious(Stat4Accum *p, int iChng){
|
||||
}
|
||||
}
|
||||
|
||||
/* Check that no sample contains an anEq[] entry with an index of
|
||||
** p->nMaxEqZero or greater set to zero. */
|
||||
/* Update the anEq[] fields of any samples already collected. */
|
||||
for(i=p->nSample-1; i>=0; i--){
|
||||
int j;
|
||||
for(j=p->nMaxEqZero; j<p->nCol; j++) assert( p->a[i].anEq[j]>0 );
|
||||
}
|
||||
|
||||
/* Update the anEq[] fields of any samples already collected. */
|
||||
if( iChng<p->nMaxEqZero ){
|
||||
for(i=p->nSample-1; i>=0; i--){
|
||||
int j;
|
||||
for(j=iChng; j<p->nCol; j++){
|
||||
if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j];
|
||||
}
|
||||
for(j=iChng; j<p->nCol; j++){
|
||||
if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j];
|
||||
}
|
||||
p->nMaxEqZero = iChng;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1388,14 +1370,27 @@ void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){
|
||||
if( i==1 ) continue; /* Do not analyze the TEMP database */
|
||||
analyzeDatabase(pParse, i);
|
||||
}
|
||||
}else if( pName2->n==0 && (iDb = sqlite3FindDb(db, pName1))>=0 ){
|
||||
/* Analyze the schema named as the argument */
|
||||
analyzeDatabase(pParse, iDb);
|
||||
}else if( pName2->n==0 ){
|
||||
/* Form 2: Analyze the database or table named */
|
||||
iDb = sqlite3FindDb(db, pName1);
|
||||
if( iDb>=0 ){
|
||||
analyzeDatabase(pParse, iDb);
|
||||
}else{
|
||||
z = sqlite3NameFromToken(db, pName1);
|
||||
if( z ){
|
||||
if( (pIdx = sqlite3FindIndex(db, z, 0))!=0 ){
|
||||
analyzeTable(pParse, pIdx->pTable, pIdx);
|
||||
}else if( (pTab = sqlite3LocateTable(pParse, 0, z, 0))!=0 ){
|
||||
analyzeTable(pParse, pTab, 0);
|
||||
}
|
||||
sqlite3DbFree(db, z);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
/* Form 3: Analyze the table or index named as an argument */
|
||||
/* Form 3: Analyze the fully qualified table name */
|
||||
iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pTableName);
|
||||
if( iDb>=0 ){
|
||||
zDb = pName2->n ? db->aDb[iDb].zDbSName : 0;
|
||||
zDb = db->aDb[iDb].zDbSName;
|
||||
z = sqlite3NameFromToken(db, pTableName);
|
||||
if( z ){
|
||||
if( (pIdx = sqlite3FindIndex(db, z, zDb))!=0 ){
|
||||
@@ -1405,11 +1400,10 @@ void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){
|
||||
}
|
||||
sqlite3DbFree(db, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
if( db->nSqlExec==0 && (v = sqlite3GetVdbe(pParse))!=0 ){
|
||||
sqlite3VdbeAddOp0(v, OP_Expire);
|
||||
}
|
||||
}
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
if( v ) sqlite3VdbeAddOp0(v, OP_Expire);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1538,11 +1532,7 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
|
||||
#endif
|
||||
pIndex->bUnordered = 0;
|
||||
decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex);
|
||||
pIndex->hasStat1 = 1;
|
||||
if( pIndex->pPartIdxWhere==0 ){
|
||||
pTable->nRowLogEst = pIndex->aiRowLogEst[0];
|
||||
pTable->tabFlags |= TF_HasStat1;
|
||||
}
|
||||
if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0];
|
||||
}else{
|
||||
Index fakeIdx;
|
||||
fakeIdx.szIdxRow = pTable->szTabRow;
|
||||
@@ -1551,7 +1541,6 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
|
||||
#endif
|
||||
decodeIntArray((char*)z, 1, 0, &pTable->nRowLogEst, &fakeIdx);
|
||||
pTable->szTabRow = fakeIdx.szIdxRow;
|
||||
pTable->tabFlags |= TF_HasStat1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1846,20 +1835,15 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
|
||||
HashElem *i;
|
||||
char *zSql;
|
||||
int rc = SQLITE_OK;
|
||||
Schema *pSchema = db->aDb[iDb].pSchema;
|
||||
|
||||
assert( iDb>=0 && iDb<db->nDb );
|
||||
assert( db->aDb[iDb].pBt!=0 );
|
||||
|
||||
/* Clear any prior statistics */
|
||||
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
|
||||
for(i=sqliteHashFirst(&pSchema->tblHash); i; i=sqliteHashNext(i)){
|
||||
Table *pTab = sqliteHashData(i);
|
||||
pTab->tabFlags &= ~TF_HasStat1;
|
||||
}
|
||||
for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
|
||||
for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
|
||||
Index *pIdx = sqliteHashData(i);
|
||||
pIdx->hasStat1 = 0;
|
||||
pIdx->aiRowLogEst[0] = 0;
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
sqlite3DeleteIndexSamples(db, pIdx);
|
||||
pIdx->aSample = 0;
|
||||
@@ -1882,9 +1866,9 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
|
||||
|
||||
/* Set appropriate defaults on all indexes not in the sqlite_stat1 table */
|
||||
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
|
||||
for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
|
||||
for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
|
||||
Index *pIdx = sqliteHashData(i);
|
||||
if( !pIdx->hasStat1 ) sqlite3DefaultRowEst(pIdx);
|
||||
if( pIdx->aiRowLogEst[0]==0 ) sqlite3DefaultRowEst(pIdx);
|
||||
}
|
||||
|
||||
/* Load the statistics from the sqlite_stat4 table. */
|
||||
@@ -1894,7 +1878,7 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
|
||||
rc = loadStat4(db, sInfo.zDatabase);
|
||||
db->lookaside.bDisable--;
|
||||
}
|
||||
for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
|
||||
for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
|
||||
Index *pIdx = sqliteHashData(i);
|
||||
sqlite3_free(pIdx->aiRowEst);
|
||||
pIdx->aiRowEst = 0;
|
||||
|
||||
+16
-89
@@ -1317,18 +1317,17 @@ static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){
|
||||
|
||||
|
||||
/*
|
||||
** Defragment the page given. This routine reorganizes cells within the
|
||||
** page so that there are no free-blocks on the free-block list.
|
||||
**
|
||||
** Parameter nMaxFrag is the maximum amount of fragmented space that may be
|
||||
** present in the page after this routine returns.
|
||||
** Defragment the page given. All Cells are moved to the
|
||||
** end of the page and all free space is collected into one
|
||||
** big FreeBlk that occurs in between the header and cell
|
||||
** pointer array and the cell content area.
|
||||
**
|
||||
** EVIDENCE-OF: R-44582-60138 SQLite may from time to time reorganize a
|
||||
** b-tree page so that there are no freeblocks or fragment bytes, all
|
||||
** unused bytes are contained in the unallocated space region, and all
|
||||
** cells are packed tightly at the end of the page.
|
||||
*/
|
||||
static int defragmentPage(MemPage *pPage, int nMaxFrag){
|
||||
static int defragmentPage(MemPage *pPage){
|
||||
int i; /* Loop counter */
|
||||
int pc; /* Address of the i-th cell */
|
||||
int hdr; /* Offset to the page header */
|
||||
@@ -1343,6 +1342,7 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
|
||||
int iCellFirst; /* First allowable cell index */
|
||||
int iCellLast; /* Last possible cell index */
|
||||
|
||||
|
||||
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
|
||||
assert( pPage->pBt!=0 );
|
||||
assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE );
|
||||
@@ -1354,56 +1354,9 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
|
||||
cellOffset = pPage->cellOffset;
|
||||
nCell = pPage->nCell;
|
||||
assert( nCell==get2byte(&data[hdr+3]) );
|
||||
iCellFirst = cellOffset + 2*nCell;
|
||||
usableSize = pPage->pBt->usableSize;
|
||||
|
||||
/* This block handles pages with two or fewer free blocks and nMaxFrag
|
||||
** or fewer fragmented bytes. In this case it is faster to move the
|
||||
** two (or one) blocks of cells using memmove() and add the required
|
||||
** offsets to each pointer in the cell-pointer array than it is to
|
||||
** reconstruct the entire page. */
|
||||
if( (int)data[hdr+7]<=nMaxFrag ){
|
||||
int iFree = get2byte(&data[hdr+1]);
|
||||
if( iFree ){
|
||||
int iFree2 = get2byte(&data[iFree]);
|
||||
|
||||
/* pageFindSlot() has already verified that free blocks are sorted
|
||||
** in order of offset within the page, and that no block extends
|
||||
** past the end of the page. Provided the two free slots do not
|
||||
** overlap, this guarantees that the memmove() calls below will not
|
||||
** overwrite the usableSize byte buffer, even if the database page
|
||||
** is corrupt. */
|
||||
assert( iFree2==0 || iFree2>iFree );
|
||||
assert( iFree+get2byte(&data[iFree+2]) <= usableSize );
|
||||
assert( iFree2==0 || iFree2+get2byte(&data[iFree2+2]) <= usableSize );
|
||||
|
||||
if( 0==iFree2 || (data[iFree2]==0 && data[iFree2+1]==0) ){
|
||||
u8 *pEnd = &data[cellOffset + nCell*2];
|
||||
u8 *pAddr;
|
||||
int sz2 = 0;
|
||||
int sz = get2byte(&data[iFree+2]);
|
||||
int top = get2byte(&data[hdr+5]);
|
||||
if( iFree2 ){
|
||||
if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_BKPT;
|
||||
sz2 = get2byte(&data[iFree2+2]);
|
||||
assert( iFree+sz+sz2+iFree2-(iFree+sz) <= usableSize );
|
||||
memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz));
|
||||
sz += sz2;
|
||||
}
|
||||
cbrk = top+sz;
|
||||
assert( cbrk+(iFree-top) <= usableSize );
|
||||
memmove(&data[cbrk], &data[top], iFree-top);
|
||||
for(pAddr=&data[cellOffset]; pAddr<pEnd; pAddr+=2){
|
||||
pc = get2byte(pAddr);
|
||||
if( pc<iFree ){ put2byte(pAddr, pc+sz); }
|
||||
else if( pc<iFree2 ){ put2byte(pAddr, pc+sz2); }
|
||||
}
|
||||
goto defragment_out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cbrk = usableSize;
|
||||
iCellFirst = cellOffset + 2*nCell;
|
||||
iCellLast = usableSize - 4;
|
||||
for(i=0; i<nCell; i++){
|
||||
u8 *pAddr; /* The i-th cell pointer */
|
||||
@@ -1437,18 +1390,16 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
|
||||
}
|
||||
memcpy(&data[cbrk], &src[pc], size);
|
||||
}
|
||||
data[hdr+7] = 0;
|
||||
|
||||
defragment_out:
|
||||
if( data[hdr+7]+cbrk-iCellFirst!=pPage->nFree ){
|
||||
return SQLITE_CORRUPT_BKPT;
|
||||
}
|
||||
assert( cbrk>=iCellFirst );
|
||||
put2byte(&data[hdr+5], cbrk);
|
||||
data[hdr+1] = 0;
|
||||
data[hdr+2] = 0;
|
||||
data[hdr+7] = 0;
|
||||
memset(&data[iCellFirst], 0, cbrk-iCellFirst);
|
||||
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
|
||||
if( cbrk-iCellFirst!=pPage->nFree ){
|
||||
return SQLITE_CORRUPT_BKPT;
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
@@ -1586,10 +1537,10 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
|
||||
testcase( gap+2+nByte==top );
|
||||
if( gap+2+nByte>top ){
|
||||
assert( pPage->nCell>0 || CORRUPT_DB );
|
||||
rc = defragmentPage(pPage, MIN(4, pPage->nFree - (2+nByte)));
|
||||
rc = defragmentPage(pPage);
|
||||
if( rc ) return rc;
|
||||
top = get2byteNotZero(&data[hdr+5]);
|
||||
assert( gap+2+nByte<=top );
|
||||
assert( gap+nByte<=top );
|
||||
}
|
||||
|
||||
|
||||
@@ -4825,7 +4776,7 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){
|
||||
pCur, pCur->curPagerFlags);
|
||||
}
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
#if SQLITE_DEBUG
|
||||
/*
|
||||
** Page pParent is an internal (non-leaf) tree page. This function
|
||||
** asserts that page number iChild is the left-child if the iIdx'th
|
||||
@@ -5368,30 +5319,6 @@ int sqlite3BtreeEof(BtCursor *pCur){
|
||||
return (CURSOR_VALID!=pCur->eState);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return an estimate for the number of rows in the table that pCur is
|
||||
** pointing to. Return a negative number if no estimate is currently
|
||||
** available.
|
||||
*/
|
||||
i64 sqlite3BtreeRowCountEst(BtCursor *pCur){
|
||||
i64 n;
|
||||
u8 i;
|
||||
|
||||
assert( cursorOwnsBtShared(pCur) );
|
||||
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
|
||||
|
||||
/* Currently this interface is only called by the OP_IfSmaller
|
||||
** opcode, and it that case the cursor will always be valid and
|
||||
** will always point to a leaf node. */
|
||||
if( NEVER(pCur->eState!=CURSOR_VALID) ) return -1;
|
||||
if( NEVER(pCur->apPage[pCur->iPage]->leaf==0) ) return -1;
|
||||
|
||||
for(n=1, i=0; i<=pCur->iPage; i++){
|
||||
n *= pCur->apPage[i]->nCell;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
/*
|
||||
** Advance the cursor to the next entry in the database. If
|
||||
** successful then set *pRes=0. If the cursor
|
||||
@@ -6236,7 +6163,7 @@ static int fillInCell(
|
||||
** Use a call to btreeParseCellPtr() to verify that the values above
|
||||
** were computed correctly.
|
||||
*/
|
||||
#ifdef SQLITE_DEBUG
|
||||
#if SQLITE_DEBUG
|
||||
{
|
||||
CellInfo info;
|
||||
pPage->xParseCell(pPage, pCell, &info);
|
||||
@@ -7762,7 +7689,7 @@ static int balance_nonroot(
|
||||
** free space needs to be up front.
|
||||
*/
|
||||
assert( nNew==1 || CORRUPT_DB );
|
||||
rc = defragmentPage(apNew[0], -1);
|
||||
rc = defragmentPage(apNew[0]);
|
||||
testcase( rc!=SQLITE_OK );
|
||||
assert( apNew[0]->nFree ==
|
||||
(get2byte(&apNew[0]->aData[5])-apNew[0]->cellOffset-apNew[0]->nCell*2)
|
||||
|
||||
@@ -296,7 +296,6 @@ u32 sqlite3BtreePayloadSize(BtCursor*);
|
||||
|
||||
char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*);
|
||||
struct Pager *sqlite3BtreePager(Btree*);
|
||||
i64 sqlite3BtreeRowCountEst(BtCursor*);
|
||||
|
||||
#ifndef SQLITE_OMIT_INCRBLOB
|
||||
int sqlite3BtreePayloadChecked(BtCursor*, u32 offset, u32 amt, void*);
|
||||
|
||||
+4
-2
@@ -692,9 +692,11 @@ struct IntegrityCk {
|
||||
*/
|
||||
#if SQLITE_BYTEORDER==4321
|
||||
# define get2byteAligned(x) (*(u16*)(x))
|
||||
#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4008000
|
||||
#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
|
||||
&& GCC_VERSION>=4008000
|
||||
# define get2byteAligned(x) __builtin_bswap16(*(u16*)(x))
|
||||
#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
|
||||
#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
|
||||
&& defined(_MSC_VER) && _MSC_VER>=1300
|
||||
# define get2byteAligned(x) _byteswap_ushort(*(u16*)(x))
|
||||
#else
|
||||
# define get2byteAligned(x) ((x)[0]<<8 | (x)[1])
|
||||
|
||||
@@ -1115,7 +1115,6 @@ void sqlite3AddNotNull(Parse *pParse, int onError){
|
||||
p = pParse->pNewTable;
|
||||
if( p==0 || NEVER(p->nCol<1) ) return;
|
||||
p->aCol[p->nCol-1].notNull = (u8)onError;
|
||||
p->tabFlags |= TF_HasNotNull;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3455,9 +3454,6 @@ void sqlite3DefaultRowEst(Index *pIdx){
|
||||
int nCopy = MIN(ArraySize(aVal), pIdx->nKeyCol);
|
||||
int i;
|
||||
|
||||
/* Indexes with default row estimates should not have stat1 data */
|
||||
assert( !pIdx->hasStat1 );
|
||||
|
||||
/* Set the first entry (number of rows in the index) to the estimated
|
||||
** number of rows in the table, or half the number of rows in the table
|
||||
** for a partial index. But do not let the estimate drop below 10. */
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ static const char * const azCompileOpt[] = {
|
||||
#if SQLITE_COVERAGE_TEST
|
||||
"COVERAGE_TEST",
|
||||
#endif
|
||||
#ifdef SQLITE_DEBUG
|
||||
#if SQLITE_DEBUG
|
||||
"DEBUG",
|
||||
#endif
|
||||
#if SQLITE_DEFAULT_LOCKING_MODE
|
||||
|
||||
+1
-2
@@ -743,19 +743,18 @@ static int parseModifier(
|
||||
** or month or year.
|
||||
*/
|
||||
if( sqlite3_strnicmp(z, "start of ", 9)!=0 ) break;
|
||||
if( !p->validJD && !p->validYMD && !p->validHMS ) break;
|
||||
z += 9;
|
||||
computeYMD(p);
|
||||
p->validHMS = 1;
|
||||
p->h = p->m = 0;
|
||||
p->s = 0.0;
|
||||
p->rawS = 0;
|
||||
p->validTZ = 0;
|
||||
p->validJD = 0;
|
||||
if( sqlite3_stricmp(z,"month")==0 ){
|
||||
p->D = 1;
|
||||
rc = 0;
|
||||
}else if( sqlite3_stricmp(z,"year")==0 ){
|
||||
computeYMD(p);
|
||||
p->M = 1;
|
||||
p->D = 1;
|
||||
rc = 0;
|
||||
|
||||
+3
-14
@@ -231,7 +231,7 @@ static char comparisonAffinity(Expr *pExpr){
|
||||
aff = sqlite3CompareAffinity(pExpr->pRight, aff);
|
||||
}else if( ExprHasProperty(pExpr, EP_xIsSelect) ){
|
||||
aff = sqlite3CompareAffinity(pExpr->x.pSelect->pEList->a[0].pExpr, aff);
|
||||
}else if( aff==0 ){
|
||||
}else if( NEVER(aff==0) ){
|
||||
aff = SQLITE_AFF_BLOB;
|
||||
}
|
||||
return aff;
|
||||
@@ -2367,7 +2367,7 @@ static char *exprINAffinity(Parse *pParse, Expr *pExpr){
|
||||
char *zRet;
|
||||
|
||||
assert( pExpr->op==TK_IN );
|
||||
zRet = sqlite3DbMallocRaw(pParse->db, nVal+1);
|
||||
zRet = sqlite3DbMallocZero(pParse->db, nVal+1);
|
||||
if( zRet ){
|
||||
int i;
|
||||
for(i=0; i<nVal; i++){
|
||||
@@ -3272,7 +3272,7 @@ void sqlite3ExprCodeGetColumnToReg(
|
||||
void sqlite3ExprCacheClear(Parse *pParse){
|
||||
int i;
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
#if SQLITE_DEBUG
|
||||
if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
|
||||
printf("CLEAR\n");
|
||||
}
|
||||
@@ -4680,17 +4680,6 @@ int sqlite3ExprListCompare(ExprList *pA, ExprList *pB, int iTab){
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Like sqlite3ExprCompare() except COLLATE operators at the top-level
|
||||
** are ignored.
|
||||
*/
|
||||
int sqlite3ExprCompareSkip(Expr *pA, Expr *pB, int iTab){
|
||||
return sqlite3ExprCompare(
|
||||
sqlite3ExprSkipCollate(pA),
|
||||
sqlite3ExprSkipCollate(pB),
|
||||
iTab);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return true if we can prove the pE2 will always be true if pE1 is
|
||||
** true. Return false if we cannot complete the proof or if pE2 might
|
||||
|
||||
+4
-10
@@ -1527,9 +1527,6 @@ void sqlite3GenerateConstraintChecks(
|
||||
}
|
||||
sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[ix]);
|
||||
VdbeComment((v, "for %s", pIdx->zName));
|
||||
#ifdef SQLITE_ENABLE_NULL_TRIM
|
||||
if( pIdx->idxType==2 ) sqlite3SetMakeRecordP5(v, pIdx->pTable);
|
||||
#endif
|
||||
|
||||
/* In an UPDATE operation, if this index is the PRIMARY KEY index
|
||||
** of a WITHOUT ROWID table and there has been no change the
|
||||
@@ -1685,11 +1682,8 @@ void sqlite3SetMakeRecordP5(Vdbe *v, Table *pTab){
|
||||
** version 2 and later (SQLite version 3.1.4, 2005-02-20). */
|
||||
if( pTab->pSchema->file_format<2 ) return;
|
||||
|
||||
for(i=pTab->nCol-1; i>0; i--){
|
||||
if( pTab->aCol[i].pDflt!=0 ) break;
|
||||
if( pTab->aCol[i].colFlags & COLFLAG_PRIMKEY ) break;
|
||||
}
|
||||
sqlite3VdbeChangeP5(v, i+1);
|
||||
for(i=pTab->nCol; i>1 && pTab->aCol[i-1].pDflt==0; i--){}
|
||||
sqlite3VdbeChangeP5(v, i);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1979,7 +1973,7 @@ static int xferOptimization(
|
||||
return 0; /* tab1 must not have triggers */
|
||||
}
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
if( IsVirtual(pDest) ){
|
||||
if( pDest->tabFlags & TF_Virtual ){
|
||||
return 0; /* tab1 must not be a virtual table */
|
||||
}
|
||||
#endif
|
||||
@@ -2041,7 +2035,7 @@ static int xferOptimization(
|
||||
return 0; /* source and destination must both be WITHOUT ROWID or not */
|
||||
}
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
if( IsVirtual(pSrc) ){
|
||||
if( pSrc->tabFlags & TF_Virtual ){
|
||||
return 0; /* tab2 must not be a virtual table */
|
||||
}
|
||||
#endif
|
||||
|
||||
+1
-2
@@ -73,7 +73,7 @@ int sqlite3_exec(
|
||||
(SQLITE_DONE==rc && !callbackIsInit
|
||||
&& db->flags&SQLITE_NullCallback)) ){
|
||||
if( !callbackIsInit ){
|
||||
azCols = sqlite3DbMallocRaw(db, (2*nCol+1)*sizeof(const char*));
|
||||
azCols = sqlite3DbMallocZero(db, 2*nCol*sizeof(const char*) + 1);
|
||||
if( azCols==0 ){
|
||||
goto exec_out;
|
||||
}
|
||||
@@ -94,7 +94,6 @@ int sqlite3_exec(
|
||||
goto exec_out;
|
||||
}
|
||||
}
|
||||
azVals[i] = 0;
|
||||
}
|
||||
if( xCallback(pArg, nCol, azVals, azCols) ){
|
||||
/* EVIDENCE-OF: R-38229-40159 If the callback function to
|
||||
|
||||
-15
@@ -921,21 +921,6 @@ sqlite_int64 sqlite3_last_insert_rowid(sqlite3 *db){
|
||||
return db->lastRowid;
|
||||
}
|
||||
|
||||
/*
|
||||
** Set the value returned by the sqlite3_last_insert_rowid() API function.
|
||||
*/
|
||||
void sqlite3_set_last_insert_rowid(sqlite3 *db, sqlite3_int64 iRowid){
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !sqlite3SafetyCheckOk(db) ){
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
db->lastRowid = iRowid;
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the number of changes in the most recent call to sqlite3_exec().
|
||||
*/
|
||||
|
||||
+6
-21
@@ -219,27 +219,12 @@ static void sqlite3MallocAlarm(int nByte){
|
||||
*/
|
||||
static void mallocWithAlarm(int n, void **pp){
|
||||
void *p;
|
||||
int nFull;
|
||||
int nFull = 0;
|
||||
assert( sqlite3_mutex_held(mem0.mutex) );
|
||||
assert( n>0 );
|
||||
|
||||
/* In Firefox (circa 2017-02-08), xRoundup() is remapped to an internal
|
||||
** implementation of malloc_good_size(), which must be called in debug
|
||||
** mode and specifically when the DMD "Dark Matter Detector" is enabled
|
||||
** or else a crash results. Hence, do not attempt to optimize out the
|
||||
** following xRoundup() call. */
|
||||
nFull = sqlite3GlobalConfig.m.xRoundup(n);
|
||||
|
||||
#ifdef SQLITE_MAX_MEMORY
|
||||
if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)+nFull>SQLITE_MAX_MEMORY ){
|
||||
*pp = 0;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, n);
|
||||
if( mem0.alarmThreshold>0 ){
|
||||
sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
|
||||
nFull = sqlite3GlobalConfig.m.xRoundup(n);
|
||||
if( nUsed >= mem0.alarmThreshold - nFull ){
|
||||
mem0.nearlyFull = 1;
|
||||
sqlite3MallocAlarm(nFull);
|
||||
@@ -247,11 +232,11 @@ static void mallocWithAlarm(int n, void **pp){
|
||||
mem0.nearlyFull = 0;
|
||||
}
|
||||
}
|
||||
p = sqlite3GlobalConfig.m.xMalloc(nFull);
|
||||
p = sqlite3GlobalConfig.m.xMalloc(n);
|
||||
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
|
||||
if( p==0 && mem0.alarmThreshold>0 ){
|
||||
sqlite3MallocAlarm(nFull);
|
||||
p = sqlite3GlobalConfig.m.xMalloc(nFull);
|
||||
p = sqlite3GlobalConfig.m.xMalloc(n);
|
||||
}
|
||||
#endif
|
||||
if( p ){
|
||||
@@ -425,7 +410,7 @@ int sqlite3MallocSize(void *p){
|
||||
int sqlite3DbMallocSize(sqlite3 *db, void *p){
|
||||
assert( p!=0 );
|
||||
if( db==0 || !isLookaside(db,p) ){
|
||||
#ifdef SQLITE_DEBUG
|
||||
#if SQLITE_DEBUG
|
||||
if( db==0 ){
|
||||
assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
|
||||
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
|
||||
@@ -486,7 +471,7 @@ void sqlite3DbFree(sqlite3 *db, void *p){
|
||||
}
|
||||
if( isLookaside(db, p) ){
|
||||
LookasideSlot *pBuf = (LookasideSlot*)p;
|
||||
#ifdef SQLITE_DEBUG
|
||||
#if SQLITE_DEBUG
|
||||
/* Trash all content in the buffer being freed */
|
||||
memset(p, 0xaa, db->lookaside.sz);
|
||||
#endif
|
||||
|
||||
+2
-4
@@ -125,9 +125,7 @@ static malloc_zone_t* _sqliteZone_;
|
||||
*/
|
||||
static void *sqlite3MemMalloc(int nByte){
|
||||
#ifdef SQLITE_MALLOCSIZE
|
||||
void *p;
|
||||
testcase( ROUND8(nByte)==nByte );
|
||||
p = SQLITE_MALLOC( nByte );
|
||||
void *p = SQLITE_MALLOC( nByte );
|
||||
if( p==0 ){
|
||||
testcase( sqlite3GlobalConfig.xLog!=0 );
|
||||
sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte);
|
||||
@@ -136,7 +134,7 @@ static void *sqlite3MemMalloc(int nByte){
|
||||
#else
|
||||
sqlite3_int64 *p;
|
||||
assert( nByte>0 );
|
||||
testcase( ROUND8(nByte)!=nByte );
|
||||
nByte = ROUND8(nByte);
|
||||
p = SQLITE_MALLOC( nByte+8 );
|
||||
if( p ){
|
||||
p[0] = nByte;
|
||||
|
||||
+8
-7
@@ -87,7 +87,8 @@ void sqlite3MemoryBarrier(void){
|
||||
SQLITE_MEMORY_BARRIER;
|
||||
#elif defined(__GNUC__)
|
||||
__sync_synchronize();
|
||||
#elif MSVC_VERSION>=1300
|
||||
#elif !defined(SQLITE_DISABLE_INTRINSIC) && \
|
||||
defined(_MSC_VER) && _MSC_VER>=1300
|
||||
_ReadWriteBarrier();
|
||||
#elif defined(MemoryBarrier)
|
||||
MemoryBarrier();
|
||||
@@ -298,8 +299,8 @@ static void winMutexEnter(sqlite3_mutex *p){
|
||||
p->owner = tid;
|
||||
p->nRef++;
|
||||
if( p->trace ){
|
||||
OSTRACE(("ENTER-MUTEX tid=%lu, mutex(%d)=%p (%d), nRef=%d\n",
|
||||
tid, p->id, p, p->trace, p->nRef));
|
||||
OSTRACE(("ENTER-MUTEX tid=%lu, mutex=%p (%d), nRef=%d\n",
|
||||
tid, p, p->trace, p->nRef));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -341,8 +342,8 @@ static int winMutexTry(sqlite3_mutex *p){
|
||||
#endif
|
||||
#ifdef SQLITE_DEBUG
|
||||
if( p->trace ){
|
||||
OSTRACE(("TRY-MUTEX tid=%lu, mutex(%d)=%p (%d), owner=%lu, nRef=%d, rc=%s\n",
|
||||
tid, p->id, p, p->trace, p->owner, p->nRef, sqlite3ErrName(rc)));
|
||||
OSTRACE(("TRY-MUTEX tid=%lu, mutex=%p (%d), owner=%lu, nRef=%d, rc=%s\n",
|
||||
tid, p, p->trace, p->owner, p->nRef, sqlite3ErrName(rc)));
|
||||
}
|
||||
#endif
|
||||
return rc;
|
||||
@@ -370,8 +371,8 @@ static void winMutexLeave(sqlite3_mutex *p){
|
||||
LeaveCriticalSection(&p->mutex);
|
||||
#ifdef SQLITE_DEBUG
|
||||
if( p->trace ){
|
||||
OSTRACE(("LEAVE-MUTEX tid=%lu, mutex(%d)=%p (%d), nRef=%d\n",
|
||||
tid, p->id, p, p->trace, p->nRef));
|
||||
OSTRACE(("LEAVE-MUTEX tid=%lu, mutex=%p (%d), nRef=%d\n",
|
||||
tid, p, p->trace, p->nRef));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
+7
-45
@@ -352,34 +352,7 @@ struct winVfsAppData {
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef SQLITE_WIN32_HEAP_CREATE
|
||||
# define SQLITE_WIN32_HEAP_CREATE (TRUE)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is the maximum possible initial size of the Win32-specific heap, in
|
||||
* bytes.
|
||||
*/
|
||||
#ifndef SQLITE_WIN32_HEAP_MAX_INIT_SIZE
|
||||
# define SQLITE_WIN32_HEAP_MAX_INIT_SIZE (4294967295U)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is the extra space for the initial size of the Win32-specific heap,
|
||||
* in bytes. This value may be zero.
|
||||
*/
|
||||
#ifndef SQLITE_WIN32_HEAP_INIT_EXTRA
|
||||
# define SQLITE_WIN32_HEAP_INIT_EXTRA (4194304)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Calculate the maximum legal cache size, in pages, based on the maximum
|
||||
* possible initial heap size and the default page size, setting aside the
|
||||
* needed extra space.
|
||||
*/
|
||||
#ifndef SQLITE_WIN32_MAX_CACHE_SIZE
|
||||
# define SQLITE_WIN32_MAX_CACHE_SIZE (((SQLITE_WIN32_HEAP_MAX_INIT_SIZE) - \
|
||||
(SQLITE_WIN32_HEAP_INIT_EXTRA)) / \
|
||||
(SQLITE_DEFAULT_PAGE_SIZE))
|
||||
# define SQLITE_WIN32_HEAP_CREATE (TRUE)
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -388,36 +361,25 @@ struct winVfsAppData {
|
||||
*/
|
||||
#ifndef SQLITE_WIN32_CACHE_SIZE
|
||||
# if SQLITE_DEFAULT_CACHE_SIZE>=0
|
||||
# define SQLITE_WIN32_CACHE_SIZE (SQLITE_DEFAULT_CACHE_SIZE)
|
||||
# define SQLITE_WIN32_CACHE_SIZE (SQLITE_DEFAULT_CACHE_SIZE)
|
||||
# else
|
||||
# define SQLITE_WIN32_CACHE_SIZE (-(SQLITE_DEFAULT_CACHE_SIZE))
|
||||
# define SQLITE_WIN32_CACHE_SIZE (-(SQLITE_DEFAULT_CACHE_SIZE))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Make sure that the calculated cache size, in pages, cannot cause the
|
||||
* initial size of the Win32-specific heap to exceed the maximum amount
|
||||
* of memory that can be specified in the call to HeapCreate.
|
||||
*/
|
||||
#if SQLITE_WIN32_CACHE_SIZE>SQLITE_WIN32_MAX_CACHE_SIZE
|
||||
# undef SQLITE_WIN32_CACHE_SIZE
|
||||
# define SQLITE_WIN32_CACHE_SIZE (2000)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The initial size of the Win32-specific heap. This value may be zero.
|
||||
*/
|
||||
#ifndef SQLITE_WIN32_HEAP_INIT_SIZE
|
||||
# define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_WIN32_CACHE_SIZE) * \
|
||||
(SQLITE_DEFAULT_PAGE_SIZE) + \
|
||||
(SQLITE_WIN32_HEAP_INIT_EXTRA))
|
||||
# define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_WIN32_CACHE_SIZE) * \
|
||||
(SQLITE_DEFAULT_PAGE_SIZE) + 4194304)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The maximum size of the Win32-specific heap. This value may be zero.
|
||||
*/
|
||||
#ifndef SQLITE_WIN32_HEAP_MAX_SIZE
|
||||
# define SQLITE_WIN32_HEAP_MAX_SIZE (0)
|
||||
# define SQLITE_WIN32_HEAP_MAX_SIZE (0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -425,7 +387,7 @@ struct winVfsAppData {
|
||||
* zero for the default behavior.
|
||||
*/
|
||||
#ifndef SQLITE_WIN32_HEAP_FLAGS
|
||||
# define SQLITE_WIN32_HEAP_FLAGS (0)
|
||||
# define SQLITE_WIN32_HEAP_FLAGS (0)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
+2
-2
@@ -899,7 +899,7 @@ term(A) ::= INTEGER(X). {
|
||||
A.pExpr = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &X, 1);
|
||||
A.zStart = X.z;
|
||||
A.zEnd = X.z + X.n;
|
||||
if( A.pExpr ) A.pExpr->flags |= EP_Leaf|EP_Resolved;
|
||||
if( A.pExpr ) A.pExpr->flags |= EP_Leaf;
|
||||
}
|
||||
expr(A) ::= VARIABLE(X). {
|
||||
if( !(X.z[0]=='#' && sqlite3Isdigit(X.z[1])) ){
|
||||
@@ -1000,7 +1000,7 @@ expr(A) ::= expr(A) STAR|SLASH|REM(OP) expr(Y).
|
||||
{spanBinaryExpr(pParse,@OP,&A,&Y);}
|
||||
expr(A) ::= expr(A) CONCAT(OP) expr(Y). {spanBinaryExpr(pParse,@OP,&A,&Y);}
|
||||
%type likeop {Token}
|
||||
likeop(A) ::= LIKE_KW|MATCH(A).
|
||||
likeop(A) ::= LIKE_KW|MATCH(X). {A=X;/*A-overwrites-X*/}
|
||||
likeop(A) ::= NOT LIKE_KW|MATCH(X). {A=X; A.n|=0x80000000; /*A-overwrite-X*/}
|
||||
expr(A) ::= expr(A) likeop(OP) expr(Y). [LIKE_KW] {
|
||||
ExprList *pList;
|
||||
|
||||
+1
-1
@@ -104,7 +104,7 @@ struct PCache {
|
||||
**
|
||||
** assert( sqlite3PcachePageSanity(pPg) );
|
||||
*/
|
||||
#ifdef SQLITE_DEBUG
|
||||
#if SQLITE_DEBUG
|
||||
int sqlite3PcachePageSanity(PgHdr *pPg){
|
||||
PCache *pCache;
|
||||
assert( pPg!=0 );
|
||||
|
||||
+48
-198
@@ -295,22 +295,6 @@ static const PragmaName *pragmaLocate(const char *zName){
|
||||
return lwr>upr ? 0 : &aPragmaName[mid];
|
||||
}
|
||||
|
||||
/*
|
||||
** Helper subroutine for PRAGMA integrity_check:
|
||||
**
|
||||
** Generate code to output a single-column result row with the result
|
||||
** held in register regResult. Decrement the result count and halt if
|
||||
** the maximum number of result rows have been issued.
|
||||
*/
|
||||
static int integrityCheckResultRow(Vdbe *v, int regResult){
|
||||
int addr;
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 1);
|
||||
addr = sqlite3VdbeAddOp3(v, OP_IfPos, 1, sqlite3VdbeCurrentAddr(v)+2, 1);
|
||||
VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
|
||||
return addr;
|
||||
}
|
||||
|
||||
/*
|
||||
** Process a pragma statement.
|
||||
**
|
||||
@@ -1114,33 +1098,29 @@ void sqlite3Pragma(
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
case PragTyp_STATS: {
|
||||
Index *pIdx;
|
||||
HashElem *i;
|
||||
pParse->nMem = 5;
|
||||
pParse->nMem = 4;
|
||||
sqlite3CodeVerifySchema(pParse, iDb);
|
||||
for(i=sqliteHashFirst(&pDb->pSchema->tblHash); i; i=sqliteHashNext(i)){
|
||||
Table *pTab = sqliteHashData(i);
|
||||
sqlite3VdbeMultiLoad(v, 1, "ssiii",
|
||||
sqlite3VdbeMultiLoad(v, 1, "ssii",
|
||||
pTab->zName,
|
||||
0,
|
||||
pTab->szTabRow,
|
||||
pTab->nRowLogEst,
|
||||
pTab->tabFlags);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 5);
|
||||
pTab->nRowLogEst);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
|
||||
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
|
||||
sqlite3VdbeMultiLoad(v, 2, "siii",
|
||||
sqlite3VdbeMultiLoad(v, 2, "sii",
|
||||
pIdx->zName,
|
||||
pIdx->szIdxRow,
|
||||
pIdx->aiRowLogEst[0],
|
||||
pIdx->hasStat1);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 5);
|
||||
pIdx->aiRowLogEst[0]);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case PragTyp_INDEX_INFO: if( zRight ){
|
||||
Index *pIdx;
|
||||
@@ -1397,17 +1377,9 @@ void sqlite3Pragma(
|
||||
#endif
|
||||
|
||||
#ifndef SQLITE_OMIT_INTEGRITY_CHECK
|
||||
/* PRAGMA integrity_check
|
||||
** PRAGMA integrity_check(N)
|
||||
** PRAGMA quick_check
|
||||
** PRAGMA quick_check(N)
|
||||
**
|
||||
** Verify the integrity of the database.
|
||||
**
|
||||
** The "quick_check" is reduced version of
|
||||
/* Pragma "quick_check" is reduced version of
|
||||
** integrity_check designed to detect most database corruption
|
||||
** without the overhead of cross-checking indexes. Quick_check
|
||||
** is linear time wherease integrity_check is O(NlogN).
|
||||
** without most of the overhead of a full integrity-check.
|
||||
*/
|
||||
case PragTyp_INTEGRITY_CHECK: {
|
||||
int i, j, addr, mxErr;
|
||||
@@ -1438,7 +1410,7 @@ void sqlite3Pragma(
|
||||
mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
|
||||
}
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, mxErr-1, 1); /* reg[1] holds errors left */
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, mxErr, 1); /* reg[1] holds errors left */
|
||||
|
||||
/* Do an integrity check on each database file */
|
||||
for(i=0; i<db->nDb; i++){
|
||||
@@ -1453,6 +1425,10 @@ void sqlite3Pragma(
|
||||
if( iDb>=0 && i!=iDb ) continue;
|
||||
|
||||
sqlite3CodeVerifySchema(pParse, i);
|
||||
addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Halt if out of errors */
|
||||
VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
|
||||
sqlite3VdbeJumpHere(v, addr);
|
||||
|
||||
/* Do an integrity check of the B-Tree
|
||||
**
|
||||
@@ -1492,12 +1468,12 @@ void sqlite3Pragma(
|
||||
P4_DYNAMIC);
|
||||
sqlite3VdbeAddOp3(v, OP_Move, 2, 4, 1);
|
||||
sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 2);
|
||||
integrityCheckResultRow(v, 2);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 2, 1);
|
||||
sqlite3VdbeJumpHere(v, addr);
|
||||
|
||||
/* Make sure all the indices are constructed correctly.
|
||||
*/
|
||||
for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
|
||||
for(x=sqliteHashFirst(pTbls); x && !isQuick; x=sqliteHashNext(x)){
|
||||
Table *pTab = sqliteHashData(x);
|
||||
Index *pIdx, *pPk;
|
||||
Index *pPrior = 0;
|
||||
@@ -1505,13 +1481,12 @@ void sqlite3Pragma(
|
||||
int iDataCur, iIdxCur;
|
||||
int r1 = -1;
|
||||
|
||||
if( pTab->pCheck==0
|
||||
&& (pTab->tabFlags & TF_HasNotNull)==0
|
||||
&& (pTab->pIndex==0 || isQuick)
|
||||
){
|
||||
continue; /* No additional checks needed for this table */
|
||||
}
|
||||
if( pTab->pIndex==0 ) continue;
|
||||
pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
|
||||
addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Stop if out of errors */
|
||||
VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
|
||||
sqlite3VdbeJumpHere(v, addr);
|
||||
sqlite3ExprCacheClear(pParse);
|
||||
sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0,
|
||||
1, 0, &iDataCur, &iIdxCur);
|
||||
@@ -1526,42 +1501,24 @@ void sqlite3Pragma(
|
||||
/* Verify that all NOT NULL columns really are NOT NULL */
|
||||
for(j=0; j<pTab->nCol; j++){
|
||||
char *zErr;
|
||||
int jmp2;
|
||||
int jmp2, jmp3;
|
||||
if( j==pTab->iPKey ) continue;
|
||||
if( pTab->aCol[j].notNull==0 ) continue;
|
||||
sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3);
|
||||
sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
|
||||
jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
|
||||
zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName,
|
||||
pTab->aCol[j].zName);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
|
||||
integrityCheckResultRow(v, 3);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1);
|
||||
jmp3 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp0(v, OP_Halt);
|
||||
sqlite3VdbeJumpHere(v, jmp2);
|
||||
}
|
||||
/* Verify CHECK constraints */
|
||||
if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
|
||||
int addrCkFault = sqlite3VdbeMakeLabel(v);
|
||||
int addrCkOk = sqlite3VdbeMakeLabel(v);
|
||||
ExprList *pCheck = pTab->pCheck;
|
||||
char *zErr;
|
||||
int k;
|
||||
pParse->iSelfTab = iDataCur;
|
||||
sqlite3ExprCachePush(pParse);
|
||||
for(k=pCheck->nExpr-1; k>0; k--){
|
||||
sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0);
|
||||
}
|
||||
sqlite3ExprIfTrue(pParse, pCheck->a[0].pExpr, addrCkOk,
|
||||
SQLITE_JUMPIFNULL);
|
||||
sqlite3VdbeResolveLabel(v, addrCkFault);
|
||||
zErr = sqlite3MPrintf(db, "CHECK constraint failed in %s",
|
||||
pTab->zName);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
|
||||
integrityCheckResultRow(v, 3);
|
||||
sqlite3VdbeResolveLabel(v, addrCkOk);
|
||||
sqlite3ExprCachePop(pParse);
|
||||
sqlite3VdbeJumpHere(v, jmp3);
|
||||
}
|
||||
/* Validate index entries for the current row */
|
||||
for(j=0, pIdx=pTab->pIndex; pIdx && !isQuick; pIdx=pIdx->pNext, j++){
|
||||
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
||||
int jmp2, jmp3, jmp4, jmp5;
|
||||
int ckUniq = sqlite3VdbeMakeLabel(v);
|
||||
if( pPk==pIdx ) continue;
|
||||
@@ -1572,13 +1529,16 @@ void sqlite3Pragma(
|
||||
/* Verify that an index entry exists for the current table row */
|
||||
jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, ckUniq, r1,
|
||||
pIdx->nColumn); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
|
||||
sqlite3VdbeLoadString(v, 3, "row ");
|
||||
sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3);
|
||||
sqlite3VdbeLoadString(v, 4, " missing from index ");
|
||||
sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
|
||||
jmp5 = sqlite3VdbeLoadString(v, 4, pIdx->zName);
|
||||
sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
|
||||
jmp4 = integrityCheckResultRow(v, 3);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1);
|
||||
jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp0(v, OP_Halt);
|
||||
sqlite3VdbeJumpHere(v, jmp2);
|
||||
/* For UNIQUE indexes, verify that only one entry exists with the
|
||||
** current key. The entry is unique if (1) any column is NULL
|
||||
@@ -1599,6 +1559,7 @@ void sqlite3Pragma(
|
||||
sqlite3VdbeJumpHere(v, jmp6);
|
||||
sqlite3VdbeAddOp4Int(v, OP_IdxGT, iIdxCur+j, uniqOk, r1,
|
||||
pIdx->nKeyCol); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
|
||||
sqlite3VdbeLoadString(v, 3, "non-unique entry in index ");
|
||||
sqlite3VdbeGoto(v, jmp5);
|
||||
sqlite3VdbeResolveLabel(v, uniqOk);
|
||||
@@ -1609,18 +1570,19 @@ void sqlite3Pragma(
|
||||
sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v);
|
||||
sqlite3VdbeJumpHere(v, loopTop-1);
|
||||
#ifndef SQLITE_OMIT_BTREECOUNT
|
||||
if( !isQuick ){
|
||||
sqlite3VdbeLoadString(v, 2, "wrong # of entries in index ");
|
||||
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
||||
if( pPk==pIdx ) continue;
|
||||
sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3);
|
||||
addr = sqlite3VdbeAddOp3(v, OP_Eq, 8+j, 0, 3); VdbeCoverage(v);
|
||||
sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
|
||||
sqlite3VdbeLoadString(v, 3, pIdx->zName);
|
||||
sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7);
|
||||
integrityCheckResultRow(v, 7);
|
||||
sqlite3VdbeJumpHere(v, addr);
|
||||
}
|
||||
sqlite3VdbeLoadString(v, 2, "wrong # of entries in index ");
|
||||
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
||||
if( pPk==pIdx ) continue;
|
||||
addr = sqlite3VdbeCurrentAddr(v);
|
||||
sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3);
|
||||
sqlite3VdbeAddOp3(v, OP_Eq, 8+j, addr+8, 3); VdbeCoverage(v);
|
||||
sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
|
||||
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
|
||||
sqlite3VdbeLoadString(v, 3, pIdx->zName);
|
||||
sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, 7, 1);
|
||||
}
|
||||
#endif /* SQLITE_OMIT_BTREECOUNT */
|
||||
}
|
||||
@@ -1629,7 +1591,7 @@ void sqlite3Pragma(
|
||||
static const int iLn = VDBE_OFFSET_LINENO(2);
|
||||
static const VdbeOpList endCode[] = {
|
||||
{ OP_AddImm, 1, 0, 0}, /* 0 */
|
||||
{ OP_IfNotZero, 1, 4, 0}, /* 1 */
|
||||
{ OP_If, 1, 4, 0}, /* 1 */
|
||||
{ OP_String8, 0, 3, 0}, /* 2 */
|
||||
{ OP_ResultRow, 3, 1, 0}, /* 3 */
|
||||
};
|
||||
@@ -1637,7 +1599,7 @@ void sqlite3Pragma(
|
||||
|
||||
aOp = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode, iLn);
|
||||
if( aOp ){
|
||||
aOp[0].p2 = 1-mxErr;
|
||||
aOp[0].p2 = -mxErr;
|
||||
aOp[2].p4type = P4_STATIC;
|
||||
aOp[2].p4.z = "ok";
|
||||
}
|
||||
@@ -1862,118 +1824,6 @@ void sqlite3Pragma(
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
** PRAGMA optimize
|
||||
** PRAGMA optimize(MASK)
|
||||
** PRAGMA schema.optimize
|
||||
** PRAGMA schema.optimize(MASK)
|
||||
**
|
||||
** Attempt to optimize the database. All schemas are optimized in the first
|
||||
** two forms, and only the specified schema is optimized in the latter two.
|
||||
**
|
||||
** The details of optimizations performed by this pragma are expected
|
||||
** to change and improve over time. Applications should anticipate that
|
||||
** this pragma will perform new optimizations in future releases.
|
||||
**
|
||||
** The optional argument is a bitmask of optimizations to perform:
|
||||
**
|
||||
** 0x0001 Debugging mode. Do not actually perform any optimizations
|
||||
** but instead return one line of text for each optimization
|
||||
** that would have been done. Off by default.
|
||||
**
|
||||
** 0x0002 Run ANALYZE on tables that might benefit. On by default.
|
||||
** See below for additional information.
|
||||
**
|
||||
** 0x0004 (Not yet implemented) Record usage and performance
|
||||
** information from the current session in the
|
||||
** database file so that it will be available to "optimize"
|
||||
** pragmas run by future database connections.
|
||||
**
|
||||
** 0x0008 (Not yet implemented) Create indexes that might have
|
||||
** been helpful to recent queries
|
||||
**
|
||||
** The default MASK is and always shall be 0xfffe. 0xfffe means perform all ** of the optimizations listed above except Debug Mode, including new
|
||||
** optimizations that have not yet been invented. If new optimizations are
|
||||
** ever added that should be off by default, those off-by-default
|
||||
** optimizations will have bitmasks of 0x10000 or larger.
|
||||
**
|
||||
** DETERMINATION OF WHEN TO RUN ANALYZE
|
||||
**
|
||||
** In the current implementation, a table is analyzed if only if all of
|
||||
** the following are true:
|
||||
**
|
||||
** (1) MASK bit 0x02 is set.
|
||||
**
|
||||
** (2) The query planner used sqlite_stat1-style statistics for one or
|
||||
** more indexes of the table at some point during the lifetime of
|
||||
** the current connection.
|
||||
**
|
||||
** (3) One or more indexes of the table are currently unanalyzed OR
|
||||
** the number of rows in the table has increased by 25 times or more
|
||||
** since the last time ANALYZE was run.
|
||||
**
|
||||
** The rules for when tables are analyzed are likely to change in
|
||||
** future releases.
|
||||
*/
|
||||
case PragTyp_OPTIMIZE: {
|
||||
int iDbLast; /* Loop termination point for the schema loop */
|
||||
int iTabCur; /* Cursor for a table whose size needs checking */
|
||||
HashElem *k; /* Loop over tables of a schema */
|
||||
Schema *pSchema; /* The current schema */
|
||||
Table *pTab; /* A table in the schema */
|
||||
Index *pIdx; /* An index of the table */
|
||||
LogEst szThreshold; /* Size threshold above which reanalysis is needd */
|
||||
char *zSubSql; /* SQL statement for the OP_SqlExec opcode */
|
||||
u32 opMask; /* Mask of operations to perform */
|
||||
|
||||
if( zRight ){
|
||||
opMask = (u32)sqlite3Atoi(zRight);
|
||||
if( (opMask & 0x02)==0 ) break;
|
||||
}else{
|
||||
opMask = 0xfffe;
|
||||
}
|
||||
iTabCur = pParse->nTab++;
|
||||
for(iDbLast = zDb?iDb:db->nDb-1; iDb<=iDbLast; iDb++){
|
||||
if( iDb==1 ) continue;
|
||||
sqlite3CodeVerifySchema(pParse, iDb);
|
||||
pSchema = db->aDb[iDb].pSchema;
|
||||
for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
|
||||
pTab = (Table*)sqliteHashData(k);
|
||||
|
||||
/* If table pTab has not been used in a way that would benefit from
|
||||
** having analysis statistics during the current session, then skip it.
|
||||
** This also has the effect of skipping virtual tables and views */
|
||||
if( (pTab->tabFlags & TF_StatsUsed)==0 ) continue;
|
||||
|
||||
/* Reanalyze if the table is 25 times larger than the last analysis */
|
||||
szThreshold = pTab->nRowLogEst + 46; assert( sqlite3LogEst(25)==46 );
|
||||
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
|
||||
if( !pIdx->hasStat1 ){
|
||||
szThreshold = 0; /* Always analyze if any index lacks statistics */
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( szThreshold ){
|
||||
sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead);
|
||||
sqlite3VdbeAddOp3(v, OP_IfSmaller, iTabCur,
|
||||
sqlite3VdbeCurrentAddr(v)+2+(opMask&1), szThreshold);
|
||||
VdbeCoverage(v);
|
||||
}
|
||||
zSubSql = sqlite3MPrintf(db, "ANALYZE \"%w\".\"%w\"",
|
||||
db->aDb[iDb].zDbSName, pTab->zName);
|
||||
if( opMask & 0x01 ){
|
||||
int r1 = sqlite3GetTempReg(pParse);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, r1, 0, zSubSql, P4_DYNAMIC);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, r1, 1);
|
||||
}else{
|
||||
sqlite3VdbeAddOp4(v, OP_SqlExec, 0, 0, 0, zSubSql, P4_DYNAMIC);
|
||||
}
|
||||
}
|
||||
}
|
||||
sqlite3VdbeAddOp0(v, OP_Expire);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
** PRAGMA busy_timeout
|
||||
** PRAGMA busy_timeout = N
|
||||
|
||||
+59
-68
@@ -30,11 +30,11 @@
|
||||
#define PragTyp_LOCKING_MODE 22
|
||||
#define PragTyp_PAGE_COUNT 23
|
||||
#define PragTyp_MMAP_SIZE 24
|
||||
#define PragTyp_OPTIMIZE 25
|
||||
#define PragTyp_PAGE_SIZE 26
|
||||
#define PragTyp_SECURE_DELETE 27
|
||||
#define PragTyp_SHRINK_MEMORY 28
|
||||
#define PragTyp_SOFT_HEAP_LIMIT 29
|
||||
#define PragTyp_PAGE_SIZE 25
|
||||
#define PragTyp_SECURE_DELETE 26
|
||||
#define PragTyp_SHRINK_MEMORY 27
|
||||
#define PragTyp_SOFT_HEAP_LIMIT 28
|
||||
#define PragTyp_STATS 29
|
||||
#define PragTyp_SYNCHRONOUS 30
|
||||
#define PragTyp_TABLE_INFO 31
|
||||
#define PragTyp_TEMP_STORE 32
|
||||
@@ -48,7 +48,6 @@
|
||||
#define PragTyp_REKEY 40
|
||||
#define PragTyp_LOCK_STATUS 41
|
||||
#define PragTyp_PARSER_TRACE 42
|
||||
#define PragTyp_STATS 43
|
||||
|
||||
/* Property flags associated with various pragma. */
|
||||
#define PragFlg_NeedSchema 0x01 /* Force schema load before running */
|
||||
@@ -72,48 +71,47 @@ static const char *const pragCName[] = {
|
||||
/* 4 */ "notnull",
|
||||
/* 5 */ "dflt_value",
|
||||
/* 6 */ "pk",
|
||||
/* 7 */ "tbl", /* Used by: stats */
|
||||
/* 8 */ "idx",
|
||||
/* 9 */ "wdth",
|
||||
/* 10 */ "hght",
|
||||
/* 11 */ "flgs",
|
||||
/* 12 */ "seqno", /* Used by: index_info */
|
||||
/* 13 */ "cid",
|
||||
/* 14 */ "name",
|
||||
/* 15 */ "seqno", /* Used by: index_xinfo */
|
||||
/* 16 */ "cid",
|
||||
/* 17 */ "name",
|
||||
/* 18 */ "desc",
|
||||
/* 19 */ "coll",
|
||||
/* 20 */ "key",
|
||||
/* 21 */ "seq", /* Used by: index_list */
|
||||
/* 22 */ "name",
|
||||
/* 23 */ "unique",
|
||||
/* 24 */ "origin",
|
||||
/* 25 */ "partial",
|
||||
/* 26 */ "seq", /* Used by: database_list */
|
||||
/* 27 */ "name",
|
||||
/* 28 */ "file",
|
||||
/* 29 */ "seq", /* Used by: collation_list */
|
||||
/* 30 */ "name",
|
||||
/* 31 */ "id", /* Used by: foreign_key_list */
|
||||
/* 32 */ "seq",
|
||||
/* 33 */ "table",
|
||||
/* 34 */ "from",
|
||||
/* 35 */ "to",
|
||||
/* 36 */ "on_update",
|
||||
/* 37 */ "on_delete",
|
||||
/* 38 */ "match",
|
||||
/* 39 */ "table", /* Used by: foreign_key_check */
|
||||
/* 40 */ "rowid",
|
||||
/* 41 */ "parent",
|
||||
/* 42 */ "fkid",
|
||||
/* 43 */ "busy", /* Used by: wal_checkpoint */
|
||||
/* 44 */ "log",
|
||||
/* 45 */ "checkpointed",
|
||||
/* 46 */ "timeout", /* Used by: busy_timeout */
|
||||
/* 47 */ "database", /* Used by: lock_status */
|
||||
/* 48 */ "status",
|
||||
/* 7 */ "table", /* Used by: stats */
|
||||
/* 8 */ "index",
|
||||
/* 9 */ "width",
|
||||
/* 10 */ "height",
|
||||
/* 11 */ "seqno", /* Used by: index_info */
|
||||
/* 12 */ "cid",
|
||||
/* 13 */ "name",
|
||||
/* 14 */ "seqno", /* Used by: index_xinfo */
|
||||
/* 15 */ "cid",
|
||||
/* 16 */ "name",
|
||||
/* 17 */ "desc",
|
||||
/* 18 */ "coll",
|
||||
/* 19 */ "key",
|
||||
/* 20 */ "seq", /* Used by: index_list */
|
||||
/* 21 */ "name",
|
||||
/* 22 */ "unique",
|
||||
/* 23 */ "origin",
|
||||
/* 24 */ "partial",
|
||||
/* 25 */ "seq", /* Used by: database_list */
|
||||
/* 26 */ "name",
|
||||
/* 27 */ "file",
|
||||
/* 28 */ "seq", /* Used by: collation_list */
|
||||
/* 29 */ "name",
|
||||
/* 30 */ "id", /* Used by: foreign_key_list */
|
||||
/* 31 */ "seq",
|
||||
/* 32 */ "table",
|
||||
/* 33 */ "from",
|
||||
/* 34 */ "to",
|
||||
/* 35 */ "on_update",
|
||||
/* 36 */ "on_delete",
|
||||
/* 37 */ "match",
|
||||
/* 38 */ "table", /* Used by: foreign_key_check */
|
||||
/* 39 */ "rowid",
|
||||
/* 40 */ "parent",
|
||||
/* 41 */ "fkid",
|
||||
/* 42 */ "busy", /* Used by: wal_checkpoint */
|
||||
/* 43 */ "log",
|
||||
/* 44 */ "checkpointed",
|
||||
/* 45 */ "timeout", /* Used by: busy_timeout */
|
||||
/* 46 */ "database", /* Used by: lock_status */
|
||||
/* 47 */ "status",
|
||||
};
|
||||
|
||||
/* Definitions of all built-in pragmas */
|
||||
@@ -159,7 +157,7 @@ static const PragmaName aPragmaName[] = {
|
||||
{/* zName: */ "busy_timeout",
|
||||
/* ePragTyp: */ PragTyp_BUSY_TIMEOUT,
|
||||
/* ePragFlg: */ PragFlg_Result0,
|
||||
/* ColNames: */ 46, 1,
|
||||
/* ColNames: */ 45, 1,
|
||||
/* iArg: */ 0 },
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{/* zName: */ "cache_size",
|
||||
@@ -196,7 +194,7 @@ static const PragmaName aPragmaName[] = {
|
||||
{/* zName: */ "collation_list",
|
||||
/* ePragTyp: */ PragTyp_COLLATION_LIST,
|
||||
/* ePragFlg: */ PragFlg_Result0,
|
||||
/* ColNames: */ 29, 2,
|
||||
/* ColNames: */ 28, 2,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS)
|
||||
@@ -231,7 +229,7 @@ static const PragmaName aPragmaName[] = {
|
||||
{/* zName: */ "database_list",
|
||||
/* ePragTyp: */ PragTyp_DATABASE_LIST,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0,
|
||||
/* ColNames: */ 26, 3,
|
||||
/* ColNames: */ 25, 3,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
|
||||
@@ -268,14 +266,14 @@ static const PragmaName aPragmaName[] = {
|
||||
{/* zName: */ "foreign_key_check",
|
||||
/* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema,
|
||||
/* ColNames: */ 39, 4,
|
||||
/* ColNames: */ 38, 4,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FOREIGN_KEY)
|
||||
{/* zName: */ "foreign_key_list",
|
||||
/* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
|
||||
/* ColNames: */ 31, 8,
|
||||
/* ColNames: */ 30, 8,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
@@ -338,17 +336,17 @@ static const PragmaName aPragmaName[] = {
|
||||
{/* zName: */ "index_info",
|
||||
/* ePragTyp: */ PragTyp_INDEX_INFO,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
|
||||
/* ColNames: */ 12, 3,
|
||||
/* ColNames: */ 11, 3,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "index_list",
|
||||
/* ePragTyp: */ PragTyp_INDEX_LIST,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
|
||||
/* ColNames: */ 21, 5,
|
||||
/* ColNames: */ 20, 5,
|
||||
/* iArg: */ 0 },
|
||||
{/* zName: */ "index_xinfo",
|
||||
/* ePragTyp: */ PragTyp_INDEX_INFO,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
|
||||
/* ColNames: */ 15, 6,
|
||||
/* ColNames: */ 14, 6,
|
||||
/* iArg: */ 1 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_INTEGRITY_CHECK)
|
||||
@@ -395,7 +393,7 @@ static const PragmaName aPragmaName[] = {
|
||||
{/* zName: */ "lock_status",
|
||||
/* ePragTyp: */ PragTyp_LOCK_STATUS,
|
||||
/* ePragFlg: */ PragFlg_Result0,
|
||||
/* ColNames: */ 47, 2,
|
||||
/* ColNames: */ 46, 2,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
@@ -414,13 +412,6 @@ static const PragmaName aPragmaName[] = {
|
||||
/* ePragFlg: */ 0,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
{/* zName: */ "optimize",
|
||||
/* ePragTyp: */ PragTyp_OPTIMIZE,
|
||||
/* ePragFlg: */ PragFlg_Result1,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
{/* zName: */ "page_count",
|
||||
/* ePragTyp: */ PragTyp_PAGE_COUNT,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
|
||||
@@ -519,11 +510,11 @@ static const PragmaName aPragmaName[] = {
|
||||
/* iArg: */ SQLITE_SqlTrace },
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG)
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
{/* zName: */ "stats",
|
||||
/* ePragTyp: */ PragTyp_STATS,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
|
||||
/* ColNames: */ 7, 5,
|
||||
/* ColNames: */ 7, 4,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
|
||||
@@ -602,7 +593,7 @@ static const PragmaName aPragmaName[] = {
|
||||
{/* zName: */ "wal_checkpoint",
|
||||
/* ePragTyp: */ PragTyp_WAL_CHECKPOINT,
|
||||
/* ePragFlg: */ PragFlg_NeedSchema,
|
||||
/* ColNames: */ 43, 3,
|
||||
/* ColNames: */ 42, 3,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
@@ -613,4 +604,4 @@ static const PragmaName aPragmaName[] = {
|
||||
/* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
|
||||
#endif
|
||||
};
|
||||
/* Number of pragmas: 60 on by default, 74 total. */
|
||||
/* Number of pragmas: 60 on by default, 73 total. */
|
||||
|
||||
+42
-55
@@ -15,7 +15,7 @@
|
||||
** Conversion types fall into various categories as defined by the
|
||||
** following enumeration.
|
||||
*/
|
||||
#define etRADIX 0 /* non-decimal integer types. %x %o */
|
||||
#define etRADIX 0 /* Integer types. %d, %x, %o, and so forth */
|
||||
#define etFLOAT 1 /* Floating point. %f */
|
||||
#define etEXP 2 /* Exponentional notation. %e and %E */
|
||||
#define etGENERIC 3 /* Floating or exponential, depending on exponent. %g */
|
||||
@@ -33,9 +33,8 @@
|
||||
#define etPOINTER 13 /* The %p conversion */
|
||||
#define etSQLESCAPE3 14 /* %w -> Strings with '\"' doubled */
|
||||
#define etORDINAL 15 /* %r -> 1st, 2nd, 3rd, 4th, etc. English only */
|
||||
#define etDECIMAL 16 /* %d or %u, but not %x, %o */
|
||||
|
||||
#define etINVALID 17 /* Any unrecognized conversion type */
|
||||
#define etINVALID 16 /* Any unrecognized conversion type */
|
||||
|
||||
|
||||
/*
|
||||
@@ -59,8 +58,8 @@ typedef struct et_info { /* Information about each format field */
|
||||
/*
|
||||
** Allowed values for et_info.flags
|
||||
*/
|
||||
#define FLAG_SIGNED 1 /* True if the value to convert is signed */
|
||||
#define FLAG_STRING 4 /* Allow infinite precision */
|
||||
#define FLAG_SIGNED 1 /* True if the value to convert is signed */
|
||||
#define FLAG_STRING 4 /* Allow infinity precision */
|
||||
|
||||
|
||||
/*
|
||||
@@ -70,7 +69,7 @@ typedef struct et_info { /* Information about each format field */
|
||||
static const char aDigits[] = "0123456789ABCDEF0123456789abcdef";
|
||||
static const char aPrefix[] = "-x0\000X0";
|
||||
static const et_info fmtinfo[] = {
|
||||
{ 'd', 10, 1, etDECIMAL, 0, 0 },
|
||||
{ 'd', 10, 1, etRADIX, 0, 0 },
|
||||
{ 's', 0, 4, etSTRING, 0, 0 },
|
||||
{ 'g', 0, 1, etGENERIC, 30, 0 },
|
||||
{ 'z', 0, 4, etDYNSTRING, 0, 0 },
|
||||
@@ -79,7 +78,7 @@ static const et_info fmtinfo[] = {
|
||||
{ 'w', 0, 4, etSQLESCAPE3, 0, 0 },
|
||||
{ 'c', 0, 0, etCHARX, 0, 0 },
|
||||
{ 'o', 8, 0, etRADIX, 0, 2 },
|
||||
{ 'u', 10, 0, etDECIMAL, 0, 0 },
|
||||
{ 'u', 10, 0, etRADIX, 0, 0 },
|
||||
{ 'x', 16, 0, etRADIX, 16, 1 },
|
||||
{ 'X', 16, 0, etRADIX, 0, 4 },
|
||||
#ifndef SQLITE_OMIT_FLOATING_POINT
|
||||
@@ -88,7 +87,7 @@ static const et_info fmtinfo[] = {
|
||||
{ 'E', 0, 1, etEXP, 14, 0 },
|
||||
{ 'G', 0, 1, etGENERIC, 14, 0 },
|
||||
#endif
|
||||
{ 'i', 10, 1, etDECIMAL, 0, 0 },
|
||||
{ 'i', 10, 1, etRADIX, 0, 0 },
|
||||
{ 'n', 0, 0, etSIZE, 0, 0 },
|
||||
{ '%', 0, 0, etPERCENT, 0, 0 },
|
||||
{ 'p', 16, 0, etPOINTER, 0, 1 },
|
||||
@@ -180,13 +179,14 @@ void sqlite3VXPrintf(
|
||||
int idx; /* A general purpose loop counter */
|
||||
int width; /* Width of the current field */
|
||||
etByte flag_leftjustify; /* True if "-" flag is present */
|
||||
etByte flag_prefix; /* '+' or ' ' or 0 for prefix */
|
||||
etByte flag_plussign; /* True if "+" flag is present */
|
||||
etByte flag_blanksign; /* True if " " flag is present */
|
||||
etByte flag_alternateform; /* True if "#" flag is present */
|
||||
etByte flag_altform2; /* True if "!" flag is present */
|
||||
etByte flag_zeropad; /* True if field width constant starts with zero */
|
||||
etByte flag_long; /* 1 for the "l" flag, 2 for "ll", 0 by default */
|
||||
etByte flag_long; /* True if "l" flag is present */
|
||||
etByte flag_longlong; /* True if the "ll" flag is present */
|
||||
etByte done; /* Loop termination flag */
|
||||
etByte cThousand; /* Thousands separator for %d and %u */
|
||||
etByte xtype = etINVALID; /* Conversion paradigm */
|
||||
u8 bArgList; /* True for SQLITE_PRINTF_SQLFUNC */
|
||||
char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */
|
||||
@@ -229,18 +229,17 @@ void sqlite3VXPrintf(
|
||||
break;
|
||||
}
|
||||
/* Find out what flags are present */
|
||||
flag_leftjustify = flag_prefix = cThousand =
|
||||
flag_leftjustify = flag_plussign = flag_blanksign =
|
||||
flag_alternateform = flag_altform2 = flag_zeropad = 0;
|
||||
done = 0;
|
||||
do{
|
||||
switch( c ){
|
||||
case '-': flag_leftjustify = 1; break;
|
||||
case '+': flag_prefix = '+'; break;
|
||||
case ' ': flag_prefix = ' '; break;
|
||||
case '+': flag_plussign = 1; break;
|
||||
case ' ': flag_blanksign = 1; break;
|
||||
case '#': flag_alternateform = 1; break;
|
||||
case '!': flag_altform2 = 1; break;
|
||||
case '0': flag_zeropad = 1; break;
|
||||
case ',': cThousand = ','; break;
|
||||
default: done = 1; break;
|
||||
}
|
||||
}while( !done && (c=(*++fmt))!=0 );
|
||||
@@ -310,11 +309,13 @@ void sqlite3VXPrintf(
|
||||
flag_long = 1;
|
||||
c = *++fmt;
|
||||
if( c=='l' ){
|
||||
flag_long = 2;
|
||||
flag_longlong = 1;
|
||||
c = *++fmt;
|
||||
}else{
|
||||
flag_longlong = 0;
|
||||
}
|
||||
}else{
|
||||
flag_long = 0;
|
||||
flag_long = flag_longlong = 0;
|
||||
}
|
||||
/* Fetch the info entry for the field */
|
||||
infop = &fmtinfo[0];
|
||||
@@ -332,11 +333,15 @@ void sqlite3VXPrintf(
|
||||
**
|
||||
** flag_alternateform TRUE if a '#' is present.
|
||||
** flag_altform2 TRUE if a '!' is present.
|
||||
** flag_prefix '+' or ' ' or zero
|
||||
** flag_plussign TRUE if a '+' is present.
|
||||
** flag_leftjustify TRUE if a '-' is present or if the
|
||||
** field width was negative.
|
||||
** flag_zeropad TRUE if the width began with 0.
|
||||
** flag_long 1 for "l", 2 for "ll"
|
||||
** flag_long TRUE if the letter 'l' (ell) prefixed
|
||||
** the conversion character.
|
||||
** flag_longlong TRUE if the letter 'll' (ell ell) prefixed
|
||||
** the conversion character.
|
||||
** flag_blanksign TRUE if a ' ' is present.
|
||||
** width The specified field width. This is
|
||||
** always non-negative. Zero is the default.
|
||||
** precision The specified precision. The default
|
||||
@@ -346,24 +351,19 @@ void sqlite3VXPrintf(
|
||||
*/
|
||||
switch( xtype ){
|
||||
case etPOINTER:
|
||||
flag_long = sizeof(char*)==sizeof(i64) ? 2 :
|
||||
sizeof(char*)==sizeof(long int) ? 1 : 0;
|
||||
flag_longlong = sizeof(char*)==sizeof(i64);
|
||||
flag_long = sizeof(char*)==sizeof(long int);
|
||||
/* Fall through into the next case */
|
||||
case etORDINAL:
|
||||
case etRADIX:
|
||||
cThousand = 0;
|
||||
/* Fall through into the next case */
|
||||
case etDECIMAL:
|
||||
case etRADIX:
|
||||
if( infop->flags & FLAG_SIGNED ){
|
||||
i64 v;
|
||||
if( bArgList ){
|
||||
v = getIntArg(pArgList);
|
||||
}else if( flag_longlong ){
|
||||
v = va_arg(ap,i64);
|
||||
}else if( flag_long ){
|
||||
if( flag_long==2 ){
|
||||
v = va_arg(ap,i64) ;
|
||||
}else{
|
||||
v = va_arg(ap,long int);
|
||||
}
|
||||
v = va_arg(ap,long int);
|
||||
}else{
|
||||
v = va_arg(ap,int);
|
||||
}
|
||||
@@ -376,17 +376,17 @@ void sqlite3VXPrintf(
|
||||
prefix = '-';
|
||||
}else{
|
||||
longvalue = v;
|
||||
prefix = flag_prefix;
|
||||
if( flag_plussign ) prefix = '+';
|
||||
else if( flag_blanksign ) prefix = ' ';
|
||||
else prefix = 0;
|
||||
}
|
||||
}else{
|
||||
if( bArgList ){
|
||||
longvalue = (u64)getIntArg(pArgList);
|
||||
}else if( flag_longlong ){
|
||||
longvalue = va_arg(ap,u64);
|
||||
}else if( flag_long ){
|
||||
if( flag_long==2 ){
|
||||
longvalue = va_arg(ap,u64);
|
||||
}else{
|
||||
longvalue = va_arg(ap,unsigned long int);
|
||||
}
|
||||
longvalue = va_arg(ap,unsigned long int);
|
||||
}else{
|
||||
longvalue = va_arg(ap,unsigned int);
|
||||
}
|
||||
@@ -396,11 +396,11 @@ void sqlite3VXPrintf(
|
||||
if( flag_zeropad && precision<width-(prefix!=0) ){
|
||||
precision = width-(prefix!=0);
|
||||
}
|
||||
if( precision<etBUFSIZE-10-etBUFSIZE/3 ){
|
||||
if( precision<etBUFSIZE-10 ){
|
||||
nOut = etBUFSIZE;
|
||||
zOut = buf;
|
||||
}else{
|
||||
nOut = precision + 10 + precision/3;
|
||||
nOut = precision + 10;
|
||||
zOut = zExtra = sqlite3Malloc( nOut );
|
||||
if( zOut==0 ){
|
||||
setStrAccumError(pAccum, STRACCUM_NOMEM);
|
||||
@@ -426,23 +426,8 @@ void sqlite3VXPrintf(
|
||||
}while( longvalue>0 );
|
||||
}
|
||||
length = (int)(&zOut[nOut-1]-bufpt);
|
||||
while( precision>length ){
|
||||
for(idx=precision-length; idx>0; idx--){
|
||||
*(--bufpt) = '0'; /* Zero pad */
|
||||
length++;
|
||||
}
|
||||
if( cThousand ){
|
||||
int nn = (length - 1)/3; /* Number of "," to insert */
|
||||
int ix = (length - 1)%3 + 1;
|
||||
bufpt -= nn;
|
||||
for(idx=0; nn>0; idx++){
|
||||
bufpt[idx] = bufpt[idx+nn];
|
||||
ix--;
|
||||
if( ix==0 ){
|
||||
bufpt[++idx] = cThousand;
|
||||
nn--;
|
||||
ix = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( prefix ) *(--bufpt) = prefix; /* Add sign */
|
||||
if( flag_alternateform && infop->prefix ){ /* Add "0" or "0x" */
|
||||
@@ -469,7 +454,9 @@ void sqlite3VXPrintf(
|
||||
realvalue = -realvalue;
|
||||
prefix = '-';
|
||||
}else{
|
||||
prefix = flag_prefix;
|
||||
if( flag_plussign ) prefix = '+';
|
||||
else if( flag_blanksign ) prefix = ' ';
|
||||
else prefix = 0;
|
||||
}
|
||||
if( xtype==etGENERIC && precision>0 ) precision--;
|
||||
testcase( precision>0xfff );
|
||||
|
||||
+24
-30
@@ -229,8 +229,7 @@ static int lookupName(
|
||||
}
|
||||
|
||||
/* Start at the inner-most context and move outward until a match is found */
|
||||
assert( pNC && cnt==0 );
|
||||
do{
|
||||
while( pNC && cnt==0 ){
|
||||
ExprList *pEList;
|
||||
SrcList *pSrcList = pNC->pSrcList;
|
||||
|
||||
@@ -415,11 +414,11 @@ static int lookupName(
|
||||
/* Advance to the next name context. The loop will exit when either
|
||||
** we have a match (cnt>0) or when we run out of name contexts.
|
||||
*/
|
||||
if( cnt ) break;
|
||||
pNC = pNC->pNext;
|
||||
nSubquery++;
|
||||
}while( pNC );
|
||||
|
||||
if( cnt==0 ){
|
||||
pNC = pNC->pNext;
|
||||
nSubquery++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** If X and Y are NULL (in other words if only the column name Z is
|
||||
@@ -609,38 +608,33 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT)
|
||||
&& !defined(SQLITE_OMIT_SUBQUERY) */
|
||||
|
||||
/* A column name: ID
|
||||
** Or table name and column name: ID.ID
|
||||
** Or a database, table and column: ID.ID.ID
|
||||
**
|
||||
** The TK_ID and TK_OUT cases are combined so that there will only
|
||||
** be one call to lookupName(). Then the compiler will in-line
|
||||
** lookupName() for a size reduction and performance increase.
|
||||
/* A lone identifier is the name of a column.
|
||||
*/
|
||||
case TK_ID: {
|
||||
return lookupName(pParse, 0, 0, pExpr->u.zToken, pNC, pExpr);
|
||||
}
|
||||
|
||||
/* A table name and column name: ID.ID
|
||||
** Or a database, table and column: ID.ID.ID
|
||||
*/
|
||||
case TK_ID:
|
||||
case TK_DOT: {
|
||||
const char *zColumn;
|
||||
const char *zTable;
|
||||
const char *zDb;
|
||||
Expr *pRight;
|
||||
|
||||
if( pExpr->op==TK_ID ){
|
||||
/* if( pSrcList==0 ) break; */
|
||||
notValid(pParse, pNC, "the \".\" operator", NC_IdxExpr);
|
||||
pRight = pExpr->pRight;
|
||||
if( pRight->op==TK_ID ){
|
||||
zDb = 0;
|
||||
zTable = 0;
|
||||
zColumn = pExpr->u.zToken;
|
||||
zTable = pExpr->pLeft->u.zToken;
|
||||
zColumn = pRight->u.zToken;
|
||||
}else{
|
||||
notValid(pParse, pNC, "the \".\" operator", NC_IdxExpr);
|
||||
pRight = pExpr->pRight;
|
||||
if( pRight->op==TK_ID ){
|
||||
zDb = 0;
|
||||
zTable = pExpr->pLeft->u.zToken;
|
||||
zColumn = pRight->u.zToken;
|
||||
}else{
|
||||
assert( pRight->op==TK_DOT );
|
||||
zDb = pExpr->pLeft->u.zToken;
|
||||
zTable = pRight->pLeft->u.zToken;
|
||||
zColumn = pRight->pRight->u.zToken;
|
||||
}
|
||||
assert( pRight->op==TK_DOT );
|
||||
zDb = pExpr->pLeft->u.zToken;
|
||||
zTable = pRight->pLeft->u.zToken;
|
||||
zColumn = pRight->pRight->u.zToken;
|
||||
}
|
||||
return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr);
|
||||
}
|
||||
|
||||
+240
-1446
File diff suppressed because it is too large
Load Diff
+89
-89
@@ -2040,30 +2040,20 @@ int sqlite3_extended_result_codes(sqlite3*, int onoff);
|
||||
** the table has a column of type [INTEGER PRIMARY KEY] then that column
|
||||
** is another alias for the rowid.
|
||||
**
|
||||
** ^The sqlite3_last_insert_rowid(D) interface usually returns the [rowid] of
|
||||
** the most recent successful [INSERT] into a rowid table or [virtual table]
|
||||
** on database connection D. ^Inserts into [WITHOUT ROWID] tables are not
|
||||
** recorded. ^If no successful [INSERT]s into rowid tables have ever occurred
|
||||
** on the database connection D, then sqlite3_last_insert_rowid(D) returns
|
||||
** zero.
|
||||
** ^The sqlite3_last_insert_rowid(D) interface returns the [rowid] of the
|
||||
** most recent successful [INSERT] into a rowid table or [virtual table]
|
||||
** on database connection D.
|
||||
** ^Inserts into [WITHOUT ROWID] tables are not recorded.
|
||||
** ^If no successful [INSERT]s into rowid tables
|
||||
** have ever occurred on the database connection D,
|
||||
** then sqlite3_last_insert_rowid(D) returns zero.
|
||||
**
|
||||
** As well as being set automatically as rows are inserted into database
|
||||
** tables, the value returned by this function may be set explicitly by
|
||||
** [sqlite3_set_last_insert_rowid()]
|
||||
**
|
||||
** Some virtual table implementations may INSERT rows into rowid tables as
|
||||
** part of committing a transaction (e.g. to flush data accumulated in memory
|
||||
** to disk). In this case subsequent calls to this function return the rowid
|
||||
** associated with these internal INSERT operations, which leads to
|
||||
** unintuitive results. Virtual table implementations that do write to rowid
|
||||
** tables in this way can avoid this problem by restoring the original
|
||||
** rowid value using [sqlite3_set_last_insert_rowid()] before returning
|
||||
** control to the user.
|
||||
**
|
||||
** ^(If an [INSERT] occurs within a trigger then this routine will
|
||||
** return the [rowid] of the inserted row as long as the trigger is
|
||||
** running. Once the trigger program ends, the value returned
|
||||
** by this routine reverts to what it was before the trigger was fired.)^
|
||||
** ^(If an [INSERT] occurs within a trigger or within a [virtual table]
|
||||
** method, then this routine will return the [rowid] of the inserted
|
||||
** row as long as the trigger or virtual table method is running.
|
||||
** But once the trigger or virtual table method ends, the value returned
|
||||
** by this routine reverts to what it was before the trigger or virtual
|
||||
** table method began.)^
|
||||
**
|
||||
** ^An [INSERT] that fails due to a constraint violation is not a
|
||||
** successful [INSERT] and does not change the value returned by this
|
||||
@@ -2090,16 +2080,6 @@ int sqlite3_extended_result_codes(sqlite3*, int onoff);
|
||||
*/
|
||||
sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Set the Last Insert Rowid value.
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** The sqlite3_set_last_insert_rowid(D, R) method allows the application to
|
||||
** set the value returned by calling sqlite3_last_insert_rowid(D) to R
|
||||
** without inserting a row into the database.
|
||||
*/
|
||||
void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Count The Number Of Rows Modified
|
||||
** METHOD: sqlite3
|
||||
@@ -6158,15 +6138,27 @@ int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
|
||||
|
||||
/*
|
||||
** CAPI3REF: A Handle To An Open BLOB
|
||||
** KEYWORDS: {BLOB handle} {BLOB handles}
|
||||
** KEYWORDS: {BLOB handle} {BLOB handles} {sqlite3_blob object}
|
||||
**
|
||||
** An instance of this object represents a connection to a single
|
||||
** column in a single row of a table that holds either a BLOB or string
|
||||
** and on which [sqlite3_blob_open | incremental BLOB I/O] can be performed.
|
||||
**
|
||||
** An instance of this object represents an open BLOB on which
|
||||
** [sqlite3_blob_open | incremental BLOB I/O] can be performed.
|
||||
** ^Objects of this type are created by [sqlite3_blob_open()]
|
||||
** and destroyed by [sqlite3_blob_close()].
|
||||
** ^The [sqlite3_blob_read()] and [sqlite3_blob_write()] interfaces
|
||||
** can be used to read or write small subsections of the BLOB.
|
||||
** ^The [sqlite3_blob_bytes()] interface returns the size of the BLOB in bytes.
|
||||
**
|
||||
** An sqlite3_blob object can be in two states: ACTIVE and RESET. When in
|
||||
** the ACTIVE state, the object is pointing to a specific entry and is
|
||||
** ready to do I/O. When RESET, the sqlite3_blob object is in standby mode,
|
||||
** is not associated with any particular row of its table,
|
||||
** and is not available for I/O.
|
||||
**
|
||||
** The sqlite3_blob object does not contain a mutex and so a single
|
||||
** sqlite3_blob object may not be safely used by multiple threads
|
||||
** concurrently.
|
||||
*/
|
||||
typedef struct sqlite3_blob sqlite3_blob;
|
||||
|
||||
@@ -6175,8 +6167,8 @@ typedef struct sqlite3_blob sqlite3_blob;
|
||||
** METHOD: sqlite3
|
||||
** CONSTRUCTOR: sqlite3_blob
|
||||
**
|
||||
** ^(This interfaces opens a [BLOB handle | handle] to the BLOB located
|
||||
** in row iRow, column zColumn, table zTable in database zDb;
|
||||
** ^(This interfaces creates an sqlite3_blob object pointing to the string
|
||||
** or BLOB located in row iRow, column zColumn, table zTable in database zDb;
|
||||
** in other words, the same BLOB that would be selected by:
|
||||
**
|
||||
** <pre>
|
||||
@@ -6193,10 +6185,11 @@ typedef struct sqlite3_blob sqlite3_blob;
|
||||
** and write access. ^If the flags parameter is zero, the BLOB is opened for
|
||||
** read-only access.
|
||||
**
|
||||
** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is stored
|
||||
** in *ppBlob. Otherwise an [error code] is returned and, unless the error
|
||||
** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided
|
||||
** the API is not misused, it is always safe to call [sqlite3_blob_close()]
|
||||
** ^(On success, [SQLITE_OK] is returned and the new [sqlite3_blob object]
|
||||
** is stored in *ppBlob. Otherwise an [error code] is returned and
|
||||
** *ppBlob is set to NULL.)^ ^Because *ppBlob is always set to either a
|
||||
** valid sqlite3_blob object or NULL
|
||||
** it is always safe to call [sqlite3_blob_close()]
|
||||
** on *ppBlob after this function it returns.
|
||||
**
|
||||
** This function fails with SQLITE_ERROR if any of the following are true:
|
||||
@@ -6228,7 +6221,8 @@ typedef struct sqlite3_blob sqlite3_blob;
|
||||
**
|
||||
** ^(If the row that a BLOB handle points to is modified by an
|
||||
** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects
|
||||
** then the BLOB handle is marked as "expired".
|
||||
** then the BLOB handle is marked as "expired" and cannot be used
|
||||
** successfully with first being [sqlite3_blob_reopen|reopened].
|
||||
** This is true if any column of the row is changed, even a column
|
||||
** other than the one the BLOB handle is open on.)^
|
||||
** ^Calls to [sqlite3_blob_read()] and [sqlite3_blob_write()] for
|
||||
@@ -6240,7 +6234,8 @@ typedef struct sqlite3_blob sqlite3_blob;
|
||||
** ^Use the [sqlite3_blob_bytes()] interface to determine the size of
|
||||
** the opened blob. ^The size of a blob may not be changed by this
|
||||
** interface. Use the [UPDATE] SQL command to change the size of a
|
||||
** blob.
|
||||
** blob. The [sqlite3_blob_bytes()] interface returns an arbitrary
|
||||
** number when used on an expired sqlite3_blob object.
|
||||
**
|
||||
** ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces
|
||||
** and the built-in [zeroblob] SQL function may be used to create a
|
||||
@@ -6251,7 +6246,8 @@ typedef struct sqlite3_blob sqlite3_blob;
|
||||
**
|
||||
** See also: [sqlite3_blob_close()],
|
||||
** [sqlite3_blob_reopen()], [sqlite3_blob_read()],
|
||||
** [sqlite3_blob_bytes()], [sqlite3_blob_write()].
|
||||
** [sqlite3_blob_bytes()], [sqlite3_blob_write()],
|
||||
** [sqlite3_blob_reset()].
|
||||
*/
|
||||
int sqlite3_blob_open(
|
||||
sqlite3*,
|
||||
@@ -6264,24 +6260,23 @@ int sqlite3_blob_open(
|
||||
);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Move a BLOB Handle to a New Row
|
||||
** CAPI3REF: Move an sqlite3_blob object to a New Row
|
||||
** METHOD: sqlite3_blob
|
||||
**
|
||||
** ^This function is used to move an existing [BLOB handle] so that it points
|
||||
** ^This function updates an existing [sqlite3_blob object] so that it points
|
||||
** to a different row of the same database table. ^The new row is identified
|
||||
** by the rowid value passed as the second argument. Only the row can be
|
||||
** changed. ^The database, table and column on which the blob handle is open
|
||||
** remain the same. Moving an existing [BLOB handle] to a new row is
|
||||
** remain the same. Moving an existing [sqlite3_blob object] to a new row is
|
||||
** faster than closing the existing handle and opening a new one.
|
||||
**
|
||||
** ^(The new row must meet the same criteria as for [sqlite3_blob_open()] -
|
||||
** it must exist and there must be either a blob or text value stored in
|
||||
** the nominated column.)^ ^If the new row is not present in the table, or if
|
||||
** it does not contain a blob or text value, or if another error occurs, an
|
||||
** SQLite error code is returned and the blob handle is considered aborted.
|
||||
** ^All subsequent calls to [sqlite3_blob_read()], [sqlite3_blob_write()] or
|
||||
** [sqlite3_blob_reopen()] on an aborted blob handle immediately return
|
||||
** SQLITE_ABORT. ^Calling [sqlite3_blob_bytes()] on an aborted blob handle
|
||||
** SQLite error code is returned and the [sqlite3_blob object] is changed
|
||||
** to the RESET state.
|
||||
** ^Calling [sqlite3_blob_bytes()] on an aborted blob handle
|
||||
** always returns zero.
|
||||
**
|
||||
** ^This function sets the database handle error code and message.
|
||||
@@ -6289,38 +6284,52 @@ int sqlite3_blob_open(
|
||||
int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Close A BLOB Handle
|
||||
** CAPI3REF: Close an sqlite3_blob object
|
||||
** DESTRUCTOR: sqlite3_blob
|
||||
**
|
||||
** ^This function closes an open [BLOB handle]. ^(The BLOB handle is closed
|
||||
** ^This function is the destructor for an [sqlite3_blob object].
|
||||
** ^(The [sqlite3_blob object] is closed
|
||||
** unconditionally. Even if this routine returns an error code, the
|
||||
** handle is still closed.)^
|
||||
** object is still closed.)^
|
||||
**
|
||||
** ^If the blob handle being closed was opened for read-write access, and if
|
||||
** the database is in auto-commit mode and there are no other open read-write
|
||||
** ^If the sqlite3_blob object being closed was opened for read-write access,
|
||||
** and is in the ACTIVE state,
|
||||
** and if the database is in auto-commit mode and there are no other open
|
||||
** read-write
|
||||
** blob handles or active write statements, the current transaction is
|
||||
** committed. ^If an error occurs while committing the transaction, an error
|
||||
** code is returned and the transaction rolled back.
|
||||
**
|
||||
** Calling this function with an argument that is not a NULL pointer or an
|
||||
** open blob handle results in undefined behaviour. ^Calling this routine
|
||||
** Calling this function with an argument that is not a NULL pointer or a
|
||||
** valid sqlite3_blob object pointer results in undefined behaviour.
|
||||
** ^Calling this routine
|
||||
** with a null pointer (such as would be returned by a failed call to
|
||||
** [sqlite3_blob_open()]) is a harmless no-op. ^Otherwise, if this function
|
||||
** is passed a valid open blob handle, the values returned by the
|
||||
** is passed a valid sqlite3_blob objecct pointer, the values returned by the
|
||||
** sqlite3_errcode() and sqlite3_errmsg() functions are set before returning.
|
||||
*/
|
||||
int sqlite3_blob_close(sqlite3_blob *);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Return The Size Of An Open BLOB
|
||||
** CAPI3REF: Reset an sqlite3_blob object
|
||||
** METHOD: sqlite3_blob
|
||||
**
|
||||
** ^Returns the size in bytes of the BLOB accessible via the
|
||||
** successfully opened [BLOB handle] in its only argument. ^The
|
||||
** incremental blob I/O routines can only read or overwriting existing
|
||||
** blob content; they cannot change the size of a blob.
|
||||
** ^This function changes an [sqlite3_blob object] to the RESET state.
|
||||
** ^If the [sqlite3_blob object] was already in the RESET state, then this
|
||||
** routine is a harmless no-op.
|
||||
*/
|
||||
int sqlite3_blob_reset(sqlite3_blob *);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Return The Size Of A BLOB
|
||||
** METHOD: sqlite3_blob
|
||||
**
|
||||
** This routine only works on a [BLOB handle] which has been created
|
||||
** ^Returns the size in bytes of the BLOB or string accessible via the
|
||||
** ACTIVE [sqlite3_blob object] in its only argument. ^The
|
||||
** incremental blob I/O routines can only read or overwriting existing
|
||||
** content; they cannot change the size of a blob or string.
|
||||
**
|
||||
** This routine only works on an [sqlite3_blob object] that has been created
|
||||
** by a prior successful call to [sqlite3_blob_open()] and which has not
|
||||
** been closed by [sqlite3_blob_close()]. Passing any other pointer in
|
||||
** to this routine results in undefined and probably undesirable behavior.
|
||||
@@ -6331,9 +6340,9 @@ int sqlite3_blob_bytes(sqlite3_blob *);
|
||||
** CAPI3REF: Read Data From A BLOB Incrementally
|
||||
** METHOD: sqlite3_blob
|
||||
**
|
||||
** ^(This function is used to read data from an open [BLOB handle] into a
|
||||
** caller-supplied buffer. N bytes of data are copied into buffer Z
|
||||
** from the open BLOB, starting at offset iOffset.)^
|
||||
** ^(This function is used to read data from string or BLOB that an
|
||||
** [sqlite3_blob object] is pointing to into a caller-supplied buffer.
|
||||
** N bytes of data are copied into buffer Z starting at offset iOffset.)^
|
||||
**
|
||||
** ^If offset iOffset is less than N bytes from the end of the BLOB,
|
||||
** [SQLITE_ERROR] is returned and no data is read. ^If N or iOffset is
|
||||
@@ -6341,17 +6350,14 @@ int sqlite3_blob_bytes(sqlite3_blob *);
|
||||
** ^The size of the blob (and hence the maximum value of N+iOffset)
|
||||
** can be determined using the [sqlite3_blob_bytes()] interface.
|
||||
**
|
||||
** ^An attempt to read from an expired [BLOB handle] fails with an
|
||||
** ^An attempt to read from an [sqlite3_blob object] that is in the RESET
|
||||
** state, or from a database row that has changed since the most recent
|
||||
** call to [sqlite3_blob_open()] or [sqlite3_blob_reopen()] fails with an
|
||||
** error code of [SQLITE_ABORT].
|
||||
**
|
||||
** ^(On success, sqlite3_blob_read() returns SQLITE_OK.
|
||||
** Otherwise, an [error code] or an [extended error code] is returned.)^
|
||||
**
|
||||
** This routine only works on a [BLOB handle] which has been created
|
||||
** by a prior successful call to [sqlite3_blob_open()] and which has not
|
||||
** been closed by [sqlite3_blob_close()]. Passing any other pointer in
|
||||
** to this routine results in undefined and probably undesirable behavior.
|
||||
**
|
||||
** See also: [sqlite3_blob_write()].
|
||||
*/
|
||||
int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
|
||||
@@ -6360,9 +6366,10 @@ int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
|
||||
** CAPI3REF: Write Data Into A BLOB Incrementally
|
||||
** METHOD: sqlite3_blob
|
||||
**
|
||||
** ^(This function is used to write data into an open [BLOB handle] from a
|
||||
** caller-supplied buffer. N bytes of data are copied from the buffer Z
|
||||
** into the open BLOB, starting at offset iOffset.)^
|
||||
** ^(This function is used to write data from a caller-supplied buffer
|
||||
** into a BLOB or string pointed to by an [sqlite3_blob object].
|
||||
** N bytes of data are copied from the buffer Z
|
||||
** into the BLOB or string, starting at offset iOffset.)^
|
||||
**
|
||||
** ^(On success, sqlite3_blob_write() returns SQLITE_OK.
|
||||
** Otherwise, an [error code] or an [extended error code] is returned.)^
|
||||
@@ -6382,17 +6389,10 @@ int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
|
||||
** using the [sqlite3_blob_bytes()] interface. ^If N or iOffset are less
|
||||
** than zero [SQLITE_ERROR] is returned and no data is written.
|
||||
**
|
||||
** ^An attempt to write to an expired [BLOB handle] fails with an
|
||||
** error code of [SQLITE_ABORT]. ^Writes to the BLOB that occurred
|
||||
** before the [BLOB handle] expired are not rolled back by the
|
||||
** expiration of the handle, though of course those changes might
|
||||
** have been overwritten by the statement that expired the BLOB handle
|
||||
** or by other independent statements.
|
||||
**
|
||||
** This routine only works on a [BLOB handle] which has been created
|
||||
** by a prior successful call to [sqlite3_blob_open()] and which has not
|
||||
** been closed by [sqlite3_blob_close()]. Passing any other pointer in
|
||||
** to this routine results in undefined and probably undesirable behavior.
|
||||
** ^An attempt to write into an [sqlite3_blob object] that is in the RESET
|
||||
** state, or into a database row that has changed since the most recent
|
||||
** call to [sqlite3_blob_open()] or [sqlite3_blob_reopen()] fails with an
|
||||
** error code of [SQLITE_ABORT].
|
||||
**
|
||||
** See also: [sqlite3_blob_read()].
|
||||
*/
|
||||
|
||||
+34
-52
@@ -103,28 +103,19 @@
|
||||
# define _LARGEFILE_SOURCE 1
|
||||
#endif
|
||||
|
||||
/* The GCC_VERSION and MSVC_VERSION macros are used to
|
||||
** conditionally include optimizations for each of these compilers. A
|
||||
** value of 0 means that compiler is not being used. The
|
||||
** SQLITE_DISABLE_INTRINSIC macro means do not use any compiler-specific
|
||||
** optimizations, and hence set all compiler macros to 0
|
||||
**
|
||||
** There was once also a CLANG_VERSION macro. However, we learn that the
|
||||
** version numbers in clang are for "marketing" only and are inconsistent
|
||||
** and unreliable. Fortunately, all versions of clang also recognize the
|
||||
** gcc version numbers and have reasonable settings for gcc version numbers,
|
||||
** so the GCC_VERSION macro will be set to a correct non-zero value even
|
||||
** when compiling with clang.
|
||||
*/
|
||||
#if defined(__GNUC__) && !defined(SQLITE_DISABLE_INTRINSIC)
|
||||
/* What version of GCC is being used. 0 means GCC is not being used */
|
||||
#ifdef __GNUC__
|
||||
# define GCC_VERSION (__GNUC__*1000000+__GNUC_MINOR__*1000+__GNUC_PATCHLEVEL__)
|
||||
#else
|
||||
# define GCC_VERSION 0
|
||||
#endif
|
||||
#if defined(_MSC_VER) && !defined(SQLITE_DISABLE_INTRINSIC)
|
||||
# define MSVC_VERSION _MSC_VER
|
||||
|
||||
/* What version of CLANG is being used. 0 means CLANG is not being used */
|
||||
#if defined(__clang__) && !defined(_WIN32)
|
||||
# define CLANG_VERSION \
|
||||
(__clang_major__*1000000+__clang_minor__*1000+__clang_patchlevel__)
|
||||
#else
|
||||
# define MSVC_VERSION 0
|
||||
# define CLANG_VERSION 0
|
||||
#endif
|
||||
|
||||
/* Needed for various definitions... */
|
||||
@@ -256,7 +247,6 @@
|
||||
# include <intrin.h>
|
||||
# pragma intrinsic(_byteswap_ushort)
|
||||
# pragma intrinsic(_byteswap_ulong)
|
||||
# pragma intrinsic(_byteswap_uint64)
|
||||
# pragma intrinsic(_ReadWriteBarrier)
|
||||
# else
|
||||
# include <cmnintrin.h>
|
||||
@@ -797,35 +787,32 @@ typedef INT16_TYPE LogEst;
|
||||
**
|
||||
** For best performance, an attempt is made to guess at the byte-order
|
||||
** using C-preprocessor macros. If that is unsuccessful, or if
|
||||
** -DSQLITE_BYTEORDER=0 is set, then byte-order is determined
|
||||
** -DSQLITE_RUNTIME_BYTEORDER=1 is set, then byte-order is determined
|
||||
** at run-time.
|
||||
*/
|
||||
#ifndef SQLITE_BYTEORDER
|
||||
# if defined(i386) || defined(__i386__) || defined(_M_IX86) || \
|
||||
#if (defined(i386) || defined(__i386__) || defined(_M_IX86) || \
|
||||
defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
|
||||
defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \
|
||||
defined(__arm__)
|
||||
# define SQLITE_BYTEORDER 1234
|
||||
# elif defined(sparc) || defined(__ppc__)
|
||||
# define SQLITE_BYTEORDER 4321
|
||||
# else
|
||||
# define SQLITE_BYTEORDER 0
|
||||
# endif
|
||||
#endif
|
||||
#if SQLITE_BYTEORDER==4321
|
||||
# define SQLITE_BIGENDIAN 1
|
||||
# define SQLITE_LITTLEENDIAN 0
|
||||
# define SQLITE_UTF16NATIVE SQLITE_UTF16BE
|
||||
#elif SQLITE_BYTEORDER==1234
|
||||
defined(__arm__)) && !defined(SQLITE_RUNTIME_BYTEORDER)
|
||||
# define SQLITE_BYTEORDER 1234
|
||||
# define SQLITE_BIGENDIAN 0
|
||||
# define SQLITE_LITTLEENDIAN 1
|
||||
# define SQLITE_UTF16NATIVE SQLITE_UTF16LE
|
||||
#else
|
||||
#endif
|
||||
#if (defined(sparc) || defined(__ppc__)) \
|
||||
&& !defined(SQLITE_RUNTIME_BYTEORDER)
|
||||
# define SQLITE_BYTEORDER 4321
|
||||
# define SQLITE_BIGENDIAN 1
|
||||
# define SQLITE_LITTLEENDIAN 0
|
||||
# define SQLITE_UTF16NATIVE SQLITE_UTF16BE
|
||||
#endif
|
||||
#if !defined(SQLITE_BYTEORDER)
|
||||
# ifdef SQLITE_AMALGAMATION
|
||||
const int sqlite3one = 1;
|
||||
# else
|
||||
extern const int sqlite3one;
|
||||
# endif
|
||||
# define SQLITE_BYTEORDER 0 /* 0 means "unknown at compile-time" */
|
||||
# define SQLITE_BIGENDIAN (*(char *)(&sqlite3one)==0)
|
||||
# define SQLITE_LITTLEENDIAN (*(char *)(&sqlite3one)==1)
|
||||
# define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE)
|
||||
@@ -1333,7 +1320,6 @@ struct sqlite3 {
|
||||
u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */
|
||||
u8 mTrace; /* zero or more SQLITE_TRACE flags */
|
||||
u8 skipBtreeMutex; /* True if no shared-cache backends */
|
||||
u8 nSqlExec; /* Number of pending OP_SqlExec opcodes */
|
||||
int nextPagesize; /* Pagesize after VACUUM if >0 */
|
||||
u32 magic; /* Magic number for detect library misuse */
|
||||
int nChange; /* Value returned by sqlite3_changes() */
|
||||
@@ -1849,7 +1835,6 @@ struct Table {
|
||||
/* ... also used as column name list in a VIEW */
|
||||
int tnum; /* Root BTree page for this table */
|
||||
u32 nTabRef; /* Number of pointers to this Table */
|
||||
u32 tabFlags; /* Mask of TF_* values */
|
||||
i16 iPKey; /* If not negative, use aCol[iPKey] as the rowid */
|
||||
i16 nCol; /* Number of columns in this table */
|
||||
LogEst nRowLogEst; /* Estimated rows in table - from sqlite_stat1 table */
|
||||
@@ -1857,6 +1842,7 @@ struct Table {
|
||||
#ifdef SQLITE_ENABLE_COSTMULT
|
||||
LogEst costMult; /* Cost multiplier for using this table */
|
||||
#endif
|
||||
u8 tabFlags; /* Mask of TF_* values */
|
||||
u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */
|
||||
#ifndef SQLITE_OMIT_ALTERTABLE
|
||||
int addColOffset; /* Offset in CREATE TABLE stmt to add a new column */
|
||||
@@ -1880,17 +1866,15 @@ struct Table {
|
||||
** the TF_OOOHidden attribute would apply in this case. Such tables require
|
||||
** special handling during INSERT processing.
|
||||
*/
|
||||
#define TF_Readonly 0x0001 /* Read-only system table */
|
||||
#define TF_Ephemeral 0x0002 /* An ephemeral table */
|
||||
#define TF_HasPrimaryKey 0x0004 /* Table has a primary key */
|
||||
#define TF_Autoincrement 0x0008 /* Integer primary key is autoincrement */
|
||||
#define TF_HasStat1 0x0010 /* nRowLogEst set from sqlite_stat1 */
|
||||
#define TF_WithoutRowid 0x0020 /* No rowid. PRIMARY KEY is the key */
|
||||
#define TF_NoVisibleRowid 0x0040 /* No user-visible "rowid" column */
|
||||
#define TF_OOOHidden 0x0080 /* Out-of-Order hidden columns */
|
||||
#define TF_StatsUsed 0x0100 /* Query planner decisions affected by
|
||||
** Index.aiRowLogEst[] values */
|
||||
#define TF_HasNotNull 0x0200 /* Contains NOT NULL constraints */
|
||||
#define TF_Readonly 0x01 /* Read-only system table */
|
||||
#define TF_Ephemeral 0x02 /* An ephemeral table */
|
||||
#define TF_HasPrimaryKey 0x04 /* Table has a primary key */
|
||||
#define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */
|
||||
#define TF_Virtual 0x10 /* Is a virtual table */
|
||||
#define TF_WithoutRowid 0x20 /* No rowid. PRIMARY KEY is the key */
|
||||
#define TF_NoVisibleRowid 0x40 /* No user-visible "rowid" column */
|
||||
#define TF_OOOHidden 0x80 /* Out-of-Order hidden columns */
|
||||
|
||||
|
||||
/*
|
||||
** Test to see whether or not a table is a virtual table. This is
|
||||
@@ -1898,7 +1882,7 @@ struct Table {
|
||||
** table support is omitted from the build.
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
# define IsVirtual(X) ((X)->nModuleArg)
|
||||
# define IsVirtual(X) (((X)->tabFlags & TF_Virtual)!=0)
|
||||
#else
|
||||
# define IsVirtual(X) 0
|
||||
#endif
|
||||
@@ -2133,7 +2117,6 @@ struct Index {
|
||||
unsigned isResized:1; /* True if resizeIndexObject() has been called */
|
||||
unsigned isCovering:1; /* True if this is a covering index */
|
||||
unsigned noSkipScan:1; /* Do not try to use skip-scan if true */
|
||||
unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
int nSample; /* Number of elements in aSample[] */
|
||||
int nSampleCol; /* Size of IndexSample.anEq[] and so on */
|
||||
@@ -2444,7 +2427,7 @@ struct Expr {
|
||||
struct ExprList {
|
||||
int nExpr; /* Number of expressions on the list */
|
||||
struct ExprList_item { /* For each expression in the list */
|
||||
Expr *pExpr; /* The parse tree for this expression */
|
||||
Expr *pExpr; /* The list of expressions */
|
||||
char *zName; /* Token associated with this expression */
|
||||
char *zSpan; /* Original text of the expression */
|
||||
u8 sortOrder; /* 1 for DESC or 0 for ASC */
|
||||
@@ -3767,7 +3750,6 @@ void sqlite3Vacuum(Parse*,Token*);
|
||||
int sqlite3RunVacuum(char**, sqlite3*, int);
|
||||
char *sqlite3NameFromToken(sqlite3*, Token*);
|
||||
int sqlite3ExprCompare(Expr*, Expr*, int);
|
||||
int sqlite3ExprCompareSkip(Expr*, Expr*, int);
|
||||
int sqlite3ExprListCompare(ExprList*, ExprList*, int);
|
||||
int sqlite3ExprImpliesExpr(Expr*, Expr*, int);
|
||||
void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
|
||||
|
||||
@@ -3405,6 +3405,10 @@ static int SQLITE_TCLAPI DbMain(
|
||||
}
|
||||
zErrMsg = 0;
|
||||
p = (SqliteDb*)Tcl_Alloc( sizeof(*p) );
|
||||
if( p==0 ){
|
||||
Tcl_SetResult(interp, (char *)"malloc failed", TCL_STATIC);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
memset(p, 0, sizeof(*p));
|
||||
zFile = Tcl_GetStringFromObj(objv[2], 0);
|
||||
zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename);
|
||||
|
||||
+8
-13
@@ -161,13 +161,13 @@ static CrashGlobal g = {0, 0, SQLITE_DEFAULT_SECTOR_SIZE, 0, 0};
|
||||
static int sqlite3CrashTestEnable = 0;
|
||||
|
||||
static void *crash_malloc(int nByte){
|
||||
return (void *)Tcl_AttemptAlloc((size_t)nByte);
|
||||
return (void *)Tcl_Alloc((size_t)nByte);
|
||||
}
|
||||
static void crash_free(void *p){
|
||||
Tcl_Free(p);
|
||||
}
|
||||
static void *crash_realloc(void *p, int n){
|
||||
return (void *)Tcl_AttemptRealloc(p, (size_t)n);
|
||||
return (void *)Tcl_Realloc(p, (size_t)n);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -315,9 +315,8 @@ static int writeListSync(CrashFile *pFile, int isCrash){
|
||||
assert(pWrite->zBuf);
|
||||
|
||||
#ifdef TRACE_CRASHTEST
|
||||
printf("Trashing %d sectors (%d bytes) @ %lld (sector %d) (%s)\n",
|
||||
1+iLast-iFirst, (1+iLast-iFirst)*g.iSectorSize,
|
||||
pWrite->iOffset, iFirst, pWrite->pFile->zName
|
||||
printf("Trashing %d sectors @ %lld (sector %d) (%s)\n",
|
||||
1+iLast-iFirst, pWrite->iOffset, iFirst, pWrite->pFile->zName
|
||||
);
|
||||
#endif
|
||||
|
||||
@@ -828,7 +827,7 @@ static int SQLITE_TCLAPI crashNowCmd(
|
||||
}
|
||||
|
||||
/*
|
||||
** tclcmd: sqlite_crash_enable ENABLE ?DEFAULT?
|
||||
** tclcmd: sqlite_crash_enable ENABLE
|
||||
**
|
||||
** Parameter ENABLE must be a boolean value. If true, then the "crash"
|
||||
** vfs is added to the system. If false, it is removed.
|
||||
@@ -840,7 +839,6 @@ static int SQLITE_TCLAPI crashEnableCmd(
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
int isEnable;
|
||||
int isDefault = 0;
|
||||
static sqlite3_vfs crashVfs = {
|
||||
2, /* iVersion */
|
||||
0, /* szOsFile */
|
||||
@@ -864,17 +862,14 @@ static int SQLITE_TCLAPI crashEnableCmd(
|
||||
0, /* xCurrentTimeInt64 */
|
||||
};
|
||||
|
||||
if( objc!=2 && objc!=3 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "ENABLE ?DEFAULT?");
|
||||
if( objc!=2 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "ENABLE");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if( Tcl_GetBooleanFromObj(interp, objv[1], &isEnable) ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( objc==3 && Tcl_GetBooleanFromObj(interp, objv[2], &isDefault) ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if( (isEnable && crashVfs.pAppData) || (!isEnable && !crashVfs.pAppData) ){
|
||||
return TCL_OK;
|
||||
@@ -885,7 +880,7 @@ static int SQLITE_TCLAPI crashEnableCmd(
|
||||
crashVfs.mxPathname = pOriginalVfs->mxPathname;
|
||||
crashVfs.pAppData = (void *)pOriginalVfs;
|
||||
crashVfs.szOsFile = sizeof(CrashFile) + pOriginalVfs->szOsFile;
|
||||
sqlite3_vfs_register(&crashVfs, isDefault);
|
||||
sqlite3_vfs_register(&crashVfs, 0);
|
||||
}else{
|
||||
crashVfs.pAppData = 0;
|
||||
sqlite3_vfs_unregister(&crashVfs);
|
||||
|
||||
+1
-5
@@ -239,11 +239,7 @@ static int SQLITE_TCLAPI test_blob_read(
|
||||
}
|
||||
|
||||
if( nByte>0 ){
|
||||
zBuf = (unsigned char *)Tcl_AttemptAlloc(nByte);
|
||||
if( zBuf==0 ){
|
||||
Tcl_AppendResult(interp, "out of memory", 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
zBuf = (unsigned char *)Tcl_Alloc(nByte);
|
||||
}
|
||||
rc = sqlite3_blob_read(pBlob, zBuf, nByte, iOffset);
|
||||
if( rc==SQLITE_OK ){
|
||||
|
||||
+11
-12
@@ -475,8 +475,8 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){
|
||||
*/
|
||||
int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
|
||||
int nErr = 0; /* Number of errors encountered */
|
||||
int i; /* Loop counter */
|
||||
void *pEngine; /* The LEMON-generated LALR(1) parser */
|
||||
int n = 0; /* Length of the next token token */
|
||||
int tokenType; /* type of the next token */
|
||||
int lastTokenParsed = -1; /* type of the previous token */
|
||||
sqlite3 *db = pParse->db; /* The database connection */
|
||||
@@ -492,6 +492,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
|
||||
}
|
||||
pParse->rc = SQLITE_OK;
|
||||
pParse->zTail = zSql;
|
||||
i = 0;
|
||||
assert( pzErrMsg!=0 );
|
||||
/* sqlite3ParserTrace(stdout, "parser: "); */
|
||||
#ifdef sqlite3Parser_ENGINEALWAYSONSTACK
|
||||
@@ -509,10 +510,12 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
|
||||
assert( pParse->nVar==0 );
|
||||
assert( pParse->pVList==0 );
|
||||
while( 1 ){
|
||||
if( zSql[0]!=0 ){
|
||||
n = sqlite3GetToken((u8*)zSql, &tokenType);
|
||||
mxSqlLen -= n;
|
||||
if( mxSqlLen<0 ){
|
||||
assert( i>=0 );
|
||||
if( zSql[i]!=0 ){
|
||||
pParse->sLastToken.z = &zSql[i];
|
||||
pParse->sLastToken.n = sqlite3GetToken((u8*)&zSql[i],&tokenType);
|
||||
i += pParse->sLastToken.n;
|
||||
if( i>mxSqlLen ){
|
||||
pParse->rc = SQLITE_TOOBIG;
|
||||
break;
|
||||
}
|
||||
@@ -526,7 +529,6 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
|
||||
}else{
|
||||
tokenType = TK_SEMI;
|
||||
}
|
||||
zSql -= n;
|
||||
}
|
||||
if( tokenType>=TK_SPACE ){
|
||||
assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL );
|
||||
@@ -535,21 +537,18 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
|
||||
break;
|
||||
}
|
||||
if( tokenType==TK_ILLEGAL ){
|
||||
sqlite3ErrorMsg(pParse, "unrecognized token: \"%.*s\"", n, zSql);
|
||||
sqlite3ErrorMsg(pParse, "unrecognized token: \"%T\"",
|
||||
&pParse->sLastToken);
|
||||
break;
|
||||
}
|
||||
zSql += n;
|
||||
}else{
|
||||
pParse->sLastToken.z = zSql;
|
||||
pParse->sLastToken.n = n;
|
||||
sqlite3Parser(pEngine, tokenType, pParse->sLastToken, pParse);
|
||||
lastTokenParsed = tokenType;
|
||||
zSql += n;
|
||||
if( pParse->rc!=SQLITE_OK || db->mallocFailed ) break;
|
||||
}
|
||||
}
|
||||
assert( nErr==0 );
|
||||
pParse->zTail = zSql;
|
||||
pParse->zTail = &zSql[i];
|
||||
#ifdef YYTRACKMAXSTACKDEPTH
|
||||
sqlite3_mutex_enter(sqlite3MallocMutex());
|
||||
sqlite3StatusHighwater(SQLITE_STATUS_PARSER_STACK,
|
||||
|
||||
+14
-7
@@ -1140,11 +1140,13 @@ u32 sqlite3Get4byte(const u8 *p){
|
||||
u32 x;
|
||||
memcpy(&x,p,4);
|
||||
return x;
|
||||
#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
|
||||
#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
|
||||
&& (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000)
|
||||
u32 x;
|
||||
memcpy(&x,p,4);
|
||||
return __builtin_bswap32(x);
|
||||
#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
|
||||
#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
|
||||
&& defined(_MSC_VER) && _MSC_VER>=1300
|
||||
u32 x;
|
||||
memcpy(&x,p,4);
|
||||
return _byteswap_ulong(x);
|
||||
@@ -1156,10 +1158,12 @@ u32 sqlite3Get4byte(const u8 *p){
|
||||
void sqlite3Put4byte(unsigned char *p, u32 v){
|
||||
#if SQLITE_BYTEORDER==4321
|
||||
memcpy(p,&v,4);
|
||||
#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
|
||||
#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
|
||||
&& (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000)
|
||||
u32 x = __builtin_bswap32(v);
|
||||
memcpy(p,&x,4);
|
||||
#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
|
||||
#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
|
||||
&& defined(_MSC_VER) && _MSC_VER>=1300
|
||||
u32 x = _byteswap_ulong(v);
|
||||
memcpy(p,&x,4);
|
||||
#else
|
||||
@@ -1275,7 +1279,8 @@ int sqlite3SafetyCheckSickOrOk(sqlite3 *db){
|
||||
** overflow, leave *pA unchanged and return 1.
|
||||
*/
|
||||
int sqlite3AddInt64(i64 *pA, i64 iB){
|
||||
#if GCC_VERSION>=5004000
|
||||
#if !defined(SQLITE_DISABLE_INTRINSIC) \
|
||||
&& (GCC_VERSION>=5004000 || CLANG_VERSION>=4000000)
|
||||
return __builtin_add_overflow(*pA, iB, pA);
|
||||
#else
|
||||
i64 iA = *pA;
|
||||
@@ -1295,7 +1300,8 @@ int sqlite3AddInt64(i64 *pA, i64 iB){
|
||||
#endif
|
||||
}
|
||||
int sqlite3SubInt64(i64 *pA, i64 iB){
|
||||
#if GCC_VERSION>=5004000
|
||||
#if !defined(SQLITE_DISABLE_INTRINSIC) \
|
||||
&& (GCC_VERSION>=5004000 || CLANG_VERSION>=4000000)
|
||||
return __builtin_sub_overflow(*pA, iB, pA);
|
||||
#else
|
||||
testcase( iB==SMALLEST_INT64+1 );
|
||||
@@ -1310,7 +1316,8 @@ int sqlite3SubInt64(i64 *pA, i64 iB){
|
||||
#endif
|
||||
}
|
||||
int sqlite3MulInt64(i64 *pA, i64 iB){
|
||||
#if GCC_VERSION>=5004000
|
||||
#if !defined(SQLITE_DISABLE_INTRINSIC) \
|
||||
&& (GCC_VERSION>=5004000 || CLANG_VERSION>=4000000)
|
||||
return __builtin_mul_overflow(*pA, iB, pA);
|
||||
#else
|
||||
i64 iA = *pA;
|
||||
|
||||
+2
-19
@@ -98,25 +98,8 @@ static int execSqlF(sqlite3 *db, char **pzErrMsg, const char *zSql, ...){
|
||||
*/
|
||||
void sqlite3Vacuum(Parse *pParse, Token *pNm){
|
||||
Vdbe *v = sqlite3GetVdbe(pParse);
|
||||
int iDb = 0;
|
||||
if( v==0 ) return;
|
||||
if( pNm ){
|
||||
#ifndef SQLITE_BUG_COMPATIBLE_20160819
|
||||
/* Default behavior: Report an error if the argument to VACUUM is
|
||||
** not recognized */
|
||||
iDb = sqlite3TwoPartName(pParse, pNm, pNm, &pNm);
|
||||
if( iDb<0 ) return;
|
||||
#else
|
||||
/* When SQLITE_BUG_COMPATIBLE_20160819 is defined, unrecognized arguments
|
||||
** to VACUUM are silently ignored. This is a back-out of a bug fix that
|
||||
** occurred on 2016-08-19 (https://www.sqlite.org/src/info/083f9e6270).
|
||||
** The buggy behavior is required for binary compatibility with some
|
||||
** legacy applications. */
|
||||
iDb = sqlite3FindDb(pParse->db, pNm);
|
||||
if( iDb<0 ) iDb = 0;
|
||||
#endif
|
||||
}
|
||||
if( iDb!=1 ){
|
||||
int iDb = pNm ? sqlite3TwoPartName(pParse, pNm, pNm, &pNm) : 0;
|
||||
if( v && (iDb>=2 || iDb==0) ){
|
||||
sqlite3VdbeAddOp1(v, OP_Vacuum, iDb);
|
||||
sqlite3VdbeUsesBtree(v, iDb);
|
||||
}
|
||||
|
||||
+11
-50
@@ -1669,21 +1669,21 @@ case OP_Function: {
|
||||
for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i];
|
||||
}
|
||||
|
||||
memAboutToChange(p, pOut);
|
||||
memAboutToChange(p, pCtx->pOut);
|
||||
#ifdef SQLITE_DEBUG
|
||||
for(i=0; i<pCtx->argc; i++){
|
||||
assert( memIsValid(pCtx->argv[i]) );
|
||||
REGISTER_TRACE(pOp->p2+i, pCtx->argv[i]);
|
||||
}
|
||||
#endif
|
||||
MemSetTypeFlag(pOut, MEM_Null);
|
||||
MemSetTypeFlag(pCtx->pOut, MEM_Null);
|
||||
pCtx->fErrorOrAux = 0;
|
||||
(*pCtx->pFunc->xSFunc)(pCtx, pCtx->argc, pCtx->argv);/* IMP: R-24505-23230 */
|
||||
|
||||
/* If the function returned an error, throw an exception */
|
||||
if( pCtx->fErrorOrAux ){
|
||||
if( pCtx->isError ){
|
||||
sqlite3VdbeError(p, "%s", sqlite3_value_text(pOut));
|
||||
sqlite3VdbeError(p, "%s", sqlite3_value_text(pCtx->pOut));
|
||||
rc = pCtx->isError;
|
||||
}
|
||||
sqlite3VdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1);
|
||||
@@ -1692,12 +1692,12 @@ case OP_Function: {
|
||||
|
||||
/* Copy the result of the function into register P3 */
|
||||
if( pOut->flags & (MEM_Str|MEM_Blob) ){
|
||||
sqlite3VdbeChangeEncoding(pOut, encoding);
|
||||
if( sqlite3VdbeMemTooBig(pOut) ) goto too_big;
|
||||
sqlite3VdbeChangeEncoding(pCtx->pOut, encoding);
|
||||
if( sqlite3VdbeMemTooBig(pCtx->pOut) ) goto too_big;
|
||||
}
|
||||
|
||||
REGISTER_TRACE(pOp->p3, pOut);
|
||||
UPDATE_MAX_BLOBSIZE(pOut);
|
||||
REGISTER_TRACE(pOp->p3, pCtx->pOut);
|
||||
UPDATE_MAX_BLOBSIZE(pCtx->pOut);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2198,7 +2198,7 @@ case OP_Compare: {
|
||||
assert( pKeyInfo!=0 );
|
||||
p1 = pOp->p1;
|
||||
p2 = pOp->p2;
|
||||
#ifdef SQLITE_DEBUG
|
||||
#if SQLITE_DEBUG
|
||||
if( aPermute ){
|
||||
int k, mx = 0;
|
||||
for(k=0; k<n; k++) if( aPermute[k]>mx ) mx = aPermute[k];
|
||||
@@ -4847,33 +4847,6 @@ case OP_Last: { /* jump */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: IfSmaller P1 P2 P3 * *
|
||||
**
|
||||
** Estimate the number of rows in the table P1. Jump to P2 if that
|
||||
** estimate is less than approximately 2**(0.1*P3).
|
||||
*/
|
||||
case OP_IfSmaller: { /* jump */
|
||||
VdbeCursor *pC;
|
||||
BtCursor *pCrsr;
|
||||
int res;
|
||||
i64 sz;
|
||||
|
||||
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
|
||||
pC = p->apCsr[pOp->p1];
|
||||
assert( pC!=0 );
|
||||
pCrsr = pC->uc.pCursor;
|
||||
assert( pCrsr );
|
||||
rc = sqlite3BtreeFirst(pCrsr, &res);
|
||||
if( rc ) goto abort_due_to_error;
|
||||
if( res==0 ){
|
||||
sz = sqlite3BtreeRowCountEst(pCrsr);
|
||||
if( ALWAYS(sz>=0) && sqlite3LogEst((u64)sz)<pOp->p3 ) res = 1;
|
||||
}
|
||||
VdbeBranchTaken(res!=0,2);
|
||||
if( res ) goto jump_to_p2;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* Opcode: SorterSort P1 P2 * * *
|
||||
**
|
||||
@@ -5518,18 +5491,6 @@ case OP_CreateTable: { /* out2 */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: SqlExec * * * P4 *
|
||||
**
|
||||
** Run the SQL statement or statements specified in the P4 string.
|
||||
*/
|
||||
case OP_SqlExec: {
|
||||
db->nSqlExec++;
|
||||
rc = sqlite3_exec(db, pOp->p4.z, 0, 0, 0);
|
||||
db->nSqlExec--;
|
||||
if( rc ) goto abort_due_to_error;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: ParseSchema P1 * * P4 *
|
||||
**
|
||||
** Read and parse all entries from the SQLITE_MASTER table of database P1
|
||||
@@ -5650,7 +5611,7 @@ case OP_DropTrigger: {
|
||||
** register P1 the text of an error message describing any problems.
|
||||
** If no problems are found, store a NULL in register P1.
|
||||
**
|
||||
** The register P3 contains one less than the maximum number of allowed errors.
|
||||
** The register P3 contains the maximum number of allowed errors.
|
||||
** At most reg(P3) errors will be reported.
|
||||
** In other words, the analysis stops as soon as reg(P1) errors are
|
||||
** seen. Reg(P1) is updated with the number of errors remaining.
|
||||
@@ -5683,14 +5644,14 @@ case OP_IntegrityCk: {
|
||||
assert( pOp->p5<db->nDb );
|
||||
assert( DbMaskTest(p->btreeMask, pOp->p5) );
|
||||
z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot,
|
||||
(int)pnErr->u.i+1, &nErr);
|
||||
(int)pnErr->u.i, &nErr);
|
||||
pnErr->u.i -= nErr;
|
||||
sqlite3VdbeMemSetNull(pIn1);
|
||||
if( nErr==0 ){
|
||||
assert( z==0 );
|
||||
}else if( z==0 ){
|
||||
goto no_mem;
|
||||
}else{
|
||||
pnErr->u.i -= nErr-1;
|
||||
sqlite3VdbeMemSetStr(pIn1, z, -1, SQLITE_UTF8, sqlite3_free);
|
||||
}
|
||||
UPDATE_MAX_BLOBSIZE(pIn1);
|
||||
|
||||
+6
-8
@@ -154,8 +154,7 @@ int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
|
||||
sqlite3VdbeMemRelease(&p->aVar[i]);
|
||||
p->aVar[i].flags = MEM_Null;
|
||||
}
|
||||
assert( p->isPrepareV2 || p->expmask==0 );
|
||||
if( p->expmask ){
|
||||
if( p->isPrepareV2 && p->expmask ){
|
||||
p->expired = 1;
|
||||
}
|
||||
sqlite3_mutex_leave(mutex);
|
||||
@@ -1259,8 +1258,9 @@ static int vdbeUnbind(Vdbe *p, int i){
|
||||
** as if there had been a schema change, on the first sqlite3_step() call
|
||||
** following any change to the bindings of that parameter.
|
||||
*/
|
||||
assert( p->isPrepareV2 || p->expmask==0 );
|
||||
if( p->expmask!=0 && (p->expmask & (i>=31 ? 0x80000000 : (u32)1<<i))!=0 ){
|
||||
if( p->isPrepareV2 &&
|
||||
((i<32 && p->expmask & ((u32)1 << i)) || p->expmask==0xffffffff)
|
||||
){
|
||||
p->expired = 1;
|
||||
}
|
||||
return SQLITE_OK;
|
||||
@@ -1523,12 +1523,10 @@ int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){
|
||||
if( pFrom->nVar!=pTo->nVar ){
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
assert( pTo->isPrepareV2 || pTo->expmask==0 );
|
||||
if( pTo->expmask ){
|
||||
if( pTo->isPrepareV2 && pTo->expmask ){
|
||||
pTo->expired = 1;
|
||||
}
|
||||
assert( pFrom->isPrepareV2 || pFrom->expmask==0 );
|
||||
if( pFrom->expmask ){
|
||||
if( pFrom->isPrepareV2 && pFrom->expmask ){
|
||||
pFrom->expired = 1;
|
||||
}
|
||||
return sqlite3TransferBindings(pFromStmt, pToStmt);
|
||||
|
||||
+7
-9
@@ -57,7 +57,6 @@ void sqlite3VdbeError(Vdbe *p, const char *zFormat, ...){
|
||||
void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, int isPrepareV2){
|
||||
assert( isPrepareV2==1 || isPrepareV2==0 );
|
||||
if( p==0 ) return;
|
||||
if( !isPrepareV2 ) p->expmask = 0;
|
||||
#if defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_ENABLE_SQLLOG)
|
||||
if( !isPrepareV2 ) return;
|
||||
#endif
|
||||
@@ -86,7 +85,6 @@ void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){
|
||||
pA->zSql = pB->zSql;
|
||||
pB->zSql = zTmp;
|
||||
pB->isPrepareV2 = pA->isPrepareV2;
|
||||
pB->expmask = pA->expmask;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2611,13 +2609,13 @@ int sqlite3VdbeHalt(Vdbe *p){
|
||||
** one, or the complete transaction if there is no statement transaction.
|
||||
*/
|
||||
|
||||
if( p->magic!=VDBE_MAGIC_RUN ){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
if( db->mallocFailed ){
|
||||
p->rc = SQLITE_NOMEM_BKPT;
|
||||
}
|
||||
closeAllCursors(p);
|
||||
if( p->magic!=VDBE_MAGIC_RUN ){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
checkActiveVdbeCnt(db);
|
||||
|
||||
/* No commit or rollback needed if the program never started or if the
|
||||
@@ -3564,7 +3562,7 @@ void sqlite3VdbeRecordUnpack(
|
||||
p->nField = u;
|
||||
}
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
#if SQLITE_DEBUG
|
||||
/*
|
||||
** This function compares two index or table record keys in the same way
|
||||
** as the sqlite3VdbeRecordCompare() routine. Unlike VdbeRecordCompare(),
|
||||
@@ -3669,7 +3667,7 @@ debugCompareEnd:
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
#if SQLITE_DEBUG
|
||||
/*
|
||||
** Count the number of fields (a.k.a. columns) in the record given by
|
||||
** pKey,nKey. The verify that this count is less than or equal to the
|
||||
@@ -4552,8 +4550,8 @@ sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff){
|
||||
*/
|
||||
void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){
|
||||
assert( iVar>0 );
|
||||
if( iVar>=32 ){
|
||||
v->expmask |= 0x80000000;
|
||||
if( iVar>32 ){
|
||||
v->expmask = 0xffffffff;
|
||||
}else{
|
||||
v->expmask |= ((u32)1 << (iVar-1));
|
||||
}
|
||||
|
||||
+46
-32
@@ -23,7 +23,7 @@
|
||||
*/
|
||||
typedef struct Incrblob Incrblob;
|
||||
struct Incrblob {
|
||||
int nByte; /* Size of open blob, in bytes */
|
||||
int nByte; /* Size of open blob if ACTIVE. -1 if RESET */
|
||||
int iOffset; /* Byte offset of blob in cursor data */
|
||||
u16 iCol; /* Table column this handle is open on */
|
||||
BtCursor *pCsr; /* Cursor pointing at blob row */
|
||||
@@ -33,7 +33,6 @@ struct Incrblob {
|
||||
Table *pTab; /* Table object */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
** This function is used by both blob_open() and blob_reopen(). It seeks
|
||||
** the b-tree cursor associated with blob handle p to point to row iRow.
|
||||
@@ -82,8 +81,8 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){
|
||||
type==0?"null": type==7?"real": "integer"
|
||||
);
|
||||
rc = SQLITE_ERROR;
|
||||
sqlite3_finalize(p->pStmt);
|
||||
p->pStmt = 0;
|
||||
sqlite3_reset(p->pStmt);
|
||||
p->nByte = -1;
|
||||
}else{
|
||||
p->iOffset = pC->aType[p->iCol + pC->nField];
|
||||
p->nByte = sqlite3VdbeSerialTypeLen(type);
|
||||
@@ -94,9 +93,9 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){
|
||||
|
||||
if( rc==SQLITE_ROW ){
|
||||
rc = SQLITE_OK;
|
||||
}else if( p->pStmt ){
|
||||
rc = sqlite3_finalize(p->pStmt);
|
||||
p->pStmt = 0;
|
||||
}else if( p->nByte>=0 ){
|
||||
rc = sqlite3_reset(p->pStmt);
|
||||
p->nByte = -1;
|
||||
if( rc==SQLITE_OK ){
|
||||
zErr = sqlite3MPrintf(p->db, "no such rowid: %lld", iRow);
|
||||
rc = SQLITE_ERROR;
|
||||
@@ -157,6 +156,7 @@ int sqlite3_blob_open(
|
||||
pParse->db = db;
|
||||
sqlite3DbFree(db, zErr);
|
||||
zErr = 0;
|
||||
sqlite3_finalize(pBlob->pStmt);
|
||||
|
||||
sqlite3BtreeEnterAll(db);
|
||||
pTab = sqlite3LocateTable(pParse, 0, zTable, zDb);
|
||||
@@ -324,6 +324,7 @@ int sqlite3_blob_open(
|
||||
|
||||
pBlob->iCol = iCol;
|
||||
pBlob->db = db;
|
||||
pBlob->nByte = 0;
|
||||
sqlite3BtreeLeaveAll(db);
|
||||
if( db->mallocFailed ){
|
||||
goto blob_open_out;
|
||||
@@ -359,7 +360,7 @@ int sqlite3_blob_close(sqlite3_blob *pBlob){
|
||||
if( p ){
|
||||
db = p->db;
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
rc = sqlite3_finalize(p->pStmt);
|
||||
rc = sqlite3VdbeFinalize((Vdbe*)p->pStmt);
|
||||
sqlite3DbFree(db, p);
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
}else{
|
||||
@@ -384,6 +385,10 @@ static int blobReadWrite(
|
||||
sqlite3 *db;
|
||||
|
||||
if( p==0 ) return SQLITE_MISUSE_BKPT;
|
||||
if( p->nByte<0 ){
|
||||
/* The blob handle is in the RESET state. Always return SQLITE_ABORT. */
|
||||
return SQLITE_ABORT;
|
||||
}
|
||||
db = p->db;
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
v = (Vdbe*)p->pStmt;
|
||||
@@ -391,11 +396,6 @@ static int blobReadWrite(
|
||||
if( n<0 || iOffset<0 || ((sqlite3_int64)iOffset+n)>p->nByte ){
|
||||
/* Request is out of range. Return a transient error. */
|
||||
rc = SQLITE_ERROR;
|
||||
}else if( v==0 ){
|
||||
/* If there is no statement handle, then the blob-handle has
|
||||
** already been invalidated. Return SQLITE_ABORT in this case.
|
||||
*/
|
||||
rc = SQLITE_ABORT;
|
||||
}else{
|
||||
/* Call either BtreeData() or BtreePutData(). If SQLITE_ABORT is
|
||||
** returned, clean-up the statement handle.
|
||||
@@ -429,8 +429,8 @@ static int blobReadWrite(
|
||||
rc = xCall(p->pCsr, iOffset+p->iOffset, n, z);
|
||||
sqlite3BtreeLeaveCursor(p->pCsr);
|
||||
if( rc==SQLITE_ABORT ){
|
||||
sqlite3VdbeFinalize(v);
|
||||
p->pStmt = 0;
|
||||
sqlite3_reset(p->pStmt);
|
||||
p->nByte = -1;
|
||||
}else{
|
||||
v->rc = rc;
|
||||
}
|
||||
@@ -458,14 +458,36 @@ int sqlite3_blob_write(sqlite3_blob *pBlob, const void *z, int n, int iOffset){
|
||||
/*
|
||||
** Query a blob handle for the size of the data.
|
||||
**
|
||||
** The Incrblob.nByte field is fixed for the lifetime of the Incrblob
|
||||
** so no mutex is required for access.
|
||||
** The Incrblob.nByte field is fixed for as long as the sqlite3_blob
|
||||
** object is pointing to the same row, so no mutex is required for access.
|
||||
**
|
||||
** When the sqlite3_blob interface was first designed in 2007, we specified
|
||||
** that sqlite3_blob_bytes() returned 0 when in the RESET state. It would
|
||||
** have been better to return -1 in order to distinguish a RESET blob handle
|
||||
** from an ACTIVE blob handle pointing to a zero-length string or blob.
|
||||
** But, sadly, we cannot change that now without breaking compatibility.
|
||||
** So 0 is returned for RESET blob handles and for ACTIVE blob handles
|
||||
** pointing to zero-length blobs.
|
||||
*/
|
||||
int sqlite3_blob_bytes(sqlite3_blob *pBlob){
|
||||
Incrblob *p = (Incrblob *)pBlob;
|
||||
return (p && p->pStmt) ? p->nByte : 0;
|
||||
return (p && p->pStmt && p->nByte>0) ? p->nByte : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Move the sqlite3_blob object to the RESET state. This releases
|
||||
** any locks and gets the object out of the way of commits and
|
||||
** rollbacks.
|
||||
*/
|
||||
int sqlite3_blob_reset(sqlite3_blob *pBlob){
|
||||
Incrblob *p = (Incrblob *)pBlob;
|
||||
if( p->nByte>=0 ){
|
||||
sqlite3_reset(p->pStmt);
|
||||
p->nByte = -1;
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Move an existing blob handle to point to a different row of the same
|
||||
** database table.
|
||||
@@ -480,28 +502,20 @@ int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){
|
||||
int rc;
|
||||
Incrblob *p = (Incrblob *)pBlob;
|
||||
sqlite3 *db;
|
||||
char *zErr;
|
||||
|
||||
if( p==0 ) return SQLITE_MISUSE_BKPT;
|
||||
db = p->db;
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
|
||||
if( p->pStmt==0 ){
|
||||
/* If there is no statement handle, then the blob-handle has
|
||||
** already been invalidated. Return SQLITE_ABORT in this case.
|
||||
*/
|
||||
rc = SQLITE_ABORT;
|
||||
}else{
|
||||
char *zErr;
|
||||
rc = blobSeekToRow(p, iRow, &zErr);
|
||||
if( rc!=SQLITE_OK ){
|
||||
sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr);
|
||||
sqlite3DbFree(db, zErr);
|
||||
}
|
||||
assert( rc!=SQLITE_SCHEMA );
|
||||
rc = blobSeekToRow(p, iRow, &zErr);
|
||||
if( rc!=SQLITE_OK ){
|
||||
sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr);
|
||||
sqlite3DbFree(db, zErr);
|
||||
}
|
||||
|
||||
rc = sqlite3ApiExit(db, rc);
|
||||
assert( rc==SQLITE_OK || p->pStmt==0 );
|
||||
assert( rc==SQLITE_OK || p->nByte<0 );
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
+10
-8
@@ -339,7 +339,8 @@ void sqlite3VtabBeginParse(
|
||||
iDb = sqlite3SchemaToIndex(db, pTable->pSchema);
|
||||
assert( iDb>=0 );
|
||||
|
||||
assert( pTable->nModuleArg==0 );
|
||||
pTable->tabFlags |= TF_Virtual;
|
||||
pTable->nModuleArg = 0;
|
||||
addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName));
|
||||
addModuleArgument(db, pTable, 0);
|
||||
addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName));
|
||||
@@ -627,7 +628,7 @@ int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){
|
||||
int rc;
|
||||
|
||||
assert( pTab );
|
||||
if( !IsVirtual(pTab) || sqlite3GetVTable(db, pTab) ){
|
||||
if( (pTab->tabFlags & TF_Virtual)==0 || sqlite3GetVTable(db, pTab) ){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
@@ -697,7 +698,7 @@ int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){
|
||||
const char *zMod;
|
||||
|
||||
pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName);
|
||||
assert( pTab && IsVirtual(pTab) && !pTab->pVTable );
|
||||
assert( pTab && (pTab->tabFlags & TF_Virtual)!=0 && !pTab->pVTable );
|
||||
|
||||
/* Locate the required virtual table module */
|
||||
zMod = pTab->azModuleArg[0];
|
||||
@@ -751,7 +752,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
|
||||
return SQLITE_MISUSE_BKPT;
|
||||
}
|
||||
pTab = pCtx->pTab;
|
||||
assert( IsVirtual(pTab) );
|
||||
assert( (pTab->tabFlags & TF_Virtual)!=0 );
|
||||
|
||||
pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
|
||||
if( pParse==0 ){
|
||||
@@ -765,7 +766,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
|
||||
&& pParse->pNewTable
|
||||
&& !db->mallocFailed
|
||||
&& !pParse->pNewTable->pSelect
|
||||
&& !IsVirtual(pParse->pNewTable)
|
||||
&& (pParse->pNewTable->tabFlags & TF_Virtual)==0
|
||||
){
|
||||
if( !pTab->aCol ){
|
||||
Table *pNew = pParse->pNewTable;
|
||||
@@ -1054,7 +1055,7 @@ FuncDef *sqlite3VtabOverloadFunction(
|
||||
if( pExpr->op!=TK_COLUMN ) return pDef;
|
||||
pTab = pExpr->pTab;
|
||||
if( NEVER(pTab==0) ) return pDef;
|
||||
if( !IsVirtual(pTab) ) return pDef;
|
||||
if( (pTab->tabFlags & TF_Virtual)==0 ) return pDef;
|
||||
pVtab = sqlite3GetVTable(db, pTab)->pVtab;
|
||||
assert( pVtab!=0 );
|
||||
assert( pVtab->pModule!=0 );
|
||||
@@ -1149,7 +1150,8 @@ int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){
|
||||
pMod->pEpoTab = pTab;
|
||||
pTab->nTabRef = 1;
|
||||
pTab->pSchema = db->aDb[0].pSchema;
|
||||
assert( pTab->nModuleArg==0 );
|
||||
pTab->tabFlags |= TF_Virtual;
|
||||
pTab->nModuleArg = 0;
|
||||
pTab->iPKey = -1;
|
||||
addModuleArgument(db, pTab, sqlite3DbStrDup(db, pTab->zName));
|
||||
addModuleArgument(db, pTab, 0);
|
||||
@@ -1220,7 +1222,7 @@ int sqlite3_vtab_config(sqlite3 *db, int op, ...){
|
||||
if( !p ){
|
||||
rc = SQLITE_MISUSE_BKPT;
|
||||
}else{
|
||||
assert( p->pTab==0 || IsVirtual(p->pTab) );
|
||||
assert( p->pTab==0 || (p->pTab->tabFlags & TF_Virtual)!=0 );
|
||||
p->pVTable->bConstraint = (u8)va_arg(ap, int);
|
||||
}
|
||||
break;
|
||||
|
||||
+2
-2
@@ -27,11 +27,11 @@
|
||||
**
|
||||
** WRC_Continue Continue descending down the tree.
|
||||
**
|
||||
** WRC_Prune Do not descend into child nodes, but allow
|
||||
** WRC_Prune Do not descend into child nodes. But allow
|
||||
** the walk to continue with sibling nodes.
|
||||
**
|
||||
** WRC_Abort Do no more callbacks. Unwind the stack and
|
||||
** return from the top-level walk call.
|
||||
** return the top-level walk call.
|
||||
**
|
||||
** The return value from this routine is WRC_Abort to abandon the tree walk
|
||||
** and WRC_Continue to continue.
|
||||
|
||||
+9
-24
@@ -209,8 +209,7 @@ static WhereTerm *whereScanNext(WhereScan *pScan){
|
||||
if( pTerm->leftCursor==iCur
|
||||
&& pTerm->u.leftColumn==iColumn
|
||||
&& (iColumn!=XN_EXPR
|
||||
|| sqlite3ExprCompareSkip(pTerm->pExpr->pLeft,
|
||||
pScan->pIdxExpr,iCur)==0)
|
||||
|| sqlite3ExprCompare(pTerm->pExpr->pLeft,pScan->pIdxExpr,iCur)==0)
|
||||
&& (pScan->iEquiv<=1 || !ExprHasProperty(pTerm->pExpr, EP_FromJoin))
|
||||
){
|
||||
if( (pTerm->eOperator & WO_EQUIV)!=0
|
||||
@@ -309,7 +308,6 @@ static WhereTerm *whereScanInit(
|
||||
iColumn = pIdx->aiColumn[j];
|
||||
if( iColumn==XN_EXPR ){
|
||||
pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr;
|
||||
pScan->zCollName = pIdx->azColl[j];
|
||||
}else if( iColumn==pIdx->pTable->iPKey ){
|
||||
iColumn = XN_ROWID;
|
||||
}else if( iColumn>=0 ){
|
||||
@@ -2387,11 +2385,6 @@ static int whereLoopAddBtreeIndex(
|
||||
continue;
|
||||
}
|
||||
|
||||
if( IsUniqueIndex(pProbe) && saved_nEq==pProbe->nKeyCol-1 ){
|
||||
pBuilder->bldFlags |= SQLITE_BLDF_UNIQUE;
|
||||
}else{
|
||||
pBuilder->bldFlags |= SQLITE_BLDF_INDEXED;
|
||||
}
|
||||
pNew->wsFlags = saved_wsFlags;
|
||||
pNew->u.btree.nEq = saved_nEq;
|
||||
pNew->u.btree.nBtm = saved_nBtm;
|
||||
@@ -2939,15 +2932,7 @@ static int whereLoopAddBtree(
|
||||
}
|
||||
}
|
||||
|
||||
pBuilder->bldFlags = 0;
|
||||
rc = whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, 0);
|
||||
if( pBuilder->bldFlags==SQLITE_BLDF_INDEXED ){
|
||||
/* If a non-unique index is used, or if a prefix of the key for
|
||||
** unique index is used (making the index functionally non-unique)
|
||||
** then the sqlite_stat1 data becomes important for scoring the
|
||||
** plan */
|
||||
pTab->tabFlags |= TF_StatsUsed;
|
||||
}
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
sqlite3Stat4ProbeFree(pBuilder->pRec);
|
||||
pBuilder->nRecValid = 0;
|
||||
@@ -4127,9 +4112,9 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
|
||||
&& nRowEst
|
||||
){
|
||||
Bitmask notUsed;
|
||||
int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pResultSet, pFrom,
|
||||
int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pDistinctSet, pFrom,
|
||||
WHERE_DISTINCTBY, nLoop-1, pFrom->aLoop[nLoop-1], ¬Used);
|
||||
if( rc==pWInfo->pResultSet->nExpr ){
|
||||
if( rc==pWInfo->pDistinctSet->nExpr ){
|
||||
pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
|
||||
}
|
||||
}
|
||||
@@ -4366,7 +4351,7 @@ WhereInfo *sqlite3WhereBegin(
|
||||
SrcList *pTabList, /* FROM clause: A list of all tables to be scanned */
|
||||
Expr *pWhere, /* The WHERE clause */
|
||||
ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */
|
||||
ExprList *pResultSet, /* Query result set. Req'd for DISTINCT */
|
||||
ExprList *pDistinctSet, /* Try not to output two rows that duplicate these */
|
||||
u16 wctrlFlags, /* The WHERE_* flags defined in sqliteInt.h */
|
||||
int iAuxArg /* If WHERE_OR_SUBCLAUSE is set, index cursor number
|
||||
** If WHERE_USE_LIMIT, then the limit amount */
|
||||
@@ -4442,7 +4427,7 @@ WhereInfo *sqlite3WhereBegin(
|
||||
pWInfo->pParse = pParse;
|
||||
pWInfo->pTabList = pTabList;
|
||||
pWInfo->pOrderBy = pOrderBy;
|
||||
pWInfo->pResultSet = pResultSet;
|
||||
pWInfo->pDistinctSet = pDistinctSet;
|
||||
pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1;
|
||||
pWInfo->nLevel = nTabList;
|
||||
pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(v);
|
||||
@@ -4520,13 +4505,13 @@ WhereInfo *sqlite3WhereBegin(
|
||||
if( db->mallocFailed ) goto whereBeginError;
|
||||
|
||||
if( wctrlFlags & WHERE_WANT_DISTINCT ){
|
||||
if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pResultSet) ){
|
||||
if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pDistinctSet) ){
|
||||
/* The DISTINCT marking is pointless. Ignore it. */
|
||||
pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
|
||||
}else if( pOrderBy==0 ){
|
||||
/* Try to ORDER BY the result set to make distinct processing easier */
|
||||
pWInfo->wctrlFlags |= WHERE_DISTINCTBY;
|
||||
pWInfo->pOrderBy = pResultSet;
|
||||
pWInfo->pOrderBy = pDistinctSet;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4602,10 +4587,10 @@ WhereInfo *sqlite3WhereBegin(
|
||||
#endif
|
||||
/* Attempt to omit tables from the join that do not effect the result */
|
||||
if( pWInfo->nLevel>=2
|
||||
&& pResultSet!=0
|
||||
&& pDistinctSet!=0
|
||||
&& OptimizationEnabled(db, SQLITE_OmitNoopJoin)
|
||||
){
|
||||
Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pResultSet);
|
||||
Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pDistinctSet);
|
||||
if( sWLB.pOrderBy ){
|
||||
tabUsed |= sqlite3WhereExprListUsage(pMaskSet, sWLB.pOrderBy);
|
||||
}
|
||||
|
||||
+1
-6
@@ -395,13 +395,8 @@ struct WhereLoopBuilder {
|
||||
UnpackedRecord *pRec; /* Probe for stat4 (if required) */
|
||||
int nRecValid; /* Number of valid fields currently in pRec */
|
||||
#endif
|
||||
unsigned int bldFlags; /* SQLITE_BLDF_* flags */
|
||||
};
|
||||
|
||||
/* Allowed values for WhereLoopBuider.bldFlags */
|
||||
#define SQLITE_BLDF_INDEXED 0x0001 /* An index is used */
|
||||
#define SQLITE_BLDF_UNIQUE 0x0002 /* All keys of a UNIQUE index used */
|
||||
|
||||
/*
|
||||
** The WHERE clause processing routine has two halves. The
|
||||
** first part does the start of the WHERE loop and the second
|
||||
@@ -416,7 +411,7 @@ struct WhereInfo {
|
||||
Parse *pParse; /* Parsing and code generating context */
|
||||
SrcList *pTabList; /* List of tables in the join */
|
||||
ExprList *pOrderBy; /* The ORDER BY clause or NULL */
|
||||
ExprList *pResultSet; /* Result set of the query */
|
||||
ExprList *pDistinctSet; /* DISTINCT over all these values */
|
||||
LogEst iLimit; /* LIMIT if wctrlFlags has WHERE_USE_LIMIT */
|
||||
int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */
|
||||
int iContinue; /* Jump here to continue with next record */
|
||||
|
||||
+2
-8
@@ -1062,7 +1062,6 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
Vdbe *v; /* The prepared stmt under constructions */
|
||||
struct SrcList_item *pTabItem; /* FROM clause term being coded */
|
||||
int addrBrk; /* Jump here to break out of the loop */
|
||||
int addrHalt; /* addrBrk for the outermost loop */
|
||||
int addrCont; /* Jump here to continue with next cycle */
|
||||
int iRowidReg = 0; /* Rowid is stored in this register, if not zero */
|
||||
int iReleaseReg = 0; /* Temp register to free before returning */
|
||||
@@ -1104,11 +1103,6 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
VdbeComment((v, "init LEFT JOIN no-match flag"));
|
||||
}
|
||||
|
||||
/* Compute a safe address to jump to if we discover that the table for
|
||||
** this loop is empty and can never contribute content. */
|
||||
for(j=iLevel; j>0 && pWInfo->a[j].iLeftJoin==0; j--){}
|
||||
addrHalt = pWInfo->a[j].addrBrk;
|
||||
|
||||
/* Special case of a FROM clause subquery implemented as a co-routine */
|
||||
if( pTabItem->fg.viaCoroutine ){
|
||||
int regYield = pTabItem->regReturn;
|
||||
@@ -1293,7 +1287,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
sqlite3ExprCacheAffinityChange(pParse, r1, 1);
|
||||
sqlite3ReleaseTempReg(pParse, rTemp);
|
||||
}else{
|
||||
sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrHalt);
|
||||
sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrBrk);
|
||||
VdbeCoverageIf(v, bRev==0);
|
||||
VdbeCoverageIf(v, bRev!=0);
|
||||
}
|
||||
@@ -1939,7 +1933,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
codeCursorHint(pTabItem, pWInfo, pLevel, 0);
|
||||
pLevel->op = aStep[bRev];
|
||||
pLevel->p1 = iCur;
|
||||
pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrHalt);
|
||||
pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk);
|
||||
VdbeCoverageIf(v, bRev==0);
|
||||
VdbeCoverageIf(v, bRev!=0);
|
||||
pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
|
||||
|
||||
+10
-18
@@ -213,6 +213,15 @@ static int isLikeOrGlob(
|
||||
#endif
|
||||
pList = pExpr->x.pList;
|
||||
pLeft = pList->a[1].pExpr;
|
||||
if( pLeft->op!=TK_COLUMN
|
||||
|| sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
|
||||
|| IsVirtual(pLeft->pTab) /* Value might be numeric */
|
||||
){
|
||||
/* IMP: R-02065-49465 The left-hand side of the LIKE or GLOB operator must
|
||||
** be the name of an indexed column with TEXT affinity. */
|
||||
return 0;
|
||||
}
|
||||
assert( pLeft->iColumn!=(-1) ); /* Because IPK never has AFF_TEXT */
|
||||
|
||||
pRight = sqlite3ExprSkipCollate(pList->a[0].pExpr);
|
||||
op = pRight->op;
|
||||
@@ -229,23 +238,6 @@ static int isLikeOrGlob(
|
||||
z = pRight->u.zToken;
|
||||
}
|
||||
if( z ){
|
||||
|
||||
/* If the RHS begins with a digit or a minus sign, then the LHS must
|
||||
** be an ordinary column (not a virtual table column) with TEXT affinity.
|
||||
** Otherwise the LHS might be numeric and "lhs >= rhs" would be false
|
||||
** even though "lhs LIKE rhs" is true. But if the RHS does not start
|
||||
** with a digit or '-', then "lhs LIKE rhs" will always be false if
|
||||
** the LHS is numeric and so the optimization still works.
|
||||
*/
|
||||
if( sqlite3Isdigit(z[0]) || z[0]=='-' ){
|
||||
if( pLeft->op!=TK_COLUMN
|
||||
|| sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
|
||||
|| IsVirtual(pLeft->pTab) /* Value might be numeric */
|
||||
){
|
||||
sqlite3ValueFree(pVal);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
cnt = 0;
|
||||
while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){
|
||||
cnt++;
|
||||
@@ -874,7 +866,7 @@ static int exprMightBeIndexed(
|
||||
if( pIdx->aColExpr==0 ) continue;
|
||||
for(i=0; i<pIdx->nKeyCol; i++){
|
||||
if( pIdx->aiColumn[i]!=XN_EXPR ) continue;
|
||||
if( sqlite3ExprCompareSkip(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){
|
||||
if( sqlite3ExprCompare(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){
|
||||
*piCur = iCur;
|
||||
*piColumn = XN_EXPR;
|
||||
return 1;
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
# 2017-02-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 file implements tests for the logic used to estimate when
|
||||
# running ANALYZE would be beneficial.
|
||||
#
|
||||
# Note that this test uses some hard-coded bitmask values from sqliteInt.h.
|
||||
# If any of the following constants changes:
|
||||
#
|
||||
# define TF_HasStat1 0x0010
|
||||
# define TF_StatsUsed 0x0100
|
||||
#
|
||||
# then some of the magic numbers in test results below might need to be
|
||||
# adjusted.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
# There is nothing to test if ANALYZE is disable for this build.
|
||||
# These tests also use "PRAGMA stats" which are only enabled for
|
||||
# debugging builds.
|
||||
#
|
||||
ifcapable {!debug || !analyze} {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
do_execsql_test autoanalyze1-100 {
|
||||
-- Build up a test table with some indexes
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d);
|
||||
CREATE UNIQUE INDEX t1bc ON t1(b,c);
|
||||
CREATE INDEX t1d ON t1(d);
|
||||
WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100)
|
||||
INSERT INTO t1(a,b,c,d) SELECT x, x, x, x FROM c;
|
||||
-- Verify that the hasStat1 flag is clear on on indexes
|
||||
SELECT idx, flgs FROM pragma_stats
|
||||
WHERE idx IS NOT NULL
|
||||
ORDER BY idx;
|
||||
-- Verify that the TF_HasStat1 flag is clear on the table
|
||||
SELECT tbl, (flgs & 0x10)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL;
|
||||
} {t1bc 0 t1d 0 t1 0}
|
||||
|
||||
# No use of stat1 recorded so far
|
||||
do_execsql_test autoanalyze1-110 {
|
||||
SELECT (flgs & 0x0100)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL;
|
||||
} {0}
|
||||
|
||||
# Access using a unique index does not set the TF_StatsUsed flag.
|
||||
#
|
||||
do_execsql_test autoanalyze1-200 {
|
||||
SELECT * FROM t1 WHERE a=55;
|
||||
} {55 55 55 55}
|
||||
do_execsql_test autoanalyze1-201 {
|
||||
SELECT (flgs & 0x0100)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL;
|
||||
} {0}
|
||||
|
||||
do_execsql_test autoanalyze1-210 {
|
||||
SELECT * FROM t1 WHERE a IN (55,199,299);
|
||||
} {55 55 55 55}
|
||||
do_execsql_test autoanalyze1-211 {
|
||||
SELECT (flgs & 0x0100)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL;
|
||||
} {0}
|
||||
|
||||
do_execsql_test autoanalyze1-220 {
|
||||
SELECT * FROM t1 WHERE (b,c)=(45,45);
|
||||
} {45 45 45 45}
|
||||
do_execsql_test autoanalyze1-221 {
|
||||
SELECT (flgs & 0x0100)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL;
|
||||
} {0}
|
||||
|
||||
# Any use of the non-unique t1d index triggers the use of stats.
|
||||
#
|
||||
sqlite3 db test.db
|
||||
do_execsql_test autoanalyze1-300 {
|
||||
SELECT * FROM t1 WHERE d=45;
|
||||
} {45 45 45 45}
|
||||
do_execsql_test autoanalyze1-301 {
|
||||
SELECT (flgs & 0x0100)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL;
|
||||
} {1}
|
||||
|
||||
sqlite3 db test.db
|
||||
do_execsql_test autoanalyze1-310 {
|
||||
SELECT * FROM t1 WHERE d=45 AND a=45;
|
||||
} {45 45 45 45}
|
||||
do_execsql_test autoanalyze1-311 {
|
||||
SELECT (flgs & 0x0100)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL;
|
||||
} {0} ;# The ROWID lookup short-circuits the d=45 constraint
|
||||
|
||||
sqlite3 db test.db
|
||||
do_execsql_test autoanalyze1-320 {
|
||||
SELECT * FROM t1 WHERE d=45 AND a IN (45,46);
|
||||
} {45 45 45 45}
|
||||
do_execsql_test autoanalyze1-321 {
|
||||
SELECT (flgs & 0x0100)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL;
|
||||
} {1}
|
||||
|
||||
# Any use of prefix of a unique index triggers the use of stats
|
||||
#
|
||||
sqlite3 db test.db
|
||||
do_execsql_test autoanalyze1-400 {
|
||||
SELECT * FROM t1 WHERE b=45;
|
||||
} {45 45 45 45}
|
||||
do_execsql_test autoanalyze1-401 {
|
||||
SELECT (flgs & 0x0100)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL;
|
||||
} {1}
|
||||
|
||||
# The TF_StatsUsed flag is reset when the database is reopened
|
||||
#
|
||||
sqlite3 db test.db
|
||||
do_execsql_test autoanalyze1-500 {
|
||||
SELECT (flgs & 0x0100)!=0 FROM pragma_stats WHERE tbl='t1' AND idx IS NULL;
|
||||
} {0}
|
||||
|
||||
finish_test
|
||||
+2
-6
@@ -309,15 +309,11 @@ do_test check-4.8 {
|
||||
PRAGMA ignore_check_constraints=ON;
|
||||
UPDATE t4 SET x=0, y=1;
|
||||
SELECT * FROM t4;
|
||||
PRAGMA integrity_check;
|
||||
}
|
||||
} {0 1 ok}
|
||||
do_execsql_test check-4.8.1 {
|
||||
PRAGMA ignore_check_constraints=OFF;
|
||||
PRAGMA integrity_check;
|
||||
} {{CHECK constraint failed in t4}}
|
||||
} {0 1}
|
||||
do_test check-4.9 {
|
||||
catchsql {
|
||||
PRAGMA ignore_check_constraints=OFF;
|
||||
UPDATE t4 SET x=0, y=2;
|
||||
}
|
||||
} {1 {CHECK constraint failed: t4}}
|
||||
|
||||
+1
-1
@@ -164,7 +164,7 @@ do_test corruptC-2.5 {
|
||||
catchsql {BEGIN; UPDATE t2 SET y='abcdef-uvwxyz'; ROLLBACK;}
|
||||
catchsql {PRAGMA integrity_check}
|
||||
} {0 {{*** in database main ***
|
||||
On tree page 4 cell 19: Extends off end of page}}}
|
||||
Page 4: btreeInitPage() returns error code 11}}}
|
||||
|
||||
# {0 {{*** in database main ***
|
||||
# Corruption detected in cell 710 on page 4
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
# 2017-03-03
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix corruptK
|
||||
|
||||
if {[permutation]=="mmap"} {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
# This module uses hard-coded offsets which do not work if the reserved_bytes
|
||||
# value is nonzero.
|
||||
if {[nonzero_reserved_bytes]} {finish_test; return;}
|
||||
database_may_be_corrupt
|
||||
|
||||
# Initialize the database.
|
||||
#
|
||||
do_execsql_test 1.1 {
|
||||
PRAGMA page_size=1024;
|
||||
PRAGMA auto_vacuum=0;
|
||||
CREATE TABLE t1(x);
|
||||
|
||||
INSERT INTO t1 VALUES(randomblob(20));
|
||||
INSERT INTO t1 VALUES(randomblob(100)); -- make this into a free slot
|
||||
INSERT INTO t1 VALUES(randomblob(27)); -- this one will be corrupt
|
||||
INSERT INTO t1 VALUES(randomblob(800));
|
||||
|
||||
DELETE FROM t1 WHERE rowid=2; -- free the 100 byte slot
|
||||
PRAGMA page_count
|
||||
} {2}
|
||||
|
||||
|
||||
# Corrupt the database so that the blob stored immediately before
|
||||
# the free slot (rowid==3) has an overlarge length field. So that
|
||||
# we can use sqlite3_blob_write() to manipulate the size field of
|
||||
# the free slot.
|
||||
#
|
||||
# Then use sqlite3_blob_write() to set the size of said free slot
|
||||
# to 24 bytes (instead of the actual 100).
|
||||
#
|
||||
# Then use the new 24 byte slot. Leaving the in-memory version of
|
||||
# the page with zero free slots and a large nFree value. Then try
|
||||
# to allocate another slot to get to defragmentPage().
|
||||
#
|
||||
do_test 1.2 {
|
||||
db close
|
||||
hexio_write test.db [expr 1024 + 0x360] 21
|
||||
hexio_write test.db [expr 1024 + 0x363] [format %x [expr 31*2 + 12]]
|
||||
sqlite3 db test.db
|
||||
|
||||
set fd [db incrblob t1 x 3]
|
||||
fconfigure $fd -translation binary -encoding binary
|
||||
seek $fd 30
|
||||
puts -nonewline $fd "\x18"
|
||||
close $fd
|
||||
} {}
|
||||
do_execsql_test 1.3 {
|
||||
INSERT INTO t1 VALUES(randomblob(20));
|
||||
}
|
||||
do_catchsql_test 1.4 {
|
||||
INSERT INTO t1 VALUES(randomblob(90));
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 2.1 {
|
||||
PRAGMA page_size=1024;
|
||||
PRAGMA auto_vacuum=0;
|
||||
CREATE TABLE t1(x);
|
||||
|
||||
INSERT INTO t1 VALUES(randomblob(20));
|
||||
INSERT INTO t1 VALUES(randomblob(20)); -- free this one
|
||||
INSERT INTO t1 VALUES(randomblob(20));
|
||||
INSERT INTO t1 VALUES(randomblob(20)); -- and this one
|
||||
INSERT INTO t1 VALUES(randomblob(20)); -- corrupt this one.
|
||||
|
||||
DELETE FROM t1 WHERE rowid IN(2, 4);
|
||||
PRAGMA page_count
|
||||
} {2}
|
||||
|
||||
do_test 2.2 {
|
||||
db close
|
||||
hexio_write test.db [expr 1024 + 0x388] 53
|
||||
hexio_write test.db [expr 1024 + 0x38A] 03812C
|
||||
|
||||
sqlite3 db test.db
|
||||
set fd [db incrblob t1 x 5]
|
||||
fconfigure $fd -translation binary -encoding binary
|
||||
|
||||
seek $fd 22
|
||||
puts -nonewline $fd "\x5d"
|
||||
close $fd
|
||||
} {}
|
||||
|
||||
do_catchsql_test 2.3 {
|
||||
INSERT INTO t1 VALUES(randomblob(900));
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
|
||||
|
||||
|
||||
finish_test
|
||||
@@ -596,17 +596,5 @@ datetest 16.29 {datetime(5373484,'-176546 months')} NULL
|
||||
datetest 16.30 {datetime(5373484,'-14712 years')} {-4713-12-31 12:00:00}
|
||||
datetest 16.31 {datetime(5373484,'-14713 years')} NULL
|
||||
|
||||
# 2017-03-02: Wrong 'start of day' computation.
|
||||
# https://www.sqlite.org/src/info/6097cb92745327a1
|
||||
#
|
||||
datetest 17.1 {datetime(2457754, 'start of day')} {2016-12-31 00:00:00}
|
||||
datetest 17.2 {datetime(2457828)} {2017-03-15 12:00:00}
|
||||
datetest 17.3 {datetime(2457828,'start of day')} {2017-03-15 00:00:00}
|
||||
datetest 17.4 {datetime(2457828,'start of month')} {2017-03-01 00:00:00}
|
||||
datetest 17.5 {datetime(2457828,'start of year')} {2017-01-01 00:00:00}
|
||||
datetest 17.6 {datetime(37,'start of year')} NULL
|
||||
datetest 17.7 {datetime(38,'start of year')} {-4712-01-01 00:00:00}
|
||||
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
+4
-4
@@ -458,7 +458,7 @@ static void StrAppend(Str *p, const char *z){
|
||||
sqlite3_uint64 nNew;
|
||||
if( p->oomErr ) return;
|
||||
nNew = p->nAlloc*2 + 100 + n;
|
||||
zNew = sqlite3_realloc64(p->z, nNew);
|
||||
zNew = sqlite3_realloc(p->z, nNew);
|
||||
if( zNew==0 ){
|
||||
sqlite3_free(p->z);
|
||||
memset(p, 0, sizeof(*p));
|
||||
@@ -468,7 +468,7 @@ static void StrAppend(Str *p, const char *z){
|
||||
p->z = zNew;
|
||||
p->nAlloc = nNew;
|
||||
}
|
||||
memcpy(p->z + p->n, z, (int)n);
|
||||
memcpy(p->z + p->n, z, n);
|
||||
p->n += n;
|
||||
p->z[p->n] = 0;
|
||||
}
|
||||
@@ -647,7 +647,7 @@ static void runSql(sqlite3 *db, const char *zSql, unsigned runFlags){
|
||||
int main(int argc, char **argv){
|
||||
int i; /* Loop counter */
|
||||
int nDb = 0; /* Number of databases to fuzz */
|
||||
char **azDb = 0; /* Names of the databases (limit: 20) */
|
||||
const char **azDb = 0; /* Names of the databases (limit: 20) */
|
||||
int verboseFlag = 0; /* True for extra output */
|
||||
int noLookaside = 0; /* Disable lookaside if true */
|
||||
int vdbeLimitFlag = 0; /* Stop after 100,000 VDBE ops */
|
||||
@@ -660,7 +660,7 @@ int main(int argc, char **argv){
|
||||
unsigned runFlags = 0; /* Flags passed to runSql */
|
||||
|
||||
for(i=1; i<argc; i++){
|
||||
char *z = argv[i];
|
||||
const char *z = argv[i];
|
||||
if( z[0]!='-' ){
|
||||
azDb = realloc(azDb, sizeof(azDb[0])*(nDb+1));
|
||||
if( azDb==0 ) fatalError("out of memory");
|
||||
|
||||
@@ -141,8 +141,8 @@ do_test 2.3.2 {
|
||||
execsql { SELECT 1, 2, 3 }
|
||||
sqlite3_errcode db
|
||||
} {SQLITE_OK}
|
||||
blob_write_error_test 2.3.3 $B 5 $blob 5 \
|
||||
SQLITE_ABORT {callback requested query abort}
|
||||
#blob_write_error_test 2.3.3 $B 5 $blob 5 \
|
||||
# SQLITE_OK {not an error}
|
||||
sqlite3_blob_close $B
|
||||
|
||||
# EVIDENCE-OF: R-08382-59936 Writes to the BLOB that occurred before the
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
# 2017-02-15
|
||||
#
|
||||
# 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 to show that a join involving an empty table is very fast.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
# Build some test data
|
||||
#
|
||||
do_execsql_test emptytable-100 {
|
||||
CREATE TABLE t1(a);
|
||||
WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100)
|
||||
INSERT INTO t1(a) SELECT x FROM c;
|
||||
CREATE TABLE empty(x);
|
||||
SELECT count(*) FROM t1;
|
||||
} {100}
|
||||
|
||||
# Interrupt queries after 1M cycles to prevent burning excess CPU
|
||||
proc stopDb {args} {
|
||||
db interrupt
|
||||
}
|
||||
db progress 1000000 {stopDb}
|
||||
|
||||
# Prior to the query planner optimization on 2017-02-15, this query would
|
||||
# take a ridiculous amount of time. If that optimization stops working,
|
||||
# the result here will be in interrupt for running too long.
|
||||
#
|
||||
do_catchsql_test emptytable-110 {
|
||||
SELECT count(*) FROM t1, t1, t1, t1, t1, t1, empty;
|
||||
} {0 0}
|
||||
|
||||
do_catchsql_test emptytable-120 {
|
||||
SELECT count(*) FROM t1, t1 LEFT JOIN empty;
|
||||
} {0 10000}
|
||||
do_catchsql_test emptytable-121 {
|
||||
SELECT count(*) FROM t1, t1 LEFT JOIN t1, empty;
|
||||
} {0 0}
|
||||
|
||||
|
||||
finish_test
|
||||
@@ -1,73 +0,0 @@
|
||||
# 2017 Feb 27
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# Tests of the last_insert_rowid functionality with fts4.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source [file join [file dirname [info script]] tester.tcl]
|
||||
set testprefix fts4lastrowid
|
||||
|
||||
ifcapable !fts3 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts4(str);
|
||||
}
|
||||
|
||||
do_execsql_test 1.1 {
|
||||
INSERT INTO t1 VALUES('one string');
|
||||
INSERT INTO t1 VALUES('two string');
|
||||
INSERT INTO t1 VALUES('three string');
|
||||
SELECT last_insert_rowid();
|
||||
} {3}
|
||||
|
||||
do_execsql_test 1.2 {
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES('one string');
|
||||
INSERT INTO t1 VALUES('two string');
|
||||
INSERT INTO t1 VALUES('three string');
|
||||
COMMIT;
|
||||
SELECT last_insert_rowid();
|
||||
} {6}
|
||||
|
||||
do_execsql_test 1.3 {
|
||||
INSERT INTO t1(rowid, str) VALUES(-22, 'some more text');
|
||||
SELECT last_insert_rowid();
|
||||
} {-22}
|
||||
|
||||
do_execsql_test 1.4 {
|
||||
BEGIN;
|
||||
INSERT INTO t1(rowid, str) VALUES(45, 'some more text');
|
||||
INSERT INTO t1(rowid, str) VALUES(46, 'some more text');
|
||||
INSERT INTO t1(rowid, str) VALUES(222, 'some more text');
|
||||
SELECT last_insert_rowid();
|
||||
COMMIT;
|
||||
SELECT last_insert_rowid();
|
||||
} {222 222}
|
||||
|
||||
do_execsql_test 1.5 {
|
||||
CREATE TABLE x1(x);
|
||||
INSERT INTO x1 VALUES('john'), ('paul'), ('george'), ('ringo');
|
||||
INSERT INTO t1 SELECT x FROM x1;
|
||||
SELECT last_insert_rowid();
|
||||
} {226}
|
||||
|
||||
do_execsql_test 1.6 {
|
||||
INSERT INTO t1(rowid, str) SELECT rowid+10, x FROM x1;
|
||||
SELECT last_insert_rowid();
|
||||
} {14}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
+9
-6
@@ -62,7 +62,7 @@ do_test incrblob3-2.1.2 {
|
||||
} {SQLITE_ERROR {no such rowid: 3}}
|
||||
do_test incrblob3-2.1.3 {
|
||||
list [catch {sqlite3_blob_reopen $::blob 1} msg] $msg
|
||||
} {1 SQLITE_ABORT}
|
||||
} {0 {}}
|
||||
do_test incrblob3-2.1.4 { close $::blob } {}
|
||||
|
||||
do_execsql_test incrblob3-2.2.1 {
|
||||
@@ -85,18 +85,21 @@ foreach {tn rowid type} {
|
||||
|
||||
do_test incrblob3-2.2.$tn.3 {
|
||||
list [catch {sqlite3_blob_reopen $::blob 1} msg] $msg
|
||||
} {1 SQLITE_ABORT}
|
||||
} {0 {}}
|
||||
do_test incrblob3-2.2.$tn.4 {
|
||||
list [catch {sqlite3_blob_read $::blob 0 10} msg] $msg
|
||||
} {1 SQLITE_ABORT}
|
||||
} {0 {hello worl}}
|
||||
do_test incrblob3-2.2.$tn.5 {
|
||||
list [catch {sqlite3_blob_write $::blob 0 "abcd"} msg] $msg
|
||||
} {1 SQLITE_ABORT}
|
||||
} {0 {}}
|
||||
do_test incrblob3-2.2.$tn.6 {
|
||||
sqlite3_blob_bytes $::blob
|
||||
} {0}
|
||||
} {100}
|
||||
do_test incrblob3-2.2.$tn.7 {
|
||||
list [catch {sqlite3_blob_write $::blob 0 "hello"} msg] $msg
|
||||
} {0 {}}
|
||||
|
||||
do_test incrblob3-2.2.$tn.7 { close $::blob } {}
|
||||
do_test incrblob3-2.2.$tn.8 { close $::blob } {}
|
||||
}
|
||||
|
||||
# Test that passing NULL to sqlite3_blob_XXX() APIs returns SQLITE_MISUSE.
|
||||
|
||||
@@ -52,7 +52,7 @@ do_faultsim_test 2 -prep {
|
||||
error [sqlite3_errmsg db]
|
||||
}
|
||||
} -test {
|
||||
faultsim_test_result {1 {no such rowid: -1}} {1 {disk I/O error}}
|
||||
faultsim_test_result {1 {no such rowid: -1}}
|
||||
close $::blob
|
||||
}
|
||||
|
||||
|
||||
@@ -370,14 +370,4 @@ do_execsql_test indexexpr1-1200.4 {
|
||||
0 0 0 2 0 4 2 0 2 2 4 0
|
||||
}
|
||||
|
||||
# Ticket https://www.sqlite.org/src/tktview/eb703ba7b50c1a
|
||||
# Incorrect result using an index on an expression with a collating function
|
||||
#
|
||||
do_execsql_test indexexpr1-1300.1 {
|
||||
CREATE TABLE t1300(a INTEGER PRIMARY KEY, b);
|
||||
INSERT INTO t1300 VALUES(1,'coffee'),(2,'COFFEE'),(3,'stress'),(4,'STRESS');
|
||||
CREATE INDEX t1300bexpr ON t1300( substr(b,4) );
|
||||
SELECT a FROM t1300 WHERE substr(b,4)='ess' COLLATE nocase ORDER BY +a;
|
||||
} {3 4}
|
||||
|
||||
finish_test
|
||||
|
||||
+3
-3
@@ -310,7 +310,7 @@ static int initMain(int argc, char **argv){
|
||||
"WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<%d)"
|
||||
" INSERT INTO kv(k,v) SELECT x, randomblob(%d+(random()%%(%d))) FROM c;\n"
|
||||
"COMMIT;\n",
|
||||
pgsz, nCount, sz, iVariance+1
|
||||
pgsz, nCount, sz, iVariance
|
||||
);
|
||||
rc = sqlite3_exec(db, zSql, 0, 0, &zErrMsg);
|
||||
if( rc ) fatalError("database create failed: %s", zErrMsg);
|
||||
@@ -473,13 +473,13 @@ static unsigned char *readFile(const char *zName, int *pnByte){
|
||||
if( in==0 ) return 0;
|
||||
pBuf = sqlite3_malloc64( nIn );
|
||||
if( pBuf==0 ) return 0;
|
||||
nRead = fread(pBuf, (size_t)nIn, 1, in);
|
||||
nRead = fread(pBuf, nIn, 1, in);
|
||||
fclose(in);
|
||||
if( nRead!=1 ){
|
||||
sqlite3_free(pBuf);
|
||||
return 0;
|
||||
}
|
||||
if( pnByte ) *pnByte = (int)nIn;
|
||||
if( pnByte ) *pnByte = nIn;
|
||||
return pBuf;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -236,12 +236,12 @@ do_test malloc5-4.2 {
|
||||
db eval {PRAGMA cache_size=1}
|
||||
db cache flush
|
||||
sqlite3_release_memory
|
||||
sqlite3_soft_heap_limit 200000
|
||||
sqlite3_soft_heap_limit 100000
|
||||
sqlite3_memory_highwater 1
|
||||
execsql {SELECT * FROM abc}
|
||||
set nMaxBytes [sqlite3_memory_highwater 1]
|
||||
puts -nonewline " (Highwater mark: $nMaxBytes) "
|
||||
expr $nMaxBytes <= 210000
|
||||
expr $nMaxBytes <= 110000
|
||||
} {1}
|
||||
do_test malloc5-4.3 {
|
||||
# Check that the content of table abc is at least roughly as expected.
|
||||
|
||||
+11
-30
@@ -6,33 +6,12 @@
|
||||
#include <stdint.h>
|
||||
#include "sqlite3.h"
|
||||
|
||||
/* Return the current real-world time in milliseconds since the
|
||||
** Julian epoch (-4714-11-24).
|
||||
*/
|
||||
static sqlite3_int64 timeOfDay(void){
|
||||
static sqlite3_vfs *clockVfs = 0;
|
||||
sqlite3_int64 t;
|
||||
if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
|
||||
if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){
|
||||
clockVfs->xCurrentTimeInt64(clockVfs, &t);
|
||||
}else{
|
||||
double r;
|
||||
clockVfs->xCurrentTime(clockVfs, &r);
|
||||
t = (sqlite3_int64)(r*86400000.0);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
|
||||
/*
|
||||
** Progress handler callback.
|
||||
**
|
||||
** The argument is the cutoff-time after which all processing should
|
||||
** stop. So return non-zero if the cut-off time is exceeded.
|
||||
** Progress handler callback
|
||||
*/
|
||||
static int progress_handler(void *pReturn) {
|
||||
sqlite3_int64 iCutoffTime = *(sqlite3_int64*)pReturn;
|
||||
return timeOfDay()>=iCutoffTime;
|
||||
return *(int*)pReturn;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -52,13 +31,13 @@ static int exec_handler(void *pCnt, int argc, char **argv, char **namev){
|
||||
** fuzzed input.
|
||||
*/
|
||||
int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
int progressArg = 0; /* 1 causes progress handler abort */
|
||||
int execCnt = 0; /* Abort row callback when count reaches zero */
|
||||
char *zErrMsg = 0; /* Error message returned by sqlite_exec() */
|
||||
sqlite3 *db; /* The database connection */
|
||||
uint8_t uSelector; /* First byte of input data[] */
|
||||
int rc; /* Return code from various interfaces */
|
||||
char *zSql; /* Zero-terminated copy of data[] */
|
||||
sqlite3_int64 iCutoff; /* Cutoff timer */
|
||||
|
||||
if( size<3 ) return 0; /* Early out if unsufficient data */
|
||||
|
||||
@@ -77,14 +56,16 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
if( rc ) return 0;
|
||||
|
||||
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
|
||||
/* Invoke the progress handler every 500 thousand instructions (approximately
|
||||
** 20 to 40 times per second) to check to see if we are taking too long.
|
||||
*/
|
||||
iCutoff = timeOfDay() + 10000; /* Now + 10 seconds */
|
||||
sqlite3_progress_handler(db, 500000, progress_handler, (void*)&iCutoff);
|
||||
/* Bit 0 of the selector enables progress callbacks. Bit 1 is the
|
||||
** return code from progress callbacks */
|
||||
if( uSelector & 1 ){
|
||||
sqlite3_progress_handler(db, 4, progress_handler, (void*)&progressArg);
|
||||
}
|
||||
#endif
|
||||
uSelector >>= 1;
|
||||
progressArg = uSelector & 1; uSelector >>= 1;
|
||||
|
||||
/* Bit 1 of the selector enables foreign key constraints */
|
||||
/* Bit 2 of the selector enables foreign key constraints */
|
||||
sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_FKEY, uSelector&1, &rc);
|
||||
uSelector >>= 1;
|
||||
|
||||
|
||||
@@ -754,10 +754,6 @@ test_suite "inmemory_journal" -description {
|
||||
|
||||
# This test assumes a journal file is created on disk.
|
||||
delete_db.test
|
||||
|
||||
# This test depends on a successful recovery from the pager error
|
||||
# state. Which is not possible with an in-memory journal
|
||||
fts5fault1.test
|
||||
}]
|
||||
|
||||
ifcapable mem3 {
|
||||
|
||||
@@ -116,37 +116,6 @@ do_execsql_test printf2-3.5 {
|
||||
SELECT printf('|%7.8c|%-7.8c|','*','*');
|
||||
} {|********|********|}
|
||||
|
||||
# The "," separator
|
||||
do_execsql_test printf2-4.1 {
|
||||
SELECT printf('|%,d|%,d|',0,-1);
|
||||
} {|0|-1|}
|
||||
do_execsql_test printf2-4.2 {
|
||||
SELECT printf('|%,d|%,d|',12,-12);
|
||||
} {|12|-12|}
|
||||
do_execsql_test printf2-4.3 {
|
||||
SELECT printf('|%,d|%,d|',123,-123);
|
||||
} {|123|-123|}
|
||||
do_execsql_test printf2-4.4 {
|
||||
SELECT printf('|%,d|%,d|',1234,-1234);
|
||||
} {|1,234|-1,234|}
|
||||
do_execsql_test printf2-4.5 {
|
||||
SELECT printf('|%,d|%,d|',12345,-12345);
|
||||
} {|12,345|-12,345|}
|
||||
do_execsql_test printf2-4.6 {
|
||||
SELECT printf('|%,d|%,d|',123456,-123456);
|
||||
} {|123,456|-123,456|}
|
||||
do_execsql_test printf2-4.7 {
|
||||
SELECT printf('|%,d|%,d|',1234567,-1234567);
|
||||
} {|1,234,567|-1,234,567|}
|
||||
do_execsql_test printf2-4.8 {
|
||||
SELECT printf('|%,d|%,d|',12345678,-12345678);
|
||||
} {|12,345,678|-12,345,678|}
|
||||
do_execsql_test printf2-4.9 {
|
||||
SELECT printf('|%,d|%,d|',123456789,-123456789);
|
||||
} {|123,456,789|-123,456,789|}
|
||||
do_execsql_test printf2-4.10 {
|
||||
SELECT printf('|%,d|%,d|',1234567890,-1234567890);
|
||||
} {|1,234,567,890|-1,234,567,890|}
|
||||
|
||||
|
||||
|
||||
|
||||
+13
-126
@@ -300,7 +300,7 @@ do_test shell1-3.4.2 {
|
||||
do_test shell1-3.4.3 {
|
||||
# too many arguments
|
||||
catchcmd "test.db" ".dump FOO BAD"
|
||||
} {1 {Usage: .dump ?--preserve-rowids? ?LIKE-PATTERN?}}
|
||||
} {1 {Usage: .dump ?LIKE-PATTERN?}}
|
||||
|
||||
# .echo ON|OFF Turn command echo on or off
|
||||
do_test shell1-3.5.1 {
|
||||
@@ -740,132 +740,19 @@ do_test shell1-4.1 {
|
||||
} {0 {PRAGMA foreign_keys=OFF;
|
||||
BEGIN TRANSACTION;
|
||||
CREATE TABLE t1(x);
|
||||
INSERT INTO t1 VALUES(NULL);
|
||||
INSERT INTO t1 VALUES('');
|
||||
INSERT INTO t1 VALUES(1);
|
||||
INSERT INTO t1 VALUES(2.25);
|
||||
INSERT INTO t1 VALUES('hello');
|
||||
INSERT INTO t1 VALUES(X'807f');
|
||||
INSERT INTO "t1" VALUES(NULL);
|
||||
INSERT INTO "t1" VALUES('');
|
||||
INSERT INTO "t1" VALUES(1);
|
||||
INSERT INTO "t1" VALUES(2.25);
|
||||
INSERT INTO "t1" VALUES('hello');
|
||||
INSERT INTO "t1" VALUES(X'807F');
|
||||
CREATE TABLE t3(x,y);
|
||||
INSERT INTO t3 VALUES(1,NULL);
|
||||
INSERT INTO t3 VALUES(2,'');
|
||||
INSERT INTO t3 VALUES(3,1);
|
||||
INSERT INTO t3 VALUES(4,2.25);
|
||||
INSERT INTO t3 VALUES(5,'hello');
|
||||
INSERT INTO t3 VALUES(6,X'807f');
|
||||
COMMIT;}}
|
||||
|
||||
# The --preserve-rowids option to .dump
|
||||
#
|
||||
do_test shell1-4.1.1 {
|
||||
catchcmd test.db {.dump --preserve-rowids}
|
||||
} {0 {PRAGMA foreign_keys=OFF;
|
||||
BEGIN TRANSACTION;
|
||||
CREATE TABLE t1(x);
|
||||
INSERT INTO t1(rowid,x) VALUES(1,NULL);
|
||||
INSERT INTO t1(rowid,x) VALUES(2,'');
|
||||
INSERT INTO t1(rowid,x) VALUES(3,1);
|
||||
INSERT INTO t1(rowid,x) VALUES(4,2.25);
|
||||
INSERT INTO t1(rowid,x) VALUES(5,'hello');
|
||||
INSERT INTO t1(rowid,x) VALUES(6,X'807f');
|
||||
CREATE TABLE t3(x,y);
|
||||
INSERT INTO t3(rowid,x,y) VALUES(1,1,NULL);
|
||||
INSERT INTO t3(rowid,x,y) VALUES(2,2,'');
|
||||
INSERT INTO t3(rowid,x,y) VALUES(3,3,1);
|
||||
INSERT INTO t3(rowid,x,y) VALUES(4,4,2.25);
|
||||
INSERT INTO t3(rowid,x,y) VALUES(5,5,'hello');
|
||||
INSERT INTO t3(rowid,x,y) VALUES(6,6,X'807f');
|
||||
COMMIT;}}
|
||||
|
||||
# If the table contains an INTEGER PRIMARY KEY, do not record a separate
|
||||
# rowid column in the output.
|
||||
#
|
||||
do_test shell1-4.1.2 {
|
||||
db close
|
||||
forcedelete test2.db
|
||||
sqlite3 db test2.db
|
||||
db eval {
|
||||
CREATE TABLE t1(x INTEGER PRIMARY KEY, y);
|
||||
INSERT INTO t1 VALUES(1,null), (2,''), (3,1),
|
||||
(4,2.25), (5,'hello'), (6,x'807f');
|
||||
}
|
||||
catchcmd test2.db {.dump --preserve-rowids}
|
||||
} {0 {PRAGMA foreign_keys=OFF;
|
||||
BEGIN TRANSACTION;
|
||||
CREATE TABLE t1(x INTEGER PRIMARY KEY, y);
|
||||
INSERT INTO t1 VALUES(1,NULL);
|
||||
INSERT INTO t1 VALUES(2,'');
|
||||
INSERT INTO t1 VALUES(3,1);
|
||||
INSERT INTO t1 VALUES(4,2.25);
|
||||
INSERT INTO t1 VALUES(5,'hello');
|
||||
INSERT INTO t1 VALUES(6,X'807f');
|
||||
COMMIT;}}
|
||||
|
||||
# Verify that the table named [table] is correctly quoted and that
|
||||
# an INTEGER PRIMARY KEY DESC is not an alias for the rowid.
|
||||
#
|
||||
do_test shell1-4.1.3 {
|
||||
db close
|
||||
forcedelete test2.db
|
||||
sqlite3 db test2.db
|
||||
db eval {
|
||||
CREATE TABLE [table](x INTEGER PRIMARY KEY DESC, y);
|
||||
INSERT INTO [table] VALUES(1,null), (12,''), (23,1),
|
||||
(34,2.25), (45,'hello'), (56,x'807f');
|
||||
}
|
||||
catchcmd test2.db {.dump --preserve-rowids}
|
||||
} {0 {PRAGMA foreign_keys=OFF;
|
||||
BEGIN TRANSACTION;
|
||||
CREATE TABLE [table](x INTEGER PRIMARY KEY DESC, y);
|
||||
INSERT INTO "table"(rowid,x,y) VALUES(1,1,NULL);
|
||||
INSERT INTO "table"(rowid,x,y) VALUES(2,12,'');
|
||||
INSERT INTO "table"(rowid,x,y) VALUES(3,23,1);
|
||||
INSERT INTO "table"(rowid,x,y) VALUES(4,34,2.25);
|
||||
INSERT INTO "table"(rowid,x,y) VALUES(5,45,'hello');
|
||||
INSERT INTO "table"(rowid,x,y) VALUES(6,56,X'807f');
|
||||
COMMIT;}}
|
||||
|
||||
# Do not record rowids for a WITHOUT ROWID table. Also check correct quoting
|
||||
# of table names that contain odd characters.
|
||||
#
|
||||
do_test shell1-4.1.4 {
|
||||
db close
|
||||
forcedelete test2.db
|
||||
sqlite3 db test2.db
|
||||
db eval {
|
||||
CREATE TABLE [ta<>ble](x INTEGER PRIMARY KEY, y) WITHOUT ROWID;
|
||||
INSERT INTO [ta<>ble] VALUES(1,null), (12,''), (23,1),
|
||||
(34,2.25), (45,'hello'), (56,x'807f');
|
||||
}
|
||||
catchcmd test2.db {.dump --preserve-rowids}
|
||||
} {0 {PRAGMA foreign_keys=OFF;
|
||||
BEGIN TRANSACTION;
|
||||
CREATE TABLE [ta<>ble](x INTEGER PRIMARY KEY, y) WITHOUT ROWID;
|
||||
INSERT INTO "ta<>ble" VALUES(1,NULL);
|
||||
INSERT INTO "ta<>ble" VALUES(12,'');
|
||||
INSERT INTO "ta<>ble" VALUES(23,1);
|
||||
INSERT INTO "ta<>ble" VALUES(34,2.25);
|
||||
INSERT INTO "ta<>ble" VALUES(45,'hello');
|
||||
INSERT INTO "ta<>ble" VALUES(56,X'807f');
|
||||
COMMIT;}}
|
||||
|
||||
# Do not record rowids if the rowid is inaccessible
|
||||
#
|
||||
do_test shell1-4.1.5 {
|
||||
db close
|
||||
forcedelete test2.db
|
||||
sqlite3 db test2.db
|
||||
db eval {
|
||||
CREATE TABLE t1(_ROWID_,rowid,oid);
|
||||
INSERT INTO t1 VALUES(1,null,'alpha'), (12,'',99), (23,1,x'b0b1b2');
|
||||
}
|
||||
catchcmd test2.db {.dump --preserve-rowids}
|
||||
} {0 {PRAGMA foreign_keys=OFF;
|
||||
BEGIN TRANSACTION;
|
||||
CREATE TABLE t1(_ROWID_,rowid,oid);
|
||||
INSERT INTO t1 VALUES(1,NULL,'alpha');
|
||||
INSERT INTO t1 VALUES(12,'',99);
|
||||
INSERT INTO t1 VALUES(23,1,X'b0b1b2');
|
||||
INSERT INTO "t3" VALUES(1,NULL);
|
||||
INSERT INTO "t3" VALUES(2,'');
|
||||
INSERT INTO "t3" VALUES(3,1);
|
||||
INSERT INTO "t3" VALUES(4,2.25);
|
||||
INSERT INTO "t3" VALUES(5,'hello');
|
||||
INSERT INTO "t3" VALUES(6,X'807F');
|
||||
COMMIT;}}
|
||||
|
||||
# Test the output of ".mode insert"
|
||||
|
||||
+1
-272
@@ -33,7 +33,7 @@ static const char zHelp[] =
|
||||
" --size N Relative test size. Default=100\n"
|
||||
" --stats Show statistics at the end\n"
|
||||
" --temp N N from 0 to 9. 0: no temp table. 9: all temp tables\n"
|
||||
" --testset T Run test-set T (main, cte, rtree, orm, debug)\n"
|
||||
" --testset T Run test-set T\n"
|
||||
" --trace Turn on SQL tracing\n"
|
||||
" --threads N Use up to N threads for sorting\n"
|
||||
" --utf16be Set text encoding to UTF-16BE\n"
|
||||
@@ -1307,275 +1307,6 @@ void testset_rtree(int p1, int p2){
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_RTREE */
|
||||
|
||||
/*
|
||||
** A testset that does key/value storage on tables with many columns.
|
||||
** This is the kind of workload generated by ORMs such as CoreData.
|
||||
*/
|
||||
void testset_orm(void){
|
||||
unsigned i, j, n;
|
||||
unsigned nRow;
|
||||
unsigned x1, len;
|
||||
char zNum[2000]; /* A number name */
|
||||
static const char zType[] = /* Types for all non-PK columns, in order */
|
||||
"IBBIIITIVVITBTBFBFITTFBTBVBVIFTBBFITFFVBIFIVBVVVBTVTIBBFFIVIBTB"
|
||||
"TVTTFTVTVFFIITIFBITFTTFFFVBIIBTTITFTFFVVVFIIITVBBVFFTVVB";
|
||||
|
||||
nRow = n = g.szTest*250;
|
||||
speedtest1_begin_test(100, "Fill %d rows", n);
|
||||
speedtest1_exec(
|
||||
"BEGIN;"
|
||||
"CREATE TABLE ZLOOKSLIKECOREDATA ("
|
||||
" ZPK INTEGER PRIMARY KEY,"
|
||||
" ZTERMFITTINGHOUSINGCOMMAND INTEGER,"
|
||||
" ZBRIEFGOBYDODGERHEIGHT BLOB,"
|
||||
" ZCAPABLETRIPDOORALMOND BLOB,"
|
||||
" ZDEPOSITPAIRCOLLEGECOMET INTEGER,"
|
||||
" ZFRAMEENTERSIMPLEMOUTH INTEGER,"
|
||||
" ZHOPEFULGATEHOLECHALK INTEGER,"
|
||||
" ZSLEEPYUSERGRANDBOWL TIMESTAMP,"
|
||||
" ZDEWPEACHCAREERCELERY INTEGER,"
|
||||
" ZHANGERLITHIUMDINNERMEET VARCHAR,"
|
||||
" ZCLUBRELEASELIZARDADVICE VARCHAR,"
|
||||
" ZCHARGECLICKHUMANEHIRE INTEGER,"
|
||||
" ZFINGERDUEPIZZAOPTION TIMESTAMP,"
|
||||
" ZFLYINGDOCTORTABLEMELODY BLOB,"
|
||||
" ZLONGFINLEAVEIMAGEOIL TIMESTAMP,"
|
||||
" ZFAMILYVISUALOWNERMATTER BLOB,"
|
||||
" ZGOLDYOUNGINITIALNOSE FLOAT,"
|
||||
" ZCAUSESALAMITERMCYAN BLOB,"
|
||||
" ZSPREADMOTORBISCUITBACON FLOAT,"
|
||||
" ZGIFTICEFISHGLUEHAIR INTEGER,"
|
||||
" ZNOTICEPEARPOLICYJUICE TIMESTAMP,"
|
||||
" ZBANKBUFFALORECOVERORBIT TIMESTAMP,"
|
||||
" ZLONGDIETESSAYNATURE FLOAT,"
|
||||
" ZACTIONRANGEELEGANTNEUTRON BLOB,"
|
||||
" ZCADETBRIGHTPLANETBANK TIMESTAMP,"
|
||||
" ZAIRFORGIVEHEADFROG BLOB,"
|
||||
" ZSHARKJUSTFRUITMOVIE VARCHAR,"
|
||||
" ZFARMERMORNINGMIRRORCONCERN BLOB,"
|
||||
" ZWOODPOETRYCOBBLERBENCH VARCHAR,"
|
||||
" ZHAFNIUMSCRIPTSALADMOTOR INTEGER,"
|
||||
" ZPROBLEMCLUBPOPOVERJELLY FLOAT,"
|
||||
" ZEIGHTLEADERWORKERMOST TIMESTAMP,"
|
||||
" ZGLASSRESERVEBARIUMMEAL BLOB,"
|
||||
" ZCLAMBITARUGULAFAJITA BLOB,"
|
||||
" ZDECADEJOYOUSWAVEHABIT FLOAT,"
|
||||
" ZCOMPANYSUMMERFIBERELF INTEGER,"
|
||||
" ZTREATTESTQUILLCHARGE TIMESTAMP,"
|
||||
" ZBROWBALANCEKEYCHOWDER FLOAT,"
|
||||
" ZPEACHCOPPERDINNERLAKE FLOAT,"
|
||||
" ZDRYWALLBEYONDBROWNBOWL VARCHAR,"
|
||||
" ZBELLYCRASHITEMLACK BLOB,"
|
||||
" ZTENNISCYCLEBILLOFFICER INTEGER,"
|
||||
" ZMALLEQUIPTHANKSGLUE FLOAT,"
|
||||
" ZMISSREPLYHUMANLIVING INTEGER,"
|
||||
" ZKIWIVISUALPRIDEAPPLE VARCHAR,"
|
||||
" ZWISHHITSKINMOTOR BLOB,"
|
||||
" ZCALMRACCOONPROGRAMDEBIT VARCHAR,"
|
||||
" ZSHINYASSISTLIVINGCRAB VARCHAR,"
|
||||
" ZRESOLVEWRISTWRAPAPPLE VARCHAR,"
|
||||
" ZAPPEALSIMPLESECONDHOUSING BLOB,"
|
||||
" ZCORNERANCHORTAPEDIVER TIMESTAMP,"
|
||||
" ZMEMORYREQUESTSOURCEBIG VARCHAR,"
|
||||
" ZTRYFACTKEEPMILK TIMESTAMP,"
|
||||
" ZDIVERPAINTLEATHEREASY INTEGER,"
|
||||
" ZSORTMISTYQUOTECABBAGE BLOB,"
|
||||
" ZTUNEGASBUFFALOCAPITAL BLOB,"
|
||||
" ZFILLSTOPLAWJOYFUL FLOAT,"
|
||||
" ZSTEELCAREFULPLATENUMBER FLOAT,"
|
||||
" ZGIVEVIVIDDIVINEMEANING INTEGER,"
|
||||
" ZTREATPACKFUTURECONVERT VARCHAR,"
|
||||
" ZCALMLYGEMFINISHEFFECT INTEGER,"
|
||||
" ZCABBAGESOCKEASEMINUTE BLOB,"
|
||||
" ZPLANETFAMILYPUREMEMORY TIMESTAMP,"
|
||||
" ZMERRYCRACKTRAINLEADER BLOB,"
|
||||
" ZMINORWAYPAPERCLASSY TIMESTAMP,"
|
||||
" ZEAGLELINEMINEMAIL VARCHAR,"
|
||||
" ZRESORTYARDGREENLET TIMESTAMP,"
|
||||
" ZYARDOREGANOVIVIDJEWEL TIMESTAMP,"
|
||||
" ZPURECAKEVIVIDNEATLY FLOAT,"
|
||||
" ZASKCONTACTMONITORFUN TIMESTAMP,"
|
||||
" ZMOVEWHOGAMMAINCH VARCHAR,"
|
||||
" ZLETTUCEBIRDMEETDEBATE TIMESTAMP,"
|
||||
" ZGENENATURALHEARINGKITE VARCHAR,"
|
||||
" ZMUFFINDRYERDRAWFORTUNE FLOAT,"
|
||||
" ZGRAYSURVEYWIRELOVE FLOAT,"
|
||||
" ZPLIERSPRINTASKOREGANO INTEGER,"
|
||||
" ZTRAVELDRIVERCONTESTLILY INTEGER,"
|
||||
" ZHUMORSPICESANDKIDNEY TIMESTAMP,"
|
||||
" ZARSENICSAMPLEWAITMUON INTEGER,"
|
||||
" ZLACEADDRESSGROUNDCAREFUL FLOAT,"
|
||||
" ZBAMBOOMESSWASABIEVENING BLOB,"
|
||||
" ZONERELEASEAVERAGENURSE INTEGER,"
|
||||
" ZRADIANTWHENTRYCARD TIMESTAMP,"
|
||||
" ZREWARDINSIDEMANGOINTENSE FLOAT,"
|
||||
" ZNEATSTEWPARTIRON TIMESTAMP,"
|
||||
" ZOUTSIDEPEAHENCOUNTICE TIMESTAMP,"
|
||||
" ZCREAMEVENINGLIPBRANCH FLOAT,"
|
||||
" ZWHALEMATHAVOCADOCOPPER FLOAT,"
|
||||
" ZLIFEUSELEAFYBELL FLOAT,"
|
||||
" ZWEALTHLINENGLEEFULDAY VARCHAR,"
|
||||
" ZFACEINVITETALKGOLD BLOB,"
|
||||
" ZWESTAMOUNTAFFECTHEARING INTEGER,"
|
||||
" ZDELAYOUTCOMEHORNAGENCY INTEGER,"
|
||||
" ZBIGTHINKCONVERTECONOMY BLOB,"
|
||||
" ZBASEGOUDAREGULARFORGIVE TIMESTAMP,"
|
||||
" ZPATTERNCLORINEGRANDCOLBY TIMESTAMP,"
|
||||
" ZCYANBASEFEEDADROIT INTEGER,"
|
||||
" ZCARRYFLOORMINNOWDRAGON TIMESTAMP,"
|
||||
" ZIMAGEPENCILOTHERBOTTOM FLOAT,"
|
||||
" ZXENONFLIGHTPALEAPPLE TIMESTAMP,"
|
||||
" ZHERRINGJOKEFEATUREHOPEFUL FLOAT,"
|
||||
" ZCAPYEARLYRIVETBRUSH FLOAT,"
|
||||
" ZAGEREEDFROGBASKET VARCHAR,"
|
||||
" ZUSUALBODYHALIBUTDIAMOND VARCHAR,"
|
||||
" ZFOOTTAPWORDENTRY VARCHAR,"
|
||||
" ZDISHKEEPBLESTMONITOR FLOAT,"
|
||||
" ZBROADABLESOLIDCASUAL INTEGER,"
|
||||
" ZSQUAREGLEEFULCHILDLIGHT INTEGER,"
|
||||
" ZHOLIDAYHEADPONYDETAIL INTEGER,"
|
||||
" ZGENERALRESORTSKYOPEN TIMESTAMP,"
|
||||
" ZGLADSPRAYKIDNEYGUPPY VARCHAR,"
|
||||
" ZSWIMHEAVYMENTIONKIND BLOB,"
|
||||
" ZMESSYSULFURDREAMFESTIVE BLOB,"
|
||||
" ZSKYSKYCLASSICBRIEF VARCHAR,"
|
||||
" ZDILLASKHOKILEMON FLOAT,"
|
||||
" ZJUNIORSHOWPRESSNOVA FLOAT,"
|
||||
" ZSIZETOEAWARDFRESH TIMESTAMP,"
|
||||
" ZKEYFAILAPRICOTMETAL VARCHAR,"
|
||||
" ZHANDYREPAIRPROTONAIRPORT VARCHAR,"
|
||||
" ZPOSTPROTEINHANDLEACTOR BLOB"
|
||||
");"
|
||||
);
|
||||
speedtest1_prepare(
|
||||
"INSERT INTO ZLOOKSLIKECOREDATA(ZPK,ZAIRFORGIVEHEADFROG,"
|
||||
"ZGIFTICEFISHGLUEHAIR,ZDELAYOUTCOMEHORNAGENCY,ZSLEEPYUSERGRANDBOWL,"
|
||||
"ZGLASSRESERVEBARIUMMEAL,ZBRIEFGOBYDODGERHEIGHT,"
|
||||
"ZBAMBOOMESSWASABIEVENING,ZFARMERMORNINGMIRRORCONCERN,"
|
||||
"ZTREATPACKFUTURECONVERT,ZCAUSESALAMITERMCYAN,ZCALMRACCOONPROGRAMDEBIT,"
|
||||
"ZHOLIDAYHEADPONYDETAIL,ZWOODPOETRYCOBBLERBENCH,ZHAFNIUMSCRIPTSALADMOTOR,"
|
||||
"ZUSUALBODYHALIBUTDIAMOND,ZOUTSIDEPEAHENCOUNTICE,ZDIVERPAINTLEATHEREASY,"
|
||||
"ZWESTAMOUNTAFFECTHEARING,ZSIZETOEAWARDFRESH,ZDEWPEACHCAREERCELERY,"
|
||||
"ZSTEELCAREFULPLATENUMBER,ZCYANBASEFEEDADROIT,ZCALMLYGEMFINISHEFFECT,"
|
||||
"ZHANDYREPAIRPROTONAIRPORT,ZGENENATURALHEARINGKITE,ZBROADABLESOLIDCASUAL,"
|
||||
"ZPOSTPROTEINHANDLEACTOR,ZLACEADDRESSGROUNDCAREFUL,ZIMAGEPENCILOTHERBOTTOM,"
|
||||
"ZPROBLEMCLUBPOPOVERJELLY,ZPATTERNCLORINEGRANDCOLBY,ZNEATSTEWPARTIRON,"
|
||||
"ZAPPEALSIMPLESECONDHOUSING,ZMOVEWHOGAMMAINCH,ZTENNISCYCLEBILLOFFICER,"
|
||||
"ZSHARKJUSTFRUITMOVIE,ZKEYFAILAPRICOTMETAL,ZCOMPANYSUMMERFIBERELF,"
|
||||
"ZTERMFITTINGHOUSINGCOMMAND,ZRESORTYARDGREENLET,ZCABBAGESOCKEASEMINUTE,"
|
||||
"ZSQUAREGLEEFULCHILDLIGHT,ZONERELEASEAVERAGENURSE,ZBIGTHINKCONVERTECONOMY,"
|
||||
"ZPLIERSPRINTASKOREGANO,ZDECADEJOYOUSWAVEHABIT,ZDRYWALLBEYONDBROWNBOWL,"
|
||||
"ZCLUBRELEASELIZARDADVICE,ZWHALEMATHAVOCADOCOPPER,ZBELLYCRASHITEMLACK,"
|
||||
"ZLETTUCEBIRDMEETDEBATE,ZCAPABLETRIPDOORALMOND,ZRADIANTWHENTRYCARD,"
|
||||
"ZCAPYEARLYRIVETBRUSH,ZAGEREEDFROGBASKET,ZSWIMHEAVYMENTIONKIND,"
|
||||
"ZTRAVELDRIVERCONTESTLILY,ZGLADSPRAYKIDNEYGUPPY,ZBANKBUFFALORECOVERORBIT,"
|
||||
"ZFINGERDUEPIZZAOPTION,ZCLAMBITARUGULAFAJITA,ZLONGFINLEAVEIMAGEOIL,"
|
||||
"ZLONGDIETESSAYNATURE,ZJUNIORSHOWPRESSNOVA,ZHOPEFULGATEHOLECHALK,"
|
||||
"ZDEPOSITPAIRCOLLEGECOMET,ZWEALTHLINENGLEEFULDAY,ZFILLSTOPLAWJOYFUL,"
|
||||
"ZTUNEGASBUFFALOCAPITAL,ZGRAYSURVEYWIRELOVE,ZCORNERANCHORTAPEDIVER,"
|
||||
"ZREWARDINSIDEMANGOINTENSE,ZCADETBRIGHTPLANETBANK,ZPLANETFAMILYPUREMEMORY,"
|
||||
"ZTREATTESTQUILLCHARGE,ZCREAMEVENINGLIPBRANCH,ZSKYSKYCLASSICBRIEF,"
|
||||
"ZARSENICSAMPLEWAITMUON,ZBROWBALANCEKEYCHOWDER,ZFLYINGDOCTORTABLEMELODY,"
|
||||
"ZHANGERLITHIUMDINNERMEET,ZNOTICEPEARPOLICYJUICE,ZSHINYASSISTLIVINGCRAB,"
|
||||
"ZLIFEUSELEAFYBELL,ZFACEINVITETALKGOLD,ZGENERALRESORTSKYOPEN,"
|
||||
"ZPURECAKEVIVIDNEATLY,ZKIWIVISUALPRIDEAPPLE,ZMESSYSULFURDREAMFESTIVE,"
|
||||
"ZCHARGECLICKHUMANEHIRE,ZHERRINGJOKEFEATUREHOPEFUL,ZYARDOREGANOVIVIDJEWEL,"
|
||||
"ZFOOTTAPWORDENTRY,ZWISHHITSKINMOTOR,ZBASEGOUDAREGULARFORGIVE,"
|
||||
"ZMUFFINDRYERDRAWFORTUNE,ZACTIONRANGEELEGANTNEUTRON,ZTRYFACTKEEPMILK,"
|
||||
"ZPEACHCOPPERDINNERLAKE,ZFRAMEENTERSIMPLEMOUTH,ZMERRYCRACKTRAINLEADER,"
|
||||
"ZMEMORYREQUESTSOURCEBIG,ZCARRYFLOORMINNOWDRAGON,ZMINORWAYPAPERCLASSY,"
|
||||
"ZDILLASKHOKILEMON,ZRESOLVEWRISTWRAPAPPLE,ZASKCONTACTMONITORFUN,"
|
||||
"ZGIVEVIVIDDIVINEMEANING,ZEIGHTLEADERWORKERMOST,ZMISSREPLYHUMANLIVING,"
|
||||
"ZXENONFLIGHTPALEAPPLE,ZSORTMISTYQUOTECABBAGE,ZEAGLELINEMINEMAIL,"
|
||||
"ZFAMILYVISUALOWNERMATTER,ZSPREADMOTORBISCUITBACON,ZDISHKEEPBLESTMONITOR,"
|
||||
"ZMALLEQUIPTHANKSGLUE,ZGOLDYOUNGINITIALNOSE,ZHUMORSPICESANDKIDNEY)"
|
||||
"VALUES(?1,?26,?20,?93,?8,?33,?3,?81,?28,?60,?18,?47,?109,?29,?30,?104,?86,"
|
||||
"?54,?92,?117,?9,?58,?97,?61,?119,?73,?107,?120,?80,?99,?31,?96,?85,?50,?71,"
|
||||
"?42,?27,?118,?36,?2,?67,?62,?108,?82,?94,?76,?35,?40,?11,?88,?41,?72,?4,"
|
||||
"?83,?102,?103,?112,?77,?111,?22,?13,?34,?15,?23,?116,?7,?5,?90,?57,?56,"
|
||||
"?75,?51,?84,?25,?63,?37,?87,?114,?79,?38,?14,?10,?21,?48,?89,?91,?110,"
|
||||
"?69,?45,?113,?12,?101,?68,?105,?46,?95,?74,?24,?53,?39,?6,?64,?52,?98,"
|
||||
"?65,?115,?49,?70,?59,?32,?44,?100,?55,?66,?16,?19,?106,?43,?17,?78);"
|
||||
);
|
||||
for(i=0; i<n; i++){
|
||||
x1 = speedtest1_random();
|
||||
speedtest1_numbername(x1%1000, zNum, sizeof(zNum));
|
||||
len = (int)strlen(zNum);
|
||||
sqlite3_bind_int(g.pStmt, 1, i^0xf);
|
||||
for(j=0; zType[j]; j++){
|
||||
switch( zType[j] ){
|
||||
case 'I':
|
||||
case 'T':
|
||||
sqlite3_bind_int64(g.pStmt, j+2, x1);
|
||||
break;
|
||||
case 'F':
|
||||
sqlite3_bind_double(g.pStmt, j+2, (double)x1);
|
||||
break;
|
||||
case 'V':
|
||||
case 'B':
|
||||
sqlite3_bind_text64(g.pStmt, j+2, zNum, len,
|
||||
SQLITE_STATIC, SQLITE_UTF8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
speedtest1_run();
|
||||
}
|
||||
speedtest1_exec("COMMIT;");
|
||||
speedtest1_end_test();
|
||||
|
||||
n = g.szTest*250;
|
||||
speedtest1_begin_test(110, "Query %d rows by rowid", n);
|
||||
speedtest1_prepare(
|
||||
"SELECT ZCYANBASEFEEDADROIT,ZJUNIORSHOWPRESSNOVA,ZCAUSESALAMITERMCYAN,"
|
||||
"ZHOPEFULGATEHOLECHALK,ZHUMORSPICESANDKIDNEY,ZSWIMHEAVYMENTIONKIND,"
|
||||
"ZMOVEWHOGAMMAINCH,ZAPPEALSIMPLESECONDHOUSING,ZHAFNIUMSCRIPTSALADMOTOR,"
|
||||
"ZNEATSTEWPARTIRON,ZLONGFINLEAVEIMAGEOIL,ZDEWPEACHCAREERCELERY,"
|
||||
"ZXENONFLIGHTPALEAPPLE,ZCALMRACCOONPROGRAMDEBIT,ZUSUALBODYHALIBUTDIAMOND,"
|
||||
"ZTRYFACTKEEPMILK,ZWEALTHLINENGLEEFULDAY,ZLONGDIETESSAYNATURE,"
|
||||
"ZLIFEUSELEAFYBELL,ZTREATPACKFUTURECONVERT,ZMEMORYREQUESTSOURCEBIG,"
|
||||
"ZYARDOREGANOVIVIDJEWEL,ZDEPOSITPAIRCOLLEGECOMET,ZSLEEPYUSERGRANDBOWL,"
|
||||
"ZBRIEFGOBYDODGERHEIGHT,ZCLUBRELEASELIZARDADVICE,ZCAPABLETRIPDOORALMOND,"
|
||||
"ZDRYWALLBEYONDBROWNBOWL,ZASKCONTACTMONITORFUN,ZKIWIVISUALPRIDEAPPLE,"
|
||||
"ZNOTICEPEARPOLICYJUICE,ZPEACHCOPPERDINNERLAKE,ZSTEELCAREFULPLATENUMBER,"
|
||||
"ZGLADSPRAYKIDNEYGUPPY,ZCOMPANYSUMMERFIBERELF,ZTENNISCYCLEBILLOFFICER,"
|
||||
"ZIMAGEPENCILOTHERBOTTOM,ZWESTAMOUNTAFFECTHEARING,ZDIVERPAINTLEATHEREASY,"
|
||||
"ZSKYSKYCLASSICBRIEF,ZMESSYSULFURDREAMFESTIVE,ZMERRYCRACKTRAINLEADER,"
|
||||
"ZBROADABLESOLIDCASUAL,ZGLASSRESERVEBARIUMMEAL,ZTUNEGASBUFFALOCAPITAL,"
|
||||
"ZBANKBUFFALORECOVERORBIT,ZTREATTESTQUILLCHARGE,ZBAMBOOMESSWASABIEVENING,"
|
||||
"ZREWARDINSIDEMANGOINTENSE,ZEAGLELINEMINEMAIL,ZCALMLYGEMFINISHEFFECT,"
|
||||
"ZKEYFAILAPRICOTMETAL,ZFINGERDUEPIZZAOPTION,ZCADETBRIGHTPLANETBANK,"
|
||||
"ZGOLDYOUNGINITIALNOSE,ZMISSREPLYHUMANLIVING,ZEIGHTLEADERWORKERMOST,"
|
||||
"ZFRAMEENTERSIMPLEMOUTH,ZBIGTHINKCONVERTECONOMY,ZFACEINVITETALKGOLD,"
|
||||
"ZPOSTPROTEINHANDLEACTOR,ZHERRINGJOKEFEATUREHOPEFUL,ZCABBAGESOCKEASEMINUTE,"
|
||||
"ZMUFFINDRYERDRAWFORTUNE,ZPROBLEMCLUBPOPOVERJELLY,ZGIVEVIVIDDIVINEMEANING,"
|
||||
"ZGENENATURALHEARINGKITE,ZGENERALRESORTSKYOPEN,ZLETTUCEBIRDMEETDEBATE,"
|
||||
"ZBASEGOUDAREGULARFORGIVE,ZCHARGECLICKHUMANEHIRE,ZPLANETFAMILYPUREMEMORY,"
|
||||
"ZMINORWAYPAPERCLASSY,ZCAPYEARLYRIVETBRUSH,ZSIZETOEAWARDFRESH,"
|
||||
"ZARSENICSAMPLEWAITMUON,ZSQUAREGLEEFULCHILDLIGHT,ZSHINYASSISTLIVINGCRAB,"
|
||||
"ZCORNERANCHORTAPEDIVER,ZDECADEJOYOUSWAVEHABIT,ZTRAVELDRIVERCONTESTLILY,"
|
||||
"ZFLYINGDOCTORTABLEMELODY,ZSHARKJUSTFRUITMOVIE,ZFAMILYVISUALOWNERMATTER,"
|
||||
"ZFARMERMORNINGMIRRORCONCERN,ZGIFTICEFISHGLUEHAIR,ZOUTSIDEPEAHENCOUNTICE,"
|
||||
"ZSPREADMOTORBISCUITBACON,ZWISHHITSKINMOTOR,ZHOLIDAYHEADPONYDETAIL,"
|
||||
"ZWOODPOETRYCOBBLERBENCH,ZAIRFORGIVEHEADFROG,ZBROWBALANCEKEYCHOWDER,"
|
||||
"ZDISHKEEPBLESTMONITOR,ZCLAMBITARUGULAFAJITA,ZPLIERSPRINTASKOREGANO,"
|
||||
"ZRADIANTWHENTRYCARD,ZDELAYOUTCOMEHORNAGENCY,ZPURECAKEVIVIDNEATLY,"
|
||||
"ZPATTERNCLORINEGRANDCOLBY,ZHANDYREPAIRPROTONAIRPORT,ZAGEREEDFROGBASKET,"
|
||||
"ZSORTMISTYQUOTECABBAGE,ZFOOTTAPWORDENTRY,ZRESOLVEWRISTWRAPAPPLE,"
|
||||
"ZDILLASKHOKILEMON,ZFILLSTOPLAWJOYFUL,ZACTIONRANGEELEGANTNEUTRON,"
|
||||
"ZRESORTYARDGREENLET,ZCREAMEVENINGLIPBRANCH,ZWHALEMATHAVOCADOCOPPER,"
|
||||
"ZGRAYSURVEYWIRELOVE,ZBELLYCRASHITEMLACK,ZHANGERLITHIUMDINNERMEET,"
|
||||
"ZCARRYFLOORMINNOWDRAGON,ZMALLEQUIPTHANKSGLUE,ZTERMFITTINGHOUSINGCOMMAND,"
|
||||
"ZONERELEASEAVERAGENURSE,ZLACEADDRESSGROUNDCAREFUL"
|
||||
" FROM ZLOOKSLIKECOREDATA WHERE ZPK=?1;"
|
||||
);
|
||||
for(i=0; i<n; i++){
|
||||
x1 = speedtest1_random()%nRow;
|
||||
sqlite3_bind_int(g.pStmt, 1, x1);
|
||||
speedtest1_run();
|
||||
}
|
||||
speedtest1_end_test();
|
||||
}
|
||||
|
||||
/*
|
||||
** A testset used for debugging speedtest1 itself.
|
||||
*/
|
||||
@@ -1879,8 +1610,6 @@ int main(int argc, char **argv){
|
||||
testset_main();
|
||||
}else if( strcmp(zTSet,"debug1")==0 ){
|
||||
testset_debug1();
|
||||
}else if( strcmp(zTSet,"orm")==0 ){
|
||||
testset_orm();
|
||||
}else if( strcmp(zTSet,"cte")==0 ){
|
||||
testset_cte();
|
||||
}else if( strcmp(zTSet,"rtree")==0 ){
|
||||
|
||||
+4
-33
@@ -919,37 +919,10 @@ proc normalize_list {L} {
|
||||
set L2
|
||||
}
|
||||
|
||||
# Either:
|
||||
#
|
||||
# do_execsql_test TESTNAME SQL ?RES?
|
||||
# do_execsql_test -db DB TESTNAME SQL ?RES?
|
||||
#
|
||||
proc do_execsql_test {args} {
|
||||
set db db
|
||||
if {[lindex $args 0]=="-db"} {
|
||||
set db [lindex $args 1]
|
||||
set args [lrange $args 2 end]
|
||||
}
|
||||
|
||||
if {[llength $args]==2} {
|
||||
foreach {testname sql} $args {}
|
||||
set result ""
|
||||
} elseif {[llength $args]==3} {
|
||||
foreach {testname sql result} $args {}
|
||||
} else {
|
||||
error [string trim {
|
||||
wrong # args: should be "do_execsql_test ?-db DB? testname sql ?result?"
|
||||
}]
|
||||
}
|
||||
|
||||
proc do_execsql_test {testname sql {result {}}} {
|
||||
fix_testname testname
|
||||
|
||||
uplevel do_test \
|
||||
[list $testname] \
|
||||
[list "execsql {$sql} $db"] \
|
||||
[list [list {*}$result]]
|
||||
uplevel do_test [list $testname] [list "execsql {$sql}"] [list [list {*}$result]]
|
||||
}
|
||||
|
||||
proc do_catchsql_test {testname sql result} {
|
||||
fix_testname testname
|
||||
uplevel do_test [list $testname] [list "catchsql {$sql}"] [list $result]
|
||||
@@ -1533,7 +1506,6 @@ proc crashsql {args} {
|
||||
set tclbody {}
|
||||
set crashfile ""
|
||||
set dc ""
|
||||
set dfltvfs 0
|
||||
set sql [lindex $args end]
|
||||
|
||||
for {set ii 0} {$ii < [llength $args]-1} {incr ii 2} {
|
||||
@@ -1547,8 +1519,7 @@ proc crashsql {args} {
|
||||
elseif {$n>1 && [string first $z -file]==0} {set crashfile $z2} \
|
||||
elseif {$n>1 && [string first $z -tclbody]==0} {set tclbody $z2} \
|
||||
elseif {$n>1 && [string first $z -blocksize]==0} {set blocksize "-s $z2" } \
|
||||
elseif {$n>1 && [string first $z -characteristics]==0} {set dc "-c {$z2}" }\
|
||||
elseif {$n>1 && [string first $z -dfltvfs]==0} {set dfltvfs $z2 }\
|
||||
elseif {$n>1 && [string first $z -characteristics]==0} {set dc "-c {$z2}" } \
|
||||
else { error "Unrecognized option: $z" }
|
||||
}
|
||||
|
||||
@@ -1562,7 +1533,7 @@ proc crashsql {args} {
|
||||
set cfile [string map {\\ \\\\} [file nativename [file join [get_pwd] $crashfile]]]
|
||||
|
||||
set f [open crash.tcl w]
|
||||
puts $f "sqlite3_crash_enable 1 $dfltvfs"
|
||||
puts $f "sqlite3_crash_enable 1"
|
||||
puts $f "sqlite3_crashparams $blocksize $dc $crashdelay $cfile"
|
||||
puts $f "sqlite3_test_control_pending_byte $::sqlite_pending_byte"
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ do_test tkt-78e04-1.3 {
|
||||
} {}
|
||||
do_test tkt-78e04-1.4 {
|
||||
execsql {
|
||||
EXPLAIN QUERY PLAN SELECT "" FROM "" WHERE "" LIKE '1abc%';
|
||||
EXPLAIN QUERY PLAN SELECT "" FROM "" WHERE "" LIKE 'abc%';
|
||||
}
|
||||
} {0 0 0 {SCAN TABLE USING COVERING INDEX i1}}
|
||||
do_test tkt-78e04-1.5 {
|
||||
|
||||
+14
-14
@@ -1295,25 +1295,25 @@ do_execsql_test 18.1.0 {
|
||||
CREATE INDEX i6 ON t6(b, a);
|
||||
INSERT INTO t6 VALUES(1, 'Peter');
|
||||
INSERT INTO t6 VALUES(2, 'Andrew');
|
||||
INSERT INTO t6 VALUES(3, '8James');
|
||||
INSERT INTO t6 VALUES(4, '8John');
|
||||
INSERT INTO t6 VALUES(3, 'James');
|
||||
INSERT INTO t6 VALUES(4, 'John');
|
||||
INSERT INTO t6 VALUES(5, 'Phillip');
|
||||
INSERT INTO t6 VALUES(6, 'Bartholomew');
|
||||
CREATE VIRTUAL TABLE e6 USING echo(t6);
|
||||
}
|
||||
|
||||
foreach {tn sql res filter} {
|
||||
1.1 "SELECT a FROM e6 WHERE b>'8James'" {4 2 6 1 5}
|
||||
{xFilter {SELECT rowid, a, b FROM 't6' WHERE b > ?} 8James}
|
||||
1.1 "SELECT a FROM e6 WHERE b>'James'" {4 1 5}
|
||||
{xFilter {SELECT rowid, a, b FROM 't6' WHERE b > ?} James}
|
||||
|
||||
1.2 "SELECT a FROM e6 WHERE b>='8' AND b<'9'" {3 4}
|
||||
{xFilter {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ?} 8 9}
|
||||
1.2 "SELECT a FROM e6 WHERE b>='J' AND b<'K'" {3 4}
|
||||
{xFilter {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ?} J K}
|
||||
|
||||
1.3 "SELECT a FROM e6 WHERE b LIKE '8J%'" {3 4}
|
||||
{xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8J%}
|
||||
1.3 "SELECT a FROM e6 WHERE b LIKE 'J%'" {3 4}
|
||||
{xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} J%}
|
||||
|
||||
1.4 "SELECT a FROM e6 WHERE b LIKE '8j%'" {3 4}
|
||||
{xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8j%}
|
||||
1.4 "SELECT a FROM e6 WHERE b LIKE 'j%'" {3 4}
|
||||
{xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} j%}
|
||||
} {
|
||||
set echo_module {}
|
||||
do_execsql_test 18.$tn.1 $sql $res
|
||||
@@ -1322,11 +1322,11 @@ foreach {tn sql res filter} {
|
||||
|
||||
do_execsql_test 18.2.0 { PRAGMA case_sensitive_like = ON }
|
||||
foreach {tn sql res filter} {
|
||||
2.1 "SELECT a FROM e6 WHERE b LIKE '8J%'" {3 4}
|
||||
{xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8J%}
|
||||
2.1 "SELECT a FROM e6 WHERE b LIKE 'J%'" {3 4}
|
||||
{xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} J%}
|
||||
|
||||
2.2 "SELECT a FROM e6 WHERE b LIKE '8j%'" {}
|
||||
{xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8j%}
|
||||
2.2 "SELECT a FROM e6 WHERE b LIKE 'j%'" {}
|
||||
{xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} j%}
|
||||
} {
|
||||
set echo_module {}
|
||||
do_execsql_test 18.$tn.1 $sql $res
|
||||
|
||||
+4
-4
@@ -31,14 +31,14 @@ do_execsql_test 1.0 {
|
||||
}
|
||||
|
||||
foreach {tn sql expect} {
|
||||
1 "SELECT * FROM e6 WHERE b LIKE '8abc'" {
|
||||
1 "SELECT * FROM e6 WHERE b LIKE 'abc'" {
|
||||
xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b like ?}
|
||||
xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8abc
|
||||
xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} abc
|
||||
}
|
||||
|
||||
2 "SELECT * FROM e6 WHERE b GLOB '8abc'" {
|
||||
2 "SELECT * FROM e6 WHERE b GLOB 'abc'" {
|
||||
xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b glob ?}
|
||||
xFilter {SELECT rowid, a, b FROM 't6' WHERE b glob ?} 8abc
|
||||
xFilter {SELECT rowid, a, b FROM 't6' WHERE b glob ?} abc
|
||||
}
|
||||
} {
|
||||
do_test 1.$tn {
|
||||
|
||||
+1
-13
@@ -124,7 +124,7 @@ IF NOT EXIST "%FRAMEWORKDIR%\csc.exe" (
|
||||
GOTO errors
|
||||
)
|
||||
|
||||
CALL :fn_PrependToPath FRAMEWORKDIR
|
||||
SET PATH=%FRAMEWORKDIR%;%PATH%
|
||||
|
||||
:skip_addToPath
|
||||
|
||||
@@ -246,18 +246,6 @@ GOTO no_errors
|
||||
ENDLOCAL && SET %1=%VALUE%
|
||||
GOTO :EOF
|
||||
|
||||
:fn_PrependToPath
|
||||
IF NOT DEFINED %1 GOTO :EOF
|
||||
SETLOCAL
|
||||
SET __ECHO_CMD=ECHO %%%1%%
|
||||
FOR /F "delims=" %%V IN ('%__ECHO_CMD%') DO (
|
||||
SET VALUE=%%V
|
||||
)
|
||||
SET VALUE=%VALUE:"=%
|
||||
REM "
|
||||
ENDLOCAL && SET PATH=%VALUE%;%PATH%
|
||||
GOTO :EOF
|
||||
|
||||
:fn_ResetErrorLevel
|
||||
VERIFY > NUL
|
||||
GOTO :EOF
|
||||
|
||||
@@ -460,7 +460,7 @@ FOR %%P IN (%PLATFORMS%) DO (
|
||||
REM
|
||||
REM NOTE: Reset the PATH here to the absolute bare minimum required.
|
||||
REM
|
||||
CALL :fn_ResetPath
|
||||
SET PATH=%TOOLPATH%;%SystemRoot%\System32;%SystemRoot%
|
||||
|
||||
REM
|
||||
REM NOTE: This is the inner loop. There are normally two iterations, one
|
||||
@@ -818,10 +818,6 @@ GOTO no_errors
|
||||
CALL :fn_ResetErrorLevel
|
||||
GOTO :EOF
|
||||
|
||||
:fn_ResetPath
|
||||
SET PATH=%TOOLPATH%;%SystemRoot%\System32;%SystemRoot%
|
||||
GOTO :EOF
|
||||
|
||||
:fn_AppendVariable
|
||||
SET __ECHO_CMD=ECHO %%%1%%
|
||||
IF DEFINED %1 (
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
** Link this program against an SQLite library of unknown provenance in order
|
||||
** to display the compile-time maximum values for various settings.
|
||||
*/
|
||||
#include "sqlite3.h"
|
||||
#include <stdio.h>
|
||||
|
||||
static const struct {
|
||||
int eCode;
|
||||
char *zName;
|
||||
} aLimit[] = {
|
||||
{ SQLITE_LIMIT_LENGTH, "SQLITE_MAX_LENGTH" },
|
||||
{ SQLITE_LIMIT_SQL_LENGTH, "SQLITE_MAX_SQL_LENGTH" },
|
||||
{ SQLITE_LIMIT_COLUMN, "SQLITE_MAX_COLUMN" },
|
||||
{ SQLITE_LIMIT_EXPR_DEPTH, "SQLITE_MAX_EXPR_DEPTH" },
|
||||
{ SQLITE_LIMIT_COMPOUND_SELECT, "SQLITE_MAX_COMPOUND_SELECT" },
|
||||
{ SQLITE_LIMIT_VDBE_OP, "SQLITE_MAX_VDBE_OP" },
|
||||
{ SQLITE_LIMIT_FUNCTION_ARG, "SQLITE_MAX_FUNCTION_ARG" },
|
||||
{ SQLITE_LIMIT_ATTACHED, "SQLITE_MAX_ATTACHED" },
|
||||
{ SQLITE_LIMIT_LIKE_PATTERN_LENGTH, "SQLITE_MAX_LIKE_PATTERN_LENGTH" },
|
||||
{ SQLITE_LIMIT_VARIABLE_NUMBER, "SQLITE_MAX_VARIABLE_NUMBER" },
|
||||
{ SQLITE_LIMIT_TRIGGER_DEPTH, "SQLITE_MAX_TRIGGER_DEPTH" },
|
||||
{ SQLITE_LIMIT_WORKER_THREADS, "SQLITE_MAX_WORKER_THREADS" },
|
||||
};
|
||||
|
||||
static int maxLimit(sqlite3 *db, int eCode){
|
||||
int iOrig = sqlite3_limit(db, eCode, 0x7fffffff);
|
||||
return sqlite3_limit(db, eCode, iOrig);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv){
|
||||
sqlite3 *db;
|
||||
int j, rc;
|
||||
rc = sqlite3_open(":memory:", &db);
|
||||
if( rc==SQLITE_OK ){
|
||||
for(j=0; j<sizeof(aLimit)/sizeof(aLimit[0]); j++){
|
||||
printf("%-35s %10d\n", aLimit[j].zName, maxLimit(db, aLimit[j].eCode));
|
||||
}
|
||||
sqlite3_close(db);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -83,7 +83,7 @@ Replace.exe:
|
||||
sqlite3.def: Replace.exe $(LIBOBJ)
|
||||
echo EXPORTS > sqlite3.def
|
||||
dumpbin /all $(LIBOBJ) \\
|
||||
| .\Replace.exe "^\s+/EXPORT:_?(sqlite3(?:session|changeset)?_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \\
|
||||
| .\Replace.exe "^\s+/EXPORT:_?(sqlite3_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \\
|
||||
| sort >> sqlite3.def
|
||||
}]]
|
||||
|
||||
|
||||
@@ -225,8 +225,8 @@ set pragma_def {
|
||||
|
||||
NAME: stats
|
||||
FLAG: NeedSchema Result0 SchemaReq
|
||||
COLS: tbl idx wdth hght flgs
|
||||
IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG)
|
||||
COLS: table index width height
|
||||
IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
|
||||
|
||||
NAME: index_info
|
||||
TYPE: INDEX_INFO
|
||||
@@ -361,9 +361,6 @@ set pragma_def {
|
||||
|
||||
NAME: threads
|
||||
FLAG: Result0
|
||||
|
||||
NAME: optimize
|
||||
FLAG: Result1
|
||||
}
|
||||
|
||||
# Open the output file
|
||||
|
||||
+2
-10
@@ -73,13 +73,7 @@ close $in
|
||||
# Set up patterns for recognizing API declarations.
|
||||
#
|
||||
set varpattern {^[a-zA-Z][a-zA-Z_0-9 *]+sqlite3_[_a-zA-Z0-9]+(\[|;| =)}
|
||||
set declpattern1 {^ *([a-zA-Z][a-zA-Z_0-9 ]+ \**)(sqlite3_[_a-zA-Z0-9]+)(\(.*)$}
|
||||
|
||||
set declpattern2 \
|
||||
{^ *([a-zA-Z][a-zA-Z_0-9 ]+ \**)(sqlite3session_[_a-zA-Z0-9]+)(\(.*)$}
|
||||
|
||||
set declpattern3 \
|
||||
{^ *([a-zA-Z][a-zA-Z_0-9 ]+ \**)(sqlite3changeset_[_a-zA-Z0-9]+)(\(.*)$}
|
||||
set declpattern {^ *([a-zA-Z][a-zA-Z_0-9 ]+ \**)(sqlite3_[_a-zA-Z0-9]+)(\(.*)$}
|
||||
|
||||
# Force the output to use unix line endings, even on Windows.
|
||||
fconfigure stdout -translation lf
|
||||
@@ -127,9 +121,7 @@ foreach file $filelist {
|
||||
if {[regexp $varpattern $line] && ![regexp {^ *typedef} $line]} {
|
||||
set line "SQLITE_API $line"
|
||||
} else {
|
||||
if {[regexp $declpattern1 $line all rettype funcname rest] || \
|
||||
[regexp $declpattern2 $line all rettype funcname rest] || \
|
||||
[regexp $declpattern3 $line all rettype funcname rest]} {
|
||||
if {[regexp $declpattern $line all rettype funcname rest]} {
|
||||
set line SQLITE_API
|
||||
append line " " [string trim $rettype]
|
||||
if {[string index $rettype end] ne "*"} {
|
||||
|
||||
Reference in New Issue
Block a user