mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-05 15:55:57 +03:00
Merge all the enhancements and bug fixes from trunk, since none are
destablizing. Call this the second beta. FossilOrigin-Name: fb3ee1b7cac09e4950e4f48b44c277e4f391cb6c8f069644732d2389ca653da4
This commit is contained in:
28
Makefile.in
28
Makefile.in
@@ -166,7 +166,8 @@ USE_AMALGAMATION = @USE_AMALGAMATION@
|
|||||||
#
|
#
|
||||||
LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \
|
LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \
|
||||||
backup.lo bitvec.lo btmutex.lo btree.lo build.lo \
|
backup.lo bitvec.lo btmutex.lo btree.lo build.lo \
|
||||||
callback.lo complete.lo ctime.lo date.lo dbstat.lo delete.lo \
|
callback.lo complete.lo ctime.lo \
|
||||||
|
date.lo dbpage.lo dbstat.lo delete.lo \
|
||||||
expr.lo fault.lo fkey.lo \
|
expr.lo fault.lo fkey.lo \
|
||||||
fts3.lo fts3_aux.lo fts3_expr.lo fts3_hash.lo fts3_icu.lo \
|
fts3.lo fts3_aux.lo fts3_expr.lo fts3_hash.lo fts3_icu.lo \
|
||||||
fts3_porter.lo fts3_snippet.lo fts3_tokenizer.lo fts3_tokenizer1.lo \
|
fts3_porter.lo fts3_snippet.lo fts3_tokenizer.lo fts3_tokenizer1.lo \
|
||||||
@@ -215,6 +216,7 @@ SRC = \
|
|||||||
$(TOP)/src/complete.c \
|
$(TOP)/src/complete.c \
|
||||||
$(TOP)/src/ctime.c \
|
$(TOP)/src/ctime.c \
|
||||||
$(TOP)/src/date.c \
|
$(TOP)/src/date.c \
|
||||||
|
$(TOP)/src/dbpage.c \
|
||||||
$(TOP)/src/dbstat.c \
|
$(TOP)/src/dbstat.c \
|
||||||
$(TOP)/src/delete.c \
|
$(TOP)/src/delete.c \
|
||||||
$(TOP)/src/expr.c \
|
$(TOP)/src/expr.c \
|
||||||
@@ -394,6 +396,7 @@ TESTSRC = \
|
|||||||
$(TOP)/src/test_intarray.c \
|
$(TOP)/src/test_intarray.c \
|
||||||
$(TOP)/src/test_journal.c \
|
$(TOP)/src/test_journal.c \
|
||||||
$(TOP)/src/test_malloc.c \
|
$(TOP)/src/test_malloc.c \
|
||||||
|
$(TOP)/src/test_md5.c \
|
||||||
$(TOP)/src/test_multiplex.c \
|
$(TOP)/src/test_multiplex.c \
|
||||||
$(TOP)/src/test_mutex.c \
|
$(TOP)/src/test_mutex.c \
|
||||||
$(TOP)/src/test_onefile.c \
|
$(TOP)/src/test_onefile.c \
|
||||||
@@ -405,6 +408,7 @@ TESTSRC = \
|
|||||||
$(TOP)/src/test_server.c \
|
$(TOP)/src/test_server.c \
|
||||||
$(TOP)/src/test_superlock.c \
|
$(TOP)/src/test_superlock.c \
|
||||||
$(TOP)/src/test_syscall.c \
|
$(TOP)/src/test_syscall.c \
|
||||||
|
$(TOP)/src/test_tclsh.c \
|
||||||
$(TOP)/src/test_tclvar.c \
|
$(TOP)/src/test_tclvar.c \
|
||||||
$(TOP)/src/test_thread.c \
|
$(TOP)/src/test_thread.c \
|
||||||
$(TOP)/src/test_vfs.c \
|
$(TOP)/src/test_vfs.c \
|
||||||
@@ -450,6 +454,7 @@ TESTSRC2 = \
|
|||||||
$(TOP)/src/build.c \
|
$(TOP)/src/build.c \
|
||||||
$(TOP)/src/ctime.c \
|
$(TOP)/src/ctime.c \
|
||||||
$(TOP)/src/date.c \
|
$(TOP)/src/date.c \
|
||||||
|
$(TOP)/src/dbpage.c \
|
||||||
$(TOP)/src/dbstat.c \
|
$(TOP)/src/dbstat.c \
|
||||||
$(TOP)/src/expr.c \
|
$(TOP)/src/expr.c \
|
||||||
$(TOP)/src/func.c \
|
$(TOP)/src/func.c \
|
||||||
@@ -570,6 +575,8 @@ SHELL_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4
|
|||||||
SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
|
SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
|
||||||
SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
|
SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
|
||||||
SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
|
SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
|
||||||
|
SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
|
||||||
|
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
|
||||||
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
|
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
|
||||||
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ
|
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ
|
||||||
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
|
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
|
||||||
@@ -753,6 +760,9 @@ ctime.lo: $(TOP)/src/ctime.c $(HDR)
|
|||||||
date.lo: $(TOP)/src/date.c $(HDR)
|
date.lo: $(TOP)/src/date.c $(HDR)
|
||||||
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/date.c
|
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/date.c
|
||||||
|
|
||||||
|
dbpage.lo: $(TOP)/src/dbpage.c $(HDR)
|
||||||
|
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/dbpage.c
|
||||||
|
|
||||||
dbstat.lo: $(TOP)/src/dbstat.c $(HDR)
|
dbstat.lo: $(TOP)/src/dbstat.c $(HDR)
|
||||||
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/dbstat.c
|
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/dbstat.c
|
||||||
|
|
||||||
@@ -937,7 +947,7 @@ tclsqlite.lo: $(TOP)/src/tclsqlite.c $(HDR)
|
|||||||
$(LTCOMPILE) -DUSE_TCL_STUBS=1 -c $(TOP)/src/tclsqlite.c
|
$(LTCOMPILE) -DUSE_TCL_STUBS=1 -c $(TOP)/src/tclsqlite.c
|
||||||
|
|
||||||
tclsqlite-shell.lo: $(TOP)/src/tclsqlite.c $(HDR)
|
tclsqlite-shell.lo: $(TOP)/src/tclsqlite.c $(HDR)
|
||||||
$(LTCOMPILE) -DTCLSH=1 -o $@ -c $(TOP)/src/tclsqlite.c
|
$(LTCOMPILE) -DTCLSH -o $@ -c $(TOP)/src/tclsqlite.c
|
||||||
|
|
||||||
tclsqlite-stubs.lo: $(TOP)/src/tclsqlite.c $(HDR)
|
tclsqlite-stubs.lo: $(TOP)/src/tclsqlite.c $(HDR)
|
||||||
$(LTCOMPILE) -DUSE_TCL_STUBS=1 -o $@ -c $(TOP)/src/tclsqlite.c
|
$(LTCOMPILE) -DUSE_TCL_STUBS=1 -o $@ -c $(TOP)/src/tclsqlite.c
|
||||||
@@ -1103,12 +1113,14 @@ sqlite3rbu.lo: $(TOP)/ext/rbu/sqlite3rbu.c $(HDR) $(EXTHDR)
|
|||||||
# necessary because the test fixture requires non-API symbols which are
|
# necessary because the test fixture requires non-API symbols which are
|
||||||
# hidden when the library is built via the amalgamation).
|
# hidden when the library is built via the amalgamation).
|
||||||
#
|
#
|
||||||
TESTFIXTURE_FLAGS = -DTCLSH=1 -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
|
TESTFIXTURE_FLAGS = -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
|
||||||
|
TESTFIXTURE_FLAGS += -DTCLSH_INIT_PROC=sqlite3TestInit
|
||||||
TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE
|
TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE
|
||||||
TESTFIXTURE_FLAGS += -DBUILD_sqlite
|
TESTFIXTURE_FLAGS += -DBUILD_sqlite
|
||||||
TESTFIXTURE_FLAGS += -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
|
TESTFIXTURE_FLAGS += -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
|
||||||
TESTFIXTURE_FLAGS += -DSQLITE_DEFAULT_PAGE_SIZE=1024
|
TESTFIXTURE_FLAGS += -DSQLITE_DEFAULT_PAGE_SIZE=1024
|
||||||
TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_STMTVTAB
|
TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_STMTVTAB
|
||||||
|
TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_DBPAGE_VTAB
|
||||||
|
|
||||||
TESTFIXTURE_SRC0 = $(TESTSRC2) libsqlite3.la
|
TESTFIXTURE_SRC0 = $(TESTSRC2) libsqlite3.la
|
||||||
TESTFIXTURE_SRC1 = sqlite3.c
|
TESTFIXTURE_SRC1 = sqlite3.c
|
||||||
@@ -1169,14 +1181,8 @@ valgrindtest: $(TESTPROGS) valgrindfuzz
|
|||||||
smoketest: $(TESTPROGS) fuzzcheck$(TEXE)
|
smoketest: $(TESTPROGS) fuzzcheck$(TEXE)
|
||||||
./testfixture$(TEXE) $(TOP)/test/main.test $(TESTOPTS)
|
./testfixture$(TEXE) $(TOP)/test/main.test $(TESTOPTS)
|
||||||
|
|
||||||
sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl
|
sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in
|
||||||
echo "#define TCLSH 2" > $@
|
$(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c
|
||||||
echo "#define SQLITE_ENABLE_DBSTAT_VTAB 1" >> $@
|
|
||||||
cat sqlite3.c $(TOP)/src/tclsqlite.c >> $@
|
|
||||||
echo "static const char *tclsh_main_loop(void){" >> $@
|
|
||||||
echo "static const char *zMainloop = " >> $@
|
|
||||||
$(TCLSH_CMD) $(TOP)/tool/tostr.tcl $(TOP)/tool/spaceanal.tcl >> $@
|
|
||||||
echo "; return zMainloop; }" >> $@
|
|
||||||
|
|
||||||
sqlite3_analyzer$(TEXE): sqlite3_analyzer.c
|
sqlite3_analyzer$(TEXE): sqlite3_analyzer.c
|
||||||
$(LTLINK) sqlite3_analyzer.c -o $@ $(LIBTCL) $(TLIBS)
|
$(LTLINK) sqlite3_analyzer.c -o $@ $(LIBTCL) $(TLIBS)
|
||||||
|
27
Makefile.msc
27
Makefile.msc
@@ -1091,7 +1091,8 @@ LTLIBS = $(LTLIBS) $(LIBICU)
|
|||||||
#
|
#
|
||||||
LIBOBJS0 = vdbe.lo parse.lo alter.lo analyze.lo attach.lo auth.lo \
|
LIBOBJS0 = vdbe.lo parse.lo alter.lo analyze.lo attach.lo auth.lo \
|
||||||
backup.lo bitvec.lo btmutex.lo btree.lo build.lo \
|
backup.lo bitvec.lo btmutex.lo btree.lo build.lo \
|
||||||
callback.lo complete.lo ctime.lo date.lo dbstat.lo delete.lo \
|
callback.lo complete.lo ctime.lo \
|
||||||
|
date.lo dbpage.lo dbstat.lo delete.lo \
|
||||||
expr.lo fault.lo fkey.lo \
|
expr.lo fault.lo fkey.lo \
|
||||||
fts3.lo fts3_aux.lo fts3_expr.lo fts3_hash.lo fts3_icu.lo \
|
fts3.lo fts3_aux.lo fts3_expr.lo fts3_hash.lo fts3_icu.lo \
|
||||||
fts3_porter.lo fts3_snippet.lo fts3_tokenizer.lo fts3_tokenizer1.lo \
|
fts3_porter.lo fts3_snippet.lo fts3_tokenizer.lo fts3_tokenizer1.lo \
|
||||||
@@ -1154,6 +1155,7 @@ SRC00 = \
|
|||||||
$(TOP)\src\complete.c \
|
$(TOP)\src\complete.c \
|
||||||
$(TOP)\src\ctime.c \
|
$(TOP)\src\ctime.c \
|
||||||
$(TOP)\src\date.c \
|
$(TOP)\src\date.c \
|
||||||
|
$(TOP)\src\dbpage.c \
|
||||||
$(TOP)\src\dbstat.c \
|
$(TOP)\src\dbstat.c \
|
||||||
$(TOP)\src\delete.c \
|
$(TOP)\src\delete.c \
|
||||||
$(TOP)\src\expr.c \
|
$(TOP)\src\expr.c \
|
||||||
@@ -1372,6 +1374,7 @@ TESTSRC = \
|
|||||||
$(TOP)\src\test_intarray.c \
|
$(TOP)\src\test_intarray.c \
|
||||||
$(TOP)\src\test_journal.c \
|
$(TOP)\src\test_journal.c \
|
||||||
$(TOP)\src\test_malloc.c \
|
$(TOP)\src\test_malloc.c \
|
||||||
|
$(TOP)\src\test_md5.c \
|
||||||
$(TOP)\src\test_multiplex.c \
|
$(TOP)\src\test_multiplex.c \
|
||||||
$(TOP)\src\test_mutex.c \
|
$(TOP)\src\test_mutex.c \
|
||||||
$(TOP)\src\test_onefile.c \
|
$(TOP)\src\test_onefile.c \
|
||||||
@@ -1383,6 +1386,7 @@ TESTSRC = \
|
|||||||
$(TOP)\src\test_server.c \
|
$(TOP)\src\test_server.c \
|
||||||
$(TOP)\src\test_superlock.c \
|
$(TOP)\src\test_superlock.c \
|
||||||
$(TOP)\src\test_syscall.c \
|
$(TOP)\src\test_syscall.c \
|
||||||
|
$(TOP)\src\test_tclsh.c \
|
||||||
$(TOP)\src\test_tclvar.c \
|
$(TOP)\src\test_tclvar.c \
|
||||||
$(TOP)\src\test_thread.c \
|
$(TOP)\src\test_thread.c \
|
||||||
$(TOP)\src\test_vfs.c \
|
$(TOP)\src\test_vfs.c \
|
||||||
@@ -1505,6 +1509,7 @@ FUZZDATA = \
|
|||||||
#
|
#
|
||||||
!IF $(DYNAMIC_SHELL)==0 && $(FOR_WIN10)==0
|
!IF $(DYNAMIC_SHELL)==0 && $(FOR_WIN10)==0
|
||||||
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_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
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
# <<mark>>
|
# <<mark>>
|
||||||
@@ -1742,7 +1747,10 @@ ctime.lo: $(TOP)\src\ctime.c $(HDR)
|
|||||||
date.lo: $(TOP)\src\date.c $(HDR)
|
date.lo: $(TOP)\src\date.c $(HDR)
|
||||||
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\date.c
|
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\date.c
|
||||||
|
|
||||||
dbstat.lo: $(TOP)\src\date.c $(HDR)
|
dbpage.lo: $(TOP)\src\dbpage.c $(HDR)
|
||||||
|
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\dbpage.c
|
||||||
|
|
||||||
|
dbstat.lo: $(TOP)\src\dbstat.c $(HDR)
|
||||||
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\dbstat.c
|
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\dbstat.c
|
||||||
|
|
||||||
delete.lo: $(TOP)\src\delete.c $(HDR)
|
delete.lo: $(TOP)\src\delete.c $(HDR)
|
||||||
@@ -1926,7 +1934,7 @@ tclsqlite.lo: $(TOP)\src\tclsqlite.c $(HDR) $(SQLITE_TCL_DEP)
|
|||||||
$(LTCOMPILE) $(NO_WARN) -DUSE_TCL_STUBS=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c
|
$(LTCOMPILE) $(NO_WARN) -DUSE_TCL_STUBS=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c
|
||||||
|
|
||||||
tclsqlite-shell.lo: $(TOP)\src\tclsqlite.c $(HDR) $(SQLITE_TCL_DEP)
|
tclsqlite-shell.lo: $(TOP)\src\tclsqlite.c $(HDR) $(SQLITE_TCL_DEP)
|
||||||
$(LTCOMPILE) $(NO_WARN) -DTCLSH=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c
|
$(LTCOMPILE) $(NO_WARN) -DTCLSH -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c
|
||||||
|
|
||||||
tclsqlite3.exe: tclsqlite-shell.lo $(SQLITE3C) $(SQLITE3H) $(LIBRESOBJS)
|
tclsqlite3.exe: tclsqlite-shell.lo $(SQLITE3C) $(SQLITE3H) $(LIBRESOBJS)
|
||||||
$(LTLINK) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite-shell.lo $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
|
$(LTLINK) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite-shell.lo $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
|
||||||
@@ -2097,12 +2105,13 @@ sqlite3rbu.lo: $(TOP)\ext\rbu\sqlite3rbu.c $(HDR) $(EXTHDR)
|
|||||||
# necessary because the test fixture requires non-API symbols which are
|
# necessary because the test fixture requires non-API symbols which are
|
||||||
# hidden when the library is built via the amalgamation).
|
# hidden when the library is built via the amalgamation).
|
||||||
#
|
#
|
||||||
TESTFIXTURE_FLAGS = -DTCLSH=1 -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
|
TESTFIXTURE_FLAGS = -DTCLSH_INIT_PROC=sqlite3TestInit -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
|
||||||
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERVER=1 -DSQLITE_PRIVATE=""
|
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERVER=1 -DSQLITE_PRIVATE=""
|
||||||
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_CORE $(NO_WARN)
|
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_CORE $(NO_WARN)
|
||||||
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
|
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
|
||||||
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_DEFAULT_PAGE_SIZE=1024
|
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_DEFAULT_PAGE_SIZE=1024
|
||||||
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB
|
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB
|
||||||
|
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB
|
||||||
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) $(TEST_CCONV_OPTS)
|
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) $(TEST_CCONV_OPTS)
|
||||||
|
|
||||||
TESTFIXTURE_SRC0 = $(TESTEXT) $(TESTSRC2)
|
TESTFIXTURE_SRC0 = $(TESTEXT) $(TESTSRC2)
|
||||||
@@ -2182,14 +2191,8 @@ smoketest: $(TESTPROGS)
|
|||||||
@set PATH=$(LIBTCLPATH);$(PATH)
|
@set PATH=$(LIBTCLPATH);$(PATH)
|
||||||
.\testfixture.exe $(TOP)\test\main.test $(TESTOPTS)
|
.\testfixture.exe $(TOP)\test\main.test $(TESTOPTS)
|
||||||
|
|
||||||
sqlite3_analyzer.c: $(SQLITE3C) $(SQLITE3H) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl $(SQLITE_TCL_DEP)
|
sqlite3_analyzer.c: $(SQLITE3C) $(SQLITE3H) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqlite3_analyzer.c.in $(SQLITE_TCL_DEP)
|
||||||
echo #define TCLSH 2 > $@
|
$(TCLSH_CMD) $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqlite3_analyzer.c.in > $@
|
||||||
echo #define SQLITE_ENABLE_DBSTAT_VTAB 1 >> $@
|
|
||||||
copy $@ + $(SQLITE3C) + $(TOP)\src\tclsqlite.c $@
|
|
||||||
echo static const char *tclsh_main_loop(void){ >> $@
|
|
||||||
echo static const char *zMainloop = >> $@
|
|
||||||
$(TCLSH_CMD) $(TOP)\tool\tostr.tcl $(TOP)\tool\spaceanal.tcl >> $@
|
|
||||||
echo ; return zMainloop; } >> $@
|
|
||||||
|
|
||||||
sqlite3_analyzer.exe: sqlite3_analyzer.c $(LIBRESOBJS)
|
sqlite3_analyzer.exe: sqlite3_analyzer.c $(LIBRESOBJS)
|
||||||
$(LTLINK) $(NO_WARN) -DBUILD_sqlite -I$(TCLINCDIR) sqlite3_analyzer.c \
|
$(LTLINK) $(NO_WARN) -DBUILD_sqlite -I$(TCLINCDIR) sqlite3_analyzer.c \
|
||||||
|
@@ -928,6 +928,7 @@ LIBRESOBJS =
|
|||||||
#
|
#
|
||||||
!IF $(DYNAMIC_SHELL)==0 && $(FOR_WIN10)==0
|
!IF $(DYNAMIC_SHELL)==0 && $(FOR_WIN10)==0
|
||||||
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_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
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
|
|
||||||
|
16
ext/repair/README.md
Normal file
16
ext/repair/README.md
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
This folder contains extensions and utility programs intended to analyze
|
||||||
|
live database files, detect problems, and possibly fix them.
|
||||||
|
|
||||||
|
As SQLite is being used on larger and larger databases, database sizes
|
||||||
|
are growing into the terabyte range. At that size, hardware malfunctions
|
||||||
|
and/or cosmic rays will occasionally corrupt a database file. Detecting
|
||||||
|
problems and fixing errors a terabyte-sized databases can take hours or days,
|
||||||
|
and it is undesirable to take applications that depend on the databases
|
||||||
|
off-line for such a long time.
|
||||||
|
The utilities in the folder are intended to provide mechanisms for
|
||||||
|
detecting and fixing problems in large databases while those databases
|
||||||
|
are in active use.
|
||||||
|
|
||||||
|
The utilities and extensions in this folder are experimental and under
|
||||||
|
active development at the time of this writing (2017-10-12). If and when
|
||||||
|
they stabilize, this README will be updated to reflect that fact.
|
299
ext/repair/checkfreelist.c
Normal file
299
ext/repair/checkfreelist.c
Normal file
@@ -0,0 +1,299 @@
|
|||||||
|
/*
|
||||||
|
** 2017 October 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.
|
||||||
|
**
|
||||||
|
*************************************************************************
|
||||||
|
**
|
||||||
|
** This module exports a single C function:
|
||||||
|
**
|
||||||
|
** int sqlite3_check_freelist(sqlite3 *db, const char *zDb);
|
||||||
|
**
|
||||||
|
** This function checks the free-list in database zDb (one of "main",
|
||||||
|
** "temp", etc.) and reports any errors by invoking the sqlite3_log()
|
||||||
|
** function. It returns SQLITE_OK if successful, or an SQLite error
|
||||||
|
** code otherwise. It is not an error if the free-list is corrupted but
|
||||||
|
** no IO or OOM errors occur.
|
||||||
|
**
|
||||||
|
** If this file is compiled and loaded as an SQLite loadable extension,
|
||||||
|
** it adds an SQL function "checkfreelist" to the database handle, to
|
||||||
|
** be invoked as follows:
|
||||||
|
**
|
||||||
|
** SELECT checkfreelist(<database-name>);
|
||||||
|
**
|
||||||
|
** This function performs the same checks as sqlite3_check_freelist(),
|
||||||
|
** except that it returns all error messages as a single text value,
|
||||||
|
** separated by newline characters. If the freelist is not corrupted
|
||||||
|
** in any way, an empty string is returned.
|
||||||
|
**
|
||||||
|
** To compile this module for use as an SQLite loadable extension:
|
||||||
|
**
|
||||||
|
** gcc -Os -fPIC -shared checkfreelist.c -o checkfreelist.so
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sqlite3ext.h"
|
||||||
|
SQLITE_EXTENSION_INIT1
|
||||||
|
|
||||||
|
#ifndef SQLITE_AMALGAMATION
|
||||||
|
# include <string.h>
|
||||||
|
# include <stdio.h>
|
||||||
|
# include <stdlib.h>
|
||||||
|
# include <assert.h>
|
||||||
|
# define ALWAYS(X) 1
|
||||||
|
# define NEVER(X) 0
|
||||||
|
typedef unsigned char u8;
|
||||||
|
typedef unsigned short u16;
|
||||||
|
typedef unsigned int u32;
|
||||||
|
#define get4byte(x) ( \
|
||||||
|
((u32)((x)[0])<<24) + \
|
||||||
|
((u32)((x)[1])<<16) + \
|
||||||
|
((u32)((x)[2])<<8) + \
|
||||||
|
((u32)((x)[3])) \
|
||||||
|
)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Execute a single PRAGMA statement and return the integer value returned
|
||||||
|
** via output parameter (*pnOut).
|
||||||
|
**
|
||||||
|
** The SQL statement passed as the third argument should be a printf-style
|
||||||
|
** format string containing a single "%s" which will be replace by the
|
||||||
|
** value passed as the second argument. e.g.
|
||||||
|
**
|
||||||
|
** sqlGetInteger(db, "main", "PRAGMA %s.page_count", pnOut)
|
||||||
|
**
|
||||||
|
** executes "PRAGMA main.page_count" and stores the results in (*pnOut).
|
||||||
|
*/
|
||||||
|
static int sqlGetInteger(
|
||||||
|
sqlite3 *db, /* Database handle */
|
||||||
|
const char *zDb, /* Database name ("main", "temp" etc.) */
|
||||||
|
const char *zFmt, /* SQL statement format */
|
||||||
|
u32 *pnOut /* OUT: Integer value */
|
||||||
|
){
|
||||||
|
int rc, rc2;
|
||||||
|
char *zSql;
|
||||||
|
sqlite3_stmt *pStmt = 0;
|
||||||
|
int bOk = 0;
|
||||||
|
|
||||||
|
zSql = sqlite3_mprintf(zFmt, zDb);
|
||||||
|
if( zSql==0 ){
|
||||||
|
rc = SQLITE_NOMEM;
|
||||||
|
}else{
|
||||||
|
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
|
||||||
|
sqlite3_free(zSql);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
|
||||||
|
*pnOut = (u32)sqlite3_column_int(pStmt, 0);
|
||||||
|
bOk = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc2 = sqlite3_finalize(pStmt);
|
||||||
|
if( rc==SQLITE_OK ) rc = rc2;
|
||||||
|
if( rc==SQLITE_OK && bOk==0 ) rc = SQLITE_ERROR;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Argument zFmt must be a printf-style format string and must be
|
||||||
|
** followed by its required arguments. If argument pzOut is NULL,
|
||||||
|
** then the results of printf()ing the format string are passed to
|
||||||
|
** sqlite3_log(). Otherwise, they are appended to the string
|
||||||
|
** at (*pzOut).
|
||||||
|
*/
|
||||||
|
static int checkFreelistError(char **pzOut, const char *zFmt, ...){
|
||||||
|
int rc = SQLITE_OK;
|
||||||
|
char *zErr = 0;
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, zFmt);
|
||||||
|
zErr = sqlite3_vmprintf(zFmt, ap);
|
||||||
|
if( zErr==0 ){
|
||||||
|
rc = SQLITE_NOMEM;
|
||||||
|
}else{
|
||||||
|
if( pzOut ){
|
||||||
|
*pzOut = sqlite3_mprintf("%s%z%s", *pzOut?"\n":"", *pzOut, zErr);
|
||||||
|
if( *pzOut==0 ) rc = SQLITE_NOMEM;
|
||||||
|
}else{
|
||||||
|
sqlite3_log(SQLITE_ERROR, "checkfreelist: %s", zErr);
|
||||||
|
}
|
||||||
|
sqlite3_free(zErr);
|
||||||
|
}
|
||||||
|
va_end(ap);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int checkFreelist(
|
||||||
|
sqlite3 *db,
|
||||||
|
const char *zDb,
|
||||||
|
char **pzOut
|
||||||
|
){
|
||||||
|
/* This query returns one row for each page on the free list. Each row has
|
||||||
|
** two columns - the page number and page content. */
|
||||||
|
const char *zTrunk =
|
||||||
|
"WITH freelist_trunk(i, d, n) AS ("
|
||||||
|
"SELECT 1, NULL, sqlite_readint32(data, 32) "
|
||||||
|
"FROM sqlite_dbpage(:1) WHERE pgno=1 "
|
||||||
|
"UNION ALL "
|
||||||
|
"SELECT n, data, sqlite_readint32(data) "
|
||||||
|
"FROM freelist_trunk, sqlite_dbpage(:1) WHERE pgno=n "
|
||||||
|
")"
|
||||||
|
"SELECT i, d FROM freelist_trunk WHERE i!=1;";
|
||||||
|
|
||||||
|
int rc, rc2; /* Return code */
|
||||||
|
sqlite3_stmt *pTrunk = 0; /* Compilation of zTrunk */
|
||||||
|
u32 nPage = 0; /* Number of pages in db */
|
||||||
|
u32 nExpected = 0; /* Expected number of free pages */
|
||||||
|
u32 nFree = 0; /* Number of pages on free list */
|
||||||
|
|
||||||
|
if( zDb==0 ) zDb = "main";
|
||||||
|
|
||||||
|
if( (rc = sqlGetInteger(db, zDb, "PRAGMA %s.page_count", &nPage))
|
||||||
|
|| (rc = sqlGetInteger(db, zDb, "PRAGMA %s.freelist_count", &nExpected))
|
||||||
|
){
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = sqlite3_prepare_v2(db, zTrunk, -1, &pTrunk, 0);
|
||||||
|
if( rc!=SQLITE_OK ) return rc;
|
||||||
|
sqlite3_bind_text(pTrunk, 1, zDb, -1, SQLITE_STATIC);
|
||||||
|
while( rc==SQLITE_OK && sqlite3_step(pTrunk)==SQLITE_ROW ){
|
||||||
|
u32 i;
|
||||||
|
u32 iTrunk = (u32)sqlite3_column_int(pTrunk, 0);
|
||||||
|
const u8 *aData = (const u8*)sqlite3_column_blob(pTrunk, 1);
|
||||||
|
int nData = sqlite3_column_bytes(pTrunk, 1);
|
||||||
|
u32 iNext = get4byte(&aData[0]);
|
||||||
|
u32 nLeaf = get4byte(&aData[4]);
|
||||||
|
|
||||||
|
if( nLeaf>((nData/4)-2-6) ){
|
||||||
|
rc = checkFreelistError(pzOut,
|
||||||
|
"leaf count out of range (%d) on trunk page %d",
|
||||||
|
(int)nLeaf, (int)iTrunk
|
||||||
|
);
|
||||||
|
nLeaf = (nData/4) - 2 - 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
nFree += 1+nLeaf;
|
||||||
|
if( iNext>nPage ){
|
||||||
|
rc = checkFreelistError(pzOut,
|
||||||
|
"trunk page %d is out of range", (int)iNext
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=0; rc==SQLITE_OK && i<nLeaf; i++){
|
||||||
|
u32 iLeaf = get4byte(&aData[8 + 4*i]);
|
||||||
|
if( iLeaf==0 || iLeaf>nPage ){
|
||||||
|
rc = checkFreelistError(pzOut,
|
||||||
|
"leaf page %d is out of range (child %d of trunk page %d)",
|
||||||
|
(int)iLeaf, (int)i, (int)iTrunk
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( rc==SQLITE_OK && nFree!=nExpected ){
|
||||||
|
rc = checkFreelistError(pzOut,
|
||||||
|
"free-list count mismatch: actual=%d header=%d",
|
||||||
|
(int)nFree, (int)nExpected
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc2 = sqlite3_finalize(pTrunk);
|
||||||
|
if( rc==SQLITE_OK ) rc = rc2;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sqlite3_check_freelist(sqlite3 *db, const char *zDb){
|
||||||
|
return checkFreelist(db, zDb, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void checkfreelist_function(
|
||||||
|
sqlite3_context *pCtx,
|
||||||
|
int nArg,
|
||||||
|
sqlite3_value **apArg
|
||||||
|
){
|
||||||
|
const char *zDb;
|
||||||
|
int rc;
|
||||||
|
char *zOut = 0;
|
||||||
|
sqlite3 *db = sqlite3_context_db_handle(pCtx);
|
||||||
|
|
||||||
|
assert( nArg==1 );
|
||||||
|
zDb = (const char*)sqlite3_value_text(apArg[0]);
|
||||||
|
rc = checkFreelist(db, zDb, &zOut);
|
||||||
|
if( rc==SQLITE_OK ){
|
||||||
|
sqlite3_result_text(pCtx, zOut?zOut:"ok", -1, SQLITE_TRANSIENT);
|
||||||
|
}else{
|
||||||
|
sqlite3_result_error_code(pCtx, rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_free(zOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** An SQL function invoked as follows:
|
||||||
|
**
|
||||||
|
** sqlite_readint32(BLOB) -- Decode 32-bit integer from start of blob
|
||||||
|
*/
|
||||||
|
static void readint_function(
|
||||||
|
sqlite3_context *pCtx,
|
||||||
|
int nArg,
|
||||||
|
sqlite3_value **apArg
|
||||||
|
){
|
||||||
|
const u8 *zBlob;
|
||||||
|
int nBlob;
|
||||||
|
int iOff = 0;
|
||||||
|
u32 iRet = 0;
|
||||||
|
|
||||||
|
if( nArg!=1 && nArg!=2 ){
|
||||||
|
sqlite3_result_error(
|
||||||
|
pCtx, "wrong number of arguments to function sqlite_readint32()", -1
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if( nArg==2 ){
|
||||||
|
iOff = sqlite3_value_int(apArg[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
zBlob = sqlite3_value_blob(apArg[0]);
|
||||||
|
nBlob = sqlite3_value_bytes(apArg[0]);
|
||||||
|
|
||||||
|
if( nBlob>=(iOff+4) ){
|
||||||
|
iRet = get4byte(&zBlob[iOff]);
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_result_int64(pCtx, (sqlite3_int64)iRet);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Register the SQL functions.
|
||||||
|
*/
|
||||||
|
static int cflRegister(sqlite3 *db){
|
||||||
|
int rc = sqlite3_create_function(
|
||||||
|
db, "sqlite_readint32", -1, SQLITE_UTF8, 0, readint_function, 0, 0
|
||||||
|
);
|
||||||
|
if( rc!=SQLITE_OK ) return rc;
|
||||||
|
rc = sqlite3_create_function(
|
||||||
|
db, "checkfreelist", 1, SQLITE_UTF8, 0, checkfreelist_function, 0, 0
|
||||||
|
);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Extension load function.
|
||||||
|
*/
|
||||||
|
#ifdef _WIN32
|
||||||
|
__declspec(dllexport)
|
||||||
|
#endif
|
||||||
|
int sqlite3_checkfreelist_init(
|
||||||
|
sqlite3 *db,
|
||||||
|
char **pzErrMsg,
|
||||||
|
const sqlite3_api_routines *pApi
|
||||||
|
){
|
||||||
|
SQLITE_EXTENSION_INIT2(pApi);
|
||||||
|
return cflRegister(db);
|
||||||
|
}
|
29
main.mk
29
main.mk
@@ -55,7 +55,8 @@ THREADLIB += $(LIBS)
|
|||||||
LIBOBJ+= vdbe.o parse.o \
|
LIBOBJ+= vdbe.o parse.o \
|
||||||
alter.o analyze.o attach.o auth.o \
|
alter.o analyze.o attach.o auth.o \
|
||||||
backup.o bitvec.o btmutex.o btree.o build.o \
|
backup.o bitvec.o btmutex.o btree.o build.o \
|
||||||
callback.o complete.o ctime.o date.o dbstat.o delete.o expr.o \
|
callback.o complete.o ctime.o \
|
||||||
|
date.o dbpage.o dbstat.o delete.o expr.o \
|
||||||
fault.o fkey.o \
|
fault.o fkey.o \
|
||||||
fts3.o fts3_aux.o fts3_expr.o fts3_hash.o fts3_icu.o fts3_porter.o \
|
fts3.o fts3_aux.o fts3_expr.o fts3_hash.o fts3_icu.o fts3_porter.o \
|
||||||
fts3_snippet.o fts3_tokenizer.o fts3_tokenizer1.o \
|
fts3_snippet.o fts3_tokenizer.o fts3_tokenizer1.o \
|
||||||
@@ -96,6 +97,7 @@ SRC = \
|
|||||||
$(TOP)/src/complete.c \
|
$(TOP)/src/complete.c \
|
||||||
$(TOP)/src/ctime.c \
|
$(TOP)/src/ctime.c \
|
||||||
$(TOP)/src/date.c \
|
$(TOP)/src/date.c \
|
||||||
|
$(TOP)/src/dbpage.c \
|
||||||
$(TOP)/src/dbstat.c \
|
$(TOP)/src/dbstat.c \
|
||||||
$(TOP)/src/delete.c \
|
$(TOP)/src/delete.c \
|
||||||
$(TOP)/src/expr.c \
|
$(TOP)/src/expr.c \
|
||||||
@@ -306,6 +308,7 @@ TESTSRC = \
|
|||||||
$(TOP)/src/test_intarray.c \
|
$(TOP)/src/test_intarray.c \
|
||||||
$(TOP)/src/test_journal.c \
|
$(TOP)/src/test_journal.c \
|
||||||
$(TOP)/src/test_malloc.c \
|
$(TOP)/src/test_malloc.c \
|
||||||
|
$(TOP)/src/test_md5.c \
|
||||||
$(TOP)/src/test_multiplex.c \
|
$(TOP)/src/test_multiplex.c \
|
||||||
$(TOP)/src/test_mutex.c \
|
$(TOP)/src/test_mutex.c \
|
||||||
$(TOP)/src/test_onefile.c \
|
$(TOP)/src/test_onefile.c \
|
||||||
@@ -318,6 +321,7 @@ TESTSRC = \
|
|||||||
$(TOP)/src/test_sqllog.c \
|
$(TOP)/src/test_sqllog.c \
|
||||||
$(TOP)/src/test_superlock.c \
|
$(TOP)/src/test_superlock.c \
|
||||||
$(TOP)/src/test_syscall.c \
|
$(TOP)/src/test_syscall.c \
|
||||||
|
$(TOP)/src/test_tclsh.c \
|
||||||
$(TOP)/src/test_tclvar.c \
|
$(TOP)/src/test_tclvar.c \
|
||||||
$(TOP)/src/test_thread.c \
|
$(TOP)/src/test_thread.c \
|
||||||
$(TOP)/src/test_vfs.c \
|
$(TOP)/src/test_vfs.c \
|
||||||
@@ -360,6 +364,7 @@ TESTSRC2 = \
|
|||||||
$(TOP)/src/btree.c \
|
$(TOP)/src/btree.c \
|
||||||
$(TOP)/src/build.c \
|
$(TOP)/src/build.c \
|
||||||
$(TOP)/src/date.c \
|
$(TOP)/src/date.c \
|
||||||
|
$(TOP)/src/dbpage.c \
|
||||||
$(TOP)/src/dbstat.c \
|
$(TOP)/src/dbstat.c \
|
||||||
$(TOP)/src/expr.c \
|
$(TOP)/src/expr.c \
|
||||||
$(TOP)/src/func.c \
|
$(TOP)/src/func.c \
|
||||||
@@ -481,6 +486,8 @@ SHELL_OPT += -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
|
|||||||
SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
|
SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
|
||||||
SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
|
SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
|
||||||
SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
|
SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
|
||||||
|
SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
|
||||||
|
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
|
||||||
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
|
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
|
||||||
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
|
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
|
||||||
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
|
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
|
||||||
@@ -770,17 +777,11 @@ sqlite3rbu.o: $(TOP)/ext/rbu/sqlite3rbu.c $(HDR) $(EXTHDR)
|
|||||||
# Rules for building test programs and for running tests
|
# Rules for building test programs and for running tests
|
||||||
#
|
#
|
||||||
tclsqlite3: $(TOP)/src/tclsqlite.c libsqlite3.a
|
tclsqlite3: $(TOP)/src/tclsqlite.c libsqlite3.a
|
||||||
$(TCCX) $(TCL_FLAGS) -DTCLSH=1 -o tclsqlite3 \
|
$(TCCX) $(TCL_FLAGS) -DTCLSH -o tclsqlite3 \
|
||||||
$(TOP)/src/tclsqlite.c libsqlite3.a $(LIBTCL) $(THREADLIB)
|
$(TOP)/src/tclsqlite.c libsqlite3.a $(LIBTCL) $(THREADLIB)
|
||||||
|
|
||||||
sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl
|
sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl $(TOP)/tool/sqlite3_analyzer.c.in $(TOP)/tool/mkccode.tcl
|
||||||
echo "#define TCLSH 2" > $@
|
tclsh $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c
|
||||||
echo "#define SQLITE_ENABLE_DBSTAT_VTAB 1" >> $@
|
|
||||||
cat sqlite3.c $(TOP)/src/tclsqlite.c >> $@
|
|
||||||
echo "static const char *tclsh_main_loop(void){" >> $@
|
|
||||||
echo "static const char *zMainloop = " >> $@
|
|
||||||
tclsh $(TOP)/tool/tostr.tcl $(TOP)/tool/spaceanal.tcl >> $@
|
|
||||||
echo "; return zMainloop; }" >> $@
|
|
||||||
|
|
||||||
sqlite3_analyzer$(EXE): sqlite3_analyzer.c
|
sqlite3_analyzer$(EXE): sqlite3_analyzer.c
|
||||||
$(TCCX) $(TCL_FLAGS) sqlite3_analyzer.c -o $@ $(LIBTCL) $(THREADLIB)
|
$(TCCX) $(TCL_FLAGS) sqlite3_analyzer.c -o $@ $(LIBTCL) $(THREADLIB)
|
||||||
@@ -796,21 +797,23 @@ TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE
|
|||||||
TESTFIXTURE_FLAGS += -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
|
TESTFIXTURE_FLAGS += -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
|
||||||
TESTFIXTURE_FLAGS += -DSQLITE_DEFAULT_PAGE_SIZE=1024
|
TESTFIXTURE_FLAGS += -DSQLITE_DEFAULT_PAGE_SIZE=1024
|
||||||
TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_STMTVTAB
|
TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_STMTVTAB
|
||||||
|
TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_DBPAGE_VTAB
|
||||||
|
TESTFIXTURE_FLAGS += -DTCLSH_INIT_PROC=sqlite3TestInit
|
||||||
|
|
||||||
testfixture$(EXE): $(TESTSRC2) libsqlite3.a $(TESTSRC) $(TOP)/src/tclsqlite.c
|
testfixture$(EXE): $(TESTSRC2) libsqlite3.a $(TESTSRC) $(TOP)/src/tclsqlite.c
|
||||||
$(TCCX) $(TCL_FLAGS) -DTCLSH=1 $(TESTFIXTURE_FLAGS) \
|
$(TCCX) $(TCL_FLAGS) $(TESTFIXTURE_FLAGS) \
|
||||||
$(TESTSRC) $(TESTSRC2) $(TOP)/src/tclsqlite.c \
|
$(TESTSRC) $(TESTSRC2) $(TOP)/src/tclsqlite.c \
|
||||||
-o testfixture$(EXE) $(LIBTCL) libsqlite3.a $(THREADLIB)
|
-o testfixture$(EXE) $(LIBTCL) libsqlite3.a $(THREADLIB)
|
||||||
|
|
||||||
amalgamation-testfixture$(EXE): sqlite3.c $(TESTSRC) $(TOP)/src/tclsqlite.c \
|
amalgamation-testfixture$(EXE): sqlite3.c $(TESTSRC) $(TOP)/src/tclsqlite.c \
|
||||||
$(TOP)/ext/session/test_session.c
|
$(TOP)/ext/session/test_session.c
|
||||||
$(TCCX) $(TCL_FLAGS) -DTCLSH=1 $(TESTFIXTURE_FLAGS) \
|
$(TCCX) $(TCL_FLAGS) $(TESTFIXTURE_FLAGS) \
|
||||||
$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c \
|
$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c \
|
||||||
$(TOP)/ext/session/test_session.c \
|
$(TOP)/ext/session/test_session.c \
|
||||||
-o testfixture$(EXE) $(LIBTCL) $(THREADLIB)
|
-o testfixture$(EXE) $(LIBTCL) $(THREADLIB)
|
||||||
|
|
||||||
fts3-testfixture$(EXE): sqlite3.c fts3amal.c $(TESTSRC) $(TOP)/src/tclsqlite.c
|
fts3-testfixture$(EXE): sqlite3.c fts3amal.c $(TESTSRC) $(TOP)/src/tclsqlite.c
|
||||||
$(TCCX) $(TCL_FLAGS) -DTCLSH=1 $(TESTFIXTURE_FLAGS) \
|
$(TCCX) $(TCL_FLAGS) $(TESTFIXTURE_FLAGS) \
|
||||||
-DSQLITE_ENABLE_FTS3=1 \
|
-DSQLITE_ENABLE_FTS3=1 \
|
||||||
$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c fts3amal.c \
|
$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c fts3amal.c \
|
||||||
-o testfixture$(EXE) $(LIBTCL) $(THREADLIB)
|
-o testfixture$(EXE) $(LIBTCL) $(THREADLIB)
|
||||||
|
63
manifest
63
manifest
@@ -1,8 +1,8 @@
|
|||||||
C Updates\sto\sthe\sMakefiles\sfor\sMSVC.\s\sCherrypick\sof\s[ac8786f3f9f35cb6].
|
C Merge\sall\sthe\senhancements\sand\sbug\sfixes\sfrom\strunk,\ssince\snone\sare\ndestablizing.\s\sCall\sthis\sthe\ssecond\sbeta.
|
||||||
D 2017-10-14T19:58:37.221
|
D 2017-10-21T17:17:17.187
|
||||||
F Makefile.in 9c9f4dea3f622464cba9768501aceca187d2bbae10b60bf420b531cd776fe5c0
|
F Makefile.in e016061b23e60ac9ec27c65cb577292b6bde0307ca55abd874ab3487b3b1beb2
|
||||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||||
F Makefile.msc 4a7ebdaacec1abd415d2847c8f5b42053c5963294e925672d43d2972a5bb2cb6
|
F Makefile.msc 37740aba9c4bb359c627eadccf1cfd7be4f5f847078723777ea7763969e533b1
|
||||||
F README.md f5c87359573c4d255425e588a56554b50fdcc2afba4e017a2e02a43701456afd
|
F README.md f5c87359573c4d255425e588a56554b50fdcc2afba4e017a2e02a43701456afd
|
||||||
F VERSION f81232df28e2d3ff049feefad5fbd5489cc33697f6bd2ecf61af7f0dde3b83d0
|
F VERSION f81232df28e2d3ff049feefad5fbd5489cc33697f6bd2ecf61af7f0dde3b83d0
|
||||||
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
||||||
@@ -11,7 +11,7 @@ F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
|
|||||||
F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
|
F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
|
||||||
F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903
|
F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903
|
||||||
F autoconf/Makefile.am 1a47d071e3d5435f8f7ebff7eb6703848bbd65d4
|
F autoconf/Makefile.am 1a47d071e3d5435f8f7ebff7eb6703848bbd65d4
|
||||||
F autoconf/Makefile.msc b045158822d2320d5551cb7291ecc685dd6123324b928490691deed71274c305
|
F autoconf/Makefile.msc 645b8a9774281515dc4a8de65d8a914f7b418ba8bd1c48b53ccbf43d3b339715
|
||||||
F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7
|
F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7
|
||||||
F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1
|
F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1
|
||||||
F autoconf/configure.ac 2893b823ecc86cea13739f6c8109a41392254d1db08235c5615e0af5722c8578
|
F autoconf/configure.ac 2893b823ecc86cea13739f6c8109a41392254d1db08235c5615e0af5722c8578
|
||||||
@@ -325,6 +325,8 @@ F ext/rbu/rbuvacuum2.test 2074ab14fe66e1c7e7210c62562650dcd215bbaa
|
|||||||
F ext/rbu/sqlite3rbu.c 64bd08c1011456f90564ed167abce3a9c2af421a924b21eb57231e078da04feb
|
F ext/rbu/sqlite3rbu.c 64bd08c1011456f90564ed167abce3a9c2af421a924b21eb57231e078da04feb
|
||||||
F ext/rbu/sqlite3rbu.h b42bcd4d8357268c6c39ab2a60b29c091e89328fa8cc49c8fac5ab8d007e79b2
|
F ext/rbu/sqlite3rbu.h b42bcd4d8357268c6c39ab2a60b29c091e89328fa8cc49c8fac5ab8d007e79b2
|
||||||
F ext/rbu/test_rbu.c 7073979b9cc80912bb03599ac8d85ab5d3bf03cfacd3463f2dcdd7822997533a
|
F ext/rbu/test_rbu.c 7073979b9cc80912bb03599ac8d85ab5d3bf03cfacd3463f2dcdd7822997533a
|
||||||
|
F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15
|
||||||
|
F ext/repair/checkfreelist.c 0abb84b4545016d57ba1a2aa8884c72c73ed838968909858c03bc1f38fb6b054
|
||||||
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
|
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
|
||||||
F ext/rtree/rtree.c f2fd34db37ea053798f8e66b44a473449b21301d2b92505ee576823789e909fb
|
F ext/rtree/rtree.c f2fd34db37ea053798f8e66b44a473449b21301d2b92505ee576823789e909fb
|
||||||
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
|
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
|
||||||
@@ -382,7 +384,7 @@ F ext/userauth/userauth.c 3410be31283abba70255d71fd24734e017a4497f
|
|||||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||||
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
|
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
|
||||||
F main.mk 3e671408634fb8e8eaa296e80627066a2524053db5a9c5c28c6ec06cf7e99a51
|
F main.mk a39528d993afc1f0c0aebde2e3623ab4171d3bba484eea1e5241615c706c9ce8
|
||||||
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
|
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
|
||||||
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
|
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
|
||||||
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
|
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
|
||||||
@@ -401,14 +403,15 @@ F src/auth.c 6277d63837357549fe14e723490d6dc1a38768d71c795c5eb5c0f8a99f918f73
|
|||||||
F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b
|
F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b
|
||||||
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
|
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
|
||||||
F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca
|
F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca
|
||||||
F src/btree.c 8565b061a6a6fad850230c73d6a7a8ffb88f3370e3352a8689a9a672160c5cc5
|
F src/btree.c 75229a5a47985997f861b428552acd14fe42b657f755cba5e0b1a007bd77b2ea
|
||||||
F src/btree.h 32ef5d3f25dc70ef1ee9cecf84a023c21378f06a57cd701d2e866e141b150f09
|
F src/btree.h 32ef5d3f25dc70ef1ee9cecf84a023c21378f06a57cd701d2e866e141b150f09
|
||||||
F src/btreeInt.h 55b702efce17e5d1941865464227d3802cfc9c7c832fac81d4c94dced47a71fc
|
F src/btreeInt.h 55b702efce17e5d1941865464227d3802cfc9c7c832fac81d4c94dced47a71fc
|
||||||
F src/build.c 6ffe76970aeee4bc94e60cf0138269e67109061a853e13098c38a904dd66e673
|
F src/build.c e24b61144f9c9b15c4aa05954514190361061da721e56dcd1af6e0e945ee5909
|
||||||
F src/callback.c 28a8ede982fde4129b828350f78f2c01fe7d12c74d1a0a05d7108ab36f308688
|
F src/callback.c 28a8ede982fde4129b828350f78f2c01fe7d12c74d1a0a05d7108ab36f308688
|
||||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||||
F src/ctime.c ff1be3eed7bdd75aaca61ca8dc848f7c9f850ef2fb9cb56f2734e922a098f9c0
|
F src/ctime.c ff1be3eed7bdd75aaca61ca8dc848f7c9f850ef2fb9cb56f2734e922a098f9c0
|
||||||
F src/date.c 48f743d88bbe88f848532d333cca84f26e52a4f217e86f86be7fc1b919c33d74
|
F src/date.c 48f743d88bbe88f848532d333cca84f26e52a4f217e86f86be7fc1b919c33d74
|
||||||
|
F src/dbpage.c c625a0bd605d4cea9a3258b8db49a5474a04976e95a9fe380cdaf74e8eb6736d
|
||||||
F src/dbstat.c 7a4ba8518b6369ef3600c49cf9c918ad979acba610b2aebef1b656d649b96720
|
F src/dbstat.c 7a4ba8518b6369ef3600c49cf9c918ad979acba610b2aebef1b656d649b96720
|
||||||
F src/delete.c 21a5f1812fdb599e9f7afb9f650bdabab60a3afd51d7e94e539c982f647b0023
|
F src/delete.c 21a5f1812fdb599e9f7afb9f650bdabab60a3afd51d7e94e539c982f647b0023
|
||||||
F src/expr.c 4d2d0aafd945424f638ee03e11330f03288ccf616e025498f3c8602d01609a0a
|
F src/expr.c 4d2d0aafd945424f638ee03e11330f03288ccf616e025498f3c8602d01609a0a
|
||||||
@@ -423,7 +426,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
|
|||||||
F src/insert.c 1f33ef4ca0553b60fff03aa171370f8709a3e945acfcc68ccafc92752d872f40
|
F src/insert.c 1f33ef4ca0553b60fff03aa171370f8709a3e945acfcc68ccafc92752d872f40
|
||||||
F src/legacy.c 134ab3e3fae00a0f67a5187981d6935b24b337bcf0f4b3e5c9fa5763da95bf4e
|
F src/legacy.c 134ab3e3fae00a0f67a5187981d6935b24b337bcf0f4b3e5c9fa5763da95bf4e
|
||||||
F src/loadext.c 20865b183bb8a3723d59cf1efffc3c50217eb452c1021d077b908c94da26b0b2
|
F src/loadext.c 20865b183bb8a3723d59cf1efffc3c50217eb452c1021d077b908c94da26b0b2
|
||||||
F src/main.c a4bdadaaa827e7380cba4de878ed7947dab5aeb84f617118ba6a0422cd745b4b
|
F src/main.c 54637b9e7f91de6d281e577cd1a997762a4613f51a0509790027ca9865185d7c
|
||||||
F src/malloc.c a02c9e69bc76bee0f639416b947a946412890b606301454727feadcb313536d6
|
F src/malloc.c a02c9e69bc76bee0f639416b947a946412890b606301454727feadcb313536d6
|
||||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||||
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
|
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
|
||||||
@@ -456,18 +459,18 @@ F src/pragma.h bb83728944b42f6d409c77f5838a8edbdb0fe83046c5496ffc9602b40340a324
|
|||||||
F src/prepare.c 9a141a1b02dca53beaa9771699d390aafcac01f5d1f1c0ae6e23ded8dcdb709a
|
F src/prepare.c 9a141a1b02dca53beaa9771699d390aafcac01f5d1f1c0ae6e23ded8dcdb709a
|
||||||
F src/printf.c 40aee47ae9be4bd3dbdc8968bd07fddc027be8edec8daddf24d3391d36698a1c
|
F src/printf.c 40aee47ae9be4bd3dbdc8968bd07fddc027be8edec8daddf24d3391d36698a1c
|
||||||
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
|
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
|
||||||
F src/resolve.c 4324a94573b1e29286f8121e4881db59eaedc014afeb274c8d3e07ed282e0e20
|
F src/resolve.c 5a461643f294ec510ca615b67256fc3861e4c8eff5f29e5940491e70553b1955
|
||||||
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
|
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
|
||||||
F src/select.c 42aca61e739c405ddd8a1b702977a7743c7d52a94885f7c5596bd7e73e6bff18
|
F src/select.c e6a068d9ea54417d625578086d3d482284af8d5a449bb3593d40c257080806a8
|
||||||
F src/shell.c.in 423944f4ad73a7e73d9c06e645e19ac1aa5f45c22069936e3a008b28a5df8003
|
F src/shell.c.in f13262c8778f0cd76bf8d9c01bbf5ef66842e6b14e1705cd60d86ab32a6ce69f
|
||||||
F src/sqlite.h.in ab4f8a29d1580dfaeb6891fa1b83cff8229ba0daa56994707ceaca71495d9ab7
|
F src/sqlite.h.in ab4f8a29d1580dfaeb6891fa1b83cff8229ba0daa56994707ceaca71495d9ab7
|
||||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||||
F src/sqlite3ext.h a1fd3aa82f967da436164e0728a7d6841651fd0c6e27b9044e0eb9f6c8462e47
|
F src/sqlite3ext.h c02d628cca67f3889c689d82d25c3eb45e2c155db08e4c6089b5840d64687d34
|
||||||
F src/sqliteInt.h c07bc88eca1f59ce73e1f486187d0df4effe67c4579e112dfdd91c159e5c0569
|
F src/sqliteInt.h 6f93fd6fde862410ac26b930f70752c38ad99ea78c3fc28356bac78049c53bd9
|
||||||
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
|
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
|
||||||
F src/status.c 9737ed017279a9e0c5da748701c3c7bf1e8ae0dae459aad20dd64fcff97a7e35
|
F src/status.c 9737ed017279a9e0c5da748701c3c7bf1e8ae0dae459aad20dd64fcff97a7e35
|
||||||
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
|
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
|
||||||
F src/tclsqlite.c 487951d81f9704800fd9f0ffdaa2f935a83ccb6be3575c2c4ef83e4789b4c828
|
F src/tclsqlite.c 1833388c01e3b77f4c712185ee7250b9423ee0981ce6ae7e401e47db0319a696
|
||||||
F src/test1.c 8ef15f7a357f85dfc41c6c748ce9c947b4f676e01bb5ae6a45bee4923dff8b51
|
F src/test1.c 8ef15f7a357f85dfc41c6c748ce9c947b4f676e01bb5ae6a45bee4923dff8b51
|
||||||
F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
|
F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
|
||||||
F src/test3.c b8434949dfb8aff8dfa082c8b592109e77844c2135ed3c492113839b6956255b
|
F src/test3.c b8434949dfb8aff8dfa082c8b592109e77844c2135ed3c492113839b6956255b
|
||||||
@@ -496,6 +499,7 @@ F src/test_intarray.h f3b7672f5d1056eac563c0d6ea8480a660b1475c
|
|||||||
F src/test_journal.c 619f2aa10e0d7a5f87c0f06825bc61dfce1c6b9c7f3ad990fb13de6c3b8874a3
|
F src/test_journal.c 619f2aa10e0d7a5f87c0f06825bc61dfce1c6b9c7f3ad990fb13de6c3b8874a3
|
||||||
F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd
|
F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd
|
||||||
F src/test_malloc.c 4f06a805de86be5216a127b3777ca2d5a1ff99d1a9238374ce136a47411be36c
|
F src/test_malloc.c 4f06a805de86be5216a127b3777ca2d5a1ff99d1a9238374ce136a47411be36c
|
||||||
|
F src/test_md5.c 7268e1e8c399d4a5e181b64ac20e1e6f3bc4dd9fc87abac02db145a3d951fa8c
|
||||||
F src/test_multiplex.c e054459f7633f3ff8ce1245da724f9a8be189e4e
|
F src/test_multiplex.c e054459f7633f3ff8ce1245da724f9a8be189e4e
|
||||||
F src/test_multiplex.h 5436d03f2d0501d04f3ed50a75819e190495b635
|
F src/test_multiplex.h 5436d03f2d0501d04f3ed50a75819e190495b635
|
||||||
F src/test_mutex.c 7f4337ba23ee6b1d2ec81c189653608cb069926a
|
F src/test_mutex.c 7f4337ba23ee6b1d2ec81c189653608cb069926a
|
||||||
@@ -510,6 +514,7 @@ F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe
|
|||||||
F src/test_sqllog.c 11e6ce7575f489155c604ac4b439f2ac1d3d5aef
|
F src/test_sqllog.c 11e6ce7575f489155c604ac4b439f2ac1d3d5aef
|
||||||
F src/test_superlock.c 4839644b9201da822f181c5bc406c0b2385f672e
|
F src/test_superlock.c 4839644b9201da822f181c5bc406c0b2385f672e
|
||||||
F src/test_syscall.c 1073306ba2e9bfc886771871a13d3de281ed3939
|
F src/test_syscall.c 1073306ba2e9bfc886771871a13d3de281ed3939
|
||||||
|
F src/test_tclsh.c 74fcfb7f3b0ff1f871e62263dd84ffba46a8e9d477439115e0fb2035e4bf69e1
|
||||||
F src/test_tclvar.c 33ff42149494a39c5fbb0df3d25d6fafb2f668888e41c0688d07273dcb268dfc
|
F src/test_tclvar.c 33ff42149494a39c5fbb0df3d25d6fafb2f668888e41c0688d07273dcb268dfc
|
||||||
F src/test_thread.c 911d15fb14e19c0c542bdc8aabf981c2f10a4858
|
F src/test_thread.c 911d15fb14e19c0c542bdc8aabf981c2f10a4858
|
||||||
F src/test_vfs.c f0186261a24de2671d080bcd8050732f0cb64f6e
|
F src/test_vfs.c f0186261a24de2671d080bcd8050732f0cb64f6e
|
||||||
@@ -539,7 +544,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
|||||||
F src/wal.c 839db09792fead5052bb35e533fa485e134913d547d05b5f42e537b73e63f07a
|
F src/wal.c 839db09792fead5052bb35e533fa485e134913d547d05b5f42e537b73e63f07a
|
||||||
F src/wal.h 8de5d2d3de0956d6f6cb48c83a4012d5f227b8fe940f3a349a4b7e85ebcb492a
|
F src/wal.h 8de5d2d3de0956d6f6cb48c83a4012d5f227b8fe940f3a349a4b7e85ebcb492a
|
||||||
F src/walker.c 3ccfa8637f95355bff61144e01a615b8ef26f79c312880848da73f03367da1e6
|
F src/walker.c 3ccfa8637f95355bff61144e01a615b8ef26f79c312880848da73f03367da1e6
|
||||||
F src/where.c 049522adcf5426f1a8c3ed07be15e1ffa3266afd34e8e7bee64b63e2fbfad0b5
|
F src/where.c d8c6d690c4b11f30211de073011fe19352364a6303ae053f45cb66f9576ba8a9
|
||||||
F src/whereInt.h 82c04c5075308abbac59180c8bad5ecb45b07453981f60a53f3c7dee21e1e971
|
F src/whereInt.h 82c04c5075308abbac59180c8bad5ecb45b07453981f60a53f3c7dee21e1e971
|
||||||
F src/wherecode.c e8c2ece5843ea56e6c90277d421f2d628f3f7b7c976642369cc519f008e1d2b1
|
F src/wherecode.c e8c2ece5843ea56e6c90277d421f2d628f3f7b7c976642369cc519f008e1d2b1
|
||||||
F src/whereexpr.c afcac9cccfc0fdaccbdda94034a398947b6dc47dbf821c1b496261722832a6a4
|
F src/whereexpr.c afcac9cccfc0fdaccbdda94034a398947b6dc47dbf821c1b496261722832a6a4
|
||||||
@@ -563,7 +568,7 @@ F test/analyze5.test 765c4e284aa69ca172772aa940946f55629bc8c4
|
|||||||
F test/analyze6.test f1c552ce39cca4ec922a7e4e0e5d0203d6b3281f
|
F test/analyze6.test f1c552ce39cca4ec922a7e4e0e5d0203d6b3281f
|
||||||
F test/analyze7.test bb1409afc9e8629e414387ef048b8e0e3e0bdc4f
|
F test/analyze7.test bb1409afc9e8629e414387ef048b8e0e3e0bdc4f
|
||||||
F test/analyze8.test c05a461d0a6b05991106467d0c47480f2e709c82
|
F test/analyze8.test c05a461d0a6b05991106467d0c47480f2e709c82
|
||||||
F test/analyze9.test b817b8e798315fc65b820a5463f73ad5f48ed8dd
|
F test/analyze9.test dac0bdc7eab965b9ad639ca83564d98717aaf13ce5a776f23d9a3680238cecd8
|
||||||
F test/analyzeA.test 3335697f6700c7052295cfd0067fc5b2aacddf9a
|
F test/analyzeA.test 3335697f6700c7052295cfd0067fc5b2aacddf9a
|
||||||
F test/analyzeB.test a4c1c3048f6d9e090eb76e83eecb18bcf6d31a70
|
F test/analyzeB.test a4c1c3048f6d9e090eb76e83eecb18bcf6d31a70
|
||||||
F test/analyzeC.test 555a6cc388b9818b6eda6df816f01ce0a75d3a93
|
F test/analyzeC.test 555a6cc388b9818b6eda6df816f01ce0a75d3a93
|
||||||
@@ -645,6 +650,7 @@ F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe
|
|||||||
F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3
|
F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3
|
||||||
F test/cffault.test 9d6b20606afe712374952eec4f8fd74b1a8097ef
|
F test/cffault.test 9d6b20606afe712374952eec4f8fd74b1a8097ef
|
||||||
F test/check.test 33a698e8c63613449d85d624a38ef669bf20331daabebe3891c9405dd6df463a
|
F test/check.test 33a698e8c63613449d85d624a38ef669bf20331daabebe3891c9405dd6df463a
|
||||||
|
F test/checkfreelist.test 100283a3e6b8a3018c7fab7cfdaf03d1d6540fc66453114e248cf82b25784d3b
|
||||||
F test/close.test 799ea4599d2f5704b0a30f477d17c2c760d8523fa5d0c8be4a7df2a8cad787d8
|
F test/close.test 799ea4599d2f5704b0a30f477d17c2c760d8523fa5d0c8be4a7df2a8cad787d8
|
||||||
F test/closure01.test b1703ba40639cfc9b295cf478d70739415eec6a4
|
F test/closure01.test b1703ba40639cfc9b295cf478d70739415eec6a4
|
||||||
F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91
|
F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91
|
||||||
@@ -684,7 +690,7 @@ F test/corruptG.test adf79b669cbfd19e28c8191a610d083ae53a6d51
|
|||||||
F test/corruptH.test 79801d97ec5c2f9f3c87739aa1ec2eb786f96454
|
F test/corruptH.test 79801d97ec5c2f9f3c87739aa1ec2eb786f96454
|
||||||
F test/corruptI.test 075fe1d75aa1d84e2949be56b6264376c41502e4
|
F test/corruptI.test 075fe1d75aa1d84e2949be56b6264376c41502e4
|
||||||
F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4
|
F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4
|
||||||
F test/corruptK.test 814a59ec699d8546b4e29005fba3d16e933ef2fe
|
F test/corruptK.test 251ef631d095e882d455d2183961fa9ba879b4156e18e96c5d2b84aa7ef5f7a9
|
||||||
F test/cost.test 1eedbfd868f806f3fa08ff072b04cf270dcf61c8
|
F test/cost.test 1eedbfd868f806f3fa08ff072b04cf270dcf61c8
|
||||||
F test/count.test cb2e0f934c6eb33670044520748d2ecccd46259c
|
F test/count.test cb2e0f934c6eb33670044520748d2ecccd46259c
|
||||||
F test/coveridxscan.test b629e896b14df2f000a99b8d170d80589c46562c
|
F test/coveridxscan.test b629e896b14df2f000a99b8d170d80589c46562c
|
||||||
@@ -707,6 +713,7 @@ F test/cursorhint2.test 8457e93d97f665f23f97cdbc8477d16e3480331b
|
|||||||
F test/date.test 9b73bbeb1b82d9c1f44dec5cf563bf7da58d2373
|
F test/date.test 9b73bbeb1b82d9c1f44dec5cf563bf7da58d2373
|
||||||
F test/date2.test 74c234bece1b016e94dd4ef9c8cc7a199a8806c0e2291cab7ba64bace6350b10
|
F test/date2.test 74c234bece1b016e94dd4ef9c8cc7a199a8806c0e2291cab7ba64bace6350b10
|
||||||
F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e
|
F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e
|
||||||
|
F test/dbpage.test 9cf4dc92a4de67c81e5c32b24e3fbb8c4757e4b642694a219b3090a4f9277a4d
|
||||||
F test/dbstatus.test 73149851b3aff14fc6db478e58f9083a66422cf5
|
F test/dbstatus.test 73149851b3aff14fc6db478e58f9083a66422cf5
|
||||||
F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab
|
F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab
|
||||||
F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d
|
F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d
|
||||||
@@ -1098,7 +1105,7 @@ F test/parser1.test 391b9bf9a229547a129c61ac345ed1a6f5eb1854
|
|||||||
F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
|
F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
|
||||||
F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
|
F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
|
||||||
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
|
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
|
||||||
F test/permutations.test d911c9ba49088d22054a05dc73743f677872a92ac89288bcdeafa0ebf3f9c531
|
F test/permutations.test 490e3333b9b1aefb7ebc6e9ab2ae0e382b7dd8713ccc4a2786b0f75467c2ab6b
|
||||||
F test/pragma.test c31b5e98998c160a4c85b1e04f590655c67f2daa7f73854640cd120610e3ac15
|
F test/pragma.test c31b5e98998c160a4c85b1e04f590655c67f2daa7f73854640cd120610e3ac15
|
||||||
F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f
|
F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f
|
||||||
F test/pragma3.test 14c12bc5352b1e100e0b6b44f371053a81ccf8ed
|
F test/pragma3.test 14c12bc5352b1e100e0b6b44f371053a81ccf8ed
|
||||||
@@ -1150,7 +1157,7 @@ F test/savepoint5.test 0735db177e0ebbaedc39812c8d065075d563c4fd
|
|||||||
F test/savepoint6.test f41279c5e137139fa5c21485773332c7adb98cd7
|
F test/savepoint6.test f41279c5e137139fa5c21485773332c7adb98cd7
|
||||||
F test/savepoint7.test cde525ea3075283eb950cdcdefe23ead4f700daa
|
F test/savepoint7.test cde525ea3075283eb950cdcdefe23ead4f700daa
|
||||||
F test/savepointfault.test f044eac64b59f09746c7020ee261734de82bf9b2
|
F test/savepointfault.test f044eac64b59f09746c7020ee261734de82bf9b2
|
||||||
F test/scanstatus.test 5253c219e331318a437f436268e0e82345700285
|
F test/scanstatus.test 1ba0e2ee25dcd1d55ec770803b19832cffaecbf0b15d376807759ebeed3669b0
|
||||||
F test/schema.test 8f7999be894260f151adf15c2c7540f1c6d6a481
|
F test/schema.test 8f7999be894260f151adf15c2c7540f1c6d6a481
|
||||||
F test/schema2.test 906408621ea881fdb496d878b1822572a34e32c5
|
F test/schema2.test 906408621ea881fdb496d878b1822572a34e32c5
|
||||||
F test/schema3.test 1bc1008e1f8cb5654b248c55f27249366eb7ed38
|
F test/schema3.test 1bc1008e1f8cb5654b248c55f27249366eb7ed38
|
||||||
@@ -1586,6 +1593,7 @@ F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862
|
|||||||
F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca
|
F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca
|
||||||
F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439
|
F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439
|
||||||
F tool/mkautoconfamal.sh 422fc365358a2e92876ffc62971a0ff28ed472fc8bcf9de0df921c736fdeca5e
|
F tool/mkautoconfamal.sh 422fc365358a2e92876ffc62971a0ff28ed472fc8bcf9de0df921c736fdeca5e
|
||||||
|
F tool/mkccode.tcl 86463e68ce9c15d3041610fedd285ce32a5cf7a58fc88b3202b8b76837650dbe x
|
||||||
F tool/mkctimec.tcl dd183b73ae1c28249669741c250525f0407e579a70482371668fd5f130d9feb3
|
F tool/mkctimec.tcl dd183b73ae1c28249669741c250525f0407e579a70482371668fd5f130d9feb3
|
||||||
F tool/mkkeywordhash.c 2e852ac0dfdc5af18886dc1ce7e9676d11714ae3df0a282dc7d90b3a0fe2033c
|
F tool/mkkeywordhash.c 2e852ac0dfdc5af18886dc1ce7e9676d11714ae3df0a282dc7d90b3a0fe2033c
|
||||||
F tool/mkmsvcmin.tcl cbd93f1cfa3a0a9ae56fc958510aa3fc3ac65e29cb111716199e3d0e66eefaa4
|
F tool/mkmsvcmin.tcl cbd93f1cfa3a0a9ae56fc958510aa3fc3ac65e29cb111716199e3d0e66eefaa4
|
||||||
@@ -1597,7 +1605,7 @@ F tool/mkshellc.tcl 574307265b49d813301fba91ccd74e6a26d33f65f74b6891c320a0ffbee0
|
|||||||
F tool/mksourceid.c d458f9004c837bee87a6382228ac20d3eae3c49ea3b0a5aace936f8b60748d3b
|
F tool/mksourceid.c d458f9004c837bee87a6382228ac20d3eae3c49ea3b0a5aace936f8b60748d3b
|
||||||
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
|
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
|
||||||
F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb
|
F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb
|
||||||
F tool/mksqlite3c.tcl b258d679829a9305f5cf107b7d97b9bf23adb3773df42947fed5ef7b180dfbd9
|
F tool/mksqlite3c.tcl 1fb69d39166f52d802a70ec37d99bca51d011c8ab30be27bc495be493196ae41
|
||||||
F tool/mksqlite3h.tcl f92f994d9709aeb9e2b6e6f9fc8b069d2f55202c8e23f453edc44390a25982dc
|
F tool/mksqlite3h.tcl f92f994d9709aeb9e2b6e6f9fc8b069d2f55202c8e23f453edc44390a25982dc
|
||||||
F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b
|
F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b
|
||||||
F tool/mkvsix.tcl b9e0777a213c23156b6542842c238479e496ebf5
|
F tool/mkvsix.tcl b9e0777a213c23156b6542842c238479e496ebf5
|
||||||
@@ -1622,13 +1630,13 @@ F tool/speedtest16.c ecb6542862151c3e6509bbc00509b234562ae81e
|
|||||||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||||
F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd
|
F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd
|
||||||
F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c
|
F tool/split-sqlite3c.tcl 3efcd4240b738f6bb2b5af0aea7e1e0ef9bc1c61654f645076cec883030b710c
|
||||||
F tool/sqldiff.c 30879bbc8de686df4624e86adce2d8981f500904c1cfb55b5d1eea2ffd9341eb
|
F tool/sqldiff.c 30879bbc8de686df4624e86adce2d8981f500904c1cfb55b5d1eea2ffd9341eb
|
||||||
|
F tool/sqlite3_analyzer.c.in 771d15fb9c67645fd8ef932a438f98959da4b7c7da3cb87ae1850b27c969edf3
|
||||||
F tool/srcck1.c 371de5363b70154012955544f86fdee8f6e5326f
|
F tool/srcck1.c 371de5363b70154012955544f86fdee8f6e5326f
|
||||||
F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43
|
F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43
|
||||||
F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d
|
F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d
|
||||||
F tool/symbols.sh c5a617b8c61a0926747a56c65f5671ef8ac0e148
|
F tool/symbols.sh c5a617b8c61a0926747a56c65f5671ef8ac0e148
|
||||||
F tool/tostr.tcl 96022f35ada2194f6f8ccf6fd95809e90ed277c4
|
|
||||||
F tool/varint.c 5d94cb5003db9dbbcbcc5df08d66f16071aee003
|
F tool/varint.c 5d94cb5003db9dbbcbcc5df08d66f16071aee003
|
||||||
F tool/vdbe-compress.tcl 5926c71f9c12d2ab73ef35c29376e756eb68361c
|
F tool/vdbe-compress.tcl 5926c71f9c12d2ab73ef35c29376e756eb68361c
|
||||||
F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
|
F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
|
||||||
@@ -1656,8 +1664,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
|||||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||||
P de20133d44773f0b3b8869db5c1cb2a90f0426a54c7f40d12a930003343ad8e0
|
P 92eb721faefcdd8396072722d3e4d7ca41b860b306e4bb0f0191dde8f30d0add 6ee8cb6ae5fd076ec226bb184b5690ba29f9df8cfaef47aaf13336873b4c1f6c
|
||||||
Q +ac8786f3f9f35cb6fa72c65f5ca41cc6659f4702cd29ab0c9dcf04d3d1189090
|
R cbea5558ab489dc3dc438260e1496797
|
||||||
R 8e422c1ee06cd57625ef547ccd862b5a
|
U drh
|
||||||
U mistachkin
|
Z 9e651e977f775eeb3bfb6c192219eebf
|
||||||
Z 0ed36b5b53069fc1c0ccb6054caf79bd
|
|
||||||
|
@@ -1 +1 @@
|
|||||||
92eb721faefcdd8396072722d3e4d7ca41b860b306e4bb0f0191dde8f30d0add
|
fb3ee1b7cac09e4950e4f48b44c277e4f391cb6c8f069644732d2389ca653da4
|
13
src/btree.c
13
src/btree.c
@@ -4824,7 +4824,7 @@ static const void *fetchPayload(
|
|||||||
BtCursor *pCur, /* Cursor pointing to entry to read from */
|
BtCursor *pCur, /* Cursor pointing to entry to read from */
|
||||||
u32 *pAmt /* Write the number of available bytes here */
|
u32 *pAmt /* Write the number of available bytes here */
|
||||||
){
|
){
|
||||||
u32 amt;
|
int amt;
|
||||||
assert( pCur!=0 && pCur->iPage>=0 && pCur->pPage);
|
assert( pCur!=0 && pCur->iPage>=0 && pCur->pPage);
|
||||||
assert( pCur->eState==CURSOR_VALID );
|
assert( pCur->eState==CURSOR_VALID );
|
||||||
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
|
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
|
||||||
@@ -4833,9 +4833,14 @@ static const void *fetchPayload(
|
|||||||
assert( pCur->info.nSize>0 );
|
assert( pCur->info.nSize>0 );
|
||||||
assert( pCur->info.pPayload>pCur->pPage->aData || CORRUPT_DB );
|
assert( pCur->info.pPayload>pCur->pPage->aData || CORRUPT_DB );
|
||||||
assert( pCur->info.pPayload<pCur->pPage->aDataEnd ||CORRUPT_DB);
|
assert( pCur->info.pPayload<pCur->pPage->aDataEnd ||CORRUPT_DB);
|
||||||
amt = (int)(pCur->pPage->aDataEnd - pCur->info.pPayload);
|
amt = pCur->info.nLocal;
|
||||||
if( pCur->info.nLocal<amt ) amt = pCur->info.nLocal;
|
if( amt>(int)(pCur->pPage->aDataEnd - pCur->info.pPayload) ){
|
||||||
*pAmt = amt;
|
/* There is too little space on the page for the expected amount
|
||||||
|
** of local content. Database must be corrupt. */
|
||||||
|
assert( CORRUPT_DB );
|
||||||
|
amt = MAX(0, (int)(pCur->pPage->aDataEnd - pCur->info.pPayload));
|
||||||
|
}
|
||||||
|
*pAmt = (u32)amt;
|
||||||
return (void*)pCur->info.pPayload;
|
return (void*)pCur->info.pPayload;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1063,12 +1063,10 @@ void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){
|
|||||||
Column *pCol;
|
Column *pCol;
|
||||||
sqlite3 *db = pParse->db;
|
sqlite3 *db = pParse->db;
|
||||||
if( (p = pParse->pNewTable)==0 ) return;
|
if( (p = pParse->pNewTable)==0 ) return;
|
||||||
#if SQLITE_MAX_COLUMN
|
|
||||||
if( p->nCol+1>db->aLimit[SQLITE_LIMIT_COLUMN] ){
|
if( p->nCol+1>db->aLimit[SQLITE_LIMIT_COLUMN] ){
|
||||||
sqlite3ErrorMsg(pParse, "too many columns on %s", p->zName);
|
sqlite3ErrorMsg(pParse, "too many columns on %s", p->zName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
z = sqlite3DbMallocRaw(db, pName->n + pType->n + 2);
|
z = sqlite3DbMallocRaw(db, pName->n + pType->n + 2);
|
||||||
if( z==0 ) return;
|
if( z==0 ) return;
|
||||||
memcpy(z, pName->z, pName->n);
|
memcpy(z, pName->z, pName->n);
|
||||||
|
329
src/dbpage.c
Normal file
329
src/dbpage.c
Normal file
@@ -0,0 +1,329 @@
|
|||||||
|
/*
|
||||||
|
** 2017-10-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.
|
||||||
|
**
|
||||||
|
******************************************************************************
|
||||||
|
**
|
||||||
|
** This file contains an implementation of the "sqlite_dbpage" virtual table.
|
||||||
|
**
|
||||||
|
** The sqlite_dbpage virtual table is used to read or write whole raw
|
||||||
|
** pages of the database file. The pager interface is used so that
|
||||||
|
** uncommitted changes and changes recorded in the WAL file are correctly
|
||||||
|
** retrieved.
|
||||||
|
**
|
||||||
|
** Usage example:
|
||||||
|
**
|
||||||
|
** SELECT data FROM sqlite_dbpage('aux1') WHERE pgno=123;
|
||||||
|
**
|
||||||
|
** This is an eponymous virtual table so it does not need to be created before
|
||||||
|
** use. The optional argument to the sqlite_dbpage() table name is the
|
||||||
|
** schema for the database file that is to be read. The default schema is
|
||||||
|
** "main".
|
||||||
|
**
|
||||||
|
** The data field of sqlite_dbpage table can be updated. The new
|
||||||
|
** value must be a BLOB which is the correct page size, otherwise the
|
||||||
|
** update fails. Rows may not be deleted or inserted.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sqliteInt.h" /* Requires access to internal data structures */
|
||||||
|
#if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \
|
||||||
|
&& !defined(SQLITE_OMIT_VIRTUALTABLE)
|
||||||
|
|
||||||
|
typedef struct DbpageTable DbpageTable;
|
||||||
|
typedef struct DbpageCursor DbpageCursor;
|
||||||
|
|
||||||
|
struct DbpageCursor {
|
||||||
|
sqlite3_vtab_cursor base; /* Base class. Must be first */
|
||||||
|
int pgno; /* Current page number */
|
||||||
|
int mxPgno; /* Last page to visit on this scan */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DbpageTable {
|
||||||
|
sqlite3_vtab base; /* Base class. Must be first */
|
||||||
|
sqlite3 *db; /* The database */
|
||||||
|
Pager *pPager; /* Pager being read/written */
|
||||||
|
int iDb; /* Index of database to analyze */
|
||||||
|
int szPage; /* Size of each page in bytes */
|
||||||
|
int nPage; /* Number of pages in the file */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Connect to or create a dbpagevfs virtual table.
|
||||||
|
*/
|
||||||
|
static int dbpageConnect(
|
||||||
|
sqlite3 *db,
|
||||||
|
void *pAux,
|
||||||
|
int argc, const char *const*argv,
|
||||||
|
sqlite3_vtab **ppVtab,
|
||||||
|
char **pzErr
|
||||||
|
){
|
||||||
|
DbpageTable *pTab = 0;
|
||||||
|
int rc = SQLITE_OK;
|
||||||
|
int iDb;
|
||||||
|
|
||||||
|
if( argc>=4 ){
|
||||||
|
Token nm;
|
||||||
|
sqlite3TokenInit(&nm, (char*)argv[3]);
|
||||||
|
iDb = sqlite3FindDb(db, &nm);
|
||||||
|
if( iDb<0 ){
|
||||||
|
*pzErr = sqlite3_mprintf("no such schema: %s", argv[3]);
|
||||||
|
return SQLITE_ERROR;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
iDb = 0;
|
||||||
|
}
|
||||||
|
rc = sqlite3_declare_vtab(db,
|
||||||
|
"CREATE TABLE x(pgno INTEGER PRIMARY KEY, data BLOB, schema HIDDEN)");
|
||||||
|
if( rc==SQLITE_OK ){
|
||||||
|
pTab = (DbpageTable *)sqlite3_malloc64(sizeof(DbpageTable));
|
||||||
|
if( pTab==0 ) rc = SQLITE_NOMEM_BKPT;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert( rc==SQLITE_OK || pTab==0 );
|
||||||
|
if( rc==SQLITE_OK ){
|
||||||
|
Btree *pBt = db->aDb[iDb].pBt;
|
||||||
|
memset(pTab, 0, sizeof(DbpageTable));
|
||||||
|
pTab->db = db;
|
||||||
|
pTab->iDb = iDb;
|
||||||
|
pTab->pPager = pBt ? sqlite3BtreePager(pBt) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ppVtab = (sqlite3_vtab*)pTab;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Disconnect from or destroy a dbpagevfs virtual table.
|
||||||
|
*/
|
||||||
|
static int dbpageDisconnect(sqlite3_vtab *pVtab){
|
||||||
|
sqlite3_free(pVtab);
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** idxNum:
|
||||||
|
**
|
||||||
|
** 0 full table scan
|
||||||
|
** 1 pgno=?1
|
||||||
|
*/
|
||||||
|
static int dbpageBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
|
||||||
|
int i;
|
||||||
|
pIdxInfo->estimatedCost = 1.0e6; /* Initial cost estimate */
|
||||||
|
for(i=0; i<pIdxInfo->nConstraint; i++){
|
||||||
|
struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i];
|
||||||
|
if( p->usable && p->iColumn<=0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
|
||||||
|
pIdxInfo->estimatedRows = 1;
|
||||||
|
pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_UNIQUE;
|
||||||
|
pIdxInfo->estimatedCost = 1.0;
|
||||||
|
pIdxInfo->idxNum = 1;
|
||||||
|
pIdxInfo->aConstraintUsage[i].argvIndex = 1;
|
||||||
|
pIdxInfo->aConstraintUsage[i].omit = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( pIdxInfo->nOrderBy>=1
|
||||||
|
&& pIdxInfo->aOrderBy[0].iColumn<=0
|
||||||
|
&& pIdxInfo->aOrderBy[0].desc==0
|
||||||
|
){
|
||||||
|
pIdxInfo->orderByConsumed = 1;
|
||||||
|
}
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Open a new dbpagevfs cursor.
|
||||||
|
*/
|
||||||
|
static int dbpageOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
|
||||||
|
DbpageCursor *pCsr;
|
||||||
|
|
||||||
|
pCsr = (DbpageCursor *)sqlite3_malloc64(sizeof(DbpageCursor));
|
||||||
|
if( pCsr==0 ){
|
||||||
|
return SQLITE_NOMEM_BKPT;
|
||||||
|
}else{
|
||||||
|
memset(pCsr, 0, sizeof(DbpageCursor));
|
||||||
|
pCsr->base.pVtab = pVTab;
|
||||||
|
pCsr->pgno = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ppCursor = (sqlite3_vtab_cursor *)pCsr;
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Close a dbpagevfs cursor.
|
||||||
|
*/
|
||||||
|
static int dbpageClose(sqlite3_vtab_cursor *pCursor){
|
||||||
|
DbpageCursor *pCsr = (DbpageCursor *)pCursor;
|
||||||
|
sqlite3_free(pCsr);
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Move a dbpagevfs cursor to the next entry in the file.
|
||||||
|
*/
|
||||||
|
static int dbpageNext(sqlite3_vtab_cursor *pCursor){
|
||||||
|
int rc = SQLITE_OK;
|
||||||
|
DbpageCursor *pCsr = (DbpageCursor *)pCursor;
|
||||||
|
pCsr->pgno++;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dbpageEof(sqlite3_vtab_cursor *pCursor){
|
||||||
|
DbpageCursor *pCsr = (DbpageCursor *)pCursor;
|
||||||
|
return pCsr->pgno > pCsr->mxPgno;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dbpageFilter(
|
||||||
|
sqlite3_vtab_cursor *pCursor,
|
||||||
|
int idxNum, const char *idxStr,
|
||||||
|
int argc, sqlite3_value **argv
|
||||||
|
){
|
||||||
|
DbpageCursor *pCsr = (DbpageCursor *)pCursor;
|
||||||
|
DbpageTable *pTab = (DbpageTable *)pCursor->pVtab;
|
||||||
|
int rc = SQLITE_OK;
|
||||||
|
Btree *pBt = pTab->db->aDb[pTab->iDb].pBt;
|
||||||
|
|
||||||
|
pTab->szPage = sqlite3BtreeGetPageSize(pBt);
|
||||||
|
pTab->nPage = sqlite3BtreeLastPage(pBt);
|
||||||
|
if( idxNum==1 ){
|
||||||
|
pCsr->pgno = sqlite3_value_int(argv[0]);
|
||||||
|
if( pCsr->pgno<1 || pCsr->pgno>pTab->nPage ){
|
||||||
|
pCsr->pgno = 1;
|
||||||
|
pCsr->mxPgno = 0;
|
||||||
|
}else{
|
||||||
|
pCsr->mxPgno = pCsr->pgno;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
pCsr->pgno = 1;
|
||||||
|
pCsr->mxPgno = pTab->nPage;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dbpageColumn(
|
||||||
|
sqlite3_vtab_cursor *pCursor,
|
||||||
|
sqlite3_context *ctx,
|
||||||
|
int i
|
||||||
|
){
|
||||||
|
DbpageCursor *pCsr = (DbpageCursor *)pCursor;
|
||||||
|
DbpageTable *pTab = (DbpageTable *)pCursor->pVtab;
|
||||||
|
int rc = SQLITE_OK;
|
||||||
|
switch( i ){
|
||||||
|
case 0: { /* pgno */
|
||||||
|
sqlite3_result_int(ctx, pCsr->pgno);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1: { /* data */
|
||||||
|
DbPage *pDbPage = 0;
|
||||||
|
rc = sqlite3PagerGet(pTab->pPager, pCsr->pgno, (DbPage**)&pDbPage, 0);
|
||||||
|
if( rc==SQLITE_OK ){
|
||||||
|
sqlite3_result_blob(ctx, sqlite3PagerGetData(pDbPage), pTab->szPage,
|
||||||
|
SQLITE_TRANSIENT);
|
||||||
|
}
|
||||||
|
sqlite3PagerUnref(pDbPage);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: { /* schema */
|
||||||
|
sqlite3 *db = sqlite3_context_db_handle(ctx);
|
||||||
|
sqlite3_result_text(ctx, db->aDb[pTab->iDb].zDbSName, -1, SQLITE_STATIC);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dbpageRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
|
||||||
|
DbpageCursor *pCsr = (DbpageCursor *)pCursor;
|
||||||
|
*pRowid = pCsr->pgno;
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dbpageUpdate(
|
||||||
|
sqlite3_vtab *pVtab,
|
||||||
|
int argc,
|
||||||
|
sqlite3_value **argv,
|
||||||
|
sqlite_int64 *pRowid
|
||||||
|
){
|
||||||
|
DbpageTable *pTab = (DbpageTable *)pVtab;
|
||||||
|
int pgno;
|
||||||
|
DbPage *pDbPage = 0;
|
||||||
|
int rc = SQLITE_OK;
|
||||||
|
char *zErr = 0;
|
||||||
|
|
||||||
|
if( argc==1 ){
|
||||||
|
zErr = "cannot delete";
|
||||||
|
goto update_fail;
|
||||||
|
}
|
||||||
|
pgno = sqlite3_value_int(argv[0]);
|
||||||
|
if( pgno<1 || pgno>pTab->nPage ){
|
||||||
|
zErr = "bad page number";
|
||||||
|
goto update_fail;
|
||||||
|
}
|
||||||
|
if( sqlite3_value_int(argv[1])!=pgno ){
|
||||||
|
zErr = "cannot insert";
|
||||||
|
goto update_fail;
|
||||||
|
}
|
||||||
|
if( sqlite3_value_type(argv[3])!=SQLITE_BLOB
|
||||||
|
|| sqlite3_value_bytes(argv[3])!=pTab->szPage
|
||||||
|
){
|
||||||
|
zErr = "bad page value";
|
||||||
|
goto update_fail;
|
||||||
|
}
|
||||||
|
rc = sqlite3PagerGet(pTab->pPager, pgno, (DbPage**)&pDbPage, 0);
|
||||||
|
if( rc==SQLITE_OK ){
|
||||||
|
rc = sqlite3PagerWrite(pDbPage);
|
||||||
|
if( rc==SQLITE_OK ){
|
||||||
|
memcpy(sqlite3PagerGetData(pDbPage),
|
||||||
|
sqlite3_value_blob(argv[3]),
|
||||||
|
pTab->szPage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sqlite3PagerUnref(pDbPage);
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
update_fail:
|
||||||
|
sqlite3_free(pVtab->zErrMsg);
|
||||||
|
pVtab->zErrMsg = sqlite3_mprintf("%s", zErr);
|
||||||
|
return SQLITE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Invoke this routine to register the "dbpage" virtual table module
|
||||||
|
*/
|
||||||
|
int sqlite3DbpageRegister(sqlite3 *db){
|
||||||
|
static sqlite3_module dbpage_module = {
|
||||||
|
0, /* iVersion */
|
||||||
|
dbpageConnect, /* xCreate */
|
||||||
|
dbpageConnect, /* xConnect */
|
||||||
|
dbpageBestIndex, /* xBestIndex */
|
||||||
|
dbpageDisconnect, /* xDisconnect */
|
||||||
|
dbpageDisconnect, /* xDestroy */
|
||||||
|
dbpageOpen, /* xOpen - open a cursor */
|
||||||
|
dbpageClose, /* xClose - close a cursor */
|
||||||
|
dbpageFilter, /* xFilter - configure scan constraints */
|
||||||
|
dbpageNext, /* xNext - advance a cursor */
|
||||||
|
dbpageEof, /* xEof - check for end of scan */
|
||||||
|
dbpageColumn, /* xColumn - read data */
|
||||||
|
dbpageRowid, /* xRowid - read data */
|
||||||
|
dbpageUpdate, /* xUpdate */
|
||||||
|
0, /* xBegin */
|
||||||
|
0, /* xSync */
|
||||||
|
0, /* xCommit */
|
||||||
|
0, /* xRollback */
|
||||||
|
0, /* xFindMethod */
|
||||||
|
0, /* xRename */
|
||||||
|
0, /* xSavepoint */
|
||||||
|
0, /* xRelease */
|
||||||
|
0, /* xRollbackTo */
|
||||||
|
};
|
||||||
|
return sqlite3_create_module(db, "sqlite_dbpage", &dbpage_module, 0);
|
||||||
|
}
|
||||||
|
#elif defined(SQLITE_ENABLE_DBPAGE_VTAB)
|
||||||
|
int sqlite3DbpageRegister(sqlite3 *db){ return SQLITE_OK; }
|
||||||
|
#endif /* SQLITE_ENABLE_DBSTAT_VTAB */
|
@@ -3054,6 +3054,12 @@ static int openDatabase(
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef SQLITE_ENABLE_DBPAGE_VTAB
|
||||||
|
if( !db->mallocFailed && rc==SQLITE_OK){
|
||||||
|
rc = sqlite3DbpageRegister(db);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef SQLITE_ENABLE_DBSTAT_VTAB
|
#ifdef SQLITE_ENABLE_DBSTAT_VTAB
|
||||||
if( !db->mallocFailed && rc==SQLITE_OK){
|
if( !db->mallocFailed && rc==SQLITE_OK){
|
||||||
rc = sqlite3DbstatRegister(db);
|
rc = sqlite3DbstatRegister(db);
|
||||||
|
@@ -959,12 +959,10 @@ static int resolveCompoundOrderBy(
|
|||||||
pOrderBy = pSelect->pOrderBy;
|
pOrderBy = pSelect->pOrderBy;
|
||||||
if( pOrderBy==0 ) return 0;
|
if( pOrderBy==0 ) return 0;
|
||||||
db = pParse->db;
|
db = pParse->db;
|
||||||
#if SQLITE_MAX_COLUMN
|
|
||||||
if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
|
if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
|
||||||
sqlite3ErrorMsg(pParse, "too many terms in ORDER BY clause");
|
sqlite3ErrorMsg(pParse, "too many terms in ORDER BY clause");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
for(i=0; i<pOrderBy->nExpr; i++){
|
for(i=0; i<pOrderBy->nExpr; i++){
|
||||||
pOrderBy->a[i].done = 0;
|
pOrderBy->a[i].done = 0;
|
||||||
}
|
}
|
||||||
@@ -1056,12 +1054,10 @@ int sqlite3ResolveOrderGroupBy(
|
|||||||
struct ExprList_item *pItem;
|
struct ExprList_item *pItem;
|
||||||
|
|
||||||
if( pOrderBy==0 || pParse->db->mallocFailed ) return 0;
|
if( pOrderBy==0 || pParse->db->mallocFailed ) return 0;
|
||||||
#if SQLITE_MAX_COLUMN
|
|
||||||
if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
|
if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
|
||||||
sqlite3ErrorMsg(pParse, "too many terms in %s BY clause", zType);
|
sqlite3ErrorMsg(pParse, "too many terms in %s BY clause", zType);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
pEList = pSelect->pEList;
|
pEList = pSelect->pEList;
|
||||||
assert( pEList!=0 ); /* sqlite3SelectNew() guarantees this */
|
assert( pEList!=0 ); /* sqlite3SelectNew() guarantees this */
|
||||||
for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
|
for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
|
||||||
|
@@ -1689,6 +1689,7 @@ int sqlite3ColumnsFromExprList(
|
|||||||
nCol = pEList->nExpr;
|
nCol = pEList->nExpr;
|
||||||
aCol = sqlite3DbMallocZero(db, sizeof(aCol[0])*nCol);
|
aCol = sqlite3DbMallocZero(db, sizeof(aCol[0])*nCol);
|
||||||
testcase( aCol==0 );
|
testcase( aCol==0 );
|
||||||
|
if( nCol>32767 ) nCol = 32767;
|
||||||
}else{
|
}else{
|
||||||
nCol = 0;
|
nCol = 0;
|
||||||
aCol = 0;
|
aCol = 0;
|
||||||
@@ -4596,12 +4597,10 @@ static int selectExpander(Walker *pWalker, Select *p){
|
|||||||
sqlite3ExprListDelete(db, pEList);
|
sqlite3ExprListDelete(db, pEList);
|
||||||
p->pEList = pNew;
|
p->pEList = pNew;
|
||||||
}
|
}
|
||||||
#if SQLITE_MAX_COLUMN
|
|
||||||
if( p->pEList && p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
|
if( p->pEList && p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
|
||||||
sqlite3ErrorMsg(pParse, "too many columns in result set");
|
sqlite3ErrorMsg(pParse, "too many columns in result set");
|
||||||
return WRC_Abort;
|
return WRC_Abort;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return WRC_Continue;
|
return WRC_Continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -3611,20 +3611,24 @@ static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
|
|||||||
{ "schema size:",
|
{ "schema size:",
|
||||||
"SELECT total(length(sql)) FROM %s" },
|
"SELECT total(length(sql)) FROM %s" },
|
||||||
};
|
};
|
||||||
sqlite3_file *pFile = 0;
|
|
||||||
int i;
|
int i;
|
||||||
char *zSchemaTab;
|
char *zSchemaTab;
|
||||||
char *zDb = nArg>=2 ? azArg[1] : "main";
|
char *zDb = nArg>=2 ? azArg[1] : "main";
|
||||||
|
sqlite3_stmt *pStmt = 0;
|
||||||
unsigned char aHdr[100];
|
unsigned char aHdr[100];
|
||||||
open_db(p, 0);
|
open_db(p, 0);
|
||||||
if( p->db==0 ) return 1;
|
if( p->db==0 ) return 1;
|
||||||
sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile);
|
sqlite3_prepare_v2(p->db,"SELECT data FROM sqlite_dbpage(?1) WHERE pgno=1",
|
||||||
if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){
|
-1, &pStmt, 0);
|
||||||
return 1;
|
sqlite3_bind_text(pStmt, 1, zDb, -1, SQLITE_STATIC);
|
||||||
}
|
if( sqlite3_step(pStmt)==SQLITE_ROW
|
||||||
i = pFile->pMethods->xRead(pFile, aHdr, 100, 0);
|
&& sqlite3_column_bytes(pStmt,0)>100
|
||||||
if( i!=SQLITE_OK ){
|
){
|
||||||
|
memcpy(aHdr, sqlite3_column_blob(pStmt,0), 100);
|
||||||
|
sqlite3_finalize(pStmt);
|
||||||
|
}else{
|
||||||
raw_printf(stderr, "unable to read database header\n");
|
raw_printf(stderr, "unable to read database header\n");
|
||||||
|
sqlite3_finalize(pStmt);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
i = get2byteInt(aHdr+16);
|
i = get2byteInt(aHdr+16);
|
||||||
@@ -4244,7 +4248,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
|||||||
utf8_printf(stderr,
|
utf8_printf(stderr,
|
||||||
"testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n",
|
"testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n",
|
||||||
p->zTestcase, azArg[1], zRes);
|
p->zTestcase, azArg[1], zRes);
|
||||||
rc = 2;
|
rc = 1;
|
||||||
}else{
|
}else{
|
||||||
utf8_printf(stdout, "testcase-%s ok\n", p->zTestcase);
|
utf8_printf(stdout, "testcase-%s ok\n", p->zTestcase);
|
||||||
p->nCheck++;
|
p->nCheck++;
|
||||||
|
@@ -134,7 +134,7 @@ struct sqlite3_api_routines {
|
|||||||
int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*,
|
int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*,
|
||||||
const char*,const char*),void*);
|
const char*,const char*),void*);
|
||||||
void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*));
|
void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*));
|
||||||
char * (*snprintf)(int,char*,const char*,...);
|
char * (*xsnprintf)(int,char*,const char*,...);
|
||||||
int (*step)(sqlite3_stmt*);
|
int (*step)(sqlite3_stmt*);
|
||||||
int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*,
|
int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*,
|
||||||
char const**,char const**,int*,int*,int*);
|
char const**,char const**,int*,int*,int*);
|
||||||
@@ -418,7 +418,7 @@ typedef int (*sqlite3_loadext_entry)(
|
|||||||
#define sqlite3_rollback_hook sqlite3_api->rollback_hook
|
#define sqlite3_rollback_hook sqlite3_api->rollback_hook
|
||||||
#define sqlite3_set_authorizer sqlite3_api->set_authorizer
|
#define sqlite3_set_authorizer sqlite3_api->set_authorizer
|
||||||
#define sqlite3_set_auxdata sqlite3_api->set_auxdata
|
#define sqlite3_set_auxdata sqlite3_api->set_auxdata
|
||||||
#define sqlite3_snprintf sqlite3_api->snprintf
|
#define sqlite3_snprintf sqlite3_api->xsnprintf
|
||||||
#define sqlite3_step sqlite3_api->step
|
#define sqlite3_step sqlite3_api->step
|
||||||
#define sqlite3_table_column_metadata sqlite3_api->table_column_metadata
|
#define sqlite3_table_column_metadata sqlite3_api->table_column_metadata
|
||||||
#define sqlite3_thread_cleanup sqlite3_api->thread_cleanup
|
#define sqlite3_thread_cleanup sqlite3_api->thread_cleanup
|
||||||
|
@@ -4400,6 +4400,9 @@ int sqlite3ThreadCreate(SQLiteThread**,void*(*)(void*),void*);
|
|||||||
int sqlite3ThreadJoin(SQLiteThread*, void**);
|
int sqlite3ThreadJoin(SQLiteThread*, void**);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)
|
||||||
|
int sqlite3DbpageRegister(sqlite3*);
|
||||||
|
#endif
|
||||||
#if defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST)
|
#if defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST)
|
||||||
int sqlite3DbstatRegister(sqlite3*);
|
int sqlite3DbstatRegister(sqlite3*);
|
||||||
#endif
|
#endif
|
||||||
|
844
src/tclsqlite.c
844
src/tclsqlite.c
@@ -14,17 +14,19 @@
|
|||||||
**
|
**
|
||||||
** Compile-time options:
|
** Compile-time options:
|
||||||
**
|
**
|
||||||
** -DTCLSH=1 Add a "main()" routine that works as a tclsh.
|
** -DTCLSH Add a "main()" routine that works as a tclsh.
|
||||||
**
|
**
|
||||||
** -DSQLITE_TCLMD5 When used in conjuction with -DTCLSH=1, add
|
** -DTCLSH_INIT_PROC=name
|
||||||
** four new commands to the TCL interpreter for
|
|
||||||
** generating MD5 checksums: md5, md5file,
|
|
||||||
** md5-10x8, and md5file-10x8.
|
|
||||||
**
|
**
|
||||||
** -DSQLITE_TEST When used in conjuction with -DTCLSH=1, add
|
** Invoke name(interp) to initialize the Tcl interpreter.
|
||||||
** hundreds of new commands used for testing
|
** If name(interp) returns a non-NULL string, then run
|
||||||
** SQLite. This option implies -DSQLITE_TCLMD5.
|
** that string as a Tcl script to launch the application.
|
||||||
|
** If name(interp) returns NULL, then run the regular
|
||||||
|
** tclsh-emulator code.
|
||||||
*/
|
*/
|
||||||
|
#ifdef TCLSH_INIT_PROC
|
||||||
|
# define TCLSH 1
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** If requested, include the SQLite compiler options file for MSVC.
|
** If requested, include the SQLite compiler options file for MSVC.
|
||||||
@@ -3286,7 +3288,42 @@ static int SQLITE_TCLAPI DbObjCmd(
|
|||||||
** Return the version string for this database.
|
** Return the version string for this database.
|
||||||
*/
|
*/
|
||||||
case DB_VERSION: {
|
case DB_VERSION: {
|
||||||
Tcl_SetResult(interp, (char *)sqlite3_libversion(), TCL_STATIC);
|
int i;
|
||||||
|
for(i=2; i<objc; i++){
|
||||||
|
const char *zArg = Tcl_GetString(objv[i]);
|
||||||
|
/* Optional arguments to $db version are used for testing purpose */
|
||||||
|
#ifdef SQLITE_TEST
|
||||||
|
/* $db version -use-legacy-prepare BOOLEAN
|
||||||
|
**
|
||||||
|
** Turn the use of legacy sqlite3_prepare() on or off.
|
||||||
|
*/
|
||||||
|
if( strcmp(zArg, "-use-legacy-prepare")==0 && i+1<objc ){
|
||||||
|
i++;
|
||||||
|
if( Tcl_GetBooleanFromObj(interp, objv[i], &pDb->bLegacyPrepare) ){
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
}else
|
||||||
|
|
||||||
|
/* $db version -last-stmt-ptr
|
||||||
|
**
|
||||||
|
** Return a string which is a hex encoding of the pointer to the
|
||||||
|
** most recent sqlite3_stmt in the statement cache.
|
||||||
|
*/
|
||||||
|
if( strcmp(zArg, "-last-stmt-ptr")==0 ){
|
||||||
|
char zBuf[100];
|
||||||
|
sqlite3_snprintf(sizeof(zBuf), zBuf, "%p",
|
||||||
|
pDb->stmtList ? pDb->stmtList->pStmt: 0);
|
||||||
|
Tcl_SetResult(interp, zBuf, TCL_VOLATILE);
|
||||||
|
}else
|
||||||
|
#endif /* SQLITE_TEST */
|
||||||
|
{
|
||||||
|
Tcl_AppendResult(interp, "unknown argument: ", zArg, (char*)0);
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( i==2 ){
|
||||||
|
Tcl_SetResult(interp, (char *)sqlite3_libversion(), TCL_STATIC);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3546,721 +3583,56 @@ int Sqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
|
|||||||
int Tclsqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
|
int Tclsqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TCLSH
|
/*
|
||||||
/*****************************************************************************
|
** If the TCLSH macro is defined, add code to make a stand-alone program.
|
||||||
** All of the code that follows is used to build standalone TCL interpreters
|
|
||||||
** that are statically linked with SQLite. Enable these by compiling
|
|
||||||
** with -DTCLSH=n where n can be 1 or 2. An n of 1 generates a standard
|
|
||||||
** tclsh but with SQLite built in. An n of 2 generates the SQLite space
|
|
||||||
** analysis program.
|
|
||||||
*/
|
*/
|
||||||
|
#if defined(TCLSH)
|
||||||
|
|
||||||
#if defined(SQLITE_TEST) || defined(SQLITE_TCLMD5)
|
/* This is the main routine for an ordinary TCL shell. If there are
|
||||||
/*
|
** are arguments, run the first argument as a script. Otherwise,
|
||||||
* This code implements the MD5 message-digest algorithm.
|
** read TCL commands from standard input
|
||||||
* The algorithm is due to Ron Rivest. This code was
|
|
||||||
* written by Colin Plumb in 1993, no copyright is claimed.
|
|
||||||
* This code is in the public domain; do with it what you wish.
|
|
||||||
*
|
|
||||||
* Equivalent code is available from RSA Data Security, Inc.
|
|
||||||
* This code has been tested against that, and is equivalent,
|
|
||||||
* except that you don't need to include two pages of legalese
|
|
||||||
* with every copy.
|
|
||||||
*
|
|
||||||
* To compute the message digest of a chunk of bytes, declare an
|
|
||||||
* MD5Context structure, pass it to MD5Init, call MD5Update as
|
|
||||||
* needed on buffers full of bytes, and then call MD5Final, which
|
|
||||||
* will fill a supplied 16-byte array with the digest.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If compiled on a machine that doesn't have a 32-bit integer,
|
|
||||||
* you just set "uint32" to the appropriate datatype for an
|
|
||||||
* unsigned 32-bit integer. For example:
|
|
||||||
*
|
|
||||||
* cc -Duint32='unsigned long' md5.c
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#ifndef uint32
|
|
||||||
# define uint32 unsigned int
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct MD5Context {
|
|
||||||
int isInit;
|
|
||||||
uint32 buf[4];
|
|
||||||
uint32 bits[2];
|
|
||||||
unsigned char in[64];
|
|
||||||
};
|
|
||||||
typedef struct MD5Context MD5Context;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Note: this code is harmless on little-endian machines.
|
|
||||||
*/
|
|
||||||
static void byteReverse (unsigned char *buf, unsigned longs){
|
|
||||||
uint32 t;
|
|
||||||
do {
|
|
||||||
t = (uint32)((unsigned)buf[3]<<8 | buf[2]) << 16 |
|
|
||||||
((unsigned)buf[1]<<8 | buf[0]);
|
|
||||||
*(uint32 *)buf = t;
|
|
||||||
buf += 4;
|
|
||||||
} while (--longs);
|
|
||||||
}
|
|
||||||
/* The four core functions - F1 is optimized somewhat */
|
|
||||||
|
|
||||||
/* #define F1(x, y, z) (x & y | ~x & z) */
|
|
||||||
#define F1(x, y, z) (z ^ (x & (y ^ z)))
|
|
||||||
#define F2(x, y, z) F1(z, x, y)
|
|
||||||
#define F3(x, y, z) (x ^ y ^ z)
|
|
||||||
#define F4(x, y, z) (y ^ (x | ~z))
|
|
||||||
|
|
||||||
/* This is the central step in the MD5 algorithm. */
|
|
||||||
#define MD5STEP(f, w, x, y, z, data, s) \
|
|
||||||
( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The core of the MD5 algorithm, this alters an existing MD5 hash to
|
|
||||||
* reflect the addition of 16 longwords of new data. MD5Update blocks
|
|
||||||
* the data and converts bytes into longwords for this routine.
|
|
||||||
*/
|
|
||||||
static void MD5Transform(uint32 buf[4], const uint32 in[16]){
|
|
||||||
register uint32 a, b, c, d;
|
|
||||||
|
|
||||||
a = buf[0];
|
|
||||||
b = buf[1];
|
|
||||||
c = buf[2];
|
|
||||||
d = buf[3];
|
|
||||||
|
|
||||||
MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478, 7);
|
|
||||||
MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
|
|
||||||
MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);
|
|
||||||
MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
|
|
||||||
MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf, 7);
|
|
||||||
MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
|
|
||||||
MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);
|
|
||||||
MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);
|
|
||||||
MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8, 7);
|
|
||||||
MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
|
|
||||||
MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);
|
|
||||||
MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);
|
|
||||||
MD5STEP(F1, a, b, c, d, in[12]+0x6b901122, 7);
|
|
||||||
MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);
|
|
||||||
MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);
|
|
||||||
MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);
|
|
||||||
|
|
||||||
MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562, 5);
|
|
||||||
MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340, 9);
|
|
||||||
MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);
|
|
||||||
MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
|
|
||||||
MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d, 5);
|
|
||||||
MD5STEP(F2, d, a, b, c, in[10]+0x02441453, 9);
|
|
||||||
MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);
|
|
||||||
MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
|
|
||||||
MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6, 5);
|
|
||||||
MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6, 9);
|
|
||||||
MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
|
|
||||||
MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
|
|
||||||
MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905, 5);
|
|
||||||
MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8, 9);
|
|
||||||
MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
|
|
||||||
MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);
|
|
||||||
|
|
||||||
MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942, 4);
|
|
||||||
MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);
|
|
||||||
MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);
|
|
||||||
MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);
|
|
||||||
MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44, 4);
|
|
||||||
MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
|
|
||||||
MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
|
|
||||||
MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);
|
|
||||||
MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6, 4);
|
|
||||||
MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
|
|
||||||
MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
|
|
||||||
MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);
|
|
||||||
MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039, 4);
|
|
||||||
MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);
|
|
||||||
MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
|
|
||||||
MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);
|
|
||||||
|
|
||||||
MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244, 6);
|
|
||||||
MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);
|
|
||||||
MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);
|
|
||||||
MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
|
|
||||||
MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3, 6);
|
|
||||||
MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
|
|
||||||
MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);
|
|
||||||
MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
|
|
||||||
MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f, 6);
|
|
||||||
MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
|
|
||||||
MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);
|
|
||||||
MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);
|
|
||||||
MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82, 6);
|
|
||||||
MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);
|
|
||||||
MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
|
|
||||||
MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);
|
|
||||||
|
|
||||||
buf[0] += a;
|
|
||||||
buf[1] += b;
|
|
||||||
buf[2] += c;
|
|
||||||
buf[3] += d;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
|
|
||||||
* initialization constants.
|
|
||||||
*/
|
|
||||||
static void MD5Init(MD5Context *ctx){
|
|
||||||
ctx->isInit = 1;
|
|
||||||
ctx->buf[0] = 0x67452301;
|
|
||||||
ctx->buf[1] = 0xefcdab89;
|
|
||||||
ctx->buf[2] = 0x98badcfe;
|
|
||||||
ctx->buf[3] = 0x10325476;
|
|
||||||
ctx->bits[0] = 0;
|
|
||||||
ctx->bits[1] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Update context to reflect the concatenation of another buffer full
|
|
||||||
* of bytes.
|
|
||||||
*/
|
|
||||||
static
|
|
||||||
void MD5Update(MD5Context *ctx, const unsigned char *buf, unsigned int len){
|
|
||||||
uint32 t;
|
|
||||||
|
|
||||||
/* Update bitcount */
|
|
||||||
|
|
||||||
t = ctx->bits[0];
|
|
||||||
if ((ctx->bits[0] = t + ((uint32)len << 3)) < t)
|
|
||||||
ctx->bits[1]++; /* Carry from low to high */
|
|
||||||
ctx->bits[1] += len >> 29;
|
|
||||||
|
|
||||||
t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
|
|
||||||
|
|
||||||
/* Handle any leading odd-sized chunks */
|
|
||||||
|
|
||||||
if ( t ) {
|
|
||||||
unsigned char *p = (unsigned char *)ctx->in + t;
|
|
||||||
|
|
||||||
t = 64-t;
|
|
||||||
if (len < t) {
|
|
||||||
memcpy(p, buf, len);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
memcpy(p, buf, t);
|
|
||||||
byteReverse(ctx->in, 16);
|
|
||||||
MD5Transform(ctx->buf, (uint32 *)ctx->in);
|
|
||||||
buf += t;
|
|
||||||
len -= t;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Process data in 64-byte chunks */
|
|
||||||
|
|
||||||
while (len >= 64) {
|
|
||||||
memcpy(ctx->in, buf, 64);
|
|
||||||
byteReverse(ctx->in, 16);
|
|
||||||
MD5Transform(ctx->buf, (uint32 *)ctx->in);
|
|
||||||
buf += 64;
|
|
||||||
len -= 64;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Handle any remaining bytes of data. */
|
|
||||||
|
|
||||||
memcpy(ctx->in, buf, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Final wrapup - pad to 64-byte boundary with the bit pattern
|
|
||||||
* 1 0* (64-bit count of bits processed, MSB-first)
|
|
||||||
*/
|
|
||||||
static void MD5Final(unsigned char digest[16], MD5Context *ctx){
|
|
||||||
unsigned count;
|
|
||||||
unsigned char *p;
|
|
||||||
|
|
||||||
/* Compute number of bytes mod 64 */
|
|
||||||
count = (ctx->bits[0] >> 3) & 0x3F;
|
|
||||||
|
|
||||||
/* Set the first char of padding to 0x80. This is safe since there is
|
|
||||||
always at least one byte free */
|
|
||||||
p = ctx->in + count;
|
|
||||||
*p++ = 0x80;
|
|
||||||
|
|
||||||
/* Bytes of padding needed to make 64 bytes */
|
|
||||||
count = 64 - 1 - count;
|
|
||||||
|
|
||||||
/* Pad out to 56 mod 64 */
|
|
||||||
if (count < 8) {
|
|
||||||
/* Two lots of padding: Pad the first block to 64 bytes */
|
|
||||||
memset(p, 0, count);
|
|
||||||
byteReverse(ctx->in, 16);
|
|
||||||
MD5Transform(ctx->buf, (uint32 *)ctx->in);
|
|
||||||
|
|
||||||
/* Now fill the next block with 56 bytes */
|
|
||||||
memset(ctx->in, 0, 56);
|
|
||||||
} else {
|
|
||||||
/* Pad block to 56 bytes */
|
|
||||||
memset(p, 0, count-8);
|
|
||||||
}
|
|
||||||
byteReverse(ctx->in, 14);
|
|
||||||
|
|
||||||
/* Append length in bits and transform */
|
|
||||||
memcpy(ctx->in + 14*4, ctx->bits, 8);
|
|
||||||
|
|
||||||
MD5Transform(ctx->buf, (uint32 *)ctx->in);
|
|
||||||
byteReverse((unsigned char *)ctx->buf, 4);
|
|
||||||
memcpy(digest, ctx->buf, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Convert a 128-bit MD5 digest into a 32-digit base-16 number.
|
|
||||||
*/
|
*/
|
||||||
static void MD5DigestToBase16(unsigned char *digest, char *zBuf){
|
|
||||||
static char const zEncode[] = "0123456789abcdef";
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
for(j=i=0; i<16; i++){
|
|
||||||
int a = digest[i];
|
|
||||||
zBuf[j++] = zEncode[(a>>4)&0xf];
|
|
||||||
zBuf[j++] = zEncode[a & 0xf];
|
|
||||||
}
|
|
||||||
zBuf[j] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Convert a 128-bit MD5 digest into sequency of eight 5-digit integers
|
|
||||||
** each representing 16 bits of the digest and separated from each
|
|
||||||
** other by a "-" character.
|
|
||||||
*/
|
|
||||||
static void MD5DigestToBase10x8(unsigned char digest[16], char zDigest[50]){
|
|
||||||
int i, j;
|
|
||||||
unsigned int x;
|
|
||||||
for(i=j=0; i<16; i+=2){
|
|
||||||
x = digest[i]*256 + digest[i+1];
|
|
||||||
if( i>0 ) zDigest[j++] = '-';
|
|
||||||
sqlite3_snprintf(50-j, &zDigest[j], "%05u", x);
|
|
||||||
j += 5;
|
|
||||||
}
|
|
||||||
zDigest[j] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** A TCL command for md5. The argument is the text to be hashed. The
|
|
||||||
** Result is the hash in base64.
|
|
||||||
*/
|
|
||||||
static int SQLITE_TCLAPI md5_cmd(
|
|
||||||
void*cd,
|
|
||||||
Tcl_Interp *interp,
|
|
||||||
int argc,
|
|
||||||
const char **argv
|
|
||||||
){
|
|
||||||
MD5Context ctx;
|
|
||||||
unsigned char digest[16];
|
|
||||||
char zBuf[50];
|
|
||||||
void (*converter)(unsigned char*, char*);
|
|
||||||
|
|
||||||
if( argc!=2 ){
|
|
||||||
Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
|
|
||||||
" TEXT\"", (char*)0);
|
|
||||||
return TCL_ERROR;
|
|
||||||
}
|
|
||||||
MD5Init(&ctx);
|
|
||||||
MD5Update(&ctx, (unsigned char*)argv[1], (unsigned)strlen(argv[1]));
|
|
||||||
MD5Final(digest, &ctx);
|
|
||||||
converter = (void(*)(unsigned char*,char*))cd;
|
|
||||||
converter(digest, zBuf);
|
|
||||||
Tcl_AppendResult(interp, zBuf, (char*)0);
|
|
||||||
return TCL_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** A TCL command to take the md5 hash of a file. The argument is the
|
|
||||||
** name of the file.
|
|
||||||
*/
|
|
||||||
static int SQLITE_TCLAPI md5file_cmd(
|
|
||||||
void*cd,
|
|
||||||
Tcl_Interp *interp,
|
|
||||||
int argc,
|
|
||||||
const char **argv
|
|
||||||
){
|
|
||||||
FILE *in;
|
|
||||||
int ofst;
|
|
||||||
int amt;
|
|
||||||
MD5Context ctx;
|
|
||||||
void (*converter)(unsigned char*, char*);
|
|
||||||
unsigned char digest[16];
|
|
||||||
char zBuf[10240];
|
|
||||||
|
|
||||||
if( argc!=2 && argc!=4 ){
|
|
||||||
Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
|
|
||||||
" FILENAME [OFFSET AMT]\"", (char*)0);
|
|
||||||
return TCL_ERROR;
|
|
||||||
}
|
|
||||||
if( argc==4 ){
|
|
||||||
ofst = atoi(argv[2]);
|
|
||||||
amt = atoi(argv[3]);
|
|
||||||
}else{
|
|
||||||
ofst = 0;
|
|
||||||
amt = 2147483647;
|
|
||||||
}
|
|
||||||
in = fopen(argv[1],"rb");
|
|
||||||
if( in==0 ){
|
|
||||||
Tcl_AppendResult(interp,"unable to open file \"", argv[1],
|
|
||||||
"\" for reading", (char*)0);
|
|
||||||
return TCL_ERROR;
|
|
||||||
}
|
|
||||||
fseek(in, ofst, SEEK_SET);
|
|
||||||
MD5Init(&ctx);
|
|
||||||
while( amt>0 ){
|
|
||||||
int n;
|
|
||||||
n = (int)fread(zBuf, 1, sizeof(zBuf)<=amt ? sizeof(zBuf) : amt, in);
|
|
||||||
if( n<=0 ) break;
|
|
||||||
MD5Update(&ctx, (unsigned char*)zBuf, (unsigned)n);
|
|
||||||
amt -= n;
|
|
||||||
}
|
|
||||||
fclose(in);
|
|
||||||
MD5Final(digest, &ctx);
|
|
||||||
converter = (void(*)(unsigned char*,char*))cd;
|
|
||||||
converter(digest, zBuf);
|
|
||||||
Tcl_AppendResult(interp, zBuf, (char*)0);
|
|
||||||
return TCL_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Register the four new TCL commands for generating MD5 checksums
|
|
||||||
** with the TCL interpreter.
|
|
||||||
*/
|
|
||||||
int Md5_Init(Tcl_Interp *interp){
|
|
||||||
Tcl_CreateCommand(interp, "md5", (Tcl_CmdProc*)md5_cmd,
|
|
||||||
MD5DigestToBase16, 0);
|
|
||||||
Tcl_CreateCommand(interp, "md5-10x8", (Tcl_CmdProc*)md5_cmd,
|
|
||||||
MD5DigestToBase10x8, 0);
|
|
||||||
Tcl_CreateCommand(interp, "md5file", (Tcl_CmdProc*)md5file_cmd,
|
|
||||||
MD5DigestToBase16, 0);
|
|
||||||
Tcl_CreateCommand(interp, "md5file-10x8", (Tcl_CmdProc*)md5file_cmd,
|
|
||||||
MD5DigestToBase10x8, 0);
|
|
||||||
return TCL_OK;
|
|
||||||
}
|
|
||||||
#endif /* defined(SQLITE_TEST) || defined(SQLITE_TCLMD5) */
|
|
||||||
|
|
||||||
#if defined(SQLITE_TEST)
|
|
||||||
/*
|
|
||||||
** During testing, the special md5sum() aggregate function is available.
|
|
||||||
** inside SQLite. The following routines implement that function.
|
|
||||||
*/
|
|
||||||
static void md5step(sqlite3_context *context, int argc, sqlite3_value **argv){
|
|
||||||
MD5Context *p;
|
|
||||||
int i;
|
|
||||||
if( argc<1 ) return;
|
|
||||||
p = sqlite3_aggregate_context(context, sizeof(*p));
|
|
||||||
if( p==0 ) return;
|
|
||||||
if( !p->isInit ){
|
|
||||||
MD5Init(p);
|
|
||||||
}
|
|
||||||
for(i=0; i<argc; i++){
|
|
||||||
const char *zData = (char*)sqlite3_value_text(argv[i]);
|
|
||||||
if( zData ){
|
|
||||||
MD5Update(p, (unsigned char*)zData, (int)strlen(zData));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static void md5finalize(sqlite3_context *context){
|
|
||||||
MD5Context *p;
|
|
||||||
unsigned char digest[16];
|
|
||||||
char zBuf[33];
|
|
||||||
p = sqlite3_aggregate_context(context, sizeof(*p));
|
|
||||||
MD5Final(digest,p);
|
|
||||||
MD5DigestToBase16(digest, zBuf);
|
|
||||||
sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
|
|
||||||
}
|
|
||||||
int Md5_Register(
|
|
||||||
sqlite3 *db,
|
|
||||||
char **pzErrMsg,
|
|
||||||
const sqlite3_api_routines *pThunk
|
|
||||||
){
|
|
||||||
int rc = sqlite3_create_function(db, "md5sum", -1, SQLITE_UTF8, 0, 0,
|
|
||||||
md5step, md5finalize);
|
|
||||||
sqlite3_overload_function(db, "md5sum", -1); /* To exercise this API */
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
#endif /* defined(SQLITE_TEST) */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** If the macro TCLSH is one, then put in code this for the
|
|
||||||
** "main" routine that will initialize Tcl and take input from
|
|
||||||
** standard input, or if a file is named on the command line
|
|
||||||
** the TCL interpreter reads and evaluates that file.
|
|
||||||
*/
|
|
||||||
#if TCLSH==1
|
|
||||||
static const char *tclsh_main_loop(void){
|
static const char *tclsh_main_loop(void){
|
||||||
static const char zMainloop[] =
|
static const char zMainloop[] =
|
||||||
"set line {}\n"
|
"if {[llength $argv]>=1} {\n"
|
||||||
"while {![eof stdin]} {\n"
|
"set argv0 [lindex $argv 0]\n"
|
||||||
"if {$line!=\"\"} {\n"
|
"set argv [lrange $argv 1 end]\n"
|
||||||
"puts -nonewline \"> \"\n"
|
"source $argv0\n"
|
||||||
"} else {\n"
|
"} else {\n"
|
||||||
"puts -nonewline \"% \"\n"
|
"set line {}\n"
|
||||||
"}\n"
|
"while {![eof stdin]} {\n"
|
||||||
"flush stdout\n"
|
"if {$line!=\"\"} {\n"
|
||||||
"append line [gets stdin]\n"
|
"puts -nonewline \"> \"\n"
|
||||||
"if {[info complete $line]} {\n"
|
"} else {\n"
|
||||||
"if {[catch {uplevel #0 $line} result]} {\n"
|
"puts -nonewline \"% \"\n"
|
||||||
"puts stderr \"Error: $result\"\n"
|
"}\n"
|
||||||
"} elseif {$result!=\"\"} {\n"
|
"flush stdout\n"
|
||||||
"puts $result\n"
|
"append line [gets stdin]\n"
|
||||||
|
"if {[info complete $line]} {\n"
|
||||||
|
"if {[catch {uplevel #0 $line} result]} {\n"
|
||||||
|
"puts stderr \"Error: $result\"\n"
|
||||||
|
"} elseif {$result!=\"\"} {\n"
|
||||||
|
"puts $result\n"
|
||||||
|
"}\n"
|
||||||
|
"set line {}\n"
|
||||||
|
"} else {\n"
|
||||||
|
"append line \\n\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
"set line {}\n"
|
|
||||||
"} else {\n"
|
|
||||||
"append line \\n\n"
|
|
||||||
"}\n"
|
"}\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
;
|
;
|
||||||
return zMainloop;
|
return zMainloop;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#if TCLSH==2
|
|
||||||
static const char *tclsh_main_loop(void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SQLITE_TEST
|
|
||||||
static void init_all(Tcl_Interp *);
|
|
||||||
static int SQLITE_TCLAPI init_all_cmd(
|
|
||||||
ClientData cd,
|
|
||||||
Tcl_Interp *interp,
|
|
||||||
int objc,
|
|
||||||
Tcl_Obj *CONST objv[]
|
|
||||||
){
|
|
||||||
|
|
||||||
Tcl_Interp *slave;
|
|
||||||
if( objc!=2 ){
|
|
||||||
Tcl_WrongNumArgs(interp, 1, objv, "SLAVE");
|
|
||||||
return TCL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
slave = Tcl_GetSlave(interp, Tcl_GetString(objv[1]));
|
|
||||||
if( !slave ){
|
|
||||||
return TCL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
init_all(slave);
|
|
||||||
return TCL_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Tclcmd: db_use_legacy_prepare DB BOOLEAN
|
|
||||||
**
|
|
||||||
** The first argument to this command must be a database command created by
|
|
||||||
** [sqlite3]. If the second argument is true, then the handle is configured
|
|
||||||
** to use the sqlite3_prepare_v2() function to prepare statements. If it
|
|
||||||
** is false, sqlite3_prepare().
|
|
||||||
*/
|
|
||||||
static int SQLITE_TCLAPI db_use_legacy_prepare_cmd(
|
|
||||||
ClientData cd,
|
|
||||||
Tcl_Interp *interp,
|
|
||||||
int objc,
|
|
||||||
Tcl_Obj *CONST objv[]
|
|
||||||
){
|
|
||||||
Tcl_CmdInfo cmdInfo;
|
|
||||||
SqliteDb *pDb;
|
|
||||||
int bPrepare;
|
|
||||||
|
|
||||||
if( objc!=3 ){
|
|
||||||
Tcl_WrongNumArgs(interp, 1, objv, "DB BOOLEAN");
|
|
||||||
return TCL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &cmdInfo) ){
|
|
||||||
Tcl_AppendResult(interp, "no such db: ", Tcl_GetString(objv[1]), (char*)0);
|
|
||||||
return TCL_ERROR;
|
|
||||||
}
|
|
||||||
pDb = (SqliteDb*)cmdInfo.objClientData;
|
|
||||||
if( Tcl_GetBooleanFromObj(interp, objv[2], &bPrepare) ){
|
|
||||||
return TCL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
pDb->bLegacyPrepare = bPrepare;
|
|
||||||
|
|
||||||
Tcl_ResetResult(interp);
|
|
||||||
return TCL_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Tclcmd: db_last_stmt_ptr DB
|
|
||||||
**
|
|
||||||
** If the statement cache associated with database DB is not empty,
|
|
||||||
** return the text representation of the most recently used statement
|
|
||||||
** handle.
|
|
||||||
*/
|
|
||||||
static int SQLITE_TCLAPI db_last_stmt_ptr(
|
|
||||||
ClientData cd,
|
|
||||||
Tcl_Interp *interp,
|
|
||||||
int objc,
|
|
||||||
Tcl_Obj *CONST objv[]
|
|
||||||
){
|
|
||||||
extern int sqlite3TestMakePointerStr(Tcl_Interp*, char*, void*);
|
|
||||||
Tcl_CmdInfo cmdInfo;
|
|
||||||
SqliteDb *pDb;
|
|
||||||
sqlite3_stmt *pStmt = 0;
|
|
||||||
char zBuf[100];
|
|
||||||
|
|
||||||
if( objc!=2 ){
|
|
||||||
Tcl_WrongNumArgs(interp, 1, objv, "DB");
|
|
||||||
return TCL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &cmdInfo) ){
|
|
||||||
Tcl_AppendResult(interp, "no such db: ", Tcl_GetString(objv[1]), (char*)0);
|
|
||||||
return TCL_ERROR;
|
|
||||||
}
|
|
||||||
pDb = (SqliteDb*)cmdInfo.objClientData;
|
|
||||||
|
|
||||||
if( pDb->stmtList ) pStmt = pDb->stmtList->pStmt;
|
|
||||||
if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ){
|
|
||||||
return TCL_ERROR;
|
|
||||||
}
|
|
||||||
Tcl_SetResult(interp, zBuf, TCL_VOLATILE);
|
|
||||||
|
|
||||||
return TCL_OK;
|
|
||||||
}
|
|
||||||
#endif /* SQLITE_TEST */
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Configure the interpreter passed as the first argument to have access
|
|
||||||
** to the commands and linked variables that make up:
|
|
||||||
**
|
|
||||||
** * the [sqlite3] extension itself,
|
|
||||||
**
|
|
||||||
** * If SQLITE_TCLMD5 or SQLITE_TEST is defined, the Md5 commands, and
|
|
||||||
**
|
|
||||||
** * If SQLITE_TEST is set, the various test interfaces used by the Tcl
|
|
||||||
** test suite.
|
|
||||||
*/
|
|
||||||
static void init_all(Tcl_Interp *interp){
|
|
||||||
Sqlite3_Init(interp);
|
|
||||||
|
|
||||||
#if defined(SQLITE_TEST) || defined(SQLITE_TCLMD5)
|
|
||||||
Md5_Init(interp);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SQLITE_TEST
|
|
||||||
{
|
|
||||||
extern int Sqliteconfig_Init(Tcl_Interp*);
|
|
||||||
extern int Sqlitetest1_Init(Tcl_Interp*);
|
|
||||||
extern int Sqlitetest2_Init(Tcl_Interp*);
|
|
||||||
extern int Sqlitetest3_Init(Tcl_Interp*);
|
|
||||||
extern int Sqlitetest4_Init(Tcl_Interp*);
|
|
||||||
extern int Sqlitetest5_Init(Tcl_Interp*);
|
|
||||||
extern int Sqlitetest6_Init(Tcl_Interp*);
|
|
||||||
extern int Sqlitetest7_Init(Tcl_Interp*);
|
|
||||||
extern int Sqlitetest8_Init(Tcl_Interp*);
|
|
||||||
extern int Sqlitetest9_Init(Tcl_Interp*);
|
|
||||||
extern int Sqlitetestasync_Init(Tcl_Interp*);
|
|
||||||
extern int Sqlitetest_autoext_Init(Tcl_Interp*);
|
|
||||||
extern int Sqlitetest_blob_Init(Tcl_Interp*);
|
|
||||||
extern int Sqlitetest_demovfs_Init(Tcl_Interp *);
|
|
||||||
extern int Sqlitetest_func_Init(Tcl_Interp*);
|
|
||||||
extern int Sqlitetest_hexio_Init(Tcl_Interp*);
|
|
||||||
extern int Sqlitetest_init_Init(Tcl_Interp*);
|
|
||||||
extern int Sqlitetest_malloc_Init(Tcl_Interp*);
|
|
||||||
extern int Sqlitetest_mutex_Init(Tcl_Interp*);
|
|
||||||
extern int Sqlitetestschema_Init(Tcl_Interp*);
|
|
||||||
extern int Sqlitetestsse_Init(Tcl_Interp*);
|
|
||||||
extern int Sqlitetesttclvar_Init(Tcl_Interp*);
|
|
||||||
extern int Sqlitetestfs_Init(Tcl_Interp*);
|
|
||||||
extern int SqlitetestThread_Init(Tcl_Interp*);
|
|
||||||
extern int SqlitetestOnefile_Init();
|
|
||||||
extern int SqlitetestOsinst_Init(Tcl_Interp*);
|
|
||||||
extern int Sqlitetestbackup_Init(Tcl_Interp*);
|
|
||||||
extern int Sqlitetestintarray_Init(Tcl_Interp*);
|
|
||||||
extern int Sqlitetestvfs_Init(Tcl_Interp *);
|
|
||||||
extern int Sqlitetestrtree_Init(Tcl_Interp*);
|
|
||||||
extern int Sqlitequota_Init(Tcl_Interp*);
|
|
||||||
extern int Sqlitemultiplex_Init(Tcl_Interp*);
|
|
||||||
extern int SqliteSuperlock_Init(Tcl_Interp*);
|
|
||||||
extern int SqlitetestSyscall_Init(Tcl_Interp*);
|
|
||||||
#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
|
|
||||||
extern int TestSession_Init(Tcl_Interp*);
|
|
||||||
#endif
|
|
||||||
extern int Fts5tcl_Init(Tcl_Interp *);
|
|
||||||
extern int SqliteRbu_Init(Tcl_Interp*);
|
|
||||||
extern int Sqlitetesttcl_Init(Tcl_Interp*);
|
|
||||||
#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
|
|
||||||
extern int Sqlitetestfts3_Init(Tcl_Interp *interp);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SQLITE_ENABLE_ZIPVFS
|
|
||||||
extern int Zipvfs_Init(Tcl_Interp*);
|
|
||||||
Zipvfs_Init(interp);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Sqliteconfig_Init(interp);
|
|
||||||
Sqlitetest1_Init(interp);
|
|
||||||
Sqlitetest2_Init(interp);
|
|
||||||
Sqlitetest3_Init(interp);
|
|
||||||
Sqlitetest4_Init(interp);
|
|
||||||
Sqlitetest5_Init(interp);
|
|
||||||
Sqlitetest6_Init(interp);
|
|
||||||
Sqlitetest7_Init(interp);
|
|
||||||
Sqlitetest8_Init(interp);
|
|
||||||
Sqlitetest9_Init(interp);
|
|
||||||
Sqlitetestasync_Init(interp);
|
|
||||||
Sqlitetest_autoext_Init(interp);
|
|
||||||
Sqlitetest_blob_Init(interp);
|
|
||||||
Sqlitetest_demovfs_Init(interp);
|
|
||||||
Sqlitetest_func_Init(interp);
|
|
||||||
Sqlitetest_hexio_Init(interp);
|
|
||||||
Sqlitetest_init_Init(interp);
|
|
||||||
Sqlitetest_malloc_Init(interp);
|
|
||||||
Sqlitetest_mutex_Init(interp);
|
|
||||||
Sqlitetestschema_Init(interp);
|
|
||||||
Sqlitetesttclvar_Init(interp);
|
|
||||||
Sqlitetestfs_Init(interp);
|
|
||||||
SqlitetestThread_Init(interp);
|
|
||||||
SqlitetestOnefile_Init();
|
|
||||||
SqlitetestOsinst_Init(interp);
|
|
||||||
Sqlitetestbackup_Init(interp);
|
|
||||||
Sqlitetestintarray_Init(interp);
|
|
||||||
Sqlitetestvfs_Init(interp);
|
|
||||||
Sqlitetestrtree_Init(interp);
|
|
||||||
Sqlitequota_Init(interp);
|
|
||||||
Sqlitemultiplex_Init(interp);
|
|
||||||
SqliteSuperlock_Init(interp);
|
|
||||||
SqlitetestSyscall_Init(interp);
|
|
||||||
#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
|
|
||||||
TestSession_Init(interp);
|
|
||||||
#endif
|
|
||||||
Fts5tcl_Init(interp);
|
|
||||||
SqliteRbu_Init(interp);
|
|
||||||
Sqlitetesttcl_Init(interp);
|
|
||||||
|
|
||||||
#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
|
|
||||||
Sqlitetestfts3_Init(interp);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Tcl_CreateObjCommand(
|
|
||||||
interp, "load_testfixture_extensions", init_all_cmd, 0, 0
|
|
||||||
);
|
|
||||||
Tcl_CreateObjCommand(
|
|
||||||
interp, "db_use_legacy_prepare", db_use_legacy_prepare_cmd, 0, 0
|
|
||||||
);
|
|
||||||
Tcl_CreateObjCommand(
|
|
||||||
interp, "db_last_stmt_ptr", db_last_stmt_ptr, 0, 0
|
|
||||||
);
|
|
||||||
|
|
||||||
#ifdef SQLITE_SSE
|
|
||||||
Sqlitetestsse_Init(interp);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Needed for the setrlimit() system call on unix */
|
|
||||||
#if defined(unix)
|
|
||||||
#include <sys/resource.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define TCLSH_MAIN main /* Needed to fake out mktclapp */
|
#define TCLSH_MAIN main /* Needed to fake out mktclapp */
|
||||||
int SQLITE_CDECL TCLSH_MAIN(int argc, char **argv){
|
int SQLITE_CDECL TCLSH_MAIN(int argc, char **argv){
|
||||||
Tcl_Interp *interp;
|
Tcl_Interp *interp;
|
||||||
|
int i;
|
||||||
|
const char *zScript = 0;
|
||||||
|
char zArgc[32];
|
||||||
|
#if defined(TCLSH_INIT_PROC)
|
||||||
|
extern const char *TCLSH_INIT_PROC(Tcl_Interp*);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(_WIN32_WCE)
|
#if !defined(_WIN32_WCE)
|
||||||
if( getenv("BREAK") ){
|
if( getenv("BREAK") ){
|
||||||
@@ -4271,17 +3643,6 @@ int SQLITE_CDECL TCLSH_MAIN(int argc, char **argv){
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Since the primary use case for this binary is testing of SQLite,
|
|
||||||
** be sure to generate core files if we crash */
|
|
||||||
#if defined(SQLITE_TEST) && defined(unix)
|
|
||||||
{ struct rlimit x;
|
|
||||||
getrlimit(RLIMIT_CORE, &x);
|
|
||||||
x.rlim_cur = x.rlim_max;
|
|
||||||
setrlimit(RLIMIT_CORE, &x);
|
|
||||||
}
|
|
||||||
#endif /* SQLITE_TEST && unix */
|
|
||||||
|
|
||||||
|
|
||||||
/* Call sqlite3_shutdown() once before doing anything else. This is to
|
/* Call sqlite3_shutdown() once before doing anything else. This is to
|
||||||
** test that sqlite3_shutdown() can be safely called by a process before
|
** test that sqlite3_shutdown() can be safely called by a process before
|
||||||
** sqlite3_initialize() is. */
|
** sqlite3_initialize() is. */
|
||||||
@@ -4290,32 +3651,27 @@ int SQLITE_CDECL TCLSH_MAIN(int argc, char **argv){
|
|||||||
Tcl_FindExecutable(argv[0]);
|
Tcl_FindExecutable(argv[0]);
|
||||||
Tcl_SetSystemEncoding(NULL, "utf-8");
|
Tcl_SetSystemEncoding(NULL, "utf-8");
|
||||||
interp = Tcl_CreateInterp();
|
interp = Tcl_CreateInterp();
|
||||||
|
Sqlite3_Init(interp);
|
||||||
|
|
||||||
#if TCLSH==2
|
sqlite3_snprintf(sizeof(zArgc), zArgc, "%d", argc-1);
|
||||||
sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
|
Tcl_SetVar(interp,"argc", zArgc, TCL_GLOBAL_ONLY);
|
||||||
#endif
|
Tcl_SetVar(interp,"argv0",argv[0],TCL_GLOBAL_ONLY);
|
||||||
|
Tcl_SetVar(interp,"argv", "", TCL_GLOBAL_ONLY);
|
||||||
init_all(interp);
|
for(i=1; i<argc; i++){
|
||||||
if( argc>=2 ){
|
Tcl_SetVar(interp, "argv", argv[i],
|
||||||
int i;
|
TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT | TCL_APPEND_VALUE);
|
||||||
char zArgc[32];
|
|
||||||
sqlite3_snprintf(sizeof(zArgc), zArgc, "%d", argc-(3-TCLSH));
|
|
||||||
Tcl_SetVar(interp,"argc", zArgc, TCL_GLOBAL_ONLY);
|
|
||||||
Tcl_SetVar(interp,"argv0",argv[1],TCL_GLOBAL_ONLY);
|
|
||||||
Tcl_SetVar(interp,"argv", "", TCL_GLOBAL_ONLY);
|
|
||||||
for(i=3-TCLSH; i<argc; i++){
|
|
||||||
Tcl_SetVar(interp, "argv", argv[i],
|
|
||||||
TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT | TCL_APPEND_VALUE);
|
|
||||||
}
|
|
||||||
if( TCLSH==1 && Tcl_EvalFile(interp, argv[1])!=TCL_OK ){
|
|
||||||
const char *zInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
|
|
||||||
if( zInfo==0 ) zInfo = Tcl_GetStringResult(interp);
|
|
||||||
fprintf(stderr,"%s: %s\n", *argv, zInfo);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if( TCLSH==2 || argc<=1 ){
|
#if defined(TCLSH_INIT_PROC)
|
||||||
Tcl_GlobalEval(interp, tclsh_main_loop());
|
zScript = TCLSH_INIT_PROC(interp);
|
||||||
|
#endif
|
||||||
|
if( zScript==0 ){
|
||||||
|
zScript = tclsh_main_loop();
|
||||||
|
}
|
||||||
|
if( Tcl_GlobalEval(interp, zScript)!=TCL_OK ){
|
||||||
|
const char *zInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
|
||||||
|
if( zInfo==0 ) zInfo = Tcl_GetStringResult(interp);
|
||||||
|
fprintf(stderr,"%s: %s\n", *argv, zInfo);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
450
src/test_md5.c
Normal file
450
src/test_md5.c
Normal file
@@ -0,0 +1,450 @@
|
|||||||
|
/*
|
||||||
|
** 2017-10-13
|
||||||
|
**
|
||||||
|
** 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 contains code to implement an MD5 extension to TCL.
|
||||||
|
*/
|
||||||
|
#include "sqlite3.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "sqlite3.h"
|
||||||
|
#if defined(INCLUDE_SQLITE_TCL_H)
|
||||||
|
# include "sqlite_tcl.h"
|
||||||
|
#else
|
||||||
|
# include "tcl.h"
|
||||||
|
# ifndef SQLITE_TCLAPI
|
||||||
|
# define SQLITE_TCLAPI
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This code implements the MD5 message-digest algorithm.
|
||||||
|
* The algorithm is due to Ron Rivest. This code was
|
||||||
|
* written by Colin Plumb in 1993, no copyright is claimed.
|
||||||
|
* This code is in the public domain; do with it what you wish.
|
||||||
|
*
|
||||||
|
* Equivalent code is available from RSA Data Security, Inc.
|
||||||
|
* This code has been tested against that, and is equivalent,
|
||||||
|
* except that you don't need to include two pages of legalese
|
||||||
|
* with every copy.
|
||||||
|
*
|
||||||
|
* To compute the message digest of a chunk of bytes, declare an
|
||||||
|
* MD5Context structure, pass it to MD5Init, call MD5Update as
|
||||||
|
* needed on buffers full of bytes, and then call MD5Final, which
|
||||||
|
* will fill a supplied 16-byte array with the digest.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If compiled on a machine that doesn't have a 32-bit integer,
|
||||||
|
* you just set "uint32" to the appropriate datatype for an
|
||||||
|
* unsigned 32-bit integer. For example:
|
||||||
|
*
|
||||||
|
* cc -Duint32='unsigned long' md5.c
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef uint32
|
||||||
|
# define uint32 unsigned int
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct MD5Context {
|
||||||
|
int isInit;
|
||||||
|
uint32 buf[4];
|
||||||
|
uint32 bits[2];
|
||||||
|
unsigned char in[64];
|
||||||
|
};
|
||||||
|
typedef struct MD5Context MD5Context;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note: this code is harmless on little-endian machines.
|
||||||
|
*/
|
||||||
|
static void byteReverse (unsigned char *buf, unsigned longs){
|
||||||
|
uint32 t;
|
||||||
|
do {
|
||||||
|
t = (uint32)((unsigned)buf[3]<<8 | buf[2]) << 16 |
|
||||||
|
((unsigned)buf[1]<<8 | buf[0]);
|
||||||
|
*(uint32 *)buf = t;
|
||||||
|
buf += 4;
|
||||||
|
} while (--longs);
|
||||||
|
}
|
||||||
|
/* The four core functions - F1 is optimized somewhat */
|
||||||
|
|
||||||
|
/* #define F1(x, y, z) (x & y | ~x & z) */
|
||||||
|
#define F1(x, y, z) (z ^ (x & (y ^ z)))
|
||||||
|
#define F2(x, y, z) F1(z, x, y)
|
||||||
|
#define F3(x, y, z) (x ^ y ^ z)
|
||||||
|
#define F4(x, y, z) (y ^ (x | ~z))
|
||||||
|
|
||||||
|
/* This is the central step in the MD5 algorithm. */
|
||||||
|
#define MD5STEP(f, w, x, y, z, data, s) \
|
||||||
|
( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The core of the MD5 algorithm, this alters an existing MD5 hash to
|
||||||
|
* reflect the addition of 16 longwords of new data. MD5Update blocks
|
||||||
|
* the data and converts bytes into longwords for this routine.
|
||||||
|
*/
|
||||||
|
static void MD5Transform(uint32 buf[4], const uint32 in[16]){
|
||||||
|
register uint32 a, b, c, d;
|
||||||
|
|
||||||
|
a = buf[0];
|
||||||
|
b = buf[1];
|
||||||
|
c = buf[2];
|
||||||
|
d = buf[3];
|
||||||
|
|
||||||
|
MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478, 7);
|
||||||
|
MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
|
||||||
|
MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);
|
||||||
|
MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
|
||||||
|
MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf, 7);
|
||||||
|
MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
|
||||||
|
MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);
|
||||||
|
MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);
|
||||||
|
MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8, 7);
|
||||||
|
MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
|
||||||
|
MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);
|
||||||
|
MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);
|
||||||
|
MD5STEP(F1, a, b, c, d, in[12]+0x6b901122, 7);
|
||||||
|
MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);
|
||||||
|
MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);
|
||||||
|
MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);
|
||||||
|
|
||||||
|
MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562, 5);
|
||||||
|
MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340, 9);
|
||||||
|
MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);
|
||||||
|
MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
|
||||||
|
MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d, 5);
|
||||||
|
MD5STEP(F2, d, a, b, c, in[10]+0x02441453, 9);
|
||||||
|
MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);
|
||||||
|
MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
|
||||||
|
MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6, 5);
|
||||||
|
MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6, 9);
|
||||||
|
MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
|
||||||
|
MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
|
||||||
|
MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905, 5);
|
||||||
|
MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8, 9);
|
||||||
|
MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
|
||||||
|
MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);
|
||||||
|
|
||||||
|
MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942, 4);
|
||||||
|
MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);
|
||||||
|
MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);
|
||||||
|
MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);
|
||||||
|
MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44, 4);
|
||||||
|
MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
|
||||||
|
MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
|
||||||
|
MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);
|
||||||
|
MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6, 4);
|
||||||
|
MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
|
||||||
|
MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
|
||||||
|
MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);
|
||||||
|
MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039, 4);
|
||||||
|
MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);
|
||||||
|
MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
|
||||||
|
MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);
|
||||||
|
|
||||||
|
MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244, 6);
|
||||||
|
MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);
|
||||||
|
MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);
|
||||||
|
MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
|
||||||
|
MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3, 6);
|
||||||
|
MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
|
||||||
|
MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);
|
||||||
|
MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
|
||||||
|
MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f, 6);
|
||||||
|
MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
|
||||||
|
MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);
|
||||||
|
MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);
|
||||||
|
MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82, 6);
|
||||||
|
MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);
|
||||||
|
MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
|
||||||
|
MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);
|
||||||
|
|
||||||
|
buf[0] += a;
|
||||||
|
buf[1] += b;
|
||||||
|
buf[2] += c;
|
||||||
|
buf[3] += d;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
|
||||||
|
* initialization constants.
|
||||||
|
*/
|
||||||
|
static void MD5Init(MD5Context *ctx){
|
||||||
|
ctx->isInit = 1;
|
||||||
|
ctx->buf[0] = 0x67452301;
|
||||||
|
ctx->buf[1] = 0xefcdab89;
|
||||||
|
ctx->buf[2] = 0x98badcfe;
|
||||||
|
ctx->buf[3] = 0x10325476;
|
||||||
|
ctx->bits[0] = 0;
|
||||||
|
ctx->bits[1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Update context to reflect the concatenation of another buffer full
|
||||||
|
* of bytes.
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
void MD5Update(MD5Context *ctx, const unsigned char *buf, unsigned int len){
|
||||||
|
uint32 t;
|
||||||
|
|
||||||
|
/* Update bitcount */
|
||||||
|
|
||||||
|
t = ctx->bits[0];
|
||||||
|
if ((ctx->bits[0] = t + ((uint32)len << 3)) < t)
|
||||||
|
ctx->bits[1]++; /* Carry from low to high */
|
||||||
|
ctx->bits[1] += len >> 29;
|
||||||
|
|
||||||
|
t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
|
||||||
|
|
||||||
|
/* Handle any leading odd-sized chunks */
|
||||||
|
|
||||||
|
if ( t ) {
|
||||||
|
unsigned char *p = (unsigned char *)ctx->in + t;
|
||||||
|
|
||||||
|
t = 64-t;
|
||||||
|
if (len < t) {
|
||||||
|
memcpy(p, buf, len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memcpy(p, buf, t);
|
||||||
|
byteReverse(ctx->in, 16);
|
||||||
|
MD5Transform(ctx->buf, (uint32 *)ctx->in);
|
||||||
|
buf += t;
|
||||||
|
len -= t;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Process data in 64-byte chunks */
|
||||||
|
|
||||||
|
while (len >= 64) {
|
||||||
|
memcpy(ctx->in, buf, 64);
|
||||||
|
byteReverse(ctx->in, 16);
|
||||||
|
MD5Transform(ctx->buf, (uint32 *)ctx->in);
|
||||||
|
buf += 64;
|
||||||
|
len -= 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle any remaining bytes of data. */
|
||||||
|
|
||||||
|
memcpy(ctx->in, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Final wrapup - pad to 64-byte boundary with the bit pattern
|
||||||
|
* 1 0* (64-bit count of bits processed, MSB-first)
|
||||||
|
*/
|
||||||
|
static void MD5Final(unsigned char digest[16], MD5Context *ctx){
|
||||||
|
unsigned count;
|
||||||
|
unsigned char *p;
|
||||||
|
|
||||||
|
/* Compute number of bytes mod 64 */
|
||||||
|
count = (ctx->bits[0] >> 3) & 0x3F;
|
||||||
|
|
||||||
|
/* Set the first char of padding to 0x80. This is safe since there is
|
||||||
|
always at least one byte free */
|
||||||
|
p = ctx->in + count;
|
||||||
|
*p++ = 0x80;
|
||||||
|
|
||||||
|
/* Bytes of padding needed to make 64 bytes */
|
||||||
|
count = 64 - 1 - count;
|
||||||
|
|
||||||
|
/* Pad out to 56 mod 64 */
|
||||||
|
if (count < 8) {
|
||||||
|
/* Two lots of padding: Pad the first block to 64 bytes */
|
||||||
|
memset(p, 0, count);
|
||||||
|
byteReverse(ctx->in, 16);
|
||||||
|
MD5Transform(ctx->buf, (uint32 *)ctx->in);
|
||||||
|
|
||||||
|
/* Now fill the next block with 56 bytes */
|
||||||
|
memset(ctx->in, 0, 56);
|
||||||
|
} else {
|
||||||
|
/* Pad block to 56 bytes */
|
||||||
|
memset(p, 0, count-8);
|
||||||
|
}
|
||||||
|
byteReverse(ctx->in, 14);
|
||||||
|
|
||||||
|
/* Append length in bits and transform */
|
||||||
|
memcpy(ctx->in + 14*4, ctx->bits, 8);
|
||||||
|
|
||||||
|
MD5Transform(ctx->buf, (uint32 *)ctx->in);
|
||||||
|
byteReverse((unsigned char *)ctx->buf, 4);
|
||||||
|
memcpy(digest, ctx->buf, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Convert a 128-bit MD5 digest into a 32-digit base-16 number.
|
||||||
|
*/
|
||||||
|
static void MD5DigestToBase16(unsigned char *digest, char *zBuf){
|
||||||
|
static char const zEncode[] = "0123456789abcdef";
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
for(j=i=0; i<16; i++){
|
||||||
|
int a = digest[i];
|
||||||
|
zBuf[j++] = zEncode[(a>>4)&0xf];
|
||||||
|
zBuf[j++] = zEncode[a & 0xf];
|
||||||
|
}
|
||||||
|
zBuf[j] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Convert a 128-bit MD5 digest into sequency of eight 5-digit integers
|
||||||
|
** each representing 16 bits of the digest and separated from each
|
||||||
|
** other by a "-" character.
|
||||||
|
*/
|
||||||
|
static void MD5DigestToBase10x8(unsigned char digest[16], char zDigest[50]){
|
||||||
|
int i, j;
|
||||||
|
unsigned int x;
|
||||||
|
for(i=j=0; i<16; i+=2){
|
||||||
|
x = digest[i]*256 + digest[i+1];
|
||||||
|
if( i>0 ) zDigest[j++] = '-';
|
||||||
|
sqlite3_snprintf(50-j, &zDigest[j], "%05u", x);
|
||||||
|
j += 5;
|
||||||
|
}
|
||||||
|
zDigest[j] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** A TCL command for md5. The argument is the text to be hashed. The
|
||||||
|
** Result is the hash in base64.
|
||||||
|
*/
|
||||||
|
static int SQLITE_TCLAPI md5_cmd(
|
||||||
|
void*cd,
|
||||||
|
Tcl_Interp *interp,
|
||||||
|
int argc,
|
||||||
|
const char **argv
|
||||||
|
){
|
||||||
|
MD5Context ctx;
|
||||||
|
unsigned char digest[16];
|
||||||
|
char zBuf[50];
|
||||||
|
void (*converter)(unsigned char*, char*);
|
||||||
|
|
||||||
|
if( argc!=2 ){
|
||||||
|
Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
|
||||||
|
" TEXT\"", (char*)0);
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
MD5Init(&ctx);
|
||||||
|
MD5Update(&ctx, (unsigned char*)argv[1], (unsigned)strlen(argv[1]));
|
||||||
|
MD5Final(digest, &ctx);
|
||||||
|
converter = (void(*)(unsigned char*,char*))cd;
|
||||||
|
converter(digest, zBuf);
|
||||||
|
Tcl_AppendResult(interp, zBuf, (char*)0);
|
||||||
|
return TCL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** A TCL command to take the md5 hash of a file. The argument is the
|
||||||
|
** name of the file.
|
||||||
|
*/
|
||||||
|
static int SQLITE_TCLAPI md5file_cmd(
|
||||||
|
void*cd,
|
||||||
|
Tcl_Interp *interp,
|
||||||
|
int argc,
|
||||||
|
const char **argv
|
||||||
|
){
|
||||||
|
FILE *in;
|
||||||
|
int ofst;
|
||||||
|
int amt;
|
||||||
|
MD5Context ctx;
|
||||||
|
void (*converter)(unsigned char*, char*);
|
||||||
|
unsigned char digest[16];
|
||||||
|
char zBuf[10240];
|
||||||
|
|
||||||
|
if( argc!=2 && argc!=4 ){
|
||||||
|
Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
|
||||||
|
" FILENAME [OFFSET AMT]\"", (char*)0);
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
if( argc==4 ){
|
||||||
|
ofst = atoi(argv[2]);
|
||||||
|
amt = atoi(argv[3]);
|
||||||
|
}else{
|
||||||
|
ofst = 0;
|
||||||
|
amt = 2147483647;
|
||||||
|
}
|
||||||
|
in = fopen(argv[1],"rb");
|
||||||
|
if( in==0 ){
|
||||||
|
Tcl_AppendResult(interp,"unable to open file \"", argv[1],
|
||||||
|
"\" for reading", (char*)0);
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
fseek(in, ofst, SEEK_SET);
|
||||||
|
MD5Init(&ctx);
|
||||||
|
while( amt>0 ){
|
||||||
|
int n;
|
||||||
|
n = (int)fread(zBuf, 1, sizeof(zBuf)<=amt ? sizeof(zBuf) : amt, in);
|
||||||
|
if( n<=0 ) break;
|
||||||
|
MD5Update(&ctx, (unsigned char*)zBuf, (unsigned)n);
|
||||||
|
amt -= n;
|
||||||
|
}
|
||||||
|
fclose(in);
|
||||||
|
MD5Final(digest, &ctx);
|
||||||
|
converter = (void(*)(unsigned char*,char*))cd;
|
||||||
|
converter(digest, zBuf);
|
||||||
|
Tcl_AppendResult(interp, zBuf, (char*)0);
|
||||||
|
return TCL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Register the four new TCL commands for generating MD5 checksums
|
||||||
|
** with the TCL interpreter.
|
||||||
|
*/
|
||||||
|
int Md5_Init(Tcl_Interp *interp){
|
||||||
|
Tcl_CreateCommand(interp, "md5", (Tcl_CmdProc*)md5_cmd,
|
||||||
|
MD5DigestToBase16, 0);
|
||||||
|
Tcl_CreateCommand(interp, "md5-10x8", (Tcl_CmdProc*)md5_cmd,
|
||||||
|
MD5DigestToBase10x8, 0);
|
||||||
|
Tcl_CreateCommand(interp, "md5file", (Tcl_CmdProc*)md5file_cmd,
|
||||||
|
MD5DigestToBase16, 0);
|
||||||
|
Tcl_CreateCommand(interp, "md5file-10x8", (Tcl_CmdProc*)md5file_cmd,
|
||||||
|
MD5DigestToBase10x8, 0);
|
||||||
|
return TCL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** During testing, the special md5sum() aggregate function is available.
|
||||||
|
** inside SQLite. The following routines implement that function.
|
||||||
|
*/
|
||||||
|
static void md5step(sqlite3_context *context, int argc, sqlite3_value **argv){
|
||||||
|
MD5Context *p;
|
||||||
|
int i;
|
||||||
|
if( argc<1 ) return;
|
||||||
|
p = sqlite3_aggregate_context(context, sizeof(*p));
|
||||||
|
if( p==0 ) return;
|
||||||
|
if( !p->isInit ){
|
||||||
|
MD5Init(p);
|
||||||
|
}
|
||||||
|
for(i=0; i<argc; i++){
|
||||||
|
const char *zData = (char*)sqlite3_value_text(argv[i]);
|
||||||
|
if( zData ){
|
||||||
|
MD5Update(p, (unsigned char*)zData, (int)strlen(zData));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void md5finalize(sqlite3_context *context){
|
||||||
|
MD5Context *p;
|
||||||
|
unsigned char digest[16];
|
||||||
|
char zBuf[33];
|
||||||
|
p = sqlite3_aggregate_context(context, sizeof(*p));
|
||||||
|
MD5Final(digest,p);
|
||||||
|
MD5DigestToBase16(digest, zBuf);
|
||||||
|
sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
|
||||||
|
}
|
||||||
|
int Md5_Register(
|
||||||
|
sqlite3 *db,
|
||||||
|
char **pzErrMsg,
|
||||||
|
const sqlite3_api_routines *pThunk
|
||||||
|
){
|
||||||
|
int rc = sqlite3_create_function(db, "md5sum", -1, SQLITE_UTF8, 0, 0,
|
||||||
|
md5step, md5finalize);
|
||||||
|
sqlite3_overload_function(db, "md5sum", -1); /* To exercise this API */
|
||||||
|
return rc;
|
||||||
|
}
|
198
src/test_tclsh.c
Normal file
198
src/test_tclsh.c
Normal file
@@ -0,0 +1,198 @@
|
|||||||
|
/*
|
||||||
|
** 2017-10-13
|
||||||
|
**
|
||||||
|
** 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 contains extensions to the the "tclsqlite.c" module used for
|
||||||
|
** testing. Basically, all of the other "test_*.c" modules are linked
|
||||||
|
** into the enhanced tclsh used for testing (and named "testfixture" or
|
||||||
|
** "testfixture.exe") using logic encoded by this file.
|
||||||
|
**
|
||||||
|
** The code in this file used to be found in tclsqlite3.c, contained within
|
||||||
|
** #if SQLITE_TEST ... #endif. It is factored out into this separate module
|
||||||
|
** in an effort to keep the tclsqlite.c file pure.
|
||||||
|
*/
|
||||||
|
#include "sqlite3.h"
|
||||||
|
#if defined(INCLUDE_SQLITE_TCL_H)
|
||||||
|
# include "sqlite_tcl.h"
|
||||||
|
#else
|
||||||
|
# include "tcl.h"
|
||||||
|
# ifndef SQLITE_TCLAPI
|
||||||
|
# define SQLITE_TCLAPI
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Needed for the setrlimit() system call on unix */
|
||||||
|
#if defined(unix)
|
||||||
|
#include <sys/resource.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Forward declaration */
|
||||||
|
static int SQLITE_TCLAPI load_testfixture_extensions(
|
||||||
|
ClientData cd,
|
||||||
|
Tcl_Interp *interp,
|
||||||
|
int objc,
|
||||||
|
Tcl_Obj *CONST objv[]
|
||||||
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
** This routine is the primary export of this file.
|
||||||
|
**
|
||||||
|
** Configure the interpreter passed as the first argument to have access
|
||||||
|
** to the commands and linked variables that make up:
|
||||||
|
**
|
||||||
|
** * the [sqlite3] extension itself,
|
||||||
|
**
|
||||||
|
** * If SQLITE_TCLMD5 or SQLITE_TEST is defined, the Md5 commands, and
|
||||||
|
**
|
||||||
|
** * If SQLITE_TEST is set, the various test interfaces used by the Tcl
|
||||||
|
** test suite.
|
||||||
|
*/
|
||||||
|
const char *sqlite3TestInit(Tcl_Interp *interp){
|
||||||
|
extern int Sqlite3_Init(Tcl_Interp*);
|
||||||
|
extern int Sqliteconfig_Init(Tcl_Interp*);
|
||||||
|
extern int Sqlitetest1_Init(Tcl_Interp*);
|
||||||
|
extern int Sqlitetest2_Init(Tcl_Interp*);
|
||||||
|
extern int Sqlitetest3_Init(Tcl_Interp*);
|
||||||
|
extern int Sqlitetest4_Init(Tcl_Interp*);
|
||||||
|
extern int Sqlitetest5_Init(Tcl_Interp*);
|
||||||
|
extern int Sqlitetest6_Init(Tcl_Interp*);
|
||||||
|
extern int Sqlitetest7_Init(Tcl_Interp*);
|
||||||
|
extern int Sqlitetest8_Init(Tcl_Interp*);
|
||||||
|
extern int Sqlitetest9_Init(Tcl_Interp*);
|
||||||
|
extern int Sqlitetestasync_Init(Tcl_Interp*);
|
||||||
|
extern int Sqlitetest_autoext_Init(Tcl_Interp*);
|
||||||
|
extern int Sqlitetest_blob_Init(Tcl_Interp*);
|
||||||
|
extern int Sqlitetest_demovfs_Init(Tcl_Interp *);
|
||||||
|
extern int Sqlitetest_func_Init(Tcl_Interp*);
|
||||||
|
extern int Sqlitetest_hexio_Init(Tcl_Interp*);
|
||||||
|
extern int Sqlitetest_init_Init(Tcl_Interp*);
|
||||||
|
extern int Sqlitetest_malloc_Init(Tcl_Interp*);
|
||||||
|
extern int Sqlitetest_mutex_Init(Tcl_Interp*);
|
||||||
|
extern int Sqlitetestschema_Init(Tcl_Interp*);
|
||||||
|
extern int Sqlitetestsse_Init(Tcl_Interp*);
|
||||||
|
extern int Sqlitetesttclvar_Init(Tcl_Interp*);
|
||||||
|
extern int Sqlitetestfs_Init(Tcl_Interp*);
|
||||||
|
extern int SqlitetestThread_Init(Tcl_Interp*);
|
||||||
|
extern int SqlitetestOnefile_Init();
|
||||||
|
extern int SqlitetestOsinst_Init(Tcl_Interp*);
|
||||||
|
extern int Sqlitetestbackup_Init(Tcl_Interp*);
|
||||||
|
extern int Sqlitetestintarray_Init(Tcl_Interp*);
|
||||||
|
extern int Sqlitetestvfs_Init(Tcl_Interp *);
|
||||||
|
extern int Sqlitetestrtree_Init(Tcl_Interp*);
|
||||||
|
extern int Sqlitequota_Init(Tcl_Interp*);
|
||||||
|
extern int Sqlitemultiplex_Init(Tcl_Interp*);
|
||||||
|
extern int SqliteSuperlock_Init(Tcl_Interp*);
|
||||||
|
extern int SqlitetestSyscall_Init(Tcl_Interp*);
|
||||||
|
#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
|
||||||
|
extern int TestSession_Init(Tcl_Interp*);
|
||||||
|
#endif
|
||||||
|
extern int Md5_Init(Tcl_Interp*);
|
||||||
|
extern int Fts5tcl_Init(Tcl_Interp *);
|
||||||
|
extern int SqliteRbu_Init(Tcl_Interp*);
|
||||||
|
extern int Sqlitetesttcl_Init(Tcl_Interp*);
|
||||||
|
#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
|
||||||
|
extern int Sqlitetestfts3_Init(Tcl_Interp *interp);
|
||||||
|
#endif
|
||||||
|
#ifdef SQLITE_ENABLE_ZIPVFS
|
||||||
|
extern int Zipvfs_Init(Tcl_Interp*);
|
||||||
|
#endif
|
||||||
|
Tcl_CmdInfo cmdInfo;
|
||||||
|
|
||||||
|
/* Since the primary use case for this binary is testing of SQLite,
|
||||||
|
** be sure to generate core files if we crash */
|
||||||
|
#if defined(unix)
|
||||||
|
{ struct rlimit x;
|
||||||
|
getrlimit(RLIMIT_CORE, &x);
|
||||||
|
x.rlim_cur = x.rlim_max;
|
||||||
|
setrlimit(RLIMIT_CORE, &x);
|
||||||
|
}
|
||||||
|
#endif /* unix */
|
||||||
|
|
||||||
|
if( Tcl_GetCommandInfo(interp, "sqlite3", &cmdInfo)==0 ){
|
||||||
|
Sqlite3_Init(interp);
|
||||||
|
}
|
||||||
|
#ifdef SQLITE_ENABLE_ZIPVFS
|
||||||
|
Zipvfs_Init(interp);
|
||||||
|
#endif
|
||||||
|
Md5_Init(interp);
|
||||||
|
Sqliteconfig_Init(interp);
|
||||||
|
Sqlitetest1_Init(interp);
|
||||||
|
Sqlitetest2_Init(interp);
|
||||||
|
Sqlitetest3_Init(interp);
|
||||||
|
Sqlitetest4_Init(interp);
|
||||||
|
Sqlitetest5_Init(interp);
|
||||||
|
Sqlitetest6_Init(interp);
|
||||||
|
Sqlitetest7_Init(interp);
|
||||||
|
Sqlitetest8_Init(interp);
|
||||||
|
Sqlitetest9_Init(interp);
|
||||||
|
Sqlitetestasync_Init(interp);
|
||||||
|
Sqlitetest_autoext_Init(interp);
|
||||||
|
Sqlitetest_blob_Init(interp);
|
||||||
|
Sqlitetest_demovfs_Init(interp);
|
||||||
|
Sqlitetest_func_Init(interp);
|
||||||
|
Sqlitetest_hexio_Init(interp);
|
||||||
|
Sqlitetest_init_Init(interp);
|
||||||
|
Sqlitetest_malloc_Init(interp);
|
||||||
|
Sqlitetest_mutex_Init(interp);
|
||||||
|
Sqlitetestschema_Init(interp);
|
||||||
|
Sqlitetesttclvar_Init(interp);
|
||||||
|
Sqlitetestfs_Init(interp);
|
||||||
|
SqlitetestThread_Init(interp);
|
||||||
|
SqlitetestOnefile_Init();
|
||||||
|
SqlitetestOsinst_Init(interp);
|
||||||
|
Sqlitetestbackup_Init(interp);
|
||||||
|
Sqlitetestintarray_Init(interp);
|
||||||
|
Sqlitetestvfs_Init(interp);
|
||||||
|
Sqlitetestrtree_Init(interp);
|
||||||
|
Sqlitequota_Init(interp);
|
||||||
|
Sqlitemultiplex_Init(interp);
|
||||||
|
SqliteSuperlock_Init(interp);
|
||||||
|
SqlitetestSyscall_Init(interp);
|
||||||
|
#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
|
||||||
|
TestSession_Init(interp);
|
||||||
|
#endif
|
||||||
|
Fts5tcl_Init(interp);
|
||||||
|
SqliteRbu_Init(interp);
|
||||||
|
Sqlitetesttcl_Init(interp);
|
||||||
|
|
||||||
|
#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
|
||||||
|
Sqlitetestfts3_Init(interp);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Tcl_CreateObjCommand(
|
||||||
|
interp, "load_testfixture_extensions", load_testfixture_extensions,0,0
|
||||||
|
);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* tclcmd: load_testfixture_extensions
|
||||||
|
*/
|
||||||
|
static int SQLITE_TCLAPI load_testfixture_extensions(
|
||||||
|
ClientData cd,
|
||||||
|
Tcl_Interp *interp,
|
||||||
|
int objc,
|
||||||
|
Tcl_Obj *CONST objv[]
|
||||||
|
){
|
||||||
|
|
||||||
|
Tcl_Interp *slave;
|
||||||
|
if( objc!=2 ){
|
||||||
|
Tcl_WrongNumArgs(interp, 1, objv, "SLAVE");
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
slave = Tcl_GetSlave(interp, Tcl_GetString(objv[1]));
|
||||||
|
if( !slave ){
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)sqlite3TestInit(slave);
|
||||||
|
return TCL_OK;
|
||||||
|
}
|
21
src/where.c
21
src/where.c
@@ -1885,18 +1885,19 @@ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
|
|||||||
** Return TRUE if all of the following are true:
|
** Return TRUE if all of the following are true:
|
||||||
**
|
**
|
||||||
** (1) X has the same or lower cost that Y
|
** (1) X has the same or lower cost that Y
|
||||||
** (2) X is a proper subset of Y
|
** (2) X uses fewer WHERE clause terms than Y
|
||||||
** (3) X skips at least as many columns as Y
|
** (3) Every WHERE clause term used by X is also used by Y
|
||||||
**
|
** (4) X skips at least as many columns as Y
|
||||||
** By "proper subset" we mean that X uses fewer WHERE clause terms
|
** (5) If X is a covering index, than Y is too
|
||||||
** than Y and that every WHERE clause term used by X is also used
|
|
||||||
** by Y.
|
|
||||||
**
|
**
|
||||||
|
** Conditions (2) and (3) mean that X is a "proper subset" of Y.
|
||||||
** If X is a proper subset of Y then Y is a better choice and ought
|
** If X is a proper subset of Y then Y is a better choice and ought
|
||||||
** to have a lower cost. This routine returns TRUE when that cost
|
** to have a lower cost. This routine returns TRUE when that cost
|
||||||
** relationship is inverted and needs to be adjusted. The third rule
|
** relationship is inverted and needs to be adjusted. Constraint (4)
|
||||||
** was added because if X uses skip-scan less than Y it still might
|
** was added because if X uses skip-scan less than Y it still might
|
||||||
** deserve a lower cost even if it is a proper subset of Y.
|
** deserve a lower cost even if it is a proper subset of Y. Constraint (5)
|
||||||
|
** was added because a covering index probably deserves to have a lower cost
|
||||||
|
** than a non-covering index even if it is a proper subset.
|
||||||
*/
|
*/
|
||||||
static int whereLoopCheaperProperSubset(
|
static int whereLoopCheaperProperSubset(
|
||||||
const WhereLoop *pX, /* First WhereLoop to compare */
|
const WhereLoop *pX, /* First WhereLoop to compare */
|
||||||
@@ -1918,6 +1919,10 @@ static int whereLoopCheaperProperSubset(
|
|||||||
}
|
}
|
||||||
if( j<0 ) return 0; /* X not a subset of Y since term X[i] not used by Y */
|
if( j<0 ) return 0; /* X not a subset of Y since term X[i] not used by Y */
|
||||||
}
|
}
|
||||||
|
if( (pX->wsFlags&WHERE_IDX_ONLY)!=0
|
||||||
|
&& (pY->wsFlags&WHERE_IDX_ONLY)==0 ){
|
||||||
|
return 0; /* Constraint (5) */
|
||||||
|
}
|
||||||
return 1; /* All conditions meet */
|
return 1; /* All conditions meet */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1052,8 +1052,11 @@ do_execsql_test 23.0 {
|
|||||||
do_eqp_test 23.1 {
|
do_eqp_test 23.1 {
|
||||||
SELECT * FROM t4 WHERE
|
SELECT * FROM t4 WHERE
|
||||||
(e=1 AND b='xyz' AND c='zyx' AND a<'AEA') AND f<300
|
(e=1 AND b='xyz' AND c='zyx' AND a<'AEA') AND f<300
|
||||||
|
-- Formerly used index i41. But i41 is not a covering index whereas
|
||||||
|
-- the PRIMARY KEY is a covering index, and so as of 2017-10-15, the
|
||||||
|
-- PRIMARY KEY is preferred.
|
||||||
} {
|
} {
|
||||||
0 0 0 {SEARCH TABLE t4 USING INDEX i41 (e=? AND c=? AND b=? AND a<?)}
|
0 0 0 {SEARCH TABLE t4 USING PRIMARY KEY (c=? AND b=? AND a<?)}
|
||||||
}
|
}
|
||||||
do_eqp_test 23.2 {
|
do_eqp_test 23.2 {
|
||||||
SELECT * FROM t4 WHERE
|
SELECT * FROM t4 WHERE
|
||||||
|
123
test/checkfreelist.test
Normal file
123
test/checkfreelist.test
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
# 2017-10-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.
|
||||||
|
#
|
||||||
|
#***********************************************************************
|
||||||
|
# This file implements regression tests for SQLite library. The
|
||||||
|
# focus of this file is testing the checkfreelist extension.
|
||||||
|
#
|
||||||
|
|
||||||
|
set testdir [file dirname $argv0]
|
||||||
|
source $testdir/tester.tcl
|
||||||
|
set testprefix checkfreelist
|
||||||
|
|
||||||
|
ifcapable !vtab||!compound {
|
||||||
|
finish_test
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if {[file exists ../checkfreelist.so]==0} {
|
||||||
|
finish_test
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
do_execsql_test 1.0 {
|
||||||
|
CREATE TABLE t1(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
db enable_load_extension 1
|
||||||
|
do_execsql_test 1.1 {
|
||||||
|
SELECT load_extension('../checkfreelist.so');
|
||||||
|
} {{}}
|
||||||
|
|
||||||
|
do_execsql_test 1.2 { SELECT checkfreelist('main') } {ok}
|
||||||
|
do_execsql_test 1.3 {
|
||||||
|
WITH s(i) AS (
|
||||||
|
SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<10000
|
||||||
|
)
|
||||||
|
INSERT INTO t1 SELECT randomblob(400), randomblob(400) FROM s;
|
||||||
|
DELETE FROM t1 WHERE rowid%3;
|
||||||
|
PRAGMA freelist_count;
|
||||||
|
} {6726}
|
||||||
|
|
||||||
|
do_execsql_test 1.4 { SELECT checkfreelist('main') } {ok}
|
||||||
|
do_execsql_test 1.5 {
|
||||||
|
WITH freelist_trunk(i, d, n) AS (
|
||||||
|
SELECT 1, NULL, sqlite_readint32(data, 32) FROM sqlite_dbpage WHERE pgno=1
|
||||||
|
UNION ALL
|
||||||
|
SELECT n, data, sqlite_readint32(data)
|
||||||
|
FROM freelist_trunk, sqlite_dbpage WHERE pgno=n
|
||||||
|
)
|
||||||
|
SELECT i FROM freelist_trunk WHERE i!=1;
|
||||||
|
} {
|
||||||
|
10010 9716 9344 8970 8596 8223 7848 7475 7103 6728 6355 5983 5609 5235
|
||||||
|
4861 4488 4113 3741 3368 2993 2620 2248 1873 1500 1126 753 378 5
|
||||||
|
}
|
||||||
|
|
||||||
|
do_execsql_test 1.6 { SELECT checkfreelist('main') } {ok}
|
||||||
|
|
||||||
|
proc set_int {blob idx newval} {
|
||||||
|
binary scan $blob I* ints
|
||||||
|
lset ints $idx $newval
|
||||||
|
binary format I* $ints
|
||||||
|
}
|
||||||
|
db func set_int set_int
|
||||||
|
|
||||||
|
proc get_int {blob idx} {
|
||||||
|
binary scan $blob I* ints
|
||||||
|
lindex $ints $idx
|
||||||
|
}
|
||||||
|
db func get_int get_int
|
||||||
|
|
||||||
|
do_execsql_test 1.7 {
|
||||||
|
BEGIN;
|
||||||
|
UPDATE sqlite_dbpage
|
||||||
|
SET data = set_int(data, 1, get_int(data, 1)-1)
|
||||||
|
WHERE pgno=4861;
|
||||||
|
SELECT checkfreelist('main');
|
||||||
|
ROLLBACK;
|
||||||
|
} {{free-list count mismatch: actual=6725 header=6726}}
|
||||||
|
|
||||||
|
do_execsql_test 1.8 {
|
||||||
|
BEGIN;
|
||||||
|
UPDATE sqlite_dbpage
|
||||||
|
SET data = set_int(data, 5, (SELECT * FROM pragma_page_count)+1)
|
||||||
|
WHERE pgno=4861;
|
||||||
|
SELECT checkfreelist('main');
|
||||||
|
ROLLBACK;
|
||||||
|
} {{leaf page 10093 is out of range (child 3 of trunk page 4861)}}
|
||||||
|
|
||||||
|
do_execsql_test 1.9 {
|
||||||
|
BEGIN;
|
||||||
|
UPDATE sqlite_dbpage
|
||||||
|
SET data = set_int(data, 5, 0)
|
||||||
|
WHERE pgno=4861;
|
||||||
|
SELECT checkfreelist('main');
|
||||||
|
ROLLBACK;
|
||||||
|
} {{leaf page 0 is out of range (child 3 of trunk page 4861)}}
|
||||||
|
|
||||||
|
do_execsql_test 1.10 {
|
||||||
|
BEGIN;
|
||||||
|
UPDATE sqlite_dbpage
|
||||||
|
SET data = set_int(data, get_int(data, 1)+1, 0)
|
||||||
|
WHERE pgno=5;
|
||||||
|
SELECT checkfreelist('main');
|
||||||
|
ROLLBACK;
|
||||||
|
} {{leaf page 0 is out of range (child 247 of trunk page 5)}}
|
||||||
|
|
||||||
|
do_execsql_test 1.11 {
|
||||||
|
BEGIN;
|
||||||
|
UPDATE sqlite_dbpage
|
||||||
|
SET data = set_int(data, 1, 249)
|
||||||
|
WHERE pgno=5;
|
||||||
|
SELECT checkfreelist('main');
|
||||||
|
ROLLBACK;
|
||||||
|
} {{leaf count out of range (249) on trunk page 5}}
|
||||||
|
|
||||||
|
finish_test
|
||||||
|
|
@@ -107,6 +107,115 @@ do_catchsql_test 2.3 {
|
|||||||
INSERT INTO t1 VALUES(randomblob(900));
|
INSERT INTO t1 VALUES(randomblob(900));
|
||||||
} {1 {database disk image is malformed}}
|
} {1 {database disk image is malformed}}
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
proc hex2blob {hex} {
|
||||||
|
# Split on newlines:
|
||||||
|
set bytes [list]
|
||||||
|
foreach l [split $hex "\n"] {
|
||||||
|
if {[string is space $l]} continue
|
||||||
|
set L [list]
|
||||||
|
foreach b [split $l] {
|
||||||
|
if {[string is xdigit $b] && [string length $b]==2} {
|
||||||
|
lappend L [expr "0x$b"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if {[llength $L]!=16} {
|
||||||
|
error "Badly formed hex (1)"
|
||||||
|
}
|
||||||
|
set bytes [concat $bytes $L]
|
||||||
|
}
|
||||||
|
|
||||||
|
binary format c* $bytes
|
||||||
|
}
|
||||||
|
|
||||||
|
reset_db
|
||||||
|
db func hex2blob hex2blob
|
||||||
|
|
||||||
|
do_execsql_test 3.1 {
|
||||||
|
PRAGMA page_size=1024;
|
||||||
|
CREATE TABLE t1(a, b, c);
|
||||||
|
CREATE TABLE t2(a, b, c);
|
||||||
|
CREATE TABLE t3(a, b, c);
|
||||||
|
CREATE TABLE t4(a, b, c);
|
||||||
|
CREATE TABLE t5(a, b, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
do_execsql_test 3.2 {
|
||||||
|
UPDATE sqlite_dbpage SET data = hex2blob('
|
||||||
|
000: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
|
||||||
|
010: 04 00 01 01 20 40 20 20 00 00 3e d9 00 00 00 06 .... @ ..>.....
|
||||||
|
020: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04 ................
|
||||||
|
030: 0f 00 00 00 00 00 00 00 00 00 00 01 00 00 83 00 ................
|
||||||
|
040: 00 00 00 00 00 00 00 00 00 00 00 00 00 38 00 00 .............8..
|
||||||
|
050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3e d9 ..............>.
|
||||||
|
060: 00 2d e6 07 0d 00 00 00 01 03 a0 00 03 e0 00 00 .-..............
|
||||||
|
070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
0a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
0b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
0c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
0d0: 00 00 00 00 00 c1 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
0e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
0f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
160: 00 83 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
180: 00 00 00 00 00 00 00 00 00 00 07 00 30 00 00 00 ............0...
|
||||||
|
190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
1a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
1b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
1c0: 02 00 00 00 00 00 00 00 00 00 00 02 00 00 00 00 ................
|
||||||
|
1d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
1e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
1f0: 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
220: 00 00 0e 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
230: 0c 00 00 00 00 00 00 60 00 00 00 06 00 00 c3 00 .......`........
|
||||||
|
240: 00 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
250: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
270: 00 00 00 18 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
290: 04 00 0e 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
2a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
2b0: 00 00 00 00 83 00 8c 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
2c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
2d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
2e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
2f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
310: 00 78 00 00 00 00 00 00 00 00 00 00 00 00 70 00 .x............p.
|
||||||
|
320: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
330: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
340: 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
350: 00 00 00 00 00 68 00 00 00 00 00 00 00 00 00 00 .....h..........
|
||||||
|
360: 00 00 00 00 00 03 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
370: 00 00 00 00 00 00 00 00 00 00 00 00 00 08 00 00 ................
|
||||||
|
380: 00 00 00 00 70 00 00 00 00 00 00 00 00 00 00 00 ....p...........
|
||||||
|
390: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||||
|
3a0: 5e 01 07 17 1b 1b 01 81 13 74 61 62 6c 65 73 65 ^........tablese
|
||||||
|
3b0: 6e 73 6f 32 73 73 65 6e 73 6f 72 73 02 43 52 45 nso2ssensors.CRE
|
||||||
|
3c0: 41 54 45 20 54 41 42 4c 45 20 73 65 6e 73 6f 72 ATE TABLE sensor
|
||||||
|
3d0: 73 20 0a 20 20 24 20 20 20 20 20 20 20 20 20 20 s . $
|
||||||
|
3e0: b8 6e 61 6d 65 21 74 65 78 74 2c 20 79 61 6c 20 .name!text, yal
|
||||||
|
3f0: 72 65 61 6c 2c 20 74 69 6d 65 20 74 65 78 74 29 real, time text)
|
||||||
|
') WHERE pgno=1
|
||||||
|
}
|
||||||
|
|
||||||
|
db close
|
||||||
|
sqlite3 db test.db
|
||||||
|
|
||||||
|
do_catchsql_test 3.3 {
|
||||||
|
PRAGMA integrity_check;
|
||||||
|
} {1 {database disk image is malformed}}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
69
test/dbpage.test
Normal file
69
test/dbpage.test
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
# 2017-10-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.
|
||||||
|
#
|
||||||
|
#***********************************************************************
|
||||||
|
# This file implements regression tests for SQLite library. The
|
||||||
|
# focus of this file is testing the sqlite_dbpage virtual table.
|
||||||
|
#
|
||||||
|
|
||||||
|
set testdir [file dirname $argv0]
|
||||||
|
source $testdir/tester.tcl
|
||||||
|
set testprefix dbpage
|
||||||
|
|
||||||
|
ifcapable !vtab||!compound {
|
||||||
|
finish_test
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
do_execsql_test 100 {
|
||||||
|
PRAGMA page_size=4096;
|
||||||
|
PRAGMA journal_mode=WAL;
|
||||||
|
CREATE TABLE t1(a,b);
|
||||||
|
WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100)
|
||||||
|
INSERT INTO t1(a,b) SELECT x, printf('%d-x%.*c',x,x,'x') FROM c;
|
||||||
|
PRAGMA integrity_check;
|
||||||
|
} {wal ok}
|
||||||
|
do_execsql_test 110 {
|
||||||
|
SELECT pgno, quote(substr(data,1,5)) FROM sqlite_dbpage('main') ORDER BY pgno;
|
||||||
|
} {1 X'53514C6974' 2 X'0500000001' 3 X'0D0000004E' 4 X'0D00000016'}
|
||||||
|
do_execsql_test 120 {
|
||||||
|
SELECT pgno, quote(substr(data,1,5)) FROM sqlite_dbpage WHERE pgno=2;
|
||||||
|
} {2 X'0500000001'}
|
||||||
|
do_execsql_test 130 {
|
||||||
|
SELECT pgno, quote(substr(data,1,5)) FROM sqlite_dbpage WHERE pgno=4;
|
||||||
|
} {4 X'0D00000016'}
|
||||||
|
do_execsql_test 140 {
|
||||||
|
SELECT pgno, quote(substr(data,1,5)) FROM sqlite_dbpage WHERE pgno=5;
|
||||||
|
} {}
|
||||||
|
do_execsql_test 150 {
|
||||||
|
SELECT pgno, quote(substr(data,1,5)) FROM sqlite_dbpage WHERE pgno=0;
|
||||||
|
} {}
|
||||||
|
|
||||||
|
do_execsql_test 200 {
|
||||||
|
CREATE TEMP TABLE saved_content(x);
|
||||||
|
INSERT INTO saved_content(x) SELECT data FROM sqlite_dbpage WHERE pgno=4;
|
||||||
|
UPDATE sqlite_dbpage SET data=zeroblob(4096) WHERE pgno=4;
|
||||||
|
} {}
|
||||||
|
do_catchsql_test 210 {
|
||||||
|
PRAGMA integrity_check;
|
||||||
|
} {1 {database disk image is malformed}}
|
||||||
|
do_execsql_test 220 {
|
||||||
|
SELECT pgno, quote(substr(data,1,5)) FROM sqlite_dbpage('main') ORDER BY pgno;
|
||||||
|
} {1 X'53514C6974' 2 X'0500000001' 3 X'0D0000004E' 4 X'0000000000'}
|
||||||
|
do_execsql_test 230 {
|
||||||
|
UPDATE sqlite_dbpage SET data=(SELECT x FROM saved_content) WHERE pgno=4;
|
||||||
|
} {}
|
||||||
|
do_catchsql_test 230 {
|
||||||
|
PRAGMA integrity_check;
|
||||||
|
} {0 ok}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
finish_test
|
@@ -194,7 +194,7 @@ test_suite "valgrind" -prefix "" -description {
|
|||||||
} -files [
|
} -files [
|
||||||
test_set $allquicktests -exclude *malloc* *ioerr* *fault* *_err* wal.test \
|
test_set $allquicktests -exclude *malloc* *ioerr* *fault* *_err* wal.test \
|
||||||
shell*.test crash8.test atof1.test selectG.test \
|
shell*.test crash8.test atof1.test selectG.test \
|
||||||
tkt-fc62af4523.test numindex1.test
|
tkt-fc62af4523.test numindex1.test corruptK.test
|
||||||
] -initialize {
|
] -initialize {
|
||||||
set ::G(valgrind) 1
|
set ::G(valgrind) 1
|
||||||
} -shutdown {
|
} -shutdown {
|
||||||
@@ -1065,7 +1065,7 @@ test_suite "no_optimization" -description {
|
|||||||
test_suite "prepare" -description {
|
test_suite "prepare" -description {
|
||||||
Run tests with the db connection using sqlite3_prepare() instead of _v2().
|
Run tests with the db connection using sqlite3_prepare() instead of _v2().
|
||||||
} -dbconfig {
|
} -dbconfig {
|
||||||
db_use_legacy_prepare $::dbhandle 1
|
$::dbhandle version -use-legacy-prepare 1
|
||||||
#$::dbhandle cache size 0
|
#$::dbhandle cache size 0
|
||||||
} -files [
|
} -files [
|
||||||
test_set $allquicktests -exclude *malloc* *ioerr* *fault* \
|
test_set $allquicktests -exclude *malloc* *ioerr* *fault* \
|
||||||
|
@@ -30,7 +30,7 @@ do_execsql_test 1.0 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
proc do_scanstatus_test {tn res} {
|
proc do_scanstatus_test {tn res} {
|
||||||
set stmt [db_last_stmt_ptr db]
|
set stmt [db version -last-stmt-ptr]
|
||||||
set idx 0
|
set idx 0
|
||||||
set ret [list]
|
set ret [list]
|
||||||
while {1} {
|
while {1} {
|
||||||
@@ -79,7 +79,7 @@ do_scanstatus_test 1.9 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
do_test 1.9 {
|
do_test 1.9 {
|
||||||
sqlite3_stmt_scanstatus_reset [db_last_stmt_ptr db]
|
sqlite3_stmt_scanstatus_reset [db version -last-stmt-ptr]
|
||||||
} {}
|
} {}
|
||||||
|
|
||||||
do_scanstatus_test 1.10 {
|
do_scanstatus_test 1.10 {
|
||||||
|
93
tool/mkccode.tcl
Executable file
93
tool/mkccode.tcl
Executable file
@@ -0,0 +1,93 @@
|
|||||||
|
#!/usr/bin/tclsh
|
||||||
|
#
|
||||||
|
# Use this script to build C-language source code for a program that uses
|
||||||
|
# tclsqlite.c together with custom TCL scripts and/or C extensions for
|
||||||
|
# either SQLite or TCL.
|
||||||
|
#
|
||||||
|
# Usage example:
|
||||||
|
#
|
||||||
|
# tclsh mktclsqliteprog.tcl demoapp.c.in >demoapp.c
|
||||||
|
#
|
||||||
|
# The demoapp.c.in file contains a mixture of C code, TCL script, and
|
||||||
|
# processing directives used by mktclsqliteprog.tcl to build the final C-code
|
||||||
|
# output file. Most lines of demoapp.c.in are copied straight through into
|
||||||
|
# the output. The following control directives are recognized:
|
||||||
|
#
|
||||||
|
# BEGIN_STRING
|
||||||
|
#
|
||||||
|
# This marks the beginning of large string literal - usually a TCL
|
||||||
|
# script of some kind. Subsequent lines of text through the first
|
||||||
|
# line that begins with END_STRING are converted into a C-language
|
||||||
|
# string literal.
|
||||||
|
#
|
||||||
|
# INCLUDE path
|
||||||
|
#
|
||||||
|
# The path argument is the name of a file to be inserted in place of
|
||||||
|
# the INCLUDE line. The path can begin with $ROOT to signify the
|
||||||
|
# root of the SQLite source tree, or $HOME to signify the directory
|
||||||
|
# that contains the demoapp.c.in input script itself. If the path does
|
||||||
|
# not begin with either $ROOT or $HOME, then it is interpreted relative
|
||||||
|
# to the current working directory.
|
||||||
|
#
|
||||||
|
# If the INCLUDE occurs in the middle of BEGIN_STRING...END_STRING
|
||||||
|
# then all of the text in the input file is converted into C-language
|
||||||
|
# string literals.
|
||||||
|
#
|
||||||
|
# None of the control directives described above will nest. Only the
|
||||||
|
# top-level input file ("demoapp.c.in" in the example) is interpreted.
|
||||||
|
# referenced files are copied verbatim.
|
||||||
|
#
|
||||||
|
if {[llength $argv]!=1} {
|
||||||
|
puts stderr "Usage: $argv0 TEMPLATE >OUTPUT"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
set infile [lindex $argv 0]
|
||||||
|
set ROOT [file normalize [file dir $argv0]/..]
|
||||||
|
set HOME [file normalize [file dir $infile]]
|
||||||
|
set in [open $infile rb]
|
||||||
|
puts [subst {/* DO NOT EDIT
|
||||||
|
**
|
||||||
|
** This file was generated by \"$argv0 $infile\".
|
||||||
|
** To make changes, edit $infile then rerun the generator
|
||||||
|
** command.
|
||||||
|
*/}]
|
||||||
|
set instr 0
|
||||||
|
while {1} {
|
||||||
|
set line [gets $in]
|
||||||
|
if {[eof $in]} break
|
||||||
|
if {[regexp {^INCLUDE (.*)} $line all path]} {
|
||||||
|
regsub {^\$ROOT\y} $path $ROOT path
|
||||||
|
regsub {^\$HOME\y} $path $HOME path
|
||||||
|
set in2 [open $path rb]
|
||||||
|
puts "/* INCLUDE $path */"
|
||||||
|
if {$instr} {
|
||||||
|
while {1} {
|
||||||
|
set line [gets $in2]
|
||||||
|
if {[eof $in2]} break
|
||||||
|
set x [string map "\\\\ \\\\\\\\ \\\" \\\\\"" $line]
|
||||||
|
puts "\"$x\\n\""
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
puts [read $in2]
|
||||||
|
}
|
||||||
|
puts "/* END $path */"
|
||||||
|
close $in2
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if {[regexp {^BEGIN_STRING} $line]} {
|
||||||
|
set instr 1
|
||||||
|
puts "/* BEGIN_STRING */"
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if {[regexp {^END_STRING} $line]} {
|
||||||
|
set instr 0
|
||||||
|
puts "/* END_STRING */"
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if {$instr} {
|
||||||
|
set x [string map "\\\\ \\\\\\\\ \\\" \\\\\"" $line]
|
||||||
|
puts "\"$x\\n\""
|
||||||
|
} else {
|
||||||
|
puts $line
|
||||||
|
}
|
||||||
|
}
|
@@ -394,6 +394,7 @@ foreach file {
|
|||||||
fts3_icu.c
|
fts3_icu.c
|
||||||
sqlite3rbu.c
|
sqlite3rbu.c
|
||||||
dbstat.c
|
dbstat.c
|
||||||
|
dbpage.c
|
||||||
sqlite3session.c
|
sqlite3session.c
|
||||||
json1.c
|
json1.c
|
||||||
fts5.c
|
fts5.c
|
||||||
|
@@ -15,6 +15,7 @@ set END {^/\*+ End of %s \*+/}
|
|||||||
|
|
||||||
set in [open sqlite3.c]
|
set in [open sqlite3.c]
|
||||||
set out1 [open sqlite3-all.c w]
|
set out1 [open sqlite3-all.c w]
|
||||||
|
fconfigure $out1 -translation lf
|
||||||
|
|
||||||
# Copy the header from sqlite3.c into sqlite3-all.c
|
# Copy the header from sqlite3.c into sqlite3-all.c
|
||||||
#
|
#
|
||||||
@@ -48,6 +49,7 @@ proc write_one_file {content} {
|
|||||||
global filecnt
|
global filecnt
|
||||||
incr filecnt
|
incr filecnt
|
||||||
set out [open sqlite3-$filecnt.c w]
|
set out [open sqlite3-$filecnt.c w]
|
||||||
|
fconfigure $out -translation lf
|
||||||
puts -nonewline $out $content
|
puts -nonewline $out $content
|
||||||
close $out
|
close $out
|
||||||
puts $::out1 "#include \"sqlite3-$filecnt.c\""
|
puts $::out1 "#include \"sqlite3-$filecnt.c\""
|
||||||
|
27
tool/sqlite3_analyzer.c.in
Normal file
27
tool/sqlite3_analyzer.c.in
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
** Read an SQLite database file and analyze its space utilization. Generate
|
||||||
|
** text on standard output.
|
||||||
|
*/
|
||||||
|
#define TCLSH_INIT_PROC sqlite3_analyzer_init_proc
|
||||||
|
#define SQLITE_ENABLE_DBSTAT_VTAB 1
|
||||||
|
#undef SQLITE_THREADSAFE
|
||||||
|
#define SQLITE_THREADSAFE 0
|
||||||
|
#undef SQLITE_ENABLE_COLUMN_METADATA
|
||||||
|
#define SQLITE_OMIT_DECLTYPE 1
|
||||||
|
#define SQLITE_OMIT_DEPRECATED 1
|
||||||
|
#define SQLITE_OMIT_PROGRESS_CALLBACK 1
|
||||||
|
#define SQLITE_OMIT_SHARED_CACHE 1
|
||||||
|
#define SQLITE_DEFAULT_MEMSTATUS 0
|
||||||
|
#define SQLITE_MAX_EXPR_DEPTH 0
|
||||||
|
#define SQLITE_OMIT_LOAD_EXTENSION 1
|
||||||
|
INCLUDE sqlite3.c
|
||||||
|
INCLUDE $ROOT/src/tclsqlite.c
|
||||||
|
|
||||||
|
const char *sqlite3_analyzer_init_proc(Tcl_Interp *interp){
|
||||||
|
(void)interp;
|
||||||
|
return
|
||||||
|
BEGIN_STRING
|
||||||
|
INCLUDE $ROOT/tool/spaceanal.tcl
|
||||||
|
END_STRING
|
||||||
|
;
|
||||||
|
}
|
@@ -1,12 +0,0 @@
|
|||||||
#!/usr/bin/tcl
|
|
||||||
#
|
|
||||||
# Convert input text into a C string
|
|
||||||
#
|
|
||||||
set in [open [lindex $argv 0] rb]
|
|
||||||
while {![eof $in]} {
|
|
||||||
set line [gets $in]
|
|
||||||
if {[eof $in]} break;
|
|
||||||
set x [string map "\\\\ \\\\\\\\ \\\" \\\\\"" $line]
|
|
||||||
puts "\"$x\\n\""
|
|
||||||
}
|
|
||||||
close $in
|
|
Reference in New Issue
Block a user