Compare commits
340 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c5b674231a | |||
| 8eebf02f53 | |||
| a8914faaaa | |||
| aa0325872f | |||
| 4aff119f3a | |||
| 5f26e00761 | |||
| e604ec0be0 | |||
| 2409f8a112 | |||
| d93ba6271b | |||
| 1563c7a4d5 | |||
| 2900a6222f | |||
| 6f7087211c | |||
| 9d60875901 | |||
| 426f4ab009 | |||
| 68cd37c10f | |||
| 9e89b957ef | |||
| 2b62b5def8 | |||
| 07d9a03187 | |||
| 114f5744d4 | |||
| ebbee40a8f | |||
| 422dded5a9 | |||
| a522473c65 | |||
| 017256802b | |||
| 2aed979592 | |||
| 26fe413be6 | |||
| 5d513ba08c | |||
| 6fe4c184fb | |||
| 26197d1b62 | |||
| c530b9c65b | |||
| 5fe63bfb93 | |||
| bd441f7700 | |||
| 087ec072ef | |||
| 4b363a5130 | |||
| 2ce26ff10a | |||
| eb09f6d788 | |||
| 49dcd79e7d | |||
| 194c21de34 | |||
| 8afffe7244 | |||
| 557341e8fa | |||
| cf1e395acb | |||
| a4c07346b7 | |||
| 80f2b33a12 | |||
| 9a8b9ec51c | |||
| dec8bc0eb4 | |||
| 12ca5ac3d2 | |||
| 033ac6af7e | |||
| 89441bf185 | |||
| 8414e81359 | |||
| 8d85364261 | |||
| 0e15d921d9 | |||
| eb5a549ecf | |||
| de6fde6af6 | |||
| 283a85ca21 | |||
| 170e998236 | |||
| a8f286a38a | |||
| e2f84b403c | |||
| b52dcd8989 | |||
| b56660f5a4 | |||
| 0b4c042b86 | |||
| 86396219a3 | |||
| 0129a54a16 | |||
| c0e2203adb | |||
| fca760c841 | |||
| 1637a5171f | |||
| 3d2a529df6 | |||
| ed916ba025 | |||
| a0620acc4a | |||
| ce0442edf3 | |||
| dd703e22a5 | |||
| e234cfd11f | |||
| e39cd91aea | |||
| a912348a19 | |||
| 11499f0ab4 | |||
| 43f58d6a17 | |||
| c2024c4ef2 | |||
| 1e75483cf0 | |||
| d3d4b3c698 | |||
| 5225449e5b | |||
| c8dcdff37e | |||
| 9c10608a26 | |||
| dc7b7385c9 | |||
| 272989b44d | |||
| 50687436f7 | |||
| e0a6e0fda0 | |||
| 240c7faf8b | |||
| 2e993288e6 | |||
| 9697308f44 | |||
| 2e3f87ae84 | |||
| ba637157ca | |||
| 2519b2a3e5 | |||
| 9de4757c9c | |||
| 5fbab882c0 | |||
| 7c95696e5c | |||
| 883486bada | |||
| e336b8914c | |||
| 2d05331444 | |||
| 64131c15ab | |||
| 4841624ab9 | |||
| a2fbe3bec6 | |||
| 05d1bad674 | |||
| 4b37cd49a6 | |||
| f5fe00399f | |||
| be11ade7cf | |||
| b10ab53f3a | |||
| ec5935924d | |||
| 9c987a833c | |||
| ee84b0f690 | |||
| 2b693d63e4 | |||
| e6912fd819 | |||
| c497441406 | |||
| 419b03c1bb | |||
| b324cf756e | |||
| 2ad96f5880 | |||
| 3480bfdae9 | |||
| 6b92288119 | |||
| 9d32b7b042 | |||
| c14566aff3 | |||
| 6c0e41b951 | |||
| debaa86c1c | |||
| edc4024b9d | |||
| 4d249e6128 | |||
| 8dc570b6af | |||
| b9f3f6b672 | |||
| 74a7ef79f7 | |||
| 469077596f | |||
| 88b69f3fb5 | |||
| 04600b249f | |||
| adb9636887 | |||
| 9fc3d1cfa7 | |||
| 2b78c0d38b | |||
| cb9e7a56af | |||
| 101f557a23 | |||
| e5a060474a | |||
| a14dfe465c | |||
| ce08336c43 | |||
| 72f0d40ac4 | |||
| 0ecefeb10b | |||
| 2a73755f4e | |||
| 7991137311 | |||
| 3db53ff77b | |||
| 04393bb585 | |||
| 2911e6c570 | |||
| 07a6166f23 | |||
| 93e52b35cc | |||
| 4f25847dbd | |||
| 62c831d829 | |||
| 241014c3f1 | |||
| 264b78a7b0 | |||
| 7aecd9ac20 | |||
| d774536f52 | |||
| 1158cd750f | |||
| 81ab26904b | |||
| 26bb3b2148 | |||
| e2fe1a59b7 | |||
| afd6cf1041 | |||
| f45491a09c | |||
| a0fafa1dee | |||
| 6a09a46b10 | |||
| 4a42d8faf2 | |||
| 68b203fe4e | |||
| 59158c25cb | |||
| b8a08d1237 | |||
| 9beb8702e8 | |||
| 6684c44a4c | |||
| bee873abcc | |||
| 961c98618d | |||
| 738394c069 | |||
| 51b021eb64 | |||
| 00c43a4a3b | |||
| a297dbb897 | |||
| 8e11f8aec5 | |||
| f035e3ce68 | |||
| 532676f142 | |||
| 7c5113fc3b | |||
| 9827122af5 | |||
| 7712ac43e8 | |||
| 99a9edc64a | |||
| 36813e51a6 | |||
| cbce710443 | |||
| 5be04de862 | |||
| 296145ff14 | |||
| 3fa3114310 | |||
| e8c1a641b1 | |||
| 05a43c305f | |||
| 557437fd51 | |||
| 471a717ccb | |||
| b13cc88cd3 | |||
| 2f1fbb5a88 | |||
| fa95fecd1a | |||
| aefbdc97bd | |||
| 5817b2a18e | |||
| 4feacdeb25 | |||
| 201959c95d | |||
| 0a175660d2 | |||
| 03f275ea83 | |||
| f6aade2b1e | |||
| b8963868c9 | |||
| 3f73784941 | |||
| 77cb4f3bf5 | |||
| a3b2856ca5 | |||
| 11a6d52005 | |||
| e4172fa884 | |||
| 79e319ef93 | |||
| 38f940254a | |||
| 417f98ddc9 | |||
| 7151722191 | |||
| 1dc14f78f0 | |||
| 6f34c36a39 | |||
| 5a3d6b1a39 | |||
| 5d5a49d8da | |||
| f6f002a3bb | |||
| 81f89ae38c | |||
| 6d88f0f145 | |||
| 4cfde6344b | |||
| 4a92cb5619 | |||
| 52c5d76673 | |||
| dde37a1cb0 | |||
| 9cc5985bc4 | |||
| edb586616b | |||
| 1c68302a1a | |||
| 3f45cf5900 | |||
| 72ab0c824d | |||
| fd855ec1e9 | |||
| c0c290d4f6 | |||
| 7a00b6c815 | |||
| 31447e8b01 | |||
| 59967e2d2e | |||
| acf5e9d692 | |||
| ef39ae556c | |||
| d419d42238 | |||
| d6edcca767 | |||
| 8a9a68e2ae | |||
| b33a4fdffe | |||
| 35d09b26e2 | |||
| b9f41b4fd1 | |||
| e1436049d8 | |||
| 4e76b64969 | |||
| 78fffbf2c2 | |||
| 3314d12e03 | |||
| b2eb39ea15 | |||
| 1489c18b99 | |||
| 3aed0eb475 | |||
| ba1bce386c | |||
| 8f0e4e2a9c | |||
| 8a1c468c3c | |||
| 29b2fb1c52 | |||
| 8749d1c8e6 | |||
| fc73c50fec | |||
| 5fbe8d658f | |||
| 02d2493753 | |||
| edd972a2ed | |||
| 42b4259a4a | |||
| 8343a6bf5e | |||
| 4678255c4e | |||
| 0cb33b650c | |||
| 9817307d2f | |||
| 296c8cad4d | |||
| 40d50d1b0f | |||
| 2f1e7b8a74 | |||
| e0ba85df8b | |||
| 39ab1aef89 | |||
| 90defefb85 | |||
| 48249a7397 | |||
| ffa0ae9924 | |||
| 495cd6b419 | |||
| 7d59b89dc9 | |||
| aa09d0503d | |||
| 3a0022dad4 | |||
| 0d92f761ed | |||
| cc40f4ceb1 | |||
| aec336af26 | |||
| d74c576ee6 | |||
| 65f0fd40d6 | |||
| f9ae91deed | |||
| 8062d660f1 | |||
| b19e7036cd | |||
| 253df3a264 | |||
| 343811ce13 | |||
| 1b1b8325e1 | |||
| 027200ec51 | |||
| d819aea05f | |||
| e96ab66f34 | |||
| 2e4491d4b1 | |||
| 1b2327c509 | |||
| 66f6ad7b94 | |||
| b5f87f4394 | |||
| fbea85d6cd | |||
| b09945e64c | |||
| c3835e0208 | |||
| d736884f3d | |||
| 283f9e7ee6 | |||
| fa64665a49 | |||
| e127a2ea9f | |||
| 5be1b1f262 | |||
| 25d2380356 | |||
| 69d67f5412 | |||
| 6f7fe3ef3e | |||
| e3a4e11bcc | |||
| 67d225da53 | |||
| 5a5ced7da9 | |||
| 985be1bce6 | |||
| 99f24349ea | |||
| 890b69fb83 | |||
| f5d6f1e0c5 | |||
| 5ec0cfe070 | |||
| 3b3b1a538d | |||
| b0fa210aa3 | |||
| 801829c812 | |||
| 9b3c15e860 | |||
| 61d3bfb78b | |||
| 45d55a254b | |||
| 51e5db70b6 | |||
| f219bba933 | |||
| a0166e1873 | |||
| aff0449d8f | |||
| c55e9b815f | |||
| 03ba419b3c | |||
| c4098a3d9f | |||
| 21ce77989a | |||
| 91973abb4b | |||
| 722db051c6 | |||
| 87dd60cd8d | |||
| 7244fdc446 | |||
| 4f7e8fcded | |||
| 95063a5774 | |||
| ad7c2a87f5 | |||
| cc3ec7cb2b | |||
| 3942b4b147 | |||
| 9aa0012a08 | |||
| efd8e3b33d | |||
| 0b90b2209f | |||
| 9782039bde | |||
| 332aa832ce | |||
| bf4cad1e4c | |||
| b0c5edcd06 | |||
| 2250799f0c | |||
| ca071dfd75 | |||
| ac0c39980a | |||
| 04d4227255 | |||
| e6c3c72c1b |
+36
-20
@@ -63,7 +63,7 @@ LIBREADLINE = @TARGET_READLINE_LIBS@
|
||||
|
||||
# Should the database engine be compiled threadsafe
|
||||
#
|
||||
TCC += -DSQLITE_THREADSAFE=@SQLITE_THREADSAFE@
|
||||
#TCC += -DSQLITE_THREADSAFE=@SQLITE_THREADSAFE@
|
||||
|
||||
# Any target libraries which libsqlite must be linked against
|
||||
#
|
||||
@@ -114,7 +114,7 @@ TCLSH_CMD = @TCLSH_CMD@
|
||||
|
||||
# Where do we want to install the tcl plugin
|
||||
#
|
||||
TCLLIBDIR = @TCLLIBDIR@
|
||||
TCLLIBDIR = /System/Library/Tcl
|
||||
|
||||
# The suffix used on shared libraries. Ex: ".dll", ".so", ".dylib"
|
||||
#
|
||||
@@ -343,6 +343,9 @@ SRC += \
|
||||
SRC += \
|
||||
$(TOP)/ext/rtree/rtree.h \
|
||||
$(TOP)/ext/rtree/rtree.c
|
||||
SRC += \
|
||||
$(TOP)/ext/sqlrr/sqlrr.h \
|
||||
$(TOP)/ext/sqlrr/sqlrr.c
|
||||
SRC += \
|
||||
$(TOP)/ext/session/sqlite3session.c \
|
||||
$(TOP)/ext/session/sqlite3session.h
|
||||
@@ -416,6 +419,7 @@ TESTSRC = \
|
||||
#
|
||||
TESTSRC += \
|
||||
$(TOP)/ext/misc/amatch.c \
|
||||
$(TOP)/ext/misc/carray.c \
|
||||
$(TOP)/ext/misc/closure.c \
|
||||
$(TOP)/ext/misc/csv.c \
|
||||
$(TOP)/ext/misc/eval.c \
|
||||
@@ -532,6 +536,17 @@ EXTHDR += \
|
||||
$(TOP)/ext/icu/sqliteicu.h
|
||||
EXTHDR += \
|
||||
$(TOP)/ext/rtree/sqlite3rtree.h
|
||||
EXTHDR += \
|
||||
$(TOP)/ext/sqlrr/sqlrr.h
|
||||
|
||||
# If using the amalgamation, use sqlite3.c directly to build the test
|
||||
# fixture. Otherwise link against libsqlite3.la. (This distinction is
|
||||
# necessary because the test fixture requires non-API symbols which are
|
||||
# hidden when the library is built via the amalgamation).
|
||||
#
|
||||
TESTFIXTURE_SRC0 = $(TESTSRC2) libsqlite3.la
|
||||
TESTFIXTURE_SRC1 = sqlite3.c
|
||||
TESTFIXTURE_SRC = $(TESTSRC) $(TOP)/src/tclsqlite.c $(TESTFIXTURE_SRC$(USE_AMALGAMATION))
|
||||
|
||||
# executables needed for testing
|
||||
#
|
||||
@@ -557,7 +572,9 @@ TESTOPTS = --verbose=file --output=test-out.txt
|
||||
# Extra compiler options for various shell tools
|
||||
#
|
||||
SHELL_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4
|
||||
# SHELL_OPT += -DSQLITE_ENABLE_FTS5
|
||||
SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
|
||||
SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
|
||||
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
|
||||
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
|
||||
|
||||
@@ -579,24 +596,23 @@ libsqlite3.la: $(LIBOBJ)
|
||||
libtclsqlite3.la: tclsqlite.lo libsqlite3.la
|
||||
$(LTLINK) -no-undefined -o $@ tclsqlite.lo \
|
||||
libsqlite3.la @TCL_STUB_LIB_SPEC@ $(TLIBS) \
|
||||
-rpath "$(TCLLIBDIR)" \
|
||||
-version-info "8:6:8" \
|
||||
-avoid-version
|
||||
-rpath "$(TCLLIBDIR)/sqlite3" \
|
||||
-version-info "8:6:8"
|
||||
|
||||
sqlite3$(TEXE): $(TOP)/src/shell.c sqlite3.c
|
||||
$(LTLINK) $(READLINE_FLAGS) $(SHELL_OPT) -o $@ \
|
||||
$(TOP)/src/shell.c sqlite3.c \
|
||||
$(LIBREADLINE) $(TLIBS) -rpath "$(libdir)"
|
||||
|
||||
sqldiff$(TEXE): $(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h
|
||||
$(LTLINK) -o $@ $(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS)
|
||||
sqldiff$(TEXE): $(TOP)/tool/sqldiff.c sqlite3.lo sqlite3.h
|
||||
$(LTLINK) -o $@ $(TOP)/tool/sqldiff.c sqlite3.lo $(TLIBS)
|
||||
|
||||
dbhash$(TEXE): $(TOP)/tool/dbhash.c sqlite3.c sqlite3.h
|
||||
$(LTLINK) -o $@ $(TOP)/tool/dbhash.c sqlite3.c $(TLIBS)
|
||||
dbhash$(TEXE): $(TOP)/tool/dbhash.c sqlite3.lo sqlite3.h
|
||||
$(LTLINK) -o $@ $(TOP)/tool/dbhash.c sqlite3.lo $(TLIBS)
|
||||
|
||||
scrub$(TEXE): $(TOP)/ext/misc/scrub.c sqlite3.o
|
||||
scrub$(TEXE): $(TOP)/ext/misc/scrub.c sqlite3.lo
|
||||
$(LTLINK) -o $@ -I. -DSCRUB_STANDALONE \
|
||||
$(TOP)/ext/misc/scrub.c sqlite3.o $(TLIBS)
|
||||
$(TOP)/ext/misc/scrub.c sqlite3.lo $(TLIBS)
|
||||
|
||||
srcck1$(BEXE): $(TOP)/tool/srcck1.c
|
||||
$(BCC) -o srcck1$(BEXE) $(TOP)/tool/srcck1.c
|
||||
@@ -611,8 +627,8 @@ fuzzershell$(TEXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h
|
||||
fuzzcheck$(TEXE): $(TOP)/test/fuzzcheck.c sqlite3.c sqlite3.h
|
||||
$(LTLINK) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/fuzzcheck.c sqlite3.c $(TLIBS)
|
||||
|
||||
mptester$(TEXE): sqlite3.c $(TOP)/mptest/mptest.c
|
||||
$(LTLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \
|
||||
mptester$(TEXE): sqlite3.lo $(TOP)/mptest/mptest.c
|
||||
$(LTLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.lo \
|
||||
$(TLIBS) -rpath "$(libdir)"
|
||||
|
||||
MPTEST1=./mptester$(TEXE) mptest.db $(TOP)/mptest/crash01.test --repeat 20
|
||||
@@ -1156,8 +1172,8 @@ rollback-test$(TEXE): $(TOP)/tool/rollback-test.c sqlite3.lo
|
||||
LogEst$(TEXE): $(TOP)/tool/logest.c sqlite3.h
|
||||
$(LTLINK) -I. -o $@ $(TOP)/tool/logest.c
|
||||
|
||||
wordcount$(TEXE): $(TOP)/test/wordcount.c sqlite3.c
|
||||
$(LTLINK) -o $@ $(TOP)/test/wordcount.c sqlite3.c $(TLIBS)
|
||||
wordcount$(TEXE): $(TOP)/test/wordcount.c sqlite3.lo
|
||||
$(LTLINK) -o $@ $(TOP)/test/wordcount.c sqlite3.lo $(TLIBS)
|
||||
|
||||
speedtest1$(TEXE): $(TOP)/test/speedtest1.c sqlite3.lo
|
||||
$(LTLINK) -o $@ $(TOP)/test/speedtest1.c sqlite3.lo $(TLIBS)
|
||||
@@ -1174,7 +1190,7 @@ loadfts$(EXE): $(TOP)/tool/loadfts.c libsqlite3.la
|
||||
#
|
||||
VALIDIDS=' sqlite3(changeset|changegroup|session)?_'
|
||||
checksymbols: sqlite3.lo
|
||||
nm -g --defined-only sqlite3.o | egrep -v $(VALIDIDS); test $$? -ne 0
|
||||
nm -g --defined-only sqlite3.lo | egrep -v $(VALIDIDS); test $$? -ne 0
|
||||
echo '0 errors out of 1 tests'
|
||||
|
||||
# Build the amalgamation-autoconf package. The amalamgation-tarball target builds
|
||||
@@ -1225,10 +1241,10 @@ install: sqlite3$(TEXE) lib_install sqlite3.h sqlite3.pc ${HAVE_TCL:1=tcl_instal
|
||||
pkgIndex.tcl:
|
||||
echo 'package ifneeded sqlite3 $(RELEASE) [list load $(TCLLIBDIR)/libtclsqlite3$(SHLIB_SUFFIX) sqlite3]' > $@
|
||||
tcl_install: lib_install libtclsqlite3.la pkgIndex.tcl
|
||||
$(INSTALL) -d $(DESTDIR)$(TCLLIBDIR)
|
||||
$(LTINSTALL) libtclsqlite3.la $(DESTDIR)$(TCLLIBDIR)
|
||||
rm -f $(DESTDIR)$(TCLLIBDIR)/libtclsqlite3.la $(DESTDIR)$(TCLLIBDIR)/libtclsqlite3.a
|
||||
$(INSTALL) -m 0644 pkgIndex.tcl $(DESTDIR)$(TCLLIBDIR)
|
||||
$(INSTALL) -d $(DESTDIR)$(TCLLIBDIR)/sqlite3
|
||||
$(LTINSTALL) libtclsqlite3.la $(DESTDIR)$(TCLLIBDIR)/sqlite3
|
||||
rm -f $(DESTDIR)$(TCLLIBDIR)/sqlite3/libtclsqlite3.la $(DESTDIR)$(TCLLIBDIR)/sqlite3/libtclsqlite3.a
|
||||
$(INSTALL) -m 0644 pkgIndex.tcl $(DESTDIR)$(TCLLIBDIR)/sqlite3
|
||||
|
||||
clean:
|
||||
rm -f *.lo *.la *.o sqlite3$(TEXE) libsqlite3.la
|
||||
|
||||
+5
-1
@@ -1292,6 +1292,7 @@ TESTSRC = \
|
||||
#
|
||||
TESTEXT = \
|
||||
$(TOP)\ext\misc\amatch.c \
|
||||
$(TOP)\ext\misc\carray.c \
|
||||
$(TOP)\ext\misc\closure.c \
|
||||
$(TOP)\ext\misc\csv.c \
|
||||
$(TOP)\ext\misc\eval.c \
|
||||
@@ -1394,7 +1395,10 @@ FUZZDATA = \
|
||||
# when the shell is not being dynamically linked.
|
||||
#
|
||||
!IF $(DYNAMIC_SHELL)==0 && $(FOR_WIN10)==0
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS4
|
||||
# SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_FTS5
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS
|
||||
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
|
||||
!ENDIF
|
||||
|
||||
# <<mark>>
|
||||
|
||||
@@ -903,6 +903,8 @@ with_readline_inc
|
||||
enable_debug
|
||||
enable_amalgamation
|
||||
enable_load_extension
|
||||
enable_memsys5
|
||||
enable_memsys3
|
||||
enable_fts3
|
||||
enable_fts4
|
||||
enable_fts5
|
||||
@@ -1552,6 +1554,8 @@ Optional Features:
|
||||
separately
|
||||
--disable-load-extension
|
||||
Disable loading of external extensions
|
||||
--enable-memsys5 Enable MEMSYS5
|
||||
--enable-memsys3 Enable MEMSYS3
|
||||
--enable-fts3 Enable the FTS3 extension
|
||||
--enable-fts4 Enable the FTS4 extension
|
||||
--enable-fts5 Enable the FTS5 extension
|
||||
@@ -3925,13 +3929,13 @@ if ${lt_cv_nm_interface+:} false; then :
|
||||
else
|
||||
lt_cv_nm_interface="BSD nm"
|
||||
echo "int some_variable = 0;" > conftest.$ac_ext
|
||||
(eval echo "\"\$as_me:3928: $ac_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:3932: $ac_compile\"" >&5)
|
||||
(eval "$ac_compile" 2>conftest.err)
|
||||
cat conftest.err >&5
|
||||
(eval echo "\"\$as_me:3931: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
|
||||
(eval echo "\"\$as_me:3935: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
|
||||
(eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
|
||||
cat conftest.err >&5
|
||||
(eval echo "\"\$as_me:3934: output\"" >&5)
|
||||
(eval echo "\"\$as_me:3938: output\"" >&5)
|
||||
cat conftest.out >&5
|
||||
if $GREP 'External.*some_variable' conftest.out > /dev/null; then
|
||||
lt_cv_nm_interface="MS dumpbin"
|
||||
@@ -5137,7 +5141,7 @@ ia64-*-hpux*)
|
||||
;;
|
||||
*-*-irix6*)
|
||||
# Find out which ABI we are using.
|
||||
echo '#line 5140 "configure"' > conftest.$ac_ext
|
||||
echo '#line 5144 "configure"' > conftest.$ac_ext
|
||||
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
|
||||
(eval $ac_compile) 2>&5
|
||||
ac_status=$?
|
||||
@@ -6662,11 +6666,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:6665: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:6669: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:6669: \$? = $ac_status" >&5
|
||||
echo "$as_me:6673: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings other than the usual output.
|
||||
@@ -7001,11 +7005,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:7004: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:7008: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:7008: \$? = $ac_status" >&5
|
||||
echo "$as_me:7012: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings other than the usual output.
|
||||
@@ -7106,11 +7110,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:7109: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:7113: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:7113: \$? = $ac_status" >&5
|
||||
echo "$as_me:7117: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s out/conftest2.$ac_objext
|
||||
then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
@@ -7161,11 +7165,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:7164: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:7168: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:7168: \$? = $ac_status" >&5
|
||||
echo "$as_me:7172: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s out/conftest2.$ac_objext
|
||||
then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
@@ -9541,7 +9545,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<_LT_EOF
|
||||
#line 9544 "configure"
|
||||
#line 9548 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@@ -9637,7 +9641,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<_LT_EOF
|
||||
#line 9640 "configure"
|
||||
#line 9644 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@@ -11339,6 +11343,44 @@ else
|
||||
OPT_FEATURE_FLAGS="-DSQLITE_OMIT_LOAD_EXTENSION=1"
|
||||
fi
|
||||
|
||||
##########
|
||||
# Do we want to support memsys3 and/or memsys5
|
||||
#
|
||||
# Check whether --enable-memsys5 was given.
|
||||
if test "${enable_memsys5+set}" = set; then :
|
||||
enableval=$enable_memsys5; enable_memsys5=yes
|
||||
else
|
||||
enable_memsys5=no
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support MEMSYS5" >&5
|
||||
$as_echo_n "checking whether to support MEMSYS5... " >&6; }
|
||||
if test "${enable_memsys5}" = "yes"; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_MEMSYS5"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
# Check whether --enable-memsys3 was given.
|
||||
if test "${enable_memsys3+set}" = set; then :
|
||||
enableval=$enable_memsys3; enable_memsys3=yes
|
||||
else
|
||||
enable_memsys3=no
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support MEMSYS3" >&5
|
||||
$as_echo_n "checking whether to support MEMSYS3... " >&6; }
|
||||
if test "${enable_memsys3}" = "yes" -a "${enable_memsys5}" = "no"; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_MEMSYS3"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
#########
|
||||
# See whether we should enable Full Text Search extensions
|
||||
# Check whether --enable-fts3 was given.
|
||||
|
||||
@@ -588,6 +588,30 @@ else
|
||||
OPT_FEATURE_FLAGS="-DSQLITE_OMIT_LOAD_EXTENSION=1"
|
||||
fi
|
||||
|
||||
##########
|
||||
# Do we want to support memsys3 and/or memsys5
|
||||
#
|
||||
AC_ARG_ENABLE(memsys5,
|
||||
AC_HELP_STRING([--enable-memsys5],[Enable MEMSYS5]),
|
||||
[enable_memsys5=yes],[enable_memsys5=no])
|
||||
AC_MSG_CHECKING([whether to support MEMSYS5])
|
||||
if test "${enable_memsys5}" = "yes"; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_MEMSYS5"
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
AC_ARG_ENABLE(memsys3,
|
||||
AC_HELP_STRING([--enable-memsys3],[Enable MEMSYS3]),
|
||||
[enable_memsys3=yes],[enable_memsys3=no])
|
||||
AC_MSG_CHECKING([whether to support MEMSYS3])
|
||||
if test "${enable_memsys3}" = "yes" -a "${enable_memsys5}" = "no"; then
|
||||
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_MEMSYS3"
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
|
||||
#########
|
||||
# See whether we should enable Full Text Search extensions
|
||||
AC_ARG_ENABLE(fts3, AC_HELP_STRING([--enable-fts3],
|
||||
|
||||
@@ -247,7 +247,11 @@ int sqlite3Fts5CreateTable(
|
||||
char *zErr = 0;
|
||||
|
||||
rc = fts5ExecPrintf(pConfig->db, &zErr, "CREATE TABLE %Q.'%q_%q'(%s)%s",
|
||||
pConfig->zDb, pConfig->zName, zPost, zDefn, bWithout?" WITHOUT ROWID":""
|
||||
pConfig->zDb, pConfig->zName, zPost, zDefn,
|
||||
#ifndef SQLITE_FTS5_NO_WITHOUT_ROWID
|
||||
bWithout?" WITHOUT ROWID":
|
||||
#endif
|
||||
""
|
||||
);
|
||||
if( zErr ){
|
||||
*pzErr = sqlite3_mprintf(
|
||||
|
||||
@@ -100,30 +100,55 @@ do_test 2.7 {
|
||||
# following tests verify that that problem has been addressed.
|
||||
#
|
||||
foreach_detail_mode $::testprefix {
|
||||
do_execsql_test 3.0 {
|
||||
do_execsql_test 3.1.0 {
|
||||
CREATE VIRTUAL TABLE y1 USING fts5(z, detail=%DETAIL%);
|
||||
INSERT INTO y1 VALUES('test xyz');
|
||||
INSERT INTO y1 VALUES('test test xyz test');
|
||||
INSERT INTO y1 VALUES('test test xyz');
|
||||
}
|
||||
|
||||
do_execsql_test 3.1 {
|
||||
do_execsql_test 3.1.1 {
|
||||
SELECT rowid FROM y1('test OR tset');
|
||||
} {1 2 3}
|
||||
|
||||
do_execsql_test 3.2 {
|
||||
do_execsql_test 3.1.2 {
|
||||
SELECT rowid FROM y1('test OR tset') ORDER BY bm25(y1)
|
||||
} {2 3 1}
|
||||
|
||||
do_execsql_test 3.3 {
|
||||
do_execsql_test 3.1.3 {
|
||||
SELECT rowid FROM y1('test OR tset') ORDER BY +rank
|
||||
} {2 3 1}
|
||||
|
||||
do_execsql_test 3.4 {
|
||||
do_execsql_test 3.1.4 {
|
||||
SELECT rowid FROM y1('test OR tset') ORDER BY rank
|
||||
} {2 3 1}
|
||||
|
||||
do_execsql_test 3.1.5 {
|
||||
SELECT rowid FROM y1('test OR xyz') ORDER BY rank
|
||||
} {3 2 1}
|
||||
|
||||
|
||||
do_execsql_test 3.2.1 {
|
||||
CREATE VIRTUAL TABLE z1 USING fts5(a, detail=%DETAIL%);
|
||||
INSERT INTO z1 VALUES('wrinkle in time');
|
||||
SELECT * FROM z1 WHERE z1 MATCH 'wrinkle in time OR a wrinkle in time';
|
||||
} {{wrinkle in time}}
|
||||
}
|
||||
|
||||
do_execsql_test 4.1 {
|
||||
DROP TABLE IF EXISTS VTest;
|
||||
CREATE virtual TABLE VTest USING FTS5(
|
||||
Title, AUthor, tokenize ='porter unicode61 remove_diacritics 1',
|
||||
columnsize='1', detail=full
|
||||
);
|
||||
INSERT INTO VTest (Title, Author) VALUES ('wrinkle in time', 'Bill Smith');
|
||||
|
||||
SELECT * FROM VTest WHERE
|
||||
VTest MATCH 'wrinkle in time OR a wrinkle in time' ORDER BY rank;
|
||||
} {{wrinkle in time} {Bill Smith}}
|
||||
|
||||
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
@@ -265,7 +265,7 @@ do_test 11.0 {
|
||||
execsql "
|
||||
INSERT INTO t4 VALUES('a b c \x1A');
|
||||
INSERT INTO t4 VALUES('a b c d\x1A');
|
||||
INSERT INTO t4 VALUES('a b c \x1Ad');
|
||||
INSERT INTO t4 VALUES('a b c \x1Ag');
|
||||
INSERT INTO t4 VALUES('a b c d');
|
||||
"
|
||||
} {}
|
||||
|
||||
@@ -0,0 +1,364 @@
|
||||
/*
|
||||
** 2016-06-29
|
||||
**
|
||||
** 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 demonstrates how to create a table-valued-function that
|
||||
** returns the values in a C-language array.
|
||||
** Examples:
|
||||
**
|
||||
** SELECT * FROM carray($ptr,5)
|
||||
**
|
||||
** The query above returns 5 integers contained in a C-language array
|
||||
** at the address $ptr. $ptr is a pointer to the array of integers that
|
||||
** has been cast to an integer.
|
||||
**
|
||||
** There is an optional third parameter to determine the datatype of
|
||||
** the C-language array. Allowed values of the third parameter are
|
||||
** 'int32', 'int64', 'double', 'char*'. Example:
|
||||
**
|
||||
** SELECT * FROM carray($ptr,10,'char*');
|
||||
**
|
||||
** HOW IT WORKS
|
||||
**
|
||||
** The carray "function" is really a virtual table with the
|
||||
** following schema:
|
||||
**
|
||||
** CREATE TABLE carray(
|
||||
** value,
|
||||
** pointer HIDDEN,
|
||||
** count HIDDEN,
|
||||
** ctype TEXT HIDDEN
|
||||
** );
|
||||
**
|
||||
** If the hidden columns "pointer" and "count" are unconstrained, then
|
||||
** the virtual table has no rows. Otherwise, the virtual table interprets
|
||||
** the integer value of "pointer" as a pointer to the array and "count"
|
||||
** as the number of elements in the array. The virtual table steps through
|
||||
** the array, element by element.
|
||||
*/
|
||||
#include "sqlite3ext.h"
|
||||
SQLITE_EXTENSION_INIT1
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
|
||||
/*
|
||||
** Allowed datatypes
|
||||
*/
|
||||
#define CARRAY_INT32 0
|
||||
#define CARRAY_INT64 1
|
||||
#define CARRAY_DOUBLE 2
|
||||
#define CARRAY_TEXT 3
|
||||
|
||||
/*
|
||||
** Names of types
|
||||
*/
|
||||
static const char *azType[] = { "int32", "int64", "double", "char*" };
|
||||
|
||||
|
||||
/* carray_cursor is a subclass of sqlite3_vtab_cursor which will
|
||||
** serve as the underlying representation of a cursor that scans
|
||||
** over rows of the result
|
||||
*/
|
||||
typedef struct carray_cursor carray_cursor;
|
||||
struct carray_cursor {
|
||||
sqlite3_vtab_cursor base; /* Base class - must be first */
|
||||
sqlite3_int64 iRowid; /* The rowid */
|
||||
sqlite3_int64 iPtr; /* Pointer to array of values */
|
||||
sqlite3_int64 iCnt; /* Number of integers in the array */
|
||||
unsigned char eType; /* One of the CARRAY_type values */
|
||||
};
|
||||
|
||||
/*
|
||||
** The carrayConnect() method is invoked to create a new
|
||||
** carray_vtab that describes the carray virtual table.
|
||||
**
|
||||
** Think of this routine as the constructor for carray_vtab objects.
|
||||
**
|
||||
** All this routine needs to do is:
|
||||
**
|
||||
** (1) Allocate the carray_vtab object and initialize all fields.
|
||||
**
|
||||
** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the
|
||||
** result set of queries against carray will look like.
|
||||
*/
|
||||
static int carrayConnect(
|
||||
sqlite3 *db,
|
||||
void *pAux,
|
||||
int argc, const char *const*argv,
|
||||
sqlite3_vtab **ppVtab,
|
||||
char **pzErr
|
||||
){
|
||||
sqlite3_vtab *pNew;
|
||||
int rc;
|
||||
|
||||
/* Column numbers */
|
||||
#define CARRAY_COLUMN_VALUE 0
|
||||
#define CARRAY_COLUMN_POINTER 1
|
||||
#define CARRAY_COLUMN_COUNT 2
|
||||
#define CARRAY_COLUMN_CTYPE 3
|
||||
|
||||
rc = sqlite3_declare_vtab(db,
|
||||
"CREATE TABLE x(value,pointer hidden,count hidden,ctype hidden)");
|
||||
if( rc==SQLITE_OK ){
|
||||
pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
|
||||
if( pNew==0 ) return SQLITE_NOMEM;
|
||||
memset(pNew, 0, sizeof(*pNew));
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** This method is the destructor for carray_cursor objects.
|
||||
*/
|
||||
static int carrayDisconnect(sqlite3_vtab *pVtab){
|
||||
sqlite3_free(pVtab);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Constructor for a new carray_cursor object.
|
||||
*/
|
||||
static int carrayOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
|
||||
carray_cursor *pCur;
|
||||
pCur = sqlite3_malloc( sizeof(*pCur) );
|
||||
if( pCur==0 ) return SQLITE_NOMEM;
|
||||
memset(pCur, 0, sizeof(*pCur));
|
||||
*ppCursor = &pCur->base;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Destructor for a carray_cursor.
|
||||
*/
|
||||
static int carrayClose(sqlite3_vtab_cursor *cur){
|
||||
sqlite3_free(cur);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Advance a carray_cursor to its next row of output.
|
||||
*/
|
||||
static int carrayNext(sqlite3_vtab_cursor *cur){
|
||||
carray_cursor *pCur = (carray_cursor*)cur;
|
||||
pCur->iRowid++;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return values of columns for the row at which the carray_cursor
|
||||
** is currently pointing.
|
||||
*/
|
||||
static int carrayColumn(
|
||||
sqlite3_vtab_cursor *cur, /* The cursor */
|
||||
sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
|
||||
int i /* Which column to return */
|
||||
){
|
||||
carray_cursor *pCur = (carray_cursor*)cur;
|
||||
sqlite3_int64 x = 0;
|
||||
switch( i ){
|
||||
case CARRAY_COLUMN_POINTER: x = pCur->iPtr; break;
|
||||
case CARRAY_COLUMN_COUNT: x = pCur->iCnt; break;
|
||||
case CARRAY_COLUMN_CTYPE: {
|
||||
sqlite3_result_text(ctx, azType[pCur->eType], -1, SQLITE_STATIC);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
default: {
|
||||
switch( pCur->eType ){
|
||||
case CARRAY_INT32: {
|
||||
int *p = (int*)pCur->iPtr;
|
||||
sqlite3_result_int(ctx, p[pCur->iRowid-1]);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
case CARRAY_INT64: {
|
||||
sqlite3_int64 *p = (sqlite3_int64*)pCur->iPtr;
|
||||
sqlite3_result_int64(ctx, p[pCur->iRowid-1]);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
case CARRAY_DOUBLE: {
|
||||
double *p = (double*)pCur->iPtr;
|
||||
sqlite3_result_double(ctx, p[pCur->iRowid-1]);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
case CARRAY_TEXT: {
|
||||
const char **p = (const char**)pCur->iPtr;
|
||||
sqlite3_result_text(ctx, p[pCur->iRowid-1], -1, SQLITE_TRANSIENT);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sqlite3_result_int64(ctx, x);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the rowid for the current row. In this implementation, the
|
||||
** rowid is the same as the output value.
|
||||
*/
|
||||
static int carrayRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
|
||||
carray_cursor *pCur = (carray_cursor*)cur;
|
||||
*pRowid = pCur->iRowid;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return TRUE if the cursor has been moved off of the last
|
||||
** row of output.
|
||||
*/
|
||||
static int carrayEof(sqlite3_vtab_cursor *cur){
|
||||
carray_cursor *pCur = (carray_cursor*)cur;
|
||||
return pCur->iRowid>pCur->iCnt;
|
||||
}
|
||||
|
||||
/*
|
||||
** This method is called to "rewind" the carray_cursor object back
|
||||
** to the first row of output.
|
||||
*/
|
||||
static int carrayFilter(
|
||||
sqlite3_vtab_cursor *pVtabCursor,
|
||||
int idxNum, const char *idxStr,
|
||||
int argc, sqlite3_value **argv
|
||||
){
|
||||
carray_cursor *pCur = (carray_cursor *)pVtabCursor;
|
||||
if( idxNum ){
|
||||
pCur->iPtr = sqlite3_value_int64(argv[0]);
|
||||
pCur->iCnt = sqlite3_value_int64(argv[1]);
|
||||
if( idxNum<3 ){
|
||||
pCur->eType = CARRAY_INT32;
|
||||
}else{
|
||||
unsigned char i;
|
||||
const char *zType = (const char*)sqlite3_value_text(argv[2]);
|
||||
for(i=0; i<sizeof(azType)/sizeof(azType[0]); i++){
|
||||
if( sqlite3_stricmp(zType, azType[i])==0 ) break;
|
||||
}
|
||||
if( i>=sizeof(azType)/sizeof(azType[0]) ){
|
||||
pVtabCursor->pVtab->zErrMsg = sqlite3_mprintf(
|
||||
"unknown datatype: %Q", zType);
|
||||
return SQLITE_ERROR;
|
||||
}else{
|
||||
pCur->eType = i;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
pCur->iPtr = 0;
|
||||
pCur->iCnt = 0;
|
||||
}
|
||||
pCur->iRowid = 1;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** SQLite will invoke this method one or more times while planning a query
|
||||
** that uses the carray virtual table. This routine needs to create
|
||||
** a query plan for each invocation and compute an estimated cost for that
|
||||
** plan.
|
||||
**
|
||||
** In this implementation idxNum is used to represent the
|
||||
** query plan. idxStr is unused.
|
||||
**
|
||||
** idxNum is 2 if the pointer= and count= constraints exist,
|
||||
** 3 if the ctype= constraint also exists, and is 0 otherwise.
|
||||
** If idxNum is 0, then carray becomes an empty table.
|
||||
*/
|
||||
static int carrayBestIndex(
|
||||
sqlite3_vtab *tab,
|
||||
sqlite3_index_info *pIdxInfo
|
||||
){
|
||||
int i; /* Loop over constraints */
|
||||
int ptrIdx = -1; /* Index of the pointer= constraint, or -1 if none */
|
||||
int cntIdx = -1; /* Index of the count= constraint, or -1 if none */
|
||||
int ctypeIdx = -1; /* Index of the ctype= constraint, or -1 if none */
|
||||
|
||||
const struct sqlite3_index_constraint *pConstraint;
|
||||
pConstraint = pIdxInfo->aConstraint;
|
||||
for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
|
||||
if( pConstraint->usable==0 ) continue;
|
||||
if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
|
||||
switch( pConstraint->iColumn ){
|
||||
case CARRAY_COLUMN_POINTER:
|
||||
ptrIdx = i;
|
||||
break;
|
||||
case CARRAY_COLUMN_COUNT:
|
||||
cntIdx = i;
|
||||
break;
|
||||
case CARRAY_COLUMN_CTYPE:
|
||||
ctypeIdx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( ptrIdx>=0 && cntIdx>=0 ){
|
||||
pIdxInfo->aConstraintUsage[ptrIdx].argvIndex = 1;
|
||||
pIdxInfo->aConstraintUsage[ptrIdx].omit = 1;
|
||||
pIdxInfo->aConstraintUsage[cntIdx].argvIndex = 2;
|
||||
pIdxInfo->aConstraintUsage[cntIdx].omit = 1;
|
||||
pIdxInfo->estimatedCost = (double)1;
|
||||
pIdxInfo->estimatedRows = 100;
|
||||
pIdxInfo->idxNum = 2;
|
||||
if( ctypeIdx>=0 ){
|
||||
pIdxInfo->aConstraintUsage[ctypeIdx].argvIndex = 3;
|
||||
pIdxInfo->aConstraintUsage[ctypeIdx].omit = 1;
|
||||
pIdxInfo->idxNum = 3;
|
||||
}
|
||||
}else{
|
||||
pIdxInfo->estimatedCost = (double)2147483647;
|
||||
pIdxInfo->estimatedRows = 2147483647;
|
||||
pIdxInfo->idxNum = 0;
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** This following structure defines all the methods for the
|
||||
** carray virtual table.
|
||||
*/
|
||||
static sqlite3_module carrayModule = {
|
||||
0, /* iVersion */
|
||||
0, /* xCreate */
|
||||
carrayConnect, /* xConnect */
|
||||
carrayBestIndex, /* xBestIndex */
|
||||
carrayDisconnect, /* xDisconnect */
|
||||
0, /* xDestroy */
|
||||
carrayOpen, /* xOpen - open a cursor */
|
||||
carrayClose, /* xClose - close a cursor */
|
||||
carrayFilter, /* xFilter - configure scan constraints */
|
||||
carrayNext, /* xNext - advance a cursor */
|
||||
carrayEof, /* xEof - check for end of scan */
|
||||
carrayColumn, /* xColumn - read data */
|
||||
carrayRowid, /* xRowid - read data */
|
||||
0, /* xUpdate */
|
||||
0, /* xBegin */
|
||||
0, /* xSync */
|
||||
0, /* xCommit */
|
||||
0, /* xRollback */
|
||||
0, /* xFindMethod */
|
||||
0, /* xRename */
|
||||
};
|
||||
|
||||
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
||||
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
int sqlite3_carray_init(
|
||||
sqlite3 *db,
|
||||
char **pzErrMsg,
|
||||
const sqlite3_api_routines *pApi
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
SQLITE_EXTENSION_INIT2(pApi);
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
rc = sqlite3_create_module(db, "carray", &carrayModule, 0);
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
+17
-9
@@ -48,6 +48,8 @@ SQLITE_EXTENSION_INIT1
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
|
||||
/*
|
||||
** A macro to hint to the compiler that a function should not be
|
||||
** inlined.
|
||||
@@ -230,7 +232,7 @@ static char *csv_read_one_field(CsvReader *p){
|
||||
|| (c==EOF && pc=='"')
|
||||
){
|
||||
do{ p->n--; }while( p->z[p->n]!='"' );
|
||||
p->cTerm = c;
|
||||
p->cTerm = (char)c;
|
||||
break;
|
||||
}
|
||||
if( pc=='"' && c!='\r' ){
|
||||
@@ -240,7 +242,7 @@ static char *csv_read_one_field(CsvReader *p){
|
||||
if( c==EOF ){
|
||||
csv_errmsg(p, "line %d: unterminated %c-quoted field\n",
|
||||
startLine, '"');
|
||||
p->cTerm = c;
|
||||
p->cTerm = (char)c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -257,7 +259,7 @@ static char *csv_read_one_field(CsvReader *p){
|
||||
p->nLine++;
|
||||
if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
|
||||
}
|
||||
p->cTerm = c;
|
||||
p->cTerm = (char)c;
|
||||
}
|
||||
if( p->z ) p->z[p->n] = 0;
|
||||
return p->z;
|
||||
@@ -336,9 +338,9 @@ static void csv_trim_whitespace(char *z){
|
||||
|
||||
/* Dequote the string */
|
||||
static void csv_dequote(char *z){
|
||||
int i, j;
|
||||
int j;
|
||||
char cQuote = z[0];
|
||||
size_t n;
|
||||
size_t i, n;
|
||||
|
||||
if( cQuote!='\'' && cQuote!='"' ) return;
|
||||
n = strlen(z);
|
||||
@@ -375,7 +377,7 @@ static int csv_string_parameter(
|
||||
char **pzVal /* Write the dequoted string value here */
|
||||
){
|
||||
const char *zValue;
|
||||
zValue = csv_parameter(zParam,strlen(zParam),zArg);
|
||||
zValue = csv_parameter(zParam,(int)strlen(zParam),zArg);
|
||||
if( zValue==0 ) return 0;
|
||||
p->zErr[0] = 0;
|
||||
if( *pzVal ){
|
||||
@@ -616,7 +618,7 @@ static int csvtabOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
|
||||
CsvCursor *pCur;
|
||||
size_t nByte;
|
||||
nByte = sizeof(*pCur) + (sizeof(char*)+sizeof(int))*pTab->nCol;
|
||||
pCur = sqlite3_malloc( nByte );
|
||||
pCur = sqlite3_malloc64( nByte );
|
||||
if( pCur==0 ) return SQLITE_NOMEM;
|
||||
memset(pCur, 0, nByte);
|
||||
pCur->azVal = (char**)&pCur[1];
|
||||
@@ -647,7 +649,7 @@ static int csvtabNext(sqlite3_vtab_cursor *cur){
|
||||
}
|
||||
if( i<pTab->nCol ){
|
||||
if( pCur->aLen[i] < pCur->rdr.n+1 ){
|
||||
char *zNew = sqlite3_realloc(pCur->azVal[i], pCur->rdr.n+1);
|
||||
char *zNew = sqlite3_realloc64(pCur->azVal[i], pCur->rdr.n+1);
|
||||
if( zNew==0 ){
|
||||
csv_errmsg(&pCur->rdr, "out of memory");
|
||||
csv_xfer_error(pTab, &pCur->rdr);
|
||||
@@ -723,7 +725,8 @@ static int csvtabFilter(
|
||||
pCur->iRowid = 0;
|
||||
if( pCur->rdr.in==0 ){
|
||||
assert( pCur->rdr.zIn==pTab->zData );
|
||||
assert( pTab->iStart<=pCur->rdr.nIn );
|
||||
assert( pTab->iStart>=0 );
|
||||
assert( (size_t)pTab->iStart<=pCur->rdr.nIn );
|
||||
pCur->rdr.iIn = pTab->iStart;
|
||||
}else{
|
||||
fseek(pCur->rdr.in, pTab->iStart, SEEK_SET);
|
||||
@@ -834,6 +837,7 @@ static sqlite3_module CsvModuleFauxWrite = {
|
||||
};
|
||||
#endif /* SQLITE_TEST */
|
||||
|
||||
#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
@@ -849,6 +853,7 @@ int sqlite3_csv_init(
|
||||
char **pzErrMsg,
|
||||
const sqlite3_api_routines *pApi
|
||||
){
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
int rc;
|
||||
SQLITE_EXTENSION_INIT2(pApi);
|
||||
rc = sqlite3_create_module(db, "csv", &CsvModule, 0);
|
||||
@@ -858,4 +863,7 @@ int sqlite3_csv_init(
|
||||
}
|
||||
#endif
|
||||
return rc;
|
||||
#else
|
||||
return SQLITE_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1211,6 +1211,25 @@ static void jsonTest1Func(
|
||||
** Scalar SQL function implementations
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
** Implementation of the json_QUOTE(VALUE) function. Return a JSON value
|
||||
** corresponding to the SQL value input. Mostly this means putting
|
||||
** double-quotes around strings and returning the unquoted string "null"
|
||||
** when given a NULL input.
|
||||
*/
|
||||
static void jsonQuoteFunc(
|
||||
sqlite3_context *ctx,
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
JsonString jx;
|
||||
|
||||
jsonInit(&jx, ctx);
|
||||
jsonAppendValue(&jx, argv[0]);
|
||||
jsonResult(&jx);
|
||||
sqlite3_result_subtype(ctx, JSON_SUBTYPE);
|
||||
}
|
||||
|
||||
/*
|
||||
** Implementation of the json_array(VALUE,...) function. Return a JSON
|
||||
** array that contains all values given in arguments. Or if any argument
|
||||
@@ -2124,6 +2143,7 @@ int sqlite3Json1Init(sqlite3 *db){
|
||||
{ "json_extract", -1, 0, jsonExtractFunc },
|
||||
{ "json_insert", -1, 0, jsonSetFunc },
|
||||
{ "json_object", -1, 0, jsonObjectFunc },
|
||||
{ "json_quote", 1, 0, jsonQuoteFunc },
|
||||
{ "json_remove", -1, 0, jsonRemoveFunc },
|
||||
{ "json_replace", -1, 0, jsonReplaceFunc },
|
||||
{ "json_set", -1, 1, jsonSetFunc },
|
||||
|
||||
@@ -74,6 +74,7 @@ struct ScrubState {
|
||||
u32 szPage; /* Page size */
|
||||
u32 szUsable; /* Usable bytes on each page */
|
||||
u32 nPage; /* Number of pages */
|
||||
u32 iLastPage; /* Page number of last page written so far*/
|
||||
u8 *page1; /* Content of page 1 */
|
||||
};
|
||||
|
||||
@@ -130,6 +131,7 @@ static void scrubBackupWrite(ScrubState *p, int pgno, const u8 *pData){
|
||||
scrubBackupErr(p, "write failed for page %d", pgno);
|
||||
p->rcErr = SQLITE_IOERR;
|
||||
}
|
||||
if( pgno>p->iLastPage ) p->iLastPage = pgno;
|
||||
}
|
||||
|
||||
/* Prepare a statement against the "db" database. */
|
||||
@@ -541,6 +543,20 @@ int sqlite3_scrub_backup(
|
||||
}
|
||||
sqlite3_finalize(pStmt);
|
||||
|
||||
/* If the last page of the input db file is a free-list leaf, then the
|
||||
** backup file on disk is still smaller than the size indicated within
|
||||
** the database header. In this case, write a page of zeroes to the
|
||||
** last page of the backup database so that SQLite does not mistakenly
|
||||
** think the db is corrupt. */
|
||||
if( s.iLastPage<s.nPage ){
|
||||
u8 *aZero = scrubBackupAllocPage(&s);
|
||||
if( aZero ){
|
||||
memset(aZero, 0, s.szPage);
|
||||
scrubBackupWrite(&s, s.nPage, aZero);
|
||||
sqlite3_free(aZero);
|
||||
}
|
||||
}
|
||||
|
||||
scrub_abort:
|
||||
/* Close the destination database without closing the transaction. If we
|
||||
** commit, page zero will be overwritten. */
|
||||
|
||||
+18
-26
@@ -10,10 +10,7 @@
|
||||
#***********************************************************************
|
||||
#
|
||||
|
||||
if {![info exists testdir]} {
|
||||
set testdir [file join [file dirname [info script]] .. .. test]
|
||||
}
|
||||
source $testdir/tester.tcl
|
||||
source [file join [file dirname [info script]] rbu_common.tcl]
|
||||
set ::testprefix rbu1
|
||||
|
||||
db close
|
||||
@@ -96,26 +93,6 @@ proc create_rbu5 {filename} {
|
||||
return $filename
|
||||
}
|
||||
|
||||
# Run the RBU in file $rbu on target database $target until completion.
|
||||
#
|
||||
proc run_rbu {target rbu} {
|
||||
sqlite3rbu rbu $target $rbu
|
||||
while 1 {
|
||||
set rc [rbu step]
|
||||
if {$rc!="SQLITE_OK"} break
|
||||
}
|
||||
rbu close
|
||||
}
|
||||
|
||||
proc step_rbu {target rbu} {
|
||||
while 1 {
|
||||
sqlite3rbu rbu $target $rbu
|
||||
set rc [rbu step]
|
||||
rbu close
|
||||
if {$rc != "SQLITE_OK"} break
|
||||
}
|
||||
set rc
|
||||
}
|
||||
|
||||
# Same as [step_rbu], except using a URI to open the target db.
|
||||
#
|
||||
@@ -641,10 +618,25 @@ foreach {tn3 create_vfs destroy_vfs} {
|
||||
# correctly.
|
||||
reset_db
|
||||
forcedelete rbu.db
|
||||
do_test $tn3.8 {
|
||||
do_test $tn3.8.1 {
|
||||
list [catch { run_rbu test.db rbu.db } msg] $msg
|
||||
} {0 SQLITE_DONE}
|
||||
|
||||
|
||||
# Test that an RBU database containing only empty data_xxx tables is
|
||||
# also handled correctly.
|
||||
reset_db
|
||||
forcedelete rbu.db
|
||||
do_execsql_test $tn3.8.2.1 {
|
||||
CREATE TABLE t1(a PRIMARY KEY, b);
|
||||
INSERT INTO t1 VALUES(1, 2);
|
||||
ATTACH 'rbu.db' AS rbu;
|
||||
CREATE TABLE data_t1(a, b, rbu_control);
|
||||
DETACH rbu;
|
||||
}
|
||||
do_test $tn3.8.2.1 {
|
||||
list [catch { run_rbu test.db rbu.db } msg] $msg
|
||||
} {0 SQLITE_DONE}
|
||||
|
||||
# Test that RBU can update indexes containing NULL values.
|
||||
#
|
||||
reset_db
|
||||
|
||||
+1
-26
@@ -12,35 +12,10 @@
|
||||
# Test some properties of the pager_rbu_mode and rbu_mode pragmas.
|
||||
#
|
||||
|
||||
if {![info exists testdir]} {
|
||||
set testdir [file join [file dirname [info script]] .. .. test]
|
||||
}
|
||||
source $testdir/tester.tcl
|
||||
source [file join [file dirname [info script]] rbu_common.tcl]
|
||||
set ::testprefix rbu5
|
||||
|
||||
|
||||
# Run the RBU in file $rbu on target database $target until completion.
|
||||
#
|
||||
proc run_rbu {target rbu} {
|
||||
sqlite3rbu rbu $target $rbu
|
||||
while { [rbu step]=="SQLITE_OK" } {}
|
||||
rbu close
|
||||
}
|
||||
|
||||
|
||||
# Run the RBU in file $rbu on target database $target one step at a
|
||||
# time until completion.
|
||||
#
|
||||
proc step_rbu {target rbu} {
|
||||
while 1 {
|
||||
sqlite3rbu rbu $target $rbu
|
||||
set rc [rbu step]
|
||||
rbu close
|
||||
if {$rc != "SQLITE_OK"} break
|
||||
}
|
||||
set rc
|
||||
}
|
||||
|
||||
# Return a list of the primary key columns for table $tbl in the database
|
||||
# opened by database handle $db.
|
||||
#
|
||||
|
||||
@@ -15,12 +15,43 @@ if {![info exists testdir]} {
|
||||
}
|
||||
source $testdir/tester.tcl
|
||||
|
||||
proc check_prestep_state {target state} {
|
||||
set oal_exists [file exists $target-oal]
|
||||
set wal_exists [file exists $target-wal]
|
||||
set progress [rbu progress]
|
||||
|
||||
if {($progress==0 && $state!="oal" && $state!="done")
|
||||
|| ($oal_exists && $wal_exists)
|
||||
|| ($progress>0 && $state=="oal" && (!$oal_exists || $wal_exists))
|
||||
|| ($state=="move" && (!$oal_exists || $wal_exists))
|
||||
|| ($state=="checkpoint" && ($oal_exists || !$wal_exists))
|
||||
|| ($state=="done" && ($oal_exists && $progress!=0))
|
||||
} {
|
||||
error "B: state=$state progress=$progress oal=$oal_exists wal=$wal_exists"
|
||||
}
|
||||
}
|
||||
|
||||
proc check_poststep_state {rc target state} {
|
||||
if {$rc=="SQLITE_OK" || $rc=="SQLITE_DONE"} {
|
||||
set oal_exists [file exists $target-oal]
|
||||
set wal_exists [file exists $target-wal]
|
||||
if {$state=="move" && ($oal_exists || !$wal_exists)} {
|
||||
error "A: state=$state progress=$progress oal=$oal_exists wal=$wal_exists"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Run the RBU in file $rbu on target database $target until completion.
|
||||
#
|
||||
proc run_rbu {target rbu} {
|
||||
sqlite3rbu rbu $target $rbu
|
||||
while 1 {
|
||||
set state [rbu state]
|
||||
|
||||
check_prestep_state $target $state
|
||||
set rc [rbu step]
|
||||
check_poststep_state $rc $target $state
|
||||
|
||||
if {$rc!="SQLITE_OK"} break
|
||||
}
|
||||
rbu close
|
||||
@@ -29,7 +60,10 @@ proc run_rbu {target rbu} {
|
||||
proc step_rbu {target rbu} {
|
||||
while 1 {
|
||||
sqlite3rbu rbu $target $rbu
|
||||
set state [rbu state]
|
||||
check_prestep_state $target $state
|
||||
set rc [rbu step]
|
||||
check_poststep_state $rc $target $state
|
||||
rbu close
|
||||
if {$rc != "SQLITE_OK"} break
|
||||
}
|
||||
@@ -41,7 +75,10 @@ proc do_rbu_vacuum_test {tn step} {
|
||||
if {$step==0} { sqlite3rbu_vacuum rbu test.db state.db }
|
||||
while 1 {
|
||||
if {$step==1} { sqlite3rbu_vacuum rbu test.db state.db }
|
||||
set state [rbu state]
|
||||
check_prestep_state test.db $state
|
||||
set rc [rbu step]
|
||||
check_poststep_state $rc test.db $state
|
||||
if {$rc!="SQLITE_OK"} break
|
||||
if {$step==1} { rbu close }
|
||||
}
|
||||
|
||||
+124
-3
@@ -25,6 +25,10 @@ proc get_rbudiff_sql {db1 db2} {
|
||||
exec $::PROG --rbu $db1 $db2
|
||||
}
|
||||
|
||||
proc get_vtab_rbudiff_sql {db1 db2} {
|
||||
exec $::PROG --vtab --rbu $db1 $db2
|
||||
}
|
||||
|
||||
proc step_rbu {target rbu} {
|
||||
while 1 {
|
||||
sqlite3rbu rbu $target $rbu
|
||||
@@ -44,6 +48,11 @@ proc apply_rbudiff {sql target} {
|
||||
step_rbu $target rbu.db
|
||||
}
|
||||
|
||||
proc sqlesc {id} {
|
||||
set ret "'[string map {' ''} $id]'"
|
||||
set ret
|
||||
}
|
||||
|
||||
# The only argument is the output of an [sqldiff -rbu] run. This command
|
||||
# tests that the contents of the rbu_count table is correct. An exception
|
||||
# is thrown if it is not.
|
||||
@@ -54,7 +63,7 @@ proc test_rbucount {sql} {
|
||||
tmpdb eval {
|
||||
SELECT name FROM sqlite_master WHERE name LIKE 'data%' AND type='table'
|
||||
} {
|
||||
set a [tmpdb eval "SELECT count(*) FROM $name"]
|
||||
set a [tmpdb eval "SELECT count(*) FROM [sqlesc $name]"]
|
||||
set b [tmpdb eval {SELECT cnt FROM rbu_count WHERE tbl = $name}]
|
||||
if {$a != $b} {
|
||||
tmpdb close
|
||||
@@ -71,9 +80,11 @@ proc rbudiff_cksum {db1} {
|
||||
sqlite3 dbtmp $db1
|
||||
foreach tbl [dbtmp eval {SELECT name FROM sqlite_master WHERE type='table'}] {
|
||||
set cols [list]
|
||||
dbtmp eval "PRAGMA table_info = $tbl" { lappend cols "quote( $name )" }
|
||||
dbtmp eval "PRAGMA table_info = [sqlesc $tbl]" {
|
||||
lappend cols "quote( $name )"
|
||||
}
|
||||
append txt [dbtmp eval \
|
||||
"SELECT [join $cols {||'.'||}] FROM $tbl ORDER BY 1"
|
||||
"SELECT [join $cols {||'.'||}] FROM [sqlesc $tbl] ORDER BY 1"
|
||||
]
|
||||
}
|
||||
dbtmp close
|
||||
@@ -159,5 +170,115 @@ foreach {tn init mod} {
|
||||
do_test 1.$tn.5 { rbudiff_cksum test.db } [rbudiff_cksum test.db2]
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test that if the --vtab switch is present, [sqldiff] handles virtual
|
||||
# table types fts[345] and rtree correctly.
|
||||
#
|
||||
ifcapable fts3&&fts5&&rtree {
|
||||
|
||||
foreach {tn init mod} {
|
||||
1 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(c);
|
||||
INSERT INTO t1 VALUES('a b c');
|
||||
INSERT INTO t1 VALUES('a b c');
|
||||
} {
|
||||
DELETE FROM t1 WHERE rowid = 1;
|
||||
INSERT INTO t1 VALUES('a b c');
|
||||
}
|
||||
|
||||
2 {
|
||||
CREATE VIRTUAL TABLE "x y" USING 'rtree'(id, x1, x2);
|
||||
INSERT INTO "x y" VALUES(1, 2, 3);
|
||||
INSERT INTO "x y" VALUES(2, 4, 6);
|
||||
} {
|
||||
DELETE FROM "x y" WHERE rowid = 1;
|
||||
INSERT INTO "x y" VALUES(3, 6, 9);
|
||||
}
|
||||
|
||||
3 {
|
||||
CREATE VIRTUAL TABLE 'x''y' USING fts3;
|
||||
INSERT INTO 'x''y' VALUES('one two three');
|
||||
INSERT INTO 'x''y' VALUES('four five six');
|
||||
} {
|
||||
DELETE FROM 'x''y' WHERE rowid = 1;
|
||||
INSERT INTO 'x''y' VALUES('one two three');
|
||||
}
|
||||
} {
|
||||
|
||||
forcedelete test.db test.db2
|
||||
sqlite3 db test.db
|
||||
db eval "$init"
|
||||
sqlite3 db test.db2
|
||||
db eval "$init ; $mod"
|
||||
db close
|
||||
|
||||
do_test 2.$tn.1 {
|
||||
set sql [get_vtab_rbudiff_sql test.db test.db2]
|
||||
apply_rbudiff $sql test.db
|
||||
} {SQLITE_DONE}
|
||||
do_test 2.$tn.2 { rbudiff_cksum test.db } [rbudiff_cksum test.db2]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ifcapable fts5 {
|
||||
foreach {tn init mod} {
|
||||
1 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(c);
|
||||
INSERT INTO t1 VALUES('a b c');
|
||||
INSERT INTO t1 VALUES('a b c');
|
||||
} {
|
||||
DELETE FROM t1 WHERE rowid = 1;
|
||||
INSERT INTO t1 VALUES('a b c');
|
||||
}
|
||||
|
||||
2 {
|
||||
CREATE VIRTUAL TABLE t1 USING FTs5(c);
|
||||
INSERT INTO t1 VALUES('a b c');
|
||||
INSERT INTO t1 VALUES('a b c');
|
||||
} {
|
||||
DELETE FROM t1 WHERE rowid = 1;
|
||||
INSERT INTO t1 VALUES('a b c');
|
||||
}
|
||||
|
||||
3 {
|
||||
creAte virTUal
|
||||
tablE t1 USING FTs5(c);
|
||||
INSERT INTO t1 VALUES('a b c');
|
||||
INSERT INTO t1 VALUES('a b c');
|
||||
} {
|
||||
DELETE FROM t1 WHERE rowid = 1;
|
||||
INSERT INTO t1 VALUES('a b c');
|
||||
}
|
||||
|
||||
} {
|
||||
forcedelete test.db test.db2
|
||||
sqlite3 db test.db
|
||||
db eval "$init"
|
||||
sqlite3 db test.db2
|
||||
db eval "$init ; $mod"
|
||||
db eval { INSERT INTO t1(t1) VALUES('optimize') }
|
||||
db close
|
||||
|
||||
do_test 3.$tn.1 {
|
||||
set sql [get_vtab_rbudiff_sql test.db test.db2]
|
||||
apply_rbudiff $sql test.db
|
||||
} {SQLITE_DONE}
|
||||
|
||||
sqlite3 db test.db
|
||||
sqlite3 db2 test.db2
|
||||
do_test 3.$tn.2 {
|
||||
db2 eval { SELECT * FROM t1 ORDER BY rowid }
|
||||
} [db eval { SELECT * FROM t1 ORDER BY rowid }]
|
||||
|
||||
do_test 3.$tn.3 {
|
||||
db2 eval { INSERT INTO t1(t1) VALUES('integrity-check') }
|
||||
} {}
|
||||
|
||||
db close
|
||||
db2 close
|
||||
}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
+60
-31
@@ -2507,9 +2507,9 @@ static void rbuFileSuffix3(const char *zBase, char *z){
|
||||
#endif
|
||||
{
|
||||
int i, sz;
|
||||
sz = sqlite3Strlen30(z);
|
||||
sz = (int)strlen(z)&0xffffff;
|
||||
for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){}
|
||||
if( z[i]=='.' && ALWAYS(sz>i+4) ) memmove(&z[i+1], &z[sz-3], 4);
|
||||
if( z[i]=='.' && sz>i+4 ) memmove(&z[i+1], &z[sz-3], 4);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -3555,30 +3555,7 @@ static sqlite3rbu *openRbuHandle(
|
||||
if( p->rc==SQLITE_OK ){
|
||||
if( p->eStage==RBU_STAGE_OAL ){
|
||||
sqlite3 *db = p->dbMain;
|
||||
|
||||
if( pState->eStage==0 && rbuIsVacuum(p) ){
|
||||
rbuCopyPragma(p, "page_size");
|
||||
rbuCopyPragma(p, "auto_vacuum");
|
||||
}
|
||||
|
||||
/* Open transactions both databases. The *-oal file is opened or
|
||||
** created at this point. */
|
||||
if( p->rc==SQLITE_OK ){
|
||||
p->rc = sqlite3_exec(db, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg);
|
||||
}
|
||||
if( p->rc==SQLITE_OK ){
|
||||
p->rc = sqlite3_exec(p->dbRbu, "BEGIN", 0, 0, &p->zErrmsg);
|
||||
}
|
||||
|
||||
/* Check if the main database is a zipvfs db. If it is, set the upper
|
||||
** level pager to use "journal_mode=off". This prevents it from
|
||||
** generating a large journal using a temp file. */
|
||||
if( p->rc==SQLITE_OK ){
|
||||
int frc = sqlite3_file_control(db, "main", SQLITE_FCNTL_ZIPVFS, 0);
|
||||
if( frc==SQLITE_OK ){
|
||||
p->rc = sqlite3_exec(db, "PRAGMA journal_mode=off",0,0,&p->zErrmsg);
|
||||
}
|
||||
}
|
||||
p->rc = sqlite3_exec(p->dbRbu, "BEGIN", 0, 0, &p->zErrmsg);
|
||||
|
||||
/* Point the object iterator at the first object */
|
||||
if( p->rc==SQLITE_OK ){
|
||||
@@ -3589,12 +3566,34 @@ static sqlite3rbu *openRbuHandle(
|
||||
** update finished. */
|
||||
if( p->rc==SQLITE_OK && p->objiter.zTbl==0 ){
|
||||
p->rc = SQLITE_DONE;
|
||||
}
|
||||
p->eStage = RBU_STAGE_DONE;
|
||||
}else{
|
||||
if( p->rc==SQLITE_OK && pState->eStage==0 && rbuIsVacuum(p) ){
|
||||
rbuCopyPragma(p, "page_size");
|
||||
rbuCopyPragma(p, "auto_vacuum");
|
||||
}
|
||||
|
||||
if( p->rc==SQLITE_OK ){
|
||||
rbuSetupOal(p, pState);
|
||||
}
|
||||
/* Open transactions both databases. The *-oal file is opened or
|
||||
** created at this point. */
|
||||
if( p->rc==SQLITE_OK ){
|
||||
p->rc = sqlite3_exec(db, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg);
|
||||
}
|
||||
|
||||
/* Check if the main database is a zipvfs db. If it is, set the upper
|
||||
** level pager to use "journal_mode=off". This prevents it from
|
||||
** generating a large journal using a temp file. */
|
||||
if( p->rc==SQLITE_OK ){
|
||||
int frc = sqlite3_file_control(db, "main", SQLITE_FCNTL_ZIPVFS, 0);
|
||||
if( frc==SQLITE_OK ){
|
||||
p->rc = sqlite3_exec(
|
||||
db, "PRAGMA journal_mode=off",0,0,&p->zErrmsg);
|
||||
}
|
||||
}
|
||||
|
||||
if( p->rc==SQLITE_OK ){
|
||||
rbuSetupOal(p, pState);
|
||||
}
|
||||
}
|
||||
}else if( p->eStage==RBU_STAGE_MOVE ){
|
||||
/* no-op */
|
||||
}else if( p->eStage==RBU_STAGE_CKPT ){
|
||||
@@ -3761,9 +3760,39 @@ void sqlite3rbu_bp_progress(sqlite3rbu *p, int *pnOne, int *pnTwo){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the current state of the RBU vacuum or update operation.
|
||||
*/
|
||||
int sqlite3rbu_state(sqlite3rbu *p){
|
||||
int aRes[] = {
|
||||
0, SQLITE_RBU_STATE_OAL, SQLITE_RBU_STATE_MOVE,
|
||||
0, SQLITE_RBU_STATE_CHECKPOINT, SQLITE_RBU_STATE_DONE
|
||||
};
|
||||
|
||||
assert( RBU_STAGE_OAL==1 );
|
||||
assert( RBU_STAGE_MOVE==2 );
|
||||
assert( RBU_STAGE_CKPT==4 );
|
||||
assert( RBU_STAGE_DONE==5 );
|
||||
assert( aRes[RBU_STAGE_OAL]==SQLITE_RBU_STATE_OAL );
|
||||
assert( aRes[RBU_STAGE_MOVE]==SQLITE_RBU_STATE_MOVE );
|
||||
assert( aRes[RBU_STAGE_CKPT]==SQLITE_RBU_STATE_CHECKPOINT );
|
||||
assert( aRes[RBU_STAGE_DONE]==SQLITE_RBU_STATE_DONE );
|
||||
|
||||
if( p->rc!=SQLITE_OK && p->rc!=SQLITE_DONE ){
|
||||
return SQLITE_RBU_STATE_ERROR;
|
||||
}else{
|
||||
assert( p->rc!=SQLITE_DONE || p->eStage==RBU_STAGE_DONE );
|
||||
assert( p->eStage==RBU_STAGE_OAL
|
||||
|| p->eStage==RBU_STAGE_MOVE
|
||||
|| p->eStage==RBU_STAGE_CKPT
|
||||
|| p->eStage==RBU_STAGE_DONE
|
||||
);
|
||||
return aRes[p->eStage];
|
||||
}
|
||||
}
|
||||
|
||||
int sqlite3rbu_savestate(sqlite3rbu *p){
|
||||
int rc = p->rc;
|
||||
|
||||
if( rc==SQLITE_DONE ) return SQLITE_OK;
|
||||
|
||||
assert( p->eStage>=RBU_STAGE_OAL && p->eStage<=RBU_STAGE_DONE );
|
||||
|
||||
@@ -474,6 +474,44 @@ sqlite3_int64 sqlite3rbu_progress(sqlite3rbu *pRbu);
|
||||
*/
|
||||
void sqlite3rbu_bp_progress(sqlite3rbu *pRbu, int *pnOne, int *pnTwo);
|
||||
|
||||
/*
|
||||
** Obtain an indication as to the current stage of an RBU update or vacuum.
|
||||
** This function always returns one of the SQLITE_RBU_STATE_XXX constants
|
||||
** defined in this file. Return values should be interpreted as follows:
|
||||
**
|
||||
** SQLITE_RBU_STATE_OAL:
|
||||
** RBU is currently building a *-oal file. The next call to sqlite3rbu_step()
|
||||
** may either add further data to the *-oal file, or compute data that will
|
||||
** be added by a subsequent call.
|
||||
**
|
||||
** SQLITE_RBU_STATE_MOVE:
|
||||
** RBU has finished building the *-oal file. The next call to sqlite3rbu_step()
|
||||
** will move the *-oal file to the equivalent *-wal path. If the current
|
||||
** operation is an RBU update, then the updated version of the database
|
||||
** file will become visible to ordinary SQLite clients following the next
|
||||
** call to sqlite3rbu_step().
|
||||
**
|
||||
** SQLITE_RBU_STATE_CHECKPOINT:
|
||||
** RBU is currently performing an incremental checkpoint. The next call to
|
||||
** sqlite3rbu_step() will copy a page of data from the *-wal file into
|
||||
** the target database file.
|
||||
**
|
||||
** SQLITE_RBU_STATE_DONE:
|
||||
** The RBU operation has finished. Any subsequent calls to sqlite3rbu_step()
|
||||
** will immediately return SQLITE_DONE.
|
||||
**
|
||||
** SQLITE_RBU_STATE_ERROR:
|
||||
** An error has occurred. Any subsequent calls to sqlite3rbu_step() will
|
||||
** immediately return the SQLite error code associated with the error.
|
||||
*/
|
||||
#define SQLITE_RBU_STATE_OAL 1
|
||||
#define SQLITE_RBU_STATE_MOVE 2
|
||||
#define SQLITE_RBU_STATE_CHECKPOINT 3
|
||||
#define SQLITE_RBU_STATE_DONE 4
|
||||
#define SQLITE_RBU_STATE_ERROR 5
|
||||
|
||||
int sqlite3rbu_state(sqlite3rbu *pRbu);
|
||||
|
||||
/*
|
||||
** Create an RBU VFS named zName that accesses the underlying file-system
|
||||
** via existing VFS zParent. Or, if the zParent parameter is passed NULL,
|
||||
|
||||
@@ -69,6 +69,8 @@ static int test_sqlite3rbu_cmd(
|
||||
{"dbMain_eval", 3, "SQL"}, /* 4 */
|
||||
{"bp_progress", 2, ""}, /* 5 */
|
||||
{"db", 3, "RBU"}, /* 6 */
|
||||
{"state", 2, ""}, /* 7 */
|
||||
{"progress", 2, ""}, /* 8 */
|
||||
{0,0,0}
|
||||
};
|
||||
int iCmd;
|
||||
@@ -166,6 +168,18 @@ static int test_sqlite3rbu_cmd(
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 7: /* state */ {
|
||||
const char *aRes[] = { 0, "oal", "move", "checkpoint", "done", "error" };
|
||||
int eState = sqlite3rbu_state(pRbu);
|
||||
assert( eState>0 && eState<=5 );
|
||||
Tcl_SetResult(interp, (char*)aRes[eState], TCL_STATIC);
|
||||
break;
|
||||
}
|
||||
case 8: /* progress */ {
|
||||
sqlite3_int64 nStep = sqlite3rbu_progress(pRbu);
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(nStep));
|
||||
break;
|
||||
}
|
||||
|
||||
default: /* seems unlikely */
|
||||
assert( !"cannot happen" );
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef SQLITE_AMALGAMATION
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
|
||||
sqlrr - 10/19/2009
|
||||
|
||||
SQL Replay Recording
|
||||
|
||||
SUMMARY
|
||||
-------------------------------------------------------
|
||||
This extension enables recording sqlite API calls that access the database so that they can be replayed or examined.
|
||||
|
||||
USAGE
|
||||
------------------------------------------------------
|
||||
Recording is enabled by compiling sqlite with symbolic constant SQLITE_ENABLE_SQLRR defined.
|
||||
By default logs are written to /tmp/<databasename>_<pid>_<connection_number>.sqlrr, to choose another directory, set the environment variable SQLITE_REPLAY_RECORD_DIR to that path.
|
||||
|
||||
FILE FORMAT
|
||||
-----------------------------------------------------
|
||||
file: <header>[<sql-command>]*
|
||||
|
||||
header: <signature><format-version>
|
||||
signature: SQLRR (5 bytes)
|
||||
format-version: n (1 byte)
|
||||
|
||||
sql-command: <timestamp><type><arg-data>
|
||||
timestamp: n (16 bytes)
|
||||
type: n (1 byte)
|
||||
open 0
|
||||
close 1
|
||||
exec 8
|
||||
bind-text 16
|
||||
bind-double 17
|
||||
bind-int 18
|
||||
bind-null 19
|
||||
bind-value 20
|
||||
bind-clear 21
|
||||
prep 32
|
||||
step 33
|
||||
reset 34
|
||||
finalize 35
|
||||
|
||||
open-arg-data: <connection><path><flags>
|
||||
close-arg-data: <connection>
|
||||
exec-arg-data: <connection><len><statement-text>
|
||||
bind-text-arg-data: <statement-ref><index><len><data>
|
||||
bind-double-arg-data: <statement-ref><index><data>
|
||||
bind-int-arg-data: <statement-ref><index><data>
|
||||
bind-null-arg-data: <statement-ref><index>
|
||||
bind-value-arg-data: <statement-ref><index><len><data> ???
|
||||
bind-clear-arg-data: <statement-ref>
|
||||
prep-arg-data: <connection><len><statement-text>
|
||||
step-arg-data: <statement-ref>
|
||||
reset-arg-data: <statement-ref>
|
||||
finalize-arg-data: <statement-ref>
|
||||
|
||||
NOTES
|
||||
@@ -0,0 +1,581 @@
|
||||
/*
|
||||
* sqlrr.c
|
||||
*/
|
||||
|
||||
#include "sqlrr.h"
|
||||
|
||||
#if defined(SQLITE_ENABLE_SQLRR)
|
||||
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/param.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <libkern/OSAtomic.h>
|
||||
|
||||
#include "sqliteInt.h"
|
||||
#include "vdbeInt.h"
|
||||
|
||||
#define LOGSUFFIXLEN 48
|
||||
|
||||
/*
|
||||
* Data types
|
||||
*/
|
||||
typedef struct SRRLogRef SRRLogRef;
|
||||
struct SRRLogRef {
|
||||
int fd;
|
||||
sqlite3 *db;
|
||||
const char *dbPath;
|
||||
char *logPath;
|
||||
int connection;
|
||||
int depth;
|
||||
SRRLogRef *nextRef;
|
||||
};
|
||||
|
||||
/*
|
||||
* Globals
|
||||
*/
|
||||
SRRLogRef *logRefHead = NULL;
|
||||
int dbLogCount = 0;
|
||||
static int srr_enabled = 1;
|
||||
pthread_mutex_t srr_log_mutex;
|
||||
static volatile int32_t srr_initialized = 0;
|
||||
|
||||
/*
|
||||
* Log management
|
||||
*/
|
||||
extern void SRRecInitialize() {
|
||||
int go = OSAtomicCompareAndSwap32Barrier(0, 1, &srr_initialized);
|
||||
if( go ){
|
||||
pthread_mutex_init(&srr_log_mutex, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static SRRLogRef *createLog(sqlite3 *db, const char *dbPath) {
|
||||
SRRLogRef *ref = NULL;
|
||||
char *baseDir = getenv("SQLITE_REPLAY_RECORD_DIR");
|
||||
char logPath[MAXPATHLEN] = "";
|
||||
char suffix[LOGSUFFIXLEN] = "";
|
||||
const char *dbName = dbPath;
|
||||
int len = 0;
|
||||
int index = 0;
|
||||
int fd = -1;
|
||||
size_t out;
|
||||
unsigned char version = SRR_FILE_VERSION;
|
||||
|
||||
SRRecInitialize();
|
||||
|
||||
/* construct the path for the log file
|
||||
* ${SQLITE_REPLAY_DIR}/<dbname>_<pid>_<connection_number>.sqlrr
|
||||
*/
|
||||
if (baseDir == NULL) {
|
||||
baseDir = "/tmp"; /* getenv(TMPDIR) */
|
||||
}
|
||||
len = strlen(baseDir);
|
||||
strlcat(logPath, baseDir, MAXPATHLEN);
|
||||
if ((len>0) && (baseDir[len-1] != '/')) {
|
||||
strlcat(logPath, "/", MAXPATHLEN);
|
||||
}
|
||||
len = strlen(dbPath);
|
||||
for (index = len-2; index >= 0; index --){
|
||||
if (dbPath[index] == '/') {
|
||||
dbName = &dbPath[index+1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
strlcat(logPath, dbName, MAXPATHLEN);
|
||||
int cNum = ++dbLogCount;
|
||||
snprintf(suffix, sizeof(suffix), "_%d_%d_XXXX.sqlrr", getpid(), cNum);
|
||||
len = strlcat(logPath, suffix, MAXPATHLEN);
|
||||
/* make it unique if we have the space */
|
||||
if ((len + 1) < MAXPATHLEN) {
|
||||
fd = mkstemps(logPath, 6);
|
||||
} else {
|
||||
fprintf(stderr, "Failed to create sqlite replay log path for %s [%s]\n", dbPath, logPath);
|
||||
return NULL;
|
||||
}
|
||||
if (fd == -1) {
|
||||
fprintf(stderr, "Failed to create sqlite replay log file for %s with path %s [%s]\n", dbPath, logPath, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
fprintf(stdout, "Writing sqlite replay log file %s\n", logPath);
|
||||
out = write(fd, SRR_FILE_SIGNATURE, SRR_FILE_SIGNATURE_LEN);
|
||||
if (out!=-1) {
|
||||
out = write(fd, &version, 1);
|
||||
}
|
||||
if (out == -1){
|
||||
fprintf(stderr, "Write failure on log [%s]: %s\n", logPath, strerror(errno));
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len = strlen(logPath) + 1;
|
||||
ref = (SRRLogRef *)malloc(sizeof(SRRLogRef));
|
||||
|
||||
ref->db = db;
|
||||
ref->dbPath = dbPath;
|
||||
ref->logPath = (char *)malloc(len * sizeof(char));
|
||||
strlcpy(ref->logPath, logPath, len);
|
||||
ref->fd = fd;
|
||||
ref->connection = cNum;
|
||||
ref->depth = 0;
|
||||
|
||||
pthread_mutex_lock(&srr_log_mutex);
|
||||
ref->nextRef = logRefHead;
|
||||
logRefHead = ref;
|
||||
pthread_mutex_unlock(&srr_log_mutex);
|
||||
return ref;
|
||||
}
|
||||
|
||||
static void closeLog(sqlite3 *db) {
|
||||
SRRLogRef *ref = NULL;
|
||||
SRRLogRef *lastRef = NULL;
|
||||
|
||||
pthread_mutex_lock(&srr_log_mutex);
|
||||
for (ref = logRefHead; ref != NULL; ref = ref->nextRef) {
|
||||
if (ref->db == db) {
|
||||
if (lastRef == NULL) {
|
||||
logRefHead = ref->nextRef;
|
||||
} else {
|
||||
lastRef->nextRef = ref->nextRef;
|
||||
}
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&srr_log_mutex);
|
||||
|
||||
if (ref != NULL) {
|
||||
fprintf(stdout, "Closing sqlite replay log file %s\n", ref->logPath);
|
||||
close(ref->fd);
|
||||
free(ref->logPath);
|
||||
free(ref);
|
||||
}
|
||||
}
|
||||
|
||||
static SRRLogRef *getLog(sqlite3 *db) {
|
||||
pthread_mutex_lock(&srr_log_mutex);
|
||||
SRRLogRef *ref = logRefHead;
|
||||
for (ref = logRefHead; ref != NULL; ref = ref->nextRef) {
|
||||
if (ref->db == db) {
|
||||
pthread_mutex_unlock(&srr_log_mutex);
|
||||
return ref;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&srr_log_mutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* SQLite recording API
|
||||
*/
|
||||
void SQLiteReplayRecorder(int flag) {
|
||||
srr_enabled = flag;
|
||||
}
|
||||
|
||||
// open-arg-data: <connection><len><path><flags>
|
||||
void _SRRecOpen(sqlite3 *db, const char *path, int flags) {
|
||||
if (!srr_enabled) return;
|
||||
if (db) {
|
||||
SRRLogRef *ref = createLog(db, path);
|
||||
if (ref) {
|
||||
SRRCommand code = SRROpen;
|
||||
int len = strlen(path);
|
||||
struct timeval tv;
|
||||
size_t out;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
out = write(ref->fd, &tv, sizeof(tv));
|
||||
if (out!=-1) { out=write(ref->fd, &code, sizeof(SRRCommand)); }
|
||||
if (out!=-1) { out=write(ref->fd, &(ref->connection), sizeof(ref->connection)); }
|
||||
if (out!=-1) { out=write(ref->fd, &len, sizeof(len)); }
|
||||
if (out!=-1) { out=write(ref->fd, path, len); }
|
||||
if (out!=-1) { out=write(ref->fd, &flags, sizeof(flags)); }
|
||||
if (out==-1) {
|
||||
fprintf(stderr, "Error writing open to log file [%s]: %s\n", ref->logPath, strerror(errno));
|
||||
closeLog(db);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//close-arg-data: <connection>
|
||||
void SRRecClose(sqlite3 *db) {
|
||||
if (!srr_enabled) return;
|
||||
if (db) {
|
||||
SRRLogRef *ref = getLog(db);
|
||||
if (ref) {
|
||||
SRRCommand code = SRRClose;
|
||||
struct timeval tv;
|
||||
size_t out;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
out = write(ref->fd, &tv, sizeof(tv));
|
||||
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
|
||||
if (out!=-1) { out = write(ref->fd, &(ref->connection), sizeof(ref->connection)); }
|
||||
if (out==-1) {
|
||||
fprintf(stderr, "Error writing close to log file [%s]: %s\n", ref->logPath, strerror(errno));
|
||||
}
|
||||
closeLog(db);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// exec-arg-data: <connection><len><statement-text>
|
||||
void SRRecExec(sqlite3 *db, const char *sql) {
|
||||
if (!srr_enabled) return;
|
||||
if (db) {
|
||||
SRRLogRef *ref = getLog(db);
|
||||
if (ref) {
|
||||
if (ref->depth == 0) {
|
||||
SRRCommand code = SRRExec;
|
||||
int len = strlen(sql);
|
||||
struct timeval tv;
|
||||
size_t out;
|
||||
|
||||
ref->depth = 1;
|
||||
gettimeofday(&tv, NULL);
|
||||
out = write(ref->fd, &tv, sizeof(tv));
|
||||
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
|
||||
if (out!=-1) { out = write(ref->fd, &(ref->connection), sizeof(ref->connection)); }
|
||||
if (out!=-1) { out = write(ref->fd, &len, sizeof(len)); }
|
||||
if (out!=-1) { out = write(ref->fd, sql, len); }
|
||||
if (out==-1) {
|
||||
fprintf(stderr, "Error writing exec to log file [%s]: %s\n", ref->logPath, strerror(errno));
|
||||
closeLog(db);
|
||||
}
|
||||
} else {
|
||||
ref->depth ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SRRecExecEnd(sqlite3 *db) {
|
||||
if (!srr_enabled) return;
|
||||
if (db) {
|
||||
SRRLogRef *ref = getLog(db);
|
||||
if (ref) {
|
||||
ref->depth --;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// prep-arg-data: <connection><len><statement-text><savesql><statement-ref>
|
||||
void _SRRecPrepare(sqlite3 *db, const char *sql, int nBytes, int saveSql, sqlite3_stmt *pStmt) {
|
||||
if (!srr_enabled) return;
|
||||
if ((db!=NULL)&&(pStmt!=NULL)) {
|
||||
SRRLogRef *ref = getLog(db);
|
||||
if (ref && (ref->depth == 0)) {
|
||||
SRRCommand code = SRRPrepare;
|
||||
struct timeval tv;
|
||||
size_t out;
|
||||
int sqlLen = nBytes;
|
||||
|
||||
if (sqlLen == -1) {
|
||||
sqlLen = strlen(sql);
|
||||
}
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
out = write(ref->fd, &tv, sizeof(tv));
|
||||
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
|
||||
if (out!=-1) { out = write(ref->fd, &(ref->connection), sizeof(ref->connection)); }
|
||||
if (out!=-1) { out = write(ref->fd, &sqlLen, sizeof(sqlLen)); }
|
||||
if (out!=-1) { out = write(ref->fd, sql, sqlLen); }
|
||||
if (out!=-1) { out = write(ref->fd, &saveSql, sizeof(saveSql)); }
|
||||
if (out!=-1) {
|
||||
int64_t stmtInt = (int64_t)((intptr_t)(pStmt));
|
||||
out = write(ref->fd, &stmtInt, sizeof(int64_t));
|
||||
}
|
||||
if (out==-1) {
|
||||
fprintf(stderr, "Error writing prepare to log file [%s]: %s\n", ref->logPath, strerror(errno));
|
||||
closeLog(db);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//step-arg-data: <statement-ref>
|
||||
void SRRecStep(sqlite3_stmt *pStmt) {
|
||||
if (!srr_enabled) return;
|
||||
if(pStmt!=NULL) {
|
||||
Vdbe *v = (Vdbe *)pStmt;
|
||||
SRRLogRef *ref = getLog(v->db);
|
||||
if (ref) {
|
||||
if (ref->depth == 0) {
|
||||
SRRCommand code = SRRStep;
|
||||
struct timeval tv;
|
||||
size_t out;
|
||||
|
||||
ref->depth = 1;
|
||||
gettimeofday(&tv, NULL);
|
||||
out = write(ref->fd, &tv, sizeof(tv));
|
||||
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
|
||||
if (out!=-1) {
|
||||
int64_t stmtInt = (int64_t)((intptr_t)(pStmt));
|
||||
out = write(ref->fd, &stmtInt, sizeof(int64_t));
|
||||
}
|
||||
if (out==-1) {
|
||||
fprintf(stderr, "Error writing step to log file [%s]: %s\n", ref->logPath, strerror(errno));
|
||||
closeLog(ref->db);
|
||||
}
|
||||
} else {
|
||||
ref->depth ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SRRecStepEnd(sqlite3_stmt *pStmt) {
|
||||
if (!srr_enabled) return;
|
||||
if(pStmt!=NULL) {
|
||||
Vdbe *v = (Vdbe *)pStmt;
|
||||
SRRLogRef *ref = getLog(v->db);
|
||||
if (ref) {
|
||||
ref->depth --;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// reset-arg-data: <statement-ref>
|
||||
void SRRecReset(sqlite3_stmt *pStmt) {
|
||||
if (!srr_enabled) return;
|
||||
if(pStmt!=NULL) {
|
||||
Vdbe *v = (Vdbe *)pStmt;
|
||||
SRRLogRef *ref = getLog(v->db);
|
||||
if (ref && (ref->depth == 0)) {
|
||||
SRRCommand code = SRRReset;
|
||||
struct timeval tv;
|
||||
size_t out;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
out = write(ref->fd, &tv, sizeof(tv));
|
||||
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
|
||||
if (out!=-1) {
|
||||
int64_t stmtInt = (int64_t)((intptr_t)(pStmt));
|
||||
out = write(ref->fd, &stmtInt, sizeof(int64_t));
|
||||
}
|
||||
if (out==-1) {
|
||||
fprintf(stderr, "Error writing reset to log file [%s]: %s\n", ref->logPath, strerror(errno));
|
||||
closeLog(ref->db);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// finalize-arg-data: <statement-ref>
|
||||
void SRRecFinalize(sqlite3_stmt *pStmt) {
|
||||
if (!srr_enabled) return;
|
||||
if(pStmt!=NULL) {
|
||||
Vdbe *v = (Vdbe *)pStmt;
|
||||
SRRLogRef *ref = getLog(v->db);
|
||||
if (ref && (ref->depth == 0)) {
|
||||
SRRCommand code = SRRFinalize;
|
||||
struct timeval tv;
|
||||
size_t out;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
out = write(ref->fd, &tv, sizeof(tv));
|
||||
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
|
||||
if (out!=-1) {
|
||||
int64_t stmtInt = (int64_t)((intptr_t)(pStmt));
|
||||
out = write(ref->fd, &stmtInt, sizeof(int64_t));
|
||||
}
|
||||
if (out==-1) {
|
||||
fprintf(stderr, "Error writing finalize to log file [%s]: %s\n", ref->logPath, strerror(errno));
|
||||
closeLog(ref->db);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// bind-text-arg-data: <statement-ref><index><len><data>
|
||||
void SRRecBindText(sqlite3_stmt *pStmt, int i, const char *zData, int64_t nData) {
|
||||
if (!srr_enabled) return;
|
||||
if(pStmt!=NULL) {
|
||||
Vdbe *v = (Vdbe *)pStmt;
|
||||
SRRLogRef *ref = getLog(v->db);
|
||||
if (ref && (ref->depth == 0)) {
|
||||
SRRCommand code = SRRBindText;
|
||||
struct timeval tv;
|
||||
size_t out;
|
||||
int64_t textLen = nData;
|
||||
if (textLen == -1) {
|
||||
textLen = strlen(zData);
|
||||
}
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
out = write(ref->fd, &tv, sizeof(tv));
|
||||
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
|
||||
if (out!=-1) {
|
||||
int64_t stmtInt = (int64_t)((intptr_t)(pStmt));
|
||||
out = write(ref->fd, &stmtInt, sizeof(int64_t));
|
||||
}
|
||||
if (out!=-1) { out = write(ref->fd, &i, sizeof(i)); }
|
||||
if (out!=-1) { out = write(ref->fd, &textLen, sizeof(textLen)); }
|
||||
if (out!=-1) { out = write(ref->fd, zData, textLen); }
|
||||
if (out==-1) {
|
||||
fprintf(stderr, "Error writing bind text to log file [%s]: %s\n", ref->logPath, strerror(errno));
|
||||
closeLog(ref->db);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// bind-blob-arg-data: <statement-ref><index><len>[<data>]
|
||||
void SRRecBindBlob(sqlite3_stmt *pStmt, int i, const char *zData, int64_t nData) {
|
||||
if (!srr_enabled) return;
|
||||
if(pStmt!=NULL) {
|
||||
Vdbe *v = (Vdbe *)pStmt;
|
||||
SRRLogRef *ref = getLog(v->db);
|
||||
if (ref && (ref->depth == 0)) {
|
||||
SRRCommand code = SRRBindBlob;
|
||||
struct timeval tv;
|
||||
size_t out;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
out = write(ref->fd, &tv, sizeof(tv));
|
||||
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
|
||||
if (out!=-1) {
|
||||
int64_t stmtInt = (int64_t)((intptr_t)(pStmt));
|
||||
out = write(ref->fd, &stmtInt, sizeof(int64_t));
|
||||
}
|
||||
if (out!=-1) { out = write(ref->fd, &i, sizeof(i)); }
|
||||
if (zData == NULL) {
|
||||
int64_t negNData = -nData;
|
||||
if (out!=-1) { out = write(ref->fd, &negNData, sizeof(negNData)); }
|
||||
} else {
|
||||
if (out!=-1) { out = write(ref->fd, &nData, sizeof(nData)); }
|
||||
if (out!=-1) { out = write(ref->fd, zData, nData); }
|
||||
}
|
||||
if (out==-1) {
|
||||
fprintf(stderr, "Error writing bind blob to log file [%s]: %s\n", ref->logPath, strerror(errno));
|
||||
closeLog(ref->db);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// bind-double-arg-data: <statement-ref><index><data>
|
||||
void SRRecBindDouble(sqlite3_stmt *pStmt, int i, double value) {
|
||||
if (!srr_enabled) return;
|
||||
if(pStmt!=NULL) {
|
||||
Vdbe *v = (Vdbe *)pStmt;
|
||||
SRRLogRef *ref = getLog(v->db);
|
||||
if (ref && (ref->depth == 0)) {
|
||||
SRRCommand code = SRRBindDouble;
|
||||
struct timeval tv;
|
||||
size_t out;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
out = write(ref->fd, &tv, sizeof(tv));
|
||||
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
|
||||
if (out!=-1) {
|
||||
int64_t stmtInt = (int64_t)((intptr_t)(pStmt));
|
||||
out = write(ref->fd, &stmtInt, sizeof(int64_t));
|
||||
}
|
||||
if (out!=-1) { out = write(ref->fd, &i, sizeof(i)); }
|
||||
if (out!=-1) { out = write(ref->fd, &value, sizeof(value)); }
|
||||
if (out==-1) {
|
||||
fprintf(stderr, "Error writing bind double to log file [%s]: %s\n", ref->logPath, strerror(errno));
|
||||
closeLog(ref->db);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// bind-int-arg-data: <statement-ref><index><data>
|
||||
void SRRecBindInt64(sqlite3_stmt *pStmt, int i, int64_t value) {
|
||||
if (!srr_enabled) return;
|
||||
if(pStmt!=NULL) {
|
||||
Vdbe *v = (Vdbe *)pStmt;
|
||||
SRRLogRef *ref = getLog(v->db);
|
||||
if (ref && (ref->depth == 0)) {
|
||||
SRRCommand code = SRRBindInt;
|
||||
struct timeval tv;
|
||||
size_t out;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
out = write(ref->fd, &tv, sizeof(tv));
|
||||
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
|
||||
if (out!=-1) {
|
||||
int64_t stmtInt = (int64_t)((intptr_t)(pStmt));
|
||||
out = write(ref->fd, &stmtInt, sizeof(int64_t));
|
||||
}
|
||||
if (out!=-1) { out = write(ref->fd, &i, sizeof(i)); }
|
||||
if (out!=-1) { out = write(ref->fd, &value, sizeof(value)); }
|
||||
if (out==-1) {
|
||||
fprintf(stderr, "Error writing bind int to log file [%s]: %s\n", ref->logPath, strerror(errno));
|
||||
closeLog(ref->db);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// bind-null-arg-data: <statement-ref><index>
|
||||
void SRRecBindNull(sqlite3_stmt *pStmt, int i) {
|
||||
if (!srr_enabled) return;
|
||||
if(pStmt!=NULL) {
|
||||
Vdbe *v = (Vdbe *)pStmt;
|
||||
SRRLogRef *ref = getLog(v->db);
|
||||
if (ref && (ref->depth == 0)) {
|
||||
SRRCommand code = SRRBindNull;
|
||||
struct timeval tv;
|
||||
size_t out;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
out = write(ref->fd, &tv, sizeof(tv));
|
||||
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
|
||||
if (out!=-1) {
|
||||
int64_t stmtInt = (int64_t)((intptr_t)(pStmt));
|
||||
out = write(ref->fd, &stmtInt, sizeof(int64_t));
|
||||
}
|
||||
if (out!=-1) { out = write(ref->fd, &i, sizeof(i)); }
|
||||
if (out==-1) {
|
||||
fprintf(stderr, "Error writing bind null to log file [%s]: %s\n", ref->logPath, strerror(errno));
|
||||
closeLog(ref->db);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// bind-value-arg-data: <statement-ref><index><len><data> ???
|
||||
void SRRecBindValue(sqlite3_stmt *pStmt, int i, const sqlite3_value *value) {
|
||||
if (!srr_enabled) return;
|
||||
if(pStmt!=NULL) {
|
||||
Vdbe *v = (Vdbe *)pStmt;
|
||||
SRRLogRef *ref = getLog(v->db);
|
||||
if (ref && (ref->depth == 0)) {
|
||||
fprintf(stderr, "SRRecBindValue(sqlite3_bind_value) is not yet supported, closing [%s]: %s\n", ref->logPath, strerror(errno));
|
||||
closeLog(ref->db);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// bind-clear-arg-data: <statement-ref>
|
||||
void SRRecClearBindings(sqlite3_stmt *pStmt) {
|
||||
if (!srr_enabled) return;
|
||||
if(pStmt!=NULL) {
|
||||
Vdbe *v = (Vdbe *)pStmt;
|
||||
SRRLogRef *ref = getLog(v->db);
|
||||
if (ref && (ref->depth == 0)) {
|
||||
SRRCommand code = SRRBindClear;
|
||||
struct timeval tv;
|
||||
size_t out;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
out = write(ref->fd, &tv, sizeof(tv));
|
||||
if (out!=-1) { out = write(ref->fd, &code, sizeof(SRRCommand)); }
|
||||
if (out!=-1) {
|
||||
int64_t stmtInt = (int64_t)((intptr_t)(pStmt));
|
||||
out = write(ref->fd, &stmtInt, sizeof(int64_t));
|
||||
}
|
||||
if (out==-1) {
|
||||
fprintf(stderr, "Error writing clear bindings to log file [%s]: %s\n", ref->logPath, strerror(errno));
|
||||
closeLog(ref->db);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SQLITE_ENABLE_SQLRR */
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* sqlrr.h
|
||||
*/
|
||||
|
||||
#ifndef _SQLRR_H_
|
||||
#define _SQLRR_H_
|
||||
|
||||
/*
|
||||
** Header constants
|
||||
*/
|
||||
#define SRR_FILE_SIGNATURE "SQLRR"
|
||||
#define SRR_FILE_SIGNATURE_LEN 5
|
||||
#define SRR_FILE_VERSION 0x1
|
||||
#define SRR_FILE_VERSION_LEN 1
|
||||
|
||||
#if defined(SQLITE_ENABLE_SQLRR)
|
||||
|
||||
#include "sqlite3.h"
|
||||
#include <sys/types.h>
|
||||
|
||||
#define SRRecOpen(A,B,C) if(!rc){_SRRecOpen(A,B,C);}
|
||||
#define SRRecPrepare(A,B,C,D,E) if(!rc){_SRRecPrepare(A,B,C,D,E);}
|
||||
|
||||
typedef enum {
|
||||
SRROpen = 0,
|
||||
SRRClose = 1,
|
||||
SRRExec = 8,
|
||||
SRRBindText = 16,
|
||||
SRRBindBlob = 17,
|
||||
SRRBindDouble = 18,
|
||||
SRRBindInt = 19,
|
||||
SRRBindNull = 20,
|
||||
SRRBindValue = 21,
|
||||
SRRBindClear = 22,
|
||||
SRRPrepare = 32,
|
||||
SRRStep = 33,
|
||||
SRRReset = 34,
|
||||
SRRFinalize = 35
|
||||
} SRRCommand;
|
||||
|
||||
extern void SQLiteReplayRecorder(int flag);
|
||||
extern void _SRRecOpen(sqlite3 *db, const char *path, int flags);
|
||||
extern void SRRecClose(sqlite3 *db);
|
||||
extern void SRRecExec(sqlite3 *db, const char *sql);
|
||||
extern void SRRecExecEnd(sqlite3 *db);
|
||||
extern void _SRRecPrepare(sqlite3 *db, const char *sql, int nBytes, int saveSql, sqlite3_stmt *stmt);
|
||||
extern void SRRecStep(sqlite3_stmt *pStmt);
|
||||
extern void SRRecStepEnd(sqlite3_stmt *pStmt);
|
||||
extern void SRRecReset(sqlite3_stmt *pStmt);
|
||||
extern void SRRecFinalize(sqlite3_stmt *pStmt);
|
||||
extern void SRRecBindText(sqlite3_stmt *pStmt, int i, const char *zData, int64_t nData);
|
||||
extern void SRRecBindBlob(sqlite3_stmt *pStmt, int i, const char *zData, int64_t nData);
|
||||
extern void SRRecBindDouble(sqlite3_stmt *pStmt, int i, double value);
|
||||
extern void SRRecBindInt64(sqlite3_stmt *pStmt, int i, int64_t value);
|
||||
extern void SRRecBindNull(sqlite3_stmt *pStmt, int i);
|
||||
extern void SRRecBindValue(sqlite3_stmt *pStmt, int i, const sqlite3_value *value);
|
||||
extern void SRRecClearBindings(sqlite3_stmt *pStmt);
|
||||
|
||||
#endif /* defined(SQLITE_ENABLE_SQLRR) */
|
||||
|
||||
#endif /* _SQLRR_H_ */
|
||||
@@ -224,6 +224,9 @@ SRC += \
|
||||
$(TOP)/ext/rtree/sqlite3rtree.h \
|
||||
$(TOP)/ext/rtree/rtree.h \
|
||||
$(TOP)/ext/rtree/rtree.c
|
||||
SRC += \
|
||||
$(TOP)/ext/sqlrr/sqlrr.h \
|
||||
$(TOP)/ext/sqlrr/sqlrr.c
|
||||
SRC += \
|
||||
$(TOP)/ext/session/sqlite3session.c \
|
||||
$(TOP)/ext/session/sqlite3session.h
|
||||
@@ -324,6 +327,7 @@ TESTSRC = \
|
||||
#
|
||||
TESTSRC += \
|
||||
$(TOP)/ext/misc/amatch.c \
|
||||
$(TOP)/ext/misc/carray.c \
|
||||
$(TOP)/ext/misc/closure.c \
|
||||
$(TOP)/ext/misc/csv.c \
|
||||
$(TOP)/ext/misc/eval.c \
|
||||
@@ -422,22 +426,7 @@ HDR = \
|
||||
# Header files used by extensions
|
||||
#
|
||||
EXTHDR += \
|
||||
$(TOP)/ext/fts1/fts1.h \
|
||||
$(TOP)/ext/fts1/fts1_hash.h \
|
||||
$(TOP)/ext/fts1/fts1_tokenizer.h
|
||||
EXTHDR += \
|
||||
$(TOP)/ext/fts2/fts2.h \
|
||||
$(TOP)/ext/fts2/fts2_hash.h \
|
||||
$(TOP)/ext/fts2/fts2_tokenizer.h
|
||||
EXTHDR += \
|
||||
$(TOP)/ext/fts3/fts3.h \
|
||||
$(TOP)/ext/fts3/fts3Int.h \
|
||||
$(TOP)/ext/fts3/fts3_hash.h \
|
||||
$(TOP)/ext/fts3/fts3_tokenizer.h
|
||||
EXTHDR += \
|
||||
$(TOP)/ext/rtree/rtree.h
|
||||
EXTHDR += \
|
||||
$(TOP)/ext/icu/sqliteicu.h
|
||||
$(TOP)/ext/sqlrr/sqlrr.h
|
||||
EXTHDR += \
|
||||
$(TOP)/ext/fts5/fts5Int.h \
|
||||
fts5parse.h \
|
||||
@@ -469,6 +458,8 @@ TESTOPTS = --verbose=file --output=test-out.txt
|
||||
# Extra compiler options for various shell tools
|
||||
#
|
||||
SHELL_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
|
||||
SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
|
||||
SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
|
||||
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
|
||||
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
|
||||
|
||||
@@ -537,10 +528,10 @@ sqlite3.o: sqlite3.c
|
||||
# files are automatically generated. This target takes care of
|
||||
# all that automatic generation.
|
||||
#
|
||||
target_source: $(SRC) $(TOP)/tool/vdbe-compress.tcl fts5.c
|
||||
target_source: $(SRC) $(EXTHDR) $(TOP)/tool/vdbe-compress.tcl fts5.c
|
||||
rm -rf tsrc
|
||||
mkdir tsrc
|
||||
cp -f $(SRC) tsrc
|
||||
cp -f $(SRC) $(EXTHDR) tsrc
|
||||
rm tsrc/sqlite.h.in tsrc/parse.y
|
||||
tclsh $(TOP)/tool/vdbe-compress.tcl $(OPTS) <tsrc/vdbe.c >vdbe.new
|
||||
mv vdbe.new tsrc/vdbe.c
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
C Fix\san\sundersized\sbuffer\sin\sthe\sSHA1\simplementation.
|
||||
D 2016-06-08T13:59:35.817
|
||||
F Makefile.in f3f7d2060ce03af4584e711ef3a626ef0b1d6340
|
||||
C Add\san\sexperimental\sSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION\scompile-time\soption.\nWhen\senabled,\sthe\s"unknown\sfunction"\serror\sis\ssuppressed\sfor\sEXPLAIN\sand\na\sno-op\sfunction\snamed\s"unknown"\sis\ssubstituted.\s\sThis\sfacilitiates\susing\nthe\scommand-line\sshell\sto\sanalyze\squeries\sfrom\sapplications\sthat\scontain\nmany\sapplication-defined\sfunctions\sthat\sare\snot\snormally\savailable\sto\sthe\nshell.
|
||||
D 2016-08-04T01:47:01.678
|
||||
F Makefile.in b0c3cd9e30ffb18d6952dbf3c2ee5ae07c6216d4
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc 50149765ef72f4e652b9a0f1f6462c4784bb9423
|
||||
F Makefile.msc c5b2eca5bdf5f73fe9eebf78f07755e2509fd629
|
||||
F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7
|
||||
F VERSION cb29eb11e493dd85b3eeec4053c03949bf98478e
|
||||
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
||||
@@ -30,8 +30,8 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
|
||||
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
|
||||
F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc
|
||||
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
|
||||
F configure 25cf7eb52a88846e4c1978016a9db22763c54f41 x
|
||||
F configure.ac 480e1a17d5316b1751c8edcb15b8e6b8ab0a6cc3
|
||||
F configure 35ce04a15ca046262bf9baaa2ced9337708cc653 x
|
||||
F configure.ac b5d3df43161374f8dffd2e5f4b88fbb51685b975
|
||||
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
||||
F doc/lemon.html e2118945e5f07ed146b45c9cd2b2dd6eabb8ebf2
|
||||
F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710
|
||||
@@ -106,7 +106,7 @@ F ext/fts5/fts5_expr.c bcb238ee4ac1164302ab528487520488516bd030
|
||||
F ext/fts5/fts5_hash.c 880998e596b60f078348d48732ca4ad9a90caad2
|
||||
F ext/fts5/fts5_index.c b429e23fabb57506f71e406997cc46b89190dc97
|
||||
F ext/fts5/fts5_main.c f85281445dcf8be32d18841c93a6f90fe27dbfe2
|
||||
F ext/fts5/fts5_storage.c 3309c6a8e34b974513016fd1ef47c83f5898f94c
|
||||
F ext/fts5/fts5_storage.c de0ed8a06738bde433afe11e92295ceaffbc4e58
|
||||
F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966
|
||||
F ext/fts5/fts5_test_mi.c 783b86697ebf773c18fc109992426c0173a055bc
|
||||
F ext/fts5/fts5_test_tok.c db08af63673c3a7d39f053b36fd6e065017706be
|
||||
@@ -176,11 +176,11 @@ F ext/fts5/test/fts5porter.test 7cdc07bef301d70eebbfa75dcaf45c3680e1d0e1
|
||||
F ext/fts5/test/fts5porter2.test 2e65633d58a1c525d5af0f6c01e5a59155bb3487
|
||||
F ext/fts5/test/fts5prefix.test efd42e00bb8e8a36383f25c838185508681c093f
|
||||
F ext/fts5/test/fts5query.test f5ec25f5f2fbb70033424113cdffc101b1985a40
|
||||
F ext/fts5/test/fts5rank.test 3e55e7eeb4c98728e4a3171c9e994e1a2f24eb99
|
||||
F ext/fts5/test/fts5rank.test 2bdc0c5f22ccc1f9dbe9f4d0b82a491dce6f8a32
|
||||
F ext/fts5/test/fts5rebuild.test 03935f617ace91ed23a6099c7c74d905227ff29b
|
||||
F ext/fts5/test/fts5restart.test c17728fdea26e7d0f617d22ad5b4b2862b994c17
|
||||
F ext/fts5/test/fts5rowid.test 16908a99d6efc9ba21081b4f2b86b3fc699839a6
|
||||
F ext/fts5/test/fts5simple.test cd23d4072ea095d652c9b6db12284cc642e49c98
|
||||
F ext/fts5/test/fts5simple.test 5da9b15ed534eb0be9f279d8a2bb2e24d30e4e38
|
||||
F ext/fts5/test/fts5simple2.test 98377ae1ff7749a42c21fe1a139c1ed312522c46
|
||||
F ext/fts5/test/fts5simple3.test 8e71733b3d1b0e695011d02c68ebc5ca40b6124e
|
||||
F ext/fts5/test/fts5synonym.test 6475d189c2e20d60795808f83e36bf9318708d48
|
||||
@@ -204,19 +204,20 @@ F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43
|
||||
F ext/icu/icu.c 43df9d8ef2fae7a325100ebd713ab089dc829dd7
|
||||
F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37
|
||||
F ext/misc/amatch.c 211108e201105e4bb0c076527b8cfd34330fc234
|
||||
F ext/misc/carray.c 40c27641010a4dc67e3690bdb7c9d36ca58b3c2d
|
||||
F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704
|
||||
F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83
|
||||
F ext/misc/csv.c f01126ba170fd4ef7c752b156568a80c912d4441
|
||||
F ext/misc/csv.c 816a3715356e4210dae2d242057745e937050896
|
||||
F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2
|
||||
F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f
|
||||
F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25
|
||||
F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c
|
||||
F ext/misc/json1.c b9c88d5c3b6ecd8c731ffdd7f5b3d902857f8c96
|
||||
F ext/misc/json1.c d51a764ba43a49e191bc3536238bfab3def258ca
|
||||
F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342
|
||||
F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63
|
||||
F ext/misc/regexp.c a68d25c659bd2d893cd1215667bbf75ecb9dc7d4
|
||||
F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a
|
||||
F ext/misc/scrub.c ea0903701e3ac02b4466ce9cffd0325c7ddbfcf0
|
||||
F ext/misc/scrub.c 1c5bfb8b0cd18b602fcb55755e84abf0023ac2fb
|
||||
F ext/misc/series.c e11e534ada797d5b816d7e7a93c022306563ca35
|
||||
F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52
|
||||
F ext/misc/spellfix.c bf1b922c2750698e9a3d4c50cce6974adb7e93be
|
||||
@@ -226,14 +227,14 @@ F ext/misc/vfsstat.c 6110aeeaab2f1df17a923c8a8acef3c74f6dc515
|
||||
F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e
|
||||
F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212
|
||||
F ext/rbu/rbu.c b2c0b5e6ae1a89affc0edfc127ebfa5f637a0ce4
|
||||
F ext/rbu/rbu1.test 42bd835e019eff789ec241017965277baeb658b1
|
||||
F ext/rbu/rbu1.test 43836fac8c7179a358eaf38a8a1ef3d6e6285842
|
||||
F ext/rbu/rbu10.test 046b0980041d30700464a800bbf6733ed2df515d
|
||||
F ext/rbu/rbu11.test 9bc68c2d3dbeb1720153626e3bd0466dcc017702
|
||||
F ext/rbu/rbu12.test bde22ed0004dd5d1888c72a84ae407e574aeae16
|
||||
F ext/rbu/rbu13.test 462ff799c4afedc3ef8a47ff818c0ffbf14ae4f2
|
||||
F ext/rbu/rbu14.test 01f5dcba904aecadbaea69d4ccdc2ea43dd30560
|
||||
F ext/rbu/rbu3.test 8bd4c6b87367c358981b6a47dc3d654fa60bff90
|
||||
F ext/rbu/rbu5.test 2e24fee3e615aecd99bbdd46967935a641e866f7
|
||||
F ext/rbu/rbu5.test cf1fa84d6107efd73e292a7be8e1fb31953ca45c
|
||||
F ext/rbu/rbu6.test 32e8ed60631b6facdb6366bd2b5f5f25245e7edb
|
||||
F ext/rbu/rbu7.test fd025d5ba440fcfe151fbb0e3835e1e7fe964fa1
|
||||
F ext/rbu/rbu8.test 3bbf2c35d71a843c463efe93946f14ad10c3ede0
|
||||
@@ -241,9 +242,9 @@ F ext/rbu/rbu9.test 0806d1772c9f4981774ff028de6656e4183082af
|
||||
F ext/rbu/rbuA.test c1a7b3e2d926b8f8448bb3b4ae787e314ee4b2b3
|
||||
F ext/rbu/rbuB.test c25bc325b8072a766e56bb76c001866b405925c2
|
||||
F ext/rbu/rbuC.test efe47db508a0269b683cb2a1913a425ffd39a831
|
||||
F ext/rbu/rbu_common.tcl 3a4b916b6f5dca9c9da9a30863e272fe5ea4414f
|
||||
F ext/rbu/rbu_common.tcl a38e8e2d4a50fd6aaf151633714c1b1d2fae3ead
|
||||
F ext/rbu/rbucrash.test 8d2ed5d4b05fef6c00c2a6b5f7ead71fa172a695
|
||||
F ext/rbu/rbudiff.test 2df0a8a7d998ecf81764c21eeda3cde5611c5091
|
||||
F ext/rbu/rbudiff.test b3c7675810b81de98a930a87fcd40d9ae545619d
|
||||
F ext/rbu/rbufault.test cc0be8d5d392d98b0c2d6a51be377ea989250a89
|
||||
F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06
|
||||
F ext/rbu/rbufault3.test 54a399888ac4af44c68f9f58afbed23149428bca
|
||||
@@ -252,11 +253,11 @@ F ext/rbu/rbuprogress.test 2023a7df2c523e3df1cb532eff811cda385a789a
|
||||
F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48
|
||||
F ext/rbu/rbuvacuum.test 4a977447c15c2581ab668781d9ef4294382530e0
|
||||
F ext/rbu/rbuvacuum2.test 45009e127c3fb385e5c0fd5a8a63fb922a79d0ab
|
||||
F ext/rbu/sqlite3rbu.c a37a7dfb225c497171aa60120e81b884954361c7
|
||||
F ext/rbu/sqlite3rbu.h 2acd0a6344a6079de15c8dc9d84d3df83a665930
|
||||
F ext/rbu/test_rbu.c 9bbdf6bd8efd58fbc4f192698df50569598fbb9e
|
||||
F ext/rbu/sqlite3rbu.c 948677ee0ec57da51148e6c5f64ac68afcf36ab2
|
||||
F ext/rbu/sqlite3rbu.h db8858120c9be14b60c9225f9da28221f5f6b945
|
||||
F ext/rbu/test_rbu.c 9f043b74c46c45b231f4313aed1fccb379a76fe6
|
||||
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
|
||||
F ext/rtree/rtree.c d26a815b0df1c412a6881dae8d7fd3c9c08cce68
|
||||
F ext/rtree/rtree.c 45c6bec21cfe7579c5b81f2f236bd929b839694c
|
||||
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
|
||||
F ext/rtree/rtree1.test 42dadfc7b44a436cd74a1bebc0b9b689e4eaf7ec
|
||||
F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba
|
||||
@@ -301,13 +302,16 @@ F ext/session/sessionfault2.test 04aa0bc9aa70ea43d8de82c4f648db4de1e990b0
|
||||
F ext/session/sqlite3session.c 37485891b4add26cf61495df193c419f36556a32
|
||||
F ext/session/sqlite3session.h 69bf73cfd71e58f2ae5d2aa935b2c1a541aee555
|
||||
F ext/session/test_session.c 464f2c8bf502795d95969387eb8e93f68c513c15
|
||||
F ext/sqlrr/README.txt 4239030e73023e72a2e727808cd433577d5bf730
|
||||
F ext/sqlrr/sqlrr.c 8d1e6571cd6a6beabdb5bcdfe3a0e723b914db41
|
||||
F ext/sqlrr/sqlrr.h 09e4f8929ad9bc2638732c0cc0db5eef8c417824
|
||||
F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220
|
||||
F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04
|
||||
F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e
|
||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
|
||||
F main.mk 3f669c06db5c4a53ff21dda639247c6310497180
|
||||
F main.mk af15e89c810547dc18d23020451e2d75effaf21c
|
||||
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
|
||||
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
|
||||
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
|
||||
@@ -319,35 +323,35 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
|
||||
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
|
||||
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
|
||||
F src/alter.c 1bb0709b3048e24217b80ec6bd78a3e99a47c01b
|
||||
F src/alter.c cc28ab933ae615b22add0d609794ffb6596b42ea
|
||||
F src/analyze.c 37fedc80ac966ce1745811746e68e4d8fa64c7fe
|
||||
F src/attach.c 771153bd1f4ab0b97a44a13dde2c7e5e1efeba22
|
||||
F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
|
||||
F src/auth.c 5c8e0f37f785f935f589496801edd19840485853
|
||||
F src/backup.c 6df65fdd569c901a418887a1a76f82ec35044556
|
||||
F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63
|
||||
F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73
|
||||
F src/btree.c 2781fb1db1e46390a9c27a2162395f371577ac66
|
||||
F src/btree.h 2107a2630e02c8cba58bb12ce14e731e734ea29c
|
||||
F src/btree.c eb4d02a0795a36a8314cf79a735ae19cec19442e
|
||||
F src/btree.h 075c45707c0f8f8af118f739f36df8098a08b7da
|
||||
F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5
|
||||
F src/build.c e827e57e4a29c00e8429c5fd4d9d4572cb1b32a4
|
||||
F src/build.c d1fdfd7ab8f5447e494ef15825973bf0719527c6
|
||||
F src/callback.c 2e76147783386374bf01b227f752c81ec872d730
|
||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||
F src/ctime.c 999a828425b35b8092a8cde25690e71c20906344
|
||||
F src/ctime.c e77f3dc297b4b65c96da78b4ae4272fdfae863d7
|
||||
F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39
|
||||
F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b
|
||||
F src/dbstat.c 4f6f7f52b49beb9636ffbd517cfe44a402ba4ad0
|
||||
F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f
|
||||
F src/expr.c 798146ea4c87d723e8a157d88450ac9c43256998
|
||||
F src/expr.c 9c5eca8602f6c496e8d4eefefe2aae3d831dd510
|
||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||
F src/fkey.c bc4145347595b7770f9a598cff1c848302cf5413
|
||||
F src/func.c 61a4114cf7004f10c542cfabbab9f2bcb9033045
|
||||
F src/func.c 29cc9acb170ec1387b9f63eb52cd85f8de96c771
|
||||
F src/global.c c45ea22aff29334f6a9ec549235ac3357c970015
|
||||
F src/hash.c 55b5fb474100cee0b901edaf203e26c970940f36
|
||||
F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
|
||||
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
|
||||
F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4
|
||||
F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da
|
||||
F src/insert.c 8f4e9fcbd8e95e85f15647ba8b413b18d556ec2b
|
||||
F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e
|
||||
F src/loadext.c 4237fd37ca589f1d90b3ea925dd9df20da8e0c84
|
||||
F src/main.c 405d13e3a4f7c5add9fb27702ae70ed0a6e32cca
|
||||
F src/legacy.c b419b813f192eef79d73f968511d2ee129525e21
|
||||
F src/loadext.c 5dd8b5a67d32a98bb75657c2a9e48b2cedbf13a4
|
||||
F src/main.c 8473928b7bcd24d492ff16c701dd0d4bbd3db190
|
||||
F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b
|
||||
@@ -355,44 +359,45 @@ F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
|
||||
F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a
|
||||
F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944
|
||||
F src/memjournal.c 95752936c11dc6995672d1dd783cd633eea0cc95
|
||||
F src/msvc.h d9ba56c6851227ab44b3f228a35f3f5772296495
|
||||
F src/msvc.h 4942752b6a253116baaa8de75256c51a459a5e81
|
||||
F src/mutex.c 8e45800ee78e0cd1f1f3fe8e398853307f4a085c
|
||||
F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85
|
||||
F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4
|
||||
F src/mutex_unix.c 27bb6cc49485ee46711a6580ab7b3f1402211d23
|
||||
F src/mutex_w32.c 5e6fe1c298fb5a8a15aaed4161d5759311431c17
|
||||
F src/notify.c 9711a7575036f0d3040ba61bc6e217f13a9888e7
|
||||
F src/os.c 4d83917f072ad958fba9235136fa2ed43df47905
|
||||
F src/os.c c03b50496df5815e8f6d45bae4404b73cadf069b
|
||||
F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343
|
||||
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
|
||||
F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
|
||||
F src/os_unix.c a9443cdab41d7f3cdf0df3a5aab62fd6e1c9b234
|
||||
F src/os_win.c d4b8faf8896b65818e67070711fdd00d8e620bd6
|
||||
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
|
||||
F src/pager.c c368634b888b1c8740aea83b36bfd266f2443e60
|
||||
F src/pager.h 8ab6b6feeee4bc0439bfde7ee59ba99df98b9bc3
|
||||
F src/parse.y 01b9f37c4c7009ab56fda98bc7db4c42643cecfe
|
||||
F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
|
||||
F src/os_unix.c defa2c6c6e01219459fa783d2f55841271c4eebc
|
||||
F src/os_win.c 8ba3403e276b0b01fd822bfcc162b83cacc80a1a
|
||||
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
||||
F src/pager.c db9dccd139b20213507392831341ad64505c4106
|
||||
F src/pager.h 0bd89bacf4b410ef36d928f6f1f7ec0913f74702
|
||||
F src/parse.y 99b676e6fc2f4e331ab93e76b3987cffdbd28efa
|
||||
F src/pcache.c 5583c8ade4b05075a60ba953ef471d1c1a9c05df
|
||||
F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490
|
||||
F src/pcache1.c 7f51d2b541aab57596adf62db2c4bb025d34f04d
|
||||
F src/pragma.c d98039af2deb5a4990f6635462b3f61f325a6c75
|
||||
F src/pcache1.c 9c2f433344e345da87f944c66e54b9e3e5d49693
|
||||
F src/pragma.c 1564ee0bc96aed8b39cfec2c5bb655e031b6431c
|
||||
F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c
|
||||
F src/prepare.c 22df6171aec1d86904ed2ad30c2348a5748aa04e
|
||||
F src/prepare.c 9c56ea254317e27d3a1273fa812b8578b5e2f850
|
||||
F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1
|
||||
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
||||
F src/resolve.c cca3aa77b95706df5d635a2141a4d1de60ae6598
|
||||
F src/resolve.c 0392c6686586b1d4dac9a4106959f03ddd70e9aa
|
||||
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
|
||||
F src/select.c f3c6e9065fb34f6a23af27ec7f1f717ffbfc2ee4
|
||||
F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6
|
||||
F src/sqlite.h.in 5f8113dbec74c6c093ead9930afb8c9fbd9f643d
|
||||
F src/shell.c 9351fc6de11e1d908648c0a92d85627138e3dee5
|
||||
F src/sqlite.h.in 944ce442e0800b2ee6334d53a49be6aabfb7f74f
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2
|
||||
F src/sqliteInt.h 801e2a569ea79b09b87d045cd6f00ec88205f1f6
|
||||
F src/sqlite3_private.h a81a9c5f97c095cc3e86914a05f8fabe0011f4a1
|
||||
F src/sqlite3ext.h 46f300b6e300e0fa916d7d58c44b53415b8471a9
|
||||
F src/sqliteInt.h 5fa89170e0ad08605cfb87b771ad70bf5a089317
|
||||
F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247
|
||||
F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba
|
||||
F src/status.c 5b18f9526900f61189ab0b83f1ef41d9f871a2ab
|
||||
F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9
|
||||
F src/tclsqlite.c 9c4c4589d078de37813ded708d8838b338ffb060
|
||||
F src/test1.c 43b37ab2b7338fd3313e74902f0d6c821eae843b
|
||||
F src/tclsqlite.c 5c213bf5fee084390f632df2328cf0821d483799
|
||||
F src/test1.c 5445032d4f1de27138802b26d8908fc3af028ba3
|
||||
F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b
|
||||
F src/test3.c c75c8af0eadb335236c9e61b51044c58a8f7dd59
|
||||
F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e
|
||||
@@ -404,10 +409,10 @@ F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60
|
||||
F src/test_async.c 21e11293a2f72080eda70e1124e9102044531cd8
|
||||
F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12
|
||||
F src/test_backup.c 2e6e6a081870150f20c526a2e9d0d29cda47d803
|
||||
F src/test_bestindex.c 29af3cc3b963ffe5760c85d142b9b3e5302c1e3d
|
||||
F src/test_bestindex.c f9e6807c52aa532e4775321ce3ed8e47c907ed45
|
||||
F src/test_blob.c b2551a9b5573232db5f66f292307c37067937239
|
||||
F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f
|
||||
F src/test_config.c 7003f6f35134de6f19c6588f44783e43390ea277
|
||||
F src/test_config.c 7711c82d42b9347540b6c8f628560055ff99b42a
|
||||
F src/test_demovfs.c 0de72c2c89551629f58486fde5734b7d90758852
|
||||
F src/test_devsym.c 4e58dec2602d8e139ca08659f62a62450587cb58
|
||||
F src/test_fs.c f10f840ca4f8c72e4837908bd8347ac4bcab074b
|
||||
@@ -415,12 +420,12 @@ F src/test_func.c 37453d346cfcf118774efd5bf6187f7e6a7e3254
|
||||
F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd
|
||||
F src/test_init.c 66b33120ffe9cd853b5a905ec850d51151337b32
|
||||
F src/test_intarray.c 870124b95ec4c645d4eb84f15efb7133528fb1a5
|
||||
F src/test_intarray.h 9dc57417fb65bc7835cc18548852cc08cc062202
|
||||
F src/test_intarray.h f3b7672f5d1056eac563c0d6ea8480a660b1475c
|
||||
F src/test_journal.c d3b83f2bcb7792c709e57abddc456a2b1818643a
|
||||
F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd
|
||||
F src/test_malloc.c 94c18e88d6df6d471a0d04ddb809f833d1739950
|
||||
F src/test_malloc.c 6b27e947eeeb70d11aa65406ed28d749e39b6356
|
||||
F src/test_multiplex.c eafc567ebe162e36f17b5062285dfe90461cf8e9
|
||||
F src/test_multiplex.h c08e4e8f8651f0c5e0509b138ff4d5b43ed1f5d3
|
||||
F src/test_multiplex.h 5436d03f2d0501d04f3ed50a75819e190495b635
|
||||
F src/test_mutex.c dbdfaff8580071f2212a0deae3325a93a737819c
|
||||
F src/test_onefile.c 416f87a28d6d673352d33fc4b1c7d39db878e50f
|
||||
F src/test_osinst.c ad0233b1dabb0390e25edded4ebd79a2a61538c6
|
||||
@@ -431,7 +436,7 @@ F src/test_rtree.c 43fff4c5a01576d6d213f27472598801a247890c
|
||||
F src/test_schema.c 2bdba21b82f601da69793e1f1d11bf481a79b091
|
||||
F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe
|
||||
F src/test_sqllog.c 0d138a8180a312bf996b37fa66da5c5799d4d57b
|
||||
F src/test_superlock.c 06797157176eb7085027d9dd278c0d7a105e3ec9
|
||||
F src/test_superlock.c 12e2bc484c6c2ba837327d37f2e6a6fd9d1464f8
|
||||
F src/test_syscall.c 268c072541162564a882c57f54a6fee12ef4a4d2
|
||||
F src/test_tclvar.c d86412527da65468ee6fa1b8607c65d0af736bc4
|
||||
F src/test_thread.c af391ec03d23486dffbcc250b7e58e073f172af9
|
||||
@@ -447,26 +452,26 @@ F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280
|
||||
F src/update.c 4f05ea8cddfa367d045e03589756c02199e8f9bd
|
||||
F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c
|
||||
F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d
|
||||
F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52
|
||||
F src/vdbe.c e23a15d352e63b51cf08af8052e678e67c54ec09
|
||||
F src/vdbe.h 5591b5add447096e31288b5a0a78ec5d7b5c5170
|
||||
F src/vdbeInt.h ddb157974436d87652de7dc641f7191496d9a8cd
|
||||
F src/vdbeapi.c 02bcbc2ca5d2004b029088b05b468b394881e103
|
||||
F src/vdbeaux.c c90275b0e55a2b32c03dc09314194fe46f2429d8
|
||||
F src/vacuum.c 9dd2f5d276bc6094d8f1d85ecd41b30c1a002a43
|
||||
F src/vdbe.c 5260025793f47c1c51c04154f9762ef3ef310607
|
||||
F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10
|
||||
F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d
|
||||
F src/vdbeapi.c facd9075897e1878446e76680b0519cc6ba199f2
|
||||
F src/vdbeaux.c a32d79aeaa88dc2b97c261172d952d395254a055
|
||||
F src/vdbeblob.c 83d2d266383157b02e2b809350bb197e89d7895b
|
||||
F src/vdbemem.c 1ecaa5ee0caff07255f25d04e8dc88befb6f88d1
|
||||
F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c
|
||||
F src/vdbetrace.c f75c5455d8cf389ef86a8bfdfd3177e0e3692484
|
||||
F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834
|
||||
F src/vtab.c 948d2d4984219eee37a7bf427d6667e21e6eb92e
|
||||
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a
|
||||
F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c
|
||||
F src/wal.c 25bc1cea2ab18a917548dd0a30c299c538878ef9
|
||||
F src/wal.h f38853cd771ff42f448de4f908238f2e2966ac8f
|
||||
F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354
|
||||
F src/where.c b9f5b0ddb14c3827e70b5379e659cf4cfd524c4d
|
||||
F src/where.c 8ccc01f9227d41bfaf09360f108583be4a36d3b1
|
||||
F src/whereInt.h e5b939701a7ceffc5a3a8188a37f9746416ebcd0
|
||||
F src/wherecode.c ba71a4e4bada29aa9842200e6299714bf18c812c
|
||||
F src/whereexpr.c c32d47085dbaca0b8fd013210f56693c7d220d48
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F src/wherecode.c 99707d11907c71d289ee9553d2d1a22f1fd8ba41
|
||||
F src/whereexpr.c d7dcbf14ce1b5876c1f76496162c30fcba669563
|
||||
F test/8_3_names.test 05034aadccd2253ffe6cbefb06662b8aa4600f77
|
||||
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
F test/aggnested.test b35b4cd69fc913f90d39a575e171e1116c3a4bb7
|
||||
@@ -474,8 +479,8 @@ F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
|
||||
F test/all.test 6ff7b43c2b4b905c74dc4a813d201d0fa64c5783
|
||||
F test/alter.test 2facdddf08d0d48e75dc6cc312cd2b030f4835dd
|
||||
F test/alter2.test 7ea05c7d92ac99349a802ef7ada17294dd647060
|
||||
F test/alter3.test b3568d11c38c4599c92f24242eda34144d78dc10
|
||||
F test/alter4.test c461150723ac957f3b2214aa0b11552cd72023ec
|
||||
F test/alter3.test 4d79934d812eaeacc6f22781a080f8cfe012fdc3
|
||||
F test/alter4.test 0c33c542247ba5aee4f4a0133ac44bcf8f97e5e0
|
||||
F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc
|
||||
F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
|
||||
F test/analyze.test 3eb35a4af972f98422e5dc0586501b17d103d321
|
||||
@@ -499,14 +504,14 @@ F test/async3.test d73a062002376d7edc1fe3edff493edbec1fc2f7
|
||||
F test/async4.test 1787e3952128aa10238bf39945126de7ca23685a
|
||||
F test/async5.test 383ab533fdb9f7ad228cc99ee66e1acb34cc0dc0
|
||||
F test/atof1.test ff0b0156fd705b67c506e1f2bfe9e26102bea9bd
|
||||
F test/attach.test 437107943f14d131cf5efc2ae5305a94d7cb1d58
|
||||
F test/attach.test 1e7275728d68631627ab3b81fa48d1fef22796ef
|
||||
F test/attach2.test 0ec5defa340363de6cd50fd595046465e9aaba2d
|
||||
F test/attach3.test 359eb65d00102cdfcef6fa4e81dc1648f8f80b27
|
||||
F test/attach4.test 53bf502f17647c6d6c5add46dda6bac8b6f4665c
|
||||
F test/attach4.test faaaf33fa51f986b414520cb03cecdc7999df108
|
||||
F test/attachmalloc.test 3a4bfca9545bfe906a8d2e622de10fbac5b711b0
|
||||
F test/auth.test 872a122b3977c1d1bb9fd637dc20016e5c01880f
|
||||
F test/auth2.test 264c6af53cad9aba5218c68bbe18036e39007bfa
|
||||
F test/auth3.test 5cfa94ed90c6617c42b7ba4b133fd79678b251c7
|
||||
F test/auth2.test 9eb7fce9f34bf1f50d3f366fb3e606be5a2000a1
|
||||
F test/auth3.test b810826b193831929951c0d50783a200e5ef6b72
|
||||
F test/autoinc.test c58912526998a39e11f66b533e23cfabea7f25b7
|
||||
F test/autoindex1.test 14b63a9f1e405fe6d5bfc8c8d00249c2ebaf13ea
|
||||
F test/autoindex2.test 12ef578928102baaa0dc23ad397601a2f4ecb0df
|
||||
@@ -528,13 +533,13 @@ F test/badutf2.test f5bc7f2d280670ecd79b9cf4f0f1760c607fe51f
|
||||
F test/bc_common.tcl b5e42d80305be95697e6370e015af571e5333a1c
|
||||
F test/bestindex1.test 0cf1bd2d7b97d3a3a8c10736125274f64765c4ee
|
||||
F test/bestindex2.test 4a06b8922ab2fd09434870da8d1cdf525aaf7060
|
||||
F test/bestindex3.test b80da904d23581d233a7ceee7d6bbad2b23a8133
|
||||
F test/bestindex3.test dd5fa4f483cd0356549203c4522f8c9e21cb1fc0
|
||||
F test/between.test 34d375fb5ce1ae283ffe82b6b233e9f38e84fc6c
|
||||
F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59
|
||||
F test/bigfile2.test 1b489a3a39ae90c7f027b79110d6b4e1dbc71bfc
|
||||
F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747
|
||||
F test/bigsort.test 8299fa9298f4f1e02fc7d2712e8b77d6cd60e5a2
|
||||
F test/bind.test 3c7b320969000c441a70952b0b15938fbb66237c
|
||||
F test/bind.test 30af0fc61bc3836034215cdbdeca46113ca1b4a1
|
||||
F test/bindxfer.test efecd12c580c14df5f4ad3b3e83c667744a4f7e0
|
||||
F test/bitvec.test 75894a880520164d73b1305c1c3f96882615e142
|
||||
F test/blob.test e7ac6c7d3a985cc4678c64f325292529a69ae252
|
||||
@@ -550,7 +555,7 @@ F test/btree01.test e08b3613540145b353f20c81cb18ead54ff12e0f
|
||||
F test/btree02.test fe69453d474d8154d19b904157ff1db4812fed99
|
||||
F test/btreefault.test c2bcb542685eea44621275cfedbd8a13f65201e3
|
||||
F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0
|
||||
F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de
|
||||
F test/cache.test 0bc2195f4a7207108af2617ed356e77daf4412f7
|
||||
F test/cacheflush.test af25bb1509df04c1da10e38d8f322d66eceedf61
|
||||
F test/capi2.test 011c16da245fdc0106a2785035de6b242c05e738
|
||||
F test/capi3.test f0c66919e43d42e1572a69be039e4527a931b00f
|
||||
@@ -574,6 +579,7 @@ F test/collate7.test 8ec29d98f3ee4ccebce6e16ce3863fb6b8c7b868
|
||||
F test/collate8.test cd9b3d3f999b8520ffaa7cc1647061fc5bab1334
|
||||
F test/collate9.test 3adcc799229545940df2f25308dd1ad65869145a
|
||||
F test/collateA.test b8218ab90d1fa5c59dcf156efabb1b2599c580d6
|
||||
F test/collateB.test 8ec2accd2d7166c1eff0d2a39bc90262c6f89632
|
||||
F test/colmeta.test 2c765ea61ee37bc43bbe6d6047f89004e6508eb1
|
||||
F test/colname.test 08948a4809d22817e0e5de89c7c0a8bd90cb551b
|
||||
F test/conflict.test 029faa2d81a0d1cafb5f88614beb663d972c01db
|
||||
@@ -614,12 +620,13 @@ F test/crashM.test d95f59046fa749b0d0822edf18a717788c8f318d
|
||||
F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
|
||||
F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8
|
||||
F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c
|
||||
F test/csv01.test 0929a9ce47021519512be92861f29e32d2538e5f
|
||||
F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47
|
||||
F test/csv01.test e0ba3caaa57e4c667a0b45977689fb8082f14348
|
||||
F test/ctime.test 4b4a66a12d0fd959fa295e56067bc21843583f88
|
||||
F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856
|
||||
F test/cursorhint2.test 2b45341d32d1aae9991a00ef31ebca339b274255
|
||||
F test/date.test 984ac1e3e5e031386866f034006148d3972b4a65
|
||||
F test/dbstatus.test 8de104bb5606f19537d23cd553b41349b5ab1204
|
||||
F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab
|
||||
F test/dbstatus.test 73149851b3aff14fc6db478e58f9083a66422cf5
|
||||
F test/dbstatus2.test 16194c6aa2d8a050f227890d2ed1eb5f8dcb8300
|
||||
F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d
|
||||
F test/delete.test e1bcdf8926234e27aac24b346ad83d3329ec8b6f
|
||||
F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa
|
||||
@@ -652,9 +659,9 @@ F test/e_totalchanges.test b12ee5809d3e63aeb83238dd501a7bca7fd72c10
|
||||
F test/e_update.test f46c2554d915c9197548681e8d8c33a267e84528
|
||||
F test/e_uri.test 25385396082b67fd02ae0038b95a3b3575fe0519
|
||||
F test/e_vacuum.test 120f29ea56bdce4d43279527ece894ab5d1729d3
|
||||
F test/e_wal.test ae9a593207a77d711443ee69ffe081fda9243625
|
||||
F test/e_wal.test 95c21e45eefe4cc31e820f998b14f92d1cb3a1bf
|
||||
F test/e_walauto.test 248af31e73c98df23476a22bdb815524c9dc3ba8
|
||||
F test/e_walckpt.test 28c371a6bb5e5fe7f31679c1df1763a19d19e8a0
|
||||
F test/e_walckpt.test 9f20ab843538484c57069074b126699266ee5521
|
||||
F test/e_walhook.test 4c0613a0c76e7a9d5c4c211e1b4cbcc1143914df
|
||||
F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea
|
||||
F test/enc2.test 83437a79ba1545a55fb549309175c683fb334473
|
||||
@@ -663,14 +670,14 @@ F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020
|
||||
F test/eqp.test 3fe051af50921284189d1970eb653f9fcf5117d2
|
||||
F test/errmsg.test f31592a594b44ee121371d25ddd5d63497bb3401
|
||||
F test/eval.test a64c9105d6ff163df7cf09d6ac29cdad5922078c
|
||||
F test/exclusive.test 9a57bd66e39144b888ca75c309914fcdefb4e3f9
|
||||
F test/exclusive.test ff85192dcf5000a1b53452a89fa9c5b61b0138cf
|
||||
F test/exclusive2.test 32798111aae78a5deec980eee383213f189df308
|
||||
F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
|
||||
F test/exists.test 79a75323c78f02bbe9c251ea502a092f9ef63dac
|
||||
F test/expr.test 79c3e7502d9e571553b85f0ecc8ff2ac7d0e4931
|
||||
F test/extension01.test 00d13cec817f331a687a243e0e5a2d87b0e358c9
|
||||
F test/extraquick.test cb254400bd42bfb777ff675356aabf3287978f79
|
||||
F test/fallocate.test 3e979af17dfa7e5e9dda5eba1a696c04fa9d47f7
|
||||
F test/fallocate.test fe52076a43ff99da8411990dbb4f374e81e88c85
|
||||
F test/filectrl.test 7c13f96457435238da99aff7343ad6a3a4885787
|
||||
F test/filefmt.test e4edbdc637ca9576ccf4337a3cce627d9df7a56c
|
||||
F test/fkey1.test 13e3d48236a2b9f5c5ebd232eef9b3ab682a8a2c
|
||||
@@ -819,20 +826,20 @@ F test/hook.test 3b7b99d0eece6d279812c2aef6fa08bdfabc633e
|
||||
F test/icu.test 73956798bace8982909c00476b216714a6d0559a
|
||||
F test/ieee754.test 806fc0ce7f305f57e3331eaceeddcfec9339e607
|
||||
F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8
|
||||
F test/in.test 61a24ae38d4b64ec69f06ccdf022992f68a98176
|
||||
F test/in.test 61d940ced6817bee66e4e0b09d5bc8608f57134b
|
||||
F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75
|
||||
F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0
|
||||
F test/in4.test d2b38cba404bc4320f4fe1b595b3d163f212c068
|
||||
F test/in5.test acc710c12af118df5f8645eaba9479f5619eed81
|
||||
F test/incrblob.test c9b96afc292aeff43d6687bcb09b0280aa599822
|
||||
F test/incrblob2.test a5ce5ed1d0b01e2ed347245a21170372528af0a5
|
||||
F test/incrblob3.test d8d036fde015d4a159cd3cbae9d29003b37227a4
|
||||
F test/incrblob3.test 5fa6f2665ae37da05928bb16851d4f86515af78a
|
||||
F test/incrblob4.test f26502a5697893e5acea268c910f16478c2f0fab
|
||||
F test/incrblob_err.test 69f9247fed50278d48ea710d1a8f9cdb09e4c0b8
|
||||
F test/incrblobfault.test 280474078f6da9e732cd2a215d3d854969014b6e
|
||||
F test/incrcorrupt.test 6c567fbf870aa9e91866fe52ce6f200cd548939a
|
||||
F test/incrvacuum.test d2a6ddf5e429720b5fe502766af747915ccf6c32
|
||||
F test/incrvacuum2.test 7d26cfda66c7e55898d196de54ac4ec7d86a4e3d
|
||||
F test/incrvacuum2.test 1e873b6caf87ce160d4cb6d8c7a46f0570da1ddc
|
||||
F test/incrvacuum3.test 75256fb1377e7c39ef2de62bfc42bbff67be295a
|
||||
F test/incrvacuum_ioerr.test 6ae2f783424e47a0033304808fe27789cf93e635
|
||||
F test/index.test fe3c7a1aad82af92623747e9c3f3aa94ccd51238
|
||||
@@ -840,8 +847,9 @@ F test/index2.test f835d5e13ca163bd78c4459ca15fd2e4ed487407
|
||||
F test/index3.test 81bc47890b8abfb181bc35f8d10b56c069803386
|
||||
F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6
|
||||
F test/index5.test 8621491915800ec274609e42e02a97d67e9b13e7
|
||||
F test/index6.test 7102ec371414c42dfb1d5ca37eb4519aa9edc23a
|
||||
F test/index6.test 43b4e29258b978fcdab84fc61df4f5212119dd09
|
||||
F test/index7.test 9c6765a74fc3fcde7aebc5b3bd40d98df14a527c
|
||||
F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7
|
||||
F test/indexedby.test 9c4cd331224e57f79fbf411ae245e6272d415985
|
||||
F test/indexexpr1.test cb71b6586177b840e28110dd952178bb2bdfedc2
|
||||
F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d
|
||||
@@ -870,11 +878,11 @@ F test/join5.test 8a5c0be6f0c260a5c7177c3b8f07c7856141038a
|
||||
F test/join6.test cfe6503791ceb0cbb509966740286ec423cbf10b
|
||||
F test/journal1.test 69abc726c51b4a0409189f9a85191205297c0577
|
||||
F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4
|
||||
F test/journal3.test ff8af941f9e06161d3db1b46bb9f965ff0e7f307
|
||||
F test/journal3.test ef775301aa8c64c80efa859e6aa0207add921a93
|
||||
F test/jrnlmode.test 7864d59cf7f6e552b9b99ba0f38acd167edc10fa
|
||||
F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d
|
||||
F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
|
||||
F test/json101.test ef42283f0b60d8bacbc2243448e7c84988578e52
|
||||
F test/json101.test 865776ed8580703e1684fe4b8ee2e473333bb121
|
||||
F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a
|
||||
F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0
|
||||
F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
|
||||
@@ -891,12 +899,13 @@ F test/lock.test be4fe08118fb988fed741f429b7dd5d65e1c90db
|
||||
F test/lock2.test 5242d8ac4e2d59c403aebff606af449b455aceff
|
||||
F test/lock3.test f271375930711ae044080f4fe6d6eda930870d00
|
||||
F test/lock4.test e175ae13865bc87680607563bafba21f31a26f12
|
||||
F test/lock5.test c6c5e0ebcb21c61a572870cc86c0cb9f14cede38
|
||||
F test/lock6.test ad5b387a3a8096afd3c68a55b9535056431b0cf5
|
||||
F test/lock5.test 1f1e0fd1670deef8c0a76e8f895bd5e124133ca4
|
||||
F test/lock6.test 83434ae8ca1d1c5e2eaf74d4e44aa24ab62b291c
|
||||
F test/lock7.test 49f1eaff1cdc491cc5dee3669f3c671d9f172431
|
||||
F test/lock_common.tcl 7ffb45accf6ee91c736df9bafe0806a44358f035
|
||||
F test/lock_proxy.test 95be9c32d79be25cf643b4e41a0aa0e53aa21621
|
||||
F test/lookaside.test 90052e87282de256d613fcf8c9cbb845e4001d2f
|
||||
F test/main.test bb75e406c9b64931f3dc7e7f04626633365bb22f
|
||||
F test/main.test 5c893511b64780c8b96563664f8b8d7d959911af
|
||||
F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9
|
||||
F test/malloc.test 21c213365f2cca95ab2d7dc078dc8525f96065f8
|
||||
F test/malloc3.test e3b32c724b5a124b57cb0ed177f675249ad0c66a
|
||||
@@ -919,14 +928,14 @@ F test/mallocI.test a88c2b9627c8506bf4703d8397420043a786cdb6
|
||||
F test/mallocJ.test b5d1839da331d96223e5f458856f8ffe1366f62e
|
||||
F test/mallocK.test 27cb5566a6e5f2d76f9d4aa2eca45524401fd61e
|
||||
F test/mallocL.test fb311ff80afddf3b1a75e52289081f4754d901dc
|
||||
F test/malloc_common.tcl aac62499b76be719fac31e7a3e54a7fd53272e7f
|
||||
F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e
|
||||
F test/malloc_common.tcl 8d368ee0b9d77c9643b174448f137c18b68e49f4
|
||||
F test/manydb.test 3cd8e52ab3112cb8365afeedd6e8231977920577
|
||||
F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f
|
||||
F test/memdb.test c1f2a343ad14398d5d6debda6ea33e80d0dafcc7
|
||||
F test/memdb.test c46019291625650d71416e770f6a54a281a1a98f
|
||||
F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2
|
||||
F test/memsubsys1.test 6d268d0ae90f8d61a2356a1838665654d83de518
|
||||
F test/memsubsys1.test b6037a276f95c88d029868b12c80ff08dbb78700
|
||||
F test/memsubsys2.test 3e4a8d0c05fd3e5fa92017c64666730a520c7e08
|
||||
F test/minmax.test 42fbad0e81afaa6e0de41c960329f2b2c3526efd
|
||||
F test/minmax.test 6751e87b409fe11b02e70a306d846fa544e25a41
|
||||
F test/minmax2.test b44bae787fc7b227597b01b0ca5575c7cb54d3bc
|
||||
F test/minmax3.test cc1e8b010136db0d01a6f2a29ba5a9f321034354
|
||||
F test/minmax4.test 936941484ebdceb8adec7c86b6cd9b6e5e897c1f
|
||||
@@ -944,7 +953,7 @@ F test/mmap2.test 9d6dd9ddb4ad2379f29cc78f38ce1e63ed418022
|
||||
F test/mmap3.test b3c297e78e6a8520aafcc1a8f140535594c9086e
|
||||
F test/mmap4.test 2e2b4e32555b58da15176e6fe750f17c9dcf7f93
|
||||
F test/mmapfault.test d4c9eff9cd8c2dc14bc43e71e042f175b0a26fe3
|
||||
F test/multiplex.test efd015ca0b5b4a57dc9535b8feb1273eebeadb60
|
||||
F test/multiplex.test 2ed4db53c3304b7eb7b8744206ee9271799a32eb
|
||||
F test/multiplex2.test 580ca5817c7edbe4cc68fa150609c9473393003a
|
||||
F test/multiplex3.test d228f59eac91839a977eac19f21d053f03e4d101
|
||||
F test/multiplex4.test e8ae4c4bd70606a5727743241f13b5701990abe4
|
||||
@@ -972,21 +981,21 @@ F test/orderby8.test 23ef1a5d72bd3adcc2f65561c654295d1b8047bd
|
||||
F test/orderby9.test 87fb9548debcc2cd141c5299002dd94672fa76a3
|
||||
F test/oserror.test b32dc34f2363ef18532e3a0a7358e3e7e321974f
|
||||
F test/ovfl.test 199c482696defceacee8c8e0e0ef36da62726b2f
|
||||
F test/pager1.test 841868017e9dd3cb459b8d78862091a7d9cff21d
|
||||
F test/pager1.test 15d423765637d8cd54b025f90ed6c8dc311e2fc3
|
||||
F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71
|
||||
F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f
|
||||
F test/pager4.test a122e9e6925d5b23b31e3dfef8c6a44bbf19590e
|
||||
F test/pagerfault.test 42ff797b1e6426c141cc7ee8b7417c9f27427950
|
||||
F test/pagerfault.test 6b3f03fca89aacb4d1ca2c0216af114acaec0c66
|
||||
F test/pagerfault2.test caf4c7facb914fd3b03a17b31ae2b180c8d6ca1f
|
||||
F test/pagerfault3.test 1003fcda009bf48a8e22a516e193b6ef0dd1bbd8
|
||||
F test/pageropt.test 84e4cc5cbca285357f7906e99b21be4f2bf5abc0
|
||||
F test/pagesize.test 5769fc62d8c890a83a503f67d47508dfdc543305
|
||||
F test/parser1.test 222b5cbf3e2e659fec1bf7d723488c8b9c94f1d0
|
||||
F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
|
||||
F test/parser1.test 391b9bf9a229547a129c61ac345ed1a6f5eb1854
|
||||
F test/pcache.test 9a04fa260cb47dd4fdc5d13c5e97054e05931592
|
||||
F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
|
||||
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
|
||||
F test/permutations.test 544a2f317fc5045bc512ae432f89eae303c0d640
|
||||
F test/pragma.test 1e94755164a3a3264cd39836de4bebcb7809e5f8
|
||||
F test/pragma.test d3b32e689ffd885b2e7bcaabab21ee4652a4f99f
|
||||
F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f
|
||||
F test/pragma3.test 14c12bc5352b1e100e0b6b44f371053a81ccf8ed
|
||||
F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc
|
||||
@@ -1006,12 +1015,12 @@ F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8
|
||||
F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8
|
||||
F test/regexp2.test aa7ffcc21350007a78361b82bcf3b74d12227144
|
||||
F test/reindex.test 44edd3966b474468b823d481eafef0c305022254
|
||||
F test/releasetest.tcl 7d80014d0245b3f9d02d393d420bf03ca155aec0
|
||||
F test/releasetest.tcl 3a66c7b8fbe55bcd97c907217c3d812d1d3c6b93
|
||||
F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb
|
||||
F test/rollback.test 458fe73eb3ffdfdf9f6ba3e9b7350a6220414dea
|
||||
F test/rollback2.test 8435d6ff0f13f51d2a4181c232e706005fa90fc5
|
||||
F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a
|
||||
F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc
|
||||
F test/rowallock.test e8c576ebc92f6b9211662f495658fd39bbcacb5b
|
||||
F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81
|
||||
F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d
|
||||
F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798
|
||||
@@ -1023,7 +1032,7 @@ F test/savepoint5.test 0735db177e0ebbaedc39812c8d065075d563c4fd
|
||||
F test/savepoint6.test f41279c5e137139fa5c21485773332c7adb98cd7
|
||||
F test/savepoint7.test cde525ea3075283eb950cdcdefe23ead4f700daa
|
||||
F test/savepointfault.test f044eac64b59f09746c7020ee261734de82bf9b2
|
||||
F test/scanstatus.test 5253c219e331318a437f436268e0e82345700285
|
||||
F test/scanstatus.test 030acbbdcea6a3fc676fee99edc84f6f16c0cf92
|
||||
F test/schema.test 8f7999be894260f151adf15c2c7540f1c6d6a481
|
||||
F test/schema2.test 906408621ea881fdb496d878b1822572a34e32c5
|
||||
F test/schema3.test 1bc1008e1f8cb5654b248c55f27249366eb7ed38
|
||||
@@ -1040,7 +1049,7 @@ F test/select6.test 39eac4a5c03650b2b473c532882273283ee8b7a0
|
||||
F test/select7.test 95e370c42d47c3c52377d05e9ffc01ccff7c1f61
|
||||
F test/select8.test 8c8f5ae43894c891efc5755ed905467d1d67ad5d
|
||||
F test/select9.test aebc2bb0c3bc44606125033cbcaac2c8d1f33a95
|
||||
F test/selectA.test e452bdb975f488ea46d091382a9185b5853ed2c7
|
||||
F test/selectA.test 101e722370ac6e84978c2958b8931c78b10a1709
|
||||
F test/selectB.test 954e4e49cf1f896d61794e440669e03a27ceea25
|
||||
F test/selectC.test 871fb55d884d3de5943c4057ebd22c2459e71977
|
||||
F test/selectD.test b0f02a04ef7737decb24e08be2c39b9664b43394
|
||||
@@ -1049,7 +1058,7 @@ F test/selectF.test 21c94e6438f76537b72532fa9fd4710cdd455fc3
|
||||
F test/selectG.test e8600e379589e85e9fefd2fe4d44a4cdd63f6982
|
||||
F test/server1.test 46803bd3fe8b99b30dbc5ff38ffc756f5c13a118
|
||||
F test/session.test 78fa2365e93d3663a6e933f86e7afc395adf18be
|
||||
F test/shared.test 1da9dbad400cee0d93f252ccf76e1ae007a63746
|
||||
F test/shared.test 13376ba3be1c5685ab1ec184189adabd15fa70be
|
||||
F test/shared2.test 03eb4a8d372e290107d34b6ce1809919a698e879
|
||||
F test/shared3.test ab693f9b6e156b8bfb2a0ad94f29fe69602a5d38
|
||||
F test/shared4.test c75f476804e76e26bf6fa0e7b421fb0ca7d07558
|
||||
@@ -1061,14 +1070,14 @@ F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5
|
||||
F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e
|
||||
F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506
|
||||
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
|
||||
F test/shell1.test c90b0415cea6eeefb86b4ab1651b06247922ca52
|
||||
F test/shell1.test 77896b65f1cde4ee79e38b2c0ed8578a8f4000e5
|
||||
F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b
|
||||
F test/shell3.test da513d522ef6f01cee8475dcf8332bff8982b3dd
|
||||
F test/shell4.test 69995ee1cc278eb149aa8746ce1f935f4eaf98b9
|
||||
F test/shell5.test 50a732c1c2158b1cd62cf53975ce1ea7ce6b9dc9
|
||||
F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
|
||||
F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5
|
||||
F test/shrink.test 1b4330b1fd9e818c04726d45cb28db73087535ce
|
||||
F test/shrink.test 09bc6e2473321e7a4711ae7d753865daffc42f4a
|
||||
F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329
|
||||
F test/skipscan1.test d37a75b4be4eb9dedeb69b4f38b1d0a74b5021d7
|
||||
F test/skipscan2.test d1d1450952b7275f0b0a3a981f0230532743951a
|
||||
@@ -1100,32 +1109,32 @@ F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33
|
||||
F test/sqldiff1.test 28cd737cf1b0078b1ec1bbf425e674c47785835e
|
||||
F test/sqllimits1.test a74ee2a3740b9f9c2437c246d8fb77354862a142
|
||||
F test/sqllog.test 6af6cb0b09f4e44e1917e06ce85be7670302517a
|
||||
F test/stat.test 66e95f97b9f724f9ab921d054ee0db3c2689f1ee
|
||||
F test/stat.test ab95d28503d0f6d98ffd8ce204643c9da090ebf1
|
||||
F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1
|
||||
F test/stmt.test 64844332db69cf1a735fcb3e11548557fc95392f
|
||||
F test/stmt.test fc832e52bd1273144abbb27c07fc01d1acdd9939
|
||||
F test/subquery.test d7268d193dd33d5505df965399d3a594e76ae13f
|
||||
F test/subquery2.test 438f8a7da1457277b22e4176510f7659b286995f
|
||||
F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4
|
||||
F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a
|
||||
F test/subtype1.test 7fe09496352f97053af1437150751be2d0a0cae8
|
||||
F test/superlock.test ec94f0556b6488d97f71c79f9061ae08d9ab8f12
|
||||
F test/superlock.test c86eacd6cead5da9c5ecd25f3d46fca30a927ef2
|
||||
F test/symlink.test c9ebe7330d228249e447038276bfc8a7b22f4849
|
||||
F test/sync.test 2f84bdbc2b2df1fcb0220575b4b9f8cea94b7529
|
||||
F test/syscall.test f59ba4e25f7ba4a4c031026cc2ef8b6e4b4c639c
|
||||
F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04
|
||||
F test/tabfunc01.test f977868fa8bb7beb4b2072883190411653473906
|
||||
F test/tabfunc01.test 50a9fb379f9747fd0d40ea6d8fa3a101361bb537
|
||||
F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f
|
||||
F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
|
||||
F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
|
||||
F test/tclsqlite.test e1306001a0ca92250b691ea6d3cecaca5b6342aa
|
||||
F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6
|
||||
F test/tclsqlite.test 1d73b9203b1ca8798d7d7310742b8d3febc0d56e
|
||||
F test/tempdb.test be87085066978807bb9eb934ae3986521e88a675
|
||||
F test/tempdb2.test 4fc92055f2a3f7626c0f2eabbb637dc021b311d5
|
||||
F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900
|
||||
F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
|
||||
F test/temptable2.test cd396beb41117a5302fff61767c35fa4270a0d5e
|
||||
F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637
|
||||
F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1
|
||||
F test/tester.tcl 3ace46dee55f07e28a1e3ab03258b929fefcee5b
|
||||
F test/tester.tcl 92af6adf39ff36788a29e60c566488e555c1b7aa
|
||||
F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5
|
||||
F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
|
||||
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
|
||||
@@ -1141,10 +1150,10 @@ F test/threadtest4.c c1e67136ceb6c7ec8184e56ac61db28f96bd2925
|
||||
F test/tkt-02a8e81d44.test 6c80d9c7514e2a42d4918bf87bf6bc54f379110c
|
||||
F test/tkt-26ff0c2d1e.test 888324e751512972c6e0d1a09df740d8f5aaf660
|
||||
F test/tkt-2a5629202f.test 0521bd25658428baa26665aa53ffed9367d33af2
|
||||
F test/tkt-2d1a5c67d.test be1326f3061caec85085f4c9ee4490561ca037c0
|
||||
F test/tkt-2d1a5c67d.test 58a56653795d1787f4ed661f9da7da153b0dc3f9
|
||||
F test/tkt-2ea2425d34.test 1cf13e6f75d149b3209a0cb32927a82d3d79fb28
|
||||
F test/tkt-31338dca7e.test 6fb8807851964da0d24e942f2e19c7c705b9fb58
|
||||
F test/tkt-313723c356.test 4b306ad45c736cedf2f5221f6155b92143244b6d
|
||||
F test/tkt-313723c356.test d78f772dd71d632f3d3f6d3d588c3105b2ab1bb3
|
||||
F test/tkt-385a5b56b9.test c0a06ada41d7f06b1686da0e718553f853771d1e
|
||||
F test/tkt-38cb5df375.test f3cc8671f1eb604d4ae9cf886ed4366bec656678
|
||||
F test/tkt-3998683a16.test 6d1d04d551ed1704eb3396ca87bb9ccc8c5c1eb7
|
||||
@@ -1244,7 +1253,7 @@ F test/tkt3357.test 77c37c6482b526fe89941ce951c22d011f5922ed
|
||||
F test/tkt3419.test 1bbf36d7ea03b638c15804251287c2391f5c1f6b
|
||||
F test/tkt3424.test 61f831bd2b071bd128fa5d00fbda57e656ca5812
|
||||
F test/tkt3442.test 53840ec5325bb94544792aad4c20476f81dc26b1
|
||||
F test/tkt3457.test 44e980fe5334753dcc27b94fa4deabc485a92f74
|
||||
F test/tkt3457.test 08d2d9b3fc37fcc7ad9f24e5d1e004571f2a79c8
|
||||
F test/tkt3461.test 228ea328a5a21e8663f80ee3d212a6ad92549a19
|
||||
F test/tkt3493.test 1686cbde85f8721fc1bdc0ee72f2ef2f63139218
|
||||
F test/tkt3508.test d75704db9501625c7f7deec119fcaf1696aefb7d
|
||||
@@ -1282,6 +1291,7 @@ F test/tokenize.test ce430a7aed48fc98301611429595883fdfcab5d7
|
||||
F test/tpch01.test 04adbf8d8300fa60a222f28d901abd76e7be6dd4
|
||||
F test/trace.test 6f676313e3ebd2a50585036d2f212a3319dd5836
|
||||
F test/trace2.test f5cb67ad3bc09e0c58e8cca78dfd0b5639259983
|
||||
F test/trace3.test 01e4111d582c7b20ab1c63156169157d256bc3d5
|
||||
F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6
|
||||
F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76
|
||||
F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94
|
||||
@@ -1320,6 +1330,7 @@ F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d
|
||||
F test/vacuum2.test aa048abee196c16c9ba308465494009057b79f9b
|
||||
F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d
|
||||
F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9
|
||||
F test/vacuummem.test e53a3fdca4612a99c515e1afe7934728a2383764
|
||||
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
|
||||
F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
|
||||
F test/view.test 765802c7a66d37fabd5ac8e2f2dbe572b43eb9ab
|
||||
@@ -1343,39 +1354,39 @@ F test/vtabI.test 751b07636700dbdea328e4265b6077ccd6811a3f
|
||||
F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5
|
||||
F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
|
||||
F test/vtab_shared.test 5253bff2355a9a3f014c15337da7e177ab0ef8ad
|
||||
F test/wal.test 613efec03e517e1775d86b993a54877d2e29a477
|
||||
F test/wal2.test 56b0bc95b8693a0be294f8d210c49025dd094bd7
|
||||
F test/wal3.test 2a93004bc0fb2b5c29888964024695bade278ab2
|
||||
F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c
|
||||
F test/wal5.test 9c11da7aeccd83a46d79a556ad11a18d3cb15aa9
|
||||
F test/wal6.test a9d6aa635b9d63607dabdc11406f5f96ca986635
|
||||
F test/wal.test 83635d428b0a3fe883939cedbaedf29e13a5affd
|
||||
F test/wal2.test 72286d113a40817702fa59285ee5b82effbfe754
|
||||
F test/wal3.test 82f70ca79e5db6829f9246f4a30d4a4751921c3b
|
||||
F test/wal4.test 5755887f321baa4c55de0b91066fa7d0cafcac9d
|
||||
F test/wal5.test 9304fada875d7279deb2783385b0ae1c02d96b88
|
||||
F test/wal6.test 557fab4cc02b4ce2adf1d0f8821cb8acdaa1304f
|
||||
F test/wal64k.test 163655ecd2cb8afef4737cac2a40fdd2eeaf20b8
|
||||
F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd
|
||||
F test/wal8.test d9df3fba4caad5854ed69ed673c68482514203c8
|
||||
F test/wal7.test 18cf68ab8010ae0a2baaa48e5b59567a9503e63e
|
||||
F test/wal8.test 82bf6e493002b2d1580823b40e47bce3e15f468a
|
||||
F test/wal9.test 378e76a9ad09cd9bee06c172ad3547b0129a6750
|
||||
F test/wal_common.tcl a98f17fba96206122eff624db0ab13ec377be4fe
|
||||
F test/walbak.test 018d4e5a3d45c6298d11b99f09a8ef6876527946
|
||||
F test/walbig.test f437473a16cfb314867c6b5d1dbcd519e73e3434
|
||||
F test/wal_common.tcl 15f152fd55703975878741beca6cfa4209d5b3b3
|
||||
F test/walbak.test e322af729156c121183af4847c6e2b17bc629f47
|
||||
F test/walbig.test 3ca3d94751b80054eed5bda20a1339ae1f619483
|
||||
F test/walblock.test be48f3a75eff0b4456209f26b3ce186c2015497d
|
||||
F test/walcksum.test bb234a1bb42248b3515d992b719708015c384278
|
||||
F test/walcrash.test 21038858cc552077b0522f50b0fa87e38139306a
|
||||
F test/walcrash2.test a0edab4e5390f03b99a790de89aad15d6ec70b36
|
||||
F test/walcrash3.test e426aa58122d20f2b9fbe9a507f9eb8cab85b8af
|
||||
F test/walcrash4.test 3374d6a0813bfe9d841a973958e0552b545a6423
|
||||
F test/walfault.test 1f8389f7709877e9b4cc679033d71d6fe529056b
|
||||
F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483
|
||||
F test/walmode.test 4022fe03ae6e830583672caa101f046438a0473c
|
||||
F test/walnoshm.test 84ca10c544632a756467336b7c3b864d493ee496
|
||||
F test/walcksum.test add42a54d7c7d9bc72a913792022a195293bef2b
|
||||
F test/walcrash.test 065a041da88f980df3830f09b7fe308337bb594a
|
||||
F test/walcrash2.test 6eb6842d34cc5955726264c80566963c32a9cbea
|
||||
F test/walcrash3.test 279640ffafa23f7564529ccd69bfb97849ccae9d
|
||||
F test/walcrash4.test e7b6e7639a950a0cca8e210e248c8dad4d63bf20
|
||||
F test/walfault.test f4160abd02d583d06d7ea9554e7a3f749f6b3410
|
||||
F test/walhook.test 5d2bdb04fd3e220e2f96e6b566d57e00020bdaec
|
||||
F test/walmode.test aa45339b4afa435dde5d88e71a95459cc221a3f4
|
||||
F test/walnoshm.test 559b878f3aab838971d820329ca35f1caa7b038e
|
||||
F test/waloverwrite.test dad2f26567f1b45174e54fbf9a8dc1cb876a7f03
|
||||
F test/walpersist.test 8c6b7e3ec1ba91b5e4dc4e0921d6d3f87cd356a6
|
||||
F test/walpersist.test abd956d66e2f36d2d9d05d3a969f48be6d2ddbec
|
||||
F test/walprotocol.test 059cb75484a1ecf6357a2c1b3324b8156749221e
|
||||
F test/walro.test 4ab7ac01b77c2f894235c699d59e3e3c7f15a160
|
||||
F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417
|
||||
F test/walslow.test c05c68d4dc2700a982f89133ce103a1a84cc285f
|
||||
F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e
|
||||
F test/walro.test 310f5f364e64eaaa2f2233229a7b602ccb038bc9
|
||||
F test/walshared.test 04590b10c677f75318701818c50bc0dda5da64ab
|
||||
F test/walslow.test 07a51cbe9d4895d0a90c7af76d14a62d363ac162
|
||||
F test/walthread.test c13f5a12fbd9d81e58f49875dc9dd8a52a84cf03
|
||||
F test/where.test f0c325563acde44f2c4ea6ba348e9e29f7121757
|
||||
F test/where2.test 478d2170637b9211f593120648858593bf2445a1
|
||||
F test/where3.test 1ad55ba900bd7747f98b6082e65bd3e442c5004e
|
||||
F test/where3.test 54cdeb02157acc979de41530b804ae7b09552bf1
|
||||
F test/where4.test 4a371bfcc607f41d233701bdec33ac2972908ba8
|
||||
F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2
|
||||
F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b
|
||||
@@ -1399,6 +1410,7 @@ F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c
|
||||
F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c
|
||||
F test/win32lock.test fbf107c91d8f5512be5a5b87c4c42ab9fdd54972
|
||||
F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d
|
||||
F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc
|
||||
F test/with1.test cef099a491eac9874f2c28bd2dc86394fb3e47b3
|
||||
F test/with2.test 2b40da883658eb74ad8ad06afabe11a408e7fb87
|
||||
F test/with3.test 511bacdbe41c49cf34f9fd1bd3245fe1575bca98
|
||||
@@ -1429,7 +1441,7 @@ F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4
|
||||
F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5
|
||||
F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
|
||||
F tool/lemon.c 09a96bed19955697a5e20c49ad863ec2005815a2
|
||||
F tool/lempar.c 8c4e9d8517e50da391f1d89a519e743dd4afbc09
|
||||
F tool/lempar.c 57ffa9852901f6abc45981f0d882f31d1ccb06c0
|
||||
F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9
|
||||
F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862
|
||||
F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca
|
||||
@@ -1442,7 +1454,7 @@ F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
|
||||
F tool/mkpragmatab.tcl f0d5bb266d1d388cf86fce5ba01a891e95d72d41
|
||||
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
|
||||
F tool/mksqlite3c-noext.tcl 87240b09c20042999b41d5fabe091b7111287835
|
||||
F tool/mksqlite3c.tcl 63af8429841f08552e6da1d93b3dee4a93ff8071
|
||||
F tool/mksqlite3c.tcl bfafc3e96885a2afa8b0d733826ee89e2db3d8b3
|
||||
F tool/mksqlite3h.tcl e7b106fc4f29fbc258e8ba9b88d9108332ea2ade
|
||||
F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b
|
||||
F tool/mkvsix.tcl 4abcaf3267171b2faadaf9b82a0dfbaa6e98f8b7
|
||||
@@ -1468,8 +1480,8 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||
F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd
|
||||
F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c
|
||||
F tool/sqldiff.c ca315aca4e2d24233e8f2000edea5880c53d1875
|
||||
F tool/srcck1.c 4c39bdfa9a92edd20233ee720df84dbeb2417602
|
||||
F tool/sqldiff.c 4478f0d30230de6adde90bdb0bfe60f68c5ab782
|
||||
F tool/srcck1.c 371de5363b70154012955544f86fdee8f6e5326f
|
||||
F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43
|
||||
F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d
|
||||
F tool/symbols.sh c5a617b8c61a0926747a56c65f5671ef8ac0e148
|
||||
@@ -1501,7 +1513,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 44f157e0f0d5a76ef9002b2592164c4fdae89e34
|
||||
R 654981991ade95156b7aa25e1b0590de
|
||||
P 97657445860363f5bd62c37e6a565e782e7eb908
|
||||
R c1b6454d8f71efcd1ab7fc64b6002698
|
||||
T *branch * unknown-function
|
||||
T *sym-unknown-function *
|
||||
T -sym-apple-osx *
|
||||
U drh
|
||||
Z 0f8b86024c43c03c854a2dd32c154497
|
||||
Z 6495d62c822011f2ce59f727ab874d9c
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
fb2768154c513881886e89801e906bea959197b3
|
||||
4ada023ca075628fdafc3bc4520239b9789cff29
|
||||
+12
-9
@@ -601,6 +601,7 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
|
||||
Expr *pDflt; /* Default value for the new column */
|
||||
sqlite3 *db; /* The database connection; */
|
||||
Vdbe *v = pParse->pVdbe; /* The prepared statement under construction */
|
||||
int r1; /* Temporary registers */
|
||||
|
||||
db = pParse->db;
|
||||
if( pParse->nErr || db->mallocFailed ) return;
|
||||
@@ -695,16 +696,18 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
|
||||
db->flags = savedDbFlags;
|
||||
}
|
||||
|
||||
/* If the default value of the new column is NULL, then the file
|
||||
** format to 2. If the default value of the new column is not NULL,
|
||||
** the file format be 3. Back when this feature was first added
|
||||
** in 2006, we went to the trouble to upgrade the file format to the
|
||||
** minimum support values. But 10-years on, we can assume that all
|
||||
** extent versions of SQLite support file-format 4, so we always and
|
||||
** unconditionally upgrade to 4.
|
||||
/* Make sure the schema version is at least 3. But do not upgrade
|
||||
** from less than 3 to 4, as that will corrupt any preexisting DESC
|
||||
** index.
|
||||
*/
|
||||
sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT,
|
||||
SQLITE_MAX_FILE_FORMAT);
|
||||
r1 = sqlite3GetTempReg(pParse);
|
||||
sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT);
|
||||
sqlite3VdbeUsesBtree(v, iDb);
|
||||
sqlite3VdbeAddOp2(v, OP_AddImm, r1, -2);
|
||||
sqlite3VdbeAddOp2(v, OP_IfPos, r1, sqlite3VdbeCurrentAddr(v)+2);
|
||||
VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, 3);
|
||||
sqlite3ReleaseTempReg(pParse, r1);
|
||||
|
||||
/* Reload the schema of the modified table. */
|
||||
reloadTableSchema(pParse, pTab, pTab->zName);
|
||||
|
||||
@@ -111,6 +111,7 @@ int sqlite3AuthReadCol(
|
||||
char *zDb = db->aDb[iDb].zName; /* Name of attached database */
|
||||
int rc; /* Auth callback return code */
|
||||
|
||||
if( db->init.busy ) return SQLITE_OK;
|
||||
rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext
|
||||
#ifdef SQLITE_USER_AUTHENTICATION
|
||||
,db->auth.zAuthUser
|
||||
|
||||
+20
-3
@@ -87,8 +87,14 @@ static BtShared *SQLITE_WSD sqlite3SharedCacheList = 0;
|
||||
** sqlite3_open(), sqlite3_open16(), or sqlite3_open_v2().
|
||||
*/
|
||||
int sqlite3_enable_shared_cache(int enable){
|
||||
#if defined(__APPLE__) && !defined(SQLITE_TEST) && !defined(TH3_COMPATIBILITY)
|
||||
/* Enable global shared cache function for debugging and unit tests,
|
||||
** but not for release */
|
||||
return SQLITE_MISUSE;
|
||||
#else
|
||||
sqlite3GlobalConfig.sharedCacheEnabled = enable;
|
||||
return SQLITE_OK;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2337,9 +2343,9 @@ int sqlite3BtreeOpen(
|
||||
#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
|
||||
/* Add the new BtShared object to the linked list sharable BtShareds.
|
||||
*/
|
||||
pBt->nRef = 1;
|
||||
if( p->sharable ){
|
||||
MUTEX_LOGIC( sqlite3_mutex *mutexShared; )
|
||||
pBt->nRef = 1;
|
||||
MUTEX_LOGIC( mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);)
|
||||
if( SQLITE_THREADSAFE && sqlite3GlobalConfig.bCoreMutex ){
|
||||
pBt->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_FAST);
|
||||
@@ -2410,6 +2416,7 @@ btree_open_out:
|
||||
assert( sqlite3_mutex_held(mutexOpen) );
|
||||
sqlite3_mutex_leave(mutexOpen);
|
||||
}
|
||||
assert( rc!=SQLITE_OK || sqlite3BtreeConnectionCount(*ppBtree)>0 );
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -5070,7 +5077,7 @@ int sqlite3BtreeMovetoUnpacked(
|
||||
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
|
||||
assert( pRes );
|
||||
assert( (pIdxKey==0)==(pCur->pKeyInfo==0) );
|
||||
assert( (pIdxKey==0)==(pCur->curIntKey!=0) || pCur->eState!=CURSOR_VALID );
|
||||
assert( pCur->eState!=CURSOR_VALID || (pIdxKey==0)==(pCur->curIntKey!=0) );
|
||||
|
||||
/* If the cursor is already positioned at the point we are trying
|
||||
** to move to, then just return without doing any work */
|
||||
@@ -7339,7 +7346,7 @@ static int balance_nonroot(
|
||||
assert( r<nMaxCells );
|
||||
(void)cachedCellSize(&b, r);
|
||||
if( szRight!=0
|
||||
&& (bBulk || szRight+b.szCell[d]+2 > szLeft-(b.szCell[r]+2)) ){
|
||||
&& (bBulk || szRight+b.szCell[d]+2 > szLeft-(b.szCell[r]+(i==k-1?0:2)))){
|
||||
break;
|
||||
}
|
||||
szRight += b.szCell[d] + 2;
|
||||
@@ -9698,4 +9705,14 @@ int sqlite3HeaderSizeBtree(void){ return ROUND8(sizeof(MemPage)); }
|
||||
int sqlite3BtreeSharable(Btree *p){
|
||||
return p->sharable;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the number of connections to the BtShared object accessed by
|
||||
** the Btree handle passed as the only argument. For private caches
|
||||
** this is always 1. For shared caches it may be 1 or greater.
|
||||
*/
|
||||
int sqlite3BtreeConnectionCount(Btree *p){
|
||||
testcase( p->sharable );
|
||||
return p->pBt->nRef;
|
||||
}
|
||||
#endif
|
||||
|
||||
+5
-3
@@ -13,8 +13,8 @@
|
||||
** subsystem. See comments in the source code for a detailed description
|
||||
** of what each interface routine does.
|
||||
*/
|
||||
#ifndef _BTREE_H_
|
||||
#define _BTREE_H_
|
||||
#ifndef SQLITE_BTREE_H
|
||||
#define SQLITE_BTREE_H
|
||||
|
||||
/* TODO: This definition is just included so other modules compile. It
|
||||
** needs to be revisited.
|
||||
@@ -328,11 +328,13 @@ void sqlite3BtreeCursorList(Btree*);
|
||||
void sqlite3BtreeEnterAll(sqlite3*);
|
||||
int sqlite3BtreeSharable(Btree*);
|
||||
void sqlite3BtreeEnterCursor(BtCursor*);
|
||||
int sqlite3BtreeConnectionCount(Btree*);
|
||||
#else
|
||||
# define sqlite3BtreeEnter(X)
|
||||
# define sqlite3BtreeEnterAll(X)
|
||||
# define sqlite3BtreeSharable(X) 0
|
||||
# define sqlite3BtreeEnterCursor(X)
|
||||
# define sqlite3BtreeConnectionCount(X) 1
|
||||
#endif
|
||||
|
||||
#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE
|
||||
@@ -357,4 +359,4 @@ void sqlite3BtreeCursorList(Btree*);
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _BTREE_H_ */
|
||||
#endif /* SQLITE_BTREE_H */
|
||||
|
||||
+16
-12
@@ -338,7 +338,7 @@ Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){
|
||||
*/
|
||||
Table *sqlite3LocateTable(
|
||||
Parse *pParse, /* context in which to report errors */
|
||||
int isView, /* True if looking for a VIEW rather than a TABLE */
|
||||
u32 flags, /* LOCATE_VIEW or LOCATE_NOERR */
|
||||
const char *zName, /* Name of the table we are looking for */
|
||||
const char *zDbase /* Name of the database. Might be NULL */
|
||||
){
|
||||
@@ -352,7 +352,7 @@ Table *sqlite3LocateTable(
|
||||
|
||||
p = sqlite3FindTable(pParse->db, zName, zDbase);
|
||||
if( p==0 ){
|
||||
const char *zMsg = isView ? "no such view" : "no such table";
|
||||
const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table";
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
if( sqlite3FindDbName(pParse->db, zDbase)<1 ){
|
||||
/* If zName is the not the name of a table in the schema created using
|
||||
@@ -364,12 +364,14 @@ Table *sqlite3LocateTable(
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if( zDbase ){
|
||||
sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName);
|
||||
}else{
|
||||
sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName);
|
||||
if( (flags & LOCATE_NOERR)==0 ){
|
||||
if( zDbase ){
|
||||
sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName);
|
||||
}else{
|
||||
sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName);
|
||||
}
|
||||
pParse->checkSchema = 1;
|
||||
}
|
||||
pParse->checkSchema = 1;
|
||||
}
|
||||
|
||||
return p;
|
||||
@@ -386,7 +388,7 @@ Table *sqlite3LocateTable(
|
||||
*/
|
||||
Table *sqlite3LocateTableItem(
|
||||
Parse *pParse,
|
||||
int isView,
|
||||
u32 flags,
|
||||
struct SrcList_item *p
|
||||
){
|
||||
const char *zDb;
|
||||
@@ -397,7 +399,7 @@ Table *sqlite3LocateTableItem(
|
||||
}else{
|
||||
zDb = p->zDatabase;
|
||||
}
|
||||
return sqlite3LocateTable(pParse, isView, p->zName, zDb);
|
||||
return sqlite3LocateTable(pParse, flags, p->zName, zDb);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2504,6 +2506,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
|
||||
assert( pName->nSrc==1 );
|
||||
if( sqlite3ReadSchema(pParse) ) goto exit_drop_table;
|
||||
if( noErr ) db->suppressErr++;
|
||||
assert( isView==0 || isView==LOCATE_VIEW );
|
||||
pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]);
|
||||
if( noErr ) db->suppressErr--;
|
||||
|
||||
@@ -3434,10 +3437,11 @@ void sqlite3DefaultRowEst(Index *pIdx){
|
||||
int i;
|
||||
|
||||
/* Set the first entry (number of rows in the index) to the estimated
|
||||
** number of rows in the table. Or 10, if the estimated number of rows
|
||||
** in the table is less than that. */
|
||||
** number of rows in the table, or half the number of rows in the table
|
||||
** for a partial index. But do not let the estimate drop below 10. */
|
||||
a[0] = pIdx->pTable->nRowLogEst;
|
||||
if( a[0]<33 ) a[0] = 33; assert( 33==sqlite3LogEst(10) );
|
||||
if( pIdx->pPartIdxWhere!=0 ) a[0] -= 10; assert( 10==sqlite3LogEst(2) );
|
||||
if( a[0]<33 ) a[0] = 33; assert( 33==sqlite3LogEst(10) );
|
||||
|
||||
/* Estimate that a[1] is 10, a[2] is 9, a[3] is 8, a[4] is 7, a[5] is
|
||||
** 6 and each subsequent value (if any) is 5. */
|
||||
|
||||
+5
-3
@@ -45,8 +45,10 @@ static const char * const azCompileOpt[] = {
|
||||
#if SQLITE_CHECK_PAGES
|
||||
"CHECK_PAGES",
|
||||
#endif
|
||||
#if defined(__clang__) && defined(__clang_version__)
|
||||
"COMPILER=clang-" __clang_version__,
|
||||
#if defined(__clang__) && defined(__clang_major__)
|
||||
"COMPILER=clang-" CTIMEOPT_VAL(__clang_major__) "."
|
||||
CTIMEOPT_VAL(__clang_minor__) "."
|
||||
CTIMEOPT_VAL(__clang_patchlevel__),
|
||||
#elif defined(_MSC_VER)
|
||||
"COMPILER=msvc-" CTIMEOPT_VAL(_MSC_VER),
|
||||
#elif defined(__GNUC__) && defined(__VERSION__)
|
||||
@@ -71,7 +73,7 @@ static const char * const azCompileOpt[] = {
|
||||
"DISABLE_LFS",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_8_3_NAMES
|
||||
"ENABLE_8_3_NAMES",
|
||||
"ENABLE_8_3_NAMES=" CTIMEOPT_VAL(SQLITE_ENABLE_8_3_NAMES),
|
||||
#endif
|
||||
#if SQLITE_ENABLE_API_ARMOR
|
||||
"ENABLE_API_ARMOR",
|
||||
|
||||
+3
-3
@@ -58,10 +58,10 @@
|
||||
*/
|
||||
#define VTAB_SCHEMA \
|
||||
"CREATE TABLE xx( " \
|
||||
" name STRING, /* Name of table or index */" \
|
||||
" path INTEGER, /* Path to page from root */" \
|
||||
" name TEXT, /* Name of table or index */" \
|
||||
" path TEXT, /* Path to page from root */" \
|
||||
" pageno INTEGER, /* Page number */" \
|
||||
" pagetype STRING, /* 'internal', 'leaf' or 'overflow' */" \
|
||||
" pagetype TEXT, /* 'internal', 'leaf' or 'overflow' */" \
|
||||
" ncell INTEGER, /* Cells on page (0 for overflow) */" \
|
||||
" payload INTEGER, /* Bytes of payload on this page */" \
|
||||
" unused INTEGER, /* Bytes of unused space on this page */" \
|
||||
|
||||
+66
-1
@@ -1818,6 +1818,11 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int *prRhsHasNull){
|
||||
eType = IN_INDEX_INDEX_ASC + pIdx->aSortOrder[0];
|
||||
|
||||
if( prRhsHasNull && !pTab->aCol[iCol].notNull ){
|
||||
#ifdef SQLITE_ENABLE_COLUMN_USED_MASK
|
||||
const i64 sOne = 1;
|
||||
sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed,
|
||||
iTab, 0, 0, (u8*)&sOne, P4_INT64);
|
||||
#endif
|
||||
*prRhsHasNull = ++pParse->nMem;
|
||||
sqlite3SetHasNullFlag(v, iTab, *prRhsHasNull);
|
||||
}
|
||||
@@ -1830,7 +1835,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int *prRhsHasNull){
|
||||
/* If no preexisting index is available for the IN clause
|
||||
** and IN_INDEX_NOOP is an allowed reply
|
||||
** and the RHS of the IN operator is a list, not a subquery
|
||||
** and the RHS is not contant or has two or fewer terms,
|
||||
** and the RHS is not constant or has two or fewer terms,
|
||||
** then it is not worth creating an ephemeral table to evaluate
|
||||
** the IN operator so return IN_INDEX_NOOP.
|
||||
*/
|
||||
@@ -2938,6 +2943,11 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
||||
assert( !ExprHasProperty(pExpr, EP_IntValue) );
|
||||
zId = pExpr->u.zToken;
|
||||
pDef = sqlite3FindFunction(db, zId, nFarg, enc, 0);
|
||||
#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
|
||||
if( pDef==0 && pParse->explain ){
|
||||
pDef = sqlite3FindFunction(db, "unknown", nFarg, enc, 0);
|
||||
}
|
||||
#endif
|
||||
if( pDef==0 || pDef->xFinalize!=0 ){
|
||||
sqlite3ErrorMsg(pParse, "unknown function: %s()", zId);
|
||||
break;
|
||||
@@ -3960,6 +3970,61 @@ int sqlite3ExprImpliesExpr(Expr *pE1, Expr *pE2, int iTab){
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** An instance of the following structure is used by the tree walker
|
||||
** to determine if an expression can be evaluated by reference to the
|
||||
** index only, without having to do a search for the corresponding
|
||||
** table entry. The IdxCover.pIdx field is the index. IdxCover.iCur
|
||||
** is the cursor for the table.
|
||||
*/
|
||||
struct IdxCover {
|
||||
Index *pIdx; /* The index to be tested for coverage */
|
||||
int iCur; /* Cursor number for the table corresponding to the index */
|
||||
};
|
||||
|
||||
/*
|
||||
** Check to see if there are references to columns in table
|
||||
** pWalker->u.pIdxCover->iCur can be satisfied using the index
|
||||
** pWalker->u.pIdxCover->pIdx.
|
||||
*/
|
||||
static int exprIdxCover(Walker *pWalker, Expr *pExpr){
|
||||
if( pExpr->op==TK_COLUMN
|
||||
&& pExpr->iTable==pWalker->u.pIdxCover->iCur
|
||||
&& sqlite3ColumnOfIndex(pWalker->u.pIdxCover->pIdx, pExpr->iColumn)<0
|
||||
){
|
||||
pWalker->eCode = 1;
|
||||
return WRC_Abort;
|
||||
}
|
||||
return WRC_Continue;
|
||||
}
|
||||
|
||||
/*
|
||||
** Determine if an index pIdx on table with cursor iCur contains will
|
||||
** the expression pExpr. Return true if the index does cover the
|
||||
** expression and false if the pExpr expression references table columns
|
||||
** that are not found in the index pIdx.
|
||||
**
|
||||
** An index covering an expression means that the expression can be
|
||||
** evaluated using only the index and without having to lookup the
|
||||
** corresponding table entry.
|
||||
*/
|
||||
int sqlite3ExprCoveredByIndex(
|
||||
Expr *pExpr, /* The index to be tested */
|
||||
int iCur, /* The cursor number for the corresponding table */
|
||||
Index *pIdx /* The index that might be used for coverage */
|
||||
){
|
||||
Walker w;
|
||||
struct IdxCover xcov;
|
||||
memset(&w, 0, sizeof(w));
|
||||
xcov.iCur = iCur;
|
||||
xcov.pIdx = pIdx;
|
||||
w.xExprCallback = exprIdxCover;
|
||||
w.u.pIdxCover = &xcov;
|
||||
sqlite3WalkExpr(&w, pExpr);
|
||||
return !w.eCode;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** An instance of the following structure is used by the tree walker
|
||||
** to count references to table columns in the arguments of an
|
||||
|
||||
+26
-3
@@ -1316,6 +1316,26 @@ static void trimFunc(
|
||||
}
|
||||
|
||||
|
||||
#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
|
||||
/*
|
||||
** The "unknown" function is automatically substituted in place of
|
||||
** any unrecognized function name when doing an EXPLAIN or EXPLAIN QUERY PLAN
|
||||
** when the SQLITE_ENABLE_UNKNOWN_FUNCTION compile-time option is used.
|
||||
** When the "sqlite3" command-line shell is built using this functionality,
|
||||
** that allows an EXPLAIN or EXPLAIN QUERY PLAN for complex queries
|
||||
** involving application-defined functions to be examined in a generic
|
||||
** sqlite3 shell.
|
||||
*/
|
||||
static void unknownFunc(
|
||||
sqlite3_context *context,
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
/* no-op */
|
||||
}
|
||||
#endif /*SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION*/
|
||||
|
||||
|
||||
/* IMP: R-25361-16150 This function is omitted from SQLite by default. It
|
||||
** is only available if the SQLITE_SOUNDEX compile-time option is used
|
||||
** when SQLite is built.
|
||||
@@ -1786,13 +1806,16 @@ void sqlite3RegisterBuiltinFunctions(void){
|
||||
AGGREGATE(group_concat, 2, 0, 0, groupConcatStep, groupConcatFinalize),
|
||||
|
||||
LIKEFUNC(glob, 2, &globInfo, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
|
||||
#ifdef SQLITE_CASE_SENSITIVE_LIKE
|
||||
#ifdef SQLITE_CASE_SENSITIVE_LIKE
|
||||
LIKEFUNC(like, 2, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
|
||||
LIKEFUNC(like, 3, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
|
||||
#else
|
||||
#else
|
||||
LIKEFUNC(like, 2, &likeInfoNorm, SQLITE_FUNC_LIKE),
|
||||
LIKEFUNC(like, 3, &likeInfoNorm, SQLITE_FUNC_LIKE),
|
||||
#endif
|
||||
#endif
|
||||
#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
|
||||
FUNCTION(unknown, -1, 0, 0, unknownFunc ),
|
||||
#endif
|
||||
FUNCTION(coalesce, 1, 0, 0, 0 ),
|
||||
FUNCTION(coalesce, 0, 0, 0, 0 ),
|
||||
FUNCTION2(coalesce, -1, 0, 0, noopFunc, SQLITE_FUNC_COALESCE),
|
||||
|
||||
+3
-3
@@ -12,8 +12,8 @@
|
||||
** This is the header file for the generic hash-table implementation
|
||||
** used in SQLite.
|
||||
*/
|
||||
#ifndef _SQLITE_HASH_H_
|
||||
#define _SQLITE_HASH_H_
|
||||
#ifndef SQLITE_HASH_H
|
||||
#define SQLITE_HASH_H
|
||||
|
||||
/* Forward declarations of structures. */
|
||||
typedef struct Hash Hash;
|
||||
@@ -93,4 +93,4 @@ void sqlite3HashClear(Hash*);
|
||||
*/
|
||||
/* #define sqliteHashCount(H) ((H)->count) // NOT USED */
|
||||
|
||||
#endif /* _SQLITE_HASH_H_ */
|
||||
#endif /* SQLITE_HASH_H */
|
||||
|
||||
+3
-3
@@ -13,8 +13,8 @@
|
||||
** This file contains inline asm code for retrieving "high-performance"
|
||||
** counters for x86 class CPUs.
|
||||
*/
|
||||
#ifndef _HWTIME_H_
|
||||
#define _HWTIME_H_
|
||||
#ifndef SQLITE_HWTIME_H
|
||||
#define SQLITE_HWTIME_H
|
||||
|
||||
/*
|
||||
** The following routine only works on pentium-class (or newer) processors.
|
||||
@@ -82,4 +82,4 @@
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* !defined(_HWTIME_H_) */
|
||||
#endif /* !defined(SQLITE_HWTIME_H) */
|
||||
|
||||
+9
-1
@@ -16,6 +16,9 @@
|
||||
*/
|
||||
|
||||
#include "sqliteInt.h"
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
# include "sqlrr.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Execute SQL code. Return one of the SQLITE_ success/failure
|
||||
@@ -42,7 +45,9 @@ int sqlite3_exec(
|
||||
|
||||
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
|
||||
if( zSql==0 ) zSql = "";
|
||||
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecExec(db, zSql);
|
||||
#endif
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
sqlite3Error(db, SQLITE_OK);
|
||||
while( rc==SQLITE_OK && zSql[0] ){
|
||||
@@ -123,6 +128,9 @@ int sqlite3_exec(
|
||||
exec_out:
|
||||
if( pStmt ) sqlite3VdbeFinalize((Vdbe *)pStmt);
|
||||
sqlite3DbFree(db, azCols);
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecExecEnd(db);
|
||||
#endif
|
||||
|
||||
rc = sqlite3ApiExit(db, rc);
|
||||
if( rc!=SQLITE_OK && pzErrMsg ){
|
||||
|
||||
+1
-1
@@ -91,7 +91,7 @@
|
||||
# define sqlite3_enable_shared_cache 0
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_OMIT_TRACE
|
||||
#if defined(SQLITE_OMIT_TRACE) || defined(SQLITE_OMIT_DEPRECATED)
|
||||
# define sqlite3_profile 0
|
||||
# define sqlite3_trace 0
|
||||
#endif
|
||||
|
||||
+186
-2
@@ -16,6 +16,9 @@
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
# include "sqlrr.h"
|
||||
#endif
|
||||
#ifdef SQLITE_ENABLE_FTS3
|
||||
# include "fts3.h"
|
||||
#endif
|
||||
@@ -1033,6 +1036,9 @@ static int sqlite3Close(sqlite3 *db, int forceZombie){
|
||||
return SQLITE_MISUSE_BKPT;
|
||||
}
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
if( db->mTrace & SQLITE_TRACE_CLOSE ){
|
||||
db->xTrace(SQLITE_TRACE_CLOSE, db->pTraceArg, db, 0);
|
||||
}
|
||||
|
||||
/* Force xDisconnect calls on all virtual tables */
|
||||
disconnectAllVtab(db);
|
||||
@@ -1204,6 +1210,10 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
|
||||
if( db->lookaside.bMalloced ){
|
||||
sqlite3_free(db->lookaside.pStart);
|
||||
}
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecClose(db);
|
||||
#endif
|
||||
|
||||
sqlite3_free(db);
|
||||
}
|
||||
|
||||
@@ -1801,7 +1811,8 @@ int sqlite3_overload_function(
|
||||
** trace is a pointer to a function that is invoked at the start of each
|
||||
** SQL statement.
|
||||
*/
|
||||
void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
void *sqlite3_trace(sqlite3 *db, void(*xTrace)(void*,const char*), void *pArg){
|
||||
void *pOld;
|
||||
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
@@ -1812,11 +1823,36 @@ void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){
|
||||
#endif
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
pOld = db->pTraceArg;
|
||||
db->xTrace = xTrace;
|
||||
db->mTrace = xTrace ? SQLITE_TRACE_LEGACY : 0;
|
||||
db->xTrace = (int(*)(u32,void*,void*,void*))xTrace;
|
||||
db->pTraceArg = pArg;
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return pOld;
|
||||
}
|
||||
#endif /* SQLITE_OMIT_DEPRECATED */
|
||||
|
||||
/* Register a trace callback using the version-2 interface.
|
||||
*/
|
||||
int sqlite3_trace_v2(
|
||||
sqlite3 *db, /* Trace this connection */
|
||||
unsigned mTrace, /* Mask of events to be traced */
|
||||
int(*xTrace)(unsigned,void*,void*,void*), /* Callback to invoke */
|
||||
void *pArg /* Context */
|
||||
){
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !sqlite3SafetyCheckOk(db) ){
|
||||
return SQLITE_MISUSE_BKPT;
|
||||
}
|
||||
#endif
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
db->mTrace = mTrace;
|
||||
db->xTrace = xTrace;
|
||||
db->pTraceArg = pArg;
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
/*
|
||||
** Register a profile function. The pArg from the previously registered
|
||||
** profile function is returned.
|
||||
@@ -1845,6 +1881,7 @@ void *sqlite3_profile(
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return pOld;
|
||||
}
|
||||
#endif /* SQLITE_OMIT_DEPRECATED */
|
||||
#endif /* SQLITE_OMIT_TRACE */
|
||||
|
||||
/*
|
||||
@@ -2462,6 +2499,44 @@ int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){
|
||||
}
|
||||
return oldLimit; /* IMP: R-53341-35419 */
|
||||
}
|
||||
#if defined(SQLITE_ENABLE_AUTO_PROFILE)
|
||||
/* stderr logging */
|
||||
void _sqlite_auto_profile(void *aux, const char *sql, u64 ns);
|
||||
void _sqlite_auto_trace(void *aux, const char *sql);
|
||||
void _sqlite_auto_profile(void *aux, const char *sql, u64 ns) {
|
||||
#pragma unused(aux)
|
||||
fprintf(stderr, "Query: %s\n Execution Time: %llu ms\n", sql, ns / 1000000);
|
||||
}
|
||||
void _sqlite_auto_trace(void *aux, const char *sql) {
|
||||
fprintf(stderr, "TraceSQL(%p): %s\n", aux, sql);
|
||||
}
|
||||
|
||||
/* syslog logging */
|
||||
#include <asl.h>
|
||||
static aslclient autolog_client = NULL;
|
||||
static void _close_asl_log() {
|
||||
if( NULL!=autolog_client ){
|
||||
asl_close(autolog_client);
|
||||
autolog_client = NULL;
|
||||
}
|
||||
}
|
||||
static void _open_asl_log() {
|
||||
if( NULL==autolog_client ){
|
||||
autolog_client = asl_open("SQLite", NULL, 0);
|
||||
atexit(_close_asl_log);
|
||||
}
|
||||
}
|
||||
|
||||
void _sqlite_auto_profile_syslog(void *aux, const char *sql, u64 ns);
|
||||
void _sqlite_auto_trace_syslog(void *aux, const char *sql);
|
||||
void _sqlite_auto_profile_syslog(void *aux, const char *sql, u64 ns) {
|
||||
#pragma unused(aux)
|
||||
asl_log(autolog_client, NULL, ASL_LEVEL_NOTICE, "Query: %s\n Execution Time: %llu ms\n", sql, ns / 1000000);
|
||||
}
|
||||
void _sqlite_auto_trace_syslog(void *aux, const char *sql) {
|
||||
asl_log(autolog_client, NULL, ASL_LEVEL_NOTICE, "TraceSQL(%p): %s\n", aux, sql);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** This function is used to parse both URIs and non-URI filenames passed by the
|
||||
@@ -2708,6 +2783,57 @@ int sqlite3ParseUri(
|
||||
return rc;
|
||||
}
|
||||
|
||||
#if defined(SQLITE_ENABLE_AUTO_PROFILE)
|
||||
#define SQLITE_AUTOLOGGING_STDERR 1
|
||||
#define SQLITE_AUTOLOGGING_SYSLOG 2
|
||||
static void enableAutoLogging(
|
||||
sqlite3 *db
|
||||
){
|
||||
char *envprofile = getenv("SQLITE_AUTO_PROFILE");
|
||||
|
||||
if( envprofile!=NULL ){
|
||||
int where = 0;
|
||||
if( !strncasecmp("1", envprofile, 1) ){
|
||||
if( isatty(2) ){
|
||||
where = SQLITE_AUTOLOGGING_STDERR;
|
||||
}else{
|
||||
where = SQLITE_AUTOLOGGING_SYSLOG;
|
||||
}
|
||||
} else if( !strncasecmp("stderr", envprofile, 6) ){
|
||||
where = SQLITE_AUTOLOGGING_STDERR;
|
||||
} else if( !strncasecmp("syslog", envprofile, 6) ){
|
||||
where = SQLITE_AUTOLOGGING_SYSLOG;
|
||||
}
|
||||
if( where==SQLITE_AUTOLOGGING_STDERR ){
|
||||
sqlite3_profile(db, _sqlite_auto_profile, db);
|
||||
}else if( where==SQLITE_AUTOLOGGING_SYSLOG ){
|
||||
_open_asl_log();
|
||||
sqlite3_profile(db, _sqlite_auto_profile_syslog, db);
|
||||
}
|
||||
}
|
||||
char *envtrace = getenv("SQLITE_AUTO_TRACE");
|
||||
if( envtrace!=NULL ){
|
||||
int where = 0;
|
||||
if( !strncasecmp("1", envtrace, 1) ){
|
||||
if( isatty(2) ){
|
||||
where = SQLITE_AUTOLOGGING_STDERR;
|
||||
}else{
|
||||
where = SQLITE_AUTOLOGGING_SYSLOG;
|
||||
}
|
||||
} else if( !strncasecmp("stderr", envtrace, 6) ){
|
||||
where = SQLITE_AUTOLOGGING_STDERR;
|
||||
} else if( !strncasecmp("syslog", envtrace, 6) ){
|
||||
where = SQLITE_AUTOLOGGING_SYSLOG;
|
||||
}
|
||||
if( where==SQLITE_AUTOLOGGING_STDERR ){
|
||||
sqlite3_trace(db, _sqlite_auto_trace, db);
|
||||
}else if( where==SQLITE_AUTOLOGGING_SYSLOG ){
|
||||
_open_asl_log();
|
||||
sqlite3_trace(db, _sqlite_auto_trace_syslog, db);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** This routine does the work of opening a database on behalf of
|
||||
@@ -3013,7 +3139,30 @@ opendb_out:
|
||||
}else if( rc!=SQLITE_OK ){
|
||||
db->magic = SQLITE_MAGIC_SICK;
|
||||
}
|
||||
#if defined(__APPLE__) && ENABLE_FORCE_WAL
|
||||
if( db && !rc ){
|
||||
if ((0 == access("/var/db/enableForceWAL", R_OK))) {
|
||||
#ifdef SQLITE_DEBUG
|
||||
fprintf(stderr, "SQLite WAL journal_mode ENABLED by default.\n");
|
||||
#endif
|
||||
|
||||
sqlite3_exec(db, "pragma journal_mode=wal", NULL, NULL, NULL);
|
||||
#ifdef SQLITE_DEBUG
|
||||
// } else {
|
||||
// fprintf(stderr, "SQLite WAL journal_mode NOT ENABLED by default.\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(SQLITE_ENABLE_AUTO_PROFILE)
|
||||
if( db && !rc ){
|
||||
enableAutoLogging(db);
|
||||
}
|
||||
#endif
|
||||
*ppDb = db;
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecOpen(db, zFilename, flags);
|
||||
#endif
|
||||
#ifdef SQLITE_ENABLE_SQLLOG
|
||||
if( sqlite3GlobalConfig.xSqllog ){
|
||||
/* Opening a db handle. Fourth parameter is passed 0. */
|
||||
@@ -3464,11 +3613,20 @@ int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){
|
||||
rc = SQLITE_OK;
|
||||
}else if( fd->pMethods ){
|
||||
rc = sqlite3OsFileControl(fd, op, pArg);
|
||||
#ifndef SQLITE_OMIT_WAL
|
||||
if( (rc==SQLITE_OK)&&(op==SQLITE_FCNTL_LAST_ERRNO)&&(*(int *)pArg==0) ){
|
||||
sqlite3_file *pWalFd = sqlite3PagerWalFile(pPager);
|
||||
if( pWalFd&&(pWalFd->pMethods) ){
|
||||
rc = sqlite3OsFileControl(pWalFd, op, pArg);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}else{
|
||||
rc = SQLITE_NOTFOUND;
|
||||
}
|
||||
sqlite3BtreeLeave(pBtree);
|
||||
}
|
||||
sqlite3Error(db, rc);
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return rc;
|
||||
}
|
||||
@@ -3904,6 +4062,32 @@ int sqlite3_db_readonly(sqlite3 *db, const char *zDbName){
|
||||
pBt = sqlite3DbNameToBtree(db, zDbName);
|
||||
return pBt ? sqlite3BtreeIsReadonly(pBt) : -1;
|
||||
}
|
||||
#if (SQLITE_ENABLE_APPLE_SPI>0) && defined(__APPLE__)
|
||||
|
||||
#include "sqlite3_private.h"
|
||||
|
||||
/*
|
||||
** Testing a file path for sqlite locks held by a process ID.
|
||||
** Returns SQLITE_LOCKSTATE_ON if locks are present on path
|
||||
** that would prevent writing to the database.
|
||||
*/
|
||||
int _sqlite3_lockstate(const char *path, pid_t pid){
|
||||
sqlite3 *db = NULL;
|
||||
|
||||
if( sqlite3_open_v2(path, &db, SQLITE_OPEN_READONLY, NULL) == SQLITE_OK ){
|
||||
LockstatePID lockstate = {pid, -1};
|
||||
sqlite3_file_control(db, NULL, SQLITE_FCNTL_LOCKSTATE_PID, &lockstate);
|
||||
sqlite3_close(db);
|
||||
int state = lockstate.state;
|
||||
return state;
|
||||
}
|
||||
if( NULL!=db ){
|
||||
sqlite3_close(db); /* need to close even if open returns an error */
|
||||
}
|
||||
return SQLITE_LOCKSTATE_ERROR;
|
||||
}
|
||||
|
||||
#endif /* SQLITE_ENABLE_APPLE_SPI */
|
||||
|
||||
#ifdef SQLITE_ENABLE_SNAPSHOT
|
||||
/*
|
||||
|
||||
+3
-3
@@ -12,8 +12,8 @@
|
||||
**
|
||||
** This file contains code that is specific to MSVC.
|
||||
*/
|
||||
#ifndef _MSVC_H_
|
||||
#define _MSVC_H_
|
||||
#ifndef SQLITE_MSVC_H
|
||||
#define SQLITE_MSVC_H
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(disable : 4054)
|
||||
@@ -33,4 +33,4 @@
|
||||
#pragma warning(disable : 4706)
|
||||
#endif /* defined(_MSC_VER) */
|
||||
|
||||
#endif /* _MSVC_H_ */
|
||||
#endif /* SQLITE_MSVC_H */
|
||||
|
||||
@@ -13,9 +13,7 @@
|
||||
** This file contains OS interface code that is common to all
|
||||
** architectures.
|
||||
*/
|
||||
#define _SQLITE_OS_C_ 1
|
||||
#include "sqliteInt.h"
|
||||
#undef _SQLITE_OS_C_
|
||||
|
||||
/*
|
||||
** If we compile with the SQLITE_TEST macro set, then the following block
|
||||
@@ -207,12 +205,18 @@ int sqlite3OsOpen(
|
||||
int *pFlagsOut
|
||||
){
|
||||
int rc;
|
||||
int openFlags;
|
||||
DO_OS_MALLOC_TEST(0);
|
||||
/* 0x87f7f is a mask of SQLITE_OPEN_ flags that are valid to be passed
|
||||
** down into the VFS layer. Some SQLITE_OPEN_ flags (for example,
|
||||
** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before
|
||||
** reaching the VFS. */
|
||||
rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x87f7f, pFlagsOut);
|
||||
#if SQLITE_ENABLE_DATA_PROTECTION
|
||||
openFlags = flags & (0x87f7f | SQLITE_OPEN_FILEPROTECTION_MASK);
|
||||
#else
|
||||
openFlags = flags & 0x87f7f;
|
||||
#endif
|
||||
rc = pVfs->xOpen(pVfs, zPath, pFile, openFlags, pFlagsOut);
|
||||
assert( rc==SQLITE_OK || pFile->pMethods==0 );
|
||||
return rc;
|
||||
}
|
||||
|
||||
+3
-3
@@ -13,8 +13,8 @@
|
||||
** This file contains pre-processor directives related to operating system
|
||||
** detection and/or setup.
|
||||
*/
|
||||
#ifndef _OS_SETUP_H_
|
||||
#define _OS_SETUP_H_
|
||||
#ifndef SQLITE_OS_SETUP_H
|
||||
#define SQLITE_OS_SETUP_H
|
||||
|
||||
/*
|
||||
** Figure out if we are dealing with Unix, Windows, or some other operating
|
||||
@@ -54,4 +54,4 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif /* _OS_SETUP_H_ */
|
||||
#endif /* SQLITE_OS_SETUP_H */
|
||||
|
||||
+1300
-41
File diff suppressed because it is too large
Load Diff
+230
-67
@@ -290,6 +290,17 @@ struct winFile {
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
** The winVfsAppData structure is used for the pAppData member for all of the
|
||||
** Win32 VFS variants.
|
||||
*/
|
||||
typedef struct winVfsAppData winVfsAppData;
|
||||
struct winVfsAppData {
|
||||
const sqlite3_io_methods *pMethod; /* The file I/O methods to use. */
|
||||
void *pAppData; /* The extra pAppData, if any. */
|
||||
BOOL bNoLock; /* Non-zero if locking is disabled. */
|
||||
};
|
||||
|
||||
/*
|
||||
** Allowed values for winFile.ctrlFlags
|
||||
*/
|
||||
@@ -2611,7 +2622,12 @@ static int winClose(sqlite3_file *id){
|
||||
}while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (sqlite3_win32_sleep(100), 1) );
|
||||
#if SQLITE_OS_WINCE
|
||||
#define WINCE_DELETION_ATTEMPTS 3
|
||||
winceDestroyLock(pFile);
|
||||
{
|
||||
winVfsAppData *pAppData = (winVfsAppData*)pFile->pVfs->pAppData;
|
||||
if( pAppData==NULL || !pAppData->bNoLock ){
|
||||
winceDestroyLock(pFile);
|
||||
}
|
||||
}
|
||||
if( pFile->zDeleteOnClose ){
|
||||
int cnt = 0;
|
||||
while(
|
||||
@@ -3343,6 +3359,44 @@ static int winUnlock(sqlite3_file *id, int locktype){
|
||||
return rc;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
****************************** No-op Locking **********************************
|
||||
**
|
||||
** Of the various locking implementations available, this is by far the
|
||||
** simplest: locking is ignored. No attempt is made to lock the database
|
||||
** file for reading or writing.
|
||||
**
|
||||
** This locking mode is appropriate for use on read-only databases
|
||||
** (ex: databases that are burned into CD-ROM, for example.) It can
|
||||
** also be used if the application employs some external mechanism to
|
||||
** prevent simultaneous access of the same database by two or more
|
||||
** database connections. But there is a serious risk of database
|
||||
** corruption if this locking mode is used in situations where multiple
|
||||
** database connections are accessing the same database file at the same
|
||||
** time and one or more of those connections are writing.
|
||||
*/
|
||||
|
||||
static int winNolockLock(sqlite3_file *id, int locktype){
|
||||
UNUSED_PARAMETER(id);
|
||||
UNUSED_PARAMETER(locktype);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
static int winNolockCheckReservedLock(sqlite3_file *id, int *pResOut){
|
||||
UNUSED_PARAMETER(id);
|
||||
UNUSED_PARAMETER(pResOut);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
static int winNolockUnlock(sqlite3_file *id, int locktype){
|
||||
UNUSED_PARAMETER(id);
|
||||
UNUSED_PARAMETER(locktype);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/******************* End of the no-op lock implementation *********************
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
** If *pArg is initially negative then this is a query. Set *pArg to
|
||||
** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set.
|
||||
@@ -3404,6 +3458,15 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){
|
||||
OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
|
||||
return SQLITE_OK;
|
||||
}
|
||||
case SQLITE_FCNTL_PERSIST_WAL: {
|
||||
int bPersist = *(int*)pArg;
|
||||
if( bPersist<0 ){
|
||||
*(int*)pArg = pFile->bPersistWal;
|
||||
}else{
|
||||
pFile->bPersistWal = bPersist!=0;
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
case SQLITE_FCNTL_PERSIST_WAL: {
|
||||
winModeBit(pFile, WINFILE_PERSIST_WAL, (int*)pArg);
|
||||
OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
|
||||
@@ -3621,12 +3684,12 @@ struct winShm {
|
||||
/*
|
||||
** Apply advisory locks for all n bytes beginning at ofst.
|
||||
*/
|
||||
#define _SHM_UNLCK 1
|
||||
#define _SHM_RDLCK 2
|
||||
#define _SHM_WRLCK 3
|
||||
#define WINSHM_UNLCK 1
|
||||
#define WINSHM_RDLCK 2
|
||||
#define WINSHM_WRLCK 3
|
||||
static int winShmSystemLock(
|
||||
winShmNode *pFile, /* Apply locks to this open shared-memory segment */
|
||||
int lockType, /* _SHM_UNLCK, _SHM_RDLCK, or _SHM_WRLCK */
|
||||
int lockType, /* WINSHM_UNLCK, WINSHM_RDLCK, or WINSHM_WRLCK */
|
||||
int ofst, /* Offset to first byte to be locked/unlocked */
|
||||
int nByte /* Number of bytes to lock or unlock */
|
||||
){
|
||||
@@ -3639,12 +3702,12 @@ static int winShmSystemLock(
|
||||
pFile->hFile.h, lockType, ofst, nByte));
|
||||
|
||||
/* Release/Acquire the system-level lock */
|
||||
if( lockType==_SHM_UNLCK ){
|
||||
if( lockType==WINSHM_UNLCK ){
|
||||
rc = winUnlockFile(&pFile->hFile.h, ofst, 0, nByte, 0);
|
||||
}else{
|
||||
/* Initialize the locking parameters */
|
||||
DWORD dwFlags = LOCKFILE_FAIL_IMMEDIATELY;
|
||||
if( lockType == _SHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK;
|
||||
if( lockType == WINSHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK;
|
||||
rc = winLockFile(&pFile->hFile.h, dwFlags, ofst, 0, nByte, 0);
|
||||
}
|
||||
|
||||
@@ -3656,7 +3719,7 @@ static int winShmSystemLock(
|
||||
}
|
||||
|
||||
OSTRACE(("SHM-LOCK file=%p, func=%s, errno=%lu, rc=%s\n",
|
||||
pFile->hFile.h, (lockType == _SHM_UNLCK) ? "winUnlockFile" :
|
||||
pFile->hFile.h, (lockType == WINSHM_UNLCK) ? "winUnlockFile" :
|
||||
"winLockFile", pFile->lastErrno, sqlite3ErrName(rc)));
|
||||
|
||||
return rc;
|
||||
@@ -3784,7 +3847,7 @@ static int winOpenSharedMemory(winFile *pDbFd){
|
||||
/* Check to see if another process is holding the dead-man switch.
|
||||
** If not, truncate the file to zero length.
|
||||
*/
|
||||
if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){
|
||||
if( winShmSystemLock(pShmNode, WINSHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){
|
||||
rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
rc = winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(),
|
||||
@@ -3792,8 +3855,8 @@ static int winOpenSharedMemory(winFile *pDbFd){
|
||||
}
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1);
|
||||
rc = winShmSystemLock(pShmNode, _SHM_RDLCK, WIN_SHM_DMS, 1);
|
||||
winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1);
|
||||
rc = winShmSystemLock(pShmNode, WINSHM_RDLCK, WIN_SHM_DMS, 1);
|
||||
}
|
||||
if( rc ) goto shm_open_err;
|
||||
}
|
||||
@@ -3822,7 +3885,7 @@ static int winOpenSharedMemory(winFile *pDbFd){
|
||||
|
||||
/* Jump here on any error */
|
||||
shm_open_err:
|
||||
winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1);
|
||||
winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1);
|
||||
winShmPurge(pDbFd->pVfs, 0); /* This call frees pShmNode if required */
|
||||
sqlite3_free(p);
|
||||
sqlite3_free(pNew);
|
||||
@@ -3911,7 +3974,7 @@ static int winShmLock(
|
||||
|
||||
/* Unlock the system-level locks */
|
||||
if( (mask & allMask)==0 ){
|
||||
rc = winShmSystemLock(pShmNode, _SHM_UNLCK, ofst+WIN_SHM_BASE, n);
|
||||
rc = winShmSystemLock(pShmNode, WINSHM_UNLCK, ofst+WIN_SHM_BASE, n);
|
||||
}else{
|
||||
rc = SQLITE_OK;
|
||||
}
|
||||
@@ -3939,7 +4002,7 @@ static int winShmLock(
|
||||
/* Get shared locks at the system level, if necessary */
|
||||
if( rc==SQLITE_OK ){
|
||||
if( (allShared & mask)==0 ){
|
||||
rc = winShmSystemLock(pShmNode, _SHM_RDLCK, ofst+WIN_SHM_BASE, n);
|
||||
rc = winShmSystemLock(pShmNode, WINSHM_RDLCK, ofst+WIN_SHM_BASE, n);
|
||||
}else{
|
||||
rc = SQLITE_OK;
|
||||
}
|
||||
@@ -3964,7 +4027,7 @@ static int winShmLock(
|
||||
** also mark the local connection as being locked.
|
||||
*/
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = winShmSystemLock(pShmNode, _SHM_WRLCK, ofst+WIN_SHM_BASE, n);
|
||||
rc = winShmSystemLock(pShmNode, WINSHM_WRLCK, ofst+WIN_SHM_BASE, n);
|
||||
if( rc==SQLITE_OK ){
|
||||
assert( (p->sharedMask & mask)==0 );
|
||||
p->exclMask |= mask;
|
||||
@@ -4407,6 +4470,44 @@ static const sqlite3_io_methods winIoMethod = {
|
||||
winUnfetch /* xUnfetch */
|
||||
};
|
||||
|
||||
/*
|
||||
** This vector defines all the methods that can operate on an
|
||||
** sqlite3_file for win32 without performing any locking.
|
||||
*/
|
||||
static const sqlite3_io_methods winIoNolockMethod = {
|
||||
3, /* iVersion */
|
||||
winClose, /* xClose */
|
||||
winRead, /* xRead */
|
||||
winWrite, /* xWrite */
|
||||
winTruncate, /* xTruncate */
|
||||
winSync, /* xSync */
|
||||
winFileSize, /* xFileSize */
|
||||
winNolockLock, /* xLock */
|
||||
winNolockUnlock, /* xUnlock */
|
||||
winNolockCheckReservedLock, /* xCheckReservedLock */
|
||||
winFileControl, /* xFileControl */
|
||||
winSectorSize, /* xSectorSize */
|
||||
winDeviceCharacteristics, /* xDeviceCharacteristics */
|
||||
winShmMap, /* xShmMap */
|
||||
winShmLock, /* xShmLock */
|
||||
winShmBarrier, /* xShmBarrier */
|
||||
winShmUnmap, /* xShmUnmap */
|
||||
winFetch, /* xFetch */
|
||||
winUnfetch /* xUnfetch */
|
||||
};
|
||||
|
||||
static winVfsAppData winAppData = {
|
||||
&winIoMethod, /* pMethod */
|
||||
0, /* pAppData */
|
||||
0 /* bNoLock */
|
||||
};
|
||||
|
||||
static winVfsAppData winNolockAppData = {
|
||||
&winIoNolockMethod, /* pMethod */
|
||||
0, /* pAppData */
|
||||
1 /* bNoLock */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
**************************** sqlite3_vfs methods ****************************
|
||||
**
|
||||
@@ -4739,7 +4840,7 @@ static int winIsDir(const void *zConverted){
|
||||
** Open a file.
|
||||
*/
|
||||
static int winOpen(
|
||||
sqlite3_vfs *pVfs, /* Used to get maximum path name length */
|
||||
sqlite3_vfs *pVfs, /* Used to get maximum path length and AppData */
|
||||
const char *zName, /* Name of the file (UTF-8) */
|
||||
sqlite3_file *id, /* Write the SQLite file handle here */
|
||||
int flags, /* Open mode flags */
|
||||
@@ -4754,6 +4855,7 @@ static int winOpen(
|
||||
#if SQLITE_OS_WINCE
|
||||
int isTemp = 0;
|
||||
#endif
|
||||
winVfsAppData *pAppData;
|
||||
winFile *pFile = (winFile*)id;
|
||||
void *zConverted; /* Filename in OS encoding */
|
||||
const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */
|
||||
@@ -4975,15 +5077,20 @@ static int winOpen(
|
||||
"rc=%s\n", h, zUtf8Name, dwDesiredAccess, pOutFlags, pOutFlags ?
|
||||
*pOutFlags : 0, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok"));
|
||||
|
||||
pAppData = (winVfsAppData*)pVfs->pAppData;
|
||||
|
||||
#if SQLITE_OS_WINCE
|
||||
if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB
|
||||
&& (rc = winceCreateLock(zName, pFile))!=SQLITE_OK
|
||||
){
|
||||
osCloseHandle(h);
|
||||
sqlite3_free(zConverted);
|
||||
sqlite3_free(zTmpname);
|
||||
OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc)));
|
||||
return rc;
|
||||
{
|
||||
if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB
|
||||
&& ((pAppData==NULL) || !pAppData->bNoLock)
|
||||
&& (rc = winceCreateLock(zName, pFile))!=SQLITE_OK
|
||||
){
|
||||
osCloseHandle(h);
|
||||
sqlite3_free(zConverted);
|
||||
sqlite3_free(zTmpname);
|
||||
OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc)));
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
if( isTemp ){
|
||||
pFile->zDeleteOnClose = zConverted;
|
||||
@@ -4994,7 +5101,7 @@ static int winOpen(
|
||||
}
|
||||
|
||||
sqlite3_free(zTmpname);
|
||||
pFile->pMethod = &winIoMethod;
|
||||
pFile->pMethod = pAppData ? pAppData->pMethod : &winIoMethod;
|
||||
pFile->pVfs = pVfs;
|
||||
pFile->h = h;
|
||||
if( isReadonly ){
|
||||
@@ -5717,53 +5824,103 @@ static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
|
||||
*/
|
||||
int sqlite3_os_init(void){
|
||||
static sqlite3_vfs winVfs = {
|
||||
3, /* iVersion */
|
||||
sizeof(winFile), /* szOsFile */
|
||||
3, /* iVersion */
|
||||
sizeof(winFile), /* szOsFile */
|
||||
SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */
|
||||
0, /* pNext */
|
||||
"win32", /* zName */
|
||||
0, /* pAppData */
|
||||
winOpen, /* xOpen */
|
||||
winDelete, /* xDelete */
|
||||
winAccess, /* xAccess */
|
||||
winFullPathname, /* xFullPathname */
|
||||
winDlOpen, /* xDlOpen */
|
||||
winDlError, /* xDlError */
|
||||
winDlSym, /* xDlSym */
|
||||
winDlClose, /* xDlClose */
|
||||
winRandomness, /* xRandomness */
|
||||
winSleep, /* xSleep */
|
||||
winCurrentTime, /* xCurrentTime */
|
||||
winGetLastError, /* xGetLastError */
|
||||
winCurrentTimeInt64, /* xCurrentTimeInt64 */
|
||||
winSetSystemCall, /* xSetSystemCall */
|
||||
winGetSystemCall, /* xGetSystemCall */
|
||||
winNextSystemCall, /* xNextSystemCall */
|
||||
0, /* pNext */
|
||||
"win32", /* zName */
|
||||
&winAppData, /* pAppData */
|
||||
winOpen, /* xOpen */
|
||||
winDelete, /* xDelete */
|
||||
winAccess, /* xAccess */
|
||||
winFullPathname, /* xFullPathname */
|
||||
winDlOpen, /* xDlOpen */
|
||||
winDlError, /* xDlError */
|
||||
winDlSym, /* xDlSym */
|
||||
winDlClose, /* xDlClose */
|
||||
winRandomness, /* xRandomness */
|
||||
winSleep, /* xSleep */
|
||||
winCurrentTime, /* xCurrentTime */
|
||||
winGetLastError, /* xGetLastError */
|
||||
winCurrentTimeInt64, /* xCurrentTimeInt64 */
|
||||
winSetSystemCall, /* xSetSystemCall */
|
||||
winGetSystemCall, /* xGetSystemCall */
|
||||
winNextSystemCall, /* xNextSystemCall */
|
||||
};
|
||||
#if defined(SQLITE_WIN32_HAS_WIDE)
|
||||
static sqlite3_vfs winLongPathVfs = {
|
||||
3, /* iVersion */
|
||||
sizeof(winFile), /* szOsFile */
|
||||
3, /* iVersion */
|
||||
sizeof(winFile), /* szOsFile */
|
||||
SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */
|
||||
0, /* pNext */
|
||||
"win32-longpath", /* zName */
|
||||
0, /* pAppData */
|
||||
winOpen, /* xOpen */
|
||||
winDelete, /* xDelete */
|
||||
winAccess, /* xAccess */
|
||||
winFullPathname, /* xFullPathname */
|
||||
winDlOpen, /* xDlOpen */
|
||||
winDlError, /* xDlError */
|
||||
winDlSym, /* xDlSym */
|
||||
winDlClose, /* xDlClose */
|
||||
winRandomness, /* xRandomness */
|
||||
winSleep, /* xSleep */
|
||||
winCurrentTime, /* xCurrentTime */
|
||||
winGetLastError, /* xGetLastError */
|
||||
winCurrentTimeInt64, /* xCurrentTimeInt64 */
|
||||
winSetSystemCall, /* xSetSystemCall */
|
||||
winGetSystemCall, /* xGetSystemCall */
|
||||
winNextSystemCall, /* xNextSystemCall */
|
||||
0, /* pNext */
|
||||
"win32-longpath", /* zName */
|
||||
&winAppData, /* pAppData */
|
||||
winOpen, /* xOpen */
|
||||
winDelete, /* xDelete */
|
||||
winAccess, /* xAccess */
|
||||
winFullPathname, /* xFullPathname */
|
||||
winDlOpen, /* xDlOpen */
|
||||
winDlError, /* xDlError */
|
||||
winDlSym, /* xDlSym */
|
||||
winDlClose, /* xDlClose */
|
||||
winRandomness, /* xRandomness */
|
||||
winSleep, /* xSleep */
|
||||
winCurrentTime, /* xCurrentTime */
|
||||
winGetLastError, /* xGetLastError */
|
||||
winCurrentTimeInt64, /* xCurrentTimeInt64 */
|
||||
winSetSystemCall, /* xSetSystemCall */
|
||||
winGetSystemCall, /* xGetSystemCall */
|
||||
winNextSystemCall, /* xNextSystemCall */
|
||||
};
|
||||
#endif
|
||||
static sqlite3_vfs winNolockVfs = {
|
||||
3, /* iVersion */
|
||||
sizeof(winFile), /* szOsFile */
|
||||
SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */
|
||||
0, /* pNext */
|
||||
"win32-none", /* zName */
|
||||
&winNolockAppData, /* pAppData */
|
||||
winOpen, /* xOpen */
|
||||
winDelete, /* xDelete */
|
||||
winAccess, /* xAccess */
|
||||
winFullPathname, /* xFullPathname */
|
||||
winDlOpen, /* xDlOpen */
|
||||
winDlError, /* xDlError */
|
||||
winDlSym, /* xDlSym */
|
||||
winDlClose, /* xDlClose */
|
||||
winRandomness, /* xRandomness */
|
||||
winSleep, /* xSleep */
|
||||
winCurrentTime, /* xCurrentTime */
|
||||
winGetLastError, /* xGetLastError */
|
||||
winCurrentTimeInt64, /* xCurrentTimeInt64 */
|
||||
winSetSystemCall, /* xSetSystemCall */
|
||||
winGetSystemCall, /* xGetSystemCall */
|
||||
winNextSystemCall, /* xNextSystemCall */
|
||||
};
|
||||
#if defined(SQLITE_WIN32_HAS_WIDE)
|
||||
static sqlite3_vfs winLongPathNolockVfs = {
|
||||
3, /* iVersion */
|
||||
sizeof(winFile), /* szOsFile */
|
||||
SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */
|
||||
0, /* pNext */
|
||||
"win32-longpath-none", /* zName */
|
||||
&winNolockAppData, /* pAppData */
|
||||
winOpen, /* xOpen */
|
||||
winDelete, /* xDelete */
|
||||
winAccess, /* xAccess */
|
||||
winFullPathname, /* xFullPathname */
|
||||
winDlOpen, /* xDlOpen */
|
||||
winDlError, /* xDlError */
|
||||
winDlSym, /* xDlSym */
|
||||
winDlClose, /* xDlClose */
|
||||
winRandomness, /* xRandomness */
|
||||
winSleep, /* xSleep */
|
||||
winCurrentTime, /* xCurrentTime */
|
||||
winGetLastError, /* xGetLastError */
|
||||
winCurrentTimeInt64, /* xCurrentTimeInt64 */
|
||||
winSetSystemCall, /* xSetSystemCall */
|
||||
winGetSystemCall, /* xGetSystemCall */
|
||||
winNextSystemCall, /* xNextSystemCall */
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -5787,6 +5944,12 @@ int sqlite3_os_init(void){
|
||||
sqlite3_vfs_register(&winLongPathVfs, 0);
|
||||
#endif
|
||||
|
||||
sqlite3_vfs_register(&winNolockVfs, 0);
|
||||
|
||||
#if defined(SQLITE_WIN32_HAS_WIDE)
|
||||
sqlite3_vfs_register(&winLongPathNolockVfs, 0);
|
||||
#endif
|
||||
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -12,8 +12,8 @@
|
||||
**
|
||||
** This file contains code that is specific to Windows.
|
||||
*/
|
||||
#ifndef _OS_WIN_H_
|
||||
#define _OS_WIN_H_
|
||||
#ifndef SQLITE_OS_WIN_H
|
||||
#define SQLITE_OS_WIN_H
|
||||
|
||||
/*
|
||||
** Include the primary Windows SDK header file.
|
||||
@@ -85,4 +85,4 @@
|
||||
# define SQLITE_OS_WIN_THREADS 0
|
||||
#endif
|
||||
|
||||
#endif /* _OS_WIN_H_ */
|
||||
#endif /* SQLITE_OS_WIN_H */
|
||||
|
||||
+58
-9
@@ -2471,7 +2471,11 @@ static int pager_delmaster(Pager *pPager, const char *zMaster){
|
||||
if( !pMaster ){
|
||||
rc = SQLITE_NOMEM_BKPT;
|
||||
}else{
|
||||
const int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MASTER_JOURNAL);
|
||||
const int flags =
|
||||
#if SQLITE_ENABLE_DATA_PROTECTION
|
||||
(pPager->vfsFlags&SQLITE_OPEN_FILEPROTECTION_MASK)|
|
||||
#endif
|
||||
(SQLITE_OPEN_READONLY|SQLITE_OPEN_MASTER_JOURNAL);
|
||||
rc = sqlite3OsOpen(pVfs, zMaster, pMaster, flags, 0);
|
||||
}
|
||||
if( rc!=SQLITE_OK ) goto delmaster_out;
|
||||
@@ -2507,7 +2511,11 @@ static int pager_delmaster(Pager *pPager, const char *zMaster){
|
||||
** so, return without deleting the master journal file.
|
||||
*/
|
||||
int c;
|
||||
int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL);
|
||||
int flags =
|
||||
#if SQLITE_ENABLE_DATA_PROTECTION
|
||||
(pPager->vfsFlags&SQLITE_OPEN_FILEPROTECTION_MASK)|
|
||||
#endif
|
||||
(SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL);
|
||||
rc = sqlite3OsOpen(pVfs, zJournal, pJournal, flags, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
goto delmaster_out;
|
||||
@@ -3582,7 +3590,11 @@ static int pagerOpentemp(
|
||||
sqlite3_opentemp_count++; /* Used for testing and analysis only */
|
||||
#endif
|
||||
|
||||
vfsFlags |= SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
|
||||
vfsFlags |=
|
||||
#if SQLITE_ENABLE_DATA_PROTECTION
|
||||
(pPager->vfsFlags&SQLITE_OPEN_FILEPROTECTION_MASK)|
|
||||
#endif
|
||||
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
|
||||
SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE;
|
||||
rc = sqlite3OsOpen(pPager->pVfs, 0, pFile, vfsFlags, 0);
|
||||
assert( rc!=SQLITE_OK || isOpen(pFile) );
|
||||
@@ -4818,6 +4830,9 @@ act_like_temp_file:
|
||||
pPager->readOnly = (u8)readOnly;
|
||||
assert( useJournal || pPager->tempFile );
|
||||
pPager->noSync = pPager->tempFile;
|
||||
pPager->fullSync = pPager->noSync ?0:1;
|
||||
pPager->syncFlags = pPager->noSync ? 0 : SQLITE_SYNC_NORMAL;
|
||||
pPager->ckptSyncFlags = pPager->syncFlags;
|
||||
if( pPager->noSync ){
|
||||
assert( pPager->fullSync==0 );
|
||||
assert( pPager->extraSync==0 );
|
||||
@@ -4969,7 +4984,11 @@ static int hasHotJournal(Pager *pPager, int *pExists){
|
||||
** it can be ignored.
|
||||
*/
|
||||
if( !jrnlOpen ){
|
||||
int f = SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL;
|
||||
int f =
|
||||
#if SQLITE_ENABLE_DATA_PROTECTION
|
||||
(pPager->vfsFlags&SQLITE_OPEN_FILEPROTECTION_MASK)|
|
||||
#endif
|
||||
SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL;
|
||||
rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &f);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
@@ -5109,7 +5128,11 @@ int sqlite3PagerSharedLock(Pager *pPager){
|
||||
pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &bExists);
|
||||
if( rc==SQLITE_OK && bExists ){
|
||||
int fout = 0;
|
||||
int f = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL;
|
||||
int f =
|
||||
#if SQLITE_ENABLE_DATA_PROTECTION
|
||||
(pPager->vfsFlags&SQLITE_OPEN_FILEPROTECTION_MASK)|
|
||||
#endif
|
||||
SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL;
|
||||
assert( !pPager->tempFile );
|
||||
rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout);
|
||||
assert( rc!=SQLITE_OK || isOpen(pPager->jfd) );
|
||||
@@ -5574,6 +5597,9 @@ static int pager_open_journal(Pager *pPager){
|
||||
int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
|
||||
int nSpill;
|
||||
|
||||
#if SQLITE_ENABLE_DATA_PROTECTION
|
||||
flags |= (pPager->vfsFlags&SQLITE_OPEN_FILEPROTECTION_MASK);
|
||||
#endif
|
||||
if( pPager->tempFile ){
|
||||
flags |= (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL);
|
||||
nSpill = sqlite3Config.nStmtSpill;
|
||||
@@ -6732,6 +6758,18 @@ sqlite3_file *sqlite3PagerFile(Pager *pPager){
|
||||
return pPager->fd;
|
||||
}
|
||||
|
||||
#if !defined(SQLITE_OMIT_WAL)
|
||||
/*
|
||||
** Return the file handle for the WAL journal file associated
|
||||
** with the pager. This might return NULL if the file has
|
||||
** not yet been opened.
|
||||
*/
|
||||
sqlite3_file *sqlite3PagerWalFile(Pager *pPager){
|
||||
return ((pPager->pWal) ? sqlite3WalFile(pPager->pWal) : (NULL));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** Return the file handle for the journal file (if it exists).
|
||||
** This will be either the rollback journal or the WAL file.
|
||||
@@ -7235,10 +7273,14 @@ static int pagerOpenWal(Pager *pPager){
|
||||
** (e.g. due to malloc() failure), return an error code.
|
||||
*/
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3WalOpen(pPager->pVfs,
|
||||
pPager->fd, pPager->zWal, pPager->exclusiveMode,
|
||||
pPager->journalSizeLimit, &pPager->pWal
|
||||
);
|
||||
#if SQLITE_ENABLE_DATA_PROTECTION
|
||||
rc = sqlite3WalOpen(pPager->pVfs, pPager->fd, pPager->zWal, pPager->exclusiveMode,
|
||||
pPager->journalSizeLimit, (pPager->vfsFlags & (SQLITE_OPEN_FILEPROTECTION_MASK | SQLITE_OPEN_READONLY)),
|
||||
&pPager->pWal);
|
||||
#else
|
||||
rc = sqlite3WalOpen(pPager->pVfs, pPager->fd, pPager->zWal, pPager->exclusiveMode,
|
||||
pPager->journalSizeLimit, (pPager->vfsFlags & SQLITE_OPEN_READONLY), &pPager->pWal);
|
||||
#endif
|
||||
}
|
||||
pagerFixMaplimit(pPager);
|
||||
|
||||
@@ -7332,6 +7374,13 @@ int sqlite3PagerCloseWal(Pager *pPager){
|
||||
pPager->pageSize, (u8*)pPager->pTmpSpace);
|
||||
pPager->pWal = 0;
|
||||
pagerFixMaplimit(pPager);
|
||||
|
||||
/* Ensure that the WAL file is deleted even if the PERSIST_WAL
|
||||
** hint is enabled. */
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3OsDelete(pPager->pVfs, pPager->zWal, 0);
|
||||
if( rc==SQLITE_IOERR_DELETE_NOENT ) rc = SQLITE_OK;
|
||||
}
|
||||
if( rc && !pPager->exclusiveMode ) pagerUnlockDb(pPager, SHARED_LOCK);
|
||||
}
|
||||
}
|
||||
|
||||
+4
-3
@@ -14,8 +14,8 @@
|
||||
** at a time and provides a journal for rollback.
|
||||
*/
|
||||
|
||||
#ifndef _PAGER_H_
|
||||
#define _PAGER_H_
|
||||
#ifndef SQLITE_PAGER_H
|
||||
#define SQLITE_PAGER_H
|
||||
|
||||
/*
|
||||
** Default maximum size for persistent journal files. A negative
|
||||
@@ -198,6 +198,7 @@ int sqlite3PagerMemUsed(Pager*);
|
||||
const char *sqlite3PagerFilename(Pager*, int);
|
||||
sqlite3_vfs *sqlite3PagerVfs(Pager*);
|
||||
sqlite3_file *sqlite3PagerFile(Pager*);
|
||||
sqlite3_file *sqlite3PagerWalFile(Pager *pPager);
|
||||
sqlite3_file *sqlite3PagerJrnlFile(Pager*);
|
||||
const char *sqlite3PagerJournalname(Pager*);
|
||||
void *sqlite3PagerTempSpace(Pager*);
|
||||
@@ -229,4 +230,4 @@ void *sqlite3PagerCodec(DbPage *);
|
||||
# define enable_simulated_io_errors()
|
||||
#endif
|
||||
|
||||
#endif /* _PAGER_H_ */
|
||||
#endif /* SQLITE_PAGER_H */
|
||||
|
||||
+11
-1
@@ -1134,9 +1134,10 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
||||
exprNot(pParse, N, &A);
|
||||
A.zEnd = &E.z[E.n];
|
||||
}
|
||||
expr(A) ::= expr(A) in_op(N) nm(Y) dbnm(Z). [IN] {
|
||||
expr(A) ::= expr(A) in_op(N) nm(Y) dbnm(Z) paren_exprlist(E). [IN] {
|
||||
SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&Y,&Z);
|
||||
Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
|
||||
if( E ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, E);
|
||||
A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0, 0);
|
||||
sqlite3PExprAddSelect(pParse, A.pExpr, pSelect);
|
||||
exprNot(pParse, N, &A);
|
||||
@@ -1193,6 +1194,15 @@ nexprlist(A) ::= nexprlist(A) COMMA expr(Y).
|
||||
nexprlist(A) ::= expr(Y).
|
||||
{A = sqlite3ExprListAppend(pParse,0,Y.pExpr); /*A-overwrites-Y*/}
|
||||
|
||||
%ifndef SQLITE_OMIT_SUBQUERY
|
||||
/* A paren_exprlist is an optional expression list contained inside
|
||||
** of parenthesis */
|
||||
%type paren_exprlist {ExprList*}
|
||||
%destructor paren_exprlist {sqlite3ExprListDelete(pParse->db, $$);}
|
||||
paren_exprlist(A) ::= . {A = 0;}
|
||||
paren_exprlist(A) ::= LP exprlist(X) RP. {A = X;}
|
||||
%endif SQLITE_OMIT_SUBQUERY
|
||||
|
||||
|
||||
///////////////////////////// The CREATE INDEX command ///////////////////////
|
||||
//
|
||||
|
||||
+1
-2
@@ -365,8 +365,7 @@ static void pcache1Free(void *p){
|
||||
sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
|
||||
#ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS
|
||||
{
|
||||
int nFreed = 0;
|
||||
nFreed = sqlite3MallocSize(p);
|
||||
int nFreed = sqlite3MallocSize(p);
|
||||
sqlite3_mutex_enter(pcache1.mutex);
|
||||
sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_OVERFLOW, nFreed);
|
||||
sqlite3_mutex_leave(pcache1.mutex);
|
||||
|
||||
+3
-3
@@ -219,11 +219,11 @@ static void setAllPagerFlags(sqlite3 *db){
|
||||
assert( SQLITE_CacheSpill==PAGER_CACHESPILL );
|
||||
assert( (PAGER_FULLFSYNC | PAGER_CKPT_FULLFSYNC | PAGER_CACHESPILL)
|
||||
== PAGER_FLAGS_MASK );
|
||||
assert( (pDb->safety_level & PAGER_SYNCHRONOUS_MASK)==pDb->safety_level );
|
||||
while( (n--) > 0 ){
|
||||
if( pDb->pBt ){
|
||||
sqlite3BtreeSetPagerFlags(pDb->pBt,
|
||||
pDb->safety_level | (db->flags & PAGER_FLAGS_MASK) );
|
||||
(pDb->safety_level & PAGER_SYNCHRONOUS_MASK)
|
||||
| (db->flags & PAGER_FLAGS_MASK) );
|
||||
}
|
||||
pDb++;
|
||||
}
|
||||
@@ -1052,7 +1052,7 @@ void sqlite3Pragma(
|
||||
*/
|
||||
case PragTyp_TABLE_INFO: if( zRight ){
|
||||
Table *pTab;
|
||||
pTab = sqlite3FindTable(db, zRight, zDb);
|
||||
pTab = sqlite3LocateTable(pParse, LOCATE_NOERR, zRight, zDb);
|
||||
if( pTab ){
|
||||
static const char *azCol[] = {
|
||||
"cid", "name", "type", "notnull", "dflt_value", "pk"
|
||||
|
||||
+12
-1
@@ -14,6 +14,9 @@
|
||||
** from disk.
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
# include "sqlrr.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Fill the InitData structure with an error message that indicates
|
||||
@@ -749,6 +752,9 @@ int sqlite3_prepare(
|
||||
){
|
||||
int rc;
|
||||
rc = sqlite3LockAndPrepare(db,zSql,nBytes,0,0,ppStmt,pzTail);
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecPrepare(db, zSql, nBytes, 0, *ppStmt);
|
||||
#endif
|
||||
assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */
|
||||
return rc;
|
||||
}
|
||||
@@ -761,6 +767,9 @@ int sqlite3_prepare_v2(
|
||||
){
|
||||
int rc;
|
||||
rc = sqlite3LockAndPrepare(db,zSql,nBytes,1,0,ppStmt,pzTail);
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecPrepare(db, zSql, nBytes, 1, *ppStmt);
|
||||
#endif
|
||||
assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */
|
||||
return rc;
|
||||
}
|
||||
@@ -804,7 +813,9 @@ static int sqlite3Prepare16(
|
||||
if( zSql8 ){
|
||||
rc = sqlite3LockAndPrepare(db, zSql8, -1, saveSqlFlag, 0, ppStmt, &zTail8);
|
||||
}
|
||||
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecPrepare(db, zSql8, -1, 1, *ppStmt);
|
||||
#endif
|
||||
if( zTail8 && pzTail ){
|
||||
/* If sqlite3_prepare returns a tail pointer, we calculate the
|
||||
** equivalent pointer into the UTF-16 string by counting the unicode
|
||||
|
||||
+5
-1
@@ -718,7 +718,11 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
|
||||
pNC->nErr++;
|
||||
is_agg = 0;
|
||||
}else if( no_such_func && pParse->db->init.busy==0 ){
|
||||
}else if( no_such_func && pParse->db->init.busy==0
|
||||
#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
|
||||
&& pParse->explain==0
|
||||
#endif
|
||||
){
|
||||
sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId);
|
||||
pNC->nErr++;
|
||||
}else if( wrong_num_args ){
|
||||
|
||||
+14
-5
@@ -2543,13 +2543,20 @@ static FILE *output_file_open(const char *zFile){
|
||||
/*
|
||||
** A routine for handling output from sqlite3_trace().
|
||||
*/
|
||||
static void sql_trace_callback(void *pArg, const char *z){
|
||||
static int sql_trace_callback(
|
||||
unsigned mType,
|
||||
void *pArg,
|
||||
void *pP,
|
||||
void *pX
|
||||
){
|
||||
FILE *f = (FILE*)pArg;
|
||||
if( f ){
|
||||
const char *z = (const char*)pX;
|
||||
int i = (int)strlen(z);
|
||||
while( i>0 && z[i-1]==';' ){ i--; }
|
||||
utf8_printf(f, "%.*s;\n", i, z);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2946,10 +2953,10 @@ static int db_int(ShellState *p, const char *zSql){
|
||||
/*
|
||||
** Convert a 2-byte or 4-byte big-endian integer into a native integer
|
||||
*/
|
||||
unsigned int get2byteInt(unsigned char *a){
|
||||
static unsigned int get2byteInt(unsigned char *a){
|
||||
return (a[0]<<8) + a[1];
|
||||
}
|
||||
unsigned int get4byteInt(unsigned char *a){
|
||||
static unsigned int get4byteInt(unsigned char *a){
|
||||
return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
|
||||
}
|
||||
|
||||
@@ -4655,9 +4662,9 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
p->traceOut = output_file_open(azArg[1]);
|
||||
#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
|
||||
if( p->traceOut==0 ){
|
||||
sqlite3_trace(p->db, 0, 0);
|
||||
sqlite3_trace_v2(p->db, 0, 0, 0);
|
||||
}else{
|
||||
sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
|
||||
sqlite3_trace_v2(p->db, SQLITE_TRACE_STMT, sql_trace_callback,p->traceOut);
|
||||
}
|
||||
#endif
|
||||
}else
|
||||
@@ -5317,6 +5324,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
|
||||
szHeap = integerValue(zSize);
|
||||
if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
|
||||
sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
|
||||
#else
|
||||
(void)cmdline_option_value(argc, argv, ++i);
|
||||
#endif
|
||||
}else if( strcmp(z,"-scratch")==0 ){
|
||||
int n, sz;
|
||||
|
||||
+144
-9
@@ -30,8 +30,8 @@
|
||||
** the version number) and changes its name to "sqlite3.h" as
|
||||
** part of the build process.
|
||||
*/
|
||||
#ifndef _SQLITE3_H_
|
||||
#define _SQLITE3_H_
|
||||
#ifndef SQLITE3_H
|
||||
#define SQLITE3_H
|
||||
#include <stdarg.h> /* Needed for the definition of va_list */
|
||||
|
||||
/*
|
||||
@@ -535,6 +535,7 @@ int sqlite3_exec(
|
||||
#define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */
|
||||
#define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */
|
||||
#define SQLITE_OPEN_WAL 0x00080000 /* VFS only */
|
||||
#define SQLITE_OPEN_FILEPROTECTION_MASK 0x00700000
|
||||
|
||||
/* Reserved: 0x00F00000 */
|
||||
|
||||
@@ -2755,6 +2756,9 @@ int sqlite3_set_authorizer(
|
||||
** CAPI3REF: Tracing And Profiling Functions
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** These routines are deprecated. Use the [sqlite3_trace_v2()] interface
|
||||
** instead of the routines described here.
|
||||
**
|
||||
** These routines register callback functions that can be used for
|
||||
** tracing and profiling the execution of SQL statements.
|
||||
**
|
||||
@@ -2780,10 +2784,104 @@ int sqlite3_set_authorizer(
|
||||
** sqlite3_profile() function is considered experimental and is
|
||||
** subject to change in future versions of SQLite.
|
||||
*/
|
||||
void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*);
|
||||
SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*,
|
||||
SQLITE_DEPRECATED void *sqlite3_trace(sqlite3*,
|
||||
void(*xTrace)(void*,const char*), void*);
|
||||
SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*,
|
||||
void(*xProfile)(void*,const char*,sqlite3_uint64), void*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: SQL Trace Event Codes
|
||||
** KEYWORDS: SQLITE_TRACE
|
||||
**
|
||||
** These constants identify classes of events that can be monitored
|
||||
** using the [sqlite3_trace_v2()] tracing logic. The third argument
|
||||
** to [sqlite3_trace_v2()] is an OR-ed combination of one or more of
|
||||
** the following constants. ^The first argument to the trace callback
|
||||
** is one of the following constants.
|
||||
**
|
||||
** New tracing constants may be added in future releases.
|
||||
**
|
||||
** ^A trace callback has four arguments: xCallback(T,C,P,X).
|
||||
** ^The T argument is one of the integer type codes above.
|
||||
** ^The C argument is a copy of the context pointer passed in as the
|
||||
** fourth argument to [sqlite3_trace_v2()].
|
||||
** The P and X arguments are pointers whose meanings depend on T.
|
||||
**
|
||||
** <dl>
|
||||
** [[SQLITE_TRACE_STMT]] <dt>SQLITE_TRACE_STMT</dt>
|
||||
** <dd>^An SQLITE_TRACE_STMT callback is invoked when a prepared statement
|
||||
** first begins running and possibly at other times during the
|
||||
** execution of the prepared statement, such as at the start of each
|
||||
** trigger subprogram. ^The P argument is a pointer to the
|
||||
** [prepared statement]. ^The X argument is a pointer to a string which
|
||||
** is the unexpanded SQL text of the prepared statement or an SQL comment
|
||||
** that indicates the invocation of a trigger. ^The callback can compute
|
||||
** the same text that would have been returned by the legacy [sqlite3_trace()]
|
||||
** interface by using the X argument when X begins with "--" and invoking
|
||||
** [sqlite3_expanded_sql(P)] otherwise.
|
||||
**
|
||||
** [[SQLITE_TRACE_PROFILE]] <dt>SQLITE_TRACE_PROFILE</dt>
|
||||
** <dd>^An SQLITE_TRACE_PROFILE callback provides approximately the same
|
||||
** information as is provided by the [sqlite3_profile()] callback.
|
||||
** ^The P argument is a pointer to the [prepared statement] and the
|
||||
** X argument points to a 64-bit integer which is the estimated of
|
||||
** the number of nanosecond that the prepared statement took to run.
|
||||
** ^The SQLITE_TRACE_PROFILE callback is invoked when the statement finishes.
|
||||
**
|
||||
** [[SQLITE_TRACE_ROW]] <dt>SQLITE_TRACE_ROW</dt>
|
||||
** <dd>^An SQLITE_TRACE_ROW callback is invoked whenever a prepared
|
||||
** statement generates a single row of result.
|
||||
** ^The P argument is a pointer to the [prepared statement] and the
|
||||
** X argument is unused.
|
||||
**
|
||||
** [[SQLITE_TRACE_CLOSE]] <dt>SQLITE_TRACE_CLOSE</dt>
|
||||
** <dd>^An SQLITE_TRACE_CLOSE callback is invoked when a database
|
||||
** connection closes.
|
||||
** ^The P argument is a pointer to the [database connection] object
|
||||
** and the X argument is unused.
|
||||
** </dl>
|
||||
*/
|
||||
#define SQLITE_TRACE_STMT 0x01
|
||||
#define SQLITE_TRACE_PROFILE 0x02
|
||||
#define SQLITE_TRACE_ROW 0x04
|
||||
#define SQLITE_TRACE_CLOSE 0x08
|
||||
|
||||
/*
|
||||
** CAPI3REF: SQL Trace Hook
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** ^The sqlite3_trace_v2(D,M,X,P) interface registers a trace callback
|
||||
** function X against [database connection] D, using property mask M
|
||||
** and context pointer P. ^If the X callback is
|
||||
** NULL or if the M mask is zero, then tracing is disabled. The
|
||||
** M argument should be the bitwise OR-ed combination of
|
||||
** zero or more [SQLITE_TRACE] constants.
|
||||
**
|
||||
** ^Each call to either sqlite3_trace() or sqlite3_trace_v2() overrides
|
||||
** (cancels) any prior calls to sqlite3_trace() or sqlite3_trace_v2().
|
||||
**
|
||||
** ^The X callback is invoked whenever any of the events identified by
|
||||
** mask M occur. ^The integer return value from the callback is currently
|
||||
** ignored, though this may change in future releases. Callback
|
||||
** implementations should return zero to ensure future compatibility.
|
||||
**
|
||||
** ^A trace callback is invoked with four arguments: callback(T,C,P,X).
|
||||
** ^The T argument is one of the [SQLITE_TRACE]
|
||||
** constants to indicate why the callback was invoked.
|
||||
** ^The C argument is a copy of the context pointer.
|
||||
** The P and X arguments are pointers whose meanings depend on T.
|
||||
**
|
||||
** The sqlite3_trace_v2() interface is intended to replace the legacy
|
||||
** interfaces [sqlite3_trace()] and [sqlite3_profile()], both of which
|
||||
** are deprecated.
|
||||
*/
|
||||
int sqlite3_trace_v2(
|
||||
sqlite3*,
|
||||
unsigned uMask,
|
||||
int(*xCallback)(unsigned,void*,void*,void*),
|
||||
void *pCtx
|
||||
);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Query Progress Callbacks
|
||||
** METHOD: sqlite3
|
||||
@@ -3402,11 +3500,35 @@ int sqlite3_prepare16_v2(
|
||||
** CAPI3REF: Retrieving Statement SQL
|
||||
** METHOD: sqlite3_stmt
|
||||
**
|
||||
** ^This interface can be used to retrieve a saved copy of the original
|
||||
** SQL text used to create a [prepared statement] if that statement was
|
||||
** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()].
|
||||
** ^The sqlite3_sql(P) interface returns a pointer to a copy of the UTF-8
|
||||
** SQL text used to create [prepared statement] P if P was
|
||||
** created by either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()].
|
||||
** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8
|
||||
** string containing the SQL text of prepared statement P with
|
||||
** [bound parameters] expanded.
|
||||
**
|
||||
** ^(For example, if a prepared statement is created using the SQL
|
||||
** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345
|
||||
** and parameter :xyz is unbound, then sqlite3_sql() will return
|
||||
** the original string, "SELECT $abc,:xyz" but sqlite3_expanded_sql()
|
||||
** will return "SELECT 2345,NULL".)^
|
||||
**
|
||||
** ^The sqlite3_expanded_sql() interface returns NULL if insufficient memory
|
||||
** is available to hold the result, or if the result would exceed the
|
||||
** the maximum string length determined by the [SQLITE_LIMIT_LENGTH].
|
||||
**
|
||||
** ^The [SQLITE_TRACE_SIZE_LIMIT] compile-time option limits the size of
|
||||
** bound parameter expansions. ^The [SQLITE_OMIT_TRACE] compile-time
|
||||
** option causes sqlite3_expanded_sql() to always return NULL.
|
||||
**
|
||||
** ^The string returned by sqlite3_sql(P) is managed by SQLite and is
|
||||
** automatically freed when the prepared statement is finalized.
|
||||
** ^The string returned by sqlite3_expanded_sql(P), on the other hand,
|
||||
** is obtained from [sqlite3_malloc()] and must be free by the application
|
||||
** by passing it to [sqlite3_free()].
|
||||
*/
|
||||
const char *sqlite3_sql(sqlite3_stmt *pStmt);
|
||||
char *sqlite3_expanded_sql(sqlite3_stmt *pStmt);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Determine If An SQL Statement Writes The Database
|
||||
@@ -6765,6 +6887,18 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
|
||||
** memory used by all pager caches associated with the database connection.)^
|
||||
** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0.
|
||||
**
|
||||
** [[SQLITE_DBSTATUS_CACHE_USED_SHARED]]
|
||||
** ^(<dt>SQLITE_DBSTATUS_CACHE_USED_SHARED</dt>
|
||||
** <dd>This parameter is similar to DBSTATUS_CACHE_USED, except that if a
|
||||
** pager cache is shared between two or more connections the bytes of heap
|
||||
** memory used by that pager cache is divided evenly between the attached
|
||||
** connections.)^ In other words, if none of the pager caches associated
|
||||
** with the database connection are shared, this request returns the same
|
||||
** value as DBSTATUS_CACHE_USED. Or, if one or more or the pager caches are
|
||||
** shared, the value returned by this call will be smaller than that returned
|
||||
** by DBSTATUS_CACHE_USED. ^The highwater mark associated with
|
||||
** SQLITE_DBSTATUS_CACHE_USED_SHARED is always 0.
|
||||
**
|
||||
** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(<dt>SQLITE_DBSTATUS_SCHEMA_USED</dt>
|
||||
** <dd>This parameter returns the approximate number of bytes of heap
|
||||
** memory used to store the schema for all databases associated
|
||||
@@ -6822,7 +6956,8 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
|
||||
#define SQLITE_DBSTATUS_CACHE_MISS 8
|
||||
#define SQLITE_DBSTATUS_CACHE_WRITE 9
|
||||
#define SQLITE_DBSTATUS_DEFERRED_FKS 10
|
||||
#define SQLITE_DBSTATUS_MAX 10 /* Largest defined DBSTATUS */
|
||||
#define SQLITE_DBSTATUS_CACHE_USED_SHARED 11
|
||||
#define SQLITE_DBSTATUS_MAX 11 /* Largest defined DBSTATUS */
|
||||
|
||||
|
||||
/*
|
||||
@@ -8205,4 +8340,4 @@ SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
|
||||
#ifdef __cplusplus
|
||||
} /* End of the 'extern "C"' block */
|
||||
#endif
|
||||
#endif /* _SQLITE3_H_ */
|
||||
#endif /* SQLITE3_H */
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* sqlite3_private.h
|
||||
*/
|
||||
|
||||
#ifndef _SQLITE3_PRIVATE_H
|
||||
#define _SQLITE3_PRIVATE_H
|
||||
|
||||
#define SQLITE_LOCKSTATE_OFF 0
|
||||
#define SQLITE_LOCKSTATE_ON 1
|
||||
#define SQLITE_LOCKSTATE_NOTADB 2
|
||||
#define SQLITE_LOCKSTATE_ERROR -1
|
||||
|
||||
#define SQLITE_LOCKSTATE_ANYPID -1
|
||||
|
||||
/*
|
||||
** Test a file path for sqlite locks held by a process ID (-1 = any PID).
|
||||
** Returns one of the following integer codes:
|
||||
**
|
||||
** SQLITE_LOCKSTATE_OFF no active sqlite file locks match the specified pid
|
||||
** SQLITE_LOCKSTATE_ON active sqlite file locks match the specified pid
|
||||
** SQLITE_LOCKSTATE_NOTADB path points to a file that is not an sqlite db file
|
||||
** SQLITE_LOCKSTATE_ERROR path was not vaild or was unreadable
|
||||
**
|
||||
** There is no support for identifying db files encrypted via SEE encryption
|
||||
** currently. Zero byte files are tested for sqlite locks, but if no sqlite
|
||||
** locks are present then SQLITE_LOCKSTATE_NOTADB is returned.
|
||||
*/
|
||||
extern int _sqlite3_lockstate(const char *path, pid_t pid);
|
||||
|
||||
/*
|
||||
** Test an open database connection for sqlite locks held by a process ID,
|
||||
** if a process has an open database connection this will avoid trashing file
|
||||
** locks by re-using open file descriptors for the database file and support
|
||||
** files (-shm)
|
||||
*/
|
||||
#define SQLITE_FCNTL_LOCKSTATE_PID 103
|
||||
|
||||
/*
|
||||
** Pass the SQLITE_TRUNCATE_DATABASE operation code to sqlite3_file_control()
|
||||
** to truncate a database and its associated journal file to zero length. The
|
||||
** SQLITE_TRUNCATE_* flags represent optional flags to safely initialize an
|
||||
** empty database in the place of the truncated database, the flags are passed
|
||||
** into sqlite3_file_control via the fourth argument using a pointer to an integer
|
||||
** configured with the ORed flags. If the fourth argument is NULL, the default
|
||||
** behavior is applied and the database file is truncated to zero bytes, a rollback
|
||||
** journal (if present) is unlinked, a WAL journal (if present) is truncated to zero
|
||||
** bytes and the first few bytes of the -shm file is scrambled to trigger existing
|
||||
** connections to rebuild the index from the database file contents.
|
||||
*/
|
||||
#define SQLITE_FCNTL_TRUNCATE_DATABASE 101
|
||||
#define SQLITE_TRUNCATE_DATABASE SQLITE_FCNTL_TRUNCATE_DATABASE
|
||||
#define SQLITE_TRUNCATE_INITIALIZE_HEADER_MASK (0x7F<<0)
|
||||
#define SQLITE_TRUNCATE_JOURNALMODE_WAL (0x1<<0)
|
||||
#define SQLITE_TRUNCATE_AUTOVACUUM_MASK (0x3<<2)
|
||||
#define SQLITE_TRUNCATE_AUTOVACUUM_OFF (0x1<<2)
|
||||
#define SQLITE_TRUNCATE_AUTOVACUUM_FULL (0x2<<2)
|
||||
#define SQLITE_TRUNCATE_AUTOVACUUM_INCREMENTAL (0x3<<2)
|
||||
#define SQLITE_TRUNCATE_PAGESIZE_MASK (0x7<<4)
|
||||
#define SQLITE_TRUNCATE_PAGESIZE_1024 (0x1<<4)
|
||||
#define SQLITE_TRUNCATE_PAGESIZE_2048 (0x2<<4)
|
||||
#define SQLITE_TRUNCATE_PAGESIZE_4096 (0x3<<4)
|
||||
#define SQLITE_TRUNCATE_PAGESIZE_8192 (0x4<<4)
|
||||
#define SQLITE_TRUNCATE_FORCE (0x1<<7)
|
||||
|
||||
/*
|
||||
** Pass the SQLITE_REPLACE_DATABASE operation code to sqlite3_file_control()
|
||||
** and a sqlite3 pointer to another open database file to safely copy the
|
||||
** contents of that database file into the receiving database.
|
||||
*/
|
||||
#define SQLITE_FCNTL_REPLACE_DATABASE 102
|
||||
#define SQLITE_REPLACE_DATABASE SQLITE_FCNTL_REPLACE_DATABASE
|
||||
|
||||
#endif
|
||||
+9
-3
@@ -15,8 +15,8 @@
|
||||
** as extensions by SQLite should #include this file instead of
|
||||
** sqlite3.h.
|
||||
*/
|
||||
#ifndef _SQLITE3EXT_H_
|
||||
#define _SQLITE3EXT_H_
|
||||
#ifndef SQLITE3EXT_H
|
||||
#define SQLITE3EXT_H
|
||||
#include "sqlite3.h"
|
||||
|
||||
typedef struct sqlite3_api_routines sqlite3_api_routines;
|
||||
@@ -281,6 +281,9 @@ struct sqlite3_api_routines {
|
||||
int (*db_cacheflush)(sqlite3*);
|
||||
/* Version 3.12.0 and later */
|
||||
int (*system_errno)(sqlite3*);
|
||||
/* Version 3.14.0 and later */
|
||||
int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*);
|
||||
char *(*expanded_sql)(sqlite3_stmt*);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -526,6 +529,9 @@ struct sqlite3_api_routines {
|
||||
#define sqlite3_db_cacheflush sqlite3_api->db_cacheflush
|
||||
/* Version 3.12.0 and later */
|
||||
#define sqlite3_system_errno sqlite3_api->system_errno
|
||||
/* Version 3.14.0 and later */
|
||||
#define sqlite3_trace_v2 sqlite3_api->trace_v2
|
||||
#define sqlite3_expanded_sql sqlite3_api->expanded_sql
|
||||
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
|
||||
|
||||
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||
@@ -543,4 +549,4 @@ struct sqlite3_api_routines {
|
||||
# define SQLITE_EXTENSION_INIT3 /*no-op*/
|
||||
#endif
|
||||
|
||||
#endif /* _SQLITE3EXT_H_ */
|
||||
#endif /* SQLITE3EXT_H */
|
||||
|
||||
+52
-10
@@ -12,8 +12,8 @@
|
||||
** Internal interface definitions for SQLite.
|
||||
**
|
||||
*/
|
||||
#ifndef _SQLITEINT_H_
|
||||
#define _SQLITEINT_H_
|
||||
#ifndef SQLITEINT_H
|
||||
#define SQLITEINT_H
|
||||
|
||||
/* Special Comments:
|
||||
**
|
||||
@@ -1241,6 +1241,15 @@ void sqlite3CryptFunc(sqlite3_context*,int,sqlite3_value**);
|
||||
const char*);
|
||||
#endif
|
||||
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
/* This is an extra SQLITE_TRACE macro that indicates "legacy" tracing
|
||||
** in the style of sqlite3_trace()
|
||||
*/
|
||||
#define SQLITE_TRACE_LEGACY 0x80
|
||||
#else
|
||||
#define SQLITE_TRACE_LEGACY 0
|
||||
#endif /* SQLITE_OMIT_DEPRECATED */
|
||||
|
||||
|
||||
/*
|
||||
** Each database connection is an instance of the following structure.
|
||||
@@ -1270,6 +1279,7 @@ struct sqlite3 {
|
||||
u8 suppressErr; /* Do not issue error messages if true */
|
||||
u8 vtabOnConflict; /* Value to return for s3_vtab_on_conflict() */
|
||||
u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */
|
||||
u8 mTrace; /* zero or more SQLITE_TRACE flags */
|
||||
int nextPagesize; /* Pagesize after VACUUM if >0 */
|
||||
u32 magic; /* Magic number for detect library misuse */
|
||||
int nChange; /* Value returned by sqlite3_changes() */
|
||||
@@ -1290,7 +1300,7 @@ struct sqlite3 {
|
||||
int nVDestroy; /* Number of active OP_VDestroy operations */
|
||||
int nExtension; /* Number of loaded extensions */
|
||||
void **aExtension; /* Array of shared library handles */
|
||||
void (*xTrace)(void*,const char*); /* Trace function */
|
||||
int (*xTrace)(u32,void*,void*,void*); /* Trace function */
|
||||
void *pTraceArg; /* Argument to the trace function */
|
||||
void (*xProfile)(void*,const char*,u64); /* Profiling function */
|
||||
void *pProfileArg; /* Argument to profile function */
|
||||
@@ -2485,7 +2495,7 @@ struct SrcList {
|
||||
int regReturn; /* Register holding return address of addrFillSub */
|
||||
int regResult; /* Registers holding results of a co-routine */
|
||||
struct {
|
||||
u8 jointype; /* Type of join between this able and the previous */
|
||||
u8 jointype; /* Type of join between this table and the previous */
|
||||
unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */
|
||||
unsigned isIndexedBy :1; /* True if there is an INDEXED BY clause */
|
||||
unsigned isTabFunc :1; /* True if table-valued-function syntax */
|
||||
@@ -3247,6 +3257,7 @@ struct Walker {
|
||||
struct SrcCount *pSrcCount; /* Counting column references */
|
||||
struct CCurHint *pCCurHint; /* Used by codeCursorHint() */
|
||||
int *aiCol; /* array of column indexes */
|
||||
struct IdxCover *pIdxCover; /* Check for index coverage */
|
||||
} u;
|
||||
};
|
||||
|
||||
@@ -3430,11 +3441,15 @@ int sqlite3HeapNearlyFull(void);
|
||||
# define sqlite3StackFree(D,P) sqlite3DbFree(D,P)
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_ENABLE_MEMSYS3
|
||||
const sqlite3_mem_methods *sqlite3MemGetMemsys3(void);
|
||||
#endif
|
||||
/* Do not allow both MEMSYS5 and MEMSYS3 to be defined together. If they
|
||||
** are, disable MEMSYS3
|
||||
*/
|
||||
#ifdef SQLITE_ENABLE_MEMSYS5
|
||||
const sqlite3_mem_methods *sqlite3MemGetMemsys5(void);
|
||||
#undef SQLITE_ENABLE_MEMSYS3
|
||||
#endif
|
||||
#ifdef SQLITE_ENABLE_MEMSYS3
|
||||
const sqlite3_mem_methods *sqlite3MemGetMemsys3(void);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -3671,8 +3686,10 @@ void sqlite3ExprIfTrue(Parse*, Expr*, int, int);
|
||||
void sqlite3ExprIfFalse(Parse*, Expr*, int, int);
|
||||
void sqlite3ExprIfFalseDup(Parse*, Expr*, int, int);
|
||||
Table *sqlite3FindTable(sqlite3*,const char*, const char*);
|
||||
Table *sqlite3LocateTable(Parse*,int isView,const char*, const char*);
|
||||
Table *sqlite3LocateTableItem(Parse*,int isView,struct SrcList_item *);
|
||||
#define LOCATE_VIEW 0x01
|
||||
#define LOCATE_NOERR 0x02
|
||||
Table *sqlite3LocateTable(Parse*,u32 flags,const char*, const char*);
|
||||
Table *sqlite3LocateTableItem(Parse*,u32 flags,struct SrcList_item *);
|
||||
Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
|
||||
void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
|
||||
void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
|
||||
@@ -3684,6 +3701,7 @@ int sqlite3ExprListCompare(ExprList*, ExprList*, int);
|
||||
int sqlite3ExprImpliesExpr(Expr*, Expr*, int);
|
||||
void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
|
||||
void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
|
||||
int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx);
|
||||
int sqlite3FunctionUsesThisSrc(Expr*, SrcList*);
|
||||
Vdbe *sqlite3GetVdbe(Parse*);
|
||||
#ifndef SQLITE_OMIT_BUILTIN_TEST
|
||||
@@ -4223,6 +4241,30 @@ SQLITE_API SQLITE_EXTERN void (SQLITE_CDECL *sqlite3IoTrace)(const char*,...);
|
||||
#define MEMTYPE_SCRATCH 0x04 /* Scratch allocations */
|
||||
#define MEMTYPE_PCACHE 0x08 /* Page cache allocations */
|
||||
|
||||
#if (SQLITE_ENABLE_APPLE_SPI>0) && defined(__APPLE__)
|
||||
|
||||
/*
|
||||
** An instance of the following structure is used to hold the process ID
|
||||
** and return-by-reference lockstate value. The SQLITE_FCNTL_LOCKSTATE_PID
|
||||
** requires the 4th argument to sqlite3_file_control to be a pointer to an
|
||||
** instance of LockstatePID initialized with a LockstatePID.pid value equal
|
||||
** to a process ID to be tested, or the special value SQLITE_LOCKSTATE_ANYPID
|
||||
** The Lockstate.state value is always set to one of the following values
|
||||
** when sqlite3_file_control returns:
|
||||
**
|
||||
** SQLITE_LOCKSTATE_OFF no active sqlite file locks match the specified pid
|
||||
** SQLITE_LOCKSTATE_ON active sqlite file locks match the specified pid
|
||||
** SQLITE_LOCKSTATE_NOTADB path points to a file that is not an sqlite db file
|
||||
** SQLITE_LOCKSTATE_ERROR path was not vaild or was unreadable
|
||||
*/
|
||||
typedef struct LockstatePID LockstatePID;
|
||||
struct LockstatePID {
|
||||
pid_t pid; /* Process ID to test */
|
||||
int state; /* The state of the lock (return value) */
|
||||
};
|
||||
|
||||
#endif /* (SQLITE_ENABLE_APPLE_SPI>0) && defined(__APPLE__) */
|
||||
|
||||
/*
|
||||
** Threading interface
|
||||
*/
|
||||
@@ -4235,4 +4277,4 @@ int sqlite3ThreadJoin(SQLiteThread*, void**);
|
||||
int sqlite3DbstatRegister(sqlite3*);
|
||||
#endif
|
||||
|
||||
#endif /* _SQLITEINT_H_ */
|
||||
#endif /* SQLITEINT_H */
|
||||
|
||||
+6
-1
@@ -219,6 +219,7 @@ int sqlite3_db_status(
|
||||
** by all pagers associated with the given database connection. The
|
||||
** highwater mark is meaningless and is returned as zero.
|
||||
*/
|
||||
case SQLITE_DBSTATUS_CACHE_USED_SHARED:
|
||||
case SQLITE_DBSTATUS_CACHE_USED: {
|
||||
int totalUsed = 0;
|
||||
int i;
|
||||
@@ -227,7 +228,11 @@ int sqlite3_db_status(
|
||||
Btree *pBt = db->aDb[i].pBt;
|
||||
if( pBt ){
|
||||
Pager *pPager = sqlite3BtreePager(pBt);
|
||||
totalUsed += sqlite3PagerMemUsed(pPager);
|
||||
int nByte = sqlite3PagerMemUsed(pPager);
|
||||
if( op==SQLITE_DBSTATUS_CACHE_USED_SHARED ){
|
||||
nByte = nByte / sqlite3BtreeConnectionCount(pBt);
|
||||
}
|
||||
totalUsed += nByte;
|
||||
}
|
||||
}
|
||||
sqlite3BtreeLeaveAll(db);
|
||||
|
||||
+257
-90
@@ -133,6 +133,7 @@ struct SqliteDb {
|
||||
char *zBusy; /* The busy callback routine */
|
||||
char *zCommit; /* The commit hook callback routine */
|
||||
char *zTrace; /* The trace callback routine */
|
||||
char *zTraceV2; /* The trace_v2 callback routine */
|
||||
char *zProfile; /* The profile callback routine */
|
||||
char *zProgress; /* The progress callback routine */
|
||||
char *zAuth; /* The authorization callback routine */
|
||||
@@ -192,7 +193,7 @@ static void closeIncrblobChannels(SqliteDb *pDb){
|
||||
for(p=pDb->pIncrblob; p; p=pNext){
|
||||
pNext = p->pNext;
|
||||
|
||||
/* Note: Calling unregister here call Tcl_Close on the incrblob channel,
|
||||
/* Note: Calling unregister here call Tcl_Close on the incrblob channel,
|
||||
** which deletes the IncrblobChannel structure at *p. So do not
|
||||
** call Tcl_Free() here.
|
||||
*/
|
||||
@@ -233,8 +234,8 @@ static int incrblobClose(ClientData instanceData, Tcl_Interp *interp){
|
||||
** Read data from an incremental blob channel.
|
||||
*/
|
||||
static int incrblobInput(
|
||||
ClientData instanceData,
|
||||
char *buf,
|
||||
ClientData instanceData,
|
||||
char *buf,
|
||||
int bufSize,
|
||||
int *errorCodePtr
|
||||
){
|
||||
@@ -265,8 +266,8 @@ static int incrblobInput(
|
||||
** Write data to an incremental blob channel.
|
||||
*/
|
||||
static int incrblobOutput(
|
||||
ClientData instanceData,
|
||||
CONST char *buf,
|
||||
ClientData instanceData,
|
||||
CONST char *buf,
|
||||
int toWrite,
|
||||
int *errorCodePtr
|
||||
){
|
||||
@@ -298,7 +299,7 @@ static int incrblobOutput(
|
||||
** Seek an incremental blob channel.
|
||||
*/
|
||||
static int incrblobSeek(
|
||||
ClientData instanceData,
|
||||
ClientData instanceData,
|
||||
long offset,
|
||||
int seekMode,
|
||||
int *errorCodePtr
|
||||
@@ -323,8 +324,8 @@ static int incrblobSeek(
|
||||
}
|
||||
|
||||
|
||||
static void incrblobWatch(ClientData instanceData, int mode){
|
||||
/* NO-OP */
|
||||
static void incrblobWatch(ClientData instanceData, int mode){
|
||||
/* NO-OP */
|
||||
}
|
||||
static int incrblobHandle(ClientData instanceData, int dir, ClientData *hPtr){
|
||||
return TCL_ERROR;
|
||||
@@ -352,11 +353,11 @@ static Tcl_ChannelType IncrblobChannelType = {
|
||||
** Create a new incrblob channel.
|
||||
*/
|
||||
static int createIncrblobChannel(
|
||||
Tcl_Interp *interp,
|
||||
SqliteDb *pDb,
|
||||
Tcl_Interp *interp,
|
||||
SqliteDb *pDb,
|
||||
const char *zDb,
|
||||
const char *zTable,
|
||||
const char *zColumn,
|
||||
const char *zTable,
|
||||
const char *zColumn,
|
||||
sqlite_int64 iRow,
|
||||
int isReadonly
|
||||
){
|
||||
@@ -438,7 +439,7 @@ static SqlFunc *findSqlFunc(SqliteDb *pDb, const char *zName){
|
||||
pNew = (SqlFunc*)Tcl_Alloc( sizeof(*pNew) + nName + 1 );
|
||||
pNew->zName = (char*)&pNew[1];
|
||||
memcpy(pNew->zName, zName, nName+1);
|
||||
for(p=pDb->pFunc; p; p=p->pNext){
|
||||
for(p=pDb->pFunc; p; p=p->pNext){
|
||||
if( sqlite3_stricmp(p->zName, pNew->zName)==0 ){
|
||||
Tcl_Free((char*)pNew);
|
||||
return p;
|
||||
@@ -508,6 +509,9 @@ static void DbDeleteCmd(void *db){
|
||||
if( pDb->zTrace ){
|
||||
Tcl_Free(pDb->zTrace);
|
||||
}
|
||||
if( pDb->zTraceV2 ){
|
||||
Tcl_Free(pDb->zTraceV2);
|
||||
}
|
||||
if( pDb->zProfile ){
|
||||
Tcl_Free(pDb->zProfile);
|
||||
}
|
||||
@@ -587,6 +591,82 @@ static void DbTraceHandler(void *cd, const char *zSql){
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SQLITE_OMIT_TRACE
|
||||
/*
|
||||
** This routine is called by the SQLite trace_v2 handler whenever a new
|
||||
** supported event is generated. Unsupported event types are ignored.
|
||||
** The TCL script in pDb->zTraceV2 is executed, with the arguments for
|
||||
** the event appended to it (as list elements).
|
||||
*/
|
||||
static int DbTraceV2Handler(
|
||||
unsigned type, /* One of the SQLITE_TRACE_* event types. */
|
||||
void *cd, /* The original context data pointer. */
|
||||
void *pd, /* Primary event data, depends on event type. */
|
||||
void *xd /* Extra event data, depends on event type. */
|
||||
){
|
||||
SqliteDb *pDb = (SqliteDb*)cd;
|
||||
Tcl_Obj *pCmd;
|
||||
|
||||
switch( type ){
|
||||
case SQLITE_TRACE_STMT: {
|
||||
sqlite3_stmt *pStmt = (sqlite3_stmt *)pd;
|
||||
char *zSql = (char *)xd;
|
||||
|
||||
pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
|
||||
Tcl_IncrRefCount(pCmd);
|
||||
Tcl_ListObjAppendElement(pDb->interp, pCmd,
|
||||
Tcl_NewWideIntObj((Tcl_WideInt)pStmt));
|
||||
Tcl_ListObjAppendElement(pDb->interp, pCmd,
|
||||
Tcl_NewStringObj(zSql, -1));
|
||||
Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
|
||||
Tcl_DecrRefCount(pCmd);
|
||||
Tcl_ResetResult(pDb->interp);
|
||||
break;
|
||||
}
|
||||
case SQLITE_TRACE_PROFILE: {
|
||||
sqlite3_stmt *pStmt = (sqlite3_stmt *)pd;
|
||||
sqlite3_int64 ns = (sqlite3_int64)xd;
|
||||
|
||||
pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
|
||||
Tcl_IncrRefCount(pCmd);
|
||||
Tcl_ListObjAppendElement(pDb->interp, pCmd,
|
||||
Tcl_NewWideIntObj((Tcl_WideInt)pStmt));
|
||||
Tcl_ListObjAppendElement(pDb->interp, pCmd,
|
||||
Tcl_NewWideIntObj((Tcl_WideInt)ns));
|
||||
Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
|
||||
Tcl_DecrRefCount(pCmd);
|
||||
Tcl_ResetResult(pDb->interp);
|
||||
break;
|
||||
}
|
||||
case SQLITE_TRACE_ROW: {
|
||||
sqlite3_stmt *pStmt = (sqlite3_stmt *)pd;
|
||||
|
||||
pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
|
||||
Tcl_IncrRefCount(pCmd);
|
||||
Tcl_ListObjAppendElement(pDb->interp, pCmd,
|
||||
Tcl_NewWideIntObj((Tcl_WideInt)pStmt));
|
||||
Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
|
||||
Tcl_DecrRefCount(pCmd);
|
||||
Tcl_ResetResult(pDb->interp);
|
||||
break;
|
||||
}
|
||||
case SQLITE_TRACE_CLOSE: {
|
||||
sqlite3 *db = (sqlite3 *)pd;
|
||||
|
||||
pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
|
||||
Tcl_IncrRefCount(pCmd);
|
||||
Tcl_ListObjAppendElement(pDb->interp, pCmd,
|
||||
Tcl_NewWideIntObj((Tcl_WideInt)db));
|
||||
Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
|
||||
Tcl_DecrRefCount(pCmd);
|
||||
Tcl_ResetResult(pDb->interp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SQLITE_OMIT_TRACE
|
||||
/*
|
||||
** This routine is called by the SQLite profile handler after a statement
|
||||
@@ -637,9 +717,9 @@ static void DbRollbackHandler(void *clientData){
|
||||
** This procedure handles wal_hook callbacks.
|
||||
*/
|
||||
static int DbWalHandler(
|
||||
void *clientData,
|
||||
sqlite3 *db,
|
||||
const char *zDb,
|
||||
void *clientData,
|
||||
sqlite3 *db,
|
||||
const char *zDb,
|
||||
int nEntry
|
||||
){
|
||||
int ret = SQLITE_OK;
|
||||
@@ -653,7 +733,7 @@ static int DbWalHandler(
|
||||
Tcl_IncrRefCount(p);
|
||||
Tcl_ListObjAppendElement(interp, p, Tcl_NewStringObj(zDb, -1));
|
||||
Tcl_ListObjAppendElement(interp, p, Tcl_NewIntObj(nEntry));
|
||||
if( TCL_OK!=Tcl_EvalObjEx(interp, p, 0)
|
||||
if( TCL_OK!=Tcl_EvalObjEx(interp, p, 0)
|
||||
|| TCL_OK!=Tcl_GetIntFromObj(interp, Tcl_GetObjResult(interp), &ret)
|
||||
){
|
||||
Tcl_BackgroundError(interp);
|
||||
@@ -695,11 +775,11 @@ static void DbUnlockNotify(void **apArg, int nArg){
|
||||
** Pre-update hook callback.
|
||||
*/
|
||||
static void DbPreUpdateHandler(
|
||||
void *p,
|
||||
void *p,
|
||||
sqlite3 *db,
|
||||
int op,
|
||||
const char *zDb,
|
||||
const char *zTbl,
|
||||
const char *zDb,
|
||||
const char *zTbl,
|
||||
sqlite_int64 iKey1,
|
||||
sqlite_int64 iKey2
|
||||
){
|
||||
@@ -727,10 +807,10 @@ static void DbPreUpdateHandler(
|
||||
#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
|
||||
|
||||
static void DbUpdateHandler(
|
||||
void *p,
|
||||
void *p,
|
||||
int op,
|
||||
const char *zDb,
|
||||
const char *zTbl,
|
||||
const char *zDb,
|
||||
const char *zTbl,
|
||||
sqlite_int64 rowid
|
||||
){
|
||||
SqliteDb *pDb = (SqliteDb *)p;
|
||||
@@ -815,7 +895,7 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){
|
||||
** script object, lappend the arguments, then evaluate the copy.
|
||||
**
|
||||
** By "shallow" copy, we mean only the outer list Tcl_Obj is duplicated.
|
||||
** The new Tcl_Obj contains pointers to the original list elements.
|
||||
** The new Tcl_Obj contains pointers to the original list elements.
|
||||
** That way, when Tcl_EvalObjv() is run and shimmers the first element
|
||||
** of the list to tclCmdNameType, that alternate representation will
|
||||
** be preserved and reused on the next invocation.
|
||||
@@ -823,15 +903,15 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){
|
||||
Tcl_Obj **aArg;
|
||||
int nArg;
|
||||
if( Tcl_ListObjGetElements(p->interp, p->pScript, &nArg, &aArg) ){
|
||||
sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1);
|
||||
sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
pCmd = Tcl_NewListObj(nArg, aArg);
|
||||
Tcl_IncrRefCount(pCmd);
|
||||
for(i=0; i<argc; i++){
|
||||
sqlite3_value *pIn = argv[i];
|
||||
Tcl_Obj *pVal;
|
||||
|
||||
|
||||
/* Set pVal to contain the i'th column of this row. */
|
||||
switch( sqlite3_value_type(pIn) ){
|
||||
case SQLITE_BLOB: {
|
||||
@@ -866,7 +946,7 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){
|
||||
rc = Tcl_ListObjAppendElement(p->interp, pCmd, pVal);
|
||||
if( rc ){
|
||||
Tcl_DecrRefCount(pCmd);
|
||||
sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1);
|
||||
sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -881,7 +961,7 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){
|
||||
}
|
||||
|
||||
if( rc && rc!=TCL_RETURN ){
|
||||
sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1);
|
||||
sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1);
|
||||
}else{
|
||||
Tcl_Obj *pVar = Tcl_GetObjResult(p->interp);
|
||||
int n;
|
||||
@@ -983,7 +1063,7 @@ static int auth_callback(
|
||||
Tcl_DStringAppendElement(&str, zArg4 ? zArg4 : "");
|
||||
#ifdef SQLITE_USER_AUTHENTICATION
|
||||
Tcl_DStringAppendElement(&str, zArg5 ? zArg5 : "");
|
||||
#endif
|
||||
#endif
|
||||
rc = Tcl_GlobalEval(pDb->interp, Tcl_DStringValue(&str));
|
||||
Tcl_DStringFree(&str);
|
||||
zReply = rc==TCL_OK ? Tcl_GetStringResult(pDb->interp) : "SQLITE_DENY";
|
||||
@@ -1075,12 +1155,12 @@ static int DbTransPostCmd(
|
||||
pDb->disableAuth++;
|
||||
if( sqlite3_exec(pDb->db, zEnd, 0, 0, 0) ){
|
||||
/* This is a tricky scenario to handle. The most likely cause of an
|
||||
** error is that the exec() above was an attempt to commit the
|
||||
** error is that the exec() above was an attempt to commit the
|
||||
** top-level transaction that returned SQLITE_BUSY. Or, less likely,
|
||||
** that an IO-error has occurred. In either case, throw a Tcl exception
|
||||
** and try to rollback the transaction.
|
||||
**
|
||||
** But it could also be that the user executed one or more BEGIN,
|
||||
** But it could also be that the user executed one or more BEGIN,
|
||||
** COMMIT, SAVEPOINT, RELEASE or ROLLBACK commands that are confusing
|
||||
** this method's logic. Not clear how this would be best handled.
|
||||
*/
|
||||
@@ -1099,7 +1179,7 @@ static int DbTransPostCmd(
|
||||
** Unless SQLITE_TEST is defined, this function is a simple wrapper around
|
||||
** sqlite3_prepare_v2(). If SQLITE_TEST is defined, then it uses either
|
||||
** sqlite3_prepare_v2() or legacy interface sqlite3_prepare(), depending
|
||||
** on whether or not the [db_use_legacy_prepare] command has been used to
|
||||
** on whether or not the [db_use_legacy_prepare] command has been used to
|
||||
** configure the connection.
|
||||
*/
|
||||
static int dbPrepare(
|
||||
@@ -1155,7 +1235,7 @@ static int dbPrepareAndBind(
|
||||
|
||||
for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pPreStmt->pNext){
|
||||
int n = pPreStmt->nSql;
|
||||
if( nSql>=n
|
||||
if( nSql>=n
|
||||
&& memcmp(pPreStmt->zSql, zSql, n)==0
|
||||
&& (zSql[n]==0 || zSql[n-1]==';')
|
||||
){
|
||||
@@ -1181,7 +1261,7 @@ static int dbPrepareAndBind(
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* If no prepared statement was found. Compile the SQL text. Also allocate
|
||||
** a new SqlPreparedStmt structure. */
|
||||
if( pPreStmt==0 ){
|
||||
@@ -1227,7 +1307,7 @@ static int dbPrepareAndBind(
|
||||
assert( strlen30(pPreStmt->zSql)==pPreStmt->nSql );
|
||||
assert( 0==memcmp(pPreStmt->zSql, zSql, pPreStmt->nSql) );
|
||||
|
||||
/* Bind values to parameters that begin with $ or : */
|
||||
/* Bind values to parameters that begin with $ or : */
|
||||
for(i=1; i<=nVar; i++){
|
||||
const char *zVar = sqlite3_bind_parameter_name(pStmt, i);
|
||||
if( zVar!=0 && (zVar[0]=='$' || zVar[0]==':' || zVar[0]=='@') ){
|
||||
@@ -1315,8 +1395,8 @@ static void dbReleaseStmt(
|
||||
assert( pDb->nStmt>0 );
|
||||
}
|
||||
pDb->nStmt++;
|
||||
|
||||
/* If we have too many statement in cache, remove the surplus from
|
||||
|
||||
/* If we have too many statement in cache, remove the surplus from
|
||||
** the end of the cache list. */
|
||||
while( pDb->nStmt>pDb->maxStmt ){
|
||||
SqlPreparedStmt *pLast = pDb->stmtLast;
|
||||
@@ -1370,8 +1450,8 @@ static void dbReleaseColumnNames(DbEvalContext *p){
|
||||
** If pArray is not NULL, then it contains the name of a Tcl array
|
||||
** variable. The "*" member of this array is set to a list containing
|
||||
** the names of the columns returned by the statement as part of each
|
||||
** call to dbEvalStep(), in order from left to right. e.g. if the names
|
||||
** of the returned columns are a, b and c, it does the equivalent of the
|
||||
** call to dbEvalStep(), in order from left to right. e.g. if the names
|
||||
** of the returned columns are a, b and c, it does the equivalent of the
|
||||
** tcl command:
|
||||
**
|
||||
** set ${pArray}(*) {a b c}
|
||||
@@ -1492,7 +1572,7 @@ static int dbEvalStep(DbEvalContext *p){
|
||||
#if SQLITE_TEST
|
||||
if( p->pDb->bLegacyPrepare && rcs==SQLITE_SCHEMA && zPrevSql ){
|
||||
/* If the runtime error was an SQLITE_SCHEMA, and the database
|
||||
** handle is configured to use the legacy sqlite3_prepare()
|
||||
** handle is configured to use the legacy sqlite3_prepare()
|
||||
** interface, retry prepare()/step() on the same SQL statement.
|
||||
** This only happens once. If there is a second SQLITE_SCHEMA
|
||||
** error, the error will be returned to the caller. */
|
||||
@@ -1580,11 +1660,11 @@ static int DbUseNre(void){
|
||||
return( (major==8 && minor>=6) || major>8 );
|
||||
}
|
||||
#else
|
||||
/*
|
||||
/*
|
||||
** Compiling using headers earlier than 8.6. In this case NR cannot be
|
||||
** used, so DbUseNre() to always return zero. Add #defines for the other
|
||||
** Tcl_NRxxx() functions to prevent them from causing compilation errors,
|
||||
** even though the only invocations of them are within conditional blocks
|
||||
** even though the only invocations of them are within conditional blocks
|
||||
** of the form:
|
||||
**
|
||||
** if( DbUseNre() ) { ... }
|
||||
@@ -1630,11 +1710,11 @@ static int DbEvalNextCmd(
|
||||
}
|
||||
}
|
||||
|
||||
/* The required interpreter variables are now populated with the data
|
||||
/* The required interpreter variables are now populated with the data
|
||||
** from the current row. If using NRE, schedule callbacks to evaluate
|
||||
** script pScript, then to invoke this function again to fetch the next
|
||||
** row (or clean up if there is no next row or the script throws an
|
||||
** exception). After scheduling the callbacks, return control to the
|
||||
** exception). After scheduling the callbacks, return control to the
|
||||
** caller.
|
||||
**
|
||||
** If not using NRE, evaluate pScript directly and continue with the
|
||||
@@ -1659,7 +1739,7 @@ static int DbEvalNextCmd(
|
||||
}
|
||||
|
||||
/*
|
||||
** This function is used by the implementations of the following database
|
||||
** This function is used by the implementations of the following database
|
||||
** handle sub-commands:
|
||||
**
|
||||
** $db update_hook ?SCRIPT?
|
||||
@@ -1726,9 +1806,10 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
"preupdate", "profile", "progress",
|
||||
"rekey", "restore", "rollback_hook",
|
||||
"status", "timeout", "total_changes",
|
||||
"trace", "transaction", "unlock_notify",
|
||||
"update_hook", "version", "wal_hook",
|
||||
0
|
||||
"trace", "trace_v2", "transaction",
|
||||
"unlock_notify", "update_hook", "version",
|
||||
"wal_hook",
|
||||
0
|
||||
};
|
||||
enum DB_enum {
|
||||
DB_AUTHORIZER, DB_BACKUP, DB_BUSY,
|
||||
@@ -1741,8 +1822,9 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
DB_PREUPDATE, DB_PROFILE, DB_PROGRESS,
|
||||
DB_REKEY, DB_RESTORE, DB_ROLLBACK_HOOK,
|
||||
DB_STATUS, DB_TIMEOUT, DB_TOTAL_CHANGES,
|
||||
DB_TRACE, DB_TRANSACTION, DB_UNLOCK_NOTIFY,
|
||||
DB_UPDATE_HOOK, DB_VERSION, DB_WAL_HOOK,
|
||||
DB_TRACE, DB_TRACE_V2, DB_TRANSACTION,
|
||||
DB_UNLOCK_NOTIFY, DB_UPDATE_HOOK, DB_VERSION,
|
||||
DB_WAL_HOOK,
|
||||
};
|
||||
/* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */
|
||||
|
||||
@@ -1928,7 +2010,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
return TCL_ERROR;
|
||||
}else{
|
||||
if( TCL_ERROR==Tcl_GetIntFromObj(interp, objv[3], &n) ){
|
||||
Tcl_AppendResult( interp, "cannot convert \"",
|
||||
Tcl_AppendResult( interp, "cannot convert \"",
|
||||
Tcl_GetStringFromObj(objv[3],0), "\" to integer", (char*)0);
|
||||
return TCL_ERROR;
|
||||
}else{
|
||||
@@ -1942,7 +2024,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
}
|
||||
}
|
||||
}else{
|
||||
Tcl_AppendResult( interp, "bad option \"",
|
||||
Tcl_AppendResult( interp, "bad option \"",
|
||||
Tcl_GetStringFromObj(objv[2],0), "\": must be flush or size",
|
||||
(char*)0);
|
||||
return TCL_ERROR;
|
||||
@@ -1953,7 +2035,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
/* $db changes
|
||||
**
|
||||
** Return the number of rows that were modified, inserted, or deleted by
|
||||
** the most recent INSERT, UPDATE or DELETE statement, not including
|
||||
** the most recent INSERT, UPDATE or DELETE statement, not including
|
||||
** any changes made by trigger programs.
|
||||
*/
|
||||
case DB_CHANGES: {
|
||||
@@ -2000,7 +2082,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
pCollate->zScript = (char*)&pCollate[1];
|
||||
pDb->pCollate = pCollate;
|
||||
memcpy(pCollate->zScript, zScript, nScript+1);
|
||||
if( sqlite3_create_collation(pDb->db, zName, SQLITE_UTF8,
|
||||
if( sqlite3_create_collation(pDb->db, zName, SQLITE_UTF8,
|
||||
pCollate, tclSqlCollate) ){
|
||||
Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE);
|
||||
return TCL_ERROR;
|
||||
@@ -2126,7 +2208,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
const char *zSep;
|
||||
const char *zNull;
|
||||
if( objc<5 || objc>7 ){
|
||||
Tcl_WrongNumArgs(interp, 2, objv,
|
||||
Tcl_WrongNumArgs(interp, 2, objv,
|
||||
"CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -2155,7 +2237,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
strcmp(zConflict, "fail" ) != 0 &&
|
||||
strcmp(zConflict, "ignore" ) != 0 &&
|
||||
strcmp(zConflict, "replace" ) != 0 ) {
|
||||
Tcl_AppendResult(interp, "Error: \"", zConflict,
|
||||
Tcl_AppendResult(interp, "Error: \"", zConflict,
|
||||
"\", conflict-algorithm must be one of: rollback, "
|
||||
"abort, fail, ignore, or replace", (char*)0);
|
||||
return TCL_ERROR;
|
||||
@@ -2244,7 +2326,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
for(i=0; i<nCol; i++){
|
||||
/* check for null data, if so, bind as null */
|
||||
if( (nNull>0 && strcmp(azCol[i], zNull)==0)
|
||||
|| strlen30(azCol[i])==0
|
||||
|| strlen30(azCol[i])==0
|
||||
){
|
||||
sqlite3_bind_null(pStmt, i+1);
|
||||
}else{
|
||||
@@ -2323,8 +2405,9 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
** The onecolumn method is the equivalent of:
|
||||
** lindex [$db eval $sql] 0
|
||||
*/
|
||||
case DB_EXISTS:
|
||||
case DB_EXISTS:
|
||||
case DB_ONECOLUMN: {
|
||||
Tcl_Obj *pResult = 0;
|
||||
DbEvalContext sEval;
|
||||
if( objc!=3 ){
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "SQL");
|
||||
@@ -2335,21 +2418,22 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
rc = dbEvalStep(&sEval);
|
||||
if( choice==DB_ONECOLUMN ){
|
||||
if( rc==TCL_OK ){
|
||||
Tcl_SetObjResult(interp, dbEvalColumnValue(&sEval, 0));
|
||||
pResult = dbEvalColumnValue(&sEval, 0);
|
||||
}else if( rc==TCL_BREAK ){
|
||||
Tcl_ResetResult(interp);
|
||||
}
|
||||
}else if( rc==TCL_BREAK || rc==TCL_OK ){
|
||||
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(rc==TCL_OK));
|
||||
pResult = Tcl_NewBooleanObj(rc==TCL_OK);
|
||||
}
|
||||
dbEvalFinalize(&sEval);
|
||||
if( pResult ) Tcl_SetObjResult(interp, pResult);
|
||||
|
||||
if( rc==TCL_BREAK ){
|
||||
rc = TCL_OK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** $db eval $sql ?array? ?{ ...code... }?
|
||||
**
|
||||
@@ -2395,7 +2479,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
}
|
||||
pScript = objv[objc-1];
|
||||
Tcl_IncrRefCount(pScript);
|
||||
|
||||
|
||||
p = (DbEvalContext *)Tcl_Alloc(sizeof(DbEvalContext));
|
||||
dbEvalInit(p, pDb, objv[2], pArray);
|
||||
|
||||
@@ -2442,7 +2526,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
if( n>2 && strncmp(z, "-deterministic",n)==0 ){
|
||||
flags |= SQLITE_DETERMINISTIC;
|
||||
}else{
|
||||
Tcl_AppendResult(interp, "bad option \"", z,
|
||||
Tcl_AppendResult(interp, "bad option \"", z,
|
||||
"\": must be -argcount or -deterministic", 0
|
||||
);
|
||||
return TCL_ERROR;
|
||||
@@ -2551,7 +2635,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
}
|
||||
|
||||
/*
|
||||
** $db last_insert_rowid
|
||||
** $db last_insert_rowid
|
||||
**
|
||||
** Return an integer which is the ROWID for the most recent insert.
|
||||
*/
|
||||
@@ -2573,7 +2657,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
*/
|
||||
|
||||
/* $db progress ?N CALLBACK?
|
||||
**
|
||||
**
|
||||
** Invoke the given callback every N virtual machine opcodes while executing
|
||||
** queries.
|
||||
*/
|
||||
@@ -2680,7 +2764,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
|
||||
/* $db restore ?DATABASE? FILENAME
|
||||
**
|
||||
** Open a database file named FILENAME. Transfer the content
|
||||
** Open a database file named FILENAME. Transfer the content
|
||||
** of FILENAME into the local database DATABASE (default: "main").
|
||||
*/
|
||||
case DB_RESTORE: {
|
||||
@@ -2741,7 +2825,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
/*
|
||||
** $db status (step|sort|autoindex)
|
||||
**
|
||||
** Display SQLITE_STMTSTATUS_FULLSCAN_STEP or
|
||||
** Display SQLITE_STMTSTATUS_FULLSCAN_STEP or
|
||||
** SQLITE_STMTSTATUS_SORT for the most recent eval.
|
||||
*/
|
||||
case DB_STATUS: {
|
||||
@@ -2759,15 +2843,15 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
}else if( strcmp(zOp, "autoindex")==0 ){
|
||||
v = pDb->nIndex;
|
||||
}else{
|
||||
Tcl_AppendResult(interp,
|
||||
"bad argument: should be autoindex, step, or sort",
|
||||
Tcl_AppendResult(interp,
|
||||
"bad argument: should be autoindex, step, or sort",
|
||||
(char*)0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(v));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** $db timeout MILLESECONDS
|
||||
**
|
||||
@@ -2783,11 +2867,11 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
sqlite3_busy_timeout(pDb->db, ms);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** $db total_changes
|
||||
**
|
||||
** Return the number of rows that were modified, inserted, or deleted
|
||||
** Return the number of rows that were modified, inserted, or deleted
|
||||
** since the database handle was created.
|
||||
*/
|
||||
case DB_TOTAL_CHANGES: {
|
||||
@@ -2828,7 +2912,8 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
}else{
|
||||
pDb->zTrace = 0;
|
||||
}
|
||||
#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
|
||||
#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) \
|
||||
&& !defined(SQLITE_OMIT_DEPRECATED)
|
||||
if( pDb->zTrace ){
|
||||
pDb->interp = interp;
|
||||
sqlite3_trace(pDb->db, DbTraceHandler, pDb);
|
||||
@@ -2840,6 +2925,88 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
break;
|
||||
}
|
||||
|
||||
/* $db trace_v2 ?CALLBACK? ?MASK?
|
||||
**
|
||||
** Make arrangements to invoke the CALLBACK routine for each trace event
|
||||
** matching the mask that is generated. The parameters are appended to
|
||||
** CALLBACK before it is executed.
|
||||
*/
|
||||
case DB_TRACE_V2: {
|
||||
if( objc>4 ){
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK? ?MASK?");
|
||||
return TCL_ERROR;
|
||||
}else if( objc==2 ){
|
||||
if( pDb->zTraceV2 ){
|
||||
Tcl_AppendResult(interp, pDb->zTraceV2, (char*)0);
|
||||
}
|
||||
}else{
|
||||
char *zTraceV2;
|
||||
int len;
|
||||
Tcl_WideInt wMask = 0;
|
||||
if( objc==4 ){
|
||||
static const char *TTYPE_strs[] = {
|
||||
"statement", "profile", "row", "close", 0
|
||||
};
|
||||
enum TTYPE_enum {
|
||||
TTYPE_STMT, TTYPE_PROFILE, TTYPE_ROW, TTYPE_CLOSE
|
||||
};
|
||||
int i;
|
||||
if( TCL_OK!=Tcl_ListObjLength(interp, objv[3], &len) ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
for(i=0; i<len; i++){
|
||||
Tcl_Obj *pObj;
|
||||
int ttype;
|
||||
if( TCL_OK!=Tcl_ListObjIndex(interp, objv[3], i, &pObj) ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( Tcl_GetIndexFromObj(interp, pObj, TTYPE_strs, "trace type",
|
||||
0, &ttype)!=TCL_OK ){
|
||||
Tcl_WideInt wType;
|
||||
Tcl_Obj *pError = Tcl_DuplicateObj(Tcl_GetObjResult(interp));
|
||||
Tcl_IncrRefCount(pError);
|
||||
if( TCL_OK==Tcl_GetWideIntFromObj(interp, pObj, &wType) ){
|
||||
Tcl_DecrRefCount(pError);
|
||||
wMask |= wType;
|
||||
}else{
|
||||
Tcl_SetObjResult(interp, pError);
|
||||
Tcl_DecrRefCount(pError);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}else{
|
||||
switch( (enum TTYPE_enum)ttype ){
|
||||
case TTYPE_STMT: wMask |= SQLITE_TRACE_STMT; break;
|
||||
case TTYPE_PROFILE: wMask |= SQLITE_TRACE_PROFILE; break;
|
||||
case TTYPE_ROW: wMask |= SQLITE_TRACE_ROW; break;
|
||||
case TTYPE_CLOSE: wMask |= SQLITE_TRACE_CLOSE; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
wMask = SQLITE_TRACE_STMT; /* use the "legacy" default */
|
||||
}
|
||||
if( pDb->zTraceV2 ){
|
||||
Tcl_Free(pDb->zTraceV2);
|
||||
}
|
||||
zTraceV2 = Tcl_GetStringFromObj(objv[2], &len);
|
||||
if( zTraceV2 && len>0 ){
|
||||
pDb->zTraceV2 = Tcl_Alloc( len + 1 );
|
||||
memcpy(pDb->zTraceV2, zTraceV2, len+1);
|
||||
}else{
|
||||
pDb->zTraceV2 = 0;
|
||||
}
|
||||
#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
|
||||
if( pDb->zTraceV2 ){
|
||||
pDb->interp = interp;
|
||||
sqlite3_trace_v2(pDb->db, (unsigned)wMask, DbTraceV2Handler, pDb);
|
||||
}else{
|
||||
sqlite3_trace_v2(pDb->db, 0, 0, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* $db transaction [-deferred|-immediate|-exclusive] SCRIPT
|
||||
**
|
||||
** Start a new transaction (if we are not already in the midst of a
|
||||
@@ -2892,7 +3059,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
/* If using NRE, schedule a callback to invoke the script pScript, then
|
||||
** a second callback to commit (or rollback) the transaction or savepoint
|
||||
** opened above. If not using NRE, evaluate the script directly, then
|
||||
** call function DbTransPostCmd() to commit (or rollback) the transaction
|
||||
** call function DbTransPostCmd() to commit (or rollback) the transaction
|
||||
** or savepoint. */
|
||||
if( DbUseNre() ){
|
||||
Tcl_NRAddCallback(interp, DbTransPostCmd, cd, 0, 0, 0);
|
||||
@@ -2923,14 +3090,14 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
Tcl_DecrRefCount(pDb->pUnlockNotify);
|
||||
pDb->pUnlockNotify = 0;
|
||||
}
|
||||
|
||||
|
||||
if( objc==3 ){
|
||||
xNotify = DbUnlockNotify;
|
||||
pNotifyArg = (void *)pDb;
|
||||
pDb->pUnlockNotify = objv[2];
|
||||
Tcl_IncrRefCount(pDb->pUnlockNotify);
|
||||
}
|
||||
|
||||
|
||||
if( sqlite3_unlock_notify(pDb->db, xNotify, pNotifyArg) ){
|
||||
Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0);
|
||||
rc = TCL_ERROR;
|
||||
@@ -3029,13 +3196,13 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
** $db update_hook ?script?
|
||||
** $db rollback_hook ?script?
|
||||
*/
|
||||
case DB_WAL_HOOK:
|
||||
case DB_UPDATE_HOOK:
|
||||
case DB_WAL_HOOK:
|
||||
case DB_UPDATE_HOOK:
|
||||
case DB_ROLLBACK_HOOK: {
|
||||
/* set ppHook to point at pUpdateHook or pRollbackHook, depending on
|
||||
/* set ppHook to point at pUpdateHook or pRollbackHook, depending on
|
||||
** whether [$db update_hook] or [$db rollback_hook] was invoked.
|
||||
*/
|
||||
Tcl_Obj **ppHook = 0;
|
||||
Tcl_Obj **ppHook = 0;
|
||||
if( choice==DB_WAL_HOOK ) ppHook = &pDb->pWalHook;
|
||||
if( choice==DB_UPDATE_HOOK ) ppHook = &pDb->pUpdateHook;
|
||||
if( choice==DB_ROLLBACK_HOOK ) ppHook = &pDb->pRollbackHook;
|
||||
@@ -3196,7 +3363,7 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
}
|
||||
}
|
||||
if( objc<3 || (objc&1)!=1 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv,
|
||||
Tcl_WrongNumArgs(interp, 1, objv,
|
||||
"HANDLE FILENAME ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?"
|
||||
" ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?"
|
||||
#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
|
||||
@@ -3488,7 +3655,7 @@ static void MD5Init(MD5Context *ctx){
|
||||
* Update context to reflect the concatenation of another buffer full
|
||||
* of bytes.
|
||||
*/
|
||||
static
|
||||
static
|
||||
void MD5Update(MD5Context *ctx, const unsigned char *buf, unsigned int len){
|
||||
uint32 t;
|
||||
|
||||
@@ -3534,7 +3701,7 @@ void MD5Update(MD5Context *ctx, const unsigned char *buf, unsigned int len){
|
||||
}
|
||||
|
||||
/*
|
||||
* Final wrapup - pad to 64-byte boundary with the bit pattern
|
||||
* 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){
|
||||
@@ -3610,7 +3777,7 @@ static void MD5DigestToBase10x8(unsigned char digest[16], char zDigest[50]){
|
||||
|
||||
/*
|
||||
** A TCL command for md5. The argument is the text to be hashed. The
|
||||
** Result is the hash in base64.
|
||||
** Result is the hash in base64.
|
||||
*/
|
||||
static int md5_cmd(void*cd, Tcl_Interp *interp, int argc, const char **argv){
|
||||
MD5Context ctx;
|
||||
@@ -3619,7 +3786,7 @@ static int md5_cmd(void*cd, Tcl_Interp *interp, int argc, const char **argv){
|
||||
void (*converter)(unsigned char*, char*);
|
||||
|
||||
if( argc!=2 ){
|
||||
Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
|
||||
Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
|
||||
" TEXT\"", (char*)0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -3644,13 +3811,13 @@ static int md5file_cmd(void*cd, Tcl_Interp*interp, int argc, const char **argv){
|
||||
char zBuf[10240];
|
||||
|
||||
if( argc!=2 ){
|
||||
Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
|
||||
Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
|
||||
" FILENAME\"", (char*)0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
in = fopen(argv[1],"rb");
|
||||
if( in==0 ){
|
||||
Tcl_AppendResult(interp,"unable to open file \"", argv[1],
|
||||
Tcl_AppendResult(interp,"unable to open file \"", argv[1],
|
||||
"\" for reading", (char*)0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -3717,7 +3884,7 @@ static void md5finalize(sqlite3_context *context){
|
||||
sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
|
||||
}
|
||||
int Md5_Register(sqlite3 *db){
|
||||
int rc = sqlite3_create_function(db, "md5sum", -1, SQLITE_UTF8, 0, 0,
|
||||
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;
|
||||
@@ -3868,7 +4035,7 @@ static int db_last_stmt_ptr(
|
||||
** Configure the interpreter passed as the first argument to have access
|
||||
** to the commands and linked variables that make up:
|
||||
**
|
||||
** * the [sqlite3] extension itself,
|
||||
** * the [sqlite3] extension itself,
|
||||
**
|
||||
** * If SQLITE_TCLMD5 or SQLITE_TEST is defined, the Md5 commands, and
|
||||
**
|
||||
|
||||
+376
-3
@@ -3241,6 +3241,145 @@ static int test_bind_int(
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Usage: intarray_addr INT ...
|
||||
**
|
||||
** Return the address of a C-language array of 32-bit integers.
|
||||
**
|
||||
** Space to hold the array is obtained from malloc(). Call this procedure once
|
||||
** with no arguments in order to release memory. Each call to this procedure
|
||||
** overwrites the previous array.
|
||||
*/
|
||||
static int test_intarray_addr(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
int i;
|
||||
static int *p = 0;
|
||||
|
||||
sqlite3_free(p);
|
||||
p = 0;
|
||||
if( objc>1 ){
|
||||
p = sqlite3_malloc( sizeof(p[0])*(objc-1) );
|
||||
if( p==0 ) return TCL_ERROR;
|
||||
for(i=0; i<objc-1; i++){
|
||||
if( Tcl_GetIntFromObj(interp, objv[1+i], &p[i]) ){
|
||||
sqlite3_free(p);
|
||||
p = 0;
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj((sqlite3_int64)p));
|
||||
return TCL_OK;
|
||||
}
|
||||
/*
|
||||
** Usage: intarray_addr INT ...
|
||||
**
|
||||
** Return the address of a C-language array of 32-bit integers.
|
||||
**
|
||||
** Space to hold the array is obtained from malloc(). Call this procedure once
|
||||
** with no arguments in order to release memory. Each call to this procedure
|
||||
** overwrites the previous array.
|
||||
*/
|
||||
static int test_int64array_addr(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
int i;
|
||||
static sqlite3_int64 *p = 0;
|
||||
|
||||
sqlite3_free(p);
|
||||
p = 0;
|
||||
if( objc>1 ){
|
||||
p = sqlite3_malloc( sizeof(p[0])*(objc-1) );
|
||||
if( p==0 ) return TCL_ERROR;
|
||||
for(i=0; i<objc-1; i++){
|
||||
Tcl_WideInt v;
|
||||
if( Tcl_GetWideIntFromObj(interp, objv[1+i], &v) ){
|
||||
sqlite3_free(p);
|
||||
p = 0;
|
||||
return TCL_ERROR;
|
||||
}
|
||||
p[i] = v;
|
||||
}
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj((sqlite3_int64)p));
|
||||
return TCL_OK;
|
||||
}
|
||||
/*
|
||||
** Usage: doublearray_addr INT ...
|
||||
**
|
||||
** Return the address of a C-language array of doubles.
|
||||
**
|
||||
** Space to hold the array is obtained from malloc(). Call this procedure once
|
||||
** with no arguments in order to release memory. Each call to this procedure
|
||||
** overwrites the previous array.
|
||||
*/
|
||||
static int test_doublearray_addr(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
int i;
|
||||
static double *p = 0;
|
||||
|
||||
sqlite3_free(p);
|
||||
p = 0;
|
||||
if( objc>1 ){
|
||||
p = sqlite3_malloc( sizeof(p[0])*(objc-1) );
|
||||
if( p==0 ) return TCL_ERROR;
|
||||
for(i=0; i<objc-1; i++){
|
||||
if( Tcl_GetDoubleFromObj(interp, objv[1+i], &p[i]) ){
|
||||
sqlite3_free(p);
|
||||
p = 0;
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj((sqlite3_int64)p));
|
||||
return TCL_OK;
|
||||
}
|
||||
/*
|
||||
** Usage: textarray_addr TEXT ...
|
||||
**
|
||||
** Return the address of a C-language array of strings.
|
||||
**
|
||||
** Space to hold the array is obtained from malloc(). Call this procedure once
|
||||
** with no arguments in order to release memory. Each call to this procedure
|
||||
** overwrites the previous array.
|
||||
*/
|
||||
static int test_textarray_addr(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
int i;
|
||||
static int n = 0;
|
||||
static char **p = 0;
|
||||
|
||||
for(i=0; i<n; i++) sqlite3_free(p[i]);
|
||||
sqlite3_free(p);
|
||||
p = 0;
|
||||
if( objc>1 ){
|
||||
p = sqlite3_malloc( sizeof(p[0])*(objc-1) );
|
||||
if( p==0 ) return TCL_ERROR;
|
||||
for(i=0; i<objc-1; i++){
|
||||
p[i] = sqlite3_mprintf("%s", Tcl_GetString(objv[1+i]));
|
||||
}
|
||||
}
|
||||
n = objc-1;
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj((sqlite3_int64)p));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_bind_int64 STMT N VALUE
|
||||
**
|
||||
@@ -3494,7 +3633,7 @@ static int test_bind_blob(
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
sqlite3_stmt *pStmt;
|
||||
int idx;
|
||||
int len, idx;
|
||||
int bytes;
|
||||
char *value;
|
||||
int rc;
|
||||
@@ -3513,9 +3652,18 @@ static int test_bind_blob(
|
||||
|
||||
if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
|
||||
if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
|
||||
value = Tcl_GetString(objv[3]);
|
||||
|
||||
value = (char*)Tcl_GetByteArrayFromObj(objv[3], &len);
|
||||
if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR;
|
||||
|
||||
if( bytes>len ){
|
||||
char zBuf[200];
|
||||
sqlite3_snprintf(sizeof(zBuf), zBuf,
|
||||
"cannot use %d blob bytes, have %d", bytes, len);
|
||||
Tcl_AppendResult(interp, zBuf, -1);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
rc = sqlite3_bind_blob(pStmt, idx, value, bytes, xDestructor);
|
||||
if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
|
||||
if( rc!=SQLITE_OK ){
|
||||
@@ -3623,6 +3771,24 @@ static int test_clear_bindings(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_clear_bindings STMT
|
||||
**
|
||||
*/
|
||||
static int test_clear_bindings_null(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
if( objc!=1 ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
/* test for handling NULL <rdar://problem/6646331> */
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_clear_bindings(0)));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_sleep MILLISECONDS
|
||||
*/
|
||||
@@ -4247,6 +4413,26 @@ static int test_sql(
|
||||
Tcl_SetResult(interp, (char *)sqlite3_sql(pStmt), TCL_VOLATILE);
|
||||
return TCL_OK;
|
||||
}
|
||||
static int test_ex_sql(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
sqlite3_stmt *pStmt;
|
||||
char *z;
|
||||
|
||||
if( objc!=2 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "STMT");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
|
||||
z = sqlite3_expanded_sql(pStmt);
|
||||
Tcl_SetResult(interp, z, TCL_VOLATILE);
|
||||
sqlite3_free(z);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_column_count STMT
|
||||
@@ -5303,6 +5489,96 @@ static int file_control_lasterrno_test(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
/* From sqlite3_private.h */
|
||||
# ifndef SQLITE_TRUNCATE_DATABASE
|
||||
# define SQLITE_TRUNCATE_DATABASE 101
|
||||
# define SQLITE_TRUNCATE_JOURNALMODE_WAL (0x1<<0)
|
||||
# define SQLITE_TRUNCATE_AUTOVACUUM_MASK (0x3<<2)
|
||||
# define SQLITE_TRUNCATE_AUTOVACUUM_OFF (0x1<<2)
|
||||
# define SQLITE_TRUNCATE_AUTOVACUUM_FULL (0x2<<2)
|
||||
# define SQLITE_TRUNCATE_AUTOVACUUM_INCREMENTAL (0x3<<2)
|
||||
# define SQLITE_TRUNCATE_PAGESIZE_MASK (0x7<<4)
|
||||
# define SQLITE_TRUNCATE_PAGESIZE_1024 (0x1<<4)
|
||||
# define SQLITE_TRUNCATE_PAGESIZE_2048 (0x2<<4)
|
||||
# define SQLITE_TRUNCATE_PAGESIZE_4096 (0x3<<4)
|
||||
# define SQLITE_TRUNCATE_PAGESIZE_8192 (0x4<<4)
|
||||
# endif
|
||||
# ifndef SQLITE_REPLACE_DATABASE
|
||||
# define SQLITE_REPLACE_DATABASE 102
|
||||
# endif
|
||||
|
||||
/*
|
||||
** tclcmd: file_control_truncate_test DB
|
||||
**
|
||||
** This TCL command runs the sqlite3_file_control interface and
|
||||
** verifies correct operation of the SQLITE_TRUNCATE_DATABASE verb.
|
||||
*/
|
||||
static int file_control_truncate_test(
|
||||
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
|
||||
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
||||
int objc, /* Number of arguments */
|
||||
Tcl_Obj *CONST objv[] /* Command arguments */
|
||||
){
|
||||
sqlite3 *db;
|
||||
int flags;
|
||||
int rc;
|
||||
|
||||
if( objc!=3 ){
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"",
|
||||
Tcl_GetStringFromObj(objv[0], 0), " DB FLAGS", 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( Tcl_GetIntFromObj(interp, objv[2], &flags) ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
rc = sqlite3_file_control(db, NULL, SQLITE_TRUNCATE_DATABASE, &flags);
|
||||
if( rc ){
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** tclcmd: file_control_replace_test DB
|
||||
**
|
||||
** This TCL command runs the sqlite3_file_control interface and
|
||||
** verifies correct operation of the SQLITE_REPLACE_DATABASE verb.
|
||||
*/
|
||||
static int file_control_replace_test(
|
||||
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
|
||||
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
||||
int objc, /* Number of arguments */
|
||||
Tcl_Obj *CONST objv[] /* Command arguments */
|
||||
){
|
||||
sqlite3 *src_db;
|
||||
sqlite3 *dst_db;
|
||||
int rc;
|
||||
|
||||
if( objc!=3 ){
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"",
|
||||
Tcl_GetStringFromObj(objv[0], 0), " DST_DB SRC_DB", 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getDbPointer(interp, Tcl_GetString(objv[1]), &dst_db) ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getDbPointer(interp, Tcl_GetString(objv[2]), &src_db) ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
rc = sqlite3_file_control(dst_db, NULL, SQLITE_REPLACE_DATABASE, src_db);
|
||||
if( rc ){
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
/*
|
||||
** tclcmd: file_control_chunksize_test DB DBNAME SIZE
|
||||
**
|
||||
@@ -5448,6 +5724,90 @@ static int file_control_lockproxy_test(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/errno.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
** tclcmd: path_is_local PWD
|
||||
*/
|
||||
static int path_is_local(
|
||||
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
|
||||
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
||||
int objc, /* Number of arguments */
|
||||
Tcl_Obj *CONST objv[] /* Command arguments */
|
||||
){
|
||||
#ifdef __APPLE__
|
||||
const char *zPath;
|
||||
int nPath;
|
||||
struct statfs fsInfo;
|
||||
|
||||
if( objc!=2 ){
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"",
|
||||
Tcl_GetStringFromObj(objv[0], 0), " PATH", 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
zPath = Tcl_GetStringFromObj(objv[1], &nPath);
|
||||
if( statfs(zPath, &fsInfo) == -1 ){
|
||||
int err = errno;
|
||||
Tcl_AppendResult(interp, "Error calling statfs on path",
|
||||
Tcl_NewIntObj(err), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( fsInfo.f_flags&MNT_LOCAL ){
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(1));
|
||||
} else {
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
|
||||
}
|
||||
#else
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(1));
|
||||
#endif
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** tclcmd: path_is_dos PWD
|
||||
*/
|
||||
static int path_is_dos(
|
||||
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
|
||||
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
||||
int objc, /* Number of arguments */
|
||||
Tcl_Obj *CONST objv[] /* Command arguments */
|
||||
){
|
||||
#ifdef __APPLE__
|
||||
const char *zPath;
|
||||
int nPath;
|
||||
struct statfs fsInfo;
|
||||
|
||||
if( objc!=2 ){
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"",
|
||||
Tcl_GetStringFromObj(objv[0], 0), " PATH", 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
zPath = Tcl_GetStringFromObj(objv[1], &nPath);
|
||||
if( statfs(zPath, &fsInfo) == -1 ){
|
||||
int err = errno;
|
||||
Tcl_AppendResult(interp, "Error calling statfs on path",
|
||||
Tcl_NewIntObj(err), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (0 == strncmp("msdos", fsInfo.f_fstypename, 5)) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(1));
|
||||
} else if (0 == strncmp("exfat", fsInfo.f_fstypename, 5)) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(1));
|
||||
} else {
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
|
||||
}
|
||||
#else
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
|
||||
#endif
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
#if SQLITE_OS_WIN
|
||||
/*
|
||||
** tclcmd: file_control_win32_av_retry DB NRETRY DELAY
|
||||
@@ -5549,7 +5909,6 @@ static int file_control_persist_wal(
|
||||
Tcl_AppendResult(interp, z, (char*)0);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** tclcmd: file_control_powersafe_overwrite DB PSOW-FLAG
|
||||
**
|
||||
@@ -6583,6 +6942,7 @@ static int tclLoadStaticExtensionCmd(
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
extern int sqlite3_amatch_init(sqlite3*,char**,const sqlite3_api_routines*);
|
||||
extern int sqlite3_carray_init(sqlite3*,char**,const sqlite3_api_routines*);
|
||||
extern int sqlite3_closure_init(sqlite3*,char**,const sqlite3_api_routines*);
|
||||
extern int sqlite3_csv_init(sqlite3*,char**,const sqlite3_api_routines*);
|
||||
extern int sqlite3_eval_init(sqlite3*,char**,const sqlite3_api_routines*);
|
||||
@@ -6601,6 +6961,7 @@ static int tclLoadStaticExtensionCmd(
|
||||
int (*pInit)(sqlite3*,char**,const sqlite3_api_routines*);
|
||||
} aExtension[] = {
|
||||
{ "amatch", sqlite3_amatch_init },
|
||||
{ "carray", sqlite3_carray_init },
|
||||
{ "closure", sqlite3_closure_init },
|
||||
{ "csv", sqlite3_csv_init },
|
||||
{ "eval", sqlite3_eval_init },
|
||||
@@ -7095,6 +7456,10 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
{ "bad_behavior", test_bad_behavior, (void*)&iZero },
|
||||
{ "register_dbstat_vtab", test_register_dbstat_vtab },
|
||||
{ "sqlite3_connection_pointer", get_sqlite_pointer, 0 },
|
||||
{ "intarray_addr", test_intarray_addr, 0 },
|
||||
{ "int64array_addr", test_int64array_addr, 0 },
|
||||
{ "doublearray_addr", test_doublearray_addr, 0 },
|
||||
{ "textarray_addr", test_textarray_addr, 0 },
|
||||
{ "sqlite3_bind_int", test_bind_int, 0 },
|
||||
{ "sqlite3_bind_zeroblob", test_bind_zeroblob, 0 },
|
||||
{ "sqlite3_bind_zeroblob64", test_bind_zeroblob64, 0 },
|
||||
@@ -7108,6 +7473,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
{ "sqlite3_bind_parameter_name", test_bind_parameter_name, 0},
|
||||
{ "sqlite3_bind_parameter_index", test_bind_parameter_index, 0},
|
||||
{ "sqlite3_clear_bindings", test_clear_bindings, 0},
|
||||
{ "sqlite3_clear_bindings_null", test_clear_bindings_null, 0},
|
||||
{ "sqlite3_sleep", test_sleep, 0},
|
||||
{ "sqlite3_errcode", test_errcode ,0 },
|
||||
{ "sqlite3_extended_errcode", test_ex_errcode ,0 },
|
||||
@@ -7131,6 +7497,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
{ "sqlite3_changes", test_changes ,0 },
|
||||
{ "sqlite3_step", test_step ,0 },
|
||||
{ "sqlite3_sql", test_sql ,0 },
|
||||
{ "sqlite3_expanded_sql", test_ex_sql ,0 },
|
||||
{ "sqlite3_next_stmt", test_next_stmt ,0 },
|
||||
{ "sqlite3_stmt_readonly", test_stmt_readonly ,0 },
|
||||
{ "sqlite3_stmt_busy", test_stmt_busy ,0 },
|
||||
@@ -7212,6 +7579,10 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
{ "file_control_test", file_control_test, 0 },
|
||||
{ "file_control_lasterrno_test", file_control_lasterrno_test, 0 },
|
||||
{ "file_control_lockproxy_test", file_control_lockproxy_test, 0 },
|
||||
#ifdef __APPLE__
|
||||
{ "file_control_truncate_test", file_control_truncate_test, 0 },
|
||||
{ "file_control_replace_test", file_control_replace_test, 0 },
|
||||
#endif
|
||||
{ "file_control_chunksize_test", file_control_chunksize_test, 0 },
|
||||
{ "file_control_sizehint_test", file_control_sizehint_test, 0 },
|
||||
#if SQLITE_OS_WIN
|
||||
@@ -7224,6 +7595,8 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
{ "file_control_tempfilename", file_control_tempfilename, 0 },
|
||||
{ "sqlite3_vfs_list", vfs_list, 0 },
|
||||
{ "sqlite3_create_function_v2", test_create_function_v2, 0 },
|
||||
{ "path_is_local", path_is_local, 0 },
|
||||
{ "path_is_dos", path_is_dos, 0 },
|
||||
|
||||
/* Functions from os.h */
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
|
||||
@@ -179,8 +179,8 @@ static int tclConnect(
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
|
||||
zCmd = sqlite3_malloc(strlen(argv[3])+1);
|
||||
pTab = (tcl_vtab*)sqlite3_malloc(sizeof(tcl_vtab));
|
||||
zCmd = sqlite3_malloc64(strlen(argv[3])+1);
|
||||
pTab = (tcl_vtab*)sqlite3_malloc64(sizeof(tcl_vtab));
|
||||
if( zCmd && pTab ){
|
||||
memcpy(zCmd, argv[3], strlen(argv[3])+1);
|
||||
tclDequote(zCmd);
|
||||
|
||||
+31
-1
@@ -580,7 +580,21 @@ Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
Tcl_SetVar2(interp,"sqlite_options","prefer_proxy_locking","0",TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#if defined(SQLITE_ENABLE_PURGEABLE_PCACHE) && defined(__APPLE__)
|
||||
Tcl_SetVar2(interp,"sqlite_options","enable_purgeable_pcache","1",TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
Tcl_SetVar2(interp,"sqlite_options","enable_purgeable_pcache","0",TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
#if SQLITE_DEFAULT_CKPTFULLFSYNC
|
||||
Tcl_SetVar2(interp,"sqlite_options","default_ckptfullfsync","1",TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
Tcl_SetVar2(interp,"sqlite_options","default_ckptfullfsync","0",TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
#if SQLITE_ENABLE_PERSIST_WAL
|
||||
Tcl_SetVar2(interp,"sqlite_options","enable_persist_wal","1",TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
Tcl_SetVar2(interp,"sqlite_options","enable_persist_wal","0",TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_OMIT_SHARED_CACHE
|
||||
Tcl_SetVar2(interp, "sqlite_options", "shared_cache", "0", TCL_GLOBAL_ONLY);
|
||||
@@ -710,6 +724,22 @@ Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY);
|
||||
Tcl_SetVar2(interp, "sqlite_options", "sqllog", "0", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
# if defined(__ppc__)
|
||||
Tcl_SetVar2(interp, "os_options", "arch", "ppc", TCL_GLOBAL_ONLY);
|
||||
# elif defined(__i386__)
|
||||
Tcl_SetVar2(interp, "os_options", "arch", "i386", TCL_GLOBAL_ONLY);
|
||||
# elif defined(__x86_64__)
|
||||
Tcl_SetVar2(interp, "os_options", "arch", "x86_64", TCL_GLOBAL_ONLY);
|
||||
# elif defined(__arm__)
|
||||
Tcl_SetVar2(interp, "os_options", "arch", "arm", TCL_GLOBAL_ONLY);
|
||||
# else
|
||||
# error Unrecognized architecture for exec_options
|
||||
# endif
|
||||
#else
|
||||
Tcl_SetVar2(interp, "os_options", "arch", "unknown", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#define LINKVAR(x) { \
|
||||
static const int cv_ ## x = SQLITE_ ## x; \
|
||||
Tcl_LinkVar(interp, "SQLITE_" #x, (char *)&(cv_ ## x), \
|
||||
|
||||
+3
-3
@@ -75,8 +75,8 @@
|
||||
** action to free the intarray objects.
|
||||
*/
|
||||
#include "sqlite3.h"
|
||||
#ifndef _INTARRAY_H_
|
||||
#define _INTARRAY_H_
|
||||
#ifndef SQLITE_INTARRAY_H
|
||||
#define SQLITE_INTARRAY_H
|
||||
|
||||
/*
|
||||
** Make sure we can call this stuff from C++.
|
||||
@@ -125,4 +125,4 @@ SQLITE_API int sqlite3_intarray_bind(
|
||||
#ifdef __cplusplus
|
||||
} /* End of the 'extern "C"' block */
|
||||
#endif
|
||||
#endif /* _INTARRAY_H_ */
|
||||
#endif /* SQLITE_INTARRAY_H */
|
||||
|
||||
+2
-1
@@ -1417,7 +1417,8 @@ static int test_db_status(
|
||||
{ "CACHE_HIT", SQLITE_DBSTATUS_CACHE_HIT },
|
||||
{ "CACHE_MISS", SQLITE_DBSTATUS_CACHE_MISS },
|
||||
{ "CACHE_WRITE", SQLITE_DBSTATUS_CACHE_WRITE },
|
||||
{ "DEFERRED_FKS", SQLITE_DBSTATUS_DEFERRED_FKS }
|
||||
{ "DEFERRED_FKS", SQLITE_DBSTATUS_DEFERRED_FKS },
|
||||
{ "CACHE_USED_SHARED", SQLITE_DBSTATUS_CACHE_USED_SHARED },
|
||||
};
|
||||
Tcl_Obj *pResult;
|
||||
if( objc!=4 ){
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
**
|
||||
*/
|
||||
|
||||
#ifndef _TEST_MULTIPLEX_H
|
||||
#define _TEST_MULTIPLEX_H
|
||||
#ifndef SQLITE_TEST_MULTIPLEX_H
|
||||
#define SQLITE_TEST_MULTIPLEX_H
|
||||
|
||||
/*
|
||||
** CAPI: File-control Operations Supported by Multiplex VFS
|
||||
@@ -96,4 +96,4 @@ extern int sqlite3_multiplex_shutdown(int eForce);
|
||||
} /* End of the 'extern "C"' block */
|
||||
#endif
|
||||
|
||||
#endif /* _TEST_MULTIPLEX_H */
|
||||
#endif /* SQLITE_TEST_MULTIPLEX_H */
|
||||
|
||||
@@ -148,7 +148,7 @@ static int superlockWalLock(
|
||||
** this function must have been obtained from a successful call to
|
||||
** sqlite3demo_superlock().
|
||||
*/
|
||||
void sqlite3demo_superunlock(void *pLock){
|
||||
static void sqlite3demo_superunlock(void *pLock){
|
||||
Superlock *p = (Superlock *)pLock;
|
||||
if( p->bWal ){
|
||||
int rc; /* Return code */
|
||||
@@ -179,9 +179,10 @@ void sqlite3demo_superunlock(void *pLock){
|
||||
** until either the lock can be obtained or the busy-handler function returns
|
||||
** 0 (indicating "give up").
|
||||
*/
|
||||
int sqlite3demo_superlock(
|
||||
static int sqlite3demo_superlock(
|
||||
const char *zPath, /* Path to database file to lock */
|
||||
const char *zVfs, /* VFS to use to access database file */
|
||||
int flags, /* Additional flags to pass to sqlite3_open_v2 */
|
||||
int (*xBusy)(void*,int), /* Busy handler callback */
|
||||
void *pBusyArg, /* Context arg for busy handler */
|
||||
void **ppLock /* OUT: Context to pass to superunlock() */
|
||||
@@ -196,7 +197,7 @@ int sqlite3demo_superlock(
|
||||
|
||||
/* Open a database handle on the file to superlock. */
|
||||
rc = sqlite3_open_v2(
|
||||
zPath, &pLock->db, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, zVfs
|
||||
zPath, &pLock->db, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|flags, zVfs
|
||||
);
|
||||
|
||||
/* Install a busy-handler and execute a BEGIN EXCLUSIVE. If this is not
|
||||
@@ -331,7 +332,7 @@ static int superlock_cmd(
|
||||
xBusy = superlock_busy;
|
||||
}
|
||||
|
||||
rc = sqlite3demo_superlock(zPath, zVfs, xBusy, &busy, &pLock);
|
||||
rc = sqlite3demo_superlock(zPath, zVfs, 0, xBusy, &busy, &pLock);
|
||||
assert( rc==SQLITE_OK || pLock==0 );
|
||||
assert( rc!=SQLITE_OK || pLock!=0 );
|
||||
|
||||
|
||||
+6
-4
@@ -121,7 +121,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
|
||||
int saved_flags; /* Saved value of the db->flags */
|
||||
int saved_nChange; /* Saved value of db->nChange */
|
||||
int saved_nTotalChange; /* Saved value of db->nTotalChange */
|
||||
void (*saved_xTrace)(void*,const char*); /* Saved db->xTrace */
|
||||
u8 saved_mTrace; /* Saved trace settings */
|
||||
Db *pDb = 0; /* Database to detach at end of vacuum */
|
||||
int isMemDb; /* True if vacuuming a :memory: database */
|
||||
int nRes; /* Bytes of reserved space at the end of each page */
|
||||
@@ -142,10 +142,10 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
|
||||
saved_flags = db->flags;
|
||||
saved_nChange = db->nChange;
|
||||
saved_nTotalChange = db->nTotalChange;
|
||||
saved_xTrace = db->xTrace;
|
||||
saved_mTrace = db->mTrace;
|
||||
db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_PreferBuiltin;
|
||||
db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder);
|
||||
db->xTrace = 0;
|
||||
db->mTrace = 0;
|
||||
|
||||
pMain = db->aDb[0].pBt;
|
||||
isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain));
|
||||
@@ -197,6 +197,8 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
|
||||
}
|
||||
#endif
|
||||
|
||||
sqlite3BtreeSetCacheSize(pTemp, db->aDb[0].pSchema->cache_size);
|
||||
sqlite3BtreeSetSpillSize(pTemp, sqlite3BtreeSetSpillSize(pMain,0));
|
||||
rc = execSql(db, pzErrMsg, "PRAGMA vacuum_db.synchronous=OFF");
|
||||
if( rc!=SQLITE_OK ) goto end_of_vacuum;
|
||||
|
||||
@@ -345,7 +347,7 @@ end_of_vacuum:
|
||||
db->flags = saved_flags;
|
||||
db->nChange = saved_nChange;
|
||||
db->nTotalChange = saved_nTotalChange;
|
||||
db->xTrace = saved_xTrace;
|
||||
db->mTrace = saved_mTrace;
|
||||
sqlite3BtreeSetPageSize(pMain, -1, -1, 1);
|
||||
|
||||
/* Currently there is an SQL level transaction open on the vacuum
|
||||
|
||||
+31
-6
@@ -597,7 +597,8 @@ int sqlite3VdbeExec(
|
||||
** sqlite3_column_text16() failed. */
|
||||
goto no_mem;
|
||||
}
|
||||
assert( p->rc==SQLITE_OK || (p->rc&0xff)==SQLITE_BUSY );
|
||||
assert( p->rc==SQLITE_OK || (p->rc&0xff)==SQLITE_BUSY
|
||||
|| (p->rc&0xFF)==SQLITE_LOCKED );
|
||||
assert( p->bIsReader || p->readOnly!=0 );
|
||||
p->rc = SQLITE_OK;
|
||||
p->iCurrentTime = 0;
|
||||
@@ -1383,6 +1384,10 @@ case OP_ResultRow: {
|
||||
}
|
||||
if( db->mallocFailed ) goto no_mem;
|
||||
|
||||
if( db->mTrace & SQLITE_TRACE_ROW ){
|
||||
db->xTrace(SQLITE_TRACE_ROW, db->pTraceArg, p, 0);
|
||||
}
|
||||
|
||||
/* Return SQLITE_ROW
|
||||
*/
|
||||
p->pc = (int)(pOp - aOp) + 1;
|
||||
@@ -2016,6 +2021,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
|
||||
if( (flags1 | flags3)&MEM_Str ){
|
||||
if( (flags1 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
|
||||
applyNumericAffinity(pIn1,0);
|
||||
flags3 = pIn3->flags;
|
||||
}
|
||||
if( (flags3 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
|
||||
applyNumericAffinity(pIn3,0);
|
||||
@@ -2028,6 +2034,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
|
||||
sqlite3VdbeMemStringify(pIn1, encoding, 1);
|
||||
testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) );
|
||||
flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask);
|
||||
flags3 = pIn3->flags;
|
||||
}
|
||||
if( (flags3 & MEM_Str)==0 && (flags3 & (MEM_Int|MEM_Real))!=0 ){
|
||||
testcase( pIn3->flags & MEM_Int );
|
||||
@@ -6776,16 +6783,34 @@ case OP_MaxPgcnt: { /* out2 */
|
||||
*/
|
||||
case OP_Init: { /* jump */
|
||||
char *zTrace;
|
||||
char *z;
|
||||
|
||||
/* If the P4 argument is not NULL, then it must be an SQL comment string.
|
||||
** The "--" string is broken up to prevent false-positives with srcck1.c.
|
||||
**
|
||||
** This assert() provides evidence for:
|
||||
** EVIDENCE-OF: R-50676-09860 The callback can compute the same text that
|
||||
** would have been returned by the legacy sqlite3_trace() interface by
|
||||
** using the X argument when X begins with "--" and invoking
|
||||
** sqlite3_expanded_sql(P) otherwise.
|
||||
*/
|
||||
assert( pOp->p4.z==0 || strncmp(pOp->p4.z, "-" "- ", 3)==0 );
|
||||
|
||||
#ifndef SQLITE_OMIT_TRACE
|
||||
if( db->xTrace
|
||||
if( (db->mTrace & (SQLITE_TRACE_STMT|SQLITE_TRACE_LEGACY))!=0
|
||||
&& !p->doingRerun
|
||||
&& (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
|
||||
){
|
||||
z = sqlite3VdbeExpandSql(p, zTrace);
|
||||
db->xTrace(db->pTraceArg, z);
|
||||
sqlite3DbFree(db, z);
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
if( db->mTrace & SQLITE_TRACE_LEGACY ){
|
||||
void (*x)(void*,const char*) = (void(*)(void*,const char*))db->xTrace;
|
||||
char *z = sqlite3VdbeExpandSql(p, zTrace);
|
||||
x(db->pTraceArg, z);
|
||||
sqlite3_free(z);
|
||||
}else
|
||||
#endif
|
||||
{
|
||||
(void)db->xTrace(SQLITE_TRACE_STMT, db->pTraceArg, p, zTrace);
|
||||
}
|
||||
}
|
||||
#ifdef SQLITE_USE_FCNTL_TRACE
|
||||
zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql);
|
||||
|
||||
+3
-3
@@ -15,8 +15,8 @@
|
||||
** or VDBE. The VDBE implements an abstract machine that runs a
|
||||
** simple program to access and modify the underlying database.
|
||||
*/
|
||||
#ifndef _SQLITE_VDBE_H_
|
||||
#define _SQLITE_VDBE_H_
|
||||
#ifndef SQLITE_VDBE_H
|
||||
#define SQLITE_VDBE_H
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
@@ -309,4 +309,4 @@ void sqlite3VdbeScanStatus(Vdbe*, int, int, int, LogEst, const char*);
|
||||
# define sqlite3VdbeScanStatus(a,b,c,d,e)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif /* SQLITE_VDBE_H */
|
||||
|
||||
+3
-3
@@ -15,8 +15,8 @@
|
||||
** 6000 lines long) it was split up into several smaller files and
|
||||
** this header information was factored out.
|
||||
*/
|
||||
#ifndef _VDBEINT_H_
|
||||
#define _VDBEINT_H_
|
||||
#ifndef SQLITE_VDBEINT_H
|
||||
#define SQLITE_VDBEINT_H
|
||||
|
||||
/*
|
||||
** The maximum number of times that a statement will try to reparse
|
||||
@@ -558,4 +558,4 @@ int sqlite3VdbeMemHandleBom(Mem *pMem);
|
||||
#define ExpandBlob(P) SQLITE_OK
|
||||
#endif
|
||||
|
||||
#endif /* !defined(_VDBEINT_H_) */
|
||||
#endif /* !defined(SQLITE_VDBEINT_H) */
|
||||
|
||||
+88
-4
@@ -15,6 +15,9 @@
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "vdbeInt.h"
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
# include "sqlrr.h"
|
||||
#endif
|
||||
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
/*
|
||||
@@ -60,12 +63,19 @@ static int vdbeSafetyNotNull(Vdbe *p){
|
||||
*/
|
||||
static SQLITE_NOINLINE void invokeProfileCallback(sqlite3 *db, Vdbe *p){
|
||||
sqlite3_int64 iNow;
|
||||
sqlite3_int64 iElapse;
|
||||
assert( p->startTime>0 );
|
||||
assert( db->xProfile!=0 );
|
||||
assert( db->xProfile!=0 || (db->mTrace & SQLITE_TRACE_PROFILE)!=0 );
|
||||
assert( db->init.busy==0 );
|
||||
assert( p->zSql!=0 );
|
||||
sqlite3OsCurrentTimeInt64(db->pVfs, &iNow);
|
||||
db->xProfile(db->pProfileArg, p->zSql, (iNow - p->startTime)*1000000);
|
||||
iElapse = (iNow - p->startTime)*1000000;
|
||||
if( db->xProfile ){
|
||||
db->xProfile(db->pProfileArg, p->zSql, iElapse);
|
||||
}
|
||||
if( db->mTrace & SQLITE_TRACE_PROFILE ){
|
||||
db->xTrace(SQLITE_TRACE_PROFILE, db->pTraceArg, p, (void*)&iElapse);
|
||||
}
|
||||
p->startTime = 0;
|
||||
}
|
||||
/*
|
||||
@@ -95,6 +105,9 @@ int sqlite3_finalize(sqlite3_stmt *pStmt){
|
||||
rc = SQLITE_OK;
|
||||
}else{
|
||||
Vdbe *v = (Vdbe*)pStmt;
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecFinalize(pStmt);
|
||||
#endif
|
||||
sqlite3 *db = v->db;
|
||||
if( vdbeSafety(v) ) return SQLITE_MISUSE_BKPT;
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
@@ -121,6 +134,9 @@ int sqlite3_reset(sqlite3_stmt *pStmt){
|
||||
}else{
|
||||
Vdbe *v = (Vdbe*)pStmt;
|
||||
sqlite3 *db = v->db;
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecReset(pStmt);
|
||||
#endif
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
checkProfileCallback(db, v);
|
||||
rc = sqlite3VdbeReset(v);
|
||||
@@ -140,7 +156,14 @@ int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
|
||||
int rc = SQLITE_OK;
|
||||
Vdbe *p = (Vdbe*)pStmt;
|
||||
#if SQLITE_THREADSAFE
|
||||
sqlite3_mutex *mutex = ((Vdbe*)pStmt)->db->mutex;
|
||||
sqlite3_mutex *mutex=NULL;
|
||||
#endif
|
||||
if( NULL==pStmt ){ return SQLITE_OK; } /* <rdar://problem/6646331> */
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecClearBindings(pStmt);
|
||||
#endif
|
||||
#if SQLITE_THREADSAFE
|
||||
mutex = ((Vdbe*)pStmt)->db->mutex;
|
||||
#endif
|
||||
sqlite3_mutex_enter(mutex);
|
||||
for(i=0; i<p->nVar; i++){
|
||||
@@ -569,7 +592,8 @@ static int sqlite3Step(Vdbe *p){
|
||||
);
|
||||
|
||||
#ifndef SQLITE_OMIT_TRACE
|
||||
if( db->xProfile && !db->init.busy && p->zSql ){
|
||||
if( (db->xProfile || (db->mTrace & SQLITE_TRACE_PROFILE)!=0)
|
||||
&& !db->init.busy && p->zSql ){
|
||||
sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime);
|
||||
}else{
|
||||
assert( p->startTime==0 );
|
||||
@@ -1301,6 +1325,9 @@ int sqlite3_bind_blob(
|
||||
int nData,
|
||||
void (*xDel)(void*)
|
||||
){
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecBindBlob(pStmt, i, zData, nData);
|
||||
#endif
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( nData<0 ) return SQLITE_MISUSE_BKPT;
|
||||
#endif
|
||||
@@ -1323,6 +1350,9 @@ int sqlite3_bind_blob64(
|
||||
int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
|
||||
int rc;
|
||||
Vdbe *p = (Vdbe *)pStmt;
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecBindDouble(pStmt, i, rValue);
|
||||
#endif
|
||||
rc = vdbeUnbind(p, i);
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3VdbeMemSetDouble(&p->aVar[i-1], rValue);
|
||||
@@ -1331,11 +1361,17 @@ int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
|
||||
return rc;
|
||||
}
|
||||
int sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecBindInt64(p, i, (i64)iValue);
|
||||
#endif
|
||||
return sqlite3_bind_int64(p, i, (i64)iValue);
|
||||
}
|
||||
int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){
|
||||
int rc;
|
||||
Vdbe *p = (Vdbe *)pStmt;
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecBindInt64(pStmt, i, iValue);
|
||||
#endif
|
||||
rc = vdbeUnbind(p, i);
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue);
|
||||
@@ -1346,6 +1382,9 @@ int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){
|
||||
int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){
|
||||
int rc;
|
||||
Vdbe *p = (Vdbe*)pStmt;
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecBindNull(pStmt, i);
|
||||
#endif
|
||||
rc = vdbeUnbind(p, i);
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3_mutex_leave(p->db->mutex);
|
||||
@@ -1359,6 +1398,9 @@ int sqlite3_bind_text(
|
||||
int nData,
|
||||
void (*xDel)(void*)
|
||||
){
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecBindText(pStmt, i, zData, nData);
|
||||
#endif
|
||||
return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF8);
|
||||
}
|
||||
int sqlite3_bind_text64(
|
||||
@@ -1385,6 +1427,9 @@ int sqlite3_bind_text16(
|
||||
int nData,
|
||||
void (*xDel)(void*)
|
||||
){
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecBindText(pStmt, i, zData, nData);
|
||||
#endif
|
||||
return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF16NATIVE);
|
||||
}
|
||||
#endif /* SQLITE_OMIT_UTF16 */
|
||||
@@ -1408,6 +1453,9 @@ int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){
|
||||
break;
|
||||
}
|
||||
case SQLITE_TEXT: {
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecBindText(pStmt, i, pValue->z, pValue->n);
|
||||
#endif
|
||||
rc = bindText(pStmt,i, pValue->z, pValue->n, SQLITE_TRANSIENT,
|
||||
pValue->enc);
|
||||
break;
|
||||
@@ -1422,6 +1470,9 @@ int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){
|
||||
int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
|
||||
int rc;
|
||||
Vdbe *p = (Vdbe *)pStmt;
|
||||
#ifdef SQLITE_ENABLE_SQLRR
|
||||
SRRecBindBlob(pStmt, i, NULL, n);
|
||||
#endif
|
||||
rc = vdbeUnbind(p, i);
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n);
|
||||
@@ -1604,6 +1655,39 @@ int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
|
||||
return (int)v;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the SQL associated with a prepared statement
|
||||
*/
|
||||
const char *sqlite3_sql(sqlite3_stmt *pStmt){
|
||||
Vdbe *p = (Vdbe *)pStmt;
|
||||
return p ? p->zSql : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the SQL associated with a prepared statement with
|
||||
** bound parameters expanded. Space to hold the returned string is
|
||||
** obtained from sqlite3_malloc(). The caller is responsible for
|
||||
** freeing the returned string by passing it to sqlite3_free().
|
||||
**
|
||||
** The SQLITE_TRACE_SIZE_LIMIT puts an upper bound on the size of
|
||||
** expanded bound parameters.
|
||||
*/
|
||||
char *sqlite3_expanded_sql(sqlite3_stmt *pStmt){
|
||||
#ifdef SQLITE_OMIT_TRACE
|
||||
return 0;
|
||||
#else
|
||||
char *z = 0;
|
||||
const char *zSql = sqlite3_sql(pStmt);
|
||||
if( zSql ){
|
||||
Vdbe *p = (Vdbe *)pStmt;
|
||||
sqlite3_mutex_enter(p->db->mutex);
|
||||
z = sqlite3VdbeExpandSql(p, zSql);
|
||||
sqlite3_mutex_leave(p->db->mutex);
|
||||
}
|
||||
return z;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
|
||||
/*
|
||||
** Allocate and populate an UnpackedRecord structure based on the serialized
|
||||
|
||||
@@ -64,14 +64,6 @@ void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, int isPrepareV2){
|
||||
p->isPrepareV2 = (u8)isPrepareV2;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the SQL associated with a prepared statement
|
||||
*/
|
||||
const char *sqlite3_sql(sqlite3_stmt *pStmt){
|
||||
Vdbe *p = (Vdbe *)pStmt;
|
||||
return p ? p->zSql : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Swap all content between two VDBE structures.
|
||||
*/
|
||||
|
||||
+9
-3
@@ -81,10 +81,13 @@ char *sqlite3VdbeExpandSql(
|
||||
int i; /* Loop counter */
|
||||
Mem *pVar; /* Value of a host parameter */
|
||||
StrAccum out; /* Accumulate the output here */
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
Mem utf8; /* Used to convert UTF16 parameters into UTF8 for display */
|
||||
#endif
|
||||
char zBase[100]; /* Initial working space */
|
||||
|
||||
db = p->db;
|
||||
sqlite3StrAccumInit(&out, db, zBase, sizeof(zBase),
|
||||
sqlite3StrAccumInit(&out, 0, zBase, sizeof(zBase),
|
||||
db->aLimit[SQLITE_LIMIT_LENGTH]);
|
||||
if( db->nVdbeExec>1 ){
|
||||
while( *zRawSql ){
|
||||
@@ -135,12 +138,14 @@ char *sqlite3VdbeExpandSql(
|
||||
int nOut; /* Number of bytes of the string text to include in output */
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
u8 enc = ENC(db);
|
||||
Mem utf8;
|
||||
if( enc!=SQLITE_UTF8 ){
|
||||
memset(&utf8, 0, sizeof(utf8));
|
||||
utf8.db = db;
|
||||
sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC);
|
||||
sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8);
|
||||
if( SQLITE_NOMEM==sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8) ){
|
||||
out.accError = STRACCUM_NOMEM;
|
||||
out.nAlloc = 0;
|
||||
}
|
||||
pVar = &utf8;
|
||||
}
|
||||
#endif
|
||||
@@ -182,6 +187,7 @@ char *sqlite3VdbeExpandSql(
|
||||
}
|
||||
}
|
||||
}
|
||||
if( out.accError ) sqlite3StrAccumReset(&out);
|
||||
return sqlite3StrAccumFinish(&out);
|
||||
}
|
||||
|
||||
|
||||
@@ -1282,11 +1282,12 @@ int sqlite3WalOpen(
|
||||
const char *zWalName, /* Name of the WAL file */
|
||||
int bNoShm, /* True to run in heap-memory mode */
|
||||
i64 mxWalSize, /* Truncate WAL to this size on reset */
|
||||
int flags, /* VFS file protection flags */
|
||||
Wal **ppWal /* OUT: Allocated Wal handle */
|
||||
){
|
||||
int rc; /* Return Code */
|
||||
Wal *pRet; /* Object to allocate and return */
|
||||
int flags; /* Flags passed to OsOpen() */
|
||||
int vfsFlags; /* Flags passed to OsOpen() */
|
||||
|
||||
assert( zWalName && zWalName[0] );
|
||||
assert( pDbFd );
|
||||
@@ -1325,9 +1326,13 @@ int sqlite3WalOpen(
|
||||
pRet->exclusiveMode = (bNoShm ? WAL_HEAPMEMORY_MODE: WAL_NORMAL_MODE);
|
||||
|
||||
/* Open file handle on the write-ahead log file. */
|
||||
flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_WAL);
|
||||
rc = sqlite3OsOpen(pVfs, zWalName, pRet->pWalFd, flags, &flags);
|
||||
if( rc==SQLITE_OK && flags&SQLITE_OPEN_READONLY ){
|
||||
if( flags&SQLITE_OPEN_READONLY ){
|
||||
vfsFlags = flags | SQLITE_OPEN_WAL;
|
||||
} else {
|
||||
vfsFlags = flags | (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_WAL);
|
||||
}
|
||||
rc = sqlite3OsOpen(pVfs, zWalName, pRet->pWalFd, vfsFlags, &vfsFlags);
|
||||
if( rc==SQLITE_OK && vfsFlags&SQLITE_OPEN_READONLY ){
|
||||
pRet->readOnly = WAL_RDONLY;
|
||||
}
|
||||
|
||||
@@ -2017,6 +2022,9 @@ static int walIndexTryHdr(Wal *pWal, int *pChanged){
|
||||
** reordering the reads and writes.
|
||||
*/
|
||||
aHdr = walIndexHdr(pWal);
|
||||
if( aHdr==NULL ){
|
||||
return 1; /* Shouldn't be getting NULL from walIndexHdr, but we are */
|
||||
}
|
||||
memcpy(&h1, (void *)&aHdr[0], sizeof(h1));
|
||||
walShmBarrier(pWal);
|
||||
memcpy(&h2, (void *)&aHdr[1], sizeof(h2));
|
||||
@@ -2617,7 +2625,6 @@ Pgno sqlite3WalDbsize(Wal *pWal){
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** This function starts a write transaction on the WAL.
|
||||
**
|
||||
@@ -2835,6 +2842,10 @@ typedef struct WalWriter {
|
||||
sqlite3_int64 iSyncPoint; /* Fsync at this offset */
|
||||
int syncFlags; /* Flags for the fsync */
|
||||
int szPage; /* Size of one page */
|
||||
#if defined(SQLITE_WRITE_WALFRAME_PREBUFFERED)
|
||||
void *aFrameBuf; /* Frame buffer */
|
||||
size_t szFrameBuf; /* Size of frame buffer */
|
||||
#endif
|
||||
} WalWriter;
|
||||
|
||||
/*
|
||||
@@ -2878,17 +2889,29 @@ static int walWriteOneFrame(
|
||||
){
|
||||
int rc; /* Result code from subfunctions */
|
||||
void *pData; /* Data actually written */
|
||||
#if defined(SQLITE_WRITE_WALFRAME_PREBUFFERED)
|
||||
u8 *aFrame = p->aFrameBuf;
|
||||
#else
|
||||
u8 aFrame[WAL_FRAME_HDRSIZE]; /* Buffer to assemble frame-header in */
|
||||
#endif
|
||||
|
||||
#if defined(SQLITE_HAS_CODEC)
|
||||
if( (pData = sqlite3PagerCodec(pPage))==0 ) return SQLITE_NOMEM_BKPT;
|
||||
#else
|
||||
pData = pPage->pData;
|
||||
#endif
|
||||
|
||||
walEncodeFrame(p->pWal, pPage->pgno, nTruncate, pData, aFrame);
|
||||
|
||||
#if defined(SQLITE_WRITE_WALFRAME_PREBUFFERED)
|
||||
memcpy(&aFrame[WAL_FRAME_HDRSIZE], pData, p->szPage);
|
||||
rc = walWriteToLog(p, aFrame, (p->szPage + WAL_FRAME_HDRSIZE), iOffset);
|
||||
#else
|
||||
rc = walWriteToLog(p, aFrame, sizeof(aFrame), iOffset);
|
||||
if( rc ) return rc;
|
||||
/* Write the page data */
|
||||
rc = walWriteToLog(p, pData, p->szPage, iOffset+sizeof(aFrame));
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -3047,6 +3070,13 @@ int sqlite3WalFrames(
|
||||
w.szPage = szPage;
|
||||
iOffset = walFrameOffset(iFrame+1, szPage);
|
||||
szFrame = szPage + WAL_FRAME_HDRSIZE;
|
||||
#if defined(SQLITE_WRITE_WALFRAME_PREBUFFERED)
|
||||
w.aFrameBuf = (void *)malloc(szFrame);
|
||||
if( NULL==w.aFrameBuf ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Write all frames into the log file exactly once */
|
||||
for(p=pList; p; p=p->pDirty){
|
||||
@@ -3082,7 +3112,12 @@ int sqlite3WalFrames(
|
||||
assert( iOffset==walFrameOffset(iFrame, szPage) );
|
||||
nDbSize = (isCommit && p->pDirty==0) ? nTruncate : 0;
|
||||
rc = walWriteOneFrame(&w, p, nDbSize, iOffset);
|
||||
if( rc ) return rc;
|
||||
if( rc ) {
|
||||
#if defined(SQLITE_WRITE_WALFRAME_PREBUFFERED)
|
||||
free(w.aFrameBuf);
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
pLast = p;
|
||||
iOffset += szFrame;
|
||||
p->flags |= PGHDR_WAL_APPEND;
|
||||
@@ -3117,7 +3152,12 @@ int sqlite3WalFrames(
|
||||
testcase( bSync );
|
||||
while( iOffset<w.iSyncPoint ){
|
||||
rc = walWriteOneFrame(&w, pLast, nTruncate, iOffset);
|
||||
if( rc ) return rc;
|
||||
if( rc ) {
|
||||
#if defined(SQLITE_WRITE_WALFRAME_PREBUFFERED)
|
||||
free(w.aFrameBuf);
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
iOffset += szFrame;
|
||||
nExtra++;
|
||||
}
|
||||
@@ -3128,6 +3168,9 @@ int sqlite3WalFrames(
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(SQLITE_WRITE_WALFRAME_PREBUFFERED)
|
||||
free(w.aFrameBuf);
|
||||
#endif
|
||||
/* If this frame set completes the first transaction in the WAL and
|
||||
** if PRAGMA journal_size_limit is set, then truncate the WAL to the
|
||||
** journal size limit, if possible.
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
** the implementation of each function in log.c for further details.
|
||||
*/
|
||||
|
||||
#ifndef _WAL_H_
|
||||
#define _WAL_H_
|
||||
#ifndef SQLITE_WAL_H
|
||||
#define SQLITE_WAL_H
|
||||
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
typedef struct Wal Wal;
|
||||
|
||||
/* Open and close a connection to a write-ahead log. */
|
||||
int sqlite3WalOpen(sqlite3_vfs*, sqlite3_file*, const char *, int, i64, Wal**);
|
||||
int sqlite3WalOpen(sqlite3_vfs*, sqlite3_file*, const char *, int, i64, int, Wal**);
|
||||
int sqlite3WalClose(Wal *pWal, int sync_flags, int, u8 *);
|
||||
|
||||
/* Set the limiting size of a WAL file. */
|
||||
@@ -78,6 +78,9 @@ int sqlite3WalReadFrame(Wal *, u32, int, u8 *);
|
||||
/* If the WAL is not empty, return the size of the database. */
|
||||
Pgno sqlite3WalDbsize(Wal *pWal);
|
||||
|
||||
/* If a WAL journal file has been created, return it */
|
||||
sqlite3_file *sqlite3WalFile(Wal *pWal);
|
||||
|
||||
/* Obtain or release the WRITER lock. */
|
||||
int sqlite3WalBeginWriteTransaction(Wal *pWal);
|
||||
int sqlite3WalEndWriteTransaction(Wal *pWal);
|
||||
@@ -143,4 +146,4 @@ int sqlite3WalFramesize(Wal *pWal);
|
||||
sqlite3_file *sqlite3WalFile(Wal *pWal);
|
||||
|
||||
#endif /* ifndef SQLITE_OMIT_WAL */
|
||||
#endif /* _WAL_H_ */
|
||||
#endif /* SQLITE_WAL_H */
|
||||
|
||||
+35
-7
@@ -2478,11 +2478,11 @@ static int whereLoopAddBtreeIndex(
|
||||
pNew->nSkip++;
|
||||
pNew->aLTerm[pNew->nLTerm++] = 0;
|
||||
pNew->wsFlags |= WHERE_SKIPSCAN;
|
||||
nIter = pProbe->aiRowLogEst[saved_nEq] - pProbe->aiRowLogEst[saved_nEq+1];
|
||||
nIter = pProbe->aiRowLogEst[saved_nEq]+1 - pProbe->aiRowLogEst[saved_nEq+1];
|
||||
pNew->nOut -= nIter;
|
||||
/* TUNING: Because uncertainties in the estimates for skip-scan queries,
|
||||
** add a 1.375 fudge factor to make skip-scan slightly less likely. */
|
||||
nIter += 5;
|
||||
nIter += 4;
|
||||
whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter + nInMul);
|
||||
pNew->nOut = saved_nOut;
|
||||
pNew->u.btree.nEq = saved_nEq;
|
||||
@@ -2701,6 +2701,7 @@ static int whereLoopAddBtree(
|
||||
pNew->rSetup += 24;
|
||||
}
|
||||
ApplyCostMultiplier(pNew->rSetup, pTab->costMult);
|
||||
if( pNew->rSetup<0 ) pNew->rSetup = 0;
|
||||
/* TUNING: Each index lookup yields 20 rows in the table. This
|
||||
** is more than the usual guess of 10 rows, since we have no way
|
||||
** of knowing how selective the index will ultimately be. It would
|
||||
@@ -2761,6 +2762,7 @@ static int whereLoopAddBtree(
|
||||
/* Full scan via index */
|
||||
if( b
|
||||
|| !HasRowid(pTab)
|
||||
|| pProbe->pPartIdxWhere!=0
|
||||
|| ( m==0
|
||||
&& pProbe->bUnordered==0
|
||||
&& (pProbe->szIdxRow<pTab->szTabRow)
|
||||
@@ -2773,11 +2775,34 @@ static int whereLoopAddBtree(
|
||||
|
||||
/* The cost of visiting the index rows is N*K, where K is
|
||||
** between 1.1 and 3.0, depending on the relative sizes of the
|
||||
** index and table rows. If this is a non-covering index scan,
|
||||
** also add the cost of visiting table rows (N*3.0). */
|
||||
** index and table rows. */
|
||||
pNew->rRun = rSize + 1 + (15*pProbe->szIdxRow)/pTab->szTabRow;
|
||||
if( m!=0 ){
|
||||
pNew->rRun = sqlite3LogEstAdd(pNew->rRun, rSize+16);
|
||||
/* If this is a non-covering index scan, add in the cost of
|
||||
** doing table lookups. The cost will be 3x the number of
|
||||
** lookups. Take into account WHERE clause terms that can be
|
||||
** satisfied using just the index, and that do not require a
|
||||
** table lookup. */
|
||||
LogEst nLookup = rSize + 16; /* Base cost: N*3 */
|
||||
int ii;
|
||||
int iCur = pSrc->iCursor;
|
||||
WhereClause *pWC = &pWInfo->sWC;
|
||||
for(ii=0; ii<pWC->nTerm; ii++){
|
||||
WhereTerm *pTerm = &pWC->a[ii];
|
||||
if( !sqlite3ExprCoveredByIndex(pTerm->pExpr, iCur, pProbe) ){
|
||||
break;
|
||||
}
|
||||
/* pTerm can be evaluated using just the index. So reduce
|
||||
** the expected number of table lookups accordingly */
|
||||
if( pTerm->truthProb<=0 ){
|
||||
nLookup += pTerm->truthProb;
|
||||
}else{
|
||||
nLookup--;
|
||||
if( pTerm->eOperator & (WO_EQ|WO_IS) ) nLookup -= 19;
|
||||
}
|
||||
}
|
||||
|
||||
pNew->rRun = sqlite3LogEstAdd(pNew->rRun, nLookup);
|
||||
}
|
||||
ApplyCostMultiplier(pNew->rRun, pTab->costMult);
|
||||
whereLoopOutputAdjust(pWC, pNew, rSize);
|
||||
@@ -3239,6 +3264,7 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
|
||||
mPrereq = mPrior;
|
||||
}
|
||||
priorJointype = pItem->fg.jointype;
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
if( IsVirtual(pItem->pTab) ){
|
||||
struct SrcList_item *p;
|
||||
for(p=&pItem[1]; p<pEnd; p++){
|
||||
@@ -3247,7 +3273,9 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
|
||||
}
|
||||
}
|
||||
rc = whereLoopAddVirtual(pBuilder, mPrereq, mUnusable);
|
||||
}else{
|
||||
}else
|
||||
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
||||
{
|
||||
rc = whereLoopAddBtree(pBuilder, mPrereq);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
@@ -3944,7 +3972,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
|
||||
if( pWInfo->nOBSat<=0 ){
|
||||
pWInfo->nOBSat = 0;
|
||||
if( nLoop>0 ){
|
||||
Bitmask m;
|
||||
Bitmask m = 0;
|
||||
int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, pFrom,
|
||||
WHERE_ORDERBY_LIMIT, nLoop-1, pFrom->aLoop[nLoop-1], &m);
|
||||
if( rc==pWInfo->pOrderBy->nExpr ){
|
||||
|
||||
+75
-6
@@ -569,7 +569,7 @@ static int codeAllEqualityTerms(
|
||||
** expression: "x>='ABC' AND x<'abd'". But this requires that the range
|
||||
** scan loop run twice, once for strings and a second time for BLOBs.
|
||||
** The OP_String opcodes on the second pass convert the upper and lower
|
||||
** bound string contants to blobs. This routine makes the necessary changes
|
||||
** bound string constants to blobs. This routine makes the necessary changes
|
||||
** to the OP_String opcodes for that to happen.
|
||||
**
|
||||
** Except, of course, if SQLITE_LIKE_DOESNT_MATCH_BLOBS is defined, then
|
||||
@@ -626,6 +626,38 @@ static int codeCursorHintCheckExpr(Walker *pWalker, Expr *pExpr){
|
||||
return WRC_Continue;
|
||||
}
|
||||
|
||||
/*
|
||||
** Test whether or not expression pExpr, which was part of a WHERE clause,
|
||||
** should be included in the cursor-hint for a table that is on the rhs
|
||||
** of a LEFT JOIN. Set Walker.eCode to non-zero before returning if the
|
||||
** expression is not suitable.
|
||||
**
|
||||
** An expression is unsuitable if it might evaluate to non NULL even if
|
||||
** a TK_COLUMN node that does affect the value of the expression is set
|
||||
** to NULL. For example:
|
||||
**
|
||||
** col IS NULL
|
||||
** col IS NOT NULL
|
||||
** coalesce(col, 1)
|
||||
** CASE WHEN col THEN 0 ELSE 1 END
|
||||
*/
|
||||
static int codeCursorHintIsOrFunction(Walker *pWalker, Expr *pExpr){
|
||||
if( pExpr->op==TK_IS
|
||||
|| pExpr->op==TK_ISNULL || pExpr->op==TK_ISNOT
|
||||
|| pExpr->op==TK_NOTNULL || pExpr->op==TK_CASE
|
||||
){
|
||||
pWalker->eCode = 1;
|
||||
}else if( pExpr->op==TK_FUNCTION ){
|
||||
int d1;
|
||||
char d2[3];
|
||||
if( 0==sqlite3IsLikeFunction(pWalker->pParse->db, pExpr, &d1, d2) ){
|
||||
pWalker->eCode = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return WRC_Continue;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** This function is called on every node of an expression tree used as an
|
||||
@@ -678,6 +710,7 @@ static int codeCursorHintFixExpr(Walker *pWalker, Expr *pExpr){
|
||||
** Insert an OP_CursorHint instruction if it is appropriate to do so.
|
||||
*/
|
||||
static void codeCursorHint(
|
||||
struct SrcList_item *pTabItem, /* FROM clause item */
|
||||
WhereInfo *pWInfo, /* The where clause */
|
||||
WhereLevel *pLevel, /* Which loop to provide hints for */
|
||||
WhereTerm *pEndRange /* Hint this end-of-scan boundary term if not NULL */
|
||||
@@ -708,7 +741,42 @@ static void codeCursorHint(
|
||||
pTerm = &pWC->a[i];
|
||||
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
|
||||
if( pTerm->prereqAll & pLevel->notReady ) continue;
|
||||
if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) continue;
|
||||
|
||||
/* Any terms specified as part of the ON(...) clause for any LEFT
|
||||
** JOIN for which the current table is not the rhs are omitted
|
||||
** from the cursor-hint.
|
||||
**
|
||||
** If this table is the rhs of a LEFT JOIN, "IS" or "IS NULL" terms
|
||||
** that were specified as part of the WHERE clause must be excluded.
|
||||
** This is to address the following:
|
||||
**
|
||||
** SELECT ... t1 LEFT JOIN t2 ON (t1.a=t2.b) WHERE t2.c IS NULL;
|
||||
**
|
||||
** Say there is a single row in t2 that matches (t1.a=t2.b), but its
|
||||
** t2.c values is not NULL. If the (t2.c IS NULL) constraint is
|
||||
** pushed down to the cursor, this row is filtered out, causing
|
||||
** SQLite to synthesize a row of NULL values. Which does match the
|
||||
** WHERE clause, and so the query returns a row. Which is incorrect.
|
||||
**
|
||||
** For the same reason, WHERE terms such as:
|
||||
**
|
||||
** WHERE 1 = (t2.c IS NULL)
|
||||
**
|
||||
** are also excluded. See codeCursorHintIsOrFunction() for details.
|
||||
*/
|
||||
if( pTabItem->fg.jointype & JT_LEFT ){
|
||||
Expr *pExpr = pTerm->pExpr;
|
||||
if( !ExprHasProperty(pExpr, EP_FromJoin)
|
||||
|| pExpr->iRightJoinTable!=pTabItem->iCursor
|
||||
){
|
||||
sWalker.eCode = 0;
|
||||
sWalker.xExprCallback = codeCursorHintIsOrFunction;
|
||||
sqlite3WalkExpr(&sWalker, pTerm->pExpr);
|
||||
if( sWalker.eCode ) continue;
|
||||
}
|
||||
}else{
|
||||
if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) continue;
|
||||
}
|
||||
|
||||
/* All terms in pWLoop->aLTerm[] except pEndRange are used to initialize
|
||||
** the cursor. These terms are not needed as hints for a pure range
|
||||
@@ -742,7 +810,7 @@ static void codeCursorHint(
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define codeCursorHint(A,B,C) /* No-op */
|
||||
# define codeCursorHint(A,B,C,D) /* No-op */
|
||||
#endif /* SQLITE_ENABLE_CURSOR_HINTS */
|
||||
|
||||
/*
|
||||
@@ -998,7 +1066,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
pStart = pEnd;
|
||||
pEnd = pTerm;
|
||||
}
|
||||
codeCursorHint(pWInfo, pLevel, pEnd);
|
||||
codeCursorHint(pTabItem, pWInfo, pLevel, pEnd);
|
||||
if( pStart ){
|
||||
Expr *pX; /* The expression that defines the start bound */
|
||||
int r1, rTemp; /* Registers for holding the start boundary */
|
||||
@@ -1212,7 +1280,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
** and store the values of those terms in an array of registers
|
||||
** starting at regBase.
|
||||
*/
|
||||
codeCursorHint(pWInfo, pLevel, pRangeEnd);
|
||||
codeCursorHint(pTabItem, pWInfo, pLevel, pRangeEnd);
|
||||
regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff);
|
||||
assert( zStartAff==0 || sqlite3Strlen30(zStartAff)>=nEq );
|
||||
if( zStartAff ) cEndAff = zStartAff[nEq];
|
||||
@@ -1251,6 +1319,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
}
|
||||
nConstraint++;
|
||||
testcase( pRangeStart->wtFlags & TERM_VIRTUAL );
|
||||
bSeekPastNull = 0;
|
||||
}else if( bSeekPastNull ){
|
||||
sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
|
||||
nConstraint++;
|
||||
@@ -1660,7 +1729,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
** a pseudo-cursor. No need to Rewind or Next such cursors. */
|
||||
pLevel->op = OP_Noop;
|
||||
}else{
|
||||
codeCursorHint(pWInfo, pLevel, 0);
|
||||
codeCursorHint(pTabItem, pWInfo, pLevel, 0);
|
||||
pLevel->op = aStep[bRev];
|
||||
pLevel->p1 = iCur;
|
||||
pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk);
|
||||
|
||||
+3
-5
@@ -785,12 +785,10 @@ static int termIsEquivalence(Parse *pParse, Expr *pExpr){
|
||||
pColl = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight);
|
||||
if( pColl==0 || sqlite3StrICmp(pColl->zName, "BINARY")==0 ) return 1;
|
||||
pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
|
||||
/* Since pLeft and pRight are both a column references, their collating
|
||||
** sequence should always be defined. */
|
||||
zColl1 = ALWAYS(pColl) ? pColl->zName : 0;
|
||||
zColl1 = pColl ? pColl->zName : 0;
|
||||
pColl = sqlite3ExprCollSeq(pParse, pExpr->pRight);
|
||||
zColl2 = ALWAYS(pColl) ? pColl->zName : 0;
|
||||
return sqlite3StrICmp(zColl1, zColl2)==0;
|
||||
zColl2 = pColl ? pColl->zName : 0;
|
||||
return sqlite3_stricmp(zColl1, zColl2)==0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -146,6 +146,8 @@ ifcapable !wal {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
if ![wal_is_ok] { finish_test; return }
|
||||
|
||||
db close
|
||||
forcedelete test.db
|
||||
do_test 8_3_names-5.0 {
|
||||
|
||||
+6
-6
@@ -184,7 +184,7 @@ do_test alter3-3.2 {
|
||||
if {!$has_codec} {
|
||||
do_test alter3-3.3 {
|
||||
get_file_format
|
||||
} {4}
|
||||
} {3}
|
||||
}
|
||||
ifcapable schema_version {
|
||||
do_test alter3-3.4 {
|
||||
@@ -220,7 +220,7 @@ do_test alter3-4.2 {
|
||||
if {!$has_codec} {
|
||||
do_test alter3-4.3 {
|
||||
get_file_format
|
||||
} {4}
|
||||
} {3}
|
||||
}
|
||||
ifcapable schema_version {
|
||||
do_test alter3-4.4 {
|
||||
@@ -270,7 +270,7 @@ ifcapable attach {
|
||||
if {!$has_codec} {
|
||||
do_test alter3-5.5 {
|
||||
list [get_file_format test2.db] [get_file_format]
|
||||
} {4 4}
|
||||
} {3 3}
|
||||
}
|
||||
do_test alter3-5.6 {
|
||||
execsql {
|
||||
@@ -347,19 +347,19 @@ if {!$has_codec} {
|
||||
ALTER TABLE abc ADD d DEFAULT NULL;
|
||||
}
|
||||
get_file_format
|
||||
} {4}
|
||||
} {3}
|
||||
do_test alter3-7.3 {
|
||||
execsql {
|
||||
ALTER TABLE abc ADD e DEFAULT 10;
|
||||
}
|
||||
get_file_format
|
||||
} {4}
|
||||
} {3}
|
||||
do_test alter3-7.4 {
|
||||
execsql {
|
||||
ALTER TABLE abc ADD f DEFAULT NULL;
|
||||
}
|
||||
get_file_format
|
||||
} {4}
|
||||
} {3}
|
||||
do_test alter3-7.5 {
|
||||
execsql {
|
||||
VACUUM;
|
||||
|
||||
@@ -355,4 +355,23 @@ do_execsql_test alter4-9.3 {
|
||||
SELECT typeof(c), c FROM t5;
|
||||
} {real 9.22337203685478e+18}
|
||||
|
||||
# Confirm that doing an ALTER TABLE on a legacy format database
|
||||
# does not corrupt DESC indexes.
|
||||
#
|
||||
# Ticket https://www.sqlite.org/src/tktview/f68bf68513a1c
|
||||
#
|
||||
do_test alter4-10.1 {
|
||||
db close
|
||||
sqlite3 db :memory:
|
||||
db eval {
|
||||
PRAGMA legacy_file_format=on;
|
||||
CREATE TABLE t1(a,b,c);
|
||||
CREATE INDEX t1a ON t1(a DESC);
|
||||
INSERT INTO t1 VALUES(1,2,3);
|
||||
INSERT INTO t1 VALUES(2,3,4);
|
||||
ALTER TABLE t1 ADD COLUMN d;
|
||||
PRAGMA integrity_check;
|
||||
}
|
||||
} {ok}
|
||||
|
||||
finish_test
|
||||
|
||||
+18
-17
@@ -737,23 +737,24 @@ do_test attach-6.1 {
|
||||
}
|
||||
} {0 {}}
|
||||
if {$tcl_platform(platform)=="unix"} {
|
||||
do_test attach-6.2 {
|
||||
sqlite3 dbx cannot-read
|
||||
dbx eval {CREATE TABLE t1(a,b,c)}
|
||||
dbx close
|
||||
file attributes cannot-read -permission 0000
|
||||
if {[file writable cannot-read]} {
|
||||
puts "\n**** Tests do not work when run as root ****"
|
||||
forcedelete cannot-read
|
||||
exit 1
|
||||
}
|
||||
catchsql {
|
||||
ATTACH DATABASE 'cannot-read' AS noread;
|
||||
}
|
||||
} {1 {unable to open database: cannot-read}}
|
||||
do_test attach-6.2.2 {
|
||||
db errorcode
|
||||
} {14}
|
||||
sqlite3 dbx cannot-read
|
||||
dbx eval {CREATE TABLE t1(a,b,c)}
|
||||
dbx close
|
||||
file attributes cannot-read -permission 0000
|
||||
if {[file writable cannot-read]} {
|
||||
#puts "\n**** Tests do not work when run as root ****"
|
||||
forcedelete cannot-read
|
||||
#exit 1
|
||||
} else {
|
||||
do_test attach-6.2 {
|
||||
catchsql {
|
||||
ATTACH DATABASE 'cannot-read' AS noread;
|
||||
}
|
||||
} {1 {unable to open database: cannot-read}}
|
||||
do_test attach-6.2.2 {
|
||||
db errorcode
|
||||
} {14}
|
||||
}
|
||||
forcedelete cannot-read
|
||||
}
|
||||
|
||||
|
||||
@@ -80,6 +80,7 @@ foreach {name f} $files {
|
||||
set mode wal
|
||||
}
|
||||
ifcapable !wal { set mode delete }
|
||||
if ![wal_is_ok] { set mode delete }
|
||||
lappend L $mode
|
||||
append S "
|
||||
PRAGMA $name.journal_mode = WAL;
|
||||
|
||||
@@ -98,12 +98,6 @@ SQLITE_UPDATE sqlite_master tbl_name main {}
|
||||
SQLITE_UPDATE sqlite_master rootpage main {}
|
||||
SQLITE_UPDATE sqlite_master sql main {}
|
||||
SQLITE_READ sqlite_master ROWID main {}
|
||||
SQLITE_READ sqlite_master name main {}
|
||||
SQLITE_READ sqlite_master rootpage main {}
|
||||
SQLITE_READ sqlite_master sql main {}
|
||||
SQLITE_READ sqlite_master tbl_name main {}
|
||||
SQLITE_READ sqlite_master type main {}
|
||||
SQLITE_READ sqlite_master ROWID main {}
|
||||
}
|
||||
do_test auth2-2.2 {
|
||||
set ::authargs {}
|
||||
@@ -119,12 +113,6 @@ SQLITE_UPDATE sqlite_master tbl_name main {}
|
||||
SQLITE_UPDATE sqlite_master rootpage main {}
|
||||
SQLITE_UPDATE sqlite_master sql main {}
|
||||
SQLITE_READ sqlite_master ROWID main {}
|
||||
SQLITE_READ sqlite_master name main {}
|
||||
SQLITE_READ sqlite_master rootpage main {}
|
||||
SQLITE_READ sqlite_master sql main {}
|
||||
SQLITE_READ sqlite_master tbl_name main {}
|
||||
SQLITE_READ sqlite_master type main {}
|
||||
SQLITE_READ sqlite_master ROWID main {}
|
||||
}
|
||||
do_test auth2-2.3 {
|
||||
set ::authargs {}
|
||||
|
||||
+19
-2
@@ -12,8 +12,7 @@
|
||||
# Test that the truncate optimization is disabled if the SQLITE_DELETE
|
||||
# authorization callback returns SQLITE_IGNORE.
|
||||
#
|
||||
# $Id: auth3.test,v 1.2 2009/05/04 01:58:31 drh Exp $
|
||||
#
|
||||
# Test that authorizer is disabled during schema parsing.
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@@ -108,4 +107,22 @@ do_test auth3-2.2 {
|
||||
set sqlite_search_count
|
||||
} {1}
|
||||
|
||||
# 2016-07-28. A problem report from a private client complaining about
|
||||
# an authorizer failure during an ALTER TABLE. The solution (I think) is
|
||||
# to disable the authorizer during schema parsing.
|
||||
#
|
||||
proc auth {code args} {
|
||||
if {$code=="SQLITE_READ" && [regexp {DoNotRead} $args]} {
|
||||
return SQLITE_DENY
|
||||
}
|
||||
return SQLITE_OK
|
||||
}
|
||||
do_execsql_test auth3-3.0 {
|
||||
CREATE TEMPORARY TABLE TempTable (
|
||||
key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE,
|
||||
value TEXT NOT NULL ON CONFLICT FAIL);
|
||||
ALTER TABLE TempTable RENAME TO DoNotRead;
|
||||
SELECT name FROM sqlite_temp_master;
|
||||
} {DoNotRead sqlite_autoindex_DoNotRead_1}
|
||||
|
||||
finish_test
|
||||
|
||||
+15
-10
@@ -135,17 +135,22 @@ foreach omit {0 1} {
|
||||
#-------------------------------------------------------------------------
|
||||
# Test the same pattern works with ordinary tables.
|
||||
#
|
||||
do_execsql_test 2.1 {
|
||||
CREATE TABLE t2(x TEXT COLLATE nocase, y TEXT);
|
||||
CREATE INDEX t2x ON t2(x COLLATE nocase);
|
||||
CREATE INDEX t2y ON t2(y);
|
||||
}
|
||||
# This test does not work if the ICU extension is enabled. ICU overrides
|
||||
# LIKE - and this optimization only works with the built-in LIKE function.
|
||||
#
|
||||
ifcapable !icu {
|
||||
do_execsql_test 2.1 {
|
||||
CREATE TABLE t2(x TEXT COLLATE nocase, y TEXT);
|
||||
CREATE INDEX t2x ON t2(x COLLATE nocase);
|
||||
CREATE INDEX t2y ON t2(y);
|
||||
}
|
||||
|
||||
do_eqp_test 2.2 {
|
||||
SELECT * FROM t2 WHERE x LIKE 'abc%' OR y = 'def'
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t2 USING INDEX t2x (x>? AND x<?)}
|
||||
0 0 0 {SEARCH TABLE t2 USING INDEX t2y (y=?)}
|
||||
do_eqp_test 2.2 {
|
||||
SELECT * FROM t2 WHERE x LIKE 'abc%' OR y = 'def'
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t2 USING INDEX t2x (x>? AND x<?)}
|
||||
0 0 0 {SEARCH TABLE t2 USING INDEX t2y (y=?)}
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
@@ -656,6 +656,9 @@ do_test bind-13.4 {
|
||||
[sqlite3_column_type $VM 2]
|
||||
} {NULL NULL NULL}
|
||||
sqlite3_finalize $VM
|
||||
do_test bind-13.5 {
|
||||
sqlite3_clear_bindings_null
|
||||
} {0}
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# These tests attempt to reproduce bug #3463.
|
||||
|
||||
+16
-5
@@ -107,12 +107,17 @@ do_execsql_test cache-2.3.3 {
|
||||
} {main exclusive temp closed}
|
||||
do_test cache-2.3.4 { pager_cache_size db } 2
|
||||
do_execsql_test cache-2.3.5 COMMIT
|
||||
do_test cache-2.3.6 { pager_cache_size db } 1
|
||||
|
||||
if !$::sqlite_options(enable_purgeable_pcache) {
|
||||
# purgeable pcache doesn't share cache between connections
|
||||
do_test cache-2.3.6 { pager_cache_size db } 1
|
||||
}
|
||||
do_execsql_test cache-2.3.7 {
|
||||
SELECT * FROM t1 UNION SELECT * FROM t2;
|
||||
} {1 2 i j x y}
|
||||
do_test cache-2.3.8 { pager_cache_size db } 1
|
||||
if !$::sqlite_options(enable_purgeable_pcache) {
|
||||
# purgeable pcache doesn't share cache between connections
|
||||
do_test cache-2.3.8 { pager_cache_size db } 1
|
||||
}
|
||||
|
||||
# Tests for cache_size = 0.
|
||||
#
|
||||
@@ -130,11 +135,17 @@ do_execsql_test cache-2.4.3 {
|
||||
do_test cache-2.4.4 { pager_cache_size db } 2
|
||||
do_execsql_test cache-2.4.5 COMMIT
|
||||
|
||||
do_test cache-2.4.6 { pager_cache_size db } 0
|
||||
if !$::sqlite_options(enable_purgeable_pcache) {
|
||||
# purgeable pcache doesn't share cache between connections
|
||||
do_test cache-2.4.6 { pager_cache_size db } 0
|
||||
}
|
||||
do_execsql_test cache-2.4.7 {
|
||||
SELECT * FROM t1 UNION SELECT * FROM t2;
|
||||
} {1 2 i j x y}
|
||||
do_test cache-2.4.8 { pager_cache_size db } 0
|
||||
if !$::sqlite_options(enable_purgeable_pcache) {
|
||||
# purgeable pcache doesn't share cache between connections
|
||||
do_test cache-2.4.8 { pager_cache_size db } 0
|
||||
}
|
||||
|
||||
sqlite3_soft_heap_limit $cmdlinearg(soft-heap-limit)
|
||||
finish_test
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
# 2016-07-01
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
# Test cases for a crash bug.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
do_execsql_test collateB-1.1 {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY);
|
||||
CREATE TABLE t2(b INTEGER PRIMARY KEY, x1 INT COLLATE NOCASE);
|
||||
CREATE TABLE t3(x2 INT);
|
||||
SELECT * FROM t3, t2, t1 WHERE x2=b AND x1=a AND a=1;
|
||||
} {}
|
||||
do_execsql_test collateB-1.2 {
|
||||
INSERT INTO t1(a) VALUES(1),(2),(3);
|
||||
INSERT INTO t2(b,x1) VALUES(11,1),(22,2),(33,3);
|
||||
INSERT INTO t3(x2) VALUES(11),(22),(33);
|
||||
SELECT *,'|' FROM t3, t2, t1 WHERE x2=b AND x1=a AND a=1;
|
||||
} {11 11 1 1 |}
|
||||
do_execsql_test collateB-1.3 {
|
||||
SELECT *,'|' FROM t3, t1, t2 WHERE x2=b AND x1=a AND a=1;
|
||||
} {11 1 11 1 |}
|
||||
do_execsql_test collateB-1.4 {
|
||||
SELECT *,'|' FROM t2, t3, t1 WHERE x2=b AND x1=a AND a=1;
|
||||
} {11 1 11 1 |}
|
||||
do_execsql_test collateB-1.5 {
|
||||
SELECT *,'|' FROM t2, t1, t3 WHERE x2=b AND x1=a AND a=1;
|
||||
} {11 1 1 11 |}
|
||||
do_execsql_test collateB-1.6 {
|
||||
SELECT *,'|' FROM t1, t2, t3 WHERE x2=b AND x1=a AND a=1;
|
||||
} {1 11 1 11 |}
|
||||
do_execsql_test collateB-1.7 {
|
||||
SELECT *,'|' FROM t1, t2, t3 WHERE x2=b AND x1=a AND a=1;
|
||||
} {1 11 1 11 |}
|
||||
do_execsql_test collateB-1.12 {
|
||||
SELECT *,'|' FROM t3, t2, t1 WHERE b=x2 AND a=x1 AND 1=a;
|
||||
} {11 11 1 1 |}
|
||||
do_execsql_test collateB-1.13 {
|
||||
SELECT *,'|' FROM t3, t1, t2 WHERE b=x2 AND a=x1 AND 1=a;
|
||||
} {11 1 11 1 |}
|
||||
do_execsql_test collateB-1.14 {
|
||||
SELECT *,'|' FROM t2, t3, t1 WHERE b=x2 AND a=x1 AND 1=a;
|
||||
} {11 1 11 1 |}
|
||||
do_execsql_test collateB-1.15 {
|
||||
SELECT *,'|' FROM t2, t1, t3 WHERE b=x2 AND a=x1 AND 1=a;
|
||||
} {11 1 1 11 |}
|
||||
do_execsql_test collateB-1.16 {
|
||||
SELECT *,'|' FROM t1, t2, t3 WHERE b=x2 AND a=x1 AND 1=a;
|
||||
} {1 11 1 11 |}
|
||||
do_execsql_test collateB-1.17 {
|
||||
SELECT *,'|' FROM t1, t2, t3 WHERE b=x2 AND a=x1 AND 1=a;
|
||||
} {1 11 1 11 |}
|
||||
|
||||
finish_test
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix closure01
|
||||
set testprefix csv01
|
||||
|
||||
ifcapable !vtab||!cte { finish_test ; return }
|
||||
|
||||
|
||||
+4
-3
@@ -196,13 +196,14 @@ set tc 1
|
||||
foreach opt $opts {
|
||||
do_test ctime-2.5.$tc {
|
||||
set N [ expr {$tc-1} ]
|
||||
set ans1 [ catchsql {
|
||||
set ans1 [catch {db one {
|
||||
SELECT sqlite_compileoption_get($N);
|
||||
} ]
|
||||
}} msg]
|
||||
lappend ans1 $msg
|
||||
set ans2 [ catchsql {
|
||||
SELECT sqlite_compileoption_used($opt);
|
||||
} ]
|
||||
list [ lindex $ans1 0 ] [ expr { [lindex $ans1 1]==$opt } ] \
|
||||
list [ lindex $ans1 0 ] [ expr { [lindex [lindex $ans1 1] 0]==$opt } ] \
|
||||
[ expr { $ans2 } ]
|
||||
} {0 1 {0 1}}
|
||||
incr tc 1
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
# 2016 June 17
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus is on testing that cursor-hints are correct for queries
|
||||
# involving LEFT JOIN.
|
||||
#
|
||||
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set ::testprefix cursorhint2
|
||||
|
||||
ifcapable !cursorhints {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
proc extract_hints {sql} {
|
||||
|
||||
db eval "SELECT tbl_name, rootpage FROM sqlite_master where rootpage" {
|
||||
set lookup($rootpage) $tbl_name
|
||||
}
|
||||
|
||||
set ret [list]
|
||||
db eval "EXPLAIN $sql" a {
|
||||
switch -- $a(opcode) {
|
||||
OpenRead {
|
||||
set csr($a(p1)) $lookup($a(p2))
|
||||
}
|
||||
CursorHint {
|
||||
lappend ret $csr($a(p1)) $a(p4)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set ret
|
||||
}
|
||||
|
||||
proc do_extract_hints_test {tn sql ret} {
|
||||
uplevel [list do_test $tn [list extract_hints $sql] [list {*}$ret]]
|
||||
}
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
PRAGMA automatic_index = 0;
|
||||
CREATE TABLE t1(a, b);
|
||||
CREATE TABLE t2(c, d);
|
||||
CREATE TABLE t3(e, f);
|
||||
}
|
||||
|
||||
do_extract_hints_test 1.1 {
|
||||
SELECT * FROM t1 WHERE a=1;
|
||||
} {
|
||||
t1 EQ(c0,1)
|
||||
}
|
||||
|
||||
do_extract_hints_test 1.2 {
|
||||
SELECT * FROM t1 CROSS JOIN t2 ON (a=c) WHERE d IS NULL;
|
||||
} {
|
||||
t2 {AND(ISNULL(c1),EQ(r[1],c0))}
|
||||
}
|
||||
|
||||
do_extract_hints_test 1.3 {
|
||||
SELECT * FROM t1 LEFT JOIN t2 ON (a=c) WHERE d IS NULL;
|
||||
} {
|
||||
t2 {EQ(r[2],c0)}
|
||||
}
|
||||
|
||||
do_extract_hints_test 1.4 {
|
||||
SELECT * FROM t1 LEFT JOIN t2 ON (a=c AND a=10) WHERE d IS NULL;
|
||||
} {
|
||||
t2 {AND(EQ(r[2],c0),EQ(r[3],10))}
|
||||
}
|
||||
|
||||
do_extract_hints_test 1.5 {
|
||||
SELECT * FROM t1 CROSS JOIN t2 ON (a=c AND a=10) WHERE d IS NULL;
|
||||
} {
|
||||
t1 EQ(c0,10) t2 {AND(ISNULL(c1),EQ(r[3],c0))}
|
||||
}
|
||||
|
||||
do_extract_hints_test 1.6 {
|
||||
SELECT * FROM t1 LEFT JOIN t2 ON (a=c) LEFT JOIN t3 ON (d=f);
|
||||
} {
|
||||
t2 {EQ(r[2],c0)} t3 {EQ(r[6],c1)}
|
||||
}
|
||||
|
||||
do_extract_hints_test 1.7 {
|
||||
SELECT * FROM t1 LEFT JOIN t2 ON (a=c AND d=e) LEFT JOIN t3 ON (d=f);
|
||||
} {
|
||||
t2 {EQ(r[2],c0)} t3 {AND(EQ(r[6],c0),EQ(r[7],c1))}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
do_execsql_test 2.0 {
|
||||
CREATE TABLE x1(x, y);
|
||||
CREATE TABLE x2(a, b);
|
||||
}
|
||||
|
||||
do_extract_hints_test 2.1 {
|
||||
SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE b IS NULL;
|
||||
} {
|
||||
x2 {EQ(c0,r[2])}
|
||||
}
|
||||
|
||||
do_extract_hints_test 2.2 {
|
||||
SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE b IS +NULL;
|
||||
} {
|
||||
x2 {EQ(c0,r[2])}
|
||||
}
|
||||
|
||||
do_extract_hints_test 2.3 {
|
||||
SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE 1 = (b IS NULL)
|
||||
} {
|
||||
x2 {EQ(c0,r[2])}
|
||||
}
|
||||
|
||||
do_extract_hints_test 2.4 {
|
||||
SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE 1 = coalesce(b, 1)
|
||||
} {
|
||||
x2 {EQ(c0,r[2])}
|
||||
}
|
||||
|
||||
do_extract_hints_test 2.5 {
|
||||
SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE 1 = coalesce(b, 1)
|
||||
} {
|
||||
x2 {EQ(c0,r[2])}
|
||||
}
|
||||
|
||||
do_extract_hints_test 2.6 {
|
||||
SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE 0 = (b IS NOT NULL)
|
||||
} {
|
||||
x2 {EQ(c0,r[2])}
|
||||
}
|
||||
|
||||
do_extract_hints_test 2.7 {
|
||||
SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE 0 = (b IS NOT +NULL)
|
||||
} {
|
||||
x2 {EQ(c0,r[2])}
|
||||
}
|
||||
|
||||
do_extract_hints_test 2.8 {
|
||||
SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE b IS NOT +NULL
|
||||
} {
|
||||
x2 {EQ(c0,r[2])}
|
||||
}
|
||||
|
||||
do_extract_hints_test 2.9 {
|
||||
SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE CASE b WHEN 0 THEN 0 ELSE 1 END;
|
||||
} {
|
||||
x2 {EQ(c0,r[2])}
|
||||
}
|
||||
|
||||
do_extract_hints_test 2.10 {
|
||||
SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE x2.b = 32+32
|
||||
} {
|
||||
x2 {AND(EQ(c1,ADD(32,32)),EQ(c0,r[2]))}
|
||||
}
|
||||
|
||||
do_extract_hints_test 2.11 {
|
||||
SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE x2.b LIKE 'abc%'
|
||||
} {
|
||||
x2 {AND(expr,EQ(c0,r[2]))}
|
||||
}
|
||||
|
||||
do_extract_hints_test 2.11 {
|
||||
SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE coalesce(x2.b, 1)
|
||||
} {
|
||||
x2 {EQ(c0,r[2])}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
+43
-5
@@ -14,6 +14,7 @@
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix dbstatus
|
||||
|
||||
ifcapable !compound {
|
||||
finish_test
|
||||
@@ -24,6 +25,7 @@ ifcapable !compound {
|
||||
db close
|
||||
sqlite3_shutdown
|
||||
sqlite3_config_memstatus 1
|
||||
sqlite3_config_uri 1
|
||||
sqlite3_initialize
|
||||
sqlite3 db test.db
|
||||
|
||||
@@ -67,16 +69,12 @@ ifcapable stat4||stat3 {
|
||||
set STAT3 0
|
||||
}
|
||||
|
||||
ifcapable malloc_usable_size {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Run the dbstatus-2 and dbstatus-3 tests with several of different
|
||||
# lookaside buffer sizes.
|
||||
#
|
||||
foreach ::lookaside_buffer_size {0 64 120} {
|
||||
ifcapable malloc_usable_size break
|
||||
|
||||
# Do not run any of these tests if there is SQL configured to run
|
||||
# as part of the [sqlite3] command. This prevents the script from
|
||||
@@ -377,4 +375,44 @@ foreach ::lookaside_buffer_size {0 64 120} {
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# The following tests focus on DBSTATUS_CACHE_USED_SHARED
|
||||
#
|
||||
ifcapable shared_cache {
|
||||
if {[permutation]=="memsys3"
|
||||
|| [permutation]=="memsys5"
|
||||
|| $::tcl_platform(os)=="Linux"} {
|
||||
proc do_cacheused_test {tn db res} {
|
||||
set cu [sqlite3_db_status $db SQLITE_DBSTATUS_CACHE_USED 0]
|
||||
set pcu [sqlite3_db_status $db SQLITE_DBSTATUS_CACHE_USED_SHARED 0]
|
||||
set cu [lindex $cu 1]
|
||||
set pcu [lindex $pcu 1]
|
||||
uplevel [list do_test $tn [list list $cu $pcu] "#/$res/"]
|
||||
}
|
||||
reset_db
|
||||
sqlite3 db file:test.db?cache=shared
|
||||
|
||||
do_execsql_test 4.0 {
|
||||
PRAGMA auto_vacuum=NONE;
|
||||
CREATE TABLE t1(a, b, c);
|
||||
INSERT INTO t1 VALUES(1, 2, 3);
|
||||
}
|
||||
do_cacheused_test 4.0.1 db { 4568 4568 }
|
||||
do_execsql_test 4.1 {
|
||||
CREATE TEMP TABLE tt(a, b, c);
|
||||
INSERT INTO tt VALUES(1, 2, 3);
|
||||
}
|
||||
do_cacheused_test 4.1.1 db { 9000 9000 }
|
||||
|
||||
sqlite3 db2 file:test.db?cache=shared
|
||||
do_cacheused_test 4.2.1 db2 { 4568 2284 }
|
||||
do_cacheused_test 4.2.2 db { 9000 6716 }
|
||||
db close
|
||||
do_cacheused_test 4.2.3 db2 { 4568 4568 }
|
||||
sqlite3 db file:test.db?cache=shared
|
||||
do_cacheused_test 4.2.4 db2 { 4568 2284 }
|
||||
db2 close
|
||||
}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -38,6 +38,9 @@ proc db_write {db {reset 0}} {
|
||||
}
|
||||
|
||||
do_test 1.1 {
|
||||
ifcapable enable_persist_wal {
|
||||
file_control_persist_wal db 0
|
||||
}
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
execsql { PRAGMA mmap_size = 0 }
|
||||
|
||||
+2
-1
@@ -33,7 +33,8 @@ testvfs oldvfs -iversion 1
|
||||
#
|
||||
# All three done with VFS "oldvfs", which has iVersion==1 and so does
|
||||
# not support shared memory.
|
||||
#
|
||||
#
|
||||
forcedelete test.db-shm
|
||||
sqlite3 db test.db -vfs oldvfs
|
||||
do_execsql_test 1.1.1 {
|
||||
PRAGMA journal_mode = WAL;
|
||||
|
||||
@@ -440,6 +440,7 @@ foreach {tn script} {
|
||||
# It's not. Test case "$tp.6".
|
||||
#
|
||||
do_test $tp.4 {
|
||||
forcedelete abc.db-shm abc.db-wal
|
||||
forcecopy test.db abc.db
|
||||
sqlite3 db4 abc.db
|
||||
db4 eval { SELECT * FROM t1 UNION ALL SELECT * FROM t2 }
|
||||
|
||||
+1
-5
@@ -401,12 +401,8 @@ sqlite3 db test.db
|
||||
# if we're using proxy locks, we use 3 filedescriptors for a db
|
||||
# that is open but NOT writing changes, normally
|
||||
# sqlite uses 1 (proxy locking adds the conch and the local lock)
|
||||
set using_proxy 0
|
||||
foreach {name value} [array get env SQLITE_FORCE_PROXY_LOCKING] {
|
||||
set using_proxy $value
|
||||
}
|
||||
set extrafds 0
|
||||
if {$using_proxy!=0} {
|
||||
if {[forced_proxy_locking]} {
|
||||
set extrafds 2
|
||||
}
|
||||
|
||||
|
||||
+12
-1
@@ -76,13 +76,24 @@ set skipwaltests [expr {
|
||||
[permutation]=="journaltest" || [permutation]=="inmemory_journal"
|
||||
}]
|
||||
ifcapable !wal { set skipwaltests 1 }
|
||||
if {![wal_is_ok]} { set skipwaltests 1 }
|
||||
|
||||
if {!$skipwaltests} {
|
||||
db close
|
||||
forcedelete test.db
|
||||
ifcapable enable_persist_wal {
|
||||
forcedelete test.db-journal
|
||||
forcedelete test.db-wal
|
||||
forcedelete test.db-shm
|
||||
}
|
||||
if {[forced_proxy_locking]} {
|
||||
forcedelete .test.db-conch
|
||||
}
|
||||
sqlite3 db test.db
|
||||
ifcapable enable_persist_wal {
|
||||
file_control_persist_wal db 0
|
||||
}
|
||||
file_control_chunksize_test db main [expr 32*1024]
|
||||
|
||||
do_test fallocate-2.1 {
|
||||
execsql {
|
||||
PRAGMA page_size = 1024;
|
||||
|
||||
@@ -640,4 +640,15 @@ do_test in-13.X {
|
||||
db nullvalue ""
|
||||
} {}
|
||||
|
||||
# At one point the following was causing valgrind to report a "jump
|
||||
# depends on unitialized location" problem.
|
||||
#
|
||||
do_execsql_test in-14.0 {
|
||||
CREATE TABLE c1(a);
|
||||
INSERT INTO c1 VALUES(1), (2), (4), (3);
|
||||
}
|
||||
do_execsql_test in-14.1 {
|
||||
SELECT * FROM c1 WHERE a IN (SELECT a FROM c1) ORDER BY 1
|
||||
} {1 2 3 4}
|
||||
|
||||
finish_test
|
||||
|
||||
+11
-6
@@ -260,12 +260,17 @@ proc access_method {args} {
|
||||
return ""
|
||||
}
|
||||
|
||||
do_test incrblob3-7.2 {
|
||||
sqlite3 db test.db
|
||||
sqlite3_db_config_lookaside db 0 0 0
|
||||
list [catch {db incrblob blobs v 1} msg] $msg
|
||||
} {1 {database schema has changed}}
|
||||
db close
|
||||
#set sqlite_os_trace 1
|
||||
# AFP asserts because the "db incrblob blobs v 1" clears the file locks and the unlock fails (HFS doesn't care about a failed unlock)
|
||||
if {[path_is_local "."]} {
|
||||
|
||||
do_test incrblob3-7.2 {
|
||||
sqlite3 db test.db
|
||||
sqlite3_db_config_lookaside db 0 0 0
|
||||
list [catch {db incrblob blobs v 1} msg] $msg
|
||||
} {1 {database schema has changed}}
|
||||
db close
|
||||
}
|
||||
tvfs delete
|
||||
|
||||
finish_test
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user