Compare commits
120 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 093d63bf34 | |||
| 20a1f35928 | |||
| 15ca9e3e8c | |||
| ffc78a41ea | |||
| 68cf69ed8d | |||
| 58db4c760f | |||
| 840c300f4a | |||
| ffdab721a3 | |||
| 42f3c5ff25 | |||
| 41a6f2cb6d | |||
| 70acb0aa6b | |||
| ef29f73479 | |||
| 69d2d35523 | |||
| 1bf208c701 | |||
| 393344f928 | |||
| a10b999d14 | |||
| 2d066bbfd8 | |||
| 6131adc074 | |||
| 980e2cd39a | |||
| 6630f9407c | |||
| 3baed31edc | |||
| 8368692815 | |||
| 7bdbe301f6 | |||
| f7c8a35b8d | |||
| 069720ea8b | |||
| 98cb7a4894 | |||
| f94c1902b9 | |||
| 391ac1b959 | |||
| 45fb850b35 | |||
| b649be3c3b | |||
| 23355215fb | |||
| ac8ba26ecb | |||
| b0f0dc3073 | |||
| 4811a710af | |||
| 9c6396ecc7 | |||
| 8784efaea9 | |||
| 14714167f7 | |||
| a48b020ddd | |||
| 5f9d192de9 | |||
| bcdb28dff3 | |||
| 49cc2f3b9c | |||
| 8d43d8443d | |||
| 6344edda80 | |||
| ad7fd5d096 | |||
| 93b7731485 | |||
| da57d9676a | |||
| f111203287 | |||
| 9c42626e43 | |||
| f0cb61d6c2 | |||
| 302ce47519 | |||
| b2194cea4e | |||
| 5e9825ecc4 | |||
| e341ec699f | |||
| 2825e4ebb1 | |||
| dd8a4af8e7 | |||
| bda30ce4d8 | |||
| 6a8a629e6b | |||
| d7fd899eeb | |||
| 5597cd42b8 | |||
| 96acafbea7 | |||
| e39ef31cd6 | |||
| 43c4ac8bfe | |||
| 171d16bb21 | |||
| 3432821192 | |||
| 8abed7b907 | |||
| 6bd4140d33 | |||
| f7e867c347 | |||
| bc8f68a3a0 | |||
| 1fcfa7240f | |||
| 007c843b0f | |||
| 5facffbc70 | |||
| fda0867873 | |||
| 4f46b58a2d | |||
| d6ec7a6ab3 | |||
| c0ec2f7762 | |||
| 8d3e15eec4 | |||
| 4f4e49a98b | |||
| 2e178d7321 | |||
| 7436f1e491 | |||
| 3993678d3d | |||
| cc398969e0 | |||
| b0b6f8783c | |||
| 57a93fa38c | |||
| a15a7c352c | |||
| 57f29b7bfb | |||
| cf7c8370d1 | |||
| 136102beda | |||
| 57e3ba7623 | |||
| 62856465f2 | |||
| 26f625fbf4 | |||
| a224ee2a1b | |||
| e28eb64d09 | |||
| 091881bbb0 | |||
| c551550808 | |||
| 713f34ace9 | |||
| f4bc6c43d7 | |||
| 46e835a2c4 | |||
| 501ea05630 | |||
| ee269a60c9 | |||
| d9274a8ae3 | |||
| 0fae06fcb6 | |||
| 4e6e5cef6c | |||
| e2d27e0259 | |||
| a9abfb1e6c | |||
| 4d1c6845ff | |||
| d446e79545 | |||
| e84c498be1 | |||
| c083cb4422 | |||
| 35043cc32a | |||
| 1db7db1f03 | |||
| 00c3ef2df9 | |||
| 31a13548f8 | |||
| e616735cb1 | |||
| a5bb43518b | |||
| 99abe5c478 | |||
| 3ec8665e22 | |||
| cb7d541d3a | |||
| 4dcac40e3d | |||
| 7de2c3e5ee | |||
| ac442f41c1 |
+15
-4
@@ -180,7 +180,7 @@ LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \
|
||||
func.lo global.lo hash.lo \
|
||||
icu.lo insert.lo json1.lo legacy.lo loadext.lo \
|
||||
main.lo malloc.lo mem0.lo mem1.lo mem2.lo mem3.lo mem5.lo \
|
||||
memjournal.lo \
|
||||
memdb.lo memjournal.lo \
|
||||
mutex.lo mutex_noop.lo mutex_unix.lo mutex_w32.lo \
|
||||
notify.lo opcodes.lo os.lo os_unix.lo os_win.lo \
|
||||
pager.lo parse.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \
|
||||
@@ -240,6 +240,7 @@ SRC = \
|
||||
$(TOP)/src/mem2.c \
|
||||
$(TOP)/src/mem3.c \
|
||||
$(TOP)/src/mem5.c \
|
||||
$(TOP)/src/memdb.c \
|
||||
$(TOP)/src/memjournal.c \
|
||||
$(TOP)/src/msvc.h \
|
||||
$(TOP)/src/mutex.c \
|
||||
@@ -591,6 +592,7 @@ SHELL_OPT += -DSQLITE_INTROSPECTION_PRAGMAS
|
||||
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
|
||||
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ
|
||||
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
|
||||
FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000
|
||||
FUZZCHECK_SRC = $(TOP)/test/fuzzcheck.c $(TOP)/test/ossfuzz.c
|
||||
DBFUZZ_OPT =
|
||||
|
||||
@@ -648,6 +650,9 @@ ossshell$(TEXE): $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3.
|
||||
$(LTLINK) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/ossshell.c \
|
||||
$(TOP)/test/ossfuzz.c sqlite3.c $(TLIBS)
|
||||
|
||||
sessionfuzz$(TEXE): $(TOP)/test/sessionfuzz.c sqlite3.c sqlite3.h
|
||||
$(CC) $(CFLAGS) -I. -o $@ $(TOP)/test/sessionfuzz.c $(TLIBS)
|
||||
|
||||
dbfuzz$(TEXE): $(TOP)/test/dbfuzz.c sqlite3.c sqlite3.h
|
||||
$(LTLINK) -o $@ $(DBFUZZ_OPT) $(TOP)/test/dbfuzz.c sqlite3.c $(TLIBS)
|
||||
|
||||
@@ -828,6 +833,9 @@ mem3.lo: $(TOP)/src/mem3.c $(HDR)
|
||||
mem5.lo: $(TOP)/src/mem5.c $(HDR)
|
||||
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem5.c
|
||||
|
||||
memdb.lo: $(TOP)/src/memdb.c $(HDR)
|
||||
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/memdb.c
|
||||
|
||||
memjournal.lo: $(TOP)/src/memjournal.c $(HDR)
|
||||
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/memjournal.c
|
||||
|
||||
@@ -1161,14 +1169,17 @@ fulltestonly: $(TESTPROGS) fuzztest
|
||||
./testfixture$(TEXE) $(TOP)/test/full.test
|
||||
|
||||
# Fuzz testing
|
||||
fuzztest: fuzzcheck$(TEXE) $(FUZZDATA)
|
||||
fuzztest: fuzzcheck$(TEXE) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessionfuzz-data1.db
|
||||
./fuzzcheck$(TEXE) $(FUZZDATA)
|
||||
./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db
|
||||
|
||||
fastfuzztest: fuzzcheck$(TEXE) $(FUZZDATA)
|
||||
fastfuzztest: fuzzcheck$(TEXE) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessionfuzz-data1.db
|
||||
./fuzzcheck$(TEXE) --limit-mem 100M $(FUZZDATA)
|
||||
./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db
|
||||
|
||||
valgrindfuzz: fuzzcheck$(TEXT) $(FUZZDATA)
|
||||
valgrindfuzz: fuzzcheck$(TEXT) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessionfuzz-data1.db
|
||||
valgrind ./fuzzcheck$(TEXE) --cell-size-check --limit-mem 10M --timeout 600 $(FUZZDATA)
|
||||
valgrind ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db
|
||||
|
||||
# The veryquick.test TCL tests.
|
||||
#
|
||||
|
||||
+17
-10
@@ -1186,7 +1186,7 @@ LIBOBJS0 = vdbe.lo parse.lo alter.lo analyze.lo attach.lo auth.lo \
|
||||
func.lo global.lo hash.lo \
|
||||
icu.lo insert.lo legacy.lo loadext.lo \
|
||||
main.lo malloc.lo mem0.lo mem1.lo mem2.lo mem3.lo mem5.lo \
|
||||
memjournal.lo \
|
||||
memdb.lo memjournal.lo \
|
||||
mutex.lo mutex_noop.lo mutex_unix.lo mutex_w32.lo \
|
||||
notify.lo opcodes.lo os.lo os_unix.lo os_win.lo \
|
||||
pager.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \
|
||||
@@ -1259,6 +1259,7 @@ SRC00 = \
|
||||
$(TOP)\src\mem2.c \
|
||||
$(TOP)\src\mem3.c \
|
||||
$(TOP)\src\mem5.c \
|
||||
$(TOP)\src\memdb.c \
|
||||
$(TOP)\src\memjournal.c \
|
||||
$(TOP)\src\mutex.c \
|
||||
$(TOP)\src\mutex_noop.c \
|
||||
@@ -1615,12 +1616,11 @@ SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_RTREE
|
||||
#
|
||||
MPTESTER_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5
|
||||
FUZZERSHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1
|
||||
FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ -DSQLITE_MAX_MEMORY=50000000
|
||||
FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ -DSQLITE_MAX_MEMORY=50000000 -DSQLITE_PRINTF_PRECISION_LIMIT=1000
|
||||
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.
|
||||
@@ -1688,7 +1688,7 @@ dbhash.exe: $(TOP)\tool\dbhash.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) $(TOP)\tool\dbhash.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
scrub.exe: $(TOP)\ext\misc\scrub.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) $(TOP)\ext\misc\scrub.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
$(LTLINK) $(NO_WARN) -DSCRUB_STANDALONE=1 $(TOP)\ext\misc\scrub.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
srcck1.exe: $(TOP)\tool\srcck1.c
|
||||
$(BCC) $(NO_WARN) -Fe$@ $(TOP)\tool\srcck1.c
|
||||
@@ -1708,6 +1708,9 @@ fuzzcheck.exe: $(FUZZCHECK_SRC) $(SQLITE3C) $(SQLITE3H)
|
||||
ossshell.exe: $(OSSSHELL_SRC) $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) $(FUZZCHECK_COMPILE_OPTS) $(OSSSHELL_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
sessionfuzz.exe: zlib $(TOP)\test\sessionfuzz.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) -I$(ZLIBINCDIR) $(TOP)\test\sessionfuzz.c /link $(LDFLAGS) $(LTLINKOPTS) /LIBPATH:$(ZLIBLIBDIR) $(ZLIBLIB)
|
||||
|
||||
mptester.exe: $(TOP)\mptest\mptest.c $(SQLITE3C) $(SQLITE3H)
|
||||
$(LTLINK) $(NO_WARN) $(MPTESTER_COMPILE_OPTS) $(TOP)\mptest\mptest.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
|
||||
@@ -1909,6 +1912,9 @@ mem3.lo: $(TOP)\src\mem3.c $(HDR)
|
||||
mem5.lo: $(TOP)\src\mem5.c $(HDR)
|
||||
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\mem5.c
|
||||
|
||||
memdb.lo: $(TOP)\src\memdb.c $(HDR)
|
||||
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\memdb.c
|
||||
|
||||
memjournal.lo: $(TOP)\src\memjournal.c $(HDR)
|
||||
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\memjournal.c
|
||||
|
||||
@@ -2252,6 +2258,7 @@ TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
|
||||
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_DEFAULT_PAGE_SIZE=1024
|
||||
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB
|
||||
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB
|
||||
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_JSON1
|
||||
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) $(TEST_CCONV_OPTS)
|
||||
|
||||
TESTFIXTURE_SRC0 = $(TESTEXT) $(TESTSRC2)
|
||||
@@ -2365,11 +2372,11 @@ sqlite3_checker.exe: sqlite3_checker.c $(LIBRESOBJS)
|
||||
$(LTLINK) $(NO_WARN) -DBUILD_sqlite -I$(TCLINCDIR) sqlite3_checker.c \
|
||||
/link $(LDFLAGS) $(LTLINKOPTS) $(TCLLIBPATHS) $(LTLIBPATHS) $(LIBRESOBJS) $(TCLLIBS) $(LTLIBS) $(TLIBS)
|
||||
|
||||
dbdump.exe: $(TOP)\ext\misc\dbdump.c $(SQLITE3C) $(SQLITE3H)
|
||||
dbdump.exe: $(TOP)\ext\misc\dbdump.c $(SQLITE3C) $(SQLITE3H) $(LIBRESOBJS)
|
||||
$(LTLINK) $(NO_WARN) -DDBDUMP_STANDALONE $(TOP)\ext\misc\dbdump.c $(SQLITE3C) \
|
||||
/link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS)
|
||||
|
||||
testloadext.lo: $(TOP)\src\test_loadext.c
|
||||
testloadext.lo: $(TOP)\src\test_loadext.c $(SQLITE3H)
|
||||
$(LTCOMPILE) $(NO_WARN) -c $(TOP)\src\test_loadext.c
|
||||
|
||||
testloadext.dll: testloadext.lo
|
||||
@@ -2422,9 +2429,6 @@ 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 \
|
||||
$(TOP)\ext\rbu\rbu.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
|
||||
@@ -2464,7 +2468,10 @@ clean:
|
||||
del /Q sqlite3_analyzer.exe sqlite3_analyzer.c 2>NUL
|
||||
del /Q sqlite-*-output.vsix 2>NUL
|
||||
del /Q fuzzershell.exe fuzzcheck.exe sqldiff.exe dbhash.exe 2>NUL
|
||||
del /Q sqltclsh.exe 2>NUL
|
||||
del /Q sqltclsh.* 2>NUL
|
||||
del /Q dbfuzz.exe sessionfuzz.exe 2>NUL
|
||||
del /Q kvtest.exe ossshell.exe scrub.exe 2>NUL
|
||||
del /Q showshm.exe sqlite3_checker.* sqlite3_expert.exe 2>NUL
|
||||
del /Q fts5.* fts5parse.* 2>NUL
|
||||
del /Q lsm.h lsm1.c 2>NUL
|
||||
# <</mark>>
|
||||
|
||||
@@ -14,15 +14,17 @@ SQLite sources are managed using the
|
||||
[Fossil](https://www.fossil-scm.org/), a distributed version control system
|
||||
that was specifically designed to support SQLite development.
|
||||
If you do not want to use Fossil, you can download tarballs or ZIP
|
||||
archives as follows:
|
||||
archives or [SQLite archives](https://sqlite.org/cli.html#sqlar) as follows:
|
||||
|
||||
* Lastest trunk check-in:
|
||||
<https://www.sqlite.org/src/tarball/sqlite.tar.gz> or
|
||||
<https://www.sqlite.org/src/zip/sqlite.zip>.
|
||||
* Lastest trunk check-in as
|
||||
[Tarball](https://www.sqlite.org/src/tarball/sqlite.tar.gz),
|
||||
[ZIP-archive](https://www.sqlite.org/src/zip/sqlite.zip), or
|
||||
[SQLite-archive](https://www.sqlite.org/src/sqlar/sqlite.sqlar).
|
||||
|
||||
* Latest release:
|
||||
<https://www.sqlite.org/src/tarball/sqlite.tar.gz?r=release> or
|
||||
<https://www.sqlite.org/src/zip/sqlite.zip?r=release>.
|
||||
* Latest release as
|
||||
[Tarball](https://www.sqlite.org/src/tarball/sqlite.tar.gz?r=release),
|
||||
[ZIP-archive](https://www.sqlite.org/src/zip/sqlite.zip?r=release), or
|
||||
[SQLite-archive](https://www.sqlite.org/src/sqlar/sqlite.sqlar?r=release).
|
||||
|
||||
* For other check-ins, substitute an appropriate branch name or
|
||||
tag or hash prefix for "release" in the URLs of the previous
|
||||
|
||||
@@ -931,6 +931,7 @@ LIBRESOBJS =
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_STMTVTAB
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_ENABLE_DBSTAT_VTAB
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC -DSQLITE_INTROSPECTION_PRAGMAS
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_RTREE
|
||||
!ENDIF
|
||||
|
||||
|
||||
|
||||
+2
-1
@@ -93,8 +93,9 @@ int main(int argc, char **argv){
|
||||
}else{
|
||||
for(i=1; i<(argc-1); i++){
|
||||
char *zArg = argv[i];
|
||||
int nArg;
|
||||
if( zArg[0]=='-' && zArg[1]=='-' && zArg[2]!=0 ) zArg++;
|
||||
int nArg = (int)strlen(zArg);
|
||||
nArg = (int)strlen(zArg);
|
||||
if( nArg>=2 && 0==sqlite3_strnicmp(zArg, "-file", nArg) ){
|
||||
if( ++i==(argc-1) ) option_requires_argument("-file");
|
||||
rc = readSqlFromFile(p, argv[i], &zErr);
|
||||
|
||||
@@ -5529,7 +5529,6 @@ int sqlite3Fts3UpdateMethod(
|
||||
){
|
||||
Fts3Table *p = (Fts3Table *)pVtab;
|
||||
int rc = SQLITE_OK; /* Return Code */
|
||||
int isRemove = 0; /* True for an UPDATE or DELETE */
|
||||
u32 *aSzIns = 0; /* Sizes of inserted documents */
|
||||
u32 *aSzDel = 0; /* Sizes of deleted documents */
|
||||
int nChng = 0; /* Net change in number of documents */
|
||||
@@ -5627,7 +5626,6 @@ int sqlite3Fts3UpdateMethod(
|
||||
if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){
|
||||
assert( sqlite3_value_type(apVal[0])==SQLITE_INTEGER );
|
||||
rc = fts3DeleteByRowid(p, apVal[0], &nChng, aSzDel);
|
||||
isRemove = 1;
|
||||
}
|
||||
|
||||
/* If this is an INSERT or UPDATE operation, insert the new record. */
|
||||
@@ -5639,7 +5637,7 @@ int sqlite3Fts3UpdateMethod(
|
||||
rc = FTS_CORRUPT_VTAB;
|
||||
}
|
||||
}
|
||||
if( rc==SQLITE_OK && (!isRemove || *pRowid!=p->iPrevDocid ) ){
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = fts3PendingTermsDocid(p, 0, iLangid, *pRowid);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
|
||||
@@ -1676,7 +1676,7 @@ Fts5ExprPhrase *sqlite3Fts5ParseTerm(
|
||||
** no token characters at all. (e.g ... MATCH '""'). */
|
||||
sCtx.pPhrase = sqlite3Fts5MallocZero(&pParse->rc, sizeof(Fts5ExprPhrase));
|
||||
}else if( sCtx.pPhrase->nTerm ){
|
||||
sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = bPrefix;
|
||||
sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = (u8)bPrefix;
|
||||
}
|
||||
pParse->apPhrase[pParse->nPhrase-1] = sCtx.pPhrase;
|
||||
}
|
||||
|
||||
+14
-15
@@ -293,7 +293,6 @@ static char **tableColumnList(DState *p, const char *zTab){
|
||||
** ordinary column in the table. Verify that azRowid[j] is a valid
|
||||
** name for the rowid before adding it to azCol[0]. WITHOUT ROWID
|
||||
** tables will fail this last check */
|
||||
int rc;
|
||||
rc = sqlite3_table_column_metadata(p->db,0,zTab,azRowid[j],0,0,0,0,0);
|
||||
if( rc==SQLITE_OK ) azCol[0] = azRowid[j];
|
||||
break;
|
||||
@@ -455,12 +454,12 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
|
||||
if( strcmp(zType, "table")==0 ){
|
||||
DText sSelect;
|
||||
DText sTable;
|
||||
char **azCol;
|
||||
char **azTCol;
|
||||
int i;
|
||||
int nCol;
|
||||
|
||||
azCol = tableColumnList(p, zTable);
|
||||
if( azCol==0 ) return 0;
|
||||
azTCol = tableColumnList(p, zTable);
|
||||
if( azTCol==0 ) return 0;
|
||||
|
||||
initText(&sTable);
|
||||
appendText(&sTable, "INSERT INTO ", 0);
|
||||
@@ -473,12 +472,12 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
|
||||
** In other words: "INSERT INTO tab(rowid,a,b,c,...) VALUES(...)"
|
||||
** instead of the usual "INSERT INTO tab VALUES(...)".
|
||||
*/
|
||||
if( azCol[0] ){
|
||||
if( azTCol[0] ){
|
||||
appendText(&sTable, "(", 0);
|
||||
appendText(&sTable, azCol[0], 0);
|
||||
for(i=1; azCol[i]; i++){
|
||||
appendText(&sTable, azTCol[0], 0);
|
||||
for(i=1; azTCol[i]; i++){
|
||||
appendText(&sTable, ",", 0);
|
||||
appendText(&sTable, azCol[i], quoteChar(azCol[i]));
|
||||
appendText(&sTable, azTCol[i], quoteChar(azTCol[i]));
|
||||
}
|
||||
appendText(&sTable, ")", 0);
|
||||
}
|
||||
@@ -487,19 +486,19 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
|
||||
/* Build an appropriate SELECT statement */
|
||||
initText(&sSelect);
|
||||
appendText(&sSelect, "SELECT ", 0);
|
||||
if( azCol[0] ){
|
||||
appendText(&sSelect, azCol[0], 0);
|
||||
if( azTCol[0] ){
|
||||
appendText(&sSelect, azTCol[0], 0);
|
||||
appendText(&sSelect, ",", 0);
|
||||
}
|
||||
for(i=1; azCol[i]; i++){
|
||||
appendText(&sSelect, azCol[i], quoteChar(azCol[i]));
|
||||
if( azCol[i+1] ){
|
||||
for(i=1; azTCol[i]; i++){
|
||||
appendText(&sSelect, azTCol[i], quoteChar(azTCol[i]));
|
||||
if( azTCol[i+1] ){
|
||||
appendText(&sSelect, ",", 0);
|
||||
}
|
||||
}
|
||||
nCol = i;
|
||||
if( azCol[0]==0 ) nCol--;
|
||||
freeColumnList(azCol);
|
||||
if( azTCol[0]==0 ) nCol--;
|
||||
freeColumnList(azTCol);
|
||||
appendText(&sSelect, " FROM ", 0);
|
||||
appendText(&sSelect, zTable, quoteChar(zTable));
|
||||
|
||||
|
||||
@@ -496,6 +496,7 @@ static void fsdirResetCursor(fsdir_cursor *pCur){
|
||||
pCur->zPath = 0;
|
||||
pCur->zBase = 0;
|
||||
pCur->nBase = 0;
|
||||
pCur->nLvl = 0;
|
||||
pCur->iLvl = -1;
|
||||
pCur->iRowid = 1;
|
||||
}
|
||||
|
||||
+2
-2
@@ -131,7 +131,7 @@ static void scrubBackupWrite(ScrubState *p, int pgno, const u8 *pData){
|
||||
scrubBackupErr(p, "write failed for page %d", pgno);
|
||||
p->rcErr = SQLITE_IOERR;
|
||||
}
|
||||
if( pgno>p->iLastPage ) p->iLastPage = pgno;
|
||||
if( (u32)pgno>p->iLastPage ) p->iLastPage = pgno;
|
||||
}
|
||||
|
||||
/* Prepare a statement against the "db" database. */
|
||||
@@ -459,7 +459,7 @@ static void scrubBackupBtree(ScrubState *p, int pgno, int iDepth){
|
||||
nLocal = K<=X ? K : M;
|
||||
if( pc+nLocal > p->szUsable-4 ){ ln=__LINE__; goto btree_corrupt; }
|
||||
iChild = scrubBackupInt32(&a[pc+nLocal]);
|
||||
scrubBackupOverflow(p, iChild, P-nLocal);
|
||||
scrubBackupOverflow(p, iChild, (u32)(P-nLocal));
|
||||
}
|
||||
|
||||
/* Walk the right-most tree */
|
||||
|
||||
+103
-16
@@ -18,6 +18,12 @@
|
||||
SQLITE_EXTENSION_INIT1
|
||||
|
||||
#ifndef SQLITE_AMALGAMATION
|
||||
# if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
|
||||
# define NDEBUG 1
|
||||
# endif
|
||||
# if defined(NDEBUG) && defined(SQLITE_DEBUG)
|
||||
# undef NDEBUG
|
||||
# endif
|
||||
# include <string.h>
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
@@ -652,6 +658,79 @@ static void editDist3ConfigDelete(void *pIn){
|
||||
sqlite3_free(p);
|
||||
}
|
||||
|
||||
/* Compare the FROM values of two EditDist3Cost objects, for sorting.
|
||||
** Return negative, zero, or positive if the A is less than, equal to,
|
||||
** or greater than B.
|
||||
*/
|
||||
static int editDist3CostCompare(EditDist3Cost *pA, EditDist3Cost *pB){
|
||||
int n = pA->nFrom;
|
||||
int rc;
|
||||
if( n>pB->nFrom ) n = pB->nFrom;
|
||||
rc = strncmp(pA->a, pB->a, n);
|
||||
if( rc==0 ) rc = pA->nFrom - pB->nFrom;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Merge together two sorted lists of EditDist3Cost objects, in order
|
||||
** of increasing FROM.
|
||||
*/
|
||||
static EditDist3Cost *editDist3CostMerge(
|
||||
EditDist3Cost *pA,
|
||||
EditDist3Cost *pB
|
||||
){
|
||||
EditDist3Cost *pHead = 0;
|
||||
EditDist3Cost **ppTail = &pHead;
|
||||
EditDist3Cost *p;
|
||||
while( pA && pB ){
|
||||
if( editDist3CostCompare(pA,pB)<=0 ){
|
||||
p = pA;
|
||||
pA = pA->pNext;
|
||||
}else{
|
||||
p = pB;
|
||||
pB = pB->pNext;
|
||||
}
|
||||
*ppTail = p;
|
||||
ppTail = &p->pNext;
|
||||
}
|
||||
if( pA ){
|
||||
*ppTail = pA;
|
||||
}else{
|
||||
*ppTail = pB;
|
||||
}
|
||||
return pHead;
|
||||
}
|
||||
|
||||
/*
|
||||
** Sort a list of EditDist3Cost objects into order of increasing FROM
|
||||
*/
|
||||
static EditDist3Cost *editDist3CostSort(EditDist3Cost *pList){
|
||||
EditDist3Cost *ap[60], *p;
|
||||
int i;
|
||||
int mx = 0;
|
||||
ap[0] = 0;
|
||||
ap[1] = 0;
|
||||
while( pList ){
|
||||
p = pList;
|
||||
pList = p->pNext;
|
||||
p->pNext = 0;
|
||||
for(i=0; ap[i]; i++){
|
||||
p = editDist3CostMerge(ap[i],p);
|
||||
ap[i] = 0;
|
||||
}
|
||||
ap[i] = p;
|
||||
if( i>mx ){
|
||||
mx = i;
|
||||
ap[i+1] = 0;
|
||||
}
|
||||
}
|
||||
p = 0;
|
||||
for(i=0; i<=mx; i++){
|
||||
if( ap[i] ) p = editDist3CostMerge(p,ap[i]);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
** Load all edit-distance weights from a table.
|
||||
*/
|
||||
@@ -685,6 +764,7 @@ static int editDist3ConfigLoad(
|
||||
assert( zTo!=0 || nTo==0 );
|
||||
if( nFrom>100 || nTo>100 ) continue;
|
||||
if( iCost<0 ) continue;
|
||||
if( iCost>10000 ) continue; /* Costs above 10K are considered infinite */
|
||||
if( pLang==0 || iLang!=iLangPrev ){
|
||||
EditDist3Lang *pNew;
|
||||
pNew = sqlite3_realloc64(p->a, (p->nLang+1)*sizeof(p->a[0]));
|
||||
@@ -722,6 +802,12 @@ static int editDist3ConfigLoad(
|
||||
}
|
||||
rc2 = sqlite3_finalize(pStmt);
|
||||
if( rc==SQLITE_OK ) rc = rc2;
|
||||
if( rc==SQLITE_OK ){
|
||||
int iLang;
|
||||
for(iLang=0; iLang<p->nLang; iLang++){
|
||||
p->a[iLang].pCost = editDist3CostSort(p->a[iLang].pCost);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -749,6 +835,7 @@ static int utf8Len(unsigned char c, int N){
|
||||
** the given string.
|
||||
*/
|
||||
static int matchTo(EditDist3Cost *p, const char *z, int n){
|
||||
if( p->a[p->nFrom]!=z[0] ) return 0;
|
||||
if( p->nTo>n ) return 0;
|
||||
if( strncmp(p->a+p->nFrom, z, p->nTo)!=0 ) return 0;
|
||||
return 1;
|
||||
@@ -760,6 +847,7 @@ static int matchTo(EditDist3Cost *p, const char *z, int n){
|
||||
*/
|
||||
static int matchFrom(EditDist3Cost *p, const char *z, int n){
|
||||
assert( p->nFrom<=n );
|
||||
if( p->a[0]!=z[0] ) return 0;
|
||||
if( strncmp(p->a, z, p->nFrom)!=0 ) return 0;
|
||||
return 1;
|
||||
}
|
||||
@@ -776,7 +864,8 @@ static int matchFromTo(
|
||||
){
|
||||
int b1 = pStr->a[n1].nByte;
|
||||
if( b1>n2 ) return 0;
|
||||
if( memcmp(pStr->z+n1, z2, b1)!=0 ) return 0;
|
||||
if( pStr->z[n1]!=z2[0] ) return 0;
|
||||
if( strncmp(pStr->z+n1, z2, b1)!=0 ) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -858,9 +947,6 @@ static EditDist3FromString *editDist3FromStringNew(
|
||||
/*
|
||||
** Update entry m[i] such that it is the minimum of its current value
|
||||
** and m[j]+iCost.
|
||||
**
|
||||
** If the iCost is 1,000,000 or greater, then consider the cost to be
|
||||
** infinite and skip the update.
|
||||
*/
|
||||
static void updateCost(
|
||||
unsigned int *m,
|
||||
@@ -868,11 +954,11 @@ static void updateCost(
|
||||
int j,
|
||||
int iCost
|
||||
){
|
||||
unsigned int b;
|
||||
assert( iCost>=0 );
|
||||
if( iCost<10000 ){
|
||||
unsigned int b = m[j] + iCost;
|
||||
if( b<m[i] ) m[i] = b;
|
||||
}
|
||||
assert( iCost<10000 );
|
||||
b = m[j] + iCost;
|
||||
if( b<m[i] ) m[i] = b;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -936,8 +1022,9 @@ static int editDist3Core(
|
||||
a2[i2].nByte = utf8Len((unsigned char)z2[i2], n2-i2);
|
||||
for(p=pLang->pCost; p; p=p->pNext){
|
||||
EditDist3Cost **apNew;
|
||||
if( p->nFrom>0 ) continue;
|
||||
if( p->nFrom>0 ) break;
|
||||
if( i2+p->nTo>n2 ) continue;
|
||||
if( p->a[0]>z2[i2] ) break;
|
||||
if( matchTo(p, z2+i2, n2-i2)==0 ) continue;
|
||||
a2[i2].nIns++;
|
||||
apNew = sqlite3_realloc64(a2[i2].apIns, sizeof(*apNew)*a2[i2].nIns);
|
||||
@@ -2492,7 +2579,7 @@ static int spellfix1FilterForMatch(
|
||||
nPattern = (int)strlen(zPattern);
|
||||
if( zPattern[nPattern-1]=='*' ) nPattern--;
|
||||
zSql = sqlite3_mprintf(
|
||||
"SELECT id, word, rank, k1"
|
||||
"SELECT id, word, rank, coalesce(k1,word)"
|
||||
" FROM \"%w\".\"%w_vocab\""
|
||||
" WHERE langid=%d AND k2>=?1 AND k2<?2",
|
||||
p->zDbName, p->zTableName, iLang
|
||||
@@ -2826,17 +2913,17 @@ static int spellfix1Update(
|
||||
if( sqlite3_value_type(argv[1])==SQLITE_NULL ){
|
||||
spellfix1DbExec(&rc, db,
|
||||
"INSERT INTO \"%w\".\"%w_vocab\"(rank,langid,word,k1,k2) "
|
||||
"VALUES(%d,%d,%Q,%Q,%Q)",
|
||||
"VALUES(%d,%d,%Q,nullif(%Q,%Q),%Q)",
|
||||
p->zDbName, p->zTableName,
|
||||
iRank, iLang, zWord, zK1, zK2
|
||||
iRank, iLang, zWord, zK1, zWord, zK2
|
||||
);
|
||||
}else{
|
||||
newRowid = sqlite3_value_int64(argv[1]);
|
||||
spellfix1DbExec(&rc, db,
|
||||
"INSERT OR %s INTO \"%w\".\"%w_vocab\"(id,rank,langid,word,k1,k2) "
|
||||
"VALUES(%lld,%d,%d,%Q,%Q,%Q)",
|
||||
"VALUES(%lld,%d,%d,%Q,nullif(%Q,%Q),%Q)",
|
||||
zConflict, p->zDbName, p->zTableName,
|
||||
newRowid, iRank, iLang, zWord, zK1, zK2
|
||||
newRowid, iRank, iLang, zWord, zK1, zWord, zK2
|
||||
);
|
||||
}
|
||||
*pRowid = sqlite3_last_insert_rowid(db);
|
||||
@@ -2845,9 +2932,9 @@ static int spellfix1Update(
|
||||
newRowid = *pRowid = sqlite3_value_int64(argv[1]);
|
||||
spellfix1DbExec(&rc, db,
|
||||
"UPDATE OR %s \"%w\".\"%w_vocab\" SET id=%lld, rank=%d, langid=%d,"
|
||||
" word=%Q, k1=%Q, k2=%Q WHERE id=%lld",
|
||||
" word=%Q, k1=nullif(%Q,%Q), k2=%Q WHERE id=%lld",
|
||||
zConflict, p->zDbName, p->zTableName, newRowid, iRank, iLang,
|
||||
zWord, zK1, zK2, rowid
|
||||
zWord, zK1, zWord, zK2, rowid
|
||||
);
|
||||
}
|
||||
sqlite3_free(zK1);
|
||||
|
||||
+50
-19
@@ -268,6 +268,7 @@ typedef struct ZipfileTab ZipfileTab;
|
||||
struct ZipfileTab {
|
||||
sqlite3_vtab base; /* Base class - must be first */
|
||||
char *zFile; /* Zip file this table accesses (may be NULL) */
|
||||
sqlite3 *db; /* Host database connection */
|
||||
u8 *aBuffer; /* Temporary buffer used for various tasks */
|
||||
|
||||
ZipfileCsr *pCsrList; /* List of cursors */
|
||||
@@ -360,6 +361,7 @@ static int zipfileConnect(
|
||||
pNew = (ZipfileTab*)sqlite3_malloc(nByte+nFile);
|
||||
if( pNew==0 ) return SQLITE_NOMEM;
|
||||
memset(pNew, 0, nByte+nFile);
|
||||
pNew->db = db;
|
||||
pNew->aBuffer = (u8*)&pNew[1];
|
||||
if( zFile ){
|
||||
pNew->zFile = (char*)&pNew->aBuffer[ZIPFILE_BUFFER_SIZE];
|
||||
@@ -473,9 +475,17 @@ static int zipfileClose(sqlite3_vtab_cursor *cur){
|
||||
** Set the error message for the virtual table associated with cursor
|
||||
** pCsr to the results of vprintf(zFmt, ...).
|
||||
*/
|
||||
static void zipfileSetErrmsg(ZipfileCsr *pCsr, const char *zFmt, ...){
|
||||
static void zipfileTableErr(ZipfileTab *pTab, const char *zFmt, ...){
|
||||
va_list ap;
|
||||
va_start(ap, zFmt);
|
||||
sqlite3_free(pTab->base.zErrMsg);
|
||||
pTab->base.zErrMsg = sqlite3_vmprintf(zFmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
static void zipfileCursorErr(ZipfileCsr *pCsr, const char *zFmt, ...){
|
||||
va_list ap;
|
||||
va_start(ap, zFmt);
|
||||
sqlite3_free(pCsr->base.pVtab->zErrMsg);
|
||||
pCsr->base.pVtab->zErrMsg = sqlite3_vmprintf(zFmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
@@ -737,7 +747,7 @@ static void zipfileMtimeToDos(ZipfileCDS *pCds, u32 mUnixTime){
|
||||
int hr, min, sec;
|
||||
|
||||
A = (int)((JD - 1867216.25)/36524.25);
|
||||
A = JD + 1 + A - (A/4);
|
||||
A = (int)(JD + 1 + A - (A/4));
|
||||
B = A + 1524;
|
||||
C = (int)((B - 122.1)/365.25);
|
||||
D = (36525*(C&32767))/100;
|
||||
@@ -751,8 +761,12 @@ static void zipfileMtimeToDos(ZipfileCDS *pCds, u32 mUnixTime){
|
||||
min = (mUnixTime % (60*60)) / 60;
|
||||
sec = (mUnixTime % 60);
|
||||
|
||||
pCds->mDate = (u16)(day + (mon << 5) + ((yr-1980) << 9));
|
||||
pCds->mTime = (u16)(sec/2 + (min<<5) + (hr<<11));
|
||||
if( yr>=1980 ){
|
||||
pCds->mDate = (u16)(day + (mon << 5) + ((yr-1980) << 9));
|
||||
pCds->mTime = (u16)(sec/2 + (min<<5) + (hr<<11));
|
||||
}else{
|
||||
pCds->mDate = pCds->mTime = 0;
|
||||
}
|
||||
|
||||
assert( mUnixTime<315507600
|
||||
|| mUnixTime==zipfileMtime(pCds)
|
||||
@@ -1234,7 +1248,7 @@ static int zipfileFilter(
|
||||
if( pTab->zFile ){
|
||||
zFile = pTab->zFile;
|
||||
}else if( idxNum==0 ){
|
||||
zipfileSetErrmsg(pCsr, "zipfile() function requires an argument");
|
||||
zipfileCursorErr(pCsr, "zipfile() function requires an argument");
|
||||
return SQLITE_ERROR;
|
||||
}else if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){
|
||||
const u8 *aBlob = (const u8*)sqlite3_value_blob(argv[0]);
|
||||
@@ -1252,7 +1266,7 @@ static int zipfileFilter(
|
||||
if( 0==pTab->pWriteFd && 0==bInMemory ){
|
||||
pCsr->pFile = fopen(zFile, "rb");
|
||||
if( pCsr->pFile==0 ){
|
||||
zipfileSetErrmsg(pCsr, "cannot open file: %s", zFile);
|
||||
zipfileCursorErr(pCsr, "cannot open file: %s", zFile);
|
||||
rc = SQLITE_ERROR;
|
||||
}else{
|
||||
rc = zipfileReadEOCD(pTab, 0, 0, pCsr->pFile, &pCsr->eocd);
|
||||
@@ -1390,9 +1404,7 @@ static int zipfileGetMode(
|
||||
switch( z[0] ){
|
||||
case '-': mode |= S_IFREG; break;
|
||||
case 'd': mode |= S_IFDIR; break;
|
||||
#if !defined(_WIN32) && !defined(WIN32)
|
||||
case 'l': mode |= S_IFLNK; break;
|
||||
#endif
|
||||
default: goto parse_error;
|
||||
}
|
||||
for(i=1; i<10; i++){
|
||||
@@ -1400,9 +1412,10 @@ static int zipfileGetMode(
|
||||
else if( z[i]!='-' ) goto parse_error;
|
||||
}
|
||||
}
|
||||
if( (bIsDir == ((mode & S_IFDIR)==0)) ){
|
||||
if( ((mode & S_IFDIR)==0)==bIsDir ){
|
||||
/* The "mode" attribute is a directory, but data has been specified.
|
||||
** Or vice-versa - no data but "mode" is a file or symlink. */
|
||||
*pzErr = sqlite3_mprintf("zipfile: mode does not match data");
|
||||
return SQLITE_CONSTRAINT;
|
||||
}
|
||||
*pMode = mode;
|
||||
@@ -1533,9 +1546,12 @@ static int zipfileUpdate(
|
||||
|
||||
if( nVal>1 ){
|
||||
/* Check that "sz" and "rawdata" are both NULL: */
|
||||
if( sqlite3_value_type(apVal[5])!=SQLITE_NULL
|
||||
|| sqlite3_value_type(apVal[6])!=SQLITE_NULL
|
||||
){
|
||||
if( sqlite3_value_type(apVal[5])!=SQLITE_NULL ){
|
||||
zipfileTableErr(pTab, "sz must be NULL");
|
||||
rc = SQLITE_CONSTRAINT;
|
||||
}
|
||||
if( sqlite3_value_type(apVal[6])!=SQLITE_NULL ){
|
||||
zipfileTableErr(pTab, "rawdata must be NULL");
|
||||
rc = SQLITE_CONSTRAINT;
|
||||
}
|
||||
|
||||
@@ -1555,6 +1571,7 @@ static int zipfileUpdate(
|
||||
pData = aIn;
|
||||
nData = nIn;
|
||||
if( iMethod!=0 && iMethod!=8 ){
|
||||
zipfileTableErr(pTab, "unknown compression method: %d", iMethod);
|
||||
rc = SQLITE_CONSTRAINT;
|
||||
}else{
|
||||
if( bAuto || iMethod ){
|
||||
@@ -1601,7 +1618,20 @@ static int zipfileUpdate(
|
||||
ZipfileEntry *p;
|
||||
for(p=pTab->pFirstEntry; p; p=p->pNext){
|
||||
if( zipfileComparePath(p->cds.zFile, zPath, nPath)==0 ){
|
||||
rc = SQLITE_CONSTRAINT;
|
||||
switch( sqlite3_vtab_on_conflict(pTab->db) ){
|
||||
case SQLITE_IGNORE: {
|
||||
goto zipfile_update_done;
|
||||
}
|
||||
case SQLITE_REPLACE: {
|
||||
pOld = p;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
zipfileTableErr(pTab, "duplicate name: \"%s\"", zPath);
|
||||
rc = SQLITE_CONSTRAINT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1623,7 +1653,7 @@ static int zipfileUpdate(
|
||||
pNew->cds.szUncompressed = (u32)sz;
|
||||
pNew->cds.iExternalAttr = (mode<<16);
|
||||
pNew->cds.iOffset = (u32)pTab->szCurrent;
|
||||
pNew->cds.nFile = nPath;
|
||||
pNew->cds.nFile = (u16)nPath;
|
||||
pNew->mUnixTime = (u32)mTime;
|
||||
rc = zipfileAppendEntry(pTab, pNew, pData, nData);
|
||||
zipfileAddEntry(pTab, pOld, pNew);
|
||||
@@ -1645,6 +1675,7 @@ static int zipfileUpdate(
|
||||
zipfileEntryFree(pOld);
|
||||
}
|
||||
|
||||
zipfile_update_done:
|
||||
sqlite3_free(pFree);
|
||||
sqlite3_free(zFree);
|
||||
return rc;
|
||||
@@ -1926,7 +1957,7 @@ void zipfileStep(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){
|
||||
/* Inspect the 'method' parameter. This must be either 0 (store), 8 (use
|
||||
** deflate compression) or NULL (choose automatically). */
|
||||
if( pMethod && SQLITE_NULL!=sqlite3_value_type(pMethod) ){
|
||||
iMethod = sqlite3_value_int64(pMethod);
|
||||
iMethod = (int)sqlite3_value_int64(pMethod);
|
||||
if( iMethod!=0 && iMethod!=8 ){
|
||||
zErr = sqlite3_mprintf("illegal method value: %d", iMethod);
|
||||
rc = SQLITE_ERROR;
|
||||
@@ -1993,14 +2024,14 @@ void zipfileStep(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){
|
||||
e.cds.iVersionMadeBy = ZIPFILE_NEWENTRY_MADEBY;
|
||||
e.cds.iVersionExtract = ZIPFILE_NEWENTRY_REQUIRED;
|
||||
e.cds.flags = ZIPFILE_NEWENTRY_FLAGS;
|
||||
e.cds.iCompression = iMethod;
|
||||
e.cds.iCompression = (u16)iMethod;
|
||||
zipfileMtimeToDos(&e.cds, (u32)e.mUnixTime);
|
||||
e.cds.crc32 = iCrc32;
|
||||
e.cds.szCompressed = nData;
|
||||
e.cds.szUncompressed = szUncompressed;
|
||||
e.cds.iExternalAttr = (mode<<16);
|
||||
e.cds.iOffset = p->body.n;
|
||||
e.cds.nFile = nName;
|
||||
e.cds.nFile = (u16)nName;
|
||||
e.cds.zFile = zName;
|
||||
|
||||
/* Append the LFH to the body of the new archive */
|
||||
@@ -2047,8 +2078,8 @@ void zipfileFinal(sqlite3_context *pCtx){
|
||||
if( p==0 ) return;
|
||||
if( p->nEntry>0 ){
|
||||
memset(&eocd, 0, sizeof(eocd));
|
||||
eocd.nEntry = p->nEntry;
|
||||
eocd.nEntryTotal = p->nEntry;
|
||||
eocd.nEntry = (u16)p->nEntry;
|
||||
eocd.nEntryTotal = (u16)p->nEntry;
|
||||
eocd.nSize = p->cds.n;
|
||||
eocd.iOffset = p->body.n;
|
||||
|
||||
|
||||
@@ -220,7 +220,9 @@ if {[catch {sqlite3 db $file_to_analyze} res]} {
|
||||
if {$bFreelistCheck || $bAll} {
|
||||
puts -nonewline "freelist-check: "
|
||||
flush stdout
|
||||
db eval BEGIN
|
||||
puts [db one {SELECT checkfreelist('main')}]
|
||||
db eval END
|
||||
}
|
||||
if {$bSummary} {
|
||||
set scale 0
|
||||
|
||||
@@ -64,4 +64,81 @@ do_test 1.3 {
|
||||
list [catch { sqlite3changeset_apply db $x xConflict } msg] $msg
|
||||
} {1 SQLITE_CORRUPT}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 2.0 {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY,b,c,d);
|
||||
CREATE TABLE t2(e TEXT PRIMARY KEY NOT NULL,f,g);
|
||||
CREATE TABLE t3(w REAL PRIMARY KEY NOT NULL,x,y);
|
||||
CREATE TABLE t4(z PRIMARY KEY) WITHOUT ROWID;
|
||||
}
|
||||
|
||||
foreach {tn blob} {
|
||||
1 54010174340012000000
|
||||
2 54fefe8bcb0012000300
|
||||
3 5480809280808001017434001200fb
|
||||
4 50af9c939c9c9cb09c9c6400b09c9c6400
|
||||
5 12000300
|
||||
6 09847304
|
||||
7 5401017434001208
|
||||
8 54010174340012fc0386868600
|
||||
9 54010174340012FC0386868600
|
||||
10 548894FEFE
|
||||
11 54010171340012E703ABFA7433FD1200
|
||||
12 540101743400120003FFED00010000000000000002120002400C00000000000054040100000074310017000100000000000000050100000000000000030100000000000000040000010000000000000004010000000000000003001700010000000000000007030378797A01000000000000000F000001000000000000000F030378797A005403010000743200090003037838790100000000800000000200000000000000000900030378327902400C0000000000000304666F7572
|
||||
13 540101743400120003001200010000000000000002120002400C0000000000005404010000007431001700010000000000000005010000000000000003010000000000000004000001000000000000000401000000000000000300170001000000000000000703FC87797A01000000000000000F000001000000000000000F030378797A005403010000743200090003037838790100000000800000000200000000000000000900030378327902400C0000000000000304666F7572
|
||||
14 540101743400120003001200010000000000000002120002400C00000000000054040100000074310017000100000000000000050100000000000000030100000000000000040000010000000000000004010000000000000003001700010000000000000007030378797A01000000000000000F000001000000000000000F03FC87797A005403010000743200090003037838790100000000800000000200000000000000000900030378327902400C0000000000000304666F7572
|
||||
15 540101743400120003001200010000000000000002120002400C00000000000054040100000074310017000100000000000000050100000000000000030100000000000000040000010000000000000004010000000000000003001700010000000000000007030378797A01000000000000000F000001000000000000000F030378797A005403010000743200090003FC8738790100000000800000000200000000000000000900030378327902400C0000000000000304666F7572
|
||||
16 540101743400120003001200010000000000000002120002400C00000000000054040100000074310017000100000000000000050100000000000000030100000000000000040000010000000000000004010000000000000003001700010000000000000007030378797A01000000000000000F000001000000000000000F030378797A00540301000074320009000303783879010000000080000000020000000000000000090003FC87327902400C0000000000000304666F7572
|
||||
17 540101743400120003FFE3000412F7010000E600000000021202120002400C0000000000005B0401000000743100171C0304646F750002400C000000000000540401000000D3310017000100000000000000050100000000000378797A405403000002F10100000100000000000004090001000100000007030378797A0100000000000D0007000001000000002300000F1B0378797A405403013900743200090003038C3879010000000000000000000002120002400C0000000000005B0401000000743117170003047C5E00FF
|
||||
18 54010174340012000300120001000000E6FF100000120002401E00000000000054040100000074310017000100040000010000000000000004FFFF7FFF0000000000010000010000001000000007030378797A01000000000000000F000000000000FA0304666F7572
|
||||
19 540101743400120003001200010000000000000002121B02400C00000000000054040000000074310017000100000000000000050100000000000000030100000000000000040000010000000000000004010000000000000003001700010000000000000007030378817A01000000000000000F000001000000000100000F030378797A005403010000743200090003FFE809000303780000000000000304666F7572
|
||||
20 5401017D3400120003001200010000000000000002120002400CFC00000000005404010000007431001700010000000000000005010000000000000003010000000000000004000001000000000000000401000000000000000300170001000000000000000703FFFF797A01000000000000000F000001000000000000000F030378797A005403010000743200090003037838790100000000800000000200000000000000000900030378326C02400C0000000000000304666F7572
|
||||
21 5401017434001200030012000100FFE20000000002120002400C00000000000054040100E0007431001700010000E99D000000020000000003FFE70009000303783279020004000001030000000000002117000003001700012701000100000000743100000100000000008000090003037F387901000000008000000002000000000400000009005303010A00FF7FFFFF00000000000304664F6572
|
||||
22 540101743400120003FFFF7FFF0000000000000002120002400C00000000000054040100000074310017000100000000000000050100000000000000030100010000000000000000040000010000000000000004010000000000000003001700010000000000000007030378797A01000000000000000F000001000000000000000F030378797A005403010000743200090003037838790100000000800000000200000000000000000900030378327902400C0000000000000304666F7572
|
||||
23 540101742700120100120003F5FF0300
|
||||
24 5401017434E312540101743400120003FFFC00
|
||||
25 540101743400540101743D3D3D3D3D3D3D3D3D3D3D3D3D3400120003FFED000300
|
||||
26 5401017446EA5301743D1D3D3D01743D1D3D3DCF3D3D3D1A3D3D3D3D3400120003FFFF000000
|
||||
27 540101743400540101743D3D3D3D3D3D3D3D3D3D251000120003FF81000000000000
|
||||
28 540101340012000397FF3D7F3D3400120003001200540101743D3D3D3D3D3D393D3D3D12000300
|
||||
29 500174340050010F74340012000300120003FFE5
|
||||
30 5004007233E900177FEF0054257F0002EF001200031E12000300
|
||||
31 5001015001015252525250010174340012EF039A9A0100E351525D52525252525252525252525252525252525250010174340012EF039A0100009A9A9A9A9A9BA3B200120003010040743400
|
||||
32 5401017400123400120003FFFC00
|
||||
33 540101743400120003001200010000000000004002120002400C0000000000005404010000007431001700010000000000000005010000000000000003010000000000000004000001000000000000000401000000000000000300170001000000000000000703FC87797A01000000000000000F000001000000000000000F030378797A005403010000743200090003037838790100000000800000000200000000000000000900030378327902400C0000000000000304666F7572
|
||||
34 54040100000074310017000100000002000015050100000000000000030100000000140000040000010000000000000004010000000000000003001700010000000000000007030378797A01000000000000000F000001000000000000000F030378797A0054030100007432000900030378387901000000008E000000020000000000000000090003FFFF000002400C0000000000000304666F7572
|
||||
35 540101743400120003001200010000000000000002120002400C00000000000050060100000074310017000100000000000000050100000000000000030100000003001700010000666F7572
|
||||
36 540101743400120003001200010000000000000002120002400C00000000000050050100000074310017000100000000000000050100000000000000030100000003001700010000666F7572
|
||||
37 540101743400120003001200010000000000000002120002400C00000000000050040100008074310017000100000000000000050100000000000000030100000003001700010000666F7572
|
||||
38 540101743400120003001200010000000000000002120002400C00000000000050040100000074310017000000000000000000050100000000000000030100000003001700010000666F7572
|
||||
39 540101743400120003001200010000000000000002120002400C00000000000050040100018074310017000100000000000000050100000000000000030100000003001700010000666F7572
|
||||
40 540101743400120003001200010000000000000002120002400C0000000000005004FEFFFFFF74310017000100000000000000050100000000000000030100000003001700010000666F7572
|
||||
41 540101743400120003001200010000000000000002120002400C00000000000050040100000074310017000004000000000000050100000000000000030100000003001700010000666F7572
|
||||
42 540101743400120003001200010000000000000002120002400C0000000000005005FFFF050074310017000100000000000000050100000000000000030100000003001700010000666F7572
|
||||
43 540101743400120003001200010000000000000002120002400C000000000000500401006E0074310017000300000000001221050100000000000000030100000003001700010000666F7572
|
||||
44 540101743400120003001200010000000000020000120002400C00000000000050050100000074310017000100000000000000050100004000000000030100000025001700010000666F7572
|
||||
45 540101743400120003001200010000000000ECFF02120002400C000000000000500401F9FF00743100170001000000000000000500E1000000000000030100000003000000000000666F7572
|
||||
46 54010174340B0B0B0B0B0B0B0B0B0B0B0B0B0B0B00120003001200010000000000000002120002400C00000000000050040100000074310017010000000000000000050100FFE900000000030100000003007F00000000666F7572
|
||||
47 54010103001200010000000000020002120002400C0000000000005004010000F374310017000100000000000000050100000000000000030100000003001700010000666F8E72
|
||||
48 540101743400120003001200010000000000000002120002400C00000000000050030012000174310017000700000000000000050100002000000001000000000003001700010000666F7572
|
||||
49 540101743400120004001200010000000000000002120002400C0000000000005004010000FC733100170001000000000000000501000000000000000301000000F6FF17000100007C6F7572
|
||||
50 54010174FFDDFF8003001200010000100000000002120002400C000000000000500401000000743100170000000005010000000000000000000003010072
|
||||
51 540101743200120003001200010000000000000002120002400C00000000000050040100001074310017000000000003010000120300170100000000000000050100000000000000030100000003001700010000666F7572
|
||||
52 540101745401017434001200010000000000001702120002400C00000000000050040100001A74310017000100000000000100000100000000000000030100000003001700010000666F7572
|
||||
53 540101743400120003001200010000000000000002120002400C000000000000500401000000743100170001000002400C00000000000050040110000074310017000000000000050100000000000000030100000003001700010000666F7572
|
||||
54 540101743400120003001200010000000000000002120002400C000000000002120002400C00000000000050040100000074310017FF0050040100000074310017FF7F00000000000000050100000000000000030100000003001700010000666F7572
|
||||
55 540101743400120003001200010000000000000002120002400C00000000000050040100000074310017000100010080000001000000020003010100000300170100000003001700010000666F7572
|
||||
56 5487ffffff7f
|
||||
} {
|
||||
do_test 2.$tn {
|
||||
set changeset [binary decode hex $blob]
|
||||
#set fd [open x.change w+]
|
||||
#fconfigure $fd -encoding binary -translation binary
|
||||
#puts -nonewline $fd $changeset
|
||||
#close $fd
|
||||
list [catch { sqlite3changeset_apply db $changeset xConflict } msg] $msg
|
||||
} {1 SQLITE_CORRUPT}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -2720,13 +2720,16 @@ static int sessionReadRecord(
|
||||
if( abPK && abPK[i]==0 ) continue;
|
||||
rc = sessionInputBuffer(pIn, 9);
|
||||
if( rc==SQLITE_OK ){
|
||||
eType = pIn->aData[pIn->iNext++];
|
||||
}
|
||||
|
||||
assert( apOut[i]==0 );
|
||||
if( eType ){
|
||||
apOut[i] = sqlite3ValueNew(0);
|
||||
if( !apOut[i] ) rc = SQLITE_NOMEM;
|
||||
if( pIn->iNext>=pIn->nData ){
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
}else{
|
||||
eType = pIn->aData[pIn->iNext++];
|
||||
assert( apOut[i]==0 );
|
||||
if( eType ){
|
||||
apOut[i] = sqlite3ValueNew(0);
|
||||
if( !apOut[i] ) rc = SQLITE_NOMEM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
@@ -2736,10 +2739,14 @@ static int sessionReadRecord(
|
||||
pIn->iNext += sessionVarintGet(aVal, &nByte);
|
||||
rc = sessionInputBuffer(pIn, nByte);
|
||||
if( rc==SQLITE_OK ){
|
||||
u8 enc = (eType==SQLITE_TEXT ? SQLITE_UTF8 : 0);
|
||||
rc = sessionValueSetStr(apOut[i],&pIn->aData[pIn->iNext],nByte,enc);
|
||||
if( nByte<0 || nByte>pIn->nData-pIn->iNext ){
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
}else{
|
||||
u8 enc = (eType==SQLITE_TEXT ? SQLITE_UTF8 : 0);
|
||||
rc = sessionValueSetStr(apOut[i],&pIn->aData[pIn->iNext],nByte,enc);
|
||||
pIn->iNext += nByte;
|
||||
}
|
||||
}
|
||||
pIn->iNext += nByte;
|
||||
}
|
||||
if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
|
||||
sqlite3_int64 v = sessionGetI64(aVal);
|
||||
@@ -2779,8 +2786,19 @@ static int sessionChangesetBufferTblhdr(SessionInput *pIn, int *pnByte){
|
||||
rc = sessionInputBuffer(pIn, 9);
|
||||
if( rc==SQLITE_OK ){
|
||||
nRead += sessionVarintGet(&pIn->aData[pIn->iNext + nRead], &nCol);
|
||||
rc = sessionInputBuffer(pIn, nRead+nCol+100);
|
||||
nRead += nCol;
|
||||
/* The hard upper limit for the number of columns in an SQLite
|
||||
** database table is, according to sqliteLimit.h, 32676. So
|
||||
** consider any table-header that purports to have more than 65536
|
||||
** columns to be corrupt. This is convenient because otherwise,
|
||||
** if the (nCol>65536) condition below were omitted, a sufficiently
|
||||
** large value for nCol may cause nRead to wrap around and become
|
||||
** negative. Leading to a crash. */
|
||||
if( nCol<0 || nCol>65536 ){
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
}else{
|
||||
rc = sessionInputBuffer(pIn, nRead+nCol+100);
|
||||
nRead += nCol;
|
||||
}
|
||||
}
|
||||
|
||||
while( rc==SQLITE_OK ){
|
||||
@@ -2857,11 +2875,15 @@ static int sessionChangesetReadTblhdr(sqlite3_changeset_iter *p){
|
||||
int nByte;
|
||||
int nVarint;
|
||||
nVarint = sessionVarintGet(&p->in.aData[p->in.iNext], &p->nCol);
|
||||
nCopy -= nVarint;
|
||||
p->in.iNext += nVarint;
|
||||
nByte = p->nCol * sizeof(sqlite3_value*) * 2 + nCopy;
|
||||
p->tblhdr.nBuf = 0;
|
||||
sessionBufferGrow(&p->tblhdr, nByte, &rc);
|
||||
if( p->nCol>0 ){
|
||||
nCopy -= nVarint;
|
||||
p->in.iNext += nVarint;
|
||||
nByte = p->nCol * sizeof(sqlite3_value*) * 2 + nCopy;
|
||||
p->tblhdr.nBuf = 0;
|
||||
sessionBufferGrow(&p->tblhdr, nByte, &rc);
|
||||
}else{
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
}
|
||||
}
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
@@ -2939,6 +2961,13 @@ static int sessionChangesetNext(
|
||||
op = p->in.aData[p->in.iNext++];
|
||||
}
|
||||
|
||||
if( p->zTab==0 ){
|
||||
/* The first record in the changeset is not a table header. Must be a
|
||||
** corrupt changeset. */
|
||||
assert( p->in.iNext==1 );
|
||||
return (p->rc = SQLITE_CORRUPT_BKPT);
|
||||
}
|
||||
|
||||
p->op = op;
|
||||
p->bIndirect = p->in.aData[p->in.iNext++];
|
||||
if( p->op!=SQLITE_UPDATE && p->op!=SQLITE_DELETE && p->op!=SQLITE_INSERT ){
|
||||
@@ -2981,9 +3010,9 @@ static int sessionChangesetNext(
|
||||
** new.* to old.*, to accommodate the code that reads these arrays. */
|
||||
for(i=0; i<p->nCol; i++){
|
||||
assert( p->apValue[i]==0 );
|
||||
assert( p->abPK[i]==0 || p->apValue[i+p->nCol] );
|
||||
if( p->abPK[i] ){
|
||||
p->apValue[i] = p->apValue[i+p->nCol];
|
||||
if( p->apValue[i]==0 ) return (p->rc = SQLITE_CORRUPT_BKPT);
|
||||
p->apValue[i+p->nCol] = 0;
|
||||
}
|
||||
}
|
||||
@@ -3708,7 +3737,13 @@ static int sessionBindRow(
|
||||
if( !abPK || abPK[i] ){
|
||||
sqlite3_value *pVal;
|
||||
(void)xValue(pIter, i, &pVal);
|
||||
rc = sessionBindValue(pStmt, i+1, pVal);
|
||||
if( pVal==0 ){
|
||||
/* The value in the changeset was "undefined". This indicates a
|
||||
** corrupt changeset blob. */
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
}else{
|
||||
rc = sessionBindValue(pStmt, i+1, pVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
|
||||
@@ -13,16 +13,23 @@ extern "C" {
|
||||
|
||||
/*
|
||||
** CAPI3REF: Session Object Handle
|
||||
**
|
||||
** An instance of this object is a [session] that can be used to
|
||||
** record changes to a database.
|
||||
*/
|
||||
typedef struct sqlite3_session sqlite3_session;
|
||||
|
||||
/*
|
||||
** CAPI3REF: Changeset Iterator Handle
|
||||
**
|
||||
** An instance of this object acts as a cursor for iterating
|
||||
** over the elements of a [changeset] or [patchset].
|
||||
*/
|
||||
typedef struct sqlite3_changeset_iter sqlite3_changeset_iter;
|
||||
|
||||
/*
|
||||
** CAPI3REF: Create A New Session Object
|
||||
** CONSTRUCTOR: sqlite3_session
|
||||
**
|
||||
** Create a new session object attached to database handle db. If successful,
|
||||
** a pointer to the new object is written to *ppSession and SQLITE_OK is
|
||||
@@ -59,6 +66,7 @@ int sqlite3session_create(
|
||||
|
||||
/*
|
||||
** CAPI3REF: Delete A Session Object
|
||||
** DESTRUCTOR: sqlite3_session
|
||||
**
|
||||
** Delete a session object previously allocated using
|
||||
** [sqlite3session_create()]. Once a session object has been deleted, the
|
||||
@@ -74,6 +82,7 @@ void sqlite3session_delete(sqlite3_session *pSession);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Enable Or Disable A Session Object
|
||||
** METHOD: sqlite3_session
|
||||
**
|
||||
** Enable or disable the recording of changes by a session object. When
|
||||
** enabled, a session object records changes made to the database. When
|
||||
@@ -93,6 +102,7 @@ int sqlite3session_enable(sqlite3_session *pSession, int bEnable);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Set Or Clear the Indirect Change Flag
|
||||
** METHOD: sqlite3_session
|
||||
**
|
||||
** Each change recorded by a session object is marked as either direct or
|
||||
** indirect. A change is marked as indirect if either:
|
||||
@@ -122,6 +132,7 @@ int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Attach A Table To A Session Object
|
||||
** METHOD: sqlite3_session
|
||||
**
|
||||
** If argument zTab is not NULL, then it is the name of a table to attach
|
||||
** to the session object passed as the first argument. All subsequent changes
|
||||
@@ -184,6 +195,7 @@ int sqlite3session_attach(
|
||||
|
||||
/*
|
||||
** CAPI3REF: Set a table filter on a Session Object.
|
||||
** METHOD: sqlite3_session
|
||||
**
|
||||
** The second argument (xFilter) is the "filter callback". For changes to rows
|
||||
** in tables that are not attached to the Session object, the filter is called
|
||||
@@ -202,6 +214,7 @@ void sqlite3session_table_filter(
|
||||
|
||||
/*
|
||||
** CAPI3REF: Generate A Changeset From A Session Object
|
||||
** METHOD: sqlite3_session
|
||||
**
|
||||
** Obtain a changeset containing changes to the tables attached to the
|
||||
** session object passed as the first argument. If successful,
|
||||
@@ -311,7 +324,8 @@ int sqlite3session_changeset(
|
||||
);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Load The Difference Between Tables Into A Session
|
||||
** CAPI3REF: Load The Difference Between Tables Into A Session
|
||||
** METHOD: sqlite3_session
|
||||
**
|
||||
** If it is not already attached to the session object passed as the first
|
||||
** argument, this function attaches table zTbl in the same manner as the
|
||||
@@ -376,6 +390,7 @@ int sqlite3session_diff(
|
||||
|
||||
/*
|
||||
** CAPI3REF: Generate A Patchset From A Session Object
|
||||
** METHOD: sqlite3_session
|
||||
**
|
||||
** The differences between a patchset and a changeset are that:
|
||||
**
|
||||
@@ -427,6 +442,7 @@ int sqlite3session_isempty(sqlite3_session *pSession);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Create An Iterator To Traverse A Changeset
|
||||
** CONSTRUCTOR: sqlite3_changeset_iter
|
||||
**
|
||||
** Create an iterator used to iterate through the contents of a changeset.
|
||||
** If successful, *pp is set to point to the iterator handle and SQLITE_OK
|
||||
@@ -467,6 +483,7 @@ int sqlite3changeset_start(
|
||||
|
||||
/*
|
||||
** CAPI3REF: Advance A Changeset Iterator
|
||||
** METHOD: sqlite3_changeset_iter
|
||||
**
|
||||
** This function may only be used with iterators created by function
|
||||
** [sqlite3changeset_start()]. If it is called on an iterator passed to
|
||||
@@ -491,6 +508,7 @@ int sqlite3changeset_next(sqlite3_changeset_iter *pIter);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Obtain The Current Operation From A Changeset Iterator
|
||||
** METHOD: sqlite3_changeset_iter
|
||||
**
|
||||
** The pIter argument passed to this function may either be an iterator
|
||||
** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
|
||||
@@ -525,6 +543,7 @@ int sqlite3changeset_op(
|
||||
|
||||
/*
|
||||
** CAPI3REF: Obtain The Primary Key Definition Of A Table
|
||||
** METHOD: sqlite3_changeset_iter
|
||||
**
|
||||
** For each modified table, a changeset includes the following:
|
||||
**
|
||||
@@ -556,6 +575,7 @@ int sqlite3changeset_pk(
|
||||
|
||||
/*
|
||||
** CAPI3REF: Obtain old.* Values From A Changeset Iterator
|
||||
** METHOD: sqlite3_changeset_iter
|
||||
**
|
||||
** The pIter argument passed to this function may either be an iterator
|
||||
** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
|
||||
@@ -586,6 +606,7 @@ int sqlite3changeset_old(
|
||||
|
||||
/*
|
||||
** CAPI3REF: Obtain new.* Values From A Changeset Iterator
|
||||
** METHOD: sqlite3_changeset_iter
|
||||
**
|
||||
** The pIter argument passed to this function may either be an iterator
|
||||
** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
|
||||
@@ -619,6 +640,7 @@ int sqlite3changeset_new(
|
||||
|
||||
/*
|
||||
** CAPI3REF: Obtain Conflicting Row Values From A Changeset Iterator
|
||||
** METHOD: sqlite3_changeset_iter
|
||||
**
|
||||
** This function should only be used with iterator objects passed to a
|
||||
** conflict-handler callback by [sqlite3changeset_apply()] with either
|
||||
@@ -646,6 +668,7 @@ int sqlite3changeset_conflict(
|
||||
|
||||
/*
|
||||
** CAPI3REF: Determine The Number Of Foreign Key Constraint Violations
|
||||
** METHOD: sqlite3_changeset_iter
|
||||
**
|
||||
** This function may only be called with an iterator passed to an
|
||||
** SQLITE_CHANGESET_FOREIGN_KEY conflict handler callback. In this case
|
||||
@@ -662,6 +685,7 @@ int sqlite3changeset_fk_conflicts(
|
||||
|
||||
/*
|
||||
** CAPI3REF: Finalize A Changeset Iterator
|
||||
** METHOD: sqlite3_changeset_iter
|
||||
**
|
||||
** This function is used to finalize an iterator allocated with
|
||||
** [sqlite3changeset_start()].
|
||||
@@ -678,6 +702,7 @@ int sqlite3changeset_fk_conflicts(
|
||||
** to that error is returned by this function. Otherwise, SQLITE_OK is
|
||||
** returned. This is to allow the following pattern (pseudo-code):
|
||||
**
|
||||
** <pre>
|
||||
** sqlite3changeset_start();
|
||||
** while( SQLITE_ROW==sqlite3changeset_next() ){
|
||||
** // Do something with change.
|
||||
@@ -686,6 +711,7 @@ int sqlite3changeset_fk_conflicts(
|
||||
** if( rc!=SQLITE_OK ){
|
||||
** // An error has occurred
|
||||
** }
|
||||
** </pre>
|
||||
*/
|
||||
int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter);
|
||||
|
||||
@@ -733,6 +759,7 @@ int sqlite3changeset_invert(
|
||||
** sqlite3_changegroup object. Calling it produces similar results as the
|
||||
** following code fragment:
|
||||
**
|
||||
** <pre>
|
||||
** sqlite3_changegroup *pGrp;
|
||||
** rc = sqlite3_changegroup_new(&pGrp);
|
||||
** if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nA, pA);
|
||||
@@ -743,6 +770,7 @@ int sqlite3changeset_invert(
|
||||
** *ppOut = 0;
|
||||
** *pnOut = 0;
|
||||
** }
|
||||
** </pre>
|
||||
**
|
||||
** Refer to the sqlite3_changegroup documentation below for details.
|
||||
*/
|
||||
@@ -758,11 +786,15 @@ int sqlite3changeset_concat(
|
||||
|
||||
/*
|
||||
** CAPI3REF: Changegroup Handle
|
||||
**
|
||||
** A changegroup is an object used to combine two or more
|
||||
** [changesets] or [patchsets]
|
||||
*/
|
||||
typedef struct sqlite3_changegroup sqlite3_changegroup;
|
||||
|
||||
/*
|
||||
** CAPI3REF: Create A New Changegroup Object
|
||||
** CONSTRUCTOR: sqlite3_changegroup
|
||||
**
|
||||
** An sqlite3_changegroup object is used to combine two or more changesets
|
||||
** (or patchsets) into a single changeset (or patchset). A single changegroup
|
||||
@@ -800,6 +832,7 @@ int sqlite3changegroup_new(sqlite3_changegroup **pp);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Add A Changeset To A Changegroup
|
||||
** METHOD: sqlite3_changegroup
|
||||
**
|
||||
** Add all changes within the changeset (or patchset) in buffer pData (size
|
||||
** nData bytes) to the changegroup.
|
||||
@@ -877,6 +910,7 @@ int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Obtain A Composite Changeset From A Changegroup
|
||||
** METHOD: sqlite3_changegroup
|
||||
**
|
||||
** Obtain a buffer containing a changeset (or patchset) representing the
|
||||
** current contents of the changegroup. If the inputs to the changegroup
|
||||
@@ -907,6 +941,7 @@ int sqlite3changegroup_output(
|
||||
|
||||
/*
|
||||
** CAPI3REF: Delete A Changegroup Object
|
||||
** DESTRUCTOR: sqlite3_changegroup
|
||||
*/
|
||||
void sqlite3changegroup_delete(sqlite3_changegroup*);
|
||||
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
|
||||
# The Zonefile Extension
|
||||
|
||||
## Functionality
|
||||
|
||||
### Creating Zonefile Files
|
||||
|
||||
To create a new zonefile, first create a database table with the following
|
||||
schema:
|
||||
|
||||
> CREATE TABLE data(
|
||||
> k INTEGER PRIMARY KEY,
|
||||
> frame INTEGER DEFAULT -1, -- frame number. Automatic if -1
|
||||
> idx INTEGER DEFAULT -1, -- index of entry within frame. Auto if -1
|
||||
> v BLOB
|
||||
> );
|
||||
|
||||
The table may be created in a persistent or temporary database and may
|
||||
take any name, but must contain the columns above. The table must be
|
||||
populated with a row for each key intended to appear in the new zonefile
|
||||
file.
|
||||
|
||||
Once the table is populated, a zonefile is created using the following
|
||||
SQL:
|
||||
|
||||
> SELECT zonefile_write(<file>, <table> [, <parameters>]);
|
||||
|
||||
where <file> is the name of the file to create on disk, <table>
|
||||
is the name of the database table to read and optional argument
|
||||
<parameters> is a JSON object containing various attributes that
|
||||
influence creation of the zonefile file.
|
||||
|
||||
Currently the only <parameters> attribute supported is
|
||||
<i>maxAutoFrameSize</i> (default value 65536), which sets the maximum
|
||||
uncompressed frame size in bytes for automatically generated zonefile
|
||||
frames.
|
||||
|
||||
For example, to create a zonefile named "test.zonefile" based on the
|
||||
contents of database table "test_input" and with a maximum automatic
|
||||
frame size of 4096 bytes:
|
||||
|
||||
> SELECT zonefile_write('test.zonefile', 'test_input',
|
||||
> '{"maxAutoFrameSize":4096}'
|
||||
> );
|
||||
|
||||
### Using (Reading) Zonefile Files
|
||||
|
||||
To create a new zonefile table:
|
||||
|
||||
> CREATE VIRTUAL TABLE z1 USING zonefile;
|
||||
|
||||
This creates two virtual tables in the database schema. One read-only table
|
||||
named "z1", with a schema equivalent to:
|
||||
|
||||
> CREATE TABLE z1( -- this whole table is read-only
|
||||
> k INTEGER PRIMARY KEY,
|
||||
> v BLOB,
|
||||
> fileid INTEGER,
|
||||
> frame INTEGER,
|
||||
> ofst INTEGER,
|
||||
> sz INTEGER
|
||||
> );
|
||||
|
||||
And a read-write table named "z1_files" with a schema like:
|
||||
|
||||
> CREATE TABLE z1_files(
|
||||
> filename TEXT PRIMARY KEY,
|
||||
> ekey BLOB, -- encryption key
|
||||
> fileid INTEGER, -- read-only
|
||||
> header JSON HIDDEN -- read-only
|
||||
> );
|
||||
|
||||
Both tables are initially empty. To add a zonefile to the index, insert a
|
||||
row into the "z1_files" table:
|
||||
|
||||
> INSERT INTO z1_files(filename) VALUES(<filename>);
|
||||
|
||||
Currently, any value provided for any column other than "filename" is
|
||||
ignored. Files are removed from the index by deleting rows from the
|
||||
z1_files table:
|
||||
|
||||
> DELETE FROM z1_files WHERE filename = <filename>;
|
||||
|
||||
Once zonefile files have been added to the index, their contents are
|
||||
visible in table "z1". To retrieve the value associated with a single
|
||||
key from one of the zonefile files in the index:
|
||||
|
||||
> SELECT v FROM z1 WHERE k = <key>;
|
||||
|
||||
|
||||
## Notes
|
||||
|
||||
* Contrary to the spec, the implementation uses 32-bit (not 16-bit) frame
|
||||
numbers. So the KeyOffsetPair structure becomes:
|
||||
|
||||
KeyOffsetPair
|
||||
{
|
||||
uint64 key;
|
||||
uint32 frameNo;
|
||||
uint32 frameByteOffset;
|
||||
};
|
||||
|
||||
Also, the ZonefileHeader.numFrames field is now 32-bit. Which makes
|
||||
the ZonefileHeader structure 26 bytes in size. The implementation
|
||||
pads this out to 32 bytes so that the ZoneFileIndex is 8-byte aligned.
|
||||
|
||||
* Multi-byte integer values are big-endian.
|
||||
|
||||
* The offsets in the ZoneFileIndex.byteOffsetZoneFrame[] array are
|
||||
relative to the offset in ZoneFileHeader.byteOffsetFrames. This is
|
||||
necessary as we may not know the offset of the start of the frame data
|
||||
until after the ZoneFileIndex structure is compressed.
|
||||
|
||||
* Currently there is no support at all for encryption or compression.
|
||||
|
||||
* Zonefile currently uses json1 to parse the json argument to
|
||||
zonefile\_write(). And so must be used with an SQLITE\_ENABLE\_JSON1
|
||||
or otherwise json1-enabled SQLite.
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,152 +0,0 @@
|
||||
# 2018 Feb 11
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# The focus of this file is testing the zonefile extension.
|
||||
#
|
||||
|
||||
if {![info exists testdir]} {
|
||||
set testdir [file join [file dirname [info script]] .. .. test]
|
||||
}
|
||||
source [file join $testdir tester.tcl]
|
||||
set testprefix zonefile1
|
||||
load_static_extension db zonefile
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE zz(k INTEGER PRIMARY KEY, frame INTEGER, idx INTEGER, v BLOB);
|
||||
INSERT INTO zz VALUES(1, -1, -1, randomblob(100));
|
||||
INSERT INTO zz VALUES(2, -1, -1, randomblob(100));
|
||||
INSERT INTO zz VALUES(3, -1, -1, randomblob(100));
|
||||
}
|
||||
|
||||
do_execsql_test 1.1 {
|
||||
SELECT zonefile_write('test.zonefile', 'zz');
|
||||
} {{}}
|
||||
|
||||
do_execsql_test 1.2 {
|
||||
CREATE VIRTUAL TABLE z1 USING zonefile;
|
||||
SELECT name FROM sqlite_master WHERE name LIKE 'z1%' ORDER BY 1;
|
||||
} {z1 z1_files z1_shadow_file z1_shadow_idx}
|
||||
|
||||
do_execsql_test 1.3 {
|
||||
INSERT INTO z1_files(filename) VALUES('test.zonefile');
|
||||
SELECT filename,
|
||||
json_extract(header, '$.magicNumber'),
|
||||
json_extract(header, '$.numFrames'),
|
||||
json_extract(header, '$.numKeys')
|
||||
FROM z1_files;
|
||||
} {test.zonefile 1179332920 1 3}
|
||||
|
||||
do_execsql_test 1.4 { SELECT count(*) FROM z1_shadow_idx } 3
|
||||
|
||||
do_execsql_test 1.5.1 { SELECT k FROM z1 } {1 2 3}
|
||||
do_execsql_test 1.5.2 { SELECT fileid FROM z1 } {1 1 1}
|
||||
do_execsql_test 1.5.3 { SELECT frame FROM z1 } {0 0 0}
|
||||
do_execsql_test 1.5.4 { SELECT sz FROM z1 } {100 100 100}
|
||||
|
||||
do_execsql_test 1.5.5 {
|
||||
SELECT zz.v==z1.v FROM zz, z1 WHERE zz.k=z1.k
|
||||
} {1 1 1}
|
||||
|
||||
do_execsql_test 1.5 {
|
||||
DELETE FROM z1_files;
|
||||
SELECT * FROM z1_files;
|
||||
} {}
|
||||
|
||||
do_execsql_test 1.6 { SELECT count(*) FROM z1_shadow_idx } 0
|
||||
|
||||
do_execsql_test 1.7 { DROP TABLE z1 }
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
reset_db
|
||||
load_static_extension db zonefile
|
||||
|
||||
do_execsql_test 2.0 {
|
||||
CREATE TABLE zz(
|
||||
k INTEGER PRIMARY KEY,
|
||||
frame INTEGER DEFAULT -1,
|
||||
idx INTEGER DEFAULT -1,
|
||||
v BLOB
|
||||
);
|
||||
CREATE TABLE rt(k INTEGER PRIMARY KEY, v BLOB);
|
||||
CREATE VIRTUAL TABLE zone USING zonefile;
|
||||
}
|
||||
|
||||
set nMinByte 0
|
||||
set nMaxByte 444
|
||||
foreach {zonefile lKey} {
|
||||
test1.zonefile {195 1238 298 405 297}
|
||||
test2.zonefile {124 1624 82 1929}
|
||||
test3.zonefile {932 683 1751 410 41}
|
||||
test4.zonefile {427 1491}
|
||||
test5.zonefile {1004 473 801 394 1672 816 1577}
|
||||
test6.zonefile {1374 1454 1005}
|
||||
test7.zonefile {450 241 319 133}
|
||||
test8.zonefile {1414 900 1406 1917 127 673}
|
||||
test9.zonefile {1192 226 988 1292 718 1345 1675}
|
||||
test10.zonefile {314}
|
||||
test11.zonefile {1177 1597 60 532 291 1164 812}
|
||||
test12.zonefile {1168 1290 1585 939 1916}
|
||||
test13.zonefile {644 1784 1476 1283 433 506}
|
||||
test14.zonefile {1141 1547 1506 364}
|
||||
test15.zonefile {1756 1885 844 1880 1896 354}
|
||||
test16.zonefile {1383 1928 1371}
|
||||
test17.zonefile {93}
|
||||
test18.zonefile {1067}
|
||||
test19.zonefile {642}
|
||||
test20.zonefile {1380 1857}
|
||||
test21.zonefile {288 293 1968 1207 1739 231 300}
|
||||
test22.zonefile {651 1007 607 830 299 1431}
|
||||
test23.zonefile {81 1651 543 1949 256 119 1088}
|
||||
test24.zonefile {1278 2024 682 1115 194 636 1804}
|
||||
test25.zonefile {514 1155 171 2015 791}
|
||||
test26.zonefile {1615 1228 147 1464}
|
||||
test27.zonefile {55 1130 781 678 78}
|
||||
test28.zonefile {1981 1401 1178}
|
||||
test29.zonefile {1754 864 183 1953 1901}
|
||||
test30.zonefile {1461 817}
|
||||
test31.zonefile {1720 1722 686 1833}
|
||||
} {
|
||||
forcedelete $zonefile
|
||||
execsql { DELETE FROM zz; }
|
||||
foreach k $lKey {
|
||||
execsql { INSERT INTO zz(k, v) VALUES($k, randomblob($k)) }
|
||||
}
|
||||
execsql { INSERT INTO rt SELECT k, v FROM zz }
|
||||
breakpoint
|
||||
execsql {
|
||||
SELECT zonefile_write($zonefile, 'zz', '{"maxAutoFrameSize":2000}');
|
||||
INSERT INTO zone_files(filename) VALUES($zonefile);
|
||||
}
|
||||
}
|
||||
|
||||
do_execsql_test 2.1 {
|
||||
SELECT k FROM zone JOIN rt USING (k) WHERE zone.v!=rt.v
|
||||
}
|
||||
do_execsql_test 2.2 {
|
||||
SELECT count(*) FROM zone JOIN rt USING (k);
|
||||
} {135}
|
||||
do_execsql_test 2.3 {
|
||||
SELECT filename,
|
||||
json_extract(header, '$.numKeys'),
|
||||
json_extract(header, '$.numFrames')
|
||||
FROM zone_files
|
||||
WHERE filename IN ('test19.zonefile', 'test20.zonefile', 'test21.zonefile')
|
||||
ORDER BY 1
|
||||
} {
|
||||
test19.zonefile 1 1
|
||||
test20.zonefile 2 2
|
||||
test21.zonefile 7 4
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -65,7 +65,7 @@ LIBOBJ+= vdbe.o parse.o \
|
||||
fts3_write.o fts5.o func.o global.o hash.o \
|
||||
icu.o insert.o json1.o legacy.o loadext.o \
|
||||
main.o malloc.o mem0.o mem1.o mem2.o mem3.o mem5.o \
|
||||
memjournal.o \
|
||||
memdb.o memjournal.o \
|
||||
mutex.o mutex_noop.o mutex_unix.o mutex_w32.o \
|
||||
notify.o opcodes.o os.o os_unix.o os_win.o \
|
||||
pager.o pcache.o pcache1.o pragma.o prepare.o printf.o \
|
||||
@@ -118,6 +118,7 @@ SRC = \
|
||||
$(TOP)/src/mem2.c \
|
||||
$(TOP)/src/mem3.c \
|
||||
$(TOP)/src/mem5.c \
|
||||
$(TOP)/src/memdb.c \
|
||||
$(TOP)/src/memjournal.c \
|
||||
$(TOP)/src/msvc.h \
|
||||
$(TOP)/src/mutex.c \
|
||||
@@ -372,7 +373,6 @@ TESTSRC += \
|
||||
$(TOP)/ext/misc/wholenumber.c \
|
||||
$(TOP)/ext/misc/vfslog.c \
|
||||
$(TOP)/ext/misc/zipfile.c \
|
||||
$(TOP)/ext/zonefile/zonefile.c \
|
||||
$(TOP)/ext/fts5/fts5_tcl.c \
|
||||
$(TOP)/ext/fts5/fts5_test_mi.c \
|
||||
$(TOP)/ext/fts5/fts5_test_tok.c
|
||||
@@ -520,6 +520,7 @@ SHELL_OPT += -DSQLITE_INTROSPECTION_PRAGMAS
|
||||
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
|
||||
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
|
||||
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
|
||||
FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000
|
||||
DBFUZZ_OPT =
|
||||
KV_OPT = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ
|
||||
ST_OPT = -DSQLITE_THREADSAFE=0
|
||||
@@ -574,6 +575,9 @@ ossshell$(EXE): $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3.h
|
||||
-DSQLITE_ENABLE_MEMSYS5 $(FUZZCHECK_OPT) \
|
||||
$(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c $(TLIBS) $(THREADLIB)
|
||||
|
||||
sessionfuzz$(EXE): $(TOP)/test/sessionfuzz.c sqlite3.c sqlite3.h
|
||||
$(TCC) -o sessionfuzz$(EXE) $(TOP)/test/sessionfuzz.c -lz $(TLIBS) $(THREADLIB)
|
||||
|
||||
mptester$(EXE): sqlite3.c $(TOP)/mptest/mptest.c
|
||||
$(TCCX) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \
|
||||
$(TLIBS) $(THREADLIB)
|
||||
@@ -894,14 +898,17 @@ fulltestonly: $(TESTPROGS) fuzztest
|
||||
queryplantest: testfixture$(EXE) sqlite3$(EXE)
|
||||
./testfixture$(EXE) $(TOP)/test/permutations.test queryplanner $(TESTOPTS)
|
||||
|
||||
fuzztest: fuzzcheck$(EXE) $(FUZZDATA)
|
||||
fuzztest: fuzzcheck$(EXE) $(FUZZDATA) sessionfuzz$(EXE) $(TOP)/test/sessionfuzz-data1.db
|
||||
./fuzzcheck$(EXE) $(FUZZDATA)
|
||||
./sessionfuzz run $(TOP)/test/sessionfuzz-data1.db
|
||||
|
||||
fastfuzztest: fuzzcheck$(EXE) $(FUZZDATA)
|
||||
fastfuzztest: fuzzcheck$(EXE) $(FUZZDATA) sessionfuzz$(EXE) $(TOP)/test/sessionfuzz-data1.db
|
||||
./fuzzcheck$(EXE) --limit-mem 100M $(FUZZDATA)
|
||||
./sessionfuzz run $(TOP)/test/sessionfuzz-data1.db
|
||||
|
||||
valgrindfuzz: fuzzcheck$(EXE) $(FUZZDATA)
|
||||
valgrindfuzz: fuzzcheck$(EXE) $(FUZZDATA) sessionfuzz$(EXE) $(TOP)/test/sessionfuzz-data1.db
|
||||
valgrind ./fuzzcheck$(EXE) --cell-size-check --limit-mem 10M --timeout 600 $(FUZZDATA)
|
||||
valgrind ./sessionfuzz run $(TOP)/test/sessionfuzz-data1.db
|
||||
|
||||
# The veryquick.test TCL tests.
|
||||
#
|
||||
@@ -1065,6 +1072,7 @@ clean:
|
||||
rm -f mptester mptester.exe
|
||||
rm -f fuzzershell fuzzershell.exe
|
||||
rm -f fuzzcheck fuzzcheck.exe
|
||||
rm -f sessionfuzz
|
||||
rm -f sqldiff sqldiff.exe
|
||||
rm -f fts5.* fts5parse.*
|
||||
rm -f lsm.h lsm1.c
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
C On\sunix,\sthe\s"PRAGMA\sfsync_interval=N"\scommand\scauses\san\sextra\sfdatasync()\nafter\swriting\sN\sbytes\sof\scontent,\sto\sforce\sa\swrite-queue\sflush\sin\sthe\nunderlying\sOS.\s\sThis\sis\san\sexperimental\shack\sthat\sis\snot\sexpected\sto\sland\non\strunk.
|
||||
D 2018-02-15T20:00:53.163
|
||||
C Draft\sfix\sfor\san\sfsdir()\sissue\sreported\svia\sthe\smailing\slist.
|
||||
D 2018-03-15T05:25:57.098
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F Makefile.in 7a3f714b4fcf793108042b7b0a5c720b0b310ec84314d61ba7f3f49f27e550ea
|
||||
F Makefile.in 7016fc56c6b9bfe5daac4f34be8be38d8c0b5fab79ccbfb764d3b23bf1c6fff3
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc b5e9eb7212c5a61d4800172c710376d1158fd5eea2edc0be8e05c0c372e767e4
|
||||
F README.md d748f58e3ab0fe0307fb4ae0942b415d93dcc4288756e366cc9e7cf8260c093f
|
||||
F Makefile.msc 8a6727b41a4626a5552016f4b0088b43fb14a32f53db1f47e83a0fefcb63c49a
|
||||
F README.md 1d5342ebda97420f114283e604e5fe99b0da939d63b76d492eabbaae23488276
|
||||
F VERSION cdf91ac446255ecf3d8f6d8c3ee40d64123235ae5b3cef29d344e61b45ec3759
|
||||
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
||||
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
|
||||
@@ -13,7 +13,7 @@ F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
|
||||
F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
|
||||
F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903
|
||||
F autoconf/Makefile.am 2c274948734e03c51790ff51468f91db8d570bcca864284d9c6d6e777264cd7e
|
||||
F autoconf/Makefile.msc 2c50a59319af7da4eaca8c13e3240881b1bc245fd175845a055faab7d03d6e67
|
||||
F autoconf/Makefile.msc 1223d1520e0b833041ad87b377fae61cc3e08d14c5aae4c1a9e36249225bd4e6
|
||||
F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7
|
||||
F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1
|
||||
F autoconf/configure.ac 18fca06f884213be062dd5e07c5297079cc45893d9cd3f522ce426e715033e3d
|
||||
@@ -43,7 +43,7 @@ F ext/async/README.txt e12275968f6fde133a80e04387d0e839b0c51f91
|
||||
F ext/async/sqlite3async.c 0f3070cc3f5ede78f2b9361fb3b629ce200d7d74
|
||||
F ext/async/sqlite3async.h f489b080af7e72aec0e1ee6f1d98ab6cf2e4dcef
|
||||
F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3
|
||||
F ext/expert/expert.c 4791c5e064aea81b2b829fa95228b22283380ee370ea88a1e580103b75516ebf
|
||||
F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4
|
||||
F ext/expert/expert1.test fd21496d8e52c817a7741f467f42b0502c0ac7e07dcdd1d6e15a3e8154ed4e41
|
||||
F ext/expert/sqlite3expert.c 1dfa561e64dc0f89d56b96e6afda87468c34b43604c2df50c47e3f4362778fb2
|
||||
F ext/expert/sqlite3expert.h af6354f8ee5c9e025024e63fec3bd640a802afcc3099a44d804752cf0791d811
|
||||
@@ -96,7 +96,7 @@ F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3
|
||||
F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004
|
||||
F ext/fts3/fts3_unicode.c 525a3bd9a7564603c5c061b7de55403a565307758a94600e8a2f6b00d1c40d9d
|
||||
F ext/fts3/fts3_unicode2.c cc04fc672bfd42b1e650398cb0bf71f64f9aae032cfe75bbcfe75b9cf966029c
|
||||
F ext/fts3/fts3_write.c 7a7cf93c02ebe0ee4211e4aa07da77586c2dcf7d381c1382f81d29c9aa8cae8c
|
||||
F ext/fts3/fts3_write.c b583dede85eb0c3c3026f8d7ccb781ea4e845ae583754fecb2ca425b5907d87d
|
||||
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
|
||||
F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
|
||||
F ext/fts3/tool/fts3cov.sh c331d006359456cf6f8f953e37f2b9c7d568f3863f00bb5f7eb87fea4ac01b73
|
||||
@@ -111,7 +111,7 @@ F ext/fts5/fts5Int.h eda28e3a0a5d87c412e8355fe35da875b04cb389908c8eb0d867ad662ad
|
||||
F ext/fts5/fts5_aux.c ca666a3bbe07c5a3bbe9fffaea19c935a1efaf337333e28bad7bdd1971ffd093
|
||||
F ext/fts5/fts5_buffer.c 1dd1ec0446b3acfc2d7d407eb894762a461613e2695273f48e449bfd13e973ff
|
||||
F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857
|
||||
F ext/fts5/fts5_expr.c 01048018d21524e2c302b063ff5c3cdcf546e03297215e577205d85b47499deb
|
||||
F ext/fts5/fts5_expr.c c23a2e4c14c401a147c4a730460e5b37057627bf4be95515ee281cd87f4d277c
|
||||
F ext/fts5/fts5_hash.c 32be400cf761868c9db33efe81a06eb19a17c5402ad477ee9efb51301546dd55
|
||||
F ext/fts5/fts5_index.c 22b71d0e9e4b3ddd123a39ae27174e0012da2806f91b64087a68584f13f189de
|
||||
F ext/fts5/fts5_main.c 24868f88ab2a865defbba7a92eebeb726cc991eb092b71b5f5508f180c72605b
|
||||
@@ -275,9 +275,9 @@ F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704
|
||||
F ext/misc/completion.c 52c3f01523e3e387eb321b4739a89d1fe47cbe6025aa1f2d8d3685e9e365df0f
|
||||
F ext/misc/compress.c dd4f8a6d0baccff3c694757db5b430f3bbd821d8686d1fc24df55cf9f035b189
|
||||
F ext/misc/csv.c 1a009b93650732e22334edc92459c4630b9fa703397cbb3c8ca279921a36ca11
|
||||
F ext/misc/dbdump.c 3509fa6b8932d04e932d6b6b827b6a82ca362781b8e8f3c77336f416793e215e
|
||||
F ext/misc/dbdump.c 22018e00eb50e9ebf9067c92d4e7162dc5006a3efc4e0c19bc3829825a1043b0
|
||||
F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2
|
||||
F ext/misc/fileio.c 4cad3a78bfbbea9b1414b4405fd704ee57fbe2621254b011888dae7b0ba8c513
|
||||
F ext/misc/fileio.c 673d6bde25cab00ad40cc95b89fa99c9f00870c565de3beaab9d6a9658bbc3e0
|
||||
F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25
|
||||
F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c
|
||||
F ext/misc/json1.c dbe086615b9546c156bf32b9378fc09383b58bd17513b866cfd24c1e15281984
|
||||
@@ -289,12 +289,12 @@ F ext/misc/percentile.c 92699c8cd7d517ff610e6037e56506f8904dae2e
|
||||
F ext/misc/regexp.c a68d25c659bd2d893cd1215667bbf75ecb9dc7d4
|
||||
F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c
|
||||
F ext/misc/rot13.c 540a169cb0d74f15522a8930b0cccdcb37a4fd071d219a5a083a319fc6e8db77
|
||||
F ext/misc/scrub.c 1c5bfb8b0cd18b602fcb55755e84abf0023ac2fb
|
||||
F ext/misc/scrub.c db9fff56fed322ca587d73727c6021b11ae79ce3f31b389e1d82891d144f22ad
|
||||
F ext/misc/series.c f3c0dba5c5c749ce1782b53076108f87cf0b71041eb6023f727a9c50681da564
|
||||
F ext/misc/sha1.c 0b9e9b855354910d3ca467bf39099d570e73db56
|
||||
F ext/misc/shathree.c 9e960ba50483214c6a7a4b1517f8d8cef799e9db381195178c3fd3ad207e10c0
|
||||
F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52
|
||||
F ext/misc/spellfix.c 705ce1ed701b38f43c8ee7dd848877ff51c09eda322e39ccac6873adb4b74735
|
||||
F ext/misc/spellfix.c b3a644285cb008f3c10ed4cf04e17adcbc7d62c3911c79d786dfc91c177534f0
|
||||
F ext/misc/sqlar.c 57d5bc45cd5492208e451f697404be88f8612527d64c9d42f96b325b64983d74
|
||||
F ext/misc/stmt.c 6f16443abb3551e3f5813bb13ba19a30e7032830015b0f92fe0c0453045c0a11
|
||||
F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512
|
||||
@@ -304,7 +304,7 @@ F ext/misc/vfsstat.c bf10ef0bc51e1ad6756629e1edb142f7a8db1178
|
||||
F ext/misc/vtablog.c 31d0d8f4406795679dcd3a67917c213d3a2a5fb3ea5de35f6e773491ed7e13c9
|
||||
F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd
|
||||
F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212
|
||||
F ext/misc/zipfile.c 3c3e21d0351a44c34c67ca7e833ba04e0de34421b4c9359aa764919ee36b37ef
|
||||
F ext/misc/zipfile.c e4e4f8289a8dee7e4f78547dacfb6548bcd83a02b52c0bc9205d8fbfb7f4b8a1
|
||||
F ext/misc/zorder.c b0ff58fa643afa1d846786d51ea8d5c4b6b35aa0254ab5a82617db92f3adda64
|
||||
F ext/rbu/rbu.c ea7d1b7eb44c123a2a619332e19fe5313500705c4a58aaa1887905c0d83ffc2e
|
||||
F ext/rbu/rbu1.test 43836fac8c7179a358eaf38a8a1ef3d6e6285842
|
||||
@@ -346,7 +346,7 @@ F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b14469
|
||||
F ext/repair/checkfreelist.c 0dbae18c1b552f58d64f8969e4fb1e7f11930c60a8c2a9a8d50b7f15bdfd54bd
|
||||
F ext/repair/checkindex.c 7d28c01a2e012ac64257d230fc452b2cafb78311a91a343633d01d95220f66f3
|
||||
F ext/repair/sqlite3_checker.c.in 4a5a3af3f450fe503e5a2985e98516dc2a6b9ad247449e284c1cf140fc91720f
|
||||
F ext/repair/sqlite3_checker.tcl cc69e7fbc163f94da4a6400609be001543442d9f8f57a797d1eeb7b897585730
|
||||
F ext/repair/sqlite3_checker.tcl a9a2caa9660567257c177a91124d8c0dccdfa341e25c51e6da7f1fd9e601eafa
|
||||
F ext/repair/test/README.md 34b2f542cf5be7bffe479242b33ee3492cea30711e447cc4a1a86cb5915f419e
|
||||
F ext/repair/test/checkfreelist01.test 3e8aa6aeb4007680c94a8d07b41c339aa635cc78249442da72ff3f8297398a69
|
||||
F ext/repair/test/checkindex01.test 6945d0ffc0c1dc993b2ce88036b26e0f5d6fcc65da70fc9df27c2647bb358b0f
|
||||
@@ -381,7 +381,7 @@ F ext/session/changeset.c 4ccbaa4531944c24584bf6a61ba3a39c62b6267a
|
||||
F ext/session/session1.test 736d7ff178662f0b717c37f46531b84a5ce0210ccb0c4edf629c55dbcbbc3ea1
|
||||
F ext/session/session2.test 284de45abae4cc1082bc52012ee81521d5ac58e0
|
||||
F ext/session/session3.test ce9ce3dfa489473987f899e9f6a0f2db9bde3479
|
||||
F ext/session/session4.test 457b02bdc349eb01151e54de014df77abd3c08c8
|
||||
F ext/session/session4.test 3eea8058643e5adbd3293a5c553255c35e774ed90e7cbec09c9b010d176ad396
|
||||
F ext/session/session5.test 716bc6fafd625ce60dfa62ae128971628c1a1169
|
||||
F ext/session/session6.test 443789bc2fca12e4f7075cf692c60b8a2bea1a26
|
||||
F ext/session/session8.test 8e194b3f655d861ca36de5d4de53f702751bab3b
|
||||
@@ -402,19 +402,16 @@ F ext/session/sessionfault.test da273f2712b6411e85e71465a1733b8501dbf6f7
|
||||
F ext/session/sessionfault2.test 04aa0bc9aa70ea43d8de82c4f648db4de1e990b0
|
||||
F ext/session/sessionstat1.test 41cd97c2e48619a41cdf8ae749e1b25f34719de638689221aa43971be693bf4e
|
||||
F ext/session/sessionwor.test 2f3744236dc8b170a695b7d8ddc8c743c7e79fdc
|
||||
F ext/session/sqlite3session.c a5b7aed647abe7e366254b755597fce3f2719d82c98990cb0e1e07a3d203fe2b
|
||||
F ext/session/sqlite3session.h 01774161cbd328fe3d496323655b9cc142317ff1fb1ae15c1232075ea240e3a4
|
||||
F ext/session/sqlite3session.c 9edfaaa74977ddecd7bbd94e8f844d9b0f6eec22d1d547e806361670db814c1e
|
||||
F ext/session/sqlite3session.h 2e1584b030fbd841cefdce15ba984871978d305f586da2d1972f6e1958fa10b1
|
||||
F ext/session/test_session.c eb0bd6c1ea791c1d66ee4ef94c16500dad936386
|
||||
F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
|
||||
F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04
|
||||
F ext/userauth/userauth.c 3410be31283abba70255d71fd24734e017a4497f
|
||||
F ext/zonefile/README.md 387ad2b748e98eeea21fd4dbb609fefe313263fadb3fc6c01c512b4c95e55ae4
|
||||
F ext/zonefile/zonefile.c 88d4ba281f47d35ce5989a7c500cfd05e3c8e348426baebcb7bcef314aee08f2
|
||||
F ext/zonefile/zonefile1.test 872ec8d549af0f1423601acdfe29390803fab3e14b8d5715f2f4bbd11431f1f5
|
||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
|
||||
F main.mk 0efdf6ac125eb810494d72dd7016ab07ddf3e3fa8615a14aef8491b69818fbe4
|
||||
F main.mk 63668484c95454af7fc04a384da27ac556f27368d6d0c345e405e1677c66768f
|
||||
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
|
||||
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
|
||||
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
|
||||
@@ -428,12 +425,12 @@ F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
|
||||
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
|
||||
F src/alter.c cf7a8af45cb0ace672f47a1b29ab24092a9e8cd8d945a9974e3b5d925f548594
|
||||
F src/analyze.c 6b42e36a5dcc2703a771f2411bd5e99524bd62c7ecde209bb88dfb04c72f046e
|
||||
F src/attach.c 84c477e856b24c2b9a0983b438a707c0cf4d616cee7a425401d418e58afec24c
|
||||
F src/attach.c f6f212c43dddba79dfcb723fb9470785f3ff55bde8953cd9d2546f3022070a41
|
||||
F src/auth.c 6277d63837357549fe14e723490d6dc1a38768d71c795c5eb5c0f8a99f918f73
|
||||
F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b
|
||||
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
|
||||
F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca
|
||||
F src/btree.c f7bb37c27b3734d58796febb30b5d818b3b4eb592b57b88039e5d92b3ebd9dab
|
||||
F src/btree.c 18a53540aa35dbdf77f715ea928422a4ed9011dc16ea7b50f803fd1617fcc4f5
|
||||
F src/btree.h 0866c0a08255142ea0e754aabd211c843cab32045c978a592a43152405ed0c84
|
||||
F src/btreeInt.h 620ab4c7235f43572cf3ac2ac8723cbdf68073be4d29da24897c7b77dda5fd96
|
||||
F src/build.c 672022c06e1a5c2653f80c77a687de11f7e65ce81d20fe2825aadfa13a875c33
|
||||
@@ -444,11 +441,11 @@ F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957
|
||||
F src/dbpage.c 8db4c97f630e7d83f884ea75caf1ffd0988c160e9d530194d93721c80821e0f6
|
||||
F src/dbstat.c 7a4ba8518b6369ef3600c49cf9c918ad979acba610b2aebef1b656d649b96720
|
||||
F src/delete.c 20c8788451dc737a967c87ea53ad43544d617f5b57d32ccce8bd52a0daf9e89b
|
||||
F src/expr.c 9e06de431c09f144438aa6895ea4d4290fa3c6875bfcc3ba331012ca78deadf0
|
||||
F src/expr.c 904f85e5f5fa232488cbb662fcf3306ae203728751468670fb9840a9b1886abc
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c d617daf66b5515e2b42c1405b2b4984c30ca50fb705ab164271a9bf66c69e331
|
||||
F src/func.c 94f42cba2cc1c34aeaa441022ba0170ec3fec4bba54db4e0ded085c6dc0fdc51
|
||||
F src/global.c ac3094f1dc59fbeb919aef7cc0cc827a8459d1fb1adb7972ef75bd9e0c10b75b
|
||||
F src/global.c 01506976bd75e5e7b977207a6a05062e2dd0050012f8071be06bbea22ec6d69a
|
||||
F src/hash.c a12580e143f10301ed5166ea4964ae2853d3905a511d4e0c44497245c7ce1f7a
|
||||
F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4
|
||||
F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da
|
||||
@@ -456,52 +453,53 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
|
||||
F src/insert.c 14686083cedc198540b15a79586cdd4be2acf6d5fa97627e355f817ab07e9fee
|
||||
F src/legacy.c 134ab3e3fae00a0f67a5187981d6935b24b337bcf0f4b3e5c9fa5763da95bf4e
|
||||
F src/loadext.c f6e4e416a736369f9e80eba609f0acda97148a8b0453784d670c78d3eed2f302
|
||||
F src/main.c dc75b3585bab31a88962eda2abe35a38b58c2e4d648e1a11e249fe43174c783f
|
||||
F src/main.c c1e97e4c6fffff1fb1a6f1c48807386819af78657b4ae4acfd6d6d17353b8277
|
||||
F src/malloc.c 07295435093ce354c6d9063ac05a2eeae28bd251d2e63c48b3d67c12c76f7e18
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
|
||||
F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
|
||||
F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a
|
||||
F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944
|
||||
F src/memdb.c 2bcebf99f77270e4b30ee5fad749347a6296db1662b3a196593e5410780aea85
|
||||
F src/memjournal.c 6f3d36a0a8f72f48f6c3c722f04301ac64f2515435fa42924293e46fc7994661
|
||||
F src/msvc.h 4942752b6a253116baaa8de75256c51a459a5e81
|
||||
F src/mutex.c b021263554c8a3995e9d53193b8194b96d1ed28e06c3b532dd7f7d29cf0c7d53
|
||||
F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85
|
||||
F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4
|
||||
F src/mutex_unix.c 27bb6cc49485ee46711a6580ab7b3f1402211d23
|
||||
F src/mutex_w32.c a898fa969823b100c0f5fdc57e54c9a1e419ab4d
|
||||
F src/mutex_unix.c aaf9ebc3f89df28483c52208497a99a02cc3650011422fc9d4c57e4392f7fe58
|
||||
F src/mutex_w32.c 7670d770c94bbfe8289bec9d7f1394c5a00a57c37f892aab6b6612d085255235
|
||||
F src/notify.c 9711a7575036f0d3040ba61bc6e217f13a9888e7
|
||||
F src/os.c 22d31db3ca5a96a408fbf1ceeaaebcaf64c87024d2ff9fe1cf2ddbec3e75c104
|
||||
F src/os.h 48388821692e87da174ea198bf96b1b2d9d83be5dfc908f673ee21fafbe0d432
|
||||
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
|
||||
F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
|
||||
F src/os_unix.c 774c789b63aaa4f3e17f5348a336c60bbd94f43e1aeb0a2bc4ffffe60fc178d3
|
||||
F src/os_unix.c 928586cbde31890538854f1657463392d63b2d7794f577774573ae53ec283d7b
|
||||
F src/os_win.c eb03c6d52f893bcd7fdd4c6006674c13c1b5e49543fec98d605201af2997171c
|
||||
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
||||
F src/pager.c 0b6bd5442733b2e08d0673de6cdafe3e7ab0b5715e4844ac836ab346b1d9ed89
|
||||
F src/pager.c 3e3b659b6b3f40b5a5efef6b8890ced490c397a81d96feb5266fde1f7362e608
|
||||
F src/pager.h 581698f2177e8bd4008fe4760898ce20b6133d1df22139b9101b5155f900df7a
|
||||
F src/parse.y 4e750e1b261ff9f1d0b6b5d40a829c66d691899f48953fde839d8b52d41aa148
|
||||
F src/pcache.c 7ae91a4557a43d77d449accbfdc68846e6516f8e2eda46e8bbe4536fb669b201
|
||||
F src/parse.y 3be4b2b5e33ef7dab3128b765898ee786fc6cd698a7f053f756a68f2f238f0aa
|
||||
F src/pcache.c 135ef0bc6fb2e3b7178d49ab5c9176254c8a691832c1bceb1156b2fbdd0869bd
|
||||
F src/pcache.h 072f94d29281cffd99e46c1539849f248c4b56ae7684c1f36626797fee375170
|
||||
F src/pcache1.c 716975564c15eb6679e97f734cec1bfd6c16ac3d4010f05f1f8e509fc7d19880
|
||||
F src/pragma.c bea56df3ae0637768c0da4fbbb8f2492f780980d95000034a105ff291bf7ca69
|
||||
F src/pragma.h bb83728944b42f6d409c77f5838a8edbdb0fe83046c5496ffc9602b40340a324
|
||||
F src/prepare.c 259f4e7960c47082c9653f3d5f0c294abd68bb9c3aab86de7630700cba1c20fb
|
||||
F src/printf.c 9506b4b96e59c0467047155f09015750cb2878aeda3d39e5610c1192ddc3c41c
|
||||
F src/printf.c d3b7844ddeb11fbbdd38dd84d09c9c1ac171d21fb038473c3aa97981201cc660
|
||||
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
|
||||
F src/resolve.c bbee7e31d369a18a2f4836644769882e9c5d40ef4a3af911db06410b65cb3730
|
||||
F src/resolve.c 66c73fcb7719b8ff0e841b58338f13604ff3e2b50a723f9b8f383595735262f6
|
||||
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
|
||||
F src/select.c f02352ac5cbb6fad3804add825743b924cfb6c742ba2e8666d726828a9985d73
|
||||
F src/shell.c.in 0b2c8d55e3703723a22610d75ccd4037962c3bcb5ad5570efd781e8c521811c4
|
||||
F src/sqlite.h.in 51f9acf52c80113d793ddd38b3940ad6895d97b4752503b19291fb8fcbf54c5e
|
||||
F src/shell.c.in 9b7e7ac1ccdbc045e285e745ff6d21dbec6ce91330f2bdd5db50d5c39f40679e
|
||||
F src/sqlite.h.in 6283ece8dbc3749d78593415a2373f4e7050afce7d18f87acea3b9a48f6fa576
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 83a3c4ce93d650bedfd1aa558cb85a516bd6d094445ee989740827d0d944368d
|
||||
F src/sqliteInt.h 119e240796d23054148005524f1d54a61e27dbef53bef3bc7ab65001405f4751
|
||||
F src/sqliteInt.h 2ef60a6d9a50e6eef224e9eae71b29a9fb91c301e882d9fbbb77afd50b6cf815
|
||||
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
|
||||
F src/status.c 9737ed017279a9e0c5da748701c3c7bf1e8ae0dae459aad20dd64fcff97a7e35
|
||||
F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
|
||||
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
|
||||
F src/tclsqlite.c 11a2618c227fd13ccad73ee02d1199f9880c59db2b3144fd7432db1980a2577d
|
||||
F src/test1.c 6b0dfd4f0a1996805bc04381b45df71ead9ed84634d2a47a757ab292febf9026
|
||||
F src/tclsqlite.c 916a92de77ec5cbe27818ca194d8cf0c58aa7ad5b87527098f6aa5a6068800ce
|
||||
F src/test1.c 1ab7cbbb6693e08364c1a9241e2aee17f8c4925e4cc52396be77ae6845a05828
|
||||
F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
|
||||
F src/test3.c b8434949dfb8aff8dfa082c8b592109e77844c2135ed3c492113839b6956255b
|
||||
F src/test4.c 18ec393bb4d0ad1de729f0b94da7267270f3d8e6
|
||||
@@ -516,7 +514,7 @@ F src/test_backup.c bf5da90c9926df0a4b941f2d92825a01bbe090a0
|
||||
F src/test_bestindex.c 78809f11026f18a93fcfd798d9479cba37e1201c830260bf1edc674b2fa9b857
|
||||
F src/test_blob.c ae4a0620b478548afb67963095a7417cd06a4ec0a56adb453542203bfdcb31ce
|
||||
F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274
|
||||
F src/test_config.c cc8a1d44648d9392a14f4ecfc841d027daaf61f952b9f70792edf11373aaa3dd
|
||||
F src/test_config.c 097c6189803886a1fb26ec37d8bc62b90512cb53ab79a1fb6d35196c1ec42ded
|
||||
F src/test_delete.c e2fe07646dff6300b48d49b2fee2fe192ed389e834dd635e3b3bac0ce0bf9f8f
|
||||
F src/test_demovfs.c a0c3bdd45ed044115c2c9f7779e56eafff18741e
|
||||
F src/test_devsym.c 1960abbb234b97e9b920f07e99503fc04b443f62bbc3c6ff2c2cea2133e3b8a2
|
||||
@@ -528,7 +526,7 @@ F src/test_intarray.c 988fc61cb0ff539f4172c0d95f15287c92516f64
|
||||
F src/test_intarray.h f3b7672f5d1056eac563c0d6ea8480a660b1475c
|
||||
F src/test_journal.c 619f2aa10e0d7a5f87c0f06825bc61dfce1c6b9c7f3ad990fb13de6c3b8874a3
|
||||
F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd
|
||||
F src/test_malloc.c 4f06a805de86be5216a127b3777ca2d5a1ff99d1a9238374ce136a47411be36c
|
||||
F src/test_malloc.c 5201422e2403e66a7a9c2b7d8df806acd8d2a0429822adb7e932f324e7b5b3c6
|
||||
F src/test_md5.c 7268e1e8c399d4a5e181b64ac20e1e6f3bc4dd9fc87abac02db145a3d951fa8c
|
||||
F src/test_multiplex.c e054459f7633f3ff8ce1245da724f9a8be189e4e
|
||||
F src/test_multiplex.h 5436d03f2d0501d04f3ed50a75819e190495b635
|
||||
@@ -554,30 +552,30 @@ F src/test_windirent.h 90dfbe95442c9762357fe128dc7ae3dc199d006de93eb33ba3972e0a9
|
||||
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
|
||||
F src/tokenize.c 5b0c661a85f783d35b9883830736eeb63be4aefc4f6b7d9cd081d48782c041e2
|
||||
F src/treeview.c eae35972ff44f67064de2eaf35f04afe94e7aea3271a8b3bcebb3f954880fec3
|
||||
F src/treeview.c e0d62678314abf0e1e6d09ea405f4de3f404a17b4641c2169c304b5edf509320
|
||||
F src/trigger.c a34539c69433276d37b0da9a89c117726ff2d292c0902895af1f393a983cd3a1
|
||||
F src/update.c a90a32ffc0100265b0693dbbdbe490756447af181f5ea2c138cce515b08c8795
|
||||
F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5
|
||||
F src/util.c d9eb0a6c4aae1b00a7369eadd7ca0bbe946cb4c953b6751aa20d357c2f482157
|
||||
F src/vacuum.c 90839322fd5f00df9617eb21b68beda9b6e2a2937576b0d65985e4aeb1c53739
|
||||
F src/vdbe.c a6892805df427bb9d554c37641406438bff568f99d26e72c1fb7e45f2ed6ce5b
|
||||
F src/vacuum.c 762ee9bbf8733d87d8cd06f58d950e881982e416f8c767334a40ffd341b6bff5
|
||||
F src/vdbe.c 88d8e0797bf49624d056014f34f302a7370cc119915cc0ece8f2b7bf5e7c30fb
|
||||
F src/vdbe.h 134beb7a12a6213c00eba58febaede33447cc4441bc568a0d9c144b33fc3720a
|
||||
F src/vdbeInt.h 8d7d07f13cb3c4cbca91e22ba4a1920e542dda7c5d9299920432a0b3d5b009f5
|
||||
F src/vdbeapi.c fea41171884a4de119f8b10ab514c788674eeeb7f27218bb6d008e1310bfd07f
|
||||
F src/vdbeInt.h 95f7adfdc5c8f1353321f55a6c5ec00a90877e3b85af5159e393afb41ff54110
|
||||
F src/vdbeapi.c 29d2baf9c1233131ec467d7bed1b7c8a03c27579048d768c4b04acf427838858
|
||||
F src/vdbeaux.c 2756ac68ac259c416554100598fc291870063288cd7e1af22847f57b3e130e56
|
||||
F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191
|
||||
F src/vdbemem.c 21c1d00f0b901dda0a2eccf56bf0d86648cae1bde37de0606ae4e7cdb0ff6d3d
|
||||
F src/vdbemem.c 414e28d3a7e2a8bee2bb247de115dcbc68e3cbac284d5862d077002f7a93bce1
|
||||
F src/vdbesort.c 731a09e5cb9e96b70c394c1b7cf3860fbe84acca7682e178615eb941a3a0ef2f
|
||||
F src/vdbetrace.c 48e11ebe040c6b41d146abed2602e3d00d621d7ebe4eb29b0a0f1617fd3c2f6c
|
||||
F src/vtab.c 0e4885495172e1bdf54b12cce23b395ac74ef5729031f15e1bc1e3e6b360ed1a
|
||||
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c 5a3f464edd64596f601683ed321d12e6fd93c5fb9afdfb3653d6ffd0fee9c48f
|
||||
F src/wal.c aa9cffc7a2bad6b826a86c8562dd4978398720ed41cb8ee7aa9d054eb8b456a0
|
||||
F src/wal.h 8de5d2d3de0956d6f6cb48c83a4012d5f227b8fe940f3a349a4b7e85ebcb492a
|
||||
F src/walker.c da987a20d40145c0a03c07d8fefcb2ed363becc7680d0500d9c79915591f5b1f
|
||||
F src/where.c 7cae47e813393d70c6d327fdf000fcb30f76b1b0b5a5b52ff6402e0c658de32c
|
||||
F src/whereInt.h 82c04c5075308abbac59180c8bad5ecb45b07453981f60a53f3c7dee21e1e971
|
||||
F src/wherecode.c cb360c511f69294ddf00340d7b390e6b1d601a1cfb77b42c4d316fe2f4cd01c3
|
||||
F src/whereexpr.c 22dbfd3bf5f6051a61523dd0ebef7a944fb29ee4aa7d2a62feb8aac6ffbbc0eb
|
||||
F src/wherecode.c e1aaadd8fec650037cfbf27d1b3470338fb3b58fec34d11082df16fe9a08fbd7
|
||||
F src/whereexpr.c 53532be687e12f3cd314f1e204cd4fbdac7ad250e918a182b048121e16e828ae
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
|
||||
F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
|
||||
@@ -730,7 +728,7 @@ F test/crash4.test fe2821baf37168dc59dd733dcf7dba2a401487bc
|
||||
F test/crash5.test 05dd3aa9dbb751a22d5cdaf22a9c49b6667aa219
|
||||
F test/crash6.test 4c56f1e40d0291e1110790a99807aa875b1647ba
|
||||
F test/crash7.test 1a194c4900a255258cf94b7fcbfd29536db572df
|
||||
F test/crash8.test 63cd5aea313222d7a69637cf7174c34d151676cc187d57193b66d4c89dedede3
|
||||
F test/crash8.test 64366e459c28dd62edfb7ad87253a409c7533b92d16fcc479a6a8131bdcc3100
|
||||
F test/crashM.test d95f59046fa749b0d0822edf18a717788c8f318d
|
||||
F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
|
||||
F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8
|
||||
@@ -743,8 +741,8 @@ F test/date.test 9b73bbeb1b82d9c1f44dec5cf563bf7da58d2373
|
||||
F test/date2.test 74c234bece1b016e94dd4ef9c8cc7a199a8806c0e2291cab7ba64bace6350b10
|
||||
F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e
|
||||
F test/dbpage.test dbf50a4d361f9e45a979432c727506065113124478a7d2db12074fa655e65d6c
|
||||
F test/dbstatus.test 73149851b3aff14fc6db478e58f9083a66422cf5
|
||||
F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab
|
||||
F test/dbstatus.test c15fa97f743dac7ce996814c84b56317e138895ee15ce27f15b608aa6924c90a
|
||||
F test/dbstatus2.test 35a987036fefbbc696e65b6a3fbd860864cfd54941c52f50c61b55d4778ac66c
|
||||
F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d
|
||||
F test/delete.test acc38fca8ee4851467705b1c2cfea64cd26667e5
|
||||
F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa
|
||||
@@ -795,7 +793,7 @@ F test/exclusive.test 1206b87e192497d78c7f35552e86a9d05421498da300fb1cce5ca5351c
|
||||
F test/exclusive2.test 984090e8e9d1b331d2e8111daf6e5d61dda0bef7
|
||||
F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
|
||||
F test/exists.test 79a75323c78f02bbe9c251ea502a092f9ef63dac
|
||||
F test/expr.test 66a2c9ac34f74f036faa4092f5402c7d3162fc93
|
||||
F test/expr.test 7cb55e80aeb41d65fec968c08212505123063fea60bdc355d764d747670e9eea
|
||||
F test/extension01.test 00d13cec817f331a687a243e0e5a2d87b0e358c9
|
||||
F test/extraquick.test cb254400bd42bfb777ff675356aabf3287978f79
|
||||
F test/fallocate.test 07416bd593a116d5893cb244f45a94d5c6fe030561df3bd972e6135f8106e509
|
||||
@@ -921,7 +919,7 @@ F test/fts4merge2.test 5faa558d1b672f82b847d2a337465fa745e46891
|
||||
F test/fts4merge3.test 8d9ccb4a3d41c4c617a149d6c4b13ad02de797d0
|
||||
F test/fts4merge4.test d895b1057a7798b67e03455d0fa50e9ea836c47b
|
||||
F test/fts4noti.test 5553d7bb2e20bf4a06b23e849352efc022ce6309
|
||||
F test/fts4onepass.test 7319d61a2ed1325fc54afd0c060a0513b462303a
|
||||
F test/fts4onepass.test d69ddc4ee3415e40b0c5d1d0408488a87614d4f63ba9c44f3e52db541d6b7cc7
|
||||
F test/fts4opt.test fd6a11684b965e1999564ae763797b7fb9e34c96
|
||||
F test/fts4unicode.test ceca76422abc251818cb25dabe33d3c3970da5f7c90e1540f190824e6b3a7c95
|
||||
F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d
|
||||
@@ -930,14 +928,14 @@ F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f
|
||||
F test/func3.test d202a7606d23f90988a664e88e268aed1087c11c
|
||||
F test/func4.test 6beacdfcb0e18c358e6c2dcacf1b65d1fa80955f
|
||||
F test/func5.test cdd224400bc3e48d891827cc913a57051a426fa4
|
||||
F test/func6.test 612311a51adad23326d15353eea8d90394798acb26dd1f7c7cad59bd8ac982d2
|
||||
F test/func6.test 90e42b64c4f9fb6f04f44cb8a1da586c8542502e926b19c76504fe74ff2a9b7c
|
||||
F test/fuzz-oss1.test e58330d01cbbd8215ee636b17a03fe220b37dbfa
|
||||
F test/fuzz.test 96083052bf5765e4518c1ba686ce2bab785670d1
|
||||
F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1
|
||||
F test/fuzz3.test 9c813e6613b837cb7a277b0383cd66bfa07042b4cf0317157c35852f30043c31
|
||||
F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b
|
||||
F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26
|
||||
F test/fuzzcheck.c 2152602232c96d9c790eff3013e1369ce59de3203fa0b75bc613531448454e61
|
||||
F test/fuzzcheck.c 5eb86c6ac96833ee622f45bf47e8045999c1b4b10d05e4eb809894a4b39f2f84
|
||||
F test/fuzzdata1.db 7ee3227bad0e7ccdeb08a9e6822916777073c664
|
||||
F test/fuzzdata2.db f03a420d3b822cc82e4f894ca957618fbe9c4973
|
||||
F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
|
||||
@@ -1004,6 +1002,7 @@ F test/ioerr3.test d3cec5e1a11ad6d27527d0d38573fbff14c71bdd
|
||||
F test/ioerr4.test f130fe9e71008577b342b8874d52984bd04ede2c
|
||||
F test/ioerr5.test 2edfa4fb0f896f733071303b42224df8bedd9da4
|
||||
F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b
|
||||
F test/istrue.test 2d89873d72248b7a0ef7b5457120100cce75a19181bcf4b30e90a3f96a5c5558
|
||||
F test/join.test 442c462eea85cf065d70a663c626b780a95af6e11585d909bb63b87598afe678
|
||||
F test/join2.test f1b5ba94ba70a791df2d99e61adcebf62edacad1eca57881c97eb3e2ca718595
|
||||
F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0
|
||||
@@ -1021,7 +1020,7 @@ F test/json102.test eeb54efa221e50b74a2d6fb9259963b48d7414dca3ce2fdfdeed45cb2848
|
||||
F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0
|
||||
F test/json104.test 877d5845f6303899b7889ea5dd1bea99076e3100574d5c536082245c5805dcaa
|
||||
F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
|
||||
F test/kvtest.c fcb38ffe3db028a3138b4818fc098359c80dc51a0d1278a91c99c554cc1abb92
|
||||
F test/kvtest.c 23452e653e6b0254dc2fd1d242d4c7c65644504de8951d7d60f7e4291c52c231
|
||||
F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
|
||||
F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
|
||||
F test/like.test 11cfd7d4ef8625389df9efc46735ff0b0b41d5e62047ef0f3bc24c380d28a7a6
|
||||
@@ -1068,6 +1067,7 @@ F test/malloc_common.tcl aac62499b76be719fac31e7a3e54a7fd53272e7f
|
||||
F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e
|
||||
F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f
|
||||
F test/memdb.test c1f2a343ad14398d5d6debda6ea33e80d0dafcc7
|
||||
F test/memdb1.test fbe47f36c12725ebdd2760f846371e6eb09f403bd7236fbdddb21aa6e3c652b4
|
||||
F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2
|
||||
F test/memsubsys1.test 9e7555a22173b8f1c96c281ce289b338fcba2abe8b157f8798ca195bbf1d347e
|
||||
F test/memsubsys2.test 3e4a8d0c05fd3e5fa92017c64666730a520c7e08
|
||||
@@ -1098,7 +1098,7 @@ F test/multiplex4.test e8ae4c4bd70606a5727743241f13b5701990abe4
|
||||
F test/mutex1.test ea2cc74d97f077b9e74c84cbd024f14d79a8126f
|
||||
F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660
|
||||
F test/nan.test 437d40e6d0778b050d7750726c0cbd2c9936b81962926e8f8c48ca698f00f4d1
|
||||
F test/nockpt.test fd5473e30a84848b25ab06524750c05095383e191be83ccb4e6951c8beddfb5b
|
||||
F test/nockpt.test 8c43b25af63b0bd620cf1b003529e37b6f1dc53bd22690e96a1bd73f78dde53a
|
||||
F test/nolock.test f196cf8b8fbea4e2ca345140a2b3f3b0da45c76e
|
||||
F test/normalize.test 501630ab49b0b26b65c74124bf03e3374c1b57fa97aae750f84803609141d167
|
||||
F test/notify1.test 669b2b743618efdc18ca4b02f45423d5d2304abf
|
||||
@@ -1120,8 +1120,8 @@ F test/orderby7.test 3d1383d52ade5b9eb3a173b3147fdd296f0202da
|
||||
F test/orderby8.test 23ef1a5d72bd3adcc2f65561c654295d1b8047bd
|
||||
F test/orderby9.test 87fb9548debcc2cd141c5299002dd94672fa76a3
|
||||
F test/oserror.test b32dc34f2363ef18532e3a0a7358e3e7e321974f
|
||||
F test/ossfuzz.c 3613bc516386234cf2e513fb94dc677ab3862eb7ebc5b3671c319a80f86839fb
|
||||
F test/ossshell.c 296ab63067841bd1b1e97b46a0b2af48ee7f69d50d1a723008bee12dd7122622
|
||||
F test/ossfuzz.c c4c4547e2c92ac52f10038b073a03248251a23c1c559728f63a18aeca0e79f03
|
||||
F test/ossshell.c f125c5bd16e537a2549aa579b328dd1c59905e7ab1338dfc210e755bb7b69f17
|
||||
F test/ovfl.test 199c482696defceacee8c8e0e0ef36da62726b2f
|
||||
F test/pager1.test f596d3bd53ce96e1d87d44d223d2ae6c8867dd782c425e5eb28b5721fa6aaa97
|
||||
F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71
|
||||
@@ -1144,7 +1144,7 @@ F test/pragma4.test 3046501bee2f652dc2a4f9c87781e2741361d6864439c8381aba6c3b774b
|
||||
F test/pragma5.test 824ce6ced5d6b7ec71abe37fc6005ff836fe39d638273dc5192b39864b9ee983
|
||||
F test/pragmafault.test 275edaf3161771d37de60e5c2b412627ac94cef11739236bec12ed1258b240f8
|
||||
F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc
|
||||
F test/printf2.test 9e6db85f81c63f2367c34a9d7db384088bd374ad
|
||||
F test/printf2.test 30b5dd0b4b992dc5626496846ecce17ff592cacbcb11c3e589f3ac4d7e129dae
|
||||
F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb
|
||||
F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
|
||||
F test/pushdown.test 5e72c51c5e33253ed639ccee1e01ce62d62b6eee5ca893cd82334e4ee7b1d7fc
|
||||
@@ -1169,7 +1169,7 @@ F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a
|
||||
F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc
|
||||
F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81
|
||||
F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d
|
||||
F test/rowvalue.test e1bd1690d891abff6138f9612241615d2de7671cb28eb58ebdd591a5b01089a4
|
||||
F test/rowvalue.test 32861d6a933ded868035f2ec79aeb993a2a46eb7a6d282ae13415a4c2e369463
|
||||
F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b
|
||||
F test/rowvalue3.test 3068f508753af69884b12125995f023da0dbb256
|
||||
F test/rowvalue4.test 4b556d7de161a0dd8cff095c336e913986398bea
|
||||
@@ -1215,6 +1215,8 @@ F test/selectF.test 21c94e6438f76537b72532fa9fd4710cdd455fc3
|
||||
F test/selectG.test 089f7d3d7e6db91566f00b036cb353107a2cca6220eb1cb264085a836dae8840
|
||||
F test/server1.test 46803bd3fe8b99b30dbc5ff38ffc756f5c13a118
|
||||
F test/session.test 78fa2365e93d3663a6e933f86e7afc395adf18be
|
||||
F test/sessionfuzz-data1.db 1f8d5def831f19b1c74571037f0d53a588ea49a6c4ca2a028fc0c27ef896dbcb
|
||||
F test/sessionfuzz.c b0fcdcf757451957e17396a3af5171f1fdf9b2babc81da9fa35675df46c4729a
|
||||
F test/shared.test 1da9dbad400cee0d93f252ccf76e1ae007a63746
|
||||
F test/shared2.test 03eb4a8d372e290107d34b6ce1809919a698e879
|
||||
F test/shared3.test ab693f9b6e156b8bfb2a0ad94f29fe69602a5d38
|
||||
@@ -1263,11 +1265,12 @@ F test/speed2.test 53177056baf6556dcbdcf032bbdfc41c1aa74ded
|
||||
F test/speed3.test 694affeb9100526007436334cf7d08f3d74b85ef
|
||||
F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715
|
||||
F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
|
||||
F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
|
||||
F test/speed4p.test 377a0c48e5a92e0b11c1c5ebb1bc9d83a7312c922bc0cb05970ef5d6a96d1f0c
|
||||
F test/speedtest1.c a5faf4cbe5769eee4b721b3875cb3f12520a9b99d9026b1063b47c39603375b8
|
||||
F test/spellfix.test f9c1f431e2c096c8775fec032952320c0e4700db
|
||||
F test/spellfix.test 951a6405d49d1a23d6b78027d3877b4a33eeb8221dcab5704b499755bb4f552e
|
||||
F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3
|
||||
F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33
|
||||
F test/spellfix4.test 51c7c26514ade169855c66bcf130bd5acfb4d7fd090cc624645ab275ae6a41fb
|
||||
F test/sqldiff1.test 28cd737cf1b0078b1ec1bbf425e674c47785835e
|
||||
F test/sqllimits1.test a74ee2a3740b9f9c2437c246d8fb77354862a142
|
||||
F test/sqllog.test 6af6cb0b09f4e44e1917e06ce85be7670302517a
|
||||
@@ -1295,7 +1298,7 @@ F test/tabfunc01.test c47171c36b3d411df2bd49719dcaa5d034f8d277477fd41d253940723b
|
||||
F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f
|
||||
F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
|
||||
F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
|
||||
F test/tclsqlite.test c3d7ac9449634b9f17fd048a3c0212e88a7448be810a9c5bd051acc1ffa00d2f
|
||||
F test/tclsqlite.test 5337e8890b96dad1ee541b15fbeec32e6bac2fe7fa096f91089057385aadba9b
|
||||
F test/tempdb.test 4cdaa23ddd8acb4d79cbb1b68ccdfd09b0537aaba909ca69a876157c2a2cbd08
|
||||
F test/tempdb2.test 27e41ed540b2f9b056c2e77e9bddc1b875358507
|
||||
F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900
|
||||
@@ -1461,7 +1464,7 @@ F test/tokenize.test ce430a7aed48fc98301611429595883fdfcab5d7
|
||||
F test/tpch01.test 04adbf8d8300fa60a222f28d901abd76e7be6dd4
|
||||
F test/trace.test a659a9862957f4789e37a92b3bf6d2caf5c86b02cdeefc41e850ae53acf6992a
|
||||
F test/trace2.test f5cb67ad3bc09e0c58e8cca78dfd0b5639259983
|
||||
F test/trace3.test 56ab944fddacf628b118cc298503fc45c2e50ab0
|
||||
F test/trace3.test b41076f536876b6edf661c0cf8f9216771316efd0fe78905576cc23ce269e7f2
|
||||
F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6
|
||||
F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76
|
||||
F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94
|
||||
@@ -1596,6 +1599,7 @@ F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc
|
||||
F test/with1.test ca08e291249a810a2ec9b72ceef5575e07d5925b360fcf6652ae6fe06ac4dced
|
||||
F test/with2.test e0030e2f0267a910d6c0e4f46f2dfe941c1cc0d4f659ba69b3597728e7e8f1ab
|
||||
F test/with3.test e71604a0e53cba82bc04c703987cb1d6751ec0b6
|
||||
F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f198205
|
||||
F test/withM.test 693b61765f2b387b5e3e24a4536e2e82de15ff64
|
||||
F test/without_rowid1.test 06b7215130882d6a072233820dd364c874c4fd69221e8fc756ec471009192874
|
||||
F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99
|
||||
@@ -1607,13 +1611,13 @@ F test/wordcount.c cb589cec469a1d90add05b1f8cee75c7210338d87a5afd65260ed5c0f4bbf
|
||||
F test/writecrash.test f1da7f7adfe8d7f09ea79b42e5ca6dcc41102f27f8e334ad71539501ddd910cc
|
||||
F test/zeroblob.test 3857870fe681b8185654414a9bccfde80b62a0fa
|
||||
F test/zerodamage.test 9c41628db7e8d9e8a0181e59ea5f189df311a9f6ce99cc376dc461f66db6f8dc
|
||||
F test/zipfile.test 44aa8af115cc3e8c905468768dc761260650a8fdfca57e10f9818f5f8008d340
|
||||
F test/zipfile.test a9806a86e5a153d897f320de624a83a9e9774515eb79ad2419496187b1acc7d7
|
||||
F test/zipfile2.test 67d5f08a202796d4b7a71dfa4b8dcb74aa7a9d1f42c5f17bedff9855c1ba7aa5
|
||||
F test/zipfilefault.test 050be76778d2ec83566a542800fc3967f65ce719671a819016ada8b654bc14f7
|
||||
F test/zipfilefault.test 44d4d7a7f7cca7521d569d7f71026b241d65a6b1757aa409c1a168827edbbc2c
|
||||
F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5
|
||||
F tool/GetTclKit.bat 8995df40c4209808b31f24de0b58f90930239a234f7591e3675d45bfbb990c5d
|
||||
F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91
|
||||
F tool/addopcodes.tcl 7181c041d495e3f26acc36d15c86923ed722285f9015f017f41a3efdb9a0dab4
|
||||
F tool/addopcodes.tcl 0288d5b26b9b35f4cb5affb76eec63f1dfce117bbc2020066708069ef60b86ff
|
||||
F tool/build-all-msvc.bat c12328d06c45fec8baada5949e3d5af54bf8c887 x
|
||||
F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367
|
||||
F tool/cg_anno.tcl f95b0006c52cf7f0496b506343415b6ee3cdcdd3 x
|
||||
@@ -1640,13 +1644,13 @@ F tool/mkkeywordhash.c 2e852ac0dfdc5af18886dc1ce7e9676d11714ae3df0a282dc7d90b3a0
|
||||
F tool/mkmsvcmin.tcl 8baf26690b80d861d0ac341b29880eec6ade39e4f11fe690271ded9cb90563a3
|
||||
F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c
|
||||
F tool/mkopcodeh.tcl 4ee2a30ccbd900dc4d5cdb61bdab87cd2166cd2affcc78c9cc0b8d22a65b2eee
|
||||
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
|
||||
F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa
|
||||
F tool/mkpragmatab.tcl 2144bc8550a6471a029db262a132d2df4b9e0db61b90398bf64f5b7b3f8d92cd
|
||||
F tool/mkshellc.tcl 1f45770aea226ac093a9c72f718efbb88a2a2833409ec2e1c4cecae4202626f5
|
||||
F tool/mksourceid.c d458f9004c837bee87a6382228ac20d3eae3c49ea3b0a5aace936f8b60748d3b
|
||||
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
|
||||
F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb
|
||||
F tool/mksqlite3c.tcl 1fb69d39166f52d802a70ec37d99bca51d011c8ab30be27bc495be493196ae41
|
||||
F tool/mksqlite3c.tcl a03cee30de81a2e67b93e5c659f24113a003677c557daeb008205c8e6d4345d6
|
||||
F tool/mksqlite3h.tcl f92f994d9709aeb9e2b6e6f9fc8b069d2f55202c8e23f453edc44390a25982dc
|
||||
F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b
|
||||
F tool/mkvsix.tcl b9e0777a213c23156b6542842c238479e496ebf5
|
||||
@@ -1666,7 +1670,7 @@ F tool/showstat4.c 0682ebea7abf4d3657f53c4a243f2e7eab48eab344ed36a94bb75dcd19a5c
|
||||
F tool/showwal.c ad9d768f96ca6199ad3a8c9562d679680bd032dd01204ea3e5ea6fb931d81847
|
||||
F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe
|
||||
F tool/spaceanal.tcl 4bfd19aad7eb3ce0372ef0255f58035e0bba4ff5e9acfd763a10c6fb365c8dec
|
||||
F tool/speed-check.sh 9ae425da8819e54e780cf494fc6d8175dfb16e109ae3214a45a5c9bb2b74e2c4
|
||||
F tool/speed-check.sh 4ff9b095cf1a7643f0264e7fb7d23f0b12b7cce587a9de315877c378e90eeaf4
|
||||
F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355
|
||||
F tool/speedtest16.c ecb6542862151c3e6509bbc00509b234562ae81e
|
||||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||
@@ -1708,10 +1712,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 fb1c2277912c55cfae30c18b5434bc193748746395fa7df983cd8a29e5741ff9
|
||||
R de6bec149ec0467cfe04c10e1715419d
|
||||
T *branch * write-queue-flush-hack
|
||||
T *sym-write-queue-flush-hack *
|
||||
T -sym-zonefile *
|
||||
U drh
|
||||
Z 7c64ce09377dd8ff73b08359bba5f163
|
||||
P 48a06eb02b42a021b835ff9766535805723259b9701b87fb17fa488b133cb53a
|
||||
R f348889711b0641611a4541c43f0ef77
|
||||
T *branch * fsDirFix
|
||||
T *sym-fsDirFix *
|
||||
T -sym-trunk *
|
||||
U mistachkin
|
||||
Z e35ad5809ec8c5cee9fda8092826113a
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
b18cc5fee44fb2ab8a48fb3ba92a780090c7ead6af1ebcb67ab1fe214dde709c
|
||||
48641010c24bf37f13d68c4d19c5c3e9b41404af12a4947705cc53a31db04178
|
||||
+105
-69
@@ -55,6 +55,10 @@ static int resolveAttachExpr(NameContext *pName, Expr *pExpr)
|
||||
**
|
||||
** If the optional "KEY z" syntax is omitted, an SQL NULL is passed as the
|
||||
** third argument.
|
||||
**
|
||||
** If the db->init.reopenMemdb flags is set, then instead of attaching a
|
||||
** new database, close the database on db->init.iDb and reopen it as an
|
||||
** empty MemDB.
|
||||
*/
|
||||
static void attachFunc(
|
||||
sqlite3_context *context,
|
||||
@@ -75,65 +79,85 @@ static void attachFunc(
|
||||
sqlite3_vfs *pVfs;
|
||||
|
||||
UNUSED_PARAMETER(NotUsed);
|
||||
|
||||
zFile = (const char *)sqlite3_value_text(argv[0]);
|
||||
zName = (const char *)sqlite3_value_text(argv[1]);
|
||||
if( zFile==0 ) zFile = "";
|
||||
if( zName==0 ) zName = "";
|
||||
|
||||
/* Check for the following errors:
|
||||
**
|
||||
** * Too many attached databases,
|
||||
** * Transaction currently open
|
||||
** * Specified database name already being used.
|
||||
*/
|
||||
if( db->nDb>=db->aLimit[SQLITE_LIMIT_ATTACHED]+2 ){
|
||||
zErrDyn = sqlite3MPrintf(db, "too many attached databases - max %d",
|
||||
db->aLimit[SQLITE_LIMIT_ATTACHED]
|
||||
);
|
||||
goto attach_error;
|
||||
}
|
||||
for(i=0; i<db->nDb; i++){
|
||||
char *z = db->aDb[i].zDbSName;
|
||||
assert( z && zName );
|
||||
if( sqlite3StrICmp(z, zName)==0 ){
|
||||
zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName);
|
||||
#ifdef SQLITE_ENABLE_DESERIALIZE
|
||||
# define REOPEN_AS_MEMDB(db) (db->init.reopenMemdb)
|
||||
#else
|
||||
# define REOPEN_AS_MEMDB(db) (0)
|
||||
#endif
|
||||
|
||||
if( REOPEN_AS_MEMDB(db) ){
|
||||
/* This is not a real ATTACH. Instead, this routine is being called
|
||||
** from sqlite3_deserialize() to close database db->init.iDb and
|
||||
** reopen it as a MemDB */
|
||||
pVfs = sqlite3_vfs_find("memdb");
|
||||
if( pVfs==0 ) return;
|
||||
pNew = &db->aDb[db->init.iDb];
|
||||
if( pNew->pBt ) sqlite3BtreeClose(pNew->pBt);
|
||||
pNew->pBt = 0;
|
||||
pNew->pSchema = 0;
|
||||
rc = sqlite3BtreeOpen(pVfs, "x", db, &pNew->pBt, 0, SQLITE_OPEN_MAIN_DB);
|
||||
}else{
|
||||
/* This is a real ATTACH
|
||||
**
|
||||
** Check for the following errors:
|
||||
**
|
||||
** * Too many attached databases,
|
||||
** * Transaction currently open
|
||||
** * Specified database name already being used.
|
||||
*/
|
||||
if( db->nDb>=db->aLimit[SQLITE_LIMIT_ATTACHED]+2 ){
|
||||
zErrDyn = sqlite3MPrintf(db, "too many attached databases - max %d",
|
||||
db->aLimit[SQLITE_LIMIT_ATTACHED]
|
||||
);
|
||||
goto attach_error;
|
||||
}
|
||||
for(i=0; i<db->nDb; i++){
|
||||
char *z = db->aDb[i].zDbSName;
|
||||
assert( z && zName );
|
||||
if( sqlite3StrICmp(z, zName)==0 ){
|
||||
zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName);
|
||||
goto attach_error;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate the new entry in the db->aDb[] array and initialize the schema
|
||||
** hash tables.
|
||||
*/
|
||||
if( db->aDb==db->aDbStatic ){
|
||||
aNew = sqlite3DbMallocRawNN(db, sizeof(db->aDb[0])*3 );
|
||||
if( aNew==0 ) return;
|
||||
memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
|
||||
}else{
|
||||
aNew = sqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
|
||||
if( aNew==0 ) return;
|
||||
}
|
||||
db->aDb = aNew;
|
||||
pNew = &db->aDb[db->nDb];
|
||||
memset(pNew, 0, sizeof(*pNew));
|
||||
|
||||
/* Open the database file. If the btree is successfully opened, use
|
||||
** it to obtain the database schema. At this point the schema may
|
||||
** or may not be initialized.
|
||||
*/
|
||||
flags = db->openFlags;
|
||||
rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr);
|
||||
if( rc!=SQLITE_OK ){
|
||||
if( rc==SQLITE_NOMEM ) sqlite3OomFault(db);
|
||||
sqlite3_result_error(context, zErr, -1);
|
||||
sqlite3_free(zErr);
|
||||
return;
|
||||
}
|
||||
assert( pVfs );
|
||||
flags |= SQLITE_OPEN_MAIN_DB;
|
||||
rc = sqlite3BtreeOpen(pVfs, zPath, db, &pNew->pBt, 0, flags);
|
||||
sqlite3_free( zPath );
|
||||
db->nDb++;
|
||||
}
|
||||
|
||||
/* Allocate the new entry in the db->aDb[] array and initialize the schema
|
||||
** hash tables.
|
||||
*/
|
||||
if( db->aDb==db->aDbStatic ){
|
||||
aNew = sqlite3DbMallocRawNN(db, sizeof(db->aDb[0])*3 );
|
||||
if( aNew==0 ) return;
|
||||
memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
|
||||
}else{
|
||||
aNew = sqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
|
||||
if( aNew==0 ) return;
|
||||
}
|
||||
db->aDb = aNew;
|
||||
pNew = &db->aDb[db->nDb];
|
||||
memset(pNew, 0, sizeof(*pNew));
|
||||
|
||||
/* Open the database file. If the btree is successfully opened, use
|
||||
** it to obtain the database schema. At this point the schema may
|
||||
** or may not be initialized.
|
||||
*/
|
||||
flags = db->openFlags;
|
||||
rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr);
|
||||
if( rc!=SQLITE_OK ){
|
||||
if( rc==SQLITE_NOMEM ) sqlite3OomFault(db);
|
||||
sqlite3_result_error(context, zErr, -1);
|
||||
sqlite3_free(zErr);
|
||||
return;
|
||||
}
|
||||
assert( pVfs );
|
||||
flags |= SQLITE_OPEN_MAIN_DB;
|
||||
rc = sqlite3BtreeOpen(pVfs, zPath, db, &pNew->pBt, 0, flags);
|
||||
sqlite3_free( zPath );
|
||||
db->nDb++;
|
||||
db->skipBtreeMutex = 0;
|
||||
if( rc==SQLITE_CONSTRAINT ){
|
||||
rc = SQLITE_ERROR;
|
||||
@@ -160,7 +184,7 @@ static void attachFunc(
|
||||
sqlite3BtreeLeave(pNew->pBt);
|
||||
}
|
||||
pNew->safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1;
|
||||
pNew->zDbSName = sqlite3DbStrDup(db, zName);
|
||||
if( !REOPEN_AS_MEMDB(db) ) pNew->zDbSName = sqlite3DbStrDup(db, zName);
|
||||
if( rc==SQLITE_OK && pNew->zDbSName==0 ){
|
||||
rc = SQLITE_NOMEM_BKPT;
|
||||
}
|
||||
@@ -200,13 +224,15 @@ static void attachFunc(
|
||||
|
||||
/* If the file was opened successfully, read the schema for the new database.
|
||||
** If this fails, or if opening the file failed, then close the file and
|
||||
** remove the entry from the db->aDb[] array. i.e. put everything back the way
|
||||
** we found it.
|
||||
** remove the entry from the db->aDb[] array. i.e. put everything back the
|
||||
** way we found it.
|
||||
*/
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3BtreeEnterAll(db);
|
||||
db->init.iDb = 0;
|
||||
rc = sqlite3Init(db, &zErrDyn);
|
||||
sqlite3BtreeLeaveAll(db);
|
||||
assert( zErrDyn==0 || rc!=SQLITE_OK );
|
||||
}
|
||||
#ifdef SQLITE_USER_AUTHENTICATION
|
||||
if( rc==SQLITE_OK ){
|
||||
@@ -218,21 +244,23 @@ static void attachFunc(
|
||||
}
|
||||
#endif
|
||||
if( rc ){
|
||||
int iDb = db->nDb - 1;
|
||||
assert( iDb>=2 );
|
||||
if( db->aDb[iDb].pBt ){
|
||||
sqlite3BtreeClose(db->aDb[iDb].pBt);
|
||||
db->aDb[iDb].pBt = 0;
|
||||
db->aDb[iDb].pSchema = 0;
|
||||
}
|
||||
sqlite3ResetAllSchemasOfConnection(db);
|
||||
db->nDb = iDb;
|
||||
if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
|
||||
sqlite3OomFault(db);
|
||||
sqlite3DbFree(db, zErrDyn);
|
||||
zErrDyn = sqlite3MPrintf(db, "out of memory");
|
||||
}else if( zErrDyn==0 ){
|
||||
zErrDyn = sqlite3MPrintf(db, "unable to open database: %s", zFile);
|
||||
if( !REOPEN_AS_MEMDB(db) ){
|
||||
int iDb = db->nDb - 1;
|
||||
assert( iDb>=2 );
|
||||
if( db->aDb[iDb].pBt ){
|
||||
sqlite3BtreeClose(db->aDb[iDb].pBt);
|
||||
db->aDb[iDb].pBt = 0;
|
||||
db->aDb[iDb].pSchema = 0;
|
||||
}
|
||||
sqlite3ResetAllSchemasOfConnection(db);
|
||||
db->nDb = iDb;
|
||||
if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
|
||||
sqlite3OomFault(db);
|
||||
sqlite3DbFree(db, zErrDyn);
|
||||
zErrDyn = sqlite3MPrintf(db, "out of memory");
|
||||
}else if( zErrDyn==0 ){
|
||||
zErrDyn = sqlite3MPrintf(db, "unable to open database: %s", zFile);
|
||||
}
|
||||
}
|
||||
goto attach_error;
|
||||
}
|
||||
@@ -504,6 +532,14 @@ int sqlite3FixSelect(
|
||||
if( sqlite3FixExpr(pFix, pSelect->pLimit) ){
|
||||
return 1;
|
||||
}
|
||||
if( pSelect->pWith ){
|
||||
int i;
|
||||
for(i=0; i<pSelect->pWith->nCte; i++){
|
||||
if( sqlite3FixSelect(pFix, pSelect->pWith->a[i].pSelect) ){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
pSelect = pSelect->pPrior;
|
||||
}
|
||||
return 0;
|
||||
|
||||
+9
-1
@@ -4388,11 +4388,19 @@ int sqlite3BtreeCloseCursor(BtCursor *pCur){
|
||||
** Using this cache reduces the number of calls to btreeParseCell().
|
||||
*/
|
||||
#ifndef NDEBUG
|
||||
static int cellInfoEqual(CellInfo *a, CellInfo *b){
|
||||
if( a->nKey!=b->nKey ) return 0;
|
||||
if( a->pPayload!=b->pPayload ) return 0;
|
||||
if( a->nPayload!=b->nPayload ) return 0;
|
||||
if( a->nLocal!=b->nLocal ) return 0;
|
||||
if( a->nSize!=b->nSize ) return 0;
|
||||
return 1;
|
||||
}
|
||||
static void assertCellInfo(BtCursor *pCur){
|
||||
CellInfo info;
|
||||
memset(&info, 0, sizeof(info));
|
||||
btreeParseCell(pCur->pPage, pCur->ix, &info);
|
||||
assert( CORRUPT_DB || memcmp(&info, &pCur->info, sizeof(info))==0 );
|
||||
assert( CORRUPT_DB || cellInfoEqual(&info, &pCur->info) );
|
||||
}
|
||||
#else
|
||||
#define assertCellInfo(x)
|
||||
|
||||
+87
@@ -1732,6 +1732,34 @@ int sqlite3SelectWalkFail(Walker *pWalker, Select *NotUsed){
|
||||
return WRC_Abort;
|
||||
}
|
||||
|
||||
/*
|
||||
** If the input expression is an ID with the name "true" or "false"
|
||||
** then convert it into an TK_TRUEFALSE term. Return non-zero if
|
||||
** the conversion happened, and zero if the expression is unaltered.
|
||||
*/
|
||||
int sqlite3ExprIdToTrueFalse(Expr *pExpr){
|
||||
assert( pExpr->op==TK_ID || pExpr->op==TK_STRING );
|
||||
if( sqlite3StrICmp(pExpr->u.zToken, "true")==0
|
||||
|| sqlite3StrICmp(pExpr->u.zToken, "false")==0
|
||||
){
|
||||
pExpr->op = TK_TRUEFALSE;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** The argument must be a TK_TRUEFALSE Expr node. Return 1 if it is TRUE
|
||||
** and 0 if it is FALSE.
|
||||
*/
|
||||
int sqlite3ExprTruthValue(const Expr *pExpr){
|
||||
assert( pExpr->op==TK_TRUEFALSE );
|
||||
assert( sqlite3StrICmp(pExpr->u.zToken,"true")==0
|
||||
|| sqlite3StrICmp(pExpr->u.zToken,"false")==0 );
|
||||
return pExpr->u.zToken[4]==0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** These routines are Walker callbacks used to check expressions to
|
||||
** see if they are "constant" for some definition of constant. The
|
||||
@@ -1779,6 +1807,12 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
|
||||
return WRC_Abort;
|
||||
}
|
||||
case TK_ID:
|
||||
/* Convert "true" or "false" in a DEFAULT clause into the
|
||||
** appropriate TK_TRUEFALSE operator */
|
||||
if( sqlite3ExprIdToTrueFalse(pExpr) ){
|
||||
return WRC_Prune;
|
||||
}
|
||||
/* Fall thru */
|
||||
case TK_COLUMN:
|
||||
case TK_AGG_FUNCTION:
|
||||
case TK_AGG_COLUMN:
|
||||
@@ -3543,6 +3577,10 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
||||
codeInteger(pParse, pExpr, 0, target);
|
||||
return target;
|
||||
}
|
||||
case TK_TRUEFALSE: {
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, sqlite3ExprTruthValue(pExpr), target);
|
||||
return target;
|
||||
}
|
||||
#ifndef SQLITE_OMIT_FLOATING_POINT
|
||||
case TK_FLOAT: {
|
||||
assert( !ExprHasProperty(pExpr, EP_IntValue) );
|
||||
@@ -3698,6 +3736,18 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
||||
sqlite3VdbeAddOp2(v, op, r1, inReg);
|
||||
break;
|
||||
}
|
||||
case TK_TRUTH: {
|
||||
int isTrue; /* IS TRUE or IS NOT TRUE */
|
||||
int bNormal; /* IS TRUE or IS FALSE */
|
||||
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
|
||||
testcase( regFree1==0 );
|
||||
isTrue = sqlite3ExprTruthValue(pExpr->pRight);
|
||||
bNormal = pExpr->op2==TK_IS;
|
||||
testcase( isTrue && bNormal);
|
||||
testcase( !isTrue && bNormal);
|
||||
sqlite3VdbeAddOp4Int(v, OP_IsTrue, r1, inReg, !isTrue, isTrue ^ bNormal);
|
||||
break;
|
||||
}
|
||||
case TK_ISNULL:
|
||||
case TK_NOTNULL: {
|
||||
int addr;
|
||||
@@ -4473,6 +4523,23 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
||||
sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
|
||||
break;
|
||||
}
|
||||
case TK_TRUTH: {
|
||||
int isNot; /* IS NOT TRUE or IS NOT FALSE */
|
||||
int isTrue; /* IS TRUE or IS NOT TRUE */
|
||||
testcase( jumpIfNull==0 );
|
||||
isNot = pExpr->op2==TK_ISNOT;
|
||||
isTrue = sqlite3ExprTruthValue(pExpr->pRight);
|
||||
testcase( isTrue && isNot );
|
||||
testcase( !isTrue && isNot );
|
||||
if( isTrue ^ isNot ){
|
||||
sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest,
|
||||
isNot ? SQLITE_JUMPIFNULL : 0);
|
||||
}else{
|
||||
sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest,
|
||||
isNot ? SQLITE_JUMPIFNULL : 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TK_IS:
|
||||
case TK_ISNOT:
|
||||
testcase( op==TK_IS );
|
||||
@@ -4627,6 +4694,26 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
||||
sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
|
||||
break;
|
||||
}
|
||||
case TK_TRUTH: {
|
||||
int isNot; /* IS NOT TRUE or IS NOT FALSE */
|
||||
int isTrue; /* IS TRUE or IS NOT TRUE */
|
||||
testcase( jumpIfNull==0 );
|
||||
isNot = pExpr->op2==TK_ISNOT;
|
||||
isTrue = sqlite3ExprTruthValue(pExpr->pRight);
|
||||
testcase( isTrue && isNot );
|
||||
testcase( !isTrue && isNot );
|
||||
if( isTrue ^ isNot ){
|
||||
/* IS TRUE and IS NOT FALSE */
|
||||
sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest,
|
||||
isNot ? 0 : SQLITE_JUMPIFNULL);
|
||||
|
||||
}else{
|
||||
/* IS FALSE and IS NOT TRUE */
|
||||
sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest,
|
||||
isNot ? 0 : SQLITE_JUMPIFNULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TK_IS:
|
||||
case TK_ISNOT:
|
||||
testcase( pExpr->op==TK_IS );
|
||||
|
||||
@@ -258,6 +258,13 @@ const Token sqlite3IntTokens[] = {
|
||||
{ "1", 1 }
|
||||
};
|
||||
|
||||
#ifdef VDBE_PROFILE
|
||||
/*
|
||||
** The following performance counter can be used in place of
|
||||
** sqlite3Hwtime() for profiling. This is a no-op on standard builds.
|
||||
*/
|
||||
sqlite3_uint64 sqlite3NProfileCnt = 0;
|
||||
#endif
|
||||
|
||||
/*
|
||||
** The value of the "pending" byte must be 0x40000000 (1 byte past the
|
||||
|
||||
+6
-1
@@ -239,6 +239,11 @@ int sqlite3_initialize(void){
|
||||
sqlite3GlobalConfig.isPCacheInit = 1;
|
||||
rc = sqlite3OsInit();
|
||||
}
|
||||
#ifdef SQLITE_ENABLE_DESERIALIZE
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3MemdbInit();
|
||||
}
|
||||
#endif
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage,
|
||||
sqlite3GlobalConfig.szPage, sqlite3GlobalConfig.nPage);
|
||||
@@ -271,7 +276,7 @@ int sqlite3_initialize(void){
|
||||
#ifndef NDEBUG
|
||||
#ifndef SQLITE_OMIT_FLOATING_POINT
|
||||
/* This section of code's only "output" is via assert() statements. */
|
||||
if ( rc==SQLITE_OK ){
|
||||
if( rc==SQLITE_OK ){
|
||||
u64 x = (((u64)1)<<63)-1;
|
||||
double y;
|
||||
assert(sizeof(x)==8);
|
||||
|
||||
+589
@@ -0,0 +1,589 @@
|
||||
/*
|
||||
** 2016-09-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 file implements in-memory VFS. A database is held as a contiguous
|
||||
** block of memory.
|
||||
**
|
||||
** This file also implements interface sqlite3_serialize() and
|
||||
** sqlite3_deserialize().
|
||||
*/
|
||||
#ifdef SQLITE_ENABLE_DESERIALIZE
|
||||
#include "sqliteInt.h"
|
||||
|
||||
/*
|
||||
** Forward declaration of objects used by this utility
|
||||
*/
|
||||
typedef struct sqlite3_vfs MemVfs;
|
||||
typedef struct MemFile MemFile;
|
||||
|
||||
/* Access to a lower-level VFS that (might) implement dynamic loading,
|
||||
** access to randomness, etc.
|
||||
*/
|
||||
#define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData))
|
||||
|
||||
/* An open file */
|
||||
struct MemFile {
|
||||
sqlite3_file base; /* IO methods */
|
||||
sqlite3_int64 sz; /* Size of the file */
|
||||
sqlite3_int64 szMax; /* Space allocated to aData */
|
||||
unsigned char *aData; /* content of the file */
|
||||
int nMmap; /* Number of memory mapped pages */
|
||||
unsigned mFlags; /* Flags */
|
||||
int eLock; /* Most recent lock against this file */
|
||||
};
|
||||
|
||||
/*
|
||||
** Methods for MemFile
|
||||
*/
|
||||
static int memdbClose(sqlite3_file*);
|
||||
static int memdbRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
|
||||
static int memdbWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst);
|
||||
static int memdbTruncate(sqlite3_file*, sqlite3_int64 size);
|
||||
static int memdbSync(sqlite3_file*, int flags);
|
||||
static int memdbFileSize(sqlite3_file*, sqlite3_int64 *pSize);
|
||||
static int memdbLock(sqlite3_file*, int);
|
||||
/* static int memdbCheckReservedLock(sqlite3_file*, int *pResOut);// not used */
|
||||
static int memdbFileControl(sqlite3_file*, int op, void *pArg);
|
||||
/* static int memdbSectorSize(sqlite3_file*); // not used */
|
||||
static int memdbDeviceCharacteristics(sqlite3_file*);
|
||||
static int memdbFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp);
|
||||
static int memdbUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p);
|
||||
|
||||
/*
|
||||
** Methods for MemVfs
|
||||
*/
|
||||
static int memdbOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
|
||||
/* static int memdbDelete(sqlite3_vfs*, const char *zName, int syncDir); */
|
||||
static int memdbAccess(sqlite3_vfs*, const char *zName, int flags, int *);
|
||||
static int memdbFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut);
|
||||
static void *memdbDlOpen(sqlite3_vfs*, const char *zFilename);
|
||||
static void memdbDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
|
||||
static void (*memdbDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void);
|
||||
static void memdbDlClose(sqlite3_vfs*, void*);
|
||||
static int memdbRandomness(sqlite3_vfs*, int nByte, char *zOut);
|
||||
static int memdbSleep(sqlite3_vfs*, int microseconds);
|
||||
/* static int memdbCurrentTime(sqlite3_vfs*, double*); */
|
||||
static int memdbGetLastError(sqlite3_vfs*, int, char *);
|
||||
static int memdbCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*);
|
||||
|
||||
static sqlite3_vfs memdb_vfs = {
|
||||
2, /* iVersion */
|
||||
0, /* szOsFile (set when registered) */
|
||||
1024, /* mxPathname */
|
||||
0, /* pNext */
|
||||
"memdb", /* zName */
|
||||
0, /* pAppData (set when registered) */
|
||||
memdbOpen, /* xOpen */
|
||||
0, /* memdbDelete, */ /* xDelete */
|
||||
memdbAccess, /* xAccess */
|
||||
memdbFullPathname, /* xFullPathname */
|
||||
memdbDlOpen, /* xDlOpen */
|
||||
memdbDlError, /* xDlError */
|
||||
memdbDlSym, /* xDlSym */
|
||||
memdbDlClose, /* xDlClose */
|
||||
memdbRandomness, /* xRandomness */
|
||||
memdbSleep, /* xSleep */
|
||||
0, /* memdbCurrentTime, */ /* xCurrentTime */
|
||||
memdbGetLastError, /* xGetLastError */
|
||||
memdbCurrentTimeInt64 /* xCurrentTimeInt64 */
|
||||
};
|
||||
|
||||
static const sqlite3_io_methods memdb_io_methods = {
|
||||
3, /* iVersion */
|
||||
memdbClose, /* xClose */
|
||||
memdbRead, /* xRead */
|
||||
memdbWrite, /* xWrite */
|
||||
memdbTruncate, /* xTruncate */
|
||||
memdbSync, /* xSync */
|
||||
memdbFileSize, /* xFileSize */
|
||||
memdbLock, /* xLock */
|
||||
memdbLock, /* xUnlock - same as xLock in this case */
|
||||
0, /* memdbCheckReservedLock, */ /* xCheckReservedLock */
|
||||
memdbFileControl, /* xFileControl */
|
||||
0, /* memdbSectorSize,*/ /* xSectorSize */
|
||||
memdbDeviceCharacteristics, /* xDeviceCharacteristics */
|
||||
0, /* xShmMap */
|
||||
0, /* xShmLock */
|
||||
0, /* xShmBarrier */
|
||||
0, /* xShmUnmap */
|
||||
memdbFetch, /* xFetch */
|
||||
memdbUnfetch /* xUnfetch */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** Close an memdb-file.
|
||||
**
|
||||
** The pData pointer is owned by the application, so there is nothing
|
||||
** to free.
|
||||
*/
|
||||
static int memdbClose(sqlite3_file *pFile){
|
||||
MemFile *p = (MemFile *)pFile;
|
||||
if( p->mFlags & SQLITE_DESERIALIZE_FREEONCLOSE ) sqlite3_free(p->aData);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Read data from an memdb-file.
|
||||
*/
|
||||
static int memdbRead(
|
||||
sqlite3_file *pFile,
|
||||
void *zBuf,
|
||||
int iAmt,
|
||||
sqlite_int64 iOfst
|
||||
){
|
||||
MemFile *p = (MemFile *)pFile;
|
||||
if( iOfst+iAmt>p->sz ){
|
||||
memset(zBuf, 0, iAmt);
|
||||
if( iOfst<p->sz ) memcpy(zBuf, p->aData+iOfst, p->sz - iOfst);
|
||||
return SQLITE_IOERR_SHORT_READ;
|
||||
}
|
||||
memcpy(zBuf, p->aData+iOfst, iAmt);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Try to enlarge the memory allocation to hold at least sz bytes
|
||||
*/
|
||||
static int memdbEnlarge(MemFile *p, sqlite3_int64 newSz){
|
||||
unsigned char *pNew;
|
||||
if( (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)==0 || p->nMmap>0 ){
|
||||
return SQLITE_FULL;
|
||||
}
|
||||
pNew = sqlite3_realloc64(p->aData, newSz);
|
||||
if( pNew==0 ) return SQLITE_NOMEM;
|
||||
p->aData = pNew;
|
||||
p->szMax = newSz;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Write data to an memdb-file.
|
||||
*/
|
||||
static int memdbWrite(
|
||||
sqlite3_file *pFile,
|
||||
const void *z,
|
||||
int iAmt,
|
||||
sqlite_int64 iOfst
|
||||
){
|
||||
MemFile *p = (MemFile *)pFile;
|
||||
if( iOfst+iAmt>p->sz ){
|
||||
int rc;
|
||||
if( iOfst+iAmt>p->szMax
|
||||
&& (rc = memdbEnlarge(p, (iOfst+iAmt)*2))!=SQLITE_OK
|
||||
){
|
||||
return rc;
|
||||
}
|
||||
if( iOfst>p->sz ) memset(p->aData+p->sz, 0, iOfst-p->sz);
|
||||
p->sz = iOfst+iAmt;
|
||||
}
|
||||
memcpy(p->aData+iOfst, z, iAmt);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Truncate an memdb-file.
|
||||
**
|
||||
** In rollback mode (which is always the case for memdb, as it does not
|
||||
** support WAL mode) the truncate() method is only used to reduce
|
||||
** the size of a file, never to increase the size.
|
||||
*/
|
||||
static int memdbTruncate(sqlite3_file *pFile, sqlite_int64 size){
|
||||
MemFile *p = (MemFile *)pFile;
|
||||
if( NEVER(size>p->sz) ) return SQLITE_FULL;
|
||||
p->sz = size;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Sync an memdb-file.
|
||||
*/
|
||||
static int memdbSync(sqlite3_file *pFile, int flags){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the current file-size of an memdb-file.
|
||||
*/
|
||||
static int memdbFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
|
||||
MemFile *p = (MemFile *)pFile;
|
||||
*pSize = p->sz;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Lock an memdb-file.
|
||||
*/
|
||||
static int memdbLock(sqlite3_file *pFile, int eLock){
|
||||
MemFile *p = (MemFile *)pFile;
|
||||
p->eLock = eLock;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
#if 0 /* Never used because memdbAccess() always returns false */
|
||||
/*
|
||||
** Check if another file-handle holds a RESERVED lock on an memdb-file.
|
||||
*/
|
||||
static int memdbCheckReservedLock(sqlite3_file *pFile, int *pResOut){
|
||||
*pResOut = 0;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** File control method. For custom operations on an memdb-file.
|
||||
*/
|
||||
static int memdbFileControl(sqlite3_file *pFile, int op, void *pArg){
|
||||
MemFile *p = (MemFile *)pFile;
|
||||
int rc = SQLITE_NOTFOUND;
|
||||
if( op==SQLITE_FCNTL_VFSNAME ){
|
||||
*(char**)pArg = sqlite3_mprintf("memdb(%p,%lld)", p->aData, p->sz);
|
||||
rc = SQLITE_OK;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
#if 0 /* Not used because of SQLITE_IOCAP_POWERSAFE_OVERWRITE */
|
||||
/*
|
||||
** Return the sector-size in bytes for an memdb-file.
|
||||
*/
|
||||
static int memdbSectorSize(sqlite3_file *pFile){
|
||||
return 1024;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Return the device characteristic flags supported by an memdb-file.
|
||||
*/
|
||||
static int memdbDeviceCharacteristics(sqlite3_file *pFile){
|
||||
return SQLITE_IOCAP_ATOMIC |
|
||||
SQLITE_IOCAP_POWERSAFE_OVERWRITE |
|
||||
SQLITE_IOCAP_SAFE_APPEND |
|
||||
SQLITE_IOCAP_SEQUENTIAL;
|
||||
}
|
||||
|
||||
/* Fetch a page of a memory-mapped file */
|
||||
static int memdbFetch(
|
||||
sqlite3_file *pFile,
|
||||
sqlite3_int64 iOfst,
|
||||
int iAmt,
|
||||
void **pp
|
||||
){
|
||||
MemFile *p = (MemFile *)pFile;
|
||||
p->nMmap++;
|
||||
*pp = (void*)(p->aData + iOfst);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/* Release a memory-mapped page */
|
||||
static int memdbUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
|
||||
MemFile *p = (MemFile *)pFile;
|
||||
p->nMmap--;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Open an mem file handle.
|
||||
*/
|
||||
static int memdbOpen(
|
||||
sqlite3_vfs *pVfs,
|
||||
const char *zName,
|
||||
sqlite3_file *pFile,
|
||||
int flags,
|
||||
int *pOutFlags
|
||||
){
|
||||
MemFile *p = (MemFile*)pFile;
|
||||
if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){
|
||||
return ORIGVFS(pVfs)->xOpen(ORIGVFS(pVfs), zName, pFile, flags, pOutFlags);
|
||||
}
|
||||
memset(p, 0, sizeof(*p));
|
||||
p->mFlags = SQLITE_DESERIALIZE_RESIZEABLE | SQLITE_DESERIALIZE_FREEONCLOSE;
|
||||
assert( pOutFlags!=0 ); /* True because flags==SQLITE_OPEN_MAIN_DB */
|
||||
*pOutFlags = flags | SQLITE_OPEN_MEMORY;
|
||||
p->base.pMethods = &memdb_io_methods;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
#if 0 /* Only used to delete rollback journals, master journals, and WAL
|
||||
** files, none of which exist in memdb. So this routine is never used */
|
||||
/*
|
||||
** Delete the file located at zPath. If the dirSync argument is true,
|
||||
** ensure the file-system modifications are synced to disk before
|
||||
** returning.
|
||||
*/
|
||||
static int memdbDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
|
||||
return SQLITE_IOERR_DELETE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Test for access permissions. Return true if the requested permission
|
||||
** is available, or false otherwise.
|
||||
**
|
||||
** With memdb, no files ever exist on disk. So always return false.
|
||||
*/
|
||||
static int memdbAccess(
|
||||
sqlite3_vfs *pVfs,
|
||||
const char *zPath,
|
||||
int flags,
|
||||
int *pResOut
|
||||
){
|
||||
*pResOut = 0;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Populate buffer zOut with the full canonical pathname corresponding
|
||||
** to the pathname in zPath. zOut is guaranteed to point to a buffer
|
||||
** of at least (INST_MAX_PATHNAME+1) bytes.
|
||||
*/
|
||||
static int memdbFullPathname(
|
||||
sqlite3_vfs *pVfs,
|
||||
const char *zPath,
|
||||
int nOut,
|
||||
char *zOut
|
||||
){
|
||||
sqlite3_snprintf(nOut, zOut, "%s", zPath);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Open the dynamic library located at zPath and return a handle.
|
||||
*/
|
||||
static void *memdbDlOpen(sqlite3_vfs *pVfs, const char *zPath){
|
||||
return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath);
|
||||
}
|
||||
|
||||
/*
|
||||
** Populate the buffer zErrMsg (size nByte bytes) with a human readable
|
||||
** utf-8 string describing the most recent error encountered associated
|
||||
** with dynamic libraries.
|
||||
*/
|
||||
static void memdbDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
|
||||
ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
|
||||
*/
|
||||
static void (*memdbDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){
|
||||
return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym);
|
||||
}
|
||||
|
||||
/*
|
||||
** Close the dynamic library handle pHandle.
|
||||
*/
|
||||
static void memdbDlClose(sqlite3_vfs *pVfs, void *pHandle){
|
||||
ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle);
|
||||
}
|
||||
|
||||
/*
|
||||
** Populate the buffer pointed to by zBufOut with nByte bytes of
|
||||
** random data.
|
||||
*/
|
||||
static int memdbRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
|
||||
return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut);
|
||||
}
|
||||
|
||||
/*
|
||||
** Sleep for nMicro microseconds. Return the number of microseconds
|
||||
** actually slept.
|
||||
*/
|
||||
static int memdbSleep(sqlite3_vfs *pVfs, int nMicro){
|
||||
return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro);
|
||||
}
|
||||
|
||||
#if 0 /* Never used. Modern cores only call xCurrentTimeInt64() */
|
||||
/*
|
||||
** Return the current time as a Julian Day number in *pTimeOut.
|
||||
*/
|
||||
static int memdbCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
|
||||
return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int memdbGetLastError(sqlite3_vfs *pVfs, int a, char *b){
|
||||
return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b);
|
||||
}
|
||||
static int memdbCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){
|
||||
return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p);
|
||||
}
|
||||
|
||||
/*
|
||||
** Translate a database connection pointer and schema name into a
|
||||
** MemFile pointer.
|
||||
*/
|
||||
static MemFile *memdbFromDbSchema(sqlite3 *db, const char *zSchema){
|
||||
MemFile *p = 0;
|
||||
int rc = sqlite3_file_control(db, zSchema, SQLITE_FCNTL_FILE_POINTER, &p);
|
||||
if( rc ) return 0;
|
||||
if( p->base.pMethods!=&memdb_io_methods ) return 0;
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the serialization of a database
|
||||
*/
|
||||
unsigned char *sqlite3_serialize(
|
||||
sqlite3 *db, /* The database connection */
|
||||
const char *zSchema, /* Which database within the connection */
|
||||
sqlite3_int64 *piSize, /* Write size here, if not NULL */
|
||||
unsigned int mFlags /* Maybe SQLITE_SERIALIZE_NOCOPY */
|
||||
){
|
||||
MemFile *p;
|
||||
int iDb;
|
||||
Btree *pBt;
|
||||
sqlite3_int64 sz;
|
||||
int szPage = 0;
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
unsigned char *pOut;
|
||||
char *zSql;
|
||||
int rc;
|
||||
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !sqlite3SafetyCheckOk(db) ){
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if( zSchema==0 ) zSchema = db->aDb[0].zDbSName;
|
||||
p = memdbFromDbSchema(db, zSchema);
|
||||
iDb = sqlite3FindDbName(db, zSchema);
|
||||
if( piSize ) *piSize = -1;
|
||||
if( iDb<0 ) return 0;
|
||||
if( p ){
|
||||
if( piSize ) *piSize = p->sz;
|
||||
if( mFlags & SQLITE_SERIALIZE_NOCOPY ){
|
||||
pOut = p->aData;
|
||||
}else{
|
||||
pOut = sqlite3_malloc64( p->sz );
|
||||
if( pOut ) memcpy(pOut, p->aData, p->sz);
|
||||
}
|
||||
return pOut;
|
||||
}
|
||||
pBt = db->aDb[iDb].pBt;
|
||||
if( pBt==0 ) return 0;
|
||||
szPage = sqlite3BtreeGetPageSize(pBt);
|
||||
zSql = sqlite3_mprintf("PRAGMA \"%w\".page_count", zSchema);
|
||||
rc = zSql ? sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0) : SQLITE_NOMEM;
|
||||
sqlite3_free(zSql);
|
||||
if( rc ) return 0;
|
||||
rc = sqlite3_step(pStmt);
|
||||
if( rc!=SQLITE_ROW ){
|
||||
pOut = 0;
|
||||
}else{
|
||||
sz = sqlite3_column_int64(pStmt, 0)*szPage;
|
||||
if( piSize ) *piSize = sz;
|
||||
if( mFlags & SQLITE_SERIALIZE_NOCOPY ){
|
||||
pOut = 0;
|
||||
}else{
|
||||
pOut = sqlite3_malloc64( sz );
|
||||
if( pOut ){
|
||||
int nPage = sqlite3_column_int(pStmt, 0);
|
||||
Pager *pPager = sqlite3BtreePager(pBt);
|
||||
int pgno;
|
||||
for(pgno=1; pgno<=nPage; pgno++){
|
||||
DbPage *pPage = 0;
|
||||
unsigned char *pTo = pOut + szPage*(sqlite3_int64)(pgno-1);
|
||||
rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pPage, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
memcpy(pTo, sqlite3PagerGetData(pPage), szPage);
|
||||
}else{
|
||||
memset(pTo, 0, szPage);
|
||||
}
|
||||
sqlite3PagerUnref(pPage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sqlite3_finalize(pStmt);
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/* Convert zSchema to a MemDB and initialize its content.
|
||||
*/
|
||||
int sqlite3_deserialize(
|
||||
sqlite3 *db, /* The database connection */
|
||||
const char *zSchema, /* Which DB to reopen with the deserialization */
|
||||
unsigned char *pData, /* The serialized database content */
|
||||
sqlite3_int64 szDb, /* Number bytes in the deserialization */
|
||||
sqlite3_int64 szBuf, /* Total size of buffer pData[] */
|
||||
unsigned mFlags /* Zero or more SQLITE_DESERIALIZE_* flags */
|
||||
){
|
||||
MemFile *p;
|
||||
char *zSql;
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
int rc;
|
||||
int iDb;
|
||||
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !sqlite3SafetyCheckOk(db) ){
|
||||
return SQLITE_MISUSE_BKPT;
|
||||
}
|
||||
if( szDb<0 ) return SQLITE_MISUSE_BKPT;
|
||||
if( szBuf<0 ) return SQLITE_MISUSE_BKPT;
|
||||
#endif
|
||||
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
if( zSchema==0 ) zSchema = db->aDb[0].zDbSName;
|
||||
iDb = sqlite3FindDbName(db, zSchema);
|
||||
if( iDb<0 ){
|
||||
rc = SQLITE_ERROR;
|
||||
goto end_deserialize;
|
||||
}
|
||||
zSql = sqlite3_mprintf("ATTACH x AS %Q", zSchema);
|
||||
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
|
||||
sqlite3_free(zSql);
|
||||
if( rc ) goto end_deserialize;
|
||||
db->init.iDb = (u8)iDb;
|
||||
db->init.reopenMemdb = 1;
|
||||
rc = sqlite3_step(pStmt);
|
||||
db->init.reopenMemdb = 0;
|
||||
if( rc!=SQLITE_DONE ){
|
||||
rc = SQLITE_ERROR;
|
||||
goto end_deserialize;
|
||||
}
|
||||
p = memdbFromDbSchema(db, zSchema);
|
||||
if( p==0 ){
|
||||
rc = SQLITE_ERROR;
|
||||
}else{
|
||||
p->aData = pData;
|
||||
p->sz = szDb;
|
||||
p->szMax = szBuf;
|
||||
p->mFlags = mFlags;
|
||||
rc = SQLITE_OK;
|
||||
}
|
||||
|
||||
end_deserialize:
|
||||
sqlite3_finalize(pStmt);
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** This routine is called when the extension is loaded.
|
||||
** Register the new VFS.
|
||||
*/
|
||||
int sqlite3MemdbInit(void){
|
||||
sqlite3_vfs *pLower = sqlite3_vfs_find(0);
|
||||
int sz = pLower->szOsFile;
|
||||
memdb_vfs.pAppData = pLower;
|
||||
/* In all known configurations of SQLite, the size of a default
|
||||
** sqlite3_file is greater than the size of a memdb sqlite3_file.
|
||||
** Should that ever change, remove the following NEVER() */
|
||||
if( NEVER(sz<sizeof(MemFile)) ) sz = sizeof(MemFile);
|
||||
memdb_vfs.szOsFile = sz;
|
||||
return sqlite3_vfs_register(&memdb_vfs, 0);
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_DESERIALIZE */
|
||||
+23
-16
@@ -50,11 +50,12 @@ struct sqlite3_mutex {
|
||||
#endif
|
||||
};
|
||||
#if SQLITE_MUTEX_NREF
|
||||
#define SQLITE3_MUTEX_INITIALIZER {PTHREAD_MUTEX_INITIALIZER,0,0,(pthread_t)0,0}
|
||||
# define SQLITE3_MUTEX_INITIALIZER(id) \
|
||||
{PTHREAD_MUTEX_INITIALIZER,id,0,(pthread_t)0,0}
|
||||
#elif defined(SQLITE_ENABLE_API_ARMOR)
|
||||
#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0 }
|
||||
# define SQLITE3_MUTEX_INITIALIZER(id) { PTHREAD_MUTEX_INITIALIZER, id }
|
||||
#else
|
||||
#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER }
|
||||
#define SQLITE3_MUTEX_INITIALIZER(id) { PTHREAD_MUTEX_INITIALIZER }
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -151,18 +152,18 @@ static int pthreadMutexEnd(void){ return SQLITE_OK; }
|
||||
*/
|
||||
static sqlite3_mutex *pthreadMutexAlloc(int iType){
|
||||
static sqlite3_mutex staticMutexes[] = {
|
||||
SQLITE3_MUTEX_INITIALIZER,
|
||||
SQLITE3_MUTEX_INITIALIZER,
|
||||
SQLITE3_MUTEX_INITIALIZER,
|
||||
SQLITE3_MUTEX_INITIALIZER,
|
||||
SQLITE3_MUTEX_INITIALIZER,
|
||||
SQLITE3_MUTEX_INITIALIZER,
|
||||
SQLITE3_MUTEX_INITIALIZER,
|
||||
SQLITE3_MUTEX_INITIALIZER,
|
||||
SQLITE3_MUTEX_INITIALIZER,
|
||||
SQLITE3_MUTEX_INITIALIZER,
|
||||
SQLITE3_MUTEX_INITIALIZER,
|
||||
SQLITE3_MUTEX_INITIALIZER
|
||||
SQLITE3_MUTEX_INITIALIZER(2),
|
||||
SQLITE3_MUTEX_INITIALIZER(3),
|
||||
SQLITE3_MUTEX_INITIALIZER(4),
|
||||
SQLITE3_MUTEX_INITIALIZER(5),
|
||||
SQLITE3_MUTEX_INITIALIZER(6),
|
||||
SQLITE3_MUTEX_INITIALIZER(7),
|
||||
SQLITE3_MUTEX_INITIALIZER(8),
|
||||
SQLITE3_MUTEX_INITIALIZER(9),
|
||||
SQLITE3_MUTEX_INITIALIZER(10),
|
||||
SQLITE3_MUTEX_INITIALIZER(11),
|
||||
SQLITE3_MUTEX_INITIALIZER(12),
|
||||
SQLITE3_MUTEX_INITIALIZER(13)
|
||||
};
|
||||
sqlite3_mutex *p;
|
||||
switch( iType ){
|
||||
@@ -180,6 +181,9 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){
|
||||
pthread_mutexattr_settype(&recursiveAttr, PTHREAD_MUTEX_RECURSIVE);
|
||||
pthread_mutex_init(&p->mutex, &recursiveAttr);
|
||||
pthread_mutexattr_destroy(&recursiveAttr);
|
||||
#endif
|
||||
#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR)
|
||||
p->id = SQLITE_MUTEX_RECURSIVE;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
@@ -188,6 +192,9 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){
|
||||
p = sqlite3MallocZero( sizeof(*p) );
|
||||
if( p ){
|
||||
pthread_mutex_init(&p->mutex, 0);
|
||||
#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR)
|
||||
p->id = SQLITE_MUTEX_FAST;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -203,7 +210,7 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){
|
||||
}
|
||||
}
|
||||
#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR)
|
||||
if( p ) p->id = iType;
|
||||
assert( p==0 || p->id==iType );
|
||||
#endif
|
||||
return p;
|
||||
}
|
||||
|
||||
+17
-17
@@ -40,7 +40,7 @@ struct sqlite3_mutex {
|
||||
#ifdef SQLITE_DEBUG
|
||||
volatile int nRef; /* Number of enterances */
|
||||
volatile DWORD owner; /* Thread holding this mutex */
|
||||
volatile int trace; /* True to trace changes */
|
||||
volatile LONG trace; /* True to trace changes */
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -52,10 +52,10 @@ struct sqlite3_mutex {
|
||||
#define SQLITE_W32_MUTEX_INITIALIZER { 0 }
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0, \
|
||||
#define SQLITE3_MUTEX_INITIALIZER(id) { SQLITE_W32_MUTEX_INITIALIZER, id, \
|
||||
0L, (DWORD)0, 0 }
|
||||
#else
|
||||
#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0 }
|
||||
#define SQLITE3_MUTEX_INITIALIZER(id) { SQLITE_W32_MUTEX_INITIALIZER, id }
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
@@ -98,18 +98,18 @@ void sqlite3MemoryBarrier(void){
|
||||
** Initialize and deinitialize the mutex subsystem.
|
||||
*/
|
||||
static sqlite3_mutex winMutex_staticMutexes[] = {
|
||||
SQLITE3_MUTEX_INITIALIZER,
|
||||
SQLITE3_MUTEX_INITIALIZER,
|
||||
SQLITE3_MUTEX_INITIALIZER,
|
||||
SQLITE3_MUTEX_INITIALIZER,
|
||||
SQLITE3_MUTEX_INITIALIZER,
|
||||
SQLITE3_MUTEX_INITIALIZER,
|
||||
SQLITE3_MUTEX_INITIALIZER,
|
||||
SQLITE3_MUTEX_INITIALIZER,
|
||||
SQLITE3_MUTEX_INITIALIZER,
|
||||
SQLITE3_MUTEX_INITIALIZER,
|
||||
SQLITE3_MUTEX_INITIALIZER,
|
||||
SQLITE3_MUTEX_INITIALIZER
|
||||
SQLITE3_MUTEX_INITIALIZER(2),
|
||||
SQLITE3_MUTEX_INITIALIZER(3),
|
||||
SQLITE3_MUTEX_INITIALIZER(4),
|
||||
SQLITE3_MUTEX_INITIALIZER(5),
|
||||
SQLITE3_MUTEX_INITIALIZER(6),
|
||||
SQLITE3_MUTEX_INITIALIZER(7),
|
||||
SQLITE3_MUTEX_INITIALIZER(8),
|
||||
SQLITE3_MUTEX_INITIALIZER(9),
|
||||
SQLITE3_MUTEX_INITIALIZER(10),
|
||||
SQLITE3_MUTEX_INITIALIZER(11),
|
||||
SQLITE3_MUTEX_INITIALIZER(12),
|
||||
SQLITE3_MUTEX_INITIALIZER(13)
|
||||
};
|
||||
|
||||
static int winMutex_isInit = 0;
|
||||
@@ -239,15 +239,15 @@ static sqlite3_mutex *winMutexAlloc(int iType){
|
||||
}
|
||||
#endif
|
||||
p = &winMutex_staticMutexes[iType-2];
|
||||
p->id = iType;
|
||||
#ifdef SQLITE_DEBUG
|
||||
#ifdef SQLITE_WIN32_MUTEX_TRACE_STATIC
|
||||
p->trace = 1;
|
||||
InterlockedCompareExchange(&p->trace, 1, 0);
|
||||
#endif
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert( p==0 || p->id==iType );
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
+5
-32
@@ -209,10 +209,6 @@ struct unixFile {
|
||||
unsigned char eFileLock; /* The type of lock held on this fd */
|
||||
unsigned short int ctrlFlags; /* Behavioral bits. UNIXFILE_* flags */
|
||||
int lastErrno; /* The unix errno from last I/O error */
|
||||
#ifdef SQLITE_WRITE_QUEUE_FLUSH_HACK
|
||||
unsigned int nUnsyncWrite; /* Bytes written since last fsync() */
|
||||
unsigned int nUnsyncLimit; /* Maximum bytes written before fsync() */
|
||||
#endif
|
||||
void *lockingContext; /* Locking style specific state */
|
||||
UnixUnusedFd *pPreallocatedUnused; /* Pre-allocated UnixUnusedFd */
|
||||
const char *zPath; /* Name of the file */
|
||||
@@ -472,7 +468,11 @@ static struct unix_syscall {
|
||||
#endif
|
||||
#define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)
|
||||
|
||||
#if defined(HAVE_FCHOWN)
|
||||
{ "geteuid", (sqlite3_syscall_ptr)geteuid, 0 },
|
||||
#else
|
||||
{ "geteuid", (sqlite3_syscall_ptr)0, 0 },
|
||||
#endif
|
||||
#define osGeteuid ((uid_t(*)(void))aSyscall[21].pCurrent)
|
||||
|
||||
#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
|
||||
@@ -3372,18 +3372,7 @@ static int unixWrite(
|
||||
}
|
||||
#endif
|
||||
|
||||
while( 1 ){
|
||||
wrote = seekAndWrite(pFile, offset, pBuf, amt);
|
||||
#ifdef SQLITE_WRITE_QUEUE_FLUSH_HACK
|
||||
if( pFile->nUnsyncLimit ){
|
||||
pFile->nUnsyncWrite += wrote;
|
||||
if( pFile->nUnsyncWrite>=pFile->nUnsyncLimit ){
|
||||
fdatasync(pFile->h);
|
||||
pFile->nUnsyncWrite = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if( wrote>=amt || wrote<=0 ) break;
|
||||
while( (wrote = seekAndWrite(pFile, offset, pBuf, amt))<amt && wrote>0 ){
|
||||
amt -= wrote;
|
||||
offset += wrote;
|
||||
pBuf = &((char*)pBuf)[wrote];
|
||||
@@ -3612,9 +3601,6 @@ static int unixSync(sqlite3_file *id, int flags){
|
||||
assert( pFile );
|
||||
OSTRACE(("SYNC %-3d\n", pFile->h));
|
||||
rc = full_fsync(pFile->h, isFullsync, isDataOnly);
|
||||
#ifdef SQLITE_WRITE_QUEUE_FLUSH_HACK
|
||||
pFile->nUnsyncWrite = 0;
|
||||
#endif
|
||||
SimulateIOError( rc=1 );
|
||||
if( rc ){
|
||||
storeLastErrno(pFile, errno);
|
||||
@@ -3836,17 +3822,6 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
|
||||
}
|
||||
#endif /* __linux__ && SQLITE_ENABLE_BATCH_ATOMIC_WRITE */
|
||||
|
||||
#ifdef SQLITE_WRITE_QUEUE_FLUSH_HACK
|
||||
case SQLITE_FCNTL_PRAGMA: {
|
||||
char **azParam = (char**)pArg;
|
||||
if( sqlite3_stricmp(azParam[1],"fsync_interval")==0 ){
|
||||
pFile->nUnsyncLimit = atoi(azParam[2]);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
return SQLITE_NOTFOUND;
|
||||
}
|
||||
#endif
|
||||
|
||||
case SQLITE_FCNTL_LOCKSTATE: {
|
||||
*(int*)pArg = pFile->eFileLock;
|
||||
return SQLITE_OK;
|
||||
@@ -4205,12 +4180,10 @@ static int unixShmSystemLock(
|
||||
|
||||
if( pShmNode->h>=0 ){
|
||||
/* Initialize the locking parameters */
|
||||
memset(&f, 0, sizeof(f));
|
||||
f.l_type = lockType;
|
||||
f.l_whence = SEEK_SET;
|
||||
f.l_start = ofst;
|
||||
f.l_len = n;
|
||||
|
||||
rc = osFcntl(pShmNode->h, F_SETLK, &f);
|
||||
rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
|
||||
}
|
||||
|
||||
+25
-8
@@ -699,7 +699,7 @@ struct Pager {
|
||||
char *zJournal; /* Name of the journal file */
|
||||
int (*xBusyHandler)(void*); /* Function to call when busy */
|
||||
void *pBusyHandlerArg; /* Context argument for xBusyHandler */
|
||||
int aStat[3]; /* Total cache hits, misses and writes */
|
||||
int aStat[4]; /* Total cache hits, misses, writes, spills */
|
||||
#ifdef SQLITE_TEST
|
||||
int nRead; /* Database pages read */
|
||||
#endif
|
||||
@@ -727,6 +727,7 @@ struct Pager {
|
||||
#define PAGER_STAT_HIT 0
|
||||
#define PAGER_STAT_MISS 1
|
||||
#define PAGER_STAT_WRITE 2
|
||||
#define PAGER_STAT_SPILL 3
|
||||
|
||||
/*
|
||||
** The following global variables hold counters used for
|
||||
@@ -4618,6 +4619,7 @@ static int pagerStress(void *p, PgHdr *pPg){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
pPager->aStat[PAGER_STAT_SPILL]++;
|
||||
pPg->pDirty = 0;
|
||||
if( pagerUseWal(pPager) ){
|
||||
/* Write a single frame for this page to the log. */
|
||||
@@ -4723,6 +4725,11 @@ int sqlite3PagerOpen(
|
||||
int rc = SQLITE_OK; /* Return code */
|
||||
int tempFile = 0; /* True for temp files (incl. in-memory files) */
|
||||
int memDb = 0; /* True if this is an in-memory file */
|
||||
#ifdef SQLITE_ENABLE_DESERIALIZE
|
||||
int memJM = 0; /* Memory journal mode */
|
||||
#else
|
||||
# define memJM 0
|
||||
#endif
|
||||
int readOnly = 0; /* True if this is a read-only file */
|
||||
int journalFileSize; /* Bytes to allocate for each journal fd */
|
||||
char *zPathname = 0; /* Full path to database file */
|
||||
@@ -4850,7 +4857,10 @@ int sqlite3PagerOpen(
|
||||
int fout = 0; /* VFS flags returned by xOpen() */
|
||||
rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout);
|
||||
assert( !memDb );
|
||||
readOnly = (fout&SQLITE_OPEN_READONLY);
|
||||
#ifdef SQLITE_ENABLE_DESERIALIZE
|
||||
memJM = (fout&SQLITE_OPEN_MEMORY)!=0;
|
||||
#endif
|
||||
readOnly = (fout&SQLITE_OPEN_READONLY)!=0;
|
||||
|
||||
/* If the file was successfully opened for read/write access,
|
||||
** choose a default page size in case we have to create the
|
||||
@@ -4981,7 +4991,7 @@ act_like_temp_file:
|
||||
setSectorSize(pPager);
|
||||
if( !useJournal ){
|
||||
pPager->journalMode = PAGER_JOURNALMODE_OFF;
|
||||
}else if( memDb ){
|
||||
}else if( memDb || memJM ){
|
||||
pPager->journalMode = PAGER_JOURNALMODE_MEMORY;
|
||||
}
|
||||
/* pPager->xBusyHandler = 0; */
|
||||
@@ -6730,8 +6740,12 @@ int *sqlite3PagerStats(Pager *pPager){
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Parameter eStat must be either SQLITE_DBSTATUS_CACHE_HIT or
|
||||
** SQLITE_DBSTATUS_CACHE_MISS. Before returning, *pnVal is incremented by the
|
||||
** Parameter eStat must be one of SQLITE_DBSTATUS_CACHE_HIT, _MISS, _WRITE,
|
||||
** or _WRITE+1. The SQLITE_DBSTATUS_CACHE_WRITE+1 case is a translation
|
||||
** of SQLITE_DBSTATUS_CACHE_SPILL. The _SPILL case is not contiguous because
|
||||
** it was added later.
|
||||
**
|
||||
** Before returning, *pnVal is incremented by the
|
||||
** current cache hit or miss count, according to the value of eStat. If the
|
||||
** reset parameter is non-zero, the cache hit or miss count is zeroed before
|
||||
** returning.
|
||||
@@ -6741,15 +6755,18 @@ void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, int *pnVal){
|
||||
assert( eStat==SQLITE_DBSTATUS_CACHE_HIT
|
||||
|| eStat==SQLITE_DBSTATUS_CACHE_MISS
|
||||
|| eStat==SQLITE_DBSTATUS_CACHE_WRITE
|
||||
|| eStat==SQLITE_DBSTATUS_CACHE_WRITE+1
|
||||
);
|
||||
|
||||
assert( SQLITE_DBSTATUS_CACHE_HIT+1==SQLITE_DBSTATUS_CACHE_MISS );
|
||||
assert( SQLITE_DBSTATUS_CACHE_HIT+2==SQLITE_DBSTATUS_CACHE_WRITE );
|
||||
assert( PAGER_STAT_HIT==0 && PAGER_STAT_MISS==1 && PAGER_STAT_WRITE==2 );
|
||||
assert( PAGER_STAT_HIT==0 && PAGER_STAT_MISS==1
|
||||
&& PAGER_STAT_WRITE==2 && PAGER_STAT_SPILL==3 );
|
||||
|
||||
*pnVal += pPager->aStat[eStat - SQLITE_DBSTATUS_CACHE_HIT];
|
||||
eStat -= SQLITE_DBSTATUS_CACHE_HIT;
|
||||
*pnVal += pPager->aStat[eStat];
|
||||
if( reset ){
|
||||
pPager->aStat[eStat - SQLITE_DBSTATUS_CACHE_HIT] = 0;
|
||||
pPager->aStat[eStat] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -313,6 +313,10 @@ ccons ::= DEFAULT MINUS(A) term(X) scanpt(Z). {
|
||||
}
|
||||
ccons ::= DEFAULT scanpt id(X). {
|
||||
Expr *p = tokenExpr(pParse, TK_STRING, X);
|
||||
if( p ){
|
||||
sqlite3ExprIdToTrueFalse(p);
|
||||
testcase( p->op==TK_TRUEFALSE && sqlite3ExprTruthValue(p) );
|
||||
}
|
||||
sqlite3AddDefaultValue(pParse,p,X.z,X.z+X.n);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -431,7 +431,7 @@ int sqlite3PcacheFetchStress(
|
||||
sqlite3_log(SQLITE_FULL,
|
||||
"spill page %d making room for %d - cache used: %d/%d",
|
||||
pPg->pgno, pgno,
|
||||
sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache),
|
||||
sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache),
|
||||
numberOfCachePages(pCache));
|
||||
#endif
|
||||
pcacheTrace(("%p.SPILL %d\n",pCache,pPg->pgno));
|
||||
|
||||
+86
-15
@@ -206,6 +206,11 @@ void sqlite3VXPrintf(
|
||||
PrintfArguments *pArgList = 0; /* Arguments for SQLITE_PRINTF_SQLFUNC */
|
||||
char buf[etBUFSIZE]; /* Conversion buffer */
|
||||
|
||||
/* pAccum never starts out with an empty buffer that was obtained from
|
||||
** malloc(). This precondition is required by the mprintf("%z...")
|
||||
** optimization. */
|
||||
assert( pAccum->nChar>0 || (pAccum->printfFlags&SQLITE_PRINTF_MALLOCED)==0 );
|
||||
|
||||
bufpt = 0;
|
||||
if( (pAccum->printfFlags & SQLITE_PRINTF_SQLFUNC)!=0 ){
|
||||
pArgList = va_arg(ap, PrintfArguments*);
|
||||
@@ -624,9 +629,38 @@ void sqlite3VXPrintf(
|
||||
case etCHARX:
|
||||
if( bArgList ){
|
||||
bufpt = getTextArg(pArgList);
|
||||
c = bufpt ? bufpt[0] : 0;
|
||||
length = 1;
|
||||
if( bufpt ){
|
||||
buf[0] = c = *(bufpt++);
|
||||
if( (c&0xc0)==0xc0 ){
|
||||
while( length<4 && (bufpt[0]&0xc0)==0x80 ){
|
||||
buf[length++] = *(bufpt++);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
buf[0] = 0;
|
||||
}
|
||||
}else{
|
||||
c = va_arg(ap,int);
|
||||
unsigned int ch = va_arg(ap,unsigned int);
|
||||
if( ch<0x00080 ){
|
||||
buf[0] = ch & 0xff;
|
||||
length = 1;
|
||||
}else if( ch<0x00800 ){
|
||||
buf[0] = 0xc0 + (u8)((ch>>6)&0x1f);
|
||||
buf[1] = 0x80 + (u8)(ch & 0x3f);
|
||||
length = 2;
|
||||
}else if( ch<0x10000 ){
|
||||
buf[0] = 0xe0 + (u8)((ch>>12)&0x0f);
|
||||
buf[1] = 0x80 + (u8)((ch>>6) & 0x3f);
|
||||
buf[2] = 0x80 + (u8)(ch & 0x3f);
|
||||
length = 3;
|
||||
}else{
|
||||
buf[0] = 0xf0 + (u8)((ch>>18) & 0x07);
|
||||
buf[1] = 0x80 + (u8)((ch>>12) & 0x3f);
|
||||
buf[2] = 0x80 + (u8)((ch>>6) & 0x3f);
|
||||
buf[3] = 0x80 + (u8)(ch & 0x3f);
|
||||
length = 4;
|
||||
}
|
||||
}
|
||||
if( precision>1 ){
|
||||
width -= precision-1;
|
||||
@@ -634,12 +668,13 @@ void sqlite3VXPrintf(
|
||||
sqlite3AppendChar(pAccum, width-1, ' ');
|
||||
width = 0;
|
||||
}
|
||||
sqlite3AppendChar(pAccum, precision-1, c);
|
||||
while( precision-- > 1 ){
|
||||
sqlite3StrAccumAppend(pAccum, buf, length);
|
||||
}
|
||||
}
|
||||
length = 1;
|
||||
buf[0] = c;
|
||||
bufpt = buf;
|
||||
break;
|
||||
flag_altform2 = 1;
|
||||
goto adjust_width_for_utf8;
|
||||
case etSTRING:
|
||||
case etDYNSTRING:
|
||||
if( bArgList ){
|
||||
@@ -651,17 +686,45 @@ void sqlite3VXPrintf(
|
||||
if( bufpt==0 ){
|
||||
bufpt = "";
|
||||
}else if( xtype==etDYNSTRING ){
|
||||
if( pAccum->nChar==0 && pAccum->mxAlloc && width==0 && precision<0 ){
|
||||
/* Special optimization for sqlite3_mprintf("%z..."):
|
||||
** Extend an existing memory allocation rather than creating
|
||||
** a new one. */
|
||||
assert( (pAccum->printfFlags&SQLITE_PRINTF_MALLOCED)==0 );
|
||||
pAccum->zText = bufpt;
|
||||
pAccum->nAlloc = sqlite3DbMallocSize(pAccum->db, bufpt);
|
||||
pAccum->nChar = 0x7fffffff & (int)strlen(bufpt);
|
||||
pAccum->printfFlags |= SQLITE_PRINTF_MALLOCED;
|
||||
length = 0;
|
||||
break;
|
||||
}
|
||||
zExtra = bufpt;
|
||||
}
|
||||
if( precision>=0 ){
|
||||
for(length=0; length<precision && bufpt[length]; length++){}
|
||||
if( flag_altform2 ){
|
||||
/* Set length to the number of bytes needed in order to display
|
||||
** precision characters */
|
||||
unsigned char *z = (unsigned char*)bufpt;
|
||||
while( precision-- > 0 && z[0] ){
|
||||
SQLITE_SKIP_UTF8(z);
|
||||
}
|
||||
length = (int)(z - (unsigned char*)bufpt);
|
||||
}else{
|
||||
for(length=0; length<precision && bufpt[length]; length++){}
|
||||
}
|
||||
}else{
|
||||
length = 0x7fffffff & (int)strlen(bufpt);
|
||||
}
|
||||
adjust_width_for_utf8:
|
||||
if( flag_altform2 && width>0 ){
|
||||
/* Adjust width to account for extra bytes in UTF-8 characters */
|
||||
int ii = length - 1;
|
||||
while( ii>=0 ) if( (bufpt[ii--] & 0xc0)==0x80 ) width++;
|
||||
}
|
||||
break;
|
||||
case etSQLESCAPE: /* Escape ' characters */
|
||||
case etSQLESCAPE2: /* Escape ' and enclose in '...' */
|
||||
case etSQLESCAPE3: { /* Escape " characters */
|
||||
case etSQLESCAPE: /* %q: Escape ' characters */
|
||||
case etSQLESCAPE2: /* %Q: Escape ' and enclose in '...' */
|
||||
case etSQLESCAPE3: { /* %w: Escape " characters */
|
||||
int i, j, k, n, isnull;
|
||||
int needQuote;
|
||||
char ch;
|
||||
@@ -675,9 +738,17 @@ void sqlite3VXPrintf(
|
||||
}
|
||||
isnull = escarg==0;
|
||||
if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
|
||||
/* For %q, %Q, and %w, the precision is the number of byte (or
|
||||
** characters if the ! flags is present) to use from the input.
|
||||
** Because of the extra quoting characters inserted, the number
|
||||
** of output characters may be larger than the precision.
|
||||
*/
|
||||
k = precision;
|
||||
for(i=n=0; k!=0 && (ch=escarg[i])!=0; i++, k--){
|
||||
if( ch==q ) n++;
|
||||
if( flag_altform2 && (ch&0xc0)==0xc0 ){
|
||||
while( (escarg[i+1]&0xc0)==0x80 ){ i++; }
|
||||
}
|
||||
}
|
||||
needQuote = !isnull && xtype==etSQLESCAPE2;
|
||||
n += i + 3;
|
||||
@@ -700,10 +771,7 @@ void sqlite3VXPrintf(
|
||||
if( needQuote ) bufpt[j++] = q;
|
||||
bufpt[j] = 0;
|
||||
length = j;
|
||||
/* The precision in %q and %Q means how many input characters to
|
||||
** consume, not the length of the output...
|
||||
** if( precision>=0 && precision<length ) length = precision; */
|
||||
break;
|
||||
goto adjust_width_for_utf8;
|
||||
}
|
||||
case etTOKEN: {
|
||||
Token *pToken;
|
||||
@@ -742,7 +810,10 @@ void sqlite3VXPrintf(
|
||||
/*
|
||||
** The text of the conversion is pointed to by "bufpt" and is
|
||||
** "length" characters long. The field width is "width". Do
|
||||
** the output.
|
||||
** the output. Both length and width are in bytes, not characters,
|
||||
** at this point. If the "!" flag was present on string conversions
|
||||
** indicating that width and precision should be expressed in characters,
|
||||
** then the values have been translated prior to reaching this point.
|
||||
*/
|
||||
width -= length;
|
||||
if( width>0 ){
|
||||
|
||||
+28
-7
@@ -431,10 +431,16 @@ static int lookupName(
|
||||
** Because no reference was made to outer contexts, the pNC->nRef
|
||||
** fields are not changed in any context.
|
||||
*/
|
||||
if( cnt==0 && zTab==0 && ExprHasProperty(pExpr,EP_DblQuoted) ){
|
||||
pExpr->op = TK_STRING;
|
||||
pExpr->pTab = 0;
|
||||
return WRC_Prune;
|
||||
if( cnt==0 && zTab==0 ){
|
||||
assert( pExpr->op==TK_ID );
|
||||
if( ExprHasProperty(pExpr,EP_DblQuoted) ){
|
||||
pExpr->op = TK_STRING;
|
||||
pExpr->pTab = 0;
|
||||
return WRC_Prune;
|
||||
}
|
||||
if( sqlite3ExprIdToTrueFalse(pExpr) ){
|
||||
return WRC_Prune;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -783,15 +789,30 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
notValid(pParse, pNC, "parameters", NC_IsCheck|NC_PartIdx|NC_IdxExpr);
|
||||
break;
|
||||
}
|
||||
case TK_IS:
|
||||
case TK_ISNOT: {
|
||||
Expr *pRight;
|
||||
assert( !ExprHasProperty(pExpr, EP_Reduced) );
|
||||
/* Handle special cases of "x IS TRUE", "x IS FALSE", "x IS NOT TRUE",
|
||||
** and "x IS NOT FALSE". */
|
||||
if( (pRight = pExpr->pRight)->op==TK_ID ){
|
||||
int rc = resolveExprStep(pWalker, pRight);
|
||||
if( rc==WRC_Abort ) return WRC_Abort;
|
||||
if( pRight->op==TK_TRUEFALSE ){
|
||||
pExpr->op2 = pExpr->op;
|
||||
pExpr->op = TK_TRUTH;
|
||||
return WRC_Continue;
|
||||
}
|
||||
}
|
||||
/* Fall thru */
|
||||
}
|
||||
case TK_BETWEEN:
|
||||
case TK_EQ:
|
||||
case TK_NE:
|
||||
case TK_LT:
|
||||
case TK_LE:
|
||||
case TK_GT:
|
||||
case TK_GE:
|
||||
case TK_IS:
|
||||
case TK_ISNOT: {
|
||||
case TK_GE: {
|
||||
int nLeft, nRight;
|
||||
if( pParse->db->mallocFailed ) break;
|
||||
assert( pExpr->pLeft!=0 );
|
||||
|
||||
+243
-120
@@ -1069,6 +1069,7 @@ struct ShellState {
|
||||
#define SHELL_OPEN_NORMAL 1 /* Normal database file */
|
||||
#define SHELL_OPEN_APPENDVFS 2 /* Use appendvfs */
|
||||
#define SHELL_OPEN_ZIPFILE 3 /* Use the zipfile virtual table */
|
||||
#define SHELL_OPEN_READONLY 4 /* Open a normal database read-only */
|
||||
|
||||
/*
|
||||
** These are the allowed shellFlgs values
|
||||
@@ -2272,29 +2273,52 @@ static int display_stats(
|
||||
){
|
||||
int iCur;
|
||||
int iHiwtr;
|
||||
FILE *out;
|
||||
if( pArg==0 || pArg->out==0 ) return 0;
|
||||
out = pArg->out;
|
||||
|
||||
if( pArg && pArg->out ){
|
||||
displayStatLine(pArg, "Memory Used:",
|
||||
"%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset);
|
||||
displayStatLine(pArg, "Number of Outstanding Allocations:",
|
||||
"%lld (max %lld)", SQLITE_STATUS_MALLOC_COUNT, bReset);
|
||||
if( pArg->shellFlgs & SHFLG_Pagecache ){
|
||||
displayStatLine(pArg, "Number of Pcache Pages Used:",
|
||||
"%lld (max %lld) pages", SQLITE_STATUS_PAGECACHE_USED, bReset);
|
||||
if( pArg->pStmt && (pArg->statsOn & 2) ){
|
||||
int nCol, i, x;
|
||||
sqlite3_stmt *pStmt = pArg->pStmt;
|
||||
char z[100];
|
||||
nCol = sqlite3_column_count(pStmt);
|
||||
raw_printf(out, "%-36s %d\n", "Number of output columns:", nCol);
|
||||
for(i=0; i<nCol; i++){
|
||||
sqlite3_snprintf(sizeof(z),z,"Column %d %nname:", i, &x);
|
||||
utf8_printf(out, "%-36s %s\n", z, sqlite3_column_name(pStmt,i));
|
||||
sqlite3_snprintf(30, z+x, "declared type:");
|
||||
utf8_printf(out, "%-36s %s\n", z, sqlite3_column_decltype(pStmt, i));
|
||||
#ifdef SQLITE_ENABLE_COLUMN_METADATA
|
||||
sqlite3_snprintf(30, z+x, "database name:");
|
||||
utf8_printf(out, "%-36s %s\n", z, sqlite3_column_database_name(pStmt,i));
|
||||
sqlite3_snprintf(30, z+x, "table name:");
|
||||
utf8_printf(out, "%-36s %s\n", z, sqlite3_column_table_name(pStmt,i));
|
||||
sqlite3_snprintf(30, z+x, "origin name:");
|
||||
utf8_printf(out, "%-36s %s\n", z, sqlite3_column_origin_name(pStmt,i));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
displayStatLine(pArg, "Number of Pcache Overflow Bytes:",
|
||||
"%lld (max %lld) bytes", SQLITE_STATUS_PAGECACHE_OVERFLOW, bReset);
|
||||
displayStatLine(pArg, "Largest Allocation:",
|
||||
"%lld bytes", SQLITE_STATUS_MALLOC_SIZE, bReset);
|
||||
displayStatLine(pArg, "Largest Pcache Allocation:",
|
||||
"%lld bytes", SQLITE_STATUS_PAGECACHE_SIZE, bReset);
|
||||
#ifdef YYTRACKMAXSTACKDEPTH
|
||||
displayStatLine(pArg, "Deepest Parser Stack:",
|
||||
"%lld (max %lld)", SQLITE_STATUS_PARSER_STACK, bReset);
|
||||
#endif
|
||||
}
|
||||
|
||||
if( pArg && pArg->out && db ){
|
||||
displayStatLine(pArg, "Memory Used:",
|
||||
"%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset);
|
||||
displayStatLine(pArg, "Number of Outstanding Allocations:",
|
||||
"%lld (max %lld)", SQLITE_STATUS_MALLOC_COUNT, bReset);
|
||||
if( pArg->shellFlgs & SHFLG_Pagecache ){
|
||||
displayStatLine(pArg, "Number of Pcache Pages Used:",
|
||||
"%lld (max %lld) pages", SQLITE_STATUS_PAGECACHE_USED, bReset);
|
||||
}
|
||||
displayStatLine(pArg, "Number of Pcache Overflow Bytes:",
|
||||
"%lld (max %lld) bytes", SQLITE_STATUS_PAGECACHE_OVERFLOW, bReset);
|
||||
displayStatLine(pArg, "Largest Allocation:",
|
||||
"%lld bytes", SQLITE_STATUS_MALLOC_SIZE, bReset);
|
||||
displayStatLine(pArg, "Largest Pcache Allocation:",
|
||||
"%lld bytes", SQLITE_STATUS_PAGECACHE_SIZE, bReset);
|
||||
#ifdef YYTRACKMAXSTACKDEPTH
|
||||
displayStatLine(pArg, "Deepest Parser Stack:",
|
||||
"%lld (max %lld)", SQLITE_STATUS_PARSER_STACK, bReset);
|
||||
#endif
|
||||
|
||||
if( db ){
|
||||
if( pArg->shellFlgs & SHFLG_Lookaside ){
|
||||
iHiwtr = iCur = -1;
|
||||
sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
|
||||
@@ -2329,6 +2353,9 @@ static int display_stats(
|
||||
sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
|
||||
raw_printf(pArg->out, "Page cache writes: %d\n", iCur);
|
||||
iHiwtr = iCur = -1;
|
||||
sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_SPILL, &iCur, &iHiwtr, 1);
|
||||
raw_printf(pArg->out, "Page cache spills: %d\n", iCur);
|
||||
iHiwtr = iCur = -1;
|
||||
sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
|
||||
raw_printf(pArg->out, "Schema Heap Usage: %d bytes\n",
|
||||
iCur);
|
||||
@@ -2338,7 +2365,7 @@ static int display_stats(
|
||||
iCur);
|
||||
}
|
||||
|
||||
if( pArg && pArg->out && db && pArg->pStmt ){
|
||||
if( pArg->pStmt ){
|
||||
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
|
||||
bReset);
|
||||
raw_printf(pArg->out, "Fullscan Steps: %d\n", iCur);
|
||||
@@ -2348,6 +2375,12 @@ static int display_stats(
|
||||
raw_printf(pArg->out, "Autoindex Inserts: %d\n", iCur);
|
||||
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
|
||||
raw_printf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
|
||||
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_REPREPARE, bReset);
|
||||
raw_printf(pArg->out, "Reprepare operations: %d\n", iCur);
|
||||
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_RUN, bReset);
|
||||
raw_printf(pArg->out, "Number of times run: %d\n", iCur);
|
||||
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_MEMUSED, bReset);
|
||||
raw_printf(pArg->out, "Memory used by prepared stmt: %d\n", iCur);
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
@@ -2563,8 +2596,7 @@ static void restore_debug_trace_modes(void){
|
||||
*/
|
||||
static void exec_prepared_stmt(
|
||||
ShellState *pArg, /* Pointer to ShellState */
|
||||
sqlite3_stmt *pStmt, /* Statment to run */
|
||||
int (*xCallback)(void*,int,char**,char**,int*) /* Callback function */
|
||||
sqlite3_stmt *pStmt /* Statment to run */
|
||||
){
|
||||
int rc;
|
||||
|
||||
@@ -2574,54 +2606,47 @@ static void exec_prepared_stmt(
|
||||
rc = sqlite3_step(pStmt);
|
||||
/* if we have a result set... */
|
||||
if( SQLITE_ROW == rc ){
|
||||
/* if we have a callback... */
|
||||
if( xCallback ){
|
||||
/* allocate space for col name ptr, value ptr, and type */
|
||||
int nCol = sqlite3_column_count(pStmt);
|
||||
void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1);
|
||||
if( !pData ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
char **azCols = (char **)pData; /* Names of result columns */
|
||||
char **azVals = &azCols[nCol]; /* Results */
|
||||
int *aiTypes = (int *)&azVals[nCol]; /* Result types */
|
||||
int i, x;
|
||||
assert(sizeof(int) <= sizeof(char *));
|
||||
/* save off ptrs to column names */
|
||||
for(i=0; i<nCol; i++){
|
||||
azCols[i] = (char *)sqlite3_column_name(pStmt, i);
|
||||
}
|
||||
do{
|
||||
/* extract the data and data types */
|
||||
for(i=0; i<nCol; i++){
|
||||
aiTypes[i] = x = sqlite3_column_type(pStmt, i);
|
||||
if( x==SQLITE_BLOB && pArg && pArg->cMode==MODE_Insert ){
|
||||
azVals[i] = "";
|
||||
}else{
|
||||
azVals[i] = (char*)sqlite3_column_text(pStmt, i);
|
||||
}
|
||||
if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
|
||||
rc = SQLITE_NOMEM;
|
||||
break; /* from for */
|
||||
}
|
||||
} /* end for */
|
||||
|
||||
/* if data and types extracted successfully... */
|
||||
if( SQLITE_ROW == rc ){
|
||||
/* call the supplied callback with the result row data */
|
||||
if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
|
||||
rc = SQLITE_ABORT;
|
||||
}else{
|
||||
rc = sqlite3_step(pStmt);
|
||||
}
|
||||
}
|
||||
} while( SQLITE_ROW == rc );
|
||||
sqlite3_free(pData);
|
||||
}
|
||||
/* allocate space for col name ptr, value ptr, and type */
|
||||
int nCol = sqlite3_column_count(pStmt);
|
||||
void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1);
|
||||
if( !pData ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
char **azCols = (char **)pData; /* Names of result columns */
|
||||
char **azVals = &azCols[nCol]; /* Results */
|
||||
int *aiTypes = (int *)&azVals[nCol]; /* Result types */
|
||||
int i, x;
|
||||
assert(sizeof(int) <= sizeof(char *));
|
||||
/* save off ptrs to column names */
|
||||
for(i=0; i<nCol; i++){
|
||||
azCols[i] = (char *)sqlite3_column_name(pStmt, i);
|
||||
}
|
||||
do{
|
||||
rc = sqlite3_step(pStmt);
|
||||
} while( rc == SQLITE_ROW );
|
||||
/* extract the data and data types */
|
||||
for(i=0; i<nCol; i++){
|
||||
aiTypes[i] = x = sqlite3_column_type(pStmt, i);
|
||||
if( x==SQLITE_BLOB && pArg && pArg->cMode==MODE_Insert ){
|
||||
azVals[i] = "";
|
||||
}else{
|
||||
azVals[i] = (char*)sqlite3_column_text(pStmt, i);
|
||||
}
|
||||
if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
|
||||
rc = SQLITE_NOMEM;
|
||||
break; /* from for */
|
||||
}
|
||||
} /* end for */
|
||||
|
||||
/* if data and types extracted successfully... */
|
||||
if( SQLITE_ROW == rc ){
|
||||
/* call the supplied callback with the result row data */
|
||||
if( shell_callback(pArg, nCol, azVals, azCols, aiTypes) ){
|
||||
rc = SQLITE_ABORT;
|
||||
}else{
|
||||
rc = sqlite3_step(pStmt);
|
||||
}
|
||||
}
|
||||
} while( SQLITE_ROW == rc );
|
||||
sqlite3_free(pData);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2767,17 +2792,15 @@ static int expertDotCommand(
|
||||
** and callback data argument.
|
||||
*/
|
||||
static int shell_exec(
|
||||
sqlite3 *db, /* An open database */
|
||||
const char *zSql, /* SQL to be evaluated */
|
||||
int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
|
||||
/* (not the same as sqlite3_exec) */
|
||||
ShellState *pArg, /* Pointer to ShellState */
|
||||
const char *zSql, /* SQL to be evaluated */
|
||||
char **pzErrMsg /* Error msg written here */
|
||||
){
|
||||
sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
|
||||
int rc = SQLITE_OK; /* Return Code */
|
||||
int rc2;
|
||||
const char *zLeftover; /* Tail of unprocessed SQL */
|
||||
sqlite3 *db = pArg->db;
|
||||
|
||||
if( pzErrMsg ){
|
||||
*pzErrMsg = NULL;
|
||||
@@ -2848,7 +2871,7 @@ static int shell_exec(
|
||||
if( rc==SQLITE_OK ){
|
||||
pArg->cMode = MODE_Explain;
|
||||
explain_data_prepare(pArg, pExplain);
|
||||
exec_prepared_stmt(pArg, pExplain, xCallback);
|
||||
exec_prepared_stmt(pArg, pExplain);
|
||||
explain_data_delete(pArg);
|
||||
}
|
||||
sqlite3_finalize(pExplain);
|
||||
@@ -2874,7 +2897,7 @@ static int shell_exec(
|
||||
}
|
||||
}
|
||||
|
||||
exec_prepared_stmt(pArg, pStmt, xCallback);
|
||||
exec_prepared_stmt(pArg, pStmt);
|
||||
explain_data_delete(pArg);
|
||||
|
||||
/* print usage stats if stats on */
|
||||
@@ -3137,11 +3160,11 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azNotUsed){
|
||||
savedMode = p->mode;
|
||||
p->zDestTable = sTable.z;
|
||||
p->mode = p->cMode = MODE_Insert;
|
||||
rc = shell_exec(p->db, sSelect.z, shell_callback, p, 0);
|
||||
rc = shell_exec(p, sSelect.z, 0);
|
||||
if( (rc&0xff)==SQLITE_CORRUPT ){
|
||||
raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n");
|
||||
toggleSelectOrder(p->db);
|
||||
shell_exec(p->db, sSelect.z, shell_callback, p, 0);
|
||||
shell_exec(p, sSelect.z, 0);
|
||||
toggleSelectOrder(p->db);
|
||||
}
|
||||
p->zDestTable = savedDestTable;
|
||||
@@ -3258,6 +3281,7 @@ static char zHelp[] =
|
||||
" on the output.\n"
|
||||
".open ?OPTIONS? ?FILE? Close existing database and reopen FILE\n"
|
||||
" The --new option starts with an empty file\n"
|
||||
" Other options: --readonly --append --zip\n"
|
||||
".output ?FILE? Send output to FILE or stdout\n"
|
||||
".print STRING... Print literal STRING\n"
|
||||
".prompt MAIN CONTINUE Replace the standard prompts\n"
|
||||
@@ -3411,13 +3435,21 @@ static int session_filter(void *pCtx, const char *zTab){
|
||||
/*
|
||||
** Try to deduce the type of file for zName based on its content. Return
|
||||
** one of the SHELL_OPEN_* constants.
|
||||
**
|
||||
** If the file does not exist or is empty but its name looks like a ZIP
|
||||
** archive and the dfltZip flag is true, then assume it is a ZIP archive.
|
||||
** Otherwise, assume an ordinary database regardless of the filename if
|
||||
** the type cannot be determined from content.
|
||||
*/
|
||||
static int deduceDatabaseType(const char *zName){
|
||||
static int deduceDatabaseType(const char *zName, int dfltZip){
|
||||
FILE *f = fopen(zName, "rb");
|
||||
size_t n;
|
||||
int rc = SHELL_OPEN_UNSPEC;
|
||||
char zBuf[100];
|
||||
if( f==0 ) return SHELL_OPEN_NORMAL;
|
||||
if( f==0 ){
|
||||
if( dfltZip && sqlite3_strlike("%.zip",zName,0)==0 ) return SHELL_OPEN_ZIPFILE;
|
||||
return SHELL_OPEN_NORMAL;
|
||||
}
|
||||
fseek(f, -25, SEEK_END);
|
||||
n = fread(zBuf, 25, 1, f);
|
||||
if( n==1 && memcmp(zBuf, "Start-Of-SQLite3-", 17)==0 ){
|
||||
@@ -3428,6 +3460,8 @@ static int deduceDatabaseType(const char *zName){
|
||||
if( n==1 && zBuf[0]==0x50 && zBuf[1]==0x4b && zBuf[2]==0x05
|
||||
&& zBuf[3]==0x06 ){
|
||||
rc = SHELL_OPEN_ZIPFILE;
|
||||
}else if( n==0 && dfltZip && sqlite3_strlike("%.zip",zName,0)==0 ){
|
||||
return SHELL_OPEN_ZIPFILE;
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
@@ -3442,7 +3476,7 @@ static void open_db(ShellState *p, int keepAlive){
|
||||
if( p->db==0 ){
|
||||
sqlite3_initialize();
|
||||
if( p->openMode==SHELL_OPEN_UNSPEC && access(p->zDbFilename,0)==0 ){
|
||||
p->openMode = (u8)deduceDatabaseType(p->zDbFilename);
|
||||
p->openMode = (u8)deduceDatabaseType(p->zDbFilename, 0);
|
||||
}
|
||||
switch( p->openMode ){
|
||||
case SHELL_OPEN_APPENDVFS: {
|
||||
@@ -3454,6 +3488,10 @@ static void open_db(ShellState *p, int keepAlive){
|
||||
sqlite3_open(":memory:", &p->db);
|
||||
break;
|
||||
}
|
||||
case SHELL_OPEN_READONLY: {
|
||||
sqlite3_open_v2(p->zDbFilename, &p->db, SQLITE_OPEN_READONLY, 0);
|
||||
break;
|
||||
}
|
||||
case SHELL_OPEN_UNSPEC:
|
||||
case SHELL_OPEN_NORMAL: {
|
||||
sqlite3_open(p->zDbFilename, &p->db);
|
||||
@@ -5233,8 +5271,8 @@ static int arCreateOrUpdateCommand(
|
||||
" data BLOB -- compressed content\n"
|
||||
")";
|
||||
const char *zDrop = "DROP TABLE IF EXISTS sqlar";
|
||||
const char *zInsertFmt =
|
||||
"REPLACE INTO sqlar(name,mode,mtime,sz,data)\n"
|
||||
const char *zInsertFmt[2] = {
|
||||
"REPLACE INTO %s(name,mode,mtime,sz,data)\n"
|
||||
" SELECT\n"
|
||||
" %s,\n"
|
||||
" mode,\n"
|
||||
@@ -5243,30 +5281,70 @@ static int arCreateOrUpdateCommand(
|
||||
" WHEN '-' THEN length(data)\n"
|
||||
" WHEN 'd' THEN 0\n"
|
||||
" ELSE -1 END,\n"
|
||||
" CASE WHEN lsmode(mode) LIKE 'd%%' THEN NULL else data END\n"
|
||||
" sqlar_compress(data)\n"
|
||||
" FROM fsdir(%Q,%Q)\n"
|
||||
" WHERE lsmode(mode) NOT LIKE '?%%';";
|
||||
" WHERE lsmode(mode) NOT LIKE '?%%';",
|
||||
"REPLACE INTO %s(name,mode,mtime,data)\n"
|
||||
" SELECT\n"
|
||||
" %s,\n"
|
||||
" mode,\n"
|
||||
" mtime,\n"
|
||||
" data\n"
|
||||
" FROM fsdir(%Q,%Q)\n"
|
||||
" WHERE lsmode(mode) NOT LIKE '?%%';"
|
||||
};
|
||||
int i; /* For iterating through azFile[] */
|
||||
int rc; /* Return code */
|
||||
const char *zTab = 0; /* SQL table into which to insert */
|
||||
char *zSql;
|
||||
char zTemp[50];
|
||||
|
||||
arExecSql(pAr, "PRAGMA page_size=512");
|
||||
rc = arExecSql(pAr, "SAVEPOINT ar;");
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
if( bUpdate==0 ){
|
||||
rc = arExecSql(pAr, zDrop);
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
zTemp[0] = 0;
|
||||
if( pAr->bZip ){
|
||||
/* Initialize the zipfile virtual table, if necessary */
|
||||
if( pAr->zFile ){
|
||||
sqlite3_uint64 r;
|
||||
sqlite3_randomness(sizeof(r),&r);
|
||||
sqlite3_snprintf(sizeof(zTemp),zTemp,"zip%016llx",r);
|
||||
zTab = zTemp;
|
||||
zSql = sqlite3_mprintf(
|
||||
"CREATE VIRTUAL TABLE temp.%s USING zipfile(%Q)",
|
||||
zTab, pAr->zFile
|
||||
);
|
||||
rc = arExecSql(pAr, zSql);
|
||||
sqlite3_free(zSql);
|
||||
}else{
|
||||
zTab = "zip";
|
||||
}
|
||||
}else{
|
||||
/* Initialize the table for an SQLAR */
|
||||
zTab = "sqlar";
|
||||
if( bUpdate==0 ){
|
||||
rc = arExecSql(pAr, zDrop);
|
||||
if( rc!=SQLITE_OK ) goto end_ar_transaction;
|
||||
}
|
||||
rc = arExecSql(pAr, zCreate);
|
||||
}
|
||||
rc = arExecSql(pAr, zCreate);
|
||||
for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){
|
||||
char *zSql = sqlite3_mprintf(zInsertFmt,
|
||||
char *zSql = sqlite3_mprintf(zInsertFmt[pAr->bZip], zTab,
|
||||
pAr->bVerbose ? "shell_putsnl(name)" : "name",
|
||||
pAr->azArg[i], pAr->zDir);
|
||||
rc = arExecSql(pAr, zSql);
|
||||
sqlite3_free(zSql);
|
||||
}
|
||||
end_ar_transaction:
|
||||
if( rc!=SQLITE_OK ){
|
||||
arExecSql(pAr, "ROLLBACK TO ar; RELEASE ar;");
|
||||
}else{
|
||||
rc = arExecSql(pAr, "RELEASE ar;");
|
||||
if( pAr->bZip && pAr->zFile ){
|
||||
zSql = sqlite3_mprintf("DROP TABLE %s", zTemp);
|
||||
arExecSql(pAr, zSql);
|
||||
sqlite3_free(zSql);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@@ -5288,20 +5366,17 @@ static int arDotCommand(
|
||||
cmd.p = pState;
|
||||
cmd.db = pState->db;
|
||||
if( cmd.zFile ){
|
||||
eDbType = deduceDatabaseType(cmd.zFile);
|
||||
eDbType = deduceDatabaseType(cmd.zFile, 1);
|
||||
}else{
|
||||
eDbType = pState->openMode;
|
||||
}
|
||||
if( eDbType==SHELL_OPEN_ZIPFILE ){
|
||||
if( cmd.zFile==0 ){
|
||||
cmd.zSrcTable = sqlite3_mprintf("zip");
|
||||
}else{
|
||||
cmd.zSrcTable = sqlite3_mprintf("zipfile(%Q)", cmd.zFile);
|
||||
}
|
||||
if( cmd.eCmd==AR_CMD_CREATE || cmd.eCmd==AR_CMD_UPDATE ){
|
||||
utf8_printf(stderr, "zip archives are read-only\n");
|
||||
rc = SQLITE_ERROR;
|
||||
goto end_ar_command;
|
||||
if( cmd.eCmd==AR_CMD_EXTRACT || cmd.eCmd==AR_CMD_LIST ){
|
||||
if( cmd.zFile==0 ){
|
||||
cmd.zSrcTable = sqlite3_mprintf("zip");
|
||||
}else{
|
||||
cmd.zSrcTable = sqlite3_mprintf("zipfile(%Q)", cmd.zFile);
|
||||
}
|
||||
}
|
||||
cmd.bZip = 1;
|
||||
}else if( cmd.zFile ){
|
||||
@@ -5326,14 +5401,12 @@ static int arDotCommand(
|
||||
goto end_ar_command;
|
||||
}
|
||||
sqlite3_fileio_init(cmd.db, 0, 0);
|
||||
#ifdef SQLITE_HAVE_ZLIB
|
||||
sqlite3_sqlar_init(cmd.db, 0, 0);
|
||||
#endif
|
||||
sqlite3_create_function(cmd.db, "shell_putsnl", 1, SQLITE_UTF8, cmd.p,
|
||||
shellPutsFunc, 0, 0);
|
||||
|
||||
}
|
||||
if( cmd.zSrcTable==0 ){
|
||||
if( cmd.zSrcTable==0 && cmd.bZip==0 ){
|
||||
if( cmd.eCmd!=AR_CMD_CREATE
|
||||
&& sqlite3_table_column_metadata(cmd.db,0,"sqlar","name",0,0,0,0,0)
|
||||
){
|
||||
@@ -5813,14 +5886,11 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
callback, &data, &zErrMsg);
|
||||
data.cMode = data.mode = MODE_Insert;
|
||||
data.zDestTable = "sqlite_stat1";
|
||||
shell_exec(p->db, "SELECT * FROM sqlite_stat1",
|
||||
shell_callback, &data,&zErrMsg);
|
||||
shell_exec(p, "SELECT * FROM sqlite_stat1", &zErrMsg);
|
||||
data.zDestTable = "sqlite_stat3";
|
||||
shell_exec(p->db, "SELECT * FROM sqlite_stat3",
|
||||
shell_callback, &data,&zErrMsg);
|
||||
shell_exec(p, "SELECT * FROM sqlite_stat3", &zErrMsg);
|
||||
data.zDestTable = "sqlite_stat4";
|
||||
shell_exec(p->db, "SELECT * FROM sqlite_stat4",
|
||||
shell_callback, &data, &zErrMsg);
|
||||
shell_exec(p, "SELECT * FROM sqlite_stat4", &zErrMsg);
|
||||
raw_printf(p->out, "ANALYZE sqlite_master;\n");
|
||||
}
|
||||
}else
|
||||
@@ -6301,12 +6371,14 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
const char *z = azArg[iName];
|
||||
if( optionMatch(z,"new") ){
|
||||
newFlag = 1;
|
||||
#ifdef SQLITE_HAVE_ZIP
|
||||
#ifdef SQLITE_HAVE_ZLIB
|
||||
}else if( optionMatch(z, "zip") ){
|
||||
p->openMode = SHELL_OPEN_ZIPFILE;
|
||||
#endif
|
||||
}else if( optionMatch(z, "append") ){
|
||||
p->openMode = SHELL_OPEN_APPENDVFS;
|
||||
}else if( optionMatch(z, "readonly") ){
|
||||
p->openMode = SHELL_OPEN_READONLY;
|
||||
}else if( z[0]=='-' ){
|
||||
utf8_printf(stderr, "unknown option: %s\n", z);
|
||||
rc = 1;
|
||||
@@ -7088,7 +7160,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
if( bDebug ){
|
||||
utf8_printf(p->out, "%s\n", zSql);
|
||||
}else{
|
||||
shell_exec(p->db, zSql, shell_callback, p, 0);
|
||||
shell_exec(p, zSql, 0);
|
||||
}
|
||||
sqlite3_free(zSql);
|
||||
}else
|
||||
@@ -7727,7 +7799,7 @@ static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){
|
||||
open_db(p, 0);
|
||||
if( ShellHasFlag(p,SHFLG_Backslash) ) resolve_backslashes(zSql);
|
||||
BEGIN_TIMER;
|
||||
rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
|
||||
rc = shell_exec(p, zSql, &zErrMsg);
|
||||
END_TIMER;
|
||||
if( rc || zErrMsg ){
|
||||
char zPrefix[100];
|
||||
@@ -7959,6 +8031,10 @@ static void process_sqliterc(
|
||||
** Show available command line options
|
||||
*/
|
||||
static const char zOptions[] =
|
||||
#if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
|
||||
" -A ARGS... run \".archive ARGS\" and exit\n"
|
||||
#endif
|
||||
" -append append the database to the end of the file\n"
|
||||
" -ascii set output mode to 'ascii'\n"
|
||||
" -bail stop after hitting an error\n"
|
||||
" -batch force batch I/O\n"
|
||||
@@ -7985,6 +8061,7 @@ static const char zOptions[] =
|
||||
" -nullvalue TEXT set text string for NULL values. Default ''\n"
|
||||
" -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
|
||||
" -quote set output mode to 'quote'\n"
|
||||
" -readonly open the database read-only\n"
|
||||
" -separator SEP set output column separator. Default: '|'\n"
|
||||
" -stats print memory stats before each finalize\n"
|
||||
" -version show SQLite version\n"
|
||||
@@ -7992,6 +8069,9 @@ static const char zOptions[] =
|
||||
#ifdef SQLITE_ENABLE_VFSTRACE
|
||||
" -vfstrace enable tracing of all VFS calls\n"
|
||||
#endif
|
||||
#ifdef SQLITE_HAVE_ZLIB
|
||||
" -zip open the file as a ZIP Archive\n"
|
||||
#endif
|
||||
;
|
||||
static void usage(int showDetail){
|
||||
utf8_printf(stderr,
|
||||
@@ -8094,21 +8174,39 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
|
||||
}
|
||||
#endif
|
||||
main_init(&data);
|
||||
sqlite3_initialize();
|
||||
|
||||
/* On Windows, we must translate command-line arguments into UTF-8.
|
||||
** The SQLite memory allocator subsystem has to be enabled in order to
|
||||
** do this. But we want to run an sqlite3_shutdown() afterwards so that
|
||||
** subsequent sqlite3_config() calls will work. So copy all results into
|
||||
** memory that does not come from the SQLite memory allocator.
|
||||
*/
|
||||
#if !SQLITE_SHELL_IS_UTF8
|
||||
argv = sqlite3_malloc64(sizeof(argv[0])*argc);
|
||||
sqlite3_initialize();
|
||||
argv = malloc(sizeof(argv[0])*argc);
|
||||
if( argv==0 ){
|
||||
raw_printf(stderr, "out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
for(i=0; i<argc; i++){
|
||||
argv[i] = sqlite3_win32_unicode_to_utf8(wargv[i]);
|
||||
char *z = sqlite3_win32_unicode_to_utf8(wargv[i]);
|
||||
int n;
|
||||
if( z==0 ){
|
||||
raw_printf(stderr, "out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
n = (int)strlen(z);
|
||||
argv[i] = malloc( n+1 );
|
||||
if( argv[i]==0 ){
|
||||
raw_printf(stderr, "out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
memcpy(argv[i], z, n+1);
|
||||
sqlite3_free(z);
|
||||
}
|
||||
sqlite3_shutdown();
|
||||
#endif
|
||||
|
||||
assert( argc>=1 && argv && argv[0] );
|
||||
Argv0 = argv[0];
|
||||
|
||||
@@ -8228,12 +8326,20 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
|
||||
utf8_printf(stderr, "no such VFS: \"%s\"\n", argv[i]);
|
||||
exit(1);
|
||||
}
|
||||
#ifdef SQLITE_HAVE_ZIP
|
||||
#ifdef SQLITE_HAVE_ZLIB
|
||||
}else if( strcmp(z,"-zip")==0 ){
|
||||
data.openMode = SHELL_OPEN_ZIPFILE;
|
||||
#endif
|
||||
}else if( strcmp(z,"-append")==0 ){
|
||||
data.openMode = SHELL_OPEN_APPENDVFS;
|
||||
}else if( strcmp(z,"-readonly")==0 ){
|
||||
data.openMode = SHELL_OPEN_READONLY;
|
||||
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
|
||||
}else if( strncmp(z, "-A",2)==0 ){
|
||||
/* All remaining command-line arguments are passed to the ".archive"
|
||||
** command, so ignore them */
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if( data.zDbFilename==0 ){
|
||||
@@ -8287,7 +8393,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
|
||||
}else if( strcmp(z,"-csv")==0 ){
|
||||
data.mode = MODE_Csv;
|
||||
memcpy(data.colSeparator,",",2);
|
||||
#ifdef SQLITE_HAVE_ZIP
|
||||
#ifdef SQLITE_HAVE_ZLIB
|
||||
}else if( strcmp(z,"-zip")==0 ){
|
||||
data.openMode = SHELL_OPEN_ZIPFILE;
|
||||
#endif
|
||||
@@ -8370,7 +8476,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
|
||||
if( rc && bail_on_error ) return rc==2 ? 0 : rc;
|
||||
}else{
|
||||
open_db(&data, 0);
|
||||
rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
|
||||
rc = shell_exec(&data, z, &zErrMsg);
|
||||
if( zErrMsg!=0 ){
|
||||
utf8_printf(stderr,"Error: %s\n", zErrMsg);
|
||||
if( bail_on_error ) return rc!=0 ? rc : 1;
|
||||
@@ -8379,6 +8485,23 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
|
||||
if( bail_on_error ) return rc;
|
||||
}
|
||||
}
|
||||
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
|
||||
}else if( strncmp(z, "-A", 2)==0 ){
|
||||
if( nCmd>0 ){
|
||||
utf8_printf(stderr, "Error: cannot mix regular SQL or dot-commands"
|
||||
" with \"%s\"\n", z);
|
||||
return 1;
|
||||
}
|
||||
open_db(&data, 0);
|
||||
if( z[2] ){
|
||||
argv[i] = &z[2];
|
||||
arDotCommand(&data, argv+(i-1), argc-(i-1));
|
||||
}else{
|
||||
arDotCommand(&data, argv+i, argc-i);
|
||||
}
|
||||
readStdin = 0;
|
||||
break;
|
||||
#endif
|
||||
}else{
|
||||
utf8_printf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
|
||||
raw_printf(stderr,"Use -help for a list of options.\n");
|
||||
@@ -8398,7 +8521,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
|
||||
if( rc ) return rc==2 ? 0 : rc;
|
||||
}else{
|
||||
open_db(&data, 0);
|
||||
rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
|
||||
rc = shell_exec(&data, azCmd[i], &zErrMsg);
|
||||
if( zErrMsg!=0 ){
|
||||
utf8_printf(stderr,"Error: %s\n", zErrMsg);
|
||||
return rc!=0 ? rc : 1;
|
||||
@@ -8461,8 +8584,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
|
||||
data.doXdgOpen = 0;
|
||||
clearTempFile(&data);
|
||||
#if !SQLITE_SHELL_IS_UTF8
|
||||
for(i=0; i<argc; i++) sqlite3_free(argv[i]);
|
||||
sqlite3_free(argv);
|
||||
for(i=0; i<argc; i++) free(argv[i]);
|
||||
free(argv);
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
+140
-72
@@ -2496,16 +2496,16 @@ void sqlite3_free_table(char **result);
|
||||
**
|
||||
** These routines are work-alikes of the "printf()" family of functions
|
||||
** from the standard C library.
|
||||
** These routines understand most of the common K&R formatting options,
|
||||
** plus some additional non-standard formats, detailed below.
|
||||
** Note that some of the more obscure formatting options from recent
|
||||
** C-library standards are omitted from this implementation.
|
||||
** These routines understand most of the common formatting options from
|
||||
** the standard library printf()
|
||||
** plus some additional non-standard formats ([%q], [%Q], [%w], and [%z]).
|
||||
** See the [built-in printf()] documentation for details.
|
||||
**
|
||||
** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their
|
||||
** results into memory obtained from [sqlite3_malloc()].
|
||||
** results into memory obtained from [sqlite3_malloc64()].
|
||||
** The strings returned by these two routines should be
|
||||
** released by [sqlite3_free()]. ^Both routines return a
|
||||
** NULL pointer if [sqlite3_malloc()] is unable to allocate enough
|
||||
** NULL pointer if [sqlite3_malloc64()] is unable to allocate enough
|
||||
** memory to hold the resulting string.
|
||||
**
|
||||
** ^(The sqlite3_snprintf() routine is similar to "snprintf()" from
|
||||
@@ -2529,71 +2529,7 @@ void sqlite3_free_table(char **result);
|
||||
**
|
||||
** ^The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf().
|
||||
**
|
||||
** These routines all implement some additional formatting
|
||||
** options that are useful for constructing SQL statements.
|
||||
** All of the usual printf() formatting options apply. In addition, there
|
||||
** is are "%q", "%Q", "%w" and "%z" options.
|
||||
**
|
||||
** ^(The %q option works like %s in that it substitutes a nul-terminated
|
||||
** string from the argument list. But %q also doubles every '\'' character.
|
||||
** %q is designed for use inside a string literal.)^ By doubling each '\''
|
||||
** character it escapes that character and allows it to be inserted into
|
||||
** the string.
|
||||
**
|
||||
** For example, assume the string variable zText contains text as follows:
|
||||
**
|
||||
** <blockquote><pre>
|
||||
** char *zText = "It's a happy day!";
|
||||
** </pre></blockquote>
|
||||
**
|
||||
** One can use this text in an SQL statement as follows:
|
||||
**
|
||||
** <blockquote><pre>
|
||||
** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText);
|
||||
** sqlite3_exec(db, zSQL, 0, 0, 0);
|
||||
** sqlite3_free(zSQL);
|
||||
** </pre></blockquote>
|
||||
**
|
||||
** Because the %q format string is used, the '\'' character in zText
|
||||
** is escaped and the SQL generated is as follows:
|
||||
**
|
||||
** <blockquote><pre>
|
||||
** INSERT INTO table1 VALUES('It''s a happy day!')
|
||||
** </pre></blockquote>
|
||||
**
|
||||
** This is correct. Had we used %s instead of %q, the generated SQL
|
||||
** would have looked like this:
|
||||
**
|
||||
** <blockquote><pre>
|
||||
** INSERT INTO table1 VALUES('It's a happy day!');
|
||||
** </pre></blockquote>
|
||||
**
|
||||
** This second example is an SQL syntax error. As a general rule you should
|
||||
** always use %q instead of %s when inserting text into a string literal.
|
||||
**
|
||||
** ^(The %Q option works like %q except it also adds single quotes around
|
||||
** the outside of the total string. Additionally, if the parameter in the
|
||||
** argument list is a NULL pointer, %Q substitutes the text "NULL" (without
|
||||
** single quotes).)^ So, for example, one could say:
|
||||
**
|
||||
** <blockquote><pre>
|
||||
** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText);
|
||||
** sqlite3_exec(db, zSQL, 0, 0, 0);
|
||||
** sqlite3_free(zSQL);
|
||||
** </pre></blockquote>
|
||||
**
|
||||
** The code above will render a correct SQL statement in the zSQL
|
||||
** variable even if the zText variable is a NULL pointer.
|
||||
**
|
||||
** ^(The "%w" formatting option is like "%q" except that it expects to
|
||||
** be contained within double-quotes instead of single quotes, and it
|
||||
** escapes the double-quote character instead of the single-quote
|
||||
** character.)^ The "%w" formatting option is intended for safely inserting
|
||||
** table and column names into a constructed SQL statement.
|
||||
**
|
||||
** ^(The "%z" formatting option works like "%s" but with the
|
||||
** addition that after the string has been read and copied into
|
||||
** the result, [sqlite3_free()] is called on the input string.)^
|
||||
** See also: [built-in printf()], [printf() SQL function]
|
||||
*/
|
||||
char *sqlite3_mprintf(const char*,...);
|
||||
char *sqlite3_vmprintf(const char*, va_list);
|
||||
@@ -7294,6 +7230,15 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
|
||||
** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0.
|
||||
** </dd>
|
||||
**
|
||||
** [[SQLITE_DBSTATUS_CACHE_SPILL]] ^(<dt>SQLITE_DBSTATUS_CACHE_SPILL</dt>
|
||||
** <dd>This parameter returns the number of dirty cache entries that have
|
||||
** been written to disk in the middle of a transaction due to the page
|
||||
** cache overflowing. Transactions are more efficient if they are written
|
||||
** to disk all at once. When pages spill mid-transaction, that introduces
|
||||
** additional overhead. This parameter can be used help identify
|
||||
** inefficiencies that can be resolve by increasing the cache size.
|
||||
** </dd>
|
||||
**
|
||||
** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt>
|
||||
** <dd>This parameter returns zero for the current value if and only if
|
||||
** all foreign key constraints (deferred or immediate) have been
|
||||
@@ -7313,7 +7258,8 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
|
||||
#define SQLITE_DBSTATUS_CACHE_WRITE 9
|
||||
#define SQLITE_DBSTATUS_DEFERRED_FKS 10
|
||||
#define SQLITE_DBSTATUS_CACHE_USED_SHARED 11
|
||||
#define SQLITE_DBSTATUS_MAX 11 /* Largest defined DBSTATUS */
|
||||
#define SQLITE_DBSTATUS_CACHE_SPILL 12
|
||||
#define SQLITE_DBSTATUS_MAX 12 /* Largest defined DBSTATUS */
|
||||
|
||||
|
||||
/*
|
||||
@@ -8793,6 +8739,128 @@ SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
|
||||
*/
|
||||
SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Serialize a database
|
||||
**
|
||||
** The sqlite3_serialize(D,S,P,F) interface returns a pointer to memory
|
||||
** that is a serialization of the S database on [database connection] D.
|
||||
** If P is not a NULL pointer, then the size of the database in bytes
|
||||
** is written into *P.
|
||||
**
|
||||
** For an ordinary on-disk database file, the serialization is just a
|
||||
** copy of the disk file. For an in-memory database or a "TEMP" database,
|
||||
** the serialization is the same sequence of bytes which would be written
|
||||
** to disk if that database where backed up to disk.
|
||||
**
|
||||
** The usual case is that sqlite3_serialize() copies the serialization of
|
||||
** the database into memory obtained from [sqlite3_malloc64()] and returns
|
||||
** a pointer to that memory. The caller is responsible for freeing the
|
||||
** returned value to avoid a memory leak. However, if the F argument
|
||||
** contains the SQLITE_SERIALIZE_NOCOPY bit, then no memory allocations
|
||||
** are made, and the sqlite3_serialize() function will return a pointer
|
||||
** to the contiguous memory representation of the database that SQLite
|
||||
** is currently using for that database, or NULL if the no such contiguous
|
||||
** memory representation of the database exists. A contiguous memory
|
||||
** representation of the database will usually only exist if there has
|
||||
** been a prior call to [sqlite3_deserialize(D,S,...)] with the same
|
||||
** values of D and S.
|
||||
** The size of the database is written into *P even if the
|
||||
** SQLITE_SERIALIZE_NOCOPY bit is set but no contigious copy
|
||||
** of the database exists.
|
||||
**
|
||||
** A call to sqlite3_serialize(D,S,P,F) might return NULL even if the
|
||||
** SQLITE_SERIALIZE_NOCOPY bit is omitted from argument F if a memory
|
||||
** allocation error occurs.
|
||||
**
|
||||
** This interface is only available if SQLite is compiled with the
|
||||
** [SQLITE_ENABLE_DESERIALIZE] option.
|
||||
*/
|
||||
unsigned char *sqlite3_serialize(
|
||||
sqlite3 *db, /* The database connection */
|
||||
const char *zSchema, /* Which DB to serialize. ex: "main", "temp", ... */
|
||||
sqlite3_int64 *piSize, /* Write size of the DB here, if not NULL */
|
||||
unsigned int mFlags /* Zero or more SQLITE_SERIALIZE_* flags */
|
||||
);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Flags for sqlite3_serialize
|
||||
**
|
||||
** Zero or more of the following constants can be OR-ed together for
|
||||
** the F argument to [sqlite3_serialize(D,S,P,F)].
|
||||
**
|
||||
** SQLITE_SERIALIZE_NOCOPY means that [sqlite3_serialize()] will return
|
||||
** a pointer to contiguous in-memory database that it is currently using,
|
||||
** without making a copy of the database. If SQLite is not currently using
|
||||
** a contiguous in-memory database, then this option causes
|
||||
** [sqlite3_serialize()] to return a NULL pointer. SQLite will only be
|
||||
** using a contiguous in-memory database if it has been initialized by a
|
||||
** prior call to [sqlite3_deserialize()].
|
||||
*/
|
||||
#define SQLITE_SERIALIZE_NOCOPY 0x001 /* Do no memory allocations */
|
||||
|
||||
/*
|
||||
** CAPI3REF: Deserialize a database
|
||||
**
|
||||
** The sqlite3_deserialize(D,S,P,N,M,F) interface causes the
|
||||
** [database connection] D to disconnection from database S and then
|
||||
** reopen S as an in-memory database based on the serialization contained
|
||||
** in P. The serialized database P is N bytes in size. M is the size of
|
||||
** the buffer P, which might be larger than N. If M is larger than N, and
|
||||
** the SQLITE_DESERIALIZE_READONLY bit is not set in F, then SQLite is
|
||||
** permitted to add content to the in-memory database as long as the total
|
||||
** size does not exceed M bytes.
|
||||
**
|
||||
** If the SQLITE_DESERIALIZE_FREEONCLOSE bit is set in F, then SQLite will
|
||||
** invoke sqlite3_free() on the serialization buffer when the database
|
||||
** connection closes. If the SQLITE_DESERIALIZE_RESIZEABLE bit is set, then
|
||||
** SQLite will try to increase the buffer size using sqlite3_realloc64()
|
||||
** if writes on the database cause it to grow larger than M bytes.
|
||||
**
|
||||
** The sqlite3_deserialize() interface will fail with SQLITE_BUSY if the
|
||||
** database is currently in a read transaction or is involved in a backup
|
||||
** operation.
|
||||
**
|
||||
** If sqlite3_deserialize(D,S,P,N,M,F) fails for any reason and if the
|
||||
** SQLITE_DESERIALIZE_FREEONCLOSE bit is set in argument F, then
|
||||
** [sqlite3_free()] is invoked on argument P prior to returning.
|
||||
**
|
||||
** This interface is only available if SQLite is compiled with the
|
||||
** [SQLITE_ENABLE_DESERIALIZE] option.
|
||||
*/
|
||||
int sqlite3_deserialize(
|
||||
sqlite3 *db, /* The database connection */
|
||||
const char *zSchema, /* Which DB to reopen with the deserialization */
|
||||
unsigned char *pData, /* The serialized database content */
|
||||
sqlite3_int64 szDb, /* Number bytes in the deserialization */
|
||||
sqlite3_int64 szBuf, /* Total size of buffer pData[] */
|
||||
unsigned mFlags /* Zero or more SQLITE_DESERIALIZE_* flags */
|
||||
);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Flags for sqlite3_deserialize()
|
||||
**
|
||||
** The following are allowed values for 6th argument (the F argument) to
|
||||
** the [sqlite3_deserialize(D,S,P,N,M,F)] interface.
|
||||
**
|
||||
** The SQLITE_DESERIALIZE_FREEONCLOSE means that the database serialization
|
||||
** in the P argument is held in memory obtained from [sqlite3_malloc64()]
|
||||
** and that SQLite should take ownership of this memory and automatically
|
||||
** free it when it has finished using it. Without this flag, the caller
|
||||
** is resposible for freeing any dynamically allocated memory.
|
||||
**
|
||||
** The SQLITE_DESERIALIZE_RESIZEABLE flag means that SQLite is allowed to
|
||||
** grow the size of the database usign calls to [sqlite3_realloc64()]. This
|
||||
** flag should only be used if SQLITE_DESERIALIZE_FREEONCLOSE is also used.
|
||||
** Without this flag, the deserialized database cannot increase in size beyond
|
||||
** the number of bytes specified by the M parameter.
|
||||
**
|
||||
** The SQLITE_DESERIALIZE_READONLY flag means that the deserialized database
|
||||
** should be treated as read-only.
|
||||
*/
|
||||
#define SQLITE_DESERIALIZE_FREEONCLOSE 1 /* Call sqlite3_free() on close */
|
||||
#define SQLITE_DESERIALIZE_RESIZEABLE 2 /* Resize using sqlite3_realloc64() */
|
||||
#define SQLITE_DESERIALIZE_READONLY 4 /* Database is read-only */
|
||||
|
||||
/*
|
||||
** Undo the hack that converts floating point types to integer for
|
||||
** builds on processors without floating point support.
|
||||
|
||||
+12
-2
@@ -1365,8 +1365,9 @@ struct sqlite3 {
|
||||
int newTnum; /* Rootpage of table being initialized */
|
||||
u8 iDb; /* Which db file is being initialized */
|
||||
u8 busy; /* TRUE if currently initializing */
|
||||
u8 orphanTrigger; /* Last statement is orphaned TEMP trigger */
|
||||
u8 imposterTable; /* Building an imposter table */
|
||||
unsigned orphanTrigger : 1; /* Last statement is orphaned TEMP trigger */
|
||||
unsigned imposterTable : 1; /* Building an imposter table */
|
||||
unsigned reopenMemdb : 1; /* ATTACH is really a reopen using MemDB */
|
||||
} init;
|
||||
int nVdbeActive; /* Number of VDBEs currently running */
|
||||
int nVdbeRead; /* Number of active VDBEs that read or write */
|
||||
@@ -3839,6 +3840,8 @@ void sqlite3EndTransaction(Parse*,int);
|
||||
void sqlite3Savepoint(Parse*, int, Token*);
|
||||
void sqlite3CloseSavepoints(sqlite3 *);
|
||||
void sqlite3LeaveMutexAndCloseZombie(sqlite3*);
|
||||
int sqlite3ExprIdToTrueFalse(Expr*);
|
||||
int sqlite3ExprTruthValue(const Expr*);
|
||||
int sqlite3ExprIsConstant(Expr*);
|
||||
int sqlite3ExprIsConstantNotJoin(Expr*);
|
||||
int sqlite3ExprIsConstantOrFunction(Expr*, u8);
|
||||
@@ -4021,6 +4024,10 @@ int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
|
||||
const char *sqlite3ErrName(int);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_ENABLE_DESERIALIZE
|
||||
int sqlite3MemdbInit(void);
|
||||
#endif
|
||||
|
||||
const char *sqlite3ErrStr(int);
|
||||
int sqlite3ReadSchema(Parse *pParse);
|
||||
CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
|
||||
@@ -4069,6 +4076,9 @@ extern FuncDefHash sqlite3BuiltinFunctions;
|
||||
extern int sqlite3PendingByte;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef VDBE_PROFILE
|
||||
extern sqlite3_uint64 sqlite3NProfileCnt;
|
||||
#endif
|
||||
void sqlite3RootPageMoved(sqlite3*, int, int, int);
|
||||
void sqlite3Reindex(Parse*, Token*, Token*);
|
||||
void sqlite3AlterFunctions(void);
|
||||
|
||||
@@ -337,6 +337,9 @@ int sqlite3_db_status(
|
||||
** pagers the database handle is connected to. *pHighwater is always set
|
||||
** to zero.
|
||||
*/
|
||||
case SQLITE_DBSTATUS_CACHE_SPILL:
|
||||
op = SQLITE_DBSTATUS_CACHE_WRITE+1;
|
||||
/* Fall through into the next case */
|
||||
case SQLITE_DBSTATUS_CACHE_HIT:
|
||||
case SQLITE_DBSTATUS_CACHE_MISS:
|
||||
case SQLITE_DBSTATUS_CACHE_WRITE:{
|
||||
|
||||
+145
-49
@@ -648,7 +648,7 @@ static int DbTraceV2Handler(
|
||||
}
|
||||
case SQLITE_TRACE_PROFILE: {
|
||||
sqlite3_stmt *pStmt = (sqlite3_stmt *)pd;
|
||||
sqlite3_int64 ns = (sqlite3_int64)xd;
|
||||
sqlite3_int64 ns = *(sqlite3_int64*)xd;
|
||||
|
||||
pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
|
||||
Tcl_IncrRefCount(pCmd);
|
||||
@@ -1848,35 +1848,35 @@ static int SQLITE_TCLAPI DbObjCmd(
|
||||
int choice;
|
||||
int rc = TCL_OK;
|
||||
static const char *DB_strs[] = {
|
||||
"authorizer", "backup", "busy",
|
||||
"cache", "changes", "close",
|
||||
"collate", "collation_needed", "commit_hook",
|
||||
"complete", "copy", "enable_load_extension",
|
||||
"errorcode", "eval", "exists",
|
||||
"function", "incrblob", "interrupt",
|
||||
"last_insert_rowid", "nullvalue", "onecolumn",
|
||||
"preupdate", "profile", "progress",
|
||||
"rekey", "restore", "rollback_hook",
|
||||
"status", "timeout", "total_changes",
|
||||
"trace", "trace_v2", "transaction",
|
||||
"unlock_notify", "update_hook", "version",
|
||||
"wal_hook",
|
||||
0
|
||||
"authorizer", "backup", "busy",
|
||||
"cache", "changes", "close",
|
||||
"collate", "collation_needed", "commit_hook",
|
||||
"complete", "copy", "deserialize",
|
||||
"enable_load_extension", "errorcode", "eval",
|
||||
"exists", "function", "incrblob",
|
||||
"interrupt", "last_insert_rowid", "nullvalue",
|
||||
"onecolumn", "preupdate", "profile",
|
||||
"progress", "rekey", "restore",
|
||||
"rollback_hook", "serialize", "status",
|
||||
"timeout", "total_changes", "trace",
|
||||
"trace_v2", "transaction", "unlock_notify",
|
||||
"update_hook", "version", "wal_hook",
|
||||
0
|
||||
};
|
||||
enum DB_enum {
|
||||
DB_AUTHORIZER, DB_BACKUP, DB_BUSY,
|
||||
DB_CACHE, DB_CHANGES, DB_CLOSE,
|
||||
DB_COLLATE, DB_COLLATION_NEEDED, DB_COMMIT_HOOK,
|
||||
DB_COMPLETE, DB_COPY, DB_ENABLE_LOAD_EXTENSION,
|
||||
DB_ERRORCODE, DB_EVAL, DB_EXISTS,
|
||||
DB_FUNCTION, DB_INCRBLOB, DB_INTERRUPT,
|
||||
DB_LAST_INSERT_ROWID, DB_NULLVALUE, DB_ONECOLUMN,
|
||||
DB_PREUPDATE, DB_PROFILE, DB_PROGRESS,
|
||||
DB_REKEY, DB_RESTORE, DB_ROLLBACK_HOOK,
|
||||
DB_STATUS, DB_TIMEOUT, DB_TOTAL_CHANGES,
|
||||
DB_TRACE, DB_TRACE_V2, DB_TRANSACTION,
|
||||
DB_UNLOCK_NOTIFY, DB_UPDATE_HOOK, DB_VERSION,
|
||||
DB_WAL_HOOK,
|
||||
DB_AUTHORIZER, DB_BACKUP, DB_BUSY,
|
||||
DB_CACHE, DB_CHANGES, DB_CLOSE,
|
||||
DB_COLLATE, DB_COLLATION_NEEDED, DB_COMMIT_HOOK,
|
||||
DB_COMPLETE, DB_COPY, DB_DESERIALIZE,
|
||||
DB_ENABLE_LOAD_EXTENSION, DB_ERRORCODE, DB_EVAL,
|
||||
DB_EXISTS, DB_FUNCTION, DB_INCRBLOB,
|
||||
DB_INTERRUPT, DB_LAST_INSERT_ROWID, DB_NULLVALUE,
|
||||
DB_ONECOLUMN, DB_PREUPDATE, DB_PROFILE,
|
||||
DB_PROGRESS, DB_REKEY, DB_RESTORE,
|
||||
DB_ROLLBACK_HOOK, DB_SERIALIZE, DB_STATUS,
|
||||
DB_TIMEOUT, DB_TOTAL_CHANGES, DB_TRACE,
|
||||
DB_TRACE_V2, DB_TRANSACTION, DB_UNLOCK_NOTIFY,
|
||||
DB_UPDATE_HOOK, DB_VERSION, DB_WAL_HOOK
|
||||
};
|
||||
/* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */
|
||||
|
||||
@@ -2414,6 +2414,53 @@ static int SQLITE_TCLAPI DbObjCmd(
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
** $db deserialize ?DATABASE? VALUE
|
||||
**
|
||||
** Reopen DATABASE (default "main") using the content in $VALUE
|
||||
*/
|
||||
case DB_DESERIALIZE: {
|
||||
#ifndef SQLITE_ENABLE_DESERIALIZE
|
||||
Tcl_AppendResult(interp, "MEMDB not available in this build",
|
||||
(char*)0);
|
||||
rc = TCL_ERROR;
|
||||
#else
|
||||
const char *zSchema;
|
||||
Tcl_Obj *pValue;
|
||||
unsigned char *pBA;
|
||||
unsigned char *pData;
|
||||
int len, xrc;
|
||||
|
||||
if( objc==3 ){
|
||||
zSchema = 0;
|
||||
pValue = objv[2];
|
||||
}else if( objc==4 ){
|
||||
zSchema = Tcl_GetString(objv[2]);
|
||||
pValue = objv[3];
|
||||
}else{
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? VALUE");
|
||||
rc = TCL_ERROR;
|
||||
break;
|
||||
}
|
||||
pBA = Tcl_GetByteArrayFromObj(pValue, &len);
|
||||
pData = sqlite3_malloc64( len );
|
||||
if( pData==0 && len>0 ){
|
||||
Tcl_AppendResult(interp, "out of memory", (char*)0);
|
||||
rc = TCL_ERROR;
|
||||
}else{
|
||||
if( len>0 ) memcpy(pData, pBA, len);
|
||||
xrc = sqlite3_deserialize(pDb->db, zSchema, pData, len, len,
|
||||
SQLITE_DESERIALIZE_FREEONCLOSE |
|
||||
SQLITE_DESERIALIZE_RESIZEABLE);
|
||||
if( xrc ){
|
||||
Tcl_AppendResult(interp, "unable to set MEMDB content", (char*)0);
|
||||
rc = TCL_ERROR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
** $db enable_load_extension BOOLEAN
|
||||
**
|
||||
@@ -2889,6 +2936,39 @@ static int SQLITE_TCLAPI DbObjCmd(
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
** $db serialize ?DATABASE?
|
||||
**
|
||||
** Return a serialization of a database.
|
||||
*/
|
||||
case DB_SERIALIZE: {
|
||||
#ifndef SQLITE_ENABLE_DESERIALIZE
|
||||
Tcl_AppendResult(interp, "MEMDB not available in this build",
|
||||
(char*)0);
|
||||
rc = TCL_ERROR;
|
||||
#else
|
||||
const char *zSchema = objc>=3 ? Tcl_GetString(objv[2]) : "main";
|
||||
sqlite3_int64 sz = 0;
|
||||
unsigned char *pData;
|
||||
if( objc!=2 && objc!=3 ){
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE?");
|
||||
rc = TCL_ERROR;
|
||||
}else{
|
||||
int needFree;
|
||||
pData = sqlite3_serialize(pDb->db, zSchema, &sz, SQLITE_SERIALIZE_NOCOPY);
|
||||
if( pData ){
|
||||
needFree = 0;
|
||||
}else{
|
||||
pData = sqlite3_serialize(pDb->db, zSchema, &sz, 0);
|
||||
needFree = 1;
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pData,sz));
|
||||
if( needFree ) sqlite3_free(pData);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
** $db status (step|sort|autoindex|vmstep)
|
||||
**
|
||||
@@ -3349,6 +3429,24 @@ static int SQLITE_TCLAPI DbObjCmdAdaptor(
|
||||
}
|
||||
#endif /* SQLITE_TCL_NRE */
|
||||
|
||||
/*
|
||||
** Issue the usage message when the "sqlite3" command arguments are
|
||||
** incorrect.
|
||||
*/
|
||||
static int sqliteCmdUsage(
|
||||
Tcl_Interp *interp,
|
||||
Tcl_Obj *const*objv
|
||||
){
|
||||
Tcl_WrongNumArgs(interp, 1, objv,
|
||||
"HANDLE ?FILENAME? ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?"
|
||||
" ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?"
|
||||
#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
|
||||
" ?-key CODECKEY?"
|
||||
#endif
|
||||
);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
** sqlite3 DBNAME FILENAME ?-vfs VFSNAME? ?-key KEY? ?-readonly BOOLEAN?
|
||||
** ?-create BOOLEAN? ?-nomutex BOOLEAN?
|
||||
@@ -3374,7 +3472,7 @@ static int SQLITE_TCLAPI DbMain(
|
||||
const char *zArg;
|
||||
char *zErrMsg;
|
||||
int i;
|
||||
const char *zFile;
|
||||
const char *zFile = 0;
|
||||
const char *zVfs = 0;
|
||||
int flags;
|
||||
Tcl_DString translatedFilename;
|
||||
@@ -3385,7 +3483,7 @@ static int SQLITE_TCLAPI DbMain(
|
||||
int rc;
|
||||
|
||||
/* In normal use, each TCL interpreter runs in a single thread. So
|
||||
** by default, we can turn of mutexing on SQLite database connections.
|
||||
** by default, we can turn off mutexing on SQLite database connections.
|
||||
** However, for testing purposes it is useful to have mutexes turned
|
||||
** on. So, by default, mutexes default off. But if compiled with
|
||||
** SQLITE_TCL_DEFAULT_FULLMUTEX then mutexes default on.
|
||||
@@ -3414,18 +3512,26 @@ static int SQLITE_TCLAPI DbMain(
|
||||
#endif
|
||||
return TCL_OK;
|
||||
}
|
||||
if( zArg[0]=='-' ) return sqliteCmdUsage(interp, objv);
|
||||
}
|
||||
for(i=3; i+1<objc; i+=2){
|
||||
for(i=2; i<objc; i++){
|
||||
zArg = Tcl_GetString(objv[i]);
|
||||
if( zArg[0]!='-' ){
|
||||
if( zFile!=0 ) return sqliteCmdUsage(interp, objv);
|
||||
zFile = zArg;
|
||||
continue;
|
||||
}
|
||||
if( i==objc-1 ) return sqliteCmdUsage(interp, objv);
|
||||
i++;
|
||||
if( strcmp(zArg,"-key")==0 ){
|
||||
#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
|
||||
pKey = Tcl_GetByteArrayFromObj(objv[i+1], &nKey);
|
||||
pKey = Tcl_GetByteArrayFromObj(objv[i], &nKey);
|
||||
#endif
|
||||
}else if( strcmp(zArg, "-vfs")==0 ){
|
||||
zVfs = Tcl_GetString(objv[i+1]);
|
||||
zVfs = Tcl_GetString(objv[i]);
|
||||
}else if( strcmp(zArg, "-readonly")==0 ){
|
||||
int b;
|
||||
if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
|
||||
if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
|
||||
if( b ){
|
||||
flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
|
||||
flags |= SQLITE_OPEN_READONLY;
|
||||
@@ -3435,7 +3541,7 @@ static int SQLITE_TCLAPI DbMain(
|
||||
}
|
||||
}else if( strcmp(zArg, "-create")==0 ){
|
||||
int b;
|
||||
if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
|
||||
if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
|
||||
if( b && (flags & SQLITE_OPEN_READONLY)==0 ){
|
||||
flags |= SQLITE_OPEN_CREATE;
|
||||
}else{
|
||||
@@ -3443,7 +3549,7 @@ static int SQLITE_TCLAPI DbMain(
|
||||
}
|
||||
}else if( strcmp(zArg, "-nomutex")==0 ){
|
||||
int b;
|
||||
if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
|
||||
if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
|
||||
if( b ){
|
||||
flags |= SQLITE_OPEN_NOMUTEX;
|
||||
flags &= ~SQLITE_OPEN_FULLMUTEX;
|
||||
@@ -3452,7 +3558,7 @@ static int SQLITE_TCLAPI DbMain(
|
||||
}
|
||||
}else if( strcmp(zArg, "-fullmutex")==0 ){
|
||||
int b;
|
||||
if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
|
||||
if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
|
||||
if( b ){
|
||||
flags |= SQLITE_OPEN_FULLMUTEX;
|
||||
flags &= ~SQLITE_OPEN_NOMUTEX;
|
||||
@@ -3461,7 +3567,7 @@ static int SQLITE_TCLAPI DbMain(
|
||||
}
|
||||
}else if( strcmp(zArg, "-uri")==0 ){
|
||||
int b;
|
||||
if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
|
||||
if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
|
||||
if( b ){
|
||||
flags |= SQLITE_OPEN_URI;
|
||||
}else{
|
||||
@@ -3472,20 +3578,10 @@ static int SQLITE_TCLAPI DbMain(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
if( objc<3 || (objc&1)!=1 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv,
|
||||
"HANDLE FILENAME ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?"
|
||||
" ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?"
|
||||
#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
|
||||
" ?-key CODECKEY?"
|
||||
#endif
|
||||
);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
zErrMsg = 0;
|
||||
p = (SqliteDb*)Tcl_Alloc( sizeof(*p) );
|
||||
memset(p, 0, sizeof(*p));
|
||||
zFile = Tcl_GetStringFromObj(objv[2], 0);
|
||||
if( zFile==0 ) zFile = "";
|
||||
zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename);
|
||||
rc = sqlite3_open_v2(zFile, &p->db, flags, zVfs);
|
||||
Tcl_DStringFree(&translatedFilename);
|
||||
|
||||
@@ -6992,7 +6992,6 @@ static int SQLITE_TCLAPI tclLoadStaticExtensionCmd(
|
||||
#ifdef SQLITE_HAVE_ZLIB
|
||||
extern int sqlite3_zipfile_init(sqlite3*,char**,const sqlite3_api_routines*);
|
||||
#endif
|
||||
extern int sqlite3_zonefile_init(sqlite3*,char**,const sqlite3_api_routines*);
|
||||
static const struct {
|
||||
const char *zExtName;
|
||||
int (*pInit)(sqlite3*,char**,const sqlite3_api_routines*);
|
||||
@@ -7017,7 +7016,6 @@ static int SQLITE_TCLAPI tclLoadStaticExtensionCmd(
|
||||
#ifdef SQLITE_HAVE_ZLIB
|
||||
{ "zipfile", sqlite3_zipfile_init },
|
||||
#endif
|
||||
{ "zonefile", sqlite3_zonefile_init },
|
||||
};
|
||||
sqlite3 *db;
|
||||
const char *zName;
|
||||
|
||||
@@ -148,6 +148,12 @@ static void set_options(Tcl_Interp *interp){
|
||||
Tcl_SetVar2(interp, "sqlite_options", "hiddencolumns", "0", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_ENABLE_DESERIALIZE
|
||||
Tcl_SetVar2(interp, "sqlite_options", "deserialize", "1", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
Tcl_SetVar2(interp, "sqlite_options", "deserialize", "0", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_ENABLE_MEMSYS3
|
||||
Tcl_SetVar2(interp, "sqlite_options", "mem3", "1", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
@@ -501,6 +507,12 @@ Tcl_SetVar2(interp, "sqlite_options", "long_double",
|
||||
|
||||
Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY);
|
||||
|
||||
#ifdef SQLITE_ENABLE_NULL_TRIM
|
||||
Tcl_SetVar2(interp, "sqlite_options", "null_trim", "1", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
Tcl_SetVar2(interp, "sqlite_options", "null_trim", "0", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_OMIT_OR_OPTIMIZATION
|
||||
Tcl_SetVar2(interp, "sqlite_options", "or_opt", "0", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
|
||||
@@ -1383,6 +1383,7 @@ static int SQLITE_TCLAPI test_db_status(
|
||||
{ "CACHE_WRITE", SQLITE_DBSTATUS_CACHE_WRITE },
|
||||
{ "DEFERRED_FKS", SQLITE_DBSTATUS_DEFERRED_FKS },
|
||||
{ "CACHE_USED_SHARED", SQLITE_DBSTATUS_CACHE_USED_SHARED },
|
||||
{ "CACHE_SPILL", SQLITE_DBSTATUS_CACHE_SPILL },
|
||||
};
|
||||
Tcl_Obj *pResult;
|
||||
if( objc!=4 ){
|
||||
|
||||
@@ -292,6 +292,11 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
|
||||
sqlite3TreeViewLine(pView,"NULL");
|
||||
break;
|
||||
}
|
||||
case TK_TRUEFALSE: {
|
||||
sqlite3TreeViewLine(pView,
|
||||
sqlite3ExprTruthValue(pExpr) ? "TRUE" : "FALSE");
|
||||
break;
|
||||
}
|
||||
#ifndef SQLITE_OMIT_BLOB_LITERAL
|
||||
case TK_BLOB: {
|
||||
sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken);
|
||||
@@ -348,6 +353,19 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
|
||||
case TK_ISNULL: zUniOp = "ISNULL"; break;
|
||||
case TK_NOTNULL: zUniOp = "NOTNULL"; break;
|
||||
|
||||
case TK_TRUTH: {
|
||||
int x;
|
||||
const char *azOp[] = {
|
||||
"IS-FALSE", "IS-TRUE", "IS-NOT-FALSE", "IS-NOT-TRUE"
|
||||
};
|
||||
assert( pExpr->op2==TK_IS || pExpr->op2==TK_ISNOT );
|
||||
assert( pExpr->pRight );
|
||||
assert( pExpr->pRight->op==TK_TRUEFALSE );
|
||||
x = (pExpr->op2==TK_ISNOT)*2 + sqlite3ExprTruthValue(pExpr->pRight);
|
||||
zUniOp = azOp[x];
|
||||
break;
|
||||
}
|
||||
|
||||
case TK_SPAN: {
|
||||
sqlite3TreeViewLine(pView, "SPAN %Q", pExpr->u.zToken);
|
||||
sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
|
||||
|
||||
+2
-2
@@ -39,8 +39,8 @@ static int execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
|
||||
while( SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){
|
||||
const char *zSubSql = (const char*)sqlite3_column_text(pStmt,0);
|
||||
assert( sqlite3_strnicmp(zSql,"SELECT",6)==0 );
|
||||
if( zSubSql ){
|
||||
assert( zSubSql[0]!='S' );
|
||||
assert( sqlite3_strnicmp(zSubSql,"SELECT",6)!=0 || CORRUPT_DB );
|
||||
if( zSubSql && zSubSql[0]!='S' ){
|
||||
rc = execSql(db, pzErrMsg, zSubSql);
|
||||
if( rc!=SQLITE_OK ) break;
|
||||
}
|
||||
|
||||
+47
-33
@@ -648,7 +648,7 @@ int sqlite3VdbeExec(
|
||||
|
||||
assert( pOp>=aOp && pOp<&aOp[p->nOp]);
|
||||
#ifdef VDBE_PROFILE
|
||||
start = sqlite3Hwtime();
|
||||
start = sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime();
|
||||
#endif
|
||||
nVmStep++;
|
||||
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
|
||||
@@ -2172,18 +2172,8 @@ case OP_Or: { /* same as TK_OR, in1, in2, out3 */
|
||||
int v1; /* Left operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
|
||||
int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
|
||||
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
if( pIn1->flags & MEM_Null ){
|
||||
v1 = 2;
|
||||
}else{
|
||||
v1 = sqlite3VdbeIntValue(pIn1)!=0;
|
||||
}
|
||||
pIn2 = &aMem[pOp->p2];
|
||||
if( pIn2->flags & MEM_Null ){
|
||||
v2 = 2;
|
||||
}else{
|
||||
v2 = sqlite3VdbeIntValue(pIn2)!=0;
|
||||
}
|
||||
v1 = sqlite3VdbeBooleanValue(&aMem[pOp->p1], 2);
|
||||
v2 = sqlite3VdbeBooleanValue(&aMem[pOp->p2], 2);
|
||||
if( pOp->opcode==OP_And ){
|
||||
static const unsigned char and_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 };
|
||||
v1 = and_logic[v1*3+v2];
|
||||
@@ -2201,6 +2191,35 @@ case OP_Or: { /* same as TK_OR, in1, in2, out3 */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: IsTrue P1 P2 P3 P4 *
|
||||
** Synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4
|
||||
**
|
||||
** This opcode implements the IS TRUE, IS FALSE, IS NOT TRUE, and
|
||||
** IS NOT FALSE operators.
|
||||
**
|
||||
** Interpret the value in register P1 as a boolean value. Store that
|
||||
** boolean (a 0 or 1) in register P2. Or if the value in register P1 is
|
||||
** NULL, then the P3 is stored in register P2. Invert the answer if P4
|
||||
** is 1.
|
||||
**
|
||||
** The logic is summarized like this:
|
||||
**
|
||||
** <ul>
|
||||
** <li> If P3==0 and P4==0 then r[P2] := r[P1] IS TRUE
|
||||
** <li> If P3==1 and P4==1 then r[P2] := r[P1] IS FALSE
|
||||
** <li> If P3==0 and P4==1 then r[P2] := r[P1] IS NOT TRUE
|
||||
** <li> If P3==1 and P4==0 then r[P2] := r[P1] IS NOT FALSE
|
||||
** </ul>
|
||||
*/
|
||||
case OP_IsTrue: { /* in1, out2 */
|
||||
assert( pOp->p4type==P4_INT32 );
|
||||
assert( pOp->p4.i==0 || pOp->p4.i==1 );
|
||||
assert( pOp->p3==0 || pOp->p3==1 );
|
||||
sqlite3VdbeMemSetInt64(&aMem[pOp->p2],
|
||||
sqlite3VdbeBooleanValue(&aMem[pOp->p1], pOp->p3) ^ pOp->p4.i);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: Not P1 P2 * * *
|
||||
** Synopsis: r[P2]= !r[P1]
|
||||
**
|
||||
@@ -2211,10 +2230,10 @@ case OP_Or: { /* same as TK_OR, in1, in2, out3 */
|
||||
case OP_Not: { /* same as TK_NOT, in1, out2 */
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
pOut = &aMem[pOp->p2];
|
||||
sqlite3VdbeMemSetNull(pOut);
|
||||
if( (pIn1->flags & MEM_Null)==0 ){
|
||||
pOut->flags = MEM_Int;
|
||||
pOut->u.i = !sqlite3VdbeIntValue(pIn1);
|
||||
sqlite3VdbeMemSetInt64(pOut, !sqlite3VdbeBooleanValue(pIn1,0));
|
||||
}else{
|
||||
sqlite3VdbeMemSetNull(pOut);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2281,30 +2300,25 @@ case OP_Once: { /* jump */
|
||||
** is considered true if it is numeric and non-zero. If the value
|
||||
** in P1 is NULL then take the jump if and only if P3 is non-zero.
|
||||
*/
|
||||
case OP_If: { /* jump, in1 */
|
||||
int c;
|
||||
c = sqlite3VdbeBooleanValue(&aMem[pOp->p1], pOp->p3);
|
||||
VdbeBranchTaken(c!=0, 2);
|
||||
if( c ) goto jump_to_p2;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: IfNot P1 P2 P3 * *
|
||||
**
|
||||
** Jump to P2 if the value in register P1 is False. The value
|
||||
** is considered false if it has a numeric value of zero. If the value
|
||||
** in P1 is NULL then take the jump if and only if P3 is non-zero.
|
||||
*/
|
||||
case OP_If: /* jump, in1 */
|
||||
case OP_IfNot: { /* jump, in1 */
|
||||
int c;
|
||||
pIn1 = &aMem[pOp->p1];
|
||||
if( pIn1->flags & MEM_Null ){
|
||||
c = pOp->p3;
|
||||
}else{
|
||||
if( pIn1->flags & MEM_Int ){
|
||||
c = pIn1->u.i!=0;
|
||||
}else{
|
||||
c = sqlite3VdbeRealValue(pIn1)!=0.0;
|
||||
}
|
||||
if( pOp->opcode==OP_IfNot ) c = !c;
|
||||
}
|
||||
c = !sqlite3VdbeBooleanValue(&aMem[pOp->p1], !pOp->p3);
|
||||
VdbeBranchTaken(c!=0, 2);
|
||||
if( c ){
|
||||
goto jump_to_p2;
|
||||
}
|
||||
if( c ) goto jump_to_p2;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2365,7 +2379,7 @@ case OP_IfNullRow: { /* jump */
|
||||
** P2 is the column number for the argument to the sqlite_offset() function.
|
||||
** This opcode does not use P2 itself, but the P2 value is used by the
|
||||
** code generator. The P1, P2, and P3 operands to this opcode are the
|
||||
** as as for OP_Column.
|
||||
** same as for OP_Column.
|
||||
**
|
||||
** This opcode is only available if SQLite is compiled with the
|
||||
** -DSQLITE_ENABLE_OFFSET_SQL_FUNC option.
|
||||
@@ -7233,7 +7247,7 @@ default: { /* This is really OP_Noop and OP_Explain */
|
||||
|
||||
#ifdef VDBE_PROFILE
|
||||
{
|
||||
u64 endTime = sqlite3Hwtime();
|
||||
u64 endTime = sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime();
|
||||
if( endTime>start ) pOrigOp->cycles += endTime - start;
|
||||
pOrigOp->cnt++;
|
||||
}
|
||||
|
||||
@@ -486,6 +486,7 @@ int sqlite3VdbeMemStringify(Mem*, u8, u8);
|
||||
i64 sqlite3VdbeIntValue(Mem*);
|
||||
int sqlite3VdbeMemIntegerify(Mem*);
|
||||
double sqlite3VdbeRealValue(Mem*);
|
||||
int sqlite3VdbeBooleanValue(Mem*, int ifNull);
|
||||
void sqlite3VdbeIntegerAffinity(Mem*);
|
||||
int sqlite3VdbeMemRealify(Mem*);
|
||||
int sqlite3VdbeMemNumerify(Mem*);
|
||||
|
||||
+3
-1
@@ -1668,7 +1668,9 @@ int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
|
||||
Vdbe *pVdbe = (Vdbe*)pStmt;
|
||||
u32 v;
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !pStmt ){
|
||||
if( !pStmt
|
||||
|| (op!=SQLITE_STMTSTATUS_MEMUSED && (op<0||op>=ArraySize(pVdbe->aCounter)))
|
||||
){
|
||||
(void)SQLITE_MISUSE_BKPT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -572,6 +572,16 @@ double sqlite3VdbeRealValue(Mem *pMem){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Return 1 if pMem represents true, and return 0 if pMem represents false.
|
||||
** Return the value ifNull if pMem is NULL.
|
||||
*/
|
||||
int sqlite3VdbeBooleanValue(Mem *pMem, int ifNull){
|
||||
if( pMem->flags & MEM_Int ) return pMem->u.i!=0;
|
||||
if( pMem->flags & MEM_Null ) return ifNull;
|
||||
return sqlite3VdbeRealValue(pMem)!=0.0;
|
||||
}
|
||||
|
||||
/*
|
||||
** The MEM structure is already a MEM_Real. Try to also make it a
|
||||
** MEM_Int if we can.
|
||||
|
||||
@@ -554,7 +554,11 @@ struct WalIterator {
|
||||
** page and SQLITE_OK is returned. If an error (an OOM or VFS error) occurs,
|
||||
** then an SQLite error code is returned and *ppPage is set to 0.
|
||||
*/
|
||||
static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
|
||||
static SQLITE_NOINLINE int walIndexPageRealloc(
|
||||
Wal *pWal, /* The WAL context */
|
||||
int iPage, /* The page we seek */
|
||||
volatile u32 **ppPage /* Write the page pointer here */
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
/* Enlarge the pWal->apWiData[] array if required */
|
||||
@@ -573,21 +577,20 @@ static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
|
||||
}
|
||||
|
||||
/* Request a pointer to the required page from the VFS */
|
||||
if( pWal->apWiData[iPage]==0 ){
|
||||
if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){
|
||||
pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ);
|
||||
if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM_BKPT;
|
||||
}else{
|
||||
rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ,
|
||||
pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
|
||||
);
|
||||
assert( pWal->apWiData[iPage]!=0 || rc!=SQLITE_OK || pWal->writeLock==0 );
|
||||
testcase( pWal->apWiData[iPage]==0 && rc==SQLITE_OK );
|
||||
if( (rc&0xff)==SQLITE_READONLY ){
|
||||
pWal->readOnly |= WAL_SHM_RDONLY;
|
||||
if( rc==SQLITE_READONLY ){
|
||||
rc = SQLITE_OK;
|
||||
}
|
||||
assert( pWal->apWiData[iPage]==0 );
|
||||
if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){
|
||||
pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ);
|
||||
if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM_BKPT;
|
||||
}else{
|
||||
rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ,
|
||||
pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
|
||||
);
|
||||
assert( pWal->apWiData[iPage]!=0 || rc!=SQLITE_OK || pWal->writeLock==0 );
|
||||
testcase( pWal->apWiData[iPage]==0 && rc==SQLITE_OK );
|
||||
if( (rc&0xff)==SQLITE_READONLY ){
|
||||
pWal->readOnly |= WAL_SHM_RDONLY;
|
||||
if( rc==SQLITE_READONLY ){
|
||||
rc = SQLITE_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -596,6 +599,16 @@ static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
|
||||
assert( iPage==0 || *ppPage || rc!=SQLITE_OK );
|
||||
return rc;
|
||||
}
|
||||
static int walIndexPage(
|
||||
Wal *pWal, /* The WAL context */
|
||||
int iPage, /* The page we seek */
|
||||
volatile u32 **ppPage /* Write the page pointer here */
|
||||
){
|
||||
if( pWal->nWiData<=iPage || (*ppPage = pWal->apWiData[iPage])==0 ){
|
||||
return walIndexPageRealloc(pWal, iPage, ppPage);
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return a pointer to the WalCkptInfo structure in the wal-index.
|
||||
@@ -1572,8 +1585,9 @@ static void walIteratorFree(WalIterator *p){
|
||||
|
||||
/*
|
||||
** Construct a WalInterator object that can be used to loop over all
|
||||
** pages in the WAL in ascending order. The caller must hold the checkpoint
|
||||
** lock.
|
||||
** pages in the WAL following frame nBackfill in ascending order. Frames
|
||||
** nBackfill or earlier may be included - excluding them is an optimization
|
||||
** only. The caller must hold the checkpoint lock.
|
||||
**
|
||||
** On success, make *pp point to the newly allocated WalInterator object
|
||||
** return SQLITE_OK. Otherwise, return an error code. If this routine
|
||||
@@ -1582,7 +1596,7 @@ static void walIteratorFree(WalIterator *p){
|
||||
** The calling routine should invoke walIteratorFree() to destroy the
|
||||
** WalIterator object when it has finished with it.
|
||||
*/
|
||||
static int walIteratorInit(Wal *pWal, WalIterator **pp){
|
||||
static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){
|
||||
WalIterator *p; /* Return value */
|
||||
int nSegment; /* Number of segments to merge */
|
||||
u32 iLast; /* Last frame in log */
|
||||
@@ -1619,7 +1633,7 @@ static int walIteratorInit(Wal *pWal, WalIterator **pp){
|
||||
rc = SQLITE_NOMEM_BKPT;
|
||||
}
|
||||
|
||||
for(i=0; rc==SQLITE_OK && i<nSegment; i++){
|
||||
for(i=walFramePage(nBackfill+1); rc==SQLITE_OK && i<nSegment; i++){
|
||||
volatile ht_slot *aHash;
|
||||
u32 iZero;
|
||||
volatile u32 *aPgno;
|
||||
@@ -1653,6 +1667,7 @@ static int walIteratorInit(Wal *pWal, WalIterator **pp){
|
||||
|
||||
if( rc!=SQLITE_OK ){
|
||||
walIteratorFree(p);
|
||||
p = 0;
|
||||
}
|
||||
*pp = p;
|
||||
return rc;
|
||||
@@ -1775,13 +1790,6 @@ static int walCheckpoint(
|
||||
pInfo = walCkptInfo(pWal);
|
||||
if( pInfo->nBackfill<pWal->hdr.mxFrame ){
|
||||
|
||||
/* Allocate the iterator */
|
||||
rc = walIteratorInit(pWal, &pIter);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
assert( pIter );
|
||||
|
||||
/* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
|
||||
** in the SQLITE_CHECKPOINT_PASSIVE mode. */
|
||||
assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
|
||||
@@ -1818,7 +1826,13 @@ static int walCheckpoint(
|
||||
}
|
||||
}
|
||||
|
||||
if( pInfo->nBackfill<mxSafeFrame
|
||||
/* Allocate the iterator */
|
||||
if( pInfo->nBackfill<mxSafeFrame ){
|
||||
rc = walIteratorInit(pWal, pInfo->nBackfill, &pIter);
|
||||
assert( rc==SQLITE_OK || pIter==0 );
|
||||
}
|
||||
|
||||
if( pIter
|
||||
&& (rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(0),1))==SQLITE_OK
|
||||
){
|
||||
i64 nSize; /* Current size of database file */
|
||||
@@ -2868,7 +2882,7 @@ int sqlite3WalFindFrame(
|
||||
** table after the current read-transaction had started.
|
||||
*/
|
||||
iMinHash = walFramePage(pWal->minFrame);
|
||||
for(iHash=walFramePage(iLast); iHash>=iMinHash && iRead==0; iHash--){
|
||||
for(iHash=walFramePage(iLast); iHash>=iMinHash; iHash--){
|
||||
volatile ht_slot *aHash; /* Pointer to hash table */
|
||||
volatile u32 *aPgno; /* Pointer to array of page numbers */
|
||||
u32 iZero; /* Frame number corresponding to aPgno[0] */
|
||||
@@ -2891,6 +2905,7 @@ int sqlite3WalFindFrame(
|
||||
return SQLITE_CORRUPT_BKPT;
|
||||
}
|
||||
}
|
||||
if( iRead ) break;
|
||||
}
|
||||
|
||||
#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
|
||||
|
||||
+9
-1
@@ -1395,7 +1395,15 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
if( sqlite3ExprIsVector(pX->pRight) ){
|
||||
r1 = rTemp = sqlite3GetTempReg(pParse);
|
||||
codeExprOrVector(pParse, pX->pRight, r1, 1);
|
||||
op = aMoveOp[(pX->op - TK_GT) | 0x0001];
|
||||
testcase( pX->op==TK_GT );
|
||||
testcase( pX->op==TK_GE );
|
||||
testcase( pX->op==TK_LT );
|
||||
testcase( pX->op==TK_LE );
|
||||
op = aMoveOp[((pX->op - TK_GT - 1) & 0x3) | 0x1];
|
||||
assert( pX->op!=TK_GT || op==OP_SeekGE );
|
||||
assert( pX->op!=TK_GE || op==OP_SeekGE );
|
||||
assert( pX->op!=TK_LT || op==OP_SeekLE );
|
||||
assert( pX->op!=TK_LE || op==OP_SeekLE );
|
||||
}else{
|
||||
r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp);
|
||||
disableTerm(pLevel, pStart);
|
||||
|
||||
+1
-1
@@ -1291,7 +1291,7 @@ static void exprAnalyze(
|
||||
exprAnalyze(pSrc, pWC, idxNew);
|
||||
}
|
||||
pTerm = &pWC->a[idxTerm];
|
||||
pTerm->wtFlags = TERM_CODED|TERM_VIRTUAL; /* Disable the original */
|
||||
pTerm->wtFlags |= TERM_CODED|TERM_VIRTUAL; /* Disable the original */
|
||||
pTerm->eOperator = 0;
|
||||
}
|
||||
|
||||
|
||||
+5
-1
@@ -352,7 +352,11 @@ ifcapable pragma {
|
||||
# Since the following tests (crash8-5.*) rely upon being able
|
||||
# to copy a file while open, they will not work on Windows.
|
||||
#
|
||||
if {$::tcl_platform(platform)=="unix"} {
|
||||
# They also depend on being able to copy the journal file, which
|
||||
# is not created on F2FS file-systems that support atomic
|
||||
# write. So do not run these tests in that case either.
|
||||
#
|
||||
if {$::tcl_platform(platform)=="unix" && [atomic_batch_write test.db]==0 } {
|
||||
for {set i 1} {$i < 10} {incr i} {
|
||||
catch { db close }
|
||||
forcedelete test.db test.db-journal
|
||||
|
||||
@@ -415,4 +415,43 @@ ifcapable shared_cache {
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test that passing an out-of-range value to sqlite3_stmt_status does
|
||||
# not cause a crash.
|
||||
reset_db
|
||||
do_execsql_test 5.0 {
|
||||
CREATE TABLE t1(x, y);
|
||||
INSERT INTO t1 VALUES(1, 2);
|
||||
INSERT INTO t1 VALUES(3, 4);
|
||||
}
|
||||
|
||||
do_test 5.1 {
|
||||
set ::stmt [sqlite3_prepare db "SELECT * FROM t1" -1 dummy]
|
||||
sqlite3_step $::stmt
|
||||
sqlite3_step $::stmt
|
||||
sqlite3_step $::stmt
|
||||
sqlite3_reset $::stmt
|
||||
} {SQLITE_OK}
|
||||
|
||||
ifcapable api_armor {
|
||||
do_test 5.2 { sqlite3_stmt_status $::stmt -1 0 } 0
|
||||
}
|
||||
do_test 5.3 { sqlite3_stmt_status $::stmt 0 0 } 0
|
||||
do_test 5.4 {
|
||||
expr [sqlite3_stmt_status $::stmt 99 0]>0
|
||||
} 1
|
||||
foreach {tn id res} {
|
||||
1 SQLITE_STMTSTATUS_MEMUSED 1
|
||||
2 SQLITE_STMTSTATUS_FULLSCAN_STEP 1
|
||||
3 SQLITE_STMTSTATUS_SORT 0
|
||||
4 SQLITE_STMTSTATUS_AUTOINDEX 0
|
||||
5 SQLITE_STMTSTATUS_VM_STEP 1
|
||||
6 SQLITE_STMTSTATUS_REPREPARE 0
|
||||
7 SQLITE_STMTSTATUS_RUN 1
|
||||
} {
|
||||
if {$tn==2} breakpoint
|
||||
do_test 5.5.$tn { expr [sqlite3_stmt_status $::stmt $id 0]>0 } $res
|
||||
}
|
||||
|
||||
sqlite3_finalize $::stmt
|
||||
finish_test
|
||||
|
||||
@@ -37,6 +37,10 @@ proc db_write {db {reset 0}} {
|
||||
sqlite3_db_status $db CACHE_WRITE $reset
|
||||
}
|
||||
|
||||
proc db_spill {db {reset 0}} {
|
||||
sqlite3_db_status $db CACHE_SPILL $reset
|
||||
}
|
||||
|
||||
do_test 1.1 {
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
@@ -98,5 +102,14 @@ do_test 2.7 {
|
||||
} {0 4 0}
|
||||
do_test 2.8 { db_write db 1 } {0 4 0}
|
||||
do_test 2.9 { db_write db 0 } {0 0 0}
|
||||
|
||||
do_test 3.0 { db_spill db 1 } {0 0 0}
|
||||
do_test 3.1 { db_spill db 0 } {0 0 0}
|
||||
do_execsql_test 3.2 {
|
||||
PRAGMA journal_mode=DELETE;
|
||||
PRAGMA cache_size=3;
|
||||
UPDATE t1 SET b=randomblob(1000);
|
||||
} {delete}
|
||||
do_test 3.2 { db_spill db 0 } {0 8 0}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -977,6 +977,63 @@ do_execsql_test expr-13.9 {
|
||||
SELECT '' <= "";
|
||||
} {1}
|
||||
|
||||
# 2018-02-26. Ticket https://www.sqlite.org/src/tktview/36fae083b450e3af85
|
||||
#
|
||||
do_execsql_test expr-14.1 {
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1(x);
|
||||
INSERT INTO t1 VALUES(0),(1),(NULL),(0.5),('1x'),('0x');
|
||||
SELECT count(*) FROM t1
|
||||
WHERE (x OR (8==9)) != (CASE WHEN x THEN 1 ELSE 0 END);
|
||||
} {0}
|
||||
do_execsql_test expr-14.2 {
|
||||
SELECT count(*) FROM t1
|
||||
WHERE (x OR (8==9)) != (NOT NOT x);
|
||||
} {0}
|
||||
do_execsql_test expr-14.3 {
|
||||
SELECT sum(NOT x) FROM t1
|
||||
WHERE x
|
||||
} {0}
|
||||
do_execsql_test expr-14.4 {
|
||||
SELECT sum(CASE WHEN x THEN 0 ELSE 1 END) FROM t1
|
||||
WHERE x
|
||||
} {0}
|
||||
|
||||
|
||||
foreach {tn val} [list 1 NaN 2 -NaN 3 NaN0 4 -NaN0 5 Inf 6 -Inf] {
|
||||
do_execsql_test expr-15.$tn.1 {
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1(x);
|
||||
INSERT INTO t1 VALUES(0),(1),(NULL),(0.5),('1x'),('0x');
|
||||
}
|
||||
|
||||
do_test expr-15.$tn.2 {
|
||||
set ::STMT [sqlite3_prepare db "INSERT INTO t1 VALUES(?)" -1 TAIL]
|
||||
sqlite3_bind_double $::STMT 1 $val
|
||||
sqlite3_step $::STMT
|
||||
sqlite3_reset $::STMT
|
||||
sqlite3_finalize $::STMT
|
||||
} {SQLITE_OK}
|
||||
|
||||
do_execsql_test expr-15.$tn.3 {
|
||||
SELECT count(*) FROM t1
|
||||
WHERE (x OR (8==9)) != (CASE WHEN x THEN 1 ELSE 0 END);
|
||||
} {0}
|
||||
|
||||
do_execsql_test expr-15.$tn.4 {
|
||||
SELECT count(*) FROM t1
|
||||
WHERE (x OR (8==9)) != (NOT NOT x);
|
||||
} {0}
|
||||
|
||||
do_execsql_test expr-15.$tn.5 {
|
||||
SELECT sum(NOT x) FROM t1
|
||||
WHERE x
|
||||
} {0}
|
||||
|
||||
do_execsql_test expr-15.$tn.6 {
|
||||
SELECT sum(CASE WHEN x THEN 0 ELSE 1 END) FROM t1
|
||||
WHERE x
|
||||
} {0}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -143,4 +143,18 @@ foreach {tn tcl1 tcl2} {
|
||||
eval $tcl2
|
||||
}
|
||||
|
||||
do_execsql_test 4.0 {
|
||||
CREATE VIRTUAL TABLE zt USING fts4(a, b);
|
||||
INSERT INTO zt(rowid, a, b) VALUES(1, 'unus duo', NULL);
|
||||
INSERT INTO zt(rowid, a, b) VALUES(2, NULL, NULL);
|
||||
|
||||
BEGIN;
|
||||
UPDATE zt SET b='septum' WHERE rowid = 1;
|
||||
UPDATE zt SET b='octo' WHERE rowid = 1;
|
||||
COMMIT;
|
||||
|
||||
SELECT count(*) FROM zt_segdir;
|
||||
} {3}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
+19
-2
@@ -22,6 +22,11 @@ ifcapable !offset_sql_func {
|
||||
return
|
||||
}
|
||||
|
||||
set bNullTrim 0
|
||||
ifcapable null_trim {
|
||||
set bNullTrim 1
|
||||
}
|
||||
|
||||
do_execsql_test func6-100 {
|
||||
PRAGMA page_size=4096;
|
||||
PRAGMA auto_vacuum=NONE;
|
||||
@@ -51,6 +56,13 @@ proc loadhex {file} {
|
||||
proc hexrecord {args} {
|
||||
set hdr ""
|
||||
set body ""
|
||||
|
||||
if {$::bNullTrim} {
|
||||
while {[llength $args] && [lindex $args end]=={}} {
|
||||
set args [lrange $args 0 end-1]
|
||||
}
|
||||
}
|
||||
|
||||
foreach x $args {
|
||||
if {$x==""} {
|
||||
append hdr 00
|
||||
@@ -103,12 +115,17 @@ set F [loadhex test.db]
|
||||
db func offrec offrec
|
||||
|
||||
# Test the sanity of the tests.
|
||||
if {$bNullTrim} {
|
||||
set offset 8180
|
||||
} else {
|
||||
set offset 8179
|
||||
}
|
||||
do_execsql_test func6-105 {
|
||||
SELECT sqlite_offset(d) FROM t1 ORDER BY rowid LIMIT 1;
|
||||
} {8179}
|
||||
} $offset
|
||||
do_test func6-106 {
|
||||
set r [hexrecord abc001 1 999 {}]
|
||||
offset_contains_record 8179 $F $r
|
||||
offset_contains_record $offset $F $r
|
||||
} 0
|
||||
|
||||
set z100 [string trim [string repeat "0 " 100]]
|
||||
|
||||
+7
-1
@@ -81,7 +81,13 @@
|
||||
|
||||
#ifdef SQLITE_OSS_FUZZ
|
||||
# include <stddef.h>
|
||||
# include <stdint.h>
|
||||
# if !defined(_MSC_VER)
|
||||
# include <stdint.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
typedef unsigned char uint8_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
# 2018-02-26
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing expressions of the form
|
||||
#
|
||||
# x IS TRUE
|
||||
# x IS FALSE
|
||||
# x IS NOT TRUE
|
||||
# x IS NOT FALSE
|
||||
#
|
||||
# Tests are also included for the use of TRUE and FALSE as
|
||||
# literal values.
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
do_execsql_test istrue-100 {
|
||||
CREATE TABLE t1(x INTEGER PRIMARY KEY, y BOOLEAN);
|
||||
INSERT INTO t1 VALUES(1, true),(2, false),(3, null);
|
||||
SELECT x FROM t1 WHERE y IS TRUE;
|
||||
} {1}
|
||||
do_execsql_test istrue-110 {
|
||||
SELECT x FROM t1 WHERE y IS FALSE;
|
||||
} {2}
|
||||
do_execsql_test istrue-120 {
|
||||
SELECT x FROM t1 WHERE y IS NULL;
|
||||
} {3}
|
||||
do_execsql_test istrue-130 {
|
||||
SELECT x FROM t1 WHERE y IS NOT TRUE;
|
||||
} {2 3}
|
||||
do_execsql_test istrue-140 {
|
||||
SELECT x FROM t1 WHERE y IS NOT FALSE;
|
||||
} {1 3}
|
||||
do_execsql_test istrue-150 {
|
||||
SELECT x FROM t1 WHERE y IS NOT NULL;
|
||||
} {1 2}
|
||||
unset -nocomplain X
|
||||
set X 9
|
||||
do_execsql_test istrue-160 {
|
||||
SELECT x FROM t1 WHERE y IS TRUE OR (8==$X)
|
||||
} {1}
|
||||
do_execsql_test istrue-170 {
|
||||
SELECT x FROM t1 WHERE y IS FALSE OR (8==$X)
|
||||
} {2}
|
||||
do_execsql_test istrue-180 {
|
||||
SELECT x FROM t1 WHERE y IS NULL OR (8==$X);
|
||||
} {3}
|
||||
do_execsql_test istrue-190 {
|
||||
SELECT x FROM t1 WHERE y IS NOT TRUE OR (8==$X);
|
||||
} {2 3}
|
||||
do_execsql_test istrue-200 {
|
||||
SELECT x FROM t1 WHERE y IS NOT FALSE OR (8==$X);
|
||||
} {1 3}
|
||||
do_execsql_test istrue-210 {
|
||||
SELECT x FROM t1 WHERE y IS NOT NULL OR (8==$X);
|
||||
} {1 2}
|
||||
|
||||
do_execsql_test istrue-300 {
|
||||
SELECT x,
|
||||
y IS TRUE, y IS FALSE, y is NULL,
|
||||
y IS NOT TRUE, y IS NOT FALSE, y IS NOT NULL, '|'
|
||||
FROM t1 ORDER BY x;
|
||||
} {1 1 0 0 0 1 1 | 2 0 1 0 1 0 1 | 3 0 0 1 1 1 0 |}
|
||||
|
||||
do_execsql_test istrue-400 {
|
||||
SELECT x FROM t1 WHERE true;
|
||||
} {1 2 3}
|
||||
do_execsql_test istrue-410 {
|
||||
SELECT x FROM t1 WHERE false;
|
||||
} {}
|
||||
|
||||
do_execsql_test istrue-500 {
|
||||
CREATE TABLE t2(
|
||||
a INTEGER PRIMARY KEY,
|
||||
b BOOLEAN DEFAULT true,
|
||||
c BOOLEAN DEFAULT(true),
|
||||
d BOOLEAN DEFAULT false,
|
||||
e BOOLEAN DEFAULT(false)
|
||||
);
|
||||
INSERT INTO t2 DEFAULT VALUES;
|
||||
SELECT * FROM t2;
|
||||
} {1 1 1 0 0}
|
||||
do_execsql_test istrue-510 {
|
||||
DROP TABLE t2;
|
||||
CREATE TABLE t2(
|
||||
a INTEGER PRIMARY KEY,
|
||||
b BOOLEAN DEFAULT(not true),
|
||||
c BOOLEAN DEFAULT(not false)
|
||||
);
|
||||
INSERT INTO t2(a) VALUES(99);
|
||||
SELECT * FROM t2;
|
||||
} {99 0 1}
|
||||
do_execsql_test istrue-520 {
|
||||
DROP TABLE t2;
|
||||
CREATE TABLE t2(
|
||||
a INTEGER PRIMARY KEY,
|
||||
b BOOLEAN CHECK(b IS TRUE),
|
||||
c BOOLEAN CHECK(c IS FALSE),
|
||||
d BOOLEAN CHECK(d IS NOT TRUE),
|
||||
e BOOLEAN CHECK(e IS NOT FALSE)
|
||||
);
|
||||
INSERT INTO t2 VALUES(1,true,false,null,null);
|
||||
SELECT * FROM t2;
|
||||
} {1 1 0 {} {}}
|
||||
do_catchsql_test istrue-521 {
|
||||
INSERT INTO t2 VALUES(2,false,false,null,null);
|
||||
} {1 {CHECK constraint failed: t2}}
|
||||
do_catchsql_test istrue-522 {
|
||||
INSERT INTO t2 VALUES(2,true,true,null,null);
|
||||
} {1 {CHECK constraint failed: t2}}
|
||||
do_catchsql_test istrue-523 {
|
||||
INSERT INTO t2 VALUES(2,true,false,true,null);
|
||||
} {1 {CHECK constraint failed: t2}}
|
||||
do_catchsql_test istrue-524 {
|
||||
INSERT INTO t2 VALUES(2,true,false,null,false);
|
||||
} {1 {CHECK constraint failed: t2}}
|
||||
|
||||
finish_test
|
||||
+4
-2
@@ -132,7 +132,9 @@ static const char zHelp[] =
|
||||
# define access _access
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#if !defined(_MSC_VER)
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
** The following macros are used to cast pointers to integers and
|
||||
@@ -557,7 +559,7 @@ static int exportMain(int argc, char **argv){
|
||||
iKey/10000, (iKey/100)%100, iKey%100);
|
||||
}
|
||||
out = fopen(zFN, "wb");
|
||||
nWrote = fwrite(pData, 1, nData, out);
|
||||
nWrote = fwrite(pData, 1, (size_t)nData, out);
|
||||
fclose(out);
|
||||
printf("\r%s ", zTail); fflush(stdout);
|
||||
if( nWrote!=nData ){
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
# 2018-01-02
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this file is the "memdb" VFS
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix memdb1
|
||||
do_not_use_codec
|
||||
|
||||
ifcapable !deserialize {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
# Create a MEMDB and populate it with some dummy data.
|
||||
# Then extract the database into the $::db1 variable.
|
||||
# Verify that the size of $::db1 is the same as the size of
|
||||
# the database.
|
||||
#
|
||||
unset -nocomplain db1
|
||||
unset -nocomplain sz1
|
||||
unset -nocomplain pgsz
|
||||
do_test 100 {
|
||||
db eval {
|
||||
CREATE TABLE t1(a,b);
|
||||
INSERT INTO t1 VALUES(1,2);
|
||||
}
|
||||
set ::pgsz [db one {PRAGMA page_size}]
|
||||
set ::sz1 [expr {$::pgsz*[db one {PRAGMA page_count}]}]
|
||||
set ::db1 [db serialize]
|
||||
expr {[string length $::db1]==$::sz1}
|
||||
} 1
|
||||
set fd [open db1.db wb]
|
||||
puts -nonewline $fd $db1
|
||||
close $fd
|
||||
|
||||
# Create a new MEMDB and initialize it to the content of $::db1
|
||||
# Verify that the content is the same.
|
||||
#
|
||||
db close
|
||||
sqlite3 db
|
||||
db deserialize $db1
|
||||
do_execsql_test 110 {
|
||||
SELECT * FROM t1;
|
||||
} {1 2}
|
||||
|
||||
# What happens when we try to VACUUM a MEMDB database?
|
||||
#
|
||||
do_execsql_test 120 {
|
||||
VACUUM;
|
||||
} {}
|
||||
do_execsql_test 130 {
|
||||
CREATE TABLE t2(x, y);
|
||||
WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100)
|
||||
INSERT INTO t2(x, y) SELECT x, randomblob(1000) FROM c;
|
||||
DROP TABLE t2;
|
||||
PRAGMA page_count;
|
||||
} {116}
|
||||
do_execsql_test 140 {
|
||||
VACUUM;
|
||||
PRAGMA page_count;
|
||||
} {2}
|
||||
|
||||
# Build a largish on-disk database and serialize it. Verify that the
|
||||
# serialization works.
|
||||
#
|
||||
db close
|
||||
forcedelete test.db
|
||||
sqlite3 db test.db
|
||||
do_execsql_test 200 {
|
||||
CREATE TABLE t3(x, y);
|
||||
WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<400)
|
||||
INSERT INTO t3(x, y) SELECT x, randomblob(1000) FROM c;
|
||||
PRAGMA quick_check;
|
||||
} {ok}
|
||||
set fd [open test.db rb]
|
||||
unset -nocomplain direct
|
||||
set direct [read $fd]
|
||||
close $fd
|
||||
do_test 210 {
|
||||
string length [db serialize]
|
||||
} [string length $direct]
|
||||
do_test 220 {
|
||||
db eval {ATTACH ':memory:' AS aux1}
|
||||
db deserialize aux1 $::direct
|
||||
db eval {
|
||||
SELECT x, y FROM main.t3 EXCEPT SELECT x, y FROM aux1.t3;
|
||||
}
|
||||
} {}
|
||||
unset -nocomplain direct
|
||||
|
||||
# Do the same with a :memory: database.
|
||||
#
|
||||
db close
|
||||
sqlite3 db :memory:
|
||||
do_execsql_test 300 {
|
||||
CREATE TABLE t3(x, y);
|
||||
WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<400)
|
||||
INSERT INTO t3(x, y) SELECT x, randomblob(1000) FROM c;
|
||||
PRAGMA quick_check;
|
||||
} {ok}
|
||||
do_test 310 {
|
||||
db eval {ATTACH ':memory:' AS aux1}
|
||||
db deserialize aux1 [db serialize main]
|
||||
db eval {
|
||||
SELECT x, y FROM main.t3 EXCEPT SELECT x, y FROM aux1.t3;
|
||||
}
|
||||
} {}
|
||||
|
||||
# Deserialize an empty database
|
||||
#
|
||||
db close
|
||||
sqlite3 db
|
||||
db deserialize {}
|
||||
do_execsql_test 400 {
|
||||
PRAGMA integrity_check;
|
||||
} {ok}
|
||||
do_execsql_test 410 {
|
||||
CREATE TABLE t4(a,b);
|
||||
INSERT INTO t4 VALUES('hello','world!');
|
||||
PRAGMA integrity_check;
|
||||
SELECT * FROM t4;
|
||||
} {ok hello world!}
|
||||
|
||||
# Deserialize something that is not a database.
|
||||
#
|
||||
db close
|
||||
sqlite3 db
|
||||
do_test 500 {
|
||||
set rc [catch {db deserialize not-a-database} msg]
|
||||
lappend rc $msg
|
||||
} {0 {}}
|
||||
do_catchsql_test 510 {
|
||||
PRAGMA integrity_check;
|
||||
} {1 {file is not a database}}
|
||||
|
||||
# Abuse the serialize and deserialize commands. Make sure errors are caught.
|
||||
#
|
||||
do_test 600 {
|
||||
set rc [catch {db deserialize} msg]
|
||||
lappend rc $msg
|
||||
} {1 {wrong # args: should be "db deserialize ?DATABASE? VALUE"}}
|
||||
do_test 610 {
|
||||
set rc [catch {db deserialize a b c} msg]
|
||||
lappend rc $msg
|
||||
} {1 {wrong # args: should be "db deserialize ?DATABASE? VALUE"}}
|
||||
do_test 620 {
|
||||
set rc [catch {db serialize a b} msg]
|
||||
lappend rc $msg
|
||||
} {1 {wrong # args: should be "db serialize ?DATABASE?"}}
|
||||
|
||||
finish_test
|
||||
@@ -110,6 +110,7 @@ forcedelete test.db test.db-wal test.db-shm
|
||||
sqlite3 db test.db
|
||||
sqlite3 db2 test.db
|
||||
do_execsql_test 2.1 {
|
||||
PRAGMA auto_vacuum=OFF;
|
||||
PRAGMA journal_mode = wal;
|
||||
CREATE TABLE y1(a PRIMARY KEY, b UNIQUE, c);
|
||||
INSERT INTO y1 VALUES('a', 'b', 'c');
|
||||
|
||||
+7
-1
@@ -3,11 +3,17 @@
|
||||
** (https://github.com/google/oss-fuzz)
|
||||
*/
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#if !defined(_MSC_VER)
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "sqlite3.h"
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
typedef unsigned char uint8_t;
|
||||
#endif
|
||||
|
||||
/* Global debugging settings. OSS-Fuzz will have all debugging turned
|
||||
** off. But if LLVMFuzzerTestOneInput() is called interactively from
|
||||
** the ossshell utility program, then these flags might be set.
|
||||
|
||||
+7
-1
@@ -6,12 +6,18 @@
|
||||
** command line and passes them one by one into ossfuzz.c.
|
||||
*/
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#if !defined(_MSC_VER)
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "sqlite3.h"
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
typedef unsigned char uint8_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
** The entry point in ossfuzz.c that this routine will be calling
|
||||
*/
|
||||
|
||||
@@ -148,6 +148,63 @@ do_execsql_test printf2-4.10 {
|
||||
SELECT printf('|%,d|%,d|',1234567890,-1234567890);
|
||||
} {|1,234,567,890|-1,234,567,890|}
|
||||
|
||||
# 2018-02-19. Unicode characters with %c
|
||||
do_execsql_test printf2-5.100 {
|
||||
SELECT printf('(%8c)',char(11106));
|
||||
} {{( ⭢)}}
|
||||
do_execsql_test printf2-5.101 {
|
||||
SELECT printf('(%-8c)',char(11106));
|
||||
} {{(⭢ )}}
|
||||
do_execsql_test printf2-5.102 {
|
||||
SELECT printf('(%5.3c)',char(1492));
|
||||
} {{( ההה)}}
|
||||
do_execsql_test printf2-5.103 {
|
||||
SELECT printf('(%-5.3c)',char(1492));
|
||||
} {{(ההה )}}
|
||||
do_execsql_test printf2-5.104 {
|
||||
SELECT printf('(%3.3c)',char(1492));
|
||||
} {{(ההה)}}
|
||||
do_execsql_test printf2-5.105 {
|
||||
SELECT printf('(%-3.3c)',char(1492));
|
||||
} {{(ההה)}}
|
||||
do_execsql_test printf2-5.104 {
|
||||
SELECT printf('(%2c)',char(1513));
|
||||
} {{( ש)}}
|
||||
do_execsql_test printf2-5.106 {
|
||||
SELECT printf('(%-2c)',char(1513));
|
||||
} {{(ש )}}
|
||||
|
||||
# 2018-02-19. Unicode characters with the "!" flag in %s and friends.
|
||||
do_execsql_test printf2-6.100 {
|
||||
SELECT printf('(%!.3s)','הנה מה־טוב ומה־נעים שבת אחים גם־יחד');
|
||||
} {(הנה)}
|
||||
do_execsql_test printf2-6.101 {
|
||||
SELECT printf('(%.6s)','הנה מה־טוב ומה־נעים שבת אחים גם־יחד');
|
||||
} {(הנה)}
|
||||
do_execsql_test printf2-6.102 {
|
||||
SELECT printf('(%!5.3s)','הנה מה־טוב ומה־נעים שבת אחים גם־יחד');
|
||||
} {{( הנה)}}
|
||||
do_execsql_test printf2-6.103 {
|
||||
SELECT printf('(%8.6s)','הנה מה־טוב ומה־נעים שבת אחים גם־יחד');
|
||||
} {{( הנה)}}
|
||||
do_execsql_test printf2-6.104 {
|
||||
SELECT printf('(%!-5.3s)','הנה מה־טוב ומה־נעים שבת אחים גם־יחד');
|
||||
} {{(הנה )}}
|
||||
do_execsql_test printf2-6.105 {
|
||||
SELECT printf('(%-8.6s)','הנה מה־טוב ומה־נעים שבת אחים גם־יחד');
|
||||
} {{(הנה )}}
|
||||
do_execsql_test printf2-6.106 {
|
||||
SELECT printf('(%!.3Q)','הנה מה־טוב ומה־נעים שבת אחים גם־יחד');
|
||||
} {('הנה')}
|
||||
do_execsql_test printf2-6.107 {
|
||||
SELECT printf('(%.6Q)','הנה מה־טוב ומה־נעים שבת אחים גם־יחד');
|
||||
} {('הנה')}
|
||||
do_execsql_test printf2-6.108 {
|
||||
SELECT printf('(%!7.3Q)','הנה מה־טוב ומה־נעים שבת אחים גם־יחד');
|
||||
} {{( 'הנה')}}
|
||||
do_execsql_test printf2-6.109 {
|
||||
SELECT printf('(%10.6Q)','הנה מה־טוב ומה־נעים שבת אחים גם־יחד');
|
||||
} {{( 'הנה')}}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
+108
-1
@@ -437,6 +437,113 @@ do_execsql_test 18.6 {
|
||||
} {1 1 1 1 2 1}
|
||||
|
||||
|
||||
finish_test
|
||||
# 2018-02-13 Ticket https://www.sqlite.org/src/tktview/f484b65f3d6230593c3
|
||||
# Incorrect result from a row-value comparison in the WHERE clause.
|
||||
#
|
||||
do_execsql_test 19.1 {
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY,b);
|
||||
INSERT INTO t1(a,b) VALUES(1,11),(2,22),(3,33),(4,44);
|
||||
SELECT * FROM t1 WHERE (a,b)>(0,0) ORDER BY a;
|
||||
} {1 11 2 22 3 33 4 44}
|
||||
do_execsql_test 19.2 {
|
||||
SELECT * FROM t1 WHERE (a,b)>=(0,0) ORDER BY a;
|
||||
} {1 11 2 22 3 33 4 44}
|
||||
do_execsql_test 19.3 {
|
||||
SELECT * FROM t1 WHERE (a,b)<(5,0) ORDER BY a DESC;
|
||||
} {4 44 3 33 2 22 1 11}
|
||||
do_execsql_test 19.4 {
|
||||
SELECT * FROM t1 WHERE (a,b)<=(5,0) ORDER BY a DESC;
|
||||
} {4 44 3 33 2 22 1 11}
|
||||
do_execsql_test 19.5 {
|
||||
SELECT * FROM t1 WHERE (a,b)>(3,0) ORDER BY a;
|
||||
} {3 33 4 44}
|
||||
do_execsql_test 19.6 {
|
||||
SELECT * FROM t1 WHERE (a,b)>=(3,0) ORDER BY a;
|
||||
} {3 33 4 44}
|
||||
do_execsql_test 19.7 {
|
||||
SELECT * FROM t1 WHERE (a,b)<(3,0) ORDER BY a DESC;
|
||||
} {2 22 1 11}
|
||||
do_execsql_test 19.8 {
|
||||
SELECT * FROM t1 WHERE (a,b)<=(3,0) ORDER BY a DESC;
|
||||
} {2 22 1 11}
|
||||
do_execsql_test 19.9 {
|
||||
SELECT * FROM t1 WHERE (a,b)>(3,32) ORDER BY a;
|
||||
} {3 33 4 44}
|
||||
do_execsql_test 19.10 {
|
||||
SELECT * FROM t1 WHERE (a,b)>(3,33) ORDER BY a;
|
||||
} {4 44}
|
||||
do_execsql_test 19.11 {
|
||||
SELECT * FROM t1 WHERE (a,b)>=(3,33) ORDER BY a;
|
||||
} {3 33 4 44}
|
||||
do_execsql_test 19.12 {
|
||||
SELECT * FROM t1 WHERE (a,b)>=(3,34) ORDER BY a;
|
||||
} {4 44}
|
||||
do_execsql_test 19.13 {
|
||||
SELECT * FROM t1 WHERE (a,b)<(3,34) ORDER BY a DESC;
|
||||
} {3 33 2 22 1 11}
|
||||
do_execsql_test 19.14 {
|
||||
SELECT * FROM t1 WHERE (a,b)<(3,33) ORDER BY a DESC;
|
||||
} {2 22 1 11}
|
||||
do_execsql_test 19.15 {
|
||||
SELECT * FROM t1 WHERE (a,b)<=(3,33) ORDER BY a DESC;
|
||||
} {3 33 2 22 1 11}
|
||||
do_execsql_test 19.16 {
|
||||
SELECT * FROM t1 WHERE (a,b)<=(3,32) ORDER BY a DESC;
|
||||
} {2 22 1 11}
|
||||
do_execsql_test 19.21 {
|
||||
SELECT * FROM t1 WHERE (0,0)<(a,b) ORDER BY a;
|
||||
} {1 11 2 22 3 33 4 44}
|
||||
do_execsql_test 19.22 {
|
||||
SELECT * FROM t1 WHERE (0,0)<=(a,b) ORDER BY a;
|
||||
} {1 11 2 22 3 33 4 44}
|
||||
do_execsql_test 19.23 {
|
||||
SELECT * FROM t1 WHERE (5,0)>(a,b) ORDER BY a DESC;
|
||||
} {4 44 3 33 2 22 1 11}
|
||||
do_execsql_test 19.24 {
|
||||
SELECT * FROM t1 WHERE (5,0)>=(a,b) ORDER BY a DESC;
|
||||
} {4 44 3 33 2 22 1 11}
|
||||
do_execsql_test 19.25 {
|
||||
SELECT * FROM t1 WHERE (3,0)<(a,b) ORDER BY a;
|
||||
} {3 33 4 44}
|
||||
do_execsql_test 19.26 {
|
||||
SELECT * FROM t1 WHERE (3,0)<=(a,b) ORDER BY a;
|
||||
} {3 33 4 44}
|
||||
do_execsql_test 19.27 {
|
||||
SELECT * FROM t1 WHERE (3,0)>(a,b) ORDER BY a DESC;
|
||||
} {2 22 1 11}
|
||||
do_execsql_test 19.28 {
|
||||
SELECT * FROM t1 WHERE (3,0)>=(a,b) ORDER BY a DESC;
|
||||
} {2 22 1 11}
|
||||
do_execsql_test 19.29 {
|
||||
SELECT * FROM t1 WHERE (3,32)<(a,b) ORDER BY a;
|
||||
} {3 33 4 44}
|
||||
do_execsql_test 19.30 {
|
||||
SELECT * FROM t1 WHERE (3,33)<(a,b) ORDER BY a;
|
||||
} {4 44}
|
||||
do_execsql_test 19.31 {
|
||||
SELECT * FROM t1 WHERE (3,33)<=(a,b) ORDER BY a;
|
||||
} {3 33 4 44}
|
||||
do_execsql_test 19.32 {
|
||||
SELECT * FROM t1 WHERE (3,34)<=(a,b) ORDER BY a;
|
||||
} {4 44}
|
||||
do_execsql_test 19.33 {
|
||||
SELECT * FROM t1 WHERE (3,34)>(a,b) ORDER BY a DESC;
|
||||
} {3 33 2 22 1 11}
|
||||
do_execsql_test 19.34 {
|
||||
SELECT * FROM t1 WHERE (3,33)>(a,b) ORDER BY a DESC;
|
||||
} {2 22 1 11}
|
||||
do_execsql_test 19.35 {
|
||||
SELECT * FROM t1 WHERE (3,33)>=(a,b) ORDER BY a DESC;
|
||||
} {3 33 2 22 1 11}
|
||||
do_execsql_test 19.36 {
|
||||
SELECT * FROM t1 WHERE (3,32)>=(a,b) ORDER BY a DESC;
|
||||
} {2 22 1 11}
|
||||
|
||||
# 2018-02-18: Memory leak nexted row-value. Detected by OSSFuzz.
|
||||
#
|
||||
do_catchsql_test 20.1 {
|
||||
SELECT 1 WHERE (2,(2,0)) IS (2,(2,0));
|
||||
} {0 1}
|
||||
|
||||
finish_test
|
||||
|
||||
Binary file not shown.
+1018
File diff suppressed because it is too large
Load Diff
@@ -168,7 +168,6 @@ speed_trial_tcl speed4p-subselect1 10000 stmt $script
|
||||
set script {
|
||||
db eval BEGIN
|
||||
for {set ii 1} {$ii < 10000} {incr ii} {
|
||||
set v [expr {$ii*3}]
|
||||
db eval {UPDATE t1 SET i=i+1 WHERE rowid=$ii}
|
||||
}
|
||||
db eval COMMIT
|
||||
|
||||
+1
-1
@@ -279,7 +279,7 @@ ifcapable trace {
|
||||
do_tracesql_test 6.2.3 {
|
||||
SELECT word, distance FROM t3 WHERE rowid = 10 AND word MATCH 'kiiner';
|
||||
} {keener 300
|
||||
{SELECT id, word, rank, k1 FROM "main"."t3_vocab" WHERE langid=0 AND k2>=?1 AND k2<?2}
|
||||
{SELECT id, word, rank, coalesce(k1,word) FROM "main"."t3_vocab" WHERE langid=0 AND k2>=?1 AND k2<?2}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,353 @@
|
||||
# 2018-02-14
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# Test cases for the editdist3() function in the spellfix extension.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix spellfix4
|
||||
|
||||
ifcapable !vtab { finish_test ; return }
|
||||
|
||||
load_static_extension db spellfix
|
||||
|
||||
do_execsql_test 100 {
|
||||
CREATE TABLE cost1(iLang, cFrom, cTo, iCost);
|
||||
INSERT INTO cost1 VALUES
|
||||
(0, '', '?', 97),
|
||||
(0, '?', '', 98),
|
||||
(0, '?', '?', 99),
|
||||
(0, 'm', 'n', 50),
|
||||
(0, 'n', 'm', 50)
|
||||
;
|
||||
SELECT editdist3('cost1');
|
||||
SELECT editdist3('anchor','amchor');
|
||||
} {{} 50}
|
||||
do_execsql_test 110 {
|
||||
SELECT editdist3('anchor','anchoxr');
|
||||
} {97}
|
||||
do_execsql_test 111 {
|
||||
SELECT editdist3('anchor','xanchor');
|
||||
} {97}
|
||||
do_execsql_test 112 {
|
||||
SELECT editdist3('anchor','anchorx');
|
||||
} {97}
|
||||
do_execsql_test 120 {
|
||||
SELECT editdist3('anchor','anchr');
|
||||
} {98}
|
||||
do_execsql_test 121 {
|
||||
SELECT editdist3('anchor','ancho');
|
||||
} {98}
|
||||
do_execsql_test 122 {
|
||||
SELECT editdist3('anchor','nchor');
|
||||
} {98}
|
||||
do_execsql_test 130 {
|
||||
SELECT editdist3('anchor','anchur');
|
||||
} {99}
|
||||
do_execsql_test 131 {
|
||||
SELECT editdist3('anchor','onchor');
|
||||
} {99}
|
||||
do_execsql_test 132 {
|
||||
SELECT editdist3('anchor','anchot');
|
||||
} {99}
|
||||
do_execsql_test 140 {
|
||||
SELECT editdist3('anchor','omchor');
|
||||
} {149}
|
||||
|
||||
do_execsql_test 200 {
|
||||
INSERT INTO cost1 VALUES
|
||||
(0, 'a', 'ä', 5),
|
||||
(0, 'ss', 'ß', 8)
|
||||
;
|
||||
SELECT editdist3('cost1');
|
||||
SELECT editdist3('strasse','straße');
|
||||
SELECT editdist3('straße','strasse');
|
||||
} {{} 8 196}
|
||||
do_execsql_test 210 {
|
||||
SELECT editdist3('baume','bäume');
|
||||
} {5}
|
||||
do_execsql_test 220 {
|
||||
SELECT editdist3('baum','bäume');
|
||||
} {102}
|
||||
do_execsql_test 230 {
|
||||
INSERT INTO cost1 VALUES
|
||||
(0, 'ä', 'a', 5),
|
||||
(0, 'ß', 'ss', 8)
|
||||
;
|
||||
SELECT editdist3('cost1');
|
||||
SELECT editdist3('strasse','straße');
|
||||
SELECT editdist3('straße','strasse');
|
||||
} {{} 8 8}
|
||||
|
||||
do_execsql_test 300 {
|
||||
DELETE FROM cost1;
|
||||
INSERT INTO cost1 VALUES
|
||||
(0, '', '?', 97),
|
||||
(0, '?', '', 98),
|
||||
(0, '?', '?', 99),
|
||||
(0, 'a', 'e', 50),
|
||||
(0, 'a', 'i', 70),
|
||||
(0, 'a', 'o', 75),
|
||||
(0, 'a', 'u', 81),
|
||||
(0, 'e', 'a', 50),
|
||||
(0, 'e', 'i', 52),
|
||||
(0, 'e', 'o', 72),
|
||||
(0, 'e', 'u', 82),
|
||||
(0, 'i', 'a', 70),
|
||||
(0, 'i', 'e', 52),
|
||||
(0, 'i', 'o', 75),
|
||||
(0, 'i', 'u', 83),
|
||||
(0, 'o', 'a', 75),
|
||||
(0, 'o', 'e', 72),
|
||||
(0, 'o', 'i', 75),
|
||||
(0, 'o', 'u', 40),
|
||||
(0, 'u', 'a', 81),
|
||||
(0, 'u', 'e', 82),
|
||||
(0, 'u', 'i', 83),
|
||||
(0, 'u', 'o', 40),
|
||||
(0, 'm', 'n', 45),
|
||||
(0, 'n', 'm', 45)
|
||||
;
|
||||
CREATE TABLE words(x TEXT);
|
||||
INSERT INTO words VALUES
|
||||
('abraham'),
|
||||
('action'),
|
||||
('africa'),
|
||||
('aladdin'),
|
||||
('alert'),
|
||||
('alien'),
|
||||
('amazon'),
|
||||
('analog'),
|
||||
('animal'),
|
||||
('apollo'),
|
||||
('archive'),
|
||||
('arnold'),
|
||||
('aspirin'),
|
||||
('august'),
|
||||
('average'),
|
||||
('bahama'),
|
||||
('bambino'),
|
||||
('barcode'),
|
||||
('bazooka'),
|
||||
('belgium'),
|
||||
('between'),
|
||||
('biology'),
|
||||
('blonde'),
|
||||
('border'),
|
||||
('brave'),
|
||||
('british'),
|
||||
('bucket'),
|
||||
('button'),
|
||||
('caesar'),
|
||||
('camilla'),
|
||||
('cannon'),
|
||||
('caramel'),
|
||||
('carpet'),
|
||||
('catalog'),
|
||||
('century'),
|
||||
('chaos'),
|
||||
('chef'),
|
||||
('china'),
|
||||
('circus'),
|
||||
('classic'),
|
||||
('clinic'),
|
||||
('coconut'),
|
||||
('combine'),
|
||||
('complex'),
|
||||
('congo'),
|
||||
('convert'),
|
||||
('cosmos'),
|
||||
('crack'),
|
||||
('crown'),
|
||||
('cyclone'),
|
||||
('deal'),
|
||||
('delete'),
|
||||
('denver'),
|
||||
('detail'),
|
||||
('diana'),
|
||||
('direct'),
|
||||
('dolby'),
|
||||
('double'),
|
||||
('dublin'),
|
||||
('echo'),
|
||||
('edition'),
|
||||
('electra'),
|
||||
('emotion'),
|
||||
('enjoy'),
|
||||
('escape'),
|
||||
('everest'),
|
||||
('exile'),
|
||||
('express'),
|
||||
('family'),
|
||||
('ferrari'),
|
||||
('filter'),
|
||||
('fish'),
|
||||
('florida'),
|
||||
('ford'),
|
||||
('forum'),
|
||||
('frank'),
|
||||
('frozen'),
|
||||
('gallery'),
|
||||
('garlic'),
|
||||
('geneva'),
|
||||
('gibson'),
|
||||
('gloria'),
|
||||
('gordon'),
|
||||
('gravity'),
|
||||
('ground'),
|
||||
('habitat'),
|
||||
('harlem'),
|
||||
('hazard'),
|
||||
('herbert'),
|
||||
('hobby'),
|
||||
('house'),
|
||||
('icon'),
|
||||
('immune'),
|
||||
('india'),
|
||||
('inside'),
|
||||
('isotope'),
|
||||
('jamaica'),
|
||||
('jazz'),
|
||||
('joker'),
|
||||
('juliet'),
|
||||
('jupiter'),
|
||||
('kevin'),
|
||||
('korea'),
|
||||
('latin'),
|
||||
('legal'),
|
||||
('lexicon'),
|
||||
('limbo'),
|
||||
('lithium'),
|
||||
('logo'),
|
||||
('lucas'),
|
||||
('madrid'),
|
||||
('major'),
|
||||
('manual'),
|
||||
('mars'),
|
||||
('maximum'),
|
||||
('medical'),
|
||||
('mental'),
|
||||
('meter'),
|
||||
('miguel'),
|
||||
('mimosa'),
|
||||
('miranda'),
|
||||
('modern'),
|
||||
('money'),
|
||||
('morgan'),
|
||||
('motor'),
|
||||
('mystic'),
|
||||
('nebula'),
|
||||
('network'),
|
||||
('nice'),
|
||||
('nitro'),
|
||||
('norway'),
|
||||
('nurse'),
|
||||
('octavia'),
|
||||
('olympic'),
|
||||
('opus'),
|
||||
('orient'),
|
||||
('othello'),
|
||||
('pacific'),
|
||||
('panama'),
|
||||
('paper'),
|
||||
('parking'),
|
||||
('pasta'),
|
||||
('paul'),
|
||||
('people'),
|
||||
('permit'),
|
||||
('phrase'),
|
||||
('pilgrim'),
|
||||
('planet'),
|
||||
('pocket'),
|
||||
('police'),
|
||||
('popular'),
|
||||
('prefer'),
|
||||
('presto'),
|
||||
('private'),
|
||||
('project'),
|
||||
('proxy'),
|
||||
('python'),
|
||||
('quota'),
|
||||
('rainbow'),
|
||||
('raymond'),
|
||||
('region'),
|
||||
('report'),
|
||||
('reward'),
|
||||
('risk'),
|
||||
('robot'),
|
||||
('rose'),
|
||||
('russian'),
|
||||
('sailor'),
|
||||
('salt'),
|
||||
('saturn'),
|
||||
('scorpio'),
|
||||
('second'),
|
||||
('seminar'),
|
||||
('shadow'),
|
||||
('shave'),
|
||||
('shock'),
|
||||
('silence'),
|
||||
('sinatra'),
|
||||
('sleep'),
|
||||
('social'),
|
||||
('sonata'),
|
||||
('spain'),
|
||||
('sphere'),
|
||||
('spray'),
|
||||
('state'),
|
||||
('stone'),
|
||||
('strong'),
|
||||
('sugar'),
|
||||
('supreme'),
|
||||
('swing'),
|
||||
('talent'),
|
||||
('telecom'),
|
||||
('thermos'),
|
||||
('tina'),
|
||||
('tommy'),
|
||||
('torso'),
|
||||
('trade'),
|
||||
('trick'),
|
||||
('tropic'),
|
||||
('turtle'),
|
||||
('uniform'),
|
||||
('user'),
|
||||
('vega'),
|
||||
('vertigo'),
|
||||
('village'),
|
||||
('visible'),
|
||||
('vocal'),
|
||||
('voyage'),
|
||||
('weekend'),
|
||||
('winter'),
|
||||
('year'),
|
||||
('zipper')
|
||||
;
|
||||
SELECT editdist3('cost1');
|
||||
} {{}}
|
||||
do_execsql_test 310 {
|
||||
SELECT editdist3(a.x,b.x), a.x, b.x
|
||||
FROM words a, words b
|
||||
WHERE a.x<b.x
|
||||
ORDER BY 1, 2
|
||||
LIMIT 20
|
||||
} {139 bucket pocket 144 meter motor 149 manual mental 169 crack trick 173 sinatra sonata 174 edition emotion 174 major motor 174 risk rose 174 state stone 194 deal detail 196 alert talent 196 analog catalog 196 deal legal 196 ford forum 196 risk trick 196 stone strong 197 china tina 197 congo logo 197 diana tina 197 florida gloria}
|
||||
do_execsql_test 320 {
|
||||
SELECT md5sum(ed||'/'||sx||'/'||sy||',') FROM (
|
||||
SELECT editdist3(a.x,b.x) AS ed, a.x AS sx, b.x AS sy
|
||||
FROM words a, words b
|
||||
WHERE a.x<b.x
|
||||
ORDER BY 1, 2
|
||||
)
|
||||
} {69d0a31872203a775e19325ea98cd053}
|
||||
|
||||
finish_test
|
||||
+3
-3
@@ -22,19 +22,19 @@ source $testdir/tester.tcl
|
||||
|
||||
# Check the error messages generated by tclsqlite
|
||||
#
|
||||
set r "sqlite_orig HANDLE FILENAME ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN? ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?"
|
||||
set r "sqlite_orig HANDLE ?FILENAME? ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN? ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?"
|
||||
if {[sqlite3 -has-codec]} {
|
||||
append r " ?-key CODECKEY?"
|
||||
}
|
||||
do_test tcl-1.1 {
|
||||
set v [catch {sqlite3 bogus} msg]
|
||||
set v [catch {sqlite3 -bogus} msg]
|
||||
regsub {really_sqlite3} $msg {sqlite3} msg
|
||||
lappend v $msg
|
||||
} [list 1 "wrong # args: should be \"$r\""]
|
||||
do_test tcl-1.2 {
|
||||
set v [catch {db bogus} msg]
|
||||
lappend v $msg
|
||||
} {1 {bad option "bogus": must be authorizer, backup, busy, cache, changes, close, collate, collation_needed, commit_hook, complete, copy, enable_load_extension, errorcode, eval, exists, function, incrblob, interrupt, last_insert_rowid, nullvalue, onecolumn, preupdate, profile, progress, rekey, restore, rollback_hook, status, timeout, total_changes, trace, trace_v2, transaction, unlock_notify, update_hook, version, or wal_hook}}
|
||||
} {1 {bad option "bogus": must be authorizer, backup, busy, cache, changes, close, collate, collation_needed, commit_hook, complete, copy, deserialize, enable_load_extension, errorcode, eval, exists, function, incrblob, interrupt, last_insert_rowid, nullvalue, onecolumn, preupdate, profile, progress, rekey, restore, rollback_hook, serialize, status, timeout, total_changes, trace, trace_v2, transaction, unlock_notify, update_hook, version, or wal_hook}}
|
||||
do_test tcl-1.2.1 {
|
||||
set v [catch {db cache bogus} msg]
|
||||
lappend v $msg
|
||||
|
||||
@@ -121,6 +121,27 @@ do_test trace3-4.2 {
|
||||
set ::stmtlist(record)
|
||||
} {/^\{-?\d+ -?\d+\}$/}
|
||||
|
||||
do_test trace3-4.3 {
|
||||
set ::stmtlist(record) {}
|
||||
db trace_v2 trace_v2_record profile
|
||||
execsql {
|
||||
SELECT a, b FROM t1 ORDER BY a;
|
||||
}
|
||||
set stmt [lindex [lindex $::stmtlist(record) 0] 0]
|
||||
set ns [lindex [lindex $::stmtlist(record) 0] 1]
|
||||
list $stmt [expr {$ns >= 0 && $ns <= 1000000}]; # less than 0.001 second
|
||||
} {/^-?\d+ 1$/}
|
||||
do_test trace3-4.4 {
|
||||
set ::stmtlist(record) {}
|
||||
db trace_v2 trace_v2_record 2
|
||||
execsql {
|
||||
SELECT a, b FROM t1 ORDER BY a;
|
||||
}
|
||||
set stmt [lindex [lindex $::stmtlist(record) 0] 0]
|
||||
set ns [lindex [lindex $::stmtlist(record) 0] 1]
|
||||
list $stmt [expr {$ns >= 0 && $ns <= 1000000}]; # less than 0.001 second
|
||||
} {/^-?\d+ 1$/}
|
||||
|
||||
do_test trace3-5.1 {
|
||||
set ::stmtlist(record) {}
|
||||
db trace_v2 trace_v2_record row
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
# 2018-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.
|
||||
#
|
||||
#***********************************************************************
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing the WITH clause in TRIGGERs and VIEWs.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set ::testprefix with4
|
||||
|
||||
ifcapable {!cte} {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
do_execsql_test 100 {
|
||||
ATTACH ':memory:' AS aux;
|
||||
CREATE TABLE main.t1(a,b);
|
||||
CREATE TABLE aux.t2(x,y);
|
||||
INSERT INTO t1 VALUES(1,2);
|
||||
INSERT INTO t2 VALUES(3,4);
|
||||
} {}
|
||||
do_catchsql_test 110 {
|
||||
CREATE VIEW v1 AS SELECT * FROM t1, aux.t2;
|
||||
} {1 {view v1 cannot reference objects in database aux}}
|
||||
do_catchsql_test 120 {
|
||||
CREATE VIEW v2 AS WITH v(m,n) AS (SELECT x,y FROM aux.t2) SELECT * FROM t1, v;
|
||||
} {1 {view v2 cannot reference objects in database aux}}
|
||||
do_catchsql_test 130 {
|
||||
CREATE VIEW v2 AS WITH v(m,n) AS (SELECT 5,?2) SELECT * FROM t1, v;
|
||||
} {1 {parameters are not allowed in views}}
|
||||
|
||||
do_catchsql_test 200 {
|
||||
CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN
|
||||
WITH v(m,n) AS (SELECT x,y FROM aux.t2) SELECT * FROM t1, v;
|
||||
END;
|
||||
} {1 {trigger r1 cannot reference objects in database aux}}
|
||||
do_catchsql_test 210 {
|
||||
CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN
|
||||
WITH v(m,n) AS (SELECT 5,?2) SELECT * FROM t1, v;
|
||||
END;
|
||||
} {1 {trigger cannot use variables}}
|
||||
|
||||
finish_test
|
||||
+39
-9
@@ -150,19 +150,19 @@ do_execsql_test 1.0 {
|
||||
do_catchsql_test 1.1.0.1 {
|
||||
INSERT INTO zz(name, mode, mtime, sz, rawdata, method)
|
||||
VALUES('f.txt', '-rw-r--r--', 1000000000, 5, 'abcde', 0);
|
||||
} {1 {constraint failed}}
|
||||
} {1 {rawdata must be NULL}}
|
||||
do_catchsql_test 1.1.0.2 {
|
||||
INSERT INTO zz(name, mtime, sz, data, method)
|
||||
VALUES('g.txt', 1000000002, 5, '12345', 0);
|
||||
} {1 {constraint failed}}
|
||||
} {1 {sz must be NULL}}
|
||||
do_catchsql_test 1.1.0.3 {
|
||||
INSERT INTO zz(name, mtime, rawdata, method)
|
||||
VALUES('g.txt', 1000000002, '12345', 0);
|
||||
} {1 {constraint failed}}
|
||||
} {1 {rawdata must be NULL}}
|
||||
do_catchsql_test 1.1.0.4 {
|
||||
INSERT INTO zz(name, data, method)
|
||||
VALUES('g.txt', '12345', 7);
|
||||
} {1 {constraint failed}}
|
||||
} {1 {unknown compression method: 7}}
|
||||
|
||||
do_execsql_test 1.1.1 {
|
||||
INSERT INTO zz(name, mode, mtime, data, method)
|
||||
@@ -287,7 +287,7 @@ do_execsql_test 1.6.6 {
|
||||
|
||||
do_catchsql_test 1.6.7 {
|
||||
UPDATE zz SET data=NULL WHERE name='i.txt'
|
||||
} {1 {constraint failed}}
|
||||
} {1 {zipfile: mode does not match data}}
|
||||
do_execsql_test 1.6.8 {
|
||||
SELECT name, mode, mtime, data, method FROM zipfile('test.zip');
|
||||
} {
|
||||
@@ -398,13 +398,13 @@ foreach {tn fname} {
|
||||
} {
|
||||
do_catchsql_test 3.1.$tn.0 {
|
||||
INSERT INTO x1(name, data) VALUES($fname, NULL);
|
||||
} {1 {constraint failed}}
|
||||
} [list 1 "duplicate name: \"$fname/\""]
|
||||
do_catchsql_test 3.1.$tn.1 {
|
||||
INSERT INTO x1(name, data) VALUES($fname || '/', NULL);
|
||||
} {1 {constraint failed}}
|
||||
} [list 1 "duplicate name: \"$fname/\""]
|
||||
do_catchsql_test 3.1.$tn.2 {
|
||||
INSERT INTO x1(name, data) VALUES($fname, 'abcd');
|
||||
} {1 {constraint failed}}
|
||||
} [list 1 "duplicate name: \"$fname\""]
|
||||
}
|
||||
|
||||
do_catchsql_test 3.2 {
|
||||
@@ -636,5 +636,35 @@ do_execsql_test 9.0 {
|
||||
)
|
||||
SELECT name FROM zipfile((SELECT zipfile(nm, NULL) FROM src))
|
||||
} {dir1/ dir2/ dir3/ dir4/ /}
|
||||
finish_test
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# INSERT OR REPLACE and INSERT OR IGNORE
|
||||
#
|
||||
catch {db close}
|
||||
forcedelete test.zip test.db
|
||||
sqlite3 db :memory:
|
||||
load_static_extension db zipfile
|
||||
do_execsql_test 10.0 {
|
||||
CREATE VIRTUAL TABLE z USING zipfile('test.zip');
|
||||
} {}
|
||||
do_catchsql_test 10.1 {
|
||||
INSERT INTO z(name,data) VALUES('a0','one'),('a0','two');
|
||||
} {1 {duplicate name: "a0"}}
|
||||
do_execsql_test 10.2 {
|
||||
SELECT name, data FROM z;
|
||||
} {a0 one}
|
||||
do_execsql_test 10.3 {
|
||||
REPLACE INTO z(name,data) VALUES('a0','three'),('a0','four');
|
||||
} {}
|
||||
do_execsql_test 10.4 {
|
||||
SELECT name, data FROM z;
|
||||
} {a0 four}
|
||||
do_execsql_test 10.5 {
|
||||
INSERT OR IGNORE INTO z(name,data) VALUES('a0','five'),('a0','six');
|
||||
} {}
|
||||
do_execsql_test 10.6 {
|
||||
SELECT name, data FROM z;
|
||||
} {a0 four}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -47,13 +47,15 @@ do_faultsim_test 2.1 -faults oom* -body {
|
||||
} -test {
|
||||
faultsim_test_result {0 {a.txt 1234567890}}
|
||||
}
|
||||
do_faultsim_test 2.2 -faults oom* -body {
|
||||
execsql {
|
||||
SELECT json_extract( zipfile_cds(z), '$.version-made-by' )
|
||||
FROM zipfile('test.zip')
|
||||
ifcapable json1 {
|
||||
do_faultsim_test 2.2 -faults oom* -body {
|
||||
execsql {
|
||||
SELECT json_extract( zipfile_cds(z), '$.version-made-by' )
|
||||
FROM zipfile('test.zip')
|
||||
}
|
||||
} -test {
|
||||
faultsim_test_result {0 798}
|
||||
}
|
||||
} -test {
|
||||
faultsim_test_result {0 798}
|
||||
}
|
||||
|
||||
forcedelete test.zip
|
||||
@@ -162,4 +164,3 @@ do_faultsim_test 7.0 -faults oom* -prep {
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ close $in
|
||||
# ILLEGAL *must* be the last two token codes and they must be in that order.
|
||||
#
|
||||
set extras {
|
||||
TRUEFALSE
|
||||
ISNOT
|
||||
FUNCTION
|
||||
COLUMN
|
||||
@@ -29,6 +30,7 @@ set extras {
|
||||
AGG_COLUMN
|
||||
UMINUS
|
||||
UPLUS
|
||||
TRUTH
|
||||
REGISTER
|
||||
VECTOR
|
||||
SELECT_COLUMN
|
||||
|
||||
+2
-2
@@ -11,7 +11,7 @@ while {![eof stdin]} {
|
||||
if {$line==""} continue
|
||||
regsub -all "\[ \t\n,\]+" [string trim $line] { } line
|
||||
foreach token [split $line { }] {
|
||||
if {![regexp {(([a-zA-Z]+)_)?([_a-zA-Z]+)} $token all px p2 name]} continue
|
||||
if {![regexp {(([a-zA-Z]+)_)?([_a-zA-Z0-9]+)} $token all px p2 name]} continue
|
||||
lappend namelist [string tolower $name]
|
||||
if {$px!=""} {set prefix $p2}
|
||||
}
|
||||
@@ -23,7 +23,7 @@ proc put_item x {
|
||||
global col
|
||||
if {$col==0} {puts -nonewline " "}
|
||||
if {$col<2} {
|
||||
puts -nonewline [format " %-21s" $x]
|
||||
puts -nonewline [format " %-25s" $x]
|
||||
incr col
|
||||
} else {
|
||||
puts $x
|
||||
|
||||
@@ -320,6 +320,7 @@ foreach file {
|
||||
|
||||
os_unix.c
|
||||
os_win.c
|
||||
memdb.c
|
||||
|
||||
bitvec.c
|
||||
pcache.c
|
||||
|
||||
+18
-2
@@ -39,6 +39,8 @@ LEAN_OPTS="$LEAN_OPTS -DSQLITE_USE_ALLOCA"
|
||||
BASELINE="trunk"
|
||||
doExplain=0
|
||||
doCachegrind=1
|
||||
doVdbeProfile=0
|
||||
doWal=1
|
||||
while test "$1" != ""; do
|
||||
case $1 in
|
||||
--reprepare)
|
||||
@@ -62,8 +64,11 @@ while test "$1" != ""; do
|
||||
--temp)
|
||||
SPEEDTEST_OPTS="$SPEEDTEST_OPTS --temp 6"
|
||||
;;
|
||||
--legacy)
|
||||
doWal=0
|
||||
;;
|
||||
--wal)
|
||||
SPEEDTEST_OPTS="$SPEEDTEST_OPTS --journal wal"
|
||||
doWal=1
|
||||
;;
|
||||
--size)
|
||||
shift; SIZE=$1
|
||||
@@ -78,6 +83,7 @@ while test "$1" != ""; do
|
||||
rm -f vdbe_profile.out
|
||||
CC_OPTS="$CC_OPTS -DVDBE_PROFILE"
|
||||
doCachegrind=0
|
||||
doVdbeProfile=1
|
||||
;;
|
||||
--lean)
|
||||
CC_OPTS="$CC_OPTS $LEAN_OPTS"
|
||||
@@ -132,11 +138,17 @@ while test "$1" != ""; do
|
||||
esac
|
||||
shift
|
||||
done
|
||||
if test $doWal -eq 1; then
|
||||
SPEEDTEST_OPTS="$SPEEDTEST_OPTS --journal wal"
|
||||
fi
|
||||
SPEEDTEST_OPTS="$SPEEDTEST_OPTS --size $SIZE"
|
||||
echo "NAME = $NAME" | tee summary-$NAME.txt
|
||||
echo "SPEEDTEST_OPTS = $SPEEDTEST_OPTS" | tee -a summary-$NAME.txt
|
||||
echo "CC_OPTS = $CC_OPTS" | tee -a summary-$NAME.txt
|
||||
rm -f cachegrind.out.* speedtest1 speedtest1.db sqlite3.o
|
||||
if test $doVdbeProfile -eq 1; then
|
||||
rm -f vdbe_profile.out
|
||||
fi
|
||||
$CC -g -Os -Wall -I. $CC_OPTS -c sqlite3.c
|
||||
size sqlite3.o | tee -a summary-$NAME.txt
|
||||
if test $doExplain -eq 1; then
|
||||
@@ -163,6 +175,10 @@ fi
|
||||
if test $doExplain -eq 1; then
|
||||
./speedtest1 --explain $SPEEDTEST_OPTS | ./sqlite3 >explain-$NAME.txt
|
||||
fi
|
||||
if test "$NAME" != "$BASELINE"; then
|
||||
if test $doVdbeProfile -eq 1; then
|
||||
tclsh ../sqlite/tool/vdbe_profile.tcl >vdbeprofile-$NAME.txt
|
||||
open vdbeprofile-$NAME.txt
|
||||
fi
|
||||
if test "$NAME" != "$BASELINE" -a $doVdbeProfile -ne 1; then
|
||||
fossil test-diff --tk -c 20 cout-$BASELINE.txt cout-$NAME.txt
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user