Compare commits
72 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 14f2dad0b2 | |||
| 4689956b9e | |||
| 5e6710ab65 | |||
| 7e84b377a9 | |||
| eeea412a9d | |||
| f196972c73 | |||
| 7898bfff26 | |||
| 2b44fd94ba | |||
| e9ba910f0d | |||
| 5c258dc1cc | |||
| c5f4816fc5 | |||
| 6f271a421d | |||
| b6bf97b384 | |||
| 44266ec651 | |||
| 3a3b420abb | |||
| 0d5b3b7665 | |||
| dc5ece86ae | |||
| d742367ab5 | |||
| dd22c09af8 | |||
| 0c5cd969b8 | |||
| 7e4acf7b44 | |||
| d2f92c26d5 | |||
| a829054049 | |||
| a8207f488f | |||
| d879e3eb8d | |||
| 30a5831c45 | |||
| ac279be98e | |||
| f9463dfbcf | |||
| 13ac46eea2 | |||
| 653a5f4e71 | |||
| 1c84bd4787 | |||
| 2c338a9d9a | |||
| a39284bfa8 | |||
| ad3b4c078e | |||
| 18fdde21b8 | |||
| 40b84365e4 | |||
| 087a29c78b | |||
| 0356ebd0a5 | |||
| ec26ce3328 | |||
| 953fbd16af | |||
| 134e527091 | |||
| b67e175448 | |||
| cbc65e5f4f | |||
| 18b20c981d | |||
| a7fc253d42 | |||
| b9e9bc1de6 | |||
| 2e9dceb432 | |||
| 9fcb6ddc1e | |||
| 821fad51b4 | |||
| 364ca6a90e | |||
| edd9bcb372 | |||
| 76f63789f2 | |||
| b18bf843f7 | |||
| 04128ace8d | |||
| 943aa77a8a | |||
| 809955b504 | |||
| 9630f3ba08 | |||
| 238390c3b4 | |||
| ff677b20fc | |||
| fe05491b87 | |||
| 010e312f8f | |||
| 88610c968e | |||
| 067cd837fb | |||
| 59a40db3d2 | |||
| a7466205ca | |||
| 1101ae4113 | |||
| 07b139b8c1 | |||
| 3accc7e1af | |||
| ce655a2367 | |||
| 413e207e31 | |||
| 2033d1c8ca | |||
| 6d683c5c6e |
@@ -1185,6 +1185,11 @@ KV_OPT += -DSQLITE_DIRECT_OVERFLOW_READ
|
||||
kvtest$(TEXE): $(TOP)/test/kvtest.c sqlite3.c
|
||||
$(LTLINK) $(KV_OPT) -o $@ $(TOP)/test/kvtest.c sqlite3.c $(TLIBS)
|
||||
|
||||
DBSELFTEST_OPT += -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_FTS4
|
||||
|
||||
dbselftest$(TEXE): $(TOP)/test/dbselftest.c sqlite3.c
|
||||
$(LTLINK) $(DBSELFTEST_OPT) -o $@ $(TOP)/test/dbselftest.c sqlite3.c $(TLIBS)
|
||||
|
||||
rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.lo
|
||||
$(LTLINK) -I. -o $@ $(TOP)/ext/rbu/rbu.c sqlite3.lo $(TLIBS)
|
||||
|
||||
|
||||
+29
-13
@@ -745,6 +745,7 @@ 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
|
||||
|
||||
@@ -1512,6 +1513,10 @@ FUZZERSHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1
|
||||
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.
|
||||
#
|
||||
@@ -1554,7 +1559,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_[^@]*)(?:@\d+)?$$" \1 \
|
||||
| $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3(?:session|changeset)?_[^@]*)(?:@\d+)?$$" \1 \
|
||||
| sort >> sqlite3.def
|
||||
# <</block2>>
|
||||
|
||||
@@ -1581,6 +1586,9 @@ 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)
|
||||
|
||||
@@ -2177,46 +2185,54 @@ 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 -Fe$@ \
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
$(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 -Fe$@ \
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
$(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 -Fe$@ \
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
$(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 -Fe$@ \
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
$(TOP)\tool\showwal.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
changeset.exe: $(TOP)\ext\session\changeset.c $(SQLITE3C)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||
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 \
|
||||
$(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 -Fe$@ \
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
$(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 -Fe$@ \
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
$(TOP)\tool\rollback-test.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
LogEst.exe: $(TOP)\tool\logest.c $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) -Fe$@ $(TOP)\tool\LogEst.c /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
$(LTLINK) $(NO_WARN) $(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 -Fe$@ \
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
$(TOP)\test\wordcount.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
speedtest1.exe: $(TOP)\test\speedtest1.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
|
||||
$(LTLINK) $(NO_WARN) $(ST_COMPILE_OPTS) -DSQLITE_OMIT_LOAD_EXTENSION \
|
||||
$(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 -Fe$@ \
|
||||
$(LTLINK) $(NO_WARN) -DSQLITE_ENABLE_RBU \
|
||||
$(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_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \
|
||||
| .\Replace.exe "^\s+/EXPORT:_?(sqlite3(?:session|changeset)?_[^@,]*)(?:@\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.17.0.
|
||||
# Generated by GNU Autoconf 2.69 for sqlite 3.18.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.17.0'
|
||||
PACKAGE_STRING='sqlite 3.17.0'
|
||||
PACKAGE_VERSION='3.18.0'
|
||||
PACKAGE_STRING='sqlite 3.18.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.17.0 to adapt to many kinds of systems.
|
||||
\`configure' configures sqlite 3.18.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.17.0:";;
|
||||
short | recursive ) echo "Configuration of sqlite 3.18.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.17.0
|
||||
sqlite configure 3.18.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.17.0, which was
|
||||
It was created by sqlite $as_me 3.18.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.17.0, which was
|
||||
This file was extended by sqlite $as_me 3.18.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.17.0
|
||||
sqlite config.status 3.18.0
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
||||
+36
-14
@@ -492,6 +492,7 @@ 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]);
|
||||
}
|
||||
@@ -1680,6 +1681,26 @@ 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.
|
||||
@@ -1687,7 +1708,7 @@ static int fts3OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){
|
||||
static int fts3CloseMethod(sqlite3_vtab_cursor *pCursor){
|
||||
Fts3Cursor *pCsr = (Fts3Cursor *)pCursor;
|
||||
assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
|
||||
sqlite3_finalize(pCsr->pStmt);
|
||||
fts3CursorFinalizeStmt(pCsr);
|
||||
sqlite3Fts3ExprFree(pCsr->pExpr);
|
||||
sqlite3Fts3FreeDeferredTokens(pCsr);
|
||||
sqlite3_free(pCsr->aDoclist);
|
||||
@@ -1705,20 +1726,23 @@ 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, sqlite3_stmt **ppStmt){
|
||||
static int fts3CursorSeekStmt(Fts3Cursor *pCsr){
|
||||
int rc = SQLITE_OK;
|
||||
if( pCsr->pStmt==0 ){
|
||||
Fts3Table *p = (Fts3Table *)pCsr->base.pVtab;
|
||||
char *zSql;
|
||||
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( 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;
|
||||
}
|
||||
*ppStmt = pCsr->pStmt;
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -1730,9 +1754,7 @@ static int fts3CursorSeekStmt(Fts3Cursor *pCsr, sqlite3_stmt **ppStmt){
|
||||
static int fts3CursorSeek(sqlite3_context *pContext, Fts3Cursor *pCsr){
|
||||
int rc = SQLITE_OK;
|
||||
if( pCsr->isRequireSeek ){
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
|
||||
rc = fts3CursorSeekStmt(pCsr, &pStmt);
|
||||
rc = fts3CursorSeekStmt(pCsr);
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iPrevId);
|
||||
pCsr->isRequireSeek = 0;
|
||||
@@ -3190,7 +3212,7 @@ static int fts3FilterMethod(
|
||||
assert( iIdx==nVal );
|
||||
|
||||
/* In case the cursor has been used before, clear it now. */
|
||||
sqlite3_finalize(pCsr->pStmt);
|
||||
fts3CursorFinalizeStmt(pCsr);
|
||||
sqlite3_free(pCsr->aDoclist);
|
||||
sqlite3Fts3MIBufferFree(pCsr->pMIBuffer);
|
||||
sqlite3Fts3ExprFree(pCsr->pExpr);
|
||||
@@ -3258,7 +3280,7 @@ static int fts3FilterMethod(
|
||||
rc = SQLITE_NOMEM;
|
||||
}
|
||||
}else if( eSearch==FTS3_DOCID_SEARCH ){
|
||||
rc = fts3CursorSeekStmt(pCsr, &pCsr->pStmt);
|
||||
rc = fts3CursorSeekStmt(pCsr);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3_bind_value(pCsr->pStmt, 1, pCons);
|
||||
}
|
||||
|
||||
@@ -230,6 +230,7 @@ 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;
|
||||
@@ -299,6 +300,7 @@ 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 */
|
||||
|
||||
+3
-1
@@ -30,7 +30,9 @@ typedef short i16;
|
||||
typedef sqlite3_int64 i64;
|
||||
typedef sqlite3_uint64 u64;
|
||||
|
||||
#define ArraySize(x) ((int)(sizeof(x) / sizeof(x[0])))
|
||||
#ifndef ArraySize
|
||||
# define ArraySize(x) ((int)(sizeof(x) / sizeof(x[0])))
|
||||
#endif
|
||||
|
||||
#define testcase(x)
|
||||
#define ALWAYS(x) 1
|
||||
|
||||
+25
-17
@@ -87,12 +87,6 @@ struct SHA1Context {
|
||||
/*
|
||||
* Hash a single 512-bit block. This is the core of the algorithm.
|
||||
*/
|
||||
#define a qq[0]
|
||||
#define b qq[1]
|
||||
#define c qq[2]
|
||||
#define d qq[3]
|
||||
#define e qq[4]
|
||||
|
||||
void SHA1Transform(unsigned int state[5], const unsigned char buffer[64]){
|
||||
unsigned int qq[5]; /* a, b, c, d, e; */
|
||||
static int one = 1;
|
||||
@@ -100,6 +94,12 @@ void SHA1Transform(unsigned int state[5], const unsigned char buffer[64]){
|
||||
memcpy(block, buffer, 64);
|
||||
memcpy(qq,state,5*sizeof(unsigned int));
|
||||
|
||||
#define a qq[0]
|
||||
#define b qq[1]
|
||||
#define c qq[2]
|
||||
#define d qq[3]
|
||||
#define e qq[4]
|
||||
|
||||
/* Copy p->state[] to working vars */
|
||||
/*
|
||||
a = state[0];
|
||||
@@ -144,6 +144,12 @@ void SHA1Transform(unsigned int state[5], const unsigned char buffer[64]){
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
state[4] += e;
|
||||
|
||||
#undef a
|
||||
#undef b
|
||||
#undef c
|
||||
#undef d
|
||||
#undef e
|
||||
}
|
||||
|
||||
|
||||
@@ -253,6 +259,7 @@ static void sha1Func(
|
||||
int nByte = sqlite3_value_bytes(argv[0]);
|
||||
char zOut[44];
|
||||
|
||||
assert( argc==1 );
|
||||
if( eType==SQLITE_NULL ) return;
|
||||
hash_init(&cx);
|
||||
if( eType==SQLITE_BLOB ){
|
||||
@@ -292,6 +299,7 @@ static void sha1QueryFunc(
|
||||
SHA1Context cx;
|
||||
char zOut[44];
|
||||
|
||||
assert( argc==1 );
|
||||
if( zSql==0 ) return;
|
||||
hash_init(&cx);
|
||||
while( zSql[0] ){
|
||||
@@ -343,7 +351,7 @@ static void sha1QueryFunc(
|
||||
case SQLITE_FLOAT: {
|
||||
sqlite3_uint64 u;
|
||||
int j;
|
||||
unsigned char x[8];
|
||||
unsigned char x[9];
|
||||
double r = sqlite3_column_double(pStmt,i);
|
||||
memcpy(&u, &r, 8);
|
||||
for(j=8; j>=1; j--){
|
||||
@@ -355,17 +363,17 @@ static void sha1QueryFunc(
|
||||
break;
|
||||
}
|
||||
case SQLITE_TEXT: {
|
||||
int n = sqlite3_column_bytes(pStmt, i);
|
||||
const unsigned char *z = sqlite3_column_text(pStmt, i);
|
||||
hash_step_vformat(&cx,"T%d:",n);
|
||||
hash_step(&cx, z, n);
|
||||
int n2 = sqlite3_column_bytes(pStmt, i);
|
||||
const unsigned char *z2 = sqlite3_column_text(pStmt, i);
|
||||
hash_step_vformat(&cx,"T%d:",n2);
|
||||
hash_step(&cx, z2, n2);
|
||||
break;
|
||||
}
|
||||
case SQLITE_BLOB: {
|
||||
int n = sqlite3_column_bytes(pStmt, i);
|
||||
const unsigned char *z = sqlite3_column_blob(pStmt, i);
|
||||
hash_step_vformat(&cx,"B%d:",n);
|
||||
hash_step(&cx, z, n);
|
||||
int n2 = sqlite3_column_bytes(pStmt, i);
|
||||
const unsigned char *z2 = sqlite3_column_blob(pStmt, i);
|
||||
hash_step_vformat(&cx,"B%d:",n2);
|
||||
hash_step(&cx, z2, n2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -382,8 +390,8 @@ static void sha1QueryFunc(
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
int sqlite3_sha_init(
|
||||
sqlite3 *db,
|
||||
char **pzErrMsg,
|
||||
sqlite3 *db,
|
||||
char **pzErrMsg,
|
||||
const sqlite3_api_routines *pApi
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
+136
-106
@@ -68,6 +68,7 @@
|
||||
#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;
|
||||
@@ -119,11 +120,13 @@ struct Rtree {
|
||||
u8 nDim2; /* Twice the number of dimensions */
|
||||
u8 eCoordType; /* RTREE_COORD_REAL32 or RTREE_COORD_INT32 */
|
||||
u8 nBytesPerCell; /* Bytes consumed per cell */
|
||||
u8 inWrTrans; /* True if inside write transaction */
|
||||
int iDepth; /* Current depth of the r-tree structure */
|
||||
char *zDb; /* Name of database containing r-tree table */
|
||||
char *zName; /* Name of r-tree table */
|
||||
int nBusy; /* Current number of users of this structure */
|
||||
u32 nBusy; /* Current number of users of this structure */
|
||||
i64 nRowEst; /* Estimated number of rows in this table */
|
||||
u32 nCursor; /* Number of open cursors */
|
||||
|
||||
/* List of nodes removed during a CondenseTree operation. List is
|
||||
** linked together via the pointer normally used for hash chains -
|
||||
@@ -133,8 +136,10 @@ struct Rtree {
|
||||
RtreeNode *pDeleted;
|
||||
int iReinsertHeight; /* Height of sub-trees Reinsert() has run on */
|
||||
|
||||
/* Blob I/O on xxx_node */
|
||||
sqlite3_blob *pNodeBlob;
|
||||
|
||||
/* Statements to read/write/delete a record from xxx_node */
|
||||
sqlite3_stmt *pReadNode;
|
||||
sqlite3_stmt *pWriteNode;
|
||||
sqlite3_stmt *pDeleteNode;
|
||||
|
||||
@@ -363,29 +368,23 @@ 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 */
|
||||
/* 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.
|
||||
*/
|
||||
#ifndef GCC_VERSION
|
||||
#ifdef __GNUC__
|
||||
#if defined(__GNUC__) && !defined(SQLITE_DISABLE_INTRINSIC)
|
||||
# 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.
|
||||
*/
|
||||
#ifndef SQLITE_AMALGMATION
|
||||
#ifndef SQLITE_AMALGAMATION
|
||||
# define testcase(X)
|
||||
#endif
|
||||
|
||||
@@ -399,23 +398,22 @@ 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__)) && !defined(SQLITE_RUNTIME_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 SQLITE_BYTEORDER 1234
|
||||
#endif
|
||||
#if (defined(sparc) || defined(__ppc__)) \
|
||||
&& !defined(SQLITE_RUNTIME_BYTEORDER)
|
||||
#elif defined(sparc) || defined(__ppc__)
|
||||
# define SQLITE_BYTEORDER 4321
|
||||
#endif
|
||||
#else
|
||||
# define SQLITE_BYTEORDER 0 /* 0 means "unknown at compile-time" */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* What version of MSVC is being used. 0 means MSVC is not being used */
|
||||
#ifndef MSVC_VERSION
|
||||
#if defined(_MSC_VER)
|
||||
#if defined(_MSC_VER) && !defined(SQLITE_DISABLE_INTRINSIC)
|
||||
# define MSVC_VERSION _MSC_VER
|
||||
#else
|
||||
# define MSVC_VERSION 0
|
||||
@@ -433,11 +431,8 @@ 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 || CLANG_VERSION>=3000000)
|
||||
#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
|
||||
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
|
||||
@@ -452,21 +447,17 @@ 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 || CLANG_VERSION>=3000000)
|
||||
#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
|
||||
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) +
|
||||
@@ -485,17 +476,16 @@ 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 int writeInt16(u8 *p, int i){
|
||||
static void 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 || CLANG_VERSION>=3000000)
|
||||
#if SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
|
||||
i = __builtin_bswap32(pCoord->u);
|
||||
memcpy(p, &i, 4);
|
||||
#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
|
||||
@@ -514,8 +504,7 @@ static int writeCoord(u8 *p, RtreeCoord *pCoord){
|
||||
return 4;
|
||||
}
|
||||
static int writeInt64(u8 *p, i64 i){
|
||||
testcase( ((((char*)p) - (char*)0)&7)!=0 ); /* Not always 8-byte aligned */
|
||||
#if SQLITE_BYTEORDER==1234 && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000)
|
||||
#if SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
|
||||
i = (i64)__builtin_bswap64((u64)i);
|
||||
memcpy(p, &i, 8);
|
||||
#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
|
||||
@@ -615,6 +604,17 @@ static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent){
|
||||
return pNode;
|
||||
}
|
||||
|
||||
/*
|
||||
** Clear the Rtree.pNodeBlob object
|
||||
*/
|
||||
static void nodeBlobReset(Rtree *pRtree){
|
||||
if( pRtree->pNodeBlob && pRtree->inWrTrans==0 && pRtree->nCursor==0 ){
|
||||
sqlite3_blob *pBlob = pRtree->pNodeBlob;
|
||||
pRtree->pNodeBlob = 0;
|
||||
sqlite3_blob_close(pBlob);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Obtain a reference to an r-tree node.
|
||||
*/
|
||||
@@ -624,9 +624,8 @@ static int nodeAcquire(
|
||||
RtreeNode *pParent, /* Either the parent node or NULL */
|
||||
RtreeNode **ppNode /* OUT: Acquired node */
|
||||
){
|
||||
int rc;
|
||||
int rc2 = SQLITE_OK;
|
||||
RtreeNode *pNode;
|
||||
int rc = SQLITE_OK;
|
||||
RtreeNode *pNode = 0;
|
||||
|
||||
/* Check if the requested node is already in the hash table. If so,
|
||||
** increase its reference count and return it.
|
||||
@@ -642,28 +641,45 @@ static int nodeAcquire(
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
sqlite3_bind_int64(pRtree->pReadNode, 1, iNode);
|
||||
rc = sqlite3_step(pRtree->pReadNode);
|
||||
if( rc==SQLITE_ROW ){
|
||||
const u8 *zBlob = sqlite3_column_blob(pRtree->pReadNode, 0);
|
||||
if( pRtree->iNodeSize==sqlite3_column_bytes(pRtree->pReadNode, 0) ){
|
||||
pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode)+pRtree->iNodeSize);
|
||||
if( !pNode ){
|
||||
rc2 = SQLITE_NOMEM;
|
||||
}else{
|
||||
pNode->pParent = pParent;
|
||||
pNode->zData = (u8 *)&pNode[1];
|
||||
pNode->nRef = 1;
|
||||
pNode->iNode = iNode;
|
||||
pNode->isDirty = 0;
|
||||
pNode->pNext = 0;
|
||||
memcpy(pNode->zData, zBlob, pRtree->iNodeSize);
|
||||
nodeReference(pParent);
|
||||
}
|
||||
if( pRtree->pNodeBlob ){
|
||||
sqlite3_blob *pBlob = pRtree->pNodeBlob;
|
||||
pRtree->pNodeBlob = 0;
|
||||
rc = sqlite3_blob_reopen(pBlob, iNode);
|
||||
pRtree->pNodeBlob = pBlob;
|
||||
if( rc ){
|
||||
nodeBlobReset(pRtree);
|
||||
if( rc==SQLITE_NOMEM ) return SQLITE_NOMEM;
|
||||
}
|
||||
}
|
||||
if( pRtree->pNodeBlob==0 ){
|
||||
char *zTab = sqlite3_mprintf("%s_node", pRtree->zName);
|
||||
if( zTab==0 ) return SQLITE_NOMEM;
|
||||
rc = sqlite3_blob_open(pRtree->db, pRtree->zDb, zTab, "data", iNode, 0,
|
||||
&pRtree->pNodeBlob);
|
||||
sqlite3_free(zTab);
|
||||
}
|
||||
if( rc ){
|
||||
nodeBlobReset(pRtree);
|
||||
*ppNode = 0;
|
||||
/* If unable to open an sqlite3_blob on the desired row, that can only
|
||||
** be because the shadow tables hold erroneous data. */
|
||||
if( rc==SQLITE_ERROR ) rc = SQLITE_CORRUPT_VTAB;
|
||||
}else if( pRtree->iNodeSize==sqlite3_blob_bytes(pRtree->pNodeBlob) ){
|
||||
pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode)+pRtree->iNodeSize);
|
||||
if( !pNode ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
pNode->pParent = pParent;
|
||||
pNode->zData = (u8 *)&pNode[1];
|
||||
pNode->nRef = 1;
|
||||
pNode->iNode = iNode;
|
||||
pNode->isDirty = 0;
|
||||
pNode->pNext = 0;
|
||||
rc = sqlite3_blob_read(pRtree->pNodeBlob, pNode->zData,
|
||||
pRtree->iNodeSize, 0);
|
||||
nodeReference(pParent);
|
||||
}
|
||||
}
|
||||
rc = sqlite3_reset(pRtree->pReadNode);
|
||||
if( rc==SQLITE_OK ) rc = rc2;
|
||||
|
||||
/* If the root node was just loaded, set pRtree->iDepth to the height
|
||||
** of the r-tree structure. A height of zero means all data is stored on
|
||||
@@ -909,7 +925,9 @@ static void rtreeReference(Rtree *pRtree){
|
||||
static void rtreeRelease(Rtree *pRtree){
|
||||
pRtree->nBusy--;
|
||||
if( pRtree->nBusy==0 ){
|
||||
sqlite3_finalize(pRtree->pReadNode);
|
||||
pRtree->inWrTrans = 0;
|
||||
pRtree->nCursor = 0;
|
||||
nodeBlobReset(pRtree);
|
||||
sqlite3_finalize(pRtree->pWriteNode);
|
||||
sqlite3_finalize(pRtree->pDeleteNode);
|
||||
sqlite3_finalize(pRtree->pReadRowid);
|
||||
@@ -947,6 +965,7 @@ static int rtreeDestroy(sqlite3_vtab *pVtab){
|
||||
if( !zCreate ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
nodeBlobReset(pRtree);
|
||||
rc = sqlite3_exec(pRtree->db, zCreate, 0, 0, 0);
|
||||
sqlite3_free(zCreate);
|
||||
}
|
||||
@@ -962,6 +981,7 @@ static int rtreeDestroy(sqlite3_vtab *pVtab){
|
||||
*/
|
||||
static int rtreeOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
|
||||
int rc = SQLITE_NOMEM;
|
||||
Rtree *pRtree = (Rtree *)pVTab;
|
||||
RtreeCursor *pCsr;
|
||||
|
||||
pCsr = (RtreeCursor *)sqlite3_malloc(sizeof(RtreeCursor));
|
||||
@@ -969,6 +989,7 @@ static int rtreeOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
|
||||
memset(pCsr, 0, sizeof(RtreeCursor));
|
||||
pCsr->base.pVtab = pVTab;
|
||||
rc = SQLITE_OK;
|
||||
pRtree->nCursor++;
|
||||
}
|
||||
*ppCursor = (sqlite3_vtab_cursor *)pCsr;
|
||||
|
||||
@@ -1001,10 +1022,13 @@ static int rtreeClose(sqlite3_vtab_cursor *cur){
|
||||
Rtree *pRtree = (Rtree *)(cur->pVtab);
|
||||
int ii;
|
||||
RtreeCursor *pCsr = (RtreeCursor *)cur;
|
||||
assert( pRtree->nCursor>0 );
|
||||
freeCursorConstraints(pCsr);
|
||||
sqlite3_free(pCsr->aPoint);
|
||||
for(ii=0; ii<RTREE_CACHE_SZ; ii++) nodeRelease(pRtree, pCsr->aNode[ii]);
|
||||
sqlite3_free(pCsr);
|
||||
pRtree->nCursor--;
|
||||
nodeBlobReset(pRtree);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
@@ -1036,7 +1060,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 || CLANG_VERSION>=3000000)
|
||||
#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
|
||||
#define RTREE_DECODE_COORD(eInt, a, r) { \
|
||||
RtreeCoord c; /* Coordinate decoded */ \
|
||||
c.u = __builtin_bswap32(*(u32*)a); \
|
||||
@@ -1077,7 +1101,6 @@ static int rtreeCallbackConstraint(
|
||||
sqlite3_rtree_dbl *prScore, /* OUT: score for the cell */
|
||||
int *peWithin /* OUT: visibility of the cell */
|
||||
){
|
||||
int i; /* Loop counter */
|
||||
sqlite3_rtree_query_info *pInfo = pConstraint->pInfo; /* Callback info */
|
||||
int nCoord = pInfo->nCoord; /* No. of coordinates */
|
||||
int rc; /* Callback return code */
|
||||
@@ -1122,9 +1145,10 @@ static int rtreeCallbackConstraint(
|
||||
}
|
||||
}
|
||||
if( pConstraint->op==RTREE_MATCH ){
|
||||
int eWithin = 0;
|
||||
rc = pConstraint->u.xGeom((sqlite3_rtree_geometry*)pInfo,
|
||||
nCoord, aCoord, &i);
|
||||
if( i==0 ) *peWithin = NOT_WITHIN;
|
||||
nCoord, aCoord, &eWithin);
|
||||
if( eWithin==0 ) *peWithin = NOT_WITHIN;
|
||||
*prScore = RTREE_ZERO;
|
||||
}else{
|
||||
pInfo->aCoord = aCoord;
|
||||
@@ -1270,7 +1294,7 @@ static int rtreeSearchPointCompare(
|
||||
}
|
||||
|
||||
/*
|
||||
** Interchange to search points in a cursor.
|
||||
** Interchange two search points in a cursor.
|
||||
*/
|
||||
static void rtreeSearchPointSwap(RtreeCursor *p, int i, int j){
|
||||
RtreeSearchPoint t = p->aPoint[i];
|
||||
@@ -1577,7 +1601,6 @@ 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 ){
|
||||
@@ -1772,19 +1795,6 @@ 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
|
||||
@@ -1864,7 +1874,7 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
|
||||
** a single row.
|
||||
*/
|
||||
pIdxInfo->estimatedCost = 30.0;
|
||||
setEstimatedRows(pIdxInfo, 1);
|
||||
pIdxInfo->estimatedRows = 1;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
@@ -1896,7 +1906,7 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
|
||||
|
||||
nRow = pRtree->nRowEst >> (iIdx/2);
|
||||
pIdxInfo->estimatedCost = (double)6.0 * (double)nRow;
|
||||
setEstimatedRows(pIdxInfo, nRow);
|
||||
pIdxInfo->estimatedRows = nRow;
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -1935,12 +1945,12 @@ static RtreeDValue cellArea(Rtree *pRtree, RtreeCell *p){
|
||||
** of the objects size in each dimension.
|
||||
*/
|
||||
static RtreeDValue cellMargin(Rtree *pRtree, RtreeCell *p){
|
||||
RtreeDValue margin;
|
||||
int ii;
|
||||
margin = DCOORD(p->aCoord[1]) - DCOORD(p->aCoord[0]);
|
||||
for(ii=2; ii<pRtree->nDim2; ii+=2){
|
||||
RtreeDValue margin = 0;
|
||||
int ii = pRtree->nDim2 - 2;
|
||||
do{
|
||||
margin += (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii]));
|
||||
}
|
||||
ii -= 2;
|
||||
}while( ii>=0 );
|
||||
return margin;
|
||||
}
|
||||
|
||||
@@ -3152,6 +3162,27 @@ constraint:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Called when a transaction starts.
|
||||
*/
|
||||
static int rtreeBeginTransaction(sqlite3_vtab *pVtab){
|
||||
Rtree *pRtree = (Rtree *)pVtab;
|
||||
assert( pRtree->inWrTrans==0 );
|
||||
pRtree->inWrTrans++;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Called when a transaction completes (either by COMMIT or ROLLBACK).
|
||||
** The sqlite3_blob object should be released at this point.
|
||||
*/
|
||||
static int rtreeEndTransaction(sqlite3_vtab *pVtab){
|
||||
Rtree *pRtree = (Rtree *)pVtab;
|
||||
pRtree->inWrTrans = 0;
|
||||
nodeBlobReset(pRtree);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** The xRename method for rtree module virtual tables.
|
||||
*/
|
||||
@@ -3173,6 +3204,7 @@ static int rtreeRename(sqlite3_vtab *pVtab, const char *zNewName){
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** This function populates the pRtree->nRowEst variable with an estimate
|
||||
** of the number of rows in the virtual table. If possible, this is based
|
||||
@@ -3232,15 +3264,15 @@ static sqlite3_module rtreeModule = {
|
||||
rtreeColumn, /* xColumn - read data */
|
||||
rtreeRowid, /* xRowid - read data */
|
||||
rtreeUpdate, /* xUpdate - write data */
|
||||
0, /* xBegin - begin transaction */
|
||||
0, /* xSync - sync transaction */
|
||||
0, /* xCommit - commit transaction */
|
||||
0, /* xRollback - rollback transaction */
|
||||
rtreeBeginTransaction, /* xBegin - begin transaction */
|
||||
rtreeEndTransaction, /* xSync - sync transaction */
|
||||
rtreeEndTransaction, /* xCommit - commit transaction */
|
||||
rtreeEndTransaction, /* xRollback - rollback transaction */
|
||||
0, /* xFindFunction - function overloading */
|
||||
rtreeRename, /* xRename - rename the table */
|
||||
0, /* xSavepoint */
|
||||
0, /* xRelease */
|
||||
0 /* xRollbackTo */
|
||||
0, /* xRollbackTo */
|
||||
};
|
||||
|
||||
static int rtreeSqlInit(
|
||||
@@ -3252,10 +3284,9 @@ static int rtreeSqlInit(
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
#define N_STATEMENT 9
|
||||
#define N_STATEMENT 8
|
||||
static const char *azSql[N_STATEMENT] = {
|
||||
/* Read and write the xxx_node table */
|
||||
"SELECT data FROM '%q'.'%q_node' WHERE nodeno = :1",
|
||||
/* Write the xxx_node table */
|
||||
"INSERT OR REPLACE INTO '%q'.'%q_node' VALUES(:1, :2)",
|
||||
"DELETE FROM '%q'.'%q_node' WHERE nodeno = :1",
|
||||
|
||||
@@ -3293,15 +3324,14 @@ static int rtreeSqlInit(
|
||||
}
|
||||
}
|
||||
|
||||
appStmt[0] = &pRtree->pReadNode;
|
||||
appStmt[1] = &pRtree->pWriteNode;
|
||||
appStmt[2] = &pRtree->pDeleteNode;
|
||||
appStmt[3] = &pRtree->pReadRowid;
|
||||
appStmt[4] = &pRtree->pWriteRowid;
|
||||
appStmt[5] = &pRtree->pDeleteRowid;
|
||||
appStmt[6] = &pRtree->pReadParent;
|
||||
appStmt[7] = &pRtree->pWriteParent;
|
||||
appStmt[8] = &pRtree->pDeleteParent;
|
||||
appStmt[0] = &pRtree->pWriteNode;
|
||||
appStmt[1] = &pRtree->pDeleteNode;
|
||||
appStmt[2] = &pRtree->pReadRowid;
|
||||
appStmt[3] = &pRtree->pWriteRowid;
|
||||
appStmt[4] = &pRtree->pDeleteRowid;
|
||||
appStmt[5] = &pRtree->pReadParent;
|
||||
appStmt[6] = &pRtree->pWriteParent;
|
||||
appStmt[7] = &pRtree->pDeleteParent;
|
||||
|
||||
rc = rtreeQueryStat1(db, pRtree);
|
||||
for(i=0; i<N_STATEMENT && rc==SQLITE_OK; i++){
|
||||
@@ -3440,7 +3470,7 @@ static int rtreeInit(
|
||||
pRtree->zDb = (char *)&pRtree[1];
|
||||
pRtree->zName = &pRtree->zDb[nDb+1];
|
||||
pRtree->nDim = (u8)((argc-4)/2);
|
||||
pRtree->nDim2 = argc - 4;
|
||||
pRtree->nDim2 = pRtree->nDim*2;
|
||||
pRtree->nBytesPerCell = 8 + pRtree->nDim2*4;
|
||||
pRtree->eCoordType = (u8)eCoordType;
|
||||
memcpy(pRtree->zDb, argv[1], nDb);
|
||||
|
||||
@@ -109,7 +109,7 @@ do_corruption_tests rtreeA-1.1 {
|
||||
}
|
||||
|
||||
do_execsql_test rtreeA-1.2.0 { DROP TABLE t1_node } {}
|
||||
do_corruption_tests rtreeA-1.2 -error "SQL logic error or missing database" {
|
||||
do_corruption_tests rtreeA-1.2 -error "database disk image is malformed" {
|
||||
1 "SELECT * FROM t1"
|
||||
2 "SELECT * FROM t1 WHERE rowid=5"
|
||||
3 "INSERT INTO t1 VALUES(1000, 1, 2, 3, 4)"
|
||||
|
||||
@@ -63,7 +63,10 @@ do_test 1.2.1 {
|
||||
INSERT INTO t1 VALUES(7, 8);
|
||||
}
|
||||
set ::log
|
||||
} {SQLITE_SCHEMA {sqlite3changeset_apply(): table t1 has 3 columns, expected 2}}
|
||||
} {}
|
||||
do_test 1.2.2 {
|
||||
db2 eval { SELECT * FROM t1 }
|
||||
} {5 6 {} 7 8 {}}
|
||||
|
||||
do_test 1.3.0 {
|
||||
execsql {
|
||||
|
||||
@@ -33,16 +33,11 @@ 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] {
|
||||
@@ -50,6 +45,12 @@ 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)
|
||||
|
||||
@@ -0,0 +1,216 @@
|
||||
# 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>=sqlite3_column_count(pIter->pConflict) ){
|
||||
if( iVal<0 || iVal>=pIter->nCol ){
|
||||
return SQLITE_RANGE;
|
||||
}
|
||||
*ppValue = sqlite3_column_value(pIter->pConflict, iVal);
|
||||
@@ -3495,7 +3495,13 @@ static int sessionInsertRow(
|
||||
|
||||
sessionAppendStr(&buf, "INSERT INTO main.", &rc);
|
||||
sessionAppendIdent(&buf, zTab, &rc);
|
||||
sessionAppendStr(&buf, " VALUES(?", &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);
|
||||
for(i=1; i<p->nCol; i++){
|
||||
sessionAppendStr(&buf, ", ?", &rc);
|
||||
}
|
||||
@@ -4041,11 +4047,17 @@ 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;
|
||||
@@ -4053,26 +4065,29 @@ 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",
|
||||
"sqlite3changeset_apply(): table %s has %d columns, "
|
||||
"expected %d or more",
|
||||
zTab, sApply.nCol, nCol
|
||||
);
|
||||
}
|
||||
else if( memcmp(sApply.abPK, abPK, nCol)!=0 ){
|
||||
else if( nCol<nMinCol || memcmp(sApply.abPK, abPK, nCol)!=0 ){
|
||||
schemaMismatch = 1;
|
||||
sqlite3_log(SQLITE_SCHEMA, "sqlite3changeset_apply(): "
|
||||
"primary key mismatch for table %s", zTab
|
||||
);
|
||||
}
|
||||
else if(
|
||||
(rc = sessionSelectRow(db, zTab, &sApply))
|
||||
|| (rc = sessionUpdateRow(db, zTab, &sApply))
|
||||
|| (rc = sessionDeleteRow(db, zTab, &sApply))
|
||||
|| (rc = sessionInsertRow(db, zTab, &sApply))
|
||||
){
|
||||
break;
|
||||
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;
|
||||
}
|
||||
}
|
||||
nTab = sqlite3Strlen30(zTab);
|
||||
}
|
||||
|
||||
@@ -319,7 +319,8 @@ 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 in each, an UPDATE record is added to the session.
|
||||
** different non-PK values in each, an UPDATE record is added to the
|
||||
** session.
|
||||
** </ul>
|
||||
**
|
||||
** To clarify, if this function is called and then a changeset constructed
|
||||
@@ -904,7 +905,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 the same number of columns as recorded in the
|
||||
** <li> The table has at least as many columns as recorded in the
|
||||
** changeset, and
|
||||
** <li> The table has primary key columns in the same position as
|
||||
** recorded in the changeset.
|
||||
@@ -949,7 +950,11 @@ 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.
|
||||
** 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.
|
||||
**
|
||||
** If no row with matching primary key values is found in the database,
|
||||
** the conflict-handler function is invoked with [SQLITE_CHANGESET_NOTFOUND]
|
||||
@@ -964,7 +969,9 @@ 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.
|
||||
** the database. If the changeset row contains fewer fields than the
|
||||
** database table, the trailing fields are populated with their default
|
||||
** values.
|
||||
**
|
||||
** If the attempt to insert the row fails because the database already
|
||||
** contains a row with the same primary key values, the conflict handler
|
||||
@@ -982,13 +989,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 non-primary key columns also match the values stored in
|
||||
** the changeset the row is updated within the target database.
|
||||
** stored in all modified 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 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 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
|
||||
** 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.
|
||||
|
||||
@@ -479,6 +479,8 @@ FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
|
||||
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
|
||||
DBFUZZ_OPT =
|
||||
KV_OPT = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ
|
||||
DBSELFTEST_OPT = -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION
|
||||
DBSELFTEST_OPT += -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
|
||||
ST_OPT = -DSQLITE_THREADSAFE=0
|
||||
|
||||
# This is the default Makefile target. The objects listed here
|
||||
@@ -898,7 +900,10 @@ 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)
|
||||
|
||||
dbselftest$(EXE): $(TOP)/test/dbselftest.c sqlite3.c
|
||||
$(TCCX) -I. $(DBSELFTEST_OPT) -o dbselftest$(EXE) $(TOP)/test/dbselftest.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 This\sis\san\sexperimental\spatch\sthat\sensures\sthat\sall\scursors\shave\stheir\sposition\nsaved\sprior\sto\sstarting\sa\sROLLBACK\sTO.
|
||||
D 2017-02-02T00:46:55.000
|
||||
F Makefile.in 5f415e7867296d678fed2e6779aea10c1318b4bc
|
||||
C Proof\sof\sconcept\sfor\sa\s"PRAGMA\svdbe_cycle_limit=N"\scommand.\s\sWhen\sN>0,\ninvoke\ssqlite3_interrupt()\swhenever\sany\sbyte\scode\sprogram\suses\smore\sthan\nN\svirtual\smachine\scycles.
|
||||
D 2017-02-21T13:29:18.463
|
||||
F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc ba953c8921fc7e18333f61898007206de7e23964
|
||||
F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2
|
||||
F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7
|
||||
F VERSION cddd8d88dc8202afa0ebc96da61fc4acbd1e96a5
|
||||
F VERSION 3605fa447e4623f5ff4a6adc97b1fde9a257b8f2
|
||||
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 3f29e0fc2a78e113250d79a5da375c1d8d8c06b0
|
||||
F autoconf/Makefile.msc 3de603bcec5c07462801a20fd7dc1b871400af99
|
||||
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 fcfa56d5d66668c9263dc007724f62acff06dc83 x
|
||||
F configure b15d030a8ae2e672d76c97b6667dacb98934a467 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 5a8cafedffd101e9946f8909ecf8d34aaa383b4d
|
||||
F ext/fts3/fts3.c c4d7eecb12de9749851bcab6e5ca616a5803047a
|
||||
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
|
||||
F ext/fts3/fts3Int.h 89d0bd4595a0de384dac78e94b803de12586e8dd
|
||||
F ext/fts3/fts3Int.h eb2502000148e80913b965db3e59f29251266d0a
|
||||
F ext/fts3/fts3_aux.c 9edc3655fcb287f0467d0a4b886a01c6185fe9f1
|
||||
F ext/fts3/fts3_expr.c dfd571a24412779ac01f25c01d888c6ef7b2d0ef
|
||||
F ext/fts3/fts3_hash.c 29b986e43f4e9dd40110eafa377dc0d63c422c60
|
||||
@@ -98,7 +98,7 @@ 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 b2eda36e0f224365c8e23dc8f559311834f1c13f
|
||||
F ext/fts5/fts5Int.h c629b24d2b92b99596f3b8e82289fddca06df6e1
|
||||
F ext/fts5/fts5_aux.c 67acf8d51723cf28ffc3828210ba662df4b8d267
|
||||
F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd
|
||||
F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857
|
||||
@@ -222,7 +222,7 @@ F ext/misc/remember.c 8440f8d0b452c5cdefb62b57135ccd1267aa729d
|
||||
F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a
|
||||
F ext/misc/scrub.c 1c5bfb8b0cd18b602fcb55755e84abf0023ac2fb
|
||||
F ext/misc/series.c e11e534ada797d5b816d7e7a93c022306563ca35
|
||||
F ext/misc/sha1.c b2e4eb8e26f09701ec15548395baf698f00e5895
|
||||
F ext/misc/sha1.c 0b9e9b855354910d3ca467bf39099d570e73db56
|
||||
F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52
|
||||
F ext/misc/spellfix.c a4723b6aff748a417b5091b68a46443265c40f0d
|
||||
F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512
|
||||
@@ -264,7 +264,7 @@ 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 70f2488eef5c04dccf15a52cbd4961492124f825
|
||||
F ext/rtree/rtree.c 3f3a595dba485e340246fa2c8ba330a6b9768b00
|
||||
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
|
||||
F ext/rtree/rtree1.test 42dadfc7b44a436cd74a1bebc0b9b689e4eaf7ec
|
||||
F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba
|
||||
@@ -275,7 +275,7 @@ F ext/rtree/rtree6.test 773a90db2dce6a8353dd0d5b64bca69b29761196
|
||||
F ext/rtree/rtree7.test 1fa710b9e6bf997a0c1a537b81be7bb6fded1971
|
||||
F ext/rtree/rtree8.test db79c812f9e4a11f9b1f3f9934007884610a713a
|
||||
F ext/rtree/rtree9.test b5eb13849545dfd271a54ff16784cb00d8792aea
|
||||
F ext/rtree/rtreeA.test ace05e729a36e342d40cf94e9efc7b4723d9dcdf
|
||||
F ext/rtree/rtreeA.test ac8b503931f2f397cc3c3303354e1e085dcadb86
|
||||
F ext/rtree/rtreeB.test c85f9ce78766c4e68b8b89fbf2979ee9cfa82b4e
|
||||
F ext/rtree/rtreeC.test c0a9c67f2efa98b6fae12acb8a28348d231a481d
|
||||
F ext/rtree/rtreeD.test bdfaaf26df8b4eea7364039aca9150bc1e1f8825
|
||||
@@ -290,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 a7a9ce59b8d1e49e2cc23d81421ac485be0eea01
|
||||
F ext/session/session3.test ce9ce3dfa489473987f899e9f6a0f2db9bde3479
|
||||
F ext/session/session4.test 457b02bdc349eb01151e54de014df77abd3c08c8
|
||||
F ext/session/session5.test 716bc6fafd625ce60dfa62ae128971628c1a1169
|
||||
F ext/session/session6.test 443789bc2fca12e4f7075cf692c60b8a2bea1a26
|
||||
@@ -303,13 +303,14 @@ 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 9b696a341cf1d3744823715ed92bb19749b6c3d4
|
||||
F ext/session/session_common.tcl 7776eda579773113b30c7abfd4545c445228cb73
|
||||
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 c61a43396368ec00dc127f7bc647e9bd6a4ee5fb
|
||||
F ext/session/sqlite3session.h 9345166bd8f80562145586cf817f707de5ecada2
|
||||
F ext/session/sqlite3session.c 13642d9c754cc18f17e141f82860d269e2adf920
|
||||
F ext/session/sqlite3session.h d4db650adfcc7a4360e9f12a09c2d117b1db6b53
|
||||
F ext/session/test_session.c eb0bd6c1ea791c1d66ee4ef94c16500dad936386
|
||||
F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220
|
||||
F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04
|
||||
@@ -317,7 +318,7 @@ F ext/userauth/userauth.c 3410be31283abba70255d71fd24734e017a4497f
|
||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
|
||||
F main.mk afc52937b4e5fe08678e8d5a4fe4487d44e3bc61
|
||||
F main.mk 08e0b151abb46353c677ac4974b50c6077f85eee
|
||||
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
|
||||
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
|
||||
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
|
||||
@@ -336,17 +337,17 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792
|
||||
F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b
|
||||
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
|
||||
F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca
|
||||
F src/btree.c 9fe65ab418d99e80289f024016b5e5e74c3059dd
|
||||
F src/btree.c 3ae66974881e74df9909093818b4c3428f8d7982
|
||||
F src/btree.h e6d352808956ec163a17f832193a3e198b3fb0ac
|
||||
F src/btreeInt.h 10c4b77c2fb399580babbcc7cf652ac10dba796e
|
||||
F src/btreeInt.h cd55d39d9916270837a88c12e701047cba0729b0
|
||||
F src/build.c 9e799f1edd910dfa8a0bc29bd390d35d310596af
|
||||
F src/callback.c 2e76147783386374bf01b227f752c81ec872d730
|
||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||
F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a
|
||||
F src/ctime.c a9984df73898c042a5cfc8f9d8e7723d02bc35c9
|
||||
F src/date.c dc3f1391d9297f8c748132813aaffcb117090d6e
|
||||
F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d
|
||||
F src/delete.c 0d9d5549d42e79ce4d82ff1db1e6c81e36d2f67c
|
||||
F src/expr.c d7ef6fdb70bc18259d7d36b22aa0bc4845c5c5b9
|
||||
F src/expr.c 8a29e9b72d4b642189999c41782cd6c5bc43512f
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae
|
||||
F src/func.c c67273e1ec08abbdcc14c189892a3ff6eeece86b
|
||||
@@ -355,13 +356,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 444354c23d4d140a57d6eb46f34e376a7f8f62e8
|
||||
F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e
|
||||
F src/insert.c 3ed64afc49c0a2221e397b9f65d231ffbef506fe
|
||||
F src/legacy.c e88ed13c2d531decde75d42c2e35623fb9ce3cb0
|
||||
F src/loadext.c a68d8d1d14cf7488bb29dc5311cb1ce9a4404258
|
||||
F src/main.c e207b81542d13b9f13d61e78ca441f9781f055b0
|
||||
F src/malloc.c fc1b9f445290f2145da48fc08730c26e6082b640
|
||||
F src/malloc.c d0a1474236486165bcb349af82e2a6560178bf7b
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b
|
||||
F src/mem1.c fd7cd6fe21d46fe0a4186367dd8dc26d87b787eb
|
||||
F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
|
||||
F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a
|
||||
F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944
|
||||
@@ -371,44 +372,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 5e6fe1c298fb5a8a15aaed4161d5759311431c17
|
||||
F src/mutex_w32.c a898fa969823b100c0f5fdc57e54c9a1e419ab4d
|
||||
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 cf90abd4e50d9f56d2c20ce8e005aff55d7bd8e9
|
||||
F src/os_win.c 2a6c73eef01c51a048cc4ddccd57f981afbec18a
|
||||
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
||||
F src/pager.c ff1232b3088a39806035ecfac4fffeb22717d80b
|
||||
F src/pager.h f2a99646c5533ffe11afa43e9e0bea74054e4efa
|
||||
F src/parse.y 591704fce84f814d9a3642774c1f011d38f4149c
|
||||
F src/pcache.c 51070ec9b8251bbf9c6ea3d35fd96a458752929e
|
||||
F src/parse.y af8830094f4aecb91cb69721f3601ad10c36abc4
|
||||
F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870
|
||||
F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490
|
||||
F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953
|
||||
F src/pragma.c 7831956012f5d764761fbd023e59b0ffc08f5e8d
|
||||
F src/pragma.h 61aa5389118594bebb28120a6720401aee34ce1a
|
||||
F src/pragma.c 9180cce9a16e0835c6f7d0aa42d8938ce59c2011
|
||||
F src/pragma.h 1ec44ee89a43e65bf70c9ef4ef066df217b9ab3f
|
||||
F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a
|
||||
F src/printf.c ff10a9b9902cd2afe5f655f3013c6307d969b1fd
|
||||
F src/printf.c 67427bbee66d891fc6f6f5aada857e9cdb368c1c
|
||||
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
|
||||
F src/resolve.c f9bc0de45a30a450da47b3766de00be89bf9be79
|
||||
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
|
||||
F src/select.c 3856db523b942062bca8722ba03b61c324ff94d6
|
||||
F src/shell.c a84e453c213f3e0d6935a582024da4e242f85a19
|
||||
F src/select.c d12f3539f80db38b09015561b569e0eb1c4b6c5f
|
||||
F src/shell.c bf976d5301be9d8a4c52852c97909cc9a41ee20d
|
||||
F src/sqlite.h.in 751ff125eb159c8f92c182b8df980a5e4f50e966
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae
|
||||
F src/sqliteInt.h 3724c48e82605b471bbf7e41109b5850c6e89f31
|
||||
F src/sqliteInt.h 46fe8e5aee3825d77fa771216ef263dc947030e7
|
||||
F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247
|
||||
F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1
|
||||
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
|
||||
F src/tclsqlite.c 418f5e5e0840425a7e5b33f3600dccd378a57549
|
||||
F src/tclsqlite.c 6c2151b6d8d98e183a04466d40df8889c0574d79
|
||||
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 55aa2775c154415dcf4ed7cd1e19a193122b3a02
|
||||
F src/test6.c 121060d2e79a4f5047eb12b5135b23a6a7a5af01
|
||||
F src/test7.c 5612e9aecf934d6df7bba6ce861fdf5ba5456010
|
||||
F src/test8.c 4f4904721167b32f7a4fa8c7b32a07a673d6cc86
|
||||
F src/test9.c 12e5ba554d2d1cbe0158f6ab3f7ffcd7a86ee4e5
|
||||
@@ -416,7 +417,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 6a4c7920d1d9c6cc0f7aa50c89c4f80016aeda83
|
||||
F src/test_blob.c f65ac717da2618691cf9dad094e6da0219dcd208
|
||||
F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274
|
||||
F src/test_config.c 83179ea845479b5be9a651d014649e3f2722a1fe
|
||||
F src/test_delete.c af7eab5702f853fb1c62a5f7665e2234cf1ae17b
|
||||
@@ -458,26 +459,26 @@ F src/treeview.c 4e44ade3bfe59d82005039f72e09333ce2b4162c
|
||||
F src/trigger.c c9f0810043b265724fdb1bdd466894f984dfc182
|
||||
F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58
|
||||
F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c
|
||||
F src/util.c a88b0466fddf445ce752226d4698ca3faada620a
|
||||
F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16
|
||||
F src/vdbe.c e7b1e860140f1d1803c6f4176b1e8f3801f3a290
|
||||
F src/util.c ca8440ede81e155d15cff7c101654f60b55a9ae6
|
||||
F src/vacuum.c 1fe4555cd8c9b263afb85b5b4ee3a4a4181ad569
|
||||
F src/vdbe.c 16f378640570c24442fd7191b136b5d6380f5c7b
|
||||
F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c
|
||||
F src/vdbeInt.h 4e4b15b2e1330e1636e4e01974eab2b0b985092f
|
||||
F src/vdbeapi.c 3e4a8893feeb78620f4aac4ac5b85d92255b97e1
|
||||
F src/vdbeaux.c b9a36e530e6525ca9d9a685bc7b1d01fa77b5cf8
|
||||
F src/vdbeaux.c 4122458d33318ab039c4b5da1ca4e7c9221c38e4
|
||||
F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9
|
||||
F src/vdbemem.c 3b5a9a5b375458d3e12a50ae1aaa41eeec2175fd
|
||||
F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face
|
||||
F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834
|
||||
F src/vtab.c c4bbe0f870f52036553f8098aee0703997f0577a
|
||||
F src/vtab.c 007513c2ef52472fcdea6a741683d50662e82790
|
||||
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c 40c543f0a2195d1b0dc88ef12142bea690009344
|
||||
F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71
|
||||
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 src/where.c 01baf58b72f3ddb7793cdee2871f751e3e09b35e
|
||||
F src/whereInt.h c0b092180f04608d80c258174b0a14a1f9c8d02f
|
||||
F src/wherecode.c 677e95413c472c0b413023b6b69a47f40fce1b04
|
||||
F src/whereexpr.c 130cdd1a43af71b19755270fb1224874cf55158c
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
|
||||
F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
|
||||
@@ -606,7 +607,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 4ef10844eba5213bd262f4d96784d7fcda114afe
|
||||
F test/corruptC.test 46ec43bd90a02fd7b37ad8a7a949c55aa5717f89
|
||||
F test/corruptD.test b3c205fac7952b1de645ce44bb02335cd9e3e040
|
||||
F test/corruptE.test 82ccf4f8f543fdbedd4aa42c709cb077f7374c62
|
||||
F test/corruptF.test be9fde98e4c93648f1ba52b74e5318edc8f59fe4
|
||||
@@ -634,7 +635,8 @@ F test/ctime.test ff6c38e822459d6ca743c34901caf57740b08b54
|
||||
F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856
|
||||
F test/cursorhint2.test 8457e93d97f665f23f97cdbc8477d16e3480331b
|
||||
F test/date.test a6a5a48b90907bca9fbcc79a30be5a715c1ab2fc
|
||||
F test/dbfuzz.c 8cc2bdb818b4483a052f9f80f96be74cbd9a6e1d
|
||||
F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e
|
||||
F test/dbselftest.c b2e6cfac59066dbcb7334b66304bb15a5508dd42
|
||||
F test/dbstatus.test 73149851b3aff14fc6db478e58f9083a66422cf5
|
||||
F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab
|
||||
F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d
|
||||
@@ -674,6 +676,7 @@ 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
|
||||
@@ -850,7 +853,7 @@ F test/incrblob2.test a5ce5ed1d0b01e2ed347245a21170372528af0a5
|
||||
F test/incrblob3.test d8d036fde015d4a159cd3cbae9d29003b37227a4
|
||||
F test/incrblob4.test 21a52a6843a56cdcce968c6a86b72a7066d0e6ba
|
||||
F test/incrblob_err.test 69f9247fed50278d48ea710d1a8f9cdb09e4c0b8
|
||||
F test/incrblobfault.test 280474078f6da9e732cd2a215d3d854969014b6e
|
||||
F test/incrblobfault.test 74dd8ac108304cea0b4a0df6df63a1567e558758
|
||||
F test/incrcorrupt.test 6c567fbf870aa9e91866fe52ce6f200cd548939a
|
||||
F test/incrvacuum.test d2a6ddf5e429720b5fe502766af747915ccf6c32
|
||||
F test/incrvacuum2.test 7d26cfda66c7e55898d196de54ac4ec7d86a4e3d
|
||||
@@ -865,7 +868,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 7d243fac508b4a99fb900ffe34eb488312cfce84
|
||||
F test/indexexpr1.test 038b3befa74e5a75126b6e9dd2ae5df61c1c7cf7
|
||||
F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d
|
||||
F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
|
||||
F test/insert.test 38742b5e9601c8f8d76e9b7555f7270288c2d371
|
||||
@@ -902,7 +905,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 7a3c38ee56b9cc45dc5a5edc50fd9bc9425659a9
|
||||
F test/kvtest.c b9a9822dda05a1aa481215a52e2fc93cd8b22ee5
|
||||
F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
|
||||
F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
|
||||
F test/like.test 0603f4fa0dad50987f70032c05800cbfa8985302
|
||||
@@ -926,7 +929,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 02ed7c5313f0a68d95f2dfca8c8962132bd1f04b
|
||||
F test/malloc5.test 192d0b5ee1d023a07d5164c34cf47d010da73da1
|
||||
F test/malloc6.test 2f039d9821927eacae43e1831f815e157659a151
|
||||
F test/malloc7.test 7c68a32942858bc715284856c5507446bba88c3a
|
||||
F test/malloc8.test 9b7a3f8cb9cf0b12fff566e80a980b1767bd961d
|
||||
@@ -1013,13 +1016,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 cd0b7bc04bf5e50d3a993d24c834d591f7d4f5fe
|
||||
F test/permutations.test 46ad98770d3c04ce2418cab2cc527647bfe961a7
|
||||
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 0b61566dd1c0f0b802f59dffa228c5dc5aa6b054
|
||||
F test/printf2.test 9e6db85f81c63f2367c34a9d7db384088bd374ad
|
||||
F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb
|
||||
F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
|
||||
F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca
|
||||
@@ -1135,7 +1138,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 02fe15bb784c5276a083ffe9969cc51e0bce7644
|
||||
F test/speedtest1.c 7b1ab42b097b484c18d99e1d1c71a6a0c9c87a7a
|
||||
F test/spellfix.test f9c1f431e2c096c8775fec032952320c0e4700db
|
||||
F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3
|
||||
F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33
|
||||
@@ -1155,7 +1158,7 @@ F test/symlink.test c9ebe7330d228249e447038276bfc8a7b22f4849
|
||||
F test/sync.test 2f84bdbc2b2df1fcb0220575b4b9f8cea94b7529
|
||||
F test/syscall.test f59ba4e25f7ba4a4c031026cc2ef8b6e4b4c639c
|
||||
F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04
|
||||
F test/tabfunc01.test 8b2ef53caa37854864c89e1e57e8a10efd4f5e43
|
||||
F test/tabfunc01.test 699251cb99651415218a891384510a685c7ab012
|
||||
F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f
|
||||
F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
|
||||
F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
|
||||
@@ -1167,7 +1170,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 2a49c1aff731f380ea640106377e19611a1443ae
|
||||
F test/tester.tcl 67835ac17e90055f24a9cf52e5c5bce0dd511c74
|
||||
F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5
|
||||
F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
|
||||
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
|
||||
@@ -1203,7 +1206,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 813779f8888f3ca226df656c4eef078f9635f3c9
|
||||
F test/tkt-78e04e52ea.test 1b2e6bf4f1d9887b216b6da774e5f25915ec8118
|
||||
F test/tkt-7a31705a7e6.test e75a2bba4eec801b92c8040eb22096ac6d35e844
|
||||
F test/tkt-7bbfb7d442.test 7b2cd79c7a17ae6750e75ec1a7846712a69c9d18
|
||||
F test/tkt-80ba201079.test 105a721e6aad0ae3c5946d7615d1e4d03f6145b8
|
||||
@@ -1372,7 +1375,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 7c4b81abd88361ada9cbe414c459efca26be6bda
|
||||
F test/vtab1.test ed4a576231d8a36e70fd18e2b79b621b31e7f22a
|
||||
F test/vtab2.test f8cd1bb9aba7143eba97812d9617880a36d247ad
|
||||
F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e
|
||||
F test/vtab4.test 8e73ed268f3d596bc3590f45fc948fb40f28e9c3
|
||||
@@ -1387,7 +1390,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 a2912cd3ea3386aecc3cb74ebfdfcc4e6d4b7dd3
|
||||
F test/vtabH.test 5f9253eb9e41ba9fe94f4aa3e9230191893d7764
|
||||
F test/vtabI.test 751b07636700dbdea328e4265b6077ccd6811a3f
|
||||
F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5
|
||||
F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
|
||||
@@ -1484,17 +1487,18 @@ 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 2f12f7fa8858bbe61cf81820a2da96c79ed1ca8d
|
||||
F tool/mkmsvcmin.tcl 95b37e202cbed873aa8ffdbb493b9db45927be2b
|
||||
F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c
|
||||
F tool/mkopcodeh.tcl a01d2c1d8a6205b03fc635adf3735b4c523befd3
|
||||
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
|
||||
F tool/mkpragmatab.tcl ebb4bfcd2f8010e0a3934b6118db4b5f2f5edf5c
|
||||
F tool/mkpragmatab.tcl b6ef1997fbc019015cb3f1b078c38b884d1ce4b6
|
||||
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
|
||||
F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb
|
||||
F tool/mksqlite3c.tcl 06b2e6a0f21cc0a5d70fbbd136b3e0a96470645e
|
||||
F tool/mksqlite3h.tcl c006c4e5da57c649b24b689511dcd270dd7b0249
|
||||
F tool/mksqlite3h.tcl b9836752c3d08f9fab2dfc0017ca9fd5d90ac863
|
||||
F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b
|
||||
F tool/mkvsix.tcl b9e0777a213c23156b6542842c238479e496ebf5
|
||||
F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091
|
||||
@@ -1552,10 +1556,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 0c66cf0f0a9ada2ddcb8d61001ef791b86226416
|
||||
R 329580c21139f900f64001f6acfc9557
|
||||
T *branch * savepoint-rollback
|
||||
T *sym-savepoint-rollback *
|
||||
P 1589db012ef1389bf84399fccf96d143b2ac4c0f
|
||||
R 927fcfe986f9d231ee2a8f2fc2e00fd4
|
||||
T *branch * vdbe_cycle_limit
|
||||
T *sym-vdbe_cycle_limit *
|
||||
T -sym-trunk *
|
||||
U drh
|
||||
Z 5087946e64391fb6ac59f69d722efdd6
|
||||
Z 42d28699ae4b43243cadb703ee72bd58
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
01d97e5b6502b1811b52a681f445e1aaae6c0ee6
|
||||
9626b41e6ef70631cc1867315e409a2a92ce2a53
|
||||
+2
-2
@@ -4776,7 +4776,7 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){
|
||||
pCur, pCur->curPagerFlags);
|
||||
}
|
||||
|
||||
#if SQLITE_DEBUG
|
||||
#ifdef 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
|
||||
@@ -6163,7 +6163,7 @@ static int fillInCell(
|
||||
** Use a call to btreeParseCellPtr() to verify that the values above
|
||||
** were computed correctly.
|
||||
*/
|
||||
#if SQLITE_DEBUG
|
||||
#ifdef SQLITE_DEBUG
|
||||
{
|
||||
CellInfo info;
|
||||
pPage->xParseCell(pPage, pCell, &info);
|
||||
|
||||
+2
-4
@@ -692,11 +692,9 @@ struct IntegrityCk {
|
||||
*/
|
||||
#if SQLITE_BYTEORDER==4321
|
||||
# define get2byteAligned(x) (*(u16*)(x))
|
||||
#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
|
||||
&& GCC_VERSION>=4008000
|
||||
#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4008000
|
||||
# define get2byteAligned(x) __builtin_bswap16(*(u16*)(x))
|
||||
#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
|
||||
&& defined(_MSC_VER) && _MSC_VER>=1300
|
||||
#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
|
||||
# define get2byteAligned(x) _byteswap_ushort(*(u16*)(x))
|
||||
#else
|
||||
# define get2byteAligned(x) ((x)[0]<<8 | (x)[1])
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ static const char * const azCompileOpt[] = {
|
||||
#if SQLITE_COVERAGE_TEST
|
||||
"COVERAGE_TEST",
|
||||
#endif
|
||||
#if SQLITE_DEBUG
|
||||
#ifdef SQLITE_DEBUG
|
||||
"DEBUG",
|
||||
#endif
|
||||
#if SQLITE_DEFAULT_LOCKING_MODE
|
||||
|
||||
+48
-29
@@ -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( NEVER(aff==0) ){
|
||||
}else if( aff==0 ){
|
||||
aff = SQLITE_AFF_BLOB;
|
||||
}
|
||||
return aff;
|
||||
@@ -1418,33 +1418,41 @@ IdList *sqlite3IdListDup(sqlite3 *db, IdList *p){
|
||||
}
|
||||
return pNew;
|
||||
}
|
||||
Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){
|
||||
Select *pNew, *pPrior;
|
||||
Select *sqlite3SelectDup(sqlite3 *db, Select *pDup, int flags){
|
||||
Select *pRet = 0;
|
||||
Select *pNext = 0;
|
||||
Select **pp = &pRet;
|
||||
Select *p;
|
||||
|
||||
assert( db!=0 );
|
||||
if( p==0 ) return 0;
|
||||
pNew = sqlite3DbMallocRawNN(db, sizeof(*p) );
|
||||
if( pNew==0 ) return 0;
|
||||
pNew->pEList = sqlite3ExprListDup(db, p->pEList, flags);
|
||||
pNew->pSrc = sqlite3SrcListDup(db, p->pSrc, flags);
|
||||
pNew->pWhere = sqlite3ExprDup(db, p->pWhere, flags);
|
||||
pNew->pGroupBy = sqlite3ExprListDup(db, p->pGroupBy, flags);
|
||||
pNew->pHaving = sqlite3ExprDup(db, p->pHaving, flags);
|
||||
pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, flags);
|
||||
pNew->op = p->op;
|
||||
pNew->pPrior = pPrior = sqlite3SelectDup(db, p->pPrior, flags);
|
||||
if( pPrior ) pPrior->pNext = pNew;
|
||||
pNew->pNext = 0;
|
||||
pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags);
|
||||
pNew->pOffset = sqlite3ExprDup(db, p->pOffset, flags);
|
||||
pNew->iLimit = 0;
|
||||
pNew->iOffset = 0;
|
||||
pNew->selFlags = p->selFlags & ~SF_UsesEphemeral;
|
||||
pNew->addrOpenEphm[0] = -1;
|
||||
pNew->addrOpenEphm[1] = -1;
|
||||
pNew->nSelectRow = p->nSelectRow;
|
||||
pNew->pWith = withDup(db, p->pWith);
|
||||
sqlite3SelectSetName(pNew, p->zSelName);
|
||||
return pNew;
|
||||
for(p=pDup; p; p=p->pPrior){
|
||||
Select *pNew = sqlite3DbMallocRawNN(db, sizeof(*p) );
|
||||
if( pNew==0 ) break;
|
||||
pNew->pEList = sqlite3ExprListDup(db, p->pEList, flags);
|
||||
pNew->pSrc = sqlite3SrcListDup(db, p->pSrc, flags);
|
||||
pNew->pWhere = sqlite3ExprDup(db, p->pWhere, flags);
|
||||
pNew->pGroupBy = sqlite3ExprListDup(db, p->pGroupBy, flags);
|
||||
pNew->pHaving = sqlite3ExprDup(db, p->pHaving, flags);
|
||||
pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, flags);
|
||||
pNew->op = p->op;
|
||||
pNew->pNext = pNext;
|
||||
pNew->pPrior = 0;
|
||||
pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags);
|
||||
pNew->pOffset = sqlite3ExprDup(db, p->pOffset, flags);
|
||||
pNew->iLimit = 0;
|
||||
pNew->iOffset = 0;
|
||||
pNew->selFlags = p->selFlags & ~SF_UsesEphemeral;
|
||||
pNew->addrOpenEphm[0] = -1;
|
||||
pNew->addrOpenEphm[1] = -1;
|
||||
pNew->nSelectRow = p->nSelectRow;
|
||||
pNew->pWith = withDup(db, p->pWith);
|
||||
sqlite3SelectSetName(pNew, p->zSelName);
|
||||
*pp = pNew;
|
||||
pp = &pNew->pPrior;
|
||||
pNext = pNew;
|
||||
}
|
||||
|
||||
return pRet;
|
||||
}
|
||||
#else
|
||||
Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){
|
||||
@@ -2359,7 +2367,7 @@ static char *exprINAffinity(Parse *pParse, Expr *pExpr){
|
||||
char *zRet;
|
||||
|
||||
assert( pExpr->op==TK_IN );
|
||||
zRet = sqlite3DbMallocZero(pParse->db, nVal+1);
|
||||
zRet = sqlite3DbMallocRaw(pParse->db, nVal+1);
|
||||
if( zRet ){
|
||||
int i;
|
||||
for(i=0; i<nVal; i++){
|
||||
@@ -3264,7 +3272,7 @@ void sqlite3ExprCodeGetColumnToReg(
|
||||
void sqlite3ExprCacheClear(Parse *pParse){
|
||||
int i;
|
||||
|
||||
#if SQLITE_DEBUG
|
||||
#ifdef SQLITE_DEBUG
|
||||
if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
|
||||
printf("CLEAR\n");
|
||||
}
|
||||
@@ -4672,6 +4680,17 @@ 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
|
||||
|
||||
+10
-4
@@ -1527,6 +1527,9 @@ 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
|
||||
@@ -1682,8 +1685,11 @@ 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; i>1 && pTab->aCol[i-1].pDflt==0; i--){}
|
||||
sqlite3VdbeChangeP5(v, i);
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1973,7 +1979,7 @@ static int xferOptimization(
|
||||
return 0; /* tab1 must not have triggers */
|
||||
}
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
if( pDest->tabFlags & TF_Virtual ){
|
||||
if( IsVirtual(pDest) ){
|
||||
return 0; /* tab1 must not be a virtual table */
|
||||
}
|
||||
#endif
|
||||
@@ -2035,7 +2041,7 @@ static int xferOptimization(
|
||||
return 0; /* source and destination must both be WITHOUT ROWID or not */
|
||||
}
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
if( pSrc->tabFlags & TF_Virtual ){
|
||||
if( IsVirtual(pSrc) ){
|
||||
return 0; /* tab2 must not be a virtual table */
|
||||
}
|
||||
#endif
|
||||
|
||||
+2
-1
@@ -73,7 +73,7 @@ int sqlite3_exec(
|
||||
(SQLITE_DONE==rc && !callbackIsInit
|
||||
&& db->flags&SQLITE_NullCallback)) ){
|
||||
if( !callbackIsInit ){
|
||||
azCols = sqlite3DbMallocZero(db, 2*nCol*sizeof(const char*) + 1);
|
||||
azCols = sqlite3DbMallocRaw(db, (2*nCol+1)*sizeof(const char*));
|
||||
if( azCols==0 ){
|
||||
goto exec_out;
|
||||
}
|
||||
@@ -94,6 +94,7 @@ 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
|
||||
|
||||
+14
-6
@@ -219,12 +219,20 @@ static void sqlite3MallocAlarm(int nByte){
|
||||
*/
|
||||
static void mallocWithAlarm(int n, void **pp){
|
||||
void *p;
|
||||
int nFull = 0;
|
||||
int nFull;
|
||||
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);
|
||||
|
||||
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);
|
||||
@@ -232,11 +240,11 @@ static void mallocWithAlarm(int n, void **pp){
|
||||
mem0.nearlyFull = 0;
|
||||
}
|
||||
}
|
||||
p = sqlite3GlobalConfig.m.xMalloc(n);
|
||||
p = sqlite3GlobalConfig.m.xMalloc(nFull);
|
||||
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
|
||||
if( p==0 && mem0.alarmThreshold>0 ){
|
||||
sqlite3MallocAlarm(nFull);
|
||||
p = sqlite3GlobalConfig.m.xMalloc(n);
|
||||
p = sqlite3GlobalConfig.m.xMalloc(nFull);
|
||||
}
|
||||
#endif
|
||||
if( p ){
|
||||
@@ -410,7 +418,7 @@ int sqlite3MallocSize(void *p){
|
||||
int sqlite3DbMallocSize(sqlite3 *db, void *p){
|
||||
assert( p!=0 );
|
||||
if( db==0 || !isLookaside(db,p) ){
|
||||
#if SQLITE_DEBUG
|
||||
#ifdef SQLITE_DEBUG
|
||||
if( db==0 ){
|
||||
assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
|
||||
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
|
||||
@@ -471,7 +479,7 @@ void sqlite3DbFree(sqlite3 *db, void *p){
|
||||
}
|
||||
if( isLookaside(db, p) ){
|
||||
LookasideSlot *pBuf = (LookasideSlot*)p;
|
||||
#if SQLITE_DEBUG
|
||||
#ifdef SQLITE_DEBUG
|
||||
/* Trash all content in the buffer being freed */
|
||||
memset(p, 0xaa, db->lookaside.sz);
|
||||
#endif
|
||||
|
||||
+4
-2
@@ -125,7 +125,9 @@ static malloc_zone_t* _sqliteZone_;
|
||||
*/
|
||||
static void *sqlite3MemMalloc(int nByte){
|
||||
#ifdef SQLITE_MALLOCSIZE
|
||||
void *p = SQLITE_MALLOC( nByte );
|
||||
void *p;
|
||||
testcase( ROUND8(nByte)==nByte );
|
||||
p = SQLITE_MALLOC( nByte );
|
||||
if( p==0 ){
|
||||
testcase( sqlite3GlobalConfig.xLog!=0 );
|
||||
sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte);
|
||||
@@ -134,7 +136,7 @@ static void *sqlite3MemMalloc(int nByte){
|
||||
#else
|
||||
sqlite3_int64 *p;
|
||||
assert( nByte>0 );
|
||||
nByte = ROUND8(nByte);
|
||||
testcase( ROUND8(nByte)!=nByte );
|
||||
p = SQLITE_MALLOC( nByte+8 );
|
||||
if( p ){
|
||||
p[0] = nByte;
|
||||
|
||||
+7
-8
@@ -87,8 +87,7 @@ void sqlite3MemoryBarrier(void){
|
||||
SQLITE_MEMORY_BARRIER;
|
||||
#elif defined(__GNUC__)
|
||||
__sync_synchronize();
|
||||
#elif !defined(SQLITE_DISABLE_INTRINSIC) && \
|
||||
defined(_MSC_VER) && _MSC_VER>=1300
|
||||
#elif MSVC_VERSION>=1300
|
||||
_ReadWriteBarrier();
|
||||
#elif defined(MemoryBarrier)
|
||||
MemoryBarrier();
|
||||
@@ -299,8 +298,8 @@ static void winMutexEnter(sqlite3_mutex *p){
|
||||
p->owner = tid;
|
||||
p->nRef++;
|
||||
if( p->trace ){
|
||||
OSTRACE(("ENTER-MUTEX tid=%lu, mutex=%p (%d), nRef=%d\n",
|
||||
tid, p, p->trace, p->nRef));
|
||||
OSTRACE(("ENTER-MUTEX tid=%lu, mutex(%d)=%p (%d), nRef=%d\n",
|
||||
tid, p->id, p, p->trace, p->nRef));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -342,8 +341,8 @@ static int winMutexTry(sqlite3_mutex *p){
|
||||
#endif
|
||||
#ifdef SQLITE_DEBUG
|
||||
if( p->trace ){
|
||||
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)));
|
||||
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)));
|
||||
}
|
||||
#endif
|
||||
return rc;
|
||||
@@ -371,8 +370,8 @@ static void winMutexLeave(sqlite3_mutex *p){
|
||||
LeaveCriticalSection(&p->mutex);
|
||||
#ifdef SQLITE_DEBUG
|
||||
if( p->trace ){
|
||||
OSTRACE(("LEAVE-MUTEX tid=%lu, mutex=%p (%d), nRef=%d\n",
|
||||
tid, p, p->trace, p->nRef));
|
||||
OSTRACE(("LEAVE-MUTEX tid=%lu, mutex(%d)=%p (%d), nRef=%d\n",
|
||||
tid, p->id, p, p->trace, p->nRef));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
+45
-7
@@ -352,7 +352,34 @@ struct winVfsAppData {
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef SQLITE_WIN32_HEAP_CREATE
|
||||
# define SQLITE_WIN32_HEAP_CREATE (TRUE)
|
||||
# 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))
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -361,25 +388,36 @@ 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) + 4194304)
|
||||
# define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_WIN32_CACHE_SIZE) * \
|
||||
(SQLITE_DEFAULT_PAGE_SIZE) + \
|
||||
(SQLITE_WIN32_HEAP_INIT_EXTRA))
|
||||
#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
|
||||
|
||||
/*
|
||||
@@ -387,7 +425,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
|
||||
|
||||
|
||||
|
||||
+1
-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(X). {A=X;/*A-overwrites-X*/}
|
||||
likeop(A) ::= LIKE_KW|MATCH(A).
|
||||
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) );
|
||||
*/
|
||||
#if SQLITE_DEBUG
|
||||
#ifdef SQLITE_DEBUG
|
||||
int sqlite3PcachePageSanity(PgHdr *pPg){
|
||||
PCache *pCache;
|
||||
assert( pPg!=0 );
|
||||
|
||||
@@ -295,6 +295,14 @@ static const PragmaName *pragmaLocate(const char *zName){
|
||||
return lwr>upr ? 0 : &aPragmaName[mid];
|
||||
}
|
||||
|
||||
/*
|
||||
** A progress handler callback that interrupts.
|
||||
*/
|
||||
static int interruptProgressHandler(void *pDb){
|
||||
sqlite3_interrupt((sqlite3*)pDb);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
** Process a pragma statement.
|
||||
**
|
||||
@@ -736,6 +744,23 @@ void sqlite3Pragma(
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** PRAGMA vdbe_cycle_limit=N
|
||||
**
|
||||
** Arrange to interrupt any SQL statement that runs for more than N
|
||||
** virtual machine instructions. If N is zero, allow virtual machines
|
||||
** to run indefinitely.
|
||||
*/
|
||||
case PragTyp_VDBE_CYCLE_LIMIT: {
|
||||
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
|
||||
if( zRight ){
|
||||
int N = sqlite3Atoi(zRight);
|
||||
sqlite3_progress_handler(db, N, N>0 ? interruptProgressHandler : 0, db);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
|
||||
/*
|
||||
** PRAGMA [schema.]cache_size
|
||||
|
||||
+19
-9
@@ -40,14 +40,15 @@
|
||||
#define PragTyp_TEMP_STORE 32
|
||||
#define PragTyp_TEMP_STORE_DIRECTORY 33
|
||||
#define PragTyp_THREADS 34
|
||||
#define PragTyp_WAL_AUTOCHECKPOINT 35
|
||||
#define PragTyp_WAL_CHECKPOINT 36
|
||||
#define PragTyp_ACTIVATE_EXTENSIONS 37
|
||||
#define PragTyp_HEXKEY 38
|
||||
#define PragTyp_KEY 39
|
||||
#define PragTyp_REKEY 40
|
||||
#define PragTyp_LOCK_STATUS 41
|
||||
#define PragTyp_PARSER_TRACE 42
|
||||
#define PragTyp_VDBE_CYCLE_LIMIT 35
|
||||
#define PragTyp_WAL_AUTOCHECKPOINT 36
|
||||
#define PragTyp_WAL_CHECKPOINT 37
|
||||
#define PragTyp_ACTIVATE_EXTENSIONS 38
|
||||
#define PragTyp_HEXKEY 39
|
||||
#define PragTyp_KEY 40
|
||||
#define PragTyp_REKEY 41
|
||||
#define PragTyp_LOCK_STATUS 42
|
||||
#define PragTyp_PARSER_TRACE 43
|
||||
|
||||
/* Property flags associated with various pragma. */
|
||||
#define PragFlg_NeedSchema 0x01 /* Force schema load before running */
|
||||
@@ -562,6 +563,15 @@ static const PragmaName aPragmaName[] = {
|
||||
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ SQLITE_VdbeAddopTrace },
|
||||
#endif
|
||||
#endif
|
||||
{/* zName: */ "vdbe_cycle_limit",
|
||||
/* ePragTyp: */ PragTyp_VDBE_CYCLE_LIMIT,
|
||||
/* ePragFlg: */ PragFlg_NoColumns,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
|
||||
#if defined(SQLITE_DEBUG)
|
||||
{/* zName: */ "vdbe_debug",
|
||||
/* ePragTyp: */ PragTyp_FLAG,
|
||||
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
|
||||
@@ -604,4 +614,4 @@ static const PragmaName aPragmaName[] = {
|
||||
/* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
|
||||
#endif
|
||||
};
|
||||
/* Number of pragmas: 60 on by default, 73 total. */
|
||||
/* Number of pragmas: 61 on by default, 74 total. */
|
||||
|
||||
+55
-42
@@ -15,7 +15,7 @@
|
||||
** Conversion types fall into various categories as defined by the
|
||||
** following enumeration.
|
||||
*/
|
||||
#define etRADIX 0 /* Integer types. %d, %x, %o, and so forth */
|
||||
#define etRADIX 0 /* non-decimal integer types. %x %o */
|
||||
#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,8 +33,9 @@
|
||||
#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 16 /* Any unrecognized conversion type */
|
||||
#define etINVALID 17 /* Any unrecognized conversion type */
|
||||
|
||||
|
||||
/*
|
||||
@@ -58,8 +59,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 infinity precision */
|
||||
#define FLAG_SIGNED 1 /* True if the value to convert is signed */
|
||||
#define FLAG_STRING 4 /* Allow infinite precision */
|
||||
|
||||
|
||||
/*
|
||||
@@ -69,7 +70,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, etRADIX, 0, 0 },
|
||||
{ 'd', 10, 1, etDECIMAL, 0, 0 },
|
||||
{ 's', 0, 4, etSTRING, 0, 0 },
|
||||
{ 'g', 0, 1, etGENERIC, 30, 0 },
|
||||
{ 'z', 0, 4, etDYNSTRING, 0, 0 },
|
||||
@@ -78,7 +79,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, etRADIX, 0, 0 },
|
||||
{ 'u', 10, 0, etDECIMAL, 0, 0 },
|
||||
{ 'x', 16, 0, etRADIX, 16, 1 },
|
||||
{ 'X', 16, 0, etRADIX, 0, 4 },
|
||||
#ifndef SQLITE_OMIT_FLOATING_POINT
|
||||
@@ -87,7 +88,7 @@ static const et_info fmtinfo[] = {
|
||||
{ 'E', 0, 1, etEXP, 14, 0 },
|
||||
{ 'G', 0, 1, etGENERIC, 14, 0 },
|
||||
#endif
|
||||
{ 'i', 10, 1, etRADIX, 0, 0 },
|
||||
{ 'i', 10, 1, etDECIMAL, 0, 0 },
|
||||
{ 'n', 0, 0, etSIZE, 0, 0 },
|
||||
{ '%', 0, 0, etPERCENT, 0, 0 },
|
||||
{ 'p', 16, 0, etPOINTER, 0, 1 },
|
||||
@@ -179,14 +180,13 @@ 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_plussign; /* True if "+" flag is present */
|
||||
etByte flag_blanksign; /* True if " " flag is present */
|
||||
etByte flag_prefix; /* '+' or ' ' or 0 for prefix */
|
||||
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; /* True if "l" flag is present */
|
||||
etByte flag_longlong; /* True if the "ll" flag is present */
|
||||
etByte flag_long; /* 1 for the "l" flag, 2 for "ll", 0 by default */
|
||||
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,17 +229,18 @@ void sqlite3VXPrintf(
|
||||
break;
|
||||
}
|
||||
/* Find out what flags are present */
|
||||
flag_leftjustify = flag_plussign = flag_blanksign =
|
||||
flag_leftjustify = flag_prefix = cThousand =
|
||||
flag_alternateform = flag_altform2 = flag_zeropad = 0;
|
||||
done = 0;
|
||||
do{
|
||||
switch( c ){
|
||||
case '-': flag_leftjustify = 1; break;
|
||||
case '+': flag_plussign = 1; break;
|
||||
case ' ': flag_blanksign = 1; break;
|
||||
case '+': flag_prefix = '+'; break;
|
||||
case ' ': flag_prefix = ' '; 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 );
|
||||
@@ -309,13 +310,11 @@ void sqlite3VXPrintf(
|
||||
flag_long = 1;
|
||||
c = *++fmt;
|
||||
if( c=='l' ){
|
||||
flag_longlong = 1;
|
||||
flag_long = 2;
|
||||
c = *++fmt;
|
||||
}else{
|
||||
flag_longlong = 0;
|
||||
}
|
||||
}else{
|
||||
flag_long = flag_longlong = 0;
|
||||
flag_long = 0;
|
||||
}
|
||||
/* Fetch the info entry for the field */
|
||||
infop = &fmtinfo[0];
|
||||
@@ -333,15 +332,11 @@ void sqlite3VXPrintf(
|
||||
**
|
||||
** flag_alternateform TRUE if a '#' is present.
|
||||
** flag_altform2 TRUE if a '!' is present.
|
||||
** flag_plussign TRUE if a '+' is present.
|
||||
** flag_prefix '+' or ' ' or zero
|
||||
** 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 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.
|
||||
** flag_long 1 for "l", 2 for "ll"
|
||||
** width The specified field width. This is
|
||||
** always non-negative. Zero is the default.
|
||||
** precision The specified precision. The default
|
||||
@@ -351,19 +346,24 @@ void sqlite3VXPrintf(
|
||||
*/
|
||||
switch( xtype ){
|
||||
case etPOINTER:
|
||||
flag_longlong = sizeof(char*)==sizeof(i64);
|
||||
flag_long = sizeof(char*)==sizeof(long int);
|
||||
flag_long = sizeof(char*)==sizeof(i64) ? 2 :
|
||||
sizeof(char*)==sizeof(long int) ? 1 : 0;
|
||||
/* Fall through into the next case */
|
||||
case etORDINAL:
|
||||
case etRADIX:
|
||||
case etRADIX:
|
||||
cThousand = 0;
|
||||
/* Fall through into the next case */
|
||||
case etDECIMAL:
|
||||
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 ){
|
||||
v = va_arg(ap,long int);
|
||||
if( flag_long==2 ){
|
||||
v = va_arg(ap,i64) ;
|
||||
}else{
|
||||
v = va_arg(ap,long int);
|
||||
}
|
||||
}else{
|
||||
v = va_arg(ap,int);
|
||||
}
|
||||
@@ -376,17 +376,17 @@ void sqlite3VXPrintf(
|
||||
prefix = '-';
|
||||
}else{
|
||||
longvalue = v;
|
||||
if( flag_plussign ) prefix = '+';
|
||||
else if( flag_blanksign ) prefix = ' ';
|
||||
else prefix = 0;
|
||||
prefix = flag_prefix;
|
||||
}
|
||||
}else{
|
||||
if( bArgList ){
|
||||
longvalue = (u64)getIntArg(pArgList);
|
||||
}else if( flag_longlong ){
|
||||
longvalue = va_arg(ap,u64);
|
||||
}else if( flag_long ){
|
||||
longvalue = va_arg(ap,unsigned long int);
|
||||
if( flag_long==2 ){
|
||||
longvalue = va_arg(ap,u64);
|
||||
}else{
|
||||
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 ){
|
||||
if( precision<etBUFSIZE-10-etBUFSIZE/3 ){
|
||||
nOut = etBUFSIZE;
|
||||
zOut = buf;
|
||||
}else{
|
||||
nOut = precision + 10;
|
||||
nOut = precision + 10 + precision/3;
|
||||
zOut = zExtra = sqlite3Malloc( nOut );
|
||||
if( zOut==0 ){
|
||||
setStrAccumError(pAccum, STRACCUM_NOMEM);
|
||||
@@ -426,8 +426,23 @@ void sqlite3VXPrintf(
|
||||
}while( longvalue>0 );
|
||||
}
|
||||
length = (int)(&zOut[nOut-1]-bufpt);
|
||||
for(idx=precision-length; idx>0; idx--){
|
||||
while( precision>length ){
|
||||
*(--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" */
|
||||
@@ -454,9 +469,7 @@ void sqlite3VXPrintf(
|
||||
realvalue = -realvalue;
|
||||
prefix = '-';
|
||||
}else{
|
||||
if( flag_plussign ) prefix = '+';
|
||||
else if( flag_blanksign ) prefix = ' ';
|
||||
else prefix = 0;
|
||||
prefix = flag_prefix;
|
||||
}
|
||||
if( xtype==etGENERIC && precision>0 ) precision--;
|
||||
testcase( precision>0xfff );
|
||||
|
||||
+18
-10
@@ -4186,7 +4186,15 @@ static int withExpand(
|
||||
pCte->zCteErr = "circular reference: %s";
|
||||
pSavedWith = pParse->pWith;
|
||||
pParse->pWith = pWith;
|
||||
sqlite3WalkSelect(pWalker, bMayRecursive ? pSel->pPrior : pSel);
|
||||
if( bMayRecursive ){
|
||||
Select *pPrior = pSel->pPrior;
|
||||
assert( pPrior->pWith==0 );
|
||||
pPrior->pWith = pSel->pWith;
|
||||
sqlite3WalkSelect(pWalker, pPrior);
|
||||
pPrior->pWith = 0;
|
||||
}else{
|
||||
sqlite3WalkSelect(pWalker, pSel);
|
||||
}
|
||||
pParse->pWith = pWith;
|
||||
|
||||
for(pLeft=pSel; pLeft->pPrior; pLeft=pLeft->pPrior);
|
||||
@@ -4230,10 +4238,12 @@ static int withExpand(
|
||||
*/
|
||||
static void selectPopWith(Walker *pWalker, Select *p){
|
||||
Parse *pParse = pWalker->pParse;
|
||||
With *pWith = findRightmost(p)->pWith;
|
||||
if( pWith!=0 ){
|
||||
assert( pParse->pWith==pWith );
|
||||
pParse->pWith = pWith->pOuter;
|
||||
if( pParse->pWith && p->pPrior==0 ){
|
||||
With *pWith = findRightmost(p)->pWith;
|
||||
if( pWith!=0 ){
|
||||
assert( pParse->pWith==pWith );
|
||||
pParse->pWith = pWith->pOuter;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
@@ -4283,8 +4293,8 @@ static int selectExpander(Walker *pWalker, Select *p){
|
||||
}
|
||||
pTabList = p->pSrc;
|
||||
pEList = p->pEList;
|
||||
if( pWalker->xSelectCallback2==selectPopWith ){
|
||||
sqlite3WithPush(pParse, findRightmost(p)->pWith, 0);
|
||||
if( p->pWith ){
|
||||
sqlite3WithPush(pParse, p->pWith, 0);
|
||||
}
|
||||
|
||||
/* Make sure cursor numbers have been assigned to all entries in
|
||||
@@ -4571,9 +4581,7 @@ static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
|
||||
sqlite3WalkSelect(&w, pSelect);
|
||||
}
|
||||
w.xSelectCallback = selectExpander;
|
||||
if( (pSelect->selFlags & SF_MultiValue)==0 ){
|
||||
w.xSelectCallback2 = selectPopWith;
|
||||
}
|
||||
w.xSelectCallback2 = selectPopWith;
|
||||
sqlite3WalkSelect(&w, pSelect);
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -2212,7 +2212,7 @@ static char zHelp[] =
|
||||
" html HTML <table> code\n"
|
||||
" insert SQL insert statements for TABLE\n"
|
||||
" line One value per line\n"
|
||||
" list Values delimited by .separator strings\n"
|
||||
" list Values delimited by \"|\"\n"
|
||||
" quote Escape answers as for SQL\n"
|
||||
" tabs Tab-separated values\n"
|
||||
" tcl TCL list elements\n"
|
||||
@@ -4614,7 +4614,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
|
||||
#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
|
||||
if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
|
||||
sqlite3SelectTrace = integerValue(azArg[1]);
|
||||
sqlite3SelectTrace = (int)integerValue(azArg[1]);
|
||||
}else
|
||||
#endif
|
||||
|
||||
@@ -5192,6 +5192,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}
|
||||
}
|
||||
}else
|
||||
#endif /* !defined(SQLITE_UNTESTABLE) */
|
||||
|
||||
if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
|
||||
open_db(p, 0);
|
||||
@@ -5228,7 +5229,6 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}
|
||||
#endif
|
||||
}else
|
||||
#endif /* !defined(SQLITE_UNTESTABLE) */
|
||||
|
||||
#if SQLITE_USER_AUTHENTICATION
|
||||
if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
|
||||
|
||||
+39
-25
@@ -103,19 +103,28 @@
|
||||
# define _LARGEFILE_SOURCE 1
|
||||
#endif
|
||||
|
||||
/* What version of GCC is being used. 0 means GCC is not being used */
|
||||
#ifdef __GNUC__
|
||||
/* 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)
|
||||
# define GCC_VERSION (__GNUC__*1000000+__GNUC_MINOR__*1000+__GNUC_PATCHLEVEL__)
|
||||
#else
|
||||
# define GCC_VERSION 0
|
||||
#endif
|
||||
|
||||
/* 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__)
|
||||
#if defined(_MSC_VER) && !defined(SQLITE_DISABLE_INTRINSIC)
|
||||
# define MSVC_VERSION _MSC_VER
|
||||
#else
|
||||
# define CLANG_VERSION 0
|
||||
# define MSVC_VERSION 0
|
||||
#endif
|
||||
|
||||
/* Needed for various definitions... */
|
||||
@@ -247,6 +256,7 @@
|
||||
# include <intrin.h>
|
||||
# pragma intrinsic(_byteswap_ushort)
|
||||
# pragma intrinsic(_byteswap_ulong)
|
||||
# pragma intrinsic(_byteswap_uint64)
|
||||
# pragma intrinsic(_ReadWriteBarrier)
|
||||
# else
|
||||
# include <cmnintrin.h>
|
||||
@@ -787,32 +797,35 @@ 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_RUNTIME_BYTEORDER=1 is set, then byte-order is determined
|
||||
** -DSQLITE_BYTEORDER=0 is set, then byte-order is determined
|
||||
** at run-time.
|
||||
*/
|
||||
#if (defined(i386) || defined(__i386__) || defined(_M_IX86) || \
|
||||
#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__)) && !defined(SQLITE_RUNTIME_BYTEORDER)
|
||||
# define SQLITE_BYTEORDER 1234
|
||||
# define SQLITE_BIGENDIAN 0
|
||||
# define SQLITE_LITTLEENDIAN 1
|
||||
# define SQLITE_UTF16NATIVE SQLITE_UTF16LE
|
||||
defined(__arm__)
|
||||
# define SQLITE_BYTEORDER 1234
|
||||
# elif defined(sparc) || defined(__ppc__)
|
||||
# define SQLITE_BYTEORDER 4321
|
||||
# else
|
||||
# define SQLITE_BYTEORDER 0
|
||||
# endif
|
||||
#endif
|
||||
#if (defined(sparc) || defined(__ppc__)) \
|
||||
&& !defined(SQLITE_RUNTIME_BYTEORDER)
|
||||
# define SQLITE_BYTEORDER 4321
|
||||
#if SQLITE_BYTEORDER==4321
|
||||
# define SQLITE_BIGENDIAN 1
|
||||
# define SQLITE_LITTLEENDIAN 0
|
||||
# define SQLITE_UTF16NATIVE SQLITE_UTF16BE
|
||||
#endif
|
||||
#if !defined(SQLITE_BYTEORDER)
|
||||
#elif SQLITE_BYTEORDER==1234
|
||||
# define SQLITE_BIGENDIAN 0
|
||||
# define SQLITE_LITTLEENDIAN 1
|
||||
# define SQLITE_UTF16NATIVE SQLITE_UTF16LE
|
||||
#else
|
||||
# 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)
|
||||
@@ -1835,6 +1848,7 @@ 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 */
|
||||
@@ -1842,7 +1856,6 @@ 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 */
|
||||
@@ -1870,7 +1883,7 @@ struct 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 */
|
||||
/* available for reuse: 0x10 */
|
||||
#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 */
|
||||
@@ -1882,7 +1895,7 @@ struct Table {
|
||||
** table support is omitted from the build.
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
# define IsVirtual(X) (((X)->tabFlags & TF_Virtual)!=0)
|
||||
# define IsVirtual(X) ((X)->nModuleArg)
|
||||
#else
|
||||
# define IsVirtual(X) 0
|
||||
#endif
|
||||
@@ -2427,7 +2440,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 list of expressions */
|
||||
Expr *pExpr; /* The parse tree for this expression */
|
||||
char *zName; /* Token associated with this expression */
|
||||
char *zSpan; /* Original text of the expression */
|
||||
u8 sortOrder; /* 1 for DESC or 0 for ASC */
|
||||
@@ -3750,6 +3763,7 @@ 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,10 +3405,6 @@ 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);
|
||||
|
||||
+2
-2
@@ -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_Alloc((size_t)nByte);
|
||||
return (void *)Tcl_AttemptAlloc((size_t)nByte);
|
||||
}
|
||||
static void crash_free(void *p){
|
||||
Tcl_Free(p);
|
||||
}
|
||||
static void *crash_realloc(void *p, int n){
|
||||
return (void *)Tcl_Realloc(p, (size_t)n);
|
||||
return (void *)Tcl_AttemptRealloc(p, (size_t)n);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+5
-1
@@ -239,7 +239,11 @@ static int SQLITE_TCLAPI test_blob_read(
|
||||
}
|
||||
|
||||
if( nByte>0 ){
|
||||
zBuf = (unsigned char *)Tcl_Alloc(nByte);
|
||||
zBuf = (unsigned char *)Tcl_AttemptAlloc(nByte);
|
||||
if( zBuf==0 ){
|
||||
Tcl_AppendResult(interp, "out of memory", 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
rc = sqlite3_blob_read(pBlob, zBuf, nByte, iOffset);
|
||||
if( rc==SQLITE_OK ){
|
||||
|
||||
+7
-14
@@ -1140,13 +1140,11 @@ u32 sqlite3Get4byte(const u8 *p){
|
||||
u32 x;
|
||||
memcpy(&x,p,4);
|
||||
return x;
|
||||
#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
|
||||
&& (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000)
|
||||
#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
|
||||
u32 x;
|
||||
memcpy(&x,p,4);
|
||||
return __builtin_bswap32(x);
|
||||
#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
|
||||
&& defined(_MSC_VER) && _MSC_VER>=1300
|
||||
#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
|
||||
u32 x;
|
||||
memcpy(&x,p,4);
|
||||
return _byteswap_ulong(x);
|
||||
@@ -1158,12 +1156,10 @@ u32 sqlite3Get4byte(const u8 *p){
|
||||
void sqlite3Put4byte(unsigned char *p, u32 v){
|
||||
#if SQLITE_BYTEORDER==4321
|
||||
memcpy(p,&v,4);
|
||||
#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
|
||||
&& (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000)
|
||||
#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
|
||||
u32 x = __builtin_bswap32(v);
|
||||
memcpy(p,&x,4);
|
||||
#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
|
||||
&& defined(_MSC_VER) && _MSC_VER>=1300
|
||||
#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
|
||||
u32 x = _byteswap_ulong(v);
|
||||
memcpy(p,&x,4);
|
||||
#else
|
||||
@@ -1279,8 +1275,7 @@ int sqlite3SafetyCheckSickOrOk(sqlite3 *db){
|
||||
** overflow, leave *pA unchanged and return 1.
|
||||
*/
|
||||
int sqlite3AddInt64(i64 *pA, i64 iB){
|
||||
#if !defined(SQLITE_DISABLE_INTRINSIC) \
|
||||
&& (GCC_VERSION>=5004000 || CLANG_VERSION>=4000000)
|
||||
#if GCC_VERSION>=5004000
|
||||
return __builtin_add_overflow(*pA, iB, pA);
|
||||
#else
|
||||
i64 iA = *pA;
|
||||
@@ -1300,8 +1295,7 @@ int sqlite3AddInt64(i64 *pA, i64 iB){
|
||||
#endif
|
||||
}
|
||||
int sqlite3SubInt64(i64 *pA, i64 iB){
|
||||
#if !defined(SQLITE_DISABLE_INTRINSIC) \
|
||||
&& (GCC_VERSION>=5004000 || CLANG_VERSION>=4000000)
|
||||
#if GCC_VERSION>=5004000
|
||||
return __builtin_sub_overflow(*pA, iB, pA);
|
||||
#else
|
||||
testcase( iB==SMALLEST_INT64+1 );
|
||||
@@ -1316,8 +1310,7 @@ int sqlite3SubInt64(i64 *pA, i64 iB){
|
||||
#endif
|
||||
}
|
||||
int sqlite3MulInt64(i64 *pA, i64 iB){
|
||||
#if !defined(SQLITE_DISABLE_INTRINSIC) \
|
||||
&& (GCC_VERSION>=5004000 || CLANG_VERSION>=4000000)
|
||||
#if GCC_VERSION>=5004000
|
||||
return __builtin_mul_overflow(*pA, iB, pA);
|
||||
#else
|
||||
i64 iA = *pA;
|
||||
|
||||
+19
-2
@@ -98,8 +98,25 @@ static int execSqlF(sqlite3 *db, char **pzErrMsg, const char *zSql, ...){
|
||||
*/
|
||||
void sqlite3Vacuum(Parse *pParse, Token *pNm){
|
||||
Vdbe *v = sqlite3GetVdbe(pParse);
|
||||
int iDb = pNm ? sqlite3TwoPartName(pParse, pNm, pNm, &pNm) : 0;
|
||||
if( v && (iDb>=2 || iDb==0) ){
|
||||
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 ){
|
||||
sqlite3VdbeAddOp1(v, OP_Vacuum, iDb);
|
||||
sqlite3VdbeUsesBtree(v, iDb);
|
||||
}
|
||||
|
||||
+1
-1
@@ -2198,7 +2198,7 @@ case OP_Compare: {
|
||||
assert( pKeyInfo!=0 );
|
||||
p1 = pOp->p1;
|
||||
p2 = pOp->p2;
|
||||
#if SQLITE_DEBUG
|
||||
#ifdef SQLITE_DEBUG
|
||||
if( aPermute ){
|
||||
int k, mx = 0;
|
||||
for(k=0; k<n; k++) if( aPermute[k]>mx ) mx = aPermute[k];
|
||||
|
||||
+2
-2
@@ -3562,7 +3562,7 @@ void sqlite3VdbeRecordUnpack(
|
||||
p->nField = u;
|
||||
}
|
||||
|
||||
#if SQLITE_DEBUG
|
||||
#ifdef SQLITE_DEBUG
|
||||
/*
|
||||
** This function compares two index or table record keys in the same way
|
||||
** as the sqlite3VdbeRecordCompare() routine. Unlike VdbeRecordCompare(),
|
||||
@@ -3667,7 +3667,7 @@ debugCompareEnd:
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SQLITE_DEBUG
|
||||
#ifdef 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
|
||||
|
||||
+8
-10
@@ -339,8 +339,7 @@ void sqlite3VtabBeginParse(
|
||||
iDb = sqlite3SchemaToIndex(db, pTable->pSchema);
|
||||
assert( iDb>=0 );
|
||||
|
||||
pTable->tabFlags |= TF_Virtual;
|
||||
pTable->nModuleArg = 0;
|
||||
assert( pTable->nModuleArg==0 );
|
||||
addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName));
|
||||
addModuleArgument(db, pTable, 0);
|
||||
addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName));
|
||||
@@ -628,7 +627,7 @@ int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){
|
||||
int rc;
|
||||
|
||||
assert( pTab );
|
||||
if( (pTab->tabFlags & TF_Virtual)==0 || sqlite3GetVTable(db, pTab) ){
|
||||
if( !IsVirtual(pTab) || sqlite3GetVTable(db, pTab) ){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
@@ -698,7 +697,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 && (pTab->tabFlags & TF_Virtual)!=0 && !pTab->pVTable );
|
||||
assert( pTab && IsVirtual(pTab) && !pTab->pVTable );
|
||||
|
||||
/* Locate the required virtual table module */
|
||||
zMod = pTab->azModuleArg[0];
|
||||
@@ -752,7 +751,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
|
||||
return SQLITE_MISUSE_BKPT;
|
||||
}
|
||||
pTab = pCtx->pTab;
|
||||
assert( (pTab->tabFlags & TF_Virtual)!=0 );
|
||||
assert( IsVirtual(pTab) );
|
||||
|
||||
pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
|
||||
if( pParse==0 ){
|
||||
@@ -766,7 +765,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
|
||||
&& pParse->pNewTable
|
||||
&& !db->mallocFailed
|
||||
&& !pParse->pNewTable->pSelect
|
||||
&& (pParse->pNewTable->tabFlags & TF_Virtual)==0
|
||||
&& !IsVirtual(pParse->pNewTable)
|
||||
){
|
||||
if( !pTab->aCol ){
|
||||
Table *pNew = pParse->pNewTable;
|
||||
@@ -1055,7 +1054,7 @@ FuncDef *sqlite3VtabOverloadFunction(
|
||||
if( pExpr->op!=TK_COLUMN ) return pDef;
|
||||
pTab = pExpr->pTab;
|
||||
if( NEVER(pTab==0) ) return pDef;
|
||||
if( (pTab->tabFlags & TF_Virtual)==0 ) return pDef;
|
||||
if( !IsVirtual(pTab) ) return pDef;
|
||||
pVtab = sqlite3GetVTable(db, pTab)->pVtab;
|
||||
assert( pVtab!=0 );
|
||||
assert( pVtab->pModule!=0 );
|
||||
@@ -1150,8 +1149,7 @@ int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){
|
||||
pMod->pEpoTab = pTab;
|
||||
pTab->nTabRef = 1;
|
||||
pTab->pSchema = db->aDb[0].pSchema;
|
||||
pTab->tabFlags |= TF_Virtual;
|
||||
pTab->nModuleArg = 0;
|
||||
assert( pTab->nModuleArg==0 );
|
||||
pTab->iPKey = -1;
|
||||
addModuleArgument(db, pTab, sqlite3DbStrDup(db, pTab->zName));
|
||||
addModuleArgument(db, pTab, 0);
|
||||
@@ -1222,7 +1220,7 @@ int sqlite3_vtab_config(sqlite3 *db, int op, ...){
|
||||
if( !p ){
|
||||
rc = SQLITE_MISUSE_BKPT;
|
||||
}else{
|
||||
assert( p->pTab==0 || (p->pTab->tabFlags & TF_Virtual)!=0 );
|
||||
assert( p->pTab==0 || IsVirtual(p->pTab) );
|
||||
p->pVTable->bConstraint = (u8)va_arg(ap, int);
|
||||
}
|
||||
break;
|
||||
|
||||
+11
-9
@@ -209,7 +209,8 @@ static WhereTerm *whereScanNext(WhereScan *pScan){
|
||||
if( pTerm->leftCursor==iCur
|
||||
&& pTerm->u.leftColumn==iColumn
|
||||
&& (iColumn!=XN_EXPR
|
||||
|| sqlite3ExprCompare(pTerm->pExpr->pLeft,pScan->pIdxExpr,iCur)==0)
|
||||
|| sqlite3ExprCompareSkip(pTerm->pExpr->pLeft,
|
||||
pScan->pIdxExpr,iCur)==0)
|
||||
&& (pScan->iEquiv<=1 || !ExprHasProperty(pTerm->pExpr, EP_FromJoin))
|
||||
){
|
||||
if( (pTerm->eOperator & WO_EQUIV)!=0
|
||||
@@ -308,6 +309,7 @@ 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 ){
|
||||
@@ -4112,9 +4114,9 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
|
||||
&& nRowEst
|
||||
){
|
||||
Bitmask notUsed;
|
||||
int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pDistinctSet, pFrom,
|
||||
int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pResultSet, pFrom,
|
||||
WHERE_DISTINCTBY, nLoop-1, pFrom->aLoop[nLoop-1], ¬Used);
|
||||
if( rc==pWInfo->pDistinctSet->nExpr ){
|
||||
if( rc==pWInfo->pResultSet->nExpr ){
|
||||
pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
|
||||
}
|
||||
}
|
||||
@@ -4351,7 +4353,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 *pDistinctSet, /* Try not to output two rows that duplicate these */
|
||||
ExprList *pResultSet, /* Query result set. Req'd for DISTINCT */
|
||||
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 */
|
||||
@@ -4427,7 +4429,7 @@ WhereInfo *sqlite3WhereBegin(
|
||||
pWInfo->pParse = pParse;
|
||||
pWInfo->pTabList = pTabList;
|
||||
pWInfo->pOrderBy = pOrderBy;
|
||||
pWInfo->pDistinctSet = pDistinctSet;
|
||||
pWInfo->pResultSet = pResultSet;
|
||||
pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1;
|
||||
pWInfo->nLevel = nTabList;
|
||||
pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(v);
|
||||
@@ -4505,13 +4507,13 @@ WhereInfo *sqlite3WhereBegin(
|
||||
if( db->mallocFailed ) goto whereBeginError;
|
||||
|
||||
if( wctrlFlags & WHERE_WANT_DISTINCT ){
|
||||
if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pDistinctSet) ){
|
||||
if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pResultSet) ){
|
||||
/* 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 = pDistinctSet;
|
||||
pWInfo->pOrderBy = pResultSet;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4587,10 +4589,10 @@ WhereInfo *sqlite3WhereBegin(
|
||||
#endif
|
||||
/* Attempt to omit tables from the join that do not effect the result */
|
||||
if( pWInfo->nLevel>=2
|
||||
&& pDistinctSet!=0
|
||||
&& pResultSet!=0
|
||||
&& OptimizationEnabled(db, SQLITE_OmitNoopJoin)
|
||||
){
|
||||
Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pDistinctSet);
|
||||
Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pResultSet);
|
||||
if( sWLB.pOrderBy ){
|
||||
tabUsed |= sqlite3WhereExprListUsage(pMaskSet, sWLB.pOrderBy);
|
||||
}
|
||||
|
||||
+1
-1
@@ -411,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 *pDistinctSet; /* DISTINCT over all these values */
|
||||
ExprList *pResultSet; /* Result set of the query */
|
||||
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 */
|
||||
|
||||
+8
-2
@@ -1062,6 +1062,7 @@ 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 */
|
||||
@@ -1103,6 +1104,11 @@ 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;
|
||||
@@ -1287,7 +1293,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
sqlite3ExprCacheAffinityChange(pParse, r1, 1);
|
||||
sqlite3ReleaseTempReg(pParse, rTemp);
|
||||
}else{
|
||||
sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrBrk);
|
||||
sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrHalt);
|
||||
VdbeCoverageIf(v, bRev==0);
|
||||
VdbeCoverageIf(v, bRev!=0);
|
||||
}
|
||||
@@ -1933,7 +1939,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
codeCursorHint(pTabItem, pWInfo, pLevel, 0);
|
||||
pLevel->op = aStep[bRev];
|
||||
pLevel->p1 = iCur;
|
||||
pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk);
|
||||
pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrHalt);
|
||||
VdbeCoverageIf(v, bRev==0);
|
||||
VdbeCoverageIf(v, bRev!=0);
|
||||
pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
|
||||
|
||||
+18
-10
@@ -213,15 +213,6 @@ 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;
|
||||
@@ -238,6 +229,23 @@ 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++;
|
||||
@@ -866,7 +874,7 @@ static int exprMightBeIndexed(
|
||||
if( pIdx->aColExpr==0 ) continue;
|
||||
for(i=0; i<pIdx->nKeyCol; i++){
|
||||
if( pIdx->aiColumn[i]!=XN_EXPR ) continue;
|
||||
if( sqlite3ExprCompare(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){
|
||||
if( sqlite3ExprCompareSkip(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){
|
||||
*piCur = iCur;
|
||||
*piColumn = XN_EXPR;
|
||||
return 1;
|
||||
|
||||
+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 ***
|
||||
Page 4: btreeInitPage() returns error code 11}}}
|
||||
On tree page 4 cell 19: Extends off end of page}}}
|
||||
|
||||
# {0 {{*** in database main ***
|
||||
# Corruption detected in cell 710 on page 4
|
||||
|
||||
+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_realloc(p->z, nNew);
|
||||
zNew = sqlite3_realloc64(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, n);
|
||||
memcpy(p->z + p->n, z, (int)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 */
|
||||
const char **azDb = 0; /* Names of the databases (limit: 20) */
|
||||
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++){
|
||||
const char *z = argv[i];
|
||||
char *z = argv[i];
|
||||
if( z[0]!='-' ){
|
||||
azDb = realloc(azDb, sizeof(azDb[0])*(nDb+1));
|
||||
if( azDb==0 ) fatalError("out of memory");
|
||||
|
||||
@@ -0,0 +1,786 @@
|
||||
/*
|
||||
** 2017-02-07
|
||||
**
|
||||
** 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 program implements an SQLite database self-verification utility.
|
||||
** Usage:
|
||||
**
|
||||
** dbselftest DATABASE ...
|
||||
**
|
||||
** This program reads the "selftest" table in DATABASE, in rowid order,
|
||||
** and runs each of the tests described there, reporting results at the
|
||||
** end.
|
||||
**
|
||||
** The intent of this program is to have a set of test database files that
|
||||
** can be run using future versions of SQLite in order to verify that
|
||||
** legacy database files continue to be readable. In other words, the
|
||||
** intent is to confirm that there have been no breaking changes in the
|
||||
** file format. The program can also be used to verify that database files
|
||||
** are fully compatible between different architectures.
|
||||
**
|
||||
** The selftest table looks like this:
|
||||
**
|
||||
** CREATE TABLE selftest (
|
||||
** id INTEGER PRIMARY KEY, -- Run tests in ascending order
|
||||
** op TEXT, -- "test", "regexp", "print", etc.
|
||||
** cmdtxt TEXT, -- Usually the SQL to be run
|
||||
** expected TEXT -- Expected results
|
||||
** );
|
||||
**
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "sqlite3.h"
|
||||
|
||||
static const char zHelp[] =
|
||||
"Usage: dbselftest [OPTIONS] DBFILE ...\n"
|
||||
"\n"
|
||||
" --init Create the selftest table\n"
|
||||
" -q Suppress most output. Errors only\n"
|
||||
" -v Show extra output\n"
|
||||
;
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
** The following code from ext/misc/sha1.c
|
||||
**
|
||||
** Context for the SHA1 hash
|
||||
*/
|
||||
typedef struct SHA1Context SHA1Context;
|
||||
struct SHA1Context {
|
||||
unsigned int state[5];
|
||||
unsigned int count[2];
|
||||
unsigned char buffer[64];
|
||||
};
|
||||
|
||||
|
||||
#if __GNUC__ && (defined(__i386__) || defined(__x86_64__))
|
||||
/*
|
||||
* GCC by itself only generates left rotates. Use right rotates if
|
||||
* possible to be kinder to dinky implementations with iterative rotate
|
||||
* instructions.
|
||||
*/
|
||||
#define SHA_ROT(op, x, k) \
|
||||
({ unsigned int y; asm(op " %1,%0" : "=r" (y) : "I" (k), "0" (x)); y; })
|
||||
#define rol(x,k) SHA_ROT("roll", x, k)
|
||||
#define ror(x,k) SHA_ROT("rorl", x, k)
|
||||
|
||||
#else
|
||||
/* Generic C equivalent */
|
||||
#define SHA_ROT(x,l,r) ((x) << (l) | (x) >> (r))
|
||||
#define rol(x,k) SHA_ROT(x,k,32-(k))
|
||||
#define ror(x,k) SHA_ROT(x,32-(k),k)
|
||||
#endif
|
||||
|
||||
|
||||
#define blk0le(i) (block[i] = (ror(block[i],8)&0xFF00FF00) \
|
||||
|(rol(block[i],8)&0x00FF00FF))
|
||||
#define blk0be(i) block[i]
|
||||
#define blk(i) (block[i&15] = rol(block[(i+13)&15]^block[(i+8)&15] \
|
||||
^block[(i+2)&15]^block[i&15],1))
|
||||
|
||||
/*
|
||||
* (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1
|
||||
*
|
||||
* Rl0() for little-endian and Rb0() for big-endian. Endianness is
|
||||
* determined at run-time.
|
||||
*/
|
||||
#define Rl0(v,w,x,y,z,i) \
|
||||
z+=((w&(x^y))^y)+blk0le(i)+0x5A827999+rol(v,5);w=ror(w,2);
|
||||
#define Rb0(v,w,x,y,z,i) \
|
||||
z+=((w&(x^y))^y)+blk0be(i)+0x5A827999+rol(v,5);w=ror(w,2);
|
||||
#define R1(v,w,x,y,z,i) \
|
||||
z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=ror(w,2);
|
||||
#define R2(v,w,x,y,z,i) \
|
||||
z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=ror(w,2);
|
||||
#define R3(v,w,x,y,z,i) \
|
||||
z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=ror(w,2);
|
||||
#define R4(v,w,x,y,z,i) \
|
||||
z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=ror(w,2);
|
||||
|
||||
/*
|
||||
* Hash a single 512-bit block. This is the core of the algorithm.
|
||||
*/
|
||||
void SHA1Transform(unsigned int state[5], const unsigned char buffer[64]){
|
||||
unsigned int qq[5]; /* a, b, c, d, e; */
|
||||
static int one = 1;
|
||||
unsigned int block[16];
|
||||
memcpy(block, buffer, 64);
|
||||
memcpy(qq,state,5*sizeof(unsigned int));
|
||||
|
||||
#define a qq[0]
|
||||
#define b qq[1]
|
||||
#define c qq[2]
|
||||
#define d qq[3]
|
||||
#define e qq[4]
|
||||
|
||||
/* Copy p->state[] to working vars */
|
||||
/*
|
||||
a = state[0];
|
||||
b = state[1];
|
||||
c = state[2];
|
||||
d = state[3];
|
||||
e = state[4];
|
||||
*/
|
||||
|
||||
/* 4 rounds of 20 operations each. Loop unrolled. */
|
||||
if( 1 == *(unsigned char*)&one ){
|
||||
Rl0(a,b,c,d,e, 0); Rl0(e,a,b,c,d, 1); Rl0(d,e,a,b,c, 2); Rl0(c,d,e,a,b, 3);
|
||||
Rl0(b,c,d,e,a, 4); Rl0(a,b,c,d,e, 5); Rl0(e,a,b,c,d, 6); Rl0(d,e,a,b,c, 7);
|
||||
Rl0(c,d,e,a,b, 8); Rl0(b,c,d,e,a, 9); Rl0(a,b,c,d,e,10); Rl0(e,a,b,c,d,11);
|
||||
Rl0(d,e,a,b,c,12); Rl0(c,d,e,a,b,13); Rl0(b,c,d,e,a,14); Rl0(a,b,c,d,e,15);
|
||||
}else{
|
||||
Rb0(a,b,c,d,e, 0); Rb0(e,a,b,c,d, 1); Rb0(d,e,a,b,c, 2); Rb0(c,d,e,a,b, 3);
|
||||
Rb0(b,c,d,e,a, 4); Rb0(a,b,c,d,e, 5); Rb0(e,a,b,c,d, 6); Rb0(d,e,a,b,c, 7);
|
||||
Rb0(c,d,e,a,b, 8); Rb0(b,c,d,e,a, 9); Rb0(a,b,c,d,e,10); Rb0(e,a,b,c,d,11);
|
||||
Rb0(d,e,a,b,c,12); Rb0(c,d,e,a,b,13); Rb0(b,c,d,e,a,14); Rb0(a,b,c,d,e,15);
|
||||
}
|
||||
R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
|
||||
R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
|
||||
R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
|
||||
R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
|
||||
R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
|
||||
R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
|
||||
R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
|
||||
R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
|
||||
R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
|
||||
R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
|
||||
R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
|
||||
R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
|
||||
R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
|
||||
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
|
||||
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
|
||||
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
|
||||
|
||||
/* Add the working vars back into context.state[] */
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
state[4] += e;
|
||||
|
||||
#undef a
|
||||
#undef b
|
||||
#undef c
|
||||
#undef d
|
||||
#undef e
|
||||
}
|
||||
|
||||
|
||||
/* Initialize a SHA1 context */
|
||||
static void hash_init(SHA1Context *p){
|
||||
/* SHA1 initialization constants */
|
||||
p->state[0] = 0x67452301;
|
||||
p->state[1] = 0xEFCDAB89;
|
||||
p->state[2] = 0x98BADCFE;
|
||||
p->state[3] = 0x10325476;
|
||||
p->state[4] = 0xC3D2E1F0;
|
||||
p->count[0] = p->count[1] = 0;
|
||||
}
|
||||
|
||||
/* Add new content to the SHA1 hash */
|
||||
static void hash_step(
|
||||
SHA1Context *p, /* Add content to this context */
|
||||
const unsigned char *data, /* Data to be added */
|
||||
unsigned int len /* Number of bytes in data */
|
||||
){
|
||||
unsigned int i, j;
|
||||
|
||||
j = p->count[0];
|
||||
if( (p->count[0] += len << 3) < j ){
|
||||
p->count[1] += (len>>29)+1;
|
||||
}
|
||||
j = (j >> 3) & 63;
|
||||
if( (j + len) > 63 ){
|
||||
(void)memcpy(&p->buffer[j], data, (i = 64-j));
|
||||
SHA1Transform(p->state, p->buffer);
|
||||
for(; i + 63 < len; i += 64){
|
||||
SHA1Transform(p->state, &data[i]);
|
||||
}
|
||||
j = 0;
|
||||
}else{
|
||||
i = 0;
|
||||
}
|
||||
(void)memcpy(&p->buffer[j], &data[i], len - i);
|
||||
}
|
||||
|
||||
/* Compute a string using sqlite3_vsnprintf() and hash it */
|
||||
static void hash_step_vformat(
|
||||
SHA1Context *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);
|
||||
hash_step(p, (unsigned char*)zBuf, n);
|
||||
}
|
||||
|
||||
|
||||
/* Add padding and compute the message digest. Render the
|
||||
** message digest as lower-case hexadecimal and put it into
|
||||
** zOut[]. zOut[] must be at least 41 bytes long. */
|
||||
static void hash_finish(
|
||||
SHA1Context *p, /* The SHA1 context to finish and render */
|
||||
char *zOut /* Store hexadecimal hash here */
|
||||
){
|
||||
unsigned int i;
|
||||
unsigned char finalcount[8];
|
||||
unsigned char digest[20];
|
||||
static const char zEncode[] = "0123456789abcdef";
|
||||
|
||||
for (i = 0; i < 8; i++){
|
||||
finalcount[i] = (unsigned char)((p->count[(i >= 4 ? 0 : 1)]
|
||||
>> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
|
||||
}
|
||||
hash_step(p, (const unsigned char *)"\200", 1);
|
||||
while ((p->count[0] & 504) != 448){
|
||||
hash_step(p, (const unsigned char *)"\0", 1);
|
||||
}
|
||||
hash_step(p, finalcount, 8); /* Should cause a SHA1Transform() */
|
||||
for (i = 0; i < 20; i++){
|
||||
digest[i] = (unsigned char)((p->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
|
||||
}
|
||||
for(i=0; i<20; i++){
|
||||
zOut[i*2] = zEncode[(digest[i]>>4)&0xf];
|
||||
zOut[i*2+1] = zEncode[digest[i] & 0xf];
|
||||
}
|
||||
zOut[i*2]= 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Implementation of the sha1(X) function.
|
||||
**
|
||||
** Return a lower-case hexadecimal rendering of the SHA1 hash of the
|
||||
** argument X. If X is a BLOB, it is hashed as is. For all other
|
||||
** types of input, X is converted into a UTF-8 string and the string
|
||||
** is hash without the trailing 0x00 terminator. The hash of a NULL
|
||||
** value is NULL.
|
||||
*/
|
||||
static void sha1Func(
|
||||
sqlite3_context *context,
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
SHA1Context cx;
|
||||
int eType = sqlite3_value_type(argv[0]);
|
||||
int nByte = sqlite3_value_bytes(argv[0]);
|
||||
char zOut[44];
|
||||
|
||||
assert( argc==1 );
|
||||
if( eType==SQLITE_NULL ) return;
|
||||
hash_init(&cx);
|
||||
if( eType==SQLITE_BLOB ){
|
||||
hash_step(&cx, sqlite3_value_blob(argv[0]), nByte);
|
||||
}else{
|
||||
hash_step(&cx, sqlite3_value_text(argv[0]), nByte);
|
||||
}
|
||||
hash_finish(&cx, zOut);
|
||||
sqlite3_result_text(context, zOut, 40, SQLITE_TRANSIENT);
|
||||
}
|
||||
|
||||
/*
|
||||
** Run a prepared statement and compute the SHA1 hash on the
|
||||
** result rows.
|
||||
*/
|
||||
static void sha1RunStatement(SHA1Context *pCtx, sqlite3_stmt *pStmt){
|
||||
int nCol = sqlite3_column_count(pStmt);
|
||||
const char *z = sqlite3_sql(pStmt);
|
||||
int n = (int)strlen(z);
|
||||
|
||||
hash_step_vformat(pCtx,"S%d:",n);
|
||||
hash_step(pCtx,(unsigned char*)z,n);
|
||||
|
||||
/* Compute a hash over the result of the query */
|
||||
while( SQLITE_ROW==sqlite3_step(pStmt) ){
|
||||
int i;
|
||||
hash_step(pCtx,(const unsigned char*)"R",1);
|
||||
for(i=0; i<nCol; i++){
|
||||
switch( sqlite3_column_type(pStmt,i) ){
|
||||
case SQLITE_NULL: {
|
||||
hash_step(pCtx, (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';
|
||||
hash_step(pCtx, 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';
|
||||
hash_step(pCtx,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(pCtx,"T%d:",n2);
|
||||
hash_step(pCtx, 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(pCtx,"B%d:",n2);
|
||||
hash_step(pCtx, z2, n2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Run one or more statements of SQL. Compute a SHA1 hash of the output.
|
||||
*/
|
||||
static int sha1Exec(
|
||||
sqlite3 *db, /* Run against this database connection */
|
||||
const char *zSql, /* The SQL to be run */
|
||||
char *zOut /* Store the SHA1 hash as hexadecimal in this buffer */
|
||||
){
|
||||
sqlite3_stmt *pStmt = 0; /* A prepared statement */
|
||||
int rc; /* Result of an API call */
|
||||
SHA1Context cx; /* The SHA1 hash context */
|
||||
|
||||
hash_init(&cx);
|
||||
while( zSql[0] ){
|
||||
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql);
|
||||
if( rc ){
|
||||
sqlite3_finalize(pStmt);
|
||||
return rc;
|
||||
}
|
||||
sha1RunStatement(&cx, pStmt);
|
||||
sqlite3_finalize(pStmt);
|
||||
}
|
||||
hash_finish(&cx, zOut);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Implementation of the sha1_query(SQL) function.
|
||||
**
|
||||
** This function compiles and runs the SQL statement(s) given in the
|
||||
** argument. The results are hashed using SHA1 and that hash is returned.
|
||||
**
|
||||
** The original SQL text is included as part of the hash.
|
||||
**
|
||||
** The hash is not just a concatenation of the outputs. Each query
|
||||
** is delimited and each row and value within the query is delimited,
|
||||
** with all values being marked with their datatypes.
|
||||
*/
|
||||
static void sha1QueryFunc(
|
||||
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 rc;
|
||||
SHA1Context cx;
|
||||
char zOut[44];
|
||||
|
||||
assert( argc==1 );
|
||||
if( zSql==0 ) return;
|
||||
hash_init(&cx);
|
||||
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;
|
||||
}
|
||||
sha1RunStatement(&cx, pStmt);
|
||||
sqlite3_finalize(pStmt);
|
||||
}
|
||||
hash_finish(&cx, zOut);
|
||||
sqlite3_result_text(context, zOut, 40, SQLITE_TRANSIENT);
|
||||
}
|
||||
/* End of ext/misc/sha1.c
|
||||
******************************************************************************/
|
||||
|
||||
/* How much output to display */
|
||||
#define VOLUME_MIN 0
|
||||
#define VOLUME_OFF 0
|
||||
#define VOLUME_ERROR_ONLY 1
|
||||
#define VOLUME_LOW 2
|
||||
#define VOLUME_ECHO 3
|
||||
#define VOLUME_VERBOSE 4
|
||||
#define VOLUME_MAX 4
|
||||
|
||||
/* A string accumulator
|
||||
*/
|
||||
typedef struct Str {
|
||||
char *z; /* Accumulated text */
|
||||
int n; /* Bytes of z[] used so far */
|
||||
int nAlloc; /* Bytes allocated for z[] */
|
||||
} Str;
|
||||
|
||||
/* Append text to the Str object
|
||||
*/
|
||||
static void strAppend(Str *p, const char *z){
|
||||
int n = (int)strlen(z);
|
||||
if( p->n+n >= p->nAlloc ){
|
||||
p->nAlloc += p->n+n + 100;
|
||||
p->z = sqlite3_realloc(p->z, p->nAlloc);
|
||||
if( z==0 ){
|
||||
printf("Could not allocate %d bytes\n", p->nAlloc);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
memcpy(p->z+p->n, z, n+1);
|
||||
p->n += n;
|
||||
}
|
||||
|
||||
/* This is an sqlite3_exec() callback that will capture all
|
||||
** output in a Str.
|
||||
**
|
||||
** Columns are separated by ",". Rows are separated by "|".
|
||||
*/
|
||||
static int execCallback(void *pStr, int argc, char **argv, char **colv){
|
||||
int i;
|
||||
Str *p = (Str*)pStr;
|
||||
if( p->n ) strAppend(p, "|");
|
||||
for(i=0; i<argc; i++){
|
||||
const char *z = (const char*)argv[i];
|
||||
if( z==0 ) z = "NULL";
|
||||
if( i>0 ) strAppend(p, ",");
|
||||
strAppend(p, z);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Run an SQL statement constructing using sqlite3_vmprintf().
|
||||
** Return the number of errors.
|
||||
*/
|
||||
static int runSql(sqlite3 *db, const char *zFormat, ...){
|
||||
char *zSql;
|
||||
char *zErr = 0;
|
||||
int rc;
|
||||
int nErr = 0;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, zFormat);
|
||||
zSql = sqlite3_vmprintf(zFormat, ap);
|
||||
va_end(ap);
|
||||
if( zSql==0 ){
|
||||
printf("Out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
rc = sqlite3_exec(db, zSql, 0, 0, &zErr);
|
||||
if( rc || zErr ){
|
||||
printf("SQL error in [%s]: code=%d: %s\n", zSql, rc, zErr);
|
||||
nErr++;
|
||||
}
|
||||
sqlite3_free(zSql);
|
||||
return nErr;
|
||||
}
|
||||
|
||||
/*
|
||||
** Generate a prepared statement using a formatted string.
|
||||
*/
|
||||
static sqlite3_stmt *prepareSql(sqlite3 *db, const char *zFormat, ...){
|
||||
char *zSql;
|
||||
int rc;
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, zFormat);
|
||||
zSql = sqlite3_vmprintf(zFormat, ap);
|
||||
va_end(ap);
|
||||
if( zSql==0 ){
|
||||
printf("Out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
|
||||
if( rc ){
|
||||
printf("SQL error in [%s]: code=%d: %s\n", zSql, rc, sqlite3_errmsg(db));
|
||||
sqlite3_finalize(pStmt);
|
||||
pStmt = 0;
|
||||
}
|
||||
sqlite3_free(zSql);
|
||||
return pStmt;
|
||||
}
|
||||
|
||||
/*
|
||||
** Construct the standard selftest configuration for the database.
|
||||
*/
|
||||
static int buildSelftestTable(sqlite3 *db){
|
||||
int rc;
|
||||
sqlite3_stmt *pStmt;
|
||||
int tno = 110;
|
||||
char *zSql;
|
||||
char zHash[50];
|
||||
|
||||
rc = runSql(db,
|
||||
"CREATE TABLE IF NOT EXISTS selftest(\n"
|
||||
" tno INTEGER PRIMARY KEY, -- test number\n"
|
||||
" op TEXT, -- what kind of test\n"
|
||||
" sql TEXT, -- SQL text for the test\n"
|
||||
" ans TEXT -- expected answer\n"
|
||||
");"
|
||||
"INSERT INTO selftest"
|
||||
" VALUES(100,'memo','Hashes generated using --init',NULL);"
|
||||
);
|
||||
if( rc ) return 1;
|
||||
tno = 110;
|
||||
zSql = "SELECT type,name,tbl_name,sql FROM sqlite_master ORDER BY name";
|
||||
sha1Exec(db, zSql, zHash);
|
||||
rc = runSql(db,
|
||||
"INSERT INTO selftest(tno,op,sql,ans)"
|
||||
" VALUES(%d,'sha1',%Q,%Q)", tno, zSql, zHash);
|
||||
tno += 10;
|
||||
pStmt = prepareSql(db,
|
||||
"SELECT lower(name) FROM sqlite_master"
|
||||
" WHERE type='table' AND sql NOT GLOB 'CREATE VIRTUAL*'"
|
||||
" AND name<>'selftest'"
|
||||
" ORDER BY 1");
|
||||
if( pStmt==0 ) return 1;
|
||||
while( SQLITE_ROW==sqlite3_step(pStmt) ){
|
||||
zSql = sqlite3_mprintf("SELECT * FROM \"%w\" NOT INDEXED",
|
||||
sqlite3_column_text(pStmt, 0));
|
||||
if( zSql==0 ){
|
||||
printf("Of of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
sha1Exec(db, zSql, zHash);
|
||||
rc = runSql(db,
|
||||
"INSERT INTO selftest(tno,op,sql,ans)"
|
||||
" VALUES(%d,'sha1',%Q,%Q)", tno, zSql, zHash);
|
||||
tno += 10;
|
||||
sqlite3_free(zSql);
|
||||
if( rc ) break;
|
||||
}
|
||||
sqlite3_finalize(pStmt);
|
||||
if( rc ) return 1;
|
||||
rc = runSql(db,
|
||||
"INSERT INTO selftest(tno,op,sql,ans)"
|
||||
" VALUES(%d,'run','PRAGMA integrity_check','ok');", tno);
|
||||
if( rc ) return 1;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return true if the named table exists
|
||||
*/
|
||||
static int tableExists(sqlite3 *db, const char *zTab){
|
||||
return sqlite3_table_column_metadata(db, "main", zTab, 0, 0, 0, 0, 0, 0)
|
||||
== SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Default selftest table content, for use when there is no selftest table
|
||||
*/
|
||||
static char *azDefaultTest[] = {
|
||||
0, 0, 0, 0,
|
||||
"0", "memo", "Missing SELFTEST table - default checks only", "",
|
||||
"1", "run", "PRAGMA integrity_check", "ok"
|
||||
};
|
||||
|
||||
int main(int argc, char **argv){
|
||||
int eVolume = VOLUME_LOW; /* How much output to display */
|
||||
const char **azDb = 0; /* Name of the database file */
|
||||
int nDb = 0; /* Number of database files to check */
|
||||
int doInit = 0; /* True if --init is present */
|
||||
sqlite3 *db = 0; /* Open database connection */
|
||||
int rc; /* Return code from API calls */
|
||||
char *zErrMsg = 0; /* An error message return */
|
||||
char **azTest; /* Content of the selftest table */
|
||||
int nRow = 0, nCol = 0; /* Rows and columns in azTest[] */
|
||||
int i; /* Loop counter */
|
||||
int nErr = 0; /* Number of errors */
|
||||
int iDb; /* Loop counter for databases */
|
||||
Str str; /* Result accumulator */
|
||||
int nTest = 0; /* Number of tests run */
|
||||
|
||||
for(i=1; i<argc; i++){
|
||||
const char *z = argv[i];
|
||||
if( z[0]=='-' ){
|
||||
if( z[1]=='-' ) z++;
|
||||
if( strcmp(z, "-help")==0 ){
|
||||
printf("%s", zHelp);
|
||||
return 0;
|
||||
}else
|
||||
if( strcmp(z, "-init")==0 ){
|
||||
doInit = 1;
|
||||
}else
|
||||
if( strcmp(z, "-a")==0 ){
|
||||
if( eVolume>VOLUME_MIN) eVolume--;
|
||||
}else
|
||||
if( strcmp(z, "-v")==0 ){
|
||||
if( eVolume<VOLUME_MAX) eVolume++;
|
||||
}else
|
||||
{
|
||||
printf("unknown option: \"%s\"\nUse --help for more information\n",
|
||||
argv[i]);
|
||||
return 1;
|
||||
}
|
||||
}else{
|
||||
nDb++;
|
||||
azDb = sqlite3_realloc(azDb, nDb*sizeof(azDb[0]));
|
||||
if( azDb==0 ){
|
||||
printf("out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
azDb[nDb-1] = argv[i];
|
||||
}
|
||||
}
|
||||
if( nDb==0 ){
|
||||
printf("No databases specified. Use --help for more info\n");
|
||||
return 1;
|
||||
}
|
||||
if( eVolume>=VOLUME_LOW ){
|
||||
printf("SQLite %s\n", sqlite3_sourceid());
|
||||
}
|
||||
memset(&str, 0, sizeof(str));
|
||||
strAppend(&str, "\n");
|
||||
for(iDb=0; iDb<nDb; iDb++, sqlite3_close(db)){
|
||||
rc = sqlite3_open_v2(azDb[iDb], &db,
|
||||
doInit ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY, 0);
|
||||
if( rc ){
|
||||
printf("Cannot open \"%s\": %s\n", azDb[iDb], sqlite3_errmsg(db));
|
||||
return 1;
|
||||
}
|
||||
rc = sqlite3_create_function(db, "sha1", 1, SQLITE_UTF8, 0,
|
||||
sha1Func, 0, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3_create_function(db, "sha1_query", 1, SQLITE_UTF8, 0,
|
||||
sha1QueryFunc, 0, 0);
|
||||
}
|
||||
if( rc ){
|
||||
printf("Initialization error: %s\n", sqlite3_errmsg(db));
|
||||
sqlite3_close(db);
|
||||
return 1;
|
||||
}
|
||||
if( doInit && !tableExists(db, "selftest") ){
|
||||
buildSelftestTable(db);
|
||||
}
|
||||
if( !tableExists(db, "selftest") ){
|
||||
azTest = azDefaultTest;
|
||||
nCol = 4;
|
||||
nRow = 2;
|
||||
}else{
|
||||
rc = sqlite3_get_table(db,
|
||||
"SELECT tno,op,sql,ans FROM selftest ORDER BY tno",
|
||||
&azTest, &nRow, &nCol, &zErrMsg);
|
||||
if( rc || zErrMsg ){
|
||||
printf("Error querying selftest: %s\n", zErrMsg);
|
||||
sqlite3_free_table(azTest);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
for(i=1; i<=nRow; i++){
|
||||
int tno = atoi(azTest[i*nCol]);
|
||||
const char *zOp = azTest[i*nCol+1];
|
||||
const char *zSql = azTest[i*nCol+2];
|
||||
const char *zAns = azTest[i*nCol+3];
|
||||
|
||||
if( eVolume>=VOLUME_ECHO ){
|
||||
char *zQuote = sqlite3_mprintf("%q", zSql);
|
||||
printf("%d: %s %s\n", tno, zOp, zSql);
|
||||
sqlite3_free(zQuote);
|
||||
}
|
||||
if( strcmp(zOp,"memo")==0 ){
|
||||
if( eVolume>=VOLUME_LOW ){
|
||||
printf("%s: %s\n", azDb[iDb], zSql);
|
||||
}
|
||||
}else
|
||||
if( strcmp(zOp,"sha1")==0 ){
|
||||
char zOut[44];
|
||||
rc = sha1Exec(db, zSql, zOut);
|
||||
nTest++;
|
||||
if( eVolume>=VOLUME_VERBOSE ){
|
||||
printf("Result: %s\n", zOut);
|
||||
}
|
||||
if( rc ){
|
||||
nErr++;
|
||||
if( eVolume>=VOLUME_ERROR_ONLY ){
|
||||
printf("%d: error-code-%d: %s\n", tno, rc, sqlite3_errmsg(db));
|
||||
}
|
||||
}else if( strcmp(zAns,zOut)!=0 ){
|
||||
nErr++;
|
||||
if( eVolume>=VOLUME_ERROR_ONLY ){
|
||||
printf("%d: Expected: [%s]\n", tno, zAns);
|
||||
printf("%d: Got: [%s]\n", tno, zOut);
|
||||
}
|
||||
}
|
||||
}else
|
||||
if( strcmp(zOp,"run")==0 ){
|
||||
str.n = 0;
|
||||
str.z[0] = 0;
|
||||
zErrMsg = 0;
|
||||
rc = sqlite3_exec(db, zSql, execCallback, &str, &zErrMsg);
|
||||
nTest++;
|
||||
if( eVolume>=VOLUME_VERBOSE ){
|
||||
printf("Result: %s\n", str.z);
|
||||
}
|
||||
if( rc || zErrMsg ){
|
||||
nErr++;
|
||||
if( eVolume>=VOLUME_ERROR_ONLY ){
|
||||
printf("%d: error-code-%d: %s\n", tno, rc, zErrMsg);
|
||||
}
|
||||
sqlite3_free(zErrMsg);
|
||||
}else if( strcmp(zAns,str.z)!=0 ){
|
||||
nErr++;
|
||||
if( eVolume>=VOLUME_ERROR_ONLY ){
|
||||
printf("%d: Expected: [%s]\n", tno, zAns);
|
||||
printf("%d: Got: [%s]\n", tno, str.z);
|
||||
}
|
||||
}
|
||||
}else
|
||||
{
|
||||
printf("Unknown operation \"%s\" on selftest line %d\n", zOp, tno);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if( azTest!=azDefaultTest ) sqlite3_free_table(azTest);
|
||||
}
|
||||
if( eVolume>=VOLUME_LOW || (nErr>0 && eVolume>=VOLUME_ERROR_ONLY) ){
|
||||
printf("%d errors out of %d tests on %d databases\n", nErr, nTest, nDb);
|
||||
}
|
||||
return nErr;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
# 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
|
||||
@@ -52,7 +52,7 @@ do_faultsim_test 2 -prep {
|
||||
error [sqlite3_errmsg db]
|
||||
}
|
||||
} -test {
|
||||
faultsim_test_result {1 {no such rowid: -1}}
|
||||
faultsim_test_result {1 {no such rowid: -1}} {1 {disk I/O error}}
|
||||
close $::blob
|
||||
}
|
||||
|
||||
|
||||
@@ -370,4 +370,14 @@ 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
|
||||
pgsz, nCount, sz, iVariance+1
|
||||
);
|
||||
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, nIn, 1, in);
|
||||
nRead = fread(pBuf, (size_t)nIn, 1, in);
|
||||
fclose(in);
|
||||
if( nRead!=1 ){
|
||||
sqlite3_free(pBuf);
|
||||
return 0;
|
||||
}
|
||||
if( pnByte ) *pnByte = nIn;
|
||||
if( pnByte ) *pnByte = (int)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 100000
|
||||
sqlite3_soft_heap_limit 200000
|
||||
sqlite3_memory_highwater 1
|
||||
execsql {SELECT * FROM abc}
|
||||
set nMaxBytes [sqlite3_memory_highwater 1]
|
||||
puts -nonewline " (Highwater mark: $nMaxBytes) "
|
||||
expr $nMaxBytes <= 110000
|
||||
expr $nMaxBytes <= 210000
|
||||
} {1}
|
||||
do_test malloc5-4.3 {
|
||||
# Check that the content of table abc is at least roughly as expected.
|
||||
|
||||
@@ -754,6 +754,10 @@ 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,6 +116,37 @@ 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|}
|
||||
|
||||
|
||||
|
||||
|
||||
+272
-1
@@ -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\n"
|
||||
" --testset T Run test-set T (main, cte, rtree, orm, debug)\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,6 +1307,275 @@ 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.
|
||||
*/
|
||||
@@ -1610,6 +1879,8 @@ 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 ){
|
||||
|
||||
+24
-16
@@ -148,60 +148,68 @@ do_execsql_test tabfunc01-600 {
|
||||
|
||||
|
||||
do_test tabfunc01-700 {
|
||||
set PTR [intarray_addr 5 7 13 17 23]
|
||||
set PTR1 [intarray_addr 5 7 13 17 23]
|
||||
db eval {
|
||||
SELECT b FROM t600, carray($PTR,5) WHERE a=value;
|
||||
SELECT b FROM t600, carray($PTR1,5) WHERE a=value;
|
||||
}
|
||||
} {(005) (007) (013) (017) (023)}
|
||||
do_test tabfunc01-701 {
|
||||
db eval {
|
||||
SELECT b FROM t600 WHERE a IN carray($PTR,5,'int32');
|
||||
SELECT b FROM t600 WHERE a IN carray($PTR1,5,'int32');
|
||||
}
|
||||
} {(005) (007) (013) (017) (023)}
|
||||
do_test tabfunc01-702 {
|
||||
db eval {
|
||||
SELECT b FROM t600 WHERE a IN carray($PTR,4,'int32');
|
||||
SELECT b FROM t600 WHERE a IN carray($PTR1,4,'int32');
|
||||
}
|
||||
} {(005) (007) (013) (017)}
|
||||
do_catchsql_test tabfunc01-710 {
|
||||
SELECT b FROM t600 WHERE a IN carray($PTR,5,'int33');
|
||||
SELECT b FROM t600 WHERE a IN carray($PTR1,5,'int33');
|
||||
} {1 {unknown datatype: 'int33'}}
|
||||
|
||||
do_test tabfunc01-720 {
|
||||
set PTR [int64array_addr 5 7 13 17 23]
|
||||
set PTR2 [int64array_addr 5 7 13 17 23]
|
||||
db eval {
|
||||
SELECT b FROM t600, carray($PTR,5,'int64') WHERE a=value;
|
||||
SELECT b FROM t600, carray($PTR2,5,'int64') WHERE a=value;
|
||||
}
|
||||
} {(005) (007) (013) (017) (023)}
|
||||
do_test tabfunc01-721 {
|
||||
db eval {
|
||||
SELECT remember(123,$PTR);
|
||||
SELECT value FROM carray($PTR,5,'int64');
|
||||
SELECT remember(123,$PTR2);
|
||||
SELECT value FROM carray($PTR2,5,'int64');
|
||||
}
|
||||
} {123 123 7 13 17 23}
|
||||
do_test tabfunc01-722 {
|
||||
set PTR2 [expr {$PTR+16}]
|
||||
set PTR3 [expr {$PTR2+16}]
|
||||
db eval {
|
||||
SELECT remember(987,$PTR2);
|
||||
SELECT value FROM carray($PTR,5,'int64');
|
||||
SELECT remember(987,$PTR3);
|
||||
SELECT value FROM carray($PTR2,5,'int64');
|
||||
}
|
||||
} {987 123 7 987 17 23}
|
||||
|
||||
do_test tabfunc01-730 {
|
||||
set PTR [doublearray_addr 5.0 7.0 13.0 17.0 23.0]
|
||||
set PTR4 [doublearray_addr 5.0 7.0 13.0 17.0 23.0]
|
||||
db eval {
|
||||
SELECT b FROM t600, carray($PTR,5,'double') WHERE a=value;
|
||||
SELECT b FROM t600, carray($PTR4,5,'double') WHERE a=value;
|
||||
}
|
||||
} {(005) (007) (013) (017) (023)}
|
||||
|
||||
do_test tabfunc01-740 {
|
||||
set PTR [textarray_addr 5 7 13 17 23]
|
||||
set PTR5 [textarray_addr x5 x7 x13 x17 x23]
|
||||
db eval {
|
||||
SELECT b FROM t600, carray($PTR,5,'char*') WHERE a=value;
|
||||
SELECT b FROM t600, carray($PTR5,5,'char*') WHERE a=trim(value,'x');
|
||||
}
|
||||
} {(005) (007) (013) (017) (023)}
|
||||
|
||||
do_test tabfunc01-750 {
|
||||
db eval {
|
||||
SELECT aa.value, bb.value, '|'
|
||||
FROM carray($PTR4,5,'double') AS aa
|
||||
JOIN carray($PTR5,5,'char*') AS bb ON aa.rowid=bb.rowid;
|
||||
}
|
||||
} {5.0 x5 | 7.0 x7 | 13.0 x13 | 17.0 x17 | 23.0 x23 |}
|
||||
|
||||
# Free up memory allocations
|
||||
intarray_addr
|
||||
int64array_addr
|
||||
doublearray_addr
|
||||
|
||||
+29
-2
@@ -919,10 +919,37 @@ proc normalize_list {L} {
|
||||
set L2
|
||||
}
|
||||
|
||||
proc do_execsql_test {testname sql {result {}}} {
|
||||
# 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?"
|
||||
}]
|
||||
}
|
||||
|
||||
fix_testname testname
|
||||
uplevel do_test [list $testname] [list "execsql {$sql}"] [list [list {*}$result]]
|
||||
|
||||
uplevel do_test \
|
||||
[list $testname] \
|
||||
[list "execsql {$sql} $db"] \
|
||||
[list [list {*}$result]]
|
||||
}
|
||||
|
||||
proc do_catchsql_test {testname sql result} {
|
||||
fix_testname testname
|
||||
uplevel do_test [list $testname] [list "catchsql {$sql}"] [list $result]
|
||||
|
||||
@@ -42,7 +42,7 @@ do_test tkt-78e04-1.3 {
|
||||
} {}
|
||||
do_test tkt-78e04-1.4 {
|
||||
execsql {
|
||||
EXPLAIN QUERY PLAN SELECT "" FROM "" WHERE "" LIKE 'abc%';
|
||||
EXPLAIN QUERY PLAN SELECT "" FROM "" WHERE "" LIKE '1abc%';
|
||||
}
|
||||
} {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, 'James');
|
||||
INSERT INTO t6 VALUES(4, 'John');
|
||||
INSERT INTO t6 VALUES(3, '8James');
|
||||
INSERT INTO t6 VALUES(4, '8John');
|
||||
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>'James'" {4 1 5}
|
||||
{xFilter {SELECT rowid, a, b FROM 't6' WHERE b > ?} James}
|
||||
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.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.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.3 "SELECT a FROM e6 WHERE b LIKE 'J%'" {3 4}
|
||||
{xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} J%}
|
||||
1.3 "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%}
|
||||
1.4 "SELECT a FROM e6 WHERE b LIKE '8j%'" {3 4}
|
||||
{xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8j%}
|
||||
} {
|
||||
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 'J%'" {3 4}
|
||||
{xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} J%}
|
||||
2.1 "SELECT a FROM e6 WHERE b LIKE '8J%'" {3 4}
|
||||
{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%}
|
||||
2.2 "SELECT a FROM e6 WHERE b LIKE '8j%'" {}
|
||||
{xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8j%}
|
||||
} {
|
||||
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 'abc'" {
|
||||
1 "SELECT * FROM e6 WHERE b LIKE '8abc'" {
|
||||
xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b like ?}
|
||||
xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} abc
|
||||
xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8abc
|
||||
}
|
||||
|
||||
2 "SELECT * FROM e6 WHERE b GLOB 'abc'" {
|
||||
2 "SELECT * FROM e6 WHERE b GLOB '8abc'" {
|
||||
xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b glob ?}
|
||||
xFilter {SELECT rowid, a, b FROM 't6' WHERE b glob ?} abc
|
||||
xFilter {SELECT rowid, a, b FROM 't6' WHERE b glob ?} 8abc
|
||||
}
|
||||
} {
|
||||
do_test 1.$tn {
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
** 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_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \\
|
||||
| .\Replace.exe "^\s+/EXPORT:_?(sqlite3(?:session|changeset)?_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \\
|
||||
| sort >> sqlite3.def
|
||||
}]]
|
||||
|
||||
|
||||
@@ -331,6 +331,9 @@ set pragma_def {
|
||||
NAME: shrink_memory
|
||||
FLAG: NoColumns
|
||||
|
||||
NAME: vdbe_cycle_limit
|
||||
FLAG: NoColumns
|
||||
|
||||
NAME: busy_timeout
|
||||
FLAG: Result0
|
||||
COLS: timeout
|
||||
|
||||
+10
-2
@@ -73,7 +73,13 @@ 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 declpattern {^ *([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]+)(\(.*)$}
|
||||
|
||||
# Force the output to use unix line endings, even on Windows.
|
||||
fconfigure stdout -translation lf
|
||||
@@ -121,7 +127,9 @@ foreach file $filelist {
|
||||
if {[regexp $varpattern $line] && ![regexp {^ *typedef} $line]} {
|
||||
set line "SQLITE_API $line"
|
||||
} else {
|
||||
if {[regexp $declpattern $line all rettype funcname rest]} {
|
||||
if {[regexp $declpattern1 $line all rettype funcname rest] || \
|
||||
[regexp $declpattern2 $line all rettype funcname rest] || \
|
||||
[regexp $declpattern3 $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