Compare commits
179 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 75940f9d6e | |||
| 13a24f841c | |||
| 8424af0f48 | |||
| 3a02daf8d2 | |||
| 3971224e9c | |||
| 6ff6032b15 | |||
| 25e838549c | |||
| ba02a63a4a | |||
| 8755a5f50c | |||
| 10819251b7 | |||
| 3d213d31e5 | |||
| 6582ae520f | |||
| aa62e48cab | |||
| 6ebf1eb2c4 | |||
| 8906b7dbde | |||
| 1c1cea8bae | |||
| d13b231923 | |||
| d4ab1034c2 | |||
| f4375446d1 | |||
| 3e0327d5de | |||
| 1fef289133 | |||
| df5e1a00de | |||
| a16cd04b43 | |||
| 31aa001fcf | |||
| 2c1820c824 | |||
| 6a12854024 | |||
| cda9a933bd | |||
| 5f36a83329 | |||
| 857df26b85 | |||
| 8f109e396f | |||
| 9b40e474ef | |||
| 828cdb3473 | |||
| 739b903e6d | |||
| e60aedc564 | |||
| b0cba4bc11 | |||
| 753c1f56db | |||
| 99eaf39784 | |||
| b2bd727e52 | |||
| 0c6ab89b41 | |||
| 0a96931b76 | |||
| bfa582a3f3 | |||
| 59ba6e8832 | |||
| dd14ecbca5 | |||
| b6750b1057 | |||
| 8f70ee0e93 | |||
| a3ab9d0c61 | |||
| d1055b1bd5 | |||
| abbf5dd3cc | |||
| 1a4a680a38 | |||
| 84ab95395e | |||
| 9af8646dce | |||
| 33aa4dbe44 | |||
| 9a9219ff24 | |||
| c722cf7d03 | |||
| 1a57c17d0f | |||
| 1a51337af8 | |||
| 36b948f88a | |||
| c049057242 | |||
| 28f98455f4 | |||
| c843016e36 | |||
| b3df0c675c | |||
| e9c5f97683 | |||
| 929b923388 | |||
| 5789d1a46f | |||
| abf582509d | |||
| 6296a2ab4b | |||
| f2db338926 | |||
| d154a43ed9 | |||
| 6c98415a1c | |||
| 6a412b8be9 | |||
| f3cdcdccbe | |||
| b4a91a9a88 | |||
| 0bdef92dc2 | |||
| d68d1f4863 | |||
| bd6789e761 | |||
| 5fb71254e4 | |||
| 06d83377e1 | |||
| 42c0a2b2f3 | |||
| 4d35c41f48 | |||
| 995f8b9d73 | |||
| a30c158c38 | |||
| b3f3d64b4b | |||
| 375d9b1f1c | |||
| 7c84c02ce3 | |||
| f332071b7f | |||
| f89aa47f80 | |||
| be5248f084 | |||
| 0ee751fb67 | |||
| 9a9705de5c | |||
| 9f18f7434e | |||
| 048810b63b | |||
| 61a0d6bc55 | |||
| 0ef84d0e5e | |||
| 8ea5eca183 | |||
| f1e1736fe1 | |||
| e1a71a582f | |||
| 875bafa17a | |||
| 1cbb7fa95c | |||
| 41148f83c4 | |||
| 00808deed0 | |||
| 38f2024062 | |||
| 0ba51089c8 | |||
| 3fb2cc1173 | |||
| 318d38cf7e | |||
| 1cb50c880e | |||
| dfb5e1cbc6 | |||
| 464083544e | |||
| be360e1ed1 | |||
| 4b79bde7a2 | |||
| 7c052da54d | |||
| 3c9a073723 | |||
| b6b676ea7c | |||
| 60f4e0918d | |||
| 0f517ea8d4 | |||
| 76f6a130a9 | |||
| 9985dabbac | |||
| 4a74d076e3 | |||
| 4eed05347c | |||
| cef2584335 | |||
| f34e9aabd8 | |||
| b496a8f547 | |||
| 19b887e4ec | |||
| 0311b622c4 | |||
| f659cf48e8 | |||
| 542a176d5e | |||
| 992590be1c | |||
| 7520996965 | |||
| 5f1d2fa4d2 | |||
| 8e18922f12 | |||
| 33c59ecafb | |||
| 1c89a7710e | |||
| d0c7305313 | |||
| 88eb7fa328 | |||
| a21f78b93f | |||
| 6bbe3dfaf2 | |||
| 816070cf5c | |||
| 7088d50109 | |||
| ea8562edce | |||
| 935f2e7074 | |||
| c982844097 | |||
| 1586699cfc | |||
| 7693c42f1a | |||
| 7b4da150da | |||
| 97ab32bcd3 | |||
| c50c8f4043 | |||
| d99d28361e | |||
| b8289a8b00 | |||
| 268e72f936 | |||
| 50be9c4b28 | |||
| e318a7f84c | |||
| a33b68364b | |||
| f3151f0a0d | |||
| a4bb7764fe | |||
| ab4e7f3337 | |||
| 6dc4148547 | |||
| a276e3fd4d | |||
| 59ac655d02 | |||
| e06874eaa1 | |||
| 9569f60e18 | |||
| 6736618a8f | |||
| 772460fd4c | |||
| b073771cdf | |||
| 67731a97a2 | |||
| 0d2e2f2b10 | |||
| 5b1c07e7fb | |||
| 3693a094b2 | |||
| d4411941e2 | |||
| cc445402c9 | |||
| 151c75ad89 | |||
| 48cc29a9ac | |||
| 398f109dfb | |||
| 0404e74caa | |||
| bfefa4c27b | |||
| 0acee5139b | |||
| bdffff9d18 | |||
| 8f87c0c4db | |||
| db5f7e954a | |||
| 46a6b99492 | |||
| f21979df76 |
+43
-16
@@ -167,7 +167,7 @@ USE_AMALGAMATION = @USE_AMALGAMATION@
|
||||
#
|
||||
LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \
|
||||
backup.lo bitvec.lo btmutex.lo btree.lo build.lo \
|
||||
callback.lo complete.lo ctime.lo date.lo delete.lo \
|
||||
callback.lo complete.lo ctime.lo date.lo dbstat.lo delete.lo \
|
||||
expr.lo fault.lo fkey.lo \
|
||||
fts3.lo fts3_aux.lo fts3_expr.lo fts3_hash.lo fts3_icu.lo \
|
||||
fts3_porter.lo fts3_snippet.lo fts3_tokenizer.lo fts3_tokenizer1.lo \
|
||||
@@ -213,6 +213,7 @@ SRC = \
|
||||
$(TOP)/src/complete.c \
|
||||
$(TOP)/src/ctime.c \
|
||||
$(TOP)/src/date.c \
|
||||
$(TOP)/src/dbstat.c \
|
||||
$(TOP)/src/delete.c \
|
||||
$(TOP)/src/expr.c \
|
||||
$(TOP)/src/fault.c \
|
||||
@@ -389,7 +390,6 @@ TESTSRC = \
|
||||
$(TOP)/src/test_server.c \
|
||||
$(TOP)/src/test_superlock.c \
|
||||
$(TOP)/src/test_syscall.c \
|
||||
$(TOP)/src/test_stat.c \
|
||||
$(TOP)/src/test_tclvar.c \
|
||||
$(TOP)/src/test_thread.c \
|
||||
$(TOP)/src/test_vfs.c \
|
||||
@@ -423,6 +423,7 @@ TESTSRC2 = \
|
||||
$(TOP)/src/build.c \
|
||||
$(TOP)/src/ctime.c \
|
||||
$(TOP)/src/date.c \
|
||||
$(TOP)/src/dbstat.c \
|
||||
$(TOP)/src/expr.c \
|
||||
$(TOP)/src/func.c \
|
||||
$(TOP)/src/insert.c \
|
||||
@@ -509,6 +510,15 @@ EXTHDR += \
|
||||
EXTHDR += \
|
||||
$(TOP)/ext/rtree/sqlite3rtree.h
|
||||
|
||||
# executables needed for testing
|
||||
#
|
||||
TESTPROGS = \
|
||||
testfixture$(TEXE) \
|
||||
sqlite3$(TEXE) \
|
||||
sqlite3_analyzer$(TEXE) \
|
||||
sqldiff$(TEXE)
|
||||
|
||||
|
||||
# This is the default Makefile target. The objects listed here
|
||||
# are what get build when you type just "make" with no arguments.
|
||||
#
|
||||
@@ -536,16 +546,19 @@ sqlite3$(TEXE): $(TOP)/src/shell.c libsqlite3.la sqlite3.h
|
||||
-o $@ $(TOP)/src/shell.c libsqlite3.la \
|
||||
$(LIBREADLINE) $(TLIBS) -rpath "$(libdir)"
|
||||
|
||||
sqldiff$(EXE): $(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h
|
||||
sqldiff$(TEXE): $(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h
|
||||
$(LTLINK) -o $@ $(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS)
|
||||
|
||||
mptester$(EXE): sqlite3.c $(TOP)/mptest/mptest.c
|
||||
fuzzershell$(TEXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h
|
||||
$(LTLINK) -o $@ $(TOP)/tool/fuzzershell.c sqlite3.c $(TLIBS)
|
||||
|
||||
mptester$(TEXE): sqlite3.c $(TOP)/mptest/mptest.c
|
||||
$(LTLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \
|
||||
$(TLIBS) -rpath "$(libdir)"
|
||||
|
||||
MPTEST1=./mptester$(EXE) mptest.db $(TOP)/mptest/crash01.test --repeat 20
|
||||
MPTEST2=./mptester$(EXE) mptest.db $(TOP)/mptest/multiwrite01.test --repeat 20
|
||||
mptest: mptester$(EXE)
|
||||
MPTEST1=./mptester$(TEXE) mptest.db $(TOP)/mptest/crash01.test --repeat 20
|
||||
MPTEST2=./mptester$(TEXE) mptest.db $(TOP)/mptest/multiwrite01.test --repeat 20
|
||||
mptest: mptester$(TEXE)
|
||||
rm -f mptest.db
|
||||
$(MPTEST1) --journalmode DELETE
|
||||
$(MPTEST2) --journalmode WAL
|
||||
@@ -649,6 +662,9 @@ ctime.lo: $(TOP)/src/ctime.c $(HDR)
|
||||
date.lo: $(TOP)/src/date.c $(HDR)
|
||||
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/date.c
|
||||
|
||||
dbstat.lo: $(TOP)/src/dbstat.c $(HDR)
|
||||
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/dbstat.c
|
||||
|
||||
delete.lo: $(TOP)/src/delete.c $(HDR)
|
||||
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/delete.c
|
||||
|
||||
@@ -948,39 +964,48 @@ testfixture$(TEXE): $(TESTFIXTURE_SRC)
|
||||
-o $@ $(TESTFIXTURE_SRC) $(LIBTCL) $(TLIBS)
|
||||
|
||||
# A very detailed test running most or all test cases
|
||||
fulltest: testfixture$(TEXE) sqlite3$(TEXE)
|
||||
fulltest: $(TESTPROGS) fuzztest
|
||||
./testfixture$(TEXE) $(TOP)/test/all.test
|
||||
|
||||
# Really really long testing
|
||||
soaktest: testfixture$(TEXE) sqlite3$(TEXE)
|
||||
soaktest: $(TESTPROGS) fuzzoomtest
|
||||
./testfixture$(TEXE) $(TOP)/test/all.test -soak=1
|
||||
|
||||
# Do extra testing but not aeverything.
|
||||
fulltestonly: testfixture$(TEXE) sqlite3$(TEXE)
|
||||
# Do extra testing but not everything.
|
||||
fulltestonly: $(TESTPROGS)
|
||||
./testfixture$(TEXE) $(TOP)/test/full.test
|
||||
|
||||
# Fuzz testing
|
||||
fuzztest: fuzzershell$(TEXE)
|
||||
./fuzzershell$(TEXE) $(TOP)/test/fuzzdata1.txt $(TOP)/test/fuzzdata2.txt
|
||||
|
||||
fuzzoomtest: fuzzershell$(TEXE)
|
||||
./fuzzershell$(TEXE) -f $(TOP)/test/fuzzdata1.txt --oom
|
||||
|
||||
# This is the common case. Run many tests but not those that take
|
||||
# a really long time.
|
||||
#
|
||||
test: testfixture$(TEXE) sqlite3$(TEXE)
|
||||
test: $(TESTPROGS) fuzztest
|
||||
./testfixture$(TEXE) $(TOP)/test/veryquick.test
|
||||
|
||||
# Run a test using valgrind. This can take a really long time
|
||||
# because valgrind is so much slower than a native machine.
|
||||
#
|
||||
valgrindtest: testfixture$(TEXE) sqlite3$(TEXE)
|
||||
valgrindtest: $(TESTPROGS) fuzzershell$(TEXE)
|
||||
valgrind -v ./fuzzershell$(TEXE) -f $(TOP)/test/fuzzdata1.txt
|
||||
OMIT_MISUSE=1 valgrind -v ./testfixture$(TEXE) $(TOP)/test/permutations.test valgrind
|
||||
|
||||
# A very fast test that checks basic sanity. The name comes from
|
||||
# the 60s-era electronics testing: "Turn it on and see if smoke
|
||||
# comes out."
|
||||
#
|
||||
smoketest: testfixture$(TEXE)
|
||||
smoketest: $(TESTPROGS) fuzzershell$(TEXE)
|
||||
./testfixture$(TEXE) $(TOP)/test/main.test
|
||||
|
||||
sqlite3_analyzer.c: sqlite3.c $(TOP)/src/test_stat.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl
|
||||
sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl
|
||||
echo "#define TCLSH 2" > $@
|
||||
cat sqlite3.c $(TOP)/src/test_stat.c $(TOP)/src/tclsqlite.c >> $@
|
||||
echo "#define SQLITE_ENABLE_DBSTAT_VTAB 1" >> $@
|
||||
cat sqlite3.c $(TOP)/src/tclsqlite.c >> $@
|
||||
echo "static const char *tclsh_main_loop(void){" >> $@
|
||||
echo "static const char *zMainloop = " >> $@
|
||||
$(NAWK) -f $(TOP)/tool/tostr.awk $(TOP)/tool/spaceanal.tcl >> $@
|
||||
@@ -1090,6 +1115,8 @@ clean:
|
||||
rm -f sqlite3_analyzer$(TEXE) sqlite3_analyzer.c
|
||||
rm -f sqlite-*-output.vsix
|
||||
rm -f mptester mptester.exe
|
||||
rm -f fuzzershell fuzzershell.exe
|
||||
rm -f sqldiff sqldiff.exe
|
||||
|
||||
distclean: clean
|
||||
rm -f config.log config.status libtool Makefile sqlite3.pc
|
||||
|
||||
+73
-18
@@ -36,6 +36,13 @@ USE_STDCALL = 0
|
||||
DYNAMIC_SHELL = 0
|
||||
!ENDIF
|
||||
|
||||
# Set this non-0 to enable extra code that attempts to detect misuse of the
|
||||
# SQLite API.
|
||||
#
|
||||
!IFNDEF API_ARMOR
|
||||
API_ARMOR = 0
|
||||
!ENDIF
|
||||
|
||||
# If necessary, create a list of harmless compiler warnings to disable when
|
||||
# compiling the various tools. For the SQLite source code itself, warnings,
|
||||
# if any, will be disabled from within it.
|
||||
@@ -115,6 +122,14 @@ USE_RC = 1
|
||||
FOR_WINRT = 0
|
||||
!ENDIF
|
||||
|
||||
# Set this non-0 to compile binaries suitable for the UAP environment.
|
||||
# This setting does not apply to any binaries that require Tcl to operate
|
||||
# properly (i.e. the text fixture, etc).
|
||||
#
|
||||
!IFNDEF FOR_UAP
|
||||
FOR_UAP = 0
|
||||
!ENDIF
|
||||
|
||||
# Set this non-0 to skip attempting to look for and/or link with the Tcl
|
||||
# runtime library.
|
||||
#
|
||||
@@ -295,6 +310,11 @@ BCC = $(BCC) -FAcs
|
||||
#
|
||||
!IF $(USE_NATIVE_LIBPATHS)!=0
|
||||
NLTLIBPATHS = "/LIBPATH:$(NCRTLIBPATH)" "/LIBPATH:$(NSDKLIBPATH)"
|
||||
|
||||
!IFDEF NUCRTLIBPATH
|
||||
NUCRTLIBPATH = $(NUCRTLIBPATH:\\=\)
|
||||
NLTLIBPATHS = $(NLTLIBPATHS) "/LIBPATH:$(NUCRTLIBPATH)"
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
# C compiler and options for use in building executables that
|
||||
@@ -478,14 +498,14 @@ BCC = $(BCC) -DNDEBUG
|
||||
RCC = $(RCC) -DNDEBUG
|
||||
!ENDIF
|
||||
|
||||
!IF $(DEBUG)>0
|
||||
TCC = $(TCC) -DSQLITE_ENABLE_API_ARMOR
|
||||
RCC = $(RCC) -DSQLITE_ENABLE_API_ARMOR
|
||||
!IF $(DEBUG)>0 || $(API_ARMOR)!=0
|
||||
TCC = $(TCC) -DSQLITE_ENABLE_API_ARMOR=1
|
||||
RCC = $(RCC) -DSQLITE_ENABLE_API_ARMOR=1
|
||||
!ENDIF
|
||||
|
||||
!IF $(DEBUG)>2
|
||||
TCC = $(TCC) -DSQLITE_DEBUG
|
||||
RCC = $(RCC) -DSQLITE_DEBUG
|
||||
TCC = $(TCC) -DSQLITE_DEBUG=1
|
||||
RCC = $(RCC) -DSQLITE_DEBUG=1
|
||||
!ENDIF
|
||||
|
||||
!IF $(DEBUG)>4 || $(OSTRACE)!=0
|
||||
@@ -494,8 +514,8 @@ RCC = $(RCC) -DSQLITE_FORCE_OS_TRACE=1 -DSQLITE_DEBUG_OS_TRACE=1
|
||||
!ENDIF
|
||||
|
||||
!IF $(DEBUG)>5
|
||||
TCC = $(TCC) -DSQLITE_ENABLE_IOTRACE
|
||||
RCC = $(RCC) -DSQLITE_ENABLE_IOTRACE
|
||||
TCC = $(TCC) -DSQLITE_ENABLE_IOTRACE=1
|
||||
RCC = $(RCC) -DSQLITE_ENABLE_IOTRACE=1
|
||||
!ENDIF
|
||||
|
||||
# Prevent warnings about "insecure" MSVC runtime library functions
|
||||
@@ -715,7 +735,7 @@ LTLIBOPTS = /NOLOGO
|
||||
#
|
||||
!IF $(FOR_WINRT)!=0
|
||||
LTLINKOPTS = $(LTLINKOPTS) /APPCONTAINER
|
||||
!IF "$(VISUALSTUDIOVERSION)"=="12.0"
|
||||
!IF "$(VISUALSTUDIOVERSION)"=="12.0" || "$(VISUALSTUDIOVERSION)"=="14.0"
|
||||
!IFNDEF STORELIBPATH
|
||||
!IF "$(PLATFORM)"=="x86"
|
||||
STORELIBPATH = $(CRTLIBPATH)\store
|
||||
@@ -759,6 +779,16 @@ LTLINKOPTS = $(LTLINKOPTS) WindowsPhoneCore.lib RuntimeObject.lib PhoneAppModelH
|
||||
LTLINKOPTS = $(LTLINKOPTS) /NODEFAULTLIB:kernel32.lib /NODEFAULTLIB:ole32.lib
|
||||
!ENDIF
|
||||
|
||||
# When compiling for UAP, some extra linker options are also required.
|
||||
#
|
||||
!IF $(FOR_UAP)!=0
|
||||
LTLINKOPTS = $(LTLINKOPTS) /DYNAMICBASE /NODEFAULTLIB:kernel32.lib
|
||||
LTLINKOPTS = $(LTLINKOPTS) mincore.lib
|
||||
!IFDEF PSDKLIBPATH
|
||||
LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(PSDKLIBPATH)"
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
# If either debugging or symbols are enabled, enable PDBs.
|
||||
#
|
||||
!IF $(DEBUG)>1 || $(SYMBOLS)!=0
|
||||
@@ -792,7 +822,7 @@ NAWK = gawk.exe
|
||||
#
|
||||
LIBOBJS0 = vdbe.lo parse.lo alter.lo analyze.lo attach.lo auth.lo \
|
||||
backup.lo bitvec.lo btmutex.lo btree.lo build.lo \
|
||||
callback.lo complete.lo ctime.lo date.lo delete.lo \
|
||||
callback.lo complete.lo ctime.lo date.lo dbstat.lo delete.lo \
|
||||
expr.lo fault.lo fkey.lo \
|
||||
fts3.lo fts3_aux.lo fts3_expr.lo fts3_hash.lo fts3_icu.lo \
|
||||
fts3_porter.lo fts3_snippet.lo fts3_tokenizer.lo fts3_tokenizer1.lo \
|
||||
@@ -848,6 +878,7 @@ SRC1 = \
|
||||
$(TOP)\src\complete.c \
|
||||
$(TOP)\src\ctime.c \
|
||||
$(TOP)\src\date.c \
|
||||
$(TOP)\src\dbstat.c \
|
||||
$(TOP)\src\delete.c \
|
||||
$(TOP)\src\expr.c \
|
||||
$(TOP)\src\fault.c \
|
||||
@@ -1025,7 +1056,6 @@ TESTSRC = \
|
||||
$(TOP)\src\test_server.c \
|
||||
$(TOP)\src\test_superlock.c \
|
||||
$(TOP)\src\test_syscall.c \
|
||||
$(TOP)\src\test_stat.c \
|
||||
$(TOP)\src\test_tclvar.c \
|
||||
$(TOP)\src\test_thread.c \
|
||||
$(TOP)\src\test_vfs.c \
|
||||
@@ -1060,6 +1090,7 @@ TESTSRC2 = \
|
||||
$(TOP)\src\build.c \
|
||||
$(TOP)\src\ctime.c \
|
||||
$(TOP)\src\date.c \
|
||||
$(TOP)\src\dbstat.c \
|
||||
$(TOP)\src\expr.c \
|
||||
$(TOP)\src\func.c \
|
||||
$(TOP)\src\insert.c \
|
||||
@@ -1148,6 +1179,15 @@ EXTHDR = $(EXTHDR) \
|
||||
EXTHDR = $(EXTHDR) \
|
||||
$(TOP)\ext\rtree\sqlite3rtree.h
|
||||
|
||||
# executables needed for testing
|
||||
#
|
||||
TESTPROGS = \
|
||||
testfixture.exe \
|
||||
sqlite3.exe \
|
||||
sqlite3_analyzer.exe \
|
||||
sqldiff.exe
|
||||
|
||||
|
||||
# This is the default Makefile target. The objects listed here
|
||||
# are what get build when you type just "make" with no arguments.
|
||||
#
|
||||
@@ -1166,6 +1206,9 @@ sqlite3.exe: $(TOP)\src\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) sqlite3.h
|
||||
sqldiff.exe: $(TOP)\tool\sqldiff.c sqlite3.c sqlite3.h
|
||||
$(LTLINK) $(TOP)\tool\sqldiff.c sqlite3.c
|
||||
|
||||
fuzzershell.exe: $(TOP)\tool\fuzzershell.c sqlite3.c sqlite3.h
|
||||
$(LTLINK) $(TOP)\tool\fuzzershell.c sqlite3.c
|
||||
|
||||
mptester.exe: $(TOP)\mptest\mptest.c $(SHELL_CORE_DEP) $(LIBRESOBJS) sqlite3.h
|
||||
$(LTLINK) $(SHELL_COMPILE_OPTS) $(TOP)\mptest\mptest.c \
|
||||
/link $(LTLINKOPTS) $(LTLIBPATHS) $(SHELL_LINK_OPTS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
|
||||
@@ -1300,6 +1343,9 @@ ctime.lo: $(TOP)\src\ctime.c $(HDR)
|
||||
date.lo: $(TOP)\src\date.c $(HDR)
|
||||
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\date.c
|
||||
|
||||
dbstat.lo: $(TOP)\src\date.c $(HDR)
|
||||
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\dbstat.c
|
||||
|
||||
delete.lo: $(TOP)\src\delete.c $(HDR)
|
||||
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\delete.c
|
||||
|
||||
@@ -1605,33 +1651,41 @@ testfixture.exe: $(TESTFIXTURE_SRC) $(LIBRESOBJS) $(HDR)
|
||||
extensiontest: testfixture.exe testloadext.dll
|
||||
.\testfixture.exe $(TOP)\test\loadext.test
|
||||
|
||||
fulltest: testfixture.exe sqlite3.exe
|
||||
fulltest: $(TESTPROGS) fuzztest
|
||||
.\testfixture.exe $(TOP)\test\all.test
|
||||
|
||||
soaktest: testfixture.exe sqlite3.exe
|
||||
soaktest: $(TESTPROGS) fuzzoomtest
|
||||
.\testfixture.exe $(TOP)\test\all.test -soak=1
|
||||
|
||||
fulltestonly: testfixture.exe sqlite3.exe
|
||||
fulltestonly: $(TESTPROGS) fuzztest
|
||||
.\testfixture.exe $(TOP)\test\full.test
|
||||
|
||||
queryplantest: testfixture.exe sqlite3.exe
|
||||
.\testfixture.exe $(TOP)\test\permutations.test queryplanner
|
||||
|
||||
test: testfixture.exe sqlite3.exe
|
||||
fuzztest: fuzzershell.exe
|
||||
.\fuzzershell.exe $(TOP)\test\fuzzdata1.txt $(TOP)\test\fuzzdata2.txt
|
||||
|
||||
fuzzoomtest: fuzzershell.exe
|
||||
.\fuzzershell.exe -f $(TOP)\test\fuzzdata1.txt --oom
|
||||
|
||||
test: $(TESTPROGS) fuzztest
|
||||
.\testfixture.exe $(TOP)\test\veryquick.test
|
||||
|
||||
smoketest: testfixture.exe
|
||||
smoketest: $(TESTPROGS) fuzzershell.exe
|
||||
.\testfixture.exe $(TOP)\test\main.test
|
||||
|
||||
sqlite3_analyzer.c: $(SQLITE3C) $(TOP)\src\test_stat.c $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl
|
||||
copy $(SQLITE3C) + $(TOP)\src\test_stat.c + $(TOP)\src\tclsqlite.c $@
|
||||
sqlite3_analyzer.c: $(SQLITE3C) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl
|
||||
echo #define TCLSH 2 > $@
|
||||
echo #define SQLITE_ENABLE_DBSTAT_VTAB 1 >> $@
|
||||
copy $@ + $(SQLITE3C) + $(TOP)\src\tclsqlite.c $@
|
||||
echo static const char *tclsh_main_loop(void){ >> $@
|
||||
echo static const char *zMainloop = >> $@
|
||||
$(NAWK) -f $(TOP)\tool\tostr.awk $(TOP)\tool\spaceanal.tcl >> $@
|
||||
echo ; return zMainloop; } >> $@
|
||||
|
||||
sqlite3_analyzer.exe: sqlite3_analyzer.c $(LIBRESOBJS)
|
||||
$(LTLINK) $(NO_WARN) -DBUILD_sqlite -DTCLSH=2 -I$(TCLINCDIR) sqlite3_analyzer.c \
|
||||
$(LTLINK) $(NO_WARN) -DBUILD_sqlite -I$(TCLINCDIR) sqlite3_analyzer.c \
|
||||
/link $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
|
||||
|
||||
testloadext.lo: $(TOP)\src\test_loadext.c
|
||||
@@ -1701,6 +1755,7 @@ clean:
|
||||
del /Q shell.c sqlite3ext.h 2>NUL
|
||||
del /Q sqlite3_analyzer.exe sqlite3_analyzer.c 2>NUL
|
||||
del /Q sqlite-*-output.vsix 2>NUL
|
||||
del /Q fuzzershell.exe sqldiff.exe 2>NUL
|
||||
|
||||
# Dynamic link library section.
|
||||
#
|
||||
|
||||
@@ -6,9 +6,9 @@ libsqlite3_la_SOURCES = sqlite3.c
|
||||
libsqlite3_la_LDFLAGS = -no-undefined -version-info 8:6:8
|
||||
|
||||
bin_PROGRAMS = sqlite3
|
||||
sqlite3_SOURCES = shell.c sqlite3.h
|
||||
sqlite3_LDADD = $(top_builddir)/libsqlite3.la @READLINE_LIBS@
|
||||
sqlite3_DEPENDENCIES = $(top_builddir)/libsqlite3.la
|
||||
sqlite3_SOURCES = shell.c sqlite3.c sqlite3.h
|
||||
sqlite3_LDADD = @READLINE_LIBS@
|
||||
sqlite3_CFLAGS = $(AM_CFLAGS)
|
||||
|
||||
include_HEADERS = sqlite3.h sqlite3ext.h
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.62 for sqlite 3.8.10.
|
||||
# Generated by GNU Autoconf 2.62 for sqlite 3.8.10.1.
|
||||
#
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
|
||||
# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
@@ -743,8 +743,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='sqlite'
|
||||
PACKAGE_TARNAME='sqlite'
|
||||
PACKAGE_VERSION='3.8.10'
|
||||
PACKAGE_STRING='sqlite 3.8.10'
|
||||
PACKAGE_VERSION='3.8.10.1'
|
||||
PACKAGE_STRING='sqlite 3.8.10.1'
|
||||
PACKAGE_BUGREPORT=''
|
||||
|
||||
# Factoring default headers for most tests.
|
||||
@@ -1481,7 +1481,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures sqlite 3.8.10 to adapt to many kinds of systems.
|
||||
\`configure' configures sqlite 3.8.10.1 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@@ -1546,7 +1546,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of sqlite 3.8.10:";;
|
||||
short | recursive ) echo "Configuration of sqlite 3.8.10.1:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1660,7 +1660,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
sqlite configure 3.8.10
|
||||
sqlite configure 3.8.10.1
|
||||
generated by GNU Autoconf 2.62
|
||||
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
|
||||
@@ -1674,7 +1674,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by sqlite $as_me 3.8.10, which was
|
||||
It was created by sqlite $as_me 3.8.10.1, which was
|
||||
generated by GNU Autoconf 2.62. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@@ -13953,7 +13953,7 @@ exec 6>&1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by sqlite $as_me 3.8.10, which was
|
||||
This file was extended by sqlite $as_me 3.8.10.1, which was
|
||||
generated by GNU Autoconf 2.62. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -14006,7 +14006,7 @@ Report bugs to <bug-autoconf@gnu.org>."
|
||||
_ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_version="\\
|
||||
sqlite config.status 3.8.10
|
||||
sqlite config.status 3.8.10.1
|
||||
configured by $0, generated by GNU Autoconf 2.62,
|
||||
with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
|
||||
|
||||
|
||||
+50
-16
@@ -508,6 +508,17 @@ static int fts3DisconnectMethod(sqlite3_vtab *pVtab){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Write an error message into *pzErr
|
||||
*/
|
||||
void sqlite3Fts3ErrMsg(char **pzErr, const char *zFormat, ...){
|
||||
va_list ap;
|
||||
sqlite3_free(*pzErr);
|
||||
va_start(ap, zFormat);
|
||||
*pzErr = sqlite3_vmprintf(zFormat, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/*
|
||||
** Construct one or more SQL statements from the format string given
|
||||
** and then evaluate those statements. The success code is written
|
||||
@@ -1039,7 +1050,7 @@ static int fts3ContentColumns(
|
||||
}else{
|
||||
rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
*pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
|
||||
sqlite3Fts3ErrMsg(pzErr, "%s", sqlite3_errmsg(db));
|
||||
}
|
||||
}
|
||||
sqlite3_free(zSql);
|
||||
@@ -1207,13 +1218,13 @@ static int fts3InitVtab(
|
||||
}
|
||||
}
|
||||
if( iOpt==SizeofArray(aFts4Opt) ){
|
||||
*pzErr = sqlite3_mprintf("unrecognized parameter: %s", z);
|
||||
sqlite3Fts3ErrMsg(pzErr, "unrecognized parameter: %s", z);
|
||||
rc = SQLITE_ERROR;
|
||||
}else{
|
||||
switch( iOpt ){
|
||||
case 0: /* MATCHINFO */
|
||||
if( strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "fts3", 4) ){
|
||||
*pzErr = sqlite3_mprintf("unrecognized matchinfo: %s", zVal);
|
||||
sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo: %s", zVal);
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
bNoDocsize = 1;
|
||||
@@ -1241,7 +1252,7 @@ static int fts3InitVtab(
|
||||
if( (strlen(zVal)!=3 || sqlite3_strnicmp(zVal, "asc", 3))
|
||||
&& (strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "desc", 4))
|
||||
){
|
||||
*pzErr = sqlite3_mprintf("unrecognized order: %s", zVal);
|
||||
sqlite3Fts3ErrMsg(pzErr, "unrecognized order: %s", zVal);
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
bDescIdx = (zVal[0]=='d' || zVal[0]=='D');
|
||||
@@ -1327,7 +1338,7 @@ static int fts3InitVtab(
|
||||
rc = fts3PrefixParameter(zPrefix, &nIndex, &aIndex);
|
||||
if( rc==SQLITE_ERROR ){
|
||||
assert( zPrefix );
|
||||
*pzErr = sqlite3_mprintf("error parsing prefix parameter: %s", zPrefix);
|
||||
sqlite3Fts3ErrMsg(pzErr, "error parsing prefix parameter: %s", zPrefix);
|
||||
}
|
||||
if( rc!=SQLITE_OK ) goto fts3_init_out;
|
||||
|
||||
@@ -1409,7 +1420,7 @@ static int fts3InitVtab(
|
||||
}
|
||||
for(i=0; i<nNotindexed; i++){
|
||||
if( azNotindexed[i] ){
|
||||
*pzErr = sqlite3_mprintf("no such column: %s", azNotindexed[i]);
|
||||
sqlite3Fts3ErrMsg(pzErr, "no such column: %s", azNotindexed[i]);
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
}
|
||||
@@ -1417,7 +1428,7 @@ static int fts3InitVtab(
|
||||
if( rc==SQLITE_OK && (zCompress==0)!=(zUncompress==0) ){
|
||||
char const *zMiss = (zCompress==0 ? "compress" : "uncompress");
|
||||
rc = SQLITE_ERROR;
|
||||
*pzErr = sqlite3_mprintf("missing %s parameter in fts4 constructor", zMiss);
|
||||
sqlite3Fts3ErrMsg(pzErr, "missing %s parameter in fts4 constructor", zMiss);
|
||||
}
|
||||
p->zReadExprlist = fts3ReadExprList(p, zUncompress, &rc);
|
||||
p->zWriteExprlist = fts3WriteExprList(p, zCompress, &rc);
|
||||
@@ -1664,7 +1675,7 @@ static int fts3CloseMethod(sqlite3_vtab_cursor *pCursor){
|
||||
sqlite3Fts3ExprFree(pCsr->pExpr);
|
||||
sqlite3Fts3FreeDeferredTokens(pCsr);
|
||||
sqlite3_free(pCsr->aDoclist);
|
||||
sqlite3_free(pCsr->aMatchinfo);
|
||||
sqlite3Fts3MIBufferFree(pCsr->pMIBuffer);
|
||||
assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
|
||||
sqlite3_free(pCsr);
|
||||
return SQLITE_OK;
|
||||
@@ -2810,7 +2821,7 @@ static int fts3SegReaderCursor(
|
||||
** calls out here. */
|
||||
if( iLevel<0 && p->aIndex ){
|
||||
Fts3SegReader *pSeg = 0;
|
||||
rc = sqlite3Fts3SegReaderPending(p, iIndex, zTerm, nTerm, isPrefix, &pSeg);
|
||||
rc = sqlite3Fts3SegReaderPending(p, iIndex, zTerm, nTerm, isPrefix||isScan, &pSeg);
|
||||
if( rc==SQLITE_OK && pSeg ){
|
||||
rc = fts3SegReaderCursorAppend(pCsr, pSeg);
|
||||
}
|
||||
@@ -3165,7 +3176,7 @@ static int fts3FilterMethod(
|
||||
/* In case the cursor has been used before, clear it now. */
|
||||
sqlite3_finalize(pCsr->pStmt);
|
||||
sqlite3_free(pCsr->aDoclist);
|
||||
sqlite3_free(pCsr->aMatchinfo);
|
||||
sqlite3Fts3MIBufferFree(pCsr->pMIBuffer);
|
||||
sqlite3Fts3ExprFree(pCsr->pExpr);
|
||||
memset(&pCursor[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor));
|
||||
|
||||
@@ -3459,11 +3470,31 @@ static void fts3ReversePoslist(char *pStart, char **ppPoslist){
|
||||
char *p = &(*ppPoslist)[-2];
|
||||
char c = 0;
|
||||
|
||||
/* Skip backwards passed any trailing 0x00 bytes added by NearTrim() */
|
||||
while( p>pStart && (c=*p--)==0 );
|
||||
|
||||
/* Search backwards for a varint with value zero (the end of the previous
|
||||
** poslist). This is an 0x00 byte preceded by some byte that does not
|
||||
** have the 0x80 bit set. */
|
||||
while( p>pStart && (*p & 0x80) | c ){
|
||||
c = *p--;
|
||||
}
|
||||
if( p>pStart ){ p = &p[2]; }
|
||||
assert( p==pStart || c==0 );
|
||||
|
||||
/* At this point p points to that preceding byte without the 0x80 bit
|
||||
** set. So to find the start of the poslist, skip forward 2 bytes then
|
||||
** over a varint.
|
||||
**
|
||||
** Normally. The other case is that p==pStart and the poslist to return
|
||||
** is the first in the doclist. In this case do not skip forward 2 bytes.
|
||||
** The second part of the if condition (c==0 && *ppPoslist>&p[2])
|
||||
** is required for cases where the first byte of a doclist and the
|
||||
** doclist is empty. For example, if the first docid is 10, a doclist
|
||||
** that begins with:
|
||||
**
|
||||
** 0x0A 0x00 <next docid delta varint>
|
||||
*/
|
||||
if( p>pStart || (c==0 && *ppPoslist>&p[2]) ){ p = &p[2]; }
|
||||
while( *p++&0x80 );
|
||||
*ppPoslist = p;
|
||||
}
|
||||
@@ -4597,12 +4628,14 @@ static void fts3EvalStartReaders(
|
||||
){
|
||||
if( pExpr && SQLITE_OK==*pRc ){
|
||||
if( pExpr->eType==FTSQUERY_PHRASE ){
|
||||
int i;
|
||||
int nToken = pExpr->pPhrase->nToken;
|
||||
for(i=0; i<nToken; i++){
|
||||
if( pExpr->pPhrase->aToken[i].pDeferred==0 ) break;
|
||||
if( nToken ){
|
||||
int i;
|
||||
for(i=0; i<nToken; i++){
|
||||
if( pExpr->pPhrase->aToken[i].pDeferred==0 ) break;
|
||||
}
|
||||
pExpr->bDeferred = (i==nToken);
|
||||
}
|
||||
pExpr->bDeferred = (i==nToken);
|
||||
*pRc = fts3EvalPhraseStart(pCsr, 1, pExpr->pPhrase);
|
||||
}else{
|
||||
fts3EvalStartReaders(pCsr, pExpr->pLeft, pRc);
|
||||
@@ -5765,7 +5798,8 @@ int sqlite3Fts3EvalPhrasePoslist(
|
||||
pIter = pPhrase->pOrPoslist;
|
||||
iDocid = pPhrase->iOrDocid;
|
||||
if( pCsr->bDesc==bDescDoclist ){
|
||||
bEof = (pIter >= (pPhrase->doclist.aAll + pPhrase->doclist.nAll));
|
||||
bEof = !pPhrase->doclist.nAll ||
|
||||
(pIter >= (pPhrase->doclist.aAll + pPhrase->doclist.nAll));
|
||||
while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){
|
||||
sqlite3Fts3DoclistNext(
|
||||
bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll,
|
||||
|
||||
+8
-4
@@ -197,6 +197,8 @@ typedef struct Fts3DeferredToken Fts3DeferredToken;
|
||||
typedef struct Fts3SegReader Fts3SegReader;
|
||||
typedef struct Fts3MultiSegReader Fts3MultiSegReader;
|
||||
|
||||
typedef struct MatchinfoBuffer MatchinfoBuffer;
|
||||
|
||||
/*
|
||||
** A connection to a fulltext index is an instance of the following
|
||||
** structure. The xCreate and xConnect methods create an instance
|
||||
@@ -306,9 +308,7 @@ struct Fts3Cursor {
|
||||
i64 iMinDocid; /* Minimum docid to return */
|
||||
i64 iMaxDocid; /* Maximum docid to return */
|
||||
int isMatchinfoNeeded; /* True when aMatchinfo[] needs filling in */
|
||||
u32 *aMatchinfo; /* Information about most recent match */
|
||||
int nMatchinfo; /* Number of elements in aMatchinfo[] */
|
||||
char *zMatchinfo; /* Matchinfo specification */
|
||||
MatchinfoBuffer *pMIBuffer; /* Buffer for matchinfo data */
|
||||
};
|
||||
|
||||
#define FTS3_EVAL_FILTER 0
|
||||
@@ -428,7 +428,9 @@ struct Fts3Expr {
|
||||
u8 bStart; /* True if iDocid is valid */
|
||||
u8 bDeferred; /* True if this expression is entirely deferred */
|
||||
|
||||
u32 *aMI;
|
||||
/* The following are used by the fts3_snippet.c module. */
|
||||
int iPhrase; /* Index of this phrase in matchinfo() results */
|
||||
u32 *aMI; /* See above */
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -539,6 +541,7 @@ int sqlite3Fts3Incrmerge(Fts3Table*,int,int);
|
||||
)
|
||||
|
||||
/* fts3.c */
|
||||
void sqlite3Fts3ErrMsg(char**,const char*,...);
|
||||
int sqlite3Fts3PutVarint(char *, sqlite3_int64);
|
||||
int sqlite3Fts3GetVarint(const char *, sqlite_int64 *);
|
||||
int sqlite3Fts3GetVarint32(const char *, int *);
|
||||
@@ -563,6 +566,7 @@ void sqlite3Fts3Snippet(sqlite3_context *, Fts3Cursor *, const char *,
|
||||
const char *, const char *, int, int
|
||||
);
|
||||
void sqlite3Fts3Matchinfo(sqlite3_context *, Fts3Cursor *, const char *);
|
||||
void sqlite3Fts3MIBufferFree(MatchinfoBuffer *p);
|
||||
|
||||
/* fts3_expr.c */
|
||||
int sqlite3Fts3ExprParse(sqlite3_tokenizer *, int,
|
||||
|
||||
+1
-1
@@ -116,7 +116,7 @@ static int fts3auxConnectMethod(
|
||||
return SQLITE_OK;
|
||||
|
||||
bad_args:
|
||||
*pzErr = sqlite3_mprintf("invalid arguments to fts4aux constructor");
|
||||
sqlite3Fts3ErrMsg(pzErr, "invalid arguments to fts4aux constructor");
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@@ -1022,13 +1022,13 @@ int sqlite3Fts3ExprParse(
|
||||
sqlite3Fts3ExprFree(*ppExpr);
|
||||
*ppExpr = 0;
|
||||
if( rc==SQLITE_TOOBIG ){
|
||||
*pzErr = sqlite3_mprintf(
|
||||
sqlite3Fts3ErrMsg(pzErr,
|
||||
"FTS expression tree is too large (maximum depth %d)",
|
||||
SQLITE_FTS3_MAX_EXPR_DEPTH
|
||||
);
|
||||
rc = SQLITE_ERROR;
|
||||
}else if( rc==SQLITE_ERROR ){
|
||||
*pzErr = sqlite3_mprintf("malformed MATCH expression: [%s]", z);
|
||||
sqlite3Fts3ErrMsg(pzErr, "malformed MATCH expression: [%s]", z);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+227
-49
@@ -27,6 +27,8 @@
|
||||
#define FTS3_MATCHINFO_LENGTH 'l' /* nCol values */
|
||||
#define FTS3_MATCHINFO_LCS 's' /* nCol values */
|
||||
#define FTS3_MATCHINFO_HITS 'x' /* 3*nCol*nPhrase values */
|
||||
#define FTS3_MATCHINFO_LHITS 'y' /* nCol*nPhrase values */
|
||||
#define FTS3_MATCHINFO_LHITS_BM 'b' /* nCol*nPhrase values */
|
||||
|
||||
/*
|
||||
** The default value for the second argument to matchinfo().
|
||||
@@ -88,9 +90,22 @@ struct MatchInfo {
|
||||
int nCol; /* Number of columns in table */
|
||||
int nPhrase; /* Number of matchable phrases in query */
|
||||
sqlite3_int64 nDoc; /* Number of docs in database */
|
||||
char flag;
|
||||
u32 *aMatchinfo; /* Pre-allocated buffer */
|
||||
};
|
||||
|
||||
/*
|
||||
** An instance of this structure is used to manage a pair of buffers, each
|
||||
** (nElem * sizeof(u32)) bytes in size. See the MatchinfoBuffer code below
|
||||
** for details.
|
||||
*/
|
||||
struct MatchinfoBuffer {
|
||||
u8 aRef[3];
|
||||
int nElem;
|
||||
int bGlobal; /* Set if global data is loaded */
|
||||
char *zMatchinfo;
|
||||
u32 aMatchinfo[0];
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
@@ -106,6 +121,97 @@ struct StrBuffer {
|
||||
};
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
** Start of MatchinfoBuffer code.
|
||||
*/
|
||||
|
||||
/*
|
||||
** Allocate a two-slot MatchinfoBuffer object.
|
||||
*/
|
||||
static MatchinfoBuffer *fts3MIBufferNew(int nElem, const char *zMatchinfo){
|
||||
MatchinfoBuffer *pRet;
|
||||
int nByte = sizeof(u32) * (2*nElem + 2) + sizeof(MatchinfoBuffer);
|
||||
int nStr = strlen(zMatchinfo);
|
||||
|
||||
pRet = sqlite3_malloc(nByte + nStr+1);
|
||||
if( pRet ){
|
||||
memset(pRet, 0, nByte);
|
||||
pRet->aMatchinfo[0] = (u8*)(&pRet->aMatchinfo[1]) - (u8*)pRet;
|
||||
pRet->aMatchinfo[1+nElem] = pRet->aMatchinfo[0] + sizeof(u32)*(nElem+1);
|
||||
pRet->nElem = nElem;
|
||||
pRet->zMatchinfo = ((char*)pRet) + nByte;
|
||||
memcpy(pRet->zMatchinfo, zMatchinfo, nStr+1);
|
||||
pRet->aRef[0] = 1;
|
||||
}
|
||||
|
||||
return pRet;
|
||||
}
|
||||
|
||||
static void fts3MIBufferFree(void *p){
|
||||
MatchinfoBuffer *pBuf = (MatchinfoBuffer*)((u8*)p - ((u32*)p)[-1]);
|
||||
|
||||
assert( (u32*)p==&pBuf->aMatchinfo[1]
|
||||
|| (u32*)p==&pBuf->aMatchinfo[pBuf->nElem+2]
|
||||
);
|
||||
if( (u32*)p==&pBuf->aMatchinfo[1] ){
|
||||
pBuf->aRef[1] = 0;
|
||||
}else{
|
||||
pBuf->aRef[2] = 0;
|
||||
}
|
||||
|
||||
if( pBuf->aRef[0]==0 && pBuf->aRef[1]==0 && pBuf->aRef[2]==0 ){
|
||||
sqlite3_free(pBuf);
|
||||
}
|
||||
}
|
||||
|
||||
static void (*fts3MIBufferAlloc(MatchinfoBuffer *p, u32 **paOut))(void*){
|
||||
void (*xRet)(void*) = 0;
|
||||
u32 *aOut = 0;
|
||||
|
||||
if( p->aRef[1]==0 ){
|
||||
p->aRef[1] = 1;
|
||||
aOut = &p->aMatchinfo[1];
|
||||
xRet = fts3MIBufferFree;
|
||||
}
|
||||
else if( p->aRef[2]==0 ){
|
||||
p->aRef[2] = 1;
|
||||
aOut = &p->aMatchinfo[p->nElem+2];
|
||||
xRet = fts3MIBufferFree;
|
||||
}else{
|
||||
aOut = (u32*)sqlite3_malloc(p->nElem * sizeof(u32));
|
||||
if( aOut ){
|
||||
xRet = sqlite3_free;
|
||||
if( p->bGlobal ) memcpy(aOut, &p->aMatchinfo[1], p->nElem*sizeof(u32));
|
||||
}
|
||||
}
|
||||
|
||||
*paOut = aOut;
|
||||
return xRet;
|
||||
}
|
||||
|
||||
static void fts3MIBufferSetGlobal(MatchinfoBuffer *p){
|
||||
p->bGlobal = 1;
|
||||
memcpy(&p->aMatchinfo[2+p->nElem], &p->aMatchinfo[1], p->nElem*sizeof(u32));
|
||||
}
|
||||
|
||||
/*
|
||||
** Free a MatchinfoBuffer object allocated using fts3MIBufferNew()
|
||||
*/
|
||||
void sqlite3Fts3MIBufferFree(MatchinfoBuffer *p){
|
||||
if( p ){
|
||||
assert( p->aRef[0]==1 );
|
||||
p->aRef[0] = 0;
|
||||
if( p->aRef[0]==0 && p->aRef[1]==0 && p->aRef[2]==0 ){
|
||||
sqlite3_free(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** End of MatchinfoBuffer code.
|
||||
*************************************************************************/
|
||||
|
||||
|
||||
/*
|
||||
** This function is used to help iterate through a position-list. A position
|
||||
** list is a list of unique integers, sorted from smallest to largest. Each
|
||||
@@ -142,7 +248,7 @@ static int fts3ExprIterate2(
|
||||
void *pCtx /* Second argument to pass to callback */
|
||||
){
|
||||
int rc; /* Return code */
|
||||
int eType = pExpr->eType; /* Type of expression node pExpr */
|
||||
int eType = pExpr->eType; /* Type of expression node pExpr */
|
||||
|
||||
if( eType!=FTSQUERY_PHRASE ){
|
||||
assert( pExpr->pLeft && pExpr->pRight );
|
||||
@@ -176,6 +282,7 @@ static int fts3ExprIterate(
|
||||
return fts3ExprIterate2(pExpr, &iPhrase, x, pCtx);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** This is an fts3ExprIterate() callback used while loading the doclists
|
||||
** for each phrase into Fts3Expr.aDoclist[]/nDoclist. See also
|
||||
@@ -220,8 +327,7 @@ static int fts3ExprLoadDoclists(
|
||||
|
||||
static int fts3ExprPhraseCountCb(Fts3Expr *pExpr, int iPhrase, void *ctx){
|
||||
(*(int *)ctx)++;
|
||||
UNUSED_PARAMETER(pExpr);
|
||||
UNUSED_PARAMETER(iPhrase);
|
||||
pExpr->iPhrase = iPhrase;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
static int fts3ExprPhraseCount(Fts3Expr *pExpr){
|
||||
@@ -442,7 +548,7 @@ static int fts3BestSnippet(
|
||||
sIter.nSnippet = nSnippet;
|
||||
sIter.nPhrase = nList;
|
||||
sIter.iCurrent = -1;
|
||||
rc = fts3ExprIterate(pCsr->pExpr, fts3SnippetFindPositions, (void *)&sIter);
|
||||
rc = fts3ExprIterate(pCsr->pExpr, fts3SnippetFindPositions, (void*)&sIter);
|
||||
if( rc==SQLITE_OK ){
|
||||
|
||||
/* Set the *pmSeen output variable. */
|
||||
@@ -743,6 +849,60 @@ static int fts3ColumnlistCount(char **ppCollist){
|
||||
return nEntry;
|
||||
}
|
||||
|
||||
/*
|
||||
** This function gathers 'y' or 'b' data for a single phrase.
|
||||
*/
|
||||
static void fts3ExprLHits(
|
||||
Fts3Expr *pExpr, /* Phrase expression node */
|
||||
MatchInfo *p /* Matchinfo context */
|
||||
){
|
||||
Fts3Table *pTab = (Fts3Table *)p->pCursor->base.pVtab;
|
||||
int iStart;
|
||||
Fts3Phrase *pPhrase = pExpr->pPhrase;
|
||||
char *pIter = pPhrase->doclist.pList;
|
||||
int iCol = 0;
|
||||
|
||||
assert( p->flag==FTS3_MATCHINFO_LHITS_BM || p->flag==FTS3_MATCHINFO_LHITS );
|
||||
if( p->flag==FTS3_MATCHINFO_LHITS ){
|
||||
iStart = pExpr->iPhrase * p->nCol;
|
||||
}else{
|
||||
iStart = pExpr->iPhrase * ((p->nCol + 31) / 32);
|
||||
}
|
||||
|
||||
while( 1 ){
|
||||
int nHit = fts3ColumnlistCount(&pIter);
|
||||
if( (pPhrase->iColumn>=pTab->nColumn || pPhrase->iColumn==iCol) ){
|
||||
if( p->flag==FTS3_MATCHINFO_LHITS ){
|
||||
p->aMatchinfo[iStart + iCol] = (u32)nHit;
|
||||
}else if( nHit ){
|
||||
p->aMatchinfo[iStart + (iCol+1)/32] |= (1 << (iCol&0x1F));
|
||||
}
|
||||
}
|
||||
assert( *pIter==0x00 || *pIter==0x01 );
|
||||
if( *pIter!=0x01 ) break;
|
||||
pIter++;
|
||||
pIter += fts3GetVarint32(pIter, &iCol);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Gather the results for matchinfo directives 'y' and 'b'.
|
||||
*/
|
||||
static void fts3ExprLHitGather(
|
||||
Fts3Expr *pExpr,
|
||||
MatchInfo *p
|
||||
){
|
||||
assert( (pExpr->pLeft==0)==(pExpr->pRight==0) );
|
||||
if( pExpr->bEof==0 && pExpr->iDocid==p->pCursor->iPrevId ){
|
||||
if( pExpr->pLeft ){
|
||||
fts3ExprLHitGather(pExpr->pLeft, p);
|
||||
fts3ExprLHitGather(pExpr->pRight, p);
|
||||
}else{
|
||||
fts3ExprLHits(pExpr, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** fts3ExprIterate() callback used to collect the "global" matchinfo stats
|
||||
** for a single query.
|
||||
@@ -821,10 +981,12 @@ static int fts3MatchinfoCheck(
|
||||
|| (cArg==FTS3_MATCHINFO_LENGTH && pTab->bHasDocsize)
|
||||
|| (cArg==FTS3_MATCHINFO_LCS)
|
||||
|| (cArg==FTS3_MATCHINFO_HITS)
|
||||
|| (cArg==FTS3_MATCHINFO_LHITS)
|
||||
|| (cArg==FTS3_MATCHINFO_LHITS_BM)
|
||||
){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
*pzErr = sqlite3_mprintf("unrecognized matchinfo request: %c", cArg);
|
||||
sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo request: %c", cArg);
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
|
||||
@@ -844,6 +1006,14 @@ static int fts3MatchinfoSize(MatchInfo *pInfo, char cArg){
|
||||
nVal = pInfo->nCol;
|
||||
break;
|
||||
|
||||
case FTS3_MATCHINFO_LHITS:
|
||||
nVal = pInfo->nCol * pInfo->nPhrase;
|
||||
break;
|
||||
|
||||
case FTS3_MATCHINFO_LHITS_BM:
|
||||
nVal = pInfo->nPhrase * ((pInfo->nCol + 31) / 32);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert( cArg==FTS3_MATCHINFO_HITS );
|
||||
nVal = pInfo->nCol * pInfo->nPhrase * 3;
|
||||
@@ -1038,7 +1208,7 @@ static int fts3MatchinfoValues(
|
||||
sqlite3_stmt *pSelect = 0;
|
||||
|
||||
for(i=0; rc==SQLITE_OK && zArg[i]; i++){
|
||||
|
||||
pInfo->flag = zArg[i];
|
||||
switch( zArg[i] ){
|
||||
case FTS3_MATCHINFO_NPHRASE:
|
||||
if( bGlobal ) pInfo->aMatchinfo[0] = pInfo->nPhrase;
|
||||
@@ -1098,6 +1268,14 @@ static int fts3MatchinfoValues(
|
||||
}
|
||||
break;
|
||||
|
||||
case FTS3_MATCHINFO_LHITS_BM:
|
||||
case FTS3_MATCHINFO_LHITS: {
|
||||
int nZero = fts3MatchinfoSize(pInfo, zArg[i]) * sizeof(u32);
|
||||
memset(pInfo->aMatchinfo, 0, nZero);
|
||||
fts3ExprLHitGather(pCsr->pExpr, pInfo);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
Fts3Expr *pExpr;
|
||||
assert( zArg[i]==FTS3_MATCHINFO_HITS );
|
||||
@@ -1129,7 +1307,8 @@ static int fts3MatchinfoValues(
|
||||
** Populate pCsr->aMatchinfo[] with data for the current row. The
|
||||
** 'matchinfo' data is an array of 32-bit unsigned integers (C type u32).
|
||||
*/
|
||||
static int fts3GetMatchinfo(
|
||||
static void fts3GetMatchinfo(
|
||||
sqlite3_context *pCtx, /* Return results here */
|
||||
Fts3Cursor *pCsr, /* FTS3 Cursor object */
|
||||
const char *zArg /* Second argument to matchinfo() function */
|
||||
){
|
||||
@@ -1138,6 +1317,9 @@ static int fts3GetMatchinfo(
|
||||
int rc = SQLITE_OK;
|
||||
int bGlobal = 0; /* Collect 'global' stats as well as local */
|
||||
|
||||
u32 *aOut = 0;
|
||||
void (*xDestroyOut)(void*) = 0;
|
||||
|
||||
memset(&sInfo, 0, sizeof(MatchInfo));
|
||||
sInfo.pCursor = pCsr;
|
||||
sInfo.nCol = pTab->nColumn;
|
||||
@@ -1145,21 +1327,18 @@ static int fts3GetMatchinfo(
|
||||
/* If there is cached matchinfo() data, but the format string for the
|
||||
** cache does not match the format string for this request, discard
|
||||
** the cached data. */
|
||||
if( pCsr->zMatchinfo && strcmp(pCsr->zMatchinfo, zArg) ){
|
||||
assert( pCsr->aMatchinfo );
|
||||
sqlite3_free(pCsr->aMatchinfo);
|
||||
pCsr->zMatchinfo = 0;
|
||||
pCsr->aMatchinfo = 0;
|
||||
if( pCsr->pMIBuffer && strcmp(pCsr->pMIBuffer->zMatchinfo, zArg) ){
|
||||
sqlite3Fts3MIBufferFree(pCsr->pMIBuffer);
|
||||
pCsr->pMIBuffer = 0;
|
||||
}
|
||||
|
||||
/* If Fts3Cursor.aMatchinfo[] is NULL, then this is the first time the
|
||||
/* If Fts3Cursor.pMIBuffer is NULL, then this is the first time the
|
||||
** matchinfo function has been called for this query. In this case
|
||||
** allocate the array used to accumulate the matchinfo data and
|
||||
** initialize those elements that are constant for every row.
|
||||
*/
|
||||
if( pCsr->aMatchinfo==0 ){
|
||||
if( pCsr->pMIBuffer==0 ){
|
||||
int nMatchinfo = 0; /* Number of u32 elements in match-info */
|
||||
int nArg; /* Bytes in zArg */
|
||||
int i; /* Used to iterate through zArg */
|
||||
|
||||
/* Determine the number of phrases in the query */
|
||||
@@ -1168,30 +1347,46 @@ static int fts3GetMatchinfo(
|
||||
|
||||
/* Determine the number of integers in the buffer returned by this call. */
|
||||
for(i=0; zArg[i]; i++){
|
||||
char *zErr = 0;
|
||||
if( fts3MatchinfoCheck(pTab, zArg[i], &zErr) ){
|
||||
sqlite3_result_error(pCtx, zErr, -1);
|
||||
sqlite3_free(zErr);
|
||||
return;
|
||||
}
|
||||
nMatchinfo += fts3MatchinfoSize(&sInfo, zArg[i]);
|
||||
}
|
||||
|
||||
/* Allocate space for Fts3Cursor.aMatchinfo[] and Fts3Cursor.zMatchinfo. */
|
||||
nArg = (int)strlen(zArg);
|
||||
pCsr->aMatchinfo = (u32 *)sqlite3_malloc(sizeof(u32)*nMatchinfo + nArg + 1);
|
||||
if( !pCsr->aMatchinfo ) return SQLITE_NOMEM;
|
||||
pCsr->pMIBuffer = fts3MIBufferNew(nMatchinfo, zArg);
|
||||
if( !pCsr->pMIBuffer ) rc = SQLITE_NOMEM;
|
||||
|
||||
pCsr->zMatchinfo = (char *)&pCsr->aMatchinfo[nMatchinfo];
|
||||
pCsr->nMatchinfo = nMatchinfo;
|
||||
memcpy(pCsr->zMatchinfo, zArg, nArg+1);
|
||||
memset(pCsr->aMatchinfo, 0, sizeof(u32)*nMatchinfo);
|
||||
pCsr->isMatchinfoNeeded = 1;
|
||||
bGlobal = 1;
|
||||
}
|
||||
|
||||
sInfo.aMatchinfo = pCsr->aMatchinfo;
|
||||
sInfo.nPhrase = pCsr->nPhrase;
|
||||
if( pCsr->isMatchinfoNeeded ){
|
||||
rc = fts3MatchinfoValues(pCsr, bGlobal, &sInfo, zArg);
|
||||
pCsr->isMatchinfoNeeded = 0;
|
||||
if( rc==SQLITE_OK ){
|
||||
xDestroyOut = fts3MIBufferAlloc(pCsr->pMIBuffer, &aOut);
|
||||
if( xDestroyOut==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
if( rc==SQLITE_OK ){
|
||||
sInfo.aMatchinfo = aOut;
|
||||
sInfo.nPhrase = pCsr->nPhrase;
|
||||
rc = fts3MatchinfoValues(pCsr, bGlobal, &sInfo, zArg);
|
||||
if( bGlobal ){
|
||||
fts3MIBufferSetGlobal(pCsr->pMIBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
if( rc!=SQLITE_OK ){
|
||||
sqlite3_result_error_code(pCtx, rc);
|
||||
if( xDestroyOut ) xDestroyOut(aOut);
|
||||
}else{
|
||||
int n = pCsr->pMIBuffer->nElem * sizeof(u32);
|
||||
sqlite3_result_blob(pCtx, aOut, n, xDestroyOut);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1397,7 +1592,7 @@ void sqlite3Fts3Offsets(
|
||||
*/
|
||||
sCtx.iCol = iCol;
|
||||
sCtx.iTerm = 0;
|
||||
(void)fts3ExprIterate(pCsr->pExpr, fts3ExprTermOffsetInit, (void *)&sCtx);
|
||||
(void)fts3ExprIterate(pCsr->pExpr, fts3ExprTermOffsetInit, (void*)&sCtx);
|
||||
|
||||
/* Retreive the text stored in column iCol. If an SQL NULL is stored
|
||||
** in column iCol, jump immediately to the next iteration of the loop.
|
||||
@@ -1489,19 +1684,9 @@ void sqlite3Fts3Matchinfo(
|
||||
const char *zArg /* Second arg to matchinfo() function */
|
||||
){
|
||||
Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
|
||||
int rc;
|
||||
int i;
|
||||
const char *zFormat;
|
||||
|
||||
if( zArg ){
|
||||
for(i=0; zArg[i]; i++){
|
||||
char *zErr = 0;
|
||||
if( fts3MatchinfoCheck(pTab, zArg[i], &zErr) ){
|
||||
sqlite3_result_error(pContext, zErr, -1);
|
||||
sqlite3_free(zErr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
zFormat = zArg;
|
||||
}else{
|
||||
zFormat = FTS3_MATCHINFO_DEFAULT;
|
||||
@@ -1510,17 +1695,10 @@ void sqlite3Fts3Matchinfo(
|
||||
if( !pCsr->pExpr ){
|
||||
sqlite3_result_blob(pContext, "", 0, SQLITE_STATIC);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Retrieve matchinfo() data. */
|
||||
rc = fts3GetMatchinfo(pCsr, zFormat);
|
||||
sqlite3Fts3SegmentsClose(pTab);
|
||||
|
||||
if( rc!=SQLITE_OK ){
|
||||
sqlite3_result_error_code(pContext, rc);
|
||||
}else{
|
||||
int n = pCsr->nMatchinfo * sizeof(u32);
|
||||
sqlite3_result_blob(pContext, pCsr->aMatchinfo, n, SQLITE_TRANSIENT);
|
||||
/* Retrieve matchinfo() data. */
|
||||
fts3GetMatchinfo(pContext, pCsr, zFormat);
|
||||
sqlite3Fts3SegmentsClose(pTab);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ static int fts3termConnectMethod(
|
||||
|
||||
/* The user should specify a single argument - the name of an fts3 table. */
|
||||
if( argc!=4 ){
|
||||
*pzErr = sqlite3_mprintf(
|
||||
sqlite3Fts3ErrMsg(pzErr,
|
||||
"wrong number of arguments to fts4term constructor"
|
||||
);
|
||||
return SQLITE_ERROR;
|
||||
|
||||
@@ -85,7 +85,7 @@ static int fts3tokQueryTokenizer(
|
||||
|
||||
p = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zName, nName+1);
|
||||
if( !p ){
|
||||
*pzErr = sqlite3_mprintf("unknown tokenizer: %s", zName);
|
||||
sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer: %s", zName);
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@@ -172,7 +172,7 @@ int sqlite3Fts3InitTokenizer(
|
||||
|
||||
m = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash,z,(int)strlen(z)+1);
|
||||
if( !m ){
|
||||
*pzErr = sqlite3_mprintf("unknown tokenizer: %s", z);
|
||||
sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer: %s", z);
|
||||
rc = SQLITE_ERROR;
|
||||
}else{
|
||||
char const **aArg = 0;
|
||||
@@ -195,7 +195,7 @@ int sqlite3Fts3InitTokenizer(
|
||||
rc = m->xCreate(iArg, aArg, ppTok);
|
||||
assert( rc!=SQLITE_OK || *ppTok );
|
||||
if( rc!=SQLITE_OK ){
|
||||
*pzErr = sqlite3_mprintf("unknown tokenizer");
|
||||
sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer");
|
||||
}else{
|
||||
(*ppTok)->pModule = m;
|
||||
}
|
||||
@@ -279,9 +279,9 @@ static void testFunc(
|
||||
p = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zName, nName+1);
|
||||
|
||||
if( !p ){
|
||||
char *zErr = sqlite3_mprintf("unknown tokenizer: %s", zName);
|
||||
sqlite3_result_error(context, zErr, -1);
|
||||
sqlite3_free(zErr);
|
||||
char *zErr2 = sqlite3_mprintf("unknown tokenizer: %s", zName);
|
||||
sqlite3_result_error(context, zErr2, -1);
|
||||
sqlite3_free(zErr2);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -326,7 +326,7 @@ static int fts3SqlStmt(
|
||||
/* 25 */ "",
|
||||
|
||||
/* 26 */ "DELETE FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?",
|
||||
/* 27 */ "SELECT DISTINCT level / (1024 * ?) FROM %Q.'%q_segdir'",
|
||||
/* 27 */ "SELECT ? UNION SELECT level / (1024 * ?) FROM %Q.'%q_segdir'",
|
||||
|
||||
/* This statement is used to determine which level to read the input from
|
||||
** when performing an incremental merge. It returns the absolute level number
|
||||
@@ -3444,7 +3444,8 @@ static int fts3DoOptimize(Fts3Table *p, int bReturnDone){
|
||||
rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
int rc2;
|
||||
sqlite3_bind_int(pAllLangid, 1, p->nIndex);
|
||||
sqlite3_bind_int(pAllLangid, 1, p->iPrevLangid);
|
||||
sqlite3_bind_int(pAllLangid, 2, p->nIndex);
|
||||
while( sqlite3_step(pAllLangid)==SQLITE_ROW ){
|
||||
int i;
|
||||
int iLangid = sqlite3_column_int(pAllLangid, 0);
|
||||
@@ -4776,7 +4777,7 @@ static int fts3IncrmergeHintPop(Blob *pHint, i64 *piAbsLevel, int *pnInput){
|
||||
pHint->n = i;
|
||||
i += sqlite3Fts3GetVarint(&pHint->a[i], piAbsLevel);
|
||||
i += fts3GetVarint32(&pHint->a[i], pnInput);
|
||||
if( i!=nHint ) return SQLITE_CORRUPT_VTAB;
|
||||
if( i!=nHint ) return FTS_CORRUPT_VTAB;
|
||||
|
||||
return SQLITE_OK;
|
||||
}
|
||||
@@ -5144,7 +5145,8 @@ static int fts3IntegrityCheck(Fts3Table *p, int *pbOk){
|
||||
rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
int rc2;
|
||||
sqlite3_bind_int(pAllLangid, 1, p->nIndex);
|
||||
sqlite3_bind_int(pAllLangid, 1, p->iPrevLangid);
|
||||
sqlite3_bind_int(pAllLangid, 2, p->nIndex);
|
||||
while( rc==SQLITE_OK && sqlite3_step(pAllLangid)==SQLITE_ROW ){
|
||||
int iLangid = sqlite3_column_int(pAllLangid, 0);
|
||||
int i;
|
||||
@@ -5157,7 +5159,6 @@ static int fts3IntegrityCheck(Fts3Table *p, int *pbOk){
|
||||
}
|
||||
|
||||
/* This block calculates the checksum according to the %_content table */
|
||||
rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3_tokenizer_module const *pModule = p->pTokenizer->pModule;
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
@@ -5254,7 +5255,7 @@ static int fts3DoIntegrityCheck(
|
||||
int rc;
|
||||
int bOk = 0;
|
||||
rc = fts3IntegrityCheck(p, &bOk);
|
||||
if( rc==SQLITE_OK && bOk==0 ) rc = SQLITE_CORRUPT_VTAB;
|
||||
if( rc==SQLITE_OK && bOk==0 ) rc = FTS_CORRUPT_VTAB;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -876,7 +876,7 @@ static fuzzer_stem *fuzzerNewStem(
|
||||
if( pNew==0 ) return 0;
|
||||
memset(pNew, 0, sizeof(*pNew));
|
||||
pNew->zBasis = (char*)&pNew[1];
|
||||
pNew->nBasis = (int)strlen(zWord);
|
||||
pNew->nBasis = (fuzzer_len)strlen(zWord);
|
||||
memcpy(pNew->zBasis, zWord, pNew->nBasis+1);
|
||||
pRule = pCur->pVtab->pRule;
|
||||
while( fuzzerSkipRule(pRule, pNew, pCur->iRuleset) ){
|
||||
|
||||
+12
-4
@@ -2820,11 +2820,19 @@ static int rtreeUpdate(
|
||||
if( nData>1 ){
|
||||
int ii;
|
||||
|
||||
/* Populate the cell.aCoord[] array. The first coordinate is azData[3]. */
|
||||
assert( nData==(pRtree->nDim*2 + 3) );
|
||||
/* Populate the cell.aCoord[] array. The first coordinate is azData[3].
|
||||
**
|
||||
** NB: nData can only be less than nDim*2+3 if the rtree is mis-declared
|
||||
** with "column" that are interpreted as table constraints.
|
||||
** Example: CREATE VIRTUAL TABLE bad USING rtree(x,y,CHECK(y>5));
|
||||
** This problem was discovered after years of use, so we silently ignore
|
||||
** these kinds of misdeclared tables to avoid breaking any legacy.
|
||||
*/
|
||||
assert( nData<=(pRtree->nDim*2 + 3) );
|
||||
|
||||
#ifndef SQLITE_RTREE_INT_ONLY
|
||||
if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
|
||||
for(ii=0; ii<(pRtree->nDim*2); ii+=2){
|
||||
for(ii=0; ii<nData-4; ii+=2){
|
||||
cell.aCoord[ii].f = rtreeValueDown(azData[ii+3]);
|
||||
cell.aCoord[ii+1].f = rtreeValueUp(azData[ii+4]);
|
||||
if( cell.aCoord[ii].f>cell.aCoord[ii+1].f ){
|
||||
@@ -2835,7 +2843,7 @@ static int rtreeUpdate(
|
||||
}else
|
||||
#endif
|
||||
{
|
||||
for(ii=0; ii<(pRtree->nDim*2); ii+=2){
|
||||
for(ii=0; ii<nData-4; ii+=2){
|
||||
cell.aCoord[ii].i = sqlite3_value_int(azData[ii+3]);
|
||||
cell.aCoord[ii+1].i = sqlite3_value_int(azData[ii+4]);
|
||||
if( cell.aCoord[ii].i>cell.aCoord[ii+1].i ){
|
||||
|
||||
@@ -87,7 +87,6 @@ do_catchsql_test rtree9-4.3 {
|
||||
#
|
||||
register_circle_geom db
|
||||
|
||||
breakpoint
|
||||
do_execsql_test rtree9-5.1 {
|
||||
CREATE VIRTUAL TABLE rt2 USING rtree(id, xmin, xmax, ymin, ymax);
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ TCCX += -I$(TOP)/ext/async -I$(TOP)/ext/userauth
|
||||
LIBOBJ+= vdbe.o parse.o \
|
||||
alter.o analyze.o attach.o auth.o \
|
||||
backup.o bitvec.o btmutex.o btree.o build.o \
|
||||
callback.o complete.o ctime.o date.o delete.o expr.o fault.o fkey.o \
|
||||
callback.o complete.o ctime.o date.o dbstat.o delete.o expr.o fault.o fkey.o \
|
||||
fts3.o fts3_aux.o fts3_expr.o fts3_hash.o fts3_icu.o fts3_porter.o \
|
||||
fts3_snippet.o fts3_tokenizer.o fts3_tokenizer1.o \
|
||||
fts3_tokenize_vtab.o \
|
||||
@@ -91,6 +91,7 @@ SRC = \
|
||||
$(TOP)/src/complete.c \
|
||||
$(TOP)/src/ctime.c \
|
||||
$(TOP)/src/date.c \
|
||||
$(TOP)/src/dbstat.c \
|
||||
$(TOP)/src/delete.c \
|
||||
$(TOP)/src/expr.c \
|
||||
$(TOP)/src/fault.c \
|
||||
@@ -270,7 +271,6 @@ TESTSRC = \
|
||||
$(TOP)/src/test_rtree.c \
|
||||
$(TOP)/src/test_schema.c \
|
||||
$(TOP)/src/test_server.c \
|
||||
$(TOP)/src/test_stat.c \
|
||||
$(TOP)/src/test_sqllog.c \
|
||||
$(TOP)/src/test_superlock.c \
|
||||
$(TOP)/src/test_syscall.c \
|
||||
@@ -306,6 +306,7 @@ TESTSRC2 = \
|
||||
$(TOP)/src/btree.c \
|
||||
$(TOP)/src/build.c \
|
||||
$(TOP)/src/date.c \
|
||||
$(TOP)/src/dbstat.c \
|
||||
$(TOP)/src/expr.c \
|
||||
$(TOP)/src/func.c \
|
||||
$(TOP)/src/insert.c \
|
||||
@@ -390,6 +391,14 @@ EXTHDR += \
|
||||
EXTHDR += \
|
||||
$(TOP)/ext/userauth/sqlite3userauth.h
|
||||
|
||||
# executables needed for testing
|
||||
#
|
||||
TESTPROGS = \
|
||||
testfixture$(EXE) \
|
||||
sqlite3$(EXE) \
|
||||
sqlite3_analyzer$(EXE) \
|
||||
sqldiff$(EXE)
|
||||
|
||||
# This is the default Makefile target. The objects listed here
|
||||
# are what get build when you type just "make" with no arguments.
|
||||
#
|
||||
@@ -408,6 +417,10 @@ sqldiff$(EXE): $(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h
|
||||
$(TCCX) -o sqldiff$(EXE) -DSQLITE_THREADSAFE=0 \
|
||||
$(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS) $(THREADLIB)
|
||||
|
||||
fuzzershell$(EXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h
|
||||
$(TCCX) -o fuzzershell$(EXE) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION\
|
||||
$(TOP)/tool/fuzzershell.c sqlite3.c $(TLIBS) $(THREADLIB)
|
||||
|
||||
mptester$(EXE): sqlite3.c $(TOP)/mptest/mptest.c
|
||||
$(TCCX) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \
|
||||
$(TLIBS) $(THREADLIB)
|
||||
@@ -597,9 +610,10 @@ tclsqlite3: $(TOP)/src/tclsqlite.c libsqlite3.a
|
||||
$(TCCX) $(TCL_FLAGS) -DTCLSH=1 -o tclsqlite3 \
|
||||
$(TOP)/src/tclsqlite.c libsqlite3.a $(LIBTCL) $(THREADLIB)
|
||||
|
||||
sqlite3_analyzer.c: sqlite3.c $(TOP)/src/test_stat.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl
|
||||
sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl
|
||||
echo "#define TCLSH 2" > $@
|
||||
cat sqlite3.c $(TOP)/src/test_stat.c $(TOP)/src/tclsqlite.c >> $@
|
||||
echo "#define SQLITE_ENABLE_DBSTAT_VTAB 1" >> $@
|
||||
cat sqlite3.c $(TOP)/src/tclsqlite.c >> $@
|
||||
echo "static const char *tclsh_main_loop(void){" >> $@
|
||||
echo "static const char *zMainloop = " >> $@
|
||||
$(NAWK) -f $(TOP)/tool/tostr.awk $(TOP)/tool/spaceanal.tcl >> $@
|
||||
@@ -629,21 +643,41 @@ fts3-testfixture$(EXE): sqlite3.c fts3amal.c $(TESTSRC) $(TOP)/src/tclsqlite.c
|
||||
$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c fts3amal.c \
|
||||
-o testfixture$(EXE) $(LIBTCL) $(THREADLIB)
|
||||
|
||||
fulltest: testfixture$(EXE) sqlite3$(EXE)
|
||||
fulltest: $(TESTPROGS) fuzztest
|
||||
./testfixture$(EXE) $(TOP)/test/all.test
|
||||
|
||||
soaktest: testfixture$(EXE) sqlite3$(EXE)
|
||||
soaktest: $(TESTPROGS) fuzzoomtest
|
||||
./testfixture$(EXE) $(TOP)/test/all.test -soak=1
|
||||
|
||||
fulltestonly: testfixture$(EXE) sqlite3$(EXE)
|
||||
fulltestonly: $(TESTPROGS) fuzztest
|
||||
./testfixture$(EXE) $(TOP)/test/full.test
|
||||
|
||||
queryplantest: testfixture$(EXE) sqlite3$(EXE)
|
||||
./testfixture$(EXE) $(TOP)/test/permutations.test queryplanner
|
||||
|
||||
test: testfixture$(EXE) sqlite3$(EXE)
|
||||
fuzztest: fuzzershell$(EXE)
|
||||
./fuzzershell$(EXE) $(TOP)/test/fuzzdata1.txt $(TOP)/test/fuzzdata2.txt
|
||||
|
||||
fuzzoomtest: fuzzershell$(EXE)
|
||||
./fuzzershell$(EXE) -f $(TOP)/test/fuzzdata1.txt --oom
|
||||
|
||||
test: $(TESTPROGS) fuzztest
|
||||
./testfixture$(EXE) $(TOP)/test/veryquick.test
|
||||
|
||||
# Run a test using valgrind. This can take a really long time
|
||||
# because valgrind is so much slower than a native machine.
|
||||
#
|
||||
valgrindtest: $(TESTPROGS) fuzzershell$(EXE)
|
||||
valgrind -v ./fuzzershell$(EXE) -f $(TOP)/test/fuzzdata1.txt
|
||||
OMIT_MISUSE=1 valgrind -v ./testfixture$(EXE) $(TOP)/test/permutations.test valgrind
|
||||
|
||||
# A very fast test that checks basic sanity. The name comes from
|
||||
# the 60s-era electronics testing: "Turn it on and see if smoke
|
||||
# comes out."
|
||||
#
|
||||
smoketest: $(TESTPROGS) fuzzershell$(EXE)
|
||||
./testfixture$(EXE) $(TOP)/test/main.test
|
||||
|
||||
# The next two rules are used to support the "threadtest" target. Building
|
||||
# threadtest runs a few thread-safety tests that are implemented in C. This
|
||||
# target is invoked by the releasetest.tcl script.
|
||||
@@ -750,3 +784,5 @@ clean:
|
||||
rm -f sqlite3_analyzer sqlite3_analyzer.exe sqlite3_analyzer.c
|
||||
rm -f sqlite-*-output.vsix
|
||||
rm -f mptester mptester.exe
|
||||
rm -f fuzzershell fuzzershell.exe
|
||||
rm -f sqldiff sqldiff.exe
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
C Revise\swhen\sthe\ssqlite3ErrName()\sfunction\sis\sdefined.
|
||||
D 2015-04-28T23:34:10.625
|
||||
C Merge\supdates\sfrom\strunk.
|
||||
D 2015-05-13T04:52:26.726
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in 5f78b1ab81b64e7c57a75d170832443e66c0880a
|
||||
F Makefile.in edfc69769e613a6359c42c06ea1d42c3bece1736
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
F Makefile.msc 29e11e91c4abf13c522b983552fac18422519321
|
||||
F Makefile.msc a9fd7fd02265aa5b3b2522f5e39d975972ff906d
|
||||
F Makefile.vxworks e1b65dea203f054e71653415bd8f96dcaed47858
|
||||
F README.md d58e3bebc0a4145e0f2a87994015fdb575a8e866
|
||||
F VERSION 2e244662b71e6e68a5c29b014ebc5b7564f4cc5a
|
||||
F VERSION 8af05c43e00f7de32be74ff9984d792c96cdb0de
|
||||
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
||||
F addopcodes.awk 9eb448a552d5c0185cf62c463f9c173cedae3811
|
||||
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
|
||||
F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
|
||||
F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
|
||||
F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903
|
||||
F autoconf/Makefile.am 8fc2972d92769cf20ab8e4a73ea901b84d69bf44
|
||||
F autoconf/Makefile.am 27de1af382c82e81f1fe36a7f38528fba004eb1a
|
||||
F autoconf/README 14458f1046c118efa721aadec5f227e876d3cd38
|
||||
F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7
|
||||
F autoconf/config.guess 94cc57e2a3fdb9c235b362ace86d77e89d188cad x
|
||||
@@ -38,7 +38,7 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
|
||||
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
|
||||
F config.h.in 42b71ad3fe21c9e88fa59e8458ca1a6bc72eb0c0
|
||||
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
|
||||
F configure 2ea5f5b58dd106da449ab598ab6e515339d7fa2a x
|
||||
F configure dae9f0ec4df32a9e300befbcdbc4ff8874731357 x
|
||||
F configure.ac 0b775d383c536bbaafc1e46dd3cbb81a7ea11aeb
|
||||
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
||||
F doc/lemon.html 334dbf6621b8fb8790297ec1abf3cfa4621709d1
|
||||
@@ -78,25 +78,25 @@ F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51
|
||||
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
|
||||
F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314
|
||||
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
|
||||
F ext/fts3/fts3.c 4bd75289875b63c04f943d6ed7c31737da99cd74
|
||||
F ext/fts3/fts3.c 341e9d9a3c7615bac8e815a8937d576265b22f78
|
||||
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
|
||||
F ext/fts3/fts3Int.h 3626655d6ba903a3919bb44e1c38e5f0f9d6be82
|
||||
F ext/fts3/fts3_aux.c 5c211e17a64885faeb16b9ba7772f9d5445c2365
|
||||
F ext/fts3/fts3_expr.c 40123785eaa3ebd4c45c9b23407cc44ac0c49905
|
||||
F ext/fts3/fts3Int.h 142837a7544dff49121b67091a71c4f7a4546b0f
|
||||
F ext/fts3/fts3_aux.c 9edc3655fcb287f0467d0a4b886a01c6185fe9f1
|
||||
F ext/fts3/fts3_expr.c 71c063da9c2a4167fb54aec089dd5ef33a58c9cb
|
||||
F ext/fts3/fts3_hash.c 29b986e43f4e9dd40110eafa377dc0d63c422c60
|
||||
F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf
|
||||
F ext/fts3/fts3_icu.c e319e108661147bcca8dd511cd562f33a1ba81b5
|
||||
F ext/fts3/fts3_porter.c 3565faf04b626cddf85f03825e86056a4562c009
|
||||
F ext/fts3/fts3_snippet.c 52c2dcf410b1f9af5a44d81a2cf8c68ed1cb5283
|
||||
F ext/fts3/fts3_term.c a521f75132f9a495bdca1bdd45949b3191c52763
|
||||
F ext/fts3/fts3_snippet.c b7aaa8698096b26e1c6eb563e317409323398142
|
||||
F ext/fts3/fts3_term.c 88c55a6fa1a51ab494e33dced0401a6c28791fd7
|
||||
F ext/fts3/fts3_test.c 8a3a78c4458b2d7c631fcf4b152a5cd656fa7038
|
||||
F ext/fts3/fts3_tokenize_vtab.c becc661223db7898b213f9e8a23d75bac02408c9
|
||||
F ext/fts3/fts3_tokenizer.c b7e586baeb8d0a061cf01a0f7081d88f3935eecf
|
||||
F ext/fts3/fts3_tokenize_vtab.c a27593ab19657166f6fa5ec073b678cc29a75860
|
||||
F ext/fts3/fts3_tokenizer.c 50e7a69a549ac5882cc1971ee43f66aaabc11395
|
||||
F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3
|
||||
F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004
|
||||
F ext/fts3/fts3_unicode.c a93f5edc0aff44ef8b06d7cb55b52026541ca145
|
||||
F ext/fts3/fts3_unicode2.c c3d01968d497bd7001e7dc774ba75b372738c057
|
||||
F ext/fts3/fts3_write.c 7104ec015474ee61a8a570349b925f35c6b0a294
|
||||
F ext/fts3/fts3_write.c 4f005f78592a1447ca96c8475ef5342ab7dbe02a
|
||||
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
|
||||
F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
|
||||
F ext/fts3/tool/fts3view.c 8e53d0190a7b3443764bbd32ad47be2bd852026d
|
||||
@@ -111,7 +111,7 @@ F ext/misc/closure.c 636024302cde41b2bf0c542f81c40c624cfb7012
|
||||
F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83
|
||||
F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2
|
||||
F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f
|
||||
F ext/misc/fuzzer.c e3e18f47252c151b5553d7e806f38e757d37c4cc
|
||||
F ext/misc/fuzzer.c 4c84635c71c26cfa7c2e5848cf49fe2d2cfcd767
|
||||
F ext/misc/ieee754.c b0362167289170627659e84173f5d2e8fee8566e
|
||||
F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342
|
||||
F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63
|
||||
@@ -124,7 +124,7 @@ F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95
|
||||
F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e
|
||||
F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212
|
||||
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
|
||||
F ext/rtree/rtree.c 14e6239434d4e3f65d3e90320713f26aa24e167f
|
||||
F ext/rtree/rtree.c 0c207fd8b814a35537d96681cbf57436e200b75e
|
||||
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
|
||||
F ext/rtree/rtree1.test 541bbcab74613907fea08b2ecdcdd5b7aa724cc9
|
||||
F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba
|
||||
@@ -134,7 +134,7 @@ F ext/rtree/rtree5.test 6a510494f12454bf57ef28f45bc7764ea279431e
|
||||
F ext/rtree/rtree6.test 773a90db2dce6a8353dd0d5b64bca69b29761196
|
||||
F ext/rtree/rtree7.test 1fa710b9e6bf997a0c1a537b81be7bb6fded1971
|
||||
F ext/rtree/rtree8.test db79c812f9e4a11f9b1f3f9934007884610a713a
|
||||
F ext/rtree/rtree9.test d86ebf08ff6328895613ed577dd8a2a37c472c34
|
||||
F ext/rtree/rtree9.test b5eb13849545dfd271a54ff16784cb00d8792aea
|
||||
F ext/rtree/rtreeA.test ace05e729a36e342d40cf94e9efc7b4723d9dcdf
|
||||
F ext/rtree/rtreeB.test c85f9ce78766c4e68b8b89fbf2979ee9cfa82b4e
|
||||
F ext/rtree/rtreeC.test df158dcc81f1a43ce7eef361af03c48ec91f1e06
|
||||
@@ -152,7 +152,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e
|
||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
|
||||
F main.mk ddffac494a82d42772df9fe30d3a78acf4f7cb41
|
||||
F main.mk d49723483ee9e4fb71dc2bd0e6be58705a481e73
|
||||
F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea
|
||||
F mkopcodeh.awk d5e22023b5238985bb54a72d33e0ac71fe4f8a32
|
||||
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
|
||||
@@ -166,37 +166,38 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
|
||||
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
|
||||
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
|
||||
F src/alter.c d23d6b6991f66b383934f137fd4384d93fb98c81
|
||||
F src/analyze.c 91540f835163d5369ccbae78e2e6c74d0dd53c1d
|
||||
F src/attach.c 3c1053a4cf1c3ca05c8c1d74a94cb688d763cef2
|
||||
F src/alter.c 8f6dc4a6ddc1ebc0ed5cc470c4e57ff0d1605e90
|
||||
F src/analyze.c d23790787f80ebed58df7774744b4cf96401498b
|
||||
F src/attach.c c38ac5a520a231d5d0308fd7f2ad95191c867bae
|
||||
F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
|
||||
F src/backup.c ff743689c4d6c5cb55ad42ed9d174b2b3e71f1e3
|
||||
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
|
||||
F src/bitvec.c 5eb7958c3bf65210211cbcfc44eff86d0ded7c9d
|
||||
F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
|
||||
F src/btree.c c6e32d84442f79d5b96965265d65b3baa231dffc
|
||||
F src/btree.c 30a80340481098d699398cba3536c895373b2e2c
|
||||
F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1
|
||||
F src/btreeInt.h 973a22a6fd61350b454ad614832b1f0a5e25a1e4
|
||||
F src/build.c 01b969b20a44a3d9620e597d9af8242348123540
|
||||
F src/build.c 61b47073f79f31e80a05db9ce13c5ca81bf8f74e
|
||||
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
|
||||
F src/complete.c a5cf5b4b56390cfb7b8636e8f7ddef90258dd575
|
||||
F src/ctime.c 98f89724adc891a1a4c655bee04e33e716e05887
|
||||
F src/ctime.c 5a0b735dc95604766f5dac73973658eef782ee8b
|
||||
F src/date.c e4d50b3283696836ec1036b695ead9a19e37a5ac
|
||||
F src/dbstat.c f402e77e25089c6003d0c60b3233b9b3947d599a
|
||||
F src/delete.c 37964e6c1d73ff49cbea9ff690c9605fb15f600e
|
||||
F src/expr.c 8800584340a9b4f4c0ca55c360de751c6da0b11a
|
||||
F src/expr.c 3fb2ab3ab69d15b4b75ae53fceb4e317f64cb306
|
||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||
F src/fkey.c 3343d551a8d810782257244fb33f2ce191493c39
|
||||
F src/func.c 1414c24c873c48796ad45942257a179a423ba42f
|
||||
F src/fkey.c c9b63a217d86582c22121699a47f22f524608869
|
||||
F src/func.c 5b8b8e77a0fb644eaf8947d413804622e32692b6
|
||||
F src/global.c 4f77cadbc5427d00139ba43d0f3979804cbb700e
|
||||
F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
|
||||
F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
|
||||
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
|
||||
F src/insert.c 305dd3f9539d0affa4bf1c14cc7dffb34867e040
|
||||
F src/insert.c 8176ba5bad8fcef643558ca5708f33ed05a4035a
|
||||
F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
|
||||
F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e
|
||||
F src/lempar.c 7274c97d24bb46631e504332ccd3bd1b37841770
|
||||
F src/loadext.c 86bd4e2fccd520b748cba52492ab60c4a770f660
|
||||
F src/main.c 6dc030204d80be177578210a90c912e1d9597126
|
||||
F src/malloc.c 6a370b83d54e4bbf6f94021221c2a311cff26a18
|
||||
F src/loadext.c 29255bbe1cfb2ce9bbff2526a5ecfddcb49b9271
|
||||
F src/main.c bd2c1bb33f9d01576a028c4c21d5beba86ee316c
|
||||
F src/malloc.c 5bc15d525811d387b37c29f2e368143460e41e96
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c abe6ee469b6c5a35c7f22bfeb9c9bac664a1c987
|
||||
F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
|
||||
@@ -214,33 +215,33 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8
|
||||
F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf
|
||||
F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e
|
||||
F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
|
||||
F src/os_unix.c cf45d7b1cd27341ba8699e62c4902062b6297039
|
||||
F src/os_win.c c2f0b0b3541906e310588b9e95080df4df75b674
|
||||
F src/os_unix.c 23eb5f56fac54d8fe0cb204291f3b3b2d94f23fc
|
||||
F src/os_win.c 97f7828a9554d753665b6fcf7540e31c2b3d6a6e
|
||||
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
|
||||
F src/pager.c 4120a49ecd37697e28f5ed807f470b9c0b88410c
|
||||
F src/pager.c 97110085b1321298412f1e5c37bddb95b36d9208
|
||||
F src/pager.h c3476e7c89cdf1c6914e50a11f3714e30b4e0a77
|
||||
F src/parse.y 1299c66e7b1707322ccd8af43a359b8fb0d46d72
|
||||
F src/parse.y c4e0387bc88c8e21e5ba653e2578959a1f3cdbc7
|
||||
F src/pcache.c 10539fb959849ad6efff80050541cab3d25089d4
|
||||
F src/pcache.h b44658c9c932d203510279439d891a2a83e12ba8
|
||||
F src/pcache1.c 69d137620a305f814398bd29a0c998038c0695e9
|
||||
F src/pragma.c 3965ae4e82bed39fb97ce04c5fe18c9bc3ee6a88
|
||||
F src/pragma.c c1f4d012ea9f6b1ce52d341b2cd0ad72d560afd7
|
||||
F src/pragma.h 09c89bca58e9a44de2116cc8272b8d454657129f
|
||||
F src/prepare.c 1fffbdcd6f8a0173a8f70d71f22528f4c0e1e3d3
|
||||
F src/printf.c 18df0da8c343dc4380f27a803858f2a4b81f1824
|
||||
F src/printf.c 54dd6dce95454fadffa3ebf7717c5f6c06250d1d
|
||||
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
||||
F src/resolve.c 66cfe49a9c3b449ef13b89a8c47036a4ed167eab
|
||||
F src/resolve.c 99eabf7eff0bfa65b75939b46caa82e2b2133f28
|
||||
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
|
||||
F src/select.c 93260bc9e7e0e6dfe1b7cb8815b0ed4cad8be9e3
|
||||
F src/shell.c 72b61a9d41ba12b67ea06fe9267abcc012c6c5bb
|
||||
F src/sqlite.h.in ca27603a36fcacdaac5a19d8ee35aaff8ce8516f
|
||||
F src/select.c 1b0bfc7d59e48c26b895a6b719157111a617d9e3
|
||||
F src/shell.c 07dda7cd692911d2f22269953418d049f2e2c0ee
|
||||
F src/sqlite.h.in 87908d43d02f8b813b151e3586da22f2a6fa12ed
|
||||
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
||||
F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
|
||||
F src/sqliteInt.h 5a4e0ae0ce02acb1cadb783abd70af800f538cba
|
||||
F src/sqliteInt.h 51bf2dcd742399257fdc6409cae1c84bf66900f2
|
||||
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
|
||||
F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179
|
||||
F src/table.c e7a09215315a978057fb42c640f890160dbcc45e
|
||||
F src/tclsqlite.c fa72a7c5278662357c105ba7925c1d0972506ff9
|
||||
F src/test1.c 90fbedce75330d48d99eadb7d5f4223e86969585
|
||||
F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
|
||||
F src/tclsqlite.c 9111a95999edac92229c972e2c34fbc171bbb6c5
|
||||
F src/test1.c a8e09b811f70184ce65012f27f30cfee7e54f268
|
||||
F src/test2.c 577961fe48961b2f2e5c8b56ee50c3f459d3359d
|
||||
F src/test3.c 64d2afdd68feac1bb5e2ffb8226c8c639f798622
|
||||
F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e
|
||||
@@ -252,7 +253,7 @@ 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_blob.c 1f2e3e25255b731c4fcf15ee7990d06347cb6c09
|
||||
F src/test_blob.c e5a7a81d61a780da79101aeb1e60d300af169e07
|
||||
F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f
|
||||
F src/test_config.c c2d3ff6c129d50183900c7eff14158ff7e9b3f03
|
||||
F src/test_demovfs.c 0de72c2c89551629f58486fde5734b7d90758852
|
||||
@@ -261,16 +262,16 @@ F src/test_fs.c ced436e3d4b8e4681328409b8081051ce614e28f
|
||||
F src/test_func.c f1ac201465472e76a73e2f3695c3553c63e7322a
|
||||
F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd
|
||||
F src/test_init.c 66b33120ffe9cd853b5a905ec850d51151337b32
|
||||
F src/test_intarray.c 6c610a21ab8edde85a3a2c7f2b069244ecf4d834
|
||||
F src/test_intarray.c 870124b95ec4c645d4eb84f15efb7133528fb1a5
|
||||
F src/test_intarray.h 9dc57417fb65bc7835cc18548852cc08cc062202
|
||||
F src/test_journal.c 5360fbe1d1e4416ca36290562fd5a2e3f70f32aa
|
||||
F src/test_loadext.c a5251f956ab6af21e138dc1f9c0399394a510cb4
|
||||
F src/test_malloc.c b9495384e74923aefde8311de974bf9b0f5ba570
|
||||
F src/test_multiplex.c 97813565daa7ee480abcc5dd1e9984ed1f71eb8c
|
||||
F src/test_malloc.c 208f09a4e21defa496bc1094fcfadea19385a112
|
||||
F src/test_multiplex.c 9fefd23f6cc3fa9bf0748a5e453167e7b9f193ce
|
||||
F src/test_multiplex.h c08e4e8f8651f0c5e0509b138ff4d5b43ed1f5d3
|
||||
F src/test_mutex.c 293042d623ebba969160f471a82aa1551626454f
|
||||
F src/test_onefile.c 0396f220561f3b4eedc450cef26d40c593c69a25
|
||||
F src/test_osinst.c 3d0340bc31a9f3d8a3547e0272373e80f78dde25
|
||||
F src/test_onefile.c 38f7cbe79d5bafe95bde683cc3a53b8ca16daf10
|
||||
F src/test_osinst.c 5423dc1d355f594371f27dd292ca54bd320b8196
|
||||
F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00
|
||||
F src/test_quota.c 180813f43683be5725458fc1ff13ac455d8e722d
|
||||
F src/test_quota.h 2a8ad1952d1d2ca9af0ce0465e56e6c023b5e15d
|
||||
@@ -278,50 +279,49 @@ F src/test_rtree.c bfe6f4386517f70054311109f3528adffec34485
|
||||
F src/test_schema.c 2bdba21b82f601da69793e1f1d11bf481a79b091
|
||||
F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe
|
||||
F src/test_sqllog.c b690c12933f50ff46491e0d56a251f84ae16e914
|
||||
F src/test_stat.c ffc8177f6e69de32a8a89fa6bca73facb6c5face
|
||||
F src/test_superlock.c 06797157176eb7085027d9dd278c0d7a105e3ec9
|
||||
F src/test_syscall.c 2e21ca7f7dc54a028f1967b63f1e76155c356f9b
|
||||
F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa
|
||||
F src/test_thread.c af391ec03d23486dffbcc250b7e58e073f172af9
|
||||
F src/test_vfs.c b7e6831e6fcf04c5090accff30640ec5c9630739
|
||||
F src/test_vfs.c 3b65d42e18b262805716bd96178c81da8f2d9283
|
||||
F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698
|
||||
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||
F src/threads.c 6bbcc9fe50c917864d48287b4792d46d6e873481
|
||||
F src/tokenize.c a8234a67577308935cdf13e618cd66556f5f45d1
|
||||
F src/trigger.c 69a91bed7c94e46223e37ffccfeeb35e34b999ac
|
||||
F src/tokenize.c b15511a2396641792f386ceb440d1d922972a78e
|
||||
F src/trigger.c 322f23aad694e8f31d384dcfa386d52a48d3c52f
|
||||
F src/update.c 3c4ecc282accf12d39edb8d524cf089645e55a13
|
||||
F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
|
||||
F src/util.c 98a7627ca48ad3265b6940915a1d08355eb3fc7e
|
||||
F src/util.c bb07b2e79e2dff45384b056274b556ecc3d016c9
|
||||
F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
|
||||
F src/vdbe.c 3f3afd12d4794cb51fe13dc948b1172a5eb71a94
|
||||
F src/vdbe.c d437887d02d13d79dc69ac018f788aefac3b3972
|
||||
F src/vdbe.h 7e538ecf47dccb307ea2d087c3ddc2dd8d70e79d
|
||||
F src/vdbeInt.h 9cbaa84f53ddd2d09a0cf61a94337a3a035d08a0
|
||||
F src/vdbeapi.c 583d56b129dd27f12bed518270de9ebe521e6a75
|
||||
F src/vdbeaux.c a20504ae52392459fa08402fda3f195f19d7c79d
|
||||
F src/vdbeaux.c 03591cca98ec50e1493043f0ff7abbece0b9c83d
|
||||
F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90
|
||||
F src/vdbemem.c c0dc81285b7571b0a31c40f17846fe2397ec1cd9
|
||||
F src/vdbesort.c 2e7f683464fd5db3be4beaa1ff2d39e24fcb64b8
|
||||
F src/vdbetrace.c 7e4222955e07dd707a2f360c0eb73452be1cb010
|
||||
F src/vtab.c 9ca557215e8591ceb66e0b7c0a579c6df1e54b2d
|
||||
F src/vdbemem.c 7bfbeef0978a2e1a05d979641fdbf7c189b7ddf4
|
||||
F src/vdbesort.c f5009e7a35e3065635d8918b9a31f498a499976b
|
||||
F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0
|
||||
F src/vtab.c c535e80259ebe616467181a83a4263555b97c694
|
||||
F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
|
||||
F src/wal.c 753995db83247f20361a8e8a874990b21a75abd9
|
||||
F src/wal.c ce2cb2d06faab54d1bce3e739bec79e063dd9113
|
||||
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
||||
F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804
|
||||
F src/where.c 8ba8ff31dc9bf1b69fe771d35d8764d5a1efd310
|
||||
F src/where.c 85fff9c40569ccb79c3177419b339e7d7df566cb
|
||||
F src/whereInt.h cbe4aa57326998d89e7698ca65bb7c28541d483c
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
F test/aggnested.test b35b4cd69fc913f90d39a575e171e1116c3a4bb7
|
||||
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
|
||||
F test/all.test 6ff7b43c2b4b905c74dc4a813d201d0fa64c5783
|
||||
F test/alter.test 547dc2d292644301ac9a7dda22b319b74f9c08d2
|
||||
F test/alter.test 2facdddf08d0d48e75dc6cc312cd2b030f4835dd
|
||||
F test/alter2.test 7ea05c7d92ac99349a802ef7ada17294dd647060
|
||||
F test/alter3.test 49c9d9fba2b8fcdce2dedeca97bbf1f369cc548d
|
||||
F test/alter4.test c461150723ac957f3b2214aa0b11552cd72023ec
|
||||
F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc
|
||||
F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
|
||||
F test/analyze.test 3eb35a4af972f98422e5dc0586501b17d103d321
|
||||
F test/analyze3.test 75b9e42ea1e4edc919250450dc5762186965d4e6
|
||||
F test/analyze3.test 0f0ee6135b293a0e5af471a8423b80b688469d71
|
||||
F test/analyze4.test eff2df19b8dd84529966420f29ea52edc6b56213
|
||||
F test/analyze5.test 765c4e284aa69ca172772aa940946f55629bc8c4
|
||||
F test/analyze6.test f1c552ce39cca4ec922a7e4e0e5d0203d6b3281f
|
||||
@@ -334,6 +334,7 @@ F test/analyzeC.test 555a6cc388b9818b6eda6df816f01ce0a75d3a93
|
||||
F test/analyzeD.test 08f9d0bee4e118a66fff3a32d02dbe0ee0a2b594
|
||||
F test/analyzeE.test 8684e8ac5722fb97c251887ad97e5d496a98af1d
|
||||
F test/analyzeF.test 7ccd7a04f7d3061bde1a8a4dacc4792edccf6bf2
|
||||
F test/analyzer1.test e3bccac3be49382050464952998a631bf51e3ce1
|
||||
F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b
|
||||
F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b
|
||||
F test/async3.test d73a062002376d7edc1fe3edff493edbec1fc2f7
|
||||
@@ -426,7 +427,7 @@ F test/corrupt8.test 2399dfe40d2c0c63af86706e30f3e6302a8d0516
|
||||
F test/corrupt9.test 730a3db08d4ab9aa43392ea30d9c2b4879cbff85
|
||||
F test/corruptA.test 53e56dafd180addcdadb402244b8cb9771d2ba26
|
||||
F test/corruptB.test 73a8d6c0b9833697ecf16b63e3c5c05c945b5dec
|
||||
F test/corruptC.test 02405cf7ed0c1e989060e1aab6d02ffbc3906fbb
|
||||
F test/corruptC.test 3fcc0f73d2cf2d69befe2d96332b942426a6aae2
|
||||
F test/corruptD.test b3c205fac7952b1de645ce44bb02335cd9e3e040
|
||||
F test/corruptE.test 193b4ca4e927e77c1d5f4f56203ddc998432a7ee
|
||||
F test/corruptF.test be9fde98e4c93648f1ba52b74e5318edc8f59fe4
|
||||
@@ -435,7 +436,7 @@ F test/corruptH.test 5dd4fa98c6c1ed33b178f9e8a48c4fdd3cfc9067
|
||||
F test/corruptI.test 221ad8b7f0a9ac6b80fc577e73b5ad8cdea31243
|
||||
F test/corruptJ.test 9e29e7a81ee3b6ac50f77ea7a9e2f3fa03f32d91
|
||||
F test/cost.test 19d314526616ce4473eb4e4e450fcb94499ce318
|
||||
F test/count.test 42a251178e32f617eda33f76236a7f79825a50b5
|
||||
F test/count.test cb2e0f934c6eb33670044520748d2ecccd46259c
|
||||
F test/coveridxscan.test cdb47d01acc4a634a34fd25abe85189e0d0f1e62
|
||||
F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f
|
||||
F test/crash2.test 5b14d4eb58b880e231361d3b609b216acda86651
|
||||
@@ -476,7 +477,7 @@ F test/e_expr.test 8f5fdd7261e2d746813b0c6a1c0e34824ad3c5ad
|
||||
F test/e_fkey.test a1783fe1f759e1990e6a11adfcf0702dac4d0707
|
||||
F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459
|
||||
F test/e_insert.test 0e63edc037afe738bb81a626a676811ed7862c90
|
||||
F test/e_reindex.test 396b7b4f0a66863b4e95116a67d93b227193e589
|
||||
F test/e_reindex.test 57d439f6c644befc8274ac93cf2f5449cf2736c1
|
||||
F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6
|
||||
F test/e_select.test 52692ff3849541e828ad4661fe3773a9b8711763
|
||||
F test/e_select2.test aceb80ab927d46fba5ce7586ebabf23e2bb0604f
|
||||
@@ -499,13 +500,13 @@ F test/exclusive.test c7ebbc756eacf544c108b15eed64d7d4e5f86b75
|
||||
F test/exclusive2.test 32798111aae78a5deec980eee383213f189df308
|
||||
F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
|
||||
F test/exists.test 8f7b27b61c2fbe5822f0a1f899c715d14e416e30
|
||||
F test/expr.test c4b9bf0cc60b26862475e19999fbd2609ca8259c
|
||||
F test/expr.test 79c3e7502d9e571553b85f0ecc8ff2ac7d0e4931
|
||||
F test/extension01.test 00d13cec817f331a687a243e0e5a2d87b0e358c9
|
||||
F test/fallocate.test 3e979af17dfa7e5e9dda5eba1a696c04fa9d47f7
|
||||
F test/filectrl.test 14fa712e42c4cb791e09dfd58a6a03efb47ef13a
|
||||
F test/filefmt.test cb34663f126cbc2d358af552dcaf5c72769b0146
|
||||
F test/fkey1.test e1d1fa84cde579185ea01358436839703e415a5b
|
||||
F test/fkey2.test 223c624e7eccee21e89c98d4d127ac88d774b940
|
||||
F test/fkey1.test de5b287f6a480b36bd51e8debcf48168e26e4ed2
|
||||
F test/fkey2.test f3d27ecba480a348c328965d154214719bb158a9
|
||||
F test/fkey3.test 76d475c80b84ee7a5d062e56ccb6ea68882e2b49
|
||||
F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d
|
||||
F test/fkey5.test 56bcb5a6e8b725b17febc267fb041a6695e86853
|
||||
@@ -551,7 +552,7 @@ F test/fts2r.test b154c30b63061d8725e320fba1a39e2201cadd5e
|
||||
F test/fts2token.test d8070b241a15ff13592a9ae4a8b7c171af6f445a
|
||||
F test/fts3.test 672a040ea57036fb4b6fdc09027c18d7d24ab654
|
||||
F test/fts3_common.tcl 99cf6659b87c0f74f55963c2aea03b3a7d66ceb0
|
||||
F test/fts3aa.test edd20ddbbc5b6015ab340abf2ca278ae11ec387d
|
||||
F test/fts3aa.test 6c263a6f8845205ee02550981a94c2e8dc1e7058
|
||||
F test/fts3ab.test 7f6cf260ae80dda064023df8e8e503e9a412b91f
|
||||
F test/fts3ac.test 636ed7486043055d4f126a0e385f2d5a82ebbf63
|
||||
F test/fts3ad.test e40570cb6f74f059129ad48bcef3d7cbc20dda49
|
||||
@@ -587,16 +588,17 @@ F test/fts3expr.test 3401d47b229c4504424caf362cc4ff704cad4162
|
||||
F test/fts3expr2.test 18da930352e5693eaa163a3eacf96233b7290d1a
|
||||
F test/fts3expr3.test 9e91b8edbcb197bf2e92161aa7696446d96dce5f
|
||||
F test/fts3expr4.test e1be1248566f43c252d4404d52914f1fc4bfa065
|
||||
F test/fts3expr5.test f9abfffbf5e53d48a33e12a1e8f8ba2c551c9b49
|
||||
F test/fts3fault.test cb72dccb0a3b9f730f16c5240f3fcb9303eb1660
|
||||
F test/fts3fault2.test f953bb3cf903988172270a9a0aafd5a890b0f98f
|
||||
F test/fts3first.test dbdedd20914c8d539aa3206c9b34a23775644641
|
||||
F test/fts3join.test 53e66a0c21eb568580674a43b21c059acb26f499
|
||||
F test/fts3malloc.test b0e4c133b8d61d4f6d112d8110f8320e9e453ef6
|
||||
F test/fts3matchinfo.test 58544fa4d254000fa4e7f494b0a832f7ba61d45e
|
||||
F test/fts3matchinfo.test 07009313ad6c082f94d8c9c3228eb8940c93ac71
|
||||
F test/fts3near.test 7e3354d46f155a822b59c0e957fd2a70c1d7e905
|
||||
F test/fts3prefix.test fa794eaab0bdae466494947b0b153d7844478ab2
|
||||
F test/fts3prefix2.test e1f0a822ca661dced7f12ce392e14eaf65609dce
|
||||
F test/fts3query.test c838b18f2b859e15fd31c64be3d79ef1556803ca
|
||||
F test/fts3query.test f33eb71a1fe1084ea585eeb7ee76b390729f5170
|
||||
F test/fts3rnd.test 1320d8826a845e38a96e769562bf83d7a92a15d0
|
||||
F test/fts3shared.test 57e26a801f21027b7530da77db54286a6fe4997e
|
||||
F test/fts3snippet.test 63dbd687d5bf5191f1b8e6a0977aa9c1e28a7004
|
||||
@@ -605,7 +607,7 @@ F test/fts3tok1.test 178c050199af8c05299b1ad572514ce1c54b7827
|
||||
F test/fts3tok_err.test 52273cd193b9036282f7bacb43da78c6be87418d
|
||||
F test/fts3varint.test 752c08ed5d32c5d7dc211b056f4ed68a76b7e36e
|
||||
F test/fts4aa.test 10aac8e9d62c7357590acfabe3fad01e9a9ce1cb
|
||||
F test/fts4check.test 74d77f6cdb768ac49df5afda575cef14ae3d239a
|
||||
F test/fts4check.test 9d9e818fd6cb29c0e007cd6d00447739d4fde430
|
||||
F test/fts4content.test abb0c77bc3da3df64fec72e00844d2257a90025d
|
||||
F test/fts4docid.test e33c383cfbdff0284685604d256f347a18fdbf01
|
||||
F test/fts4growth.test df10fde9f47cf5c71861e63fd8efcd573c4f7e53
|
||||
@@ -630,6 +632,8 @@ F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1
|
||||
F test/fuzz3.test efd384b896c647b61a2c1848ba70d42aad60a7b3
|
||||
F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b
|
||||
F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26
|
||||
F test/fuzzdata1.txt 9fceb50868e0b798160e83742bd7e44e457176a0
|
||||
F test/fuzzdata2.txt ba9b4467d7ec46cc85d32c0d031540cd727ae6ad
|
||||
F test/fuzzer1.test d4c52aaf3ef923da293a2653cfab33d02f718a36
|
||||
F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536
|
||||
F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98
|
||||
@@ -659,14 +663,14 @@ F test/index3.test b6ec456cf3b81d9a32123fe7e449bde434db338b
|
||||
F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6
|
||||
F test/index5.test 25b0b451aceed4ac5f7d49f856f6de7257470b3e
|
||||
F test/index6.test 3ae54e53c53f2adcacda269237d8e52bdb05a481
|
||||
F test/index7.test 3d54dce09344c4530ea39a458aa304da044c887a
|
||||
F test/index7.test 9c6765a74fc3fcde7aebc5b3bd40d98df14a527c
|
||||
F test/indexedby.test 5f527a78bae74c61b8046ae3037f9dfb0bf0c353
|
||||
F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d
|
||||
F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
|
||||
F test/insert.test 38742b5e9601c8f8d76e9b7555f7270288c2d371
|
||||
F test/insert2.test 4f3a04d168c728ed5ec2c88842e772606c7ce435
|
||||
F test/insert2.test 4d14b8f1b810a41995f6286b64a6943215d52208
|
||||
F test/insert3.test 1b7db95a03ad9c5013fdf7d6722b6cd66ee55e30
|
||||
F test/insert4.test 4791662c50518bdd37d394cae9a7a8014e845bb3
|
||||
F test/insert4.test a20432f1c0fbbcff8f11d0e6ab4acb8c9db58023
|
||||
F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6
|
||||
F test/instr.test 737bbf80685232033f3abedc6ae92f75860b5dd2
|
||||
F test/intarray.test 066b7d7ac38d25bf96f87f1b017bfc687551cdd4
|
||||
@@ -688,7 +692,7 @@ F test/join6.test cfe6503791ceb0cbb509966740286ec423cbf10b
|
||||
F test/journal1.test 69abc726c51b4a0409189f9a85191205297c0577
|
||||
F test/journal2.test ae06f566c28552c313ded3fee79a6c69e6d049b1
|
||||
F test/journal3.test ff8af941f9e06161d3db1b46bb9f965ff0e7f307
|
||||
F test/jrnlmode.test 9ee3a78f53d52cca737db69293d15dc41c0cbd36
|
||||
F test/jrnlmode.test 7864d59cf7f6e552b9b99ba0f38acd167edc10fa
|
||||
F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d
|
||||
F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
|
||||
F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
|
||||
@@ -711,7 +715,7 @@ F test/lock_common.tcl 7ffb45accf6ee91c736df9bafe0806a44358f035
|
||||
F test/lookaside.test 93f07bac140c5bb1d49f3892d2684decafdc7af2
|
||||
F test/main.test 16131264ea0c2b93b95201f0c92958e85f2ba11a
|
||||
F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9
|
||||
F test/malloc.test 96939d2d1a6f39667bbebe5bc27c6525f2ab614e
|
||||
F test/malloc.test 21c213365f2cca95ab2d7dc078dc8525f96065f8
|
||||
F test/malloc3.test e3b32c724b5a124b57cb0ed177f675249ad0c66a
|
||||
F test/malloc4.test 957337613002b7058a85116493a262f679f3a261
|
||||
F test/malloc5.test 79182b8bffd6d62f77b1a5a8ba8e6bf0e5053b8e
|
||||
@@ -743,15 +747,16 @@ F test/minmax.test 42fbad0e81afaa6e0de41c960329f2b2c3526efd
|
||||
F test/minmax2.test b44bae787fc7b227597b01b0ca5575c7cb54d3bc
|
||||
F test/minmax3.test cc1e8b010136db0d01a6f2a29ba5a9f321034354
|
||||
F test/minmax4.test 936941484ebdceb8adec7c86b6cd9b6e5e897c1f
|
||||
F test/misc1.test 9abcae9a0b8785d6fa92925dbb19c309ae9ea077
|
||||
F test/misc1.test 783ba75743b2cf71e0f646bf540a6cef57264811
|
||||
F test/misc2.test 00d7de54eda90e237fc9a38b9e5ccc769ebf6d4d
|
||||
F test/misc3.test cf3dda47d5dda3e53fc5804a100d3c82be736c9d
|
||||
F test/misc4.test 9c078510fbfff05a9869a0b6d8b86a623ad2c4f6
|
||||
F test/misc5.test 528468b26d03303b1f047146e5eefc941b9069f5
|
||||
F test/misc5.test f96428ea95b3820aafc6f1c50cf48a09e4597ee1
|
||||
F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91
|
||||
F test/misc7.test edd0b63e2ee29a256900b0514f6fff27e19e9bb2
|
||||
F test/misc8.test fc2754d38892f7dac30c22db3616c2764f117d66
|
||||
F test/misuse.test 3c34719944ba045cc6c188a4852ba04680728912
|
||||
F test/mkfuzzdata1.tcl 5f9c33fadc64b078bb4a2c04c18b6dd3da075bec
|
||||
F test/mmap1.test 1bfd611b9841eafb44f7d83c0788e146d84a33c9
|
||||
F test/mmap2.test 9d6dd9ddb4ad2379f29cc78f38ce1e63ed418022
|
||||
F test/mmap3.test c92273e16eb8d23c1d55c9815b446bb72ef0512e
|
||||
@@ -789,12 +794,12 @@ F test/pagerfault.test ae9ee0db5a30aecda9db8290ce3dd12e5f7bbaa1
|
||||
F test/pagerfault2.test caf4c7facb914fd3b03a17b31ae2b180c8d6ca1f
|
||||
F test/pagerfault3.test 1003fcda009bf48a8e22a516e193b6ef0dd1bbd8
|
||||
F test/pageropt.test 6b8f6a123a5572c195ad4ae40f2987007923bbd6
|
||||
F test/pagesize.test 1dd51367e752e742f58e861e65ed7390603827a0
|
||||
F test/pagesize.test 5769fc62d8c890a83a503f67d47508dfdc543305
|
||||
F test/pcache.test b09104b03160aca0d968d99e8cd2c5b1921a993d
|
||||
F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
|
||||
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
|
||||
F test/permutations.test f9cc1dd987986c9d4949211c7a4ed55ec9aecba1
|
||||
F test/pragma.test e6605ce89c66db930aef561e43a22281a09ffc66
|
||||
F test/pragma.test be7195f0aa72bdb8a512133e9640ac40f15b57a2
|
||||
F test/pragma2.test f624a496a95ee878e81e59961eade66d5c00c028
|
||||
F test/pragma3.test 6f849ccffeee7e496d2f2b5e74152306c0b8757c
|
||||
F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc
|
||||
@@ -812,8 +817,8 @@ F test/randexpr1.test eda062a97e60f9c38ae8d806b03b0ddf23d796df
|
||||
F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8
|
||||
F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8
|
||||
F test/reindex.test 44edd3966b474468b823d481eafef0c305022254
|
||||
F test/releasetest.tcl a37cd82092c8be438255d65804b5951d6e3ecdae
|
||||
F test/resolver01.test 33abf37ff8335e6bf98f2b45a0af3e06996ccd9a
|
||||
F test/releasetest.tcl 7ad4fd49ae50c41ec7781815bdda8a8b278781d4
|
||||
F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb
|
||||
F test/rollback.test 458fe73eb3ffdfdf9f6ba3e9b7350a6220414dea
|
||||
F test/rollback2.test fc14cf6d1a2b250d2735ef16124b971bce152f14
|
||||
F test/rollbackfault.test 6a004f71087cc399296cffbb5429ea6da655ae65
|
||||
@@ -836,10 +841,10 @@ F test/schema4.test e6a66e20cc69f0e306667c08be7fda3d11707dc5
|
||||
F test/schema5.test 29699b4421f183c8f0e88bd28ce7d75d13ea653e
|
||||
F test/securedel.test 21749c32ccc30f1ea9e4b9f33295a6521ec20fa0
|
||||
F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5
|
||||
F test/select1.test fc2a61f226a649393664ad54bc5376631801517c
|
||||
F test/select1.test be62204d2bd9a5a8a149e9974cfddce893d8f686
|
||||
F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56
|
||||
F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054
|
||||
F test/select4.test 16fa1cafb942f42294ec85cbb78954c2f2d15a44
|
||||
F test/select4.test 824342f382f16b4afe42d0887ef82b3d6abb6075
|
||||
F test/select5.test e758b8ef94f69b111df4cb819008856655dcd535
|
||||
F test/select6.test 39eac4a5c03650b2b473c532882273283ee8b7a0
|
||||
F test/select7.test 7fd2ef598cfabb6b9ff6ac13973b91d0527df49d
|
||||
@@ -865,7 +870,7 @@ F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5
|
||||
F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e
|
||||
F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506
|
||||
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
|
||||
F test/shell1.test ca88b14a8fc8b1f3543a24e519d019585ac9c903
|
||||
F test/shell1.test ce5e744870387164703bf2dee2cc9753e4a71513
|
||||
F test/shell2.test 12b8bf901b0e3a8ac58cf5c0c63a0a388d4d1862
|
||||
F test/shell3.test 5e8545ec72c4413a0e8d4c6be56496e3c257ca29
|
||||
F test/shell4.test ddf0a99044e2245a87fc17423e3aaa1445b3243b
|
||||
@@ -897,10 +902,12 @@ F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
|
||||
F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
|
||||
F test/speedtest1.c 2b416dca3a155fcaa849540b2e7fc1df12896c23
|
||||
F test/spellfix.test 24f676831acddd2f4056a598fd731a72c6311f49
|
||||
F test/sqldiff1.test e5ecfe95b3a2ff6380f0db6ea8bec246b675e122
|
||||
F test/sqllimits1.test e05786eaed7950ff6a2d00031d001d8a26131e68
|
||||
F test/stat.test 76fd746b85459e812a0193410fb599f0531f22de
|
||||
F test/stat.test 8de91498c99f5298b303f70f1d1f3b9557af91bf
|
||||
F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1
|
||||
F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9
|
||||
F test/subquery.test 666fdecceac258f5fd84bed09a64e49d9f37edd9
|
||||
F test/subquery.test d7268d193dd33d5505df965399d3a594e76ae13f
|
||||
F test/subquery2.test 438f8a7da1457277b22e4176510f7659b286995f
|
||||
F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4
|
||||
F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a
|
||||
@@ -908,14 +915,14 @@ F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2
|
||||
F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85
|
||||
F test/syscall.test d2fdaad713f103ac611fe7ef9b724c7b69f8149c
|
||||
F test/sysfault.test fa776e60bf46bdd3ae69f0b73e46ee3977a58ae6
|
||||
F test/table.test 06271d61eb13871490d38168433c1ef3dd82bb2a
|
||||
F test/table.test bd841e8df69b99172ce9c7d53587463913d711ca
|
||||
F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
|
||||
F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
|
||||
F test/tclsqlite.test 7fb866443c7deceed22b63948ccd6f76b52ad054
|
||||
F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c
|
||||
F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
|
||||
F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1
|
||||
F test/tester.tcl ed77454e6c7b40eb501db7e79d1c6fbfd3eebbff
|
||||
F test/tester.tcl 51211254f2ee2340d3e4fa0a83bd5381b9e1a227
|
||||
F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5
|
||||
F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
|
||||
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
|
||||
@@ -1071,7 +1078,7 @@ F test/tkt4018.test 7c2c9ba4df489c676a0a7a0e809a1fb9b2185bd1
|
||||
F test/tokenize.test ce430a7aed48fc98301611429595883fdfcab5d7
|
||||
F test/tpch01.test 04adbf8d8300fa60a222f28d901abd76e7be6dd4
|
||||
F test/trace.test 73a5508100f7fccfbc3f8018d5f6963ed478eea0
|
||||
F test/trace2.test 93b47ca6996c66b47f57224cfb146f34e07df382
|
||||
F test/trace2.test f5cb67ad3bc09e0c58e8cca78dfd0b5639259983
|
||||
F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6
|
||||
F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76
|
||||
F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94
|
||||
@@ -1087,7 +1094,7 @@ F test/trigger8.test 30cb0530bd7c4728055420e3f739aa00412eafa4
|
||||
F test/trigger9.test 2226ec795a33b0460ab5cf8891e9054cc7edef41
|
||||
F test/triggerA.test fe5597f47ee21bacb4936dc827994ed94161e332
|
||||
F test/triggerB.test 56780c031b454abac2340dbb3b71ac5c56c3d7fe
|
||||
F test/triggerC.test a68980c5955d62ee24be6f97129d824f199f9a4c
|
||||
F test/triggerC.test 302d8995f5ffe63bbc15053abb3ef7a39cf5a092
|
||||
F test/triggerD.test 8e7f3921a92a5797d472732108109e44575fa650
|
||||
F test/triggerE.test 355e9c5cbaed5cd039a60baad1fb2197caeb8e52
|
||||
F test/tt3_checkpoint.c 9e75cf7c1c364f52e1c47fd0f14c4340a9db0fe1
|
||||
@@ -1113,7 +1120,7 @@ F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9
|
||||
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
|
||||
F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
|
||||
F test/view.test f311691d696a5cc27e3c1b875cec1b0866b4ccd9
|
||||
F test/vtab1.test c9dc2a73e93331d70b37ce4b246ef6dc18412fef
|
||||
F test/vtab1.test d1e5ec7a818f1d3f0402382b6a1d0c06071b770f
|
||||
F test/vtab2.test 3644649aa8d1daac57fd541f6a5f914cac59203e
|
||||
F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e
|
||||
F test/vtab4.test 942f8b8280b3ea8a41dae20e7822d065ca1cb275
|
||||
@@ -1122,7 +1129,7 @@ F test/vtab6.test 5f5380c425e52993560ab4763db4f826d2ba7b09
|
||||
F test/vtab7.test ae560ebea870ed04e9aa4177cc302f910faaabb5
|
||||
F test/vtab8.test e19fa4a538fcd1bb66c22825fa8f71618fb13583
|
||||
F test/vtab9.test ea58d2b95d61955f87226381716b2d0b1d4e4f9b
|
||||
F test/vtabA.test c86e1990b7e1e2bb34602a06fffa4c69f2b516dc
|
||||
F test/vtabA.test 1317f06a03597eee29f40a49b6c21e1aaba4285f
|
||||
F test/vtabB.test 04df5dc531b9f44d9ca65b9c1b79f12b5922a796
|
||||
F test/vtabC.test 4528f459a13136f982e75614d120aef165f17292
|
||||
F test/vtabD.test 05b3f1d77117271671089e48719524b676842e96
|
||||
@@ -1196,17 +1203,18 @@ F test/without_rowid6.test db0dbf03c49030aa3c1ba5f618620334bd2baf5f
|
||||
F test/wordcount.c 9915e06cb33d8ca8109b8700791afe80d305afda
|
||||
F test/zeroblob.test fb3c0e4ab172d386954deda24c03f500e121d80d
|
||||
F test/zerodamage.test cf6748bad89553cc1632be51a6f54e487e4039ac
|
||||
F tool/build-all-msvc.bat 72e05bc8deca39a547884485c086b915f50a91ed x
|
||||
F tool/build-all-msvc.bat 9058bd90a3c078a3d8c17d40e853aaa0f47885f4 x
|
||||
F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367
|
||||
F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2
|
||||
F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b
|
||||
F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2
|
||||
F tool/fast_vacuum.c 5ba0d6f5963a0a63bdc42840f678bad75b2ebce1
|
||||
F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439
|
||||
F tool/fuzzershell.c e8be9a8bd8e0e7814592c5e3e38de99ad7beee83
|
||||
F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4
|
||||
F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5
|
||||
F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
|
||||
F tool/lemon.c ae5f61e3b164d35955777b20d6febcbaf0950702
|
||||
F tool/lemon.c b9109f59b57e7b6f101c4fe644c8361ba6dee969
|
||||
F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc
|
||||
F tool/logest.c eef612f8adf4d0993dafed0416064cf50d5d33c6
|
||||
F tool/mkautoconfamal.sh d1a2da0e15b2ed33d60af35c7e9d483f13a8eb9f
|
||||
@@ -1215,10 +1223,10 @@ F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
|
||||
F tool/mkpragmatab.tcl 94f196c9961e0ca3513e29f57125a3197808be2d
|
||||
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
|
||||
F tool/mksqlite3c-noext.tcl 69bae8ce4aa52d2ff82d4a8a856bf283ec035b2e
|
||||
F tool/mksqlite3c.tcl 52a3352f7aa15f1db851e45ac3a5e2173d6fe93c
|
||||
F tool/mksqlite3c.tcl 10c06c9c616415c0269c13a33304a75e3c319c3f
|
||||
F tool/mksqlite3h.tcl 44730d586c9031638cdd2eb443b801c0d2dbd9f8
|
||||
F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b
|
||||
F tool/mkvsix.tcl 52a4c613707ac34ae9c226e5ccc69cb948556105
|
||||
F tool/mkvsix.tcl 3b58b9398f91c7dbf18d49eb87cefeee9efdbce1
|
||||
F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091
|
||||
F tool/omittest.tcl 34d7ac01fe4fd18e3637f64abe12c40eca0f6b97
|
||||
F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
|
||||
@@ -1232,14 +1240,14 @@ F tool/showstat4.c 9515faa8ec176599d4a8288293ba8ec61f7b728a
|
||||
F tool/showwal.c 85cb36d4fe3e93e2fbd63e786e0d1ce42d0c4fad
|
||||
F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe
|
||||
F tool/space_used.tcl f714c41a59e326b8b9042f415b628b561bafa06b
|
||||
F tool/spaceanal.tcl d5a09620c66a6c144576cb9d2bdfa9a6fbe362a5
|
||||
F tool/spaceanal.tcl 713c587a057334de42c41ad9566f10e255d3ad27
|
||||
F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355
|
||||
F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
|
||||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||
F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c
|
||||
F tool/sqldiff.c 5c16cf3a1f566873abbdecac0d13a6691437564f
|
||||
F tool/sqldiff.c 0748c0daed08f31e5a8eab6de98ca57500e61ecf
|
||||
F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43
|
||||
F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d
|
||||
F tool/symbols.sh fec58532668296d7c7dc48be9c87f75ccdb5814f
|
||||
@@ -1250,7 +1258,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P c37f4d492f98ac5c07c08705a3826a3e86107306
|
||||
R f96d406cf134e6be926fdb343dc33ea3
|
||||
P 28cfdabc471e132a856292781767777c6390ea3c 59e3e9e764440b7feaafadff74f422535d21bca2
|
||||
R 6d9983e3c63d923bd10dfd89492e7521
|
||||
U mistachkin
|
||||
Z 0af972753cfc85d551aad5ddaa27fa03
|
||||
Z c62be7c9e3b3706985519faa753e0586
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
9e593fb3dbc58e86f499ba4399530e3e760eb84d
|
||||
10ee36d012e6ee82febbe0ef2e90381e215afb90
|
||||
@@ -126,6 +126,7 @@ static void renameParentFunc(
|
||||
n = sqlite3GetToken(z, &token);
|
||||
}while( token==TK_SPACE );
|
||||
|
||||
if( token==TK_ILLEGAL ) break;
|
||||
zParent = sqlite3DbStrNDup(db, (const char *)z, n);
|
||||
if( zParent==0 ) break;
|
||||
sqlite3Dequote(zParent);
|
||||
|
||||
+9
-6
@@ -1519,14 +1519,17 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
|
||||
z = argv[2];
|
||||
|
||||
if( pIndex ){
|
||||
tRowcnt *aiRowEst = 0;
|
||||
int nCol = pIndex->nKeyCol+1;
|
||||
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
|
||||
tRowcnt * const aiRowEst = pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(
|
||||
sizeof(tRowcnt) * nCol
|
||||
);
|
||||
if( aiRowEst==0 ) pInfo->db->mallocFailed = 1;
|
||||
#else
|
||||
tRowcnt * const aiRowEst = 0;
|
||||
/* Index.aiRowEst may already be set here if there are duplicate
|
||||
** sqlite_stat1 entries for this index. In that case just clobber
|
||||
** the old data with the new instead of allocating a new array. */
|
||||
if( pIndex->aiRowEst==0 ){
|
||||
pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(sizeof(tRowcnt) * nCol);
|
||||
if( pIndex->aiRowEst==0 ) pInfo->db->mallocFailed = 1;
|
||||
}
|
||||
aiRowEst = pIndex->aiRowEst;
|
||||
#endif
|
||||
pIndex->bUnordered = 0;
|
||||
decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex);
|
||||
|
||||
@@ -332,7 +332,6 @@ static void codeAttach(
|
||||
SQLITE_OK!=(rc = resolveAttachExpr(&sName, pDbname)) ||
|
||||
SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey))
|
||||
){
|
||||
pParse->nErr++;
|
||||
goto attach_end;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -341,7 +341,7 @@ int sqlite3BitvecBuiltinTest(int sz, int *aOp){
|
||||
** bits to act as the reference */
|
||||
pBitvec = sqlite3BitvecCreate( sz );
|
||||
pV = sqlite3MallocZero( (sz+7)/8 + 1 );
|
||||
pTmpSpace = sqlite3_malloc(BITVEC_SZ);
|
||||
pTmpSpace = sqlite3_malloc64(BITVEC_SZ);
|
||||
if( pBitvec==0 || pV==0 || pTmpSpace==0 ) goto bitvec_end;
|
||||
|
||||
/* NULL pBitvec tests */
|
||||
|
||||
+74
-18
@@ -2429,7 +2429,7 @@ int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, int iFix){
|
||||
if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE &&
|
||||
((pageSize-1)&pageSize)==0 ){
|
||||
assert( (pageSize & 7)==0 );
|
||||
assert( !pBt->pPage1 && !pBt->pCursor );
|
||||
assert( !pBt->pCursor );
|
||||
pBt->pageSize = (u32)pageSize;
|
||||
freeTempSpace(pBt);
|
||||
}
|
||||
@@ -8528,6 +8528,57 @@ static void checkList(
|
||||
}
|
||||
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
|
||||
|
||||
/*
|
||||
** An implementation of a min-heap.
|
||||
**
|
||||
** aHeap[0] is the number of elements on the heap. aHeap[1] is the
|
||||
** root element. The daughter nodes of aHeap[N] are aHeap[N*2]
|
||||
** and aHeap[N*2+1].
|
||||
**
|
||||
** The heap property is this: Every node is less than or equal to both
|
||||
** of its daughter nodes. A consequence of the heap property is that the
|
||||
** root node aHeap[1] is always the minimum value currently in the heap.
|
||||
**
|
||||
** The btreeHeapInsert() routine inserts an unsigned 32-bit number onto
|
||||
** the heap, preserving the heap property. The btreeHeapPull() routine
|
||||
** removes the root element from the heap (the minimum value in the heap)
|
||||
** and then moves other nodes around as necessary to preserve the heap
|
||||
** property.
|
||||
**
|
||||
** This heap is used for cell overlap and coverage testing. Each u32
|
||||
** entry represents the span of a cell or freeblock on a btree page.
|
||||
** The upper 16 bits are the index of the first byte of a range and the
|
||||
** lower 16 bits are the index of the last byte of that range.
|
||||
*/
|
||||
static void btreeHeapInsert(u32 *aHeap, u32 x){
|
||||
u32 j, i = ++aHeap[0];
|
||||
aHeap[i] = x;
|
||||
while( (j = i/2)>0 && aHeap[j]>aHeap[i] ){
|
||||
x = aHeap[j];
|
||||
aHeap[j] = aHeap[i];
|
||||
aHeap[i] = x;
|
||||
i = j;
|
||||
}
|
||||
}
|
||||
static int btreeHeapPull(u32 *aHeap, u32 *pOut){
|
||||
u32 j, i, x;
|
||||
if( (x = aHeap[0])==0 ) return 0;
|
||||
*pOut = aHeap[1];
|
||||
aHeap[1] = aHeap[x];
|
||||
aHeap[x] = 0xffffffff;
|
||||
aHeap[0]--;
|
||||
i = 1;
|
||||
while( (j = i*2)<=aHeap[0] ){
|
||||
if( aHeap[j]>aHeap[j+1] ) j++;
|
||||
if( aHeap[i]<aHeap[j] ) break;
|
||||
x = aHeap[i];
|
||||
aHeap[i] = aHeap[j];
|
||||
aHeap[j] = x;
|
||||
i = j;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_INTEGRITY_CHECK
|
||||
/*
|
||||
** Do various sanity checks on a single page of a tree. Return
|
||||
@@ -8560,7 +8611,8 @@ static int checkTreePage(
|
||||
u8 *data;
|
||||
BtShared *pBt;
|
||||
int usableSize;
|
||||
char *hit = 0;
|
||||
u32 *heap = 0;
|
||||
u32 x, prev = 0;
|
||||
i64 nMinKey = 0;
|
||||
i64 nMaxKey = 0;
|
||||
const char *saved_zPfx = pCheck->zPfx;
|
||||
@@ -8705,15 +8757,15 @@ static int checkTreePage(
|
||||
*/
|
||||
data = pPage->aData;
|
||||
hdr = pPage->hdrOffset;
|
||||
hit = sqlite3PageMalloc( pBt->pageSize );
|
||||
heap = (u32*)sqlite3PageMalloc( pBt->pageSize );
|
||||
pCheck->zPfx = 0;
|
||||
if( hit==0 ){
|
||||
if( heap==0 ){
|
||||
pCheck->mallocFailed = 1;
|
||||
}else{
|
||||
int contentOffset = get2byteNotZero(&data[hdr+5]);
|
||||
assert( contentOffset<=usableSize ); /* Enforced by btreeInitPage() */
|
||||
memset(hit+contentOffset, 0, usableSize-contentOffset);
|
||||
memset(hit, 1, contentOffset);
|
||||
heap[0] = 0;
|
||||
btreeHeapInsert(heap, contentOffset-1);
|
||||
/* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the
|
||||
** number of cells on the page. */
|
||||
nCell = get2byte(&data[hdr+3]);
|
||||
@@ -8725,7 +8777,6 @@ static int checkTreePage(
|
||||
for(i=0; i<nCell; i++){
|
||||
int pc = get2byte(&data[cellStart+i*2]);
|
||||
u32 size = 65536;
|
||||
int j;
|
||||
if( pc<=usableSize-4 ){
|
||||
size = cellSizePtr(pPage, &data[pc]);
|
||||
}
|
||||
@@ -8734,7 +8785,7 @@ static int checkTreePage(
|
||||
checkAppendMsg(pCheck,
|
||||
"Corruption detected in cell %d on page %d",i,iPage);
|
||||
}else{
|
||||
for(j=pc+size-1; j>=pc; j--) hit[j]++;
|
||||
btreeHeapInsert(heap, (pc<<16)|(pc+size-1));
|
||||
}
|
||||
}
|
||||
/* EVIDENCE-OF: R-20690-50594 The second field of the b-tree page header
|
||||
@@ -8746,7 +8797,7 @@ static int checkTreePage(
|
||||
assert( i<=usableSize-4 ); /* Enforced by btreeInitPage() */
|
||||
size = get2byte(&data[i+2]);
|
||||
assert( i+size<=usableSize ); /* Enforced by btreeInitPage() */
|
||||
for(j=i+size-1; j>=i; j--) hit[j]++;
|
||||
btreeHeapInsert(heap, (i<<16)|(i+size-1));
|
||||
/* EVIDENCE-OF: R-58208-19414 The first 2 bytes of a freeblock are a
|
||||
** big-endian integer which is the offset in the b-tree page of the next
|
||||
** freeblock in the chain, or zero if the freeblock is the last on the
|
||||
@@ -8758,27 +8809,33 @@ static int checkTreePage(
|
||||
assert( j<=usableSize-4 ); /* Enforced by btreeInitPage() */
|
||||
i = j;
|
||||
}
|
||||
for(i=cnt=0; i<usableSize; i++){
|
||||
if( hit[i]==0 ){
|
||||
cnt++;
|
||||
}else if( hit[i]>1 ){
|
||||
cnt = 0;
|
||||
assert( heap[0]>0 );
|
||||
assert( (heap[1]>>16)==0 );
|
||||
btreeHeapPull(heap,&prev);
|
||||
while( btreeHeapPull(heap,&x) ){
|
||||
if( (prev&0xffff)+1>(x>>16) ){
|
||||
checkAppendMsg(pCheck,
|
||||
"Multiple uses for byte %d of page %d", i, iPage);
|
||||
"Multiple uses for byte %u of page %d", x>>16, iPage);
|
||||
break;
|
||||
}else{
|
||||
cnt += (x>>16) - (prev&0xffff) - 1;
|
||||
prev = x;
|
||||
}
|
||||
}
|
||||
cnt += usableSize - (prev&0xffff) - 1;
|
||||
/* EVIDENCE-OF: R-43263-13491 The total number of bytes in all fragments
|
||||
** is stored in the fifth field of the b-tree page header.
|
||||
** EVIDENCE-OF: R-07161-27322 The one-byte integer at offset 7 gives the
|
||||
** number of fragmented free bytes within the cell content area.
|
||||
*/
|
||||
if( cnt!=data[hdr+7] ){
|
||||
if( heap[0]==0 && cnt!=data[hdr+7] ){
|
||||
checkAppendMsg(pCheck,
|
||||
"Fragmentation of %d bytes reported as %d on page %d",
|
||||
cnt, data[hdr+7], iPage);
|
||||
}
|
||||
}
|
||||
sqlite3PageFree(hit);
|
||||
sqlite3PageFree(heap);
|
||||
releasePage(pPage);
|
||||
|
||||
end_of_check:
|
||||
@@ -8842,8 +8899,7 @@ char *sqlite3BtreeIntegrityCheck(
|
||||
}
|
||||
i = PENDING_BYTE_PAGE(pBt);
|
||||
if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i);
|
||||
sqlite3StrAccumInit(&sCheck.errMsg, zErr, sizeof(zErr), SQLITE_MAX_LENGTH);
|
||||
sCheck.errMsg.useMalloc = 2;
|
||||
sqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), SQLITE_MAX_LENGTH);
|
||||
|
||||
/* Check the integrity of the freelist
|
||||
*/
|
||||
|
||||
+10
-10
@@ -142,9 +142,11 @@ void sqlite3FinishCoding(Parse *pParse){
|
||||
|
||||
assert( pParse->pToplevel==0 );
|
||||
db = pParse->db;
|
||||
if( db->mallocFailed ) return;
|
||||
if( pParse->nested ) return;
|
||||
if( pParse->nErr ) return;
|
||||
if( db->mallocFailed || pParse->nErr ){
|
||||
if( pParse->rc==SQLITE_OK ) pParse->rc = SQLITE_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Begin by generating some termination code at the end of the
|
||||
** vdbe program
|
||||
@@ -761,14 +763,12 @@ int sqlite3TwoPartName(
|
||||
if( ALWAYS(pName2!=0) && pName2->n>0 ){
|
||||
if( db->init.busy ) {
|
||||
sqlite3ErrorMsg(pParse, "corrupt database");
|
||||
pParse->nErr++;
|
||||
return -1;
|
||||
}
|
||||
*pUnqual = pName2;
|
||||
iDb = sqlite3FindDb(db, pName1);
|
||||
if( iDb<0 ){
|
||||
sqlite3ErrorMsg(pParse, "unknown database %T", pName1);
|
||||
pParse->nErr++;
|
||||
return -1;
|
||||
}
|
||||
}else{
|
||||
@@ -927,7 +927,7 @@ void sqlite3StartTable(
|
||||
if( !noErr ){
|
||||
sqlite3ErrorMsg(pParse, "table %T already exists", pName);
|
||||
}else{
|
||||
assert( !db->init.busy );
|
||||
assert( !db->init.busy || CORRUPT_DB );
|
||||
sqlite3CodeVerifySchema(pParse, iDb);
|
||||
}
|
||||
goto begin_table_error;
|
||||
@@ -1216,7 +1216,8 @@ void sqlite3AddColumnType(Parse *pParse, Token *pType){
|
||||
p = pParse->pNewTable;
|
||||
if( p==0 || NEVER(p->nCol<1) ) return;
|
||||
pCol = &p->aCol[p->nCol-1];
|
||||
assert( pCol->zType==0 );
|
||||
assert( pCol->zType==0 || CORRUPT_DB );
|
||||
sqlite3DbFree(pParse->db, pCol->zType);
|
||||
pCol->zType = sqlite3NameFromToken(pParse->db, pType);
|
||||
pCol->affinity = sqlite3AffinityType(pCol->zType, &pCol->szEst);
|
||||
}
|
||||
@@ -2450,6 +2451,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
|
||||
}
|
||||
assert( pParse->nErr==0 );
|
||||
assert( pName->nSrc==1 );
|
||||
if( sqlite3ReadSchema(pParse) ) goto exit_drop_table;
|
||||
if( noErr ) db->suppressErr++;
|
||||
pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]);
|
||||
if( noErr ) db->suppressErr--;
|
||||
@@ -2857,8 +2859,7 @@ Index *sqlite3CreateIndex(
|
||||
char *zExtra = 0; /* Extra space after the Index object */
|
||||
Index *pPk = 0; /* PRIMARY KEY index for WITHOUT ROWID tables */
|
||||
|
||||
assert( pParse->nErr==0 ); /* Never called with prior errors */
|
||||
if( db->mallocFailed || IN_DECLARE_VTAB ){
|
||||
if( db->mallocFailed || IN_DECLARE_VTAB || pParse->nErr>0 ){
|
||||
goto exit_create_index;
|
||||
}
|
||||
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
|
||||
@@ -4023,8 +4024,7 @@ void sqlite3UniqueConstraint(
|
||||
StrAccum errMsg;
|
||||
Table *pTab = pIdx->pTable;
|
||||
|
||||
sqlite3StrAccumInit(&errMsg, 0, 0, 200);
|
||||
errMsg.db = pParse->db;
|
||||
sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 200);
|
||||
for(j=0; j<pIdx->nKeyCol; j++){
|
||||
char *zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
|
||||
if( j ) sqlite3StrAccumAppend(&errMsg, ", ", 2);
|
||||
|
||||
@@ -75,6 +75,9 @@ static const char * const azCompileOpt[] = {
|
||||
#if SQLITE_ENABLE_COLUMN_METADATA
|
||||
"ENABLE_COLUMN_METADATA",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_DBSTAT_VTAB
|
||||
"ENABLE_DBSTAT_VTAB",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_EXPENSIVE_ASSERT
|
||||
"ENABLE_EXPENSIVE_ASSERT",
|
||||
#endif
|
||||
|
||||
+110
-106
@@ -18,11 +18,9 @@
|
||||
** for an example implementation.
|
||||
*/
|
||||
|
||||
#ifndef SQLITE_AMALGAMATION
|
||||
# include "sqliteInt.h"
|
||||
#endif
|
||||
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
#include "sqliteInt.h" /* Requires access to internal data structures */
|
||||
#if (defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST)) \
|
||||
&& !defined(SQLITE_OMIT_VIRTUALTABLE)
|
||||
|
||||
/*
|
||||
** Page paths:
|
||||
@@ -124,6 +122,7 @@ struct StatCursor {
|
||||
struct StatTable {
|
||||
sqlite3_vtab base;
|
||||
sqlite3 *db;
|
||||
int iDb; /* Index of database to analyze */
|
||||
};
|
||||
|
||||
#ifndef get2byte
|
||||
@@ -140,15 +139,34 @@ static int statConnect(
|
||||
sqlite3_vtab **ppVtab,
|
||||
char **pzErr
|
||||
){
|
||||
StatTable *pTab;
|
||||
StatTable *pTab = 0;
|
||||
int rc = SQLITE_OK;
|
||||
int iDb;
|
||||
|
||||
pTab = (StatTable *)sqlite3_malloc(sizeof(StatTable));
|
||||
memset(pTab, 0, sizeof(StatTable));
|
||||
pTab->db = db;
|
||||
if( argc>=4 ){
|
||||
iDb = sqlite3FindDbName(db, argv[3]);
|
||||
if( iDb<0 ){
|
||||
*pzErr = sqlite3_mprintf("no such database: %s", argv[3]);
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
}else{
|
||||
iDb = 0;
|
||||
}
|
||||
rc = sqlite3_declare_vtab(db, VTAB_SCHEMA);
|
||||
if( rc==SQLITE_OK ){
|
||||
pTab = (StatTable *)sqlite3_malloc64(sizeof(StatTable));
|
||||
if( pTab==0 ) rc = SQLITE_NOMEM;
|
||||
}
|
||||
|
||||
sqlite3_declare_vtab(db, VTAB_SCHEMA);
|
||||
*ppVtab = &pTab->base;
|
||||
return SQLITE_OK;
|
||||
assert( rc==SQLITE_OK || pTab==0 );
|
||||
if( rc==SQLITE_OK ){
|
||||
memset(pTab, 0, sizeof(StatTable));
|
||||
pTab->db = db;
|
||||
pTab->iDb = iDb;
|
||||
}
|
||||
|
||||
*ppVtab = (sqlite3_vtab*)pTab;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -195,33 +213,45 @@ static int statOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
|
||||
StatCursor *pCsr;
|
||||
int rc;
|
||||
|
||||
pCsr = (StatCursor *)sqlite3_malloc(sizeof(StatCursor));
|
||||
memset(pCsr, 0, sizeof(StatCursor));
|
||||
pCsr->base.pVtab = pVTab;
|
||||
pCsr = (StatCursor *)sqlite3_malloc64(sizeof(StatCursor));
|
||||
if( pCsr==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
char *zSql;
|
||||
memset(pCsr, 0, sizeof(StatCursor));
|
||||
pCsr->base.pVtab = pVTab;
|
||||
|
||||
rc = sqlite3_prepare_v2(pTab->db,
|
||||
"SELECT 'sqlite_master' AS name, 1 AS rootpage, 'table' AS type"
|
||||
" UNION ALL "
|
||||
"SELECT name, rootpage, type FROM sqlite_master WHERE rootpage!=0"
|
||||
" ORDER BY name", -1,
|
||||
&pCsr->pStmt, 0
|
||||
);
|
||||
if( rc!=SQLITE_OK ){
|
||||
sqlite3_free(pCsr);
|
||||
return rc;
|
||||
zSql = sqlite3_mprintf(
|
||||
"SELECT 'sqlite_master' AS name, 1 AS rootpage, 'table' AS type"
|
||||
" UNION ALL "
|
||||
"SELECT name, rootpage, type"
|
||||
" FROM \"%w\".sqlite_master WHERE rootpage!=0"
|
||||
" ORDER BY name", pTab->db->aDb[pTab->iDb].zName);
|
||||
if( zSql==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0);
|
||||
sqlite3_free(zSql);
|
||||
}
|
||||
if( rc!=SQLITE_OK ){
|
||||
sqlite3_free(pCsr);
|
||||
pCsr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
*ppCursor = (sqlite3_vtab_cursor *)pCsr;
|
||||
return SQLITE_OK;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void statClearPage(StatPage *p){
|
||||
int i;
|
||||
for(i=0; i<p->nCell; i++){
|
||||
sqlite3_free(p->aCell[i].aOvfl);
|
||||
if( p->aCell ){
|
||||
for(i=0; i<p->nCell; i++){
|
||||
sqlite3_free(p->aCell[i].aOvfl);
|
||||
}
|
||||
sqlite3_free(p->aCell);
|
||||
}
|
||||
sqlite3PagerUnref(p->pPg);
|
||||
sqlite3_free(p->aCell);
|
||||
sqlite3_free(p->zPath);
|
||||
memset(p, 0, sizeof(StatPage));
|
||||
}
|
||||
@@ -306,7 +336,8 @@ static int statDecodePage(Btree *pBt, StatPage *p){
|
||||
sqlite3BtreeEnter(pBt);
|
||||
nUsable = szPage - sqlite3BtreeGetReserveNoMutex(pBt);
|
||||
sqlite3BtreeLeave(pBt);
|
||||
p->aCell = sqlite3_malloc((p->nCell+1) * sizeof(StatCell));
|
||||
p->aCell = sqlite3_malloc64((p->nCell+1) * sizeof(StatCell));
|
||||
if( p->aCell==0 ) return SQLITE_NOMEM;
|
||||
memset(p->aCell, 0, (p->nCell+1) * sizeof(StatCell));
|
||||
|
||||
for(i=0; i<p->nCell; i++){
|
||||
@@ -338,7 +369,8 @@ static int statDecodePage(Btree *pBt, StatPage *p){
|
||||
int nOvfl = ((nPayload - nLocal) + nUsable-4 - 1) / (nUsable - 4);
|
||||
pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4);
|
||||
pCell->nOvfl = nOvfl;
|
||||
pCell->aOvfl = sqlite3_malloc(sizeof(u32)*nOvfl);
|
||||
pCell->aOvfl = sqlite3_malloc64(sizeof(u32)*nOvfl);
|
||||
if( pCell->aOvfl==0 ) return SQLITE_NOMEM;
|
||||
pCell->aOvfl[0] = sqlite3Get4byte(&aData[iOff+nLocal]);
|
||||
for(j=1; j<nOvfl; j++){
|
||||
int rc;
|
||||
@@ -366,7 +398,7 @@ static int statDecodePage(Btree *pBt, StatPage *p){
|
||||
*/
|
||||
static void statSizeAndOffset(StatCursor *pCsr){
|
||||
StatTable *pTab = (StatTable *)((sqlite3_vtab_cursor *)pCsr)->pVtab;
|
||||
Btree *pBt = pTab->db->aDb[0].pBt;
|
||||
Btree *pBt = pTab->db->aDb[pTab->iDb].pBt;
|
||||
Pager *pPager = sqlite3BtreePager(pBt);
|
||||
sqlite3_file *fd;
|
||||
sqlite3_int64 x[2];
|
||||
@@ -380,7 +412,7 @@ static void statSizeAndOffset(StatCursor *pCsr){
|
||||
*/
|
||||
fd = sqlite3PagerFile(pPager);
|
||||
x[0] = pCsr->iPageno;
|
||||
if( sqlite3OsFileControl(fd, 230440, &x)==SQLITE_OK ){
|
||||
if( fd->pMethods!=0 && sqlite3OsFileControl(fd, 230440, &x)==SQLITE_OK ){
|
||||
pCsr->iOffset = x[0];
|
||||
pCsr->szPage = (int)x[1];
|
||||
}
|
||||
@@ -392,9 +424,10 @@ static void statSizeAndOffset(StatCursor *pCsr){
|
||||
static int statNext(sqlite3_vtab_cursor *pCursor){
|
||||
int rc;
|
||||
int nPayload;
|
||||
char *z;
|
||||
StatCursor *pCsr = (StatCursor *)pCursor;
|
||||
StatTable *pTab = (StatTable *)pCursor->pVtab;
|
||||
Btree *pBt = pTab->db->aDb[0].pBt;
|
||||
Btree *pBt = pTab->db->aDb[pTab->iDb].pBt;
|
||||
Pager *pPager = sqlite3BtreePager(pBt);
|
||||
|
||||
sqlite3_free(pCsr->zPath);
|
||||
@@ -414,8 +447,9 @@ statNextRestart:
|
||||
rc = sqlite3PagerGet(pPager, iRoot, &pCsr->aPage[0].pPg);
|
||||
pCsr->aPage[0].iPgno = iRoot;
|
||||
pCsr->aPage[0].iCell = 0;
|
||||
pCsr->aPage[0].zPath = sqlite3_mprintf("/");
|
||||
pCsr->aPage[0].zPath = z = sqlite3_mprintf("/");
|
||||
pCsr->iPage = 0;
|
||||
if( z==0 ) rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
pCsr->isEof = 1;
|
||||
return sqlite3_reset(pCsr->pStmt);
|
||||
@@ -438,7 +472,7 @@ statNextRestart:
|
||||
pCsr->zPagetype = "overflow";
|
||||
pCsr->nCell = 0;
|
||||
pCsr->nMxPayload = 0;
|
||||
pCsr->zPath = sqlite3_mprintf(
|
||||
pCsr->zPath = z = sqlite3_mprintf(
|
||||
"%s%.3x+%.6x", p->zPath, p->iCell, pCell->iOvfl
|
||||
);
|
||||
if( pCell->iOvfl<pCell->nOvfl-1 ){
|
||||
@@ -450,7 +484,7 @@ statNextRestart:
|
||||
}
|
||||
pCell->iOvfl++;
|
||||
statSizeAndOffset(pCsr);
|
||||
return SQLITE_OK;
|
||||
return z==0 ? SQLITE_NOMEM : SQLITE_OK;
|
||||
}
|
||||
if( p->iRightChildPg ) break;
|
||||
p->iCell++;
|
||||
@@ -472,8 +506,9 @@ statNextRestart:
|
||||
}
|
||||
rc = sqlite3PagerGet(pPager, p[1].iPgno, &p[1].pPg);
|
||||
p[1].iCell = 0;
|
||||
p[1].zPath = sqlite3_mprintf("%s%.3x/", p->zPath, p->iCell);
|
||||
p[1].zPath = z = sqlite3_mprintf("%s%.3x/", p->zPath, p->iCell);
|
||||
p->iCell++;
|
||||
if( z==0 ) rc = SQLITE_NOMEM;
|
||||
}
|
||||
|
||||
|
||||
@@ -486,31 +521,34 @@ statNextRestart:
|
||||
pCsr->zName = (char *)sqlite3_column_text(pCsr->pStmt, 0);
|
||||
pCsr->iPageno = p->iPgno;
|
||||
|
||||
statDecodePage(pBt, p);
|
||||
statSizeAndOffset(pCsr);
|
||||
rc = statDecodePage(pBt, p);
|
||||
if( rc==SQLITE_OK ){
|
||||
statSizeAndOffset(pCsr);
|
||||
|
||||
switch( p->flags ){
|
||||
case 0x05: /* table internal */
|
||||
case 0x02: /* index internal */
|
||||
pCsr->zPagetype = "internal";
|
||||
break;
|
||||
case 0x0D: /* table leaf */
|
||||
case 0x0A: /* index leaf */
|
||||
pCsr->zPagetype = "leaf";
|
||||
break;
|
||||
default:
|
||||
pCsr->zPagetype = "corrupted";
|
||||
break;
|
||||
switch( p->flags ){
|
||||
case 0x05: /* table internal */
|
||||
case 0x02: /* index internal */
|
||||
pCsr->zPagetype = "internal";
|
||||
break;
|
||||
case 0x0D: /* table leaf */
|
||||
case 0x0A: /* index leaf */
|
||||
pCsr->zPagetype = "leaf";
|
||||
break;
|
||||
default:
|
||||
pCsr->zPagetype = "corrupted";
|
||||
break;
|
||||
}
|
||||
pCsr->nCell = p->nCell;
|
||||
pCsr->nUnused = p->nUnused;
|
||||
pCsr->nMxPayload = p->nMxPayload;
|
||||
pCsr->zPath = z = sqlite3_mprintf("%s", p->zPath);
|
||||
if( z==0 ) rc = SQLITE_NOMEM;
|
||||
nPayload = 0;
|
||||
for(i=0; i<p->nCell; i++){
|
||||
nPayload += p->aCell[i].nLocal;
|
||||
}
|
||||
pCsr->nPayload = nPayload;
|
||||
}
|
||||
pCsr->nCell = p->nCell;
|
||||
pCsr->nUnused = p->nUnused;
|
||||
pCsr->nMxPayload = p->nMxPayload;
|
||||
pCsr->zPath = sqlite3_mprintf("%s", p->zPath);
|
||||
nPayload = 0;
|
||||
for(i=0; i<p->nCell; i++){
|
||||
nPayload += p->aCell[i].nLocal;
|
||||
}
|
||||
pCsr->nPayload = nPayload;
|
||||
}
|
||||
|
||||
return rc;
|
||||
@@ -540,7 +578,7 @@ static int statColumn(
|
||||
StatCursor *pCsr = (StatCursor *)pCursor;
|
||||
switch( i ){
|
||||
case 0: /* name */
|
||||
sqlite3_result_text(ctx, pCsr->zName, -1, SQLITE_STATIC);
|
||||
sqlite3_result_text(ctx, pCsr->zName, -1, SQLITE_TRANSIENT);
|
||||
break;
|
||||
case 1: /* path */
|
||||
sqlite3_result_text(ctx, pCsr->zPath, -1, SQLITE_TRANSIENT);
|
||||
@@ -566,7 +604,8 @@ static int statColumn(
|
||||
case 8: /* pgoffset */
|
||||
sqlite3_result_int64(ctx, pCsr->iOffset);
|
||||
break;
|
||||
case 9: /* pgsize */
|
||||
default: /* pgsize */
|
||||
assert( i==9 );
|
||||
sqlite3_result_int(ctx, pCsr->szPage);
|
||||
break;
|
||||
}
|
||||
@@ -579,7 +618,10 @@ static int statRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
int sqlite3_dbstat_register(sqlite3 *db){
|
||||
/*
|
||||
** Invoke this routine to register the "dbstat" virtual table module
|
||||
*/
|
||||
int sqlite3DbstatRegister(sqlite3 *db){
|
||||
static sqlite3_module dbstat_module = {
|
||||
0, /* iVersion */
|
||||
statConnect, /* xCreate */
|
||||
@@ -602,46 +644,8 @@ int sqlite3_dbstat_register(sqlite3 *db){
|
||||
0, /* xFindMethod */
|
||||
0, /* xRename */
|
||||
};
|
||||
sqlite3_create_module(db, "dbstat", &dbstat_module, 0);
|
||||
return SQLITE_OK;
|
||||
return sqlite3_create_module(db, "dbstat", &dbstat_module, 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(SQLITE_TEST) || TCLSH==2
|
||||
#include <tcl.h>
|
||||
|
||||
static int test_dbstat(
|
||||
void *clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
#ifdef SQLITE_OMIT_VIRTUALTABLE
|
||||
Tcl_AppendResult(interp, "dbstat not available because of "
|
||||
"SQLITE_OMIT_VIRTUALTABLE", (void*)0);
|
||||
return TCL_ERROR;
|
||||
#else
|
||||
struct SqliteDb { sqlite3 *db; };
|
||||
char *zDb;
|
||||
Tcl_CmdInfo cmdInfo;
|
||||
|
||||
if( objc!=2 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "DB");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
zDb = Tcl_GetString(objv[1]);
|
||||
if( Tcl_GetCommandInfo(interp, zDb, &cmdInfo) ){
|
||||
sqlite3* db = ((struct SqliteDb*)cmdInfo.objClientData)->db;
|
||||
sqlite3_dbstat_register(db);
|
||||
}
|
||||
return TCL_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
int SqlitetestStat_Init(Tcl_Interp *interp){
|
||||
Tcl_CreateObjCommand(interp, "register_dbstat_vtab", test_dbstat, 0, 0);
|
||||
return TCL_OK;
|
||||
}
|
||||
#endif /* if defined(SQLITE_TEST) || TCLSH==2 */
|
||||
#elif defined(SQLITE_ENABLE_DBSTAT_VTAB)
|
||||
int sqlite3DbstatRegister(sqlite3 *db){ return SQLITE_OK; }
|
||||
#endif /* SQLITE_ENABLE_DBSTAT_VTAB */
|
||||
+5
-4
@@ -1251,7 +1251,8 @@ u32 sqlite3ExprListFlags(const ExprList *pList){
|
||||
u32 m = 0;
|
||||
if( pList ){
|
||||
for(i=0; i<pList->nExpr; i++){
|
||||
m |= pList->a[i].pExpr->flags;
|
||||
Expr *pExpr = pList->a[i].pExpr;
|
||||
if( ALWAYS(pExpr) ) m |= pExpr->flags;
|
||||
}
|
||||
}
|
||||
return m;
|
||||
@@ -2016,7 +2017,7 @@ int sqlite3CodeSubselect(
|
||||
pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0,
|
||||
&sqlite3IntTokens[1]);
|
||||
pSel->iLimit = 0;
|
||||
pSel->selFlags &= ~SF_AllValues;
|
||||
pSel->selFlags &= ~SF_MultiValue;
|
||||
if( sqlite3Select(pParse, pSel, &dest) ){
|
||||
return 0;
|
||||
}
|
||||
@@ -3382,7 +3383,7 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
|
||||
break;
|
||||
}
|
||||
case TK_ID: {
|
||||
sqlite3TreeViewLine(pView,"ID %Q", pExpr->u.zToken);
|
||||
sqlite3TreeViewLine(pView,"ID \"%w\"", pExpr->u.zToken);
|
||||
break;
|
||||
}
|
||||
#ifndef SQLITE_OMIT_CAST
|
||||
@@ -4017,7 +4018,7 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){
|
||||
if( sqlite3ExprCompare(pA->pLeft, pB->pLeft, iTab) ) return 2;
|
||||
if( sqlite3ExprCompare(pA->pRight, pB->pRight, iTab) ) return 2;
|
||||
if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2;
|
||||
if( ALWAYS((combinedFlags & EP_Reduced)==0) ){
|
||||
if( ALWAYS((combinedFlags & EP_Reduced)==0) && pA->op!=TK_STRING ){
|
||||
if( pA->iColumn!=pB->iColumn ) return 2;
|
||||
if( pA->iTable!=pB->iTable
|
||||
&& (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
|
||||
|
||||
+12
-13
@@ -1197,10 +1197,10 @@ static Trigger *fkActionTrigger(
|
||||
** parent table are used for the comparison. */
|
||||
pEq = sqlite3PExpr(pParse, TK_EQ,
|
||||
sqlite3PExpr(pParse, TK_DOT,
|
||||
sqlite3PExpr(pParse, TK_ID, 0, 0, &tOld),
|
||||
sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol)
|
||||
sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
|
||||
sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)
|
||||
, 0),
|
||||
sqlite3PExpr(pParse, TK_ID, 0, 0, &tFromCol)
|
||||
sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0)
|
||||
, 0);
|
||||
pWhere = sqlite3ExprAnd(db, pWhere, pEq);
|
||||
|
||||
@@ -1212,12 +1212,12 @@ static Trigger *fkActionTrigger(
|
||||
if( pChanges ){
|
||||
pEq = sqlite3PExpr(pParse, TK_IS,
|
||||
sqlite3PExpr(pParse, TK_DOT,
|
||||
sqlite3PExpr(pParse, TK_ID, 0, 0, &tOld),
|
||||
sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol),
|
||||
sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
|
||||
sqlite3ExprAlloc(db, TK_ID, &tToCol, 0),
|
||||
0),
|
||||
sqlite3PExpr(pParse, TK_DOT,
|
||||
sqlite3PExpr(pParse, TK_ID, 0, 0, &tNew),
|
||||
sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol),
|
||||
sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
|
||||
sqlite3ExprAlloc(db, TK_ID, &tToCol, 0),
|
||||
0),
|
||||
0);
|
||||
pWhen = sqlite3ExprAnd(db, pWhen, pEq);
|
||||
@@ -1227,8 +1227,8 @@ static Trigger *fkActionTrigger(
|
||||
Expr *pNew;
|
||||
if( action==OE_Cascade ){
|
||||
pNew = sqlite3PExpr(pParse, TK_DOT,
|
||||
sqlite3PExpr(pParse, TK_ID, 0, 0, &tNew),
|
||||
sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol)
|
||||
sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
|
||||
sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)
|
||||
, 0);
|
||||
}else if( action==OE_SetDflt ){
|
||||
Expr *pDflt = pFKey->pFrom->aCol[iFromCol].pDflt;
|
||||
@@ -1275,13 +1275,12 @@ static Trigger *fkActionTrigger(
|
||||
pTrigger = (Trigger *)sqlite3DbMallocZero(db,
|
||||
sizeof(Trigger) + /* struct Trigger */
|
||||
sizeof(TriggerStep) + /* Single step in trigger program */
|
||||
nFrom + 1 /* Space for pStep->target.z */
|
||||
nFrom + 1 /* Space for pStep->zTarget */
|
||||
);
|
||||
if( pTrigger ){
|
||||
pStep = pTrigger->step_list = (TriggerStep *)&pTrigger[1];
|
||||
pStep->target.z = (char *)&pStep[1];
|
||||
pStep->target.n = nFrom;
|
||||
memcpy((char *)pStep->target.z, zFrom, nFrom);
|
||||
pStep->zTarget = (char *)&pStep[1];
|
||||
memcpy((char *)pStep->zTarget, zFrom, nFrom);
|
||||
|
||||
pStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
|
||||
pStep->pExprList = sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE);
|
||||
|
||||
+6
-7
@@ -232,13 +232,13 @@ static void printfFunc(
|
||||
StrAccum str;
|
||||
const char *zFormat;
|
||||
int n;
|
||||
sqlite3 *db = sqlite3_context_db_handle(context);
|
||||
|
||||
if( argc>=1 && (zFormat = (const char*)sqlite3_value_text(argv[0]))!=0 ){
|
||||
x.nArg = argc-1;
|
||||
x.nUsed = 0;
|
||||
x.apArg = argv+1;
|
||||
sqlite3StrAccumInit(&str, 0, 0, SQLITE_MAX_LENGTH);
|
||||
str.db = sqlite3_context_db_handle(context);
|
||||
sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]);
|
||||
sqlite3XPrintf(&str, SQLITE_PRINTF_SQLFUNC, zFormat, &x);
|
||||
n = str.nChar;
|
||||
sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n,
|
||||
@@ -388,7 +388,7 @@ static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Allocate nByte bytes of space using sqlite3_malloc(). If the
|
||||
** Allocate nByte bytes of space using sqlite3Malloc(). If the
|
||||
** allocation fails, call sqlite3_result_error_nomem() to notify
|
||||
** the database handle that malloc() has failed and return NULL.
|
||||
** If nByte is larger than the maximum string or blob length, then
|
||||
@@ -1057,7 +1057,7 @@ static void charFunc(
|
||||
){
|
||||
unsigned char *z, *zOut;
|
||||
int i;
|
||||
zOut = z = sqlite3_malloc( argc*4+1 );
|
||||
zOut = z = sqlite3_malloc64( argc*4+1 );
|
||||
if( z==0 ){
|
||||
sqlite3_result_error_nomem(context);
|
||||
return;
|
||||
@@ -1205,7 +1205,7 @@ static void replaceFunc(
|
||||
return;
|
||||
}
|
||||
zOld = zOut;
|
||||
zOut = sqlite3_realloc(zOut, (int)nOut);
|
||||
zOut = sqlite3_realloc64(zOut, (int)nOut);
|
||||
if( zOut==0 ){
|
||||
sqlite3_result_error_nomem(context);
|
||||
sqlite3_free(zOld);
|
||||
@@ -1567,8 +1567,7 @@ static void groupConcatStep(
|
||||
|
||||
if( pAccum ){
|
||||
sqlite3 *db = sqlite3_context_db_handle(context);
|
||||
int firstTerm = pAccum->useMalloc==0;
|
||||
pAccum->useMalloc = 2;
|
||||
int firstTerm = pAccum->mxAlloc==0;
|
||||
pAccum->mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH];
|
||||
if( !firstTerm ){
|
||||
if( argc==2 ){
|
||||
|
||||
+20
-17
@@ -342,20 +342,23 @@ static int xferOptimization(
|
||||
/*
|
||||
** This routine is called to handle SQL of the following forms:
|
||||
**
|
||||
** insert into TABLE (IDLIST) values(EXPRLIST)
|
||||
** insert into TABLE (IDLIST) values(EXPRLIST),(EXPRLIST),...
|
||||
** insert into TABLE (IDLIST) select
|
||||
** insert into TABLE (IDLIST) default values
|
||||
**
|
||||
** The IDLIST following the table name is always optional. If omitted,
|
||||
** then a list of all columns for the table is substituted. The IDLIST
|
||||
** appears in the pColumn parameter. pColumn is NULL if IDLIST is omitted.
|
||||
** then a list of all (non-hidden) columns for the table is substituted.
|
||||
** The IDLIST appears in the pColumn parameter. pColumn is NULL if IDLIST
|
||||
** is omitted.
|
||||
**
|
||||
** The pList parameter holds EXPRLIST in the first form of the INSERT
|
||||
** statement above, and pSelect is NULL. For the second form, pList is
|
||||
** NULL and pSelect is a pointer to the select statement used to generate
|
||||
** data for the insert.
|
||||
** For the pSelect parameter holds the values to be inserted for the
|
||||
** first two forms shown above. A VALUES clause is really just short-hand
|
||||
** for a SELECT statement that omits the FROM clause and everything else
|
||||
** that follows. If the pSelect parameter is NULL, that means that the
|
||||
** DEFAULT VALUES form of the INSERT statement is intended.
|
||||
**
|
||||
** The code generated follows one of four templates. For a simple
|
||||
** insert with data coming from a VALUES clause, the code executes
|
||||
** insert with data coming from a single-row VALUES clause, the code executes
|
||||
** once straight down through. Pseudo-code follows (we call this
|
||||
** the "1st template"):
|
||||
**
|
||||
@@ -462,7 +465,7 @@ void sqlite3Insert(
|
||||
u8 useTempTable = 0; /* Store SELECT results in intermediate table */
|
||||
u8 appendFlag = 0; /* True if the insert is likely to be an append */
|
||||
u8 withoutRowid; /* 0 for normal table. 1 for WITHOUT ROWID table */
|
||||
u8 bIdListInOrder = 1; /* True if IDLIST is in table order */
|
||||
u8 bIdListInOrder; /* True if IDLIST is in table order */
|
||||
ExprList *pList = 0; /* List of VALUES() to be inserted */
|
||||
|
||||
/* Register allocations */
|
||||
@@ -487,8 +490,8 @@ void sqlite3Insert(
|
||||
}
|
||||
|
||||
/* If the Select object is really just a simple VALUES() list with a
|
||||
** single row values (the common case) then keep that one row of values
|
||||
** and go ahead and discard the Select object
|
||||
** single row (the common case) then keep that one row of values
|
||||
** and discard the other (unused) parts of the pSelect object
|
||||
*/
|
||||
if( pSelect && (pSelect->selFlags & SF_Values)!=0 && pSelect->pPrior==0 ){
|
||||
pList = pSelect->pEList;
|
||||
@@ -596,6 +599,7 @@ void sqlite3Insert(
|
||||
** is appears in the original table. (The index of the INTEGER
|
||||
** PRIMARY KEY in the original table is pTab->iPKey.)
|
||||
*/
|
||||
bIdListInOrder = (pTab->tabFlags & TF_OOOHidden)==0;
|
||||
if( pColumn ){
|
||||
for(i=0; i<pColumn->nId; i++){
|
||||
pColumn->a[i].idx = -1;
|
||||
@@ -631,7 +635,8 @@ void sqlite3Insert(
|
||||
** co-routine is the common header to the 3rd and 4th templates.
|
||||
*/
|
||||
if( pSelect ){
|
||||
/* Data is coming from a SELECT. Generate a co-routine to run the SELECT */
|
||||
/* Data is coming from a SELECT or from a multi-row VALUES clause.
|
||||
** Generate a co-routine to run the SELECT. */
|
||||
int regYield; /* Register holding co-routine entry-point */
|
||||
int addrTop; /* Top of the co-routine */
|
||||
int rc; /* Result code */
|
||||
@@ -644,8 +649,7 @@ void sqlite3Insert(
|
||||
dest.nSdst = pTab->nCol;
|
||||
rc = sqlite3Select(pParse, pSelect, &dest);
|
||||
regFromSelect = dest.iSdst;
|
||||
assert( pParse->nErr==0 || rc );
|
||||
if( rc || db->mallocFailed ) goto insert_cleanup;
|
||||
if( rc || db->mallocFailed || pParse->nErr ) goto insert_cleanup;
|
||||
sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield);
|
||||
sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */
|
||||
assert( pSelect->pEList );
|
||||
@@ -693,8 +697,8 @@ void sqlite3Insert(
|
||||
sqlite3ReleaseTempReg(pParse, regTempRowid);
|
||||
}
|
||||
}else{
|
||||
/* This is the case if the data for the INSERT is coming from a VALUES
|
||||
** clause
|
||||
/* This is the case if the data for the INSERT is coming from a
|
||||
** single-row VALUES clause
|
||||
*/
|
||||
NameContext sNC;
|
||||
memset(&sNC, 0, sizeof(sNC));
|
||||
@@ -2021,7 +2025,6 @@ static int xferOptimization(
|
||||
** might change the definition of a collation sequence and then run
|
||||
** a VACUUM command. In that case keys may not be written in strictly
|
||||
** sorted order. */
|
||||
int i;
|
||||
for(i=0; i<pSrcIdx->nColumn; i++){
|
||||
char *zColl = pSrcIdx->azColl[i];
|
||||
assert( zColl!=0 );
|
||||
|
||||
+10
-10
@@ -430,7 +430,7 @@ static int sqlite3LoadExtension(
|
||||
const char *zEntry;
|
||||
char *zAltEntry = 0;
|
||||
void **aHandle;
|
||||
int nMsg = 300 + sqlite3Strlen30(zFile);
|
||||
u64 nMsg = 300 + sqlite3Strlen30(zFile);
|
||||
int ii;
|
||||
|
||||
/* Shared library endings to try if zFile cannot be loaded as written */
|
||||
@@ -473,7 +473,7 @@ static int sqlite3LoadExtension(
|
||||
#endif
|
||||
if( handle==0 ){
|
||||
if( pzErrMsg ){
|
||||
*pzErrMsg = zErrmsg = sqlite3_malloc(nMsg);
|
||||
*pzErrMsg = zErrmsg = sqlite3_malloc64(nMsg);
|
||||
if( zErrmsg ){
|
||||
sqlite3_snprintf(nMsg, zErrmsg,
|
||||
"unable to open shared library [%s]", zFile);
|
||||
@@ -499,7 +499,7 @@ static int sqlite3LoadExtension(
|
||||
if( xInit==0 && zProc==0 ){
|
||||
int iFile, iEntry, c;
|
||||
int ncFile = sqlite3Strlen30(zFile);
|
||||
zAltEntry = sqlite3_malloc(ncFile+30);
|
||||
zAltEntry = sqlite3_malloc64(ncFile+30);
|
||||
if( zAltEntry==0 ){
|
||||
sqlite3OsDlClose(pVfs, handle);
|
||||
return SQLITE_NOMEM;
|
||||
@@ -521,7 +521,7 @@ static int sqlite3LoadExtension(
|
||||
if( xInit==0 ){
|
||||
if( pzErrMsg ){
|
||||
nMsg += sqlite3Strlen30(zEntry);
|
||||
*pzErrMsg = zErrmsg = sqlite3_malloc(nMsg);
|
||||
*pzErrMsg = zErrmsg = sqlite3_malloc64(nMsg);
|
||||
if( zErrmsg ){
|
||||
sqlite3_snprintf(nMsg, zErrmsg,
|
||||
"no entry point [%s] in shared library [%s]", zEntry, zFile);
|
||||
@@ -620,7 +620,7 @@ static const sqlite3_api_routines sqlite3Apis = { 0 };
|
||||
*/
|
||||
typedef struct sqlite3AutoExtList sqlite3AutoExtList;
|
||||
static SQLITE_WSD struct sqlite3AutoExtList {
|
||||
int nExt; /* Number of entries in aExt[] */
|
||||
u32 nExt; /* Number of entries in aExt[] */
|
||||
void (**aExt)(void); /* Pointers to the extension init functions */
|
||||
} sqlite3Autoext = { 0, 0 };
|
||||
|
||||
@@ -653,7 +653,7 @@ int sqlite3_auto_extension(void (*xInit)(void)){
|
||||
}else
|
||||
#endif
|
||||
{
|
||||
int i;
|
||||
u32 i;
|
||||
#if SQLITE_THREADSAFE
|
||||
sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
|
||||
#endif
|
||||
@@ -663,9 +663,9 @@ int sqlite3_auto_extension(void (*xInit)(void)){
|
||||
if( wsdAutoext.aExt[i]==xInit ) break;
|
||||
}
|
||||
if( i==wsdAutoext.nExt ){
|
||||
int nByte = (wsdAutoext.nExt+1)*sizeof(wsdAutoext.aExt[0]);
|
||||
u64 nByte = (wsdAutoext.nExt+1)*sizeof(wsdAutoext.aExt[0]);
|
||||
void (**aNew)(void);
|
||||
aNew = sqlite3_realloc(wsdAutoext.aExt, nByte);
|
||||
aNew = sqlite3_realloc64(wsdAutoext.aExt, nByte);
|
||||
if( aNew==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
@@ -697,7 +697,7 @@ int sqlite3_cancel_auto_extension(void (*xInit)(void)){
|
||||
int n = 0;
|
||||
wsdAutoextInit;
|
||||
sqlite3_mutex_enter(mutex);
|
||||
for(i=wsdAutoext.nExt-1; i>=0; i--){
|
||||
for(i=(int)wsdAutoext.nExt-1; i>=0; i--){
|
||||
if( wsdAutoext.aExt[i]==xInit ){
|
||||
wsdAutoext.nExt--;
|
||||
wsdAutoext.aExt[i] = wsdAutoext.aExt[wsdAutoext.nExt];
|
||||
@@ -735,7 +735,7 @@ void sqlite3_reset_auto_extension(void){
|
||||
** If anything goes wrong, set an error in the database connection.
|
||||
*/
|
||||
void sqlite3AutoLoadExtensions(sqlite3 *db){
|
||||
int i;
|
||||
u32 i;
|
||||
int go = 1;
|
||||
int rc;
|
||||
int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
|
||||
|
||||
+47
-3
@@ -1763,6 +1763,25 @@ void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){
|
||||
return pOld;
|
||||
}
|
||||
/*
|
||||
** Return the current trace function and argument.
|
||||
*/
|
||||
int sqlite3_get_trace(
|
||||
const sqlite3 *db,
|
||||
void (**pxTrace)(void*,const char*),
|
||||
void **ppArg
|
||||
){
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !sqlite3SafetyCheckOk(db) || pxTrace==0 || ppArg==0 ){
|
||||
return SQLITE_MISUSE_BKPT;
|
||||
}
|
||||
#endif
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
*pxTrace = db->xTrace;
|
||||
*ppArg = db->pTraceArg;
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
/*
|
||||
** Register a profile function. The pArg from the previously registered
|
||||
** profile function is returned.
|
||||
**
|
||||
@@ -1790,6 +1809,25 @@ void *sqlite3_profile(
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return pOld;
|
||||
}
|
||||
/*
|
||||
** Return the current profile function and argument.
|
||||
*/
|
||||
int sqlite3_get_profile(
|
||||
const sqlite3 *db,
|
||||
void (**pxProfile)(void*,const char*,sqlite3_uint64),
|
||||
void **ppArg
|
||||
){
|
||||
#ifdef SQLITE_ENABLE_API_ARMOR
|
||||
if( !sqlite3SafetyCheckOk(db) || pxProfile==0 || ppArg==0 ){
|
||||
return SQLITE_MISUSE_BKPT;
|
||||
}
|
||||
#endif
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
*pxProfile = db->xProfile;
|
||||
*ppArg = db->pProfileArg;
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
#endif /* SQLITE_OMIT_TRACE */
|
||||
|
||||
/*
|
||||
@@ -2431,14 +2469,14 @@ int sqlite3ParseUri(
|
||||
int eState; /* Parser state when parsing URI */
|
||||
int iIn; /* Input character index */
|
||||
int iOut = 0; /* Output character index */
|
||||
int nByte = nUri+2; /* Bytes of space to allocate */
|
||||
u64 nByte = nUri+2; /* Bytes of space to allocate */
|
||||
|
||||
/* Make sure the SQLITE_OPEN_URI flag is set to indicate to the VFS xOpen
|
||||
** method that there may be extra parameters following the file-name. */
|
||||
flags |= SQLITE_OPEN_URI;
|
||||
|
||||
for(iIn=0; iIn<nUri; iIn++) nByte += (zUri[iIn]=='&');
|
||||
zFile = sqlite3_malloc(nByte);
|
||||
zFile = sqlite3_malloc64(nByte);
|
||||
if( !zFile ) return SQLITE_NOMEM;
|
||||
|
||||
iIn = 5;
|
||||
@@ -2604,7 +2642,7 @@ int sqlite3ParseUri(
|
||||
}
|
||||
|
||||
}else{
|
||||
zFile = sqlite3_malloc(nUri+2);
|
||||
zFile = sqlite3_malloc64(nUri+2);
|
||||
if( !zFile ) return SQLITE_NOMEM;
|
||||
memcpy(zFile, zUri, nUri);
|
||||
zFile[nUri] = '\0';
|
||||
@@ -2876,6 +2914,12 @@ static int openDatabase(
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_ENABLE_DBSTAT_VTAB
|
||||
if( !db->mallocFailed && rc==SQLITE_OK){
|
||||
rc = sqlite3DbstatRegister(db);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking
|
||||
** mode. -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking
|
||||
** mode. Doing nothing at all also makes NORMAL the default.
|
||||
|
||||
+5
-9
@@ -226,10 +226,8 @@ void sqlite3MallocEnd(void){
|
||||
** Return the amount of memory currently checked out.
|
||||
*/
|
||||
sqlite3_int64 sqlite3_memory_used(void){
|
||||
int n, mx;
|
||||
sqlite3_int64 res;
|
||||
sqlite3_status(SQLITE_STATUS_MEMORY_USED, &n, &mx, 0);
|
||||
res = (sqlite3_int64)n; /* Work around bug in Borland C. Ticket #3216 */
|
||||
sqlite3_int64 res, mx;
|
||||
sqlite3_status64(SQLITE_STATUS_MEMORY_USED, &res, &mx, 0);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -239,11 +237,9 @@ sqlite3_int64 sqlite3_memory_used(void){
|
||||
** or since the most recent reset.
|
||||
*/
|
||||
sqlite3_int64 sqlite3_memory_highwater(int resetFlag){
|
||||
int n, mx;
|
||||
sqlite3_int64 res;
|
||||
sqlite3_status(SQLITE_STATUS_MEMORY_USED, &n, &mx, resetFlag);
|
||||
res = (sqlite3_int64)mx; /* Work around bug in Borland C. Ticket #3216 */
|
||||
return res;
|
||||
sqlite3_int64 res, mx;
|
||||
sqlite3_status64(SQLITE_STATUS_MEMORY_USED, &res, &mx, resetFlag);
|
||||
return mx;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+15
-15
@@ -904,7 +904,7 @@ static struct vxworksFileId *vxworksFindFileId(const char *zAbsoluteName){
|
||||
|
||||
assert( zAbsoluteName[0]=='/' );
|
||||
n = (int)strlen(zAbsoluteName);
|
||||
pNew = sqlite3_malloc( sizeof(*pNew) + (n+1) );
|
||||
pNew = sqlite3_malloc64( sizeof(*pNew) + (n+1) );
|
||||
if( pNew==0 ) return 0;
|
||||
pNew->zCanonicalName = (char*)&pNew[1];
|
||||
memcpy(pNew->zCanonicalName, zAbsoluteName, n+1);
|
||||
@@ -1308,7 +1308,7 @@ static int findInodeInfo(
|
||||
pInode = pInode->pNext;
|
||||
}
|
||||
if( pInode==0 ){
|
||||
pInode = sqlite3_malloc( sizeof(*pInode) );
|
||||
pInode = sqlite3_malloc64( sizeof(*pInode) );
|
||||
if( pInode==0 ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
@@ -3829,7 +3829,7 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
case SQLITE_FCNTL_TEMPFILENAME: {
|
||||
char *zTFile = sqlite3_malloc( pFile->pVfs->mxPathname );
|
||||
char *zTFile = sqlite3_malloc64( pFile->pVfs->mxPathname );
|
||||
if( zTFile ){
|
||||
unixGetTempname(pFile->pVfs->mxPathname, zTFile);
|
||||
*(char**)pArg = zTFile;
|
||||
@@ -4270,7 +4270,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
|
||||
int nShmFilename; /* Size of the SHM filename in bytes */
|
||||
|
||||
/* Allocate space for the new unixShm object. */
|
||||
p = sqlite3_malloc( sizeof(*p) );
|
||||
p = sqlite3_malloc64( sizeof(*p) );
|
||||
if( p==0 ) return SQLITE_NOMEM;
|
||||
memset(p, 0, sizeof(*p));
|
||||
assert( pDbFd->pShm==0 );
|
||||
@@ -4301,7 +4301,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
|
||||
#else
|
||||
nShmFilename = 6 + (int)strlen(zBasePath);
|
||||
#endif
|
||||
pShmNode = sqlite3_malloc( sizeof(*pShmNode) + nShmFilename );
|
||||
pShmNode = sqlite3_malloc64( sizeof(*pShmNode) + nShmFilename );
|
||||
if( pShmNode==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
goto shm_open_err;
|
||||
@@ -4511,7 +4511,7 @@ static int unixShmMap(
|
||||
goto shmpage_out;
|
||||
}
|
||||
}else{
|
||||
pMem = sqlite3_malloc(szRegion);
|
||||
pMem = sqlite3_malloc64(szRegion);
|
||||
if( pMem==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
goto shmpage_out;
|
||||
@@ -5348,7 +5348,7 @@ static int fillInUnixFile(
|
||||
** the afpLockingContext.
|
||||
*/
|
||||
afpLockingContext *pCtx;
|
||||
pNew->lockingContext = pCtx = sqlite3_malloc( sizeof(*pCtx) );
|
||||
pNew->lockingContext = pCtx = sqlite3_malloc64( sizeof(*pCtx) );
|
||||
if( pCtx==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
@@ -5378,7 +5378,7 @@ static int fillInUnixFile(
|
||||
int nFilename;
|
||||
assert( zFilename!=0 );
|
||||
nFilename = (int)strlen(zFilename) + 6;
|
||||
zLockFile = (char *)sqlite3_malloc(nFilename);
|
||||
zLockFile = (char *)sqlite3_malloc64(nFilename);
|
||||
if( zLockFile==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
@@ -5755,7 +5755,7 @@ static int unixOpen(
|
||||
if( pUnused ){
|
||||
fd = pUnused->fd;
|
||||
}else{
|
||||
pUnused = sqlite3_malloc(sizeof(*pUnused));
|
||||
pUnused = sqlite3_malloc64(sizeof(*pUnused));
|
||||
if( !pUnused ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
@@ -6135,7 +6135,7 @@ static int unixRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){
|
||||
*/
|
||||
memset(zBuf, 0, nBuf);
|
||||
randomnessPid = osGetpid(0);
|
||||
#if !defined(SQLITE_TEST)
|
||||
#if !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS)
|
||||
{
|
||||
int fd, got;
|
||||
fd = robust_open("/dev/urandom", O_RDONLY, 0);
|
||||
@@ -6547,7 +6547,7 @@ static int proxyCreateUnixFile(
|
||||
if( pUnused ){
|
||||
fd = pUnused->fd;
|
||||
}else{
|
||||
pUnused = sqlite3_malloc(sizeof(*pUnused));
|
||||
pUnused = sqlite3_malloc64(sizeof(*pUnused));
|
||||
if( !pUnused ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
@@ -6580,7 +6580,7 @@ static int proxyCreateUnixFile(
|
||||
}
|
||||
}
|
||||
|
||||
pNew = (unixFile *)sqlite3_malloc(sizeof(*pNew));
|
||||
pNew = (unixFile *)sqlite3_malloc64(sizeof(*pNew));
|
||||
if( pNew==NULL ){
|
||||
rc = SQLITE_NOMEM;
|
||||
goto end_create_proxy;
|
||||
@@ -7042,7 +7042,7 @@ static int proxyReleaseConch(unixFile *pFile){
|
||||
|
||||
/*
|
||||
** Given the name of a database file, compute the name of its conch file.
|
||||
** Store the conch filename in memory obtained from sqlite3_malloc().
|
||||
** Store the conch filename in memory obtained from sqlite3_malloc64().
|
||||
** Make *pConchPath point to the new name. Return SQLITE_OK on success
|
||||
** or SQLITE_NOMEM if unable to obtain memory.
|
||||
**
|
||||
@@ -7058,7 +7058,7 @@ static int proxyCreateConchPathname(char *dbPath, char **pConchPath){
|
||||
|
||||
/* Allocate space for the conch filename and initialize the name to
|
||||
** the name of the original database file. */
|
||||
*pConchPath = conchPath = (char *)sqlite3_malloc(len + 8);
|
||||
*pConchPath = conchPath = (char *)sqlite3_malloc64(len + 8);
|
||||
if( conchPath==0 ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
@@ -7174,7 +7174,7 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) {
|
||||
OSTRACE(("TRANSPROXY %d for %s pid=%d\n", pFile->h,
|
||||
(lockPath ? lockPath : ":auto:"), osGetpid(0)));
|
||||
|
||||
pCtx = sqlite3_malloc( sizeof(*pCtx) );
|
||||
pCtx = sqlite3_malloc64( sizeof(*pCtx) );
|
||||
if( pCtx==0 ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
|
||||
+5
-5
@@ -3925,7 +3925,7 @@ static int winShmMap(
|
||||
}
|
||||
|
||||
/* Map the requested memory region into this processes address space. */
|
||||
apNew = (struct ShmRegion *)sqlite3_realloc(
|
||||
apNew = (struct ShmRegion *)sqlite3_realloc64(
|
||||
pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0])
|
||||
);
|
||||
if( !apNew ){
|
||||
@@ -5372,7 +5372,7 @@ static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
|
||||
static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
|
||||
int n = 0;
|
||||
UNUSED_PARAMETER(pVfs);
|
||||
#if defined(SQLITE_TEST)
|
||||
#if defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS)
|
||||
n = nBuf;
|
||||
memset(zBuf, 0, nBuf);
|
||||
#else
|
||||
@@ -5406,23 +5406,23 @@ static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
|
||||
memcpy(&zBuf[n], &i, sizeof(i));
|
||||
n += sizeof(i);
|
||||
}
|
||||
#endif
|
||||
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
|
||||
if( sizeof(UUID)<=nBuf-n ){
|
||||
UUID id;
|
||||
memset(&id, 0, sizeof(UUID));
|
||||
osUuidCreate(&id);
|
||||
memcpy(zBuf, &id, sizeof(UUID));
|
||||
memcpy(&zBuf[n], &id, sizeof(UUID));
|
||||
n += sizeof(UUID);
|
||||
}
|
||||
if( sizeof(UUID)<=nBuf-n ){
|
||||
UUID id;
|
||||
memset(&id, 0, sizeof(UUID));
|
||||
osUuidCreateSequential(&id);
|
||||
memcpy(zBuf, &id, sizeof(UUID));
|
||||
memcpy(&zBuf[n], &id, sizeof(UUID));
|
||||
n += sizeof(UUID);
|
||||
}
|
||||
#endif
|
||||
#endif /* defined(SQLITE_TEST) || defined(SQLITE_ZERO_PRNG_SEED) */
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
+2
-4
@@ -3044,9 +3044,7 @@ static int pagerWalFrames(
|
||||
){
|
||||
int rc; /* Return code */
|
||||
int nList; /* Number of pages in pList */
|
||||
#if defined(SQLITE_DEBUG) || defined(SQLITE_CHECK_PAGES)
|
||||
PgHdr *p; /* For looping over pages */
|
||||
#endif
|
||||
|
||||
assert( pPager->pWal );
|
||||
assert( pList );
|
||||
@@ -3063,7 +3061,6 @@ static int pagerWalFrames(
|
||||
** any pages with page numbers greater than nTruncate into the WAL file.
|
||||
** They will never be read by any client. So remove them from the pDirty
|
||||
** list here. */
|
||||
PgHdr *p;
|
||||
PgHdr **ppNext = &pList;
|
||||
nList = 0;
|
||||
for(p=pList; (*ppNext = p)!=0; p=p->pDirty){
|
||||
@@ -3083,7 +3080,6 @@ static int pagerWalFrames(
|
||||
pPager->pageSize, pList, nTruncate, isCommit, pPager->walSyncFlags
|
||||
);
|
||||
if( rc==SQLITE_OK && pPager->pBackup ){
|
||||
PgHdr *p;
|
||||
for(p=pList; p; p=p->pDirty){
|
||||
sqlite3BackupUpdate(pPager->pBackup, p->pgno, (u8 *)p->pData);
|
||||
}
|
||||
@@ -7014,6 +7010,8 @@ int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){
|
||||
}
|
||||
assert( state==pPager->eState );
|
||||
}
|
||||
}else if( eMode==PAGER_JOURNALMODE_OFF ){
|
||||
sqlite3OsClose(pPager->jfd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+28
-16
@@ -409,28 +409,35 @@ cmd ::= select(X). {
|
||||
%type oneselect {Select*}
|
||||
%destructor oneselect {sqlite3SelectDelete(pParse->db, $$);}
|
||||
|
||||
select(A) ::= with(W) selectnowith(X). {
|
||||
Select *p = X, *pNext, *pLoop;
|
||||
if( p ){
|
||||
int cnt = 0, mxSelect;
|
||||
p->pWith = W;
|
||||
%include {
|
||||
/*
|
||||
** For a compound SELECT statement, make sure p->pPrior->pNext==p for
|
||||
** all elements in the list. And make sure list length does not exceed
|
||||
** SQLITE_LIMIT_COMPOUND_SELECT.
|
||||
*/
|
||||
static void parserDoubleLinkSelect(Parse *pParse, Select *p){
|
||||
if( p->pPrior ){
|
||||
u16 allValues = SF_Values;
|
||||
pNext = 0;
|
||||
Select *pNext = 0, *pLoop;
|
||||
int mxSelect, cnt = 0;
|
||||
for(pLoop=p; pLoop; pNext=pLoop, pLoop=pLoop->pPrior, cnt++){
|
||||
pLoop->pNext = pNext;
|
||||
pLoop->selFlags |= SF_Compound;
|
||||
allValues &= pLoop->selFlags;
|
||||
}
|
||||
if( allValues ){
|
||||
p->selFlags |= SF_AllValues;
|
||||
}else if(
|
||||
(mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0
|
||||
&& cnt>mxSelect
|
||||
if( (p->selFlags & SF_MultiValue)==0 &&
|
||||
(mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 &&
|
||||
cnt>mxSelect
|
||||
){
|
||||
sqlite3ErrorMsg(pParse, "too many terms in compound SELECT");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
select(A) ::= with(W) selectnowith(X). {
|
||||
Select *p = X;
|
||||
if( p ){
|
||||
p->pWith = W;
|
||||
parserDoubleLinkSelect(pParse, p);
|
||||
}else{
|
||||
sqlite3WithDelete(pParse->db, W);
|
||||
}
|
||||
@@ -445,12 +452,14 @@ selectnowith(A) ::= selectnowith(X) multiselect_op(Y) oneselect(Z). {
|
||||
SrcList *pFrom;
|
||||
Token x;
|
||||
x.n = 0;
|
||||
parserDoubleLinkSelect(pParse, pRhs);
|
||||
pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0,0);
|
||||
pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0,0);
|
||||
}
|
||||
if( pRhs ){
|
||||
pRhs->op = (u8)Y;
|
||||
pRhs->pPrior = X;
|
||||
pRhs->selFlags &= ~SF_MultiValue;
|
||||
if( Y!=TK_ALL ) pParse->hasCompound = 1;
|
||||
}else{
|
||||
sqlite3SelectDelete(pParse->db, X);
|
||||
@@ -498,13 +507,16 @@ values(A) ::= VALUES LP nexprlist(X) RP. {
|
||||
A = sqlite3SelectNew(pParse,X,0,0,0,0,0,SF_Values,0,0);
|
||||
}
|
||||
values(A) ::= values(X) COMMA LP exprlist(Y) RP. {
|
||||
Select *pRight = sqlite3SelectNew(pParse,Y,0,0,0,0,0,SF_Values,0,0);
|
||||
Select *pRight, *pLeft = X;
|
||||
pRight = sqlite3SelectNew(pParse,Y,0,0,0,0,0,SF_Values|SF_MultiValue,0,0);
|
||||
if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue;
|
||||
if( pRight ){
|
||||
pRight->op = TK_ALL;
|
||||
pRight->pPrior = X;
|
||||
pLeft = X;
|
||||
pRight->pPrior = pLeft;
|
||||
A = pRight;
|
||||
}else{
|
||||
A = X;
|
||||
A = pLeft;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+9
-7
@@ -164,15 +164,15 @@ static int changeTempStorage(Parse *pParse, const char *zStorageType){
|
||||
*/
|
||||
static void returnSingleInt(Parse *pParse, const char *zLabel, i64 value){
|
||||
Vdbe *v = sqlite3GetVdbe(pParse);
|
||||
int mem = ++pParse->nMem;
|
||||
int nMem = ++pParse->nMem;
|
||||
i64 *pI64 = sqlite3DbMallocRaw(pParse->db, sizeof(value));
|
||||
if( pI64 ){
|
||||
memcpy(pI64, &value, sizeof(value));
|
||||
}
|
||||
sqlite3VdbeAddOp4(v, OP_Int64, 0, mem, 0, (char*)pI64, P4_INT64);
|
||||
sqlite3VdbeAddOp4(v, OP_Int64, 0, nMem, 0, (char*)pI64, P4_INT64);
|
||||
sqlite3VdbeSetNumCols(v, 1);
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, SQLITE_STATIC);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, nMem, 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -337,11 +337,11 @@ void sqlite3Pragma(
|
||||
rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl);
|
||||
if( rc==SQLITE_OK ){
|
||||
if( aFcntl[0] ){
|
||||
int mem = ++pParse->nMem;
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, mem, 0, aFcntl[0], 0);
|
||||
int nMem = ++pParse->nMem;
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, nMem, 0, aFcntl[0], 0);
|
||||
sqlite3VdbeSetNumCols(v, 1);
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "result", SQLITE_STATIC);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, nMem, 1);
|
||||
sqlite3_free(aFcntl[0]);
|
||||
}
|
||||
goto pragma_out;
|
||||
@@ -946,7 +946,9 @@ void sqlite3Pragma(
|
||||
sqlite3ErrorMsg(pParse,
|
||||
"Safety level may not be changed inside a transaction");
|
||||
}else{
|
||||
pDb->safety_level = getSafetyLevel(zRight,0,1)+1;
|
||||
int iLevel = (getSafetyLevel(zRight,0,1)+1) & PAGER_SYNCHRONOUS_MASK;
|
||||
if( iLevel==0 ) iLevel = 1;
|
||||
pDb->safety_level = iLevel;
|
||||
setAllPagerFlags(db);
|
||||
}
|
||||
}
|
||||
|
||||
+28
-33
@@ -138,6 +138,7 @@ static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
|
||||
** Set the StrAccum object to an error mode.
|
||||
*/
|
||||
static void setStrAccumError(StrAccum *p, u8 eError){
|
||||
assert( eError==STRACCUM_NOMEM || eError==STRACCUM_TOOBIG );
|
||||
p->accError = eError;
|
||||
p->nAlloc = 0;
|
||||
}
|
||||
@@ -252,7 +253,6 @@ void sqlite3VXPrintf(
|
||||
}
|
||||
}while( !done && (c=(*++fmt))!=0 );
|
||||
/* Get the field width */
|
||||
width = 0;
|
||||
if( c=='*' ){
|
||||
if( bArgList ){
|
||||
width = (int)getIntArg(pArgList);
|
||||
@@ -276,7 +276,6 @@ void sqlite3VXPrintf(
|
||||
|
||||
/* Get the precision */
|
||||
if( c=='.' ){
|
||||
precision = 0;
|
||||
c = *++fmt;
|
||||
if( c=='*' ){
|
||||
if( bArgList ){
|
||||
@@ -755,7 +754,7 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
|
||||
testcase(p->accError==STRACCUM_NOMEM);
|
||||
return 0;
|
||||
}
|
||||
if( !p->useMalloc ){
|
||||
if( p->mxAlloc==0 ){
|
||||
N = p->nAlloc - p->nChar - 1;
|
||||
setStrAccumError(p, STRACCUM_TOOBIG);
|
||||
return N;
|
||||
@@ -775,10 +774,10 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
|
||||
}else{
|
||||
p->nAlloc = (int)szNew;
|
||||
}
|
||||
if( p->useMalloc==1 ){
|
||||
if( p->db ){
|
||||
zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
|
||||
}else{
|
||||
zNew = sqlite3_realloc(zOld, p->nAlloc);
|
||||
zNew = sqlite3_realloc64(zOld, p->nAlloc);
|
||||
}
|
||||
if( zNew ){
|
||||
assert( p->zText!=0 || p->nChar==0 );
|
||||
@@ -855,12 +854,8 @@ void sqlite3StrAccumAppendAll(StrAccum *p, const char *z){
|
||||
char *sqlite3StrAccumFinish(StrAccum *p){
|
||||
if( p->zText ){
|
||||
p->zText[p->nChar] = 0;
|
||||
if( p->useMalloc && p->zText==p->zBase ){
|
||||
if( p->useMalloc==1 ){
|
||||
p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
|
||||
}else{
|
||||
p->zText = sqlite3_malloc(p->nChar+1);
|
||||
}
|
||||
if( p->mxAlloc>0 && p->zText==p->zBase ){
|
||||
p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
|
||||
if( p->zText ){
|
||||
memcpy(p->zText, p->zBase, p->nChar+1);
|
||||
}else{
|
||||
@@ -876,25 +871,31 @@ char *sqlite3StrAccumFinish(StrAccum *p){
|
||||
*/
|
||||
void sqlite3StrAccumReset(StrAccum *p){
|
||||
if( p->zText!=p->zBase ){
|
||||
if( p->useMalloc==1 ){
|
||||
sqlite3DbFree(p->db, p->zText);
|
||||
}else{
|
||||
sqlite3_free(p->zText);
|
||||
}
|
||||
sqlite3DbFree(p->db, p->zText);
|
||||
}
|
||||
p->zText = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Initialize a string accumulator
|
||||
** Initialize a string accumulator.
|
||||
**
|
||||
** p: The accumulator to be initialized.
|
||||
** db: Pointer to a database connection. May be NULL. Lookaside
|
||||
** memory is used if not NULL. db->mallocFailed is set appropriately
|
||||
** when not NULL.
|
||||
** zBase: An initial buffer. May be NULL in which case the initial buffer
|
||||
** is malloced.
|
||||
** n: Size of zBase in bytes. If total space requirements never exceed
|
||||
** n then no memory allocations ever occur.
|
||||
** mx: Maximum number of bytes to accumulate. If mx==0 then no memory
|
||||
** allocations will ever occur.
|
||||
*/
|
||||
void sqlite3StrAccumInit(StrAccum *p, char *zBase, int n, int mx){
|
||||
void sqlite3StrAccumInit(StrAccum *p, sqlite3 *db, char *zBase, int n, int mx){
|
||||
p->zText = p->zBase = zBase;
|
||||
p->db = 0;
|
||||
p->db = db;
|
||||
p->nChar = 0;
|
||||
p->nAlloc = n;
|
||||
p->mxAlloc = mx;
|
||||
p->useMalloc = 1;
|
||||
p->accError = 0;
|
||||
}
|
||||
|
||||
@@ -907,9 +908,8 @@ char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){
|
||||
char zBase[SQLITE_PRINT_BUF_SIZE];
|
||||
StrAccum acc;
|
||||
assert( db!=0 );
|
||||
sqlite3StrAccumInit(&acc, zBase, sizeof(zBase),
|
||||
sqlite3StrAccumInit(&acc, db, zBase, sizeof(zBase),
|
||||
db->aLimit[SQLITE_LIMIT_LENGTH]);
|
||||
acc.db = db;
|
||||
sqlite3VXPrintf(&acc, SQLITE_PRINTF_INTERNAL, zFormat, ap);
|
||||
z = sqlite3StrAccumFinish(&acc);
|
||||
if( acc.accError==STRACCUM_NOMEM ){
|
||||
@@ -967,8 +967,7 @@ char *sqlite3_vmprintf(const char *zFormat, va_list ap){
|
||||
#ifndef SQLITE_OMIT_AUTOINIT
|
||||
if( sqlite3_initialize() ) return 0;
|
||||
#endif
|
||||
sqlite3StrAccumInit(&acc, zBase, sizeof(zBase), SQLITE_MAX_LENGTH);
|
||||
acc.useMalloc = 2;
|
||||
sqlite3StrAccumInit(&acc, 0, zBase, sizeof(zBase), SQLITE_MAX_LENGTH);
|
||||
sqlite3VXPrintf(&acc, 0, zFormat, ap);
|
||||
z = sqlite3StrAccumFinish(&acc);
|
||||
return z;
|
||||
@@ -1013,8 +1012,7 @@ char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){
|
||||
return zBuf;
|
||||
}
|
||||
#endif
|
||||
sqlite3StrAccumInit(&acc, zBuf, n, 0);
|
||||
acc.useMalloc = 0;
|
||||
sqlite3StrAccumInit(&acc, 0, zBuf, n, 0);
|
||||
sqlite3VXPrintf(&acc, 0, zFormat, ap);
|
||||
return sqlite3StrAccumFinish(&acc);
|
||||
}
|
||||
@@ -1040,8 +1038,7 @@ static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){
|
||||
StrAccum acc; /* String accumulator */
|
||||
char zMsg[SQLITE_PRINT_BUF_SIZE*3]; /* Complete log message */
|
||||
|
||||
sqlite3StrAccumInit(&acc, zMsg, sizeof(zMsg), 0);
|
||||
acc.useMalloc = 0;
|
||||
sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0);
|
||||
sqlite3VXPrintf(&acc, 0, zFormat, ap);
|
||||
sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode,
|
||||
sqlite3StrAccumFinish(&acc));
|
||||
@@ -1069,8 +1066,7 @@ void sqlite3DebugPrintf(const char *zFormat, ...){
|
||||
va_list ap;
|
||||
StrAccum acc;
|
||||
char zBuf[500];
|
||||
sqlite3StrAccumInit(&acc, zBuf, sizeof(zBuf), 0);
|
||||
acc.useMalloc = 0;
|
||||
sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
|
||||
va_start(ap,zFormat);
|
||||
sqlite3VXPrintf(&acc, 0, zFormat, ap);
|
||||
va_end(ap);
|
||||
@@ -1097,7 +1093,7 @@ void sqlite3DebugPrintf(const char *zFormat, ...){
|
||||
** is not the last item in the tree. */
|
||||
TreeView *sqlite3TreeViewPush(TreeView *p, u8 moreToFollow){
|
||||
if( p==0 ){
|
||||
p = sqlite3_malloc( sizeof(*p) );
|
||||
p = sqlite3_malloc64( sizeof(*p) );
|
||||
if( p==0 ) return 0;
|
||||
memset(p, 0, sizeof(*p));
|
||||
}else{
|
||||
@@ -1120,8 +1116,7 @@ void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){
|
||||
int i;
|
||||
StrAccum acc;
|
||||
char zBuf[500];
|
||||
sqlite3StrAccumInit(&acc, zBuf, sizeof(zBuf), 0);
|
||||
acc.useMalloc = 0;
|
||||
sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
|
||||
if( p ){
|
||||
for(i=0; i<p->iLevel && i<sizeof(p->bLine)-1; i++){
|
||||
sqlite3StrAccumAppend(&acc, p->bLine[i] ? "| " : " ", 4);
|
||||
|
||||
+9
-4
@@ -79,7 +79,7 @@ static void incrAggFunctionDepth(Expr *pExpr, int N){
|
||||
** SELECT a+b, c+d FROM t1 ORDER BY (a+b) COLLATE nocase;
|
||||
**
|
||||
** The nSubquery parameter specifies how many levels of subquery the
|
||||
** alias is removed from the original expression. The usually value is
|
||||
** alias is removed from the original expression. The usual value is
|
||||
** zero but it might be more if the alias is contained within a subquery
|
||||
** of the original expression. The Expr.op2 field of TK_AGG_FUNCTION
|
||||
** structures must be increased by the nSubquery amount.
|
||||
@@ -99,7 +99,6 @@ static void resolveAlias(
|
||||
assert( iCol>=0 && iCol<pEList->nExpr );
|
||||
pOrig = pEList->a[iCol].pExpr;
|
||||
assert( pOrig!=0 );
|
||||
assert( pOrig->flags & EP_Resolved );
|
||||
db = pParse->db;
|
||||
pDup = sqlite3ExprDup(db, pOrig, 0);
|
||||
if( pDup==0 ) return;
|
||||
@@ -460,7 +459,6 @@ static int lookupName(
|
||||
if( cnt==0 && zTab==0 && ExprHasProperty(pExpr,EP_DblQuoted) ){
|
||||
pExpr->op = TK_STRING;
|
||||
pExpr->pTab = 0;
|
||||
pExpr->iTable = -1;
|
||||
return WRC_Prune;
|
||||
}
|
||||
|
||||
@@ -1300,8 +1298,15 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
|
||||
** The ORDER BY clause for compounds SELECT statements is handled
|
||||
** below, after all of the result-sets for all of the elements of
|
||||
** the compound have been resolved.
|
||||
**
|
||||
** If there is an ORDER BY clause on a term of a compound-select other
|
||||
** than the right-most term, then that is a syntax error. But the error
|
||||
** is not detected until much later, and so we need to go ahead and
|
||||
** resolve those symbols on the incorrect ORDER BY for consistency.
|
||||
*/
|
||||
if( !isCompound && resolveOrderGroupBy(&sNC, p, p->pOrderBy, "ORDER") ){
|
||||
if( isCompound<=nCompound /* Defer right-most ORDER BY of a compound */
|
||||
&& resolveOrderGroupBy(&sNC, p, p->pOrderBy, "ORDER")
|
||||
){
|
||||
return WRC_Abort;
|
||||
}
|
||||
if( db->mallocFailed ){
|
||||
|
||||
+22
-20
@@ -111,7 +111,6 @@ Select *sqlite3SelectNew(
|
||||
Select standin;
|
||||
sqlite3 *db = pParse->db;
|
||||
pNew = sqlite3DbMallocZero(db, sizeof(*pNew) );
|
||||
assert( db->mallocFailed || !pOffset || pLimit ); /* OFFSET implies LIMIT */
|
||||
if( pNew==0 ){
|
||||
assert( db->mallocFailed );
|
||||
pNew = &standin;
|
||||
@@ -131,7 +130,7 @@ Select *sqlite3SelectNew(
|
||||
pNew->op = TK_SELECT;
|
||||
pNew->pLimit = pLimit;
|
||||
pNew->pOffset = pOffset;
|
||||
assert( pOffset==0 || pLimit!=0 );
|
||||
assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || db->mallocFailed!=0 );
|
||||
pNew->addrOpenEphm[0] = -1;
|
||||
pNew->addrOpenEphm[1] = -1;
|
||||
if( db->mallocFailed ) {
|
||||
@@ -1381,7 +1380,7 @@ static const char *columnTypeImpl(
|
||||
** of the SELECT statement. Return the declaration type and origin
|
||||
** data for the result-set column of the sub-select.
|
||||
*/
|
||||
if( iCol>=0 && ALWAYS(iCol<pS->pEList->nExpr) ){
|
||||
if( iCol>=0 && iCol<pS->pEList->nExpr ){
|
||||
/* If iCol is less than zero, then the expression requests the
|
||||
** rowid of the sub-select or view. This expression is legal (see
|
||||
** test case misc2.2.2) - it always evaluates to NULL.
|
||||
@@ -1701,12 +1700,14 @@ static void selectAddColumnTypeAndCollation(
|
||||
a = pSelect->pEList->a;
|
||||
for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
|
||||
p = a[i].pExpr;
|
||||
pCol->zType = sqlite3DbStrDup(db, columnType(&sNC, p,0,0,0, &pCol->szEst));
|
||||
if( pCol->zType==0 ){
|
||||
pCol->zType = sqlite3DbStrDup(db, columnType(&sNC, p,0,0,0, &pCol->szEst));
|
||||
}
|
||||
szAll += pCol->szEst;
|
||||
pCol->affinity = sqlite3ExprAffinity(p);
|
||||
if( pCol->affinity==0 ) pCol->affinity = SQLITE_AFF_NONE;
|
||||
pColl = sqlite3ExprCollSeq(pParse, p);
|
||||
if( pColl ){
|
||||
if( pColl && pCol->zColl==0 ){
|
||||
pCol->zColl = sqlite3DbStrDup(db, pColl->zName);
|
||||
}
|
||||
}
|
||||
@@ -2108,8 +2109,7 @@ static int multiSelectValues(
|
||||
int nExpr = p->pEList->nExpr;
|
||||
int nRow = 1;
|
||||
int rc = 0;
|
||||
assert( p->pNext==0 );
|
||||
assert( p->selFlags & SF_AllValues );
|
||||
assert( p->selFlags & SF_MultiValue );
|
||||
do{
|
||||
assert( p->selFlags & SF_Values );
|
||||
assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) );
|
||||
@@ -2218,7 +2218,7 @@ static int multiSelect(
|
||||
|
||||
/* Special handling for a compound-select that originates as a VALUES clause.
|
||||
*/
|
||||
if( p->selFlags & SF_AllValues ){
|
||||
if( p->selFlags & SF_MultiValue ){
|
||||
rc = multiSelectValues(pParse, p, &dest);
|
||||
goto multi_select_end;
|
||||
}
|
||||
@@ -2603,7 +2603,7 @@ static int generateOutputSubroutine(
|
||||
*/
|
||||
case SRT_Set: {
|
||||
int r1;
|
||||
assert( pIn->nSdst==1 );
|
||||
assert( pIn->nSdst==1 || pParse->nErr>0 );
|
||||
pDest->affSdst =
|
||||
sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affSdst);
|
||||
r1 = sqlite3GetTempReg(pParse);
|
||||
@@ -2629,7 +2629,7 @@ static int generateOutputSubroutine(
|
||||
** of the scan loop.
|
||||
*/
|
||||
case SRT_Mem: {
|
||||
assert( pIn->nSdst==1 );
|
||||
assert( pIn->nSdst==1 || pParse->nErr>0 ); testcase( pIn->nSdst!=1 );
|
||||
sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, 1);
|
||||
/* The LIMIT clause will jump out of the loop for us */
|
||||
break;
|
||||
@@ -2644,7 +2644,7 @@ static int generateOutputSubroutine(
|
||||
pDest->iSdst = sqlite3GetTempRange(pParse, pIn->nSdst);
|
||||
pDest->nSdst = pIn->nSdst;
|
||||
}
|
||||
sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSdst, pDest->nSdst);
|
||||
sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSdst, pIn->nSdst);
|
||||
sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
|
||||
break;
|
||||
}
|
||||
@@ -2860,8 +2860,10 @@ static int multiSelectOrderBy(
|
||||
if( aPermute ){
|
||||
struct ExprList_item *pItem;
|
||||
for(i=0, pItem=pOrderBy->a; i<nOrderBy; i++, pItem++){
|
||||
assert( pItem->u.x.iOrderByCol>0
|
||||
&& pItem->u.x.iOrderByCol<=p->pEList->nExpr );
|
||||
assert( pItem->u.x.iOrderByCol>0 );
|
||||
/* assert( pItem->u.x.iOrderByCol<=p->pEList->nExpr ) is also true
|
||||
** but only for well-formed SELECT statements. */
|
||||
testcase( pItem->u.x.iOrderByCol > p->pEList->nExpr );
|
||||
aPermute[i] = pItem->u.x.iOrderByCol - 1;
|
||||
}
|
||||
pKeyMerge = multiSelectOrderByKeyInfo(pParse, p, 1);
|
||||
@@ -4422,7 +4424,7 @@ static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
|
||||
sqlite3WalkSelect(&w, pSelect);
|
||||
}
|
||||
w.xSelectCallback = selectExpander;
|
||||
if( (pSelect->selFlags & SF_AllValues)==0 ){
|
||||
if( (pSelect->selFlags & SF_MultiValue)==0 ){
|
||||
w.xSelectCallback2 = selectPopWith;
|
||||
}
|
||||
sqlite3WalkSelect(&w, pSelect);
|
||||
@@ -4608,7 +4610,8 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
|
||||
}
|
||||
if( pF->iDistinct>=0 ){
|
||||
addrNext = sqlite3VdbeMakeLabel(v);
|
||||
assert( nArg==1 );
|
||||
testcase( nArg==0 ); /* Error condition */
|
||||
testcase( nArg>1 ); /* Also an error */
|
||||
codeDistinct(pParse, pF->iDistinct, addrNext, 1, regAgg);
|
||||
}
|
||||
if( pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
|
||||
@@ -5483,10 +5486,9 @@ int sqlite3Select(
|
||||
*/
|
||||
sqlite3VdbeResolveLabel(v, iEnd);
|
||||
|
||||
/* The SELECT was successfully coded. Set the return code to 0
|
||||
** to indicate no errors.
|
||||
*/
|
||||
rc = 0;
|
||||
/* The SELECT has been coded. If there is an error in the Parse structure,
|
||||
** set the return code to 1. Otherwise 0. */
|
||||
rc = (pParse->nErr>0);
|
||||
|
||||
/* Control jumps to here if an error is encountered above, or upon
|
||||
** successful coding of the SELECT.
|
||||
@@ -5537,7 +5539,7 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
|
||||
struct SrcList_item *pItem = &p->pSrc->a[i];
|
||||
StrAccum x;
|
||||
char zLine[100];
|
||||
sqlite3StrAccumInit(&x, zLine, sizeof(zLine), 0);
|
||||
sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
|
||||
sqlite3XPrintf(&x, 0, "{%d,*}", pItem->iCursor);
|
||||
if( pItem->zDatabase ){
|
||||
sqlite3XPrintf(&x, 0, " %s.%s", pItem->zDatabase, pItem->zName);
|
||||
|
||||
+174
-65
@@ -336,7 +336,7 @@ static int stdin_is_interactive = 1;
|
||||
** to this database a static variable so that it can be accessed
|
||||
** by the SIGINT handler to interrupt database processing.
|
||||
*/
|
||||
static sqlite3 *db = 0;
|
||||
static sqlite3 *globalDb = 0;
|
||||
|
||||
/*
|
||||
** True if an interrupt (Control-C) has been received.
|
||||
@@ -527,6 +527,7 @@ struct ShellState {
|
||||
int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
|
||||
int statsOn; /* True to display memory stats before each finalize */
|
||||
int scanstatsOn; /* True to display scan stats before each finalize */
|
||||
int backslashOn; /* Resolve C-style \x escapes in SQL input text */
|
||||
int outCount; /* Revert to stdout when reaching zero */
|
||||
int cnt; /* Number of records displayed so far */
|
||||
FILE *out; /* Write results here */
|
||||
@@ -804,7 +805,7 @@ static void interrupt_handler(int NotUsed){
|
||||
UNUSED_PARAMETER(NotUsed);
|
||||
seenInterrupt++;
|
||||
if( seenInterrupt>2 ) exit(1);
|
||||
if( db ) sqlite3_interrupt(db);
|
||||
if( globalDb ) sqlite3_interrupt(globalDb);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -989,7 +990,16 @@ static int shell_callback(
|
||||
case MODE_Insert: {
|
||||
p->cnt++;
|
||||
if( azArg==0 ) break;
|
||||
fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
|
||||
fprintf(p->out,"INSERT INTO %s",p->zDestTable);
|
||||
if( p->showHeader ){
|
||||
fprintf(p->out,"(");
|
||||
for(i=0; i<nArg; i++){
|
||||
char *zSep = i>0 ? ",": "";
|
||||
fprintf(p->out, "%s%s", zSep, azCol[i]);
|
||||
}
|
||||
fprintf(p->out,")");
|
||||
}
|
||||
fprintf(p->out," VALUES(");
|
||||
for(i=0; i<nArg; i++){
|
||||
char *zSep = i>0 ? ",": "";
|
||||
if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
|
||||
@@ -1190,7 +1200,7 @@ static char *save_err_msg(
|
||||
sqlite3 *db /* Database to query */
|
||||
){
|
||||
int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
|
||||
char *zErrMsg = sqlite3_malloc(nErrMsg);
|
||||
char *zErrMsg = sqlite3_malloc64(nErrMsg);
|
||||
if( zErrMsg ){
|
||||
memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
|
||||
}
|
||||
@@ -1427,8 +1437,8 @@ static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
|
||||
/* Grow the p->aiIndent array as required */
|
||||
if( iOp>=nAlloc ){
|
||||
nAlloc += 100;
|
||||
p->aiIndent = (int*)sqlite3_realloc(p->aiIndent, nAlloc*sizeof(int));
|
||||
abYield = (int*)sqlite3_realloc(abYield, nAlloc*sizeof(int));
|
||||
p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int));
|
||||
abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
|
||||
}
|
||||
abYield[iOp] = str_in_array(zOp, azYield);
|
||||
p->aiIndent[iOp] = 0;
|
||||
@@ -1545,7 +1555,7 @@ static int shell_exec(
|
||||
if( xCallback ){
|
||||
/* allocate space for col name ptr, value ptr, and type */
|
||||
int nCol = sqlite3_column_count(pStmt);
|
||||
void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
|
||||
void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1);
|
||||
if( !pData ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
@@ -1771,6 +1781,7 @@ static int run_schema_dump_query(
|
||||
static char zHelp[] =
|
||||
".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
|
||||
".bail on|off Stop after hitting an error. Default OFF\n"
|
||||
".binary on|off Turn binary output on or off. Default OFF\n"
|
||||
".clone NEWDB Clone data into NEWDB from the existing database\n"
|
||||
".databases List names and files of attached databases\n"
|
||||
".dbinfo ?DB? Show status information about the database\n"
|
||||
@@ -1792,6 +1803,7 @@ static char zHelp[] =
|
||||
#ifdef SQLITE_ENABLE_IOTRACE
|
||||
".iotrace FILE Enable I/O diagnostic logging to FILE\n"
|
||||
#endif
|
||||
".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n"
|
||||
#ifndef SQLITE_OMIT_LOAD_EXTENSION
|
||||
".load FILE ?ENTRY? Load an extension library\n"
|
||||
#endif
|
||||
@@ -1861,7 +1873,7 @@ static void readfileFunc(
|
||||
fseek(in, 0, SEEK_END);
|
||||
nIn = ftell(in);
|
||||
rewind(in);
|
||||
pBuf = sqlite3_malloc( nIn );
|
||||
pBuf = sqlite3_malloc64( nIn );
|
||||
if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
|
||||
sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
|
||||
}else{
|
||||
@@ -1908,23 +1920,23 @@ static void open_db(ShellState *p, int keepAlive){
|
||||
if( p->db==0 ){
|
||||
sqlite3_initialize();
|
||||
sqlite3_open(p->zDbFilename, &p->db);
|
||||
db = p->db;
|
||||
if( db && sqlite3_errcode(db)==SQLITE_OK ){
|
||||
sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
|
||||
globalDb = p->db;
|
||||
if( p->db && sqlite3_errcode(p->db)==SQLITE_OK ){
|
||||
sqlite3_create_function(p->db, "shellstatic", 0, SQLITE_UTF8, 0,
|
||||
shellstaticFunc, 0, 0);
|
||||
}
|
||||
if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
|
||||
if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
|
||||
fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
|
||||
p->zDbFilename, sqlite3_errmsg(db));
|
||||
p->zDbFilename, sqlite3_errmsg(p->db));
|
||||
if( keepAlive ) return;
|
||||
exit(1);
|
||||
}
|
||||
#ifndef SQLITE_OMIT_LOAD_EXTENSION
|
||||
sqlite3_enable_load_extension(p->db, 1);
|
||||
#endif
|
||||
sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0,
|
||||
sqlite3_create_function(p->db, "readfile", 1, SQLITE_UTF8, 0,
|
||||
readfileFunc, 0, 0);
|
||||
sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0,
|
||||
sqlite3_create_function(p->db, "writefile", 2, SQLITE_UTF8, 0,
|
||||
writefileFunc, 0, 0);
|
||||
}
|
||||
}
|
||||
@@ -1932,12 +1944,18 @@ static void open_db(ShellState *p, int keepAlive){
|
||||
/*
|
||||
** Do C-language style dequoting.
|
||||
**
|
||||
** \a -> alarm
|
||||
** \b -> backspace
|
||||
** \t -> tab
|
||||
** \n -> newline
|
||||
** \v -> vertical tab
|
||||
** \f -> form feed
|
||||
** \r -> carriage return
|
||||
** \s -> space
|
||||
** \" -> "
|
||||
** \NNN -> ascii character NNN in octal
|
||||
** \' -> '
|
||||
** \\ -> backslash
|
||||
** \NNN -> ascii character NNN in octal
|
||||
*/
|
||||
static void resolve_backslashes(char *z){
|
||||
int i, j;
|
||||
@@ -1946,12 +1964,24 @@ static void resolve_backslashes(char *z){
|
||||
for(i=j=0; (c = z[i])!=0; i++, j++){
|
||||
if( c=='\\' && z[i+1]!=0 ){
|
||||
c = z[++i];
|
||||
if( c=='n' ){
|
||||
c = '\n';
|
||||
if( c=='a' ){
|
||||
c = '\a';
|
||||
}else if( c=='b' ){
|
||||
c = '\b';
|
||||
}else if( c=='t' ){
|
||||
c = '\t';
|
||||
}else if( c=='n' ){
|
||||
c = '\n';
|
||||
}else if( c=='v' ){
|
||||
c = '\v';
|
||||
}else if( c=='f' ){
|
||||
c = '\f';
|
||||
}else if( c=='r' ){
|
||||
c = '\r';
|
||||
}else if( c=='"' ){
|
||||
c = '"';
|
||||
}else if( c=='\'' ){
|
||||
c = '\'';
|
||||
}else if( c=='\\' ){
|
||||
c = '\\';
|
||||
}else if( c>='0' && c<='7' ){
|
||||
@@ -2121,7 +2151,7 @@ struct ImportCtx {
|
||||
static void import_append_char(ImportCtx *p, int c){
|
||||
if( p->n+1>=p->nAlloc ){
|
||||
p->nAlloc += p->nAlloc + 100;
|
||||
p->z = sqlite3_realloc(p->z, p->nAlloc);
|
||||
p->z = sqlite3_realloc64(p->z, p->nAlloc);
|
||||
if( p->z==0 ){
|
||||
fprintf(stderr, "out of memory\n");
|
||||
exit(1);
|
||||
@@ -2135,7 +2165,7 @@ static void import_append_char(ImportCtx *p, int c){
|
||||
**
|
||||
** + Input comes from p->in.
|
||||
** + Store results in p->z of length p->n. Space to hold p->z comes
|
||||
** from sqlite3_malloc().
|
||||
** from sqlite3_malloc64().
|
||||
** + Use p->cSep as the column separator. The default is ",".
|
||||
** + Use p->rSep as the row separator. The default is "\n".
|
||||
** + Keep track of the line number in p->nLine.
|
||||
@@ -2209,7 +2239,7 @@ static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){
|
||||
**
|
||||
** + Input comes from p->in.
|
||||
** + Store results in p->z of length p->n. Space to hold p->z comes
|
||||
** from sqlite3_malloc().
|
||||
** from sqlite3_malloc64().
|
||||
** + Use p->cSep as the column separator. The default is "\x1F".
|
||||
** + Use p->rSep as the row separator. The default is "\x1E".
|
||||
** + Keep track of the row number in p->nLine.
|
||||
@@ -2269,7 +2299,7 @@ static void tryToCloneData(
|
||||
goto end_data_xfer;
|
||||
}
|
||||
n = sqlite3_column_count(pQuery);
|
||||
zInsert = sqlite3_malloc(200 + nTable + n*3);
|
||||
zInsert = sqlite3_malloc64(200 + nTable + n*3);
|
||||
if( zInsert==0 ){
|
||||
fprintf(stderr, "out of memory\n");
|
||||
goto end_data_xfer;
|
||||
@@ -2585,7 +2615,7 @@ static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
|
||||
** Return 1 on error, 2 to exit, and 0 otherwise.
|
||||
*/
|
||||
static int do_meta_command(char *zLine, ShellState *p){
|
||||
int i = 1;
|
||||
int h = 1;
|
||||
int nArg = 0;
|
||||
int n, c;
|
||||
int rc = 0;
|
||||
@@ -2593,24 +2623,24 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
|
||||
/* Parse the input line into tokens.
|
||||
*/
|
||||
while( zLine[i] && nArg<ArraySize(azArg) ){
|
||||
while( IsSpace(zLine[i]) ){ i++; }
|
||||
if( zLine[i]==0 ) break;
|
||||
if( zLine[i]=='\'' || zLine[i]=='"' ){
|
||||
int delim = zLine[i++];
|
||||
azArg[nArg++] = &zLine[i];
|
||||
while( zLine[i] && zLine[i]!=delim ){
|
||||
if( zLine[i]=='\\' && delim=='"' && zLine[i+1]!=0 ) i++;
|
||||
i++;
|
||||
while( zLine[h] && nArg<ArraySize(azArg) ){
|
||||
while( IsSpace(zLine[h]) ){ h++; }
|
||||
if( zLine[h]==0 ) break;
|
||||
if( zLine[h]=='\'' || zLine[h]=='"' ){
|
||||
int delim = zLine[h++];
|
||||
azArg[nArg++] = &zLine[h];
|
||||
while( zLine[h] && zLine[h]!=delim ){
|
||||
if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
|
||||
h++;
|
||||
}
|
||||
if( zLine[i]==delim ){
|
||||
zLine[i++] = 0;
|
||||
if( zLine[h]==delim ){
|
||||
zLine[h++] = 0;
|
||||
}
|
||||
if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
|
||||
}else{
|
||||
azArg[nArg++] = &zLine[i];
|
||||
while( zLine[i] && !IsSpace(zLine[i]) ){ i++; }
|
||||
if( zLine[i] ) zLine[i++] = 0;
|
||||
azArg[nArg++] = &zLine[h];
|
||||
while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
|
||||
if( zLine[h] ) zLine[h++] = 0;
|
||||
resolve_backslashes(azArg[nArg-1]);
|
||||
}
|
||||
}
|
||||
@@ -2685,6 +2715,19 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}
|
||||
}else
|
||||
|
||||
if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){
|
||||
if( nArg==2 ){
|
||||
if( booleanValue(azArg[1]) ){
|
||||
setBinaryMode(p->out);
|
||||
}else{
|
||||
setTextMode(p->out);
|
||||
}
|
||||
}else{
|
||||
fprintf(stderr, "Usage: .binary on|off\n");
|
||||
rc = 1;
|
||||
}
|
||||
}else
|
||||
|
||||
/* The undocumented ".breakpoint" command causes a call to the no-op
|
||||
** routine named test_breakpoint().
|
||||
*/
|
||||
@@ -2986,7 +3029,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
nByte = strlen30(zSql);
|
||||
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
|
||||
import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
|
||||
if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){
|
||||
if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
|
||||
char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
|
||||
char cSep = '(';
|
||||
while( xRead(&sCtx) ){
|
||||
@@ -3006,7 +3049,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
sqlite3_free(zCreate);
|
||||
if( rc ){
|
||||
fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
|
||||
sqlite3_errmsg(db));
|
||||
sqlite3_errmsg(p->db));
|
||||
sqlite3_free(sCtx.z);
|
||||
xCloser(sCtx.in);
|
||||
return 1;
|
||||
@@ -3016,7 +3059,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
sqlite3_free(zSql);
|
||||
if( rc ){
|
||||
if (pStmt) sqlite3_finalize(pStmt);
|
||||
fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
|
||||
fprintf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
|
||||
xCloser(sCtx.in);
|
||||
return 1;
|
||||
}
|
||||
@@ -3024,7 +3067,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
sqlite3_finalize(pStmt);
|
||||
pStmt = 0;
|
||||
if( nCol==0 ) return 0; /* no columns, no error */
|
||||
zSql = sqlite3_malloc( nByte*2 + 20 + nCol*2 );
|
||||
zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
|
||||
if( zSql==0 ){
|
||||
fprintf(stderr, "Error: out of memory\n");
|
||||
xCloser(sCtx.in);
|
||||
@@ -3041,13 +3084,13 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
|
||||
sqlite3_free(zSql);
|
||||
if( rc ){
|
||||
fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
|
||||
fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
|
||||
if (pStmt) sqlite3_finalize(pStmt);
|
||||
xCloser(sCtx.in);
|
||||
return 1;
|
||||
}
|
||||
needCommit = sqlite3_get_autocommit(db);
|
||||
if( needCommit ) sqlite3_exec(db, "BEGIN", 0, 0, 0);
|
||||
needCommit = sqlite3_get_autocommit(p->db);
|
||||
if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
|
||||
do{
|
||||
int startLine = sCtx.nLine;
|
||||
for(i=0; i<nCol; i++){
|
||||
@@ -3086,7 +3129,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
rc = sqlite3_reset(pStmt);
|
||||
if( rc!=SQLITE_OK ){
|
||||
fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile, startLine,
|
||||
sqlite3_errmsg(db));
|
||||
sqlite3_errmsg(p->db));
|
||||
}
|
||||
}
|
||||
}while( sCtx.cTerm!=EOF );
|
||||
@@ -3094,7 +3137,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
xCloser(sCtx.in);
|
||||
sqlite3_free(sCtx.z);
|
||||
sqlite3_finalize(pStmt);
|
||||
if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0);
|
||||
if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
|
||||
}else
|
||||
|
||||
if( c=='i' && (strncmp(azArg[0], "indices", n)==0
|
||||
@@ -3164,6 +3207,64 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}
|
||||
}else
|
||||
#endif
|
||||
if( c=='l' && n>=5 && strncmp(azArg[0], "limits", n)==0 ){
|
||||
static const struct {
|
||||
const char *zLimitName; /* Name of a limit */
|
||||
int limitCode; /* Integer code for that limit */
|
||||
} aLimit[] = {
|
||||
{ "length", SQLITE_LIMIT_LENGTH },
|
||||
{ "sql_length", SQLITE_LIMIT_SQL_LENGTH },
|
||||
{ "column", SQLITE_LIMIT_COLUMN },
|
||||
{ "expr_depth", SQLITE_LIMIT_EXPR_DEPTH },
|
||||
{ "compound_select", SQLITE_LIMIT_COMPOUND_SELECT },
|
||||
{ "vdbe_op", SQLITE_LIMIT_VDBE_OP },
|
||||
{ "function_arg", SQLITE_LIMIT_FUNCTION_ARG },
|
||||
{ "attached", SQLITE_LIMIT_ATTACHED },
|
||||
{ "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH },
|
||||
{ "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER },
|
||||
{ "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH },
|
||||
{ "worker_threads", SQLITE_LIMIT_WORKER_THREADS },
|
||||
};
|
||||
int i, n2;
|
||||
open_db(p, 0);
|
||||
if( nArg==1 ){
|
||||
for(i=0; i<sizeof(aLimit)/sizeof(aLimit[0]); i++){
|
||||
printf("%20s %d\n", aLimit[i].zLimitName,
|
||||
sqlite3_limit(p->db, aLimit[i].limitCode, -1));
|
||||
}
|
||||
}else if( nArg>3 ){
|
||||
fprintf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n");
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}else{
|
||||
int iLimit = -1;
|
||||
n2 = strlen30(azArg[1]);
|
||||
for(i=0; i<sizeof(aLimit)/sizeof(aLimit[0]); i++){
|
||||
if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){
|
||||
if( iLimit<0 ){
|
||||
iLimit = i;
|
||||
}else{
|
||||
fprintf(stderr, "ambiguous limit: \"%s\"\n", azArg[1]);
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( iLimit<0 ){
|
||||
fprintf(stderr, "unknown limit: \"%s\"\n"
|
||||
"enter \".limits\" with no arguments for a list.\n",
|
||||
azArg[1]);
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}
|
||||
if( nArg==3 ){
|
||||
sqlite3_limit(p->db, aLimit[iLimit].limitCode,
|
||||
(int)integerValue(azArg[2]));
|
||||
}
|
||||
printf("%20s %d\n", aLimit[iLimit].zLimitName,
|
||||
sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
|
||||
}
|
||||
}else
|
||||
|
||||
#ifndef SQLITE_OMIT_LOAD_EXTENSION
|
||||
if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
|
||||
@@ -3648,13 +3749,13 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
while( sqlite3_step(pStmt)==SQLITE_ROW ){
|
||||
if( nRow>=nAlloc ){
|
||||
char **azNew;
|
||||
int n = nAlloc*2 + 10;
|
||||
azNew = sqlite3_realloc(azResult, sizeof(azResult[0])*n);
|
||||
int n2 = nAlloc*2 + 10;
|
||||
azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2);
|
||||
if( azNew==0 ){
|
||||
fprintf(stderr, "Error: out of memory\n");
|
||||
break;
|
||||
}
|
||||
nAlloc = n;
|
||||
nAlloc = n2;
|
||||
azResult = azNew;
|
||||
}
|
||||
azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
|
||||
@@ -3707,15 +3808,15 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
{ "imposter", SQLITE_TESTCTRL_IMPOSTER },
|
||||
};
|
||||
int testctrl = -1;
|
||||
int rc = 0;
|
||||
int i, n;
|
||||
int rc2 = 0;
|
||||
int i, n2;
|
||||
open_db(p, 0);
|
||||
|
||||
/* convert testctrl text option to value. allow any unique prefix
|
||||
** of the option name, or a numerical value. */
|
||||
n = strlen30(azArg[1]);
|
||||
n2 = strlen30(azArg[1]);
|
||||
for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
|
||||
if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
|
||||
if( strncmp(azArg[1], aCtrl[i].zCtrlName, n2)==0 ){
|
||||
if( testctrl<0 ){
|
||||
testctrl = aCtrl[i].ctrlCode;
|
||||
}else{
|
||||
@@ -3736,8 +3837,8 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
case SQLITE_TESTCTRL_RESERVE:
|
||||
if( nArg==3 ){
|
||||
int opt = (int)strtol(azArg[2], 0, 0);
|
||||
rc = sqlite3_test_control(testctrl, p->db, opt);
|
||||
fprintf(p->out, "%d (0x%08x)\n", rc, rc);
|
||||
rc2 = sqlite3_test_control(testctrl, p->db, opt);
|
||||
fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
|
||||
} else {
|
||||
fprintf(stderr,"Error: testctrl %s takes a single int option\n",
|
||||
azArg[1]);
|
||||
@@ -3750,8 +3851,8 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
case SQLITE_TESTCTRL_PRNG_RESET:
|
||||
case SQLITE_TESTCTRL_BYTEORDER:
|
||||
if( nArg==2 ){
|
||||
rc = sqlite3_test_control(testctrl);
|
||||
fprintf(p->out, "%d (0x%08x)\n", rc, rc);
|
||||
rc2 = sqlite3_test_control(testctrl);
|
||||
fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
|
||||
} else {
|
||||
fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
|
||||
}
|
||||
@@ -3761,8 +3862,8 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
case SQLITE_TESTCTRL_PENDING_BYTE:
|
||||
if( nArg==3 ){
|
||||
unsigned int opt = (unsigned int)integerValue(azArg[2]);
|
||||
rc = sqlite3_test_control(testctrl, opt);
|
||||
fprintf(p->out, "%d (0x%08x)\n", rc, rc);
|
||||
rc2 = sqlite3_test_control(testctrl, opt);
|
||||
fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
|
||||
} else {
|
||||
fprintf(stderr,"Error: testctrl %s takes a single unsigned"
|
||||
" int option\n", azArg[1]);
|
||||
@@ -3775,8 +3876,8 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
case SQLITE_TESTCTRL_NEVER_CORRUPT:
|
||||
if( nArg==3 ){
|
||||
int opt = booleanValue(azArg[2]);
|
||||
rc = sqlite3_test_control(testctrl, opt);
|
||||
fprintf(p->out, "%d (0x%08x)\n", rc, rc);
|
||||
rc2 = sqlite3_test_control(testctrl, opt);
|
||||
fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
|
||||
} else {
|
||||
fprintf(stderr,"Error: testctrl %s takes a single int option\n",
|
||||
azArg[1]);
|
||||
@@ -3788,8 +3889,8 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
case SQLITE_TESTCTRL_ISKEYWORD:
|
||||
if( nArg==3 ){
|
||||
const char *opt = azArg[2];
|
||||
rc = sqlite3_test_control(testctrl, opt);
|
||||
fprintf(p->out, "%d (0x%08x)\n", rc, rc);
|
||||
rc2 = sqlite3_test_control(testctrl, opt);
|
||||
fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
|
||||
} else {
|
||||
fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
|
||||
azArg[1]);
|
||||
@@ -3799,11 +3900,11 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
|
||||
case SQLITE_TESTCTRL_IMPOSTER:
|
||||
if( nArg==5 ){
|
||||
rc = sqlite3_test_control(testctrl, p->db,
|
||||
rc2 = sqlite3_test_control(testctrl, p->db,
|
||||
azArg[2],
|
||||
integerValue(azArg[3]),
|
||||
integerValue(azArg[4]));
|
||||
fprintf(p->out, "%d (0x%08x)\n", rc, rc);
|
||||
fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
|
||||
}else{
|
||||
fprintf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n");
|
||||
}
|
||||
@@ -4111,6 +4212,7 @@ static int process_input(ShellState *p, FILE *in){
|
||||
&& sqlite3_complete(zSql) ){
|
||||
p->cnt = 0;
|
||||
open_db(p, 0);
|
||||
if( p->backslashOn ) resolve_backslashes(zSql);
|
||||
BEGIN_TIMER;
|
||||
rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
|
||||
END_TIMER;
|
||||
@@ -4577,6 +4679,13 @@ int SQLITE_CDECL main(int argc, char **argv){
|
||||
data.statsOn = 1;
|
||||
}else if( strcmp(z,"-scanstats")==0 ){
|
||||
data.scanstatsOn = 1;
|
||||
}else if( strcmp(z,"-backslash")==0 ){
|
||||
/* Undocumented command-line option: -backslash
|
||||
** Causes C-style backslash escapes to be evaluated in SQL statements
|
||||
** prior to sending the SQL into SQLite. Useful for injecting
|
||||
** crazy bytes in the middle of SQL statements for testing and debugging.
|
||||
*/
|
||||
data.backslashOn = 1;
|
||||
}else if( strcmp(z,"-bail")==0 ){
|
||||
bail_on_error = 1;
|
||||
}else if( strcmp(z,"-version")==0 ){
|
||||
|
||||
+24
-19
@@ -2672,7 +2672,7 @@ int sqlite3_set_authorizer(
|
||||
** CAPI3REF: Tracing And Profiling Functions
|
||||
** METHOD: sqlite3
|
||||
**
|
||||
** These routines register callback functions that can be used for
|
||||
** These routines control callback functions that can be used for
|
||||
** tracing and profiling the execution of SQL statements.
|
||||
**
|
||||
** ^The callback function registered by sqlite3_trace() is invoked at
|
||||
@@ -2683,6 +2683,10 @@ int sqlite3_set_authorizer(
|
||||
** as each triggered subprogram is entered. The callbacks for triggers
|
||||
** contain a UTF-8 SQL comment that identifies the trigger.)^
|
||||
**
|
||||
** ^The [sqlite3_get_trace(D,X,P)] interface writes into X and P the
|
||||
** values of the trace callback and pointer set by the most recent
|
||||
** [sqlite3_trace()] call on the same [database connection] D.
|
||||
**
|
||||
** The [SQLITE_TRACE_SIZE_LIMIT] compile-time option can be used to limit
|
||||
** the length of [bound parameter] expansion in the output of sqlite3_trace().
|
||||
**
|
||||
@@ -2693,13 +2697,21 @@ int sqlite3_set_authorizer(
|
||||
** time is in units of nanoseconds, however the current implementation
|
||||
** is only capable of millisecond resolution so the six least significant
|
||||
** digits in the time are meaningless. Future versions of SQLite
|
||||
** might provide greater resolution on the profiler callback. The
|
||||
** sqlite3_profile() function is considered experimental and is
|
||||
** subject to change in future versions of SQLite.
|
||||
** might provide greater resolution on the profiler callback.
|
||||
**
|
||||
** ^The [sqlite3_get_profile(D,X,P)] interface writes into X and P the
|
||||
** values of the profile callback and pointer set by the most recent
|
||||
** [sqlite3_profile()] call on the same [database connection] D.
|
||||
**
|
||||
** All of the tracing and profile interfaces are omitted when the
|
||||
** [SQLITE_OMIT_TRACE] compile-time option is used.
|
||||
*/
|
||||
void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*);
|
||||
SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*,
|
||||
void *sqlite3_profile(sqlite3*,
|
||||
void(*xProfile)(void*,const char*,sqlite3_uint64), void*);
|
||||
int sqlite3_get_trace(const sqlite3*, void(**)(void*,const char*),void**);
|
||||
int sqlite3_get_profile(const sqlite3*,
|
||||
void(**)(void*,const char*,sqlite3_uint64),void**);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Query Progress Callbacks
|
||||
@@ -3893,8 +3905,6 @@ int sqlite3_data_count(sqlite3_stmt *pStmt);
|
||||
** KEYWORDS: {column access functions}
|
||||
** METHOD: sqlite3_stmt
|
||||
**
|
||||
** These routines form the "result set" interface.
|
||||
**
|
||||
** ^These routines return information about a single column of the current
|
||||
** result row of a query. ^In every case the first argument is a pointer
|
||||
** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*]
|
||||
@@ -3954,13 +3964,14 @@ int sqlite3_data_count(sqlite3_stmt *pStmt);
|
||||
** even empty strings, are always zero-terminated. ^The return
|
||||
** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.
|
||||
**
|
||||
** ^The object returned by [sqlite3_column_value()] is an
|
||||
** [unprotected sqlite3_value] object. An unprotected sqlite3_value object
|
||||
** may only be used with [sqlite3_bind_value()] and [sqlite3_result_value()].
|
||||
** <b>Warning:</b> ^The object returned by [sqlite3_column_value()] is an
|
||||
** [unprotected sqlite3_value] object. In a multithreaded environment,
|
||||
** an unprotected sqlite3_value object may only be used safely with
|
||||
** [sqlite3_bind_value()] and [sqlite3_result_value()].
|
||||
** If the [unprotected sqlite3_value] object returned by
|
||||
** [sqlite3_column_value()] is used in any other way, including calls
|
||||
** to routines like [sqlite3_value_int()], [sqlite3_value_text()],
|
||||
** or [sqlite3_value_bytes()], then the behavior is undefined.
|
||||
** or [sqlite3_value_bytes()], the behavior is not threadsafe.
|
||||
**
|
||||
** These routines attempt to convert the value where appropriate. ^For
|
||||
** example, if the internal representation is FLOAT and a text result
|
||||
@@ -3991,12 +4002,6 @@ int sqlite3_data_count(sqlite3_stmt *pStmt);
|
||||
** </table>
|
||||
** </blockquote>)^
|
||||
**
|
||||
** The table above makes reference to standard C library functions atoi()
|
||||
** and atof(). SQLite does not really use these functions. It has its
|
||||
** own equivalent internal routines. The atoi() and atof() names are
|
||||
** used in the table for brevity and because they are familiar to most
|
||||
** C programmers.
|
||||
**
|
||||
** Note that when type conversions occur, pointers returned by prior
|
||||
** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
|
||||
** sqlite3_column_text16() may be invalidated.
|
||||
@@ -4021,7 +4026,7 @@ int sqlite3_data_count(sqlite3_stmt *pStmt);
|
||||
** of conversion are done in place when it is possible, but sometimes they
|
||||
** are not possible and in those cases prior pointers are invalidated.
|
||||
**
|
||||
** The safest and easiest to remember policy is to invoke these routines
|
||||
** The safest policy is to invoke these routines
|
||||
** in one of the following ways:
|
||||
**
|
||||
** <ul>
|
||||
@@ -4041,7 +4046,7 @@ int sqlite3_data_count(sqlite3_stmt *pStmt);
|
||||
** ^The pointers returned are valid until a type conversion occurs as
|
||||
** described above, or until [sqlite3_step()] or [sqlite3_reset()] or
|
||||
** [sqlite3_finalize()] is called. ^The memory space used to hold strings
|
||||
** and BLOBs is freed automatically. Do <b>not</b> pass the pointers returned
|
||||
** and BLOBs is freed automatically. Do <em>not</em> pass the pointers returned
|
||||
** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
|
||||
** [sqlite3_free()].
|
||||
**
|
||||
|
||||
+26
-42
@@ -1583,34 +1583,8 @@ struct VTable {
|
||||
};
|
||||
|
||||
/*
|
||||
** Each SQL table is represented in memory by an instance of the
|
||||
** following structure.
|
||||
**
|
||||
** Table.zName is the name of the table. The case of the original
|
||||
** CREATE TABLE statement is stored, but case is not significant for
|
||||
** comparisons.
|
||||
**
|
||||
** Table.nCol is the number of columns in this table. Table.aCol is a
|
||||
** pointer to an array of Column structures, one for each column.
|
||||
**
|
||||
** If the table has an INTEGER PRIMARY KEY, then Table.iPKey is the index of
|
||||
** the column that is that key. Otherwise Table.iPKey is negative. Note
|
||||
** that the datatype of the PRIMARY KEY must be INTEGER for this field to
|
||||
** be set. An INTEGER PRIMARY KEY is used as the rowid for each row of
|
||||
** the table. If a table has no INTEGER PRIMARY KEY, then a random rowid
|
||||
** is generated for each row of the table. TF_HasPrimaryKey is set if
|
||||
** the table has any PRIMARY KEY, INTEGER or otherwise.
|
||||
**
|
||||
** Table.tnum is the page number for the root BTree page of the table in the
|
||||
** database file. If Table.iDb is the index of the database table backend
|
||||
** in sqlite.aDb[]. 0 is for the main database and 1 is for the file that
|
||||
** holds temporary tables and indices. If TF_Ephemeral is set
|
||||
** then the table is stored in a file that is automatically deleted
|
||||
** when the VDBE cursor to the table is closed. In this case Table.tnum
|
||||
** refers VDBE cursor number that holds the table open, not to the root
|
||||
** page number. Transient tables are used to hold the results of a
|
||||
** sub-query that appears instead of a real table name in the FROM clause
|
||||
** of a SELECT statement.
|
||||
** The schema for each SQL table and view is represented in memory
|
||||
** by an instance of the following structure.
|
||||
*/
|
||||
struct Table {
|
||||
char *zName; /* Name of the table or view */
|
||||
@@ -1622,11 +1596,11 @@ struct Table {
|
||||
#ifndef SQLITE_OMIT_CHECK
|
||||
ExprList *pCheck; /* All CHECK constraints */
|
||||
#endif
|
||||
LogEst nRowLogEst; /* Estimated rows in table - from sqlite_stat1 table */
|
||||
int tnum; /* Root BTree node for this table (see note above) */
|
||||
i16 iPKey; /* If not negative, use aCol[iPKey] as the primary key */
|
||||
int tnum; /* Root BTree page for this table */
|
||||
i16 iPKey; /* If not negative, use aCol[iPKey] as the rowid */
|
||||
i16 nCol; /* Number of columns in this table */
|
||||
u16 nRef; /* Number of pointers to this Table */
|
||||
LogEst nRowLogEst; /* Estimated rows in table - from sqlite_stat1 table */
|
||||
LogEst szTabRow; /* Estimated size of each table row in bytes */
|
||||
#ifdef SQLITE_ENABLE_COSTMULT
|
||||
LogEst costMult; /* Cost multiplier for using this table */
|
||||
@@ -1648,6 +1622,12 @@ struct Table {
|
||||
|
||||
/*
|
||||
** Allowed values for Table.tabFlags.
|
||||
**
|
||||
** TF_OOOHidden applies to virtual tables that have hidden columns that are
|
||||
** followed by non-hidden columns. Example: "CREATE VIRTUAL TABLE x USING
|
||||
** vtab1(a HIDDEN, b);". Since "b" is a non-hidden column but "a" is hidden,
|
||||
** the TF_OOOHidden attribute would apply in this case. Such tables require
|
||||
** special handling during INSERT processing.
|
||||
*/
|
||||
#define TF_Readonly 0x01 /* Read-only system table */
|
||||
#define TF_Ephemeral 0x02 /* An ephemeral table */
|
||||
@@ -1655,6 +1635,7 @@ struct Table {
|
||||
#define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */
|
||||
#define TF_Virtual 0x10 /* Is a virtual table */
|
||||
#define TF_WithoutRowid 0x20 /* No rowid used. PRIMARY KEY is the key */
|
||||
#define TF_OOOHidden 0x40 /* Out-of-Order hidden columns */
|
||||
|
||||
|
||||
/*
|
||||
@@ -2411,7 +2392,7 @@ struct Select {
|
||||
#define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */
|
||||
#define SF_Compound 0x0040 /* Part of a compound query */
|
||||
#define SF_Values 0x0080 /* Synthesized from VALUES clause */
|
||||
#define SF_AllValues 0x0100 /* All terms of compound are VALUES */
|
||||
#define SF_MultiValue 0x0100 /* Single VALUES term with multiple rows */
|
||||
#define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */
|
||||
#define SF_MaybeConvert 0x0400 /* Need convertCompoundSelectToSubquery() */
|
||||
#define SF_Recursive 0x0800 /* The recursive part of a recursive CTE */
|
||||
@@ -2795,7 +2776,7 @@ struct Trigger {
|
||||
* orconf -> stores the ON CONFLICT algorithm
|
||||
* pSelect -> If this is an INSERT INTO ... SELECT ... statement, then
|
||||
* this stores a pointer to the SELECT statement. Otherwise NULL.
|
||||
* target -> A token holding the quoted name of the table to insert into.
|
||||
* zTarget -> Dequoted name of the table to insert into.
|
||||
* pExprList -> If this is an INSERT INTO ... VALUES ... statement, then
|
||||
* this stores values to be inserted. Otherwise NULL.
|
||||
* pIdList -> If this is an INSERT INTO ... (<column-names>) VALUES ...
|
||||
@@ -2803,12 +2784,12 @@ struct Trigger {
|
||||
* inserted into.
|
||||
*
|
||||
* (op == TK_DELETE)
|
||||
* target -> A token holding the quoted name of the table to delete from.
|
||||
* zTarget -> Dequoted name of the table to delete from.
|
||||
* pWhere -> The WHERE clause of the DELETE statement if one is specified.
|
||||
* Otherwise NULL.
|
||||
*
|
||||
* (op == TK_UPDATE)
|
||||
* target -> A token holding the quoted name of the table to update rows of.
|
||||
* zTarget -> Dequoted name of the table to update.
|
||||
* pWhere -> The WHERE clause of the UPDATE statement if one is specified.
|
||||
* Otherwise NULL.
|
||||
* pExprList -> A list of the columns to update and the expressions to update
|
||||
@@ -2820,8 +2801,8 @@ struct TriggerStep {
|
||||
u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */
|
||||
u8 orconf; /* OE_Rollback etc. */
|
||||
Trigger *pTrig; /* The trigger that this step is a part of */
|
||||
Select *pSelect; /* SELECT statment or RHS of INSERT INTO .. SELECT ... */
|
||||
Token target; /* Target table for DELETE, UPDATE, INSERT */
|
||||
Select *pSelect; /* SELECT statement or RHS of INSERT INTO SELECT ... */
|
||||
char *zTarget; /* Target table for DELETE, UPDATE, INSERT */
|
||||
Expr *pWhere; /* The WHERE clause for DELETE or UPDATE steps */
|
||||
ExprList *pExprList; /* SET clause for UPDATE. */
|
||||
IdList *pIdList; /* Column names for INSERT */
|
||||
@@ -2854,8 +2835,7 @@ struct StrAccum {
|
||||
char *zText; /* The string collected so far */
|
||||
int nChar; /* Length of the string so far */
|
||||
int nAlloc; /* Amount of space allocated in zText */
|
||||
int mxAlloc; /* Maximum allowed string length */
|
||||
u8 useMalloc; /* 0: none, 1: sqlite3DbMalloc, 2: sqlite3_malloc */
|
||||
int mxAlloc; /* Maximum allowed allocation. 0 for no malloc usage */
|
||||
u8 accError; /* STRACCUM_NOMEM or STRACCUM_TOOBIG */
|
||||
};
|
||||
#define STRACCUM_NOMEM 1
|
||||
@@ -3404,8 +3384,8 @@ FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,u8);
|
||||
void sqlite3RegisterBuiltinFunctions(sqlite3*);
|
||||
void sqlite3RegisterDateTimeFunctions(void);
|
||||
void sqlite3RegisterGlobalFunctions(void);
|
||||
int sqlite3SafetyCheckOk(sqlite3*);
|
||||
int sqlite3SafetyCheckSickOrOk(sqlite3*);
|
||||
int sqlite3SafetyCheckOk(const sqlite3*);
|
||||
int sqlite3SafetyCheckSickOrOk(const sqlite3*);
|
||||
void sqlite3ChangeCookie(Parse*, int);
|
||||
|
||||
#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
|
||||
@@ -3613,7 +3593,7 @@ int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *,
|
||||
int sqlite3ApiExit(sqlite3 *db, int);
|
||||
int sqlite3OpenTempDatabase(Parse *);
|
||||
|
||||
void sqlite3StrAccumInit(StrAccum*, char*, int, int);
|
||||
void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int);
|
||||
void sqlite3StrAccumAppend(StrAccum*,const char*,int);
|
||||
void sqlite3StrAccumAppendAll(StrAccum*,const char*);
|
||||
void sqlite3AppendChar(StrAccum*,int,char);
|
||||
@@ -3887,4 +3867,8 @@ int sqlite3ThreadCreate(SQLiteThread**,void*(*)(void*),void*);
|
||||
int sqlite3ThreadJoin(SQLiteThread*, void**);
|
||||
#endif
|
||||
|
||||
#if defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST)
|
||||
int sqlite3DbstatRegister(sqlite3*);
|
||||
#endif
|
||||
|
||||
#endif /* _SQLITEINT_H_ */
|
||||
|
||||
+3
-3
@@ -90,7 +90,7 @@ static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
|
||||
z = 0;
|
||||
}else{
|
||||
int n = sqlite3Strlen30(argv[i])+1;
|
||||
z = sqlite3_malloc( n );
|
||||
z = sqlite3_malloc64( n );
|
||||
if( z==0 ) goto malloc_failed;
|
||||
memcpy(z, argv[i], n);
|
||||
}
|
||||
@@ -139,7 +139,7 @@ int sqlite3_get_table(
|
||||
res.nData = 1;
|
||||
res.nAlloc = 20;
|
||||
res.rc = SQLITE_OK;
|
||||
res.azResult = sqlite3_malloc(sizeof(char*)*res.nAlloc );
|
||||
res.azResult = sqlite3_malloc64(sizeof(char*)*res.nAlloc );
|
||||
if( res.azResult==0 ){
|
||||
db->errCode = SQLITE_NOMEM;
|
||||
return SQLITE_NOMEM;
|
||||
@@ -167,7 +167,7 @@ int sqlite3_get_table(
|
||||
}
|
||||
if( res.nAlloc>res.nData ){
|
||||
char **azNew;
|
||||
azNew = sqlite3_realloc( res.azResult, sizeof(char*)*res.nData );
|
||||
azNew = sqlite3_realloc64( res.azResult, sizeof(char*)*res.nData );
|
||||
if( azNew==0 ){
|
||||
sqlite3_free_table(&res.azResult[1]);
|
||||
db->errCode = SQLITE_NOMEM;
|
||||
|
||||
+6
-17
@@ -1191,7 +1191,7 @@ static int dbPrepareAndBind(
|
||||
int n;
|
||||
u8 *data;
|
||||
const char *zType = (pVar->typePtr ? pVar->typePtr->name : "");
|
||||
char c = zType[0];
|
||||
c = zType[0];
|
||||
if( zVar[0]=='@' ||
|
||||
(c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0) ){
|
||||
/* Load a BLOB type if the Tcl variable is a bytearray and
|
||||
@@ -2298,7 +2298,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
}
|
||||
Tcl_DecrRefCount(pRet);
|
||||
}else{
|
||||
ClientData cd[2];
|
||||
ClientData cd2[2];
|
||||
DbEvalContext *p;
|
||||
Tcl_Obj *pArray = 0;
|
||||
Tcl_Obj *pScript;
|
||||
@@ -2312,9 +2312,9 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
||||
p = (DbEvalContext *)Tcl_Alloc(sizeof(DbEvalContext));
|
||||
dbEvalInit(p, pDb, objv[2], pArray);
|
||||
|
||||
cd[0] = (void *)p;
|
||||
cd[1] = (void *)pScript;
|
||||
rc = DbEvalNextCmd(cd, interp, TCL_OK);
|
||||
cd2[0] = (void *)p;
|
||||
cd2[1] = (void *)pScript;
|
||||
rc = DbEvalNextCmd(cd2, interp, TCL_OK);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -3704,7 +3704,7 @@ static int db_last_stmt_ptr(
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
#endif
|
||||
#endif /* SQLITE_TEST */
|
||||
|
||||
/*
|
||||
** Configure the interpreter passed as the first argument to have access
|
||||
@@ -3724,17 +3724,6 @@ static void init_all(Tcl_Interp *interp){
|
||||
Md5_Init(interp);
|
||||
#endif
|
||||
|
||||
/* Install the [register_dbstat_vtab] command to access the implementation
|
||||
** of virtual table dbstat (source file test_stat.c). This command is
|
||||
** required for testfixture and sqlite3_analyzer, but not by the production
|
||||
** Tcl extension. */
|
||||
#if defined(SQLITE_TEST) || TCLSH==2
|
||||
{
|
||||
extern int SqlitetestStat_Init(Tcl_Interp*);
|
||||
SqlitetestStat_Init(interp);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_TEST
|
||||
{
|
||||
extern int Sqliteconfig_Init(Tcl_Interp*);
|
||||
|
||||
+35
-1
@@ -6680,7 +6680,40 @@ static int test_bad_behavior(
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** tclcmd: register_dbstat_vtab DB
|
||||
**
|
||||
** Cause the dbstat virtual table to be available on the connection DB
|
||||
*/
|
||||
static int test_register_dbstat_vtab(
|
||||
void *clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
#ifdef SQLITE_OMIT_VIRTUALTABLE
|
||||
Tcl_AppendResult(interp, "dbstat not available because of "
|
||||
"SQLITE_OMIT_VIRTUALTABLE", (void*)0);
|
||||
return TCL_ERROR;
|
||||
#else
|
||||
struct SqliteDb { sqlite3 *db; };
|
||||
char *zDb;
|
||||
Tcl_CmdInfo cmdInfo;
|
||||
|
||||
if( objc!=2 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "DB");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
zDb = Tcl_GetString(objv[1]);
|
||||
if( Tcl_GetCommandInfo(interp, zDb, &cmdInfo) ){
|
||||
sqlite3* db = ((struct SqliteDb*)cmdInfo.objClientData)->db;
|
||||
sqlite3DbstatRegister(db);
|
||||
}
|
||||
return TCL_OK;
|
||||
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
||||
}
|
||||
|
||||
/*
|
||||
** Register commands with the TCL interpreter.
|
||||
@@ -6752,6 +6785,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
void *clientData;
|
||||
} aObjCmd[] = {
|
||||
{ "bad_behavior", test_bad_behavior, (void*)&iZero },
|
||||
{ "register_dbstat_vtab", test_register_dbstat_vtab },
|
||||
{ "sqlite3_connection_pointer", get_sqlite_pointer, 0 },
|
||||
{ "sqlite3_bind_int", test_bind_int, 0 },
|
||||
{ "sqlite3_bind_zeroblob", test_bind_zeroblob, 0 },
|
||||
|
||||
+4
-1
@@ -16,6 +16,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#ifndef SQLITE_OMIT_INCRBLOB
|
||||
|
||||
/* These functions are implemented in main.c. */
|
||||
extern const char *sqlite3ErrName(int);
|
||||
@@ -295,12 +296,13 @@ static int test_blob_write(
|
||||
|
||||
return (rc==SQLITE_OK ? TCL_OK : TCL_ERROR);
|
||||
}
|
||||
|
||||
#endif /* SQLITE_OMIT_INCRBLOB */
|
||||
|
||||
/*
|
||||
** Register commands with the TCL interpreter.
|
||||
*/
|
||||
int Sqlitetest_blob_Init(Tcl_Interp *interp){
|
||||
#ifndef SQLITE_OMIT_INCRBLOB
|
||||
static struct {
|
||||
char *zName;
|
||||
Tcl_ObjCmdProc *xProc;
|
||||
@@ -315,5 +317,6 @@ int Sqlitetest_blob_Init(Tcl_Interp *interp){
|
||||
for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
|
||||
Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0);
|
||||
}
|
||||
#endif /* SQLITE_OMIT_INCRBLOB */
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
+4
-4
@@ -85,7 +85,7 @@ static int intarrayCreate(
|
||||
char **pzErr /* Put error message text here */
|
||||
){
|
||||
int rc = SQLITE_NOMEM;
|
||||
intarray_vtab *pVtab = sqlite3_malloc(sizeof(intarray_vtab));
|
||||
intarray_vtab *pVtab = sqlite3_malloc64(sizeof(intarray_vtab));
|
||||
|
||||
if( pVtab ){
|
||||
memset(pVtab, 0, sizeof(intarray_vtab));
|
||||
@@ -102,7 +102,7 @@ static int intarrayCreate(
|
||||
static int intarrayOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
|
||||
int rc = SQLITE_NOMEM;
|
||||
intarray_cursor *pCur;
|
||||
pCur = sqlite3_malloc(sizeof(intarray_cursor));
|
||||
pCur = sqlite3_malloc64(sizeof(intarray_cursor));
|
||||
if( pCur ){
|
||||
memset(pCur, 0, sizeof(intarray_cursor));
|
||||
*ppCursor = (sqlite3_vtab_cursor *)pCur;
|
||||
@@ -225,7 +225,7 @@ SQLITE_API int sqlite3_intarray_create(
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
sqlite3_intarray *p;
|
||||
|
||||
*ppReturn = p = sqlite3_malloc( sizeof(*p) );
|
||||
*ppReturn = p = sqlite3_malloc64( sizeof(*p) );
|
||||
if( p==0 ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
@@ -340,7 +340,7 @@ static int test_intarray_bind(
|
||||
pArray = (sqlite3_intarray*)sqlite3TestTextToPtr(Tcl_GetString(objv[1]));
|
||||
n = objc - 2;
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
a = sqlite3_malloc( sizeof(a[0])*n );
|
||||
a = sqlite3_malloc64( sizeof(a[0])*n );
|
||||
if( a==0 ){
|
||||
Tcl_AppendResult(interp, "SQLITE_NOMEM", (char*)0);
|
||||
return TCL_ERROR;
|
||||
|
||||
+5
-5
@@ -211,15 +211,15 @@ static int faultsimInstall(int install){
|
||||
faultsimBeginBenign, faultsimEndBenign
|
||||
);
|
||||
}else{
|
||||
sqlite3_mem_methods m;
|
||||
sqlite3_mem_methods m2;
|
||||
assert(memfault.m.xMalloc);
|
||||
|
||||
/* One should be able to reset the default memory allocator by storing
|
||||
** a zeroed allocator then calling GETMALLOC. */
|
||||
memset(&m, 0, sizeof(m));
|
||||
sqlite3_config(SQLITE_CONFIG_MALLOC, &m);
|
||||
sqlite3_config(SQLITE_CONFIG_GETMALLOC, &m);
|
||||
assert( memcmp(&m, &memfault.m, sizeof(m))==0 );
|
||||
memset(&m2, 0, sizeof(m2));
|
||||
sqlite3_config(SQLITE_CONFIG_MALLOC, &m2);
|
||||
sqlite3_config(SQLITE_CONFIG_GETMALLOC, &m2);
|
||||
assert( memcmp(&m2, &memfault.m, sizeof(m2))==0 );
|
||||
|
||||
rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &memfault.m);
|
||||
sqlite3_test_control(SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, 0, 0);
|
||||
|
||||
+12
-12
@@ -286,7 +286,7 @@ static void multiplexFilename(
|
||||
static int multiplexSubFilename(multiplexGroup *pGroup, int iChunk){
|
||||
if( iChunk>=pGroup->nReal ){
|
||||
struct multiplexReal *p;
|
||||
p = sqlite3_realloc(pGroup->aReal, (iChunk+1)*sizeof(*p));
|
||||
p = sqlite3_realloc64(pGroup->aReal, (iChunk+1)*sizeof(*p));
|
||||
if( p==0 ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
@@ -297,7 +297,7 @@ static int multiplexSubFilename(multiplexGroup *pGroup, int iChunk){
|
||||
if( pGroup->zName && pGroup->aReal[iChunk].z==0 ){
|
||||
char *z;
|
||||
int n = pGroup->nName;
|
||||
pGroup->aReal[iChunk].z = z = sqlite3_malloc( n+5 );
|
||||
pGroup->aReal[iChunk].z = z = sqlite3_malloc64( n+5 );
|
||||
if( z==0 ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
@@ -357,7 +357,7 @@ static sqlite3_file *multiplexSubOpen(
|
||||
}
|
||||
flags &= ~SQLITE_OPEN_CREATE;
|
||||
}
|
||||
pSubOpen = sqlite3_malloc( pOrigVfs->szOsFile );
|
||||
pSubOpen = sqlite3_malloc64( pOrigVfs->szOsFile );
|
||||
if( pSubOpen==0 ){
|
||||
*rc = SQLITE_IOERR_NOMEM;
|
||||
return 0;
|
||||
@@ -524,7 +524,7 @@ static int multiplexOpen(
|
||||
nName = zName ? multiplexStrlen30(zName) : 0;
|
||||
sz = sizeof(multiplexGroup) /* multiplexGroup */
|
||||
+ nName + 1; /* zName */
|
||||
pGroup = sqlite3_malloc( sz );
|
||||
pGroup = sqlite3_malloc64( sz );
|
||||
if( pGroup==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}
|
||||
@@ -568,15 +568,15 @@ static int multiplexOpen(
|
||||
if( pSubOpen==0 && rc==SQLITE_OK ) rc = SQLITE_CANTOPEN;
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3_int64 sz;
|
||||
sqlite3_int64 sz64;
|
||||
|
||||
rc = pSubOpen->pMethods->xFileSize(pSubOpen, &sz);
|
||||
rc = pSubOpen->pMethods->xFileSize(pSubOpen, &sz64);
|
||||
if( rc==SQLITE_OK && zName ){
|
||||
int bExists;
|
||||
if( flags & SQLITE_OPEN_MASTER_JOURNAL ){
|
||||
pGroup->bEnabled = 0;
|
||||
}else
|
||||
if( sz==0 ){
|
||||
if( sz64==0 ){
|
||||
if( flags & SQLITE_OPEN_MAIN_JOURNAL ){
|
||||
/* If opening a main journal file and the first chunk is zero
|
||||
** bytes in size, delete any subsequent chunks from the
|
||||
@@ -607,10 +607,10 @@ static int multiplexOpen(
|
||||
rc = pOrigVfs->xAccess(pOrigVfs, pGroup->aReal[1].z,
|
||||
SQLITE_ACCESS_EXISTS, &bExists);
|
||||
bExists = multiplexSubSize(pGroup, 1, &rc)>0;
|
||||
if( rc==SQLITE_OK && bExists && sz==(sz&0xffff0000) && sz>0
|
||||
&& sz!=pGroup->szChunk ){
|
||||
pGroup->szChunk = (int)sz;
|
||||
}else if( rc==SQLITE_OK && !bExists && sz>pGroup->szChunk ){
|
||||
if( rc==SQLITE_OK && bExists && sz64==(sz64&0xffff0000) && sz64>0
|
||||
&& sz64!=pGroup->szChunk ){
|
||||
pGroup->szChunk = (int)sz64;
|
||||
}else if( rc==SQLITE_OK && !bExists && sz64>pGroup->szChunk ){
|
||||
pGroup->bEnabled = 0;
|
||||
}
|
||||
}
|
||||
@@ -655,7 +655,7 @@ static int multiplexDelete(
|
||||
*/
|
||||
int nName = (int)strlen(zName);
|
||||
char *z;
|
||||
z = sqlite3_malloc(nName + 5);
|
||||
z = sqlite3_malloc64(nName + 5);
|
||||
if( z==0 ){
|
||||
rc = SQLITE_IOERR_NOMEM;
|
||||
}else{
|
||||
|
||||
+3
-3
@@ -595,9 +595,9 @@ static int fsOpen(
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
if( 0==(flags&(SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_MAIN_JOURNAL)) ){
|
||||
tmp_file *p = (tmp_file *)pFile;
|
||||
memset(p, 0, sizeof(*p));
|
||||
p->base.pMethods = &tmp_io_methods;
|
||||
tmp_file *p2 = (tmp_file *)pFile;
|
||||
memset(p2, 0, sizeof(*p2));
|
||||
p2->base.pMethods = &tmp_io_methods;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -1131,7 +1131,6 @@ static int test_vfslog(
|
||||
|
||||
switch( (enum VL_enum)iSub ){
|
||||
case VL_ANNOTATE: {
|
||||
int rc;
|
||||
char *zVfs;
|
||||
char *zMsg;
|
||||
if( objc!=4 ){
|
||||
@@ -1148,7 +1147,6 @@ static int test_vfslog(
|
||||
break;
|
||||
}
|
||||
case VL_FINALIZE: {
|
||||
int rc;
|
||||
char *zVfs;
|
||||
if( objc!=3 ){
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "VFS");
|
||||
@@ -1164,7 +1162,6 @@ static int test_vfslog(
|
||||
};
|
||||
|
||||
case VL_NEW: {
|
||||
int rc;
|
||||
char *zVfs;
|
||||
char *zParent;
|
||||
char *zLog;
|
||||
|
||||
+1
-2
@@ -1080,7 +1080,7 @@ static int testvfs_obj_cmd(
|
||||
switch( aSubcmd[i].eCmd ){
|
||||
case CMD_SHM: {
|
||||
Tcl_Obj *pObj;
|
||||
int i, rc;
|
||||
int rc;
|
||||
TestvfsBuffer *pBuffer;
|
||||
char *zName;
|
||||
if( objc!=3 && objc!=4 ){
|
||||
@@ -1160,7 +1160,6 @@ static int testvfs_obj_cmd(
|
||||
};
|
||||
Tcl_Obj **apElem = 0;
|
||||
int nElem = 0;
|
||||
int i;
|
||||
int mask = 0;
|
||||
if( objc!=3 ){
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "LIST");
|
||||
|
||||
+5
-5
@@ -450,12 +450,14 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
|
||||
}
|
||||
abort_parse:
|
||||
assert( nErr==0 );
|
||||
if( zSql[i]==0 && pParse->rc==SQLITE_OK ){
|
||||
if( zSql[i]==0 && pParse->rc==SQLITE_OK && db->mallocFailed==0 ){
|
||||
if( lastTokenParsed!=TK_SEMI ){
|
||||
sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
|
||||
pParse->zTail = &zSql[i];
|
||||
}
|
||||
sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
|
||||
if( pParse->rc==SQLITE_OK && db->mallocFailed==0 ){
|
||||
sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
|
||||
}
|
||||
}
|
||||
#ifdef YYTRACKMAXSTACKDEPTH
|
||||
sqlite3_mutex_enter(sqlite3MallocMutex());
|
||||
@@ -516,8 +518,6 @@ abort_parse:
|
||||
pParse->pZombieTab = p->pNextZombie;
|
||||
sqlite3DeleteTable(db, p);
|
||||
}
|
||||
if( nErr>0 && pParse->rc==SQLITE_OK ){
|
||||
pParse->rc = SQLITE_ERROR;
|
||||
}
|
||||
assert( nErr==0 || pParse->rc!=SQLITE_OK );
|
||||
return nErr;
|
||||
}
|
||||
|
||||
+10
-9
@@ -193,7 +193,6 @@ void sqlite3BeginTrigger(
|
||||
/* Do not create a trigger on a system table */
|
||||
if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){
|
||||
sqlite3ErrorMsg(pParse, "cannot create trigger on system table");
|
||||
pParse->nErr++;
|
||||
goto trigger_cleanup;
|
||||
}
|
||||
|
||||
@@ -373,12 +372,12 @@ static TriggerStep *triggerStepAllocate(
|
||||
){
|
||||
TriggerStep *pTriggerStep;
|
||||
|
||||
pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n);
|
||||
pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1);
|
||||
if( pTriggerStep ){
|
||||
char *z = (char*)&pTriggerStep[1];
|
||||
memcpy(z, pName->z, pName->n);
|
||||
pTriggerStep->target.z = z;
|
||||
pTriggerStep->target.n = pName->n;
|
||||
sqlite3Dequote(z);
|
||||
pTriggerStep->zTarget = z;
|
||||
pTriggerStep->op = op;
|
||||
}
|
||||
return pTriggerStep;
|
||||
@@ -661,7 +660,7 @@ Trigger *sqlite3TriggersExist(
|
||||
}
|
||||
|
||||
/*
|
||||
** Convert the pStep->target token into a SrcList and return a pointer
|
||||
** Convert the pStep->zTarget string into a SrcList and return a pointer
|
||||
** to that SrcList.
|
||||
**
|
||||
** This routine adds a specific database name, if needed, to the target when
|
||||
@@ -674,16 +673,17 @@ static SrcList *targetSrcList(
|
||||
Parse *pParse, /* The parsing context */
|
||||
TriggerStep *pStep /* The trigger containing the target token */
|
||||
){
|
||||
sqlite3 *db = pParse->db;
|
||||
int iDb; /* Index of the database to use */
|
||||
SrcList *pSrc; /* SrcList to be returned */
|
||||
|
||||
pSrc = sqlite3SrcListAppend(pParse->db, 0, &pStep->target, 0);
|
||||
pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
|
||||
if( pSrc ){
|
||||
assert( pSrc->nSrc>0 );
|
||||
iDb = sqlite3SchemaToIndex(pParse->db, pStep->pTrig->pSchema);
|
||||
pSrc->a[pSrc->nSrc-1].zName = sqlite3DbStrDup(db, pStep->zTarget);
|
||||
iDb = sqlite3SchemaToIndex(db, pStep->pTrig->pSchema);
|
||||
if( iDb==0 || iDb>=2 ){
|
||||
sqlite3 *db = pParse->db;
|
||||
assert( iDb<pParse->db->nDb );
|
||||
assert( iDb<db->nDb );
|
||||
pSrc->a[pSrc->nSrc-1].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zName);
|
||||
}
|
||||
}
|
||||
@@ -795,6 +795,7 @@ static void transferParseError(Parse *pTo, Parse *pFrom){
|
||||
if( pTo->nErr==0 ){
|
||||
pTo->zErrMsg = pFrom->zErrMsg;
|
||||
pTo->nErr = pFrom->nErr;
|
||||
pTo->rc = pFrom->rc;
|
||||
}else{
|
||||
sqlite3DbFree(pFrom->db, pFrom->zErrMsg);
|
||||
}
|
||||
|
||||
+3
-2
@@ -655,6 +655,7 @@ int sqlite3GetInt32(const char *zNum, int *pValue){
|
||||
}
|
||||
}
|
||||
#endif
|
||||
while( zNum[0]=='0' ) zNum++;
|
||||
for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){
|
||||
v = v*10 + c;
|
||||
}
|
||||
@@ -1156,7 +1157,7 @@ static void logBadConnection(const char *zType){
|
||||
** open properly and is not fit for general use but which can be
|
||||
** used as an argument to sqlite3_errmsg() or sqlite3_close().
|
||||
*/
|
||||
int sqlite3SafetyCheckOk(sqlite3 *db){
|
||||
int sqlite3SafetyCheckOk(const sqlite3 *db){
|
||||
u32 magic;
|
||||
if( db==0 ){
|
||||
logBadConnection("NULL");
|
||||
@@ -1173,7 +1174,7 @@ int sqlite3SafetyCheckOk(sqlite3 *db){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
int sqlite3SafetyCheckSickOrOk(sqlite3 *db){
|
||||
int sqlite3SafetyCheckSickOrOk(const sqlite3 *db){
|
||||
u32 magic;
|
||||
magic = db->magic;
|
||||
if( magic!=SQLITE_MAGIC_SICK &&
|
||||
|
||||
+20
-14
@@ -539,6 +539,9 @@ int sqlite3VdbeExec(
|
||||
){
|
||||
Op *aOp = p->aOp; /* Copy of p->aOp */
|
||||
Op *pOp = aOp; /* Current operation */
|
||||
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
|
||||
Op *pOrigOp; /* Value of pOp at the top of the loop */
|
||||
#endif
|
||||
int rc = SQLITE_OK; /* Value to return */
|
||||
sqlite3 *db = p->db; /* The database */
|
||||
u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */
|
||||
@@ -681,6 +684,9 @@ int sqlite3VdbeExec(
|
||||
memAboutToChange(p, &aMem[pOp->p3]);
|
||||
}
|
||||
#endif
|
||||
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
|
||||
pOrigOp = pOp;
|
||||
#endif
|
||||
|
||||
switch( pOp->opcode ){
|
||||
|
||||
@@ -979,7 +985,6 @@ case OP_Halt: {
|
||||
assert( rc==SQLITE_OK || db->nDeferredCons>0 || db->nDeferredImmCons>0 );
|
||||
rc = p->rc ? SQLITE_ERROR : SQLITE_DONE;
|
||||
}
|
||||
pOp = &aOp[pcx];
|
||||
goto vdbe_return;
|
||||
}
|
||||
|
||||
@@ -1199,10 +1204,11 @@ case OP_Move: {
|
||||
memAboutToChange(p, pOut);
|
||||
sqlite3VdbeMemMove(pOut, pIn1);
|
||||
#ifdef SQLITE_DEBUG
|
||||
if( pOut->pScopyFrom>=&aMem[p1] && pOut->pScopyFrom<&aMem[p1+pOp->p3] ){
|
||||
pOut->pScopyFrom += p1 - pOp->p2;
|
||||
if( pOut->pScopyFrom>=&aMem[p1] && pOut->pScopyFrom<pOut ){
|
||||
pOut->pScopyFrom += pOp->p2 - p1;
|
||||
}
|
||||
#endif
|
||||
Deephemeralize(pOut);
|
||||
REGISTER_TRACE(p2++, pOut);
|
||||
pIn1++;
|
||||
pOut++;
|
||||
@@ -2471,7 +2477,7 @@ case OP_Column: {
|
||||
}
|
||||
}
|
||||
|
||||
/* If after trying to extra new entries from the header, nHdrParsed is
|
||||
/* If after trying to extract new entries from the header, nHdrParsed is
|
||||
** still not up to p2, that means that the record has fewer than p2
|
||||
** columns. So the result will be either the default value or a NULL.
|
||||
*/
|
||||
@@ -2919,7 +2925,7 @@ case OP_Savepoint: {
|
||||
db->nDeferredImmCons = pSavepoint->nDeferredImmCons;
|
||||
}
|
||||
|
||||
if( !isTransaction ){
|
||||
if( !isTransaction || p1==SAVEPOINT_ROLLBACK ){
|
||||
rc = sqlite3VtabSavepoint(db, p1, iSavepoint);
|
||||
if( rc!=SQLITE_OK ) goto abort_due_to_error;
|
||||
}
|
||||
@@ -5906,7 +5912,6 @@ case OP_JournalMode: { /* out2 */
|
||||
}
|
||||
eNew = sqlite3PagerSetJournalMode(pPager, eNew);
|
||||
|
||||
pOut = &aMem[pOp->p2];
|
||||
pOut->flags = MEM_Str|MEM_Static|MEM_Term;
|
||||
pOut->z = (char *)sqlite3JournalModename(eNew);
|
||||
pOut->n = sqlite3Strlen30(pOut->z);
|
||||
@@ -6101,8 +6106,9 @@ case OP_VOpen: {
|
||||
pCur->pVtabCursor = pVtabCursor;
|
||||
pVtab->nRef++;
|
||||
}else{
|
||||
db->mallocFailed = 1;
|
||||
assert( db->mallocFailed );
|
||||
pModule->xClose(pVtabCursor);
|
||||
goto no_mem;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -6489,8 +6495,8 @@ default: { /* This is really OP_Noop and OP_Explain */
|
||||
#ifdef VDBE_PROFILE
|
||||
{
|
||||
u64 endTime = sqlite3Hwtime();
|
||||
if( endTime>start ) pOp->cycles += endTime - start;
|
||||
pOp->cnt++;
|
||||
if( endTime>start ) pOrigOp->cycles += endTime - start;
|
||||
pOrigOp->cnt++;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -6500,16 +6506,16 @@ default: { /* This is really OP_Noop and OP_Explain */
|
||||
** the evaluator loop. So we can leave it out when NDEBUG is defined.
|
||||
*/
|
||||
#ifndef NDEBUG
|
||||
assert( pOp>=&aOp[-1] && pOp<&aOp[p->nOp] );
|
||||
assert( pOp>=&aOp[-1] && pOp<&aOp[p->nOp-1] );
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
if( db->flags & SQLITE_VdbeTrace ){
|
||||
if( rc!=0 ) printf("rc=%d\n",rc);
|
||||
if( pOp->opflags & (OPFLG_OUT2) ){
|
||||
registerTrace(pOp->p2, &aMem[pOp->p2]);
|
||||
if( pOrigOp->opflags & (OPFLG_OUT2) ){
|
||||
registerTrace(pOrigOp->p2, &aMem[pOrigOp->p2]);
|
||||
}
|
||||
if( pOp->opflags & OPFLG_OUT3 ){
|
||||
registerTrace(pOp->p3, &aMem[pOp->p3]);
|
||||
if( pOrigOp->opflags & OPFLG_OUT3 ){
|
||||
registerTrace(pOrigOp->p3, &aMem[pOrigOp->p3]);
|
||||
}
|
||||
}
|
||||
#endif /* SQLITE_DEBUG */
|
||||
|
||||
+18
-11
@@ -1789,6 +1789,22 @@ void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
** Close all cursors in the current frame.
|
||||
*/
|
||||
static void closeCursorsInFrame(Vdbe *p){
|
||||
if( p->apCsr ){
|
||||
int i;
|
||||
for(i=0; i<p->nCursor; i++){
|
||||
VdbeCursor *pC = p->apCsr[i];
|
||||
if( pC ){
|
||||
sqlite3VdbeFreeCursor(p, pC);
|
||||
p->apCsr[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Copy the values stored in the VdbeFrame structure to its Vdbe. This
|
||||
** is used, for example, when a trigger sub-program is halted to restore
|
||||
@@ -1796,6 +1812,7 @@ void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){
|
||||
*/
|
||||
int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){
|
||||
Vdbe *v = pFrame->v;
|
||||
closeCursorsInFrame(v);
|
||||
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
|
||||
v->anExec = pFrame->anExec;
|
||||
#endif
|
||||
@@ -1830,17 +1847,7 @@ static void closeAllCursors(Vdbe *p){
|
||||
p->nFrame = 0;
|
||||
}
|
||||
assert( p->nFrame==0 );
|
||||
|
||||
if( p->apCsr ){
|
||||
int i;
|
||||
for(i=0; i<p->nCursor; i++){
|
||||
VdbeCursor *pC = p->apCsr[i];
|
||||
if( pC ){
|
||||
sqlite3VdbeFreeCursor(p, pC);
|
||||
p->apCsr[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
closeCursorsInFrame(p);
|
||||
if( p->aMem ){
|
||||
releaseMemArray(&p->aMem[1], p->nMem);
|
||||
}
|
||||
|
||||
+5
-4
@@ -200,10 +200,11 @@ int sqlite3VdbeMemMakeWriteable(Mem *pMem){
|
||||
pMem->z[pMem->n] = 0;
|
||||
pMem->z[pMem->n+1] = 0;
|
||||
pMem->flags |= MEM_Term;
|
||||
#ifdef SQLITE_DEBUG
|
||||
pMem->pScopyFrom = 0;
|
||||
#endif
|
||||
}
|
||||
pMem->flags &= ~MEM_Ephem;
|
||||
#ifdef SQLITE_DEBUG
|
||||
pMem->pScopyFrom = 0;
|
||||
#endif
|
||||
|
||||
return SQLITE_OK;
|
||||
}
|
||||
@@ -1647,7 +1648,7 @@ void sqlite3Stat4ProbeFree(UnpackedRecord *pRec){
|
||||
Mem *aMem = pRec->aMem;
|
||||
sqlite3 *db = aMem[0].db;
|
||||
for(i=0; i<nCol; i++){
|
||||
if( aMem[i].szMalloc ) sqlite3DbFree(db, aMem[i].zMalloc);
|
||||
sqlite3VdbeMemRelease(&aMem[i]);
|
||||
}
|
||||
sqlite3KeyInfoUnref(pRec->pKeyInfo);
|
||||
sqlite3DbFree(db, pRec);
|
||||
|
||||
+95
-71
@@ -2063,11 +2063,12 @@ static void vdbeMergeEngineCompare(
|
||||
#define INCRINIT_TASK 1
|
||||
#define INCRINIT_ROOT 2
|
||||
|
||||
/* Forward reference.
|
||||
** The vdbeIncrMergeInit() and vdbePmaReaderIncrMergeInit() routines call each
|
||||
** other (when building a merge tree).
|
||||
/*
|
||||
** Forward reference required as the vdbeIncrMergeInit() and
|
||||
** vdbePmaReaderIncrInit() routines are called mutually recursively when
|
||||
** building a merge tree.
|
||||
*/
|
||||
static int vdbePmaReaderIncrMergeInit(PmaReader *pReadr, int eMode);
|
||||
static int vdbePmaReaderIncrInit(PmaReader *pReadr, int eMode);
|
||||
|
||||
/*
|
||||
** Initialize the MergeEngine object passed as the second argument. Once this
|
||||
@@ -2114,7 +2115,7 @@ static int vdbeMergeEngineInit(
|
||||
** better advantage of multi-processor hardware. */
|
||||
rc = vdbePmaReaderNext(&pMerger->aReadr[nTree-i-1]);
|
||||
}else{
|
||||
rc = vdbePmaReaderIncrMergeInit(&pMerger->aReadr[i], INCRINIT_NORMAL);
|
||||
rc = vdbePmaReaderIncrInit(&pMerger->aReadr[i], INCRINIT_NORMAL);
|
||||
}
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
}
|
||||
@@ -2126,17 +2127,15 @@ static int vdbeMergeEngineInit(
|
||||
}
|
||||
|
||||
/*
|
||||
** Initialize the IncrMerge field of a PmaReader.
|
||||
**
|
||||
** If the PmaReader passed as the first argument is not an incremental-reader
|
||||
** (if pReadr->pIncr==0), then this function is a no-op. Otherwise, it serves
|
||||
** to open and/or initialize the temp file related fields of the IncrMerge
|
||||
** The PmaReader passed as the first argument is guaranteed to be an
|
||||
** incremental-reader (pReadr->pIncr!=0). This function serves to open
|
||||
** and/or initialize the temp file related fields of the IncrMerge
|
||||
** object at (pReadr->pIncr).
|
||||
**
|
||||
** If argument eMode is set to INCRINIT_NORMAL, then all PmaReaders
|
||||
** in the sub-tree headed by pReadr are also initialized. Data is then loaded
|
||||
** into the buffers belonging to pReadr and it is set to
|
||||
** point to the first key in its range.
|
||||
** in the sub-tree headed by pReadr are also initialized. Data is then
|
||||
** loaded into the buffers belonging to pReadr and it is set to point to
|
||||
** the first key in its range.
|
||||
**
|
||||
** If argument eMode is set to INCRINIT_TASK, then pReadr is guaranteed
|
||||
** to be a multi-threaded PmaReader and this function is being called in a
|
||||
@@ -2163,59 +2162,62 @@ static int vdbeMergeEngineInit(
|
||||
static int vdbePmaReaderIncrMergeInit(PmaReader *pReadr, int eMode){
|
||||
int rc = SQLITE_OK;
|
||||
IncrMerger *pIncr = pReadr->pIncr;
|
||||
SortSubtask *pTask = pIncr->pTask;
|
||||
sqlite3 *db = pTask->pSorter->db;
|
||||
|
||||
/* eMode is always INCRINIT_NORMAL in single-threaded mode */
|
||||
assert( SQLITE_MAX_WORKER_THREADS>0 || eMode==INCRINIT_NORMAL );
|
||||
|
||||
if( pIncr ){
|
||||
SortSubtask *pTask = pIncr->pTask;
|
||||
sqlite3 *db = pTask->pSorter->db;
|
||||
rc = vdbeMergeEngineInit(pTask, pIncr->pMerger, eMode);
|
||||
|
||||
rc = vdbeMergeEngineInit(pTask, pIncr->pMerger, eMode);
|
||||
|
||||
/* Set up the required files for pIncr. A multi-theaded IncrMerge object
|
||||
** requires two temp files to itself, whereas a single-threaded object
|
||||
** only requires a region of pTask->file2. */
|
||||
if( rc==SQLITE_OK ){
|
||||
int mxSz = pIncr->mxSz;
|
||||
/* Set up the required files for pIncr. A multi-theaded IncrMerge object
|
||||
** requires two temp files to itself, whereas a single-threaded object
|
||||
** only requires a region of pTask->file2. */
|
||||
if( rc==SQLITE_OK ){
|
||||
int mxSz = pIncr->mxSz;
|
||||
#if SQLITE_MAX_WORKER_THREADS>0
|
||||
if( pIncr->bUseThread ){
|
||||
rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[0].pFd);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[1].pFd);
|
||||
}
|
||||
}else
|
||||
if( pIncr->bUseThread ){
|
||||
rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[0].pFd);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[1].pFd);
|
||||
}
|
||||
}else
|
||||
#endif
|
||||
/*if( !pIncr->bUseThread )*/{
|
||||
if( pTask->file2.pFd==0 ){
|
||||
assert( pTask->file2.iEof>0 );
|
||||
rc = vdbeSorterOpenTempFile(db, pTask->file2.iEof, &pTask->file2.pFd);
|
||||
pTask->file2.iEof = 0;
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
pIncr->aFile[1].pFd = pTask->file2.pFd;
|
||||
pIncr->iStartOff = pTask->file2.iEof;
|
||||
pTask->file2.iEof += mxSz;
|
||||
}
|
||||
/*if( !pIncr->bUseThread )*/{
|
||||
if( pTask->file2.pFd==0 ){
|
||||
assert( pTask->file2.iEof>0 );
|
||||
rc = vdbeSorterOpenTempFile(db, pTask->file2.iEof, &pTask->file2.pFd);
|
||||
pTask->file2.iEof = 0;
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
pIncr->aFile[1].pFd = pTask->file2.pFd;
|
||||
pIncr->iStartOff = pTask->file2.iEof;
|
||||
pTask->file2.iEof += mxSz;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if SQLITE_MAX_WORKER_THREADS>0
|
||||
if( rc==SQLITE_OK && pIncr->bUseThread ){
|
||||
/* Use the current thread to populate aFile[1], even though this
|
||||
** PmaReader is multi-threaded. The reason being that this function
|
||||
** is already running in background thread pIncr->pTask->thread. */
|
||||
assert( eMode==INCRINIT_ROOT || eMode==INCRINIT_TASK );
|
||||
rc = vdbeIncrPopulate(pIncr);
|
||||
}
|
||||
if( rc==SQLITE_OK && pIncr->bUseThread ){
|
||||
/* Use the current thread to populate aFile[1], even though this
|
||||
** PmaReader is multi-threaded. If this is an INCRINIT_TASK object,
|
||||
** then this function is already running in background thread
|
||||
** pIncr->pTask->thread.
|
||||
**
|
||||
** If this is the INCRINIT_ROOT object, then it is running in the
|
||||
** main VDBE thread. But that is Ok, as that thread cannot return
|
||||
** control to the VDBE or proceed with anything useful until the
|
||||
** first results are ready from this merger object anyway.
|
||||
*/
|
||||
assert( eMode==INCRINIT_ROOT || eMode==INCRINIT_TASK );
|
||||
rc = vdbeIncrPopulate(pIncr);
|
||||
}
|
||||
#endif
|
||||
|
||||
if( rc==SQLITE_OK
|
||||
&& (SQLITE_MAX_WORKER_THREADS==0 || eMode!=INCRINIT_TASK)
|
||||
){
|
||||
rc = vdbePmaReaderNext(pReadr);
|
||||
}
|
||||
if( rc==SQLITE_OK && (SQLITE_MAX_WORKER_THREADS==0 || eMode!=INCRINIT_TASK) ){
|
||||
rc = vdbePmaReaderNext(pReadr);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -2224,7 +2226,7 @@ static int vdbePmaReaderIncrMergeInit(PmaReader *pReadr, int eMode){
|
||||
** The main routine for vdbePmaReaderIncrMergeInit() operations run in
|
||||
** background threads.
|
||||
*/
|
||||
static void *vdbePmaReaderBgInit(void *pCtx){
|
||||
static void *vdbePmaReaderBgIncrInit(void *pCtx){
|
||||
PmaReader *pReader = (PmaReader*)pCtx;
|
||||
void *pRet = SQLITE_INT_TO_PTR(
|
||||
vdbePmaReaderIncrMergeInit(pReader,INCRINIT_TASK)
|
||||
@@ -2232,20 +2234,36 @@ static void *vdbePmaReaderBgInit(void *pCtx){
|
||||
pReader->pIncr->pTask->bDone = 1;
|
||||
return pRet;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Use a background thread to invoke vdbePmaReaderIncrMergeInit(INCRINIT_TASK)
|
||||
** on the PmaReader object passed as the first argument.
|
||||
**
|
||||
** This call will initialize the various fields of the pReadr->pIncr
|
||||
** structure and, if it is a multi-threaded IncrMerger, launch a
|
||||
** background thread to populate aFile[1].
|
||||
** If the PmaReader passed as the first argument is not an incremental-reader
|
||||
** (if pReadr->pIncr==0), then this function is a no-op. Otherwise, it invokes
|
||||
** the vdbePmaReaderIncrMergeInit() function with the parameters passed to
|
||||
** this routine to initialize the incremental merge.
|
||||
**
|
||||
** If the IncrMerger object is multi-threaded (IncrMerger.bUseThread==1),
|
||||
** then a background thread is launched to call vdbePmaReaderIncrMergeInit().
|
||||
** Or, if the IncrMerger is single threaded, the same function is called
|
||||
** using the current thread.
|
||||
*/
|
||||
static int vdbePmaReaderBgIncrInit(PmaReader *pReadr){
|
||||
void *pCtx = (void*)pReadr;
|
||||
return vdbeSorterCreateThread(pReadr->pIncr->pTask, vdbePmaReaderBgInit, pCtx);
|
||||
}
|
||||
static int vdbePmaReaderIncrInit(PmaReader *pReadr, int eMode){
|
||||
IncrMerger *pIncr = pReadr->pIncr; /* Incremental merger */
|
||||
int rc = SQLITE_OK; /* Return code */
|
||||
if( pIncr ){
|
||||
#if SQLITE_MAX_WORKER_THREADS>0
|
||||
assert( pIncr->bUseThread==0 || eMode==INCRINIT_TASK );
|
||||
if( pIncr->bUseThread ){
|
||||
void *pCtx = (void*)pReadr;
|
||||
rc = vdbeSorterCreateThread(pIncr->pTask, vdbePmaReaderBgIncrInit, pCtx);
|
||||
}else
|
||||
#endif
|
||||
{
|
||||
rc = vdbePmaReaderIncrMergeInit(pReadr, eMode);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Allocate a new MergeEngine object to merge the contents of nPMA level-0
|
||||
@@ -2490,15 +2508,21 @@ static int vdbeSorterSetupMerge(VdbeSorter *pSorter){
|
||||
}
|
||||
}
|
||||
for(iTask=0; rc==SQLITE_OK && iTask<pSorter->nTask; iTask++){
|
||||
/* Check that:
|
||||
**
|
||||
** a) The incremental merge object is configured to use the
|
||||
** right task, and
|
||||
** b) If it is using task (nTask-1), it is configured to run
|
||||
** in single-threaded mode. This is important, as the
|
||||
** root merge (INCRINIT_ROOT) will be using the same task
|
||||
** object.
|
||||
*/
|
||||
PmaReader *p = &pMain->aReadr[iTask];
|
||||
assert( p->pIncr==0 || p->pIncr->pTask==&pSorter->aTask[iTask] );
|
||||
if( p->pIncr ){
|
||||
if( iTask==pSorter->nTask-1 ){
|
||||
rc = vdbePmaReaderIncrMergeInit(p, INCRINIT_TASK);
|
||||
}else{
|
||||
rc = vdbePmaReaderBgIncrInit(p);
|
||||
}
|
||||
}
|
||||
assert( p->pIncr==0 || (
|
||||
(p->pIncr->pTask==&pSorter->aTask[iTask]) /* a */
|
||||
&& (iTask!=pSorter->nTask-1 || p->pIncr->bUseThread==0) /* b */
|
||||
));
|
||||
rc = vdbePmaReaderIncrInit(p, INCRINIT_TASK);
|
||||
}
|
||||
}
|
||||
pMain = 0;
|
||||
|
||||
+6
-3
@@ -84,9 +84,8 @@ char *sqlite3VdbeExpandSql(
|
||||
char zBase[100]; /* Initial working space */
|
||||
|
||||
db = p->db;
|
||||
sqlite3StrAccumInit(&out, zBase, sizeof(zBase),
|
||||
sqlite3StrAccumInit(&out, db, zBase, sizeof(zBase),
|
||||
db->aLimit[SQLITE_LIMIT_LENGTH]);
|
||||
out.db = db;
|
||||
if( db->nVdbeExec>1 ){
|
||||
while( *zRawSql ){
|
||||
const char *zStart = zRawSql;
|
||||
@@ -95,6 +94,8 @@ char *sqlite3VdbeExpandSql(
|
||||
assert( (zRawSql - zStart) > 0 );
|
||||
sqlite3StrAccumAppend(&out, zStart, (int)(zRawSql-zStart));
|
||||
}
|
||||
}else if( p->nVar==0 ){
|
||||
sqlite3StrAccumAppend(&out, zRawSql, sqlite3Strlen30(zRawSql));
|
||||
}else{
|
||||
while( zRawSql[0] ){
|
||||
n = findNextHostParameter(zRawSql, &nToken);
|
||||
@@ -111,10 +112,12 @@ char *sqlite3VdbeExpandSql(
|
||||
idx = nextIndex;
|
||||
}
|
||||
}else{
|
||||
assert( zRawSql[0]==':' || zRawSql[0]=='$' || zRawSql[0]=='@' );
|
||||
assert( zRawSql[0]==':' || zRawSql[0]=='$' ||
|
||||
zRawSql[0]=='@' || zRawSql[0]=='#' );
|
||||
testcase( zRawSql[0]==':' );
|
||||
testcase( zRawSql[0]=='$' );
|
||||
testcase( zRawSql[0]=='@' );
|
||||
testcase( zRawSql[0]=='#' );
|
||||
idx = sqlite3VdbeParameterIndex(p, zRawSql, nToken);
|
||||
assert( idx>0 );
|
||||
}
|
||||
|
||||
+11
-4
@@ -472,7 +472,7 @@ void sqlite3VtabArgExtend(Parse *pParse, Token *p){
|
||||
pArg->z = p->z;
|
||||
pArg->n = p->n;
|
||||
}else{
|
||||
assert(pArg->z < p->z);
|
||||
assert(pArg->z <= p->z);
|
||||
pArg->n = (int)(&p->z[p->n] - pArg->z);
|
||||
}
|
||||
}
|
||||
@@ -559,6 +559,7 @@ static int vtabCallConstructor(
|
||||
rc = SQLITE_ERROR;
|
||||
}else{
|
||||
int iCol;
|
||||
u8 oooHidden = 0;
|
||||
/* If everything went according to plan, link the new VTable structure
|
||||
** into the linked list headed by pTab->pVTable. Then loop through the
|
||||
** columns of the table to see if any of them contain the token "hidden".
|
||||
@@ -571,7 +572,10 @@ static int vtabCallConstructor(
|
||||
char *zType = pTab->aCol[iCol].zType;
|
||||
int nType;
|
||||
int i = 0;
|
||||
if( !zType ) continue;
|
||||
if( !zType ){
|
||||
pTab->tabFlags |= oooHidden;
|
||||
continue;
|
||||
}
|
||||
nType = sqlite3Strlen30(zType);
|
||||
if( sqlite3StrNICmp("hidden", zType, 6)||(zType[6] && zType[6]!=' ') ){
|
||||
for(i=0; i<nType; i++){
|
||||
@@ -594,6 +598,9 @@ static int vtabCallConstructor(
|
||||
zType[i-1] = '\0';
|
||||
}
|
||||
pTab->aCol[iCol].colFlags |= COLFLAG_HIDDEN;
|
||||
oooHidden = TF_OOOHidden;
|
||||
}else{
|
||||
pTab->tabFlags |= oooHidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -957,7 +964,7 @@ int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
assert( op==SAVEPOINT_RELEASE||op==SAVEPOINT_ROLLBACK||op==SAVEPOINT_BEGIN );
|
||||
assert( iSavepoint>=0 );
|
||||
assert( iSavepoint>=-1 );
|
||||
if( db->aVTrans ){
|
||||
int i;
|
||||
for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){
|
||||
@@ -1075,7 +1082,7 @@ void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){
|
||||
if( pTab==pToplevel->apVtabLock[i] ) return;
|
||||
}
|
||||
n = (pToplevel->nVtabLock+1)*sizeof(pToplevel->apVtabLock[0]);
|
||||
apVtabLock = sqlite3_realloc(pToplevel->apVtabLock, n);
|
||||
apVtabLock = sqlite3_realloc64(pToplevel->apVtabLock, n);
|
||||
if( apVtabLock ){
|
||||
pToplevel->apVtabLock = apVtabLock;
|
||||
pToplevel->apVtabLock[pToplevel->nVtabLock++] = pTab;
|
||||
|
||||
@@ -522,7 +522,7 @@ static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
|
||||
if( pWal->nWiData<=iPage ){
|
||||
int nByte = sizeof(u32*)*(iPage+1);
|
||||
volatile u32 **apNew;
|
||||
apNew = (volatile u32 **)sqlite3_realloc((void *)pWal->apWiData, nByte);
|
||||
apNew = (volatile u32 **)sqlite3_realloc64((void *)pWal->apWiData, nByte);
|
||||
if( !apNew ){
|
||||
*ppPage = 0;
|
||||
return SQLITE_NOMEM;
|
||||
@@ -1147,7 +1147,7 @@ static int walIndexRecover(Wal *pWal){
|
||||
|
||||
/* Malloc a buffer to read frames into. */
|
||||
szFrame = szPage + WAL_FRAME_HDRSIZE;
|
||||
aFrame = (u8 *)sqlite3_malloc(szFrame);
|
||||
aFrame = (u8 *)sqlite3_malloc64(szFrame);
|
||||
if( !aFrame ){
|
||||
rc = SQLITE_NOMEM;
|
||||
goto recovery_error;
|
||||
@@ -1540,7 +1540,7 @@ static int walIteratorInit(Wal *pWal, WalIterator **pp){
|
||||
nByte = sizeof(WalIterator)
|
||||
+ (nSegment-1)*sizeof(struct WalSegment)
|
||||
+ iLast*sizeof(ht_slot);
|
||||
p = (WalIterator *)sqlite3_malloc(nByte);
|
||||
p = (WalIterator *)sqlite3_malloc64(nByte);
|
||||
if( !p ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
@@ -1550,7 +1550,7 @@ static int walIteratorInit(Wal *pWal, WalIterator **pp){
|
||||
/* Allocate temporary space used by the merge-sort routine. This block
|
||||
** of memory will be freed before this function returns.
|
||||
*/
|
||||
aTmp = (ht_slot *)sqlite3_malloc(
|
||||
aTmp = (ht_slot *)sqlite3_malloc64(
|
||||
sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast)
|
||||
);
|
||||
if( !aTmp ){
|
||||
|
||||
+13
-8
@@ -255,13 +255,14 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){
|
||||
** all terms of the WHERE clause.
|
||||
*/
|
||||
static void whereSplit(WhereClause *pWC, Expr *pExpr, u8 op){
|
||||
Expr *pE2 = sqlite3ExprSkipCollate(pExpr);
|
||||
pWC->op = op;
|
||||
if( pExpr==0 ) return;
|
||||
if( pExpr->op!=op ){
|
||||
if( pE2==0 ) return;
|
||||
if( pE2->op!=op ){
|
||||
whereClauseInsert(pWC, pExpr, 0);
|
||||
}else{
|
||||
whereSplit(pWC, pExpr->pLeft, op);
|
||||
whereSplit(pWC, pExpr->pRight, op);
|
||||
whereSplit(pWC, pE2->pLeft, op);
|
||||
whereSplit(pWC, pE2->pRight, op);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3102,8 +3103,7 @@ static int explainOneScan(
|
||||
|| ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0))
|
||||
|| (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));
|
||||
|
||||
sqlite3StrAccumInit(&str, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
|
||||
str.db = db;
|
||||
sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
|
||||
sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN");
|
||||
if( pItem->pSelect ){
|
||||
sqlite3XPrintf(&str, 0, " SUBQUERY %d", pItem->iSelectId);
|
||||
@@ -4302,6 +4302,13 @@ static void whereLoopDelete(sqlite3 *db, WhereLoop *p){
|
||||
*/
|
||||
static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
|
||||
if( ALWAYS(pWInfo) ){
|
||||
int i;
|
||||
for(i=0; i<pWInfo->nLevel; i++){
|
||||
WhereLevel *pLevel = &pWInfo->a[i];
|
||||
if( pLevel->pWLoop && (pLevel->pWLoop->wsFlags & WHERE_IN_ABLE) ){
|
||||
sqlite3DbFree(db, pLevel->u.in.aInLoop);
|
||||
}
|
||||
}
|
||||
whereClauseClear(&pWInfo->sWC);
|
||||
while( pWInfo->pLoops ){
|
||||
WhereLoop *p = pWInfo->pLoops;
|
||||
@@ -6646,7 +6653,6 @@ WhereInfo *sqlite3WhereBegin(
|
||||
}
|
||||
#ifdef WHERETRACE_ENABLED /* !=0 */
|
||||
if( sqlite3WhereTrace ){
|
||||
int ii;
|
||||
sqlite3DebugPrintf("---- Solution nRow=%d", pWInfo->nRowOut);
|
||||
if( pWInfo->nOBSat>0 ){
|
||||
sqlite3DebugPrintf(" ORDERBY=%d,0x%llx", pWInfo->nOBSat, pWInfo->revMask);
|
||||
@@ -6899,7 +6905,6 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
|
||||
VdbeCoverageIf(v, pIn->eEndLoopOp==OP_NextIfOpen);
|
||||
sqlite3VdbeJumpHere(v, pIn->addrInTop-1);
|
||||
}
|
||||
sqlite3DbFree(db, pLevel->u.in.aInLoop);
|
||||
}
|
||||
sqlite3VdbeResolveLabel(v, pLevel->addrBrk);
|
||||
if( pLevel->addrSkip ){
|
||||
|
||||
@@ -912,5 +912,14 @@ do_execsql_test alter-17.9 {
|
||||
do_execsql_test alter-17.10 {
|
||||
SELECT sqlite_rename_parent(NULL,'abc','xyz');
|
||||
} {{}}
|
||||
do_execsql_test alter-17.11 {
|
||||
SELECT sqlite_rename_parent('create references ''','abc','xyz');
|
||||
} {{create references '}}
|
||||
do_execsql_test alter-17.12 {
|
||||
SELECT sqlite_rename_parent('create references "abc"123" ','abc','xyz');
|
||||
} {{create references "xyz"123" }}
|
||||
do_execsql_test alter-17.13 {
|
||||
SELECT sqlite_rename_parent("references '''",'abc','xyz');
|
||||
} {{references '''}}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix analyze3
|
||||
|
||||
ifcapable !stat4&&!stat3 {
|
||||
finish_test
|
||||
@@ -46,6 +47,9 @@ ifcapable !stat4&&!stat3 {
|
||||
#
|
||||
# analyze3-6.*: Test that the problem fixed by commit [127a5b776d] is fixed.
|
||||
#
|
||||
# analyze3-7.*: Test that some memory leaks discovered by fuzz testing
|
||||
# have been fixed.
|
||||
#
|
||||
|
||||
proc getvar {varname} { uplevel #0 set $varname }
|
||||
db function var getvar
|
||||
@@ -662,4 +666,30 @@ do_eqp_test analyze3-6-2 {
|
||||
SELECT * FROM t1 WHERE a = 5 AND b > 'w' AND c = 13;
|
||||
} {0 0 0 {SEARCH TABLE t1 USING INDEX i2 (c=?)}}
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# 2015-04-20.
|
||||
# Memory leak in sqlite3Stat4ProbeFree(). (Discovered while fuzzing.)
|
||||
#
|
||||
do_execsql_test analyze-7.1 {
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
|
||||
INSERT INTO t1 VALUES(1,1,'0000');
|
||||
CREATE INDEX t0b ON t1(b);
|
||||
ANALYZE;
|
||||
SELECT c FROM t1 WHERE b=3 AND a BETWEEN 30 AND hex(1);
|
||||
} {}
|
||||
|
||||
# At one point duplicate stat1 entries were causing a memory leak.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 7.2 {
|
||||
CREATE TABLE t1(a,b,c);
|
||||
CREATE INDEX t1a ON t1(a);
|
||||
ANALYZE;
|
||||
SELECT * FROM sqlite_stat1;
|
||||
INSERT INTO sqlite_stat1(tbl,idx,stat) VALUES('t1','t1a','12000');
|
||||
INSERT INTO sqlite_stat1(tbl,idx,stat) VALUES('t1','t1a','12000');
|
||||
ANALYZE sqlite_master;
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
# 2015-05-11
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# Quick tests for the sqlite3_analyzer tool
|
||||
#
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
ifcapable !vtab {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
if {$tcl_platform(platform)=="windows"} {
|
||||
set PROG "sqlite3_analyzer.exe"
|
||||
} else {
|
||||
set PROG "./sqlite3_analyzer"
|
||||
}
|
||||
db close
|
||||
forcedelete test.db test.db-journal test.db-wal
|
||||
sqlite3 db test.db
|
||||
|
||||
do_test analyzer1-1.0 {
|
||||
db eval {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
|
||||
CREATE TABLE t2(a INT PRIMARY KEY, b) WITHOUT ROWID;
|
||||
WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<250)
|
||||
INSERT INTO t1(a,b) SELECT x, randomblob(200) FROM c;
|
||||
INSERT INTO t2(a,b) SELECT a, b FROM t1;
|
||||
}
|
||||
set line "exec $PROG test.db"
|
||||
unset -nocomplain ::MSG
|
||||
catch {eval $line} ::MSG
|
||||
} {0}
|
||||
do_test analyzer1-1.1 {
|
||||
regexp {^/\*\* Disk-Space Utilization.*COMMIT;\W*$} $::MSG
|
||||
} {1}
|
||||
|
||||
finish_test
|
||||
+1
-1
@@ -292,7 +292,7 @@ do_test corruptC-2.15 {
|
||||
hexio_write test.db 986 b9
|
||||
sqlite3 db test.db
|
||||
catchsql {SELECT count(*) FROM sqlite_master;}
|
||||
} {1 {malformed database schema (t1i1) - no such table: main.t1}}
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
#
|
||||
# Now test for a series of quasi-random seeds.
|
||||
|
||||
@@ -191,4 +191,9 @@ do_execsql_test count-5.1 {
|
||||
SELECT count(*) FROM t5;
|
||||
} {1}
|
||||
|
||||
do_catchsql_test count-6.1 {
|
||||
CREATE TABLE t6(x);
|
||||
SELECT count(DISTINCT) FROM t6 GROUP BY x;
|
||||
} {1 {DISTINCT aggregates must have exactly one argument}}
|
||||
|
||||
finish_test
|
||||
|
||||
+6
-2
@@ -48,8 +48,11 @@ do_execsql_test e_reindex-1.1 {
|
||||
INSERT INTO t1 VALUES(1, 2);
|
||||
INSERT INTO t1 VALUES(3, 4);
|
||||
INSERT INTO t1 VALUES(5, 6);
|
||||
|
||||
CREATE TABLE saved(a,b,c,d,e);
|
||||
INSERT INTO saved SELECT * FROM sqlite_master WHERE type = 'index';
|
||||
PRAGMA writable_schema = 1;
|
||||
UPDATE sqlite_master SET sql = '-- ' || sql WHERE type = 'index';
|
||||
DELETE FROM sqlite_master WHERE type = 'index';
|
||||
} {}
|
||||
|
||||
db close
|
||||
@@ -59,7 +62,8 @@ do_execsql_test e_reindex-1.2 {
|
||||
INSERT INTO t1 VALUES(7, 8);
|
||||
INSERT INTO t1 VALUES(9, 10);
|
||||
PRAGMA writable_schema = 1;
|
||||
UPDATE sqlite_master SET sql = substr(sql, 4) WHERE type = 'index';
|
||||
INSERT INTO sqlite_master SELECT * FROM saved;
|
||||
DROP TABLE saved;
|
||||
} {}
|
||||
|
||||
db close
|
||||
|
||||
@@ -943,5 +943,13 @@ do_realnum_test expr-13.7 {
|
||||
}
|
||||
} {9.22337203685478e+18}
|
||||
|
||||
do_execsql_test expr-13.8 {
|
||||
SELECT "" <= '';
|
||||
} {1}
|
||||
do_execsql_test expr-13.9 {
|
||||
SELECT '' <= "";
|
||||
} {1}
|
||||
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -121,4 +121,34 @@ do_test fkey1-3.5 {
|
||||
sqlite3_db_status db DBSTATUS_DEFERRED_FKS 0
|
||||
} {0 0 0}
|
||||
|
||||
# Stress the dequoting logic. The first test is not so bad.
|
||||
do_execsql_test fkey1-4.0 {
|
||||
PRAGMA foreign_keys=ON;
|
||||
CREATE TABLE "xx1"("xx2" TEXT PRIMARY KEY, "xx3" TEXT);
|
||||
INSERT INTO "xx1"("xx2","xx3") VALUES('abc','def');
|
||||
CREATE TABLE "xx4"("xx5" TEXT REFERENCES "xx1" ON DELETE CASCADE);
|
||||
INSERT INTO "xx4"("xx5") VALUES('abc');
|
||||
INSERT INTO "xx1"("xx2","xx3") VALUES('uvw','xyz');
|
||||
SELECT 1, "xx5" FROM "xx4";
|
||||
DELETE FROM "xx1";
|
||||
SELECT 2, "xx5" FROM "xx4";
|
||||
} {1 abc}
|
||||
|
||||
# This case is identical to the previous except the "xx" in each name
|
||||
# is changed to a single escaped double-quote character.
|
||||
do_execsql_test fkey1-4.1 {
|
||||
PRAGMA foreign_keys=ON;
|
||||
CREATE TABLE """1"("""2" TEXT PRIMARY KEY, """3" TEXT);
|
||||
INSERT INTO """1"("""2","""3") VALUES('abc','def');
|
||||
CREATE TABLE """4"("""5" TEXT REFERENCES """1" ON DELETE CASCADE);
|
||||
INSERT INTO """4"("""5") VALUES('abc');
|
||||
INSERT INTO """1"("""2","""3") VALUES('uvw','xyz');
|
||||
SELECT 1, """5" FROM """4";
|
||||
DELETE FROM """1";
|
||||
SELECT 2, """5" FROM """4";
|
||||
} {1 abc}
|
||||
do_execsql_test fkey1-4.2 {
|
||||
PRAGMA table_info="""1";
|
||||
} {0 {"2} TEXT 0 {} 1 1 {"3} TEXT 0 {} 0}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -676,6 +676,11 @@ do_test fkey2-9.2.3 {
|
||||
SELECT * FROM cc;
|
||||
}
|
||||
} {{} A {} {} B {} 3 A 2 3 B 2}
|
||||
do_execsql_test fkey2-9.3.0 {
|
||||
CREATE TABLE t3(x PRIMARY KEY REFERENCES t3 ON DELETE SET NULL);
|
||||
INSERT INTO t3(x) VALUES(12345);
|
||||
DROP TABLE t3;
|
||||
} {}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# The following tests, fkey2-10.*, test "foreign key mismatch" and
|
||||
@@ -2014,4 +2019,18 @@ do_test fkey2-ce7c13.1.6 {
|
||||
}
|
||||
} {1 {FOREIGN KEY constraint failed}}
|
||||
|
||||
# 2015-04-16: Foreign key errors propagate back up to the parser.
|
||||
#
|
||||
do_test fkey2-20150416-100 {
|
||||
db close
|
||||
sqlite3 db :memory:
|
||||
catchsql {
|
||||
PRAGMA foreign_keys=1;
|
||||
CREATE TABLE t1(x PRIMARY KEY);
|
||||
CREATE TABLE t(y REFERENCES t0(x)ON DELETE SET DEFAULT);
|
||||
CREATE TABLE t0(y REFERENCES t1 ON DELETE SET NULL);
|
||||
REPLACE INTO t1 SELECT(0);CREATE TABLE t2(x);CREATE TABLE t3;
|
||||
}
|
||||
} {1 {foreign key mismatch - "t" referencing "t0"}}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix fts3aa
|
||||
|
||||
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
|
||||
ifcapable !fts3 {
|
||||
@@ -221,5 +222,26 @@ do_catchsql_test fts3aa-7.5 {
|
||||
CREATE VIRTUAL TABLE t4 USING fts4(tokenize=simple, tokenize=simple);
|
||||
} {1 {unrecognized parameter: tokenize=simple}}
|
||||
|
||||
do_execsql_test 8.0 {
|
||||
CREATE VIRTUAL TABLE t0 USING fts4(order=desc);
|
||||
BEGIN;
|
||||
INSERT INTO t0(rowid, content) VALUES(1, 'abc');
|
||||
UPDATE t0 SET docid=5 WHERE docid=1;
|
||||
INSERT INTO t0(rowid, content) VALUES(6, 'abc');
|
||||
}
|
||||
do_execsql_test 8.1 {
|
||||
SELECT docid FROM t0 WHERE t0 MATCH 'abc';
|
||||
} {6 5}
|
||||
do_execsql_test 8.2 {
|
||||
SELECT docid FROM t0 WHERE t0 MATCH '"abc abc"';
|
||||
} {}
|
||||
do_execsql_test 8.3 { COMMIT }
|
||||
do_execsql_test 8.4 {
|
||||
SELECT docid FROM t0 WHERE t0 MATCH 'abc';
|
||||
} {6 5}
|
||||
do_execsql_test 8.5 {
|
||||
SELECT docid FROM t0 WHERE t0 MATCH '"abc abc"';
|
||||
} {}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
# 2006 September 9
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#*************************************************************************
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this script is testing the FTS3 module.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix fts3expr5
|
||||
|
||||
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
|
||||
ifcapable !fts3 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Various forms of empty phrase expressions.
|
||||
#
|
||||
do_execsql_test 1.0 {
|
||||
CREATE VIRTUAL TABLE t0 USING fts3(x);
|
||||
SELECT rowid FROM t0 WHERE x MATCH '';
|
||||
} {}
|
||||
do_execsql_test 1.1 {
|
||||
SELECT rowid FROM t0 WHERE x MATCH '""';
|
||||
} {}
|
||||
do_execsql_test 1.2 {
|
||||
SELECT rowid FROM t0 WHERE x MATCH '"" ""';
|
||||
} {}
|
||||
do_execsql_test 1.3 {
|
||||
SELECT rowid FROM t0 WHERE x MATCH '"" OR ""';
|
||||
} {}
|
||||
do_execsql_test 1.4 {
|
||||
SELECT rowid FROM t0 WHERE x MATCH '"" NOT ""';
|
||||
} {}
|
||||
do_execsql_test 1.5 {
|
||||
SELECT rowid FROM t0 WHERE x MATCH '""""';
|
||||
} {}
|
||||
|
||||
finish_test
|
||||
@@ -449,5 +449,107 @@ do_execsql_test 10.1 {
|
||||
ORDER BY 1;
|
||||
} {1 1 one 2 2 two 3 3 three}
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Test the 'y' matchinfo flag
|
||||
#
|
||||
set sqlite_fts3_enable_parentheses 1
|
||||
reset_db
|
||||
do_execsql_test 11.0 {
|
||||
CREATE VIRTUAL TABLE tt USING fts3(x, y);
|
||||
INSERT INTO tt VALUES('c d a c d d', 'e a g b d a'); -- 1
|
||||
INSERT INTO tt VALUES('c c g a e b', 'c g d g e c'); -- 2
|
||||
INSERT INTO tt VALUES('b e f d e g', 'b a c b c g'); -- 3
|
||||
INSERT INTO tt VALUES('a c f f g d', 'd b f d e g'); -- 4
|
||||
INSERT INTO tt VALUES('g a c f c f', 'd g g b c c'); -- 5
|
||||
INSERT INTO tt VALUES('g a c e b b', 'd b f b g g'); -- 6
|
||||
INSERT INTO tt VALUES('f d a a f c', 'e e a d c f'); -- 7
|
||||
INSERT INTO tt VALUES('a c b b g f', 'a b a e d f'); -- 8
|
||||
INSERT INTO tt VALUES('b a f e c c', 'f d b b a b'); -- 9
|
||||
INSERT INTO tt VALUES('f d c e a c', 'f a f a a f'); -- 10
|
||||
}
|
||||
|
||||
db func mit mit
|
||||
foreach {tn expr res} {
|
||||
1 "a" {
|
||||
1 {1 2} 2 {1 0} 3 {0 1} 4 {1 0} 5 {1 0}
|
||||
6 {1 0} 7 {2 1} 8 {1 2} 9 {1 1} 10 {1 3}
|
||||
}
|
||||
|
||||
2 "b" {
|
||||
1 {0 1} 2 {1 0} 3 {1 2} 4 {0 1} 5 {0 1}
|
||||
6 {2 2} 8 {2 1} 9 {1 3}
|
||||
}
|
||||
|
||||
3 "y:a" {
|
||||
1 {0 2} 3 {0 1}
|
||||
7 {0 1} 8 {0 2} 9 {0 1} 10 {0 3}
|
||||
}
|
||||
|
||||
4 "x:a" {
|
||||
1 {1 0} 2 {1 0} 4 {1 0} 5 {1 0}
|
||||
6 {1 0} 7 {2 0} 8 {1 0} 9 {1 0} 10 {1 0}
|
||||
}
|
||||
|
||||
5 "a OR b" {
|
||||
1 {1 2 0 1} 2 {1 0 1 0} 3 {0 1 1 2} 4 {1 0 0 1} 5 {1 0 0 1}
|
||||
6 {1 0 2 2} 7 {2 1 0 0} 8 {1 2 2 1} 9 {1 1 1 3} 10 {1 3 0 0}
|
||||
}
|
||||
|
||||
6 "a AND b" {
|
||||
1 {1 2 0 1} 2 {1 0 1 0} 3 {0 1 1 2} 4 {1 0 0 1} 5 {1 0 0 1}
|
||||
6 {1 0 2 2} 8 {1 2 2 1} 9 {1 1 1 3}
|
||||
}
|
||||
|
||||
7 "a OR (a AND b)" {
|
||||
1 {1 2 1 2 0 1} 2 {1 0 1 0 1 0} 3 {0 1 0 1 1 2} 4 {1 0 1 0 0 1}
|
||||
5 {1 0 1 0 0 1} 6 {1 0 1 0 2 2} 7 {2 1 0 0 0 0} 8 {1 2 1 2 2 1}
|
||||
9 {1 1 1 1 1 3} 10 {1 3 0 0 0 0}
|
||||
}
|
||||
|
||||
} {
|
||||
do_execsql_test 11.1.$tn.1 {
|
||||
SELECT rowid, mit(matchinfo(tt, 'y')) FROM tt WHERE tt MATCH $expr
|
||||
} $res
|
||||
|
||||
set r2 [list]
|
||||
foreach {rowid L} $res {
|
||||
lappend r2 $rowid
|
||||
set M [list]
|
||||
foreach {a b} $L {
|
||||
lappend M [expr ($a ? 1 : 0) + ($b ? 2 : 0)]
|
||||
}
|
||||
lappend r2 $M
|
||||
}
|
||||
|
||||
do_execsql_test 11.1.$tn.2 {
|
||||
SELECT rowid, mit(matchinfo(tt, 'b')) FROM tt WHERE tt MATCH $expr
|
||||
} $r2
|
||||
breakpoint
|
||||
|
||||
do_execsql_test 11.1.$tn.2 {
|
||||
SELECT rowid, mit(matchinfo(tt, 'b')) FROM tt WHERE tt MATCH $expr
|
||||
} $r2
|
||||
}
|
||||
set sqlite_fts3_enable_parentheses 0
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Test the 'b' matchinfo flag
|
||||
#
|
||||
set sqlite_fts3_enable_parentheses 1
|
||||
reset_db
|
||||
db func mit mit
|
||||
|
||||
do_test 12.0 {
|
||||
set cols [list]
|
||||
for {set i 0} {$i < 50} {incr i} { lappend cols "c$i" }
|
||||
execsql "CREATE VIRTUAL TABLE tt USING fts3([join $cols ,])"
|
||||
} {}
|
||||
|
||||
do_execsql_test 12.1 {
|
||||
INSERT INTO tt (rowid, c4, c45) VALUES(1, 'abc', 'abc');
|
||||
SELECT mit(matchinfo(tt, 'b')) FROM tt WHERE tt MATCH 'abc';
|
||||
} [list [list [expr 1<<4] [expr 1<<(45-32)]]]
|
||||
|
||||
set sqlite_fts3_enable_parentheses 0
|
||||
finish_test
|
||||
|
||||
|
||||
+2
-2
@@ -173,8 +173,8 @@ do_select_tests 5.4 -errorformat {
|
||||
4 "SELECT optimize(content) FROM t2 WHERE t2 MATCH 'history'" optimize
|
||||
}
|
||||
do_catchsql_test 5.5.1 {
|
||||
SELECT matchinfo(t2, 'abc') FROM t2 WHERE t2 MATCH 'history'
|
||||
} {1 {unrecognized matchinfo request: b}}
|
||||
SELECT matchinfo(t2, 'abcd') FROM t2 WHERE t2 MATCH 'history'
|
||||
} {1 {unrecognized matchinfo request: d}}
|
||||
|
||||
do_execsql_test 5.5 { DROP TABLE t2 }
|
||||
|
||||
|
||||
@@ -179,5 +179,35 @@ do_test 4.2 {
|
||||
} {1 {database disk image is malformed}}
|
||||
reset_db
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Test case 5.*
|
||||
#
|
||||
# Test that the integrity-check works if there is uncommitted data.
|
||||
#
|
||||
do_execsql_test 5.0 {
|
||||
BEGIN;
|
||||
CREATE VIRTUAL TABLE t5 USING fts4(a, prefix="1,2,3");
|
||||
INSERT INTO t5 VALUES('And down by Kosiosko, where the reed-banks sweep');
|
||||
INSERT INTO t5 VALUES('and sway, and the rolling plains are wide, the');
|
||||
INSERT INTO t5 VALUES('man from snowy river is a household name today,');
|
||||
INSERT INTO t5 VALUES('and the stockmen tell the story of his ride');
|
||||
}
|
||||
|
||||
do_execsql_test 5.1 {
|
||||
INSERT INTO t5(t5) VALUES('integrity-check');
|
||||
} {}
|
||||
|
||||
do_catchsql_test 5.2 {
|
||||
INSERT INTO t5_content VALUES(5, 'his hardy mountain pony');
|
||||
INSERT INTO t5(t5) VALUES('integrity-check');
|
||||
} {1 {database disk image is malformed}}
|
||||
|
||||
do_execsql_test 5.3 ROLLBACK
|
||||
|
||||
do_execsql_test 5.4 {
|
||||
CREATE VIRTUAL TABLE t5 USING fts4(a, prefix="1,2,3");
|
||||
INSERT INTO t5(t5) VALUES('integrity-check');
|
||||
} {}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -311,5 +311,9 @@ do_eqp_test index7-6.4 {
|
||||
} {
|
||||
0 0 0 {SEARCH TABLE t4 USING INDEX i4 (c=?)}
|
||||
}
|
||||
do_catchsql_test index7-6.5 {
|
||||
CREATE INDEX t5a ON t5(a) WHERE a=#1;
|
||||
} {1 {near "#1": syntax error}}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix insert2
|
||||
|
||||
# Create some tables with data that we can select against
|
||||
#
|
||||
@@ -275,4 +276,23 @@ ifcapable subquery {
|
||||
} {1 2 1 3 1 4}
|
||||
}
|
||||
|
||||
do_execsql_test 6.0 {
|
||||
CREATE TABLE t5(a, b, c DEFAULT 'c', d);
|
||||
}
|
||||
do_execsql_test 6.1 {
|
||||
INSERT INTO t5(a) SELECT 456 UNION ALL SELECT 123 ORDER BY 1;
|
||||
SELECT * FROM t5 ORDER BY rowid;
|
||||
} {123 {} c {} 456 {} c {}}
|
||||
|
||||
ifcapable fts3 {
|
||||
do_execsql_test 6.2 {
|
||||
CREATE VIRTUAL TABLE t0 USING fts4(a);
|
||||
}
|
||||
do_execsql_test 6.3 {
|
||||
INSERT INTO t0 SELECT 0 UNION SELECT 0 AS 'x' ORDER BY x;
|
||||
SELECT * FROM t0;
|
||||
} {0}
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -560,5 +560,10 @@ do_test insert4-8.25 {
|
||||
}
|
||||
} {1 3}
|
||||
|
||||
do_catchsql_test insert4-9.1 {
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1(x);
|
||||
INSERT INTO t1(x) VALUES(5 COLLATE xyzzy) UNION SELECT 0;
|
||||
} {1 {no such collation sequence: xyzzy}}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -555,4 +555,18 @@ do_execsql_test jrnlmode-8.28 { PRAGMA journal_mode=DELETE } {delete}
|
||||
do_execsql_test jrnlmode-8.29 { COMMIT } {}
|
||||
do_execsql_test jrnlmode-8.30 { PRAGMA journal_mode=DELETE } {delete}
|
||||
|
||||
# Assertion fault on 2015-05-01
|
||||
do_test jrnlmode-9.1 {
|
||||
forcedelete test2.db
|
||||
sqlite3 db2 test2.db
|
||||
db2 eval {CREATE TEMP TABLE t(l); PRAGMA journal_mode=off;}
|
||||
db2 close
|
||||
} {}
|
||||
do_execsql_test jrnlmode-9.2 {
|
||||
PRAGMA locking_mode = exclusive;
|
||||
CREATE TABLE tx(a);
|
||||
PRAGMA journal_mode = off;
|
||||
} {exclusive off}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -923,6 +923,27 @@ do_faultsim_test 41.2 -faults oom* -body {
|
||||
faultsim_integrity_check
|
||||
}
|
||||
|
||||
reset_db
|
||||
do_execsql_test 42.0 {
|
||||
CREATE TABLE t1(x INTEGER PRIMARY KEY, y, z);
|
||||
CREATE TABLE t2(a, b);
|
||||
CREATE VIEW a002 AS SELECT *, sum(b) AS m FROM t2 GROUP BY a;
|
||||
}
|
||||
faultsim_save_and_close
|
||||
do_faultsim_test 42 -faults oom-tran* -prep {
|
||||
faultsim_restore_and_reopen
|
||||
execsql { SELECT * FROM sqlite_master }
|
||||
} -body {
|
||||
execsql {
|
||||
SELECT t1.z, a002.m
|
||||
FROM t1 JOIN a002 ON t1.y=a002.m
|
||||
WHERE t1.x IN (1,2,3);
|
||||
}
|
||||
} -test {
|
||||
faultsim_test_result {0 {}}
|
||||
}
|
||||
|
||||
|
||||
# Ensure that no file descriptors were leaked.
|
||||
do_test malloc-99.X {
|
||||
catch {db close}
|
||||
|
||||
@@ -644,4 +644,44 @@ do_execsql_test misc1-22.1 {
|
||||
SELECT ""+3 FROM (SELECT ""+5);
|
||||
} {3}
|
||||
|
||||
# 2015-04-19: NULL pointer dereference on a corrupt schema
|
||||
#
|
||||
db close
|
||||
sqlite3 db :memory:
|
||||
do_execsql_test misc1-23.1 {
|
||||
CREATE TABLE t1(x);
|
||||
PRAGMA writable_schema=ON;
|
||||
UPDATE sqlite_master SET sql='CREATE table t(d CHECK(T(#0)';
|
||||
BEGIN;
|
||||
CREATE TABLE t2(y);
|
||||
ROLLBACK;
|
||||
DROP TABLE IF EXISTS t3;
|
||||
} {}
|
||||
|
||||
# 2015-04-19: Faulty assert() statement
|
||||
#
|
||||
db close
|
||||
database_may_be_corrupt
|
||||
sqlite3 db :memory:
|
||||
do_catchsql_test misc1-23.2 {
|
||||
CREATE TABLE t1(x UNIQUE);
|
||||
PRAGMA writable_schema=ON;
|
||||
UPDATE sqlite_master SET sql='CREATE TABLE IF not EXISTS t(c)';
|
||||
BEGIN;
|
||||
CREATE TABLE t2(x);
|
||||
ROLLBACK;
|
||||
DROP TABLE F;
|
||||
} {1 {no such table: F}}
|
||||
db close
|
||||
sqlite3 db :memory:
|
||||
do_catchsql_test misc1-23.3 {
|
||||
CREATE TABLE t1(x UNIQUE);
|
||||
PRAGMA writable_schema=ON;
|
||||
UPDATE sqlite_master SET sql='CREATE table y(a TEXT, a TEXT)';
|
||||
BEGIN;
|
||||
CREATE TABLE t2(y);
|
||||
ROLLBACK;
|
||||
DROP TABLE IF EXISTS t;
|
||||
} {0 {}}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -583,6 +583,24 @@ do_test misc5-7.1 {
|
||||
catchsql $sql
|
||||
} {1 {parser stack overflow}}
|
||||
|
||||
# Parser stack overflow is silently ignored when it occurs while parsing the
|
||||
# schema and PRAGMA writable_schema is turned on.
|
||||
#
|
||||
do_test misc5-7.2 {
|
||||
sqlite3 db2 :memory:
|
||||
catchsql {
|
||||
CREATE TABLE t1(x UNIQUE);
|
||||
PRAGMA writable_schema=ON;
|
||||
UPDATE sqlite_master SET sql='CREATE table t(o CHECK(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((;VALUES(o)';
|
||||
BEGIN;
|
||||
CREATE TABLE t2(y);
|
||||
ROLLBACK;
|
||||
DROP TABLE IF EXISTS D;
|
||||
} db2
|
||||
} {0 {}}
|
||||
db2 close
|
||||
|
||||
|
||||
# Ticket #1911
|
||||
#
|
||||
ifcapable compound {
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
#!/usr/bin/tclsh
|
||||
#
|
||||
# Run this script in order to rebuild the fuzzdata1.txt file containing
|
||||
# fuzzer data for the fuzzershell utility that is create by afl-fuzz.
|
||||
#
|
||||
# This script gathers all of the test cases identified by afl-fuzz and
|
||||
# runs afl-cmin and afl-tmin over them all to try to generate a mimimum
|
||||
# set of tests that cover all observed behavior.
|
||||
#
|
||||
# Options:
|
||||
#
|
||||
# --afl-bin DIR1 DIR1 contains the AFL binaries
|
||||
# --fuzzershell PATH Full pathname of instrumented fuzzershell
|
||||
# --afl-data DIR3 DIR3 is the "-o" directory from afl-fuzz
|
||||
# -o FILE Write results into FILE
|
||||
#
|
||||
set AFLBIN {}
|
||||
set FUZZERSHELL {}
|
||||
set AFLDATA {}
|
||||
set OUTFILE {}
|
||||
|
||||
proc usage {} {
|
||||
puts stderr "Usage: $::argv0 --afl-bin DIR --fuzzershell PATH\
|
||||
--afl-data DIR -o FILE"
|
||||
exit 1
|
||||
}
|
||||
proc cmdlineerr {msg} {
|
||||
puts stderr $msg
|
||||
usage
|
||||
}
|
||||
|
||||
for {set i 0} {$i<[llength $argv]} {incr i} {
|
||||
set x [lindex $argv $i]
|
||||
if {[string index $x 0]!="-"} {cmdlineerr "illegal argument: $x"}
|
||||
set x [string trimleft $x -]
|
||||
incr i
|
||||
if {$i>=[llength $argv]} {cmdlineerr "no argument on --$x"}
|
||||
set a [lindex $argv $i]
|
||||
switch -- $x {
|
||||
afl-bin {set AFLBIN $a}
|
||||
afl-data {set AFLDATA $a}
|
||||
fuzzershell {set FUZZERSHELL $a}
|
||||
o {set OUTFILE $a}
|
||||
default {cmdlineerr "unknown option: --$x"}
|
||||
}
|
||||
}
|
||||
proc checkarg {varname option} {
|
||||
set val [set ::$varname]
|
||||
if {$val==""} {cmdlineerr "required option missing: --$option"}
|
||||
}
|
||||
checkarg AFLBIN afl-bin
|
||||
checkarg AFLDATA afl-data
|
||||
checkarg FUZZERSHELL fuzzershell
|
||||
checkarg OUTFILE o
|
||||
proc checkexec {x} {
|
||||
if {![file exec $x]} {cmdlineerr "cannot find $x"}
|
||||
}
|
||||
checkexec $AFLBIN/afl-cmin
|
||||
checkexec $AFLBIN/afl-tmin
|
||||
checkexec $FUZZERSHELL
|
||||
proc checkdir {x} {
|
||||
if {![file isdir $x]} {cmdlineerr "no such directory: $x"}
|
||||
}
|
||||
checkdir $AFLDATA/queue
|
||||
|
||||
proc progress {msg} {
|
||||
puts "******** $msg"
|
||||
flush stdout
|
||||
}
|
||||
progress "mkdir tmp1 tmp2"
|
||||
file mkdir tmp1 tmp2
|
||||
progress "copying test cases from $AFLDATA into tmp1..."
|
||||
set n 0
|
||||
foreach file [glob -nocomplain $AFLDATA/queue/id:*] {
|
||||
incr n
|
||||
file copy $file tmp1/$n
|
||||
}
|
||||
foreach file [glob -nocomplain $AFLDATA/crash*/id:*] {
|
||||
incr n
|
||||
file copy $file tmp1/$n
|
||||
}
|
||||
progress "total $n files copied."
|
||||
progress "running: $AFLBIN/afl-cmin -i tmp1 -o tmp2 $FUZZERSHELL"
|
||||
exec $AFLBIN/afl-cmin -i tmp1 -o tmp2 $FUZZERSHELL >&@ stdout
|
||||
progress "afl-cmin complete."
|
||||
#
|
||||
# Experiments show that running afl-tmin is too slow for this application.
|
||||
# And it doesn't really make the test cases that much smaller. So let's
|
||||
# just skip it.
|
||||
#
|
||||
# foreach file [glob tmp2/*] {
|
||||
# progress "$AFLBIN/afl-tmin -i $file -o tmp3/[file tail $file] $FUZZERSHELL"
|
||||
# exec $AFLBIN/afl-tmin -i $file -o tmp3/[file tail $file] \
|
||||
# $FUZZERSHELL >&@ stdout
|
||||
# }
|
||||
progress "generating final output into $OUTFILE"
|
||||
set out [open $OUTFILE wb]
|
||||
puts $out "# Test data for use with fuzzershell. Automatically
|
||||
# generated using $argv0. This file contains binary data
|
||||
#"
|
||||
set n 0
|
||||
foreach file [glob tmp2/*] {
|
||||
incr n
|
||||
puts -nonewline $out "/****<$n>****/"
|
||||
set in [open $file rb]
|
||||
puts -nonewline $out [read $in]
|
||||
close $in
|
||||
}
|
||||
close $out
|
||||
progress "done. $n test cases written to $OUTFILE"
|
||||
progress "clean-up..."
|
||||
file delete -force tmp1
|
||||
progress "culled test cases left in the tmp2 directory"
|
||||
@@ -216,4 +216,22 @@ foreach PGSZ {512 2048 4096 8192} {
|
||||
} [list $PGSZ $PGSZ]
|
||||
}
|
||||
|
||||
reset_db
|
||||
do_execsql_test pagesize-3.1 {
|
||||
BEGIN;
|
||||
SELECT * FROM sqlite_master;
|
||||
PRAGMA page_size=2048;
|
||||
PRAGMA main.page_size;
|
||||
} {1024}
|
||||
do_execsql_test pagesize-3.2 {
|
||||
CREATE TABLE t1(x);
|
||||
COMMIT;
|
||||
}
|
||||
do_execsql_test pagesize-3.3 {
|
||||
BEGIN;
|
||||
PRAGMA page_size = 2048;
|
||||
COMMIT;
|
||||
PRAGMA main.page_size;
|
||||
} {1024}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -219,6 +219,24 @@ do_test pragma-1.14 {
|
||||
PRAGMA synchronous;
|
||||
}
|
||||
} {2}
|
||||
do_test pragma-1.14.1 {
|
||||
execsql {
|
||||
PRAGMA synchronous=4;
|
||||
PRAGMA synchronous;
|
||||
}
|
||||
} {0}
|
||||
do_test pragma-1.14.2 {
|
||||
execsql {
|
||||
PRAGMA synchronous=3;
|
||||
PRAGMA synchronous;
|
||||
}
|
||||
} {0}
|
||||
do_test pragma-1.14.3 {
|
||||
execsql {
|
||||
PRAGMA synchronous=10;
|
||||
PRAGMA synchronous;
|
||||
}
|
||||
} {2}
|
||||
} ;# ifcapable pager_pragmas
|
||||
|
||||
# Test turning "flag" pragmas on and off.
|
||||
|
||||
+21
-2
@@ -18,6 +18,7 @@ optional) are:
|
||||
--buildonly (Just build testfixture - do not run)
|
||||
--dryrun (Print what would have happened)
|
||||
--info (Show diagnostic info)
|
||||
--with-tcl=DIR (Use TCL build at DIR)
|
||||
|
||||
The default value for --srcdir is the parent of the directory holding
|
||||
this script.
|
||||
@@ -110,6 +111,13 @@ array set ::Configs [strip_comments {
|
||||
-DSQLITE_ENABLE_STAT4
|
||||
-DSQLITE_MAX_ATTACHED=125
|
||||
}
|
||||
"Fast-One" {
|
||||
-O6
|
||||
-DSQLITE_ENABLE_FTS4=1
|
||||
-DSQLITE_ENABLE_RTREE=1
|
||||
-DSQLITE_ENABLE_STAT4
|
||||
-DSQLITE_MAX_ATTACHED=125
|
||||
}
|
||||
"Device-One" {
|
||||
-O2
|
||||
-DSQLITE_DEBUG=1
|
||||
@@ -199,6 +207,8 @@ array set ::Configs [strip_comments {
|
||||
Fail2 {-O0}
|
||||
Fail3 {-O0}
|
||||
Fail4 {-O0}
|
||||
FuzzFail1 {-O0}
|
||||
FuzzFail2 {-O0}
|
||||
}]
|
||||
|
||||
array set ::Platforms [strip_comments {
|
||||
@@ -214,6 +224,7 @@ array set ::Platforms [strip_comments {
|
||||
"No-lookaside" test
|
||||
"Devkit" test
|
||||
"Sanitize" {QUICKTEST_OMIT=func4.test,nan.test test}
|
||||
"Fast-One" fuzzoomtest
|
||||
"Valgrind" valgrindtest
|
||||
"Default" "threadtest fulltest"
|
||||
"Device-One" fulltest
|
||||
@@ -255,6 +266,8 @@ array set ::Platforms [strip_comments {
|
||||
Fail2 "TEST_FAILURE=2 valgrindtest"
|
||||
Fail3 "TEST_FAILURE=3 valgrindtest"
|
||||
Fail4 "TEST_FAILURE=4 test"
|
||||
FuzzFail1 "TEST_FAILURE=5 test"
|
||||
FuzzFail2 "TEST_FAILURE=5 valgrindtest"
|
||||
}
|
||||
}]
|
||||
|
||||
@@ -351,7 +364,7 @@ proc run_test_suite {name testtarget config} {
|
||||
set cflags [expr {$::MSVC ? "-Zi" : "-g"}]
|
||||
set opts ""
|
||||
set title ${name}($testtarget)
|
||||
set configOpts ""
|
||||
set configOpts $::WITHTCL
|
||||
|
||||
regsub -all {#[^\n]*\n} $config \n config
|
||||
foreach arg $config {
|
||||
@@ -482,6 +495,7 @@ proc process_options {argv} {
|
||||
set ::DRYRUN 0
|
||||
set ::EXEC exec
|
||||
set ::TRACE 0
|
||||
set ::WITHTCL {}
|
||||
set config {}
|
||||
set platform $::tcl_platform(os)-$::tcl_platform(machine)
|
||||
|
||||
@@ -556,6 +570,10 @@ proc process_options {argv} {
|
||||
}
|
||||
}
|
||||
|
||||
-with-tcl=* {
|
||||
set ::WITHTCL -$x
|
||||
}
|
||||
|
||||
-D* -
|
||||
-O* -
|
||||
-enable-* -
|
||||
@@ -643,10 +661,11 @@ proc main {argv} {
|
||||
# it and run veryquick.test. If it did not include the SQLITE_DEBUG option
|
||||
# add it and run veryquick.test.
|
||||
if {$target!="checksymbols" && $target!="valgrindtest"
|
||||
&& !$::BUILDONLY && $::QUICK<2} {
|
||||
&& $target!="fuzzoomtest" && !$::BUILDONLY && $::QUICK<2} {
|
||||
set debug_idx [lsearch -glob $config_options -DSQLITE_DEBUG*]
|
||||
set xtarget $target
|
||||
regsub -all {fulltest[a-z]*} $xtarget test xtarget
|
||||
regsub -all {fuzzoomtest} $xtarget fuzztest xtarget
|
||||
if {$debug_idx < 0} {
|
||||
incr NTEST
|
||||
append config_options " -DSQLITE_DEBUG=1"
|
||||
|
||||
@@ -11,10 +11,12 @@
|
||||
#
|
||||
# This file tests features of the name resolver (the component that
|
||||
# figures out what identifiers in the SQL statement refer to) that
|
||||
# were fixed by ticket [2500cdb9be]
|
||||
# were fixed by ticket [2500cdb9be].
|
||||
#
|
||||
# See also tickets [1c69be2daf] and [f617ea3125] from 2013-08-14.
|
||||
#
|
||||
# Also a fuzzer-discovered problem on 2015-04-23.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@@ -201,6 +203,12 @@ do_execsql_test resolver01-6.3 {
|
||||
GROUP BY lower(name);
|
||||
} {1 {} 1 {}}
|
||||
|
||||
do_execsql_test resolver01-7.1 {
|
||||
SELECT 2 AS x WHERE (SELECT x AS y WHERE 3>y);
|
||||
} {2}
|
||||
do_execsql_test resolver01-7.2 {
|
||||
SELECT 2 AS x WHERE (SELECT x AS y WHERE 1>y);
|
||||
} {}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -307,6 +307,9 @@ do_test select1-4.4 {
|
||||
set v [catch {execsql {SELECT f1 FROM test1 ORDER BY min(f1)}} msg]
|
||||
lappend v $msg
|
||||
} {1 {misuse of aggregate: min()}}
|
||||
do_catchsql_test select1-4.5 {
|
||||
INSERT INTO test1(f1) SELECT f1 FROM test1 ORDER BY min(f1);
|
||||
} {1 {misuse of aggregate: min()}}
|
||||
|
||||
# The restriction not allowing constants in the ORDER BY clause
|
||||
# has been removed. See ticket #1768
|
||||
@@ -1072,5 +1075,10 @@ if {[db one {PRAGMA locking_mode}]=="normal"} {
|
||||
do_test select1-16.1 {
|
||||
catchsql {SELECT 1 FROM (SELECT *)}
|
||||
} {1 {no tables specified}}
|
||||
|
||||
# 2015-04-17: assertion fix.
|
||||
do_catchsql_test select1-16.2 {
|
||||
SELECT 1 FROM sqlite_master LIMIT 1,#1;
|
||||
} {1 {near "#1": syntax error}}
|
||||
|
||||
finish_test
|
||||
|
||||
+35
-1
@@ -118,6 +118,10 @@ do_test select4-1.3 {
|
||||
}} msg]
|
||||
lappend v $msg
|
||||
} {1 {ORDER BY clause should come after UNION ALL not before}}
|
||||
do_catchsql_test select4-1.4 {
|
||||
SELECT (VALUES(0) INTERSECT SELECT(0) UNION SELECT(0) ORDER BY 1 UNION
|
||||
SELECT 0 UNION SELECT 0 ORDER BY 1);
|
||||
} {1 {ORDER BY clause should come after UNION not before}}
|
||||
|
||||
# Union operator
|
||||
#
|
||||
@@ -148,6 +152,15 @@ do_test select4-2.3 {
|
||||
}} msg]
|
||||
lappend v $msg
|
||||
} {1 {ORDER BY clause should come after UNION not before}}
|
||||
do_test select4-2.4 {
|
||||
set v [catch {execsql {
|
||||
SELECT 0 ORDER BY (SELECT 0) UNION SELECT 0;
|
||||
}} msg]
|
||||
lappend v $msg
|
||||
} {1 {ORDER BY clause should come after UNION not before}}
|
||||
do_execsql_test select4-2.5 {
|
||||
SELECT 123 AS x ORDER BY (SELECT x ORDER BY 1);
|
||||
} {123}
|
||||
|
||||
# Except operator
|
||||
#
|
||||
@@ -264,6 +277,16 @@ do_test select4-4.3 {
|
||||
}} msg]
|
||||
lappend v $msg
|
||||
} {1 {ORDER BY clause should come after INTERSECT not before}}
|
||||
do_catchsql_test select4-4.4 {
|
||||
SELECT 3 IN (
|
||||
SELECT 0 ORDER BY 1
|
||||
INTERSECT
|
||||
SELECT 1
|
||||
INTERSECT
|
||||
SELECT 2
|
||||
ORDER BY 1
|
||||
);
|
||||
} {1 {ORDER BY clause should come after INTERSECT not before}}
|
||||
|
||||
# Various error messages while processing UNION or INTERSECT
|
||||
#
|
||||
@@ -874,6 +897,17 @@ do_execsql_test select4-14.10 {
|
||||
do_execsql_test select4-14.11 {
|
||||
SELECT (SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4)
|
||||
} {1}
|
||||
|
||||
do_execsql_test select4-14.12 {
|
||||
VALUES(1) UNION VALUES(2);
|
||||
} {1 2}
|
||||
do_execsql_test select4-14.13 {
|
||||
VALUES(1),(2),(3) EXCEPT VALUES(2);
|
||||
} {1 3}
|
||||
do_execsql_test select4-14.14 {
|
||||
VALUES(1),(2),(3) EXCEPT VALUES(1),(3);
|
||||
} {2}
|
||||
do_execsql_test select4-14.15 {
|
||||
SELECT * FROM (SELECT 123), (SELECT 456) ON likely(0 OR 1) OR 0;
|
||||
} {123 456}
|
||||
|
||||
finish_test
|
||||
|
||||
+101
-1
@@ -738,6 +738,9 @@ do_test shell1-4.1 {
|
||||
PRAGMA encoding=UTF16;
|
||||
CREATE TABLE t1(x);
|
||||
INSERT INTO t1 VALUES(null), (''), (1), (2.25), ('hello'), (x'807f');
|
||||
CREATE TABLE t3(x,y);
|
||||
INSERT INTO t3 VALUES(1,null), (2,''), (3,1),
|
||||
(4,2.25), (5,'hello'), (6,x'807f');
|
||||
}
|
||||
catchcmd test.db {.dump}
|
||||
} {0 {PRAGMA foreign_keys=OFF;
|
||||
@@ -749,11 +752,18 @@ INSERT INTO "t1" VALUES(1);
|
||||
INSERT INTO "t1" VALUES(2.25);
|
||||
INSERT INTO "t1" VALUES('hello');
|
||||
INSERT INTO "t1" VALUES(X'807F');
|
||||
CREATE TABLE t3(x,y);
|
||||
INSERT INTO "t3" VALUES(1,NULL);
|
||||
INSERT INTO "t3" VALUES(2,'');
|
||||
INSERT INTO "t3" VALUES(3,1);
|
||||
INSERT INTO "t3" VALUES(4,2.25);
|
||||
INSERT INTO "t3" VALUES(5,'hello');
|
||||
INSERT INTO "t3" VALUES(6,X'807F');
|
||||
COMMIT;}}
|
||||
|
||||
# Test the output of ".mode insert"
|
||||
#
|
||||
do_test shell1-4.2 {
|
||||
do_test shell1-4.2.1 {
|
||||
catchcmd test.db ".mode insert t1\nselect * from t1;"
|
||||
} {0 {INSERT INTO t1 VALUES(NULL);
|
||||
INSERT INTO t1 VALUES('');
|
||||
@@ -762,6 +772,39 @@ INSERT INTO t1 VALUES(2.25);
|
||||
INSERT INTO t1 VALUES('hello');
|
||||
INSERT INTO t1 VALUES(X'807f');}}
|
||||
|
||||
# Test the output of ".mode insert" with headers
|
||||
#
|
||||
do_test shell1-4.2.2 {
|
||||
catchcmd test.db ".mode insert t1\n.headers on\nselect * from t1;"
|
||||
} {0 {INSERT INTO t1(x) VALUES(NULL);
|
||||
INSERT INTO t1(x) VALUES('');
|
||||
INSERT INTO t1(x) VALUES(1);
|
||||
INSERT INTO t1(x) VALUES(2.25);
|
||||
INSERT INTO t1(x) VALUES('hello');
|
||||
INSERT INTO t1(x) VALUES(X'807f');}}
|
||||
|
||||
# Test the output of ".mode insert"
|
||||
#
|
||||
do_test shell1-4.2.3 {
|
||||
catchcmd test.db ".mode insert t3\nselect * from t3;"
|
||||
} {0 {INSERT INTO t3 VALUES(1,NULL);
|
||||
INSERT INTO t3 VALUES(2,'');
|
||||
INSERT INTO t3 VALUES(3,1);
|
||||
INSERT INTO t3 VALUES(4,2.25);
|
||||
INSERT INTO t3 VALUES(5,'hello');
|
||||
INSERT INTO t3 VALUES(6,X'807f');}}
|
||||
|
||||
# Test the output of ".mode insert" with headers
|
||||
#
|
||||
do_test shell1-4.2.4 {
|
||||
catchcmd test.db ".mode insert t3\n.headers on\nselect * from t3;"
|
||||
} {0 {INSERT INTO t3(x,y) VALUES(1,NULL);
|
||||
INSERT INTO t3(x,y) VALUES(2,'');
|
||||
INSERT INTO t3(x,y) VALUES(3,1);
|
||||
INSERT INTO t3(x,y) VALUES(4,2.25);
|
||||
INSERT INTO t3(x,y) VALUES(5,'hello');
|
||||
INSERT INTO t3(x,y) VALUES(6,X'807f');}}
|
||||
|
||||
# Test the output of ".mode tcl"
|
||||
#
|
||||
do_test shell1-4.3 {
|
||||
@@ -818,4 +861,61 @@ do_test shell1-4.6 {
|
||||
";"
|
||||
"$"} 7}
|
||||
|
||||
# Test using arbitrary byte data with the shell via standard input/output.
|
||||
#
|
||||
do_test shell1-5.0 {
|
||||
#
|
||||
# NOTE: Skip NUL byte because it appears to be incompatible with command
|
||||
# shell argument parsing.
|
||||
#
|
||||
for {set i 1} {$i < 256} {incr i} {
|
||||
#
|
||||
# NOTE: Due to how the Tcl [exec] command works (i.e. where it treats
|
||||
# command channels opened for it as textual ones), the carriage
|
||||
# return character (and on Windows, the end-of-file character)
|
||||
# cannot be used here.
|
||||
#
|
||||
if {$i==0x0D || ($tcl_platform(platform)=="windows" && $i==0x1A)} {
|
||||
continue
|
||||
}
|
||||
set hex [format %02X $i]
|
||||
set char [subst \\x$hex]; set oldChar $char
|
||||
set escapes [list]
|
||||
if {$tcl_platform(platform)=="windows"} {
|
||||
#
|
||||
# NOTE: On Windows, we need to escape all the whitespace characters,
|
||||
# the alarm (\a) character, and those with special meaning to
|
||||
# the SQLite shell itself.
|
||||
#
|
||||
set escapes [list \
|
||||
\a \\a \b \\b \t \\t \n \\n \v \\v \f \\f \r \\r \
|
||||
" " "\" \"" \" \\\" ' \"'\" \\ \\\\]
|
||||
} else {
|
||||
#
|
||||
# NOTE: On Unix, we need to escape most of the whitespace characters
|
||||
# and those with special meaning to the SQLite shell itself.
|
||||
# The alarm (\a), backspace (\b), and carriage-return (\r)
|
||||
# characters do not appear to require escaping on Unix. For
|
||||
# the alarm and backspace characters, this is probably due to
|
||||
# differences in the command shell. For the carriage-return,
|
||||
# it is probably due to differences in how Tcl handles command
|
||||
# channel end-of-line translations.
|
||||
#
|
||||
set escapes [list \
|
||||
\t \\t \n \\n \v \\v \f \\f \
|
||||
" " "\" \"" \" \\\" ' \"'\" \\ \\\\]
|
||||
}
|
||||
set char [string map $escapes $char]
|
||||
set x [catchcmdex test.db ".print $char\n"]
|
||||
set code [lindex $x 0]
|
||||
set res [lindex $x 1]
|
||||
if {$code ne "0"} {
|
||||
error "failed with error: $res"
|
||||
}
|
||||
if {$res ne "$oldChar\n"} {
|
||||
error "failed with byte $hex mismatch"
|
||||
}
|
||||
}
|
||||
} {}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
# 2015-05-11
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# Quick tests for the sqldiff tool
|
||||
#
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
if {$tcl_platform(platform)=="windows"} {
|
||||
set PROG "sqldiff.exe"
|
||||
} else {
|
||||
set PROG "./sqldiff"
|
||||
}
|
||||
db close
|
||||
forcedelete test.db test2.db
|
||||
sqlite3 db test.db
|
||||
|
||||
do_test sqldiff-1.0 {
|
||||
db eval {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
|
||||
CREATE TABLE t2(a INT PRIMARY KEY, b) WITHOUT ROWID;
|
||||
WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100)
|
||||
INSERT INTO t1(a,b) SELECT x, printf('abc-%d-xyz',x) FROM c;
|
||||
INSERT INTO t2(a,b) SELECT a, b FROM t1;
|
||||
}
|
||||
db backup test2.db
|
||||
db eval {
|
||||
ATTACH 'test2.db' AS x2;
|
||||
DELETE FROM x2.t1 WHERE a=49;
|
||||
DELETE FROM x2.t2 WHERE a=48;
|
||||
INSERT INTO x2.t1(a,b) VALUES(1234,'hello');
|
||||
INSERT INTO x2.t2(a,b) VALUES(50.5,'xyzzy');
|
||||
CREATE TABLE x2.t3(a,b,c);
|
||||
INSERT INTO x2.t3 VALUES(111,222,333);
|
||||
CREATE TABLE main.t4(x,y,z);
|
||||
INSERT INTO t4 SELECT * FROM t3;
|
||||
}
|
||||
set line "exec $PROG test.db test2.db"
|
||||
unset -nocomplain ::MSG
|
||||
catch {eval $line} ::MSG
|
||||
} {0}
|
||||
do_test sqldiff-1.1 {
|
||||
set ::MSG
|
||||
} {DELETE FROM t1 WHERE a=49;
|
||||
INSERT INTO t1(a,b) VALUES(1234,'hello');
|
||||
DELETE FROM t2 WHERE a=48;
|
||||
INSERT INTO t2(a,b) VALUES(50.5,'xyzzy');
|
||||
CREATE TABLE t3(a,b,c);
|
||||
INSERT INTO t3(rowid,a,b,c) VALUES(1,111,222,333);
|
||||
DROP TABLE t4;}
|
||||
|
||||
finish_test
|
||||
+8
-2
@@ -166,8 +166,10 @@ sqlite3 db test.db
|
||||
register_dbstat_vtab db
|
||||
do_execsql_test stat-5.1 {
|
||||
PRAGMA auto_vacuum = OFF;
|
||||
CREATE VIRTUAL TABLE temp.stat USING dbstat;
|
||||
CREATE TABLE t1(x);
|
||||
CREATE TABLE tx(y);
|
||||
ATTACH ':memory:' AS aux1;
|
||||
CREATE VIRTUAL TABLE temp.stat USING dbstat(aux1);
|
||||
CREATE TABLE aux1.t1(x);
|
||||
INSERT INTO t1 VALUES(zeroblob(1513));
|
||||
INSERT INTO t1 VALUES(zeroblob(1514));
|
||||
SELECT name, path, pageno, pagetype, ncell, payload, unused, mx_payload
|
||||
@@ -178,4 +180,8 @@ do_execsql_test stat-5.1 {
|
||||
t1 /001+000000 4 overflow 0 1020 0 0 \
|
||||
]
|
||||
|
||||
do_catchsql_test stat-6.1 {
|
||||
CREATE VIRTUAL TABLE temp.s2 USING dbstat(mainx);
|
||||
} {1 {no such database: mainx}}
|
||||
|
||||
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